171 lines
6.1 KiB
TypeScript
171 lines
6.1 KiB
TypeScript
import type { Field } from 'payload'
|
|
import { describe, expect, it } from 'vitest'
|
|
|
|
import { ApplicationForm } from '@/ApplicationForm/config'
|
|
import { ApplicationPhase } from '@/ApplicationPhase/config'
|
|
import { Footer } from '@/Footer/config'
|
|
import { Header } from '@/Header/config'
|
|
import { NewsletterForm } from '@/NewsletterForm/config'
|
|
import { SiteSettings } from '@/SiteSettings/config'
|
|
import { aboutFields } from '@/collections/Pages/aboutFields'
|
|
import { homeFields } from '@/collections/Pages/homeFields'
|
|
import { netzwerkFields } from '@/collections/Pages/netzwerkFields'
|
|
import { participationFields } from '@/collections/Pages/participationFields'
|
|
import { pressIndexFields } from '@/collections/Pages/pressIndexFields'
|
|
|
|
function fieldPaths(fields: Field[], prefix = ''): string[] {
|
|
return fields.flatMap((field) => {
|
|
if (!('name' in field) || typeof field.name !== 'string') {
|
|
return 'fields' in field && Array.isArray(field.fields) ? fieldPaths(field.fields, prefix) : []
|
|
}
|
|
|
|
const path = prefix ? `${prefix}.${field.name}` : field.name
|
|
const children = 'fields' in field && Array.isArray(field.fields) ? fieldPaths(field.fields, path) : []
|
|
return [path, ...children]
|
|
})
|
|
}
|
|
|
|
function findField(fields: Field[], path: string): Field | undefined {
|
|
const [name, ...rest] = path.split('.')
|
|
const field = fields.find((candidate) => 'name' in candidate && candidate.name === name)
|
|
if (!field || rest.length === 0) return field
|
|
if (!('fields' in field) || !Array.isArray(field.fields)) return undefined
|
|
return findField(field.fields, rest.join('.'))
|
|
}
|
|
|
|
describe('Payload field inventory', () => {
|
|
it('keeps obsolete page controls out of the schema', () => {
|
|
const paths = [
|
|
...fieldPaths(homeFields),
|
|
...fieldPaths(participationFields),
|
|
...fieldPaths(aboutFields),
|
|
...fieldPaths(pressIndexFields),
|
|
...fieldPaths(netzwerkFields),
|
|
]
|
|
|
|
expect(paths).not.toEqual(
|
|
expect.arrayContaining([
|
|
'home.application',
|
|
'home.form',
|
|
'participation.applicationForm',
|
|
'participation.form',
|
|
'participation.eligibility.secondaryCta',
|
|
'participation.eligibility.nudgeCta',
|
|
'participation.applicationWays.recommendedLabel',
|
|
'participation.applicationWays.fallbackCta',
|
|
'participation.applicationWays.ways.featured',
|
|
'participation.applicationWays.ways.cta',
|
|
'about.highlights',
|
|
'pressIndex.events.detailLabel',
|
|
'pressIndex.news.readMoreLabel',
|
|
'pressIndex.downloads.kitLabel',
|
|
'pressIndex.downloads.kitMeta',
|
|
'pressIndex.downloads.kitFile',
|
|
'pressIndex.downloads.kitUrl',
|
|
'pressIndex.downloads.kitDownloadName',
|
|
'pressIndex.accreditation',
|
|
'netzwerk.jury.note',
|
|
'netzwerk.partners.premiumLabel',
|
|
'netzwerk.partners.defaultLogoColor',
|
|
'netzwerk.sponsoring.footnotePrefix',
|
|
'netzwerk.sponsoring.footnoteLabel',
|
|
'netzwerk.sponsoring.footnoteUrl',
|
|
'netzwerk.sponsoring.formEyebrow',
|
|
'netzwerk.sponsoringForm.packages',
|
|
'netzwerk.sponsoringForm.step1Eyebrow',
|
|
'netzwerk.sponsoringForm.step1Heading',
|
|
'netzwerk.sponsoringForm.requiredPackageError',
|
|
]),
|
|
)
|
|
})
|
|
|
|
it('retains rendered page controls and authoritative relationships', () => {
|
|
const paths = [
|
|
...fieldPaths(homeFields),
|
|
...fieldPaths(participationFields),
|
|
...fieldPaths(aboutFields),
|
|
...fieldPaths(pressIndexFields),
|
|
...fieldPaths(netzwerkFields),
|
|
]
|
|
|
|
expect(paths).toEqual(
|
|
expect.arrayContaining([
|
|
'home.hero',
|
|
'home.winners.featured',
|
|
'home.videoModal.video',
|
|
'participation.process.steps',
|
|
'participation.awardsGrid.cards',
|
|
'about.testimonials.items',
|
|
'pressIndex.events.statusLabels',
|
|
'pressIndex.downloads.contactName',
|
|
'pressIndex.downloads.contactImage',
|
|
'pressIndex.downloads.contactImageAlt',
|
|
'netzwerk.jury.members',
|
|
'netzwerk.patronage.greetingVideo',
|
|
'netzwerk.patronage.greetingVideoButtonLabel',
|
|
'netzwerk.patronage.greetingVideoTitle',
|
|
'netzwerk.patronage.greetingVideoDescription',
|
|
'netzwerk.patronage.greetingVideoCloseLabel',
|
|
'netzwerk.partners.tiers',
|
|
'netzwerk.partners.modal.websiteLabel',
|
|
'netzwerk.sponsoringForm.steps',
|
|
'netzwerk.sponsoringForm.requiredFieldError',
|
|
]),
|
|
)
|
|
})
|
|
|
|
it('keeps shared multi-page and site-wide content in Globals', () => {
|
|
const globals = [ApplicationForm, ApplicationPhase, NewsletterForm, Header, Footer, SiteSettings]
|
|
const slugs = globals.map((global) => global.slug)
|
|
|
|
expect(slugs).toEqual([
|
|
'application-form',
|
|
'application-phase',
|
|
'newsletter-form',
|
|
'header',
|
|
'footer',
|
|
'site-settings',
|
|
])
|
|
expect(fieldPaths(ApplicationForm.fields)).toEqual(expect.arrayContaining(['section', 'form']))
|
|
expect(fieldPaths(ApplicationPhase.fields)).toEqual(expect.arrayContaining(['activePhase', 'phases']))
|
|
expect(fieldPaths(NewsletterForm.fields)).toEqual(expect.arrayContaining(['evaluation', 'completed']))
|
|
})
|
|
|
|
it('exposes exactly two editable sponsoring step labels', () => {
|
|
expect(findField(netzwerkFields, 'netzwerk.sponsoringForm.steps')).toMatchObject({
|
|
minRows: 2,
|
|
maxRows: 2,
|
|
})
|
|
})
|
|
|
|
it('limits the Netzwerk greeting upload to video media', () => {
|
|
const field = findField(netzwerkFields, 'netzwerk.patronage.greetingVideo')
|
|
|
|
expect(field).toMatchObject({
|
|
type: 'upload',
|
|
relationTo: 'media',
|
|
filterOptions: {
|
|
mimeType: {
|
|
contains: 'video',
|
|
},
|
|
},
|
|
})
|
|
expect(field).not.toHaveProperty('defaultValue')
|
|
})
|
|
|
|
it('limits the press contact upload to image media', () => {
|
|
const field = findField(pressIndexFields, 'pressIndex.downloads.contactImage')
|
|
|
|
expect(field).toMatchObject({
|
|
type: 'upload',
|
|
relationTo: 'media',
|
|
filterOptions: {
|
|
mimeType: {
|
|
contains: 'image',
|
|
},
|
|
},
|
|
})
|
|
expect(field).not.toHaveProperty('defaultValue')
|
|
})
|
|
})
|