Skip to content

Commit

Permalink
fix: add unit test to cover this imported changes and extend the impl…
Browse files Browse the repository at this point in the history
…ementation.
  • Loading branch information
EnricoSchw committed Jan 20, 2025
1 parent d67e0d0 commit 0055d71
Show file tree
Hide file tree
Showing 2 changed files with 125 additions and 4 deletions.
112 changes: 110 additions & 2 deletions src/script/calling/CallingRepository.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,16 +18,16 @@
*/

import {
ConversationProtocol,
CONVERSATION_TYPE,
ConversationProtocol,
DefaultConversationRoleName,
} from '@wireapp/api-client/lib/conversation';
import {QualifiedId} from '@wireapp/api-client/lib/user';
import 'jsdom-worker';
import ko, {Subscription} from 'knockout';
import {container} from 'tsyringe';

import {CONV_TYPE, CALL_TYPE, STATE as CALL_STATE, REASON, Wcall} from '@wireapp/avs';
import {CALL_TYPE, CONV_TYPE, REASON, STATE as CALL_STATE, VIDEO_STATE, Wcall} from '@wireapp/avs';
import {Runtime} from '@wireapp/commons';

import {Call} from 'src/script/calling/Call';
Expand Down Expand Up @@ -520,6 +520,114 @@ describe('CallingRepository', () => {
expect(selfParticipant.releaseVideoStream).toHaveBeenCalledTimes(1);
});
});

describe('camera', () => {
let selfParticipant: Participant;
let conv: Conversation;
let call: Call;
beforeEach(() => {
selfParticipant = createSelfParticipant();
conv = createConversation();
call = new Call(
{domain: '', id: ''},
conv,
CONV_TYPE.CONFERENCE,
selfParticipant,
CALL_TYPE.NORMAL,
buildMediaDevicesHandler(),
);
});

describe('on incoming call', () => {
it('toggle on', async () => {
selfParticipant.videoState(VIDEO_STATE.STOPPED);
spyOn(selfParticipant, 'releaseVideoStream');
spyOn(wCall, 'setVideoSendState');
call.state(CALL_STATE.INCOMING);
callingRepository.toggleCamera(call);
expect(selfParticipant.releaseVideoStream).toHaveBeenCalledTimes(0);
expect(wCall.setVideoSendState).toHaveBeenCalledWith(wUser, conv.id, VIDEO_STATE.STARTED);
});

it('toggle off', async () => {
selfParticipant.videoState(VIDEO_STATE.STARTED);
spyOn(selfParticipant, 'releaseVideoStream');
spyOn(wCall, 'setVideoSendState');
call.state(CALL_STATE.INCOMING);
callingRepository.toggleCamera(call);

expect(selfParticipant.releaseVideoStream).toHaveBeenCalledTimes(1);
expect(wCall.setVideoSendState).toHaveBeenCalledWith(wUser, conv.id, VIDEO_STATE.STOPPED);
});
});

describe('on running call', () => {
it('toggle on', async () => {
selfParticipant.videoState(VIDEO_STATE.STOPPED);
spyOn(selfParticipant, 'releaseVideoStream');
spyOn(wCall, 'setVideoSendState');
call.state(CALL_STATE.MEDIA_ESTAB);
callingRepository.toggleCamera(call);
expect(selfParticipant.releaseVideoStream).toHaveBeenCalledTimes(0);
expect(wCall.setVideoSendState).toHaveBeenCalledWith(wUser, conv.id, VIDEO_STATE.STARTED);
});

it('toggle off', async () => {
selfParticipant.videoState(VIDEO_STATE.STARTED);
spyOn(selfParticipant, 'releaseVideoStream');
spyOn(wCall, 'setVideoSendState');
call.state(CALL_STATE.MEDIA_ESTAB);
callingRepository.toggleCamera(call);

expect(selfParticipant.releaseVideoStream).toHaveBeenCalledTimes(1);
expect(wCall.setVideoSendState).toHaveBeenCalledWith(wUser, conv.id, VIDEO_STATE.STOPPED);
});

// This is an edge case. You can toggleCamera on when you have screen share enabled!
it('toggle on when screen shared', async () => {
selfParticipant.videoState(VIDEO_STATE.SCREENSHARE);
spyOn(selfParticipant, 'releaseVideoStream');
spyOn(wCall, 'setVideoSendState');
call.state(CALL_STATE.MEDIA_ESTAB);
callingRepository.toggleCamera(call);
expect(selfParticipant.releaseVideoStream).toHaveBeenCalledTimes(0);
expect(wCall.setVideoSendState).toHaveBeenCalledWith(wUser, conv.id, VIDEO_STATE.STARTED);
});
});

describe('on not supported call state', () => {
it('ANSWERED, toggle will be failing', async () => {
selfParticipant.videoState(VIDEO_STATE.STOPPED);
call.state(CALL_STATE.ANSWERED);
expect(() => callingRepository.toggleCamera(call)).toThrow('invalid call state in `toggleCamera`');
});
it('NONE, toggle will be failing', async () => {
selfParticipant.videoState(VIDEO_STATE.STOPPED);
call.state(CALL_STATE.NONE);
expect(() => callingRepository.toggleCamera(call)).toThrow('invalid call state in `toggleCamera`');
});
it('UNKNOWN, toggle will be failing', async () => {
selfParticipant.videoState(VIDEO_STATE.STOPPED);
call.state(CALL_STATE.UNKNOWN);
expect(() => callingRepository.toggleCamera(call)).toThrow('invalid call state in `toggleCamera`');
});
it('OUTGOING, toggle will be failing', async () => {
selfParticipant.videoState(VIDEO_STATE.STOPPED);
call.state(CALL_STATE.OUTGOING);
expect(() => callingRepository.toggleCamera(call)).toThrow('invalid call state in `toggleCamera`');
});
it('TERM_LOCAL, toggle will be failing', async () => {
selfParticipant.videoState(VIDEO_STATE.STOPPED);
call.state(CALL_STATE.TERM_LOCAL);
expect(() => callingRepository.toggleCamera(call)).toThrow('invalid call state in `toggleCamera`');
});
it('TERM_REMOTE, toggle will be failing', async () => {
selfParticipant.videoState(VIDEO_STATE.STOPPED);
call.state(CALL_STATE.TERM_REMOTE);
expect(() => callingRepository.toggleCamera(call)).toThrow('invalid call state in `toggleCamera`');
});
});
});
});

describe('CallingRepository ISO', () => {
Expand Down
17 changes: 15 additions & 2 deletions src/script/calling/CallingRepository.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1039,17 +1039,30 @@ export class CallingRepository {
toggleCamera(call: Call): void {
const selfParticipant = call.getSelfParticipant();
const newState = selfParticipant.sharesCamera() ? VIDEO_STATE.STOPPED : VIDEO_STATE.STARTED;
if (call.state() === CALL_STATE.INCOMING) {
const callState = call.state();
if (callState === CALL_STATE.INCOMING) {
selfParticipant.videoState(newState);
if (newState === VIDEO_STATE.STOPPED) {
selfParticipant.releaseVideoStream(true);
} else {
this.warmupMediaStreams(call, false, true);
}
} else if (call.state() === CALL_STATE.MEDIA_ESTAB && !selfParticipant.sharesScreen()) {
} else if (
callState === CALL_STATE.MEDIA_ESTAB &&
newState === VIDEO_STATE.STOPPED &&
// This condition is to be safe. This should not happen because: `newState === VIDEO_STATE.STARTED` when
// participant doing screen share!
!selfParticipant.sharesScreen()
) {
selfParticipant.releaseVideoStream(true);
}

if (callState !== CALL_STATE.MEDIA_ESTAB && callState !== CALL_STATE.INCOMING) {
// Toggle Camera should not be available in any other call state for this reason we make an exception for the
// case that someone wants to access the camera outside a call!
throw new Error('invalid call state in `toggleCamera`');
}

this.wCall?.setVideoSendState(this.wUser, this.serializeQualifiedId(call.conversation.qualifiedId), newState);
}

Expand Down

0 comments on commit 0055d71

Please sign in to comment.