Files
creator-hub/internal/creator/event_details_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

142 lines
5.4 KiB
Go

package creator
import (
"errors"
"fmt"
"os"
"path/filepath"
"strings"
"testing"
"time"
)
func TestEventDetailsValidateWithoutDroppingFailures(t *testing.T) {
d := ListenerDelivery{DeliveryID: "1", Kind: "notice", Notice: &ListenerNotice{EventKey: "2", EventType: "like", WorkAuthorUID: "123", WorkCoverError: "download failed"}}
if err := d.Validate(); err != nil {
t.Fatal(err)
}
d.Notice.WorkAuthorUID = "../123"
if !errors.Is(d.Validate(), ErrInvalid) {
t.Fatal("bad author identity accepted")
}
d.Notice.WorkAuthorUID = "123"
d.Notice.InteractorName = strings.Repeat("x", 32769)
if !errors.Is(d.Validate(), ErrInvalid) {
t.Fatal("oversized profile accepted")
}
}
func TestEventCoverUsesPlatformIdentityWithoutPlaceholderWork(t *testing.T) {
s := &Store{coverDirectory: t.TempDir()}
if _, err := s.GetPlatformWorkCover("123", "456"); !errors.Is(err, ErrNotFound) {
t.Fatal(err)
}
if err := s.SavePlatformWorkCover("123", "456", "image/webp", []byte("image")); err != nil {
t.Fatal(err)
}
path, err := s.GetPlatformWorkCover("123", "456")
if err != nil || path != filepath.Join(s.coverDirectory, "123", "456.webp") {
t.Fatalf("%s %v", path, err)
}
if err := s.SavePlatformWorkCover("../bad", "456", "image/png", []byte("image")); !errors.Is(err, ErrInvalid) {
t.Fatal(err)
}
if err := s.SavePlatformWorkCover("123", "456", "text/html", []byte("bad")); !errors.Is(err, ErrInvalid) {
t.Fatal(err)
}
if err := os.WriteFile(path, []byte{}, 0600); err != nil {
t.Fatal(err)
}
if _, err := s.GetPlatformWorkCover("123", "456"); !errors.Is(err, ErrInvalid) {
t.Fatal(err)
}
}
func TestEventDetailsBackfillPreservesMessageAndTimes(t *testing.T) {
store, accounts, ctx := openCreatorIntegrationStore(t)
store.coverDirectory = t.TempDir()
id := createIntegrationAccount(t, ctx, accounts, fmt.Sprint(time.Now().UnixNano()))
profile, err := store.GetAccountProfile(ctx, id)
if err != nil {
t.Fatal(err)
}
if _, err = store.RecordVerifiedLoginResult(ctx, id, profile.PlatformAccountKey); err != nil {
t.Fatal(err)
}
state, err := store.SetListenerEnabled(ctx, id, true)
if err != nil {
t.Fatal(err)
}
now := time.Now().UTC().Truncate(time.Microsecond)
d := ListenerDelivery{DeliveryID: "original", Kind: "notice", Baseline: true, Notice: &ListenerNotice{EventKey: "101", EventType: "comment", InteractorUID: "456", WorkID: "987", PlatformEventAt: &now, MessageText: "原评论"}}
if err = store.RecordListenerDeliveries(ctx, id, state.Generation, []ListenerDelivery{d}); err != nil {
t.Fatal(err)
}
d.DeliveryID = "details"
d.Notice.InteractorName = "用户昵称"
d.Notice.InteractorSecUID = "MS4wLjABAAAAprofile"
d.Notice.WorkAuthorUID = "123"
d.Notice.WorkCoverURL = "https://p3.douyinpic.com/cover.jpg"
d.Notice.WorkURL = "https://www.douyin.com/video/987"
d.Notice.MessageText = "不应覆盖的重读内容"
later := now.Add(time.Hour)
d.Notice.PlatformEventAt = &later
if err = store.SavePlatformWorkCover("123", "987", "image/jpeg", []byte("image")); err != nil {
t.Fatal(err)
}
if err = store.RecordListenerDeliveries(ctx, id, state.Generation, []ListenerDelivery{d}); err != nil {
t.Fatal(err)
}
page, err := store.ListAggregatedEventsPage(ctx, EventAggregationFilter{AccountID: id}, 1, 25)
if err != nil || page.Total != 1 {
t.Fatalf("%+v %v", page, err)
}
event := page.Data[0]
if event.InteractorName != "用户昵称" || event.InteractorSecUID != "MS4wLjABAAAAprofile" || !event.HasWorkCover {
t.Fatalf("details not filled: %+v", event)
}
if event.MessageText != "原评论" || !event.PlatformEventAt.Equal(now) || !event.Baseline {
t.Fatalf("original changed: %+v", event)
}
if _, err = store.GetEventWorkCover(ctx, event.ID); err != nil {
t.Fatal(err)
}
d.Notice.InteractorName = ""
d.Notice.InteractorSecUID = ""
d.Notice.WorkCoverURL = ""
d.Notice.WorkURL = ""
d.Notice.WorkAuthorUID = ""
if err = store.RecordListenerDeliveries(ctx, id, state.Generation, []ListenerDelivery{d}); err != nil {
t.Fatal(err)
}
page, err = store.ListAggregatedEventsPage(ctx, EventAggregationFilter{AccountID: id}, 1, 25)
if err != nil || page.Data[0].InteractorName != "用户昵称" || page.Data[0].WorkURL == "" {
t.Fatalf("partial response erased details: %+v %v", page, err)
}
d.Notice.InteractorUID = "789"
d.Notice.InteractorName = "不同用户"
d.Notice.InteractorSecUID = "other"
d.Notice.WorkID = "111"
d.Notice.WorkAuthorUID = "222"
d.Notice.WorkURL = "https://www.douyin.com/video/111"
if err = store.RecordListenerDeliveries(ctx, id, state.Generation, []ListenerDelivery{d}); err != nil {
t.Fatal(err)
}
page, err = store.ListAggregatedEventsPage(ctx, EventAggregationFilter{AccountID: id}, 1, 25)
if err != nil || page.Data[0].InteractorName != "用户昵称" || page.Data[0].InteractorSecUID != "MS4wLjABAAAAprofile" || page.Data[0].WorkAuthorUID != "123" || page.Data[0].WorkURL != "https://www.douyin.com/video/987" {
t.Fatalf("merged notification misattributed details: %+v %v", page, err)
}
if _, err = store.GetEventWorkCover(ctx, "bad"); !errors.Is(err, ErrInvalid) {
t.Fatal(err)
}
if _, err = store.GetEventWorkCover(ctx, "999999999"); !errors.Is(err, ErrNotFound) {
t.Fatal(err)
}
if _, err = store.SetListenerEnabled(ctx, id, false); err != nil {
t.Fatal(err)
}
if _, err = store.GetEventWorkCover(ctx, event.ID); !errors.Is(err, ErrNotFound) {
t.Fatalf("disabled account cover remained exposed: %v", err)
}
}