takt/src/__tests__/permission-mode.test.ts
nrslib a49d3af7a9 settingSources に project を追加し、CLAUDE.md の読み込みを SDK に委譲
手動で CLAUDE.md を読み込んでいた loadProjectContext を削除し、
SDK の settingSources: ['project'] でプロジェクトコンテキストを自動解決するよう変更
2026-02-24 16:48:43 +09:00

113 lines
3.6 KiB
TypeScript

/**
* Tests for permission mode mapping functions
*/
import { describe, it, expect } from 'vitest';
import { SdkOptionsBuilder, buildSdkOptions } from '../infra/claude/options-builder.js';
import { mapToCodexSandboxMode } from '../infra/codex/types.js';
import type { PermissionMode } from '../core/models/index.js';
import type { ClaudeSpawnOptions } from '../infra/claude/types.js';
describe('SdkOptionsBuilder.mapToSdkPermissionMode', () => {
it('should map readonly to SDK default', () => {
expect(SdkOptionsBuilder.mapToSdkPermissionMode('readonly')).toBe('default');
});
it('should map edit to SDK acceptEdits', () => {
expect(SdkOptionsBuilder.mapToSdkPermissionMode('edit')).toBe('acceptEdits');
});
it('should map full to SDK bypassPermissions', () => {
expect(SdkOptionsBuilder.mapToSdkPermissionMode('full')).toBe('bypassPermissions');
});
it('should map all PermissionMode values exhaustively', () => {
const modes: PermissionMode[] = ['readonly', 'edit', 'full'];
for (const mode of modes) {
const result = SdkOptionsBuilder.mapToSdkPermissionMode(mode);
expect(result).toBeDefined();
expect(typeof result).toBe('string');
}
});
});
describe('mapToCodexSandboxMode', () => {
it('should map readonly to read-only', () => {
expect(mapToCodexSandboxMode('readonly')).toBe('read-only');
});
it('should map edit to workspace-write', () => {
expect(mapToCodexSandboxMode('edit')).toBe('workspace-write');
});
it('should map full to danger-full-access', () => {
expect(mapToCodexSandboxMode('full')).toBe('danger-full-access');
});
it('should map all PermissionMode values exhaustively', () => {
const modes: PermissionMode[] = ['readonly', 'edit', 'full'];
for (const mode of modes) {
const result = mapToCodexSandboxMode(mode);
expect(result).toBeDefined();
expect(typeof result).toBe('string');
}
});
});
describe('SdkOptionsBuilder.build() — mcpServers', () => {
it('should include mcpServers in SDK options when provided', () => {
const spawnOptions: ClaudeSpawnOptions = {
cwd: '/tmp/test',
mcpServers: {
playwright: {
command: 'npx',
args: ['-y', '@anthropic-ai/mcp-server-playwright'],
},
},
};
const sdkOptions = buildSdkOptions(spawnOptions);
expect(sdkOptions.mcpServers).toEqual({
playwright: {
command: 'npx',
args: ['-y', '@anthropic-ai/mcp-server-playwright'],
},
});
});
it('should not include mcpServers in SDK options when not provided', () => {
const spawnOptions: ClaudeSpawnOptions = {
cwd: '/tmp/test',
};
const sdkOptions = buildSdkOptions(spawnOptions);
expect(sdkOptions).not.toHaveProperty('mcpServers');
});
it('should include mcpServers alongside other options', () => {
const spawnOptions: ClaudeSpawnOptions = {
cwd: '/tmp/test',
allowedTools: ['Read', 'mcp__playwright__*'],
mcpServers: {
playwright: {
command: 'npx',
args: ['-y', '@anthropic-ai/mcp-server-playwright'],
},
},
permissionMode: 'edit',
};
const sdkOptions = buildSdkOptions(spawnOptions);
expect(sdkOptions.mcpServers).toBeDefined();
expect(sdkOptions.allowedTools).toEqual(['Read', 'mcp__playwright__*']);
expect(sdkOptions.permissionMode).toBe('acceptEdits');
});
});
describe('SdkOptionsBuilder.build() — settingSources', () => {
it('includes project in settingSources', () => {
const options = buildSdkOptions({ cwd: '/test' });
expect(options.settingSources).toEqual(['project']);
});
});