116 lines
4.5 KiB
Go
116 lines
4.5 KiB
Go
package dramaser
|
|
|
|
import (
|
|
"fmt"
|
|
"net/http/httptest"
|
|
"reflect"
|
|
"testing"
|
|
"time"
|
|
|
|
"91porn-server/models/v/mediamod"
|
|
|
|
"github.com/gin-gonic/gin/binding"
|
|
"go.mongodb.org/mongo-driver/bson"
|
|
"go.mongodb.org/mongo-driver/bson/primitive"
|
|
)
|
|
|
|
func TestDramaListSortMatchesMediaLibraryEnum(t *testing.T) {
|
|
tests := []struct {
|
|
name string
|
|
sortType int
|
|
want bson.D
|
|
}{
|
|
{name: "热门推荐", sortType: 1, want: bson.D{{Key: "sortCode", Value: -1}, {Key: "createdAt", Value: -1}, {Key: "_id", Value: -1}}},
|
|
{name: "最新上架", sortType: 2, want: bson.D{{Key: "latestPublishedAt", Value: -1}, {Key: "createdAt", Value: -1}, {Key: "_id", Value: -1}}},
|
|
{name: "最热", sortType: 3, want: bson.D{{Key: "countLike", Value: -1}, {Key: "createdAt", Value: -1}, {Key: "_id", Value: -1}}},
|
|
{name: "最多收藏", sortType: 4, want: bson.D{{Key: "countCollect", Value: -1}, {Key: "createdAt", Value: -1}, {Key: "_id", Value: -1}}},
|
|
}
|
|
for _, test := range tests {
|
|
t.Run(test.name, func(t *testing.T) {
|
|
request := httptest.NewRequest("GET", fmt.Sprintf("/?pageNumber=1&pageSize=20&sortType=%d", test.sortType), nil)
|
|
var params ListRequest
|
|
if err := binding.Query.Bind(request, ¶ms); err != nil {
|
|
t.Fatalf("bind sortType=%d: %v", test.sortType, err)
|
|
}
|
|
if got := dramaListSort(params.SortType); !reflect.DeepEqual(got, test.want) {
|
|
t.Fatalf("dramaListSort(%d) = %#v, want %#v", test.sortType, got, test.want)
|
|
}
|
|
})
|
|
}
|
|
|
|
legacyRequest := httptest.NewRequest("GET", "/?pageNumber=1&pageSize=20&sortType=7", nil)
|
|
if err := binding.Query.Bind(legacyRequest, &ListRequest{}); err == nil {
|
|
t.Fatal("bind legacy sortType=7 succeeded, want validation error")
|
|
}
|
|
}
|
|
|
|
func TestDramaFeedQueueVersionChangesWithCandidateSet(t *testing.T) {
|
|
now := time.Date(2026, 8, 28, 10, 0, 0, 0, time.FixedZone("CST", 8*60*60))
|
|
first := dramaFeedQueueVersion(now, []string{"media-b", "media-a"})
|
|
sameSet := dramaFeedQueueVersion(now.Add(time.Hour), []string{"media-a", "media-b"})
|
|
withNewDrama := dramaFeedQueueVersion(now.Add(time.Hour), []string{"media-a", "media-b", "media-c"})
|
|
nextDay := dramaFeedQueueVersion(now.Add(24*time.Hour), []string{"media-a", "media-b"})
|
|
|
|
if first != sameSet {
|
|
t.Fatalf("same-day candidate set produced different versions: %q != %q", first, sameSet)
|
|
}
|
|
if first == withNewDrama {
|
|
t.Fatalf("new candidate did not change queue version: %q", first)
|
|
}
|
|
if first == nextDay {
|
|
t.Fatalf("next day did not change queue version: %q", first)
|
|
}
|
|
}
|
|
|
|
func TestOrderFeedCandidatesPrioritizesRecommendedAndIsStable(t *testing.T) {
|
|
now := time.Date(2026, 8, 24, 12, 0, 0, 0, time.UTC)
|
|
recommended := &mediamod.Media{ID: primitive.NewObjectID(), SortCode: 10, CreatedAt: now.Add(-time.Hour)}
|
|
high := &mediamod.Media{ID: primitive.NewObjectID(), CountLike: 100, CreatedAt: now.Add(-48 * time.Hour)}
|
|
recent := &mediamod.Media{ID: primitive.NewObjectID(), CreatedAt: now.Add(-time.Hour)}
|
|
|
|
candidates := []*mediamod.Media{high, recent, recommended}
|
|
ordered := orderFeedCandidates(candidates, now)
|
|
again := orderFeedCandidates(candidates, now.Add(time.Minute))
|
|
if len(ordered) != 3 || len(again) != 3 {
|
|
t.Fatalf("ordered lengths = %d/%d, want 3/3", len(ordered), len(again))
|
|
}
|
|
if ordered[0].ID != recommended.ID {
|
|
t.Fatalf("first item = %s, want recommended %s", ordered[0].ID, recommended.ID)
|
|
}
|
|
for i := range ordered {
|
|
if ordered[i].ID != again[i].ID {
|
|
t.Fatalf("same-day queue changed at %d: %s != %s", i, ordered[i].ID, again[i].ID)
|
|
}
|
|
}
|
|
}
|
|
|
|
func TestValidateAnalyticsEventRequiresCheckoutContextForPaywall(t *testing.T) {
|
|
event := AnalyticsEvent{
|
|
EventID: "event-1", EventName: "DRAMA_PAYWALL_EXPOSURE", SessionID: "session-1",
|
|
OccurredAt: time.Now(), MediaID: primitive.NewObjectID(), ContentID: primitive.NewObjectID(),
|
|
Scene: "detail",
|
|
}
|
|
if err := validateAnalyticsEvent(event); err == nil {
|
|
t.Fatal("validateAnalyticsEvent() should reject missing checkoutContextId")
|
|
}
|
|
event.CheckoutContextID = "drama-checkout-test"
|
|
if err := validateAnalyticsEvent(event); err != nil {
|
|
t.Fatalf("validateAnalyticsEvent() error = %v", err)
|
|
}
|
|
}
|
|
|
|
func TestDramaInteractionScoreUses91PWeights(t *testing.T) {
|
|
media := &mediamod.Media{
|
|
CountLike: 1, CountCollect: 2, CountComment: 3, CountShare: 4, CountBrowse: 999,
|
|
}
|
|
if got, want := dramaInteractionScore(media), int64(34); got != want {
|
|
t.Fatalf("dramaInteractionScore() = %d, want %d", got, want)
|
|
}
|
|
}
|
|
|
|
func TestObjectIDStringReturnsEmptyForZeroID(t *testing.T) {
|
|
if got := objectIDString(primitive.NilObjectID); got != "" {
|
|
t.Fatalf("objectIDString(zero) = %q, want empty", got)
|
|
}
|
|
}
|