package main import ( "context" "os" "path/filepath" "testing" "harness/internal/llm" ) // fakeHome writes a credentials file with a token that is not expired. func fakeHome(t *testing.T) string { t.Helper() home := t.TempDir() dir := filepath.Join(home, ".claude") if err := os.MkdirAll(dir, 0o700); err != nil { t.Fatal(err) } // expiresAt is 2035, comfortably in the future. body := `{"claudeAiOauth":{"accessToken":"file-token","refreshToken":"r", "expiresAt":2058430000000,"refreshTokenExpiresAt":2058430000000, "scopes":["user:inference"],"subscriptionType":"team"}}` if err := os.WriteFile(filepath.Join(dir, ".credentials.json"), []byte(body), 0o600); err != nil { t.Fatal(err) } return home } func TestClaudeCodeFillsInAMissingCredential(t *testing.T) { c := llm.New(llm.WithBaseURL(llm.DefaultBaseURL)) c.ClearCredentialsForTest() src, note, err := resolveClaudeCode(c, fakeHome(t), false) if err != nil { t.Fatalf("resolveClaudeCode: %v", err) } if src == nil { t.Fatal("expected a token source") } tok, err := src.Token(context.Background()) if err != nil { t.Fatalf("token: %v", err) } if tok != "file-token" { t.Errorf("token = %q, want file-token", tok) } if note == "" { t.Error("using a discovered credential should be announced") } } // tripwireHome writes a credentials file that is malformed JSON: a // deliberate landmine, not a fixture. If resolveClaudeCode ever reads it // before deciding the endpoint disqualifies discovery, claudecode.Load // returns a parse error and the test surfaces that loudly, rather than // passing on the unobservable (and here false) assumption that the file // went untouched. func tripwireHome(t *testing.T) string { t.Helper() home := t.TempDir() dir := filepath.Join(home, ".claude") if err := os.MkdirAll(dir, 0o700); err != nil { t.Fatal(err) } if err := os.WriteFile(filepath.Join(dir, ".credentials.json"), []byte("{not json"), 0o600); err != nil { t.Fatal(err) } return home } // An explicit credential wins. We never override what the user typed. func TestClaudeCodeIsSkippedWhenACredentialExists(t *testing.T) { c := llm.New(llm.WithBaseURL(llm.DefaultBaseURL), llm.WithAPIKey("sk-ant-explicit")) src, _, err := resolveClaudeCode(c, fakeHome(t), false) if err != nil { t.Fatalf("resolveClaudeCode: %v", err) } if src != nil { t.Error("an explicit credential must not be replaced by the file") } } // The security property: a credential we found is never sent to an endpoint // the user pointed us at. "We did not send it" is not observable from outside, // so it is a test rather than a comment. The home directory here contains // malformed JSON rather than a valid credential: if resolveClaudeCode ever // reads the file before rejecting the non-default endpoint, claudecode.Load // fails to parse it and err comes back non-nil, which the assertion below // catches. A nil err is what proves the file was never opened. func TestClaudeCodeIsNeverSentToANonDefaultEndpoint(t *testing.T) { c := llm.New(llm.WithBaseURL("http://gateway.example")) c.ClearCredentialsForTest() src, _, err := resolveClaudeCode(c, tripwireHome(t), false) if err != nil { t.Fatalf("resolveClaudeCode read the credentials file (err = %v); it must not touch disk once the endpoint disqualifies discovery", err) } if src != nil { t.Fatal("a discovered credential must never go to a non-default endpoint") } } func TestClaudeCodeCanBeDisabled(t *testing.T) { c := llm.New(llm.WithBaseURL(llm.DefaultBaseURL)) c.ClearCredentialsForTest() src, _, err := resolveClaudeCode(c, fakeHome(t), true) if err != nil { t.Fatalf("resolveClaudeCode: %v", err) } if src != nil { t.Error("-no-claude-code-auth must skip discovery entirely") } } // Not logged in is not an error. It falls through to errNoCredentials. func TestClaudeCodeMissingFileIsNotAnError(t *testing.T) { c := llm.New(llm.WithBaseURL(llm.DefaultBaseURL)) c.ClearCredentialsForTest() src, _, err := resolveClaudeCode(c, t.TempDir(), false) if err != nil { t.Fatalf("a missing file is not an error, got %v", err) } if src != nil { t.Error("no file means no source") } }