Files
portal/app/tests/Frontend/AppShell.spec.ts
T
Дмитрий e909a95a8d phase2(login): vue-router 4 + AuthLayout + LoginView - первый реальный экран
- vue-router@^4.6.4 (--legacy-peer-deps из-за Histoire vs Vite 8 peerDep).
- resources/js/router/index.ts: createWebHistory + lazy-imports + meta.layout.
  Маршрут / -> /login, /login -> LoginView (meta.layout=auth).
- resources/js/layouts/AuthLayout.vue: двухпанельный (brand-pane тёмный с
  radial-gradient акцентами + form-pane warm ivory). На mobile brand-pane скрыт.
- resources/js/views/auth/LoginView.vue: форма Vuetify по v8_login.html
  секция #form-login - email/password (autocomplete + eye-icon), primary submit,
  Yandex 360 SSO, RouterLink на /register и /forgot.
- AppShell.vue: layout-mapper по route.meta.layout (default/auth).
- routes/web.php: явные Route::view для 6 SPA-путей (НЕ catch-all - он перехватывал
  /_test/* в Pest beforeEach и валил 5 SetTenantContextTest).
- Vitest: +LoginView.spec.ts (5), +router.spec.ts (2), AppShell.spec.ts переписан (3).
  Vitest 10/10 за 3.01s.
- LoginView.story.vue для Histoire. Setup расширен memory-router'ом.
- cspell-words.txt: рендерят, коммиты, Лидерру.
- Регресс: lint:vue OK, type-check OK, format:check OK, vitest 10/10,
  vite build 212 модулей за 383ms (LoginView lazy-chunk 43.5KB JS / 51.7KB CSS),
  story:build 2/2 за 29.94s, Pest 48/48 за 4.86s.

CLAUDE.md v1.18->v1.19, реестр Открытых_вопросов v1.27->v1.28.

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

46 lines
1.9 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 AppShell from '../../resources/js/components/AppShell.vue';
// AppShell мапит meta.layout текущего route'а на layout-компонент.
// На default-layout рендерит v-app + v-app-bar; на 'auth' — AuthLayout.
const mountWithRouter = async (path: string, defaultMeta: Record<string, unknown> = {}) => {
const router = createRouter({
history: createMemoryHistory(),
routes: [
{ path: '/', redirect: '/test' },
{ path: '/test', component: { template: '<div>test view</div>' }, meta: defaultMeta },
{ path: '/login', component: { template: '<div>login stub</div>' }, meta: { layout: 'auth' } },
],
});
await router.push(path);
await router.isReady();
return mount(AppShell, {
global: {
plugins: [createVuetify(), router],
},
});
};
describe('AppShell.vue', () => {
it('монтируется без ошибок на default-layout', async () => {
const wrapper = await mountWithRouter('/test');
expect(wrapper.exists()).toBe(true);
});
it('рендерит брендовое имя и chip фазы на default-layout', async () => {
const wrapper = await mountWithRouter('/test');
expect(wrapper.text()).toContain('Лидерра.');
expect(wrapper.text()).toContain('phase 2');
});
it('переключается на AuthLayout при meta.layout = auth', async () => {
const wrapper = await mountWithRouter('/login');
// На auth-layout shell не показывает app-bar и phase-chip — рендерится AuthLayout.
expect(wrapper.text()).not.toContain('phase 2');
});
});