/** * Tests for the sandbox-policy home: the deployment default (mode + * workspaceRoot) the service exposes, and the per-session `sandbox/mode` * override kit (fold + write path) both enforcing families read. */ import { resolve } from 'node:path' import { describe, expect, it } from 'vitest' import { Context } from 'cordis' import { Session, SessionId } from '@deepseek-ai/dsh-session' import SandboxPolicyService, { SANDBOX_MODES, effectiveSandboxMode, setSandboxMode } from '@deepseek-ai/dsh-sandbox-policy' async function mounted(config: { mode?: 'read-only' | 'workspace-write' | 'danger-full-access'; workspaceRoot?: string } = {}) { const ctx = new Context() await ctx.plugin(SandboxPolicyService, config) return ctx } describe('SandboxPolicyService', () => { it('defaults to read-only under the process cwd', async () => { const ctx = await mounted() expect(ctx.sandboxPolicy.defaultMode).toBe('read-only') expect(ctx.sandboxPolicy.workspaceRoot).toBe(resolve(process.cwd())) }) it('carries a configured mode and resolves the workspace root absolute', async () => { const ctx = await mounted({ mode: 'workspace-write', workspaceRoot: '/ws/../ws/./sub' }) expect(ctx.sandboxPolicy.defaultMode).toBe('workspace-write') expect(ctx.sandboxPolicy.workspaceRoot).toBe(resolve('/ws/../ws/./sub')) }) it('rejects a mode outside the closed vocabulary at load', async () => { const ctx = new Context() // schemastery rejects the union violation when the plugin loads. await expect(ctx.plugin(SandboxPolicyService, { mode: 'yolo' as never })).rejects.toThrow() }) it('unregisters cleanly from a child fiber (HMR safety)', async () => { const ctx = new Context() const fiber = await ctx.plugin(SandboxPolicyService, {}) expect(ctx.sandboxPolicy).toBeDefined() await fiber.dispose() expect(ctx.get('sandboxPolicy')).toBeUndefined() }) }) describe('the sandbox/mode session kit', () => { it('SANDBOX_MODES lists every mode for advertisement and validation', () => { expect(SANDBOX_MODES).toEqual(['read-only', 'workspace-write', 'danger-full-access']) }) it('effectiveSandboxMode folds to the last switch, or undefined without one', () => { const session = new Session(SessionId('sess-fold')) expect(effectiveSandboxMode(session.events)).toBeUndefined() setSandboxMode(session, 'workspace-write') setSandboxMode(session, 'read-only') expect(effectiveSandboxMode(session.events)).toBe('read-only') }) it('setSandboxMode appends exactly one sandbox/mode event per switch', () => { const session = new Session(SessionId('sess-write')) setSandboxMode(session, 'danger-full-access') const modeEvents = session.events.filter(e => e.type === 'sandbox/mode') expect(modeEvents).toHaveLength(1) expect(modeEvents[0]?.data).toEqual({ mode: 'danger-full-access' }) }) })