import { describe, it, expect, vi, beforeEach } from 'vitest'; import { createPinia, setActivePinia } from 'pinia'; import { useLeadStatusesStore } from '../../resources/js/stores/leadStatuses'; import { LEAD_STATUSES } from '../../resources/js/composables/leadStatuses'; vi.mock('../../resources/js/api/leadStatuses', () => ({ listLeadStatuses: vi.fn(), })); const api = await import('../../resources/js/api/leadStatuses'); beforeEach(() => { vi.clearAllMocks(); setActivePinia(createPinia()); }); describe('useLeadStatusesStore', () => { it('initial state — snapshot из LEAD_STATUSES', () => { const store = useLeadStatusesStore(); expect(store.statuses).toHaveLength(LEAD_STATUSES.length); expect(store.loaded).toBe(false); expect(store.fetchError).toBe(false); }); it('findBySlug возвращает статус из snapshot до load (won)', () => { const store = useLeadStatusesStore(); const found = store.findBySlug('won'); expect(found).not.toBeNull(); expect(found!.nameRu).toBe('Сделка'); }); it('findBySlug возвращает null для неизвестного slug', () => { const store = useLeadStatusesStore(); expect(store.findBySlug('not_a_real_slug')).toBeNull(); }); it('load() success — replace на API-данные + loaded=true', async () => { vi.mocked(api.listLeadStatuses).mockResolvedValueOnce([ { slug: 'custom', name_ru: 'Кастомный', is_system: false, sort_order: 100, color_hex: '#ABCDEF', description: null, }, ]); const store = useLeadStatusesStore(); await store.load(); expect(store.loaded).toBe(true); expect(store.statuses).toHaveLength(1); expect(store.statuses[0].slug).toBe('custom'); expect(store.statuses[0].nameRu).toBe('Кастомный'); expect(store.findBySlug('custom')!.colorHex).toBe('#ABCDEF'); }); it('load() reject — fetchError=true + snapshot остаётся', async () => { vi.mocked(api.listLeadStatuses).mockRejectedValueOnce(new Error('500')); const store = useLeadStatusesStore(); await store.load(); expect(store.fetchError).toBe(true); expect(store.loaded).toBe(false); expect(store.statuses).toHaveLength(LEAD_STATUSES.length); }); it('load() идемпотентен — повторный вызов не делает второй request', async () => { vi.mocked(api.listLeadStatuses).mockResolvedValue([ { slug: 'x', name_ru: 'X', is_system: false, sort_order: 1, color_hex: '#000000', description: null, }, ]); const store = useLeadStatusesStore(); await store.load(); await store.load(); expect(api.listLeadStatuses).toHaveBeenCalledTimes(1); }); it('load(force=true) делает повторный fetch', async () => { vi.mocked(api.listLeadStatuses).mockResolvedValue([ { slug: 'x', name_ru: 'X', is_system: false, sort_order: 1, color_hex: '#000000', description: null, }, ]); const store = useLeadStatusesStore(); await store.load(); await store.load(true); expect(api.listLeadStatuses).toHaveBeenCalledTimes(2); }); });