namespace RpgRoller.Tests; public sealed class AuthApiTests : ApiTestBase { public AuthApiTests(WebApplicationFactory factory) : base(factory) { } [Fact] public async Task RegisterLoginAndMeFlow_WorksWithDuplicateUsernameGuard() { using var factory = CreateFactory(4, 4, 4); using var client = factory.CreateClient(new() { AllowAutoRedirect = false }); var registerResult = await RegisterAsync(client, "alice", "Password123", "Alice"); Assert.Equal("alice", registerResult.Username); var duplicate = await client.PostAsJsonAsync("/api/auth/register", new RegisterRequest("alice", "Password123", "Alice 2")); Assert.Equal(HttpStatusCode.BadRequest, duplicate.StatusCode); var loginResult = await client.PostAsJsonAsync("/api/auth/login", new LoginRequest("alice", "Password123")); Assert.Equal(HttpStatusCode.OK, loginResult.StatusCode); var me = await GetAsync(client, "/api/me"); Assert.Equal(registerResult.Id, me.User.Id); Assert.Null(me.ActiveCharacterId); Assert.Null(me.CurrentCampaignId); var invalidLogin = await client.PostAsJsonAsync("/api/auth/login", new LoginRequest("alice", "wrong-password")); Assert.Equal(HttpStatusCode.BadRequest, invalidLogin.StatusCode); } [Fact] public async Task UsernamesEndpoint_RequiresAuthAndReturnsAlphabeticalList() { using var factory = CreateFactory(); using var client = factory.CreateClient(new() { AllowAutoRedirect = false }); await RegisterAsync(client, "zoe", "Password123", "Zoe"); await RegisterAsync(client, "amy", "Password123", "Amy"); await RegisterAsync(client, "bob", "Password123", "Bob"); var unauthorized = await client.GetAsync("/api/users/usernames"); Assert.Equal(HttpStatusCode.Unauthorized, unauthorized.StatusCode); await LoginAsync(client, "bob", "Password123"); var usernames = await GetAsync>(client, "/api/users/usernames"); Assert.Equal(["amy", "bob", "zoe"], usernames); } }