import { describe, expect, it } from 'vitest'
import { isPaymentProviderError } from './errors'
import { assertClientSecretShape, assertPublishableKey } from './guards'

describe('assertPublishableKey (allowlist / default-deny)', () => {
  it('ACCEPTS pk_test_ and pk_live_', () => {
    expect(() => assertPublishableKey('pk_test_abc123')).not.toThrow()
    expect(() => assertPublishableKey('pk_live_abc123')).not.toThrow()
  })

  it('REJECTS a secret key sk_live_ with PaymentProviderError', () => {
    let thrown: unknown
    try {
      assertPublishableKey('sk_live_DEADBEEF')
    } catch (e) {
      thrown = e
    }
    expect(isPaymentProviderError(thrown)).toBe(true)
  })

  it('REJECTS restricted rk_, empty, and unenumerated garbage (default-deny)', () => {
    for (const bad of ['rk_live_x', '', 'pk', 'sk_test_x', 'whatever', 'PK_TEST_x']) {
      expect(() => assertPublishableKey(bad), bad).toThrow()
    }
  })

  it('REJECTS newline-injection tail (pk_test_x\\nsk_live_REAL) with PaymentProviderError', () => {
    let thrown: unknown
    try {
      assertPublishableKey('pk_test_x\nsk_live_REAL')
    } catch (e) {
      thrown = e
    }
    expect(isPaymentProviderError(thrown)).toBe(true)
  })

  it('ACCEPTS pk_test_ and pk_live_ with alphanumeric body', () => {
    expect(() => assertPublishableKey('pk_test_abc123XYZ')).not.toThrow()
    expect(() => assertPublishableKey('pk_live_abc123XYZ')).not.toThrow()
  })
})

describe('assertClientSecretShape', () => {
  it('accepts a valid PaymentIntent client secret', () => {
    expect(() => assertClientSecretShape('pi_3ABC_secret_XYZ')).not.toThrow()
  })

  it('accepts a SetupIntent client secret', () => {
    expect(() => assertClientSecretShape('seti_1ABC_secret_XYZ')).not.toThrow()
  })

  it('rejects a malformed secret with PaymentProviderError', () => {
    for (const bad of ['', 'pi_nope', 'secret_only', 'pk_test_x']) {
      let thrown: unknown
      try {
        assertClientSecretShape(bad)
      } catch (e) {
        thrown = e
      }
      expect(isPaymentProviderError(thrown), bad).toBe(true)
    }
  })
})