48 lines
1.9 KiB
TypeScript
48 lines
1.9 KiB
TypeScript
import { describe, expect, it } from 'vitest'
|
|
import { defaultSiteDocument, siteDocumentSchema } from '../server/utils/site-schema'
|
|
|
|
describe('siteDocumentSchema', () => {
|
|
it('accepts the seeded phase-one website document', () => {
|
|
expect(siteDocumentSchema.parse(defaultSiteDocument)).toEqual(defaultSiteDocument)
|
|
expect(defaultSiteDocument.brand.name).toBe('慧遇书院')
|
|
expect(defaultSiteDocument.brand.navFontSize).toBe(14)
|
|
})
|
|
|
|
it('keeps the navigation font size within a readable range', () => {
|
|
const invalid = structuredClone(defaultSiteDocument)
|
|
invalid.brand.navFontSize = 36
|
|
expect(siteDocumentSchema.safeParse(invalid).success).toBe(false)
|
|
})
|
|
|
|
it('rejects unsafe oversized content', () => {
|
|
const invalid = structuredClone(defaultSiteDocument)
|
|
invalid.hero.titleLine1 = '超'.repeat(21)
|
|
expect(() => siteDocumentSchema.parse(invalid)).toThrow()
|
|
})
|
|
|
|
it('contains routable published content', () => {
|
|
const parsed = siteDocumentSchema.parse(defaultSiteDocument)
|
|
expect(parsed.products.every(item => /^[a-z0-9-]+$/.test(item.slug))).toBe(true)
|
|
expect(parsed.articles.some(item => item.type === 'statement')).toBe(true)
|
|
expect(parsed.team.length).toBeGreaterThan(0)
|
|
})
|
|
|
|
it('rejects duplicate route slugs', () => {
|
|
const invalid = structuredClone(defaultSiteDocument)
|
|
invalid.products[1].slug = invalid.products[0].slug
|
|
expect(siteDocumentSchema.safeParse(invalid).success).toBe(false)
|
|
})
|
|
|
|
it('rejects unsafe external protocols', () => {
|
|
const invalid = structuredClone(defaultSiteDocument)
|
|
invalid.channels[0].url = 'javascript:alert(1)'
|
|
expect(siteDocumentSchema.safeParse(invalid).success).toBe(false)
|
|
})
|
|
|
|
it('allows channels to stay unlinked before official URLs are confirmed', () => {
|
|
const draft = structuredClone(defaultSiteDocument)
|
|
draft.channels.forEach(channel => { channel.url = '' })
|
|
expect(siteDocumentSchema.safeParse(draft).success).toBe(true)
|
|
})
|
|
})
|