import { describe, it, expect, beforeEach, vi } from 'vitest'; import { mount } from '@vue/test-utils'; import { createPinia, setActivePinia } from 'pinia'; import { createVuetify } from 'vuetify'; import { reactive, ref } from 'vue'; vi.mock('../../resources/js/api/autopodbor'); import FieldWorkspaceScreen from '../../resources/js/views/autopodbor/screens/FieldWorkspaceScreen.vue'; import { useAutopodborStore } from '../../resources/js/stores/autopodborStore'; const vuetify = createVuetify(); function makeNav() { return { go: vi.fn(), ctx: reactive({ competitorId: null }), screen: ref('field') }; } function field(over: Partial = {}) { return { id: 1, name: 'Окна Комфорт', description: 'd', is_federal: false, relevance_pct: 90, origin: 'auto', box: 'field', site_url: 'okna.ru', directory_urls: [], studied_at: null, study_run_id: null, search_run_id: 5, counters: { sources: 2, projects_created: 1, projects_in_work: 1 }, sources: [], ...over, }; } function mountWs(nav: any) { return mount(FieldWorkspaceScreen, { global: { plugins: [vuetify], provide: { autopodborNav: nav } } }); } describe('FieldWorkspaceScreen', () => { beforeEach(() => { setActivePinia(createPinia()); vi.clearAllMocks(); }); it('грузит поле и показывает конкурентов со счётчиками', async () => { const store = useAutopodborStore(); vi.spyOn(store, 'loadField').mockImplementation(async () => { store.field = [field()] as any; }); const w = mountWs(makeNav()); await new Promise((r) => setTimeout(r, 0)); expect(store.loadField).toHaveBeenCalled(); expect(w.text()).toContain('Окна Комфорт'); expect(w.text()).toContain('создано проектов'); }); it('сортирует по похожести: 100% сверху', async () => { const store = useAutopodborStore(); vi.spyOn(store, 'loadField').mockImplementation(async () => { store.field = [ field({ id: 1, name: 'Низкая', relevance_pct: 40 }), field({ id: 2, name: 'Высокая', relevance_pct: 100 }), ] as any; }); const w = mountWs(makeNav()); await new Promise((r) => setTimeout(r, 0)); const names = w.findAll('.ld-card__nm').map((n) => n.text()); expect(names[0]).toContain('Высокая'); }); it('пустое поле показывает заглушку', async () => { const store = useAutopodborStore(); vi.spyOn(store, 'loadField').mockImplementation(async () => { store.field = [] as any; }); const w = mountWs(makeNav()); await new Promise((r) => setTimeout(r, 0)); expect(w.text()).toContain('В поле пока пусто'); }); it('«Собрать конкурентов для меня» открывает окно сбора с ценой', async () => { const store = useAutopodborStore(); vi.spyOn(store, 'loadField').mockResolvedValue(); store.prices = { search: '300', study: '50' }; const w = mountWs(makeNav()); await new Promise((r) => setTimeout(r, 0)); const btn = w.findAll('button').find((b) => b.text().includes('Собрать конкурентов для меня')); await btn!.trigger('click'); expect(w.find('.ld-ovl').exists()).toBe(true); expect(w.text()).toContain('Сбор конкурентов'); expect(w.text()).toContain('300 ₽'); }); it('«Открыть конкурента» открывает карточку', async () => { const store = useAutopodborStore(); vi.spyOn(store, 'loadField').mockImplementation(async () => { store.field = [field({ id: 7 })] as any; }); const nav = makeNav(); const w = mountWs(nav); await new Promise((r) => setTimeout(r, 0)); const btn = w.findAll('button').find((b) => b.text().includes('Открыть конкурента')); await btn!.trigger('click'); expect(nav.ctx.competitorId).toBe(7); expect(nav.go).toHaveBeenCalledWith('fieldcompetitor'); }); it('всплывающая панель показывается при ≥2 выбранных и массово включает проекты', async () => { const store = useAutopodborStore(); vi.spyOn(store, 'loadField').mockImplementation(async () => { store.field = [ field({ id: 1, sources: [{ id: 10, project: { id: 100, is_active: false } }], counters: { sources: 1, projects_created: 1, projects_in_work: 0 } }), field({ id: 2, sources: [{ id: 11, project: { id: 101, is_active: false } }], counters: { sources: 1, projects_created: 1, projects_in_work: 0 } }), ] as any; }); const toggleSpy = vi.spyOn(store, 'toggleProjectActive').mockResolvedValue(); const w = mountWs(makeNav()); await new Promise((r) => setTimeout(r, 0)); const boxes = w.findAll('.ld-pick'); await boxes[0].trigger('change'); await boxes[1].trigger('change'); expect(w.find('.ld-bulkbar').exists()).toBe(true); const btn = w.findAll('.ld-bulkbar button').find((b) => b.text().includes('Включить')); await btn!.trigger('click'); await new Promise((r) => setTimeout(r, 0)); expect(toggleSpy).toHaveBeenCalledWith(100, true); expect(toggleSpy).toHaveBeenCalledWith(101, true); }); });