package hfb import ( "context" "crypto/hmac" "crypto/sha256" "encoding/hex" "io" "net/http" "net/http/httptest" "testing" "time" ) func TestUploadSendsSignedRequest(t *testing.T) { const secret = "test-secret" server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { if r.URL.Path != uploadPath { t.Fatalf("path = %q", r.URL.Path) } body, err := io.ReadAll(r.Body) if err != nil { t.Fatalf("ReadAll() error = %v", err) } timestamp := r.Header.Get("X-HFB-Timestamp") signature := r.Header.Get("X-HFB-Signature") if timestamp == "" || signature == "" { t.Fatal("missing signature headers") } if signature != expectedSignature(secret, timestamp, body) { t.Fatalf("signature = %q", signature) } w.WriteHeader(http.StatusCreated) _, _ = w.Write([]byte(`{"ok":true}`)) })) defer server.Close() client := Client{Server: server.URL, Secret: secret, Timeout: time.Second} req := NewExternalUploadRequest("张三", "淘宝", mustSampleAccount(t), time.Unix(100, 0)) resp, err := client.Upload(context.Background(), req) if err != nil { t.Fatalf("Upload() error = %v", err) } if resp != `{"ok":true}` { t.Fatalf("resp = %q", resp) } } func TestNormalizeEndpoint(t *testing.T) { got, err := normalizeEndpoint("http://127.0.0.1:8080") if err != nil { t.Fatalf("normalizeEndpoint() error = %v", err) } want := "http://127.0.0.1:8080" + uploadPath if got != want { t.Fatalf("endpoint = %q, want %q", got, want) } } func mustSampleAccount(t *testing.T) ExternalAccountData { t.Helper() parsed, err := ParseUploadText(sampleText) if err != nil { t.Fatalf("ParseUploadText() error = %v", err) } return parsed.Account } func expectedSignature(secret, timestamp string, body []byte) string { mac := hmac.New(sha256.New, []byte(secret)) mac.Write([]byte(timestamp)) mac.Write([]byte(".")) mac.Write(body) return hex.EncodeToString(mac.Sum(nil)) }