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:
Jakub Zych
2026-09-29 02:59:13 +02:00
parent 6b0ac15086
commit 11c4e5466b
9 changed files with 1194 additions and 9 deletions

View File

@@ -6,11 +6,14 @@ import RelationField from '../../src/components/form/fields/RelationField.vue'
import SwitchField from '../../src/components/form/fields/SwitchField.vue'
import TextField from '../../src/components/form/fields/TextField.vue'
import TextareaField from '../../src/components/form/fields/TextareaField.vue'
import PartialField from '../../src/components/form/fields/PartialField.vue'
import UnsupportedField from '../../src/components/form/fields/UnsupportedField.vue'
import WidgetField from '../../src/components/form/fields/WidgetField.vue'
import RelationManager from '../../src/components/relation/RelationManager.vue'
import {
controlAttributes,
controlClass,
groupLabelled,
isRegistered,
needsRecord,
ownsLabel,
@@ -60,6 +63,26 @@ describe('field renderer registry (D-05)', () => {
})
})
describe('plugin extension types (Phase 10.1, D-09)', () => {
it('registers widget and partial with their controls', () => {
expect(rendererFor('widget')).toBe(WidgetField)
expect(rendererFor('partial')).toBe(PartialField)
})
it.each(['widget', 'partial'])('treats %s as valueless, rendered on create and group-labelled', (type) => {
expect(isRegistered(type)).toBe(false)
expect(needsRecord(type)).toBe(false)
expect(groupLabelled(type)).toBe(true)
expect(ownsLabel(type)).toBe(false)
})
it('labels every other type as a control, not a group', () => {
for (const type of ['text', 'textarea', 'number', 'dropdown', 'switch', 'checkbox', 'relation', RELATION_MANAGER, 'colorpicker']) {
expect(groupLabelled(type), type).toBe(false)
}
})
})
describe('control attributes', () => {
it('passes only allow-listed Winter attributes, lower-cased, and drops null and false', () => {
const field = formField('name')