// Unit tests for safeRedirectPath (SEC-004 / Batch 6).
//
// The function must be a pure, synchronous guard with no framework imports.
// It prevents open-redirect attacks on the OAuth callback route by ensuring
// only same-origin relative paths are used as redirect targets.

import { describe, it, expect } from 'vitest'
import { safeRedirectPath, SAFE_REDIRECT_FALLBACK } from '@/lib/auth/safe-redirect'

const FALLBACK = SAFE_REDIRECT_FALLBACK

describe('safeRedirectPath — safe inputs', () => {
  it('returns a normal relative path unchanged', () => {
    expect(safeRedirectPath('/projektanlage')).toBe('/projektanlage')
  })

  it('returns a nested relative path unchanged', () => {
    expect(safeRedirectPath('/project/abc/stopwatch')).toBe('/project/abc/stopwatch')
  })

  it('returns the root path unchanged', () => {
    expect(safeRedirectPath('/dashboard')).toBe('/dashboard')
  })

  it('returns a path with query string unchanged', () => {
    expect(safeRedirectPath('/search?q=test')).toBe('/search?q=test')
  })
})

describe('safeRedirectPath — malicious / absolute inputs fall back', () => {
  it('rejects protocol-relative URL  //evil.com', () => {
    expect(safeRedirectPath('//evil.com')).toBe(FALLBACK)
  })

  it('rejects protocol-relative URL  //evil.com/path', () => {
    expect(safeRedirectPath('//evil.com/path')).toBe(FALLBACK)
  })

  it('rejects https absolute URL', () => {
    expect(safeRedirectPath('https://evil.com/steal')).toBe(FALLBACK)
  })

  it('rejects http absolute URL', () => {
    expect(safeRedirectPath('http://evil.com')).toBe(FALLBACK)
  })

  it('rejects forward-slash + backslash trick  /\\evil.com', () => {
    expect(safeRedirectPath('/\\evil.com')).toBe(FALLBACK)
  })

  it('rejects backslash-start  \\evil.com', () => {
    expect(safeRedirectPath('\\evil.com')).toBe(FALLBACK)
  })

  it('rejects triple-slash  ///evil.com', () => {
    expect(safeRedirectPath('///evil.com')).toBe(FALLBACK)
  })

  it('rejects URL-encoded slash trick  /%2Fevil.com', () => {
    // %2F is a forward slash — still starts with /% which is safe by our regex,
    // but an additional path-traversal encoding check is out of scope here;
    // this test documents the current behaviour (pass-through for encoded paths).
    // The route already resolves within origin, so %2F cannot escape the host.
    const encoded = '/%2Fevil.com'
    expect(safeRedirectPath(encoded)).toBe(encoded)
  })
})

describe('safeRedirectPath — null / empty inputs fall back', () => {
  it('returns fallback for null', () => {
    expect(safeRedirectPath(null)).toBe(FALLBACK)
  })

  it('returns fallback for undefined', () => {
    expect(safeRedirectPath(undefined)).toBe(FALLBACK)
  })

  it('returns fallback for empty string', () => {
    expect(safeRedirectPath('')).toBe(FALLBACK)
  })

  it('returns fallback for whitespace-only string', () => {
    expect(safeRedirectPath('   ')).toBe(FALLBACK)
  })
})
