import { describe, it, expect } from 'vitest' import { localizeError } from './errors' import { ApiRequestError } from '../api/client' import type { MessageKey } from '../i18n/en' // Echo translator: returns the key (with vars) so we can assert which key was chosen. const t = ((key: MessageKey, vars?: Record) => vars ? `${key}:${JSON.stringify(vars)}` : key) as ( key: MessageKey, vars?: Record, ) => string describe('localizeError', () => { it('maps network error to error.network', () => { const e = new ApiRequestError({ status: 0, message: 'network error' }) expect(localizeError(e, t, 'error.paymentCreate')).toBe('error.network') }) it('maps timeout to error.timeout', () => { const e = new ApiRequestError({ status: 0, message: 'request timed out' }) expect(localizeError(e, t, 'error.paymentCreate')).toBe('error.timeout') }) it('uses localized fallback + request id, NOT raw backend text', () => { const e = new ApiRequestError({ status: 422, message: 'cannot cancel a succeeded payment', requestId: 'req1' }) const out = localizeError(e, t, 'error.cancel') expect(out).toContain('error.withRef') expect(out).toContain('error.cancel') expect(out).toContain('req1') expect(out).not.toContain('cannot cancel') // raw backend text never shown }) it('falls back to the operation key when no request id', () => { const e = new ApiRequestError({ status: 500, message: 'boom' }) expect(localizeError(e, t, 'error.refund')).toBe('error.refund') }) it('handles non-API errors with the fallback', () => { expect(localizeError(new Error('x'), t, 'error.generic')).toBe('error.generic') }) })