Initial commit

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
2026-09-15 13:57:10 +08:00
co-authored by Claude Opus 5
commit 8679200f41
1897 changed files with 257900 additions and 0 deletions
+105
View File
@@ -0,0 +1,105 @@
package dailyAdverCalc
import (
"91porn-server/common"
"91porn-server/models/commod"
"91porn-server/models/s/dailyretentionmod"
"testing"
"time"
"go.mongodb.org/mongo-driver/bson"
)
func TestCalculateRetentionRate(t *testing.T) {
t.Run("zero cohort size returns zero", func(t *testing.T) {
if got := calculateRetentionRate(10, 0); got != 0 {
t.Fatalf("expected zero rate, got %v", got)
}
})
t.Run("uses retained divided by cohort size", func(t *testing.T) {
got := calculateRetentionRate(25, 100)
want := 0.25
if got != want {
t.Fatalf("expected %v, got %v", want, got)
}
})
}
func TestGetPrevAccum(t *testing.T) {
t.Run("nil item or day zero returns zeros", func(t *testing.T) {
adClick, totalClick, payCount, payTotal := getPrevAccum(nil, 0)
if adClick != 0 || totalClick != 0 || payCount != 0 || payTotal != 0 {
t.Fatalf("expected all zero values, got %d %d %d %d", adClick, totalClick, payCount, payTotal)
}
})
t.Run("reads previous day accumulators", func(t *testing.T) {
item := &dailyretentionmod.DailyRetention{
AdClickAcc: map[int]int64{1: 3, 2: 8},
TotalClickAcc: map[int]int64{1: 5, 2: 13},
PayCountAcc: map[int]int64{1: 1, 2: 2},
PayTotalAcc: map[int]int64{1: 100, 2: 300},
}
adClick, totalClick, payCount, payTotal := getPrevAccum(item, 3)
if adClick != 8 || totalClick != 13 || payCount != 2 || payTotal != 300 {
t.Fatalf("unexpected previous accum values: %d %d %d %d", adClick, totalClick, payCount, payTotal)
}
})
}
func TestBuildDailyRetentionUpsertData(t *testing.T) {
loc, err := time.LoadLocation("Asia/Shanghai")
if err != nil {
t.Fatalf("load location failed: %v", err)
}
regDay := time.Date(2026, 3, 18, 14, 25, 0, 0, loc)
now := time.Date(2026, 3, 19, 9, 30, 0, 0, loc)
t.Run("day zero writes new users and normalizes date", func(t *testing.T) {
filter, update := buildDailyRetentionUpsertData(regDay, commod.AdGroupA, 0, 12, 1, 4, 8, 2, 600, now)
wantDate := common.NormalizeDate(regDay)
if got := filter["date"].(time.Time); !got.Equal(wantDate) {
t.Fatalf("expected normalized date %v, got %v", wantDate, got)
}
if got := filter["adGroup"]; got != commod.AdGroupA {
t.Fatalf("expected ad group %v, got %v", commod.AdGroupA, got)
}
setOnInsert := update["$setOnInsert"].(bson.M)
if got := setOnInsert["date"].(time.Time); !got.Equal(wantDate) {
t.Fatalf("expected setOnInsert date %v, got %v", wantDate, got)
}
if got := setOnInsert["createdAt"].(time.Time); !got.Equal(now) {
t.Fatalf("expected createdAt %v, got %v", now, got)
}
setFields := update["$set"].(bson.M)
if got := setFields["userRetained.0"]; got != int64(12) {
t.Fatalf("expected userRetained.0 to be 12, got %v", got)
}
if got := setFields["userRates.0"]; got != float64(1) {
t.Fatalf("expected userRates.0 to be 1, got %v", got)
}
if got := setFields["newUsers"]; got != int64(12) {
t.Fatalf("expected newUsers to be 12, got %v", got)
}
})
t.Run("non day zero does not overwrite new users", func(t *testing.T) {
_, update := buildDailyRetentionUpsertData(regDay, commod.AdGroupB, 2, 6, 0.3, 9, 11, 3, 800, now)
setFields := update["$set"].(bson.M)
if got := setFields["userRetained.2"]; got != int64(6) {
t.Fatalf("expected userRetained.2 to be 6, got %v", got)
}
if got := setFields["userRates.2"]; got != 0.3 {
t.Fatalf("expected userRates.2 to be 0.3, got %v", got)
}
if _, ok := setFields["newUsers"]; ok {
t.Fatalf("did not expect newUsers on non-day-zero update")
}
})
}