109 lines
3.2 KiB
JavaScript
109 lines
3.2 KiB
JavaScript
|
|
import { jest } from '@jest/globals';
|
||
|
|
import { ServerRecordingPeer } from '../../public/call/media/server-recording-peer.js';
|
||
|
|
|
||
|
|
function createTrack(kind, id) {
|
||
|
|
return {
|
||
|
|
kind,
|
||
|
|
id,
|
||
|
|
readyState: 'live'
|
||
|
|
};
|
||
|
|
}
|
||
|
|
|
||
|
|
function createStream(tracks) {
|
||
|
|
return {
|
||
|
|
getTracks() {
|
||
|
|
return tracks;
|
||
|
|
}
|
||
|
|
};
|
||
|
|
}
|
||
|
|
|
||
|
|
describe('ServerRecordingPeer', () => {
|
||
|
|
test('queues remote candidates until answer is applied', async () => {
|
||
|
|
const originalRTCPeerConnection = window.RTCPeerConnection;
|
||
|
|
const originalRTCSessionDescription = window.RTCSessionDescription;
|
||
|
|
const originalRTCIceCandidate = window.RTCIceCandidate;
|
||
|
|
class FakeRTCPeerConnection {
|
||
|
|
constructor() {
|
||
|
|
this.localDescription = null;
|
||
|
|
this.remoteDescription = null;
|
||
|
|
this.candidates = [];
|
||
|
|
}
|
||
|
|
|
||
|
|
addTransceiver() {}
|
||
|
|
|
||
|
|
async createOffer() {
|
||
|
|
return { type: 'offer', sdp: 'test-offer-sdp' };
|
||
|
|
}
|
||
|
|
|
||
|
|
async setLocalDescription(description) {
|
||
|
|
this.localDescription = description;
|
||
|
|
}
|
||
|
|
|
||
|
|
async setRemoteDescription(description) {
|
||
|
|
this.remoteDescription = description;
|
||
|
|
}
|
||
|
|
|
||
|
|
async addIceCandidate(candidate) {
|
||
|
|
if (!this.remoteDescription) {
|
||
|
|
throw new Error('remote description missing');
|
||
|
|
}
|
||
|
|
this.candidates.push(candidate);
|
||
|
|
}
|
||
|
|
|
||
|
|
close() {}
|
||
|
|
}
|
||
|
|
|
||
|
|
window.RTCPeerConnection = FakeRTCPeerConnection;
|
||
|
|
window.RTCSessionDescription = class {
|
||
|
|
constructor(init) {
|
||
|
|
Object.assign(this, init);
|
||
|
|
}
|
||
|
|
};
|
||
|
|
window.RTCIceCandidate = class {
|
||
|
|
constructor(init) {
|
||
|
|
Object.assign(this, init);
|
||
|
|
}
|
||
|
|
};
|
||
|
|
|
||
|
|
const signaling = {
|
||
|
|
sendRecordingOffer: jest.fn(),
|
||
|
|
sendRecordingCandidate: jest.fn()
|
||
|
|
};
|
||
|
|
const peer = new ServerRecordingPeer({
|
||
|
|
rtcConfiguration: {},
|
||
|
|
getLocalStream: () => createStream([createTrack('video', 'video-1')]),
|
||
|
|
getSignaling: () => signaling,
|
||
|
|
getConnectionId: () => 'room-1',
|
||
|
|
getParticipantId: () => 'participant-1'
|
||
|
|
});
|
||
|
|
|
||
|
|
await peer.start({
|
||
|
|
recordingId: 'recording-1',
|
||
|
|
connectionId: 'room-1'
|
||
|
|
});
|
||
|
|
|
||
|
|
await expect(peer.addIceCandidate({
|
||
|
|
recordingId: 'recording-1',
|
||
|
|
candidate: 'candidate:1',
|
||
|
|
sdpMid: '0',
|
||
|
|
sdpMLineIndex: 0
|
||
|
|
})).resolves.toBeUndefined();
|
||
|
|
|
||
|
|
const state = peer.peers.get('recording-1');
|
||
|
|
expect(state.pendingCandidates).toHaveLength(1);
|
||
|
|
expect(state.pc.candidates).toHaveLength(0);
|
||
|
|
|
||
|
|
await peer.applyAnswer({
|
||
|
|
recordingId: 'recording-1',
|
||
|
|
sdp: 'test-answer-sdp'
|
||
|
|
});
|
||
|
|
|
||
|
|
expect(state.pendingCandidates).toHaveLength(0);
|
||
|
|
expect(state.pc.candidates).toHaveLength(1);
|
||
|
|
|
||
|
|
window.RTCPeerConnection = originalRTCPeerConnection;
|
||
|
|
window.RTCSessionDescription = originalRTCSessionDescription;
|
||
|
|
window.RTCIceCandidate = originalRTCIceCandidate;
|
||
|
|
});
|
||
|
|
});
|