Skip to content

Commit 5541991

Browse files
authored
Merge pull request #1079 from ensdomains/feature/fet-2590-app-v3-header-zoom-is-unresponsive
Refactor HeaderCrop component to fix zoom functionality
2 parents 7c67803 + a0f4e3e commit 5541991

File tree

4 files changed

+348
-388
lines changed

4 files changed

+348
-388
lines changed
Lines changed: 144 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,144 @@
1+
import { fireEvent, mockFunction, render, screen, waitFor } from '@app/test-utils'
2+
import { beforeAll, describe, expect, it, vi } from 'vitest'
3+
4+
import { makeMockIntersectionObserver } from '../../../../../test/mock/makeMockIntersectionObserver'
5+
import { CropComponent } from './HeaderCrop'
6+
7+
makeMockIntersectionObserver()
8+
9+
const mockHandleCancel = vi.fn()
10+
const mockSetDataURL = vi.fn()
11+
12+
// Create a simple 100x100 image for testing
13+
const createTestImage = () => {
14+
const canvas = document.createElement('canvas')
15+
canvas.width = 100
16+
canvas.height = 100
17+
const ctx = canvas.getContext('2d')!
18+
ctx.fillStyle = 'red'
19+
ctx.fillRect(0, 0, 100, 100)
20+
21+
return new Promise<File>((resolve) => {
22+
canvas.toBlob((blob) => {
23+
if (blob) {
24+
resolve(new File([blob], 'test.png', { type: 'image/png' }))
25+
}
26+
})
27+
})
28+
}
29+
30+
describe('<CropComponent /> - Zoom Functionality', () => {
31+
beforeAll(() => {
32+
URL.createObjectURL = vi.fn(() => 'https://localhost/test.png')
33+
})
34+
35+
it('renders the crop component with zoom slider', async () => {
36+
const mockFile = await createTestImage()
37+
render(
38+
<CropComponent header={mockFile} handleCancel={mockHandleCancel} setDataURL={mockSetDataURL} />
39+
)
40+
41+
expect(screen.getByTestId('edit-image-container')).toBeVisible()
42+
43+
// Check if slider is present
44+
const slider = screen.getByLabelText('zoom')
45+
expect(slider).toBeInTheDocument()
46+
expect(slider).toHaveAttribute('min', '100')
47+
expect(slider).toHaveAttribute('max', '200')
48+
})
49+
50+
it('changes zoom value when slider is moved', async () => {
51+
const mockFile = await createTestImage()
52+
render(
53+
<CropComponent header={mockFile} handleCancel={mockHandleCancel} setDataURL={mockSetDataURL} />
54+
)
55+
56+
const slider = screen.getByLabelText('zoom') as HTMLInputElement
57+
58+
// Initial value should be 100
59+
expect(slider.value).toBe('100')
60+
61+
// Change zoom to 150
62+
fireEvent.change(slider, { target: { value: '150' } })
63+
64+
await waitFor(() => {
65+
expect(slider.value).toBe('150')
66+
})
67+
})
68+
69+
it('handles zoom to maximum value', async () => {
70+
const mockFile = await createTestImage()
71+
render(
72+
<CropComponent header={mockFile} handleCancel={mockHandleCancel} setDataURL={mockSetDataURL} />
73+
)
74+
75+
const slider = screen.getByLabelText('zoom') as HTMLInputElement
76+
77+
// Change zoom to max (200)
78+
fireEvent.change(slider, { target: { value: '200' } })
79+
80+
await waitFor(() => {
81+
expect(slider.value).toBe('200')
82+
})
83+
})
84+
85+
it('calls handleCancel when cancel button is clicked', async () => {
86+
const mockFile = await createTestImage()
87+
render(
88+
<CropComponent header={mockFile} handleCancel={mockHandleCancel} setDataURL={mockSetDataURL} />
89+
)
90+
91+
const cancelButton = screen.getByTestId('header-cancel-button')
92+
fireEvent.click(cancelButton)
93+
94+
expect(mockHandleCancel).toHaveBeenCalled()
95+
})
96+
97+
it('calls setDataURL when continue button is clicked', async () => {
98+
const mockFile = await createTestImage()
99+
mockSetDataURL.mockClear()
100+
101+
render(
102+
<CropComponent header={mockFile} handleCancel={mockHandleCancel} setDataURL={mockSetDataURL} />
103+
)
104+
105+
// Wait for canvas to be in the document
106+
await waitFor(() => {
107+
const canvas = document.querySelector('canvas')
108+
expect(canvas).toBeInTheDocument()
109+
}, { timeout: 3000 })
110+
111+
const continueButton = screen.getByTestId('continue-button')
112+
fireEvent.click(continueButton)
113+
114+
await waitFor(() => {
115+
expect(mockSetDataURL).toHaveBeenCalled()
116+
const dataURL = mockSetDataURL.mock.calls[0][0]
117+
expect(dataURL).toMatch(/^data:image\/jpeg;base64,/)
118+
})
119+
})
120+
121+
it('displays 3:1 aspect ratio labels', async () => {
122+
const mockFile = await createTestImage()
123+
render(
124+
<CropComponent header={mockFile} handleCancel={mockHandleCancel} setDataURL={mockSetDataURL} />
125+
)
126+
127+
await waitFor(() => {
128+
const labels = screen.getAllByText(/3:1/i)
129+
expect(labels).toHaveLength(2)
130+
})
131+
})
132+
133+
it('displays 6:1 aspect ratio labels', async () => {
134+
const mockFile = await createTestImage()
135+
render(
136+
<CropComponent header={mockFile} handleCancel={mockHandleCancel} setDataURL={mockSetDataURL} />
137+
)
138+
139+
await waitFor(() => {
140+
const labels = screen.getAllByText(/6:1/i)
141+
expect(labels).toHaveLength(2)
142+
})
143+
})
144+
})

0 commit comments

Comments
 (0)