@@ -0,0 +1,115 @@
|
||||
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)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user