Import tests: app/backend/tests/phase10-smoke.test.mjs
Import the existing local project snapshot. This commit organizes existing files; it does not represent newly developed functionality.
This commit is contained in:
@@ -0,0 +1,73 @@
|
||||
import test from 'node:test';
|
||||
import assert from 'node:assert/strict';
|
||||
|
||||
const BASE = process.env.TEST_BASE_URL || 'http://127.0.0.1:3010';
|
||||
const SESSION = process.env.TEST_SESSION_COOKIE || '';
|
||||
const CSRF = process.env.TEST_CSRF_TOKEN || '';
|
||||
const TEST_ARTICLE_SLUG = process.env.TEST_ARTICLE_SLUG || 'agentic-ai-production-2026';
|
||||
const REQUIRE_SERVER = process.env.TEST_REQUIRE_SERVER === '1';
|
||||
|
||||
async function serverAvailable() {
|
||||
try {
|
||||
const res = await fetch(`${BASE}/api/health`, { signal: AbortSignal.timeout(1500) });
|
||||
return res.status < 500;
|
||||
} catch {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
const HAS_SERVER = await serverAvailable();
|
||||
if (!HAS_SERVER && REQUIRE_SERVER) {
|
||||
throw new Error(`TEST_REQUIRE_SERVER=1 but no backend is reachable at ${BASE}`);
|
||||
}
|
||||
const SERVER_SKIP = HAS_SERVER ? false : `no backend reachable at ${BASE}`;
|
||||
|
||||
async function request(path, options = {}) {
|
||||
const headers = {
|
||||
'content-type': 'application/json',
|
||||
...(SESSION ? { cookie: SESSION } : {}),
|
||||
...(CSRF ? { 'x-csrf-token': CSRF } : {}),
|
||||
...(options.headers || {}),
|
||||
};
|
||||
return fetch(`${BASE}${path}`, { ...options, headers });
|
||||
}
|
||||
|
||||
test('auth rejects invalid credentials without leaking internals', { skip: SERVER_SKIP }, async () => {
|
||||
const res = await request('/api/v1/auth/login', {
|
||||
method: 'POST',
|
||||
body: JSON.stringify({ identifier: 'nobody@example.invalid', password: 'wrong', captchaId: 'invalid', userSolution: '0000' }),
|
||||
});
|
||||
assert.ok([400, 401, 429].includes(res.status));
|
||||
const body = await res.json().catch(() => ({}));
|
||||
assert.ok(body.error || body.message);
|
||||
});
|
||||
|
||||
test('public article and comments endpoints are reachable', { skip: SERVER_SKIP }, async () => {
|
||||
const articleRes = await request(`/api/v1/articles/${TEST_ARTICLE_SLUG}`);
|
||||
assert.equal(articleRes.status, 200);
|
||||
const articleBody = await articleRes.json();
|
||||
assert.ok(articleBody.article?.id);
|
||||
|
||||
const commentsRes = await request(`/api/v1/articles/${TEST_ARTICLE_SLUG}/comments`);
|
||||
assert.equal(commentsRes.status, 200);
|
||||
const commentsBody = await commentsRes.json();
|
||||
assert.ok(Array.isArray(commentsBody.items));
|
||||
});
|
||||
|
||||
test('authenticated comment flow works when TEST_SESSION_COOKIE and TEST_CSRF_TOKEN are set', { skip: SERVER_SKIP || !SESSION || !CSRF }, async () => {
|
||||
const res = await request(`/api/v1/articles/${TEST_ARTICLE_SLUG}/comments`, {
|
||||
method: 'POST',
|
||||
body: JSON.stringify({ body: `Phase 10 smoke ${Date.now()}` }),
|
||||
});
|
||||
assert.equal(res.status, 200);
|
||||
const body = await res.json();
|
||||
assert.ok(body.comment?.id);
|
||||
});
|
||||
|
||||
test('authenticated article publish workflow is protected and callable when configured', { skip: SERVER_SKIP || !SESSION || !CSRF || !process.env.TEST_PUBLISH_ARTICLE_ID }, async () => {
|
||||
const res = await request(`/api/v1/admin/articles/${encodeURIComponent(process.env.TEST_PUBLISH_ARTICLE_ID)}/publish`, {
|
||||
method: 'POST',
|
||||
body: JSON.stringify({}),
|
||||
});
|
||||
assert.ok([200, 403, 404].includes(res.status));
|
||||
});
|
||||
Reference in New Issue
Block a user