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> { private readonly HttpClient m_Client; public UnitTest1(WebApplicationFactory factory) { m_Client = factory.WithWebHostBuilder(builder => builder.ConfigureServices(services => { services.RemoveAll(); services.AddSingleton(new FixedDiceRoller(7)); })).CreateClient(); } [Fact] public async Task GetHealth_ReturnsOkPayload() { var response = await m_Client.GetAsync("/api/health"); var payload = await response.Content.ReadFromJsonAsync(); 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(); 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(); 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); } } }