diff --git a/.github/workflows/codecoverage.yml b/.github/workflows/codecoverage.yml index 68b73fb..a3bc8a8 100644 --- a/.github/workflows/codecoverage.yml +++ b/.github/workflows/codecoverage.yml @@ -2,46 +2,52 @@ name: Code Coverage on: push: - # branches to consider in the event; optional, defaults to all branches: - main workflow_dispatch: -jobs: +permissions: + contents: read + +jobs: build: - name: "Code Coverage" + name: Code Coverage env: - ASPNETCORE_ENVIRONMENT: "Production" + ASPNETCORE_ENVIRONMENT: Production runs-on: ubuntu-latest steps: - - uses: actions/checkout@v2.3.4 - - - name: Restore Nuget Packages - run: dotnet restore FileProcessor.sln --source ${{ secrets.PUBLICFEEDURL }} --source ${{ secrets.PRIVATEFEED_URL }} - - - name: Build Code - run: dotnet build FileProcessor.sln --configuration Release - - - name: Run Unit Tests - run: | - echo "ASPNETCORE_ENVIRONMENT are > ${ASPNETCORE_ENVIRONMENT}" - dotnet test "FileProcessor.BusinessLogic.Tests\FileProcessor.BusinessLogic.Tests.csproj" /p:CollectCoverage=true /p:Exclude="[xunit*]*" /p:ExcludeByAttribute="Obsolete" /p:ExcludeByAttribute="GeneratedCodeAttribute" /p:ExcludeByAttribute="CompilerGeneratedAttribute" /p:ExcludeByAttribute="ExcludeFromCodeCoverageAttribute" /p:CoverletOutput="../lcov1.info" /maxcpucount:1 /p:CoverletOutputFormat="lcov" - dotnet test "FileProcessor.FileAggregate.Tests\FileProcessor.FileAggregate.Tests.csproj" /p:CollectCoverage=true /p:Exclude="[xunit*]*" /p:ExcludeByAttribute="Obsolete" /p:ExcludeByAttribute="GeneratedCodeAttribute" /p:ExcludeByAttribute="CompilerGeneratedAttribute" /p:ExcludeByAttribute="ExcludeFromCodeCoverageAttribute" /p:CoverletOutput="../lcov2.info" /maxcpucount:1 /p:CoverletOutputFormat="lcov" - dotnet test "FileProcessor.FileImportLogAggregate.Tests\FileProcessor.FileImportLogAggregate.Tests.csproj" /p:CollectCoverage=true /p:Exclude="[xunit*]*" /p:ExcludeByAttribute="Obsolete" /p:ExcludeByAttribute="GeneratedCodeAttribute" /p:ExcludeByAttribute="CompilerGeneratedAttribute" /p:ExcludeByAttribute="ExcludeFromCodeCoverageAttribute" /p:CoverletOutput="../lcov3.info" /maxcpucount:1 /p:CoverletOutputFormat="lcov" - - - name: Install LCOV merger - run: npm install -g lcov-result-merger - - - name: Merge LCOV reports - run: | - mkdir -p coverage - lcov-result-merger "*.info" > lcov.info - - - name: Upload merged coverage to Codacy - uses: codacy/codacy-coverage-reporter-action@v1 - with: - project-token: ${{ secrets.CODACY_PROJECT_TOKEN }} - coverage-reports: ./lcov.info + - uses: actions/checkout@v6 + + - name: Setup .NET + uses: actions/setup-dotnet@v4 + with: + dotnet-version: 10.0.x + + - name: Restore Nuget Packages + run: dotnet restore FileProcessor.sln --source ${{ secrets.PUBLICFEEDURL }} --source ${{ secrets.PRIVATEFEED_URL }} + + - name: Build Code + run: dotnet build FileProcessor.sln --configuration Release --no-restore + + - name: Run Unit Tests + run: | + echo "ASPNETCORE_ENVIRONMENT are > ${ASPNETCORE_ENVIRONMENT}" + dotnet run --project "FileProcessor.BusinessLogic.Tests/FileProcessor.BusinessLogic.Tests.csproj" --configuration Release --no-build -- --coverage --coverage-output-format cobertura --coverage-output coverage.cobertura.xml --results-directory "./coverage/businesslogic" + dotnet run --project "FileProcessor.FileAggregate.Tests/FileProcessor.FileAggregate.Tests.csproj" --configuration Release --no-build -- --coverage --coverage-output-format cobertura --coverage-output coverage.cobertura.xml --results-directory "./coverage/fileaggregate" + dotnet run --project "FileProcessor.FileImportLogAggregate.Tests/FileProcessor.FileImportLogAggregate.Tests.csproj" --configuration Release --no-build -- --coverage --coverage-output-format cobertura --coverage-output coverage.cobertura.xml --results-directory "./coverage/fileimportlogaggregate" + + - name: Merge Coverage Reports + uses: danielpalme/ReportGenerator-GitHub-Action@v5 + with: + reports: ./coverage/**/*.cobertura.xml + targetdir: ./coverage-report + reporttypes: Cobertura + + - name: Upload coverage to Codacy + uses: codacy/codacy-coverage-reporter-action@v1 + with: + project-token: ${{ secrets.CODACY_PROJECT_TOKEN }} + coverage-reports: ./coverage-report/Cobertura.xml diff --git a/.github/workflows/nightlybuild.yml b/.github/workflows/nightlybuild.yml index 4dad0b9..029c05d 100644 --- a/.github/workflows/nightlybuild.yml +++ b/.github/workflows/nightlybuild.yml @@ -12,54 +12,59 @@ permissions: jobs: build: - name: "Nightly Build" + name: Nightly Build env: - ASPNETCORE_ENVIRONMENT: "Production" + ASPNETCORE_ENVIRONMENT: Production runs-on: ubuntu-latest steps: - - uses: actions/checkout@v2.3.4 + - uses: actions/checkout@v6 + + - name: Setup .NET + uses: actions/setup-dotnet@v4 + with: + dotnet-version: 10.0.x - - name: Set Up Variables - run: echo "action_url=$GITHUB_SERVER_URL/$GITHUB_REPOSITORY/actions/runs/$GITHUB_RUN_ID" >> $GITHUB_ENV + - name: Set Up Variables + run: echo "action_url=$GITHUB_SERVER_URL/$GITHUB_REPOSITORY/actions/runs/$GITHUB_RUN_ID" >> $GITHUB_ENV - - name: Restore Nuget Packages - run: dotnet restore FileProcessor.sln --source ${{ secrets.PUBLICFEEDURL }} --source ${{ secrets.PRIVATEFEED_URL }} + - name: Restore Nuget Packages + run: dotnet restore FileProcessor.sln --source ${{ secrets.PUBLICFEEDURL }} --source ${{ secrets.PRIVATEFEED_URL }} - - name: Build Code - run: dotnet build FileProcessor.sln --configuration Release + - name: Build Code + run: dotnet build FileProcessor.sln --configuration Release --no-restore - - name: Run Unit Tests - run: | - echo "ASPNETCORE_ENVIRONMENT are > ${ASPNETCORE_ENVIRONMENT}" - dotnet test "FileProcessor.BusinessLogic.Tests\FileProcessor.BusinessLogic.Tests.csproj" /p:CollectCoverage=true /p:Exclude="[xunit*]*" /p:ExcludeByAttribute="Obsolete" /p:ExcludeByAttribute="GeneratedCodeAttribute" /p:ExcludeByAttribute="CompilerGeneratedAttribute" /p:ExcludeByAttribute="ExcludeFromCodeCoverageAttribute" /p:CoverletOutput="../lcov1.info" /maxcpucount:1 /p:CoverletOutputFormat="lcov" - dotnet test "FileProcessor.FileAggregate.Tests\FileProcessor.FileAggregate.Tests.csproj" /p:CollectCoverage=true /p:Exclude="[xunit*]*" /p:ExcludeByAttribute="Obsolete" /p:ExcludeByAttribute="GeneratedCodeAttribute" /p:ExcludeByAttribute="CompilerGeneratedAttribute" /p:ExcludeByAttribute="ExcludeFromCodeCoverageAttribute" /p:CoverletOutput="../lcov2.info" /maxcpucount:1 /p:CoverletOutputFormat="lcov" - dotnet test "FileProcessor.FileImportLogAggregate.Tests\FileProcessor.FileImportLogAggregate.Tests.csproj" /p:CollectCoverage=true /p:Exclude="[xunit*]*" /p:ExcludeByAttribute="Obsolete" /p:ExcludeByAttribute="GeneratedCodeAttribute" /p:ExcludeByAttribute="CompilerGeneratedAttribute" /p:ExcludeByAttribute="ExcludeFromCodeCoverageAttribute" /p:CoverletOutput="../lcov3.info" /maxcpucount:1 /p:CoverletOutputFormat="lcov" + - name: Run Unit Tests + run: | + echo "ASPNETCORE_ENVIRONMENT are > ${ASPNETCORE_ENVIRONMENT}" + dotnet test "FileProcessor.BusinessLogic.Tests/FileProcessor.BusinessLogic.Tests.csproj" --configuration Release --no-build + dotnet test "FileProcessor.FileAggregate.Tests/FileProcessor.FileAggregate.Tests.csproj" --configuration Release --no-build + dotnet test "FileProcessor.FileImportLogAggregate.Tests/FileProcessor.FileImportLogAggregate.Tests.csproj" --configuration Release --no-build - - name: Build Docker Image - run: docker build . --file FileProcessor/Dockerfile --tag fileprocessor:latest - - - name: Run Integration Tests - run: dotnet test "FileProcessor.IntegrationTests\FileProcessor.IntegrationTests.csproj" + - name: Build Docker Image + run: docker build . --file FileProcessor/Dockerfile --tag fileprocessor:latest + + - name: Run Integration Tests + run: dotnet test "FileProcessor.IntegrationTests/FileProcessor.IntegrationTests.csproj" --configuration Release --no-build - - uses: actions/upload-artifact@v4.4.0 - with: - name: tracelogs - path: /home/runner/trace/ + - uses: actions/upload-artifact@v4.4.0 + with: + name: tracelogs + path: /home/runner/trace/ - - name: Notify on nightly failure - if: ${{ failure() }} - uses: TransactionProcessing/org-ci-workflows/.github/actions/nightly-failure-issue@main - with: - github_token: ${{ secrets.GITHUB_TOKEN }} - title: Investigate Nightly Build Failure - labels: nightlybuild - dedupe_key: nightlybuild - body: | - Repo: ${{ github.repository }} - Run: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }} - Commit: ${{ github.sha }} - Workflow: ${{ github.workflow }} - Job: ${{ github.job }} + - name: Notify on nightly failure + if: ${{ failure() }} + uses: TransactionProcessing/org-ci-workflows/.github/actions/nightly-failure-issue@main + with: + github_token: ${{ secrets.GITHUB_TOKEN }} + title: Investigate Nightly Build Failure + labels: nightlybuild + dedupe_key: nightlybuild + body: | + Repo: ${{ github.repository }} + Run: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }} + Commit: ${{ github.sha }} + Workflow: ${{ github.workflow }} + Job: ${{ github.job }} diff --git a/.github/workflows/pullrequest.yml b/.github/workflows/pullrequest.yml index b0713f4..9ac31a4 100644 --- a/.github/workflows/pullrequest.yml +++ b/.github/workflows/pullrequest.yml @@ -7,57 +7,62 @@ on: jobs: build: - name: "Build and Test Pull Requests" + name: Build and Test Pull Requests env: - ASPNETCORE_ENVIRONMENT: "Production" + ASPNETCORE_ENVIRONMENT: Production runs-on: ubuntu-latest steps: - - uses: actions/checkout@v2.3.4 - - - name: Echo vars - run: | - echo "CI is > ${CI}" - echo "HOME is > ${HOME}" - - - name: Restore Nuget Packages - run: dotnet restore FileProcessor.sln --source ${{ secrets.PUBLICFEEDURL }} --source ${{ secrets.PRIVATEFEED_URL }} - - - name: Build Code - run: dotnet build FileProcessor.sln --configuration Release - - - name: Run Unit Tests - run: | - echo "ASPNETCORE_ENVIRONMENT are > ${ASPNETCORE_ENVIRONMENT}" - dotnet test "FileProcessor.BusinessLogic.Tests\FileProcessor.BusinessLogic.Tests.csproj" --configuration Release --no-build --verbosity normal --logger "trx;LogFileName=businesslogic-test-results.trx" - dotnet test "FileProcessor.FileAggregate.Tests\FileProcessor.FileAggregate.Tests.csproj" --configuration Release --no-build --verbosity normal --logger "trx;LogFileName=fileaggregate-test-results.trx" - dotnet test "FileProcessor.FileImportLogAggregate.Tests\FileProcessor.FileImportLogAggregate.Tests.csproj" --configuration Release --no-build --verbosity normal --logger "trx;LogFileName=fileimportlogaggregate-test-results.trx" - - - name: Build Docker Image - run: docker build . --file FileProcessor/Dockerfile --tag fileprocessor:latest - - - name: Run Integration Tests - run: dotnet test "FileProcessor.IntegrationTests\FileProcessor.IntegrationTests.csproj" --filter Category=PRTest --configuration Release --no-build --verbosity normal --logger "trx;LogFileName=integration-test-results.trx" - - - uses: actions/upload-artifact@v4.4.0 - with: - name: tracelogs - path: /home/runner/trace/ - - - name: Publish test results - uses: dorny/test-reporter@v1 - if: always() - with: + - uses: actions/checkout@v6 + + - name: Setup .NET + uses: actions/setup-dotnet@v4 + with: + dotnet-version: 10.0.x + + - name: Echo vars + run: | + echo "CI is > ${CI}" + echo "HOME is > ${HOME}" + + - name: Restore Nuget Packages + run: dotnet restore FileProcessor.sln --source ${{ secrets.PUBLICFEEDURL }} --source ${{ secrets.PRIVATEFEED_URL }} + + - name: Build Code + run: dotnet build FileProcessor.sln --configuration Release --no-restore + + - name: Run Unit Tests + run: | + echo "ASPNETCORE_ENVIRONMENT are > ${ASPNETCORE_ENVIRONMENT}" + dotnet test "FileProcessor.BusinessLogic.Tests/FileProcessor.BusinessLogic.Tests.csproj" --configuration Release --no-build --verbosity normal -- --report-xunit-trx --report-xunit-trx-filename businesslogic-test-results.trx + dotnet test "FileProcessor.FileAggregate.Tests/FileProcessor.FileAggregate.Tests.csproj" --configuration Release --no-build --verbosity normal -- --report-xunit-trx --report-xunit-trx-filename fileaggregate-test-results.trx + dotnet test "FileProcessor.FileImportLogAggregate.Tests/FileProcessor.FileImportLogAggregate.Tests.csproj" --configuration Release --no-build --verbosity normal -- --report-xunit-trx --report-xunit-trx-filename fileimportlogaggregate-test-results.trx + + - name: Build Docker Image + run: docker build . --file FileProcessor/Dockerfile --tag fileprocessor:latest + + - name: Run Integration Tests + run: dotnet test "FileProcessor.IntegrationTests/FileProcessor.IntegrationTests.csproj" --configuration Release --no-build --verbosity normal -- --filter "Category=PRTest" + + - uses: actions/upload-artifact@v4.4.0 + with: + name: tracelogs + path: /home/runner/trace/ + + - name: Publish test results + uses: dorny/test-reporter@v1 + if: always() + with: name: Unit Test Results path: '**/TestResults/*.trx' reporter: dotnet-trx fail-on-error: true - - - name: Upload test results - uses: actions/upload-artifact@v4 - if: always() - with: + + - name: Upload test results + uses: actions/upload-artifact@v4 + if: always() + with: name: test-results - path: '**/TestResults/*.trx' - retention-days: 30 \ No newline at end of file + path: '**/TestResults/*' + retention-days: 30 diff --git a/Directory.Packages.props b/Directory.Packages.props index ec31b57..8987715 100644 --- a/Directory.Packages.props +++ b/Directory.Packages.props @@ -4,59 +4,60 @@ - - - + + + - + - - - - - - - - - - + + + + + + + + + + + - + - + - - + + - - - - - - - - - - + + + + + + + + + + - - - - - - - - - - + + + + + + + + + + - \ No newline at end of file + diff --git a/FileProcessor.BusinessLogic.Tests/FileProcessor.BusinessLogic.Tests.csproj b/FileProcessor.BusinessLogic.Tests/FileProcessor.BusinessLogic.Tests.csproj index 1a14965..87a427c 100644 --- a/FileProcessor.BusinessLogic.Tests/FileProcessor.BusinessLogic.Tests.csproj +++ b/FileProcessor.BusinessLogic.Tests/FileProcessor.BusinessLogic.Tests.csproj @@ -2,6 +2,9 @@ net10.0 + Exe + true + true None false @@ -11,6 +14,7 @@ + diff --git a/FileProcessor.FileAggregate.Tests/FileProcessor.FileAggregate.Tests.csproj b/FileProcessor.FileAggregate.Tests/FileProcessor.FileAggregate.Tests.csproj index 8319203..9476828 100644 --- a/FileProcessor.FileAggregate.Tests/FileProcessor.FileAggregate.Tests.csproj +++ b/FileProcessor.FileAggregate.Tests/FileProcessor.FileAggregate.Tests.csproj @@ -2,12 +2,16 @@ net10.0 + Exe + true + true None false + diff --git a/FileProcessor.FileImportLogAggregate.Tests/FileProcessor.FileImportLogAggregate.Tests.csproj b/FileProcessor.FileImportLogAggregate.Tests/FileProcessor.FileImportLogAggregate.Tests.csproj index 78fe438..0deda4c 100644 --- a/FileProcessor.FileImportLogAggregate.Tests/FileProcessor.FileImportLogAggregate.Tests.csproj +++ b/FileProcessor.FileImportLogAggregate.Tests/FileProcessor.FileImportLogAggregate.Tests.csproj @@ -2,12 +2,16 @@ net10.0 + Exe + true + true None false + diff --git a/FileProcessor.FileProfileAggregate.Tests/FileProcessor.FileProfileAggregate.Tests.csproj b/FileProcessor.FileProfileAggregate.Tests/FileProcessor.FileProfileAggregate.Tests.csproj index c27c911..1429d19 100644 --- a/FileProcessor.FileProfileAggregate.Tests/FileProcessor.FileProfileAggregate.Tests.csproj +++ b/FileProcessor.FileProfileAggregate.Tests/FileProcessor.FileProfileAggregate.Tests.csproj @@ -2,12 +2,16 @@ net10.0 + Exe + true + true Full false + diff --git a/FileProcessor.IntegrationTests/Common/DockerHelper.cs b/FileProcessor.IntegrationTests/Common/DockerHelper.cs index f6c3637..8896398 100644 --- a/FileProcessor.IntegrationTests/Common/DockerHelper.cs +++ b/FileProcessor.IntegrationTests/Common/DockerHelper.cs @@ -1,7 +1,7 @@ -using System; +using DotNet.Testcontainers.Builders; +using System; using System.Collections.Generic; using System.Threading.Tasks; -using DotNet.Testcontainers.Builders; namespace FileProcessor.IntegrationTests.Common { @@ -11,6 +11,7 @@ namespace FileProcessor.IntegrationTests.Common using Shared.IntegrationTesting; using Shared.Serialisation; using System.Net.Http; + using TestHosts.Clients; using TransactionProcessor.Client; public class DockerHelper : global::Shared.IntegrationTesting.TestContainers.DockerHelper{ @@ -34,6 +35,8 @@ public class DockerHelper : global::Shared.IntegrationTesting.TestContainers.Doc public EventStoreProjectionManagementClient ProjectionManagementClient; + public IAgencyBankingClient AgencyBankingClient; + #endregion #region Constructors @@ -73,7 +76,7 @@ public override ContainerBuilder SetupFileProcessorContainer() { { "AppSettings:FileProfilePollingWindowInSeconds", "5" } }; - this.AdditionalVariables.Add(ContainerType.FileProcessor, variables); + this.AdditionalVariables[ContainerType.FileProcessor] = variables; return base.SetupFileProcessorContainer(); } @@ -85,7 +88,8 @@ public override async Task StartContainersForScenarioRun(String scenarioName, Do String SecurityServiceBaseAddressResolver(String api) => $"https://127.0.0.1:{this.SecurityServicePort}"; String FileProcessorBaseAddressResolver(String api) => $"http://127.0.0.1:{this.FileProcessorPort}"; String TransactionProcessorBaseAddressResolver(String api) => $"http://127.0.0.1:{this.TransactionProcessorPort}"; - + String TestHostServiceBaseAddressResolver(String api) => $"http://127.0.0.1:{this.TestHostServicePort}"; + HttpClientHandler clientHandler = new HttpClientHandler{ ServerCertificateCustomValidationCallback = (message, certificate2, @@ -109,7 +113,8 @@ public override async Task StartContainersForScenarioRun(String scenarioName, Do this.TransactionProcessorClient = new TransactionProcessorClient(TransactionProcessorBaseAddressResolver, httpClient, Serialise, Deserialise); this.TestHostHttpClient = new HttpClient(clientHandler); this.TestHostHttpClient.BaseAddress = new Uri($"http://127.0.0.1:{this.TestHostServicePort}"); - + this.AgencyBankingClient = new AgencyBankingClient(TestHostServiceBaseAddressResolver, httpClient, Serialise_CamelCase, this.Deserialise_CamelCase); + this.ProjectionManagementClient = new EventStoreProjectionManagementClient(ConfigureEventStoreSettings()); } @@ -123,6 +128,16 @@ Object Deserialise(String arg, Type type) return StringSerialiser.DeserializeObject(arg, type, new SerialiserOptions(SerialiserPropertyFormat.SnakeCase)); } + String Serialise_CamelCase(Object arg) + { + return StringSerialiser.Serialise(arg, new SerialiserOptions(SerialiserPropertyFormat.CamelCase)); + } + + Object Deserialise_CamelCase(String arg, Type type) + { + return StringSerialiser.DeserializeObject(arg, type, new SerialiserOptions(SerialiserPropertyFormat.CamelCase)); + } + #endregion } } diff --git a/FileProcessor.IntegrationTests/Common/GenericSteps.cs b/FileProcessor.IntegrationTests/Common/GenericSteps.cs index 80d2d96..08c6427 100644 --- a/FileProcessor.IntegrationTests/Common/GenericSteps.cs +++ b/FileProcessor.IntegrationTests/Common/GenericSteps.cs @@ -36,9 +36,7 @@ public async Task StartSystem() logger.Initialise(LogManager.GetLogger(scenarioName), scenarioName); LogManager.AddHiddenAssembly(typeof(NlogLogger).Assembly); - DockerServices dockerServices = DockerServices.EventStore | DockerServices.FileProcessor | DockerServices.MessagingService | - DockerServices.SecurityService | DockerServices.SqlServer | DockerServices.TestHost | DockerServices.TransactionProcessor | - DockerServices.TestHost | DockerServices.CallbackHandler | DockerServices.TransactionProcessorAcl; + DockerServices dockerServices = this.GetDockerServicesForScenario(); this.TestingContext.DockerHelper = new DockerHelper(); this.TestingContext.DockerHelper.Logger = logger; @@ -60,6 +58,23 @@ public async Task StartSystem() this.TestingContext.Logger.LogInformation("Containers for Scenario Run Started"); } + private DockerServices GetDockerServicesForScenario() + { + String scenarioTitle = this.ScenarioContext.ScenarioInfo.Title; + + // File profile CRUD scenarios only need the API, auth service, event store, and SQL. + // The FileProcessor health check still depends on the TransactionProcessor service, but + // the rest of the transaction-processing stack is unnecessary for these scenarios. + if (scenarioTitle.Contains("file profile", StringComparison.OrdinalIgnoreCase)) + { + return DockerServices.EventStore | DockerServices.FileProcessor | DockerServices.SecurityService | + DockerServices.SqlServer | DockerServices.TransactionProcessor; + } + + return DockerServices.EventStore | DockerServices.FileProcessor | DockerServices.MessagingService | + DockerServices.SecurityService | DockerServices.SqlServer | DockerServices.TestHost | DockerServices.TransactionProcessor; + } + [AfterScenario] public async Task StopSystem(){ DockerServices shareDockerServices = DockerServices.None; diff --git a/FileProcessor.IntegrationTests/FileProcessor.IntegrationTests.csproj b/FileProcessor.IntegrationTests/FileProcessor.IntegrationTests.csproj index e6ce79e..1ec2b98 100644 --- a/FileProcessor.IntegrationTests/FileProcessor.IntegrationTests.csproj +++ b/FileProcessor.IntegrationTests/FileProcessor.IntegrationTests.csproj @@ -2,6 +2,9 @@ net10.0 + Exe + true + true false diff --git a/FileProcessor.IntegrationTests/Steps/SharedSteps.cs b/FileProcessor.IntegrationTests/Steps/SharedSteps.cs index d309861..2c83ebb 100644 --- a/FileProcessor.IntegrationTests/Steps/SharedSteps.cs +++ b/FileProcessor.IntegrationTests/Steps/SharedSteps.cs @@ -27,6 +27,7 @@ namespace FileProcessor.IntegrationTests.Steps using System.IO; using System.Text.Json; using System.Threading; + using TestHosts.Clients; [Binding] [Scope(Tag = "shared")] @@ -38,24 +39,39 @@ public class SharedSteps private readonly SecurityServiceSteps SecurityServiceSteps; - private readonly TransactionProcessorSteps TransactionProcessorSteps; - - private readonly FileProcessorSteps FileProcessorSteps; + private TransactionProcessorSteps? TransactionProcessorSteps; + private FileProcessorSteps? FileProcessorSteps; + public SharedSteps(ScenarioContext scenarioContext, TestingContext testingContext) { ScenarioContext = scenarioContext; TestingContext = testingContext; this.SecurityServiceSteps = new SecurityServiceSteps(testingContext.DockerHelper.SecurityServiceClient); - this.TransactionProcessorSteps = new TransactionProcessorSteps(testingContext.DockerHelper.TransactionProcessorClient,testingContext.DockerHelper.TestHostHttpClient, testingContext.DockerHelper.ProjectionManagementClient); - this.FileProcessorSteps = new FileProcessorSteps(testingContext.DockerHelper.FileProcessorClient); + } + + private TransactionProcessorSteps GetTransactionProcessorSteps() + { + this.TransactionProcessorSteps ??= new TransactionProcessorSteps(this.TestingContext.DockerHelper.TransactionProcessorClient, + this.TestingContext.DockerHelper.TestHostHttpClient, + this.TestingContext.DockerHelper.ProjectionManagementClient, + this.TestingContext.DockerHelper.AgencyBankingClient); + + return this.TransactionProcessorSteps; + } + + private FileProcessorSteps GetFileProcessorSteps() + { + this.FileProcessorSteps ??= new FileProcessorSteps(this.TestingContext.DockerHelper.FileProcessorClient); + + return this.FileProcessorSteps; } [Given(@"I have a file named '(.*)' with the following contents")] public void GivenIHaveAFileNamedWithTheFollowingContents(string fileName, DataTable table){ String fileData = table.Rows.ToFileData(); - this.TestingContext.UploadFile = this.FileProcessorSteps.WriteDileToDisk(fileName, fileData); + this.TestingContext.UploadFile = this.GetFileProcessorSteps().WriteDileToDisk(fileName, fileData); } [Given(@"I upload this file for processing")] @@ -65,7 +81,7 @@ public async Task GivenIUploadThisFileForProcessing(DataTable table) Byte[] fileData = await File.ReadAllBytesAsync(filePath); (EstateDetails1, UploadFileRequest) uploadFileRequest = table.Rows.ToUploadFileRequest(this.TestingContext.Estates, fileData); - await this.FileProcessorSteps.GivenIUploadThisFileForProcessing(this.TestingContext.AccessToken, filePath, fileData, uploadFileRequest.Item1, uploadFileRequest.Item2); + await this.GetFileProcessorSteps().GivenIUploadThisFileForProcessing(this.TestingContext.AccessToken, filePath, fileData, uploadFileRequest.Item1, uploadFileRequest.Item2); } [Given(@"I upload this file for processing an error should be returned indicating the file is a duplicate")] @@ -74,12 +90,12 @@ public async Task GivenIUploadThisFileForProcessingAnErrorShouldBeReturnedIndica String filePath = TestingContext.UploadFile; Byte[] fileData = await File.ReadAllBytesAsync(filePath); (EstateDetails1, UploadFileRequest) uploadFileRequest = table.Rows.ToUploadFileRequest(this.TestingContext.Estates, fileData); - await this.FileProcessorSteps.GivenIUploadThisFileForProcessingAnErrorShouldBeReturnedIndicatingTheFileIsADuplicate(this.TestingContext.AccessToken, filePath, fileData, uploadFileRequest.Item2); + await this.GetFileProcessorSteps().GivenIUploadThisFileForProcessingAnErrorShouldBeReturnedIndicatingTheFileIsADuplicate(this.TestingContext.AccessToken, filePath, fileData, uploadFileRequest.Item2); } [When(@"I get the import log for estate '([^']*)' the date on the import log is '([^']*)'")] public async Task WhenIGetTheImportLogForEstateTheDateOnTheImportLogIs(string estateName, string expectedDateString){ - await this.FileProcessorSteps.WhenIGetTheImportLogForEstateTheDateOnTheImportLogIs(this.TestingContext.AccessToken, estateName, expectedDateString, this.TestingContext.Estates); + await this.GetFileProcessorSteps().WhenIGetTheImportLogForEstateTheDateOnTheImportLogIs(this.TestingContext.AccessToken, estateName, expectedDateString, this.TestingContext.Estates); } //[When(@"As merchant ""(.*)"" on Estate ""(.*)"" I get my transactions (.*) transaction should be returned")] @@ -113,7 +129,7 @@ public async Task WhenICreateTheFollowingEstates(DataTable table) { List requests = table.Rows.ToCreateEstateRequests(); - List verifiedEstates = await this.TransactionProcessorSteps.WhenICreateTheFollowingEstatesX(this.TestingContext.AccessToken, requests); + List verifiedEstates = await this.GetTransactionProcessorSteps().WhenICreateTheFollowingEstatesX(this.TestingContext.AccessToken, requests); foreach (EstateResponse verifiedEstate in verifiedEstates) { @@ -137,7 +153,7 @@ public async Task WhenIAssignTheFollowingOperatorToTheMerchants(DataTable table) var estates = this.TestingContext.Estates.Select(e => e.EstateDetails).ToList(); List<(EstateDetails, Guid, TransactionProcessor.DataTransferObjects.Requests.Merchant.AssignOperatorRequest)> requests = table.Rows.ToAssignOperatorRequests(estates); - List<(EstateDetails, TransactionProcessor.DataTransferObjects.Responses.Merchant.MerchantOperatorResponse)> results = await this.TransactionProcessorSteps.WhenIAssignTheFollowingOperatorToTheMerchants(this.TestingContext.AccessToken, requests); + List<(EstateDetails, TransactionProcessor.DataTransferObjects.Responses.Merchant.MerchantOperatorResponse)> results = await this.GetTransactionProcessorSteps().WhenIAssignTheFollowingOperatorToTheMerchants(this.TestingContext.AccessToken, requests); foreach ((EstateDetails, MerchantOperatorResponse) result in results) { @@ -152,7 +168,7 @@ public async Task WhenICreateTheFollowingOperators(DataTable table) var estates = this.TestingContext.Estates.Select(e => e.EstateDetails).ToList(); List<(EstateDetails estate, CreateOperatorRequest request)> requests = table.Rows.ToCreateOperatorRequests(estates); - List<(Guid, EstateOperatorResponse)> results = await this.TransactionProcessorSteps.WhenICreateTheFollowingOperators(this.TestingContext.AccessToken, requests); + List<(Guid, EstateOperatorResponse)> results = await this.GetTransactionProcessorSteps().WhenICreateTheFollowingOperators(this.TestingContext.AccessToken, requests); foreach ((Guid, EstateOperatorResponse) result in results) { @@ -165,7 +181,7 @@ public async Task GivenIHaveAssignedTheFollowingOperatorsToTheEstates(DataTable { List<(EstateDetails estate, AssignOperatorRequest request)> requests = dataTable.Rows.ToAssignOperatorToEstateRequests(this.TestingContext.Estates.Select(s => s.EstateDetails).ToList()); - await this.TransactionProcessorSteps.GivenIHaveAssignedTheFollowingOperatorsToTheEstates(this.TestingContext.AccessToken, requests); + await this.GetTransactionProcessorSteps().GivenIHaveAssignedTheFollowingOperatorsToTheEstates(this.TestingContext.AccessToken, requests); // TODO Verify } @@ -175,9 +191,9 @@ public async Task GivenIHaveAssignedTheFollowingOperatorsToTheEstates(DataTable public async Task WhenICreateTheFollowingMerchants(DataTable table) { var estates = this.TestingContext.Estates.Select(e => e.EstateDetails).ToList(); - List<(EstateDetails estate, CreateMerchantRequest)> requests = table.Rows.ToCreateMerchantRequests(estates); + var requests = table.Rows.ToCreateMerchantRequests(estates); - List verifiedMerchants = await this.TransactionProcessorSteps.WhenICreateTheFollowingMerchants(this.TestingContext.AccessToken, requests); + List verifiedMerchants = await this.GetTransactionProcessorSteps().WhenICreateTheFollowingMerchants(this.TestingContext.AccessToken, requests); foreach (TransactionProcessor.DataTransferObjects.Responses.Merchant.MerchantResponse verifiedMerchant in verifiedMerchants) { @@ -192,7 +208,7 @@ public async Task GivenICreateAContractWithTheFollowingValues(DataTable table) { var estates = this.TestingContext.Estates.Select(e => e.EstateDetails).ToList(); List<(EstateDetails, CreateContractRequest)> requests = table.Rows.ToCreateContractRequests(estates); - List responses = await this.TransactionProcessorSteps.GivenICreateAContractWithTheFollowingValues(this.TestingContext.AccessToken, requests); + List responses = await this.GetTransactionProcessorSteps().GivenICreateAContractWithTheFollowingValues(this.TestingContext.AccessToken, requests); foreach (ContractResponse contractResponse in responses) { EstateDetails1 estate = this.TestingContext.Estates.Single(e => e.EstateDetails.EstateId == contractResponse.EstateId); @@ -206,7 +222,7 @@ public async Task WhenICreateTheFollowingProducts(DataTable table) var estates = this.TestingContext.Estates.Select(e => e.EstateDetails).ToList(); List<(EstateDetails, TransactionProcessor.IntegrationTesting.Helpers.Contract, AddProductToContractRequest)> requests = table.Rows.ToAddProductToContractRequest(estates); - await this.TransactionProcessorSteps.WhenICreateTheFollowingProducts(this.TestingContext.AccessToken, requests); + await this.GetTransactionProcessorSteps().WhenICreateTheFollowingProducts(this.TestingContext.AccessToken, requests); } [When(@"I add the following Transaction Fees")] @@ -214,7 +230,7 @@ public async Task WhenIAddTheFollowingTransactionFees(DataTable table) { var estates = this.TestingContext.Estates.Select(e => e.EstateDetails).ToList(); List<(EstateDetails, TransactionProcessor.IntegrationTesting.Helpers.Contract, TransactionProcessor.IntegrationTesting.Helpers.Product, AddTransactionFeeForProductToContractRequest)> requests = table.Rows.ToAddTransactionFeeForProductToContractRequests(estates); - await this.TransactionProcessorSteps.WhenIAddTheFollowingTransactionFees(this.TestingContext.AccessToken, requests); + await this.GetTransactionProcessorSteps().WhenIAddTheFollowingTransactionFees(this.TestingContext.AccessToken, requests); } [Given(@"the following api resources exist")] @@ -251,7 +267,7 @@ public async Task GivenIHaveAssignedTheFollowingDevicesToTheMerchants(DataTable List estates = this.TestingContext.Estates.Select(e => e.EstateDetails).ToList(); List<(EstateDetails, Guid, AddMerchantDeviceRequest)> requests = table.Rows.ToAddMerchantDeviceRequests(estates); - List<(EstateDetails, TransactionProcessor.DataTransferObjects.Responses.Merchant.MerchantResponse, String)> results = await this.TransactionProcessorSteps.GivenIHaveAssignedTheFollowingDevicesToTheMerchants(this.TestingContext.AccessToken, requests); + List<(EstateDetails, TransactionProcessor.DataTransferObjects.Responses.Merchant.MerchantResponse, String)> results = await this.GetTransactionProcessorSteps().GivenIHaveAssignedTheFollowingDevicesToTheMerchants(this.TestingContext.AccessToken, requests); foreach ((EstateDetails, MerchantResponse, String) result in results) { this.TestingContext.Logger.LogInformation($"Device {result.Item3} assigned to Merchant {result.Item2.MerchantName} Estate {result.Item1.EstateName}"); @@ -263,7 +279,7 @@ public async Task WhenIAddTheFollowingContractsToTheFollowingMerchants(DataTable { List estates = this.TestingContext.Estates.Select(e => e.EstateDetails).ToList(); List<(EstateDetails, Guid, Guid)> requests = table.Rows.ToAddContractToMerchantRequests(estates); - await this.TransactionProcessorSteps.WhenIAddTheFollowingContractsToTheFollowingMerchants(this.TestingContext.AccessToken, requests); + await this.GetTransactionProcessorSteps().WhenIAddTheFollowingContractsToTheFollowingMerchants(this.TestingContext.AccessToken, requests); } private async Task GetMerchantBalance(Guid merchantId) @@ -281,7 +297,7 @@ public async Task GivenIMakeTheFollowingManualMerchantDeposits(DataTable table) foreach ((EstateDetails, Guid, MakeMerchantDepositRequest) request in requests){ Decimal previousMerchantBalance = await this.GetMerchantBalance(request.Item2); - await this.TransactionProcessorSteps.GivenIMakeTheFollowingManualMerchantDeposits(this.TestingContext.AccessToken, request); + await this.GetTransactionProcessorSteps().GivenIMakeTheFollowingManualMerchantDeposits(this.TestingContext.AccessToken, request); await Retry.For(async () => { Decimal currentMerchantBalance = await this.GetMerchantBalance(request.Item2); diff --git a/FileProcessor.Tests/FileProcessor.Tests.csproj b/FileProcessor.Tests/FileProcessor.Tests.csproj index f968bae..6c8e6e7 100644 --- a/FileProcessor.Tests/FileProcessor.Tests.csproj +++ b/FileProcessor.Tests/FileProcessor.Tests.csproj @@ -2,12 +2,16 @@ net10.0 + Exe + true + true None false + @@ -30,4 +34,4 @@ - \ No newline at end of file + diff --git a/global.json b/global.json new file mode 100644 index 0000000..3140116 --- /dev/null +++ b/global.json @@ -0,0 +1,5 @@ +{ + "test": { + "runner": "Microsoft.Testing.Platform" + } +}