Files
GameList/GameList.Tests/VoteTests.cs

195 lines
7.6 KiB
C#

using System.Net;
using System.Net.Http.Json;
using System.Text.Json;
using GameList.Tests.Support;
using Microsoft.EntityFrameworkCore;
namespace GameList.Tests;
public class VoteTests
{
[Fact]
public async Task Finalizing_votes_blocks_further_changes()
{
using var factory = new TestWebApplicationFactory();
var client = factory.CreateClientWithCookies();
await client.RegisterAsync("voter");
var suggestionId = await client.CreateSuggestionAsync("VoteGame");
await client.PostAsJsonAsync("/api/me/phase/next", new { });
var vote = await client.PostAsJsonAsync("/api/votes", new { SuggestionId = suggestionId, Score = 7 });
vote.EnsureSuccessStatusCode();
var finalize = await client.PostAsJsonAsync("/api/votes/finalize", new { Final = true });
finalize.EnsureSuccessStatusCode();
var change = await client.PostAsJsonAsync("/api/votes", new { SuggestionId = suggestionId, Score = 5 });
Assert.Equal(HttpStatusCode.BadRequest, change.StatusCode);
}
[Fact]
public async Task Score_out_of_range_rejected()
{
using var factory = new TestWebApplicationFactory();
var client = factory.CreateClientWithCookies();
await client.RegisterAsync("score");
var id = await client.CreateSuggestionAsync("RangeGame");
await client.PostAsJsonAsync("/api/me/phase/next", new { });
var resp = await client.PostAsJsonAsync("/api/votes", new { SuggestionId = id, Score = 11 });
Assert.Equal(HttpStatusCode.BadRequest, resp.StatusCode);
}
[Fact]
public async Task Negative_score_rejected()
{
using var factory = new TestWebApplicationFactory();
var client = factory.CreateClientWithCookies();
await client.RegisterAsync("negative");
var id = await client.CreateSuggestionAsync("RangeGame2");
await client.PostAsJsonAsync("/api/me/phase/next", new { });
var resp = await client.PostAsJsonAsync("/api/votes", new { SuggestionId = id, Score = -1 });
Assert.Equal(HttpStatusCode.BadRequest, resp.StatusCode);
}
[Fact]
public async Task Invalid_suggestion_id_rejected()
{
using var factory = new TestWebApplicationFactory();
var client = factory.CreateClientWithCookies();
await client.RegisterAsync("invalid");
await client.PostAsJsonAsync("/api/me/phase/next", new { });
var resp = await client.PostAsJsonAsync("/api/votes", new { SuggestionId = 9999, Score = 5 });
Assert.Equal(HttpStatusCode.BadRequest, resp.StatusCode);
}
[Fact]
public async Task Votes_require_display_name()
{
using var factory = new TestWebApplicationFactory();
var client = factory.CreateClientWithCookies();
await client.RegisterAsync("anon");
var id = await client.CreateSuggestionAsync("NeedName");
await factory.WithDbContextAsync(async db =>
{
var p = await db.Players.FirstAsync();
p.DisplayName = null;
await db.SaveChangesAsync();
});
await client.PostAsJsonAsync("/api/me/phase/next", new { });
var resp = await client.PostAsJsonAsync("/api/votes", new { SuggestionId = id, Score = 5 });
Assert.Equal(HttpStatusCode.BadRequest, resp.StatusCode);
}
[Fact]
public async Task Finalize_only_in_vote_phase()
{
using var factory = new TestWebApplicationFactory();
var client = factory.CreateClientWithCookies();
await client.RegisterAsync("phase");
var resp = await client.PostAsJsonAsync("/api/votes/finalize", new { Final = true });
Assert.Equal(HttpStatusCode.BadRequest, resp.StatusCode);
}
[Fact]
public async Task Finalize_toggle_allows_unfinalize()
{
using var factory = new TestWebApplicationFactory();
var client = factory.CreateClientWithCookies();
await client.RegisterAsync("toggle");
var id = await client.CreateSuggestionAsync("Toggle");
await client.PostAsJsonAsync("/api/me/phase/next", new { });
await client.PostAsJsonAsync("/api/votes", new { SuggestionId = id, Score = 5 });
var finalize = await client.PostAsJsonAsync("/api/votes/finalize", new { Final = true });
finalize.EnsureSuccessStatusCode();
var unfinalize = await client.PostAsJsonAsync("/api/votes/finalize", new { Final = false });
unfinalize.EnsureSuccessStatusCode();
var me = await client.GetFromJsonAsync<JsonElement>("/api/me");
Assert.False(me.GetProperty("votesFinal").GetBoolean());
}
[Fact]
public async Task Linked_votes_apply_to_all_linked_suggestions()
{
using var factory = new TestWebApplicationFactory();
var admin = factory.CreateClientWithCookies();
await admin.RegisterAsync("admin", admin: true);
await admin.PostAsJsonAsync("/api/me/phase/next", new { });
var player = factory.CreateClientWithCookies();
await player.RegisterAsync("linker");
var id1 = await player.CreateSuggestionAsync("Game A");
var id2 = await player.CreateSuggestionAsync("Game B");
await player.PostAsJsonAsync("/api/me/phase/next", new { });
var linkResponse = await admin.PostAsJsonAsync("/api/admin/link-suggestions", new { SourceSuggestionId = id1, TargetSuggestionId = id2 });
linkResponse.EnsureSuccessStatusCode();
var vote = await player.PostAsJsonAsync("/api/votes", new { SuggestionId = id1, Score = 9 });
vote.EnsureSuccessStatusCode();
var mine = await player.GetFromJsonAsync<List<VoteRecord>>("/api/votes/mine");
Assert.NotNull(mine);
Assert.Equal(2, mine!.Count);
Assert.All(mine, v => Assert.Equal(9, v.Score));
}
[Fact]
public async Task Linked_votes_apply_across_chain()
{
using var factory = new TestWebApplicationFactory();
var admin = factory.CreateClientWithCookies();
await admin.RegisterAsync("admin", admin: true);
await admin.PostAsJsonAsync("/api/me/phase/next", new { });
var player = factory.CreateClientWithCookies();
await player.RegisterAsync("chain");
var a = await player.CreateSuggestionAsync("A");
var b = await player.CreateSuggestionAsync("B");
var c = await player.CreateSuggestionAsync("C");
await player.PostAsJsonAsync("/api/me/phase/next", new { });
await admin.PostAsJsonAsync("/api/admin/link-suggestions", new { SourceSuggestionId = a, TargetSuggestionId = b });
await admin.PostAsJsonAsync("/api/admin/link-suggestions", new { SourceSuggestionId = b, TargetSuggestionId = c });
var vote = await player.PostAsJsonAsync("/api/votes", new { SuggestionId = c, Score = 6 });
vote.EnsureSuccessStatusCode();
var mine = await player.GetFromJsonAsync<List<VoteRecord>>("/api/votes/mine");
Assert.NotNull(mine);
Assert.Equal(3, mine!.Count);
Assert.All(mine, v => Assert.Equal(6, v.Score));
}
[Fact]
public async Task Votes_mine_requires_vote_phase_and_auth()
{
using var factory = new TestWebApplicationFactory();
var anon = factory.CreateClient();
var unauth = await anon.GetAsync("/api/votes/mine");
Assert.Equal(HttpStatusCode.Unauthorized, unauth.StatusCode);
var client = factory.CreateClientWithCookies();
await client.RegisterAsync("phaseguard");
var resp = await client.GetAsync("/api/votes/mine");
Assert.Equal(HttpStatusCode.BadRequest, resp.StatusCode);
}
private record VoteRecord(int SuggestionId, int Score);
}