81 lines
3.3 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

package command
import (
"bytes"
"testing"
)
func TestSendGiftIdempotencyIgnoresGatewayResolvedSnapshots(t *testing.T) {
base := SendGift{
Base: Base{CommandID: "combo-1_b1", Room: "room-1", ActorID: 42, DeviceID: "device-first"},
TargetType: "user", TargetUserIDs: []int64{43}, TargetUserID: 43,
GiftID: "rose", GiftCount: 9, ComboSessionID: "combo-1", BatchSeq: 1,
SenderRegionID: 1001, SenderCountryID: 840,
TargetHostScopes: []GiftTargetHostScope{{TargetUserID: 43, TargetIsHost: true, TargetHostRegionID: 1001}},
SenderDisplayProfile: GiftDisplayProfile{UserID: 42, Username: "before"},
}
retry := base
retry.SenderRegionID = 2002
retry.SenderCountryID = 356
retry.TargetHostScopes = []GiftTargetHostScope{{TargetUserID: 43, TargetIsHost: false}}
retry.SenderDisplayProfile = GiftDisplayProfile{UserID: 42, Username: "after"}
retry.DeviceID = "device-after-token-rotation"
left, err := IdempotencyPayloadForCommand(base)
if err != nil {
t.Fatalf("base payload: %v", err)
}
right, err := IdempotencyPayloadForCommand(retry)
if err != nil {
t.Fatalf("retry payload: %v", err)
}
if !bytes.Equal(left, right) {
t.Fatalf("gateway snapshot drift changed client idempotency semantics:\nleft=%s\nright=%s", left, right)
}
}
func TestSendGiftCommandLogPreservesTrustedDeviceIDAndReadsLegacyPayload(t *testing.T) {
original := SendGift{
Base: Base{
AppCode: "lalu", CommandID: "cmd-device-recovery", Room: "room-1", ActorID: 42,
SessionID: "sess-not-a-device", DeviceID: "device-auth-session-1", SentAtMS: 1_000,
},
TargetType: "user", TargetUserIDs: []int64{43}, TargetUserID: 43,
GiftID: "rose", GiftCount: 1,
}
payload, err := Serialize(original)
if err != nil {
t.Fatalf("serialize send gift device snapshot: %v", err)
}
recovered, err := Deserialize(original.Type(), payload)
if err != nil {
t.Fatalf("deserialize send gift device snapshot: %v", err)
}
got, ok := recovered.(*SendGift)
if !ok || got.DeviceID != "device-auth-session-1" || got.SessionID != "sess-not-a-device" {
t.Fatalf("recovered trusted device snapshot mismatch: %#v", recovered)
}
// 滚动升级前的 command log 不包含 device_id反序列化必须保持可恢复
// 并留下空值让 fixed_v2 兼容、dynamic_v3 在 owner 处明确拒绝。
legacy, err := Deserialize(original.Type(), []byte(`{"app_code":"lalu","command_id":"cmd-legacy","actor_user_id":42,"room_id":"room-1","session_id":"sess-legacy","target_type":"user","target_user_id":43,"gift_id":"rose","gift_count":1}`))
if err != nil {
t.Fatalf("deserialize legacy send gift: %v", err)
}
legacyGift := legacy.(*SendGift)
if legacyGift.DeviceID != "" || legacyGift.SessionID != "sess-legacy" {
t.Fatalf("legacy command must not derive device from session: %+v", legacyGift.Base)
}
}
func TestSendGiftIdempotencyKeepsComboBatchIdentity(t *testing.T) {
base := SendGift{Base: Base{CommandID: "combo-1_b1", Room: "room-1", ActorID: 42}, TargetType: "user", TargetUserIDs: []int64{43}, TargetUserID: 43, GiftID: "rose", GiftCount: 1, ComboSessionID: "combo-1", BatchSeq: 1}
reused := base
reused.BatchSeq = 2
left, _ := IdempotencyPayloadForCommand(base)
right, _ := IdempotencyPayloadForCommand(reused)
if bytes.Equal(left, right) {
t.Fatal("same command_id reused for another combo batch was not detected")
}
}