Add admin roles, user management, and campaign deletion

This commit is contained in:
2026-02-26 17:15:10 +01:00
parent 3026221cd6
commit 2e2f364c5e
26 changed files with 1127 additions and 31 deletions

View File

@@ -14,6 +14,7 @@ public sealed class AuthApiTests : ApiTestBase
var registerResult = await RegisterAsync(client, "alice", "Password123", "Alice");
Assert.Equal("alice", registerResult.Username);
Assert.Contains(registerResult.Roles, role => string.Equals(role, "admin", StringComparison.OrdinalIgnoreCase));
var duplicate = await client.PostAsJsonAsync("/api/auth/register", new RegisterRequest("alice", "Password123", "Alice 2"));
Assert.Equal(HttpStatusCode.BadRequest, duplicate.StatusCode);

View File

@@ -103,4 +103,52 @@ public sealed class CampaignApiTests : ApiTestBase
var receiverActivate = await receiverClient.PostAsync($"/api/characters/{character.Id}/activate", null);
Assert.Equal(HttpStatusCode.OK, receiverActivate.StatusCode);
}
[Fact]
public async Task AdminUserManagementAndCampaignDeletion_WorkThroughApi()
{
using var factory = CreateFactory(6, 5, 4);
using var adminClient = factory.CreateClient(new() { AllowAutoRedirect = false });
using var gmClient = factory.CreateClient(new() { AllowAutoRedirect = false });
using var playerClient = factory.CreateClient(new() { AllowAutoRedirect = false });
var admin = await RegisterAsync(adminClient, "admin3", "Password123", "Admin");
var gm = await RegisterAsync(gmClient, "gm3", "Password123", "GM");
var player = await RegisterAsync(playerClient, "player3", "Password123", "Player");
await LoginAsync(adminClient, "admin3", "Password123");
await LoginAsync(gmClient, "gm3", "Password123");
await LoginAsync(playerClient, "player3", "Password123");
var adminUsers = await GetAsync<IReadOnlyList<AdminUserSummary>>(adminClient, "/api/admin/users");
var adminEntry = adminUsers.Single(user => user.Id == admin.Id);
var playerEntry = adminUsers.Single(user => user.Id == player.Id);
Assert.Contains(adminEntry.Roles, role => string.Equals(role, "admin", StringComparison.OrdinalIgnoreCase));
Assert.Empty(playerEntry.Roles);
var promotedPlayer = await PutAsync<UpdateUserRolesRequest, AdminUserSummary>(adminClient, $"/api/admin/users/{player.Id}/roles", new([ "admin" ]));
Assert.Contains(promotedPlayer.Roles, role => string.Equals(role, "admin", StringComparison.OrdinalIgnoreCase));
var campaign = await PostAsync<CreateCampaignRequest, CampaignDetails>(gmClient, "/api/campaigns", new("Disposable Campaign", "d6"));
var character = await PostAsync<CreateCharacterRequest, CharacterSummary>(playerClient, "/api/characters", new("Disposable Hero", campaign.Id));
var skill = await PostAsync<CreateSkillRequest, SkillSummary>(playerClient, $"/api/characters/{character.Id}/skills", new("Stealth", "2D+1", 1, true));
_ = await PostAsync<RollSkillRequest, RollResult>(playerClient, $"/api/skills/{skill.Id}/roll", new("public"));
var deleteCampaign = await adminClient.DeleteAsync($"/api/campaigns/{campaign.Id}");
Assert.Equal(HttpStatusCode.OK, deleteCampaign.StatusCode);
var getDeletedCampaign = await gmClient.GetAsync($"/api/campaigns/{campaign.Id}");
Assert.Equal(HttpStatusCode.BadRequest, getDeletedCampaign.StatusCode);
var playerCharacters = await GetAsync<IReadOnlyList<CharacterSummary>>(playerClient, "/api/characters");
Assert.Single(playerCharacters);
Assert.Null(playerCharacters[0].CampaignId);
var deleteUser = await adminClient.DeleteAsync($"/api/admin/users/{player.Id}");
Assert.Equal(HttpStatusCode.OK, deleteUser.StatusCode);
var usersAfterDelete = await GetAsync<IReadOnlyList<AdminUserSummary>>(adminClient, "/api/admin/users");
Assert.DoesNotContain(usersAfterDelete, user => user.Id == player.Id);
Assert.Contains(usersAfterDelete, user => user.Id == gm.Id);
}
}