Files
admin-web/src/app/router/index.test.ts
T

155 lines
7.8 KiB
TypeScript

import { describe, expect, it } from 'vitest'
import { adminNavigation, getNavigationLeaves } from '@/core/navigation/adminNavigation'
import router from './index'
describe('admin router access metadata', () => {
it('uses the root route as a permission-aware entry point and registers the formal dashboard', () => {
const home = router.getRoutes().find((route) => route.name === 'home')
expect(home?.path).toBe('/')
expect(home?.meta.permission).toBeUndefined()
const dashboard = router.getRoutes().find((route) => route.name === 'dashboard')
expect(dashboard?.path).toBe('/dashboard')
expect(dashboard?.meta.permission).toBeUndefined()
})
it('protects warehouse management with its stable list permission', () => {
const warehouseRoute = router.getRoutes().find((route) => route.name === 'warehouses')
expect(warehouseRoute?.path).toBe('/warehouses')
expect(warehouseRoute?.meta.permission).toBe('platform:warehouse:list')
})
it('protects phase-two inbound operations and master data with deployed permissions', () => {
const expected = [
['inbound-orders', '/inbounds', 'platform:firstleg:inbound:list'],
['fba-carrier-rates', '/first-leg-pricing/carrier-rates', 'firstleg:fba-pricing:rate:view'],
['locations', '/master-data/locations', 'platform:location:list'],
['pallets', '/master-data/pallets', 'platform:pallet:list'],
]
for (const [name, path, permission] of expected) {
const route = router.getRoutes().find((item) => item.name === name)
expect(route?.path).toBe(path)
expect(route?.meta.permission).toBe(permission)
}
})
it('does not register removed duplicate pricing and FBA placeholder pages', () => {
const removedRouteNames = ['inbound-order-detail', 'fba-customer-rules', 'general-fba', 'general-voyage']
for (const name of removedRouteNames) {
expect(router.getRoutes().some((route) => route.name === name)).toBe(false)
}
})
it('protects express company records with a stable master-data permission', () => {
const route = router.getRoutes().find((item) => item.name === 'express-companies')
expect(route?.path).toBe('/master-data/express-companies')
expect(route?.meta.permission).toBe('platform:express:list')
})
it('keeps smart loading as an order dialog while retaining the single-container deep link', () => {
expect(router.getRoutes().some((item) => item.name === 'global-smart-loading-workbench')).toBe(false)
const detail = router.getRoutes().find((item) => item.name === 'smart-loading-workbench')
expect(detail?.path).toBe('/container-loading/domestic/:containerId/smart-loading')
expect(detail?.meta.permission).toBe('platform:firstleg:smart-loading:list')
})
it('registers the retained phase-three service center routes with stable permissions', () => {
const expected = [
['ocean-bookings', '/ocean-bookings', 'platform:firstleg:ocean-booking:list'],
['trucking', '/trucking', 'platform:firstleg:truck-appointment:list'],
]
for (const [name, path, permission] of expected) {
const route = router.getRoutes().find((item) => item.name === name)
expect(route?.path).toBe(path)
expect(route?.meta.permission).toBe(permission)
}
expect(router.getRoutes().find((item) => item.name === 'port-schedules')).toBeUndefined()
expect(router.getRoutes().find((item) => item.name === 'outbound-dispatches')).toBeUndefined()
})
it('protects counterparty records with a stable master-data permission', () => {
const route = router.getRoutes().find((item) => item.name === 'counterparties')
expect(route?.path).toBe('/master-data/counterparties')
expect(route?.meta.permission).toBe('platform:counterparty:list')
})
it('registers the confirmed phase-four routes with stable list permissions', () => {
const expected = [
['overseas-last-mile-orders', '/overseas-warehouse/last-mile-orders', 'platform:overseas-warehouse:last-mile-order:list'],
['overseas-inbound-orders', '/overseas-warehouse/inbound-orders', 'platform:overseas-warehouse:inbound-order:list'],
['overseas-dispatches', '/overseas-warehouse/dispatches', 'platform:overseas-warehouse:dispatch:list'],
['overseas-relabel-orders', '/overseas-warehouse/relabel-orders', 'platform:overseas-warehouse:relabel-order:list'],
['overseas-pallets', '/overseas-warehouse/pallets', 'platform:overseas-warehouse:pallet:list'],
['overseas-inventory', '/overseas-warehouse/inventory', 'platform:overseas-warehouse:inventory:list'],
['overseas-business-purchases', '/overseas-business/purchases', 'platform:overseas-business:purchase:list'],
['overseas-business-trucks', '/overseas-business/trucks', 'platform:overseas-business:truck:list'],
['overseas-business-looseboards', '/overseas-business/looseboards', 'platform:overseas-business:looseboard:list'],
['overseas-master-data-quotes', '/overseas-master-data/quotes', 'platform:overseas-master-data:quote:list'],
['overseas-master-data-exchange-rates', '/overseas-master-data/exchange-rates', 'platform:overseas-master-data:exchange-rate:list'],
['overseas-master-data-vehicles', '/overseas-master-data/vehicles', 'platform:overseas-master-data:vehicle:list'],
]
for (const [name, path, permission] of expected) {
const route = router.getRoutes().find((item) => item.name === name)
expect(route?.path).toBe(path)
expect(route?.meta.permission).toBe(permission)
}
})
it('protects the download center with its stable list permission', () => {
const route = router.getRoutes().find((item) => item.name === 'download-center')
expect(route?.path).toBe('/downloads')
expect(route?.meta.permission).toBe('platform:download:list')
})
it('registers message-center routes with the frozen IAM permissions', () => {
const expected = [
['notification-inbox', '/notifications', 'platform:notification:view'],
['notification-messages', '/notifications/messages', 'platform:notification:task:list'],
['notification-templates', '/notifications/templates', 'platform:notification:template:list'],
]
for (const [name, path, permission] of expected) {
const route = router.getRoutes().find((item) => item.name === name)
expect(route?.path).toBe(path)
expect(route?.meta.permission).toBe(permission)
}
expect(router.getRoutes().find((item) => item.name === 'my-notifications')).toBeUndefined()
})
it('redirects the removed enterprise review route to the protected customer list', () => {
const route = router.getRoutes().find((item) => item.name === 'enterprise-reviews')
expect(route?.path).toBe('/customers/reviews')
expect(route?.redirect).toBe('/customers')
expect(route?.meta.permission).toBe('platform:customer:list')
expect(route?.meta.permissionAnyOf).toContain('platform:customer:review')
})
it('keeps forbidden inside the authenticated layout without a business permission', () => {
const authenticatedLayout = router.options.routes.find((route) => route.path === '/')
const forbidden = authenticatedLayout?.children?.find((route) => route.name === 'forbidden')
const resolved = router.resolve('/403')
expect(authenticatedLayout?.meta?.requiresAuth).toBe(true)
expect(forbidden?.path).toBe('403')
expect(forbidden?.meta?.permission).toBeUndefined()
expect(resolved.matched.some((record) => record.meta.requiresAuth)).toBe(true)
})
it('keeps every registered navigation path and permission aligned with routes', () => {
for (const item of getNavigationLeaves(adminNavigation)) {
const resolved = router.resolve(item.path)
const pageRoute = resolved.matched.at(-1)
expect(pageRoute, `missing route for ${item.path}`).toBeDefined()
expect(pageRoute?.meta.permission, `permission mismatch for ${item.path}`).toBe(item.permission)
}
})
})