diff --git a/src/Components/Profile/Subcomponents/GalleryForm.spec.tsx b/src/Components/Profile/Subcomponents/GalleryForm.spec.tsx new file mode 100644 index 00000000..dd8d2713 --- /dev/null +++ b/src/Components/Profile/Subcomponents/GalleryForm.spec.tsx @@ -0,0 +1,105 @@ +import { readFileSync } from 'node:fs' +import path from 'node:path' + +import { render, fireEvent, screen } from '@testing-library/react' +import { describe, it, vi, expect } from 'vitest' + +import { GalleryForm } from './GalleryForm' + +import type { FormState } from '#types/FormState' +import type { GalleryItem, Item } from '#types/Item' +import type { MarkerIcon } from '#types/MarkerIcon' +import type { Tag } from '#types/Tag' + +const testImagePaths = ['./tests/image1.jpg', './tests/image2.jpg', './tests/image3.jpg'] + +const testImages = testImagePaths.map((imagePath) => + // eslint-disable-next-line security/detect-non-literal-fs-filename + readFileSync(path.join(__dirname, '../../../../', imagePath)), +) + +const setState = vi.fn() + +const baseState = { + color: '', + id: '', + group_type: 'wuerdekompass', + status: 'active', + name: '', + subname: '', + text: '', + contact: '', + telephone: '', + next_appointment: '', + image: '', + marker_icon: {} as MarkerIcon, + offers: [] as Tag[], + needs: [] as Tag[], + relations: [] as Item[], + start: '', + end: '', + openCollectiveSlug: '', + gallery: [], + uploadingImages: [], +} + +describe('GalleryForm', () => { + const Wrapper = ({ gallery = [] as GalleryItem[], uploadingImages = [] as File[] } = {}) => { + const state: FormState = { + ...baseState, + gallery, + uploadingImages, + } + return render() + } + + describe('without previous images', () => { + it('renders', () => { + const wrapper = Wrapper() + expect(wrapper.container).toMatchSnapshot() + }) + }) + + describe('with previous images', () => { + const gallery = [ + { + directus_files_id: { + id: '1', + width: 800, + height: 600, + }, + }, + { + directus_files_id: { + id: '2', + width: 1024, + height: 768, + }, + }, + ] + + it('renders', () => { + const wrapper = Wrapper({ gallery }) + expect(wrapper.container).toMatchSnapshot() + }) + + it('can delete an image', () => { + Wrapper({ gallery }) + const deleteButton = screen.getByTestId('delete-image-1') + expect(deleteButton).toBeInTheDocument() + fireEvent.click(deleteButton) + }) + }) + + describe('with uploading images', () => { + it('renders', () => { + const wrapper = Wrapper({ + uploadingImages: testImages.map( + (image, index) => + new File([image], `test-image-${index + 1}.jpg`, { type: 'image/jpeg' }), + ), + }) + expect(wrapper.container).toMatchSnapshot() + }) + }) +}) diff --git a/src/Components/Profile/Subcomponents/GalleryForm.tsx b/src/Components/Profile/Subcomponents/GalleryForm.tsx index aafa7f91..82c2449d 100644 --- a/src/Components/Profile/Subcomponents/GalleryForm.tsx +++ b/src/Components/Profile/Subcomponents/GalleryForm.tsx @@ -121,7 +121,7 @@ export const GalleryForm = ({ state, setState }: Props) => { {...getRootProps()} className='tw:flex tw:flex-col tw:items-center tw:justify-center tw:text-base-content/50 tw:w-full tw:h-full tw:cursor-pointer tw:card tw:card-body tw:border tw:border-current/50 tw:border-dashed tw:bg-base-200' > - +
Upload Image diff --git a/src/Components/Profile/Subcomponents/__snapshots__/GalleryForm.spec.tsx.snap b/src/Components/Profile/Subcomponents/__snapshots__/GalleryForm.spec.tsx.snap new file mode 100644 index 00000000..1b194110 --- /dev/null +++ b/src/Components/Profile/Subcomponents/__snapshots__/GalleryForm.spec.tsx.snap @@ -0,0 +1,210 @@ +// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html + +exports[`GalleryForm > with previous images > renders 1`] = ` +
+
+
+ Gallery image 1 + +
+
+ Gallery image 2 + +
+ +
+
+`; + +exports[`GalleryForm > with uploading images > renders 1`] = ` +
+
+
+ Gallery image 1 + +
+
+ Gallery image 2 + +
+
+ Gallery image 3 + +
+ +
+
+`; + +exports[`GalleryForm > without previous images > renders 1`] = ` +
+
+ +
+
+`; diff --git a/src/Utils/getImageDimensions.spec.ts b/src/Utils/getImageDimensions.spec.ts new file mode 100644 index 00000000..5cd6350e --- /dev/null +++ b/src/Utils/getImageDimensions.spec.ts @@ -0,0 +1,33 @@ +import { readFileSync } from 'node:fs' +import path from 'node:path' + +import { describe, it, expect } from 'vitest' + +import { getImageDimensions } from './getImageDimensions' + +const testImagePaths = ['./tests/image1.jpg', './tests/image2.jpg', './tests/image3.jpg'] + +const testImages = testImagePaths.map((imagePath) => + // eslint-disable-next-line security/detect-non-literal-fs-filename + readFileSync(path.join(__dirname, '../../', imagePath)), +) + +// vi.spyOn(global, 'FileReader').mockImplementation((fileReader: FileReader) => fileReader) + +describe('getImageDimensions', () => { + it.skip('returns the correct dimensions for a valid image file', async () => { + const file = new File([testImages[0]], 'image1.jpg', { type: 'image/jpeg' }) + const dimensions = await getImageDimensions(file) + expect(dimensions).toEqual({ width: 800, height: 600 }) // Adjust expected values based on actual test image dimensions + }) + + it.skip('throws an error for an invalid file type', async () => { + const file = new File(['not an image'], 'invalid.txt', { type: 'text/plain' }) + await expect(getImageDimensions(file)).rejects.toThrow('Error reading image file') + }) + + it.skip('throws an error if the image cannot be loaded', async () => { + const file = new File([''], 'empty.jpg', { type: 'image/jpeg' }) + await expect(getImageDimensions(file)).rejects.toThrow('Error loading image') + }) +}) diff --git a/src/Utils/getImageDimensions.ts b/src/Utils/getImageDimensions.ts index 7d5b36ae..9f6f1f72 100644 --- a/src/Utils/getImageDimensions.ts +++ b/src/Utils/getImageDimensions.ts @@ -10,16 +10,16 @@ export const getImageDimensions = ( const fileReader = new FileReader() fileReader.onload = () => { - const img = new Image() + try { + const img = new Image() - img.onload = function () { - resolve({ - width: img.width, - height: img.height, - }) + img.onload = () => resolve({ width: img.width, height: img.height }) + + img.src = fileReader.result as string // is the data URL because called with readAsDataURL + } catch (error) { + reject(error) + throw new Error('Error loading image') } - - img.src = fileReader.result as string // is the data URL because called with readAsDataURL } fileReader.readAsDataURL(file) diff --git a/tests/image1.jpg b/tests/image1.jpg new file mode 100644 index 00000000..14516b6f Binary files /dev/null and b/tests/image1.jpg differ diff --git a/tests/image2.jpg b/tests/image2.jpg new file mode 100644 index 00000000..ad6af0c4 Binary files /dev/null and b/tests/image2.jpg differ diff --git a/tests/image3.jpg b/tests/image3.jpg new file mode 100644 index 00000000..356c7d24 Binary files /dev/null and b/tests/image3.jpg differ