import config from '@/payload.config' import { resolveHomeWinners } from '@/spa/homeWinnerSelection' import { selectJuryDocs } from '@/spa/juryMembers' import type { CmsRouteDoc } from '@/spa/cmsRoute' import { getPublicationQueryOptions } from '@/utilities/publicationQuery' import type { Payload } from 'payload' import { getPayload } from 'payload' import { afterAll, beforeAll, describe, expect, it } from 'vitest' const lexicalDocument = { root: { children: [ { children: [ { detail: 0, format: 0, mode: 'normal' as const, style: '', text: 'Route hydration fixture', type: 'text', version: 1, }, ], direction: 'ltr' as const, format: '' as const, indent: 0, textFormat: 0, type: 'paragraph', version: 1, }, ], direction: 'ltr' as const, format: '' as const, indent: 0, type: 'root', version: 1, }, } const fixtureKey = `route-hydration-${process.pid}-${Date.now()}` let payload: Payload let mediaID: number const cleanup: Array<() => Promise> = [] async function findFixtureDocs( collection: 'events' | 'jury-mitglieder' | 'partners' | 'posts' | 'preistraeger', ids: Array, preview: boolean, sort?: string, ): Promise { const result = await payload.find({ collection, ...getPublicationQueryOptions(preview), depth: 1, limit: 20, pagination: false, ...(sort ? { sort } : {}), where: { id: { in: ids } }, }) return result.docs as unknown as CmsRouteDoc[] } describe('public route hydration', () => { beforeAll(async () => { payload = await getPayload({ config }) const imageData = Buffer.from( 'iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAQAAAC1HAwCAAAAC0lEQVR42mNk+A8AAQUBAScY42YAAAAASUVORK5CYII=', 'base64', ) const media = await payload.create({ collection: 'media', data: { alt: 'Route hydration fixture' }, file: { data: imageData, mimetype: 'image/png', name: `${fixtureKey}.png`, size: imageData.length, }, }) mediaID = media.id }) afterAll(async () => { for (const remove of cleanup.reverse()) await remove() if (mediaID) await payload.delete({ collection: 'media', id: mediaID }) }) it('omits an unpublished jury member selected on /netzwerk and restores it in preview', async () => { const first = await payload.create({ collection: 'jury-mitglieder', context: { disableRevalidate: true }, data: { _status: 'published', name: `${fixtureKey} jury first`, sortOrder: 10 }, draft: false, }) const unpublished = await payload.create({ collection: 'jury-mitglieder', context: { disableRevalidate: true }, data: { _status: 'draft', name: `${fixtureKey} jury unpublished`, sortOrder: 20 }, draft: false, }) const third = await payload.create({ collection: 'jury-mitglieder', context: { disableRevalidate: true }, data: { _status: 'published', name: `${fixtureKey} jury third`, sortOrder: 30 }, draft: false, }) cleanup.push( () => payload.delete({ collection: 'jury-mitglieder', context: { disableRevalidate: true }, id: first.id, }), () => payload.delete({ collection: 'jury-mitglieder', context: { disableRevalidate: true }, id: unpublished.id, }), () => payload.delete({ collection: 'jury-mitglieder', context: { disableRevalidate: true }, id: third.id, }), ) const ids = [first.id, unpublished.id, third.id] const selection = [third, unpublished, first] const publicDocs = await findFixtureDocs('jury-mitglieder', ids, false, 'sortOrder') const previewDocs = await findFixtureDocs('jury-mitglieder', ids, true, 'sortOrder') expect(selectJuryDocs(selection, publicDocs).map((doc) => doc.id)).toEqual([third.id, first.id]) expect(selectJuryDocs(selection, previewDocs).map((doc) => doc.id)).toEqual([ third.id, unpublished.id, first.id, ]) }) it('omits an unpublished selected homepage winner and restores it after republishing without a page edit', async () => { const first = await payload.create({ collection: 'preistraeger', context: { disableRevalidate: true }, data: { _status: 'published', slug: `${fixtureKey}-winner-first`, title: `${fixtureKey} winner first`, year: 2026, }, draft: false, }) const unpublished = await payload.create({ collection: 'preistraeger', context: { disableRevalidate: true }, data: { _status: 'draft', slug: `${fixtureKey}-winner-unpublished`, title: `${fixtureKey} winner unpublished`, year: 2026, }, draft: false, }) const third = await payload.create({ collection: 'preistraeger', context: { disableRevalidate: true }, data: { _status: 'published', slug: `${fixtureKey}-winner-third`, title: `${fixtureKey} winner third`, year: 2026, }, draft: false, }) cleanup.push( () => payload.delete({ collection: 'preistraeger', context: { disableRevalidate: true }, id: first.id, }), () => payload.delete({ collection: 'preistraeger', context: { disableRevalidate: true }, id: unpublished.id, }), () => payload.delete({ collection: 'preistraeger', context: { disableRevalidate: true }, id: third.id, }), ) const ids = [first.id, unpublished.id, third.id] const selection = [third, unpublished, first] const publicDocs = await findFixtureDocs('preistraeger', ids, false) const previewDocs = await findFixtureDocs('preistraeger', ids, true) expect(resolveHomeWinners(selection, publicDocs).map((doc) => doc.id)).toEqual([ third.id, first.id, ]) expect(resolveHomeWinners(selection, previewDocs).map((doc) => doc.id)).toEqual([ third.id, unpublished.id, first.id, ]) await payload.update({ collection: 'preistraeger', context: { disableRevalidate: true }, id: unpublished.id, data: { _status: 'published' }, draft: false, }) const republishedDocs = await findFixtureDocs('preistraeger', ids, false) expect(resolveHomeWinners(selection, republishedDocs).map((doc) => doc.id)).toEqual([ third.id, unpublished.id, first.id, ]) }) it('omits an unpublished partner from the homepage ticker and preserves sort order', async () => { const first = await payload.create({ collection: 'partners', context: { disableRevalidate: true }, data: { _status: 'published', logo: mediaID, name: `${fixtureKey} partner first`, sortOrder: 10, stableId: `${fixtureKey}-partner-first`, tier: 1, }, draft: false, }) const unpublished = await payload.create({ collection: 'partners', context: { disableRevalidate: true }, data: { _status: 'draft', logo: mediaID, name: `${fixtureKey} partner unpublished`, sortOrder: 20, stableId: `${fixtureKey}-partner-unpublished`, tier: 2, }, draft: false, }) const third = await payload.create({ collection: 'partners', context: { disableRevalidate: true }, data: { _status: 'published', logo: mediaID, name: `${fixtureKey} partner third`, sortOrder: 30, stableId: `${fixtureKey}-partner-third`, tier: 3, }, draft: false, }) cleanup.push( () => payload.delete({ collection: 'partners', context: { disableRevalidate: true }, id: first.id, }), () => payload.delete({ collection: 'partners', context: { disableRevalidate: true }, id: unpublished.id, }), () => payload.delete({ collection: 'partners', context: { disableRevalidate: true }, id: third.id, }), ) const ids = [first.id, unpublished.id, third.id] const publicDocs = await findFixtureDocs('partners', ids, false, 'sortOrder') const previewDocs = await findFixtureDocs('partners', ids, true, 'sortOrder') expect(publicDocs.map((doc) => doc.id)).toEqual([first.id, third.id]) expect(previewDocs.map((doc) => doc.id)).toEqual([first.id, unpublished.id, third.id]) }) it('leaves no event row after the final /presse event is unpublished', async () => { const event = await payload.create({ collection: 'events', context: { disableRevalidate: true }, data: { _status: 'published', slug: `${fixtureKey}-event-final`, title: `${fixtureKey} event final`, }, draft: false, }) cleanup.push(() => payload.delete({ collection: 'events', context: { disableRevalidate: true }, id: event.id, }), ) expect((await findFixtureDocs('events', [event.id], false)).map((doc) => doc.id)).toEqual([ event.id, ]) await payload.update({ collection: 'events', context: { disableRevalidate: true }, id: event.id, data: { _status: 'draft' }, draft: false, }) expect(await findFixtureDocs('events', [event.id], false)).toEqual([]) expect((await findFixtureDocs('events', [event.id], true)).map((doc) => doc.id)).toEqual([ event.id, ]) }) it('omits an unpublished event previously rendered on /presse', async () => { const published = await payload.create({ collection: 'events', context: { disableRevalidate: true }, data: { _status: 'published', slug: `${fixtureKey}-event-published`, title: `${fixtureKey} event published`, }, draft: false, }) const unpublished = await payload.create({ collection: 'events', context: { disableRevalidate: true }, data: { _status: 'draft', slug: `${fixtureKey}-event-unpublished`, title: `${fixtureKey} event unpublished`, }, draft: false, }) cleanup.push( () => payload.delete({ collection: 'events', context: { disableRevalidate: true }, id: published.id, }), () => payload.delete({ collection: 'events', context: { disableRevalidate: true }, id: unpublished.id, }), ) const ids = [published.id, unpublished.id] const publicDocs = await findFixtureDocs('events', ids, false) const previewDocs = await findFixtureDocs('events', ids, true) expect(publicDocs.map((doc) => doc.id)).toEqual([published.id]) expect(previewDocs.map((doc) => doc.id).sort()).toEqual(ids.sort()) }) it('leaves no news card after the final /presse article is unpublished', async () => { const post = await payload.create({ collection: 'posts', context: { disableRevalidate: true }, data: { _status: 'published', content: lexicalDocument, slug: `${fixtureKey}-post-final`, title: `${fixtureKey} post final`, }, draft: false, }) cleanup.push(() => payload.delete({ collection: 'posts', context: { disableRevalidate: true }, id: post.id, }), ) expect((await findFixtureDocs('posts', [post.id], false)).map((doc) => doc.id)).toEqual([ post.id, ]) await payload.update({ collection: 'posts', context: { disableRevalidate: true }, id: post.id, data: { _status: 'draft' }, draft: false, }) expect(await findFixtureDocs('posts', [post.id], false)).toEqual([]) expect((await findFixtureDocs('posts', [post.id], true)).map((doc) => doc.id)).toEqual([ post.id, ]) }) it('omits an unpublished press article previously rendered on /presse', async () => { const published = await payload.create({ collection: 'posts', context: { disableRevalidate: true }, data: { _status: 'published', content: lexicalDocument, slug: `${fixtureKey}-post-published`, title: `${fixtureKey} post published`, }, draft: false, }) const unpublished = await payload.create({ collection: 'posts', context: { disableRevalidate: true }, data: { _status: 'draft', content: lexicalDocument, slug: `${fixtureKey}-post-unpublished`, title: `${fixtureKey} post unpublished`, }, draft: false, }) cleanup.push( () => payload.delete({ collection: 'posts', context: { disableRevalidate: true }, id: published.id, }), () => payload.delete({ collection: 'posts', context: { disableRevalidate: true }, id: unpublished.id, }), ) const ids = [published.id, unpublished.id] const publicDocs = await findFixtureDocs('posts', ids, false) const previewDocs = await findFixtureDocs('posts', ids, true) expect(publicDocs.map((doc) => doc.id)).toEqual([published.id]) expect(previewDocs.map((doc) => doc.id).sort()).toEqual(ids.sort()) }) })