Files
portal/app/tests/Frontend/AppShell.spec.ts
T
Дмитрий 1d1353931d phase2(user-chip): реальный user в AppLayout/AdminLayout + Logout-menu
- AppLayout: userInitials/userShortName computed из auth-store, fallback цепочка → email → '?' / 'Гость'
- AdminLayout: тот же паттерн с админ-defaults 'АО' / 'Админ Оператор'
- v-menu offset=8 на user-chip: email + Настройки/Выйти из админки + Выйти
- handleLogout async: auth.logout() (swallows API errors) → router.push('/login')
- Vitest +3 в AppLayout.spec.ts (всего 145/145): store-mock + null-user + email-fallback
- AppShell.spec.ts получил createPinia в plugins
- Регресс: lint+type+format OK, vitest 145/145 за 11.01с, build 855ms, story:build 21/28 за 32.11с, Pest 67/67 за 6.16с
- CLAUDE.md v1.34→v1.35, реестр v1.43→v1.44

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-08 20:29:05 +03:00

55 lines
2.6 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 { createPinia } from 'pinia';
import { createVuetify } from 'vuetify';
import { createRouter, createMemoryHistory } from 'vue-router';
import AppShell from '../../resources/js/components/AppShell.vue';
// AppShell — layout-mapper по route.meta.layout: 'app' (default) → AppLayout, 'auth' → AuthLayout.
const mountWithRouter = async (path: string) => {
const router = createRouter({
history: createMemoryHistory(),
routes: [
{ path: '/', redirect: '/dashboard' },
{ path: '/dashboard', component: { template: '<div>dashboard</div>' }, meta: { layout: 'app' } },
{ path: '/login', component: { template: '<div>login stub</div>' }, meta: { layout: 'auth' } },
// Stub'ы для всех nav-targets AppLayout, чтобы избежать router-warn'ов.
{ path: '/deals', component: { template: '<div />' } },
{ path: '/kanban', component: { template: '<div />' } },
{ path: '/reminders', component: { template: '<div />' } },
{ path: '/billing', component: { template: '<div />' } },
{ path: '/reports', component: { template: '<div />' } },
{ path: '/managers', component: { template: '<div />' } },
{ path: '/settings', component: { template: '<div />' } },
],
});
await router.push(path);
await router.isReady();
return mount(AppShell, {
global: { plugins: [createPinia(), createVuetify(), router] },
});
};
describe('AppShell.vue', () => {
it('монтируется без ошибок', async () => {
const wrapper = await mountWithRouter('/dashboard');
expect(wrapper.exists()).toBe(true);
});
it('рендерит AppLayout на default-layout (sidebar с brand + nav)', async () => {
const wrapper = await mountWithRouter('/dashboard');
expect(wrapper.text()).toContain('Лидерра');
// Sidebar nav-группы и пункты — признак AppLayout.
expect(wrapper.text()).toContain('Дашборд');
expect(wrapper.text()).toContain('Сделки');
});
it('переключается на AuthLayout при meta.layout = auth', async () => {
const wrapper = await mountWithRouter('/login');
// На auth-layout sidebar не рендерится — нет nav-пунктов «Сделки»/«Дашборд».
expect(wrapper.text()).not.toContain('Сделки');
expect(wrapper.text()).not.toContain('Дашборд');
});
});