/** * @vitest-environment node */ import { createMockRequest } from '@sim/testing' import { beforeEach, describe, expect, it, vi } from 'vitest' const handlerMocks = vi.hoisted(() => ({ betterAuthGET: vi.fn(), betterAuthPOST: vi.fn(), ensureAnonymousUserExists: vi.fn(), createAnonymousSession: vi.fn(() => ({ user: { id: 'anon' }, session: { id: 'anon-session' }, })), isAuthDisabled: false, })) vi.mock('better-auth/next-js', () => ({ toNextJsHandler: () => ({ GET: handlerMocks.betterAuthGET, POST: handlerMocks.betterAuthPOST, }), })) vi.mock('@/lib/auth', () => ({ auth: { handler: {} }, })) vi.mock('@/lib/auth/anonymous', () => ({ ensureAnonymousUserExists: handlerMocks.ensureAnonymousUserExists, createAnonymousSession: handlerMocks.createAnonymousSession, })) vi.mock('@/lib/core/config/env-flags', () => ({ get isAuthDisabled() { return handlerMocks.isAuthDisabled }, })) import { GET, POST } from '@/app/api/auth/[...all]/route' describe('auth catch-all route (DISABLE_AUTH get-session)', () => { beforeEach(() => { vi.clearAllMocks() handlerMocks.isAuthDisabled = false }) it('returns anonymous session in better-auth response envelope when auth is disabled', async () => { handlerMocks.isAuthDisabled = true const req = createMockRequest( 'GET', undefined, {}, 'http://localhost:3000/api/auth/get-session' ) const res = await GET(req as any) const json = await res.json() expect(handlerMocks.ensureAnonymousUserExists).toHaveBeenCalledTimes(1) expect(handlerMocks.betterAuthGET).not.toHaveBeenCalled() expect(json).toEqual({ user: { id: 'anon' }, session: { id: 'anon-session' }, }) }) it('delegates to better-auth handler when auth is enabled', async () => { handlerMocks.isAuthDisabled = false const { NextResponse } = await import('next/server') handlerMocks.betterAuthGET.mockResolvedValueOnce( new NextResponse(JSON.stringify({ data: { ok: true } }), { headers: { 'content-type': 'application/json' }, }) as any ) const req = createMockRequest( 'GET', undefined, {}, 'http://localhost:3000/api/auth/get-session' ) const res = await GET(req as any) const json = await res.json() expect(handlerMocks.ensureAnonymousUserExists).not.toHaveBeenCalled() expect(handlerMocks.betterAuthGET).toHaveBeenCalledTimes(1) expect(json).toEqual({ data: { ok: true } }) }) }) describe('auth catch-all route organization mutations', () => { beforeEach(() => { vi.clearAllMocks() }) it('blocks Better Auth organization mutation endpoints that bypass app lifecycle rules', async () => { const req = createMockRequest( 'POST', undefined, {}, 'http://localhost:3000/api/auth/organization/create' ) const res = await POST(req as any) const json = await res.json() expect(res.status).toBe(404) expect(handlerMocks.betterAuthPOST).not.toHaveBeenCalled() expect(json).toEqual({ error: 'Organization mutations are handled by application API routes.', }) }) it('allows safe Better Auth organization session endpoints', async () => { const { NextResponse } = await import('next/server') handlerMocks.betterAuthPOST.mockResolvedValueOnce( new NextResponse(JSON.stringify({ data: { ok: true } }), { headers: { 'content-type': 'application/json' }, }) as any ) const req = createMockRequest( 'POST', undefined, {}, 'http://localhost:3000/api/auth/organization/set-active' ) const res = await POST(req as any) const json = await res.json() expect(handlerMocks.betterAuthPOST).toHaveBeenCalledTimes(1) expect(json).toEqual({ data: { ok: true } }) }) })