V13-FE-006: consolidate approved UI and contract hardening
This commit is contained in:
@@ -0,0 +1,9 @@
|
||||
export type RouteAccessMeta = {
|
||||
readonly permissions?: readonly string[]
|
||||
}
|
||||
|
||||
/** UI visibility hint only; the API remains the authorization authority. */
|
||||
export function canAccessRoute(meta: RouteAccessMeta, grantedPermissions: ReadonlySet<string>): boolean {
|
||||
const required = meta.permissions ?? []
|
||||
return required.every(permission => grantedPermissions.has(permission))
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
import { describe, expect, it } from 'vitest'
|
||||
import { canAccessRoute } from '../routeAccess'
|
||||
import { router } from '../../../app/router'
|
||||
import { modelsDetailScreen, modelsListScreen } from '../../../features/models/registry'
|
||||
import { shadowRunDetailScreen, shadowRunListScreen } from '../../../features/shadow-run/registry'
|
||||
|
||||
describe('route access contract', () => {
|
||||
it('allows routes without a declared permission', () => {
|
||||
expect(canAccessRoute({}, new Set())).toBe(true)
|
||||
})
|
||||
|
||||
it('requires every declared permission', () => {
|
||||
expect(canAccessRoute({ permissions: ['model.read'] }, new Set())).toBe(false)
|
||||
expect(canAccessRoute({ permissions: ['model.read'] }, new Set(['model.read']))).toBe(true)
|
||||
})
|
||||
|
||||
it('keeps active ModelOps route metadata aligned with feature registries', () => {
|
||||
const registered = [modelsListScreen, modelsDetailScreen, shadowRunListScreen, shadowRunDetailScreen]
|
||||
for (const screen of registered) {
|
||||
const route = router.getRoutes().find(candidate => candidate.path === screen.path)
|
||||
expect(route?.meta.permissions).toEqual(screen.permissions)
|
||||
}
|
||||
})
|
||||
})
|
||||
Reference in New Issue
Block a user