import { describe, it, expect, beforeEach, vi } from 'vitest'; import { mount } from '@vue/test-utils'; import { createPinia, setActivePinia } from 'pinia'; import { createVuetify } from 'vuetify'; vi.mock('../../resources/js/api/autopodbor'); import CreateScreen from '../../resources/js/views/autopodbor/screens/CreateScreen.vue'; import { useAutopodborStore } from '../../resources/js/stores/autopodborStore'; import { AUTOPODBOR_NAV, type AutopodborNav } from '../../resources/js/views/autopodbor/nav'; import { exposed } from './support/exposed'; import { competitor, fieldSource, navStub } from './support/fixtures'; const vuetify = createVuetify(); /** Экран создания отдаёт наружу выбранный регион. */ interface CreateVm { regionCode: number; } function makeNav(): AutopodborNav { return navStub('create', { runId: 5, competitorId: 3, selectedSourceIds: [11, 12] }); } function seed(store: ReturnType) { store.competitor = competitor({ id: 3, name: 'Окна Комфорт', site_url: 'okna.ru', description: 'd', studied_at: '2026-06-28', study_run_id: 9, search_run_id: 5 }); store.sources = [ fieldSource({ id: 11, competitor_id: 3, signal_type: 'site', identifier: 'okna-komfort-kzn.ru', provenance_label: '2ГИС' }), fieldSource({ id: 12, competitor_id: 3, signal_type: 'call', identifier: '78432001122', phone_kind: 'real', provenance_label: '2ГИС' }), ]; } function mountCreate(nav: AutopodborNav) { return mount(CreateScreen, { global: { plugins: [vuetify], provide: { [AUTOPODBOR_NAV]: nav } } }); } describe('CreateScreen', () => { beforeEach(() => { setActivePinia(createPinia()); vi.clearAllMocks(); }); it('показывает выбранные источники и число проектов', async () => { const store = useAutopodborStore(); seed(store); const w = mountCreate(makeNav()); await new Promise(r => setTimeout(r, 0)); expect(w.text()).toContain('okna-komfort-kzn.ru'); expect(w.text()).toContain('Окна Комфорт'); // производное имя }); it('«Создать (без запуска)» зовёт makeProjects(launch=false) и идёт на done', async () => { const store = useAutopodborStore(); seed(store); vi.spyOn(store, 'makeProjects').mockResolvedValue({ data: [{ id: 1, name: 'Окна Комфорт', is_active: true }, { id: 2, name: 'Окна Комфорт ✓', is_active: true }], launch: { launched: 2, deferred: 0, balance: null } }); const nav = makeNav(); const w = mountCreate(nav); exposed(w).regionCode = 16; await new Promise(r => setTimeout(r, 0)); const btn = w.findAll('button').find(b => b.text().includes('без запуска')); await btn!.trigger('click'); await new Promise(r => setTimeout(r, 0)); expect(store.makeProjects).toHaveBeenCalled(); const arg = vi.mocked(store.makeProjects).mock.calls[0][0]; expect(arg.launch).toBe(false); expect(arg.source_ids).toEqual([11, 12]); expect(nav.ctx.createdCount).toBe(2); expect(nav.go).toHaveBeenCalledWith('done'); }); it('409 нехватки баланса показывает сообщение и возвращает на create', async () => { const store = useAutopodborStore(); seed(store); vi.spyOn(store, 'makeProjects').mockRejectedValue({ response: { data: { error: 'balance_insufficient' } } }); const nav = makeNav(); const w = mountCreate(nav); exposed(w).regionCode = 16; await new Promise(r => setTimeout(r, 0)); const btn = w.findAll('button').find(b => b.text().includes('запустить')); await btn!.trigger('click'); await new Promise(r => setTimeout(r, 0)); expect(store.makeProjects).toHaveBeenCalled(); expect(nav.go).toHaveBeenCalledWith('create'); }); });