package tencentim import ( "bytes" "context" "encoding/json" "io" "net/http" "strings" "testing" "time" ) // roundTripFunc 允许测试拦截腾讯云 REST 请求而不访问外网。 type roundTripFunc func(*http.Request) (*http.Response, error) // RoundTrip 实现 http.RoundTripper。 func (f roundTripFunc) RoundTrip(request *http.Request) (*http.Response, error) { return f(request) } // TestRESTClientEnsureRoomGroupBuildsTencentRequest 锁定建群请求的 REST 命令和核心字段。 func TestRESTClientEnsureRoomGroupBuildsTencentRequest(t *testing.T) { var capturedPath string var capturedBody map[string]any client := newTestRESTClient(t, func(request *http.Request) (*http.Response, error) { capturedPath = request.URL.Path if err := json.NewDecoder(request.Body).Decode(&capturedBody); err != nil { t.Fatalf("decode request body failed: %v", err) } return okRESTResponse(), nil }) if err := client.EnsureRoomGroup(context.Background(), "room-1001", 10001); err != nil { t.Fatalf("EnsureRoomGroup failed: %v", err) } if capturedPath != "/"+createGroupCommand { t.Fatalf("path mismatch: got %q", capturedPath) } if capturedBody["GroupId"] != "room-1001" || capturedBody["Type"] != DefaultGroupType { t.Fatalf("unexpected create group body: %+v", capturedBody) } } // TestRESTClientPublishRoomEventBuildsCustomMessage 锁定房间系统事件的自定义消息载荷。 func TestRESTClientPublishRoomEventBuildsCustomMessage(t *testing.T) { var capturedPath string var capturedBody map[string]any client := newTestRESTClient(t, func(request *http.Request) (*http.Response, error) { capturedPath = request.URL.Path if err := json.NewDecoder(request.Body).Decode(&capturedBody); err != nil { t.Fatalf("decode request body failed: %v", err) } return okRESTResponse(), nil }) err := client.PublishRoomEvent(context.Background(), RoomEvent{ EventID: "evt-1", RoomID: "room-1001", EventType: "room_gift_sent", ActorUserID: 10001, TargetUserID: 10002, GiftValue: 20, RoomVersion: 7, }) if err != nil { t.Fatalf("PublishRoomEvent failed: %v", err) } if capturedPath != "/"+sendGroupMsgCommand { t.Fatalf("path mismatch: got %q", capturedPath) } if capturedBody["GroupId"] != "room-1001" { t.Fatalf("group id mismatch: %+v", capturedBody) } body, ok := capturedBody["MsgBody"].([]any) if !ok || len(body) != 1 { t.Fatalf("unexpected msg body: %+v", capturedBody["MsgBody"]) } element, ok := body[0].(map[string]any) if !ok || element["MsgType"] != "TIMCustomElem" { t.Fatalf("unexpected message element: %+v", body[0]) } content, ok := element["MsgContent"].(map[string]any) if !ok || content["Ext"] != "room_system_message" || content["Desc"] != "room_gift_sent" { t.Fatalf("unexpected custom content: %+v", element["MsgContent"]) } if !strings.Contains(content["Data"].(string), `"event_id":"evt-1"`) { t.Fatalf("event payload missing event_id: %s", content["Data"]) } } // TestRESTClientDeleteRoomGroupMemberBuildsTencentRequest 锁定踢出 IM 群成员的 REST 请求。 func TestRESTClientDeleteRoomGroupMemberBuildsTencentRequest(t *testing.T) { var capturedPath string var capturedBody map[string]any client := newTestRESTClient(t, func(request *http.Request) (*http.Response, error) { capturedPath = request.URL.Path if err := json.NewDecoder(request.Body).Decode(&capturedBody); err != nil { t.Fatalf("decode request body failed: %v", err) } return okRESTResponse(), nil }) if err := client.DeleteRoomGroupMember(context.Background(), "room-1001", 10002); err != nil { t.Fatalf("DeleteRoomGroupMember failed: %v", err) } if capturedPath != "/"+deleteGroupMemberCommand { t.Fatalf("path mismatch: got %q", capturedPath) } members, ok := capturedBody["MemberToDel_Account"].([]any) if !ok || len(members) != 1 || members[0] != "10002" { t.Fatalf("unexpected member removal body: %+v", capturedBody) } if capturedBody["GroupId"] != "room-1001" || capturedBody["Silence"].(float64) != 1 { t.Fatalf("unexpected group removal body: %+v", capturedBody) } } func newTestRESTClient(t *testing.T, roundTrip roundTripFunc) *RESTClient { t.Helper() client, err := NewRESTClient(RESTConfig{ SDKAppID: 1400000000, SecretKey: "secret", AdminIdentifier: "administrator", AdminUserSigTTL: time.Hour, HTTPClient: &http.Client{ Transport: roundTrip, }, }) if err != nil { t.Fatalf("NewRESTClient failed: %v", err) } return client } func okRESTResponse() *http.Response { payload := []byte(`{"ActionStatus":"OK","ErrorCode":0,"ErrorInfo":""}`) return &http.Response{ StatusCode: http.StatusOK, Body: io.NopCloser(bytes.NewReader(payload)), Header: make(http.Header), } }