120 lines
3.5 KiB
TypeScript
120 lines
3.5 KiB
TypeScript
import { beforeEach, describe, expect, it } from 'vitest'
|
|
import { createPinia, setActivePinia } from 'pinia'
|
|
import { useAuthStore } from '../src/stores/auth'
|
|
import { useMissionControlUiStore } from '../src/stores/missionControlUi'
|
|
import { buildMissionControlContext } from '../src/utils/missionControlContext'
|
|
import { reportOperationEnvelope } from '../src/services/operationResults'
|
|
import { routeForEntity } from '../src/utils/entityNavigation'
|
|
|
|
beforeEach(() => {
|
|
setActivePinia(createPinia())
|
|
})
|
|
|
|
describe('mission control context', () => {
|
|
it('maps an object route into bounded Iris context', () => {
|
|
const context = buildMissionControlContext({
|
|
name: 'TaskDetail',
|
|
path: '/tasks/98f927bb',
|
|
params: { id: '98f927bb' },
|
|
})
|
|
|
|
expect(context).toEqual({
|
|
routeName: 'TaskDetail',
|
|
path: '/tasks/98f927bb',
|
|
surface: 'Task detail',
|
|
entityType: 'task',
|
|
entityId: '98f927bb',
|
|
})
|
|
})
|
|
|
|
it('keeps index routes free of invented entity identifiers', () => {
|
|
const context = buildMissionControlContext({
|
|
name: 'Run Control',
|
|
path: '/runs',
|
|
params: {},
|
|
})
|
|
|
|
expect(context.surface).toBe('Run Control')
|
|
expect(context.entityType).toBeNull()
|
|
expect(context.entityId).toBeNull()
|
|
})
|
|
})
|
|
|
|
describe('mission control overlays', () => {
|
|
it('keeps command and Iris dialogs mutually exclusive', () => {
|
|
useAuthStore().applySession({
|
|
accessToken: 'owner-token',
|
|
expiresAt: '2026-07-31T12:00:00.000Z',
|
|
user: {
|
|
id: 'bao',
|
|
email: 'bao@nexus.local',
|
|
displayName: 'Bao',
|
|
role: 'owner',
|
|
},
|
|
})
|
|
const store = useMissionControlUiStore()
|
|
|
|
store.openCommand()
|
|
expect(store.commandOpen).toBe(true)
|
|
expect(store.irisOpen).toBe(false)
|
|
|
|
store.openIris()
|
|
expect(store.commandOpen).toBe(false)
|
|
expect(store.irisOpen).toBe(true)
|
|
})
|
|
|
|
it('refuses to open the Iris mutation dialog for non-owners', () => {
|
|
useAuthStore().applySession({
|
|
accessToken: 'viewer-token',
|
|
expiresAt: '2026-07-31T12:00:00.000Z',
|
|
user: {
|
|
id: 'viewer',
|
|
email: 'viewer@nexus.local',
|
|
displayName: 'Viewer',
|
|
role: 'viewer',
|
|
},
|
|
})
|
|
const store = useMissionControlUiStore()
|
|
|
|
store.openCommand()
|
|
store.openIris()
|
|
|
|
expect(store.commandOpen).toBe(true)
|
|
expect(store.irisOpen).toBe(false)
|
|
})
|
|
|
|
it('publishes and dismisses a normalized mutation result', () => {
|
|
const store = useMissionControlUiStore()
|
|
|
|
const result = reportOperationEnvelope({
|
|
operation: {
|
|
operationId: 'operation-9',
|
|
status: 'updated',
|
|
revision: '3',
|
|
primaryRef: { type: 'task', id: 'task-9', label: 'Task 9' },
|
|
affectedRefs: [{ type: 'agent', id: 'iris', label: 'Iris' }],
|
|
traceId: null,
|
|
},
|
|
}, 'Task aktualisiert')
|
|
|
|
expect(result?.revision).toBe(3)
|
|
expect(store.operationTitle).toBe('Task aktualisiert')
|
|
expect(store.operationResult?.primaryRef?.id).toBe('task-9')
|
|
|
|
store.dismissOperation()
|
|
expect(store.operationResult).toBeNull()
|
|
})
|
|
|
|
it('resolves OpenClaw runtime and agent-file references to existing routes', () => {
|
|
expect(routeForEntity({ type: 'openclaw-task', id: 'runtime-1', label: null })).toEqual({
|
|
name: 'Run Control',
|
|
query: { task: 'runtime-1' },
|
|
})
|
|
expect(routeForEntity({ type: 'agent-file', id: 'iris/AGENTS.md', label: null })).toEqual({
|
|
name: 'AgentDetail',
|
|
params: { id: 'iris' },
|
|
query: { file: 'AGENTS.md' },
|
|
})
|
|
})
|
|
})
|