feat(recipes): image upload, fix save 500, HelloFresh seed data #53

Merged
marcel merged 50 commits from feat/issue-46-wire-suggestions-recipe-picker into master 2026-04-10 10:18:10 +02:00
2 changed files with 28 additions and 0 deletions
Showing only changes of commit 56e6143fd2 - Show all commits

View File

@@ -64,6 +64,7 @@
let imageError = $state<string | null>(null);
const MAX_IMAGE_BYTES = 5 * 1024 * 1024;
const ALLOWED_MIME_TYPES = ['image/jpeg', 'image/jpg', 'image/png', 'image/gif', 'image/webp'];
function handleImageChange(e: Event) {
const file = (e.currentTarget as HTMLInputElement).files?.[0];
@@ -73,6 +74,11 @@
(e.currentTarget as HTMLInputElement).value = '';
return;
}
if (!ALLOWED_MIME_TYPES.includes(file.type)) {
imageError = 'Dateityp nicht unterstützt. Erlaubt: JPEG, PNG, GIF, WebP.';
(e.currentTarget as HTMLInputElement).value = '';
return;
}
imageError = null;
const reader = new FileReader();
reader.onload = () => {

View File

@@ -189,4 +189,26 @@ describe('RecipeForm', () => {
expect(screen.queryByText(/datei zu groß/i)).not.toBeInTheDocument();
});
it('shows error when selected file has unsupported type', async () => {
const user = userEvent.setup();
render(RecipeForm, { props: emptyProps });
const bmpFile = new File(['content'], 'image.bmp', { type: 'image/bmp' });
const fileInput = document.querySelector('input[type="file"]') as HTMLInputElement;
await user.upload(fileInput, bmpFile);
expect(screen.getByText(/dateityp/i)).toBeInTheDocument();
});
it('does not show type error for supported image types', async () => {
const user = userEvent.setup();
render(RecipeForm, { props: emptyProps });
const jpgFile = new File(['content'], 'photo.jpg', { type: 'image/jpeg' });
const fileInput = document.querySelector('input[type="file"]') as HTMLInputElement;
await user.upload(fileInput, jpgFile);
expect(screen.queryByText(/dateityp/i)).not.toBeInTheDocument();
});
});