package adapters import ( "context" "strings" "testing" ) func TestTheTwoShapesAreSelectedByVendor(t *testing.T) { static, err := For("anthropic-api-key") if err != nil { t.Fatal(err) } if static.Shape() != StaticKey { t.Fatalf("anthropic-api-key is %q, expected static-key", static.Shape()) } grant, err := For("anthropic") if err != nil { t.Fatal(err) } if grant.Shape() != RefreshableGrant { t.Fatalf("anthropic is %q, expected refreshable-grant", grant.Shape()) } // openai is a second static-key vendor, served by the same generic adapter — the registry line is // the whole of its integration, and it reports the static-key shape like any other. openai, err := For("openai") if err != nil { t.Fatal(err) } if openai.Shape() != StaticKey { t.Fatalf("openai is %q, expected static-key", openai.Shape()) } } // The type assertion is what gates the carve-out: a static key is not a Refresher, so it can never // reach the machinery that holds a token readably. A refreshable grant is one. func TestOnlyARefreshableGrantIsARefresher(t *testing.T) { static, _ := For("anthropic-api-key") if _, ok := static.(Refresher); ok { t.Fatal("a static-key adapter is a Refresher, so the carve-out is not gated by shape") } grant, _ := For("anthropic") if _, ok := grant.(Refresher); !ok { t.Fatal("a refreshable-grant adapter is not a Refresher, so it cannot be refreshed") } } // With nothing plugged in, a refresh is refused in a way that names why — not answered with a // silent no-op that would look like a refresh that changed nothing. func TestARefreshWithNoRefresherPluggedInIsRefused(t *testing.T) { grant, _ := For("anthropic") r := grant.(Refresher) _, err := r.Refresh(context.Background(), RefreshInput{Licence: "personal"}) if err == nil { t.Fatal("a refresh succeeded with no vendor refresher plugged in") } if !strings.Contains(err.Error(), "Phase C") { t.Fatalf("the refusal does not point at the missing plug-in: %v", err) } } type fakeVendor struct { result RefreshResult got RefreshInput } func (f *fakeVendor) Refresh(_ context.Context, in RefreshInput) (RefreshResult, error) { f.got = in return f.result, nil } // A plugged-in refresher is dispatched to, and is handed the sealed refresh token (never a plaintext // one) plus which node is the manager. func TestAPluggedInRefresherIsDispatchedTo(t *testing.T) { fake := &fakeVendor{result: RefreshResult{AccessToken: "at-new"}} RegisterRefresher("anthropic", fake) defer RegisterRefresher("anthropic", nil) grant, _ := For("anthropic") r := grant.(Refresher) in := RefreshInput{ Licence: "personal", Manager: "workstation", Sealed: "sealed-box", ManagerKey: "mk", } out, err := r.Refresh(context.Background(), in) if err != nil { t.Fatal(err) } if out.AccessToken != "at-new" { t.Fatalf("the dispatched result did not come back: %q", out.AccessToken) } if fake.got.Manager != "workstation" || fake.got.Sealed != "sealed-box" { t.Fatalf("the refresher was handed the wrong input: %+v", fake.got) } } // A vendor this build has no adapter for is refused, and the refusal lists what it does know so a // typo and an unsupported vendor are told apart. func TestAnUnknownVendorIsRefusedWithTheList(t *testing.T) { _, err := For("acme-models") if err == nil { t.Fatal("an unknown vendor returned an adapter") } if !strings.Contains(err.Error(), "anthropic") { t.Fatalf("the refusal does not list the known vendors: %v", err) } } // Both shapes deliver their stored blob unchanged: a static key has no vendor step, and a // refreshable grant's holder row holds an access token with no refresh token to strip. func TestBothShapesDeliverTheStoredBlobUnchanged(t *testing.T) { for _, vendor := range []string{"anthropic", "anthropic-api-key"} { a, _ := For(vendor) if got := a.Deliver("sealed-blob"); got != "sealed-blob" { t.Fatalf("%s changed the delivered blob to %q", vendor, got) } } }