diff --git a/src/mocks/rtc-peer-connection-stub.ts b/src/mocks/rtc-peer-connection-stub.ts index a34124f..a26da42 100644 --- a/src/mocks/rtc-peer-connection-stub.ts +++ b/src/mocks/rtc-peer-connection-stub.ts @@ -13,7 +13,15 @@ class RTCPeerConnectionStub { getStats(): Promise { return new Promise(() => {}); } - setLocalDescription(): Promise { + setLocalDescription( + description?: RTCSessionDescription | RTCSessionDescriptionInit + ): Promise { + return new Promise(() => {}); + } + + setRemoteDescription( + description?: RTCSessionDescription | RTCSessionDescriptionInit + ): Promise { return new Promise(() => {}); } onconnectionstatechange: () => void = () => {}; diff --git a/src/peer-connection.spec.ts b/src/peer-connection.spec.ts index f061166..d0387f8 100644 --- a/src/peer-connection.spec.ts +++ b/src/peer-connection.spec.ts @@ -1,4 +1,5 @@ import { BrowserInfo } from '@webex/web-capabilities'; +import { MockedObjectDeep } from 'ts-jest'; import { ConnectionState, ConnectionStateHandler } from './connection-state-handler'; import { mocked } from './mocks/mock'; import { RTCPeerConnectionStub } from './mocks/rtc-peer-connection-stub'; @@ -247,17 +248,76 @@ describe('PeerConnection', () => { }); }); + describe('createOffer', () => { + let mockPc: MockedObjectDeep; + let createOfferSpy: jest.SpyInstance; + const callback = jest.fn(); + let pc: PeerConnection; + const mockedReturnedOffer: RTCSessionDescriptionInit = { + sdp: 'blah', + type: 'offer', + }; + + beforeEach(() => { + jest.clearAllMocks(); + mockPc = mocked(new RTCPeerConnectionStub(), true); + mockPc.createOffer.mockImplementation((description) => { + return new Promise((resolve, reject) => { + if (!description) { + reject(new Error()); + } else { + resolve(mockedReturnedOffer); + } + }); + }); + mockCreateRTCPeerConnection.mockReturnValueOnce(mockPc as unknown as RTCPeerConnection); + pc = new PeerConnection(); + createOfferSpy = jest.spyOn(pc, 'createOffer'); + pc.on(PeerConnection.Events.CreateOffer, callback); + }); + + it('should emit event when createOffer called', async () => { + expect.hasAssertions(); + const options: RTCOfferOptions = { + iceRestart: true, + }; + const offer = await pc.createOffer(options); + expect(offer).toStrictEqual(mockedReturnedOffer); + expect(createOfferSpy).toHaveBeenCalledWith(options); + expect(callback).toHaveBeenCalledWith(mockedReturnedOffer); + }); + + it('should not emit event when createOffer failed', async () => { + expect.hasAssertions(); + const offerPromise = pc.createOffer(null as unknown as RTCOfferOptions); + await expect(offerPromise).rejects.toThrow(Error); + expect(createOfferSpy).toHaveBeenCalledWith(null); + expect(callback).toHaveBeenCalledTimes(0); + }); + }); + describe('setLocalDescription', () => { - let mockPc: RTCPeerConnectionStub; + let mockPc: MockedObjectDeep; let setLocalDescriptionSpy: jest.SpyInstance; + const callback = jest.fn(); let pc: PeerConnection; beforeEach(() => { jest.clearAllMocks(); mockPc = mocked(new RTCPeerConnectionStub(), true); mockCreateRTCPeerConnection.mockReturnValueOnce(mockPc as unknown as RTCPeerConnection); + mockPc.setLocalDescription.mockImplementation((description) => { + return new Promise((resolve, reject) => { + if (description?.sdp === 'reject') { + reject(new Error()); + } else { + resolve(); + } + }); + }); setLocalDescriptionSpy = jest.spyOn(mockPc, 'setLocalDescription'); pc = new PeerConnection(); + pc.on(PeerConnection.Events.SetLocalDescription, callback); }); it('sets the local description with an SDP offer', async () => { @@ -278,5 +338,72 @@ describe('PeerConnection', () => { pc.setLocalDescription({ type: 'offer', sdp: 'm=video 9 UDP/TLS/RTP' }) ).rejects.toThrow(Error); }); + + it('should emit event when setLocalDescription called', async () => { + expect.hasAssertions(); + const options = { + sdp: 'blah', + }; + await pc.setLocalDescription(options as unknown as RTCSessionDescriptionInit); + expect(setLocalDescriptionSpy).toHaveBeenCalledWith(options); + expect(callback).toHaveBeenCalledWith(options); + }); + + it('should not emit event when setLocalDescription failed', async () => { + expect.hasAssertions(); + const options = { + sdp: 'reject', + }; + const offerPromise = pc.setLocalDescription(options as unknown as RTCSessionDescriptionInit); + await expect(offerPromise).rejects.toThrow(Error); + expect(setLocalDescriptionSpy).toHaveBeenCalledWith(options); + expect(callback).toHaveBeenCalledTimes(0); + }); + }); + + describe('setRemoteDescription', () => { + let mockPc: MockedObjectDeep; + let setRemoteDescriptionSpy: jest.SpyInstance; + const callback = jest.fn(); + let pc: PeerConnection; + + beforeEach(() => { + jest.clearAllMocks(); + mockPc = mocked(new RTCPeerConnectionStub(), true); + mockPc.setRemoteDescription.mockImplementation((description) => { + return new Promise((resolve, reject) => { + if (description?.sdp === 'reject') { + reject(new Error()); + } else { + resolve(); + } + }); + }); + mockCreateRTCPeerConnection.mockReturnValueOnce(mockPc as unknown as RTCPeerConnection); + pc = new PeerConnection(); + setRemoteDescriptionSpy = jest.spyOn(pc, 'setRemoteDescription'); + pc.on(PeerConnection.Events.SetRemoteDescription, callback); + }); + + it('should emit event when setRemoteDescription called', async () => { + expect.hasAssertions(); + const options = { + sdp: 'blah', + }; + await pc.setRemoteDescription(options as unknown as RTCSessionDescriptionInit); + expect(setRemoteDescriptionSpy).toHaveBeenCalledWith(options); + expect(callback).toHaveBeenCalledWith(options); + }); + + it('should not emit event when setRemoteDescription failed', async () => { + expect.hasAssertions(); + const options = { + sdp: 'reject', + }; + const offerPromise = pc.setRemoteDescription(options as unknown as RTCSessionDescriptionInit); + await expect(offerPromise).rejects.toThrow(Error); + expect(setRemoteDescriptionSpy).toHaveBeenCalledWith(options); + expect(callback).toHaveBeenCalledTimes(0); + }); }); });