Files
portal/app/tests/Frontend/AutopodborView.deeplink.spec.ts
T
Дмитрий 98614604af feat(сделки): колонки «Конкурент» и «Источник» со ссылками в автоподбор
Раздел «Сделки»: колонка «Источник» разбита на две — «Конкурент» (ссылка на
экран конкурента) и «Источник» (ссылка на «Настройки проекта»). В модалку
настроек добавлена кнопка пуск/стоп (срабатывает не закрывая окно).

- бэк DealController::index: батч-резолв конкурента+источника по
  deal.project_id → autopodbor_sources.created_project_id → competitor (без N+1)
- контракт ApiDeal/MockDeal + маппер: competitor_*/source_* поля
- DealsTable: 1 колонка → 2 (Конкурент/Источник), router-link, fallback без автоподбора
- AutopodborView: deep-link ?competitor=&project= открывает экран конкурента + модалку
- FieldCompetitorScreen: кнопка ⏸/▶ в модалке настроек + авто-открытие по ссылке

Тесты: бэк DealIndexTest +4 (31 ), фронт +новые (66 ). Дизайн не менялся.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-08 07:56:30 +03:00

70 lines
2.7 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import { describe, it, expect, vi, beforeEach } from 'vitest';
import { mount, flushPromises } from '@vue/test-utils';
import { createPinia, setActivePinia } from 'pinia';
import { createRouter, createMemoryHistory } from 'vue-router';
vi.mock('../../resources/js/stores/autopodborStore', () => ({
useAutopodborStore: () => ({ loadState: vi.fn().mockResolvedValue(undefined) }),
}));
import AutopodborView from '../../resources/js/views/autopodbor/AutopodborView.vue';
async function mountWithQuery(query: Record<string, string>) {
const router = createRouter({
history: createMemoryHistory(),
routes: [{ path: '/autopodbor', name: 'autopodbor', component: { template: '<div />' } }],
});
await router.push({ path: '/autopodbor', query });
await router.isReady();
return mount(AutopodborView, {
global: {
plugins: [router],
stubs: {
FieldWorkspaceScreen: { template: '<div>field</div>' },
FieldCompetitorScreen: { template: '<div class="fc">competitor screen</div>' },
EditProjectScreen: true,
FieldProposalsScreen: true,
EntryScreen: true,
AutoFormScreen: true,
ManualFormScreen: true,
LoadingScreen: true,
ListScreen: true,
DetailScreen: true,
CreateScreen: true,
DoneScreen: true,
},
},
});
}
describe('AutopodborView deep-link (?competitor=&project=)', () => {
beforeEach(() => setActivePinia(createPinia()));
it('query competitor → экран конкурента с ctx.competitorId', async () => {
const w = await mountWithQuery({ competitor: '3' });
await flushPromises();
expect((w.vm as any).screen).toBe('fieldcompetitor');
expect((w.vm as any).ctx.competitorId).toBe(3);
});
it('query competitor+project → выставлен ctx.openProjectSettingsId', async () => {
const w = await mountWithQuery({ competitor: '3', project: '5' });
await flushPromises();
expect((w.vm as any).ctx.openProjectSettingsId).toBe(5);
});
it('без query — дефолтный экран field', async () => {
const w = await mountWithQuery({});
await flushPromises();
expect((w.vm as any).screen).toBe('field');
expect((w.vm as any).ctx.competitorId).toBeNull();
});
it('невалидный competitor — остаёмся на field', async () => {
const w = await mountWithQuery({ competitor: 'abc' });
await flushPromises();
expect((w.vm as any).screen).toBe('field');
});
});