Skip to content

Commit

Permalink
Initial point for refactoring Helpdesk sample to Wolverine
Browse files Browse the repository at this point in the history
  • Loading branch information
oskardudycz committed Aug 2, 2023
2 parents 6e495d6 + 6e495d6 commit b1c36cd
Show file tree
Hide file tree
Showing 36 changed files with 2,025 additions and 0 deletions.
@@ -0,0 +1,30 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFramework>net7.0</TargetFramework>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="FluentAssertions" Version="6.11.0" />
<PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="7.0.0" />
<PackageReference Include="Microsoft.Extensions.Configuration.FileExtensions" Version="7.0.0" />
<PackageReference Include="Microsoft.Extensions.Configuration.Json" Version="7.0.0" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.6.3" />
<PackageReference Include="NSubstitute" Version="5.0.0" />
<PackageReference Include="xunit" Version="2.5.0" />
<PackageReference Include="Microsoft.AspNetCore.TestHost" Version="7.0.9" />
<PackageReference Include="Ogooreck" Version="0.6.0" />
<PackageReference Include="Bogus" Version="34.0.2" />
<PackageReference Include="xunit.runner.visualstudio" Version="2.5.0">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
</ItemGroup>

<ItemGroup>
<ProjectReference Include="..\Helpdesk.Api\Helpdesk.Api.csproj" />
</ItemGroup>

<Import Project="..\..\..\Tests.Build.props" />

</Project>
@@ -0,0 +1,40 @@
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 async Task ResolveCommand_Succeeds()
{
await API
.Given(
URI($"/api/customers/{API.Incident.CustomerId}/incidents/{API.Incident.Id}/acknowledge"),
HEADERS(IF_MATCH(2))
)
.When(POST)
.Then(OK);

await API
.Given(URI($"/api/incidents/{API.Incident.Id}"))
.When(GET)
.Then(
OK,
RESPONSE_BODY(
API.Incident with
{
Status = IncidentStatus.ResolutionAcknowledgedByCustomer,
Version = 3
}
)
);
}

private readonly ApiWithResolvedIncident API;

public AcknowledgeResolutionIncidentTests(ApiWithResolvedIncident api) => API = api;
}
@@ -0,0 +1,40 @@
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(
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,
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;
}
@@ -0,0 +1,45 @@
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(
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)
.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;

}
@@ -0,0 +1,41 @@
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(
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)
.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;
}
@@ -0,0 +1,18 @@
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;
}

@@ -0,0 +1,15 @@
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;
}
@@ -0,0 +1,18 @@
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;
}

@@ -0,0 +1,114 @@
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();

var response = await api.Scenario(
api.ResolveIncident(incident.Id, agentId, resolvedType),
_ => api.GetIncidentDetails(incident.Id)
);

return await response.GetResultFromJson<IncidentDetails>();
}

public static async Task<IncidentDetails> AcknowledgedIncident(
this ApiSpecification<Program> api
)
{
var incident = await api.ResolvedIncident();

var response = await api.Scenario(
api.AcknowledgeIncident(incident.Id, incident.CustomerId),
_ => api.GetIncidentDetails(incident.Id)
);

return await response.GetResultFromJson<IncidentDetails>();
}

private static Task<HttpResponseMessage> LogIncident(
this ApiSpecification<Program> api,
Guid customerId,
Contact contact,
string incidentDescription
) =>
api.Given(
URI($"api/customers/{customerId}/incidents/"),
BODY(new LogIncidentRequest(contact, incidentDescription))
)
.When(POST)
.Then(CREATED_WITH_DEFAULT_HEADERS(locationHeaderPrefix: "/api/incidents/"));

private static Task<HttpResponseMessage> ResolveIncident<T>(
this ApiSpecification<T> api,
Guid incidentId,
Guid agentId,
ResolutionType resolutionType
) where T : class =>
api.Given(
URI($"/api/agents/{agentId}/incidents/{incidentId}/resolve"),
BODY(new ResolveIncidentRequest(resolutionType)),
HEADERS(IF_MATCH(1))
)
.When(POST)
.Then(OK);

private static Task<HttpResponseMessage> AcknowledgeIncident<T>(
this ApiSpecification<T> api,
Guid incidentId,
Guid customerId
) where T : class =>
api.Given(
URI($"/api/customers/{customerId}/incidents/{incidentId}/acknowledge"),
HEADERS(IF_MATCH(2))
)
.When(POST)
.Then(OK);

private static Task<HttpResponseMessage> GetIncidentDetails(
this ApiSpecification<Program> api,
Guid incidentId
) =>
api.Given(URI($"/api/incidents/{incidentId}"))
.When(GET)
.Then(OK);
}

0 comments on commit b1c36cd

Please sign in to comment.