664427ce7a
Единственное место с обращением на «ты» переведено на «вы» (У вас…, пополните/поставьте/уменьшите). В окно добавлена кнопка «Пополнить баланс», которая закрывает окно и ведёт в /billing (онлайн-оплата ждёт Б-1, но вход в пополнение теперь под рукой). Логику/цифры не трогал. vitest: текст-на-вы + переход в /billing, 7 passed. Проверено глазами на 8000. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
87 lines
3.6 KiB
TypeScript
87 lines
3.6 KiB
TypeScript
import { describe, it, expect, vi } from 'vitest';
|
||
import { mount } from '@vue/test-utils';
|
||
import { createVuetify } from 'vuetify';
|
||
import { createRouter, createMemoryHistory } from 'vue-router';
|
||
import ProjectLimitOverloadDialog from '../../resources/js/components/projects/ProjectLimitOverloadDialog.vue';
|
||
|
||
// Billing v2 Spec C Task 1.10 — диалог перегрузки лимита (§6.2). Принимает
|
||
// 409-payload `balance_insufficient`, эмитит решение пользователя.
|
||
|
||
const payload = {
|
||
current_balance_rub: '1000.00',
|
||
current_capacity_leads: 30,
|
||
would_be_required_leads: 50,
|
||
deficit_leads: 20,
|
||
};
|
||
|
||
const mountDialog = () =>
|
||
mount(ProjectLimitOverloadDialog, {
|
||
props: { modelValue: true, payload },
|
||
global: {
|
||
plugins: [createVuetify()],
|
||
stubs: { VDialog: { template: '<div><slot /></div>' } },
|
||
},
|
||
});
|
||
|
||
describe('ProjectLimitOverloadDialog', () => {
|
||
it('рендерит данные 409-payload', () => {
|
||
const w = mountDialog();
|
||
const text = w.text();
|
||
expect(text).toContain('1000.00');
|
||
expect(text).toContain('30');
|
||
expect(text).toContain('50');
|
||
expect(text).toContain('20');
|
||
});
|
||
|
||
it('«Сохранить и приостановить» эмитит save-blocked', async () => {
|
||
const w = mountDialog();
|
||
await w.find('[data-testid="overload-save-blocked"]').trigger('click');
|
||
expect(w.emitted('save-blocked')).toBeTruthy();
|
||
});
|
||
|
||
it('«Поставить лимит 0» эмитит set-zero', async () => {
|
||
const w = mountDialog();
|
||
await w.find('[data-testid="overload-set-zero"]').trigger('click');
|
||
expect(w.emitted('set-zero')).toBeTruthy();
|
||
});
|
||
|
||
it('«Отмена» закрывает диалог (update:modelValue=false)', async () => {
|
||
const w = mountDialog();
|
||
await w.find('[data-testid="overload-cancel"]').trigger('click');
|
||
expect(w.emitted('update:modelValue')?.[0]).toEqual([false]);
|
||
});
|
||
|
||
it('косяк 06: текст на «вы», без «ты»', () => {
|
||
const w = mountDialog();
|
||
const text = w.text();
|
||
expect(text).toContain('У вас');
|
||
expect(text).not.toContain('У тебя');
|
||
expect(text).not.toContain('пополни ');
|
||
expect(text).not.toContain('поставь ');
|
||
expect(text).not.toContain('уменьши ');
|
||
});
|
||
|
||
it('косяк 06: «Пополнить баланс» закрывает окно и ведёт в /billing', async () => {
|
||
const router = createRouter({
|
||
history: createMemoryHistory(),
|
||
routes: [{ path: '/billing', component: { template: '<div>billing</div>' } }],
|
||
});
|
||
const push = vi.spyOn(router, 'push');
|
||
const w = mount(ProjectLimitOverloadDialog, {
|
||
props: { modelValue: true, payload },
|
||
global: { plugins: [createVuetify(), router], stubs: { VDialog: { template: '<div><slot /></div>' } } },
|
||
});
|
||
await w.find('[data-testid="overload-topup"]').trigger('click');
|
||
expect(w.emitted('update:modelValue')?.[0]).toEqual([false]);
|
||
expect(push).toHaveBeenCalledWith('/billing');
|
||
});
|
||
|
||
it('payload=null — без падения, ничего не рендерит', () => {
|
||
const w = mount(ProjectLimitOverloadDialog, {
|
||
props: { modelValue: true, payload: null },
|
||
global: { plugins: [createVuetify()], stubs: { VDialog: { template: '<div><slot /></div>' } } },
|
||
});
|
||
expect(w.find('[data-testid="overload-save-blocked"]').exists()).toBe(false);
|
||
});
|
||
});
|