98 lines
3.8 KiB
Go
98 lines
3.8 KiB
Go
package api
|
|
|
|
import (
|
|
"bytes"
|
|
"encoding/base64"
|
|
"encoding/json"
|
|
"fmt"
|
|
"io"
|
|
"net/http"
|
|
"net/http/httptest"
|
|
"os"
|
|
"path/filepath"
|
|
"strings"
|
|
"testing"
|
|
"time"
|
|
|
|
"git.ipao.vip/rogee/creator-hub/internal/account"
|
|
"git.ipao.vip/rogee/creator-hub/internal/creator"
|
|
hub "git.ipao.vip/rogee/creator-hub/internal/environment"
|
|
"github.com/gofiber/fiber/v3"
|
|
)
|
|
|
|
func TestOwnedCoversCacheFilesAndReportIndividualFailures(t *testing.T) {
|
|
databaseURL := os.Getenv("CREATORHUB_POSTGRES_TEST_URL")
|
|
if databaseURL == "" {
|
|
t.Skip("set CREATORHUB_POSTGRES_TEST_URL for isolated PostgreSQL coverage")
|
|
}
|
|
store, accounts, ctx := openCreatorIntegrationStoreForAPITest(t, databaseURL)
|
|
owner := account.Account{
|
|
ID: "owned-cover-account", Name: "封面账号", Platform: creator.PlatformDouyin, PlatformAccountKey: "12345678901",
|
|
CredentialReference: account.CredentialReference{ID: "cover-test-credential", Provider: "os_keyring"},
|
|
CredentialKey: "creatorhub/owned-cover-account/cookies",
|
|
}
|
|
if err := accounts.CreateAccount(ctx, owner, &testCredentialBridge{values: make(map[string]string)}); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
works := make(map[string]creator.Work)
|
|
for _, key := range []string{"good", "broken"} {
|
|
work, _, err := store.UpsertWork(ctx, creator.WorkInput{SourceType: creator.SourceOwned, SourceID: owner.ID, Platform: creator.PlatformDouyin, WorkKey: "owned-cover-" + key, CoverURL: "https://p3-pc-sign.douyinpic.com/" + key + ".png"}, time.Now().UTC())
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
works[key] = work
|
|
}
|
|
requests := 0
|
|
gateway := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
|
if r.URL.Path != "/v1/browsers/owned-cover-alias/douyin/image" {
|
|
http.NotFound(w, r)
|
|
return
|
|
}
|
|
requests++
|
|
var payload struct {
|
|
URL string `json:"url"`
|
|
}
|
|
if err := json.NewDecoder(r.Body).Decode(&payload); err != nil {
|
|
t.Error(err)
|
|
w.WriteHeader(400)
|
|
return
|
|
}
|
|
if strings.Contains(payload.URL, "broken") {
|
|
w.WriteHeader(502)
|
|
_, _ = io.WriteString(w, "image upstream unavailable")
|
|
return
|
|
}
|
|
_ = json.NewEncoder(w).Encode(map[string]any{"status": 200, "content_type": "image/png", "body_base64": base64.StdEncoding.EncodeToString([]byte("owned-cover-bytes"))})
|
|
}))
|
|
t.Cleanup(gateway.Close)
|
|
browser := creatorGatewayBrowser{gateway: hub.Gateway{Endpoint: gateway.URL, Token: "test-token"}, environment: hub.EnvironmentContext{Env: hub.Env{Alias: "owned-cover-alias"}, RuntimeID: "runtime-cover", RuntimeNetworkID: "network-cover", BindingVersion: 1}}
|
|
if err := cacheWorkCovers(ctx, store, browser, creator.SourceOwned, owner.ID); err == nil || !strings.Contains(err.Error(), works["broken"].ID) {
|
|
t.Fatalf("individual failure was hidden: %v", err)
|
|
}
|
|
if requests != 2 {
|
|
t.Fatalf("failure stopped other covers from downloading: %d", requests)
|
|
}
|
|
path, err := store.GetWorkCover(ctx, works["good"].ID)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if filepath.Base(filepath.Dir(path)) != owner.PlatformAccountKey || filepath.Base(path) != "owned-cover-good.png" {
|
|
t.Fatalf("wrong UID/work-ID layout: %s", path)
|
|
}
|
|
missing, err := store.ListWorksMissingCover(ctx, creator.SourceOwned, owner.ID)
|
|
if err != nil || len(missing) != 1 || missing[0].ID != works["broken"].ID {
|
|
t.Fatalf("cache retry targets: %v %v", missing, err)
|
|
}
|
|
app := fiber.New()
|
|
RegisterCreator(app, store, accounts, nil)
|
|
response, err := app.Test(httptest.NewRequest(http.MethodGet, fmt.Sprintf("/api/creator/works/%s/cover", works["good"].ID), nil))
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
defer response.Body.Close()
|
|
body, err := io.ReadAll(response.Body)
|
|
if err != nil || response.StatusCode != 200 || !strings.HasPrefix(response.Header.Get("Content-Type"), "image/png") || !bytes.Equal(body, []byte("owned-cover-bytes")) {
|
|
t.Fatalf("static cover response: %d %s %q %v", response.StatusCode, response.Header.Get("Content-Type"), body, err)
|
|
}
|
|
}
|