84 lines
3.4 KiB
Go
84 lines
3.4 KiB
Go
package creator
|
|
|
|
import (
|
|
"errors"
|
|
"strings"
|
|
"testing"
|
|
"time"
|
|
)
|
|
|
|
func TestBuildWorkQueryAnalysis(t *testing.T) {
|
|
for _, field := range []string{"published_at", "likes", "comments_count", "shares", "collect_count", "play_count", "likes_growth"} {
|
|
for _, order := range []string{"asc", "desc"} {
|
|
query, _, err := buildWorkQuery(WorkFilter{SortBy: field, SortOrder: order})
|
|
if err != nil {
|
|
t.Fatalf("%s %s: %v", field, order, err)
|
|
}
|
|
expected := field + " " + strings.ToUpper(order) + " NULLS LAST"
|
|
if field == "likes_growth" {
|
|
expected = "published_at DESC NULLS LAST"
|
|
}
|
|
if !strings.Contains(query, expected) || !strings.HasSuffix(query, ", id") {
|
|
t.Fatalf("unexpected query: %s", query)
|
|
}
|
|
}
|
|
}
|
|
after := time.Now().Add(-time.Hour)
|
|
before := time.Now()
|
|
query, args, err := buildWorkQuery(WorkFilter{Platform: "douyin", SourceType: SourceOwned, SourceID: "owned-1", PublishedAtStatus: "verified", PublishedAfter: &after, PublishedBefore: &before, MinLikes: int64Ptr(0), MinComments: int64Ptr(1), MinShares: int64Ptr(2), MinCollectCount: int64Ptr(3), MinPlayCount: int64Ptr(4)})
|
|
if err != nil || len(args) != 11 {
|
|
t.Fatalf("query=%s args=%v err=%v", query, args, err)
|
|
}
|
|
for _, column := range []string{"likes", "comments_count", "shares", "collect_count", "play_count"} {
|
|
if !strings.Contains(query, column+" IS NOT NULL AND "+column+" >=") {
|
|
t.Fatalf("nil threshold must be excluded: %s", query)
|
|
}
|
|
}
|
|
query, _, err = buildWorkQuery(WorkFilter{})
|
|
if err != nil || !strings.Contains(query, "ORDER BY published_at DESC NULLS LAST, id") {
|
|
t.Fatalf("default: %s %v", query, err)
|
|
}
|
|
for _, status := range []string{"verified", "future", "pending_verification", "invalid"} {
|
|
if _, _, err := buildWorkQuery(WorkFilter{PublishedAtStatus: status, SourceType: SourceCompetitor}); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
}
|
|
for _, filter := range []WorkFilter{
|
|
{SortBy: "likes; DROP TABLE creator_work"}, {SortOrder: "invalid"}, {Platform: "invalid"}, {SourceType: "invalid"}, {PublishedAtStatus: "unknown"},
|
|
{PublishedAfter: &before, PublishedBefore: &after},
|
|
{MinLikes: int64Ptr(-1)}, {MinComments: int64Ptr(-1)}, {MinShares: int64Ptr(-1)}, {MinCollectCount: int64Ptr(-1)}, {MinPlayCount: int64Ptr(-1)},
|
|
} {
|
|
if _, _, err := buildWorkQuery(filter); !errors.Is(err, ErrInvalid) {
|
|
t.Fatalf("invalid filter accepted: %+v, %v", filter, err)
|
|
}
|
|
}
|
|
}
|
|
|
|
func TestAnalysisGrowthSortBeforePagination(t *testing.T) {
|
|
works := []Work{{ID: "unknown"}, {ID: "low", LikesGrowth: int64Ptr(1)}, {ID: "high", LikesGrowth: int64Ptr(9)}, {ID: "equal", LikesGrowth: int64Ptr(9)}}
|
|
for _, tc := range []struct {
|
|
order string
|
|
ids []string
|
|
}{
|
|
{"desc", []string{"high", "equal", "low", "unknown"}},
|
|
{"asc", []string{"low", "high", "equal", "unknown"}},
|
|
} {
|
|
items := append([]Work(nil), works...)
|
|
sortWorksGrowth(items, tc.order)
|
|
for i, id := range tc.ids {
|
|
if items[i].ID != id {
|
|
t.Fatalf("%s: %+v", tc.order, items)
|
|
}
|
|
}
|
|
page, err := slicePage(items, 2, 2)
|
|
if err != nil || page.Total != 4 || page.Data[0].ID != tc.ids[2] {
|
|
t.Fatalf("page=%+v err=%v", page, err)
|
|
}
|
|
}
|
|
sortWorksGrowth([]Work{{ID: "a"}, {ID: "b"}}, "desc")
|
|
filtered, err := ApplyWorkGrowthFilter(works, nil, WorkGrowthFilter{MinLikes: int64Ptr(0)})
|
|
if err != nil || len(filtered) != 3 || filtered[0].ID != "low" {
|
|
t.Fatalf("filter must preserve explicit sorting: %+v %v", filtered, err)
|
|
}
|
|
}
|