import { describe, it, expect } from 'vitest'; import { mount } from '@vue/test-utils'; import { createVuetify } from 'vuetify'; import { setActivePinia, createPinia } from 'pinia'; import DealDetailBody from '../../resources/js/components/deals/DealDetailBody.vue'; import type { MockDeal } from '../../resources/js/composables/mockDeals'; const vuetify = createVuetify(); function makeDeal(overrides: Partial = {}): MockDeal { return { id: 1, name: '+79991234567', phone: '+79991234567', statusSlug: 'new', project: 'p', manager: { initials: 'AD', name: 'Admin' }, cost: 0, receivedMinutesAgo: 1, projectSignalType: 'site', projectSignalIdentifier: 'krk-finance.ru', projectSmsKeyword: null, projectSmsSenders: null, ...overrides, }; } describe('DealDetailBody — Тип и Источник (18.05.2026 ux)', () => { it('site: показывает Тип «Сайт» и Источник = signal_identifier', () => { setActivePinia(createPinia()); const w = mount(DealDetailBody, { props: { deal: makeDeal() }, global: { plugins: [vuetify] }, }); expect(w.text()).toContain('Сайт'); expect(w.text()).toContain('krk-finance.ru'); }); it('call: Тип «Звонок» и Источник = телефонный номер', () => { setActivePinia(createPinia()); const w = mount(DealDetailBody, { props: { deal: makeDeal({ projectSignalType: 'call', projectSignalIdentifier: '79992223344', }), }, global: { plugins: [vuetify] }, }); expect(w.text()).toContain('Звонок'); expect(w.text()).toContain('79992223344'); }); it('sms с keyword: Источник = «sender (KEYWORD)»', () => { setActivePinia(createPinia()); const w = mount(DealDetailBody, { props: { deal: makeDeal({ projectSignalType: 'sms', projectSignalIdentifier: null, projectSmsSenders: ['MTS', 'BEELINE'], projectSmsKeyword: 'КРЕДИТ', }), }, global: { plugins: [vuetify] }, }); expect(w.text()).toContain('СМС'); expect(w.text()).toContain('MTS (КРЕДИТ)'); }); it('sms без keyword: Источник = только sender', () => { setActivePinia(createPinia()); const w = mount(DealDetailBody, { props: { deal: makeDeal({ projectSignalType: 'sms', projectSignalIdentifier: null, projectSmsSenders: ['MTS'], projectSmsKeyword: null, }), }, global: { plugins: [vuetify] }, }); expect(w.text()).toContain('СМС'); expect(w.text()).toContain('MTS'); // Никаких пустых скобок expect(w.text()).not.toMatch(/\(\s*\)/); }); it('не отображает «Менеджер»', () => { setActivePinia(createPinia()); const w = mount(DealDetailBody, { props: { deal: makeDeal() }, global: { plugins: [vuetify] }, }); expect(w.text()).not.toContain('Менеджер'); expect(w.text()).not.toContain('Не назначен'); }); }); describe('DealDetailBody — Город (F1)', () => { it('показывает подпись «Город» и значение city', () => { setActivePinia(createPinia()); const w = mount(DealDetailBody, { props: { deal: makeDeal({ city: 'Москва' }) }, global: { plugins: [vuetify] }, }); expect(w.text()).toContain('Город'); expect(w.text()).toContain('Москва'); }); it('при пустом city показывает «Город» и прочерк', () => { setActivePinia(createPinia()); const w = mount(DealDetailBody, { props: { deal: makeDeal({ city: null }) }, global: { plugins: [vuetify] }, }); expect(w.text()).toContain('Город'); expect(w.text()).toContain('—'); }); }); describe('DealDetailBody — Стоимость лида (F2)', () => { it('показывает списанную сумму при costKopecks (rub)', () => { setActivePinia(createPinia()); const w = mount(DealDetailBody, { props: { deal: makeDeal({ costKopecks: 50000 }) }, global: { plugins: [vuetify] }, }); expect(w.text()).toContain('Стоимость лида'); expect(w.text()).toContain('500'); }); it('показывает прочерк, а не «0 ₽», при отсутствии списания (costKopecks null)', () => { setActivePinia(createPinia()); const w = mount(DealDetailBody, { props: { deal: makeDeal({ costKopecks: null }) }, global: { plugins: [vuetify] }, }); expect(w.text()).toContain('Стоимость лида'); expect(w.text()).not.toContain('0 ₽'); }); });