fix: support agora rtc join delivery flow
This commit is contained in:
+2
-2
@@ -2068,11 +2068,11 @@ X-MeetingIM-APIKey: <预置的普通 API Key>
|
|||||||
| --- | --- | --- |
|
| --- | --- | --- |
|
||||||
| WebSocket 发起通话 | `{"pub":{"id":"call-1","topic":"p2p...","head":{"mime":"application/json","webrtc":"started","x-im-type":"call"},"content":{"callId":"call_1","callType":"audio","audio":true,"video":false}}}` | `{"ctrl":{"id":"call-1","code":202,"params":{"seq":12}}}` |
|
| WebSocket 发起通话 | `{"pub":{"id":"call-1","topic":"p2p...","head":{"mime":"application/json","webrtc":"started","x-im-type":"call"},"content":{"callId":"call_1","callType":"audio","audio":true,"video":false}}}` | `{"ctrl":{"id":"call-1","code":202,"params":{"seq":12}}}` |
|
||||||
| WebSocket 通话事件 | `{"note":{"topic":"p2p...","what":"call","event":"accept","seq":12,"payload":{"callId":"call_1"}}}` | 对端收到 `{"info":{"topic":"p2p...","what":"call","event":"accept","seq":12,"payload":{"callId":"call_1"}}}` |
|
| WebSocket 通话事件 | `{"note":{"topic":"p2p...","what":"call","event":"accept","seq":12,"payload":{"callId":"call_1"}}}` | 对端收到 `{"info":{"topic":"p2p...","what":"call","event":"accept","seq":12,"payload":{"callId":"call_1"}}}` |
|
||||||
| `POST /v1/im/calls/rtc-join` | `{"topic":"p2p...","call_id":"call_1","seq":12,"call_type":"audio","role":"caller"}` | `{"provider":"agora","auth_mode":"token","app_id":"声网 App ID","channel_name":"call_call_1","uid":"usr...","token":"007eJx...","token_expires_at":"2026-09-02T10:00:00Z","call_id":"call_1","topic":"p2p...","seq":12,"call_type":"audio","role":"caller"}` |
|
| `POST /v1/im/calls/rtc-join` | `{"topic":"usr_peer 或 p2p...","call_id":"call_1","seq":12,"call_type":"audio","role":"caller"}` | `{"provider":"agora","auth_mode":"token","app_id":"声网 App ID","channel_name":"call_call_1","uid":"usr...","token":"007eJx...","token_expires_at":"2026-09-02T10:00:00Z","call_id":"call_1","topic":"p2p...","seq":12,"call_type":"audio","role":"caller"}` |
|
||||||
| `GET /v1/im/calls?limit=20&cursor=` | Query only | `{"items":[{"call_id":"call_1","topic":"p2p...","seq":12,"call_type":"audio","status":"finished","started_at":"2026-08-20T09:00:00Z","duration_ms":60000,"peer":{"user_id":"usr...","display_name":"张三"}}],"next_cursor":""}` |
|
| `GET /v1/im/calls?limit=20&cursor=` | Query only | `{"items":[{"call_id":"call_1","topic":"p2p...","seq":12,"call_type":"audio","status":"finished","started_at":"2026-08-20T09:00:00Z","duration_ms":60000,"peer":{"user_id":"usr...","display_name":"张三"}}],"next_cursor":""}` |
|
||||||
| `GET /v1/im/calls/{topic}?cursor=` | Path topic | `{"topic":"p2p...","items":[{"call_id":"call_1","seq":12,"status":"missed","call_type":"video","created_at":"2026-08-20T09:00:00Z"}],"next_cursor":""}` |
|
| `GET /v1/im/calls/{topic}?cursor=` | Path topic | `{"topic":"p2p...","items":[{"call_id":"call_1","seq":12,"status":"missed","call_type":"video","created_at":"2026-08-20T09:00:00Z"}],"next_cursor":""}` |
|
||||||
|
|
||||||
声网模式下,新客户端在发起方收到 `ctrl.params.seq` 后、被叫方点击接听后,分别调用 `POST /v1/im/calls/rtc-join` 获取 `app_id/channel_name/uid/token`。当前按正式 `token` 模式接入,后端使用 `im_shengwang` 分组中的 `agora_app_certificate` 生成 RTC Token。客户端不接触 `app_certificate`、`customer_id`、`customer_secret`,也不再通过 IM WebSocket 交换 SDP/ICE,音视频媒体协商和传输由声网 RTC SDK 完成。
|
声网模式下,新客户端在发起方收到 `ctrl.params.seq` 后、被叫方点击接听后,分别调用 `POST /v1/im/calls/rtc-join` 获取 `app_id/channel_name/uid/token`。`topic` 可直接传当前会话里看到的 P2P 别名,例如发起方传被叫 `usr...`、被叫方传发起方 `usr...`;后端会归一到真实 `p2p...` 并在响应中返回。当前按正式 `token` 模式接入,后端使用 `im_shengwang` 分组中的 `agora_app_certificate` 生成 RTC Token。客户端不接触 `app_certificate`、`customer_id`、`customer_secret`,也不再通过 IM WebSocket 交换 SDP/ICE,音视频媒体协商和传输由声网 RTC SDK 完成。
|
||||||
|
|
||||||
## 9. 企业工作台与办公协同
|
## 9. 企业工作台与办公协同
|
||||||
|
|
||||||
|
|||||||
@@ -309,7 +309,7 @@ Content-Type: application/json
|
|||||||
1. 后台配置 `agora_enabled=true`、`agora_auth_mode=token`、`agora_app_id`、`agora_app_certificate`。
|
1. 后台配置 `agora_enabled=true`、`agora_auth_mode=token`、`agora_app_id`、`agora_app_certificate`。
|
||||||
2. 客户端集成声网 RTC SDK,并使用后端返回的 RTC Token 入会。
|
2. 客户端集成声网 RTC SDK,并使用后端返回的 RTC Token 入会。
|
||||||
3. A 发起语音通话,确认 B 能收到 IM 来电信令。
|
3. A 发起语音通话,确认 B 能收到 IM 来电信令。
|
||||||
4. A、B 分别调用 `/v1/im/calls/rtc-join`,确认返回同一个 `channel_name`。
|
4. A、B 分别调用 `/v1/im/calls/rtc-join`,可直接传各自会话中看到的对端 `usr...` topic,确认返回同一个 `channel_name` 和真实 `p2p...` topic。
|
||||||
5. A、B 使用各自 `uid` 加入声网频道,确认音频可通。
|
5. A、B 使用各自 `uid` 加入声网频道,确认音频可通。
|
||||||
6. 切换视频通话,确认视频流可通。
|
6. 切换视频通话,确认视频流可通。
|
||||||
7. 测试取消、拒接、挂断、超时、网络断开。
|
7. 测试取消、拒接、挂断、超时、网络断开。
|
||||||
|
|||||||
@@ -188,7 +188,7 @@ Content-Type: application/json
|
|||||||
|
|
||||||
| 字段 | 必填 | 说明 |
|
| 字段 | 必填 | 说明 |
|
||||||
| --- | --- | --- |
|
| --- | --- | --- |
|
||||||
| `topic` | 是 | P2P Topic。首期只支持一对一通话。 |
|
| `topic` | 是 | P2P Topic。可传客户端当前会话看到的 `usr...` 别名,也可传真实 `p2p...`;首期只支持一对一通话。 |
|
||||||
| `call_id` | 是 | 通话 ID,必须和 WebSocket call 消息一致。 |
|
| `call_id` | 是 | 通话 ID,必须和 WebSocket call 消息一致。 |
|
||||||
| `seq` | 建议 | 通话消息 seq。发起方可在 `{pub}` 返回后传入;接听方从收到的 call 消息中取得。 |
|
| `seq` | 建议 | 通话消息 seq。发起方可在 `{pub}` 返回后传入;接听方从收到的 call 消息中取得。 |
|
||||||
| `call_type` | 是 | `audio` 或 `video`。 |
|
| `call_type` | 是 | `audio` 或 `video`。 |
|
||||||
|
|||||||
@@ -195,7 +195,7 @@ func backfillUsernames(ctx context.Context, conn *sqlx.Conn, scoped bool) error
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
var rows []identityValue
|
var rows []identityValue
|
||||||
query := "SELECT " + prefix + "COALESCE(NULLIF(u.username,''),NULLIF(" + selectAuth + ",''),NULLIF(u.phone,''),CONCAT('reserved_',u.id)) AS value FROM im_users AS u" + authJoin + " ORDER BY " + orderBy
|
query := "SELECT " + prefix + "COALESCE(NULLIF(u.username,''),NULLIF(" + selectAuth + ",''),NULLIF(u.phone,''),CONCAT('reserved_',u.id)) AS value FROM im_users AS u" + authJoin + " WHERE u.username IS NULL OR u.username='' ORDER BY " + orderBy
|
||||||
if err = conn.SelectContext(ctx, &rows, query); err != nil {
|
if err = conn.SelectContext(ctx, &rows, query); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -64,10 +64,12 @@ func serveIMCallRTCJoin(wrt http.ResponseWriter, req *http.Request) {
|
|||||||
writeIMError(wrt, req, http.StatusBadRequest, 30000, imReasonMalformedRequest, "malformed request", nil)
|
writeIMError(wrt, req, http.StatusBadRequest, 30000, imReasonMalformedRequest, "malformed request", nil)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if types.GetTopicCat(body.Topic) != types.TopicCatP2P {
|
normalizedTopic, _ := normalizeP2PConversationTopic(body.Topic, principal.Uid)
|
||||||
|
if normalizedTopic == "" {
|
||||||
writeIMError(wrt, req, http.StatusBadRequest, 30000, imReasonMalformedRequest, "malformed request", map[string]any{"field": "topic"})
|
writeIMError(wrt, req, http.StatusBadRequest, 30000, imReasonMalformedRequest, "malformed request", map[string]any{"field": "topic"})
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
body.Topic = normalizedTopic
|
||||||
config, err := loadIMAgoraConfig()
|
config, err := loadIMAgoraConfig()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if errors.Is(err, types.ErrNotFound) || errors.Is(err, types.ErrMalformed) {
|
if errors.Is(err, types.ErrNotFound) || errors.Is(err, types.ErrMalformed) {
|
||||||
|
|||||||
+77
-17
@@ -4759,11 +4759,12 @@ func TestServeIMCallRTCJoinReturnsAgoraAppIDMode(t *testing.T) {
|
|||||||
oldCalls := store.Calls
|
oldCalls := store.Calls
|
||||||
oldThirdParty := store.ThirdPartyConfig
|
oldThirdParty := store.ThirdPartyConfig
|
||||||
subs := mock_store.NewMockSubsPersistenceInterface(ctrl)
|
subs := mock_store.NewMockSubsPersistenceInterface(ctrl)
|
||||||
|
topic := types.Uid(42).P2PName(types.Uid(43))
|
||||||
calls := &testCallsStore{items: []types.CallRecord{{
|
calls := &testCallsStore{items: []types.CallRecord{{
|
||||||
ID: 9,
|
ID: 9,
|
||||||
TenantID: 7,
|
TenantID: 7,
|
||||||
CallID: "call-1",
|
CallID: "call-1",
|
||||||
Topic: "p2pTopic",
|
Topic: topic,
|
||||||
SeqID: 12,
|
SeqID: 12,
|
||||||
CallerID: 42,
|
CallerID: 42,
|
||||||
CalleeID: 43,
|
CalleeID: 43,
|
||||||
@@ -4788,18 +4789,18 @@ func TestServeIMCallRTCJoinReturnsAgoraAppIDMode(t *testing.T) {
|
|||||||
store.Calls = oldCalls
|
store.Calls = oldCalls
|
||||||
store.ThirdPartyConfig = oldThirdParty
|
store.ThirdPartyConfig = oldThirdParty
|
||||||
}()
|
}()
|
||||||
subs.EXPECT().Get(types.TenantID(7), "p2pTopic", types.Uid(42), false).Return(&types.Subscription{
|
subs.EXPECT().Get(types.TenantID(7), topic, types.Uid(42), false).Return(&types.Subscription{
|
||||||
TenantID: 7, User: types.Uid(42).String(), Topic: "p2pTopic", ModeWant: types.ModeCPublic, ModeGiven: types.ModeCPublic,
|
TenantID: 7, User: types.Uid(42).String(), Topic: topic, ModeWant: types.ModeCPublic, ModeGiven: types.ModeCPublic,
|
||||||
}, nil)
|
}, nil)
|
||||||
|
|
||||||
req := httptest.NewRequest(http.MethodPost, "/v1/im/calls/rtc-join", strings.NewReader(`{"topic":"p2pTopic","call_id":"call-1","seq":12,"call_type":"video","role":"caller"}`))
|
req := httptest.NewRequest(http.MethodPost, "/v1/im/calls/rtc-join", strings.NewReader(`{"topic":"`+topic+`","call_id":"call-1","seq":12,"call_type":"video","role":"caller"}`))
|
||||||
req.Header.Set("Authorization", "Bearer token-caller")
|
req.Header.Set("Authorization", "Bearer token-caller")
|
||||||
rec := httptest.NewRecorder()
|
rec := httptest.NewRecorder()
|
||||||
serveIMCallRTCJoin(rec, req)
|
serveIMCallRTCJoin(rec, req)
|
||||||
if rec.Code != http.StatusOK {
|
if rec.Code != http.StatusOK {
|
||||||
t.Fatalf("rtc join status: got %d body=%s", rec.Code, rec.Body.String())
|
t.Fatalf("rtc join status: got %d body=%s", rec.Code, rec.Body.String())
|
||||||
}
|
}
|
||||||
if !calls.listed || calls.tenant != 7 || calls.user != 42 || calls.topic != "p2pTopic" || calls.limit != 100 {
|
if !calls.listed || calls.tenant != 7 || calls.user != 42 || calls.topic != topic || calls.limit != 100 {
|
||||||
t.Fatalf("calls lookup mismatch: %#v", calls)
|
t.Fatalf("calls lookup mismatch: %#v", calls)
|
||||||
}
|
}
|
||||||
resp := decodeIMHTTPResponse(t, rec)
|
resp := decodeIMHTTPResponse(t, rec)
|
||||||
@@ -4810,6 +4811,62 @@ func TestServeIMCallRTCJoinReturnsAgoraAppIDMode(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestServeIMCallRTCJoinAcceptsP2PAliasTopic(t *testing.T) {
|
||||||
|
ctrl := gomock.NewController(t)
|
||||||
|
defer ctrl.Finish()
|
||||||
|
expectIMBearer(t, ctrl, "token-caller", 7, 42)
|
||||||
|
oldSubs := store.Subs
|
||||||
|
oldCalls := store.Calls
|
||||||
|
oldThirdParty := store.ThirdPartyConfig
|
||||||
|
subs := mock_store.NewMockSubsPersistenceInterface(ctrl)
|
||||||
|
peer := types.Uid(43)
|
||||||
|
topic := types.Uid(42).P2PName(peer)
|
||||||
|
calls := &testCallsStore{items: []types.CallRecord{{
|
||||||
|
ID: 9,
|
||||||
|
TenantID: 7,
|
||||||
|
CallID: "call-1",
|
||||||
|
Topic: topic,
|
||||||
|
SeqID: 12,
|
||||||
|
CallerID: 42,
|
||||||
|
CalleeID: peer,
|
||||||
|
CallType: "audio",
|
||||||
|
Status: types.CallStatusStarted,
|
||||||
|
StartedAt: time.Date(2026, 9, 2, 9, 0, 0, 0, time.UTC),
|
||||||
|
CreatedAt: time.Date(2026, 9, 2, 9, 0, 0, 0, time.UTC),
|
||||||
|
UpdatedAt: time.Date(2026, 9, 2, 9, 0, 0, 0, time.UTC),
|
||||||
|
}}}
|
||||||
|
store.Subs = subs
|
||||||
|
store.Calls = calls
|
||||||
|
store.ThirdPartyConfig = testThirdPartyConfigStore{
|
||||||
|
"agora_enabled": "1",
|
||||||
|
"agora_auth_mode": "app_id",
|
||||||
|
"agora_app_id": "app123",
|
||||||
|
"agora_channel_prefix": "call_",
|
||||||
|
"agora_uid_mode": "string",
|
||||||
|
"agora_token_ttl_seconds": "3600",
|
||||||
|
}
|
||||||
|
defer func() {
|
||||||
|
store.Subs = oldSubs
|
||||||
|
store.Calls = oldCalls
|
||||||
|
store.ThirdPartyConfig = oldThirdParty
|
||||||
|
}()
|
||||||
|
subs.EXPECT().Get(types.TenantID(7), topic, types.Uid(42), false).Return(&types.Subscription{
|
||||||
|
TenantID: 7, User: types.Uid(42).String(), Topic: topic, ModeWant: types.ModeCPublic, ModeGiven: types.ModeCPublic,
|
||||||
|
}, nil)
|
||||||
|
|
||||||
|
req := httptest.NewRequest(http.MethodPost, "/v1/im/calls/rtc-join", strings.NewReader(`{"topic":"`+peer.UserId()+`","call_id":"call-1","seq":12,"call_type":"audio","role":"caller"}`))
|
||||||
|
req.Header.Set("Authorization", "Bearer token-caller")
|
||||||
|
rec := httptest.NewRecorder()
|
||||||
|
serveIMCallRTCJoin(rec, req)
|
||||||
|
if rec.Code != http.StatusOK {
|
||||||
|
t.Fatalf("rtc join status: got %d body=%s", rec.Code, rec.Body.String())
|
||||||
|
}
|
||||||
|
data := decodeIMHTTPResponse(t, rec).Data.(map[string]any)
|
||||||
|
if data["topic"] != topic || calls.topic != topic {
|
||||||
|
t.Fatalf("alias topic was not normalized: data=%#v calls=%#v", data, calls)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func TestServeIMCallRTCJoinReturnsSameAgoraChannelForCallee(t *testing.T) {
|
func TestServeIMCallRTCJoinReturnsSameAgoraChannelForCallee(t *testing.T) {
|
||||||
ctrl := gomock.NewController(t)
|
ctrl := gomock.NewController(t)
|
||||||
defer ctrl.Finish()
|
defer ctrl.Finish()
|
||||||
@@ -4827,11 +4884,12 @@ func TestServeIMCallRTCJoinReturnsSameAgoraChannelForCallee(t *testing.T) {
|
|||||||
oldCalls := store.Calls
|
oldCalls := store.Calls
|
||||||
oldThirdParty := store.ThirdPartyConfig
|
oldThirdParty := store.ThirdPartyConfig
|
||||||
subs := mock_store.NewMockSubsPersistenceInterface(ctrl)
|
subs := mock_store.NewMockSubsPersistenceInterface(ctrl)
|
||||||
|
topic := types.Uid(42).P2PName(types.Uid(43))
|
||||||
calls := &testCallsStore{items: []types.CallRecord{{
|
calls := &testCallsStore{items: []types.CallRecord{{
|
||||||
ID: 9,
|
ID: 9,
|
||||||
TenantID: 7,
|
TenantID: 7,
|
||||||
CallID: "call-1",
|
CallID: "call-1",
|
||||||
Topic: "p2pTopic",
|
Topic: topic,
|
||||||
SeqID: 12,
|
SeqID: 12,
|
||||||
CallerID: 42,
|
CallerID: 42,
|
||||||
CalleeID: 43,
|
CalleeID: 43,
|
||||||
@@ -4857,14 +4915,14 @@ func TestServeIMCallRTCJoinReturnsSameAgoraChannelForCallee(t *testing.T) {
|
|||||||
store.Calls = oldCalls
|
store.Calls = oldCalls
|
||||||
store.ThirdPartyConfig = oldThirdParty
|
store.ThirdPartyConfig = oldThirdParty
|
||||||
}()
|
}()
|
||||||
subs.EXPECT().Get(types.TenantID(7), "p2pTopic", types.Uid(42), false).Return(&types.Subscription{
|
subs.EXPECT().Get(types.TenantID(7), topic, types.Uid(42), false).Return(&types.Subscription{
|
||||||
TenantID: 7, User: types.Uid(42).String(), Topic: "p2pTopic", ModeWant: types.ModeCPublic, ModeGiven: types.ModeCPublic,
|
TenantID: 7, User: types.Uid(42).String(), Topic: topic, ModeWant: types.ModeCPublic, ModeGiven: types.ModeCPublic,
|
||||||
}, nil)
|
}, nil)
|
||||||
subs.EXPECT().Get(types.TenantID(7), "p2pTopic", types.Uid(43), false).Return(&types.Subscription{
|
subs.EXPECT().Get(types.TenantID(7), topic, types.Uid(43), false).Return(&types.Subscription{
|
||||||
TenantID: 7, User: types.Uid(43).String(), Topic: "p2pTopic", ModeWant: types.ModeCPublic, ModeGiven: types.ModeCPublic,
|
TenantID: 7, User: types.Uid(43).String(), Topic: topic, ModeWant: types.ModeCPublic, ModeGiven: types.ModeCPublic,
|
||||||
}, nil)
|
}, nil)
|
||||||
|
|
||||||
callerReq := httptest.NewRequest(http.MethodPost, "/v1/im/calls/rtc-join", strings.NewReader(`{"topic":"p2pTopic","call_id":"call-1","seq":12,"call_type":"audio","role":"caller"}`))
|
callerReq := httptest.NewRequest(http.MethodPost, "/v1/im/calls/rtc-join", strings.NewReader(`{"topic":"`+topic+`","call_id":"call-1","seq":12,"call_type":"audio","role":"caller"}`))
|
||||||
callerReq.Header.Set("Authorization", "Bearer token-caller")
|
callerReq.Header.Set("Authorization", "Bearer token-caller")
|
||||||
callerRec := httptest.NewRecorder()
|
callerRec := httptest.NewRecorder()
|
||||||
serveIMCallRTCJoin(callerRec, callerReq)
|
serveIMCallRTCJoin(callerRec, callerReq)
|
||||||
@@ -4872,7 +4930,7 @@ func TestServeIMCallRTCJoinReturnsSameAgoraChannelForCallee(t *testing.T) {
|
|||||||
t.Fatalf("caller rtc join status: got %d body=%s", callerRec.Code, callerRec.Body.String())
|
t.Fatalf("caller rtc join status: got %d body=%s", callerRec.Code, callerRec.Body.String())
|
||||||
}
|
}
|
||||||
|
|
||||||
calleeReq := httptest.NewRequest(http.MethodPost, "/v1/im/calls/rtc-join", strings.NewReader(`{"topic":"p2pTopic","call_id":"call-1","seq":12,"call_type":"audio","role":"callee"}`))
|
calleeReq := httptest.NewRequest(http.MethodPost, "/v1/im/calls/rtc-join", strings.NewReader(`{"topic":"`+topic+`","call_id":"call-1","seq":12,"call_type":"audio","role":"callee"}`))
|
||||||
calleeReq.Header.Set("Authorization", "Bearer token-callee")
|
calleeReq.Header.Set("Authorization", "Bearer token-callee")
|
||||||
calleeRec := httptest.NewRecorder()
|
calleeRec := httptest.NewRecorder()
|
||||||
serveIMCallRTCJoin(calleeRec, calleeReq)
|
serveIMCallRTCJoin(calleeRec, calleeReq)
|
||||||
@@ -4901,11 +4959,12 @@ func TestServeIMCallRTCJoinReturnsAgoraTokenMode(t *testing.T) {
|
|||||||
oldCalls := store.Calls
|
oldCalls := store.Calls
|
||||||
oldThirdParty := store.ThirdPartyConfig
|
oldThirdParty := store.ThirdPartyConfig
|
||||||
subs := mock_store.NewMockSubsPersistenceInterface(ctrl)
|
subs := mock_store.NewMockSubsPersistenceInterface(ctrl)
|
||||||
|
topic := types.Uid(42).P2PName(types.Uid(43))
|
||||||
calls := &testCallsStore{items: []types.CallRecord{{
|
calls := &testCallsStore{items: []types.CallRecord{{
|
||||||
ID: 9,
|
ID: 9,
|
||||||
TenantID: 7,
|
TenantID: 7,
|
||||||
CallID: "call-1",
|
CallID: "call-1",
|
||||||
Topic: "p2pTopic",
|
Topic: topic,
|
||||||
SeqID: 12,
|
SeqID: 12,
|
||||||
CallerID: 42,
|
CallerID: 42,
|
||||||
CalleeID: 43,
|
CalleeID: 43,
|
||||||
@@ -4931,11 +4990,11 @@ func TestServeIMCallRTCJoinReturnsAgoraTokenMode(t *testing.T) {
|
|||||||
store.Calls = oldCalls
|
store.Calls = oldCalls
|
||||||
store.ThirdPartyConfig = oldThirdParty
|
store.ThirdPartyConfig = oldThirdParty
|
||||||
}()
|
}()
|
||||||
subs.EXPECT().Get(types.TenantID(7), "p2pTopic", types.Uid(42), false).Return(&types.Subscription{
|
subs.EXPECT().Get(types.TenantID(7), topic, types.Uid(42), false).Return(&types.Subscription{
|
||||||
TenantID: 7, User: types.Uid(42).String(), Topic: "p2pTopic", ModeWant: types.ModeCPublic, ModeGiven: types.ModeCPublic,
|
TenantID: 7, User: types.Uid(42).String(), Topic: topic, ModeWant: types.ModeCPublic, ModeGiven: types.ModeCPublic,
|
||||||
}, nil)
|
}, nil)
|
||||||
|
|
||||||
req := httptest.NewRequest(http.MethodPost, "/v1/im/calls/rtc-join", strings.NewReader(`{"topic":"p2pTopic","call_id":"call-1","seq":12,"call_type":"video","role":"caller"}`))
|
req := httptest.NewRequest(http.MethodPost, "/v1/im/calls/rtc-join", strings.NewReader(`{"topic":"`+topic+`","call_id":"call-1","seq":12,"call_type":"video","role":"caller"}`))
|
||||||
req.Header.Set("Authorization", "Bearer token-1")
|
req.Header.Set("Authorization", "Bearer token-1")
|
||||||
rec := httptest.NewRecorder()
|
rec := httptest.NewRecorder()
|
||||||
serveIMCallRTCJoin(rec, req)
|
serveIMCallRTCJoin(rec, req)
|
||||||
@@ -4959,7 +5018,8 @@ func TestServeIMCallRTCJoinRejectsDisabledAgora(t *testing.T) {
|
|||||||
store.ThirdPartyConfig = testThirdPartyConfigStore{"agora_enabled": "0"}
|
store.ThirdPartyConfig = testThirdPartyConfigStore{"agora_enabled": "0"}
|
||||||
defer func() { store.ThirdPartyConfig = oldThirdParty }()
|
defer func() { store.ThirdPartyConfig = oldThirdParty }()
|
||||||
|
|
||||||
req := httptest.NewRequest(http.MethodPost, "/v1/im/calls/rtc-join", strings.NewReader(`{"topic":"p2pTopic","call_id":"call-1","seq":12,"call_type":"video","role":"caller"}`))
|
topic := types.Uid(42).P2PName(types.Uid(43))
|
||||||
|
req := httptest.NewRequest(http.MethodPost, "/v1/im/calls/rtc-join", strings.NewReader(`{"topic":"`+topic+`","call_id":"call-1","seq":12,"call_type":"video","role":"caller"}`))
|
||||||
req.Header.Set("Authorization", "Bearer token-1")
|
req.Header.Set("Authorization", "Bearer token-1")
|
||||||
rec := httptest.NewRecorder()
|
rec := httptest.NewRecorder()
|
||||||
serveIMCallRTCJoin(rec, req)
|
serveIMCallRTCJoin(rec, req)
|
||||||
|
|||||||
Reference in New Issue
Block a user