import { afterEach, describe, expect, it, vi } from 'vitest'; import { buildAuthHandoffUrl } from './api'; afterEach(() => { vi.unstubAllEnvs(); vi.resetModules(); }); describe('auth URL handling', () => { it('builds auth portal URLs when configured portal host has no scheme', async () => { vi.stubEnv('NEXT_PUBLIC_AUTH_PORTAL_URL', 'auth.example.com'); const { buildAuthPortalUrl } = await import('./auth-portal'); expect(buildAuthPortalUrl('/login', '/mcp')).toBe('http://auth.example.com/login?next=%2Fmcp'); }); it('builds a handoff URL when backend returns a hostname without scheme', () => { const url = buildAuthHandoffUrl({ access_token: 'token', refresh_token: '', token_type: 'bearer', user_id: 'u1', username: 'u1', role: 'owner', handoff_code: 'handoff-1', backend_connection: { frontend_base_url: 'workspace.example.com:8088', }, }, '/mcp'); expect(url).toBe('http://workspace.example.com:8088/handoff?code=handoff-1&next=%2Fmcp'); }); it('rejects malformed handoff base URLs instead of throwing URL constructor errors', () => { const url = buildAuthHandoffUrl({ access_token: 'token', refresh_token: '', token_type: 'bearer', user_id: 'u1', username: 'u1', role: 'owner', handoff_code: 'handoff-1', backend_connection: { frontend_base_url: 'http://', }, }, '/mcp'); expect(url).toBeNull(); }); });