999 lines
36 KiB
Go
999 lines
36 KiB
Go
package managercenter
|
|
|
|
import (
|
|
"context"
|
|
"errors"
|
|
"strings"
|
|
"testing"
|
|
"time"
|
|
|
|
"chatapp3-golang/internal/integration"
|
|
"chatapp3-golang/internal/model"
|
|
|
|
"gorm.io/driver/sqlite"
|
|
"gorm.io/gorm"
|
|
)
|
|
|
|
type fakeManagerGateway struct {
|
|
recharges map[int64][]integration.UserTotalRecharge
|
|
rechargeErr error
|
|
freightSellers map[int64]bool
|
|
freightSellerErr error
|
|
abilities map[int64]integration.PropsNobleVIPAbility
|
|
maxAbility integration.PropsNobleVIPAbility
|
|
giveRequests []integration.GivePropsBackpackRequest
|
|
punishRequests []integration.PunishAccountRequest
|
|
unblockRequests []integration.UnblockAccountRequest
|
|
switchIDs []int64
|
|
cacheCleared []int64
|
|
badgeActivations []fakeBadgeActivation
|
|
}
|
|
|
|
type fakeBadgeActivation struct {
|
|
userID int64
|
|
badgeID int64
|
|
days int
|
|
}
|
|
|
|
func (f *fakeManagerGateway) GetUserProfile(context.Context, int64) (integration.UserProfile, error) {
|
|
return integration.UserProfile{}, nil
|
|
}
|
|
|
|
func (f *fakeManagerGateway) GetUserProfileByAccountOne(context.Context, string) (integration.UserProfile, error) {
|
|
return integration.UserProfile{}, nil
|
|
}
|
|
|
|
func (f *fakeManagerGateway) MapUserTotalRecharge(_ context.Context, userIDs []int64) (map[int64][]integration.UserTotalRecharge, error) {
|
|
if f.rechargeErr != nil {
|
|
return nil, f.rechargeErr
|
|
}
|
|
result := make(map[int64][]integration.UserTotalRecharge, len(userIDs))
|
|
for _, userID := range userIDs {
|
|
result[userID] = f.recharges[userID]
|
|
}
|
|
return result, nil
|
|
}
|
|
|
|
func (f *fakeManagerGateway) ExistsFreightSeller(_ context.Context, userID int64) (bool, error) {
|
|
if f.freightSellerErr != nil {
|
|
return false, f.freightSellerErr
|
|
}
|
|
return f.freightSellers[userID], nil
|
|
}
|
|
|
|
func (f *fakeManagerGateway) GivePropsBackpack(_ context.Context, req integration.GivePropsBackpackRequest) error {
|
|
f.giveRequests = append(f.giveRequests, req)
|
|
return nil
|
|
}
|
|
|
|
func (f *fakeManagerGateway) GetNobleVIPAbility(_ context.Context, sourceID int64) (integration.PropsNobleVIPAbility, error) {
|
|
return f.abilities[sourceID], nil
|
|
}
|
|
|
|
func (f *fakeManagerGateway) GetUserMaxNobleVIPAbility(context.Context, int64) (integration.PropsNobleVIPAbility, error) {
|
|
return f.maxAbility, nil
|
|
}
|
|
|
|
func (f *fakeManagerGateway) SwitchUseProps(_ context.Context, _ int64, propsID int64) error {
|
|
f.switchIDs = append(f.switchIDs, propsID)
|
|
return nil
|
|
}
|
|
|
|
func (f *fakeManagerGateway) ActivateTemporaryBadge(_ context.Context, userID int64, badgeID int64, days int) error {
|
|
f.badgeActivations = append(f.badgeActivations, fakeBadgeActivation{userID: userID, badgeID: badgeID, days: days})
|
|
return nil
|
|
}
|
|
|
|
func (f *fakeManagerGateway) RemoveUserProfileCacheAll(_ context.Context, userID int64) error {
|
|
f.cacheCleared = append(f.cacheCleared, userID)
|
|
return nil
|
|
}
|
|
|
|
func (f *fakeManagerGateway) PunishAccount(_ context.Context, req integration.PunishAccountRequest) error {
|
|
f.punishRequests = append(f.punishRequests, req)
|
|
return nil
|
|
}
|
|
|
|
func (f *fakeManagerGateway) UnblockAccount(_ context.Context, req integration.UnblockAccountRequest) error {
|
|
f.unblockRequests = append(f.unblockRequests, req)
|
|
return nil
|
|
}
|
|
|
|
func TestListPropsRequiresAdminFreeAndFiltersVIPLevels(t *testing.T) {
|
|
service, _ := newManagerCenterTestService(t)
|
|
seedManager(t, service.db.(*gorm.DB), 1)
|
|
seedProps(t, service.db.(*gorm.DB),
|
|
propsSourceRecordRow{ID: 101, Type: propsTypeRide, Name: "Giftable ride", AdminFree: true},
|
|
propsSourceRecordRow{ID: 102, Type: propsTypeRide, Name: "Paid ride", AdminFree: false},
|
|
propsSourceRecordRow{ID: 201, Type: propsTypeNobleVIP, Name: "VIP 3", AdminFree: true},
|
|
propsSourceRecordRow{ID: 204, Type: propsTypeNobleVIP, Name: "VIP 4", AdminFree: true},
|
|
)
|
|
seedAbilities(t, service.db.(*gorm.DB),
|
|
propsNobleVIPAbilityRow{ID: 201, VIPLevel: 3},
|
|
propsNobleVIPAbilityRow{ID: 204, VIPLevel: 4},
|
|
)
|
|
|
|
resp, err := service.ListProps(context.Background(), AuthUser{UserID: 1}, "")
|
|
if err != nil {
|
|
t.Fatalf("ListProps() error = %v", err)
|
|
}
|
|
|
|
got := map[int64]PropsView{}
|
|
for _, item := range resp.Records {
|
|
got[item.ID.Int64()] = item
|
|
}
|
|
if _, ok := got[101]; !ok {
|
|
t.Fatalf("records = %+v, want giftable ride", resp.Records)
|
|
}
|
|
if _, ok := got[102]; ok {
|
|
t.Fatalf("records = %+v, non-admin-free props must be hidden", resp.Records)
|
|
}
|
|
if item, ok := got[201]; !ok || item.Days != defaultVIPGiftDays || item.VIPLevel != 3 {
|
|
t.Fatalf("vip 201 = %+v, want level 3 with 3 days", item)
|
|
}
|
|
if _, ok := got[204]; ok {
|
|
t.Fatalf("records = %+v, VIP level 4 must be hidden", resp.Records)
|
|
}
|
|
}
|
|
|
|
func TestListPropsReturnsVIPLevelConfigs(t *testing.T) {
|
|
service, _ := newManagerCenterTestService(t)
|
|
db := service.db.(*gorm.DB)
|
|
seedManager(t, db, 1)
|
|
seedVIPConfigs(t, db,
|
|
model.VipLevelConfig{ID: 301, SysOrigin: "LIKEI", Level: 1, LevelCode: "VIP1", DisplayName: "VIP 1", Enabled: true, DurationDays: 30},
|
|
model.VipLevelConfig{ID: 302, SysOrigin: "LIKEI", Level: 2, LevelCode: "VIP2", DisplayName: "VIP 2", Enabled: false, DurationDays: 30},
|
|
model.VipLevelConfig{ID: 303, SysOrigin: "ATYOU", Level: 1, LevelCode: "VIP1", DisplayName: "ATYOU VIP 1", Enabled: true, DurationDays: 30},
|
|
model.VipLevelConfig{ID: 304, SysOrigin: "LIKEI", Level: 4, LevelCode: "VIP4", DisplayName: "VIP 4", Enabled: true, DurationDays: 30},
|
|
)
|
|
|
|
resp, err := service.ListProps(context.Background(), AuthUser{UserID: 1, SysOrigin: "LIKEI"}, propsTypeNobleVIP)
|
|
if err != nil {
|
|
t.Fatalf("ListProps() error = %v", err)
|
|
}
|
|
if len(resp.Records) != 1 {
|
|
t.Fatalf("records = %+v, want only one enabled LIKEI vip config", resp.Records)
|
|
}
|
|
got := resp.Records[0]
|
|
if got.ID.Int64() != 301 || got.Type != propsTypeNobleVIP || got.VIPLevel != 1 || got.Days != 30 {
|
|
t.Fatalf("vip props = %+v, want config 301 level 1", got)
|
|
}
|
|
}
|
|
|
|
func TestGetProfileToleratesRechargeQueryFailure(t *testing.T) {
|
|
service, fake := newManagerCenterTestService(t)
|
|
db := service.db.(*gorm.DB)
|
|
seedManager(t, db, 1)
|
|
seedUsers(t, db, userBaseInfoRow{ID: 1, Account: "1"})
|
|
fake.rechargeErr = errors.New("order service unavailable")
|
|
|
|
resp, err := service.GetProfile(context.Background(), AuthUser{UserID: 1})
|
|
if err != nil {
|
|
t.Fatalf("GetProfile() error = %v", err)
|
|
}
|
|
if resp.Manager.HasRecharge || resp.Manager.CanBan {
|
|
t.Fatalf("manager = %+v, want unknown recharge state and ban disabled", resp.Manager)
|
|
}
|
|
}
|
|
|
|
func TestGetProfileReturnsManagerFeatures(t *testing.T) {
|
|
service, _ := newManagerCenterTestService(t)
|
|
db := service.db.(*gorm.DB)
|
|
seedManagerWithFeatures(t, db, 1, ManagerFeatures{
|
|
AddBDLeader: true,
|
|
GiftProps: false,
|
|
BanUser: true,
|
|
UnbanUser: false,
|
|
ChangeCountry: true,
|
|
})
|
|
seedUsers(t, db, userBaseInfoRow{ID: 1, Account: "1"})
|
|
|
|
resp, err := service.GetProfile(context.Background(), AuthUser{UserID: 1})
|
|
if err != nil {
|
|
t.Fatalf("GetProfile() error = %v", err)
|
|
}
|
|
if !resp.Features.AddBDLeader || resp.Features.GiftProps || !resp.Features.BanUser || resp.Features.UnbanUser || !resp.Features.ChangeCountry {
|
|
t.Fatalf("features = %+v, want row switches returned", resp.Features)
|
|
}
|
|
}
|
|
|
|
func TestAddBDLeaderCreatesLeaderAndListEntry(t *testing.T) {
|
|
service, _ := newManagerCenterTestService(t)
|
|
db := service.db.(*gorm.DB)
|
|
seedManager(t, db, 1)
|
|
seedUsers(t, db,
|
|
userBaseInfoRow{ID: 2, Account: "2002", UserNickname: "leader", OriginSys: "LIKEI"},
|
|
)
|
|
|
|
resp, err := service.AddBDLeader(context.Background(), AuthUser{UserID: 1, SysOrigin: "LIKEI"}, AddBDLeaderRequest{
|
|
UserID: ID(2),
|
|
Contact: "whatsapp",
|
|
})
|
|
if err != nil {
|
|
t.Fatalf("AddBDLeader() error = %v", err)
|
|
}
|
|
if !resp.Success || resp.Leader.UserID.Int64() != 2 || resp.Leader.RegionID != "SA" {
|
|
t.Fatalf("resp = %+v, want created leader for user 2 in manager region", resp)
|
|
}
|
|
|
|
var bdInfo businessDevelopmentBaseInfoRow
|
|
if err := db.Where("user_id = ?", int64(2)).First(&bdInfo).Error; err != nil {
|
|
t.Fatalf("load bd info: %v", err)
|
|
}
|
|
if bdInfo.BDLeadUserID == nil || *bdInfo.BDLeadUserID != 2 || bdInfo.Region != "SA" {
|
|
t.Fatalf("bd info = %+v, want self-linked BD leader info", bdInfo)
|
|
}
|
|
|
|
var identity userHistoryIdentityRow
|
|
if err := db.Where("user_id = ?", int64(2)).First(&identity).Error; err != nil {
|
|
t.Fatalf("load identity: %v", err)
|
|
}
|
|
if !identity.IsBD {
|
|
t.Fatalf("identity = %+v, want is_bd=true", identity)
|
|
}
|
|
|
|
list, err := service.ListBDLeaders(context.Background(), AuthUser{UserID: 1, SysOrigin: "LIKEI"})
|
|
if err != nil {
|
|
t.Fatalf("ListBDLeaders() error = %v", err)
|
|
}
|
|
if list.Count != 1 || list.Records[0].UserID.Int64() != 2 || list.Records[0].Account != "2002" {
|
|
t.Fatalf("list = %+v, want one created leader", list)
|
|
}
|
|
}
|
|
|
|
func TestAddBDLeaderRejectsExistingLeader(t *testing.T) {
|
|
service, _ := newManagerCenterTestService(t)
|
|
db := service.db.(*gorm.DB)
|
|
seedManager(t, db, 1)
|
|
seedUsers(t, db, userBaseInfoRow{ID: 2, Account: "2002", OriginSys: "LIKEI"})
|
|
if err := db.Create(&bdLeaderRow{ID: 10, UserID: 2, Origin: "LIKEI", RegionID: "SA", CreateUser: 1}).Error; err != nil {
|
|
t.Fatalf("seed bd leader: %v", err)
|
|
}
|
|
|
|
_, err := service.AddBDLeader(context.Background(), AuthUser{UserID: 1, SysOrigin: "LIKEI"}, AddBDLeaderRequest{UserID: ID(2)})
|
|
assertAppErrorCode(t, err, "user_already_bd_leader")
|
|
}
|
|
|
|
func TestAddBDLeaderRejectsTargetFromOtherOrigin(t *testing.T) {
|
|
service, _ := newManagerCenterTestService(t)
|
|
db := service.db.(*gorm.DB)
|
|
seedManager(t, db, 1)
|
|
seedUsers(t, db, userBaseInfoRow{ID: 2, Account: "2002", OriginSys: "ATYOU"})
|
|
|
|
_, err := service.AddBDLeader(context.Background(), AuthUser{UserID: 1, SysOrigin: "LIKEI"}, AddBDLeaderRequest{UserID: ID(2)})
|
|
assertAppErrorCode(t, err, "bd_leader_origin_mismatch")
|
|
}
|
|
|
|
func TestAddBDLeaderRejectsDisabledFeature(t *testing.T) {
|
|
service, _ := newManagerCenterTestService(t)
|
|
db := service.db.(*gorm.DB)
|
|
seedManagerWithFeatures(t, db, 1, ManagerFeatures{GiftProps: true, BanUser: true, UnbanUser: true})
|
|
seedUsers(t, db, userBaseInfoRow{ID: 2, Account: "2002", OriginSys: "LIKEI"})
|
|
|
|
_, err := service.AddBDLeader(context.Background(), AuthUser{UserID: 1, SysOrigin: "LIKEI"}, AddBDLeaderRequest{UserID: ID(2)})
|
|
assertAppErrorCode(t, err, "manager_feature_disabled")
|
|
|
|
var count int64
|
|
if err := db.Model(&bdLeaderRow{}).Where("user_id = ?", int64(2)).Count(&count).Error; err != nil {
|
|
t.Fatalf("count bd leaders: %v", err)
|
|
}
|
|
if count != 0 {
|
|
t.Fatalf("bd leader count = %d, want 0", count)
|
|
}
|
|
}
|
|
|
|
func TestSendPropsRejectsNonAdminFree(t *testing.T) {
|
|
service, fake := newManagerCenterTestService(t)
|
|
db := service.db.(*gorm.DB)
|
|
seedManager(t, db, 1)
|
|
seedUsers(t, db, userBaseInfoRow{ID: 2, Account: "2"})
|
|
seedProps(t, db, propsSourceRecordRow{ID: 102, Type: propsTypeRide, Name: "Paid ride", AdminFree: false})
|
|
|
|
_, err := service.SendProps(context.Background(), AuthUser{UserID: 1}, SendPropsRequest{
|
|
AcceptUserID: ID(2),
|
|
PropsID: ID(102),
|
|
})
|
|
assertAppErrorCode(t, err, "prop_not_giftable")
|
|
if len(fake.giveRequests) != 0 {
|
|
t.Fatalf("give requests = %+v, want none", fake.giveRequests)
|
|
}
|
|
}
|
|
|
|
func TestSendNobleVIPGivesAccessoriesAndSwitchesMax(t *testing.T) {
|
|
service, fake := newManagerCenterTestService(t)
|
|
db := service.db.(*gorm.DB)
|
|
seedManager(t, db, 1)
|
|
seedUsers(t, db, userBaseInfoRow{ID: 2, Account: "2"})
|
|
seedProps(t, db, propsSourceRecordRow{ID: 201, Type: propsTypeNobleVIP, Name: "VIP 3", AdminFree: true})
|
|
seedAbilities(t, db, propsNobleVIPAbilityRow{ID: 201, VIPLevel: 3})
|
|
fake.abilities[201] = integration.PropsNobleVIPAbility{
|
|
ID: integration.Int64Value(201),
|
|
AvatarFrameID: integration.Int64Value(302),
|
|
CarID: integration.Int64Value(301),
|
|
ChatBubbleID: integration.Int64Value(303),
|
|
DataCardID: integration.Int64Value(304),
|
|
}
|
|
fake.maxAbility = fake.abilities[201]
|
|
|
|
resp, err := service.SendProps(context.Background(), AuthUser{UserID: 1}, SendPropsRequest{
|
|
AcceptUserID: ID(2),
|
|
PropsID: ID(201),
|
|
})
|
|
if err != nil {
|
|
t.Fatalf("SendProps() error = %v", err)
|
|
}
|
|
if !resp.Success || resp.Days != defaultVIPGiftDays {
|
|
t.Fatalf("resp = %+v, want success and VIP days", resp)
|
|
}
|
|
if len(fake.giveRequests) != 5 {
|
|
t.Fatalf("give requests = %+v, want main VIP plus 4 accessories", fake.giveRequests)
|
|
}
|
|
for _, req := range fake.giveRequests {
|
|
if req.AcceptUserID != 2 || req.Origin != adminFreeOrigin || req.OpUser != 1 || !req.UseProps || req.AllowGive {
|
|
t.Fatalf("give request = %+v, want admin-free grant to target", req)
|
|
}
|
|
}
|
|
wantSwitch := []int64{201, 302, 304, 301, 303}
|
|
if !equalInt64Slice(fake.switchIDs, wantSwitch) {
|
|
t.Fatalf("switch ids = %+v, want %+v", fake.switchIDs, wantSwitch)
|
|
}
|
|
if !equalInt64Slice(fake.cacheCleared, []int64{2}) {
|
|
t.Fatalf("cacheCleared = %+v, want [2]", fake.cacheCleared)
|
|
}
|
|
}
|
|
|
|
func TestSendPropsRejectsDisabledFeature(t *testing.T) {
|
|
service, fake := newManagerCenterTestService(t)
|
|
db := service.db.(*gorm.DB)
|
|
seedManagerWithFeatures(t, db, 1, ManagerFeatures{AddBDLeader: true, BanUser: true, UnbanUser: true})
|
|
seedUsers(t, db, userBaseInfoRow{ID: 2, Account: "2"})
|
|
seedProps(t, db, propsSourceRecordRow{ID: 101, Type: propsTypeRide, Name: "Giftable ride", AdminFree: true})
|
|
|
|
_, err := service.SendProps(context.Background(), AuthUser{UserID: 1}, SendPropsRequest{
|
|
AcceptUserID: ID(2),
|
|
PropsID: ID(101),
|
|
})
|
|
assertAppErrorCode(t, err, "manager_feature_disabled")
|
|
if len(fake.giveRequests) != 0 {
|
|
t.Fatalf("give requests = %+v, want none", fake.giveRequests)
|
|
}
|
|
}
|
|
|
|
func TestSendBadgeActivatesBadgeBackpack(t *testing.T) {
|
|
service, fake := newManagerCenterTestService(t)
|
|
db := service.db.(*gorm.DB)
|
|
seedManager(t, db, 1)
|
|
seedUsers(t, db, userBaseInfoRow{ID: 2, Account: "2"})
|
|
seedProps(t, db, propsSourceRecordRow{ID: 501, Type: propsTypeBadge, Name: "Activity badge", AdminFree: true})
|
|
|
|
resp, err := service.SendProps(context.Background(), AuthUser{UserID: 1}, SendPropsRequest{
|
|
AcceptUserID: ID(2),
|
|
PropsID: ID(501),
|
|
})
|
|
if err != nil {
|
|
t.Fatalf("SendProps() error = %v", err)
|
|
}
|
|
if !resp.Success || resp.Type != propsTypeBadge || resp.Days != defaultGiftDays {
|
|
t.Fatalf("resp = %+v, want badge success with default days", resp)
|
|
}
|
|
if len(fake.badgeActivations) != 1 {
|
|
t.Fatalf("badge activations = %+v, want one", fake.badgeActivations)
|
|
}
|
|
if got := fake.badgeActivations[0]; got.userID != 2 || got.badgeID != 501 || got.days != defaultGiftDays {
|
|
t.Fatalf("badge activation = %+v, want user 2 badge 501 days %d", got, defaultGiftDays)
|
|
}
|
|
if len(fake.giveRequests) != 0 {
|
|
t.Fatalf("give requests = %+v, want no props backpack grant", fake.giveRequests)
|
|
}
|
|
}
|
|
|
|
func TestSendVIPUsesVIPLevelConfig(t *testing.T) {
|
|
service, _ := newManagerCenterTestService(t)
|
|
db := service.db.(*gorm.DB)
|
|
seedManager(t, db, 1)
|
|
seedUsers(t, db,
|
|
userBaseInfoRow{ID: 1, Account: "1", UserNickname: "manager", OriginSys: "LIKEI"},
|
|
userBaseInfoRow{ID: 2, Account: "2", OriginSys: "LIKEI"},
|
|
)
|
|
seedVIPConfigs(t, db, model.VipLevelConfig{
|
|
ID: 301,
|
|
SysOrigin: "LIKEI",
|
|
Level: 3,
|
|
LevelCode: "VIP3",
|
|
DisplayName: "VIP 3",
|
|
Enabled: true,
|
|
DurationDays: 30,
|
|
PriceGold: 3000,
|
|
})
|
|
|
|
resp, err := service.SendProps(context.Background(), AuthUser{UserID: 1, SysOrigin: "LIKEI"}, SendPropsRequest{
|
|
AcceptUserID: ID(2),
|
|
PropsID: ID(301),
|
|
})
|
|
if err != nil {
|
|
t.Fatalf("SendProps() error = %v", err)
|
|
}
|
|
if !resp.Success || resp.Type != propsTypeNobleVIP || resp.VIPLevel != 3 || resp.Days != 30 {
|
|
t.Fatalf("resp = %+v, want vip gift success", resp)
|
|
}
|
|
|
|
var state model.UserVipState
|
|
if err := db.Where("sys_origin = ? AND user_id = ?", "LIKEI", int64(2)).First(&state).Error; err != nil {
|
|
t.Fatalf("load state: %v", err)
|
|
}
|
|
if state.Level != 3 || state.Status != vipStatusActive {
|
|
t.Fatalf("state = %+v, want vip3 active", state)
|
|
}
|
|
var orders int64
|
|
if err := db.Model(&model.VipOrderRecord{}).Where("user_id = ? AND order_type = ?", int64(2), vipOrderTypeGMGift).Count(&orders).Error; err != nil {
|
|
t.Fatalf("count orders: %v", err)
|
|
}
|
|
if orders != 1 {
|
|
t.Fatalf("orders = %d, want 1", orders)
|
|
}
|
|
var records int64
|
|
if err := db.Model(&gmVIPGiftRecordRow{}).Where("user_id = ? AND vip_level = ?", int64(2), 3).Count(&records).Error; err != nil {
|
|
t.Fatalf("count gift records: %v", err)
|
|
}
|
|
if records != 1 {
|
|
t.Fatalf("gift records = %d, want 1", records)
|
|
}
|
|
}
|
|
|
|
func TestVIPGiftCleanupExpiresOldVIPResourcesOnly(t *testing.T) {
|
|
service, _ := newManagerCenterTestService(t)
|
|
db := service.db.(*gorm.DB)
|
|
if err := db.AutoMigrate(&managerVIPCleanupPropsRow{}, &managerVIPCleanupBadgeRow{}); err != nil {
|
|
t.Fatalf("auto migrate cleanup tables: %v", err)
|
|
}
|
|
now := time.Date(2026, 5, 30, 10, 0, 0, 0, time.UTC)
|
|
future := now.AddDate(0, 0, 20)
|
|
userID := int64(2)
|
|
|
|
seedManagerVIPCleanupProps(t, db,
|
|
managerVIPCleanupPropsRow{ID: 1, UserID: userID, PropsID: 101, Type: propsTypeAvatarFrame, ExpireTime: future, UseProps: true, AllowGive: true},
|
|
managerVIPCleanupPropsRow{ID: 2, UserID: userID, PropsID: 201, Type: propsTypeAvatarFrame, ExpireTime: future, UseProps: true, AllowGive: true},
|
|
managerVIPCleanupPropsRow{ID: 3, UserID: userID, PropsID: 999, Type: propsTypeAvatarFrame, ExpireTime: future, UseProps: true, AllowGive: true},
|
|
managerVIPCleanupPropsRow{ID: 4, UserID: userID, PropsID: 103, Type: propsTypeDataCard, ExpireTime: future, UseProps: true, AllowGive: true},
|
|
)
|
|
seedManagerVIPCleanupBadges(t, db,
|
|
managerVIPCleanupBadgeRow{ID: 1, UserID: userID, BadgeID: 100, ExpireTime: future, UseProps: true},
|
|
managerVIPCleanupBadgeRow{ID: 2, UserID: userID, BadgeID: 200, ExpireTime: future, UseProps: true},
|
|
)
|
|
|
|
target := vipGiftResourcesFromConfig(model.VipLevelConfig{
|
|
BadgeResourceID: 200,
|
|
AvatarFrameResourceID: 201,
|
|
})
|
|
all := append(vipGiftResourcesFromConfig(model.VipLevelConfig{
|
|
BadgeResourceID: 100,
|
|
AvatarFrameResourceID: 101,
|
|
BackgroundCardResourceID: 103,
|
|
}), target...)
|
|
if err := service.cleanupSupersededVIPGiftResources(context.Background(), userID, target, all, now); err != nil {
|
|
t.Fatalf("cleanupSupersededVIPGiftResources() error = %v", err)
|
|
}
|
|
|
|
assertManagerVIPCleanupProps(t, db, 101, now, false, false)
|
|
assertManagerVIPCleanupProps(t, db, 103, now, false, false)
|
|
assertManagerVIPCleanupProps(t, db, 201, future, true, true)
|
|
assertManagerVIPCleanupProps(t, db, 999, future, true, true)
|
|
assertManagerVIPCleanupBadge(t, db, 100, now, false)
|
|
assertManagerVIPCleanupBadge(t, db, 200, future, true)
|
|
}
|
|
|
|
func TestSendVIPRejectsLevelAboveGiftLimit(t *testing.T) {
|
|
service, _ := newManagerCenterTestService(t)
|
|
db := service.db.(*gorm.DB)
|
|
seedManager(t, db, 1)
|
|
seedUsers(t, db,
|
|
userBaseInfoRow{ID: 1, Account: "1", UserNickname: "manager", OriginSys: "LIKEI"},
|
|
userBaseInfoRow{ID: 2, Account: "2", OriginSys: "LIKEI"},
|
|
)
|
|
seedVIPConfigs(t, db, model.VipLevelConfig{
|
|
ID: 304,
|
|
SysOrigin: "LIKEI",
|
|
Level: 4,
|
|
LevelCode: "VIP4",
|
|
DisplayName: "VIP 4",
|
|
Enabled: true,
|
|
DurationDays: 30,
|
|
})
|
|
|
|
_, err := service.SendProps(context.Background(), AuthUser{UserID: 1, SysOrigin: "LIKEI"}, SendPropsRequest{
|
|
AcceptUserID: ID(2),
|
|
PropsID: ID(304),
|
|
})
|
|
assertAppErrorCode(t, err, "vip_not_giftable")
|
|
}
|
|
|
|
type managerVIPCleanupPropsRow struct {
|
|
ID int64 `gorm:"column:id;primaryKey"`
|
|
UserID int64 `gorm:"column:user_id"`
|
|
PropsID int64 `gorm:"column:props_id"`
|
|
Type string `gorm:"column:type"`
|
|
ExpireTime time.Time `gorm:"column:expire_time"`
|
|
UseProps bool `gorm:"column:is_use_props"`
|
|
AllowGive bool `gorm:"column:allow_give"`
|
|
UpdateTime time.Time `gorm:"column:update_time"`
|
|
}
|
|
|
|
func (managerVIPCleanupPropsRow) TableName() string {
|
|
return "user_props_backpack"
|
|
}
|
|
|
|
type managerVIPCleanupBadgeRow struct {
|
|
ID int64 `gorm:"column:id;primaryKey"`
|
|
UserID int64 `gorm:"column:user_id"`
|
|
BadgeID int64 `gorm:"column:badge_id"`
|
|
ExpireType string `gorm:"column:expire_type"`
|
|
ExpireTime time.Time `gorm:"column:expire_time"`
|
|
UseProps bool `gorm:"column:is_use_props"`
|
|
UpdateTime time.Time `gorm:"column:update_time"`
|
|
}
|
|
|
|
func (managerVIPCleanupBadgeRow) TableName() string {
|
|
return "user_badge_backpack"
|
|
}
|
|
|
|
func seedManagerVIPCleanupProps(t *testing.T, db *gorm.DB, rows ...managerVIPCleanupPropsRow) {
|
|
t.Helper()
|
|
for _, row := range rows {
|
|
if err := db.Create(&row).Error; err != nil {
|
|
t.Fatalf("seed manager cleanup props: %v", err)
|
|
}
|
|
}
|
|
}
|
|
|
|
func seedManagerVIPCleanupBadges(t *testing.T, db *gorm.DB, rows ...managerVIPCleanupBadgeRow) {
|
|
t.Helper()
|
|
for _, row := range rows {
|
|
if err := db.Create(&row).Error; err != nil {
|
|
t.Fatalf("seed manager cleanup badge: %v", err)
|
|
}
|
|
}
|
|
}
|
|
|
|
func assertManagerVIPCleanupProps(t *testing.T, db *gorm.DB, propsID int64, expireTime time.Time, useProps bool, allowGive bool) {
|
|
t.Helper()
|
|
var row managerVIPCleanupPropsRow
|
|
if err := db.Where("props_id = ?", propsID).First(&row).Error; err != nil {
|
|
t.Fatalf("load manager cleanup props %d: %v", propsID, err)
|
|
}
|
|
if !row.ExpireTime.Equal(expireTime) || row.UseProps != useProps || row.AllowGive != allowGive {
|
|
t.Fatalf("props %d = expire:%s use:%v allow:%v, want expire:%s use:%v allow:%v",
|
|
propsID, row.ExpireTime, row.UseProps, row.AllowGive, expireTime, useProps, allowGive)
|
|
}
|
|
}
|
|
|
|
func assertManagerVIPCleanupBadge(t *testing.T, db *gorm.DB, badgeID int64, expireTime time.Time, useProps bool) {
|
|
t.Helper()
|
|
var row managerVIPCleanupBadgeRow
|
|
if err := db.Where("badge_id = ?", badgeID).First(&row).Error; err != nil {
|
|
t.Fatalf("load manager cleanup badge %d: %v", badgeID, err)
|
|
}
|
|
if !row.ExpireTime.Equal(expireTime) || row.UseProps != useProps {
|
|
t.Fatalf("badge %d = expire:%s use:%v, want expire:%s use:%v",
|
|
badgeID, row.ExpireTime, row.UseProps, expireTime, useProps)
|
|
}
|
|
}
|
|
|
|
func TestBanUserRejectsDisabledFeature(t *testing.T) {
|
|
service, fake := newManagerCenterTestService(t)
|
|
db := service.db.(*gorm.DB)
|
|
seedManagerWithFeatures(t, db, 1, ManagerFeatures{AddBDLeader: true, GiftProps: true, UnbanUser: true})
|
|
seedUsers(t, db, userBaseInfoRow{ID: 2, Account: "2"})
|
|
|
|
_, err := service.BanUser(context.Background(), AuthUser{UserID: 1}, BanUserRequest{UserID: ID(2)})
|
|
assertAppErrorCode(t, err, "manager_feature_disabled")
|
|
if len(fake.punishRequests) != 0 {
|
|
t.Fatalf("punish requests = %+v, want none", fake.punishRequests)
|
|
}
|
|
}
|
|
|
|
func TestBanUserRejectsRechargedUser(t *testing.T) {
|
|
service, fake := newManagerCenterTestService(t)
|
|
db := service.db.(*gorm.DB)
|
|
seedManager(t, db, 1)
|
|
seedUsers(t, db, userBaseInfoRow{ID: 2, Account: "2"})
|
|
fake.recharges[2] = []integration.UserTotalRecharge{{Amount: integration.DecimalString("1.00")}}
|
|
|
|
_, err := service.BanUser(context.Background(), AuthUser{UserID: 1}, BanUserRequest{UserID: ID(2)})
|
|
assertAppErrorCode(t, err, "user_recharged")
|
|
if len(fake.punishRequests) != 0 {
|
|
t.Fatalf("punish requests = %+v, want none", fake.punishRequests)
|
|
}
|
|
}
|
|
|
|
func TestBanUserFailsWhenRechargeQueryUnavailable(t *testing.T) {
|
|
service, fake := newManagerCenterTestService(t)
|
|
db := service.db.(*gorm.DB)
|
|
seedManager(t, db, 1)
|
|
seedUsers(t, db, userBaseInfoRow{ID: 2, Account: "2"})
|
|
fake.rechargeErr = errors.New("order service unavailable")
|
|
|
|
_, err := service.BanUser(context.Background(), AuthUser{UserID: 1}, BanUserRequest{UserID: ID(2)})
|
|
assertAppErrorCode(t, err, "recharge_query_failed")
|
|
if len(fake.punishRequests) != 0 {
|
|
t.Fatalf("punish requests = %+v, want none", fake.punishRequests)
|
|
}
|
|
}
|
|
|
|
func TestBanUserRejectsArchivedUser(t *testing.T) {
|
|
service, fake := newManagerCenterTestService(t)
|
|
db := service.db.(*gorm.DB)
|
|
seedManager(t, db, 1)
|
|
seedUsers(t, db, userBaseInfoRow{ID: 2, Account: "2", AccountStatus: accountStatusArchive})
|
|
|
|
_, err := service.BanUser(context.Background(), AuthUser{UserID: 1}, BanUserRequest{UserID: ID(2)})
|
|
assertAppErrorCode(t, err, "user_already_banned")
|
|
if len(fake.punishRequests) != 0 {
|
|
t.Fatalf("punish requests = %+v, want none", fake.punishRequests)
|
|
}
|
|
}
|
|
|
|
func TestBanUserRejectsFrozenUser(t *testing.T) {
|
|
service, fake := newManagerCenterTestService(t)
|
|
db := service.db.(*gorm.DB)
|
|
seedManager(t, db, 1)
|
|
seedUsers(t, db, userBaseInfoRow{ID: 2, Account: "2", AccountStatus: accountStatusFreeze})
|
|
|
|
_, err := service.BanUser(context.Background(), AuthUser{UserID: 1}, BanUserRequest{UserID: ID(2)})
|
|
assertAppErrorCode(t, err, "user_already_banned")
|
|
if len(fake.punishRequests) != 0 {
|
|
t.Fatalf("punish requests = %+v, want none", fake.punishRequests)
|
|
}
|
|
}
|
|
|
|
func TestBanUserWithoutRechargeCallsPunishment(t *testing.T) {
|
|
service, fake := newManagerCenterTestService(t)
|
|
db := service.db.(*gorm.DB)
|
|
seedManager(t, db, 1)
|
|
seedUsers(t, db, userBaseInfoRow{ID: 2, Account: "2"})
|
|
|
|
resp, err := service.BanUser(context.Background(), AuthUser{UserID: 1}, BanUserRequest{
|
|
UserID: ID(2),
|
|
Reason: "spam",
|
|
})
|
|
if err != nil {
|
|
t.Fatalf("BanUser() error = %v", err)
|
|
}
|
|
if !resp.Success || resp.AccountStatus != accountStatusArchive {
|
|
t.Fatalf("resp = %+v, want archived success", resp)
|
|
}
|
|
if len(fake.punishRequests) != 1 {
|
|
t.Fatalf("punish requests = %+v, want one", fake.punishRequests)
|
|
}
|
|
got := fake.punishRequests[0]
|
|
if got.BeOptUserID != 2 || got.OptUserID != 1 || got.Status != accountStatusArchive {
|
|
t.Fatalf("punish request = %+v, want target 2 manager 1 archive", got)
|
|
}
|
|
}
|
|
|
|
func TestUnbanUserRejectsDisabledFeature(t *testing.T) {
|
|
service, fake := newManagerCenterTestService(t)
|
|
db := service.db.(*gorm.DB)
|
|
seedManagerWithFeatures(t, db, 1, ManagerFeatures{AddBDLeader: true, GiftProps: true, BanUser: true})
|
|
seedUsers(t, db, userBaseInfoRow{ID: 2, Account: "2", AccountStatus: accountStatusArchive})
|
|
|
|
_, err := service.UnbanUser(context.Background(), AuthUser{UserID: 1}, UnbanUserRequest{UserID: ID(2)})
|
|
assertAppErrorCode(t, err, "manager_feature_disabled")
|
|
if len(fake.unblockRequests) != 0 {
|
|
t.Fatalf("unblock requests = %+v, want none", fake.unblockRequests)
|
|
}
|
|
}
|
|
|
|
func TestUnbanUserRejectsNormalUser(t *testing.T) {
|
|
service, fake := newManagerCenterTestService(t)
|
|
db := service.db.(*gorm.DB)
|
|
seedManager(t, db, 1)
|
|
seedUsers(t, db, userBaseInfoRow{ID: 2, Account: "2", AccountStatus: accountStatusNormal})
|
|
|
|
_, err := service.UnbanUser(context.Background(), AuthUser{UserID: 1}, UnbanUserRequest{UserID: ID(2)})
|
|
assertAppErrorCode(t, err, "user_not_banned")
|
|
if len(fake.unblockRequests) != 0 {
|
|
t.Fatalf("unblock requests = %+v, want none", fake.unblockRequests)
|
|
}
|
|
}
|
|
|
|
func TestUnbanUserCallsUnblockAccount(t *testing.T) {
|
|
service, fake := newManagerCenterTestService(t)
|
|
db := service.db.(*gorm.DB)
|
|
seedManager(t, db, 1)
|
|
seedUsers(t, db, userBaseInfoRow{ID: 2, Account: "2", AccountStatus: accountStatusArchive})
|
|
|
|
resp, err := service.UnbanUser(context.Background(), AuthUser{UserID: 1}, UnbanUserRequest{
|
|
UserID: ID(2),
|
|
Reason: "appeal passed",
|
|
})
|
|
if err != nil {
|
|
t.Fatalf("UnbanUser() error = %v", err)
|
|
}
|
|
if !resp.Success || resp.AccountStatus != accountStatusNormal {
|
|
t.Fatalf("resp = %+v, want normal success", resp)
|
|
}
|
|
if len(fake.unblockRequests) != 1 {
|
|
t.Fatalf("unblock requests = %+v, want one", fake.unblockRequests)
|
|
}
|
|
got := fake.unblockRequests[0]
|
|
if got.BeOptUserID != 2 || got.OptUserID != 1 {
|
|
t.Fatalf("unblock request = %+v, want target 2 manager 1", got)
|
|
}
|
|
if got.Description == "" || !strings.Contains(got.Description, "appeal passed") {
|
|
t.Fatalf("description = %q, want reason included", got.Description)
|
|
}
|
|
}
|
|
|
|
func TestUnbanUserAllowsFrozenUser(t *testing.T) {
|
|
service, fake := newManagerCenterTestService(t)
|
|
db := service.db.(*gorm.DB)
|
|
seedManager(t, db, 1)
|
|
seedUsers(t, db, userBaseInfoRow{ID: 2, Account: "2", AccountStatus: accountStatusFreeze})
|
|
|
|
resp, err := service.UnbanUser(context.Background(), AuthUser{UserID: 1}, UnbanUserRequest{UserID: ID(2)})
|
|
if err != nil {
|
|
t.Fatalf("UnbanUser() error = %v", err)
|
|
}
|
|
if !resp.Success || resp.AccountStatus != accountStatusNormal {
|
|
t.Fatalf("resp = %+v, want normal success", resp)
|
|
}
|
|
if len(fake.unblockRequests) != 1 {
|
|
t.Fatalf("unblock requests = %+v, want one", fake.unblockRequests)
|
|
}
|
|
}
|
|
|
|
func TestListCountriesReturnsOpenCountries(t *testing.T) {
|
|
service, _ := newManagerCenterTestService(t)
|
|
db := service.db.(*gorm.DB)
|
|
seedManager(t, db, 1)
|
|
seedCountries(t, db,
|
|
sysCountryCodeRow{ID: 10, AlphaTwo: "SA", CountryName: "Saudi Arabia", Open: true, Sort: 2},
|
|
sysCountryCodeRow{ID: 11, AlphaTwo: "AE", CountryName: "United Arab Emirates", Open: true, Sort: 1},
|
|
sysCountryCodeRow{ID: 12, AlphaTwo: "XX", CountryName: "Closed", Open: false, Sort: 3},
|
|
)
|
|
|
|
resp, err := service.ListCountries(context.Background(), AuthUser{UserID: 1})
|
|
if err != nil {
|
|
t.Fatalf("ListCountries() error = %v", err)
|
|
}
|
|
if len(resp.Records) != 2 {
|
|
t.Fatalf("countries = %+v, want two open rows", resp.Records)
|
|
}
|
|
if resp.Records[0].CountryCode != "AE" || resp.Records[1].CountryCode != "SA" {
|
|
t.Fatalf("countries = %+v, want sort order AE then SA", resp.Records)
|
|
}
|
|
}
|
|
|
|
func TestChangeUserCountryUpdatesCountryAndClearsCache(t *testing.T) {
|
|
service, fake := newManagerCenterTestService(t)
|
|
db := service.db.(*gorm.DB)
|
|
seedManager(t, db, 1)
|
|
seedUsers(t, db, userBaseInfoRow{ID: 2, Account: "2", CountryID: 10, CountryCode: "SA", CountryName: "Saudi Arabia"})
|
|
seedCountries(t, db, sysCountryCodeRow{ID: 11, AlphaTwo: "AE", CountryName: "United Arab Emirates", Open: true})
|
|
|
|
resp, err := service.ChangeUserCountry(context.Background(), AuthUser{UserID: 1}, ChangeUserCountryRequest{
|
|
UserID: ID(2),
|
|
CountryID: ID(11),
|
|
})
|
|
if err != nil {
|
|
t.Fatalf("ChangeUserCountry() error = %v", err)
|
|
}
|
|
if !resp.Success || resp.User.CountryCode != "AE" || resp.User.CountryName != "United Arab Emirates" {
|
|
t.Fatalf("resp = %+v, want changed country", resp)
|
|
}
|
|
|
|
var row userBaseInfoRow
|
|
if err := db.Where("id = ?", int64(2)).First(&row).Error; err != nil {
|
|
t.Fatalf("load user: %v", err)
|
|
}
|
|
if row.CountryID != 11 || row.CountryCode != "AE" || row.CountryName != "United Arab Emirates" || row.UpdateUser != 1 {
|
|
t.Fatalf("user row = %+v, want AE country and manager updater", row)
|
|
}
|
|
if !equalInt64Slice(fake.cacheCleared, []int64{2}) {
|
|
t.Fatalf("cacheCleared = %+v, want [2]", fake.cacheCleared)
|
|
}
|
|
}
|
|
|
|
func TestChangeUserCountryRejectsDisabledFeature(t *testing.T) {
|
|
service, _ := newManagerCenterTestService(t)
|
|
db := service.db.(*gorm.DB)
|
|
seedManagerWithFeatures(t, db, 1, ManagerFeatures{AddBDLeader: true, GiftProps: true, BanUser: true, UnbanUser: true})
|
|
seedUsers(t, db, userBaseInfoRow{ID: 2, Account: "2", CountryID: 10, CountryCode: "SA", CountryName: "Saudi Arabia"})
|
|
seedCountries(t, db, sysCountryCodeRow{ID: 11, AlphaTwo: "AE", CountryName: "United Arab Emirates", Open: true})
|
|
|
|
_, err := service.ChangeUserCountry(context.Background(), AuthUser{UserID: 1}, ChangeUserCountryRequest{UserID: ID(2), CountryID: ID(11)})
|
|
assertAppErrorCode(t, err, "manager_feature_disabled")
|
|
|
|
var row userBaseInfoRow
|
|
if err := db.Where("id = ?", int64(2)).First(&row).Error; err != nil {
|
|
t.Fatalf("load user: %v", err)
|
|
}
|
|
if row.CountryID != 10 || row.CountryCode != "SA" {
|
|
t.Fatalf("user row = %+v, want unchanged country when feature disabled", row)
|
|
}
|
|
}
|
|
|
|
func TestChangeUserCountryRejectsHistoryIdentity(t *testing.T) {
|
|
service, _ := newManagerCenterTestService(t)
|
|
db := service.db.(*gorm.DB)
|
|
seedManager(t, db, 1)
|
|
seedUsers(t, db, userBaseInfoRow{ID: 2, Account: "2", CountryID: 10, CountryCode: "SA"})
|
|
seedCountries(t, db, sysCountryCodeRow{ID: 11, AlphaTwo: "AE", CountryName: "United Arab Emirates", Open: true})
|
|
if err := db.Create(&userHistoryIdentityRow{UserID: 2, IsHost: true}).Error; err != nil {
|
|
t.Fatalf("seed identity: %v", err)
|
|
}
|
|
|
|
_, err := service.ChangeUserCountry(context.Background(), AuthUser{UserID: 1}, ChangeUserCountryRequest{UserID: ID(2), CountryID: ID(11)})
|
|
assertAppErrorCode(t, err, "user_identity_locked")
|
|
}
|
|
|
|
func TestChangeUserCountryRejectsBDLeader(t *testing.T) {
|
|
service, _ := newManagerCenterTestService(t)
|
|
db := service.db.(*gorm.DB)
|
|
seedManager(t, db, 1)
|
|
seedUsers(t, db, userBaseInfoRow{ID: 2, Account: "2", CountryID: 10, CountryCode: "SA"})
|
|
seedCountries(t, db, sysCountryCodeRow{ID: 11, AlphaTwo: "AE", CountryName: "United Arab Emirates", Open: true})
|
|
if err := db.Create(&bdLeaderRow{ID: 20, UserID: 2, Origin: "LIKEI", RegionID: "SA"}).Error; err != nil {
|
|
t.Fatalf("seed bd leader: %v", err)
|
|
}
|
|
|
|
_, err := service.ChangeUserCountry(context.Background(), AuthUser{UserID: 1}, ChangeUserCountryRequest{UserID: ID(2), CountryID: ID(11)})
|
|
assertAppErrorCode(t, err, "user_identity_locked")
|
|
}
|
|
|
|
func TestChangeUserCountryRejectsCoinSeller(t *testing.T) {
|
|
service, fake := newManagerCenterTestService(t)
|
|
db := service.db.(*gorm.DB)
|
|
seedManager(t, db, 1)
|
|
seedUsers(t, db, userBaseInfoRow{ID: 2, Account: "2", CountryID: 10, CountryCode: "SA"})
|
|
seedCountries(t, db, sysCountryCodeRow{ID: 11, AlphaTwo: "AE", CountryName: "United Arab Emirates", Open: true})
|
|
fake.freightSellers[2] = true
|
|
|
|
_, err := service.ChangeUserCountry(context.Background(), AuthUser{UserID: 1}, ChangeUserCountryRequest{UserID: ID(2), CountryID: ID(11)})
|
|
assertAppErrorCode(t, err, "user_identity_locked")
|
|
}
|
|
|
|
func newManagerCenterTestService(t *testing.T) (*Service, *fakeManagerGateway) {
|
|
t.Helper()
|
|
db, err := gorm.Open(sqlite.Open("file:"+t.Name()+"?mode=memory&cache=shared"), &gorm.Config{})
|
|
if err != nil {
|
|
t.Fatalf("open sqlite: %v", err)
|
|
}
|
|
if err := db.AutoMigrate(
|
|
&teamManagerInfoRow{},
|
|
&userBaseInfoRow{},
|
|
&sysCountryCodeRow{},
|
|
&bdLeaderRow{},
|
|
&businessDevelopmentBaseInfoRow{},
|
|
&userHistoryIdentityRow{},
|
|
&administratorRow{},
|
|
&propsSourceRecordRow{},
|
|
&propsNobleVIPAbilityRow{},
|
|
&model.VipLevelConfig{},
|
|
&model.UserVipState{},
|
|
&model.VipOrderRecord{},
|
|
&gmVIPGiftRecordRow{},
|
|
); err != nil {
|
|
t.Fatalf("auto migrate: %v", err)
|
|
}
|
|
fake := &fakeManagerGateway{
|
|
recharges: map[int64][]integration.UserTotalRecharge{},
|
|
freightSellers: map[int64]bool{},
|
|
abilities: map[int64]integration.PropsNobleVIPAbility{},
|
|
}
|
|
return NewService(db, fake), fake
|
|
}
|
|
|
|
func seedManager(t *testing.T, db *gorm.DB, userID int64) {
|
|
t.Helper()
|
|
seedManagerWithFeatures(t, db, userID, ManagerFeatures{
|
|
AddBDLeader: true,
|
|
GiftProps: true,
|
|
BanUser: true,
|
|
UnbanUser: true,
|
|
ChangeCountry: true,
|
|
})
|
|
}
|
|
|
|
func seedManagerWithFeatures(t *testing.T, db *gorm.DB, userID int64, features ManagerFeatures) {
|
|
t.Helper()
|
|
if err := db.Create(&teamManagerInfoRow{
|
|
ID: userID,
|
|
UserID: userID,
|
|
Origin: "LIKEI",
|
|
RegionID: "SA",
|
|
CanAddBDLeader: boolPtr(features.AddBDLeader),
|
|
CanGiftProps: boolPtr(features.GiftProps),
|
|
CanBanUser: boolPtr(features.BanUser),
|
|
CanUnbanUser: boolPtr(features.UnbanUser),
|
|
CanChangeCountry: boolPtr(features.ChangeCountry),
|
|
}).Error; err != nil {
|
|
t.Fatalf("seed manager: %v", err)
|
|
}
|
|
}
|
|
|
|
func boolPtr(value bool) *bool {
|
|
return &value
|
|
}
|
|
|
|
func seedUsers(t *testing.T, db *gorm.DB, rows ...userBaseInfoRow) {
|
|
t.Helper()
|
|
for _, row := range rows {
|
|
if row.AccountStatus == "" {
|
|
row.AccountStatus = "ACTIVE"
|
|
}
|
|
if err := db.Create(&row).Error; err != nil {
|
|
t.Fatalf("seed user: %v", err)
|
|
}
|
|
}
|
|
}
|
|
|
|
func seedCountries(t *testing.T, db *gorm.DB, rows ...sysCountryCodeRow) {
|
|
t.Helper()
|
|
for _, row := range rows {
|
|
if err := db.Create(&row).Error; err != nil {
|
|
t.Fatalf("seed country: %v", err)
|
|
}
|
|
}
|
|
}
|
|
|
|
func seedProps(t *testing.T, db *gorm.DB, rows ...propsSourceRecordRow) {
|
|
t.Helper()
|
|
for _, row := range rows {
|
|
if err := db.Create(&row).Error; err != nil {
|
|
t.Fatalf("seed props: %v", err)
|
|
}
|
|
}
|
|
}
|
|
|
|
func seedAbilities(t *testing.T, db *gorm.DB, rows ...propsNobleVIPAbilityRow) {
|
|
t.Helper()
|
|
for _, row := range rows {
|
|
if err := db.Create(&row).Error; err != nil {
|
|
t.Fatalf("seed ability: %v", err)
|
|
}
|
|
}
|
|
}
|
|
|
|
func seedVIPConfigs(t *testing.T, db *gorm.DB, rows ...model.VipLevelConfig) {
|
|
t.Helper()
|
|
now := time.Now()
|
|
for _, row := range rows {
|
|
if row.CreateTime.IsZero() {
|
|
row.CreateTime = now
|
|
}
|
|
if row.UpdateTime.IsZero() {
|
|
row.UpdateTime = now
|
|
}
|
|
if err := db.Create(&row).Error; err != nil {
|
|
t.Fatalf("seed vip config: %v", err)
|
|
}
|
|
}
|
|
}
|
|
|
|
func assertAppErrorCode(t *testing.T, err error, code string) {
|
|
t.Helper()
|
|
if err == nil {
|
|
t.Fatalf("error is nil, want code %s", code)
|
|
}
|
|
var appErr *AppError
|
|
if !errors.As(err, &appErr) {
|
|
t.Fatalf("error = %T %v, want AppError", err, err)
|
|
}
|
|
if appErr.Code != code {
|
|
t.Fatalf("error code = %s, want %s", appErr.Code, code)
|
|
}
|
|
}
|
|
|
|
func equalInt64Slice(a, b []int64) bool {
|
|
if len(a) != len(b) {
|
|
return false
|
|
}
|
|
for i := range a {
|
|
if a[i] != b[i] {
|
|
return false
|
|
}
|
|
}
|
|
return true
|
|
}
|