package creator import ( "fmt" "testing" "time" ) func TestCreatorPostgresRecoversStaleProcessingWithoutRetry(t *testing.T) { store, phaseAStore, ctx := openCreatorIntegrationStore(t) stamp := time.Now().UnixNano() bigID, smallID, work, comment, _ := prepareIntegrationActionFixture(t, store, phaseAStore, ctx, fmt.Sprintf("%d", stamp)) recorded, err := store.RecordEvent(ctx, InteractionEvent{Platform: PlatformDouyin, ReceivingAccountID: bigID, EventKey: fmt.Sprintf("recovery-event-%d", stamp), EventType: "comment", InteractorUID: comment.AuthorUID, CommentID: comment.ID, WorkID: work.ID}) if err != nil { t.Fatalf("record event: result=%+v err=%v", recorded, err) } event := recorded.Event op, inserted, err := store.CreateOperation(ctx, OperationInput{IdempotencyKey: fmt.Sprintf("recovery-op-%d", stamp), Source: "manual", Action: ActionReplyComment, Platform: PlatformDouyin, AccountID: smallID, TargetUID: comment.AuthorUID, TargetCommentID: comment.ID, TargetWorkID: work.ID, Text: "reply", EventID: event.ID}) if err != nil || !inserted { t.Fatalf("create operation: operation=%+v inserted=%v err=%v", op, inserted, err) } old := time.Now().UTC().Add(-3 * time.Minute) if _, err := store.db.ExecContext(ctx, `UPDATE creator_operation SET source='automatic',state='processing',updated_at=$2 WHERE id=$1`, op.ID, old); err != nil { t.Fatal(err) } if _, err := store.db.ExecContext(ctx, `UPDATE creator_event SET state='processing',processing_started_at=$2 WHERE id=$1`, event.ID, old); err != nil { t.Fatal(err) } count, err := store.RecoverStaleProcessing(ctx, time.Now().UTC()) if err != nil || count != 1 { t.Fatalf("recover stale processing: count=%d err=%v", count, err) } recoveredOperation, err := store.GetOperation(ctx, op.ID) if err != nil || recoveredOperation.State != "uncertain" { t.Fatalf("operation was not made uncertain: operation=%+v err=%v", recoveredOperation, err) } recoveredEvent, err := store.GetEvent(ctx, event.ID) if err != nil || recoveredEvent.State != "uncertain" { t.Fatalf("event was not made uncertain: event=%+v err=%v", recoveredEvent, err) } }