From ebe2f8471f22e0f0f53437e0bde82863bd0364b7 Mon Sep 17 00:00:00 2001 From: CDR Open Source Date: Thu, 20 Mar 2025 01:24:16 +0000 Subject: [PATCH] v3.0.0 release --- .azuredevops/pipelines/publish.yml | 187 +++++++++--------- CHANGELOG.md | 7 + SECURITY.md | 3 +- Source/.editorconfig | 120 +++++++++++ ...ckSolution.TestAutomation.UnitTests.csproj | 9 + .../Tests/TestClass1.cs | 7 +- ...antTooling.MockSolution.TestAutomation.sln | 2 + .../Assertions.cs | 69 +++---- .../DisplayTestMethodNameAttribute.cs | 11 +- .../AuthoriseURLBuilder.cs | 37 +++- .../Constants.cs | 33 ++-- ...Tooling.MockSolution.TestAutomation.csproj | 10 +- .../DataRecipientConsentCallback.cs | 25 ++- .../Enums/CdsErrors.cs | 8 +- .../Enums/EntityType.cs | 7 +- .../Enums/Industry.cs | 8 +- .../Enums/LegalEntityStatus.cs | 8 +- .../Enums/ResponseMode.cs | 19 +- .../Enums/ResponseType.cs | 14 +- .../Enums/SoftwareProductStatus.cs | 8 +- .../Enums/Status.cs | 7 +- .../Enums/TokenType.cs | 16 +- .../Exceptions/AuthoriseException.cs | 22 ++- .../InvalidClientException.cs | 63 ++++-- .../InvalidClientMetadataException.cs | 37 ++-- .../InvalidGrantException.cs | 32 +-- .../InvalidKeyHolderException.cs | 4 +- .../InvalidRedirectUriException.cs | 5 +- .../InvalidRequestException.cs | 76 ++++--- .../InvalidRequestObjectException.cs | 46 +++-- .../InvalidScopeException.cs | 5 +- .../InvalidSoftwareStatementException.cs | 3 +- .../UnsupportedGrantTypeException.cs | 13 +- .../Exceptions/CdrErrorExtensions.cs | 10 +- .../Exceptions/CdrException.cs | 8 +- .../Exceptions/CdrValidationException.cs | 8 +- .../AdrStatusNotActiveException.cs | 23 ++- .../InvalidArrangementException.cs | 12 +- .../CdsExceptions/InvalidConsentException.cs | 17 +- .../InvalidEnergyAccountException.cs | 12 +- .../CdsExceptions/InvalidFieldException.cs | 12 +- .../CdsExceptions/InvalidHeaderException.cs | 9 +- .../CdsExceptions/InvalidPageException.cs | 14 +- .../CdsExceptions/InvalidPageSizeException.cs | 12 +- .../CdsExceptions/InvalidVersionException.cs | 15 +- .../MissingRequiredFieldException.cs | 12 +- .../MissingRequiredHeaderException.cs | 12 +- .../ResourceNotFoundException.cs | 17 +- .../UnavailableBankingAccountException.cs | 14 +- .../UnsupportedVersionException.cs | 16 +- ...horiseIncorrectOneTimePasswordException.cs | 1 - .../Exceptions/InvalidTokenException.cs | 3 +- .../PageElementNotFoundException.cs | 8 +- .../Exceptions/UnexpectedErrorException.cs | 5 +- .../Extensions/DateTimeExtensions.cs | 3 +- .../Extensions/EnumHelper.cs | 6 +- .../Extensions/JsonExtensions.cs | 33 ++-- .../Extensions/JwtSecurityTokenExtensions.cs | 26 ++- .../Extensions/PlaywrightExtensions.cs | 10 +- .../Extensions/SQLExtensions.cs | 35 ++-- .../Extensions/ServiceCollectionExtensions.cs | 20 +- .../Extensions/StringExtensions.cs | 16 +- .../Extensions/TokenTypeExtensions.cs | 18 +- .../Fixtures/BaseFixture.cs | 45 +++-- .../Fixtures/PlaywrightFixture.cs | 6 +- .../RegisterSoftwareProductFixture.cs | 18 +- .../Helpers.cs | 71 ++++--- .../Interfaces/IAccessTokenService.cs | 10 + .../Interfaces/IApiService.cs | 22 ++- .../Interfaces/IApiServiceDirector.cs | 21 +- .../Interfaces/ICdrValidationException.cs | 6 +- .../Interfaces/IDataHolderAccessTokenCache.cs | 9 +- .../Interfaces/IDataHolderAuthoriseService.cs | 22 ++- .../Interfaces/IDataHolderParService.cs | 10 +- .../Interfaces/IDataHolderRegisterService.cs | 44 +++-- .../Interfaces/IDataHolderTokenService.cs | 10 +- .../Interfaces/IPrivateKeyJwtService.cs | 4 + .../Interfaces/IRegisterSSAService.cs | 6 +- .../Interfaces/ISqlQueryService.cs | 8 +- .../JwksEndpoint.cs | 32 +-- .../KeyValuePairBuilder.cs | 32 +-- .../LoggingHandler.cs | 6 +- .../Models/AccessToken.cs | 11 +- .../Models/AuthError.cs | 8 +- .../Models/CdrErrorAttribute.cs | 6 +- .../Models/DataRecipientBrand.cs | 11 +- .../Banking/Accounts/BankingAccountV2.cs | 20 +- .../Dataholders/Banking/Accounts/Data.cs | 8 +- .../Accounts/ResponseBankingAccountListV2.cs | 6 +- .../Transactions/BankingTransaction.cs | 39 ++-- .../Dataholders/Banking/Transactions/Data.cs | 8 +- .../ResponseBankingTransactionListV2.cs | 6 +- .../Models/Dataholders/Energy/Data.cs | 8 +- .../Dataholders/Energy/EnergyAccountV2.cs | 17 +- .../Models/Dataholders/Energy/Plan.cs | 14 +- .../Models/Dataholders/Energy/PlanOverview.cs | 14 +- .../Energy/ResponseEnergyAccountListV2.cs | 6 +- .../Models/Dataholders/LinksPaginated.cs | 10 +- .../Models/Dataholders/MetaPaginated.cs | 7 +- .../Models/Dataholders/TokenResponse.cs | 10 +- .../Models/Error.cs | 6 +- .../Models/ErrorV2.cs | 12 +- .../Models/JWK.cs | 11 +- .../Models/JWKS.cs | 6 +- .../Models/LegalEntity.cs | 10 +- .../TestAutomationAuthServerOptions.cs | 6 +- .../Models/Options/TestAutomationOptions.cs | 21 +- .../Models/Person.cs | 8 + .../Models/ResponseErrorList.cs | 12 +- .../Models/ResponseErrorListV2.cs | 22 ++- .../Models/SoftwareProduct.cs | 10 +- .../Services/AccessTokenService.cs | 37 ++-- .../Services/ApiService.cs | 45 +++-- .../Services/ApiServiceDirector.cs | 29 +-- .../Services/DataHolderAccessTokenCache.cs | 42 ++-- .../Services/DataHolderAuthoriseService.cs | 170 ++++++++-------- .../Services/DataHolderParService.cs | 49 ++--- .../Services/DataHolderRegisterService.cs | 77 ++++---- .../DataHolderTokenRevocationService.cs | 16 +- .../Services/DataHolderTokenService.cs | 78 ++++---- .../Services/PrivateKeyJwtService.cs | 27 +-- .../Services/RegisterSSAService.cs | 24 +-- .../Services/SqlQueryService.cs | 24 +-- .../SharedBaseTest.cs | 21 +- .../TestAssertionStrategy.cs | 24 +-- .../Authorisation/AuthenticateLoginPage.cs | 17 +- .../ConfirmAccountSharingPage.cs | 14 +- .../Authorisation/OneTimePasswordPage.cs | 19 +- .../Pages/Authorisation/SelectAccountsPage.cs | 24 +-- .../UI/PlaywrightDriver.cs | 20 +- .../XUnit/AlphabeticalOrderer.cs | 10 +- Source/Directory.Build.props | 8 + 132 files changed, 1680 insertions(+), 1138 deletions(-) create mode 100644 Source/Directory.Build.props diff --git a/.azuredevops/pipelines/publish.yml b/.azuredevops/pipelines/publish.yml index a0b2b41..455bfe0 100644 --- a/.azuredevops/pipelines/publish.yml +++ b/.azuredevops/pipelines/publish.yml @@ -1,34 +1,17 @@ -pool: - vmImage: 'windows-latest' parameters: +- name: PublishPackage + displayName: 'Confirm Publish Package to nuget' + type: boolean + default: false - name: pushEnvironment - displayName: 'Push to which environment?' + displayName: 'Nuget Environment' type: string values: - - Test - - Production - default: Test + - dev + - prod + default: dev -# The build configuration is defined, in this case we are building Release packages -# Based on 'pushEnvironment' parameter, we set other variables and variable groups to use test vs prod settings -variables: - - name: buildConfiguration - value: 'Release' - - name : apiKey - ${{ if eq(parameters.pushEnvironment, 'Production') }}: - value: $(nuget-mock-solution-test-automation-api-key) - ${{ if ne(parameters.pushEnvironment, 'Production') }}: - value: $(int-nugettest-mock-solution-test-automation-api-key) - - name : nugetOrgSource - ${{ if eq(parameters.pushEnvironment, 'Production') }}: - value: 'https://api.nuget.org/v3/index.json' - ${{ if ne(parameters.pushEnvironment, 'Production') }}: - value: 'https://apiint.nugettest.org/v3/index.json' - - ${{ if eq(parameters.pushEnvironment, 'Production') }}: - - group: nuget_package_deployment - - ${{ if ne(parameters.pushEnvironment, 'Production') }}: - - group: int_nugettest_package_deployment # The github-ref-prefix should be either 'tags/' (for a tagged release) or 'heads/' (for a branch). Release number is either the tag name or branch name # The standard release process would use a tagged release where the tag name is the version number (e.g 1.0.0) so prefix is default 'tags/' and release-number would be '1.0.0' @@ -40,72 +23,100 @@ resources: endpoint: github.com_CDR-CI ref: refs/$(github-ref-prefix)$(release-number) -# The build has 3 seperate tasks run under 1 step -steps: -- checkout: GitHubRepo - fetchDepth: 0 -# Build the project by running the dotnet command build, pointing to our csproj file -- task: DotNetCoreCLI@2 - displayName: 'dotnet build' - inputs: - command: 'build' - versioningScheme: byBuildNumber - arguments: '--configuration $(buildConfiguration) /p:UsingGitHubSource=true' - projects: '$(System.DefaultWorkingDirectory)\Source\**\*.csproj' +stages: +- stage: ${{parameters.pushEnvironment}} + variables: + - group: nuget_package_deployment_${{parameters.pushEnvironment}} + - group: nuget_package_deployment_certificate + - name: buildConfiguration + value: 'Release' + - name : nuget-server-url + ${{ if eq(parameters.pushEnvironment, 'prod') }}: + value: 'https://api.nuget.org/v3/index.json' + ${{ else }}: + value: 'https://apiint.nugettest.org/v3/index.json' + -# Create the package by running the dotnet pack command again pointing to the csproj file -# The nobuild means the project will not be compiled before running pack, because its already built in above step -- task: DotNetCoreCLI@2 - displayName: "dotnet pack" - inputs: - command: 'pack' - configuration: $(BuildConfiguration) - packagesToPack: '$(System.DefaultWorkingDirectory)\Source\**\*.csproj' - nobuild: true - versioningScheme: 'off' - -- task: PublishSymbols@2 - displayName: Publish symbols path - continueOnError: True - inputs: - SearchPattern: '**\bin\**\*.pdb' - PublishSymbols: false - SymbolServerType: TeamServices + pool: + vmImage: 'windows-latest' + jobs: + - job : deploy_${{parameters.pushEnvironment}} + + # The build has 3 seperate tasks run under 1 step + steps: + - checkout: GitHubRepo + fetchDepth: 0 -- task: DotNetCoreCLI@2 - displayName: Install NuGetKeyVaultSignTool - inputs: - command: 'custom' - custom: 'tool' - arguments: 'install --tool-path . NuGetKeyVaultSignTool' + # Build the project by running the dotnet command build, pointing to our csproj file + - task: DotNetCoreCLI@2 + displayName: 'dotnet build' + inputs: + command: 'build' + versioningScheme: byBuildNumber + arguments: '--configuration $(buildConfiguration) /p:UsingGitHubSource=true' + projects: '$(System.DefaultWorkingDirectory)\Source\**\*.csproj' + + # Create the package by running the dotnet pack command again pointing to the csproj file + # The nobuild means the project will not be compiled before running pack, because its already built in above step + - task: DotNetCoreCLI@2 + displayName: "dotnet pack" + inputs: + command: 'pack' + configuration: $(BuildConfiguration) + packagesToPack: '$(System.DefaultWorkingDirectory)\Source\**\*.csproj' + nobuild: true + versioningScheme: 'off' + + - task: PublishSymbols@2 + displayName: Publish symbols path + continueOnError: True + inputs: + SearchPattern: '**\bin\**\*.pdb' + PublishSymbols: false + SymbolServerType: TeamServices + + - task: DotNetCoreCLI@2 + displayName: Install NuGetKeyVaultSignTool + inputs: + command: 'custom' + custom: 'tool' + arguments: 'install --tool-path . NuGetKeyVaultSignTool' -# WARNING: This will not throw an error if it can't find the file and will close silently (false positive) -- task: PowerShell@2 - displayName: Signing with NuGetKeyVaultSignTool - inputs: - targetType: 'inline' - script: | - .\NuGetKeyVaultSignTool sign $(Build.ArtifactStagingDirectory)\*.nupkg ` - --file-digest "sha256" ` - --timestamp-rfc3161 "http://timestamp.digicert.com" ` - --timestamp-digest "sha256" ` - --azure-key-vault-url $(code-signing-kv-url) ` - --azure-key-vault-tenant-id $(code-signing-kv-tenant-id) ` - --azure-key-vault-client-id $(sp-code-signing-prod-client-id) ` - --azure-key-vault-client-secret $(sp-code-signing-prod-client-secret) ` - --azure-key-vault-certificate $(code-signing-cert-name) + # WARNING: This will not throw an error if it can't find the file and will close silently (false positive) + - task: PowerShell@2 + displayName: Signing with NuGetKeyVaultSignTool + inputs: + targetType: 'inline' + script: | + .\NuGetKeyVaultSignTool sign $(Build.ArtifactStagingDirectory)\*.nupkg ` + --file-digest "sha256" ` + --timestamp-rfc3161 "http://timestamp.digicert.com" ` + --timestamp-digest "sha256" ` + --azure-key-vault-url $(code-signing-kv-url) ` + --azure-key-vault-tenant-id $(code-signing-kv-tenant-id) ` + --azure-key-vault-client-id $(sp-code-signing-prod-client-id) ` + --azure-key-vault-client-secret $(sp-code-signing-prod-client-secret) ` + --azure-key-vault-certificate $(code-signing-cert-name) + + # NOTE: Avoiding verifying with NuGetKeyVaultSignTool as it is rather faulty. Will give false positive for a file that doesn't exist. + # Use dotnet nuget verify instead + - task: PowerShell@2 + displayName: Verifying NuGetKeyVaultSign + inputs: + targetType: 'inline' + script: 'dotnet nuget verify $(Build.ArtifactStagingDirectory)\*.nupkg' -# NOTE: Avoiding verifying with NuGetKeyVaultSignTool as it is rather faulty. Will give false positive for a file that doesn't exist. -# Use dotnet nuget verify instead -- task: PowerShell@2 - displayName: Verifying NuGetKeyVaultSign - inputs: - targetType: 'inline' - script: 'dotnet nuget verify $(Build.ArtifactStagingDirectory)\*.nupkg' + - task: PowerShell@2 + displayName: 'Publishing to $(nuget-server-url)' + condition: and(succeeded(), eq(${{parameters.PublishPackage}} , true)) + inputs: + targetType: 'inline' + script: 'dotnet nuget push $(Build.ArtifactStagingDirectory)\*.nupkg --api-key $(nuget-server-api-key) -n --source $(nuget-server-url)' -- task: PowerShell@2 - displayName: Publishing signed package - inputs: - targetType: 'inline' - script: 'dotnet nuget push $(Build.ArtifactStagingDirectory)\*.nupkg --api-key $(apiKey) -n --source $(nugetOrgSource)' \ No newline at end of file + - task: PublishPipelineArtifact@1 + displayName: Publish Signed Package + condition: succeeded() + inputs: + path: $(Build.ArtifactStagingDirectory) + artifact: mock-test-automation-solution \ No newline at end of file diff --git a/CHANGELOG.md b/CHANGELOG.md index 0fa93d8..64ecb41 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,13 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] +## [3.0.0] - 2025-03-19 +### Changed +- Fixed multiple build warnings to improve code quality and maintainability. + +### Removed +- Removed all OIDC Hybrid Flow related code and functionality. + ## [2.0.0] - 2024-08-06 ### Changed - Updated nuget package versions. diff --git a/SECURITY.md b/SECURITY.md index c83c5df..d49b8d6 100644 --- a/SECURITY.md +++ b/SECURITY.md @@ -11,7 +11,8 @@ Visit our [Responsible disclosure of security vulnerabilities policy](https://ww | Version | Supported | | ------- | ------------------ | -| 2.0.x | :white_check_mark: | +| 3.0.x | :white_check_mark: | +| 2.x.x | :x: | | 1.x.x | :x: | diff --git a/Source/.editorconfig b/Source/.editorconfig index c968c10..a8ceb60 100644 --- a/Source/.editorconfig +++ b/Source/.editorconfig @@ -256,3 +256,123 @@ tab_width = 4 indent_size = 4 end_of_line = crlf dotnet_style_prefer_is_null_check_over_reference_equality_method = true:suggestion + +[*.cs] +# complete the task associated to this 'TODO' +dotnet_diagnostic.S1135.severity = none + +# documentation missing for a parameter +dotnet_diagnostic.SA1611.severity = none + +# Filename should match first type name +dotnet_diagnostic.SA1649.severity = none + +# element parameter should have text +dotnet_diagnostic.SA1614.severity = none + +# enumeration elements should be documented +dotnet_diagnostic.SA1602.severity = none + +# partial elements should be documented +dotnet_diagnostic.SA1601.severity = none + +# elements should be documented +dotnet_diagnostic.SA1600.severity = none + +# file may only contain a single type +dotnet_diagnostic.SA1402.severity = none + +# The public modifier should appear before static +dotnet_diagnostic.SA1206.severity = none + +# static members should appear before non-static members +dotnet_diagnostic.SA1204.severity = none + +# public members should come before private +dotnet_diagnostic.SA1202.severity = none + +# a filed should not follow a property +dotnet_diagnostic.SA1201.severity = none + +# code should not contain blank lines at end +dotnet_diagnostic.SA1518.severity = none + +# closing brace should be followed by blank line +dotnet_diagnostic.SA1513.severity = none + +# element should not be on a single line +dotnet_diagnostic.SA1502.severity = none + +# use trailing comma in multi-line intializers +dotnet_diagnostic.SA1413.severity = none + +# variable should begin with lower case letter +dotnet_diagnostic.SA1312.severity = none + +# field should be private +dotnet_diagnostic.SA1401.severity = none + +# element should declare access modifier +dotnet_diagnostic.SA1400.severity = none + +# parameter should being with lower-case +dotnet_diagnostic.SA1313.severity = none + +# field should begin with upper case +dotnet_diagnostic.SA1307.severity = none + +# readonly fields should appear before non-readonly +dotnet_diagnostic.SA1214.severity = none + +# constant fields should appear before non-constant fields +dotnet_diagnostic.SA1203.severity = none + +# do not use regions +dotnet_diagnostic.SA1124.severity = none + +# generic type constraints should be on their own line +dotnet_diagnostic.SA1127.severity = none + +# use built-in type alias +dotnet_diagnostic.SA1121.severity = none + +# parameters should all be placed on the same line +dotnet_diagnostic.SA1117.severity = none + +# parameter spans multiple lines +dotnet_diagnostic.SA1118.severity = none + +# parameter should begin on the line after the previous parameter +dotnet_diagnostic.SA1115.severity = none + +# code should not contain trailing whitespace +dotnet_diagnostic.SA1028.severity = none + +# closing square bracket should be followed by a space +dotnet_diagnostic.SA1011.severity = none + +# keyword new should be followed by a space +dotnet_diagnostic.SA1000.severity = none + +# opening square brackets should not be preceded by a space +dotnet_diagnostic.SA1010.severity = none + +[DataRecipientConsentCallback*.cs] +# remove the unused private method +dotnet_diagnostic.S1144.severity = none + +[JwksEndpoint.cs] +# remove the unused private method +dotnet_diagnostic.S1144.severity = none + +[Test*.cs] +# Missing xml comment for publicly visible type +dotnet_diagnostic.CS1591.severity = none + +[RegisterSSAService.cs] +# remove this useless conditional +dotnet_diagnostic.S3440.severity = none + +[DateTimeExtensions.cs] +# use string.Empty for empty strings +dotnet_diagnostic.SA1122.severity = none \ No newline at end of file diff --git a/Source/ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation.UnitTests/ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation.UnitTests.csproj b/Source/ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation.UnitTests/ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation.UnitTests.csproj index b667bb6..a4b21c0 100644 --- a/Source/ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation.UnitTests/ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation.UnitTests.csproj +++ b/Source/ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation.UnitTests/ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation.UnitTests.csproj @@ -5,6 +5,7 @@ enable false true + True @@ -17,6 +18,14 @@ runtime; build; native; contentfiles; analyzers; buildtransitive + + all + runtime; build; native; contentfiles; analyzers; buildtransitive + + + all + runtime; build; native; contentfiles; analyzers; buildtransitive + all diff --git a/Source/ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation.UnitTests/Tests/TestClass1.cs b/Source/ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation.UnitTests/Tests/TestClass1.cs index 10a5240..bd1344c 100644 --- a/Source/ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation.UnitTests/Tests/TestClass1.cs +++ b/Source/ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation.UnitTests/Tests/TestClass1.cs @@ -9,8 +9,11 @@ public class TestClass1 { public class Startup { - //A default startup is required due to the test project inheriting Xunit.DependencyInjection from the Nuget project. - public void ConfigureServices(IServiceCollection services) { } + // A default startup is required due to the test project inheriting Xunit.DependencyInjection from the Nuget project. + public void ConfigureServices(IServiceCollection services) + { + // Method intentionally left empty. + } } [Fact] diff --git a/Source/ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation.sln b/Source/ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation.sln index a82f242..b0f1782 100644 --- a/Source/ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation.sln +++ b/Source/ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation.sln @@ -5,6 +5,8 @@ VisualStudioVersion = 17.6.33815.320 MinimumVisualStudioVersion = 10.0.40219.1 Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{5EB0C4E7-3595-403D-A2EB-481BC66E3B0E}" ProjectSection(SolutionItems) = preProject + .editorconfig = .editorconfig + Directory.Build.props = Directory.Build.props ..\README.md = ..\README.md EndProjectSection EndProject diff --git a/Source/ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation/Assertions.cs b/Source/ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation/Assertions.cs index e659b13..5c8862b 100644 --- a/Source/ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation/Assertions.cs +++ b/Source/ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation/Assertions.cs @@ -1,24 +1,24 @@ -using System.Net.Http.Headers; -using System.Security.Claims; -using ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation.Exceptions; -using ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation.Extensions; -using ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation.Models; -using FluentAssertions; -using Newtonsoft.Json; - -namespace ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation +namespace ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation { + using System.Net.Http.Headers; + using System.Security.Claims; + using ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation.Exceptions; + using ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation.Extensions; + using ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation.Models; + using FluentAssertions; + using Newtonsoft.Json; + public static class Assertions { - /// - /// Assert response content and expectedJson are equivalent + /// Assert response content and expectedJson are equivalent. /// - /// The expected json - /// The response content + /// The expected json. + /// The response content. + /// Task representing the asynchronous operation. public static async Task AssertHasContentJson(string? expectedJson, HttpContent? content) { - content.Should().NotBeNull(expectedJson ?? ""); + content.Should().NotBeNull(expectedJson ?? string.Empty); if (content == null) { return; @@ -30,7 +30,7 @@ public static async Task AssertHasContentJson(string? expectedJson, HttpContent? public static async Task AssertHasContentJson(string? expectedJson, HttpContent? content) { - content.Should().NotBeNull(expectedJson ?? ""); + content.Should().NotBeNull(expectedJson ?? string.Empty); if (content == null) { return; @@ -41,10 +41,11 @@ public static async Task AssertHasContentJson(string? expectedJson, HttpConte } /// - /// Assert response content is empty + /// Assert response content is empty. /// - /// The response content - /// Reason the assertion is needed + /// The response content. + /// Reason the assertion is needed. + /// Task representing the asynchronous operation. public static async Task AssertHasNoContent(HttpContent? content, string? because = null) { content.Should().NotBeNull(); @@ -58,10 +59,10 @@ public static async Task AssertHasNoContent(HttpContent? content, string? becaus } /// - /// Assert_HasNoContent because "No detail about response content in AC, check that API does not actually return any response content" + /// Assert_HasNoContent because "No detail about response content in AC, check that API does not actually return any response content". /// /// - /// + /// Task. public static async Task AssertHasNoContent2(HttpContent? content) { // Assert - No detail about response content in AC, check that API does not actually return any response content @@ -69,13 +70,13 @@ public static async Task AssertHasNoContent2(HttpContent? content) } /// - /// Assert actual json is equivalent to expected json + /// Assert actual json is equivalent to expected json. /// - /// The expected json - /// The actual json + /// The expected json. + /// The actual json. public static void AssertJson(string? expectedJson, string actualJson) { - AssertJson(expectedJson, actualJson); + AssertJson(expectedJson, actualJson); } public static void AssertJson(string? expectedJson, string actualJson) @@ -95,14 +96,13 @@ public static void AssertJson(string? expectedJson, string actualJson) var actualJsonNormalised = JsonConvert.SerializeObject(actualObject); actualJson?.JsonCompare(expectedJson).Should().BeTrue( - $"\r\nExpected json:\r\n{expectedJsonNormalised}\r\nActual Json:\r\n{actualJsonNormalised}\r\n" - ); + $"\r\nExpected json:\r\n{expectedJsonNormalised}\r\nActual Json:\r\n{actualJsonNormalised}\r\n"); } private static bool AssertIsJsonNullOrEmpty(string? expectedJson, string actualJson) { expectedJson.Should().NotBeNullOrEmpty(); - actualJson.Should().NotBeNullOrEmpty(expectedJson == null ? "" : $"expected {expectedJson}"); + actualJson.Should().NotBeNullOrEmpty(expectedJson == null ? string.Empty : $"expected {expectedJson}"); if (string.IsNullOrEmpty(expectedJson) || string.IsNullOrEmpty(actualJson)) { @@ -114,12 +114,12 @@ private static bool AssertIsJsonNullOrEmpty(string? expectedJson, string actualJ /// /// Assert headers has a single header with the expected value. - /// If expectedValue then just check for the existence of the header (and not it's value) + /// If expectedValue then just check for the existence of the header (and not it's value). /// - /// The expected header value - /// The headers to check - /// Name of header to check - /// Whether the header just needs to start with the expected value (opposed to matching exactly) + /// The expected header value. + /// The headers to check. + /// Name of header to check. + /// Whether the header just needs to start with the expected value (opposed to matching exactly). public static void AssertHasHeader(string? expectedValue, HttpHeaders headers, string name, bool startsWith = false) { headers.Should().NotBeNull(); @@ -149,7 +149,7 @@ public static void AssertHasHeader(string? expectedValue, HttpHeaders headers, s } /// - /// Assert header has content type of ApplicationJson + /// Assert header has content type of ApplicationJson. /// /// public static void AssertHasContentTypeApplicationJson(HttpContent content) @@ -161,7 +161,7 @@ public static void AssertHasContentTypeApplicationJson(HttpContent content) } /// - /// Assert claim exists + /// Assert claim exists. /// public static void AssertClaim(IEnumerable claims, string claimType, string claimValue) { @@ -188,6 +188,7 @@ public static async Task AssertErrorAsync(HttpResponseMessage responseMessage, A receivedError.Code.Should().Be(expectedError.Error); } } + public static async Task AssertErrorAsync(HttpResponseMessage responseMessage, CdrException expectedError) { responseMessage.StatusCode.Should().Be(expectedError.StatusCode); diff --git a/Source/ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation/Attributes/DisplayTestMethodNameAttribute.cs b/Source/ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation/Attributes/DisplayTestMethodNameAttribute.cs index e05cd41..8d9224d 100644 --- a/Source/ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation/Attributes/DisplayTestMethodNameAttribute.cs +++ b/Source/ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation/Attributes/DisplayTestMethodNameAttribute.cs @@ -1,9 +1,10 @@ -using System.Reflection; -using Serilog; -using Xunit.Sdk; - -namespace ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation.Attributes +namespace ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation.Attributes { + using System.Reflection; + using Serilog; + using Xunit.Sdk; + + [System.AttributeUsage(System.AttributeTargets.Class, Inherited = true)] public class DisplayTestMethodNameAttribute : BeforeAfterTestAttribute { private int _count = 0; diff --git a/Source/ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation/AuthoriseURLBuilder.cs b/Source/ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation/AuthoriseURLBuilder.cs index 28347c6..bf13c4c 100644 --- a/Source/ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation/AuthoriseURLBuilder.cs +++ b/Source/ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation/AuthoriseURLBuilder.cs @@ -7,29 +7,36 @@ namespace ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation.APIs { /// - /// Url for Authorise endpoint + /// Url for Authorise endpoint. /// public class AuthoriseUrl { public string ClientId { get; private set; } + public string RedirectURI { get; private set; } + public string JwtCertificateFilename { get; private set; } = Constants.Certificates.JwtCertificateFilename; + public string JwtCertificatePassword { get; private set; } = Constants.Certificates.JwtCertificatePassword; + public string Scope { get; private set; } + public string ResponseType { get; private set; } + public string? Request { get; private set; } = null; // use this as the request, rather than build request + public string? RequestUri { get; private set; } = null; public string Url { get; private set; } /// - /// Lifetime (in seconds) of the access token. It has to be less than 60 mins + /// Lifetime (in seconds) of the access token. It has to be less than 60 mins. /// public int TokenLifetime { get; private set; } = Constants.AuthServer.DefaultTokenLifetime; /// /// Lifetime (in seconds) of the CDR arrangement. - /// 7776000 = 90 days + /// 7776000 = 90 days. /// public int? SharingDuration { get; private set; } = Constants.AuthServer.SharingDuration; @@ -49,36 +56,43 @@ public AuthoriseUrlBuilder WithClientId(string value) _authoriseUrl.ClientId = value; return this; } + public AuthoriseUrlBuilder WithRedirectURI(string value) { _authoriseUrl.RedirectURI = value; return this; } + public AuthoriseUrlBuilder WithJWTCertificateFilename(string value) { _authoriseUrl.JwtCertificateFilename = value; return this; } + public AuthoriseUrlBuilder WithJWTCertificatePassword(string value) { _authoriseUrl.JwtCertificatePassword = value; return this; } + public AuthoriseUrlBuilder WithScope(string value) { _authoriseUrl.Scope = value; return this; } + public AuthoriseUrlBuilder WithResponseType(string value) { _authoriseUrl.ResponseType = value; return this; } + public AuthoriseUrlBuilder WithRequest(string value) { _authoriseUrl.Request = value; return this; } + public AuthoriseUrlBuilder WithRequestUri(string? value) { _authoriseUrl.RequestUri = value; @@ -124,9 +138,9 @@ private void FillMissingDefaults() { Log.Information("Filling missing defaults for public properties"); - var _options = _authoriseUrl.TestAutomationOptions; //purely to shorten reference + var _options = _authoriseUrl.TestAutomationOptions; // purely to shorten reference - //Anything that doesn't have a value which should...will get it's default value set + // Anything that doesn't have a value which should...will get it's default value set if (_authoriseUrl.Scope.IsNullOrWhiteSpace()) { _authoriseUrl.Scope = _options.SCOPE; @@ -161,15 +175,20 @@ private string CreateRequest() { "scope", _authoriseUrl.Scope }, { "state", "foo" }, { "nonce", "foo" }, - { "claims", new { + { + "claims", new + { sharing_duration = _authoriseUrl.SharingDuration.ToString(), - id_token = new { - acr = new { + id_token = new + { + acr = new + { essential = true, values = new string[] { "urn:cds.au:cdr:2" } } } - }} + } + } }; return Helpers.Jwt.CreateJWT(_authoriseUrl.JwtCertificateFilename, _authoriseUrl.JwtCertificatePassword, subject); diff --git a/Source/ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation/Constants.cs b/Source/ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation/Constants.cs index a29c929..1338f1e 100644 --- a/Source/ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation/Constants.cs +++ b/Source/ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation/Constants.cs @@ -30,21 +30,21 @@ public static class AuthServer } /// - /// User/Customer IDs used for testing. Industry specific users are in an industry sub-class whereas the rest are at the first level + /// User/Customer IDs used for testing. Industry specific users are in an industry sub-class whereas the rest are at the first level. /// public static class Users { /// - /// Banking-specific Users + /// Banking-specific Users. /// public static class Banking { - public const string UserIdJaneWilson = "jwilson"; //Banking customer - public const string CustomerIdJaneWilson = "bfb689fb-7745-45b9-bbaa-b21e00072447";//Banking customer + public const string UserIdJaneWilson = "jwilson"; // Banking customer + public const string CustomerIdJaneWilson = "bfb689fb-7745-45b9-bbaa-b21e00072447"; // Banking customer } /// - /// Energy-specific Users + /// Energy-specific Users. /// public static class Energy { @@ -66,16 +66,16 @@ public static class Energy public static class Accounts { /// - /// Banking-specific Accounts + /// Banking-specific Accounts. /// public static class Banking { public const string AccountIdJaneWilson = "98765988"; - public const string AccountIdsAllJaneWilson = "98765988,98765987"; //Banking customer + public const string AccountIdsAllJaneWilson = "98765988,98765987"; // Banking customer } /// - /// Energy-specific Accounts + /// Energy-specific Accounts. /// public static class Energy { @@ -85,7 +85,6 @@ public static class Energy public const string AccountIdsAllHeddaHare = "4ee1a8db-13af-44d7-b54b-e94dff3df548"; // Energy customer } - public const string AccountIdJohnSmith = "1122334455"; public const string AccountIdKamillaSmith = "0000001"; @@ -140,7 +139,6 @@ public static class AccessTokens @"tUQhX0-IqUzdVsdTf2t9DNva2VRkK9Cdf2kCtqs17NGDlWceQ7IKR-U6qn9izNOYeM47Qhqa6MiROtrfe5Ja3p8vjnN72eEQ_XPd2bMVxkbyh0IrG9-5JCOolbjjnbZaxh4dIggfdY52JS" + @"2-DLYhQnMnJtrVkKe1J212x8SVf7FKcNGY0OM4MLG3Gcl5S8EzQQuh464Nr-rPnec7SbrqjQ2xyn56s4Nhv5PfQ-VOqPQXOkyBPzH"; - // VSCode slows on excessively long lines, splitting string constant into smaller lines. public const string ConsumerAccessTokenBankingExpired = @"eyJhbGciOiJQUzI1NiIsImtpZCI6IjdDNTcxNjU1M0U5QjEzMkVGMzI1QzQ5Q0EyMDc5NzM3MTk2QzAzREIiLCJ4NXQiOiJmRmNXVlQ2YkV5N3pKY1Njb2dlWE54bHNBOXMiLCJ0eXAiOiJhdCtqd3QifQ.eyJuYmYiOjE2NTI2ODM2NDksImV4cCI6MTY1MjY4NzI0OSwiaXNzIjoiaHR0cHM6Ly9tb2NrLWRh" + @@ -219,11 +217,11 @@ public static class SoftwareProducts public static class Scopes { - // Scope - public const string ScopeBanking = "openid profile common:customer.basic:read bank:accounts.basic:read bank:transactions:read"; //Also used by Auth Server - public const string ScopeBankingWithoutOpenId = "profile common:customer.basic:read bank:accounts.basic:read bank:transactions:read"; //Also used by Auth Server + // Scope + public const string ScopeBanking = "openid profile common:customer.basic:read bank:accounts.basic:read bank:transactions:read"; // Also used by Auth Server + public const string ScopeBankingWithoutOpenId = "profile common:customer.basic:read bank:accounts.basic:read bank:transactions:read"; // Also used by Auth Server public const string ScopeEnergy = "openid profile common:customer.basic:read energy:accounts.basic:read energy:accounts.concessions:read"; // scope of 'energy:accounts.concessions:read' is not working? - public const string ScopeEnergyWithoutOpenId = "profile common:customer.basic:read energy:accounts.basic:read energy:accounts.concessions:read"; // scope of 'energy:accounts.concessions:read' is not working?; + public const string ScopeEnergyWithoutOpenId = "profile common:customer.basic:read energy:accounts.basic:read energy:accounts.concessions:read"; // energy:accounts.concessions:read is not working? public const string ScopeRegistration = "cdr:registration"; } @@ -258,7 +256,7 @@ public static class Authorization { public const string AuthorizationHolderOfKeyCheckFailed = "ERR-AUTH-001: Holder of Key check failed"; public const string AuthorizationAccessTokenExpired = "ERR-AUTH-002: Access Token check failed - it has been revoked"; - public const string AuthorizationInsufficientScope = "ERR-AUTH-003: Insufficent scope"; //This doesn't match the one in AuthServer because it had no additional text + public const string AuthorizationInsufficientScope = "ERR-AUTH-003: Insufficent scope"; // This doesn't match the one in AuthServer because it had no additional text public const string RequestUriClientIdMismatch = "ERR-AUTH-0004: client_id does not match request_uri client_id"; public const string RequestUriAlreadyUsed = "ERR-AUTH-005: request_uri has already been used"; public const string ExpiredRequestUri = "ERR-AUTH-006: request_uri has expired"; @@ -283,6 +281,7 @@ public static class CdrArrangement { public const string InvalidConsentCdrArrangement = "ERR-ARR-001: Invalid Consent Arrangement"; } + public static class Jwt { public const string JwtInvalidAudience = "ERR-JWT-001: {0} - Invalid audience"; @@ -301,6 +300,7 @@ public static class Dcr public const string SoftwareStatementEmptyOrInvalid = "ERR-DCR-006: The software_statement is empty or invalid"; public const string InvalidSectorIdentifierUri = "ERR-DCR-007: Invalid sector_identifier_uri"; } + public static class Token { public const string ExpiredRefreshToken = "ERR-TKN-001: refresh_token has expired"; @@ -311,6 +311,7 @@ public static class Token public const string MissingCodeVerifier = "ERR-TKN-006: code_verifier is missing"; public const string InvalidAuthorizationCode = "ERR-TKN-007: authorization code is invalid"; } + public static class General { public const string SoftwareProductNotFound = "ERR-GEN-001: Software product not found"; @@ -325,7 +326,7 @@ public static class General public const string ResponseTypeMismatchRequestUriResponseType = "ERR-GEN-010: response_type does not match request_uri response_type"; public const string MissingScope = "ERR-GEN-011: scope is missing"; public const string MissingOpenIdScope = "ERR-GEN-012: openid scope is missing"; - public const string UnsupportedResponseMode = "ERR-GEN-013: response_mode is not supported"; //This was INVALID_RESPONSE_MODE in auth server + public const string UnsupportedResponseMode = "ERR-GEN-013: response_mode is not supported"; // This was INVALID_RESPONSE_MODE in auth server public const string GrantTypeNotProvided = "ERR-GEN-014: grant_type not provided"; public const string UnsupportedGrantType = "ERR-GEN-015: unsupported grant_type"; public const string MissingIssuerClaim = "ERR-GEN-016: Missing iss claim"; diff --git a/Source/ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation/ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation.csproj b/Source/ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation/ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation.csproj index cee989b..cf9ccbd 100644 --- a/Source/ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation/ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation.csproj +++ b/Source/ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation/ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation.csproj @@ -82,13 +82,21 @@ + + all + runtime; build; native; contentfiles; analyzers; buildtransitive + + + all + runtime; build; native; contentfiles; analyzers; buildtransitive + - + $(PackageVersion)+$(MinVerBuildMetadata) $(PackageVersion) diff --git a/Source/ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation/DataRecipientConsentCallback.cs b/Source/ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation/DataRecipientConsentCallback.cs index bbd818e..4bc2fd9 100644 --- a/Source/ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation/DataRecipientConsentCallback.cs +++ b/Source/ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation/DataRecipientConsentCallback.cs @@ -1,11 +1,11 @@ -using Microsoft.AspNetCore.Builder; -using Microsoft.AspNetCore.Hosting; -using Microsoft.Extensions.DependencyInjection; -using Microsoft.Extensions.Hosting; -using Serilog; - namespace ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation { + using Microsoft.AspNetCore.Builder; + using Microsoft.AspNetCore.Hosting; + using Microsoft.Extensions.DependencyInjection; + using Microsoft.Extensions.Hosting; + using Serilog; + public class DataRecipientConsentCallback { public DataRecipientConsentCallback(string redirectUrl) @@ -14,11 +14,12 @@ public DataRecipientConsentCallback(string redirectUrl) Request = new CallbackRequest { - PathAndQuery = new Uri(redirectUrl).PathAndQuery + PathAndQuery = new Uri(redirectUrl).PathAndQuery, }; } public string RedirectUrl { get; init; } + private string RedirectUrlLeftPart => new Uri(RedirectUrl).GetLeftPart(UriPartial.Authority); private IWebHost? _host; @@ -26,15 +27,17 @@ public DataRecipientConsentCallback(string redirectUrl) public class CallbackRequest { public string? PathAndQuery { get; init; } + public bool received = false; public HttpMethod? method; public string? body; public string? queryString; } + private CallbackRequest Request { get; init; } /// - /// Start web host + /// Start web host. /// public void Start() { @@ -51,8 +54,9 @@ public void Start() } /// - /// Stop web host + /// Stop web host. /// + /// Task representing the asynchronous operation. public async Task Stop() { Log.Information(Constants.LogTemplates.StartedFunctionInClass, nameof(Stop), nameof(DataRecipientConsentCallback)); @@ -64,8 +68,9 @@ public async Task Stop() } /// - /// Wait until we get a callback or otherwise timeout + /// Wait until we get a callback or otherwise timeout. /// + /// Task representing the asynchronous operation. public async Task WaitForCallback(int timeoutSeconds = 30) { Log.Information(Constants.LogTemplates.StartedFunctionInClass, nameof(WaitForCallback), nameof(DataRecipientConsentCallback)); diff --git a/Source/ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation/Enums/CdsErrors.cs b/Source/ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation/Enums/CdsErrors.cs index 2f98e70..cd43a55 100644 --- a/Source/ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation/Enums/CdsErrors.cs +++ b/Source/ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation/Enums/CdsErrors.cs @@ -1,7 +1,7 @@ -using ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation.Models; - -namespace ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation.Enums +namespace ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation.Enums { + using ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation.Models; + public enum CdsError { [CdrError("Expected Error Encountered", "urn:au-cds:error:cds-all:GeneralError/Expected")] @@ -73,7 +73,7 @@ public enum CdsError [CdrError("Invalid Software Product", "urn:au-cds:error:cds-register:Field/InvalidSoftwareProduct")] InvalidSoftwareProduct, - [CdrError("Invalid Energy Account","urn:au-cds:error:cds-energy:Authorisation/InvalidEnergyAccount")] + [CdrError("Invalid Energy Account", "urn:au-cds:error:cds-energy:Authorisation/InvalidEnergyAccount")] InvalidEnergyAccount, [CdrError("Invalid Banking Account", "urn:au-cds:error:cds-banking:Authorisation/InvalidBankingAccount")] diff --git a/Source/ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation/Enums/EntityType.cs b/Source/ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation/Enums/EntityType.cs index 75b7bd8..3a96d16 100644 --- a/Source/ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation/Enums/EntityType.cs +++ b/Source/ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation/Enums/EntityType.cs @@ -1,4 +1,9 @@ namespace ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation.Enums { - public enum EntityType { SOFTWAREPRODUCT, LEGALENTITY, BRAND } + public enum EntityType + { + SOFTWAREPRODUCT, + LEGALENTITY, + BRAND, + } } diff --git a/Source/ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation/Enums/Industry.cs b/Source/ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation/Enums/Industry.cs index dca173b..851fb7c 100644 --- a/Source/ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation/Enums/Industry.cs +++ b/Source/ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation/Enums/Industry.cs @@ -1,8 +1,8 @@ -using System.Runtime.Serialization; -using System.Text.Json.Serialization; - -namespace ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation.Enums +namespace ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation.Enums { + using System.Runtime.Serialization; + using System.Text.Json.Serialization; + [JsonConverter(typeof(JsonStringEnumConverter))] public enum Industry { diff --git a/Source/ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation/Enums/LegalEntityStatus.cs b/Source/ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation/Enums/LegalEntityStatus.cs index 437bb6b..07d7d56 100644 --- a/Source/ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation/Enums/LegalEntityStatus.cs +++ b/Source/ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation/Enums/LegalEntityStatus.cs @@ -1,7 +1,7 @@ -using System.Runtime.Serialization; - -namespace ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation.Enums +namespace ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation.Enums { + using System.Runtime.Serialization; + public enum LegalEntityStatus { [EnumMember(Value = "ACTIVE")] @@ -9,6 +9,6 @@ public enum LegalEntityStatus [EnumMember(Value = "INACTIVE")] INACTIVE, [EnumMember(Value = "REMOVED")] - REMOVED + REMOVED, } } diff --git a/Source/ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation/Enums/ResponseMode.cs b/Source/ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation/Enums/ResponseMode.cs index 7c211de..9d8efcf 100644 --- a/Source/ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation/Enums/ResponseMode.cs +++ b/Source/ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation/Enums/ResponseMode.cs @@ -1,11 +1,15 @@ -using System.Runtime.Serialization; -using System.Text.Json.Serialization; - -namespace ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation.Enums +namespace ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation.Enums { + using System.Runtime.Serialization; + using System.Text.Json.Serialization; + [JsonConverter(typeof(JsonStringEnumConverter))] public enum ResponseMode { + [EnumMember(Value = "jwt")] + Jwt, + + // Invalid values used for testing [EnumMember(Value = "form_post")] FormPost, @@ -14,8 +18,7 @@ public enum ResponseMode [EnumMember(Value = "query")] Query, - [EnumMember(Value = "jwt")] - Jwt, + [EnumMember(Value = "form_post.jwt")] FormPostJwt, @@ -25,7 +28,7 @@ public enum ResponseMode [EnumMember(Value = "query.jwt")] QueryJwt, - [EnumMember(Value = "foo")] //Nonsense value used for testing - TestOnlyFoo + [EnumMember(Value = "foo")] + TestOnlyFoo, } } diff --git a/Source/ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation/Enums/ResponseType.cs b/Source/ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation/Enums/ResponseType.cs index 0d3405f..a78e428 100644 --- a/Source/ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation/Enums/ResponseType.cs +++ b/Source/ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation/Enums/ResponseType.cs @@ -1,17 +1,17 @@ -using System.Runtime.Serialization; -using System.Text.Json.Serialization; - -namespace ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation.Enums +namespace ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation.Enums { + using System.Runtime.Serialization; + using System.Text.Json.Serialization; + [JsonConverter(typeof(JsonStringEnumConverter))] public enum ResponseType { - [EnumMember(Value = "code id_token")] - CodeIdToken, [EnumMember(Value = "code")] Code, - //Nonsense values used for testing + // Invalid values used for testing + [EnumMember(Value = "code id_token")] + CodeIdToken, [EnumMember(Value = "Foo")] TestOnlyFoo, [EnumMember(Value = "token")] diff --git a/Source/ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation/Enums/SoftwareProductStatus.cs b/Source/ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation/Enums/SoftwareProductStatus.cs index 0ea40a6..fd2f083 100644 --- a/Source/ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation/Enums/SoftwareProductStatus.cs +++ b/Source/ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation/Enums/SoftwareProductStatus.cs @@ -1,7 +1,7 @@ -using System.Runtime.Serialization; - -namespace ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation.Enums +namespace ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation.Enums { + using System.Runtime.Serialization; + public enum SoftwareProductStatus { [EnumMember(Value = "ACTIVE")] @@ -9,6 +9,6 @@ public enum SoftwareProductStatus [EnumMember(Value = "INACTIVE")] INACTIVE, [EnumMember(Value = "REMOVED")] - REMOVED + REMOVED, } } diff --git a/Source/ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation/Enums/Status.cs b/Source/ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation/Enums/Status.cs index b85906f..f07b0aa 100644 --- a/Source/ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation/Enums/Status.cs +++ b/Source/ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation/Enums/Status.cs @@ -1,4 +1,9 @@ namespace ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation.Enums { - public enum Status { STATUS, LEGALENTITYSTATUS, BRANDSTATUS } //STATUS - SoftwareProduct Status, rest of the status as name implies + public enum Status + { + STATUS, + LEGALENTITYSTATUS, + BRANDSTATUS, + } // STATUS - SoftwareProduct Status, rest of the status as name implies } diff --git a/Source/ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation/Enums/TokenType.cs b/Source/ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation/Enums/TokenType.cs index 544f5a6..188a734 100644 --- a/Source/ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation/Enums/TokenType.cs +++ b/Source/ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation/Enums/TokenType.cs @@ -6,15 +6,25 @@ public enum TokenType /// Used for energy /// MaryMoss, + /// /// Used for energy /// - HeddaHare,//used for energy + HeddaHare, // used for energy + /// /// Used for banking /// - JaneWilson, + JaneWilson, - SteveKennedy, DewayneSteve, Business1, Beverage, InvalidFoo, InvalidEmpty, InvalidOmit, KamillaSmith, Business2 + SteveKennedy, + DewayneSteve, + Business1, + Beverage, + InvalidFoo, + InvalidEmpty, + InvalidOmit, + KamillaSmith, + Business2, } } diff --git a/Source/ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation/Exceptions/AuthoriseException.cs b/Source/ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation/Exceptions/AuthoriseException.cs index d309201..b15143b 100644 --- a/Source/ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation/Exceptions/AuthoriseException.cs +++ b/Source/ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation/Exceptions/AuthoriseException.cs @@ -1,8 +1,8 @@ -using System.Net; -using Newtonsoft.Json; - -namespace ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation.Exceptions +namespace ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation.Exceptions { + using System.Net; + using Newtonsoft.Json; + public class AuthoriseException : Exception { public HttpStatusCode StatusCode { get; } @@ -13,13 +13,19 @@ public class AuthoriseException : Exception [JsonProperty("error_description")] public string ErrorDescription { get; } - public AuthoriseException() { } + public AuthoriseException() + { + } public AuthoriseException(string message) - : base(message) { } + : base(message) + { + } public AuthoriseException(string message, Exception inner) - : base(message, inner) { } + : base(message, inner) + { + } public AuthoriseException(string message, HttpStatusCode statusCode, string error, string errorDescription) : this(message) @@ -27,6 +33,6 @@ public AuthoriseException(string message, HttpStatusCode statusCode, string erro StatusCode = statusCode; Error = error; ErrorDescription = errorDescription; - } + } } } diff --git a/Source/ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation/Exceptions/AuthoriseExceptions/InvalidClientException.cs b/Source/ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation/Exceptions/AuthoriseExceptions/InvalidClientException.cs index 81774df..6e0854e 100644 --- a/Source/ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation/Exceptions/AuthoriseExceptions/InvalidClientException.cs +++ b/Source/ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation/Exceptions/AuthoriseExceptions/InvalidClientException.cs @@ -8,66 +8,87 @@ public class InvalidClientException : AuthoriseException /// public InvalidClientException(string detail) : base(string.Empty, System.Net.HttpStatusCode.BadRequest, "invalid_client", detail) - { } + { + } } public class ClientNotFoundException : InvalidClientException { - public ClientNotFoundException() : base(Constants.ErrorMessages.General.ClientNotFound) - { } + public ClientNotFoundException() + : base(Constants.ErrorMessages.General.ClientNotFound) + { + } } public class MissingClientAssertionException : InvalidClientException { - public MissingClientAssertionException() : base(Constants.ErrorMessages.General.ClientAssertionNotProvided) - { } + public MissingClientAssertionException() + : base(Constants.ErrorMessages.General.ClientAssertionNotProvided) + { + } } public class MissingClientAssertionTypeException : InvalidClientException { - public MissingClientAssertionTypeException() : base(Constants.ErrorMessages.ClientAssertion.ClientAssertionTypeNotProvided) - { } + public MissingClientAssertionTypeException() + : base(Constants.ErrorMessages.ClientAssertion.ClientAssertionTypeNotProvided) + { + } } public class InvalidClientAssertionTypeException : InvalidClientException { - public InvalidClientAssertionTypeException() : base(Constants.ErrorMessages.ClientAssertion.InvalidClientAssertionType) - { } + public InvalidClientAssertionTypeException() + : base(Constants.ErrorMessages.ClientAssertion.InvalidClientAssertionType) + { + } } public class InvalidClientAssertionFormatException : InvalidClientException { - public InvalidClientAssertionFormatException() : base(Constants.ErrorMessages.ClientAssertion.ClientAssertionInvalidFormat) - { } + public InvalidClientAssertionFormatException() + : base(Constants.ErrorMessages.ClientAssertion.ClientAssertionInvalidFormat) + { + } } public class MissingIssClaimException : InvalidClientException { - public MissingIssClaimException() : base(Constants.ErrorMessages.ClientAssertion.ClientAssertionMissingIssClaim) - { } + public MissingIssClaimException() + : base(Constants.ErrorMessages.ClientAssertion.ClientAssertionMissingIssClaim) + { + } } public class MissingJtiException : InvalidClientException { - public MissingJtiException() : base(Constants.ErrorMessages.General.JtiRequired) - { } + public MissingJtiException() + : base(Constants.ErrorMessages.General.JtiRequired) + { + } } public class TokenValidationClientAssertionException : InvalidClientException { - public TokenValidationClientAssertionException() : base(Constants.ErrorMessages.Jwt.JwtValidationErro.Replace("{0}","client_assertion")) - { } + public TokenValidationClientAssertionException() + : base(Constants.ErrorMessages.Jwt.JwtValidationErro.Replace("{0}", "client_assertion")) + { + } } public class InvalidAudienceException : InvalidClientException { - public InvalidAudienceException() : base(Constants.ErrorMessages.Jwt.JwtInvalidAudience.Replace("{0}", "client_assertion")) - { } + public InvalidAudienceException() + : base(Constants.ErrorMessages.Jwt.JwtInvalidAudience.Replace("{0}", "client_assertion")) + { + } } public class ExpiredClientAssertionException : InvalidClientException { - public ExpiredClientAssertionException() : base(Constants.ErrorMessages.Jwt.JwtExpired.Replace("{0}", "client_assertion")) - { } + public ExpiredClientAssertionException() + : base(Constants.ErrorMessages.Jwt.JwtExpired.Replace("{0}", "client_assertion")) + { + } } } diff --git a/Source/ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation/Exceptions/AuthoriseExceptions/InvalidClientMetadataException.cs b/Source/ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation/Exceptions/AuthoriseExceptions/InvalidClientMetadataException.cs index 8bb4657..db4ff87 100644 --- a/Source/ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation/Exceptions/AuthoriseExceptions/InvalidClientMetadataException.cs +++ b/Source/ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation/Exceptions/AuthoriseExceptions/InvalidClientMetadataException.cs @@ -8,40 +8,47 @@ public class InvalidClientMetadataException : AuthoriseException /// public InvalidClientMetadataException(string detail) : base(string.Empty, System.Net.HttpStatusCode.BadRequest, "invalid_client_metadata", detail) - { } + { + } } public class AuthorizationSignedResponseAlgClaimInvalidException : InvalidClientMetadataException { - public AuthorizationSignedResponseAlgClaimInvalidException() : base("The 'authorization_signed_response_alg' claim value must be one of 'PS256,ES256'.")//TODO: Should a error gen code and add to constants. Bug 64146 - { } + public AuthorizationSignedResponseAlgClaimInvalidException() + : base("The 'authorization_signed_response_alg' claim value must be one of 'PS256,ES256'.") // TODO: Should a error gen code and add to constants. Bug 64146 + { + } } public class AuthorizationSignedResponseAlgClaimMissingException : InvalidClientMetadataException { - public AuthorizationSignedResponseAlgClaimMissingException() : base("The 'authorization_signed_response_alg' claim is missing.")//TODO: Should a error gen code and add to constants. Bug 64146 - { } - + public AuthorizationSignedResponseAlgClaimMissingException() + : base("The 'authorization_signed_response_alg' claim is missing.") // TODO: Should a error gen code and add to constants. Bug 64146 + { + } } public class TokenEndpointAuthSigningAlgClaimInvalidException : InvalidClientMetadataException { - public TokenEndpointAuthSigningAlgClaimInvalidException() : base("The 'token_endpoint_auth_signing_alg' claim value must be one of 'PS256,ES256'.")//TODO: Should a error gen code and add to constants. Bug 64146 - { } - + public TokenEndpointAuthSigningAlgClaimInvalidException() + : base("The 'token_endpoint_auth_signing_alg' claim value must be one of 'PS256,ES256'.") // TODO: Should a error gen code and add to constants. Bug 64146 + { + } } public class DuplicateRegistrationForSoftwareIdException : InvalidClientMetadataException { - public DuplicateRegistrationForSoftwareIdException() : base(Constants.ErrorMessages.Dcr.DuplicateRegistration) - { } - + public DuplicateRegistrationForSoftwareIdException() + : base(Constants.ErrorMessages.Dcr.DuplicateRegistration) + { + } } public class GrantTypesMissingAuthorizationCodeException : InvalidClientMetadataException { - public GrantTypesMissingAuthorizationCodeException() : base("The 'grant_types' claim value must contain the 'authorization_code' value.")//TODO: Should a error gen code and add to constants. Bug 64146 - { } - + public GrantTypesMissingAuthorizationCodeException() + : base("The 'grant_types' claim value must contain the 'authorization_code' value.") // TODO: Should a error gen code and add to constants. Bug 64146 + { + } } } diff --git a/Source/ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation/Exceptions/AuthoriseExceptions/InvalidGrantException.cs b/Source/ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation/Exceptions/AuthoriseExceptions/InvalidGrantException.cs index 149af63..f80a3f3 100644 --- a/Source/ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation/Exceptions/AuthoriseExceptions/InvalidGrantException.cs +++ b/Source/ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation/Exceptions/AuthoriseExceptions/InvalidGrantException.cs @@ -8,35 +8,39 @@ public class InvalidGrantException : AuthoriseException /// public InvalidGrantException(string detail) : base(string.Empty, System.Net.HttpStatusCode.BadRequest, "invalid_grant", detail) - { } - + { + } } public class ExpiredAuthorizationCodeException : InvalidGrantException { - public ExpiredAuthorizationCodeException() : base(Constants.ErrorMessages.Token.AuthorizationCodeExpired) - { } - + public ExpiredAuthorizationCodeException() + : base(Constants.ErrorMessages.Token.AuthorizationCodeExpired) + { + } } public class InvalidAuthorizationCodeException : InvalidGrantException { - public InvalidAuthorizationCodeException() : base(Constants.ErrorMessages.Token.InvalidAuthorizationCode) - { } - + public InvalidAuthorizationCodeException() + : base(Constants.ErrorMessages.Token.InvalidAuthorizationCode) + { + } } public class MissingRefreshTokenException : InvalidGrantException { - public MissingRefreshTokenException() : base(Constants.ErrorMessages.Token.MissingRefreshToken) - { } - + public MissingRefreshTokenException() + : base(Constants.ErrorMessages.Token.MissingRefreshToken) + { + } } public class InvalidRefreshTokenException : InvalidGrantException { - public InvalidRefreshTokenException() : base(Constants.ErrorMessages.Token.InvalidRefreshToken) - { } - + public InvalidRefreshTokenException() + : base(Constants.ErrorMessages.Token.InvalidRefreshToken) + { + } } } diff --git a/Source/ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation/Exceptions/AuthoriseExceptions/InvalidKeyHolderException.cs b/Source/ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation/Exceptions/AuthoriseExceptions/InvalidKeyHolderException.cs index 4375150..92a87d2 100644 --- a/Source/ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation/Exceptions/AuthoriseExceptions/InvalidKeyHolderException.cs +++ b/Source/ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation/Exceptions/AuthoriseExceptions/InvalidKeyHolderException.cs @@ -8,7 +8,7 @@ public class InvalidKeyHolderException : AuthoriseException /// public InvalidKeyHolderException() : base(string.Empty, System.Net.HttpStatusCode.Unauthorized, "invalid_token", Constants.ErrorMessages.Authorization.AuthorizationHolderOfKeyCheckFailed) - { } - + { + } } } diff --git a/Source/ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation/Exceptions/AuthoriseExceptions/InvalidRedirectUriException.cs b/Source/ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation/Exceptions/AuthoriseExceptions/InvalidRedirectUriException.cs index e558eca..303cb08 100644 --- a/Source/ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation/Exceptions/AuthoriseExceptions/InvalidRedirectUriException.cs +++ b/Source/ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation/Exceptions/AuthoriseExceptions/InvalidRedirectUriException.cs @@ -7,7 +7,8 @@ public class InvalidRedirectUriException : AuthoriseException /// Status code: 400 (Bad Request). /// public InvalidRedirectUriException(string redirectUri) - : base(string.Empty, System.Net.HttpStatusCode.BadRequest, "invalid_redirect_uri", Constants.ErrorMessages.Dcr.RegistrationRequestInvalidRedirectUri.Replace("{0}",redirectUri)) - { } + : base(string.Empty, System.Net.HttpStatusCode.BadRequest, "invalid_redirect_uri", Constants.ErrorMessages.Dcr.RegistrationRequestInvalidRedirectUri.Replace("{0}", redirectUri)) + { + } } } diff --git a/Source/ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation/Exceptions/AuthoriseExceptions/InvalidRequestException.cs b/Source/ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation/Exceptions/AuthoriseExceptions/InvalidRequestException.cs index 8853e60..202e907 100644 --- a/Source/ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation/Exceptions/AuthoriseExceptions/InvalidRequestException.cs +++ b/Source/ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation/Exceptions/AuthoriseExceptions/InvalidRequestException.cs @@ -1,7 +1,7 @@ -using System.Net; - -namespace ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation.Exceptions.AuthoriseExceptions +namespace ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation.Exceptions.AuthoriseExceptions { + using System.Net; + public class InvalidRequestException : AuthoriseException { /// @@ -10,7 +10,8 @@ public class InvalidRequestException : AuthoriseException /// public InvalidRequestException(string detail) : base(string.Empty, System.Net.HttpStatusCode.BadRequest, "invalid_request", detail) - { } + { + } /// /// Initializes a new instance of the class. @@ -18,65 +19,90 @@ public InvalidRequestException(string detail) /// public InvalidRequestException(string detail, HttpStatusCode statusCode) : base(string.Empty, statusCode, "invalid_request", detail) - { } - + { + } } public class UnsupportedRequestUriFormParameterException : InvalidRequestException { - public UnsupportedRequestUriFormParameterException() : base(Constants.ErrorMessages.Par.ParRequestUriFormParameterNotSupported) - { } + public UnsupportedRequestUriFormParameterException() + : base(Constants.ErrorMessages.Par.ParRequestUriFormParameterNotSupported) + { + } + } + + public class MissingResponseModeException : InvalidRequestException + { + public MissingResponseModeException() + : base(Constants.ErrorMessages.Par.MissingResponseMode) + { + } } public class UnsupportedResponseModeException : InvalidRequestException { - public UnsupportedResponseModeException() : base(Constants.ErrorMessages.General.UnsupportedResponseMode) - { } + public UnsupportedResponseModeException() + : base(Constants.ErrorMessages.General.UnsupportedResponseMode) + { + } } public class UnsupportedResponseTypeException : InvalidRequestException { - public UnsupportedResponseTypeException() : base(Constants.ErrorMessages.General.UnsupportedResponseType) - { } + public UnsupportedResponseTypeException() + : base(Constants.ErrorMessages.General.UnsupportedResponseType) + { + } } public class MissingResponseTypeException : InvalidRequestException { - public MissingResponseTypeException() : base(Constants.ErrorMessages.General.MissingResponseType) - { } + public MissingResponseTypeException() + : base(Constants.ErrorMessages.General.MissingResponseType) + { + } } public class MissingOpenIdScopeException : InvalidRequestException { - public MissingOpenIdScopeException() : base("OpenID Connect requests MUST contain the openid scope value.") //TODO: Should a error gen code and add to constants. Bug 64146 - { } + public MissingOpenIdScopeException() + : base("OpenID Connect requests MUST contain the openid scope value.") // TODO: Should a error gen code and add to constants. Bug 64146 + { + } } public class MissingAuthorizationCodeException : InvalidRequestException { - public MissingAuthorizationCodeException() : base(Constants.ErrorMessages.General.MissingCode) - { } + public MissingAuthorizationCodeException() + : base(Constants.ErrorMessages.General.MissingCode) + { + } } public class InvalidRedirectUriForClientException : InvalidRequestException { - public InvalidRedirectUriForClientException() : base(Constants.ErrorMessages.General.InvalidRedirectUri) - { } - + public InvalidRedirectUriForClientException() + : base(Constants.ErrorMessages.General.InvalidRedirectUri) + { + } } #region 302Redirects public class UnsupportedResponseTypeRedirectException : InvalidRequestException { - public UnsupportedResponseTypeRedirectException() : base("Unsupported response_type", HttpStatusCode.Redirect)//TODO: Should a error gen code and add to constants. Bug 64146 - { } + public UnsupportedResponseTypeRedirectException() + : base("Unsupported response_type", HttpStatusCode.Redirect) // TODO: Should a error gen code and add to constants. Bug 64146 + { + } } public class InvalidClientIdRedirectException : InvalidRequestException { - public InvalidClientIdRedirectException() : base("Invalid client ID.", HttpStatusCode.Redirect)//TODO: Should a error gen code and add to constants. Bug 64146 - { } + public InvalidClientIdRedirectException() + : base("Invalid client ID.", HttpStatusCode.Redirect) // TODO: Should a error gen code and add to constants. Bug 64146 + { + } } #endregion } diff --git a/Source/ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation/Exceptions/AuthoriseExceptions/InvalidRequestObjectException.cs b/Source/ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation/Exceptions/AuthoriseExceptions/InvalidRequestObjectException.cs index 0b56351..53c3292 100644 --- a/Source/ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation/Exceptions/AuthoriseExceptions/InvalidRequestObjectException.cs +++ b/Source/ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation/Exceptions/AuthoriseExceptions/InvalidRequestObjectException.cs @@ -8,49 +8,63 @@ public class InvalidRequestObjectException : AuthoriseException /// public InvalidRequestObjectException(string detail) : base(string.Empty, System.Net.HttpStatusCode.BadRequest, "invalid_request_object", detail) - { } - + { + } } public class TokenValidationRequestException : InvalidRequestObjectException { - public TokenValidationRequestException() : base(Constants.ErrorMessages.Jwt.JwtValidationErro.Replace("{0}","request")) - { } + public TokenValidationRequestException() + : base(Constants.ErrorMessages.Jwt.JwtValidationErro.Replace("{0}", "request")) + { + } } public class ExpiredRequestException : InvalidRequestObjectException { - public ExpiredRequestException() : base(Constants.ErrorMessages.Jwt.JwtExpired.Replace("{0}", "request")) - { } + public ExpiredRequestException() + : base(Constants.ErrorMessages.Jwt.JwtExpired.Replace("{0}", "request")) + { + } } public class InvalidExpClaimException : InvalidRequestObjectException { - public InvalidExpClaimException() : base(Constants.ErrorMessages.General.ExpiryGreaterThan60AfterNbf) - { } + public InvalidExpClaimException() + : base(Constants.ErrorMessages.General.ExpiryGreaterThan60AfterNbf) + { + } } public class InvalidResponseModeForResponseTypeException : InvalidRequestObjectException { - public InvalidResponseModeForResponseTypeException() : base(Constants.ErrorMessages.General.InvalidResponseModeForResponseType) - { } + public InvalidResponseModeForResponseTypeException() + : base(Constants.ErrorMessages.General.InvalidResponseModeForResponseType) + { + } } public class InvalidJwtException : InvalidRequestObjectException { - public InvalidJwtException() : base("Invalid JWT request")//TODO: Should a error gen code and add to constants. Bug 64146 - { } + public InvalidJwtException() + : base("Invalid JWT request") // TODO: Should a error gen code and add to constants. Bug 64146 + { + } } public class InvalidArrangementIdException : InvalidRequestObjectException { - public InvalidArrangementIdException() : base(Constants.ErrorMessages.General.InvalidCdrArrangementId) - { } + public InvalidArrangementIdException() + : base(Constants.ErrorMessages.General.InvalidCdrArrangementId) + { + } } public class MissingNbfClaimException : InvalidRequestObjectException { - public MissingNbfClaimException() : base(Constants.ErrorMessages.General.MissingNbf) - { } + public MissingNbfClaimException() + : base(Constants.ErrorMessages.General.MissingNbf) + { + } } } diff --git a/Source/ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation/Exceptions/AuthoriseExceptions/InvalidScopeException.cs b/Source/ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation/Exceptions/AuthoriseExceptions/InvalidScopeException.cs index 1e8274d..a5264e0 100644 --- a/Source/ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation/Exceptions/AuthoriseExceptions/InvalidScopeException.cs +++ b/Source/ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation/Exceptions/AuthoriseExceptions/InvalidScopeException.cs @@ -7,7 +7,8 @@ public class InvalidScopeException : AuthoriseException /// Status code: 400 (Bad Request). /// public InvalidScopeException() - : base(string.Empty, System.Net.HttpStatusCode.BadRequest, "invalid_scope", "Additional scopes were requested in the refresh_token request") //TODO: Should a error gen code and add to constants. Bug 64146 - { } + : base(string.Empty, System.Net.HttpStatusCode.BadRequest, "invalid_scope", "Additional scopes were requested in the refresh_token request") // TODO: Should a error gen code and add to constants. Bug 64146 + { + } } } diff --git a/Source/ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation/Exceptions/AuthoriseExceptions/InvalidSoftwareStatementException.cs b/Source/ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation/Exceptions/AuthoriseExceptions/InvalidSoftwareStatementException.cs index c92d49d..9c713b9 100644 --- a/Source/ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation/Exceptions/AuthoriseExceptions/InvalidSoftwareStatementException.cs +++ b/Source/ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation/Exceptions/AuthoriseExceptions/InvalidSoftwareStatementException.cs @@ -8,6 +8,7 @@ public class InvalidSoftwareStatementException : AuthoriseException /// public InvalidSoftwareStatementException() : base(string.Empty, System.Net.HttpStatusCode.BadRequest, "invalid_software_statement", Constants.ErrorMessages.Dcr.SsaValidationFailed) - { } + { + } } } diff --git a/Source/ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation/Exceptions/AuthoriseExceptions/UnsupportedGrantTypeException.cs b/Source/ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation/Exceptions/AuthoriseExceptions/UnsupportedGrantTypeException.cs index 896bd7d..efea9b9 100644 --- a/Source/ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation/Exceptions/AuthoriseExceptions/UnsupportedGrantTypeException.cs +++ b/Source/ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation/Exceptions/AuthoriseExceptions/UnsupportedGrantTypeException.cs @@ -8,17 +8,20 @@ public class UnsupportedGrantTypeException : AuthoriseException /// public UnsupportedGrantTypeException(string detail) : base(string.Empty, System.Net.HttpStatusCode.BadRequest, "unsupported_grant_type", detail) - { } + { + } public UnsupportedGrantTypeException() : base(string.Empty, System.Net.HttpStatusCode.BadRequest, "unsupported_grant_type", Constants.ErrorMessages.General.UnsupportedGrantType) - { } + { + } } public class MissingGrantTypeException : UnsupportedGrantTypeException { - public MissingGrantTypeException() : base(Constants.ErrorMessages.General.GrantTypeNotProvided) - { } + public MissingGrantTypeException() + : base(Constants.ErrorMessages.General.GrantTypeNotProvided) + { + } } - } diff --git a/Source/ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation/Exceptions/CdrErrorExtensions.cs b/Source/ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation/Exceptions/CdrErrorExtensions.cs index 857564b..1120707 100644 --- a/Source/ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation/Exceptions/CdrErrorExtensions.cs +++ b/Source/ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation/Exceptions/CdrErrorExtensions.cs @@ -1,9 +1,9 @@ -using ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation.Enums; -using ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation.Extensions; -using ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation.Models; - -namespace ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation.Exceptions +namespace ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation.Exceptions { + using ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation.Enums; + using ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation.Extensions; + using ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation.Models; + public static class CdrErrorExtensions { private static readonly Dictionary _errors = InitErrors(); diff --git a/Source/ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation/Exceptions/CdrException.cs b/Source/ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation/Exceptions/CdrException.cs index 25dd4a4..7523d58 100644 --- a/Source/ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation/Exceptions/CdrException.cs +++ b/Source/ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation/Exceptions/CdrException.cs @@ -1,8 +1,8 @@ -using System.Net; -using ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation.Enums; - -namespace ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation.Exceptions +namespace ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation.Exceptions { + using System.Net; + using ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation.Enums; + public class CdrException : Exception { private readonly string _code; diff --git a/Source/ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation/Exceptions/CdrValidationException.cs b/Source/ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation/Exceptions/CdrValidationException.cs index 99e2e0e..7ba06d9 100644 --- a/Source/ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation/Exceptions/CdrValidationException.cs +++ b/Source/ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation/Exceptions/CdrValidationException.cs @@ -1,8 +1,8 @@ -using System.ComponentModel.DataAnnotations; -using ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation.Interfaces; - -namespace Register.Common.Exceptions +namespace Register.Common.Exceptions { + using System.ComponentModel.DataAnnotations; + using ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation.Interfaces; + public class CdrValidationException : Exception, ICdrValidationException { public CdrValidationException() diff --git a/Source/ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation/Exceptions/CdsExceptions/AdrStatusNotActiveException.cs b/Source/ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation/Exceptions/CdsExceptions/AdrStatusNotActiveException.cs index 2374644..0449006 100644 --- a/Source/ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation/Exceptions/CdsExceptions/AdrStatusNotActiveException.cs +++ b/Source/ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation/Exceptions/CdsExceptions/AdrStatusNotActiveException.cs @@ -1,8 +1,8 @@ -using ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation.Enums; -using ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation.Extensions; - -namespace ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation.Exceptions.CdsExceptions +namespace ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation.Exceptions.CdsExceptions { + using ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation.Enums; + using ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation.Extensions; + public class AdrStatusNotActiveException : CdrException { /// @@ -13,19 +13,22 @@ public class AdrStatusNotActiveException : CdrException /// public AdrStatusNotActiveException(string detail, string message) : base(CdsError.ADRStatusIsNotActive, detail, System.Net.HttpStatusCode.Forbidden, message) - { } + { + } public AdrStatusNotActiveException(string detail) : base(CdsError.ADRStatusIsNotActive, detail, System.Net.HttpStatusCode.Forbidden, null) - { } + { + } public AdrStatusNotActiveException(SoftwareProductStatus status) : base(CdsError.ADRStatusIsNotActive, Constants.ErrorMessages.General.SoftwareProductStatusInactive.Replace("{0}", status.ToEnumMemberAttrValue()), System.Net.HttpStatusCode.Forbidden, null) - { } + { + } public AdrStatusNotActiveException(LegalEntityStatus status) - : base(CdsError.ADRStatusIsNotActive, Constants.ErrorMessages.General.SoftwareProductStatusInactive.Replace("{0}", status.ToEnumMemberAttrValue()), System.Net.HttpStatusCode.Forbidden, null) //TODO: Should the message be Legal Entity Status instead of Software Product? Noted in Bug 63710 - { } - + : base(CdsError.ADRStatusIsNotActive, Constants.ErrorMessages.General.SoftwareProductStatusInactive.Replace("{0}", status.ToEnumMemberAttrValue()), System.Net.HttpStatusCode.Forbidden, null) // TODO: Should the message be Legal Entity Status instead of Software Product? Noted in Bug 63710 + { + } } } diff --git a/Source/ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation/Exceptions/CdsExceptions/InvalidArrangementException.cs b/Source/ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation/Exceptions/CdsExceptions/InvalidArrangementException.cs index b91cffe..1eb41fe 100644 --- a/Source/ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation/Exceptions/CdsExceptions/InvalidArrangementException.cs +++ b/Source/ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation/Exceptions/CdsExceptions/InvalidArrangementException.cs @@ -1,7 +1,7 @@ -using ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation.Enums; - -namespace ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation.Exceptions.CdsExceptions +namespace ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation.Exceptions.CdsExceptions { + using ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation.Enums; + public class InvalidArrangementException : CdrException { /// @@ -12,10 +12,12 @@ public class InvalidArrangementException : CdrException /// public InvalidArrangementException(string detail, string message) : base(CdsError.InvalidConsentArrangement, detail, System.Net.HttpStatusCode.UnprocessableEntity, message) - { } + { + } public InvalidArrangementException(string detail) : base(CdsError.InvalidConsentArrangement, detail, System.Net.HttpStatusCode.UnprocessableEntity, null) - { } + { + } } } diff --git a/Source/ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation/Exceptions/CdsExceptions/InvalidConsentException.cs b/Source/ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation/Exceptions/CdsExceptions/InvalidConsentException.cs index bb84c67..fd24f5b 100644 --- a/Source/ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation/Exceptions/CdsExceptions/InvalidConsentException.cs +++ b/Source/ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation/Exceptions/CdsExceptions/InvalidConsentException.cs @@ -1,8 +1,8 @@ -using System.Net; -using ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation.Enums; - -namespace ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation.Exceptions.CdsExceptions +namespace ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation.Exceptions.CdsExceptions { + using System.Net; + using ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation.Enums; + public class InvalidConsentException : CdrException { /// @@ -13,14 +13,17 @@ public class InvalidConsentException : CdrException /// public InvalidConsentException(string detail, string message) : base(CdsError.ConsentIsInvalid, detail, HttpStatusCode.Forbidden, message) - { } + { + } public InvalidConsentException(string detail) : base(CdsError.ConsentIsInvalid, detail, HttpStatusCode.Forbidden, null) - { } + { + } public InvalidConsentException() : base(CdsError.ConsentIsInvalid, "The authorised consumer's consent is insufficient to execute the resource", HttpStatusCode.Forbidden, null) - { } + { + } } } diff --git a/Source/ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation/Exceptions/CdsExceptions/InvalidEnergyAccountException.cs b/Source/ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation/Exceptions/CdsExceptions/InvalidEnergyAccountException.cs index 08bb21b..0f061ce 100644 --- a/Source/ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation/Exceptions/CdsExceptions/InvalidEnergyAccountException.cs +++ b/Source/ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation/Exceptions/CdsExceptions/InvalidEnergyAccountException.cs @@ -1,7 +1,7 @@ -using ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation.Enums; - -namespace ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation.Exceptions.CdsExceptions +namespace ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation.Exceptions.CdsExceptions { + using ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation.Enums; + public class InvalidEnergyAccountException : CdrException { /// @@ -12,10 +12,12 @@ public class InvalidEnergyAccountException : CdrException /// public InvalidEnergyAccountException(string detail, string message) : base(CdsError.InvalidEnergyAccount, detail, System.Net.HttpStatusCode.NotFound, message) - { } + { + } public InvalidEnergyAccountException(string detail) : base(CdsError.InvalidEnergyAccount, detail, System.Net.HttpStatusCode.NotFound, null) - { } + { + } } } diff --git a/Source/ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation/Exceptions/CdsExceptions/InvalidFieldException.cs b/Source/ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation/Exceptions/CdsExceptions/InvalidFieldException.cs index 4307316..3e6d0a9 100644 --- a/Source/ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation/Exceptions/CdsExceptions/InvalidFieldException.cs +++ b/Source/ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation/Exceptions/CdsExceptions/InvalidFieldException.cs @@ -1,7 +1,7 @@ -using ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation.Enums; - -namespace ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation.Exceptions.CdsExceptions +namespace ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation.Exceptions.CdsExceptions { + using ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation.Enums; + public class InvalidFieldException : CdrException { /// @@ -12,10 +12,12 @@ public class InvalidFieldException : CdrException /// public InvalidFieldException(string detail, string message) : base(CdsError.InvalidField, detail, System.Net.HttpStatusCode.BadRequest, message) - { } + { + } public InvalidFieldException(string detail) : base(CdsError.InvalidField, detail, System.Net.HttpStatusCode.BadRequest, null) - { } + { + } } } diff --git a/Source/ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation/Exceptions/CdsExceptions/InvalidHeaderException.cs b/Source/ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation/Exceptions/CdsExceptions/InvalidHeaderException.cs index b30c8e4..5caf960 100644 --- a/Source/ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation/Exceptions/CdsExceptions/InvalidHeaderException.cs +++ b/Source/ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation/Exceptions/CdsExceptions/InvalidHeaderException.cs @@ -1,7 +1,7 @@ -using ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation.Enums; - -namespace ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation.Exceptions.CdsExceptions +namespace ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation.Exceptions.CdsExceptions { + using ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation.Enums; + public class InvalidHeaderException : CdrException { /// @@ -17,6 +17,7 @@ public InvalidHeaderException(string detail, string message) public InvalidHeaderException(string detail) : base(CdsError.InvalidHeader, detail, System.Net.HttpStatusCode.BadRequest, null) - { } + { + } } } diff --git a/Source/ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation/Exceptions/CdsExceptions/InvalidPageException.cs b/Source/ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation/Exceptions/CdsExceptions/InvalidPageException.cs index 014651e..37394fa 100644 --- a/Source/ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation/Exceptions/CdsExceptions/InvalidPageException.cs +++ b/Source/ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation/Exceptions/CdsExceptions/InvalidPageException.cs @@ -1,8 +1,8 @@ -using System.Net; -using ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation.Enums; - -namespace ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation.Exceptions.CdsExceptions +namespace ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation.Exceptions.CdsExceptions { + using System.Net; + using ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation.Enums; + public class InvalidPageException : CdrException { /// @@ -13,10 +13,12 @@ public class InvalidPageException : CdrException /// public InvalidPageException(string detail, string message) : base(CdsError.InvalidPage, detail, HttpStatusCode.UnprocessableEntity, message) - { } + { + } public InvalidPageException(string detail) : base(CdsError.InvalidPage, detail, HttpStatusCode.UnprocessableEntity, null) - { } + { + } } } diff --git a/Source/ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation/Exceptions/CdsExceptions/InvalidPageSizeException.cs b/Source/ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation/Exceptions/CdsExceptions/InvalidPageSizeException.cs index 9deccf0..5735104 100644 --- a/Source/ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation/Exceptions/CdsExceptions/InvalidPageSizeException.cs +++ b/Source/ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation/Exceptions/CdsExceptions/InvalidPageSizeException.cs @@ -1,7 +1,7 @@ -using ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation.Enums; - -namespace ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation.Exceptions.CdsExceptions +namespace ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation.Exceptions.CdsExceptions { + using ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation.Enums; + public class InvalidPageSizeException : CdrException { /// @@ -12,10 +12,12 @@ public class InvalidPageSizeException : CdrException /// public InvalidPageSizeException(string detail, string message) : base(CdsError.InvalidPageSize, detail, System.Net.HttpStatusCode.BadRequest, message) - { } + { + } public InvalidPageSizeException(string detail) : base(CdsError.InvalidPageSize, detail, System.Net.HttpStatusCode.BadRequest, null) - { } + { + } } } diff --git a/Source/ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation/Exceptions/CdsExceptions/InvalidVersionException.cs b/Source/ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation/Exceptions/CdsExceptions/InvalidVersionException.cs index 407be60..bfcc5f7 100644 --- a/Source/ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation/Exceptions/CdsExceptions/InvalidVersionException.cs +++ b/Source/ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation/Exceptions/CdsExceptions/InvalidVersionException.cs @@ -1,7 +1,7 @@ -using ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation.Enums; - -namespace ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation.Exceptions.CdsExceptions +namespace ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation.Exceptions.CdsExceptions { + using ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation.Enums; + public class InvalidVersionException : CdrException { /// @@ -12,14 +12,17 @@ public class InvalidVersionException : CdrException /// public InvalidVersionException(string detail, string message) : base(CdsError.InvalidVersion, detail, System.Net.HttpStatusCode.BadRequest, message) - { } + { + } public InvalidVersionException(string detail) : base(CdsError.InvalidVersion, detail, System.Net.HttpStatusCode.BadRequest, null) - { } + { + } public InvalidVersionException() : base(CdsError.InvalidVersion, "Version is not a positive Integer.", System.Net.HttpStatusCode.BadRequest, null) - { } + { + } } } diff --git a/Source/ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation/Exceptions/CdsExceptions/MissingRequiredFieldException.cs b/Source/ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation/Exceptions/CdsExceptions/MissingRequiredFieldException.cs index c3be671..2a0db7d 100644 --- a/Source/ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation/Exceptions/CdsExceptions/MissingRequiredFieldException.cs +++ b/Source/ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation/Exceptions/CdsExceptions/MissingRequiredFieldException.cs @@ -1,7 +1,7 @@ -using ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation.Enums; - -namespace ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation.Exceptions.CdsExceptions +namespace ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation.Exceptions.CdsExceptions { + using ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation.Enums; + public class MissingRequiredFieldException : CdrException { /// @@ -12,10 +12,12 @@ public class MissingRequiredFieldException : CdrException /// public MissingRequiredFieldException(string detail, string message) : base(CdsError.MissingRequiredField, detail, System.Net.HttpStatusCode.BadRequest, message) - { } + { + } public MissingRequiredFieldException(string detail) : base(CdsError.MissingRequiredField, detail, System.Net.HttpStatusCode.BadRequest, null) - { } + { + } } } diff --git a/Source/ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation/Exceptions/CdsExceptions/MissingRequiredHeaderException.cs b/Source/ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation/Exceptions/CdsExceptions/MissingRequiredHeaderException.cs index 6eff903..ecd351d 100644 --- a/Source/ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation/Exceptions/CdsExceptions/MissingRequiredHeaderException.cs +++ b/Source/ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation/Exceptions/CdsExceptions/MissingRequiredHeaderException.cs @@ -1,7 +1,7 @@ -using ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation.Enums; - -namespace ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation.Exceptions.CdsExceptions +namespace ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation.Exceptions.CdsExceptions { + using ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation.Enums; + public class MissingRequiredHeaderException : CdrException { /// @@ -12,10 +12,12 @@ public class MissingRequiredHeaderException : CdrException /// public MissingRequiredHeaderException(string detail, string message) : base(CdsError.MissingRequiredHeader, detail, System.Net.HttpStatusCode.BadRequest, message) - { } + { + } public MissingRequiredHeaderException(string detail) : base(CdsError.MissingRequiredHeader, detail, System.Net.HttpStatusCode.BadRequest, null) - { } + { + } } } diff --git a/Source/ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation/Exceptions/CdsExceptions/ResourceNotFoundException.cs b/Source/ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation/Exceptions/CdsExceptions/ResourceNotFoundException.cs index 5fa57f9..50fa646 100644 --- a/Source/ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation/Exceptions/CdsExceptions/ResourceNotFoundException.cs +++ b/Source/ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation/Exceptions/CdsExceptions/ResourceNotFoundException.cs @@ -1,8 +1,8 @@ -using System.Net; -using ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation.Enums; - -namespace ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation.Exceptions.CdsExceptions +namespace ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation.Exceptions.CdsExceptions { + using System.Net; + using ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation.Enums; + public class ResourceNotFoundException : CdrException { /// @@ -13,14 +13,17 @@ public class ResourceNotFoundException : CdrException /// public ResourceNotFoundException(string detail, string message) : base(CdsError.ResourceNotFound, detail, HttpStatusCode.NotFound, message) - { } + { + } public ResourceNotFoundException(string detail) : base(CdsError.ResourceNotFound, detail, HttpStatusCode.NotFound, null) - { } + { + } public ResourceNotFoundException() : base(CdsError.ResourceNotFound, "The authorised consumer's consent is insufficient to execute the resource", HttpStatusCode.NotFound, null) - { } + { + } } } diff --git a/Source/ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation/Exceptions/CdsExceptions/UnavailableBankingAccountException.cs b/Source/ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation/Exceptions/CdsExceptions/UnavailableBankingAccountException.cs index 8f66a45..f80d2c9 100644 --- a/Source/ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation/Exceptions/CdsExceptions/UnavailableBankingAccountException.cs +++ b/Source/ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation/Exceptions/CdsExceptions/UnavailableBankingAccountException.cs @@ -1,8 +1,8 @@ -using System.Runtime.Serialization; -using ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation.Enums; - -namespace ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation.Exceptions.CdsExceptions +namespace ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation.Exceptions.CdsExceptions { + using System.Runtime.Serialization; + using ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation.Enums; + public class UnavailableBankingAccountException : CdrException { /// @@ -13,10 +13,12 @@ public class UnavailableBankingAccountException : CdrException /// public UnavailableBankingAccountException(string detail, string message) : base(CdsError.UnavailableBankingAccount, detail, System.Net.HttpStatusCode.UnprocessableEntity, message) - { } + { + } public UnavailableBankingAccountException(string detail) : base(CdsError.UnavailableBankingAccount, detail, System.Net.HttpStatusCode.UnprocessableEntity, null) - { } + { + } } } diff --git a/Source/ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation/Exceptions/CdsExceptions/UnsupportedVersionException.cs b/Source/ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation/Exceptions/CdsExceptions/UnsupportedVersionException.cs index e8f5393..2a3634b 100644 --- a/Source/ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation/Exceptions/CdsExceptions/UnsupportedVersionException.cs +++ b/Source/ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation/Exceptions/CdsExceptions/UnsupportedVersionException.cs @@ -1,7 +1,7 @@ -using ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation.Enums; - -namespace ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation.Exceptions.CdsExceptions +namespace ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation.Exceptions.CdsExceptions { + using ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation.Enums; + public class UnsupportedVersionException : CdrException { /// @@ -12,15 +12,17 @@ public class UnsupportedVersionException : CdrException /// public UnsupportedVersionException(string detail, string message) : base(CdsError.UnsupportedVersion, detail, System.Net.HttpStatusCode.NotAcceptable, message) - { } + { + } public UnsupportedVersionException(string detail) : base(CdsError.UnsupportedVersion, detail, System.Net.HttpStatusCode.NotAcceptable, null) - { } + { + } public UnsupportedVersionException() : base(CdsError.UnsupportedVersion, "Requested version is lower than the minimum version or greater than maximum version.", System.Net.HttpStatusCode.NotAcceptable, null) - { } - + { + } } } diff --git a/Source/ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation/Exceptions/DataHolderAuthoriseIncorrectOneTimePasswordException.cs b/Source/ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation/Exceptions/DataHolderAuthoriseIncorrectOneTimePasswordException.cs index 730f6d4..36f1103 100644 --- a/Source/ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation/Exceptions/DataHolderAuthoriseIncorrectOneTimePasswordException.cs +++ b/Source/ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation/Exceptions/DataHolderAuthoriseIncorrectOneTimePasswordException.cs @@ -2,6 +2,5 @@ { public class DataHolderAuthoriseIncorrectOneTimePasswordException : Exception { - } } diff --git a/Source/ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation/Exceptions/InvalidTokenException.cs b/Source/ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation/Exceptions/InvalidTokenException.cs index e09fb83..5e7e9c7 100644 --- a/Source/ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation/Exceptions/InvalidTokenException.cs +++ b/Source/ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation/Exceptions/InvalidTokenException.cs @@ -8,6 +8,7 @@ public class InvalidTokenException : CdrException /// public InvalidTokenException() : base("401", "Unauthorized", "invalid_token", System.Net.HttpStatusCode.Unauthorized, null) - { } + { + } } } diff --git a/Source/ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation/Exceptions/PageElementNotFoundException.cs b/Source/ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation/Exceptions/PageElementNotFoundException.cs index 1334371..dacc0f0 100644 --- a/Source/ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation/Exceptions/PageElementNotFoundException.cs +++ b/Source/ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation/Exceptions/PageElementNotFoundException.cs @@ -1,8 +1,10 @@ namespace ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation.Exceptions { public class PageElementNotFoundException : Exception - { - public PageElementNotFoundException(string page, string selector) : base($"{page} page element could not be found using selector: {selector}") - { } + { + public PageElementNotFoundException(string page, string selector) + : base($"{page} page element could not be found using selector: {selector}") + { + } } } diff --git a/Source/ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation/Exceptions/UnexpectedErrorException.cs b/Source/ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation/Exceptions/UnexpectedErrorException.cs index b583ced..1e7b5d1 100644 --- a/Source/ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation/Exceptions/UnexpectedErrorException.cs +++ b/Source/ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation/Exceptions/UnexpectedErrorException.cs @@ -3,11 +3,12 @@ public class UnexpectedErrorException : CdrException { /// - /// Initializes a new instance of the class. + /// Initializes a new instance of the class. /// Status code: 400 (Bad Request). /// public UnexpectedErrorException(string description) : base(Enums.CdsError.UnexpectedError, description, System.Net.HttpStatusCode.BadRequest, description) - { } + { + } } } diff --git a/Source/ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation/Extensions/DateTimeExtensions.cs b/Source/ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation/Extensions/DateTimeExtensions.cs index b45a206..b650ad7 100644 --- a/Source/ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation/Extensions/DateTimeExtensions.cs +++ b/Source/ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation/Extensions/DateTimeExtensions.cs @@ -16,8 +16,9 @@ public static class DateTimeExtensions } /// - /// Return datetime converted to Unix Epoch (number of seconds since 00:00:00 UTC on 1 Jan 1970) + /// Return datetime converted to Unix Epoch (number of seconds since 00:00:00 UTC on 1 Jan 1970). /// + /// string. public static int UnixEpoch(this DateTime datetime) { return Convert.ToInt32(datetime.Subtract(DateTime.UnixEpoch).TotalSeconds); diff --git a/Source/ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation/Extensions/EnumHelper.cs b/Source/ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation/Extensions/EnumHelper.cs index 3f90385..cd23584 100644 --- a/Source/ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation/Extensions/EnumHelper.cs +++ b/Source/ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation/Extensions/EnumHelper.cs @@ -1,7 +1,7 @@ -using System.Runtime.Serialization; - -namespace ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation.Extensions +namespace ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation.Extensions { + using System.Runtime.Serialization; + public static class EnumHelper { public static TEnum ToEnum(this string enumText, Exception? exception = null) diff --git a/Source/ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation/Extensions/JsonExtensions.cs b/Source/ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation/Extensions/JsonExtensions.cs index 85348f5..702313c 100644 --- a/Source/ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation/Extensions/JsonExtensions.cs +++ b/Source/ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation/Extensions/JsonExtensions.cs @@ -1,37 +1,39 @@ -using System.Text.Json; -using Newtonsoft.Json; -using Newtonsoft.Json.Linq; -using Serilog; - -namespace ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation.Extensions +namespace ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation.Extensions { + using System.Text.Json; + using Newtonsoft.Json; + using Newtonsoft.Json.Linq; + using Serilog; + public static class JsonExtensions { public static void WriteJsonToFile(string filename, string json) { - Log.Information("Calling {FunctionName} with Params: {P1}={V1},{P2}={V2}", nameof(WriteJsonToFile), nameof(filename), filename, nameof(json), json); - //TODO: Expect this is the System.Text.Json.JsonSerializer way to replace Newtonsoft, if we decide to do it (model property attributes would need to change) + Log.Information("Calling {FunctionName} with Params: {P1}={V1},{P2}={V2}", nameof(WriteJsonToFile), nameof(filename), filename, nameof(json), json); + + // TODO: Expect this is the System.Text.Json.JsonSerializer way to replace Newtonsoft, if we decide to do it (model property attributes would need to change) var options = new JsonSerializerOptions { - WriteIndented = true + WriteIndented = true, }; var jsonObj = System.Text.Json.JsonSerializer.Deserialize(json); var jsonStr = System.Text.Json.JsonSerializer.Serialize(jsonObj, options); - + File.WriteAllText(filename, jsonStr); } /// - /// Strip comments from json string. - /// The json will be reserialized so it's formatting may change (ie whitespace/indentation etc) + /// Strip comments from json string. + /// The json will be reserialized so it's formatting may change (ie whitespace/indentation etc). /// + /// string. public static string JsonStripComments(this string json) { var options = new JsonSerializerOptions { ReadCommentHandling = JsonCommentHandling.Skip, - WriteIndented = true + WriteIndented = true, }; var jsonObject = System.Text.Json.JsonSerializer.Deserialize(json, options); @@ -40,10 +42,11 @@ public static string JsonStripComments(this string json) } /// - /// Compare json. + /// Compare json. /// Json is converted to JTokens prior to comparision, thus formatting is ignore. /// Returns true if json is equivalent, otherwise false. /// + /// string. public static bool JsonCompare(this string json, string jsonToCompare) { Log.Information("Calling {FunctionName} with Params: {P1}={V1},{P2}={V2}", nameof(JsonCompare), nameof(json), json, nameof(jsonToCompare), jsonToCompare); @@ -56,7 +59,7 @@ public static bool JsonCompare(this string json, string jsonToCompare) public static async Task DeserializeResponseAsync(HttpResponseMessage response) { var responseContent = await response.Content.ReadAsStringAsync(); - + if (string.IsNullOrEmpty(responseContent)) { return default; diff --git a/Source/ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation/Extensions/JwtSecurityTokenExtensions.cs b/Source/ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation/Extensions/JwtSecurityTokenExtensions.cs index 899e56b..35d4404 100644 --- a/Source/ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation/Extensions/JwtSecurityTokenExtensions.cs +++ b/Source/ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation/Extensions/JwtSecurityTokenExtensions.cs @@ -1,32 +1,31 @@ -using FluentAssertions; -using System.IdentityModel.Tokens.Jwt; -using System.Security.Claims; - -namespace ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation.Extensions +namespace ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation.Extensions { + using System.IdentityModel.Tokens.Jwt; + using System.Security.Claims; + using FluentAssertions; + static public class JwtSecurityTokenExtensions { /// /// Get claim for claimType. Throws exception if no claim or multiple claims (ie must be a single claim for claimType). /// - /// + /// Cliam. static public Claim Claim(this JwtSecurityToken jwt, string claimType) => jwt.Claims.Single(claim => claim.Type == claimType); - /// /// Assert JWT contains a claim with given value. /// - /// JWT to make the assertions on - /// The claim type to assert - /// The claim value to assert. If null then claim value can be anything (it is not checked) - /// If true then the claim itself is optional and doesn't need to exist in the claims + /// JWT to make the assertions on. + /// The claim type to assert. + /// The claim value to assert. If null then claim value can be anything (it is not checked). + /// If true then the claim itself is optional and doesn't need to exist in the claims. static public void AssertClaim(this JwtSecurityToken jwt, string claimType, string? claimValue, bool optional = false) { var claims = jwt.Claims.Where(claim => claim.Type == claimType); // Claim not found and it's optional so just exit - if (optional && !claims.Any()) + if (optional && !claims.Any()) { return; } @@ -42,5 +41,4 @@ static public void AssertClaim(this JwtSecurityToken jwt, string claimType, stri } } } - -} +} \ No newline at end of file diff --git a/Source/ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation/Extensions/PlaywrightExtensions.cs b/Source/ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation/Extensions/PlaywrightExtensions.cs index c46909f..a22c12d 100644 --- a/Source/ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation/Extensions/PlaywrightExtensions.cs +++ b/Source/ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation/Extensions/PlaywrightExtensions.cs @@ -1,9 +1,9 @@ -using ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation.Exceptions; -using ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation.UI.Pages.Authorisation; -using Microsoft.Playwright; - -namespace ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation.Extensions +namespace ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation.Extensions { + using ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation.Exceptions; + using ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation.UI.Pages.Authorisation; + using Microsoft.Playwright; + public static class PlaywrightExtensions { public static ILocator Locator(this IPage? page, string selector, bool throwErrorIfNotFound) diff --git a/Source/ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation/Extensions/SQLExtensions.cs b/Source/ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation/Extensions/SQLExtensions.cs index 5a99165..3dd0f68 100644 --- a/Source/ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation/Extensions/SQLExtensions.cs +++ b/Source/ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation/Extensions/SQLExtensions.cs @@ -1,14 +1,15 @@ -using Microsoft.Data.SqlClient; -using Serilog; -using System.Text; - -namespace ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation.Extensions +namespace ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation.Extensions { + using System.Text; + using Microsoft.Data.SqlClient; + using Serilog; + static public class SqlExtensions { /// - /// Execute scalar command and return result as Int32. Throw error if no results or conversion error + /// Execute scalar command and return result as Int32. Throw error if no results or conversion error. /// + /// Int32. static public Int32 ExecuteScalarInt32(this SqlCommand command) { var res = command.ExecuteScalar(); @@ -18,7 +19,9 @@ static public Int32 ExecuteScalarInt32(this SqlCommand command) // Build list of paramters var sb = new StringBuilder(); foreach (SqlParameter p in command.Parameters) + { sb.Append($"{p.ParameterName}={p.Value.ToString()}"); + } // Throw exception throw new System.Data.DataException($"Command returns no results - CommandText=\"{command.CommandText}\", Parameters: {sb.ToString()}"); @@ -27,20 +30,29 @@ static public Int32 ExecuteScalarInt32(this SqlCommand command) return Convert.ToInt32(res); } + static public Int32 ExecuteScalarInt32(this SqlConnection connection, string sql) + { + Log.Information("Calling {FunctionName} with SQL command: {Sql}", nameof(ExecuteScalarInt32), sql); + using var command = new SqlCommand(sql, connection); + return command.ExecuteScalarInt32(); + } + /// - /// Execute scalar command and return result as string. Throw error if no results or conversion error + /// Execute scalar command and return result as string. Throw error if no results or conversion error. /// + /// string. static public string ExecuteScalarString(this SqlCommand command) { var res = command.ExecuteScalar(); if (res == DBNull.Value || res == null) { - // Build list of paramters var sb = new StringBuilder(); foreach (SqlParameter p in command.Parameters) + { sb.Append($"{p.ParameterName}={p.Value.ToString()}"); + } // Throw exception throw new System.Data.DataException($"Command returns no results - CommandText=\"{command.CommandText}\", Parameters: {sb.ToString()}"); @@ -49,13 +61,6 @@ static public string ExecuteScalarString(this SqlCommand command) return Convert.ToString(res); } - static public Int32 ExecuteScalarInt32(this SqlConnection connection, string sql) - { - Log.Information("Calling {FunctionName} with SQL command: {Sql}", nameof(ExecuteScalarInt32), sql); - using var command = new SqlCommand(sql, connection); - return command.ExecuteScalarInt32(); - } - static public string ExecuteScalarString(this SqlConnection connection, string sql) { Log.Information("Calling {FunctionName} with SQL command: {Sql}", nameof(ExecuteScalarString), sql); diff --git a/Source/ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation/Extensions/ServiceCollectionExtensions.cs b/Source/ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation/Extensions/ServiceCollectionExtensions.cs index 3d49bd1..5b6e9af 100644 --- a/Source/ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation/Extensions/ServiceCollectionExtensions.cs +++ b/Source/ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation/Extensions/ServiceCollectionExtensions.cs @@ -1,12 +1,12 @@ -using ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation.Interfaces; -using ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation.Models.Options; -using ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation.Services; -using Microsoft.Extensions.Configuration; -using Microsoft.Extensions.DependencyInjection; -using Serilog; - -namespace ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation.Extensions +namespace ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation.Extensions { + using ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation.Interfaces; + using ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation.Models.Options; + using ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation.Services; + using Microsoft.Extensions.Configuration; + using Microsoft.Extensions.DependencyInjection; + using Serilog; + public static class ServiceCollectionExtensions { public static IServiceCollection AddTestAutomationSettings(this IServiceCollection services, Action configureTestAutomationOptions) @@ -20,7 +20,7 @@ public static IServiceCollection AddTestAutomationSettings(this IServiceCollecti try { - //Doesn't check for Industry because it's an enum and defaults to banking if not supplied + // Doesn't check for Industry because it's an enum and defaults to banking if not supplied if (options.SCOPE.IsNullOrWhiteSpace()) { throw new InvalidOperationException($"{nameof(TestAutomationOptions.SCOPE)} - required setting is missing from StartUp"); @@ -123,7 +123,7 @@ public static IServiceCollection AddTestAutomationServices(this IServiceCollecti { Log.Information("Registering Test Automation shared services."); - if (configuration == null) + if (configuration == null) { throw new InvalidOperationException($"{nameof(AddTestAutomationServices)} - configuration cannot be null").Log(); } diff --git a/Source/ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation/Extensions/StringExtensions.cs b/Source/ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation/Extensions/StringExtensions.cs index 340f3f7..cef33d9 100644 --- a/Source/ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation/Extensions/StringExtensions.cs +++ b/Source/ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation/Extensions/StringExtensions.cs @@ -1,10 +1,10 @@ -using System.Security.Cryptography; -using System.Text; -using IdentityModel; -using Serilog; - -namespace ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation.Extensions +namespace ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation.Extensions { + using System.Security.Cryptography; + using System.Text; + using IdentityModel; + using Serilog; + public static class StringExtensions { static public void WriteStringToFile(string filename, string? str) @@ -14,8 +14,9 @@ static public void WriteStringToFile(string filename, string? str) } /// - /// Convert string to int + /// Convert string to int. /// + /// int. public static int ToInt(this string str) { return Convert.ToInt32(str); @@ -31,6 +32,5 @@ public static bool IsNullOrWhiteSpace(this string? str) { return string.IsNullOrWhiteSpace(str); } - } } diff --git a/Source/ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation/Extensions/TokenTypeExtensions.cs b/Source/ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation/Extensions/TokenTypeExtensions.cs index 970053e..cd6d0ea 100644 --- a/Source/ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation/Extensions/TokenTypeExtensions.cs +++ b/Source/ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation/Extensions/TokenTypeExtensions.cs @@ -1,17 +1,15 @@ -using ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation.Enums; - -namespace ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation.Extensions +namespace ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation.Extensions { + using ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation.Enums; public static class TokenTypeExtensions { public static string? GetUserIdByTokenType(this TokenType tokenType) { - return tokenType switch { - TokenType.JaneWilson => Constants.Users.Banking.UserIdJaneWilson, //Banking - TokenType.MaryMoss => Constants.Users.Energy.UserIdMaryMoss, //Energy + TokenType.JaneWilson => Constants.Users.Banking.UserIdJaneWilson, // Banking + TokenType.MaryMoss => Constants.Users.Energy.UserIdMaryMoss, // Energy TokenType.HeddaHare => Constants.Users.Energy.UserIdHeddaHare, TokenType.SteveKennedy => Constants.Users.UserIdSteveKennedy, TokenType.DewayneSteve => Constants.Users.UserIdDewayneSteve, @@ -20,16 +18,16 @@ public static class TokenTypeExtensions TokenType.Beverage => Constants.Users.UserIdBeverage, TokenType.KamillaSmith => Constants.Users.UserIdKamillaSmith, _ => null - }; + }; } public static string GetAllAccountIdsByTokenType(this TokenType tokenType) { return tokenType switch { - TokenType.JaneWilson => Constants.Accounts.Banking.AccountIdsAllJaneWilson, //Banking - TokenType.MaryMoss => Constants.Accounts.Energy.AccountIdsAllMaryMoss, //Energy - TokenType.HeddaHare => Constants.Accounts.Energy.AccountIdsAllHeddaHare,//Energy + TokenType.JaneWilson => Constants.Accounts.Banking.AccountIdsAllJaneWilson, // Banking + TokenType.MaryMoss => Constants.Accounts.Energy.AccountIdsAllMaryMoss, // Energy + TokenType.HeddaHare => Constants.Accounts.Energy.AccountIdsAllHeddaHare, // Energy TokenType.SteveKennedy => Constants.Accounts.AccountIdsAllSteveKennedy, TokenType.DewayneSteve => Constants.Accounts.AccountIdsAllDewayneSmith, TokenType.Business1 => Constants.Accounts.AccountIdsAllBusiness1, diff --git a/Source/ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation/Fixtures/BaseFixture.cs b/Source/ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation/Fixtures/BaseFixture.cs index f7a867e..7fb5144 100644 --- a/Source/ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation/Fixtures/BaseFixture.cs +++ b/Source/ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation/Fixtures/BaseFixture.cs @@ -1,15 +1,15 @@ -using ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation.Enums; -using ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation.Models.Options; -using Dapper; -using Dapper.Contrib.Extensions; -using Microsoft.Data.SqlClient; -using Microsoft.Extensions.DependencyInjection; -using Microsoft.Extensions.Options; -using Serilog; -using Xunit; - namespace ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation.Fixtures { + using ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation.Enums; + using ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation.Models.Options; + using Dapper; + using Dapper.Contrib.Extensions; + using Microsoft.Data.SqlClient; + using Microsoft.Extensions.DependencyInjection; + using Microsoft.Extensions.Options; + using Serilog; + using Xunit; + /// /// Patches Register SoftwareProduct RedirectURI and JwksURI. /// Stands up JWKS endpoint. @@ -25,7 +25,7 @@ public BaseFixture(IOptions options) _options = options?.Value ?? throw new ArgumentNullException(nameof(options)); } - public ServiceProvider ServiceProvider { get; private set; } + public ServiceProvider ServiceProvider { get; } public Task InitializeAsync() { @@ -40,12 +40,13 @@ public Task InitializeAsync() } // Stand-up JWKS endpoint - _jwksEndpoint = new JwksEndpoint(_options.SOFTWAREPRODUCT_JWKS_URI_FOR_INTEGRATION_TESTS, + _jwksEndpoint = new JwksEndpoint( + _options.SOFTWAREPRODUCT_JWKS_URI_FOR_INTEGRATION_TESTS, Constants.Certificates.JwtCertificateFilename, Constants.Certificates.JwtCertificatePassword); _jwksEndpoint.Start(); - //The Auth Server testing seeds specific data + // The Auth Server testing seeds specific data if (_options.IS_AUTH_SERVER) { CdrAuthServer_SeedDatabase(); @@ -59,12 +60,14 @@ public async Task DisposeAsync() Log.Information(Constants.LogTemplates.StartedFunctionInClass, nameof(DisposeAsync), nameof(BaseFixture)); if (_jwksEndpoint != null) + { await _jwksEndpoint.DisposeAsync(); + } } /// /// The seed data for the Register is using the loopback uri for jwksuri. - /// Since the integration tests stands up it's own data recipient jwks endpoint we need to + /// Since the integration tests stands up it's own data recipient jwks endpoint we need to /// patch the jwks uri to match our endpoint. /// private void Register_PatchScopes() @@ -101,7 +104,7 @@ private void CdrAuthServer_SeedDatabase() LegalEntityStatus = "ACTIVE", BrandId = Constants.Brands.BrandId, BrandName = "Mock Data Recipient Brand Name", - BrandStatus = "ACTIVE" + BrandStatus = "ACTIVE", }); connection.Insert(new SoftwareProduct() @@ -116,22 +119,32 @@ private void CdrAuthServer_SeedDatabase() LegalEntityStatus = "ACTIVE", BrandId = Constants.Brands.AdditionalBrandId, BrandName = "Finance X", - BrandStatus = "ACTIVE" + BrandStatus = "ACTIVE", }); } private class SoftwareProduct { public string? SoftwareProductId { get; set; } + public string? SoftwareProductName { get; set; } + public string? SoftwareProductDescription { get; set; } + public string? LogoUri { get; set; } + public string? Status { get; set; } + public string? LegalEntityId { get; set; } + public string? LegalEntityName { get; set; } + public string? LegalEntityStatus { get; set; } + public string? BrandId { get; set; } + public string? BrandName { get; set; } + public string? BrandStatus { get; set; } } } diff --git a/Source/ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation/Fixtures/PlaywrightFixture.cs b/Source/ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation/Fixtures/PlaywrightFixture.cs index 706a9cc..c67bbc6 100644 --- a/Source/ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation/Fixtures/PlaywrightFixture.cs +++ b/Source/ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation/Fixtures/PlaywrightFixture.cs @@ -1,8 +1,8 @@ -using Serilog; -using Xunit; - namespace ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation.Fixtures { + using Serilog; + using Xunit; + public class PlaywrightFixture : IAsyncLifetime { static private bool RUNNING_IN_CONTAINER => Environment.GetEnvironmentVariable("DOTNET_RUNNING_IN_CONTAINER")?.ToUpper() == "TRUE"; diff --git a/Source/ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation/Fixtures/RegisterSoftwareProductFixture.cs b/Source/ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation/Fixtures/RegisterSoftwareProductFixture.cs index 4d4c1a4..69fb6b5 100644 --- a/Source/ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation/Fixtures/RegisterSoftwareProductFixture.cs +++ b/Source/ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation/Fixtures/RegisterSoftwareProductFixture.cs @@ -1,14 +1,15 @@ -using ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation.Interfaces; -using ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation.Models.Options; -using Microsoft.Extensions.Options; -using Serilog; -using Xunit; - namespace ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation.Fixtures { + using ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation.Enums; + using ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation.Interfaces; + using ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation.Models.Options; + using Microsoft.Extensions.Options; + using Serilog; + using Xunit; + /// /// Purges DataHolders AuthServer database and registers software product - /// (in addition to operations performed by TestFixture) + /// (in addition to operations performed by TestFixture). /// public class RegisterSoftwareProductFixture : BaseFixture, IAsyncLifetime { @@ -41,7 +42,7 @@ public RegisterSoftwareProductFixture( Helpers.AuthServer.PurgeAuthServerForDataholder(_options); // Register software product - await _dataHolderRegisterService.RegisterSoftwareProduct(responseType: "code,code id_token"); + await _dataHolderRegisterService.RegisterSoftwareProduct(responseType: ResponseType.Code); } new public async Task DisposeAsync() @@ -49,7 +50,6 @@ public RegisterSoftwareProductFixture( Log.Information(Constants.LogTemplates.StartedFunctionInClass, nameof(DisposeAsync), nameof(RegisterSoftwareProductFixture)); await base.DisposeAsync(); - } } } diff --git a/Source/ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation/Helpers.cs b/Source/ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation/Helpers.cs index 8be96a4..57c3636 100644 --- a/Source/ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation/Helpers.cs +++ b/Source/ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation/Helpers.cs @@ -1,18 +1,18 @@ -using System.IdentityModel.Tokens.Jwt; -using System.Net; -using System.Net.Http.Headers; -using System.Security.Cryptography.X509Certificates; -using ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation.Extensions; -using ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation.Models; -using ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation.Models.Options; -using Jose; -using Microsoft.Data.SqlClient; -using Microsoft.IdentityModel.Tokens; -using Newtonsoft.Json; -using Serilog; - namespace ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation { + using System.IdentityModel.Tokens.Jwt; + using System.Net; + using System.Net.Http.Headers; + using System.Security.Cryptography.X509Certificates; + using ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation.Extensions; + using ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation.Models; + using ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation.Models.Options; + using Jose; + using Microsoft.Data.SqlClient; + using Microsoft.IdentityModel.Tokens; + using Newtonsoft.Json; + using Serilog; + public static class Helpers { public static class Web @@ -23,16 +23,17 @@ public static HttpClient CreateHttpClient(string? certFilename = null, string? c { AllowAutoRedirect = allowAutoRedirect, }; - clientHandler.ServerCertificateCustomValidationCallback += (sender, cert, chain, sslPolicyErrors) => true; //sonarqube will raise this as a vulnerability as it is not away this is a test library only + clientHandler.ServerCertificateCustomValidationCallback += (sender, cert, chain, sslPolicyErrors) => true; // sonarqube will raise this as a vulnerability as it is not away this is a test library only // Set cookie container if (cookieContainer != null) { if (cookies != null) { - throw new ArgumentOutOfRangeException(nameof(cookies),"Cookies and CookieContainer parameters cannot be provided at the same time.").Log(); + throw new ArgumentOutOfRangeException(nameof(cookies), "Cookies and CookieContainer parameters cannot be provided at the same time.").Log(); } - clientHandler.UseDefaultCredentials = true; //used with the Cookie Container + + clientHandler.UseDefaultCredentials = true; // used with the Cookie Container clientHandler.UseCookies = true; clientHandler.CookieContainer = cookieContainer; } @@ -42,7 +43,7 @@ public static HttpClient CreateHttpClient(string? certFilename = null, string? c { if (request == null) { - throw new ArgumentNullException(nameof(request),"Request parameter cannot be null when Cookies parameter has been provided.").Log(); + throw new ArgumentNullException(nameof(request), "Request parameter cannot be null when Cookies parameter has been provided.").Log(); } clientHandler.UseCookies = false; @@ -54,14 +55,13 @@ public static HttpClient CreateHttpClient(string? certFilename = null, string? c { if (certPassword == null) { - throw new ArgumentNullException(nameof(certPassword),"Certificate password parameter cannot be null when Certificate filename parameter has been provided.").Log(); + throw new ArgumentNullException(nameof(certPassword), "Certificate password parameter cannot be null when Certificate filename parameter has been provided.").Log(); } clientHandler.ClientCertificates.Add(new X509Certificate2( certFilename, certPassword, - X509KeyStorageFlags.Exportable - )); + X509KeyStorageFlags.Exportable)); } return new HttpClient(new LoggingHandler(clientHandler)); @@ -87,7 +87,7 @@ public static string CreateJWT(string certificateFilename, string certificatePas { { JwtHeaderParameterNames.Alg, SecurityAlgorithms.RsaSsaPssSha256 }, { JwtHeaderParameterNames.Typ, "JWT" }, - { JwtHeaderParameterNames.Kid, securityKey.KeyId}, + { JwtHeaderParameterNames.Kid, securityKey.KeyId }, }; var jwt = JWT.Encode(payload, cert.GetRSAPrivateKey(), JwsAlgorithm.PS256, jwtHeader); @@ -99,13 +99,14 @@ public static string CreateJWT(string certificateFilename, string certificatePas public static class Jwk { /// - /// Build JWKS from certificate + /// Build JWKS from certificate. /// + /// Jwks. public static Jwks BuildJWKS(string certificateFilename, string certificatePassword) { var cert = new X509Certificate2(certificateFilename, certificatePassword); - //Get credentials from certificate + // Get credentials from certificate var securityKey = new X509SecurityKey(cert); var signingCredentials = new X509SigningCredentials(cert, SecurityAlgorithms.RsaSsaPssSha256); var encryptingCredentials = new X509EncryptingCredentials(cert, SecurityAlgorithms.RsaOaepKeyWrap, SecurityAlgorithms.RsaOAEP); @@ -118,11 +119,12 @@ public static Jwks BuildJWKS(string certificateFilename, string certificatePassw { Alg = signingCredentials.Algorithm, Kid = signingCredentials.Kid, - // kid = signingCredentials.Key.KeyId, + + // kid = signingCredentials.Key.KeyId, Kty = securityKey.PublicKey.KeyExchangeAlgorithm, N = n, E = e, - Use = "sig" + Use = "sig", }; var jwkEnc = new Models.Jwk() @@ -132,12 +134,12 @@ public static Jwks BuildJWKS(string certificateFilename, string certificatePassw Kty = securityKey.PublicKey.KeyExchangeAlgorithm, N = n, E = e, - Use = "enc" + Use = "enc", }; return new Jwks() { - Keys = [jwkSign, jwkEnc] + Keys = [jwkSign, jwkEnc], }; } } @@ -167,10 +169,10 @@ static public void AttachHeadersForStandAlone(string url, HttpHeaders headers, s } /// - /// Clear data from the Dataholder's AuthServer database + /// Clear data from the Dataholder's AuthServer database. /// /// - /// Only clear the persisted grants table + /// Only clear the persisted grants table. public static void PurgeAuthServerForDataholder(TestAutomationOptions options, bool onlyPersistedGrants = false) { Log.Information(Constants.LogTemplates.StartedFunctionInClass, nameof(PurgeAuthServerForDataholder), nameof(Helpers.AuthServer)); @@ -212,7 +214,7 @@ void Purge(string table) /// /// The seed data for the Register is using the loopback uri for redirecturi. - /// Since the integration tests stands up it's own data recipient consent/callback endpoint we need to + /// Since the integration tests stands up it's own data recipient consent/callback endpoint we need to /// patch the redirect uri to match our callback. /// public static void PatchRedirectUriForRegister(TestAutomationOptions options, string softwareProductId = TestAutomation.Constants.SoftwareProducts.SoftwareProductId, string redirectURI = "") @@ -245,13 +247,11 @@ public static void PatchRedirectUriForRegister(TestAutomationOptions options, st { ex.LogAndThrow(); } - } - /// /// The seed data for the Register is using the loopback uri for jwksuri. - /// Since the integration tests stands up it's own data recipient jwks endpoint we need to + /// Since the integration tests stands up it's own data recipient jwks endpoint we need to /// patch the jwks uri to match our endpoint. /// public static void PatchJwksUriForRegister(TestAutomationOptions options, string softwareProductId = TestAutomation.Constants.SoftwareProducts.SoftwareProductId, string jwksURI = "") @@ -263,8 +263,8 @@ public static void PatchJwksUriForRegister(TestAutomationOptions options, string jwksURI = options.SOFTWAREPRODUCT_JWKS_URI_FOR_INTEGRATION_TESTS; } - try - { + try + { using var connection = new SqlConnection(options.REGISTER_CONNECTIONSTRING); connection.Open(); @@ -310,5 +310,4 @@ public static void UpdateAuthServerClientClaim(TestAutomationOptions options, st } } } - } \ No newline at end of file diff --git a/Source/ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation/Interfaces/IAccessTokenService.cs b/Source/ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation/Interfaces/IAccessTokenService.cs index c5a268c..9b1d80f 100644 --- a/Source/ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation/Interfaces/IAccessTokenService.cs +++ b/Source/ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation/Interfaces/IAccessTokenService.cs @@ -3,15 +3,25 @@ public interface IAccessTokenService { string Audience { get; init; } + string? CertificateFilename { get; set; } + string? CertificatePassword { get; set; } + string ClientAssertionType { get; init; } + string ClientId { get; init; } + string GrantType { get; init; } + string Issuer { get; init; } + string? JwtCertificateFilename { get; set; } + string? JwtCertificatePassword { get; set; } + string Scope { get; init; } + string URL { get; init; } Task GetAsync(string dhMtlsGatewayUrl, string xtlsClientCertThumbprint, bool isStandalone); diff --git a/Source/ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation/Interfaces/IApiService.cs b/Source/ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation/Interfaces/IApiService.cs index 7893836..318a2e3 100644 --- a/Source/ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation/Interfaces/IApiService.cs +++ b/Source/ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation/Interfaces/IApiService.cs @@ -1,25 +1,41 @@ -using System.Net.Http.Headers; - -namespace ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation.Interfaces +namespace ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation.Interfaces { + using System.Net.Http.Headers; + public interface IApiService { string? Accept { get; } + string? AccessToken { get; } + string? CertificateFilename { get; } + string? CertificatePassword { get; } + HttpContent? Content { get; } + MediaTypeHeaderValue? ContentType { get; } + IEnumerable? Cookies { get; } + string? DhMtlsGatewayUrl { get; } + HttpMethod? HttpMethod { get; } + string? IfNoneMatch { get; } + bool IsStandalone { get; } + string? URL { get; } + string? XFapiAuthDate { get; } + string? XFapiInteractionId { get; } + string? XMinV { get; } + string? XtlsClientCertificateThumbprint { get; } + string? XV { get; } Task SendAsync(bool allowAutoRedirect = true, string? xtlsThumbprint = null); diff --git a/Source/ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation/Interfaces/IApiServiceDirector.cs b/Source/ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation/Interfaces/IApiServiceDirector.cs index 605acdd..116d1be 100644 --- a/Source/ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation/Interfaces/IApiServiceDirector.cs +++ b/Source/ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation/Interfaces/IApiServiceDirector.cs @@ -1,23 +1,36 @@ -using ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation.Enums; -using ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation.Services; - -namespace ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation.Interfaces +namespace ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation.Interfaces { + using ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation.Enums; + using ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation.Services; + public interface IApiServiceDirector { ApiService BuildAuthServerAuthorizeAPI(Dictionary queryString); + ApiService BuildAuthServerJWKSAPI(); + ApiService BuildAuthServerOpenIdConfigurationAPI(); + ApiService BuildCustomerResourceAPI(string? accessToken); + ApiService BuildDataHolderDiscoveryStatusAPI(); + ApiService BuildDataHolderDiscoveryOutagesAPI(); + ApiService BuildDataHolderBankingGetAccountsAPI(string? accessToken, string? xFapiAuthDate, string? xv = "2", string? xFapiInteractionId = null, string certFileName = Constants.Certificates.CertificateFilename, string certPassword = Constants.Certificates.CertificatePassword, string? url = null); + ApiService BuildDataHolderBankingGetTransactionsAPI(string? accessToken, string? xFapiAuthDate, string? encryptedAccountId = null, string? xv = "1", string? xFapiInteractionId = null, string certFileName = Constants.Certificates.CertificateFilename, string certPassword = Constants.Certificates.CertificatePassword, string? url = null); + ApiService BuildDataHolderCommonGetCustomerAPI(string? accessToken, string? xFapiAuthDate, string? xv = "1", string certFileName = Constants.Certificates.CertificateFilename, string certPassword = Constants.Certificates.CertificatePassword); + ApiService BuildDataholderRegisterAPI(string? accessToken, string? registrationRequest, HttpMethod? httpMethod, string clientId = ""); + ApiService BuildRegisterSSAAPI(Industry? industry, string brandId, string softwareProductId, string? accessToken, string? xv); + ApiService BuildUserInfoAPI(string? xv, string? accessToken, string? thumbprint, HttpMethod? httpMethod, string certFilename = Constants.Certificates.CertificateFilename, string certPassword = Constants.Certificates.CertificatePassword); + ApiService BuildDataHolderEnergyGetAccountsAPI(string? accessToken, string? xFapiAuthDate, string? xv = "1", string? xMinV = null, string? xFapiInteractionId = null, string certFileName = Constants.Certificates.CertificateFilename, string certPassword = Constants.Certificates.CertificatePassword, string? url = null); + ApiService BuildDataHolderEnergyGetConcessionsAPI(string? accessToken, string? xFapiAuthDate, string? encryptedAccountId = null, string? xv = "1", string certFileName = Constants.Certificates.CertificateFilename, string certPassword = Constants.Certificates.CertificatePassword, string? url = null); } } diff --git a/Source/ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation/Interfaces/ICdrValidationException.cs b/Source/ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation/Interfaces/ICdrValidationException.cs index 8f26d67..301ffc5 100644 --- a/Source/ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation/Interfaces/ICdrValidationException.cs +++ b/Source/ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation/Interfaces/ICdrValidationException.cs @@ -1,7 +1,7 @@ -using System.ComponentModel.DataAnnotations; - -namespace ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation.Interfaces +namespace ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation.Interfaces { + using System.ComponentModel.DataAnnotations; + public interface ICdrValidationException { List Items { get; set; } diff --git a/Source/ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation/Interfaces/IDataHolderAccessTokenCache.cs b/Source/ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation/Interfaces/IDataHolderAccessTokenCache.cs index e9b362d..9f494a3 100644 --- a/Source/ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation/Interfaces/IDataHolderAccessTokenCache.cs +++ b/Source/ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation/Interfaces/IDataHolderAccessTokenCache.cs @@ -1,14 +1,15 @@ -using ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation.Enums; - -namespace ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation.Interfaces +namespace ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation.Interfaces { + using ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation.Enums; + public interface IDataHolderAccessTokenCache { int Hits { get; } + int Misses { get; } void ClearCache(); - Task GetAccessToken(TokenType tokenType, string? scope = null, bool useCache = true, ResponseType responseType = ResponseType.Code, ResponseMode responseMode = ResponseMode.Jwt); + Task GetAccessToken(TokenType tokenType, string? scope = null, bool useCache = true, ResponseType responseType = ResponseType.Code, ResponseMode responseMode = ResponseMode.Jwt); } } \ No newline at end of file diff --git a/Source/ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation/Interfaces/IDataHolderAuthoriseService.cs b/Source/ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation/Interfaces/IDataHolderAuthoriseService.cs index 2857266..eda78df 100644 --- a/Source/ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation/Interfaces/IDataHolderAuthoriseService.cs +++ b/Source/ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation/Interfaces/IDataHolderAuthoriseService.cs @@ -1,27 +1,43 @@ -using ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation.Enums; - -namespace ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation.Interfaces +namespace ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation.Interfaces { + using ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation.Enums; + public interface IDataHolderAuthoriseService { string? CdrArrangementId { get; } + string CertificateFilename { get; } + string CertificatePassword { get; } + string ClientId { get; } + string JwtCertificateFilename { get; } + string JwtCertificatePassword { get; } + string OTP { get; } + string RedirectURI { get; } + string? RequestUri { get; } + ResponseMode ResponseMode { get; } + ResponseType ResponseType { get; } + string Scope { get; } + string? SelectedAccountIds { get; } + int? SharingDuration { get; } + int TokenLifetime { get; } + string UserId { get; } Task<(string authCode, string idToken)> Authorise(); + Task AuthoriseForJarm(); } } \ No newline at end of file diff --git a/Source/ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation/Interfaces/IDataHolderParService.cs b/Source/ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation/Interfaces/IDataHolderParService.cs index 897a441..f9e6616 100644 --- a/Source/ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation/Interfaces/IDataHolderParService.cs +++ b/Source/ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation/Interfaces/IDataHolderParService.cs @@ -1,12 +1,14 @@ -using ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation.Enums; -using static ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation.Services.DataHolderParService; - -namespace ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation.Interfaces +namespace ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation.Interfaces { + using ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation.Enums; + using static ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation.Services.DataHolderParService; + public interface IDataHolderParService { Task GetRequestUri(string? scope, string? clientId = null, string jwtCertificateForClientAssertionFilename = Constants.Certificates.JwtCertificateFilename, string jwtCertificateForClientAssertionPassword = Constants.Certificates.JwtCertificatePassword, string jwtCertificateForRequestObjectFilename = Constants.Certificates.JwtCertificateFilename, string jwtCertificateForRequestObjectPassword = Constants.Certificates.JwtCertificatePassword, string? redirectUri = null, int? sharingDuration = Constants.AuthServer.SharingDuration, string? cdrArrangementId = null, ResponseType responseType = ResponseType.Code, ResponseMode responseMode = ResponseMode.Jwt); + Task SendRequest(string? scope, string? clientId = null, string clientAssertionType = Constants.ClientAssertionType, int? sharingDuration = Constants.AuthServer.SharingDuration, string? aud = null, int nbfOffsetSeconds = 0, int expOffsetSeconds = 0, bool addRequestObject = true, bool addNotBeforeClaim = true, bool addExpiryClaim = true, string? cdrArrangementId = null, string? redirectUri = null, string? clientAssertion = null, string codeVerifier = Constants.AuthServer.FapiPhase2CodeVerifier, string codeChallengeMethod = Constants.AuthServer.FapiPhase2CodeChallengeMethod, string? requestUri = null, ResponseMode? responseMode = ResponseMode.Jwt, string certificateFilename = Constants.Certificates.CertificateFilename, string certificatePassword = Constants.Certificates.CertificatePassword, string jwtCertificateForClientAssertionFilename = Constants.Certificates.JwtCertificateFilename, string jwtCertificateForClientAssertionPassword = Constants.Certificates.JwtCertificatePassword, string jwtCertificateForRequestObjectFilename = Constants.Certificates.JwtCertificateFilename, string jwtCertificateForRequestObjectPassword = Constants.Certificates.JwtCertificatePassword, ResponseType? responseType = ResponseType.Code, string? state = null); + Task DeserializeResponse(HttpResponseMessage response); } } \ No newline at end of file diff --git a/Source/ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation/Interfaces/IDataHolderRegisterService.cs b/Source/ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation/Interfaces/IDataHolderRegisterService.cs index c261a8d..d8208ec 100644 --- a/Source/ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation/Interfaces/IDataHolderRegisterService.cs +++ b/Source/ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation/Interfaces/IDataHolderRegisterService.cs @@ -1,27 +1,33 @@ -using Microsoft.IdentityModel.Tokens; - -namespace ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation.Interfaces +namespace ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation.Interfaces { + using ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation.Enums; + using Microsoft.IdentityModel.Tokens; + public interface IDataHolderRegisterService { - string CreateRegistrationRequest(string ssa, - string tokenEndpointAuthSigningAlg = SecurityAlgorithms.RsaSsaPssSha256, - string[]? redirectUris = null, - string jwtCertificateFilename = Constants.Certificates.JwtCertificateFilename, - string jwtCertificatePassword = Constants.Certificates.JwtCertificatePassword, - string applicationType = "web", - string requestObjectSigningAlg = SecurityAlgorithms.RsaSsaPssSha256, - string responseType = "code id_token", - string[]? grantTypes = null, - string? authorizationSignedResponseAlg = "PS256", - string? authorizationEncryptedResponseAlg = null, - string? authorizationEncryptedResponseEnc = null, - string? idTokenSignedResponseAlg = "PS256", - string? idTokenEncryptedResponseAlg = "RSA-OAEP", - string? idTokenEncryptedResponseEnc = "A256GCM"); + string CreateRegistrationRequest( + string ssa, + string tokenEndpointAuthSigningAlg = SecurityAlgorithms.RsaSsaPssSha256, + string[]? redirectUris = null, + string jwtCertificateFilename = Constants.Certificates.JwtCertificateFilename, + string jwtCertificatePassword = Constants.Certificates.JwtCertificatePassword, + string applicationType = "web", + string requestObjectSigningAlg = SecurityAlgorithms.RsaSsaPssSha256, + ResponseType responseType = ResponseType.Code, + string[]? grantTypes = null, + string? authorizationSignedResponseAlg = "PS256", + string? authorizationEncryptedResponseAlg = null, + string? authorizationEncryptedResponseEnc = null, + string? idTokenSignedResponseAlg = "PS256"); Task RegisterSoftwareProduct(string registrationRequest); - Task<(string ssa, string registration, string clientId)> RegisterSoftwareProduct(string brandId = Constants.Brands.BrandId, string softwareProductId = Constants.SoftwareProducts.SoftwareProductId, string jwtCertificateFilename = Constants.Certificates.JwtCertificateFilename, string jwtCertificatePassword = Constants.Certificates.JwtCertificatePassword, string responseType = "code,code id_token", string authorizationSignedResponseAlg = SecurityAlgorithms.RsaSsaPssSha256); + Task<(string ssa, string registration, string clientId)> RegisterSoftwareProduct( + string brandId = Constants.Brands.BrandId, + string softwareProductId = Constants.SoftwareProducts.SoftwareProductId, + string jwtCertificateFilename = Constants.Certificates.JwtCertificateFilename, + string jwtCertificatePassword = Constants.Certificates.JwtCertificatePassword, + ResponseType responseType = ResponseType.Code, + string authorizationSignedResponseAlg = SecurityAlgorithms.RsaSsaPssSha256); } } \ No newline at end of file diff --git a/Source/ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation/Interfaces/IDataHolderTokenService.cs b/Source/ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation/Interfaces/IDataHolderTokenService.cs index 6d3de7e..9c6cc0a 100644 --- a/Source/ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation/Interfaces/IDataHolderTokenService.cs +++ b/Source/ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation/Interfaces/IDataHolderTokenService.cs @@ -1,13 +1,17 @@ -using ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation.Models.Dataholders; - -namespace ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation.Interfaces +namespace ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation.Interfaces { + using ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation.Models.Dataholders; + public interface IDataHolderTokenService { Task GetAccessToken(string authCode); + Task GetResponse(string authCode, int? shareDuration = null, string? clientId = null, string? redirectUri = null, string certificateFilename = Constants.Certificates.CertificateFilename, string certificatePassword = Constants.Certificates.CertificatePassword, string jwkCertificateFilename = Constants.Certificates.JwtCertificateFilename, string jwkCertificatePassword = Constants.Certificates.JwtCertificatePassword, string? scope = null); + Task SendRequest(string? authCode = null, bool usePut = false, string grantType = "authorization_code", string? clientId = null, string? issuerClaim = null, string clientAssertionType = Constants.ClientAssertionType, bool useClientAssertion = true, int? shareDuration = null, string? refreshToken = null, string? customClientAssertion = null, string? scope = null, string? redirectUri = null, string certificateFilename = Constants.Certificates.CertificateFilename, string certificatePassword = Constants.Certificates.CertificatePassword, string jwkCertificateFilename = Constants.Certificates.JwtCertificateFilename, string jwkCertificatePassword = Constants.Certificates.JwtCertificatePassword); + Task DeserializeResponse(HttpResponseMessage response); + Task GetResponseUsingRefreshToken(string? refreshToken, string? scope = null); } } \ No newline at end of file diff --git a/Source/ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation/Interfaces/IPrivateKeyJwtService.cs b/Source/ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation/Interfaces/IPrivateKeyJwtService.cs index 4f5c07b..224d949 100644 --- a/Source/ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation/Interfaces/IPrivateKeyJwtService.cs +++ b/Source/ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation/Interfaces/IPrivateKeyJwtService.cs @@ -3,9 +3,13 @@ public interface IPrivateKeyJwtService { string Audience { get; set; } + string CertificateFilename { get; set; } + string CertificatePassword { get; set; } + string Issuer { get; set; } + bool RequireIssuer { get; init; } string Generate(); diff --git a/Source/ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation/Interfaces/IRegisterSSAService.cs b/Source/ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation/Interfaces/IRegisterSSAService.cs index c081a97..dca4ff0 100644 --- a/Source/ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation/Interfaces/IRegisterSSAService.cs +++ b/Source/ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation/Interfaces/IRegisterSSAService.cs @@ -1,7 +1,7 @@ -using ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation.Enums; - -namespace ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation.Interfaces +namespace ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation.Interfaces { + using ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation.Enums; + public interface IRegisterSsaService { Task GetSSA(string brandId, string softwareProductId, string xv = "3", string jwtCertificateFilename = Constants.Certificates.JwtCertificateFilename, string jwtCertificatePassword = Constants.Certificates.JwtCertificatePassword, Industry? industry = null); diff --git a/Source/ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation/Interfaces/ISqlQueryService.cs b/Source/ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation/Interfaces/ISqlQueryService.cs index cbbaaac..03eb757 100644 --- a/Source/ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation/Interfaces/ISqlQueryService.cs +++ b/Source/ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation/Interfaces/ISqlQueryService.cs @@ -1,11 +1,13 @@ -using ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation.Enums; - -namespace ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation.Interfaces +namespace ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation.Interfaces { + using ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation.Enums; + public interface ISqlQueryService { string GetClientId(string softwareProductId); + string GetStatus(EntityType entityType, string id); + void SetStatus(EntityType entityType, string id, string status); } } \ No newline at end of file diff --git a/Source/ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation/JwksEndpoint.cs b/Source/ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation/JwksEndpoint.cs index 2ea89d0..bee81e2 100644 --- a/Source/ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation/JwksEndpoint.cs +++ b/Source/ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation/JwksEndpoint.cs @@ -1,16 +1,17 @@ -using Microsoft.AspNetCore.Builder; -using Microsoft.AspNetCore.Hosting; -using Microsoft.AspNetCore.Http; -using Microsoft.Extensions.DependencyInjection; -using Microsoft.Extensions.Hosting; -using Serilog; - namespace ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation { + using Microsoft.AspNetCore.Builder; + using Microsoft.AspNetCore.Hosting; + using Microsoft.AspNetCore.Http; + using Microsoft.Extensions.DependencyInjection; + using Microsoft.Extensions.Hosting; + using Serilog; + public partial class JwksEndpoint : IAsyncDisposable { /// - /// Emulate a JWKS endpoint on url returning a JWKS for the given certificate + /// Initializes a new instance of the class. + /// Emulate a JWKS endpoint on url returning a JWKS for the given certificate. /// public JwksEndpoint(string url, string certificateFilename, string certificatePassword) { @@ -20,9 +21,13 @@ public JwksEndpoint(string url, string certificateFilename, string certificatePa } public string Url { get; init; } + private string Url_PathAndQuery => new Uri(Url).PathAndQuery; + private int UrlPort => new Uri(Url).Port; + public string CertificateFilename { get; init; } + public string CertificatePassword { get; init; } private IWebHost? _host; @@ -36,7 +41,7 @@ public void Start() { opts.ListenAnyIP(UrlPort, opts => opts.UseHttps()); // This will use the default developer certificate. Use "dotnet dev-certs https" to install if necessary }) - .UseStartup(_ => new JWKSCallback_Startup(this)) + .UseStartup(_ => new JwksCallback_Startup(this)) .Build(); _host.RunAsync(); @@ -53,6 +58,7 @@ public async Task Stop() } bool _disposed; + public async ValueTask DisposeAsync() { Log.Information(Constants.LogTemplates.StartedFunctionInClass, nameof(DisposeAsync), nameof(JwksEndpoint)); @@ -66,18 +72,18 @@ public async ValueTask DisposeAsync() GC.SuppressFinalize(this); } - class JWKSCallback_Startup + class JwksCallback_Startup { private JwksEndpoint Endpoint { get; init; } - public JWKSCallback_Startup(JwksEndpoint endpoint) + public JwksCallback_Startup(JwksEndpoint endpoint) { Endpoint = endpoint; } /// /// This is used by the JWKS endpoint for Startup - /// NOTE: You may see warnings about 0 references to this function, but it is used 'automatically' as part of the startup process + /// NOTE: You may see warnings about 0 references to this function, but it is used 'automatically' as part of the startup process. /// /// public void Configure(IApplicationBuilder app) @@ -97,7 +103,7 @@ public void Configure(IApplicationBuilder app) /// /// This is used by the JWKS endpoint for Startup - /// NOTE: You may see warnings about 0 references to this function, but it is used 'automatically' as part of the startup process + /// NOTE: You may see warnings about 0 references to this function, but it is used 'automatically' as part of the startup process. /// /// public static void ConfigureServices(IServiceCollection services) diff --git a/Source/ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation/KeyValuePairBuilder.cs b/Source/ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation/KeyValuePairBuilder.cs index 8a1d9d9..315d5eb 100644 --- a/Source/ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation/KeyValuePairBuilder.cs +++ b/Source/ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation/KeyValuePairBuilder.cs @@ -1,23 +1,25 @@ -using System.Text; - -namespace ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation +namespace ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation { + using System.Text; + /// - /// Key/Value pair builder + /// Key/Value pair builder. /// public class KeyValuePairBuilder { private readonly string _delimiter; private readonly StringBuilder _sb = new StringBuilder(); + /// - /// Get key/value pairs as string + /// Get key/value pairs as string. /// public string Value => _sb.ToString(); private int _count = 0; + /// - /// Number of key/value pairs + /// Number of key/value pairs. /// public int Count => _count; @@ -27,10 +29,10 @@ public KeyValuePairBuilder(string delimiter = "&") } /// - /// Append key/value pair + /// Append key/value pair. /// - /// Key to add - /// Value to add + /// Key to add. + /// Value to add. public void Add(string key, string value) { if (_sb.Length > 0) @@ -44,20 +46,20 @@ public void Add(string key, string value) } /// - /// Add key/value pair + /// Add key/value pair. /// - /// Key to add - /// Value to add + /// Key to add. + /// Value to add. public void Add(string key, int value) { Add(key, value.ToString()); } /// - /// Add key/value pair + /// Add key/value pair. /// - /// Key to add - /// Value to add + /// Key to add. + /// Value to add. public void Add(string key, long value) { Add(key, value.ToString()); diff --git a/Source/ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation/LoggingHandler.cs b/Source/ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation/LoggingHandler.cs index c68ba9f..491078e 100644 --- a/Source/ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation/LoggingHandler.cs +++ b/Source/ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation/LoggingHandler.cs @@ -1,7 +1,7 @@ -using Serilog; - -namespace ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation +namespace ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation { + using Serilog; + public class LoggingHandler : DelegatingHandler { public LoggingHandler(HttpMessageHandler innerHandler) diff --git a/Source/ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation/Models/AccessToken.cs b/Source/ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation/Models/AccessToken.cs index 4a6fac3..044ea4c 100644 --- a/Source/ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation/Models/AccessToken.cs +++ b/Source/ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation/Models/AccessToken.cs @@ -1,18 +1,21 @@ -using Newtonsoft.Json; - -namespace ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation.Models +namespace ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation.Models { + using Newtonsoft.Json; + /// - /// Access token + /// Access token. /// public class AccessToken { [JsonProperty("access_token")] public string Token { get; set; } + [JsonProperty("expires_in")] public int ExpiresIn { get; set; } + [JsonProperty("token_type")] public string TokenType { get; set; } + [JsonProperty(nameof(Scope))] public string Scope { get; set; } } diff --git a/Source/ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation/Models/AuthError.cs b/Source/ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation/Models/AuthError.cs index e178559..f8ac3bf 100644 --- a/Source/ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation/Models/AuthError.cs +++ b/Source/ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation/Models/AuthError.cs @@ -1,9 +1,9 @@ -using Newtonsoft.Json; - -namespace ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation.Models +namespace ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation.Models { + using Newtonsoft.Json; + /// - /// This error is used for deserializing errors that we get during the authetication process, so that we can check the properties against exceptions instead of hard-coded strings + /// This error is used for deserializing errors that we get during the authetication process, so that we can check the properties against exceptions instead of hard-coded strings. /// public class AuthError { diff --git a/Source/ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation/Models/CdrErrorAttribute.cs b/Source/ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation/Models/CdrErrorAttribute.cs index 340b0b6..0347c2b 100644 --- a/Source/ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation/Models/CdrErrorAttribute.cs +++ b/Source/ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation/Models/CdrErrorAttribute.cs @@ -1,7 +1,7 @@ -using System; - -namespace ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation.Models +namespace ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation.Models { + using System; + [AttributeUsage(AttributeTargets.Field, Inherited = false, AllowMultiple = false)] public class CdrErrorAttribute : Attribute { diff --git a/Source/ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation/Models/DataRecipientBrand.cs b/Source/ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation/Models/DataRecipientBrand.cs index ffc9b77..1dff495 100644 --- a/Source/ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation/Models/DataRecipientBrand.cs +++ b/Source/ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation/Models/DataRecipientBrand.cs @@ -1,19 +1,22 @@ -using Newtonsoft.Json; - -namespace ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation.Models +namespace ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation.Models { + using Newtonsoft.Json; + public class DataRecipientBrand { [JsonProperty("dataRecipientBrandId")] public string DataRecipientBrandId { get; set; } + [JsonProperty("brandName")] public string BrandName { get; set; } + [JsonProperty("logoUri")] public string LogoUri { get; set; } + [JsonProperty("status")] public string Status { get; set; } + [JsonProperty("softwareProducts")] public List SoftwareProducts { get; set; } } - } diff --git a/Source/ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation/Models/Dataholders/Banking/Accounts/BankingAccountV2.cs b/Source/ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation/Models/Dataholders/Banking/Accounts/BankingAccountV2.cs index 5d9b7fd..7219072 100644 --- a/Source/ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation/Models/Dataholders/Banking/Accounts/BankingAccountV2.cs +++ b/Source/ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation/Models/Dataholders/Banking/Accounts/BankingAccountV2.cs @@ -1,7 +1,6 @@ -using Newtonsoft.Json; - namespace ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation.Models.Dataholders.Banking.Accounts { + using Newtonsoft.Json; public class BankingAccountV2 { @@ -10,48 +9,57 @@ public class BankingAccountV2 /// [JsonProperty("accountId", Required = Required.Always)] public string AccountId { get; set; } + /// /// Date that the account was created (if known). /// [JsonProperty("creationDate")] public string? CreationDate { get; set; } + /// - /// The display name of the account as defined by the bank. This should not incorporate account numbers or PANs. + /// The display name of the account as defined by the bank. This should not incorporate account numbers or PANs. /// If it does the values should be masked according to the rules of the MaskedAccountString common type. /// [JsonProperty("displayName", Required = Required.Always)] public string DisplayName { get; set; } + /// /// A customer supplied nick name for the account. /// [JsonProperty("nickname")] public string? Nickname { get; set; } + /// /// Open or closed status for the account. If not present then OPEN is assumed. /// [JsonProperty("openStatus")] public string? OpenStatus { get; set; } + /// /// Flag indicating that the customer associated with the authorisation is an owner of the account. Does not indicate sole ownership, however. If not present then 'true' is assumed. /// [JsonProperty("isOwned")] public bool? IsOwned { get; set; } + /// /// Value indicating the number of customers that have ownership of the account, according to the data holder's definition of account ownership. /// Does not indicate that all account owners are eligible consumers. /// - [JsonProperty("accountOwnership")] - public string AccountOwnership { get; set; } + [JsonProperty("accountOwnership")] + public string AccountOwnership { get; set; } + /// - /// A masked version of the account. Whether BSB/Account Number, Credit Card PAN or another number + /// A masked version of the account. Whether BSB/Account Number, Credit Card PAN or another number. /// [JsonProperty("maskedNumber", Required = Required.Always)] public string MaskedNumber { get; set; } + /// /// The category to which a product or account belongs. /// [JsonProperty("productCategory", Required = Required.Always)] public string ProductCategory { get; set; } + /// /// The unique identifier of the account as defined by the data holder (akin to model number for the account). /// diff --git a/Source/ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation/Models/Dataholders/Banking/Accounts/Data.cs b/Source/ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation/Models/Dataholders/Banking/Accounts/Data.cs index f2b9735..dc4e8a5 100644 --- a/Source/ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation/Models/Dataholders/Banking/Accounts/Data.cs +++ b/Source/ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation/Models/Dataholders/Banking/Accounts/Data.cs @@ -1,11 +1,11 @@ -using Newtonsoft.Json; - -namespace ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation.Models.Dataholders.Banking.Accounts +namespace ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation.Models.Dataholders.Banking.Accounts { + using Newtonsoft.Json; + public class Data { /// - /// Array of accounts + /// Array of accounts. /// [JsonProperty("accounts", Required = Required.Always)] public BankingAccountV2[]? Accounts { get; set; } diff --git a/Source/ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation/Models/Dataholders/Banking/Accounts/ResponseBankingAccountListV2.cs b/Source/ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation/Models/Dataholders/Banking/Accounts/ResponseBankingAccountListV2.cs index 29116f7..76379b2 100644 --- a/Source/ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation/Models/Dataholders/Banking/Accounts/ResponseBankingAccountListV2.cs +++ b/Source/ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation/Models/Dataholders/Banking/Accounts/ResponseBankingAccountListV2.cs @@ -1,7 +1,7 @@ -using Newtonsoft.Json; - -namespace ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation.Models.Dataholders.Banking.Accounts +namespace ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation.Models.Dataholders.Banking.Accounts { + using Newtonsoft.Json; + public class ResponseBankingAccountListV2 { [JsonProperty("data", Required = Required.Always)] diff --git a/Source/ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation/Models/Dataholders/Banking/Transactions/BankingTransaction.cs b/Source/ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation/Models/Dataholders/Banking/Transactions/BankingTransaction.cs index 41e5e21..0d77942 100644 --- a/Source/ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation/Models/Dataholders/Banking/Transactions/BankingTransaction.cs +++ b/Source/ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation/Models/Dataholders/Banking/Transactions/BankingTransaction.cs @@ -1,101 +1,118 @@ -using Newtonsoft.Json; - -namespace ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation.Models.Dataholders.Banking.Transactions +namespace ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation.Models.Dataholders.Banking.Transactions { + using Newtonsoft.Json; + public class BankingTransaction { /// - /// ID of the account for which transactions are provided + /// ID of the account for which transactions are provided. /// [JsonProperty("accountId", Required = Required.Always)] public string AccountId { get; set; } + /// - /// A unique ID of the transaction adhering to the standards for ID permanence. - /// This is mandatory (through hashing if necessary) unless there are specific and justifiable technical reasons why a transaction cannot be uniquely identified for a particular account type. + /// A unique ID of the transaction adhering to the standards for ID permanence. + /// This is mandatory (through hashing if necessary) unless there are specific and justifiable technical reasons why a transaction cannot be uniquely identified for a particular account type. /// It is mandatory if isDetailAvailable is set to true. /// [JsonProperty("transactionId")] public string? TransactionId { get; set; } + /// /// True if extended information is available using the transaction detail end point. False if extended data is not available. /// [JsonProperty("isDetailAvailable", Required = Required.Always)] public bool IsDetailAvailable { get; set; } + /// - /// The type of the transaction + /// The type of the transaction. /// [JsonProperty("type", Required = Required.Always)] public string Type { get; set; } + /// - /// Status of the transaction whether pending or posted. + /// Status of the transaction whether pending or posted. /// Note that there is currently no provision in the standards to guarantee the ability to correlate a pending transaction with an associated posted transaction. /// [JsonProperty("status", Required = Required.Always)] public string Status { get; set; } + /// /// The transaction description as applied by the financial institution. /// [JsonProperty("description", Required = Required.Always)] public string Description { get; set; } + /// - /// The time the transaction was posted. + /// The time the transaction was posted. /// This field is Mandatory if the transaction has status POSTED. This is the time that appears on a standard statement. /// [JsonProperty("postingDateTime")] public string? PostingDateTime { get; set; } + /// /// Date and time at which assets become available to the account owner in case of a credit entry, or cease to be available to the account owner in case of a debit transaction entry. /// [JsonProperty("valueDateTime")] public string? ValueDateTime { get; set; } + /// /// The time the transaction was executed by the originating customer, if available. /// [JsonProperty("executionDateTime")] public string? ExecutionDateTime { get; set; } + /// /// The value of the transaction. Negative values mean money was outgoing from the account. /// [JsonProperty("amount", Required = Required.Always)] public string Amount { get; set; } + /// /// The currency for the transaction amount. AUD assumed if not present. /// [JsonProperty("currency")] public string? Currency { get; set; } + /// /// The reference for the transaction provided by the originating institution. Empty string if no data provided. /// [JsonProperty("reference", Required = Required.Always)] public string Reference { get; set; } + /// /// Name of the merchant for an outgoing payment to a merchant. /// [JsonProperty("merchantName")] public string? MerchantName { get; set; } + /// /// The merchant category code (or MCC) for an outgoing payment to a merchant. /// [JsonProperty("merchantCategoryCode")] public string? MerchantCategoryCode { get; set; } + /// /// BPAY Biller Code for the transaction (if available). /// [JsonProperty("billerCode")] public string? BillerCode { get; set; } + /// - /// Name of the BPAY biller for the transaction (if available) + /// Name of the BPAY biller for the transaction (if available). /// [JsonProperty("billerName")] public string? BillerName { get; set; } + /// - /// BPAY CRN for the transaction (if available). + /// BPAY CRN for the transaction (if available). /// Where the CRN contains sensitive information, it should be masked in line with how the Data Holder currently displays account identifiers in their existing online banking channels. /// If the contents of the CRN match the format of a Credit Card PAN they should be masked according to the rules applicable for MaskedPANString. /// If the contents are otherwise sensitive, then it should be masked using the rules applicable for the MaskedAccountString common type. /// [JsonProperty("crn")] public string? Crn { get; set; } + /// /// 6 Digit APCA number for the initiating institution. The field is fixed-width and padded with leading zeros if applicable. /// diff --git a/Source/ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation/Models/Dataholders/Banking/Transactions/Data.cs b/Source/ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation/Models/Dataholders/Banking/Transactions/Data.cs index 917395a..f8405a6 100644 --- a/Source/ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation/Models/Dataholders/Banking/Transactions/Data.cs +++ b/Source/ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation/Models/Dataholders/Banking/Transactions/Data.cs @@ -1,11 +1,11 @@ -using Newtonsoft.Json; - -namespace ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation.Models.Dataholders.Banking.Transactions +namespace ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation.Models.Dataholders.Banking.Transactions { + using Newtonsoft.Json; + public class Data { /// - /// Array of transactions + /// Array of transactions. /// [JsonProperty("transactions", Required = Required.Always)] public BankingTransaction[] Transactions { get; set; } diff --git a/Source/ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation/Models/Dataholders/Banking/Transactions/ResponseBankingTransactionListV2.cs b/Source/ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation/Models/Dataholders/Banking/Transactions/ResponseBankingTransactionListV2.cs index 364afd2..72f2c0c 100644 --- a/Source/ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation/Models/Dataholders/Banking/Transactions/ResponseBankingTransactionListV2.cs +++ b/Source/ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation/Models/Dataholders/Banking/Transactions/ResponseBankingTransactionListV2.cs @@ -1,7 +1,7 @@ -using Newtonsoft.Json; - -namespace ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation.Models.Dataholders.Banking.Transactions +namespace ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation.Models.Dataholders.Banking.Transactions { + using Newtonsoft.Json; + public class ResponseBankingTransactionListV2 { [JsonProperty("data", Required = Required.Always)] diff --git a/Source/ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation/Models/Dataholders/Energy/Data.cs b/Source/ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation/Models/Dataholders/Energy/Data.cs index 153b1eb..6370bad 100644 --- a/Source/ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation/Models/Dataholders/Energy/Data.cs +++ b/Source/ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation/Models/Dataholders/Energy/Data.cs @@ -1,11 +1,11 @@ -using Newtonsoft.Json; - -namespace ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation.Models.Dataholders.Energy +namespace ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation.Models.Dataholders.Energy { + using Newtonsoft.Json; + public class Data { /// - /// Array of accounts + /// Array of accounts. /// [JsonProperty("accounts", Required = Required.Always)] public EnergyAccountV2[] Accounts { get; set; } diff --git a/Source/ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation/Models/Dataholders/Energy/EnergyAccountV2.cs b/Source/ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation/Models/Dataholders/Energy/EnergyAccountV2.cs index ff98f2d..7311a41 100644 --- a/Source/ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation/Models/Dataholders/Energy/EnergyAccountV2.cs +++ b/Source/ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation/Models/Dataholders/Energy/EnergyAccountV2.cs @@ -1,8 +1,8 @@ -using System.ComponentModel.DataAnnotations; -using Newtonsoft.Json; - namespace ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation.Models.Dataholders.Energy { + using System.ComponentModel.DataAnnotations; + using Newtonsoft.Json; + public class EnergyAccountV2 { /// @@ -10,28 +10,33 @@ public class EnergyAccountV2 /// [JsonProperty("accountId", Required = Required.Always)] public string AccountId { get; set; } + /// - /// Optional identifier of the account as defined by the data holder. + /// Optional identifier of the account as defined by the data holder. /// This must be the value presented on physical statements (if it exists) and must not be used for the value of accountId. /// [JsonProperty("accountNumber")] public string? AccountNumber { get; set; } + /// - /// The date that the account was created or opened. Mandatory if openStatus is OPEN + /// The date that the account was created or opened. Mandatory if openStatus is OPEN. /// [JsonProperty("creationDate")] public string? CreationDate { get; set; } + /// - /// An optional display name for the account if one exists or can be derived. + /// An optional display name for the account if one exists or can be derived. /// The content of this field is at the discretion of the data holder. /// [JsonProperty("displayName")] public string? DisplayName { get; set; } + /// /// Open or closed status for the account. If not present then OPEN is assumed. /// [JsonProperty("openStatus")] public string? OpenStatus { get; set; } + /// /// The array of plans containing service points and associated plan details. /// diff --git a/Source/ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation/Models/Dataholders/Energy/Plan.cs b/Source/ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation/Models/Dataholders/Energy/Plan.cs index 76c0097..6e550a9 100644 --- a/Source/ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation/Models/Dataholders/Energy/Plan.cs +++ b/Source/ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation/Models/Dataholders/Energy/Plan.cs @@ -1,9 +1,9 @@ -using Newtonsoft.Json; - -namespace ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation.Models.Dataholders.Energy +namespace ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation.Models.Dataholders.Energy { + using Newtonsoft.Json; + /// - /// Used by Energy Accounts + /// Used by Energy Accounts. /// public class Plan { @@ -12,14 +12,16 @@ public class Plan /// [JsonProperty("nickname")] public string? Nickname { get; set; } + /// - /// An array of servicePointIds, representing NMIs, that this plan is linked to. + /// An array of servicePointIds, representing NMIs, that this plan is linked to. /// If there are no service points allocated to this plan then an empty array would be expected. /// [JsonProperty("servicePointIds", Required = Required.Always)] public string[] ServicePointIds { get; set; } + /// - /// Mandatory if openStatus is OPEN + /// Mandatory if openStatus is OPEN. /// [JsonProperty("planOverview")] public PlanOverview? PlanOverview { get; set; } diff --git a/Source/ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation/Models/Dataholders/Energy/PlanOverview.cs b/Source/ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation/Models/Dataholders/Energy/PlanOverview.cs index 224bc4b..19a18e8 100644 --- a/Source/ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation/Models/Dataholders/Energy/PlanOverview.cs +++ b/Source/ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation/Models/Dataholders/Energy/PlanOverview.cs @@ -1,9 +1,9 @@ -using Newtonsoft.Json; - -namespace ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation.Models.Dataholders.Energy +namespace ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation.Models.Dataholders.Energy { + using Newtonsoft.Json; + /// - /// Used by Energy Accounts/Plans + /// Used by Energy Accounts/Plans. /// public class PlanOverview { @@ -12,13 +12,15 @@ public class PlanOverview /// [JsonProperty("displayName")] public string? DisplayName { get; set; } + /// - /// The start date of the applicability of this plan + /// The start date of the applicability of this plan. /// [JsonProperty("startDate", Required = Required.Always)] public string StartDate { get; set; } + /// - /// The end date of the applicability of this plan + /// The end date of the applicability of this plan. /// [JsonProperty("endDate")] public string? EndDate { get; set; } diff --git a/Source/ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation/Models/Dataholders/Energy/ResponseEnergyAccountListV2.cs b/Source/ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation/Models/Dataholders/Energy/ResponseEnergyAccountListV2.cs index 7613b7b..7c0fafa 100644 --- a/Source/ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation/Models/Dataholders/Energy/ResponseEnergyAccountListV2.cs +++ b/Source/ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation/Models/Dataholders/Energy/ResponseEnergyAccountListV2.cs @@ -1,7 +1,7 @@ -using Newtonsoft.Json; - -namespace ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation.Models.Dataholders.Energy +namespace ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation.Models.Dataholders.Energy { + using Newtonsoft.Json; + public class ResponseEnergyAccountListV2 { /// diff --git a/Source/ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation/Models/Dataholders/LinksPaginated.cs b/Source/ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation/Models/Dataholders/LinksPaginated.cs index a960c71..bb7eefa 100644 --- a/Source/ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation/Models/Dataholders/LinksPaginated.cs +++ b/Source/ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation/Models/Dataholders/LinksPaginated.cs @@ -1,7 +1,7 @@ -using Newtonsoft.Json; - -namespace ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation.Models.Dataholders +namespace ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation.Models.Dataholders { + using Newtonsoft.Json; + public class LinksPaginated { /// @@ -9,21 +9,25 @@ public class LinksPaginated /// [JsonProperty("first")] public string? First { get; set; } + /// /// URI to the last page of this set. Mandatory if this response is not the last page. /// [JsonProperty("last")] public string? Last { get; set; } + /// /// URI to the next page of this set. Mandatory if this response is not the last page. /// [JsonProperty("next")] public string? Next { get; set; } + /// /// URI to the previous page of this set. Mandatory if this response is not the first page. /// [JsonProperty("prev")] public string? Prev { get; set; } + /// /// Fully qualified link that generated the current response document. /// diff --git a/Source/ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation/Models/Dataholders/MetaPaginated.cs b/Source/ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation/Models/Dataholders/MetaPaginated.cs index a896033..586a00f 100644 --- a/Source/ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation/Models/Dataholders/MetaPaginated.cs +++ b/Source/ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation/Models/Dataholders/MetaPaginated.cs @@ -1,7 +1,7 @@ -using Newtonsoft.Json; - -namespace ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation.Models.Dataholders +namespace ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation.Models.Dataholders { + using Newtonsoft.Json; + public class MetaPaginated { /// @@ -9,6 +9,7 @@ public class MetaPaginated /// [JsonProperty("totalRecords", Required = Required.Always)] public long TotalRecords { get; set; } + /// /// The total number of pages in the full set. /// diff --git a/Source/ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation/Models/Dataholders/TokenResponse.cs b/Source/ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation/Models/Dataholders/TokenResponse.cs index d9fc164..d082d6a 100644 --- a/Source/ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation/Models/Dataholders/TokenResponse.cs +++ b/Source/ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation/Models/Dataholders/TokenResponse.cs @@ -1,8 +1,7 @@ -using Newtonsoft.Json; -using Newtonsoft.Json.Serialization; - -namespace ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation.Models.Dataholders +namespace ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation.Models.Dataholders { + using Newtonsoft.Json; + using Newtonsoft.Json.Serialization; public class TokenResponse { @@ -26,6 +25,5 @@ public class TokenResponse [JsonProperty("scope")] public string? Scope { get; set; } - }; - + } } diff --git a/Source/ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation/Models/Error.cs b/Source/ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation/Models/Error.cs index aa8f211..c61ba10 100644 --- a/Source/ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation/Models/Error.cs +++ b/Source/ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation/Models/Error.cs @@ -1,7 +1,7 @@ -using System.ComponentModel.DataAnnotations; - -namespace ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation.Models +namespace ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation.Models { + using System.ComponentModel.DataAnnotations; + public class Error { public Error() diff --git a/Source/ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation/Models/ErrorV2.cs b/Source/ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation/Models/ErrorV2.cs index c2e8150..af8acce 100644 --- a/Source/ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation/Models/ErrorV2.cs +++ b/Source/ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation/Models/ErrorV2.cs @@ -1,9 +1,9 @@ -using System.ComponentModel.DataAnnotations; -using ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation.Extensions; -using Newtonsoft.Json; - -namespace ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation.Models +namespace ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation.Models { + using System.ComponentModel.DataAnnotations; + using ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation.Extensions; + using Newtonsoft.Json; + public class ErrorV2 { public ErrorV2(string code, string title, string detail, string? metaUrn) @@ -39,6 +39,6 @@ public ErrorV2(string code, string title, string detail, string? metaUrn) /// Optional additional data for specific error types. /// [JsonProperty("meta")] - public object Meta { get; set; } + public object? Meta { get; set; } } } diff --git a/Source/ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation/Models/JWK.cs b/Source/ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation/Models/JWK.cs index c4c4dd4..11257cd 100644 --- a/Source/ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation/Models/JWK.cs +++ b/Source/ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation/Models/JWK.cs @@ -1,19 +1,24 @@ -using Newtonsoft.Json; - -namespace ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation.Models +namespace ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation.Models { + using Newtonsoft.Json; + public class Jwk { [JsonProperty("alg")] public string? Alg { get; set; } + [JsonProperty("e")] public string? E { get; set; } + [JsonProperty("kid")] public string? Kid { get; set; } + [JsonProperty("kty")] public string? Kty { get; set; } + [JsonProperty("n")] public string? N { get; set; } + [JsonProperty("use")] public string? Use { get; set; } } diff --git a/Source/ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation/Models/JWKS.cs b/Source/ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation/Models/JWKS.cs index b7a7c1e..32b81a8 100644 --- a/Source/ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation/Models/JWKS.cs +++ b/Source/ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation/Models/JWKS.cs @@ -1,7 +1,7 @@ -using Newtonsoft.Json; - -namespace ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation.Models +namespace ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation.Models { + using Newtonsoft.Json; + public class Jwks { [JsonProperty("keys")] diff --git a/Source/ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation/Models/LegalEntity.cs b/Source/ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation/Models/LegalEntity.cs index 0b7fe85..0322ed3 100644 --- a/Source/ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation/Models/LegalEntity.cs +++ b/Source/ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation/Models/LegalEntity.cs @@ -1,17 +1,21 @@ -using Newtonsoft.Json; - -namespace ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation.Models +namespace ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation.Models { + using Newtonsoft.Json; + public class LegalEntity { [JsonProperty("legalEntityId")] public string LegalEntityId { get; set; } + [JsonProperty("legalEntityName")] public string LegalEntityName { get; set; } + [JsonProperty("logoUri")] public string LogoUri { get; set; } + [JsonProperty("status")] public string Status { get; set; } + [JsonProperty("dataRecipientBrands")] public List DataRecipientBrands { get; set; } } diff --git a/Source/ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation/Models/Options/TestAutomationAuthServerOptions.cs b/Source/ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation/Models/Options/TestAutomationAuthServerOptions.cs index b15bf32..fddddc6 100644 --- a/Source/ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation/Models/Options/TestAutomationAuthServerOptions.cs +++ b/Source/ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation/Models/Options/TestAutomationAuthServerOptions.cs @@ -10,18 +10,18 @@ public class TestAutomationAuthServerOptions // X-TlsClientCertThumbprint header to add if running standalone public string XTLSCLIENTCERTTHUMBPRINT { get; set; } - // X-TlsClientCertThumbprint (for additional certificate) header to add if running standalone + // X-TlsClientCertThumbprint (for additional certificate) header to add if running standalone public string XTLSADDITIONALCLIENTCERTTHUMBPRINT { get; set; } public int? ACCESSTOKENLIFETIMESECONDS { get; set; } /// - /// Running CdrAuthServer in headless mode (for authentication)? + /// Running CdrAuthServer in headless mode (for authentication)?. /// public bool HEADLESSMODE { get; set; } /// - /// Running CdrAuthServer with JARM encryption turned on? + /// Running CdrAuthServer with JARM encryption turned on?. /// public bool JARM_ENCRYPTION_ON { get; set; } } diff --git a/Source/ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation/Models/Options/TestAutomationOptions.cs b/Source/ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation/Models/Options/TestAutomationOptions.cs index 455e89e..fd1d4b4 100644 --- a/Source/ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation/Models/Options/TestAutomationOptions.cs +++ b/Source/ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation/Models/Options/TestAutomationOptions.cs @@ -1,13 +1,16 @@ -using ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation.Enums; - -namespace ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation.Models.Options +namespace ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation.Models.Options { + using ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation.Enums; + [System.Diagnostics.CodeAnalysis.SuppressMessage("SonarAnalyzer", "CA1707:Remove the underscores from member name", Justification = "Renaming these now require change in other repos as well.")] public class TestAutomationOptions { public bool IS_AUTH_SERVER { get; set; } = false; + public Industry INDUSTRY { get; set; } + public string SCOPE { get; set; } + public string DH_MTLS_GATEWAY_URL { get; set; } public string DH_MTLS_AUTHSERVER_TOKEN_URL => DH_MTLS_GATEWAY_URL + "/idp/connect/token"; @@ -22,19 +25,19 @@ public class TestAutomationOptions public string REGISTRATION_AUDIENCE_URI => DH_TLS_AUTHSERVER_BASE_URL; - //Migrated from Auth Server Settings as needed for DH tests + // Migrated from Auth Server Settings as needed for DH tests public string CDRAUTHSERVER_SECUREBASEURI { get; set; } - // Connection strings public string DATAHOLDER_CONNECTIONSTRING { get; set; } + public string AUTHSERVER_CONNECTIONSTRING { get; set; } + public string REGISTER_CONNECTIONSTRING { get; set; } // Seed-data offset public bool SEEDDATA_OFFSETDATES { get; set; } - public string MDH_INTEGRATION_TESTS_HOST { get; set; } public string SOFTWAREPRODUCT_REDIRECT_URI_FOR_INTEGRATION_TESTS => $"{MDH_INTEGRATION_TESTS_HOST}:9999/consent/callback"; @@ -47,14 +50,16 @@ public class TestAutomationOptions public string ADDITIONAL_SOFTWAREPRODUCT_JWKS_URI_FOR_INTEGRATION_TESTS => $"{MDH_INTEGRATION_TESTS_HOST}:9996/jwks"; - //For Playwright testing + // For Playwright testing public bool RUNNING_IN_CONTAINER { get; set; } = false; + public bool CREATE_MEDIA { get; set; } = false; + public int TEST_TIMEOUT { get; set; } = 30000; + public string MEDIA_FOLDER { get; set; } // Store dynamic client id for each successful Data Holder registration request public string? LastRegisteredClientId { get; set; } - } } diff --git a/Source/ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation/Models/Person.cs b/Source/ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation/Models/Person.cs index 8b70ed6..0d2f0a3 100644 --- a/Source/ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation/Models/Person.cs +++ b/Source/ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation/Models/Person.cs @@ -3,13 +3,21 @@ public class Person { public string PersonId { get; set; } + public string FirstName { get; set; } + public string LastName { get; set; } + public string MiddleNames { get; set; } + public string Prefix { get; set; } + public string Suffix { get; set; } + public string OccupationCode { get; set; } + public string OccupationCodeVersion { get; set; } + public DateTime? LastUpdateTime { get; set; } } } diff --git a/Source/ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation/Models/ResponseErrorList.cs b/Source/ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation/Models/ResponseErrorList.cs index 11e70a9..6650e19 100644 --- a/Source/ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation/Models/ResponseErrorList.cs +++ b/Source/ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation/Models/ResponseErrorList.cs @@ -1,10 +1,10 @@ -using System.ComponentModel.DataAnnotations; -using ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation.Enums; -using ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation.Exceptions; -using Newtonsoft.Json; - -namespace ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation.Models +namespace ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation.Models { + using System.ComponentModel.DataAnnotations; + using ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation.Enums; + using ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation.Exceptions; + using Newtonsoft.Json; + public class ResponseErrorList { public ResponseErrorList() diff --git a/Source/ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation/Models/ResponseErrorListV2.cs b/Source/ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation/Models/ResponseErrorListV2.cs index 60fd1b2..1526a82 100644 --- a/Source/ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation/Models/ResponseErrorListV2.cs +++ b/Source/ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation/Models/ResponseErrorListV2.cs @@ -1,9 +1,9 @@ -using System.ComponentModel.DataAnnotations; -using ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation.Exceptions; -using Newtonsoft.Json; - -namespace ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation.Models +namespace ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation.Models { + using System.ComponentModel.DataAnnotations; + using ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation.Exceptions; + using Newtonsoft.Json; + public class ResponseErrorListV2 { public ResponseErrorListV2() @@ -23,9 +23,10 @@ public ResponseErrorListV2(string errorCode, string errorTitle, string errorDeta } /// - /// A straight conversion of the Exception into an error response, which will include a message similar to 'An exception of type 'Exception' was thrown' as the urn of the error's meta property + /// Initializes a new instance of the class. + /// A straight conversion of the Exception into an error response, which will include a message similar to 'An exception of type 'Exception' was thrown' as the urn of the error's meta property. /// - /// The exception that was thrown + /// The exception that was thrown. public ResponseErrorListV2(CdrException ex) { var error = new ErrorV2(ex.Code, ex.Title, ex.Detail, ex.Message); @@ -33,10 +34,11 @@ public ResponseErrorListV2(CdrException ex) } /// - /// Allows for a custom (or empty) error message to be set, as the ex.message from a thrown exception may not be desired + /// Initializes a new instance of the class. + /// Allows for a custom (or empty) error message to be set, as the ex.message from a thrown exception may not be desired. /// - /// The exception that was thrown - /// The message that will show up as the urn of the error's meta property + /// The exception that was thrown. + /// The message that will show up as the urn of the error's meta property. public ResponseErrorListV2(CdrException ex, string message) { var error = new ErrorV2(ex.Code, ex.Title, ex.Detail, message); diff --git a/Source/ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation/Models/SoftwareProduct.cs b/Source/ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation/Models/SoftwareProduct.cs index 6b8b1b5..a6505e8 100644 --- a/Source/ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation/Models/SoftwareProduct.cs +++ b/Source/ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation/Models/SoftwareProduct.cs @@ -1,17 +1,21 @@ -using Newtonsoft.Json; - -namespace ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation.Models +namespace ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation.Models { + using Newtonsoft.Json; + public class SoftwareProduct { [JsonProperty("softwareProductId")] public string SoftwareProductId { get; set; } + [JsonProperty("softwareProductName")] public string SoftwareProductName { get; set; } + [JsonProperty("softwareProductDescription")] public string SoftwareProductDescription { get; set; } + [JsonProperty("logoUri")] public string LogoUri { get; set; } + [JsonProperty("status")] public string Status { get; set; } } diff --git a/Source/ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation/Services/AccessTokenService.cs b/Source/ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation/Services/AccessTokenService.cs index 8fc4557..6725d87 100644 --- a/Source/ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation/Services/AccessTokenService.cs +++ b/Source/ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation/Services/AccessTokenService.cs @@ -1,12 +1,12 @@ -using System.Net; -using System.Net.Http.Headers; -using System.Text; -using ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation.Extensions; -using ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation.Interfaces; -using Serilog; - namespace ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation.Services { + using System.Net; + using System.Net.Http.Headers; + using System.Text; + using ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation.Extensions; + using ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation.Interfaces; + using Serilog; + public class AccessTokenService : IAccessTokenService { public AccessTokenService(string mtlsAuthServerTokenUrl) @@ -18,21 +18,29 @@ public AccessTokenService(string mtlsAuthServerTokenUrl) private const string _defaultClientId = "86ecb655-9eba-409c-9be3-59e7adf7080d"; public string? CertificateFilename { get; set; } + public string? CertificatePassword { get; set; } public string? JwtCertificateFilename { get; set; } + public string? JwtCertificatePassword { get; set; } public string URL { get; init; } + public string Issuer { get; init; } = _defaultClientId; + public string Audience { get; init; } + public string Scope { get; init; } = "bank:accounts.basic:read"; - public string GrantType { get; init; } = ""; + + public string GrantType { get; init; } = string.Empty; + public string ClientId { get; init; } = _defaultClientId; - public string ClientAssertionType { get; init; } = ""; + + public string ClientAssertionType { get; init; } = string.Empty; /// - /// Get HttpRequestMessage for access token request + /// Get HttpRequestMessage for access token request. /// private static HttpRequestMessage CreateAccessTokenRequest( string url, @@ -79,7 +87,7 @@ static string BuildContent(string scope, string grant_type, string client_id, st CertificateFilename = jwtCertificateFilename, CertificatePassword = jwtCertificatePassword, Issuer = issuer, - Audience = audience + Audience = audience, }.Generate(); var request = new HttpRequestMessage(HttpMethod.Post, url) @@ -87,7 +95,7 @@ static string BuildContent(string scope, string grant_type, string client_id, st Content = new StringContent( BuildContent(scope, grantType, clientId, clientAssertionType, client_assertion), Encoding.UTF8, - "application/json") + "application/json"), }; request.Content.Headers.ContentType = new MediaTypeHeaderValue("application/x-www-form-urlencoded"); @@ -96,12 +104,13 @@ static string BuildContent(string scope, string grant_type, string client_id, st } /// - /// Get an access token from Auth Server + /// Get an access token from Auth Server. /// + /// Task representing the asynchronous operation. public async Task GetAsync(string dhMtlsGatewayUrl, string xtlsClientCertThumbprint, bool isStandalone) { Log.Information(Constants.LogTemplates.StartedFunctionInClass, nameof(GetAsync), nameof(AccessTokenService)); - + // Create HttpClient using var client = Helpers.Web.CreateHttpClient(CertificateFilename, CertificatePassword); diff --git a/Source/ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation/Services/ApiService.cs b/Source/ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation/Services/ApiService.cs index 4ebe45f..c8c7c74 100644 --- a/Source/ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation/Services/ApiService.cs +++ b/Source/ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation/Services/ApiService.cs @@ -1,23 +1,23 @@ -using System.Net.Http.Headers; -using ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation.Extensions; -using ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation.Interfaces; -using Serilog; - namespace ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation.Services { + using System.Net.Http.Headers; + using ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation.Extensions; + using ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation.Interfaces; + using Serilog; + /// - /// Call API + /// Call API. /// public class ApiService : IApiService { /// - /// Filename of certificate to use. + /// Filename of certificate to use. /// If null then no certificate will be attached to the request. /// public string? CertificateFilename { get; private set; } = Constants.Certificates.CertificateFilename; /// - /// Password for certificate. + /// Password for certificate. /// If null then no certificate password will be set. /// public string? CertificatePassword { get; private set; } = Constants.Certificates.CertificatePassword; @@ -90,33 +90,35 @@ public class ApiService : IApiService public IEnumerable? Cookies { get; private set; } /// - /// Set authentication header explicity. Can't be used if AccessToken is set + /// Set authentication header explicity. Can't be used if AccessToken is set. /// public AuthenticationHeaderValue? AuthenticationHeaderValue { get; } /// - /// Running standalone CdrAuthServer (ie no MtlsGateway) + /// Running standalone CdrAuthServer (ie no MtlsGateway). /// public bool IsStandalone { get; private set; } = false; /// - /// Dh Mtls Gateway Url - /// Only needed if isStandalone is true + /// Dh Mtls Gateway Url + /// Only needed if isStandalone is true. /// public string? DhMtlsGatewayUrl { get; private set; } /// /// Xtls Client Certificate Thumbprint - /// Only needed if isStandalone is true + /// Only needed if isStandalone is true. /// public string? XtlsClientCertificateThumbprint { get; private set; } - private ApiService() { } //restricts class instantiation to builder only + private ApiService() + { + } // restricts class instantiation to builder only /// /// Send a request to the API. /// - /// The API response + /// The API response. public async Task SendAsync(bool allowAutoRedirect = true, string? xtlsThumbprint = null) { Log.Information(Constants.LogTemplates.StartedFunctionInClass, nameof(SendAsync), nameof(ApiService)); @@ -215,10 +217,11 @@ private async Task SendRequest(HttpRequestMessage request, return await client.SendAsync(request); } - public class ApiServiceBuilder : IBuilder { - public ApiServiceBuilder() { } + public ApiServiceBuilder() + { + } private readonly ApiService _api = new ApiService(); @@ -227,26 +230,31 @@ public ApiServiceBuilder WithUrl(string? value) _api.URL = value; return this; } + public ApiServiceBuilder WithXV(string? value) { _api.XV = value; return this; } + public ApiServiceBuilder WithXFapiAuthDate(string? value) { _api.XFapiAuthDate = value; return this; } + public ApiServiceBuilder WithAccessToken(string? value) { _api.AccessToken = value; return this; } + public ApiServiceBuilder WithXFapiInteractionId(string? value) { _api.XFapiInteractionId = value; return this; } + public ApiServiceBuilder WithHttpMethod(HttpMethod? value) { _api.HttpMethod = value; @@ -264,6 +272,7 @@ public ApiServiceBuilder WithContentType(MediaTypeHeaderValue? value) _api.ContentType = value; return this; } + public ApiServiceBuilder WithAccept(string? value) { _api.Accept = value; @@ -305,11 +314,13 @@ public ApiServiceBuilder WithIsStandalone(bool value) _api.IsStandalone = value; return this; } + public ApiServiceBuilder WithDhMtlsGatewayUrl(string? value) { _api.DhMtlsGatewayUrl = value; return this; } + public ApiServiceBuilder WithXtlsClientCertificateThumbprint(string? value) { _api.XtlsClientCertificateThumbprint = value; diff --git a/Source/ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation/Services/ApiServiceDirector.cs b/Source/ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation/Services/ApiServiceDirector.cs index 4b8be52..884283c 100644 --- a/Source/ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation/Services/ApiServiceDirector.cs +++ b/Source/ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation/Services/ApiServiceDirector.cs @@ -1,16 +1,16 @@ -using System.Net.Http.Headers; -using System.Text; -using ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation.Enums; -using ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation.Extensions; -using ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation.Interfaces; -using ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation.Models.Options; -using Microsoft.AspNetCore.WebUtilities; -using Microsoft.Extensions.Options; -using Serilog; -using static ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation.Services.ApiService; - -namespace ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation.Services +namespace ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation.Services { + using System.Net.Http.Headers; + using System.Text; + using ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation.Enums; + using ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation.Extensions; + using ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation.Interfaces; + using ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation.Models.Options; + using Microsoft.AspNetCore.WebUtilities; + using Microsoft.Extensions.Options; + using Serilog; + using static ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation.Services.ApiService; + public class ApiServiceDirector : IApiServiceDirector { private readonly TestAutomationOptions _options; @@ -62,7 +62,7 @@ public ApiService BuildDataholderRegisterAPI(string? accessToken, string? regist _builder = new ApiServiceBuilder(); - var additionalUrl = clientId.IsNullOrWhiteSpace() ? "" : $"/{clientId}"; + var additionalUrl = clientId.IsNullOrWhiteSpace() ? string.Empty : $"/{clientId}"; _builder .WithUrl($"{_options.DH_MTLS_GATEWAY_URL}/connect/register{additionalUrl}") @@ -99,6 +99,7 @@ public ApiService BuildRegisterSSAAPI(Industry? industry, string brandId, string .WithXtlsClientCertificateThumbprint(_authServerOptions.XTLSCLIENTCERTTHUMBPRINT) .Build(); } + public ApiService BuildAuthServerOpenIdConfigurationAPI() { Log.Information(Constants.LogTemplates.StartedFunctionInClass, nameof(BuildAuthServerOpenIdConfigurationAPI), nameof(ApiServiceDirector)); @@ -113,6 +114,7 @@ public ApiService BuildAuthServerOpenIdConfigurationAPI() .WithXtlsClientCertificateThumbprint(_authServerOptions.XTLSCLIENTCERTTHUMBPRINT) .Build(); } + public ApiService BuildCustomerResourceAPI(string? accessToken) { Log.Information(Constants.LogTemplates.StartedFunctionInClass, nameof(BuildCustomerResourceAPI), nameof(ApiServiceDirector)); @@ -188,6 +190,7 @@ public ApiService BuildDataHolderCommonGetCustomerAPI(string? accessToken, strin .WithAccessToken(accessToken) .Build(); } + public ApiService BuildDataHolderBankingGetAccountsAPI(string? accessToken, string? xFapiAuthDate, string? xv = "2", string? xFapiInteractionId = null, string certFileName = Constants.Certificates.CertificateFilename, string certPassword = Constants.Certificates.CertificatePassword, string? url = null) { Log.Information(Constants.LogTemplates.StartedFunctionInClass, nameof(BuildDataHolderBankingGetAccountsAPI), nameof(ApiServiceDirector)); diff --git a/Source/ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation/Services/DataHolderAccessTokenCache.cs b/Source/ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation/Services/DataHolderAccessTokenCache.cs index f3f03f2..6c2c613 100644 --- a/Source/ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation/Services/DataHolderAccessTokenCache.cs +++ b/Source/ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation/Services/DataHolderAccessTokenCache.cs @@ -1,12 +1,12 @@ -using ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation.Enums; -using ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation.Extensions; -using ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation.Interfaces; -using ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation.Models.Options; -using Microsoft.Extensions.Options; -using Serilog; - namespace ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation.Services { + using ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation.Enums; + using ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation.Extensions; + using ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation.Interfaces; + using ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation.Models.Options; + using Microsoft.Extensions.Options; + using Serilog; + /// /// Get access token from DataHolder. /// Cache request (user/selectedaccounts/scope) and accesstoken. @@ -23,6 +23,7 @@ public class DataHolderAccessTokenCache : IDataHolderAccessTokenCache private readonly TestAutomationAuthServerOptions _authServerOptions; public int Hits { get; private set; } = 0; + public int Misses { get; private set; } = 0; public DataHolderAccessTokenCache(IOptions options, IOptions authServerOptions, IDataHolderParService dataHolderParService, IDataHolderTokenService dataHolderTokenService, IApiServiceDirector apiServiceDirector) @@ -34,12 +35,16 @@ public DataHolderAccessTokenCache(IOptions options, IOpti _authServerOptions = authServerOptions.Value ?? throw new ArgumentNullException(nameof(authServerOptions)); } - class CacheItem + private class CacheItem { public string? UserId { get; init; } + public string? SelectedAccounts { get; init; } + public string? Scope { get; init; } + public ResponseType ResponseType { get; init; } + public ResponseMode ResponseMode { get; init; } public string? AccessToken { get; set; } @@ -51,9 +56,9 @@ class CacheItem switch (tokenType) { - case TokenType.MaryMoss: //this was used by energy + case TokenType.MaryMoss: // this was used by energy case TokenType.HeddaHare: - case TokenType.JaneWilson: //this was used by banking + case TokenType.JaneWilson: // this was used by banking case TokenType.SteveKennedy: case TokenType.DewayneSteve: case TokenType.Business1: @@ -69,7 +74,7 @@ class CacheItem case TokenType.InvalidFoo: return "foo"; case TokenType.InvalidEmpty: - return ""; + return string.Empty; case TokenType.InvalidOmit: return null; @@ -84,8 +89,7 @@ class CacheItem string? scope = null, bool useCache = true, ResponseType responseType = ResponseType.Code, - ResponseMode responseMode = ResponseMode.Jwt - ) + ResponseMode responseMode = ResponseMode.Jwt) { Log.Information("Calling {FUNCTION} in {ClassName} with Params: {P1}={V1},{P2}={V2},{P3}={V3},{P4}={V4}.", nameof(GetAccessToken), nameof(DataHolderAccessTokenCache), nameof(userId), userId, nameof(selectedAccounts), selectedAccounts, nameof(scope), scope, nameof(useCache), useCache); @@ -114,6 +118,7 @@ class CacheItem return cacheHit.AccessToken; } + // Cache miss, so perform auth/consent flow to get accesstoken/refreshtoken else { @@ -138,7 +143,8 @@ class CacheItem } } - private async Task<(string accessToken, string refreshToken)> FromAuthConsentFlow(string userId, + private async Task<(string accessToken, string refreshToken)> FromAuthConsentFlow( + string userId, string selectedAccounts, string? scope = null, ResponseType responseType = ResponseType.Code, @@ -162,7 +168,7 @@ class CacheItem } else { - authService = await new DataHolderAuthoriseService.DataHolderAuthoriseServiceBuilder(_options, _dataHolderParService, _apiServiceDirector) + authService = await new DataHolderAuthoriseService.DataHolderAuthoriseServiceBuilder(_options, _dataHolderParService, _apiServiceDirector) .WithUserId(userId) .WithScope(scope) .WithSelectedAccountIds(selectedAccounts) @@ -177,18 +183,22 @@ class CacheItem var tokenResponse = await _dataHolderTokenService.GetResponse(authCode); if (tokenResponse?.AccessToken == null) + { throw new InvalidOperationException($"{nameof(FromAuthConsentFlow)} - access token is null").Log(); + } if (tokenResponse.RefreshToken == null) + { throw new InvalidOperationException($"{nameof(FromAuthConsentFlow)} - refresh token is null").Log(); + } return (tokenResponse.AccessToken, tokenResponse.RefreshToken); } + public void ClearCache() { Log.Information(Constants.LogTemplates.StartedFunctionInClass, nameof(ClearCache), nameof(DataHolderAccessTokenCache)); _cache.Clear(); } - } } diff --git a/Source/ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation/Services/DataHolderAuthoriseService.cs b/Source/ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation/Services/DataHolderAuthoriseService.cs index e58945d..26b074d 100644 --- a/Source/ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation/Services/DataHolderAuthoriseService.cs +++ b/Source/ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation/Services/DataHolderAuthoriseService.cs @@ -1,47 +1,51 @@ -using System.IdentityModel.Tokens.Jwt; -using System.Net; -using System.Security.Cryptography.X509Certificates; -using System.Web; -using ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation.APIs; -using ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation.Enums; -using ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation.Exceptions; -using ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation.Exceptions.AuthoriseExceptions; -using ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation.Extensions; -using ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation.Interfaces; -using ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation.Models.Options; -using ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation.UI; -using ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation.UI.Pages.Authorisation; -using Dapper; -using FluentAssertions; -using HtmlAgilityPack; -using Jose; -using Microsoft.AspNetCore.WebUtilities; -using Microsoft.Data.SqlClient; -using Microsoft.Playwright; -using Serilog; - namespace ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation.Services { + using System.IdentityModel.Tokens.Jwt; + using System.Net; + using System.Security.Cryptography.X509Certificates; + using System.Web; + using ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation.APIs; + using ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation.Enums; + using ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation.Exceptions; + using ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation.Exceptions.AuthoriseExceptions; + using ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation.Extensions; + using ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation.Interfaces; + using ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation.Models.Options; + using ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation.UI; + using ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation.UI.Pages.Authorisation; + using Dapper; + using FluentAssertions; + using HtmlAgilityPack; + using Jose; + using Microsoft.AspNetCore.WebUtilities; + using Microsoft.Data.SqlClient; + using Microsoft.Playwright; + using Serilog; + public partial class DataHolderAuthoriseService : IDataHolderAuthoriseService { - - private DataHolderAuthoriseService() { } //private constructor ensures that the builder must be used to instantiate a new service + private DataHolderAuthoriseService() + { + } // private constructor ensures that the builder must be used to instantiate a new service private string[]? SelectedAccountDisplayNamesCache { get; set; } = null; + private string? AuthoriseUrl { get; set; } + private TestAutomationOptions TestAutomationOptions { get; set; } + private TestAutomationAuthServerOptions? AuthServerOptions { get; set; } private IApiServiceDirector? ApiDirector { get; set; } /// - /// The customer's userid with the DataHolder - eg "jwilson" + /// The customer's userid with the DataHolder - eg "jwilson". /// public string UserId { get; private set; } /// /// The OTP (One-time password) that is sent to the customer (via sms etc) so the DataHolder can authenticate the Customer. - /// For the mock solution use "000789" + /// For the mock solution use "000789". /// public string OTP { get; private set; } = Constants.AuthoriseOTP; @@ -53,31 +57,37 @@ public partial class DataHolderAuthoriseService : IDataHolderAuthoriseService protected string[]? SelectedAccountIdsArray => SelectedAccountIds?.Split(","); /// - /// Scope + /// Scope. /// public string Scope { get; private set; } /// - /// Lifetime (in seconds) of the access token + /// Lifetime (in seconds) of the access token. /// public int TokenLifetime { get; private set; } = Constants.AuthServer.DefaultTokenLifetime; /// /// Lifetime (in seconds) of the CDR arrangement. - /// SHARING_DURATION = 90 days + /// SHARING_DURATION = 90 days. /// public int? SharingDuration { get; private set; } = Constants.AuthServer.SharingDuration; public string? RequestUri { get; private set; } public string CertificateFilename { get; private set; } + public string CertificatePassword { get; private set; } + public string ClientId { get; private set; } + public string RedirectURI { get; private set; } + public string JwtCertificateFilename { get; private set; } + public string JwtCertificatePassword { get; private set; } public ResponseType ResponseType { get; private set; } = ResponseType.Code; + public ResponseMode ResponseMode { get; private set; } = ResponseMode.Jwt; public string? CdrArrangementId { get; private set; } @@ -91,7 +101,7 @@ public DataHolderAuthoriseServiceBuilder(TestAutomationOptions options, IDataHol _dataHolderAuthoriseService.TestAutomationOptions = options ?? throw new ArgumentNullException(nameof(options)); _dataHolderAuthoriseService.ApiDirector = apiServiceDirector ?? throw new ArgumentNullException(nameof(apiServiceDirector)); - _dataHolderAuthoriseService.AuthServerOptions = authServerOptions; //no null check here because this is nullable + _dataHolderAuthoriseService.AuthServerOptions = authServerOptions; // no null check here because this is nullable } private readonly DataHolderAuthoriseService _dataHolderAuthoriseService = new DataHolderAuthoriseService(); @@ -127,56 +137,67 @@ public DataHolderAuthoriseServiceBuilder WithTokenLifetime(int value) _dataHolderAuthoriseService.TokenLifetime = value; return this; } + public DataHolderAuthoriseServiceBuilder WithSharingDuration(int? value) { _dataHolderAuthoriseService.SharingDuration = value; return this; } + public DataHolderAuthoriseServiceBuilder WithRequestUri(string value) { _dataHolderAuthoriseService.RequestUri = value; return this; } + public DataHolderAuthoriseServiceBuilder WithClientId(string value) { _dataHolderAuthoriseService.ClientId = value; return this; } + public DataHolderAuthoriseServiceBuilder WithRedirectUri(string value) { _dataHolderAuthoriseService.RedirectURI = value; return this; } + public DataHolderAuthoriseServiceBuilder WithResponseType(ResponseType value) { _dataHolderAuthoriseService.ResponseType = value; return this; } + public DataHolderAuthoriseServiceBuilder WithResponseMode(ResponseMode value) { _dataHolderAuthoriseService.ResponseMode = value; return this; } + public DataHolderAuthoriseServiceBuilder WithCertificateFilename(string value) { _dataHolderAuthoriseService.CertificateFilename = value; return this; } + public DataHolderAuthoriseServiceBuilder WithCertificatePassword(string value) { _dataHolderAuthoriseService.CertificatePassword = value; return this; } + public DataHolderAuthoriseServiceBuilder WithJwtCertificateFilename(string value) { _dataHolderAuthoriseService.JwtCertificateFilename = value; return this; } + public DataHolderAuthoriseServiceBuilder WithJwtCertificatePassword(string value) { _dataHolderAuthoriseService.JwtCertificatePassword = value; return this; } + public DataHolderAuthoriseServiceBuilder WithCdrArrangementId(string? value) { _dataHolderAuthoriseService.CdrArrangementId = value; @@ -187,7 +208,7 @@ public async Task BuildAsync() { Log.Information("Building a {BuiltClass} using {BuilderClass}.", nameof(DataHolderAuthoriseService), nameof(DataHolderAuthoriseServiceBuilder)); - var _options = _dataHolderAuthoriseService.TestAutomationOptions; //purely to shorten reference + var _options = _dataHolderAuthoriseService.TestAutomationOptions; // purely to shorten reference FillMissingDefaults(); Validate(); @@ -202,8 +223,7 @@ public async Task BuildAsync() clientId: _dataHolderAuthoriseService.ClientId, cdrArrangementId: _dataHolderAuthoriseService.CdrArrangementId, responseType: _dataHolderAuthoriseService.ResponseType, - responseMode: _dataHolderAuthoriseService.ResponseMode - ); + responseMode: _dataHolderAuthoriseService.ResponseMode); } _dataHolderAuthoriseService.AuthoriseUrl = new AuthoriseUrl.AuthoriseUrlBuilder(_options) @@ -226,8 +246,7 @@ public async Task BuildAsync() clientId: _dataHolderAuthoriseService.ClientId, responseType: _dataHolderAuthoriseService.ResponseType, responseMode: _dataHolderAuthoriseService.ResponseMode, - cdrArrangementId: _dataHolderAuthoriseService.CdrArrangementId - ); + cdrArrangementId: _dataHolderAuthoriseService.CdrArrangementId); } } @@ -283,7 +302,6 @@ private static void SetDefaultValueIfEmpty(string property, object target, Func< } } - private void Validate() { Log.Information("Validating {BUILTOBJECT} mandatory properties.", nameof(DataHolderAuthoriseService)); @@ -315,7 +333,7 @@ public static string GetAccountIdsForUser(string userId) } } - public async Task<(string authCode, string? idToken)> Authorise() + public async Task<(string authCode, string idToken)> Authorise() { Log.Information(Constants.LogTemplates.StartedFunctionInClass, nameof(Authorise), nameof(DataHolderAuthoriseService)); @@ -360,9 +378,9 @@ public async Task AuthoriseForJarm() } /// - /// Perform authorisation and consent flow. Returns authCode and idToken + /// Perform authorisation and consent flow. Returns authCode and idToken. /// - private async Task<(string authCode, string? idToken)> AuthoriseHeadless() + private async Task<(string authCode, string idToken)> AuthoriseHeadless() { Log.Information(Constants.LogTemplates.StartedFunctionInClass, nameof(AuthoriseHeadless), nameof(DataHolderAuthoriseService)); @@ -383,14 +401,14 @@ public async Task AuthoriseForJarm() finally { await callback.Stop(); - } + } - (string authCode, string? idToken) ExtractAuthCodeIdToken(HttpResponseMessage response) + (string authCode, string idToken) ExtractAuthCodeIdToken(HttpResponseMessage response) { Log.Information(Constants.LogTemplates.StartedFunctionInClass, nameof(ExtractAuthCodeIdToken), nameof(DataHolderAuthoriseService)); string? authCode = null; - string? idToken = null; + string? idToken = null; // Handle Authorisation Code Flow response if (ResponseType == ResponseType.Code) @@ -405,24 +423,27 @@ public async Task AuthoriseForJarm() if (AuthServerOptions.JARM_ENCRYPTION_ON) { Log.Information("Authorisation Server has JARM Encryption turned on. JWT is being decrypted."); - // Check claims of decode jwt + + // Check claims of decode jwt var encryptedJwt = new JwtSecurityTokenHandler().ReadJwtToken(encodedJwt); encryptedJwt.Header["alg"].Should().Be("RSA-OAEP", because: "JARM Encryption is turned on."); encryptedJwt.Header["enc"].Should().Be("A128CBC-HS256", because: "JARM Encryption is turned on."); + // Decrypt the JARM JWT. var privateKeyCertificate = new X509Certificate2(JwtCertificateFilename, JwtCertificatePassword, X509KeyStorageFlags.Exportable); var privateKey = privateKeyCertificate.GetRSAPrivateKey(); JweToken token = JWE.Decrypt(queryValueResponse, privateKey); - encodedJwt = token.Plaintext; + encodedJwt = token.Plaintext; } // Return Authorisation Code - var jwt = new JwtSecurityTokenHandler().ReadJwtToken(encodedJwt); + var jwt = new JwtSecurityTokenHandler().ReadJwtToken(encodedJwt); authCode = jwt.Claim("code").Value; - } + // Handle Hybrid Flow response - else if (ResponseType == ResponseType.CodeIdToken) { + else if (ResponseType == ResponseType.CodeIdToken) + { var fragment = response.RequestMessage?.RequestUri?.Fragment; if (fragment == null) { @@ -439,17 +460,17 @@ public async Task AuthoriseForJarm() throw new NotSupportedException($"Only '{ResponseType.Code.ToEnumMemberAttrValue()}' and '{ResponseType.CodeIdToken.ToEnumMemberAttrValue()}' Response types are supported."); } - if (authCode == null) { throw new InvalidOperationException("authCode cannot be null."); } - if (idToken == null && ResponseType == ResponseType.CodeIdToken) { + if (idToken == null && ResponseType == ResponseType.CodeIdToken) + { throw new InvalidOperationException("idToken cannot be null for hybrid flow."); } - return (authCode, idToken); + return (authCode, idToken) !; } } @@ -470,6 +491,7 @@ public async Task AuthoriseForJarm() #endregion #region Dataholder + // Call authorise endpoint, should respond with a redirect to auth UI, return the redirect URI private async Task Authorise_GetRedirectUri() { @@ -499,18 +521,17 @@ private async Task Authorise_GetRedirectUri() var error = doc.DocumentNode.SelectSingleNode("//input[@name='error']").Attributes["value"].Value; var errorDescription = doc.DocumentNode.SelectSingleNode("//input[@name='error_description']").Attributes["value"].Value; - throw new AuthoriseException($"Expected {HttpStatusCode.Redirect} but got {response.StatusCode}", response.StatusCode, error, errorDescription); //TODO: This was the original code, but it's returning Ok when it should not be 200Ok. Bug 63710 + throw new AuthoriseException($"Expected {HttpStatusCode.Redirect} but got {response.StatusCode}", response.StatusCode, error, errorDescription); // TODO: This was the original code, but it's returning Ok when it should not be 200Ok. Bug 63710 } return response.Headers.Location ?? throw new InvalidOperationException($"{nameof(response.Headers.Location.AbsoluteUri)} is null"); } - private async Task<(string authCode, string idToken)> Authorize_Consent(Uri authRedirectUri) { Log.Information("Calling {FUNCTION} in {ClassName} with Params: {P1}={V1}.", nameof(Authorize_Consent), nameof(DataHolderAuthoriseService), nameof(authRedirectUri), authRedirectUri); - var authRedirectLeftPart = authRedirectUri.GetLeftPart(UriPartial.Authority) + "/ui"; + _ = authRedirectUri.GetLeftPart(UriPartial.Authority) + "/ui"; string? code = null; string? idtoken = null; @@ -562,11 +583,11 @@ private async Task Authorise_GetRedirectUri() return ( authCode: code ?? throw new InvalidOperationException($"{nameof(code)} is null"), - idToken: idtoken ?? throw new InvalidOperationException($"{nameof(idtoken)} is null") - ); + idToken: idtoken ?? throw new InvalidOperationException($"{nameof(idtoken)} is null")); } private delegate Task HandleDataRecipientCallback_Setup(IPage page); + private async Task<(string code, string idtoken)> HandleDataRecipientCallback(string redirectUri, IPage page, HandleDataRecipientCallback_Setup setup) { Log.Information(Constants.LogTemplates.StartedFunctionInClass, nameof(HandleDataRecipientCallback), nameof(DataHolderAuthoriseService)); @@ -578,34 +599,20 @@ private async Task Authorise_GetRedirectUri() await setup(page); var callbackRequest = await callback.WaitForCallback(); - switch (ResponseMode.ToEnumMemberAttrValue()) + + if (ResponseMode == ResponseMode.Jwt) { - case "form_post": - { - callbackRequest.Should().NotBeNull(); - callbackRequest?.received.Should().BeTrue(); - callbackRequest?.method.Should().Be(HttpMethod.Post); - callbackRequest?.body.Should().NotBeNullOrEmpty(); - - var body = QueryHelpers.ParseQuery(callbackRequest?.body); - var code = body["code"]; - var id_token = body["id_token"]; - return (code, id_token); - } - case "jwt": - { - callbackRequest.Should().NotBeNull(); - callbackRequest?.received.Should().BeTrue(); - var queryValues = HttpUtility.ParseQueryString(callbackRequest?.queryString ?? throw new InvalidOperationException($"{nameof(callbackRequest.queryString)} is null")); - var encodedJwt = queryValues["response"]; - var jwt = new JwtSecurityTokenHandler().ReadJwtToken(encodedJwt); - return (jwt.Claim("code").Value, ""); - } - case "fragment": - case "query": - default: - throw new NotSupportedException(ResponseMode.ToEnumMemberAttrValue() + " response mode is not supported."); + callbackRequest.Should().NotBeNull(); + callbackRequest?.received.Should().BeTrue(); + var queryValues = HttpUtility.ParseQueryString(callbackRequest?.queryString ?? throw new InvalidOperationException($"{nameof(callbackRequest.queryString)} is null")); + var encodedJwt = queryValues["response"]; + var jwt = new JwtSecurityTokenHandler().ReadJwtToken(encodedJwt); + return (jwt.Claim("code").Value, string.Empty); } + else + { + throw new NotSupportedException(ResponseMode.ToEnumMemberAttrValue() + " response mode is not supported."); + } } finally { @@ -638,5 +645,4 @@ private string[] GetSelectedAccountDisplayNames() return SelectedAccountDisplayNamesCache; } } - } diff --git a/Source/ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation/Services/DataHolderParService.cs b/Source/ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation/Services/DataHolderParService.cs index 95ba0e0..4896145 100644 --- a/Source/ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation/Services/DataHolderParService.cs +++ b/Source/ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation/Services/DataHolderParService.cs @@ -1,14 +1,14 @@ -using System.Net; -using ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation.Enums; -using ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation.Extensions; -using ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation.Interfaces; -using ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation.Models.Options; -using Microsoft.Extensions.Options; -using Newtonsoft.Json; -using Serilog; - namespace ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation.Services { + using System.Net; + using ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation.Enums; + using ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation.Extensions; + using ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation.Interfaces; + using ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation.Models.Options; + using Microsoft.Extensions.Options; + using Newtonsoft.Json; + using Serilog; + public class DataHolderParService : IDataHolderParService { private readonly TestAutomationOptions _options; @@ -27,7 +27,7 @@ public class Response [JsonProperty("expires_in")] public int? ExpiresIn { get; set; } - }; + } public async Task SendRequest( string? scope, @@ -92,36 +92,39 @@ public async Task SendRequest( CertificateFilename = jwtCertificateForClientAssertionFilename, CertificatePassword = jwtCertificateForClientAssertionPassword, Issuer = clientId ?? throw new InvalidOperationException($"{nameof(clientId)} is null"), - Audience = aud ?? issuer - }.Generate() - )); + Audience = aud ?? issuer, + }.Generate())); if (addRequestObject) { var iat = new DateTimeOffset(DateTime.Now).ToUnixTimeSeconds(); - var requestObject = new Dictionary { - { "iss", clientId ?? throw new InvalidOperationException($"{nameof(clientId)} is null")}, + var requestObject = new Dictionary + { + { "iss", clientId ?? throw new InvalidOperationException($"{nameof(clientId)} is null") }, { "iat", iat }, { "jti", Guid.NewGuid().ToString().Replace("-", string.Empty) }, - - { "response_mode", responseMode?.ToEnumMemberAttrValue()}, + { "response_mode", responseMode?.ToEnumMemberAttrValue() }, { "aud", aud ?? _options.DH_TLS_AUTHSERVER_BASE_URL }, { "client_id", clientId }, { "redirect_uri", redirectUri }, { "state", state ?? Guid.NewGuid().ToString() }, { "nonce", Guid.NewGuid().ToString() }, - { "claims", new { + { + "claims", new + { sharing_duration = $"{sharingDuration}", cdr_arrangement_id = cdrArrangementId, - id_token = new { - acr = new { + id_token = new + { + acr = new + { essential = true, - values = new string[] { "urn:cds.au:cdr:2" } - } + values = new string[] { "urn:cds.au:cdr:2" }, }, - } + }, } + }, }; if (addNotBeforeClaim) diff --git a/Source/ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation/Services/DataHolderRegisterService.cs b/Source/ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation/Services/DataHolderRegisterService.cs index ae3478f..45d0859 100644 --- a/Source/ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation/Services/DataHolderRegisterService.cs +++ b/Source/ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation/Services/DataHolderRegisterService.cs @@ -1,15 +1,16 @@ -using System.IdentityModel.Tokens.Jwt; -using System.Net; -using ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation.Extensions; -using ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation.Interfaces; -using ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation.Models.Options; -using Microsoft.Extensions.Options; -using Microsoft.IdentityModel.Tokens; -using Newtonsoft.Json; -using Serilog; - namespace ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation.Services { + using System.IdentityModel.Tokens.Jwt; + using System.Net; + using ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation.Enums; + using ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation.Extensions; + using ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation.Interfaces; + using ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation.Models.Options; + using Microsoft.Extensions.Options; + using Microsoft.IdentityModel.Tokens; + using Newtonsoft.Json; + using Serilog; + public class DataHolderRegisterService : IDataHolderRegisterService { private readonly TestAutomationOptions _options; @@ -24,9 +25,11 @@ public DataHolderRegisterService(IOptions options, IRegis _registerSSAService = registerSSAService ?? throw new ArgumentNullException(nameof(registerSSAService)); _apiServiceDirector = apiServiceDirector ?? throw new ArgumentNullException(nameof(apiServiceDirector)); } + /// - /// Create registration request JWT for SSA + /// Create registration request JWT for SSA. /// + /// string. public string CreateRegistrationRequest( string ssa, string tokenEndpointAuthSigningAlg = SecurityAlgorithms.RsaSsaPssSha256, @@ -35,20 +38,15 @@ public string CreateRegistrationRequest( string jwtCertificatePassword = Constants.Certificates.JwtCertificatePassword, string applicationType = "web", string requestObjectSigningAlg = SecurityAlgorithms.RsaSsaPssSha256, - string responseType = "code id_token", + ResponseType responseType = ResponseType.Code, string[]? grantTypes = null, string? authorizationSignedResponseAlg = SecurityAlgorithms.RsaSsaPssSha256, string? authorizationEncryptedResponseAlg = null, string? authorizationEncryptedResponseEnc = null, - string? idTokenSignedResponseAlg = SecurityAlgorithms.RsaSsaPssSha256, - string? idTokenEncryptedResponseAlg = "RSA-OAEP", - string? idTokenEncryptedResponseEnc = "A256GCM" - ) + string? idTokenSignedResponseAlg = SecurityAlgorithms.RsaSsaPssSha256) { Log.Information(Constants.LogTemplates.StartedFunctionInClass, nameof(CreateRegistrationRequest), nameof(DataHolderRegisterService)); - string[] responseTypes = responseType.Contains(',') ? responseType.Split(',') : [responseType]; - grantTypes = grantTypes ?? ["client_credentials", "authorization_code", "refresh_token"]; JwtSecurityToken decodedSSA; @@ -75,22 +73,19 @@ public string CreateRegistrationRequest( { "aud", _options.REGISTRATION_AUDIENCE_URI }, // Get redirect_uris from SSA - { "redirect_uris", + { + "redirect_uris", redirectUris ?? - decodedSSA.Claims.Where(claim => claim.Type == "redirect_uris").Select(claim => claim.Value).ToArray() }, - + decodedSSA.Claims.Where(claim => claim.Type == "redirect_uris").Select(claim => claim.Value).ToArray() + }, { "token_endpoint_auth_signing_alg", tokenEndpointAuthSigningAlg }, { "token_endpoint_auth_method", "private_key_jwt" }, { "grant_types", grantTypes }, - { "response_types", responseTypes }, + { "response_types", responseType.ToEnumMemberAttrValue() }, - //{ "id_token_signed_response_alg", "PS256" }, //TODO: Optional? - //{ "id_token_encrypted_response_alg", "RSA-OAEP" }, //TODO: Optional? - //{ "id_token_encrypted_response_enc", "A256GCM" }, //TODO: Optional? - //{ "application_type", applicationType }, // spec says optional + // { "application_type", applicationType }, // spec says optional { "software_statement", ssa }, - - { "client_id",softwareId }, + { "client_id", softwareId }, }; // Optional fields. @@ -108,7 +103,7 @@ public string CreateRegistrationRequest( { if (authorizationSignedResponseAlg == Constants.Null) { - subject.Add("authorization_signed_response_alg", null); + subject.Add("authorization_signed_response_alg", string.Empty); } else { @@ -120,6 +115,7 @@ public string CreateRegistrationRequest( { subject.Add("authorization_encrypted_response_alg", authorizationEncryptedResponseAlg); } + if (authorizationEncryptedResponseEnc != null) { subject.Add("authorization_encrypted_response_enc", authorizationEncryptedResponseEnc); @@ -130,15 +126,6 @@ public string CreateRegistrationRequest( subject.Add("id_token_signed_response_alg", idTokenSignedResponseAlg); } - if (idTokenEncryptedResponseAlg != null) - { - subject.Add("id_token_encrypted_response_alg", idTokenEncryptedResponseAlg); - } - if (idTokenEncryptedResponseEnc != null) - { - subject.Add("id_token_encrypted_response_enc", idTokenEncryptedResponseEnc); - } - var jwt = Helpers.Jwt.CreateJWT( jwtCertificateFilename, jwtCertificatePassword, @@ -148,8 +135,9 @@ public string CreateRegistrationRequest( } /// - /// Register software product using registration request + /// Register software product using registration request. /// + /// Task representing the asynchronous operation. public async Task RegisterSoftwareProduct(string registrationRequest) { Log.Information("Calling {FUNCTION} in {ClassName} with Params: {P1}={V1}.", nameof(RegisterSoftwareProduct), nameof(DataHolderRegisterService), nameof(registrationRequest), registrationRequest); @@ -161,7 +149,7 @@ public async Task RegisterSoftwareProduct(string registrati CertificateFilename = Constants.Certificates.JwtCertificateFilename, CertificatePassword = Constants.Certificates.JwtCertificatePassword, Issuer = Constants.SoftwareProducts.SoftwareProductId.ToLower(), - Audience = url + Audience = url, }.Generate(); // Post the request @@ -177,7 +165,7 @@ public async Task RegisterSoftwareProduct(string registrati string softwareProductId = Constants.SoftwareProducts.SoftwareProductId, string jwtCertificateFilename = Constants.Certificates.JwtCertificateFilename, string jwtCertificatePassword = Constants.Certificates.JwtCertificatePassword, - string responseType = "code,code id_token", + ResponseType responseType = ResponseType.Code, string authorizationSignedResponseAlg = SecurityAlgorithms.RsaSsaPssSha256) { Log.Information(Constants.LogTemplates.StartedFunctionInClass, nameof(RegisterSoftwareProduct), nameof(DataHolderRegisterService)); @@ -186,12 +174,15 @@ public async Task RegisterSoftwareProduct(string registrati var ssa = await _registerSSAService.GetSSA(brandId, softwareProductId, _latestSSAVersion, jwtCertificateFilename, jwtCertificatePassword); // Register software product with DataHolder - var registrationRequest = CreateRegistrationRequest(ssa, + var registrationRequest = CreateRegistrationRequest( + ssa, jwtCertificateFilename: jwtCertificateFilename, jwtCertificatePassword: jwtCertificatePassword, responseType: responseType, authorizationSignedResponseAlg: authorizationSignedResponseAlg); + Log.Information("Registration Request to be sent: {RegistrationRequest}", registrationRequest); + var response = await RegisterSoftwareProduct(registrationRequest); if (response.StatusCode != HttpStatusCode.Created) { @@ -208,7 +199,7 @@ public async Task RegisterSoftwareProduct(string registrati } _options.LastRegisteredClientId = clientId; - return (ssa, registration, clientId); + return (ssa, registration, clientId ?? string.Empty); } } } diff --git a/Source/ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation/Services/DataHolderTokenRevocationService.cs b/Source/ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation/Services/DataHolderTokenRevocationService.cs index d7ba573..4478bba 100644 --- a/Source/ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation/Services/DataHolderTokenRevocationService.cs +++ b/Source/ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation/Services/DataHolderTokenRevocationService.cs @@ -1,11 +1,11 @@ -using System.Security.Cryptography.X509Certificates; -using ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation.Extensions; -using ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation.Interfaces; -using ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation.Models.Options; -using Microsoft.Extensions.Options; - namespace ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation.Services { + using System.Security.Cryptography.X509Certificates; + using ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation.Extensions; + using ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation.Interfaces; + using ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation.Models.Options; + using Microsoft.Extensions.Options; + public class DataHolderTokenRevocationService : IDataHolderTokenRevocationService { private readonly TestAutomationOptions _options; @@ -14,7 +14,7 @@ public class DataHolderTokenRevocationService : IDataHolderTokenRevocationServic public DataHolderTokenRevocationService(IOptions options, IOptions? authServerOptions = null) { _options = options.Value ?? throw new ArgumentNullException(nameof(options)); - _authServerOptions = authServerOptions?.Value; //no null check here because this is nullable for Data Holder projects + _authServerOptions = authServerOptions?.Value; // no null check here because this is nullable for Data Holder projects } // Send token request, returning HttpResponseMessage @@ -88,7 +88,7 @@ private static string GenerateClientAssertion(string jwtCertificateFilename, str CertificateFilename = jwtCertificateFilename, CertificatePassword = jwtCertificatePassword, Issuer = clientId ?? throw new InvalidOperationException($"{nameof(clientId)} can not be null.").Log(), - Audience = url + Audience = url, }.Generate(); } diff --git a/Source/ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation/Services/DataHolderTokenService.cs b/Source/ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation/Services/DataHolderTokenService.cs index fcfce59..e695e37 100644 --- a/Source/ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation/Services/DataHolderTokenService.cs +++ b/Source/ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation/Services/DataHolderTokenService.cs @@ -1,15 +1,15 @@ -using System.Net; -using ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation.Extensions; -using ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation.Interfaces; -using ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation.Models.Dataholders; -using ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation.Models.Options; -using Microsoft.Extensions.Options; -using Microsoft.IdentityModel.Tokens; -using Newtonsoft.Json; -using Serilog; - namespace ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation.Services { + using System.Net; + using ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation.Extensions; + using ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation.Interfaces; + using ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation.Models.Dataholders; + using ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation.Models.Options; + using Microsoft.Extensions.Options; + using Microsoft.IdentityModel.Tokens; + using Newtonsoft.Json; + using Serilog; + public partial class DataHolderTokenService : IDataHolderTokenService { private readonly TestAutomationOptions _options; @@ -24,22 +24,21 @@ public DataHolderTokenService(IOptions options, IOptions< // Send token request, returning HttpResponseMessage public async Task SendRequest( string? authCode = null, - bool usePut = false, - string grantType = "authorization_code", - string? clientId = null, - string? issuerClaim = null, - string clientAssertionType = Constants.ClientAssertionType, - bool useClientAssertion = true, - int? shareDuration = null, - string? refreshToken = null, - string? customClientAssertion = null, - string? scope = null, - string? redirectUri = null, - string certificateFilename = Constants.Certificates.CertificateFilename, - string certificatePassword = Constants.Certificates.CertificatePassword, - string jwkCertificateFilename = Constants.Certificates.JwtCertificateFilename, - string jwkCertificatePassword = Constants.Certificates.JwtCertificatePassword - ) + bool usePut = false, + string grantType = "authorization_code", + string? clientId = null, + string? issuerClaim = null, + string clientAssertionType = Constants.ClientAssertionType, + bool useClientAssertion = true, + int? shareDuration = null, + string? refreshToken = null, + string? customClientAssertion = null, + string? scope = null, + string? redirectUri = null, + string certificateFilename = Constants.Certificates.CertificateFilename, + string certificatePassword = Constants.Certificates.CertificatePassword, + string jwkCertificateFilename = Constants.Certificates.JwtCertificateFilename, + string jwkCertificatePassword = Constants.Certificates.JwtCertificatePassword) { Log.Information(Constants.LogTemplates.StartedFunctionInClass, nameof(SendRequest), nameof(DataHolderTokenService)); @@ -89,20 +88,21 @@ public async Task SendRequest( { formFields.Add(new KeyValuePair("client_assertion", customClientAssertion)); } - else if (useClientAssertion) //only check if we haven't provided custom client assertion + else if (useClientAssertion) { + // only check if we haven't provided custom client assertion var clientAssertion = new PrivateKeyJwtService { CertificateFilename = jwkCertificateFilename, CertificatePassword = jwkCertificatePassword, // Allow for clientId to be deliberately omitted from the JWT - Issuer = issuerClaim == Constants.Omit ? "" : issuerClaim ?? throw new InvalidOperationException($"{nameof(issuerClaim)} can not be empty unless intentionally omitted.").Log(), + Issuer = issuerClaim == Constants.Omit ? string.Empty : issuerClaim ?? throw new InvalidOperationException($"{nameof(issuerClaim)} can not be empty unless intentionally omitted.").Log(), // Don't check for issuer if we are deliberately omitting clientId RequireIssuer = clientId != Constants.Omit, - Audience = URL + Audience = URL, }.Generate(); formFields.Add(new KeyValuePair("client_assertion", clientAssertion)); @@ -145,8 +145,9 @@ await client.PutAsync(URL, content) : } /// - /// Use authCode to get access token + /// Use authCode to get access token. /// + /// Task representing the asynchronous operation. public async Task GetAccessToken(string authCode) { Log.Information(Constants.LogTemplates.StartedFunctionInClass, nameof(GetAccessToken), nameof(DataHolderTokenService)); @@ -162,8 +163,9 @@ await client.PutAsync(URL, content) : } /// - /// Use authCode to get tokens. + /// Use authCode to get tokens. /// + /// Task representing the asynchronous operation. public async Task GetResponse(string authCode, int? shareDuration = null, string? clientId = null, string? redirectUri = null, @@ -171,8 +173,7 @@ await client.PutAsync(URL, content) : string? certificatePassword = Constants.Certificates.CertificatePassword, string? jwkCertificateFilename = Constants.Certificates.JwtCertificateFilename, string? jwkCertificatePassword = Constants.Certificates.JwtCertificatePassword, - string? scope = null //added for auth server tests - ) + string? scope = null) // added for auth server tests { Log.Information(Constants.LogTemplates.StartedFunctionInClass, nameof(GetResponse), nameof(DataHolderTokenService)); @@ -181,7 +182,7 @@ await client.PutAsync(URL, content) : redirectUri = _options.SOFTWAREPRODUCT_REDIRECT_URI_FOR_INTEGRATION_TESTS; } - if (clientId == null) + if (clientId == null) { clientId = _options.LastRegisteredClientId; } @@ -194,8 +195,7 @@ await client.PutAsync(URL, content) : certificatePassword: certificatePassword, jwkCertificateFilename: jwkCertificateFilename, jwkCertificatePassword: jwkCertificatePassword, - scope: scope - ); + scope: scope); if (responseMessage.StatusCode != HttpStatusCode.OK) { @@ -208,8 +208,9 @@ await client.PutAsync(URL, content) : } /// - /// Use refresh token to get tokens + /// Use refresh token to get tokens. /// + /// Task representing the asynchronous operation. public async Task GetResponseUsingRefreshToken(string? refreshToken, string? scope = null) { Log.Information(Constants.LogTemplates.StartedFunctionInClass, nameof(GetResponseUsingRefreshToken), nameof(DataHolderTokenService)); @@ -219,8 +220,7 @@ await client.PutAsync(URL, content) : var tokenResponseMessage = await SendRequest( grantType: "refresh_token", refreshToken: refreshToken, - scope: scope - ); + scope: scope); if (tokenResponseMessage.StatusCode != HttpStatusCode.OK) { diff --git a/Source/ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation/Services/PrivateKeyJwtService.cs b/Source/ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation/Services/PrivateKeyJwtService.cs index a26158a..a460c27 100644 --- a/Source/ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation/Services/PrivateKeyJwtService.cs +++ b/Source/ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation/Services/PrivateKeyJwtService.cs @@ -1,18 +1,22 @@ -using System.IdentityModel.Tokens.Jwt; -using System.Security.Claims; -using System.Security.Cryptography.X509Certificates; -using ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation.Interfaces; -using Microsoft.IdentityModel.Tokens; -using Serilog; - namespace ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation.Services { + using System.IdentityModel.Tokens.Jwt; + using System.Security.Claims; + using System.Security.Cryptography.X509Certificates; + using ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation.Interfaces; + using Microsoft.IdentityModel.Tokens; + using Serilog; + public class PrivateKeyJwtService : IPrivateKeyJwtService { public bool RequireIssuer { get; init; } = true; + public string CertificateFilename { get; set; } + public string CertificatePassword { get; set; } + public string Issuer { get; set; } + public string Audience { get; set; } public string Generate() @@ -21,7 +25,7 @@ public string Generate() { new Claim("sub", Issuer), new Claim("jti", Guid.NewGuid().ToString()), - new Claim("iat", DateTimeOffset.UtcNow.ToUnixTimeSeconds().ToString(), ClaimValueTypes.Integer) + new Claim("iat", DateTimeOffset.UtcNow.ToUnixTimeSeconds().ToString(), ClaimValueTypes.Integer), }; return Generate(claims, DateTime.UtcNow.AddMinutes(10)); @@ -35,12 +39,9 @@ private string Generate(IEnumerable claims, DateTime expires) var x509SigningCredentials = new X509SigningCredentials(certificate, SecurityAlgorithms.RsaSsaPssSha256); - if (RequireIssuer) + if (RequireIssuer && string.IsNullOrEmpty(Issuer)) { - if (string.IsNullOrEmpty(Issuer)) - { - throw new ArgumentException("issuer must be provided"); - } + throw new ArgumentException("issuer must be provided"); } if (string.IsNullOrEmpty(Audience)) diff --git a/Source/ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation/Services/RegisterSSAService.cs b/Source/ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation/Services/RegisterSSAService.cs index ed565ec..afcf57f 100644 --- a/Source/ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation/Services/RegisterSSAService.cs +++ b/Source/ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation/Services/RegisterSSAService.cs @@ -1,11 +1,11 @@ -using ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation.Enums; -using ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation.Interfaces; -using ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation.Models.Options; -using Microsoft.Extensions.Options; -using Serilog; - namespace ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation.Services { + using ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation.Enums; + using ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation.Interfaces; + using ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation.Models.Options; + using Microsoft.Extensions.Options; + using Serilog; + public class RegisterSsaService : IRegisterSsaService { private readonly TestAutomationOptions _options; @@ -18,9 +18,11 @@ public RegisterSsaService(IOptions options, IOptions - /// Get SSA from the Register + /// Get SSA from the Register. /// + /// Task representing the asynchronous operation. public async Task GetSSA( string brandId, string softwareProductId, @@ -36,12 +38,12 @@ public async Task GetSSA( industry = _options.INDUSTRY switch { Industry.BANKING => Industry.BANKING, - Industry.ENERGY => Industry.ALL, //Energy was using the ALL parameter + Industry.ENERGY => Industry.ALL, // Energy was using the ALL parameter _ => throw new ArgumentException($"{nameof(_options.INDUSTRY)}") }; } - // Get access token + // Get access token var registerAccessToken = await new AccessTokenService(_options.DH_MTLS_AUTHSERVER_TOKEN_URL) { URL = _options.REGISTER_MTLS_TOKEN_URL, @@ -54,10 +56,10 @@ public async Task GetSSA( ClientAssertionType = Constants.ClientAssertionType, GrantType = "client_credentials", Issuer = softwareProductId, - Audience = _options.REGISTER_MTLS_TOKEN_URL + Audience = _options.REGISTER_MTLS_TOKEN_URL, }.GetAsync(_options.DH_MTLS_GATEWAY_URL, _authServerOptions.XTLSCLIENTCERTTHUMBPRINT, _authServerOptions.STANDALONE); - // Get the SSA + // Get the SSA var api = _apiServiceDirector.BuildRegisterSSAAPI(industry, brandId, softwareProductId, registerAccessToken, xv); var response = await api.SendAsync(); diff --git a/Source/ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation/Services/SqlQueryService.cs b/Source/ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation/Services/SqlQueryService.cs index 0f1cb70..6339e97 100644 --- a/Source/ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation/Services/SqlQueryService.cs +++ b/Source/ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation/Services/SqlQueryService.cs @@ -1,14 +1,13 @@ -using ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation.Enums; -using ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation.Extensions; -using ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation.Interfaces; -using ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation.Models.Options; -using Dapper; -using Microsoft.Data.SqlClient; -using Microsoft.Extensions.Options; -using Serilog; - -namespace ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation.Services +namespace ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation.Services { + using ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation.Enums; + using ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation.Extensions; + using ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation.Interfaces; + using ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation.Models.Options; + using Dapper; + using Microsoft.Data.SqlClient; + using Microsoft.Extensions.Options; + using Serilog; public class SqlQueryService : ISqlQueryService { @@ -20,8 +19,9 @@ public SqlQueryService(IOptions options) } /// - /// Get DCR ClientId for a SoftwareProductID + /// Get DCR ClientId for a SoftwareProductID. /// + /// string. public string GetClientId(string softwareProductId) { Log.Information(Constants.LogTemplates.StartedFunctionInClass, nameof(GetClientId), nameof(SqlQueryService)); @@ -33,7 +33,7 @@ public string GetClientId(string softwareProductId) new { ClaimType = "SOFTWARE_ID", - ClaimValue = softwareProductId.ToUpper() + ClaimValue = softwareProductId.ToUpper(), }); if (string.IsNullOrEmpty(clientId)) diff --git a/Source/ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation/SharedBaseTest.cs b/Source/ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation/SharedBaseTest.cs index 4432115..99eee0a 100644 --- a/Source/ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation/SharedBaseTest.cs +++ b/Source/ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation/SharedBaseTest.cs @@ -1,21 +1,22 @@ -using ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation.Attributes; -using FluentAssertions.Execution; -using Microsoft.Extensions.Configuration; -using Serilog; -using Serilog.Extensions.Hosting; -using Xunit.DependencyInjection; - namespace ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation { + using ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation.Attributes; + using FluentAssertions.Execution; + using Microsoft.Extensions.Configuration; + using Serilog; + using Serilog.Extensions.Hosting; + using Xunit.DependencyInjection; + [DisplayTestMethodName] abstract public class SharedBaseTest { public IAssertionStrategy BaseTestAssertionStrategy { get; init; } + protected SharedBaseTest(ITestOutputHelperAccessor testOutputHelperAccessor, IConfiguration config) { BaseTestAssertionStrategy = new TestAssertionStrategy(); - //Will only reload the first time, as it is frozen after that + // Will only reload the first time, as it is frozen after that ((ReloadableLogger)Log.Logger).Reload(lc => { return lc @@ -25,12 +26,12 @@ protected SharedBaseTest(ITestOutputHelperAccessor testOutputHelperAccessor, ICo try { - //Workaround as we can't tell if the Logger has been frozen, but it will fail if we try to freeze it + // Workaround as we can't tell if the Logger has been frozen, but it will fail if we try to freeze it ((ReloadableLogger)Log.Logger).Freeze(); } catch (Exception) { - //No need to add to log as the reconfiguration wasn't needde + // No need to add to log as the reconfiguration wasn't needde return; } diff --git a/Source/ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation/TestAssertionStrategy.cs b/Source/ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation/TestAssertionStrategy.cs index fc052cf..59b5e78 100644 --- a/Source/ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation/TestAssertionStrategy.cs +++ b/Source/ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation/TestAssertionStrategy.cs @@ -1,16 +1,15 @@ -using System; -using System.Collections.Generic; -using System.Globalization; -using System.Linq; -using System.Text; -using System.Threading.Tasks; -using FluentAssertions.Execution; -using Serilog; - -namespace ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation +namespace ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation { + using System; + using System.Collections.Generic; + using System.Globalization; + using System.Linq; + using System.Text; + using FluentAssertions.Execution; + using Serilog; + /// - /// A custom assertion strategy used for Participant Tooling assertion scopes which is a close copy of CollectingAssertionStratgy, but required due to the protection level of that class being internal + /// A custom assertion strategy used for Participant Tooling assertion scopes which is a close copy of CollectingAssertionStratgy, but required due to the protection level of that class being internal. /// public class TestAssertionStrategy : IAssertionStrategy { @@ -24,6 +23,7 @@ public class TestAssertionStrategy : IAssertionStrategy /// /// Discards and returns the failure messages that happened up to now. /// + /// string. public IEnumerable DiscardFailures() { var discardedFailures = _failureMessages.ToArray(); @@ -33,7 +33,7 @@ public IEnumerable DiscardFailures() /// /// Will throw a combined exception for any failures have been collected. - /// Some additional logging has been added for better reporting of issues + /// Some additional logging has been added for better reporting of issues. /// public void ThrowIfAny(IDictionary context) { diff --git a/Source/ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation/UI/Pages/Authorisation/AuthenticateLoginPage.cs b/Source/ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation/UI/Pages/Authorisation/AuthenticateLoginPage.cs index 92b775b..5b7547a 100644 --- a/Source/ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation/UI/Pages/Authorisation/AuthenticateLoginPage.cs +++ b/Source/ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation/UI/Pages/Authorisation/AuthenticateLoginPage.cs @@ -1,9 +1,9 @@ -using ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation.Extensions; -using Microsoft.Playwright; -using Serilog; - -namespace ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation.UI.Pages.Authorisation +namespace ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation.UI.Pages.Authorisation { + using ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation.Extensions; + using Microsoft.Playwright; + using Serilog; + public class AuthenticateLoginPage { private readonly IPage _page; @@ -29,8 +29,8 @@ public AuthenticateLoginPage(IPage page, bool waitForPageToLoad = true) public async Task EnterCustomerId(string customerId) { await _txtCustomerId.WaitForAsync(); - await Task.Delay(1000); //require for JS delayed defaulting of field. It can sometimes overwrite the entered value. - await _txtCustomerId.FillAsync(""); + await Task.Delay(1000); // require for JS delayed defaulting of field. It can sometimes overwrite the entered value. + await _txtCustomerId.FillAsync(string.Empty); await _txtCustomerId.FillAsync(customerId); } @@ -52,12 +52,11 @@ public async Task CustomerIdErrorExists(string errorToCheckFor) return await element.IsVisibleAsync(); } - catch (TimeoutException) { } + catch (TimeoutException) { Log.Error("A timeout exception was caught in {Class}.{Function}", nameof(AuthenticateLoginPage), nameof(CustomerIdErrorExists)); return false; } } - } } diff --git a/Source/ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation/UI/Pages/Authorisation/ConfirmAccountSharingPage.cs b/Source/ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation/UI/Pages/Authorisation/ConfirmAccountSharingPage.cs index b31531d..dbad6d9 100644 --- a/Source/ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation/UI/Pages/Authorisation/ConfirmAccountSharingPage.cs +++ b/Source/ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation/UI/Pages/Authorisation/ConfirmAccountSharingPage.cs @@ -1,15 +1,14 @@ -using ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation.Extensions; -using Microsoft.Playwright; - -namespace ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation.UI.Pages.Authorisation +namespace ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation.UI.Pages.Authorisation { + using ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation.Extensions; + using Microsoft.Playwright; + public class ConfirmAccountSharingPage { private readonly IPage _page; private readonly ILocator _btnAuthorise; private readonly ILocator _btnDeny; - public ConfirmAccountSharingPage(IPage page, bool waitForPageToLoad = true) { _page = page; @@ -26,6 +25,7 @@ public async Task ClickAuthorise() { await _btnAuthorise.ClickAsync(); } + public async Task ClickDeny() { await _btnDeny.ClickAsync(); @@ -39,7 +39,7 @@ public async Task ClickCLusterHeadingToExpand(string clusterHeading) public async Task GetClusterDetail(string clusterHeading) { var stopAt = DateTime.Now.AddSeconds(10); - string clusterDetail = ""; + string clusterDetail = string.Empty; // Need a custom sync to work around issue where cluster details sometimes do not load in time. // Retry for up to 10 Seconds to get a non blank value for cluser details. @@ -50,7 +50,6 @@ public async Task GetClusterDetail(string clusterHeading) } return clusterDetail; - } public async Task GetClusterCount() @@ -58,6 +57,5 @@ public async Task GetClusterCount() var allClusterHeadings = await _page.QuerySelectorAllAsync("//div[contains(@class,'MuiAccordionSummary')]/a"); return allClusterHeadings.Count; } - } } diff --git a/Source/ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation/UI/Pages/Authorisation/OneTimePasswordPage.cs b/Source/ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation/UI/Pages/Authorisation/OneTimePasswordPage.cs index fa0fe69..a0157b6 100644 --- a/Source/ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation/UI/Pages/Authorisation/OneTimePasswordPage.cs +++ b/Source/ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation/UI/Pages/Authorisation/OneTimePasswordPage.cs @@ -1,9 +1,9 @@ -using ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation.Extensions; -using Microsoft.Playwright; -using Serilog; - -namespace ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation.UI.Pages.Authorisation +namespace ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation.UI.Pages.Authorisation { + using ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation.Extensions; + using Microsoft.Playwright; + using Serilog; + public class OneTimePasswordPage { private readonly IPage _page; @@ -23,8 +23,8 @@ public OneTimePasswordPage(IPage page) _divAlert = _page.Locator("//div[@role='alert']", true); _headDataHolderheading = _page.Locator("//h6", true); _btnCloseAlert = _page.Locator("[role=\"alert\"]>>[title=\"Close\"]", true); - } + public async Task EnterOtp(string otp) { await _txtOneTimePassword.WaitForAsync(); @@ -70,16 +70,15 @@ public async Task OtpErrorExists(string errorToCheckFor) { try { - var element = await _page.WaitForSelectorAsync($"//p[text()='{errorToCheckFor}']",true); + var element = await _page.WaitForSelectorAsync($"//p[text()='{errorToCheckFor}']", true); return await element.IsVisibleAsync(); } - catch (TimeoutException) { } + catch (TimeoutException) { - Log.Error("A timeout exception was caught in {Class}.{Function}",nameof(OneTimePasswordPage),nameof(OtpErrorExists)); + Log.Error("A timeout exception was caught in {Class}.{Function}", nameof(OneTimePasswordPage), nameof(OtpErrorExists)); return false; } } - } } diff --git a/Source/ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation/UI/Pages/Authorisation/SelectAccountsPage.cs b/Source/ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation/UI/Pages/Authorisation/SelectAccountsPage.cs index c8e1a46..b62a463 100644 --- a/Source/ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation/UI/Pages/Authorisation/SelectAccountsPage.cs +++ b/Source/ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation/UI/Pages/Authorisation/SelectAccountsPage.cs @@ -1,13 +1,12 @@ -using ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation.Extensions; -using Microsoft.IdentityModel.Tokens; -using Microsoft.Playwright; -using Serilog; - -namespace ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation.UI.Pages.Authorisation +namespace ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation.UI.Pages.Authorisation { + using ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation.Extensions; + using Microsoft.IdentityModel.Tokens; + using Microsoft.Playwright; + using Serilog; + public class SelectAccountsPage { - private readonly IPage _page; private readonly ILocator _btnContinue; private readonly ILocator _btnCancel; @@ -32,14 +31,15 @@ public async Task SelectAccount(string accountToSelect) await _page.Locator($"//input[@aria-labelledby='account-{accountToSelect}']", true).CheckAsync(); } + public async Task SelectAccounts(string[] accountsToSelect) { foreach (string accountToSelect in accountsToSelect) { await SelectAccount(accountToSelect.Trim()); } - } + public async Task SelectAccounts(string accountsToSelectCsv) { if (string.IsNullOrEmpty(accountsToSelectCsv)) @@ -63,31 +63,31 @@ public async Task SelectAllCheckboxes() { await input.CheckAsync(); } - } public async Task ClickContinue() { await _btnContinue.ClickAsync(); } + public async Task ClickCancel() { await _btnCancel.ClickAsync(); } + public async Task NoAccountSelectedErrorExists() { try { - var element = await _page.WaitForSelectorAsync($"//p[text()='Please select one or more Accounts']",true); + var element = await _page.WaitForSelectorAsync($"//p[text()='Please select one or more Accounts']", true); return await element.IsVisibleAsync(); } - catch (TimeoutException) { } + catch (TimeoutException) { Log.Error("A timeout exception was caught in {Class}.{Function}", nameof(SelectAccountsPage), nameof(NoAccountSelectedErrorExists)); return false; } } - } } diff --git a/Source/ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation/UI/PlaywrightDriver.cs b/Source/ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation/UI/PlaywrightDriver.cs index d52bcb8..ce6fe48 100644 --- a/Source/ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation/UI/PlaywrightDriver.cs +++ b/Source/ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation/UI/PlaywrightDriver.cs @@ -1,12 +1,14 @@ -using Microsoft.Playwright; -using Serilog; - -namespace ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation.UI +namespace ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation.UI { + using Microsoft.Playwright; + using Serilog; + public class PlaywrightDriver { public IBrowser Browser { get; set; } = null!; + private IPlaywright PlaywrightInstance { get; set; } = null!; + private IBrowserContext? _browserContext; private string? _mediaFilePrefix; private const string _mediaFilePath = "/testresults/media"; @@ -25,20 +27,20 @@ public async Task NewBrowserContext(string? mediaFilePrefix = n { _mediaFilePrefix = mediaFilePrefix; } - + PlaywrightInstance = await Playwright.CreateAsync(); Browser = await GetBrowser(); var options = new BrowserNewContextOptions { - IgnoreHTTPSErrors = true, + IgnoreHTTPSErrors = true, }; options.ViewportSize = new ViewportSize { Width = 2000, - Height = 1000 - }; + Height = 1000, + }; _browserContext = await Browser.NewContextAsync(options); @@ -69,7 +71,7 @@ private async Task GetBrowser() { Headless = false, }); - } + } } public async Task DisposeAsync() diff --git a/Source/ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation/XUnit/AlphabeticalOrderer.cs b/Source/ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation/XUnit/AlphabeticalOrderer.cs index 21bc9e3..f05224f 100644 --- a/Source/ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation/XUnit/AlphabeticalOrderer.cs +++ b/Source/ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation/XUnit/AlphabeticalOrderer.cs @@ -1,10 +1,10 @@ -using System.Collections.Generic; -using System.Linq; -using Xunit.Abstractions; -using Xunit.Sdk; - namespace ConsumerDataRight.ParticipantTooling.MockSolution.TestAutomation.XUnit { + using System.Collections.Generic; + using System.Linq; + using Xunit.Abstractions; + using Xunit.Sdk; + public class AlphabeticalOrderer : ITestCaseOrderer { public IEnumerable OrderTestCases(IEnumerable testCases) where TTestCase : ITestCase => diff --git a/Source/Directory.Build.props b/Source/Directory.Build.props new file mode 100644 index 0000000..c22f455 --- /dev/null +++ b/Source/Directory.Build.props @@ -0,0 +1,8 @@ + + + net8.0 + true + true + true + + \ No newline at end of file