Files
creator-hub/internal/creator/account_collection_monitor_test.go
T
rogee e50bed9ad8
douyin-release-gate / verify (push) Failing after 18m54s
feat: add account events and private message management
Add Douyin notification polling, event details, and manual multi-account private messaging.

Refine environment memory settings, account operations, login collection recovery, and message UI; update tests and documentation.
2026-10-07 10:23:05 +08:00

111 lines
4.3 KiB
Go

package creator
import (
"encoding/json"
"fmt"
"strings"
"testing"
"time"
)
func TestCreatorPostgresMonitorViewIncludesCollectionCheckpoints(t *testing.T) {
store, accounts, ctx := openCreatorIntegrationStore(t)
accountID := createIntegrationAccount(t, ctx, accounts, fmt.Sprintf("9%d", time.Now().UnixNano()))
otherID := createIntegrationAccount(t, ctx, accounts, fmt.Sprintf("8%d", time.Now().UnixNano()))
for _, id := range []string{accountID, otherID} {
if err := store.EnsureAccountProfile(ctx, id); err != nil {
t.Fatal(err)
}
}
viewFor := func(id string) AccountMonitorView {
t.Helper()
views, err := store.ListAccountMonitorViews(ctx)
if err != nil {
t.Fatal(err)
}
for _, view := range views {
if view.ID == id {
return view
}
}
t.Fatalf("account %s missing from monitor views", id)
return AccountMonitorView{}
}
pending := viewFor(accountID)
if pending.WorksCollection.Status != "pending" || pending.CommentsCollection.Status != "pending" {
t.Fatalf("missing checkpoints must be pending, not healthy: %+v", pending)
}
now := time.Now().UTC()
works, err := store.beginCheckpoint(ctx, SourceOwned, accountID, "works", now.Add(-time.Hour), now)
if err != nil {
t.Fatal(err)
}
if viewFor(accountID).WorksCollection.Status != "running" {
t.Fatal("list must expose the currently running works checkpoint")
}
if err := store.finishCheckpoint(ctx, SourceOwned, accountID, "works", works, "succeeded", "", nil); err != nil {
t.Fatal(err)
}
completed := viewFor(accountID).WorksCollection
if completed.Status != "succeeded" || completed.LastCompletedAt == nil {
t.Fatalf("list must expose the real last completion: %+v", completed)
}
comments, err := store.beginCheckpoint(ctx, SourceOwned, accountID, "comments", now.Add(-time.Hour), now)
if err != nil {
t.Fatal(err)
}
if err := store.failCheckpoint(ctx, SourceOwned, accountID, "comments", comments, fmt.Errorf("comments transport failed")); err == nil {
t.Fatal("failed checkpoint must return the collection error")
}
works, err = store.beginCheckpoint(ctx, SourceOwned, accountID, "works", now, now.Add(time.Hour))
if err != nil {
t.Fatal(err)
}
if err := store.finishCheckpoint(ctx, SourceOwned, accountID, "works", works, "blocked", "browser is awaiting user login", nil); err != nil {
t.Fatal(err)
}
// Competitor checkpoints must never be mistaken for an owned-account result.
if _, err := store.beginCheckpoint(ctx, SourceCompetitor, accountID, "works", now, now.Add(2*time.Hour)); err != nil {
t.Fatal(err)
}
view := viewFor(accountID)
detail, err := store.GetAccountCollectionStatus(ctx, accountID)
if err != nil {
t.Fatal(err)
}
if view.WorksCollection.Status != detail.Works.Status || view.WorksCollection.LastError != detail.Works.LastError ||
view.WorksCollection.LastCompletedAt == nil || !view.WorksCollection.LastCompletedAt.Equal(*detail.Works.LastCompletedAt) {
t.Fatalf("list and detail works checkpoints differ: list=%+v detail=%+v", view.WorksCollection, detail.Works)
}
if !view.WorksCollection.LastCompletedAt.Equal(*completed.LastCompletedAt) {
t.Fatal("blocked attempt must not replace the previous successful completion time")
}
if view.CommentsCollection.Status != "failed" || view.CommentsCollection.LastError != "comments transport failed" || view.CommentsCollection.LastCompletedAt != nil {
t.Fatalf("comment failures must remain independent and not invent completion: %+v", view.CommentsCollection)
}
other := viewFor(otherID)
if other.WorksCollection.Status != "pending" || other.CommentsCollection.Status != "pending" {
t.Fatalf("one account's failures must not affect another: %+v", other)
}
payload, err := json.Marshal(view)
if err != nil {
t.Fatal(err)
}
if !strings.Contains(string(payload), `"works_collection"`) || !strings.Contains(string(payload), `"comments_collection"`) {
t.Fatalf("monitor API must include both checkpoints: %s", payload)
}
}
func TestCreatorPostgresMonitorViewDoesNotHideCheckpointReadFailure(t *testing.T) {
store, _, ctx := openCreatorIntegrationStore(t)
if _, err := store.db.ExecContext(ctx, `DROP TABLE creator_collection_checkpoint`); err != nil {
t.Fatal(err)
}
if _, err := store.ListAccountMonitorViews(ctx); err == nil {
t.Fatal("unreadable checkpoints must not be reported as healthy or pending")
}
}