diff --git a/Endpoints/AdminWorkflowService.cs b/Endpoints/AdminWorkflowService.cs index b869bed..973bb09 100644 --- a/Endpoints/AdminWorkflowService.cs +++ b/Endpoints/AdminWorkflowService.cs @@ -9,7 +9,7 @@ internal sealed class AdminWorkflowService(AppDbContext db) { public async Task SetResultsOpenAsync(bool resultsOpen) { - var state = await db.AppState.FirstAsync(); + var state = await db.AppState.SingleAsync(); state.ResultsOpen = resultsOpen; state.UpdatedAt = DateTimeOffset.UtcNow; @@ -26,7 +26,7 @@ internal sealed class AdminWorkflowService(AppDbContext db) await db.SaveChangesAsync(); await tx.CommitAsync(); - var currentState = await db.AppState.AsNoTracking().FirstAsync(); + var currentState = await db.AppState.AsNoTracking().SingleAsync(); return Results.Ok(new AdminResultsStateResponse(currentState.ResultsOpen, currentState.UpdatedAt)); } @@ -186,7 +186,7 @@ internal sealed class AdminWorkflowService(AppDbContext db) await db.Suggestions.ExecuteDeleteAsync(); await db.Players.ExecuteUpdateAsync(p => p.SetProperty(x => x.CurrentPhase, Phase.Suggest).SetProperty(x => x.VotesFinal, false).SetProperty(x => x.HasJoker, false)); - var state = await db.AppState.FirstAsync(); + var state = await db.AppState.SingleAsync(); state.ResultsOpen = false; state.UpdatedAt = DateTimeOffset.UtcNow; await db.SaveChangesAsync(); diff --git a/Endpoints/EndpointHelpers.cs b/Endpoints/EndpointHelpers.cs index b55cbeb..e8c0b7d 100644 --- a/Endpoints/EndpointHelpers.cs +++ b/Endpoints/EndpointHelpers.cs @@ -44,7 +44,7 @@ internal static class EndpointHelpers if (playerPhase is null) return Phase.Suggest; - var resultsOpen = await db.AppState.AsNoTracking().Select(s => s.ResultsOpen).FirstAsync(); + var resultsOpen = await db.AppState.AsNoTracking().Select(s => s.ResultsOpen).SingleAsync(); return GetCurrentPhase(playerPhase.Value, resultsOpen); } diff --git a/Endpoints/ResultsWorkflowService.cs b/Endpoints/ResultsWorkflowService.cs index 2854bcb..aed8267 100644 --- a/Endpoints/ResultsWorkflowService.cs +++ b/Endpoints/ResultsWorkflowService.cs @@ -9,7 +9,7 @@ internal sealed class ResultsWorkflowService(AppDbContext db) { public async Task GetResultsAsync(Guid playerId) { - var appState = await db.AppState.AsNoTracking().FirstAsync(); + var appState = await db.AppState.AsNoTracking().SingleAsync(); if (!appState.ResultsOpen) return EndpointHelpers.BadRequestError("Results are locked until the admin enables them."); diff --git a/Endpoints/StateWorkflowService.cs b/Endpoints/StateWorkflowService.cs index dc5ccea..8e11142 100644 --- a/Endpoints/StateWorkflowService.cs +++ b/Endpoints/StateWorkflowService.cs @@ -9,7 +9,7 @@ internal sealed class StateWorkflowService(AppDbContext db) { public async Task GetStateAsync(Player player) { - var state = await db.AppState.AsNoTracking().FirstAsync(); + var state = await db.AppState.AsNoTracking().SingleAsync(); var phase = EndpointHelpers.GetCurrentPhase(player.CurrentPhase, state.ResultsOpen); var summary = new StateSummaryResponse( phase, @@ -26,7 +26,7 @@ internal sealed class StateWorkflowService(AppDbContext db) public async Task GetMeAsync(Player player) { - var state = await db.AppState.AsNoTracking().FirstAsync(); + var state = await db.AppState.AsNoTracking().SingleAsync(); var phase = EndpointHelpers.GetCurrentPhase(player.CurrentPhase, state.ResultsOpen); return Results.Ok(new MeResponse( player.Id, @@ -41,7 +41,7 @@ internal sealed class StateWorkflowService(AppDbContext db) public async Task NextPhaseAsync(Player player) { - var appState = await db.AppState.FirstAsync(); + var appState = await db.AppState.SingleAsync(); var shouldSave = EndpointHelpers.ReconcilePlayerPhase(player, appState.ResultsOpen); try @@ -75,7 +75,7 @@ internal sealed class StateWorkflowService(AppDbContext db) if (!player.IsAdmin) return EndpointHelpers.BadRequestError("Only admins can move backward."); - var appState = await db.AppState.FirstAsync(); + var appState = await db.AppState.SingleAsync(); _ = EndpointHelpers.ReconcilePlayerPhase(player, appState.ResultsOpen); player.CurrentPhase = PrevPhase(player.CurrentPhase); diff --git a/GameList.Tests/AdminTests.cs b/GameList.Tests/AdminTests.cs index 22f88bf..a407b58 100644 --- a/GameList.Tests/AdminTests.cs +++ b/GameList.Tests/AdminTests.cs @@ -244,7 +244,7 @@ public class AdminTests { var p = await db.Players.FirstAsync(x => !x.IsAdmin); p.VotesFinal = true; - var state = await db.AppState.FirstAsync(); + var state = await db.AppState.SingleAsync(); state.UpdatedAt = DateTimeOffset.UnixEpoch; await db.SaveChangesAsync(); }); @@ -257,7 +257,7 @@ public class AdminTests var p = await db.Players.FirstAsync(x => !x.IsAdmin); Assert.Equal(Phase.Vote, p.CurrentPhase); Assert.False(p.VotesFinal); - var state = await db.AppState.AsNoTracking().FirstAsync(); + var state = await db.AppState.AsNoTracking().SingleAsync(); Assert.False(state.ResultsOpen); Assert.True(state.UpdatedAt > DateTimeOffset.UnixEpoch); }); @@ -433,7 +433,7 @@ public class AdminTests var player = await db.Players.SingleAsync(x => x.Username == "flags"); Assert.False(player.HasJoker); Assert.False(player.VotesFinal); - var state = await db.AppState.AsNoTracking().FirstAsync(); + var state = await db.AppState.AsNoTracking().SingleAsync(); Assert.False(state.ResultsOpen); }); @@ -441,7 +441,7 @@ public class AdminTests factoryReset.EnsureSuccessStatusCode(); await factory.WithDbContextAsync(async db => { - var state = await db.AppState.AsNoTracking().FirstAsync(); + var state = await db.AppState.AsNoTracking().SingleAsync(); Assert.False(state.ResultsOpen); }); } diff --git a/GameList.Tests/AuthTests.cs b/GameList.Tests/AuthTests.cs index cae84bf..c0fd0a0 100644 --- a/GameList.Tests/AuthTests.cs +++ b/GameList.Tests/AuthTests.cs @@ -71,7 +71,7 @@ public class AuthTests await factory.WithDbContextAsync(async db => { - var player = await db.Players.FirstAsync(); + var player = await db.Players.SingleAsync(); player.DisplayName = null; player.LastLoginAt = DateTimeOffset.UnixEpoch; await db.SaveChangesAsync(); diff --git a/GameList.Tests/FiltersTests.cs b/GameList.Tests/FiltersTests.cs index 72b9b9d..7e15a90 100644 --- a/GameList.Tests/FiltersTests.cs +++ b/GameList.Tests/FiltersTests.cs @@ -91,7 +91,7 @@ public class FiltersTests DisplayName = "User" }; db.Players.Add(player); - var state = await db.AppState.FirstAsync(); + var state = await db.AppState.SingleAsync(); state.ResultsOpen = resultsOpen; await db.SaveChangesAsync(); diff --git a/GameList.Tests/StateTests.cs b/GameList.Tests/StateTests.cs index 8206b78..b873894 100644 --- a/GameList.Tests/StateTests.cs +++ b/GameList.Tests/StateTests.cs @@ -19,7 +19,7 @@ public class StateTests await client.RegisterAsync("payload"); await factory.WithDbContextAsync(async db => { - var player = await db.Players.FirstAsync(); + var player = await db.Players.SingleAsync(); player.HasJoker = true; await db.SaveChangesAsync(); }); @@ -55,7 +55,7 @@ public class StateTests }; playerId = player.Id; db.Players.Add(player); - var state = await db.AppState.FirstAsync(); + var state = await db.AppState.SingleAsync(); state.ResultsOpen = true; await db.SaveChangesAsync(); }); @@ -69,7 +69,7 @@ public class StateTests await factory.WithDbContextAsync(async db => { - var state = await db.AppState.FirstAsync(); + var state = await db.AppState.SingleAsync(); state.ResultsOpen = false; await db.SaveChangesAsync(); }); @@ -95,7 +95,7 @@ public class StateTests await factory.WithDbContextAsync(async db => { - var player = await db.Players.FirstAsync(); + var player = await db.Players.SingleAsync(); player.VotesFinal = true; await db.SaveChangesAsync(); }); @@ -127,7 +127,7 @@ public class StateTests await admin.PostAsJsonAsync("/api/me/phase/next", new { }); // Vote await factory.WithDbContextAsync(async db => { - var player = await db.Players.FirstAsync(); + var player = await db.Players.SingleAsync(); player.VotesFinal = true; await db.SaveChangesAsync(); }); @@ -255,7 +255,7 @@ public class StateTests await factory.WithDbContextAsync(async db => { - var player = await db.Players.FirstAsync(); + var player = await db.Players.SingleAsync(); db.Players.Remove(player); await db.SaveChangesAsync(); }); @@ -284,10 +284,10 @@ public class StateTests await factory.WithDbContextAsync(async db => { - var player = await db.Players.FirstAsync(); + var player = await db.Players.SingleAsync(); player.CurrentPhase = Phase.Results; player.VotesFinal = true; - var state = await db.AppState.FirstAsync(); + var state = await db.AppState.SingleAsync(); state.ResultsOpen = false; await db.SaveChangesAsync(); }); @@ -300,7 +300,7 @@ public class StateTests await factory.WithDbContextAsync(async db => { - var player = await db.Players.AsNoTracking().FirstAsync(); + var player = await db.Players.AsNoTracking().SingleAsync(); Assert.Equal(Phase.Results, player.CurrentPhase); Assert.True(player.VotesFinal); }); @@ -323,17 +323,18 @@ public class StateTests CurrentPhase = Phase.Vote }; db.Players.Add(player); - var state = await db.AppState.FirstAsync(); + var state = await db.AppState.SingleAsync(); state.ResultsOpen = true; await db.SaveChangesAsync(); }); using var scope = factory.Services.CreateScope(); var db = scope.ServiceProvider.GetRequiredService(); - var playerId = await db.Players.Select(p => p.Id).FirstAsync(); + var playerId = await db.Players.Select(p => p.Id).SingleAsync(); var phase = await Endpoints.EndpointHelpers.GetCurrentPhaseAsync(db, playerId); Assert.Equal(Phase.Results, phase); } } + diff --git a/GameList.Tests/SuggestionTests.cs b/GameList.Tests/SuggestionTests.cs index 3a95a2c..46b6001 100644 --- a/GameList.Tests/SuggestionTests.cs +++ b/GameList.Tests/SuggestionTests.cs @@ -91,7 +91,7 @@ public class SuggestionTests await factory.WithDbContextAsync(async db => { - var p = await db.Players.FirstAsync(); + var p = await db.Players.SingleAsync(x => x.Username == "joker"); p.HasJoker = true; p.CurrentPhase = Domain.Phase.Vote; var o = await db.Players.SingleAsync(x => x.Username == "other"); @@ -114,7 +114,7 @@ public class SuggestionTests await factory.WithDbContextAsync(async db => { - var p = await db.Players.FirstAsync(); + var p = await db.Players.SingleAsync(x => x.Username == "joker"); Assert.False(p.HasJoker); Assert.False(p.VotesFinal); var o = await db.Players.SingleAsync(x => x.Username == "other"); @@ -187,9 +187,9 @@ public class SuggestionTests // Move everyone to Results await factory.WithDbContextAsync(async db => { - var state = await db.AppState.FirstAsync(); + var state = await db.AppState.SingleAsync(); state.ResultsOpen = true; - var p = await db.Players.FirstAsync(); + var p = await db.Players.SingleAsync(); p.CurrentPhase = Domain.Phase.Results; await db.SaveChangesAsync(); }); @@ -267,7 +267,7 @@ public class SuggestionTests await client.PostAsJsonAsync("/api/me/phase/next", new { }); await factory.WithDbContextAsync(async db => { - var p = await db.Players.FirstAsync(); + var p = await db.Players.SingleAsync(); p.HasJoker = true; await db.SaveChangesAsync(); }); @@ -288,7 +288,7 @@ public class SuggestionTests // Grant another joker and add a seventh suggestion await factory.WithDbContextAsync(async db => { - var p = await db.Players.FirstAsync(); + var p = await db.Players.SingleAsync(); p.HasJoker = true; await db.SaveChangesAsync(); }); @@ -389,7 +389,7 @@ public class SuggestionTests await factory.WithDbContextAsync(async db => { - var p = await db.Players.FirstAsync(); + var p = await db.Players.SingleAsync(); p.CurrentPhase = Domain.Phase.Vote; p.DisplayName = null; await db.SaveChangesAsync(); @@ -410,7 +410,7 @@ public class SuggestionTests await factory.WithDbContextAsync(async db => { - var p = await db.Players.FirstAsync(); + var p = await db.Players.SingleAsync(); p.CurrentPhase = Domain.Phase.Suggest; await db.SaveChangesAsync(); }); @@ -526,7 +526,7 @@ public class SuggestionTests await factory.WithDbContextAsync(async db => { - var s = await db.Suggestions.AsNoTracking().FirstAsync(); + var s = await db.Suggestions.AsNoTracking().SingleAsync(); Assert.Equal(50, s.Genre!.Length); Assert.Equal(500, s.Description!.Length); Assert.Equal("http://example.com/img.png", s.ScreenshotUrl); diff --git a/GameList.Tests/VoteTests.cs b/GameList.Tests/VoteTests.cs index c5ed476..5ccb67d 100644 --- a/GameList.Tests/VoteTests.cs +++ b/GameList.Tests/VoteTests.cs @@ -98,7 +98,7 @@ public class VoteTests await factory.WithDbContextAsync(async db => { - var p = await db.Players.FirstAsync(); + var p = await db.Players.SingleAsync(); p.DisplayName = null; await db.SaveChangesAsync(); });