import { describe, it, expect } from 'vitest'; import { mount } from '@vue/test-utils'; import { createVuetify } from 'vuetify'; import FunnelChart from '../../resources/js/components/charts/FunnelChart.vue'; import { LEAD_STATUSES } from '../../resources/js/composables/leadStatuses'; describe('FunnelChart.vue', () => { const factory = (props?: Record) => mount(FunnelChart, { props, global: { plugins: [createVuetify()] }, }); it('монтируется и содержит заголовок «Воронка»', () => { const wrapper = factory(); expect(wrapper.text()).toContain('Воронка'); }); it('содержит ровно 5 сегментов в bar (по числу lead_statuses)', () => { const wrapper = factory(); const segs = wrapper.findAll('.funnel-seg'); expect(segs).toHaveLength(5); }); it('содержит ровно 5 list-items', () => { const wrapper = factory(); const items = wrapper.findAll('.funnel-list-item'); expect(items).toHaveLength(5); }); it('использует правильные slug-имена из schema (НЕ из BRANDBOOK)', () => { const wrapper = factory(); const text = wrapper.text(); // Проверка что все 5 имён из lead_statuses присутствуют. LEAD_STATUSES.forEach((s) => { expect(text).toContain(s.nameRu); }); // Гарантия что мы НЕ используем имена из BRANDBOOK §3.6 (расхождение #1). // Например, "Думает" / "Не дозвон." / "Спам" / "КП" — handoff-only. expect(text).not.toContain('Думает'); expect(text).not.toContain('Спам'); }); it('сортирует список по убыванию count (in_progress 96 — первый)', () => { const wrapper = factory(); const names = wrapper.findAll('.funnel-list-item .name').map((n) => n.text()); expect(names[0]).toBe('В работе'); // count=96 — самый большой в DEFAULT_COUNTS. }); it('применяет colorHex из lead_statuses к dots и сегментам', () => { const wrapper = factory(); const segs = wrapper.findAll('.funnel-seg'); // Первый segment в bar — статус с sortOrder=1 (new, цвет #3B82F6). expect(segs[0].element.style.background).toContain('rgb(59, 130, 246)'); }); it('считает total как сумму counts', () => { const wrapper = factory({ counts: { new: 10, won: 20 } }); const text = wrapper.text(); // total = 10 + 20 = 30 (остальные слаги с counts={} → 0). expect(text).toContain('30 лидов'); }); });