feat(recipes): image upload, fix save 500, HelloFresh seed data #53
@@ -191,11 +191,11 @@ public class RecipeService {
|
||||
// ── Image validation ──
|
||||
|
||||
private static final java.util.regex.Pattern ALLOWED_IMAGE_PATTERN =
|
||||
java.util.regex.Pattern.compile("^data:image/(jpeg|jpg|png|gif|webp);base64,");
|
||||
java.util.regex.Pattern.compile("data:image/(jpeg|jpg|png|gif|webp);base64,.*");
|
||||
|
||||
private void validateHeroImageUrl(String heroImageUrl) {
|
||||
if (heroImageUrl == null || heroImageUrl.isBlank()) return;
|
||||
if (!ALLOWED_IMAGE_PATTERN.matcher(heroImageUrl).find()) {
|
||||
if (!ALLOWED_IMAGE_PATTERN.matcher(heroImageUrl).matches()) {
|
||||
throw new ValidationException("Ungültiger Bildtyp. Erlaubt sind: JPEG, PNG, GIF, WebP.");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -12,7 +12,7 @@ public record RecipeCreateRequest(
|
||||
Integer serves,
|
||||
Integer cookTimeMin,
|
||||
@NotBlank @Pattern(regexp = "easy|medium|hard") String effort,
|
||||
String heroImageUrl,
|
||||
@Size(max = 7_000_000) String heroImageUrl,
|
||||
@NotEmpty @Valid List<IngredientEntry> ingredients,
|
||||
@Valid List<StepEntry> steps,
|
||||
@NotEmpty List<UUID> tagIds
|
||||
|
||||
@@ -161,6 +161,33 @@ class RecipeControllerTest {
|
||||
verify(recipeService).deleteRecipe(HOUSEHOLD_ID, RECIPE_ID);
|
||||
}
|
||||
|
||||
@Test
|
||||
void createRecipeWithOversizedHeroImageShouldReturn400() throws Exception {
|
||||
String heroImageUrl = "data:image/jpeg;base64," + "A".repeat(7_000_000);
|
||||
String body = "{\"name\":\"Test\",\"effort\":\"easy\",\"tagIds\":[\"" + UUID.randomUUID() + "\"]," +
|
||||
"\"ingredients\":[{\"quantity\":1,\"unit\":\"g\",\"newIngredientName\":\"x\",\"sortOrder\":0}]," +
|
||||
"\"heroImageUrl\":\"" + heroImageUrl + "\"}";
|
||||
|
||||
mockMvc.perform(post("/v1/recipes")
|
||||
.principal(() -> "sarah@example.com")
|
||||
.contentType(MediaType.APPLICATION_JSON)
|
||||
.content(body))
|
||||
.andExpect(status().isBadRequest());
|
||||
}
|
||||
|
||||
@Test
|
||||
void createRecipeWithEmptyIngredientsListShouldReturn400() throws Exception {
|
||||
var body = """
|
||||
{"name":"Test","effort":"easy","tagIds":["%s"],"ingredients":[]}
|
||||
""".formatted(UUID.randomUUID());
|
||||
|
||||
mockMvc.perform(post("/v1/recipes")
|
||||
.principal(() -> "sarah@example.com")
|
||||
.contentType(MediaType.APPLICATION_JSON)
|
||||
.content(body))
|
||||
.andExpect(status().isBadRequest());
|
||||
}
|
||||
|
||||
@Test
|
||||
void createRecipeWithCapitalisedEffortShouldReturn400() throws Exception {
|
||||
var body = """
|
||||
|
||||
Reference in New Issue
Block a user