Files
RpgRoller/RpgRoller.Tests/Support/ApiTestBase.cs

99 lines
3.7 KiB
C#

using System.Net;
using System.Net.Http.Json;
using Microsoft.AspNetCore.Mvc.Testing;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Diagnostics;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.DependencyInjection.Extensions;
using RpgRoller.Contracts;
using RpgRoller.Data;
using RpgRoller.Services;
namespace RpgRoller.Tests;
public abstract class ApiTestBase : IClassFixture<WebApplicationFactory<Program>>
{
private readonly WebApplicationFactory<Program> m_BaseFactory;
protected ApiTestBase(WebApplicationFactory<Program> factory)
{
m_BaseFactory = factory;
}
protected WebApplicationFactory<Program> CreateFactory(params int[] rollValues)
{
return m_BaseFactory.WithWebHostBuilder(builder =>
builder.ConfigureServices(services =>
{
services.RemoveAll<IDiceRoller>();
services.AddSingleton<IDiceRoller>(new FixedDiceRoller(rollValues));
services.RemoveAll<DbContextOptions<RpgRollerDbContext>>();
services.RemoveAll<IDbContextFactory<RpgRollerDbContext>>();
services.RemoveAll<RpgRollerDbContext>();
var dbPath = Path.Combine(Path.GetTempPath(), $"rpgroller-tests-{Guid.NewGuid():N}.db");
services.AddDbContextFactory<RpgRollerDbContext>(options =>
options.UseSqlite($"Data Source={dbPath}")
.ConfigureWarnings(warnings => warnings.Ignore(RelationalEventId.PendingModelChangesWarning)));
}));
}
protected static async Task<UserSummary> RegisterAsync(HttpClient client, string username, string password, string displayName)
{
return await PostAsync<RegisterRequest, UserSummary>(
client,
"/api/auth/register",
new RegisterRequest(username, password, displayName));
}
protected static async Task LoginAsync(HttpClient client, string username, string password)
{
var response = await client.PostAsJsonAsync("/api/auth/login", new LoginRequest(username, password));
Assert.Equal(HttpStatusCode.OK, response.StatusCode);
}
protected static async Task<TResponse> PostAsync<TRequest, TResponse>(HttpClient client, string uri, TRequest payload)
{
var response = await client.PostAsJsonAsync(uri, payload);
Assert.Equal(HttpStatusCode.OK, response.StatusCode);
var result = await response.Content.ReadFromJsonAsync<TResponse>();
Assert.NotNull(result);
return result;
}
protected static async Task<TResponse> PutAsync<TRequest, TResponse>(HttpClient client, string uri, TRequest payload)
{
var response = await client.PutAsJsonAsync(uri, payload);
Assert.Equal(HttpStatusCode.OK, response.StatusCode);
var result = await response.Content.ReadFromJsonAsync<TResponse>();
Assert.NotNull(result);
return result;
}
protected static async Task<TResponse> GetAsync<TResponse>(HttpClient client, string uri)
{
var response = await client.GetAsync(uri);
Assert.Equal(HttpStatusCode.OK, response.StatusCode);
var result = await response.Content.ReadFromJsonAsync<TResponse>();
Assert.NotNull(result);
return result;
}
private sealed class FixedDiceRoller : IDiceRoller
{
private readonly Queue<int> m_Values;
public FixedDiceRoller(IEnumerable<int> values)
{
m_Values = new Queue<int>(values);
}
public int Roll(int sides)
{
var next = m_Values.Count > 0 ? m_Values.Dequeue() : 1;
return Math.Clamp(next, 1, sides);
}
}
}