- 9 backend security test files (auth, headers, rate-limit, middleware order, smoke, validation, WS auth, integration bootstrap) - 1 e2e test (clear-preference) - SECURITY.md policy doc These files powered the 369-test suite but were never committed. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
84 lines
2.9 KiB
TypeScript
84 lines
2.9 KiB
TypeScript
import { describe, it, expect, beforeEach, afterEach } from 'vitest';
|
|
import request from 'supertest';
|
|
import { initDb, closeDb, setActiveTenant } from '../../src/db.js';
|
|
import path from 'path';
|
|
import os from 'os';
|
|
import fs from 'fs';
|
|
|
|
let dbPath: string;
|
|
let app: any;
|
|
const frontendDir = path.join(process.cwd(), 'dist/frontend');
|
|
const frontendHtmlPath = path.join(frontendDir, 'index.html');
|
|
let originalFrontendHtml: string | null = null;
|
|
let hadFrontendHtml = false;
|
|
|
|
beforeEach(async () => {
|
|
dbPath = path.join(os.tmpdir(), `excalidraw-smoke-test-${Date.now()}-${Math.random().toString(36).slice(2)}.db`);
|
|
initDb(dbPath);
|
|
setActiveTenant('default');
|
|
hadFrontendHtml = fs.existsSync(frontendHtmlPath);
|
|
originalFrontendHtml = hadFrontendHtml ? fs.readFileSync(frontendHtmlPath, 'utf8') : null;
|
|
fs.mkdirSync(frontendDir, { recursive: true });
|
|
fs.writeFileSync(frontendHtmlPath, '<!doctype html><html><head><title>Smoke</title></head><body><div id="root"></div></body></html>');
|
|
const mod = await import('../../src/server.js');
|
|
app = mod.default;
|
|
});
|
|
|
|
afterEach(() => {
|
|
delete process.env.EXCALIDRAW_API_KEY;
|
|
closeDb();
|
|
if (hadFrontendHtml && originalFrontendHtml !== null) {
|
|
fs.writeFileSync(frontendHtmlPath, originalFrontendHtml);
|
|
} else {
|
|
try { fs.unlinkSync(frontendHtmlPath); } catch {}
|
|
}
|
|
for (const suffix of ['', '-wal', '-shm']) {
|
|
try { fs.unlinkSync(dbPath + suffix); } catch {}
|
|
}
|
|
});
|
|
|
|
describe('Smoke checks', () => {
|
|
it('serves the health endpoint and frontend shell', async () => {
|
|
const healthRes = await request(app).get('/health');
|
|
expect(healthRes.status).toBe(200);
|
|
expect(healthRes.body.status).toBe('healthy');
|
|
|
|
const rootRes = await request(app).get('/');
|
|
expect(rootRes.status).toBe(200);
|
|
expect(rootRes.text).toContain('<div id="root"></div>');
|
|
});
|
|
|
|
it('supports a keyed create-list-delete smoke flow', async () => {
|
|
process.env.EXCALIDRAW_API_KEY = 'smoke-secret';
|
|
|
|
const createRes = await request(app)
|
|
.post('/api/elements')
|
|
.set('X-API-Key', 'smoke-secret')
|
|
.send({ id: 'smoke-el', type: 'rectangle', x: 0, y: 0, width: 100, height: 50 });
|
|
expect(createRes.status).toBe(200);
|
|
|
|
const listRes = await request(app)
|
|
.get('/api/elements')
|
|
.set('X-API-Key', 'smoke-secret');
|
|
expect(listRes.status).toBe(200);
|
|
expect(listRes.body.count).toBe(1);
|
|
expect(listRes.body.elements[0].id).toBe('smoke-el');
|
|
|
|
const searchRes = await request(app)
|
|
.get('/api/elements/search')
|
|
.set('X-API-Key', 'smoke-secret')
|
|
.query({ q: 'rectangle' });
|
|
expect(searchRes.status).toBe(200);
|
|
|
|
const deleteRes = await request(app)
|
|
.delete('/api/elements/smoke-el')
|
|
.set('X-API-Key', 'smoke-secret');
|
|
expect(deleteRes.status).toBe(200);
|
|
|
|
const finalListRes = await request(app)
|
|
.get('/api/elements')
|
|
.set('X-API-Key', 'smoke-secret');
|
|
expect(finalListRes.body.count).toBe(0);
|
|
});
|
|
});
|