Assessor_2.0/tests/features/datahub-topbar-context.test.ts

46 lines
3.2 KiB
TypeScript

import { readFileSync } from 'node:fs';
import { describe, expect, it } from 'vitest';
const app = readFileSync(new URL('../../src/app/App.tsx', import.meta.url), 'utf8');
const datahub = readFileSync(new URL('../../src/features/project-import/DataHub.tsx', import.meta.url), 'utf8');
const layout = readFileSync(new URL('../../src/styles/layout.css', import.meta.url), 'utf8');
describe('Datahub topbar context', () => {
it('labels the overview Data Hub and an opened detail Client', () => {
expect(app).toContain("'data-hub': 'Data Hub'");
expect(app).toContain("activeArea === 'data-hub' && dataHubClientView ? 'Client' : AREA_TOPBAR_TITLE[activeArea]");
expect(app).toContain('onDetailViewChanged={handleDataHubDetailViewChanged}');
expect(datahub).toContain("onDetailViewChanged?.(form !== null, form?.mode === 'edit' ? form.name.trim() || form.project?.name : undefined)");
expect(datahub).toContain('useEffect(() => () => onDetailViewChanged?.(false), [onDetailViewChanged])');
});
it('labels the graph area consistently as Pathfinder', () => {
expect(app).toContain("graph: 'Pathfinder'");
expect(app).toContain("['graph', 'Pathfinder']");
expect(app).not.toContain("graph: 'MITRE Attack Paths'");
expect(app).not.toContain("['graph', 'Graph']");
});
it('shows the active client as unboxed right-aligned text in every area header', () => {
expect(app).toContain("const headerClientName = (activeArea === 'data-hub' && dataHubClientView ? dataHubDetailClientName : activeProjectName)?.trim();");
expect(app).toContain('const handleDataHubDetailViewChanged = useCallback((isDetailView: boolean, clientName?: string) =>');
expect(app.match(/className="app-header-client-name"/g)).toHaveLength(1);
expect(app).toContain('const headerContext = <div className="app-header-context">');
expect(app).toContain("headerClientName && activeArea !== 'dashboard'");
expect(app).toContain('<div className="work-header-row">');
expect(layout).toMatch(/\.app-header-panel:not\(\.app-header-panel-work\) \.app-header-context\s*\{[^}]*position:\s*absolute;[^}]*top:\s*3px;[^}]*right:\s*0;/s);
expect(layout).toMatch(/\.app-header-client-name\s*\{[^}]*margin-right:\s*16px;[^}]*font-size:\s*var\(--fs-xl\);[^}]*text-align:\s*right;[^}]*white-space:\s*nowrap;/s);
const clientNameRule = layout.match(/\.app-header-client-name\s*\{([^}]*)\}/)?.[1] ?? '';
expect(clientNameRule).not.toMatch(/(?:border|background)\s*:/);
});
it('shows the dashboard client beside its title with the active triangle marker', () => {
expect(app).toContain("const dashboardClientContext = activeArea === 'dashboard' && headerClientName");
expect(app).toContain('<span className="area-client-marker"><TriangleIcon direction="right" /></span>');
expect(app).toContain('<span className="area-client-name" title={headerClientName}>{headerClientName}</span>');
expect(app).toContain('{dashboardClientContext}{activeArea === \'graph\' && <PathfinderFilterTrail />}');
expect(layout).toMatch(/\.area-client-marker\s*\{[^}]*color:\s*var\(--state-active\);/s);
expect(layout).toMatch(/\.area-client-name\s*\{[^}]*font-size:\s*var\(--type-h3-size\);[^}]*white-space:\s*nowrap;/s);
});
});