2026-05-13 00:28:39 +03:00
|
|
|
|
import { describe, it, expect } from 'vitest';
|
|
|
|
|
|
import { mount } from '@vue/test-utils';
|
|
|
|
|
|
import { createVuetify } from 'vuetify';
|
|
|
|
|
|
import DealsTable from '../../resources/js/components/deals/DealsTable.vue';
|
|
|
|
|
|
import type { MockDeal } from '../../resources/js/composables/mockDeals';
|
|
|
|
|
|
|
|
|
|
|
|
const vuetify = createVuetify();
|
|
|
|
|
|
|
|
|
|
|
|
const sampleDeals: MockDeal[] = [
|
|
|
|
|
|
{
|
2026-06-17 05:17:12 +03:00
|
|
|
|
id: 1,
|
|
|
|
|
|
name: '+7 (916) 100-00-01',
|
|
|
|
|
|
phone: '+7 (916) 100-00-01',
|
|
|
|
|
|
statusSlug: 'new',
|
|
|
|
|
|
project: 'Окна',
|
|
|
|
|
|
manager: { initials: 'AD', name: 'Admin' },
|
|
|
|
|
|
cost: 0,
|
|
|
|
|
|
receivedMinutesAgo: 5,
|
|
|
|
|
|
signalType: 'call',
|
|
|
|
|
|
city: 'Москва',
|
|
|
|
|
|
comment: 'звонил',
|
|
|
|
|
|
receivedAt: '2026-05-15T09:00:00+00:00',
|
2026-05-13 00:28:39 +03:00
|
|
|
|
},
|
|
|
|
|
|
{
|
2026-06-17 05:17:12 +03:00
|
|
|
|
id: 2,
|
|
|
|
|
|
name: '+7 (916) 100-00-02',
|
|
|
|
|
|
phone: '+7 (916) 100-00-02',
|
|
|
|
|
|
statusSlug: 'new',
|
|
|
|
|
|
project: 'Двери',
|
|
|
|
|
|
manager: { initials: 'AD', name: 'Admin' },
|
|
|
|
|
|
cost: 0,
|
|
|
|
|
|
receivedMinutesAgo: 30,
|
|
|
|
|
|
signalType: 'site',
|
|
|
|
|
|
city: null,
|
|
|
|
|
|
comment: null,
|
|
|
|
|
|
receivedAt: '2026-05-14T09:00:00+00:00',
|
2026-05-13 00:28:39 +03:00
|
|
|
|
},
|
|
|
|
|
|
];
|
|
|
|
|
|
|
2026-05-17 15:24:51 +03:00
|
|
|
|
describe('DealsTable', () => {
|
|
|
|
|
|
it('рендерит колонки реестра лидов', () => {
|
|
|
|
|
|
const w = mount(DealsTable, {
|
|
|
|
|
|
props: { deals: sampleDeals, selectedIds: [], statusBySlug: new Map() },
|
|
|
|
|
|
global: { plugins: [vuetify] },
|
|
|
|
|
|
});
|
|
|
|
|
|
const headers = w.findAll('thead th').map((h) => h.text());
|
2026-06-19 11:29:35 +03:00
|
|
|
|
['Телефон', 'Источник', 'Город', 'Статус', 'Комментарий', 'Поставлен'].forEach((label) => {
|
2026-05-17 15:24:51 +03:00
|
|
|
|
expect(headers.some((h) => h.includes(label))).toBe(true);
|
|
|
|
|
|
});
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
it('город без значения рендерится как «—»', () => {
|
|
|
|
|
|
const w = mount(DealsTable, {
|
|
|
|
|
|
props: { deals: sampleDeals, selectedIds: [], statusBySlug: new Map() },
|
|
|
|
|
|
global: { plugins: [vuetify] },
|
|
|
|
|
|
});
|
|
|
|
|
|
expect(w.text()).toContain('—');
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
it('select-all чекбокс имеет aria-label', () => {
|
|
|
|
|
|
const w = mount(DealsTable, {
|
2026-05-13 00:28:39 +03:00
|
|
|
|
props: { deals: sampleDeals, selectedIds: [], statusBySlug: new Map() },
|
|
|
|
|
|
global: { plugins: [vuetify] },
|
|
|
|
|
|
});
|
2026-06-17 05:17:12 +03:00
|
|
|
|
expect(w.find('th .v-selection-control input[type="checkbox"][aria-label="Выбрать все сделки"]').exists()).toBe(
|
|
|
|
|
|
true,
|
|
|
|
|
|
);
|
2026-05-13 00:28:39 +03:00
|
|
|
|
});
|
|
|
|
|
|
|
2026-05-17 15:24:51 +03:00
|
|
|
|
it('клик по строке эмитит row-click с deal', async () => {
|
|
|
|
|
|
const w = mount(DealsTable, {
|
2026-05-13 00:28:39 +03:00
|
|
|
|
props: { deals: sampleDeals, selectedIds: [], statusBySlug: new Map() },
|
|
|
|
|
|
global: { plugins: [vuetify] },
|
|
|
|
|
|
});
|
2026-05-17 15:24:51 +03:00
|
|
|
|
await w.find('tbody tr').trigger('click');
|
|
|
|
|
|
expect(w.emitted('row-click')?.[0]?.[0]).toMatchObject({ id: 1 });
|
2026-05-13 00:28:39 +03:00
|
|
|
|
});
|
|
|
|
|
|
});
|