Ctrl K
ComunidadGuías…

lib/auth/__tests__/supabase-provider.test.ts

Rama main · réplica de lectura del repositorio original.

Archivo original ↗Preguntar a KiBot
import { NextRequest, NextResponse } from 'next/server'

import { beforeEach, describe, expect, it, vi } from 'vitest'

import { supabaseAuthProvider } from '@/lib/auth/providers/supabase'
import { createAuthActionClient } from '@/lib/supabase/server'

vi.mock('@/lib/supabase/server', () => ({
  createClient: vi.fn(),
  createAuthActionClient: vi.fn()
}))
vi.mock('@/lib/supabase/middleware', () => ({
  updateSession: vi.fn(),
  exchangeAuthCode: vi.fn()
}))
vi.mock('@/lib/supabase/keys', () => ({
  hasSupabasePublicConfig: vi.fn(() => true)
}))
vi.mock('next/headers', () => ({ headers: vi.fn() }))

import { headers } from 'next/headers'

import { exchangeAuthCode, updateSession } from '@/lib/supabase/middleware'

function request(url: string) {
  return new NextRequest(url)
}

describe('supabase provider', () => {
  const resetPasswordForEmail = vi.fn()

  beforeEach(() => {
    vi.clearAllMocks()
    vi.mocked(createAuthActionClient).mockResolvedValue({
      auth: { resetPasswordForEmail }
    } as never)
    vi.mocked(headers).mockResolvedValue(
      new Headers({ origin: 'http://localhost:3000' }) as never
    )
  })

  describe('requestPasswordReset', () => {
    it('keeps the legacy allowlisted recovery destination', async () => {
      resetPasswordForEmail.mockResolvedValue({ error: null })

      const result =
        await supabaseAuthProvider.requestPasswordReset!('user@example.com')

      expect(result).toEqual({ success: true })
      expect(resetPasswordForEmail).toHaveBeenCalledWith('user@example.com', {
        redirectTo: 'http://localhost:3000/auth/update-password'
      })
    })
  })

  describe('handleSession', () => {
    it('exchanges a recovery code arriving at update-password', async () => {
      const exchanged = NextResponse.redirect(
        'http://localhost:3000/auth/update-password'
      )
      vi.mocked(exchangeAuthCode).mockResolvedValue(exchanged)
      const req = request(
        'http://localhost:3000/auth/update-password?code=abc&state=xyz'
      )

      const response = await supabaseAuthProvider.handleSession!(req)

      expect(exchangeAuthCode).toHaveBeenCalledWith(req, 'abc')
      expect(updateSession).not.toHaveBeenCalled()
      expect(response).toBe(exchanged)
    })

    it('runs normal session handling without a code', async () => {
      const next = NextResponse.next()
      vi.mocked(updateSession).mockResolvedValue(next)

      const response = await supabaseAuthProvider.handleSession!(
        request('http://localhost:3000/auth/update-password')
      )

      expect(updateSession).toHaveBeenCalledOnce()
      expect(exchangeAuthCode).not.toHaveBeenCalled()
      expect(response).toBe(next)
    })

    it('exchanges a sign-up confirmation code arriving at the root', async () => {
      const exchanged = NextResponse.redirect('http://localhost:3000/')
      vi.mocked(exchangeAuthCode).mockResolvedValue(exchanged)
      const req = request('http://localhost:3000/?code=abc')

      const response = await supabaseAuthProvider.handleSession!(req)

      expect(exchangeAuthCode).toHaveBeenCalledWith(req, 'abc', '?confirmed=1')
      expect(updateSession).not.toHaveBeenCalled()
      expect(response).toBe(exchanged)
    })

    it('ignores code params on other paths', async () => {
      const next = NextResponse.next()
      vi.mocked(updateSession).mockResolvedValue(next)

      await supabaseAuthProvider.handleSession!(
        request('http://localhost:3000/auth/login?code=abc')
      )

      expect(updateSession).toHaveBeenCalledOnce()
      expect(exchangeAuthCode).not.toHaveBeenCalled()
    })
  })
})