import assert from 'node:assert/strict' import { test } from 'node:test' import { emptyCreation, validateCreation } from '../lib/desktop-client/creation.mjs' function fixture(warnings) { const value = emptyCreation() value.brief.name = '真实合同形状的产品资料' value.facts = { status: 'ready', items: [{ text: '测试仅验证已存资料合同,不派发模型请求', source: '本地合成合同样例' }], missing: Array.from({ length: 12 }, (_, index) => `事实待确认 ${index + 1}`), } value.sellingPoints.batches = [{ id: 'batch-1', direction: '', items: ['产品外观表达'], factsHash: 'a'.repeat(64), warnings: [...warnings], }] value.plan = { ...value.plan, status: 'needs-confirm', screens: [{ id: 'S01', name: '首屏', module: '产品介绍', image: true, title: '产品', body: '', imagePrompt: '仅验证数据结构' }], warnings: [...warnings], } return value } function storedUnion(each) { return [ ...Array.from({ length: each }, (_, index) => `事实待确认 ${index + 1}`), ...Array.from({ length: each }, (_, index) => `模型待确认 ${index + 1}`), ] } test('the stored 12 factual plus 12 model warnings survive in both batches and the plan', () => { const warnings = storedUnion(12), value = fixture(warnings), clean = validateCreation(value) assert.equal(warnings.length, 24) assert.deepEqual(clean.sellingPoints.batches[0].warnings, warnings) assert.deepEqual(clean.plan.warnings, warnings) assert.deepEqual(clean.facts, value.facts) }) test('all 40 merged warnings retain their order and text instead of being truncated', () => { const warnings = storedUnion(20), clean = validateCreation(fixture(warnings)) assert.equal(warnings.length, 40) assert.deepEqual(clean.sellingPoints.batches[0].warnings, warnings) assert.deepEqual(clean.plan.warnings, warnings) }) test('41 stored warnings fail independently in the batch and plan fields', () => { const warnings = Array.from({ length: 41 }, (_, index) => `待确认 ${index + 1}`) const batch = fixture([]); batch.sellingPoints.batches[0].warnings = warnings assert.throws(() => validateCreation(batch), /卖点待确认项超出限制/) const plan = fixture([]); plan.plan.warnings = warnings assert.throws(() => validateCreation(plan), /方案待确认项超出限制/) }) test('the existing 500-character string boundary still applies to every merged warning', () => { const allowed = fixture(['字'.repeat(500)]) assert.equal(validateCreation(allowed).plan.warnings[0].length, 500) for (const target of ['batch', 'plan']) { const value = fixture([]) if (target === 'batch') value.sellingPoints.batches[0].warnings = ['字'.repeat(501)] else value.plan.warnings = ['字'.repeat(501)] assert.throws(() => validateCreation(value), /待确认项格式无效/) } }) test('older 20-item, empty and omitted warning fields remain compatible', () => { const old = Array.from({ length: 20 }, (_, index) => `原有待确认 ${index + 1}`) const clean = validateCreation(fixture(old)) assert.deepEqual(clean.sellingPoints.batches[0].warnings, old) assert.deepEqual(clean.plan.warnings, old) const empty = validateCreation(fixture([])) assert.deepEqual(empty.sellingPoints.batches[0].warnings, []) assert.deepEqual(empty.plan.warnings, []) const legacy = fixture([]) delete legacy.sellingPoints.batches[0].warnings; delete legacy.plan.warnings const upgraded = validateCreation(legacy) assert.equal(Object.hasOwn(upgraded.sellingPoints.batches[0], 'warnings'), false) assert.equal(Object.hasOwn(upgraded.plan, 'warnings'), false) })