f65b2ca8d8
- AdminBillingView: 4 stats (MRR, Выручка, Просрочка, Возвраты) + v-data-table 7 колонок (Тенант с ИНН / Тариф / Баланс с error-color / пополнения / списания / MRR / Статус-chip) + поиск
- AdminIncidentsView: 3 stats + 5 фильтров статуса + v-list с incident_id (INC-YYYY-MMDD-NNNN) + severity/status/РКН-pending chips + дедлайн 24ч по 152-ФЗ
- AdminSystemView: read-only warning + поиск + v-list 7 system_settings (webhook_rate_limit, login_max_attempts, retention и т.д.) с type-chip и updated_at
- composables/mockAdmin.ts: AdminBillingTenantRow + AdminIncidentRow + AdminSystemSetting + mock-данные
- Router: /admin/{billing,incidents,system} → реальные views (не placeholder)
- Vitest +13 (179/179 за 11.98с)
- TODO: edit-flow для system_settings + backend /api/admin/* endpoints
- Регресс: lint+type+format OK; build 743ms; story:build 21/28 за 31.5с
- CLAUDE.md v1.42→v1.43, реестр v1.51→v1.52
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
53 lines
2.0 KiB
TypeScript
53 lines
2.0 KiB
TypeScript
import { describe, it, expect } from 'vitest';
|
|
import { mount } from '@vue/test-utils';
|
|
import { createVuetify } from 'vuetify';
|
|
import { createRouter, createMemoryHistory } from 'vue-router';
|
|
import AdminSystemView from '../../resources/js/views/admin/AdminSystemView.vue';
|
|
|
|
const mountView = async () => {
|
|
const router = createRouter({
|
|
history: createMemoryHistory(),
|
|
routes: [{ path: '/admin/system', component: AdminSystemView }],
|
|
});
|
|
await router.push('/admin/system');
|
|
await router.isReady();
|
|
return mount(AdminSystemView, {
|
|
global: { plugins: [createVuetify(), router] },
|
|
});
|
|
};
|
|
|
|
describe('AdminSystemView.vue', () => {
|
|
it('монтируется и содержит заголовок «Система»', async () => {
|
|
const wrapper = await mountView();
|
|
expect(wrapper.text()).toContain('Система');
|
|
});
|
|
|
|
it('показывает read-only warning', async () => {
|
|
const wrapper = await mountView();
|
|
expect(wrapper.text()).toContain('Read-only');
|
|
});
|
|
|
|
it('перечисляет ключевые system_settings (rate-limit, retention, login_max_attempts)', async () => {
|
|
const wrapper = await mountView();
|
|
const text = wrapper.text();
|
|
expect(text).toContain('webhook_rate_limit_rps');
|
|
expect(text).toContain('login_max_attempts');
|
|
expect(text).toContain('password_min_length');
|
|
expect(text).toContain('webhook_log_retention_days');
|
|
expect(text).toContain('maintenance_mode');
|
|
});
|
|
|
|
it('содержит type-chip для каждой строки (int/string/bool/json)', async () => {
|
|
const wrapper = await mountView();
|
|
const text = wrapper.text();
|
|
expect(text).toContain('int');
|
|
expect(text).toContain('bool');
|
|
});
|
|
|
|
it('число строк settings = 7 (mock count)', async () => {
|
|
const wrapper = await mountView();
|
|
const rows = wrapper.findAll('[data-testid="setting-row"]');
|
|
expect(rows.length).toBe(7);
|
|
});
|
|
});
|