const { test } = require('node:test') const assert = require('node:assert/strict') const fs = require('node:fs') const vm = require('node:vm') const ts = require('typescript') function setup() { const api = {} const revoked = [] let count = 0 vm.runInNewContext(ts.transpileModule(fs.readFileSync(require.resolve('../src/renderer/src/components/chatAttachments.ts'), 'utf8'), { compilerOptions: { module: ts.ModuleKind.CommonJS, target: ts.ScriptTarget.ES2022 } }).outputText, { exports: api, TextDecoder, createImageBitmap: async file => { if (file.invalid) throw Error('invalid') return { width: file.width ?? 10, height: file.height ?? 10, close() {} } }, URL: { createObjectURL: () => `blob:fixture-${++count}`, revokeObjectURL: url => revoked.push(url) } }) return { read: (files, existing = []) => api.readChatAttachments(files, existing, { imagesEnabled: true }), revoked } } const image = (extra = {}) => ({ name: 'screen.png', size: 100, ...extra }) test('image and text attachments coexist without counting image bytes as text context', async () => { const h = setup() const files = await h.read([image({ size: 5 * 1024 * 1024 }), { name: 'config.yaml', size: 10, arrayBuffer: async () => new TextEncoder().encode('robot: mini').buffer }]) assert.equal(files[0].kind, 'image') assert.equal(files[0].previewUrl, 'blob:fixture-1') assert.equal(files[1].content, 'robot: mini') }) test('bounds image counts, byte sizes, decoded pixels and rejects malformed images', async () => { const h = setup() await assert.rejects(h.read([image({ size: 5 * 1024 * 1024 + 1 })]), /5MB/) await assert.rejects(h.read([image({ width: 4001, height: 4001 })]), /1600만/) await assert.rejects(h.read([image({ invalid: true })]), /읽지 못/) await assert.rejects(h.read(Array.from({ length: 4 }, () => image())), /3장/) assert.equal(h.revoked.length, 3) }) test('a mixed batch failure revokes only newly created image previews', async () => { const h = setup() const existing = await h.read([image()]) await assert.rejects(h.read([image(), { name: 'file.pdf', size: 20 }], existing), /PDF/) assert.deepEqual(h.revoked, ['blob:fixture-2']) assert.equal(existing[0].previewUrl, 'blob:fixture-1') })