diff --git a/.github/workflows/docker-test-2.yaml b/.github/workflows/docker-test-2.yaml new file mode 100644 index 00000000..9da522c7 --- /dev/null +++ b/.github/workflows/docker-test-2.yaml @@ -0,0 +1,58 @@ +name: Test using Docker for CI +on: + push: + branches: [ feature/docker-image-null ] + +jobs: + docker-test: + runs-on: ubuntu-latest + container: + image: mcr.microsoft.com/dotnet/sdk:3.1 + options: --network-alias refimpl-api + strategy: + fail-fast: false + matrix: + mode: ['random'] + profile: ['all-features'] + steps: + - name: Checkout OpenActive.Server.NET + uses: actions/checkout@v2 + with: + path: server + - name: Install OpenActive.Server.NET dependencies + if: ${{ matrix.profile != 'no-auth' && matrix.profile != 'single-seller' }} + run: dotnet restore ./server/ + - name: Build .NET Core Authentication Authority Reference Implementation + if: ${{ matrix.profile != 'no-auth' && matrix.profile != 'single-seller' }} + run: dotnet build ./server/Examples/BookingSystem.AspNetCore.IdentityServer/BookingSystem.AspNetCore.IdentityServer.csproj --configuration Release --no-restore + - name: Start .NET Core Authentication Authority Reference Implementation + if: ${{ matrix.profile != 'no-auth' && matrix.profile != 'single-seller' }} + run: | + dotnet run --no-launch-profile --project ./server/Examples/BookingSystem.AspNetCore.IdentityServer/BookingSystem.AspNetCore.IdentityServer.csproj --configuration Release --no-build & + - name: Build .NET Core Booking Server Reference Implementation + run: dotnet build ./server/Examples/BookingSystem.AspNetCore/BookingSystem.AspNetCore.csproj --configuration Release ${{ matrix.profile != 'no-auth' && matrix.profile != 'single-seller' && '--no-restore' || '' }} + - name: Start .NET Core Booking Server Reference Implementation + run: | + dotnet run --no-launch-profile --project ./server/Examples/BookingSystem.AspNetCore/BookingSystem.AspNetCore.csproj --configuration Release --no-build & + env: + ASPNETCORE_ENVIRONMENT: ${{ matrix.profile }} + + - name: Setup tmate session + uses: mxschmitt/action-tmate@v3 + if: ${{ success() || failure() }} + + + - name: Run OpenActive Test Suite + uses: openactive/openactive-test-suite@master + with: + NODE_CONFIG: | + {"ci": false, "broker": {"outputPath": "/github/workspace/output/", "datasetSiteUrl": "https://refimpl-api:5001/openactive"}, "integrationTests": { "outputPath": "/github/workspace/output/", "conformanceCertificatePath": "/github/workspace/conformance/examples/${{ matrix.profile }}/${{ matrix.mode }}/", "useRandomOpportunities": ${{ matrix.mode == 'random' }}, "conformanceCertificateId": "https://certificates.reference-implementation.openactive.io/examples/${{ matrix.profile }}/${{ matrix.mode }}/" }} + NODE_ENV: .example.${{ matrix.profile }} + NODE_APP_INSTANCE: ci + + - name: Upload test output for ${{ matrix.mode }} mode as artifact + uses: actions/upload-artifact@v4 + if: ${{ success() || failure() }} + with: + name: core.${{ matrix.mode }}.${{ matrix.profile }} + path: ./output/ diff --git a/.github/workflows/docker-test-3.yml b/.github/workflows/docker-test-3.yml new file mode 100644 index 00000000..0b2700d4 --- /dev/null +++ b/.github/workflows/docker-test-3.yml @@ -0,0 +1,52 @@ +name: Test using Docker for CI +on: + push: + branches: [ feature/docker-image ] + +jobs: + docker-test: + runs-on: ubuntu-latest + container: + image: mcr.microsoft.com/dotnet/sdk:3.1 + options: --network-alias booking.system + strategy: + fail-fast: false + matrix: + mode: ['random'] + profile: ['no-auth'] + steps: + - name: Checkout OpenActive.Server.NET + uses: actions/checkout@v2 + with: + path: server + - name: Install OpenActive.Server.NET dependencies + if: ${{ matrix.profile != 'no-auth' && matrix.profile != 'single-seller' }} + run: dotnet restore ./server/ + - name: Build .NET Core Booking Server Reference Implementation + run: dotnet build ./server/Examples/BookingSystem.AspNetCore/BookingSystem.AspNetCore.csproj --configuration Release ${{ matrix.profile != 'no-auth' && matrix.profile != 'single-seller' && '--no-restore' || '' }} + - name: Start .NET Core Booking Server Reference Implementation + run: | + dotnet run --no-launch-profile --project ./server/Examples/BookingSystem.AspNetCore/BookingSystem.AspNetCore.csproj --configuration Release --no-build & + env: + ASPNETCORE_ENVIRONMENT: ${{ matrix.profile }} + ApplicationHostBaseUrl: http://booking.system:5000 + Urls: 'http://*:5000' + ASPNETCORE_URLS: 'http://*:5000' + + - name: Create output dir + run: mkdir -p ./output/ + + - name: Run OpenActive Test Suite + uses: openactive/openactive-test-suite@master + with: + NODE_CONFIG: | + {"ci": true, "broker": {"outputPath": "/github/workspace/output/", "datasetSiteUrl": "http://booking.system:5000/openactive"}, "integrationTests": { "outputPath": "/github/workspace/output/", "conformanceCertificatePath": "/github/workspace/conformance/examples/${{ matrix.profile }}/${{ matrix.mode }}/", "useRandomOpportunities": ${{ matrix.mode == 'random' }}, "conformanceCertificateId": "https://certificates.reference-implementation.openactive.io/examples/${{ matrix.profile }}/${{ matrix.mode }}/" }} + NODE_ENV: .example.${{ matrix.profile }} + NODE_APP_INSTANCE: ci + + - name: Upload test output for ${{ matrix.mode }} mode as artifact + uses: actions/upload-artifact@v4 + if: ${{ success() || failure() }} + with: + name: core.${{ matrix.mode }}.${{ matrix.profile }} + path: ./output/ diff --git a/.github/workflows/docker-test-4.yml b/.github/workflows/docker-test-4.yml new file mode 100644 index 00000000..b9c1580e --- /dev/null +++ b/.github/workflows/docker-test-4.yml @@ -0,0 +1,53 @@ +name: Test using Docker for CI +on: + push: + branches: [ feature/docker-image ] + +jobs: + docker-test: + runs-on: ubuntu-latest + strategy: + fail-fast: false + matrix: + mode: ['random'] + profile: ['no-auth'] + steps: + - name: Setup .NET Core 3.1.419 + uses: actions/setup-dotnet@v1 + with: + dotnet-version: 3.1.419 + - name: Checkout OpenActive.Server.NET + uses: actions/checkout@v2 + with: + path: server + - name: Install OpenActive.Server.NET dependencies + if: ${{ matrix.profile != 'no-auth' && matrix.profile != 'single-seller' }} + run: dotnet restore ./server/ + - name: Build .NET Core Booking Server Reference Implementation + run: dotnet build ./server/Examples/BookingSystem.AspNetCore/BookingSystem.AspNetCore.csproj --configuration Release ${{ matrix.profile != 'no-auth' && matrix.profile != 'single-seller' && '--no-restore' || '' }} + - name: Start .NET Core Booking Server Reference Implementation + run: | + dotnet run --no-launch-profile --project ./server/Examples/BookingSystem.AspNetCore/BookingSystem.AspNetCore.csproj --configuration Release --no-build & + env: + ASPNETCORE_ENVIRONMENT: ${{ matrix.profile }} + ApplicationHostBaseUrl: http://172.17.0.1:5000 + Urls: 'http://*:5000' + ASPNETCORE_URLS: 'http://*:5000' + + - name: Create output dir + run: mkdir -p ./output/ + + - name: Run OpenActive Test Suite + uses: openactive/openactive-test-suite@master + with: + NODE_CONFIG: | + {"ci": true, "broker": {"outputPath": "/github/workspace/output/", "datasetSiteUrl": "http://172.17.0.1:5000/openactive"}, "integrationTests": { "outputPath": "/github/workspace/output/", "conformanceCertificatePath": "/github/workspace/conformance/examples/${{ matrix.profile }}/${{ matrix.mode }}/", "useRandomOpportunities": ${{ matrix.mode == 'random' }}, "conformanceCertificateId": "https://certificates.reference-implementation.openactive.io/examples/${{ matrix.profile }}/${{ matrix.mode }}/" }} + NODE_ENV: .example.${{ matrix.profile }} + NODE_APP_INSTANCE: ci + + - name: Upload test output for ${{ matrix.mode }} mode as artifact + uses: actions/upload-artifact@v4 + if: ${{ success() || failure() }} + with: + name: core.${{ matrix.mode }}.${{ matrix.profile }} + path: ./output/ diff --git a/.github/workflows/docker-test-5.yml b/.github/workflows/docker-test-5.yml new file mode 100644 index 00000000..c1d73908 --- /dev/null +++ b/.github/workflows/docker-test-5.yml @@ -0,0 +1,53 @@ +name: Test using Docker for CI +on: + push: + branches: [ feature/docker-image ] + +jobs: + docker-test: + runs-on: ubuntu-latest + strategy: + fail-fast: false + matrix: + mode: ['random'] + profile: ['no-auth'] + steps: + - name: Setup .NET Core 3.1.419 + uses: actions/setup-dotnet@v1 + with: + dotnet-version: 3.1.419 + - name: Checkout OpenActive.Server.NET + uses: actions/checkout@v2 + with: + path: server + - name: Install OpenActive.Server.NET dependencies + if: ${{ matrix.profile != 'no-auth' && matrix.profile != 'single-seller' }} + run: dotnet restore ./server/ + - name: Build .NET Core Booking Server Reference Implementation + run: dotnet build ./server/Examples/BookingSystem.AspNetCore/BookingSystem.AspNetCore.csproj --configuration Release ${{ matrix.profile != 'no-auth' && matrix.profile != 'single-seller' && '--no-restore' || '' }} + - name: Start .NET Core Booking Server Reference Implementation + run: | + dotnet run --no-launch-profile --project ./server/Examples/BookingSystem.AspNetCore/BookingSystem.AspNetCore.csproj --configuration Release --no-build & + env: + ASPNETCORE_ENVIRONMENT: ${{ matrix.profile }} + ApplicationHostBaseUrl: http://host.docker.internal:5000 + Urls: 'http://*:5000' + ASPNETCORE_URLS: 'http://*:5000' + + - name: Create output dir + run: mkdir -p ./output/json + + - name: Run OpenActive Test Suite + uses: openactive/openactive-test-suite@master + with: + NODE_CONFIG: | + {"ci": true, "broker": {"outputPath": "/github/workspace/output/", "datasetSiteUrl": "http://host.docker.internal:5000/openactive"}, "integrationTests": { "outputPath": "/github/workspace/output/", "conformanceCertificatePath": "/github/workspace/conformance/examples/${{ matrix.profile }}/${{ matrix.mode }}/", "useRandomOpportunities": ${{ matrix.mode == 'random' }}, "conformanceCertificateId": "https://certificates.reference-implementation.openactive.io/examples/${{ matrix.profile }}/${{ matrix.mode }}/" }} + NODE_ENV: .example.${{ matrix.profile }} + NODE_APP_INSTANCE: ci + + - name: Upload test output for ${{ matrix.mode }} mode as artifact + uses: actions/upload-artifact@v4 + if: ${{ success() || failure() }} + with: + name: core.${{ matrix.mode }}.${{ matrix.profile }} + path: ./output/ diff --git a/.github/workflows/docker-test.yaml b/.github/workflows/docker-test.yaml new file mode 100644 index 00000000..b8f16671 --- /dev/null +++ b/.github/workflows/docker-test.yaml @@ -0,0 +1,65 @@ +name: Docker Image Integration Test + +on: + registry_package: + types: [ published ] + push: + branches: [ feature/docker-image-null ] + +jobs: + tests: + # Only run after 'reference.bookingsystem' is published + # if: ${{ github.event.package.name == 'reference.bookingsystem' }} + runs-on: ubuntu-latest + container: node:14.17.0 + + services: + # Label used to access the service container + reference.bookingsystem: + # Docker Hub image + image: ghcr.io/openactive/reference.bookingsystem:latest # ${{ github.event.package.package_version.version }} + # Config for postgres + env: + ASPNETCORE_ENVIRONMENT: all-features + ApplicationHostBaseUrl: http://reference.bookingsystem + OpenIdIssuerUrl: http://reference.bookingsystem.identity + # Set health checks to wait until postgres has started + options: >- + --health-cmd "curl -f http://localhost/OpenActive" + --health-interval 10s + --health-timeout 5s + --health-retries 5 + ports: + - 80:80 + + # Label used to access the service container + reference.bookingsystem.identity: + # Docker Hub image + image: ghcr.io/openactive/reference.bookingsystem.identity:latest # ${{ github.event.package.package_version.version }} + # Config for postgres + env: + ASPNETCORE_ENVIRONMENT: all-features + ApplicationHostBaseUrl: http://reference.bookingsystem.identity + Urls: '' + ASPNETCORE_URLS: '' + # Set health checks to wait until postgres has started + options: >- + --health-cmd "curl -f http://localhost/.well-known/openid-configuration" + --health-interval 10s + --health-timeout 5s + --health-retries 5 + + steps: + - name: Run OpenActive Test Suite + uses: openactive/openactive-test-suite@master + with: + NODE_CONFIG: | + {"broker": {"outputPath": "/github/workspace/output/", "datasetSiteUrl": "http://reference.bookingsystem/openactive"}, "integrationTests": { "outputPath": "/github/workspace/output/", "useRandomOpportunities": true }, "sellers": {"primary": { "@id": "http://reference.bookingsystem/api/identifiers/sellers/1","authentication": {"requestHeaders": {"X-OpenActive-Test-Seller-Id": "http://reference.bookingsystem/api/identifiers/sellers/1"}}},"secondary": { "@id": "http://reference.bookingsystem/api/identifiers/sellers/2","authentication": {"requestHeaders": {"X-OpenActive-Test-Seller-Id": "http://reference.bookingsystem/api/identifiers/sellers/2"}}}}} + NODE_ENV: .example.all-features + NODE_APP_INSTANCE: ci + - name: Upload test output as artifact + uses: actions/upload-artifact@v4 + if: ${{ success() || failure() }} + with: + name: docker-test + path: ./output/ diff --git a/.github/workflows/openactive-test-suite.yml b/.github/workflows/openactive-test-suite.yml index b8d20c3b..26458816 100644 --- a/.github/workflows/openactive-test-suite.yml +++ b/.github/workflows/openactive-test-suite.yml @@ -1,9 +1,9 @@ name: Ref Impl on: push: - branches: [ master ] + branches: [ master-null ] pull_request: - branches: [ master ] + branches: [ master-null ] jobs: test-server: @@ -256,6 +256,8 @@ jobs: This release contains minor amendments based on updates to the [OpenActive Vocabulary](https://openactive.io/ns/) (codified by the [Data Models](https://github.com/openactive/data-models)), and the latest version of the [Dataset Site Template](https://github.com/openactive/dataset-site-template). Published to Nuget: [OpenActive.Server.NET](https://www.nuget.org/packages/OpenActive.Server.NET/${{ steps.nbgv.outputs.SimpleVersion }}) and [OpenActive.FakeDatabase.NET](https://www.nuget.org/packages/OpenActive.FakeDatabase.NET/${{ steps.nbgv.outputs.SimpleVersion }}). + + Published to GitHub Container Registry: [reference.bookingsystem](https://github.com/openactive/OpenActive.Server.NET/pkgs/container/reference.bookingsystem) and [reference.bookingsystem.identity](https://github.com/openactive/OpenActive.Server.NET/pkgs/container/reference.bookingsystem.identity) draft: false prerelease: false @@ -291,3 +293,77 @@ jobs: - name: Push to Nuget if: "! contains(toJSON(github.event.commits.*.message), '[no-release]')" run: dotnet nuget push "./Fakes/OpenActive.FakeDatabase.NET/**/*.nupkg" -k ${{secrets.NUGET_API_KEY}} --skip-duplicate -s https://api.nuget.org/v3/index.json + + build-and-push-docker-image: + # Publish to GitHub Container Registry + # Master branch only + # if: ${{ github.ref == 'refs/heads/master' }} + # needs: + # - core + # - framework + runs-on: ubuntu-latest + permissions: + contents: read + packages: write + env: + REGISTRY: ghcr.io + # IMAGE_NAME: ${{ github.repository }} + steps: + - name: Checkout + uses: actions/checkout@v3 + with: + fetch-depth: 0 # avoid shallow clone so nbgv can do its work. + - name: Install Nerdbank.GitVersioning + run: cp Directory.Build.props.template Directory.Build.props + - name: Get current version + uses: dotnet/nbgv@master + id: nbgv + + - name: Log in to the Container registry + uses: docker/login-action@v2 + with: + registry: ${{ env.REGISTRY }} + username: ${{ github.actor }} + password: ${{ secrets.GITHUB_TOKEN }} + + - name: Extract metadata (tags, labels) for Booking System + id: meta-booking + uses: docker/metadata-action@v4 + with: + images: ${{ env.REGISTRY }}/OpenActive/Reference.BookingSystem + labels: | + org.opencontainers.image.title=OpenActive Reference Implementation - Booking System + org.opencontainers.image.description=Reference Implementation for OpenActive data publishing and Open Booking API implementation + org.opencontainers.image.vendor=OpenActive + tags: | + type=semver,pattern={{version}},value=v${{ steps.nbgv.outputs.SimpleVersion }} + + - name: Extract metadata (tags, labels) for Identity Server + id: meta-id + uses: docker/metadata-action@v4 + with: + images: ${{ env.REGISTRY }}/OpenActive/Reference.BookingSystem.Identity + labels: | + org.opencontainers.image.title=OpenActive Reference Implementation - Identity Server + org.opencontainers.image.description=Reference Implementation for OpenID Connect implementation for OpenActive + org.opencontainers.image.vendor=OpenActive + tags: | + type=semver,pattern={{version}},value=v${{ steps.nbgv.outputs.SimpleVersion }} + + - name: Build and push Docker image for Booking System + uses: docker/build-push-action@v4 + with: + context: . + push: true + tags: ${{ steps.meta-booking.outputs.tags }} + labels: ${{ steps.meta-booking.outputs.labels }} + target: booking-server + + - name: Build and push Docker image for Identity Server + uses: docker/build-push-action@v4 + with: + context: . + push: true + tags: ${{ steps.meta-id.outputs.tags }} + labels: ${{ steps.meta-id.outputs.labels }} + target: identity-server diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 00000000..86705341 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,41 @@ +# https://hub.docker.com/_/microsoft-dotnet +FROM mcr.microsoft.com/dotnet/sdk:3.1 AS build +WORKDIR /source + +# Copy csproj and restore as distinct layers +COPY *.sln . +COPY Examples/BookingSystem.AspNetCore.IdentityServer/BookingSystem.AspNetCore.IdentityServer.csproj ./Examples/BookingSystem.AspNetCore.IdentityServer/ +COPY Examples/BookingSystem.AspNetCore/BookingSystem.AspNetCore.csproj ./Examples/BookingSystem.AspNetCore/ +COPY Fakes/OpenActive.FakeDatabase.NET/OpenActive.FakeDatabase.NET.csproj ./Fakes/OpenActive.FakeDatabase.NET/ +COPY Fakes/OpenActive.FakeDatabase.NET.Tests/OpenActive.FakeDatabase.NET.Tests.csproj ./Fakes/OpenActive.FakeDatabase.NET.Tests/ +COPY OpenActive.Server.NET/OpenActive.Server.NET.csproj ./OpenActive.Server.NET/ +COPY OpenActive.Server.NET.Tests/OpenActive.Server.NET.Tests.csproj ./OpenActive.Server.NET.Tests/ +COPY Examples/BookingSystem.AspNetFramework/BookingSystem.AspNetFramework.csproj ./Examples/BookingSystem.AspNetFramework/ +COPY Examples/BookingSystem.AspNetFramework.Tests/BookingSystem.AspNetFramework.Tests.csproj ./Examples/BookingSystem.AspNetFramework.Tests/ +RUN dotnet restore + +# Copy everything else +COPY Examples/. ./Examples/ +COPY /Fakes/OpenActive.FakeDatabase.NET/. ./Fakes/OpenActive.FakeDatabase.NET/ +COPY /OpenActive.Server.NET/. ./OpenActive.Server.NET/ + +# Build .NET Core Authentication Authority Reference Implementation +WORKDIR /source/Examples/BookingSystem.AspNetCore.IdentityServer +RUN dotnet publish -c release -o /app-id --no-restore + +# Build .NET Core Booking Server Reference Implementation +WORKDIR /source/Examples/BookingSystem.AspNetCore +RUN dotnet publish -c release -o /app --no-restore + +# target for identity-server +# See https://learn.microsoft.com/en-us/aspnet/core/security/docker-https to run +FROM mcr.microsoft.com/dotnet/aspnet:3.1 AS identity-server +WORKDIR /app-id +COPY --from=build /app-id ./ +ENTRYPOINT ["dotnet", "BookingSystem.AspNetCore.IdentityServer.dll"] + +# default target; for booking-server +FROM mcr.microsoft.com/dotnet/aspnet:3.1 AS booking-server +WORKDIR /app +COPY --from=build /app ./ +ENTRYPOINT ["dotnet", "BookingSystem.AspNetCore.dll"] \ No newline at end of file diff --git a/README.md b/README.md index 2f65f5dc..5d448e1a 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,5 @@  -# OpenActive.Server.NET [![Nuget](https://img.shields.io/nuget/v/OpenActive.Server.NET.svg)](https://www.nuget.org/packages/OpenActive.Server.NET/) [![OpenActive.Server.NET.Test](https://github.com/openactive/OpenActive.Server.NET/workflows/OpenActive.Server.NET.Tests/badge.svg?branch=master)](https://github.com/openactive/OpenActive.Server.NET/actions?query=workflow%3AOpenActive.Server.NET.Tests) +# OpenActive.Server.NET [![Nuget](https://img.shields.io/nuget/v/OpenActive.Server.NET.svg)](https://www.nuget.org/packages/OpenActive.Server.NET/) The Open Booking SDK for .NET provides components that aid the implementation of the OpenActive specifications, including the [Open Booking API](https://openactive.io/open-booking-api/EditorsDraft/). @@ -7,10 +7,24 @@ A readme is available within the [`OpenActive.Server.NET`](https://github.com/op Further documentation, including a step-by-step tutorial, can be found at https://tutorials.openactive.io/open-booking-sdk/. -# OpenActive Reference Implementation [![OpenActive Test Suite](https://github.com/openactive/OpenActive.Server.NET/workflows/OpenActive%20Reference%20Implementation/badge.svg?branch=master)](https://certificates.reference-implementation.openactive.io/examples/all-features/controlled/) +# OpenActive Reference Implementation [![OpenActive Reference Implementation](https://github.com/openactive/OpenActive.Server.NET/actions/workflows/openactive-test-suite.yml/badge.svg?branch=master))](https://certificates.reference-implementation.openactive.io/examples/all-features/controlled/) [`BookingSystem.AspNetCore`](https://github.com/openactive/OpenActive.Server.NET/tree/master/Examples/BookingSystem.AspNetCore) provides an example use of the OpenActive.Server.NET library, as a fully standards compliant reference implementation of the OpenActive specifications, including the Open Booking API. This is designed to have its code copied-and-pasted to provide a quick working starting point for any implementation. +## Docker + +Docker can be used to run the reference implementation locally or within a CI environment: + +``` +docker run -it --rm -p 5000:80 --name openactive_refimpl -e ASPNETCORE_ENVIRONMENT=no-auth ghcr.io/openactive/reference.bookingsystem:0.14.12 +``` + +Then visit `http://localhost:5000/OpenActive`. + +See https://learn.microsoft.com/en-us/aspnet/core/security/docker-https to run `https://localhost:5001/OpenActive`. + + # OpenActive.FakeDatabase.NET [![Nuget](https://img.shields.io/nuget/v/OpenActive.FakeDatabase.NET.svg)](https://www.nuget.org/packages/OpenActive.FakeDatabase.NET/) [![OpenActive.FakeDatabase.NET.Tests](https://github.com/openactive/OpenActive.Server.NET/workflows/OpenActive.FakeDatabase.NET.Tests/badge.svg?branch=master)](https://github.com/openactive/OpenActive.Server.NET/actions?query=workflow%3AOpenActive.FakeDatabase.NET.Tests) [`OpenActive.FakeDatabase.NET`](https://github.com/openactive/OpenActive.Server.NET/tree/master/Fakes/OpenActive.FakeDatabase.NET) is an in-memory database that is used by BookingSystem.AspNetCore for illustration purposes. It can be added as a dependency to your project during the initial stages of implementation, to get a conformant test implementation as a starting position. +