303 lines
9.9 KiB
Go
303 lines
9.9 KiB
Go
package main
|
||
|
||
import (
|
||
"fmt"
|
||
"time"
|
||
|
||
"91porn-server/common/timeutil"
|
||
"91porn-server/models/v/checkinconfigmod"
|
||
"91porn-server/models/v/checkinprizemod"
|
||
"91porn-server/models/v/usercheckinmod"
|
||
|
||
fw "git.ruishengces.com/pub_tool/autotest"
|
||
"go.mongodb.org/mongo-driver/bson"
|
||
"go.mongodb.org/mongo-driver/bson/primitive"
|
||
)
|
||
|
||
type CheckinSuite struct {
|
||
env *Env
|
||
url string // AppBaseURL
|
||
prizeIds []primitive.ObjectID
|
||
}
|
||
|
||
func (s *CheckinSuite) Name() string { return "签到功能" }
|
||
|
||
func (s *CheckinSuite) Setup(ctx *fw.TestContext) error {
|
||
// 确保签到功能已启用
|
||
cfg, _ := checkinconfigmod.FindOne(bson.M{})
|
||
if cfg == nil {
|
||
if err := checkinconfigmod.InsertOne(&checkinconfigmod.CheckinConfig{
|
||
Enable: true,
|
||
Description: "测试签到",
|
||
}); err != nil {
|
||
return err
|
||
}
|
||
} else if !cfg.Enable {
|
||
if err := checkinconfigmod.UpdateOne(bson.M{"_id": cfg.ID}, bson.M{"$set": bson.M{"enable": true}}); err != nil {
|
||
return err
|
||
}
|
||
}
|
||
|
||
// 创建测试用签到奖品配置(连续签到第1~3天)
|
||
s.prizeIds = make([]primitive.ObjectID, 3)
|
||
for i := 0; i < 3; i++ {
|
||
id := primitive.NewObjectID()
|
||
s.prizeIds[i] = id
|
||
if err := checkinprizemod.InsertOne(&checkinprizemod.CheckinPrize{
|
||
ID: id,
|
||
Title: fmt.Sprintf("测试奖品第%d天", i+1),
|
||
CheckinDays: int64(i + 1),
|
||
CheckinType: checkinprizemod.CheckinTypeContinuously,
|
||
PrizeId: primitive.NewObjectID(), // 故意用不存在的奖品ID
|
||
PrizeName: fmt.Sprintf("测试奖品%d", i+1),
|
||
Status: true,
|
||
BigPrize: false,
|
||
}); err != nil {
|
||
return err
|
||
}
|
||
}
|
||
return nil
|
||
}
|
||
|
||
func (s *CheckinSuite) Teardown(ctx *fw.TestContext) {
|
||
s.cleanCheckins()
|
||
s.cleanPrizes()
|
||
}
|
||
|
||
func (s *CheckinSuite) cleanCheckins() {
|
||
for {
|
||
n, _ := usercheckinmod.DeleteOne(bson.M{"userId": s.env.TestUID})
|
||
if n == 0 {
|
||
break
|
||
}
|
||
}
|
||
}
|
||
|
||
func (s *CheckinSuite) cleanPrizes() {
|
||
for _, id := range s.prizeIds {
|
||
checkinprizemod.DeleteOne(bson.M{"_id": id})
|
||
}
|
||
}
|
||
|
||
func (s *CheckinSuite) insertRecord(date time.Time, contDays, cumDays int64) {
|
||
s.insertRecordWithGave(date, contDays, cumDays, true)
|
||
}
|
||
|
||
func (s *CheckinSuite) insertRecordWithGave(date time.Time, contDays, cumDays int64, gave bool) {
|
||
_ = usercheckinmod.InsertOne(&usercheckinmod.UserCheckin{
|
||
ID: primitive.NewObjectID(),
|
||
Date: timeutil.BeginOfTime(date),
|
||
UserId: s.env.TestUID,
|
||
Gave: gave,
|
||
ContinuouslyDays: contDays,
|
||
CumulativeDays: cumDays,
|
||
CreatedAt: date,
|
||
})
|
||
}
|
||
|
||
func (s *CheckinSuite) headers() map[string]string {
|
||
return map[string]string{
|
||
"Authorization": s.env.AppToken,
|
||
"User-Agent": "91porn/3.8.0 (Android; test)",
|
||
"X-User-Agent": "ver=3.8.0&sysType=android&devType=test&devId=checkin-test-001",
|
||
}
|
||
}
|
||
|
||
func (s *CheckinSuite) getPrize() *fw.Resp {
|
||
return fw.DoWithHeaders("POST", s.url+"/api/app/checkin/prize", map[string]interface{}{}, s.headers())
|
||
}
|
||
|
||
func (s *CheckinSuite) Run(ctx *fw.TestContext) {
|
||
s.testQueryEmpty(ctx)
|
||
s.testContinuous3Days(ctx)
|
||
s.testBrokenStreak(ctx)
|
||
s.testBrokenStreakOneDayGap(ctx)
|
||
s.testCrossMonthContinuous(ctx)
|
||
s.testTodayChecked(ctx)
|
||
s.testDoubleReward(ctx)
|
||
s.testCheckinAfterBroken(ctx)
|
||
s.testIsCheckedIn(ctx)
|
||
}
|
||
|
||
// 空数据查询
|
||
func (s *CheckinSuite) testQueryEmpty(ctx *fw.TestContext) {
|
||
s.cleanCheckins()
|
||
resp := s.getPrize()
|
||
ctx.CodeEqual("空数据查询-code=200", resp, 200)
|
||
data := resp.Data()
|
||
if data != nil {
|
||
checkin, _ := data["checkin"].(map[string]interface{})
|
||
if checkin != nil {
|
||
ctx.Equal("空数据-todayChecked=false", checkin["todayChecked"], false)
|
||
ctx.Equal("空数据-连续=0", fw.Num(checkin, "continuouslyDays"), float64(0))
|
||
ctx.Equal("空数据-累计=0", fw.Num(checkin, "cumulativeDays"), float64(0))
|
||
}
|
||
}
|
||
}
|
||
|
||
// 连续签到3天
|
||
func (s *CheckinSuite) testContinuous3Days(ctx *fw.TestContext) {
|
||
s.cleanCheckins()
|
||
now := time.Now().Local()
|
||
today := timeutil.BeginOfTime(now)
|
||
s.insertRecord(today.Add(-3*24*time.Hour), 1, 1)
|
||
s.insertRecord(today.Add(-2*24*time.Hour), 2, 2)
|
||
s.insertRecord(today.Add(-1*24*time.Hour), 3, 3)
|
||
|
||
resp := s.getPrize()
|
||
ctx.CodeEqual("连续3天-code=200", resp, 200)
|
||
data := resp.Data()
|
||
checkin, _ := data["checkin"].(map[string]interface{})
|
||
ctx.Equal("连续3天-todayChecked=false", checkin["todayChecked"], false)
|
||
ctx.Equal("连续3天-continuously=3", fw.Num(checkin, "continuouslyDays"), float64(3))
|
||
ctx.Equal("连续3天-cumulative=3", fw.Num(checkin, "cumulativeDays"), float64(3))
|
||
}
|
||
|
||
// 断签:4天前、3天前签到,昨天和前天没签
|
||
func (s *CheckinSuite) testBrokenStreak(ctx *fw.TestContext) {
|
||
s.cleanCheckins()
|
||
now := time.Now().Local()
|
||
today := timeutil.BeginOfTime(now)
|
||
s.insertRecord(today.Add(-4*24*time.Hour), 1, 1)
|
||
s.insertRecord(today.Add(-3*24*time.Hour), 2, 2)
|
||
|
||
resp := s.getPrize()
|
||
ctx.CodeEqual("断签-code=200", resp, 200)
|
||
checkin, _ := resp.Data()["checkin"].(map[string]interface{})
|
||
ctx.Equal("断签-continuously=0", fw.Num(checkin, "continuouslyDays"), float64(0))
|
||
ctx.Equal("断签-cumulative=2", fw.Num(checkin, "cumulativeDays"), float64(2))
|
||
}
|
||
|
||
// 中间断一天:3天前签,2天前没签,昨天签
|
||
func (s *CheckinSuite) testBrokenStreakOneDayGap(ctx *fw.TestContext) {
|
||
s.cleanCheckins()
|
||
now := time.Now().Local()
|
||
today := timeutil.BeginOfTime(now)
|
||
s.insertRecord(today.Add(-3*24*time.Hour), 1, 1)
|
||
s.insertRecord(today.Add(-1*24*time.Hour), 1, 2)
|
||
|
||
resp := s.getPrize()
|
||
ctx.CodeEqual("断一天-code=200", resp, 200)
|
||
checkin, _ := resp.Data()["checkin"].(map[string]interface{})
|
||
ctx.Equal("断一天-continuously=1", fw.Num(checkin, "continuouslyDays"), float64(1))
|
||
ctx.Equal("断一天-cumulative=2", fw.Num(checkin, "cumulativeDays"), float64(2))
|
||
}
|
||
|
||
// 跨月:上月记录不计入连续
|
||
func (s *CheckinSuite) testCrossMonthContinuous(ctx *fw.TestContext) {
|
||
s.cleanCheckins()
|
||
now := time.Now().Local()
|
||
beginOfMonth := timeutil.BeginningOfMonth(now)
|
||
s.insertRecord(beginOfMonth.Add(-3*24*time.Hour), 1, 1)
|
||
s.insertRecord(beginOfMonth.Add(-2*24*time.Hour), 2, 2)
|
||
s.insertRecord(beginOfMonth.Add(-1*24*time.Hour), 3, 3)
|
||
|
||
resp := s.getPrize()
|
||
ctx.CodeEqual("跨月-code=200", resp, 200)
|
||
checkin, _ := resp.Data()["checkin"].(map[string]interface{})
|
||
ctx.Equal("跨月-continuously=0", fw.Num(checkin, "continuouslyDays"), float64(0))
|
||
ctx.Info(fmt.Sprintf("跨月-cumulative=%v (含上月记录,原版行为)", fw.Num(checkin, "cumulativeDays")))
|
||
}
|
||
|
||
// 今天已签到
|
||
func (s *CheckinSuite) testTodayChecked(ctx *fw.TestContext) {
|
||
s.cleanCheckins()
|
||
now := time.Now().Local()
|
||
today := timeutil.BeginOfTime(now)
|
||
if now.Day() < 3 {
|
||
ctx.Info("月初不足3天,跳过今天已签到测试")
|
||
return
|
||
}
|
||
s.insertRecord(today.Add(-2*24*time.Hour), 1, 1)
|
||
s.insertRecord(today.Add(-1*24*time.Hour), 2, 2)
|
||
s.insertRecord(today, 3, 3)
|
||
|
||
resp := s.getPrize()
|
||
ctx.CodeEqual("今天已签到-code=200", resp, 200)
|
||
checkin, _ := resp.Data()["checkin"].(map[string]interface{})
|
||
ctx.Equal("今天已签到-todayChecked=true", checkin["todayChecked"], true)
|
||
ctx.Equal("今天已签到-continuously=3", fw.Num(checkin, "continuouslyDays"), float64(3))
|
||
}
|
||
|
||
// 第7天双倍奖励
|
||
func (s *CheckinSuite) testDoubleReward(ctx *fw.TestContext) {
|
||
s.cleanCheckins()
|
||
now := time.Now().Local()
|
||
today := timeutil.BeginOfTime(now)
|
||
if now.Day() < 7 {
|
||
ctx.Info("本月不足7天,跳过双倍奖励测试")
|
||
return
|
||
}
|
||
for i := 6; i >= 1; i-- {
|
||
d := today.Add(time.Duration(-i) * 24 * time.Hour)
|
||
s.insertRecord(d, int64(7-i), int64(7-i))
|
||
}
|
||
|
||
resp := s.getPrize()
|
||
ctx.CodeEqual("双倍奖励-code=200", resp, 200)
|
||
checkin, _ := resp.Data()["checkin"].(map[string]interface{})
|
||
ctx.Equal("6天连续+未签到-doubleReward=true", checkin["doubleReward"], true)
|
||
ctx.Equal("6天连续-continuously=6", fw.Num(checkin, "continuouslyDays"), float64(6))
|
||
}
|
||
|
||
// 断签后恢复
|
||
func (s *CheckinSuite) testCheckinAfterBroken(ctx *fw.TestContext) {
|
||
s.cleanCheckins()
|
||
now := time.Now().Local()
|
||
today := timeutil.BeginOfTime(now)
|
||
if now.Day() < 5 {
|
||
ctx.Info("月初不足5天,跳过断签恢复测试")
|
||
return
|
||
}
|
||
s.insertRecord(today.Add(-5*24*time.Hour), 1, 1)
|
||
s.insertRecord(today.Add(-4*24*time.Hour), 2, 2)
|
||
// 3天前和2天前断签
|
||
s.insertRecord(today.Add(-1*24*time.Hour), 1, 3)
|
||
|
||
resp := s.getPrize()
|
||
ctx.CodeEqual("断签恢复-code=200", resp, 200)
|
||
checkin, _ := resp.Data()["checkin"].(map[string]interface{})
|
||
ctx.Equal("断签恢复-continuously=1", fw.Num(checkin, "continuouslyDays"), float64(1))
|
||
ctx.Equal("断签恢复-cumulative=3", fw.Num(checkin, "cumulativeDays"), float64(3))
|
||
}
|
||
|
||
// isCheckedIn字段:签到但未发奖时isCheckedIn=true,isReceive=false
|
||
func (s *CheckinSuite) testIsCheckedIn(ctx *fw.TestContext) {
|
||
s.cleanCheckins()
|
||
now := time.Now().Local()
|
||
today := timeutil.BeginOfTime(now)
|
||
if now.Day() < 3 {
|
||
ctx.Info("月初不足3天,跳过isCheckedIn测试")
|
||
return
|
||
}
|
||
// 第1天正常发奖,第2天签到但未发奖(Gave=false),第3天正常发奖
|
||
s.insertRecord(today.Add(-2*24*time.Hour), 1, 1)
|
||
s.insertRecordWithGave(today.Add(-1*24*time.Hour), 2, 2, false) // 签到了但奖品未发放
|
||
s.insertRecord(today, 3, 3)
|
||
|
||
resp := s.getPrize()
|
||
ctx.CodeEqual("isCheckedIn-code=200", resp, 200)
|
||
data := resp.Data()
|
||
|
||
prizes, _ := data["prizes"].([]interface{})
|
||
if len(prizes) < 3 {
|
||
ctx.Info(fmt.Sprintf("prizes数量不足3个(got=%d),跳过isCheckedIn断言", len(prizes)))
|
||
return
|
||
}
|
||
|
||
// 第1天:isCheckedIn=true, isReceive=true
|
||
p1, _ := prizes[0].(map[string]interface{})
|
||
ctx.Equal("第1天-isCheckedIn=true", p1["isCheckedIn"], true)
|
||
ctx.Equal("第1天-isReceive=true", p1["isReceive"], true)
|
||
|
||
// 第2天:签到了但未发奖 → isCheckedIn=true, isReceive=false
|
||
p2, _ := prizes[1].(map[string]interface{})
|
||
ctx.Equal("第2天-isCheckedIn=true(签到未发奖)", p2["isCheckedIn"], true)
|
||
ctx.Equal("第2天-isReceive=false(奖品未发放)", p2["isReceive"], false)
|
||
|
||
// 第3天:isCheckedIn=true, isReceive=true
|
||
p3, _ := prizes[2].(map[string]interface{})
|
||
ctx.Equal("第3天-isCheckedIn=true", p3["isCheckedIn"], true)
|
||
ctx.Equal("第3天-isReceive=true", p3["isReceive"], true)
|
||
}
|