Expand test coverage to match specs
This commit is contained in:
@@ -87,12 +87,16 @@ public class SuggestionTests
|
||||
using var factory = new TestWebApplicationFactory();
|
||||
var player = factory.CreateClientWithCookies();
|
||||
await player.RegisterAsync("joker");
|
||||
var other = factory.CreateClientWithCookies();
|
||||
await other.RegisterAsync("other");
|
||||
|
||||
await factory.WithDbContextAsync(async db =>
|
||||
{
|
||||
var p = await db.Players.FirstAsync();
|
||||
p.HasJoker = true;
|
||||
p.CurrentPhase = Domain.Phase.Vote;
|
||||
var o = await db.Players.SingleAsync(x => x.Username == "other");
|
||||
o.VotesFinal = true;
|
||||
await db.SaveChangesAsync();
|
||||
});
|
||||
|
||||
@@ -114,6 +118,8 @@ public class SuggestionTests
|
||||
var p = await db.Players.FirstAsync();
|
||||
Assert.False(p.HasJoker);
|
||||
Assert.False(p.VotesFinal);
|
||||
var o = await db.Players.SingleAsync(x => x.Username == "other");
|
||||
Assert.False(o.VotesFinal);
|
||||
});
|
||||
}
|
||||
|
||||
@@ -219,4 +225,173 @@ public class SuggestionTests
|
||||
var mine = await client.GetFromJsonAsync<List<JsonElement>>("/api/suggestions/mine");
|
||||
Assert.Equal("Second", mine![0].GetProperty("name").GetString());
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task Create_requires_suggest_phase_and_display_name()
|
||||
{
|
||||
using var factory = new TestWebApplicationFactory();
|
||||
var client = factory.CreateClientWithCookies();
|
||||
await client.RegisterAsync("phasegate");
|
||||
|
||||
await factory.WithDbContextAsync(async db =>
|
||||
{
|
||||
var p = await db.Players.FirstAsync();
|
||||
p.CurrentPhase = Domain.Phase.Vote;
|
||||
p.DisplayName = null;
|
||||
await db.SaveChangesAsync();
|
||||
});
|
||||
|
||||
var badPhase = await client.PostAsJsonAsync("/api/suggestions", new { Name = "Nope", 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, badPhase.StatusCode);
|
||||
|
||||
await factory.WithDbContextAsync(async db =>
|
||||
{
|
||||
var p = await db.Players.FirstAsync();
|
||||
p.CurrentPhase = Domain.Phase.Suggest;
|
||||
await db.SaveChangesAsync();
|
||||
});
|
||||
|
||||
var noDisplay = await client.PostAsJsonAsync("/api/suggestions", new { Name = "NoDisplay", 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, noDisplay.StatusCode);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task Rejects_invalid_urls_name_length_and_player_counts()
|
||||
{
|
||||
using var factory = new TestWebApplicationFactory();
|
||||
var client = factory.CreateClientWithCookies();
|
||||
await client.RegisterAsync("validate2");
|
||||
|
||||
var badGame = await client.PostAsJsonAsync("/api/suggestions", new { Name = "Bad", Genre = (string?)null, Description = (string?)null, ScreenshotUrl = (string?)null, YoutubeUrl = (string?)null, GameUrl = "ftp://bad", MinPlayers = (int?)null, MaxPlayers = (int?)null });
|
||||
Assert.Equal(HttpStatusCode.BadRequest, badGame.StatusCode);
|
||||
|
||||
var badYoutube = await client.PostAsJsonAsync("/api/suggestions", new { Name = "BadYt", Genre = (string?)null, Description = (string?)null, ScreenshotUrl = (string?)null, YoutubeUrl = "file://bad", GameUrl = (string?)null, MinPlayers = (int?)null, MaxPlayers = (int?)null });
|
||||
Assert.Equal(HttpStatusCode.BadRequest, badYoutube.StatusCode);
|
||||
|
||||
var longName = await client.PostAsJsonAsync("/api/suggestions", new { Name = new string('x', 101), 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, longName.StatusCode);
|
||||
|
||||
var minOnly = await client.PostAsJsonAsync("/api/suggestions", new { Name = "MinOnly", Genre = (string?)null, Description = (string?)null, ScreenshotUrl = (string?)null, YoutubeUrl = (string?)null, GameUrl = (string?)null, MinPlayers = 2, MaxPlayers = (int?)null });
|
||||
Assert.Equal(HttpStatusCode.BadRequest, minOnly.StatusCode);
|
||||
|
||||
var maxTooHigh = await client.PostAsJsonAsync("/api/suggestions", new { Name = "MaxHigh", Genre = (string?)null, Description = (string?)null, ScreenshotUrl = (string?)null, YoutubeUrl = (string?)null, GameUrl = (string?)null, MinPlayers = 2, MaxPlayers = 40 });
|
||||
Assert.Equal(HttpStatusCode.BadRequest, maxTooHigh.StatusCode);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task Trims_and_truncates_optional_fields()
|
||||
{
|
||||
using var factory = new TestWebApplicationFactory();
|
||||
var client = factory.CreateClientWithCookies();
|
||||
await client.RegisterAsync("trim");
|
||||
|
||||
var longGenre = new string('g', 60);
|
||||
var longDesc = new string('d', 600);
|
||||
var resp = await client.PostAsJsonAsync("/api/suggestions", new
|
||||
{
|
||||
Name = "Trim",
|
||||
Genre = $" {longGenre} ",
|
||||
Description = $" {longDesc} ",
|
||||
ScreenshotUrl = "http://example.com/img.png",
|
||||
YoutubeUrl = "http://example.com/y",
|
||||
GameUrl = "http://example.com/g",
|
||||
MinPlayers = 1,
|
||||
MaxPlayers = 4
|
||||
});
|
||||
resp.EnsureSuccessStatusCode();
|
||||
|
||||
await factory.WithDbContextAsync(async db =>
|
||||
{
|
||||
var s = await db.Suggestions.AsNoTracking().FirstAsync();
|
||||
Assert.Equal(50, s.Genre!.Length);
|
||||
Assert.Equal(500, s.Description!.Length);
|
||||
Assert.Equal("http://example.com/img.png", s.ScreenshotUrl);
|
||||
});
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task Mine_excludes_other_players()
|
||||
{
|
||||
using var factory = new TestWebApplicationFactory();
|
||||
var a = factory.CreateClientWithCookies();
|
||||
await a.RegisterAsync("alice");
|
||||
var b = factory.CreateClientWithCookies();
|
||||
await b.RegisterAsync("bob");
|
||||
|
||||
await a.CreateSuggestionAsync("AliceGame");
|
||||
await b.CreateSuggestionAsync("BobGame");
|
||||
|
||||
var mine = await a.GetFromJsonAsync<List<JsonElement>>("/api/suggestions/mine");
|
||||
Assert.Single(mine!);
|
||||
Assert.Equal("AliceGame", mine[0].GetProperty("name").GetString());
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task All_returns_link_metadata_and_ordering()
|
||||
{
|
||||
using var factory = new TestWebApplicationFactory();
|
||||
var client = factory.CreateClientWithCookies();
|
||||
await client.RegisterAsync("owner");
|
||||
|
||||
var id1 = await client.CreateSuggestionAsync("Alpha");
|
||||
await Task.Delay(10);
|
||||
var id2 = await client.CreateSuggestionAsync("Beta");
|
||||
await factory.WithDbContextAsync(async db =>
|
||||
{
|
||||
var beta = await db.Suggestions.FindAsync(id2);
|
||||
beta!.ParentSuggestionId = id1;
|
||||
await db.SaveChangesAsync();
|
||||
});
|
||||
|
||||
await client.PostAsJsonAsync("/api/me/phase/next", new { }); // to Vote
|
||||
|
||||
var all = await client.GetFromJsonAsync<List<JsonElement>>("/api/suggestions/all");
|
||||
Assert.Equal(2, all!.Count);
|
||||
var first = all[0];
|
||||
Assert.Equal("Alpha", first.GetProperty("name").GetString());
|
||||
var second = all[1];
|
||||
var linkedIds = second.GetProperty("linkedIds").EnumerateArray().Select(x => x.GetInt32()).ToList();
|
||||
Assert.Contains(id1, linkedIds);
|
||||
var linkedTitles = second.GetProperty("linkedTitles").EnumerateArray().Select(x => x.GetString()).ToList();
|
||||
Assert.Contains("Alpha", linkedTitles);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task Delete_respects_phase_and_clears_links_and_votes()
|
||||
{
|
||||
using var factory = new TestWebApplicationFactory();
|
||||
var owner = factory.CreateClientWithCookies();
|
||||
await owner.RegisterAsync("deleter");
|
||||
var other = factory.CreateClientWithCookies();
|
||||
await other.RegisterAsync("voter");
|
||||
|
||||
var id = await owner.CreateSuggestionAsync("DeleteMe");
|
||||
var child = await owner.CreateSuggestionAsync("Child");
|
||||
await factory.WithDbContextAsync(async db =>
|
||||
{
|
||||
var c = await db.Suggestions.FindAsync(child);
|
||||
c!.ParentSuggestionId = id;
|
||||
await db.SaveChangesAsync();
|
||||
});
|
||||
|
||||
await owner.PostAsJsonAsync("/api/me/phase/next", new { }); // Vote
|
||||
await other.PostAsJsonAsync("/api/me/phase/next", new { });
|
||||
await other.PostAsJsonAsync("/api/votes", new { SuggestionId = id, Score = 5 });
|
||||
|
||||
var blocked = await owner.DeleteAsync($"/api/suggestions/{id}");
|
||||
Assert.Equal(HttpStatusCode.BadRequest, blocked.StatusCode);
|
||||
|
||||
var admin = factory.CreateClientWithCookies();
|
||||
await admin.RegisterAsync("admin", admin: true);
|
||||
var delete = await admin.DeleteAsync($"/api/suggestions/{id}");
|
||||
delete.EnsureSuccessStatusCode();
|
||||
|
||||
await factory.WithDbContextAsync(async db =>
|
||||
{
|
||||
Assert.False(await db.Suggestions.AnyAsync(s => s.Id == id));
|
||||
var childEntity = await db.Suggestions.FindAsync(child);
|
||||
Assert.Null(childEntity!.ParentSuggestionId);
|
||||
Assert.False(db.Votes.Any(v => v.SuggestionId == id));
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user