import test from 'node:test'; import assert from 'node:assert/strict'; import { api } from '../src/api.js'; test('api.listDocuments calls correct endpoint', async () => { const calls = []; globalThis.fetch = async (url, options) => { calls.push({ url: String(url), options }); return { ok: true, json: async () => [{ id: '1', filename: 'a.md', bytes: 3 }], }; }; const out = await api.listDocuments('conv123'); assert.equal(calls.length, 1); assert.match(calls[0].url, /\/api\/conversations\/conv123\/documents$/); assert.deepEqual(out, [{ id: '1', filename: 'a.md', bytes: 3 }]); }); test('api.uploadDocument uses multipart form and POST', async () => { const calls = []; globalThis.fetch = async (url, options) => { calls.push({ url: String(url), options }); return { ok: true, json: async () => ({ id: 'doc1', filename: 'x.md', bytes: 10 }), }; }; // Node 18 doesn't provide a global File, but it does provide Blob. // Our api.uploadDocument supports Blob + filename. const file = new Blob(['hello'], { type: 'text/markdown' }); file.name = 'x.md'; const out = await api.uploadDocument('conv999', file); assert.equal(calls.length, 1); assert.match(calls[0].url, /\/api\/conversations\/conv999\/documents$/); assert.equal(calls[0].options.method, 'POST'); assert.ok(calls[0].options.body instanceof FormData); assert.equal(out.id, 'doc1'); }); test('api.uploadDocuments uses multipart form and POST', async () => { const calls = []; globalThis.fetch = async (url, options) => { calls.push({ url: String(url), options }); return { ok: true, json: async () => ({ uploaded: [{ id: 'a' }, { id: 'b' }] }), }; }; const a = new Blob(['one'], { type: 'text/markdown' }); a.name = 'a.md'; const b = new Blob(['two'], { type: 'text/markdown' }); b.name = 'b.md'; const out = await api.uploadDocuments('conv999', [a, b]); assert.equal(calls.length, 1); assert.match(calls[0].url, /\/api\/conversations\/conv999\/documents$/); assert.equal(calls[0].options.method, 'POST'); assert.ok(calls[0].options.body instanceof FormData); assert.equal(out.uploaded.length, 2); }); test('api.getDocument calls correct endpoint', async () => { const calls = []; globalThis.fetch = async (url) => { calls.push({ url: String(url) }); return { ok: true, json: async () => ({ id: 'd1', content: '# hi' }), }; }; const out = await api.getDocument('c1', 'd1'); assert.equal(calls.length, 1); assert.match(calls[0].url, /\/api\/conversations\/c1\/documents\/d1$/); assert.equal(out.content, '# hi'); }); test('api.deleteDocument uses DELETE', async () => { const calls = []; globalThis.fetch = async (url, options) => { calls.push({ url: String(url), options }); return { ok: true, json: async () => ({ ok: true }) }; }; const out = await api.deleteDocument('c1', 'd1'); assert.equal(calls.length, 1); assert.match(calls[0].url, /\/api\/conversations\/c1\/documents\/d1$/); assert.equal(calls[0].options.method, 'DELETE'); assert.equal(out.ok, true); });