Files
floci-ui/packages/frontend/src/components/DynamoDbItemEditor.test.tsx
T
2026-09-30 17:43:42 -04:00

82 lines
3.5 KiB
TypeScript

import {render, screen} from '@testing-library/react'
import userEvent from '@testing-library/user-event'
import {expect, test, vi} from 'vitest'
import {DynamoDbItemEditor} from './DynamoDbItemEditor'
test('preserves typed attributes while switching between form and DynamoDB JSON', async () => {
const user = userEvent.setup()
render(<DynamoDbItemEditor
keyFields={[{name: 'id', type: 'S'}]}
initialDocument={{id: {S: 'order-1'}, total: {N: '9007199254740993'}, tags: {SS: ['new', 'priority']}}}
isPending={false}
onClose={() => {}}
onSubmit={vi.fn()}
/>)
await user.click(screen.getByRole('tab', {name: 'DynamoDB JSON'}))
const json = screen.getByLabelText('DynamoDB AttributeValue JSON')
expect((json as HTMLTextAreaElement).value).toContain('"N": "9007199254740993"')
expect((json as HTMLTextAreaElement).value).toContain('"SS"')
await user.click(screen.getByRole('tab', {name: 'Form'}))
expect(screen.getAllByLabelText('Attribute value').map((input) => input.getAttribute('value'))).toContain('9007199254740993')
expect(screen.getByLabelText('Attribute values')).toHaveValue('new\npriority')
})
test('submits DynamoDB AttributeValue JSON from the typed form', async () => {
const onSubmit = vi.fn()
const user = userEvent.setup()
render(<DynamoDbItemEditor
keyFields={[{name: 'id', type: 'S'}]}
initialDocument={{id: {S: 'order-1'}}}
isPending={false}
onClose={() => {}}
onSubmit={onSubmit}
/>)
await user.selectOptions(screen.getByRole('combobox', {name: 'Add new attribute'}), 'S')
const names = screen.getAllByLabelText('Attribute name')
await user.type(names[names.length - 1], 'active')
const values = screen.getAllByLabelText('Attribute value')
await user.type(values[values.length - 1], 'yes')
await user.click(screen.getByRole('button', {name: 'Create item'}))
expect(onSubmit).toHaveBeenCalledWith({id: {S: 'order-1'}, active: {S: 'yes'}})
})
test('renders a blank numeric key draft and validates it on submit', async () => {
const onSubmit = vi.fn()
const user = userEvent.setup()
render(<DynamoDbItemEditor
keyFields={[{name: 'customerId', type: 'N'}]}
isPending={false}
onClose={() => {}}
onSubmit={onSubmit}
/>)
const keyInput = screen.getByLabelText('Attribute value')
expect(keyInput).toHaveValue('')
await user.click(screen.getByRole('button', {name: 'Create item'}))
expect(screen.getByText('Attribute customerId must be a DynamoDB number.')).toBeInTheDocument()
expect(onSubmit).not.toHaveBeenCalled()
await user.type(keyInput, '42')
await user.click(screen.getByRole('button', {name: 'Create item'}))
expect(onSubmit).toHaveBeenCalledWith({customerId: {N: '42'}})
})
test('renders required keys before other attributes in the Attributes workspace', () => {
render(<DynamoDbItemEditor
keyFields={[{name: 'pk', type: 'S'}, {name: 'sk', type: 'N'}]}
initialDocument={{description: {S: 'order'}, sk: {N: '2'}, pk: {S: 'customer'}}}
isPending={false}
onClose={() => {}}
onSubmit={vi.fn()}
/>)
expect(screen.getByRole('heading', {name: 'Create item'})).toBeInTheDocument()
expect(screen.getByRole('heading', {name: 'Attributes'})).toBeInTheDocument()
expect(screen.getAllByLabelText('Attribute name').map((input) => input.getAttribute('value'))).toEqual(['pk', 'sk', 'description'])
expect(screen.getAllByText('Required key')).toHaveLength(2)
})