feat: redirect router (302 to VM) instead of S3 stream + bump 0.0.3

This commit is contained in:
“Naeel”
2026-09-02 18:36:47 +03:00
parent 658e6e9c7f
commit 5360893b2a
5 changed files with 81 additions and 1504 deletions
+15 -82
View File
@@ -1,12 +1,11 @@
'use strict';
process.env.S3_BUCKET = process.env.S3_BUCKET || 'terraform-registry';
process.env.VM_DOCS_BASE_URL = process.env.VM_DOCS_BASE_URL || 'http://vm.example';
const test = require('node:test');
const assert = require('node:assert');
const { Readable } = require('node:stream');
const { getDocsCandidates, contentTypeFor, server, s3 } = require('../server.js');
const { server } = require('../server.js');
async function withServer(fn) {
await new Promise((resolve) => server.listen(0, '127.0.0.1', resolve));
@@ -18,100 +17,34 @@ async function withServer(fn) {
}
}
// --- getDocsCandidates (URL -> S3 keys) ---
test('candidates: trailing slash -> index.html', () => {
assert.deepStrictEqual(
getDocsCandidates('/nubes/nubes/1.0.0/'),
['docs/nubes/nubes/1.0.0/index.html']
);
});
test('candidates: file with extension -> exact + root index fallback', () => {
assert.deepStrictEqual(
getDocsCandidates('/nubes/nubes/1.0.0/page.html'),
['docs/nubes/nubes/1.0.0/page.html', 'docs/nubes/nubes/1.0.0/index.html']
);
});
test('candidates: directory-style path -> exact + index.html + root index', () => {
assert.deepStrictEqual(
getDocsCandidates('/nubes/nubes/1.0.0/guides/getting-started'),
[
'docs/nubes/nubes/1.0.0/guides/getting-started',
'docs/nubes/nubes/1.0.0/guides/getting-started/index.html',
'docs/nubes/nubes/1.0.0/index.html',
]
);
});
// --- contentTypeFor ---
test('contentTypeFor: known and unknown extensions', () => {
assert.strictEqual(contentTypeFor('index.html'), 'text/html; charset=utf-8');
assert.strictEqual(contentTypeFor('style.css'), 'text/css; charset=utf-8');
assert.strictEqual(contentTypeFor('app.js'), 'application/javascript; charset=utf-8');
assert.strictEqual(contentTypeFor('logo.png'), 'image/png');
assert.strictEqual(contentTypeFor('data.json'), 'application/json; charset=utf-8');
assert.strictEqual(contentTypeFor('file.unknown'), 'application/octet-stream');
});
// --- /health ---
test('GET /health -> 200 ok when S3 available', async () => {
const originalSend = s3.send;
s3.send = async () => ({ $metadata: { httpStatusCode: 200 } });
test('GET /health -> 200 ok', async () => {
await withServer(async (base) => {
const res = await fetch(`${base}/health`);
assert.strictEqual(res.status, 200);
assert.strictEqual(await res.text(), 'ok');
});
s3.send = originalSend;
});
test('GET /health -> 503 when S3 unreachable', async () => {
const originalSend = s3.send;
s3.send = async () => { throw new Error('boom'); };
test('GET /nubes-test/akhq/ -> 302 to VM', async () => {
await withServer(async (base) => {
const res = await fetch(`${base}/health`);
assert.strictEqual(res.status, 503);
assert.match(await res.text(), /s3 unreachable/);
const res = await fetch(`${base}/nubes-test/akhq/`, { redirect: 'manual' });
assert.strictEqual(res.status, 302);
assert.strictEqual(res.headers.get('location'), 'http://vm.example/nubes-test/akhq/');
});
s3.send = originalSend;
});
// --- /docs ---
test('GET /docs/... -> 200 streams body with content-type', async () => {
const originalSend = s3.send;
s3.send = async (cmd) => {
if (cmd.input && cmd.input.Key) {
return { Body: Readable.from(['<html>ok</html>']), ContentType: 'text/html' };
}
return { $metadata: { httpStatusCode: 200 } };
};
test('GET / -> 302 to VM root', async () => {
await withServer(async (base) => {
const res = await fetch(`${base}/nubes/nubes/1.0.0/`);
assert.strictEqual(res.status, 200);
assert.match(res.headers.get('content-type') || '', /text\/html/);
assert.strictEqual(await res.text(), '<html>ok</html>');
const res = await fetch(`${base}/`, { redirect: 'manual' });
assert.strictEqual(res.status, 302);
assert.strictEqual(res.headers.get('location'), 'http://vm.example/');
});
s3.send = originalSend;
});
test('GET /docs/... -> 404 when no key found', async () => {
const originalSend = s3.send;
s3.send = async (cmd) => {
if (cmd.input && cmd.input.Key) {
const err = new Error('Not Found');
err.name = 'NoSuchKey';
throw err;
}
return { $metadata: { httpStatusCode: 200 } };
};
test('POST -> 405', async () => {
await withServer(async (base) => {
const res = await fetch(`${base}/nubes/nubes/1.0.0/missing`);
assert.strictEqual(res.status, 404);
const res = await fetch(`${base}/health`, { method: 'POST' });
assert.strictEqual(res.status, 405);
});
s3.send = originalSend;
});