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 FieldProposalsScreen from '../../resources/js/views/autopodbor/screens/FieldProposalsScreen.vue'; import { useAutopodborStore } from '../../resources/js/stores/autopodborStore'; const vuetify = createVuetify(); function makeNav() { return { go: vi.fn(), ctx: reactive({ competitorId: null }), screen: ref('field-proposals') }; } function comp(over: Partial = {}) { return { id: 1, name: 'Окна', description: 'Окна ПВХ под ключ', is_federal: false, relevance_pct: 80, origin: 'auto', box: 'proposal', site_url: 'okna.ru', directory_urls: ['https://2gis.ru/firm/1', 'https://yandex.ru/maps/1'], studied_at: null, study_run_id: null, search_run_id: 5, ...over, }; } function mountP(nav: any) { return mount(FieldProposalsScreen, { global: { plugins: [vuetify], provide: { autopodborNav: nav } } }); } describe('FieldProposalsScreen', () => { beforeEach(() => { setActivePinia(createPinia()); vi.clearAllMocks(); }); it('грузит предложения и показывает карточку-плитку с похожестью и Справочником', async () => { const store = useAutopodborStore(); vi.spyOn(store, 'loadProposals').mockImplementation(async () => { store.proposals = [comp({ id: 1, name: 'Окна Комфорт', relevance_pct: 80 })] as any; }); const w = mountP(makeNav()); await new Promise((r) => setTimeout(r, 0)); expect(store.loadProposals).toHaveBeenCalled(); expect(w.find('.ld-card').exists()).toBe(true); expect(w.text()).toContain('Окна Комфорт'); expect(w.text()).toContain('80'); expect(w.text()).toContain('Справочник'); expect(w.text()).toContain('2ГИС'); expect(w.text()).toContain('Яндекс.Карты'); }); it('«В поле →» по конкуренту зовёт moveCompetitorToBox(field)', async () => { const store = useAutopodborStore(); vi.spyOn(store, 'loadProposals').mockImplementation(async () => { store.proposals = [comp({ id: 7 })] as any; }); const moveSpy = vi.spyOn(store, 'moveCompetitorToBox').mockResolvedValue(); const w = mountP(makeNav()); await new Promise((r) => setTimeout(r, 0)); const btn = w.find('.ld-cfoot button'); await btn.trigger('click'); await new Promise((r) => setTimeout(r, 0)); expect(moveSpy).toHaveBeenCalledWith(7, 'field'); }); it('пусто показывает заглушку', async () => { const store = useAutopodborStore(); vi.spyOn(store, 'loadProposals').mockImplementation(async () => { store.proposals = [] as any; }); const w = mountP(makeNav()); await new Promise((r) => setTimeout(r, 0)); expect(w.text()).toContain('Предложений пока нет'); }); it('«Собрать конкурентов» открывает окно сбора с ценой 300 ₽ (не уходит на старую форму)', async () => { const store = useAutopodborStore(); vi.spyOn(store, 'loadProposals').mockResolvedValue(); store.prices = { search: '300', study: '50' }; const nav = makeNav(); const w = mountP(nav); 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 ₽'); expect(nav.go).not.toHaveBeenCalledWith('autoform'); }); it('массово переносит выбранных в поле при ≥2', async () => { const store = useAutopodborStore(); vi.spyOn(store, 'loadProposals').mockImplementation(async () => { store.proposals = [comp({ id: 1 }), comp({ id: 2 })] as any; }); const moveSpy = vi.spyOn(store, 'moveCompetitorToBox').mockResolvedValue(); const w = mountP(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(moveSpy).toHaveBeenCalledWith(1, 'field'); expect(moveSpy).toHaveBeenCalledWith(2, 'field'); }); it('«Изменить» открывает окно правки карточки конкурента', async () => { const store = useAutopodborStore(); vi.spyOn(store, 'loadProposals').mockImplementation(async () => { store.proposals = [comp({ id: 1, name: 'Окна Комфорт' })] as any; }); const w = mountP(makeNav()); await new Promise((r) => setTimeout(r, 0)); const link = w.findAll('.ld-link').find((b) => b.text().includes('Изменить')); await link!.trigger('click'); await new Promise((r) => setTimeout(r, 0)); expect(w.find('.ld-ovl').exists()).toBe(true); expect(w.text()).toContain('карточку конкурента'); }); });