import { describe, test, expect } from 'bun:test' // Dynamic import — module may not exist yet (TDD) let buildSessionCookies: | (( accessToken: string, refreshToken: string, options?: { secret?: string; secure?: boolean }, ) => string[]) | undefined try { const mod = await import('../auth/cookie') buildSessionCookies = mod.buildSessionCookies } catch { // Module not implemented yet — tests will fail on assertions } describe('buildSessionCookies', () => { test('access token cookie has HttpOnly, Secure, SameSite=Strict, Path=/', () => { expect(buildSessionCookies).toBeDefined() const cookies = buildSessionCookies!( 'rct_access_token_value', 'rct_refresh_token_value', { secret: 'cookie-secret', secure: true }, ) expect(Array.isArray(cookies)).toBe(true) expect(cookies.length).toBeGreaterThanOrEqual(2) // Find the access token cookie const accessCookie = cookies.find( c => c.includes('rct_access_token_value') || c.toLowerCase().includes('access'), ) expect(accessCookie).toBeDefined() expect(accessCookie!.toLowerCase()).toContain('httponly') expect(accessCookie!.toLowerCase()).toContain('secure') expect(accessCookie!.toLowerCase()).toContain('samesite=strict') expect(accessCookie!.toLowerCase()).toContain('path=/') }) test('refresh token cookie has longer Max-Age than access token', () => { expect(buildSessionCookies).toBeDefined() const cookies = buildSessionCookies!( 'rct_access_token_value', 'rct_refresh_token_value', { secret: 'cookie-secret', secure: true }, ) // Extract Max-Age from each cookie function extractMaxAge(cookie: string): number { const match = cookie.match(/max-age=(\d+)/i) return match ? parseInt(match[1], 10) : 0 } // We expect at least 2 cookies: access + refresh // The refresh cookie should have a larger Max-Age const maxAges = cookies.map(extractMaxAge).filter(m => m > 0) expect(maxAges.length).toBeGreaterThanOrEqual(2) const sorted = [...maxAges].sort((a, b) => a - b) // Access token max-age should be less than refresh token max-age expect(sorted[0]).toBeLessThan(sorted[sorted.length - 1]) }) test('development mode (non-HTTPS) sets Secure=false', () => { expect(buildSessionCookies).toBeDefined() const cookies = buildSessionCookies!( 'rct_access_token_value', 'rct_refresh_token_value', { secret: 'cookie-secret', secure: false }, ) // In dev mode, cookies should NOT have the Secure flag for (const cookie of cookies) { // Check that "Secure" is not present as a flag // Note: "Secure" could appear in the cookie name or value, // so we check for it as a standalone attribute const parts = cookie.split(';').map(p => p.trim().toLowerCase()) const hasSecure = parts.some(p => p === 'secure') expect(hasSecure).toBe(false) } }) })