128 lines
4.0 KiB
Go
128 lines
4.0 KiB
Go
package deck
|
|
|
|
import (
|
|
"bd2server/internal/server/gamedata"
|
|
"bd2server/internal/server/player"
|
|
"bd2server/internal/server/stateio"
|
|
"bd2server/internal/server/wire"
|
|
"bytes"
|
|
"errors"
|
|
"testing"
|
|
)
|
|
|
|
func waypointFixture(t *testing.T) (*Store, *stateio.Memory) {
|
|
t.Helper()
|
|
memory := stateio.NewMemory()
|
|
seededStore := seeded(t)
|
|
s, err := OpenStore(memory, Seed{Version: seededStore.state.Version, FieldDeck: seededStore.state.FieldDeck, FieldCharControlDeckType: seededStore.state.FieldCharControlDeckType})
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
configureWaypointFixture(t, s)
|
|
return s, memory
|
|
}
|
|
func configureWaypointFixture(t *testing.T, s *Store) {
|
|
t.Helper()
|
|
if err := s.ConfigureWaypoints(func(uint64) (gamedata.WaypointPack, error) {
|
|
return gamedata.WaypointPack{Points: map[uint64]gamedata.Waypoint{1: {ID: 1, MapID: 10}, 2: {ID: 2, MapID: 20}}, PriceType: 4, PriceUnit: 7}, nil
|
|
}, func(pack uint64, _ bool) error {
|
|
if pack == 3 {
|
|
return errors.New("locked pack")
|
|
}
|
|
return nil
|
|
}); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
}
|
|
func waypointReq(seq, pack, start, end uint64) []byte {
|
|
body := wire.AppendVarint(nil, 2, pack)
|
|
if start != 0 {
|
|
body = wire.AppendVarint(body, 3, start)
|
|
}
|
|
if end != 0 {
|
|
body = wire.AppendVarint(body, 4, end)
|
|
body = wire.AppendVarint(body, 5, 1)
|
|
}
|
|
return req(seq, body)
|
|
}
|
|
|
|
func TestWaypointActivationPersistsAllIDsAndInfoScopesPack(t *testing.T) {
|
|
s, memory := waypointFixture(t)
|
|
for _, r := range []struct{ seq, pack, id uint64 }{{1, 1, 2}, {2, 1, 1}, {3, 2, 2}, {4, 1, 1}} {
|
|
if _, _, _, err := s.Handle("/WaypointSave", waypointReq(r.seq, r.pack, r.id, 0)); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
}
|
|
reopened, err := OpenStore(memory, Seed{Version: s.state.Version, FieldDeck: s.state.FieldDeck, FieldCharControlDeckType: s.state.FieldCharControlDeckType})
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
configureWaypointFixture(t, reopened)
|
|
code, body, _, err := reopened.Handle("/WaypointInfo", waypointReq(5, 1, 0, 0))
|
|
if err != nil || code != 31 || !bytes.Equal(body, []byte{10, 2, 1, 2}) {
|
|
t.Fatalf("pack1 info %d %x %v", code, body, err)
|
|
}
|
|
_, body, _, err = reopened.Handle("/WaypointInfo", waypointReq(6, 2, 0, 0))
|
|
if err != nil || !bytes.Equal(body, []byte{10, 1, 2}) {
|
|
t.Fatalf("pack2 info %x %v", body, err)
|
|
}
|
|
if len(reopened.state.Waypoints[1]) != 2 {
|
|
t.Fatal("duplicate activation persisted")
|
|
}
|
|
}
|
|
|
|
func TestWaypointTravelChargesOnceAndRejectsInvalidBeforeSpending(t *testing.T) {
|
|
s, memory := waypointFixture(t)
|
|
wallet, err := player.OpenWallet(memory, player.Currency{Gold: 14})
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
s.wallet = wallet
|
|
s.BeginSession("test-session")
|
|
for i := uint64(1); i <= 2; i++ {
|
|
if _, _, _, err = s.Handle("/WaypointSave", waypointReq(i, 1, i, 0)); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
}
|
|
for _, request := range [][]byte{waypointReq(3, 3, 1, 2), waypointReq(4, 1, 1, 99), waypointReq(5, 2, 1, 2)} {
|
|
if _, _, _, err = s.Handle("/WaypointUse", request); err == nil {
|
|
t.Fatal("invalid travel accepted")
|
|
}
|
|
if wallet.Snapshot().Gold != 14 {
|
|
t.Fatal("invalid travel charged")
|
|
}
|
|
}
|
|
valid := waypointReq(6, 1, 1, 2)
|
|
for range 2 {
|
|
code, _, _, err := s.Handle("/WaypointUse", valid)
|
|
if err != nil || code != 33 {
|
|
t.Fatalf("travel %d %v", code, err)
|
|
}
|
|
}
|
|
if wallet.Snapshot().Gold != 7 {
|
|
t.Fatal("repeat travel double charged")
|
|
}
|
|
reopened, err := OpenStore(memory, Seed{Version: s.state.Version, FieldDeck: s.state.FieldDeck, FieldCharControlDeckType: s.state.FieldCharControlDeckType})
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
configureWaypointFixture(t, reopened)
|
|
reopened.wallet = wallet
|
|
reopened.BeginSession("test-session")
|
|
if _, _, _, err = reopened.Handle("/WaypointUse", valid); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if wallet.Snapshot().Gold != 7 {
|
|
t.Fatal("restart retry charged")
|
|
}
|
|
if _, _, _, err = reopened.Handle("/WaypointUse", waypointReq(7, 1, 2, 1)); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if _, _, _, err = reopened.Handle("/WaypointUse", waypointReq(8, 1, 1, 2)); err == nil {
|
|
t.Fatal("insufficient balance accepted")
|
|
}
|
|
if wallet.Snapshot().Gold != 0 {
|
|
t.Fatal("failed debit changed wallet")
|
|
}
|
|
}
|