Skip to content

Commit f8ea1f2

Browse files
committed
test: cover item use-to-item guard edges
1 parent 745665c commit f8ea1f2

1 file changed

Lines changed: 110 additions & 0 deletions

File tree

internal/minimal/factory_test.go

Lines changed: 110 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3382,6 +3382,116 @@ func TestNewGameSessionFactoryItemMovePartialMergeKeepsSourceQuickslotStable(t *
33823382
}
33833383
}
33843384

3385+
func TestNewGameSessionFactoryItemUseToItemRejectsLockedSourceOrTargetWithoutMutation(t *testing.T) {
3386+
cases := []struct {
3387+
name string
3388+
inventory []inventory.ItemInstance
3389+
}{
3390+
{
3391+
name: "locked source",
3392+
inventory: []inventory.ItemInstance{
3393+
{ID: 11, Vnum: 27001, Count: 3, Slot: 5, Locked: true},
3394+
{ID: 12, Vnum: 27001, Count: 2, Slot: 8},
3395+
},
3396+
},
3397+
{
3398+
name: "locked target",
3399+
inventory: []inventory.ItemInstance{
3400+
{ID: 11, Vnum: 27001, Count: 3, Slot: 5},
3401+
{ID: 12, Vnum: 27001, Count: 2, Slot: 8, Locked: true},
3402+
},
3403+
},
3404+
}
3405+
for _, tc := range cases {
3406+
t.Run(tc.name, func(t *testing.T) {
3407+
store := loginticket.NewFileStore(t.TempDir())
3408+
accounts := accountstore.NewFileStore(t.TempDir())
3409+
characters := stubCharacters()
3410+
characters[1].Inventory = append([]inventory.ItemInstance(nil), tc.inventory...)
3411+
characters[1].Quickslots = []loginticket.Quickslot{
3412+
{Position: 2, Type: quickslotproto.TypeItem, Slot: 5},
3413+
{Position: 3, Type: quickslotproto.TypeItem, Slot: 8},
3414+
}
3415+
if err := accounts.Save(accountstore.Account{Login: StubLogin, Empire: 2, Characters: cloneCharacters(characters)}); err != nil {
3416+
t.Fatalf("save account: %v", err)
3417+
}
3418+
if err := store.Issue(loginticket.Ticket{Login: StubLogin, LoginKey: 0x01020304, Empire: 2, Characters: cloneCharacters(characters)}); err != nil {
3419+
t.Fatalf("issue login ticket: %v", err)
3420+
}
3421+
flow := newStartedGameFlow(t, store, accounts)
3422+
3423+
mergeOut, err := flow.HandleClientFrame(decodeSingleFrame(t, itemproto.EncodeClientUseToItem(itemproto.ClientUseToItemPacket{
3424+
Source: itemproto.InventoryPosition(5),
3425+
Target: itemproto.InventoryPosition(8),
3426+
})))
3427+
if err != nil {
3428+
t.Fatalf("unexpected locked %s use-to-item error: %v", tc.name, err)
3429+
}
3430+
if len(mergeOut) != 0 {
3431+
t.Fatalf("expected locked %s use-to-item to fail closed with no frames, got %d", tc.name, len(mergeOut))
3432+
}
3433+
account, err := accounts.Load(StubLogin)
3434+
if err != nil {
3435+
t.Fatalf("load persisted account: %v", err)
3436+
}
3437+
if !reflect.DeepEqual(account.Characters[1].Inventory, characters[1].Inventory) {
3438+
t.Fatalf("unexpected persisted inventory after locked %s use-to-item attempt: %#v", tc.name, account.Characters[1].Inventory)
3439+
}
3440+
if !reflect.DeepEqual(account.Characters[1].Quickslots, characters[1].Quickslots) {
3441+
t.Fatalf("unexpected persisted quickslots after locked %s use-to-item attempt: %#v", tc.name, account.Characters[1].Quickslots)
3442+
}
3443+
})
3444+
}
3445+
}
3446+
3447+
func TestNewGameSessionFactoryItemUseToItemRejectsNonStackableTemplateWithoutMutation(t *testing.T) {
3448+
store := loginticket.NewFileStore(t.TempDir())
3449+
accounts := accountstore.NewFileStore(t.TempDir())
3450+
characters := stubCharacters()
3451+
characters[1].Inventory = []inventory.ItemInstance{
3452+
{ID: 11, Vnum: 27001, Count: 1, Slot: 5},
3453+
{ID: 12, Vnum: 27001, Count: 1, Slot: 8},
3454+
}
3455+
characters[1].Quickslots = []loginticket.Quickslot{
3456+
{Position: 2, Type: quickslotproto.TypeItem, Slot: 5},
3457+
{Position: 3, Type: quickslotproto.TypeItem, Slot: 8},
3458+
}
3459+
if err := accounts.Save(accountstore.Account{Login: StubLogin, Empire: 2, Characters: cloneCharacters(characters)}); err != nil {
3460+
t.Fatalf("save account: %v", err)
3461+
}
3462+
if err := store.Issue(loginticket.Ticket{Login: StubLogin, LoginKey: 0x01020304, Empire: 2, Characters: cloneCharacters(characters)}); err != nil {
3463+
t.Fatalf("issue login ticket: %v", err)
3464+
}
3465+
itemTemplates := staticItemTemplateStore{snapshot: itemcatalog.Snapshot{Templates: []itemcatalog.Template{{
3466+
Vnum: 27001,
3467+
Name: "Non-Stackable Potion-Like Item",
3468+
Stackable: false,
3469+
MaxCount: 1,
3470+
}}}}
3471+
flow := newStartedGameFlowWithItemStore(t, store, accounts, itemTemplates)
3472+
3473+
mergeOut, err := flow.HandleClientFrame(decodeSingleFrame(t, itemproto.EncodeClientUseToItem(itemproto.ClientUseToItemPacket{
3474+
Source: itemproto.InventoryPosition(5),
3475+
Target: itemproto.InventoryPosition(8),
3476+
})))
3477+
if err != nil {
3478+
t.Fatalf("unexpected non-stackable use-to-item error: %v", err)
3479+
}
3480+
if len(mergeOut) != 0 {
3481+
t.Fatalf("expected non-stackable use-to-item to fail closed with no frames, got %d", len(mergeOut))
3482+
}
3483+
account, err := accounts.Load(StubLogin)
3484+
if err != nil {
3485+
t.Fatalf("load persisted account: %v", err)
3486+
}
3487+
if !reflect.DeepEqual(account.Characters[1].Inventory, characters[1].Inventory) {
3488+
t.Fatalf("unexpected persisted inventory after non-stackable use-to-item attempt: %#v", account.Characters[1].Inventory)
3489+
}
3490+
if !reflect.DeepEqual(account.Characters[1].Quickslots, characters[1].Quickslots) {
3491+
t.Fatalf("unexpected persisted quickslots after non-stackable use-to-item attempt: %#v", account.Characters[1].Quickslots)
3492+
}
3493+
}
3494+
33853495
func TestNewGameSessionFactoryItemUseToItemRejectsAuthoredSexAntiFlagWithoutMutation(t *testing.T) {
33863496
store := loginticket.NewFileStore(t.TempDir())
33873497
accounts := accountstore.NewFileStore(t.TempDir())

0 commit comments

Comments
 (0)