From 07032c68d352751c24e77003e84c87dd5b424991 Mon Sep 17 00:00:00 2001 From: Mehdi Hadeli Date: Sun, 1 Sep 2024 17:11:44 +0330 Subject: [PATCH 1/4] fix: some package reference fixes --- .../Shared/Tests.Shared/Factory/CustomWebApplicationFactory.cs | 2 -- tests/Shared/Tests.Shared/Tests.Shared.csproj | 2 -- 2 files changed, 4 deletions(-) diff --git a/tests/Shared/Tests.Shared/Factory/CustomWebApplicationFactory.cs b/tests/Shared/Tests.Shared/Factory/CustomWebApplicationFactory.cs index 396d3319..de651a4f 100644 --- a/tests/Shared/Tests.Shared/Factory/CustomWebApplicationFactory.cs +++ b/tests/Shared/Tests.Shared/Factory/CustomWebApplicationFactory.cs @@ -1,5 +1,3 @@ -using System.Reflection; -using BuildingBlocks.Core.Persistence.Extensions; using BuildingBlocks.Core.Web.Extensions; using BuildingBlocks.Security.Jwt; using Microsoft.AspNetCore.Authentication; diff --git a/tests/Shared/Tests.Shared/Tests.Shared.csproj b/tests/Shared/Tests.Shared/Tests.Shared.csproj index 396a2bd8..b5eb8873 100644 --- a/tests/Shared/Tests.Shared/Tests.Shared.csproj +++ b/tests/Shared/Tests.Shared/Tests.Shared.csproj @@ -14,9 +14,7 @@ - - From 4773337f3f33b796f5f0eee72f12d73677ac27c8 Mon Sep 17 00:00:00 2001 From: Mehdi Hadeli Date: Wed, 4 Sep 2024 00:49:13 +0330 Subject: [PATCH 2/4] ci: refactoring ci --- .github/workflows/back-merge.yml | 354 +++++++++++++++---------------- 1 file changed, 176 insertions(+), 178 deletions(-) diff --git a/.github/workflows/back-merge.yml b/.github/workflows/back-merge.yml index 7785e724..fd4f82fe 100644 --- a/.github/workflows/back-merge.yml +++ b/.github/workflows/back-merge.yml @@ -1,178 +1,176 @@ -# Back-merging should typically be done as part of your Continuous Integration (CI) process -# By performing back-merging as part of the CI process, we can catch and fix any conflicts between the dev and main branches early in the development cycle, before the changes are deployed to production. This helps to ensure that the dev branch remains in a releasable state, and reduces the risk of integration issues when changes are eventually merged into the main branch. -name: Back-Merge - -on: - - # https://docs.github.com/en/actions/using-workflows/events-that-trigger-workflows#workflow_run - # https://stackoverflow.com/questions/63343937/how-to-use-the-github-actions-workflow-run-event - # https://blog.pother.ca/github-actions-workflow_run-event/ - # This event will only trigger a workflow run if the workflow file is on the default branch. - # According documentation 'GITHUB_REF' for workflow_run always is default branch(develop), and for access original branch for workflow_run we can use 'github.event.workflow_run.head_branch' - workflow_run: - workflows: [ "Catalogs-CI-CD", "Customers-CI-CD", "Identity-CI-CD", "Orders-CI-CD" ] - branches: [ develop, main, preview, beta ] - types: [ completed ] - - - pull_request: - types: [closed] # when PR is merged, CD will be triggered - branches: - - develop - - beta - - preview - - main - - workflow_dispatch: - logLevel: - description: 'Log level' - required: true - default: 'info' - type: choice - options: - - info - - warning - - debug - -jobs: - - pre-check: - runs-on: ubuntu-latest - - # Skipping workflow runs for some commits types - # https://itnext.io/automate-your-integration-tests-and-semantic-releases-with-github-actions-43875ad83092 - # https://github.com/actions/runner/issues/491#issuecomment-850884422 - # https://stackoverflow.com/questions/69354003/github-action-job-fire-when-previous-job-skipped - # we should not filter on head commit message types like 'chore', 'docs' because it is possible it our latest SHA commit in integration branches like develop and main be these types and it will skips whole of our trigger - if: | - github.actor != 'dependabot[bot]' - - steps: - - name: Job Info - run: | - echo "pre-check is successful." - echo workspace is: ${{ github.workspace }} - echo "is workflow_dispatch event? ${{ github.event_name == 'workflow_dispatch' }}" - echo "is push event? ${{ github.event_name == 'push' }}" - echo "is pull request event? ${{ github.event_name == 'pull_request' }}" - echo "pull_request.head.ref is: ${{ github.event.pull_request.head.ref }}" - echo "github.ref_name is: ${{ github.ref_name }}" - echo "github.ref is: ${{ github.ref }}" - echo "github.head_ref is: ${{ github.head_ref }}" - echo "should publish in dispatch mode? ${{ github.event.inputs.should-publish }}" - - back-merge: - runs-on: ubuntu-latest - needs: [ pre-check ] - - if: | - success() && - github.event_name != 'pull_request' && - ((github.event_name == 'workflow_run' && github.event.workflow_run.conclusion == 'success' && contains(fromJson('["develop", "main", "preview", "beta"]'), github.event.workflow_run.head_branch)) || (github.event_name == 'workflow_dispatch' && contains(fromJson('["develop", "main", "preview", "beta"]'), github.ref_name))) - - permissions: - pull-requests: write - - steps: - - name: Set branch name as env variable - shell: bash - run: | - if [ ${{ github.event_name }} = 'workflow_run' ]; then - echo "BRANCH=${{ github.event.workflow_run.head_branch }}" >> $GITHUB_ENV - else - echo "BRANCH=${{ github.ref_name }}" >> $GITHUB_ENV - fi - - # https://github.com/cycjimmy/semantic-release-action/issues/6 - # https://github.com/actions/checkout#push-a-commit-using-the-built-in-token - # https://stackoverflow.com/questions/750172/how-do-i-change-the-author-and-committer-name-email-for-multiple-commits - # https://github.com/semantic-release/semantic-release/issues/1208 - # https://github.com/orgs/community/discussions/26560 - # https://blog.pother.ca/github-actions-workflow_run-event/ - # https://stackoverflow.com/questions/63343937/how-to-use-the-github-actions-workflow-run-event - # https://docs.github.com/en/actions/using-workflows/events-that-trigger-workflows#workflow_run - # https://github.com/semantic-release/semantic-release/blob/b9b5c7689f0acdfdc079c839db0fcf78339745e2/index.js#L92 - ## https://github.com/actions/checkout/issues/439#issuecomment-965968956 - # get latest remote change because sematic-release in `verifyConditions` event checks local branch has latest remote branch changes, for preventing: The local branch `something` is behind the remote one, therefore a new version won't be published. - # By default checkout@v3, will check branch on ref/SHA that triggered in starting workflow, so if inner a job in the workflow we change HEAD of repository by changing code, subsequent jobs don't get these commits and they get ref/SHA that triggered in starting workflow - # we can't create a `composite-action` for `checkout` because for finding composite-action locally with relative path, repository should be `checkout` first - - name: Check out code - uses: actions/checkout@v3 - with: - # https://github.com/actions/checkout#fetch-all-history-for-all-tags-and-branches - # Only a single commit is fetched by default, for the ref/SHA that triggered the workflow. Set fetch-depth: 0 to fetch all history for all branches and tags - fetch-depth: 0 - repository: ${{ github.repository }} - token: ${{ secrets.GITHUB_TOKEN }} - # set ref to 'github.ref' works correctly with both pull_requests event and push event and this is default behavior checkout action when we don't use ref attribute - ref: ${{ github.ref }} - - run: | - git config user.name 'github-actions[bot]' - git config user.email 'github-actions[bot]@users.noreply.github.com' - shell: bash - - - name: Call Composite Action back-merge - uses: ./.github/actions/back-merge - id: back-merge-step - with: - source-branch: ${{ env.BRANCH }} - - back-merge-pr-closed: - runs-on: ubuntu-latest - needs: [ pre-check ] - - permissions: - contents: write # for back-merging feature branch - - if: | - success() && - (github.event_name == 'pull_request' && github.event.pull_request.merged == true && contains(fromJson('["develop", "preview", "beta"]'), github.ref_name)) - - steps: - - - name: Set branch name as env variable - shell: bash - run: | - if [ ${{ github.event_name }} = 'workflow_run' ]; then - echo "BRANCH=${{ github.event.workflow_run.head_branch }}" >> $GITHUB_ENV - else - echo "BRANCH=${{ github.ref_name }}" >> $GITHUB_ENV - fi - - # https://github.com/cycjimmy/semantic-release-action/issues/6 - # https://github.com/actions/checkout#push-a-commit-using-the-built-in-token - # https://stackoverflow.com/questions/750172/how-do-i-change-the-author-and-committer-name-email-for-multiple-commits - # https://github.com/semantic-release/semantic-release/issues/1208 - # https://github.com/orgs/community/discussions/26560 - # https://blog.pother.ca/github-actions-workflow_run-event/ - # https://stackoverflow.com/questions/63343937/how-to-use-the-github-actions-workflow-run-event - # https://docs.github.com/en/actions/using-workflows/events-that-trigger-workflows#workflow_run - # https://github.com/semantic-release/semantic-release/blob/b9b5c7689f0acdfdc079c839db0fcf78339745e2/index.js#L92 - ## https://github.com/actions/checkout/issues/439#issuecomment-965968956 - # get latest remote change because sematic-release in `verifyConditions` event checks local branch has latest remote branch changes, for preventing: The local branch `something` is behind the remote one, therefore a new version won't be published. - # By default checkout@v3, will check branch on ref/SHA that triggered in starting workflow, so if inner a job in the workflow we change HEAD of repository by changing code, subsequent jobs don't get these commits and they get ref/SHA that triggered in starting workflow - # we can't create a `composite-action` for `checkout` because for finding composite-action locally with relative path, repository should be `checkout` first - - name: Check out code - uses: actions/checkout@v3 - with: - # https://github.com/actions/checkout#fetch-all-history-for-all-tags-and-branches - # Only a single commit is fetched by default, for the ref/SHA that triggered the workflow. Set fetch-depth: 0 to fetch all history for all branches and tags - fetch-depth: 0 - repository: ${{ github.repository }} - token: ${{ secrets.GITHUB_TOKEN }} - # set ref to 'github.ref' works correctly with both pull_requests event and push event and this is default behavior checkout action when we don't use ref attribute - ref: ${{ github.ref }} - - run: | - git config user.name 'github-actions[bot]' - git config user.email 'github-actions[bot]@users.noreply.github.com' - shell: bash - - # https://stackoverflow.com/questions/69839851/github-actions-copy-git-user-name-and-user-email-from-last-commit - # https://github.com/orgs/community/discussions/26560 - # https://github.com/semantic-release/semantic-release/discussions/2557 - # https://github.com/semantic-release/github/issues/175 - # this needs a PAT with write permission without doing pull request - - name: Back Merge Feature Branches - shell: bash - run: | - ./back-merge.sh ${{ github.ref_name }} +## Back-merging should typically be done as part of your Continuous Integration (CI) process +## By performing back-merging as part of the CI process, we can catch and fix any conflicts between the dev and main branches early in the development cycle, before the changes are deployed to production. This helps to ensure that the dev branch remains in a releasable state, and reduces the risk of integration issues when changes are eventually merged into the main branch. +# name: Back-Merge +# +#on: +# # https://docs.github.com/en/actions/using-workflows/events-that-trigger-workflows#workflow_run +# # https://stackoverflow.com/questions/63343937/how-to-use-the-github-actions-workflow-run-event +# # https://blog.pother.ca/github-actions-workflow_run-event/ +# # This event will only trigger a workflow run if the workflow file is on the default branch. +# # According documentation 'GITHUB_REF' for workflow_run always is default branch(develop), and for access original branch for workflow_run we can use 'github.event.workflow_run.head_branch' +# workflow_run: +# workflows: +# ["Catalogs-CI-CD", "Customers-CI-CD", "Identity-CI-CD", "Orders-CI-CD"] +# branches: [develop, main, preview, beta] +# types: [completed] +# +# pull_request: +# types: [closed] # when PR is merged, CD will be triggered +# branches: +# - develop +# - beta +# - preview +# - main +# +# workflow_dispatch: +# inputs: +# logLevel: +# description: "Log level" +# required: true +# default: "info" +# type: choice +# options: +# - info +# - warning +# - debug +# +#jobs: +# pre-check: +# runs-on: ubuntu-latest +# +# # Skipping workflow runs for some commits types +# # https://itnext.io/automate-your-integration-tests-and-semantic-releases-with-github-actions-43875ad83092 +# # https://github.com/actions/runner/issues/491#issuecomment-850884422 +# # https://stackoverflow.com/questions/69354003/github-action-job-fire-when-previous-job-skipped +# # we should not filter on head commit message types like 'chore', 'docs' because it is possible it our latest SHA commit in integration branches like develop and main be these types and it will skips whole of our trigger +# if: | +# github.actor != 'dependabot[bot]' +# +# steps: +# - name: Job Info +# run: | +# echo "pre-check is successful." +# echo workspace is: ${{ github.workspace }} +# echo "is workflow_dispatch event? ${{ github.event_name == 'workflow_dispatch' }}" +# echo "is push event? ${{ github.event_name == 'push' }}" +# echo "is pull request event? ${{ github.event_name == 'pull_request' }}" +# echo "pull_request.head.ref is: ${{ github.event.pull_request.head.ref }}" +# echo "github.ref_name is: ${{ github.ref_name }}" +# echo "github.ref is: ${{ github.ref }}" +# echo "github.head_ref is: ${{ github.head_ref }}" +# echo "should publish in dispatch mode? ${{ github.event.inputs.should-publish }}" +# +# back-merge: +# runs-on: ubuntu-latest +# needs: [pre-check] +# +# if: | +# success() && +# github.event_name != 'pull_request' && +# ((github.event_name == 'workflow_run' && github.event.workflow_run.conclusion == 'success' && contains(fromJson('["develop", "main", "preview", "beta"]'), github.event.workflow_run.head_branch)) || (github.event_name == 'workflow_dispatch' && contains(fromJson('["develop", "main", "preview", "beta"]'), github.ref_name))) +# +# permissions: +# pull-requests: write +# +# steps: +# - name: Set branch name as env variable +# shell: bash +# run: | +# if [ ${{ github.event_name }} = 'workflow_run' ]; then +# echo "BRANCH=${{ github.event.workflow_run.head_branch }}" >> $GITHUB_ENV +# else +# echo "BRANCH=${{ github.ref_name }}" >> $GITHUB_ENV +# fi +# +# # https://github.com/cycjimmy/semantic-release-action/issues/6 +# # https://github.com/actions/checkout#push-a-commit-using-the-built-in-token +# # https://stackoverflow.com/questions/750172/how-do-i-change-the-author-and-committer-name-email-for-multiple-commits +# # https://github.com/semantic-release/semantic-release/issues/1208 +# # https://github.com/orgs/community/discussions/26560 +# # https://blog.pother.ca/github-actions-workflow_run-event/ +# # https://stackoverflow.com/questions/63343937/how-to-use-the-github-actions-workflow-run-event +# # https://docs.github.com/en/actions/using-workflows/events-that-trigger-workflows#workflow_run +# # https://github.com/semantic-release/semantic-release/blob/b9b5c7689f0acdfdc079c839db0fcf78339745e2/index.js#L92 +# ## https://github.com/actions/checkout/issues/439#issuecomment-965968956 +# # get latest remote change because sematic-release in `verifyConditions` event checks local branch has latest remote branch changes, for preventing: The local branch `something` is behind the remote one, therefore a new version won't be published. +# # By default checkout@v3, will check branch on ref/SHA that triggered in starting workflow, so if inner a job in the workflow we change HEAD of repository by changing code, subsequent jobs don't get these commits and they get ref/SHA that triggered in starting workflow +# # we can't create a `composite-action` for `checkout` because for finding composite-action locally with relative path, repository should be `checkout` first +# - name: Check out code +# uses: actions/checkout@v3 +# with: +# # https://github.com/actions/checkout#fetch-all-history-for-all-tags-and-branches +# # Only a single commit is fetched by default, for the ref/SHA that triggered the workflow. Set fetch-depth: 0 to fetch all history for all branches and tags +# fetch-depth: 0 +# repository: ${{ github.repository }} +# token: ${{ secrets.GITHUB_TOKEN }} +# # set ref to 'github.ref' works correctly with both pull_requests event and push event and this is default behavior checkout action when we don't use ref attribute +# ref: ${{ github.ref }} +# - run: | +# git config user.name 'github-actions[bot]' +# git config user.email 'github-actions[bot]@users.noreply.github.com' +# shell: bash +# +# - name: Call Composite Action back-merge +# uses: ./.github/actions/back-merge +# id: back-merge-step +# with: +# source-branch: ${{ env.BRANCH }} +# +# back-merge-pr-closed: +# runs-on: ubuntu-latest +# needs: [pre-check] +# +# permissions: +# contents: write # for back-merging feature branch +# +# if: | +# success() && +# (github.event_name == 'pull_request' && github.event.pull_request.merged == true && contains(fromJson('["develop", "preview", "beta"]'), github.ref_name)) +# +# steps: +# - name: Set branch name as env variable +# shell: bash +# run: | +# if [ ${{ github.event_name }} = 'workflow_run' ]; then +# echo "BRANCH=${{ github.event.workflow_run.head_branch }}" >> $GITHUB_ENV +# else +# echo "BRANCH=${{ github.ref_name }}" >> $GITHUB_ENV +# fi +# +# # https://github.com/cycjimmy/semantic-release-action/issues/6 +# # https://github.com/actions/checkout#push-a-commit-using-the-built-in-token +# # https://stackoverflow.com/questions/750172/how-do-i-change-the-author-and-committer-name-email-for-multiple-commits +# # https://github.com/semantic-release/semantic-release/issues/1208 +# # https://github.com/orgs/community/discussions/26560 +# # https://blog.pother.ca/github-actions-workflow_run-event/ +# # https://stackoverflow.com/questions/63343937/how-to-use-the-github-actions-workflow-run-event +# # https://docs.github.com/en/actions/using-workflows/events-that-trigger-workflows#workflow_run +# # https://github.com/semantic-release/semantic-release/blob/b9b5c7689f0acdfdc079c839db0fcf78339745e2/index.js#L92 +# ## https://github.com/actions/checkout/issues/439#issuecomment-965968956 +# # get latest remote change because sematic-release in `verifyConditions` event checks local branch has latest remote branch changes, for preventing: The local branch `something` is behind the remote one, therefore a new version won't be published. +# # By default checkout@v3, will check branch on ref/SHA that triggered in starting workflow, so if inner a job in the workflow we change HEAD of repository by changing code, subsequent jobs don't get these commits and they get ref/SHA that triggered in starting workflow +# # we can't create a `composite-action` for `checkout` because for finding composite-action locally with relative path, repository should be `checkout` first +# - name: Check out code +# uses: actions/checkout@v3 +# with: +# # https://github.com/actions/checkout#fetch-all-history-for-all-tags-and-branches +# # Only a single commit is fetched by default, for the ref/SHA that triggered the workflow. Set fetch-depth: 0 to fetch all history for all branches and tags +# fetch-depth: 0 +# repository: ${{ github.repository }} +# token: ${{ secrets.GITHUB_TOKEN }} +# # set ref to 'github.ref' works correctly with both pull_requests event and push event and this is default behavior checkout action when we don't use ref attribute +# ref: ${{ github.ref }} +# - run: | +# git config user.name 'github-actions[bot]' +# git config user.email 'github-actions[bot]@users.noreply.github.com' +# shell: bash +# +# # https://stackoverflow.com/questions/69839851/github-actions-copy-git-user-name-and-user-email-from-last-commit +# # https://github.com/orgs/community/discussions/26560 +# # https://github.com/semantic-release/semantic-release/discussions/2557 +# # https://github.com/semantic-release/github/issues/175 +# # this needs a PAT with write permission without doing pull request +# - name: Back Merge Feature Branches +# shell: bash +# run: | +# ./back-merge.sh ${{ github.ref_name }} From a13b01f76d144f8c070a3a37da47376f6eb81806 Mon Sep 17 00:00:00 2001 From: Mehdi Hadeli Date: Sun, 8 Sep 2024 20:24:07 +0330 Subject: [PATCH 3/4] test: :white_check_mark: add some test fixes --- .github/workflows/app-version.yml | 314 +++++++++--------- food-delivery-microservices.sln | 7 + .../ServiceCollection/Dependency.cs | 34 +- .../Extensions/ValidationExtensions.cs | 32 +- .../Types/MachineInstanceInfo.cs | 2 +- .../BuildingBlocks.Core/Web/Environments.cs | 11 + .../Extensions/HostEnvironmentExtensions.cs | 6 +- .../Program.cs | 8 +- .../CreatingProduct/v1/CreateProduct.cs | 4 +- .../v1/Events/Domain/ProductCreated.cs | 4 +- .../Products/Models/Product.cs | 6 +- .../CustomersApiMetadata.cs | 2 +- .../Program.cs | 8 +- .../Customers/CustomersModuleMapping.cs | 31 +- .../CreatingCustomer/v1/CreateCustomer.cs | 3 + .../v1/Read/Mongo/UpdateCustomerRead.cs | 6 +- .../Customers/ValueObjects/CustomerName.cs | 11 +- .../v1/CreateRestockSubscription.cs | 6 + .../Domain/RestockSubscriptionCreated.cs | 2 +- .../v1/GetRestockSubscriptionById.cs | 2 +- .../Program.cs | 8 +- .../PhoneNumberNotConfirmedException.cs | 7 +- .../v1/GenerateRefreshToken.cs | 2 +- .../v1/GetRefreshTokenValidity.cs | 2 +- .../GettingUserById/v1/GetUserById.cs | 2 +- .../v1/Events/Integration/UserStateUpdated.cs | 2 +- .../Program.cs | 8 +- .../v1/Integration/CustomerUpdatedV1.cs | 2 +- .../Events/v1/Integration/UserRegisteredV1.cs | 2 +- .../DependencyTests.cs | 3 +- .../xunit.runner.json | 8 + .../UnitTest1.cs | 60 ---- .../DependencyTests.cs | 3 +- .../xunit.runner.json | 8 + .../Commands/FakeUpdateCustomerRead.cs | 16 +- .../v1/CreateCustomerTests.cs | 4 +- .../v1/Read/UpdateCustomerTests.cs | 8 +- .../v1/UpdateCustomerTests.cs | 3 +- .../Customers/Models/CustomerTests.cs | 6 +- .../Customers/ValueObjects/CustomerIdTests.cs | 3 +- .../ValueObjects/CustomerNameTests.cs | 28 +- .../v1/CreateRestockSubscriptionTests.cs | 5 +- .../DependencyTests.cs | 32 ++ ...y.Services.Identity.DependencyTests.csproj | 22 ++ .../xunit.runner.json | 8 + .../RegisteringUser/v1/RegisterUserTests.cs | 2 +- .../Factory/CustomWebApplicationFactory.cs | 3 +- .../Factory/WebApplicationFactoryWithHost.cs | 80 ++--- 48 files changed, 465 insertions(+), 371 deletions(-) create mode 100644 src/BuildingBlocks/BuildingBlocks.Core/Web/Environments.cs create mode 100644 tests/Services/Catalogs/FoodDelivery.Services.Catalogs.DependencyTests/xunit.runner.json delete mode 100644 tests/Services/Catalogs/FoodDelivery.Services.Catalogs.IntegrationTests/UnitTest1.cs create mode 100644 tests/Services/Customers/FoodDelivery.Services.Customers.DependencyTests/xunit.runner.json create mode 100644 tests/Services/Identity/FoodDelivery.Services.Identity.DependencyTests/DependencyTests.cs create mode 100644 tests/Services/Identity/FoodDelivery.Services.Identity.DependencyTests/FoodDelivery.Services.Identity.DependencyTests.csproj create mode 100644 tests/Services/Identity/FoodDelivery.Services.Identity.DependencyTests/xunit.runner.json diff --git a/.github/workflows/app-version.yml b/.github/workflows/app-version.yml index 4a76061e..df360e95 100644 --- a/.github/workflows/app-version.yml +++ b/.github/workflows/app-version.yml @@ -1,157 +1,157 @@ -name: Update App Version - -on: - # https://docs.github.com/en/actions/using-workflows/events-that-trigger-workflows#schedule - # https://github.com/peter-evans/create-pull-request/issues/1608 - schedule: - - cron: '0 0 * * *' # run at midnight every day - - workflow_dispatch: - inputs: - logLevel: - description: 'Log level' - required: true - default: 'info' - type: choice - options: - - info - - warning - - debug - -jobs: - update-main-version: - runs-on: ubuntu-latest - - permissions: - pull-requests: write # app-version pull request - contents: write - - steps: - - name: Check out code - uses: actions/checkout@v3 - with: - # https://github.com/actions/checkout#fetch-all-history-for-all-tags-and-branches - # Only a single commit is fetched by default, for the ref/SHA that triggered the workflow. Set fetch-depth: 0 to fetch all history for all branches and tags - fetch-depth: 0 - ref: 'main' - - run: | - git config user.name 'github-actions[bot]' - git config user.email 'github-actions[bot]@users.noreply.github.com' - - - name: Application Version - id: app-version-step - shell: bash - if: success() - # https://gist.github.com/rponte/fdc0724dd984088606b0 - # https://linuxhint.com/bash_if_else_examples/ - # https://github.com/semantic-release/semantic-release/issues/2703 - # https://docs.github.com/en/actions/using-workflows/workflow-commands-for-github-actions#setting-an-environment-variable - # https://docs.github.com/en/actions/using-workflows/workflow-commands-for-github-actions#setting-an-output-parameter - # environment variable available to any 'subsequent steps' (not in the current step that is set) in a workflow job by defining or updating the environment variable and writing this to the GITHUB_ENV environment file - run: | - LATEST_TAG=$(git describe --abbrev=0 --tags --exclude "*dev*" --exclude "*beta*" --exclude "*preview*" --exclude "*ops*" | sed 's/^v//') - echo "latest tag for main branch is: $LATEST_TAG" - echo "APP_VERSION=$LATEST_TAG" >> "$GITHUB_ENV" - echo "app-version=$LATEST_TAG" >> "$GITHUB_OUTPUT" - ./update-version.sh "$LATEST_TAG" - - # https://github.com/peter-evans/create-pull-request/blob/main/docs/concepts-guidelines.md - # https://github.com/peter-evans/create-pull-request/blob/main/docs/examples.md - # https://github.com/peter-evans/create-pull-request/issues/1608 - - name: Create Update Version Pull Request - uses: peter-evans/create-pull-request@v4 - if: success() - with: - author: "github-actions[bot] " - commit-message: "chore: ⬆️ upgrading application version to: ${{ steps.app-version-step.outputs.app-version }} [skip ci]" - title: "chore: ⬆️ upgrading application version to: ${{ steps.app-version-step.outputs.app-version }} [skip ci]" - token: ${{ secrets.GITHUB_TOKEN }} - delete-branch: true - # https://github.com/peter-evans/create-pull-request#alternative-strategy---always-create-a-new-pull-request-branch - # branch-suffix: timestamp - assignees: mehdihadeli - reviewers: mehdihadeli - branch: upgrade-app-version-${{ env.APP_VERSION }} - labels: | - chore - # https://git-scm.com/docs/gitglossary#Documentation/gitglossary.txt-aiddefpathspecapathspec - add-paths: | - *.Packages.props - - update-develop-version: - runs-on: ubuntu-latest - - permissions: - pull-requests: write # app-version pull request - contents: write - - steps: - - name: Check out code - uses: actions/checkout@v3 - with: - # https://github.com/actions/checkout#fetch-all-history-for-all-tags-and-branches - # Only a single commit is fetched by default, for the ref/SHA that triggered the workflow. Set fetch-depth: 0 to fetch all history for all branches and tags - fetch-depth: 0 - ref: 'develop' - - run: | - git config user.name 'github-actions[bot]' - git config user.email 'github-actions[bot]@users.noreply.github.com' - - - name: Application Version - id: app-version-step - shell: bash - if: success() - # https://gist.github.com/rponte/fdc0724dd984088606b0 - # https://linuxhint.com/bash_if_else_examples/ - # https://github.com/semantic-release/semantic-release/issues/2703 - # https://docs.github.com/en/actions/using-workflows/workflow-commands-for-github-actions#setting-an-environment-variable - # https://docs.github.com/en/actions/using-workflows/workflow-commands-for-github-actions#setting-an-output-parameter - # environment variable available to any 'subsequent steps' (not in the current step that is set) in a workflow job by defining or updating the environment variable and writing this to the GITHUB_ENV environment file - run: | - LATEST_TAG=$(git describe --abbrev=0 --tags --match "*dev*" | sed 's/^v//') - echo "latest tag for develop branch is: $LATEST_TAG" - echo "APP_VERSION=$LATEST_TAG" >> "$GITHUB_ENV" - echo "app-version=$LATEST_TAG" >> "$GITHUB_OUTPUT" - ./update-version.sh "$LATEST_TAG" - - # https://github.com/peter-evans/create-pull-request/blob/main/docs/concepts-guidelines.md - # https://github.com/peter-evans/create-pull-request/blob/main/docs/examples.md - # https://github.com/peter-evans/create-pull-request/issues/1608 - - name: Create Update Version Pull Request - uses: peter-evans/create-pull-request@v4 - if: success() - with: - author: "github-actions[bot] " - commit-message: "chore: ⬆️ upgrading application version to: ${{ steps.app-version-step.outputs.app-version }} [skip ci]" - title: "chore: ⬆️ upgrading application version to: ${{ steps.app-version-step.outputs.app-version }} [skip ci]" - token: ${{ secrets.GITHUB_TOKEN }} - delete-branch: true - # https://github.com/peter-evans/create-pull-request#alternative-strategy---always-create-a-new-pull-request-branch - # branch-suffix: timestamp - assignees: mehdihadeli - reviewers: mehdihadeli - branch: upgrade-app-version-${{ env.APP_VERSION }} - labels: | - chore - # https://git-scm.com/docs/gitglossary#Documentation/gitglossary.txt-aiddefpathspecapathspec - add-paths: | - *.Packages.props - -# # we could create a temporary personal token for push app version in a commit directly with this plugin: https://github.com/peter-murray/workflow-application-token-action - -# # https://github.com/semantic-release/semantic-release/discussions/2557 -# # https://github.com/semantic-release/github/issues/175 -# # this needs a PAT with write permission without doing pull request -# - name: Commit Updated Application Version File -# uses: stefanzweifel/git-auto-commit-action@v4 -# if: ${{ success() }} -# with: -# commit_message: 'chore(release): ⬆️ upgrading application version to: ${{ steps.semantic-version.outputs.semantic_nextRelease_version }} [skip ci]' -# file_pattern: '**/Directory.Packages.props' -# disable_globbing: true -# # https://github.com/stefanzweifel/git-auto-commit-action#usage -# commit_author: github-actions[bot] # defaults to author of the commit that triggered the run -# commit_user_name: github-actions[bot] # defaults to "github-actions[bot]" -# commit_user_email: github-actions[bot]@users.noreply.github.com # defaults to "41898282+github-actions[bot]@users.noreply.github.com" - - +#name: Update App Version +# +#on: +# # https://docs.github.com/en/actions/using-workflows/events-that-trigger-workflows#schedule +# # https://github.com/peter-evans/create-pull-request/issues/1608 +# schedule: +# - cron: '0 0 * * *' # run at midnight every day +# +# workflow_dispatch: +# inputs: +# logLevel: +# description: 'Log level' +# required: true +# default: 'info' +# type: choice +# options: +# - info +# - warning +# - debug +# +#jobs: +# update-main-version: +# runs-on: ubuntu-latest +# +# permissions: +# pull-requests: write # app-version pull request +# contents: write +# +# steps: +# - name: Check out code +# uses: actions/checkout@v3 +# with: +# # https://github.com/actions/checkout#fetch-all-history-for-all-tags-and-branches +# # Only a single commit is fetched by default, for the ref/SHA that triggered the workflow. Set fetch-depth: 0 to fetch all history for all branches and tags +# fetch-depth: 0 +# ref: 'main' +# - run: | +# git config user.name 'github-actions[bot]' +# git config user.email 'github-actions[bot]@users.noreply.github.com' +# +# - name: Application Version +# id: app-version-step +# shell: bash +# if: success() +# # https://gist.github.com/rponte/fdc0724dd984088606b0 +# # https://linuxhint.com/bash_if_else_examples/ +# # https://github.com/semantic-release/semantic-release/issues/2703 +# # https://docs.github.com/en/actions/using-workflows/workflow-commands-for-github-actions#setting-an-environment-variable +# # https://docs.github.com/en/actions/using-workflows/workflow-commands-for-github-actions#setting-an-output-parameter +# # environment variable available to any 'subsequent steps' (not in the current step that is set) in a workflow job by defining or updating the environment variable and writing this to the GITHUB_ENV environment file +# run: | +# LATEST_TAG=$(git describe --abbrev=0 --tags --exclude "*dev*" --exclude "*beta*" --exclude "*preview*" --exclude "*ops*" | sed 's/^v//') +# echo "latest tag for main branch is: $LATEST_TAG" +# echo "APP_VERSION=$LATEST_TAG" >> "$GITHUB_ENV" +# echo "app-version=$LATEST_TAG" >> "$GITHUB_OUTPUT" +# ./update-version.sh "$LATEST_TAG" +# +# # https://github.com/peter-evans/create-pull-request/blob/main/docs/concepts-guidelines.md +# # https://github.com/peter-evans/create-pull-request/blob/main/docs/examples.md +# # https://github.com/peter-evans/create-pull-request/issues/1608 +# - name: Create Update Version Pull Request +# uses: peter-evans/create-pull-request@v4 +# if: success() +# with: +# author: "github-actions[bot] " +# commit-message: "chore: ⬆️ upgrading application version to: ${{ steps.app-version-step.outputs.app-version }} [skip ci]" +# title: "chore: ⬆️ upgrading application version to: ${{ steps.app-version-step.outputs.app-version }} [skip ci]" +# token: ${{ secrets.GITHUB_TOKEN }} +# delete-branch: true +# # https://github.com/peter-evans/create-pull-request#alternative-strategy---always-create-a-new-pull-request-branch +# # branch-suffix: timestamp +# assignees: mehdihadeli +# reviewers: mehdihadeli +# branch: upgrade-app-version-${{ env.APP_VERSION }} +# labels: | +# chore +# # https://git-scm.com/docs/gitglossary#Documentation/gitglossary.txt-aiddefpathspecapathspec +# add-paths: | +# *.Packages.props +# +# update-develop-version: +# runs-on: ubuntu-latest +# +# permissions: +# pull-requests: write # app-version pull request +# contents: write +# +# steps: +# - name: Check out code +# uses: actions/checkout@v3 +# with: +# # https://github.com/actions/checkout#fetch-all-history-for-all-tags-and-branches +# # Only a single commit is fetched by default, for the ref/SHA that triggered the workflow. Set fetch-depth: 0 to fetch all history for all branches and tags +# fetch-depth: 0 +# ref: 'develop' +# - run: | +# git config user.name 'github-actions[bot]' +# git config user.email 'github-actions[bot]@users.noreply.github.com' +# +# - name: Application Version +# id: app-version-step +# shell: bash +# if: success() +# # https://gist.github.com/rponte/fdc0724dd984088606b0 +# # https://linuxhint.com/bash_if_else_examples/ +# # https://github.com/semantic-release/semantic-release/issues/2703 +# # https://docs.github.com/en/actions/using-workflows/workflow-commands-for-github-actions#setting-an-environment-variable +# # https://docs.github.com/en/actions/using-workflows/workflow-commands-for-github-actions#setting-an-output-parameter +# # environment variable available to any 'subsequent steps' (not in the current step that is set) in a workflow job by defining or updating the environment variable and writing this to the GITHUB_ENV environment file +# run: | +# LATEST_TAG=$(git describe --abbrev=0 --tags --match "*dev*" | sed 's/^v//') +# echo "latest tag for develop branch is: $LATEST_TAG" +# echo "APP_VERSION=$LATEST_TAG" >> "$GITHUB_ENV" +# echo "app-version=$LATEST_TAG" >> "$GITHUB_OUTPUT" +# ./update-version.sh "$LATEST_TAG" +# +# # https://github.com/peter-evans/create-pull-request/blob/main/docs/concepts-guidelines.md +# # https://github.com/peter-evans/create-pull-request/blob/main/docs/examples.md +# # https://github.com/peter-evans/create-pull-request/issues/1608 +# - name: Create Update Version Pull Request +# uses: peter-evans/create-pull-request@v4 +# if: success() +# with: +# author: "github-actions[bot] " +# commit-message: "chore: ⬆️ upgrading application version to: ${{ steps.app-version-step.outputs.app-version }} [skip ci]" +# title: "chore: ⬆️ upgrading application version to: ${{ steps.app-version-step.outputs.app-version }} [skip ci]" +# token: ${{ secrets.GITHUB_TOKEN }} +# delete-branch: true +# # https://github.com/peter-evans/create-pull-request#alternative-strategy---always-create-a-new-pull-request-branch +# # branch-suffix: timestamp +# assignees: mehdihadeli +# reviewers: mehdihadeli +# branch: upgrade-app-version-${{ env.APP_VERSION }} +# labels: | +# chore +# # https://git-scm.com/docs/gitglossary#Documentation/gitglossary.txt-aiddefpathspecapathspec +# add-paths: | +# *.Packages.props +# +## # we could create a temporary personal token for push app version in a commit directly with this plugin: https://github.com/peter-murray/workflow-application-token-action +# +## # https://github.com/semantic-release/semantic-release/discussions/2557 +## # https://github.com/semantic-release/github/issues/175 +## # this needs a PAT with write permission without doing pull request +## - name: Commit Updated Application Version File +## uses: stefanzweifel/git-auto-commit-action@v4 +## if: ${{ success() }} +## with: +## commit_message: 'chore(release): ⬆️ upgrading application version to: ${{ steps.semantic-version.outputs.semantic_nextRelease_version }} [skip ci]' +## file_pattern: '**/Directory.Packages.props' +## disable_globbing: true +## # https://github.com/stefanzweifel/git-auto-commit-action#usage +## commit_author: github-actions[bot] # defaults to author of the commit that triggered the run +## commit_user_name: github-actions[bot] # defaults to "github-actions[bot]" +## commit_user_email: github-actions[bot]@users.noreply.github.com # defaults to "41898282+github-actions[bot]@users.noreply.github.com" +# +# diff --git a/food-delivery-microservices.sln b/food-delivery-microservices.sln index 5bae6f63..d30b9071 100644 --- a/food-delivery-microservices.sln +++ b/food-delivery-microservices.sln @@ -542,6 +542,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "FoodDelivery.Services.Ident EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "FoodDelivery.Services.Identity.TestShared", "tests\Services\Identity\FoodDelivery.Services.Identity.TestShared\FoodDelivery.Services.Identity.TestShared.csproj", "{D12A7726-3B12-4CCD-A3F4-4ABDD28BD44C}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "FoodDelivery.Services.Identity.DependencyTests", "tests\Services\Identity\FoodDelivery.Services.Identity.DependencyTests\FoodDelivery.Services.Identity.DependencyTests.csproj", "{12AB9357-D6EE-404A-AADB-7D31BBFAFCD7}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -812,6 +814,10 @@ Global {D12A7726-3B12-4CCD-A3F4-4ABDD28BD44C}.Debug|Any CPU.Build.0 = Debug|Any CPU {D12A7726-3B12-4CCD-A3F4-4ABDD28BD44C}.Release|Any CPU.ActiveCfg = Release|Any CPU {D12A7726-3B12-4CCD-A3F4-4ABDD28BD44C}.Release|Any CPU.Build.0 = Release|Any CPU + {12AB9357-D6EE-404A-AADB-7D31BBFAFCD7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {12AB9357-D6EE-404A-AADB-7D31BBFAFCD7}.Debug|Any CPU.Build.0 = Debug|Any CPU + {12AB9357-D6EE-404A-AADB-7D31BBFAFCD7}.Release|Any CPU.ActiveCfg = Release|Any CPU + {12AB9357-D6EE-404A-AADB-7D31BBFAFCD7}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -968,6 +974,7 @@ Global {D9A193CB-020A-4367-A954-6D4EDAD9E327} = {A9B8E9D0-8E3C-4495-B8FE-CBBAE3D46E62} {84A67508-47F8-41D8-95D8-3493FF35554A} = {A9B8E9D0-8E3C-4495-B8FE-CBBAE3D46E62} {D12A7726-3B12-4CCD-A3F4-4ABDD28BD44C} = {A9B8E9D0-8E3C-4495-B8FE-CBBAE3D46E62} + {12AB9357-D6EE-404A-AADB-7D31BBFAFCD7} = {A9B8E9D0-8E3C-4495-B8FE-CBBAE3D46E62} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {AD0585D6-CBA4-4818-86D8-0D914F18E390} diff --git a/src/BuildingBlocks/BuildingBlocks.Core/Extensions/ServiceCollection/Dependency.cs b/src/BuildingBlocks/BuildingBlocks.Core/Extensions/ServiceCollection/Dependency.cs index 4b6b51f5..5903997a 100644 --- a/src/BuildingBlocks/BuildingBlocks.Core/Extensions/ServiceCollection/Dependency.cs +++ b/src/BuildingBlocks/BuildingBlocks.Core/Extensions/ServiceCollection/Dependency.cs @@ -1,5 +1,6 @@ using System.Reflection; using Microsoft.Extensions.DependencyInjection.Extensions; +using Microsoft.Extensions.Hosting; namespace BuildingBlocks.Core.Extensions.ServiceCollection; @@ -233,7 +234,6 @@ params Assembly[] assembliesToScan ) { var scanAssemblies = assembliesToScan.Length != 0 ? assembliesToScan : [Assembly.GetExecutingAssembly(),]; - var exceptions = new List(); // for resolving scoped based dependencies without errors using var scope = rootServiceProvider.CreateScope(); @@ -241,21 +241,37 @@ params Assembly[] assembliesToScan foreach (var serviceDescriptor in services) { + // Skip services that are not typically resolved directly or are special cases + if ( + serviceDescriptor.ServiceType == typeof(IHostedService) + || serviceDescriptor.ServiceType == typeof(IApplicationLifetime) + ) + { + continue; + } + try { var serviceType = serviceDescriptor.ServiceType; if (scanAssemblies.Contains(serviceType.Assembly)) - sp.GetRequiredService(serviceType); + { + // Attempt to resolve the service + var service = sp.GetService(serviceType); + + // Assert: Check that the service was resolved if it's not meant to be optional + if ( + serviceDescriptor.ImplementationInstance == null + && serviceDescriptor.ImplementationFactory == null + ) + { + service.NotBeNull(); + } + } } - catch (System.Exception e) + catch (System.Exception ex) { - exceptions.Add($"Unable to resolve '{serviceDescriptor.ServiceType.FullName}', detail: {e.Message}"); + throw new($"Failed to resolve service {serviceDescriptor.ServiceType.FullName}: {ex.Message}", ex); } } - - if (exceptions.Count != 0) - { - throw new System.Exception(string.Join("\n", exceptions)); - } } } diff --git a/src/BuildingBlocks/BuildingBlocks.Core/Extensions/ValidationExtensions.cs b/src/BuildingBlocks/BuildingBlocks.Core/Extensions/ValidationExtensions.cs index 2276b3b6..0d89ed8e 100644 --- a/src/BuildingBlocks/BuildingBlocks.Core/Extensions/ValidationExtensions.cs +++ b/src/BuildingBlocks/BuildingBlocks.Core/Extensions/ValidationExtensions.cs @@ -35,7 +35,7 @@ public static T NotBeNull([NotNull] this T? argument, System.Exception except return argument; } - public static string NotBeEmpty( + public static string NotBeInvalid( this string argument, [CallerArgumentExpression("argument")] string? argumentName = null ) @@ -74,7 +74,7 @@ public static string NotBeNullOrWhiteSpace( return argument; } - public static Guid NotBeEmpty( + public static Guid NotBeInvalid( this Guid argument, [CallerArgumentExpression("argument")] string? argumentName = null ) @@ -87,7 +87,7 @@ public static Guid NotBeEmpty( return argument; } - public static Guid NotBeEmpty( + public static Guid NotBeInvalid( [NotNull] this Guid? argument, [CallerArgumentExpression("argument")] string? argumentName = null ) @@ -97,7 +97,7 @@ public static Guid NotBeEmpty( throw new ValidationException(message: $"{argumentName} cannot be null or empty."); } - return argument.Value.NotBeEmpty(); + return argument.Value.NotBeInvalid(); } public static int NotBeNegativeOrZero( @@ -105,7 +105,7 @@ public static int NotBeNegativeOrZero( [CallerArgumentExpression("argument")] string? argumentName = null ) { - if (argument == 0) + if (argument <= 0) { throw new ValidationException($"{argumentName} cannot be zero."); } @@ -131,9 +131,9 @@ public static long NotBeNegativeOrZero( [CallerArgumentExpression("argument")] string? argumentName = null ) { - if (argument == 0) + if (argument <= 0) { - throw new ValidationException($"{argumentName} cannot be zero."); + throw new ValidationException($"{argumentName} cannot be negative or zero."); } return argument; @@ -157,9 +157,9 @@ public static decimal NotBeNegativeOrZero( [CallerArgumentExpression("argument")] string? argumentName = null ) { - if (argument == 0) + if (argument <= 0) { - throw new ValidationException($"{argumentName} cannot be zero."); + throw new ValidationException($"{argumentName} cannot be negative or zero."); } return argument; @@ -183,7 +183,7 @@ public static double NotBeNegativeOrZero( [CallerArgumentExpression("argument")] string? argumentName = null ) { - if (argument == 0) + if (argument <= 0) { throw new ValidationException($"{argumentName} cannot be zero."); } @@ -277,29 +277,31 @@ public static TEnum NotBeEmptyOrNull( throw new ValidationException(message: $"{argumentName} cannot be null or empty."); } - enumValue.NotBeEmpty(); + enumValue.NotBeInvalid(); return enumValue; } - public static TEnum NotBeEmpty( + public static TEnum NotBeInvalid( [NotNull] this TEnum enumValue, [CallerArgumentExpression("enumValue")] string? argumentName = null ) where TEnum : Enum { enumValue.NotBeNull(); - if (enumValue.Equals(default(TEnum))) + + // returns `true` if `enumValue` corresponds to one of the defined values in `TEnum` + if (!Enum.IsDefined(typeof(TEnum), enumValue)) { throw new ValidationException( - $"The value of '{argumentName}' cannot be the default value of '{typeof(TEnum).Name}' enum." + $"The value of '{argumentName}' is not valid for enum of '{typeof(TEnum).Name}'." ); } return enumValue; } - public static void NotBeEmpty( + public static void NotBeInvalid( this DateTime dateTime, [CallerArgumentExpression("dateTime")] string? argumentName = null ) diff --git a/src/BuildingBlocks/BuildingBlocks.Core/Types/MachineInstanceInfo.cs b/src/BuildingBlocks/BuildingBlocks.Core/Types/MachineInstanceInfo.cs index be47431c..df9c77ed 100644 --- a/src/BuildingBlocks/BuildingBlocks.Core/Types/MachineInstanceInfo.cs +++ b/src/BuildingBlocks/BuildingBlocks.Core/Types/MachineInstanceInfo.cs @@ -8,7 +8,7 @@ public record MachineInstanceInfo : IMachineInstanceInfo public MachineInstanceInfo(Guid clientId, string? clientGroup) { clientGroup.NotBeNullOrWhiteSpace(); - clientId.NotBeEmpty(); + clientId.NotBeInvalid(); ClientId = clientId; ClientGroup = clientGroup; diff --git a/src/BuildingBlocks/BuildingBlocks.Core/Web/Environments.cs b/src/BuildingBlocks/BuildingBlocks.Core/Web/Environments.cs new file mode 100644 index 00000000..98c0082f --- /dev/null +++ b/src/BuildingBlocks/BuildingBlocks.Core/Web/Environments.cs @@ -0,0 +1,11 @@ +namespace BuildingBlocks.Core.Web; + +public static class Environments +{ + public const string Development = "Development"; + public const string Staging = "Staging"; + public const string Production = "Production"; + public const string Test = "Test"; + public const string Docker = "Docker"; + public const string DependencyTest = "DependencyTest"; +} diff --git a/src/BuildingBlocks/BuildingBlocks.Core/Web/Extensions/HostEnvironmentExtensions.cs b/src/BuildingBlocks/BuildingBlocks.Core/Web/Extensions/HostEnvironmentExtensions.cs index bd215d28..342d36ae 100644 --- a/src/BuildingBlocks/BuildingBlocks.Core/Web/Extensions/HostEnvironmentExtensions.cs +++ b/src/BuildingBlocks/BuildingBlocks.Core/Web/Extensions/HostEnvironmentExtensions.cs @@ -4,7 +4,9 @@ namespace BuildingBlocks.Core.Web.Extensions; public static class HostEnvironmentExtensions { - public static bool IsTest(this IHostEnvironment env) => env.IsEnvironment("test"); + public static bool IsTest(this IHostEnvironment env) => env.IsEnvironment("Test"); - public static bool IsDocker(this IHostEnvironment env) => env.IsEnvironment("docker"); + public static bool IsDependencyTest(this IHostEnvironment env) => env.IsEnvironment("DependencyTest"); + + public static bool IsDocker(this IHostEnvironment env) => env.IsEnvironment("Docker"); } diff --git a/src/Services/Catalogs/FoodDelivery.Services.Catalogs.Api/Program.cs b/src/Services/Catalogs/FoodDelivery.Services.Catalogs.Api/Program.cs index 6c49f719..1b5923a1 100644 --- a/src/Services/Catalogs/FoodDelivery.Services.Catalogs.Api/Program.cs +++ b/src/Services/Catalogs/FoodDelivery.Services.Catalogs.Api/Program.cs @@ -53,13 +53,9 @@ var app = builder.Build(); -if (app.Environment.IsDevelopment() || app.Environment.IsTest()) +if (app.Environment.IsDependencyTest()) { - app.Services.ValidateDependencies( - builder.Services, - typeof(CatalogsMetadata).Assembly, - Assembly.GetExecutingAssembly() - ); + return; } /*----------------- Module Middleware Setup ------------------*/ diff --git a/src/Services/Catalogs/FoodDelivery.Services.Catalogs/Products/Features/CreatingProduct/v1/CreateProduct.cs b/src/Services/Catalogs/FoodDelivery.Services.Catalogs/Products/Features/CreatingProduct/v1/CreateProduct.cs index 7431a738..702d0022 100644 --- a/src/Services/Catalogs/FoodDelivery.Services.Catalogs/Products/Features/CreatingProduct/v1/CreateProduct.cs +++ b/src/Services/Catalogs/FoodDelivery.Services.Catalogs/Products/Features/CreatingProduct/v1/CreateProduct.cs @@ -87,11 +87,11 @@ public static CreateProduct Of( Name.Of(name), Price.Of(price), Stock.Of(stock, restockThreshold, maxStockThreshold), - status.NotBeEmpty(), + status.NotBeInvalid(), productType, Dimensions.Of(width, height, depth), Size.Of(size), - color.NotBeEmpty(), + color.NotBeInvalid(), CategoryId.Of(categoryId), SupplierId.Of(supplierId), BrandId.Of(brandId), diff --git a/src/Services/Catalogs/FoodDelivery.Services.Catalogs/Products/Features/CreatingProduct/v1/Events/Domain/ProductCreated.cs b/src/Services/Catalogs/FoodDelivery.Services.Catalogs/Products/Features/CreatingProduct/v1/Events/Domain/ProductCreated.cs index 56ab6673..755463ca 100644 --- a/src/Services/Catalogs/FoodDelivery.Services.Catalogs/Products/Features/CreatingProduct/v1/Events/Domain/ProductCreated.cs +++ b/src/Services/Catalogs/FoodDelivery.Services.Catalogs/Products/Features/CreatingProduct/v1/Events/Domain/ProductCreated.cs @@ -66,12 +66,12 @@ public static ProductCreated Of( stock.Available, stock.RestockThreshold, stock.MaxStockThreshold, - status.NotBeEmpty(), + status.NotBeInvalid(), dimensions.Width, dimensions.Height, dimensions.Depth, size, - color.NotBeEmpty(), + color.NotBeInvalid(), categoryId, supplierId, brandId, diff --git a/src/Services/Catalogs/FoodDelivery.Services.Catalogs/Products/Models/Product.cs b/src/Services/Catalogs/FoodDelivery.Services.Catalogs/Products/Models/Product.cs index 5a66a8ce..38f5bd4d 100644 --- a/src/Services/Catalogs/FoodDelivery.Services.Catalogs/Products/Models/Product.cs +++ b/src/Services/Catalogs/FoodDelivery.Services.Catalogs/Products/Models/Product.cs @@ -137,10 +137,10 @@ public void ChangeProductDetail( name.NotBeNull(); Name = name; - status.NotBeEmpty(); + status.NotBeInvalid(); ProductStatus = status; - productType.NotBeEmpty(); + productType.NotBeInvalid(); ProductType = productType; dimensions.NotBeNull(); @@ -149,7 +149,7 @@ public void ChangeProductDetail( size.NotBeNull(); Size = size; - color.NotBeEmpty(); + color.NotBeInvalid(); Color = color; // input validation will do in the command and our value objects, here we just do business validation diff --git a/src/Services/Customers/FoodDelivery.Services.Customers.Api/CustomersApiMetadata.cs b/src/Services/Customers/FoodDelivery.Services.Customers.Api/CustomersApiMetadata.cs index 86ac4c50..67b74a78 100644 --- a/src/Services/Customers/FoodDelivery.Services.Customers.Api/CustomersApiMetadata.cs +++ b/src/Services/Customers/FoodDelivery.Services.Customers.Api/CustomersApiMetadata.cs @@ -1,3 +1,3 @@ namespace FoodDelivery.Services.Customers.Api; -public class CustomersApiMetadata { } +public class CustomersApiMetadata; diff --git a/src/Services/Customers/FoodDelivery.Services.Customers.Api/Program.cs b/src/Services/Customers/FoodDelivery.Services.Customers.Api/Program.cs index 86b1e03b..aa1033a3 100644 --- a/src/Services/Customers/FoodDelivery.Services.Customers.Api/Program.cs +++ b/src/Services/Customers/FoodDelivery.Services.Customers.Api/Program.cs @@ -55,13 +55,9 @@ var app = builder.Build(); -if (app.Environment.IsDevelopment() || app.Environment.IsTest()) +if (app.Environment.IsDependencyTest()) { - // app.Services.ValidateDependencies( - // builder.Services, - // typeof(CustomersMetadata).Assembly, - // Assembly.GetExecutingAssembly() - // ); + return; } /*----------------- Module Middleware Setup ------------------*/ diff --git a/src/Services/Customers/FoodDelivery.Services.Customers/Customers/CustomersModuleMapping.cs b/src/Services/Customers/FoodDelivery.Services.Customers/Customers/CustomersModuleMapping.cs index 35c84119..8b844eca 100644 --- a/src/Services/Customers/FoodDelivery.Services.Customers/Customers/CustomersModuleMapping.cs +++ b/src/Services/Customers/FoodDelivery.Services.Customers/Customers/CustomersModuleMapping.cs @@ -4,6 +4,7 @@ using FoodDelivery.Services.Customers.Customers.Features.UpdatingCustomer.v1; using FoodDelivery.Services.Customers.Customers.Features.UpdatingCustomer.v1.Events.Domain; using FoodDelivery.Services.Customers.Customers.Features.UpdatingCustomer.v1.Read.Mongo; +using FoodDelivery.Services.Customers.Customers.Models.Reads; using Riok.Mapperly.Abstractions; namespace FoodDelivery.Services.Customers.Customers; @@ -112,16 +113,28 @@ internal static partial class CustomersModuleMapping )] internal static partial UpdateCustomerRead ToUpdateCustomerRead(this Models.Customer customer); - [MapProperty(nameof(UpdateCustomerRead.CustomerId), nameof(Models.Reads.Customer.CustomerId))] - [MapProperty(nameof(UpdateCustomerRead.Id), nameof(Models.Reads.Customer.Id))] - [MapProperty(nameof(UpdateCustomerRead.OccurredOn), nameof(Models.Reads.Customer.Created))] - internal static partial Models.Reads.Customer ToCustomer(this UpdateCustomerRead updateCustomerRead); - // https://mapperly.riok.app/docs/configuration/existing-target/ - [MapProperty(nameof(UpdateCustomerRead.CustomerId), nameof(Models.Reads.Customer.CustomerId))] - [MapProperty(nameof(UpdateCustomerRead.Id), nameof(Models.Reads.Customer.Id))] - [MapProperty(nameof(UpdateCustomerRead.OccurredOn), nameof(Models.Reads.Customer.Created))] - internal static partial void ToCustomer(this UpdateCustomerRead updateCustomerRead, Models.Reads.Customer customer); + // Todo: doesn't map correctly + internal static Models.Reads.Customer ToCustomer(this UpdateCustomerRead updateCustomerRead) + { + return new Customer + { + Created = updateCustomerRead.OccurredOn, + Email = updateCustomerRead.Email, + CustomerId = updateCustomerRead.CustomerId, + IdentityId = updateCustomerRead.IdentityId, + FirstName = updateCustomerRead.FirstName, + LastName = updateCustomerRead.LastName, + FullName = updateCustomerRead.FullName, + PhoneNumber = updateCustomerRead.PhoneNumber, + Country = updateCustomerRead.Country, + City = updateCustomerRead.City, + DetailAddress = updateCustomerRead.DetailAddress, + Nationality = updateCustomerRead.Nationality, + BirthDate = updateCustomerRead.BirthDate, + Id = updateCustomerRead.Id + }; + } [MapperIgnoreTarget(nameof(UpdateCustomerRead.Id))] [MapProperty(nameof(CustomerUpdated.Id), nameof(UpdateCustomerRead.CustomerId))] diff --git a/src/Services/Customers/FoodDelivery.Services.Customers/Customers/Features/CreatingCustomer/v1/CreateCustomer.cs b/src/Services/Customers/FoodDelivery.Services.Customers/Customers/Features/CreatingCustomer/v1/CreateCustomer.cs index d71fc5d1..5acf50fb 100644 --- a/src/Services/Customers/FoodDelivery.Services.Customers/Customers/Features/CreatingCustomer/v1/CreateCustomer.cs +++ b/src/Services/Customers/FoodDelivery.Services.Customers/Customers/Features/CreatingCustomer/v1/CreateCustomer.cs @@ -1,5 +1,6 @@ using BuildingBlocks.Abstractions.Commands; using BuildingBlocks.Core.Domain.ValueObjects; +using BuildingBlocks.Core.Exception.Types; using BuildingBlocks.Core.Extensions; using BuildingBlocks.Core.IdsGenerator; using BuildingBlocks.Validation.Extensions; @@ -58,6 +59,8 @@ public async Task Handle(CreateCustomer command, Cancellat throw new CustomerAlreadyExistsException($"Customer with email '{command.Email}' already exists."); var identityUser = await identityApiClient.GetUserByEmailAsync(command.Email, cancellationToken); + if (identityUser is null) + throw new NotFoundAppException($"user with email {command.Email} not found."); var customer = Customer.Create( CustomerId.Of(command.Id), diff --git a/src/Services/Customers/FoodDelivery.Services.Customers/Customers/Features/UpdatingCustomer/v1/Read/Mongo/UpdateCustomerRead.cs b/src/Services/Customers/FoodDelivery.Services.Customers/Customers/Features/UpdatingCustomer/v1/Read/Mongo/UpdateCustomerRead.cs index fe3e1a96..ac98e3d5 100644 --- a/src/Services/Customers/FoodDelivery.Services.Customers/Customers/Features/UpdatingCustomer/v1/Read/Mongo/UpdateCustomerRead.cs +++ b/src/Services/Customers/FoodDelivery.Services.Customers/Customers/Features/UpdatingCustomer/v1/Read/Mongo/UpdateCustomerRead.cs @@ -88,7 +88,7 @@ public async Task Handle(UpdateCustomerRead command, CancellationToken cancellat command.NotBeNull(); var existingCustomer = await customersReadUnitOfWork.CustomersRepository.FindOneAsync( - x => x.CustomerId == command.CustomerId, + x => x.CustomerId == command.CustomerId && x.Id == command.Id && x.IdentityId == command.IdentityId, cancellationToken ); @@ -97,9 +97,9 @@ public async Task Handle(UpdateCustomerRead command, CancellationToken cancellat throw new CustomerNotFoundException(command.CustomerId); } - command.ToCustomer(existingCustomer); + var updatedCustomer = command.ToCustomer(); - await customersReadUnitOfWork.CustomersRepository.UpdateAsync(existingCustomer, cancellationToken); + await customersReadUnitOfWork.CustomersRepository.UpdateAsync(updatedCustomer, cancellationToken); await customersReadUnitOfWork.CommitAsync(cancellationToken); } diff --git a/src/Services/Customers/FoodDelivery.Services.Customers/Customers/ValueObjects/CustomerName.cs b/src/Services/Customers/FoodDelivery.Services.Customers/Customers/ValueObjects/CustomerName.cs index 9061bba0..e40fd71c 100644 --- a/src/Services/Customers/FoodDelivery.Services.Customers/Customers/ValueObjects/CustomerName.cs +++ b/src/Services/Customers/FoodDelivery.Services.Customers/Customers/ValueObjects/CustomerName.cs @@ -17,17 +17,14 @@ private CustomerName() { } public static CustomerName Of([NotNull] string? firstName, [NotNull] string? lastName) { - firstName.NotBeNullOrWhiteSpace(); - lastName.NotBeNullOrWhiteSpace(); - - if (firstName.Length is > 100 or < 3) + if (string.IsNullOrEmpty(firstName) || firstName.Length is > 100 or < 3) { - throw new InvalidNameException(firstName); + throw new InvalidNameException(firstName ?? "First Name can't be null or empty."); } - if (lastName.Length is > 100 or < 3) + if (string.IsNullOrEmpty(lastName) || lastName.Length is > 100 or < 3) { - throw new InvalidNameException(lastName); + throw new InvalidNameException(lastName ?? "Last Name can't be null or empty."); } return new CustomerName { FirstName = firstName, LastName = lastName }; diff --git a/src/Services/Customers/FoodDelivery.Services.Customers/RestockSubscriptions/Features/CreatingRestockSubscription/v1/CreateRestockSubscription.cs b/src/Services/Customers/FoodDelivery.Services.Customers/RestockSubscriptions/Features/CreatingRestockSubscription/v1/CreateRestockSubscription.cs index 4e02f6af..2fb1825e 100644 --- a/src/Services/Customers/FoodDelivery.Services.Customers/RestockSubscriptions/Features/CreatingRestockSubscription/v1/CreateRestockSubscription.cs +++ b/src/Services/Customers/FoodDelivery.Services.Customers/RestockSubscriptions/Features/CreatingRestockSubscription/v1/CreateRestockSubscription.cs @@ -7,6 +7,7 @@ using FoodDelivery.Services.Customers.Customers.Exceptions.Application; using FoodDelivery.Services.Customers.Customers.ValueObjects; using FoodDelivery.Services.Customers.Products; +using FoodDelivery.Services.Customers.Products.Exceptions; using FoodDelivery.Services.Customers.RestockSubscriptions.Dtos.v1; using FoodDelivery.Services.Customers.RestockSubscriptions.Features.CreatingRestockSubscription.v1.Exceptions; using FoodDelivery.Services.Customers.RestockSubscriptions.Models.Write; @@ -74,6 +75,11 @@ CancellationToken cancellationToken var product = await catalogApiClient.GetProductByIdAsync(request.ProductId, cancellationToken); + if (product is null) + { + throw new ProductNotFoundException(request.ProductId); + } + if (product!.AvailableStock > 0) throw new ProductHasStockException(product.Id, product.AvailableStock, product.Name); diff --git a/src/Services/Customers/FoodDelivery.Services.Customers/RestockSubscriptions/Features/CreatingRestockSubscription/v1/Events/Domain/RestockSubscriptionCreated.cs b/src/Services/Customers/FoodDelivery.Services.Customers/RestockSubscriptions/Features/CreatingRestockSubscription/v1/Events/Domain/RestockSubscriptionCreated.cs index 6c91b762..d96aac74 100644 --- a/src/Services/Customers/FoodDelivery.Services.Customers/RestockSubscriptions/Features/CreatingRestockSubscription/v1/Events/Domain/RestockSubscriptionCreated.cs +++ b/src/Services/Customers/FoodDelivery.Services.Customers/RestockSubscriptions/Features/CreatingRestockSubscription/v1/Events/Domain/RestockSubscriptionCreated.cs @@ -41,7 +41,7 @@ bool processed customerId.NotBeNegativeOrZero(); productName.NotBeNullOrWhiteSpace(); email.NotBeNullOrWhiteSpace(); - created.NotBeEmpty(); + created.NotBeInvalid(); return new RestockSubscriptionCreated(id, productId, customerId, productName, email, created, processed); } diff --git a/src/Services/Customers/FoodDelivery.Services.Customers/RestockSubscriptions/Features/GetRestockSubscriptionById/v1/GetRestockSubscriptionById.cs b/src/Services/Customers/FoodDelivery.Services.Customers/RestockSubscriptions/Features/GetRestockSubscriptionById/v1/GetRestockSubscriptionById.cs index 56974e39..1d55e4ed 100644 --- a/src/Services/Customers/FoodDelivery.Services.Customers/RestockSubscriptions/Features/GetRestockSubscriptionById/v1/GetRestockSubscriptionById.cs +++ b/src/Services/Customers/FoodDelivery.Services.Customers/RestockSubscriptions/Features/GetRestockSubscriptionById/v1/GetRestockSubscriptionById.cs @@ -11,7 +11,7 @@ internal record GetRestockSubscriptionById(Guid Id) : IQuery { - public static GenerateRefreshToken Of(Guid userId, string? token = null) => new(userId.NotBeEmpty(), token); + public static GenerateRefreshToken Of(Guid userId, string? token = null) => new(userId.NotBeInvalid(), token); } internal class GenerateRefreshTokenHandler(IdentityContext context) diff --git a/src/Services/Identity/FoodDelivery.Services.Identity/Identity/Features/GettingRefreshTokenValidity/v1/GetRefreshTokenValidity.cs b/src/Services/Identity/FoodDelivery.Services.Identity/Identity/Features/GettingRefreshTokenValidity/v1/GetRefreshTokenValidity.cs index 84aace30..d3b8c08c 100644 --- a/src/Services/Identity/FoodDelivery.Services.Identity/Identity/Features/GettingRefreshTokenValidity/v1/GetRefreshTokenValidity.cs +++ b/src/Services/Identity/FoodDelivery.Services.Identity/Identity/Features/GettingRefreshTokenValidity/v1/GetRefreshTokenValidity.cs @@ -8,7 +8,7 @@ namespace FoodDelivery.Services.Identity.Identity.Features.GettingRefreshTokenVa internal record GetRefreshTokenValidity(Guid UserId, string RefreshToken) : IQuery { public static GetRefreshTokenValidity Of(Guid userId, string? refreshToken) => - new(userId.NotBeEmpty(), refreshToken.NotBeNull()); + new(userId.NotBeInvalid(), refreshToken.NotBeNull()); } internal class GetRefreshTokenValidityQueryHandler : IQueryHandler diff --git a/src/Services/Identity/FoodDelivery.Services.Identity/Users/Features/GettingUserById/v1/GetUserById.cs b/src/Services/Identity/FoodDelivery.Services.Identity/Users/Features/GettingUserById/v1/GetUserById.cs index 5ced4c56..294d83d5 100644 --- a/src/Services/Identity/FoodDelivery.Services.Identity/Users/Features/GettingUserById/v1/GetUserById.cs +++ b/src/Services/Identity/FoodDelivery.Services.Identity/Users/Features/GettingUserById/v1/GetUserById.cs @@ -12,7 +12,7 @@ namespace FoodDelivery.Services.Identity.Users.Features.GettingUserById.v1; internal record GetUserById(Guid Id) : IQuery { - public static GetUserById Of(Guid id) => new GetUserById(id.NotBeEmpty()); + public static GetUserById Of(Guid id) => new GetUserById(id.NotBeInvalid()); } internal class GetUserByIdValidator : AbstractValidator diff --git a/src/Services/Identity/FoodDelivery.Services.Identity/Users/Features/UpdatingUserState/v1/Events/Integration/UserStateUpdated.cs b/src/Services/Identity/FoodDelivery.Services.Identity/Users/Features/UpdatingUserState/v1/Events/Integration/UserStateUpdated.cs index 760809e2..2c3e24ae 100644 --- a/src/Services/Identity/FoodDelivery.Services.Identity/Users/Features/UpdatingUserState/v1/Events/Integration/UserStateUpdated.cs +++ b/src/Services/Identity/FoodDelivery.Services.Identity/Users/Features/UpdatingUserState/v1/Events/Integration/UserStateUpdated.cs @@ -14,5 +14,5 @@ public record UserStateUpdated(Guid UserId, UserState OldUserState, UserState Ne /// /// public static UserStateUpdated Of(Guid userId, UserState oldUserState, UserState newUserState) => - new(userId.NotBeEmpty(), oldUserState, newUserState); + new(userId.NotBeInvalid(), oldUserState, newUserState); } diff --git a/src/Services/Orders/FoodDelivery.Services.Orders.Api/Program.cs b/src/Services/Orders/FoodDelivery.Services.Orders.Api/Program.cs index 25fc94e0..aae17095 100644 --- a/src/Services/Orders/FoodDelivery.Services.Orders.Api/Program.cs +++ b/src/Services/Orders/FoodDelivery.Services.Orders.Api/Program.cs @@ -53,13 +53,9 @@ var app = builder.Build(); -if (app.Environment.IsDevelopment() || app.Environment.IsTest()) +if (app.Environment.IsDependencyTest()) { - app.Services.ValidateDependencies( - builder.Services, - typeof(OrdersMetadata).Assembly, - Assembly.GetExecutingAssembly() - ); + return; } /*----------------- Module Middleware Setup ------------------*/ diff --git a/src/Services/Shared/FoodDelivery.Services.Shared/Customers/Customers/Events/v1/Integration/CustomerUpdatedV1.cs b/src/Services/Shared/FoodDelivery.Services.Shared/Customers/Customers/Events/v1/Integration/CustomerUpdatedV1.cs index bf460f77..982e17ad 100644 --- a/src/Services/Shared/FoodDelivery.Services.Shared/Customers/Customers/Events/v1/Integration/CustomerUpdatedV1.cs +++ b/src/Services/Shared/FoodDelivery.Services.Shared/Customers/Customers/Events/v1/Integration/CustomerUpdatedV1.cs @@ -48,7 +48,7 @@ public static CustomerUpdatedV1 Of( lastName.NotBeNullOrWhiteSpace(); email.NotBeNullOrWhiteSpace().NotBeInvalidEmail(); phoneNumber.NotBeNullOrWhiteSpace(); - identityId.NotBeEmpty(); + identityId.NotBeInvalid(); return new CustomerUpdatedV1( id, diff --git a/src/Services/Shared/FoodDelivery.Services.Shared/Identity/Users/Events/v1/Integration/UserRegisteredV1.cs b/src/Services/Shared/FoodDelivery.Services.Shared/Identity/Users/Events/v1/Integration/UserRegisteredV1.cs index 3386f4cd..f2346c83 100644 --- a/src/Services/Shared/FoodDelivery.Services.Shared/Identity/Users/Events/v1/Integration/UserRegisteredV1.cs +++ b/src/Services/Shared/FoodDelivery.Services.Shared/Identity/Users/Events/v1/Integration/UserRegisteredV1.cs @@ -35,7 +35,7 @@ public static UserRegisteredV1 Of( ) { return new UserRegisteredV1( - identityId.NotBeEmpty(), + identityId.NotBeInvalid(), email.NotBeEmptyOrNull().NotBeInvalidEmail(), phoneNumber.NotBeEmptyOrNull(), userName.NotBeEmptyOrNull(), diff --git a/tests/Services/Catalogs/FoodDelivery.Services.Catalogs.DependencyTests/DependencyTests.cs b/tests/Services/Catalogs/FoodDelivery.Services.Catalogs.DependencyTests/DependencyTests.cs index 7f53510d..c07ecc56 100644 --- a/tests/Services/Catalogs/FoodDelivery.Services.Catalogs.DependencyTests/DependencyTests.cs +++ b/tests/Services/Catalogs/FoodDelivery.Services.Catalogs.DependencyTests/DependencyTests.cs @@ -1,4 +1,5 @@ using BuildingBlocks.Core.Extensions.ServiceCollection; +using BuildingBlocks.Core.Web; using FoodDelivery.Services.Catalogs.Api; using Microsoft.AspNetCore.Hosting; using Microsoft.AspNetCore.Mvc.Testing; @@ -15,7 +16,7 @@ public void validate_service_dependencies() { var factory = new WebApplicationFactory().WithWebHostBuilder(webHostBuilder => { - webHostBuilder.UseEnvironment("test"); + webHostBuilder.UseEnvironment(Environments.DependencyTest); webHostBuilder.ConfigureTestServices(services => { diff --git a/tests/Services/Catalogs/FoodDelivery.Services.Catalogs.DependencyTests/xunit.runner.json b/tests/Services/Catalogs/FoodDelivery.Services.Catalogs.DependencyTests/xunit.runner.json new file mode 100644 index 00000000..adcf8123 --- /dev/null +++ b/tests/Services/Catalogs/FoodDelivery.Services.Catalogs.DependencyTests/xunit.runner.json @@ -0,0 +1,8 @@ +{ + "$schema": "https://xunit.net/schema/current/xunit.runner.schema.json", + "parallelizeAssembly": false, + "parallelizeTestCollections": false, + "methodDisplay": "method", + "methodDisplayOptions": "all", + "diagnosticMessages" : true +} diff --git a/tests/Services/Catalogs/FoodDelivery.Services.Catalogs.IntegrationTests/UnitTest1.cs b/tests/Services/Catalogs/FoodDelivery.Services.Catalogs.IntegrationTests/UnitTest1.cs deleted file mode 100644 index 41b4af94..00000000 --- a/tests/Services/Catalogs/FoodDelivery.Services.Catalogs.IntegrationTests/UnitTest1.cs +++ /dev/null @@ -1,60 +0,0 @@ -using Bogus; -using BuildingBlocks.Core.Extensions; -using FoodDelivery.Services.Catalogs.Brands; -using FoodDelivery.Services.Catalogs.Brands.Contracts; -using FoodDelivery.Services.Catalogs.Brands.Data; -using FoodDelivery.Services.Catalogs.Brands.ValueObjects; -using FoodDelivery.Services.Catalogs.Categories; -using FoodDelivery.Services.Catalogs.Categories.Data; -using FoodDelivery.Services.Catalogs.Products.Models; -using FoodDelivery.Services.Catalogs.Products.ValueObjects; -using FoodDelivery.Services.Catalogs.Suppliers; -using FoodDelivery.Services.Catalogs.Suppliers.Contracts; -using FoodDelivery.Services.Catalogs.Suppliers.Data; -using NSubstitute; - -namespace FoodDelivery.Services.Catalogs.IntegrationTests; - -public class UnitTest1 -{ - [Fact] - [Trait("Category", "Integration")] - public void Test1() - { - long id = 1; - var category = new CategoryFaker().Generate(); - var supplier = new SupplierFaker().Generate(); - var brand = new BrandFaker().Generate(); - - var supplierChecker = Substitute.For(); - supplierChecker.SupplierExists(Arg.Any()).Returns(true); - - var brandChecker = Substitute.For(); - brandChecker.BrandExists(Arg.Any()).Returns(true); - - // Call for objects that have complex initialization - var productFaker = new Faker().CustomInstantiator(faker => - Product.Create( - ProductId.Of(id++), - Name.Of(faker.Commerce.ProductName()), - ProductInformation.Of(faker.Commerce.ProductName(), faker.Commerce.ProductDescription()), - Stock.Of(faker.Random.Int(10, 20), 5, 20), - ProductStatus.Available, - faker.Random.Enum(), - Dimensions.Of(faker.Random.Int(10, 50), faker.Random.Int(10, 50), faker.Random.Int(10, 50)), - Size.Of(faker.PickRandom("M", "S", "L")), - faker.Random.Enum(), - faker.Commerce.ProductDescription(), - Price.Of(faker.PickRandom(100, 200, 500)), - category.Id, - SupplierId.Of(faker.Random.Long(1, 5)), - BrandId.Of(faker.Random.Long(1, 5)), - _ => Task.FromResult(true)!, - supplierChecker, - brandChecker - ) - ); - - var s = productFaker.Generate(5); - } -} diff --git a/tests/Services/Customers/FoodDelivery.Services.Customers.DependencyTests/DependencyTests.cs b/tests/Services/Customers/FoodDelivery.Services.Customers.DependencyTests/DependencyTests.cs index 0534e9c3..3898f715 100644 --- a/tests/Services/Customers/FoodDelivery.Services.Customers.DependencyTests/DependencyTests.cs +++ b/tests/Services/Customers/FoodDelivery.Services.Customers.DependencyTests/DependencyTests.cs @@ -5,6 +5,7 @@ using Microsoft.AspNetCore.TestHost; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.DependencyInjection.Extensions; +using Environments = BuildingBlocks.Core.Web.Environments; namespace FoodDelivery.Services.Customers.DependencyTests; @@ -15,7 +16,7 @@ public void validate_service_dependencies() { var factory = new WebApplicationFactory().WithWebHostBuilder(webHostBuilder => { - webHostBuilder.UseEnvironment("test"); + webHostBuilder.UseEnvironment(Environments.DependencyTest); webHostBuilder.ConfigureTestServices(services => { diff --git a/tests/Services/Customers/FoodDelivery.Services.Customers.DependencyTests/xunit.runner.json b/tests/Services/Customers/FoodDelivery.Services.Customers.DependencyTests/xunit.runner.json new file mode 100644 index 00000000..adcf8123 --- /dev/null +++ b/tests/Services/Customers/FoodDelivery.Services.Customers.DependencyTests/xunit.runner.json @@ -0,0 +1,8 @@ +{ + "$schema": "https://xunit.net/schema/current/xunit.runner.schema.json", + "parallelizeAssembly": false, + "parallelizeTestCollections": false, + "methodDisplay": "method", + "methodDisplayOptions": "all", + "diagnosticMessages" : true +} diff --git a/tests/Services/Customers/FoodDelivery.Services.Customers.TestShared/Fakes/Customers/Commands/FakeUpdateCustomerRead.cs b/tests/Services/Customers/FoodDelivery.Services.Customers.TestShared/Fakes/Customers/Commands/FakeUpdateCustomerRead.cs index ab6f0965..05e98666 100644 --- a/tests/Services/Customers/FoodDelivery.Services.Customers.TestShared/Fakes/Customers/Commands/FakeUpdateCustomerRead.cs +++ b/tests/Services/Customers/FoodDelivery.Services.Customers.TestShared/Fakes/Customers/Commands/FakeUpdateCustomerRead.cs @@ -5,9 +5,19 @@ namespace FoodDelivery.Services.Customers.TestShared.Fakes.Customers.Commands; internal sealed class FakeUpdateCustomerRead : AutoFaker { - public FakeUpdateCustomerRead() + public FakeUpdateCustomerRead(Guid id, long customerId, Guid identityId) { - long id = 1; - RuleFor(x => x.CustomerId, f => id++); + RuleFor(x => x.CustomerId, f => customerId) + .RuleFor(x => x.Id, (f, u) => id) + .RuleFor(x => x.IdentityId, (f, u) => identityId) + .RuleFor(x => x.FirstName, (f, u) => f.Name.FirstName()) + .RuleFor(u => u.LastName, (f, u) => f.Name.LastName()) + .RuleFor(u => u.FullName, (f, u) => f.Name.FullName()) + .RuleFor(u => u.Email, (f, u) => f.Internet.Email(u.FirstName, u.LastName)) + .RuleFor(u => u.PhoneNumber, (f, u) => f.Phone.PhoneNumber("(+##)##########")) + .RuleFor(u => u.City, (f, u) => f.Address.City()) + .RuleFor(u => u.Country, (f, u) => f.Address.Country()) + .RuleFor(u => u.DetailAddress, (f, u) => f.Address.FullAddress()) + .RuleFor(u => u.BirthDate, (f, u) => DateTime.Now); } } diff --git a/tests/Services/Customers/FoodDelivery.Services.Customers.UnitTests/Customers/Features/CreatingCustomer/v1/CreateCustomerTests.cs b/tests/Services/Customers/FoodDelivery.Services.Customers.UnitTests/Customers/Features/CreatingCustomer/v1/CreateCustomerTests.cs index 795bc406..829870ab 100644 --- a/tests/Services/Customers/FoodDelivery.Services.Customers.UnitTests/Customers/Features/CreatingCustomer/v1/CreateCustomerTests.cs +++ b/tests/Services/Customers/FoodDelivery.Services.Customers.UnitTests/Customers/Features/CreatingCustomer/v1/CreateCustomerTests.cs @@ -81,7 +81,7 @@ public async Task must_throw_not_found_exception_with_none_exists_user() // Assert //https://fluentassertions.com/exceptions/ await act.Should() - .ThrowAsync() + .ThrowAsync() .WithMessage("*") .Where(e => e.StatusCode == StatusCodes.Status404NotFound); } @@ -100,7 +100,7 @@ public async Task must_throw_argument_exception_with_null_command() }; // Assert - await act.Should().ThrowAsync(); + await act.Should().ThrowAsync(); } [CategoryTrait(TestCategory.Unit)] diff --git a/tests/Services/Customers/FoodDelivery.Services.Customers.UnitTests/Customers/Features/UpdatingCustomer/v1/Read/UpdateCustomerTests.cs b/tests/Services/Customers/FoodDelivery.Services.Customers.UnitTests/Customers/Features/UpdatingCustomer/v1/Read/UpdateCustomerTests.cs index 4a0e499c..b79710d7 100644 --- a/tests/Services/Customers/FoodDelivery.Services.Customers.UnitTests/Customers/Features/UpdatingCustomer/v1/Read/UpdateCustomerTests.cs +++ b/tests/Services/Customers/FoodDelivery.Services.Customers.UnitTests/Customers/Features/UpdatingCustomer/v1/Read/UpdateCustomerTests.cs @@ -32,8 +32,12 @@ public UpdateCustomerTests() public async Task can_update_customer_read_with_valid_inputs() { // Arrange - var fakeUpdateCustomerReadCommand = new FakeUpdateCustomerRead().Generate(); var existCustomer = new FakeCustomerReadModel().Generate(); + var fakeUpdateCustomerReadCommand = new FakeUpdateCustomerRead( + existCustomer.Id, + existCustomer.CustomerId, + existCustomer.IdentityId + ).Generate(); var updateCustomer = fakeUpdateCustomerReadCommand.ToCustomer(); _customersReadUnitOfWork @@ -71,7 +75,7 @@ await _customersReadUnitOfWork public async Task must_throw_not_found_exception_when_customer_not_exist() { // Arrange - var fakeUpdateCustomerReadCommand = new FakeUpdateCustomerRead().Generate(); + var fakeUpdateCustomerReadCommand = new FakeUpdateCustomerRead(Guid.NewGuid(), 230, Guid.NewGuid()).Generate(); _customersReadUnitOfWork .CustomersRepository.FindOneAsync(Arg.Any>>(), Arg.Any()) diff --git a/tests/Services/Customers/FoodDelivery.Services.Customers.UnitTests/Customers/Features/UpdatingCustomer/v1/UpdateCustomerTests.cs b/tests/Services/Customers/FoodDelivery.Services.Customers.UnitTests/Customers/Features/UpdatingCustomer/v1/UpdateCustomerTests.cs index d1e68a9e..905edacb 100644 --- a/tests/Services/Customers/FoodDelivery.Services.Customers.UnitTests/Customers/Features/UpdatingCustomer/v1/UpdateCustomerTests.cs +++ b/tests/Services/Customers/FoodDelivery.Services.Customers.UnitTests/Customers/Features/UpdatingCustomer/v1/UpdateCustomerTests.cs @@ -1,3 +1,4 @@ +using BuildingBlocks.Core.Exception.Types; using FluentAssertions; using FoodDelivery.Services.Customers.Customers.Exceptions.Application; using FoodDelivery.Services.Customers.Customers.Features.UpdatingCustomer.v1; @@ -51,7 +52,7 @@ public async Task must_throw_argument_exception_with_null_command() }; // Assert - await act.Should().ThrowAsync(); + await act.Should().ThrowAsync(); } [CategoryTrait(TestCategory.Unit)] diff --git a/tests/Services/Customers/FoodDelivery.Services.Customers.UnitTests/Customers/Models/CustomerTests.cs b/tests/Services/Customers/FoodDelivery.Services.Customers.UnitTests/Customers/Models/CustomerTests.cs index 4b6c6b77..06d4d71e 100644 --- a/tests/Services/Customers/FoodDelivery.Services.Customers.UnitTests/Customers/Models/CustomerTests.cs +++ b/tests/Services/Customers/FoodDelivery.Services.Customers.UnitTests/Customers/Models/CustomerTests.cs @@ -1,7 +1,6 @@ using FluentAssertions; using FoodDelivery.Services.Customers.Customers.Features.CreatingCustomer.v1.Events.Domain; using FoodDelivery.Services.Customers.Customers.Features.UpdatingCustomer.v1.Events.Domain; -using FoodDelivery.Services.Customers.TestShared.Fakes.Customers.Commands; using FoodDelivery.Services.Customers.TestShared.Fakes.Customers.Entities; using Tests.Shared.XunitCategories; @@ -28,7 +27,10 @@ public void can_create_customer_with_valid_inputs() customerInput.Email, customerInput.PhoneNumber, customerInput.Name, - customerInput.IdentityId + customerInput.IdentityId, + customerInput.Address, + customerInput.BirthDate, + customerInput.Nationality ); // Assert diff --git a/tests/Services/Customers/FoodDelivery.Services.Customers.UnitTests/Customers/ValueObjects/CustomerIdTests.cs b/tests/Services/Customers/FoodDelivery.Services.Customers.UnitTests/Customers/ValueObjects/CustomerIdTests.cs index 181e3667..e6b89cf2 100644 --- a/tests/Services/Customers/FoodDelivery.Services.Customers.UnitTests/Customers/ValueObjects/CustomerIdTests.cs +++ b/tests/Services/Customers/FoodDelivery.Services.Customers.UnitTests/Customers/ValueObjects/CustomerIdTests.cs @@ -2,6 +2,7 @@ using FluentAssertions; using FoodDelivery.Services.Customers.Customers.ValueObjects; using Tests.Shared.XunitCategories; +using ValidationException = BuildingBlocks.Core.Exception.Types.ValidationException; namespace FoodDelivery.Services.Customers.UnitTests.Customers.ValueObjects; @@ -37,6 +38,6 @@ public void must_throw_exception_with_invalid_id() }; // Assert - act.Should().Throw(); + act.Should().Throw(); } } diff --git a/tests/Services/Customers/FoodDelivery.Services.Customers.UnitTests/Customers/ValueObjects/CustomerNameTests.cs b/tests/Services/Customers/FoodDelivery.Services.Customers.UnitTests/Customers/ValueObjects/CustomerNameTests.cs index 171cecfa..8295a298 100644 --- a/tests/Services/Customers/FoodDelivery.Services.Customers.UnitTests/Customers/ValueObjects/CustomerNameTests.cs +++ b/tests/Services/Customers/FoodDelivery.Services.Customers.UnitTests/Customers/ValueObjects/CustomerNameTests.cs @@ -3,17 +3,13 @@ using FoodDelivery.Services.Customers.Customers.Exceptions.Domain; using FoodDelivery.Services.Customers.Customers.ValueObjects; using Tests.Shared.XunitCategories; +using ValidationException = BuildingBlocks.Core.Exception.Types.ValidationException; namespace FoodDelivery.Services.Customers.UnitTests.Customers.ValueObjects; public class CustomerNameTests { - private readonly Faker _faker; - - public CustomerNameTests() - { - _faker = new Faker(); - } + private readonly Faker _faker = new(); [Fact] [CategoryTrait(TestCategory.Unit)] @@ -30,7 +26,7 @@ public void can_create_name_with_valid_inputs() [Fact] [CategoryTrait(TestCategory.Unit)] - public void must_throw_exception_with_invalid_name() + public void must_throw_exception_with_null_last_name() { string firstName = string.Empty; string lastName = null!; @@ -45,4 +41,22 @@ public void must_throw_exception_with_invalid_name() // Assert act.Should().Throw(); } + + [Fact] + [CategoryTrait(TestCategory.Unit)] + public void must_throw_exception_with_invalid_last_name_first_name() + { + string firstName = "ss"; + string lastName = string.Empty; + + //Act + var act = () => + { + var customerNameValueObject = CustomerName.Of(firstName, lastName); + return customerNameValueObject; + }; + + // Assert + act.Should().Throw(); + } } diff --git a/tests/Services/Customers/FoodDelivery.Services.Customers.UnitTests/RestockSubscriptions/Features/CreatingRestockSubscription/v1/CreateRestockSubscriptionTests.cs b/tests/Services/Customers/FoodDelivery.Services.Customers.UnitTests/RestockSubscriptions/Features/CreatingRestockSubscription/v1/CreateRestockSubscriptionTests.cs index 3ecdd631..39ab7f65 100644 --- a/tests/Services/Customers/FoodDelivery.Services.Customers.UnitTests/RestockSubscriptions/Features/CreatingRestockSubscription/v1/CreateRestockSubscriptionTests.cs +++ b/tests/Services/Customers/FoodDelivery.Services.Customers.UnitTests/RestockSubscriptions/Features/CreatingRestockSubscription/v1/CreateRestockSubscriptionTests.cs @@ -3,6 +3,7 @@ using FoodDelivery.Services.Customers.Customers.Exceptions.Application; using FoodDelivery.Services.Customers.Customers.ValueObjects; using FoodDelivery.Services.Customers.Products; +using FoodDelivery.Services.Customers.Products.Exceptions; using FoodDelivery.Services.Customers.RestockSubscriptions.Features.CreatingRestockSubscription.v1; using FoodDelivery.Services.Customers.RestockSubscriptions.Features.CreatingRestockSubscription.v1.Exceptions; using FoodDelivery.Services.Customers.RestockSubscriptions.ValueObjects; @@ -77,7 +78,7 @@ public async Task must_throw_argument_exception_with_null_command() }; // Assert - await act.Should().ThrowAsync(); + await act.Should().ThrowAsync(); } [CategoryTrait(TestCategory.Unit)] @@ -120,7 +121,7 @@ public async Task must_throw_not_found_exception_with_none_exists_product() // Assert //https://fluentassertions.com/exceptions/ await act.Should() - .ThrowAsync() + .ThrowAsync() .WithMessage("*") .Where(e => e.StatusCode == StatusCodes.Status404NotFound); } diff --git a/tests/Services/Identity/FoodDelivery.Services.Identity.DependencyTests/DependencyTests.cs b/tests/Services/Identity/FoodDelivery.Services.Identity.DependencyTests/DependencyTests.cs new file mode 100644 index 00000000..81413d24 --- /dev/null +++ b/tests/Services/Identity/FoodDelivery.Services.Identity.DependencyTests/DependencyTests.cs @@ -0,0 +1,32 @@ +using BuildingBlocks.Core.Extensions.ServiceCollection; +using BuildingBlocks.Core.Web; +using FoodDelivery.Services.Identity.Api; +using Microsoft.AspNetCore.Hosting; +using Microsoft.AspNetCore.Mvc.Testing; +using Microsoft.AspNetCore.TestHost; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.DependencyInjection.Extensions; + +namespace FoodDelivery.Services.Identity.DependencyTests; + +public class DependencyTests +{ + [Fact] + public void validate_service_dependencies() + { + var factory = new WebApplicationFactory().WithWebHostBuilder(webHostBuilder => + { + webHostBuilder.UseEnvironment(Environments.DependencyTest); + + webHostBuilder.ConfigureTestServices(services => + { + services.TryAddTransient(_ => services); + }); + }); + + using var scope = factory.Services.CreateScope(); + var sp = scope.ServiceProvider; + var services = sp.GetRequiredService(); + sp.ValidateDependencies(services, typeof(IdentityApiMetadata).Assembly, typeof(IdentityApiMetadata).Assembly); + } +} diff --git a/tests/Services/Identity/FoodDelivery.Services.Identity.DependencyTests/FoodDelivery.Services.Identity.DependencyTests.csproj b/tests/Services/Identity/FoodDelivery.Services.Identity.DependencyTests/FoodDelivery.Services.Identity.DependencyTests.csproj new file mode 100644 index 00000000..f4d0f638 --- /dev/null +++ b/tests/Services/Identity/FoodDelivery.Services.Identity.DependencyTests/FoodDelivery.Services.Identity.DependencyTests.csproj @@ -0,0 +1,22 @@ + + + + + + + all + runtime; build; native; contentfiles; analyzers; buildtransitive + + + + + + PreserveNewest + + + + + + + + diff --git a/tests/Services/Identity/FoodDelivery.Services.Identity.DependencyTests/xunit.runner.json b/tests/Services/Identity/FoodDelivery.Services.Identity.DependencyTests/xunit.runner.json new file mode 100644 index 00000000..adcf8123 --- /dev/null +++ b/tests/Services/Identity/FoodDelivery.Services.Identity.DependencyTests/xunit.runner.json @@ -0,0 +1,8 @@ +{ + "$schema": "https://xunit.net/schema/current/xunit.runner.schema.json", + "parallelizeAssembly": false, + "parallelizeTestCollections": false, + "methodDisplay": "method", + "methodDisplayOptions": "all", + "diagnosticMessages" : true +} diff --git a/tests/Services/Identity/FoodDelivery.Services.Identity.IntegrationTests/Users/Features/RegisteringUser/v1/RegisterUserTests.cs b/tests/Services/Identity/FoodDelivery.Services.Identity.IntegrationTests/Users/Features/RegisteringUser/v1/RegisterUserTests.cs index 97d9275d..74b588aa 100644 --- a/tests/Services/Identity/FoodDelivery.Services.Identity.IntegrationTests/Users/Features/RegisteringUser/v1/RegisterUserTests.cs +++ b/tests/Services/Identity/FoodDelivery.Services.Identity.IntegrationTests/Users/Features/RegisteringUser/v1/RegisterUserTests.cs @@ -27,7 +27,7 @@ ITestOutputHelper outputHelper faker.Person.LastName, faker.Person.UserName, faker.Person.Email, - faker.Phone.PhoneNumber(), + faker.Phone.PhoneNumber("(+##)##########"), "123456", "123456" )) diff --git a/tests/Shared/Tests.Shared/Factory/CustomWebApplicationFactory.cs b/tests/Shared/Tests.Shared/Factory/CustomWebApplicationFactory.cs index de651a4f..83e030cd 100644 --- a/tests/Shared/Tests.Shared/Factory/CustomWebApplicationFactory.cs +++ b/tests/Shared/Tests.Shared/Factory/CustomWebApplicationFactory.cs @@ -13,6 +13,7 @@ using Serilog; using Serilog.Events; using WebMotions.Fake.Authentication.JwtBearer; +using Environments = BuildingBlocks.Core.Web.Environments; using ILogger = Microsoft.Extensions.Logging.ILogger; namespace Tests.Shared.Factory; @@ -80,7 +81,7 @@ public CustomWebApplicationFactory WithHostBuilder(Action /// -class WebApplicationFactoryWithHost : WebApplicationFactory +class WebApplicationFactoryWithHost( + Action configureServices, + Action configure, + string[]? args = null +) : WebApplicationFactory where TEntryPoint : class { - private readonly Action _configureServices; - readonly Action _configure; - readonly string[] _args; + readonly string[] _args = args ?? []; public ITestOutputHelper? TestOutputHelper { get; set; } public Action? HostBuilderCustomization { get; set; } public Action? WebHostBuilderCustomization { get; set; } - public WebApplicationFactoryWithHost( - Action configureServices, - Action configure, - string[]? args = null - ) - { - _configureServices = configureServices; - _configure = configure; - _args = args ?? Array.Empty(); - } - protected override void ConfigureWebHost(IWebHostBuilder builder) { - builder.ConfigureServices(services => - { - // change existing services ... - if (TestOutputHelper != null) - services.AddLogging(b => b.AddXUnit(TestOutputHelper)); - }); - builder.ConfigureTestServices(services => { // change existing services ... @@ -62,28 +48,44 @@ protected override void ConfigureWebHost(IWebHostBuilder builder) } // This creates a new host, when there is no program file (EntryPoint) for finding the CreateDefaultBuilder - this approach use for testing web components without startup or program - protected override IHostBuilder CreateHostBuilder() + protected override IHost CreateHost(IHostBuilder builder) { - var hostBuilder = Host.CreateDefaultBuilder(_args); - // create startup with these configs - hostBuilder.ConfigureWebHostDefaults( - (webBuilder) => + builder.UseEnvironment(Environments.Test); + builder.UseContentRoot("."); + + // UseSerilog on WebHostBuilder is absolute so we should use IHostBuilder + builder.UseSerilog( + (ctx, loggerConfiguration) => { - webBuilder.ConfigureServices(_configureServices); + //https://github.com/trbenning/serilog-sinks-xunit + if (TestOutputHelper is not null) + { + loggerConfiguration.WriteTo.TestOutput( + TestOutputHelper, + LogEventLevel.Information, + "{Timestamp:yyyy-MM-dd HH:mm:ss.fff} {Level} - {Message:lj}{NewLine}{Exception}" + ); + } + } + ); - //https://github.com/dotnet/aspnetcore/issues/37680#issuecomment-1331559463 - //https://github.com/dotnet/aspnetcore/issues/45319#issuecomment-1334355103 - // Set this so that the async context flows - _configure.ConfigureTestApplicationBuilder(); + // create startup with these configs + builder.ConfigureWebHostDefaults(webBuilder => + { + webBuilder.ConfigureServices(configureServices); - webBuilder.Configure(_configure); + //https://github.com/dotnet/aspnetcore/issues/37680#issuecomment-1331559463 + //https://github.com/dotnet/aspnetcore/issues/45319#issuecomment-1334355103 + // Set this so that the async context flows + configure.ConfigureTestApplicationBuilder(); - WebHostBuilderCustomization?.Invoke(webBuilder); - } - ); + webBuilder.Configure(configure); + + WebHostBuilderCustomization?.Invoke(webBuilder); + }); - HostBuilderCustomization?.Invoke(hostBuilder); + HostBuilderCustomization?.Invoke(builder); - return hostBuilder; + return base.CreateHost(builder); } } From 5a52242f132c55db4dcb59c48a03a2d3f61e51eb Mon Sep 17 00:00:00 2001 From: Mehdi Hadeli Date: Sun, 15 Sep 2024 15:11:58 +0330 Subject: [PATCH 4/4] test: :test_tube: refactor some tests --- .devcontainer/devcontainer.json | 3 ++- .github/actions/app-version/action.yml | 2 +- .github/actions/docker-build-push/action.yml | 2 +- .github/actions/publish-app/action.yml | 2 +- .github/actions/test-coverage/action.yml | 2 +- .github/workflows/reusable-build-test-push.yml | 2 +- 6 files changed, 7 insertions(+), 6 deletions(-) diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json index d53b0e1d..430ab706 100644 --- a/.devcontainer/devcontainer.json +++ b/.devcontainer/devcontainer.json @@ -107,7 +107,8 @@ "vscode-icons-team.vscode-icons", "csharpier.csharpier-vscode", "redhat.vscode-yaml", - "kennylong.kubernetes-yaml-formatter" + "kennylong.kubernetes-yaml-formatter", + "sonarsource.sonarlint-vscode" ] } }, diff --git a/.github/actions/app-version/action.yml b/.github/actions/app-version/action.yml index b8b90471..88f7ac08 100644 --- a/.github/actions/app-version/action.yml +++ b/.github/actions/app-version/action.yml @@ -132,7 +132,7 @@ runs: - name: Upload Version Artifact if: success() - uses: actions/upload-artifact@v2 + uses: actions/upload-artifact@v4 with: name: ${{ inputs.service-name}}_version_artifacts path: version_name.txt diff --git a/.github/actions/docker-build-push/action.yml b/.github/actions/docker-build-push/action.yml index ba642ba6..3b83d690 100644 --- a/.github/actions/docker-build-push/action.yml +++ b/.github/actions/docker-build-push/action.yml @@ -94,7 +94,7 @@ runs: - name: Upload artifact if: success() - uses: actions/upload-artifact@v2 + uses: actions/upload-artifact@v4 with: name: ${{ inputs.service-name}}_image_artifacts path: image_name.txt diff --git a/.github/actions/publish-app/action.yml b/.github/actions/publish-app/action.yml index 8ab81ce6..4f894cf7 100644 --- a/.github/actions/publish-app/action.yml +++ b/.github/actions/publish-app/action.yml @@ -85,7 +85,7 @@ runs: run: ls -R ${{ github.workspace }}/output - name: Upload Publish Services Artifacts For Deployment Jobs - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 if: success() with: name: ${{ inputs.service-name}}_publish_artifacts diff --git a/.github/actions/test-coverage/action.yml b/.github/actions/test-coverage/action.yml index e5e2dc99..a31750b8 100644 --- a/.github/actions/test-coverage/action.yml +++ b/.github/actions/test-coverage/action.yml @@ -68,7 +68,7 @@ runs: # https://github.blog/changelog/2020-10-08-github-actions-ability-to-change-retention-days-for-artifacts-and-logs/ # https://github.com/actions/upload-artifact#upload-an-entire-directory - name: Upload Test And Coverage Results Artifacts - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 if: steps.test-results-zip.outcome == 'success' with: name: ${{ inputs.service-name}}_test_artifacts diff --git a/.github/workflows/reusable-build-test-push.yml b/.github/workflows/reusable-build-test-push.yml index f365cf06..d0137a17 100644 --- a/.github/workflows/reusable-build-test-push.yml +++ b/.github/workflows/reusable-build-test-push.yml @@ -188,7 +188,7 @@ jobs: - name: Upload CD Status artifact if: success() - uses: actions/upload-artifact@v2 + uses: actions/upload-artifact@v4 with: name: ${{ inputs.service-name}}_cd_status_artifacts path: cd_status.txt