Files
portal/app/tests/Frontend/FunnelChart.spec.ts
T

64 lines
2.8 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 } 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<string, unknown>) =>
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<HTMLElement>('.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 лидов');
});
});