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('