import { readFileSync } from 'node:fs';
import { describe, expect, it } from 'vitest';
import type { FindingRecord } from '../../src/domain/finding';
import type { EnvironmentSnapshot } from '../../src/domain/environment-context';
import { dashboardCisCatSeverityRemainder, dashboardDomainInformation, dashboardEnvironmentSummary, dashboardExplicitIoeCount, dashboardExplicitIoeRecordIds, dashboardOverallScore, dashboardPingCastleRiskCategories, dashboardRiskTools, dashboardScanSourceLabel } from '../../src/features/dashboard/DashboardPanel';
import { securityDomainCatalog } from '../../src/features/dashboard/security-domains';
const component = readFileSync(new URL('../../src/features/dashboard/DashboardPanel.tsx', import.meta.url), 'utf8');
const styles = readFileSync(new URL('../../src/styles/datahub.css', import.meta.url), 'utf8');
describe('dashboard reference layout', () => {
it('uses the requested summary-to-action client information hierarchy', () => {
expect(component).toContain('className="client-overview-header"');
expect(component).toContain('');
expect(component.match(/Data');
expect(component).toContain('Domain Information');
expect(component).toContain('Assessment Gaps');
expect(component).toContain('Source Overview');
expect(component).toContain(' jump(() => setPathFindingIds([recordId]))} />');
expect(styles).toMatch(/\.dashboard-page\s*\{[^}]*container-type:\s*inline-size;/s);
expect(component).toContain('className={`client-posture tone-${overallTone}`}');
expect(styles).toMatch(/\.dashboard-page\.client-command-center\s*\{[^}]*--client-info-surface-raised:\s*var\(--tile-surface\);[^}]*background:\s*var\(--surface-app\);/s);
expect(component).not.toContain('className="client-overview-facts"');
expect(component).toContain('className="client-data-facts"');
expect(styles).not.toContain('.client-overview-fact');
expect(styles).toMatch(/\.client-data-facts\s*\{[^}]*grid-template-columns:\s*repeat\(3, minmax\(0, 1fr\)\);/s);
expect(styles).toMatch(/\.client-data-fact\s*\{[^}]*background:\s*transparent;/s);
expect(styles).toMatch(/\.client-overview-main\s*\{[^}]*grid-template-columns:\s*repeat\(2, minmax\(0, 1fr\)\);[^}]*align-items:\s*stretch;/s);
expect(styles).toMatch(/\.client-priority\s*\{[^}]*grid-template-columns:\s*repeat\(2, minmax\(0, 1fr\)\);[^}]*grid-template-rows:\s*auto minmax\(0, 1fr\);[^}]*align-content:\s*stretch;[^}]*align-items:\s*stretch;/s);
expect(styles).toMatch(/\.client-assessment-gaps\s*\{[^}]*grid-column:\s*1 \/ -1;/s);
expect(styles).toMatch(/@container \(max-width: 760px\)[\s\S]*?\.client-priority\s*\{[^}]*grid-template-columns:\s*1fr;[^}]*grid-template-rows:\s*none;/s);
expect(styles).toMatch(/\.client-posture\s*\{[^}]*grid-template-columns:\s*minmax\(300px, \.82fr\) minmax\(430px, 1\.18fr\);/s);
expect(styles).toMatch(/\.client-risk-register-layout\s*\{[^}]*grid-template-columns:\s*clamp\(420px, 27vw, 520px\) minmax\(0, 1fr\);[^}]*height:\s*calc\(var\(--tile-content-min-height\) \* 2\.5\);/s);
expect(styles).toMatch(/\.client-risk-register-navigation\s*\{[^}]*border-right:\s*var\(--bw-hairline\) solid var\(--border-default\);/s);
expect(styles).toMatch(/\.client-risk-register-information\s*\{[^}]*padding:\s*var\(--space-5\) var\(--space-6\);[^}]*overflow-y:\s*auto;/s);
expect(styles).toMatch(/\.client-risk-register-list button\[aria-pressed="true"\]\s*\{[^}]*box-shadow:\s*inset var\(--marker-width\) 0 0 var\(--marking-color\);/s);
expect(component).toContain('onOpenFinding={recordId => jump(() => setPathFindingIds([recordId]))}');
});
it('keeps source-balanced score, coverage and critical guardrail separate', () => {
expect(dashboardOverallScore([{ score: 90 }, { score: 30 }, { score: undefined }])).toBe(60);
expect(dashboardOverallScore([{ score: undefined }])).toBeUndefined();
expect(component).toContain(' jump(() => undefined, false)} />');
expect(component).toContain('Assessment Coverage');
expect(component).not.toContain('className="client-overall-status');
expect(component).not.toContain('className="client-overall-critical"');
expect(component).not.toContain('className="client-overall-secondary"');
expect(component).not.toContain('Lowest domain pass rate');
expect(component).toContain('dashboardOverallScore(sourceScores)');
expect(component).toContain("name: 'PingCastle'");
expect(component).toContain("name: 'GPO Analysis'");
expect(component).toContain("className=\"client-posture-connectors\"");
expect(styles).toMatch(/\.client-overall-coverage\s*\{[^}]*width:\s*min\(70%, var\(--tile-content-width\)\);/s);
expect(component).not.toContain('Design concept');
expect(component).not.toContain('Illustrative data');
});
it('shows eight evidence-backed security domains and all available sources', () => {
expect(securityDomainCatalog.map(domain => domain.label)).toEqual([
'Identity & Account Hygiene', 'Privilege & Attack Paths', 'Authentication & Access', 'AD Infrastructure & PKI',
'System Hardening', 'GPO & Baseline', 'Cloud & Applications', 'Monitoring & Recovery'
]);
expect(component).toContain('orderedSourceScores.map');
expect(component).toContain('nativePingCastleRisk');
expect(component).toContain('dashboardEnvironmentTableNumber');
expect(component).not.toContain('className="client-source-overview"');
expect(component).toContain('className="client-environment-sources"');
expect(styles).toMatch(/\.client-environment-sources ul\s*\{[^}]*list-style:\s*none;/s);
expect(styles).toMatch(/\.client-environment-sources li > button\s*\{[^}]*cursor:\s*pointer;/s);
expect(styles).not.toContain('.client-source-overview');
expect(component).toContain('