You've already forked agentic-coding-workflow
ACP / MCP
This commit is contained in:
@@ -0,0 +1,107 @@
|
||||
package acp
|
||||
|
||||
import (
|
||||
"context"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"runtime"
|
||||
"testing"
|
||||
|
||||
"github.com/google/uuid"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
"github.com/yan1h/agent-coding-workflow/internal/infra/crypto"
|
||||
)
|
||||
|
||||
// cfgRepoStub 只实现 ListConfigFiles;其余方法走嵌入的 nil 接口(调用即 panic)。
|
||||
type cfgRepoStub struct {
|
||||
Repository
|
||||
files []*ConfigFile
|
||||
}
|
||||
|
||||
func (s cfgRepoStub) ListConfigFiles(context.Context, uuid.UUID) ([]*ConfigFile, error) {
|
||||
return s.files, nil
|
||||
}
|
||||
|
||||
func TestMaterializeAgentHome(t *testing.T) {
|
||||
t.Parallel()
|
||||
enc, err := crypto.NewEncryptor([]byte("0123456789abcdef0123456789abcdef"))
|
||||
require.NoError(t, err)
|
||||
|
||||
kind := &AgentKind{ID: uuid.New(), ClientType: ClientCodex}
|
||||
content := []byte(`model = "gpt-5.5"`)
|
||||
encrypted, err := enc.Encrypt(content)
|
||||
require.NoError(t, err)
|
||||
|
||||
root := t.TempDir()
|
||||
s := &Supervisor{
|
||||
repo: cfgRepoStub{files: []*ConfigFile{{AgentKindID: kind.ID, RelPath: ".codex/config.toml", EncryptedContent: encrypted}}},
|
||||
crypto: enc,
|
||||
cfg: SupervisorConfig{AgentHomesDir: root},
|
||||
}
|
||||
|
||||
home, err := s.materializeAgentHome(context.Background(), kind)
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, filepath.Join(root, kind.ID.String()), home)
|
||||
|
||||
got, err := os.ReadFile(filepath.Join(home, ".codex", "config.toml"))
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, content, got)
|
||||
|
||||
// 二次物化幂等(覆写)
|
||||
_, err = s.materializeAgentHome(context.Background(), kind)
|
||||
require.NoError(t, err)
|
||||
}
|
||||
|
||||
func TestMaterializeAgentHome_RejectsEscape(t *testing.T) {
|
||||
t.Parallel()
|
||||
enc, err := crypto.NewEncryptor([]byte("0123456789abcdef0123456789abcdef"))
|
||||
require.NoError(t, err)
|
||||
encrypted, err := enc.Encrypt([]byte("x"))
|
||||
require.NoError(t, err)
|
||||
|
||||
kind := &AgentKind{ID: uuid.New(), ClientType: ClientGeneric}
|
||||
s := &Supervisor{
|
||||
repo: cfgRepoStub{files: []*ConfigFile{{AgentKindID: kind.ID, RelPath: "../escape.txt", EncryptedContent: encrypted}}},
|
||||
crypto: enc,
|
||||
cfg: SupervisorConfig{AgentHomesDir: t.TempDir()},
|
||||
}
|
||||
_, err = s.materializeAgentHome(context.Background(), kind)
|
||||
require.Error(t, err)
|
||||
assert.Contains(t, err.Error(), "escapes agent home")
|
||||
}
|
||||
|
||||
func TestAgentHomeEnv_ByClientType(t *testing.T) {
|
||||
t.Parallel()
|
||||
home := filepath.Join(string(filepath.Separator), "data", "agent-homes", "x")
|
||||
|
||||
env := agentHomeEnv(home, ClientClaudeCode)
|
||||
assert.Equal(t, home, env["HOME"])
|
||||
assert.Equal(t, filepath.Join(home, ".claude"), env["CLAUDE_CONFIG_DIR"])
|
||||
|
||||
env = agentHomeEnv(home, ClientCodex)
|
||||
assert.Equal(t, filepath.Join(home, ".codex"), env["CODEX_HOME"])
|
||||
|
||||
env = agentHomeEnv(home, ClientGemini)
|
||||
assert.Equal(t, home, env["GEMINI_CLI_HOME"])
|
||||
|
||||
env = agentHomeEnv(home, ClientGeneric)
|
||||
assert.Equal(t, map[string]string{"HOME": home}, stripWinEnv(env))
|
||||
|
||||
if runtime.GOOS == "windows" {
|
||||
assert.Equal(t, home, agentHomeEnv(home, ClientGeneric)["USERPROFILE"])
|
||||
}
|
||||
}
|
||||
|
||||
// stripWinEnv 去掉平台相关的 USERPROFILE,便于跨平台断言。
|
||||
func stripWinEnv(env map[string]string) map[string]string {
|
||||
out := map[string]string{}
|
||||
for k, v := range env {
|
||||
if k == "USERPROFILE" {
|
||||
continue
|
||||
}
|
||||
out[k] = v
|
||||
}
|
||||
return out
|
||||
}
|
||||
Reference in New Issue
Block a user