67 lines
3.0 KiB
JavaScript
67 lines
3.0 KiB
JavaScript
import assert from 'node:assert/strict';
|
|
import { spawn, spawnSync } from 'node:child_process';
|
|
import { access, cp, readFile, mkdtemp, rm } from 'node:fs/promises';
|
|
import { tmpdir } from 'node:os';
|
|
import { once } from 'node:events';
|
|
import path from 'node:path';
|
|
import test from 'node:test';
|
|
|
|
const projectRoot = path.resolve('.');
|
|
const standaloneRoot = path.join(projectRoot, '.next', 'standalone');
|
|
const port = 43217;
|
|
const origin = `http://127.0.0.1:${port}`;
|
|
|
|
async function waitForServer(process, getLogs) {
|
|
const deadline = Date.now() + 60_000;
|
|
while (Date.now() < deadline) {
|
|
if (process.exitCode !== null) throw new Error('standalone server exited early');
|
|
try {
|
|
const response = await fetch(origin, { signal: AbortSignal.timeout(10_000) });
|
|
if (response.ok) return;
|
|
} catch {}
|
|
await new Promise((resolve) => setTimeout(resolve, 150));
|
|
}
|
|
throw new Error(`standalone server did not become ready\n${getLogs()}`);
|
|
}
|
|
|
|
test('the standalone server renders generic samples without private content', async (t) => {
|
|
const dataDir = await mkdtemp(path.join(tmpdir(), 'portfolio-runtime-'));
|
|
const env = { ...process.env, DATA_DIR: dataDir, SITE_URL: origin, HOSTNAME: '127.0.0.1', PORT: String(port) };
|
|
await access(path.join(standaloneRoot, 'server.js'));
|
|
await cp(path.join(projectRoot, 'public'), path.join(standaloneRoot, 'public'), { recursive: true });
|
|
await cp(
|
|
path.join(projectRoot, '.next', 'static'),
|
|
path.join(standaloneRoot, '.next', 'static'),
|
|
{ recursive: true },
|
|
);
|
|
|
|
const imported = spawnSync(process.execPath, ['maintenance.mjs', 'init'], { cwd: standaloneRoot, env, encoding: 'utf8' });
|
|
assert.equal(imported.status, 0, imported.stderr);
|
|
const server = spawn(process.execPath, ['server.js'], {
|
|
cwd: standaloneRoot,
|
|
env,
|
|
stdio: ['ignore', 'pipe', 'pipe'],
|
|
});
|
|
let serverLogs = '';
|
|
server.stdout.on('data', (chunk) => { serverLogs += chunk; });
|
|
server.stderr.on('data', (chunk) => { serverLogs += chunk; });
|
|
t.after(async () => { if (server.exitCode === null) { const exited = once(server, 'exit'); server.kill(); await exited; } await rm(dataDir, { recursive: true, force: true }); });
|
|
await waitForServer(server, () => serverLogs);
|
|
|
|
const englishResponse = await fetch(`${origin}/`);
|
|
assert.equal(englishResponse.status, 200);
|
|
const englishHtml = await englishResponse.text();
|
|
assert.match(englishHtml, /<html[^>]*lang="en"[^>]*dir="ltr"/i);
|
|
assert.match(englishHtml, /Your Name/);
|
|
assert.equal((await fetch(`${origin}/fa`)).status, 404);
|
|
assert.equal((await fetch(`${origin}/projects/sample-projects`)).status, 200);
|
|
assert.equal((await fetch(`${origin}/projects/not-a-project`)).status, 404);
|
|
|
|
const staticAsset = englishHtml.match(/(?:src|href)="(\/_next\/static\/[^"?#]+)/)?.[1];
|
|
assert.ok(staticAsset, 'expected a built static asset');
|
|
assert.equal((await fetch(`${origin}${staticAsset}`)).status, 200);
|
|
|
|
const placeholder = await fetch(`${origin}/images/portfolio-placeholder.svg`);
|
|
assert.equal(placeholder.status, 200);
|
|
});
|