import { describe, it, expect, vi, beforeEach } from 'vitest'; import { mount, flushPromises } from '@vue/test-utils'; import { createVuetify } from 'vuetify'; import { createPinia } from 'pinia'; import { createRouter, createMemoryHistory } from 'vue-router'; import SalesManagersView from '../../resources/js/views/sales/SalesManagersView.vue'; // ─── mock API (listSalesManagers / createSalesManager) ──────────────────────── vi.mock('../../resources/js/api/sales', async () => { const actual = await vi.importActual('../../resources/js/api/sales'); return { ...actual, listSalesManagers: vi.fn().mockResolvedValue([ { id: 1, name: 'Виктор Орлов', email: 'v.orlov@liderra.ru', role: 'head', is_active: true, clients_count: 0, paid_all_time_rub: 0, }, { id: 2, name: 'Алексей Смирнов', email: 'a.smirnov@liderra.ru', role: 'manager', is_active: true, clients_count: 7, paid_all_time_rub: 85000, }, { id: 3, name: 'Игорь Лебедев', email: 'i.lebedev@liderra.ru', role: 'manager', is_active: false, clients_count: 4, paid_all_time_rub: 40000, }, ]), createSalesManager: vi.fn().mockResolvedValue({ id: 4, name: 'Иван Иванов', email: 'i.ivanov@liderra.ru', role: 'manager', is_active: true, }), }; }); beforeEach(() => vi.clearAllMocks()); // ─── helpers ────────────────────────────────────────────────────────────────── function makeRouter() { const router = createRouter({ history: createMemoryHistory(), routes: [{ path: '/sales/managers', name: 'sales-managers', component: SalesManagersView }], }); return router.push('/sales/managers').then(() => router); } async function mountView() { const router = await makeRouter(); const wrapper = mount(SalesManagersView, { global: { plugins: [createVuetify(), createPinia(), router] }, }); await flushPromises(); return wrapper; } describe('SalesManagersView', () => { it('вызывает listSalesManagers при монтировании', async () => { await mountView(); const api = await import('../../resources/js/api/sales'); expect(api.listSalesManagers).toHaveBeenCalled(); }); it('отрисовывает строки менеджеров из мока', async () => { const wrapper = await mountView(); const rows = wrapper.findAll('[data-testid="manager-row"]'); expect(rows.length).toBe(3); const text = wrapper.text(); expect(text).toContain('Виктор Орлов'); expect(text).toContain('v.orlov@liderra.ru'); expect(text).toContain('Алексей Смирнов'); expect(text).toContain('Игорь Лебедев'); }); it('роль head → «Начальник», manager → «Менеджер»', async () => { const wrapper = await mountView(); const text = wrapper.text(); expect(text).toContain('Начальник'); expect(text).toContain('Менеджер'); }); it('статус is_active → «Активен», иначе → «Отпуск»', async () => { const wrapper = await mountView(); const text = wrapper.text(); expect(text).toContain('Активен'); expect(text).toContain('Отпуск'); }); it('«Создать менеджера» вызывает createSalesManager с верным payload и перезагружает список', async () => { const wrapper = await mountView(); const api = await import('../../resources/js/api/sales'); wrapper.vm.form.name = 'Иван Иванов'; wrapper.vm.form.email = 'i.ivanov@liderra.ru'; wrapper.vm.form.password = 'secret123'; wrapper.vm.form.role = 'manager'; (api.listSalesManagers as ReturnType).mockClear(); await wrapper.vm.submit(); await flushPromises(); expect(api.createSalesManager).toHaveBeenCalledWith({ name: 'Иван Иванов', email: 'i.ivanov@liderra.ru', password: 'secret123', role: 'manager', }); // список перезагружен после успешного создания expect(api.listSalesManagers).toHaveBeenCalled(); // форма очищена expect(wrapper.vm.form.name).toBe(''); expect(wrapper.vm.form.email).toBe(''); expect(wrapper.vm.form.password).toBe(''); }); it('ошибка создания (422) показывается пользователю', async () => { const wrapper = await mountView(); const api = await import('../../resources/js/api/sales'); (api.createSalesManager as ReturnType).mockRejectedValueOnce({ isAxiosError: true, response: { status: 422, data: { message: 'E-mail уже занят.' } }, }); wrapper.vm.form.name = 'Дубль'; wrapper.vm.form.email = 'v.orlov@liderra.ru'; wrapper.vm.form.password = 'secret123'; wrapper.vm.form.role = 'manager'; await wrapper.vm.submit(); await flushPromises(); expect(wrapper.vm.snackbarText).toContain('E-mail уже занят'); // форма НЕ очищена при ошибке expect(wrapper.vm.form.name).toBe('Дубль'); }); });