diff --git a/TeachingRecordSystem/src/TeachingRecordSystem.Api/ApiError.cs b/TeachingRecordSystem/src/TeachingRecordSystem.Api/ApiError.cs index a3809a1ba4..86e94653f1 100644 --- a/TeachingRecordSystem/src/TeachingRecordSystem.Api/ApiError.cs +++ b/TeachingRecordSystem/src/TeachingRecordSystem.Api/ApiError.cs @@ -36,6 +36,7 @@ public static class ErrorCodes public static int UnableToChangeFailProfessionalStatusStatus => 10055; public static int UnableToChangeWithdrawnProfessionalStatusStatus => 10056; public static int PiiUpdatesForbiddenPersonHasEyts => 10057; + public static int PersonInactive => 10058; } public static ApiError PersonNotFound(string trn, DateOnly? dateOfBirth = null, string? nationalInsuranceNumber = null) @@ -55,6 +56,13 @@ public static ApiError PersonNotFound(string trn, DateOnly? dateOfBirth = null, return new ApiError(ErrorCodes.PersonNotFound, title, detail); } + public static ApiError PersonInactive(string trn) + { + var title = $"Person is inactive."; + + return new ApiError(ErrorCodes.PersonInactive, title); + } + public static ApiError SpecifiedResourceUrlDoesNotExist(string url) => new(ErrorCodes.SpecifiedResourceUrlDoesNotExist, "The specified resource does not exist.", $"URL: '{url}'"); diff --git a/TeachingRecordSystem/src/TeachingRecordSystem.Api/V3/Implementation/Operations/GetPerson.cs b/TeachingRecordSystem/src/TeachingRecordSystem.Api/V3/Implementation/Operations/GetPerson.cs index 930c256b6f..2c50cff7e0 100644 --- a/TeachingRecordSystem/src/TeachingRecordSystem.Api/V3/Implementation/Operations/GetPerson.cs +++ b/TeachingRecordSystem/src/TeachingRecordSystem.Api/V3/Implementation/Operations/GetPerson.cs @@ -178,7 +178,7 @@ public async Task> HandleAsync(GetPersonCommand comma } var contactDetail = await crmQueryDispatcher.ExecuteQueryAsync( - new GetActiveContactDetailByTrnQuery( + new GetContactDetailByTrnQuery( command.Trn, new ColumnSet( Contact.Fields.FirstName, @@ -203,6 +203,11 @@ public async Task> HandleAsync(GetPersonCommand comma return ApiError.PersonNotFound(command.Trn); } + if (contactDetail.Contact.StateCode is ContactState.Inactive) + { + return ApiError.PersonInactive(command.Trn); + } + // If a DateOfBirth or NationalInsuranceNumber was provided, ensure the record we've retrieved with the TRN matches if (command.DateOfBirth is DateOnly dateOfBirth && contactDetail.Contact.BirthDate.ToDateOnlyWithDqtBstFix(isLocalTime: false) != dateOfBirth) diff --git a/TeachingRecordSystem/src/TeachingRecordSystem.Api/V3/V20240101/Controllers/TeacherController.cs b/TeachingRecordSystem/src/TeachingRecordSystem.Api/V3/V20240101/Controllers/TeacherController.cs index e65d111031..826e629bc7 100644 --- a/TeachingRecordSystem/src/TeachingRecordSystem.Api/V3/V20240101/Controllers/TeacherController.cs +++ b/TeachingRecordSystem/src/TeachingRecordSystem.Api/V3/V20240101/Controllers/TeacherController.cs @@ -35,6 +35,7 @@ public async Task GetAsync( var result = await handler.HandleAsync(command); return result.ToActionResult(r => Ok(mapper.Map(r))) + .MapErrorCode(ApiError.ErrorCodes.PersonNotFound, StatusCodes.Status403Forbidden) .MapErrorCode(ApiError.ErrorCodes.PersonNotFound, StatusCodes.Status403Forbidden); } } diff --git a/TeachingRecordSystem/src/TeachingRecordSystem.Api/V3/V20240101/Controllers/TeachersController.cs b/TeachingRecordSystem/src/TeachingRecordSystem.Api/V3/V20240101/Controllers/TeachersController.cs index b85f433465..a3c4735d6c 100644 --- a/TeachingRecordSystem/src/TeachingRecordSystem.Api/V3/V20240101/Controllers/TeachersController.cs +++ b/TeachingRecordSystem/src/TeachingRecordSystem.Api/V3/V20240101/Controllers/TeachersController.cs @@ -36,7 +36,8 @@ public async Task GetAsync( var result = await handler.HandleAsync(command); return result.ToActionResult(r => Ok(mapper.Map(r))) - .MapErrorCode(ApiError.ErrorCodes.PersonNotFound, StatusCodes.Status404NotFound); + .MapErrorCode(ApiError.ErrorCodes.PersonNotFound, StatusCodes.Status404NotFound) + .MapErrorCode(ApiError.ErrorCodes.PersonInactive, StatusCodes.Status404NotFound); } [HttpPost("name-changes")] diff --git a/TeachingRecordSystem/src/TeachingRecordSystem.Api/V3/V20240416/Controllers/TeacherController.cs b/TeachingRecordSystem/src/TeachingRecordSystem.Api/V3/V20240416/Controllers/TeacherController.cs index 557a4502eb..08d3d51ca9 100644 --- a/TeachingRecordSystem/src/TeachingRecordSystem.Api/V3/V20240416/Controllers/TeacherController.cs +++ b/TeachingRecordSystem/src/TeachingRecordSystem.Api/V3/V20240416/Controllers/TeacherController.cs @@ -35,6 +35,7 @@ public async Task GetAsync( var result = await handler.HandleAsync(command); return result.ToActionResult(r => Ok(mapper.Map(r))) - .MapErrorCode(ApiError.ErrorCodes.PersonNotFound, StatusCodes.Status403Forbidden); + .MapErrorCode(ApiError.ErrorCodes.PersonNotFound, StatusCodes.Status403Forbidden) + .MapErrorCode(ApiError.ErrorCodes.PersonInactive, StatusCodes.Status403Forbidden); } } diff --git a/TeachingRecordSystem/src/TeachingRecordSystem.Api/V3/V20240416/Controllers/TeachersController.cs b/TeachingRecordSystem/src/TeachingRecordSystem.Api/V3/V20240416/Controllers/TeachersController.cs index 329306c915..cbbd441394 100644 --- a/TeachingRecordSystem/src/TeachingRecordSystem.Api/V3/V20240416/Controllers/TeachersController.cs +++ b/TeachingRecordSystem/src/TeachingRecordSystem.Api/V3/V20240416/Controllers/TeachersController.cs @@ -37,6 +37,7 @@ public async Task GetAsync( var result = await handler.HandleAsync(command); return result.ToActionResult(r => Ok(mapper.Map(r))) - .MapErrorCode(ApiError.ErrorCodes.PersonNotFound, StatusCodes.Status404NotFound); + .MapErrorCode(ApiError.ErrorCodes.PersonNotFound, StatusCodes.Status404NotFound) + .MapErrorCode(ApiError.ErrorCodes.PersonInactive, StatusCodes.Status404NotFound); } } diff --git a/TeachingRecordSystem/src/TeachingRecordSystem.Api/V3/V20240606/Controllers/PersonController.cs b/TeachingRecordSystem/src/TeachingRecordSystem.Api/V3/V20240606/Controllers/PersonController.cs index 3652f9ea9e..c37f069b23 100644 --- a/TeachingRecordSystem/src/TeachingRecordSystem.Api/V3/V20240606/Controllers/PersonController.cs +++ b/TeachingRecordSystem/src/TeachingRecordSystem.Api/V3/V20240606/Controllers/PersonController.cs @@ -35,7 +35,8 @@ public async Task GetAsync( var result = await handler.HandleAsync(command); return result.ToActionResult(r => Ok(mapper.Map(r))) - .MapErrorCode(ApiError.ErrorCodes.PersonNotFound, StatusCodes.Status403Forbidden); + .MapErrorCode(ApiError.ErrorCodes.PersonNotFound, StatusCodes.Status403Forbidden) + .MapErrorCode(ApiError.ErrorCodes.PersonInactive, StatusCodes.Status403Forbidden); } [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 0728d1f0c7..8337b1c8b0 100644 --- a/TeachingRecordSystem/src/TeachingRecordSystem.Api/V3/V20240606/Controllers/PersonsController.cs +++ b/TeachingRecordSystem/src/TeachingRecordSystem.Api/V3/V20240606/Controllers/PersonsController.cs @@ -37,7 +37,8 @@ public async Task GetAsync( var result = await handler.HandleAsync(command); return result.ToActionResult(r => Ok(mapper.Map(r))) - .MapErrorCode(ApiError.ErrorCodes.PersonNotFound, StatusCodes.Status404NotFound); + .MapErrorCode(ApiError.ErrorCodes.PersonNotFound, StatusCodes.Status404NotFound) + .MapErrorCode(ApiError.ErrorCodes.PersonInactive, StatusCodes.Status404NotFound); } [HttpGet("")] diff --git a/TeachingRecordSystem/src/TeachingRecordSystem.Api/V3/V20240920/Controllers/PersonController.cs b/TeachingRecordSystem/src/TeachingRecordSystem.Api/V3/V20240920/Controllers/PersonController.cs index e448682ac0..0a49076869 100644 --- a/TeachingRecordSystem/src/TeachingRecordSystem.Api/V3/V20240920/Controllers/PersonController.cs +++ b/TeachingRecordSystem/src/TeachingRecordSystem.Api/V3/V20240920/Controllers/PersonController.cs @@ -35,6 +35,7 @@ public async Task GetAsync( var result = await handler.HandleAsync(command); return result.ToActionResult(r => Ok(mapper.Map(r))) - .MapErrorCode(ApiError.ErrorCodes.PersonNotFound, StatusCodes.Status403Forbidden); + .MapErrorCode(ApiError.ErrorCodes.PersonNotFound, StatusCodes.Status403Forbidden) + .MapErrorCode(ApiError.ErrorCodes.PersonInactive, StatusCodes.Status403Forbidden); } } diff --git a/TeachingRecordSystem/src/TeachingRecordSystem.Api/V3/V20240920/Controllers/PersonsController.cs b/TeachingRecordSystem/src/TeachingRecordSystem.Api/V3/V20240920/Controllers/PersonsController.cs index 1e7fbb280e..9525b49936 100644 --- a/TeachingRecordSystem/src/TeachingRecordSystem.Api/V3/V20240920/Controllers/PersonsController.cs +++ b/TeachingRecordSystem/src/TeachingRecordSystem.Api/V3/V20240920/Controllers/PersonsController.cs @@ -40,6 +40,7 @@ public async Task GetAsync( return result.ToActionResult(r => Ok(mapper.Map(r))) .MapErrorCode(ApiError.ErrorCodes.PersonNotFound, StatusCodes.Status404NotFound) + .MapErrorCode(ApiError.ErrorCodes.PersonInactive, StatusCodes.Status404NotFound) .MapErrorCode(ApiError.ErrorCodes.ForbiddenForAppropriateBody, StatusCodes.Status403Forbidden); } diff --git a/TeachingRecordSystem/src/TeachingRecordSystem.Api/V3/V20250203/Controllers/PersonController.cs b/TeachingRecordSystem/src/TeachingRecordSystem.Api/V3/V20250203/Controllers/PersonController.cs index ec1e05e21d..083956bda3 100644 --- a/TeachingRecordSystem/src/TeachingRecordSystem.Api/V3/V20250203/Controllers/PersonController.cs +++ b/TeachingRecordSystem/src/TeachingRecordSystem.Api/V3/V20250203/Controllers/PersonController.cs @@ -35,6 +35,7 @@ public async Task GetAsync( var result = await handler.HandleAsync(command); return result.ToActionResult(r => Ok(mapper.Map(r))) - .MapErrorCode(ApiError.ErrorCodes.PersonNotFound, StatusCodes.Status403Forbidden); + .MapErrorCode(ApiError.ErrorCodes.PersonNotFound, StatusCodes.Status403Forbidden) + .MapErrorCode(ApiError.ErrorCodes.PersonInactive, StatusCodes.Status403Forbidden); } } diff --git a/TeachingRecordSystem/src/TeachingRecordSystem.Api/V3/V20250203/Controllers/PersonsController.cs b/TeachingRecordSystem/src/TeachingRecordSystem.Api/V3/V20250203/Controllers/PersonsController.cs index f25a1db4b8..8d21c7c42e 100644 --- a/TeachingRecordSystem/src/TeachingRecordSystem.Api/V3/V20250203/Controllers/PersonsController.cs +++ b/TeachingRecordSystem/src/TeachingRecordSystem.Api/V3/V20250203/Controllers/PersonsController.cs @@ -77,6 +77,7 @@ public async Task GetAsync( return result .ToActionResult(r => Ok(mapper.Map(r))) .MapErrorCode(ApiError.ErrorCodes.PersonNotFound, StatusCodes.Status404NotFound) + .MapErrorCode(ApiError.ErrorCodes.PersonInactive, StatusCodes.Status404NotFound) .MapErrorCode(ApiError.ErrorCodes.ForbiddenForAppropriateBody, StatusCodes.Status403Forbidden); } diff --git a/TeachingRecordSystem/src/TeachingRecordSystem.Api/V3/V20250327/Controllers/PersonController.cs b/TeachingRecordSystem/src/TeachingRecordSystem.Api/V3/V20250327/Controllers/PersonController.cs index bd9d19cc57..5fb32913d5 100644 --- a/TeachingRecordSystem/src/TeachingRecordSystem.Api/V3/V20250327/Controllers/PersonController.cs +++ b/TeachingRecordSystem/src/TeachingRecordSystem.Api/V3/V20250327/Controllers/PersonController.cs @@ -35,6 +35,7 @@ public async Task GetAsync( var result = await handler.HandleAsync(command); return result.ToActionResult(r => Ok(mapper.Map(r))) - .MapErrorCode(ApiError.ErrorCodes.PersonNotFound, StatusCodes.Status403Forbidden); + .MapErrorCode(ApiError.ErrorCodes.PersonNotFound, StatusCodes.Status403Forbidden) + .MapErrorCode(ApiError.ErrorCodes.PersonInactive, StatusCodes.Status403Forbidden); } } diff --git a/TeachingRecordSystem/src/TeachingRecordSystem.Api/V3/V20250327/Controllers/PersonsController.cs b/TeachingRecordSystem/src/TeachingRecordSystem.Api/V3/V20250327/Controllers/PersonsController.cs index b1bf920001..cb93ba989d 100644 --- a/TeachingRecordSystem/src/TeachingRecordSystem.Api/V3/V20250327/Controllers/PersonsController.cs +++ b/TeachingRecordSystem/src/TeachingRecordSystem.Api/V3/V20250327/Controllers/PersonsController.cs @@ -49,6 +49,7 @@ public async Task GetAsync( return result .ToActionResult(r => Ok(mapper.Map(r))) .MapErrorCode(ApiError.ErrorCodes.PersonNotFound, StatusCodes.Status404NotFound) + .MapErrorCode(ApiError.ErrorCodes.PersonInactive, StatusCodes.Status404NotFound) .MapErrorCode(ApiError.ErrorCodes.ForbiddenForAppropriateBody, StatusCodes.Status403Forbidden); } diff --git a/TeachingRecordSystem/src/TeachingRecordSystem.Core/Dqt/Queries/GetActiveContactDetailByTrnQuery.cs b/TeachingRecordSystem/src/TeachingRecordSystem.Core/Dqt/Queries/GetActiveContactDetailByTrnQuery.cs deleted file mode 100644 index 039debc0b6..0000000000 --- a/TeachingRecordSystem/src/TeachingRecordSystem.Core/Dqt/Queries/GetActiveContactDetailByTrnQuery.cs +++ /dev/null @@ -1,5 +0,0 @@ -using Microsoft.Xrm.Sdk.Query; - -namespace TeachingRecordSystem.Core.Dqt.Queries; - -public record GetActiveContactDetailByTrnQuery(string Trn, ColumnSet ColumnSet) : 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 0000000000..9dd48e8ecd --- /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/GetActiveContactDetailByTrnHandler.cs b/TeachingRecordSystem/src/TeachingRecordSystem.Core/Dqt/QueryHandlers/GetContactDetailByTrnHandler.cs similarity index 87% rename from TeachingRecordSystem/src/TeachingRecordSystem.Core/Dqt/QueryHandlers/GetActiveContactDetailByTrnHandler.cs rename to TeachingRecordSystem/src/TeachingRecordSystem.Core/Dqt/QueryHandlers/GetContactDetailByTrnHandler.cs index fee4fea314..1f1bc0f2c3 100644 --- a/TeachingRecordSystem/src/TeachingRecordSystem.Core/Dqt/QueryHandlers/GetActiveContactDetailByTrnHandler.cs +++ b/TeachingRecordSystem/src/TeachingRecordSystem.Core/Dqt/QueryHandlers/GetContactDetailByTrnHandler.cs @@ -5,16 +5,17 @@ namespace TeachingRecordSystem.Core.Dqt.QueryHandlers; -public class GetActiveContactDetailByTrnHandler : ICrmQueryHandler +public class GetContactDetailByTrnHandler : ICrmQueryHandler { - public async Task ExecuteAsync(GetActiveContactDetailByTrnQuery query, IOrganizationServiceAsync organizationService) + public async Task ExecuteAsync(GetContactDetailByTrnQuery query, IOrganizationServiceAsync organizationService) { + var columns = query.ColumnSet.AllColumns ? query.ColumnSet : new ColumnSet(query.ColumnSet.Columns.Append(Contact.Fields.StateCode).ToArray()); + var contactFilter = new FilterExpression(); contactFilter.AddCondition(Contact.Fields.dfeta_TRN, ConditionOperator.Equal, query.Trn); - contactFilter.AddCondition(Contact.Fields.StateCode, ConditionOperator.Equal, (int)ContactState.Active); var contactQueryExpression = new QueryExpression(Contact.EntityLogicalName) { - ColumnSet = query.ColumnSet, + ColumnSet = columns, Criteria = contactFilter }; diff --git a/TeachingRecordSystem/tests/TeachingRecordSystem.Api.IntegrationTests/V3/V20240101/GetTeacherByTrnTests.cs b/TeachingRecordSystem/tests/TeachingRecordSystem.Api.IntegrationTests/V3/V20240101/GetTeacherByTrnTests.cs index b4a3c0df2e..935e192b7c 100644 --- a/TeachingRecordSystem/tests/TeachingRecordSystem.Api.IntegrationTests/V3/V20240101/GetTeacherByTrnTests.cs +++ b/TeachingRecordSystem/tests/TeachingRecordSystem.Api.IntegrationTests/V3/V20240101/GetTeacherByTrnTests.cs @@ -311,4 +311,19 @@ public async Task Get_ValidRequestWithPreviousNames_ReturnsExpectedPreviousNames await ValidRequestWithPreviousNames_ReturnsExpectedPreviousNamesContent(GetHttpClientWithApiKey(), baseUrl, contact); } + + [Fact] + public async Task ValidRequest_ForInactiveContact_ReturnsNotFound() + { + // Arrange + var person = await TestData.CreatePersonAsync(p => p.WithTrn().WithContactState(ContactState.Inactive)); + + var request = new HttpRequestMessage(HttpMethod.Get, $"/v3/teachers/{person.Trn}"); + + // Act + var response = await GetHttpClientWithApiKey().SendAsync(request); + + // Assert + await AssertEx.JsonResponseIsErrorAsync(response, ApiError.ErrorCodes.PersonInactive, StatusCodes.Status404NotFound); + } } diff --git a/TeachingRecordSystem/tests/TeachingRecordSystem.Api.IntegrationTests/V3/V20240416/GetTeacherByTrnTests.cs b/TeachingRecordSystem/tests/TeachingRecordSystem.Api.IntegrationTests/V3/V20240416/GetTeacherByTrnTests.cs index 3fefb50807..6e74d204c5 100644 --- a/TeachingRecordSystem/tests/TeachingRecordSystem.Api.IntegrationTests/V3/V20240416/GetTeacherByTrnTests.cs +++ b/TeachingRecordSystem/tests/TeachingRecordSystem.Api.IntegrationTests/V3/V20240416/GetTeacherByTrnTests.cs @@ -55,4 +55,19 @@ public async Task Get_DateOfBirthNotProvided_ReturnsOk() // Assert Assert.Equal(StatusCodes.Status200OK, (int)response.StatusCode); } + + [Fact] + public async Task ValidRequest_ForInactiveContact_ReturnsNotFound() + { + // Arrange + var person = await TestData.CreatePersonAsync(p => p.WithTrn().WithContactState(ContactState.Inactive)); + + var request = new HttpRequestMessage(HttpMethod.Get, $"/v3/teachers/{person.Trn}"); + + // Act + var response = await GetHttpClientWithApiKey().SendAsync(request); + + // Assert + await AssertEx.JsonResponseIsErrorAsync(response, ApiError.ErrorCodes.PersonInactive, StatusCodes.Status404NotFound); + } } diff --git a/TeachingRecordSystem/tests/TeachingRecordSystem.Api.IntegrationTests/V3/V20240606/GetPersonByTrnTests.cs b/TeachingRecordSystem/tests/TeachingRecordSystem.Api.IntegrationTests/V3/V20240606/GetPersonByTrnTests.cs index cc82357076..c69ffee583 100644 --- a/TeachingRecordSystem/tests/TeachingRecordSystem.Api.IntegrationTests/V3/V20240606/GetPersonByTrnTests.cs +++ b/TeachingRecordSystem/tests/TeachingRecordSystem.Api.IntegrationTests/V3/V20240606/GetPersonByTrnTests.cs @@ -359,4 +359,19 @@ public async Task Get_DateOfBirthNotProvided_ReturnsOk() // Assert Assert.Equal(StatusCodes.Status200OK, (int)response.StatusCode); } + + [Fact] + public async Task ValidRequest_ForInactiveContact_ReturnsNotFound() + { + // Arrange + var person = await TestData.CreatePersonAsync(p => p.WithTrn().WithContactState(ContactState.Inactive)); + + var request = new HttpRequestMessage(HttpMethod.Get, $"/v3/persons/{person.Trn}"); + + // Act + var response = await GetHttpClientWithApiKey().SendAsync(request); + + // Assert + await AssertEx.JsonResponseIsErrorAsync(response, ApiError.ErrorCodes.PersonInactive, StatusCodes.Status404NotFound); + } } diff --git a/TeachingRecordSystem/tests/TeachingRecordSystem.Api.IntegrationTests/V3/V20240920/GetPersonByTrnTests.cs b/TeachingRecordSystem/tests/TeachingRecordSystem.Api.IntegrationTests/V3/V20240920/GetPersonByTrnTests.cs index 6b4a3d8323..1da1c331e5 100644 --- a/TeachingRecordSystem/tests/TeachingRecordSystem.Api.IntegrationTests/V3/V20240920/GetPersonByTrnTests.cs +++ b/TeachingRecordSystem/tests/TeachingRecordSystem.Api.IntegrationTests/V3/V20240920/GetPersonByTrnTests.cs @@ -258,6 +258,21 @@ public async Task Get_WithItt_ReturnsExpectedItt() responseItt); } + [Fact] + public async Task ValidRequest_ForInactiveContact_ReturnsNotFound() + { + // Arrange + var person = await TestData.CreatePersonAsync(p => p.WithTrn().WithContactState(ContactState.Inactive)); + + var request = new HttpRequestMessage(HttpMethod.Get, $"/v3/persons/{person.Trn}"); + + // Act + var response = await GetHttpClientWithApiKey().SendAsync(request); + + // Assert + await AssertEx.JsonResponseIsErrorAsync(response, ApiError.ErrorCodes.PersonInactive, StatusCodes.Status404NotFound); + } + private static dfeta_initialteachertraining CreateIttEntity(Guid contactId, string ittProviderUkprn, string ittProviderName) { var ittStartDate = new DateOnly(2021, 9, 7); diff --git a/TeachingRecordSystem/tests/TeachingRecordSystem.Api.IntegrationTests/V3/V20250203/GetPersonByTrnTests.cs b/TeachingRecordSystem/tests/TeachingRecordSystem.Api.IntegrationTests/V3/V20250203/GetPersonByTrnTests.cs index c52362add6..7703cf0a80 100644 --- a/TeachingRecordSystem/tests/TeachingRecordSystem.Api.IntegrationTests/V3/V20250203/GetPersonByTrnTests.cs +++ b/TeachingRecordSystem/tests/TeachingRecordSystem.Api.IntegrationTests/V3/V20250203/GetPersonByTrnTests.cs @@ -235,4 +235,19 @@ public async Task Get_WithNullDqtInductionStatus_ReturnsNoneInductionStatus() }, responseInduction); } + + [Fact] + public async Task ValidRequest_ForInactiveContact_ReturnsNotFound() + { + // Arrange + var person = await TestData.CreatePersonAsync(p => p.WithTrn().WithContactState(ContactState.Inactive)); + + var request = new HttpRequestMessage(HttpMethod.Get, $"/v3/persons/{person.Trn}"); + + // Act + var response = await GetHttpClientWithApiKey().SendAsync(request); + + // Assert + await AssertEx.JsonResponseIsErrorAsync(response, ApiError.ErrorCodes.PersonInactive, StatusCodes.Status404NotFound); + } } diff --git a/TeachingRecordSystem/tests/TeachingRecordSystem.Api.IntegrationTests/V3/V20250327/GetPersonByTrnTests.cs b/TeachingRecordSystem/tests/TeachingRecordSystem.Api.IntegrationTests/V3/V20250327/GetPersonByTrnTests.cs index 39260268d6..dcc0962602 100644 --- a/TeachingRecordSystem/tests/TeachingRecordSystem.Api.IntegrationTests/V3/V20250327/GetPersonByTrnTests.cs +++ b/TeachingRecordSystem/tests/TeachingRecordSystem.Api.IntegrationTests/V3/V20250327/GetPersonByTrnTests.cs @@ -12,8 +12,6 @@ public GetPersonByTrnTests(HostFixture hostFixture) public async Task Get_PersonWithQtlsAndQtsViaAnotherRoute_ReturnsExpectedAwardedOrApprovedCount() { // Arrange - - var person = await TestData.CreatePersonAsync(p => p .WithTrn() .WithQts() @@ -31,4 +29,19 @@ public async Task Get_PersonWithQtlsAndQtsViaAnotherRoute_ReturnsExpectedAwarded var awardedOrApprovedCount = responseJson.RootElement.GetProperty("qts").GetProperty("awardedOrApprovedCount").GetInt32(); Assert.Equal(2, awardedOrApprovedCount); } + + [Fact] + public async Task ValidRequest_ForInactiveContact_ReturnsNotFound() + { + // Arrange + var person = await TestData.CreatePersonAsync(p => p.WithTrn().WithContactState(ContactState.Inactive)); + + var request = new HttpRequestMessage(HttpMethod.Get, $"/v3/persons/{person.Trn}"); + + // Act + var response = await GetHttpClientWithApiKey().SendAsync(request); + + // Assert + await AssertEx.JsonResponseIsErrorAsync(response, ApiError.ErrorCodes.PersonInactive, StatusCodes.Status404NotFound); + } } diff --git a/TeachingRecordSystem/tests/TeachingRecordSystem.Core.Dqt.CrmIntegrationTests/QueryTests/GetActiveContactDetailByTrnTests.cs b/TeachingRecordSystem/tests/TeachingRecordSystem.Core.Dqt.CrmIntegrationTests/QueryTests/GetActiveContactDetailByTrnTests.cs index a52045c996..5ed10ed814 100644 --- a/TeachingRecordSystem/tests/TeachingRecordSystem.Core.Dqt.CrmIntegrationTests/QueryTests/GetActiveContactDetailByTrnTests.cs +++ b/TeachingRecordSystem/tests/TeachingRecordSystem.Core.Dqt.CrmIntegrationTests/QueryTests/GetActiveContactDetailByTrnTests.cs @@ -24,7 +24,7 @@ public async Task WhenCalled_WithTrnForNonExistentContact_ReturnsNull() var trn = "DodgyTrn"; // Act - var result = await _crmQueryDispatcher.ExecuteQueryAsync(new GetActiveContactDetailByTrnQuery(trn, new ColumnSet())); + var result = await _crmQueryDispatcher.ExecuteQueryAsync(new GetContactDetailByTrnQuery(trn, new ColumnSet())); // Assert Assert.Null(result); @@ -37,7 +37,7 @@ public async Task WhenCalled_WithTrnForExistingContact_ReturnsContactDetail() var person = await _dataScope.TestData.CreatePersonAsync(p => p.WithTrn()); // Act - var result = await _crmQueryDispatcher.ExecuteQueryAsync(new GetActiveContactDetailByTrnQuery(person.Trn!, new ColumnSet())); + var result = await _crmQueryDispatcher.ExecuteQueryAsync(new GetContactDetailByTrnQuery(person.Trn!, new ColumnSet())); // Assert Assert.NotNull(result); @@ -56,7 +56,7 @@ public async Task WhenCalled_WithTrnForExistingContactWithPreviousName_ReturnsCo await _dataScope.TestData.UpdatePersonAsync(b => b.WithPersonId(person.ContactId).WithUpdatedName(updatedFirstName, updatedMiddleName, updatedLastName)); // Act - var result = await _crmQueryDispatcher.ExecuteQueryAsync(new GetActiveContactDetailByTrnQuery(person.Trn!, new ColumnSet())); + var result = await _crmQueryDispatcher.ExecuteQueryAsync(new GetContactDetailByTrnQuery(person.Trn!, new ColumnSet())); // Assert Assert.NotNull(result); diff --git a/TeachingRecordSystem/tests/TeachingRecordSystem.TestCommon/TestData.CreatePerson.cs b/TeachingRecordSystem/tests/TeachingRecordSystem.TestCommon/TestData.CreatePerson.cs index 5c3d7b64e0..086f54c2df 100644 --- a/TeachingRecordSystem/tests/TeachingRecordSystem.TestCommon/TestData.CreatePerson.cs +++ b/TeachingRecordSystem/tests/TeachingRecordSystem.TestCommon/TestData.CreatePerson.cs @@ -50,6 +50,7 @@ public class CreatePersonBuilder private string? _slugId; private int? _loginFailedCounter; private CreatePersonInductionBuilder? _inductionBuilder; + private ContactState? _contactState; public Guid PersonId { get; } = Guid.NewGuid(); @@ -299,6 +300,12 @@ public CreatePersonBuilder WithInductionStatus(Action ExecuteAsync(TestData testData) { var trn = _hasTrn == true ? await testData.GenerateTrnAsync() : null; @@ -511,6 +518,16 @@ internal async Task ExecuteAsync(TestData testData) } } + if (_contactState is ContactState.Inactive) + { + txnRequestBuilder.AddRequest(new SetStateRequest() + { + EntityMoniker = PersonId.ToEntityReference(Contact.EntityLogicalName), + State = new OptionSetValue((int)TaskState.Completed), + Status = new OptionSetValue((int)Task_StatusCode.Completed) + }); + } + var retrieveContactHandle = txnRequestBuilder.AddRequest(new RetrieveRequest() { ColumnSet = new(allColumns: true),