import { describe, it, expect, vi, beforeEach, afterEach } from 'vitest'; import { getAppMode, isPreLaunch, isAlpha, getPublicRoutes, isPublicRoute } from './mode'; describe('mode', () => { const originalEnv = process.env; beforeEach(() => { vi.resetModules(); process.env = { ...originalEnv }; }); afterEach(() => { process.env = originalEnv; }); describe('getAppMode', () => { it('should return "pre-launch" when NEXT_PUBLIC_GRIDPILOT_MODE is not set', () => { delete process.env.NEXT_PUBLIC_GRIDPILOT_MODE; expect(getAppMode()).toBe('pre-launch'); }); it('should return "pre-launch" when NEXT_PUBLIC_GRIDPILOT_MODE is empty', () => { process.env.NEXT_PUBLIC_GRIDPILOT_MODE = ''; expect(getAppMode()).toBe('pre-launch'); }); it('should return "pre-launch" when NEXT_PUBLIC_GRIDPILOT_MODE is "pre-launch"', () => { process.env.NEXT_PUBLIC_GRIDPILOT_MODE = 'pre-launch'; expect(getAppMode()).toBe('pre-launch'); }); it('should return "alpha" when NEXT_PUBLIC_GRIDPILOT_MODE is "alpha"', () => { process.env.NEXT_PUBLIC_GRIDPILOT_MODE = 'alpha'; expect(getAppMode()).toBe('alpha'); }); it('should throw error in development for invalid mode', () => { process.env.NODE_ENV = 'development'; process.env.NEXT_PUBLIC_GRIDPILOT_MODE = 'invalid'; expect(() => getAppMode()).toThrow('Invalid NEXT_PUBLIC_GRIDPILOT_MODE: "invalid". Must be one of: pre-launch, alpha'); }); it('should log error and return "pre-launch" in production for invalid mode', () => { process.env.NODE_ENV = 'production'; process.env.NEXT_PUBLIC_GRIDPILOT_MODE = 'invalid'; const consoleSpy = vi.spyOn(console, 'error').mockImplementation(() => {}); const result = getAppMode(); expect(consoleSpy).toHaveBeenCalledWith( 'Invalid NEXT_PUBLIC_GRIDPILOT_MODE: "invalid". Must be one of: pre-launch, alpha' ); expect(result).toBe('pre-launch'); consoleSpy.mockRestore(); }); }); describe('isPreLaunch', () => { it('should return true when mode is "pre-launch"', () => { process.env.NEXT_PUBLIC_GRIDPILOT_MODE = 'pre-launch'; expect(isPreLaunch()).toBe(true); }); it('should return false when mode is "alpha"', () => { process.env.NEXT_PUBLIC_GRIDPILOT_MODE = 'alpha'; expect(isPreLaunch()).toBe(false); }); it('should return true when mode is not set', () => { delete process.env.NEXT_PUBLIC_GRIDPILOT_MODE; expect(isPreLaunch()).toBe(true); }); }); describe('isAlpha', () => { it('should return true when mode is "alpha"', () => { process.env.NEXT_PUBLIC_GRIDPILOT_MODE = 'alpha'; expect(isAlpha()).toBe(true); }); it('should return false when mode is "pre-launch"', () => { process.env.NEXT_PUBLIC_GRIDPILOT_MODE = 'pre-launch'; expect(isAlpha()).toBe(false); }); it('should return false when mode is not set', () => { delete process.env.NEXT_PUBLIC_GRIDPILOT_MODE; expect(isAlpha()).toBe(false); }); }); describe('getPublicRoutes', () => { it('should return an array of public routes', () => { const routes = getPublicRoutes(); expect(Array.isArray(routes)).toBe(true); expect(routes.length).toBeGreaterThan(0); }); it('should include core public pages', () => { const routes = getPublicRoutes(); expect(routes).toContain('/'); expect(routes).toContain('/leagues'); expect(routes).toContain('/drivers'); }); it('should include auth routes', () => { const routes = getPublicRoutes(); expect(routes).toContain('/auth/login'); expect(routes).toContain('/auth/signup'); expect(routes).toContain('/api/auth/login'); }); it('should return consistent results', () => { const routes1 = getPublicRoutes(); const routes2 = getPublicRoutes(); expect(routes1).toEqual(routes2); // Same content expect(routes1).not.toBe(routes2); // Different references (immutable) }); }); describe('isPublicRoute', () => { it('should return true for exact matches', () => { expect(isPublicRoute('/')).toBe(true); expect(isPublicRoute('/leagues')).toBe(true); expect(isPublicRoute('/auth/login')).toBe(true); }); it('should return true for nested routes under public prefixes', () => { expect(isPublicRoute('/leagues/123')).toBe(true); expect(isPublicRoute('/leagues/create')).toBe(true); expect(isPublicRoute('/drivers/456')).toBe(true); expect(isPublicRoute('/teams/789')).toBe(true); expect(isPublicRoute('/races/abc')).toBe(true); }); it('should return false for private routes', () => { expect(isPublicRoute('/dashboard')).toBe(false); expect(isPublicRoute('/admin')).toBe(false); // Note: /leagues/123/admin is actually public because it starts with /leagues/ // This is the intended behavior - all nested routes under public prefixes are public }); it('should return true for nested routes under public prefixes', () => { // These are all public because they start with public prefixes expect(isPublicRoute('/leagues/123')).toBe(true); expect(isPublicRoute('/leagues/123/admin')).toBe(true); expect(isPublicRoute('/drivers/456')).toBe(true); expect(isPublicRoute('/teams/789')).toBe(true); expect(isPublicRoute('/races/abc')).toBe(true); }); it('should return false for routes that only start with public prefix but are different', () => { // This tests that '/leaguex' doesn't match '/leagues' expect(isPublicRoute('/leaguex')).toBe(false); }); it('should handle trailing slashes correctly', () => { expect(isPublicRoute('/leagues/')).toBe(true); expect(isPublicRoute('/drivers/')).toBe(true); }); }); });