diff --git a/Sample/Helpdesk.Wolverine/Helpdesk.Api.Tests/Incidents/AcknowledgeResolutionIncidentTests.cs b/Sample/Helpdesk.Wolverine/Helpdesk.Api.Tests/Incidents/AcknowledgeResolutionIncidentTests.cs index 83b2bb944..2d11f02a2 100644 --- a/Sample/Helpdesk.Wolverine/Helpdesk.Api.Tests/Incidents/AcknowledgeResolutionIncidentTests.cs +++ b/Sample/Helpdesk.Wolverine/Helpdesk.Api.Tests/Incidents/AcknowledgeResolutionIncidentTests.cs @@ -1,38 +1,28 @@ +using Alba; using Helpdesk.Api.Incidents; using Helpdesk.Api.Incidents.AcknowledgingResolution; using Helpdesk.Api.Tests.Incidents.Fixtures; using Xunit; -using static Ogooreck.API.ApiSpecification; namespace Helpdesk.Api.Tests.Incidents; -public class AcknowledgeResolutionIncidentTests(ApiWithResolvedIncident API): - IClassFixture +public class AcknowledgeResolutionIncidentTests(AppFixture fixture): ApiWithResolvedIncident(fixture) { [Fact] [Trait("Category", "Acceptance")] - public Task ResolveCommand_Succeeds() => - API - .Given() - .When( - POST, - URI($"/api/customers/{API.Incident.CustomerId}/incidents/{API.Incident.Id}/acknowledge"), - BODY(new AcknowledgeResolution(API.Incident.Id)), - HEADERS(IF_MATCH(2)) - ) - .Then(OK) + public async Task ResolveCommand_Succeeds() + { + await Host.Scenario(x => + { + x.Post.Json(new AcknowledgeResolution(Incident.Id, Incident.CustomerId, Incident.Version)) + .ToUrl($"/api/customers/{Incident.CustomerId}/incidents/{Incident.Id}/acknowledge"); - .And() + x.StatusCodeShouldBeOk(); + }); - .When(GET, URI($"/api/incidents/{API.Incident.Id}")) - .Then( - OK, - RESPONSE_BODY( - API.Incident with - { - Status = IncidentStatus.ResolutionAcknowledgedByCustomer, - Version = 3 - } - ) - ); + await Host.IncidentDetailsShouldBe(Incident with + { + Status = IncidentStatus.ResolutionAcknowledgedByCustomer, Version = 3 + }); + } } diff --git a/Sample/Helpdesk.Wolverine/Helpdesk.Api.Tests/Incidents/AssignAgentTests.cs b/Sample/Helpdesk.Wolverine/Helpdesk.Api.Tests/Incidents/AssignAgentTests.cs index 4bf97d84a..be482700d 100644 --- a/Sample/Helpdesk.Wolverine/Helpdesk.Api.Tests/Incidents/AssignAgentTests.cs +++ b/Sample/Helpdesk.Wolverine/Helpdesk.Api.Tests/Incidents/AssignAgentTests.cs @@ -1,34 +1,25 @@ +using Alba; using Helpdesk.Api.Incidents.AssigningAgent; using Helpdesk.Api.Tests.Incidents.Fixtures; using Xunit; -using static Ogooreck.API.ApiSpecification; namespace Helpdesk.Api.Tests.Incidents; -public class AssignAgentToIncidentTests(ApiWithLoggedIncident API): - IClassFixture +public class AssignAgentToIncidentTests(AppFixture fixture): ApiWithLoggedIncident(fixture) { [Fact] [Trait("Category", "Acceptance")] public async Task AssignAgentCommand_ChangesIncidentCategory() { - await API - .Given() - .When( - POST, - URI($"/api/agents/{agentId}/incidents/{API.Incident.Id}/assign"), - HEADERS(IF_MATCH(1)), - BODY(new AssignAgentToIncident(API.Incident.Id)) - ) - .Then(OK) - .And() - .When(GET, URI($"/api/incidents/{API.Incident.Id}")) - .Then( - OK, - RESPONSE_BODY( - API.Incident with { AgentId = agentId, Version = 2 } - ) - ); + await Host.Scenario(x => + { + x.Post.Json(new AssignAgentToIncident(Incident.Id, Incident.Version)) + .ToUrl($"/api/agents/{agentId}/incidents/{Incident.Id}/assign"); + + x.StatusCodeShouldBeOk(); + }); + + await Host.IncidentDetailsShouldBe(Incident with { AgentId = agentId, Version = 2 }); } private readonly Guid agentId = Guid.NewGuid(); diff --git a/Sample/Helpdesk.Wolverine/Helpdesk.Api.Tests/Incidents/CategoriseIncidentTests.cs b/Sample/Helpdesk.Wolverine/Helpdesk.Api.Tests/Incidents/CategoriseIncidentTests.cs index a189aad7f..75411a432 100644 --- a/Sample/Helpdesk.Wolverine/Helpdesk.Api.Tests/Incidents/CategoriseIncidentTests.cs +++ b/Sample/Helpdesk.Wolverine/Helpdesk.Api.Tests/Incidents/CategoriseIncidentTests.cs @@ -1,38 +1,27 @@ +using Alba; using Bogus; using Helpdesk.Api.Incidents; using Helpdesk.Api.Incidents.Categorising; using Helpdesk.Api.Tests.Incidents.Fixtures; using Xunit; -using static Ogooreck.API.ApiSpecification; namespace Helpdesk.Api.Tests.Incidents; -public class CategoriseIncidentTests(ApiWithLoggedIncident API): - IClassFixture +public class CategoriseIncidentTests(AppFixture fixture): ApiWithLoggedIncident(fixture) { [Fact] [Trait("Category", "Acceptance")] public async Task CategoriseCommand_ChangesIncidentCategory() { - await API - .Given() - .When( - POST, - URI($"/api/agents/{agentId}/incidents/{API.Incident.Id}/category"), - BODY(new CategoriseIncident(API.Incident.Id, category)), - HEADERS(IF_MATCH(1)) - ) - .Then(OK); + await Host.Scenario(x => + { + x.Post.Json(new CategoriseIncident(Incident.Id, category, Incident.Version)) + .ToUrl($"/api/agents/{agentId}/incidents/{Incident.Id}/category"); - await API - .Given() - .When(GET, URI($"/api/incidents/{API.Incident.Id}")) - .Then( - OK, - RESPONSE_BODY( - API.Incident with { Category = category, Version = 2 } - ) - ); + x.StatusCodeShouldBeOk(); + }); + + await Host.IncidentDetailsShouldBe(Incident with { Category = category, Version = 2 }); } private readonly Guid agentId = Guid.NewGuid(); diff --git a/Sample/Helpdesk.Wolverine/Helpdesk.Api.Tests/Incidents/CloseIncidentTests.cs b/Sample/Helpdesk.Wolverine/Helpdesk.Api.Tests/Incidents/CloseIncidentTests.cs index e68d50b9a..d13844645 100644 --- a/Sample/Helpdesk.Wolverine/Helpdesk.Api.Tests/Incidents/CloseIncidentTests.cs +++ b/Sample/Helpdesk.Wolverine/Helpdesk.Api.Tests/Incidents/CloseIncidentTests.cs @@ -1,37 +1,26 @@ +using Alba; using Helpdesk.Api.Incidents; using Helpdesk.Api.Incidents.Closing; using Helpdesk.Api.Tests.Incidents.Fixtures; using Xunit; -using static Ogooreck.API.ApiSpecification; namespace Helpdesk.Api.Tests.Incidents; -public class CloseIncidentTests(ApiWithAcknowledgedIncident API): - IClassFixture +public class CloseIncidentTests(AppFixture fixture): ApiWithAcknowledgedIncident(fixture) { [Fact] [Trait("Category", "Acceptance")] public async Task ResolveCommand_Succeeds() { - await API - .Given() - .When( - POST, - URI($"/api/agents/{agentId}/incidents/{API.Incident.Id}/close"), - BODY(new CloseIncident(API.Incident.Id)), - HEADERS(IF_MATCH(3)) - ) - .Then(OK); + await Host.Scenario(x => + { + x.Post.Json(new CloseIncident(Incident.Id, Incident.Version)) + .ToUrl($"/api/agents/{agentId}/incidents/{Incident.Id}/close"); - await API - .Given() - .When(GET, URI($"/api/incidents/{API.Incident.Id}")) - .Then( - OK, - RESPONSE_BODY( - API.Incident with { Status = IncidentStatus.Closed, Version = 4 } - ) - ); + x.StatusCodeShouldBeOk(); + }); + + await Host.IncidentDetailsShouldBe(Incident with { Status = IncidentStatus.Closed, Version = 4 }); } private Guid agentId = Guid.NewGuid(); diff --git a/Sample/Helpdesk.Wolverine/Helpdesk.Api.Tests/Incidents/Fixtures/ApiWithAcknowledgedIncident.cs b/Sample/Helpdesk.Wolverine/Helpdesk.Api.Tests/Incidents/Fixtures/ApiWithAcknowledgedIncident.cs index 2fff3608f..444a9c601 100644 --- a/Sample/Helpdesk.Wolverine/Helpdesk.Api.Tests/Incidents/Fixtures/ApiWithAcknowledgedIncident.cs +++ b/Sample/Helpdesk.Wolverine/Helpdesk.Api.Tests/Incidents/Fixtures/ApiWithAcknowledgedIncident.cs @@ -1,18 +1,13 @@ using Helpdesk.Api.Incidents.GettingDetails; -using Ogooreck.API; using Xunit; namespace Helpdesk.Api.Tests.Incidents.Fixtures; -public class ApiWithAcknowledgedIncident: ApiSpecification, IAsyncLifetime +public class ApiWithAcknowledgedIncident(AppFixture fixture): IntegrationContext(fixture), IAsyncLifetime { - public async Task InitializeAsync() - { - Incident = await this.AcknowledgedIncident(); - } + public override async Task InitializeAsync() => + Incident = await Host.AcknowledgedIncident(); public IncidentDetails Incident { get; set; } = default!; - - public Task DisposeAsync() => Task.CompletedTask; } diff --git a/Sample/Helpdesk.Wolverine/Helpdesk.Api.Tests/Incidents/Fixtures/ApiWithLoggedIncident.cs b/Sample/Helpdesk.Wolverine/Helpdesk.Api.Tests/Incidents/Fixtures/ApiWithLoggedIncident.cs index 479fd97a1..f3c6b8aad 100644 --- a/Sample/Helpdesk.Wolverine/Helpdesk.Api.Tests/Incidents/Fixtures/ApiWithLoggedIncident.cs +++ b/Sample/Helpdesk.Wolverine/Helpdesk.Api.Tests/Incidents/Fixtures/ApiWithLoggedIncident.cs @@ -1,15 +1,12 @@ using Helpdesk.Api.Incidents.GettingDetails; -using Ogooreck.API; using Xunit; namespace Helpdesk.Api.Tests.Incidents.Fixtures; -public class ApiWithLoggedIncident: ApiSpecification, IAsyncLifetime +public class ApiWithLoggedIncident(AppFixture fixture): IntegrationContext(fixture), IAsyncLifetime { - public async Task InitializeAsync() - { - Incident = await this.LoggedIncident(); - } + public override async Task InitializeAsync() => + Incident = await Host.LoggedIncident(); + public IncidentDetails Incident { get; protected set; } = default!; - public Task DisposeAsync() => Task.CompletedTask; } diff --git a/Sample/Helpdesk.Wolverine/Helpdesk.Api.Tests/Incidents/Fixtures/ApiWithResolvedIncident.cs b/Sample/Helpdesk.Wolverine/Helpdesk.Api.Tests/Incidents/Fixtures/ApiWithResolvedIncident.cs index db57c043c..ec3e0d8f1 100644 --- a/Sample/Helpdesk.Wolverine/Helpdesk.Api.Tests/Incidents/Fixtures/ApiWithResolvedIncident.cs +++ b/Sample/Helpdesk.Wolverine/Helpdesk.Api.Tests/Incidents/Fixtures/ApiWithResolvedIncident.cs @@ -1,18 +1,13 @@ using Helpdesk.Api.Incidents.GettingDetails; -using Ogooreck.API; using Xunit; namespace Helpdesk.Api.Tests.Incidents.Fixtures; -public class ApiWithResolvedIncident: ApiSpecification, IAsyncLifetime +public class ApiWithResolvedIncident(AppFixture fixture): IntegrationContext(fixture), IAsyncLifetime { - public async Task InitializeAsync() - { - Incident = await this.ResolvedIncident(); - } + public override async Task InitializeAsync() => + Incident = await Host.ResolvedIncident(); public IncidentDetails Incident { get; set; } = default!; - - public Task DisposeAsync() => Task.CompletedTask; } diff --git a/Sample/Helpdesk.Wolverine/Helpdesk.Api.Tests/Incidents/Fixtures/Scenarios.cs b/Sample/Helpdesk.Wolverine/Helpdesk.Api.Tests/Incidents/Fixtures/Scenarios.cs index 5b9f1fc33..2bae11523 100644 --- a/Sample/Helpdesk.Wolverine/Helpdesk.Api.Tests/Incidents/Fixtures/Scenarios.cs +++ b/Sample/Helpdesk.Wolverine/Helpdesk.Api.Tests/Incidents/Fixtures/Scenarios.cs @@ -1,12 +1,14 @@ +using Alba; using Bogus; using Bogus.DataSets; +using FluentAssertions; using Helpdesk.Api.Incidents; using Helpdesk.Api.Incidents.AcknowledgingResolution; using Helpdesk.Api.Incidents.GettingDetails; using Helpdesk.Api.Incidents.Logging; using Helpdesk.Api.Incidents.Resolving; -using Ogooreck.API; -using static Ogooreck.API.ApiSpecification; +using Wolverine.Http; +using Xunit; namespace Helpdesk.Api.Tests.Incidents.Fixtures; @@ -16,7 +18,7 @@ public static class Scenarios private static readonly Lorem loremIpsum = new(); public static async Task LoggedIncident( - this ApiSpecification api + this IAlbaHost api ) { var customerId = Guid.NewGuid(); @@ -30,84 +32,131 @@ this ApiSpecification api ); var incidentDescription = loremIpsum.Sentence(); - var response = await api.Scenario( - api.LogIncident(customerId, contact, incidentDescription), - r => api.GetIncidentDetails(r.GetCreatedId()) - ); + var result = await api.LogIncident(customerId, contact, incidentDescription); - return await response.GetResultFromJson(); + result = await api.GetIncidentDetails(await result.GetCreatedId()); + var incident = await result.ReadAsJsonAsync(); + incident.Should().NotBeNull(); + return incident!; } public static async Task ResolvedIncident( - this ApiSpecification api + this IAlbaHost api ) { var agentId = Guid.NewGuid(); var resolvedType = faker.PickRandom(); var incident = await api.LoggedIncident(); - return await api.Scenario( - api.ResolveIncident(incident.Id, agentId, resolvedType), - _ => api.GetIncidentDetails(incident.Id) - ).GetResponseBody(); + await api.ResolveIncident(incident.Id, agentId, resolvedType, incident.Version); + + var result = await api.GetIncidentDetails(incident.Id); + incident = await result.ReadAsJsonAsync(); + incident.Should().NotBeNull(); + return incident!; } public static async Task AcknowledgedIncident( - this ApiSpecification api + this IAlbaHost api ) { var incident = await api.ResolvedIncident(); - return await api.Scenario( - api.AcknowledgeIncident(incident.Id, incident.CustomerId), - _ => api.GetIncidentDetails(incident.Id) - ).GetResponseBody(); + await api.AcknowledgeIncident(incident.Id, incident.CustomerId, incident.Version); + + var result = await api.GetIncidentDetails(incident.Id); + incident = await result.ReadAsJsonAsync(); + incident.Should().NotBeNull(); + return incident!; } - private static Task LogIncident( - this ApiSpecification api, + private static Task LogIncident( + this IAlbaHost api, Guid customerId, Contact contact, string incidentDescription ) => - api.Given() - .When(POST, URI($"api/customers/{customerId}/incidents/"), BODY(new LogIncident(customerId, contact, incidentDescription))) - .Then(CREATED_WITH_DEFAULT_HEADERS(locationHeaderPrefix: "/api/incidents/")); + api.Scenario(x => + { + x.Post.Url($"/api/customers/{customerId}/incidents/"); + x.Post.Json(new LogIncident(customerId, contact, incidentDescription)); + + x.StatusCodeShouldBe(201); + }); - private static Task ResolveIncident( - this ApiSpecification api, + private static Task ResolveIncident( + this IAlbaHost api, Guid incidentId, Guid agentId, - ResolutionType resolutionType - ) where T : class => - api.Given() - .When( - POST, - URI($"/api/agents/{agentId}/incidents/{incidentId}/resolve"), - BODY(new ResolveIncident(incidentId, agentId, resolutionType)), - HEADERS(IF_MATCH(1)) - ) - .Then(OK); - - private static Task AcknowledgeIncident( - this ApiSpecification api, + ResolutionType resolutionType, + int expectedVersion + ) => + api.Scenario(x => + { + x.Post.Url($"/api/agents/{agentId}/incidents/{incidentId}/resolve"); + x.Post.Json(new ResolveIncident(incidentId, agentId, resolutionType, expectedVersion)); + + x.StatusCodeShouldBeOk(); + }); + + private static Task AcknowledgeIncident( + this IAlbaHost api, Guid incidentId, - Guid customerId - ) where T : class => - api.Given() - .When( - POST, - URI($"/api/customers/{customerId}/incidents/{incidentId}/acknowledge"), - BODY(new AcknowledgeResolution(incidentId)), - HEADERS(IF_MATCH(2)) - ) - .Then(OK); - - private static Task GetIncidentDetails( - this ApiSpecification api, + Guid customerId, + int expectedVersion + ) => + api.Scenario(x => + { + x.Post.Url($"/api/customers/{customerId}/incidents/{incidentId}/acknowledge"); + x.Post.Json(new AcknowledgeResolution(incidentId, customerId, expectedVersion)); + + x.StatusCodeShouldBeOk(); + }); + + public static Task GetIncidentDetails( + this IAlbaHost api, Guid incidentId ) => - api.Given() - .When(GET, URI($"/api/incidents/{incidentId}")) - .Then(OK); + api.Scenario(x => + { + x.Get.Url($"/api/incidents/{incidentId}"); + + x.StatusCodeShouldBeOk(); + }); + + public static async Task IncidentDetailsShouldBe( + this IAlbaHost api, + IncidentDetails incident + ) + { + var result = await api.GetIncidentDetails(incident.Id); + + var updated = await result.ReadAsJsonAsync(); + updated.Should().BeEquivalentTo(incident); + + return result; + } + + public static async Task GetCreatedId(this IScenarioResult result) + { + var response = await result.ReadAsJsonAsync(); + response.Should().NotBeNull(); + response!.Url.Should().StartWith("/api/incidents/"); + + return response.GetCreatedId(); + } + + public static Guid GetCreatedId(this CreationResponse response) + { + response.Url.Should().StartWith("/api/incidents/"); + + var createdId = response.Url["/api/incidents/".Length..]; + + if (!Guid.TryParse(createdId, out var guid)) + { + Assert.Fail("Wrong Created Id"); + } + + return guid; + } } diff --git a/Sample/Helpdesk.Wolverine/Helpdesk.Api.Tests/Incidents/LogIncidentsTests.cs b/Sample/Helpdesk.Wolverine/Helpdesk.Api.Tests/Incidents/LogIncidentsTests.cs index 45896b1a9..87dcb9c31 100644 --- a/Sample/Helpdesk.Wolverine/Helpdesk.Api.Tests/Incidents/LogIncidentsTests.cs +++ b/Sample/Helpdesk.Wolverine/Helpdesk.Api.Tests/Incidents/LogIncidentsTests.cs @@ -1,14 +1,12 @@ -using Alba; using Bogus; using Bogus.DataSets; using FluentAssertions; using Helpdesk.Api.Incidents; using Helpdesk.Api.Incidents.GettingDetails; using Helpdesk.Api.Incidents.Logging; +using Helpdesk.Api.Tests.Incidents.Fixtures; using Xunit; -using Ogooreck.API; using Wolverine.Http; -using static Ogooreck.API.ApiSpecification; namespace Helpdesk.Api.Tests.Incidents; @@ -17,9 +15,7 @@ public class LogIncidentsTests(AppFixture fixture): IntegrationContext(fixture) [Fact] public async Task LogIncident_ShouldSucceed() { - // POST a CategoriseIncident to the HTTP endpoint, wait until all - // cascading Wolverine processing is complete - var result = await Host.Scenario(x => + var result = await Host.Scenario(x => { x.Post.Json(new LogIncident(CustomerId, Contact, IncidentDescription)) .ToUrl($"/api/customers/{CustomerId}/incidents/"); @@ -31,22 +27,19 @@ public async Task LogIncident_ShouldSucceed() response.Should().NotBeNull(); response!.Url.Should().StartWith("/api/incidents/"); - result = await Host.Scenario(x => - { - x.Get.Url(response.Url); - - x.StatusCodeShouldBeOk(); - }); - var incident = await result.ReadAsJsonAsync(); - incident.Should().NotBeNull(); - incident!.CustomerId.Should().Be(CustomerId); - incident.Status.Should().Be(IncidentStatus.Pending); - incident.Notes.Should().BeEmpty(); - incident.Category.Should().BeNull(); - incident.Priority.Should().BeNull(); - incident.AgentId.Should().BeNull(); - incident.Version.Should().Be(1); + await Host.IncidentDetailsShouldBe( + new IncidentDetails( + response.GetCreatedId(), + CustomerId, + IncidentStatus.Pending, + [], + null, + null, + null, + 1 + ) + ); } private readonly Guid CustomerId = Guid.NewGuid(); diff --git a/Sample/Helpdesk.Wolverine/Helpdesk.Api.Tests/Incidents/PrioritiseIncidentTests.cs b/Sample/Helpdesk.Wolverine/Helpdesk.Api.Tests/Incidents/PrioritiseIncidentTests.cs index a8ae67e64..0f16ea603 100644 --- a/Sample/Helpdesk.Wolverine/Helpdesk.Api.Tests/Incidents/PrioritiseIncidentTests.cs +++ b/Sample/Helpdesk.Wolverine/Helpdesk.Api.Tests/Incidents/PrioritiseIncidentTests.cs @@ -1,42 +1,27 @@ +using Alba; using Bogus; using Helpdesk.Api.Incidents; using Helpdesk.Api.Incidents.Prioritising; using Helpdesk.Api.Tests.Incidents.Fixtures; using Xunit; -using static Ogooreck.API.ApiSpecification; namespace Helpdesk.Api.Tests.Incidents; -public class PrioritiseIncidentTests(ApiWithLoggedIncident API): - IClassFixture +public class PrioritiseIncidentTests(AppFixture fixture): ApiWithLoggedIncident(fixture) { [Fact] [Trait("Category", "Acceptance")] public async Task PrioritiseCommand_ChangesIncidentPriority() { - await API - .Given() - .When( - POST, - URI($"/api/agents/{agentId}/incidents/{API.Incident.Id}/priority"), - BODY(new PrioritiseIncident(API.Incident.Id, agentId, priority)), - HEADERS(IF_MATCH(1)) - ) - .Then(OK); + await Host.Scenario(x => + { + x.Post.Json(new PrioritiseIncident(Incident.Id, agentId, priority, Incident.Version)) + .ToUrl($"/api/agents/{agentId}/incidents/{Incident.Id}/priority"); - await API - .Given() - .When(GET, URI($"/api/incidents/{API.Incident.Id}")) - .Then( - OK, - RESPONSE_BODY( - API.Incident with - { - Priority = priority, - Version = 2 - } - ) - ); + x.StatusCodeShouldBeOk(); + }); + + await Host.IncidentDetailsShouldBe(Incident with { Priority = priority, Version = 2 }); } private readonly Guid agentId = Guid.NewGuid(); diff --git a/Sample/Helpdesk.Wolverine/Helpdesk.Api.Tests/Incidents/RecordAgentResponseToIncidentTests.cs b/Sample/Helpdesk.Wolverine/Helpdesk.Api.Tests/Incidents/RecordAgentResponseToIncidentTests.cs index 5977df159..e11f05089 100644 --- a/Sample/Helpdesk.Wolverine/Helpdesk.Api.Tests/Incidents/RecordAgentResponseToIncidentTests.cs +++ b/Sample/Helpdesk.Wolverine/Helpdesk.Api.Tests/Incidents/RecordAgentResponseToIncidentTests.cs @@ -1,46 +1,35 @@ +using Alba; using Bogus; using Bogus.DataSets; using Helpdesk.Api.Incidents.GettingDetails; using Helpdesk.Api.Incidents.RecordingAgentResponse; using Helpdesk.Api.Tests.Incidents.Fixtures; using Xunit; -using static Ogooreck.API.ApiSpecification; namespace Helpdesk.Api.Tests.Incidents; -public class RecordAgentResponseToIncidentTests(ApiWithLoggedIncident api): - IClassFixture +public class RecordAgentResponseToIncidentTests(AppFixture fixture): ApiWithLoggedIncident(fixture) { [Fact] [Trait("Category", "Acceptance")] public async Task RecordAgentResponseCommand_RecordsResponse() { - await api - .Given() - .When( - POST, - URI($"/api/agents/{agentId}/incidents/{api.Incident.Id}/responses"), - BODY(new RecordAgentResponseToIncident(api.Incident.Id, agentId, content, visibleToCustomer)), - HEADERS(IF_MATCH(1)) - ) - .Then(OK); + await Host.Scenario(x => + { + x.Post.Json(new RecordAgentResponseToIncident(Incident.Id, agentId, content, visibleToCustomer, Incident.Version)) + .ToUrl($"/api/agents/{agentId}/incidents/{Incident.Id}/responses"); - await api - .Given() - .When(GET, URI($"/api/incidents/{api.Incident.Id}")) - .Then( - OK, - RESPONSE_BODY( - api.Incident with - { - Notes = new[] - { - new IncidentNote(IncidentNoteType.FromAgent, agentId, content, visibleToCustomer) - }, - Version = 2 - } - ) - ); + x.StatusCodeShouldBeOk(); + }); + + await Host.IncidentDetailsShouldBe(Incident with + { + Notes = + [ + new IncidentNote(IncidentNoteType.FromAgent, agentId, content, visibleToCustomer) + ], + Version = 2 + }); } private readonly Guid agentId = Guid.NewGuid(); diff --git a/Sample/Helpdesk.Wolverine/Helpdesk.Api.Tests/Incidents/RecordCustomerResponseToIncidentTests.cs b/Sample/Helpdesk.Wolverine/Helpdesk.Api.Tests/Incidents/RecordCustomerResponseToIncidentTests.cs index abd0672cd..0321e2bd1 100644 --- a/Sample/Helpdesk.Wolverine/Helpdesk.Api.Tests/Incidents/RecordCustomerResponseToIncidentTests.cs +++ b/Sample/Helpdesk.Wolverine/Helpdesk.Api.Tests/Incidents/RecordCustomerResponseToIncidentTests.cs @@ -1,43 +1,32 @@ +using Alba; using Bogus.DataSets; using Helpdesk.Api.Incidents.GettingDetails; using Helpdesk.Api.Incidents.RecordingCustomerResponse; using Helpdesk.Api.Tests.Incidents.Fixtures; using Xunit; -using static Ogooreck.API.ApiSpecification; namespace Helpdesk.Api.Tests.Incidents; -public class RecordCustomerResponseToIncidentTests(ApiWithLoggedIncident API): - IClassFixture +public class RecordCustomerResponseToIncidentTests(AppFixture fixture): ApiWithLoggedIncident(fixture) { [Fact] [Trait("Category", "Acceptance")] public async Task RecordCustomerResponseCommand_RecordsResponse() { - await API - .Given() - .When( - POST, - URI($"/api/customers/{customerId}/incidents/{API.Incident.Id}/responses"), - BODY(new RecordCustomerResponseToIncident(API.Incident.Id, customerId, content)), - HEADERS(IF_MATCH(1)) - ) - .Then(OK); + await Host.Scenario(x => + { + x.Post.Json(new RecordCustomerResponseToIncident(Incident.Id, customerId, content, Incident.Version)) + .ToUrl($"/api/customers/{customerId}/incidents/{Incident.Id}/responses"); - await API - .Given() - .When(GET, URI($"/api/incidents/{API.Incident.Id}")) - .Then( - OK, - RESPONSE_BODY( - API.Incident with - { - Notes = - [new IncidentNote(IncidentNoteType.FromCustomer, customerId, content, true)], - Version = 2 - } - ) - ); + x.StatusCodeShouldBeOk(); + }); + + await Host.IncidentDetailsShouldBe(Incident with + { + Notes = + [new IncidentNote(IncidentNoteType.FromCustomer, customerId, content, true)], + Version = 2 + }); } private readonly Guid customerId = Guid.NewGuid(); diff --git a/Sample/Helpdesk.Wolverine/Helpdesk.Api.Tests/Incidents/ResolveIncidentTests.cs b/Sample/Helpdesk.Wolverine/Helpdesk.Api.Tests/Incidents/ResolveIncidentTests.cs index 097d2d45f..a954a4e12 100644 --- a/Sample/Helpdesk.Wolverine/Helpdesk.Api.Tests/Incidents/ResolveIncidentTests.cs +++ b/Sample/Helpdesk.Wolverine/Helpdesk.Api.Tests/Incidents/ResolveIncidentTests.cs @@ -1,41 +1,27 @@ +using Alba; using Bogus; using Helpdesk.Api.Incidents; using Helpdesk.Api.Incidents.Resolving; using Helpdesk.Api.Tests.Incidents.Fixtures; using Xunit; -using static Ogooreck.API.ApiSpecification; namespace Helpdesk.Api.Tests.Incidents; -public class ResolveIncidentTests(ApiWithLoggedIncident API): - IClassFixture +public class ResolveIncidentTests(AppFixture fixture): ApiWithLoggedIncident(fixture) { [Fact] [Trait("Category", "Acceptance")] public async Task ResolveCommand_Succeeds() { - await API - .Given() - .When( - POST, - URI($"/api/agents/{agentId}/incidents/{API.Incident.Id}/resolve"), - BODY(new ResolveIncident(API.Incident.Id, agentId, resolutionType)), - HEADERS(IF_MATCH(1)) - ) - .Then(OK); + await Host.Scenario(x => + { + x.Post.Json(new ResolveIncident(Incident.Id, agentId, resolutionType, Incident.Version)) + .ToUrl($"/api/agents/{agentId}/incidents/{Incident.Id}/resolve"); - await API - .Given() - .When( - GET, - URI($"/api/incidents/{API.Incident.Id}") - ) - .Then( - OK, - RESPONSE_BODY( - API.Incident with { Status = IncidentStatus.Resolved, Version = 2 } - ) - ); + x.StatusCodeShouldBeOk(); + }); + + await Host.IncidentDetailsShouldBe(Incident with { Status = IncidentStatus.Resolved, Version = 2 }); } private readonly Guid agentId = Guid.NewGuid(); diff --git a/Sample/Helpdesk.Wolverine/Helpdesk.Api.Tests/IntegrationContext.cs b/Sample/Helpdesk.Wolverine/Helpdesk.Api.Tests/IntegrationContext.cs index e4fe941cc..3dba521a8 100644 --- a/Sample/Helpdesk.Wolverine/Helpdesk.Api.Tests/IntegrationContext.cs +++ b/Sample/Helpdesk.Wolverine/Helpdesk.Api.Tests/IntegrationContext.cs @@ -1,9 +1,7 @@ using Alba; using Alba.Security; using FluentAssertions; -using JasperFx.Core; using Marten; -using Marten.Schema; using Microsoft.Extensions.DependencyInjection; using Oakton; using Wolverine; @@ -83,7 +81,7 @@ public abstract class IntegrationContext(AppFixture fixture): IAsyncLifetime public IDocumentStore Store => fixture.Host.Services.GetRequiredService(); - async Task IAsyncLifetime.InitializeAsync() + public virtual async Task InitializeAsync() { // Using Marten, wipe out all data and reset the state // back to exactly what we described in InitialAccountData diff --git a/Sample/Helpdesk.Wolverine/Helpdesk.Api/Incidents/AcknowledgingResolution/AcknowledgeResolution.cs b/Sample/Helpdesk.Wolverine/Helpdesk.Api/Incidents/AcknowledgingResolution/AcknowledgeResolution.cs index 7a4368a23..fce76303d 100644 --- a/Sample/Helpdesk.Wolverine/Helpdesk.Api/Incidents/AcknowledgingResolution/AcknowledgeResolution.cs +++ b/Sample/Helpdesk.Wolverine/Helpdesk.Api/Incidents/AcknowledgingResolution/AcknowledgeResolution.cs @@ -1,4 +1,3 @@ -using Microsoft.AspNetCore.Mvc; using Wolverine.Http; using Wolverine.Marten; using static Microsoft.AspNetCore.Http.TypedResults; @@ -11,21 +10,20 @@ public static class AcknowledgeResolutionEndpoint [WolverinePost("/api/customers/{customerId:guid}/incidents/{incidentId:guid}/acknowledge")] public static (IResult, Events) AcknowledgeResolution ( - AcknowledgeResolution request, + AcknowledgeResolution command, Incident incident, - [FromRoute] Guid agentId, - [FromRoute] Guid incidentId, - DateTimeOffset now ) { if (incident.Status is not IncidentStatus.Resolved) throw new InvalidOperationException("Only resolved incident can be acknowledged"); - return (Ok(), [new ResolutionAcknowledgedByCustomer(incidentId, agentId, now)]); + return (Ok(), [new ResolutionAcknowledgedByCustomer(incident.Id, command.CustomerId, now)]); } } public record AcknowledgeResolution( - Guid IncidentId // TODO: meh + Guid IncidentId, + Guid CustomerId, + int Version ); diff --git a/Sample/Helpdesk.Wolverine/Helpdesk.Api/Incidents/AssigningAgent/AssignAgent.cs b/Sample/Helpdesk.Wolverine/Helpdesk.Api/Incidents/AssigningAgent/AssignAgent.cs index b0a221b1f..20883e920 100644 --- a/Sample/Helpdesk.Wolverine/Helpdesk.Api/Incidents/AssigningAgent/AssignAgent.cs +++ b/Sample/Helpdesk.Wolverine/Helpdesk.Api/Incidents/AssigningAgent/AssignAgent.cs @@ -25,5 +25,6 @@ public static (IResult, Events) AssignAgent( } public record AssignAgentToIncident( - Guid IncidentId // TODO: meh + Guid IncidentId, + int Version ); diff --git a/Sample/Helpdesk.Wolverine/Helpdesk.Api/Incidents/Categorising/Categorise.cs b/Sample/Helpdesk.Wolverine/Helpdesk.Api/Incidents/Categorising/Categorise.cs index 0ca5b767d..414527fb5 100644 --- a/Sample/Helpdesk.Wolverine/Helpdesk.Api/Incidents/Categorising/Categorise.cs +++ b/Sample/Helpdesk.Wolverine/Helpdesk.Api/Incidents/Categorising/Categorise.cs @@ -27,6 +27,7 @@ DateTimeOffset now } public record CategoriseIncident( - Guid IncidentId, // TODO: meh - IncidentCategory Category + Guid IncidentId, + IncidentCategory Category, + int Version ); diff --git a/Sample/Helpdesk.Wolverine/Helpdesk.Api/Incidents/Closing/Close.cs b/Sample/Helpdesk.Wolverine/Helpdesk.Api/Incidents/Closing/Close.cs index e25dfa9d4..956819c57 100644 --- a/Sample/Helpdesk.Wolverine/Helpdesk.Api/Incidents/Closing/Close.cs +++ b/Sample/Helpdesk.Wolverine/Helpdesk.Api/Incidents/Closing/Close.cs @@ -30,5 +30,6 @@ DateTimeOffset now } public record CloseIncident( - Guid IncidentId + Guid IncidentId, + int Version ); diff --git a/Sample/Helpdesk.Wolverine/Helpdesk.Api/Incidents/Prioritising/Prioritise.cs b/Sample/Helpdesk.Wolverine/Helpdesk.Api/Incidents/Prioritising/Prioritise.cs index 702aa4026..6fddf1d43 100644 --- a/Sample/Helpdesk.Wolverine/Helpdesk.Api/Incidents/Prioritising/Prioritise.cs +++ b/Sample/Helpdesk.Wolverine/Helpdesk.Api/Incidents/Prioritising/Prioritise.cs @@ -11,7 +11,6 @@ public static class PrioritiseEndpoint public static (IResult, Events) Prioritise( PrioritiseIncident command, Incident incident, - DateTimeOffset now ) { @@ -23,7 +22,8 @@ DateTimeOffset now } public record PrioritiseIncident( - Guid IncidentId, // TODO: meh + Guid IncidentId, Guid AgentId, - IncidentPriority Priority + IncidentPriority Priority, + int Version ); diff --git a/Sample/Helpdesk.Wolverine/Helpdesk.Api/Incidents/RecordingAgentResponse/RecordAgentResponse.cs b/Sample/Helpdesk.Wolverine/Helpdesk.Api/Incidents/RecordingAgentResponse/RecordAgentResponse.cs index 391caa279..b07b13fde 100644 --- a/Sample/Helpdesk.Wolverine/Helpdesk.Api/Incidents/RecordingAgentResponse/RecordAgentResponse.cs +++ b/Sample/Helpdesk.Wolverine/Helpdesk.Api/Incidents/RecordingAgentResponse/RecordAgentResponse.cs @@ -30,5 +30,6 @@ public record RecordAgentResponseToIncident( Guid IncidentId, Guid AgentId, string Content, - bool VisibleToCustomer + bool VisibleToCustomer, + int Version ); diff --git a/Sample/Helpdesk.Wolverine/Helpdesk.Api/Incidents/RecordingCustomerResponse/RecordCustomerResponse.cs b/Sample/Helpdesk.Wolverine/Helpdesk.Api/Incidents/RecordingCustomerResponse/RecordCustomerResponse.cs index ddc17541e..58b453b73 100644 --- a/Sample/Helpdesk.Wolverine/Helpdesk.Api/Incidents/RecordingCustomerResponse/RecordCustomerResponse.cs +++ b/Sample/Helpdesk.Wolverine/Helpdesk.Api/Incidents/RecordingCustomerResponse/RecordCustomerResponse.cs @@ -18,10 +18,8 @@ DateTimeOffset now if (incident.Status == IncidentStatus.Closed) throw new InvalidOperationException("Incident is already closed"); - var (_, customerId, content) = command; - var response = new IncidentResponse.FromCustomer( - customerId, content + command.CustomerId, command.Content ); return (Ok(), [new CustomerRespondedToIncident(incident.Id, response, now)]); @@ -31,5 +29,6 @@ DateTimeOffset now public record RecordCustomerResponseToIncident( Guid IncidentId, Guid CustomerId, - string Content + string Content, + int Version ); diff --git a/Sample/Helpdesk.Wolverine/Helpdesk.Api/Incidents/Resolving/Resolve.cs b/Sample/Helpdesk.Wolverine/Helpdesk.Api/Incidents/Resolving/Resolve.cs index e526fa770..64f5a63cf 100644 --- a/Sample/Helpdesk.Wolverine/Helpdesk.Api/Incidents/Resolving/Resolve.cs +++ b/Sample/Helpdesk.Wolverine/Helpdesk.Api/Incidents/Resolving/Resolve.cs @@ -1,4 +1,3 @@ -using Microsoft.AspNetCore.Mvc; using Wolverine.Http; using Wolverine.Marten; using static Microsoft.AspNetCore.Http.TypedResults; @@ -22,14 +21,13 @@ DateTimeOffset now if (incident.HasOutstandingResponseToCustomer) throw new InvalidOperationException("Cannot resolve incident that has outstanding responses to customer"); - var (_, agentId, resolution) = command; - - return (Ok(), [new IncidentResolved(incident.Id, resolution, agentId, now)]); + return (Ok(), [new IncidentResolved(incident.Id, command.Resolution, command.AgentId, now)]); } } public record ResolveIncident( Guid IncidentId, Guid AgentId, - ResolutionType Resolution + ResolutionType Resolution, + int Version );