95 lines
4.8 KiB
TypeScript
95 lines
4.8 KiB
TypeScript
import { readFile } from 'node:fs/promises';
|
|
import { describe, expect, it } from 'vitest';
|
|
import { validateProductionInputs } from '@/content/schemas';
|
|
|
|
const repositoryRoot = process.cwd();
|
|
const readJson = async (relativePath: string): Promise<unknown> =>
|
|
JSON.parse(await readFile(`${repositoryRoot}/${relativePath}`, 'utf8')) as unknown;
|
|
|
|
describe('approved public portfolio projection', () => {
|
|
it('contains approved identity and balanced evidence without prohibited surfaces', async () => {
|
|
const { content, manifest, site } = validateProductionInputs(
|
|
await readJson('content/public/portfolio-content.json'),
|
|
await readJson('content/public/asset-manifest.json'),
|
|
await readJson('config/site.preview.json'),
|
|
new URL('file:///prepared-assets/'),
|
|
);
|
|
|
|
expect(content.identity).toEqual(expect.objectContaining({
|
|
name: 'Luca Pîslaru',
|
|
role: 'System Administrator & Full-Stack Developer',
|
|
}));
|
|
expect(content.systemsOperations.title).toBe('Professional systems operations');
|
|
expect(content.infrastructure.title).toBe('Secure self-hosted platform and lifecycle');
|
|
expect(content.projects.selected).toHaveLength(3);
|
|
expect(content.projects.selected.filter((project) => project.visibility === 'private')
|
|
.every((project) => project.url === undefined)).toBe(true);
|
|
expect(content.projects.selected.find((project) => project.visibility === 'private')?.title)
|
|
.toBe('Private self-hosted medication tracker');
|
|
expect(content.projects.additional.find((project) => project.id === 'private-game-prototype')?.title)
|
|
.toBe('Private game prototype');
|
|
expect(content.toolkit.flatMap((group) => group.technologies).map((technology) => technology.name))
|
|
.toEqual(expect.arrayContaining(['Linux', 'Docker', 'Python', 'Vue.js', 'Java']));
|
|
expect(content.contact).toEqual(expect.objectContaining({ email: 'luca.pislaru@gmail.com' }));
|
|
expect(content.contact.social.map((link) => link.url)).toEqual([
|
|
'https://github.com/LucaPisl',
|
|
'https://gitlab.com/luca_pisl',
|
|
'https://linkedin.com/in/luca-pisl',
|
|
]);
|
|
const publishedReferences = [
|
|
...content.projects.selected.flatMap((project) => project.assetIds),
|
|
...content.projects.additional.flatMap((project) => project.assetIds),
|
|
...content.toolkit.flatMap((group) => group.technologies.flatMap((technology) =>
|
|
technology.assetId === undefined ? [] : [technology.assetId])),
|
|
...(content.metadata.socialPreviewAssetId === undefined ? [] : [content.metadata.socialPreviewAssetId]),
|
|
...(content.soundtrack === undefined ? [] : [
|
|
content.soundtrack.intro.opusAssetId,
|
|
content.soundtrack.intro.mp3AssetId,
|
|
content.soundtrack.main.opusAssetId,
|
|
content.soundtrack.main.mp3AssetId,
|
|
content.soundtrack.afterglow.opusAssetId,
|
|
content.soundtrack.afterglow.mp3AssetId,
|
|
content.soundtrack.driveLift.opusAssetId,
|
|
content.soundtrack.driveLift.mp3AssetId,
|
|
]),
|
|
];
|
|
expect([...publishedReferences].sort()).toEqual(manifest.assets.map((asset) => asset.id).sort());
|
|
expect(site).toEqual({
|
|
environment: 'preview',
|
|
canonicalUrl: 'https://portfolio.localhost/',
|
|
buildId: 'preview-semantic-v1',
|
|
});
|
|
expect(JSON.stringify(content)).not.toMatch(/Arch Linux|CV download|heatmap|expert|percent/i);
|
|
});
|
|
|
|
it('publishes only the four verified owner repositories and no private project links', async () => {
|
|
const { content } = validateProductionInputs(
|
|
await readJson('content/public/portfolio-content.json'),
|
|
await readJson('content/public/asset-manifest.json'),
|
|
await readJson('config/site.preview.json'),
|
|
new URL('file:///prepared-assets/'),
|
|
);
|
|
const expected = new Map([
|
|
['footy-tracker', 'https://github.com/LucaPisl/footy-tracker'],
|
|
['opinion-dynamics-simulation', 'https://github.com/LucaPisl/opinion-dynamics-simulation'],
|
|
['currency-converter', 'https://github.com/LucaPisl/CurrencyConverterAvalonia'],
|
|
['linux-modding-guide', 'https://github.com/LucaPisl/LinuxModdingGuide'],
|
|
]);
|
|
const projects = [...content.projects.selected, ...content.projects.additional];
|
|
|
|
expect(new Map(projects.flatMap((project) => project.url === undefined ? [] : [[project.id, project.url]]))).toEqual(expected);
|
|
for (const project of projects) {
|
|
if (project.visibility === 'private') expect(project.url).toBeUndefined();
|
|
if (project.url !== undefined) {
|
|
const url = new URL(project.url);
|
|
expect(url.protocol).toBe('https:');
|
|
expect(url.hostname).toBe('github.com');
|
|
expect(url.pathname.startsWith('/LucaPisl/')).toBe(true);
|
|
expect(url.search).toBe('');
|
|
expect(url.hash).toBe('');
|
|
}
|
|
}
|
|
expect(JSON.stringify(content)).not.toContain('CurrencyConverterAvaloniaProject');
|
|
});
|
|
});
|