cloud-functions.special-actions.test.ts 1.4 KB

1234567891011121314151617181920212223242526
  1. import { test } from 'node:test';
  2. import assert from 'node:assert/strict';
  3. import { createSpecialActionHandler } from '../src/cloud-functions/special-actions.js';
  4. test('ai cloud action forwards only the allow-listed completion fields', async () => {
  5. let captured: Record<string, unknown> | undefined;
  6. const handler = createSpecialActionHandler({
  7. ai: { createChatCompletion: async (body: Record<string, unknown>) => { captured = body; return new Response(JSON.stringify({ choices: [] }), { status: 200 }); } } as any,
  8. domestic: {} as any,
  9. });
  10. const response = { json(value: unknown) { return value; } } as any;
  11. const handled = await handler({} as any, response, 'ai.chat', {
  12. workspaceId: 'workspace-a', action: 'ai.chat', messages: [{ role: 'user', content: 'hello' }], model: 'test-model', secret: 'must-not-forward', stream: true,
  13. }, 'request-1');
  14. assert.equal(handled, true);
  15. assert.deepEqual(captured, { messages: [{ role: 'user', content: 'hello' }], model: 'test-model', stream: false });
  16. });
  17. test('local upstream adapter rejects arbitrary URLs before configuration lookup', async () => {
  18. const handler = createSpecialActionHandler({ ai: {} as any, domestic: {} as any });
  19. const response = {} as any;
  20. await assert.rejects(
  21. handler({} as any, response, 'upstream.amazon', { path: 'https://attacker.invalid/relay', operation: 'get' }, 'request-2'),
  22. (error: any) => error?.code === 'upstream_path_not_allowed',
  23. );
  24. });