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|TRANSLATION_TASK/); const question = String(body.question); const text = question.includes('AGENT_REPLY_POLISH') ? 'Please provide the order number.' : 'Dzień dobry'; if (question.includes('AGENT_REPLY_POLISH')) { assert.match(question, /English \(en\)/); assert.match(question, /output MUST be English/); } return new Response(JSON.stringify({ text }), { status: 200, headers: { 'Content-Type': 'application/json' }, }); } if (url.includes('eksupport.easyklima.com') && url.includes('/conversations/42/messages')) { assert.equal((init?.headers as Record)?.api_access_token, 'test-chatwoot-token'); return new Response( JSON.stringify({ payload: [ { id: 1, message_type: 'outgoing', content: 'Dzień dobry' }, { id: 2, message_type: 0, private: false, created_at: 1, content: 'Hey, I have not received my order. What is going on?' }, ], }), { 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: 'auto', conversationId: 42, }); assert.equal(res.status, 200); assert.equal(res.body.ok, true); assert.equal(res.body.provider, 'flowise'); assert.equal(res.body.targetLanguage, 'en'); assert.equal(res.body.translatedText, 'Please provide the order number.'); }); 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 }; }