Files
chenhg5-cc-connect/agent/codex/integration_test.go
Claude f8d2cad68f refactor: restructure provider presets with per-agent-type configuration
- Restructure provider-presets.json (v1→v2): replace flat endpoints/
  agent_models/models/agents/codex_config fields with a unified
  `agents` map keyed by agent type, each containing base_url, model,
  models list, and optional codex_config
- Update ProviderPreset Go struct with PresetAgentConfig and helper
  methods SupportsAgent()/AgentConfig()
- Add AgentModelLists to config.ProviderConfig for per-agent model
  lists; ResolveProviderRefs now resolves models per agent type
- Filter global provider linking by agent type in IM /provider add
  card and executeProviderLink to prevent incompatible associations
- Fix Codex 404 caused by shengsuanyun agent_types including "codex"
  with wrong base_url; remove codex from its agent_types
- Update web frontend ProviderPreset type and preset display/add logic
  to use the new agents map structure

Made-with: Cursor
2026-04-18 15:24:32 +08:00

110 lines
3.1 KiB
Go

package codex
import (
"encoding/json"
"os"
"os/exec"
"path/filepath"
"strings"
"testing"
)
// TestIntegration_CodexProviderFlow verifies the full provider config flow:
// 1. ensureCodexProviderConfig writes correct config.toml
// 2. ensureCodexAuth writes correct auth.json
// 3. Codex CLI can authenticate and respond using the written config
//
// Requires: SHENGSUANYUN_API_KEY env var and `codex` CLI in PATH.
// Skip with: go test ./agent/codex/ -run TestIntegration -v
func TestIntegration_CodexProviderFlow(t *testing.T) {
apiKey := os.Getenv("SHENGSUANYUN_API_KEY")
if apiKey == "" {
t.Skip("SHENGSUANYUN_API_KEY not set, skipping integration test")
}
if _, err := exec.LookPath("codex"); err != nil {
t.Skip("codex CLI not in PATH, skipping integration test")
}
home := filepath.Join(t.TempDir(), ".codex")
// Step 1: write config.toml via our function
err := ensureCodexProviderConfig(home, "shengsuanyun-codex",
"https://router.shengsuanyun.com/api/v1", "responses", nil)
if err != nil {
t.Fatalf("ensureCodexProviderConfig: %v", err)
}
// Verify config.toml content
cfgData, err := os.ReadFile(filepath.Join(home, "config.toml"))
if err != nil {
t.Fatalf("read config.toml: %v", err)
}
cfgContent := string(cfgData)
t.Logf("Generated config.toml:\n%s", cfgContent)
for _, want := range []string{
`[model_providers.shengsuanyun-codex]`,
`base_url = "https://router.shengsuanyun.com/api/v1"`,
`wire_api = "responses"`,
`env_key = "OPENAI_API_KEY"`,
} {
if !strings.Contains(cfgContent, want) {
t.Errorf("config.toml missing: %s", want)
}
}
// Step 2: write auth.json via our function
err = ensureCodexAuth(home, apiKey)
if err != nil {
t.Fatalf("ensureCodexAuth: %v", err)
}
// Verify auth.json content
authData, err := os.ReadFile(filepath.Join(home, "auth.json"))
if err != nil {
t.Fatalf("read auth.json: %v", err)
}
var authMap map[string]any
if err := json.Unmarshal(authData, &authMap); err != nil {
t.Fatalf("parse auth.json: %v", err)
}
if authMap["auth_mode"] != "apikey" {
t.Errorf("auth_mode = %v, want apikey", authMap["auth_mode"])
}
if authMap["OPENAI_API_KEY"] != apiKey {
t.Errorf("OPENAI_API_KEY not set correctly in auth.json")
}
// Step 3: run codex exec with the generated config
workDir := filepath.Join(t.TempDir(), "repo")
os.MkdirAll(workDir, 0o755)
gitInit := exec.Command("git", "init", "-q")
gitInit.Dir = workDir
if err := gitInit.Run(); err != nil {
t.Fatalf("git init: %v", err)
}
cmd := exec.Command("codex", "exec",
"--model", "openai/gpt-5.3-codex",
"-c", `model_provider="shengsuanyun-codex"`,
"-c", `openai_base_url="https://router.shengsuanyun.com/api/v1"`,
"--full-auto",
)
cmd.Dir = workDir
cmd.Env = append(os.Environ(),
"CODEX_HOME="+home,
"OPENAI_API_KEY="+apiKey,
)
cmd.Stdin = strings.NewReader("reply with exactly 'integration-ok' and nothing else")
output, err := cmd.CombinedOutput()
t.Logf("Codex output:\n%s", string(output))
if err != nil {
t.Fatalf("codex exec failed: %v\noutput: %s", err, output)
}
if !strings.Contains(string(output), "integration-ok") {
t.Errorf("expected 'integration-ok' in output, got:\n%s", output)
}
}