1
0
mirror of https://github.com/matrix-org/matrix-js-sdk.git synced 2025-08-09 10:22:46 +03:00

Add a few group call event handler tests (#2679)

This commit is contained in:
Šimon Brandner
2022-09-22 17:05:51 +02:00
committed by GitHub
parent 72b89fde6e
commit 72a6ec0dd3
2 changed files with 178 additions and 12 deletions

View File

@@ -21,10 +21,12 @@ import {
GroupCall, GroupCall,
GroupCallIntent, GroupCallIntent,
GroupCallType, GroupCallType,
IContent,
ISendEventResponse, ISendEventResponse,
MatrixClient, MatrixClient,
MatrixEvent, MatrixEvent,
Room, Room,
RoomState,
RoomStateEvent, RoomStateEvent,
RoomStateEventHandlerMap, RoomStateEventHandlerMap,
} from "../../src"; } from "../../src";
@@ -381,8 +383,18 @@ export class MockCallMatrixClient extends TypedEventEmitter<EmittedEvents, Emitt
getSyncState = jest.fn<SyncState, []>().mockReturnValue(SyncState.Syncing); getSyncState = jest.fn<SyncState, []>().mockReturnValue(SyncState.Syncing);
getRooms = jest.fn<Room[], []>().mockReturnValue([]); getRooms = jest.fn<Room[], []>().mockReturnValue([]);
getRoom = jest.fn();
typed(): MatrixClient { return this as unknown as MatrixClient; } typed(): MatrixClient { return this as unknown as MatrixClient; }
emitRoomState(event: MatrixEvent, state: RoomState): void {
this.emit(
RoomStateEvent.Events,
event,
state,
null,
);
}
} }
export class MockCallFeed { export class MockCallFeed {
@@ -436,15 +448,15 @@ export function installWebRTCMocks() {
}; };
} }
export function makeMockGroupCallStateEvent(roomId: string, groupCallId: string): MatrixEvent { export function makeMockGroupCallStateEvent(roomId: string, groupCallId: string, content: IContent = {
"m.type": GroupCallType.Video,
"m.intent": GroupCallIntent.Prompt,
}): MatrixEvent {
return { return {
getType: jest.fn().mockReturnValue(EventType.GroupCallPrefix), getType: jest.fn().mockReturnValue(EventType.GroupCallPrefix),
getRoomId: jest.fn().mockReturnValue(roomId), getRoomId: jest.fn().mockReturnValue(roomId),
getTs: jest.fn().mockReturnValue(0), getTs: jest.fn().mockReturnValue(0),
getContent: jest.fn().mockReturnValue({ getContent: jest.fn().mockReturnValue(content),
"m.type": GroupCallType.Video,
"m.intent": GroupCallIntent.Prompt,
}),
getStateKey: jest.fn().mockReturnValue(groupCallId), getStateKey: jest.fn().mockReturnValue(groupCallId),
} as unknown as MatrixEvent; } as unknown as MatrixEvent;
} }

View File

@@ -14,8 +14,21 @@ See the License for the specific language governing permissions and
limitations under the License. limitations under the License.
*/ */
import { ClientEvent, GroupCall, Room, RoomState, RoomStateEvent } from "../../../src"; import { mocked } from "jest-mock";
import {
ClientEvent,
GroupCall,
GroupCallIntent,
GroupCallState,
GroupCallType,
IContent,
MatrixEvent,
Room,
RoomState,
} from "../../../src";
import { SyncState } from "../../../src/sync"; import { SyncState } from "../../../src/sync";
import { GroupCallTerminationReason } from "../../../src/webrtc/groupCall";
import { GroupCallEventHandler, GroupCallEventHandlerEvent } from "../../../src/webrtc/groupCallEventHandler"; import { GroupCallEventHandler, GroupCallEventHandlerEvent } from "../../../src/webrtc/groupCallEventHandler";
import { flushPromises } from "../../test-utils/flushPromises"; import { flushPromises } from "../../test-utils/flushPromises";
import { import {
@@ -53,6 +66,35 @@ describe('Group Call Event Handler', function() {
(mockClient as any).getRoom = jest.fn().mockReturnValue(mockRoom); (mockClient as any).getRoom = jest.fn().mockReturnValue(mockRoom);
}); });
describe("reacts to state changes", () => {
it("terminates call", async () => {
await groupCallEventHandler.start();
mockClient.emitRoomState(
makeMockGroupCallStateEvent(FAKE_ROOM_ID, FAKE_GROUP_CALL_ID),
{ roomId: FAKE_ROOM_ID } as unknown as RoomState,
);
const groupCall = groupCallEventHandler.groupCalls.get(FAKE_ROOM_ID);
expect(groupCall.state).toBe(GroupCallState.LocalCallFeedUninitialized);
mockClient.emitRoomState(
makeMockGroupCallStateEvent(
FAKE_ROOM_ID, FAKE_GROUP_CALL_ID, {
"m.type": GroupCallType.Video,
"m.intent": GroupCallIntent.Prompt,
"m.terminated": GroupCallTerminationReason.CallEnded,
},
),
{
roomId: FAKE_ROOM_ID,
} as unknown as RoomState,
);
expect(groupCall.state).toBe(GroupCallState.Ended);
});
});
it("waits until client starts syncing", async () => { it("waits until client starts syncing", async () => {
mockClient.getSyncState.mockReturnValue(null); mockClient.getSyncState.mockReturnValue(null);
let isStarted = false; let isStarted = false;
@@ -119,15 +161,13 @@ describe('Group Call Event Handler', function() {
mockClient.on(GroupCallEventHandlerEvent.Incoming, onIncomingGroupCall); mockClient.on(GroupCallEventHandlerEvent.Incoming, onIncomingGroupCall);
await groupCallEventHandler.start(); await groupCallEventHandler.start();
mockClient.emit( mockClient.emitRoomState(
RoomStateEvent.Events,
makeMockGroupCallStateEvent( makeMockGroupCallStateEvent(
FAKE_ROOM_ID, FAKE_GROUP_CALL_ID, FAKE_ROOM_ID, FAKE_GROUP_CALL_ID,
), ),
{ {
roomId: FAKE_ROOM_ID, roomId: FAKE_ROOM_ID,
} as unknown as RoomState, } as unknown as RoomState,
null,
); );
expect(onIncomingGroupCall).toHaveBeenCalledWith(expect.objectContaining({ expect(onIncomingGroupCall).toHaveBeenCalledWith(expect.objectContaining({
@@ -137,6 +177,40 @@ describe('Group Call Event Handler', function() {
mockClient.off(GroupCallEventHandlerEvent.Incoming, onIncomingGroupCall); mockClient.off(GroupCallEventHandlerEvent.Incoming, onIncomingGroupCall);
}); });
it("handles data channel", async () => {
await groupCallEventHandler.start();
const dataChannelOptions = {
"maxPacketLifeTime": "life_time",
"maxRetransmits": "retransmits",
"ordered": "ordered",
"protocol": "protocol",
};
mockClient.emitRoomState(
makeMockGroupCallStateEvent(
FAKE_ROOM_ID,
FAKE_GROUP_CALL_ID,
{
"m.type": GroupCallType.Video,
"m.intent": GroupCallIntent.Prompt,
"dataChannelsEnabled": true,
dataChannelOptions,
},
),
{
roomId: FAKE_ROOM_ID,
} as unknown as RoomState,
);
// @ts-ignore Mock dataChannelsEnabled is private
expect(groupCallEventHandler.groupCalls.get(FAKE_ROOM_ID)?.dataChannelsEnabled).toBe(true);
// @ts-ignore Mock dataChannelOptions is private
expect(groupCallEventHandler.groupCalls.get(FAKE_ROOM_ID)?.dataChannelOptions).toStrictEqual(
dataChannelOptions,
);
});
it("sends member events to group calls", async () => { it("sends member events to group calls", async () => {
await groupCallEventHandler.start(); await groupCallEventHandler.start();
@@ -148,15 +222,95 @@ describe('Group Call Event Handler', function() {
const mockStateEvent = makeMockGroupCallMemberStateEvent(FAKE_ROOM_ID, FAKE_GROUP_CALL_ID); const mockStateEvent = makeMockGroupCallMemberStateEvent(FAKE_ROOM_ID, FAKE_GROUP_CALL_ID);
mockClient.emit( mockClient.emitRoomState(
RoomStateEvent.Events,
mockStateEvent, mockStateEvent,
{ {
roomId: FAKE_ROOM_ID, roomId: FAKE_ROOM_ID,
} as unknown as RoomState, } as unknown as RoomState,
null,
); );
expect(mockGroupCall.onMemberStateChanged).toHaveBeenCalledWith(mockStateEvent); expect(mockGroupCall.onMemberStateChanged).toHaveBeenCalledWith(mockStateEvent);
}); });
describe("ignoring invalid group call state events", () => {
let mockClientEmit: jest.Func;
beforeEach(() => {
mockClientEmit = mockClient.emit = jest.fn();
});
afterEach(() => {
groupCallEventHandler.stop();
jest.clearAllMocks();
});
const setupCallAndStart = async (content?: IContent) => {
mocked(mockRoom.currentState.getStateEvents).mockReturnValue([
makeMockGroupCallStateEvent(
FAKE_ROOM_ID,
FAKE_GROUP_CALL_ID,
content,
),
] as unknown as MatrixEvent);
mockClient.getRooms.mockReturnValue([mockRoom]);
await groupCallEventHandler.start();
};
it("ignores terminated calls", async () => {
await setupCallAndStart({
"m.type": GroupCallType.Video,
"m.intent": GroupCallIntent.Prompt,
"m.terminated": GroupCallTerminationReason.CallEnded,
});
expect(mockClientEmit).not.toHaveBeenCalledWith(
GroupCallEventHandlerEvent.Incoming,
expect.objectContaining({
groupCallId: FAKE_GROUP_CALL_ID,
}),
);
});
it("ignores calls with invalid type", async () => {
await setupCallAndStart({
"m.type": "fake_type",
"m.intent": GroupCallIntent.Prompt,
});
expect(mockClientEmit).not.toHaveBeenCalledWith(
GroupCallEventHandlerEvent.Incoming,
expect.objectContaining({
groupCallId: FAKE_GROUP_CALL_ID,
}),
);
});
it("ignores calls with invalid intent", async () => {
await setupCallAndStart({
"m.type": GroupCallType.Video,
"m.intent": "fake_intent",
});
expect(mockClientEmit).not.toHaveBeenCalledWith(
GroupCallEventHandlerEvent.Incoming,
expect.objectContaining({
groupCallId: FAKE_GROUP_CALL_ID,
}),
);
});
it("ignores calls without a room", async () => {
mockClient.getRoom.mockReturnValue(undefined);
await setupCallAndStart();
expect(mockClientEmit).not.toHaveBeenCalledWith(
GroupCallEventHandlerEvent.Incoming,
expect.objectContaining({
groupCallId: FAKE_GROUP_CALL_ID,
}),
);
});
});
}); });