Files
portal/app/tests/Frontend/DealDetailBody.spec.ts
T
Дмитрий 4d8a1af099 feat(deals): карточка показывает реальную стоимость лида — F2
Backend: GET /api/deals/{id} отдаёт cost_kopecks — снимок rub-списания из
lead_charges по deal_id, либо null для prepaid/не списано. Frontend: ApiDeal.cost_kopecks
→ MockDeal.costKopecks → карточка DealDetailBody показывает formatCost(costKopecks/100)
либо прочерк вместо вводящего в заблуждение 0 рублей. TDD: 3 Pest + 4 vitest.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-17 13:30:46 +03:00

144 lines
5.3 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 { 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> = {}): 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 ₽');
});
});