test(credential): pin the TAT mint-then-cache happy path

First resolve mints over HTTP, second is served from the sync.Once
cache with exactly one HTTP call total.
This commit is contained in:
luozhixiong
2026-07-15 16:05:33 +08:00
committed by review
parent 6b80706300
commit 16ed51252e

View File

@@ -6,6 +6,7 @@ package credential
import (
"context"
"errors"
"io"
"net/http"
"strings"
"testing"
@@ -185,3 +186,47 @@ func TestDefaultTokenProvider_TATChecksAppBeforeAnyTokenWork(t *testing.T) {
t.Fatal("token work started for a mismatched app: the check must run before any HTTP client is built")
}
}
// countingTATTripper serves a canned successful TAT response and counts calls.
type countingTATTripper struct{ calls int }
func (c *countingTATTripper) RoundTrip(*http.Request) (*http.Response, error) {
c.calls++
return &http.Response{
StatusCode: http.StatusOK,
Body: io.NopCloser(strings.NewReader(`{"code":0,"access_token":"tat-token-value"}`)),
Header: http.Header{"Content-Type": []string{"application/json"}},
}, nil
}
// TAT happy path: the first request mints the token over HTTP, the second is
// served from the sync.Once cache without another HTTP call.
func TestDefaultTokenProvider_TATSuccessAndCacheHit(t *testing.T) {
t.Setenv("LARKSUITE_CLI_CONFIG_DIR", t.TempDir())
multi := &core.MultiAppConfig{CurrentApp: "tenant_a", Apps: []core.AppConfig{{
Name: "tenant_a", AppId: "cli_a", AppSecret: core.PlainSecret("your-secret"), Brand: core.BrandFeishu,
}}}
if err := core.SaveMultiAppConfig(multi); err != nil {
t.Fatalf("SaveMultiAppConfig: %v", err)
}
tripper := &countingTATTripper{}
tp := NewDefaultTokenProvider(
NewDefaultAccountProvider(nil, "tenant_a"),
func() (*http.Client, error) { return &http.Client{Transport: tripper}, nil },
nil,
)
req := TokenSpec{Type: TokenTypeTAT, AppID: "cli_a"}
first, err := tp.ResolveToken(context.Background(), req)
if err != nil || first.Token != "tat-token-value" {
t.Fatalf("first resolve = %+v, %v; want minted token", first, err)
}
second, err := tp.ResolveToken(context.Background(), req)
if err != nil || second.Token != "tat-token-value" {
t.Fatalf("second resolve = %+v, %v; want cached token", second, err)
}
if tripper.calls != 1 {
t.Fatalf("HTTP calls = %d, want exactly 1 (second resolve must hit the cache)", tripper.calls)
}
}