-
-
Notifications
You must be signed in to change notification settings - Fork 467
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Added Helpdesk sample from EventSourcing.NET repo
- Loading branch information
1 parent
f5085ef
commit 0f96981
Showing
37 changed files
with
2,043 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
28 changes: 28 additions & 0 deletions
28
src/samples/Helpdesk/Helpdesk.Api.Tests/Helpdesk.Api.Tests.csproj
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
<Project Sdk="Microsoft.NET.Sdk"> | ||
|
||
<PropertyGroup> | ||
<TargetFramework>net8.0</TargetFramework> | ||
</PropertyGroup> | ||
|
||
<ItemGroup> | ||
<PackageReference Include="FluentAssertions" Version="6.12.0"/> | ||
<PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="8.0.0"/> | ||
<PackageReference Include="Microsoft.Extensions.Configuration.FileExtensions" Version="8.0.0"/> | ||
<PackageReference Include="Microsoft.Extensions.Configuration.Json" Version="8.0.0"/> | ||
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.8.0"/> | ||
<PackageReference Include="NSubstitute" Version="5.1.0"/> | ||
<PackageReference Include="xunit" Version="2.6.3"/> | ||
<PackageReference Include="Microsoft.AspNetCore.TestHost" Version="8.0.0"/> | ||
<PackageReference Include="Ogooreck" Version="0.8.0"/> | ||
<PackageReference Include="Bogus" Version="35.0.1"/> | ||
<PackageReference Include="xunit.runner.visualstudio" Version="2.5.5"> | ||
<PrivateAssets>all</PrivateAssets> | ||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets> | ||
</PackageReference> | ||
</ItemGroup> | ||
|
||
<ItemGroup> | ||
<ProjectReference Include="..\Helpdesk.Api\Helpdesk.Api.csproj"/> | ||
</ItemGroup> | ||
|
||
</Project> |
34 changes: 34 additions & 0 deletions
34
src/samples/Helpdesk/Helpdesk.Api.Tests/Incidents/AcknowledgeResolutionIncidentTests.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
using System.Threading.Tasks; | ||
using Helpdesk.Api.Incidents; | ||
using Helpdesk.Api.Tests.Incidents.Fixtures; | ||
using Xunit; | ||
using static Ogooreck.API.ApiSpecification; | ||
|
||
namespace Helpdesk.Api.Tests.Incidents; | ||
|
||
public class AcknowledgeResolutionIncidentTests: IClassFixture<ApiWithResolvedIncident> | ||
{ | ||
[Fact] | ||
[Trait("Category", "Acceptance")] | ||
public Task ResolveCommand_Succeeds() => | ||
API | ||
.Given() | ||
.When( | ||
POST, | ||
URI($"/api/customers/{API.Incident.CustomerId}/incidents/{API.Incident.Id}/acknowledge"), | ||
HEADERS(IF_MATCH(2)) | ||
) | ||
.Then(OK) | ||
.And() | ||
.When(GET, URI($"/api/incidents/{API.Incident.Id}")) | ||
.Then( | ||
OK, | ||
RESPONSE_BODY( | ||
API.Incident with { Status = IncidentStatus.ResolutionAcknowledgedByCustomer, Version = 3 } | ||
) | ||
); | ||
|
||
private readonly ApiWithResolvedIncident API; | ||
|
||
public AcknowledgeResolutionIncidentTests(ApiWithResolvedIncident api) => API = api; | ||
} |
37 changes: 37 additions & 0 deletions
37
src/samples/Helpdesk/Helpdesk.Api.Tests/Incidents/AssignAgentTests.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
using System; | ||
using System.Threading.Tasks; | ||
using Helpdesk.Api.Tests.Incidents.Fixtures; | ||
using Xunit; | ||
using static Ogooreck.API.ApiSpecification; | ||
|
||
namespace Helpdesk.Api.Tests.Incidents; | ||
|
||
public class AssignAgentToIncidentTests: IClassFixture<ApiWithLoggedIncident> | ||
{ | ||
[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)) | ||
) | ||
.Then(OK) | ||
.And() | ||
.When(GET, URI($"/api/incidents/{API.Incident.Id}")) | ||
.Then( | ||
OK, | ||
RESPONSE_BODY( | ||
API.Incident with { AgentId = agentId, Version = 2 } | ||
) | ||
); | ||
} | ||
|
||
private readonly Guid agentId = Guid.NewGuid(); | ||
private readonly ApiWithLoggedIncident API; | ||
|
||
public AssignAgentToIncidentTests(ApiWithLoggedIncident api) => API = api; | ||
} |
43 changes: 43 additions & 0 deletions
43
src/samples/Helpdesk/Helpdesk.Api.Tests/Incidents/CategoriseIncidentTests.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,43 @@ | ||
using System; | ||
using System.Threading.Tasks; | ||
using Bogus; | ||
using Helpdesk.Api.Incidents; | ||
using Helpdesk.Api.Tests.Incidents.Fixtures; | ||
using Xunit; | ||
using static Ogooreck.API.ApiSpecification; | ||
|
||
namespace Helpdesk.Api.Tests.Incidents; | ||
|
||
public class CategoriseIncidentTests: IClassFixture<ApiWithLoggedIncident> | ||
{ | ||
[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 CategoriseIncidentRequest(category)), | ||
HEADERS(IF_MATCH(1)) | ||
) | ||
.Then(OK); | ||
|
||
await API | ||
.Given() | ||
.When(GET, URI($"/api/incidents/{API.Incident.Id}")) | ||
.Then( | ||
OK, | ||
RESPONSE_BODY( | ||
API.Incident with { Category = category, Version = 2 } | ||
) | ||
); | ||
} | ||
|
||
private readonly Guid agentId = Guid.NewGuid(); | ||
private readonly IncidentCategory category = new Faker().PickRandom<IncidentCategory>(); | ||
private readonly ApiWithLoggedIncident API; | ||
|
||
public CategoriseIncidentTests(ApiWithLoggedIncident api) => API = api; | ||
} |
40 changes: 40 additions & 0 deletions
40
src/samples/Helpdesk/Helpdesk.Api.Tests/Incidents/CloseIncidentTests.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,40 @@ | ||
using System; | ||
using System.Threading.Tasks; | ||
using Helpdesk.Api.Incidents; | ||
using Helpdesk.Api.Tests.Incidents.Fixtures; | ||
using Xunit; | ||
using static Ogooreck.API.ApiSpecification; | ||
|
||
namespace Helpdesk.Api.Tests.Incidents; | ||
|
||
public class CloseIncidentTests: IClassFixture<ApiWithAcknowledgedIncident> | ||
{ | ||
[Fact] | ||
[Trait("Category", "Acceptance")] | ||
public async Task ResolveCommand_Succeeds() | ||
{ | ||
await API | ||
.Given() | ||
.When( | ||
POST, | ||
URI($"/api/agents/{agentId}/incidents/{API.Incident.Id}/close"), | ||
HEADERS(IF_MATCH(3)) | ||
) | ||
.Then(OK); | ||
|
||
await API | ||
.Given() | ||
.When(GET, URI($"/api/incidents/{API.Incident.Id}")) | ||
.Then( | ||
OK, | ||
RESPONSE_BODY( | ||
API.Incident with { Status = IncidentStatus.Closed, Version = 4 } | ||
) | ||
); | ||
} | ||
|
||
private readonly ApiWithAcknowledgedIncident API; | ||
private Guid agentId = Guid.NewGuid(); | ||
|
||
public CloseIncidentTests(ApiWithAcknowledgedIncident api) => API = api; | ||
} |
18 changes: 18 additions & 0 deletions
18
src/samples/Helpdesk/Helpdesk.Api.Tests/Incidents/Fixtures/ApiWithAcknowledgedIncident.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
using System.Threading.Tasks; | ||
using Helpdesk.Api.Incidents.GetIncidentDetails; | ||
using Ogooreck.API; | ||
using Xunit; | ||
|
||
namespace Helpdesk.Api.Tests.Incidents.Fixtures; | ||
|
||
public class ApiWithAcknowledgedIncident: ApiSpecification<Program>, IAsyncLifetime | ||
{ | ||
public async Task InitializeAsync() | ||
{ | ||
Incident = await this.AcknowledgedIncident(); | ||
} | ||
|
||
public IncidentDetails Incident { get; set; } = default!; | ||
|
||
public Task DisposeAsync() => Task.CompletedTask; | ||
} |
17 changes: 17 additions & 0 deletions
17
src/samples/Helpdesk/Helpdesk.Api.Tests/Incidents/Fixtures/ApiWithLoggedIncident.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
using System.Threading.Tasks; | ||
using Helpdesk.Api.Incidents.GetIncidentDetails; | ||
using Ogooreck.API; | ||
using Xunit; | ||
|
||
namespace Helpdesk.Api.Tests.Incidents.Fixtures; | ||
|
||
public class ApiWithLoggedIncident: ApiSpecification<Program>, IAsyncLifetime | ||
{ | ||
public async Task InitializeAsync() | ||
{ | ||
Incident = await this.LoggedIncident(); | ||
} | ||
|
||
public IncidentDetails Incident { get; protected set; } = default!; | ||
public Task DisposeAsync() => Task.CompletedTask; | ||
} |
18 changes: 18 additions & 0 deletions
18
src/samples/Helpdesk/Helpdesk.Api.Tests/Incidents/Fixtures/ApiWithResolvedIncident.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
using System.Threading.Tasks; | ||
using Helpdesk.Api.Incidents.GetIncidentDetails; | ||
using Ogooreck.API; | ||
using Xunit; | ||
|
||
namespace Helpdesk.Api.Tests.Incidents.Fixtures; | ||
|
||
public class ApiWithResolvedIncident: ApiSpecification<Program>, IAsyncLifetime | ||
{ | ||
public async Task InitializeAsync() | ||
{ | ||
Incident = await this.ResolvedIncident(); | ||
} | ||
|
||
public IncidentDetails Incident { get; set; } = default!; | ||
|
||
public Task DisposeAsync() => Task.CompletedTask; | ||
} |
112 changes: 112 additions & 0 deletions
112
src/samples/Helpdesk/Helpdesk.Api.Tests/Incidents/Fixtures/Scenarios.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,112 @@ | ||
using System; | ||
using System.Threading.Tasks; | ||
using Bogus; | ||
using Bogus.DataSets; | ||
using Helpdesk.Api.Incidents; | ||
using Helpdesk.Api.Incidents.GetIncidentDetails; | ||
using Ogooreck.API; | ||
using static Ogooreck.API.ApiSpecification; | ||
|
||
namespace Helpdesk.Api.Tests.Incidents.Fixtures; | ||
|
||
public static class Scenarios | ||
{ | ||
private static readonly Faker faker = new(); | ||
private static readonly Lorem loremIpsum = new(); | ||
|
||
public static async Task<IncidentDetails> LoggedIncident( | ||
this ApiSpecification<Program> api | ||
) | ||
{ | ||
var customerId = Guid.NewGuid(); | ||
|
||
var contact = new Contact( | ||
faker.PickRandom<ContactChannel>(), | ||
faker.Name.FirstName(), | ||
faker.Name.LastName(), | ||
faker.Internet.Email(), | ||
faker.Phone.PhoneNumber() | ||
); | ||
var incidentDescription = loremIpsum.Sentence(); | ||
|
||
var response = await api.Scenario( | ||
api.LogIncident(customerId, contact, incidentDescription), | ||
r => api.GetIncidentDetails(r.GetCreatedId<Guid>()) | ||
); | ||
|
||
return await response.GetResultFromJson<IncidentDetails>(); | ||
} | ||
|
||
public static async Task<IncidentDetails> ResolvedIncident( | ||
this ApiSpecification<Program> api | ||
) | ||
{ | ||
var agentId = Guid.NewGuid(); | ||
var resolvedType = faker.PickRandom<ResolutionType>(); | ||
var incident = await api.LoggedIncident(); | ||
|
||
return await api.Scenario( | ||
api.ResolveIncident(incident.Id, agentId, resolvedType), | ||
_ => api.GetIncidentDetails(incident.Id) | ||
).GetResponseBody<IncidentDetails>(); | ||
} | ||
|
||
public static async Task<IncidentDetails> AcknowledgedIncident( | ||
this ApiSpecification<Program> api | ||
) | ||
{ | ||
var incident = await api.ResolvedIncident(); | ||
|
||
return await api.Scenario( | ||
api.AcknowledgeIncident(incident.Id, incident.CustomerId), | ||
_ => api.GetIncidentDetails(incident.Id) | ||
).GetResponseBody<IncidentDetails>(); | ||
} | ||
|
||
private static Task<Result> LogIncident( | ||
this ApiSpecification<Program> api, | ||
Guid customerId, | ||
Contact contact, | ||
string incidentDescription | ||
) => | ||
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<Result> ResolveIncident<T>( | ||
this ApiSpecification<T> api, | ||
Guid incidentId, | ||
Guid agentId, | ||
ResolutionType resolutionType | ||
) where T : class => | ||
api.Given() | ||
.When( | ||
POST, | ||
URI($"/api/agents/{agentId}/incidents/{incidentId}/resolve"), | ||
BODY(new ResolveIncidentRequest(resolutionType)), | ||
HEADERS(IF_MATCH(1)) | ||
) | ||
.Then(OK); | ||
|
||
private static Task<Result> AcknowledgeIncident<T>( | ||
this ApiSpecification<T> api, | ||
Guid incidentId, | ||
Guid customerId | ||
) where T : class => | ||
api.Given() | ||
.When( | ||
POST, | ||
URI($"/api/customers/{customerId}/incidents/{incidentId}/acknowledge"), | ||
HEADERS(IF_MATCH(2)) | ||
) | ||
.Then(OK); | ||
|
||
private static Task<Result> GetIncidentDetails( | ||
this ApiSpecification<Program> api, | ||
Guid incidentId | ||
) => | ||
api.Given() | ||
.When(GET, URI($"/api/incidents/{incidentId}")) | ||
.Then(OK); | ||
} |
Oops, something went wrong.