Files
picoclaw/pkg/auth/token_test.go
T
BallerIsLeet 23abbb67ea feat(auth): add Anthropic OAuth setup-token login (#926)
* feat(auth): add Anthropic OAuth setup-token login flow

Add support for Anthropic's OAuth-based setup tokens (sk-ant-oat01-*)
as an alternative to API keys. This includes:

- New `--setup-token` flag on `auth login` command
- Interactive login menu for Anthropic (setup token vs API key)
- Setup token validation and credential storage with oauth auth method
- Usage endpoint integration to show 5h/7d utilization in `auth status`
- Streaming support for OAuth tokens (required by Anthropic API)
- Model ID normalization (dots to hyphens) for API compatibility
- Remove .env.example (secrets should not be templated)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* feat(auth):  update related functionality

* refactor(auth): organize constants and improve header casing in requests fo CI

* fix(auth): fix golint again

* fix(auth): handle nil arguments in tool calls for buildParams function

---------

Co-authored-by: Baller <sharonms3377@gmail.com>
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-06 19:58:23 +08:00

62 lines
1.6 KiB
Go

package auth
import (
"strings"
"testing"
)
func TestLoginSetupToken(t *testing.T) {
// A valid token: correct prefix + at least 80 chars
validToken := "sk-ant-oat01-" + strings.Repeat("a", 80)
tests := []struct {
name string
input string
wantErr string
}{
{"valid token", validToken, ""},
{"empty input", "", "expected prefix sk-ant-oat01-"},
{"wrong prefix", "sk-ant-api-" + strings.Repeat("a", 80), "expected prefix sk-ant-oat01-"},
{"too short", "sk-ant-oat01-short", "too short"},
{"whitespace only", " ", "expected prefix sk-ant-oat01-"},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
r := strings.NewReader(tt.input + "\n")
cred, err := LoginSetupToken(r)
if tt.wantErr != "" {
if err == nil {
t.Fatalf("expected error containing %q, got nil", tt.wantErr)
}
if !strings.Contains(err.Error(), tt.wantErr) {
t.Fatalf("expected error containing %q, got %q", tt.wantErr, err.Error())
}
return
}
if err != nil {
t.Fatalf("unexpected error: %v", err)
}
if cred.AccessToken != validToken {
t.Errorf("AccessToken = %q, want %q", cred.AccessToken, validToken)
}
if cred.Provider != "anthropic" {
t.Errorf("Provider = %q, want %q", cred.Provider, "anthropic")
}
if cred.AuthMethod != "oauth" {
t.Errorf("AuthMethod = %q, want %q", cred.AuthMethod, "oauth")
}
})
}
}
func TestLoginSetupToken_EmptyReader(t *testing.T) {
r := strings.NewReader("")
_, err := LoginSetupToken(r)
if err == nil {
t.Fatal("expected error for empty reader, got nil")
}
}