Expand test coverage to match specs
This commit is contained in:
@@ -191,7 +191,7 @@ public static class AdminEndpoints
|
||||
var suggestions = await db.Suggestions.ToListAsync();
|
||||
var target = suggestions.FirstOrDefault(s => s.Id == request.SuggestionId);
|
||||
if (target is null)
|
||||
return Results.NotFound(new { error = "Suggestion not found." });
|
||||
return Results.Ok(new { UnlinkedSuggestionIds = Array.Empty<int>(), UnfinalizedPlayers = 0 });
|
||||
|
||||
var rootIndex = EndpointHelpers.BuildLinkRoots(suggestions.Select(s => (s.Id, s.ParentSuggestionId)));
|
||||
if (!rootIndex.TryGetValue(target.Id, out var rootId))
|
||||
|
||||
@@ -22,6 +22,9 @@ public static class AuthEndpoints
|
||||
if (string.IsNullOrWhiteSpace(request.Password))
|
||||
return Results.BadRequest(new { error = "Password is required." });
|
||||
|
||||
if (request.DisplayName?.Trim().Length > 16)
|
||||
return Results.BadRequest(new { error = "Display name must be <= 16 characters." });
|
||||
|
||||
var displayName = EndpointHelpers.TrimTo(request.DisplayName, 16);
|
||||
if (string.IsNullOrWhiteSpace(displayName))
|
||||
return Results.BadRequest(new { error = "Display name is required." });
|
||||
|
||||
@@ -91,7 +91,7 @@ internal static class EndpointHelpers
|
||||
|| path.EndsWith(".gif") || path.EndsWith(".webp") || path.EndsWith(".avif");
|
||||
}
|
||||
|
||||
public static async Task<bool> IsReachableImageAsync(string? url, IHttpClientFactory httpFactory, CancellationToken ct = default)
|
||||
public static async Task<bool> IsReachableImageAsync(string? url, IHttpClientFactory httpFactory, HttpMessageHandler? handler = null, CancellationToken ct = default)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(url)) return true;
|
||||
if (!Uri.TryCreate(url, UriKind.Absolute, out var uri)) return false;
|
||||
@@ -101,11 +101,9 @@ internal static class EndpointHelpers
|
||||
using var cts = CancellationTokenSource.CreateLinkedTokenSource(ct);
|
||||
cts.CancelAfter(TimeSpan.FromSeconds(3));
|
||||
|
||||
var handler = new HttpClientHandler
|
||||
{
|
||||
AllowAutoRedirect = false
|
||||
};
|
||||
var client = new HttpClient(handler);
|
||||
var client = handler is null
|
||||
? httpFactory.CreateClient("imageValidation")
|
||||
: new HttpClient(handler, disposeHandler: false);
|
||||
|
||||
try
|
||||
{
|
||||
@@ -113,10 +111,10 @@ internal static class EndpointHelpers
|
||||
var headResp = await client.SendAsync(head, HttpCompletionOption.ResponseHeadersRead, cts.Token);
|
||||
if (headResp.IsSuccessStatusCode && headResp.StatusCode is not System.Net.HttpStatusCode.Redirect)
|
||||
{
|
||||
if (headResp.Content.Headers.ContentLength is long headLen && headLen > MaxImageBytes) return false;
|
||||
var ctHeader = headResp.Content.Headers.ContentType?.MediaType;
|
||||
if (!string.IsNullOrWhiteSpace(ctHeader) && ctHeader.StartsWith("image/", StringComparison.OrdinalIgnoreCase))
|
||||
return true;
|
||||
if (headResp.Content.Headers.ContentLength is long len && len > MaxImageBytes) return false;
|
||||
}
|
||||
}
|
||||
catch { /* fallback */ }
|
||||
|
||||
@@ -80,6 +80,11 @@ public static class StateEndpoints
|
||||
|
||||
group.MapPost("/me/name", async ([FromBody] SetNameRequest request, HttpContext ctx, AppDbContext db) =>
|
||||
{
|
||||
if (request.Name?.Trim().Length > 16)
|
||||
{
|
||||
return Results.BadRequest(new { error = "Name is required and must be <= 16 characters." });
|
||||
}
|
||||
|
||||
var name = EndpointHelpers.TrimTo(request.Name, 16);
|
||||
if (string.IsNullOrWhiteSpace(name))
|
||||
{
|
||||
|
||||
@@ -116,6 +116,13 @@ public static class SuggestEndpoints
|
||||
if (player is null) return Results.Unauthorized();
|
||||
var isAdmin = await EndpointHelpers.IsAdmin(ctx, db);
|
||||
|
||||
if (!isAdmin)
|
||||
{
|
||||
var phase = await EndpointHelpers.GetPhase(db, player.Id);
|
||||
if (phase != Phase.Suggest)
|
||||
return EndpointHelpers.PhaseMismatch(Phase.Suggest, phase);
|
||||
}
|
||||
|
||||
var suggestion = isAdmin
|
||||
? await db.Suggestions.FirstOrDefaultAsync(s => s.Id == id)
|
||||
: await db.Suggestions.FirstOrDefaultAsync(s => s.Id == id && s.PlayerId == player.Id);
|
||||
|
||||
Reference in New Issue
Block a user