diff --git a/src/Spd.Manager.Licence.UnitTest/BizLicAppValidationTest.cs b/src/Spd.Manager.Licence.UnitTest/BizLicAppValidationTest.cs index 61cc52c07..c92abc122 100644 --- a/src/Spd.Manager.Licence.UnitTest/BizLicAppValidationTest.cs +++ b/src/Spd.Manager.Licence.UnitTest/BizLicAppValidationTest.cs @@ -1,10 +1,13 @@ using AutoFixture; using FluentValidation.TestHelper; +using Microsoft.Extensions.Configuration; +using System.Text; namespace Spd.Manager.Licence.UnitTest; public class BizLicAppValidationTest { private readonly IFixture fixture; + private readonly IConfiguration config; public BizLicAppValidationTest() { @@ -13,23 +16,39 @@ public BizLicAppValidationTest() fixture.Customize(composer => composer.FromFactory(DateOnly.FromDateTime)); fixture.Behaviors.Remove(new ThrowingRecursionBehavior()); fixture.Behaviors.Add(new OmitOnRecursionBehavior()); + config = CreateConfiguration(); } [Fact] public void BizLicAppUpsertRequestValidator_ShouldPass() { - BizLicAppUpsertRequestValidator validator = new BizLicAppUpsertRequestValidator(); + BizLicAppUpsertRequestValidator validator = new BizLicAppUpsertRequestValidator(config); var model = GenerateValidRequest(); var result = validator.TestValidate(model); result.ShouldNotHaveAnyValidationErrors(); } + [Fact] + public void BizLicAppUpsertRequestValidator_With_Locksmith_SecurityAlarmInstaller_ShouldPass() + { + BizLicAppUpsertRequestValidator validator = new BizLicAppUpsertRequestValidator(config); + + var model = GenerateValidRequest(); + model.CategoryCodes = new List() + { + WorkerCategoryTypeCode.Locksmith, + WorkerCategoryTypeCode.SecurityAlarmInstaller + }; + + var result = validator.TestValidate(model); + result.ShouldNotHaveAnyValidationErrors(); + } [Fact] public void BizLicAppUpsertRequestValidator_WithEmptyFields_ShouldPass() { - BizLicAppUpsertRequestValidator validator = new BizLicAppUpsertRequestValidator(); + BizLicAppUpsertRequestValidator validator = new BizLicAppUpsertRequestValidator(config); var model = GenerateValidRequest(); @@ -44,7 +63,7 @@ public void BizLicAppUpsertRequestValidator_WithEmptyFields_ShouldPass() [Fact] public void BizLicAppSubmitRequestValidator_ShouldPass() { - BizLicAppSubmitRequestValidator validator = new BizLicAppSubmitRequestValidator(); + BizLicAppSubmitRequestValidator validator = new BizLicAppSubmitRequestValidator(config); var model = GenerateValidRequest(); @@ -55,7 +74,7 @@ public void BizLicAppSubmitRequestValidator_ShouldPass() [Fact] public void BizLicAppSubmitRequestValidator_WithEmptyFields_ShouldPass() { - BizLicAppSubmitRequestValidator validator = new BizLicAppSubmitRequestValidator(); + BizLicAppSubmitRequestValidator validator = new BizLicAppSubmitRequestValidator(config); var model = GenerateValidRequest(); @@ -72,7 +91,7 @@ public void BizLicAppSubmitRequestValidator_WithEmptyFields_ShouldPass() [Fact] public void ApplicantContactInfo_WhenHasEmptyFields_ShouldThrowException() { - BizLicAppUpsertRequestValidator validator = new BizLicAppUpsertRequestValidator(); + BizLicAppUpsertRequestValidator validator = new BizLicAppUpsertRequestValidator(config); var model = GenerateValidRequest(); model.ApplicantContactInfo.GivenName = string.Empty; @@ -90,10 +109,10 @@ public void ApplicantContactInfo_WhenHasEmptyFields_ShouldThrowException() [Fact] public void CategoryCodes_WhenHasWrongSet_ShouldThrowException() { - BizLicAppUpsertRequestValidator validator = new BizLicAppUpsertRequestValidator(); + BizLicAppUpsertRequestValidator validator = new BizLicAppUpsertRequestValidator(config); var model = GenerateValidRequest(); - model.CategoryCodes = new List() { WorkerCategoryTypeCode.SecurityAlarmInstaller }; + model.CategoryCodes = new List() { WorkerCategoryTypeCode.PrivateInvestigator, WorkerCategoryTypeCode.PrivateInvestigatorUnderSupervision }; var result = validator.TestValidate(model); result.ShouldHaveValidationErrorFor(r => r.CategoryCodes); @@ -102,7 +121,7 @@ public void CategoryCodes_WhenHasWrongSet_ShouldThrowException() [Fact] public void BizLicAppUpsertRequest_DocumentInfos_WithoutMandatoryDocuments_ShouldThrowException() { - BizLicAppUpsertRequestValidator validator = new BizLicAppUpsertRequestValidator(); + BizLicAppUpsertRequestValidator validator = new BizLicAppUpsertRequestValidator(config); var model = GenerateValidRequest(); model.DocumentInfos = null; @@ -114,7 +133,7 @@ public void BizLicAppUpsertRequest_DocumentInfos_WithoutMandatoryDocuments_Shoul [Fact] public void BizLicAppUpsertRequest_DocumentInfos_WhenExceedsMaxAllowed_ShouldThrowException() { - BizLicAppUpsertRequestValidator validator = new BizLicAppUpsertRequestValidator(); + BizLicAppUpsertRequestValidator validator = new BizLicAppUpsertRequestValidator(config); var model = GenerateValidRequest(); @@ -182,7 +201,7 @@ public void BizLicAppUpsertRequest_DocumentInfos_WhenExceedsMaxAllowed_ShouldThr [Fact] public void PrivateInvestigatorSwlInfo_WhenHasEmptyFields_ShouldThrowException() { - BizLicAppUpsertRequestValidator validator = new BizLicAppUpsertRequestValidator(); + BizLicAppUpsertRequestValidator validator = new BizLicAppUpsertRequestValidator(config); var model = GenerateValidRequest(); @@ -257,4 +276,37 @@ private T GenerateValidRequest() return (T)Convert.ChangeType(model, typeof(T)); } + private static IConfiguration CreateConfiguration() + { + var json = @" + { + ""InvalidWorkerLicenceCategoryMatrix"": { + ""ArmouredCarGuard"": [""ArmouredCarGuard"", ""SecurityGuardUnderSupervision""], + ""BodyArmourSales"": [""SecurityGuardUnderSupervision"", ""BodyArmourSales""], + ""ClosedCircuitTelevisionInstaller"": [""SecurityAlarmInstallerUnderSupervision"", ""SecurityAlarmInstaller"", ""ClosedCircuitTelevisionInstaller"", ""SecurityGuardUnderSupervision""], + ""ElectronicLockingDeviceInstaller"": [""ElectronicLockingDeviceInstaller"", ""SecurityAlarmInstallerUnderSupervision"", ""SecurityAlarmInstaller"", ""LocksmithUnderSupervision"", ""Locksmith"", ""SecurityGuardUnderSupervision""], + ""FireInvestigator"": [""PrivateInvestigatorUnderSupervision"", ""PrivateInvestigator"", ""FireInvestigator"", ""SecurityGuardUnderSupervision""], + ""Locksmith"": [""ElectronicLockingDeviceInstaller"", ""LocksmithUnderSupervision"", ""Locksmith"", ""SecurityGuardUnderSupervision""], + ""LocksmithUnderSupervision"": [""ElectronicLockingDeviceInstaller"", ""LocksmithUnderSupervision"", ""Locksmith"", ""SecurityGuardUnderSupervision""], + ""PrivateInvestigator"": [""PrivateInvestigatorUnderSupervision"", ""PrivateInvestigator"", ""FireInvestigator"", ""SecurityGuardUnderSupervision""], + ""PrivateInvestigatorUnderSupervision"": [""PrivateInvestigatorUnderSupervision"", ""PrivateInvestigator"", ""FireInvestigator"", ""SecurityGuardUnderSupervision""], + ""SecurityAlarmInstaller"": [""ElectronicLockingDeviceInstaller"", ""SecurityAlarmInstallerUnderSupervision"", ""SecurityAlarmInstaller"", ""SecurityAlarmMonitor"", ""SecurityAlarmResponse"", ""SecurityAlarmSales"", ""ClosedCircuitTelevisionInstaller"", ""SecurityGuardUnderSupervision""], + ""SecurityAlarmInstallerUnderSupervision"": [""ElectronicLockingDeviceInstaller"", ""SecurityAlarmInstallerUnderSupervision"", ""SecurityAlarmInstaller"", ""SecurityAlarmMonitor"", ""SecurityAlarmResponse"", ""SecurityAlarmSales"", ""ClosedCircuitTelevisionInstaller"", ""SecurityGuardUnderSupervision""], + ""SecurityAlarmMonitor"": [""SecurityAlarmInstallerUnderSupervision"", ""SecurityAlarmInstaller"", ""SecurityAlarmMonitor"", ""SecurityAlarmResponse"", ""SecurityGuardUnderSupervision"", ""SecurityAlarmSales"", ""SecurityGuard""], + ""SecurityAlarmResponse"": [""SecurityAlarmInstallerUnderSupervision"", ""SecurityAlarmInstaller"", ""SecurityAlarmMonitor"", ""SecurityAlarmResponse"", ""SecurityGuardUnderSupervision"", ""SecurityGuard""], + ""SecurityAlarmSales"": [""SecurityAlarmInstallerUnderSupervision"", ""SecurityAlarmInstaller"", ""SecurityAlarmMonitor"", ""SecurityAlarmSales"", ""SecurityGuardUnderSupervision"", ""SecurityGuard""], + ""SecurityConsultant"": [""SecurityConsultant"", ""SecurityGuardUnderSupervision""], + ""SecurityGuard"": [""SecurityAlarmMonitor"", ""SecurityAlarmResponse"", ""SecurityGuardUnderSupervision"", ""SecurityGuard"", ""SecurityAlarmSales""], + ""SecurityGuardUnderSupervision"": [""ArmouredCarGuard"", ""ElectronicLockingDeviceInstaller"", ""SecurityAlarmInstallerUnderSupervision"", ""SecurityAlarmInstaller"", ""SecurityAlarmMonitor"", ""SecurityAlarmResponse"", ""SecurityAlarmSales"", ""ClosedCircuitTelevisionInstaller"", ""LocksmithUnderSupervision"", ""Locksmith"", ""PrivateInvestigator"", ""PrivateInvestigatorUnderSupervision"", ""FireInvestigator"", ""SecurityConsultant"", ""SecurityGuardUnderSupervision"", ""SecurityGuard"", ""BodyArmourSales""] + } + }"; + + + var builder = new ConfigurationBuilder() + .AddJsonStream(new MemoryStream(Encoding.UTF8.GetBytes(json))); + + + + return builder.Build(); + } } diff --git a/src/Spd.Manager.Licence/BizLicAppBaseValidation.cs b/src/Spd.Manager.Licence/BizLicAppBaseValidation.cs index 3dc127d7e..f971cb3e3 100644 --- a/src/Spd.Manager.Licence/BizLicAppBaseValidation.cs +++ b/src/Spd.Manager.Licence/BizLicAppBaseValidation.cs @@ -30,25 +30,6 @@ public BizLicAppBaseValidator() .Must(r => r == Shared.LicenceTermCode.OneYear || r == Shared.LicenceTermCode.TwoYears || r == Shared.LicenceTermCode.ThreeYears); RuleFor(r => r.AgreeToCompleteAndAccurate).NotEmpty().Equal(true); - // Parent/child categories - //RuleFor(r => r.CategoryCodes) - // .Must(r => r.Contains(WorkerCategoryTypeCode.SecurityAlarmSales) && - // r.Contains(WorkerCategoryTypeCode.SecurityAlarmMonitor) && - // r.Contains(WorkerCategoryTypeCode.SecurityAlarmResponse) && - // r.Contains(WorkerCategoryTypeCode.ClosedCircuitTelevisionInstaller) && - // r.Contains(WorkerCategoryTypeCode.ElectronicLockingDeviceInstaller)) - // .When(r => r.CategoryCodes.Any(c => c == WorkerCategoryTypeCode.SecurityAlarmInstaller)); - //RuleFor(r => r.CategoryCodes) - // .Must(r => r.Contains(WorkerCategoryTypeCode.SecurityAlarmMonitor)) - // .When(r => r.CategoryCodes.Any(c => c == WorkerCategoryTypeCode.SecurityAlarmResponse)); - //RuleFor(r => r.CategoryCodes) - // .Must(r => r.Contains(WorkerCategoryTypeCode.ElectronicLockingDeviceInstaller)) - // .When(r => r.CategoryCodes.Any(c => c == WorkerCategoryTypeCode.Locksmith)); - //RuleFor(r => r.CategoryCodes) - // .Must(r => r.Contains(WorkerCategoryTypeCode.SecurityAlarmMonitor) && - // r.Contains(WorkerCategoryTypeCode.SecurityAlarmResponse)) - // .When(r => r.CategoryCodes.Any(c => c == WorkerCategoryTypeCode.SecurityGuard)); - // Private investigator RuleFor(r => r.PrivateInvestigatorSwlInfo) .Must(r => r.ContactId != null && r.ContactId != Guid.Empty && diff --git a/src/Spd.Manager.Licence/BizLicAppValidation.cs b/src/Spd.Manager.Licence/BizLicAppValidation.cs index d44c763e8..7b7ec2307 100644 --- a/src/Spd.Manager.Licence/BizLicAppValidation.cs +++ b/src/Spd.Manager.Licence/BizLicAppValidation.cs @@ -1,10 +1,42 @@ using FluentValidation; +using Microsoft.Extensions.Configuration; +using Spd.Utilities.Shared.Exceptions; namespace Spd.Manager.Licence; public class BizLicAppUpsertRequestValidator : BizLicAppBaseValidator { - public BizLicAppUpsertRequestValidator() + public BizLicAppUpsertRequestValidator(IConfiguration configuration) { + //category + RuleFor(r => r.CategoryCodes).NotEmpty().Must(d => d.Any() && d.Count() < 7); + var invalidCategoryMatrix = configuration.GetSection("InvalidWorkerLicenceCategoryMatrix").Get>>(); + if (invalidCategoryMatrix == null) + throw new ApiException(System.Net.HttpStatusCode.InternalServerError, "missing configuration for invalid worker licence category matrix"); + + RuleFor(r => r.CategoryCodes).Must(c => + { + foreach (var code in c) + { + var invalidCodes = invalidCategoryMatrix.GetValueOrDefault(code); + if (invalidCodes != null) + { + foreach (var cat in c) + { + if (cat != code) + { + if (invalidCodes.Contains(cat)) + { + return false; + } + } + } + } + } + return true; + }) + .When(c => c.CategoryCodes != null) + .WithMessage("Some category cannot be in the same licence request."); + // General validations RuleFor(r => r.BizId).NotEqual(Guid.Empty); RuleFor(r => r.HasExpiredLicence).NotEmpty(); @@ -57,7 +89,7 @@ public BizLicAppUpsertRequestValidator() public class BizLicAppSubmitRequestValidator : BizLicAppBaseValidator { - public BizLicAppSubmitRequestValidator() + public BizLicAppSubmitRequestValidator(IConfiguration configuration) { // General validations RuleFor(r => r.LatestApplicationId).NotEmpty(); @@ -68,5 +100,35 @@ public BizLicAppSubmitRequestValidator() RuleFor(r => r.BizTypeCode) .Must(r => r == BizTypeCode.NonRegisteredSoleProprietor || r == BizTypeCode.RegisteredSoleProprietor) .When(r => r.SoleProprietorSWLAppId != null); + + //category + RuleFor(r => r.CategoryCodes).NotEmpty().Must(d => d.Any() && d.Count() < 7); + var invalidCategoryMatrix = configuration.GetSection("InvalidWorkerLicenceCategoryMatrix").Get>>(); + if (invalidCategoryMatrix == null) + throw new ApiException(System.Net.HttpStatusCode.InternalServerError, "missing configuration for invalid worker licence category matrix"); + + RuleFor(r => r.CategoryCodes).Must(c => + { + foreach (var code in c) + { + var invalidCodes = invalidCategoryMatrix.GetValueOrDefault(code); + if (invalidCodes != null) + { + foreach (var cat in c) + { + if (cat != code) + { + if (invalidCodes.Contains(cat)) + { + return false; + } + } + } + } + } + return true; + }) + .When(c => c.CategoryCodes != null) + .WithMessage("Some category cannot be in the same licence request."); } }