143 lines
5.1 KiB
Go
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
|
|
}
|