Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
a16b367
Refactor HeaderCrop component to fix zoom functionality and improve c…
storywithoutend Nov 3, 2025
01ed614
Fix: Reorder import statements in HeaderUpload for consistency
storywithoutend Nov 3, 2025
1b050a8
Fix: Correct translation key in HeaderCrop dialog title
storywithoutend Nov 3, 2025
a7c363f
Add crop guide lines to HeaderCrop component for better image positio…
storywithoutend Nov 17, 2025
247e5a2
feat: add 3:1 and 6:1 aspect ratio labels to HeaderCrop
storywithoutend Nov 17, 2025
8cb704d
Fix: Replace invalid theme.fontWeights.medium with theme.fontWeights.…
storywithoutend Nov 17, 2025
4c371af
chore: adjust 6:1 aspect ratio label positioning for better visual al…
storywithoutend Nov 17, 2025
03429d1
chore: add accessibility labels to aspect ratio indicators
storywithoutend Nov 17, 2025
9b794c9
chore: reposition aspect ratio labels to left side of crop frame
storywithoutend Nov 17, 2025
465b8fd
chore: move aspect ratio labels outside crop frame on the left
storywithoutend Nov 17, 2025
d73a527
chore: anchor aspect ratio labels to crop frame left edge
storywithoutend Nov 17, 2025
05d0ded
chore: align aspect ratio labels with crop frame boundaries
storywithoutend Nov 17, 2025
03744a0
chore: add aspect ratio labels to bottom grid lines in header crop
storywithoutend Nov 20, 2025
54c3118
chore: fix prettier formatting for aspect ratio labels
storywithoutend Nov 21, 2025
20556d5
chore: adjust vertical guidelines to 25% 50% 25% spacing
storywithoutend Nov 21, 2025
ad6cd73
Merge branch 'main' into feature/fet-2590-app-v3-header-zoom-is-unres…
storywithoutend Nov 25, 2025
638f514
Merge branch 'main' into feature/fet-2590-app-v3-header-zoom-is-unres…
storywithoutend Nov 26, 2025
df4c602
Merge branch 'main' into feature/fet-2590-app-v3-header-zoom-is-unres…
storywithoutend Dec 5, 2025
839c984
fix: use getAllByText for aspect ratio labels in HeaderCrop tests
storywithoutend Dec 5, 2025
7caf527
Merge branch 'main' into feature/fet-2590-app-v3-header-zoom-is-unres…
laurgk Jan 7, 2026
a0f4e3e
Merge branch 'main' into feature/fet-2590-app-v3-header-zoom-is-unres…
laurgk Jan 8, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
144 changes: 144 additions & 0 deletions src/components/@molecules/ProfileEditor/Header/HeaderCrop.test.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,144 @@
import { fireEvent, mockFunction, render, screen, waitFor } from '@app/test-utils'
import { beforeAll, describe, expect, it, vi } from 'vitest'

import { makeMockIntersectionObserver } from '../../../../../test/mock/makeMockIntersectionObserver'
import { CropComponent } from './HeaderCrop'

makeMockIntersectionObserver()

const mockHandleCancel = vi.fn()
const mockSetDataURL = vi.fn()

// Create a simple 100x100 image for testing
const createTestImage = () => {
const canvas = document.createElement('canvas')
canvas.width = 100
canvas.height = 100
const ctx = canvas.getContext('2d')!
ctx.fillStyle = 'red'
ctx.fillRect(0, 0, 100, 100)

return new Promise<File>((resolve) => {
canvas.toBlob((blob) => {
if (blob) {
resolve(new File([blob], 'test.png', { type: 'image/png' }))
}
})
})
}

describe('<CropComponent /> - Zoom Functionality', () => {
beforeAll(() => {
URL.createObjectURL = vi.fn(() => 'https://localhost/test.png')
})

it('renders the crop component with zoom slider', async () => {
const mockFile = await createTestImage()
render(
<CropComponent header={mockFile} handleCancel={mockHandleCancel} setDataURL={mockSetDataURL} />
)

expect(screen.getByTestId('edit-image-container')).toBeVisible()

// Check if slider is present
const slider = screen.getByLabelText('zoom')
expect(slider).toBeInTheDocument()
expect(slider).toHaveAttribute('min', '100')
expect(slider).toHaveAttribute('max', '200')
})

it('changes zoom value when slider is moved', async () => {
const mockFile = await createTestImage()
render(
<CropComponent header={mockFile} handleCancel={mockHandleCancel} setDataURL={mockSetDataURL} />
)

const slider = screen.getByLabelText('zoom') as HTMLInputElement

// Initial value should be 100
expect(slider.value).toBe('100')

// Change zoom to 150
fireEvent.change(slider, { target: { value: '150' } })

await waitFor(() => {
expect(slider.value).toBe('150')
})
})

it('handles zoom to maximum value', async () => {
const mockFile = await createTestImage()
render(
<CropComponent header={mockFile} handleCancel={mockHandleCancel} setDataURL={mockSetDataURL} />
)

const slider = screen.getByLabelText('zoom') as HTMLInputElement

// Change zoom to max (200)
fireEvent.change(slider, { target: { value: '200' } })

await waitFor(() => {
expect(slider.value).toBe('200')
})
})

it('calls handleCancel when cancel button is clicked', async () => {
const mockFile = await createTestImage()
render(
<CropComponent header={mockFile} handleCancel={mockHandleCancel} setDataURL={mockSetDataURL} />
)

const cancelButton = screen.getByTestId('header-cancel-button')
fireEvent.click(cancelButton)

expect(mockHandleCancel).toHaveBeenCalled()
})

it('calls setDataURL when continue button is clicked', async () => {
const mockFile = await createTestImage()
mockSetDataURL.mockClear()

render(
<CropComponent header={mockFile} handleCancel={mockHandleCancel} setDataURL={mockSetDataURL} />
)

// Wait for canvas to be in the document
await waitFor(() => {
const canvas = document.querySelector('canvas')
expect(canvas).toBeInTheDocument()
}, { timeout: 3000 })

const continueButton = screen.getByTestId('continue-button')
fireEvent.click(continueButton)

await waitFor(() => {
expect(mockSetDataURL).toHaveBeenCalled()
const dataURL = mockSetDataURL.mock.calls[0][0]
expect(dataURL).toMatch(/^data:image\/jpeg;base64,/)
})
})

it('displays 3:1 aspect ratio labels', async () => {
const mockFile = await createTestImage()
render(
<CropComponent header={mockFile} handleCancel={mockHandleCancel} setDataURL={mockSetDataURL} />
)

await waitFor(() => {
const labels = screen.getAllByText(/3:1/i)
expect(labels).toHaveLength(2)
})
})

it('displays 6:1 aspect ratio labels', async () => {
const mockFile = await createTestImage()
render(
<CropComponent header={mockFile} handleCancel={mockHandleCancel} setDataURL={mockSetDataURL} />
)

await waitFor(() => {
const labels = screen.getAllByText(/6:1/i)
expect(labels).toHaveLength(2)
})
})
})
Loading