cbf8b4fb43
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
110 lines
4.2 KiB
TypeScript
110 lines
4.2 KiB
TypeScript
import { describe, expect, it } from 'vitest';
|
||
import { mapApiDeal } from '../../resources/js/composables/dealsApiMapper';
|
||
import type { ApiDeal } from '../../resources/js/api/deals';
|
||
|
||
describe('mapApiDeal', () => {
|
||
const baseApi: ApiDeal = {
|
||
id: 42,
|
||
tenant_id: 1,
|
||
project_id: 7,
|
||
project_name: 'Окна Москва',
|
||
phone: '+7 (999) 111-11-11',
|
||
contact_name: 'Анна С.',
|
||
status: 'new',
|
||
manager_id: 3,
|
||
manager_name: 'Иван П.',
|
||
manager_initials: 'ИП',
|
||
received_at: '2026-05-09T10:00:00Z',
|
||
comment: null,
|
||
city: null,
|
||
project_signal_type: null,
|
||
};
|
||
|
||
it('маппит обязательные поля 1:1', () => {
|
||
const m = mapApiDeal(baseApi, new Date('2026-05-09T10:30:00Z'));
|
||
expect(m.id).toBe(42);
|
||
expect(m.phone).toBe('+7 (999) 111-11-11');
|
||
expect(m.statusSlug).toBe('new');
|
||
expect(m.project).toBe('Окна Москва');
|
||
expect(m.manager.name).toBe('Иван П.');
|
||
expect(m.manager.initials).toBe('ИП');
|
||
});
|
||
|
||
it('name берёт contact_name; fallback на phone когда contact_name = null', () => {
|
||
const m1 = mapApiDeal(baseApi);
|
||
expect(m1.name).toBe('Анна С.');
|
||
|
||
const m2 = mapApiDeal({ ...baseApi, contact_name: null });
|
||
expect(m2.name).toBe('+7 (999) 111-11-11');
|
||
});
|
||
|
||
it('manager.name = «Не назначен» / initials = «—» если manager null', () => {
|
||
const m = mapApiDeal({ ...baseApi, manager_id: null, manager_name: null, manager_initials: null });
|
||
expect(m.manager.name).toBe('Не назначен');
|
||
expect(m.manager.initials).toBe('—');
|
||
});
|
||
|
||
it('project = «—» если project_name null', () => {
|
||
const m = mapApiDeal({ ...baseApi, project_name: null });
|
||
expect(m.project).toBe('—');
|
||
});
|
||
|
||
it("cost всегда 0 (отдельного endpoint'а пока нет)", () => {
|
||
const m = mapApiDeal(baseApi);
|
||
expect(m.cost).toBe(0);
|
||
});
|
||
|
||
it('receivedMinutesAgo вычисляется из received_at', () => {
|
||
const m = mapApiDeal(baseApi, new Date('2026-05-09T10:30:00Z'));
|
||
expect(m.receivedMinutesAgo).toBe(30);
|
||
});
|
||
|
||
it('receivedMinutesAgo не уходит в отрицательные числа при future timestamp', () => {
|
||
const m = mapApiDeal(baseApi, new Date('2026-05-09T09:00:00Z'));
|
||
expect(m.receivedMinutesAgo).toBe(0);
|
||
});
|
||
|
||
it('received_at = null → 0 минут (используем "сейчас")', () => {
|
||
const m = mapApiDeal({ ...baseApi, received_at: null }, new Date('2026-05-09T10:30:00Z'));
|
||
expect(m.receivedMinutesAgo).toBe(0);
|
||
});
|
||
|
||
it('mapApiDeal переносит city/comment/signalType/receivedAt', () => {
|
||
const iso = '2026-05-15T09:00:00+00:00';
|
||
const result = mapApiDeal({
|
||
id: 7,
|
||
tenant_id: 1,
|
||
project_id: 2,
|
||
project_name: 'Окна',
|
||
phone: '+7 999 000-00-00',
|
||
contact_name: null,
|
||
status: 'new',
|
||
manager_id: null,
|
||
manager_name: null,
|
||
manager_initials: null,
|
||
received_at: iso,
|
||
comment: 'звонил клиент',
|
||
city: 'Москва',
|
||
project_signal_type: 'call',
|
||
});
|
||
expect(result.city).toBe('Москва');
|
||
expect(result.comment).toBe('звонил клиент');
|
||
expect(result.signalType).toBe('call');
|
||
expect(result.receivedAt).toBe(iso);
|
||
});
|
||
|
||
// F2 (17.06.2026): costKopecks — снимок rub-списания из cost_kopecks API.
|
||
it('costKopecks берётся из cost_kopecks (rub-списание)', () => {
|
||
const m = mapApiDeal({ ...baseApi, cost_kopecks: 50000 });
|
||
expect(m.costKopecks).toBe(50000);
|
||
});
|
||
|
||
it('costKopecks = null если cost_kopecks null/отсутствует', () => {
|
||
const m1 = mapApiDeal({ ...baseApi, cost_kopecks: null });
|
||
expect(m1.costKopecks).toBeNull();
|
||
|
||
const m2 = mapApiDeal(baseApi);
|
||
expect(m2.costKopecks).toBeNull();
|
||
});
|
||
});
|