package clients import ( "context" "crypto/sha256" "encoding/hex" "encoding/json" "net/http" "net/http/httptest" "strings" "testing" "time" ) func TestVolcesAssetClientSignsCreateAndReadsAsset(t *testing.T) { var calls []string server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { calls = append(calls, r.URL.Query().Get("Action")) if r.Method != http.MethodPost || r.URL.Path != "/" || r.URL.Query().Get("Version") != "2024-01-01" { t.Fatalf("unexpected asset request %s %s?%s", r.Method, r.URL.Path, r.URL.RawQuery) } if r.Header.Get("X-Date") != "20260718T010203Z" { t.Fatalf("unexpected x-date: %q", r.Header.Get("X-Date")) } if !strings.HasPrefix(r.Header.Get("Authorization"), "HMAC-SHA256 Credential=asset-ak/") { t.Fatalf("missing Volces authorization: %q", r.Header.Get("Authorization")) } var body map[string]any if err := json.NewDecoder(r.Body).Decode(&body); err != nil { t.Fatalf("decode body: %v", err) } raw, _ := json.Marshal(body) digest := sha256.Sum256(raw) if got := r.Header.Get("X-Content-Sha256"); got != hex.EncodeToString(digest[:]) { t.Fatalf("content hash mismatch got=%q", got) } switch r.URL.Query().Get("Action") { case "CreateAsset": if body["GroupId"] != "group-1" || body["AssetType"] != "Image" { t.Fatalf("unexpected CreateAsset body: %+v", body) } _ = json.NewEncoder(w).Encode(map[string]any{"ResponseMetadata": map[string]any{"RequestId": "create-rid"}, "Result": map[string]any{"Id": "asset-1"}}) case "GetAsset": _ = json.NewEncoder(w).Encode(map[string]any{"ResponseMetadata": map[string]any{"RequestId": "get-rid"}, "Result": map[string]any{"Id": "asset-1", "Status": "Active", "AssetType": "Image"}}) default: t.Fatalf("unexpected Action: %q", r.URL.Query().Get("Action")) } })) defer server.Close() client := VolcesAssetClient{HTTPClient: server.Client(), Now: func() time.Time { return time.Date(2026, 7, 18, 1, 2, 3, 0, time.UTC) }} credentials := VolcesAssetCredentials{AccessKey: "asset-ak", SecretKey: "asset-sk", Endpoint: server.URL} created, requestID, err := client.CreateAsset(context.Background(), credentials, map[string]any{"GroupId": "group-1", "URL": "https://example.com/person.png", "AssetType": "Image", "ProjectName": "default"}) if err != nil || created.ID != "asset-1" || requestID != "create-rid" { t.Fatalf("unexpected CreateAsset result=%+v requestID=%s err=%v", created, requestID, err) } asset, requestID, err := client.GetAsset(context.Background(), credentials, map[string]any{"Id": "asset-1", "ProjectName": "default"}) if err != nil || asset.Status != "Active" || requestID != "get-rid" { t.Fatalf("unexpected GetAsset result=%+v requestID=%s err=%v", asset, requestID, err) } if strings.Join(calls, ",") != "CreateAsset,GetAsset" { t.Fatalf("unexpected actions: %+v", calls) } }