test(10.1-04): bring the SPA extension point under Vitest
- WidgetField: skeleton and aria-busy, the 5000 ms whenDefined timeout, script failure, attributes only, fill-values and locale sync, one POST while busy, fill-key-only patching, danger toasts, unmount - PartialHost and partialNodes: exhaustive tag, attribute and URL allowlist, depth and node caps, skeleton sizes, empty, failure, busy refetch and ?id= only with a record - PartialField, ListToolbar, ListView, registry, formState, FormField and FormView: group labels, registered toolbar actions, header refetch rules, form context provision and asset loading
This commit is contained in:
@@ -3,8 +3,8 @@ import { mount } from '@vue/test-utils'
|
||||
import FieldRenderer from '../../src/components/form/FieldRenderer.vue'
|
||||
import FormErrorBanner from '../../src/components/form/FormErrorBanner.vue'
|
||||
import FormField from '../../src/components/form/FormField.vue'
|
||||
import { formField } from '../fixtures/typed'
|
||||
import { resetState } from '../helpers'
|
||||
import { clone, extensionFormSchemaFixture, formField } from '../fixtures/typed'
|
||||
import { mockApi, resetState } from '../helpers'
|
||||
|
||||
beforeEach(() => {
|
||||
resetState()
|
||||
@@ -55,6 +55,44 @@ describe('form field', () => {
|
||||
})
|
||||
})
|
||||
|
||||
describe('widget and partial rows (Phase 10.1)', () => {
|
||||
function extensionField(name: string, change: Record<string, unknown> = {}) {
|
||||
const field = clone(extensionFormSchemaFixture).data.fields.find((item) => item.name === name)
|
||||
if (!field) {
|
||||
throw new Error(`fixture field ${name} missing`)
|
||||
}
|
||||
return { ...field, ...change }
|
||||
}
|
||||
|
||||
it.each(['lookup', 'summary'])('labels the %s group with a span the group points at', (name) => {
|
||||
mockApi({})
|
||||
const wrapper = mount(FormField, {
|
||||
props: { field: extensionField(name, { required: true }), modelValue: undefined, idPrefix: 'f', source: null },
|
||||
})
|
||||
const label = wrapper.find(`#f-${name}-label`)
|
||||
expect(label.element.tagName).toBe('SPAN')
|
||||
expect(label.classes()).toContain('font-semibold')
|
||||
expect(label.find('[aria-hidden="true"]').text()).toBe('*')
|
||||
expect(wrapper.find('label').exists()).toBe(false)
|
||||
expect(wrapper.find(`#f-${name}`).attributes('aria-labelledby')).toBe(`f-${name}-label`)
|
||||
})
|
||||
|
||||
it.each(['lookup', 'summary'])('shows no label row for an unlabelled %s', (name) => {
|
||||
mockApi({})
|
||||
const wrapper = mount(FormField, { props: { field: extensionField(name, { label: '' }), modelValue: undefined, idPrefix: 'f', source: null } })
|
||||
expect(wrapper.find(`#f-${name}-label`).exists()).toBe(false)
|
||||
expect(wrapper.find('label').exists()).toBe(false)
|
||||
expect(wrapper.find(`#f-${name}`).attributes('aria-labelledby')).toBeUndefined()
|
||||
})
|
||||
|
||||
it('points the widget group at its comment', () => {
|
||||
mockApi({})
|
||||
const wrapper = mount(FormField, { props: { field: extensionField('lookup'), modelValue: undefined, idPrefix: 'f', source: null } })
|
||||
expect(wrapper.find('#f-lookup-comment').text()).toBe('Fills in the name. Save to keep it.')
|
||||
expect(wrapper.find('#f-lookup').attributes('aria-describedby')).toBe('f-lookup-comment')
|
||||
})
|
||||
})
|
||||
|
||||
describe('field renderer', () => {
|
||||
it('picks the control by type and forwards the shared props and updates', async () => {
|
||||
const wrapper = mount(FieldRenderer, {
|
||||
|
||||
Reference in New Issue
Block a user