import { describe, expect, it } from 'vitest'
import {
  PaymentConfirmError,
  PaymentProviderError,
  isPaymentConfirmError,
  isPaymentProviderError,
} from './errors'

describe('errors', () => {
  it('PaymentProviderError is name-tagged', () => {
    const e = new PaymentProviderError('bad key')
    expect(e.name).toBe('PaymentProviderError')
    expect(e.message).toBe('bad key')
  })

  it('PaymentConfirmError carries a verbatim PSP code string', () => {
    const e = new PaymentConfirmError('declined', 'card_declined')
    expect(e.name).toBe('PaymentConfirmError')
    expect(e.code).toBe('card_declined')
  })

  it('guards are structural (by name), true for own', () => {
    expect(isPaymentProviderError(new PaymentProviderError('x'))).toBe(true)
    expect(isPaymentConfirmError(new PaymentConfirmError('x', 'c'))).toBe(true)
  })

  it('guards reject a foreign by-name lookalike that is not the class', () => {
    const fakeProvider = { name: 'PaymentProviderError' }
    const fakeConfirm = { name: 'PaymentConfirmError', code: 'x' }
    // structural guard keys on name AND error-shape; a bare object is NOT an Error
    expect(isPaymentProviderError(fakeProvider)).toBe(false)
    expect(isPaymentConfirmError(fakeConfirm)).toBe(false)
    // cross-type: a confirm error is not a provider error
    expect(isPaymentProviderError(new PaymentConfirmError('x', 'c'))).toBe(false)
    expect(isPaymentConfirmError(new PaymentProviderError('x'))).toBe(false)
  })
})