2026-06-25 15:07:46 +08:00

143 lines
5.1 KiB
Go

package cpweeklyrank_test
import (
"context"
"errors"
"strconv"
"testing"
"time"
"hyapp/pkg/appcode"
domain "hyapp/services/activity-service/internal/domain/cpweeklyrank"
service "hyapp/services/activity-service/internal/service/cpweeklyrank"
)
func TestGetStatusReturnsPreviousEntriesFromPreviousWeek(t *testing.T) {
now := time.Date(2026, 6, 24, 12, 0, 0, 0, time.UTC)
currentStart, currentEnd := service.WeekWindow(now)
previousStart, previousEnd := service.PreviousWeekWindow(now)
rankSource := &fakeCPWeeklyRankSource{
windows: map[[2]int64][]domain.Entry{
{currentStart.UnixMilli(), currentEnd.UnixMilli()}: cpWeeklyRankEntries(2, 1000),
{previousStart.UnixMilli(), previousEnd.UnixMilli()}: cpWeeklyRankEntries(5, 5000),
},
}
svc := service.New(&fakeCPWeeklyRankRepository{config: domain.Config{
AppCode: "lalu",
ActivityCode: domain.ActivityCode,
Enabled: true,
RelationType: "cp",
TopCount: 10,
}}, rankSource, nil)
svc.SetClock(func() time.Time { return now })
status, err := svc.GetStatus(appcode.WithContext(context.Background(), "lalu"), 1, 0)
if err != nil {
t.Fatalf("GetStatus failed: %v", err)
}
if len(status.Entries) != 1 {
t.Fatalf("current entries mismatch: %+v", status.Entries)
}
if len(status.PreviousEntries) != 3 {
t.Fatalf("previous entries should be limited to 3, got %+v", status.PreviousEntries)
}
if status.PreviousEntries[0].UserA.Username != "left-1" || status.PreviousEntries[0].UserA.Avatar != "https://avatar/left-1.png" ||
status.PreviousEntries[0].UserB.Username != "right-1" || status.PreviousEntries[0].UserB.Avatar != "https://avatar/right-1.png" ||
status.PreviousEntries[0].Score != 5001 {
t.Fatalf("previous entry should keep user snapshots and intimacy score: %+v", status.PreviousEntries[0])
}
if len(rankSource.calls) != 2 {
t.Fatalf("rank source call count mismatch: %+v", rankSource.calls)
}
if rankSource.calls[0].startMS != currentStart.UnixMilli() || rankSource.calls[0].endMS != currentEnd.UnixMilli() || rankSource.calls[0].limit != 1 {
t.Fatalf("current window call mismatch: %+v", rankSource.calls[0])
}
if rankSource.calls[1].startMS != previousStart.UnixMilli() || rankSource.calls[1].endMS != previousEnd.UnixMilli() || rankSource.calls[1].limit != 3 {
t.Fatalf("previous window call mismatch: %+v", rankSource.calls[1])
}
}
type fakeCPWeeklyRankRepository struct {
config domain.Config
}
func (r *fakeCPWeeklyRankRepository) GetCPWeeklyRankConfig(context.Context) (domain.Config, bool, error) {
return r.config, true, nil
}
func (r *fakeCPWeeklyRankRepository) UpdateCPWeeklyRankConfig(context.Context, domain.Config, int64) (domain.Config, error) {
return domain.Config{}, errors.New("not implemented")
}
func (r *fakeCPWeeklyRankRepository) ListCPWeeklyRankSettlements(context.Context, int64, int64) ([]domain.Settlement, error) {
return nil, errors.New("not implemented")
}
func (r *fakeCPWeeklyRankRepository) PrepareCPWeeklyRankSettlements(context.Context, domain.Config, []domain.Entry, int64, int64, int64) ([]domain.Settlement, error) {
return nil, errors.New("not implemented")
}
func (r *fakeCPWeeklyRankRepository) ListPendingCPWeeklyRankSettlements(context.Context, int64, int64, int) ([]domain.Settlement, error) {
return nil, errors.New("not implemented")
}
func (r *fakeCPWeeklyRankRepository) MarkCPWeeklyRankSettlementGranted(context.Context, string, string, int64) error {
return errors.New("not implemented")
}
func (r *fakeCPWeeklyRankRepository) MarkCPWeeklyRankSettlementFailed(context.Context, string, string, int64) error {
return errors.New("not implemented")
}
type fakeCPWeeklyRankSource struct {
calls []fakeCPWeeklyRankSourceCall
windows map[[2]int64][]domain.Entry
}
type fakeCPWeeklyRankSourceCall struct {
relationType string
startMS int64
endMS int64
limit int32
}
func (s *fakeCPWeeklyRankSource) ListCPWeeklyRankEntries(_ context.Context, relationType string, startMS int64, endMS int64, limit int32) ([]domain.Entry, error) {
s.calls = append(s.calls, fakeCPWeeklyRankSourceCall{
relationType: relationType,
startMS: startMS,
endMS: endMS,
limit: limit,
})
entries := append([]domain.Entry(nil), s.windows[[2]int64{startMS, endMS}]...)
if limit > 0 && len(entries) > int(limit) {
entries = entries[:limit]
}
return entries, nil
}
func cpWeeklyRankEntries(count int, baseScore int64) []domain.Entry {
entries := make([]domain.Entry, 0, count)
for index := 1; index <= count; index++ {
suffix := strconv.Itoa(index)
entries = append(entries, domain.Entry{
Rank: int64(index),
RelationshipID: "cp-rel-" + suffix,
RelationType: "cp",
Score: baseScore + int64(index),
UserA: domain.User{
UserID: int64(1000 + index),
DisplayUserID: "L" + suffix,
Username: "left-" + suffix,
Avatar: "https://avatar/left-" + suffix + ".png",
},
UserB: domain.User{
UserID: int64(2000 + index),
DisplayUserID: "R" + suffix,
Username: "right-" + suffix,
Avatar: "https://avatar/right-" + suffix + ".png",
},
})
}
return entries
}