import { describe, expect, test } from 'vitest'; import { isPublicRoute } from './publicRoutes'; describe('isPublicRoute', () => { test('/login is public — login form must render to unauthenticated visitors', () => { expect(isPublicRoute('/login')).toBe(true); }); // Regression guard for #376: /register was previously bounced to /login // by the layout guard, breaking bootstrap-admin self-registration on // fresh deployments. Do NOT remove /register from the public set unless // you have a deliberate replacement (e.g. invite-only landing page). test('/register is public — bootstrap admin must reach the form', () => { expect(isPublicRoute('/register')).toBe(true); }); test('/ is gated', () => { expect(isPublicRoute('/')).toBe(false); }); test('/admin/users is gated', () => { expect(isPublicRoute('/admin/users')).toBe(false); }); test('/settings is gated', () => { expect(isPublicRoute('/settings')).toBe(false); }); test('paths that merely start with /login are not public', () => { expect(isPublicRoute('/login/extra')).toBe(false); expect(isPublicRoute('/loginx')).toBe(false); }); // Regression guard for drift #558: /forgot-password and the // /reset-password/ deep links must be reachable without a // session — the reset flow is entered by clicking an email link // while signed out, so the auth gate redirecting to /login broke // account recovery. test('/forgot-password is public', () => { expect(isPublicRoute('/forgot-password')).toBe(true); }); test('/reset-password/ is public', () => { expect(isPublicRoute('/reset-password/abc-123')).toBe(true); expect(isPublicRoute('/reset-password/')).toBe(true); }); test('/reset-password (no trailing slash) is NOT public — only the token sub-path', () => { expect(isPublicRoute('/reset-password')).toBe(false); }); });