refactor: remove bundled personal portfolio
This commit is contained in:
@@ -24,7 +24,7 @@ async function waitForServer(process, getLogs) {
|
||||
throw new Error(`standalone server did not become ready\n${getLogs()}`);
|
||||
}
|
||||
|
||||
test('the standalone server renders both locales and serves local images', async (t) => {
|
||||
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'));
|
||||
@@ -35,7 +35,7 @@ test('the standalone server renders both locales and serves local images', async
|
||||
{ recursive: true },
|
||||
);
|
||||
|
||||
const imported = spawnSync(process.execPath, ['maintenance.mjs', 'import-legacy'], { cwd: standaloneRoot, env, encoding: 'utf8' });
|
||||
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,
|
||||
@@ -48,77 +48,19 @@ test('the standalone server renders both locales and serves local images', async
|
||||
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, persianResponse] = await Promise.all([
|
||||
fetch(`${origin}/`),
|
||||
fetch(`${origin}/fa`),
|
||||
]);
|
||||
const englishResponse = await fetch(`${origin}/`);
|
||||
assert.equal(englishResponse.status, 200);
|
||||
assert.equal(persianResponse.status, 200);
|
||||
|
||||
const [englishHtml, persianHtml] = await Promise.all([
|
||||
englishResponse.text(),
|
||||
persianResponse.text(),
|
||||
]);
|
||||
const englishHtml = await englishResponse.text();
|
||||
assert.match(englishHtml, /<html[^>]*lang="en"[^>]*dir="ltr"/i);
|
||||
assert.match(englishHtml, /href="\/fa"/i);
|
||||
assert.match(englishHtml, /hreflang="fa"/i);
|
||||
assert.match(englishHtml, />Software Engineer</);
|
||||
assert.doesNotMatch(englishHtml, /id="site-loader"/);
|
||||
assert.match(persianHtml, /<html[^>]*lang="fa"[^>]*dir="rtl"/i);
|
||||
assert.match(persianHtml, /سلام، من امیرحسین خلیلی هستم/);
|
||||
|
||||
const projectIds = [
|
||||
'qlockify',
|
||||
'guilan-ace',
|
||||
'zarinpal',
|
||||
'iran-implant',
|
||||
'interanet-solutions',
|
||||
'postgresql-job-queue',
|
||||
'subsource',
|
||||
];
|
||||
const projectRoutes = projectIds.flatMap((id) => [`/projects/${id}`, `/fa/projects/${id}`]);
|
||||
const projectResponses = await Promise.all(projectRoutes.map((route) => fetch(`${origin}${route}`)));
|
||||
for (const response of projectResponses) assert.equal(response.status, 200);
|
||||
const projectHtml = await Promise.all(projectResponses.map((response) => response.text()));
|
||||
for (let index = 0; index < projectHtml.length; index += 1) {
|
||||
assert.match(projectHtml[index], /<dialog[^>]*aria-labelledby="case-study-title"/i);
|
||||
assert.match(projectHtml[index], /id="case-study-title"/i);
|
||||
assert.match(projectHtml[index], /Qlockify|Guilan|زرین|Implant|ایمپلنت|Interanet|اینترانت|PostgreSQL|Subsource|سابسورس/i);
|
||||
assert.match(projectHtml[index], index % 2 === 0 ? /<html[^>]*dir="ltr"/i : /<html[^>]*dir="rtl"/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);
|
||||
assert.equal((await fetch(`${origin}/fa/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 optimized = await fetch(
|
||||
`${origin}/_next/image?url=%2Fimages%2Favatar.png&w=256&q=75`,
|
||||
{ headers: { Accept: 'image/webp' } },
|
||||
);
|
||||
assert.equal(optimized.status, 200);
|
||||
assert.match(
|
||||
optimized.headers.get('content-type') ?? '',
|
||||
/^image\/(?:webp|png)$/,
|
||||
'expected WebP output or Next.js PNG fallback on unsupported CPUs',
|
||||
);
|
||||
assert.match(optimized.headers.get('cache-control') ?? '', /max-age=/);
|
||||
assert.ok((await optimized.arrayBuffer()).byteLength > 0);
|
||||
});
|
||||
|
||||
test('Persian source copy uses standard characters and punctuation', async () => {
|
||||
const localizedFiles = [
|
||||
'src/i18n/content.ts',
|
||||
'src/data/projects.ts',
|
||||
'src/data/experience.ts',
|
||||
'src/data/education.ts',
|
||||
'src/data/milestones.ts',
|
||||
];
|
||||
const source = (
|
||||
await Promise.all(localizedFiles.map((file) => readFile(file, 'utf8')))
|
||||
).join('\n');
|
||||
|
||||
assert.doesNotMatch(source, /[يك]/, 'use Persian ی and ک instead of Arabic forms');
|
||||
assert.doesNotMatch(source, /[—–]/, 'use Persian punctuation instead of em/en dashes');
|
||||
const placeholder = await fetch(`${origin}/images/portfolio-placeholder.svg`);
|
||||
assert.equal(placeholder.status, 200);
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user