From fcce9f4cb252132f3d146cd72f74a16fe1655d19 Mon Sep 17 00:00:00 2001 From: Sukhvinder Bhullar Date: Tue, 20 Jan 2026 16:17:31 +0000 Subject: [PATCH 1/6] Added significant change to api --- .../Dfe.CaseAggregationService.Api.csproj | 2 +- .../appsettings.Development.json | 3 +- .../appsettings.Production.json | 3 +- .../appsettings.Test.json | 3 +- .../appsettings.json | 6 ++ .../ApplicationServiceCollectionExtensions.cs | 3 + .../GetCaseInfoFromSigChangeSummary.cs | 30 ++++++ .../Services/Builders/GetSystemLinks.cs | 10 +- .../SystemIntegration/SigChangeIntegration.cs | 27 ++++++ .../Entities/SigChange/SigChangeSummary.cs | 15 +++ .../Repositories/ISigChangeRepository.cs | 15 +++ .../ValueObjects/NameDetails.cs | 4 - ...seAggregationService.Infrastructure.csproj | 4 +- .../Gateways/AcademisationApiClient.cs | 2 +- .../Gateways/SignificantChangeApiClient.cs | 54 +++++++++++ ...frastructureServiceCollectionExtensions.cs | 2 + .../Gateways/AcademisationApiClientTests.cs | 7 +- .../SignificantChangeApiClientTests.cs | 95 +++++++++++++++++++ 18 files changed, 267 insertions(+), 18 deletions(-) create mode 100644 src/Dfe.CaseAggregationService.Application/Services/Builders/GetCaseInfoFromSigChangeSummary.cs create mode 100644 src/Dfe.CaseAggregationService.Application/Services/SystemIntegration/SigChangeIntegration.cs create mode 100644 src/Dfe.CaseAggregationService.Domain/Entities/SigChange/SigChangeSummary.cs create mode 100644 src/Dfe.CaseAggregationService.Domain/Interfaces/Repositories/ISigChangeRepository.cs delete mode 100644 src/Dfe.CaseAggregationService.Domain/ValueObjects/NameDetails.cs create mode 100644 src/Dfe.CaseAggregationService.Infrastructure/Gateways/SignificantChangeApiClient.cs create mode 100644 src/Tests/Dfe.CaseAggregationService.Infrastructure.Tests/Gateways/SignificantChangeApiClientTests.cs diff --git a/src/Dfe.CaseAggregationService.Api/Dfe.CaseAggregationService.Api.csproj b/src/Dfe.CaseAggregationService.Api/Dfe.CaseAggregationService.Api.csproj index fe7c113..978ded8 100644 --- a/src/Dfe.CaseAggregationService.Api/Dfe.CaseAggregationService.Api.csproj +++ b/src/Dfe.CaseAggregationService.Api/Dfe.CaseAggregationService.Api.csproj @@ -33,7 +33,7 @@ - + diff --git a/src/Dfe.CaseAggregationService.Api/appsettings.Development.json b/src/Dfe.CaseAggregationService.Api/appsettings.Development.json index cb1ae50..5683d1a 100644 --- a/src/Dfe.CaseAggregationService.Api/appsettings.Development.json +++ b/src/Dfe.CaseAggregationService.Api/appsettings.Development.json @@ -41,7 +41,8 @@ "PrepareFormAMatLink": "https://dev.prepare-conversions.education.gov.uk/schools-in-this-mat/{0}", "CompleteLink": "https://dev.complete.education.gov.uk/projects/{0}/tasks", "MfspLink": "https://dev.manage-free-school-projects.education.gov.uk/projects/{0}/overview", - "RecastLink": "https://dev.record-concerns-support-trusts.education.gov.uk/case/{0}/management" + "RecastLink": "https://dev.record-concerns-support-trusts.education.gov.uk/case/{0}/management", + "SignificantChangeLink": "https://rsconnect/rsc/sig-change-portal/?sigchangeid={0}" }, "AllowedHosts": "*", "AzureAd": { diff --git a/src/Dfe.CaseAggregationService.Api/appsettings.Production.json b/src/Dfe.CaseAggregationService.Api/appsettings.Production.json index 0c2653f..09d1a3e 100644 --- a/src/Dfe.CaseAggregationService.Api/appsettings.Production.json +++ b/src/Dfe.CaseAggregationService.Api/appsettings.Production.json @@ -42,7 +42,8 @@ "PrepareFormAMatLink": "https://www.prepare-conversions.education.gov.uk/schools-in-this-mat/{0}", "CompleteLink": "https://www.complete.education.gov.uk/projects/{0}/tasks", "MfspLink": "https://www.manage-free-school-projects.education.gov.uk/projects/{0}/overview", - "RecastLink": "https://www.record-concerns-support-trusts.education.gov.uk/case/{0}/management" + "RecastLink": "https://www.record-concerns-support-trusts.education.gov.uk/case/{0}/management", + "SignificantChangeLink": "https://rsconnect/rsc/sig-change-portal/?sigchangeid={0}" }, "AzureAd": { "Instance": "https://login.microsoftonline.com/", diff --git a/src/Dfe.CaseAggregationService.Api/appsettings.Test.json b/src/Dfe.CaseAggregationService.Api/appsettings.Test.json index 453d4f2..c8d4c55 100644 --- a/src/Dfe.CaseAggregationService.Api/appsettings.Test.json +++ b/src/Dfe.CaseAggregationService.Api/appsettings.Test.json @@ -41,7 +41,8 @@ "PrepareFormAMatLink": "https://test.prepare-conversions.education.gov.uk/schools-in-this-mat/{0}", "CompleteLink": "https://test.complete.education.gov.uk/projects/{0}/tasks", "MfspLink": "https://test.manage-free-school-projects.education.gov.uk/projects/{0}/overview", - "RecastLink": "https://test.record-concerns-support-trusts.education.gov.uk/case/{0}/management" + "RecastLink": "https://test.record-concerns-support-trusts.education.gov.uk/case/{0}/management", + "SignificantChangeLink": "https://rsconnect/rsc/sig-change-portal/?sigchangeid={0}" }, "AllowedHosts": "*", "AzureAd": { diff --git a/src/Dfe.CaseAggregationService.Api/appsettings.json b/src/Dfe.CaseAggregationService.Api/appsettings.json index 558845d..07f4b1c 100644 --- a/src/Dfe.CaseAggregationService.Api/appsettings.json +++ b/src/Dfe.CaseAggregationService.Api/appsettings.json @@ -209,6 +209,12 @@ "Title": "Directive Academy Order (DAO) guidance (Word document)", "Link": "https://educationgovuk.sharepoint.com/sites/lvewp00030/SitePages/Directive-Academy-Order-(dAO).aspx" } + ], + "SignificantChange": [ + { + "Title": "Significant change guidance", + "Link": "https://educationgovuk.sharepoint.com/sites/lvewp00030/SitePages/Significant-Change.aspx" + } ] }, "ResourcesLookup": { diff --git a/src/Dfe.CaseAggregationService.Application/ApplicationServiceCollectionExtensions.cs b/src/Dfe.CaseAggregationService.Application/ApplicationServiceCollectionExtensions.cs index 85e77e3..da14bf1 100644 --- a/src/Dfe.CaseAggregationService.Application/ApplicationServiceCollectionExtensions.cs +++ b/src/Dfe.CaseAggregationService.Application/ApplicationServiceCollectionExtensions.cs @@ -10,6 +10,7 @@ using Dfe.CaseAggregationService.Domain.Entities.Mfsp; using Dfe.CaseAggregationService.Domain.Entities.Recast; using Dfe.CaseAggregationService.Application.Services.SystemIntegration; +using Dfe.CaseAggregationService.Domain.Entities.SigChange; namespace Microsoft.Extensions.DependencyInjection { @@ -38,10 +39,12 @@ public static IServiceCollection AddApplicationDependencyGroup( services.AddScoped, GetCaseInfoFromRecastSummary>(); services.AddScoped, GetCaseInfoFromMfspSummary>(); services.AddScoped, GetCaseInfoFromCompleteSummary>(); + services.AddScoped, GetCaseInfoFromSigChangeSummary>(); services.AddScoped(); services.AddScoped(); services.AddScoped(); services.AddScoped(); + services.AddScoped(); services.AddScoped(); services.AddScoped(); diff --git a/src/Dfe.CaseAggregationService.Application/Services/Builders/GetCaseInfoFromSigChangeSummary.cs b/src/Dfe.CaseAggregationService.Application/Services/Builders/GetCaseInfoFromSigChangeSummary.cs new file mode 100644 index 0000000..a696c8d --- /dev/null +++ b/src/Dfe.CaseAggregationService.Application/Services/Builders/GetCaseInfoFromSigChangeSummary.cs @@ -0,0 +1,30 @@ +using Dfe.CaseAggregationService.Application.Common.Models; +using Dfe.CaseAggregationService.Application.Services.Builders.Dfe.CaseAggregationService.Application.Services.Builders; +using Dfe.CaseAggregationService.Domain.Entities.SigChange; + +namespace Dfe.CaseAggregationService.Application.Services.Builders +{ + public class GetCaseInfoFromSigChangeSummary(IGetGuidanceLinks getGuidanceLinks, IGetSystemLinks getSystemLinks) : IGetCaseInfo + { + private const string System = "Significant Change Tracker"; + + public UserCaseInfo GetCaseInfo(SigChangeSummary summary) + { + return new UserCaseInfo(summary.AcademyName ?? "", + getSystemLinks.GetSigChangeTitleLink(summary.SigChangeId), + System, + summary.ChangeType ?? "Unknown Type", + summary.CreatedDate, + summary.UpdatedDate, + [ + new CaseInfoItem("Trust", summary.Trust, null), + new CaseInfoItem("URN", summary.Urn, null), + new CaseInfoItem("Local Authority", summary.LocalAuthority, null), + new CaseInfoItem("Region", summary.Region, null), + new CaseInfoItem("Date Of Decision", summary.DateOfDecision?.ToString("dd/MM/yyyy"), null) + ], + getGuidanceLinks.GenerateLinkItems("SignificantChange"), + []); + } + } +} diff --git a/src/Dfe.CaseAggregationService.Application/Services/Builders/GetSystemLinks.cs b/src/Dfe.CaseAggregationService.Application/Services/Builders/GetSystemLinks.cs index 0dc14c3..d709dfe 100644 --- a/src/Dfe.CaseAggregationService.Application/Services/Builders/GetSystemLinks.cs +++ b/src/Dfe.CaseAggregationService.Application/Services/Builders/GetSystemLinks.cs @@ -15,6 +15,8 @@ public interface IGetSystemLinks string GetCompleteTitleLink(params object[] formatKeys); string GetPrepareFormAMatTitleLink(params object[] formatKeys); + + string GetSigChangeTitleLink(params object[] formatKeys); } public class GetSystemLinks(IConfiguration configuration): IGetSystemLinks @@ -23,7 +25,6 @@ public string GetPrepareConversionTitleLink(params object[] formatKeys) { return BuildLink("PrepareConversionLink", formatKeys); } - public string GetPrepareTransferTitleLink(params object[] formatKeys) { return BuildLink("PrepareTransferLink", formatKeys); @@ -49,7 +50,12 @@ public string GetCompleteTitleLink(params object[] formatKeys) return BuildLink("CompleteLink", formatKeys); } - private string BuildLink(string linkKey, object[] formatKeys) + public string GetSigChangeTitleLink(params object[] formatKeys) + { + return BuildLink("SignificantChangeLink", formatKeys); + } + + private string BuildLink(string linkKey, object[] formatKeys) { var linkBase = configuration.GetSection($"SystemLinks:{linkKey}").Get(); if (string.IsNullOrEmpty(linkBase)) diff --git a/src/Dfe.CaseAggregationService.Application/Services/SystemIntegration/SigChangeIntegration.cs b/src/Dfe.CaseAggregationService.Application/Services/SystemIntegration/SigChangeIntegration.cs new file mode 100644 index 0000000..97be799 --- /dev/null +++ b/src/Dfe.CaseAggregationService.Application/Services/SystemIntegration/SigChangeIntegration.cs @@ -0,0 +1,27 @@ +using Microsoft.Extensions.Logging; +using Dfe.CaseAggregationService.Application.Cases.Queries.GetCasesForUser; +using Dfe.CaseAggregationService.Application.Common.Models; +using Dfe.CaseAggregationService.Application.Services.Builders; +using Dfe.CaseAggregationService.Domain.Entities.SigChange; +using Dfe.CaseAggregationService.Domain.Interfaces.Repositories; + +namespace Dfe.CaseAggregationService.Application.Services.SystemIntegration +{ + public class SigChangeIntegration( + ISigChangeRepository repo, + IGetCaseInfo mapper, + ILogger logger) + : IntegrationWrapper(mapper, logger), ISystemIntegration + { + public Task> GetCasesForQuery(GetCasesForUserQuery query, CancellationToken cancellationToken) + { + if (query.IncludeSignificantChange) + { + return repo.GetSigChangeSummaries(query.UserName, cancellationToken) + .ContinueWith(ProcessResult, cancellationToken); + } + + return Task.FromResult>(new List()); + } + } +} diff --git a/src/Dfe.CaseAggregationService.Domain/Entities/SigChange/SigChangeSummary.cs b/src/Dfe.CaseAggregationService.Domain/Entities/SigChange/SigChangeSummary.cs new file mode 100644 index 0000000..0b33b0d --- /dev/null +++ b/src/Dfe.CaseAggregationService.Domain/Entities/SigChange/SigChangeSummary.cs @@ -0,0 +1,15 @@ +namespace Dfe.CaseAggregationService.Domain.Entities.SigChange; + +public class SigChangeSummary +{ + public string SigChangeId { get; set; } + public string? AcademyName { get; set; } + public string? ChangeType { get; set; } + public string? Trust { get; set; } + public string? Urn { get; set; } + public string? LocalAuthority { get; set; } + public string? Region { get; set; } + public DateTime? DateOfDecision { get; set; } + public DateTime CreatedDate { get; set; } + public DateTime UpdatedDate { get; set; } +} \ No newline at end of file diff --git a/src/Dfe.CaseAggregationService.Domain/Interfaces/Repositories/ISigChangeRepository.cs b/src/Dfe.CaseAggregationService.Domain/Interfaces/Repositories/ISigChangeRepository.cs new file mode 100644 index 0000000..978a3b3 --- /dev/null +++ b/src/Dfe.CaseAggregationService.Domain/Interfaces/Repositories/ISigChangeRepository.cs @@ -0,0 +1,15 @@ +using Dfe.CaseAggregationService.Domain.Entities.SigChange; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading; +using System.Threading.Tasks; + +namespace Dfe.CaseAggregationService.Domain.Interfaces.Repositories +{ + public interface ISigChangeRepository + { + Task> GetSigChangeSummaries(string? userName, CancellationToken cancellationToken); + } +} diff --git a/src/Dfe.CaseAggregationService.Domain/ValueObjects/NameDetails.cs b/src/Dfe.CaseAggregationService.Domain/ValueObjects/NameDetails.cs deleted file mode 100644 index 1ed2fbc..0000000 --- a/src/Dfe.CaseAggregationService.Domain/ValueObjects/NameDetails.cs +++ /dev/null @@ -1,4 +0,0 @@ -namespace Dfe.CaseAggregationService.Domain.ValueObjects -{ - public record NameDetails(string? NameListAs, string? NameDisplayAs, string? NameFullTitle); -} diff --git a/src/Dfe.CaseAggregationService.Infrastructure/Dfe.CaseAggregationService.Infrastructure.csproj b/src/Dfe.CaseAggregationService.Infrastructure/Dfe.CaseAggregationService.Infrastructure.csproj index d73b585..a59bc4e 100644 --- a/src/Dfe.CaseAggregationService.Infrastructure/Dfe.CaseAggregationService.Infrastructure.csproj +++ b/src/Dfe.CaseAggregationService.Infrastructure/Dfe.CaseAggregationService.Infrastructure.csproj @@ -4,7 +4,7 @@ - + @@ -17,7 +17,7 @@ - + diff --git a/src/Dfe.CaseAggregationService.Infrastructure/Gateways/AcademisationApiClient.cs b/src/Dfe.CaseAggregationService.Infrastructure/Gateways/AcademisationApiClient.cs index 4d6e297..defd52a 100644 --- a/src/Dfe.CaseAggregationService.Infrastructure/Gateways/AcademisationApiClient.cs +++ b/src/Dfe.CaseAggregationService.Infrastructure/Gateways/AcademisationApiClient.cs @@ -9,7 +9,7 @@ public class AcademisationApiClient : ApiClient, IAcademisationRepository { public AcademisationApiClient( IHttpClientFactory clientFactory, - ILogger logger, + ILogger logger, string httpClientName = "AcademisationApiClient") : base(clientFactory, logger, httpClientName) { diff --git a/src/Dfe.CaseAggregationService.Infrastructure/Gateways/SignificantChangeApiClient.cs b/src/Dfe.CaseAggregationService.Infrastructure/Gateways/SignificantChangeApiClient.cs new file mode 100644 index 0000000..35e6773 --- /dev/null +++ b/src/Dfe.CaseAggregationService.Infrastructure/Gateways/SignificantChangeApiClient.cs @@ -0,0 +1,54 @@ +using Dfe.AcademiesApi.Client.Contracts; +using Dfe.CaseAggregationService.Domain.Entities.SigChange; +using Dfe.CaseAggregationService.Domain.Interfaces.Repositories; + +namespace Dfe.CaseAggregationService.Infrastructure.Gateways +{ + public class SignificantChangeApiClient(ISignificantChangesV4Client significantChangesClient): ISigChangeRepository + { + + public async Task> GetSigChangeSummaries(string? userName, CancellationToken cancellationToken) + { + + var response = await significantChangesClient.SearchSignificantChangesAsync(userName, null, null, null, null, cancellationToken); + + if (response.Data == null) + throw new Exception(); + + return response.Data.Where(x => x.AllActionsCompleted != true) + .Select(x => new SigChangeSummary() + { + SigChangeId = x.SigChangeId.ToString() ?? "", + AcademyName = x.AcademyName, + ChangeType = x.TypeOfSigChangeMapped, + Trust = x.TrustName, + Urn = x.Urn.ToString(), + LocalAuthority = x.LocalAuthority, + Region = x.Region, + DateOfDecision = ParseNullableDate(x.DecisionDate), + CreatedDate = ParseDate(x.ChangeCreationDate), + UpdatedDate = ParseDate(x.ChangeEditDate) + }); + } + + private DateTime? ParseNullableDate(string? dateString) + { + if (string.IsNullOrEmpty(dateString)) + return null; + + if (DateTime.TryParse(dateString, out var date)) + return date; + + return null; + } + + private DateTime ParseDate(string? dateString) + { + if (string.IsNullOrEmpty(dateString)) + return DateTime.MinValue; + + return DateTime.TryParse(dateString, out var date) ? date : DateTime.MinValue; + } + + } +} diff --git a/src/Dfe.CaseAggregationService.Infrastructure/InfrastructureServiceCollectionExtensions.cs b/src/Dfe.CaseAggregationService.Infrastructure/InfrastructureServiceCollectionExtensions.cs index 35cec95..688be8f 100644 --- a/src/Dfe.CaseAggregationService.Infrastructure/InfrastructureServiceCollectionExtensions.cs +++ b/src/Dfe.CaseAggregationService.Infrastructure/InfrastructureServiceCollectionExtensions.cs @@ -20,8 +20,10 @@ public static IServiceCollection AddInfrastructureDependencyGroup( services.AddScoped(); services.AddScoped(); services.AddScoped(); + services.AddScoped(); services.AddAcademiesApiClient(config); + services.AddAcademiesApiClient(config); services.AddCompleteApiClient(config); //Cache service diff --git a/src/Tests/Dfe.CaseAggregationService.Infrastructure.Tests/Gateways/AcademisationApiClientTests.cs b/src/Tests/Dfe.CaseAggregationService.Infrastructure.Tests/Gateways/AcademisationApiClientTests.cs index 3916034..48e0e4e 100644 --- a/src/Tests/Dfe.CaseAggregationService.Infrastructure.Tests/Gateways/AcademisationApiClientTests.cs +++ b/src/Tests/Dfe.CaseAggregationService.Infrastructure.Tests/Gateways/AcademisationApiClientTests.cs @@ -1,9 +1,6 @@ -using Dfe.CaseAggregationService.Domain.Entities.Academisation; -using Dfe.CaseAggregationService.Infrastructure.Gateways; -using Dfe.Complete.Client.Contracts; +using Dfe.CaseAggregationService.Infrastructure.Gateways; using Microsoft.Extensions.Logging; using NSubstitute; -using System.Security.Policy; namespace Dfe.CaseAggregationService.Infrastructure.Tests.Gateways { @@ -14,7 +11,7 @@ public class AcademisationApiClientTests public AcademisationApiClientTests() { var httpClient = Substitute.For(); - var logger = Substitute.For>(); + var logger = Substitute.For>(); _repo = new AcademisationApiClient(httpClient, logger); diff --git a/src/Tests/Dfe.CaseAggregationService.Infrastructure.Tests/Gateways/SignificantChangeApiClientTests.cs b/src/Tests/Dfe.CaseAggregationService.Infrastructure.Tests/Gateways/SignificantChangeApiClientTests.cs new file mode 100644 index 0000000..d69391e --- /dev/null +++ b/src/Tests/Dfe.CaseAggregationService.Infrastructure.Tests/Gateways/SignificantChangeApiClientTests.cs @@ -0,0 +1,95 @@ +using Dfe.AcademiesApi.Client.Contracts; +using Dfe.CaseAggregationService.Infrastructure.Gateways; +using Microsoft.Extensions.Logging; +using NSubstitute; + +namespace Dfe.CaseAggregationService.Infrastructure.Tests.Gateways +{ + public class SignificantChangeApiClientTests + { + private const string DeliveryOfficer = "Delivery Officer"; + + private readonly SignificantChangeApiClient _repo; + + public SignificantChangeApiClientTests() + { + var httpClient = Substitute.For(); + var logger = Substitute.For>(); + var sigChangeProjects = Substitute.For(); + + var results = new PagedDataResponseOfSignificantChangeDto() + { + Data = + [ + new() + { + SigChangeId = 1, + AcademyName = "Academy 1", + TypeOfSigChangeMapped = "Type 1", + TrustName = "Trust 1", + Urn = 123456, + LocalAuthority = "LA 1", + Region = "Region 1", + DecisionDate = "10/02/2026", + ChangeCreationDate = "10/02/2026", + ChangeEditDate = "10/02/2026" + }, + + new() + { + SigChangeId = 2, + AcademyName = "Academy 2", + TypeOfSigChangeMapped = "Type 2", + TrustName = "Trust 2", + Urn = 123457, + LocalAuthority = "LA 2", + Region = "Region 2", + DecisionDate = "10/02/2026", + ChangeCreationDate = "10/02/2026", + ChangeEditDate = "10/02/2026" + } + ] + }; + + sigChangeProjects.SearchSignificantChangesAsync(Arg.Is(DeliveryOfficer), + null, null, null, null, + Arg.Any()) + .Returns(Task.FromResult(results)); + + _repo = new SignificantChangeApiClient(sigChangeProjects); + } + + [Fact] + public async Task GivenCorrectCallReturnSummary() + { + var result = await _repo.GetSigChangeSummaries(DeliveryOfficer, CancellationToken.None); + + Assert.Equal(2, result.Count()); + + var first = result.First(); + + Assert.Equal("Academy 1", first.AcademyName); + Assert.Equal("Type 1", first.ChangeType); + Assert.Equal("Trust 1", first.Trust); + Assert.Equal("123456", first.Urn); + Assert.Equal("LA 1", first.LocalAuthority); + Assert.Equal("Region 1", first.Region); + Assert.Equal(new DateTime(2026, 2, 10), first.DateOfDecision); + Assert.Equal(new DateTime(2026, 2, 10), first.CreatedDate); + Assert.Equal(new DateTime(2026, 2, 10), first.UpdatedDate); + + var second = result.Skip(1).First(); + + Assert.Equal("Academy 2", second.AcademyName); + Assert.Equal("Type 2", second.ChangeType); + Assert.Equal("Trust 2", second.Trust); + Assert.Equal("123457", second.Urn); + Assert.Equal("LA 2", second.LocalAuthority); + Assert.Equal("Region 2", second.Region); + Assert.Equal(new DateTime(2026, 2, 10), second.DateOfDecision); + Assert.Equal(new DateTime(2026, 2, 10), second.CreatedDate); + Assert.Equal(new DateTime(2026, 2, 10), second.UpdatedDate); + } + + } +} From da761f75ca46bb952bdb90c17ab6d2db50400354 Mon Sep 17 00:00:00 2001 From: Sukhvinder Bhullar Date: Tue, 20 Jan 2026 16:39:58 +0000 Subject: [PATCH 2/6] Fixed CI test fail based on which culture the tests are run in --- .../Gateways/SignificantChangeApiClient.cs | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/Dfe.CaseAggregationService.Infrastructure/Gateways/SignificantChangeApiClient.cs b/src/Dfe.CaseAggregationService.Infrastructure/Gateways/SignificantChangeApiClient.cs index 35e6773..6381110 100644 --- a/src/Dfe.CaseAggregationService.Infrastructure/Gateways/SignificantChangeApiClient.cs +++ b/src/Dfe.CaseAggregationService.Infrastructure/Gateways/SignificantChangeApiClient.cs @@ -1,4 +1,5 @@ -using Dfe.AcademiesApi.Client.Contracts; +using System.Globalization; +using Dfe.AcademiesApi.Client.Contracts; using Dfe.CaseAggregationService.Domain.Entities.SigChange; using Dfe.CaseAggregationService.Domain.Interfaces.Repositories; @@ -47,7 +48,11 @@ private DateTime ParseDate(string? dateString) if (string.IsNullOrEmpty(dateString)) return DateTime.MinValue; - return DateTime.TryParse(dateString, out var date) ? date : DateTime.MinValue; + string format = "dd/MM/yyyy"; + CultureInfo provider = CultureInfo.InvariantCulture; + + return DateTime.TryParseExact(dateString, format, provider, + DateTimeStyles.None, out var date) ? date : DateTime.MinValue; } } From 8850f46682962232d72179c17ba422d2cc5bd5c7 Mon Sep 17 00:00:00 2001 From: Sukhvinder Bhullar Date: Wed, 21 Jan 2026 09:53:58 +0000 Subject: [PATCH 3/6] Fixed date parse for CI --- .../Gateways/SignificantChangeApiClient.cs | 20 ++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/src/Dfe.CaseAggregationService.Infrastructure/Gateways/SignificantChangeApiClient.cs b/src/Dfe.CaseAggregationService.Infrastructure/Gateways/SignificantChangeApiClient.cs index 6381110..86ed305 100644 --- a/src/Dfe.CaseAggregationService.Infrastructure/Gateways/SignificantChangeApiClient.cs +++ b/src/Dfe.CaseAggregationService.Infrastructure/Gateways/SignificantChangeApiClient.cs @@ -5,9 +5,12 @@ namespace Dfe.CaseAggregationService.Infrastructure.Gateways { - public class SignificantChangeApiClient(ISignificantChangesV4Client significantChangesClient): ISigChangeRepository + public class SignificantChangeApiClient(ISignificantChangesV4Client significantChangesClient) : ISigChangeRepository { + + const string format = "dd/MM/yyyy"; + public async Task> GetSigChangeSummaries(string? userName, CancellationToken cancellationToken) { @@ -37,7 +40,8 @@ public async Task> GetSigChangeSummaries(string? u if (string.IsNullOrEmpty(dateString)) return null; - if (DateTime.TryParse(dateString, out var date)) + if (DateTime.TryParseExact(dateString, format, CultureInfo.InvariantCulture, + DateTimeStyles.None, out var date)) return date; return null; @@ -45,15 +49,13 @@ public async Task> GetSigChangeSummaries(string? u private DateTime ParseDate(string? dateString) { - if (string.IsNullOrEmpty(dateString)) - return DateTime.MinValue; + if (string.IsNullOrEmpty(dateString)) + return DateTime.MinValue; - string format = "dd/MM/yyyy"; - CultureInfo provider = CultureInfo.InvariantCulture; - return DateTime.TryParseExact(dateString, format, provider, - DateTimeStyles.None, out var date) ? date : DateTime.MinValue; + return DateTime.TryParseExact(dateString, format, CultureInfo.InvariantCulture, + DateTimeStyles.None, out var date) ? date : DateTime.MinValue; } - } + } } From 535845ae2bc11980c93b94db3ca6b0c9411b47de Mon Sep 17 00:00:00 2001 From: Sukhvinder Bhullar Date: Wed, 18 Mar 2026 17:11:44 +0000 Subject: [PATCH 4/6] Added tests to sig change --- .../Gateways/SignificantChangeApiClient.cs | 2 - .../Controllers/CasesControllerTests.cs | 60 +++++++++++++++++++ .../GetCaseInfoFromSigChangeSummaryTests.cs | 58 ++++++++++++++++++ ...pplicationDbContextFactoryCustomization.cs | 29 +++++---- 4 files changed, 135 insertions(+), 14 deletions(-) create mode 100644 src/Tests/Dfe.CaseAggregationService.Application.Tests/Services/GetCaseInfoFromSigChangeSummaryTests.cs diff --git a/src/Dfe.CaseAggregationService.Infrastructure/Gateways/SignificantChangeApiClient.cs b/src/Dfe.CaseAggregationService.Infrastructure/Gateways/SignificantChangeApiClient.cs index 86ed305..a342776 100644 --- a/src/Dfe.CaseAggregationService.Infrastructure/Gateways/SignificantChangeApiClient.cs +++ b/src/Dfe.CaseAggregationService.Infrastructure/Gateways/SignificantChangeApiClient.cs @@ -7,8 +7,6 @@ namespace Dfe.CaseAggregationService.Infrastructure.Gateways { public class SignificantChangeApiClient(ISignificantChangesV4Client significantChangesClient) : ISigChangeRepository { - - const string format = "dd/MM/yyyy"; public async Task> GetSigChangeSummaries(string? userName, CancellationToken cancellationToken) diff --git a/src/Tests/Dfe.CaseAggregationService.Api.Tests.Integration/Controllers/CasesControllerTests.cs b/src/Tests/Dfe.CaseAggregationService.Api.Tests.Integration/Controllers/CasesControllerTests.cs index e4e9692..ce1081d 100644 --- a/src/Tests/Dfe.CaseAggregationService.Api.Tests.Integration/Controllers/CasesControllerTests.cs +++ b/src/Tests/Dfe.CaseAggregationService.Api.Tests.Integration/Controllers/CasesControllerTests.cs @@ -137,6 +137,41 @@ public async Task GetCasesAsync_ShouldAcademisationCases_WhenCaseExists( Assert.Equal(transfersSummarySchoolName, result.CaseInfos.First().Title); } + [Theory] + [CustomAutoData(typeof(CustomWebApplicationDbContextFactoryCustomization))] + public async Task GetCasesAsync_ShouldSigChangeCases_WhenCaseExists( + CustomWebApplicationDbContextFactory factory, + ICasesClient caseClient, + IFixture fixture) + { + factory.TestClaims = [new Claim(ClaimTypes.Role, "API.Read")]; + + const string? academyName = "Academy School Name"; + + SetupSigChange(factory, fixture, "userName", academyName); + + // Act + var result = await caseClient.GetCasesByUserAsync("userName", + "userEmail", + true, + false, + false, + false, + false, + false, + [], + "", + null, + 1, + 25, + "1"); + + //// Assert + Assert.NotNull(result); + Assert.Equal(1, result.TotalRecordCount); + Assert.Equal(academyName, result.CaseInfos.First().Title); + } + private static void SetupRecast(CustomWebApplicationDbContextFactory factory, IFixture fixture, params (string trustName, string caseType)[] recastCase) { @@ -260,5 +295,30 @@ private static void SetupPrepare(CustomWebApplicationDbContextFactory f factory.WireMockServer.AddGetWithJsonResponse($"/conversion-project/formamatproject/123", new[] { conversionAcademySummary, transferAcademySummary }); } + + private static void SetupSigChange(CustomWebApplicationDbContextFactory factory, IFixture fixture, + string deliveryOfficer, + string academyName) + { + var sigChangeSummary = new PagedDataResponseOfSignificantChangeDto + {Data = [new (){ + SigChangeId = 12345, + AcademyName = academyName, + TypeOfSigChangeMapped = "changeType", + TrustName = "trust", + Urn = 123456, + LocalAuthority = "LA1", + Region = "Region1", + DecisionDate = "18/03/2025", + ChangeCreationDate = "02/01/2025", + ChangeEditDate = "06/04/2025" + }] + }; + + Assert.NotNull(factory.WireMockServer); + factory.WireMockServer.AddGetWithJsonResponse($"/academies/v4/significantchanges", sigChangeSummary, new List> { new("deliveryOfficer", deliveryOfficer) }); + + + } } } diff --git a/src/Tests/Dfe.CaseAggregationService.Application.Tests/Services/GetCaseInfoFromSigChangeSummaryTests.cs b/src/Tests/Dfe.CaseAggregationService.Application.Tests/Services/GetCaseInfoFromSigChangeSummaryTests.cs new file mode 100644 index 0000000..bb6eee1 --- /dev/null +++ b/src/Tests/Dfe.CaseAggregationService.Application.Tests/Services/GetCaseInfoFromSigChangeSummaryTests.cs @@ -0,0 +1,58 @@ +using Dfe.CaseAggregationService.Application.Services.Builders; +using Dfe.CaseAggregationService.Application.Services.Builders.Dfe.CaseAggregationService.Application.Services.Builders; +using NSubstitute; +using Dfe.CaseAggregationService.Application.Common.Models; +using Dfe.CaseAggregationService.Domain.Entities.SigChange; + +namespace Dfe.CaseAggregationService.Application.Tests.Services +{ + public class GetCaseInfoFromSigChangeSummaryTests + { + [Fact] + public void GivenPresumptionReturnCaseInfo() + { + var sigChangeSummary = new SigChangeSummary() + { + SigChangeId = "1", + AcademyName = "Academy 1", + ChangeType = "Type 1", + Trust = "Trust 1", + Urn = "123456", + LocalAuthority = "LA 1", + Region = "Region 1", + DateOfDecision = new DateTime(2025, 5, 1), + CreatedDate = new DateTime(2025, 5, 1), + UpdatedDate = new DateTime(2025, 5, 1) + }; + + var getGuidanceLinks = Substitute.For(); + getGuidanceLinks.GenerateLinkItems(Arg.Is("SignificantChange")).Returns(new List { new("Guidance Pres", "http://guide.pres.link") }); + + var getSystemLinks = Substitute.For(); + getSystemLinks.GetSigChangeTitleLink(Arg.Any()).Returns("http://TitleLink"); + + var underTest = new GetCaseInfoFromSigChangeSummary(getGuidanceLinks, getSystemLinks); + + var result = underTest.GetCaseInfo(sigChangeSummary); + + Assert.NotNull(result); + + Assert.Equal(new DateTime(2025, 5, 1), result.CreatedDate); + Assert.Equal(new DateTime(2025, 5, 1), result.UpdatedDate); + Assert.Equal("Type 1", result.ProjectType); + Assert.Equal(5, result.Info.Count()); + Assert.Equal(result.Guidance.FirstOrDefault().Title, "Guidance Pres"); + Assert.Equal(result.Guidance.FirstOrDefault().Link, "http://guide.pres.link"); + var info = result.Info.ToArray(); + + info[0].ShouldBe("Trust", "Trust 1"); + info[1].ShouldBe("URN", "123456"); + info[2].ShouldBe("Local Authority", "LA 1"); + info[3].ShouldBe("Region", "Region 1"); + info[4].ShouldBe("Date Of Decision", "01/05/2025"); + + + } + + } +} diff --git a/src/Tests/Dfe.CaseAggregationService.Tests.Common/Customizations/CustomWebApplicationDbContextFactoryCustomization.cs b/src/Tests/Dfe.CaseAggregationService.Tests.Common/Customizations/CustomWebApplicationDbContextFactoryCustomization.cs index 9309858..9f1ed84 100644 --- a/src/Tests/Dfe.CaseAggregationService.Tests.Common/Customizations/CustomWebApplicationDbContextFactoryCustomization.cs +++ b/src/Tests/Dfe.CaseAggregationService.Tests.Common/Customizations/CustomWebApplicationDbContextFactoryCustomization.cs @@ -15,9 +15,6 @@ using Dfe.AcademiesApi.Client.Contracts; using Dfe.AcademiesApi.Client.Security; using Dfe.AcademiesApi.Client.Settings; -using Dfe.Complete.Client; -using Dfe.Complete.Client.Contracts; -using NSubstitute; namespace Dfe.CaseAggregationService.Tests.Common.Customizations { @@ -94,6 +91,23 @@ public void Customize(IFixture fixture) return new ApiKeyHandler(apiSettings); }); + + services.AddHttpClient( + (httpClient, serviceProvider) => + { + var wConfig = serviceProvider.GetRequiredService(); + + httpClient.BaseAddress = new Uri(wConfig["AcademiesApiClient:BaseUrl"]!); + + return ActivatorUtilities.CreateInstance( + serviceProvider, httpClient, wConfig["AcademiesApiClient:BaseUrl"]!); + }) + .AddHttpMessageHandler(serviceProvider => + { + var apiSettings = serviceProvider.GetRequiredService(); + return new ApiKeyHandler(apiSettings); + }); + services.AddHttpClient("RecastApiClient", (serviceProvider, httpClient) => { var wConfig = serviceProvider.GetRequiredService(); @@ -101,15 +115,6 @@ public void Customize(IFixture fixture) httpClient.BaseAddress = new Uri(wConfig["RecastApiClient:BaseUrl"]!); }); - //services.AddHttpClient((httpClient, serviceProvider) => - //{ - // var wConfig = serviceProvider.GetRequiredService(); - - // httpClient.BaseAddress = new Uri(wConfig["CompleteApiClient:BaseUrl"]!); - - // return ActivatorUtilities.CreateInstance( - // serviceProvider, httpClient, wConfig["CompleteApiClient:BaseUrl"]!); - //}); } }; From 222be617c6750c362373000ba5fa90a65e1fac10 Mon Sep 17 00:00:00 2001 From: Sukhvinder Bhullar Date: Mon, 23 Mar 2026 11:49:19 +0000 Subject: [PATCH 5/6] Fixed dates and does not return cases if project filter is set --- .../SystemIntegration/SigChangeIntegration.cs | 10 ++++++ .../Gateways/SignificantChangeApiClient.cs | 5 +-- .../GetCasesForUserQueryHandlerTests.cs | 36 +++++++++++++++++++ 3 files changed, 49 insertions(+), 2 deletions(-) diff --git a/src/Dfe.CaseAggregationService.Application/Services/SystemIntegration/SigChangeIntegration.cs b/src/Dfe.CaseAggregationService.Application/Services/SystemIntegration/SigChangeIntegration.cs index 97be799..ed213d8 100644 --- a/src/Dfe.CaseAggregationService.Application/Services/SystemIntegration/SigChangeIntegration.cs +++ b/src/Dfe.CaseAggregationService.Application/Services/SystemIntegration/SigChangeIntegration.cs @@ -15,12 +15,22 @@ public class SigChangeIntegration( { public Task> GetCasesForQuery(GetCasesForUserQuery query, CancellationToken cancellationToken) { + if(query.FilterProjectTypes != null && query.FilterProjectTypes.Length > 0) + { + return EmptyResult(); + } + if (query.IncludeSignificantChange) { return repo.GetSigChangeSummaries(query.UserName, cancellationToken) .ContinueWith(ProcessResult, cancellationToken); } + return EmptyResult(); + } + + private static Task> EmptyResult() + { return Task.FromResult>(new List()); } } diff --git a/src/Dfe.CaseAggregationService.Infrastructure/Gateways/SignificantChangeApiClient.cs b/src/Dfe.CaseAggregationService.Infrastructure/Gateways/SignificantChangeApiClient.cs index a342776..44cea56 100644 --- a/src/Dfe.CaseAggregationService.Infrastructure/Gateways/SignificantChangeApiClient.cs +++ b/src/Dfe.CaseAggregationService.Infrastructure/Gateways/SignificantChangeApiClient.cs @@ -51,8 +51,9 @@ private DateTime ParseDate(string? dateString) return DateTime.MinValue; - return DateTime.TryParseExact(dateString, format, CultureInfo.InvariantCulture, - DateTimeStyles.None, out var date) ? date : DateTime.MinValue; + return DateTime.TryParseExact(dateString, "yyyy-MM-dd'T'HH:mm:ssK", + CultureInfo.InvariantCulture, + DateTimeStyles.RoundtripKind, out var date) ? date : DateTime.MinValue; } } diff --git a/src/Tests/Dfe.CaseAggregationService.Application.Tests/QueryHandlers/GetCasesForUser/GetCasesForUserQueryHandlerTests.cs b/src/Tests/Dfe.CaseAggregationService.Application.Tests/QueryHandlers/GetCasesForUser/GetCasesForUserQueryHandlerTests.cs index 5bf54ed..3f38206 100644 --- a/src/Tests/Dfe.CaseAggregationService.Application.Tests/QueryHandlers/GetCasesForUser/GetCasesForUserQueryHandlerTests.cs +++ b/src/Tests/Dfe.CaseAggregationService.Application.Tests/QueryHandlers/GetCasesForUser/GetCasesForUserQueryHandlerTests.cs @@ -298,6 +298,42 @@ private ISystemIntegration FixtureIntegration(string userEmail) return integration; } + [Fact] + public async Task Handle_GetCaseForUser_ReturnsEmptyIfProjectTypeIsSet() + { + // Arrange + var fixture = new Fixture(); + var userName = fixture.Create(); + var userEmail = fixture.Create(); + var query = new GetCasesForUserQuery(userName, + userEmail, + false, + true, + false, + false, + false, + false, + ["project type" + ], + null, + SortCriteria.CreatedDateDescending); + + + var logger = Substitute.For>(); + + var handler = new GetCasesForUserQueryHandler([FixtureIntegration(userEmail)], logger); + + // Act + var result = await handler.Handle(query, CancellationToken.None); + + // Assert + Assert.NotNull(result); + + var getCasesByUserResponseModel = result.Value!; + Assert.Equal(0, getCasesByUserResponseModel.TotalRecordCount); + Assert.Equal(0, getCasesByUserResponseModel.CaseInfos.Count); + } + private UserCaseInfo FixtureUserCaseInfo(int day) { return _fixture.Build() From 3810dca72fa9bc46bc3462781ed577a8fdf0c946 Mon Sep 17 00:00:00 2001 From: Sukhvinder Bhullar Date: Tue, 24 Mar 2026 18:48:17 +0000 Subject: [PATCH 6/6] Fixed tests --- .../GetCasesForUserQueryHandlerTests.cs | 36 --------- .../SigChangeIntegrationTests.cs | 80 +++++++++++++++++++ .../SignificantChangeApiClientTests.cs | 8 +- 3 files changed, 84 insertions(+), 40 deletions(-) create mode 100644 src/Tests/Dfe.CaseAggregationService.Application.Tests/Services/SystemIntegration/SigChangeIntegrationTests.cs diff --git a/src/Tests/Dfe.CaseAggregationService.Application.Tests/QueryHandlers/GetCasesForUser/GetCasesForUserQueryHandlerTests.cs b/src/Tests/Dfe.CaseAggregationService.Application.Tests/QueryHandlers/GetCasesForUser/GetCasesForUserQueryHandlerTests.cs index 3f38206..5bf54ed 100644 --- a/src/Tests/Dfe.CaseAggregationService.Application.Tests/QueryHandlers/GetCasesForUser/GetCasesForUserQueryHandlerTests.cs +++ b/src/Tests/Dfe.CaseAggregationService.Application.Tests/QueryHandlers/GetCasesForUser/GetCasesForUserQueryHandlerTests.cs @@ -298,42 +298,6 @@ private ISystemIntegration FixtureIntegration(string userEmail) return integration; } - [Fact] - public async Task Handle_GetCaseForUser_ReturnsEmptyIfProjectTypeIsSet() - { - // Arrange - var fixture = new Fixture(); - var userName = fixture.Create(); - var userEmail = fixture.Create(); - var query = new GetCasesForUserQuery(userName, - userEmail, - false, - true, - false, - false, - false, - false, - ["project type" - ], - null, - SortCriteria.CreatedDateDescending); - - - var logger = Substitute.For>(); - - var handler = new GetCasesForUserQueryHandler([FixtureIntegration(userEmail)], logger); - - // Act - var result = await handler.Handle(query, CancellationToken.None); - - // Assert - Assert.NotNull(result); - - var getCasesByUserResponseModel = result.Value!; - Assert.Equal(0, getCasesByUserResponseModel.TotalRecordCount); - Assert.Equal(0, getCasesByUserResponseModel.CaseInfos.Count); - } - private UserCaseInfo FixtureUserCaseInfo(int day) { return _fixture.Build() diff --git a/src/Tests/Dfe.CaseAggregationService.Application.Tests/Services/SystemIntegration/SigChangeIntegrationTests.cs b/src/Tests/Dfe.CaseAggregationService.Application.Tests/Services/SystemIntegration/SigChangeIntegrationTests.cs new file mode 100644 index 0000000..ac27df8 --- /dev/null +++ b/src/Tests/Dfe.CaseAggregationService.Application.Tests/Services/SystemIntegration/SigChangeIntegrationTests.cs @@ -0,0 +1,80 @@ +using AutoFixture; +using Dfe.CaseAggregationService.Application.Cases.Queries.GetCasesForUser; +using Dfe.CaseAggregationService.Application.Common.Models; +using Dfe.CaseAggregationService.Application.Services.Builders; +using Dfe.CaseAggregationService.Application.Services.SystemIntegration; +using Dfe.CaseAggregationService.Domain.Entities.SigChange; +using Dfe.CaseAggregationService.Domain.Interfaces.Repositories; +using FluentAssertions; +using Microsoft.Extensions.Logging; +using NSubstitute; + +namespace Dfe.CaseAggregationService.Application.Tests.Services.SystemIntegration +{ + public class SigChangeIntegrationTests + { + private readonly Fixture _fixture; + + public SigChangeIntegrationTests() + { + _fixture = new Fixture(); + } + + [Fact] + public async Task Handle_GetCaseForUserReturnsSingleItem() + { + var integration = CreateSigChangeIntegration(); + + var query = new GetCasesForUserQuery(UserName: "test user", UserEmail: "test.user@education.gov.uk", true, + false, false, false, false, false, []); + + var resultEnumerable = await integration.GetCasesForQuery(query, CancellationToken.None); + var result = resultEnumerable.ToArray() ?? []; + result.Should().NotBeNullOrEmpty(); + + result.Should().HaveCount(1); + } + + [Fact] + public async Task Handle_GetCaseForUserIfNotSelectedReturnsEmpty() + { + var integration = CreateSigChangeIntegration(); + + var query = new GetCasesForUserQuery(UserName: "test user", UserEmail: "test.user@education.gov.uk", false, + false, false, false, false, false, []); + + var resultEnumerable = await integration.GetCasesForQuery(query, CancellationToken.None); + var result = resultEnumerable.ToArray() ?? []; + result.Should().NotBeNull(); + result.Should().BeEmpty(); + } + + [Fact] + public async Task Handle_GetCaseForUserIfProjectTypeFilterReturnsEmpty() + { + var integration = CreateSigChangeIntegration(); + + var query = new GetCasesForUserQuery(UserName: "test user", UserEmail: "test.user@education.gov.uk", true, + false, false, false, false, false, ["project type"]); + + var resultEnumerable = await integration.GetCasesForQuery(query, CancellationToken.None); + var result = resultEnumerable.ToArray() ?? []; + result.Should().NotBeNull(); + result.Should().BeEmpty(); + } + + private SigChangeIntegration CreateSigChangeIntegration() + { + ISigChangeRepository repo = Substitute.For(); + IGetCaseInfo mapper = Substitute.For>(); + ILogger logger = Substitute.For>(); + + repo.GetSigChangeSummaries(Arg.Any(), Arg.Any()).Returns([_fixture.Create() + ]); + mapper.GetCaseInfo(Arg.Any()).Returns(_fixture.Create()); + + var integration = new SigChangeIntegration(repo, mapper, logger); + return integration; + } + } +} diff --git a/src/Tests/Dfe.CaseAggregationService.Infrastructure.Tests/Gateways/SignificantChangeApiClientTests.cs b/src/Tests/Dfe.CaseAggregationService.Infrastructure.Tests/Gateways/SignificantChangeApiClientTests.cs index d69391e..06259c7 100644 --- a/src/Tests/Dfe.CaseAggregationService.Infrastructure.Tests/Gateways/SignificantChangeApiClientTests.cs +++ b/src/Tests/Dfe.CaseAggregationService.Infrastructure.Tests/Gateways/SignificantChangeApiClientTests.cs @@ -31,8 +31,8 @@ public SignificantChangeApiClientTests() LocalAuthority = "LA 1", Region = "Region 1", DecisionDate = "10/02/2026", - ChangeCreationDate = "10/02/2026", - ChangeEditDate = "10/02/2026" + ChangeCreationDate = "2026-02-10T00:00:00Z", + ChangeEditDate = "2026-02-10T00:00:00Z" }, new() @@ -45,8 +45,8 @@ public SignificantChangeApiClientTests() LocalAuthority = "LA 2", Region = "Region 2", DecisionDate = "10/02/2026", - ChangeCreationDate = "10/02/2026", - ChangeEditDate = "10/02/2026" + ChangeCreationDate = "2026-02-10T00:00:00Z", + ChangeEditDate = "2026-02-10T00:00:00Z" } ] };