Files
bd2/go/internal/server/eventtasks/pass_reward_integration_test.go
T

130 lines
4.2 KiB
Go

package eventtasks
import (
"bytes"
"testing"
"bd2server/internal/server/events"
"bd2server/internal/server/gamedata"
"bd2server/internal/server/player"
"bd2server/internal/server/stateio"
"bd2server/internal/server/wire"
)
type passRewardDesign struct{}
func (passRewardDesign) Character(uint64) (gamedata.CharacterDesign, bool) {
return gamedata.CharacterDesign{}, false
}
func (passRewardDesign) RollOptions(uint64) ([]gamedata.EquipmentOptionChoice, []gamedata.EquipmentOptionChoice, *gamedata.EquipmentOptionChoice, error) {
return nil, nil, nil, nil
}
func (passRewardDesign) Resolve(r []gamedata.BattleReward) ([]gamedata.BattleReward, error) {
return r, nil
}
func realPassEconomy(t *testing.T, store stateio.Store) (*events.Economy, *player.Inventory, *player.Wallet) {
t.Helper()
items, err := player.OpenInventory(store, &player.Starter{Version: "2.35.10"})
if err != nil {
t.Fatal(err)
}
wallet, err := player.OpenWallet(store, player.Currency{})
if err != nil {
t.Fatal(err)
}
collection, err := player.OpenCollectionStore(store, nil)
if err != nil {
t.Fatal(err)
}
equipment, err := player.OpenEquipmentInventory(store)
if err != nil {
t.Fatal(err)
}
for _, persist := range []func() error{items.EnsurePersisted, wallet.EnsurePersisted, collection.EnsurePersisted, equipment.EnsurePersisted} {
if err := persist(); err != nil {
t.Fatal(err)
}
}
design := passRewardDesign{}
economy, err := events.NewEconomy(store, items, wallet, collection, equipment, design, design, design, nil)
if err != nil {
t.Fatal(err)
}
return economy, items, wallet
}
// A spy alone cannot detect a claim recorded without a durable inventory grant.
// Exercise the native BASIC -> PREMIUM one-click flow through the real economy.
func TestPassRewardAllPersistsEveryCurrencyAndItemAcrossRestart(t *testing.T) {
s, _, store := setup(t)
economy, items, wallet := realPassEconomy(t, store)
s.economy = economy
s.design.PassLevels[8] = []gamedata.EventPassLevel{
{ID: 1, NeedExp: 20, Basic: gamedata.Reward{Type: 3, Count: 5}, Premium: gamedata.Reward{Type: 8, ID: 1000, Count: 2}},
{ID: 2, NeedExp: 30, Basic: gamedata.Reward{Type: 3, Count: 7}, Premium: gamedata.Reward{Type: 8, ID: 1000, Count: 3}},
{ID: 3, NeedExp: 40, Basic: gamedata.Reward{Type: 8, ID: 1000, Count: 11}, Premium: gamedata.Reward{Type: 4, Count: 100}},
{ID: 4, Basic: gamedata.Reward{Type: 3, Count: 999}, Premium: gamedata.Reward{Type: 4, Count: 999}},
}
p := s.pass(s.registry.List()[2])
p.Exp = 50
p.Premium = true
basic := passClaimRequest(1, 0, true, 0)
premium := passClaimRequest(2, 1, true, 0)
basicReply := claimPass(t, s, basic)
premiumReply := claimPass(t, s, premium)
assertBalances := func(items *player.Inventory, wallet *player.Wallet) {
t.Helper()
c := wallet.Snapshot()
if c.FreeJewelry != 12 || c.Gold != 100 {
t.Fatalf("durable currencies: %+v", c)
}
var total uint64
for _, item := range items.All() {
if item.Type == 8 && item.ID == 1000 {
total += item.Count
}
}
if total != 16 {
t.Fatalf("durable ticket quantity=%d want=16", total)
}
}
assertBalances(items, wallet)
for _, response := range [][]byte{basicReply, premiumReply} {
bundle, _, err := wire.Bytes(response, 1)
if err != nil {
t.Fatal(err)
}
count := 0
if err := wire.Walk(bundle, func(f wire.Field) error {
if f.Number == 1 {
count++
}
return nil
}); err != nil {
t.Fatal(err)
}
if count != 3 {
t.Fatalf("bundle omitted rewards: entries=%d want=3", count)
}
}
economy, items, wallet = realPassEconomy(t, store)
reopened, err := Open(store, s.design, s.registry, economy)
if err != nil {
t.Fatal(err)
}
reopened.now = s.now
reopened.SetSession("test")
if !bytes.Equal(claimPass(t, reopened, basic), basicReply) || !bytes.Equal(claimPass(t, reopened, premium), premiumReply) {
t.Fatal("replay response changed")
}
assertBalances(items, wallet)
for typ := uint64(0); typ <= 1; typ++ {
claimPass(t, reopened, passClaimRequest(3+typ, typ, true, 0))
}
assertBalances(items, wallet)
if reopened.pass(reopened.registry.List()[2]).Claimed[key(4, 0)] || reopened.pass(reopened.registry.List()[2]).Claimed[key(4, 1)] {
t.Fatal("locked level was claimed")
}
}