126 lines
3.8 KiB
JavaScript
126 lines
3.8 KiB
JavaScript
import test, { beforeEach } from 'node:test';
|
|
import assert from 'node:assert/strict';
|
|
import request from 'supertest';
|
|
import { createApp } from '../src/app.js';
|
|
import { __resetLlmRateLimitForTests } from '../src/services/llm-rate-limit.js';
|
|
|
|
beforeEach(() => {
|
|
process.env.AUTH_BYPASS = 'true';
|
|
process.env.LLM_MOCK = 'true';
|
|
process.env.SIGNED_URL_MOCK = 'true';
|
|
process.env.MAX_SIGNED_URL_SECONDS = '900';
|
|
process.env.LLM_RATE_LIMIT_PER_MINUTE = '20';
|
|
__resetLlmRateLimitForTests();
|
|
});
|
|
|
|
test('GET /healthz returns healthy response', async () => {
|
|
const app = createApp();
|
|
const res = await request(app).get('/healthz');
|
|
|
|
assert.equal(res.status, 200);
|
|
assert.equal(res.body.ok, true);
|
|
assert.equal(typeof res.body.requestId, 'string');
|
|
assert.equal(typeof res.headers['x-request-id'], 'string');
|
|
});
|
|
|
|
test('POST /core/create-signed-url requires auth', async () => {
|
|
process.env.AUTH_BYPASS = 'false';
|
|
const app = createApp();
|
|
const res = await request(app).post('/core/create-signed-url').send({
|
|
fileUri: 'gs://krow-workforce-dev-private/foo.pdf',
|
|
});
|
|
|
|
assert.equal(res.status, 401);
|
|
assert.equal(res.body.code, 'UNAUTHENTICATED');
|
|
process.env.AUTH_BYPASS = 'true';
|
|
});
|
|
|
|
test('POST /core/create-signed-url returns signed URL', async () => {
|
|
const app = createApp();
|
|
const res = await request(app)
|
|
.post('/core/create-signed-url')
|
|
.set('Authorization', 'Bearer test-token')
|
|
.send({
|
|
fileUri: 'gs://krow-workforce-dev-private/uploads/test-user/foo.pdf',
|
|
expiresInSeconds: 300,
|
|
});
|
|
|
|
assert.equal(res.status, 200);
|
|
assert.equal(typeof res.body.signedUrl, 'string');
|
|
assert.equal(typeof res.body.expiresAt, 'string');
|
|
assert.equal(typeof res.body.requestId, 'string');
|
|
});
|
|
|
|
test('POST /core/create-signed-url rejects non-owned path', async () => {
|
|
const app = createApp();
|
|
const res = await request(app)
|
|
.post('/core/create-signed-url')
|
|
.set('Authorization', 'Bearer test-token')
|
|
.send({
|
|
fileUri: 'gs://krow-workforce-dev-private/uploads/other-user/foo.pdf',
|
|
expiresInSeconds: 300,
|
|
});
|
|
|
|
assert.equal(res.status, 403);
|
|
assert.equal(res.body.code, 'FORBIDDEN');
|
|
});
|
|
|
|
test('POST /core/create-signed-url enforces expiry cap', async () => {
|
|
process.env.MAX_SIGNED_URL_SECONDS = '300';
|
|
const app = createApp();
|
|
const res = await request(app)
|
|
.post('/core/create-signed-url')
|
|
.set('Authorization', 'Bearer test-token')
|
|
.send({
|
|
fileUri: 'gs://krow-workforce-dev-private/uploads/test-user/foo.pdf',
|
|
expiresInSeconds: 301,
|
|
});
|
|
|
|
assert.equal(res.status, 400);
|
|
assert.equal(res.body.code, 'VALIDATION_ERROR');
|
|
});
|
|
|
|
test('POST /invokeLLM legacy alias works', async () => {
|
|
const app = createApp();
|
|
const res = await request(app)
|
|
.post('/invokeLLM')
|
|
.set('Authorization', 'Bearer test-token')
|
|
.send({
|
|
prompt: 'hello',
|
|
responseJsonSchema: { type: 'object' },
|
|
fileUrls: [],
|
|
});
|
|
|
|
assert.equal(res.status, 200);
|
|
assert.equal(typeof res.body.result, 'object');
|
|
assert.equal(typeof res.body.model, 'string');
|
|
});
|
|
|
|
test('POST /core/invoke-llm enforces per-user rate limit', async () => {
|
|
process.env.LLM_RATE_LIMIT_PER_MINUTE = '1';
|
|
const app = createApp();
|
|
|
|
const first = await request(app)
|
|
.post('/core/invoke-llm')
|
|
.set('Authorization', 'Bearer test-token')
|
|
.send({
|
|
prompt: 'hello',
|
|
responseJsonSchema: { type: 'object' },
|
|
fileUrls: [],
|
|
});
|
|
|
|
const second = await request(app)
|
|
.post('/core/invoke-llm')
|
|
.set('Authorization', 'Bearer test-token')
|
|
.send({
|
|
prompt: 'hello again',
|
|
responseJsonSchema: { type: 'object' },
|
|
fileUrls: [],
|
|
});
|
|
|
|
assert.equal(first.status, 200);
|
|
assert.equal(second.status, 429);
|
|
assert.equal(second.body.code, 'RATE_LIMITED');
|
|
assert.equal(typeof second.headers['retry-after'], 'string');
|
|
});
|