From 8b1fe99ac5ed84881bb3ac5faaf16eb834f19a4f Mon Sep 17 00:00:00 2001 From: Oskar Dudycz Date: Tue, 15 Aug 2023 13:52:43 +0200 Subject: [PATCH] Upgraded api tests to breaking changes in Ogooreck --- Core.Testing/Core.Testing.csproj | 2 +- EventSourcing.NetCore.sln | 6 + .../AddingProduct/AddProductTests.cs | 60 +++------ .../Canceling/CancelShoppingCartTests.cs | 74 ++++------ .../Confirming/ConfirmShoppingCartTests.cs | 74 +++------- .../Opening/OpenShoppingCartTests.cs | 42 +++--- .../RemovingProduct/RemoveProductTests.cs | 83 ++++++------ .../ShoppingCarts/ShoppingCartsApi.cs | 19 +++ .../InitializingOrder/InitializeOrderTests.cs | 5 +- .../RequestingPayment/RequestPaymentsTests.cs | 9 +- .../Packages/SendPackageTests.cs | 5 +- .../AddingProduct/AddProductTests.cs | 55 +++----- .../Canceling/CancelShoppingCartTests.cs | 60 +++------ .../Confirming/ConfirmShoppingCartTests.cs | 23 ++-- .../Opening/OpenShoppingCartTests.cs | 21 ++- .../RemovingProduct/RemoveProductTests.cs | 66 +++++---- .../ShoppingCarts/ShoppingCartsApi.cs | 19 +++ .../AddingProduct/AddProductTests.cs | 48 ++----- .../Canceling/CancelShoppingCartTests.cs | 62 +++------ .../Confirming/ConfirmShoppingCartTests.cs | 23 ++-- .../Opening/OpenShoppingCartTests.cs | 13 +- .../RemovingProduct/RemoveProductTests.cs | 57 ++++---- .../ShoppingCarts/ShoppingCartsApi.cs | 19 +++ .../Helpdesk.Api.Tests.csproj | 2 +- .../AcknowledgeResolutionIncidentTests.cs | 19 ++- .../Incidents/AssignAgentTests.cs | 19 +-- .../Incidents/CategoriseIncidentTests.cs | 16 +-- .../Incidents/CloseIncidentTests.cs | 15 +-- .../Incidents/Fixtures/Scenarios.cs | 43 +++--- .../Incidents/LogIncidentsTests.cs | 51 ++++--- .../Incidents/PrioritiseIncidentTests.cs | 9 +- .../RecordAgentResponseToIncidentTests.cs | 9 +- .../RecordCustomerResponseToIncidentTests.cs | 12 +- .../Incidents/ResolveIncidentTests.cs | 18 +-- .../Helpdesk/Helpdesk.Api.Tests/Settings.cs | 2 +- .../HotelManagement.Tests.csproj | 2 +- .../ScheduleMeetingTests.cs | 50 +++---- .../CreatingMeeting/CreateMeetingTests.cs | 13 +- .../CreateTentativeReservationTests.cs | 127 ++++++++---------- .../GetProductDetailsTests.cs | 23 ++-- .../GettingProducts/GetProductsTests.cs | 31 ++--- 41 files changed, 558 insertions(+), 748 deletions(-) create mode 100644 Sample/ECommerce/Carts/Carts.Api.Tests/ShoppingCarts/ShoppingCartsApi.cs create mode 100644 Sample/EventStoreDB/ECommerce/Carts/Carts.Api.Tests/ShoppingCarts/ShoppingCartsApi.cs create mode 100644 Sample/EventStoreDB/Simple/ECommerce.Api.Tests/ShoppingCarts/ShoppingCartsApi.cs diff --git a/Core.Testing/Core.Testing.csproj b/Core.Testing/Core.Testing.csproj index 67dc8b29b..f45bcf9aa 100644 --- a/Core.Testing/Core.Testing.csproj +++ b/Core.Testing/Core.Testing.csproj @@ -16,7 +16,7 @@ - + diff --git a/EventSourcing.NetCore.sln b/EventSourcing.NetCore.sln index edc3edb64..acbd3298a 100644 --- a/EventSourcing.NetCore.sln +++ b/EventSourcing.NetCore.sln @@ -430,6 +430,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Decider", "Sample\decider\D EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Reservations", "Sample\HotelManagement\Reservations\Reservations.csproj", "{92DC3F6A-BB06-4E33-A9C7-8262CC68F93C}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Ogooreck", "..\..\Repos\Ogooreck\src\Ogooreck\Ogooreck.csproj", "{7D39308C-9B20-4F70-99BB-DD3703AE35FC}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -956,6 +958,10 @@ Global {92DC3F6A-BB06-4E33-A9C7-8262CC68F93C}.Debug|Any CPU.Build.0 = Debug|Any CPU {92DC3F6A-BB06-4E33-A9C7-8262CC68F93C}.Release|Any CPU.ActiveCfg = Release|Any CPU {92DC3F6A-BB06-4E33-A9C7-8262CC68F93C}.Release|Any CPU.Build.0 = Release|Any CPU + {7D39308C-9B20-4F70-99BB-DD3703AE35FC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {7D39308C-9B20-4F70-99BB-DD3703AE35FC}.Debug|Any CPU.Build.0 = Debug|Any CPU + {7D39308C-9B20-4F70-99BB-DD3703AE35FC}.Release|Any CPU.ActiveCfg = Release|Any CPU + {7D39308C-9B20-4F70-99BB-DD3703AE35FC}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/Sample/ECommerce/Carts/Carts.Api.Tests/ShoppingCarts/AddingProduct/AddProductTests.cs b/Sample/ECommerce/Carts/Carts.Api.Tests/ShoppingCarts/AddingProduct/AddProductTests.cs index be5aa0477..ee26e027b 100644 --- a/Sample/ECommerce/Carts/Carts.Api.Tests/ShoppingCarts/AddingProduct/AddProductTests.cs +++ b/Sample/ECommerce/Carts/Carts.Api.Tests/ShoppingCarts/AddingProduct/AddProductTests.cs @@ -1,40 +1,20 @@ using Carts.Api.Requests; using Carts.ShoppingCarts; using Carts.ShoppingCarts.GettingCartById; -using Carts.ShoppingCarts.Products; using FluentAssertions; using Ogooreck.API; -using static Ogooreck.API.ApiSpecification; using Xunit; +using static Ogooreck.API.ApiSpecification; namespace Carts.Api.Tests.ShoppingCarts.AddingProduct; -public class AddProductFixture: ApiSpecification, IAsyncLifetime -{ - public Guid ShoppingCartId { get; private set; } - - public readonly Guid ClientId = Guid.NewGuid(); - - public async Task InitializeAsync() - { - var openResponse = await Send( - new ApiRequest(POST, URI("/api/ShoppingCarts"), BODY(new OpenShoppingCartRequest(ClientId))) - ); - - await CREATED(openResponse); - await RESPONSE_LOCATION_HEADER()(openResponse); +using static ShoppingCartsApi; - ShoppingCartId = openResponse.GetCreatedId(); - } - - public Task DisposeAsync() => Task.CompletedTask; -} - -public class AddProductTests: IClassFixture +public class AddProductTests: IClassFixture> { - private readonly AddProductFixture API; + private readonly ApiSpecification API; - public AddProductTests(AddProductFixture api) => API = api; + public AddProductTests(ApiSpecification api) => API = api; [Fact] [Trait("Category", "Acceptance")] @@ -43,26 +23,26 @@ public async Task Post_Should_AddProductItem_To_ShoppingCart() var product = new ProductItemRequest(Guid.NewGuid(), 1); await API - .Given( - URI($"/api/ShoppingCarts/{API.ShoppingCartId}/products"), + .Given("Opened Shopping Cart", OpenShoppingCart()) + .When( + "Add new product", + POST, + URI(ctx => $"/api/ShoppingCarts/{ctx.OpenedShoppingCartId()}/products"), BODY(new AddProductRequest(product)), - HEADERS(IF_MATCH(1)) + HEADERS(IF_MATCH(0)) ) - .When(POST) - .Then(OK); - - await API - .Given(URI($"/api/ShoppingCarts/{API.ShoppingCartId}")) - .When(GET_UNTIL(RESPONSE_ETAG_IS(2))) + .Then(OK) + .And() + .When(GET, URI(ctx => $"/api/ShoppingCarts/{ctx.OpenedShoppingCartId()}")) .Then( - RESPONSE_BODY(details => + RESPONSE_BODY((details, ctx) => { - details.Id.Should().Be(API.ShoppingCartId); + details.Id.Should().Be(ctx.OpenedShoppingCartId()); details.Status.Should().Be(ShoppingCartStatus.Pending); - details.ProductItems.Should().HaveCount(1); - details.ProductItems.Single().ProductItem.Should() - .Be(ProductItem.From(product.ProductId, product.Quantity)); - details.Version.Should().Be(2); + var productItem = details.ProductItems.Single(); + productItem.Quantity.Should().Be(product.Quantity); + productItem.ProductId.Should().Be(product.ProductId!.Value); + details.Version.Should().Be(1); }) ); } diff --git a/Sample/ECommerce/Carts/Carts.Api.Tests/ShoppingCarts/Canceling/CancelShoppingCartTests.cs b/Sample/ECommerce/Carts/Carts.Api.Tests/ShoppingCarts/Canceling/CancelShoppingCartTests.cs index 6b2baafac..42f260163 100644 --- a/Sample/ECommerce/Carts/Carts.Api.Tests/ShoppingCarts/Canceling/CancelShoppingCartTests.cs +++ b/Sample/ECommerce/Carts/Carts.Api.Tests/ShoppingCarts/Canceling/CancelShoppingCartTests.cs @@ -1,71 +1,43 @@ -using Carts.Api.Requests; using Carts.ShoppingCarts; using Carts.ShoppingCarts.GettingCartById; -using Carts.ShoppingCarts.Products; +using FluentAssertions; using Ogooreck.API; using Xunit; using static Ogooreck.API.ApiSpecification; +using static Carts.Api.Tests.ShoppingCarts.ShoppingCartsApi; namespace Carts.Api.Tests.ShoppingCarts.Canceling; -public class CancelShoppingCartFixture: ApiSpecification, IAsyncLifetime +public class CancelShoppingCartTests: IClassFixture> { - public Guid ShoppingCartId { get; private set; } + private readonly ApiSpecification API; + public CancelShoppingCartTests(ApiSpecification api) => API = api; public readonly Guid ClientId = Guid.NewGuid(); - public async Task InitializeAsync() - { - var openResponse = await Send( - new ApiRequest(POST, URI("/api/ShoppingCarts"), BODY(new OpenShoppingCartRequest(ClientId))) - ); - - await CREATED_WITH_DEFAULT_HEADERS(eTag: 1)(openResponse); - - ShoppingCartId = openResponse.GetCreatedId(); - } - - public Task DisposeAsync() - { - Dispose(); - return Task.CompletedTask; - } -} - -public class CancelShoppingCartTests: IClassFixture -{ - private readonly CancelShoppingCartFixture API; - - public CancelShoppingCartTests(CancelShoppingCartFixture api) => API = api; - [Fact] [Trait("Category", "Acceptance")] - public async Task Delete_Should_Return_OK_And_Cancel_Shopping_Cart() - { - await API - .Given( - URI($"/api/ShoppingCarts/{API.ShoppingCartId}"), - HEADERS(IF_MATCH(1)) + public Task Delete_Should_Return_OK_And_Cancel_Shopping_Cart() => + API + .Given("Opened Shopping Cart", OpenShoppingCart(ClientId)) + .When( + "Cancel Shopping Cart", + DELETE, + URI(ctx => $"/api/ShoppingCarts/{ctx.OpenedShoppingCartId()}"), + HEADERS(IF_MATCH(0)) ) - .When(DELETE) - .Then(OK); - - await API - .Given( - URI($"/api/ShoppingCarts/{API.ShoppingCartId}") - ) - .When(GET_UNTIL(RESPONSE_ETAG_IS(2))) + .Then(OK) + .And() + .When(GET, URI(ctx => $"/api/ShoppingCarts/{ctx.OpenedShoppingCartId()}")) + .Until(RESPONSE_ETAG_IS(1)) .Then( OK, - RESPONSE_BODY(new ShoppingCartDetails + RESPONSE_BODY((details, ctx) => { - Id = API.ShoppingCartId, - Status = ShoppingCartStatus.Canceled, - ProductItems = new List(), - ClientId = API.ClientId, - Version = 2, + details.Id.Should().Be(ctx.OpenedShoppingCartId()); + details.Status.Should().Be(ShoppingCartStatus.Canceled); + details.ProductItems.Should().BeEmpty(); + details.ClientId.Should().Be(ClientId); + details.Version.Should().Be(1); })); - - // API.PublishedExternalEventsOfType(); - } } diff --git a/Sample/ECommerce/Carts/Carts.Api.Tests/ShoppingCarts/Confirming/ConfirmShoppingCartTests.cs b/Sample/ECommerce/Carts/Carts.Api.Tests/ShoppingCarts/Confirming/ConfirmShoppingCartTests.cs index b1277c591..80aa8a6b9 100644 --- a/Sample/ECommerce/Carts/Carts.Api.Tests/ShoppingCarts/Confirming/ConfirmShoppingCartTests.cs +++ b/Sample/ECommerce/Carts/Carts.Api.Tests/ShoppingCarts/Confirming/ConfirmShoppingCartTests.cs @@ -1,7 +1,7 @@ using Carts.Api.Requests; using Carts.ShoppingCarts; using Carts.ShoppingCarts.GettingCartById; -using Carts.ShoppingCarts.Products; +using FluentAssertions; using Ogooreck.API; using Xunit; using static Ogooreck.API.ApiSpecification; @@ -14,39 +14,12 @@ public class ConfirmShoppingCartFixture: ApiSpecification, IAsyncLifeti public readonly Guid ClientId = Guid.NewGuid(); - public readonly ProductItemRequest ProductItem = new(Guid.NewGuid(), 1); - - public decimal UnitPrice; - public async Task InitializeAsync() { - var openResponse = await Send( - new ApiRequest(POST, URI("/api/ShoppingCarts"), BODY(new OpenShoppingCartRequest(ClientId))) - ); - - await CREATED_WITH_DEFAULT_HEADERS(eTag: 1)(openResponse); - - ShoppingCartId = openResponse.GetCreatedId(); - - var addResponse = await Send( - new ApiRequest( - POST, - URI($"/api/ShoppingCarts/{ShoppingCartId}/products"), - BODY(new AddProductRequest(ProductItem)), - HEADERS(IF_MATCH(1))) - ); - - await OK(addResponse); - - var getResponse = await Send( - new ApiRequest( - GET_UNTIL(RESPONSE_ETAG_IS(2)), - URI($"/api/ShoppingCarts/{ShoppingCartId}") - ) - ); - - var cartDetails = await getResponse.GetResultFromJson(); - UnitPrice = cartDetails.ProductItems.Single().UnitPrice; + ShoppingCartId = await Given() + .When(POST, URI("/api/ShoppingCarts"), BODY(new OpenShoppingCartRequest(ClientId))) + .Then(CREATED_WITH_DEFAULT_HEADERS(eTag: 0)) + .GetCreatedId(); } public Task DisposeAsync() => Task.CompletedTask; @@ -54,42 +27,39 @@ public async Task InitializeAsync() public class ConfirmShoppingCartTests: IClassFixture { + private readonly ConfirmShoppingCartFixture API; public ConfirmShoppingCartTests(ConfirmShoppingCartFixture api) => API = api; [Fact] [Trait("Category", "Acceptance")] - public async Task Put_Should_Return_OK_And_Confirm_Shopping_Cart() + public async Task Put_Should_Return_OK_And_Cancel_Shopping_Cart() { await API - .Given( + .Given() + .When( + PUT, URI($"/api/ShoppingCarts/{API.ShoppingCartId}/confirmation"), - HEADERS(IF_MATCH(2)) + HEADERS(IF_MATCH(0)) ) - .When(PUT) .Then(OK); await API - .Given( - URI($"/api/ShoppingCarts/{API.ShoppingCartId}") - ) - .When(GET_UNTIL(RESPONSE_ETAG_IS(3))) + .Given() + .When(GET, URI($"/api/ShoppingCarts/{API.ShoppingCartId}")) + .Until(RESPONSE_ETAG_IS(1)) .Then( OK, - RESPONSE_BODY(new ShoppingCartDetails + RESPONSE_BODY(details => { - Id = API.ShoppingCartId, - Status = ShoppingCartStatus.Confirmed, - ClientId = API.ClientId, - ProductItems = new List - { - PricedProductItem.Create( - ProductItem.From(API.ProductItem.ProductId, API.ProductItem.Quantity), - API.UnitPrice - ) - }, - Version = 3, + details.Id.Should().Be(API.ShoppingCartId); + details.Status.Should().Be(ShoppingCartStatus.Confirmed); + details.ProductItems.Should().BeEmpty(); + details.ClientId.Should().Be(API.ClientId); + details.Version.Should().Be(1); })); + + // API.PublishedExternalEventsOfType(); } } diff --git a/Sample/ECommerce/Carts/Carts.Api.Tests/ShoppingCarts/Opening/OpenShoppingCartTests.cs b/Sample/ECommerce/Carts/Carts.Api.Tests/ShoppingCarts/Opening/OpenShoppingCartTests.cs index 92c404b3b..e2a0cfb5a 100644 --- a/Sample/ECommerce/Carts/Carts.Api.Tests/ShoppingCarts/Opening/OpenShoppingCartTests.cs +++ b/Sample/ECommerce/Carts/Carts.Api.Tests/ShoppingCarts/Opening/OpenShoppingCartTests.cs @@ -1,46 +1,44 @@ using Carts.Api.Requests; using Carts.ShoppingCarts; using Carts.ShoppingCarts.GettingCartById; -using Carts.ShoppingCarts.Products; -using Core.Testing; -using Xunit; +using FluentAssertions; using Ogooreck.API; +using Xunit; using static Ogooreck.API.ApiSpecification; namespace Carts.Api.Tests.ShoppingCarts.Opening; -public class OpenShoppingCartTests: IClassFixture> +public class OpenShoppingCartTests: IClassFixture> { + private readonly ApiSpecification API; + [Fact] public Task Post_ShouldReturn_CreatedStatus_With_CartId() => API.Scenario( - API.Given( + API.Given() + .When( + POST, URI("/api/ShoppingCarts/"), BODY(new OpenShoppingCartRequest(ClientId)) ) - .When(POST) - .Then(CREATED_WITH_DEFAULT_HEADERS(eTag: 1)), - + .Then(CREATED_WITH_DEFAULT_HEADERS(eTag: 0)), response => - API.Given( - URI($"/api/ShoppingCarts/{response.GetCreatedId()}") - ) - .When(GET_UNTIL(RESPONSE_ETAG_IS(1))) + API.Given() + .When(GET, URI($"/api/ShoppingCarts/{response.GetCreatedId()}")) + .Until(RESPONSE_ETAG_IS(0)) .Then( OK, - RESPONSE_BODY(new ShoppingCartDetails + RESPONSE_BODY(details => { - Id = response.GetCreatedId(), - Status = ShoppingCartStatus.Pending, - ProductItems = new List(), - ClientId = ClientId, - Version = 1, + details.Id.Should().Be(response.GetCreatedId()); + details.Status.Should().Be(ShoppingCartStatus.Pending); + details.ProductItems.Should().BeEmpty(); + details.ClientId.Should().Be(ClientId); + details.Version.Should().Be(0); })) ); - public OpenShoppingCartTests(TestWebApplicationFactory fixture) => - API = ApiSpecification.Setup(fixture); + public OpenShoppingCartTests(ApiSpecification api) => API = api; - private readonly ApiSpecification API; - private readonly Guid ClientId = Guid.NewGuid(); + public readonly Guid ClientId = Guid.NewGuid(); } diff --git a/Sample/ECommerce/Carts/Carts.Api.Tests/ShoppingCarts/RemovingProduct/RemoveProductTests.cs b/Sample/ECommerce/Carts/Carts.Api.Tests/ShoppingCarts/RemovingProduct/RemoveProductTests.cs index afc0b4c0b..57025e0af 100644 --- a/Sample/ECommerce/Carts/Carts.Api.Tests/ShoppingCarts/RemovingProduct/RemoveProductTests.cs +++ b/Sample/ECommerce/Carts/Carts.Api.Tests/ShoppingCarts/RemovingProduct/RemoveProductTests.cs @@ -3,8 +3,9 @@ using Carts.ShoppingCarts; using Carts.ShoppingCarts.GettingCartById; using Carts.ShoppingCarts.Products; -using Xunit; +using FluentAssertions; using Ogooreck.API; +using Xunit; using static Ogooreck.API.ApiSpecification; namespace Carts.Api.Tests.ShoppingCarts.RemovingProduct; @@ -21,32 +22,24 @@ public class RemoveProductFixture: ApiSpecification, IAsyncLifetime public async Task InitializeAsync() { - var openResponse = await Send( - new ApiRequest(POST, URI("/api/ShoppingCarts"), BODY(new OpenShoppingCartRequest(ClientId))) - ); - - await CREATED_WITH_DEFAULT_HEADERS(eTag: 1)(openResponse); - - ShoppingCartId = openResponse.GetCreatedId(); - - var addResponse = await Send( - new ApiRequest( + var cartDetails = await Given() + .When(POST, URI("/api/ShoppingCarts"), BODY(new OpenShoppingCartRequest(ClientId))) + .Then(CREATED_WITH_DEFAULT_HEADERS(eTag: 0)) + .And() + .When( POST, - URI($"/api/ShoppingCarts/{ShoppingCartId}/products"), + URI(ctx => $"/api/ShoppingCarts/{ctx.GetCreatedId()}/products"), BODY(new AddProductRequest(ProductItem)), - HEADERS(IF_MATCH(1))) - ); - - await OK(addResponse); - - var getResponse = await Send( - new ApiRequest( - GET_UNTIL(RESPONSE_ETAG_IS(2)), - URI($"/api/ShoppingCarts/{ShoppingCartId}") + HEADERS(IF_MATCH(0)) ) - ); - - var cartDetails = await getResponse.GetResultFromJson(); + .Then(OK) + .And() + .When(GET, URI(ctx => $"/api/ShoppingCarts/{ctx.GetCreatedId()}")) + .Until(RESPONSE_ETAG_IS(1)) + .Then(OK) + .GetResponseBody(); + + ShoppingCartId = cartDetails.Id; UnitPrice = cartDetails.ProductItems.Single().UnitPrice; } @@ -64,34 +57,36 @@ public class RemoveProductTests: IClassFixture public async Task Delete_Should_Return_OK_And_Cancel_Shopping_Cart() { await API - .Given( + .Given() + .When( + DELETE, URI( $"/api/ShoppingCarts/{API.ShoppingCartId}/products/{API.ProductItem.ProductId}?quantity={RemovedCount}&unitPrice={API.UnitPrice.ToString(CultureInfo.InvariantCulture)}"), - HEADERS(IF_MATCH(2)) - ) - .When(DELETE) - .Then(NO_CONTENT); - - await API - .Given( - URI($"/api/ShoppingCarts/{API.ShoppingCartId}") + HEADERS(IF_MATCH(1)) ) - .When(GET_UNTIL(RESPONSE_ETAG_IS(3))) + .Then(NO_CONTENT) + .And() + .When(GET, URI($"/api/ShoppingCarts/{API.ShoppingCartId}")) + .Until(RESPONSE_ETAG_IS(2)) .Then( OK, - RESPONSE_BODY(new ShoppingCartDetails + RESPONSE_BODY(details => { - Id = API.ShoppingCartId, - Status = ShoppingCartStatus.Pending, - ClientId = API.ClientId, - ProductItems = new List - { + details.Id.Should().Be(API.ShoppingCartId); + details.Status.Should().Be(ShoppingCartStatus.Pending); + details.ProductItems.Should().HaveCount(1); + var productItem = details.ProductItems.Single(); + productItem.Should().BeEquivalentTo( PricedProductItem.Create( - ProductItem.From(API.ProductItem.ProductId, API.ProductItem.Quantity - RemovedCount), + ProductItem.From + ( + API.ProductItem.ProductId!.Value, + API.ProductItem.Quantity!.Value - RemovedCount + ), API.UnitPrice - ) - }, - Version = 3, + )); + details.ClientId.Should().Be(API.ClientId); + details.Version.Should().Be(2); })); } diff --git a/Sample/ECommerce/Carts/Carts.Api.Tests/ShoppingCarts/ShoppingCartsApi.cs b/Sample/ECommerce/Carts/Carts.Api.Tests/ShoppingCarts/ShoppingCartsApi.cs new file mode 100644 index 000000000..56c927656 --- /dev/null +++ b/Sample/ECommerce/Carts/Carts.Api.Tests/ShoppingCarts/ShoppingCartsApi.cs @@ -0,0 +1,19 @@ +using Carts.Api.Requests; +using Ogooreck.API; +using static Ogooreck.API.ApiSpecification; + +namespace Carts.Api.Tests.ShoppingCarts; + +public static class ShoppingCartsApi +{ + public static RequestDefinition OpenShoppingCart(Guid? clientId = null) => + SEND( + "Open ShoppingCart", + POST, + URI("/api/ShoppingCarts"), + BODY(new OpenShoppingCartRequest(clientId ?? Guid.NewGuid())) + ); + + public static Guid OpenedShoppingCartId(this TestContext ctx) => + ctx.GetCreatedId(); +} diff --git a/Sample/ECommerce/Orders/Orders.Api.Tests/Orders/InitializingOrder/InitializeOrderTests.cs b/Sample/ECommerce/Orders/Orders.Api.Tests/Orders/InitializingOrder/InitializeOrderTests.cs index 69110b10a..d862a6d1d 100644 --- a/Sample/ECommerce/Orders/Orders.Api.Tests/Orders/InitializingOrder/InitializeOrderTests.cs +++ b/Sample/ECommerce/Orders/Orders.Api.Tests/Orders/InitializingOrder/InitializeOrderTests.cs @@ -20,7 +20,9 @@ public InitializeOrderTests(TestWebApplicationFactory fixture) [Fact] [Trait("Category", "Acceptance")] public Task InitializeOrder_ShouldReturn_CreatedStatus_With_OrderId() => - API.Given( + API.Given() + .When( + POST, URI("/api/Orders/"), BODY(new InitOrderRequest( ClientId, @@ -28,7 +30,6 @@ public InitializeOrderTests(TestWebApplicationFactory fixture) TotalPrice )) ) - .When(POST) .Then(CREATED_WITH_DEFAULT_HEADERS(eTag: 1)); private readonly Guid ClientId = Guid.NewGuid(); diff --git a/Sample/ECommerce/Payments/Payments.Api.Tests/Payments/RequestingPayment/RequestPaymentsTests.cs b/Sample/ECommerce/Payments/Payments.Api.Tests/Payments/RequestingPayment/RequestPaymentsTests.cs index bd5069129..15272b48c 100644 --- a/Sample/ECommerce/Payments/Payments.Api.Tests/Payments/RequestingPayment/RequestPaymentsTests.cs +++ b/Sample/ECommerce/Payments/Payments.Api.Tests/Payments/RequestingPayment/RequestPaymentsTests.cs @@ -19,12 +19,13 @@ public RequestPaymentsTests(TestWebApplicationFactory fixture) [Fact] [Trait("Category", "Acceptance")] - public Task RequestPayment_ShouldReturn_CreatedStatus_With_PaymentId() => - API.Given( + public Task RequestPayment_ShouldReturn_CreatedStatus_With_PaymentId() => + API.Given() + .When( + POST, URI("/api/Payments/"), - BODY(new RequestPaymentRequest {OrderId = OrderId, Amount = Amount}) + BODY(new RequestPaymentRequest { OrderId = OrderId, Amount = Amount }) ) - .When(POST) .Then(CREATED_WITH_DEFAULT_HEADERS(eTag: 1)); private readonly Guid OrderId = Guid.NewGuid(); diff --git a/Sample/ECommerce/Shipments/Shipments.Api.Tests/Packages/SendPackageTests.cs b/Sample/ECommerce/Shipments/Shipments.Api.Tests/Packages/SendPackageTests.cs index 93a852b21..0c25e7128 100644 --- a/Sample/ECommerce/Shipments/Shipments.Api.Tests/Packages/SendPackageTests.cs +++ b/Sample/ECommerce/Shipments/Shipments.Api.Tests/Packages/SendPackageTests.cs @@ -22,11 +22,12 @@ public SendPackageTests(TestWebApplicationFactory fixture) [Fact] [Trait("Category", "Acceptance")] public Task SendPackage_ShouldReturn_CreatedStatus_With_PackageId() => - API.Given( + API.Given() + .When( + POST, URI("/api/Shipments/"), BODY(new SendPackage(OrderId, ProductItems)) ) - .When(POST) .Then(CREATED_WITH_DEFAULT_HEADERS()) .And(response => fixture.ShouldPublishInternalEventOfType( @event => diff --git a/Sample/EventStoreDB/ECommerce/Carts/Carts.Api.Tests/ShoppingCarts/AddingProduct/AddProductTests.cs b/Sample/EventStoreDB/ECommerce/Carts/Carts.Api.Tests/ShoppingCarts/AddingProduct/AddProductTests.cs index b210ee418..ee26e027b 100644 --- a/Sample/EventStoreDB/ECommerce/Carts/Carts.Api.Tests/ShoppingCarts/AddingProduct/AddProductTests.cs +++ b/Sample/EventStoreDB/ECommerce/Carts/Carts.Api.Tests/ShoppingCarts/AddingProduct/AddProductTests.cs @@ -1,39 +1,20 @@ using Carts.Api.Requests; using Carts.ShoppingCarts; using Carts.ShoppingCarts.GettingCartById; -using Carts.ShoppingCarts.Products; using FluentAssertions; using Ogooreck.API; -using static Ogooreck.API.ApiSpecification; using Xunit; +using static Ogooreck.API.ApiSpecification; namespace Carts.Api.Tests.ShoppingCarts.AddingProduct; -public class AddProductFixture: ApiSpecification, IAsyncLifetime -{ - public Guid ShoppingCartId { get; private set; } - - public readonly Guid ClientId = Guid.NewGuid(); - - public async Task InitializeAsync() - { - var openResponse = await Send( - new ApiRequest(POST, URI("/api/ShoppingCarts"), BODY(new OpenShoppingCartRequest(ClientId))) - ); - - await CREATED_WITH_DEFAULT_HEADERS(eTag: 0)(openResponse); +using static ShoppingCartsApi; - ShoppingCartId = openResponse.GetCreatedId(); - } - - public Task DisposeAsync() => Task.CompletedTask; -} - -public class AddProductTests: IClassFixture +public class AddProductTests: IClassFixture> { - private readonly AddProductFixture API; + private readonly ApiSpecification API; - public AddProductTests(AddProductFixture api) => API = api; + public AddProductTests(ApiSpecification api) => API = api; [Fact] [Trait("Category", "Acceptance")] @@ -42,25 +23,25 @@ public async Task Post_Should_AddProductItem_To_ShoppingCart() var product = new ProductItemRequest(Guid.NewGuid(), 1); await API - .Given( - URI($"/api/ShoppingCarts/{API.ShoppingCartId}/products"), + .Given("Opened Shopping Cart", OpenShoppingCart()) + .When( + "Add new product", + POST, + URI(ctx => $"/api/ShoppingCarts/{ctx.OpenedShoppingCartId()}/products"), BODY(new AddProductRequest(product)), HEADERS(IF_MATCH(0)) ) - .When(POST) - .Then(OK); - - await API - .Given(URI($"/api/ShoppingCarts/{API.ShoppingCartId}")) - .When(GET_UNTIL(RESPONSE_ETAG_IS(1))) + .Then(OK) + .And() + .When(GET, URI(ctx => $"/api/ShoppingCarts/{ctx.OpenedShoppingCartId()}")) .Then( - RESPONSE_BODY(details => + RESPONSE_BODY((details, ctx) => { - details.Id.Should().Be(API.ShoppingCartId); + details.Id.Should().Be(ctx.OpenedShoppingCartId()); details.Status.Should().Be(ShoppingCartStatus.Pending); - details.ProductItems.Should().HaveCount(1); - details.ProductItems.Single().ProductItem.Should() - .Be(ProductItem.From(product.ProductId, product.Quantity)); + var productItem = details.ProductItems.Single(); + productItem.Quantity.Should().Be(product.Quantity); + productItem.ProductId.Should().Be(product.ProductId!.Value); details.Version.Should().Be(1); }) ); diff --git a/Sample/EventStoreDB/ECommerce/Carts/Carts.Api.Tests/ShoppingCarts/Canceling/CancelShoppingCartTests.cs b/Sample/EventStoreDB/ECommerce/Carts/Carts.Api.Tests/ShoppingCarts/Canceling/CancelShoppingCartTests.cs index 521901cb5..42f260163 100644 --- a/Sample/EventStoreDB/ECommerce/Carts/Carts.Api.Tests/ShoppingCarts/Canceling/CancelShoppingCartTests.cs +++ b/Sample/EventStoreDB/ECommerce/Carts/Carts.Api.Tests/ShoppingCarts/Canceling/CancelShoppingCartTests.cs @@ -1,67 +1,43 @@ -using Carts.Api.Requests; using Carts.ShoppingCarts; using Carts.ShoppingCarts.GettingCartById; using FluentAssertions; using Ogooreck.API; using Xunit; using static Ogooreck.API.ApiSpecification; +using static Carts.Api.Tests.ShoppingCarts.ShoppingCartsApi; namespace Carts.Api.Tests.ShoppingCarts.Canceling; -public class CancelShoppingCartFixture: ApiSpecification, IAsyncLifetime +public class CancelShoppingCartTests: IClassFixture> { - public Guid ShoppingCartId { get; private set; } + private readonly ApiSpecification API; + public CancelShoppingCartTests(ApiSpecification api) => API = api; public readonly Guid ClientId = Guid.NewGuid(); - public async Task InitializeAsync() - { - var openResponse = await Send( - new ApiRequest(POST, URI("/api/ShoppingCarts"), BODY(new OpenShoppingCartRequest(ClientId))) - ); - - await CREATED_WITH_DEFAULT_HEADERS(eTag: 0)(openResponse); - - ShoppingCartId = openResponse.GetCreatedId(); - } - - public Task DisposeAsync() => Task.CompletedTask; -} - -public class CancelShoppingCartTests: IClassFixture -{ - private readonly CancelShoppingCartFixture API; - - public CancelShoppingCartTests(CancelShoppingCartFixture api) => API = api; - [Fact] [Trait("Category", "Acceptance")] - public async Task Delete_Should_Return_OK_And_Cancel_Shopping_Cart() - { - await API - .Given( - URI($"/api/ShoppingCarts/{API.ShoppingCartId}"), + public Task Delete_Should_Return_OK_And_Cancel_Shopping_Cart() => + API + .Given("Opened Shopping Cart", OpenShoppingCart(ClientId)) + .When( + "Cancel Shopping Cart", + DELETE, + URI(ctx => $"/api/ShoppingCarts/{ctx.OpenedShoppingCartId()}"), HEADERS(IF_MATCH(0)) ) - .When(DELETE) - .Then(OK); - - await API - .Given( - URI($"/api/ShoppingCarts/{API.ShoppingCartId}") - ) - .When(GET_UNTIL(RESPONSE_ETAG_IS(1))) + .Then(OK) + .And() + .When(GET, URI(ctx => $"/api/ShoppingCarts/{ctx.OpenedShoppingCartId()}")) + .Until(RESPONSE_ETAG_IS(1)) .Then( OK, - RESPONSE_BODY(details => + RESPONSE_BODY((details, ctx) => { - details.Id.Should().Be(API.ShoppingCartId); + details.Id.Should().Be(ctx.OpenedShoppingCartId()); details.Status.Should().Be(ShoppingCartStatus.Canceled); details.ProductItems.Should().BeEmpty(); - details.ClientId.Should().Be(API.ClientId); + details.ClientId.Should().Be(ClientId); details.Version.Should().Be(1); })); - - // API.PublishedExternalEventsOfType(); - } } diff --git a/Sample/EventStoreDB/ECommerce/Carts/Carts.Api.Tests/ShoppingCarts/Confirming/ConfirmShoppingCartTests.cs b/Sample/EventStoreDB/ECommerce/Carts/Carts.Api.Tests/ShoppingCarts/Confirming/ConfirmShoppingCartTests.cs index 33659c537..80aa8a6b9 100644 --- a/Sample/EventStoreDB/ECommerce/Carts/Carts.Api.Tests/ShoppingCarts/Confirming/ConfirmShoppingCartTests.cs +++ b/Sample/EventStoreDB/ECommerce/Carts/Carts.Api.Tests/ShoppingCarts/Confirming/ConfirmShoppingCartTests.cs @@ -16,13 +16,10 @@ public class ConfirmShoppingCartFixture: ApiSpecification, IAsyncLifeti public async Task InitializeAsync() { - var openResponse = await Send( - new ApiRequest(POST, URI("/api/ShoppingCarts"), BODY(new OpenShoppingCartRequest(ClientId))) - ); - - await CREATED_WITH_DEFAULT_HEADERS(eTag: 0)(openResponse); - - ShoppingCartId = openResponse.GetCreatedId(); + ShoppingCartId = await Given() + .When(POST, URI("/api/ShoppingCarts"), BODY(new OpenShoppingCartRequest(ClientId))) + .Then(CREATED_WITH_DEFAULT_HEADERS(eTag: 0)) + .GetCreatedId(); } public Task DisposeAsync() => Task.CompletedTask; @@ -40,18 +37,18 @@ public class ConfirmShoppingCartTests: IClassFixture public async Task Put_Should_Return_OK_And_Cancel_Shopping_Cart() { await API - .Given( + .Given() + .When( + PUT, URI($"/api/ShoppingCarts/{API.ShoppingCartId}/confirmation"), HEADERS(IF_MATCH(0)) ) - .When(PUT) .Then(OK); await API - .Given( - URI($"/api/ShoppingCarts/{API.ShoppingCartId}") - ) - .When(GET_UNTIL(RESPONSE_ETAG_IS(1))) + .Given() + .When(GET, URI($"/api/ShoppingCarts/{API.ShoppingCartId}")) + .Until(RESPONSE_ETAG_IS(1)) .Then( OK, RESPONSE_BODY(details => diff --git a/Sample/EventStoreDB/ECommerce/Carts/Carts.Api.Tests/ShoppingCarts/Opening/OpenShoppingCartTests.cs b/Sample/EventStoreDB/ECommerce/Carts/Carts.Api.Tests/ShoppingCarts/Opening/OpenShoppingCartTests.cs index 70dd470de..e2a0cfb5a 100644 --- a/Sample/EventStoreDB/ECommerce/Carts/Carts.Api.Tests/ShoppingCarts/Opening/OpenShoppingCartTests.cs +++ b/Sample/EventStoreDB/ECommerce/Carts/Carts.Api.Tests/ShoppingCarts/Opening/OpenShoppingCartTests.cs @@ -1,7 +1,6 @@ using Carts.Api.Requests; using Carts.ShoppingCarts; using Carts.ShoppingCarts.GettingCartById; -using Core.Testing; using FluentAssertions; using Ogooreck.API; using Xunit; @@ -9,25 +8,24 @@ namespace Carts.Api.Tests.ShoppingCarts.Opening; -public class OpenShoppingCartTests: IClassFixture> +public class OpenShoppingCartTests: IClassFixture> { private readonly ApiSpecification API; [Fact] public Task Post_ShouldReturn_CreatedStatus_With_CartId() => API.Scenario( - API.Given( + API.Given() + .When( + POST, URI("/api/ShoppingCarts/"), BODY(new OpenShoppingCartRequest(ClientId)) - ) - .When(POST) + ) .Then(CREATED_WITH_DEFAULT_HEADERS(eTag: 0)), - response => - API.Given( - URI($"/api/ShoppingCarts/{response.GetCreatedId()}") - ) - .When(GET_UNTIL(RESPONSE_ETAG_IS(0))) + API.Given() + .When(GET, URI($"/api/ShoppingCarts/{response.GetCreatedId()}")) + .Until(RESPONSE_ETAG_IS(0)) .Then( OK, RESPONSE_BODY(details => @@ -40,8 +38,7 @@ public class OpenShoppingCartTests: IClassFixture fixture) => - API = ApiSpecification.Setup(fixture); + public OpenShoppingCartTests(ApiSpecification api) => API = api; public readonly Guid ClientId = Guid.NewGuid(); } diff --git a/Sample/EventStoreDB/ECommerce/Carts/Carts.Api.Tests/ShoppingCarts/RemovingProduct/RemoveProductTests.cs b/Sample/EventStoreDB/ECommerce/Carts/Carts.Api.Tests/ShoppingCarts/RemovingProduct/RemoveProductTests.cs index 4ef656130..26d7b8b74 100644 --- a/Sample/EventStoreDB/ECommerce/Carts/Carts.Api.Tests/ShoppingCarts/RemovingProduct/RemoveProductTests.cs +++ b/Sample/EventStoreDB/ECommerce/Carts/Carts.Api.Tests/ShoppingCarts/RemovingProduct/RemoveProductTests.cs @@ -4,8 +4,8 @@ using Carts.ShoppingCarts.GettingCartById; using Carts.ShoppingCarts.Products; using FluentAssertions; -using Xunit; using Ogooreck.API; +using Xunit; using static Ogooreck.API.ApiSpecification; namespace Carts.Api.Tests.ShoppingCarts.RemovingProduct; @@ -22,32 +22,24 @@ public class RemoveProductFixture: ApiSpecification, IAsyncLifetime public async Task InitializeAsync() { - var openResponse = await Send( - new ApiRequest(POST, URI("/api/ShoppingCarts"), BODY(new OpenShoppingCartRequest(ClientId))) - ); - - await CREATED_WITH_DEFAULT_HEADERS(eTag: 0)(openResponse); - - ShoppingCartId = openResponse.GetCreatedId(); - - var addResponse = await Send( - new ApiRequest( + var cartDetails = await Given() + .When(POST, URI("/api/ShoppingCarts"), BODY(new OpenShoppingCartRequest(ClientId))) + .Then(CREATED_WITH_DEFAULT_HEADERS(eTag: 0)) + .And() + .When( POST, - URI($"/api/ShoppingCarts/{ShoppingCartId}/products"), + URI(ctx => $"/api/ShoppingCarts/{ctx.GetCreatedId()}/products"), BODY(new AddProductRequest(ProductItem)), - HEADERS(IF_MATCH(0))) - ); - - await OK(addResponse); - - var getResponse = await Send( - new ApiRequest( - GET_UNTIL(RESPONSE_ETAG_IS(1)), - URI($"/api/ShoppingCarts/{ShoppingCartId}") + HEADERS(IF_MATCH(0)) ) - ); - - var cartDetails = await getResponse.GetResultFromJson(); + .Then(OK) + .And() + .When(GET, URI(ctx => $"/api/ShoppingCarts/{ctx.GetCreatedId()}")) + .Until(RESPONSE_ETAG_IS(1)) + .Then(OK) + .GetResponseBody(); + + ShoppingCartId = cartDetails.Id; UnitPrice = cartDetails.ProductItems.Single().UnitPrice; } @@ -65,19 +57,17 @@ public class RemoveProductTests: IClassFixture public async Task Delete_Should_Return_OK_And_Cancel_Shopping_Cart() { await API - .Given( + .Given() + .When( + DELETE, URI( $"/api/ShoppingCarts/{API.ShoppingCartId}/products/{API.ProductItem.ProductId}?quantity={RemovedCount}&unitPrice={API.UnitPrice.ToString(CultureInfo.InvariantCulture)}"), HEADERS(IF_MATCH(1)) ) - .When(DELETE) - .Then(NO_CONTENT); - - await API - .Given( - URI($"/api/ShoppingCarts/{API.ShoppingCartId}") - ) - .When(GET_UNTIL(RESPONSE_ETAG_IS(2))) + .Then(NO_CONTENT) + .And() + .When(GET, URI($"/api/ShoppingCarts/{API.ShoppingCartId}")) + .Until(RESPONSE_ETAG_IS(2)) .Then( OK, RESPONSE_BODY(details => @@ -86,9 +76,13 @@ await API details.Status.Should().Be(ShoppingCartStatus.Pending); details.ProductItems.Should().HaveCount(1); var productItem = details.ProductItems.Single(); - productItem.Should().Be( - PricedProductItem.From( - ProductItem.From(API.ProductItem.ProductId, API.ProductItem.Quantity - RemovedCount), + productItem.Should().BeEquivalentTo( + new PricedProductItem( + new ProductItem + ( + API.ProductItem.ProductId!.Value, + API.ProductItem.Quantity!.Value - RemovedCount + ), API.UnitPrice )); details.ClientId.Should().Be(API.ClientId); diff --git a/Sample/EventStoreDB/ECommerce/Carts/Carts.Api.Tests/ShoppingCarts/ShoppingCartsApi.cs b/Sample/EventStoreDB/ECommerce/Carts/Carts.Api.Tests/ShoppingCarts/ShoppingCartsApi.cs new file mode 100644 index 000000000..56c927656 --- /dev/null +++ b/Sample/EventStoreDB/ECommerce/Carts/Carts.Api.Tests/ShoppingCarts/ShoppingCartsApi.cs @@ -0,0 +1,19 @@ +using Carts.Api.Requests; +using Ogooreck.API; +using static Ogooreck.API.ApiSpecification; + +namespace Carts.Api.Tests.ShoppingCarts; + +public static class ShoppingCartsApi +{ + public static RequestDefinition OpenShoppingCart(Guid? clientId = null) => + SEND( + "Open ShoppingCart", + POST, + URI("/api/ShoppingCarts"), + BODY(new OpenShoppingCartRequest(clientId ?? Guid.NewGuid())) + ); + + public static Guid OpenedShoppingCartId(this TestContext ctx) => + ctx.GetCreatedId(); +} diff --git a/Sample/EventStoreDB/Simple/ECommerce.Api.Tests/ShoppingCarts/AddingProduct/AddProductTests.cs b/Sample/EventStoreDB/Simple/ECommerce.Api.Tests/ShoppingCarts/AddingProduct/AddProductTests.cs index df2bd1d87..b30c23a33 100644 --- a/Sample/EventStoreDB/Simple/ECommerce.Api.Tests/ShoppingCarts/AddingProduct/AddProductTests.cs +++ b/Sample/EventStoreDB/Simple/ECommerce.Api.Tests/ShoppingCarts/AddingProduct/AddProductTests.cs @@ -8,33 +8,13 @@ namespace ECommerce.Api.Tests.ShoppingCarts.AddingProduct; -public class AddProductFixture: ApiSpecification, IAsyncLifetime -{ - public AddProductFixture(): base(new ShoppingCartsApplicationFactory()) { } - - public Guid ShoppingCartId { get; private set; } - - public readonly Guid ClientId = Guid.NewGuid(); - - public async Task InitializeAsync() - { - var openResponse = await Send( - new ApiRequest(POST, URI("/api/ShoppingCarts"), BODY(new OpenShoppingCartRequest(ClientId))) - ); - - await CREATED_WITH_DEFAULT_HEADERS(eTag: 0)(openResponse); +using static ShoppingCartsApi; - ShoppingCartId = openResponse.GetCreatedId(); - } - - public Task DisposeAsync() => Task.CompletedTask; -} - -public class AddProductTests: IClassFixture +public class AddProductTests: IClassFixture> { - private readonly AddProductFixture API; + private readonly ApiSpecification API; - public AddProductTests(AddProductFixture api) => API = api; + public AddProductTests(ApiSpecification api) => API = api; [Fact] [Trait("Category", "Acceptance")] @@ -43,21 +23,21 @@ public async Task Post_Should_AddProductItem_To_ShoppingCart() var product = new ProductItemRequest(Guid.NewGuid(), 1); await API - .Given( - URI($"/api/ShoppingCarts/{API.ShoppingCartId}/products"), + .Given("Opened Shopping Cart", OpenShoppingCart()) + .When( + "Add new product", + POST, + URI(ctx => $"/api/ShoppingCarts/{ctx.OpenedShoppingCartId()}/products"), BODY(new AddProductRequest(product)), HEADERS(IF_MATCH(0)) ) - .When(POST) - .Then(OK); - - await API - .Given(URI($"/api/ShoppingCarts/{API.ShoppingCartId}")) - .When(GET_UNTIL(RESPONSE_ETAG_IS(1))) + .Then(OK) + .And() + .When(GET, URI(ctx => $"/api/ShoppingCarts/{ctx.OpenedShoppingCartId()}")) .Then( - RESPONSE_BODY(details => + RESPONSE_BODY((details, ctx) => { - details.Id.Should().Be(API.ShoppingCartId); + details.Id.Should().Be(ctx.OpenedShoppingCartId()); details.Status.Should().Be(ShoppingCartStatus.Pending); var productItem = details.ProductItems.Single(); productItem.Quantity.Should().Be(product.Quantity); diff --git a/Sample/EventStoreDB/Simple/ECommerce.Api.Tests/ShoppingCarts/Canceling/CancelShoppingCartTests.cs b/Sample/EventStoreDB/Simple/ECommerce.Api.Tests/ShoppingCarts/Canceling/CancelShoppingCartTests.cs index 45d5ba2fc..adde433e8 100644 --- a/Sample/EventStoreDB/Simple/ECommerce.Api.Tests/ShoppingCarts/Canceling/CancelShoppingCartTests.cs +++ b/Sample/EventStoreDB/Simple/ECommerce.Api.Tests/ShoppingCarts/Canceling/CancelShoppingCartTests.cs @@ -1,69 +1,43 @@ -using ECommerce.Api.Requests; using ECommerce.ShoppingCarts; using ECommerce.ShoppingCarts.GettingCartById; using FluentAssertions; using Ogooreck.API; using Xunit; using static Ogooreck.API.ApiSpecification; +using static ECommerce.Api.Tests.ShoppingCarts.ShoppingCartsApi; namespace ECommerce.Api.Tests.ShoppingCarts.Canceling; -public class CancelShoppingCartFixture: ApiSpecification, IAsyncLifetime +public class CancelShoppingCartTests: IClassFixture> { - public CancelShoppingCartFixture(): base(new ShoppingCartsApplicationFactory()) { } - - public Guid ShoppingCartId { get; private set; } + private readonly ApiSpecification API; + public CancelShoppingCartTests(ApiSpecification api) => API = api; public readonly Guid ClientId = Guid.NewGuid(); - public async Task InitializeAsync() - { - var openResponse = await Send( - new ApiRequest(POST, URI("/api/ShoppingCarts"), BODY(new OpenShoppingCartRequest(ClientId))) - ); - - await CREATED_WITH_DEFAULT_HEADERS(eTag: 0)(openResponse); - - ShoppingCartId = openResponse.GetCreatedId(); - } - - public Task DisposeAsync() => Task.CompletedTask; -} - -public class CancelShoppingCartTests: IClassFixture -{ - private readonly CancelShoppingCartFixture API; - - public CancelShoppingCartTests(CancelShoppingCartFixture api) => API = api; - [Fact] [Trait("Category", "Acceptance")] - public async Task Delete_Should_Return_OK_And_Cancel_Shopping_Cart() - { - await API - .Given( - URI($"/api/ShoppingCarts/{API.ShoppingCartId}"), + public Task Delete_Should_Return_OK_And_Cancel_Shopping_Cart() => + API + .Given("Opened Shopping Cart", OpenShoppingCart(ClientId)) + .When( + "Cancel Shopping Cart", + DELETE, + URI(ctx => $"/api/ShoppingCarts/{ctx.OpenedShoppingCartId()}"), HEADERS(IF_MATCH(0)) ) - .When(DELETE) - .Then(OK); - - await API - .Given( - URI($"/api/ShoppingCarts/{API.ShoppingCartId}") - ) - .When(GET_UNTIL(RESPONSE_ETAG_IS(1))) + .Then(OK) + .And() + .When(GET, URI(ctx => $"/api/ShoppingCarts/{ctx.OpenedShoppingCartId()}")) + .Until(RESPONSE_ETAG_IS(1)) .Then( OK, - RESPONSE_BODY(details => + RESPONSE_BODY((details, ctx) => { - details.Id.Should().Be(API.ShoppingCartId); + details.Id.Should().Be(ctx.OpenedShoppingCartId()); details.Status.Should().Be(ShoppingCartStatus.Canceled); details.ProductItems.Should().BeEmpty(); - details.ClientId.Should().Be(API.ClientId); + details.ClientId.Should().Be(ClientId); details.Version.Should().Be(1); })); - - // API.PublishedExternalEventsOfType(); - } } diff --git a/Sample/EventStoreDB/Simple/ECommerce.Api.Tests/ShoppingCarts/Confirming/ConfirmShoppingCartTests.cs b/Sample/EventStoreDB/Simple/ECommerce.Api.Tests/ShoppingCarts/Confirming/ConfirmShoppingCartTests.cs index dff23cfa7..cc66ad183 100644 --- a/Sample/EventStoreDB/Simple/ECommerce.Api.Tests/ShoppingCarts/Confirming/ConfirmShoppingCartTests.cs +++ b/Sample/EventStoreDB/Simple/ECommerce.Api.Tests/ShoppingCarts/Confirming/ConfirmShoppingCartTests.cs @@ -18,13 +18,10 @@ public class ConfirmShoppingCartFixture: ApiSpecification, IAsyncLifeti public async Task InitializeAsync() { - var openResponse = await Send( - new ApiRequest(POST, URI("/api/ShoppingCarts"), BODY(new OpenShoppingCartRequest(ClientId))) - ); - - await CREATED_WITH_DEFAULT_HEADERS(eTag: 0)(openResponse); - - ShoppingCartId = openResponse.GetCreatedId(); + ShoppingCartId = await Given() + .When(POST, URI("/api/ShoppingCarts"), BODY(new OpenShoppingCartRequest(ClientId))) + .Then(CREATED_WITH_DEFAULT_HEADERS(eTag: 0)) + .GetCreatedId(); } public Task DisposeAsync() => Task.CompletedTask; @@ -42,18 +39,18 @@ public class ConfirmShoppingCartTests: IClassFixture public async Task Put_Should_Return_OK_And_Cancel_Shopping_Cart() { await API - .Given( + .Given() + .When( + PUT, URI($"/api/ShoppingCarts/{API.ShoppingCartId}/confirmation"), HEADERS(IF_MATCH(0)) ) - .When(PUT) .Then(OK); await API - .Given( - URI($"/api/ShoppingCarts/{API.ShoppingCartId}") - ) - .When(GET_UNTIL(RESPONSE_ETAG_IS(1))) + .Given() + .When(GET, URI($"/api/ShoppingCarts/{API.ShoppingCartId}")) + .Until(RESPONSE_ETAG_IS(1)) .Then( OK, RESPONSE_BODY(details => diff --git a/Sample/EventStoreDB/Simple/ECommerce.Api.Tests/ShoppingCarts/Opening/OpenShoppingCartTests.cs b/Sample/EventStoreDB/Simple/ECommerce.Api.Tests/ShoppingCarts/Opening/OpenShoppingCartTests.cs index bf44a7edc..846c33e73 100644 --- a/Sample/EventStoreDB/Simple/ECommerce.Api.Tests/ShoppingCarts/Opening/OpenShoppingCartTests.cs +++ b/Sample/EventStoreDB/Simple/ECommerce.Api.Tests/ShoppingCarts/Opening/OpenShoppingCartTests.cs @@ -15,18 +15,17 @@ public class OpenShoppingCartTests: IClassFixture API.Scenario( - API.Given( + API.Given() + .When( + POST, URI("/api/ShoppingCarts/"), BODY(new OpenShoppingCartRequest(ClientId)) ) - .When(POST) .Then(CREATED_WITH_DEFAULT_HEADERS(eTag: 0)), - response => - API.Given( - URI($"/api/ShoppingCarts/{response.GetCreatedId()}") - ) - .When(GET_UNTIL(RESPONSE_ETAG_IS(0))) + API.Given() + .When(GET, URI($"/api/ShoppingCarts/{response.GetCreatedId()}")) + .Until(RESPONSE_ETAG_IS(0)) .Then( OK, RESPONSE_BODY(details => diff --git a/Sample/EventStoreDB/Simple/ECommerce.Api.Tests/ShoppingCarts/RemovingProduct/RemoveProductTests.cs b/Sample/EventStoreDB/Simple/ECommerce.Api.Tests/ShoppingCarts/RemovingProduct/RemoveProductTests.cs index fab2c29b9..2c7ce03b7 100644 --- a/Sample/EventStoreDB/Simple/ECommerce.Api.Tests/ShoppingCarts/RemovingProduct/RemoveProductTests.cs +++ b/Sample/EventStoreDB/Simple/ECommerce.Api.Tests/ShoppingCarts/RemovingProduct/RemoveProductTests.cs @@ -22,32 +22,24 @@ public class RemoveProductFixture: ApiSpecification, IAsyncLifetime public async Task InitializeAsync() { - var openResponse = await Send( - new ApiRequest(POST, URI("/api/ShoppingCarts"), BODY(new OpenShoppingCartRequest(ClientId))) - ); - - await CREATED_WITH_DEFAULT_HEADERS(eTag: 0)(openResponse); - - ShoppingCartId = openResponse.GetCreatedId(); - - var addResponse = await Send( - new ApiRequest( + var cartDetails = await Given() + .When(POST, URI("/api/ShoppingCarts"), BODY(new OpenShoppingCartRequest(ClientId))) + .Then(CREATED_WITH_DEFAULT_HEADERS(eTag: 0)) + .And() + .When( POST, - URI($"/api/ShoppingCarts/{ShoppingCartId}/products"), + URI(ctx => $"/api/ShoppingCarts/{ctx.GetCreatedId()}/products"), BODY(new AddProductRequest(ProductItem)), - HEADERS(IF_MATCH(0))) - ); - - await OK(addResponse); - - var getResponse = await Send( - new ApiRequest( - GET_UNTIL(RESPONSE_ETAG_IS(1)), - URI($"/api/ShoppingCarts/{ShoppingCartId}") + HEADERS(IF_MATCH(0)) ) - ); - - var cartDetails = await getResponse.GetResultFromJson(); + .Then(OK) + .And() + .When(GET, URI(ctx=>$"/api/ShoppingCarts/{ctx.GetCreatedId()}")) + .Until(RESPONSE_ETAG_IS(1)) + .Then(OK) + .GetResponseBody(); + + ShoppingCartId = cartDetails.Id; UnitPrice = cartDetails.ProductItems.Single().UnitPrice; } @@ -65,19 +57,18 @@ public class RemoveProductTests: IClassFixture public async Task Delete_Should_Return_OK_And_Cancel_Shopping_Cart() { await API - .Given( - URI( - $"/api/ShoppingCarts/{API.ShoppingCartId}/products/{API.ProductItem.ProductId}?quantity={RemovedCount}&unitPrice={API.UnitPrice.ToString(CultureInfo.InvariantCulture)}"), + .Given() + .When( + DELETE, + URI($"/api/ShoppingCarts/{API.ShoppingCartId}/products/{API.ProductItem.ProductId}?quantity={RemovedCount}&unitPrice={API.UnitPrice.ToString(CultureInfo.InvariantCulture)}"), HEADERS(IF_MATCH(1)) ) - .When(DELETE) - .Then(NO_CONTENT); + .Then(NO_CONTENT) - await API - .Given( - URI($"/api/ShoppingCarts/{API.ShoppingCartId}") - ) - .When(GET_UNTIL(RESPONSE_ETAG_IS(2))) + .And() + + .When(GET, URI($"/api/ShoppingCarts/{API.ShoppingCartId}")) + .Until(RESPONSE_ETAG_IS(2)) .Then( OK, RESPONSE_BODY(details => diff --git a/Sample/EventStoreDB/Simple/ECommerce.Api.Tests/ShoppingCarts/ShoppingCartsApi.cs b/Sample/EventStoreDB/Simple/ECommerce.Api.Tests/ShoppingCarts/ShoppingCartsApi.cs new file mode 100644 index 000000000..8a6e2c5c5 --- /dev/null +++ b/Sample/EventStoreDB/Simple/ECommerce.Api.Tests/ShoppingCarts/ShoppingCartsApi.cs @@ -0,0 +1,19 @@ +using ECommerce.Api.Requests; +using Ogooreck.API; +using static Ogooreck.API.ApiSpecification; + +namespace ECommerce.Api.Tests.ShoppingCarts; + +public static class ShoppingCartsApi +{ + public static RequestDefinition OpenShoppingCart(Guid? clientId = null) => + SEND( + "Open ShoppingCart", + POST, + URI("/api/ShoppingCarts"), + BODY(new OpenShoppingCartRequest(clientId ?? Guid.NewGuid())) + ); + + public static Guid OpenedShoppingCartId(this TestContext ctx) => + ctx.GetCreatedId(); +} diff --git a/Sample/Helpdesk/Helpdesk.Api.Tests/Helpdesk.Api.Tests.csproj b/Sample/Helpdesk/Helpdesk.Api.Tests/Helpdesk.Api.Tests.csproj index ea9fe6328..91d4cac57 100644 --- a/Sample/Helpdesk/Helpdesk.Api.Tests/Helpdesk.Api.Tests.csproj +++ b/Sample/Helpdesk/Helpdesk.Api.Tests/Helpdesk.Api.Tests.csproj @@ -13,7 +13,7 @@ - + all diff --git a/Sample/Helpdesk/Helpdesk.Api.Tests/Incidents/AcknowledgeResolutionIncidentTests.cs b/Sample/Helpdesk/Helpdesk.Api.Tests/Incidents/AcknowledgeResolutionIncidentTests.cs index d16286e5c..b3653122a 100644 --- a/Sample/Helpdesk/Helpdesk.Api.Tests/Incidents/AcknowledgeResolutionIncidentTests.cs +++ b/Sample/Helpdesk/Helpdesk.Api.Tests/Incidents/AcknowledgeResolutionIncidentTests.cs @@ -9,19 +9,19 @@ public class AcknowledgeResolutionIncidentTests: IClassFixture + API + .Given() + .When( + POST, URI($"/api/customers/{API.Incident.CustomerId}/incidents/{API.Incident.Id}/acknowledge"), HEADERS(IF_MATCH(2)) ) - .When(POST) - .Then(OK); + .Then(OK) - await API - .Given(URI($"/api/incidents/{API.Incident.Id}")) - .When(GET) + .And() + + .When(GET, URI($"/api/incidents/{API.Incident.Id}")) .Then( OK, RESPONSE_BODY( @@ -32,7 +32,6 @@ API.Incident with } ) ); - } private readonly ApiWithResolvedIncident API; diff --git a/Sample/Helpdesk/Helpdesk.Api.Tests/Incidents/AssignAgentTests.cs b/Sample/Helpdesk/Helpdesk.Api.Tests/Incidents/AssignAgentTests.cs index 8ae5b5b66..1449cb101 100644 --- a/Sample/Helpdesk/Helpdesk.Api.Tests/Incidents/AssignAgentTests.cs +++ b/Sample/Helpdesk/Helpdesk.Api.Tests/Incidents/AssignAgentTests.cs @@ -11,24 +11,19 @@ public class AssignAgentToIncidentTests: IClassFixture public async Task AssignAgentCommand_ChangesIncidentCategory() { await API - .Given( + .Given() + .When( + POST, URI($"/api/agents/{agentId}/incidents/{API.Incident.Id}/assign"), HEADERS(IF_MATCH(1)) ) - .When(POST) - .Then(OK); - - await API - .Given(URI($"/api/incidents/{API.Incident.Id}")) - .When(GET) + .Then(OK) + .And() + .When(GET, URI($"/api/incidents/{API.Incident.Id}")) .Then( OK, RESPONSE_BODY( - API.Incident with - { - AgentId = agentId, - Version = 2 - } + API.Incident with { AgentId = agentId, Version = 2 } ) ); } diff --git a/Sample/Helpdesk/Helpdesk.Api.Tests/Incidents/CategoriseIncidentTests.cs b/Sample/Helpdesk/Helpdesk.Api.Tests/Incidents/CategoriseIncidentTests.cs index 9f24165b4..72d59c4a2 100644 --- a/Sample/Helpdesk/Helpdesk.Api.Tests/Incidents/CategoriseIncidentTests.cs +++ b/Sample/Helpdesk/Helpdesk.Api.Tests/Incidents/CategoriseIncidentTests.cs @@ -13,25 +13,22 @@ public class CategoriseIncidentTests: IClassFixture public async Task CategoriseCommand_ChangesIncidentCategory() { await API - .Given( + .Given() + .When( + POST, URI($"/api/agents/{agentId}/incidents/{API.Incident.Id}/category"), BODY(new CategoriseIncidentRequest(category)), HEADERS(IF_MATCH(1)) ) - .When(POST) .Then(OK); await API - .Given(URI($"/api/incidents/{API.Incident.Id}")) - .When(GET) + .Given() + .When(GET, URI($"/api/incidents/{API.Incident.Id}")) .Then( OK, RESPONSE_BODY( - API.Incident with - { - Category = category, - Version = 2 - } + API.Incident with { Category = category, Version = 2 } ) ); } @@ -41,5 +38,4 @@ API.Incident with private readonly ApiWithLoggedIncident API; public CategoriseIncidentTests(ApiWithLoggedIncident api) => API = api; - } diff --git a/Sample/Helpdesk/Helpdesk.Api.Tests/Incidents/CloseIncidentTests.cs b/Sample/Helpdesk/Helpdesk.Api.Tests/Incidents/CloseIncidentTests.cs index 2a6763bc5..00e997930 100644 --- a/Sample/Helpdesk/Helpdesk.Api.Tests/Incidents/CloseIncidentTests.cs +++ b/Sample/Helpdesk/Helpdesk.Api.Tests/Incidents/CloseIncidentTests.cs @@ -12,24 +12,21 @@ public class CloseIncidentTests: IClassFixture public async Task ResolveCommand_Succeeds() { await API - .Given( + .Given() + .When( + POST, URI($"/api/agents/{agentId}/incidents/{API.Incident.Id}/close"), HEADERS(IF_MATCH(3)) ) - .When(POST) .Then(OK); await API - .Given(URI($"/api/incidents/{API.Incident.Id}")) - .When(GET) + .Given() + .When(GET, URI($"/api/incidents/{API.Incident.Id}")) .Then( OK, RESPONSE_BODY( - API.Incident with - { - Status = IncidentStatus.Closed, - Version = 4 - } + API.Incident with { Status = IncidentStatus.Closed, Version = 4 } ) ); } diff --git a/Sample/Helpdesk/Helpdesk.Api.Tests/Incidents/Fixtures/Scenarios.cs b/Sample/Helpdesk/Helpdesk.Api.Tests/Incidents/Fixtures/Scenarios.cs index 0f95b664d..d69e06f50 100644 --- a/Sample/Helpdesk/Helpdesk.Api.Tests/Incidents/Fixtures/Scenarios.cs +++ b/Sample/Helpdesk/Helpdesk.Api.Tests/Incidents/Fixtures/Scenarios.cs @@ -43,12 +43,10 @@ public static class Scenarios var resolvedType = faker.PickRandom(); var incident = await api.LoggedIncident(); - var response = await api.Scenario( + return await api.Scenario( api.ResolveIncident(incident.Id, agentId, resolvedType), _ => api.GetIncidentDetails(incident.Id) - ); - - return await response.GetResultFromJson(); + ).GetResponseBody(); } public static async Task AcknowledgedIncident( @@ -57,58 +55,55 @@ public static class Scenarios { var incident = await api.ResolvedIncident(); - var response = await api.Scenario( + return await api.Scenario( api.AcknowledgeIncident(incident.Id, incident.CustomerId), _ => api.GetIncidentDetails(incident.Id) - ); - - return await response.GetResultFromJson(); + ).GetResponseBody(); } - private static Task LogIncident( + private static Task LogIncident( this ApiSpecification api, Guid customerId, Contact contact, string incidentDescription ) => - api.Given( - URI($"api/customers/{customerId}/incidents/"), - BODY(new LogIncidentRequest(contact, incidentDescription)) - ) - .When(POST) + api.Given() + .When(POST, URI($"api/customers/{customerId}/incidents/"), BODY(new LogIncidentRequest(contact, incidentDescription))) .Then(CREATED_WITH_DEFAULT_HEADERS(locationHeaderPrefix: "/api/incidents/")); - private static Task ResolveIncident( + private static Task ResolveIncident( this ApiSpecification api, Guid incidentId, Guid agentId, ResolutionType resolutionType ) where T : class => - api.Given( + api.Given() + .When( + POST, URI($"/api/agents/{agentId}/incidents/{incidentId}/resolve"), BODY(new ResolveIncidentRequest(resolutionType)), HEADERS(IF_MATCH(1)) ) - .When(POST) .Then(OK); - private static Task AcknowledgeIncident( + private static Task AcknowledgeIncident( this ApiSpecification api, Guid incidentId, Guid customerId ) where T : class => - api.Given( + api.Given() + .When( + POST, URI($"/api/customers/{customerId}/incidents/{incidentId}/acknowledge"), HEADERS(IF_MATCH(2)) - ) - .When(POST) + ) .Then(OK); - private static Task GetIncidentDetails( + private static Task GetIncidentDetails( this ApiSpecification api, Guid incidentId ) => - api.Given(URI($"/api/incidents/{incidentId}")) - .When(GET) + api.Given() + .When(GET, URI($"/api/incidents/{incidentId}")) .Then(OK); } diff --git a/Sample/Helpdesk/Helpdesk.Api.Tests/Incidents/LogIncidentsTests.cs b/Sample/Helpdesk/Helpdesk.Api.Tests/Incidents/LogIncidentsTests.cs index 782298dae..0c26a5bc1 100644 --- a/Sample/Helpdesk/Helpdesk.Api.Tests/Incidents/LogIncidentsTests.cs +++ b/Sample/Helpdesk/Helpdesk.Api.Tests/Incidents/LogIncidentsTests.cs @@ -12,38 +12,35 @@ public class LogIncidentsTests: IClassFixture> { [Fact] public Task LogIncident_ShouldSucceed() => - API.Scenario( - // Log Incident - API.Given( - URI($"api/customers/{CustomerId}/incidents/"), - BODY(new LogIncidentRequest(Contact, IncidentDescription)) - ) - .When(POST) - .Then(CREATED_WITH_DEFAULT_HEADERS(locationHeaderPrefix: "/api/incidents/")), - // Get Details - response => - API.Given(URI($"/api/incidents/{response.GetCreatedId()}")) - .When(GET) - .Then( - OK, - RESPONSE_BODY( - new IncidentDetails( - response.GetCreatedId(), - CustomerId, - IncidentStatus.Pending, - Array.Empty(), - null, - null, - null, - 1 - ) - ) + API.Given() + .When( + POST, + URI($"api/customers/{CustomerId}/incidents/"), + BODY(new LogIncidentRequest(Contact, IncidentDescription)) + ) + .Then(CREATED_WITH_DEFAULT_HEADERS(locationHeaderPrefix: "/api/incidents/")) + .And() + .When(GET, URI(ctx => $"/api/incidents/{ctx.GetCreatedId()}")) + .Then( + OK, + RESPONSE_BODY(ctx => + new IncidentDetails( + ctx.GetCreatedId(), + CustomerId, + IncidentStatus.Pending, + Array.Empty(), + null, + null, + null, + 1 ) - ); + ) + ); public LogIncidentsTests(ApiSpecification api) => API = api; private readonly ApiSpecification API; + private readonly Guid CustomerId = Guid.NewGuid(); private readonly Contact Contact = new Faker().CustomInstantiator( diff --git a/Sample/Helpdesk/Helpdesk.Api.Tests/Incidents/PrioritiseIncidentTests.cs b/Sample/Helpdesk/Helpdesk.Api.Tests/Incidents/PrioritiseIncidentTests.cs index 216156358..cbec22cb9 100644 --- a/Sample/Helpdesk/Helpdesk.Api.Tests/Incidents/PrioritiseIncidentTests.cs +++ b/Sample/Helpdesk/Helpdesk.Api.Tests/Incidents/PrioritiseIncidentTests.cs @@ -13,17 +13,18 @@ public class PrioritiseIncidentTests: IClassFixture public async Task PrioritiseCommand_ChangesIncidentPriority() { await API - .Given( + .Given() + .When( + POST, URI($"/api/agents/{agentId}/incidents/{API.Incident.Id}/priority"), BODY(new PrioritiseIncidentRequest(priority)), HEADERS(IF_MATCH(1)) ) - .When(POST) .Then(OK); await API - .Given(URI($"/api/incidents/{API.Incident.Id}")) - .When(GET) + .Given() + .When(GET, URI($"/api/incidents/{API.Incident.Id}")) .Then( OK, RESPONSE_BODY( diff --git a/Sample/Helpdesk/Helpdesk.Api.Tests/Incidents/RecordAgentResponseToIncidentTests.cs b/Sample/Helpdesk/Helpdesk.Api.Tests/Incidents/RecordAgentResponseToIncidentTests.cs index 7993c6424..9910c671d 100644 --- a/Sample/Helpdesk/Helpdesk.Api.Tests/Incidents/RecordAgentResponseToIncidentTests.cs +++ b/Sample/Helpdesk/Helpdesk.Api.Tests/Incidents/RecordAgentResponseToIncidentTests.cs @@ -14,17 +14,18 @@ public class RecordAgentResponseToIncidentTests: IClassFixture public async Task ResolveCommand_Succeeds() { await API - .Given( + .Given() + .When( + POST, URI($"/api/agents/{agentId}/incidents/{API.Incident.Id}/resolve"), BODY(new ResolveIncidentRequest(resolutionType)), HEADERS(IF_MATCH(1)) ) - .When(POST) .Then(OK); await API - .Given(URI($"/api/incidents/{API.Incident.Id}")) - .When(GET) + .Given() + .When( + GET, + URI($"/api/incidents/{API.Incident.Id}") + ) .Then( OK, RESPONSE_BODY( - API.Incident with - { - Status = IncidentStatus.Resolved, - Version = 2 - } + API.Incident with { Status = IncidentStatus.Resolved, Version = 2 } ) ); } diff --git a/Sample/Helpdesk/Helpdesk.Api.Tests/Settings.cs b/Sample/Helpdesk/Helpdesk.Api.Tests/Settings.cs index d4d174bf7..f9408ec1c 100644 --- a/Sample/Helpdesk/Helpdesk.Api.Tests/Settings.cs +++ b/Sample/Helpdesk/Helpdesk.Api.Tests/Settings.cs @@ -3,7 +3,7 @@ using Xunit.Abstractions; using Xunit.Sdk; -[assembly: CollectionBehavior(DisableTestParallelization = true)] +// [assembly: CollectionBehavior(DisableTestParallelization = true)] [assembly: TestFramework("Helpdesk.Api.Tests.AssemblyFixture", "Helpdesk.Api.Tests")] diff --git a/Sample/HotelManagement/HotelManagement.Tests/HotelManagement.Tests.csproj b/Sample/HotelManagement/HotelManagement.Tests/HotelManagement.Tests.csproj index 46aaa5203..f2c59a1f5 100644 --- a/Sample/HotelManagement/HotelManagement.Tests/HotelManagement.Tests.csproj +++ b/Sample/HotelManagement/HotelManagement.Tests/HotelManagement.Tests.csproj @@ -12,7 +12,7 @@ - + all diff --git a/Sample/MeetingsManagement/MeetingsManagement.IntegrationTests/Meetings/SchedulingMeetings/ScheduleMeetingTests.cs b/Sample/MeetingsManagement/MeetingsManagement.IntegrationTests/Meetings/SchedulingMeetings/ScheduleMeetingTests.cs index 4b5997384..af7f5e697 100644 --- a/Sample/MeetingsManagement/MeetingsManagement.IntegrationTests/Meetings/SchedulingMeetings/ScheduleMeetingTests.cs +++ b/Sample/MeetingsManagement/MeetingsManagement.IntegrationTests/Meetings/SchedulingMeetings/ScheduleMeetingTests.cs @@ -8,31 +8,12 @@ namespace MeetingsManagement.IntegrationTests.Meetings.SchedulingMeetings; - -public class ScheduleMeetingFixture: ApiSpecification, IAsyncLifetime -{ - public async Task InitializeAsync() - { - var openResponse = await Send( - new ApiRequest(POST, URI(MeetingsManagementApi.MeetingsUrl), BODY(new CreateMeeting(MeetingId, MeetingName))) - ); - - await CREATED_WITH_DEFAULT_HEADERS(eTag: 1)(openResponse); - } - - public Task DisposeAsync() => Task.CompletedTask; - - - public readonly Guid MeetingId = Guid.NewGuid(); - public readonly string MeetingName = "Event Sourcing Workshop"; -} - -public class ScheduleMeetingTests: IClassFixture +public class ScheduleMeetingTests: IClassFixture> { - private readonly ScheduleMeetingFixture API; + private readonly ApiSpecification API; - public ScheduleMeetingTests(ScheduleMeetingFixture api) => API = api; + public ScheduleMeetingTests(ApiSpecification api) => API = api; [Fact] [Trait("Category", "Acceptance")] @@ -40,24 +21,24 @@ public async Task UpdateCommand_Should_Succeed() { await API .Given( - URI($"{MeetingsManagementApi.MeetingsUrl}/{API.MeetingId}/schedule"), + "Created Meeting", + SEND(POST, URI(MeetingsManagementApi.MeetingsUrl), BODY(new CreateMeeting(MeetingId, MeetingName))) + ) + .When( + POST, + URI(ctx => $"{MeetingsManagementApi.MeetingsUrl}/{ctx.GetCreatedId()}/schedule"), BODY(DateRange.Create(Start, End)), HEADERS(IF_MATCH(1)) ) - .When(POST) - .Then(OK); - - await API - .Given( - URI($"{MeetingsManagementApi.MeetingsUrl}/{API.MeetingId}") - ) - .When(GET_UNTIL(RESPONSE_ETAG_IS(2))) + .Then(OK) + .AndWhen(GET, URI(ctx => $"{MeetingsManagementApi.MeetingsUrl}/{ctx.GetCreatedId()}")) + .Until(RESPONSE_ETAG_IS(2)) .Then( OK, RESPONSE_BODY(meeting => { - meeting.Id.Should().Be(API.MeetingId); - meeting.Name.Should().Be(API.MeetingName); + meeting.Id.Should().Be(MeetingId); + meeting.Name.Should().Be(MeetingName); meeting.Start.Should().Be(Start); meeting.End.Should().Be(End); })); @@ -65,4 +46,7 @@ await API private readonly DateTime Start = DateTime.UtcNow; private readonly DateTime End = DateTime.UtcNow; + + public readonly Guid MeetingId = Guid.NewGuid(); + public readonly string MeetingName = "Event Sourcing Workshop"; } diff --git a/Sample/MeetingsManagement/MeetingsSearch.IntegrationTests/Meetings/CreatingMeeting/CreateMeetingTests.cs b/Sample/MeetingsManagement/MeetingsSearch.IntegrationTests/Meetings/CreatingMeeting/CreateMeetingTests.cs index a301e336b..ad106290c 100644 --- a/Sample/MeetingsManagement/MeetingsSearch.IntegrationTests/Meetings/CreatingMeeting/CreateMeetingTests.cs +++ b/Sample/MeetingsManagement/MeetingsSearch.IntegrationTests/Meetings/CreatingMeeting/CreateMeetingTests.cs @@ -32,14 +32,15 @@ public async Task CreateCommand_ShouldPublish_MeetingCreateEvent() new EventMetadata("event-id", 1, 2, null) )); - await API.Given( + await API.Given() + .When( + GET, URI($"{MeetingsSearchApi.MeetingsUrl}?filter={MeetingName}") ) - .When( - GET_UNTIL( - RESPONSE_BODY_MATCHES>( - meetings => meetings.Any(m => m.Id == MeetingId)) - )) + .Until( + RESPONSE_BODY_MATCHES>( + meetings => meetings.Any(m => m.Id == MeetingId)) + ) .Then( RESPONSE_BODY>(meetings => meetings.Should().Contain(meeting => diff --git a/Sample/Tickets/Tickets.Api.Tests/Reservations/CreatingTentativeReservation/CreateTentativeReservationTests.cs b/Sample/Tickets/Tickets.Api.Tests/Reservations/CreatingTentativeReservation/CreateTentativeReservationTests.cs index 3d3df96e8..1e09ab584 100644 --- a/Sample/Tickets/Tickets.Api.Tests/Reservations/CreatingTentativeReservation/CreateTentativeReservationTests.cs +++ b/Sample/Tickets/Tickets.Api.Tests/Reservations/CreatingTentativeReservation/CreateTentativeReservationTests.cs @@ -15,86 +15,65 @@ namespace Tickets.Api.Tests.Reservations.CreatingTentativeReservation; public class CreateTentativeReservationTests: IClassFixture> { [Fact] - public async Task Post_ShouldReturn_CreatedStatus_With_CartId() - { - var createdReservationId = Guid.Empty; + public Task Post_ShouldReturn_CreatedStatus_With_CartId() => + API.Given() + .When( + POST, + URI("/api/Reservations/"), + BODY(new CreateTentativeReservationRequest { SeatId = SeatId }) + ) + .Then(CREATED_WITH_DEFAULT_HEADERS(eTag: 1)) + .And() + .When(GET, URI(ctx => $"/api/Reservations/{ctx.GetCreatedId()}")) + .Then( + OK, + RESPONSE_BODY((reservation, ctx) => + { + reservation.Id.Should().Be(ctx.GetCreatedId()); + reservation.Status.Should().Be(ReservationStatus.Tentative); + reservation.SeatId.Should().Be(SeatId); + reservation.Number.Should().NotBeEmpty(); + reservation.Version.Should().Be(1); + }) + ) + .And() + .When(GET, URI("/api/Reservations/")) + .Then( + OK, + RESPONSE_BODY>((reservations, ctx) => + { + reservations.Should().NotBeNull(); + reservations.Items.Should().NotBeNull(); - await API.Scenario( - // Create Reservations - API.Given( - URI("/api/Reservations/"), - BODY(new CreateTentativeReservationRequest { SeatId = SeatId }) - ) - .When(POST) - .Then(CREATED_WITH_DEFAULT_HEADERS(eTag: 1), - response => - { - createdReservationId = response.GetCreatedId(); - return ValueTask.CompletedTask; - }), + reservations.Items.Should().HaveCount(1); + reservations.TotalItemCount.Should().Be(1); + reservations.HasNextPage.Should().Be(false); - // Get reservation details - _ => API.Given( - URI($"/api/Reservations/{createdReservationId}") - ) - .When(GET) - .Then( - OK, - RESPONSE_BODY(reservation => - { - reservation.Id.Should().Be(createdReservationId); - reservation.Status.Should().Be(ReservationStatus.Tentative); - reservation.SeatId.Should().Be(SeatId); - reservation.Number.Should().NotBeEmpty(); - reservation.Version.Should().Be(1); - })), + var reservationInfo = reservations.Items.Single(); - // Get reservations list - _ => API.Given( - URI("/api/Reservations/") - ) - .When(GET) - .Then( - OK, - RESPONSE_BODY>(reservations => - { - reservations.Should().NotBeNull(); - reservations.Items.Should().NotBeNull(); + reservationInfo.Id.Should().Be(ctx.GetCreatedId()); + reservationInfo.Number.Should().NotBeNull().And.NotBeEmpty(); + reservationInfo.Status.Should().Be(ReservationStatus.Tentative); + })) + .And() + .When(GET, URI(ctx => $"/api/Reservations/{ctx.GetCreatedId()}/history")) + .Then( + OK, + RESPONSE_BODY>((reservations, ctx) => + { + reservations.Should().NotBeNull(); + reservations.Items.Should().NotBeNull(); - reservations.Items.Should().HaveCount(1); - reservations.TotalItemCount.Should().Be(1); - reservations.HasNextPage.Should().Be(false); + reservations.Items.Should().HaveCount(1); + reservations.TotalItemCount.Should().Be(1); + reservations.HasNextPage.Should().Be(false); - var reservationInfo = reservations.Items.Single(); + var reservationInfo = reservations.Items.Single(); - reservationInfo.Id.Should().Be(createdReservationId); - reservationInfo.Number.Should().NotBeNull().And.NotBeEmpty(); - reservationInfo.Status.Should().Be(ReservationStatus.Tentative); - })), - - // Get reservation history - _ => API.Given( - URI($"/api/Reservations/{createdReservationId}/history") - ) - .When(GET) - .Then( - OK, - RESPONSE_BODY>(reservations => - { - reservations.Should().NotBeNull(); - reservations.Items.Should().NotBeNull(); - - reservations.Items.Should().HaveCount(1); - reservations.TotalItemCount.Should().Be(1); - reservations.HasNextPage.Should().Be(false); - - var reservationInfo = reservations.Items.Single(); - - reservationInfo.ReservationId.Should().Be(createdReservationId); - reservationInfo.Description.Should().StartWith("Created tentative reservation with number"); - })) - ); - } + reservationInfo.ReservationId.Should().Be(ctx.GetCreatedId()); + reservationInfo.Description.Should().StartWith("Created tentative reservation with number"); + }) + ); private readonly Guid SeatId = Guid.NewGuid(); diff --git a/Sample/Warehouse/Warehouse.Api.Tests/Products/GettingProductDetails/GetProductDetailsTests.cs b/Sample/Warehouse/Warehouse.Api.Tests/Products/GettingProductDetails/GetProductDetailsTests.cs index 2e1cd6270..ac7214cdf 100644 --- a/Sample/Warehouse/Warehouse.Api.Tests/Products/GettingProductDetails/GetProductDetailsTests.cs +++ b/Sample/Warehouse/Warehouse.Api.Tests/Products/GettingProductDetails/GetProductDetailsTests.cs @@ -14,22 +14,22 @@ public class GetProductDetailsTests: IClassFixture [Fact] public Task ValidRequest_With_NoParams_ShouldReturn_200() => - API.Given(URI($"/api/products/{API.ExistingProduct.Id}")) - .When(GET) + API.Given() + .When(GET, URI($"/api/products/{API.ExistingProduct.Id}")) .Then(OK, RESPONSE_BODY(API.ExistingProduct)); [Theory] [InlineData(12)] [InlineData("not-a-guid")] public Task InvalidGuidId_ShouldReturn_404(object invalidId) => - API.Given(URI($"/api/products/{invalidId}")) - .When(GET) + API.Given() + .When(GET, URI($"/api/products/{invalidId}")) .Then(NOT_FOUND); [Fact] public Task NotExistingId_ShouldReturn_404() => - API.Given(URI($"/api/products/{Guid.NewGuid()}")) - .When(GET) + API.Given() + .When(GET, URI($"/api/products/{Guid.NewGuid()}")) .Then(NOT_FOUND); } @@ -43,14 +43,13 @@ public class GetProductDetailsFixture: ApiSpecification, IAsyncLifetime public async Task InitializeAsync() { var registerProduct = new RegisterProductRequest("IN11111", "ValidName", "ValidDescription"); - var registerResponse = await Send( - new ApiRequest(POST, URI("/api/products"), BODY(registerProduct)) - ); - - await CREATED(registerResponse); + var productId = await Given() + .When(POST, URI("/api/products"), BODY(registerProduct)) + .Then(CREATED) + .GetCreatedId(); var (sku, name, description) = registerProduct; - ExistingProduct = new ProductDetails(registerResponse.GetCreatedId(), sku!, name!, description); + ExistingProduct = new ProductDetails(productId, sku!, name!, description); } public Task DisposeAsync() => Task.CompletedTask; diff --git a/Sample/Warehouse/Warehouse.Api.Tests/Products/GettingProducts/GetProductsTests.cs b/Sample/Warehouse/Warehouse.Api.Tests/Products/GettingProducts/GetProductsTests.cs index 1a4e596b2..5aa3c3574 100644 --- a/Sample/Warehouse/Warehouse.Api.Tests/Products/GettingProducts/GetProductsTests.cs +++ b/Sample/Warehouse/Warehouse.Api.Tests/Products/GettingProducts/GetProductsTests.cs @@ -15,8 +15,8 @@ public class GetProductsTests: IClassFixture [Fact] public Task ValidRequest_With_NoParams_ShouldReturn_200() => - API.Given(URI("/api/products/")) - .When(GET) + API.Given() + .When(GET, URI("/api/products/")) .Then(OK, RESPONSE_BODY(API.RegisteredProducts)); [Fact] @@ -25,8 +25,8 @@ public Task ValidRequest_With_Filter_ShouldReturn_SubsetOfRecords() var registeredProduct = API.RegisteredProducts.First(); var filter = registeredProduct.Sku[1..]; - return API.Given(URI($"/api/products/?filter={filter}")) - .When(GET) + return API.Given() + .When(GET, URI($"/api/products/?filter={filter}")) .Then(OK, RESPONSE_BODY(new List { registeredProduct })); } @@ -41,23 +41,23 @@ public Task ValidRequest_With_Paging_ShouldReturn_PageOfRecords() .Take(pageSize) .ToList(); - return API.Given(URI($"/api/products/?page={page}&pageSize={pageSize}")) - .When(GET) + return API.Given() + .When(GET, URI($"/api/products/?page={page}&pageSize={pageSize}")) .Then(OK, RESPONSE_BODY(pagedRecords)); } [Fact] public Task NegativePage_ShouldReturn_400() => - API.Given(URI($"/api/products/?page={-20}")) - .When(GET) + API.Given() + .When(GET, URI($"/api/products/?page={-20}")) .Then(BAD_REQUEST); [Theory] [InlineData(0)] [InlineData(-20)] public Task NegativeOrZeroPageSize_ShouldReturn_400(int pageSize) => - API.Given(URI($"/api/products/?pageSize={pageSize}")) - .When(GET) + API.Given() + .When(GET, URI($"/api/products/?pageSize={pageSize}")) .Then(BAD_REQUEST); } @@ -79,13 +79,10 @@ public async Task InitializeAsync() foreach (var registerProduct in productsToRegister) { - var registerResponse = await Send( - new ApiRequest(POST, URI("/api/products"), BODY(registerProduct)) - ); - - await CREATED(registerResponse); - - var createdId = registerResponse.GetCreatedId(); + var createdId = await Given() + .When(POST, URI("/api/products"), BODY(registerProduct)) + .Then(CREATED) + .GetCreatedId(); var (sku, name, _) = registerProduct; RegisteredProducts.Add(new ProductListItem(createdId, sku!, name!));