diff --git a/.editorconfig b/.editorconfig index 73472fa15f..6ee110ee1e 100644 --- a/.editorconfig +++ b/.editorconfig @@ -20,6 +20,15 @@ indent_size = 2 # All Rules are enabled with default severity. # Rules with IsEnabledByDefault = false are force-enabled with default severity. +# CA1515 Suppress "Because an application's API isn't typically referenced from outside the assembly, types can be made internal" +dotnet_diagnostic.ca1515.severity = none + +# IDE0290 Suppress "Use primary constructor" +dotnet_diagnostic.IDE0290.severity = none + +# IDE0160 Suppress "Convert to block scoped namespace" +dotnet_diagnostic.IDE0160.severity = none + # S101: Types should be named in PascalCase dotnet_diagnostic.s101.severity = none diff --git a/Apps/AccountDataAccess/src/Audit/AuditRepository.cs b/Apps/AccountDataAccess/src/Audit/AuditRepository.cs index ceabdd7f2b..3c1ef3b508 100644 --- a/Apps/AccountDataAccess/src/Audit/AuditRepository.cs +++ b/Apps/AccountDataAccess/src/Audit/AuditRepository.cs @@ -25,19 +25,9 @@ namespace HealthGateway.AccountDataAccess.Audit /// /// Handle audit data. /// - public class AuditRepository : IAuditRepository + /// The injected agent audit delegate. + public class AuditRepository(IAgentAuditDelegate agentAuditDelegate) : IAuditRepository { - private readonly IAgentAuditDelegate agentAuditDelegate; - - /// - /// Initializes a new instance of the class. - /// - /// The injected agent audit delegate. - public AuditRepository(IAgentAuditDelegate agentAuditDelegate) - { - this.agentAuditDelegate = agentAuditDelegate; - } - private static ActivitySource ActivitySource { get; } = new(typeof(AuditRepository).FullName); /// @@ -50,7 +40,7 @@ public async Task> HandleAsync(AgentAuditQuery query, Ca activity?.AddBaggage("AuditGroup", query.Group.ToString()); } - return await this.agentAuditDelegate.GetAgentAuditsAsync(query.Hdid, query.Group, ct); + return await agentAuditDelegate.GetAgentAuditsAsync(query.Hdid, query.Group, ct); } } } diff --git a/Apps/AccountDataAccess/src/Patient/Address.cs b/Apps/AccountDataAccess/src/Patient/Address.cs index 5081950b25..91c317e164 100644 --- a/Apps/AccountDataAccess/src/Patient/Address.cs +++ b/Apps/AccountDataAccess/src/Patient/Address.cs @@ -16,7 +16,6 @@ namespace HealthGateway.AccountDataAccess.Patient { using System.Collections.Generic; - using System.Linq; /// /// Represents an address. @@ -26,7 +25,7 @@ public class Address /// /// Gets or sets the street lines. /// - public IEnumerable StreetLines { get; set; } = Enumerable.Empty(); + public IEnumerable StreetLines { get; set; } = []; /// /// Gets or sets the city name. diff --git a/Apps/AccountDataAccess/src/Patient/ClientRegistriesDelegate.cs b/Apps/AccountDataAccess/src/Patient/ClientRegistriesDelegate.cs index ad75bf4d28..82a2b43383 100644 --- a/Apps/AccountDataAccess/src/Patient/ClientRegistriesDelegate.cs +++ b/Apps/AccountDataAccess/src/Patient/ClientRegistriesDelegate.cs @@ -32,7 +32,11 @@ namespace HealthGateway.AccountDataAccess.Patient /// /// The Client Registries delegate. /// - internal class ClientRegistriesDelegate : IClientRegistriesDelegate + /// The injected logger provider. + /// The injected client registries soap client. + internal class ClientRegistriesDelegate( + ILogger logger, + QUPA_AR101102_PortType clientRegistriesClient) : IClientRegistriesDelegate { private const string Instance = "INSTANCE"; private static readonly List WarningResponseCodes = @@ -41,23 +45,6 @@ internal class ClientRegistriesDelegate : IClientRegistriesDelegate "BCHCIM.GD.1.0022", "BCHCIM.GD.0.0023", "BCHCIM.GD.1.0023", "BCHCIM.GD.0.0578", "BCHCIM.GD.1.0578", ]; - private readonly QUPA_AR101102_PortType clientRegistriesClient; - private readonly ILogger logger; - - /// - /// Initializes a new instance of the class. - /// Constructor that requires an IEndpointBehavior for dependency injection. - /// - /// The injected logger provider. - /// The injected client registries soap client. - public ClientRegistriesDelegate( - ILogger logger, - QUPA_AR101102_PortType clientRegistriesClient) - { - this.logger = logger; - this.clientRegistriesClient = clientRegistriesClient; - } - private static ActivitySource ActivitySource { get; } = new(typeof(ClientRegistriesDelegate).FullName); /// @@ -66,13 +53,13 @@ public async Task GetDemographicsAsync(OidType type, string identi using Activity? activity = ActivitySource.StartActivity(); activity?.AddBaggage("PatientIdentifier", identifier); - this.logger.LogDebug("Retrieving patient from the Client Registry"); + logger.LogDebug("Retrieving patient from the Client Registry"); // Create request object HCIM_IN_GetDemographicsRequest request = CreateRequest(type, identifier); // Perform the request - HCIM_IN_GetDemographicsResponse1 reply = await this.clientRegistriesClient.HCIM_IN_GetDemographicsAsync(request); + HCIM_IN_GetDemographicsResponse1 reply = await clientRegistriesClient.HCIM_IN_GetDemographicsAsync(request); return this.ParseResponse(reply); } @@ -162,7 +149,32 @@ private static HCIM_IN_GetDemographicsRequest CreateRequest(OidType oidType, str return new HCIM_IN_GetDemographicsRequest(request); } - private static Address? MapAddress(AD? address) + private static Name ExtractName(PN nameSection) + { + // Extract the subject names + List givenNameList = []; + List lastNameList = []; + foreach (ENXP name in nameSection.Items) + { + if (name.GetType() == typeof(engiven) && (name.qualifier == null || !name.qualifier.Contains(cs_EntityNamePartQualifier.CL))) + { + givenNameList.Add(name.Text[0]); + } + else if (name.GetType() == typeof(enfamily) && (name.qualifier == null || !name.qualifier.Contains(cs_EntityNamePartQualifier.CL))) + { + lastNameList.Add(name.Text[0]); + } + } + + const string delimiter = " "; + return new Name + { + GivenName = givenNameList.Aggregate((i, j) => i + delimiter + j), + Surname = lastNameList.Aggregate((i, j) => i + delimiter + j), + }; + } + + private Address? MapAddress(AD? address) { if (address?.Items == null) { @@ -189,37 +201,15 @@ private static HCIM_IN_GetDemographicsRequest CreateRequest(OidType oidType, str case ADCountry country: retAddress.Country = country.Text[0] ?? string.Empty; break; + default: + logger.LogDebug("Unmatched item of type {Type}", item.GetType()); + break; } } return retAddress; } - private static Name ExtractName(PN nameSection) - { - // Extract the subject names - List givenNameList = []; - List lastNameList = []; - foreach (ENXP name in nameSection.Items) - { - if (name.GetType() == typeof(engiven) && (name.qualifier == null || !name.qualifier.Contains(cs_EntityNamePartQualifier.CL))) - { - givenNameList.Add(name.Text[0]); - } - else if (name.GetType() == typeof(enfamily) && (name.qualifier == null || !name.qualifier.Contains(cs_EntityNamePartQualifier.CL))) - { - lastNameList.Add(name.Text[0]); - } - } - - const string delimiter = " "; - return new Name - { - GivenName = givenNameList.Aggregate((i, j) => i + delimiter + j), - Surname = lastNameList.Aggregate((i, j) => i + delimiter + j), - }; - } - private void CheckResponseCode(string responseCode) { if (responseCode.Contains("BCHCIM.GD.2.0018", StringComparison.InvariantCulture)) @@ -229,7 +219,7 @@ private void CheckResponseCode(string responseCode) if (responseCode.Contains("BCHCIM.GD.2.0006", StringComparison.InvariantCulture)) { - this.logger.LogWarning(ErrorMessages.PhnInvalid); + logger.LogWarning(ErrorMessages.PhnInvalid); throw new ValidationException(ErrorMessages.PhnInvalid, [new("PHN", ErrorMessages.PhnInvalid)]); // should throw InvalidDataException instead } @@ -241,7 +231,7 @@ private void CheckResponseCode(string responseCode) // Verify that the reply contains a result if (!responseCode.Contains("BCHCIM.GD.0.0013", StringComparison.InvariantCulture)) { - this.logger.LogWarning(ErrorMessages.ClientRegistryDoesNotReturnPerson); + logger.LogWarning(ErrorMessages.ClientRegistryDoesNotReturnPerson); throw new NotFoundException(ErrorMessages.ClientRegistryDoesNotReturnPerson); } } @@ -261,7 +251,7 @@ private PatientModel ParseResponse(HCIM_IN_GetDemographicsResponse1 reply) string? dobStr = retrievedPerson.identifiedPerson.birthTime.value; if (!DateTime.TryParseExact(dobStr, "yyyyMMdd", CultureInfo.InvariantCulture, DateTimeStyles.None, out DateTime dob)) { - this.logger.LogWarning("Unable to parse patient's date of birth"); + logger.LogWarning("Unable to parse patient's date of birth"); throw new NotFoundException(ErrorMessages.InvalidServicesCard); } @@ -288,8 +278,8 @@ private PatientModel ParseResponse(HCIM_IN_GetDemographicsResponse1 reply) AD[] addresses = retrievedPerson.addr; if (addresses != null) { - patientModel.PhysicalAddress = MapAddress(addresses.FirstOrDefault(a => a.use.Any(u => u == cs_PostalAddressUse.PHYS))); - patientModel.PostalAddress = MapAddress(addresses.FirstOrDefault(a => a.use.Any(u => u == cs_PostalAddressUse.PST))); + patientModel.PhysicalAddress = this.MapAddress(addresses.FirstOrDefault(a => a.use.Any(u => u == cs_PostalAddressUse.PHYS))); + patientModel.PostalAddress = this.MapAddress(addresses.FirstOrDefault(a => a.use.Any(u => u == cs_PostalAddressUse.PST))); } if (WarningResponseCodes.Any(code => responseCode.Contains(code, StringComparison.InvariantCulture))) @@ -309,11 +299,11 @@ private void PopulateNames(HCIM_IN_GetDemographicsResponseIdentifiedPerson retri if (documentedName == null && legalName == null) { - this.logger.LogWarning("The Client Registry returned a person without a Documented Name or a Legal Name"); + logger.LogWarning("The Client Registry returned a person without a Documented Name or a Legal Name"); } else if (documentedName == null) { - this.logger.LogWarning("The Client Registry returned a person without a Documented Name"); + logger.LogWarning("The Client Registry returned a person without a Documented Name"); } if (documentedName != null) @@ -333,7 +323,7 @@ private void PopulateIdentifiers(HCIM_IN_GetDemographicsResponseIdentifiedPerson II? identifiedPersonId = retrievedPerson.identifiedPerson?.id?.FirstOrDefault(x => x.root == OidType.Phn.ToString()); if (identifiedPersonId == null) { - this.logger.LogWarning("The Client Registry returned a person without a PHN"); + logger.LogWarning("The Client Registry returned a person without a PHN"); } else { @@ -343,7 +333,7 @@ private void PopulateIdentifiers(HCIM_IN_GetDemographicsResponseIdentifiedPerson II? subjectId = retrievedPerson.id?.FirstOrDefault(x => x.displayable && x.root == OidType.Hdid.ToString()); if (subjectId == null) { - this.logger.LogWarning("The Client Registry returned a person without an HDID"); + logger.LogWarning("The Client Registry returned a person without an HDID"); } else { diff --git a/Apps/AccountDataAccess/src/Patient/PatientMappings.cs b/Apps/AccountDataAccess/src/Patient/PatientMappings.cs index d893e8423d..aa8a13fcf1 100644 --- a/Apps/AccountDataAccess/src/Patient/PatientMappings.cs +++ b/Apps/AccountDataAccess/src/Patient/PatientMappings.cs @@ -38,7 +38,7 @@ public PatientMappings() private static Name ExtractPreferredName(PatientIdentity patientIdentity) { string preferredName = StringManipulator.JoinWithoutBlanks( - new[] { patientIdentity.PreferredFirstName, patientIdentity.PreferredSecondName, patientIdentity.PreferredThirdName }); + [patientIdentity.PreferredFirstName, patientIdentity.PreferredSecondName, patientIdentity.PreferredThirdName]); return new() { @@ -50,7 +50,7 @@ private static Name ExtractPreferredName(PatientIdentity patientIdentity) private static Name ExtractLegalName(PatientIdentity patientIdentity) { string legalName = StringManipulator.JoinWithoutBlanks( - new[] { patientIdentity.LegalFirstName, patientIdentity.LegalSecondName, patientIdentity.LegalThirdName }); + [patientIdentity.LegalFirstName, patientIdentity.LegalSecondName, patientIdentity.LegalThirdName]); return new() { @@ -64,7 +64,7 @@ private static Name ExtractLegalName(PatientIdentity patientIdentity) if (ShouldReturnHomeAddress(patientIdentity)) { IEnumerable streetLines = StringManipulator.ExcludeBlanks( - new[] { patientIdentity.HomeAddressStreetOne, patientIdentity.HomeAddressStreetTwo, patientIdentity.HomeAddressStreetThree }); + [patientIdentity.HomeAddressStreetOne, patientIdentity.HomeAddressStreetTwo, patientIdentity.HomeAddressStreetThree]); return new() { @@ -84,7 +84,7 @@ private static Name ExtractLegalName(PatientIdentity patientIdentity) if (ShouldReturnPostalAddress(patientIdentity)) { IEnumerable streetLines = StringManipulator.ExcludeBlanks( - new[] { patientIdentity.MailAddressStreetOne, patientIdentity.MailAddressStreetTwo, patientIdentity.MailAddressStreetThree }); + [patientIdentity.MailAddressStreetOne, patientIdentity.MailAddressStreetTwo, patientIdentity.MailAddressStreetThree]); return new() { diff --git a/Apps/AccountDataAccess/src/Patient/PatientRepository.cs b/Apps/AccountDataAccess/src/Patient/PatientRepository.cs index 5e8942f8c2..8e1b941222 100644 --- a/Apps/AccountDataAccess/src/Patient/PatientRepository.cs +++ b/Apps/AccountDataAccess/src/Patient/PatientRepository.cs @@ -189,6 +189,11 @@ private static string GetStrategy(string? hdid, PatientDetailSource source) private async Task HandlePatientDetailsQueryAsync(PatientDetailsQuery query, CancellationToken ct) { + if (ct.IsCancellationRequested) + { + throw new InvalidOperationException("Cancellation was requested"); + } + using Activity? activity = ActivitySource.StartActivity(); if (!string.IsNullOrEmpty(query.Hdid)) @@ -206,17 +211,9 @@ private async Task HandlePatientDetailsQueryAsync(PatientDet this.logger.LogDebug("Retrieving patient details"); - if (ct.IsCancellationRequested) - { - throw new InvalidOperationException("Cancellation was requested"); - } - - if (query.Hdid == null && query.Phn == null) - { - throw new InvalidOperationException("Must specify either Hdid or Phn to query patient details"); - } - - return await this.GetPatientAsync(query, ct: ct); + return (query.Hdid ?? query.Phn) == null + ? throw new InvalidOperationException("Must specify either Hdid or Phn to query patient details") + : await this.GetPatientAsync(query, ct: ct); } private async Task GetPatientAsync(PatientDetailsQuery query, bool disabledValidation = false, CancellationToken ct = default) diff --git a/Apps/AccountDataAccess/src/Patient/Strategy/HdidAllStrategy.cs b/Apps/AccountDataAccess/src/Patient/Strategy/HdidAllStrategy.cs index 7a2e8ab1a0..ed7f313692 100644 --- a/Apps/AccountDataAccess/src/Patient/Strategy/HdidAllStrategy.cs +++ b/Apps/AccountDataAccess/src/Patient/Strategy/HdidAllStrategy.cs @@ -31,35 +31,20 @@ namespace HealthGateway.AccountDataAccess.Patient.Strategy /// /// Strategy implementation for all hdid patient data sources with or without cache. /// - internal class HdidAllStrategy : PatientQueryStrategy + /// The injected configuration. + /// The injected cache provider. + /// The injected logger. + /// The injected client registries delegate. + /// The injected patient identity api. + /// The injected mapper. + internal class HdidAllStrategy( + IConfiguration configuration, + ICacheProvider cacheProvider, + IClientRegistriesDelegate clientRegistriesDelegate, + IPatientIdentityApi patientIdentityApi, + ILogger logger, + IMapper mapper) : PatientQueryStrategy(configuration, cacheProvider, logger) { - private readonly IClientRegistriesDelegate clientRegistriesDelegate; - private readonly IPatientIdentityApi patientIdentityApi; - private readonly IMapper mapper; - - /// - /// Initializes a new instance of the class. - /// - /// The injected configuration. - /// The injected cache provider. - /// The injected logger. - /// The injected client registries delegate. - /// The injected patient identity api. - /// The injected mapper. - public HdidAllStrategy( - IConfiguration configuration, - ICacheProvider cacheProvider, - IClientRegistriesDelegate clientRegistriesDelegate, - IPatientIdentityApi patientIdentityApi, - ILogger logger, - IMapper mapper) - : base(configuration, cacheProvider, logger) - { - this.clientRegistriesDelegate = clientRegistriesDelegate; - this.patientIdentityApi = patientIdentityApi; - this.mapper = mapper; - } - /// public override async Task GetPatientAsync(PatientRequest request, CancellationToken ct = default) { @@ -67,7 +52,7 @@ public override async Task GetPatientAsync(PatientRequest request, try { - patient ??= await this.clientRegistriesDelegate.GetDemographicsAsync(OidType.Hdid, request.Identifier, request.DisabledValidation, ct); + patient ??= await clientRegistriesDelegate.GetDemographicsAsync(OidType.Hdid, request.Identifier, request.DisabledValidation, ct); } catch (CommunicationException ce) { @@ -76,8 +61,8 @@ public override async Task GetPatientAsync(PatientRequest request, try { this.GetLogger().LogDebug("Retrieving patient from PHSA"); - PatientIdentity result = await this.patientIdentityApi.GetPatientIdentityAsync(request.Identifier, ct); - patient = this.mapper.Map(result); + PatientIdentity result = await patientIdentityApi.GetPatientIdentityAsync(request.Identifier, ct); + patient = mapper.Map(result); } catch (ApiException e) when (e.StatusCode == HttpStatusCode.NotFound) { diff --git a/Apps/AccountDataAccess/src/Patient/Strategy/HdidEmpiStrategy.cs b/Apps/AccountDataAccess/src/Patient/Strategy/HdidEmpiStrategy.cs index 990f39d695..cb87a117e9 100644 --- a/Apps/AccountDataAccess/src/Patient/Strategy/HdidEmpiStrategy.cs +++ b/Apps/AccountDataAccess/src/Patient/Strategy/HdidEmpiStrategy.cs @@ -25,32 +25,21 @@ namespace HealthGateway.AccountDataAccess.Patient.Strategy /// /// Strategy implementation for EMPI hdid patient data source with or without cache. /// - internal class HdidEmpiStrategy : PatientQueryStrategy + /// The injected configuration. + /// The injected cache provider. + /// The injected client registries delegate. + /// The injected logger. + internal class HdidEmpiStrategy( + IConfiguration configuration, + ICacheProvider cacheProvider, + IClientRegistriesDelegate clientRegistriesDelegate, + ILogger logger) : PatientQueryStrategy(configuration, cacheProvider, logger) { - private readonly IClientRegistriesDelegate clientRegistriesDelegate; - - /// - /// Initializes a new instance of the class. - /// - /// The injected configuration. - /// The injected cache provider. - /// The injected client registries delegate. - /// The injected logger. - public HdidEmpiStrategy( - IConfiguration configuration, - ICacheProvider cacheProvider, - IClientRegistriesDelegate clientRegistriesDelegate, - ILogger logger) - : base(configuration, cacheProvider, logger) - { - this.clientRegistriesDelegate = clientRegistriesDelegate; - } - /// public override async Task GetPatientAsync(PatientRequest request, CancellationToken ct = default) { PatientModel patient = (request.UseCache ? await this.GetFromCacheAsync(request.Identifier, PatientIdentifierType.Hdid, ct) : null) ?? - await this.clientRegistriesDelegate.GetDemographicsAsync(OidType.Hdid, request.Identifier, request.DisabledValidation, ct); + await clientRegistriesDelegate.GetDemographicsAsync(OidType.Hdid, request.Identifier, request.DisabledValidation, ct); await this.CachePatientAsync(patient, request.DisabledValidation, ct); return patient; diff --git a/Apps/AccountDataAccess/src/Patient/Strategy/HdidPhsaStrategy.cs b/Apps/AccountDataAccess/src/Patient/Strategy/HdidPhsaStrategy.cs index beab4373bf..813b284165 100644 --- a/Apps/AccountDataAccess/src/Patient/Strategy/HdidPhsaStrategy.cs +++ b/Apps/AccountDataAccess/src/Patient/Strategy/HdidPhsaStrategy.cs @@ -30,31 +30,18 @@ namespace HealthGateway.AccountDataAccess.Patient.Strategy /// /// Strategy implementation for PHSA phn patient data source with or without cache. /// - internal class HdidPhsaStrategy : PatientQueryStrategy + /// The injected configuration. + /// The injected cache provider. + /// The injected patient identity api. + /// The injected logger. + /// The injected mapper. + internal class HdidPhsaStrategy( + IConfiguration configuration, + ICacheProvider cacheProvider, + IPatientIdentityApi patientIdentityApi, + ILogger logger, + IMapper mapper) : PatientQueryStrategy(configuration, cacheProvider, logger) { - private readonly IPatientIdentityApi patientIdentityApi; - private readonly IMapper mapper; - - /// - /// Initializes a new instance of the class. - /// - /// The injected configuration. - /// The injected cache provider. - /// The injected patient identity api. - /// The injected logger. - /// The injected mapper. - public HdidPhsaStrategy( - IConfiguration configuration, - ICacheProvider cacheProvider, - IPatientIdentityApi patientIdentityApi, - ILogger logger, - IMapper mapper) - : base(configuration, cacheProvider, logger) - { - this.patientIdentityApi = patientIdentityApi; - this.mapper = mapper; - } - /// public override async Task GetPatientAsync(PatientRequest request, CancellationToken ct = default) { @@ -65,8 +52,8 @@ public override async Task GetPatientAsync(PatientRequest request, try { this.GetLogger().LogDebug("Retrieving patient from PHSA"); - PatientIdentity result = await this.patientIdentityApi.GetPatientIdentityAsync(request.Identifier, ct); - patient = this.mapper.Map(result); + PatientIdentity result = await patientIdentityApi.GetPatientIdentityAsync(request.Identifier, ct); + patient = mapper.Map(result); } catch (ApiException e) when (e.StatusCode == HttpStatusCode.NotFound) { diff --git a/Apps/AccountDataAccess/src/Patient/Strategy/PatientQueryContext.cs b/Apps/AccountDataAccess/src/Patient/Strategy/PatientQueryContext.cs index ce2f5f32ab..a8f1b724f0 100644 --- a/Apps/AccountDataAccess/src/Patient/Strategy/PatientQueryContext.cs +++ b/Apps/AccountDataAccess/src/Patient/Strategy/PatientQueryContext.cs @@ -21,22 +21,9 @@ namespace HealthGateway.AccountDataAccess.Patient.Strategy /// /// The Context defines the interface of interest to clients. /// - internal class PatientQueryContext + /// The implemented request to use. + internal class PatientQueryContext(PatientQueryStrategy patientQueryStrategy) { - // The Context maintains a reference to one of the Strategy objects. The - // Context does not know the concrete class of a request. It should - // work with all strategies via the Strategy interface. - private readonly PatientQueryStrategy patientQueryStrategy; - - /// - /// Initializes a new instance of the class. - /// - /// The implemented request to use. - public PatientQueryContext(PatientQueryStrategy patientQueryStrategy) - { - this.patientQueryStrategy = patientQueryStrategy; - } - /// /// Returns patient from the specified source in the patient request. /// @@ -45,7 +32,7 @@ public PatientQueryContext(PatientQueryStrategy patientQueryStrategy) /// The patient model. public async Task GetPatientAsync(PatientRequest patientRequest, CancellationToken ct = default) { - return await this.patientQueryStrategy.GetPatientAsync(patientRequest, ct); + return await patientQueryStrategy.GetPatientAsync(patientRequest, ct); } } } diff --git a/Apps/AccountDataAccess/src/Patient/Strategy/PatientQueryFactory.cs b/Apps/AccountDataAccess/src/Patient/Strategy/PatientQueryFactory.cs index b76bdcf07d..694fb02de3 100644 --- a/Apps/AccountDataAccess/src/Patient/Strategy/PatientQueryFactory.cs +++ b/Apps/AccountDataAccess/src/Patient/Strategy/PatientQueryFactory.cs @@ -21,19 +21,9 @@ namespace HealthGateway.AccountDataAccess.Patient.Strategy /// /// Factory for instances. /// - internal class PatientQueryFactory + /// The injected service provider. + internal class PatientQueryFactory(IServiceProvider serviceProvider) { - private readonly IServiceProvider serviceProvider; - - /// - /// Initializes a new instance of the class. - /// - /// The injected service provider. - public PatientQueryFactory(IServiceProvider serviceProvider) - { - this.serviceProvider = serviceProvider; - } - /// /// Returns an instance of the requested class. /// @@ -42,7 +32,7 @@ public PatientQueryFactory(IServiceProvider serviceProvider) public PatientQueryStrategy GetPatientQueryStrategy(string strategy) { Type type = Type.GetType(strategy) ?? throw new ArgumentException($"Invalid strategy type {strategy}"); - return (PatientQueryStrategy)this.serviceProvider.GetRequiredService(type); + return (PatientQueryStrategy)serviceProvider.GetRequiredService(type); } } } diff --git a/Apps/AccountDataAccess/src/Patient/Strategy/PatientQueryStrategy.cs b/Apps/AccountDataAccess/src/Patient/Strategy/PatientQueryStrategy.cs index 51e2c19338..f99a825633 100644 --- a/Apps/AccountDataAccess/src/Patient/Strategy/PatientQueryStrategy.cs +++ b/Apps/AccountDataAccess/src/Patient/Strategy/PatientQueryStrategy.cs @@ -33,29 +33,16 @@ namespace HealthGateway.AccountDataAccess.Patient.Strategy /// The Context uses this interface to call the algorithm defined by Concrete /// Strategies. /// - internal abstract class PatientQueryStrategy + /// The Configuration to use. + /// The injected cache provider. + /// The injected logger. + internal abstract class PatientQueryStrategy( + IConfiguration configuration, + ICacheProvider cacheProvider, + ILogger logger) { private const string PatientCacheDomain = "PatientV2"; - - private readonly ILogger logger; - private readonly ICacheProvider cacheProvider; - private readonly int cacheTtl; - - /// - /// Initializes a new instance of the class. - /// - /// The Configuration to use. - /// The injected cache provider. - /// The injected logger. - protected PatientQueryStrategy( - IConfiguration configuration, - ICacheProvider cacheProvider, - ILogger logger) - { - this.cacheProvider = cacheProvider; - this.logger = logger; - this.cacheTtl = configuration.GetSection("PatientService").GetValue("CacheTTL", 0); - } + private readonly int cacheTtl = configuration.GetSection("PatientService").GetValue("CacheTTL", 0); private static ActivitySource ActivitySource { get; } = new(typeof(PatientQueryStrategy).FullName); @@ -75,7 +62,7 @@ protected PatientQueryStrategy( /// A class. protected ILogger GetLogger() { - return this.logger; + return logger; } /// @@ -94,16 +81,16 @@ protected ILogger GetLogger() using Activity? activity = ActivitySource.StartActivity(); activity?.AddBaggage("CacheIdentifier", identifier); - this.logger.LogDebug("Accessing patient cache via {CacheIdentifierType}", identifierType); + logger.LogDebug("Accessing patient cache via {CacheIdentifierType}", identifierType); PatientModel? retPatient = identifierType switch { - PatientIdentifierType.Hdid => await this.cacheProvider.GetItemAsync($"{PatientCacheDomain}:HDID:{identifier}", ct), - PatientIdentifierType.Phn => await this.cacheProvider.GetItemAsync($"{PatientCacheDomain}:PHN:{identifier}", ct), + PatientIdentifierType.Hdid => await cacheProvider.GetItemAsync($"{PatientCacheDomain}:HDID:{identifier}", ct), + PatientIdentifierType.Phn => await cacheProvider.GetItemAsync($"{PatientCacheDomain}:PHN:{identifier}", ct), _ => null, }; - this.logger.LogDebug("Patient cache access outcome: {CacheResult}", retPatient == null ? "miss" : "hit"); + logger.LogDebug("Patient cache access outcome: {CacheResult}", retPatient == null ? "miss" : "hit"); return retPatient; } @@ -138,15 +125,15 @@ private async Task CachePatientAsync(PatientModel patientModel, CancellationToke if (!string.IsNullOrEmpty(patientModel.Hdid)) { activity?.AddBaggage("CacheIdentifier", patientModel.Hdid); - this.logger.LogDebug("Storing patient in cache via {CacheIdentifierType}", PatientIdentifierType.Hdid); - await this.cacheProvider.AddItemAsync($"{PatientCacheDomain}:HDID:{patientModel.Hdid}", patientModel, expiry, ct); + logger.LogDebug("Storing patient in cache via {CacheIdentifierType}", PatientIdentifierType.Hdid); + await cacheProvider.AddItemAsync($"{PatientCacheDomain}:HDID:{patientModel.Hdid}", patientModel, expiry, ct); } if (!string.IsNullOrEmpty(patientModel.Phn)) { activity?.AddBaggage("CacheIdentifier", patientModel.Phn); - this.logger.LogDebug("Storing patient in cache via {CacheIdentifierType}", PatientIdentifierType.Phn); - await this.cacheProvider.AddItemAsync($"{PatientCacheDomain}:PHN:{patientModel.Phn}", patientModel, expiry, ct); + logger.LogDebug("Storing patient in cache via {CacheIdentifierType}", PatientIdentifierType.Phn); + await cacheProvider.AddItemAsync($"{PatientCacheDomain}:PHN:{patientModel.Phn}", patientModel, expiry, ct); } } } diff --git a/Apps/AccountDataAccess/src/Patient/Strategy/PhnEmpiStrategy.cs b/Apps/AccountDataAccess/src/Patient/Strategy/PhnEmpiStrategy.cs index 55e6f3432f..65cf43cbbb 100644 --- a/Apps/AccountDataAccess/src/Patient/Strategy/PhnEmpiStrategy.cs +++ b/Apps/AccountDataAccess/src/Patient/Strategy/PhnEmpiStrategy.cs @@ -27,34 +27,23 @@ namespace HealthGateway.AccountDataAccess.Patient.Strategy /// /// Strategy implementation for EMPI phn patient data source with or without cache. /// - internal class PhnEmpiStrategy : PatientQueryStrategy + /// The injected configuration. + /// The injected cache provider. + /// The injected client registries delegate. + /// The injected logger. + internal class PhnEmpiStrategy( + IConfiguration configuration, + ICacheProvider cacheProvider, + IClientRegistriesDelegate clientRegistriesDelegate, + ILogger logger) : PatientQueryStrategy(configuration, cacheProvider, logger) { - private readonly IClientRegistriesDelegate clientRegistriesDelegate; - - /// - /// Initializes a new instance of the class. - /// - /// The injected configuration. - /// The injected cache provider. - /// The injected client registries delegate. - /// The injected logger. - public PhnEmpiStrategy( - IConfiguration configuration, - ICacheProvider cacheProvider, - IClientRegistriesDelegate clientRegistriesDelegate, - ILogger logger) - : base(configuration, cacheProvider, logger) - { - this.clientRegistriesDelegate = clientRegistriesDelegate; - } - /// public override async Task GetPatientAsync(PatientRequest request, CancellationToken ct = default) { await new PhnValidator(ErrorMessages.PhnInvalid).ValidateAndThrowAsync(request.Identifier, ct); PatientModel patient = (request.UseCache ? await this.GetFromCacheAsync(request.Identifier, PatientIdentifierType.Phn, ct) : null) ?? - await this.clientRegistriesDelegate.GetDemographicsAsync(OidType.Phn, request.Identifier, request.DisabledValidation, ct); + await clientRegistriesDelegate.GetDemographicsAsync(OidType.Phn, request.Identifier, request.DisabledValidation, ct); await this.CachePatientAsync(patient, request.DisabledValidation, ct); return patient; diff --git a/Apps/AccountDataAccess/test/unit/ClientRegistriesDelegateTests.cs b/Apps/AccountDataAccess/test/unit/ClientRegistriesDelegateTests.cs index c0a292905f..6182d7a6d3 100644 --- a/Apps/AccountDataAccess/test/unit/ClientRegistriesDelegateTests.cs +++ b/Apps/AccountDataAccess/test/unit/ClientRegistriesDelegateTests.cs @@ -478,21 +478,18 @@ private static EnName GenerateEnName(string name, cs_EntityNamePartQualifier? qu private static II[] GenerateId(bool shouldReturnEmpty = false, string? extension = null, string? oidType = null, bool displayable = true) { - if (shouldReturnEmpty) - { - return []; - } - - return - [ - new II - { - root = oidType ?? HdidOidType, - extension = oidType == null || (oidType == HdidOidType && extension == null) ? Hdid - : oidType == PhnOidType && extension == null ? Phn : extension, - displayable = displayable, - }, - ]; + return shouldReturnEmpty + ? [] + : + [ + new II + { + root = oidType ?? HdidOidType, + extension = oidType == null || (oidType == HdidOidType && extension == null) ? Hdid + : oidType == PhnOidType && extension == null ? Phn : extension, + displayable = displayable, + }, + ]; } private static HCIM_IN_GetDemographicsResponsePerson GenerateIdentifiedPerson( @@ -507,7 +504,9 @@ private static HCIM_IN_GetDemographicsResponsePerson GenerateIdentifiedPerson( return new HCIM_IN_GetDemographicsResponsePerson { deceasedInd = new BL - { value = deceasedInd }, + { + value = deceasedInd, + }, id = GenerateId(shouldReturnEmpty, extension, oidType), name = names.ToArray(), birthTime = new TS diff --git a/Apps/AccountDataAccess/test/unit/PatientMappingsTests.cs b/Apps/AccountDataAccess/test/unit/PatientMappingsTests.cs index fb2e0afd64..72b4bd3aab 100644 --- a/Apps/AccountDataAccess/test/unit/PatientMappingsTests.cs +++ b/Apps/AccountDataAccess/test/unit/PatientMappingsTests.cs @@ -86,9 +86,15 @@ public void ShouldGetPatientModel() ResponseCode = string.Empty, IsDeceased = true, CommonName = new Name - { GivenName = expectedCommonGivenName, Surname = PhsaPreferredLastName }, + { + GivenName = expectedCommonGivenName, + Surname = PhsaPreferredLastName, + }, LegalName = new Name - { GivenName = expectedLegalGivenName, Surname = PhsaLegalLastName }, + { + GivenName = expectedLegalGivenName, + Surname = PhsaLegalLastName, + }, PhysicalAddress = new Address { StreetLines = @@ -173,9 +179,15 @@ public void ShouldGetPatientModelGivenNoNamesAndAddresses() ResponseCode = string.Empty, IsDeceased = true, CommonName = new Name - { GivenName = expectedCommonGivenName, Surname = expectedCommonSurname }, + { + GivenName = expectedCommonGivenName, + Surname = expectedCommonSurname, + }, LegalName = new Name - { GivenName = expectedLegalGivenName, Surname = expectedLegalSurname }, + { + GivenName = expectedLegalGivenName, + Surname = expectedLegalSurname, + }, PhysicalAddress = null, PostalAddress = null, }; diff --git a/Apps/AccountDataAccess/test/unit/PatientRepositoryTests.cs b/Apps/AccountDataAccess/test/unit/PatientRepositoryTests.cs index e4048e4c43..f2df441bdb 100644 --- a/Apps/AccountDataAccess/test/unit/PatientRepositoryTests.cs +++ b/Apps/AccountDataAccess/test/unit/PatientRepositoryTests.cs @@ -303,7 +303,7 @@ private static IConfigurationRoot GetIConfigurationRoot(bool blockedDataSourcesE }; return new ConfigurationBuilder() - .AddInMemoryCollection(myConfiguration.ToList()) + .AddInMemoryCollection(myConfiguration) .Build(); } @@ -330,10 +330,12 @@ private static BlockAccessMock SetupBlockAccessMock(BlockedAccess blockedAccess, if (changeFeedEnabled) { - IEnumerable events = new MessageEnvelope[] - { - new(new DataSourcesBlockedEvent(blockedAccess.Hdid, GetDataSourceValues(blockedAccess.DataSources)), blockedAccess.Hdid), - }; + IEnumerable events = + [ + new( + new DataSourcesBlockedEvent(blockedAccess.Hdid, GetDataSourceValues(blockedAccess.DataSources)), + blockedAccess.Hdid), + ]; messageSender.Setup(ms => ms.SendAsync(events, It.IsAny())); } diff --git a/Apps/AccountDataAccess/test/unit/Strategy/CacheProviderTests.cs b/Apps/AccountDataAccess/test/unit/Strategy/CacheProviderTests.cs index a2cd5ac834..ed9f872af4 100644 --- a/Apps/AccountDataAccess/test/unit/Strategy/CacheProviderTests.cs +++ b/Apps/AccountDataAccess/test/unit/Strategy/CacheProviderTests.cs @@ -87,7 +87,7 @@ private static IConfigurationRoot GetConfiguration(bool useCache) }; return new ConfigurationBuilder() - .AddInMemoryCollection(myConfiguration.ToList()) + .AddInMemoryCollection(myConfiguration) .Build(); } @@ -105,7 +105,7 @@ private static CachePatientMock SetupCachePatientMock(bool useCache, PatientMode s => s.GetDemographicsAsync( It.Is(x => x == OidType.Hdid), It.Is(x => x == Hdid), - It.Is(x => x == false), + It.Is(x => !x), It.IsAny())) .ReturnsAsync(patient); diff --git a/Apps/AccountDataAccess/test/unit/Strategy/HdidAllStrategyTests.cs b/Apps/AccountDataAccess/test/unit/Strategy/HdidAllStrategyTests.cs index 4319916c82..8a7e4c9480 100644 --- a/Apps/AccountDataAccess/test/unit/Strategy/HdidAllStrategyTests.cs +++ b/Apps/AccountDataAccess/test/unit/Strategy/HdidAllStrategyTests.cs @@ -98,9 +98,15 @@ public async Task ShouldGetPatientFromPhsa() ResponseCode = string.Empty, IsDeceased = false, CommonName = new Name - { GivenName = string.Empty, Surname = string.Empty }, + { + GivenName = string.Empty, + Surname = string.Empty, + }, LegalName = new Name - { GivenName = string.Empty, Surname = string.Empty }, + { + GivenName = string.Empty, + Surname = string.Empty, + }, }; PatientIdentity patientIdentity = new() @@ -146,7 +152,7 @@ private static IConfigurationRoot GetConfiguration() }; return new ConfigurationBuilder() - .AddInMemoryCollection(myConfiguration.ToList()) + .AddInMemoryCollection(myConfiguration) .Build(); } @@ -169,7 +175,7 @@ private static PatientMock SetupGetPatientMock(bool useCache, PatientModel patie s => s.GetDemographicsAsync( It.Is(x => x == OidType.Hdid), It.Is(x => x == Hdid), - It.Is(x => x == false), + It.Is(x => !x), It.IsAny())) .ReturnsAsync(patient); } @@ -192,7 +198,7 @@ private static HdidAllStrategy SetupHdidAllStrategyForGetPatientFromPhsa(Patient s => s.GetDemographicsAsync( It.Is(x => x == OidType.Hdid), It.Is(x => x == PhsaHdid), - It.Is(x => x == false), + It.Is(x => !x), It.IsAny())) .Throws(new CommunicationException("Unit test PHSA get patient identity.")); @@ -219,7 +225,7 @@ private static HdidAllStrategy SetupHdidAllStrategyForGetPatientHandlesPatientId s => s.GetDemographicsAsync( It.Is(x => x == OidType.Hdid), It.Is(x => x == PhsaHdidNotFound), - It.Is(x => x == false), + It.Is(x => !x), It.IsAny())) .Throws(new CommunicationException("Unit test PHSA get patient identity. NotFound")); diff --git a/Apps/AccountDataAccess/test/unit/Strategy/HdidEmpiStrategyTests.cs b/Apps/AccountDataAccess/test/unit/Strategy/HdidEmpiStrategyTests.cs index b41c4978a6..bb7da4f68c 100644 --- a/Apps/AccountDataAccess/test/unit/Strategy/HdidEmpiStrategyTests.cs +++ b/Apps/AccountDataAccess/test/unit/Strategy/HdidEmpiStrategyTests.cs @@ -77,7 +77,7 @@ private static IConfigurationRoot GetConfiguration() }; return new ConfigurationBuilder() - .AddInMemoryCollection(myConfiguration.ToList()) + .AddInMemoryCollection(myConfiguration) .Build(); } @@ -100,7 +100,7 @@ private static PatientMock SetupGetPatientMock(bool useCache, PatientModel patie s => s.GetDemographicsAsync( It.Is(x => x == OidType.Hdid), It.Is(x => x == Hdid), - It.Is(x => x == false), + It.Is(x => !x), It.IsAny())) .ReturnsAsync(patient); } diff --git a/Apps/AccountDataAccess/test/unit/Strategy/HdidPhsaStrategyTests.cs b/Apps/AccountDataAccess/test/unit/Strategy/HdidPhsaStrategyTests.cs index d8679e5ffb..bb25a3ebc1 100644 --- a/Apps/AccountDataAccess/test/unit/Strategy/HdidPhsaStrategyTests.cs +++ b/Apps/AccountDataAccess/test/unit/Strategy/HdidPhsaStrategyTests.cs @@ -63,9 +63,15 @@ public async Task ShouldGetPatient(bool useCache) ResponseCode = string.Empty, IsDeceased = false, CommonName = new Name - { GivenName = string.Empty, Surname = string.Empty }, + { + GivenName = string.Empty, + Surname = string.Empty, + }, LegalName = new Name - { GivenName = string.Empty, Surname = string.Empty }, + { + GivenName = string.Empty, + Surname = string.Empty, + }, }; (HdidPhsaStrategy strategy, Mock cacheProvider) = SetupPatientMockForGetPatient(useCache, expected); @@ -110,7 +116,7 @@ private static IConfigurationRoot GetConfiguration() }; return new ConfigurationBuilder() - .AddInMemoryCollection(myConfiguration.ToList()) + .AddInMemoryCollection(myConfiguration) .Build(); } diff --git a/Apps/AccountDataAccess/test/unit/Strategy/PhnEmpiStrategyTests.cs b/Apps/AccountDataAccess/test/unit/Strategy/PhnEmpiStrategyTests.cs index 5b0b5883c7..a175c0a8c5 100644 --- a/Apps/AccountDataAccess/test/unit/Strategy/PhnEmpiStrategyTests.cs +++ b/Apps/AccountDataAccess/test/unit/Strategy/PhnEmpiStrategyTests.cs @@ -104,7 +104,7 @@ private static IConfigurationRoot GetConfiguration() }; return new ConfigurationBuilder() - .AddInMemoryCollection(myConfiguration.ToList()) + .AddInMemoryCollection(myConfiguration) .Build(); } @@ -127,7 +127,7 @@ private static PatientMock SetupGetPatientMock(bool useCache, PatientModel patie s => s.GetDemographicsAsync( It.Is(x => x == OidType.Phn), It.Is(x => x == Phn), - It.Is(x => x == false), + It.Is(x => !x), It.IsAny())) .ReturnsAsync(patient); } diff --git a/Apps/Admin/Client/Components/Communications/BroadcastDialog.razor.cs b/Apps/Admin/Client/Components/Communications/BroadcastDialog.razor.cs index c622c4b74c..2cc6b5e7fb 100644 --- a/Apps/Admin/Client/Components/Communications/BroadcastDialog.razor.cs +++ b/Apps/Admin/Client/Components/Communications/BroadcastDialog.razor.cs @@ -17,6 +17,7 @@ namespace HealthGateway.Admin.Client.Components.Communications; using System; using System.Collections.Generic; +using System.Diagnostics.CodeAnalysis; using System.Threading.Tasks; using Fluxor; using Fluxor.Blazor.Web.Components; @@ -47,21 +48,18 @@ public partial class BroadcastDialog : FluxorComponent BroadcastActionType.ExternalLink, ]; + [SuppressMessage("Style", "IDE0072:Populate switch", Justification = "Team decision")] private Func ValidateActionUrl => urlString => { - switch (this.Broadcast.ActionType) + return this.Broadcast.ActionType switch { - case BroadcastActionType.InternalLink: - case BroadcastActionType.ExternalLink: - return urlString.StartsWith("https://", StringComparison.InvariantCultureIgnoreCase) - && Uri.TryCreate(this.ActionUrlString, UriKind.Absolute, out Uri? _) - ? null - : "URL is invalid"; - case BroadcastActionType.None: - default: - return urlString.Length == 0 ? null : "Selected Action Type does not support Action URL"; - } + BroadcastActionType.InternalLink or BroadcastActionType.ExternalLink => urlString.StartsWith("https://", StringComparison.InvariantCultureIgnoreCase) + && Uri.TryCreate(this.ActionUrlString, UriKind.Absolute, out Uri? _) + ? null + : "URL is invalid", + _ => urlString.Length == 0 ? null : "Selected Action Type does not support Action URL", + }; }; [CascadingParameter] @@ -149,14 +147,10 @@ private void RetrieveFormValues() ? null : (this.ExpiryDate.Value + this.ExpiryTime.Value).ToUniversalTime(); - if (this.ActionUrlString.Length > 0 && Uri.TryCreate(this.ActionUrlString, UriKind.Absolute, out Uri? result)) - { - this.Broadcast.ActionUrl = result; - } - else - { - this.Broadcast.ActionUrl = null; - } + this.Broadcast.ActionUrl = this.ActionUrlString.Length > 0 && + Uri.TryCreate(this.ActionUrlString, UriKind.Absolute, out Uri? result) + ? result + : null; } private void HandleClickCancel() diff --git a/Apps/Admin/Client/Components/Delegation/DelegateTable.razor.cs b/Apps/Admin/Client/Components/Delegation/DelegateTable.razor.cs index 9ffb916f0b..e0470b3c9e 100644 --- a/Apps/Admin/Client/Components/Delegation/DelegateTable.razor.cs +++ b/Apps/Admin/Client/Components/Delegation/DelegateTable.razor.cs @@ -17,6 +17,7 @@ namespace HealthGateway.Admin.Client.Components.Delegation { using System; using System.Collections.Generic; + using System.Diagnostics.CodeAnalysis; using System.Linq; using Fluxor; using Fluxor.Blazor.Web.Components; @@ -49,6 +50,7 @@ public partial class DelegateTable : FluxorComponent private IEnumerable Rows => this.Data.Select(d => new DelegateRow(d)); + [SuppressMessage("Style", "IDE0072:Populate switch", Justification = "Team decision")] private static Color GetStatusColor(DelegationStatus status) { return status switch @@ -73,11 +75,9 @@ public DelegateRow(ExtendedDelegateInfo model) this.DateOfBirth = model.Birthdate; this.PersonalHealthNumber = model.PersonalHealthNumber; this.Address = AddressUtility.GetAddressAsSingleLine(model.PhysicalAddress ?? model.PostalAddress); - this.DelegationStatus = model.DelegationStatus switch - { - DelegationStatus.Unknown => DelegationStatus.Allowed, - _ => model.DelegationStatus, - }; + this.DelegationStatus = model.DelegationStatus == DelegationStatus.Unknown + ? DelegationStatus.Allowed + : model.DelegationStatus; this.ToBeRemoved = model.StagedDelegationStatus == DelegationStatus.Disallowed; } diff --git a/Apps/Admin/Client/Components/Support/AddressConfirmationDialog.razor.cs b/Apps/Admin/Client/Components/Support/AddressConfirmationDialog.razor.cs index c52b07f695..eb1cd0309a 100644 --- a/Apps/Admin/Client/Components/Support/AddressConfirmationDialog.razor.cs +++ b/Apps/Admin/Client/Components/Support/AddressConfirmationDialog.razor.cs @@ -109,6 +109,7 @@ public partial class AddressConfirmationDialog : F private IMask? PostalCodeMask { get; set; } + [SuppressMessage("Style", "IDE0072:Populate switch", Justification = "Team decision")] private string Country { get => this.country; @@ -188,6 +189,16 @@ private static string GetCountryNameFromInput(string input) return string.Empty; } + private static string? ValidateCanadianPostalCode(string postalCode) + { + return !AddressUtility.PostalCodeRegex().IsMatch(postalCode) ? "Incomplete postal code" : null; + } + + private static string? ValidateUsPostalCode(string postalCode) + { + return !AddressUtility.ZipCodeRegex().IsMatch(postalCode) ? "Incomplete zip code" : null; + } + private void PopulateInputs(Address address) { this.AddressLines = string.Join(Environment.NewLine, address.StreetLines); @@ -211,14 +222,16 @@ private void PopulateInputs(Address address) private string GetCountryToOutput() { - if (this.SelectedCountryCode == CountryCode.CA && this.OutputCanadaAsEmptyString) - { - return string.Empty; - } + string? canadaOutput = this.SelectedCountryCode == CountryCode.CA && this.OutputCanadaAsEmptyString + ? string.Empty + : null; - return this.OutputCountryCodeFormat ? this.SelectedCountryCode.ToString() : AddressUtility.GetCountryName(this.SelectedCountryCode); + return canadaOutput ?? (this.OutputCountryCodeFormat + ? this.SelectedCountryCode.ToString() + : AddressUtility.GetCountryName(this.SelectedCountryCode)); } + [SuppressMessage("Style", "IDE0072:Populate switch", Justification = "Team decision")] private Address GetAddressModel() { return new() @@ -245,22 +258,17 @@ private void HandleCountryChanged(string value) this.OtherState = string.Empty; } + [SuppressMessage("Style", "IDE0072:Populate switch", Justification = "Team decision")] private string? ValidatePostalCode(string postalCode) { - if (string.IsNullOrWhiteSpace(postalCode)) - { - return "Required"; - } - - switch (this.SelectedCountryCode) - { - case CountryCode.CA: - return !AddressUtility.PostalCodeRegex().IsMatch(postalCode) ? "Incomplete postal code" : null; - case CountryCode.US: - return !AddressUtility.ZipCodeRegex().IsMatch(postalCode) ? "Incomplete zip code" : null; - default: - return null; - } + return string.IsNullOrWhiteSpace(postalCode) + ? "Required" + : this.SelectedCountryCode switch + { + CountryCode.CA => ValidateCanadianPostalCode(postalCode), + CountryCode.US => ValidateUsPostalCode(postalCode), + _ => null, + }; } private void HandleActionSuccess(TSuccessAction successAction) diff --git a/Apps/Admin/Client/Pages/AgentAccessPage.razor.cs b/Apps/Admin/Client/Pages/AgentAccessPage.razor.cs index 43f4c2ff30..83bab27814 100644 --- a/Apps/Admin/Client/Pages/AgentAccessPage.razor.cs +++ b/Apps/Admin/Client/Pages/AgentAccessPage.razor.cs @@ -40,17 +40,13 @@ public partial class AgentAccessPage : FluxorComponent private static Func ValidateQueryParameter => parameter => { - if (string.IsNullOrWhiteSpace(parameter)) - { - return "Search parameter is required"; - } - - if (StringManipulator.StripWhitespace(parameter).Length < 3) - { - return "Query must contain at least 3 characters"; - } + string? lengthValidationResult = StringManipulator.StripWhitespace(parameter).Length < 3 + ? "Query must contain at least 3 characters" + : null; - return null; + return string.IsNullOrWhiteSpace(parameter) + ? "Search parameter is required" + : lengthValidationResult; }; [Inject] diff --git a/Apps/Admin/Client/Pages/BetaAccessPage.razor.cs b/Apps/Admin/Client/Pages/BetaAccessPage.razor.cs index 740b70a41c..d0078745d3 100644 --- a/Apps/Admin/Client/Pages/BetaAccessPage.razor.cs +++ b/Apps/Admin/Client/Pages/BetaAccessPage.razor.cs @@ -36,17 +36,13 @@ public partial class BetaAccessPage : FluxorComponent { private static Func ValidateQueryParameter => parameter => { - if (string.IsNullOrWhiteSpace(parameter)) - { - return "Email is required"; - } - - if (!NaiveEmailValidator.IsValid(StringManipulator.StripWhitespace(parameter))) - { - return "Invalid email format"; - } + string? emailValidationResult = !NaiveEmailValidator.IsValid(StringManipulator.StripWhitespace(parameter)) + ? "Invalid email format" + : null; - return null; + return string.IsNullOrWhiteSpace(parameter) + ? "Email is required" + : emailValidationResult; }; [Inject] diff --git a/Apps/Admin/Client/Pages/DashboardPage.razor.cs b/Apps/Admin/Client/Pages/DashboardPage.razor.cs index ca22ead45c..e36cedc22e 100644 --- a/Apps/Admin/Client/Pages/DashboardPage.razor.cs +++ b/Apps/Admin/Client/Pages/DashboardPage.razor.cs @@ -134,24 +134,19 @@ private int UniqueDays } } - private IEnumerable TableData - { - get - { - return this.DailyUsageCounts.UserRegistrations.Select(x => new DailyDataRow { Date = x.Key, UserRegistrations = x.Value }) - .Concat(this.DailyUsageCounts.UserLogins.Select(x => new DailyDataRow { Date = x.Key, UserLogins = x.Value })) - .Concat(this.DailyUsageCounts.DependentRegistrations.Select(x => new DailyDataRow { Date = x.Key, DependentRegistrations = x.Value })) - .GroupBy(x => x.Date) - .Select( - g => new DailyDataRow - { - Date = g.Key, - UserRegistrations = g.Sum(x => x.UserRegistrations), - UserLogins = g.Sum(x => x.UserLogins), - DependentRegistrations = g.Sum(x => x.DependentRegistrations), - }); - } - } + private IEnumerable TableData => + this.DailyUsageCounts.UserRegistrations.Select(x => new DailyDataRow { Date = x.Key, UserRegistrations = x.Value }) + .Concat(this.DailyUsageCounts.UserLogins.Select(x => new DailyDataRow { Date = x.Key, UserLogins = x.Value })) + .Concat(this.DailyUsageCounts.DependentRegistrations.Select(x => new DailyDataRow { Date = x.Key, DependentRegistrations = x.Value })) + .GroupBy(x => x.Date) + .Select( + g => new DailyDataRow + { + Date = g.Key, + UserRegistrations = g.Sum(x => x.UserRegistrations), + UserLogins = g.Sum(x => x.UserLogins), + DependentRegistrations = g.Sum(x => x.DependentRegistrations), + }); /// protected override void OnInitialized() diff --git a/Apps/Admin/Client/Pages/DelegationPage.razor.cs b/Apps/Admin/Client/Pages/DelegationPage.razor.cs index f9121eee37..c0218c981d 100644 --- a/Apps/Admin/Client/Pages/DelegationPage.razor.cs +++ b/Apps/Admin/Client/Pages/DelegationPage.razor.cs @@ -43,17 +43,13 @@ public partial class DelegationPage : FluxorComponent private static Func ValidateQueryParameter => parameter => { - if (string.IsNullOrWhiteSpace(parameter)) - { - return "PHN is required"; - } - - if (!PhnValidator.Validate(StringManipulator.StripWhitespace(parameter)).IsValid) - { - return "Invalid PHN"; - } + string? phnValidationResult = !PhnValidator.Validate(StringManipulator.StripWhitespace(parameter)).IsValid + ? "Invalid PHN" + : null; - return null; + return string.IsNullOrWhiteSpace(parameter) + ? "PHN is required" + : phnValidationResult; }; [Inject] diff --git a/Apps/Admin/Client/Pages/LoginPage.razor.cs b/Apps/Admin/Client/Pages/LoginPage.razor.cs index d0559d13c0..50cbe960b1 100644 --- a/Apps/Admin/Client/Pages/LoginPage.razor.cs +++ b/Apps/Admin/Client/Pages/LoginPage.razor.cs @@ -16,6 +16,7 @@ namespace HealthGateway.Admin.Client.Pages; +using System; using System.Collections.Generic; using System.Threading.Tasks; using Microsoft.AspNetCore.Components; @@ -52,7 +53,29 @@ protected override async Task OnInitializedAsync() AuthenticationState authState = await this.AuthenticationStateProvider.GetAuthenticationStateAsync(); if (authState.User.Identity is { IsAuthenticated: true }) { - this.NavigationManager.NavigateTo(this.ReturnPath ?? "/", replace: true); + // Validate ReturnPath to ensure it's a safe URL + string safeReturnPath = ValidateReturnPath(this.ReturnPath); + + // Perform the navigation + this.NavigationManager.NavigateTo(safeReturnPath, true); } } + + private static string ValidateReturnPath(string? returnPath) + { + // Ensure the return path is not null or whitespace + if (!string.IsNullOrWhiteSpace(returnPath) && + Uri.TryCreate(returnPath, UriKind.Relative, out Uri? validatedUri)) + { + // Normalize the path and ensure it starts with "/" + string normalizedPath = validatedUri.ToString(); + if (normalizedPath.StartsWith('/')) + { + return normalizedPath; + } + } + + // Fallback to the default safe path + return "/"; + } } diff --git a/Apps/Admin/Client/Pages/SupportPage.razor.cs b/Apps/Admin/Client/Pages/SupportPage.razor.cs index 16f41a755c..591c9a52be 100644 --- a/Apps/Admin/Client/Pages/SupportPage.razor.cs +++ b/Apps/Admin/Client/Pages/SupportPage.razor.cs @@ -18,6 +18,7 @@ namespace HealthGateway.Admin.Client.Pages using System; using System.Collections.Generic; using System.Collections.Immutable; + using System.Diagnostics.CodeAnalysis; using System.Linq; using System.Threading.Tasks; using Fluxor; @@ -109,24 +110,8 @@ private PatientQueryType SelectedQueryType private Func ValidateQueryParameter => parameter => { - if (string.IsNullOrWhiteSpace(parameter)) - { - return "Search parameter is required"; - } - - if (this.PhnOrDependentSelected && !PhnValidator.Validate(StringManipulator.StripWhitespace(parameter)).IsValid) - { - return "Invalid PHN"; - } - - return this.SelectedQueryType switch - { - PatientQueryType.Email or PatientQueryType.Sms when StringManipulator.StripWhitespace(parameter).Length < 5 - => "Email/SMS must be minimum 5 characters", - PatientQueryType.Sms when !StringManipulator.IsPositiveNumeric(parameter) - => "SMS must contain digits only", - _ => null, - }; + string? result = ValidateParameterInput(parameter) ?? ValidatePhn(parameter, this.PhnOrDependentSelected); + return result ?? ValidateQueryType(parameter, this.SelectedQueryType); }; private AuthenticationState? AuthenticationState { get; set; } @@ -167,6 +152,31 @@ protected override async ValueTask DisposeAsyncCore(bool disposing) await base.DisposeAsyncCore(disposing); } + private static string? ValidateParameterInput(string parameter) + { + return string.IsNullOrWhiteSpace(parameter) ? "Search parameter is required" : null; + } + + private static string? ValidatePhn(string parameter, bool phnOrDependentSelected) + { + return phnOrDependentSelected && !PhnValidator.Validate(StringManipulator.StripWhitespace(parameter)).IsValid + ? "Invalid PHN" + : null; + } + + [SuppressMessage("Style", "IDE0072:Populate switch", Justification = "Team decision")] + private static string? ValidateQueryType(string parameter, PatientQueryType selectedQueryType) + { + return selectedQueryType switch + { + PatientQueryType.Email or PatientQueryType.Sms when StringManipulator.StripWhitespace(parameter).Length < 5 + => "Email/SMS must be minimum 5 characters", + PatientQueryType.Sms when !StringManipulator.IsPositiveNumeric(parameter) + => "SMS must contain digits only", + _ => null, + }; + } + private void Clear() { this.Dispatcher.Dispatch(new PatientSupportActions.ResetStateAction()); diff --git a/Apps/Admin/Client/Services/DateConversionService.cs b/Apps/Admin/Client/Services/DateConversionService.cs index e4079a4986..8ac1bec372 100644 --- a/Apps/Admin/Client/Services/DateConversionService.cs +++ b/Apps/Admin/Client/Services/DateConversionService.cs @@ -32,17 +32,8 @@ public DateTime ConvertFromUtc(DateTime utcDateTime) /// public DateTime? ConvertFromUtc(DateTime? utcDateTime, bool returnNowIfNull = false) { - if (utcDateTime != null) - { - return this.ConvertFromUtc(utcDateTime.Value); - } - - if (returnNowIfNull) - { - return this.ConvertFromUtc(DateTime.UtcNow); - } - - return null; + DateTime? dateTimeToConvert = GetDateTimeToConvert(utcDateTime, returnNowIfNull); + return dateTimeToConvert.HasValue ? this.ConvertFromUtc(dateTimeToConvert.Value) : null; } /// @@ -50,5 +41,10 @@ public string ConvertToShortFormatFromUtc(DateTime? utcDateTime, string fallback { return utcDateTime == null ? fallbackString : DateFormatter.ToShortDateAndTime(this.ConvertFromUtc(utcDateTime.Value)); } + + private static DateTime? GetDateTimeToConvert(DateTime? utcDateTime, bool returnNowIfNull) + { + return utcDateTime ?? (returnNowIfNull ? DateTime.UtcNow : null); + } } } diff --git a/Apps/Admin/Client/Utils/BreakpointUtility.cs b/Apps/Admin/Client/Utils/BreakpointUtility.cs index a5627a2728..b09cceea01 100644 --- a/Apps/Admin/Client/Utils/BreakpointUtility.cs +++ b/Apps/Admin/Client/Utils/BreakpointUtility.cs @@ -15,6 +15,7 @@ // ------------------------------------------------------------------------- namespace HealthGateway.Admin.Client.Utils { + using System.Diagnostics.CodeAnalysis; using MudBlazor; /// @@ -59,6 +60,7 @@ public static class BreakpointUtility /// A string containing the override code for the breakpoint or null if the breakpoint has no associated override /// code. /// + [SuppressMessage("Style", "IDE0072:Populate switch", Justification = "Team decision")] public static string? GetOverrideCode(this Breakpoint breakpoint) { return breakpoint switch diff --git a/Apps/Admin/Client/Utils/FormattingUtility.cs b/Apps/Admin/Client/Utils/FormattingUtility.cs index a9a322a351..0a03ef852d 100644 --- a/Apps/Admin/Client/Utils/FormattingUtility.cs +++ b/Apps/Admin/Client/Utils/FormattingUtility.cs @@ -15,6 +15,7 @@ // ------------------------------------------------------------------------- namespace HealthGateway.Admin.Client.Utils { + using System.Diagnostics.CodeAnalysis; using HealthGateway.Admin.Common.Constants; using HealthGateway.Common.Data.Constants; using HealthGateway.Common.Data.Models; @@ -55,6 +56,7 @@ public static string FormatBroadcastEnabled(bool enabled) /// /// The communication status to format. /// A string formatted for display. + [SuppressMessage("Style", "IDE0072:Populate switch", Justification = "Team decision")] public static string FormatCommunicationStatus(CommunicationStatus status) { return status switch @@ -69,6 +71,7 @@ public static string FormatCommunicationStatus(CommunicationStatus status) /// /// The communication type to format. /// A string formatted for display. + [SuppressMessage("Style", "IDE0072:Populate switch", Justification = "Team decision")] public static string FormatCommunicationType(CommunicationType? communicationType) { return communicationType switch @@ -85,6 +88,7 @@ public static string FormatCommunicationType(CommunicationType? communicationTyp /// /// The data source to format. /// A string formatted for display. + [SuppressMessage("Style", "IDE0072:Populate switch", Justification = "Team decision")] public static string FormatDataSource(DataSource dataSource) { return dataSource switch @@ -110,6 +114,7 @@ public static string FormatDataSource(DataSource dataSource) /// /// The identity provider to format. /// A string formatted for display. + [SuppressMessage("Style", "IDE0072:Populate switch", Justification = "Team decision")] public static string FormatKeycloakIdentityProvider(KeycloakIdentityProvider identityProvider) { return identityProvider switch @@ -125,6 +130,7 @@ public static string FormatKeycloakIdentityProvider(KeycloakIdentityProvider ide /// /// The patient status to format. /// A string formatted for display. + [SuppressMessage("Style", "IDE0072:Populate switch", Justification = "Team decision")] public static string FormatPatientStatus(PatientStatus status) { return status switch @@ -141,6 +147,7 @@ public static string FormatPatientStatus(PatientStatus status) /// /// The query type to format. /// A string formatted for display. + [SuppressMessage("Style", "IDE0072:Populate switch", Justification = "Team decision")] public static string FormatPatientQueryType(PatientQueryType queryType) { return queryType switch diff --git a/Apps/Admin/Client/Utils/StoreUtility.cs b/Apps/Admin/Client/Utils/StoreUtility.cs index f5f37c95f1..79fa13c6fb 100644 --- a/Apps/Admin/Client/Utils/StoreUtility.cs +++ b/Apps/Admin/Client/Utils/StoreUtility.cs @@ -48,32 +48,7 @@ public static RequestError FormatRequestError(RequestResultError? resultError) /// The generated . public static RequestError FormatRequestError(Exception? exception, RequestResultError? resultError = null) { - if (resultError is not null) - { - return new() - { - Message = resultError.ResultMessage, - Details = new() - { - { "errorCode", resultError.ErrorCode }, - { "traceId", resultError.TraceId }, - { "actionCode", resultError.ActionCodeValue ?? string.Empty }, - }, - }; - } - - if (exception is not null) - { - return new() - { - Message = exception.Message, - }; - } - - return new() - { - Message = "Unknown error", - }; + return resultError is not null ? CreateRequestError(resultError) : CreateRequestError(exception); } /// @@ -100,5 +75,27 @@ public static async Task LoadPatientSupportAction( await SessionUtility.SetSessionStorageItem(jsRuntime, SessionUtility.SupportQueryType, patientQueryType.ToString()); await SessionUtility.SetSessionStorageItem(jsRuntime, SessionUtility.SupportQueryString, patientQueryString); } + + private static RequestError CreateRequestError(RequestResultError resultError) + { + return new() + { + Message = resultError.ResultMessage, + Details = new() + { + { "errorCode", resultError.ErrorCode }, + { "traceId", resultError.TraceId }, + { "actionCode", resultError.ActionCodeValue ?? string.Empty }, + }, + }; + } + + private static RequestError CreateRequestError(Exception? exception) + { + return new() + { + Message = exception?.Message ?? "Unknown error", + }; + } } } diff --git a/Apps/Admin/Server/Controllers/SupportController.cs b/Apps/Admin/Server/Controllers/SupportController.cs index 72ddff20e3..6507f105c8 100644 --- a/Apps/Admin/Server/Controllers/SupportController.cs +++ b/Apps/Admin/Server/Controllers/SupportController.cs @@ -16,6 +16,7 @@ namespace HealthGateway.Admin.Server.Controllers { using System.Collections.Generic; + using System.Diagnostics.CodeAnalysis; using System.Security.Claims; using System.Threading; using System.Threading.Tasks; @@ -41,6 +42,7 @@ namespace HealthGateway.Admin.Server.Controllers [Route("v{version:apiVersion}/api/[controller]")] [Produces("application/json")] [Authorize(Roles = "AdminUser,AdminReviewer,SupportUser")] + [SuppressMessage("Major Code Smell", "S6960:This controller has multiple responsibilities and could be split into 2 smaller controllers", Justification = "Team decision")] public class SupportController(ICovidSupportService covidSupportService, ISupportService supportService) : ControllerBase { /// diff --git a/Apps/Admin/Server/Delegates/RestImmunizationAdminDelegate.cs b/Apps/Admin/Server/Delegates/RestImmunizationAdminDelegate.cs index a730eed8bf..8f8571b470 100644 --- a/Apps/Admin/Server/Delegates/RestImmunizationAdminDelegate.cs +++ b/Apps/Admin/Server/Delegates/RestImmunizationAdminDelegate.cs @@ -17,6 +17,7 @@ namespace HealthGateway.Admin.Server.Delegates { using System; using System.Diagnostics; + using System.Diagnostics.CodeAnalysis; using System.Linq; using System.Threading; using System.Threading.Tasks; @@ -47,6 +48,7 @@ public class RestImmunizationAdminDelegate( private static ActivitySource ActivitySource { get; } = new(typeof(RestImmunizationAdminDelegate).FullName); /// + [SuppressMessage("Style", "IDE0046:Simplify 'if' statement", Justification = "Team decision")] public async Task GetVaccineDetailsWithRetriesAsync(string phn, string accessToken, bool refresh = false, CancellationToken ct = default) { using Activity? activity = ActivitySource.StartActivity(); diff --git a/Apps/Admin/Server/Delegates/RestVaccineStatusDelegate.cs b/Apps/Admin/Server/Delegates/RestVaccineStatusDelegate.cs index fe9bce50c4..1fc9d4699f 100644 --- a/Apps/Admin/Server/Delegates/RestVaccineStatusDelegate.cs +++ b/Apps/Admin/Server/Delegates/RestVaccineStatusDelegate.cs @@ -17,6 +17,7 @@ namespace HealthGateway.Admin.Server.Delegates { using System; using System.Diagnostics; + using System.Diagnostics.CodeAnalysis; using System.Threading; using System.Threading.Tasks; using HealthGateway.Admin.Server.Api; @@ -42,6 +43,7 @@ public class RestVaccineStatusDelegate( private static ActivitySource ActivitySource { get; } = new(typeof(RestVaccineStatusDelegate).FullName); /// + [SuppressMessage("Style", "IDE0046:Simplify 'if' statement", Justification = "Team decision")] public async Task> GetVaccineStatusWithRetriesAsync(string phn, DateTime dateOfBirth, string accessToken, CancellationToken ct = default) { using Activity? activity = ActivitySource.StartActivity(); diff --git a/Apps/Admin/Server/MapProfiles/BetaFeatureProfile.cs b/Apps/Admin/Server/MapProfiles/BetaFeatureProfile.cs index 7846c95273..495a23902a 100644 --- a/Apps/Admin/Server/MapProfiles/BetaFeatureProfile.cs +++ b/Apps/Admin/Server/MapProfiles/BetaFeatureProfile.cs @@ -16,12 +16,14 @@ namespace HealthGateway.Admin.Server.MapProfiles { using System; + using System.Diagnostics.CodeAnalysis; using AutoMapper; using HealthGateway.Admin.Common.Constants; /// /// An AutoMapper profile class which defines mapping between DB and UI Models. /// + [SuppressMessage("Style", "IDE0072:Populate switch", Justification = "Team decision")] public class BetaFeatureProfile : Profile { /// diff --git a/Apps/Admin/Server/Services/AdminReportService.cs b/Apps/Admin/Server/Services/AdminReportService.cs index bfb65f6fb2..5557b89437 100644 --- a/Apps/Admin/Server/Services/AdminReportService.cs +++ b/Apps/Admin/Server/Services/AdminReportService.cs @@ -67,7 +67,7 @@ public async Task> GetBlockedAccessReportAsync( IList records = await blockedAccessDelegate.GetAllAsync(ct); return records .Where(r => r.DataSources.Count > 0) - .Select(r => new BlockedAccessRecord(r.Hdid, r.DataSources.ToList())); + .Select(r => new BlockedAccessRecord(r.Hdid, [.. r.DataSources])); } } } diff --git a/Apps/Admin/Server/Services/CovidSupportService.cs b/Apps/Admin/Server/Services/CovidSupportService.cs index af1d612b26..8805488698 100644 --- a/Apps/Admin/Server/Services/CovidSupportService.cs +++ b/Apps/Admin/Server/Services/CovidSupportService.cs @@ -16,6 +16,7 @@ namespace HealthGateway.Admin.Server.Services { using System; + using System.Diagnostics.CodeAnalysis; using System.Threading; using System.Threading.Tasks; using HealthGateway.AccountDataAccess.Patient; @@ -89,15 +90,10 @@ private async Task GetPatientAsync(string phn, CancellationToken c private async Task GetVaccineStatusResultAsync(string phn, DateTime birthdate, string accessToken, CancellationToken ct) { PhsaResult phsaResult = await vaccineStatusDelegate.GetVaccineStatusWithRetriesAsync(phn, birthdate, accessToken, ct); - - if (phsaResult.Result == null) - { - throw new NotFoundException(ErrorMessages.CannotGetVaccineStatus); - } - - return phsaResult.Result; + return phsaResult.Result ?? throw new NotFoundException(ErrorMessages.CannotGetVaccineStatus); } + [SuppressMessage("Style", "IDE0046:Simplify 'if' statement", Justification = "Team decision")] private VaccinationStatus GetVaccinationStatus(VaccineStatusResult result) { logger.LogDebug("Vaccination Status Indicator: {VaccinationStatusIndicator}", result.StatusIndicator); @@ -118,6 +114,7 @@ VaccineState.NotFound or VaccineState.DataMismatch or VaccineState.Threshold or }; } + [SuppressMessage("Style", "IDE0046:Simplify 'if' statement", Justification = "Team decision")] private async Task GetVaccineProofAsync(VaccinationStatus vaccinationStatus, string qrCode, CancellationToken ct) { VaccineProofRequest request = new() @@ -127,6 +124,7 @@ private async Task GetVaccineProofAsync(VaccinationStatus }; RequestResult vaccineProof = await vaccineProofDelegate.GenerateAsync(this.vaccineCardConfig.PrintTemplate, request, ct); + if (vaccineProof.ResultStatus != ResultType.Success || vaccineProof.ResourcePayload == null) { throw new NotFoundException(vaccineProof.ResultError?.ResultMessage ?? ErrorMessages.CannotGetVaccineProof); diff --git a/Apps/Admin/Server/Services/DelegationService.cs b/Apps/Admin/Server/Services/DelegationService.cs index 6fecc38713..510c480b7b 100644 --- a/Apps/Admin/Server/Services/DelegationService.cs +++ b/Apps/Admin/Server/Services/DelegationService.cs @@ -17,6 +17,7 @@ namespace HealthGateway.Admin.Server.Services { using System; using System.Collections.Generic; + using System.Diagnostics.CodeAnalysis; using System.Linq; using System.Threading; using System.Threading.Tasks; @@ -211,13 +212,7 @@ public async Task ProtectDependentAsync(string dependentHdid, IEnum public async Task UnprotectDependentAsync(string dependentHdid, string reason, CancellationToken ct = default) { string authenticatedUserId = authenticationDelegate.FetchAuthenticatedUserId() ?? UserId.DefaultUser; - Dependent? dependent = await delegationDelegate.GetDependentAsync(dependentHdid, true, ct); - - if (dependent == null) - { - throw new NotFoundException($"Dependent not found for hdid: {dependentHdid}"); - } - + Dependent dependent = await delegationDelegate.GetDependentAsync(dependentHdid, true, ct) ?? throw new NotFoundException($"Dependent not found for hdid: {dependentHdid}"); dependent.Protected = false; dependent.UpdatedBy = authenticatedUserId; dependent.AllowedDelegations = []; @@ -253,6 +248,7 @@ public async Task UnprotectDependentAsync(string dependentHdid, str return mappingService.MapToAgentAction(agentAudit); } + [SuppressMessage("Style", "IDE0010:Populate switch", Justification = "Team decision")] private static void ValidatePatientResult(RequestResult patientResult) { switch (patientResult) diff --git a/Apps/Admin/Server/Services/InactiveUserService.cs b/Apps/Admin/Server/Services/InactiveUserService.cs index 7b8d872fe2..3e4e5e6cc6 100644 --- a/Apps/Admin/Server/Services/InactiveUserService.cs +++ b/Apps/Admin/Server/Services/InactiveUserService.cs @@ -158,19 +158,17 @@ private void PopulateUserDetails(List inactiveUsers, List< private void AddInactiveUser( List inactiveUsers, IEnumerable activeUserProfiles, - ICollection identityAccessUsers, + List identityAccessUsers, IdentityAccessRole role) { this.logger.LogDebug("Keycloak {Role} count: {Count}...", role, identityAccessUsers.Count); // Filter identities from keycloak where inactive (database) user's username does not match keycloak user's username // and active (database) user's username does not match keycloak users username - IEnumerable adminUserProfiles = identityAccessUsers - .Where(x1 => inactiveUsers.TrueForAll(x2 => x1.Username != x2.Username) && activeUserProfiles.All(x2 => x1.Username != x2.Username)) - .Select(user => this.mappingService.MapToAdminUserProfileView(user)); - - foreach (AdminUserProfileView adminUserProfile in adminUserProfiles) + foreach (UserRepresentation user in identityAccessUsers + .Where(x1 => inactiveUsers.TrueForAll(x2 => x1.Username != x2.Username) && activeUserProfiles.All(x2 => x1.Username != x2.Username))) { + AdminUserProfileView adminUserProfile = this.mappingService.MapToAdminUserProfileView(user); adminUserProfile.RealmRoles = role.ToString(); inactiveUsers.Add(adminUserProfile); } diff --git a/Apps/Admin/Server/Services/SupportService.cs b/Apps/Admin/Server/Services/SupportService.cs index 5116da1ef7..a3532eb19b 100644 --- a/Apps/Admin/Server/Services/SupportService.cs +++ b/Apps/Admin/Server/Services/SupportService.cs @@ -17,6 +17,7 @@ namespace HealthGateway.Admin.Server.Services { using System; using System.Collections.Generic; + using System.Diagnostics.CodeAnalysis; using System.Globalization; using System.Linq; using System.Threading; @@ -72,16 +73,11 @@ public async Task GetPatientSupportDetailsAsync( PatientSupportDetailsQuery query, CancellationToken ct = default) { - PatientModel patient; - - if (query.QueryType == ClientRegistryType.Hdid) - { - patient = await this.GetPatientAsync(new(Hdid: query.QueryParameter, Source: PatientDetailSource.All, UseCache: false), ct); - } - else - { - patient = await this.GetPatientAsync(new(query.QueryParameter, Source: PatientDetailSource.Empi, UseCache: false), ct); - } + PatientModel patient = await this.GetPatientAsync( + query.QueryType == ClientRegistryType.Hdid + ? new(Hdid: query.QueryParameter, Source: PatientDetailSource.All, UseCache: false) + : new(query.QueryParameter, Source: PatientDetailSource.Empi, UseCache: false), + ct); Task? getVaccineDetails = query.IncludeCovidDetails ? this.GetVaccineDetailsAsync(patient, query.RefreshVaccineDetails, ct) : null; @@ -109,6 +105,7 @@ public async Task GetPatientSupportDetailsAsync( } /// + [SuppressMessage("Style", "IDE0072:Populate switch", Justification = "Team decision")] public async Task> GetPatientsAsync(PatientQueryType queryType, string queryString, CancellationToken ct = default) { if (queryType is PatientQueryType.Hdid or PatientQueryType.Phn) @@ -206,6 +203,7 @@ private async Task> GetAllDependentInfo return dependentInfo; } + [SuppressMessage("Style", "IDE0046:'if' statement can be simplified", Justification = "Team decision")] private async Task GetVaccineDetailsAsync(PatientModel patient, bool refresh, CancellationToken ct) { if (string.IsNullOrEmpty(patient.Phn) || patient.Birthdate == DateTime.MinValue) @@ -233,12 +231,9 @@ private async Task GetAccessTokenAsync(CancellationToken ct) ? null : await userProfileDelegate.GetUserProfileAsync(hdid, ct: ct); - if (patient == null && profile == null) - { - return null; - } - - return mappingService.MapToPatientSupportResult(patient, profile); + return patient == null && profile == null + ? null + : mappingService.MapToPatientSupportResult(patient, profile); } private async Task GetPatientSupportResultAsync(UserProfile profile, CancellationToken ct) diff --git a/Apps/Admin/Server/Services/UserFeedbackService.cs b/Apps/Admin/Server/Services/UserFeedbackService.cs index 0dd46e44f6..715bc5b134 100644 --- a/Apps/Admin/Server/Services/UserFeedbackService.cs +++ b/Apps/Admin/Server/Services/UserFeedbackService.cs @@ -103,7 +103,7 @@ public async Task>> GetAllTagsAsync(Cancellati { IEnumerable adminTags = await adminTagDelegate.GetAllAsync(ct); - IList adminTagViews = adminTags.Select(mappingService.MapToAdminTagView).ToList(); + List adminTagViews = adminTags.Select(mappingService.MapToAdminTagView).ToList(); return new RequestResult> { diff --git a/Apps/Admin/Tests/Delegates/RestImmunizationAdminDelegateTests.cs b/Apps/Admin/Tests/Delegates/RestImmunizationAdminDelegateTests.cs index f038f49062..72f1f7b2ba 100644 --- a/Apps/Admin/Tests/Delegates/RestImmunizationAdminDelegateTests.cs +++ b/Apps/Admin/Tests/Delegates/RestImmunizationAdminDelegateTests.cs @@ -17,7 +17,6 @@ namespace HealthGateway.Admin.Tests.Delegates { using System; using System.Collections.Generic; - using System.Linq; using System.Threading; using System.Threading.Tasks; using HealthGateway.Admin.Common.Models.CovidSupport; @@ -190,7 +189,7 @@ private static IConfigurationRoot GetIConfigurationRoot() }; return new ConfigurationBuilder() - .AddInMemoryCollection(myConfiguration.ToList()) + .AddInMemoryCollection(myConfiguration) .Build(); } } diff --git a/Apps/Admin/Tests/Delegates/RestVaccineStatusDelegateTests.cs b/Apps/Admin/Tests/Delegates/RestVaccineStatusDelegateTests.cs index 44b99821a8..3650b33e1d 100644 --- a/Apps/Admin/Tests/Delegates/RestVaccineStatusDelegateTests.cs +++ b/Apps/Admin/Tests/Delegates/RestVaccineStatusDelegateTests.cs @@ -18,7 +18,6 @@ namespace HealthGateway.Admin.Tests.Delegates using System; using System.Collections.Generic; using System.Globalization; - using System.Linq; using System.Threading; using System.Threading.Tasks; using HealthGateway.Admin.Server.Api; @@ -151,7 +150,7 @@ private static IConfigurationRoot GetIConfigurationRoot() }; return new ConfigurationBuilder() - .AddInMemoryCollection(myConfiguration.ToList()) + .AddInMemoryCollection(myConfiguration) .Build(); } } diff --git a/Apps/Admin/Tests/Services/AdminReportServiceTests.cs b/Apps/Admin/Tests/Services/AdminReportServiceTests.cs index e936245072..4a3b633196 100644 --- a/Apps/Admin/Tests/Services/AdminReportServiceTests.cs +++ b/Apps/Admin/Tests/Services/AdminReportServiceTests.cs @@ -132,9 +132,9 @@ private static IAdminReportService GetAdminReportService( Mock? blockedAccessDelegateMock = null, Mock? patientRepositoryMock = null) { - delegationDelegateMock = delegationDelegateMock ?? new(); - blockedAccessDelegateMock = blockedAccessDelegateMock ?? new(); - patientRepositoryMock = patientRepositoryMock ?? new(); + delegationDelegateMock ??= new(); + blockedAccessDelegateMock ??= new(); + patientRepositoryMock ??= new(); return new AdminReportService( delegationDelegateMock.Object, diff --git a/Apps/Admin/Tests/Services/AgentAccessServiceTests.cs b/Apps/Admin/Tests/Services/AgentAccessServiceTests.cs index a2932a574e..fb26107b29 100644 --- a/Apps/Admin/Tests/Services/AgentAccessServiceTests.cs +++ b/Apps/Admin/Tests/Services/AgentAccessServiceTests.cs @@ -236,8 +236,8 @@ private static IAgentAccessService GetAgentAccessService( Mock? authenticationDelegateMock = null, Mock? keycloakAdminApiMock = null) { - authenticationDelegateMock = authenticationDelegateMock ?? new(); - keycloakAdminApiMock = keycloakAdminApiMock ?? new(); + authenticationDelegateMock ??= new(); + keycloakAdminApiMock ??= new(); return new AgentAccessService( authenticationDelegateMock.Object, diff --git a/Apps/Admin/Tests/Services/BetaFeatureServiceTests.cs b/Apps/Admin/Tests/Services/BetaFeatureServiceTests.cs index 0a046aec2f..2bb53fa52f 100644 --- a/Apps/Admin/Tests/Services/BetaFeatureServiceTests.cs +++ b/Apps/Admin/Tests/Services/BetaFeatureServiceTests.cs @@ -285,7 +285,7 @@ private static IConfigurationRoot GetIConfigurationRoot() }; return new ConfigurationBuilder() - .AddInMemoryCollection(myConfiguration.ToList()) + .AddInMemoryCollection(myConfiguration) .Build(); } @@ -358,8 +358,8 @@ private static IBetaFeatureService GetBetaFeatureService( Mock? profileDelegateMock = null, Mock? betaFeatureAccessDelegateMock = null) { - profileDelegateMock = profileDelegateMock ?? new(); - betaFeatureAccessDelegateMock = betaFeatureAccessDelegateMock ?? new(); + profileDelegateMock ??= new(); + betaFeatureAccessDelegateMock ??= new(); return new BetaFeatureService( profileDelegateMock.Object, diff --git a/Apps/Admin/Tests/Services/CommunicationServiceTests.cs b/Apps/Admin/Tests/Services/CommunicationServiceTests.cs index e2abb9d618..673280fe77 100644 --- a/Apps/Admin/Tests/Services/CommunicationServiceTests.cs +++ b/Apps/Admin/Tests/Services/CommunicationServiceTests.cs @@ -17,7 +17,6 @@ namespace HealthGateway.Admin.Tests.Services { using System; using System.Collections.Generic; - using System.Linq; using System.Threading; using System.Threading.Tasks; using DeepEqual.Syntax; @@ -306,7 +305,7 @@ private static IConfigurationRoot GetIConfigurationRoot() }; return new ConfigurationBuilder() - .AddInMemoryCollection(myConfiguration.ToList()) + .AddInMemoryCollection(myConfiguration) .Build(); } } diff --git a/Apps/Admin/Tests/Services/ConfigurationServiceTests.cs b/Apps/Admin/Tests/Services/ConfigurationServiceTests.cs index 8908934415..cfbe7410ae 100644 --- a/Apps/Admin/Tests/Services/ConfigurationServiceTests.cs +++ b/Apps/Admin/Tests/Services/ConfigurationServiceTests.cs @@ -16,7 +16,6 @@ namespace HealthGateway.Admin.Tests.Services { using System.Collections.Generic; - using System.Linq; using HealthGateway.Admin.Common.Models; using HealthGateway.Admin.Server.Services; using Microsoft.Extensions.Configuration; @@ -61,7 +60,7 @@ private static IConfigurationRoot GetIConfigurationRoot() }; return new ConfigurationBuilder() - .AddInMemoryCollection(myConfiguration.ToList()) + .AddInMemoryCollection(myConfiguration) .Build(); } } diff --git a/Apps/Admin/Tests/Services/CovidSupportServiceTests.cs b/Apps/Admin/Tests/Services/CovidSupportServiceTests.cs index 4a7a48ba36..8291367e69 100644 --- a/Apps/Admin/Tests/Services/CovidSupportServiceTests.cs +++ b/Apps/Admin/Tests/Services/CovidSupportServiceTests.cs @@ -18,7 +18,6 @@ namespace HealthGateway.Admin.Tests.Services using System; using System.Collections.Generic; using System.Globalization; - using System.Linq; using System.Threading; using System.Threading.Tasks; using HealthGateway.AccountDataAccess.Patient; @@ -553,7 +552,7 @@ private static MailDocumentRequest GenerateMailDocumentRequest() PersonalHealthNumber = Phn, MailAddress = new() { - StreetLines = new[] { "9105 ROTTERDAM PLACE" }, + StreetLines = ["9105 ROTTERDAM PLACE"], City = "VANCOUVER", Country = string.Empty, PostalCode = "V3X 4J5", @@ -659,7 +658,7 @@ private static IConfigurationRoot GetIConfigurationRoot() }; return new ConfigurationBuilder() - .AddInMemoryCollection(myConfiguration.ToList()) + .AddInMemoryCollection(myConfiguration) .Build(); } } diff --git a/Apps/Admin/Tests/Services/CsvExportServiceTests.cs b/Apps/Admin/Tests/Services/CsvExportServiceTests.cs index 5024f0898f..bce1209951 100644 --- a/Apps/Admin/Tests/Services/CsvExportServiceTests.cs +++ b/Apps/Admin/Tests/Services/CsvExportServiceTests.cs @@ -19,7 +19,6 @@ namespace HealthGateway.Admin.Tests.Services using System; using System.Collections.Generic; using System.IO; - using System.Linq; using System.Threading; using System.Threading.Tasks; using DeepEqual.Syntax; @@ -354,7 +353,7 @@ private static IConfigurationRoot GetIConfigurationRoot() }; return new ConfigurationBuilder() - .AddInMemoryCollection(myConfiguration.ToList()) + .AddInMemoryCollection(myConfiguration) .Build(); } @@ -366,12 +365,12 @@ private static ICsvExportService GetCsvExportService( Mock? inactiveUserServiceMock = null, Mock? feedbackDelegateMock = null) { - profileDelegateMock = profileDelegateMock ?? new(); - commentDelegateMock = commentDelegateMock ?? new(); - noteDelegateMock = noteDelegateMock ?? new(); - ratingDelegateMock = ratingDelegateMock ?? new(); - inactiveUserServiceMock = inactiveUserServiceMock ?? new(); - feedbackDelegateMock = feedbackDelegateMock ?? new(); + profileDelegateMock ??= new(); + commentDelegateMock ??= new(); + noteDelegateMock ??= new(); + ratingDelegateMock ??= new(); + inactiveUserServiceMock ??= new(); + feedbackDelegateMock ??= new(); return new CsvExportService( Configuration, diff --git a/Apps/Admin/Tests/Services/DashboardServiceTests.cs b/Apps/Admin/Tests/Services/DashboardServiceTests.cs index 3e437db5ac..8e20a3ff6c 100644 --- a/Apps/Admin/Tests/Services/DashboardServiceTests.cs +++ b/Apps/Admin/Tests/Services/DashboardServiceTests.cs @@ -17,7 +17,6 @@ namespace HealthGateway.Admin.Tests.Services { using System; using System.Collections.Generic; - using System.Linq; using System.Threading; using System.Threading.Tasks; using DeepEqual.Syntax; @@ -55,7 +54,7 @@ public async Task ShouldGetAllTimeCounts() Dependents = dependentCount, }; - IDashboardService service = SetupGetAllTimeCountsMock(userProfileCount, closedUserProfileCount, dependentCount); + IDashboardService service = SetupDashboardServiceForAllTimeCounts(userProfileCount, closedUserProfileCount, dependentCount); // Act AllTimeCounts actual = await service.GetAllTimeCountsAsync(); @@ -104,7 +103,7 @@ public async Task ShouldGetDailyUsageCounts() DependentRegistrations = new SortedDictionary(dependentRegistrationCounts), }; - IDashboardService service = SetupDailyUsageCountsMock(userRegistrationCounts, userLoginCounts, dependentRegistrationCounts); + IDashboardService service = SetupDashboardServiceForDailyUsageCounts(userRegistrationCounts, userLoginCounts, dependentRegistrationCounts); // Act DailyUsageCounts actual = await service.GetDailyUsageCountsAsync(startDate, endDate); @@ -128,7 +127,7 @@ public async Task ShouldGetRecurringUserCount() const int userCount = 10; const int expected = 10; - IDashboardService service = SetupGetRecurringUserCountMock(dayCount, userCount); + IDashboardService service = SetupDashboardServiceForRecurringUserCount(dayCount, userCount); // Act int actual = await service.GetRecurringUserCountAsync(dayCount, startDate, endDate); @@ -156,7 +155,7 @@ public async Task ShouldGetAppLoginCounts() AppLoginCounts expected = new(webCount, mobileCount + androidCount + iosCount, androidCount, iosCount, salesforceCount); - IDashboardService service = SetupGetAppLoginCountsMock(webCount, mobileCount, androidCount, iosCount, salesforceCount); + IDashboardService service = SetupDashboardServiceForAppLoginCounts(webCount, mobileCount, androidCount, iosCount, salesforceCount); // Act AppLoginCounts actual = await service.GetAppLoginCountsAsync(startDate, endDate); @@ -185,7 +184,7 @@ public async Task ShouldGetRatingsSummary() { "5", fiveStarCount }, }; - IDashboardService service = SetupGetRatingsSummaryMock(threeStarCount, fiveStarCount); + IDashboardService service = SetupDashboardServiceForRatingsSummary(threeStarCount, fiveStarCount); // Act IDictionary actual = await service.GetRatingsSummaryAsync(startDate, endDate); @@ -206,8 +205,9 @@ public async Task ShouldGetAgeCounts() DateOnly startDatePlus5Years = startDate.AddYears(5); DateOnly endDate = new(2024, 1, 15); - const int startDateAge = 14; - const int startDatePlus5YearsAge = 9; + int currentYear = DateTime.UtcNow.Year; + int startDateAge = currentYear - startDate.Year; + int startDatePlus5YearsAge = currentYear - startDatePlus5Years.Year; const int startDateAgeCount = 5; const int startDatePlus5YearsAgeCount = 1; @@ -217,7 +217,7 @@ public async Task ShouldGetAgeCounts() { startDatePlus5YearsAge, startDatePlus5YearsAgeCount }, }; - IDashboardService service = SetupGetAgeCountsMock(startDate, startDatePlus5Years, startDateAgeCount, startDatePlus5YearsAgeCount); + IDashboardService service = SetupDashboardServiceForAgeCounts(startDate, startDatePlus5Years, startDateAgeCount, startDatePlus5YearsAgeCount); // Act IDictionary actual = await service.GetAgeCountsAsync(startDate, endDate); @@ -235,7 +235,7 @@ private static IConfigurationRoot GetIConfigurationRoot() }; return new ConfigurationBuilder() - .AddInMemoryCollection(myConfiguration.ToList()) + .AddInMemoryCollection(myConfiguration) .Build(); } @@ -255,7 +255,7 @@ private static IDashboardService GetDashboardService( ratingDelegateMock.Object); } - private static IDashboardService SetupGetAllTimeCountsMock(int userProfileCount, int closedUserProfileCount, int dependentCount) + private static IDashboardService SetupDashboardServiceForAllTimeCounts(int userProfileCount, int closedUserProfileCount, int dependentCount) { Mock userProfileDelegateMock = new(); userProfileDelegateMock.Setup(s => s.GetUserProfileCountAsync(It.IsAny())).ReturnsAsync(userProfileCount); @@ -267,7 +267,7 @@ private static IDashboardService SetupGetAllTimeCountsMock(int userProfileCount, return GetDashboardService(dependentDelegateMock, userProfileDelegateMock); } - private static IDashboardService SetupDailyUsageCountsMock( + private static IDashboardService SetupDashboardServiceForDailyUsageCounts( IDictionary userRegistrationCounts, IDictionary userLoginCounts, IDictionary dependentRegistrationCounts) @@ -284,7 +284,7 @@ private static IDashboardService SetupDailyUsageCountsMock( return GetDashboardService(dependentDelegateMock, userProfileDelegateMock); } - private static IDashboardService SetupGetRecurringUserCountMock(int dayCount, int userCount) + private static IDashboardService SetupDashboardServiceForRecurringUserCount(int dayCount, int userCount) { Mock userProfileDelegateMock = new(); userProfileDelegateMock.Setup(s => s.GetRecurringUserCountAsync(dayCount, It.IsAny(), It.IsAny(), It.IsAny())) @@ -293,7 +293,7 @@ private static IDashboardService SetupGetRecurringUserCountMock(int dayCount, in return GetDashboardService(userProfileDelegateMock: userProfileDelegateMock); } - private static IDashboardService SetupGetAppLoginCountsMock(int webCount, int mobileCount, int androidCount, int iosCount, int salesforceCount) + private static IDashboardService SetupDashboardServiceForAppLoginCounts(int webCount, int mobileCount, int androidCount, int iosCount, int salesforceCount) { IDictionary lastLoginClientCounts = new Dictionary { @@ -311,7 +311,7 @@ private static IDashboardService SetupGetAppLoginCountsMock(int webCount, int mo return GetDashboardService(userProfileDelegateMock: userProfileDelegateMock); } - private static IDashboardService SetupGetRatingsSummaryMock(int threeStarCount, int fiveStarCount) + private static IDashboardService SetupDashboardServiceForRatingsSummary(int threeStarCount, int fiveStarCount) { IDictionary summary = new Dictionary { @@ -326,7 +326,7 @@ private static IDashboardService SetupGetRatingsSummaryMock(int threeStarCount, return GetDashboardService(ratingDelegateMock: ratingsDelegateMock); } - private static IDashboardService SetupGetAgeCountsMock(DateOnly startDate, DateOnly startDatePlus5Years, int startDateAgeCount, int startDatePlus5YearsAgeCount) + private static IDashboardService SetupDashboardServiceForAgeCounts(DateOnly startDate, DateOnly startDatePlus5Years, int startDateAgeCount, int startDatePlus5YearsAgeCount) { IDictionary yearOfBirthCounts = new Dictionary { diff --git a/Apps/Admin/Tests/Services/DelegationServiceTests.cs b/Apps/Admin/Tests/Services/DelegationServiceTests.cs index d8e56c59ae..9405e82803 100644 --- a/Apps/Admin/Tests/Services/DelegationServiceTests.cs +++ b/Apps/Admin/Tests/Services/DelegationServiceTests.cs @@ -575,7 +575,7 @@ private static IConfigurationRoot GetIConfigurationRoot(bool isChangeFeedEnabled }; return new ConfigurationBuilder() - .AddInMemoryCollection(myConfiguration.ToList()) + .AddInMemoryCollection(myConfiguration) .Build(); } @@ -844,7 +844,7 @@ private static DelegationService GetDelegationService( delegationDelegate.Setup(p => p.GetDependentAsync(resourceOwnerHdid, true, CancellationToken.None)).ReturnsAsync(dependent); - messageSender = messageSender ?? new(); + messageSender ??= new(); return new( GetIConfigurationRoot(isChangeFeedEnabled), diff --git a/Apps/Admin/Tests/Services/InactiveUserServiceTests.cs b/Apps/Admin/Tests/Services/InactiveUserServiceTests.cs index 1d01043b7d..c350f85a2d 100644 --- a/Apps/Admin/Tests/Services/InactiveUserServiceTests.cs +++ b/Apps/Admin/Tests/Services/InactiveUserServiceTests.cs @@ -17,7 +17,6 @@ namespace HealthGateway.Admin.Tests.Services { using System; using System.Collections.Generic; - using System.Linq; using System.Net; using System.Threading; using System.Threading.Tasks; @@ -234,7 +233,7 @@ private static IConfigurationRoot GetIConfigurationRoot() }; return new ConfigurationBuilder() - .AddInMemoryCollection(myConfiguration.ToList()) + .AddInMemoryCollection(myConfiguration) .Build(); } diff --git a/Apps/Admin/Tests/Services/SupportServiceTests.cs b/Apps/Admin/Tests/Services/SupportServiceTests.cs index db34f02820..81bfd60a1b 100644 --- a/Apps/Admin/Tests/Services/SupportServiceTests.cs +++ b/Apps/Admin/Tests/Services/SupportServiceTests.cs @@ -148,11 +148,11 @@ public async Task ShouldGetPatientSupportDetails( IList messagingVerifications = GenerateMessagingVerifications(SmsNumber, Email); VaccineDetails vaccineDetails = GenerateVaccineDetails(GenerateVaccineDose()); AgentAuditQuery auditQuery = new(Hdid); - IEnumerable agentAudits = new[] { GenerateAgentAudit() }; - IEnumerable blockedDataSources = new[] - { + IEnumerable agentAudits = [GenerateAgentAudit()]; + IEnumerable blockedDataSources = + [ DataSource.Immunization, - }; + ]; ResourceDelegateQuery resourceDelegateQuery = new() { ByDelegateHdid = patientQuery.Hdid, IncludeDependent = true }; ResourceDelegateQueryResult resourceDelegateQueryResult = GenerateResourceDelegatesForDelegate(patientQuery.Hdid, [Hdid2]); PatientDetailsQuery dependentPatientQuery = diff --git a/Apps/Admin/Tests/Services/UserFeedbackServiceTests.cs b/Apps/Admin/Tests/Services/UserFeedbackServiceTests.cs index 2bab6a132c..ac5b54604b 100644 --- a/Apps/Admin/Tests/Services/UserFeedbackServiceTests.cs +++ b/Apps/Admin/Tests/Services/UserFeedbackServiceTests.cs @@ -429,7 +429,7 @@ private static IConfigurationRoot GetIConfigurationRoot() }; return new ConfigurationBuilder() - .AddInMemoryCollection(myConfiguration.ToList()) + .AddInMemoryCollection(myConfiguration) .Build(); } @@ -438,9 +438,9 @@ private static IUserFeedbackService GetUserFeedbackService( Mock? adminTagDelegateMock = null, Mock? userProfileDelegateMock = null) { - feedbackDelegateMock = feedbackDelegateMock ?? new(); - adminTagDelegateMock = adminTagDelegateMock ?? new(); - userProfileDelegateMock = userProfileDelegateMock ?? new(); + feedbackDelegateMock ??= new(); + adminTagDelegateMock ??= new(); + userProfileDelegateMock ??= new(); return new UserFeedbackService( new Mock>().Object, diff --git a/Apps/ClinicalDocument/src/Services/ClinicalDocumentService.cs b/Apps/ClinicalDocument/src/Services/ClinicalDocumentService.cs index 011498d0d7..accbae24a5 100644 --- a/Apps/ClinicalDocument/src/Services/ClinicalDocumentService.cs +++ b/Apps/ClinicalDocument/src/Services/ClinicalDocumentService.cs @@ -94,7 +94,7 @@ public async Task>> GetRecords this.logger.LogDebug("Retrieving clinical documents"); PhsaHealthDataResponse apiResponse = await this.clinicalDocumentsApi.GetClinicalDocumentRecordsAsync(pid, ct); - IList clinicalDocuments = apiResponse.Data.Select(this.mappingService.MapToClinicalDocumentRecord).ToList(); + List clinicalDocuments = apiResponse.Data.Select(this.mappingService.MapToClinicalDocumentRecord).ToList(); requestResult.ResultStatus = ResultType.Success; requestResult.ResourcePayload = clinicalDocuments; requestResult.TotalResultCount = clinicalDocuments.Count; diff --git a/Apps/Common/src/AccessManagement/Authentication/AuthenticationDelegate.cs b/Apps/Common/src/AccessManagement/Authentication/AuthenticationDelegate.cs index 108201b41f..04f49fda08 100644 --- a/Apps/Common/src/AccessManagement/Authentication/AuthenticationDelegate.cs +++ b/Apps/Common/src/AccessManagement/Authentication/AuthenticationDelegate.cs @@ -217,13 +217,13 @@ private async Task GetSystemTokenAsync(ClientCredentialsRequest reques private async Task ClientCredentialsGrantAsync(ClientCredentialsRequest request, CancellationToken ct) { ClientCredentialsRequestParameters parameters = request.Parameters; - IEnumerable> oauthParams = new[] - { - new KeyValuePair("client_id", parameters.ClientId), - new KeyValuePair("client_secret", parameters.ClientSecret), - new KeyValuePair("audience", parameters.Audience), - new KeyValuePair("grant_type", "client_credentials"), - }; + IEnumerable> oauthParams = + [ + new("client_id", parameters.ClientId), + new("client_secret", parameters.ClientSecret), + new("audience", parameters.Audience), + new("grant_type", "client_credentials"), + ]; using FormUrlEncodedContent content = new(oauthParams); return await this.AuthenticateAsync(request.TokenUri, content, ct); } diff --git a/Apps/Common/src/AspNetConfiguration/Modules/Audit.cs b/Apps/Common/src/AspNetConfiguration/Modules/Audit.cs index a8866df15d..46329d6ab2 100644 --- a/Apps/Common/src/AspNetConfiguration/Modules/Audit.cs +++ b/Apps/Common/src/AspNetConfiguration/Modules/Audit.cs @@ -37,7 +37,7 @@ public static class Audit /// The configuration to use. public static void ConfigureAuditServices(IServiceCollection services, ILogger logger, IConfiguration configuration) { - services.AddMvc(options => options.Filters.Add(typeof(AuditFilter))); + services.AddMvc(options => options.Filters.Add()); bool redisAuditing = configuration.GetValue("RedisAuditing", false); if (redisAuditing) diff --git a/Apps/Common/src/AspNetConfiguration/Modules/Auth.cs b/Apps/Common/src/AspNetConfiguration/Modules/Auth.cs index de41da3219..0f03f608d7 100644 --- a/Apps/Common/src/AspNetConfiguration/Modules/Auth.cs +++ b/Apps/Common/src/AspNetConfiguration/Modules/Auth.cs @@ -58,6 +58,7 @@ public static class Auth /// The services collection provider. /// The logger to use. /// The configuration to use for values. + [SuppressMessage("Style", "IDE0060:Remove unused parameter", Justification = "Parameter kept for future extensibility")] public static void ConfigureAuthorizationServices(IServiceCollection services, ILogger logger, IConfiguration configuration) { logger.LogDebug("ConfigureAuthorizationServices..."); diff --git a/Apps/Common/src/AspNetConfiguration/Modules/Db.cs b/Apps/Common/src/AspNetConfiguration/Modules/Db.cs index 51ca43a4d6..37fbdd5ee7 100644 --- a/Apps/Common/src/AspNetConfiguration/Modules/Db.cs +++ b/Apps/Common/src/AspNetConfiguration/Modules/Db.cs @@ -43,17 +43,18 @@ public static void ConfigureDatabaseServices(IServiceCollection services, ILogge logger.LogDebug("Sensitive Data Logging is enabled: {IsSensitiveDataLoggingEnabled}", isSensitiveDataLoggingEnabled); services.AddEntityFrameworkNpgsql(); - services.AddSingleton(_ => - { - NpgsqlDataSourceBuilder dataSourceBuilder = new(configuration.GetConnectionString("GatewayConnection")); - dataSourceBuilder.EnableDynamicJson(); - return dataSourceBuilder.Build(); - }); + services.AddSingleton( + _ => + { + NpgsqlDataSourceBuilder dataSourceBuilder = new(configuration.GetConnectionString("GatewayConnection")); + dataSourceBuilder.EnableDynamicJson(); + return dataSourceBuilder.Build(); + }); services.AddDbContextPool( (sp, options) => { - var ds = sp.GetRequiredService(); + NpgsqlDataSource ds = sp.GetRequiredService(); options.UseInternalServiceProvider(sp); options.UseNpgsql( ds, diff --git a/Apps/Common/src/AspNetConfiguration/Modules/HttpWeb.cs b/Apps/Common/src/AspNetConfiguration/Modules/HttpWeb.cs index 6b02bdf039..dcd4569cba 100644 --- a/Apps/Common/src/AspNetConfiguration/Modules/HttpWeb.cs +++ b/Apps/Common/src/AspNetConfiguration/Modules/HttpWeb.cs @@ -291,11 +291,7 @@ private static StaticFileOptions GetBlazorStaticFileOptions(IWebHostEnvironment if (context.File.Name == "blazor.boot.json") { - if (context.Context.Response.Headers.ContainsKey("blazor-environment")) - { - context.Context.Response.Headers.Remove("blazor-environment"); - } - + context.Context.Response.Headers.Remove("blazor-environment"); context.Context.Response.Headers.Append("blazor-environment", environment.EnvironmentName); } }, diff --git a/Apps/Common/src/AspNetConfiguration/Modules/Observability.cs b/Apps/Common/src/AspNetConfiguration/Modules/Observability.cs index eaf425ea26..99add031ac 100644 --- a/Apps/Common/src/AspNetConfiguration/Modules/Observability.cs +++ b/Apps/Common/src/AspNetConfiguration/Modules/Observability.cs @@ -84,7 +84,9 @@ public static IApplicationBuilder UseDefaultHttpRequestLogging(this IApplication opts => { opts.IncludeQueryInRequestPath = true; - opts.GetLevel = (httpCtx, _, exception) => ExcludePaths(httpCtx, exception, excludePaths ?? []); + + // ReSharper disable once RedundantDelegateCreation + opts.GetLevel = new Func((httpCtx, _, exception) => ExcludePaths(httpCtx, exception, excludePaths ?? [])); opts.EnrichDiagnosticContext = (diagCtx, httpCtx) => { diagCtx.Set("Host", httpCtx.Request.Host.Value); @@ -104,7 +106,7 @@ public static IApplicationBuilder UseDefaultHttpRequestLogging(this IApplication /// OpenTelemetry configuration values. /// The DI container. #pragma warning disable CA1506 //Avoid excessive class coupling - public static IServiceCollection AddOpenTelemetryDefaults(this IServiceCollection services, OpenTelemetryConfig otlpConfig) + public static IServiceCollection AddOpenTelemetryDefaults(this IServiceCollection services, OpenTelemetryConfig otlpConfig) // NOSONAR { if (string.IsNullOrEmpty(otlpConfig.ServiceName)) { @@ -127,14 +129,14 @@ public static IServiceCollection AddOpenTelemetryDefaults(this IServiceCollectio .AddAspNetCoreInstrumentation( options => { - options.Filter = httpContext => !Array.Exists( + // ReSharper disable once RedundantLambdaParameterType + options.Filter = (HttpContext httpContext) => !Array.Exists( otlpConfig.IgnorePathPrefixes, s => httpContext.Request.Path.ToString().StartsWith(s, StringComparison.OrdinalIgnoreCase)); }) .AddRedisInstrumentation() .AddEntityFrameworkCoreInstrumentation() - .AddNpgsql() - ; + .AddNpgsql(); foreach (string source in otlpConfig.Sources) { @@ -167,8 +169,7 @@ public static IServiceCollection AddOpenTelemetryDefaults(this IServiceCollectio builder .AddHttpClientInstrumentation() .AddAspNetCoreInstrumentation() - .AddRuntimeInstrumentation() - ; + .AddRuntimeInstrumentation(); if (otlpConfig.MetricsConsoleExporterEnabled) { @@ -270,9 +271,8 @@ private static LogEventLevel ExcludePaths(HttpContext ctx, Exception? ex, string return LogEventLevel.Error; } - return Array.Exists(excludedPaths, path => IsWildcardMatch(ctx.Request.Path, path)) - ? LogEventLevel.Verbose - : LogEventLevel.Information; + bool isWildcardMatch = Array.Exists(excludedPaths, path => IsWildcardMatch(ctx.Request.Path, path)); + return isWildcardMatch ? LogEventLevel.Verbose : LogEventLevel.Information; } private static bool IsWildcardMatch(PathString requestPath, string path) @@ -282,17 +282,18 @@ private static bool IsWildcardMatch(PathString requestPath, string path) return false; } - if (path.EndsWith('*')) - { - return requestPath.Value!.StartsWith(path.Replace("*", string.Empty, StringComparison.InvariantCultureIgnoreCase), StringComparison.InvariantCultureIgnoreCase); - } + string requestPathValue = requestPath.Value!; - if (path.StartsWith('*')) + return path switch { - return requestPath.Value!.EndsWith(path.Replace("*", string.Empty, StringComparison.InvariantCultureIgnoreCase), StringComparison.InvariantCultureIgnoreCase); - } - - return requestPath.Equals(path, StringComparison.InvariantCultureIgnoreCase); + _ when path.EndsWith('*') => requestPathValue.StartsWith( + path.TrimEnd('*'), + StringComparison.InvariantCultureIgnoreCase), + _ when path.StartsWith('*') => requestPathValue.EndsWith( + path.TrimStart('*'), + StringComparison.InvariantCultureIgnoreCase), + _ => requestPath.Equals(path, StringComparison.InvariantCultureIgnoreCase), + }; } } } diff --git a/Apps/Common/src/AspNetConfiguration/Modules/Patient.cs b/Apps/Common/src/AspNetConfiguration/Modules/Patient.cs index 111bd8a118..1217a70839 100644 --- a/Apps/Common/src/AspNetConfiguration/Modules/Patient.cs +++ b/Apps/Common/src/AspNetConfiguration/Modules/Patient.cs @@ -59,7 +59,11 @@ public static void ConfigurePatientAccess(IServiceCollection services, ILogger l // Note: As per reading we do not have to dispose of the certificate. string? clientCertificatePath = clientConfiguration.GetSection("ClientCertificate").GetValue("Path"); string? certificatePassword = clientConfiguration.GetSection("ClientCertificate").GetValue("Password"); +#pragma warning disable SYSLIB0057 + + // Using the obsolete X509Certificate2 constructor X509Certificate2 clientRegistriesCertificate = new(File.ReadAllBytes(clientCertificatePath), certificatePassword); +#pragma warning restore SYSLIB0057 client.ClientCredentials.ClientCertificate.Certificate = clientRegistriesCertificate; client.Endpoint.EndpointBehaviors.Add(s.GetService()); client.ClientCredentials.ServiceCertificate.SslCertificateAuthentication = diff --git a/Apps/Common/src/AspNetConfiguration/ProgramConfiguration.cs b/Apps/Common/src/AspNetConfiguration/ProgramConfiguration.cs index 4fe6d8b911..87b03daef3 100644 --- a/Apps/Common/src/AspNetConfiguration/ProgramConfiguration.cs +++ b/Apps/Common/src/AspNetConfiguration/ProgramConfiguration.cs @@ -84,7 +84,7 @@ public static ILogger GetInitialLogger(IConfiguration configuration) .Enrich.FromLogContext() .CreateBootstrapLogger(); - using var factory = new SerilogLoggerFactory(Log.Logger); + using SerilogLoggerFactory factory = new(Log.Logger); return factory.CreateLogger("Startup"); } } diff --git a/Apps/Common/src/Constants/OidType.cs b/Apps/Common/src/Constants/OidType.cs index 339909a40d..94d3063148 100644 --- a/Apps/Common/src/Constants/OidType.cs +++ b/Apps/Common/src/Constants/OidType.cs @@ -50,23 +50,19 @@ private OidType(string value) /// The first type to compare, or null. /// The second type to compare, or null. [ExcludeFromCodeCoverage] - public static bool operator ==(OidType lhs, OidType rhs) + public static bool operator ==(OidType? lhs, OidType? rhs) { - // Check for null on left side. - if (ReferenceEquals(lhs, null)) + // Use ReferenceEquals to check for null equality. + if (ReferenceEquals(lhs, rhs)) { - if (ReferenceEquals(rhs, null)) - { - // null == null = true. - return true; - } - - // Only the left side is null. - return false; + return true; } - // Equals handles case of null on right side. - return lhs.Equals(rhs); + // If lhs is null, return false (rhs is not null at this point). + return lhs is not null && + + // Delegate to Equals for further comparison. + lhs.Equals(rhs); } /// @@ -109,13 +105,9 @@ public override string ToString() [ExcludeFromCodeCoverage] public override bool Equals(object? obj) { - // Check for null and compare run-time types. - if (obj == null || !this.GetType().Equals(obj.GetType())) - { - return false; - } - - return this.Equals((OidType)obj); + // Use 'is' to check for null and type compatibility, then delegate to the strongly-typed Equals method. + return obj is OidType other && + this.Equals(other); } /// diff --git a/Apps/Common/src/Delegates/ClientRegistriesDelegate.cs b/Apps/Common/src/Delegates/ClientRegistriesDelegate.cs index b962bc3515..3af0d154b9 100644 --- a/Apps/Common/src/Delegates/ClientRegistriesDelegate.cs +++ b/Apps/Common/src/Delegates/ClientRegistriesDelegate.cs @@ -18,6 +18,7 @@ namespace HealthGateway.Common.Delegates using System; using System.Collections.Generic; using System.Diagnostics; + using System.Diagnostics.CodeAnalysis; using System.Globalization; using System.Linq; using System.ServiceModel; @@ -129,51 +130,91 @@ public async Task> GetDemographicsByPhnAsync(string private static HCIM_IN_GetDemographicsRequest CreateRequest(OidType oidType, string identifierValue, string clientIp) { - HCIM_IN_GetDemographics request = new(); - request.id = new II { root = "2.16.840.1.113883.3.51.1.1.1", extension = DateTimeOffset.Now.ToUnixTimeMilliseconds().ToString(CultureInfo.InvariantCulture) }; - request.creationTime = new TS { value = DateTime.Now.ToString("yyyyMMddHHmmss", CultureInfo.InvariantCulture) }; - request.versionCode = new CS { code = "V3PR1" }; - request.interactionId = new II { root = "2.16.840.1.113883.3.51.1.1.2", extension = "HCIM_IN_GetDemographics" }; - request.processingCode = new CS { code = "P" }; - request.processingModeCode = new CS { code = "T" }; - request.acceptAckCode = new CS { code = "NE" }; - - request.receiver = new MCCI_MT000100Receiver { typeCode = "RCV" }; - request.receiver.device = new MCCI_MT000100Device { determinerCode = Instance, classCode = "DEV" }; - request.receiver.device.id = new II { root = "2.16.840.1.113883.3.51.1.1.4", extension = clientIp }; - request.receiver.device.asAgent = new MCCI_MT000100Agent { classCode = "AGNT" }; - request.receiver.device.asAgent.representedOrganization = new MCCI_MT000100Organization { determinerCode = Instance, classCode = "ORG" }; - request.receiver.device.asAgent.representedOrganization = new MCCI_MT000100Organization { determinerCode = Instance, classCode = "ORG" }; - request.receiver.device.asAgent.representedOrganization.id = new II { root = "2.16.840.1.113883.3.51.1.1.3", extension = "HCIM" }; - - request.sender = new MCCI_MT000100Sender { typeCode = "SND" }; - request.sender.device = new MCCI_MT000100Device { determinerCode = Instance, classCode = "DEV" }; - request.sender.device.id = new II { root = "2.16.840.1.113883.3.51.1.1.5", extension = "MOH_CRS" }; - request.sender.device.asAgent = new MCCI_MT000100Agent { classCode = "AGNT" }; - request.sender.device.asAgent.representedOrganization = new MCCI_MT000100Organization { determinerCode = Instance, classCode = "ORG" }; - request.sender.device.asAgent.representedOrganization = new MCCI_MT000100Organization { determinerCode = Instance, classCode = "ORG" }; - request.sender.device.asAgent.representedOrganization.id = new II { root = "2.16.840.1.113883.3.51.1.1.3", extension = "HGWAY" }; - - request.controlActProcess = new HCIM_IN_GetDemographicsQUQI_MT020001ControlActProcess { classCode = "ACCM", moodCode = "EVN" }; - request.controlActProcess.effectiveTime = new IVL_TS { value = DateTime.Now.ToString("yyyyMMddHHmmss", CultureInfo.InvariantCulture) }; - request.controlActProcess.dataEnterer = new QUQI_MT020001DataEnterer { typeCode = "CST", time = null, typeId = null }; - request.controlActProcess.dataEnterer.assignedPerson = new COCT_MT090100AssignedPerson { classCode = "ENT" }; - - request.controlActProcess.dataEnterer.assignedPerson.id = new II { root = "2.16.840.1.113883.3.51.1.1.7", extension = "HLTHGTWAY" }; - - request.controlActProcess.queryByParameter = new HCIM_IN_GetDemographicsQUQI_MT020001QueryByParameter(); - request.controlActProcess.queryByParameter.queryByParameterPayload = new HCIM_IN_GetDemographicsQueryByParameterPayload(); - request.controlActProcess.queryByParameter.queryByParameterPayload.personid = new HCIM_IN_GetDemographicsPersonid(); - request.controlActProcess.queryByParameter.queryByParameterPayload.personid.value = new II + HCIM_IN_GetDemographics request = new() { - root = oidType.ToString(), - extension = identifierValue, - assigningAuthorityName = "LCTZ_IAS", + id = new II { root = "2.16.840.1.113883.3.51.1.1.1", extension = DateTimeOffset.Now.ToUnixTimeMilliseconds().ToString(CultureInfo.InvariantCulture) }, + creationTime = new TS { value = DateTime.Now.ToString("yyyyMMddHHmmss", CultureInfo.InvariantCulture) }, + versionCode = new CS { code = "V3PR1" }, + interactionId = new II { root = "2.16.840.1.113883.3.51.1.1.2", extension = "HCIM_IN_GetDemographics" }, + processingCode = new CS { code = "P" }, + processingModeCode = new CS { code = "T" }, + acceptAckCode = new CS { code = "NE" }, + receiver = new MCCI_MT000100Receiver + { + typeCode = "RCV", + device = new MCCI_MT000100Device + { + determinerCode = Instance, classCode = "DEV", + id = new II { root = "2.16.840.1.113883.3.51.1.1.4", extension = clientIp }, + asAgent = new MCCI_MT000100Agent + { + classCode = "AGNT", + representedOrganization = new MCCI_MT000100Organization { determinerCode = Instance, classCode = "ORG" }, + }, + }, + }, + }; + + request.receiver.device.asAgent.representedOrganization = new MCCI_MT000100Organization + { + determinerCode = Instance, classCode = "ORG", + id = new II { root = "2.16.840.1.113883.3.51.1.1.3", extension = "HCIM" }, + }; + + request.sender = new MCCI_MT000100Sender + { + typeCode = "SND", + device = new MCCI_MT000100Device + { + determinerCode = Instance, classCode = "DEV", + id = new II { root = "2.16.840.1.113883.3.51.1.1.5", extension = "MOH_CRS" }, + asAgent = new MCCI_MT000100Agent + { + classCode = "AGNT", + representedOrganization = new MCCI_MT000100Organization { determinerCode = Instance, classCode = "ORG" }, + }, + }, + }; + request.sender.device.asAgent.representedOrganization = new MCCI_MT000100Organization + { + determinerCode = Instance, classCode = "ORG", + id = new II { root = "2.16.840.1.113883.3.51.1.1.3", extension = "HGWAY" }, + }; + + request.controlActProcess = new HCIM_IN_GetDemographicsQUQI_MT020001ControlActProcess + { + classCode = "ACCM", moodCode = "EVN", + effectiveTime = new IVL_TS { value = DateTime.Now.ToString("yyyyMMddHHmmss", CultureInfo.InvariantCulture) }, + dataEnterer = new QUQI_MT020001DataEnterer + { + typeCode = "CST", time = null, typeId = null, + assignedPerson = new COCT_MT090100AssignedPerson + { + classCode = "ENT", + id = new II { root = "2.16.840.1.113883.3.51.1.1.7", extension = "HLTHGTWAY" }, + }, + }, + queryByParameter = new HCIM_IN_GetDemographicsQUQI_MT020001QueryByParameter + { + queryByParameterPayload = new HCIM_IN_GetDemographicsQueryByParameterPayload + { + personid = new HCIM_IN_GetDemographicsPersonid + { + value = new II + { + root = oidType.ToString(), + extension = identifierValue, + assigningAuthorityName = "LCTZ_IAS", + }, + }, + }, + }, }; return new HCIM_IN_GetDemographicsRequest(request); } + [SuppressMessage("Style", "IDE0010:Populate switch", Justification = "Team decision")] private static Address? MapAddress(AD? address) { if (address?.Items == null) @@ -399,7 +440,7 @@ private bool PopulateNames(HCIM_IN_GetDemographicsResponseIdentifiedPerson retri private bool PopulateIdentifiers(HCIM_IN_GetDemographicsResponseIdentifiedPerson retrievedPerson, PatientModel patient) { - II? identifiedPersonId = Array.Find(retrievedPerson.identifiedPerson.id ?? Array.Empty(), x => x.root == OidType.Phn.ToString()); + II? identifiedPersonId = Array.Find(retrievedPerson.identifiedPerson.id ?? [], x => x.root == OidType.Phn.ToString()); if (identifiedPersonId == null) { this.logger.LogWarning("The Client Registry returned a person without a PHN"); @@ -409,7 +450,7 @@ private bool PopulateIdentifiers(HCIM_IN_GetDemographicsResponseIdentifiedPerson patient.PersonalHealthNumber = identifiedPersonId.extension; } - II? subjectId = Array.Find(retrievedPerson.id ?? Array.Empty(), x => x.displayable && x.root == OidType.Hdid.ToString()); + II? subjectId = Array.Find(retrievedPerson.id ?? [], x => x.displayable && x.root == OidType.Hdid.ToString()); if (subjectId == null) { this.logger.LogWarning("The Client Registry returned a person without an HDID"); diff --git a/Apps/Common/src/Delegates/HmacHashDelegate.cs b/Apps/Common/src/Delegates/HmacHashDelegate.cs index 3c6f809f4d..e07ab8402d 100644 --- a/Apps/Common/src/Delegates/HmacHashDelegate.cs +++ b/Apps/Common/src/Delegates/HmacHashDelegate.cs @@ -16,6 +16,7 @@ namespace HealthGateway.Common.Delegates { using System; + using System.Diagnostics.CodeAnalysis; using System.Security.Cryptography; using HealthGateway.Common.Constants; using HealthGateway.Common.Models; @@ -53,6 +54,8 @@ public HmacHashDelegate(IConfiguration configuration) /// The pseudorandom function to use for the hash. /// The number of iterations to process over the hash. /// The hash object. + [SuppressMessage("Style", "IDE0010:Populate switch", Justification = "Team decision")] + [SuppressMessage("Style", "IDE0072:Populate switch", Justification = "Team decision")] public static HmacHash HmacHash( string? key, byte[] salt, @@ -69,19 +72,12 @@ public static HmacHash HmacHash( { // The key is not null, so we can generate a hash // Calculate the length in bytes of the hash given the function size - int hashLength; - switch (prf) + int hashLength = prf switch { - case KeyDerivationPrf.HMACSHA1: - hashLength = 20; - break; - case KeyDerivationPrf.HMACSHA256: - hashLength = 32; - break; - default: - hashLength = 64; - break; - } + KeyDerivationPrf.HMACSHA1 => 20, + KeyDerivationPrf.HMACSHA256 => 32, + _ => 64, + }; retHash.Salt = Convert.ToBase64String(salt); retHash.Hash = Convert.ToBase64String(KeyDerivation.Pbkdf2(key, salt, prf, iterations, hashLength)); diff --git a/Apps/Common/src/Delegates/VaccineProofDelegate.cs b/Apps/Common/src/Delegates/VaccineProofDelegate.cs index 3bf1227b99..c713790b6a 100644 --- a/Apps/Common/src/Delegates/VaccineProofDelegate.cs +++ b/Apps/Common/src/Delegates/VaccineProofDelegate.cs @@ -64,6 +64,7 @@ public VaccineProofDelegate( } /// + [SuppressMessage("Style", "IDE0072:Populate swtich", Justification = "Team decision")] public async Task> MailAsync(VaccineProofTemplate vaccineProofTemplate, VaccineProofRequest request, Address address, CancellationToken ct = default) { RequestResult retVal = new() @@ -134,6 +135,7 @@ public async Task> MailAsync(VaccineProofTem } /// + [SuppressMessage("Style", "IDE0072:Populate switch", Justification = "Team decision")] public async Task> GenerateAsync(VaccineProofTemplate vaccineProofTemplate, VaccineProofRequest request, CancellationToken ct = default) { RequestResult retVal = new() @@ -192,6 +194,7 @@ public async Task> GenerateAsync(VaccineProo /// [SuppressMessage("Design", "CA1031:Do not catch general exception types", Justification = "Prevent exception propagation")] + [SuppressMessage("Style", "IDE0010:Populate switch", Justification = "Team decision")] public async Task> GetAssetAsync(Uri assetUri, CancellationToken ct = default) { RequestResult retVal = new() @@ -258,6 +261,7 @@ public async Task> GetAssetAsync(Uri assetUri, Cancel } // ReSharper disable once CognitiveComplexity + [SuppressMessage("Style", "IDE0010:Populate switch", Justification = "Team decision")] private async Task> PostAsync(string endpointString, StringContent httpContent, CancellationToken ct) where T : class { diff --git a/Apps/Common/src/ErrorHandling/ExceptionUtilities.cs b/Apps/Common/src/ErrorHandling/ExceptionUtilities.cs index e199e8fcf6..e64f4b2c04 100644 --- a/Apps/Common/src/ErrorHandling/ExceptionUtilities.cs +++ b/Apps/Common/src/ErrorHandling/ExceptionUtilities.cs @@ -110,7 +110,8 @@ private static string FormatTitle(string title) return new { e.Message, e.StackTrace }; } - return new { e.Message, e.StackTrace, InnerException = FormatExceptionDetails(e.InnerException, maxDepth - 1) }; + object? innerExceptionDetails = FormatExceptionDetails(e.InnerException, maxDepth - 1); + return new { e.Message, e.StackTrace, InnerException = innerExceptionDetails }; } } } diff --git a/Apps/Common/src/Services/CommunicationService.cs b/Apps/Common/src/Services/CommunicationService.cs index 3144475a66..e29dbb7dee 100644 --- a/Apps/Common/src/Services/CommunicationService.cs +++ b/Apps/Common/src/Services/CommunicationService.cs @@ -141,6 +141,7 @@ public void ClearCache() /// /// The CommunicationType to retrieve the key for. /// The key for the cache associated with the given CommunicationType. + [SuppressMessage("Style", "IDE0072:Populate switch", Justification = "Team decision")] internal static string GetCacheKey(CommunicationType communicationType) { return communicationType switch diff --git a/Apps/Common/src/Services/NotificationSettingsService.cs b/Apps/Common/src/Services/NotificationSettingsService.cs index c1f840513d..ae2446ec45 100644 --- a/Apps/Common/src/Services/NotificationSettingsService.cs +++ b/Apps/Common/src/Services/NotificationSettingsService.cs @@ -17,6 +17,7 @@ namespace HealthGateway.Common.Services { using System; using System.Collections.Generic; + using System.Linq; using System.Text.Json; using System.Threading; using System.Threading.Tasks; @@ -55,7 +56,7 @@ public NotificationSettingsService( /// public async Task QueueNotificationSettingsAsync(NotificationSettingsRequest notificationSettings, CancellationToken ct = default) { - if (notificationSettings.SmsEnabled && !notificationSettings.SmsVerified && string.IsNullOrEmpty(notificationSettings.SmsVerificationCode)) + if (notificationSettings is { SmsEnabled: true, SmsVerified: false } && string.IsNullOrEmpty(notificationSettings.SmsVerificationCode)) { throw new InvalidOperationException(); } @@ -66,26 +67,37 @@ public async Task QueueNotificationSettingsAsync(NotificationSettingsRequest not // Update the notification settings for any dependents IEnumerable resourceDelegates = await this.resourceDelegateDelegate.GetAsync(notificationSettings.SubjectHdid, 0, 500, ct); - foreach (ResourceDelegate resourceDelegate in resourceDelegates) - { - NotificationSettingsRequest dependentNotificationSettings = new() - { - SubjectHdid = resourceDelegate.ResourceOwnerHdid, - EmailAddress = notificationSettings.EmailAddress, - EmailEnabled = notificationSettings.EmailEnabled, - EmailScope = notificationSettings.EmailScope, - }; - // Only populate SMS number if it has been verified - if (notificationSettings.SmsVerified) - { - dependentNotificationSettings.SmsNumber = notificationSettings.SmsNumber; - dependentNotificationSettings.SmsEnabled = notificationSettings.SmsEnabled; - dependentNotificationSettings.SmsScope = notificationSettings.SmsScope; - dependentNotificationSettings.SmsVerified = notificationSettings.SmsVerified; - } + // Transform resourceDelegates to NotificationSettingsRequest using LINQ + List dependentNotificationSettingsList = resourceDelegates + .Select( + resourceDelegate => + { + NotificationSettingsRequest dependentNotificationSettings = new() + { + SubjectHdid = resourceDelegate.ResourceOwnerHdid, + EmailAddress = notificationSettings.EmailAddress, + EmailEnabled = notificationSettings.EmailEnabled, + EmailScope = notificationSettings.EmailScope, + }; + + // Only populate SMS number if it has been verified + if (notificationSettings.SmsVerified) + { + dependentNotificationSettings.SmsNumber = notificationSettings.SmsNumber; + dependentNotificationSettings.SmsEnabled = notificationSettings.SmsEnabled; + dependentNotificationSettings.SmsScope = notificationSettings.SmsScope; + dependentNotificationSettings.SmsVerified = notificationSettings.SmsVerified; + } - this.logger.LogDebug("Queueing notification settings push for dependent {Hdid}", resourceDelegate.ResourceOwnerHdid); + return dependentNotificationSettings; + }) + .ToList(); + + // Process the transformed list + foreach (NotificationSettingsRequest dependentNotificationSettings in dependentNotificationSettingsList) + { + this.logger.LogDebug("Queueing notification settings push for dependent {Hdid}", dependentNotificationSettings.SubjectHdid); string delegateJson = JsonSerializer.Serialize(dependentNotificationSettings); this.jobClient.Enqueue(j => j.PushNotificationSettingsAsync(delegateJson, ct)); } diff --git a/Apps/Common/src/Swagger/ConfigureSwaggerGenOptions.cs b/Apps/Common/src/Swagger/ConfigureSwaggerGenOptions.cs index f1ab2a5a33..97b26a2776 100644 --- a/Apps/Common/src/Swagger/ConfigureSwaggerGenOptions.cs +++ b/Apps/Common/src/Swagger/ConfigureSwaggerGenOptions.cs @@ -43,8 +43,10 @@ public ConfigureSwaggerGenOptions( IApiVersionDescriptionProvider versionDescriptionProvider, IOptions swaggerSettings) { - Debug.Assert(versionDescriptionProvider != null, $"{nameof(versionDescriptionProvider)} != null"); - Debug.Assert(swaggerSettings != null, $"{nameof(swaggerSettings)} != null"); +#pragma warning disable S3236 + Debug.Assert(versionDescriptionProvider != null, "The versionDescriptionProvider parameter cannot be null."); + Debug.Assert(swaggerSettings != null, "The swaggerSettings parameter cannot be null."); +#pragma warning restore S3236 this.provider = versionDescriptionProvider; this.settings = swaggerSettings.Value; diff --git a/Apps/Common/src/Swagger/ConfigureSwaggerUiOptions.cs b/Apps/Common/src/Swagger/ConfigureSwaggerUiOptions.cs index b7bd73f9c8..fb2f4aa97a 100644 --- a/Apps/Common/src/Swagger/ConfigureSwaggerUiOptions.cs +++ b/Apps/Common/src/Swagger/ConfigureSwaggerUiOptions.cs @@ -37,9 +37,10 @@ public sealed class ConfigureSwaggerUiOptions : IConfigureOptionssettings. public ConfigureSwaggerUiOptions(IApiVersionDescriptionProvider versionDescriptionProvider, IOptions settings) { - Debug.Assert(versionDescriptionProvider != null, $"{nameof(versionDescriptionProvider)} != null"); - Debug.Assert(settings != null, $"{nameof(versionDescriptionProvider)} != null"); - +#pragma warning disable S3236 + Debug.Assert(versionDescriptionProvider != null, "The versionDescriptionProvider parameter cannot be null."); + Debug.Assert(settings != null, "The settings parameter cannot be null."); +#pragma warning restore S3236 this.provider = versionDescriptionProvider; this.settings = settings.Value; } diff --git a/Apps/Common/src/Swagger/SwaggerDefaultValues.cs b/Apps/Common/src/Swagger/SwaggerDefaultValues.cs index dd10625056..a4e7d54e26 100644 --- a/Apps/Common/src/Swagger/SwaggerDefaultValues.cs +++ b/Apps/Common/src/Swagger/SwaggerDefaultValues.cs @@ -46,10 +46,7 @@ public void Apply(OpenApiOperation operation, OperationFilterContext context) ApiParameterDescription description = context.ApiDescription.ParameterDescriptions.First(p => p.Name == parameter.Name); ApiParameterRouteInfo? routeInfo = description.RouteInfo; - if (parameter.Description == null) - { - parameter.Description = description.ModelMetadata?.Description; - } + parameter.Description ??= description.ModelMetadata?.Description; if (routeInfo == null) { diff --git a/Apps/Common/src/Utils/Odr/OdrAuthorizationHandler.cs b/Apps/Common/src/Utils/Odr/OdrAuthorizationHandler.cs index b65aee78fb..0b0853e720 100644 --- a/Apps/Common/src/Utils/Odr/OdrAuthorizationHandler.cs +++ b/Apps/Common/src/Utils/Odr/OdrAuthorizationHandler.cs @@ -52,7 +52,12 @@ public OdrAuthorizationHandler(IConfiguration configuration) if (odrConfig.ClientCertificate?.Enabled == true) { byte[] certificateData = File.ReadAllBytes(odrConfig.ClientCertificate?.Path); + +#pragma warning disable SYSLIB0057 + + // Using the obsolete X509Certificate2 constructor this.ClientCertificates.Add(new X509Certificate2(certificateData, odrConfig.ClientCertificate?.Password)); +#pragma warning restore SYSLIB0057 } } diff --git a/Apps/Common/src/Utils/PolymorphicJsonConverter.cs b/Apps/Common/src/Utils/PolymorphicJsonConverter.cs index a6ca226c40..0d338444c7 100644 --- a/Apps/Common/src/Utils/PolymorphicJsonConverter.cs +++ b/Apps/Common/src/Utils/PolymorphicJsonConverter.cs @@ -36,12 +36,8 @@ public class PolymorphicJsonConverter : JsonConverter /// public override T Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) { - Type? actualType = this.FindType(typeToConvert, ref reader); - - if (actualType == null) - { - throw new JsonException($"serialized json doesn't have a {this.Discriminator} property"); - } + Type actualType = this.FindType(typeToConvert, ref reader) + ?? throw new JsonException($"serialized json doesn't have a {this.Discriminator} property"); return (T)(JsonSerializer.Deserialize(ref reader, actualType, options) ?? throw new JsonException($"failed to deserialize type {actualType.Name}")); diff --git a/Apps/Common/src/Utils/SerializationHelper.cs b/Apps/Common/src/Utils/SerializationHelper.cs index 1adca37af7..eb9b374480 100644 --- a/Apps/Common/src/Utils/SerializationHelper.cs +++ b/Apps/Common/src/Utils/SerializationHelper.cs @@ -64,12 +64,14 @@ public static byte[] Serialize(this T? obj, bool serializeUsingActualType = t { if (obj == null) { - return Array.Empty(); + return []; } - return serializeUsingActualType + byte[] serializedData = serializeUsingActualType ? SerializeUsingConcreteType(obj, options) : SerializeUsingGenericType(obj, options); + + return serializedData; } private static byte[] SerializeUsingConcreteType(T obj, JsonSerializerOptions? options = null) diff --git a/Apps/Common/test/unit/AccessManagement/Authentication/AuthenticationDelegateTests.cs b/Apps/Common/test/unit/AccessManagement/Authentication/AuthenticationDelegateTests.cs index fe6800b0a9..e8610cb6af 100644 --- a/Apps/Common/test/unit/AccessManagement/Authentication/AuthenticationDelegateTests.cs +++ b/Apps/Common/test/unit/AccessManagement/Authentication/AuthenticationDelegateTests.cs @@ -223,10 +223,9 @@ public void ShouldBeAbleToDetermineLoginClientType(string clientAzp, UserLoginCl { User = new ClaimsPrincipal( new ClaimsIdentity( - new Claim[] - { + [ new("azp", clientAzp), - }, + ], "token")), }; Mock mockHttpContextAccessor = new(); diff --git a/Apps/Common/test/unit/AccessManagement/Authorization/PersonalAccessHandlerTests.cs b/Apps/Common/test/unit/AccessManagement/Authorization/PersonalAccessHandlerTests.cs index 13d4053011..1eccd967d1 100644 --- a/Apps/Common/test/unit/AccessManagement/Authorization/PersonalAccessHandlerTests.cs +++ b/Apps/Common/test/unit/AccessManagement/Authorization/PersonalAccessHandlerTests.cs @@ -50,9 +50,9 @@ public void UnknownRequirement() List claims = [ - new Claim(ClaimTypes.Name, username), - new Claim(ClaimTypes.NameIdentifier, userId), - new Claim(GatewayClaims.Hdid, hdid), + new(ClaimTypes.Name, username), + new(ClaimTypes.NameIdentifier, userId), + new(GatewayClaims.Hdid, hdid), ]; ClaimsIdentity identity = new(claims, "TestAuth"); ClaimsPrincipal claimsPrincipal = new(identity); @@ -80,7 +80,7 @@ public void UnknownRequirement() ILogger logger = loggerFactory.CreateLogger(); PersonalAccessHandler authHandler = new(logger, httpContextAccessorMock.Object); - NameAuthorizationRequirement[] requirements = { new(username) }; + NameAuthorizationRequirement[] requirements = [new(username)]; AuthorizationHandlerContext context = new(requirements, claimsPrincipal, null); @@ -104,9 +104,9 @@ public void ReadWriteNoResource() List claims = [ - new Claim(ClaimTypes.Name, username), - new Claim(ClaimTypes.NameIdentifier, userId), - new Claim(GatewayClaims.Hdid, hdid), + new(ClaimTypes.Name, username), + new(ClaimTypes.NameIdentifier, userId), + new(GatewayClaims.Hdid, hdid), ]; ClaimsIdentity identity = new(claims, "TestAuth"); ClaimsPrincipal claimsPrincipal = new(identity); @@ -131,7 +131,7 @@ public void ReadWriteNoResource() ILogger logger = loggerFactory.CreateLogger(); PersonalAccessHandler authHandler = new(logger, httpContextAccessorMock.Object); - PersonalFhirRequirement[] requirements = { new(FhirResource.Patient, FhirAccessType.Read) }; + PersonalFhirRequirement[] requirements = [new(FhirResource.Patient, FhirAccessType.Read)]; AuthorizationHandlerContext context = new(requirements, claimsPrincipal, null); @@ -156,9 +156,9 @@ public void ShouldAuthPatientReadAsOwner() List claims = [ - new Claim(ClaimTypes.Name, username), - new Claim(ClaimTypes.NameIdentifier, userId), - new Claim(GatewayClaims.Hdid, hdid), + new(ClaimTypes.Name, username), + new(ClaimTypes.NameIdentifier, userId), + new(GatewayClaims.Hdid, hdid), ]; ClaimsIdentity identity = new(claims, "TestAuth"); ClaimsPrincipal claimsPrincipal = new(identity); @@ -186,7 +186,7 @@ public void ShouldAuthPatientReadAsOwner() ILogger logger = loggerFactory.CreateLogger(); PersonalAccessHandler authHandler = new(logger, httpContextAccessorMock.Object); - PersonalFhirRequirement[] requirements = { new(FhirResource.Patient, FhirAccessType.Read) }; + PersonalFhirRequirement[] requirements = [new(FhirResource.Patient, FhirAccessType.Read)]; AuthorizationHandlerContext context = new(requirements, claimsPrincipal, null); @@ -211,9 +211,9 @@ public void ShouldAuthPatientReadAsOwnerUsingParameter() List claims = [ - new Claim(ClaimTypes.Name, username), - new Claim(ClaimTypes.NameIdentifier, userId), - new Claim(GatewayClaims.Hdid, hdid), + new(ClaimTypes.Name, username), + new(ClaimTypes.NameIdentifier, userId), + new(GatewayClaims.Hdid, hdid), ]; ClaimsIdentity identity = new(claims, "TestAuth"); ClaimsPrincipal claimsPrincipal = new(identity); @@ -242,7 +242,7 @@ public void ShouldAuthPatientReadAsOwnerUsingParameter() ILogger logger = loggerFactory.CreateLogger(); PersonalAccessHandler authHandler = new(logger, httpContextAccessorMock.Object); - PersonalFhirRequirement[] requirements = { new(FhirResource.Patient, FhirAccessType.Read, FhirSubjectLookupMethod.Parameter) }; + PersonalFhirRequirement[] requirements = [new(FhirResource.Patient, FhirAccessType.Read, FhirSubjectLookupMethod.Parameter)]; AuthorizationHandlerContext context = new(requirements, claimsPrincipal, null); @@ -267,8 +267,8 @@ public void ShouldNotAuthPatientReadWithoutHdidClaim() List claims = [ - new Claim(ClaimTypes.Name, username), - new Claim(ClaimTypes.NameIdentifier, userId), + new(ClaimTypes.Name, username), + new(ClaimTypes.NameIdentifier, userId), ]; ClaimsIdentity identity = new(claims, "TestAuth"); ClaimsPrincipal claimsPrincipal = new(identity); @@ -321,9 +321,9 @@ public void ShouldNotAuthPatientReadAsOwner() List claims = [ - new Claim(ClaimTypes.Name, username), - new Claim(ClaimTypes.NameIdentifier, userId), - new Claim(GatewayClaims.Hdid, hdid), + new(ClaimTypes.Name, username), + new(ClaimTypes.NameIdentifier, userId), + new(GatewayClaims.Hdid, hdid), ]; ClaimsIdentity identity = new(claims, "TestAuth"); ClaimsPrincipal claimsPrincipal = new(identity); @@ -351,7 +351,7 @@ public void ShouldNotAuthPatientReadAsOwner() ILogger logger = loggerFactory.CreateLogger(); PersonalAccessHandler authHandler = new(logger, httpContextAccessorMock.Object); - PersonalFhirRequirement[] requirements = { new(FhirResource.Patient, FhirAccessType.Read) }; + PersonalFhirRequirement[] requirements = [new(FhirResource.Patient, FhirAccessType.Read)]; AuthorizationHandlerContext context = new(requirements, claimsPrincipal, null); @@ -376,10 +376,10 @@ public void ShouldNotAuthPatientReadAsOtherPatient() string scopes = "user/Patient.read"; List claims = [ - new Claim(ClaimTypes.Name, username), - new Claim(ClaimTypes.NameIdentifier, userId), - new Claim(GatewayClaims.Hdid, hdid), - new Claim(GatewayClaims.Scope, scopes), + new(ClaimTypes.Name, username), + new(ClaimTypes.NameIdentifier, userId), + new(GatewayClaims.Hdid, hdid), + new(GatewayClaims.Scope, scopes), ]; ClaimsIdentity identity = new(claims, "TestAuth"); ClaimsPrincipal claimsPrincipal = new(identity); @@ -407,7 +407,7 @@ public void ShouldNotAuthPatientReadAsOtherPatient() ILogger logger = loggerFactory.CreateLogger(); PersonalAccessHandler authHandler = new(logger, httpContextAccessorMock.Object); - PersonalFhirRequirement[] requirements = { new(FhirResource.Patient, FhirAccessType.Read) }; + PersonalFhirRequirement[] requirements = [new(FhirResource.Patient, FhirAccessType.Read)]; AuthorizationHandlerContext context = new(requirements, claimsPrincipal, null); @@ -432,9 +432,9 @@ public void ShouldAuthPatientWriteAsOwner() List claims = [ - new Claim(ClaimTypes.Name, username), - new Claim(ClaimTypes.NameIdentifier, userId), - new Claim(GatewayClaims.Hdid, hdid), + new(ClaimTypes.Name, username), + new(ClaimTypes.NameIdentifier, userId), + new(GatewayClaims.Hdid, hdid), ]; ClaimsIdentity identity = new(claims, "TestAuth"); ClaimsPrincipal claimsPrincipal = new(identity); @@ -462,7 +462,7 @@ public void ShouldAuthPatientWriteAsOwner() ILogger logger = loggerFactory.CreateLogger(); PersonalAccessHandler authHandler = new(logger, httpContextAccessorMock.Object); - PersonalFhirRequirement[] requirements = { new(FhirResource.Patient, FhirAccessType.Write) }; + PersonalFhirRequirement[] requirements = [new(FhirResource.Patient, FhirAccessType.Write)]; AuthorizationHandlerContext context = new(requirements, claimsPrincipal, null); @@ -487,10 +487,10 @@ public void ShouldNotAuthPatientWriteAsOtherPatient() string scopes = "user/Patient.write"; List claims = [ - new Claim(ClaimTypes.Name, username), - new Claim(ClaimTypes.NameIdentifier, userId), - new Claim(GatewayClaims.Hdid, hdid), - new Claim(GatewayClaims.Scope, scopes), + new(ClaimTypes.Name, username), + new(ClaimTypes.NameIdentifier, userId), + new(GatewayClaims.Hdid, hdid), + new(GatewayClaims.Scope, scopes), ]; ClaimsIdentity identity = new(claims, "TestAuth"); ClaimsPrincipal claimsPrincipal = new(identity); @@ -518,7 +518,7 @@ public void ShouldNotAuthPatientWriteAsOtherPatient() ILogger logger = loggerFactory.CreateLogger(); PersonalAccessHandler authHandler = new(logger, httpContextAccessorMock.Object); - PersonalFhirRequirement[] requirements = { new(FhirResource.Patient, FhirAccessType.Write) }; + PersonalFhirRequirement[] requirements = [new(FhirResource.Patient, FhirAccessType.Write)]; AuthorizationHandlerContext context = new(requirements, claimsPrincipal, null); @@ -543,9 +543,9 @@ public void ShouldNotAuthPatientWriteAsOwner() List claims = [ - new Claim(ClaimTypes.Name, username), - new Claim(ClaimTypes.NameIdentifier, userId), - new Claim(GatewayClaims.Hdid, hdid), + new(ClaimTypes.Name, username), + new(ClaimTypes.NameIdentifier, userId), + new(GatewayClaims.Hdid, hdid), ]; ClaimsIdentity identity = new(claims, "TestAuth"); ClaimsPrincipal claimsPrincipal = new(identity); @@ -573,7 +573,7 @@ public void ShouldNotAuthPatientWriteAsOwner() ILogger logger = loggerFactory.CreateLogger(); PersonalAccessHandler authHandler = new(logger, httpContextAccessorMock.Object); - PersonalFhirRequirement[] requirements = { new(FhirResource.Patient, FhirAccessType.Write) }; + PersonalFhirRequirement[] requirements = [new(FhirResource.Patient, FhirAccessType.Write)]; AuthorizationHandlerContext context = new(requirements, claimsPrincipal, null); diff --git a/Apps/Common/test/unit/AccessManagement/Authorization/SystemDelegatedAccessHandlerTests.cs b/Apps/Common/test/unit/AccessManagement/Authorization/SystemDelegatedAccessHandlerTests.cs index 802a491627..2fb346a008 100644 --- a/Apps/Common/test/unit/AccessManagement/Authorization/SystemDelegatedAccessHandlerTests.cs +++ b/Apps/Common/test/unit/AccessManagement/Authorization/SystemDelegatedAccessHandlerTests.cs @@ -49,9 +49,9 @@ public void UnknownRequirement() List claims = [ - new Claim(ClaimTypes.Name, username), - new Claim(ClaimTypes.NameIdentifier, userId), - new Claim(GatewayClaims.Hdid, hdid), + new(ClaimTypes.Name, username), + new(ClaimTypes.NameIdentifier, userId), + new(GatewayClaims.Hdid, hdid), ]; ClaimsIdentity identity = new(claims, "TestAuth"); ClaimsPrincipal claimsPrincipal = new(identity); @@ -79,7 +79,7 @@ public void UnknownRequirement() ILogger logger = loggerFactory.CreateLogger(); SystemDelegatedAccessHandler authHandler = new(logger, httpContextAccessorMock.Object); - NameAuthorizationRequirement[] requirements = { new(username) }; + NameAuthorizationRequirement[] requirements = [new(username)]; AuthorizationHandlerContext context = new(requirements, claimsPrincipal, null); @@ -104,9 +104,9 @@ public void ShouldNotAuthPatientReadAsSystemDelegationDisabled() string scopes = "system/Patient.read"; List claims = [ - new Claim(ClaimTypes.Name, username), - new Claim(ClaimTypes.NameIdentifier, userId), - new Claim(GatewayClaims.Scope, scopes), + new(ClaimTypes.Name, username), + new(ClaimTypes.NameIdentifier, userId), + new(GatewayClaims.Scope, scopes), ]; ClaimsIdentity identity = new(claims, "TestAuth"); ClaimsPrincipal claimsPrincipal = new(identity); @@ -134,7 +134,7 @@ public void ShouldNotAuthPatientReadAsSystemDelegationDisabled() ILogger logger = loggerFactory.CreateLogger(); SystemDelegatedAccessHandler authHandler = new(logger, httpContextAccessorMock.Object); - PersonalFhirRequirement[] requirements = { new(FhirResource.Patient, FhirAccessType.Read, supportsSystemDelegation: false) }; + PersonalFhirRequirement[] requirements = [new(FhirResource.Patient, FhirAccessType.Read, supportsSystemDelegation: false)]; AuthorizationHandlerContext context = new(requirements, claimsPrincipal, null); @@ -159,9 +159,9 @@ public void ShouldNotAuthPatientReadAsSystemEmptyScope() string scopes = string.Empty; List claims = [ - new Claim(ClaimTypes.Name, username), - new Claim(ClaimTypes.NameIdentifier, userId), - new Claim(GatewayClaims.Scope, scopes), + new(ClaimTypes.Name, username), + new(ClaimTypes.NameIdentifier, userId), + new(GatewayClaims.Scope, scopes), ]; ClaimsIdentity identity = new(claims, "TestAuth"); ClaimsPrincipal claimsPrincipal = new(identity); @@ -189,7 +189,7 @@ public void ShouldNotAuthPatientReadAsSystemEmptyScope() ILogger logger = loggerFactory.CreateLogger(); SystemDelegatedAccessHandler authHandler = new(logger, httpContextAccessorMock.Object); - PersonalFhirRequirement[] requirements = { new(FhirResource.Patient, FhirAccessType.Read) }; + PersonalFhirRequirement[] requirements = [new(FhirResource.Patient, FhirAccessType.Read)]; AuthorizationHandlerContext context = new(requirements, claimsPrincipal, null); @@ -213,8 +213,8 @@ public void ShouldNotAuthPatientReadAsSystemMissingScope() string username = "User Name"; List claims = [ - new Claim(ClaimTypes.Name, username), - new Claim(ClaimTypes.NameIdentifier, userId), + new(ClaimTypes.Name, username), + new(ClaimTypes.NameIdentifier, userId), ]; ClaimsIdentity identity = new(claims, "TestAuth"); ClaimsPrincipal claimsPrincipal = new(identity); @@ -242,7 +242,7 @@ public void ShouldNotAuthPatientReadAsSystemMissingScope() ILogger logger = loggerFactory.CreateLogger(); SystemDelegatedAccessHandler authHandler = new(logger, httpContextAccessorMock.Object); - PersonalFhirRequirement[] requirements = { new(FhirResource.Patient, FhirAccessType.Read) }; + PersonalFhirRequirement[] requirements = [new(FhirResource.Patient, FhirAccessType.Read)]; AuthorizationHandlerContext context = new(requirements, claimsPrincipal, null); @@ -267,9 +267,9 @@ public void ShouldAuthPatientReadAsSystem() string scopes = "system/Patient.read"; List claims = [ - new Claim(ClaimTypes.Name, username), - new Claim(ClaimTypes.NameIdentifier, userId), - new Claim(GatewayClaims.Scope, scopes), + new(ClaimTypes.Name, username), + new(ClaimTypes.NameIdentifier, userId), + new(GatewayClaims.Scope, scopes), ]; ClaimsIdentity identity = new(claims, "TestAuth"); ClaimsPrincipal claimsPrincipal = new(identity); @@ -297,7 +297,7 @@ public void ShouldAuthPatientReadAsSystem() ILogger logger = loggerFactory.CreateLogger(); SystemDelegatedAccessHandler authHandler = new(logger, httpContextAccessorMock.Object); - PersonalFhirRequirement[] requirements = { new(FhirResource.Patient, FhirAccessType.Read) }; + PersonalFhirRequirement[] requirements = [new(FhirResource.Patient, FhirAccessType.Read)]; AuthorizationHandlerContext context = new(requirements, claimsPrincipal, null); @@ -322,9 +322,9 @@ public void ShouldAuthPatientWriteAsSystem() string scopes = "system/Patient.write"; List claims = [ - new Claim(ClaimTypes.Name, username), - new Claim(ClaimTypes.NameIdentifier, userId), - new Claim(GatewayClaims.Scope, scopes), + new(ClaimTypes.Name, username), + new(ClaimTypes.NameIdentifier, userId), + new(GatewayClaims.Scope, scopes), ]; ClaimsIdentity identity = new(claims, "TestAuth"); ClaimsPrincipal claimsPrincipal = new(identity); @@ -352,7 +352,7 @@ public void ShouldAuthPatientWriteAsSystem() ILogger logger = loggerFactory.CreateLogger(); SystemDelegatedAccessHandler authHandler = new(logger, httpContextAccessorMock.Object); - PersonalFhirRequirement[] requirements = { new(FhirResource.Patient, FhirAccessType.Write) }; + PersonalFhirRequirement[] requirements = [new(FhirResource.Patient, FhirAccessType.Write)]; AuthorizationHandlerContext context = new(requirements, claimsPrincipal, null); diff --git a/Apps/Common/test/unit/AccessManagement/Authorization/UserDelegatedAccessHandlerTests.cs b/Apps/Common/test/unit/AccessManagement/Authorization/UserDelegatedAccessHandlerTests.cs index 8ab923c65e..b1a9ed81d0 100644 --- a/Apps/Common/test/unit/AccessManagement/Authorization/UserDelegatedAccessHandlerTests.cs +++ b/Apps/Common/test/unit/AccessManagement/Authorization/UserDelegatedAccessHandlerTests.cs @@ -18,7 +18,6 @@ namespace HealthGateway.CommonTests.AccessManagement.Authorization using System; using System.Collections.Generic; using System.Globalization; - using System.Linq; using System.Security.Claims; using System.Threading; using System.Threading.Tasks; @@ -73,7 +72,7 @@ public async Task UnknownRequirement() httpContextAccessorMock.Object, new Mock().Object, new Mock().Object); - NameAuthorizationRequirement[] requirements = { new(this.username) }; + NameAuthorizationRequirement[] requirements = [new(this.username)]; AuthorizationHandlerContext context = new(requirements, claimsPrincipal, null); @@ -118,7 +117,7 @@ public async Task ReadWriteNoResource() httpContextAccessorMock.Object, new Mock().Object, new Mock().Object); - PersonalFhirRequirement[] requirements = { new(FhirResource.Patient, FhirAccessType.Read) }; + PersonalFhirRequirement[] requirements = [new(FhirResource.Patient, FhirAccessType.Read)]; AuthorizationHandlerContext context = new(requirements, claimsPrincipal, null); @@ -148,7 +147,7 @@ public async Task ShouldNotAuthPatientReadAsUserDelegationDisabled() httpContextAccessorMock.Object, new Mock().Object, new Mock().Object); - PersonalFhirRequirement[] requirements = { new(FhirResource.Patient, FhirAccessType.Read, supportsUserDelegation: false) }; + PersonalFhirRequirement[] requirements = [new(FhirResource.Patient, FhirAccessType.Read, supportsUserDelegation: false)]; AuthorizationHandlerContext context = new(requirements, claimsPrincipal, null); @@ -177,7 +176,7 @@ public async Task ShouldNotAuthPatientReadAsOwner() httpContextAccessorMock.Object, new Mock().Object, new Mock().Object); - PersonalFhirRequirement[] requirements = { new(FhirResource.Patient, FhirAccessType.Read) }; + PersonalFhirRequirement[] requirements = [new(FhirResource.Patient, FhirAccessType.Read)]; AuthorizationHandlerContext context = new(requirements, claimsPrincipal, null); @@ -227,7 +226,7 @@ public async Task ShouldAuthResourceDelegate(bool configContainsMaxAge) httpContextAccessorMock.Object, mockPatientService.Object, mockDependentDelegate.Object); - PersonalFhirRequirement[] requirements = { new(FhirResource.Observation, FhirAccessType.Read, supportsUserDelegation: true) }; + PersonalFhirRequirement[] requirements = [new(FhirResource.Observation, FhirAccessType.Read, supportsUserDelegation: true)]; AuthorizationHandlerContext context = new(requirements, claimsPrincipal, null); @@ -322,7 +321,7 @@ private static IConfigurationRoot GetConfiguration(bool includeMaxDependentAge = } return new ConfigurationBuilder() - .AddInMemoryCollection(configDictionary.ToList()) + .AddInMemoryCollection(configDictionary) .Build(); } @@ -330,9 +329,9 @@ private ClaimsPrincipal GetClaimsPrincipal() { List claims = [ - new Claim(ClaimTypes.Name, this.username), - new Claim(ClaimTypes.NameIdentifier, this.userId), - new Claim(GatewayClaims.Hdid, this.hdid), + new(ClaimTypes.Name, this.username), + new(ClaimTypes.NameIdentifier, this.userId), + new(GatewayClaims.Hdid, this.hdid), ]; ClaimsIdentity identity = new(claims, "TestAuth"); return new ClaimsPrincipal(identity); diff --git a/Apps/Common/test/unit/Auditing/DbAuditLoggerTests.cs b/Apps/Common/test/unit/Auditing/DbAuditLoggerTests.cs index 730d1e6dce..18e132812e 100644 --- a/Apps/Common/test/unit/Auditing/DbAuditLoggerTests.cs +++ b/Apps/Common/test/unit/Auditing/DbAuditLoggerTests.cs @@ -58,7 +58,7 @@ public void ShouldPopulateWithHttpContext(bool useRouteValues, bool useQueryPara // Arrange DefaultHttpContext ctx = new() { - Connection = { RemoteIpAddress = new IPAddress(new byte[] { 127, 0, 0, 1 }) }, + Connection = { RemoteIpAddress = new IPAddress([127, 0, 0, 1]) }, User = new(new ClaimsIdentity([new Claim("hdid", Hdid), new Claim("preferred_username", Idir)])), }; @@ -111,7 +111,7 @@ public void ShouldPopulateWithHttpContextHandleStatus401() { DefaultHttpContext ctx = new() { - Connection = { RemoteIpAddress = new IPAddress(new byte[] { 127, 0, 0, 1 }) }, + Connection = { RemoteIpAddress = new IPAddress([127, 0, 0, 1]) }, Response = { StatusCode = 401 }, }; AuditEvent expected = new() @@ -142,7 +142,7 @@ public void ShouldPopulateWithHttpContextHandleOtherStatus400() { DefaultHttpContext ctx = new() { - Connection = { RemoteIpAddress = new IPAddress(new byte[] { 127, 0, 0, 1 }) }, + Connection = { RemoteIpAddress = new IPAddress([127, 0, 0, 1]) }, Response = { StatusCode = 405 }, }; AuditEvent expected = new() @@ -173,7 +173,7 @@ public void ShouldPopulateWithHttpContextHandle500() { DefaultHttpContext ctx = new() { - Connection = { RemoteIpAddress = new IPAddress(new byte[] { 127, 0, 0, 1 }) }, + Connection = { RemoteIpAddress = new IPAddress([127, 0, 0, 1]) }, Response = { StatusCode = 500 }, }; AuditEvent expected = new() @@ -205,7 +205,7 @@ public async Task ShouldWriteAuditEvent() { DefaultHttpContext ctx = new() { - Connection = { RemoteIpAddress = new IPAddress(new byte[] { 127, 0, 0, 1 }) }, + Connection = { RemoteIpAddress = new IPAddress([127, 0, 0, 1]) }, }; AuditEvent expected = new() { @@ -235,7 +235,7 @@ public async Task ShouldWriteAuditEventHandleException() { DefaultHttpContext ctx = new() { - Connection = { RemoteIpAddress = new IPAddress(new byte[] { 127, 0, 0, 1 }) }, + Connection = { RemoteIpAddress = new IPAddress([127, 0, 0, 1]) }, }; AuditEvent expected = new() { diff --git a/Apps/Common/test/unit/CacheProviders/DistributedCacheProviderTests.cs b/Apps/Common/test/unit/CacheProviders/DistributedCacheProviderTests.cs index 32df332d29..5a12130338 100644 --- a/Apps/Common/test/unit/CacheProviders/DistributedCacheProviderTests.cs +++ b/Apps/Common/test/unit/CacheProviders/DistributedCacheProviderTests.cs @@ -284,7 +284,7 @@ private static object GetDefaultItemValue(CacheType cacheType) return number; case CacheType.ObjectType: - IEnumerable dataSources = new[] { DataSource.Immunization }; + IEnumerable dataSources = [DataSource.Immunization]; return dataSources; case CacheType.StringType: diff --git a/Apps/Common/test/unit/Delegates/AesCryptoDelegateTests.cs b/Apps/Common/test/unit/Delegates/AesCryptoDelegateTests.cs index 4e6fb236a8..2f2d83cd51 100644 --- a/Apps/Common/test/unit/Delegates/AesCryptoDelegateTests.cs +++ b/Apps/Common/test/unit/Delegates/AesCryptoDelegateTests.cs @@ -51,7 +51,7 @@ public void VerifyConfigurationBinding() }; IConfigurationRoot configuration = new ConfigurationBuilder() - .AddInMemoryCollection(myConfiguration.ToList()) + .AddInMemoryCollection(myConfiguration) .Build(); AesCryptoDelegate aesDelegate = new(configuration); @@ -92,7 +92,7 @@ public void VerifyKeyGeneration() }; IConfigurationRoot configuration = new ConfigurationBuilder() - .AddInMemoryCollection(myConfiguration.ToList()) + .AddInMemoryCollection(myConfiguration) .Build(); AesCryptoDelegate aesDelegate = new(configuration); diff --git a/Apps/Common/test/unit/Delegates/CDogsDelegateTests.cs b/Apps/Common/test/unit/Delegates/CDogsDelegateTests.cs index 6067fc61e7..9fbd91fdff 100644 --- a/Apps/Common/test/unit/Delegates/CDogsDelegateTests.cs +++ b/Apps/Common/test/unit/Delegates/CDogsDelegateTests.cs @@ -97,7 +97,7 @@ public async Task ShouldReturnErrorForGenerateReportAsyncHttpError() using HttpResponseMessage httpResponseMessage = new(); httpResponseMessage.StatusCode = statusCode; - httpResponseMessage.Content = new ByteArrayContent(Array.Empty()); + httpResponseMessage.Content = new ByteArrayContent([]); Mock> mockLogger = new(); Mock mockCdogsApi = new(); diff --git a/Apps/Common/test/unit/Delegates/ClientRegistriesDelegateTests.cs b/Apps/Common/test/unit/Delegates/ClientRegistriesDelegateTests.cs index fab1ec577a..8d2c91a1c7 100644 --- a/Apps/Common/test/unit/Delegates/ClientRegistriesDelegateTests.cs +++ b/Apps/Common/test/unit/Delegates/ClientRegistriesDelegateTests.cs @@ -773,21 +773,18 @@ private static HCIM_IN_GetDemographicsResponse1 GenerateDemographicResponse( private static II[] GenerateId(bool shouldReturnEmpty = false, string? extension = null, string? oidType = null) { - if (shouldReturnEmpty) - { - return []; - } - - return - [ - new II - { - root = oidType ?? HdidOidType, - extension = oidType == null || (oidType == HdidOidType && extension == null) ? Hdid - : oidType == PhnOidType && extension == null ? Phn : extension, - displayable = true, - }, - ]; + return shouldReturnEmpty + ? [] + : + [ + new II + { + root = oidType ?? HdidOidType, + extension = oidType == null || (oidType == HdidOidType && extension == null) ? Hdid + : oidType == PhnOidType && extension == null ? Phn : extension, + displayable = true, + }, + ]; } private static IEnumerable GenerateItems(IEnumerable givenNames, IEnumerable familyNames) @@ -848,7 +845,9 @@ private static HCIM_IN_GetDemographicsResponsePerson GenerateIdentifiedPerson( return new HCIM_IN_GetDemographicsResponsePerson { deceasedInd = new BL - { value = deceasedInd }, + { + value = deceasedInd, + }, id = GenerateId(shouldReturnEmpty, extension, oidType), name = names.ToArray(), birthTime = new TS diff --git a/Apps/Common/test/unit/Delegates/HmacHashDelegateTests.cs b/Apps/Common/test/unit/Delegates/HmacHashDelegateTests.cs index 2f6271cf61..a5323e698f 100644 --- a/Apps/Common/test/unit/Delegates/HmacHashDelegateTests.cs +++ b/Apps/Common/test/unit/Delegates/HmacHashDelegateTests.cs @@ -54,7 +54,7 @@ public void VerifyConfigurationBinding() }; IConfigurationRoot configuration = new ConfigurationBuilder() - .AddInMemoryCollection(myConfiguration.ToList()) + .AddInMemoryCollection(myConfiguration) .Build(); HmacHashDelegate hashDelegate = new(configuration); diff --git a/Apps/Common/test/unit/Delegates/RestTokenSwapDelegateTests.cs b/Apps/Common/test/unit/Delegates/RestTokenSwapDelegateTests.cs index e3c0530013..d41fa1c2a0 100644 --- a/Apps/Common/test/unit/Delegates/RestTokenSwapDelegateTests.cs +++ b/Apps/Common/test/unit/Delegates/RestTokenSwapDelegateTests.cs @@ -16,7 +16,6 @@ namespace HealthGateway.CommonTests.Delegates { using System.Collections.Generic; - using System.Linq; using System.Net.Http; using System.Threading; using System.Threading.Tasks; @@ -103,7 +102,7 @@ private static IConfigurationRoot GetIConfigurationRoot() }; return new ConfigurationBuilder() - .AddInMemoryCollection(configuration.ToList()) + .AddInMemoryCollection(configuration) .Build(); } diff --git a/Apps/Common/test/unit/Delegates/VaccineProofDelegateTests.cs b/Apps/Common/test/unit/Delegates/VaccineProofDelegateTests.cs index c96c799197..f51eb30ebf 100644 --- a/Apps/Common/test/unit/Delegates/VaccineProofDelegateTests.cs +++ b/Apps/Common/test/unit/Delegates/VaccineProofDelegateTests.cs @@ -406,7 +406,7 @@ public async Task ValidateGetAssetAsyncSuccess() TotalResultCount = 1, }; - byte[] fileContents = { 1 }; + byte[] fileContents = [1]; using MemoryStream memoryStream = new(fileContents); using HttpResponseMessage httpResponseMessage = new(); httpResponseMessage.StatusCode = HttpStatusCode.OK; @@ -461,7 +461,7 @@ public async Task ValidateGetAssetAsyncNotFound() public async Task ValidateGetAssetAsyncEmptyPayload() { Uri jobUri = new($"https://localhost/{JobId}"); - byte[] fileContents = Array.Empty(); + byte[] fileContents = []; using MemoryStream memoryStream = new(fileContents); using HttpResponseMessage httpResponseMessage = new(); httpResponseMessage.StatusCode = HttpStatusCode.OK; diff --git a/Apps/Common/test/unit/Messaging/AzureServiceBusTests.cs b/Apps/Common/test/unit/Messaging/AzureServiceBusTests.cs index 33802e12a7..7849676afa 100644 --- a/Apps/Common/test/unit/Messaging/AzureServiceBusTests.cs +++ b/Apps/Common/test/unit/Messaging/AzureServiceBusTests.cs @@ -67,9 +67,9 @@ public async Task ValidateSendAsync(int messageCount, int batchSize, int expecte // Arrange IEnumerable allMessages = [ - new MessageEnvelope(AccountCreatedEvent, AccountCreatedEvent.Hdid) { CreatedOn = DateTime }, - new MessageEnvelope(AccountClosedEvent, AccountClosedEvent.Hdid) { CreatedOn = DateTime }, - new MessageEnvelope(DependentAddedEvent, DependentAddedEvent.DelegateHdid) { CreatedOn = DateTime }, + new(AccountCreatedEvent, AccountCreatedEvent.Hdid) { CreatedOn = DateTime }, + new(AccountClosedEvent, AccountClosedEvent.Hdid) { CreatedOn = DateTime }, + new(DependentAddedEvent, DependentAddedEvent.DelegateHdid) { CreatedOn = DateTime }, ]; IList messages = allMessages.Take(messageCount).ToList(); IList expectedMessages = messages.Select(m => new ServiceBusMessage { SessionId = m.SessionId, Body = new(m.Content.Serialize(false)) }).ToList(); @@ -236,14 +236,16 @@ private static SendAsyncSetup GetSendAsyncSetup(int messageCount, int batchSize) attemptedAddMessageCollections.Add(attemptedAddMessageCollection); int callCount = 0; - Func tryAddFunc = message => + + setupSequentialResult = setupSequentialResult.ReturnsAsync(ServiceBusModelFactory.ServiceBusMessageBatch(0, [], null, TryAddFunc)); + continue; + + bool TryAddFunc(ServiceBusMessage message) { bool added = callCount++ < batchSize; attemptedAddMessageCollection.Add((message, added)); return added; - }; - - setupSequentialResult = setupSequentialResult.ReturnsAsync(ServiceBusModelFactory.ServiceBusMessageBatch(0, [], null, tryAddFunc)); + } } setupSequentialResult.ThrowsAsync(new InvalidOperationException("More batches were created than expected.")); diff --git a/Apps/Common/test/unit/Services/AccessTokenServiceTests.cs b/Apps/Common/test/unit/Services/AccessTokenServiceTests.cs index fcd4d5a506..4ec3be3f3b 100644 --- a/Apps/Common/test/unit/Services/AccessTokenServiceTests.cs +++ b/Apps/Common/test/unit/Services/AccessTokenServiceTests.cs @@ -16,7 +16,6 @@ namespace HealthGateway.CommonTests.Services { using System.Collections.Generic; - using System.Linq; using System.Threading; using System.Threading.Tasks; using HealthGateway.Common.AccessManagement.Authentication; @@ -144,7 +143,7 @@ private static IConfigurationRoot GetIConfigurationRoot(bool cacheEnabled) } return new ConfigurationBuilder() - .AddInMemoryCollection(configuration.ToList()) + .AddInMemoryCollection(configuration) .Build(); } diff --git a/Apps/Common/test/unit/Services/CommunicationServiceTests.cs b/Apps/Common/test/unit/Services/CommunicationServiceTests.cs index 1bbdc387c6..439862a579 100644 --- a/Apps/Common/test/unit/Services/CommunicationServiceTests.cs +++ b/Apps/Common/test/unit/Services/CommunicationServiceTests.cs @@ -77,7 +77,11 @@ public async Task ShouldGetActiveCommunicationFromCache(Scenario scenario, Commu EffectiveDateTime = scenario switch { Scenario.Future => DateTime.UtcNow.AddDays(3), - _ => DateTime.UtcNow, + Scenario.Active => DateTime.UtcNow, + Scenario.Expired => DateTime.UtcNow, + Scenario.Deleted => DateTime.UtcNow, + Scenario.DifferentCache => DateTime.UtcNow, + _ => throw new ArgumentOutOfRangeException(nameof(scenario), scenario, "Unhandled scenario value"), }, }; @@ -100,9 +104,15 @@ public async Task ShouldGetActiveCommunicationFromCache(Scenario scenario, Commu Assert.Equal(ResultType.Success, actualResult.ResultStatus); break; - default: + case Scenario.Active: + case Scenario.Expired: + case Scenario.Deleted: + case Scenario.DifferentCache: Assert.Equal(commResult.ResourcePayload!.Id, actualResult.ResourcePayload!.Id); break; + + default: + throw new ArgumentOutOfRangeException(nameof(scenario), $"Unexpected scenario: {scenario}"); } } @@ -221,6 +231,9 @@ public void ShouldProcessChangeEvent(string action, Scenario scenario, bool cach communication.ExpiryDateTime = DateTime.Now.AddDays(5); break; + case Scenario.Active: + case Scenario.Deleted: + case Scenario.DifferentCache: default: communication.EffectiveDateTime = DateTime.Now; communication.ExpiryDateTime = DateTime.Now.AddDays(1); @@ -306,6 +319,9 @@ public void ShouldProcessChangeEvent(string action, Scenario scenario, bool cach Assert.Equal(ResultType.Success, cacheResult!.ResultStatus); Assert.Equal(1, cacheResult.TotalResultCount); break; + + default: + throw new InvalidOperationException($"Unhandled scenario: {scenario}"); } } diff --git a/Apps/Common/test/unit/Services/PatientServiceTests.cs b/Apps/Common/test/unit/Services/PatientServiceTests.cs index cb73245055..0d6849c79b 100644 --- a/Apps/Common/test/unit/Services/PatientServiceTests.cs +++ b/Apps/Common/test/unit/Services/PatientServiceTests.cs @@ -227,7 +227,7 @@ public async Task ShouldThrowIfInvalidIdentifierType() } /// - /// GetPatient - Returns action required when identifer is null. + /// GetPatient - Returns action required when identifier is null. /// /// The identifier type used to query with. /// @@ -297,7 +297,7 @@ private static async Task GetPatientAsync(PatientIdentifierType identifierType, Mock patientDelegateMock = new(); IConfigurationRoot config = new ConfigurationBuilder() - .AddInMemoryCollection(configDictionary.ToList()) + .AddInMemoryCollection(configDictionary) .Build(); patientDelegateMock.Setup(p => p.GetDemographicsByHdidAsync(It.IsAny(), false, It.IsAny())).ReturnsAsync(requestResult); diff --git a/Apps/Common/test/unit/Services/PersonalAccountServiceTests.cs b/Apps/Common/test/unit/Services/PersonalAccountServiceTests.cs index f95b473c04..5497267d55 100644 --- a/Apps/Common/test/unit/Services/PersonalAccountServiceTests.cs +++ b/Apps/Common/test/unit/Services/PersonalAccountServiceTests.cs @@ -17,7 +17,6 @@ namespace HealthGateway.CommonTests.Services { using System; using System.Collections.Generic; - using System.Linq; using System.Net.Http; using System.Threading; using System.Threading.Tasks; @@ -101,7 +100,7 @@ private static IConfigurationRoot GetIConfigurationRoot(string cacheToLive = "90 }; return new ConfigurationBuilder() - .AddInMemoryCollection(configuration.ToList()) + .AddInMemoryCollection(configuration) .Build(); } diff --git a/Apps/Common/test/unit/Utils/DateOnlyJsonConverterTests.cs b/Apps/Common/test/unit/Utils/DateOnlyJsonConverterTests.cs index 957377e2e9..5bc082ce66 100644 --- a/Apps/Common/test/unit/Utils/DateOnlyJsonConverterTests.cs +++ b/Apps/Common/test/unit/Utils/DateOnlyJsonConverterTests.cs @@ -55,7 +55,7 @@ public void ShouldDeserialize() Converters = { new DateOnlyJsonConverter() }, }; - object? actualResult = JsonSerializer.Deserialize($@"""{dateStr}""", typeof(DateOnly), options); + object? actualResult = JsonSerializer.Deserialize($@"""{dateStr}""", options); Assert.IsType(actualResult); Assert.True(date.Equals(actualResult)); diff --git a/Apps/Common/test/unit/Utils/HttpContextHelperTests.cs b/Apps/Common/test/unit/Utils/HttpContextHelperTests.cs index dd84921f74..4d52820793 100644 --- a/Apps/Common/test/unit/Utils/HttpContextHelperTests.cs +++ b/Apps/Common/test/unit/Utils/HttpContextHelperTests.cs @@ -1,18 +1,18 @@ -//------------------------------------------------------------------------- -// Copyright © 2019 Province of British Columbia +// ------------------------------------------------------------------------- +// Copyright © 2019 Province of British Columbia // -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// http://www.apache.org/licenses/LICENSE-2.0 // -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -//------------------------------------------------------------------------- +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// ------------------------------------------------------------------------- namespace HealthGateway.CommonTests.Utils { using System; @@ -61,7 +61,7 @@ public void ShouldGetResourceHdid(FhirSubjectLookupMethod lookupMethod) Assert.Equal(expected, actual); } - [SuppressMessage("ReSharper", "SwitchStatementHandlesSomeKnownEnumValuesWithDefault", Justification = "Unknown enum value expected and is handled in mock setup.")] + [SuppressMessage("Style", "IDE0010:Populate switch", Justification = "Team decision")] private static Mock SetupHttpContextForGetResourceHdid(FhirSubjectLookupMethod lookupMethod) { Mock httpRequestMock = new(); diff --git a/Apps/Common/test/unit/Utils/SerializationHelperTests.cs b/Apps/Common/test/unit/Utils/SerializationHelperTests.cs index 201ff9622a..cd0947e896 100644 --- a/Apps/Common/test/unit/Utils/SerializationHelperTests.cs +++ b/Apps/Common/test/unit/Utils/SerializationHelperTests.cs @@ -37,11 +37,11 @@ public class SerializationHelperTests [InlineData(typeof(string[]))] public void ShouldReturnDefaultOfGenericIfNoData(Type type) { - MethodInfo? deserializerRef = typeof(SerializationHelper).GetMethod(nameof(SerializationHelper.Deserialize), 2, new[] { typeof(byte[]), typeof(JsonSerializerOptions) }) + MethodInfo? deserializerRef = typeof(SerializationHelper).GetMethod(nameof(SerializationHelper.Deserialize), 2, [typeof(byte[]), typeof(JsonSerializerOptions)]) ?.MakeGenericMethod(type); if (deserializerRef != null) { - byte[] data = Array.Empty(); + byte[] data = []; Assert.Equal(Activator.CreateInstance(type), deserializerRef.Invoke(data, null)); byte[]? dataNull = null; Assert.Equal(Activator.CreateInstance(type), deserializerRef.Invoke(dataNull, null)); @@ -49,13 +49,13 @@ public void ShouldReturnDefaultOfGenericIfNoData(Type type) } /// - /// Non generic deserialize should return default of Object? when data is or empty which is null. + /// Non-generic deserialize should return default of Object? when data is or empty which is null. /// [Fact] public void ShouldReturnNullIfNoData() { Type anyType = typeof(string); - byte[] data = Array.Empty(); + byte[] data = []; byte[]? dataNull = null; Assert.Null(data.Deserialize(anyType)); Assert.Null(dataNull.Deserialize(anyType)); @@ -89,7 +89,7 @@ public void ShouldReturnEmptyByteArrayWhenNull() [Fact] public void ShouldSerializeWhetherConcreteOrGeneric() { - string anyObj = "SomeValue"; + const string anyObj = "SomeValue"; // serialize and deserialize using concrete byte[] serialized = anyObj.Serialize(); @@ -98,7 +98,7 @@ public void ShouldSerializeWhetherConcreteOrGeneric() // serialize and deserialize using generic byte[] serialized2 = anyObj.Serialize(false); - string? deserialized2 = serialized2.Deserialize(typeof(string)) as string; + string? deserialized2 = serialized2.Deserialize(); Assert.Equal(anyObj, deserialized2); // serialize results should be equivalent. diff --git a/Apps/Common/test/unit/Utils/TimeOnlyJsonConverterTests.cs b/Apps/Common/test/unit/Utils/TimeOnlyJsonConverterTests.cs index 97b80d47d3..af192f2591 100644 --- a/Apps/Common/test/unit/Utils/TimeOnlyJsonConverterTests.cs +++ b/Apps/Common/test/unit/Utils/TimeOnlyJsonConverterTests.cs @@ -57,7 +57,7 @@ public void ShouldDeserialize() Converters = { new TimeOnlyJsonConverter() }, }; - object? actualResult = JsonSerializer.Deserialize($@"""{timeStr}""", typeof(TimeOnly), options); + object? actualResult = JsonSerializer.Deserialize($@"""{timeStr}""", options); Assert.IsType(actualResult); Assert.True(time.Equals(actualResult)); diff --git a/Apps/Common/test/unit/Validations/VaccineStatusQueryValidatorTests.cs b/Apps/Common/test/unit/Validations/VaccineStatusQueryValidatorTests.cs index aa55709463..e663bb6567 100644 --- a/Apps/Common/test/unit/Validations/VaccineStatusQueryValidatorTests.cs +++ b/Apps/Common/test/unit/Validations/VaccineStatusQueryValidatorTests.cs @@ -17,6 +17,7 @@ namespace HealthGateway.CommonTests.Validations { using System; + using FluentValidation.Results; using HealthGateway.Common.Models.PHSA; using HealthGateway.Common.Validations; using Xunit; @@ -38,13 +39,14 @@ public class VaccineStatusQueryValidatorTests [InlineData("2000-01-01", "2021-01-01", "", "PHN is empty")] public void ShouldNotBeValid(DateTime dob, DateTime dov, string phn, string reason) { - var validator = new VaccineStatusQueryValidator(); - var validationResult = validator.Validate(new VaccineStatusQuery - { - DateOfBirth = dob, - DateOfVaccine = dov, - PersonalHealthNumber = phn, - }); + VaccineStatusQueryValidator validator = new(); + ValidationResult? validationResult = validator.Validate( + new VaccineStatusQuery + { + DateOfBirth = dob, + DateOfVaccine = dov, + PersonalHealthNumber = phn, + }); Assert.False(validationResult.IsValid, reason); } @@ -59,13 +61,14 @@ public void ShouldNotBeValid(DateTime dob, DateTime dov, string phn, string reas [InlineData("2000-01-01", "2021-01-01", "9735353315")] public void ShouldBeValid(DateTime dob, DateTime dov, string phn) { - var validator = new VaccineStatusQueryValidator(); - var validationResult = validator.Validate(new VaccineStatusQuery - { - DateOfBirth = dob, - DateOfVaccine = dov, - PersonalHealthNumber = phn, - }); + VaccineStatusQueryValidator validator = new(); + ValidationResult? validationResult = validator.Validate( + new VaccineStatusQuery + { + DateOfBirth = dob, + DateOfVaccine = dov, + PersonalHealthNumber = phn, + }); Assert.True(validationResult.IsValid); } diff --git a/Apps/CommonData/src/Models/Address.cs b/Apps/CommonData/src/Models/Address.cs index 009006e60a..649093c70a 100644 --- a/Apps/CommonData/src/Models/Address.cs +++ b/Apps/CommonData/src/Models/Address.cs @@ -16,7 +16,6 @@ namespace HealthGateway.Common.Data.Models { using System.Collections.Generic; - using System.Linq; /// /// Represents an address. @@ -26,7 +25,7 @@ public class Address /// /// Gets or sets the street lines. /// - public IEnumerable StreetLines { get; set; } = Enumerable.Empty(); + public IEnumerable StreetLines { get; set; } = []; /// /// Gets or sets the city name. diff --git a/Apps/CommonData/src/Utils/AddressUtility.cs b/Apps/CommonData/src/Utils/AddressUtility.cs index 9da47cc400..d478cdf054 100644 --- a/Apps/CommonData/src/Utils/AddressUtility.cs +++ b/Apps/CommonData/src/Utils/AddressUtility.cs @@ -240,7 +240,7 @@ public static string GetAddressAsSingleLine(Address? address, bool includeCountr } IEnumerable addressElements = address.StreetLines - .Concat(new[] { address.City, address.State, address.PostalCode }); + .Concat([address.City, address.State, address.PostalCode]); if (includeCountry) { diff --git a/Apps/CommonData/src/Utils/EnumUtility.cs b/Apps/CommonData/src/Utils/EnumUtility.cs index cf2899f55a..f451fe6b3d 100644 --- a/Apps/CommonData/src/Utils/EnumUtility.cs +++ b/Apps/CommonData/src/Utils/EnumUtility.cs @@ -45,7 +45,7 @@ public static string ToEnumString(T instance, bool useAttribute = false) if (attr != null) { // if there's no EnumMember attr, use the default value - enumString = attr.Value !; + enumString = attr.Value!; } } } diff --git a/Apps/CommonData/src/Validations/PhnValidator.cs b/Apps/CommonData/src/Validations/PhnValidator.cs index 6e3edd691e..ee1b4787c2 100644 --- a/Apps/CommonData/src/Validations/PhnValidator.cs +++ b/Apps/CommonData/src/Validations/PhnValidator.cs @@ -26,7 +26,7 @@ namespace HealthGateway.Common.Data.Validations /// public class PhnValidator : AbstractValidator { - private static readonly int[] PhnSigDigits = { 2, 4, 8, 5, 10, 9, 7, 3 }; + private static readonly int[] PhnSigDigits = [2, 4, 8, 5, 10, 9, 7, 3]; /// /// Initializes a new instance of the class. @@ -49,7 +49,7 @@ public static bool IsValid(string? phn) private static bool IsValidInternal(string? phn) { - if (string.IsNullOrEmpty(phn) || phn.Length != 10 || !phn.All(c => char.IsDigit(c)) || phn[0] != '9') + if (string.IsNullOrEmpty(phn) || phn.Length != 10 || !phn.All(char.IsDigit) || phn[0] != '9') { return false; } diff --git a/Apps/CommonData/test/unit/Extensions/ClaimsPrincipalExtensionsTests.cs b/Apps/CommonData/test/unit/Extensions/ClaimsPrincipalExtensionsTests.cs index 288104b31f..adf72bd21d 100644 --- a/Apps/CommonData/test/unit/Extensions/ClaimsPrincipalExtensionsTests.cs +++ b/Apps/CommonData/test/unit/Extensions/ClaimsPrincipalExtensionsTests.cs @@ -43,7 +43,7 @@ public class ClaimsPrincipalExtensionsTests public void ValidateToEnumString(string[] userRoles, string[] targetRoles, bool expected) { IEnumerable claims = userRoles.Select(r => new Claim(ClaimsIdentity.DefaultRoleClaimType, r)); - ClaimsPrincipal user = new(new[] { new ClaimsIdentity(claims) }); + ClaimsPrincipal user = new([new ClaimsIdentity(claims)]); bool actual = user.IsInAnyRole(targetRoles); diff --git a/Apps/CommonData/test/unit/Utils/DateFormatterTests.cs b/Apps/CommonData/test/unit/Utils/DateFormatterTests.cs index 532ca38050..c2fea27436 100644 --- a/Apps/CommonData/test/unit/Utils/DateFormatterTests.cs +++ b/Apps/CommonData/test/unit/Utils/DateFormatterTests.cs @@ -17,7 +17,6 @@ namespace HealthGateway.Common.Data.Tests.Utils { using System; using System.Collections.Generic; - using System.Linq; using HealthGateway.Common.Data.Utils; using Microsoft.Extensions.Configuration; using Xunit; @@ -211,7 +210,7 @@ private static IConfigurationRoot GetIConfigurationRoot(string unixLocalTimeZone }; return new ConfigurationBuilder() - .AddInMemoryCollection(myConfiguration.ToList()) + .AddInMemoryCollection(myConfiguration) .Build(); } } diff --git a/Apps/CommonUi/test/unit/Utils/IJSRuntimeExtensionMethodsTests.cs b/Apps/CommonUi/test/unit/Utils/IJSRuntimeExtensionMethodsTests.cs index 769fbd8878..d99ef783ab 100644 --- a/Apps/CommonUi/test/unit/Utils/IJSRuntimeExtensionMethodsTests.cs +++ b/Apps/CommonUi/test/unit/Utils/IJSRuntimeExtensionMethodsTests.cs @@ -42,9 +42,10 @@ public async Task ShouldInitializeInactivityTimer() jsRuntime.Verify( a => a.InvokeAsync( - It.Is(s => - s.Equals("initializeInactivityTimer", StringComparison.OrdinalIgnoreCase)), - It.IsAny()), + It.Is( + s => + s.Equals("initializeInactivityTimer", StringComparison.OrdinalIgnoreCase)), + It.IsAny()), Times.Once); } } diff --git a/Apps/DBMaintainer/Apps/BCPProvDrugDBApp.cs b/Apps/DBMaintainer/Apps/BCPProvDrugDBApp.cs index 292d3e879c..1ecbc7ff0e 100644 --- a/Apps/DBMaintainer/Apps/BCPProvDrugDBApp.cs +++ b/Apps/DBMaintainer/Apps/BCPProvDrugDBApp.cs @@ -120,10 +120,12 @@ protected override async Task ProcessDownloadAsync(string sourceFolder, FileDown /// Search for all download files matching this one. protected override void RemoveOldFiles(FileDownload downloadedFile) { - List oldIds = this.DrugDbContext.FileDownload - .Where(p => p.ProgramCode == downloadedFile.ProgramCode) - .Select(f => new FileDownload { Id = f.Id, ProgramCode = f.ProgramCode, Version = f.Version }) - .ToList(); + List oldIds = + [ + .. this.DrugDbContext.FileDownload + .Where(p => p.ProgramCode == downloadedFile.ProgramCode) + .Select(f => new FileDownload { Id = f.Id, ProgramCode = f.ProgramCode, Version = f.Version }), + ]; oldIds.ForEach(s => this.Logger.LogInformation("Deleting old file downloads with id: {Id} and program code: {ProgramCode}", s.Id, s.ProgramCode)); this.DrugDbContext.RemoveRange(oldIds); } @@ -131,12 +133,7 @@ protected override void RemoveOldFiles(FileDownload downloadedFile) private static string GetDownloadedFile(string sourceFolder, string filenamePattern) { string[] files = Directory.GetFiles(sourceFolder, filenamePattern); - if (files.Length > 1) - { - throw new FormatException($"The zip file contained {files.Length} CSV files, very confused."); - } - - return files[0]; + return files.Length > 1 ? throw new FormatException($"The zip file contained {files.Length} CSV files, very confused.") : files[0]; } private static void ModifyPharmaCareDrug(PharmacyAssessment pharmacyAssessment, IList pharmaCareDrugs) diff --git a/Apps/DBMaintainer/Apps/BaseDrugApp.cs b/Apps/DBMaintainer/Apps/BaseDrugApp.cs index 51f64be0b6..d819a829b6 100644 --- a/Apps/DBMaintainer/Apps/BaseDrugApp.cs +++ b/Apps/DBMaintainer/Apps/BaseDrugApp.cs @@ -140,10 +140,12 @@ protected async Task AddFileToDbAsync(FileDownload downloadedFile, CancellationT /// Search for all download files not matching this one. protected virtual void RemoveOldFiles(FileDownload downloadedFile) { - List oldIds = this.DrugDbContext.FileDownload - .Where(p => p.ProgramCode == downloadedFile.ProgramCode && p.Hash != downloadedFile.Hash) - .Select(f => new FileDownload { Id = f.Id, Version = f.Version }) - .ToList(); + List oldIds = + [ + .. this.DrugDbContext.FileDownload + .Where(p => p.ProgramCode == downloadedFile.ProgramCode && p.Hash != downloadedFile.Hash) + .Select(f => new FileDownload { Id = f.Id, Version = f.Version }), + ]; oldIds.ForEach(s => this.Logger.LogInformation("Deleting old Download file with hash: {Hash}", s.Hash)); this.DrugDbContext.RemoveRange(oldIds); } diff --git a/Apps/DBMaintainer/Mappers/Converters/BooleanConverter.cs b/Apps/DBMaintainer/Mappers/Converters/BooleanConverter.cs index 68d11b8867..dadb9d9fb1 100644 --- a/Apps/DBMaintainer/Mappers/Converters/BooleanConverter.cs +++ b/Apps/DBMaintainer/Mappers/Converters/BooleanConverter.cs @@ -27,12 +27,7 @@ public class BooleanConverter : DefaultTypeConverter /// public override object? ConvertFromString(string? text, IReaderRow row, MemberMapData memberMapData) { - if (TryConvertToBool(text, out bool result)) - { - return result; - } - - return null; + return TryConvertToBool(text, out bool result) ? result : null; } private static bool TryConvertToBool(string text, out bool result) diff --git a/Apps/DBMaintainer/Mappers/PharmacyAssessmentMapper.cs b/Apps/DBMaintainer/Mappers/PharmacyAssessmentMapper.cs index e362aa10ef..70d086164f 100644 --- a/Apps/DBMaintainer/Mappers/PharmacyAssessmentMapper.cs +++ b/Apps/DBMaintainer/Mappers/PharmacyAssessmentMapper.cs @@ -30,7 +30,9 @@ public sealed class PharmacyAssessmentMapper : ClassMap /// Performs the mapping of read Pharmacy Assessment file to the db model. /// /// The fileDownload to map. - [SuppressMessage("ReSharper", "UnusedParameter.Local", Justification = "Required by ClassMap")] + [SuppressMessage("Style", "IDE0060:Remove unused parameter", Justification = "Required by ClassMap")] + + // ReSharper disable once UnusedParameter.Local public PharmacyAssessmentMapper(FileDownload fileDownload) { this.Map(m => m.Pin).Index(0); diff --git a/Apps/DBMaintainer/Parsers/FederalDrugProductParser.cs b/Apps/DBMaintainer/Parsers/FederalDrugProductParser.cs index 00ff2ecf19..afe2a79fbb 100644 --- a/Apps/DBMaintainer/Parsers/FederalDrugProductParser.cs +++ b/Apps/DBMaintainer/Parsers/FederalDrugProductParser.cs @@ -241,12 +241,7 @@ public IList ParseVeterinarySpeciesFile(string filePath, IEnu private static string GetFileMatching(string sourceFolder, string fileMatch) { string[] files = Directory.GetFiles(sourceFolder, fileMatch); - if (files.Length > 1 || files.Length == 0) - { - throw new FormatException($"The zip file contained {files.Length} CSV files, very confused."); - } - - return files[0]; + return files.Length is > 1 or 0 ? throw new FormatException($"The zip file contained {files.Length} CSV files, very confused.") : files[0]; } } } diff --git a/Apps/DBMaintainer/Program.cs b/Apps/DBMaintainer/Program.cs index 76c2b3fda5..2a063f3b5f 100644 --- a/Apps/DBMaintainer/Program.cs +++ b/Apps/DBMaintainer/Program.cs @@ -74,7 +74,7 @@ public static async Task Main(string[] args) /// /// The IHostBuilder. /// The set of command line arguments. - [SuppressMessage("Usage", "CA1801:Review unused parameters", Justification = "Required for migrations")] + [SuppressMessage("Style", "IDE0060:Remove unused parameter", Justification = "Required for migrations.")] public static IHostBuilder CreateWebHostBuilder(string[] args) { string environment = Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT") ?? "Development"; diff --git a/Apps/Database/src/Delegates/DbBetaFeatureAccessDelegate.cs b/Apps/Database/src/Delegates/DbBetaFeatureAccessDelegate.cs index 27b33d87c2..f6816df3b5 100644 --- a/Apps/Database/src/Delegates/DbBetaFeatureAccessDelegate.cs +++ b/Apps/Database/src/Delegates/DbBetaFeatureAccessDelegate.cs @@ -82,7 +82,7 @@ public async Task>> GetAllA int totalCount = await emailQuery.CountAsync(ct); - IList emailAddresses = await emailQuery + List emailAddresses = await emailQuery .OrderBy(p => p) .Skip(pageIndex * pageSize) .Take(pageSize) diff --git a/Apps/Database/src/Delegates/DbResourceDelegateDelegate.cs b/Apps/Database/src/Delegates/DbResourceDelegateDelegate.cs index 77a5b279ef..fc20d14948 100644 --- a/Apps/Database/src/Delegates/DbResourceDelegateDelegate.cs +++ b/Apps/Database/src/Delegates/DbResourceDelegateDelegate.cs @@ -214,20 +214,23 @@ public async Task SearchAsync(ResourceDelegateQuery dbQuery = dbQuery.Take(query.TakeAmount.Value); } - IList items; - if (query.IncludeDependent) - { - items = await dbQuery.GroupJoin( + IList items = query.IncludeDependent + ? await dbQuery.GroupJoin( dbContext.Dependent, rd => rd.ResourceOwnerHdid, d => d.HdId, - (rd, d) => new ResourceDelegateQueryResultItem { ResourceDelegate = rd, Dependent = d.FirstOrDefault() }) + (rd, d) => new ResourceDelegateQueryResultItem + { + ResourceDelegate = rd, + Dependent = d.FirstOrDefault(), + }) + .ToListAsync(ct) + : await dbQuery.Select( + rd => new ResourceDelegateQueryResultItem + { + ResourceDelegate = rd, + }) .ToListAsync(ct); - } - else - { - items = await dbQuery.Select(rd => new ResourceDelegateQueryResultItem { ResourceDelegate = rd }).ToListAsync(ct); - } return new() { Items = items }; } diff --git a/Apps/Database/src/Wrapper/DBDelegateHelper.cs b/Apps/Database/src/Wrapper/DBDelegateHelper.cs index b12a31d241..5e8ed0e51e 100644 --- a/Apps/Database/src/Wrapper/DBDelegateHelper.cs +++ b/Apps/Database/src/Wrapper/DBDelegateHelper.cs @@ -19,7 +19,6 @@ namespace HealthGateway.Database.Wrapper using System.Linq; using System.Threading; using System.Threading.Tasks; - using HealthGateway.Database.Constants; using Microsoft.EntityFrameworkCore; /// @@ -27,26 +26,6 @@ namespace HealthGateway.Database.Wrapper /// public static class DbDelegateHelper { - /// - /// Gets a list of DBModel records for a specific page. - /// - /// A query that needs to be paged. - /// The starting offset for the query. - /// The maximum amount of rows to return. - /// A DBModel type. - /// A list of DBModel records wrapped in a DBResult. - public static DbResult> GetPagedDbResult(IQueryable query, int page, int pageSize) - where T : class - { - int offset = page * pageSize; - DbResult> result = new() - { - Payload = query.Skip(offset).Take(pageSize).ToList(), - }; - result.Status = DbStatusCode.Read; - return result; - } - /// /// Gets a list of DBModel records for a specific page. /// diff --git a/Apps/Encounter/src/MapProfiles/EncounterModelProfile.cs b/Apps/Encounter/src/MapProfiles/EncounterModelProfile.cs index d32e9da016..76aae55ee4 100644 --- a/Apps/Encounter/src/MapProfiles/EncounterModelProfile.cs +++ b/Apps/Encounter/src/MapProfiles/EncounterModelProfile.cs @@ -41,8 +41,7 @@ public EncounterModelProfile() .ForMember( dest => dest.Clinic, opt => opt.MapFrom( - src => new Clinic - { Name = src.LocationName })) + src => new Clinic { Name = src.LocationName })) .AfterMap( (src, dest) => { diff --git a/Apps/Encounter/src/Models/PHSA/HospitalVisitResult.cs b/Apps/Encounter/src/Models/PHSA/HospitalVisitResult.cs index a1fade298e..b001c87edc 100644 --- a/Apps/Encounter/src/Models/PHSA/HospitalVisitResult.cs +++ b/Apps/Encounter/src/Models/PHSA/HospitalVisitResult.cs @@ -16,7 +16,6 @@ namespace HealthGateway.Encounter.Models.PHSA { using System.Collections.Generic; - using System.Linq; using System.Text.Json.Serialization; /// @@ -49,6 +48,6 @@ public class HospitalVisitResult /// Gets or sets the list of hospital visits. /// [JsonPropertyName("hospitalVisits")] - public IEnumerable HospitalVisits { get; set; } = Enumerable.Empty(); + public IEnumerable HospitalVisits { get; set; } = []; } } diff --git a/Apps/Encounter/test/unit/Delegates/RestHospitalVisitDelegateTests.cs b/Apps/Encounter/test/unit/Delegates/RestHospitalVisitDelegateTests.cs index 40c7d8f304..eda52aca95 100644 --- a/Apps/Encounter/test/unit/Delegates/RestHospitalVisitDelegateTests.cs +++ b/Apps/Encounter/test/unit/Delegates/RestHospitalVisitDelegateTests.cs @@ -167,7 +167,7 @@ private static IConfigurationRoot GetIConfigurationRoot() }; return new ConfigurationBuilder() - .AddInMemoryCollection(configuration.ToList()) + .AddInMemoryCollection(configuration) .Build(); } } diff --git a/Apps/Encounter/test/unit/Services/EncounterServiceTests.cs b/Apps/Encounter/test/unit/Services/EncounterServiceTests.cs index 175a2ddb6f..b0ec8d10fb 100644 --- a/Apps/Encounter/test/unit/Services/EncounterServiceTests.cs +++ b/Apps/Encounter/test/unit/Services/EncounterServiceTests.cs @@ -344,7 +344,7 @@ public async Task GetHospitalVisitsShouldReturnNoRows() ResultStatus = ResultType.Success, ResourcePayload = new PhsaResult> { - Result = Enumerable.Empty(), + Result = [], }, TotalResultCount = 0, }; @@ -377,7 +377,7 @@ public async Task GetHospitalVisitsShouldReturnRefreshInProgress() ResultStatus = ResultType.ActionRequired, ResourcePayload = new PhsaResult> { - Result = Enumerable.Empty(), + Result = [], LoadState = new() { Queued = true, @@ -416,7 +416,7 @@ public async Task GetHospitalVisitsShouldReturnError() ResultStatus = ResultType.Error, ResourcePayload = new PhsaResult> { - Result = Enumerable.Empty(), + Result = [], }, }; IEncounterService service = GetEncounterService(hospitalVisitResults); diff --git a/Apps/GatewayApi/src/Controllers/CommentController.cs b/Apps/GatewayApi/src/Controllers/CommentController.cs index 591ed47716..59ebaaf9d5 100644 --- a/Apps/GatewayApi/src/Controllers/CommentController.cs +++ b/Apps/GatewayApi/src/Controllers/CommentController.cs @@ -130,12 +130,9 @@ public async Task>> Update(string hdid, [Authorize(Policy = UserProfilePolicy.Write)] public async Task>> Delete(string hdid, [FromBody] UserComment comment, CancellationToken ct) { - if (comment.UserProfileId != hdid) - { - return new ForbidResult(); - } - - return await this.commentService.DeleteAsync(comment, ct); + return comment.UserProfileId != hdid + ? new ForbidResult() + : await this.commentService.DeleteAsync(comment, ct); } /// diff --git a/Apps/GatewayApi/src/Controllers/PhsaController.cs b/Apps/GatewayApi/src/Controllers/PhsaController.cs index 38fb8b0f57..244794b9ae 100644 --- a/Apps/GatewayApi/src/Controllers/PhsaController.cs +++ b/Apps/GatewayApi/src/Controllers/PhsaController.cs @@ -18,6 +18,7 @@ namespace HealthGateway.GatewayApi.Controllers { using System; using System.Collections.Generic; + using System.Diagnostics.CodeAnalysis; using System.Threading; using System.Threading.Tasks; using Asp.Versioning; @@ -37,6 +38,7 @@ namespace HealthGateway.GatewayApi.Controllers [ApiVersion("1.0")] [Route("[controller]")] [ApiController] + [SuppressMessage("Major Code Smell", "S6960:Controllers should not have mixed responsibilities", Justification = "Team decision")] public class PhsaController : ControllerBase { private readonly IDependentService dependentService; diff --git a/Apps/GatewayApi/src/Controllers/UserFeedbackController.cs b/Apps/GatewayApi/src/Controllers/UserFeedbackController.cs index 05d014047b..6398418ff1 100644 --- a/Apps/GatewayApi/src/Controllers/UserFeedbackController.cs +++ b/Apps/GatewayApi/src/Controllers/UserFeedbackController.cs @@ -75,12 +75,7 @@ public async Task CreateUserFeedback(string hdid, [FromBody] Feed } DbResult result = await this.userFeedbackService.CreateUserFeedbackAsync(feedback, hdid, ct); - if (result.Status != DbStatusCode.Created) - { - return new ConflictResult(); - } - - return new OkResult(); + return result.Status != DbStatusCode.Created ? new ConflictResult() : new OkResult(); } /// diff --git a/Apps/GatewayApi/src/Controllers/UserProfileController.cs b/Apps/GatewayApi/src/Controllers/UserProfileController.cs index b504dfc808..3bcba62c9a 100644 --- a/Apps/GatewayApi/src/Controllers/UserProfileController.cs +++ b/Apps/GatewayApi/src/Controllers/UserProfileController.cs @@ -39,6 +39,7 @@ namespace HealthGateway.GatewayApi.Controllers [ApiVersion("1.0")] [Route("[controller]")] [ApiController] + [SuppressMessage("Major Code Smell", "S6960:Controllers should not have mixed responsibilities", Justification = "Team decision")] public class UserProfileController : ControllerBase { private readonly IAuthenticationDelegate authenticationDelegate; diff --git a/Apps/GatewayApi/src/Controllers/UserProfileControllerV2.cs b/Apps/GatewayApi/src/Controllers/UserProfileControllerV2.cs index 91f5d5805f..498415d728 100644 --- a/Apps/GatewayApi/src/Controllers/UserProfileControllerV2.cs +++ b/Apps/GatewayApi/src/Controllers/UserProfileControllerV2.cs @@ -41,6 +41,7 @@ namespace HealthGateway.GatewayApi.Controllers [Route("UserProfile")] [ApiController] [ExcludeFromCodeCoverage] + [SuppressMessage("Major Code Smell", "S6960:Controllers should not have mixed responsibilities", Justification = "Team decision")] public class UserProfileControllerV2 : ControllerBase { private readonly IHttpContextAccessor httpContextAccessor; @@ -131,7 +132,7 @@ public async Task> CreateUserProfile(string hdid, /// The requested user profile, or an empty profile if the requested profile doesn't exist. /// The user hdid. /// to manage the async request. - /// Returns the requested user profile, or an empty profile if the requested profile doesn't exists. + /// Returns the requested user profile, or an empty profile if the requested profile doesn't exist. /// Validation error. /// The client must authenticate itself to get the requested response. /// @@ -415,12 +416,9 @@ public async Task UpdateUserSmsNumberAsync(string hdid, [FromBody public async Task> UpdateUserPreference(string hdid, [FromBody] UserPreferenceModel? userPreferenceModel, CancellationToken ct) { await new UserPreferenceModelValidator().ValidateAndThrowAsync(userPreferenceModel, ct); - if (!hdid.Equals(userPreferenceModel?.HdId, StringComparison.OrdinalIgnoreCase)) - { - return new ForbidResult(); - } - - return await this.userPreferenceService.UpdateUserPreferenceAsync(hdid, userPreferenceModel, ct); + return !hdid.Equals(userPreferenceModel?.HdId, StringComparison.OrdinalIgnoreCase) + ? new ForbidResult() + : await this.userPreferenceService.UpdateUserPreferenceAsync(hdid, userPreferenceModel, ct); } /// diff --git a/Apps/GatewayApi/src/Services/CommentService.cs b/Apps/GatewayApi/src/Services/CommentService.cs index 2213a33f8b..d8a907c774 100644 --- a/Apps/GatewayApi/src/Services/CommentService.cs +++ b/Apps/GatewayApi/src/Services/CommentService.cs @@ -35,6 +35,7 @@ namespace HealthGateway.GatewayApi.Services public class CommentService : ICommentService { private const string ProfileKeyNotSet = "Profile Key not set"; + private const string ProfileEncryptionKeyMissing = "Profile does not have an encryption key"; private readonly IGatewayApiMappingService mappingService; private readonly ICommentDelegate commentDelegate; @@ -75,19 +76,16 @@ public async Task> AddAsync(UserComment userComment, string? key = profile?.EncryptionKey; if (key == null) { - this.logger.LogError("Profile does not have an encryption key"); + this.logger.LogError(ProfileEncryptionKeyMissing); return RequestResultFactory.ServiceError(ErrorType.InvalidState, ServiceType.Database, ProfileKeyNotSet); } Comment comment = this.mappingService.MapToComment(userComment, key); DbResult dbResult = await this.commentDelegate.AddAsync(comment, ct: ct); - if (dbResult.Status != DbStatusCode.Created) - { - return RequestResultFactory.ServiceError(ErrorType.CommunicationInternal, ServiceType.Database, dbResult.Message); - } - - return RequestResultFactory.Success(this.mappingService.MapToUserComment(dbResult.Payload, key)); + return dbResult.Status != DbStatusCode.Created + ? RequestResultFactory.ServiceError(ErrorType.CommunicationInternal, ServiceType.Database, dbResult.Message) + : RequestResultFactory.Success(this.mappingService.MapToUserComment(dbResult.Payload, key)); } /// @@ -99,22 +97,19 @@ public async Task>> GetEntryCommentsAsync // Check that the key has been set if (key == null) { - this.logger.LogError("Profile does not have an encryption key"); + this.logger.LogError(ProfileEncryptionKeyMissing); return RequestResultFactory.ServiceError>(ErrorType.InvalidState, ServiceType.Database, ProfileKeyNotSet); } DbResult> dbComments = await this.commentDelegate.GetByParentEntryAsync(hdId, parentEntryId, ct); - if (dbComments.Status != DbStatusCode.Read) - { - return RequestResultFactory.ServiceError>(ErrorType.CommunicationInternal, ServiceType.Database, dbComments.Message); - } - - return RequestResultFactory.Success( - dbComments.Payload.Select(c => this.mappingService.MapToUserComment(c, key)), - dbComments.Payload.Count, - 0, - dbComments.Payload.Count); + return dbComments.Status != DbStatusCode.Read + ? RequestResultFactory.ServiceError>(ErrorType.CommunicationInternal, ServiceType.Database, dbComments.Message) + : RequestResultFactory.Success( + dbComments.Payload.Select(c => this.mappingService.MapToUserComment(c, key)), + dbComments.Payload.Count, + 0, + dbComments.Payload.Count); } /// @@ -126,24 +121,21 @@ public async Task>>> // Check that the key has been set if (key == null) { - this.logger.LogError("Profile does not have an encryption key"); + this.logger.LogError(ProfileEncryptionKeyMissing); return RequestResultFactory.ServiceError>>(ErrorType.InvalidState, ServiceType.Database, ProfileKeyNotSet); } DbResult> dbComments = await this.commentDelegate.GetAllAsync(hdId, ct); IEnumerable comments = dbComments.Payload.Select(c => this.mappingService.MapToUserComment(c, key)); - IDictionary> userCommentsByEntry = comments.GroupBy(x => x.ParentEntryId).ToDictionary(g => g.Key, g => g.AsEnumerable()); - - if (dbComments.Status != DbStatusCode.Read) - { - return RequestResultFactory.ServiceError>>(ErrorType.CommunicationInternal, ServiceType.Database, dbComments.Message); - } - - return RequestResultFactory.Success( - userCommentsByEntry, - userCommentsByEntry.Count, - 0, - userCommentsByEntry.Count); + Dictionary> userCommentsByEntry = comments.GroupBy(x => x.ParentEntryId).ToDictionary(g => g.Key, g => g.AsEnumerable()); + + return dbComments.Status != DbStatusCode.Read + ? RequestResultFactory.ServiceError>>(ErrorType.CommunicationInternal, ServiceType.Database, dbComments.Message) + : RequestResultFactory.Success>>( + userCommentsByEntry, + userCommentsByEntry.Count, + 0, + userCommentsByEntry.Count); } /// @@ -161,19 +153,16 @@ public async Task> UpdateAsync(UserComment userCommen string? key = profile?.EncryptionKey; if (key == null) { - this.logger.LogError("Profile does not have an encryption key"); + this.logger.LogError(ProfileEncryptionKeyMissing); return RequestResultFactory.ServiceError(ErrorType.InvalidState, ServiceType.Database, ProfileKeyNotSet); } Comment comment = this.mappingService.MapToComment(userComment, key); DbResult dbResult = await this.commentDelegate.UpdateAsync(comment, ct: ct); - if (dbResult.Status != DbStatusCode.Updated) - { - return RequestResultFactory.ServiceError(ErrorType.CommunicationInternal, ServiceType.Database, dbResult.Message); - } - - return RequestResultFactory.Success(this.mappingService.MapToUserComment(dbResult.Payload, key)); + return dbResult.Status != DbStatusCode.Updated + ? RequestResultFactory.ServiceError(ErrorType.CommunicationInternal, ServiceType.Database, dbResult.Message) + : RequestResultFactory.Success(this.mappingService.MapToUserComment(dbResult.Payload, key)); } /// @@ -191,19 +180,16 @@ public async Task> DeleteAsync(UserComment userCommen string? key = profile?.EncryptionKey; if (key == null) { - this.logger.LogError("Profile does not have an encryption key"); + this.logger.LogError(ProfileEncryptionKeyMissing); return RequestResultFactory.ServiceError(ErrorType.InvalidState, ServiceType.Database, ProfileKeyNotSet); } Comment comment = this.mappingService.MapToComment(userComment, key); DbResult dbResult = await this.commentDelegate.DeleteAsync(comment, ct: ct); - if (dbResult.Status != DbStatusCode.Deleted) - { - return RequestResultFactory.ServiceError(ErrorType.CommunicationInternal, ServiceType.Database, dbResult.Message); - } - - return RequestResultFactory.Success(this.mappingService.MapToUserComment(dbResult.Payload, key)); + return dbResult.Status != DbStatusCode.Deleted + ? RequestResultFactory.ServiceError(ErrorType.CommunicationInternal, ServiceType.Database, dbResult.Message) + : RequestResultFactory.Success(this.mappingService.MapToUserComment(dbResult.Payload, key)); } } } diff --git a/Apps/GatewayApi/src/Services/DependentService.cs b/Apps/GatewayApi/src/Services/DependentService.cs index 51f810e4bb..5a61df1beb 100644 --- a/Apps/GatewayApi/src/Services/DependentService.cs +++ b/Apps/GatewayApi/src/Services/DependentService.cs @@ -240,11 +240,8 @@ public async Task>> GetDependent /// public async Task> RemoveAsync(string delegateHdid, string dependentHdid, CancellationToken ct = default) { - ResourceDelegate? resourceDelegate = (await this.resourceDelegateDelegate.GetAsync(delegateHdid, 0, 500, ct)).FirstOrDefault(d => d.ResourceOwnerHdid == dependentHdid); - if (resourceDelegate == null) - { - throw new NotFoundException($"Dependent {dependentHdid} not found for delegate {delegateHdid}"); - } + ResourceDelegate resourceDelegate = (await this.resourceDelegateDelegate.GetAsync(delegateHdid, 0, 500, ct)).FirstOrDefault(d => d.ResourceOwnerHdid == dependentHdid) ?? + throw new NotFoundException($"Dependent {dependentHdid} not found for delegate {delegateHdid}"); // commit to the database if change feed is disabled; if change feed enabled, commit will happen when message sender is called // this is temporary and will be changed when we introduce a proper unit of work to manage transactionality. @@ -266,29 +263,13 @@ public async Task> RemoveAsync(string delegateHdid private static bool IsMatch(AddDependentRequest? request, PatientModel? response) { - if (request == null || response == null) - { - return false; - } - - if (!response.LastName.Equals(ReplaceSmartApostrophe(request.LastName), StringComparison.OrdinalIgnoreCase)) - { - return false; - } - - if (!response.FirstName.Equals(ReplaceSmartApostrophe(request.FirstName), StringComparison.OrdinalIgnoreCase)) - { - return false; - } - - if (response.Birthdate.Year != request.DateOfBirth.Year || - response.Birthdate.Month != request.DateOfBirth.Month || - response.Birthdate.Day != request.DateOfBirth.Day) - { - return false; - } - - return true; + return request != null && + response != null && + response.LastName.Equals(ReplaceSmartApostrophe(request.LastName), StringComparison.OrdinalIgnoreCase) && + response.FirstName.Equals(ReplaceSmartApostrophe(request.FirstName), StringComparison.OrdinalIgnoreCase) && + response.Birthdate.Year == request.DateOfBirth.Year && + response.Birthdate.Month == request.DateOfBirth.Month && + response.Birthdate.Day == request.DateOfBirth.Day; } private static string? ReplaceSmartApostrophe(string? value) @@ -327,6 +308,7 @@ static string FormatValue(string? s) } [SuppressMessage("ReSharper", "CognitiveComplexity", Justification = "Team decision")] + [SuppressMessage("Style", "IDE0010:Populate switch", Justification = "Team decision")] private async Task?> ValidateDependentAsync( AddDependentRequest addDependentRequest, string delegateHdid, diff --git a/Apps/GatewayApi/src/Services/MessagingVerificationService.cs b/Apps/GatewayApi/src/Services/MessagingVerificationService.cs index 7c9a345d3b..247aa491af 100644 --- a/Apps/GatewayApi/src/Services/MessagingVerificationService.cs +++ b/Apps/GatewayApi/src/Services/MessagingVerificationService.cs @@ -131,8 +131,7 @@ private static string CreateVerificationCode() return BitConverter .ToUInt32(data) - .ToString("D6", CultureInfo.InvariantCulture) - .Substring(0, 6); + .ToString("D6", CultureInfo.InvariantCulture)[..6]; } private static string SanitizeSms(string smsNumber) diff --git a/Apps/GatewayApi/src/Services/NoteService.cs b/Apps/GatewayApi/src/Services/NoteService.cs index 0fdce6dd96..9aba5be4b2 100644 --- a/Apps/GatewayApi/src/Services/NoteService.cs +++ b/Apps/GatewayApi/src/Services/NoteService.cs @@ -83,12 +83,9 @@ public async Task> CreateNoteAsync(UserNote userNote, Ca DbResult dbNote = await this.noteDelegate.AddNoteAsync(note, ct: ct); - if (dbNote.Status != DbStatusCode.Created) - { - return RequestResultFactory.ServiceError(ErrorType.CommunicationInternal, ServiceType.Database, dbNote.Message); - } - - return RequestResultFactory.Success(this.mappingService.MapToUserNote(dbNote.Payload, key)); + return dbNote.Status != DbStatusCode.Created + ? RequestResultFactory.ServiceError(ErrorType.CommunicationInternal, ServiceType.Database, dbNote.Message) + : RequestResultFactory.Success(this.mappingService.MapToUserNote(dbNote.Payload, key)); } /// @@ -99,7 +96,7 @@ public async Task>> GetNotesAsync(string hdI return new RequestResult> { ResultStatus = ResultType.Success, - ResourcePayload = Enumerable.Empty(), + ResourcePayload = [], TotalResultCount = 0, }; } @@ -117,16 +114,13 @@ public async Task>> GetNotesAsync(string hdI dbNotes = await this.noteDelegate.GetNotesAsync(hdId, offset, pageSize, ct); } - if (dbNotes.Status != DbStatusCode.Read) - { - return RequestResultFactory.ServiceError>(ErrorType.CommunicationInternal, ServiceType.Database, dbNotes.Message); - } - - return RequestResultFactory.Success( - dbNotes.Payload.Select(c => this.mappingService.MapToUserNote(c, key)), - dbNotes.Payload.Count, - page, - pageSize); + return dbNotes.Status != DbStatusCode.Read + ? RequestResultFactory.ServiceError>(ErrorType.CommunicationInternal, ServiceType.Database, dbNotes.Message) + : RequestResultFactory.Success( + dbNotes.Payload.Select(c => this.mappingService.MapToUserNote(c, key)), + dbNotes.Payload.Count, + page, + pageSize); } /// @@ -143,12 +137,9 @@ public async Task> UpdateNoteAsync(UserNote userNote, Ca Note note = this.mappingService.MapToNote(userNote, key); DbResult dbResult = await this.noteDelegate.UpdateNoteAsync(note, ct: ct); - if (dbResult.Status != DbStatusCode.Updated) - { - return RequestResultFactory.ServiceError(ErrorType.CommunicationInternal, ServiceType.Database, dbResult.Message); - } - - return RequestResultFactory.Success(this.mappingService.MapToUserNote(dbResult.Payload, key)); + return dbResult.Status != DbStatusCode.Updated + ? RequestResultFactory.ServiceError(ErrorType.CommunicationInternal, ServiceType.Database, dbResult.Message) + : RequestResultFactory.Success(this.mappingService.MapToUserNote(dbResult.Payload, key)); } /// @@ -165,12 +156,9 @@ public async Task> DeleteNoteAsync(UserNote userNote, Ca Note note = this.mappingService.MapToNote(userNote, key); DbResult dbResult = await this.noteDelegate.DeleteNoteAsync(note, ct: ct); - if (dbResult.Status != DbStatusCode.Deleted) - { - return RequestResultFactory.ServiceError(ErrorType.CommunicationInternal, ServiceType.Database, dbResult.Message); - } - - return RequestResultFactory.Success(this.mappingService.MapToUserNote(dbResult.Payload, key)); + return dbResult.Status != DbStatusCode.Deleted + ? RequestResultFactory.ServiceError(ErrorType.CommunicationInternal, ServiceType.Database, dbResult.Message) + : RequestResultFactory.Success(this.mappingService.MapToUserNote(dbResult.Payload, key)); } private async Task EncryptFirstTimeAsync(UserProfile profile, IList dbNotes, CancellationToken ct) @@ -191,12 +179,7 @@ private async Task EncryptFirstTimeAsync(UserProfile profile, IList> batchUpdateResult = await this.noteDelegate.BatchUpdateAsync(dbNotes, ct: ct); - if (batchUpdateResult.Status != DbStatusCode.Updated) - { - throw new DatabaseException(batchUpdateResult.Message); - } - - return key; + return batchUpdateResult.Status != DbStatusCode.Updated ? throw new DatabaseException(batchUpdateResult.Message) : key; } } } diff --git a/Apps/GatewayApi/src/Services/PatientDetailsService.cs b/Apps/GatewayApi/src/Services/PatientDetailsService.cs index 9f9edcc07a..16b0e4a875 100644 --- a/Apps/GatewayApi/src/Services/PatientDetailsService.cs +++ b/Apps/GatewayApi/src/Services/PatientDetailsService.cs @@ -52,17 +52,10 @@ public async Task GetPatientAsync( PatientModel patientModel = (await this.patientRepository.QueryAsync(query, ct)).Item; - if (patientModel.LegalName == null && patientModel.CommonName == null) - { - throw new InvalidDataException(ErrorMessages.InvalidServicesCard); - } - - if (string.IsNullOrEmpty(patientModel.Hdid) && string.IsNullOrEmpty(patientModel.Phn) && !disableIdValidation) - { - throw new InvalidDataException(ErrorMessages.InvalidServicesCard); - } - - return this.mappingService.MapToPatientDetails(patientModel); + return (patientModel.LegalName == null && patientModel.CommonName == null) || + (string.IsNullOrEmpty(patientModel.Hdid) && string.IsNullOrEmpty(patientModel.Phn) && !disableIdValidation) + ? throw new InvalidDataException(ErrorMessages.InvalidServicesCard) + : this.mappingService.MapToPatientDetails(patientModel); } } } diff --git a/Apps/GatewayApi/src/Services/UserPreferenceServiceV2.cs b/Apps/GatewayApi/src/Services/UserPreferenceServiceV2.cs index 82bd79677b..71b61f1b30 100644 --- a/Apps/GatewayApi/src/Services/UserPreferenceServiceV2.cs +++ b/Apps/GatewayApi/src/Services/UserPreferenceServiceV2.cs @@ -38,12 +38,7 @@ public async Task UpdateUserPreferenceAsync(string hdid, Us UserPreference userPreference = mappingService.MapToUserPreference(userPreferenceModel); DbResult dbResult = await userPreferenceDelegate.UpdateUserPreferenceAsync(userPreference, ct: ct); - if (dbResult.Status != DbStatusCode.Updated) - { - throw new DatabaseException(dbResult.Message); - } - - return mappingService.MapToUserPreferenceModel(dbResult.Payload); + return dbResult.Status != DbStatusCode.Updated ? throw new DatabaseException(dbResult.Message) : mappingService.MapToUserPreferenceModel(dbResult.Payload); } /// @@ -55,12 +50,7 @@ public async Task CreateUserPreferenceAsync(string hdid, Us UserPreference userPreference = mappingService.MapToUserPreference(userPreferenceModel); DbResult dbResult = await userPreferenceDelegate.CreateUserPreferenceAsync(userPreference, ct: ct); - if (dbResult.Status != DbStatusCode.Created) - { - throw new DatabaseException(dbResult.Message); - } - - return mappingService.MapToUserPreferenceModel(dbResult.Payload); + return dbResult.Status != DbStatusCode.Created ? throw new DatabaseException(dbResult.Message) : mappingService.MapToUserPreferenceModel(dbResult.Payload); } /// diff --git a/Apps/GatewayApi/src/Services/UserSmsService.cs b/Apps/GatewayApi/src/Services/UserSmsService.cs index 25d0930ec8..a24a3723b8 100644 --- a/Apps/GatewayApi/src/Services/UserSmsService.cs +++ b/Apps/GatewayApi/src/Services/UserSmsService.cs @@ -178,8 +178,7 @@ private static string CreateVerificationCode() return BitConverter .ToUInt32(data) - .ToString("D6", CultureInfo.InvariantCulture) - .Substring(0, 6); + .ToString("D6", CultureInfo.InvariantCulture)[..6]; } private static string SanitizeSms(string smsNumber) diff --git a/Apps/GatewayApi/test/unit/Controllers.Test/DependentControllerTests.cs b/Apps/GatewayApi/test/unit/Controllers.Test/DependentControllerTests.cs index b8903d9552..63a6c0e45b 100644 --- a/Apps/GatewayApi/test/unit/Controllers.Test/DependentControllerTests.cs +++ b/Apps/GatewayApi/test/unit/Controllers.Test/DependentControllerTests.cs @@ -197,10 +197,9 @@ private static Mock CreateValidHttpContext(string token, s Mock authenticationMock = new(); AuthenticateResult authResult = AuthenticateResult.Success(new AuthenticationTicket(claimsPrincipal, JwtBearerDefaults.AuthenticationScheme)); authResult.Properties.StoreTokens( - new[] - { - new AuthenticationToken { Name = "access_token", Value = token }, - }); + [ + new AuthenticationToken { Name = "access_token", Value = token }, + ]); authenticationMock .Setup(x => x.AuthenticateAsync(httpContextAccessorMock.Object.HttpContext, It.IsAny())) .ReturnsAsync(authResult); diff --git a/Apps/GatewayApi/test/unit/Controllers.Test/UserProfileControllerTests.cs b/Apps/GatewayApi/test/unit/Controllers.Test/UserProfileControllerTests.cs index 763809a44a..f573e3a1fe 100644 --- a/Apps/GatewayApi/test/unit/Controllers.Test/UserProfileControllerTests.cs +++ b/Apps/GatewayApi/test/unit/Controllers.Test/UserProfileControllerTests.cs @@ -555,11 +555,11 @@ private static Mock CreateValidHttpContext(string token, s List claims = [ - new Claim(ClaimTypes.Name, "username"), - new Claim(ClaimTypes.NameIdentifier, userId), - new Claim("hdid", hdid), - new Claim("auth_time", "123"), - new Claim("access_token", token), + new(ClaimTypes.Name, "username"), + new(ClaimTypes.NameIdentifier, userId), + new("hdid", hdid), + new("auth_time", "123"), + new("access_token", token), ]; ClaimsIdentity identity = new(claims, "TestAuth"); ClaimsPrincipal claimsPrincipal = new(identity); @@ -572,10 +572,9 @@ private static Mock CreateValidHttpContext(string token, s Mock authenticationMock = new(); AuthenticateResult authResult = AuthenticateResult.Success(new AuthenticationTicket(claimsPrincipal, JwtBearerDefaults.AuthenticationScheme)); authResult.Properties.StoreTokens( - new[] - { - new AuthenticationToken { Name = "access_token", Value = token }, - }); + [ + new AuthenticationToken { Name = "access_token", Value = token }, + ]); authenticationMock .Setup(x => x.AuthenticateAsync(httpContextAccessorMock.Object.HttpContext, It.IsAny())) .ReturnsAsync(authResult); diff --git a/Apps/GatewayApi/test/unit/Services.Test/CommentServiceTests.cs b/Apps/GatewayApi/test/unit/Services.Test/CommentServiceTests.cs index 6199cb51ef..273487c66d 100644 --- a/Apps/GatewayApi/test/unit/Services.Test/CommentServiceTests.cs +++ b/Apps/GatewayApi/test/unit/Services.Test/CommentServiceTests.cs @@ -64,7 +64,7 @@ public async Task ShouldGetEntryComments(DbStatusCode? dbStatusCode, string? enc // Arrange List comments = [ - new Comment + new() { UserProfileId = Hdid, ParentEntryId = ParentEntryId, @@ -73,7 +73,7 @@ public async Task ShouldGetEntryComments(DbStatusCode? dbStatusCode, string? enc CreatedDateTime = DateTime.Parse("2020-01-01", CultureInfo.InvariantCulture), }, - new Comment + new() { UserProfileId = Hdid, ParentEntryId = ParentEntryId, @@ -127,7 +127,7 @@ public async Task ShouldGetProfileComments(DbStatusCode? dbStatusCode, string? e // Arrange List comments = [ - new Comment + new() { UserProfileId = Hdid, ParentEntryId = ParentEntryId, @@ -342,8 +342,7 @@ private static CommentService GetCommentService( DbResult>? parentEntryCommentsDbResult = null, DbResult>? allCommentsDbResult = null) { - UserProfile userProfile = new() - { EncryptionKey = encryptionKey }; + UserProfile userProfile = new() { EncryptionKey = encryptionKey }; Mock profileDelegateMock = new(); profileDelegateMock.Setup(s => s.GetUserProfileAsync(Hdid, It.IsAny(), It.IsAny())).ReturnsAsync(userProfile); diff --git a/Apps/GatewayApi/test/unit/Services.Test/DependentServiceTests.cs b/Apps/GatewayApi/test/unit/Services.Test/DependentServiceTests.cs index f12ad44cd7..f8ae877e6e 100644 --- a/Apps/GatewayApi/test/unit/Services.Test/DependentServiceTests.cs +++ b/Apps/GatewayApi/test/unit/Services.Test/DependentServiceTests.cs @@ -411,7 +411,11 @@ public async Task ValidateAddProtectedDependentNotAllowed() [Fact] public async Task ValidateRemove() { - IList resourceDelegates = new[] { new ResourceDelegate { ProfileHdid = this.mockParentHdid, ResourceOwnerHdid = this.mockHdId } }; + IList resourceDelegates = + [ + new() + { ProfileHdid = this.mockParentHdid, ResourceOwnerHdid = this.mockHdId }, + ]; DbResult dbResult = new() { Status = DbStatusCode.Deleted, @@ -465,7 +469,7 @@ private static IConfigurationRoot GetIConfigurationRoot(Dictionary SetupPatientRequestResultForInvalidPatient(ResultType resultType, string message) { - if (resultType == ResultType.ActionRequired) - { - return new() + return resultType == ResultType.ActionRequired + ? new() { ResultStatus = ResultType.ActionRequired, ResultError = message == ErrorMessages.InvalidServicesCard @@ -513,13 +516,11 @@ private static RequestResult SetupPatientRequestResultForInvalidPa ActionCode = ActionType.NoHdId, } : null, + } + : new() + { + ResultStatus = resultType, }; - } - - return new() - { - ResultStatus = resultType, - }; } private IList GenerateMockResourceDelegatesList() diff --git a/Apps/GatewayApi/test/unit/Services.Test/NoteServiceTests.cs b/Apps/GatewayApi/test/unit/Services.Test/NoteServiceTests.cs index f4c05b8d4b..de08a307ea 100644 --- a/Apps/GatewayApi/test/unit/Services.Test/NoteServiceTests.cs +++ b/Apps/GatewayApi/test/unit/Services.Test/NoteServiceTests.cs @@ -17,6 +17,7 @@ namespace HealthGateway.GatewayApiTests.Services.Test { using System; using System.Collections.Generic; + using System.Diagnostics.CodeAnalysis; using System.Globalization; using System.Linq; using System.Threading; @@ -67,6 +68,7 @@ public class NoteServiceTests [InlineData(DbStatusCode.Read, DbStatusCode.Deferred, DbStatusCode.Error, null, true, true)] [InlineData(DbStatusCode.Read, DbStatusCode.Error, null, null, true, true)] [InlineData(null, null, null, null, false, false)] + [SuppressMessage("Style", "IDE0010:Populate switch", Justification = "Team decision")] public async Task ShouldGetNotes( DbStatusCode? notesDbStatusCode, DbStatusCode? updateProfileDbStatusCode, @@ -78,7 +80,7 @@ public async Task ShouldGetNotes( // Arrange List expected = [ - new UserNote + new() { HdId = Hdid, Title = "First Note", @@ -86,7 +88,7 @@ public async Task ShouldGetNotes( CreatedDateTime = DateTime.Parse("2020-01-01", CultureInfo.InvariantCulture), }, - new UserNote + new() { HdId = Hdid, Title = "Second Note", @@ -95,7 +97,7 @@ public async Task ShouldGetNotes( }, ]; - IList notes = expected.Select(n => Mapper.Map(n)).ToList(); + IList notes = expected.Select(Mapper.Map).ToList(); if (encryptionKey != null) { foreach (Note note in notes) @@ -203,8 +205,7 @@ public async Task ShouldInsertNote(DbStatusCode? dbStatusCode, string? encryptio } : null; - UserProfile userProfile = new() - { EncryptionKey = encryptionKey }; + UserProfile userProfile = new() { EncryptionKey = encryptionKey }; NoteService service = GetNoteService(userProfile: userProfile, noteDbResult: noteDbResult); @@ -256,8 +257,7 @@ public async Task ShouldUpdateNote(DbStatusCode? dbStatusCode, string? encryptio } : null; - UserProfile userProfile = new() - { EncryptionKey = encryptionKey }; + UserProfile userProfile = new() { EncryptionKey = encryptionKey }; NoteService service = GetNoteService(userProfile: userProfile, noteDbResult: noteDbResult); @@ -309,8 +309,7 @@ public async Task ShouldDeleteNote(DbStatusCode? dbStatusCode, string? encryptio } : null; - UserProfile userProfile = new() - { EncryptionKey = encryptionKey }; + UserProfile userProfile = new() { EncryptionKey = encryptionKey }; NoteService service = GetNoteService(userProfile: userProfile, noteDbResult: noteDbResult); diff --git a/Apps/GatewayApi/test/unit/Services.Test/UserEmailServiceTests.cs b/Apps/GatewayApi/test/unit/Services.Test/UserEmailServiceTests.cs index 5ac55506f5..7e1758850c 100644 --- a/Apps/GatewayApi/test/unit/Services.Test/UserEmailServiceTests.cs +++ b/Apps/GatewayApi/test/unit/Services.Test/UserEmailServiceTests.cs @@ -210,7 +210,7 @@ public async Task ValidateEmailReturnsError() /// /// ValidateEmailAsync - invalid invite. /// - /// The hdid associated with the verification by invite key.. + /// The hdid associated with the verification by invite key. /// The last verification for user Validated value. /// The last verification's Deleted value. /// @@ -317,7 +317,7 @@ private static IConfiguration GetConfiguration(bool changeFeedEnabled) }; return new ConfigurationBuilder() - .AddInMemoryCollection(myConfiguration.ToList()) + .AddInMemoryCollection(myConfiguration) .Build(); } } diff --git a/Apps/GatewayApi/test/unit/Services.Test/UserEmailServiceV2Tests.cs b/Apps/GatewayApi/test/unit/Services.Test/UserEmailServiceV2Tests.cs index 472d4b2de6..0fbcc665ca 100644 --- a/Apps/GatewayApi/test/unit/Services.Test/UserEmailServiceV2Tests.cs +++ b/Apps/GatewayApi/test/unit/Services.Test/UserEmailServiceV2Tests.cs @@ -280,7 +280,7 @@ private static void VerifyVerificationUpdateValidatedFalse(Mock s.UpdateAsync( It.Is( - mv => mv.Validated == false && + mv => !mv.Validated && mv.VerificationAttempts == 1), It.IsAny(), It.IsAny()), @@ -291,8 +291,7 @@ private static void VerifyVerificationUpdateValidatedTrue(Mock s.UpdateAsync( - It.Is( - mv => mv.Validated == true), + It.Is(mv => mv.Validated), It.IsAny(), It.IsAny()), times ?? Times.Once()); @@ -496,8 +495,7 @@ private static Mock SetupUserProfileDelegateMock( It.IsAny(), It.IsAny())) .ReturnsAsync( - new DbResult - { Status = dbUpdateStatus.Value }); + new DbResult { Status = dbUpdateStatus.Value }); } return userProfileDelegateMock; diff --git a/Apps/GatewayApi/test/unit/Services.Test/UserPreferenceServiceTests.cs b/Apps/GatewayApi/test/unit/Services.Test/UserPreferenceServiceTests.cs index af072fa20e..5723aad41b 100644 --- a/Apps/GatewayApi/test/unit/Services.Test/UserPreferenceServiceTests.cs +++ b/Apps/GatewayApi/test/unit/Services.Test/UserPreferenceServiceTests.cs @@ -179,7 +179,7 @@ private static IUserPreferenceService SetupUserPreferenceServiceForCreateUserPre userPreferenceDelegateMock.Setup( s => s.CreateUserPreferenceAsync( It.Is(x => x.Preference == userPreference.Preference), - It.Is(x => x == true), + It.Is(x => x), It.IsAny())) .ReturnsAsync(dbResult); @@ -192,7 +192,7 @@ private static IUserPreferenceService SetupUserPreferenceServiceForUpdateUserPre userPreferenceDelegateMock.Setup( s => s.UpdateUserPreferenceAsync( It.Is(x => x.Preference == userPreference.Preference), - It.Is(x => x == true), + It.Is(x => x), It.IsAny())) .ReturnsAsync(dbResult); diff --git a/Apps/GatewayApi/test/unit/Services.Test/UserPreferenceServiceV2Tests.cs b/Apps/GatewayApi/test/unit/Services.Test/UserPreferenceServiceV2Tests.cs index 709719dab0..4a2b806e52 100644 --- a/Apps/GatewayApi/test/unit/Services.Test/UserPreferenceServiceV2Tests.cs +++ b/Apps/GatewayApi/test/unit/Services.Test/UserPreferenceServiceV2Tests.cs @@ -198,14 +198,14 @@ private static IUserPreferenceServiceV2 SetupUserPreferenceServiceForCreateUserP userPreferenceDelegateMock.Setup( s => s.CreateUserPreferenceAsync( It.Is(x => x.Preference == createUserPreference.Preference), - It.Is(x => x == true), + It.Is(x => x), It.IsAny())) .ReturnsAsync(dbResult); userPreferenceDelegateMock.Setup( s => s.UpdateUserPreferenceAsync( It.Is(x => x.Preference == createUserPreference.Preference), - It.Is(x => x == true), + It.Is(x => x), It.IsAny())) .ReturnsAsync(dbResult); @@ -219,7 +219,7 @@ private static IUserPreferenceServiceV2 SetupUserPreferenceServiceForUpdateUserP userPreferenceDelegateMock.Setup( s => s.UpdateUserPreferenceAsync( It.Is(x => x.Preference == updateUserPreference.Preference), - It.Is(x => x == true), + It.Is(x => x), It.IsAny())) .ReturnsAsync(dbResult); diff --git a/Apps/GatewayApi/test/unit/Services.Test/UserProfileServiceTests.cs b/Apps/GatewayApi/test/unit/Services.Test/UserProfileServiceTests.cs index eda3f6dfe1..0a08fdcc35 100644 --- a/Apps/GatewayApi/test/unit/Services.Test/UserProfileServiceTests.cs +++ b/Apps/GatewayApi/test/unit/Services.Test/UserProfileServiceTests.cs @@ -17,6 +17,7 @@ namespace HealthGateway.GatewayApiTests.Services.Test { using System; using System.Collections.Generic; + using System.Diagnostics.CodeAnalysis; using System.Globalization; using System.Linq; using System.Threading; @@ -256,6 +257,7 @@ public async Task ShouldUpdateAcceptedTerms(DbStatusCode updatedStatus, bool use [InlineData(DbStatusCode.Created, false, false, true, true, true, ResultType.Error)] // Cannot insert due to get patient error [InlineData(DbStatusCode.Concurrency, false, false, true, true, false, ResultType.Error)] // Cannot insert due to database error [InlineData(DbStatusCode.Error, false, false, true, true, false, ResultType.Error)] // Cannot insert due to database error + [SuppressMessage("Style", "IDE0046: 'if' statement can be simplified", Justification = "Team decision")] public async Task ShouldCreateUserProfile( DbStatusCode insertedStatus, bool accountsFeedEnabled, @@ -515,7 +517,7 @@ public async Task ShouldCloseUserProfile(DbStatusCode updatedStatus, bool userPr It.IsAny(), It.Is(x => x == EmailTemplateName.AccountClosedTemplate), It.IsAny>(), - It.Is(x => x == true), + It.Is(x => x), It.IsAny()), expectedTimesSendEmail); } @@ -614,7 +616,7 @@ public async Task ShouldRecoverUserProfile(DbStatusCode updatedStatus, bool user It.IsAny(), It.Is(x => x == EmailTemplateName.AccountRecoveredTemplate), It.IsAny>(), - It.Is(x => x == true), + It.Is(x => x), It.IsAny()), expectedTimesSendEmail); } @@ -831,7 +833,7 @@ private static IConfigurationRoot GetIConfiguration( }; return new ConfigurationBuilder() - .AddInMemoryCollection(myConfiguration.ToList()) + .AddInMemoryCollection(myConfiguration) .Build(); } @@ -856,7 +858,7 @@ private static CreateUserProfileMock SetupCreateUserProfileMock( s => s.GetPatientAsync( It.Is(x => x == Hdid), It.Is(x => x == PatientIdentifierType.Hdid), - It.Is(x => x == false), + It.Is(x => !x), It.IsAny())) .ReturnsAsync(patientResult); @@ -947,7 +949,7 @@ private static UserProfileMock SetupGetUserProfileMock( userProfileDelegateMock.Setup( s => s.GetUserProfileAsync( It.Is(x => x == Hdid), - It.Is(x => x == true), + It.Is(x => x), It.IsAny())) .ReturnsAsync(userProfile); @@ -964,7 +966,7 @@ private static UserProfileMock SetupGetUserProfileMock( s => s.GetPatientAsync( It.Is(x => x == Hdid), It.Is(x => x == PatientIdentifierType.Hdid), - It.Is(x => x == false), + It.Is(x => !x), It.IsAny())) .ReturnsAsync(patientResult); @@ -1053,14 +1055,14 @@ private static IUserProfileService SetupUserProfileServiceForUpdateAcceptedTerms userProfileDelegateMock.Setup( s => s.GetUserProfileAsync( It.Is(x => x == Hdid), - It.Is(x => x == false), + It.Is(x => !x), It.IsAny())) .ReturnsAsync(userProfile); userProfileDelegateMock.Setup( s => s.UpdateAsync( It.Is(x => x.HdId == Hdid), - It.Is(x => x == true), + It.Is(x => x), It.IsAny())) .ReturnsAsync(updateResult!); @@ -1110,14 +1112,14 @@ private static CloseUserProfileMock SetupCloseUserProfileMock( userProfileDelegateMock.Setup( s => s.GetUserProfileAsync( It.Is(x => x == Hdid), - It.Is(x => x == false), + It.Is(x => !x), It.IsAny())) .ReturnsAsync(readUserProfile); userProfileDelegateMock.Setup( s => s.UpdateAsync( It.Is(x => x.HdId == Hdid), - It.Is(x => x == true), + It.Is(x => x), It.IsAny())) .ReturnsAsync(updateResult); @@ -1170,14 +1172,14 @@ private static RecoverUserProfileMock SetupRecoverUserProfileMock(DbResult s.GetUserProfileAsync( It.Is(x => x == Hdid), - It.Is(x => x == false), + It.Is(x => !x), It.IsAny())) .ReturnsAsync(readUserProfile); userProfileDelegateMock.Setup( s => s.UpdateAsync( It.Is(x => x.HdId == Hdid), - It.Is(x => x == true), + It.Is(x => x), It.IsAny())) .ReturnsAsync(updateResult); diff --git a/Apps/GatewayApi/test/unit/Services.Test/UserProfileServiceV2Tests.cs b/Apps/GatewayApi/test/unit/Services.Test/UserProfileServiceV2Tests.cs index 7b10a23304..e8bd7a5038 100644 --- a/Apps/GatewayApi/test/unit/Services.Test/UserProfileServiceV2Tests.cs +++ b/Apps/GatewayApi/test/unit/Services.Test/UserProfileServiceV2Tests.cs @@ -17,6 +17,7 @@ namespace HealthGateway.GatewayApiTests.Services.Test { using System; using System.Collections.Generic; + using System.Diagnostics.CodeAnalysis; using System.Globalization; using System.Threading; using System.Threading.Tasks; @@ -547,14 +548,11 @@ private static BaseUserProfileServiceMock SetupUpdateAcceptedTermsMock(DbStatusC IUserProfileServiceV2 service = GetUserProfileService( userProfileDelegateMock: userProfileDelegateMock); - if (profileUpdateStatus == DbStatusCode.Updated) - { - return new UpdateAcceptedTermsMock( + return profileUpdateStatus == DbStatusCode.Updated + ? new UpdateAcceptedTermsMock( service, - userProfileDelegateMock); - } - - return new UpdateAcceptedTermsExceptionMock(service); + userProfileDelegateMock) + : new UpdateAcceptedTermsExceptionMock(service); } private static BaseUserProfileServiceMock SetupCloseUserProfileMock( @@ -580,17 +578,15 @@ private static BaseUserProfileServiceMock SetupCloseUserProfileMock( authenticationDelegateMock: authenticationDelegateMock, jobServiceMock: jobServiceMock); - if (closedDateTime != null || profileUpdateStatus == DbStatusCode.Updated) - { - return new CloseUserProfileMock( + return closedDateTime != null || profileUpdateStatus == DbStatusCode.Updated + ? new CloseUserProfileMock( service, userProfileDelegateMock, - jobServiceMock); - } - - return new CloseUserProfileExceptionMock(service); + jobServiceMock) + : new CloseUserProfileExceptionMock(service); } + [SuppressMessage("Style", "IDE0046: 'if' statement can be simplified", Justification = "Team decision")] private static BaseUserProfileServiceMock SetupRecoverUserProfileMock( bool userProfileExists = true, DateTime? profileClosedDateTime = null, @@ -616,15 +612,9 @@ private static BaseUserProfileServiceMock SetupRecoverUserProfileMock( if (userProfileExists) { - if (profileUpdateStatus == DbStatusCode.Error) - { - return new RecoverUserProfileExceptionMock(service); - } - - return new RecoverUserProfileMock( - service, - userProfileDelegateMock, - jobServiceMock); + return profileUpdateStatus == DbStatusCode.Error + ? new RecoverUserProfileExceptionMock(service) + : new RecoverUserProfileMock(service, userProfileDelegateMock, jobServiceMock); } return new RecoverUserProfileExceptionMock(service); diff --git a/Apps/GatewayApi/test/unit/Services.Test/UserSmsServiceTests.cs b/Apps/GatewayApi/test/unit/Services.Test/UserSmsServiceTests.cs index 36b06055a6..33f5980e74 100644 --- a/Apps/GatewayApi/test/unit/Services.Test/UserSmsServiceTests.cs +++ b/Apps/GatewayApi/test/unit/Services.Test/UserSmsServiceTests.cs @@ -335,7 +335,7 @@ private static IConfiguration GetConfiguration(bool changeFeedEnabled = false) }; return new ConfigurationBuilder() - .AddInMemoryCollection(myConfiguration.ToList()) + .AddInMemoryCollection(myConfiguration) .Build(); } } diff --git a/Apps/Immunization/src/Services/ImmunizationService.cs b/Apps/Immunization/src/Services/ImmunizationService.cs index 1334404021..33e527e89e 100644 --- a/Apps/Immunization/src/Services/ImmunizationService.cs +++ b/Apps/Immunization/src/Services/ImmunizationService.cs @@ -61,28 +61,26 @@ public async Task> GetImmunizationsAsync(strin } RequestResult> delegateResult = await this.immunizationDelegate.GetImmunizationsAsync(hdid, ct); - if (delegateResult.ResultStatus == ResultType.Success) - { - return new RequestResult + + return delegateResult.ResultStatus == ResultType.Success + ? new RequestResult { ResultStatus = delegateResult.ResultStatus, ResourcePayload = new ImmunizationResult { LoadState = this.mappingService.MapToLoadStateModel(delegateResult.ResourcePayload!.LoadState), Immunizations = delegateResult.ResourcePayload!.Result!.ImmunizationViews.Select(this.mappingService.MapToImmunizationEvent).ToList(), - Recommendations = this.mappingService.MapToImmunizationRecommendations(delegateResult.ResourcePayload.Result.Recommendations).ToList(), + Recommendations = this.mappingService.MapToImmunizationRecommendations(delegateResult.ResourcePayload.Result.Recommendations), }, PageIndex = delegateResult.PageIndex, PageSize = delegateResult.PageSize, TotalResultCount = delegateResult.TotalResultCount, + } + : new RequestResult + { + ResultStatus = delegateResult.ResultStatus, + ResultError = delegateResult.ResultError, }; - } - - return new RequestResult - { - ResultStatus = delegateResult.ResultStatus, - ResultError = delegateResult.ResultError, - }; } } } diff --git a/Apps/Immunization/src/Services/VaccineStatusService.cs b/Apps/Immunization/src/Services/VaccineStatusService.cs index 5f23e39b1c..d40bc1c531 100644 --- a/Apps/Immunization/src/Services/VaccineStatusService.cs +++ b/Apps/Immunization/src/Services/VaccineStatusService.cs @@ -16,6 +16,7 @@ namespace HealthGateway.Immunization.Services { using System; + using System.Diagnostics.CodeAnalysis; using System.Threading; using System.Threading.Tasks; using FluentValidation.Results; @@ -237,6 +238,7 @@ private async Task> GetAuthenticatedVaccineStatusWi return retVal; } + [SuppressMessage("Style", "IDE0072:Populate switch", Justification = "Team decision")] private async Task> GetVaccineStatusFromDelegateAsync(VaccineStatusQuery query, string accessToken, string? phn = null, CancellationToken ct = default) { RequestResult retVal = new() diff --git a/Apps/Immunization/test/unit/Delegates.Test/ImmunizationDelegateTests.cs b/Apps/Immunization/test/unit/Delegates.Test/ImmunizationDelegateTests.cs index 7bcce200bf..83ee02cf21 100644 --- a/Apps/Immunization/test/unit/Delegates.Test/ImmunizationDelegateTests.cs +++ b/Apps/Immunization/test/unit/Delegates.Test/ImmunizationDelegateTests.cs @@ -113,7 +113,7 @@ private static IConfigurationRoot GetIConfigurationRoot() .AddJsonFile("appsettings.json", true) .AddJsonFile("appsettings.Development.json", true) .AddJsonFile("appsettings.local.json", true) - .AddInMemoryCollection(myConfiguration.ToList()) + .AddInMemoryCollection(myConfiguration) .Build(); } diff --git a/Apps/Immunization/test/unit/Services.Test/VaccineStatusServiceTests.cs b/Apps/Immunization/test/unit/Services.Test/VaccineStatusServiceTests.cs index 278d21329d..431c46a576 100644 --- a/Apps/Immunization/test/unit/Services.Test/VaccineStatusServiceTests.cs +++ b/Apps/Immunization/test/unit/Services.Test/VaccineStatusServiceTests.cs @@ -75,7 +75,10 @@ public async Task ShouldGetVaccineStatus(string statusIndicator, VaccineState st ResourcePayload = new PhsaResult { LoadState = new PhsaLoadState - { RefreshInProgress = false, BackOffMilliseconds = 500 }, + { + RefreshInProgress = false, + BackOffMilliseconds = 500, + }, Result = new VaccineStatusResult { FirstName = "Bob", @@ -159,7 +162,10 @@ public async Task ShouldGetErrorDataMismatchVaccineStatus(bool isPublicEndpoint) ResourcePayload = new PhsaResult { LoadState = new PhsaLoadState - { RefreshInProgress = false, BackOffMilliseconds = 500 }, + { + RefreshInProgress = false, + BackOffMilliseconds = 500, + }, Result = new VaccineStatusResult { FirstName = "Bob", @@ -246,7 +252,10 @@ public async Task ShouldGetErrorRefreshInProgressVaccineStatus(bool isPublicEndp ResourcePayload = new PhsaResult { LoadState = new PhsaLoadState - { RefreshInProgress = true, BackOffMilliseconds = 500 }, + { + RefreshInProgress = true, + BackOffMilliseconds = 500, + }, Result = new VaccineStatusResult { FirstName = "Bob", @@ -339,7 +348,10 @@ public async Task ShouldGetErrorNotFoundVaccineStatus(bool isPublicEndpoint) ResourcePayload = new PhsaResult { LoadState = new PhsaLoadState - { RefreshInProgress = false, BackOffMilliseconds = 500 }, + { + RefreshInProgress = false, + BackOffMilliseconds = 500, + }, Result = new VaccineStatusResult { FirstName = "Bob", @@ -454,7 +466,10 @@ public async Task ShouldGetVaccineProof(bool isPublicEndpoint, bool federalVacci ResourcePayload = new PhsaResult { LoadState = new PhsaLoadState - { RefreshInProgress = false, BackOffMilliseconds = 500 }, + { + RefreshInProgress = false, + BackOffMilliseconds = 500, + }, Result = new VaccineStatusResult { FirstName = "Bob", diff --git a/Apps/JobScheduler/src/Controllers/JobSchedulerController.cs b/Apps/JobScheduler/src/Controllers/JobSchedulerController.cs index fc5f0ebacd..1f75db0d1c 100644 --- a/Apps/JobScheduler/src/Controllers/JobSchedulerController.cs +++ b/Apps/JobScheduler/src/Controllers/JobSchedulerController.cs @@ -57,12 +57,8 @@ public IActionResult Login() this.logger.LogDebug(@"Redirecting to dashboard"); string basePath = this.httpContextAccessor.HttpContext?.Request.PathBase.Value ?? string.Empty; - if (this.Url.IsLocalUrl(basePath)) - { - return new RedirectResult($"{basePath}/"); - } + return this.Url.IsLocalUrl(basePath) ? new RedirectResult($"{basePath}/") : new RedirectResult("/"); - return new RedirectResult("/"); #pragma warning restore CA1303 //Restore literal warning } @@ -75,11 +71,10 @@ public IActionResult Login() public IActionResult Logout() { return new SignOutResult( - new[] - { - OpenIdConnectDefaults.AuthenticationScheme, - CookieAuthenticationDefaults.AuthenticationScheme, - }); + [ + OpenIdConnectDefaults.AuthenticationScheme, + CookieAuthenticationDefaults.AuthenticationScheme, + ]); } /// diff --git a/Apps/JobScheduler/src/Jobs/EmailJob.cs b/Apps/JobScheduler/src/Jobs/EmailJob.cs index de9d886f4b..5460b866c8 100644 --- a/Apps/JobScheduler/src/Jobs/EmailJob.cs +++ b/Apps/JobScheduler/src/Jobs/EmailJob.cs @@ -183,37 +183,35 @@ private async Task SendEmailAsync(Email email, CancellationToken ct) email.Attempts++; try { - using (SmtpClient smtpClient = new()) + using SmtpClient smtpClient = new(); + try { + await smtpClient.ConnectAsync(this.host, this.port, SecureSocketOptions.None, ct); try { - await smtpClient.ConnectAsync(this.host, this.port, SecureSocketOptions.None, ct); - try - { - using MimeMessage message = PrepareMessage(email); - await smtpClient.SendAsync(message, ct); - email.SmtpStatusCode = (int)SmtpStatusCode.Ok; - email.EmailStatusCode = EmailStatus.Processed; - email.SentDateTime = DateTime.UtcNow; - await this.emailDelegate.UpdateEmailAsync(email, ct); - } - catch (SmtpCommandException e) - { - caught = e; - this.logger.LogError(e, "Unexpected error while sending email {Id}, SMTP Error = {SmtpStatusCode}", email.Id, email.SmtpStatusCode); - } - - await smtpClient.DisconnectAsync(true, ct); + using MimeMessage message = PrepareMessage(email); + await smtpClient.SendAsync(message, ct); + email.SmtpStatusCode = (int)SmtpStatusCode.Ok; + email.EmailStatusCode = EmailStatus.Processed; + email.SentDateTime = DateTime.UtcNow; + await this.emailDelegate.UpdateEmailAsync(email, ct); } catch (SmtpCommandException e) { caught = e; - this.logger.LogError( - e, - "Unexpected error while connecting to SMTP Server to send email {Id}, SMTP Error = {SmtpStatusCode}", - email.Id.ToString(), - email.SmtpStatusCode); + this.logger.LogError(e, "Unexpected error while sending email {Id}, SMTP Error = {SmtpStatusCode}", email.Id, email.SmtpStatusCode); } + + await smtpClient.DisconnectAsync(true, ct); + } + catch (SmtpCommandException e) + { + caught = e; + this.logger.LogError( + e, + "Unexpected error while connecting to SMTP Server to send email {Id}, SMTP Error = {SmtpStatusCode}", + email.Id.ToString(), + email.SmtpStatusCode); } } catch (Exception e) diff --git a/Apps/JobScheduler/src/Tasks/FinalizeIncompleteUserRegistrations.cs b/Apps/JobScheduler/src/Tasks/FinalizeIncompleteUserRegistrations.cs index b02b88f439..311d12a68f 100644 --- a/Apps/JobScheduler/src/Tasks/FinalizeIncompleteUserRegistrations.cs +++ b/Apps/JobScheduler/src/Tasks/FinalizeIncompleteUserRegistrations.cs @@ -72,7 +72,7 @@ private async Task SendAccountCreatedEventsAsync(CancellationToken ct) DateTime extendedStartDateTime = StartDateTime.AddMinutes(-5); DateTime extendedHotfixDateTime = HotfixDateTime.AddMinutes(5); - IList profiles = await dbContext.UserProfile + List profiles = await dbContext.UserProfile .AsNoTracking() .Where(p => p.CreatedDateTime > extendedStartDateTime && p.CreatedDateTime < extendedHotfixDateTime) .ToListAsync(ct); @@ -90,7 +90,7 @@ private async Task UpdateEmailAddressesAsync(CancellationToken ct) DateTime extendedHotfixDateTime = HotfixDateTime.AddMinutes(-5); int iteration = 0; - IList profiles; + List profiles; do { profiles = await dbContext.UserProfile @@ -128,7 +128,7 @@ private async Task QueueNotificationSettingsRequestsAsync(CancellationToken ct) DateTime extendedStartDateTime = StartDateTime.AddMinutes(-5); int iteration = 0; - IList profiles; + List profiles; do { profiles = await dbContext.UserProfile diff --git a/Apps/Laboratory/src/Controllers/LaboratoryController.cs b/Apps/Laboratory/src/Controllers/LaboratoryController.cs index 982afb3dde..16b9aa2517 100644 --- a/Apps/Laboratory/src/Controllers/LaboratoryController.cs +++ b/Apps/Laboratory/src/Controllers/LaboratoryController.cs @@ -36,6 +36,7 @@ namespace HealthGateway.Laboratory.Controllers [Route("[controller]")] [ApiController] [ExcludeFromCodeCoverage] + [SuppressMessage("SonarLint", "S6960:This controller has multiple responsibilities and could be split into 2 smaller controllers", Justification = "Team decision")] public class LaboratoryController : ControllerBase { private readonly ILaboratoryService labService; diff --git a/Apps/Laboratory/src/Delegates/MockLaboratoryDelegate.cs b/Apps/Laboratory/src/Delegates/MockLaboratoryDelegate.cs index 884e758fdb..44dee63f95 100644 --- a/Apps/Laboratory/src/Delegates/MockLaboratoryDelegate.cs +++ b/Apps/Laboratory/src/Delegates/MockLaboratoryDelegate.cs @@ -43,7 +43,7 @@ public async Task>>> GetCovid19O }; List mockData = [ - new PhsaCovid19Order + new() { Id = Guid.Parse("612d31e5-12e1-451f-a475-58d6b0a8f007"), Phn = "9735352542", @@ -56,8 +56,8 @@ public async Task>>> GetCovid19O MessageId = "20200770000196", AdditionalData = string.Empty, ReportAvailable = true, - Covid19Tests = new PhsaCovid19Test[] - { + Covid19Tests = + [ new() { Id = Guid.Parse("dee12642-fb2c-481f-9ae4-c672b045b2b1"), @@ -76,7 +76,7 @@ public async Task>>> GetCovid19O "This test targets the RdRP and E gene regions of COVID‑19 virus (2019-nCoV) and has not been fully validated.", ], }, - }, + ], }, ]; diff --git a/Apps/Laboratory/src/Delegates/RestLaboratoryDelegate.cs b/Apps/Laboratory/src/Delegates/RestLaboratoryDelegate.cs index 4fa92a0d5c..d30ecb1fde 100644 --- a/Apps/Laboratory/src/Delegates/RestLaboratoryDelegate.cs +++ b/Apps/Laboratory/src/Delegates/RestLaboratoryDelegate.cs @@ -72,6 +72,8 @@ public async Task>>> GetCovid19O { this.logger.LogDebug("Retrieving COVID-19 test results"); PhsaResult> response = await this.laboratoryApi.GetCovid19OrdersAsync(hdid, this.labConfig.FetchSize, bearerToken, ct); + + // ReSharper disable once NullCoalescingConditionIsAlwaysNotNullAccordingToAPIContract retVal.ResourcePayload = response ?? new() { Result = [] }; retVal.TotalResultCount = retVal.ResourcePayload.Result!.Count; retVal.ResultStatus = ResultType.Success; @@ -150,6 +152,8 @@ public async Task>> GetLaborator { this.logger.LogDebug("Retrieving laboratory orders"); PhsaResult response = await this.laboratoryApi.GetPlisLaboratorySummaryAsync(hdid, bearerToken, ct); + + // ReSharper disable once NullCoalescingConditionIsAlwaysNotNullAccordingToAPIContract retVal.ResourcePayload = response ?? new() { Result = new() }; retVal.TotalResultCount = retVal.ResourcePayload.Result!.LabOrderCount; retVal.ResultStatus = ResultType.Success; diff --git a/Apps/Laboratory/src/Models/Covid19Order.cs b/Apps/Laboratory/src/Models/Covid19Order.cs index d16fade546..3fb3983c8f 100644 --- a/Apps/Laboratory/src/Models/Covid19Order.cs +++ b/Apps/Laboratory/src/Models/Covid19Order.cs @@ -17,7 +17,6 @@ namespace HealthGateway.Laboratory.Models { using System; using System.Collections.Generic; - using System.Linq; using System.Text.Json.Serialization; /// @@ -95,6 +94,6 @@ public class Covid19Order /// Gets or sets the collection of COVID-19 tests. /// [JsonPropertyName("labResults")] - public IEnumerable Covid19Tests { get; set; } = Enumerable.Empty(); + public IEnumerable Covid19Tests { get; set; } = []; } } diff --git a/Apps/Laboratory/src/Models/Covid19OrderResult.cs b/Apps/Laboratory/src/Models/Covid19OrderResult.cs index 52d7365bc7..2e041fd4fe 100644 --- a/Apps/Laboratory/src/Models/Covid19OrderResult.cs +++ b/Apps/Laboratory/src/Models/Covid19OrderResult.cs @@ -16,7 +16,6 @@ namespace HealthGateway.Laboratory.Models; using System.Collections.Generic; -using System.Linq; using System.Text.Json.Serialization; /// @@ -43,5 +42,5 @@ public class Covid19OrderResult /// Gets or sets the collection of COVID-19 laboratory orders. /// [JsonPropertyName("orders")] - public IEnumerable Covid19Orders { get; set; } = Enumerable.Empty(); + public IEnumerable Covid19Orders { get; set; } = []; } diff --git a/Apps/Laboratory/src/Models/LaboratoryOrder.cs b/Apps/Laboratory/src/Models/LaboratoryOrder.cs index 876f55ad04..f6efb4d069 100644 --- a/Apps/Laboratory/src/Models/LaboratoryOrder.cs +++ b/Apps/Laboratory/src/Models/LaboratoryOrder.cs @@ -17,7 +17,6 @@ namespace HealthGateway.Laboratory.Models; using System; using System.Collections.Generic; -using System.Linq; using System.Text.Json.Serialization; /// @@ -89,5 +88,5 @@ public class LaboratoryOrder /// Gets or sets the collection of laboratory tests. /// [JsonPropertyName("laboratoryTests")] - public IEnumerable LaboratoryTests { get; set; } = Enumerable.Empty(); + public IEnumerable LaboratoryTests { get; set; } = []; } diff --git a/Apps/Laboratory/src/Models/LaboratoryOrderResult.cs b/Apps/Laboratory/src/Models/LaboratoryOrderResult.cs index 51081c822d..513035619e 100644 --- a/Apps/Laboratory/src/Models/LaboratoryOrderResult.cs +++ b/Apps/Laboratory/src/Models/LaboratoryOrderResult.cs @@ -16,7 +16,6 @@ namespace HealthGateway.Laboratory.Models; using System.Collections.Generic; -using System.Linq; using System.Text.Json.Serialization; /// @@ -49,5 +48,5 @@ public class LaboratoryOrderResult /// Gets or sets the collection of laboratory orders. /// [JsonPropertyName("orders")] - public IEnumerable LaboratoryOrders { get; set; } = Enumerable.Empty(); + public IEnumerable LaboratoryOrders { get; set; } = []; } diff --git a/Apps/Laboratory/src/Services/LabTestKitService.cs b/Apps/Laboratory/src/Services/LabTestKitService.cs index e1908b767e..e4ad09c9e4 100644 --- a/Apps/Laboratory/src/Services/LabTestKitService.cs +++ b/Apps/Laboratory/src/Services/LabTestKitService.cs @@ -15,6 +15,7 @@ //------------------------------------------------------------------------- namespace HealthGateway.Laboratory.Services { + using System.Diagnostics.CodeAnalysis; using System.Globalization; using System.Net; using System.Net.Http; @@ -127,6 +128,7 @@ private static RequestResult InitializeResult(T payload) return result; } + [SuppressMessage("Style", "IDE0010:Populate switch", Justification = "Team decision")] private static RequestResult ProcessResponse(T payload, HttpStatusCode responseStatusCode) { RequestResult requestResult = InitializeResult(payload); diff --git a/Apps/Laboratory/src/Services/LaboratoryService.cs b/Apps/Laboratory/src/Services/LaboratoryService.cs index e023bd7f07..b6c3c9e2d6 100644 --- a/Apps/Laboratory/src/Services/LaboratoryService.cs +++ b/Apps/Laboratory/src/Services/LaboratoryService.cs @@ -17,6 +17,7 @@ namespace HealthGateway.Laboratory.Services { using System; using System.Collections.Generic; + using System.Diagnostics.CodeAnalysis; using System.Linq; using System.Threading; using System.Threading.Tasks; @@ -73,6 +74,7 @@ public LaboratoryService( } /// + [SuppressMessage("Style", "IDE0046:'if' statement can be simplified", Justification = "Team decision")] public async Task> GetCovid19OrdersAsync(string hdid, int pageIndex = 0, CancellationToken ct = default) { if (!await this.patientRepository.CanAccessDataSourceAsync(hdid, DataSource.Covid19TestResult, ct)) @@ -107,23 +109,21 @@ public async Task> GetCovid19OrdersAsync(strin "Refresh in progress"); } - if (delegateResult.ResultStatus != ResultType.Success) - { - return RequestResultFactory.Error(delegateResult.ResultError); - } - - return RequestResultFactory.Success( - new Covid19OrderResult - { - Covid19Orders = delegateResult.ResourcePayload?.Result?.Select(this.mappingService.MapToCovid19Order).ToList() ?? [], - Loaded = true, - }, - delegateResult.TotalResultCount, - delegateResult.PageIndex, - delegateResult.PageSize); + return delegateResult.ResultStatus != ResultType.Success + ? RequestResultFactory.Error(delegateResult.ResultError) + : RequestResultFactory.Success( + new Covid19OrderResult + { + Covid19Orders = delegateResult.ResourcePayload?.Result?.Select(this.mappingService.MapToCovid19Order).ToList() ?? [], + Loaded = true, + }, + delegateResult.TotalResultCount, + delegateResult.PageIndex, + delegateResult.PageSize); } /// + [SuppressMessage("Style", "IDE0046:'if' statement can be simplified", Justification = "Team decision")] public async Task> GetLaboratoryOrdersAsync(string hdid, CancellationToken ct = default) { if (!await this.patientRepository.CanAccessDataSourceAsync(hdid, DataSource.LabResult, ct)) @@ -163,21 +163,18 @@ public async Task> GetLaboratoryOrdersAsync "Refresh in progress"); } - if (delegateResult.ResultStatus != ResultType.Success) - { - return RequestResultFactory.Error(delegateResult.ResultError); - } - - return RequestResultFactory.Success( - new LaboratoryOrderResult - { - LaboratoryOrders = delegateResult.ResourcePayload?.Result?.LabOrders?.Select(this.mappingService.MapToLaboratoryOrder).ToList() ?? [], - Loaded = !(loadState?.RefreshInProgress ?? false), - Queued = loadState?.Queued ?? false, - }, - delegateResult.TotalResultCount, - delegateResult.PageIndex, - delegateResult.PageSize); + return delegateResult.ResultStatus != ResultType.Success + ? RequestResultFactory.Error(delegateResult.ResultError) + : RequestResultFactory.Success( + new LaboratoryOrderResult + { + LaboratoryOrders = delegateResult.ResourcePayload?.Result?.LabOrders?.Select(this.mappingService.MapToLaboratoryOrder).ToList() ?? [], + Loaded = !(loadState?.RefreshInProgress ?? false), + Queued = loadState?.Queued ?? false, + }, + delegateResult.TotalResultCount, + delegateResult.PageIndex, + delegateResult.PageSize); } /// diff --git a/Apps/Medication/src/Services/MedicationRequestService.cs b/Apps/Medication/src/Services/MedicationRequestService.cs index ca0abff011..92c75abfe8 100644 --- a/Apps/Medication/src/Services/MedicationRequestService.cs +++ b/Apps/Medication/src/Services/MedicationRequestService.cs @@ -66,27 +66,25 @@ public async Task>> GetMedicationRequests // Retrieve the phn RequestResult patientResult = await this.patientService.GetPatientAsync(hdid, ct: ct); - if (patientResult.ResultStatus == ResultType.Success && patientResult.ResourcePayload != null) + if (patientResult is { ResultStatus: ResultType.Success, ResourcePayload: not null }) { PatientModel patient = patientResult.ResourcePayload; RequestResult> delegateResult = await this.medicationRequestDelegate.GetMedicationRequestsAsync(patient.PersonalHealthNumber, ct); - if (delegateResult.ResultStatus == ResultType.Success) - { - return new RequestResult> + + return delegateResult.ResultStatus == ResultType.Success + ? new RequestResult> { ResultStatus = delegateResult.ResultStatus, ResourcePayload = delegateResult.ResourcePayload, PageIndex = delegateResult.PageIndex, PageSize = delegateResult.PageSize, TotalResultCount = delegateResult.TotalResultCount, + } + : new RequestResult> + { + ResultStatus = delegateResult.ResultStatus, + ResultError = delegateResult.ResultError, }; - } - - return new RequestResult> - { - ResultStatus = delegateResult.ResultStatus, - ResultError = delegateResult.ResultError, - }; } return new RequestResult> diff --git a/Apps/Patient/src/Controllers/PatientController.cs b/Apps/Patient/src/Controllers/PatientController.cs index 50c8549bc5..566763c3d8 100644 --- a/Apps/Patient/src/Controllers/PatientController.cs +++ b/Apps/Patient/src/Controllers/PatientController.cs @@ -15,6 +15,7 @@ //------------------------------------------------------------------------- namespace HealthGateway.Patient.Controllers { + using System.Diagnostics.CodeAnalysis; using System.Threading; using System.Threading.Tasks; using Asp.Versioning; @@ -33,6 +34,7 @@ namespace HealthGateway.Patient.Controllers [Route("[controller]")] [ApiController] [Authorize] + [SuppressMessage("SonarLint", "S6960:This controller has multiple responsibilities and could be split into 2 smaller controllers", Justification = "Team Decision")] public class PatientController : ControllerBase { /// diff --git a/Apps/Patient/src/Controllers/PatientDataController.cs b/Apps/Patient/src/Controllers/PatientDataController.cs index e25c4c60bc..112fbef691 100644 --- a/Apps/Patient/src/Controllers/PatientDataController.cs +++ b/Apps/Patient/src/Controllers/PatientDataController.cs @@ -64,17 +64,9 @@ public PatientDataController(IPatientDataService patientDataService) [ProducesResponseType(StatusCodes.Status502BadGateway, Type = typeof(ProblemDetails))] public async Task> Get(string hdid, [FromQuery] PatientDataType[] patientDataTypes, CancellationToken ct) { - if (string.IsNullOrEmpty(hdid)) - { - throw new ValidationException("Hdid is missing"); - } - - if (patientDataTypes == null || patientDataTypes.Length == 0) - { - throw new ValidationException("Must have at least one data type"); - } - - return await this.patientDataService.QueryAsync(new PatientDataQuery(hdid, patientDataTypes), ct); + ValidateRequest(hdid, patientDataTypes); + PatientDataQuery query = new(hdid, patientDataTypes); + return await this.patientDataService.QueryAsync(query, ct); } /// @@ -93,6 +85,27 @@ public async Task> Get(string hdid, [FromQuery [ProducesResponseType(StatusCodes.Status404NotFound)] [ProducesResponseType(StatusCodes.Status502BadGateway, Type = typeof(ProblemDetails))] public async Task> GetFile(string hdid, string fileId, CancellationToken ct) + { + ValidateFileRequest(hdid, fileId); + PatientFileQuery query = new(hdid, fileId); + return await this.patientDataService.QueryAsync(query, ct) ?? + throw new NotFoundException($"file {fileId} not found"); + } + + private static void ValidateRequest(string hdid, PatientDataType[] patientDataTypes) + { + if (string.IsNullOrEmpty(hdid)) + { + throw new ValidationException("Hdid is missing"); + } + + if (patientDataTypes == null || patientDataTypes.Length == 0) + { + throw new ValidationException("Must have at least one data type"); + } + } + + private static void ValidateFileRequest(string hdid, string fileId) { if (string.IsNullOrEmpty(hdid)) { @@ -103,9 +116,6 @@ public async Task> GetFile(string hdid, string { throw new ValidationException("File id is missing"); } - - return await this.patientDataService.QueryAsync(new PatientFileQuery(hdid, fileId), ct) ?? - throw new NotFoundException($"file {fileId} not found"); } } } diff --git a/Apps/Patient/src/Services/PatientDataService.cs b/Apps/Patient/src/Services/PatientDataService.cs index 49c8261759..2a4e7dff7c 100644 --- a/Apps/Patient/src/Services/PatientDataService.cs +++ b/Apps/Patient/src/Services/PatientDataService.cs @@ -51,7 +51,7 @@ public async Task QueryAsync(PatientDataQuery query, Cancel IList unblockedPatientDataTypes = await this.GetUnblockedPatientDataTypesAsync(query.Hdid, query.PatientDataTypes, ct); if (!unblockedPatientDataTypes.Any()) { - return new PatientDataResponse(Enumerable.Empty()); + return new PatientDataResponse([]); } Guid pid = await this.ResolvePidFromHdidAsync(query.Hdid, ct); diff --git a/Apps/Patient/src/Services/PatientService.cs b/Apps/Patient/src/Services/PatientService.cs index c9b7b8aea8..57c843fc37 100644 --- a/Apps/Patient/src/Services/PatientService.cs +++ b/Apps/Patient/src/Services/PatientService.cs @@ -57,7 +57,12 @@ public async Task GetPatientAsync( : new PatientDetailsQuery(identifier, Source: PatientDetailSource.All, UseCache: true); PatientModel patientDetails = (await this.patientRepository.QueryAsync(query, ct)).Item; + this.ValidatePatientDetails(patientDetails, disableIdValidation); + return this.mappingService.MapToPatientDetails(patientDetails); + } + private void ValidatePatientDetails(PatientModel patientDetails, bool disableIdValidation) + { if (patientDetails.IsDeceased == true) { this.logger.LogWarning("Patient is deceased"); @@ -73,8 +78,6 @@ public async Task GetPatientAsync( { throw new InvalidDataException(ErrorMessages.InvalidServicesCard); } - - return this.mappingService.MapToPatientDetails(patientDetails); } } } diff --git a/Apps/Patient/test/unit/Services/PatientDataServiceTests.cs b/Apps/Patient/test/unit/Services/PatientDataServiceTests.cs index 5d9b658bcc..daec6deeb5 100644 --- a/Apps/Patient/test/unit/Services/PatientDataServiceTests.cs +++ b/Apps/Patient/test/unit/Services/PatientDataServiceTests.cs @@ -60,9 +60,9 @@ public void CanSerializeOrganDonorData() }; PatientData[] data = - { + [ organDonorRegistration, - }; + ]; PatientDataResponse response = new(data); @@ -95,9 +95,9 @@ public void CanSerializeDiagnosticImagingData() }; PatientData[] data = - { + [ diagnosticImagingExam, - }; + ]; PatientDataResponse response = new(data); @@ -142,7 +142,7 @@ public async Task CanGetOrganDonorRegistrationData(bool canAccessDataSource) PatientDataService sut = new(patientDataRepository.Object, patientRepository.Object, personalAccountService.Object, MappingService); - PatientDataResponse result = await sut.QueryAsync(new PatientDataQuery(this.hdid, new[] { PatientDataType.OrganDonorRegistrationStatus }), CancellationToken.None) + PatientDataResponse result = await sut.QueryAsync(new PatientDataQuery(this.hdid, [PatientDataType.OrganDonorRegistrationStatus]), CancellationToken.None) ; if (canAccessDataSource) @@ -184,7 +184,7 @@ public async Task CanGetCancerScreeningData(bool canAccessDataSource) PatientDataService sut = new(patientDataRepository.Object, patientRepository.Object, personalAccountService.Object, MappingService); - PatientDataResponse result = await sut.QueryAsync(new PatientDataQuery(this.hdid, new[] { PatientDataType.BcCancerScreening }), CancellationToken.None) + PatientDataResponse result = await sut.QueryAsync(new PatientDataQuery(this.hdid, [PatientDataType.BcCancerScreening]), CancellationToken.None) ; if (canAccessDataSource) @@ -230,8 +230,7 @@ public async Task CanGetDiagnosticImagingData(bool canAccessDataSource) PatientDataService sut = new(patientDataRepository.Object, patientRepository.Object, personalAccountService.Object, MappingService); - PatientDataResponse result = await sut.QueryAsync(new PatientDataQuery(this.hdid, new[] { PatientDataType.DiagnosticImaging }), CancellationToken.None) - ; + PatientDataResponse result = await sut.QueryAsync(new PatientDataQuery(this.hdid, [PatientDataType.DiagnosticImaging]), CancellationToken.None); if (canAccessDataSource) { diff --git a/Apps/Patient/test/unit/Services/PatientServiceTests.cs b/Apps/Patient/test/unit/Services/PatientServiceTests.cs index 3e9af27fba..c221f941e3 100644 --- a/Apps/Patient/test/unit/Services/PatientServiceTests.cs +++ b/Apps/Patient/test/unit/Services/PatientServiceTests.cs @@ -126,7 +126,8 @@ private static PatientModel GetPatient(bool commonNameExists = true, bool legalN return errorMessage switch { ErrorMessages.ClientRegistryReturnedDeceasedPerson => CreatePatient(deceased: true), - ErrorMessages.InvalidServicesCard => commonNameExists == false ? CreatePatient(commonNameExists: false, legalNameExists: false) : CreatePatient(string.Empty, string.Empty), + ErrorMessages.InvalidServicesCard => + commonNameExists ? CreatePatient(string.Empty, string.Empty) : CreatePatient(commonNameExists: false, legalNameExists: false), ErrorMessages.PhnInvalid => CreatePatient(), _ => CreatePatient(commonNameExists: commonNameExists, legalNameExists: legalNameExists), }; diff --git a/Apps/PatientDataAccess/src/PatientDataRepository.cs b/Apps/PatientDataAccess/src/PatientDataRepository.cs index ae58668509..eb97571517 100644 --- a/Apps/PatientDataAccess/src/PatientDataRepository.cs +++ b/Apps/PatientDataAccess/src/PatientDataRepository.cs @@ -17,6 +17,7 @@ namespace HealthGateway.PatientDataAccess { using System; using System.Collections.Generic; + using System.Diagnostics.CodeAnalysis; using System.Linq; using System.Net; using System.Threading; @@ -28,22 +29,10 @@ namespace HealthGateway.PatientDataAccess /// /// Provides internal data access for Patient. /// - internal class PatientDataRepository : IPatientDataRepository + /// The patient API to use. + /// The injected mapper. + internal class PatientDataRepository(IPatientApi patientApi, IMapper mapper) : IPatientDataRepository { - private readonly IPatientApi patientApi; - private readonly IMapper mapper; - - /// - /// Initializes a new instance of the class. - /// - /// The patient API to use. - /// The injected mapper. - public PatientDataRepository(IPatientApi patientApi, IMapper mapper) - { - this.patientApi = patientApi; - this.mapper = mapper; - } - /// /// Performs a query against the data repository. /// @@ -61,6 +50,7 @@ public async Task QueryAsync(PatientDataQuery query, Can }; } + [SuppressMessage("Style", "IDE0072:Populate switch", Justification = "Team decision")] private static string? MapHealthOptionsCategories(HealthCategory category) { return category switch @@ -70,6 +60,7 @@ public async Task QueryAsync(PatientDataQuery query, Can }; } + [SuppressMessage("Style", "IDE0072:Populate switch", Justification = "Team decision")] private static string? MapHealthDataCategories(HealthCategory category) { return category switch @@ -101,7 +92,7 @@ private async Task HandleAsync(PatientFileQuery query, C { try { - FileResult? fileResult = await this.patientApi.GetFileAsync(query.Pid, query.FileId, ct); + FileResult? fileResult = await patientApi.GetFileAsync(query.Pid, query.FileId, ct); IEnumerable mappedFiles = new[] { fileResult } .Where(f => f?.Data != null) .Select(f => Map(query.FileId, f!)); @@ -110,7 +101,7 @@ private async Task HandleAsync(PatientFileQuery query, C catch (ApiException e) when (e.StatusCode == HttpStatusCode.NotFound) { // file not found - return new PatientDataQueryResult(Array.Empty()); + return new PatientDataQueryResult([]); } } @@ -124,13 +115,13 @@ private async Task> HandleServiceQueryAsync(HealthQuery if (categories.Length != 0) { - HealthOptionsResult results = await this.patientApi.GetHealthOptionsAsync(query.Pid, categories, ct) ?? - new(new HealthOptionsMetadata(), Array.Empty()); + HealthOptionsResult results = await patientApi.GetHealthOptionsAsync(query.Pid, categories, ct) ?? + new(new HealthOptionsMetadata(), []); return results.Data.Select(this.Map); } - return Array.Empty(); + return []; } private async Task> HandleDataQueryAsync(HealthQuery query, CancellationToken ct) @@ -143,23 +134,23 @@ private async Task> HandleDataQueryAsync(HealthQuery que if (categories.Length != 0) { - HealthDataResult results = await this.patientApi.GetHealthDataAsync(query.Pid, categories, ct) ?? - new(new HealthDataMetadata(), Array.Empty()); + HealthDataResult results = await patientApi.GetHealthDataAsync(query.Pid, categories, ct) ?? + new(new HealthDataMetadata(), []); return results.Data.Select(this.Map); } - return Array.Empty(); + return []; } private HealthData Map(HealthOptionsData healthOptionsData) { - return this.mapper.Map(healthOptionsData); + return mapper.Map(healthOptionsData); } private HealthData Map(HealthDataEntry healthDataEntry) { - return this.mapper.Map(healthDataEntry); + return mapper.Map(healthDataEntry); } } } diff --git a/Apps/PatientDataAccess/test/unit/PatientDataRepositoryTests.cs b/Apps/PatientDataAccess/test/unit/PatientDataRepositoryTests.cs index 4f98243117..a5fa44334b 100644 --- a/Apps/PatientDataAccess/test/unit/PatientDataRepositoryTests.cs +++ b/Apps/PatientDataAccess/test/unit/PatientDataRepositoryTests.cs @@ -47,11 +47,11 @@ public async Task CanGetOrganDonorData() patientApi .Setup(api => api.GetHealthOptionsAsync(this.pid, It.IsAny(), It.IsAny())) - .ReturnsAsync(new HealthOptionsResult(new HealthOptionsMetadata(), new[] { phsaOrganDonorRegistrationResponse })); + .ReturnsAsync(new HealthOptionsResult(new HealthOptionsMetadata(), [phsaOrganDonorRegistrationResponse])); IPatientDataRepository sut = CreateSut(patientApi.Object); - PatientDataQueryResult result = await sut.QueryAsync(new HealthQuery(this.pid, new[] { HealthCategory.OrganDonorRegistrationStatus }), CancellationToken.None); + PatientDataQueryResult result = await sut.QueryAsync(new HealthQuery(this.pid, [HealthCategory.OrganDonorRegistrationStatus]), CancellationToken.None); result.ShouldNotBeNull(); HealthGateway.PatientDataAccess.OrganDonorRegistration @@ -81,14 +81,11 @@ public async Task CanGetCancerScreeningData() .ReturnsAsync( new HealthDataResult( new HealthDataMetadata(), - new[] - { - bcCancerScreening, - })); + [bcCancerScreening])); IPatientDataRepository sut = CreateSut(patientApi.Object); - PatientDataQueryResult result = await sut.QueryAsync(new HealthQuery(this.pid, new[] { HealthCategory.BcCancerScreening }), CancellationToken.None); + PatientDataQueryResult result = await sut.QueryAsync(new HealthQuery(this.pid, [HealthCategory.BcCancerScreening]), CancellationToken.None); result.ShouldNotBeNull(); HealthGateway.PatientDataAccess.BcCancerScreening exam = result.Items.ShouldHaveSingleItem().ShouldBeOfType(); @@ -121,14 +118,11 @@ public async Task CanGetDiagnosticImagingData() .ReturnsAsync( new HealthDataResult( new HealthDataMetadata(), - new[] - { - phsaDiagnosticImageExam, - })); + [phsaDiagnosticImageExam])); IPatientDataRepository sut = CreateSut(patientApi.Object); - PatientDataQueryResult result = await sut.QueryAsync(new HealthQuery(this.pid, new[] { HealthCategory.DiagnosticImaging }), CancellationToken.None); + PatientDataQueryResult result = await sut.QueryAsync(new HealthQuery(this.pid, [HealthCategory.DiagnosticImaging]), CancellationToken.None); result.ShouldNotBeNull(); HealthGateway.PatientDataAccess.DiagnosticImagingExam exam = result.Items.ShouldHaveSingleItem().ShouldBeOfType(); @@ -159,11 +153,11 @@ public async Task CanGetCancerScreeningAndDiagnosticImagingData() patientApi .Setup(api => api.GetHealthDataAsync(this.pid, It.IsAny(), It.IsAny())) - .ReturnsAsync(new HealthDataResult(new HealthDataMetadata(), new HealthDataEntry[] { phsaDiagnosticImageExam, bcCancerScreening })); + .ReturnsAsync(new HealthDataResult(new HealthDataMetadata(), [phsaDiagnosticImageExam, bcCancerScreening])); IPatientDataRepository sut = CreateSut(patientApi.Object); - PatientDataQueryResult result = await sut.QueryAsync(new HealthQuery(this.pid, new[] { HealthCategory.DiagnosticImaging, HealthCategory.BcCancerScreening }), CancellationToken.None) + PatientDataQueryResult result = await sut.QueryAsync(new HealthQuery(this.pid, [HealthCategory.DiagnosticImaging, HealthCategory.BcCancerScreening]), CancellationToken.None) ; result.ShouldNotBeNull(); diff --git a/Apps/WebClient/src/ClientApp/src/ioc/container.ts b/Apps/WebClient/src/ClientApp/src/ioc/container.ts index b32589dd9d..45603dd833 100644 --- a/Apps/WebClient/src/ClientApp/src/ioc/container.ts +++ b/Apps/WebClient/src/ClientApp/src/ioc/container.ts @@ -6,8 +6,8 @@ interface IContainer { } class Container implements IContainer { - private mappings = new Map any>(); - private cachedMappings = new Map(); + private readonly mappings = new Map any>(); + private readonly cachedMappings = new Map(); public set(key: Identifier, factory: (c: Container) => T): void { this.mappings.set(key, factory); diff --git a/Apps/WebClient/src/ClientApp/src/models/timeline/bcCancerScreeningTimelineEntry.ts b/Apps/WebClient/src/ClientApp/src/models/timeline/bcCancerScreeningTimelineEntry.ts index c377d9060b..696420a149 100644 --- a/Apps/WebClient/src/ClientApp/src/models/timeline/bcCancerScreeningTimelineEntry.ts +++ b/Apps/WebClient/src/ClientApp/src/models/timeline/bcCancerScreeningTimelineEntry.ts @@ -17,7 +17,7 @@ export default class BcCancerScreeningTimelineEntry extends TimelineEntry { public fileName!: string; public eventText!: string; - private getComments: (entryId: string) => UserComment[] | null; + private readonly getComments: (entryId: string) => UserComment[] | null; public constructor( model: BcCancerScreening, diff --git a/Apps/WebClient/src/ClientApp/src/models/timeline/clinicalDocumentTimelineEntry.ts b/Apps/WebClient/src/ClientApp/src/models/timeline/clinicalDocumentTimelineEntry.ts index 31adcf23a6..7d8dffd95b 100644 --- a/Apps/WebClient/src/ClientApp/src/models/timeline/clinicalDocumentTimelineEntry.ts +++ b/Apps/WebClient/src/ClientApp/src/models/timeline/clinicalDocumentTimelineEntry.ts @@ -11,7 +11,7 @@ export default class ClinicalDocumentTimelineEntry extends TimelineEntry { public documentType: string; public facilityName: string; public discipline: string; - private getComments: (entyId: string) => UserComment[] | null; + private readonly getComments: (entyId: string) => UserComment[] | null; public constructor( model: ClinicalDocument, diff --git a/Apps/WebClient/src/ClientApp/src/models/timeline/covid19TestResultTimelineEntry.ts b/Apps/WebClient/src/ClientApp/src/models/timeline/covid19TestResultTimelineEntry.ts index c66d06b67d..b56440b7e7 100644 --- a/Apps/WebClient/src/ClientApp/src/models/timeline/covid19TestResultTimelineEntry.ts +++ b/Apps/WebClient/src/ClientApp/src/models/timeline/covid19TestResultTimelineEntry.ts @@ -25,7 +25,7 @@ export default class Covid19TestResultTimelineEntry extends TimelineEntry { public tests: Covid19TestData[]; - private getComments: (entyId: string) => UserComment[] | null; + private readonly getComments: (entyId: string) => UserComment[] | null; public constructor( model: Covid19LaboratoryOrder, diff --git a/Apps/WebClient/src/ClientApp/src/models/timeline/diagnosticImagingTimelineEntry.ts b/Apps/WebClient/src/ClientApp/src/models/timeline/diagnosticImagingTimelineEntry.ts index fb0c6dbcde..b3cb76964c 100644 --- a/Apps/WebClient/src/ClientApp/src/models/timeline/diagnosticImagingTimelineEntry.ts +++ b/Apps/WebClient/src/ClientApp/src/models/timeline/diagnosticImagingTimelineEntry.ts @@ -16,7 +16,7 @@ export default class DiagnosticImagingTimelineEntry extends TimelineEntry { public fileId: string | undefined; public examDate: StringISODate; - private getComments: (entryId: string) => UserComment[] | null; + private readonly getComments: (entryId: string) => UserComment[] | null; public constructor( model: DiagnosticImagingExam, diff --git a/Apps/WebClient/src/ClientApp/src/models/timeline/healthVisitTimelineEntry.ts b/Apps/WebClient/src/ClientApp/src/models/timeline/healthVisitTimelineEntry.ts index 5a2001362f..7678866e3c 100644 --- a/Apps/WebClient/src/ClientApp/src/models/timeline/healthVisitTimelineEntry.ts +++ b/Apps/WebClient/src/ClientApp/src/models/timeline/healthVisitTimelineEntry.ts @@ -12,7 +12,7 @@ export default class HealthVisitTimelineEntry extends TimelineEntry { public specialtyDescription: string; public clinic: ClinicViewModel; public showRollOffWarning: boolean; - private getComments: (entyId: string) => UserComment[] | null; + private readonly getComments: (entyId: string) => UserComment[] | null; public constructor( model: Encounter, diff --git a/Apps/WebClient/src/ClientApp/src/models/timeline/hospitalVisitTimelineEntry.ts b/Apps/WebClient/src/ClientApp/src/models/timeline/hospitalVisitTimelineEntry.ts index d2fc0db2fd..200785cf48 100644 --- a/Apps/WebClient/src/ClientApp/src/models/timeline/hospitalVisitTimelineEntry.ts +++ b/Apps/WebClient/src/ClientApp/src/models/timeline/hospitalVisitTimelineEntry.ts @@ -15,7 +15,7 @@ export default class HospitalVisitTimelineEntry extends TimelineEntry { public admitDateTime: DateWrapper; public endDateTime?: DateWrapper; - private getComments: (entyId: string) => UserComment[] | null; + private readonly getComments: (entyId: string) => UserComment[] | null; public constructor( model: HospitalVisit, diff --git a/Apps/WebClient/src/ClientApp/src/models/timeline/labResultTimelineEntry.ts b/Apps/WebClient/src/ClientApp/src/models/timeline/labResultTimelineEntry.ts index 88c8534ce8..6124f325a2 100644 --- a/Apps/WebClient/src/ClientApp/src/models/timeline/labResultTimelineEntry.ts +++ b/Apps/WebClient/src/ClientApp/src/models/timeline/labResultTimelineEntry.ts @@ -21,7 +21,7 @@ export default class LabResultTimelineEntry extends TimelineEntry { public tests: LaboratoryTestViewModel[]; - private getComments: (entyId: string) => UserComment[] | null; + private readonly getComments: (entyId: string) => UserComment[] | null; public constructor( model: LaboratoryOrder, diff --git a/Apps/WebClient/src/ClientApp/src/models/timeline/medicationTimelineEntry.ts b/Apps/WebClient/src/ClientApp/src/models/timeline/medicationTimelineEntry.ts index 63529f3046..e583f539ef 100644 --- a/Apps/WebClient/src/ClientApp/src/models/timeline/medicationTimelineEntry.ts +++ b/Apps/WebClient/src/ClientApp/src/models/timeline/medicationTimelineEntry.ts @@ -19,7 +19,7 @@ export default class MedicationTimelineEntry extends TimelineEntry { public prescriptionProvided?: boolean; public redirectedToHealthCareProvider?: boolean; - private getComments: (entyId: string) => UserComment[] | null; + private readonly getComments: (entyId: string) => UserComment[] | null; public constructor( model: MedicationStatement, diff --git a/Apps/WebClient/src/ClientApp/src/models/timeline/noteTimelineEntry.ts b/Apps/WebClient/src/ClientApp/src/models/timeline/noteTimelineEntry.ts index 04852a679b..dd19f6a991 100644 --- a/Apps/WebClient/src/ClientApp/src/models/timeline/noteTimelineEntry.ts +++ b/Apps/WebClient/src/ClientApp/src/models/timeline/noteTimelineEntry.ts @@ -11,7 +11,7 @@ export default class NoteTimelineEntry extends TimelineEntry { public title: string; public hdid: string; public version?: number; - private static maxSumaryLength = 40; + private static readonly maxSumaryLength = 40; public constructor(model: UserNote) { super( diff --git a/Apps/WebClient/src/ClientApp/src/models/timeline/specialAuthorityRequestTimelineEntry.ts b/Apps/WebClient/src/ClientApp/src/models/timeline/specialAuthorityRequestTimelineEntry.ts index 9e69ab5a1f..468dca73d4 100644 --- a/Apps/WebClient/src/ClientApp/src/models/timeline/specialAuthorityRequestTimelineEntry.ts +++ b/Apps/WebClient/src/ClientApp/src/models/timeline/specialAuthorityRequestTimelineEntry.ts @@ -13,7 +13,7 @@ export default class SpecialAuthorityRequestTimelineEntry extends TimelineEntry public expiryDate?: DateWrapper; public referenceNumber: string; - private getComments: (entyId: string) => UserComment[] | null; + private readonly getComments: (entyId: string) => UserComment[] | null; public constructor( model: MedicationRequest, diff --git a/Apps/WebClient/src/ClientApp/src/services/httpDelegate.ts b/Apps/WebClient/src/ClientApp/src/services/httpDelegate.ts index 609ff760af..0f7d42e43a 100644 --- a/Apps/WebClient/src/ClientApp/src/services/httpDelegate.ts +++ b/Apps/WebClient/src/ClientApp/src/services/httpDelegate.ts @@ -5,7 +5,7 @@ import { HttpError } from "@/models/errors"; import { IHttpDelegate, ILogger } from "@/services/interfaces"; export class HttpDelegate implements IHttpDelegate { - private logger; + private readonly logger; constructor(logger: ILogger) { this.logger = logger; diff --git a/Apps/WebClient/src/ClientApp/src/services/restAuthService.ts b/Apps/WebClient/src/ClientApp/src/services/restAuthService.ts index d25e5e7fc2..476029d726 100644 --- a/Apps/WebClient/src/ClientApp/src/services/restAuthService.ts +++ b/Apps/WebClient/src/ClientApp/src/services/restAuthService.ts @@ -8,11 +8,11 @@ import { IAuthenticationService, ILogger } from "@/services/interfaces"; const REFRESH_CUSHION = 30; export class RestAuthenticationService implements IAuthenticationService { - private logger; - private keycloak; - private scope!: string; - private logonCallback!: string; - private logoutCallback!: string; + private readonly logger; + private readonly keycloak; + private readonly scope!: string; + private readonly logonCallback!: string; + private readonly logoutCallback!: string; // RestAuthenticationService.GetService() should be called instead of using the constructor directly. constructor( diff --git a/Apps/WebClient/src/ClientApp/src/services/restClinicalDocumentService.ts b/Apps/WebClient/src/ClientApp/src/services/restClinicalDocumentService.ts index 9a6aac2b06..b86c8f7b7b 100644 --- a/Apps/WebClient/src/ClientApp/src/services/restClinicalDocumentService.ts +++ b/Apps/WebClient/src/ClientApp/src/services/restClinicalDocumentService.ts @@ -16,10 +16,10 @@ import ErrorTranslator from "@/utility/errorTranslator"; export class RestClinicalDocumentService implements IClinicalDocumentService { private readonly BASE_URI = "ClinicalDocument"; - private logger; - private http; - private baseUri; - private isEnabled; + private readonly logger; + private readonly http; + private readonly baseUri; + private readonly isEnabled; constructor( logger: ILogger, diff --git a/Apps/WebClient/src/ClientApp/src/services/restCommunicationService.ts b/Apps/WebClient/src/ClientApp/src/services/restCommunicationService.ts index cecdd9d4b2..1047640c65 100644 --- a/Apps/WebClient/src/ClientApp/src/services/restCommunicationService.ts +++ b/Apps/WebClient/src/ClientApp/src/services/restCommunicationService.ts @@ -12,9 +12,9 @@ import ErrorTranslator from "@/utility/errorTranslator"; export class RestCommunicationService implements ICommunicationService { private readonly BASE_URI: string = "Communication"; - private logger; - private http; - private baseUri; + private readonly logger; + private readonly http; + private readonly baseUri; constructor( logger: ILogger, diff --git a/Apps/WebClient/src/ClientApp/src/services/restConfigService.ts b/Apps/WebClient/src/ClientApp/src/services/restConfigService.ts index 8b95282e06..a4093af5db 100644 --- a/Apps/WebClient/src/ClientApp/src/services/restConfigService.ts +++ b/Apps/WebClient/src/ClientApp/src/services/restConfigService.ts @@ -5,10 +5,10 @@ import { IConfigService, IHttpDelegate, ILogger } from "@/services/interfaces"; import ErrorTranslator from "@/utility/errorTranslator"; export class RestConfigService implements IConfigService { - private logger; + private readonly logger; private readonly CONFIG_BASE_URI: string = "configuration"; - private http; - private baseUri = import.meta.env.VITE_WEB_CLIENT_BASE_URI || "/"; + private readonly http; + private readonly baseUri = import.meta.env.VITE_WEB_CLIENT_BASE_URI || "/"; constructor(logger: ILogger, httpDelegate: IHttpDelegate) { this.logger = logger; diff --git a/Apps/WebClient/src/ClientApp/src/services/restDependentService.ts b/Apps/WebClient/src/ClientApp/src/services/restDependentService.ts index 804b13bd7d..0111db2ced 100644 --- a/Apps/WebClient/src/ClientApp/src/services/restDependentService.ts +++ b/Apps/WebClient/src/ClientApp/src/services/restDependentService.ts @@ -14,10 +14,10 @@ import RequestResultUtil from "@/utility/requestResultUtil"; export class RestDependentService implements IDependentService { private readonly DEPENDENT_BASE_URI: string = "UserProfile"; - private logger; - private http; - private baseUri; - private isEnabled; + private readonly logger; + private readonly http; + private readonly baseUri; + private readonly isEnabled; constructor( logger: ILogger, diff --git a/Apps/WebClient/src/ClientApp/src/services/restEncounterService.ts b/Apps/WebClient/src/ClientApp/src/services/restEncounterService.ts index fb11725104..1ab13721ac 100644 --- a/Apps/WebClient/src/ClientApp/src/services/restEncounterService.ts +++ b/Apps/WebClient/src/ClientApp/src/services/restEncounterService.ts @@ -15,10 +15,10 @@ import ErrorTranslator from "@/utility/errorTranslator"; export class RestEncounterService implements IEncounterService { private readonly ENCOUNTER_BASE_URI: string = "Encounter"; - private logger; - private http; - private baseUri; - private isEnabled; + private readonly logger; + private readonly http; + private readonly baseUri; + private readonly isEnabled; constructor( logger: ILogger, diff --git a/Apps/WebClient/src/ClientApp/src/services/restHospitalVisitService.ts b/Apps/WebClient/src/ClientApp/src/services/restHospitalVisitService.ts index a3c4a6a3b4..0f0389f138 100644 --- a/Apps/WebClient/src/ClientApp/src/services/restHospitalVisitService.ts +++ b/Apps/WebClient/src/ClientApp/src/services/restHospitalVisitService.ts @@ -15,10 +15,10 @@ import ErrorTranslator from "@/utility/errorTranslator"; export class RestHospitalVisitService implements IHospitalVisitService { private readonly HOSPITAL_VISIT_BASE_URI: string = "Encounter"; - private logger; - private http; - private baseUri; - private isEnabled; + private readonly logger; + private readonly http; + private readonly baseUri; + private readonly isEnabled; constructor( logger: ILogger, diff --git a/Apps/WebClient/src/ClientApp/src/services/restImmunizationService.ts b/Apps/WebClient/src/ClientApp/src/services/restImmunizationService.ts index 91e5c1ca63..5db4a8ac4f 100644 --- a/Apps/WebClient/src/ClientApp/src/services/restImmunizationService.ts +++ b/Apps/WebClient/src/ClientApp/src/services/restImmunizationService.ts @@ -15,10 +15,10 @@ import ErrorTranslator from "@/utility/errorTranslator"; export class RestImmunizationService implements IImmunizationService { private readonly IMMS_BASE_URI: string = "Immunization"; - private logger; - private http; - private baseUri; - private isEnabled; + private readonly logger; + private readonly http; + private readonly baseUri; + private readonly isEnabled; constructor( logger: ILogger, diff --git a/Apps/WebClient/src/ClientApp/src/services/restLaboratoryService.ts b/Apps/WebClient/src/ClientApp/src/services/restLaboratoryService.ts index 47fd2339c8..b3ba551c5e 100644 --- a/Apps/WebClient/src/ClientApp/src/services/restLaboratoryService.ts +++ b/Apps/WebClient/src/ClientApp/src/services/restLaboratoryService.ts @@ -19,11 +19,11 @@ import ErrorTranslator from "@/utility/errorTranslator"; export class RestLaboratoryService implements ILaboratoryService { private readonly LABORATORY_BASE_URI: string = "Laboratory"; - private logger; - private http; - private baseUri; - private isEnabled; - private isCovid19Enabled; + private readonly logger; + private readonly http; + private readonly baseUri; + private readonly isEnabled; + private readonly isCovid19Enabled; constructor( logger: ILogger, diff --git a/Apps/WebClient/src/ClientApp/src/services/restMedicationService.ts b/Apps/WebClient/src/ClientApp/src/services/restMedicationService.ts index 7dcb2a66c7..3456ecb418 100644 --- a/Apps/WebClient/src/ClientApp/src/services/restMedicationService.ts +++ b/Apps/WebClient/src/ClientApp/src/services/restMedicationService.ts @@ -16,10 +16,10 @@ import ErrorTranslator from "@/utility/errorTranslator"; export class RestMedicationService implements IMedicationService { private readonly BASE_URI: string = "MedicationStatement"; - private logger; - private http; - private baseUri; - private isEnabled; + private readonly logger; + private readonly http; + private readonly baseUri; + private readonly isEnabled; constructor( logger: ILogger, diff --git a/Apps/WebClient/src/ClientApp/src/services/restNotificationService.ts b/Apps/WebClient/src/ClientApp/src/services/restNotificationService.ts index 353bd464bf..e9d17e465d 100644 --- a/Apps/WebClient/src/ClientApp/src/services/restNotificationService.ts +++ b/Apps/WebClient/src/ClientApp/src/services/restNotificationService.ts @@ -11,10 +11,10 @@ import ErrorTranslator from "@/utility/errorTranslator"; export class RestNotificationService implements INotificationService { private readonly NOTIFICATION_BASE_URI: string = "Notification"; - private logger; - private http; - private baseUri; - private isEnabled; + private readonly logger; + private readonly http; + private readonly baseUri; + private readonly isEnabled; constructor( logger: ILogger, diff --git a/Apps/WebClient/src/ClientApp/src/services/restPatientDataService.ts b/Apps/WebClient/src/ClientApp/src/services/restPatientDataService.ts index 72b4c698af..32965a1fb0 100644 --- a/Apps/WebClient/src/ClientApp/src/services/restPatientDataService.ts +++ b/Apps/WebClient/src/ClientApp/src/services/restPatientDataService.ts @@ -39,9 +39,9 @@ export const entryTypeToPatientDataTypeMap: Map = export class RestPatientDataService implements IPatientDataService { private readonly BASE_URI = "PatientData"; - private logger; - private http; - private baseUri; + private readonly logger; + private readonly http; + private readonly baseUri; constructor( logger: ILogger, diff --git a/Apps/WebClient/src/ClientApp/src/services/restPatientService.ts b/Apps/WebClient/src/ClientApp/src/services/restPatientService.ts index c4c92f8e36..296435c1ba 100644 --- a/Apps/WebClient/src/ClientApp/src/services/restPatientService.ts +++ b/Apps/WebClient/src/ClientApp/src/services/restPatientService.ts @@ -7,9 +7,9 @@ import ErrorTranslator from "@/utility/errorTranslator"; export class RestPatientService implements IPatientService { private readonly PATIENT_BASE_URI: string = "Patient"; - private logger; - private http; - private baseUri; + private readonly logger; + private readonly http; + private readonly baseUri; constructor( logger: ILogger, diff --git a/Apps/WebClient/src/ClientApp/src/services/restPcrTestService.ts b/Apps/WebClient/src/ClientApp/src/services/restPcrTestService.ts index f6ff132544..f70fc1f138 100644 --- a/Apps/WebClient/src/ClientApp/src/services/restPcrTestService.ts +++ b/Apps/WebClient/src/ClientApp/src/services/restPcrTestService.ts @@ -11,10 +11,10 @@ import RequestResultUtil from "@/utility/requestResultUtil"; export class RestPcrTestService implements IPcrTestService { private readonly LABORATORY_BASE_URI: string = "Laboratory"; private readonly PUBLIC_LABORATORY_BASE_URI: string = "PublicLaboratory"; - private logger; - private http; - private baseUri; - private isEnabled; + private readonly logger; + private readonly http; + private readonly baseUri; + private readonly isEnabled; constructor( logger: ILogger, diff --git a/Apps/WebClient/src/ClientApp/src/services/restReportService.ts b/Apps/WebClient/src/ClientApp/src/services/restReportService.ts index ee78a9301e..d19b803f96 100644 --- a/Apps/WebClient/src/ClientApp/src/services/restReportService.ts +++ b/Apps/WebClient/src/ClientApp/src/services/restReportService.ts @@ -9,9 +9,9 @@ import ErrorTranslator from "@/utility/errorTranslator"; export class RestReportService implements IReportService { private readonly REPORT_BASE_URI: string = "Report"; - private logger; - private http; - private baseUri; + private readonly logger; + private readonly http; + private readonly baseUri; constructor( logger: ILogger, diff --git a/Apps/WebClient/src/ClientApp/src/services/restSpecialAuthorityService.ts b/Apps/WebClient/src/ClientApp/src/services/restSpecialAuthorityService.ts index ff4d242cf5..ed7033c222 100644 --- a/Apps/WebClient/src/ClientApp/src/services/restSpecialAuthorityService.ts +++ b/Apps/WebClient/src/ClientApp/src/services/restSpecialAuthorityService.ts @@ -15,10 +15,10 @@ import ErrorTranslator from "@/utility/errorTranslator"; export class RestSpecialAuthorityService implements ISpecialAuthorityService { private readonly SPECIAL_AUTHORITY_BASE_URI: string = "MedicationRequest"; - private logger; - private http; - private baseUri; - private isEnabled; + private readonly logger; + private readonly http; + private readonly baseUri; + private readonly isEnabled; constructor( logger: ILogger, diff --git a/Apps/WebClient/src/ClientApp/src/services/restTrackingService.ts b/Apps/WebClient/src/ClientApp/src/services/restTrackingService.ts index 91ad2a6bb4..95e56abbda 100644 --- a/Apps/WebClient/src/ClientApp/src/services/restTrackingService.ts +++ b/Apps/WebClient/src/ClientApp/src/services/restTrackingService.ts @@ -4,7 +4,7 @@ import { ILogger, ITrackingService } from "@/services/interfaces"; declare let window: SnowplowWindow; export class RestTrackingService implements ITrackingService { - private logger; + private readonly logger; constructor(logger: ILogger) { this.logger = logger; diff --git a/Apps/WebClient/src/ClientApp/src/services/restUserCommentService.ts b/Apps/WebClient/src/ClientApp/src/services/restUserCommentService.ts index c3a3397f34..473f7b0990 100644 --- a/Apps/WebClient/src/ClientApp/src/services/restUserCommentService.ts +++ b/Apps/WebClient/src/ClientApp/src/services/restUserCommentService.ts @@ -15,10 +15,10 @@ import RequestResultUtil from "@/utility/requestResultUtil"; export class RestUserCommentService implements IUserCommentService { private readonly USER_COMMENT_BASE_URI: string = "UserProfile"; - private logger; - private http; - private baseUri; - private isEnabled; + private readonly logger; + private readonly http; + private readonly baseUri; + private readonly isEnabled; constructor( logger: ILogger, diff --git a/Apps/WebClient/src/ClientApp/src/services/restUserFeedback.ts b/Apps/WebClient/src/ClientApp/src/services/restUserFeedback.ts index 14d1603b4f..fe4b37958b 100644 --- a/Apps/WebClient/src/ClientApp/src/services/restUserFeedback.ts +++ b/Apps/WebClient/src/ClientApp/src/services/restUserFeedback.ts @@ -11,9 +11,9 @@ import ErrorTranslator from "@/utility/errorTranslator"; export class RestUserFeedbackService implements IUserFeedbackService { private readonly USER_FEEDBACK_BASE_URI: string = "UserFeedback"; - private logger; - private http; - private baseUri; + private readonly logger; + private readonly http; + private readonly baseUri; constructor( logger: ILogger, diff --git a/Apps/WebClient/src/ClientApp/src/services/restUserNoteService.ts b/Apps/WebClient/src/ClientApp/src/services/restUserNoteService.ts index b3efbe3f9e..b828a13daf 100644 --- a/Apps/WebClient/src/ClientApp/src/services/restUserNoteService.ts +++ b/Apps/WebClient/src/ClientApp/src/services/restUserNoteService.ts @@ -17,10 +17,10 @@ import RequestResultUtil from "@/utility/requestResultUtil"; export class RestUserNoteService implements IUserNoteService { private readonly USER_NOTE_BASE_URI: string = "Note"; - private logger; - private http; - private baseUri; - private isEnabled; + private readonly logger; + private readonly http; + private readonly baseUri; + private readonly isEnabled; constructor( logger: ILogger, diff --git a/Apps/WebClient/src/ClientApp/src/services/restUserProfileService.ts b/Apps/WebClient/src/ClientApp/src/services/restUserProfileService.ts index 1a8d573a1b..82d1e69caf 100644 --- a/Apps/WebClient/src/ClientApp/src/services/restUserProfileService.ts +++ b/Apps/WebClient/src/ClientApp/src/services/restUserProfileService.ts @@ -19,9 +19,9 @@ export class RestUserProfileService implements IUserProfileService { "application/json; charset=utf-8"; private readonly CONTENT_TYPE: string = "Content-Type"; private readonly USER_PROFILE_BASE_URI: string = "UserProfile"; - private logger; - private http; - private baseUri; + private readonly logger; + private readonly http; + private readonly baseUri; constructor( logger: ILogger, diff --git a/Apps/WebClient/src/ClientApp/src/services/restUserProfileServiceV2.ts b/Apps/WebClient/src/ClientApp/src/services/restUserProfileServiceV2.ts index cd22fd2379..23ba4c9c5a 100644 --- a/Apps/WebClient/src/ClientApp/src/services/restUserProfileServiceV2.ts +++ b/Apps/WebClient/src/ClientApp/src/services/restUserProfileServiceV2.ts @@ -18,9 +18,9 @@ export class RestUserProfileServiceV2 implements IUserProfileService { private readonly CONTENT_TYPE: string = "Content-Type"; private readonly USER_PROFILE_BASE_URI: string = "UserProfile"; private readonly API_VERSION: string = "2.0"; - private logger; - private http; - private baseUri; + private readonly logger; + private readonly http; + private readonly baseUri; constructor( logger: ILogger, diff --git a/Apps/WebClient/src/ClientApp/src/services/restUserRatingService.ts b/Apps/WebClient/src/ClientApp/src/services/restUserRatingService.ts index 37127d821d..abba721770 100644 --- a/Apps/WebClient/src/ClientApp/src/services/restUserRatingService.ts +++ b/Apps/WebClient/src/ClientApp/src/services/restUserRatingService.ts @@ -11,9 +11,9 @@ import ErrorTranslator from "@/utility/errorTranslator"; export class RestUserRatingService implements IUserRatingService { private readonly USER_RATING_BASE_URI: string = "UserFeedback/Rating"; - private logger; - private http; - private baseUri; + private readonly logger; + private readonly http; + private readonly baseUri; constructor( logger: ILogger, diff --git a/Apps/WebClient/src/ClientApp/src/services/restVaccinationStatusService.ts b/Apps/WebClient/src/ClientApp/src/services/restVaccinationStatusService.ts index f1cd2b9c9c..37ada92eaf 100644 --- a/Apps/WebClient/src/ClientApp/src/services/restVaccinationStatusService.ts +++ b/Apps/WebClient/src/ClientApp/src/services/restVaccinationStatusService.ts @@ -18,10 +18,10 @@ export class RestVaccinationStatusService implements IVaccinationStatusService { "PublicVaccineStatus"; private readonly AUTHENTICATED_VACCINATION_STATUS_BASE_URI: string = "AuthenticatedVaccineStatus"; - private logger; - private http; - private baseUri; - private isEnabled; + private readonly logger; + private readonly http; + private readonly baseUri; + private readonly isEnabled; constructor( logger: ILogger, diff --git a/Apps/WebClient/src/ClientApp/src/stores/auth.ts b/Apps/WebClient/src/ClientApp/src/stores/auth.ts index fca55c0b6c..f3398749c7 100644 --- a/Apps/WebClient/src/ClientApp/src/stores/auth.ts +++ b/Apps/WebClient/src/ClientApp/src/stores/auth.ts @@ -124,21 +124,29 @@ export const useAuthStore = defineStore("auth", () => { } } + function handleTokenRefreshed() { + logger.verbose("Refreshed access token"); + const tokenDetails = authService.getOidcTokenDetails(); + if (tokenDetails !== null) { + handleSuccessfulAuthentication(tokenDetails); + } + } + + function handleTokenNotRefreshed() { + logger.verbose("Access token refresh not required"); + } + function refreshToken() { logger.info("Refreshing access token"); + + const actions: Record void> = { + true: handleTokenRefreshed, + false: handleTokenNotRefreshed, + }; + authService .refreshToken() - .then((refreshed) => { - if (refreshed) { - logger.verbose("Refreshed access token"); - const tokenDetails = authService.getOidcTokenDetails(); - if (tokenDetails !== null) { - handleSuccessfulAuthentication(tokenDetails); - } - } else { - logger.verbose("Access token refresh not required"); - } - }) + .then((refreshed) => actions[refreshed.toString()]()) .catch(() => { logger.warn("Access token expired unexpectedly"); signOut(); diff --git a/Apps/WebClient/src/ClientApp/src/utility/idleDetector.ts b/Apps/WebClient/src/ClientApp/src/utility/idleDetector.ts index 3b31c1f0b6..30de33f888 100644 --- a/Apps/WebClient/src/ClientApp/src/utility/idleDetector.ts +++ b/Apps/WebClient/src/ClientApp/src/utility/idleDetector.ts @@ -13,11 +13,13 @@ export class IdleDetector { ]; private readonly idleTimer: ReliableTimer; private enabled = false; - private notifyActiveThrottled = throttle(1000, () => this.notifyActive()); + private readonly notifyActiveThrottled = throttle(1000, () => + this.notifyActive() + ); constructor( - private isIdleCallback: (timeIdle: number) => void, - private timeBeforeIdle: number, + private readonly isIdleCallback: (timeIdle: number) => void, + private readonly timeBeforeIdle: number, startEnabled: boolean ) { this.idleTimer = new ReliableTimer( diff --git a/Apps/WebClient/src/ClientApp/src/utility/reliableTimer.ts b/Apps/WebClient/src/ClientApp/src/utility/reliableTimer.ts index 3f415c4bcb..9747125b14 100644 --- a/Apps/WebClient/src/ClientApp/src/utility/reliableTimer.ts +++ b/Apps/WebClient/src/ClientApp/src/utility/reliableTimer.ts @@ -3,7 +3,10 @@ export class ReliableTimer { private timeoutId?: ReturnType; private startingTimestamp?: number; - constructor(private callback: () => void, private duration: number) { + constructor( + private readonly callback: () => void, + private readonly duration: number + ) { if (duration < this.interval) { throw new Error(`Duration must be at least ${this.interval}ms`); } diff --git a/Apps/WebClient/src/ClientApp/src/utility/validationUtil.ts b/Apps/WebClient/src/ClientApp/src/utility/validationUtil.ts index d533f38858..95afa229ce 100644 --- a/Apps/WebClient/src/ClientApp/src/utility/validationUtil.ts +++ b/Apps/WebClient/src/ClientApp/src/utility/validationUtil.ts @@ -79,6 +79,6 @@ export default abstract class ValidationUtil { predicate: boolean, validatorObject: object ) { - return predicate ? validatorObject : {}; + return (predicate && validatorObject) || {}; } } diff --git a/Apps/WebClient/src/Server/Models/MobileConfiguration.cs b/Apps/WebClient/src/Server/Models/MobileConfiguration.cs index cd3d447e23..14dd63000a 100644 --- a/Apps/WebClient/src/Server/Models/MobileConfiguration.cs +++ b/Apps/WebClient/src/Server/Models/MobileConfiguration.cs @@ -17,7 +17,6 @@ namespace HealthGateway.WebClient.Server.Models { using System; using System.Collections.Generic; - using System.Linq; /// /// Configuration data to be used by the Health Gateway Mobile App. @@ -35,16 +34,16 @@ public record MobileConfiguration( /// /// Gets or sets the collection of enabled datasets. /// - public IEnumerable Datasets { get; set; } = Enumerable.Empty(); + public IEnumerable Datasets { get; set; } = []; /// /// Gets or sets the collection of enabled datasets for dependents. /// - public IEnumerable DependentDatasets { get; set; } = Enumerable.Empty(); + public IEnumerable DependentDatasets { get; set; } = []; /// /// Gets or sets the collection of enabled services. /// - public IEnumerable Services { get; set; } = Enumerable.Empty(); + public IEnumerable Services { get; set; } = []; } } diff --git a/Apps/WebClient/test/unit/Controllers/RobotsControllerTests.cs b/Apps/WebClient/test/unit/Controllers/RobotsControllerTests.cs index bacf94ca7e..c660175061 100644 --- a/Apps/WebClient/test/unit/Controllers/RobotsControllerTests.cs +++ b/Apps/WebClient/test/unit/Controllers/RobotsControllerTests.cs @@ -17,7 +17,6 @@ namespace HealthGateway.WebClientTests.Controllers { using System.Collections.Generic; using System.IO; - using System.Linq; using System.Net.Mime; using System.Threading.Tasks; using DeepEqual.Syntax; @@ -73,7 +72,7 @@ public async Task ShouldGetRobots(bool robotsFilePathExists, bool robotsFileCont }; IConfigurationRoot configuration = new ConfigurationBuilder() - .AddInMemoryCollection(myConfiguration.ToList()) + .AddInMemoryCollection(myConfiguration) .Build(); using RobotsController controller = new(configuration); diff --git a/Apps/WebClient/test/unit/Services/ConfigurationServiceTests.cs b/Apps/WebClient/test/unit/Services/ConfigurationServiceTests.cs index c91d00ae6f..3c1c57446c 100644 --- a/Apps/WebClient/test/unit/Services/ConfigurationServiceTests.cs +++ b/Apps/WebClient/test/unit/Services/ConfigurationServiceTests.cs @@ -81,8 +81,8 @@ public async Task TestGetMobileConfiguration() "myhealthbc://*"), 2) { - Datasets = new[] - { + Datasets = + [ "bcCancerScreening", "clinicalDocument", "covid19TestResult", @@ -94,9 +94,9 @@ public async Task TestGetMobileConfiguration() "medication", "note", "specialAuthorityRequest", - }, - DependentDatasets = new[] - { + ], + DependentDatasets = + [ "bcCancerScreening", "clinicalDocument", "covid19TestResult", @@ -107,12 +107,12 @@ public async Task TestGetMobileConfiguration() "labResult", "medication", "specialAuthorityRequest", - }, - Services = new[] - { + ], + Services = + [ "organDonorRegistration", "healthConnectRegistry", - }, + ], }; MobileConfiguration actualResult = await this.service.GetMobileConfigurationAsync(); @@ -176,8 +176,8 @@ private static ExternalConfiguration GenerateExternalConfiguration( { "Logout", new Uri("https://localhost/logout") }, }, }, - IdentityProviders = new[] - { + IdentityProviders = + [ new IdentityProviderConfiguration { Id = "Id", @@ -186,7 +186,7 @@ private static ExternalConfiguration GenerateExternalConfiguration( Hint = "Hint", Disabled = true, }, - }, + ], WebClient = new WebClientConfiguration { LogLevel = "LogLevel", @@ -207,23 +207,10 @@ private static ExternalConfiguration GenerateExternalConfiguration( new HomepageSettings(true, true), new NotificationCentreSettings(true), new TimelineSettings(true), - new DatasetSettings[] - { - new("bcCancerScreening", true), - new("clinicalDocument", true), - new("covid19TestResult", true), - new("diagnosticImaging", true), - new("healthVisit", true), - new("hospitalVisit", true), - new("immunization", true), - new("labResult", true), - new("medication", true), - new("note", true), - new("specialAuthorityRequest", true), - }, + GetFeatureDatasetSettings(), new Covid19Settings(true, new PublicCovid19Settings(true), new ProofOfVaccinationSettings(false)), - new DependentsSettings(true, true, new DatasetSettings[] { new("note", false) }), - new ServicesSettings(true, new ServiceSetting[] { new("organDonorRegistration", true), new("healthConnectRegistry", true) })) + new DependentsSettings(true, true, [new("note", false)]), + new ServicesSettings(true, [new("organDonorRegistration", true), new("healthConnectRegistry", true)])) : null, }, ServiceEndpoints = new Dictionary @@ -234,5 +221,14 @@ private static ExternalConfiguration GenerateExternalConfiguration( }, }; } + + private static DatasetSettings[] GetFeatureDatasetSettings() + { + return + [ + new("bcCancerScreening", true), new("clinicalDocument", true), new("covid19TestResult", true), new("diagnosticImaging", true), new("healthVisit", true), + new("hospitalVisit", true), new("immunization", true), new("labResult", true), new("medication", true), new("note", true), new("specialAuthorityRequest", true), + ]; + } } } diff --git a/Apps/sonar-config.xml b/Apps/sonar-config.xml index 92f4b52019..035f8d70d9 100644 --- a/Apps/sonar-config.xml +++ b/Apps/sonar-config.xml @@ -17,7 +17,8 @@ --> - **/node_modules/**/*,**/wwwroot/**/*,**/ClientApp/public/**/*,**/Startup.cs + $(Build.SourcesDirectory)/Apps + **/node_modules/**/*,**/wwwroot/**/*,**/ClientApp/public/**/*,**/Startup.cs,**/Testing/**,**/Tools/** **/test/**/*Tests.cs,**/Tests/**/*Tests.cs **/*Controller.cs,**/Models/**/*,**/Admin/Client/**/*,**/Database/**/*,**/DBMaintainer/**/*,**/JobScheduler/**/*,**/ClientApp/**/* https://sonarcloud.io