Extract shared suggestion validation and remove dead DTO
This commit is contained in:
@@ -42,28 +42,9 @@ public static class SuggestEndpoints
|
||||
|
||||
group.MapPost("/", async ([FromBody] SuggestionRequest request, HttpContext ctx, AppDbContext db, IHttpClientFactory http) =>
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(request.Name) || request.Name.Length > 100)
|
||||
{
|
||||
return Results.BadRequest(new { error = "Name is required and must be <= 100 characters." });
|
||||
}
|
||||
|
||||
if (!EndpointHelpers.IsValidImageUrl(request.ScreenshotUrl))
|
||||
{
|
||||
return Results.BadRequest(new { error = "Screenshot URL must be http(s) and end with an image file extension." });
|
||||
}
|
||||
|
||||
if (!await EndpointHelpers.IsReachableImageAsync(request.ScreenshotUrl, http))
|
||||
{
|
||||
return Results.BadRequest(new { error = "Screenshot URL could not be validated as an image. Use a public image link (http/https, no redirects, max 5 MB)." });
|
||||
}
|
||||
|
||||
if (!EndpointHelpers.IsValidHttpUrl(request.GameUrl))
|
||||
return Results.BadRequest(new { error = "Game URL must be http or https." });
|
||||
if (!EndpointHelpers.IsValidHttpUrl(request.YoutubeUrl))
|
||||
return Results.BadRequest(new { error = "YouTube URL must be http or https." });
|
||||
|
||||
if (!ValidatePlayers(request.MinPlayers, request.MaxPlayers, out var playersError))
|
||||
return Results.BadRequest(new { error = playersError });
|
||||
var validationError = await SuggestionValidator.ValidateAsync(request, http);
|
||||
if (validationError is not null)
|
||||
return Results.BadRequest(new { error = validationError });
|
||||
|
||||
var player = await EndpointHelpers.GetAuthenticatedPlayer(ctx, db);
|
||||
if (player is null)
|
||||
@@ -149,28 +130,9 @@ public static class SuggestEndpoints
|
||||
if (!isAdmin && player is null)
|
||||
return Results.Unauthorized();
|
||||
|
||||
if (string.IsNullOrWhiteSpace(request.Name) || request.Name.Length > 100)
|
||||
{
|
||||
return Results.BadRequest(new { error = "Name is required and must be <= 100 characters." });
|
||||
}
|
||||
|
||||
if (!EndpointHelpers.IsValidImageUrl(request.ScreenshotUrl))
|
||||
{
|
||||
return Results.BadRequest(new { error = "Screenshot URL must be http(s) and end with an image file extension." });
|
||||
}
|
||||
|
||||
if (!await EndpointHelpers.IsReachableImageAsync(request.ScreenshotUrl, http))
|
||||
{
|
||||
return Results.BadRequest(new { error = "Screenshot URL could not be validated as an image. Use a public image link (http/https, no redirects, max 5 MB)." });
|
||||
}
|
||||
|
||||
if (!EndpointHelpers.IsValidHttpUrl(request.GameUrl))
|
||||
return Results.BadRequest(new { error = "Game URL must be http or https." });
|
||||
if (!EndpointHelpers.IsValidHttpUrl(request.YoutubeUrl))
|
||||
return Results.BadRequest(new { error = "YouTube URL must be http or https." });
|
||||
|
||||
if (!ValidatePlayers(request.MinPlayers, request.MaxPlayers, out var playersError))
|
||||
return Results.BadRequest(new { error = playersError });
|
||||
var validationError = await SuggestionValidator.ValidateAsync(request, http);
|
||||
if (validationError is not null)
|
||||
return Results.BadRequest(new { error = validationError });
|
||||
|
||||
var suggestion = await db.Suggestions.FirstOrDefaultAsync(s => s.Id == id);
|
||||
if (suggestion == null)
|
||||
@@ -294,38 +256,5 @@ public static class SuggestEndpoints
|
||||
return Results.Ok(ordered);
|
||||
});
|
||||
}
|
||||
|
||||
private static bool ValidatePlayers(int? minPlayers, int? maxPlayers, out string? error)
|
||||
{
|
||||
error = null;
|
||||
if (minPlayers is null && maxPlayers is null)
|
||||
return true;
|
||||
|
||||
if (minPlayers is < 1 or > 32)
|
||||
{
|
||||
error = "Min players must be between 1 and 32.";
|
||||
return false;
|
||||
}
|
||||
|
||||
if (maxPlayers is < 1 or > 32)
|
||||
{
|
||||
error = "Max players must be between 1 and 32.";
|
||||
return false;
|
||||
}
|
||||
|
||||
if (minPlayers is null || maxPlayers is null)
|
||||
{
|
||||
error = "Provide both min and max players.";
|
||||
return false;
|
||||
}
|
||||
|
||||
if (minPlayers > maxPlayers)
|
||||
{
|
||||
error = "Min players cannot exceed max players.";
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
46
Endpoints/SuggestionValidator.cs
Normal file
46
Endpoints/SuggestionValidator.cs
Normal file
@@ -0,0 +1,46 @@
|
||||
using GameList.Contracts;
|
||||
|
||||
namespace GameList.Endpoints;
|
||||
|
||||
internal static class SuggestionValidator
|
||||
{
|
||||
public static async Task<string?> ValidateAsync(SuggestionRequest request, IHttpClientFactory httpFactory)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(request.Name) || request.Name.Length > 100)
|
||||
return "Name is required and must be <= 100 characters.";
|
||||
|
||||
if (!EndpointHelpers.IsValidImageUrl(request.ScreenshotUrl))
|
||||
return "Screenshot URL must be http(s) and end with an image file extension.";
|
||||
|
||||
if (!await EndpointHelpers.IsReachableImageAsync(request.ScreenshotUrl, httpFactory))
|
||||
return "Screenshot URL could not be validated as an image. Use a public image link (http/https, no redirects, max 5 MB).";
|
||||
|
||||
if (!EndpointHelpers.IsValidHttpUrl(request.GameUrl))
|
||||
return "Game URL must be http or https.";
|
||||
|
||||
if (!EndpointHelpers.IsValidHttpUrl(request.YoutubeUrl))
|
||||
return "YouTube URL must be http or https.";
|
||||
|
||||
return ValidatePlayers(request.MinPlayers, request.MaxPlayers);
|
||||
}
|
||||
|
||||
private static string? ValidatePlayers(int? minPlayers, int? maxPlayers)
|
||||
{
|
||||
if (minPlayers is null && maxPlayers is null)
|
||||
return null;
|
||||
|
||||
if (minPlayers is < 1 or > 32)
|
||||
return "Min players must be between 1 and 32.";
|
||||
|
||||
if (maxPlayers is < 1 or > 32)
|
||||
return "Max players must be between 1 and 32.";
|
||||
|
||||
if (minPlayers is null || maxPlayers is null)
|
||||
return "Provide both min and max players.";
|
||||
|
||||
if (minPlayers > maxPlayers)
|
||||
return "Min players cannot exceed max players.";
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user