test(01-02): add failing tests for InlineEditCell
- renders formatted currency in display mode - enters edit mode on click - calls onSave with parsed number on blur/Enter - does not call onSave when value unchanged
This commit is contained in:
106
frontend/src/components/InlineEditCell.test.tsx
Normal file
106
frontend/src/components/InlineEditCell.test.tsx
Normal file
@@ -0,0 +1,106 @@
|
||||
import { render, screen, fireEvent } from '@testing-library/react'
|
||||
import userEvent from '@testing-library/user-event'
|
||||
import { describe, it, expect, vi, beforeEach } from 'vitest'
|
||||
import { InlineEditCell } from './InlineEditCell'
|
||||
|
||||
// Wrap in a table/row to satisfy semantic HTML for TableCell
|
||||
function Wrapper({ children }: { children: React.ReactNode }) {
|
||||
return (
|
||||
<table>
|
||||
<tbody>
|
||||
<tr>{children}</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
)
|
||||
}
|
||||
|
||||
describe('InlineEditCell', () => {
|
||||
const defaultProps = {
|
||||
value: 42.5,
|
||||
currency: 'EUR',
|
||||
onSave: vi.fn().mockResolvedValue(undefined),
|
||||
}
|
||||
|
||||
beforeEach(() => {
|
||||
vi.clearAllMocks()
|
||||
})
|
||||
|
||||
it('renders formatted currency value in display mode', () => {
|
||||
render(
|
||||
<Wrapper>
|
||||
<InlineEditCell {...defaultProps} />
|
||||
</Wrapper>
|
||||
)
|
||||
// Should show formatted value (42.5 in EUR → some formatted string containing 42)
|
||||
expect(screen.getByText(/42/)).toBeInTheDocument()
|
||||
})
|
||||
|
||||
it('enters edit mode on click', async () => {
|
||||
const user = userEvent.setup()
|
||||
render(
|
||||
<Wrapper>
|
||||
<InlineEditCell {...defaultProps} />
|
||||
</Wrapper>
|
||||
)
|
||||
const span = screen.getByText(/42/)
|
||||
await user.click(span)
|
||||
// After click, an input should be visible
|
||||
expect(screen.getByRole('spinbutton')).toBeInTheDocument()
|
||||
})
|
||||
|
||||
it('calls onSave with parsed number on blur', async () => {
|
||||
const user = userEvent.setup()
|
||||
const onSave = vi.fn().mockResolvedValue(undefined)
|
||||
render(
|
||||
<Wrapper>
|
||||
<InlineEditCell {...defaultProps} onSave={onSave} />
|
||||
</Wrapper>
|
||||
)
|
||||
const span = screen.getByText(/42/)
|
||||
await user.click(span)
|
||||
|
||||
const input = screen.getByRole('spinbutton')
|
||||
await user.clear(input)
|
||||
await user.type(input, '100')
|
||||
fireEvent.blur(input)
|
||||
|
||||
expect(onSave).toHaveBeenCalledWith(100)
|
||||
})
|
||||
|
||||
it('does not call onSave when value unchanged', async () => {
|
||||
const user = userEvent.setup()
|
||||
const onSave = vi.fn().mockResolvedValue(undefined)
|
||||
render(
|
||||
<Wrapper>
|
||||
<InlineEditCell {...defaultProps} onSave={onSave} />
|
||||
</Wrapper>
|
||||
)
|
||||
const span = screen.getByText(/42/)
|
||||
await user.click(span)
|
||||
|
||||
// Don't change the value, just blur
|
||||
const input = screen.getByRole('spinbutton')
|
||||
fireEvent.blur(input)
|
||||
|
||||
expect(onSave).not.toHaveBeenCalled()
|
||||
})
|
||||
|
||||
it('calls onSave on Enter key', async () => {
|
||||
const user = userEvent.setup()
|
||||
const onSave = vi.fn().mockResolvedValue(undefined)
|
||||
render(
|
||||
<Wrapper>
|
||||
<InlineEditCell {...defaultProps} onSave={onSave} />
|
||||
</Wrapper>
|
||||
)
|
||||
const span = screen.getByText(/42/)
|
||||
await user.click(span)
|
||||
|
||||
const input = screen.getByRole('spinbutton')
|
||||
await user.clear(input)
|
||||
await user.type(input, '99')
|
||||
await user.keyboard('{Enter}')
|
||||
|
||||
expect(onSave).toHaveBeenCalledWith(99)
|
||||
})
|
||||
})
|
||||
Reference in New Issue
Block a user