|
1 | 1 | import { redirect } from 'next/navigation' |
| 2 | +import { NextRequest } from 'next/server' |
2 | 3 | import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest' |
3 | 4 | import { AUTH_URLS, PROTECTED_URLS } from '@/configs/urls' |
4 | 5 | import { |
|
7 | 8 | signInWithOAuthAction, |
8 | 9 | signUpAction, |
9 | 10 | } from '@/core/server/actions/auth-actions' |
10 | | -import { authRouter } from '@/core/server/api/routers/auth' |
11 | | -import { createCallerFactory, createTRPCContext } from '@/core/server/trpc/init' |
12 | 11 | import { encodedRedirect } from '@/lib/utils/auth' |
13 | 12 |
|
14 | 13 | // Create hoisted mock functions that can be used throughout the file |
@@ -513,48 +512,26 @@ describe('Auth Actions - Integration Tests', () => { |
513 | 512 | }) |
514 | 513 | }) |
515 | 514 |
|
516 | | - describe('Sign Out Flow (trpc auth.signOut)', () => { |
517 | | - const createCaller = createCallerFactory(authRouter) |
518 | | - |
519 | | - const getCaller = async () => |
520 | | - createCaller( |
521 | | - await createTRPCContext({ |
522 | | - headers: new Headers(), |
523 | | - requestUrl: 'http://localhost:3000/api/trpc', |
524 | | - }) |
525 | | - ) |
| 515 | + describe('Sign Out Flow (GET /api/auth/sign-out)', () => { |
| 516 | + const callSignOutRoute = async () => { |
| 517 | + const { GET } = await import('@/app/api/auth/sign-out/route') |
| 518 | + return GET(new NextRequest('https://app.e2b.dev/api/auth/sign-out')) |
| 519 | + } |
526 | 520 |
|
527 | 521 | /** |
528 | | - * AUTHENTICATION TEST: Verifies that sign-out returns the sign-in page url |
| 522 | + * AUTHENTICATION TEST: the plain (non-auth()-wrapped) route handler clears |
| 523 | + * the session via the provider and redirects to the sign-in page. Running |
| 524 | + * the cookie clear here — rather than inside the auth()-wrapped tRPC route — |
| 525 | + * is what keeps the deletion from being clobbered by a re-issued JWT cookie. |
529 | 526 | */ |
530 | | - it('should return sign-in page url on sign-out', async () => { |
531 | | - // Setup: Mock Supabase client to return successful sign-out |
532 | | - mockSupabaseClient.auth.signOut.mockResolvedValue({ |
533 | | - error: null, |
534 | | - }) |
535 | | - |
536 | | - // Execute and Verify: the mutation returns the URL for the client to hard-navigate to |
537 | | - const caller = await getCaller() |
538 | | - await expect(caller.signOut()).resolves.toEqual({ |
539 | | - url: AUTH_URLS.SIGN_IN, |
540 | | - }) |
541 | | - }) |
| 527 | + it('clears the session and redirects to the sign-in page', async () => { |
| 528 | + mockSupabaseClient.auth.signOut.mockResolvedValue({ error: null }) |
542 | 529 |
|
543 | | - /** |
544 | | - * AUTHENTICATION TEST: Verifies that sign-out returns the sign-in url with returnTo |
545 | | - */ |
546 | | - it('should return sign-in page url with returnTo parameter', async () => { |
547 | | - // Setup: Mock Supabase client to return successful sign-out |
548 | | - mockSupabaseClient.auth.signOut.mockResolvedValue({ |
549 | | - error: null, |
550 | | - }) |
| 530 | + const response = await callSignOutRoute() |
551 | 531 |
|
552 | | - // Execute and Verify: the mutation returns the URL for the client to hard-navigate to |
553 | | - const caller = await getCaller() |
554 | | - await expect(caller.signOut({ returnTo: '/dashboard' })).resolves.toEqual( |
555 | | - { |
556 | | - url: `${AUTH_URLS.SIGN_IN}?returnTo=${encodeURIComponent('/dashboard')}`, |
557 | | - } |
| 532 | + expect(mockSupabaseClient.auth.signOut).toHaveBeenCalled() |
| 533 | + expect(response.headers.get('location')).toBe( |
| 534 | + `https://app.e2b.dev${AUTH_URLS.SIGN_IN}` |
558 | 535 | ) |
559 | 536 | }) |
560 | 537 | }) |
|
0 commit comments