500 lines
18 KiB
Go
500 lines
18 KiB
Go
package integration
|
|
|
|
import (
|
|
"bytes"
|
|
"context"
|
|
"encoding/json"
|
|
"io"
|
|
"net/http"
|
|
"testing"
|
|
"time"
|
|
|
|
roomeventsv1 "hyapp.local/api/proto/events/room/v1"
|
|
"hyapp/pkg/tencentim"
|
|
"hyapp/services/room-service/internal/room/outbox"
|
|
)
|
|
|
|
func TestRoomEventFromEnvelopeSkipsNonIMEvents(t *testing.T) {
|
|
record, err := outbox.Build("room-noop", "RoomCreated", 1, time.Now(), &roomeventsv1.RoomCreated{
|
|
OwnerUserId: 1,
|
|
SeatCount: 4,
|
|
Mode: "social",
|
|
})
|
|
if err != nil {
|
|
t.Fatalf("Build RoomCreated envelope failed: %v", err)
|
|
}
|
|
|
|
event, publish, err := roomEventFromEnvelope(record.Envelope)
|
|
if err != nil {
|
|
t.Fatalf("RoomCreated should be a no-op success: %v", err)
|
|
}
|
|
if publish {
|
|
t.Fatalf("RoomCreated must not publish Tencent IM message: %+v", event)
|
|
}
|
|
}
|
|
|
|
func TestRoomUserJoinedCarriesEntryVehicleSnapshot(t *testing.T) {
|
|
record, err := outbox.Build("room-vehicle", "RoomUserJoined", 9, time.Now(), &roomeventsv1.RoomUserJoined{
|
|
UserId: 42,
|
|
Role: "audience",
|
|
VisibleRegionId: 86,
|
|
Nickname: "Join Nina",
|
|
Avatar: "https://cdn.example.com/nina.png",
|
|
DisplayUserId: "100042",
|
|
PrettyDisplayUserId: "888042",
|
|
EntryVehicle: &roomeventsv1.RoomEntryVehicleSnapshot{
|
|
ResourceId: 7001,
|
|
ResourceCode: "vehicle_gold",
|
|
Name: "Gold Vehicle",
|
|
AssetUrl: "https://cdn.example.com/vehicle.png",
|
|
PreviewUrl: "https://cdn.example.com/vehicle-preview.png",
|
|
AnimationUrl: "https://cdn.example.com/vehicle.svga",
|
|
MetadataJson: `{"speed":"fast"}`,
|
|
EntitlementId: "ent-vehicle",
|
|
ExpiresAtMs: 1999999999999,
|
|
},
|
|
})
|
|
if err != nil {
|
|
t.Fatalf("Build RoomUserJoined envelope failed: %v", err)
|
|
}
|
|
|
|
event, publish, err := roomEventFromEnvelope(record.Envelope)
|
|
if err != nil {
|
|
t.Fatalf("RoomUserJoined should decode: %v", err)
|
|
}
|
|
if !publish {
|
|
t.Fatal("RoomUserJoined must publish Tencent IM message")
|
|
}
|
|
if event.EntryVehicle == nil || event.EntryVehicle.ResourceID != 7001 || event.EntryVehicle.AnimationURL != "https://cdn.example.com/vehicle.svga" {
|
|
t.Fatalf("entry vehicle snapshot mismatch: %+v", event.EntryVehicle)
|
|
}
|
|
if event.Attributes["nickname"] != "Join Nina" || event.Attributes["avatar"] != "https://cdn.example.com/nina.png" || event.Attributes["display_user_id"] != "100042" || event.Attributes["pretty_display_user_id"] != "888042" {
|
|
t.Fatalf("joined display profile attributes mismatch: %+v", event.Attributes)
|
|
}
|
|
}
|
|
|
|
func TestRoomBackgroundChangedPublishesDedicatedIMEvent(t *testing.T) {
|
|
record, err := outbox.Build("room-bg", "RoomBackgroundChanged", 7, time.Now(), &roomeventsv1.RoomBackgroundChanged{
|
|
ActorUserId: 42,
|
|
BackgroundId: 101,
|
|
RoomBackgroundUrl: "https://cdn.example.com/bg.png",
|
|
})
|
|
if err != nil {
|
|
t.Fatalf("Build RoomBackgroundChanged envelope failed: %v", err)
|
|
}
|
|
|
|
event, publish, err := roomEventFromEnvelope(record.Envelope)
|
|
if err != nil {
|
|
t.Fatalf("RoomBackgroundChanged should decode: %v", err)
|
|
}
|
|
if !publish {
|
|
t.Fatal("RoomBackgroundChanged must publish Tencent IM message")
|
|
}
|
|
if event.EventType != "room_background_changed" || event.Attributes["room_background_url"] != "https://cdn.example.com/bg.png" || event.Attributes["background_id"] != "101" {
|
|
t.Fatalf("background IM event mismatch: %+v", event)
|
|
}
|
|
}
|
|
|
|
func TestRoomGiftSentCarriesTargetGiftValueInIMAttributes(t *testing.T) {
|
|
record, err := outbox.Build("room-gift-value", "RoomGiftSent", 8, time.Now(), &roomeventsv1.RoomGiftSent{
|
|
SenderUserId: 1001,
|
|
TargetUserId: 1002,
|
|
GiftId: "gift_rose",
|
|
GiftCount: 1,
|
|
GiftValue: 117,
|
|
TargetGiftValue: 367,
|
|
SenderName: "Robot Sender",
|
|
SenderAvatar: "https://cdn.example/sender.png",
|
|
SenderDisplayUserId: "100001",
|
|
ReceiverNickname: "Robot Receiver",
|
|
ReceiverAvatar: "https://cdn.example/receiver.png",
|
|
ReceiverDisplayUserId: "100002",
|
|
})
|
|
if err != nil {
|
|
t.Fatalf("Build RoomGiftSent envelope failed: %v", err)
|
|
}
|
|
|
|
event, publish, err := roomEventFromEnvelope(record.Envelope)
|
|
if err != nil {
|
|
t.Fatalf("RoomGiftSent should decode: %v", err)
|
|
}
|
|
if !publish {
|
|
t.Fatal("RoomGiftSent must publish Tencent IM message")
|
|
}
|
|
if event.EventType != "room_gift_sent" || event.GiftValue != 117 || event.Attributes["target_gift_value"] != "367" {
|
|
t.Fatalf("gift IM event target gift value mismatch: %+v", event)
|
|
}
|
|
if event.Attributes["sender_name"] != "Robot Sender" || event.Attributes["sender_avatar"] != "https://cdn.example/sender.png" || event.Attributes["sender_display_user_id"] != "100001" {
|
|
t.Fatalf("gift IM event sender display fields mismatch: %+v", event.Attributes)
|
|
}
|
|
if event.Attributes["receiver_nickname"] != "Robot Receiver" || event.Attributes["receiver_avatar"] != "https://cdn.example/receiver.png" || event.Attributes["receiver_display_user_id"] != "100002" {
|
|
t.Fatalf("gift IM event receiver display fields mismatch: %+v", event.Attributes)
|
|
}
|
|
}
|
|
|
|
func TestRoomGiftSentBatchDisplayFactSkipsSingleTargetIM(t *testing.T) {
|
|
record, err := outbox.Build("room-gift-batch-fact", "RoomGiftSent", 9, time.Now(), &roomeventsv1.RoomGiftSent{
|
|
SenderUserId: 1001,
|
|
TargetUserId: 1002,
|
|
GiftId: "gift_clover",
|
|
GiftCount: 1,
|
|
GiftValue: 100,
|
|
TargetGiftValue: 900,
|
|
DisplayMode: "batch",
|
|
})
|
|
if err != nil {
|
|
t.Fatalf("Build batch RoomGiftSent fact failed: %v", err)
|
|
}
|
|
|
|
event, publish, err := roomEventFromEnvelope(record.Envelope)
|
|
if err != nil {
|
|
t.Fatalf("batch RoomGiftSent fact should decode without publishing: %v", err)
|
|
}
|
|
if publish {
|
|
t.Fatalf("batch RoomGiftSent fact must not publish single-target IM, event=%+v", event)
|
|
}
|
|
}
|
|
|
|
func TestRoomGiftBatchSentPublishesSingleBatchIMEvent(t *testing.T) {
|
|
record, err := outbox.Build("room-gift-batch", "RoomGiftBatchSent", 12, time.Now(), &roomeventsv1.RoomGiftBatchSent{
|
|
SenderUserId: 1001,
|
|
SenderName: "Batch Sender",
|
|
GiftId: "gift_clover",
|
|
GiftCount: 2,
|
|
TotalGiftValue: 600,
|
|
TotalCoinSpent: 600,
|
|
BillingReceiptId: "receipt-batch",
|
|
RoomHeat: 6600,
|
|
PoolId: "super_lucky",
|
|
GiftEffectTypes: []string{"room"},
|
|
TargetUserIds: []int64{1002, 1003},
|
|
CommandId: "cmd-batch",
|
|
Targets: []*roomeventsv1.RoomGiftBatchTarget{
|
|
{
|
|
TargetUserId: 1002,
|
|
ReceiverNickname: "Receiver One",
|
|
GiftValue: 300,
|
|
TargetGiftValue: 1300,
|
|
CommandId: "cmd-batch:target:1002",
|
|
LuckyGift: &roomeventsv1.RoomGiftBatchLuckyResult{
|
|
Enabled: true,
|
|
DrawId: "draw-1",
|
|
CommandId: "cmd-batch:target:1002",
|
|
PoolId: "super_lucky",
|
|
GiftId: "gift_clover",
|
|
MultiplierPpm: 2_000_000,
|
|
EffectiveRewardCoins: 200,
|
|
RewardStatus: "granted",
|
|
TargetUserId: 1002,
|
|
},
|
|
},
|
|
{TargetUserId: 1003, ReceiverNickname: "Receiver Two", GiftValue: 300, TargetGiftValue: 900, CommandId: "cmd-batch:target:1003"},
|
|
},
|
|
})
|
|
if err != nil {
|
|
t.Fatalf("Build RoomGiftBatchSent envelope failed: %v", err)
|
|
}
|
|
|
|
event, publish, err := roomEventFromEnvelope(record.Envelope)
|
|
if err != nil {
|
|
t.Fatalf("RoomGiftBatchSent should decode: %v", err)
|
|
}
|
|
if !publish || event.EventType != "room_gift_batch_sent" || event.ActorUserID != 1001 || event.TargetUserID != 1002 || event.GiftValue != 600 || event.RoomHeat != 6600 {
|
|
t.Fatalf("batch gift IM event mismatch: publish=%t event=%+v", publish, event)
|
|
}
|
|
if event.Attributes["target_user_ids"] != `[1002,1003]` || event.Attributes["target_count"] != "2" {
|
|
t.Fatalf("batch gift IM target attributes mismatch: %+v", event.Attributes)
|
|
}
|
|
if event.Attributes["gift_id"] != "gift_clover" || event.Attributes["gift_count"] != "2" || event.Attributes["command_id"] != "cmd-batch" {
|
|
t.Fatalf("batch gift IM gift attributes mismatch: %+v", event.Attributes)
|
|
}
|
|
if _, exists := event.Attributes["targets"]; exists {
|
|
t.Fatalf("room batch IM must not include bulky targets: %+v", event.Attributes)
|
|
}
|
|
if _, exists := event.Attributes["lucky_gifts"]; exists {
|
|
t.Fatalf("room batch IM must not include bulky lucky_gifts: %+v", event.Attributes)
|
|
}
|
|
if _, exists := event.Attributes["coin_balance_after"]; exists {
|
|
t.Fatalf("room IM must not expose sender coin balance: %+v", event.Attributes)
|
|
}
|
|
payload, err := json.Marshal(event)
|
|
if err != nil {
|
|
t.Fatalf("marshal batch gift IM event failed: %v", err)
|
|
}
|
|
if len(payload) > 4096 {
|
|
t.Fatalf("batch gift IM payload should stay small, bytes=%d payload=%s", len(payload), payload)
|
|
}
|
|
}
|
|
|
|
func TestRoomHeatAndRankChangedPublishDisplayIMEvents(t *testing.T) {
|
|
heatRecord, err := outbox.Build("room-robot-heat", "RoomHeatChanged", 9, time.Now(), &roomeventsv1.RoomHeatChanged{
|
|
Delta: 120,
|
|
CurrentHeat: 880,
|
|
})
|
|
if err != nil {
|
|
t.Fatalf("Build RoomHeatChanged envelope failed: %v", err)
|
|
}
|
|
heatEvent, publish, err := roomEventFromEnvelope(heatRecord.Envelope)
|
|
if err != nil {
|
|
t.Fatalf("RoomHeatChanged should decode: %v", err)
|
|
}
|
|
if !publish || heatEvent.EventType != "room_heat_changed" || heatEvent.RoomHeat != 880 || heatEvent.Attributes["delta"] != "120" {
|
|
t.Fatalf("heat IM event mismatch: publish=%t event=%+v", publish, heatEvent)
|
|
}
|
|
|
|
rankRecord, err := outbox.Build("room-robot-rank", "RoomRankChanged", 10, time.Now(), &roomeventsv1.RoomRankChanged{
|
|
UserId: 1002,
|
|
Score: 360,
|
|
GiftValue: 360,
|
|
})
|
|
if err != nil {
|
|
t.Fatalf("Build RoomRankChanged envelope failed: %v", err)
|
|
}
|
|
rankEvent, publish, err := roomEventFromEnvelope(rankRecord.Envelope)
|
|
if err != nil {
|
|
t.Fatalf("RoomRankChanged should decode: %v", err)
|
|
}
|
|
if !publish || rankEvent.EventType != "room_rank_changed" || rankEvent.TargetUserID != 1002 || rankEvent.GiftValue != 360 || rankEvent.Attributes["score"] != "360" {
|
|
t.Fatalf("rank IM event mismatch: publish=%t event=%+v", publish, rankEvent)
|
|
}
|
|
}
|
|
|
|
func TestRoomRobotLuckyGiftDrawnPublishesLuckyGiftIMEvent(t *testing.T) {
|
|
record, err := outbox.Build("room-robot-lucky", "RoomRobotLuckyGiftDrawn", 11, time.Now(), &roomeventsv1.RoomRobotLuckyGiftDrawn{
|
|
DrawId: "robot_lucky_draw_1",
|
|
CommandId: "cmd_robot_lucky_1",
|
|
SenderUserId: 1001,
|
|
TargetUserId: 1002,
|
|
GiftId: "gift_lucky_1",
|
|
GiftCount: 1,
|
|
PoolId: "robot_lucky_display",
|
|
MultiplierPpm: 5000000,
|
|
BaseRewardCoins: 500,
|
|
EffectiveRewardCoins: 500,
|
|
CreatedAtMs: 1778000000000,
|
|
VisibleRegionId: 86,
|
|
IsRobot: true,
|
|
Synthetic: true,
|
|
})
|
|
if err != nil {
|
|
t.Fatalf("Build RoomRobotLuckyGiftDrawn envelope failed: %v", err)
|
|
}
|
|
|
|
event, publish, err := roomEventFromEnvelope(record.Envelope)
|
|
if err != nil {
|
|
t.Fatalf("RoomRobotLuckyGiftDrawn should decode: %v", err)
|
|
}
|
|
if !publish || event.EventType != "lucky_gift_drawn" || event.ActorUserID != 1001 || event.TargetUserID != 1002 {
|
|
t.Fatalf("robot lucky gift IM event mismatch: publish=%t event=%+v", publish, event)
|
|
}
|
|
if event.Attributes["draw_id"] != "robot_lucky_draw_1" ||
|
|
event.Attributes["gift_id"] != "gift_lucky_1" ||
|
|
event.Attributes["pool_id"] != "robot_lucky_display" ||
|
|
event.Attributes["effective_reward_coins"] != "500" ||
|
|
event.Attributes["reward_status"] != "granted" {
|
|
t.Fatalf("robot lucky gift IM attributes mismatch: %+v", event.Attributes)
|
|
}
|
|
}
|
|
|
|
func TestRoomMicChangedCarriesTargetGiftValueInIMAttributes(t *testing.T) {
|
|
record, err := outbox.Build("room-mic-value", "RoomMicChanged", 9, time.Now(), &roomeventsv1.RoomMicChanged{
|
|
ActorUserId: 1001,
|
|
TargetUserId: 1002,
|
|
FromSeat: 2,
|
|
ToSeat: 5,
|
|
Action: "change",
|
|
TargetGiftValue: 367,
|
|
TargetNickname: "Mic Alice",
|
|
TargetAvatar: "https://cdn.example.test/alice.png",
|
|
TargetDisplayUserId: "200002",
|
|
TargetPrettyDisplayUserId: "VIP200002",
|
|
})
|
|
if err != nil {
|
|
t.Fatalf("Build RoomMicChanged envelope failed: %v", err)
|
|
}
|
|
|
|
event, publish, err := roomEventFromEnvelope(record.Envelope)
|
|
if err != nil {
|
|
t.Fatalf("RoomMicChanged should decode: %v", err)
|
|
}
|
|
if !publish {
|
|
t.Fatal("RoomMicChanged must publish Tencent IM message")
|
|
}
|
|
if event.EventType != "room_mic_changed" || event.SeatNo != 5 || event.Attributes["target_gift_value"] != "367" {
|
|
t.Fatalf("mic IM event target gift value mismatch: %+v", event)
|
|
}
|
|
if event.Attributes["target_nickname"] != "Mic Alice" ||
|
|
event.Attributes["target_avatar"] != "https://cdn.example.test/alice.png" ||
|
|
event.Attributes["target_display_user_id"] != "200002" ||
|
|
event.Attributes["target_pretty_display_user_id"] != "VIP200002" {
|
|
t.Fatalf("mic IM target display snapshot mismatch: %+v", event.Attributes)
|
|
}
|
|
if _, exists := event.Attributes["nickname"]; exists {
|
|
t.Fatalf("admin mic change must not expose target snapshot as actor nickname: %+v", event.Attributes)
|
|
}
|
|
}
|
|
|
|
func TestRoomMicChangedSelfEventCarriesLegacyDisplayAliases(t *testing.T) {
|
|
record, err := outbox.Build("room-mic-self", "RoomMicChanged", 10, time.Now(), &roomeventsv1.RoomMicChanged{
|
|
ActorUserId: 1002,
|
|
TargetUserId: 1002,
|
|
ToSeat: 3,
|
|
Action: "up",
|
|
TargetNickname: "Mic Alice",
|
|
TargetAvatar: "https://cdn.example.test/alice.png",
|
|
TargetDisplayUserId: "200002",
|
|
TargetPrettyDisplayUserId: "VIP200002",
|
|
})
|
|
if err != nil {
|
|
t.Fatalf("Build RoomMicChanged envelope failed: %v", err)
|
|
}
|
|
|
|
event, publish, err := roomEventFromEnvelope(record.Envelope)
|
|
if err != nil {
|
|
t.Fatalf("RoomMicChanged should decode: %v", err)
|
|
}
|
|
if !publish {
|
|
t.Fatal("RoomMicChanged must publish Tencent IM message")
|
|
}
|
|
if event.Attributes["nickname"] != "Mic Alice" ||
|
|
event.Attributes["avatar"] != "https://cdn.example.test/alice.png" ||
|
|
event.Attributes["display_user_id"] != "200002" ||
|
|
event.Attributes["pretty_display_user_id"] != "VIP200002" {
|
|
t.Fatalf("self mic IM display aliases mismatch: %+v", event.Attributes)
|
|
}
|
|
}
|
|
|
|
func TestRoomPasswordChangedSkipsRoomGroupIM(t *testing.T) {
|
|
record, err := outbox.Build("room-lock", "RoomPasswordChanged", 8, time.Now(), &roomeventsv1.RoomPasswordChanged{
|
|
ActorUserId: 42,
|
|
Locked: true,
|
|
VisibleRegionId: 86,
|
|
})
|
|
if err != nil {
|
|
t.Fatalf("Build RoomPasswordChanged envelope failed: %v", err)
|
|
}
|
|
|
|
event, publish, err := roomEventFromEnvelope(record.Envelope)
|
|
if err != nil {
|
|
t.Fatalf("RoomPasswordChanged should decode: %v", err)
|
|
}
|
|
if publish {
|
|
t.Fatalf("RoomPasswordChanged must use activity region broadcast, not room group IM: %+v", event)
|
|
}
|
|
}
|
|
|
|
func TestTencentIMPublisherRemovesGroupMemberBeforeKickMessage(t *testing.T) {
|
|
paths := make([]string, 0, 2)
|
|
bodies := make([]map[string]any, 0, 2)
|
|
client, err := tencentim.NewRESTClient(tencentim.RESTConfig{
|
|
SDKAppID: 1400000000,
|
|
SecretKey: "secret",
|
|
AdminIdentifier: "administrator",
|
|
AdminUserSigTTL: time.Hour,
|
|
HTTPClient: &http.Client{Transport: roundTripFunc(func(request *http.Request) (*http.Response, error) {
|
|
paths = append(paths, request.URL.Path)
|
|
var body map[string]any
|
|
if err := json.NewDecoder(request.Body).Decode(&body); err != nil {
|
|
t.Fatalf("decode request body failed: %v", err)
|
|
}
|
|
bodies = append(bodies, body)
|
|
return &http.Response{
|
|
StatusCode: http.StatusOK,
|
|
Body: io.NopCloser(bytes.NewReader([]byte(`{"ActionStatus":"OK","ErrorCode":0,"ErrorInfo":""}`))),
|
|
Header: make(http.Header),
|
|
}, nil
|
|
})},
|
|
})
|
|
if err != nil {
|
|
t.Fatalf("NewRESTClient failed: %v", err)
|
|
}
|
|
|
|
record, err := outbox.Build("room-kick", "RoomUserKicked", 3, time.Now(), &roomeventsv1.RoomUserKicked{
|
|
ActorUserId: 1,
|
|
TargetUserId: 2,
|
|
})
|
|
if err != nil {
|
|
t.Fatalf("Build RoomUserKicked envelope failed: %v", err)
|
|
}
|
|
publisher := NewTencentIMPublisher(client)
|
|
if err := publisher.PublishOutboxEvent(context.Background(), record.Envelope); err != nil {
|
|
t.Fatalf("PublishOutboxEvent failed: %v", err)
|
|
}
|
|
|
|
if len(paths) != 2 || paths[0] != "/v4/group_open_http_svc/delete_group_member" || paths[1] != "/v4/group_open_http_svc/send_group_msg" {
|
|
t.Fatalf("kick outbox should delete member before system message, paths=%+v", paths)
|
|
}
|
|
if bodies[0]["GroupId"] != "room-kick" || bodies[1]["GroupId"] != "room-kick" {
|
|
t.Fatalf("kick outbox must use original room group id, bodies=%+v", bodies)
|
|
}
|
|
}
|
|
|
|
func TestTencentIMPublisherEnsuresRoomGroupAndRetriesWhenGroupMissing(t *testing.T) {
|
|
paths := make([]string, 0, 3)
|
|
bodies := make([]map[string]any, 0, 3)
|
|
client, err := tencentim.NewRESTClient(tencentim.RESTConfig{
|
|
SDKAppID: 1400000000,
|
|
SecretKey: "secret",
|
|
AdminIdentifier: "administrator",
|
|
AdminUserSigTTL: time.Hour,
|
|
HTTPClient: &http.Client{Transport: roundTripFunc(func(request *http.Request) (*http.Response, error) {
|
|
paths = append(paths, request.URL.Path)
|
|
var body map[string]any
|
|
if err := json.NewDecoder(request.Body).Decode(&body); err != nil {
|
|
t.Fatalf("decode request body failed: %v", err)
|
|
}
|
|
bodies = append(bodies, body)
|
|
if len(paths) == 1 {
|
|
return &http.Response{
|
|
StatusCode: http.StatusOK,
|
|
Body: io.NopCloser(bytes.NewReader([]byte(`{"ActionStatus":"FAIL","ErrorCode":10015,"ErrorInfo":"bytes_group_id invalid"}`))),
|
|
Header: make(http.Header),
|
|
}, nil
|
|
}
|
|
return &http.Response{
|
|
StatusCode: http.StatusOK,
|
|
Body: io.NopCloser(bytes.NewReader([]byte(`{"ActionStatus":"OK","ErrorCode":0,"ErrorInfo":""}`))),
|
|
Header: make(http.Header),
|
|
}, nil
|
|
})},
|
|
})
|
|
if err != nil {
|
|
t.Fatalf("NewRESTClient failed: %v", err)
|
|
}
|
|
|
|
publisher := NewTencentIMPublisher(client)
|
|
err = publisher.PublishRoomEvent(context.Background(), tencentim.RoomEvent{
|
|
EventID: "evt-retry",
|
|
RoomID: "lalu_2963d975-316e-444d-ad5c-f82fc36c28ca",
|
|
EventType: "room_mic_changed",
|
|
})
|
|
if err != nil {
|
|
t.Fatalf("PublishRoomEvent should retry after ensuring group: %v", err)
|
|
}
|
|
|
|
wantPaths := []string{
|
|
"/v4/group_open_http_svc/send_group_msg",
|
|
"/v4/group_open_http_svc/create_group",
|
|
"/v4/group_open_http_svc/send_group_msg",
|
|
}
|
|
if len(paths) != len(wantPaths) {
|
|
t.Fatalf("path count mismatch: paths=%+v bodies=%+v", paths, bodies)
|
|
}
|
|
for index, want := range wantPaths {
|
|
if paths[index] != want {
|
|
t.Fatalf("path[%d] mismatch: got %s want %s", index, paths[index], want)
|
|
}
|
|
}
|
|
for index, body := range bodies {
|
|
if body["GroupId"] != "lalu_2963d975-316e-444d-ad5c-f82fc36c28ca" {
|
|
t.Fatalf("request %d must preserve original room group id: %+v", index, body)
|
|
}
|
|
}
|
|
}
|
|
|
|
type roundTripFunc func(*http.Request) (*http.Response, error)
|
|
|
|
func (f roundTripFunc) RoundTrip(request *http.Request) (*http.Response, error) {
|
|
return f(request)
|
|
}
|