From a4df6962d183f7aff5075c01fefa6d46c146b3d3 Mon Sep 17 00:00:00 2001 From: James Gunn Date: Thu, 12 Sep 2024 15:37:00 +0100 Subject: [PATCH] Amend API responses for TRS alerts data model (#1506) --- CHANGELOG.md | 11 ++ .../VersionedDtoGenerator.cs | 5 + .../TeachingRecordSystem.Api/GlobalUsings.cs | 1 + .../src/TeachingRecordSystem.Api/Program.cs | 8 +- .../TeachingRecordSystem.Api/V3/Constants.cs | 4 +- .../FindPersonByLastNameAndDateOfBirth.cs | 31 +++- .../FindPersonsByTrnAndDateOfBirth.cs | 31 +++- .../V3/Core/Operations/GetPerson.cs | 43 ++++-- .../SharedModels/{AlertInfo.cs => Alert.cs} | 4 +- .../V3/Core/SharedModels/AlertCategory.cs | 7 + .../V3/Core/SharedModels/AlertType.cs | 8 +- .../V3/V20240101/ApiModels/AlertInfo.cs | 16 +- .../Controllers/TeacherController.cs | 3 +- .../Controllers/TeachersController.cs | 3 +- .../Controllers/TeacherController.cs | 3 +- .../Controllers/TeachersController.cs | 3 +- .../V20240606/Controllers/PersonController.cs | 5 +- .../Controllers/PersonsController.cs | 5 +- .../Controllers/PersonsController.cs | 4 +- .../V3/VNext/ApiModels/Alert.cs | 3 +- ...{AlertCategoryInfo.cs => AlertCategory.cs} | 3 +- .../{AlertTypeInfo.cs => AlertType.cs} | 5 +- .../V3/VNext/Controllers/PersonController.cs | 5 +- .../V3/VNext/Controllers/PersonsController.cs | 46 +++++- .../V3/VNext/Requests/FindPersonRequest.cs | 18 +++ .../V3/VNext/Requests/FindPersonsRequest.cs | 12 ++ .../V3/VNext/Responses/FindPersonResponse.cs | 19 +++ .../V3/VNext/Responses/FindPersonsResponse.cs | 20 +++ .../V3/VNext/Responses/GetPersonResponse.cs | 9 +- .../AsyncEnumerableExtensions.cs | 2 + .../ReferenceDataCache.cs | 6 + .../TestBase.cs | 2 + .../V3/V20240101/FindTeachersTests.cs | 2 +- .../V3/V20240101/GetTeacherTestBase.cs | 4 +- ...FindPersonByLastNameAndDateOfBirthTests.cs | 2 +- .../V3/V20240606/GetPersonTestBase.cs | 4 +- ...FindPersonByLastNameAndDateOfBirthTests.cs | 2 +- .../FindPersonsByTrnAndDateOfBirthTests.cs | 2 +- ...FindPersonByLastNameAndDateOfBirthTests.cs | 76 ++++++++++ .../FindPersonsByTrnAndDateOfBirthTests.cs | 66 +++++++++ .../V3/VNext/GetPersonByTrnTests.cs | 137 ++++++++++++++++++ .../V3/VNext/GetPersonTests.cs | 113 +++++---------- .../V3/VNext/TestBase.cs | 8 +- .../DbHelper.cs | 8 +- 44 files changed, 639 insertions(+), 130 deletions(-) rename TeachingRecordSystem/src/TeachingRecordSystem.Api/V3/Core/SharedModels/{AlertInfo.cs => Alert.cs} (73%) create mode 100644 TeachingRecordSystem/src/TeachingRecordSystem.Api/V3/Core/SharedModels/AlertCategory.cs rename TeachingRecordSystem/src/TeachingRecordSystem.Api/V3/VNext/ApiModels/{AlertCategoryInfo.cs => AlertCategory.cs} (67%) rename TeachingRecordSystem/src/TeachingRecordSystem.Api/V3/VNext/ApiModels/{AlertTypeInfo.cs => AlertType.cs} (54%) create mode 100644 TeachingRecordSystem/src/TeachingRecordSystem.Api/V3/VNext/Requests/FindPersonRequest.cs create mode 100644 TeachingRecordSystem/src/TeachingRecordSystem.Api/V3/VNext/Requests/FindPersonsRequest.cs create mode 100644 TeachingRecordSystem/src/TeachingRecordSystem.Api/V3/VNext/Responses/FindPersonResponse.cs create mode 100644 TeachingRecordSystem/src/TeachingRecordSystem.Api/V3/VNext/Responses/FindPersonsResponse.cs create mode 100644 TeachingRecordSystem/tests/TeachingRecordSystem.Api.Tests/V3/VNext/FindPersonByLastNameAndDateOfBirthTests.cs create mode 100644 TeachingRecordSystem/tests/TeachingRecordSystem.Api.Tests/V3/VNext/FindPersonsByTrnAndDateOfBirthTests.cs create mode 100644 TeachingRecordSystem/tests/TeachingRecordSystem.Api.Tests/V3/VNext/GetPersonByTrnTests.cs diff --git a/CHANGELOG.md b/CHANGELOG.md index 138d0c19e..330db432b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,14 @@ # API Changelog +## Unreleased + +All references to `sanctions` have been removed and replaced with `alerts`; the following endpoints are affected: +- `GET /v3/persons/` +- `GET /v3/person` +- `GET /v3/persons` +- `GET /v3/persons/find` + + ## 20240814 ### `POST /v3/persons/find` @@ -10,6 +19,7 @@ New endpoint added for bulk person lookup by TRN and date of birth. `inductionStatus`, `qts` and `eyts` members have been added to align with the bulk `POST` endpoint. + ## 20240606 All endpoints under `/teacher` and `/teachers` have been moved to `/person` and `/persons`, respectively. @@ -27,6 +37,7 @@ The `person` property has been removed from the response. The `person` property has been removed from the response. + ## 20240416 ### `GET /v3/teachers/` diff --git a/TeachingRecordSystem/gen/TeachingRecordSystem.Api.Generator/VersionedDtoGenerator.cs b/TeachingRecordSystem/gen/TeachingRecordSystem.Api.Generator/VersionedDtoGenerator.cs index 288a4daee..57931d519 100644 --- a/TeachingRecordSystem/gen/TeachingRecordSystem.Api.Generator/VersionedDtoGenerator.cs +++ b/TeachingRecordSystem/gen/TeachingRecordSystem.Api.Generator/VersionedDtoGenerator.cs @@ -201,6 +201,11 @@ void AddUsing(UsingDirectiveSyntax usingSyntax) foreach (var (property, propertyType) in referenceGeneratedTypeInfo.Properties) { + if (excludeMembers.Contains(property.Identifier.ValueText)) + { + continue; + } + AddProperty(property, propertyType); } } diff --git a/TeachingRecordSystem/src/TeachingRecordSystem.Api/GlobalUsings.cs b/TeachingRecordSystem/src/TeachingRecordSystem.Api/GlobalUsings.cs index dd580a7b0..5e7f7278a 100644 --- a/TeachingRecordSystem/src/TeachingRecordSystem.Api/GlobalUsings.cs +++ b/TeachingRecordSystem/src/TeachingRecordSystem.Api/GlobalUsings.cs @@ -1 +1,2 @@ global using AutoMapper; +global using PostgresModels = TeachingRecordSystem.Core.DataStore.Postgres.Models; diff --git a/TeachingRecordSystem/src/TeachingRecordSystem.Api/Program.cs b/TeachingRecordSystem/src/TeachingRecordSystem.Api/Program.cs index 3975e6014..279208048 100644 --- a/TeachingRecordSystem/src/TeachingRecordSystem.Api/Program.cs +++ b/TeachingRecordSystem/src/TeachingRecordSystem.Api/Program.cs @@ -166,8 +166,7 @@ public static void Main(string[] args) { cfg.AddMaps(typeof(Program).Assembly); cfg.CreateMap(typeof(Option<>), typeof(Option<>)).ConvertUsing(typeof(OptionMapper<,>)); - }) - .AddTransient(typeof(OptionMapper<,>)); + }); services.Scan(scan => { @@ -175,6 +174,11 @@ public static void Main(string[] args) .AddClasses(filter => filter.InNamespaces("TeachingRecordSystem.Api.V3.Core.Operations").Where(type => type.Name.EndsWith("Handler"))) .AsSelf() .WithTransientLifetime(); + + scan.FromAssemblyOf() + .AddClasses(filter => filter.AssignableTo(typeof(ITypeConverter<,>))) + .AsSelf() + .WithTransientLifetime(); }); services.AddMediatR(cfg => cfg.RegisterServicesFromAssemblyContaining()); diff --git a/TeachingRecordSystem/src/TeachingRecordSystem.Api/V3/Constants.cs b/TeachingRecordSystem/src/TeachingRecordSystem.Api/V3/Constants.cs index 736b178cb..5f2e018f1 100644 --- a/TeachingRecordSystem/src/TeachingRecordSystem.Api/V3/Constants.cs +++ b/TeachingRecordSystem/src/TeachingRecordSystem.Api/V3/Constants.cs @@ -2,7 +2,7 @@ namespace TeachingRecordSystem.Api.V3; public static class Constants { - public static IReadOnlyCollection ExposableSanctionCodes { get; } = new[] + public static IReadOnlyCollection LegacyExposableSanctionCodes { get; } = new[] { "G1", "A18", @@ -37,7 +37,7 @@ public static class Constants "A23", }; - public static IReadOnlyCollection ProhibitionSanctionCodes { get; } = new[] + public static IReadOnlyCollection LegacyProhibitionSanctionCodes { get; } = new[] { "G1", "B1", diff --git a/TeachingRecordSystem/src/TeachingRecordSystem.Api/V3/Core/Operations/FindPersonByLastNameAndDateOfBirth.cs b/TeachingRecordSystem/src/TeachingRecordSystem.Api/V3/Core/Operations/FindPersonByLastNameAndDateOfBirth.cs index aa2d75d74..2f5062f14 100644 --- a/TeachingRecordSystem/src/TeachingRecordSystem.Api/V3/Core/Operations/FindPersonByLastNameAndDateOfBirth.cs +++ b/TeachingRecordSystem/src/TeachingRecordSystem.Api/V3/Core/Operations/FindPersonByLastNameAndDateOfBirth.cs @@ -19,6 +19,7 @@ public record FindPersonByLastNameAndDateOfBirthResultItem public required string MiddleName { get; init; } public required string LastName { get; init; } public required IReadOnlyCollection Sanctions { get; init; } + public required IReadOnlyCollection Alerts { get; init; } public required IReadOnlyCollection PreviousNames { get; init; } public required InductionStatusInfo? InductionStatus { get; init; } public required QtsInfo? Qts { get; init; } @@ -53,7 +54,7 @@ public async Task Handle(FindPersonByL new GetSanctionsByContactIdsQuery( contactsById.Keys, ActiveOnly: true, - new())); + new(dfeta_sanction.Fields.dfeta_StartDate, dfeta_sanction.Fields.dfeta_EndDate))); var getPreviousNamesTask = crmQueryDispatcher.ExecuteQuery(new GetPreviousNamesByContactIdsQuery(contactsById.Keys)); @@ -86,13 +87,39 @@ public async Task Handle(FindPersonByL MiddleName = r.ResolveMiddleName(), LastName = r.ResolveLastName(), Sanctions = sanctions[r.Id] - .Where(s => Constants.ExposableSanctionCodes.Contains(s.SanctionCode)) + .Where(s => Constants.LegacyExposableSanctionCodes.Contains(s.SanctionCode)) .Select(s => new SanctionInfo() { Code = s.SanctionCode, StartDate = s.Sanction.dfeta_StartDate?.ToDateOnlyWithDqtBstFix(isLocalTime: true) }) .AsReadOnly(), + Alerts = await sanctions[r.Id] + .ToAsyncEnumerable() + .SelectAwait(async s => + { + var alertType = await referenceDataCache.GetAlertTypeByDqtSanctionCode(s.SanctionCode); + var alertCategory = await referenceDataCache.GetAlertCategoryById(alertType.AlertCategoryId); + + return new Alert() + { + AlertId = s.Sanction.Id, + AlertType = new() + { + AlertTypeId = alertType.AlertTypeId, + AlertCategory = new() + { + AlertCategoryId = alertCategory.AlertCategoryId, + Name = alertCategory.Name + }, + Name = alertType.Name, + DqtSanctionCode = alertType.DqtSanctionCode! + }, + StartDate = s.Sanction.dfeta_StartDate?.ToDateOnlyWithDqtBstFix(isLocalTime: true), + EndDate = s.Sanction.dfeta_EndDate?.ToDateOnlyWithDqtBstFix(isLocalTime: true) + }; + }) + .AsReadOnlyAsync(), PreviousNames = previousNameHelper.GetFullPreviousNames(previousNames[r.Id], contactsById[r.Id]) .Select(name => new NameInfo() { diff --git a/TeachingRecordSystem/src/TeachingRecordSystem.Api/V3/Core/Operations/FindPersonsByTrnAndDateOfBirth.cs b/TeachingRecordSystem/src/TeachingRecordSystem.Api/V3/Core/Operations/FindPersonsByTrnAndDateOfBirth.cs index ab1fbdd26..22d549d3a 100644 --- a/TeachingRecordSystem/src/TeachingRecordSystem.Api/V3/Core/Operations/FindPersonsByTrnAndDateOfBirth.cs +++ b/TeachingRecordSystem/src/TeachingRecordSystem.Api/V3/Core/Operations/FindPersonsByTrnAndDateOfBirth.cs @@ -19,6 +19,7 @@ public record FindPersonsByTrnAndDateOfBirthResultItem public required string MiddleName { get; init; } public required string LastName { get; init; } public required IReadOnlyCollection Sanctions { get; init; } + public required IReadOnlyCollection Alerts { get; init; } public required IReadOnlyCollection PreviousNames { get; init; } public required InductionStatusInfo? InductionStatus { get; init; } public required QtsInfo? Qts { get; init; } @@ -60,7 +61,7 @@ public async Task Handle(FindPersonsByTrnA new GetSanctionsByContactIdsQuery( contactsById.Keys, ActiveOnly: true, - new())); + new(dfeta_sanction.Fields.dfeta_StartDate, dfeta_sanction.Fields.dfeta_EndDate))); var getPreviousNamesTask = crmQueryDispatcher.ExecuteQuery(new GetPreviousNamesByContactIdsQuery(contactsById.Keys)); @@ -93,13 +94,39 @@ public async Task Handle(FindPersonsByTrnA MiddleName = r.ResolveMiddleName(), LastName = r.ResolveLastName(), Sanctions = sanctions[r.Id] - .Where(s => Constants.ExposableSanctionCodes.Contains(s.SanctionCode)) + .Where(s => Constants.LegacyExposableSanctionCodes.Contains(s.SanctionCode)) .Select(s => new SanctionInfo() { Code = s.SanctionCode, StartDate = s.Sanction.dfeta_StartDate?.ToDateOnlyWithDqtBstFix(isLocalTime: true) }) .AsReadOnly(), + Alerts = await sanctions[r.Id] + .ToAsyncEnumerable() + .SelectAwait(async s => + { + var alertType = await referenceDataCache.GetAlertTypeByDqtSanctionCode(s.SanctionCode); + var alertCategory = await referenceDataCache.GetAlertCategoryById(alertType.AlertCategoryId); + + return new Alert() + { + AlertId = s.Sanction.Id, + AlertType = new() + { + AlertTypeId = alertType.AlertTypeId, + AlertCategory = new() + { + AlertCategoryId = alertCategory.AlertCategoryId, + Name = alertCategory.Name + }, + Name = alertType.Name, + DqtSanctionCode = alertType.DqtSanctionCode! + }, + StartDate = s.Sanction.dfeta_StartDate?.ToDateOnlyWithDqtBstFix(isLocalTime: true), + EndDate = s.Sanction.dfeta_EndDate?.ToDateOnlyWithDqtBstFix(isLocalTime: true) + }; + }) + .AsReadOnlyAsync(), PreviousNames = previousNameHelper.GetFullPreviousNames(previousNames[r.Id], contactsById[r.Id]) .Select(name => new NameInfo() { diff --git a/TeachingRecordSystem/src/TeachingRecordSystem.Api/V3/Core/Operations/GetPerson.cs b/TeachingRecordSystem/src/TeachingRecordSystem.Api/V3/Core/Operations/GetPerson.cs index 07475ca0f..1643003fe 100644 --- a/TeachingRecordSystem/src/TeachingRecordSystem.Api/V3/Core/Operations/GetPerson.cs +++ b/TeachingRecordSystem/src/TeachingRecordSystem.Api/V3/Core/Operations/GetPerson.cs @@ -3,14 +3,13 @@ using Optional; using TeachingRecordSystem.Api.V3.Core.SharedModels; using TeachingRecordSystem.Core.DataStore.Postgres; -using TeachingRecordSystem.Core.DataStore.Postgres.Models; using TeachingRecordSystem.Core.Dqt; using TeachingRecordSystem.Core.Dqt.Models; using TeachingRecordSystem.Core.Dqt.Queries; namespace TeachingRecordSystem.Api.V3.Core.Operations; -public record GetPersonCommand(string Trn, GetPersonCommandIncludes Include, DateOnly? DateOfBirth); +public record GetPersonCommand(string Trn, GetPersonCommandIncludes Include, DateOnly? DateOfBirth, bool ApplyLegacyAlertsBehavior); [Flags] public enum GetPersonCommandIncludes @@ -47,7 +46,7 @@ public record GetPersonResult public required Option> MandatoryQualifications { get; init; } public required Option> HigherEducationQualifications { get; init; } public required Option> Sanctions { get; init; } - public required Option> Alerts { get; init; } + public required Option> Alerts { get; init; } public required Option> PreviousNames { get; init; } public required Option AllowIdSignInWithProhibitions { get; init; } } @@ -392,7 +391,7 @@ async Task GetSanctions() default, Sanctions = command.Include.HasFlag(GetPersonCommandIncludes.Sanctions) ? Option.Some((await getSanctionsTask!) - .Where(s => Constants.ExposableSanctionCodes.Contains(s.SanctionCode)) + .Where(s => Constants.LegacyExposableSanctionCodes.Contains(s.SanctionCode)) .Where(s => s.Sanction.dfeta_EndDate is null && s.Sanction.dfeta_Spent != true) .Select(s => new SanctionInfo() { @@ -402,16 +401,34 @@ async Task GetSanctions() .AsReadOnly()) : default, Alerts = command.Include.HasFlag(GetPersonCommandIncludes.Alerts) ? - Option.Some((await getSanctionsTask!) - .Where(s => Constants.ProhibitionSanctionCodes.Contains(s.SanctionCode)) - .Select(s => new AlertInfo() + Option.Some(await (await getSanctionsTask!) + .ToAsyncEnumerable() + // The Legacy behavior is to only return prohibition-type alerts + .Where(s => !command.ApplyLegacyAlertsBehavior || Constants.LegacyProhibitionSanctionCodes.Contains(s.SanctionCode)) + .SelectAwait(async s => { - AlertType = SharedModels.AlertType.Prohibition, - DqtSanctionCode = s.SanctionCode, - StartDate = s.Sanction.dfeta_StartDate?.ToDateOnlyWithDqtBstFix(isLocalTime: true), - EndDate = s.Sanction.dfeta_EndDate?.ToDateOnlyWithDqtBstFix(isLocalTime: true) + var alertType = await referenceDataCache.GetAlertTypeByDqtSanctionCode(s.SanctionCode); + var alertCategory = await referenceDataCache.GetAlertCategoryById(alertType.AlertCategoryId); + + return new Alert() + { + AlertId = s.Sanction.Id, + AlertType = new() + { + AlertTypeId = alertType.AlertTypeId, + AlertCategory = new() + { + AlertCategoryId = alertCategory.AlertCategoryId, + Name = alertCategory.Name + }, + Name = alertType.Name, + DqtSanctionCode = alertType.DqtSanctionCode! + }, + StartDate = s.Sanction.dfeta_StartDate?.ToDateOnlyWithDqtBstFix(isLocalTime: true), + EndDate = s.Sanction.dfeta_EndDate?.ToDateOnlyWithDqtBstFix(isLocalTime: true) + }; }) - .AsReadOnly()) : + .AsReadOnlyAsync()) : default, PreviousNames = command.Include.HasFlag(GetPersonCommandIncludes.PreviousNames) ? Option.Some(previousNames.Select(n => n).AsReadOnly()) : @@ -576,7 +593,7 @@ private static NpqQualificationType MapNpqQualificationType(dfeta_qualification_ _ => throw new ArgumentException($"Unrecognized qualification type: '{qualificationType}'.", nameof(qualificationType)) }; - private static IReadOnlyCollection MapMandatoryQualifications(MandatoryQualification[] qualifications) => + private static IReadOnlyCollection MapMandatoryQualifications(PostgresModels.MandatoryQualification[] qualifications) => qualifications .Where(q => q.EndDate.HasValue && q.Specialism.HasValue) .Select(mq => new GetPersonResultMandatoryQualification() diff --git a/TeachingRecordSystem/src/TeachingRecordSystem.Api/V3/Core/SharedModels/AlertInfo.cs b/TeachingRecordSystem/src/TeachingRecordSystem.Api/V3/Core/SharedModels/Alert.cs similarity index 73% rename from TeachingRecordSystem/src/TeachingRecordSystem.Api/V3/Core/SharedModels/AlertInfo.cs rename to TeachingRecordSystem/src/TeachingRecordSystem.Api/V3/Core/SharedModels/Alert.cs index a29a899d7..9e7b2053c 100644 --- a/TeachingRecordSystem/src/TeachingRecordSystem.Api/V3/Core/SharedModels/AlertInfo.cs +++ b/TeachingRecordSystem/src/TeachingRecordSystem.Api/V3/Core/SharedModels/Alert.cs @@ -1,9 +1,9 @@ namespace TeachingRecordSystem.Api.V3.Core.SharedModels; -public record AlertInfo +public record Alert { + public required Guid AlertId { get; init; } public required AlertType AlertType { get; init; } - public required string DqtSanctionCode { get; init; } public required DateOnly? StartDate { get; init; } public required DateOnly? EndDate { get; init; } } diff --git a/TeachingRecordSystem/src/TeachingRecordSystem.Api/V3/Core/SharedModels/AlertCategory.cs b/TeachingRecordSystem/src/TeachingRecordSystem.Api/V3/Core/SharedModels/AlertCategory.cs new file mode 100644 index 000000000..4b68ab0b7 --- /dev/null +++ b/TeachingRecordSystem/src/TeachingRecordSystem.Api/V3/Core/SharedModels/AlertCategory.cs @@ -0,0 +1,7 @@ +namespace TeachingRecordSystem.Api.V3.Core.SharedModels; + +public record AlertCategory +{ + public required Guid AlertCategoryId { get; init; } + public required string Name { get; init; } +} diff --git a/TeachingRecordSystem/src/TeachingRecordSystem.Api/V3/Core/SharedModels/AlertType.cs b/TeachingRecordSystem/src/TeachingRecordSystem.Api/V3/Core/SharedModels/AlertType.cs index 31298b708..0b423f9c2 100644 --- a/TeachingRecordSystem/src/TeachingRecordSystem.Api/V3/Core/SharedModels/AlertType.cs +++ b/TeachingRecordSystem/src/TeachingRecordSystem.Api/V3/Core/SharedModels/AlertType.cs @@ -1,7 +1,9 @@ namespace TeachingRecordSystem.Api.V3.Core.SharedModels; -public enum AlertType +public record AlertType { - Prohibition, - // Only exposing Prohibitions for now + public required Guid AlertTypeId { get; init; } + public required AlertCategory AlertCategory { get; init; } + public required string Name { get; init; } + public required string DqtSanctionCode { get; init; } } diff --git a/TeachingRecordSystem/src/TeachingRecordSystem.Api/V3/V20240101/ApiModels/AlertInfo.cs b/TeachingRecordSystem/src/TeachingRecordSystem.Api/V3/V20240101/ApiModels/AlertInfo.cs index 626a07575..ebb22986f 100644 --- a/TeachingRecordSystem/src/TeachingRecordSystem.Api/V3/V20240101/ApiModels/AlertInfo.cs +++ b/TeachingRecordSystem/src/TeachingRecordSystem.Api/V3/V20240101/ApiModels/AlertInfo.cs @@ -1,6 +1,8 @@ +using TeachingRecordSystem.Api.V3.Core.SharedModels; + namespace TeachingRecordSystem.Api.V3.V20240101.ApiModels; -[AutoMap(typeof(Core.SharedModels.AlertInfo))] +[AutoMap(typeof(Alert), TypeConverter = typeof(AlertInfoTypeConverter))] public record AlertInfo { public required AlertType AlertType { get; init; } @@ -8,3 +10,15 @@ public record AlertInfo public required DateOnly? StartDate { get; init; } public required DateOnly? EndDate { get; init; } } + +public class AlertInfoTypeConverter : ITypeConverter +{ + public AlertInfo Convert(Alert source, AlertInfo destination, ResolutionContext context) => + new() + { + AlertType = AlertType.Prohibition, + DqtSanctionCode = source.AlertType.DqtSanctionCode, + StartDate = source.StartDate, + EndDate = source.EndDate, + }; +} diff --git a/TeachingRecordSystem/src/TeachingRecordSystem.Api/V3/V20240101/Controllers/TeacherController.cs b/TeachingRecordSystem/src/TeachingRecordSystem.Api/V3/V20240101/Controllers/TeacherController.cs index 54ca0f5be..dc23388bc 100644 --- a/TeachingRecordSystem/src/TeachingRecordSystem.Api/V3/V20240101/Controllers/TeacherController.cs +++ b/TeachingRecordSystem/src/TeachingRecordSystem.Api/V3/V20240101/Controllers/TeacherController.cs @@ -35,7 +35,8 @@ public async Task Get( var command = new GetPersonCommand( trn, include is not null ? (GetPersonCommandIncludes)include : GetPersonCommandIncludes.None, - DateOfBirth: null); + DateOfBirth: null, + ApplyLegacyAlertsBehavior: true); var result = await handler.Handle(command); diff --git a/TeachingRecordSystem/src/TeachingRecordSystem.Api/V3/V20240101/Controllers/TeachersController.cs b/TeachingRecordSystem/src/TeachingRecordSystem.Api/V3/V20240101/Controllers/TeachersController.cs index 364791766..beb16c68c 100644 --- a/TeachingRecordSystem/src/TeachingRecordSystem.Api/V3/V20240101/Controllers/TeachersController.cs +++ b/TeachingRecordSystem/src/TeachingRecordSystem.Api/V3/V20240101/Controllers/TeachersController.cs @@ -29,7 +29,8 @@ public async Task Get( var command = new GetPersonCommand( trn, include is not null ? (GetPersonCommandIncludes)include : GetPersonCommandIncludes.None, - DateOfBirth: null); + DateOfBirth: null, + ApplyLegacyAlertsBehavior: true); var result = await handler.Handle(command); diff --git a/TeachingRecordSystem/src/TeachingRecordSystem.Api/V3/V20240416/Controllers/TeacherController.cs b/TeachingRecordSystem/src/TeachingRecordSystem.Api/V3/V20240416/Controllers/TeacherController.cs index 62dd6e9a3..39a3cfd27 100644 --- a/TeachingRecordSystem/src/TeachingRecordSystem.Api/V3/V20240416/Controllers/TeacherController.cs +++ b/TeachingRecordSystem/src/TeachingRecordSystem.Api/V3/V20240416/Controllers/TeacherController.cs @@ -35,7 +35,8 @@ public async Task Get( var command = new GetPersonCommand( trn, include is not null ? (GetPersonCommandIncludes)include : GetPersonCommandIncludes.None, - DateOfBirth: null); + DateOfBirth: null, + ApplyLegacyAlertsBehavior: true); var result = await handler.Handle(command); diff --git a/TeachingRecordSystem/src/TeachingRecordSystem.Api/V3/V20240416/Controllers/TeachersController.cs b/TeachingRecordSystem/src/TeachingRecordSystem.Api/V3/V20240416/Controllers/TeachersController.cs index 1aedb52fc..2fad8b591 100644 --- a/TeachingRecordSystem/src/TeachingRecordSystem.Api/V3/V20240416/Controllers/TeachersController.cs +++ b/TeachingRecordSystem/src/TeachingRecordSystem.Api/V3/V20240416/Controllers/TeachersController.cs @@ -30,7 +30,8 @@ public async Task Get( var command = new GetPersonCommand( trn, include is not null ? (GetPersonCommandIncludes)include : GetPersonCommandIncludes.None, - dateOfBirth); + dateOfBirth, + ApplyLegacyAlertsBehavior: true); var result = await handler.Handle(command); diff --git a/TeachingRecordSystem/src/TeachingRecordSystem.Api/V3/V20240606/Controllers/PersonController.cs b/TeachingRecordSystem/src/TeachingRecordSystem.Api/V3/V20240606/Controllers/PersonController.cs index 1fd22d822..e8c38f137 100644 --- a/TeachingRecordSystem/src/TeachingRecordSystem.Api/V3/V20240606/Controllers/PersonController.cs +++ b/TeachingRecordSystem/src/TeachingRecordSystem.Api/V3/V20240606/Controllers/PersonController.cs @@ -28,11 +28,12 @@ public async Task Get( var command = new GetPersonCommand( Trn: User.FindFirstValue("trn")!, include is not null ? (GetPersonCommandIncludes)include : GetPersonCommandIncludes.None, - DateOfBirth: null); + DateOfBirth: null, + ApplyLegacyAlertsBehavior: true); var result = await handler.Handle(command); var response = mapper.Map(result); - return response is null ? Forbid() : Ok(result); + return response is null ? Forbid() : Ok(response); } [HttpPost("name-changes")] diff --git a/TeachingRecordSystem/src/TeachingRecordSystem.Api/V3/V20240606/Controllers/PersonsController.cs b/TeachingRecordSystem/src/TeachingRecordSystem.Api/V3/V20240606/Controllers/PersonsController.cs index 9a2c889c6..a2317fd60 100644 --- a/TeachingRecordSystem/src/TeachingRecordSystem.Api/V3/V20240606/Controllers/PersonsController.cs +++ b/TeachingRecordSystem/src/TeachingRecordSystem.Api/V3/V20240606/Controllers/PersonsController.cs @@ -30,7 +30,8 @@ public async Task Get( var command = new GetPersonCommand( trn, include is not null ? (GetPersonCommandIncludes)include : GetPersonCommandIncludes.None, - dateOfBirth); + dateOfBirth, + ApplyLegacyAlertsBehavior: true); var result = await handler.Handle(command); @@ -51,7 +52,7 @@ public async Task Get( [ProducesResponseType(typeof(FindPersonResponse), StatusCodes.Status200OK)] [ProducesResponseType(typeof(ProblemDetails), StatusCodes.Status400BadRequest)] [Authorize(Policy = AuthorizationPolicies.ApiKey, Roles = ApiRoles.GetPerson)] - public async Task FindTeachers( + public async Task FindPersons( FindPersonRequest request, [FromServices] FindPersonByLastNameAndDateOfBirthHandler handler) { diff --git a/TeachingRecordSystem/src/TeachingRecordSystem.Api/V3/V20240814/Controllers/PersonsController.cs b/TeachingRecordSystem/src/TeachingRecordSystem.Api/V3/V20240814/Controllers/PersonsController.cs index 84b610836..b6bb93915 100644 --- a/TeachingRecordSystem/src/TeachingRecordSystem.Api/V3/V20240814/Controllers/PersonsController.cs +++ b/TeachingRecordSystem/src/TeachingRecordSystem.Api/V3/V20240814/Controllers/PersonsController.cs @@ -19,7 +19,7 @@ public class PersonsController(IMapper mapper) : ControllerBase [ProducesResponseType(typeof(FindPersonsResponse), StatusCodes.Status200OK)] [ProducesResponseType(typeof(ProblemDetails), StatusCodes.Status400BadRequest)] [Authorize(Policy = AuthorizationPolicies.ApiKey, Roles = ApiRoles.GetPerson)] - public async Task FindTeachers( + public async Task FindPersons( [FromBody] FindPersonsRequest request, [FromServices] FindPersonsByTrnAndDateOfBirthHandler handler) { @@ -37,7 +37,7 @@ public async Task FindTeachers( [ProducesResponseType(typeof(FindPersonResponse), StatusCodes.Status200OK)] [ProducesResponseType(typeof(ProblemDetails), StatusCodes.Status400BadRequest)] [Authorize(Policy = AuthorizationPolicies.ApiKey, Roles = ApiRoles.GetPerson)] - public async Task FindTeachers( + public async Task FindPersons( FindPersonRequest request, [FromServices] FindPersonByLastNameAndDateOfBirthHandler handler) { diff --git a/TeachingRecordSystem/src/TeachingRecordSystem.Api/V3/VNext/ApiModels/Alert.cs b/TeachingRecordSystem/src/TeachingRecordSystem.Api/V3/VNext/ApiModels/Alert.cs index b5454a060..1fea1c96e 100644 --- a/TeachingRecordSystem/src/TeachingRecordSystem.Api/V3/VNext/ApiModels/Alert.cs +++ b/TeachingRecordSystem/src/TeachingRecordSystem.Api/V3/VNext/ApiModels/Alert.cs @@ -1,9 +1,10 @@ namespace TeachingRecordSystem.Api.V3.VNext.ApiModels; +[AutoMap(typeof(Core.SharedModels.Alert))] public record Alert { public required Guid AlertId { get; init; } - public required AlertTypeInfo AlertType { get; init; } + public required AlertType AlertType { get; init; } public required DateOnly? StartDate { get; init; } public required DateOnly? EndDate { get; init; } } diff --git a/TeachingRecordSystem/src/TeachingRecordSystem.Api/V3/VNext/ApiModels/AlertCategoryInfo.cs b/TeachingRecordSystem/src/TeachingRecordSystem.Api/V3/VNext/ApiModels/AlertCategory.cs similarity index 67% rename from TeachingRecordSystem/src/TeachingRecordSystem.Api/V3/VNext/ApiModels/AlertCategoryInfo.cs rename to TeachingRecordSystem/src/TeachingRecordSystem.Api/V3/VNext/ApiModels/AlertCategory.cs index db5bc625b..29d7622b0 100644 --- a/TeachingRecordSystem/src/TeachingRecordSystem.Api/V3/VNext/ApiModels/AlertCategoryInfo.cs +++ b/TeachingRecordSystem/src/TeachingRecordSystem.Api/V3/VNext/ApiModels/AlertCategory.cs @@ -1,6 +1,7 @@ namespace TeachingRecordSystem.Api.V3.VNext.ApiModels; -public record AlertCategoryInfo +[AutoMap(typeof(Core.SharedModels.AlertCategory))] +public record AlertCategory { public required Guid AlertCategoryId { get; init; } public required string Name { get; init; } diff --git a/TeachingRecordSystem/src/TeachingRecordSystem.Api/V3/VNext/ApiModels/AlertTypeInfo.cs b/TeachingRecordSystem/src/TeachingRecordSystem.Api/V3/VNext/ApiModels/AlertType.cs similarity index 54% rename from TeachingRecordSystem/src/TeachingRecordSystem.Api/V3/VNext/ApiModels/AlertTypeInfo.cs rename to TeachingRecordSystem/src/TeachingRecordSystem.Api/V3/VNext/ApiModels/AlertType.cs index 059caa74c..d437db788 100644 --- a/TeachingRecordSystem/src/TeachingRecordSystem.Api/V3/VNext/ApiModels/AlertTypeInfo.cs +++ b/TeachingRecordSystem/src/TeachingRecordSystem.Api/V3/VNext/ApiModels/AlertType.cs @@ -1,8 +1,9 @@ namespace TeachingRecordSystem.Api.V3.VNext.ApiModels; -public record AlertTypeInfo +[AutoMap(typeof(Core.SharedModels.AlertType))] +public record AlertType { public required Guid AlertTypeId { get; init; } - public required AlertCategoryInfo AlertCategory { get; init; } + public required AlertCategory AlertCategory { get; init; } public required string Name { get; init; } } diff --git a/TeachingRecordSystem/src/TeachingRecordSystem.Api/V3/VNext/Controllers/PersonController.cs b/TeachingRecordSystem/src/TeachingRecordSystem.Api/V3/VNext/Controllers/PersonController.cs index 99c807914..e529d3d9f 100644 --- a/TeachingRecordSystem/src/TeachingRecordSystem.Api/V3/VNext/Controllers/PersonController.cs +++ b/TeachingRecordSystem/src/TeachingRecordSystem.Api/V3/VNext/Controllers/PersonController.cs @@ -28,10 +28,11 @@ public async Task Get( var command = new GetPersonCommand( Trn: User.FindFirstValue("trn")!, include is not null ? (GetPersonCommandIncludes)include : GetPersonCommandIncludes.None, - DateOfBirth: null); + DateOfBirth: null, + ApplyLegacyAlertsBehavior: false); var result = await handler.Handle(command); var response = mapper.Map(result); - return response is null ? Forbid() : Ok(result); + return response is null ? Forbid() : Ok(response); } } diff --git a/TeachingRecordSystem/src/TeachingRecordSystem.Api/V3/VNext/Controllers/PersonsController.cs b/TeachingRecordSystem/src/TeachingRecordSystem.Api/V3/VNext/Controllers/PersonsController.cs index 1dd2f85d1..bef060061 100644 --- a/TeachingRecordSystem/src/TeachingRecordSystem.Api/V3/VNext/Controllers/PersonsController.cs +++ b/TeachingRecordSystem/src/TeachingRecordSystem.Api/V3/VNext/Controllers/PersonsController.cs @@ -82,7 +82,8 @@ public async Task Get( var command = new GetPersonCommand( trn, (GetPersonCommandIncludes)include, - dateOfBirth); + dateOfBirth, + ApplyLegacyAlertsBehavior: false); var result = await handler.Handle(command); @@ -94,4 +95,47 @@ public async Task Get( var response = mapper.Map(result); return Ok(response); } + + [HttpPost("find")] + [SwaggerOperation( + OperationId = "FindPersons", + Summary = "Find persons", + Description = "Finds persons matching the specified criteria.")] + [ProducesResponseType(typeof(FindPersonsResponse), StatusCodes.Status200OK)] + [ProducesResponseType(typeof(ProblemDetails), StatusCodes.Status400BadRequest)] + [Authorize(Policy = AuthorizationPolicies.ApiKey, Roles = ApiRoles.GetPerson)] + public async Task FindPersons( + [FromBody] FindPersonsRequest request, + [FromServices] FindPersonsByTrnAndDateOfBirthHandler handler) + { + var command = new FindPersonsByTrnAndDateOfBirthCommand(request.Persons.Select(p => (p.Trn, p.DateOfBirth))); + var result = await handler.Handle(command); + var response = mapper.Map(result); + return Ok(response); + } + + [HttpGet("")] + [SwaggerOperation( + OperationId = "FindPerson", + Summary = "Find person", + Description = "Finds a person matching the specified criteria.")] + [ProducesResponseType(typeof(FindPersonResponse), StatusCodes.Status200OK)] + [ProducesResponseType(typeof(ProblemDetails), StatusCodes.Status400BadRequest)] + [Authorize(Policy = AuthorizationPolicies.ApiKey, Roles = ApiRoles.GetPerson)] + public async Task FindPersons( + FindPersonRequest request, + [FromServices] FindPersonByLastNameAndDateOfBirthHandler handler) + { + var command = new FindPersonByLastNameAndDateOfBirthCommand(request.LastName!, request.DateOfBirth!.Value); + var result = await handler.Handle(command); + + var response = new FindPersonResponse() + { + Total = result.Total, + Query = request, + Results = result.Items.Select(mapper.Map).AsReadOnly() + }; + + return Ok(response); + } } diff --git a/TeachingRecordSystem/src/TeachingRecordSystem.Api/V3/VNext/Requests/FindPersonRequest.cs b/TeachingRecordSystem/src/TeachingRecordSystem.Api/V3/VNext/Requests/FindPersonRequest.cs new file mode 100644 index 000000000..83f6d9a21 --- /dev/null +++ b/TeachingRecordSystem/src/TeachingRecordSystem.Api/V3/VNext/Requests/FindPersonRequest.cs @@ -0,0 +1,18 @@ +using Microsoft.AspNetCore.Mvc; + +namespace TeachingRecordSystem.Api.V3.VNext.Requests; + +public record FindPersonRequest +{ + [FromQuery(Name = "findBy")] + public FindPersonFindBy FindBy { get; init; } + [FromQuery(Name = "lastName")] + public string? LastName { get; init; } + [FromQuery(Name = "dateOfBirth")] + public DateOnly? DateOfBirth { get; init; } +} + +public enum FindPersonFindBy +{ + LastNameAndDateOfBirth = 1 +} diff --git a/TeachingRecordSystem/src/TeachingRecordSystem.Api/V3/VNext/Requests/FindPersonsRequest.cs b/TeachingRecordSystem/src/TeachingRecordSystem.Api/V3/VNext/Requests/FindPersonsRequest.cs new file mode 100644 index 000000000..cbc1940d8 --- /dev/null +++ b/TeachingRecordSystem/src/TeachingRecordSystem.Api/V3/VNext/Requests/FindPersonsRequest.cs @@ -0,0 +1,12 @@ +namespace TeachingRecordSystem.Api.V3.VNext.Requests; + +public record FindPersonsRequest +{ + public required IReadOnlyCollection Persons { get; init; } +} + +public record FindPersonsRequestPerson +{ + public required string Trn { get; init; } + public required DateOnly DateOfBirth { get; init; } +} diff --git a/TeachingRecordSystem/src/TeachingRecordSystem.Api/V3/VNext/Responses/FindPersonResponse.cs b/TeachingRecordSystem/src/TeachingRecordSystem.Api/V3/VNext/Responses/FindPersonResponse.cs new file mode 100644 index 000000000..3e8222b54 --- /dev/null +++ b/TeachingRecordSystem/src/TeachingRecordSystem.Api/V3/VNext/Responses/FindPersonResponse.cs @@ -0,0 +1,19 @@ +using TeachingRecordSystem.Api.V3.Core.Operations; +using TeachingRecordSystem.Api.V3.VNext.ApiModels; +using TeachingRecordSystem.Api.V3.VNext.Requests; + +namespace TeachingRecordSystem.Api.V3.VNext.Responses; + +[GenerateVersionedDto(typeof(V20240814.Responses.FindPersonResponse), excludeMembers: ["Query", "Results"])] +public partial record FindPersonResponse +{ + public required FindPersonRequest Query { get; init; } + public required IReadOnlyCollection Results { get; init; } +} + +[AutoMap(typeof(FindPersonByLastNameAndDateOfBirthResultItem))] +[GenerateVersionedDto(typeof(V20240814.Responses.FindPersonResponseResult), excludeMembers: ["Sanctions"])] +public partial record FindPersonResponseResult +{ + public required IReadOnlyCollection Alerts { get; init; } +} diff --git a/TeachingRecordSystem/src/TeachingRecordSystem.Api/V3/VNext/Responses/FindPersonsResponse.cs b/TeachingRecordSystem/src/TeachingRecordSystem.Api/V3/VNext/Responses/FindPersonsResponse.cs new file mode 100644 index 000000000..a1f9c6083 --- /dev/null +++ b/TeachingRecordSystem/src/TeachingRecordSystem.Api/V3/VNext/Responses/FindPersonsResponse.cs @@ -0,0 +1,20 @@ +using AutoMapper.Configuration.Annotations; +using TeachingRecordSystem.Api.V3.Core.Operations; +using TeachingRecordSystem.Api.V3.VNext.ApiModels; + +namespace TeachingRecordSystem.Api.V3.VNext.Responses; + +[AutoMap(typeof(FindPersonsByTrnAndDateOfBirthResult))] +[GenerateVersionedDto(typeof(V20240814.Responses.FindPersonsResponse), excludeMembers: ["Results"])] +public partial record FindPersonsResponse +{ + [SourceMember(nameof(FindPersonsByTrnAndDateOfBirthResult.Items))] + public required IReadOnlyCollection Results { get; init; } +} + +[AutoMap(typeof(FindPersonsByTrnAndDateOfBirthResultItem))] +[GenerateVersionedDto(typeof(V20240814.Responses.FindPersonsResponseResult), excludeMembers: ["Sanctions"])] +public partial record FindPersonsResponseResult +{ + public required IReadOnlyCollection Alerts { get; init; } +} diff --git a/TeachingRecordSystem/src/TeachingRecordSystem.Api/V3/VNext/Responses/GetPersonResponse.cs b/TeachingRecordSystem/src/TeachingRecordSystem.Api/V3/VNext/Responses/GetPersonResponse.cs index effc13fc9..b677340aa 100644 --- a/TeachingRecordSystem/src/TeachingRecordSystem.Api/V3/VNext/Responses/GetPersonResponse.cs +++ b/TeachingRecordSystem/src/TeachingRecordSystem.Api/V3/VNext/Responses/GetPersonResponse.cs @@ -1,7 +1,12 @@ +using Optional; using TeachingRecordSystem.Api.V3.Core.Operations; +using TeachingRecordSystem.Api.V3.VNext.ApiModels; namespace TeachingRecordSystem.Api.V3.VNext.Responses; [AutoMap(typeof(GetPersonResult))] -[GenerateVersionedDto(typeof(V20240606.Responses.GetPersonResponse))] -public partial record GetPersonResponse; +[GenerateVersionedDto(typeof(V20240606.Responses.GetPersonResponse), excludeMembers: ["Alerts", "Sanctions"])] +public partial record GetPersonResponse +{ + public required Option> Alerts { get; init; } +} diff --git a/TeachingRecordSystem/src/TeachingRecordSystem.Core/AsyncEnumerableExtensions.cs b/TeachingRecordSystem/src/TeachingRecordSystem.Core/AsyncEnumerableExtensions.cs index 03779e8ed..339177634 100644 --- a/TeachingRecordSystem/src/TeachingRecordSystem.Core/AsyncEnumerableExtensions.cs +++ b/TeachingRecordSystem/src/TeachingRecordSystem.Core/AsyncEnumerableExtensions.cs @@ -2,6 +2,8 @@ namespace TeachingRecordSystem.Core; public static class AsyncEnumerableExtensions { + public static async ValueTask> AsReadOnlyAsync(this IAsyncEnumerable enumerable) => await enumerable.ToArrayAsync(); + public static async IAsyncEnumerable Chunk(this IAsyncEnumerable source, int size) { ArgumentOutOfRangeException.ThrowIfLessThanOrEqual(size, 0); diff --git a/TeachingRecordSystem/src/TeachingRecordSystem.Core/ReferenceDataCache.cs b/TeachingRecordSystem/src/TeachingRecordSystem.Core/ReferenceDataCache.cs index 35ef0eeac..75452a591 100644 --- a/TeachingRecordSystem/src/TeachingRecordSystem.Core/ReferenceDataCache.cs +++ b/TeachingRecordSystem/src/TeachingRecordSystem.Core/ReferenceDataCache.cs @@ -172,6 +172,12 @@ public async Task GetAlertTypes() return alertTypes; } + public async Task GetAlertTypeByDqtSanctionCode(string dqtSanctionCode) + { + var alertTypes = await EnsureAlertTypes(); + return alertTypes.Single(at => at.DqtSanctionCode == dqtSanctionCode, $"Could not find alert type with DQT sanction code: '{dqtSanctionCode}'."); + } + private Task EnsureSanctionCodes() => LazyInitializer.EnsureInitialized( ref _getSanctionCodesTask, diff --git a/TeachingRecordSystem/tests/TeachingRecordSystem.Api.Tests/TestBase.cs b/TeachingRecordSystem/tests/TeachingRecordSystem.Api.Tests/TestBase.cs index 7ba5c323d..da103715c 100644 --- a/TeachingRecordSystem/tests/TeachingRecordSystem.Api.Tests/TestBase.cs +++ b/TeachingRecordSystem/tests/TeachingRecordSystem.Api.Tests/TestBase.cs @@ -36,6 +36,8 @@ protected TestBase(HostFixture hostFixture) public Mock GetAnIdentityApiClientMock => _testServices.GetAnIdentityApiClientMock; + public ReferenceDataCache ReferenceDataCache => HostFixture.Services.GetRequiredService(); + public TestData TestData => HostFixture.Services.GetRequiredService(); public IXrmFakedContext XrmFakedContext => HostFixture.Services.GetRequiredService(); diff --git a/TeachingRecordSystem/tests/TeachingRecordSystem.Api.Tests/V3/V20240101/FindTeachersTests.cs b/TeachingRecordSystem/tests/TeachingRecordSystem.Api.Tests/V3/V20240101/FindTeachersTests.cs index a195c310e..579b07674 100644 --- a/TeachingRecordSystem/tests/TeachingRecordSystem.Api.Tests/V3/V20240101/FindTeachersTests.cs +++ b/TeachingRecordSystem/tests/TeachingRecordSystem.Api.Tests/V3/V20240101/FindTeachersTests.cs @@ -237,7 +237,7 @@ public async Task Get_NonExposableSanctionCode_IsNotReturned() var dateOfBirth = new DateOnly(1990, 1, 1); var sanctionCode = "A17"; - Debug.Assert(!TeachingRecordSystem.Api.V3.Constants.ExposableSanctionCodes.Contains(sanctionCode)); + Debug.Assert(!TeachingRecordSystem.Api.V3.Constants.LegacyExposableSanctionCodes.Contains(sanctionCode)); var person = await TestData.CreatePerson(b => b.WithLastName(lastName).WithDateOfBirth(dateOfBirth).WithSanction(sanctionCode)); var request = new HttpRequestMessage( diff --git a/TeachingRecordSystem/tests/TeachingRecordSystem.Api.Tests/V3/V20240101/GetTeacherTestBase.cs b/TeachingRecordSystem/tests/TeachingRecordSystem.Api.Tests/V3/V20240101/GetTeacherTestBase.cs index b39a71822..e5be392b3 100644 --- a/TeachingRecordSystem/tests/TeachingRecordSystem.Api.Tests/V3/V20240101/GetTeacherTestBase.cs +++ b/TeachingRecordSystem/tests/TeachingRecordSystem.Api.Tests/V3/V20240101/GetTeacherTestBase.cs @@ -414,7 +414,7 @@ protected async Task ValidRequestWithSanctions_ReturnsExpectedSanctionsContent( new("A18", null), new("G1", new DateOnly(2022, 4, 1)), }; - Debug.Assert(sanctions.Select(s => s.SanctionCode).All(TeachingRecordSystem.Api.V3.Constants.ExposableSanctionCodes.Contains)); + Debug.Assert(sanctions.Select(s => s.SanctionCode).All(TeachingRecordSystem.Api.V3.Constants.LegacyExposableSanctionCodes.Contains)); await ConfigureMocks(contact, sanctions: sanctions); @@ -455,7 +455,7 @@ protected async Task ValidRequestWithAlerts_ReturnsExpectedSanctionsContent( new("B1", null), new("G1", new DateOnly(2022, 4, 1)), }; - Debug.Assert(sanctions.Select(s => s.SanctionCode).All(TeachingRecordSystem.Api.V3.Constants.ProhibitionSanctionCodes.Contains)); + Debug.Assert(sanctions.Select(s => s.SanctionCode).All(TeachingRecordSystem.Api.V3.Constants.LegacyProhibitionSanctionCodes.Contains)); await ConfigureMocks(contact, sanctions: sanctions); diff --git a/TeachingRecordSystem/tests/TeachingRecordSystem.Api.Tests/V3/V20240606/FindPersonByLastNameAndDateOfBirthTests.cs b/TeachingRecordSystem/tests/TeachingRecordSystem.Api.Tests/V3/V20240606/FindPersonByLastNameAndDateOfBirthTests.cs index b94058f84..7845277e8 100644 --- a/TeachingRecordSystem/tests/TeachingRecordSystem.Api.Tests/V3/V20240606/FindPersonByLastNameAndDateOfBirthTests.cs +++ b/TeachingRecordSystem/tests/TeachingRecordSystem.Api.Tests/V3/V20240606/FindPersonByLastNameAndDateOfBirthTests.cs @@ -237,7 +237,7 @@ public async Task Get_NonExposableSanctionCode_IsNotReturned() var dateOfBirth = new DateOnly(1990, 1, 1); var sanctionCode = "A17"; - Debug.Assert(!Api.V3.Constants.ExposableSanctionCodes.Contains(sanctionCode)); + Debug.Assert(!Api.V3.Constants.LegacyExposableSanctionCodes.Contains(sanctionCode)); var person = await TestData.CreatePerson(b => b.WithLastName(lastName).WithDateOfBirth(dateOfBirth).WithSanction(sanctionCode)); var request = new HttpRequestMessage( diff --git a/TeachingRecordSystem/tests/TeachingRecordSystem.Api.Tests/V3/V20240606/GetPersonTestBase.cs b/TeachingRecordSystem/tests/TeachingRecordSystem.Api.Tests/V3/V20240606/GetPersonTestBase.cs index 090a60ec8..fa17d8763 100644 --- a/TeachingRecordSystem/tests/TeachingRecordSystem.Api.Tests/V3/V20240606/GetPersonTestBase.cs +++ b/TeachingRecordSystem/tests/TeachingRecordSystem.Api.Tests/V3/V20240606/GetPersonTestBase.cs @@ -414,7 +414,7 @@ protected async Task ValidRequestWithSanctions_ReturnsExpectedSanctionsContent( new("A18", null), new("G1", new DateOnly(2022, 4, 1)), }; - Debug.Assert(sanctions.Select(s => s.SanctionCode).All(Api.V3.Constants.ExposableSanctionCodes.Contains)); + Debug.Assert(sanctions.Select(s => s.SanctionCode).All(Api.V3.Constants.LegacyExposableSanctionCodes.Contains)); await ConfigureMocks(contact, sanctions: sanctions); @@ -455,7 +455,7 @@ protected async Task ValidRequestWithAlerts_ReturnsExpectedSanctionsContent( new("B1", null), new("G1", new DateOnly(2022, 4, 1)), }; - Debug.Assert(sanctions.Select(s => s.SanctionCode).All(Api.V3.Constants.ProhibitionSanctionCodes.Contains)); + Debug.Assert(sanctions.Select(s => s.SanctionCode).All(Api.V3.Constants.LegacyProhibitionSanctionCodes.Contains)); await ConfigureMocks(contact, sanctions: sanctions); diff --git a/TeachingRecordSystem/tests/TeachingRecordSystem.Api.Tests/V3/V20240814/FindPersonByLastNameAndDateOfBirthTests.cs b/TeachingRecordSystem/tests/TeachingRecordSystem.Api.Tests/V3/V20240814/FindPersonByLastNameAndDateOfBirthTests.cs index 4620feb2d..68cb146e6 100644 --- a/TeachingRecordSystem/tests/TeachingRecordSystem.Api.Tests/V3/V20240814/FindPersonByLastNameAndDateOfBirthTests.cs +++ b/TeachingRecordSystem/tests/TeachingRecordSystem.Api.Tests/V3/V20240814/FindPersonByLastNameAndDateOfBirthTests.cs @@ -229,7 +229,7 @@ public async Task Get_NonExposableSanctionCode_IsNotReturned() var dateOfBirth = new DateOnly(1990, 1, 1); var sanctionCode = "A17"; - Debug.Assert(!Api.V3.Constants.ExposableSanctionCodes.Contains(sanctionCode)); + Debug.Assert(!Api.V3.Constants.LegacyExposableSanctionCodes.Contains(sanctionCode)); var person = await TestData.CreatePerson(b => b.WithLastName(lastName).WithDateOfBirth(dateOfBirth).WithSanction(sanctionCode)); var request = new HttpRequestMessage( diff --git a/TeachingRecordSystem/tests/TeachingRecordSystem.Api.Tests/V3/V20240814/FindPersonsByTrnAndDateOfBirthTests.cs b/TeachingRecordSystem/tests/TeachingRecordSystem.Api.Tests/V3/V20240814/FindPersonsByTrnAndDateOfBirthTests.cs index 1b7e74a93..2f21c05e1 100644 --- a/TeachingRecordSystem/tests/TeachingRecordSystem.Api.Tests/V3/V20240814/FindPersonsByTrnAndDateOfBirthTests.cs +++ b/TeachingRecordSystem/tests/TeachingRecordSystem.Api.Tests/V3/V20240814/FindPersonsByTrnAndDateOfBirthTests.cs @@ -196,7 +196,7 @@ public async Task Get_NonExposableSanctionCode_IsNotReturned() var dateOfBirth = new DateOnly(1990, 1, 1); var sanctionCode = "A17"; - Debug.Assert(!Api.V3.Constants.ExposableSanctionCodes.Contains(sanctionCode)); + Debug.Assert(!Api.V3.Constants.LegacyExposableSanctionCodes.Contains(sanctionCode)); var person = await TestData.CreatePerson(b => b .WithDateOfBirth(dateOfBirth) .WithSanction(sanctionCode)); diff --git a/TeachingRecordSystem/tests/TeachingRecordSystem.Api.Tests/V3/VNext/FindPersonByLastNameAndDateOfBirthTests.cs b/TeachingRecordSystem/tests/TeachingRecordSystem.Api.Tests/V3/VNext/FindPersonByLastNameAndDateOfBirthTests.cs new file mode 100644 index 000000000..d094ad78e --- /dev/null +++ b/TeachingRecordSystem/tests/TeachingRecordSystem.Api.Tests/V3/VNext/FindPersonByLastNameAndDateOfBirthTests.cs @@ -0,0 +1,76 @@ +namespace TeachingRecordSystem.Api.Tests.V3.VNext; + +[Collection(nameof(DisableParallelization))] +public class FindPersonByLastNameAndDateOfBirthTests : TestBase +{ + public FindPersonByLastNameAndDateOfBirthTests(HostFixture hostFixture) : base(hostFixture) + { + XrmFakedContext.DeleteAllEntities(); + SetCurrentApiClient([ApiRoles.GetPerson]); + } + + [Fact] + public async Task Get_ValidRequestWithMatchOnPersonWithAlerts_ReturnsExpectedAlertsContent() + { + // Arrange + var lastName = "Smith"; + var dateOfBirth = new DateOnly(1990, 1, 1); + + var sanctionCode = "G1"; + var startDate = new DateOnly(2022, 4, 1); + var endDate = new DateOnly(2023, 1, 20); + var alertType = await ReferenceDataCache.GetAlertTypeByDqtSanctionCode(sanctionCode); + var alertCategory = await ReferenceDataCache.GetAlertCategoryById(alertType.AlertCategoryId); + + var person = await TestData.CreatePerson(b => b + .WithLastName(lastName) + .WithDateOfBirth(dateOfBirth) + .WithSanction(sanctionCode, startDate, endDate)); + + var sanction = person.Sanctions.Single(); + + var request = new HttpRequestMessage(HttpMethod.Post, $"/v3/persons/find") + { + Content = JsonContent.Create(new + { + persons = new[] + { + new + { + trn = person.Trn, + dateOfBirth = person.DateOfBirth + } + } + }) + }; + + // Act + var response = await GetHttpClientWithApiKey().SendAsync(request); + + // Assert + var jsonResponse = await AssertEx.JsonResponse(response); + var responseAlerts = jsonResponse.RootElement.GetProperty("results").EnumerateArray().Single().GetProperty("alerts"); + + AssertEx.JsonObjectEquals( + new[] + { + new + { + alertId = sanction.SanctionId, + alertType = new + { + alertTypeId = alertType.AlertTypeId, + name = alertType.Name, + alertCategory = new + { + alertCategoryId = alertCategory.AlertCategoryId, + name = alertCategory.Name + } + }, + startDate = startDate, + endDate = endDate, + } + }, + responseAlerts); + } +} diff --git a/TeachingRecordSystem/tests/TeachingRecordSystem.Api.Tests/V3/VNext/FindPersonsByTrnAndDateOfBirthTests.cs b/TeachingRecordSystem/tests/TeachingRecordSystem.Api.Tests/V3/VNext/FindPersonsByTrnAndDateOfBirthTests.cs new file mode 100644 index 000000000..00e35a161 --- /dev/null +++ b/TeachingRecordSystem/tests/TeachingRecordSystem.Api.Tests/V3/VNext/FindPersonsByTrnAndDateOfBirthTests.cs @@ -0,0 +1,66 @@ +namespace TeachingRecordSystem.Api.Tests.V3.VNext; + +[Collection(nameof(DisableParallelization))] +public class FindPersonsByTrnAndDateOfBirthTests : TestBase +{ + public FindPersonsByTrnAndDateOfBirthTests(HostFixture hostFixture) : base(hostFixture) + { + XrmFakedContext.DeleteAllEntities(); + SetCurrentApiClient([ApiRoles.GetPerson]); + } + + [Fact] + public async Task Get_ValidRequestWithMatchOnPersonWithAlerts_ReturnsExpectedAlertsContent() + { + // Arrange + var findBy = "LastNameAndDateOfBirth"; + var lastName = "Smith"; + var dateOfBirth = new DateOnly(1990, 1, 1); + + var sanctionCode = "G1"; + var startDate = new DateOnly(2022, 4, 1); + var endDate = new DateOnly(2023, 1, 20); + var alertType = await ReferenceDataCache.GetAlertTypeByDqtSanctionCode(sanctionCode); + var alertCategory = await ReferenceDataCache.GetAlertCategoryById(alertType.AlertCategoryId); + + var person = await TestData.CreatePerson(b => b + .WithLastName(lastName) + .WithDateOfBirth(dateOfBirth) + .WithSanction(sanctionCode, startDate, endDate)); + + var sanction = person.Sanctions.Single(); + + var request = new HttpRequestMessage( + HttpMethod.Get, + $"/v3/persons?findBy={findBy}&lastName={lastName}&dateOfBirth={dateOfBirth:yyyy-MM-dd}"); + + // Act + var response = await GetHttpClientWithApiKey().SendAsync(request); + + // Assert + var jsonResponse = await AssertEx.JsonResponse(response); + var responseAlerts = jsonResponse.RootElement.GetProperty("results").EnumerateArray().Single().GetProperty("alerts"); + + AssertEx.JsonObjectEquals( + new[] + { + new + { + alertId = sanction.SanctionId, + alertType = new + { + alertTypeId = alertType.AlertTypeId, + name = alertType.Name, + alertCategory = new + { + alertCategoryId = alertCategory.AlertCategoryId, + name = alertCategory.Name + } + }, + startDate = startDate, + endDate = endDate, + } + }, + responseAlerts); + } +} diff --git a/TeachingRecordSystem/tests/TeachingRecordSystem.Api.Tests/V3/VNext/GetPersonByTrnTests.cs b/TeachingRecordSystem/tests/TeachingRecordSystem.Api.Tests/V3/VNext/GetPersonByTrnTests.cs new file mode 100644 index 000000000..9471bc7d0 --- /dev/null +++ b/TeachingRecordSystem/tests/TeachingRecordSystem.Api.Tests/V3/VNext/GetPersonByTrnTests.cs @@ -0,0 +1,137 @@ +using TeachingRecordSystem.Api.V3.VNext.Requests; + +namespace TeachingRecordSystem.Api.Tests.V3.VNext; + +public class GetPersonByTrnTests : TestBase +{ + public GetPersonByTrnTests(HostFixture hostFixture) + : base(hostFixture) + { + SetCurrentApiClient(roles: [ApiRoles.GetPerson]); + } + + [Theory, RoleNamesData(except: [ApiRoles.GetPerson, ApiRoles.AppropriateBody])] + public async Task Get_ClientDoesNotHavePermission_ReturnsForbidden(string[] roles) + { + // Arrange + SetCurrentApiClient(roles); + + var person = await TestData.CreatePerson(x => x.WithTrn()); + + var request = new HttpRequestMessage(HttpMethod.Get, $"/v3/persons/{person.Trn}?dateOfBirth={person.DateOfBirth:yyyy-MM-dd}"); + + // Act + var response = await GetHttpClientWithApiKey().SendAsync(request); + + // Assert + Assert.Equal(StatusCodes.Status403Forbidden, (int)response.StatusCode); + } + + [Theory] + [InlineData(GetPersonRequestIncludes.InitialTeacherTraining)] + [InlineData(GetPersonRequestIncludes.NpqQualifications)] + [InlineData(GetPersonRequestIncludes.MandatoryQualifications)] + [InlineData(GetPersonRequestIncludes.PendingDetailChanges)] + [InlineData(GetPersonRequestIncludes.HigherEducationQualifications)] + [InlineData(GetPersonRequestIncludes.PreviousNames)] + [InlineData(GetPersonRequestIncludes._AllowIdSignInWithProhibitions)] + public async Task Get_AsAppropriateBodyWithNotPermittedInclude_ReturnsForbidden(GetPersonRequestIncludes include) + { + // Arrange + SetCurrentApiClient(roles: [ApiRoles.AppropriateBody]); + + var person = await TestData.CreatePerson(x => x.WithTrn()); + + var request = new HttpRequestMessage(HttpMethod.Get, $"/v3/persons/{person.Trn}?dateOfBirth={person.DateOfBirth:yyyy-MM-dd}&include={Uri.EscapeDataString(include.ToString())}"); + + // Act + var response = await GetHttpClientWithApiKey().SendAsync(request); + + // Assert + Assert.Equal(StatusCodes.Status403Forbidden, (int)response.StatusCode); + } + + [Theory] + [InlineData(GetPersonRequestIncludes.Induction)] + [InlineData(GetPersonRequestIncludes.Alerts)] + public async Task Get_AsAppropriateBodyWithPermittedInclude_ReturnsOk(GetPersonRequestIncludes include) + { + // Arrange + SetCurrentApiClient(roles: [ApiRoles.AppropriateBody]); + + var person = await TestData.CreatePerson(x => x.WithTrn()); + + var request = new HttpRequestMessage(HttpMethod.Get, $"/v3/persons/{person.Trn}?dateOfBirth={person.DateOfBirth:yyyy-MM-dd}&include={Uri.EscapeDataString(include.ToString())}"); + + // Act + var response = await GetHttpClientWithApiKey().SendAsync(request); + + // Assert + Assert.Equal(StatusCodes.Status200OK, (int)response.StatusCode); + } + + [Fact] + public async Task Get_AsAppropriateBodyWithoutDateOfBirth_ReturnsForbidden() + { + // Arrange + SetCurrentApiClient(roles: [ApiRoles.AppropriateBody]); + + var person = await TestData.CreatePerson(x => x.WithTrn()); + + var request = new HttpRequestMessage(HttpMethod.Get, $"/v3/persons/{person.Trn}"); + + // Act + var response = await GetHttpClientWithApiKey().SendAsync(request); + + // Assert + Assert.Equal(StatusCodes.Status403Forbidden, (int)response.StatusCode); + } + + [Fact] + public async Task Get_ValidRequest_ReturnsExpectedAlertsContent() + { + // Arrange + var sanctionCode = "G1"; + var startDate = new DateOnly(2022, 4, 1); + var endDate = new DateOnly(2023, 1, 20); + var alertType = await ReferenceDataCache.GetAlertTypeByDqtSanctionCode(sanctionCode); + var alertCategory = await ReferenceDataCache.GetAlertCategoryById(alertType.AlertCategoryId); + + var person = await TestData.CreatePerson(x => x + .WithTrn() + .WithSanction(sanctionCode, startDate, endDate)); + + var sanction = person.Sanctions.Single(); + + var request = new HttpRequestMessage(HttpMethod.Get, $"/v3/persons/{person.Trn}?include=Alerts"); + + // Act + var response = await GetHttpClientWithApiKey().SendAsync(request); + + // Assert + var jsonResponse = await AssertEx.JsonResponse(response); + var responseAlerts = jsonResponse.RootElement.GetProperty("alerts"); + + AssertEx.JsonObjectEquals( + new[] + { + new + { + alertId = sanction.SanctionId, + alertType = new + { + alertTypeId = alertType.AlertTypeId, + name = alertType.Name, + alertCategory = new + { + alertCategoryId = alertCategory.AlertCategoryId, + name = alertCategory.Name + } + }, + startDate = startDate, + endDate = endDate, + } + }, + responseAlerts); + } +} diff --git a/TeachingRecordSystem/tests/TeachingRecordSystem.Api.Tests/V3/VNext/GetPersonTests.cs b/TeachingRecordSystem/tests/TeachingRecordSystem.Api.Tests/V3/VNext/GetPersonTests.cs index 7122de55b..41b94ab23 100644 --- a/TeachingRecordSystem/tests/TeachingRecordSystem.Api.Tests/V3/VNext/GetPersonTests.cs +++ b/TeachingRecordSystem/tests/TeachingRecordSystem.Api.Tests/V3/VNext/GetPersonTests.cs @@ -1,89 +1,54 @@ -using TeachingRecordSystem.Api.V3.VNext.Requests; - namespace TeachingRecordSystem.Api.Tests.V3.VNext; -public class GetPersonTests : TestBase +public class GetPersonTests(HostFixture hostFixture) : TestBase(hostFixture) { - public GetPersonTests(HostFixture hostFixture) - : base(hostFixture) - { - SetCurrentApiClient(roles: [ApiRoles.GetPerson]); - } - - [Theory, RoleNamesData(except: [ApiRoles.GetPerson, ApiRoles.AppropriateBody])] - public async Task Get_ClientDoesNotHavePermission_ReturnsForbidden(string[] roles) - { - // Arrange - SetCurrentApiClient(roles); - - var person = await TestData.CreatePerson(x => x.WithTrn()); - - var request = new HttpRequestMessage(HttpMethod.Get, $"/v3/persons/{person.Trn}?dateOfBirth={person.DateOfBirth:yyyy-MM-dd}"); - - // Act - var response = await GetHttpClientWithApiKey().SendAsync(request); - - // Assert - Assert.Equal(StatusCodes.Status403Forbidden, (int)response.StatusCode); - } - - [Theory] - [InlineData(GetPersonRequestIncludes.InitialTeacherTraining)] - [InlineData(GetPersonRequestIncludes.NpqQualifications)] - [InlineData(GetPersonRequestIncludes.MandatoryQualifications)] - [InlineData(GetPersonRequestIncludes.PendingDetailChanges)] - [InlineData(GetPersonRequestIncludes.HigherEducationQualifications)] - [InlineData(GetPersonRequestIncludes.PreviousNames)] - [InlineData(GetPersonRequestIncludes._AllowIdSignInWithProhibitions)] - public async Task Get_AsAppropriateBodyWithNotPermittedInclude_ReturnsForbidden(GetPersonRequestIncludes include) - { - // Arrange - SetCurrentApiClient(roles: [ApiRoles.AppropriateBody]); - - var person = await TestData.CreatePerson(x => x.WithTrn()); - - var request = new HttpRequestMessage(HttpMethod.Get, $"/v3/persons/{person.Trn}?dateOfBirth={person.DateOfBirth:yyyy-MM-dd}&include={Uri.EscapeDataString(include.ToString())}"); - - // Act - var response = await GetHttpClientWithApiKey().SendAsync(request); - - // Assert - Assert.Equal(StatusCodes.Status403Forbidden, (int)response.StatusCode); - } - - [Theory] - [InlineData(GetPersonRequestIncludes.Induction)] - [InlineData(GetPersonRequestIncludes.Alerts)] - public async Task Get_AsAppropriateBodyWithPermittedInclude_ReturnsOk(GetPersonRequestIncludes include) + [Fact] + public async Task Get_ValidRequestWithAlerts_ReturnsExpectedAlertsContent() { // Arrange - SetCurrentApiClient(roles: [ApiRoles.AppropriateBody]); - - var person = await TestData.CreatePerson(x => x.WithTrn()); + var sanctionCode = "G1"; + var startDate = new DateOnly(2022, 4, 1); + var endDate = new DateOnly(2023, 1, 20); + var alertType = await ReferenceDataCache.GetAlertTypeByDqtSanctionCode(sanctionCode); + var alertCategory = await ReferenceDataCache.GetAlertCategoryById(alertType.AlertCategoryId); - var request = new HttpRequestMessage(HttpMethod.Get, $"/v3/persons/{person.Trn}?dateOfBirth={person.DateOfBirth:yyyy-MM-dd}&include={Uri.EscapeDataString(include.ToString())}"); + var person = await TestData.CreatePerson(x => x + .WithTrn() + .WithSanction(sanctionCode, startDate, endDate)); - // Act - var response = await GetHttpClientWithApiKey().SendAsync(request); - - // Assert - Assert.Equal(StatusCodes.Status200OK, (int)response.StatusCode); - } - - [Fact] - public async Task Get_AsAppropriateBodyWithoutDateOfBirth_ReturnsForbidden() - { - // Arrange - SetCurrentApiClient(roles: [ApiRoles.AppropriateBody]); + var sanction = person.Sanctions.Single(); - var person = await TestData.CreatePerson(x => x.WithTrn()); + var request = new HttpRequestMessage(HttpMethod.Get, $"/v3/person?include=Alerts"); - var request = new HttpRequestMessage(HttpMethod.Get, $"/v3/persons/{person.Trn}"); + var httpClient = GetHttpClientWithIdentityAccessToken(person.Trn!); // Act - var response = await GetHttpClientWithApiKey().SendAsync(request); + var response = await httpClient.SendAsync(request); // Assert - Assert.Equal(StatusCodes.Status403Forbidden, (int)response.StatusCode); + var jsonResponse = await AssertEx.JsonResponse(response); + var responseAlerts = jsonResponse.RootElement.GetProperty("alerts"); + + AssertEx.JsonObjectEquals( + new[] + { + new + { + alertId = sanction.SanctionId, + alertType = new + { + alertTypeId = alertType.AlertTypeId, + name = alertType.Name, + alertCategory = new + { + alertCategoryId = alertCategory.AlertCategoryId, + name = alertCategory.Name + } + }, + startDate = startDate, + endDate = endDate + } + }, + responseAlerts); } } diff --git a/TeachingRecordSystem/tests/TeachingRecordSystem.Api.Tests/V3/VNext/TestBase.cs b/TeachingRecordSystem/tests/TeachingRecordSystem.Api.Tests/V3/VNext/TestBase.cs index e7e22ecaf..e28e5215c 100644 --- a/TeachingRecordSystem/tests/TeachingRecordSystem.Api.Tests/V3/VNext/TestBase.cs +++ b/TeachingRecordSystem/tests/TeachingRecordSystem.Api.Tests/V3/VNext/TestBase.cs @@ -2,9 +2,15 @@ namespace TeachingRecordSystem.Api.Tests.V3.VNext; public abstract class TestBase : Tests.TestBase { + public const string Version = VersionRegistry.V3MinorVersions.VNext; + protected TestBase(HostFixture hostFixture) : base(hostFixture) { } - public HttpClient GetHttpClientWithApiKey() => GetHttpClientWithApiKey(VersionRegistry.V3MinorVersions.VNext); + public HttpClient GetHttpClientWithApiKey() => + GetHttpClientWithApiKey(Version); + + public HttpClient GetHttpClientWithIdentityAccessToken(string trn, string scope = "dqt:read") => + GetHttpClientWithIdentityAccessToken(trn, scope, Version); } diff --git a/TeachingRecordSystem/tests/TeachingRecordSystem.TestCommon/DbHelper.cs b/TeachingRecordSystem/tests/TeachingRecordSystem.TestCommon/DbHelper.cs index 297d6efeb..2081dd393 100644 --- a/TeachingRecordSystem/tests/TeachingRecordSystem.TestCommon/DbHelper.cs +++ b/TeachingRecordSystem/tests/TeachingRecordSystem.TestCommon/DbHelper.cs @@ -101,6 +101,12 @@ private async Task EnsureRespawner(DbConnection connection) => new RespawnerOptions() { DbAdapter = DbAdapter.Postgres, - TablesToIgnore = ["mandatory_qualification_providers", "establishment_sources", "tps_establishment_types"] + TablesToIgnore = [ + "mandatory_qualification_providers", + "establishment_sources", + "tps_establishment_types", + "alert_types", + "alert_categories" + ] }); }