mirror of
https://github.com/utopia-os/utopia-ui.git
synced 2026-03-01 12:44:17 +00:00
Add tests (WIP)
This commit is contained in:
parent
71612951d1
commit
72ddc5affe
105
src/Components/Profile/Subcomponents/GalleryForm.spec.tsx
Normal file
105
src/Components/Profile/Subcomponents/GalleryForm.spec.tsx
Normal file
@ -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(<GalleryForm state={state} setState={setState} />)
|
||||
}
|
||||
|
||||
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()
|
||||
})
|
||||
})
|
||||
})
|
||||
@ -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'
|
||||
>
|
||||
<input {...getInputProps()} />
|
||||
<input {...getInputProps()} data-testid='gallery-upload-input' />
|
||||
<div>
|
||||
<BiSolidImage className='tw:h-16 tw:w-16 tw:m-auto tw:mb-2' />
|
||||
<span className='tw:text-center'>Upload Image</span>
|
||||
|
||||
@ -0,0 +1,210 @@
|
||||
// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
|
||||
|
||||
exports[`GalleryForm > with previous images > renders 1`] = `
|
||||
<div>
|
||||
<div
|
||||
class="tw:flex tw:flex-wrap tw:gap-4 tw:my-4"
|
||||
>
|
||||
<div
|
||||
class="tw:relative"
|
||||
>
|
||||
<img
|
||||
alt="Gallery image 1"
|
||||
class="tw:w-60 tw:h-60 tw:object-cover tw:rounded-lg "
|
||||
src="undefined1.jpg"
|
||||
/>
|
||||
<button
|
||||
class="tw:m-2 tw:bg-red-500 tw:text-white tw:p-2 tw:rounded-full tw:absolute tw:top-0 tw:right-0 tw:hover:bg-red-600"
|
||||
type="button"
|
||||
>
|
||||
<svg
|
||||
aria-hidden="true"
|
||||
class="tw:h-5 tw:w-5"
|
||||
data-slot="icon"
|
||||
fill="currentColor"
|
||||
viewBox="0 0 24 24"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
>
|
||||
<path
|
||||
clip-rule="evenodd"
|
||||
d="M16.5 4.478v.227a48.816 48.816 0 0 1 3.878.512.75.75 0 1 1-.256 1.478l-.209-.035-1.005 13.07a3 3 0 0 1-2.991 2.77H8.084a3 3 0 0 1-2.991-2.77L4.087 6.66l-.209.035a.75.75 0 0 1-.256-1.478A48.567 48.567 0 0 1 7.5 4.705v-.227c0-1.564 1.213-2.9 2.816-2.951a52.662 52.662 0 0 1 3.369 0c1.603.051 2.815 1.387 2.815 2.951Zm-6.136-1.452a51.196 51.196 0 0 1 3.273 0C14.39 3.05 15 3.684 15 4.478v.113a49.488 49.488 0 0 0-6 0v-.113c0-.794.609-1.428 1.364-1.452Zm-.355 5.945a.75.75 0 1 0-1.5.058l.347 9a.75.75 0 1 0 1.499-.058l-.346-9Zm5.48.058a.75.75 0 1 0-1.498-.058l-.347 9a.75.75 0 0 0 1.5.058l.345-9Z"
|
||||
fill-rule="evenodd"
|
||||
/>
|
||||
</svg>
|
||||
</button>
|
||||
</div>
|
||||
<div
|
||||
class="tw:relative"
|
||||
>
|
||||
<img
|
||||
alt="Gallery image 2"
|
||||
class="tw:w-60 tw:h-60 tw:object-cover tw:rounded-lg "
|
||||
src="undefined2.jpg"
|
||||
/>
|
||||
<button
|
||||
class="tw:m-2 tw:bg-red-500 tw:text-white tw:p-2 tw:rounded-full tw:absolute tw:top-0 tw:right-0 tw:hover:bg-red-600"
|
||||
type="button"
|
||||
>
|
||||
<svg
|
||||
aria-hidden="true"
|
||||
class="tw:h-5 tw:w-5"
|
||||
data-slot="icon"
|
||||
fill="currentColor"
|
||||
viewBox="0 0 24 24"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
>
|
||||
<path
|
||||
clip-rule="evenodd"
|
||||
d="M16.5 4.478v.227a48.816 48.816 0 0 1 3.878.512.75.75 0 1 1-.256 1.478l-.209-.035-1.005 13.07a3 3 0 0 1-2.991 2.77H8.084a3 3 0 0 1-2.991-2.77L4.087 6.66l-.209.035a.75.75 0 0 1-.256-1.478A48.567 48.567 0 0 1 7.5 4.705v-.227c0-1.564 1.213-2.9 2.816-2.951a52.662 52.662 0 0 1 3.369 0c1.603.051 2.815 1.387 2.815 2.951Zm-6.136-1.452a51.196 51.196 0 0 1 3.273 0C14.39 3.05 15 3.684 15 4.478v.113a49.488 49.488 0 0 0-6 0v-.113c0-.794.609-1.428 1.364-1.452Zm-.355 5.945a.75.75 0 1 0-1.5.058l.347 9a.75.75 0 1 0 1.499-.058l-.346-9Zm5.48.058a.75.75 0 1 0-1.498-.058l-.347 9a.75.75 0 0 0 1.5.058l.345-9Z"
|
||||
fill-rule="evenodd"
|
||||
/>
|
||||
</svg>
|
||||
</button>
|
||||
</div>
|
||||
<div
|
||||
class="tw:flex tw:center tw:w-60 tw:h-60 tw:cursor-pointer tw:border tw:border-dashed tw:border-gray-300 tw:p-4 tw:rounded-lg"
|
||||
role="presentation"
|
||||
tabindex="0"
|
||||
>
|
||||
<input
|
||||
accept="image/jpeg"
|
||||
data-testid="gallery-upload-input"
|
||||
multiple=""
|
||||
style="border: 0px; clip: rect(0, 0, 0, 0); clip-path: inset(50%); height: 1px; margin: 0px -1px -1px 0px; overflow: hidden; padding: 0px; position: absolute; width: 1px; white-space: nowrap;"
|
||||
tabindex="-1"
|
||||
type="file"
|
||||
/>
|
||||
<svg
|
||||
aria-hidden="true"
|
||||
class="tw:h-8 tw:w-8 tw:m-auto"
|
||||
data-slot="icon"
|
||||
fill="none"
|
||||
stroke="currentColor"
|
||||
stroke-width="1.5"
|
||||
viewBox="0 0 24 24"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
>
|
||||
<path
|
||||
d="M3 16.5v2.25A2.25 2.25 0 0 0 5.25 21h13.5A2.25 2.25 0 0 0 21 18.75V16.5m-13.5-9L12 3m0 0 4.5 4.5M12 3v13.5"
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
/>
|
||||
</svg>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
|
||||
exports[`GalleryForm > with uploading images > renders 1`] = `
|
||||
<div>
|
||||
<div
|
||||
class="tw:flex tw:flex-wrap tw:gap-4 tw:my-4"
|
||||
>
|
||||
<div
|
||||
class="tw:relative"
|
||||
>
|
||||
<img
|
||||
alt="Gallery image 1"
|
||||
class="tw:w-60 tw:h-60 tw:object-cover tw:rounded-lg tw:opacity-50"
|
||||
src="blob:nodedata:ce8d6df7-ec41-40a0-b77b-eebfdcd76e47"
|
||||
/>
|
||||
<span
|
||||
class="tw:loading tw:loading-spinner tw:absolute tw:inset-0 tw:m-auto"
|
||||
/>
|
||||
</div>
|
||||
<div
|
||||
class="tw:relative"
|
||||
>
|
||||
<img
|
||||
alt="Gallery image 2"
|
||||
class="tw:w-60 tw:h-60 tw:object-cover tw:rounded-lg tw:opacity-50"
|
||||
src="blob:nodedata:d65c4061-dc86-40ee-a1da-7e783a6db3ce"
|
||||
/>
|
||||
<span
|
||||
class="tw:loading tw:loading-spinner tw:absolute tw:inset-0 tw:m-auto"
|
||||
/>
|
||||
</div>
|
||||
<div
|
||||
class="tw:relative"
|
||||
>
|
||||
<img
|
||||
alt="Gallery image 3"
|
||||
class="tw:w-60 tw:h-60 tw:object-cover tw:rounded-lg tw:opacity-50"
|
||||
src="blob:nodedata:c989c354-4d76-40f2-91d5-476399d52f64"
|
||||
/>
|
||||
<span
|
||||
class="tw:loading tw:loading-spinner tw:absolute tw:inset-0 tw:m-auto"
|
||||
/>
|
||||
</div>
|
||||
<div
|
||||
class="tw:flex tw:center tw:w-60 tw:h-60 tw:cursor-pointer tw:border tw:border-dashed tw:border-gray-300 tw:p-4 tw:rounded-lg"
|
||||
role="presentation"
|
||||
tabindex="0"
|
||||
>
|
||||
<input
|
||||
accept="image/jpeg"
|
||||
data-testid="gallery-upload-input"
|
||||
multiple=""
|
||||
style="border: 0px; clip: rect(0, 0, 0, 0); clip-path: inset(50%); height: 1px; margin: 0px -1px -1px 0px; overflow: hidden; padding: 0px; position: absolute; width: 1px; white-space: nowrap;"
|
||||
tabindex="-1"
|
||||
type="file"
|
||||
/>
|
||||
<svg
|
||||
aria-hidden="true"
|
||||
class="tw:h-8 tw:w-8 tw:m-auto"
|
||||
data-slot="icon"
|
||||
fill="none"
|
||||
stroke="currentColor"
|
||||
stroke-width="1.5"
|
||||
viewBox="0 0 24 24"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
>
|
||||
<path
|
||||
d="M3 16.5v2.25A2.25 2.25 0 0 0 5.25 21h13.5A2.25 2.25 0 0 0 21 18.75V16.5m-13.5-9L12 3m0 0 4.5 4.5M12 3v13.5"
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
/>
|
||||
</svg>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
|
||||
exports[`GalleryForm > without previous images > renders 1`] = `
|
||||
<div>
|
||||
<div
|
||||
class="tw:flex tw:flex-wrap tw:gap-4 tw:my-4"
|
||||
>
|
||||
<div
|
||||
class="tw:flex tw:center tw:w-60 tw:h-60 tw:cursor-pointer tw:border tw:border-dashed tw:border-gray-300 tw:p-4 tw:rounded-lg"
|
||||
role="presentation"
|
||||
tabindex="0"
|
||||
>
|
||||
<input
|
||||
accept="image/jpeg"
|
||||
data-testid="gallery-upload-input"
|
||||
multiple=""
|
||||
style="border: 0px; clip: rect(0, 0, 0, 0); clip-path: inset(50%); height: 1px; margin: 0px -1px -1px 0px; overflow: hidden; padding: 0px; position: absolute; width: 1px; white-space: nowrap;"
|
||||
tabindex="-1"
|
||||
type="file"
|
||||
/>
|
||||
<svg
|
||||
aria-hidden="true"
|
||||
class="tw:h-8 tw:w-8 tw:m-auto"
|
||||
data-slot="icon"
|
||||
fill="none"
|
||||
stroke="currentColor"
|
||||
stroke-width="1.5"
|
||||
viewBox="0 0 24 24"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
>
|
||||
<path
|
||||
d="M3 16.5v2.25A2.25 2.25 0 0 0 5.25 21h13.5A2.25 2.25 0 0 0 21 18.75V16.5m-13.5-9L12 3m0 0 4.5 4.5M12 3v13.5"
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
/>
|
||||
</svg>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
33
src/Utils/getImageDimensions.spec.ts
Normal file
33
src/Utils/getImageDimensions.spec.ts
Normal file
@ -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')
|
||||
})
|
||||
})
|
||||
@ -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)
|
||||
|
||||
BIN
tests/image1.jpg
Normal file
BIN
tests/image1.jpg
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 3.4 MiB |
BIN
tests/image2.jpg
Normal file
BIN
tests/image2.jpg
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 3.6 MiB |
BIN
tests/image3.jpg
Normal file
BIN
tests/image3.jpg
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 3.5 MiB |
Loading…
x
Reference in New Issue
Block a user