Files
TREK/client/src/managed/index.test.ts
T
Maurice f2329c9a63 feat(client): let a managed surface attach as an admin tab
The nav-entry seam was the wrong shape for what actually attaches here. A
subscription surface is about the install, not about a trip: /admin is already
behind an admin check, already grouped, and already where somebody looks to
change how their instance works. A top-level nav entry put it beside My Trips
for a screen opened once a month by one person.

Two lines in AdminPage rather than an overlay replacing the file: the tab list
gets the extra entries appended per group, and the body renders whichever one is
active. Appended rather than inserted because PageSidebar needs a group's tabs
contiguous.

The route and nav-entry seams stay. They are the right answer for a surface that
genuinely is a page, and both remain empty here.
2026-08-15 18:07:21 +02:00

67 lines
2.5 KiB
TypeScript

/**
* The attachment point is empty here, and the filter over it is the one piece of
* logic it does carry — so it is the one piece worth testing.
*
* The emptiness matters on its own: this is the seam where an install can attach
* its own screens, and the promise to everyone else is that a build of this
* repository carries none of them.
*/
import { describe, it, expect } from 'vitest'
import { Briefcase } from 'lucide-react'
import {
managedAdminTabs,
managedNavItems,
managedRoutes,
visibleManagedNavItems,
type ManagedNavItem,
} from './index'
describe('managed attachment point', () => {
it('FE-MANAGED-001: ships empty, so the public build registers nothing', () => {
expect(managedRoutes).toEqual([])
expect(managedNavItems).toEqual([])
expect(managedAdminTabs).toEqual([])
})
it('FE-MANAGED-002: an empty list stays empty for either kind of user', () => {
// The nav bars call this unconditionally. If it ever returned anything here,
// every install would grow an entry nobody asked for.
expect(visibleManagedNavItems(true)).toEqual([])
expect(visibleManagedNavItems(false)).toEqual([])
})
})
describe('visibleManagedNavItems', () => {
const item = (over: Partial<ManagedNavItem>): ManagedNavItem => ({
id: 'x',
path: '/x',
label: 'X',
Icon: Briefcase,
...over,
})
// The function is exported and takes its list implicitly, so exercise the rule
// directly rather than mutating the module constant.
const apply = (items: ManagedNavItem[], isAdmin: boolean) =>
items.filter((i) => !i.adminOnly || isAdmin).map((i) => i.id)
it('FE-MANAGED-003: an adminOnly entry is offered to an admin and nobody else', () => {
const items = [item({ id: 'billing', adminOnly: true })]
expect(apply(items, true)).toEqual(['billing'])
expect(apply(items, false)).toEqual([])
})
it('FE-MANAGED-004: without the flag an entry is for everyone', () => {
// Absent means "for everyone", not "for nobody" — a missing flag must not
// silently hide a screen somebody attached on purpose.
const items = [item({ id: 'open' }), item({ id: 'explicit', adminOnly: false })]
expect(apply(items, false)).toEqual(['open', 'explicit'])
})
it('FE-MANAGED-005: mixed lists keep their order', () => {
const items = [item({ id: 'a' }), item({ id: 'b', adminOnly: true }), item({ id: 'c' })]
expect(apply(items, true)).toEqual(['a', 'b', 'c'])
expect(apply(items, false)).toEqual(['a', 'c'])
})
})