import { after, before, test } from 'node:test'; import assert from 'node:assert/strict'; import { prepareTestDatabase, startServer, type RunningServer } from '../helpers/testServer.js'; import { applyTestConfig } from '../helpers/testConfig.js'; const dbUrl = prepareTestDatabase('test-agent-tools'); const { createApp } = await import('../../src/http/app.js'); const { disconnectDb } = await import('../../src/store/db.js'); let running: RunningServer; let originalFetch: typeof globalThis.fetch; let flowiseCalls = 0; before(async () => { applyTestConfig({ DATABASE_URL: dbUrl, AGENT_UI_TOKEN: 'test-agent-token', CHATWOOT_BASE_URL: 'https://eksupport.easyklima.com', FLOWISE_TRANSLATION_PREDICT_URL: 'https://flowise.test/api/v1/prediction/translation', }); originalFetch = globalThis.fetch; globalThis.fetch = (async (input: Parameters[0], init?: Parameters[1]) => { const url = String(input); if (url.includes('flowise.test')) { flowiseCalls += 1; const body = JSON.parse(String(init?.body ?? '{}')) as Record; assert.match(String(body.question), /Translate this/); return new Response(JSON.stringify({ text: 'Dzień dobry' }), { status: 200, headers: { 'Content-Type': 'application/json' }, }); } return originalFetch(input, init); }) as typeof globalThis.fetch; running = await startServer(createApp()); }); after(async () => { globalThis.fetch = originalFetch; await running.close(); await disconnectDb(); }); test('serves the Chatwoot injection asset without secrets', async () => { const res = await fetch(`${running.baseUrl}/chatwoot-ai-tools.js`); const text = await res.text(); assert.equal(res.status, 200); assert.match(res.headers.get('content-type') ?? '', /application\/javascript/); assert.match(text, /AI tłumacz/); assert.ok(!text.includes('test-agent-token')); }); test('agent translation endpoints require the agent UI token', async () => { const res = await fetch(`${running.baseUrl}/agent-tools/translate-message`, { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ sourceText: 'Hello', targetLanguage: 'pl' }), }); assert.equal(res.status, 401); }); test('translates message text through Flowise and caches repeated requests', async () => { const payload = { sourceText: 'Good morning', targetLanguage: 'pl', conversationId: 42, messageId: 'm-1' }; const first = await postTranslate('/agent-tools/translate-message', payload); const second = await postTranslate('/agent-tools/translate-message', payload); assert.equal(first.status, 200); assert.equal(second.status, 200); assert.equal(first.body.translatedText, 'Dzień dobry'); assert.equal(first.body.cached, false); assert.equal(second.body.cached, true); assert.equal(flowiseCalls, 1); }); test('translates draft text through the draft endpoint', async () => { const res = await postTranslate('/agent-tools/translate-draft', { draftText: 'Proszę podać numer zamówienia.', targetLanguage: 'de', conversationId: 42, }); assert.equal(res.status, 200); assert.equal(res.body.ok, true); assert.equal(res.body.provider, 'flowise'); }); async function postTranslate(path: string, body: Record) { const res = await fetch(`${running.baseUrl}${path}`, { method: 'POST', headers: { 'Content-Type': 'application/json', Authorization: 'Bearer test-agent-token', Origin: 'https://eksupport.easyklima.com', }, body: JSON.stringify(body), }); return { status: res.status, body: (await res.json()) as Record }; }