feat(layout): Plan 2.5 P1 foundation — APP_NAVIGATION + walkNavTree + AppBreadcrumb
Per RFC-WS-PRIMEVUE-PLAN-2-5 §8 step 1. Foundation scaffolding only — no shell fixes, no Public Sans removal, no useShellUiStore changes (P2–P6 scope). Implements: - theme darkModeSelector verified at '.dark' (already correct in plugins/primevue/index.ts — config site is here, not theme.ts). - src/config/navigation.ts: APP_NAVIGATION registry per AD-2.5-B1 (Dashboard entry only — v2-dashboard is the only v2 route today). - src/composables/useBreadcrumb.ts: walkNavTree pure helper + useNavBreadcrumb composable per AD-2.5-B1. The legacy meta-based useBreadcrumb is preserved (consumed by AppTopbar, P1 may not touch AppTopbar); P4 retires it and renames useNavBreadcrumb. - src/components-v2/layout/AppBreadcrumb.vue: layout primitive wrapping PrimeVue Breadcrumb, consuming useNavBreadcrumb. - Tests: walkNavTree (4 specs, co-located), AppBreadcrumb mount (2 specs, tests/component/layouts/). Suite 564 → 570 (+6, all new specs green). vue-tsc clean. Scoped ESLint clean. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
59
apps/app/tests/component/layouts/AppBreadcrumb.spec.ts
Normal file
59
apps/app/tests/component/layouts/AppBreadcrumb.spec.ts
Normal file
@@ -0,0 +1,59 @@
|
||||
// AppBreadcrumb component spec — RFC-WS-PRIMEVUE-PLAN-2-5 AD-2.5-B1.
|
||||
//
|
||||
// Verifies the foundation primitive renders breadcrumb items derived
|
||||
// from APP_NAVIGATION via useNavBreadcrumb. P1 only checks the matched
|
||||
// and unmatched-route paths; integration into AppTopbar is P5 scope.
|
||||
//
|
||||
// Path follows the existing convention (sibling to AppShellV2.spec.ts /
|
||||
// OrganizerLayoutV2.spec.ts under apps/app/tests/component/layouts/).
|
||||
|
||||
import { describe, expect, it } from 'vitest'
|
||||
import { mount } from '@vue/test-utils'
|
||||
import { defineComponent } from 'vue'
|
||||
import { createMemoryHistory, createRouter } from 'vue-router'
|
||||
import PrimeVue from 'primevue/config'
|
||||
import AppBreadcrumb from '@/components-v2/layout/AppBreadcrumb.vue'
|
||||
|
||||
const StubRouteComponent = defineComponent({ template: '<div />' })
|
||||
|
||||
function makeRouter(initialRouteName: string | null) {
|
||||
const router = createRouter({
|
||||
history: createMemoryHistory(),
|
||||
routes: [
|
||||
{ path: '/', name: 'v2-dashboard', component: StubRouteComponent },
|
||||
{ path: '/none', name: 'nonexistent', component: StubRouteComponent },
|
||||
],
|
||||
})
|
||||
|
||||
if (initialRouteName)
|
||||
router.push({ name: initialRouteName })
|
||||
|
||||
return router
|
||||
}
|
||||
|
||||
describe('AppBreadcrumb (AD-2.5-B1)', () => {
|
||||
it('renders the Dashboard label for the v2-dashboard route', async () => {
|
||||
const router = makeRouter('v2-dashboard')
|
||||
|
||||
await router.isReady()
|
||||
|
||||
const wrapper = mount(AppBreadcrumb, {
|
||||
global: { plugins: [router, PrimeVue] },
|
||||
})
|
||||
|
||||
expect(wrapper.text()).toContain('Dashboard')
|
||||
})
|
||||
|
||||
it('renders no breadcrumb items when the route is unmatched', async () => {
|
||||
const router = makeRouter('nonexistent')
|
||||
|
||||
await router.isReady()
|
||||
|
||||
const wrapper = mount(AppBreadcrumb, {
|
||||
global: { plugins: [router, PrimeVue] },
|
||||
})
|
||||
|
||||
// PrimeVue Breadcrumb renders its items as <li>; an empty model → 0 items.
|
||||
expect(wrapper.findAll('li')).toHaveLength(0)
|
||||
})
|
||||
})
|
||||
Reference in New Issue
Block a user