Files
gridpilot.gg/apps/website/lib/mode.test.ts
2026-01-01 22:46:59 +01:00

165 lines
5.8 KiB
TypeScript

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);
});
});
});