diff --git a/src/CallHandler.tsx b/src/CallHandler.tsx index 55c29c7a6f..733c9b8499 100644 --- a/src/CallHandler.tsx +++ b/src/CallHandler.tsx @@ -265,28 +265,43 @@ export default class CallHandler extends EventEmitter { return this.supportsSipNativeVirtual; } - public pstnLookup(phoneNumber: string): Promise { - return MatrixClientPeg.get().getThirdpartyUser( - this.pstnSupportPrefixed ? PROTOCOL_PSTN_PREFIXED : PROTOCOL_PSTN, { - 'm.id.phone': phoneNumber, - }, - ); + public async pstnLookup(phoneNumber: string): Promise { + try { + return await MatrixClientPeg.get().getThirdpartyUser( + this.pstnSupportPrefixed ? PROTOCOL_PSTN_PREFIXED : PROTOCOL_PSTN, { + 'm.id.phone': phoneNumber, + }, + ); + } catch (e) { + logger.warn('Failed to lookup user from phone number', e); + return Promise.resolve([]); + } } - public sipVirtualLookup(nativeMxid: string): Promise { - return MatrixClientPeg.get().getThirdpartyUser( - PROTOCOL_SIP_VIRTUAL, { - 'native_mxid': nativeMxid, - }, - ); + public async sipVirtualLookup(nativeMxid: string): Promise { + try { + return await MatrixClientPeg.get().getThirdpartyUser( + PROTOCOL_SIP_VIRTUAL, { + 'native_mxid': nativeMxid, + }, + ); + } catch (e) { + logger.warn('Failed to query SIP identity for user', e); + return Promise.resolve([]); + } } - public sipNativeLookup(virtualMxid: string): Promise { - return MatrixClientPeg.get().getThirdpartyUser( - PROTOCOL_SIP_NATIVE, { - 'virtual_mxid': virtualMxid, - }, - ); + public async sipNativeLookup(virtualMxid: string): Promise { + try { + return await MatrixClientPeg.get().getThirdpartyUser( + PROTOCOL_SIP_NATIVE, { + 'virtual_mxid': virtualMxid, + }, + ); + } catch (e) { + logger.warn('Failed to query identity for SIP user', e); + return Promise.resolve([]); + } } private onCallIncoming = (call: MatrixCall): void => { diff --git a/test/CallHandler-test.ts b/test/CallHandler-test.ts index 6a4f29aaa1..b7a047a9ef 100644 --- a/test/CallHandler-test.ts +++ b/test/CallHandler-test.ts @@ -79,7 +79,7 @@ class FakeCall extends EventEmitter { roomId: string; callId = "fake call id"; - constructor(roomId) { + constructor(roomId: string) { super(); this.roomId = roomId; @@ -104,14 +104,14 @@ function untilCallHandlerEvent(callHandler: CallHandler, event: CallHandlerEvent describe('CallHandler', () => { let dmRoomMap; let callHandler; - let audioElement; + let audioElement: HTMLAudioElement; let fakeCall; // what addresses the app has looked up via pstn and native lookup let pstnLookup: string; let nativeLookup: string; - beforeEach(() => { + beforeEach(async () => { stubClient(); MatrixClientPeg.get().createCall = roomId => { if (fakeCall && fakeCall.roomId !== roomId) { @@ -151,7 +151,7 @@ describe('CallHandler', () => { }; dmRoomMap = { - getUserIdForRoomId: roomId => { + getUserIdForRoomId: (roomId: string) => { if (roomId === NATIVE_ROOM_ALICE) { return NATIVE_ALICE; } else if (roomId === NATIVE_ROOM_BOB) { @@ -164,7 +164,7 @@ describe('CallHandler', () => { return null; } }, - getDMRoomsForUserId: userId => { + getDMRoomsForUserId: (userId: string) => { if (userId === NATIVE_ALICE) { return [NATIVE_ROOM_ALICE]; } else if (userId === NATIVE_BOB) { @@ -322,3 +322,88 @@ describe('CallHandler', () => { expect(callHandler.getCallForRoom(NATIVE_ROOM_CHARLIE)).toBe(fakeCall); }); }); + +describe('CallHandler without third party protocols', () => { + let dmRoomMap; + let callHandler: CallHandler; + let audioElement: HTMLAudioElement; + let fakeCall; + + beforeEach(() => { + stubClient(); + MatrixClientPeg.get().createCall = roomId => { + if (fakeCall && fakeCall.roomId !== roomId) { + throw new Error("Only one call is supported!"); + } + fakeCall = new FakeCall(roomId); + return fakeCall; + }; + + MatrixClientPeg.get().getThirdpartyProtocols = () => { + throw new Error("Endpoint unsupported."); + }; + + callHandler = new CallHandler(); + callHandler.start(); + + const nativeRoomAlice = mkStubDM(NATIVE_ROOM_ALICE, NATIVE_ALICE); + + MatrixClientPeg.get().getRoom = roomId => { + switch (roomId) { + case NATIVE_ROOM_ALICE: + return nativeRoomAlice; + } + }; + + dmRoomMap = { + getUserIdForRoomId: (roomId: string) => { + if (roomId === NATIVE_ROOM_ALICE) { + return NATIVE_ALICE; + } else { + return null; + } + }, + getDMRoomsForUserId: (userId: string) => { + if (userId === NATIVE_ALICE) { + return [NATIVE_ROOM_ALICE]; + } else { + return []; + } + }, + }; + DMRoomMap.setShared(dmRoomMap); + + MatrixClientPeg.get().getThirdpartyUser = (_proto, _params) => { + throw new Error("Endpoint unsupported."); + }; + + audioElement = document.createElement('audio'); + audioElement.id = "remoteAudio"; + document.body.appendChild(audioElement); + }); + + afterEach(() => { + callHandler.stop(); + DMRoomMap.setShared(null); + // @ts-ignore + window.mxCallHandler = null; + fakeCall = null; + MatrixClientPeg.unset(); + + document.body.removeChild(audioElement); + SdkConfig.unset(); + }); + + it('should still start a native call', async () => { + callHandler.placeCall(NATIVE_ROOM_ALICE, CallType.Voice); + + await untilCallHandlerEvent(callHandler, CallHandlerEvent.CallState); + + // Check that a call was started: its room on the protocol level + // should be the virtual room + expect(fakeCall.roomId).toEqual(NATIVE_ROOM_ALICE); + + // but it should appear to the user to be in thw native room for Bob + expect(callHandler.roomIdForCall(fakeCall)).toEqual(NATIVE_ROOM_ALICE); + }); +});