You've already forked matrix-js-sdk
mirror of
https://github.com/matrix-org/matrix-js-sdk.git
synced 2025-07-31 15:24:23 +03:00
Test fallback screensharing (#2659)
* Test fallback screensharing * Test replacetrack is called * Unused import * Return type * Fix other test after new track IDs
This commit is contained in:
@ -104,13 +104,18 @@ export class MockRTCPeerConnection {
|
|||||||
private onReadyToNegotiate: () => void;
|
private onReadyToNegotiate: () => void;
|
||||||
localDescription: RTCSessionDescription;
|
localDescription: RTCSessionDescription;
|
||||||
signalingState: RTCSignalingState = "stable";
|
signalingState: RTCSignalingState = "stable";
|
||||||
|
public senders: MockRTCRtpSender[] = [];
|
||||||
|
|
||||||
public static triggerAllNegotiations() {
|
public static triggerAllNegotiations(): void {
|
||||||
for (const inst of this.instances) {
|
for (const inst of this.instances) {
|
||||||
inst.doNegotiation();
|
inst.doNegotiation();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static hasAnyPendingNegotiations(): boolean {
|
||||||
|
return this.instances.some(i => i.needsNegotiation);
|
||||||
|
}
|
||||||
|
|
||||||
public static resetInstances() {
|
public static resetInstances() {
|
||||||
this.instances = [];
|
this.instances = [];
|
||||||
}
|
}
|
||||||
@ -153,10 +158,12 @@ export class MockRTCPeerConnection {
|
|||||||
}
|
}
|
||||||
close() { }
|
close() { }
|
||||||
getStats() { return []; }
|
getStats() { return []; }
|
||||||
addTrack(track: MockMediaStreamTrack) {
|
addTrack(track: MockMediaStreamTrack): MockRTCRtpSender {
|
||||||
this.needsNegotiation = true;
|
this.needsNegotiation = true;
|
||||||
this.onReadyToNegotiate();
|
this.onReadyToNegotiate();
|
||||||
return new MockRTCRtpSender(track);
|
const newSender = new MockRTCRtpSender(track);
|
||||||
|
this.senders.push(newSender);
|
||||||
|
return newSender;
|
||||||
}
|
}
|
||||||
|
|
||||||
removeTrack() {
|
removeTrack() {
|
||||||
@ -164,6 +171,8 @@ export class MockRTCPeerConnection {
|
|||||||
this.onReadyToNegotiate();
|
this.onReadyToNegotiate();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
getSenders(): MockRTCRtpSender[] { return this.senders; }
|
||||||
|
|
||||||
doNegotiation() {
|
doNegotiation() {
|
||||||
if (this.needsNegotiation && this.negotiationNeededListener) {
|
if (this.needsNegotiation && this.negotiationNeededListener) {
|
||||||
this.needsNegotiation = false;
|
this.needsNegotiation = false;
|
||||||
@ -271,8 +280,8 @@ export class MockMediaHandler {
|
|||||||
|
|
||||||
getUserMediaStream(audio: boolean, video: boolean) {
|
getUserMediaStream(audio: boolean, video: boolean) {
|
||||||
const tracks = [];
|
const tracks = [];
|
||||||
if (audio) tracks.push(new MockMediaStreamTrack("audio_track", "audio"));
|
if (audio) tracks.push(new MockMediaStreamTrack("usermedia_audio_track", "audio"));
|
||||||
if (video) tracks.push(new MockMediaStreamTrack("video_track", "video"));
|
if (video) tracks.push(new MockMediaStreamTrack("usermedia_video_track", "video"));
|
||||||
|
|
||||||
const stream = new MockMediaStream(USERMEDIA_STREAM_ID, tracks);
|
const stream = new MockMediaStream(USERMEDIA_STREAM_ID, tracks);
|
||||||
this.userMediaStreams.push(stream);
|
this.userMediaStreams.push(stream);
|
||||||
@ -282,8 +291,8 @@ export class MockMediaHandler {
|
|||||||
stream.isStopped = true;
|
stream.isStopped = true;
|
||||||
}
|
}
|
||||||
getScreensharingStream = jest.fn((opts?: IScreensharingOpts) => {
|
getScreensharingStream = jest.fn((opts?: IScreensharingOpts) => {
|
||||||
const tracks = [new MockMediaStreamTrack("video_track", "video")];
|
const tracks = [new MockMediaStreamTrack("screenshare_video_track", "video")];
|
||||||
if (opts?.audio) tracks.push(new MockMediaStreamTrack("audio_track", "audio"));
|
if (opts?.audio) tracks.push(new MockMediaStreamTrack("screenshare_audio_track", "audio"));
|
||||||
|
|
||||||
const stream = new MockMediaStream(SCREENSHARE_STREAM_ID, tracks);
|
const stream = new MockMediaStream(SCREENSHARE_STREAM_ID, tracks);
|
||||||
this.screensharingStreams.push(stream);
|
this.screensharingStreams.push(stream);
|
||||||
|
@ -389,14 +389,14 @@ describe('Call', function() {
|
|||||||
|
|
||||||
const usermediaSenders: Array<RTCRtpSender> = (call as any).usermediaSenders;
|
const usermediaSenders: Array<RTCRtpSender> = (call as any).usermediaSenders;
|
||||||
|
|
||||||
expect(call.localUsermediaStream.getAudioTracks()[0].id).toBe("audio_track");
|
expect(call.localUsermediaStream.getAudioTracks()[0].id).toBe("usermedia_audio_track");
|
||||||
expect(call.localUsermediaStream.getVideoTracks()[0].id).toBe("video_track");
|
expect(call.localUsermediaStream.getVideoTracks()[0].id).toBe("usermedia_video_track");
|
||||||
expect(usermediaSenders.find((sender) => {
|
expect(usermediaSenders.find((sender) => {
|
||||||
return sender?.track?.kind === "audio";
|
return sender?.track?.kind === "audio";
|
||||||
}).track.id).toBe("audio_track");
|
}).track.id).toBe("usermedia_audio_track");
|
||||||
expect(usermediaSenders.find((sender) => {
|
expect(usermediaSenders.find((sender) => {
|
||||||
return sender?.track?.kind === "video";
|
return sender?.track?.kind === "video";
|
||||||
}).track.id).toBe("video_track");
|
}).track.id).toBe("usermedia_video_track");
|
||||||
});
|
});
|
||||||
|
|
||||||
it("should handle SDPStreamMetadata changes", async () => {
|
it("should handle SDPStreamMetadata changes", async () => {
|
||||||
@ -925,8 +925,8 @@ describe('Call', function() {
|
|||||||
await call.setScreensharingEnabled(true);
|
await call.setScreensharingEnabled(true);
|
||||||
|
|
||||||
expect(
|
expect(
|
||||||
call.getLocalFeeds().filter(f => f.purpose == SDPStreamMetadataPurpose.Screenshare).length,
|
call.getLocalFeeds().filter(f => f.purpose == SDPStreamMetadataPurpose.Screenshare),
|
||||||
).toEqual(1);
|
).toHaveLength(1);
|
||||||
|
|
||||||
mockSendEvent.mockReset();
|
mockSendEvent.mockReset();
|
||||||
const sendNegotiatePromise = new Promise<void>(resolve => {
|
const sendNegotiatePromise = new Promise<void>(resolve => {
|
||||||
@ -955,8 +955,54 @@ describe('Call', function() {
|
|||||||
await call.setScreensharingEnabled(false);
|
await call.setScreensharingEnabled(false);
|
||||||
|
|
||||||
expect(
|
expect(
|
||||||
call.getLocalFeeds().filter(f => f.purpose == SDPStreamMetadataPurpose.Screenshare).length,
|
call.getLocalFeeds().filter(f => f.purpose == SDPStreamMetadataPurpose.Screenshare),
|
||||||
).toEqual(0);
|
).toHaveLength(0);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it("falls back to replaceTrack for opponents that don't support stream metadata", async () => {
|
||||||
|
await startVideoCall(client, call);
|
||||||
|
|
||||||
|
await call.onAnswerReceived(makeMockEvent("@test:foo", {
|
||||||
|
"version": 1,
|
||||||
|
"call_id": call.callId,
|
||||||
|
"party_id": 'party_id',
|
||||||
|
"answer": {
|
||||||
|
sdp: DUMMY_SDP,
|
||||||
|
},
|
||||||
|
}));
|
||||||
|
|
||||||
|
MockRTCPeerConnection.triggerAllNegotiations();
|
||||||
|
|
||||||
|
const mockVideoSender = call.peerConn.getSenders().find(s => s.track.kind === "video");
|
||||||
|
const mockReplaceTrack = mockVideoSender.replaceTrack = jest.fn();
|
||||||
|
|
||||||
|
await call.setScreensharingEnabled(true);
|
||||||
|
|
||||||
|
// our local feed should still reflect the purpose of the feed (ie. screenshare)
|
||||||
|
expect(
|
||||||
|
call.getLocalFeeds().filter(f => f.purpose == SDPStreamMetadataPurpose.Screenshare).length,
|
||||||
|
).toEqual(1);
|
||||||
|
|
||||||
|
// but we should not have re-negotiated
|
||||||
|
expect(MockRTCPeerConnection.hasAnyPendingNegotiations()).toEqual(false);
|
||||||
|
|
||||||
|
expect(mockReplaceTrack).toHaveBeenCalledWith(expect.objectContaining({
|
||||||
|
id: "screenshare_video_track",
|
||||||
|
}));
|
||||||
|
mockReplaceTrack.mockClear();
|
||||||
|
|
||||||
|
await call.setScreensharingEnabled(false);
|
||||||
|
|
||||||
|
expect(
|
||||||
|
call.getLocalFeeds().filter(f => f.purpose == SDPStreamMetadataPurpose.Screenshare),
|
||||||
|
).toHaveLength(0);
|
||||||
|
expect(call.getLocalFeeds()).toHaveLength(1);
|
||||||
|
|
||||||
|
expect(MockRTCPeerConnection.hasAnyPendingNegotiations()).toEqual(false);
|
||||||
|
|
||||||
|
expect(mockReplaceTrack).toHaveBeenCalledWith(expect.objectContaining({
|
||||||
|
id: "usermedia_video_track",
|
||||||
|
}));
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
Reference in New Issue
Block a user