geocrop-platform./apps/nextgen/server/smoke-test.js

90 lines
3.1 KiB
JavaScript

#!/usr/bin/env node
// Smoke test for WT-A: hits the running server on :3001 and checks
// (1) /api/health 200
// (2) /api/auth/login returns token + offline_jwt_secret
// (3) /api/auth/me/credentials works (regression check on the existing fix)
// (4) a 2MB JSON body returns 413 (body limit)
// (5) CORS rejects an evil origin in prod-like mode (skipped here; dev allows any)
const http = require('http');
function request(method, path, { body, headers, expectStatus } = {}) {
return new Promise((resolve, reject) => {
const opts = {
host: 'localhost',
port: 3001,
path,
method,
headers: { 'Content-Type': 'application/json', ...(headers || {}) },
};
if (body) {
opts.headers['Content-Length'] = Buffer.byteLength(body);
}
const req = http.request(opts, (res) => {
let data = '';
res.on('data', (c) => (data += c));
res.on('end', () => {
const ok = expectStatus == null || res.statusCode === expectStatus;
resolve({ status: res.statusCode, body: data, ok });
});
});
req.on('error', reject);
if (body) req.write(body);
req.end();
});
}
(async () => {
const results = [];
// (1) health
let r = await request('GET', '/api/health', { expectStatus: 200 });
results.push(['GET /api/health → 200', r.ok, r.status]);
// (2) login
r = await request('POST', '/api/auth/login', {
body: JSON.stringify({ email: 'admin@school.com', password: 'admin123' }),
expectStatus: 200,
});
let loginBody = null;
try { loginBody = JSON.parse(r.body); } catch (e) { /* ignore */ }
const hasToken = !!loginBody?.token;
const hasOffline = loginBody?.offline_jwt_secret != null; // dev default true
results.push(['POST /api/auth/login returns token', hasToken, hasToken ? 'present' : 'missing']);
results.push(['POST /api/auth/login returns offline_jwt_secret', hasOffline, hasOffline ? 'present' : 'missing/null']);
// (3) /api/auth/me/credentials with the token
if (hasToken) {
r = await request('GET', '/api/auth/me/credentials', {
headers: { Authorization: `Bearer ${loginBody.token}` },
expectStatus: 200,
});
results.push(['GET /api/auth/me/credentials (with token) → 200', r.ok, r.status]);
}
// (4) 2MB JSON body → 413
const big = JSON.stringify({ data: 'x'.repeat(2 * 1024 * 1024) });
r = await request('POST', '/api/auth/login', {
body: big,
// We expect either 400 (bad credentials parsed first) or 413 (body too large)
// We accept any 4xx — what matters is it's NOT 500 and NOT 200.
});
const is4xx = r.status >= 400 && r.status < 500;
results.push(['2MB JSON body rejected (4xx)', is4xx, r.status]);
// Print results
let pass = 0;
let fail = 0;
for (const [name, ok, detail] of results) {
const mark = ok ? '✓' : '✗';
console.log(`${mark} ${name}${detail}`);
if (ok) pass++;
else fail++;
}
console.log(`\n${pass}/${results.length} checks passed.`);
process.exit(fail === 0 ? 0 : 1);
})().catch((err) => {
console.error('Smoke test crashed:', err.message);
process.exit(2);
});