Scaffold full-stack solution and CI baseline
This commit is contained in:
89
RpgRoller.Tests/UnitTest1.cs
Normal file
89
RpgRoller.Tests/UnitTest1.cs
Normal file
@@ -0,0 +1,89 @@
|
||||
using System.Net;
|
||||
using System.Net.Http.Json;
|
||||
using Microsoft.AspNetCore.Mvc.Testing;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.Extensions.DependencyInjection.Extensions;
|
||||
using RpgRoller.Contracts;
|
||||
using RpgRoller.Services;
|
||||
|
||||
namespace RpgRoller.Tests;
|
||||
|
||||
public sealed class UnitTest1 : IClassFixture<WebApplicationFactory<Program>>
|
||||
{
|
||||
private readonly HttpClient m_Client;
|
||||
|
||||
public UnitTest1(WebApplicationFactory<Program> factory)
|
||||
{
|
||||
m_Client = factory.WithWebHostBuilder(builder =>
|
||||
builder.ConfigureServices(services =>
|
||||
{
|
||||
services.RemoveAll<IDiceRoller>();
|
||||
services.AddSingleton<IDiceRoller>(new FixedDiceRoller(7));
|
||||
})).CreateClient();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task GetHealth_ReturnsOkPayload()
|
||||
{
|
||||
var response = await m_Client.GetAsync("/api/health");
|
||||
var payload = await response.Content.ReadFromJsonAsync<HealthResponse>();
|
||||
|
||||
Assert.Equal(HttpStatusCode.OK, response.StatusCode);
|
||||
Assert.NotNull(payload);
|
||||
Assert.Equal("ok", payload.Status);
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[InlineData(1, "Dice must have at least 2 sides.")]
|
||||
[InlineData(1001, "Dice must have at most 1000 sides.")]
|
||||
public async Task Roll_WithInvalidSides_ReturnsBadRequest(int sides, string expectedError)
|
||||
{
|
||||
var response = await m_Client.GetAsync($"/api/roll/{sides}");
|
||||
var payload = await response.Content.ReadFromJsonAsync<ApiError>();
|
||||
|
||||
Assert.Equal(HttpStatusCode.BadRequest, response.StatusCode);
|
||||
Assert.NotNull(payload);
|
||||
Assert.Equal(expectedError, payload.Error);
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[InlineData(2)]
|
||||
[InlineData(1000)]
|
||||
public async Task Roll_WithValidSides_ReturnsExpectedResult(int sides)
|
||||
{
|
||||
var response = await m_Client.GetAsync($"/api/roll/{sides}");
|
||||
var payload = await response.Content.ReadFromJsonAsync<RollResponse>();
|
||||
|
||||
Assert.Equal(HttpStatusCode.OK, response.StatusCode);
|
||||
Assert.NotNull(payload);
|
||||
Assert.Equal(sides, payload.Sides);
|
||||
Assert.Equal(Math.Min(7, sides), payload.Value);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void RandomDiceRoller_ProducesValueWithinRange()
|
||||
{
|
||||
var roller = new RandomDiceRoller();
|
||||
|
||||
for (var i = 0; i < 200; i += 1)
|
||||
{
|
||||
var value = roller.Roll(6);
|
||||
Assert.InRange(value, 1, 6);
|
||||
}
|
||||
}
|
||||
|
||||
private sealed class FixedDiceRoller : IDiceRoller
|
||||
{
|
||||
private readonly int m_Result;
|
||||
|
||||
public FixedDiceRoller(int result)
|
||||
{
|
||||
m_Result = result;
|
||||
}
|
||||
|
||||
public int Roll(int sides)
|
||||
{
|
||||
return Math.Min(m_Result, sides);
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user