import assert from 'node:assert/strict'; import test from 'node:test'; import { createMindSpaceImageReviewService, mindSpaceImageReviewInternals, } from './mindspace-image-review.mjs'; test('image review parses a fenced Qwen JSON response', () => { const result = mindSpaceImageReviewInternals.parseReviewJson(`\`\`\`json {"verdict":"reject","relevance_score":0,"observed_subjects":["人物"],"missing_required_elements":["竹海"],"reason":"不符"} \`\`\``); assert.deepEqual(result, { verdict: 'reject', relevanceScore: 0, observedSubjects: ['人物'], missingRequiredElements: ['竹海'], reason: '不符', }); }); test('image review sends image bytes and original requirements to Qwen vision', async () => { let received = null; const service = createMindSpaceImageReviewService({ llmProviderService: { async analyzeImagesWithVision(items, prompt) { received = { items, prompt }; return JSON.stringify({ verdict: 'pass', relevance_score: 91, observed_subjects: ['竹海'], missing_required_elements: [], reason: '主体与场景一致', }); }, }, env: { IMAGE_MAKE_SEMANTIC_REVIEW_MIN_SCORE: '70' }, }); const result = await service.review({ buffer: Buffer.from('webp-image'), mimeType: 'image/webp', purpose: 'hero', prompt: '安吉竹海', }); assert.equal(result.pass, true); assert.equal(result.relevanceScore, 91); assert.equal(received.items[0].data, Buffer.from('webp-image').toString('base64')); assert.match(received.prompt, /页面首图/); assert.match(received.prompt, /安吉竹海/); assert.match(received.prompt, /70/); }); test('image review rejects a nominal pass below the configured score', async () => { const service = createMindSpaceImageReviewService({ llmProviderService: { async analyzeImagesWithVision() { return '{"verdict":"pass","relevance_score":69,"reason":"仅颜色接近"}'; }, }, env: { IMAGE_MAKE_SEMANTIC_REVIEW_MIN_SCORE: '70' }, }); const result = await service.review({ buffer: Buffer.from('image'), mimeType: 'image/webp', purpose: 'hero', prompt: '安吉竹海', }); assert.equal(result.ok, true); assert.equal(result.pass, false); }); test('image review fails closed on missing or malformed Qwen responses', async () => { for (const response of [null, '不是 JSON']) { const service = createMindSpaceImageReviewService({ llmProviderService: { async analyzeImagesWithVision() { return response; } }, logger: { warn() {} }, }); const result = await service.review({ buffer: Buffer.from('image'), mimeType: 'image/webp', purpose: 'hero', prompt: '安吉竹海', }); assert.equal(result.ok, false); assert.equal(result.code, 'IMAGE_REVIEW_INVALID_RESPONSE'); } });