Files
Aether/frontend/src/layouts/main-layout/__tests__/navigation.spec.ts
T
elky 066ea87d72 feat: revamp analytics dashboards and harden database migrations
Add dashboard and overview analytics, health monitoring, provider expense tracking, and announcement updates across the gateway and frontend.

Keep schema migrations free of historical backfills while preserving automatic backfill execution. Bound migration deadlines, run schema preparation before Compose replacement, and anonymize deleted dashboard users.

Include the current documentation cleanup and regression coverage.
2026-10-01 11:48:17 +08:00

229 lines
7.0 KiB
TypeScript

import { describe, expect, it } from 'vitest'
import type { RouteLocationNormalizedLoaded } from 'vue-router'
import { buildBreadcrumbs, buildNavigation } from '@/layouts/main-layout/navigation'
import type { MessageKey } from '@/i18n'
const translate = (key: MessageKey) => `tx:${key}`
function route(path: string, name?: string, meta: Record<string, unknown> = {}): RouteLocationNormalizedLoaded {
return {
path,
fullPath: path,
query: {},
hash: '',
name,
params: {},
matched: [],
meta,
redirectedFrom: undefined,
} as RouteLocationNormalizedLoaded
}
describe('main layout navigation builder', () => {
it('builds user navigation from translation keys and active modules', () => {
const navigation = buildNavigation({
canAccessAdmin: false,
modules: {},
isModuleActive: (name) => name === 'referral',
t: translate,
})
expect(navigation.map(group => group.title)).toEqual([
'tx:nav.group.overview',
'tx:nav.group.resources',
'tx:nav.group.account',
])
expect(navigation.flatMap(group => group.items.map(item => item.name))).toContain('tx:nav.myReferral')
})
it('exposes remote control to users and active administrators', () => {
const userNavigation = buildNavigation({
canAccessAdmin: false,
modules: {},
isModuleActive: () => false,
t: translate,
})
const adminNavigation = buildNavigation({
canAccessAdmin: true,
modules: {
vscodex: {
active: true,
name: 'test-module',
available: true,
enabled: true,
config_validated: true,
config_error: null,
description: '',
category: 'integration',
health: 'healthy',
admin_route: '/dashboard/vscodex',
admin_menu_group: 'overview',
admin_menu_order: 80,
admin_menu_icon: 'SquareTerminal',
display_name: '远程控制',
},
},
isModuleActive: () => false,
t: translate,
})
const findVscodeControl = (navigation: ReturnType<typeof buildNavigation>) => (
navigation
.flatMap(group => group.items)
.find(item => item.href === '/dashboard/vscodex')
)
expect(findVscodeControl(userNavigation)).toMatchObject({
name: 'tx:nav.vscodex',
href: '/dashboard/vscodex',
})
expect(findVscodeControl(adminNavigation)).toMatchObject({
name: '远程控制',
href: '/dashboard/vscodex',
})
const overviewItems = adminNavigation.find(group => group.title === 'tx:nav.group.overview')?.items ?? []
expect(overviewItems.findIndex(item => item.name === '远程控制')).toBe(
overviewItems.findIndex(item => item.name === 'tx:nav.healthMonitor') + 1,
)
})
it('keeps the five fixed overview destinations in product order', () => {
const navigation = buildNavigation({ canAccessAdmin: true, modules: {}, isModuleActive: () => false })
expect(navigation[0]?.items.map(item => item.href)).toEqual([
'/admin/dashboard', '/admin/operations', '/admin/user-stats', '/admin/cost-analysis', '/admin/health-monitor',
])
})
it('builds admin navigation with dynamic module menu items sorted by menu order', () => {
const navigation = buildNavigation({
canAccessAdmin: true,
modules: {
first: {
active: true,
name: 'test-module',
available: true,
enabled: true,
config_validated: true,
config_error: null,
description: '',
category: 'integration',
health: 'healthy',
admin_route: '/admin/first',
admin_menu_group: 'management',
admin_menu_order: 2,
admin_menu_icon: 'Gift',
display_name: 'First module',
},
second: {
active: true,
name: 'test-module',
available: true,
enabled: true,
config_validated: true,
config_error: null,
description: '',
category: 'integration',
health: 'healthy',
admin_route: '/admin/second',
admin_menu_group: 'management',
admin_menu_order: 1,
admin_menu_icon: 'Key',
display_name: 'Second module',
},
},
isModuleActive: () => false,
t: translate,
})
const managementItems = navigation.find(group => group.title === 'tx:nav.group.management')?.items ?? []
expect(managementItems.map(item => item.name)).toEqual(expect.arrayContaining(['Second module', 'First module']))
expect(managementItems.findIndex(item => item.name === 'Second module')).toBeLessThan(
managementItems.findIndex(item => item.name === 'First module')
)
})
it('builds translated breadcrumbs for settings and routing detail pages', () => {
const navigation = buildNavigation({
canAccessAdmin: true,
modules: {},
isModuleActive: () => false,
t: translate,
})
expect(buildBreadcrumbs({
route: route('/dashboard/settings'),
navigation,
modules: {},
isNavActive: () => false,
t: translate,
})).toEqual([
{ label: 'tx:nav.group.account' },
{ label: 'tx:breadcrumb.personalSettings' },
])
expect(buildBreadcrumbs({
route: route('/admin/routing/new', 'RoutingProfileCreate'),
navigation,
modules: {},
isNavActive: href => href === '/admin/routing',
t: translate,
})).toEqual([
{ label: 'tx:nav.group.management' },
{ label: 'tx:nav.routing', href: '/admin/routing' },
{ label: 'tx:breadcrumb.routingCreate' },
])
expect(buildBreadcrumbs({
route: route('/dashboard/vscodex'),
navigation: buildNavigation({
canAccessAdmin: true,
modules: {
vscodex: {
active: true,
name: 'test-module',
available: true,
enabled: true,
config_validated: true,
config_error: null,
description: '',
category: 'integration',
health: 'healthy',
admin_route: '/dashboard/vscodex',
admin_menu_group: 'overview',
admin_menu_order: 80,
admin_menu_icon: 'SquareTerminal',
display_name: '远程控制',
},
},
isModuleActive: () => false,
t: translate,
}),
modules: {
vscodex: {
active: true,
name: 'test-module',
available: true,
enabled: true,
config_validated: true,
config_error: null,
description: '',
category: 'integration',
health: 'healthy',
admin_route: '/dashboard/vscodex',
admin_menu_group: 'overview',
admin_menu_order: 80,
admin_menu_icon: 'SquareTerminal',
display_name: '远程控制',
},
},
isNavActive: href => href === '/dashboard/vscodex',
t: translate,
})).toEqual([
expect.objectContaining({ label: expect.any(String) }),
{ label: '远程控制' },
])
})
})