/** * classify-access.test — the PURE access-verdict classifier extracted from the * Playwright driver (C1). A generated-route denial has no single in-page signal, * so this must also treat a redirect AWAY from the requested path as a denial. */ import { describe, it, expect } from 'vitest'; import { classifyAccessState } from '../playwright-driver.js'; describe('classifyAccessState', () => { it('reports redirect_login when the SPA bounced to /login', () => { expect(classifyAccessState({ path: '/login', denied: false, overlay: false }, '/hr/employees')).toBe( 'redirect_login', ); }); it('reports error on a dev-server overlay', () => { expect(classifyAccessState({ path: '/hr/employees', denied: true, overlay: true }, '/hr/employees')).toBe('error'); }); it('reports denied on a permission marker / denial text', () => { expect(classifyAccessState({ path: '/hr/employees', denied: true, overlay: false }, '/hr/employees')).toBe( 'denied', ); }); it('reports denied when redirected AWAY from the requested route (no in-page marker)', () => { // The platform sends a module/section denial to /applications — a blank/redirected page. expect(classifyAccessState({ path: '/applications', denied: false, overlay: false }, '/hr/employees')).toBe( 'denied', ); }); it('reports allowed when the requested route (or a child of it) rendered', () => { expect(classifyAccessState({ path: '/hr/employees', denied: false, overlay: false }, '/hr/employees')).toBe( 'allowed', ); // A module home that lands on its first child is still "at or under" the request. expect(classifyAccessState({ path: '/hr/employees', denied: false, overlay: false }, '/hr')).toBe('allowed'); }); it('never false-flags a dynamic destination (requestedPath = null, e.g. click_row detail)', () => { expect(classifyAccessState({ path: '/hr/employees/abc-123', denied: false, overlay: false }, null)).toBe( 'allowed', ); }); });