2026-07-05 06:41:23 +02:00
|
|
|
import { describe, expect, it } from 'vitest'
|
|
|
|
|
import { WIDGETS, getWidgetsForArea } from '../registry/widgetRegistry.js'
|
|
|
|
|
import { VIEWS, getNavViews } from '../registry/viewRegistry.js'
|
2026-07-05 06:58:48 +02:00
|
|
|
import { getAppNavItems, isNavItemActive } from '../config/appNav.js'
|
2026-07-05 06:41:23 +02:00
|
|
|
|
|
|
|
|
describe('widgetRegistry', () => {
|
|
|
|
|
it('contains expected AP0.6 widgets', () => {
|
|
|
|
|
const keys = WIDGETS.map((w) => w.key)
|
|
|
|
|
expect(keys).toContain('kairo.my_open_actions')
|
2026-07-05 18:29:47 +02:00
|
|
|
expect(keys).toContain('kairo.initiative_portfolio')
|
2026-07-05 06:41:23 +02:00
|
|
|
expect(keys).toContain('kairo.blocked_actions')
|
|
|
|
|
expect(keys).toContain('kairo.tenant_context')
|
2026-07-05 07:25:01 +02:00
|
|
|
expect(keys).toContain('kairo.workspace_summary')
|
2026-07-05 15:55:05 +02:00
|
|
|
expect(keys).toContain('kairo.next_actions')
|
|
|
|
|
expect(keys).toContain('kairo.workspace_today')
|
2026-07-05 15:11:15 +02:00
|
|
|
expect(keys).toContain('kairo.attention')
|
2026-07-05 06:41:23 +02:00
|
|
|
})
|
|
|
|
|
|
|
|
|
|
it('filters widgets by capability', () => {
|
|
|
|
|
const all = getWidgetsForArea('workspace', [
|
|
|
|
|
'kairo.action.read',
|
|
|
|
|
'kairo.initiative.read',
|
2026-07-05 15:11:15 +02:00
|
|
|
'kairo.workspace.read',
|
2026-07-05 06:41:23 +02:00
|
|
|
])
|
2026-07-05 15:55:05 +02:00
|
|
|
expect(all.length).toBe(8)
|
2026-07-05 06:41:23 +02:00
|
|
|
|
|
|
|
|
const readOnly = getWidgetsForArea('workspace', ['kairo.initiative.read'])
|
|
|
|
|
expect(readOnly.some((w) => w.key === 'kairo.my_open_actions')).toBe(false)
|
2026-07-05 18:29:47 +02:00
|
|
|
expect(readOnly.some((w) => w.key === 'kairo.initiative_portfolio')).toBe(true)
|
2026-07-05 15:15:27 +02:00
|
|
|
expect(readOnly.some((w) => w.key === 'kairo.attention')).toBe(false)
|
2026-07-05 06:41:23 +02:00
|
|
|
})
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
describe('viewRegistry', () => {
|
2026-07-08 12:55:37 +02:00
|
|
|
it('contains cockpit, work modes and initiatives catalog', () => {
|
2026-07-05 06:41:23 +02:00
|
|
|
const keys = VIEWS.map((v) => v.key)
|
2026-07-08 12:55:37 +02:00
|
|
|
expect(keys).toContain('kairo.cockpit')
|
|
|
|
|
expect(keys).toContain('kairo.work')
|
|
|
|
|
expect(keys).toContain('kairo.plan')
|
|
|
|
|
expect(keys).toContain('kairo.control')
|
|
|
|
|
expect(keys).toContain('kairo.team')
|
2026-07-05 06:41:23 +02:00
|
|
|
expect(keys).toContain('kairo.initiatives')
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
it('filters nav views by capability', () => {
|
|
|
|
|
const nav = getNavViews(['kairo.initiative.read'])
|
2026-07-08 12:55:37 +02:00
|
|
|
expect(nav.some((v) => v.key === 'kairo.cockpit')).toBe(false)
|
2026-07-05 06:41:23 +02:00
|
|
|
expect(nav.some((v) => v.key === 'kairo.initiatives')).toBe(true)
|
|
|
|
|
})
|
|
|
|
|
})
|
2026-07-05 06:58:48 +02:00
|
|
|
|
|
|
|
|
describe('appNav', () => {
|
|
|
|
|
it('maps views to nav items with icons', () => {
|
|
|
|
|
const items = getAppNavItems([
|
|
|
|
|
'kairo.action.read',
|
|
|
|
|
'kairo.initiative.read',
|
|
|
|
|
])
|
2026-07-08 12:55:37 +02:00
|
|
|
expect(items.length).toBeGreaterThanOrEqual(5)
|
2026-07-05 06:58:48 +02:00
|
|
|
expect(items[0].Icon).toBeTruthy()
|
|
|
|
|
})
|
|
|
|
|
|
2026-07-08 12:55:37 +02:00
|
|
|
it('highlights plan mode for project object route', () => {
|
2026-07-05 06:58:48 +02:00
|
|
|
const items = getAppNavItems(['kairo.action.read', 'kairo.initiative.read'])
|
2026-07-08 12:55:37 +02:00
|
|
|
const plan = items.find((i) => i.key === 'kairo.plan')
|
|
|
|
|
expect(isNavItemActive('/projects/abc-123', plan, false)).toBe(true)
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
it('highlights work mode for action object route', () => {
|
|
|
|
|
const items = getAppNavItems(['kairo.action.read', 'kairo.initiative.read'])
|
|
|
|
|
const work = items.find((i) => i.key === 'kairo.work')
|
|
|
|
|
expect(isNavItemActive('/actions/abc-123', work, false)).toBe(true)
|
2026-07-05 06:58:48 +02:00
|
|
|
})
|
|
|
|
|
})
|