package web import ( "net/http" "net/http/httptest" "os" "os/exec" "path/filepath" "strings" "testing" ) func TestEachToolGetsItsConfigurationWithTheKey(t *testing.T) { c := connectFor("continue", "https://gw.example", "qwen2.5-coder-7b", "sk-llmgw-abc") if !strings.Contains(c.Files[0].Body, "apiBase: https://gw.example/v1") || !strings.Contains(c.Files[0].Body, "apiKey: sk-llmgw-abc") || c.Files[0].Path != "~/.continue/assistants/llmgw.yaml" { t.Errorf("continue = %+v", c.Files) } // The key goes in the environment, not the URL, where it would be kept in // shell history and proxy logs. if strings.Contains(strings.Split(c.Command, "|")[0], "sk-llmgw-abc") { t.Errorf("the key is in the URL: %s", c.Command) } x := connectFor("codex", "https://gw.example", "qwen2.5-coder-7b", "sk-llmgw-abc") if strings.Contains(x.Files[0].Body, "sk-llmgw-abc") || !strings.Contains(x.Files[0].Body, `env_key = "LLMGW_API_KEY"`) { t.Errorf("codex writes the key into its file: %s", x.Files[0].Body) } cl := connectFor("cline", "https://gw.example", "m", "sk-llmgw-abc") if len(cl.Fields) != 4 || cl.Fields[1].Value != "https://gw.example/v1" || cl.Command != "" { t.Errorf("cline = %+v", cl) } } // runScript fetches a setup script and runs it with HOME in a temporary // directory, as a person's shell would. func runScript(t *testing.T, tool string, env ...string) string { t.Helper() p := &AccountPages{} w := httptest.NewRecorder() r := httptest.NewRequest("GET", "http://gw.example/setup/"+tool+"?model=qwen2.5-coder-7b", nil) r.SetPathValue("tool", tool) p.setupScript(w, r) if w.Code != http.StatusOK { t.Fatalf("%d %s", w.Code, w.Body.String()) } home := t.TempDir() cmd := exec.Command("sh") cmd.Stdin = strings.NewReader(w.Body.String()) cmd.Env = append([]string{"HOME=" + home, "PATH=" + os.Getenv("PATH")}, env...) if out, err := cmd.CombinedOutput(); err != nil { t.Fatalf("%v: %s", err, out) } return home } func TestTheContinueScriptWritesItsOwnFileWithTheKey(t *testing.T) { home := runScript(t, "continue", "LLMGW_KEY=sk-llmgw-xyz") b, err := os.ReadFile(filepath.Join(home, ".continue", "assistants", "llmgw.yaml")) if err != nil { t.Fatal(err) } if !strings.Contains(string(b), "apiKey: sk-llmgw-xyz") || strings.Contains(string(b), "__LLMGW_KEY__") { t.Errorf("wrote %s", b) } if fi, _ := os.Stat(filepath.Join(home, ".continue", "assistants", "llmgw.yaml")); fi.Mode().Perm()&0o077 != 0 { t.Errorf("a file holding a key is readable by others: %v", fi.Mode()) } } func TestTheCodexScriptKeepsTheRestOfTheConfig(t *testing.T) { // Run twice over a config with the person's own settings: theirs stay, // and ours appear once. p := &AccountPages{} w := httptest.NewRecorder() r := httptest.NewRequest("GET", "http://gw.example/setup/codex?model=qwen2.5-coder-7b", nil) r.SetPathValue("tool", "codex") p.setupScript(w, r) home := t.TempDir() if err := os.MkdirAll(filepath.Join(home, ".codex"), 0o755); err != nil { t.Fatal(err) } mine := "model = \"o3\"\n\n[mcp_servers.docs]\ncommand = \"docs-mcp\"\n" cfg := filepath.Join(home, ".codex", "config.toml") if err := os.WriteFile(cfg, []byte(mine), 0o644); err != nil { t.Fatal(err) } for range 2 { cmd := exec.Command("sh") cmd.Stdin = strings.NewReader(w.Body.String()) cmd.Env = []string{"HOME=" + home, "PATH=" + os.Getenv("PATH")} if out, err := cmd.CombinedOutput(); err != nil { t.Fatalf("%v: %s", err, out) } } b, _ := os.ReadFile(cfg) got := string(b) if !strings.Contains(got, `model = "o3"`) || !strings.Contains(got, "[mcp_servers.docs]") { t.Errorf("the person's settings were lost:\n%s", got) } if strings.Count(got, "[model_providers.llmgw]") != 1 || strings.Count(got, "[profiles.llmgw]") != 1 { t.Errorf("ours should be there once:\n%s", got) } if backups, _ := filepath.Glob(cfg + ".bak.*"); len(backups) == 0 { t.Error("no copy was kept of the file as it was") } } func TestASetupScriptRefusesANameAShellWouldRead(t *testing.T) { p := &AccountPages{} w := httptest.NewRecorder() r := httptest.NewRequest("GET", "http://gw.example/setup/codex?model=$(rm%20-rf%20~)", nil) r.SetPathValue("tool", "codex") p.setupScript(w, r) if w.Code != http.StatusBadRequest { t.Errorf("%d", w.Code) } }