Add owner role and admin management controls

This commit is contained in:
2026-02-08 19:01:58 +01:00
parent 97f1b30b75
commit 1c59d68a50
25 changed files with 540 additions and 9 deletions

View File

@@ -94,6 +94,82 @@ public class AdminTests
});
}
[Fact]
public async Task Admin_can_grant_and_revoke_admin_for_non_owner_accounts()
{
await using var factory = new TestWebApplicationFactory();
var owner = factory.CreateClientWithCookies();
await owner.RegisterAsync("owner", admin: true);
var player = factory.CreateClientWithCookies();
await player.RegisterAsync("player");
var playerId = await player.GetProfileIdAsync();
var grant = await owner.PostAsJsonAsync("/api/admin/player-admin", new
{
playerId = playerId,
isAdmin = true
});
grant.EnsureSuccessStatusCode();
await factory.WithDbContextAsync(async db =>
{
var promoted = await db.Players.AsNoTracking().SingleAsync(p => p.Id == playerId);
Assert.True(promoted.IsAdmin);
Assert.False(promoted.IsOwner);
});
var revoke = await owner.PostAsJsonAsync("/api/admin/player-admin", new
{
playerId = playerId,
isAdmin = false
});
revoke.EnsureSuccessStatusCode();
await factory.WithDbContextAsync(async db =>
{
var demoted = await db.Players.AsNoTracking().SingleAsync(p => p.Id == playerId);
Assert.False(demoted.IsAdmin);
});
}
[Fact]
public async Task Owner_admin_role_cannot_be_changed_or_deleted()
{
await using var factory = new TestWebApplicationFactory();
var owner = factory.CreateClientWithCookies();
await owner.RegisterAsync("owner", admin: true);
var ownerId = await owner.GetProfileIdAsync();
var toggleOwner = await owner.PostAsJsonAsync("/api/admin/player-admin", new
{
playerId = ownerId,
isAdmin = false
});
Assert.Equal(HttpStatusCode.BadRequest, toggleOwner.StatusCode);
var deleteOwner = await owner.SendAsync(new HttpRequestMessage(HttpMethod.Delete, $"/api/admin/players/{ownerId}")
{
Content = JsonContent.Create(new { password = AdminPassword })
});
Assert.Equal(HttpStatusCode.BadRequest, deleteOwner.StatusCode);
}
[Fact]
public async Task Set_player_admin_returns_not_found_for_unknown_player()
{
await using var factory = new TestWebApplicationFactory();
var owner = factory.CreateClientWithCookies();
await owner.RegisterAsync("owner", admin: true);
var response = await owner.PostAsJsonAsync("/api/admin/player-admin", new
{
playerId = Guid.NewGuid(),
isAdmin = true
});
Assert.Equal(HttpStatusCode.NotFound, response.StatusCode);
}
[Fact]
public async Task Admin_player_phase_requires_vote_phase_and_suggest_target()
{