import { describe, it, expect } from 'vitest'; import { AxiosError } from 'axios'; import { apiErrorBody, apiErrorCode, apiFieldError } from '../../resources/js/api/errors'; function axErr(status: number, body: unknown): AxiosError { const e = new AxiosError('err'); // @ts-expect-error — минимальный мок ответа e.response = { status, data: body, statusText: '', headers: {}, config: {} }; return e; } describe('чтение ошибки от бэкенда — работает и на настоящей ошибке axios, и на её форме', () => { it('код ошибки читается из настоящей ошибки axios', () => { expect(apiErrorCode(axErr(409, { error: 'balance_insufficient' }))).toBe('balance_insufficient'); }); it('код ошибки читается из простого объекта той же формы', () => { // Так ошибку подсовывают тесты экранов: mockRejectedValue({ response: { data: { error: ... } } }). // Поведение обязано совпадать с настоящей ошибкой — иначе экран ведёт себя в тестах // не так, как в бою. expect(apiErrorCode({ response: { data: { error: 'run_in_flight' } } })).toBe('run_in_flight'); }); it('ошибка поля читается по имени поля', () => { const e = axErr(422, { errors: { name: ['Название занято.'], site: ['Плохой сайт.'] } }); expect(apiFieldError(e, 'name')).toBe('Название занято.'); expect(apiFieldError(e, 'site')).toBe('Плохой сайт.'); }); it('нет такого поля — undefined, а не падение', () => { expect(apiFieldError(axErr(422, { errors: { name: ['занято'] } }), 'site')).toBeUndefined(); }); it('тело ошибки отдаётся целиком, когда оно есть', () => { expect(apiErrorBody(axErr(422, { message: 'Так нельзя.' }))).toEqual({ message: 'Так нельзя.' }); }); it('обычная ошибка без ответа сервера — undefined во всех трёх случаях', () => { expect(apiErrorBody(new Error('x'))).toBeUndefined(); expect(apiErrorCode(new Error('x'))).toBeUndefined(); expect(apiFieldError(new Error('x'), 'name')).toBeUndefined(); }); it('мусор вместо ошибки не роняет чтение', () => { for (const junk of [null, undefined, 0, '', 'строка', { response: null }, { response: { data: 7 } }]) { expect(apiErrorCode(junk)).toBeUndefined(); } }); });