82 lines
3.4 KiB
TypeScript
82 lines
3.4 KiB
TypeScript
|
|
import { describe, it, expect, beforeEach, vi } from 'vitest';
|
|||
|
|
import { mount } from '@vue/test-utils';
|
|||
|
|
import { createVuetify } from 'vuetify';
|
|||
|
|
|
|||
|
|
vi.mock('../../resources/js/api/admin');
|
|||
|
|
import AdminAutopodborPricingView from '../../resources/js/views/admin/AdminAutopodborPricingView.vue';
|
|||
|
|
import { listSystemSettings, updateSystemSetting, getPricingTiers } from '../../resources/js/api/admin';
|
|||
|
|
|
|||
|
|
const vuetify = createVuetify();
|
|||
|
|
|
|||
|
|
function settings(search = '300', study = '50') {
|
|||
|
|
return [
|
|||
|
|
{ key: 'autopodbor_price_search_rub', value: search, type: 'decimal', description: null, updated_at: '', updated_by: null },
|
|||
|
|
{ key: 'autopodbor_price_study_rub', value: study, type: 'decimal', description: null, updated_at: '', updated_by: null },
|
|||
|
|
{ key: 'other_key', value: '1', type: 'int', description: null, updated_at: '', updated_by: null },
|
|||
|
|
];
|
|||
|
|
}
|
|||
|
|
function tiers() {
|
|||
|
|
return {
|
|||
|
|
active: [{ tier_no: 1, leads_in_tier: 100, price_per_lead_kopecks: 50000, effective_from: '2026-06-01' }],
|
|||
|
|
scheduled: {},
|
|||
|
|
};
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
function mountV() {
|
|||
|
|
return mount(AdminAutopodborPricingView, { global: { plugins: [vuetify] } });
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
describe('AdminAutopodborPricingView', () => {
|
|||
|
|
beforeEach(() => {
|
|||
|
|
vi.clearAllMocks();
|
|||
|
|
vi.mocked(listSystemSettings).mockResolvedValue(settings() as any);
|
|||
|
|
vi.mocked(getPricingTiers).mockResolvedValue(tiers() as any);
|
|||
|
|
vi.mocked(updateSystemSetting).mockResolvedValue({} as any);
|
|||
|
|
});
|
|||
|
|
|
|||
|
|
it('грузит текущие тарифы доп.услуг из system-settings', async () => {
|
|||
|
|
const w = mountV();
|
|||
|
|
await new Promise((r) => setTimeout(r, 0));
|
|||
|
|
expect(listSystemSettings).toHaveBeenCalled();
|
|||
|
|
expect((w.vm as any).searchPrice).toBe('300');
|
|||
|
|
expect((w.vm as any).studyPrice).toBe('50');
|
|||
|
|
});
|
|||
|
|
|
|||
|
|
it('показывает сетку лидов для справки', async () => {
|
|||
|
|
const w = mountV();
|
|||
|
|
await new Promise((r) => setTimeout(r, 0));
|
|||
|
|
expect(w.text()).toContain('Тариф на лиды');
|
|||
|
|
expect(w.text()).toContain('500'); // 50000 коп = 500 ₽
|
|||
|
|
});
|
|||
|
|
|
|||
|
|
it('сохранение изменённой цены зовёт updateSystemSetting с value и reason', async () => {
|
|||
|
|
const w = mountV();
|
|||
|
|
await new Promise((r) => setTimeout(r, 0));
|
|||
|
|
(w.vm as any).searchPrice = '350';
|
|||
|
|
await (w.vm as any).save();
|
|||
|
|
expect(updateSystemSetting).toHaveBeenCalledWith(
|
|||
|
|
'autopodbor_price_search_rub',
|
|||
|
|
expect.objectContaining({ value: '350' }),
|
|||
|
|
);
|
|||
|
|
expect(updateSystemSetting).not.toHaveBeenCalledWith('autopodbor_price_study_rub', expect.anything());
|
|||
|
|
});
|
|||
|
|
|
|||
|
|
it('причина короче 30 символов блокирует сохранение', async () => {
|
|||
|
|
const w = mountV();
|
|||
|
|
await new Promise((r) => setTimeout(r, 0));
|
|||
|
|
(w.vm as any).searchPrice = '350';
|
|||
|
|
(w.vm as any).reason = 'мало';
|
|||
|
|
await (w.vm as any).save();
|
|||
|
|
expect(updateSystemSetting).not.toHaveBeenCalled();
|
|||
|
|
expect((w.vm as any).errorMessage).toContain('30');
|
|||
|
|
});
|
|||
|
|
|
|||
|
|
it('без изменений не зовёт сохранение', async () => {
|
|||
|
|
const w = mountV();
|
|||
|
|
await new Promise((r) => setTimeout(r, 0));
|
|||
|
|
await (w.vm as any).save();
|
|||
|
|
expect(updateSystemSetting).not.toHaveBeenCalled();
|
|||
|
|
expect((w.vm as any).errorMessage).toBeTruthy();
|
|||
|
|
});
|
|||
|
|
});
|