Harden suggestion update gating and joker cap

This commit is contained in:
2026-02-05 19:36:31 +01:00
parent d9573540d6
commit a2dd212377
3 changed files with 170 additions and 17 deletions

View File

@@ -174,6 +174,131 @@ public class SuggestionTests
var loaded = await factory.WithDbContextAsync(async db => await db.Suggestions.FindAsync(id));
Assert.Equal("Lock", loaded!.Name); // title locked
Assert.Equal("NewGenre", loaded.Genre); // other fields still editable in vote
}
[Fact]
public async Task Player_cannot_edit_suggestion_in_results_phase()
{
using var factory = new TestWebApplicationFactory();
var player = factory.CreateClientWithCookies();
await player.RegisterAsync("results");
var id = await player.CreateSuggestionAsync("Frozen");
// Move everyone to Results
await factory.WithDbContextAsync(async db =>
{
var state = await db.AppState.FirstAsync();
state.ResultsOpen = true;
var p = await db.Players.FirstAsync();
p.CurrentPhase = Domain.Phase.Results;
await db.SaveChangesAsync();
});
var update = await player.PutAsJsonAsync($"/api/suggestions/{id}", new
{
Name = "ShouldFail",
Genre = "Nope",
Description = (string?)null,
ScreenshotUrl = (string?)null,
YoutubeUrl = (string?)null,
GameUrl = (string?)null,
MinPlayers = (int?)null,
MaxPlayers = (int?)null
});
Assert.Equal(HttpStatusCode.BadRequest, update.StatusCode);
var loaded = await factory.WithDbContextAsync(async db => await db.Suggestions.FindAsync(id));
Assert.Equal("Frozen", loaded!.Name);
Assert.Equal("Coop", loaded.Genre);
}
[Fact]
public async Task Player_cannot_edit_other_players_suggestion()
{
using var factory = new TestWebApplicationFactory();
var owner = factory.CreateClientWithCookies();
await owner.RegisterAsync("owner");
var other = factory.CreateClientWithCookies();
await other.RegisterAsync("intruder");
var id = await owner.CreateSuggestionAsync("Protected");
var update = await other.PutAsJsonAsync($"/api/suggestions/{id}", new
{
Name = "Hacked",
Genre = "Bad",
Description = (string?)null,
ScreenshotUrl = (string?)null,
YoutubeUrl = (string?)null,
GameUrl = (string?)null,
MinPlayers = (int?)null,
MaxPlayers = (int?)null
});
Assert.Equal(HttpStatusCode.Unauthorized, update.StatusCode);
}
[Fact]
public async Task Joker_allows_sixth_suggestion_but_blocks_seventh()
{
using var factory = new TestWebApplicationFactory();
var client = factory.CreateClientWithCookies();
await client.RegisterAsync("sixth");
// Seed 5 suggestions in Suggest phase
for (var i = 0; i < 5; i++)
{
var resp = await client.PostAsJsonAsync("/api/suggestions", new
{
Name = $"Game{i}",
Genre = (string?)null,
Description = (string?)null,
ScreenshotUrl = (string?)null,
YoutubeUrl = (string?)null,
GameUrl = (string?)null,
MinPlayers = (int?)null,
MaxPlayers = (int?)null
});
resp.EnsureSuccessStatusCode();
}
// Move to Vote and grant joker
await client.PostAsJsonAsync("/api/me/phase/next", new { });
await factory.WithDbContextAsync(async db =>
{
var p = await db.Players.FirstAsync();
p.HasJoker = true;
await db.SaveChangesAsync();
});
var sixth = await client.PostAsJsonAsync("/api/suggestions", new
{
Name = "JokerExtra",
Genre = (string?)null,
Description = (string?)null,
ScreenshotUrl = (string?)null,
YoutubeUrl = (string?)null,
GameUrl = (string?)null,
MinPlayers = (int?)null,
MaxPlayers = (int?)null
});
sixth.EnsureSuccessStatusCode();
var seventh = await client.PostAsJsonAsync("/api/suggestions", new
{
Name = "TooMany",
Genre = (string?)null,
Description = (string?)null,
ScreenshotUrl = (string?)null,
YoutubeUrl = (string?)null,
GameUrl = (string?)null,
MinPlayers = (int?)null,
MaxPlayers = (int?)null
});
Assert.Equal(HttpStatusCode.BadRequest, seventh.StatusCode);
}
[Fact]