Support explicit current-output A/B fill, protected edited drafts, scoped cloud update offers and atomic native restore with stale-open CAS. Preserve original unknown requests, improve Pi conversation continuity and native DPI/navigation reads, and publish the authenticated template metadata contract. Validated: native backend 172 passed/5 environment tests ignored, UI 110, Pi 53, template/rule API 24 and native cloud contract 6; strict Clippy, layering and wasm. Real S01 selected B, edited/undo-redo, PCraft reopen and layered PSD roundtrip pass with exact pixels. Full nine-output generation and Photoshop acceptance remain open.
63 lines
4.1 KiB
TypeScript
63 lines
4.1 KiB
TypeScript
/** @jest-environment node */
|
|
import { desktopProjectBody } from '@/lib/desktop-client/contract.mjs'
|
|
import { emptyCreation } from '@/lib/desktop-client/creation.mjs'
|
|
const hash = 'a'.repeat(64)
|
|
function fixture() { return { revision: 0, status: 'draft', document: { version: 3, id: 'project', name: '顾家五屏', screens: [{ id: 'one', width: 1440, height: 2200, previewSource: null }], native: { format: 'photocraft', schemaVersion: 1, documentSource: null as string | null, files: [] as any[] } } } }
|
|
test('accepts an explicit incomplete draft but never labels it completed', () => {
|
|
const value = fixture(); expect(desktopProjectBody(value).document.version).toBe(3)
|
|
value.status = 'completed'; expect(() => desktopProjectBody(value)).toThrow('完结项目')
|
|
})
|
|
test('requires a complete safe manifest and strips unrecognized fields from native metadata', () => {
|
|
const value = fixture()
|
|
value.document.native.files = ['canvas.pcraft','context.json','session-backup.json'].map(path => ({ path, source: 'native:' + hash, sha256: hash, size: 100 }))
|
|
value.document.native.documentSource = 'native:' + hash
|
|
expect(desktopProjectBody(value).document.native.files).toHaveLength(3)
|
|
value.document.native.files[0].path = '../credentials.json'; expect(() => desktopProjectBody(value)).toThrow('原生工程文件')
|
|
})
|
|
test('rejects unhashed native sources, missing session backup, duplicate screens and oversized geometry', () => {
|
|
const value = fixture()
|
|
value.document.native.files = [{ path: 'canvas.pcraft', source: 'native:' + hash, sha256: hash, size: 100 }]
|
|
value.document.native.documentSource = 'native:' + hash
|
|
expect(() => desktopProjectBody(value)).toThrow('会话恢复文件')
|
|
value.document.native.files[0].source = 'native:uuid'; expect(() => desktopProjectBody(value)).toThrow('工程文件无效')
|
|
const other = fixture(); other.document.screens[0].height = 30001; expect(() => desktopProjectBody(other)).toThrow('画布超出限制')
|
|
})
|
|
|
|
function nativeCreationFixture() {
|
|
const value: any = fixture()
|
|
value.status = 'completed'
|
|
value.document.native.files = ['canvas.pcraft', 'context.json', 'session-backup.json'].map(path => ({ path, source: 'native:' + hash, sha256: hash, size: 100 }))
|
|
value.document.native.documentSource = 'native:' + hash
|
|
value.document.screens[0].previewSource = 'local:first-screen'
|
|
const inherited = Array.from({ length: 20 }, (_, index) => `事实待确认${index + 1}`)
|
|
const own = Array.from({ length: 20 }, (_, index) => `模型待确认${index + 1}`)
|
|
const creation: any = emptyCreation()
|
|
creation.facts.missing = inherited
|
|
creation.sellingPoints.batches = [{ id: 'batch-1', direction: '', items: ['可见桌面'], warnings: [...inherited, ...own] }]
|
|
creation.plan.warnings = [...inherited, ...own]
|
|
value.document.creation = creation
|
|
return value
|
|
}
|
|
|
|
test('native cloud upload preserves all forty inherited and model warnings in selling points and plan', () => {
|
|
const value = nativeCreationFixture()
|
|
const original = JSON.stringify(value)
|
|
const saved = desktopProjectBody(value)
|
|
expect(saved.document.version).toBe(3)
|
|
expect(saved.document.native.documentSource).toBe('native:' + hash)
|
|
expect(saved.document.creation.sellingPoints.batches[0].warnings).toEqual(value.document.creation.sellingPoints.batches[0].warnings)
|
|
expect(saved.document.creation.plan.warnings).toEqual(value.document.creation.plan.warnings)
|
|
expect(saved.document.creation.sellingPoints.batches[0].warnings).toHaveLength(40)
|
|
expect(saved.document.creation.plan.warnings).toHaveLength(40)
|
|
expect(saved.document.creation.facts.missing).toHaveLength(20)
|
|
expect(JSON.stringify(value)).toBe(original)
|
|
})
|
|
|
|
test.each(['sellingPoints', 'plan'])('native cloud upload rejects forty-one %s warnings instead of truncating evidence', field => {
|
|
const value = nativeCreationFixture()
|
|
const warnings = field === 'sellingPoints' ? value.document.creation.sellingPoints.batches[0].warnings : value.document.creation.plan.warnings
|
|
warnings.push('第41条不得静默丢弃')
|
|
expect(() => desktopProjectBody(value)).toThrow(field === 'sellingPoints' ? '卖点待确认项超出限制' : '方案待确认项超出限制')
|
|
expect(warnings).toHaveLength(41)
|
|
})
|