package smashegg import ( "testing" "chatapp3-golang/internal/integration" ) func TestNormalizeSaveRequestAcceptsNewbiePoolWithinRTPTolerance(t *testing.T) { normalized, err := normalizeSaveRequest(SaveConfigRequest{ SysOrigin: "yumi", Enabled: true, Timezone: "Asia/Riyadh", RTPBasisPoints: 9500, NewbiePoolEnabled: true, NewbieWindowDays: 7, NewbieMaxDrawCount: 3, DrawOptions: []DrawOptionInput{ {Enabled: true, Sort: 1, OptionKey: "ONE", Label: "1", Times: 1, PriceGold: 100}, {Enabled: true, Sort: 2, OptionKey: "TEN", Label: "10", Times: 10, PriceGold: 1000}, }, Rewards: []RewardConfigInput{{ Enabled: true, RewardType: rewardTypeGold, GoldAmount: 95, RewardValueGold: 95, }}, NewbieRewards: []RewardConfigInput{{ Enabled: true, RewardType: rewardTypeGold, GoldAmount: 96, RewardValueGold: 96, }}, }) if err != nil { t.Fatalf("normalizeSaveRequest returned error: %v", err) } if normalized.Rewards[0].Probability != probabilityTotal { t.Fatalf("general probability = %d, want %d", normalized.Rewards[0].Probability, probabilityTotal) } if normalized.NewbieRewards[0].Probability != probabilityTotal { t.Fatalf("newbie probability = %d, want %d", normalized.NewbieRewards[0].Probability, probabilityTotal) } } func TestNormalizeSaveRequestAutoCalculatesProbabilities(t *testing.T) { normalized, err := normalizeSaveRequest(SaveConfigRequest{ SysOrigin: "yumi", Enabled: true, Timezone: "Asia/Riyadh", RTPBasisPoints: 9500, DrawOptions: []DrawOptionInput{ {Enabled: true, Sort: 1, OptionKey: "ONE", Label: "1", Times: 1, PriceGold: 500}, }, Rewards: []RewardConfigInput{ {Enabled: true, RewardType: rewardTypeGold, GoldAmount: 50}, {Enabled: true, RewardType: rewardTypeGold, GoldAmount: 100}, {Enabled: true, RewardType: rewardTypeGold, GoldAmount: 500}, {Enabled: true, RewardType: rewardTypeGold, GoldAmount: 5000}, }, }) if err != nil { t.Fatalf("normalizeSaveRequest returned error: %v", err) } total := 0 for _, reward := range normalized.Rewards { total += reward.Probability } if total != probabilityTotal { t.Fatalf("probability total = %d, want %d", total, probabilityTotal) } weighted := weightedRewardValueFromInputs(normalized.Rewards) rtp := drawOptionRTPBasisPointsFromWeightedValue(weighted, normalized.DrawOptions[0].Times, normalized.DrawOptions[0].PriceGold) if rtp < normalized.RTPBasisPoints-rtpToleranceBasisPoints || rtp > normalized.RTPBasisPoints+rtpToleranceBasisPoints { t.Fatalf("auto RTP = %d, want %d ± %d", rtp, normalized.RTPBasisPoints, rtpToleranceBasisPoints) } } func TestNormalizeSaveRequestAutoCalculatesDraftProbabilities(t *testing.T) { normalized, err := normalizeSaveRequest(SaveConfigRequest{ SysOrigin: "yumi", Enabled: false, Timezone: "Asia/Riyadh", RTPBasisPoints: 9500, DrawOptions: []DrawOptionInput{ {Enabled: true, Sort: 1, OptionKey: "ONE", Label: "1", Times: 1, PriceGold: 500}, }, Rewards: []RewardConfigInput{ {Enabled: true, RewardType: rewardTypeGold, GoldAmount: 50}, {Enabled: true, RewardType: rewardTypeGold, GoldAmount: 100}, {Enabled: true, RewardType: rewardTypeGold, GoldAmount: 500}, {Enabled: true, RewardType: rewardTypeGold, GoldAmount: 10000}, }, }) if err != nil { t.Fatalf("normalizeSaveRequest returned error: %v", err) } total := 0 for _, reward := range normalized.Rewards { if reward.Enabled && reward.Probability <= 0 { t.Fatalf("enabled reward %d probability = %d, want > 0", reward.GoldAmount, reward.Probability) } total += reward.Probability } if total != probabilityTotal { t.Fatalf("probability total = %d, want %d", total, probabilityTotal) } } func TestNormalizeSaveRequestRejectsNewbiePoolOutsideRTPTolerance(t *testing.T) { _, err := normalizeSaveRequest(SaveConfigRequest{ SysOrigin: "yumi", Enabled: true, Timezone: "Asia/Riyadh", RTPBasisPoints: 9500, NewbiePoolEnabled: true, NewbieWindowDays: 7, NewbieMaxDrawCount: 3, DrawOptions: []DrawOptionInput{ {Enabled: true, Sort: 1, OptionKey: "ONE", Label: "1", Times: 1, PriceGold: 100}, }, Rewards: []RewardConfigInput{{ Enabled: true, RewardType: rewardTypeGold, GoldAmount: 95, RewardValueGold: 95, }}, NewbieRewards: []RewardConfigInput{{ Enabled: true, RewardType: rewardTypeGold, GoldAmount: 110, RewardValueGold: 110, }}, }) if err == nil { t.Fatal("normalizeSaveRequest succeeded, want RTP validation error") } } func TestNormalizeSaveRequestAcceptsResourceRewardAndUsesDisplayPrice(t *testing.T) { normalized, err := normalizeSaveRequest(SaveConfigRequest{ SysOrigin: "yumi", Enabled: true, Timezone: "Asia/Riyadh", RTPBasisPoints: 9500, DrawOptions: []DrawOptionInput{ {Enabled: true, Sort: 1, OptionKey: "ONE", Label: "1", Times: 1, PriceGold: 100}, }, Rewards: []RewardConfigInput{{ Enabled: true, RewardType: "RESOURCE", ResourceID: ResourceID(123), ResourceName: "Avatar Frame", ResourceType: "AVATAR_FRAME", CoverURL: "https://example.test/frame.png", DurationDays: 7, DisplayGoldAmount: 95, }}, }) if err != nil { t.Fatalf("normalizeSaveRequest returned error: %v", err) } reward := normalized.Rewards[0] if reward.RewardType != rewardTypeResource { t.Fatalf("reward type = %s, want RESOURCE", reward.RewardType) } if reward.RewardGroupID == nil || *reward.RewardGroupID != 123 { t.Fatalf("reward group id = %v, want 123", reward.RewardGroupID) } if reward.RewardValueGold != 95 || reward.DisplayGoldAmount != 95 || reward.GoldAmount != 0 { t.Fatalf("normalized resource values = value:%d display:%d gold:%d", reward.RewardValueGold, reward.DisplayGoldAmount, reward.GoldAmount) } } func TestTotalRechargeAtLeast(t *testing.T) { items := []integration.UserTotalRecharge{ {Amount: integration.DecimalString("80.50")}, {Amount: integration.DecimalString("20")}, } if !totalRechargeAtLeast(items, 100) { t.Fatal("totalRechargeAtLeast returned false, want true") } if totalRechargeAtLeast(items, 101) { t.Fatal("totalRechargeAtLeast returned true, want false") } }