Files
TeleUploader/test/web-api.test.ts
T

86 lines
3.1 KiB
TypeScript

import { afterAll, beforeAll, describe, expect, it, mock } from 'bun:test';
const mockBuckets = [
{ id: 'uuid-1', name: 'test-bucket', createdAt: new Date('2026-01-01'), updatedAt: new Date('2026-01-01') },
];
mock.module('../src/db/buckets', () => ({
listBuckets: () => Promise.resolve(mockBuckets),
findBucketByName: (name: string) => Promise.resolve(mockBuckets.find((b) => b.name === name) || null),
createBucket: (name: string) => Promise.resolve({ id: 'new-uuid', name, createdAt: new Date(), updatedAt: new Date() }),
deleteBucket: () => Promise.resolve(true),
bucketExists: () => Promise.resolve(false),
}));
mock.module('../src/db/files-ext', () => ({
findFileByBucketAndKey: () => Promise.resolve(null),
listObjectsByPrefix: () => Promise.resolve({ objects: [], prefixes: [] }),
softDeleteFile: () => Promise.resolve(true),
softDeleteFilesBatch: () => Promise.resolve(0),
countBucketObjects: () => Promise.resolve(0),
findOrphanFilesByBucket: () => Promise.resolve([]),
}));
mock.module('../src/utils/telegram', () => ({
forwardToStorage: () =>
Promise.resolve({
telegramFileId: 'mock-tg-id',
telegramFileUniqueId: 'mock-tg-unique',
storageMessageId: 12345,
}),
getFileInfo: () =>
Promise.resolve({
file_size: 100,
mime_type: 'text/plain',
file_path: 'documents/file.txt',
bot_token: '123456:ABC-DEF',
}),
}));
describe('Web API v1', () => {
let handleWebApiV1: typeof import('../src/routes/web-api').handleWebApiV1;
beforeAll(async () => {
process.env.BOT_TOKEN = '123456:ABC-DEF';
process.env.STORAGE_CHANNEL_ID = '-1001234567890';
process.env.BASE_URL = 'http://localhost:3000';
process.env.DATABASE_URL = 'postgresql://localhost/test';
const webApi = await import('../src/routes/web-api');
handleWebApiV1 = webApi.handleWebApiV1;
});
afterAll(() => {
mock.restore();
});
it('should list buckets via GET /api/v1/buckets', async () => {
const req = new Request('http://localhost:3000/api/v1/buckets');
const res = await handleWebApiV1(req);
expect(res.status).toBe(200);
const data = (await res.json()) as { buckets: { name: string }[] };
expect(data).toHaveProperty('buckets');
expect(Array.isArray(data.buckets)).toBe(true);
expect(data.buckets[0].name).toBe('test-bucket');
});
it('should return 404 for unknown API path', async () => {
const req = new Request('http://localhost:3000/api/v1/unknown');
const res = await handleWebApiV1(req);
expect(res.status).toBe(404);
const data = (await res.json()) as { error: string };
expect(data).toHaveProperty('error');
});
it('should return 400 for invalid bucket name on create', async () => {
const req = new Request('http://localhost:3000/api/v1/buckets', {
method: 'POST',
headers: { 'content-type': 'application/json' },
body: JSON.stringify({ name: 'INVALID_NAME!' }),
});
const res = await handleWebApiV1(req);
expect(res.status).toBe(400);
const data = (await res.json()) as { error: string };
expect(data.error).toContain('Invalid bucket name');
});
});