Files
crewli/apps/portal/tests/components/public-form/IdentityMatchBanner.spec.ts
bert.hausmans 9256c05db0 feat(portal): implement TAG_PICKER, AVAILABILITY_PICKER, SECTION_PRIORITY field types
- FieldTagPicker: VAutocomplete multiple with grouped category slots,
  empty/null category normalised to "Overig", empty-state info alert
  when the server delivers no tags.
- FieldAvailabilityPicker: date-grouped checkbox list, festival-aware
  via usePublicFormTimeSlots. Event-name subheaders only surface when
  the time-slots span multiple events. Time format strips seconds.
- FieldSectionPriority: tap-to-rank + drag-to-reorder via vuedraggable
  for desktop; mobile tap-only. Renumbers priorities on every mutation.
  Self-heals malformed modelValue. UI soft cap via
  validation_rules.max_priorities clamped to the backend hard cap of 5.
- FieldRenderer: three new types removed from isStubbed.
- publicFormInjection: page-level provide/inject for the public token.
- IdentityMatchBanner: prefers backend-provided Dutch copy with
  frontend defaults as defensive fallback.
- FormConfirmation wires the banner inline.
- usePublicFormTimeSlots and usePublicFormSections TanStack composables.
- 40 new Vitest assertions.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-23 20:00:40 +02:00

60 lines
1.9 KiB
TypeScript

import { mount } from '@vue/test-utils'
import { describe, expect, it } from 'vitest'
import IdentityMatchBanner from '@/components/public-form/IdentityMatchBanner.vue'
function mountBanner(props: { status: 'pending' | 'matched' | 'none' | null; message?: string | null }) {
return mount(IdentityMatchBanner, {
props,
global: {
stubs: {
VAlert: {
name: 'VAlert',
props: ['type', 'variant', 'prominent'],
template: '<div class="v-alert-stub" :data-type="type"><slot/></div>',
},
},
},
})
}
describe('IdentityMatchBanner', () => {
it('renders nothing when status is null', () => {
const w = mountBanner({ status: null })
expect(w.find('.v-alert-stub').exists()).toBe(false)
})
it('renders the pending banner with info type and backend message when provided', () => {
const w = mountBanner({
status: 'pending',
message: 'We controleren of je al bekend bent bij de organisator.',
})
const alert = w.find('.v-alert-stub')
expect(alert.exists()).toBe(true)
expect(alert.attributes('data-type')).toBe('info')
expect(w.text()).toContain('We controleren')
})
it('renders the matched banner with success type and backend message when provided', () => {
const w = mountBanner({
status: 'matched',
message: 'Je account is gekoppeld aan een bekende deelnemer.',
})
const alert = w.find('.v-alert-stub')
expect(alert.exists()).toBe(true)
expect(alert.attributes('data-type')).toBe('success')
expect(w.text()).toContain('gekoppeld')
})
it('falls back to frontend copy when backend message is missing', () => {
const w = mountBanner({ status: 'none', message: null })
const alert = w.find('.v-alert-stub')
expect(alert.exists()).toBe(true)
expect(alert.attributes('data-type')).toBe('success')
expect(w.text()).toContain('Aanmelding ontvangen')
})
})