diff --git a/application/CohortManager/src/Functions/CohortDistributionServices/TransformDataService/TransformDataLookupFacade.cs b/application/CohortManager/src/Functions/CohortDistributionServices/TransformDataService/TransformDataLookupFacade.cs index 27f688bf3c..984a84162a 100644 --- a/application/CohortManager/src/Functions/CohortDistributionServices/TransformDataService/TransformDataLookupFacade.cs +++ b/application/CohortManager/src/Functions/CohortDistributionServices/TransformDataService/TransformDataLookupFacade.cs @@ -60,14 +60,22 @@ public async Task> GetCachedExcludedSMUValues() return excludedSMUData!; } + public bool ValidateOutcode(string postcode) { - string outcode = ValidationHelper.ParseOutcode(postcode) + var parsedOutCode = ValidationHelper.ParseOutcode(postcode); + _ = parsedOutCode.outcode ?? throw new TransformationException("Postcode format invalid"); - var result = _outcodeClient.GetSingle(outcode).Result; + // we can bypass checking the database if it's a dummy postcode + if (parsedOutCode.isDummyPostCode) + { + return true; + } + var result = _outcodeClient.GetSingle(parsedOutCode.outcode).Result; return result != null; + } /// @@ -83,7 +91,7 @@ public bool ValidateLanguageCode(string languageCode) public string GetBsoCode(string postcode) { - string outcode = ValidationHelper.ParseOutcode(postcode) + string outcode = ValidationHelper.ParseOutcode(postcode).outcode ?? throw new TransformationException("Postcode format invalid"); var result = _outcodeClient.GetSingle(outcode).Result; diff --git a/application/CohortManager/src/Functions/ScreeningValidationService/LookupValidation/DataLookupFacadeBreastScreening.cs b/application/CohortManager/src/Functions/ScreeningValidationService/LookupValidation/DataLookupFacadeBreastScreening.cs index a765e9a5e9..1c2536c3e4 100644 --- a/application/CohortManager/src/Functions/ScreeningValidationService/LookupValidation/DataLookupFacadeBreastScreening.cs +++ b/application/CohortManager/src/Functions/ScreeningValidationService/LookupValidation/DataLookupFacadeBreastScreening.cs @@ -53,7 +53,7 @@ public bool ValidateOutcode(string postcode) { var outcode = ValidationHelper.ParseOutcode(postcode); _logger.LogInformation("Validating Outcode: {Outcode}", outcode); - var result = _outcodeClient.GetSingle(outcode).Result; + var result = _outcodeClient.GetSingle(outcode.outcode!).Result; return result != null; } diff --git a/application/CohortManager/src/Functions/Shared/Common/ValidationHelper.cs b/application/CohortManager/src/Functions/Shared/Common/ValidationHelper.cs index 76cbdfe34a..318266a15d 100644 --- a/application/CohortManager/src/Functions/Shared/Common/ValidationHelper.cs +++ b/application/CohortManager/src/Functions/Shared/Common/ValidationHelper.cs @@ -1,7 +1,10 @@ namespace Common; using System.Globalization; +using System.Linq.Expressions; using System.Text.RegularExpressions; +using Hl7.Fhir.Validation; +using Model; public static class ValidationHelper { @@ -100,31 +103,36 @@ public static bool ValidatePostcode(string postcode) } /// - /// Gets the outcode (1st part of postcode) from the postcode. + /// Gets the outcode (1st part of postcode) from the postcode and if the postcode is a dummy code /// /// a non-null string representing the postcode /// /// Works for valid UK postcodes and dummy postcodes. /// Works with or without a space separator between outcode and incode. /// - public static string? ParseOutcode(string postcode) + public static (string? outcode, bool isDummyPostCode) ParseOutcode(string postcode) { - if (postcode == "ZZZSECUR") - { - return postcode; - } - string pattern = @"^([A-Za-z][A-Za-z]?[0-9][A-Za-z0-9]?) ?[0-9][A-Za-z]{2}$"; + string specialDummyOutCodePattern = "^ZZ99|^ZZZSECUR$"; Match match = Regex.Match(postcode, pattern, RegexOptions.IgnoreCase, TimeSpan.FromSeconds(2)); + Match dummyOutCodePattern = Regex.Match(postcode, specialDummyOutCodePattern, RegexOptions.IgnoreCase, TimeSpan.FromSeconds(2)); + + if (dummyOutCodePattern.Success) + { + return (postcode, true); + } + if (!match.Success) { - return null; + return (null, false); } + + string outcode = match.Groups[1].Value; - return outcode; + return (outcode, false); } private static bool ParseInt32(char value, out int integerValue) diff --git a/tests/UnitTests/TransformDataServiceTests/TransformDataServiceTests/TransformDataLookupFacadeTests.cs b/tests/UnitTests/TransformDataServiceTests/TransformDataServiceTests/TransformDataLookupFacadeTests.cs index 2e85299567..9697c0a5ac 100644 --- a/tests/UnitTests/TransformDataServiceTests/TransformDataServiceTests/TransformDataLookupFacadeTests.cs +++ b/tests/UnitTests/TransformDataServiceTests/TransformDataServiceTests/TransformDataLookupFacadeTests.cs @@ -95,6 +95,23 @@ public void ValidateOutcode_OutcodeNotFound_ReturnFalse() Assert.IsFalse(result); } + [TestMethod] + public void ValidateOutcode_OutCodeIsSpecial_ReturnTrue() + { + // Arrange + _outcodeClientMock + .Setup(x => x.GetSingle(It.IsAny())) + .ReturnsAsync((BsSelectOutCode)null); + + string postcode = "ZZZSECUR"; + + // Act + bool result = _sut.ValidateOutcode(postcode); + + // Assert + Assert.IsTrue(result); + } + [TestMethod] [DataRow("")] [DataRow("ABC123")]