Files
cms-website/packages/contracts/test/manifests.test.ts
T

142 lines
5.4 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import { describe, it, expect } from 'vitest'
import {
ROUTE_MANIFEST_VERSION, RENDER_SNAPSHOT_VERSION, THEME_MANIFEST_VERSION,
RENDER_SNAPSHOT_FILES, isRouteManifest, isThemeManifest,
} from '../src/index.js'
const validRouteManifest: any = {
manifest_version: 1, site_id: 's1', build_job_id: 'b1', origin: 'https://fixture.example',
generated_from_route_snapshot_hash: 'abc',
routes: [{ exact_key: '/', query_policy: 'ignore', kind: 'html', target_file: 'index.html', status: 200, indexable: true }],
}
const validThemeManifest: any = {
key: 'pilot-minimal', version: '0.1.0', renderContractVersion: '1',
supportedContentTypes: ['news_article', 'product', 'basic_page'],
requiredSiteConfig: ['origin', 'listPaths'],
templates: [{ key: 'home', appliesTo: 'home' }],
}
describe('manifest 契约', () => {
it('三个版本号冻结为 1', () => {
expect([ROUTE_MANIFEST_VERSION, RENDER_SNAPSHOT_VERSION, THEME_MANIFEST_VERSION]).toEqual([1, 1, 1])
})
it('Render Snapshot 文件清单冻结(spec §9.2)', () => {
expect(RENDER_SNAPSHOT_FILES).toEqual([
'site.json', 'content.json', 'taxonomies.json', 'routes.json', 'assets.json', 'render-manifest.json',
])
})
it('合法 RouteManifest 通过守卫', () => {
expect(isRouteManifest({
manifest_version: 1, site_id: 's1', build_job_id: 'b1', origin: 'https://fixture.example',
generated_from_route_snapshot_hash: 'abc',
routes: [{ exact_key: '/', query_policy: 'ignore', kind: 'html', target_file: 'index.html', status: 200, indexable: true }],
})).toBe(true)
})
it('非法 kind 拒绝', () => {
const m: any = { manifest_version: 1, site_id: 's', build_job_id: 'b', origin: 'o', generated_from_route_snapshot_hash: 'h', routes: [{ exact_key: '/', query_policy: 'ignore', kind: 'weird', status: 200, indexable: true }] }
expect(isRouteManifest(m)).toBe(false)
})
it('合法 ThemeManifest 通过守卫', () => {
expect(isThemeManifest({
key: 'pilot-minimal', version: '0.1.0', renderContractVersion: '1',
supportedContentTypes: ['news_article', 'product', 'basic_page'],
requiredSiteConfig: ['origin', 'listPaths'],
templates: [{ key: 'home', appliesTo: 'home' }],
})).toBe(true)
})
})
describe('RouteManifest 守卫拒绝路径', () => {
it('manifest_version ≠ 1 拒绝(2 与字符串 "1")', () => {
expect(isRouteManifest({ ...validRouteManifest, manifest_version: 2 })).toBe(false)
expect(isRouteManifest({ ...validRouteManifest, manifest_version: '1' })).toBe(false)
})
it('routes 非数组拒绝(字符串)', () => {
expect(isRouteManifest({ ...validRouteManifest, routes: 'x' })).toBe(false)
})
it('routes 元素缺 exact_key / 元素为 null 拒绝', () => {
const { exact_key: _omit, ...route } = validRouteManifest.routes[0]
expect(isRouteManifest({ ...validRouteManifest, routes: [route] })).toBe(false)
expect(isRouteManifest({ ...validRouteManifest, routes: [null] })).toBe(false)
})
it('status 非数字拒绝(status: "200")', () => {
expect(isRouteManifest({
...validRouteManifest,
routes: [{ ...validRouteManifest.routes[0], status: '200' }],
})).toBe(false)
})
it('status 非整数拒绝(200.5)', () => {
expect(isRouteManifest({
...validRouteManifest,
routes: [{ ...validRouteManifest.routes[0], status: 200.5 }],
})).toBe(false)
})
it('status 超域拒绝(999)', () => {
expect(isRouteManifest({
...validRouteManifest,
routes: [{ ...validRouteManifest.routes[0], status: 999 }],
})).toBe(false)
})
it('indexable 非布尔拒绝(indexable: 1)', () => {
expect(isRouteManifest({
...validRouteManifest,
routes: [{ ...validRouteManifest.routes[0], indexable: 1 }],
})).toBe(false)
})
it('query_policy 非四值之一拒绝', () => {
expect(isRouteManifest({
...validRouteManifest,
routes: [{ ...validRouteManifest.routes[0], query_policy: 'loose' }],
})).toBe(false)
})
it('顶层必填字符串字段非字符串拒绝(site_id 数字)', () => {
expect(isRouteManifest({ ...validRouteManifest, site_id: 101 })).toBe(false)
})
it('非对象输入拒绝(null / number / array)', () => {
expect(isRouteManifest(null)).toBe(false)
expect(isRouteManifest(42)).toBe(false)
expect(isRouteManifest([])).toBe(false)
})
})
describe('ThemeManifest 守卫拒绝路径', () => {
it('version 非 semver 拒绝("abc" 与 "1")', () => {
expect(isThemeManifest({ ...validThemeManifest, version: 'abc' })).toBe(false)
expect(isThemeManifest({ ...validThemeManifest, version: '1' })).toBe(false)
})
it('key 非字符串拒绝(数字)', () => {
expect(isThemeManifest({ ...validThemeManifest, key: 42 })).toBe(false)
})
it('templates 非数组拒绝', () => {
expect(isThemeManifest({ ...validThemeManifest, templates: 'x' })).toBe(false)
})
it('templates 元素缺 appliesTo 拒绝(查值类型,不只查键存在)', () => {
expect(isThemeManifest({
...validThemeManifest,
templates: [{ key: 'home', appliesTo: 42 }],
})).toBe(false)
})
it('renderContractVersion 非字符串拒绝', () => {
expect(isThemeManifest({ ...validThemeManifest, renderContractVersion: 1 })).toBe(false)
})
it('非对象输入拒绝(null / number)', () => {
expect(isThemeManifest(null)).toBe(false)
expect(isThemeManifest(42)).toBe(false)
})
})