diff --git a/TeachingRecordSystem/src/TeachingRecordSystem.Api/V3/ApiModels/NameInfo.cs b/TeachingRecordSystem/src/TeachingRecordSystem.Api/V3/ApiModels/NameInfo.cs new file mode 100644 index 000000000..4f2846562 --- /dev/null +++ b/TeachingRecordSystem/src/TeachingRecordSystem.Api/V3/ApiModels/NameInfo.cs @@ -0,0 +1,8 @@ +namespace TeachingRecordSystem.Api.V3.ApiModels; + +public record NameInfo +{ + public required string FirstName { get; init; } + public required string MiddleName { get; init; } + public required string LastName { get; init; } +} diff --git a/TeachingRecordSystem/src/TeachingRecordSystem.Api/V3/Handlers/GetTeacherHandler.cs b/TeachingRecordSystem/src/TeachingRecordSystem.Api/V3/Handlers/GetTeacherHandler.cs index 1782e6c3d..0f06422cb 100644 --- a/TeachingRecordSystem/src/TeachingRecordSystem.Api/V3/Handlers/GetTeacherHandler.cs +++ b/TeachingRecordSystem/src/TeachingRecordSystem.Api/V3/Handlers/GetTeacherHandler.cs @@ -1,5 +1,6 @@ using System.Text; using MediatR; +using Microsoft.Xrm.Sdk.Query; using Optional; using TeachingRecordSystem.Api.V3.ApiModels; using TeachingRecordSystem.Api.V3.Requests; @@ -16,37 +17,43 @@ public class GetTeacherHandler : IRequestHandler("ConcurrentNameChangeWindowSeconds", 5)); } public async Task Handle(GetTeacherRequest request, CancellationToken cancellationToken) { - var teacher = await _dataverseAdapter.GetTeacherByTrn( - request.Trn, - columnNames: new[] - { - Contact.Fields.FirstName, - Contact.Fields.MiddleName, - Contact.Fields.LastName, - Contact.Fields.dfeta_StatedFirstName, - Contact.Fields.dfeta_StatedMiddleName, - Contact.Fields.dfeta_StatedLastName, - Contact.Fields.BirthDate, - Contact.Fields.dfeta_NINumber, - Contact.Fields.dfeta_QTSDate, - Contact.Fields.dfeta_EYTSDate, - Contact.Fields.EMailAddress1 - }); - - if (teacher is null) + var contactDetail = await _crmQueryDispatcher.ExecuteQuery( + new GetContactDetailByTrnQuery( + request.Trn, + new ColumnSet( + Contact.Fields.FirstName, + Contact.Fields.MiddleName, + Contact.Fields.LastName, + Contact.Fields.dfeta_StatedFirstName, + Contact.Fields.dfeta_StatedMiddleName, + Contact.Fields.dfeta_StatedLastName, + Contact.Fields.BirthDate, + Contact.Fields.dfeta_NINumber, + Contact.Fields.dfeta_QTSDate, + Contact.Fields.dfeta_EYTSDate, + Contact.Fields.EMailAddress1))); + + if (contactDetail is null) { return null; } + var teacher = contactDetail.Contact; + dfeta_induction? induction = default; dfeta_inductionperiod[]? inductionPeriods = default; @@ -199,6 +206,60 @@ public GetTeacherHandler(IDataverseAdapter dataverseAdapter, ICrmQueryDispatcher sanctions = (await _crmQueryDispatcher.ExecuteQuery(getSanctionsQuery))[teacher.Id]; } + List? previousNames = null; + + if (request.Include.HasFlag(GetTeacherRequestIncludes.PreviousNames)) + { + previousNames = new List(); + var currentFirstName = contactDetail.Contact.FirstName; + var currentMiddleName = contactDetail.Contact.MiddleName; + var currentLastName = contactDetail.Contact.LastName; + DateTime? createdOnBaseline = null; + + foreach (var previousName in contactDetail.PreviousNames.OrderByDescending(p => p.CreatedOn)) + { + if (createdOnBaseline is null) + { + createdOnBaseline = previousName.CreatedOn; + } + else if (createdOnBaseline - previousName.CreatedOn > _concurrentNameChangeWindow) + { + previousNames.Add(new NameInfo() + { + FirstName = currentFirstName, + MiddleName = currentMiddleName ?? string.Empty, + LastName = currentLastName + }); + createdOnBaseline = previousName.CreatedOn; + } + + switch (previousName.dfeta_Type) + { + case dfeta_NameType.FirstName: + currentFirstName = previousName.dfeta_name; + break; + case dfeta_NameType.MiddleName: + currentMiddleName = previousName.dfeta_name; + break; + case dfeta_NameType.LastName: + currentLastName = previousName.dfeta_name; + break; + default: + break; + } + } + + if (createdOnBaseline is not null) + { + previousNames.Add(new NameInfo() + { + FirstName = currentFirstName, + MiddleName = currentMiddleName ?? string.Empty, + LastName = currentLastName + }); + } + } + var firstName = teacher.ResolveFirstName(); var middleName = teacher.ResolveMiddleName(); var lastName = teacher.ResolveLastName(); @@ -270,6 +331,9 @@ public GetTeacherHandler(IDataverseAdapter dataverseAdapter, ICrmQueryDispatcher AlertType = AlertType.Prohibition, DqtSanctionCode = s.SanctionCode })) : + default, + PreviousNames = request.Include.HasFlag(GetTeacherRequestIncludes.PreviousNames) ? + Option.Some(previousNames!.Select(n => n)) : default }; } diff --git a/TeachingRecordSystem/src/TeachingRecordSystem.Api/V3/Requests/GetTeacherRequest.cs b/TeachingRecordSystem/src/TeachingRecordSystem.Api/V3/Requests/GetTeacherRequest.cs index 7bdd943d0..822fa6d11 100644 --- a/TeachingRecordSystem/src/TeachingRecordSystem.Api/V3/Requests/GetTeacherRequest.cs +++ b/TeachingRecordSystem/src/TeachingRecordSystem.Api/V3/Requests/GetTeacherRequest.cs @@ -25,6 +25,7 @@ public enum GetTeacherRequestIncludes HigherEducationQualifications = 1 << 5, Sanctions = 1 << 6, Alerts = 1 << 7, + PreviousNames = 1 << 8, - All = Induction | InitialTeacherTraining | NpqQualifications | MandatoryQualifications | PendingDetailChanges | HigherEducationQualifications | Sanctions | Alerts + All = Induction | InitialTeacherTraining | NpqQualifications | MandatoryQualifications | PendingDetailChanges | HigherEducationQualifications | Sanctions | Alerts | PreviousNames } diff --git a/TeachingRecordSystem/src/TeachingRecordSystem.Api/V3/Responses/GetTeacherResponse.cs b/TeachingRecordSystem/src/TeachingRecordSystem.Api/V3/Responses/GetTeacherResponse.cs index 8ded8421a..78e6511a6 100644 --- a/TeachingRecordSystem/src/TeachingRecordSystem.Api/V3/Responses/GetTeacherResponse.cs +++ b/TeachingRecordSystem/src/TeachingRecordSystem.Api/V3/Responses/GetTeacherResponse.cs @@ -24,6 +24,7 @@ public record GetTeacherResponse public required Option> HigherEducationQualifications { get; init; } public required Option> Sanctions { get; init; } public required Option> Alerts { get; init; } + public required Option> PreviousNames { get; init; } } public record GetTeacherResponseQts diff --git a/TeachingRecordSystem/src/TeachingRecordSystem.Api/appsettings.Testing.json b/TeachingRecordSystem/src/TeachingRecordSystem.Api/appsettings.Testing.json index bb1180e3f..e997509a4 100644 --- a/TeachingRecordSystem/src/TeachingRecordSystem.Api/appsettings.Testing.json +++ b/TeachingRecordSystem/src/TeachingRecordSystem.Api/appsettings.Testing.json @@ -12,5 +12,6 @@ "Microsoft.AspNetCore": "Fatal" } } - } + }, + "ConcurrentNameChangeWindowSeconds": 1 } diff --git a/TeachingRecordSystem/src/TeachingRecordSystem.Api/appsettings.json b/TeachingRecordSystem/src/TeachingRecordSystem.Api/appsettings.json index 3cbaba00a..f6ce9c986 100644 --- a/TeachingRecordSystem/src/TeachingRecordSystem.Api/appsettings.json +++ b/TeachingRecordSystem/src/TeachingRecordSystem.Api/appsettings.json @@ -83,5 +83,6 @@ "ProcessAllEntityTypesConcurrently": true, "IgnoreInvalidData": false, "RunService": false - } + }, + "ConcurrentNameChangeWindowSeconds": 5 } diff --git a/TeachingRecordSystem/src/TeachingRecordSystem.Core/Dqt/Queries/GetAllEarlyYearsStatusesQuery.cs b/TeachingRecordSystem/src/TeachingRecordSystem.Core/Dqt/Queries/GetAllEarlyYearsStatusesQuery.cs new file mode 100644 index 000000000..97927859f --- /dev/null +++ b/TeachingRecordSystem/src/TeachingRecordSystem.Core/Dqt/Queries/GetAllEarlyYearsStatusesQuery.cs @@ -0,0 +1,3 @@ +namespace TeachingRecordSystem.Core.Dqt.Queries; + +public record GetAllEarlyYearsStatusesQuery : ICrmQuery; diff --git a/TeachingRecordSystem/src/TeachingRecordSystem.Core/Dqt/Queries/GetContactDetailByTrnQuery.cs b/TeachingRecordSystem/src/TeachingRecordSystem.Core/Dqt/Queries/GetContactDetailByTrnQuery.cs new file mode 100644 index 000000000..9dd48e8ec --- /dev/null +++ b/TeachingRecordSystem/src/TeachingRecordSystem.Core/Dqt/Queries/GetContactDetailByTrnQuery.cs @@ -0,0 +1,5 @@ +using Microsoft.Xrm.Sdk.Query; + +namespace TeachingRecordSystem.Core.Dqt.Queries; + +public record GetContactDetailByTrnQuery(string Trn, ColumnSet ColumnSet) : ICrmQuery; diff --git a/TeachingRecordSystem/src/TeachingRecordSystem.Core/Dqt/QueryHandlers/GetAllEarlyYearsStatusesHandler.cs b/TeachingRecordSystem/src/TeachingRecordSystem.Core/Dqt/QueryHandlers/GetAllEarlyYearsStatusesHandler.cs new file mode 100644 index 000000000..7f1691165 --- /dev/null +++ b/TeachingRecordSystem/src/TeachingRecordSystem.Core/Dqt/QueryHandlers/GetAllEarlyYearsStatusesHandler.cs @@ -0,0 +1,30 @@ +using Microsoft.PowerPlatform.Dataverse.Client; +using Microsoft.Xrm.Sdk.Messages; +using Microsoft.Xrm.Sdk.Query; +using TeachingRecordSystem.Core.Dqt.Queries; + +namespace TeachingRecordSystem.Core.Dqt.QueryHandlers; + +public class GetAllEarlyYearsStatusesHandler : ICrmQueryHandler +{ + public async Task Execute(GetAllEarlyYearsStatusesQuery query, IOrganizationServiceAsync organizationService) + { + var queryExpression = new QueryExpression() + { + EntityName = dfeta_earlyyearsstatus.EntityLogicalName, + ColumnSet = new ColumnSet( + dfeta_earlyyearsstatus.Fields.dfeta_name, + dfeta_earlyyearsstatus.Fields.dfeta_Value) + }; + queryExpression.Criteria.AddCondition(dfeta_earlyyearsstatus.Fields.StateCode, ConditionOperator.Equal, (int)dfeta_earlyyearsStatusState.Active); + + var request = new RetrieveMultipleRequest() + { + Query = queryExpression + }; + + var response = await organizationService.RetrieveMultipleAsync(queryExpression); + + return response.Entities.Select(e => e.ToEntity()).ToArray(); + } +} diff --git a/TeachingRecordSystem/src/TeachingRecordSystem.Core/Dqt/QueryHandlers/GetContactDetailByTrnHandler.cs b/TeachingRecordSystem/src/TeachingRecordSystem.Core/Dqt/QueryHandlers/GetContactDetailByTrnHandler.cs new file mode 100644 index 000000000..aaba92ef3 --- /dev/null +++ b/TeachingRecordSystem/src/TeachingRecordSystem.Core/Dqt/QueryHandlers/GetContactDetailByTrnHandler.cs @@ -0,0 +1,74 @@ +using Microsoft.PowerPlatform.Dataverse.Client; +using Microsoft.Xrm.Sdk.Messages; +using Microsoft.Xrm.Sdk.Query; +using TeachingRecordSystem.Core.Dqt.Queries; + +namespace TeachingRecordSystem.Core.Dqt.QueryHandlers; + +public class GetContactDetailByTrnHandler : ICrmQueryHandler +{ + public async Task Execute(GetContactDetailByTrnQuery query, IOrganizationServiceAsync organizationService) + { + var contactFilter = new FilterExpression(); + contactFilter.AddCondition(Contact.Fields.dfeta_TRN, ConditionOperator.Equal, query.Trn); + var contactQueryExpression = new QueryExpression(Contact.EntityLogicalName) + { + ColumnSet = query.ColumnSet, + Criteria = contactFilter + }; + + var contactRequest = new RetrieveMultipleRequest() + { + Query = contactQueryExpression + }; + + var previousNameFilter = new FilterExpression(); + previousNameFilter.AddCondition(dfeta_previousname.Fields.StateCode, ConditionOperator.Equal, (int)dfeta_documentState.Active); + previousNameFilter.AddCondition(dfeta_previousname.Fields.dfeta_Type, ConditionOperator.NotEqual, (int)dfeta_NameType.Title); + var previousNameQueryExpression = new QueryExpression(dfeta_previousname.EntityLogicalName) + { + ColumnSet = new ColumnSet( + dfeta_previousname.PrimaryIdAttribute, + dfeta_previousname.Fields.dfeta_PersonId, + dfeta_previousname.Fields.CreatedOn, + dfeta_previousname.Fields.dfeta_ChangedOn, + dfeta_previousname.Fields.dfeta_name, + dfeta_previousname.Fields.dfeta_Type), + Criteria = previousNameFilter + }; + + var contactLink = previousNameQueryExpression.AddLink( + Contact.EntityLogicalName, + dfeta_previousname.Fields.dfeta_PersonId, + Contact.PrimaryIdAttribute, + JoinOperator.Inner); + + contactLink.Columns = new ColumnSet( + Contact.PrimaryIdAttribute, + Contact.Fields.dfeta_TRN); + + contactLink.EntityAlias = Contact.EntityLogicalName; + contactLink.LinkCriteria = contactFilter; + + var previousNameRequest = new RetrieveMultipleRequest() + { + Query = previousNameQueryExpression + }; + + var requestBuilder = RequestBuilder.CreateMultiple(organizationService); + var contactResponse = requestBuilder.AddRequest(contactRequest); + var previousNameResponse = requestBuilder.AddRequest(previousNameRequest); + + await requestBuilder.Execute(); + + var contact = (await contactResponse.GetResponseAsync()).EntityCollection.Entities.FirstOrDefault()?.ToEntity(); + var previousNames = (await previousNameResponse.GetResponseAsync()).EntityCollection.Entities.Select(e => e.ToEntity()).ToArray(); + + if (contact is null) + { + return null; + } + + return new ContactDetail(contact, previousNames); + } +} diff --git a/TeachingRecordSystem/src/TeachingRecordSystem.Core/Dqt/ReferenceDataCache.cs b/TeachingRecordSystem/src/TeachingRecordSystem.Core/Dqt/ReferenceDataCache.cs index 7bc5c0bba..69d2621e9 100644 --- a/TeachingRecordSystem/src/TeachingRecordSystem.Core/Dqt/ReferenceDataCache.cs +++ b/TeachingRecordSystem/src/TeachingRecordSystem.Core/Dqt/ReferenceDataCache.cs @@ -8,6 +8,7 @@ public class ReferenceDataCache private Task? _getSanctionCodesTask; private Task? _getSubjectsTask; private Task? _getTeacherStatusesTask; + private Task? _getEarlyYearsStatusesTask; public ReferenceDataCache(ICrmQueryDispatcher crmQueryDispatcher) { @@ -45,6 +46,12 @@ public async Task GetTeacherStatusByValue(string value) return teacherStatuses.Single(ts => ts.dfeta_Value == value); } + public async Task GetEarlyYearsStatusByValue(string value) + { + var earlyYearsStatuses = await EnsureEarlyYearsStatuses(); + return earlyYearsStatuses.Single(ey => ey.dfeta_Value == value); + } + private Task EnsureSanctionCodes() => LazyInitializer.EnsureInitialized( ref _getSanctionCodesTask, @@ -59,4 +66,9 @@ private Task EnsureTeacherStatuses() => LazyInitializer.EnsureInitialized( ref _getTeacherStatusesTask, () => _crmQueryDispatcher.ExecuteQuery(new GetAllTeacherStatusesQuery())); + + private Task EnsureEarlyYearsStatuses() => + LazyInitializer.EnsureInitialized( + ref _getEarlyYearsStatusesTask, + () => _crmQueryDispatcher.ExecuteQuery(new GetAllEarlyYearsStatusesQuery())); } diff --git a/TeachingRecordSystem/tests/TeachingRecordSystem.Api.Tests/V3/GetTeacherByTrnTests.cs b/TeachingRecordSystem/tests/TeachingRecordSystem.Api.Tests/V3/GetTeacherByTrnTests.cs index bec3f401b..f1ab4e93d 100644 --- a/TeachingRecordSystem/tests/TeachingRecordSystem.Api.Tests/V3/GetTeacherByTrnTests.cs +++ b/TeachingRecordSystem/tests/TeachingRecordSystem.Api.Tests/V3/GetTeacherByTrnTests.cs @@ -38,110 +38,119 @@ public async Task Get_TrnNotFound_ReturnsNotFound() } [Fact] - public Task Get_ValidRequest_ReturnsExpectedResponse() + public async Task Get_ValidRequest_ReturnsExpectedResponse() { - var trn = "1234567"; - var baseUrl = $"/v3/teachers/{trn}"; + var contact = await CreateContact(qualifiedInWales: false); + var baseUrl = $"/v3/teachers/{contact.dfeta_TRN}"; - return ValidRequestForTeacher_ReturnsExpectedContent(HttpClientWithApiKey, baseUrl, trn, qualifiedInWales: false, expectQtsCertificateUrl: false, expectEysCertificateUrl: false); + await ValidRequestForTeacher_ReturnsExpectedContent(HttpClientWithApiKey, baseUrl, contact, expectQtsCertificateUrl: false, expectEysCertificateUrl: false); } [Fact] - public Task Get_ValidRequestForTeacherQualifiedInWales_ReturnsExpectedResponse() + public async Task Get_ValidRequestForTeacherQualifiedInWales_ReturnsExpectedResponse() { - var trn = "1234567"; - var baseUrl = $"/v3/teachers/{trn}"; + var contact = await CreateContact(qualifiedInWales: true); + var baseUrl = $"/v3/teachers/{contact.dfeta_TRN}"; - return ValidRequestForTeacher_ReturnsExpectedContent(HttpClientWithApiKey, baseUrl, trn, qualifiedInWales: true, expectQtsCertificateUrl: false, expectEysCertificateUrl: false); + await ValidRequestForTeacher_ReturnsExpectedContent(HttpClientWithApiKey, baseUrl, contact, expectQtsCertificateUrl: false, expectEysCertificateUrl: false); } [Fact] - public Task Get_ValidRequestForContactWithMultiWordFirstName_ReturnsExpectedResponse() + public async Task Get_ValidRequestForContactWithMultiWordFirstName_ReturnsExpectedResponse() { - var trn = "1234567"; - var baseUrl = $"/v3/teachers/{trn}"; + var contact = await CreateContact(); + var baseUrl = $"/v3/teachers/{contact.dfeta_TRN}"; - return ValidRequestForTeacherWithMultiWordFirstName_ReturnsExpectedContent(HttpClientWithApiKey, baseUrl, trn, expectCertificateUrls: false); + await ValidRequestForTeacherWithMultiWordFirstName_ReturnsExpectedContent(HttpClientWithApiKey, baseUrl, contact, expectCertificateUrls: false); } [Fact] - public Task Get_ValidRequestWithInduction_ReturnsExpectedInductionContent() + public async Task Get_ValidRequestWithInduction_ReturnsExpectedInductionContent() { - var trn = "1234567"; - var baseUrl = $"/v3/teachers/{trn}"; + var contact = await CreateContact(); + var baseUrl = $"/v3/teachers/{contact.dfeta_TRN}"; - return ValidRequestWithInduction_ReturnsExpectedInductionContent(HttpClientWithApiKey, baseUrl, trn, expectCertificateUrls: false); + await ValidRequestWithInduction_ReturnsExpectedInductionContent(HttpClientWithApiKey, baseUrl, contact, expectCertificateUrls: false); } [Fact] - public Task Get_ValidRequestWithInitialTeacherTraining_ReturnsExpectedInitialTeacherTrainingContent() + public async Task Get_ValidRequestWithInitialTeacherTraining_ReturnsExpectedInitialTeacherTrainingContent() { - var trn = "1234567"; - var baseUrl = $"/v3/teachers/{trn}"; + var contact = await CreateContact(); + var baseUrl = $"/v3/teachers/{contact.dfeta_TRN}"; - return ValidRequestWithInitialTeacherTraining_ReturnsExpectedInitialTeacherTrainingContent(HttpClientWithApiKey, baseUrl, trn); + await ValidRequestWithInitialTeacherTraining_ReturnsExpectedInitialTeacherTrainingContent(HttpClientWithApiKey, baseUrl, contact); } [Fact] - public Task Get_ValidRequestWithNpqQualifications_ReturnsExpectedNpqQualificationsContent() + public async Task Get_ValidRequestWithNpqQualifications_ReturnsExpectedNpqQualificationsContent() { - var trn = "1234567"; - var baseUrl = $"/v3/teachers/{trn}"; + var contact = await CreateContact(); + var baseUrl = $"/v3/teachers/{contact.dfeta_TRN}"; - return ValidRequestWithNpqQualifications_ReturnsExpectedNpqQualificationsContent(HttpClientWithApiKey, baseUrl, trn, expectCertificateUrls: false); + await ValidRequestWithNpqQualifications_ReturnsExpectedNpqQualificationsContent(HttpClientWithApiKey, baseUrl, contact, expectCertificateUrls: false); } [Fact] - public Task Get_ValidRequestWithMandatoryQualifications_ReturnsExpectedMandatoryQualificationsContent() + public async Task Get_ValidRequestWithMandatoryQualifications_ReturnsExpectedMandatoryQualificationsContent() { - var trn = "1234567"; - var baseUrl = $"/v3/teachers/{trn}"; + var contact = await CreateContact(); + var baseUrl = $"/v3/teachers/{contact.dfeta_TRN}"; - return ValidRequestWithMandatoryQualifications_ReturnsExpectedMandatoryQualificationsContent(HttpClientWithApiKey, baseUrl, trn); + await ValidRequestWithMandatoryQualifications_ReturnsExpectedMandatoryQualificationsContent(HttpClientWithApiKey, baseUrl, contact); } [Fact] - public Task Get_ValidRequestWithHigherEducationQualifications_ReturnsExpectedHigherEducationQualificationsContent() + public async Task Get_ValidRequestWithHigherEducationQualifications_ReturnsExpectedHigherEducationQualificationsContent() { - var trn = "1234567"; - var baseUrl = $"/v3/teachers/{trn}"; + var contact = await CreateContact(); + var baseUrl = $"/v3/teachers/{contact.dfeta_TRN}"; - return ValidRequestWithHigherEducationQualifications_ReturnsExpectedHigherEducationQualificationsContent(HttpClientWithApiKey, baseUrl, trn); + await ValidRequestWithHigherEducationQualifications_ReturnsExpectedHigherEducationQualificationsContent(HttpClientWithApiKey, baseUrl, contact); } [Fact] - public Task Get_ValidRequestForContactWithPendingNameChange_ReturnsPendingNameChangeTrue() + public async Task Get_ValidRequestForContactWithPendingNameChange_ReturnsPendingNameChangeTrue() { - var trn = "1234567"; - var baseUrl = $"/v3/teachers/{trn}"; + var contact = await CreateContact(); + var baseUrl = $"/v3/teachers/{contact.dfeta_TRN}"; - return ValidRequestForContactWithPendingNameChange_ReturnsPendingNameChangeTrue(HttpClientWithApiKey, baseUrl, trn); + await ValidRequestForContactWithPendingNameChange_ReturnsPendingNameChangeTrue(HttpClientWithApiKey, baseUrl, contact); } [Fact] - public Task Get_ValidRequestForContactWithPendingDateOfBirthChange_ReturnsPendingDateOfBirthChangeTrue() + public async Task Get_ValidRequestForContactWithPendingDateOfBirthChange_ReturnsPendingDateOfBirthChangeTrue() { - var trn = "1234567"; - var baseUrl = $"/v3/teachers/{trn}"; + var contact = await CreateContact(); + var baseUrl = $"/v3/teachers/{contact.dfeta_TRN}"; - return ValidRequestForContactWithPendingDateOfBirthChange_ReturnsPendingDateOfBirthChangeTrue(HttpClientWithApiKey, baseUrl, trn); + await ValidRequestForContactWithPendingDateOfBirthChange_ReturnsPendingDateOfBirthChangeTrue(HttpClientWithApiKey, baseUrl, contact); } [Fact] - public Task Get_ValidRequestWithSanctions_ReturnsExpectedSanctionsContent() + public async Task Get_ValidRequestWithSanctions_ReturnsExpectedSanctionsContent() { - var trn = "1234567"; - var baseUrl = $"/v3/teachers/{trn}"; + var contact = await CreateContact(); + var baseUrl = $"/v3/teachers/{contact.dfeta_TRN}"; - return ValidRequestWithSanctions_ReturnsExpectedSanctionsContent(HttpClientWithApiKey, baseUrl, trn); + await ValidRequestWithSanctions_ReturnsExpectedSanctionsContent(HttpClientWithApiKey, baseUrl, contact); } [Fact] - public Task Get_ValidRequestWithAlerts_ReturnsExpectedSanctionsContent() + public async Task Get_ValidRequestWithAlerts_ReturnsExpectedSanctionsContent() { - var trn = "1234567"; - var baseUrl = $"/v3/teachers/{trn}"; + var contact = await CreateContact(); + var baseUrl = $"/v3/teachers/{contact.dfeta_TRN}"; + + await ValidRequestWithAlerts_ReturnsExpectedSanctionsContent(HttpClientWithApiKey, baseUrl, contact); + } + + [Fact] + public async Task Get_ValidRequestWithPreviousNames_ReturnsExpectedPreviousNamesContent() + { + var contact = await CreateContact(); + var baseUrl = $"/v3/teachers/{contact.dfeta_TRN}"; - return ValidRequestWithAlerts_ReturnsExpectedSanctionsContent(HttpClientWithApiKey, baseUrl, trn); + await ValidRequestWithPreviousNames_ReturnsExpectedPreviousNamesContent(HttpClientWithApiKey, baseUrl, contact); } } diff --git a/TeachingRecordSystem/tests/TeachingRecordSystem.Api.Tests/V3/GetTeacherTestBase.cs b/TeachingRecordSystem/tests/TeachingRecordSystem.Api.Tests/V3/GetTeacherTestBase.cs index ffd0b19bb..cf62d6331 100644 --- a/TeachingRecordSystem/tests/TeachingRecordSystem.Api.Tests/V3/GetTeacherTestBase.cs +++ b/TeachingRecordSystem/tests/TeachingRecordSystem.Api.Tests/V3/GetTeacherTestBase.cs @@ -8,6 +8,7 @@ namespace TeachingRecordSystem.Api.Tests.V3; public abstract class GetTeacherTestBase : ApiTestBase { + private const string QualifiedTeacherTrainedTeacherStatusValue = "71"; private const string QtsAwardedInWalesTeacherStatusValue = "213"; private readonly Guid _qtsAwardedInWalesTeacherStatusId = Guid.NewGuid(); @@ -21,28 +22,12 @@ protected GetTeacherTestBase(ApiFixture apiFixture) : base(apiFixture) protected async Task ValidRequestForTeacher_ReturnsExpectedContent( HttpClient httpClient, string baseUrl, - string trn, - bool qualifiedInWales, + Contact contact, bool expectQtsCertificateUrl, bool expectEysCertificateUrl) { // Arrange - var contact = await CreateContact(trn); - - dfeta_qtsregistration[]? qtsRegistrations = null; - if (qualifiedInWales) - { - qtsRegistrations = new[] - { - new dfeta_qtsregistration() - { - dfeta_QTSDate = contact.dfeta_QTSDate, - dfeta_TeacherStatusId = _qtsAwardedInWalesTeacherStatusId.ToEntityReference(dfeta_teacherstatus.EntityLogicalName) - } - }; - } - - await ConfigureMocks(trn, contact, qtsRegistrations: qtsRegistrations); + await ConfigureMocks(contact); var request = new HttpRequestMessage(HttpMethod.Get, baseUrl); @@ -55,7 +40,7 @@ protected async Task ValidRequestForTeacher_ReturnsExpectedContent( firstName = contact.FirstName, lastName = contact.LastName, middleName = contact.MiddleName, - trn = trn, + trn = contact.dfeta_TRN, dateOfBirth = contact.BirthDate?.ToString("yyyy-MM-dd"), nationalInsuranceNumber = contact.dfeta_NINumber, qts = new @@ -90,13 +75,11 @@ await AssertEx.JsonResponseEquals( protected async Task ValidRequestForTeacherWithMultiWordFirstName_ReturnsExpectedContent( HttpClient httpClient, string baseUrl, - string trn, + Contact contact, bool expectCertificateUrls) { // Arrange - var contact = await CreateContact(trn, hasMultiWordFirstName: true); - - await ConfigureMocks(trn, contact); + await ConfigureMocks(contact); var request = new HttpRequestMessage(HttpMethod.Get, baseUrl); @@ -109,7 +92,7 @@ protected async Task ValidRequestForTeacherWithMultiWordFirstName_ReturnsExpecte firstName = contact.dfeta_StatedFirstName, lastName = contact.dfeta_StatedLastName, middleName = contact.dfeta_StatedMiddleName, - trn = trn, + trn = contact.dfeta_TRN, dateOfBirth = contact.BirthDate?.ToString("yyyy-MM-dd"), nationalInsuranceNumber = contact.dfeta_NINumber, qts = new @@ -140,15 +123,14 @@ await AssertEx.JsonResponseEquals( protected async Task ValidRequestWithInduction_ReturnsExpectedInductionContent( HttpClient httpClient, string baseUrl, - string trn, + Contact contact, bool expectCertificateUrls) { // Arrange - var contact = await CreateContact(trn); var induction = CreateInduction(); var inductionPeriods = CreateInductionPeriods(); - await ConfigureMocks(trn, contact, induction: induction, inductionPeriods: inductionPeriods); + await ConfigureMocks(contact, induction: induction, inductionPeriods: inductionPeriods); var request = new HttpRequestMessage(HttpMethod.Get, $"{baseUrl}?include=Induction"); @@ -191,13 +173,12 @@ protected async Task ValidRequestWithInduction_ReturnsExpectedInductionContent( protected async Task ValidRequestWithInitialTeacherTraining_ReturnsExpectedInitialTeacherTrainingContent( HttpClient httpClient, string baseUrl, - string trn) + Contact contact) { // Arrange - var contact = await CreateContact(trn); var itt = CreateItt(contact); - await ConfigureMocks(trn, contact, itt); + await ConfigureMocks(contact, itt); var request = new HttpRequestMessage(HttpMethod.Get, $"{baseUrl}?include=InitialTeacherTraining"); @@ -257,12 +238,10 @@ protected async Task ValidRequestWithInitialTeacherTraining_ReturnsExpectedIniti protected async Task ValidRequestWithNpqQualifications_ReturnsExpectedNpqQualificationsContent( HttpClient httpClient, string baseUrl, - string trn, + Contact contact, bool expectCertificateUrls) { // Arrange - var contact = await CreateContact(trn); - var npqQualificationNoAwardDate = CreateQualification(dfeta_qualification_dfeta_Type.NPQLL, null, dfeta_qualificationState.Active, null); var npqQualificationInactive = CreateQualification(dfeta_qualification_dfeta_Type.NPQSL, new DateTime(2022, 5, 6), dfeta_qualificationState.Inactive, null); var npqQualificationValid = CreateQualification(dfeta_qualification_dfeta_Type.NPQEYL, new DateTime(2022, 3, 4), dfeta_qualificationState.Active, null); @@ -274,7 +253,7 @@ protected async Task ValidRequestWithNpqQualifications_ReturnsExpectedNpqQualifi npqQualificationValid }; - await ConfigureMocks(trn, contact, qualifications: qualifications); + await ConfigureMocks(contact, qualifications: qualifications); var request = new HttpRequestMessage(HttpMethod.Get, $"{baseUrl}?include=NpqQualifications"); @@ -310,11 +289,9 @@ protected async Task ValidRequestWithNpqQualifications_ReturnsExpectedNpqQualifi protected async Task ValidRequestWithMandatoryQualifications_ReturnsExpectedMandatoryQualificationsContent( HttpClient httpClient, string baseUrl, - string trn) + Contact contact) { // Arrange - var contact = await CreateContact(trn); - var mandatoryQualificationNoAwardDate = CreateQualification(dfeta_qualification_dfeta_Type.MandatoryQualification, null, dfeta_qualificationState.Active, "Visual Impairment"); var mandatoryQualificationNoSpecialism = CreateQualification(dfeta_qualification_dfeta_Type.MandatoryQualification, new DateTime(2022, 2, 3), dfeta_qualificationState.Active, null); var mandatoryQualificationValid = CreateQualification(dfeta_qualification_dfeta_Type.MandatoryQualification, new DateTime(2022, 4, 6), dfeta_qualificationState.Active, "Hearing"); @@ -328,7 +305,7 @@ protected async Task ValidRequestWithMandatoryQualifications_ReturnsExpectedMand mandatoryQualificationInactive }; - await ConfigureMocks(trn, contact, qualifications: qualifications); + await ConfigureMocks(contact, qualifications: qualifications); var request = new HttpRequestMessage(HttpMethod.Get, $"{baseUrl}?include=MandatoryQualifications"); @@ -354,10 +331,9 @@ protected async Task ValidRequestWithMandatoryQualifications_ReturnsExpectedMand protected async Task ValidRequestWithHigherEducationQualifications_ReturnsExpectedHigherEducationQualificationsContent( HttpClient httpClient, string baseUrl, - string trn) + Contact contact) { // Arrange - var contact = await CreateContact(trn); var qualification1AwardDate = new DateTime(2022, 4, 6); var qualification1Name = "My HE Qual 1"; var qualification1Subject1 = (Code: "Qualification1Subject1", Name: "Qualification 1 Subject 1"); @@ -418,7 +394,7 @@ protected async Task ValidRequestWithHigherEducationQualifications_ReturnsExpect heQualificationInactive }; - await ConfigureMocks(trn, contact, qualifications: qualifications); + await ConfigureMocks(contact, qualifications: qualifications); var request = new HttpRequestMessage(HttpMethod.Get, $"{baseUrl}?include=HigherEducationQualifications"); @@ -468,11 +444,9 @@ protected async Task ValidRequestWithHigherEducationQualifications_ReturnsExpect protected async Task ValidRequestForContactWithPendingNameChange_ReturnsPendingNameChangeTrue( HttpClient httpClient, string baseUrl, - string trn) + Contact contact) { // Arrange - var contact = await CreateContact(trn); - var incidents = new[] { new Incident() @@ -483,7 +457,7 @@ protected async Task ValidRequestForContactWithPendingNameChange_ReturnsPendingN } }; - await ConfigureMocks(trn, contact, incidents: incidents); + await ConfigureMocks(contact, incidents: incidents); var request = new HttpRequestMessage(HttpMethod.Get, $"{baseUrl}?include=PendingDetailChanges"); @@ -498,11 +472,9 @@ protected async Task ValidRequestForContactWithPendingNameChange_ReturnsPendingN protected async Task ValidRequestForContactWithPendingDateOfBirthChange_ReturnsPendingDateOfBirthChangeTrue( HttpClient httpClient, string baseUrl, - string trn) + Contact contact) { // Arrange - var contact = await CreateContact(trn); - var incidents = new[] { new Incident() @@ -513,7 +485,7 @@ protected async Task ValidRequestForContactWithPendingDateOfBirthChange_ReturnsP } }; - await ConfigureMocks(trn, contact, incidents: incidents); + await ConfigureMocks(contact, incidents: incidents); var request = new HttpRequestMessage(HttpMethod.Get, $"{baseUrl}?include=PendingDetailChanges"); @@ -528,11 +500,9 @@ protected async Task ValidRequestForContactWithPendingDateOfBirthChange_ReturnsP protected async Task ValidRequestWithSanctions_ReturnsExpectedSanctionsContent( HttpClient httpClient, string baseUrl, - string trn) + Contact contact) { // Arrange - var contact = await CreateContact(trn); - var sanctions = new (string SanctionCode, DateOnly? StartDate)[] { new("A18", null), @@ -540,7 +510,7 @@ protected async Task ValidRequestWithSanctions_ReturnsExpectedSanctionsContent( }; Debug.Assert(sanctions.Select(s => s.SanctionCode).All(TeachingRecordSystem.Api.V3.Constants.ExposableSanctionCodes.Contains)); - await ConfigureMocks(trn, contact, sanctions: sanctions); + await ConfigureMocks(contact, sanctions: sanctions); var request = new HttpRequestMessage(HttpMethod.Get, $"{baseUrl}?include=Sanctions"); @@ -571,11 +541,9 @@ protected async Task ValidRequestWithSanctions_ReturnsExpectedSanctionsContent( protected async Task ValidRequestWithAlerts_ReturnsExpectedSanctionsContent( HttpClient httpClient, string baseUrl, - string trn) + Contact contact) { // Arrange - var contact = await CreateContact(trn); - var sanctions = new (string SanctionCode, DateOnly? StartDate)[] { new("B1", null), @@ -583,7 +551,7 @@ protected async Task ValidRequestWithAlerts_ReturnsExpectedSanctionsContent( }; Debug.Assert(sanctions.Select(s => s.SanctionCode).All(TeachingRecordSystem.Api.V3.Constants.ProhibitionSanctionCodes.Contains)); - await ConfigureMocks(trn, contact, sanctions: sanctions); + await ConfigureMocks(contact, sanctions: sanctions); var request = new HttpRequestMessage(HttpMethod.Get, $"{baseUrl}?include=Alerts"); @@ -611,15 +579,76 @@ protected async Task ValidRequestWithAlerts_ReturnsExpectedSanctionsContent( responseAlerts); } + protected async Task ValidRequestWithPreviousNames_ReturnsExpectedPreviousNamesContent( + HttpClient httpClient, + string baseUrl, + Contact contact) + { + // Arrange + var updatedFirstName = TestData.GenerateFirstName(); + var updatedMiddleName = TestData.GenerateMiddleName(); + var updatedLastName = TestData.GenerateLastName(); + var updatedNames = new[] + { + (FirstName: updatedFirstName, MiddleName: updatedMiddleName, LastName: contact.LastName), + (FirstName: updatedFirstName, MiddleName: updatedMiddleName, LastName: updatedLastName) + }; + + await ConfigureMocks(contact, updatedNames: updatedNames!); + + var request = new HttpRequestMessage(HttpMethod.Get, $"{baseUrl}?include=PreviousNames"); + + // Act + var response = await httpClient.SendAsync(request); + + // Assert + var jsonResponse = await AssertEx.JsonResponse(response); + var responsePreviousNames = jsonResponse.RootElement.GetProperty("previousNames"); + + AssertEx.JsonObjectEquals( + new[] + { + new + { + firstName = updatedFirstName, + middleName = updatedMiddleName, + lastName = contact.LastName, + }, + new + { + firstName = contact.FirstName, + middleName = contact.MiddleName, + lastName = contact.LastName, + } + }, + responsePreviousNames); + } + + protected async Task CreateContact( + bool hasMultiWordFirstName = false, + bool qualifiedInWales = false) + { + var qtsDate = new DateOnly(1997, 4, 23); + var eytsDate = new DateOnly(1995, 5, 14); + var firstName = hasMultiWordFirstName ? $"{Faker.Name.First()} {Faker.Name.First()}" : Faker.Name.First(); + + var person = await TestData.CreatePerson( + b => b.WithFirstName(firstName) + .WithTrn() + .WithQts(qtsDate, qualifiedInWales ? QtsAwardedInWalesTeacherStatusValue : QualifiedTeacherTrainedTeacherStatusValue) + .WithEyts(eytsDate)); + + return person.ToContact(); + } + private async Task ConfigureMocks( - string trn, Contact contact, dfeta_initialteachertraining? itt = null, dfeta_induction? induction = null, dfeta_inductionperiod[]? inductionPeriods = null, dfeta_qualification[]? qualifications = null, Incident[]? incidents = null, - dfeta_qtsregistration[]? qtsRegistrations = null, + (string FirstName, string? MiddleName, string LastName)[]? updatedNames = null, (string SanctionCode, DateOnly? StartDate)[]? sanctions = null) { DataverseAdapterMock @@ -639,7 +668,7 @@ private async Task ConfigureMocks( }); DataverseAdapterMock - .Setup(mock => mock.GetTeacherByTrn(trn, /* columnNames: */ It.IsAny(), /* activeOnly: */ true)) + .Setup(mock => mock.GetTeacherByTrn(contact.dfeta_TRN, /* columnNames: */ It.IsAny(), /* activeOnly: */ true)) .ReturnsAsync(contact); DataverseAdapterMock @@ -678,19 +707,12 @@ private async Task ConfigureMocks( .Setup(mock => mock.GetTeacherStatus( It.Is(s => s == QtsAwardedInWalesTeacherStatusValue), It.IsAny())) - .ReturnsAsync(new dfeta_teacherstatus() - { - Id = _qtsAwardedInWalesTeacherStatusId - }); + .Returns(async (string s, RequestBuilder b) => await TestData.ReferenceDataCache.GetTeacherStatusByValue(s)); - DataverseAdapterMock - .Setup(mock => mock.GetTeacherStatus( - It.Is(s => s != QtsAwardedInWalesTeacherStatusValue), - It.IsAny())) - .ReturnsAsync(new dfeta_teacherstatus() - { - Id = Guid.NewGuid() - }); + using var ctx = new DqtCrmServiceContext(TestData.OrganizationService); + var qtsRegistrations = ctx.dfeta_qtsregistrationSet + .Where(c => c.GetAttributeValue(dfeta_qtsregistration.Fields.dfeta_PersonId) == contact.Id) + .ToArray(); DataverseAdapterMock .Setup(mock => mock.GetQtsRegistrationsByTeacher( @@ -711,42 +733,12 @@ await TestData.OrganizationService.CreateAsync(new dfeta_sanction() dfeta_StartDate = sanction.StartDate?.FromDateOnlyWithDqtBstFix(isLocalTime: true) }); } - } - private async Task CreateContact(string trn, bool hasMultiWordFirstName = false) - { - var contactId = Guid.NewGuid(); - var firstName1 = Faker.Name.First(); - var firstName2 = Faker.Name.First(); - var lastName = Faker.Name.Last(); - var middleName = Faker.Name.Middle(); - var dateOfBirth = DateOnly.FromDateTime(Faker.Identification.DateOfBirth()); - var nino = Faker.Identification.UkNationalInsuranceNumber(); - var email = Faker.Internet.Email(); - - var qtsDate = new DateOnly(1997, 4, 23); - var eytsDate = new DateOnly(1995, 5, 14); - - var teacher = new Contact() + foreach (var updatedName in updatedNames ?? Array.Empty<(string, string?, string)>()) { - Id = contactId, - dfeta_TRN = trn, - FirstName = firstName1, - MiddleName = hasMultiWordFirstName ? $"{firstName2} {middleName}" : middleName, - LastName = lastName, - dfeta_StatedFirstName = hasMultiWordFirstName ? $"{firstName1} {firstName2}" : firstName1, - dfeta_StatedMiddleName = middleName, - dfeta_StatedLastName = lastName, - BirthDate = dateOfBirth.ToDateTime(), - dfeta_NINumber = nino, - dfeta_QTSDate = qtsDate.ToDateTime(), - dfeta_EYTSDate = eytsDate.ToDateTime(), - EMailAddress1 = email - }; - - await TestData.OrganizationService.CreateAsync(teacher); - - return teacher; + await TestData.UpdatePerson(b => b.WithPersonId(contact.Id).WithUpdatedName(updatedName.FirstName, updatedName.MiddleName, updatedName.LastName)); + await Task.Delay(2000); + } } private static dfeta_initialteachertraining CreateItt(Contact teacher) diff --git a/TeachingRecordSystem/tests/TeachingRecordSystem.Api.Tests/V3/GetTeacherTests.cs b/TeachingRecordSystem/tests/TeachingRecordSystem.Api.Tests/V3/GetTeacherTests.cs index 580cb38b1..67e908a7b 100644 --- a/TeachingRecordSystem/tests/TeachingRecordSystem.Api.Tests/V3/GetTeacherTests.cs +++ b/TeachingRecordSystem/tests/TeachingRecordSystem.Api.Tests/V3/GetTeacherTests.cs @@ -24,122 +24,132 @@ public async Task Get_TeacherWithTrnDoesNotExist_ReturnsBadRequest() } [Fact] - public Task Get_ValidRequest_ReturnsExpectedResponse() + public async Task Get_ValidRequest_ReturnsExpectedResponse() { - var trn = "1234567"; - var httpClient = GetHttpClientWithIdentityAccessToken(trn); + var contact = await CreateContact(qualifiedInWales: false); + var httpClient = GetHttpClientWithIdentityAccessToken(contact.dfeta_TRN); var baseUrl = "/v3/teacher"; - return ValidRequestForTeacher_ReturnsExpectedContent(httpClient, baseUrl, trn, qualifiedInWales: false, expectQtsCertificateUrl: true, expectEysCertificateUrl: true); + await ValidRequestForTeacher_ReturnsExpectedContent(httpClient, baseUrl, contact, expectQtsCertificateUrl: true, expectEysCertificateUrl: true); } [Fact] - public Task Get_ValidRequestForTeacherQualifiedInWales_ReturnsExpectedResponse() + public async Task Get_ValidRequestForTeacherQualifiedInWales_ReturnsExpectedResponse() { - var trn = "1234567"; - var httpClient = GetHttpClientWithIdentityAccessToken(trn); + var contact = await CreateContact(qualifiedInWales: true); + var httpClient = GetHttpClientWithIdentityAccessToken(contact.dfeta_TRN); var baseUrl = "/v3/teacher"; - return ValidRequestForTeacher_ReturnsExpectedContent(httpClient, baseUrl, trn, qualifiedInWales: true, expectQtsCertificateUrl: false, expectEysCertificateUrl: true); + await ValidRequestForTeacher_ReturnsExpectedContent(httpClient, baseUrl, contact, expectQtsCertificateUrl: false, expectEysCertificateUrl: true); } [Fact] - public Task Get_ValidRequestForContactWithMultiWordFirstName_ReturnsExpectedResponse() + public async Task Get_ValidRequestForContactWithMultiWordFirstName_ReturnsExpectedResponse() { - var trn = "1234567"; - var httpClient = GetHttpClientWithIdentityAccessToken(trn); + var contact = await CreateContact(hasMultiWordFirstName: true); + var httpClient = GetHttpClientWithIdentityAccessToken(contact.dfeta_TRN); var baseUrl = "/v3/teacher"; - return ValidRequestForTeacherWithMultiWordFirstName_ReturnsExpectedContent(httpClient, baseUrl, trn, expectCertificateUrls: true); + await ValidRequestForTeacherWithMultiWordFirstName_ReturnsExpectedContent(httpClient, baseUrl, contact, expectCertificateUrls: true); } [Fact] - public Task Get_ValidRequestWithInduction_ReturnsExpectedInductionContent() + public async Task Get_ValidRequestWithInduction_ReturnsExpectedInductionContent() { - var trn = "1234567"; - var httpClient = GetHttpClientWithIdentityAccessToken(trn); + var contact = await CreateContact(); + var httpClient = GetHttpClientWithIdentityAccessToken(contact.dfeta_TRN); var baseUrl = "/v3/teacher"; - return ValidRequestWithInduction_ReturnsExpectedInductionContent(httpClient, baseUrl, trn, expectCertificateUrls: true); + await ValidRequestWithInduction_ReturnsExpectedInductionContent(httpClient, baseUrl, contact, expectCertificateUrls: true); } [Fact] - public Task Get_ValidRequestWithInitialTeacherTraining_ReturnsExpectedInitialTeacherTrainingContent() + public async Task Get_ValidRequestWithInitialTeacherTraining_ReturnsExpectedInitialTeacherTrainingContent() { - var trn = "1234567"; - var httpClient = GetHttpClientWithIdentityAccessToken(trn); + var contact = await CreateContact(); + var httpClient = GetHttpClientWithIdentityAccessToken(contact.dfeta_TRN); var baseUrl = "/v3/teacher"; - return ValidRequestWithInitialTeacherTraining_ReturnsExpectedInitialTeacherTrainingContent(httpClient, baseUrl, trn); + await ValidRequestWithInitialTeacherTraining_ReturnsExpectedInitialTeacherTrainingContent(httpClient, baseUrl, contact); } [Fact] - public Task Get_ValidRequestWithNpqQualifications_ReturnsExpectedNpqQualificationsContent() + public async Task Get_ValidRequestWithNpqQualifications_ReturnsExpectedNpqQualificationsContent() { - var trn = "1234567"; - var httpClient = GetHttpClientWithIdentityAccessToken(trn); + var contact = await CreateContact(); + var httpClient = GetHttpClientWithIdentityAccessToken(contact.dfeta_TRN); var baseUrl = "/v3/teacher"; - return ValidRequestWithNpqQualifications_ReturnsExpectedNpqQualificationsContent(httpClient, baseUrl, trn, expectCertificateUrls: true); + await ValidRequestWithNpqQualifications_ReturnsExpectedNpqQualificationsContent(httpClient, baseUrl, contact, expectCertificateUrls: true); } [Fact] - public Task Get_ValidRequestWithMandatoryQualifications_ReturnsExpectedMandatoryQualificationsContent() + public async Task Get_ValidRequestWithMandatoryQualifications_ReturnsExpectedMandatoryQualificationsContent() { - var trn = "1234567"; - var httpClient = GetHttpClientWithIdentityAccessToken(trn); + var contact = await CreateContact(); + var httpClient = GetHttpClientWithIdentityAccessToken(contact.dfeta_TRN); var baseUrl = "/v3/teacher"; - return ValidRequestWithMandatoryQualifications_ReturnsExpectedMandatoryQualificationsContent(httpClient, baseUrl, trn); + await ValidRequestWithMandatoryQualifications_ReturnsExpectedMandatoryQualificationsContent(httpClient, baseUrl, contact); } [Fact] - public Task Get_ValidRequestWithHigherEducationQualifications_ReturnsExpectedHigherEducationQualificationsContent() + public async Task Get_ValidRequestWithHigherEducationQualifications_ReturnsExpectedHigherEducationQualificationsContent() { - var trn = "1234567"; - var httpClient = GetHttpClientWithIdentityAccessToken(trn); + var contact = await CreateContact(); + var httpClient = GetHttpClientWithIdentityAccessToken(contact.dfeta_TRN); var baseUrl = "/v3/teacher"; - return ValidRequestWithHigherEducationQualifications_ReturnsExpectedHigherEducationQualificationsContent(httpClient, baseUrl, trn); + await ValidRequestWithHigherEducationQualifications_ReturnsExpectedHigherEducationQualificationsContent(httpClient, baseUrl, contact); } [Fact] - public Task Get_ValidRequestForContactWithPendingNameChange_ReturnsPendingNameChangeTrue() + public async Task Get_ValidRequestForContactWithPendingNameChange_ReturnsPendingNameChangeTrue() { - var trn = "1234567"; - var httpClient = GetHttpClientWithIdentityAccessToken(trn); + var contact = await CreateContact(); + var httpClient = GetHttpClientWithIdentityAccessToken(contact.dfeta_TRN); var baseUrl = "v3/teacher"; - return ValidRequestForContactWithPendingNameChange_ReturnsPendingNameChangeTrue(httpClient, baseUrl, trn); + await ValidRequestForContactWithPendingNameChange_ReturnsPendingNameChangeTrue(httpClient, baseUrl, contact); } [Fact] - public Task Get_ValidRequestForContactWithPendingDateOfBirthChange_ReturnsPendingDateOfBirthChangeTrue() + public async Task Get_ValidRequestForContactWithPendingDateOfBirthChange_ReturnsPendingDateOfBirthChangeTrue() { - var trn = "1234567"; - var httpClient = GetHttpClientWithIdentityAccessToken(trn); + var contact = await CreateContact(); + var httpClient = GetHttpClientWithIdentityAccessToken(contact.dfeta_TRN); var baseUrl = "v3/teacher"; - return ValidRequestForContactWithPendingDateOfBirthChange_ReturnsPendingDateOfBirthChangeTrue(httpClient, baseUrl, trn); + await ValidRequestForContactWithPendingDateOfBirthChange_ReturnsPendingDateOfBirthChangeTrue(httpClient, baseUrl, contact); } [Fact] - public Task Get_ValidRequestWithSanctions_ReturnsExpectedSanctionsContent() + public async Task Get_ValidRequestWithSanctions_ReturnsExpectedSanctionsContent() { - var trn = "1234567"; - var httpClient = GetHttpClientWithIdentityAccessToken(trn); + var contact = await CreateContact(); + var httpClient = GetHttpClientWithIdentityAccessToken(contact.dfeta_TRN); var baseUrl = "v3/teacher"; - return ValidRequestWithSanctions_ReturnsExpectedSanctionsContent(httpClient, baseUrl, trn); + await ValidRequestWithSanctions_ReturnsExpectedSanctionsContent(httpClient, baseUrl, contact); } [Fact] - public Task Get_ValidRequestWithAlerts_ReturnsExpectedSanctionsContent() + public async Task Get_ValidRequestWithAlerts_ReturnsExpectedSanctionsContent() { - var trn = "1234567"; - var httpClient = GetHttpClientWithIdentityAccessToken(trn); + var contact = await CreateContact(); + var httpClient = GetHttpClientWithIdentityAccessToken(contact.dfeta_TRN); + var baseUrl = "v3/teacher"; + + await ValidRequestWithAlerts_ReturnsExpectedSanctionsContent(httpClient, baseUrl, contact); + } + + [Fact] + public async Task Get_ValidRequestWithPreviousNames_ReturnsExpectedPreviousNamesContent() + { + var contact = await CreateContact(); + var httpClient = GetHttpClientWithIdentityAccessToken(contact.dfeta_TRN); var baseUrl = "v3/teacher"; - return ValidRequestWithAlerts_ReturnsExpectedSanctionsContent(httpClient, baseUrl, trn); + await ValidRequestWithPreviousNames_ReturnsExpectedPreviousNamesContent(httpClient, baseUrl, contact); } } diff --git a/TeachingRecordSystem/tests/TeachingRecordSystem.Core.Dqt.Tests/QueryTests/GetAllEarlyYearsStatusesTests.cs b/TeachingRecordSystem/tests/TeachingRecordSystem.Core.Dqt.Tests/QueryTests/GetAllEarlyYearsStatusesTests.cs new file mode 100644 index 000000000..ef7c9351c --- /dev/null +++ b/TeachingRecordSystem/tests/TeachingRecordSystem.Core.Dqt.Tests/QueryTests/GetAllEarlyYearsStatusesTests.cs @@ -0,0 +1,24 @@ +namespace TeachingRecordSystem.Core.Dqt.Tests.QueryTests; + +public class GetAllEarlyYearsStatusesTests +{ + private readonly CrmQueryDispatcher _crmQueryDispatcher; + + public GetAllEarlyYearsStatusesTests(CrmClientFixture crmClientFixture) + { + _crmQueryDispatcher = crmClientFixture.CreateQueryDispatcher(); + } + + [Fact] + public async Task QueryExecutesSuccessfully() + { + // Arrange + var query = new GetAllEarlyYearsStatusesQuery(); + + // Act + var result = await _crmQueryDispatcher.ExecuteQuery(query); + + // Assert + Assert.NotEmpty(result); + } +} diff --git a/TeachingRecordSystem/tests/TeachingRecordSystem.Core.Dqt.Tests/QueryTests/GetContactDetailByTrnTests.cs b/TeachingRecordSystem/tests/TeachingRecordSystem.Core.Dqt.Tests/QueryTests/GetContactDetailByTrnTests.cs new file mode 100644 index 000000000..421ea67ef --- /dev/null +++ b/TeachingRecordSystem/tests/TeachingRecordSystem.Core.Dqt.Tests/QueryTests/GetContactDetailByTrnTests.cs @@ -0,0 +1,66 @@ +using Microsoft.Xrm.Sdk.Query; + +namespace TeachingRecordSystem.Core.Dqt.Tests.QueryTests; + +public class GetContactDetailByTrnTests : IAsyncLifetime +{ + private readonly CrmClientFixture.TestDataScope _dataScope; + private readonly CrmQueryDispatcher _crmQueryDispatcher; + + public GetContactDetailByTrnTests(CrmClientFixture crmClientFixture) + { + _dataScope = crmClientFixture.CreateTestDataScope(); + _crmQueryDispatcher = crmClientFixture.CreateQueryDispatcher(); + } + + public Task InitializeAsync() => Task.CompletedTask; + + public async Task DisposeAsync() => await _dataScope.DisposeAsync(); + + [Fact] + public async Task WhenCalled_WithTrnForNonExistentContact_ReturnsNull() + { + // Arrange + var trn = "DodgyTrn"; + + // Act + var result = await _crmQueryDispatcher.ExecuteQuery(new GetContactDetailByTrnQuery(trn, new ColumnSet())); + + // Assert + Assert.Null(result); + } + + [Fact] + public async Task WhenCalled_WithTrnForExistingContact_ReturnsContactDetail() + { + // Arrange + var person = await _dataScope.TestData.CreatePerson(b => b.WithTrn()); + + // Act + var result = await _crmQueryDispatcher.ExecuteQuery(new GetContactDetailByTrnQuery(person.Trn!, new ColumnSet())); + + // Assert + Assert.NotNull(result); + Assert.Equal(result.Contact.Id, person.ContactId); + Assert.Empty(result.PreviousNames); + } + + [Fact] + public async Task WhenCalled_WithTrnForExistingContactWithPreviousName_ReturnsContactDetailIncludingPreviousNames() + { + // Arrange + var updatedFirstName = _dataScope.TestData.GenerateFirstName(); + var updatedMiddleName = _dataScope.TestData.GenerateMiddleName(); + var updatedLastName = _dataScope.TestData.GenerateLastName(); + var person = await _dataScope.TestData.CreatePerson(b => b.WithTrn()); + await _dataScope.TestData.UpdatePerson(b => b.WithPersonId(person.ContactId).WithUpdatedName(updatedFirstName, updatedMiddleName, updatedLastName)); + + // Act + var result = await _crmQueryDispatcher.ExecuteQuery(new GetContactDetailByTrnQuery(person.Trn!, new ColumnSet())); + + // Assert + Assert.NotNull(result); + Assert.Equal(result.Contact.Id, person.ContactId); + Assert.Equal(3, result.PreviousNames.Length); + } +} diff --git a/TeachingRecordSystem/tests/TeachingRecordSystem.Core.Dqt.Tests/Usings.cs b/TeachingRecordSystem/tests/TeachingRecordSystem.Core.Dqt.Tests/Usings.cs index cd2ca3047..c0029d5f4 100644 --- a/TeachingRecordSystem/tests/TeachingRecordSystem.Core.Dqt.Tests/Usings.cs +++ b/TeachingRecordSystem/tests/TeachingRecordSystem.Core.Dqt.Tests/Usings.cs @@ -1,4 +1,3 @@ -global using Moq; global using TeachingRecordSystem.Core.Dqt.Models; global using TeachingRecordSystem.Core.Dqt.Queries; global using TeachingRecordSystem.TestCommon; diff --git a/TeachingRecordSystem/tests/TeachingRecordSystem.TestCommon/CrmTestData.CreatePerson.cs b/TeachingRecordSystem/tests/TeachingRecordSystem.TestCommon/CrmTestData.CreatePerson.cs index 1da79f40c..97979cc9c 100644 --- a/TeachingRecordSystem/tests/TeachingRecordSystem.TestCommon/CrmTestData.CreatePerson.cs +++ b/TeachingRecordSystem/tests/TeachingRecordSystem.TestCommon/CrmTestData.CreatePerson.cs @@ -16,6 +16,9 @@ public Task CreatePerson(Action? config public class CreatePersonBuilder { + private const string TeacherStatusQualifiedTeacherTrained = "71"; + private const string EaryYearsStatusProfessionalStatus = "222"; + private DateOnly? _dateOfBirth; private bool? _hasTrn; private string? _firstName; @@ -23,8 +26,12 @@ public class CreatePersonBuilder private string? _lastName; private string? _email; private string? _mobileNumber; - private bool? _hasNationalInsuranceNumber; private Contact_GenderCode? _gender; + private bool? _hasNationalInsuranceNumber; + private DateOnly? _qtsDate; + private string? _teacherStatus; + private DateOnly? _eytsDate; + private string? _earlyYearsStatus; private readonly List _sanctions = new(); public CreatePersonBuilder WithDateOfBirth(DateOnly dateOfBirth) @@ -140,13 +147,39 @@ public CreatePersonBuilder WithNationalInsuranceNumber(bool? hasNationalInsuranc return this; } + public CreatePersonBuilder WithQts(DateOnly qtsDate, string teacherStatus = TeacherStatusQualifiedTeacherTrained) + { + if ((_qtsDate is not null && _qtsDate != qtsDate) || (_teacherStatus is not null && _teacherStatus != teacherStatus)) + { + throw new InvalidOperationException("WithQts cannot be changed after it's set."); + } + + _qtsDate = qtsDate; + _teacherStatus = teacherStatus; + return this; + } + + public CreatePersonBuilder WithEyts(DateOnly eytsDate, string earlyYearsStatus = EaryYearsStatusProfessionalStatus) + { + if ((_eytsDate is not null && _eytsDate != eytsDate) || (_earlyYearsStatus is not null && _earlyYearsStatus != earlyYearsStatus)) + { + throw new InvalidOperationException("WithEyts cannot be changed after it's set."); + } + + _eytsDate = eytsDate; + _earlyYearsStatus = earlyYearsStatus; + return this; + } + public async Task Execute(CrmTestData testData) { var hasTrn = _hasTrn ?? true; var trn = hasTrn ? await testData.GenerateTrn() : null; - - var firstName = _firstName ?? testData.GenerateFirstName(); - var middleName = _middleName ?? testData.GenerateMiddleName(); + var statedFirstName = _firstName ?? testData.GenerateFirstName(); + var statedMiddleName = _middleName ?? testData.GenerateMiddleName(); + var firstAndMiddleNames = $"{statedFirstName} {statedMiddleName}".Split(' ', StringSplitOptions.RemoveEmptyEntries | StringSplitOptions.TrimEntries); + var firstName = firstAndMiddleNames.First(); + var middleName = string.Join(" ", firstAndMiddleNames.Skip(1)); var lastName = _lastName ?? testData.GenerateLastName(); var dateOfBirth = _dateOfBirth ?? testData.GenerateDateOfBirth(); var gender = _gender ?? testData.GenerateGender(); @@ -159,6 +192,9 @@ public async Task Execute(CrmTestData testData) FirstName = firstName, MiddleName = middleName, LastName = lastName, + dfeta_StatedFirstName = statedFirstName, + dfeta_StatedMiddleName = statedMiddleName, + dfeta_StatedLastName = lastName, BirthDate = dateOfBirth.ToDateTime(new TimeOnly()), dfeta_TRN = trn, GenderCode = gender @@ -182,6 +218,54 @@ public async Task Execute(CrmTestData testData) var txnRequestBuilder = RequestBuilder.CreateTransaction(testData.OrganizationService); txnRequestBuilder.AddRequest(new CreateRequest() { Target = contact }); + if (_qtsDate is not null && _teacherStatus is not null) + { + var teacherStatus = await testData.ReferenceDataCache.GetTeacherStatusByValue(_teacherStatus); + var qtsRegistrationId = Guid.NewGuid(); + txnRequestBuilder.AddRequest(new CreateRequest() + { + Target = new dfeta_qtsregistration() + { + Id = qtsRegistrationId, + dfeta_PersonId = personId.ToEntityReference(Contact.EntityLogicalName) + } + }); + // Plugin which updates Contact with QTS Date only fires on Update or Delete + txnRequestBuilder.AddRequest(new UpdateRequest() + { + Target = new dfeta_qtsregistration() + { + Id = qtsRegistrationId, + dfeta_QTSDate = _qtsDate.Value.FromDateOnlyWithDqtBstFix(isLocalTime: true), + dfeta_TeacherStatusId = teacherStatus.Id.ToEntityReference(dfeta_teacherstatus.EntityLogicalName), + } + }); + } + + if (_eytsDate is not null && _earlyYearsStatus is not null) + { + var earlyYearsStatus = await testData.ReferenceDataCache.GetEarlyYearsStatusByValue(_earlyYearsStatus); + var eytsRegistrationId = Guid.NewGuid(); + txnRequestBuilder.AddRequest(new CreateRequest() + { + Target = new dfeta_qtsregistration() + { + Id = eytsRegistrationId, + dfeta_PersonId = personId.ToEntityReference(Contact.EntityLogicalName) + } + }); + // Plugin which updates Contact with EYTS Date only fires on Update or Delete + txnRequestBuilder.AddRequest(new UpdateRequest() + { + Target = new dfeta_qtsregistration() + { + Id = eytsRegistrationId, + dfeta_EYTSDate = _eytsDate.Value.FromDateOnlyWithDqtBstFix(isLocalTime: true), + dfeta_EarlyYearsStatusId = earlyYearsStatus.Id.ToEntityReference(dfeta_earlyyearsstatus.EntityLogicalName), + } + }); + } + foreach (var sanction in _sanctions) { var sanctionCode = await testData.ReferenceDataCache.GetSanctionCodeByValue(sanction.SanctionCode); @@ -230,10 +314,15 @@ public async Task Execute(CrmTestData testData) FirstName = firstName, MiddleName = middleName, LastName = lastName, + StatedFirstName = statedFirstName, + StatedMiddleName = statedMiddleName, + StatedLastName = lastName, Email = _email, MobileNumber = _mobileNumber, Gender = gender.ToString(), NationalInsuranceNumber = contact.dfeta_NINumber, + QtsDate = _qtsDate, + EytsDate = _eytsDate, Sanctions = _sanctions.ToImmutableArray() }; } @@ -248,10 +337,15 @@ public record CreatePersonResult public required string FirstName { get; init; } public required string MiddleName { get; init; } public required string LastName { get; init; } + public required string StatedFirstName { get; init; } + public required string StatedMiddleName { get; init; } + public required string StatedLastName { get; init; } public required string? Email { get; init; } public required string? MobileNumber { get; init; } public required string Gender { get; init; } public required string? NationalInsuranceNumber { get; init; } + public required DateOnly? QtsDate { get; init; } + public required DateOnly? EytsDate { get; init; } public required ImmutableArray Sanctions { get; init; } public Contact ToContact() => new() @@ -260,14 +354,16 @@ public record CreatePersonResult FirstName = FirstName, MiddleName = MiddleName, LastName = LastName, - dfeta_StatedFirstName = FirstName, - dfeta_StatedMiddleName = MiddleName, - dfeta_StatedLastName = LastName, + dfeta_StatedFirstName = StatedFirstName, + dfeta_StatedMiddleName = StatedMiddleName, + dfeta_StatedLastName = StatedLastName, BirthDate = DateOfBirth.FromDateOnlyWithDqtBstFix(isLocalTime: false), dfeta_TRN = Trn, EMailAddress1 = Email, MobilePhone = MobileNumber, dfeta_NINumber = NationalInsuranceNumber, + dfeta_QTSDate = QtsDate?.FromDateOnlyWithDqtBstFix(isLocalTime: true), + dfeta_EYTSDate = EytsDate?.FromDateOnlyWithDqtBstFix(isLocalTime: true), GenderCode = Enum.Parse(Gender) }; } diff --git a/TeachingRecordSystem/tests/TeachingRecordSystem.TestCommon/CrmTestData.UpdatePerson.cs b/TeachingRecordSystem/tests/TeachingRecordSystem.TestCommon/CrmTestData.UpdatePerson.cs index a4b79519d..638ca85b7 100644 --- a/TeachingRecordSystem/tests/TeachingRecordSystem.TestCommon/CrmTestData.UpdatePerson.cs +++ b/TeachingRecordSystem/tests/TeachingRecordSystem.TestCommon/CrmTestData.UpdatePerson.cs @@ -15,7 +15,7 @@ public Task UpdatePerson(Action? configure) public class UpdatePersonBuilder { private Guid? _personId = null; - private (string FirstName, string MiddleName, string LastName)? _updatedName = null; + private (string FirstName, string? MiddleName, string LastName)? _updatedName = null; public UpdatePersonBuilder WithPersonId(Guid personId) { @@ -28,7 +28,7 @@ public UpdatePersonBuilder WithPersonId(Guid personId) return this; } - public UpdatePersonBuilder WithUpdatedName(string firstName, string middleName, string lastName) + public UpdatePersonBuilder WithUpdatedName(string firstName, string? middleName, string lastName) { if (_updatedName is not null) { diff --git a/TeachingRecordSystem/tests/TeachingRecordSystem.TestCommon/Infrastructure/FakeXrmEasy/Plugins/QtsRegistrationUpdatedPlugin.cs b/TeachingRecordSystem/tests/TeachingRecordSystem.TestCommon/Infrastructure/FakeXrmEasy/Plugins/QtsRegistrationUpdatedPlugin.cs new file mode 100644 index 000000000..d19a02901 --- /dev/null +++ b/TeachingRecordSystem/tests/TeachingRecordSystem.TestCommon/Infrastructure/FakeXrmEasy/Plugins/QtsRegistrationUpdatedPlugin.cs @@ -0,0 +1,115 @@ +using FakeXrmEasy.Abstractions; +using FakeXrmEasy.Abstractions.Plugins.Enums; +using FakeXrmEasy.Pipeline; +using FakeXrmEasy.Plugins.Definitions; +using FakeXrmEasy.Plugins.PluginImages; +using FakeXrmEasy.Plugins.PluginSteps; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Xrm.Sdk; +using Microsoft.Xrm.Sdk.Messages; +using TeachingRecordSystem.Core.Dqt.Models; + +namespace TeachingRecordSystem.TestCommon.Infrastructure.FakeXrmEasy.Plugins; + +/// +/// This plugin mirrors the poorly named QTSRegistrationDeletPlugin in CRM. +/// +public class QtsRegistrationUpdatedPlugin : IPlugin +{ + internal static void Register(IXrmFakedContext context) + { + var preImageDefinition = new PluginImageDefinition( + "preImage", + ProcessingStepImageType.PreImage, + new string[] + { + dfeta_qtsregistration.Fields.dfeta_PersonId, + dfeta_qtsregistration.Fields.dfeta_QTSDate, + dfeta_qtsregistration.Fields.dfeta_EYTSDate + }); + context.RegisterPluginStep( + new PluginStepDefinition() + { + EntityLogicalName = dfeta_qtsregistration.EntityLogicalName, + MessageName = "Delete", + Stage = ProcessingStepStage.Postoperation, + ImagesDefinitions = new List() { preImageDefinition } + }); + context.RegisterPluginStep( + new PluginStepDefinition() + { + EntityLogicalName = dfeta_qtsregistration.EntityLogicalName, + MessageName = "Update", + Stage = ProcessingStepStage.Postoperation, + ImagesDefinitions = new List() { preImageDefinition } + }); + } + + public void Execute(IServiceProvider serviceProvider) + { + var context = serviceProvider.GetRequiredService(); + var orgService = serviceProvider.GetRequiredService(); + + if (context.PreEntityImages.TryGetValue("preImage", out var preImage)) + { + if (preImage.TryGetAttributeValue(dfeta_qtsregistration.Fields.dfeta_PersonId, out var personIdEntityReference)) + { + var personId = personIdEntityReference.Id; + if (context.MessageName == "Delete") + { + UpdatePersonQtsDate(orgService, personId, null); + UpdatePersonEytsDate(orgService, personId, null); + } + else + { + var target = context.InputParameters["Target"] as Entity; + var state = target!.GetAttributeValue(dfeta_qtsregistration.Fields.StateCode); + if (state?.Value == 1) + { + UpdatePersonQtsDate(orgService, personId, null); + UpdatePersonEytsDate(orgService, personId, null); + } + else + { + var qtsDate = target.GetAttributeValue(dfeta_qtsregistration.Fields.dfeta_QTSDate); + var eytsDate = target.GetAttributeValue(dfeta_qtsregistration.Fields.dfeta_EYTSDate); + + if (qtsDate.HasValue) + { + UpdatePersonQtsDate(orgService, personId, qtsDate); + } + + if (eytsDate.HasValue) + { + UpdatePersonEytsDate(orgService, personId, eytsDate); + } + } + } + } + } + } + + private void UpdatePersonQtsDate(IOrganizationService orgService, Guid personId, DateTime? qtsDate) + { + orgService.Execute(new UpdateRequest() + { + Target = new Contact() + { + Id = personId, + dfeta_QTSDate = qtsDate + } + }); + } + + private void UpdatePersonEytsDate(IOrganizationService orgService, Guid personId, DateTime? eytsDate) + { + orgService.Execute(new UpdateRequest() + { + Target = new Contact() + { + Id = personId, + dfeta_EYTSDate = eytsDate + } + }); + } +} diff --git a/TeachingRecordSystem/tests/TeachingRecordSystem.TestCommon/SeedCrmReferenceData.cs b/TeachingRecordSystem/tests/TeachingRecordSystem.TestCommon/SeedCrmReferenceData.cs index 3d34a256b..0ad476e25 100644 --- a/TeachingRecordSystem/tests/TeachingRecordSystem.TestCommon/SeedCrmReferenceData.cs +++ b/TeachingRecordSystem/tests/TeachingRecordSystem.TestCommon/SeedCrmReferenceData.cs @@ -17,6 +17,8 @@ public Task Execute() { AddSubjects(); AddSanctionCodes(); + AddTeacherStatuses(); + AddEarlyYearsStatuses(); return Task.CompletedTask; } @@ -66,4 +68,56 @@ private void AddSanctionCodes() dfeta_name = "B1 Description" }); } + + private void AddTeacherStatuses() + { + _xrmFakedContext.CreateEntity(new dfeta_teacherstatus() + { + dfeta_Value = "71", + dfeta_name = "Qualified Teacher (trained)", + dfeta_QTSDateRequired = true + }); + + _xrmFakedContext.CreateEntity(new dfeta_teacherstatus() + { + dfeta_Value = "100", + dfeta_name = "Qualified Teacher: Assessment Only Route", + dfeta_QTSDateRequired = true + }); + + _xrmFakedContext.CreateEntity(new dfeta_teacherstatus() + { + dfeta_Value = "90", + dfeta_name = "Qualified teacher: by virtue of achieving international qualified teacher status", + dfeta_QTSDateRequired = true + }); + + _xrmFakedContext.CreateEntity(new dfeta_teacherstatus() + { + dfeta_Value = "213", + dfeta_name = "Qualified Teacher: QTS awarded in Wales", + dfeta_QTSDateRequired = true + }); + } + + private void AddEarlyYearsStatuses() + { + _xrmFakedContext.CreateEntity(new dfeta_earlyyearsstatus() + { + dfeta_Value = "220", + dfeta_name = "Early Years Trainee", + }); + + _xrmFakedContext.CreateEntity(new dfeta_earlyyearsstatus() + { + dfeta_Value = "221", + dfeta_name = "Early Years Teacher Status" + }); + + _xrmFakedContext.CreateEntity(new dfeta_earlyyearsstatus() + { + dfeta_Value = "222", + dfeta_name = "Early Years Professional Status" + }); + } } diff --git a/TeachingRecordSystem/tests/TeachingRecordSystem.TestCommon/ServiceCollectionExtensions.cs b/TeachingRecordSystem/tests/TeachingRecordSystem.TestCommon/ServiceCollectionExtensions.cs index 6692a8468..1167cf0a4 100644 --- a/TeachingRecordSystem/tests/TeachingRecordSystem.TestCommon/ServiceCollectionExtensions.cs +++ b/TeachingRecordSystem/tests/TeachingRecordSystem.TestCommon/ServiceCollectionExtensions.cs @@ -48,6 +48,7 @@ public static IServiceCollection AddFakeXrm(this IServiceCollection services) AssignTicketNumberToIncidentPlugin.Register(fakedXrmContext); PersonNameChangedPlugin.Register(fakedXrmContext); CalculateActiveSanctionsPlugin.Register(fakedXrmContext); + QtsRegistrationUpdatedPlugin.Register(fakedXrmContext); services.AddSingleton(fakedXrmContext); var organizationService = fakedXrmContext.GetAsyncOrganizationService();