'use strict'; const test = require('node:test'); const assert = require('node:assert/strict'); const { createServer } = require('../src/server'); const baseCfg = { port: 0, toolsSharedKey: 'test-key', toolsPublicBaseUrl: 'http://host.docker.internal:4010', devBypassVerification: false, twenty: {}, }; function fakeTools() { return [ { name: 'search_products', description: 'search', parameters: { type: 'object', properties: { query: { type: 'string' } } }, requiresVerification: false, handler: async (args, ctx) => ({ echo: args.query || null, verified: ctx.verified }), }, { name: 'search_orders', description: 'orders', parameters: { type: 'object', properties: {} }, requiresVerification: true, handler: async () => ({ orders: [] }), }, ]; } async function startServer(tools = fakeTools(), cfg = baseCfg) { const server = createServer({ config: cfg, tools }); await new Promise((resolve) => server.listen(0, '127.0.0.1', resolve)); const { port } = server.address(); return { base: `http://127.0.0.1:${port}`, close: () => new Promise((resolve) => server.close(resolve)), }; } test('GET /healthz is public and reports tool names', async () => { const s = await startServer(); try { const res = await fetch(`${s.base}/healthz`); assert.equal(res.status, 200); const body = await res.json(); assert.equal(body.ok, true); assert.deepEqual(body.tools, ['search_products', 'search_orders']); } finally { await s.close(); } }); test('tools endpoints reject missing/wrong key', async () => { const s = await startServer(); try { const missing = await fetch(`${s.base}/tools/manifest`); assert.equal(missing.status, 401); const wrong = await fetch(`${s.base}/tools/manifest`, { headers: { 'x-tools-key': 'nope' } }); assert.equal(wrong.status, 401); } finally { await s.close(); } }); test('manifest exposes URL, schema and verification flag', async () => { const s = await startServer(); try { const res = await fetch(`${s.base}/tools/manifest`, { headers: { 'x-tools-key': 'test-key' } }); const body = await res.json(); assert.equal(res.status, 200); const orders = body.tools.find((t) => t.name === 'search_orders'); assert.equal(orders.url, 'http://host.docker.internal:4010/tools/search_orders'); assert.equal(orders.requires_verification, true); assert.equal(body.tools[0].auth.headers[0].key, 'X-Tools-Key'); } finally { await s.close(); } }); test('verification is enforced on the server, not only in LibreDesk', async () => { const s = await startServer(); try { const res = await fetch(`${s.base}/tools/search_orders`, { method: 'POST', headers: { 'x-tools-key': 'test-key', 'content-type': 'application/json' }, body: '{}', }); assert.equal(res.status, 403); const body = await res.json(); assert.equal(body.error, 'verification_required'); } finally { await s.close(); } }); test('verified header is forwarded to handlers and result is returned', async () => { const s = await startServer(); try { const res = await fetch(`${s.base}/tools/search_products`, { method: 'POST', headers: { 'x-tools-key': 'test-key', 'content-type': 'application/json', 'x-libredesk-contact-email': 'A@B.com', 'x-libredesk-contact-verified': 'true', }, body: JSON.stringify({ query: 'hoops' }), }); const body = await res.json(); assert.equal(res.status, 200); assert.equal(body.ok, true); assert.equal(body.tool, 'search_products'); assert.equal(body.echo, 'hoops'); assert.equal(body.verified, true); } finally { await s.close(); } }); test('invalid JSON is a 400, unknown tool is a 404', async () => { const s = await startServer(); try { const bad = await fetch(`${s.base}/tools/search_products`, { method: 'POST', headers: { 'x-tools-key': 'test-key', 'content-type': 'application/json' }, body: '{not-json', }); assert.equal(bad.status, 400); const unknown = await fetch(`${s.base}/tools/nope`, { method: 'POST', headers: { 'x-tools-key': 'test-key' }, }); assert.equal(unknown.status, 404); } finally { await s.close(); } }); test('missing TOOLS_SHARED_KEY fails closed with 503', async () => { const s = await startServer(fakeTools(), { ...baseCfg, toolsSharedKey: '' }); try { const res = await fetch(`${s.base}/tools/manifest`, { headers: { 'x-tools-key': '' } }); assert.equal(res.status, 503); } finally { await s.close(); } });