import { describe, it, expect, beforeEach, vi } from 'vitest'; import { mount } from '@vue/test-utils'; import { setActivePinia, createPinia } from 'pinia'; vi.mock('../../resources/js/api/autopodbor', async (importOriginal) => { const actual = await importOriginal(); return { ...actual, fetchCompetitor: vi.fn() }; }); import * as api from '../../resources/js/api/autopodbor'; import { useAutopodborStore } from '../../resources/js/stores/autopodborStore'; import FieldCompetitorScreen from '../../resources/js/views/autopodbor/screens/FieldCompetitorScreen.vue'; const makeNav = (competitorId = 10) => ({ go: vi.fn(), ctx: { competitorId, editProjectId: null, selectedSourceIds: [] }, screen: { value: 'field-competitor' }, }); // Источник-предложение (box 'proposal', без проекта). const makeProposal = (id: number) => ({ id, competitor_id: 10, signal_type: 'site' as const, identifier: `prop-${id}.ru`, phone_kind: null, phone_type: null, box: 'proposal' as const, provenance_url: null, provenance_label: null, created_project_id: null, project: null, }); async function mountWithProposals() { (api.fetchCompetitor as ReturnType).mockResolvedValue({ competitor: { id: 10, name: 'Окна', is_federal: false, relevance_pct: 90, origin: 'auto', box: 'field', site_url: 'okna.ru', directory_urls: [], studied_at: '2026-01-01', study_run_id: 1, search_run_id: 1, description: '' }, sources: [makeProposal(1), makeProposal(2)], }); const store = useAutopodborStore(); await store.loadCompetitor(10); const wrapper = mount(FieldCompetitorScreen, { global: { provide: { autopodborNav: makeNav() }, stubs: { Transition: false } }, }); await new Promise((r) => setTimeout(r, 50)); return { wrapper, store }; } beforeEach(() => { setActivePinia(createPinia()); vi.clearAllMocks(); }); describe('FieldCompetitorScreen — массовые действия на вкладке «Предложения» (Баг 1)', () => { it('при 2+ выбранных предложениях показывается панель массового переноса', async () => { const { wrapper } = await mountWithProposals(); // eslint-disable-next-line @typescript-eslint/no-explicit-any const vm = wrapper.vm as any; vm.switchTab('sugg'); vm.selected = [1, 2]; await wrapper.vm.$nextTick(); expect(wrapper.find('.ld-bulkbar').exists()).toBe(true); expect(wrapper.text()).toContain('Перенести выбранные в источники'); }); it('bulkMoveToWork переносит каждый выбранный источник в box field', async () => { const { wrapper, store } = await mountWithProposals(); const spy = vi.spyOn(store, 'moveSourceToBox').mockResolvedValue(); // eslint-disable-next-line @typescript-eslint/no-explicit-any const vm = wrapper.vm as any; vm.switchTab('sugg'); vm.selected = [1, 2]; await wrapper.vm.$nextTick(); await vm.bulkMoveToWork(); expect(spy).toHaveBeenCalledWith(10, 1, 'field'); expect(spy).toHaveBeenCalledWith(10, 2, 'field'); expect(spy).toHaveBeenCalledTimes(2); }); });