diff --git a/src/Directory.Packages.props b/src/Directory.Packages.props index c36bd2038..2dc57d7bd 100644 --- a/src/Directory.Packages.props +++ b/src/Directory.Packages.props @@ -34,6 +34,7 @@ + diff --git a/src/ECER.Engines.Validation/Applications/ApplicationRenewalValidationEngine.cs b/src/ECER.Engines.Validation/Applications/ApplicationRenewalValidationEngine.cs new file mode 100644 index 000000000..b9e1f1bc1 --- /dev/null +++ b/src/ECER.Engines.Validation/Applications/ApplicationRenewalValidationEngine.cs @@ -0,0 +1,80 @@ +using ECER.Managers.Registry.Contract.Applications; +using ECER.Resources.Documents.Certifications; +using System.Runtime.CompilerServices; + +namespace ECER.Engines.Validation.Applications; + +internal sealed partial class ApplicationRenewalValidationEngine : IApplicationValidationEngine +{ + private ICertificationRepository _certificateRepository; + + public ApplicationRenewalValidationEngine(ICertificationRepository certificationRepository) + { + _certificateRepository = certificationRepository; + } + + public async Task Validate(Application application) + { + await Task.CompletedTask; + var validationErrors = new List(); + + if (application.CertificationTypes.Contains(CertificationType.EceAssistant)) + { + validationErrors = await EceAssistant(application); + } + else if (application.CertificationTypes.Contains(CertificationType.OneYear)) + { + validationErrors = await OneYear(application); + } + else if (application.CertificationTypes.Contains(CertificationType.FiveYears)) + { + validationErrors = await FiveYears(application); + } + return new ValidationResults(validationErrors); + } + + private enum CertificateStatus + { + Active, + ExpiredLessThanFiveYearsAgo, + ExpiredMoreThanFiveYearsAgo, + NoCertificateFound + } + + private async Task GetCertificateStatus(string applicantId) + { + try + { + var expiryDate = await getLastCertificateExpiryDate(applicantId); + var now = DateTime.Now; + + if (expiryDate > now) + { + return CertificateStatus.Active; + } + else if (expiryDate <= now && expiryDate > now.AddYears(-5)) + { + return CertificateStatus.ExpiredLessThanFiveYearsAgo; + } + else + { + return CertificateStatus.ExpiredMoreThanFiveYearsAgo; + } + } + catch (InvalidOperationException) + { + return CertificateStatus.NoCertificateFound; + } + } + + private async Task getLastCertificateExpiryDate(string applicantId) + { + var certificates = await _certificateRepository.Query(new UserCertificationQuery() { ByApplicantId = applicantId }); + var lastCertificate = certificates.OrderByDescending(d => d.ExpiryDate).FirstOrDefault(); + if (lastCertificate == null || lastCertificate.ExpiryDate == null) + { + throw new InvalidOperationException("Certificate or datetime is null"); + } + return (DateTime)lastCertificate.ExpiryDate; + } +} diff --git a/src/ECER.Engines.Validation/Applications/ApplicationSubmissionValidationEngine.cs b/src/ECER.Engines.Validation/Applications/ApplicationSubmissionValidationEngine.cs index d30383f3b..21cc5ee1f 100644 --- a/src/ECER.Engines.Validation/Applications/ApplicationSubmissionValidationEngine.cs +++ b/src/ECER.Engines.Validation/Applications/ApplicationSubmissionValidationEngine.cs @@ -2,7 +2,7 @@ namespace ECER.Engines.Validation.Applications; -internal sealed class ApplicationSubmissionValidationEngine : IApplicationSubmissionValidationEngine +internal sealed class ApplicationSubmissionValidationEngine : IApplicationValidationEngine { private static readonly IEnumerable fiveYearNestedCertificationTypes = new[] { CertificationType.Ite, CertificationType.Sne }; diff --git a/src/ECER.Engines.Validation/Applications/ApplicationValidationEngineResolver.cs b/src/ECER.Engines.Validation/Applications/ApplicationValidationEngineResolver.cs new file mode 100644 index 000000000..05f68480f --- /dev/null +++ b/src/ECER.Engines.Validation/Applications/ApplicationValidationEngineResolver.cs @@ -0,0 +1,29 @@ +using ECER.Managers.Registry.Contract.Applications; +using Microsoft.Extensions.DependencyInjection; + +namespace ECER.Engines.Validation.Applications; + +public interface IApplicationValidationEngineResolver +{ + IApplicationValidationEngine Resolve(ApplicationTypes appType); +} + +public class ApplicationValidationEngineResolver : IApplicationValidationEngineResolver +{ + private readonly IServiceProvider _serviceProvider; + + public ApplicationValidationEngineResolver(IServiceProvider serviceProvider) + { + _serviceProvider = serviceProvider; + } + + public IApplicationValidationEngine Resolve(ApplicationTypes appType) + { + return appType switch + { + ApplicationTypes.New => _serviceProvider.GetRequiredService(), + ApplicationTypes.Renewal => _serviceProvider.GetRequiredService(), + _ => throw new ArgumentOutOfRangeException(nameof(appType), appType, null) + }; + } +} diff --git a/src/ECER.Engines.Validation/Applications/IApplicationSubmissionValidationEngine.cs b/src/ECER.Engines.Validation/Applications/IApplicationValidationEngine.cs similarity index 91% rename from src/ECER.Engines.Validation/Applications/IApplicationSubmissionValidationEngine.cs rename to src/ECER.Engines.Validation/Applications/IApplicationValidationEngine.cs index e68ba345d..e3d2382d6 100644 --- a/src/ECER.Engines.Validation/Applications/IApplicationSubmissionValidationEngine.cs +++ b/src/ECER.Engines.Validation/Applications/IApplicationValidationEngine.cs @@ -5,7 +5,7 @@ namespace ECER.Engines.Validation.Applications; /// /// Validates registry applications /// -public interface IApplicationSubmissionValidationEngine +public interface IApplicationValidationEngine { /// /// Validates if an application is completed diff --git a/src/ECER.Engines.Validation/Applications/RenewalValidationConditions/EceAssistant.cs b/src/ECER.Engines.Validation/Applications/RenewalValidationConditions/EceAssistant.cs new file mode 100644 index 000000000..2ff03da63 --- /dev/null +++ b/src/ECER.Engines.Validation/Applications/RenewalValidationConditions/EceAssistant.cs @@ -0,0 +1,27 @@ +using ECER.Managers.Registry.Contract.Applications; + +namespace ECER.Engines.Validation.Applications; + +internal sealed partial class ApplicationRenewalValidationEngine +{ + private async Task> EceAssistant(Application application) + { + await Task.CompletedTask; + var validationErrors = new List(); + switch (await GetCertificateStatus(application.RegistrantId)) + { + case CertificateStatus.Active: + break; + + case CertificateStatus.ExpiredLessThanFiveYearsAgo: + break; + + case CertificateStatus.ExpiredMoreThanFiveYearsAgo: + break; + + case CertificateStatus.NoCertificateFound: + break; + } + return validationErrors; + } +} diff --git a/src/ECER.Engines.Validation/Applications/RenewalValidationConditions/FiveYears.cs b/src/ECER.Engines.Validation/Applications/RenewalValidationConditions/FiveYears.cs new file mode 100644 index 000000000..fda8a14f5 --- /dev/null +++ b/src/ECER.Engines.Validation/Applications/RenewalValidationConditions/FiveYears.cs @@ -0,0 +1,27 @@ +using ECER.Managers.Registry.Contract.Applications; + +namespace ECER.Engines.Validation.Applications; + +internal sealed partial class ApplicationRenewalValidationEngine +{ + private async Task> FiveYears(Application application) + { + await Task.CompletedTask; + var validationErrors = new List(); + switch (await GetCertificateStatus(application.RegistrantId)) + { + case CertificateStatus.Active: + break; + + case CertificateStatus.ExpiredLessThanFiveYearsAgo: + break; + + case CertificateStatus.ExpiredMoreThanFiveYearsAgo: + break; + + case CertificateStatus.NoCertificateFound: + break; + } + return validationErrors; + } +} diff --git a/src/ECER.Engines.Validation/Applications/RenewalValidationConditions/OneYear.cs b/src/ECER.Engines.Validation/Applications/RenewalValidationConditions/OneYear.cs new file mode 100644 index 000000000..74f1e4190 --- /dev/null +++ b/src/ECER.Engines.Validation/Applications/RenewalValidationConditions/OneYear.cs @@ -0,0 +1,38 @@ +using ECER.Managers.Registry.Contract.Applications; + +namespace ECER.Engines.Validation.Applications; + +internal sealed partial class ApplicationRenewalValidationEngine +{ + private async Task> OneYear(Application application) + { + await Task.CompletedTask; + var validationErrors = new List(); + switch (await GetCertificateStatus(application.RegistrantId)) + { + case CertificateStatus.Active: + + // each application should contain explanation letter + if (string.IsNullOrEmpty(application.ExplanationLetter)) + { + validationErrors.Add("the application does not have explanation letter"); + } + // each application should contain at least one character reference + if (!application.CharacterReferences.Any()) + { + validationErrors.Add("the application does not have any character references"); + } + break; + + case CertificateStatus.ExpiredLessThanFiveYearsAgo: + break; + + case CertificateStatus.ExpiredMoreThanFiveYearsAgo: + break; + + case CertificateStatus.NoCertificateFound: + break; + } + return validationErrors; + } +} diff --git a/src/ECER.Engines.Validation/Configurer.cs b/src/ECER.Engines.Validation/Configurer.cs index a9e5ebe86..8014d9ef3 100644 --- a/src/ECER.Engines.Validation/Configurer.cs +++ b/src/ECER.Engines.Validation/Configurer.cs @@ -7,8 +7,15 @@ namespace ECER.Engines.Validation; public class Configurer : IConfigureComponents { - public void Configure([NotNull] ConfigurationContext configurationContext) + public void Configure([NotNull] ConfigurationContext configurationContext) + { + configurationContext.Services.AddTransient(); + configurationContext.Services.AddTransient(); + configurationContext.Services.AddTransient(); + + configurationContext.Services.AddTransient(provider => { - configurationContext.Services.AddTransient(); - } + return provider.GetRequiredService(); + }); + } } diff --git a/src/ECER.Engines.Validation/ECER.Engines.Validation.csproj b/src/ECER.Engines.Validation/ECER.Engines.Validation.csproj index ae83f8ad7..fc1ef9290 100644 --- a/src/ECER.Engines.Validation/ECER.Engines.Validation.csproj +++ b/src/ECER.Engines.Validation/ECER.Engines.Validation.csproj @@ -5,5 +5,6 @@ + diff --git a/src/ECER.Managers.Registry/ApplicationHandlers.cs b/src/ECER.Managers.Registry/ApplicationHandlers.cs index 2e128a3c6..83d165cd4 100644 --- a/src/ECER.Managers.Registry/ApplicationHandlers.cs +++ b/src/ECER.Managers.Registry/ApplicationHandlers.cs @@ -19,7 +19,7 @@ public class ApplicationHandlers( IPortalInvitationRepository portalInvitationRepository, IApplicationRepository applicationRepository, IMapper mapper, - IApplicationSubmissionValidationEngine validationEngine, + IApplicationValidationEngineResolver validationResolver, EcerContext ecerContext) : IRequestHandler, IRequestHandler, @@ -109,6 +109,7 @@ public async Task Handle(SubmitApplicationCommand r } var draftApplication = draftApplicationResults.Items.First(); + var validationEngine = validationResolver?.Resolve(draftApplication.ApplicationType); var validationErrors = await validationEngine?.Validate(draftApplication)!; if (validationErrors.ValidationErrors.Any()) { diff --git a/src/ECER.Resources.Documents/Certifications/ICertificationRepository.cs b/src/ECER.Resources.Documents/Certifications/ICertificationRepository.cs index 8f2a75782..a3e474acf 100644 --- a/src/ECER.Resources.Documents/Certifications/ICertificationRepository.cs +++ b/src/ECER.Resources.Documents/Certifications/ICertificationRepository.cs @@ -9,6 +9,7 @@ public record UserCertificationQuery { public string? ById { get; set; } public string? ByApplicantId { get; set; } + public string? ByApplicationId { get; set; } } public record Certification(string Id) diff --git a/src/ECER.Tests/ECER.Tests.csproj b/src/ECER.Tests/ECER.Tests.csproj index b2702e419..7e851531c 100644 --- a/src/ECER.Tests/ECER.Tests.csproj +++ b/src/ECER.Tests/ECER.Tests.csproj @@ -1,6 +1,7 @@  + ECER.Tests false true CA1001;1701;1702;CA1707 @@ -11,6 +12,7 @@ + diff --git a/src/ECER.Tests/Integration/Api/FileTests.cs b/src/ECER.Tests/Integration/Api/FileTests.cs index 48e3b97b7..3bd879fdd 100644 --- a/src/ECER.Tests/Integration/Api/FileTests.cs +++ b/src/ECER.Tests/Integration/Api/FileTests.cs @@ -1,8 +1,7 @@ -using System.Net.Http.Headers; -using Alba; +using Alba; using Bogus; -using ECER.Tests.Integration; using Shouldly; +using System.Net.Http.Headers; using Xunit.Abstractions; using Xunit.Categories; diff --git a/src/ECER.Tests/Integration/AuthenticationHelper.cs b/src/ECER.Tests/Integration/AuthenticationHelper.cs index 6b18733fb..fca03ba58 100644 --- a/src/ECER.Tests/Integration/AuthenticationHelper.cs +++ b/src/ECER.Tests/Integration/AuthenticationHelper.cs @@ -1,6 +1,6 @@ -using System.Security.Claims; -using Alba; +using Alba; using ECER.Utilities.Security; +using System.Security.Claims; namespace ECER.Tests.Integration; diff --git a/src/ECER.Tests/Integration/RegistryApi/ApplicationTests.cs b/src/ECER.Tests/Integration/RegistryApi/ApplicationTests.cs index cdb86239a..e27a78f49 100644 --- a/src/ECER.Tests/Integration/RegistryApi/ApplicationTests.cs +++ b/src/ECER.Tests/Integration/RegistryApi/ApplicationTests.cs @@ -1,13 +1,11 @@ using Alba; using Bogus; using ECER.Clients.RegistryPortal.Server.Applications; +using ECER.Clients.RegistryPortal.Server.Files; using Shouldly; using System.Net; -using Xunit.Abstractions; using System.Net.Http.Headers; -using Xunit.Categories; -using ECER.Clients.RegistryPortal.Server.Files; -using System; +using Xunit.Abstractions; namespace ECER.Tests.Integration.RegistryApi; diff --git a/src/ECER.Tests/Integration/RegistryApi/FileTests.cs b/src/ECER.Tests/Integration/RegistryApi/FileTests.cs index 5a66bb0a7..132598137 100644 --- a/src/ECER.Tests/Integration/RegistryApi/FileTests.cs +++ b/src/ECER.Tests/Integration/RegistryApi/FileTests.cs @@ -1,9 +1,8 @@ -using System.Net.Http.Headers; -using Alba; +using Alba; using Bogus; +using System.Net.Http.Headers; using Xunit.Abstractions; using Xunit.Categories; -using Xunit.Sdk; namespace ECER.Tests.Integration.RegistryApi; diff --git a/src/ECER.Tests/Integration/RegistryApi/ProfileTests.cs b/src/ECER.Tests/Integration/RegistryApi/ProfileTests.cs index 40590d376..b365bd12a 100644 --- a/src/ECER.Tests/Integration/RegistryApi/ProfileTests.cs +++ b/src/ECER.Tests/Integration/RegistryApi/ProfileTests.cs @@ -41,7 +41,7 @@ private PreviousName CreatePreviousName() faker.Name.FirstName(), faker.Name.LastName() ); } - + private UserProfile CreateNewUser() { var address = new Faker
("en_CA") @@ -53,7 +53,6 @@ private UserProfile CreateNewUser() f.Address.State(), f.Address.Country() )); - return new Faker("en_CA") .RuleFor(f => f.FirstName, f => f.Name.FirstName()) .RuleFor(f => f.LastName, f => f.Name.LastName()) diff --git a/src/ECER.Tests/Integration/RegistryApi/UserInfoTests.cs b/src/ECER.Tests/Integration/RegistryApi/UserInfoTests.cs index f8978626d..93bb7eed1 100644 --- a/src/ECER.Tests/Integration/RegistryApi/UserInfoTests.cs +++ b/src/ECER.Tests/Integration/RegistryApi/UserInfoTests.cs @@ -1,9 +1,9 @@ -using System.Net; -using Alba; +using Alba; using Bogus; using ECER.Clients.RegistryPortal.Server.Users; using ECER.Utilities.Security; using Shouldly; +using System.Net; using Xunit.Abstractions; namespace ECER.Tests.Integration.RegistryApi; diff --git a/src/ECER.Tests/Integration/RegistryPortalWebAppScenarioBase.cs b/src/ECER.Tests/Integration/RegistryPortalWebAppScenarioBase.cs index 53c6ab097..1b5e8bd94 100644 --- a/src/ECER.Tests/Integration/RegistryPortalWebAppScenarioBase.cs +++ b/src/ECER.Tests/Integration/RegistryPortalWebAppScenarioBase.cs @@ -16,25 +16,25 @@ public class WebAppScenarioCollectionFixture : ICollectionFixture (RegistryPortalWebAppFixture)base.Fixture; + protected new RegistryPortalWebAppFixture Fixture => (RegistryPortalWebAppFixture)base.Fixture; - protected RegistryPortalWebAppScenarioBase(ITestOutputHelper output, RegistryPortalWebAppFixture fixture) : base(output, fixture) - { - } + protected RegistryPortalWebAppScenarioBase(ITestOutputHelper output, RegistryPortalWebAppFixture fixture) : base(output, fixture) + { + } } public class RegistryPortalWebAppFixture : WebAppFixtureBase { - private IServiceScope serviceScope = null!; - private Contact authenticatedBcscUser = null!; + private IServiceScope serviceScope = null!; + private Contact authenticatedBcscUser = null!; - private ecer_Application inProgressTestApplication = null!; - private ecer_Application draftTestApplication = null!; + private ecer_Application inProgressTestApplication = null!; + private ecer_Application draftTestApplication = null!; - private ecer_Communication testCommunication1 = null!; - private ecer_Communication testCommunication2 = null!; - private ecer_Communication testCommunication3 = null!; - private ecer_Communication testCommunication4 = null!; + private ecer_Communication testCommunication1 = null!; + private ecer_Communication testCommunication2 = null!; + private ecer_Communication testCommunication3 = null!; + private ecer_Communication testCommunication4 = null!; private ecer_Certificate testCertification = null!; @@ -46,18 +46,18 @@ public class RegistryPortalWebAppFixture : WebAppFixtureBase private ecer_PortalInvitation testPortalInvitationWorkExperienceReferenceCompleted = null!; private Contact authenticatedBcscUser2 = null!; - private ecer_PreviousName previousName = null!; + private ecer_PreviousName previousName = null!; - public IServiceProvider Services => serviceScope.ServiceProvider; - public UserIdentity AuthenticatedBcscUserIdentity => authenticatedBcscUser.ecer_contact_ecer_authentication_455.Select(a => new UserIdentity(a.ecer_ExternalID, a.ecer_IdentityProvider)).First(); - public string AuthenticatedBcscUserId => authenticatedBcscUser.Id.ToString(); + public IServiceProvider Services => serviceScope.ServiceProvider; + public UserIdentity AuthenticatedBcscUserIdentity => authenticatedBcscUser.ecer_contact_ecer_authentication_455.Select(a => new UserIdentity(a.ecer_ExternalID, a.ecer_IdentityProvider)).First(); + public string AuthenticatedBcscUserId => authenticatedBcscUser.Id.ToString(); - public string communicationOneId => testCommunication1.Id.ToString(); - public string communicationTwoId => testCommunication2.Id.ToString(); - public string communicationThreeId => testCommunication3.Id.ToString(); - public string communicationFourId => testCommunication4.Id.ToString(); - public string inProgressApplicationId => inProgressTestApplication.Id.ToString(); - public string draftTestApplicationId => draftTestApplication.Id.ToString(); + public string communicationOneId => testCommunication1.Id.ToString(); + public string communicationTwoId => testCommunication2.Id.ToString(); + public string communicationThreeId => testCommunication3.Id.ToString(); + public string communicationFourId => testCommunication4.Id.ToString(); + public string inProgressApplicationId => inProgressTestApplication.Id.ToString(); + public string draftTestApplicationId => draftTestApplication.Id.ToString(); public string certificationOneId => testCertification.Id.ToString(); @@ -89,111 +89,111 @@ public class RegistryPortalWebAppFixture : WebAppFixtureBase public string submittedTestApplicationWorkExperienceRefId => submittedTestApplicationWorkExperienceRef.Id.ToString(); public string submittedTestApplicationWorkExperienceRefId2 => submittedTestApplicationWorkExperienceRef2.Id.ToString(); - public string submittedTestApplicationCharacterRefId => submittedTestApplicationCharacterRef.Id.ToString(); + public string submittedTestApplicationCharacterRefId => submittedTestApplicationCharacterRef.Id.ToString(); - protected override void AddAuthorizationOptions(AuthorizationOptions opts) - { - ArgumentNullException.ThrowIfNull(opts); - opts.AddPolicy("registry_user", new AuthorizationPolicyBuilder(opts.GetPolicy("registry_user")!).AddAuthenticationSchemes(JwtBearerDefaults.AuthenticationScheme).Build()); - opts.AddPolicy("registry_new_user", new AuthorizationPolicyBuilder(opts.GetPolicy("registry_new_user")!).AddAuthenticationSchemes(JwtBearerDefaults.AuthenticationScheme).Build()); - opts.DefaultPolicy = opts.GetPolicy("registry_user")!; - } + protected override void AddAuthorizationOptions(AuthorizationOptions opts) + { + ArgumentNullException.ThrowIfNull(opts); + opts.AddPolicy("registry_user", new AuthorizationPolicyBuilder(opts.GetPolicy("registry_user")!).AddAuthenticationSchemes(JwtBearerDefaults.AuthenticationScheme).Build()); + opts.AddPolicy("registry_new_user", new AuthorizationPolicyBuilder(opts.GetPolicy("registry_new_user")!).AddAuthenticationSchemes(JwtBearerDefaults.AuthenticationScheme).Build()); + opts.DefaultPolicy = opts.GetPolicy("registry_user")!; + } - public override async Task InitializeAsync() - { - Host = await CreateHost(); - serviceScope = Host.Services.CreateScope(); - var context = serviceScope.ServiceProvider.GetRequiredService(); - await InitializeDataverseTestData(context); - } + public override async Task InitializeAsync() + { + Host = await CreateHost(); + serviceScope = Host.Services.CreateScope(); + var context = serviceScope.ServiceProvider.GetRequiredService(); + await InitializeDataverseTestData(context); + } - public override async Task DisposeAsync() - { - await Task.CompletedTask; - serviceScope.Dispose(); - } + public override async Task DisposeAsync() + { + await Task.CompletedTask; + serviceScope.Dispose(); + } - private async Task InitializeDataverseTestData(EcerContext context) - { - await Task.CompletedTask; - - authenticatedBcscUser = GetOrAddApplicant(context, "bcsc", $"{TestRunId}_user1"); - - inProgressTestApplication = GetOrAddApplication(context, authenticatedBcscUser, ecer_Application_StatusCode.InProgress); - inProgressTestApplication2 = GetOrAddApplication(context, authenticatedBcscUser, ecer_Application_StatusCode.InProgress); - draftTestApplication = GetOrAddApplication(context, authenticatedBcscUser, ecer_Application_StatusCode.Draft); - draftTestApplication2 = GetOrAddApplication(context, authenticatedBcscUser, ecer_Application_StatusCode.Draft); - draftTestApplication3 = GetOrAddApplication(context, authenticatedBcscUser, ecer_Application_StatusCode.Draft); - submittedTestApplication = GetOrAddApplication(context, authenticatedBcscUser, ecer_Application_StatusCode.Submitted); - submittedTestApplication2 = GetOrAddApplication(context, authenticatedBcscUser, ecer_Application_StatusCode.Submitted); - submittedTestApplication3 = GetOrAddApplication(context, authenticatedBcscUser, ecer_Application_StatusCode.Submitted); - submittedTestApplication4 = GetOrAddApplication(context, authenticatedBcscUser, ecer_Application_StatusCode.Submitted); - submittedTestApplicationWorkExperienceRef = AddWorkExperienceReferenceToApplication(context, submittedTestApplication); - submittedTestApplicationWorkExperienceRef2 = AddWorkExperienceReferenceToApplication(context, submittedTestApplication2); - submittedTestApplicationCharacterRef = AddCharacterReferenceToApplication(context, submittedTestApplication3); - testCommunication1 = GetOrAddCommunication(context, inProgressTestApplication, "comm1", null); - testCommunication2 = GetOrAddCommunication(context, inProgressTestApplication, "comm2", null); - testCommunication3 = GetOrAddCommunication(context, inProgressTestApplication, "comm3", null); - testCommunication4 = GetOrAddCommunication(context, inProgressTestApplication, "comm4", null); - testCertification = GetOrAddCertification(context); - previousName = GetOrAddPreviousName(context, authenticatedBcscUser); - testPortalInvitationOne = GetOrAddPortalInvitation_CharacterReference(context, authenticatedBcscUser, "name1"); - testPortalInvitationCharacterReferenceSubmit = GetOrAddPortalInvitation_CharacterReference(context, authenticatedBcscUser, "name2"); - testPortalInvitationWorkExperienceReferenceSubmit = GetOrAddPortalInvitation_WorkExperienceReference(context, authenticatedBcscUser, "name3"); - testPortalInvitationCharacterReferenceOptout = GetOrAddPortalInvitation_CharacterReference(context, authenticatedBcscUser, "name4"); - testPortalInvitationWorkExperienceReferenceOptout = GetOrAddPortalInvitation_WorkExperienceReference(context, authenticatedBcscUser, "name5"); - testPortalInvitationWorkExperienceReferenceCompleted = GetOrAddPortalInvitation_WorkExperienceReference(context, authenticatedBcscUser, "name6"); - - context.SaveChanges(); - - CompletePortalInvitation_WorkExperienceReference(context, "name6"); - - //load dependent properties - context.Attach(authenticatedBcscUser); - context.LoadProperty(authenticatedBcscUser, Contact.Fields.ecer_contact_ecer_authentication_455); - - //load user 2 - authenticatedBcscUser2 = GetOrAddApplicant(context, "bcsc", $"{TestRunId}_user2"); - inProgressTestApplication2 = GetOrAddApplication(context, authenticatedBcscUser2, ecer_Application_StatusCode.InProgress); - draftTestApplication2 = GetOrAddApplication(context, authenticatedBcscUser2, ecer_Application_StatusCode.Draft); - - context.SaveChanges(); - - //load dependent properties - context.Attach(authenticatedBcscUser2); - context.LoadProperty(authenticatedBcscUser2, Contact.Fields.ecer_contact_ecer_authentication_455); - } + private async Task InitializeDataverseTestData(EcerContext context) + { + await Task.CompletedTask; + + authenticatedBcscUser = GetOrAddApplicant(context, "bcsc", $"{TestRunId}_user1"); + + inProgressTestApplication = GetOrAddApplication(context, authenticatedBcscUser, ecer_Application_StatusCode.InProgress); + inProgressTestApplication2 = GetOrAddApplication(context, authenticatedBcscUser, ecer_Application_StatusCode.InProgress); + draftTestApplication = GetOrAddApplication(context, authenticatedBcscUser, ecer_Application_StatusCode.Draft); + draftTestApplication2 = GetOrAddApplication(context, authenticatedBcscUser, ecer_Application_StatusCode.Draft); + draftTestApplication3 = GetOrAddApplication(context, authenticatedBcscUser, ecer_Application_StatusCode.Draft); + submittedTestApplication = GetOrAddApplication(context, authenticatedBcscUser, ecer_Application_StatusCode.Submitted); + submittedTestApplication2 = GetOrAddApplication(context, authenticatedBcscUser, ecer_Application_StatusCode.Submitted); + submittedTestApplication3 = GetOrAddApplication(context, authenticatedBcscUser, ecer_Application_StatusCode.Submitted); + submittedTestApplication4 = GetOrAddApplication(context, authenticatedBcscUser, ecer_Application_StatusCode.Submitted); + submittedTestApplicationWorkExperienceRef = AddWorkExperienceReferenceToApplication(context, submittedTestApplication); + submittedTestApplicationWorkExperienceRef2 = AddWorkExperienceReferenceToApplication(context, submittedTestApplication2); + submittedTestApplicationCharacterRef = AddCharacterReferenceToApplication(context, submittedTestApplication3); + testCommunication1 = GetOrAddCommunication(context, inProgressTestApplication, "comm1", null); + testCommunication2 = GetOrAddCommunication(context, inProgressTestApplication, "comm2", null); + testCommunication3 = GetOrAddCommunication(context, inProgressTestApplication, "comm3", null); + testCommunication4 = GetOrAddCommunication(context, inProgressTestApplication, "comm4", null); + testCertification = GetOrAddCertification(context); + previousName = GetOrAddPreviousName(context, authenticatedBcscUser); + testPortalInvitationOne = GetOrAddPortalInvitation_CharacterReference(context, authenticatedBcscUser, "name1"); + testPortalInvitationCharacterReferenceSubmit = GetOrAddPortalInvitation_CharacterReference(context, authenticatedBcscUser, "name2"); + testPortalInvitationWorkExperienceReferenceSubmit = GetOrAddPortalInvitation_WorkExperienceReference(context, authenticatedBcscUser, "name3"); + testPortalInvitationCharacterReferenceOptout = GetOrAddPortalInvitation_CharacterReference(context, authenticatedBcscUser, "name4"); + testPortalInvitationWorkExperienceReferenceOptout = GetOrAddPortalInvitation_WorkExperienceReference(context, authenticatedBcscUser, "name5"); + testPortalInvitationWorkExperienceReferenceCompleted = GetOrAddPortalInvitation_WorkExperienceReference(context, authenticatedBcscUser, "name6"); + + context.SaveChanges(); + + CompletePortalInvitation_WorkExperienceReference(context, "name6"); + + //load dependent properties + context.Attach(authenticatedBcscUser); + context.LoadProperty(authenticatedBcscUser, Contact.Fields.ecer_contact_ecer_authentication_455); + + //load user 2 + authenticatedBcscUser2 = GetOrAddApplicant(context, "bcsc", $"{TestRunId}_user2"); + inProgressTestApplication2 = GetOrAddApplication(context, authenticatedBcscUser2, ecer_Application_StatusCode.InProgress); + draftTestApplication2 = GetOrAddApplication(context, authenticatedBcscUser2, ecer_Application_StatusCode.Draft); + + context.SaveChanges(); + + //load dependent properties + context.Attach(authenticatedBcscUser2); + context.LoadProperty(authenticatedBcscUser2, Contact.Fields.ecer_contact_ecer_authentication_455); + } + + private Contact GetOrAddApplicant(EcerContext context, string identityProvider, string userId) + { + var contact = (from a in context.ecer_AuthenticationSet + join c in context.ContactSet on a.ecer_contact_ecer_authentication_455.ContactId equals c.ContactId into contacts + from c in contacts.DefaultIfEmpty() + where a.ecer_IdentityProvider == identityProvider && a.ecer_ExternalID == userId + select c).SingleOrDefault(); - private Contact GetOrAddApplicant(EcerContext context, string identityProvider, string userId) + if (contact == null) { - var contact = (from a in context.ecer_AuthenticationSet - join c in context.ContactSet on a.ecer_contact_ecer_authentication_455.ContactId equals c.ContactId into contacts - from c in contacts.DefaultIfEmpty() - where a.ecer_IdentityProvider == identityProvider && a.ecer_ExternalID == userId - select c).SingleOrDefault(); + contact = new Contact + { + FirstName = "test1", + LastName = "test1", + BirthDate = DateTime.Parse("2000-03-15", CultureInfo.InvariantCulture), + }; - if (contact == null) - { - contact = new Contact - { - FirstName = "test1", - LastName = "test1", - BirthDate = DateTime.Parse("2000-03-15", CultureInfo.InvariantCulture), - }; - - var authentication = new ecer_Authentication - { - ecer_IdentityProvider = identityProvider, - ecer_ExternalID = userId - }; - context.AddObject(authentication); - context.AddObject(contact); - context.AddLink(authentication, ecer_Authentication.Fields.ecer_contact_ecer_authentication_455, contact); - } - - return contact; + var authentication = new ecer_Authentication + { + ecer_IdentityProvider = identityProvider, + ecer_ExternalID = userId + }; + context.AddObject(authentication); + context.AddObject(contact); + context.AddLink(authentication, ecer_Authentication.Fields.ecer_contact_ecer_authentication_455, contact); } + return contact; + } + private ecer_PreviousName GetOrAddPreviousName(EcerContext context, Contact applicant) { var previousName = (from p in context.ecer_PreviousNameSet @@ -218,111 +218,111 @@ private ecer_PreviousName GetOrAddPreviousName(EcerContext context, Contact appl return previousName; } - private ecer_Application GetOrAddApplication(EcerContext context, Contact applicant, ecer_Application_StatusCode status) - { - var application = (from a in context.ecer_ApplicationSet - where a.ecer_Applicantid.Id == applicant.Id && a.ecer_isECE5YR == true && a.StatusCode == status - select a).FirstOrDefault(); - - if (application == null) - { - application = new ecer_Application - { - Id = Guid.NewGuid(), - ecer_isECE5YR = true, - StatusCode = status, - StateCode = ecer_application_statecode.Active, - ecer_CertificateType = "ECE 5 YR", - }; - context.AddObject(application); - context.AddLink(application, ecer_Application.Fields.ecer_application_Applicantid_contact, applicant); - } - return application; - } + private ecer_Application GetOrAddApplication(EcerContext context, Contact applicant, ecer_Application_StatusCode status) + { + var application = (from a in context.ecer_ApplicationSet + where a.ecer_Applicantid.Id == applicant.Id && a.ecer_isECE5YR == true && a.StatusCode == status + select a).FirstOrDefault(); - private ecer_WorkExperienceRef AddWorkExperienceReferenceToApplication(EcerContext context, ecer_Application application) + if (application == null) { - var wpGuid = Guid.NewGuid(); - - var workexperienceReference = new ecer_WorkExperienceRef - { - Id = wpGuid, - ecer_WorkExperienceRefId = wpGuid, - ecer_Name = "Test name", - ecer_FirstName = "Test firstname", - ecer_LastName = "Test lastname", - ecer_EmailAddress = "Work_Experience_Reference@example.com", - ecer_PhoneNumber = "9999999999", - ecer_StartDate = DateTime.Now, - ecer_EndDate = DateTime.Now, - }; - - context.AddObject(workexperienceReference); - context.AddLink(workexperienceReference, ecer_WorkExperienceRef.Fields.ecer_workexperienceref_Applicationid_ecer, application); - - return workexperienceReference; + application = new ecer_Application + { + Id = Guid.NewGuid(), + ecer_isECE5YR = true, + StatusCode = status, + StateCode = ecer_application_statecode.Active, + ecer_CertificateType = "ECE 5 YR", + }; + context.AddObject(application); + context.AddLink(application, ecer_Application.Fields.ecer_application_Applicantid_contact, applicant); } + return application; + } + + private ecer_WorkExperienceRef AddWorkExperienceReferenceToApplication(EcerContext context, ecer_Application application) + { + var wpGuid = Guid.NewGuid(); - private ecer_CharacterReference AddCharacterReferenceToApplication(EcerContext context, ecer_Application application) + var workexperienceReference = new ecer_WorkExperienceRef { - var wpGuid = Guid.NewGuid(); + Id = wpGuid, + ecer_WorkExperienceRefId = wpGuid, + ecer_Name = "Test name", + ecer_FirstName = "Test firstname", + ecer_LastName = "Test lastname", + ecer_EmailAddress = "Work_Experience_Reference@example.com", + ecer_PhoneNumber = "9999999999", + ecer_StartDate = DateTime.Now, + ecer_EndDate = DateTime.Now, + }; + + context.AddObject(workexperienceReference); + context.AddLink(workexperienceReference, ecer_WorkExperienceRef.Fields.ecer_workexperienceref_Applicationid_ecer, application); + + return workexperienceReference; + } - var characterReference = new ecer_CharacterReference - { - Id = wpGuid, - ecer_CharacterReferenceId = wpGuid, - ecer_Name = "Test name", - ecer_FirstName = "Test firstname", - ecer_LastName = "Test lastname", - ecer_EmailAddress = "Character_Reference@example.com", - ecer_PhoneNumber = "9999999999" - }; + private ecer_CharacterReference AddCharacterReferenceToApplication(EcerContext context, ecer_Application application) + { + var wpGuid = Guid.NewGuid(); - context.AddObject(characterReference); - context.AddLink(characterReference, ecer_CharacterReference.Fields.ecer_characterreference_Applicationid, application); + var characterReference = new ecer_CharacterReference + { + Id = wpGuid, + ecer_CharacterReferenceId = wpGuid, + ecer_Name = "Test name", + ecer_FirstName = "Test firstname", + ecer_LastName = "Test lastname", + ecer_EmailAddress = "Character_Reference@example.com", + ecer_PhoneNumber = "9999999999" + }; + + context.AddObject(characterReference); + context.AddLink(characterReference, ecer_CharacterReference.Fields.ecer_characterreference_Applicationid, application); + + return characterReference; + } - return characterReference; - } + private ecer_Communication GetOrAddCommunication(EcerContext context, ecer_Application application, string message, Guid? parentCommunicationId) + { + var communication = context.ecer_CommunicationSet.FirstOrDefault(c => c.ecer_Applicationid.Id == application.Id && c.ecer_Registrantid.Id == authenticatedBcscUser.Id && c.ecer_Message == message && c.StatusCode == ecer_Communication_StatusCode.NotifiedRecipient); - private ecer_Communication GetOrAddCommunication(EcerContext context, ecer_Application application, string message, Guid? parentCommunicationId) + if (communication == null) { - var communication = context.ecer_CommunicationSet.FirstOrDefault(c => c.ecer_Applicationid.Id == application.Id && c.ecer_Registrantid.Id == authenticatedBcscUser.Id && c.ecer_Message == message && c.StatusCode == ecer_Communication_StatusCode.NotifiedRecipient); + communication = new ecer_Communication + { + Id = Guid.NewGuid(), + ecer_Message = message, + ecer_Acknowledged = false, + StatusCode = ecer_Communication_StatusCode.NotifiedRecipient, + }; + if (parentCommunicationId == null) + { + communication.ecer_IsRoot = true; + } + context.AddObject(communication); - if (communication == null) + if (parentCommunicationId != null) + { + var parent = context.ecer_CommunicationSet.SingleOrDefault(d => d.ecer_CommunicationId == parentCommunicationId); + var Referencingecer_communication_ParentCommunicationid = new Relationship(ecer_Communication.Fields.Referencingecer_communication_ParentCommunicationid) { - communication = new ecer_Communication - { - Id = Guid.NewGuid(), - ecer_Message = message, - ecer_Acknowledged = false, - StatusCode = ecer_Communication_StatusCode.NotifiedRecipient, - }; - if (parentCommunicationId == null) - { - communication.ecer_IsRoot = true; - } - context.AddObject(communication); - - if (parentCommunicationId != null) - { - var parent = context.ecer_CommunicationSet.SingleOrDefault(d => d.ecer_CommunicationId == parentCommunicationId); - var Referencingecer_communication_ParentCommunicationid = new Relationship(ecer_Communication.Fields.Referencingecer_communication_ParentCommunicationid) - { - PrimaryEntityRole = EntityRole.Referencing - }; - context.AddLink(communication, Referencingecer_communication_ParentCommunicationid, parent); - } - context.AddLink(communication, ecer_Communication.Fields.ecer_communication_Applicationid, inProgressTestApplication); + PrimaryEntityRole = EntityRole.Referencing + }; + context.AddLink(communication, Referencingecer_communication_ParentCommunicationid, parent); + } + context.AddLink(communication, ecer_Communication.Fields.ecer_communication_Applicationid, inProgressTestApplication); #pragma warning disable S125 // Sections of code should not be commented out - // Adding this statement causes duplicate key issue for all tests "Cannot insert duplicate key" - //context.AddLink(authenticatedBcscUser, ecer_Communication.Fields.ecer_contact_ecer_communication_122, communication); + // Adding this statement causes duplicate key issue for all tests "Cannot insert duplicate key" + //context.AddLink(authenticatedBcscUser, ecer_Communication.Fields.ecer_contact_ecer_communication_122, communication); #pragma warning restore S125 // Sections of code should not be commented out - } - - return communication; } + return communication; + } + private ecer_Certificate GetOrAddCertification(EcerContext context) { var certification = context.ecer_CertificateSet.FirstOrDefault(c => c.ecer_CertificateNumber == "123456"); @@ -361,102 +361,102 @@ private ecer_PortalInvitation GetOrAddPortalInvitation_CharacterReference(EcerCo p.ecer_CharacterReferenceId != null && p.StatusCode == ecer_PortalInvitation_StatusCode.Sent); - if (portalInvitation == null) - { - var charGuid = Guid.NewGuid(); - - var characterReference = new ecer_CharacterReference - { - Id = charGuid, - ecer_CharacterReferenceId = charGuid, - ecer_Name = "Reference Test name", - ecer_FirstName = "Reference Test firstname", - ecer_LastName = "Reference Test lastname", - ecer_EmailAddress = "reference_test@example.com" - }; - - var guid = Guid.NewGuid(); - portalInvitation = new ecer_PortalInvitation - { - Id = guid, - ecer_PortalInvitationId = guid, - ecer_Name = name, - ecer_FirstName = "Test firstname", - ecer_LastName = "Test lastname", - ecer_EmailAddress = "test@example.com", - StatusCode = ecer_PortalInvitation_StatusCode.Sent, - }; - - context.AddObject(characterReference); - context.AddObject(portalInvitation); - context.AddLink(portalInvitation, ecer_PortalInvitation.Fields.ecer_portalinvitation_CharacterReferenceId, characterReference); - context.AddLink(portalInvitation, ecer_PortalInvitation.Fields.ecer_portalinvitation_ApplicantId, registrant); - context.AddLink(portalInvitation, ecer_PortalInvitation.Fields.ecer_portalinvitation_ApplicationId, inProgressTestApplication); - } - - return portalInvitation; + if (portalInvitation == null) + { + var charGuid = Guid.NewGuid(); + + var characterReference = new ecer_CharacterReference + { + Id = charGuid, + ecer_CharacterReferenceId = charGuid, + ecer_Name = "Reference Test name", + ecer_FirstName = "Reference Test firstname", + ecer_LastName = "Reference Test lastname", + ecer_EmailAddress = "reference_test@example.com" + }; + + var guid = Guid.NewGuid(); + portalInvitation = new ecer_PortalInvitation + { + Id = guid, + ecer_PortalInvitationId = guid, + ecer_Name = name, + ecer_FirstName = "Test firstname", + ecer_LastName = "Test lastname", + ecer_EmailAddress = "test@example.com", + StatusCode = ecer_PortalInvitation_StatusCode.Sent, + }; + + context.AddObject(characterReference); + context.AddObject(portalInvitation); + context.AddLink(portalInvitation, ecer_PortalInvitation.Fields.ecer_portalinvitation_CharacterReferenceId, characterReference); + context.AddLink(portalInvitation, ecer_PortalInvitation.Fields.ecer_portalinvitation_ApplicantId, registrant); + context.AddLink(portalInvitation, ecer_PortalInvitation.Fields.ecer_portalinvitation_ApplicationId, inProgressTestApplication); } - private void CompletePortalInvitation_WorkExperienceReference(EcerContext context, string name) - { - var portalInvitations = context.ecer_PortalInvitationSet - .Where(p => p.ecer_ApplicantId != null && - p.ecer_ApplicationId != null && - p.ecer_Name == name && - p.ecer_WorkExperienceReferenceId != null) - .ToList(); - - foreach (var portalInvitation in portalInvitations) - { - portalInvitation.StateCode = ecer_portalinvitation_statecode.Inactive; - portalInvitation.StatusCode = ecer_PortalInvitation_StatusCode.Completed; - context.UpdateObject(portalInvitation); - } + return portalInvitation; + } - context.SaveChanges(); + private void CompletePortalInvitation_WorkExperienceReference(EcerContext context, string name) + { + var portalInvitations = context.ecer_PortalInvitationSet + .Where(p => p.ecer_ApplicantId != null && + p.ecer_ApplicationId != null && + p.ecer_Name == name && + p.ecer_WorkExperienceReferenceId != null) + .ToList(); + + foreach (var portalInvitation in portalInvitations) + { + portalInvitation.StateCode = ecer_portalinvitation_statecode.Inactive; + portalInvitation.StatusCode = ecer_PortalInvitation_StatusCode.Completed; + context.UpdateObject(portalInvitation); } - private ecer_PortalInvitation GetOrAddPortalInvitation_WorkExperienceReference(EcerContext context, Contact registrant, string name) + context.SaveChanges(); + } + + private ecer_PortalInvitation GetOrAddPortalInvitation_WorkExperienceReference(EcerContext context, Contact registrant, string name) + { + var portalInvitation = context.ecer_PortalInvitationSet.FirstOrDefault(p => p.ecer_ApplicantId != null && + p.ecer_ApplicationId != null && + p.ecer_Name == name && + p.ecer_WorkExperienceReferenceId != null && + p.StatusCode == ecer_PortalInvitation_StatusCode.Sent); + + if (portalInvitation == null) { - var portalInvitation = context.ecer_PortalInvitationSet.FirstOrDefault(p => p.ecer_ApplicantId != null && - p.ecer_ApplicationId != null && - p.ecer_Name == name && - p.ecer_WorkExperienceReferenceId != null && - p.StatusCode == ecer_PortalInvitation_StatusCode.Sent); + var wpGuid = Guid.NewGuid(); - if (portalInvitation == null) - { - var wpGuid = Guid.NewGuid(); - - var workexperienceReference = new ecer_WorkExperienceRef - { - Id = wpGuid, - ecer_WorkExperienceRefId = wpGuid, - ecer_Name = "Reference Test name", - ecer_FirstName = "Reference Test firstname", - ecer_LastName = "Reference Test lastname", - ecer_EmailAddress = "reference_test@example.com", - }; - - var guid = Guid.NewGuid(); - portalInvitation = new ecer_PortalInvitation - { - Id = guid, - ecer_PortalInvitationId = guid, - ecer_Name = name, - ecer_FirstName = "Test firstname", - ecer_LastName = "Test lastname", - ecer_EmailAddress = "test@example.com", - StatusCode = ecer_PortalInvitation_StatusCode.Sent, - }; - - context.AddObject(workexperienceReference); - context.AddObject(portalInvitation); - context.AddLink(portalInvitation, ecer_PortalInvitation.Fields.ecer_portalinvitation_ApplicantId, registrant); - context.AddLink(portalInvitation, ecer_PortalInvitation.Fields.ecer_portalinvitation_ApplicationId, inProgressTestApplication); - context.AddLink(portalInvitation, ecer_PortalInvitation.Fields.ecer_portalinvitation_WorkExperienceRefId, workexperienceReference); - } - - return portalInvitation; + var workexperienceReference = new ecer_WorkExperienceRef + { + Id = wpGuid, + ecer_WorkExperienceRefId = wpGuid, + ecer_Name = "Reference Test name", + ecer_FirstName = "Reference Test firstname", + ecer_LastName = "Reference Test lastname", + ecer_EmailAddress = "reference_test@example.com", + }; + + var guid = Guid.NewGuid(); + portalInvitation = new ecer_PortalInvitation + { + Id = guid, + ecer_PortalInvitationId = guid, + ecer_Name = name, + ecer_FirstName = "Test firstname", + ecer_LastName = "Test lastname", + ecer_EmailAddress = "test@example.com", + StatusCode = ecer_PortalInvitation_StatusCode.Sent, + }; + + context.AddObject(workexperienceReference); + context.AddObject(portalInvitation); + context.AddLink(portalInvitation, ecer_PortalInvitation.Fields.ecer_portalinvitation_ApplicantId, registrant); + context.AddLink(portalInvitation, ecer_PortalInvitation.Fields.ecer_portalinvitation_ApplicationId, inProgressTestApplication); + context.AddLink(portalInvitation, ecer_PortalInvitation.Fields.ecer_portalinvitation_WorkExperienceRefId, workexperienceReference); } + + return portalInvitation; + } } diff --git a/src/ECER.Tests/Integration/Resources/Accounts/Communications/CommunicationRepositoryTests.cs b/src/ECER.Tests/Integration/Resources/Accounts/Communications/CommunicationRepositoryTests.cs index 62c7d2cb3..b34e7402a 100644 --- a/src/ECER.Tests/Integration/Resources/Accounts/Communications/CommunicationRepositoryTests.cs +++ b/src/ECER.Tests/Integration/Resources/Accounts/Communications/CommunicationRepositoryTests.cs @@ -1,5 +1,4 @@ -using ECER.Managers.Registry.Contract.Communications; -using ECER.Resources.Accounts.Communications; +using ECER.Resources.Accounts.Communications; using Microsoft.Extensions.DependencyInjection; using Shouldly; using Xunit.Abstractions; diff --git a/src/ECER.Tests/Unit/ApplicationRenewalValidationEngineTests.cs b/src/ECER.Tests/Unit/ApplicationRenewalValidationEngineTests.cs new file mode 100644 index 000000000..ed8c11116 --- /dev/null +++ b/src/ECER.Tests/Unit/ApplicationRenewalValidationEngineTests.cs @@ -0,0 +1,133 @@ +using Bogus; +using ECER.Engines.Validation.Applications; +using ECER.Managers.Registry.Contract.Applications; +using ECER.Resources.Documents.Certifications; +using Moq; + +namespace ECER.Tests.Unit; + +public class ApplicationRenewalValidationEngineTests +{ + private readonly ApplicationRenewalValidationEngine _validator; + private readonly Mock _certificationRepositoryMock; + private readonly Faker _faker; + + public ApplicationRenewalValidationEngineTests() + { + _certificationRepositoryMock = new Mock(); + _validator = new ApplicationRenewalValidationEngine(_certificationRepositoryMock.Object); + _faker = new Faker("en_CA"); + } + + [Fact] + public async Task Validate_OneYearRenewalWithActiveCertificate_ReturnsNoValidationError() + { + // Arrange + var application = new Application("id", "registrantId", ApplicationStatus.Draft) + { + CertificationTypes = new List { CertificationType.OneYear }, + ExplanationLetter = "This is an explanation letter", + CharacterReferences = new List { CreateMockCharacterReference() } + }; + + _certificationRepositoryMock + .Setup(repo => repo.Query(It.IsAny())) + .ReturnsAsync(new List { + CreateMockCertification(DateTime.Now.AddYears(1), CertificateStatusCode.Active) // Certification is active + }); + + // Act + var result = await _validator.Validate(application); + + // Assert + Assert.Empty(result.ValidationErrors); + } + + [Fact] + public async Task Validate_OneYearRenewalWithActiveCertificateWithoutExplanationLetter_ReturnsExplanationLetterError() + { + // Arrange + var application = new Application("id", "registrantId", ApplicationStatus.Draft) + { + CertificationTypes = new List { CertificationType.OneYear }, + ExplanationLetter = null, // No explanation letter + CharacterReferences = new List { CreateMockCharacterReference() } + }; + + _certificationRepositoryMock + .Setup(repo => repo.Query(It.IsAny())) + .ReturnsAsync(new List { + CreateMockCertification(DateTime.Now.AddYears(1), CertificateStatusCode.Active) // Certification is active + }); + + // Act + var result = await _validator.Validate(application); + + // Assert + Assert.Contains("the application does not have explanation letter", result.ValidationErrors); + } + + [Fact] + public async Task Validate_OneYearRenewalWithActiveCertificateWithoutCharacterReferences_ReturnsCharacterReferenceError() + { + // Arrange + var application = new Application("id", "registrantId", ApplicationStatus.Draft) + { + CertificationTypes = new List { CertificationType.OneYear }, + ExplanationLetter = "This is an explanation letter", + CharacterReferences = new List() // No character references + }; + + _certificationRepositoryMock + .Setup(repo => repo.Query(It.IsAny())) + .ReturnsAsync(new List { + CreateMockCertification(DateTime.Now.AddYears(1), CertificateStatusCode.Active) // Certification is active + }); + + // Act + var result = await _validator.Validate(application); + + // Assert + Assert.Contains("the application does not have any character references", result.ValidationErrors); + } + + private Certification CreateMockCertification(DateTime expiryDate, CertificateStatusCode statusCode) + { + return new Certification(_faker.Random.Guid().ToString()) + { + ExpiryDate = expiryDate, + StatusCode = statusCode, + Number = _faker.Random.String(10), + EffectiveDate = expiryDate.AddYears(-1), + Date = expiryDate.AddYears(-1), + PrintDate = expiryDate.AddMonths(-1), + HasConditions = _faker.Random.Bool(), + LevelName = _faker.Company.CompanyName(), + IneligibleReference = _faker.Random.Enum(), + Levels = new List + { + new CertificationLevel(_faker.Random.Guid().ToString()) { Type = _faker.Random.Word() } + }, + Files = new List + { + new CertificationFile(_faker.Random.Guid().ToString()) + { + Url = _faker.Internet.Url(), + Extention = _faker.System.FileExt(), + Size = _faker.Random.Number(1000, 10000).ToString(), + Name = _faker.System.FileName() + } + } + }; + } + + private CharacterReference CreateMockCharacterReference() + { + return new CharacterReference( + _faker.Name.FirstName(), + _faker.Name.LastName(), + _faker.Internet.Email(), + _faker.Phone.PhoneNumber() + ); + } +} diff --git a/src/ECER.Tests/Unit/ApplicationSubmissionValidationEngineTests.cs b/src/ECER.Tests/Unit/ApplicationSubmissionValidationEngineTests.cs index 3f24bf2ab..902e60d4f 100644 --- a/src/ECER.Tests/Unit/ApplicationSubmissionValidationEngineTests.cs +++ b/src/ECER.Tests/Unit/ApplicationSubmissionValidationEngineTests.cs @@ -2,175 +2,174 @@ using ECER.Engines.Validation.Applications; using ECER.Managers.Registry.Contract.Applications; -namespace ECER.Tests.Unit +namespace ECER.Tests.Unit; + +public class ApplicationSubmissionValidationEngineTests { - public class ApplicationSubmissionValidationEngineTests + private readonly ApplicationSubmissionValidationEngine _validator; + + public ApplicationSubmissionValidationEngineTests() { - private readonly ApplicationSubmissionValidationEngine _validator; + _validator = new ApplicationSubmissionValidationEngine(); + } - public ApplicationSubmissionValidationEngineTests() + [Fact] + public async Task Validate_WithoutEducation_ReturnsEducationError() + { + var application = new Application("id", "registrantId", ApplicationStatus.Draft) { - _validator = new ApplicationSubmissionValidationEngine(); - } + Transcripts = new List(), + CharacterReferences = new List { CreateMockCharacterReference() }, + CertificationTypes = new List { CertificationType.EceAssistant }, + WorkExperienceReferences = new List { CreateMockWorkExperienceReference(500) } + }; + + var result = await _validator.Validate(application); + Assert.Contains("the application does not have any education", result.ValidationErrors); + } - [Fact] - public async Task Validate_WithoutEducation_ReturnsEducationError() + [Fact] + public async Task Validate_WithoutCharacterReferences_ReturnsCharacterReferenceError() + { + var application = new Application("id", "registrantId", ApplicationStatus.Draft) { - var application = new Application("id", "registrantId", ApplicationStatus.Draft) - { - Transcripts = new List(), - CharacterReferences = new List { CreateMockCharacterReference() }, - CertificationTypes = new List { CertificationType.EceAssistant }, - WorkExperienceReferences = new List { CreateMockWorkExperienceReference(500) } - }; - - var result = await _validator.Validate(application); - Assert.Contains("the application does not have any education", result.ValidationErrors); - } + Transcripts = new List { CreateMockTranscript(false) }, + CharacterReferences = new List(), + CertificationTypes = new List { CertificationType.EceAssistant }, + WorkExperienceReferences = new List { CreateMockWorkExperienceReference(500) } + }; + + var result = await _validator.Validate(application); + Assert.Contains("the application does not have any character references", result.ValidationErrors); + } - [Fact] - public async Task Validate_WithoutCharacterReferences_ReturnsCharacterReferenceError() + [Fact] + public async Task Validate_WithOutdatedEceAssistantEducation_ReturnsOutdatedEducationError() + { + var application = new Application("id", "registrantId", ApplicationStatus.Draft) { - var application = new Application("id", "registrantId", ApplicationStatus.Draft) - { - Transcripts = new List { CreateMockTranscript(false) }, - CharacterReferences = new List(), - CertificationTypes = new List { CertificationType.EceAssistant }, - WorkExperienceReferences = new List { CreateMockWorkExperienceReference(500) } - }; - - var result = await _validator.Validate(application); - Assert.Contains("the application does not have any character references", result.ValidationErrors); - } + Transcripts = new List { CreateMockTranscript(true) }, + CharacterReferences = new List { CreateMockCharacterReference() }, + CertificationTypes = new List { CertificationType.EceAssistant }, + WorkExperienceReferences = new List { CreateMockWorkExperienceReference(500) } + }; + + var result = await _validator.Validate(application); + Assert.Contains("Education was completed more than 5 years ago", result.ValidationErrors); + } - [Fact] - public async Task Validate_WithOutdatedEceAssistantEducation_ReturnsOutdatedEducationError() + [Fact] + public async Task Validate_WithInadequateWorkExperienceForFiveYears_ReturnsWorkExperienceError() + { + var application = new Application("id", "registrantId", ApplicationStatus.Draft) { - var application = new Application("id", "registrantId", ApplicationStatus.Draft) - { - Transcripts = new List { CreateMockTranscript(true) }, - CharacterReferences = new List { CreateMockCharacterReference() }, - CertificationTypes = new List { CertificationType.EceAssistant }, - WorkExperienceReferences = new List { CreateMockWorkExperienceReference(500) } - }; - - var result = await _validator.Validate(application); - Assert.Contains("Education was completed more than 5 years ago", result.ValidationErrors); - } + Transcripts = new List { CreateMockTranscript(false) }, + CharacterReferences = new List { CreateMockCharacterReference() }, + CertificationTypes = new List { CertificationType.FiveYears }, + WorkExperienceReferences = new List { CreateMockWorkExperienceReference(499) } + }; + + var result = await _validator.Validate(application); + Assert.Contains("Work experience does not meet 500 hours", result.ValidationErrors); + } - [Fact] - public async Task Validate_WithInadequateWorkExperienceForFiveYears_ReturnsWorkExperienceError() + [Fact] + public async Task Validate_WithSneAndIteWithoutFiveYears_ReturnsCertificationError() + { + var application = new Application("id", "registrantId", ApplicationStatus.Draft) { - var application = new Application("id", "registrantId", ApplicationStatus.Draft) - { - Transcripts = new List { CreateMockTranscript(false) }, - CharacterReferences = new List { CreateMockCharacterReference() }, - CertificationTypes = new List { CertificationType.FiveYears }, - WorkExperienceReferences = new List { CreateMockWorkExperienceReference(499) } - }; - - var result = await _validator.Validate(application); - Assert.Contains("Work experience does not meet 500 hours", result.ValidationErrors); - } + Transcripts = new List { CreateMockTranscript(false) }, + CharacterReferences = new List { CreateMockCharacterReference() }, + CertificationTypes = new List { CertificationType.Sne, CertificationType.Ite }, + WorkExperienceReferences = new List { CreateMockWorkExperienceReference(500) } + }; + + var result = await _validator.Validate(application); + Assert.Contains("Sub five year certification type selected but without five year certification", result.ValidationErrors); + } - [Fact] - public async Task Validate_WithSneAndIteWithoutFiveYears_ReturnsCertificationError() + [Theory] + [InlineData(CertificationType.Ite)] + [InlineData(CertificationType.Sne)] + public async Task Validate_WithInsufficientEducationForIteOrSne_ReturnsEducationError(CertificationType certificationType) + { + var application = new Application("id", "registrantId", ApplicationStatus.Draft) { - var application = new Application("id", "registrantId", ApplicationStatus.Draft) - { - Transcripts = new List { CreateMockTranscript(false) }, - CharacterReferences = new List { CreateMockCharacterReference() }, - CertificationTypes = new List { CertificationType.Sne, CertificationType.Ite }, - WorkExperienceReferences = new List { CreateMockWorkExperienceReference(500) } - }; - - var result = await _validator.Validate(application); - Assert.Contains("Sub five year certification type selected but without five year certification", result.ValidationErrors); - } + Transcripts = new List { CreateMockTranscript(false) }, // Only one transcript + CharacterReferences = new List { CreateMockCharacterReference() }, + CertificationTypes = new List { certificationType }, + WorkExperienceReferences = new List { CreateMockWorkExperienceReference(500) } + }; + + var result = await _validator.Validate(application); + var expectedError = certificationType == CertificationType.Ite ? "applicant does not have enough education for ITE" : "applicant does not have enough education for SNE"; + Assert.Contains(expectedError, result.ValidationErrors); + } - [Theory] - [InlineData(CertificationType.Ite)] - [InlineData(CertificationType.Sne)] - public async Task Validate_WithInsufficientEducationForIteOrSne_ReturnsEducationError(CertificationType certificationType) + [Fact] + public async Task Validate_WithBothIteAndSneAndLessThanThreeEducations_ReturnsEducationError() + { + var application = new Application("id", "registrantId", ApplicationStatus.Draft) { - var application = new Application("id", "registrantId", ApplicationStatus.Draft) - { - Transcripts = new List { CreateMockTranscript(false) }, // Only one transcript - CharacterReferences = new List { CreateMockCharacterReference() }, - CertificationTypes = new List { certificationType }, - WorkExperienceReferences = new List { CreateMockWorkExperienceReference(500) } - }; - - var result = await _validator.Validate(application); - var expectedError = certificationType == CertificationType.Ite ? "applicant does not have enough education for ITE" : "applicant does not have enough education for SNE"; - Assert.Contains(expectedError, result.ValidationErrors); - } + Transcripts = new List { CreateMockTranscript(false), CreateMockTranscript(false) }, // Only two transcripts + CharacterReferences = new List { CreateMockCharacterReference() }, + CertificationTypes = new List { CertificationType.Ite, CertificationType.Sne }, + WorkExperienceReferences = new List { CreateMockWorkExperienceReference(500) } + }; + + var result = await _validator.Validate(application); + Assert.Contains("applicant does not have enough education for both ITE and SNE", result.ValidationErrors); + } - [Fact] - public async Task Validate_WithBothIteAndSneAndLessThanThreeEducations_ReturnsEducationError() + [Fact] + public async Task Validate_ValidApplication_ReturnsNoValidationError() + { + var application = new Application("id", "registrantId", ApplicationStatus.Draft) { - var application = new Application("id", "registrantId", ApplicationStatus.Draft) - { - Transcripts = new List { CreateMockTranscript(false), CreateMockTranscript(false) }, // Only two transcripts - CharacterReferences = new List { CreateMockCharacterReference() }, - CertificationTypes = new List { CertificationType.Ite, CertificationType.Sne }, - WorkExperienceReferences = new List { CreateMockWorkExperienceReference(500) } - }; - - var result = await _validator.Validate(application); - Assert.Contains("applicant does not have enough education for both ITE and SNE", result.ValidationErrors); - } + Transcripts = new List { CreateMockTranscript(false), CreateMockTranscript(false), CreateMockTranscript(false) }, + CharacterReferences = new List { CreateMockCharacterReference() }, + CertificationTypes = new List { CertificationType.FiveYears }, + WorkExperienceReferences = new List { CreateMockWorkExperienceReference(500) } + }; + + var result = await _validator.Validate(application); + Assert.Empty(result.ValidationErrors); + } - [Fact] - public async Task Validate_ValidApplication_ReturnsNoValidationError() + private Transcript CreateMockTranscript(bool invalid) + { + DateTime startDate = DateTime.Now.AddYears(-2); + DateTime endDate = DateTime.Now.AddYears(-1); + if (invalid) { - var application = new Application("id", "registrantId", ApplicationStatus.Draft) - { - Transcripts = new List { CreateMockTranscript(false), CreateMockTranscript(false), CreateMockTranscript(false) }, - CharacterReferences = new List { CreateMockCharacterReference() }, - CertificationTypes = new List { CertificationType.FiveYears }, - WorkExperienceReferences = new List { CreateMockWorkExperienceReference(500) } - }; - - var result = await _validator.Validate(application); - Assert.Empty(result.ValidationErrors); + startDate = DateTime.Now.AddYears(-20); + endDate = DateTime.Now.AddYears(-19); } - private Transcript CreateMockTranscript(bool invalid) - { - DateTime startDate = DateTime.Now.AddYears(-2); - DateTime endDate = DateTime.Now.AddYears(-1); - if (invalid) - { - startDate = DateTime.Now.AddYears(-20); - endDate = DateTime.Now.AddYears(-19); - } - - var faker = new Faker("en_CA"); - var transcript = new Transcript(null, faker.Company.CompanyName(), $"{faker.Hacker.Adjective()} Program", faker.Random.Number(10000000, 99999999).ToString(), startDate, endDate, faker.Random.Bool(), faker.Random.Bool(), faker.Random.Bool(), faker.Name.FirstName(), faker.Name.LastName(), faker.Random.Bool()); - - return transcript; - } + var faker = new Faker("en_CA"); + var transcript = new Transcript(null, faker.Company.CompanyName(), $"{faker.Hacker.Adjective()} Program", faker.Random.Number(10000000, 99999999).ToString(), startDate, endDate, faker.Random.Bool(), faker.Random.Bool(), faker.Random.Bool(), faker.Name.FirstName(), faker.Name.LastName(), faker.Random.Bool()); - private CharacterReference CreateMockCharacterReference() - { - var faker = new Faker("en_CA"); + return transcript; + } - return new CharacterReference( - faker.Name.FirstName(), faker.Name.LastName(), faker.Internet.Email(), faker.Phone.PhoneNumber() - ); - } + private CharacterReference CreateMockCharacterReference() + { + var faker = new Faker("en_CA"); - private WorkExperienceReference CreateMockWorkExperienceReference(int hours) + return new CharacterReference( + faker.Name.FirstName(), faker.Name.LastName(), faker.Internet.Email(), faker.Phone.PhoneNumber() + ); + } + + private WorkExperienceReference CreateMockWorkExperienceReference(int hours) + { + var faker = new Faker("en_CA"); + + return new WorkExperienceReference( + faker.Name.FirstName(), faker.Name.FirstName(), faker.Internet.Email(), hours + ) { - var faker = new Faker("en_CA"); - - return new WorkExperienceReference( - faker.Name.FirstName(), faker.Name.FirstName(), faker.Internet.Email(), hours - ) - { - PhoneNumber = faker.Phone.PhoneNumber() - }; - } + PhoneNumber = faker.Phone.PhoneNumber() + }; } } diff --git a/src/ECER.Tests/Unit/AutoMapperValidation.cs b/src/ECER.Tests/Unit/AutoMapperValidation.cs index 882828aca..6c434ca84 100644 --- a/src/ECER.Tests/Unit/AutoMapperValidation.cs +++ b/src/ECER.Tests/Unit/AutoMapperValidation.cs @@ -6,15 +6,15 @@ namespace ECER.Tests.Unit; public class AutoMapperValidation { - [Fact] - public void Validate() - { - var mapperConfig = new MapperConfiguration(cfg => - { - cfg.AddMaps(ReflectionExtensions.DiscoverLocalAessemblies(prefix: "ECER")); - cfg.EnableEnumMappingValidation(); - }); + [Fact] + public void Validate() + { + var mapperConfig = new MapperConfiguration(cfg => + { + cfg.AddMaps(ReflectionExtensions.DiscoverLocalAessemblies(prefix: "ECER")); + cfg.EnableEnumMappingValidation(); + }); - mapperConfig.AssertConfigurationIsValid(); - } -} \ No newline at end of file + mapperConfig.AssertConfigurationIsValid(); + } +}