douyin-release-gate / verify (push) Failing after 18m54s
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.
111 lines
4.3 KiB
Go
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")
|
|
}
|
|
}
|