Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using EntityFrameworkCore.Projectables;
using FluentValidation;
using TeachingRecordSystem.Core.Events.Legacy;

namespace TeachingRecordSystem.Core.DataStore.Postgres.Models;
Expand All @@ -10,6 +11,8 @@ public class Alert
public const string PersonIdIndexName = "ix_alerts_person_id";
public const string PersonForeignKeyName = "fk_alerts_person";

public const int DetailsMaxLength = 4000;

public required Guid AlertId { get; init; }
public AlertType? AlertType { get; }
public required Guid AlertTypeId { get; init; }
Expand Down Expand Up @@ -137,3 +140,41 @@ public void Update(
};
}
}

public static class AlertValidationExtensions
{
public static IRuleBuilderOptions<T, string?> AlertDetails<T>(
this IRuleBuilder<T, string?> ruleBuilder,
Func<int, string> maxLengthMessage)
{
return ruleBuilder
.MaximumLength(Alert.DetailsMaxLength).WithMessage(maxLengthMessage(Alert.DetailsMaxLength));
}

public static IRuleBuilderOptions<T, string?> AlertLink<T>(
this IRuleBuilder<T, string?> ruleBuilder,
string invalidUrlMessage)
{
return ruleBuilder
.Must(link => TrsUriHelper.TryCreateWebsiteUri(link, out _)).WithMessage(invalidUrlMessage);
}

public static IRuleBuilderOptions<T, DateOnly?> AlertStartDate<T>(
this IRuleBuilder<T, DateOnly?> ruleBuilder,
DateOnly today,
string requiredMessage,
string dateInFutureMessage)
{
return ruleBuilder
.NotNull().WithMessage(requiredMessage)
.LessThanOrEqualTo(today).WithMessage(dateInFutureMessage);
}

public static IRuleBuilderOptions<T, Guid?> AlertType<T>(
this IRuleBuilder<T, Guid?> ruleBuilder,
string requiredMessage)
{
return ruleBuilder
.NotNull().WithMessage(requiredMessage);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,20 @@
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Filters;
using Microsoft.AspNetCore.Mvc.RazorPages;
using TeachingRecordSystem.Core.DataStore.Postgres.Models;
using TeachingRecordSystem.SupportUi.Pages.Shared.Evidence;

namespace TeachingRecordSystem.SupportUi.Pages.Alerts.AddAlert;

[Journey(JourneyNames.AddAlert), RequireJourneyInstance]
public class DetailsModel(SupportUiLinkGenerator linkGenerator, EvidenceUploadManager evidenceUploadManager) : PageModel
{
private static readonly InlineValidator<DetailsModel> _validator = new()
{
v => v.RuleFor(m => m.Details).AlertDetails(
maxLengthMessage: maxLength => $"Details must be {maxLength} characters or less")
};

public JourneyInstance<AddAlertState>? JourneyInstance { get; set; }

[FromQuery]
Expand All @@ -23,7 +30,7 @@

[BindProperty]
[Display(Description = "For example, include any restrictions it places on a teacher.")]
[MaxLength(UiDefaults.DetailMaxCharacterCount, ErrorMessage = $"Details {UiDefaults.DetailMaxCharacterCountErrorMessage}")]
[MaxLength(FileUploadDefaults.DetailMaxCharacterCount, ErrorMessage = $"Details {FileUploadDefaults.DetailMaxCharacterCountErrorMessage}")]

Check failure on line 33 in TeachingRecordSystem/src/TeachingRecordSystem.SupportUi/Pages/Alerts/AddAlert/Details.cshtml.cs

View workflow job for this annotation

GitHub Actions / Package application / Build & package

The name 'FileUploadDefaults' does not exist in the current context

Check failure on line 33 in TeachingRecordSystem/src/TeachingRecordSystem.SupportUi/Pages/Alerts/AddAlert/Details.cshtml.cs

View workflow job for this annotation

GitHub Actions / Package application / Build & package

The name 'FileUploadDefaults' does not exist in the current context

Check failure on line 33 in TeachingRecordSystem/src/TeachingRecordSystem.SupportUi/Pages/Alerts/AddAlert/Details.cshtml.cs

View workflow job for this annotation

GitHub Actions / Tests (SupportUi.EndToEndTests)

The name 'FileUploadDefaults' does not exist in the current context

Check failure on line 33 in TeachingRecordSystem/src/TeachingRecordSystem.SupportUi/Pages/Alerts/AddAlert/Details.cshtml.cs

View workflow job for this annotation

GitHub Actions / Tests (SupportUi.EndToEndTests)

The name 'FileUploadDefaults' does not exist in the current context

Check failure on line 33 in TeachingRecordSystem/src/TeachingRecordSystem.SupportUi/Pages/Alerts/AddAlert/Details.cshtml.cs

View workflow job for this annotation

GitHub Actions / Tests (SupportUi.EndToEndTests)

The name 'FileUploadDefaults' does not exist in the current context

Check failure on line 33 in TeachingRecordSystem/src/TeachingRecordSystem.SupportUi/Pages/Alerts/AddAlert/Details.cshtml.cs

View workflow job for this annotation

GitHub Actions / Tests (SupportUi.EndToEndTests)

The name 'FileUploadDefaults' does not exist in the current context

Check failure on line 33 in TeachingRecordSystem/src/TeachingRecordSystem.SupportUi/Pages/Alerts/AddAlert/Details.cshtml.cs

View workflow job for this annotation

GitHub Actions / Tests (SupportUi.Tests)

The name 'FileUploadDefaults' does not exist in the current context

Check failure on line 33 in TeachingRecordSystem/src/TeachingRecordSystem.SupportUi/Pages/Alerts/AddAlert/Details.cshtml.cs

View workflow job for this annotation

GitHub Actions / Tests (SupportUi.Tests)

The name 'FileUploadDefaults' does not exist in the current context

Check failure on line 33 in TeachingRecordSystem/src/TeachingRecordSystem.SupportUi/Pages/Alerts/AddAlert/Details.cshtml.cs

View workflow job for this annotation

GitHub Actions / Tests (SupportUi.Tests)

The name 'FileUploadDefaults' does not exist in the current context

Check failure on line 33 in TeachingRecordSystem/src/TeachingRecordSystem.SupportUi/Pages/Alerts/AddAlert/Details.cshtml.cs

View workflow job for this annotation

GitHub Actions / Tests (SupportUi.Tests)

The name 'FileUploadDefaults' does not exist in the current context
public string? Details { get; set; }

public void OnGet()
Expand All @@ -33,10 +40,7 @@

public async Task<IActionResult> OnPostAsync()
{
if (!ModelState.IsValid)
{
return this.PageWithErrors();
}
await _validator.ValidateAndThrowAsync(this);

await JourneyInstance!.UpdateStateAsync(state =>
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,20 @@
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Filters;
using Microsoft.AspNetCore.Mvc.RazorPages;
using TeachingRecordSystem.Core.DataStore.Postgres.Models;
using TeachingRecordSystem.SupportUi.Pages.Shared.Evidence;

namespace TeachingRecordSystem.SupportUi.Pages.Alerts.AddAlert;

[Journey(JourneyNames.AddAlert), RequireJourneyInstance]
public class LinkModel(SupportUiLinkGenerator linkGenerator, EvidenceUploadManager evidenceUploadManager) : PageModel
{
private static readonly InlineValidator<LinkModel> _validator = new()
{
v => v.RuleFor(m => m.AddLink).NotNull().WithMessage("Select yes if you want to add a link to a panel outcome"),
v => v.RuleFor(m => m.Link).AlertLink("Enter a valid URL").When(m => m.AddLink == true)
};

public JourneyInstance<AddAlertState>? JourneyInstance { get; set; }

[FromQuery]
Expand All @@ -21,7 +28,6 @@ public class LinkModel(SupportUiLinkGenerator linkGenerator, EvidenceUploadManag

[BindProperty]
[Display(Name = "Do you want to add a link to a panel outcome?")]
[Required(ErrorMessage = "Select yes if you want to add a link to a panel outcome")]
public bool? AddLink { get; set; }

[BindProperty]
Expand All @@ -36,15 +42,7 @@ public void OnGet()

public async Task<IActionResult> OnPostAsync()
{
if (AddLink == true && !TrsUriHelper.TryCreateWebsiteUri(Link, out _))
{
ModelState.AddModelError(nameof(Link), "Enter a valid URL");
}

if (!ModelState.IsValid)
{
return this.PageWithErrors();
}
await _validator.ValidateAndThrowAsync(this);

await JourneyInstance!.UpdateStateAsync(state =>
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,24 @@
[Journey(JourneyNames.AddAlert), RequireJourneyInstance]
public class ReasonModel(SupportUiLinkGenerator linkGenerator, EvidenceUploadManager evidenceUploadManager) : PageModel
{
private static readonly InlineValidator<ReasonModel> _validator = new()
{
v => v.RuleFor(m => m.AddReason)
.NotNull().WithMessage("Select a reason"),
v => v.RuleFor(m => m.HasAdditionalReasonDetail)
.NotNull().WithMessage("Select yes if you want to add more information about why you’re adding this alert"),
v => v.RuleFor(m => m.AddReasonDetail)
.NotNull().WithMessage("Enter additional detail")
.MaximumLength(4000).WithMessage("Additional detail must be 4000 characters or less")
.When(m => m.HasAdditionalReasonDetail == true),
v => v.RuleFor(m => m.UploadEvidence)
.NotNull().WithMessage("Select yes if you want to upload evidence"),
v => v.RuleFor(m => m.EvidenceFile)
.NotNull().WithMessage("Select a file")
.EvidenceFile()
.When(m => m.UploadEvidence == true && m.EvidenceFileId is null)
};

public JourneyInstance<AddAlertState>? JourneyInstance { get; set; }

[FromQuery]
Expand All @@ -21,17 +39,15 @@

[BindProperty]
[Display(Name = "Select a reason")]
[Required(ErrorMessage = "Select a reason")]
public AddAlertReasonOption? AddReason { get; set; }

[BindProperty]
[Display(Name = "Do you want to add more information about why you’re adding this alert?")]
[Required(ErrorMessage = "Select yes if you want to add more information about why you’re adding this alert")]
public bool? HasAdditionalReasonDetail { get; set; }

[BindProperty]
[Display(Name = "Add additional detail")]
[MaxLength(UiDefaults.DetailMaxCharacterCount, ErrorMessage = $"Additional detail {UiDefaults.DetailMaxCharacterCountErrorMessage}")]
[MaxLength(FileUploadDefaults.DetailMaxCharacterCount, ErrorMessage = $"Additional detail {FileUploadDefaults.DetailMaxCharacterCountErrorMessage}")]

Check failure on line 50 in TeachingRecordSystem/src/TeachingRecordSystem.SupportUi/Pages/Alerts/AddAlert/Reason.cshtml.cs

View workflow job for this annotation

GitHub Actions / Package application / Build & package

The name 'FileUploadDefaults' does not exist in the current context

Check failure on line 50 in TeachingRecordSystem/src/TeachingRecordSystem.SupportUi/Pages/Alerts/AddAlert/Reason.cshtml.cs

View workflow job for this annotation

GitHub Actions / Package application / Build & package

The name 'FileUploadDefaults' does not exist in the current context

Check failure on line 50 in TeachingRecordSystem/src/TeachingRecordSystem.SupportUi/Pages/Alerts/AddAlert/Reason.cshtml.cs

View workflow job for this annotation

GitHub Actions / Tests (SupportUi.EndToEndTests)

The name 'FileUploadDefaults' does not exist in the current context

Check failure on line 50 in TeachingRecordSystem/src/TeachingRecordSystem.SupportUi/Pages/Alerts/AddAlert/Reason.cshtml.cs

View workflow job for this annotation

GitHub Actions / Tests (SupportUi.EndToEndTests)

The name 'FileUploadDefaults' does not exist in the current context

Check failure on line 50 in TeachingRecordSystem/src/TeachingRecordSystem.SupportUi/Pages/Alerts/AddAlert/Reason.cshtml.cs

View workflow job for this annotation

GitHub Actions / Tests (SupportUi.EndToEndTests)

The name 'FileUploadDefaults' does not exist in the current context

Check failure on line 50 in TeachingRecordSystem/src/TeachingRecordSystem.SupportUi/Pages/Alerts/AddAlert/Reason.cshtml.cs

View workflow job for this annotation

GitHub Actions / Tests (SupportUi.EndToEndTests)

The name 'FileUploadDefaults' does not exist in the current context

Check failure on line 50 in TeachingRecordSystem/src/TeachingRecordSystem.SupportUi/Pages/Alerts/AddAlert/Reason.cshtml.cs

View workflow job for this annotation

GitHub Actions / Tests (SupportUi.Tests)

The name 'FileUploadDefaults' does not exist in the current context

Check failure on line 50 in TeachingRecordSystem/src/TeachingRecordSystem.SupportUi/Pages/Alerts/AddAlert/Reason.cshtml.cs

View workflow job for this annotation

GitHub Actions / Tests (SupportUi.Tests)

The name 'FileUploadDefaults' does not exist in the current context

Check failure on line 50 in TeachingRecordSystem/src/TeachingRecordSystem.SupportUi/Pages/Alerts/AddAlert/Reason.cshtml.cs

View workflow job for this annotation

GitHub Actions / Tests (SupportUi.Tests)

The name 'FileUploadDefaults' does not exist in the current context

Check failure on line 50 in TeachingRecordSystem/src/TeachingRecordSystem.SupportUi/Pages/Alerts/AddAlert/Reason.cshtml.cs

View workflow job for this annotation

GitHub Actions / Tests (SupportUi.Tests)

The name 'FileUploadDefaults' does not exist in the current context
public string? AddReasonDetail { get; set; }

[BindProperty]
Expand Down Expand Up @@ -60,17 +76,8 @@

public async Task<IActionResult> OnPostAsync()
{
if (HasAdditionalReasonDetail == true && AddReasonDetail is null)
{
ModelState.AddModelError(nameof(AddReasonDetail), "Enter additional detail");
}

await evidenceUploadManager.ValidateAndUploadAsync(Evidence, ModelState);

if (!ModelState.IsValid)
{
return this.PageWithErrors();
}
await _validator.ValidateAndThrowAsync(this);
ModelState.AddModelError(nameof(EvidenceFile), "Select a file");

await JourneyInstance!.UpdateStateAsync(state =>
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,22 @@
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Filters;
using Microsoft.AspNetCore.Mvc.RazorPages;
using TeachingRecordSystem.Core.DataStore.Postgres.Models;
using TeachingRecordSystem.SupportUi.Pages.Shared.Evidence;

namespace TeachingRecordSystem.SupportUi.Pages.Alerts.AddAlert;

[Journey(JourneyNames.AddAlert), RequireJourneyInstance]
public class StartDateModel(SupportUiLinkGenerator linkGenerator, EvidenceUploadManager evidenceUploadManager, IClock clock) : PageModel
{
private readonly InlineValidator<StartDateModel> _validator = new()
{
v => v.RuleFor(m => m.StartDate).AlertStartDate(
clock.Today,
requiredMessage: "Enter a start date",
dateInFutureMessage: "Start date cannot be in the future")
};

public JourneyInstance<AddAlertState>? JourneyInstance { get; set; }

[FromQuery]
Expand All @@ -21,7 +30,6 @@ public class StartDateModel(SupportUiLinkGenerator linkGenerator, EvidenceUpload

[BindProperty]
[DateInput(ErrorMessagePrefix = "Start date")]
[Required(ErrorMessage = "Enter a start date")]
[Display(Name = "Enter start date")]
public DateOnly? StartDate { get; set; }

Expand All @@ -32,15 +40,7 @@ public void OnGet()

public async Task<IActionResult> OnPostAsync()
{
if (StartDate > clock.Today)
{
ModelState.AddModelError(nameof(StartDate), "Start date cannot be in the future");
}

if (!ModelState.IsValid)
{
return this.PageWithErrors();
}
await _validator.ValidateAndThrowAsync(this);

await JourneyInstance!.UpdateStateAsync(state =>
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Filters;
using Microsoft.AspNetCore.Mvc.RazorPages;
using TeachingRecordSystem.Core.DataStore.Postgres.Models;
using TeachingRecordSystem.SupportUi.Infrastructure.Security;
using TeachingRecordSystem.SupportUi.Infrastructure.Security.Requirements;
using TeachingRecordSystem.SupportUi.Pages.Shared.Evidence;
Expand All @@ -16,6 +17,11 @@ public class TypeModel(
EvidenceUploadManager evidenceUploadManager,
IAuthorizationService authorizationService) : PageModel
{
private static readonly InlineValidator<TypeModel> _validator = new()
{
v => v.RuleFor(m => m.AlertTypeId).AlertType(requiredMessage: "Select an alert type")
};

public JourneyInstance<AddAlertState>? JourneyInstance { get; set; }

[FromQuery]
Expand All @@ -28,7 +34,6 @@ public class TypeModel(

[BindProperty]
[Display(Name = "Select an alert type")]
[Required(ErrorMessage = "Select an alert type")]
public Guid? AlertTypeId { get; set; }

public AlertCategoryInfo[]? Categories { get; set; }
Expand All @@ -42,10 +47,7 @@ public void OnGet()

public async Task<IActionResult> OnPostAsync()
{
if (!ModelState.IsValid)
{
return this.PageWithErrors();
}
await _validator.ValidateAndThrowAsync(this);

var selectedType = AlertTypes!.Single(t => t.AlertTypeId == AlertTypeId);

Expand Down
Loading