tools.test.ts 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109
  1. import { after, before, test } from 'node:test';
  2. import assert from 'node:assert/strict';
  3. import { prepareTestDatabase, startServer, type RunningServer } from '../helpers/testServer.js';
  4. import { applyTestConfig } from '../helpers/testConfig.js';
  5. const dbUrl = prepareTestDatabase('test-tools');
  6. const { createApp } = await import('../../src/http/app.js');
  7. const { disconnectDb } = await import('../../src/store/db.js');
  8. let running: RunningServer;
  9. const TOOL_PATHS = [
  10. '/tools/get_order_data',
  11. '/tools/get_product_data',
  12. '/tools/get_shipping_data',
  13. '/tools/get_payment_methods',
  14. '/tools/get_product_compatibility',
  15. '/tools/get_car_data',
  16. '/tools/new_ticket',
  17. ];
  18. before(async () => {
  19. applyTestConfig({ DATABASE_URL: dbUrl });
  20. running = await startServer(createApp());
  21. });
  22. after(async () => {
  23. await running.close();
  24. await disconnectDb();
  25. });
  26. async function post(path: string, body: unknown, auth?: string) {
  27. const headers: Record<string, string> = { 'Content-Type': 'application/json' };
  28. if (auth !== undefined) headers.Authorization = auth;
  29. const res = await fetch(`${running.baseUrl}${path}`, {
  30. method: 'POST',
  31. headers,
  32. body: JSON.stringify(body),
  33. });
  34. return { status: res.status, body: (await res.json()) as Record<string, unknown> };
  35. }
  36. test('every tool endpoint exists and rejects an unauthenticated call', async () => {
  37. for (const path of TOOL_PATHS) {
  38. const res = await post(path, {});
  39. assert.equal(res.status, 401, `${path} must require auth`);
  40. assert.equal(res.body.code, 'UNAUTHORIZED');
  41. }
  42. });
  43. test('a wrong bearer token is rejected', async () => {
  44. for (const path of TOOL_PATHS) {
  45. const res = await post(path, {}, 'Bearer wrong-secret');
  46. assert.equal(res.status, 401, `${path} must reject a wrong secret`);
  47. }
  48. });
  49. test('a token of the same length but different value is still rejected', async () => {
  50. const res = await post('/tools/new_ticket', { conversationId: 1 }, 'Bearer test-shared-secreT');
  51. assert.equal(res.status, 401);
  52. });
  53. test('an authenticated call with missing parameters returns 400, not 401', async () => {
  54. const res = await post('/tools/new_ticket', {}, 'Bearer test-shared-secret');
  55. assert.equal(res.status, 400);
  56. assert.equal(res.body.code, 'MISSING_PARAMS');
  57. });
  58. test('get_order_data requires an e-mail for ownership verification', async () => {
  59. const res = await post('/tools/get_order_data', { orderNumber: '123' }, 'Bearer test-shared-secret');
  60. assert.equal(res.status, 400);
  61. assert.equal(res.body.code, 'INVALID_PARAMS');
  62. });
  63. test('get_product_data requires at least one selector', async () => {
  64. const res = await post('/tools/get_product_data', {}, 'Bearer test-shared-secret');
  65. assert.equal(res.status, 400);
  66. assert.equal(res.body.code, 'MISSING_PARAMS');
  67. });
  68. test('admin endpoints require the admin token, not the tool secret', async () => {
  69. const noAuth = await fetch(`${running.baseUrl}/admin/events`);
  70. assert.equal(noAuth.status, 401);
  71. const toolSecret = await fetch(`${running.baseUrl}/admin/events`, {
  72. headers: { Authorization: 'Bearer test-shared-secret' },
  73. });
  74. assert.equal(toolSecret.status, 401);
  75. const admin = await fetch(`${running.baseUrl}/admin/events`, {
  76. headers: { Authorization: 'Bearer test-admin-token' },
  77. });
  78. assert.equal(admin.status, 200);
  79. const body = (await admin.json()) as Record<string, unknown>;
  80. assert.equal(body.ok, true);
  81. assert.ok(Array.isArray(body.events));
  82. });
  83. test('an unknown route returns a JSON 404', async () => {
  84. const res = await fetch(`${running.baseUrl}/tools/does_not_exist`, {
  85. method: 'POST',
  86. headers: { 'Content-Type': 'application/json', Authorization: 'Bearer test-shared-secret' },
  87. body: '{}',
  88. });
  89. assert.equal(res.status, 404);
  90. const body = (await res.json()) as Record<string, unknown>;
  91. assert.equal(body.code, 'NOT_FOUND');
  92. });