fix: bind section labels by canonical id
This commit is contained in:
@@ -3,6 +3,7 @@ import { resolve } from 'node:path';
|
||||
import { describe, expect, it } from 'vitest';
|
||||
import { validateProductionInputs } from '@/content/schemas';
|
||||
import { render } from '@/entry-server';
|
||||
import type { SectionId } from '@/content/types';
|
||||
|
||||
const fixture = (name: string): unknown =>
|
||||
JSON.parse(readFileSync(resolve(process.cwd(), 'tests/fixtures', name), 'utf8'));
|
||||
@@ -15,8 +16,12 @@ const validInputs = validateProductionInputs(
|
||||
);
|
||||
|
||||
const renderedDocument = async (): Promise<Document> => {
|
||||
return renderedDocumentFor(validInputs);
|
||||
};
|
||||
|
||||
const renderedDocumentFor = async (inputs: typeof validInputs): Promise<Document> => {
|
||||
const document = globalThis.document.implementation.createHTMLDocument('Portfolio');
|
||||
document.body.innerHTML = await render('/', validInputs);
|
||||
document.body.innerHTML = await render('/', inputs);
|
||||
return document;
|
||||
};
|
||||
|
||||
@@ -52,6 +57,33 @@ describe('semantic portfolio document', () => {
|
||||
expect(document.body.textContent).toContain('For a current CV or role-specific information, contact me directly.');
|
||||
});
|
||||
|
||||
it('binds navigation and section labels to their canonical IDs when content navigation is reordered', async () => {
|
||||
const content = fixture('portfolio-content.valid.json') as {
|
||||
navigation: Array<{ id: SectionId; label: string }>;
|
||||
};
|
||||
const navigationById = new Map(content.navigation.map((item) => [item.id, item]));
|
||||
const reorderedIds: readonly SectionId[] = [
|
||||
'contact', 'toolkit', 'additional-work', 'selected-builds', 'infrastructure', 'experience', 'profile', 'start',
|
||||
];
|
||||
content.navigation = reorderedIds.map((id) => navigationById.get(id)!);
|
||||
const reorderedInputs = validateProductionInputs(
|
||||
content,
|
||||
fixture('asset-manifest.valid.json'),
|
||||
fixture('site-config.preview.json'),
|
||||
new URL('file:///prepared-assets/'),
|
||||
);
|
||||
|
||||
const document = await renderedDocumentFor(reorderedInputs);
|
||||
|
||||
expect([...document.querySelectorAll('main > section > h2')].map((heading) => heading.textContent)).toEqual([
|
||||
'START', 'PROFILE', 'EXPERIENCE', 'INFRASTRUCTURE', 'SELECTED BUILDS', 'ADDITIONAL WORK', 'TOOLKIT', 'CONTACT',
|
||||
]);
|
||||
expect([...document.querySelectorAll('nav a')].map((link) => [link.getAttribute('href'), link.textContent])).toEqual([
|
||||
['#start', 'Start'], ['#profile', 'Profile'], ['#experience', 'Experience'], ['#infrastructure', 'Infrastructure'],
|
||||
['#selected-builds', 'Selected builds'], ['#additional-work', 'Additional work'], ['#toolkit', 'Toolkit'], ['#contact', 'Contact'],
|
||||
]);
|
||||
});
|
||||
|
||||
it('includes systems and software evidence in server-rendered content', async () => {
|
||||
const document = await renderedDocument();
|
||||
|
||||
|
||||
Reference in New Issue
Block a user