mattermost-mobile/app/products/calls/state/actions.test.ts
Daniel Espino García af0a7525c8
Refactor Open Profile (#8746)
* Refactor Open Profile

* Add missing changes

* Fix tests

* Fix tests

* Address feedback
2025-05-13 17:07:13 +02:00

1707 lines
63 KiB
TypeScript

// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
// See LICENSE.txt for license information.
/* eslint-disable max-lines */
import assert from 'assert';
import {act, renderHook} from '@testing-library/react-hooks'; // Use instead of react-native version due to different behavior. Consider migrating
import {AppState} from 'react-native';
import {needsRecordingAlert} from '@calls/alerts';
import {
newCurrentCall,
processIncomingCalls,
processMeanOpinionScore,
receivedCaption,
removeIncomingCall,
setAudioDeviceInfo,
setCallQualityAlertDismissed,
setCallsConfig,
setCallsState,
setChannelsWithCalls,
setCurrentCall,
setHost,
setIncomingCalls,
setJoiningChannelId,
setMicPermissionsErrorDismissed,
setMicPermissionsGranted,
setRecordingState,
useCallsConfig,
useCallsState,
useChannelsWithCalls,
useCurrentCall,
useGlobalCallsState,
useIncomingCalls,
userReacted,
setCallForChannel,
} from '@calls/state';
import {
callEnded,
callStarted,
myselfLeftCall,
setCalls,
setCallScreenOff,
setCallScreenOn,
setChannelEnabled,
setConfig,
setPluginEnabled,
setRaisedHand,
setScreenShareURL,
setSpeakerPhone,
setUserMuted,
setUserVoiceOn,
userJoinedCall,
userLeftCall,
callsOnAppStateChange,
playIncomingCallsRinging,
} from '@calls/state/actions';
import {
AudioDevice,
type Call,
type CallsState,
type CurrentCall,
DefaultCallsConfig,
DefaultCallsState,
DefaultCurrentCall,
DefaultGlobalCallsState,
DefaultIncomingCalls,
type GlobalCallsState,
type IncomingCalls,
} from '@calls/types/calls';
import {License} from '@constants';
import Calls from '@constants/calls';
import DatabaseManager from '@database/manager';
import {getUserById} from '@queries/servers/user';
import TestHelper from '@test/test_helper';
import type {CallJobState, LiveCaptionData} from '@mattermost/calls/lib/types';
jest.mock('@calls/alerts');
jest.mock('@constants/calls', () => ({
...jest.requireActual('@constants/calls'),
CALL_QUALITY_RESET_MS: 100,
}));
jest.mock('@actions/remote/thread', () => ({
updateThreadFollowing: jest.fn(() => Promise.resolve({})),
}));
jest.mock('@queries/servers/thread', () => ({
getThreadById: jest.fn(() => Promise.resolve({
isFollowing: false,
})),
}));
jest.mock('@queries/servers/channel', () => ({
getChannelById: jest.fn(() => Promise.resolve({
type: 'D',
})),
}));
jest.mock('@queries/servers/user', () => ({
getUserById: jest.fn(),
getCurrentUser: jest.fn(),
}));
const user5 = TestHelper.fakeUserModel({username: 'user-5'});
jest.mocked(getUserById).mockResolvedValue(user5);
jest.mock('react-native-navigation', () => ({
Navigation: {
pop: jest.fn(() => Promise.resolve({
catch: jest.fn(),
})),
setDefaultOptions: jest.fn(),
},
}));
const call1: Call = {
id: 'call1',
sessions: {
session1: {sessionId: 'session1', userId: 'user-1', muted: false, raisedHand: 0},
session2: {sessionId: 'session2', userId: 'user-2', muted: true, raisedHand: 0},
},
channelId: 'channel-1',
startTime: 123,
screenOn: '',
threadId: 'thread-1',
ownerId: 'user-1',
hostId: 'user-1',
dismissed: {},
};
const call2: Call = {
id: 'call2',
sessions: {
session3: {sessionId: 'session3', userId: 'user-3', muted: false, raisedHand: 0},
session4: {sessionId: 'session4', userId: 'user-4', muted: true, raisedHand: 0},
},
channelId: 'channel-2',
startTime: 123,
screenOn: '',
threadId: 'thread-2',
ownerId: 'user-3',
hostId: 'user-3',
dismissed: {},
};
const call3: Call = {
id: 'call3',
sessions: {
session5: {sessionId: 'session5', userId: 'user-5', muted: false, raisedHand: 0},
session6: {sessionId: 'session6', userId: 'user-6', muted: true, raisedHand: 0},
},
channelId: 'channel-3',
startTime: 123,
screenOn: '',
threadId: 'thread-3',
ownerId: 'user-5',
hostId: 'user-5',
dismissed: {},
};
const callDM: Call = {
id: 'callDM',
sessions: {
session5: {sessionId: 'session5', userId: 'user-5', muted: false, raisedHand: 0},
},
channelId: 'channel-private',
startTime: 123,
screenOn: '',
threadId: 'thread-4',
ownerId: 'user-5',
hostId: 'user-5',
dismissed: {},
};
describe('useCallsState', () => {
const {updateThreadFollowing} = require('@actions/remote/thread');
beforeAll(() => {
// create subjects
const {result} = renderHook(() => {
return [useCallsState('server1'), useChannelsWithCalls('server1'), useCurrentCall()];
});
assert.deepEqual(result.current[0], DefaultCallsState);
assert.deepEqual(result.current[1], {});
assert.deepEqual(result.current[2], null);
});
beforeEach(() => {
// reset to default state for each test
updateThreadFollowing.mockClear();
act(() => {
setCallsState('server1', DefaultCallsState);
setChannelsWithCalls('server1', {});
setCurrentCall(null);
});
});
it('default state', () => {
const {result} = renderHook(() => {
return [useCallsState('server1'), useChannelsWithCalls('server1')];
});
assert.deepEqual(result.current[0], DefaultCallsState);
assert.deepEqual(result.current[1], {});
});
it('setCalls, two callsState hooks, channelsWithCalls hook, ', async () => {
const initialCallsState = {
...DefaultCallsState,
calls: {'channel-1': call1},
enabled: {'channel-1': true},
};
const initialChannelsWithCallsState = {
'channel-1': true,
};
const initialCurrentCallState: CurrentCall = {
...DefaultCurrentCall,
serverUrl: 'server1',
myUserId: 'myUserId',
...call1,
};
const testNewCall1 = {
...call1,
sessions: {
session1: {sessionId: 'session1', userId: 'user-1', muted: false, raisedHand: 0},
session2: {sessionId: 'session2', userId: 'user-2', muted: true, raisedHand: 0},
session3: {sessionId: 'session3', userId: 'user-3', muted: false, raisedHand: 123},
},
};
const test = {
calls: {'channel-1': testNewCall1, 'channel-2': call2, 'channel-3': call3},
enabled: {'channel-2': true},
};
const expectedCallsState = {
...initialCallsState,
myUserId: 'myId',
calls: {'channel-1': testNewCall1, 'channel-2': call2, 'channel-3': call3},
enabled: {'channel-2': true},
};
const expectedChannelsWithCallsState = {
...initialChannelsWithCallsState,
'channel-2': true,
'channel-3': true,
};
const expectedCurrentCallState = {
...initialCurrentCallState,
...testNewCall1,
};
// setup
const {result} = renderHook(() => {
return [
useCallsState('server1'),
useCallsState('server1'),
useChannelsWithCalls('server1'),
useCurrentCall(),
];
});
act(() => {
setCallsState('server1', initialCallsState);
setChannelsWithCalls('server1', initialChannelsWithCallsState);
setCurrentCall(initialCurrentCallState);
});
assert.deepEqual(result.current[0], initialCallsState);
assert.deepEqual(result.current[1], initialCallsState);
assert.deepEqual(result.current[2], initialChannelsWithCallsState);
assert.deepEqual(result.current[3], initialCurrentCallState);
// test
await act(async () => setCalls('server1', 'myId', test.calls, test.enabled));
assert.deepEqual(result.current[0], expectedCallsState);
assert.deepEqual(result.current[1], expectedCallsState);
assert.deepEqual(result.current[2], expectedChannelsWithCallsState);
assert.deepEqual(result.current[3], expectedCurrentCallState);
});
it('joinedCall', () => {
const initialCallsState = {
...DefaultCallsState,
calls: {'channel-1': call1},
};
const initialChannelsWithCallsState = {
'channel-1': true,
};
const initialCurrentCallState: CurrentCall = {
...DefaultCurrentCall,
connected: true,
serverUrl: 'server1',
myUserId: 'myUserId',
...call1,
};
const expectedCallsState = {
'channel-1': {
id: 'call1',
sessions: {
session1: {sessionId: 'session1', userId: 'user-1', muted: false, raisedHand: 0},
session2: {sessionId: 'session2', userId: 'user-2', muted: true, raisedHand: 0},
session3: {sessionId: 'session3', userId: 'user-3', muted: true, raisedHand: 0},
},
channelId: 'channel-1',
startTime: 123,
screenOn: '',
threadId: 'thread-1',
ownerId: 'user-1',
hostId: 'user-1',
dismissed: {},
},
};
const expectedChannelsWithCallsState = initialChannelsWithCallsState;
const expectedCurrentCallState: CurrentCall = {
...initialCurrentCallState,
...expectedCallsState['channel-1'],
};
// setup
const {result} = renderHook(() => {
return [useCallsState('server1'), useChannelsWithCalls('server1'), useCurrentCall()] as const;
});
act(() => {
setCallsState('server1', initialCallsState);
setChannelsWithCalls('server1', initialChannelsWithCallsState);
setCurrentCall(initialCurrentCallState);
});
assert.deepEqual(result.current[0], initialCallsState);
assert.deepEqual(result.current[1], initialChannelsWithCallsState);
assert.deepEqual(result.current[2], initialCurrentCallState);
// test
act(() => userJoinedCall('server1', 'channel-1', 'user-3', 'session3'));
assert.deepEqual(result.current[0].calls, expectedCallsState);
assert.deepEqual(result.current[1], expectedChannelsWithCallsState);
assert.deepEqual(result.current[2], expectedCurrentCallState);
act(() => userJoinedCall('server1', 'invalid-channel', 'user-1', 'session1'));
assert.deepEqual(result.current[0].calls, expectedCallsState);
assert.deepEqual(result.current[1], expectedChannelsWithCallsState);
assert.deepEqual(result.current[2], expectedCurrentCallState);
});
it('leftCall', () => {
const initialCallsState = {
...DefaultCallsState,
calls: {'channel-1': call1},
};
const initialChannelsWithCallsState = {
'channel-1': true,
};
const initialCurrentCallState: CurrentCall = {
...DefaultCurrentCall,
connected: true,
serverUrl: 'server1',
myUserId: 'myUserId',
...call1,
};
const expectedCallsState = {
'channel-1': {
id: 'call1',
sessions: {
session2: {sessionId: 'session2', userId: 'user-2', muted: true, raisedHand: 0},
},
channelId: 'channel-1',
startTime: 123,
screenOn: '',
threadId: 'thread-1',
ownerId: 'user-1',
hostId: 'user-1',
dismissed: {},
},
};
const expectedChannelsWithCallsState = initialChannelsWithCallsState;
const expectedCurrentCallState: CurrentCall = {
...initialCurrentCallState,
...expectedCallsState['channel-1'],
};
// setup
const {result} = renderHook(() => {
return [useCallsState('server1'), useChannelsWithCalls('server1'), useCurrentCall()] as const;
});
act(() => {
setCallsState('server1', initialCallsState);
setChannelsWithCalls('server1', initialChannelsWithCallsState);
setCurrentCall(initialCurrentCallState);
});
assert.deepEqual(result.current[0], initialCallsState);
assert.deepEqual(result.current[1], initialChannelsWithCallsState);
assert.deepEqual(result.current[2], initialCurrentCallState);
// test
act(() => userLeftCall('server1', 'channel-1', 'session1'));
assert.deepEqual(result.current[0].calls, expectedCallsState);
assert.deepEqual(result.current[1], expectedChannelsWithCallsState);
assert.deepEqual(result.current[2], expectedCurrentCallState);
act(() => userLeftCall('server1', 'invalid-channel', 'session2'));
assert.deepEqual(result.current[0].calls, expectedCallsState);
assert.deepEqual(result.current[1], expectedChannelsWithCallsState);
assert.deepEqual(result.current[2], expectedCurrentCallState);
});
it('leftCall with screensharing on', () => {
const initialCallsState: CallsState = {
...DefaultCallsState,
calls: {
'channel-1': {
...call1,
screenOn: 'session1',
},
},
};
const initialChannelsWithCallsState = {
'channel-1': true,
};
const initialCurrentCallState: CurrentCall = {
...DefaultCurrentCall,
connected: true,
serverUrl: 'server1',
myUserId: 'myUserId',
...call1,
screenOn: 'session1',
};
const expectedCallsState = {
'channel-1': {
id: 'call1',
sessions: {
session2: {sessionId: 'session2', userId: 'user-2', muted: true, raisedHand: 0},
},
channelId: 'channel-1',
startTime: 123,
threadId: 'thread-1',
ownerId: 'user-1',
hostId: 'user-1',
screenOn: '',
dismissed: {},
},
};
const expectedChannelsWithCallsState = initialChannelsWithCallsState;
const expectedCurrentCallState: CurrentCall = {
...initialCurrentCallState,
...expectedCallsState['channel-1'],
};
// setup
const {result} = renderHook(() => {
return [useCallsState('server1'), useChannelsWithCalls('server1'), useCurrentCall()] as const;
});
act(() => {
setCallsState('server1', initialCallsState);
setChannelsWithCalls('server1', initialChannelsWithCallsState);
setCurrentCall(initialCurrentCallState);
});
assert.deepEqual(result.current[0], initialCallsState);
assert.deepEqual(result.current[1], initialChannelsWithCallsState);
assert.deepEqual(result.current[2], initialCurrentCallState);
// test
act(() => userLeftCall('server1', 'channel-1', 'session1'));
assert.deepEqual(result.current[0].calls, expectedCallsState);
assert.deepEqual(result.current[1], expectedChannelsWithCallsState);
assert.deepEqual(result.current[2], expectedCurrentCallState);
});
it('callStarted', async () => {
const initialCurrentCallState: CurrentCall = {
...DefaultCurrentCall,
connected: false,
serverUrl: 'server1',
myUserId: 'myUserId',
...call1,
};
// setup
await DatabaseManager.init(['server1']);
const {result} = renderHook(() => {
return [useCallsState('server1'), useChannelsWithCalls('server1'), useCurrentCall()] as const;
});
assert.deepEqual(result.current[0], DefaultCallsState);
assert.deepEqual(result.current[1], {});
assert.deepEqual(result.current[2], null);
// test
await act(async () => {
setCurrentCall(initialCurrentCallState);
await callStarted('server1', call1);
});
assert.deepEqual(result.current[0].calls, {'channel-1': call1});
assert.deepEqual(result.current[1], {'channel-1': true});
assert.deepEqual(result.current[2], initialCurrentCallState);
expect(updateThreadFollowing).toBeCalled();
});
it('callEnded', () => {
const initialCallsState = {
...DefaultCallsState,
calls: {'channel-1': call1, 'channel-2': call2},
};
const initialChannelsWithCallsState = {'channel-1': true, 'channel-2': true};
const expectedCallsState = {
...DefaultCallsState,
calls: {'channel-2': call2},
};
const expectedChannelsWithCallsState = {'channel-2': true};
// setup
const {result} = renderHook(() => {
return [useCallsState('server1'), useChannelsWithCalls('server1'), useCurrentCall()];
});
act(() => {
setCallsState('server1', initialCallsState);
setChannelsWithCalls('server1', initialChannelsWithCallsState);
});
assert.deepEqual(result.current[0], initialCallsState);
assert.deepEqual(result.current[1], initialChannelsWithCallsState);
assert.deepEqual(result.current[2], null);
// test
act(() => callEnded('server1', 'channel-1'));
assert.deepEqual(result.current[0], expectedCallsState);
assert.deepEqual(result.current[1], expectedChannelsWithCallsState);
assert.deepEqual(result.current[2], null);
});
it('setUserMuted', () => {
const initialCallsState = {
...DefaultCallsState,
calls: {'channel-1': call1, 'channel-2': call2},
};
const initialChannelsWithCallsState = {'channel-1': true, 'channel-2': true};
const initialCurrentCallState: CurrentCall = {
...DefaultCurrentCall,
connected: true,
serverUrl: 'server1',
myUserId: 'myUserId',
...call1,
};
// setup
const {result} = renderHook(() => {
return [useCallsState('server1'), useChannelsWithCalls('server1'), useCurrentCall()] as const;
});
act(() => {
setCallsState('server1', initialCallsState);
setChannelsWithCalls('server1', initialChannelsWithCallsState);
setCurrentCall(initialCurrentCallState);
});
assert.deepEqual(result.current[0], initialCallsState);
assert.deepEqual(result.current[1], initialChannelsWithCallsState);
assert.deepEqual(result.current[2], initialCurrentCallState);
// test
act(() => setUserMuted('server1', 'channel-1', 'session1', true));
assert.deepEqual((result.current[0]).calls['channel-1'].sessions.session1.muted, true);
assert.deepEqual((result.current[2])?.sessions.session1.muted, true);
act(() => {
setUserMuted('server1', 'channel-1', 'session1', false);
setUserMuted('server1', 'channel-1', 'session2', false);
});
assert.deepEqual((result.current[0]).calls['channel-1'].sessions.session1.muted, false);
assert.deepEqual((result.current[0]).calls['channel-1'].sessions.session2.muted, false);
assert.deepEqual((result.current[2])?.sessions.session1.muted, false);
assert.deepEqual((result.current[2])?.sessions.session2.muted, false);
act(() => setUserMuted('server1', 'channel-1', 'session2', true));
assert.deepEqual((result.current[0]).calls['channel-1'].sessions.session2.muted, true);
assert.deepEqual((result.current[2])?.sessions.session2.muted, true);
assert.deepEqual(result.current[0], initialCallsState);
act(() => setUserMuted('server1', 'invalid-channel', 'session1', true));
assert.deepEqual(result.current[0], initialCallsState);
});
it('setCallScreenOn/Off', () => {
const initialCallsState = {
...DefaultCallsState,
calls: {'channel-1': call1, 'channel-2': call2},
};
const initialChannelsWithCallsState = {'channel-1': true, 'channel-2': true};
const initialCurrentCallState: CurrentCall = {
...DefaultCurrentCall,
serverUrl: 'server1',
myUserId: 'myUserId',
...call1,
};
// setup
const {result} = renderHook(() => {
return [useCallsState('server1'), useChannelsWithCalls('server1'), useCurrentCall()] as const;
});
act(() => {
setCallsState('server1', initialCallsState);
setChannelsWithCalls('server1', initialChannelsWithCallsState);
setCurrentCall(initialCurrentCallState);
});
assert.deepEqual(result.current[0], initialCallsState);
assert.deepEqual(result.current[1], initialChannelsWithCallsState);
assert.deepEqual(result.current[2], initialCurrentCallState);
// test
act(() => setCallScreenOn('server1', 'channel-1', 'session1'));
assert.deepEqual((result.current[0]).calls['channel-1'].screenOn, 'session1');
assert.deepEqual(result.current[1], initialChannelsWithCallsState);
assert.deepEqual((result.current[2])?.screenOn, 'session1');
act(() => setCallScreenOff('server1', 'channel-1', 'session1'));
assert.deepEqual(result.current[0], initialCallsState);
assert.deepEqual(result.current[1], initialChannelsWithCallsState);
assert.deepEqual(result.current[2], initialCurrentCallState);
act(() => setCallScreenOn('server1', 'channel-1', 'invalid-user'));
assert.deepEqual(result.current[0], initialCallsState);
assert.deepEqual(result.current[1], initialChannelsWithCallsState);
assert.deepEqual(result.current[2], initialCurrentCallState);
act(() => setCallScreenOff('server1', 'invalid-channel', 'session1'));
assert.deepEqual(result.current[0], initialCallsState);
assert.deepEqual(result.current[1], initialChannelsWithCallsState);
assert.deepEqual(result.current[2], initialCurrentCallState);
});
it('setRaisedHand', () => {
const initialCallsState = {
...DefaultCallsState,
calls: {'channel-1': call1},
};
const expectedCalls = {
'channel-1': {
id: 'call1',
sessions: {
session1: {sessionId: 'session1', userId: 'user-1', muted: false, raisedHand: 0},
session2: {sessionId: 'session2', userId: 'user-2', muted: true, raisedHand: 345},
},
channelId: 'channel-1',
startTime: 123,
screenOn: false,
threadId: 'thread-1',
ownerId: 'user-1',
hostId: 'user-1',
dismissed: {},
},
};
const initialCurrentCallState: CurrentCall = {
...DefaultCurrentCall,
connected: true,
serverUrl: 'server1',
myUserId: 'myUserId',
...call1,
};
const expectedCurrentCallState = {
...initialCurrentCallState,
...expectedCalls['channel-1'],
};
// setup
const {result} = renderHook(() => {
return [useCallsState('server1'), useCurrentCall()] as const;
});
act(() => {
setCallsState('server1', initialCallsState);
setCurrentCall(initialCurrentCallState);
});
assert.deepEqual(result.current[0], initialCallsState);
assert.deepEqual(result.current[1], initialCurrentCallState);
// test
act(() => setRaisedHand('server1', 'channel-1', 'session2', 345));
assert.deepEqual((result.current[0]).calls, expectedCalls);
assert.deepEqual((result.current[1]), expectedCurrentCallState);
act(() => setRaisedHand('server1', 'invalid-channel', 'session1', 345));
assert.deepEqual((result.current[0]).calls, expectedCalls);
assert.deepEqual((result.current[1]), expectedCurrentCallState);
// unraise hand:
act(() => setRaisedHand('server1', 'channel-1', 'session2', 0));
assert.deepEqual(result.current[0], initialCallsState);
assert.deepEqual(result.current[1], initialCurrentCallState);
});
it('myselfJoinedCall / LeftCall', () => {
const initialCallsState = {
...DefaultCallsState,
myUserId: 'myUserId',
calls: {'channel-1': call1, 'channel-2': call2},
};
const newCall1 = {
...call1,
sessions: {
...call1.sessions,
mySessionId: {sessionId: 'mySessionId', userId: 'myUserId', muted: true, raisedHand: 0},
},
};
const expectedCallsState = {
...initialCallsState,
calls: {
...initialCallsState.calls,
'channel-1': newCall1,
},
};
const expectedCurrentCallState: CurrentCall = {
...DefaultCurrentCall,
connected: true,
serverUrl: 'server1',
myUserId: 'myUserId',
mySessionId: 'mySessionId',
...newCall1,
};
// setup
const {result} = renderHook(() => {
return [useCallsState('server1'), useCurrentCall()];
});
act(() => setCallsState('server1', initialCallsState));
assert.deepEqual(result.current[0], initialCallsState);
assert.deepEqual(result.current[1], null);
// test
act(() => {
newCurrentCall('server1', 'channel-1', 'myUserId');
userJoinedCall('server1', 'channel-1', 'myUserId', 'mySessionId');
});
assert.deepEqual(result.current[0], expectedCallsState);
assert.deepEqual(result.current[1], expectedCurrentCallState);
act(() => {
myselfLeftCall();
userLeftCall('server1', 'channel-1', 'mySessionId');
});
assert.deepEqual(result.current[0], initialCallsState);
assert.deepEqual(result.current[1], null);
});
it('setChannelEnabled', async () => {
const initialState = {
...DefaultCallsState,
enabled: {'channel-1': true, 'channel-2': false},
};
// setup
const {result} = renderHook(() => useCallsState('server1'));
await act(async () => setCallsState('server1', initialState));
assert.deepEqual(result.current, initialState);
// test setCalls affects enabled:
await act(async () => setCalls('server1', 'myUserId', {}, {'channel-1': true}));
assert.deepEqual(result.current.enabled, {'channel-1': true});
// re-setup:
await act(async () => setCallsState('server1', initialState));
assert.deepEqual(result.current, initialState);
// test setChannelEnabled affects enabled:
await act(async () => setChannelEnabled('server1', 'channel-3', true));
assert.deepEqual(result.current.enabled, {'channel-1': true, 'channel-2': false, 'channel-3': true});
await act(async () => setChannelEnabled('server1', 'channel-3', false));
assert.deepEqual(result.current.enabled, {
'channel-1': true,
'channel-2': false,
'channel-3': false,
});
await act(async () => setChannelEnabled('server1', 'channel-1', true));
assert.deepEqual(result.current.enabled, {
'channel-1': true,
'channel-2': false,
'channel-3': false,
});
await act(async () => setChannelEnabled('server1', 'channel-1', false));
assert.deepEqual(result.current.enabled, {
'channel-1': false,
'channel-2': false,
'channel-3': false,
});
});
it('setScreenShareURL', () => {
const initialCallsState = {
...DefaultCallsState,
myUserId: 'myUserId',
calls: {'channel-1': call1, 'channel-2': call2},
};
// setup
const {result} = renderHook(() => {
return [useCallsState('server1'), useCurrentCall()] as const;
});
act(() => setCallsState('server1', initialCallsState));
assert.deepEqual(result.current[0], initialCallsState);
assert.deepEqual(result.current[1], null);
// test joining a call and setting url:
act(() => newCurrentCall('server1', 'channel-1', 'myUserId'));
act(() => userJoinedCall('server1', 'channel-1', 'myUserId', 'mySessionId'));
assert.deepEqual((result.current[1])?.screenShareURL, '');
act(() => setScreenShareURL('testUrl'));
assert.deepEqual((result.current[1])?.screenShareURL, 'testUrl');
act(() => {
myselfLeftCall();
userLeftCall('server1', 'channel-1', 'mySessionId');
setScreenShareURL('test');
});
assert.deepEqual(result.current[0], initialCallsState);
assert.deepEqual(result.current[1], null);
});
it('setSpeakerPhoneOn', () => {
const initialCallsState = {
...DefaultCallsState,
myUserId: 'myUserId',
calls: {'channel-1': call1, 'channel-2': call2},
};
const newCall1 = {
...call1,
sessions: {
...call1.sessions,
mySessionId: {sessionId: 'mySessionId', userId: 'myUserId', muted: true, raisedHand: 0},
},
};
const expectedCallsState = {
...initialCallsState,
calls: {
...initialCallsState.calls,
'channel-1': newCall1,
},
};
// setup
const {result} = renderHook(() => {
return [useCallsState('server1'), useCurrentCall()] as const;
});
act(() => setCallsState('server1', initialCallsState));
assert.deepEqual(result.current[0], initialCallsState);
assert.deepEqual(result.current[1], null);
// test
act(() => newCurrentCall('server1', 'channel-1', 'myUserId'));
act(() => userJoinedCall('server1', 'channel-1', 'myUserId', 'mySessionId'));
assert.deepEqual((result.current[1])?.speakerphoneOn, false);
act(() => setSpeakerPhone(true));
assert.deepEqual((result.current[1])?.speakerphoneOn, true);
act(() => setSpeakerPhone(false));
assert.deepEqual((result.current[1])?.speakerphoneOn, false);
assert.deepEqual(result.current[0], expectedCallsState);
act(() => {
myselfLeftCall();
setSpeakerPhone(true);
});
assert.deepEqual(result.current[0], expectedCallsState);
assert.deepEqual(result.current[1], null);
});
it('setAudioDeviceInfo', () => {
const initialCallsState = {
...DefaultCallsState,
myUserId: 'myUserId',
calls: {'channel-1': call1, 'channel-2': call2},
};
const newCall1 = {
...call1,
sessions: {
...call1.sessions,
mySessionId: {sessionId: 'mySessionId', userId: 'myUserId', muted: true, raisedHand: 0},
},
};
const expectedCallsState = {
...initialCallsState,
calls: {
...initialCallsState.calls,
'channel-1': newCall1,
},
};
const defaultAudioDeviceInfo = {
availableAudioDeviceList: [],
selectedAudioDevice: AudioDevice.None,
};
const newAudioDeviceInfo = {
availableAudioDeviceList: [AudioDevice.Speakerphone, AudioDevice.Earpiece],
selectedAudioDevice: AudioDevice.Speakerphone,
};
// setup
const {result} = renderHook(() => {
return [useCallsState('server1'), useCurrentCall()] as const;
});
act(() => setCallsState('server1', initialCallsState));
assert.deepEqual(result.current[0], initialCallsState);
assert.deepEqual(result.current[1], null);
// test
act(() => newCurrentCall('server1', 'channel-1', 'myUserId'));
act(() => userJoinedCall('server1', 'channel-1', 'myUserId', 'mySessionId'));
assert.deepEqual((result.current[1])?.audioDeviceInfo, defaultAudioDeviceInfo);
act(() => setAudioDeviceInfo(newAudioDeviceInfo));
assert.deepEqual((result.current[1])?.audioDeviceInfo, newAudioDeviceInfo);
assert.deepEqual((result.current[1])?.speakerphoneOn, false);
assert.deepEqual(result.current[0], expectedCallsState);
act(() => {
myselfLeftCall();
});
assert.deepEqual(result.current[0], expectedCallsState);
assert.deepEqual(result.current[1], null);
});
it('MicPermissions', () => {
const initialGlobalState = DefaultGlobalCallsState;
const initialCallsState: CallsState = {
...DefaultCallsState,
myUserId: 'myUserId',
calls: {'channel-1': call1, 'channel-2': call2},
};
const newCall1: Call = {
...call1,
sessions: {
...call1.sessions,
mySessionId: {sessionId: 'mySessionId', userId: 'myUserId', muted: true, raisedHand: 0},
},
};
const expectedCallsState: CallsState = {
...initialCallsState,
calls: {
...initialCallsState.calls,
'channel-1': newCall1,
},
};
const expectedCurrentCallState: CurrentCall = {
...DefaultCurrentCall,
serverUrl: 'server1',
myUserId: 'myUserId',
mySessionId: 'mySessionId',
connected: true,
...newCall1,
};
const secondExpectedCurrentCallState: CurrentCall = {
...expectedCurrentCallState,
micPermissionsErrorDismissed: true,
};
const expectedGlobalState: GlobalCallsState = {
micPermissionsGranted: true,
joiningChannelId: null,
};
// setup
const {result} = renderHook(() => {
return [useCallsState('server1'), useCurrentCall(), useGlobalCallsState()];
});
act(() => setCallsState('server1', initialCallsState));
assert.deepEqual(result.current[0], initialCallsState);
assert.deepEqual(result.current[1], null);
assert.deepEqual(result.current[2], initialGlobalState);
// join call
act(() => {
setMicPermissionsGranted(false);
newCurrentCall('server1', 'channel-1', 'myUserId');
userJoinedCall('server1', 'channel-1', 'myUserId', 'mySessionId');
});
assert.deepEqual(result.current[0], expectedCallsState);
assert.deepEqual(result.current[1], expectedCurrentCallState);
assert.deepEqual(result.current[2], initialGlobalState);
// dismiss mic error
act(() => setMicPermissionsErrorDismissed());
assert.deepEqual(result.current[0], expectedCallsState);
assert.deepEqual(result.current[1], secondExpectedCurrentCallState);
assert.deepEqual(result.current[2], initialGlobalState);
// grant permissions
act(() => setMicPermissionsGranted(true));
assert.deepEqual(result.current[0], expectedCallsState);
assert.deepEqual(result.current[1], secondExpectedCurrentCallState);
assert.deepEqual(result.current[2], expectedGlobalState);
act(() => {
myselfLeftCall();
userLeftCall('server1', 'channel-1', 'mySessionId');
// reset state to default
setMicPermissionsGranted(false);
});
assert.deepEqual(result.current[0], initialCallsState);
assert.deepEqual(result.current[1], null);
});
it('joining call', () => {
const initialGlobalState = DefaultGlobalCallsState;
const expectedGlobalState: GlobalCallsState = {
...DefaultGlobalCallsState,
joiningChannelId: 'channel-1',
};
// setup
const {result} = renderHook(() => {
return [useGlobalCallsState()];
});
// start joining call
act(() => setJoiningChannelId('channel-1'));
assert.deepEqual(result.current[0], expectedGlobalState);
// end joining call
act(() => setJoiningChannelId(null));
assert.deepEqual(result.current[0], initialGlobalState);
});
it('CallQuality', async () => {
const initialCallsState: CallsState = {
...DefaultCallsState,
myUserId: 'myUserId',
calls: {'channel-1': call1, 'channel-2': call2},
};
const newCall1: Call = {
...call1,
sessions: {
...call1.sessions,
mySessionId: {sessionId: 'mySessionId', userId: 'myUserId', muted: true, raisedHand: 0},
},
};
const expectedCallsState: CallsState = {
...initialCallsState,
calls: {
...initialCallsState.calls,
'channel-1': newCall1,
},
};
const currentCallNoAlertNoDismissed: CurrentCall = {
...DefaultCurrentCall,
serverUrl: 'server1',
myUserId: 'myUserId',
mySessionId: 'mySessionId',
connected: true,
...newCall1,
};
// setup
const {result} = renderHook(() => {
return [useCallsState('server1'), useCurrentCall()] as const;
});
act(() => setCallsState('server1', initialCallsState));
assert.deepEqual(result.current[0], initialCallsState);
assert.deepEqual(result.current[1], null);
// join call
act(() => {
newCurrentCall('server1', 'channel-1', 'myUserId');
userJoinedCall('server1', 'channel-1', 'myUserId', 'mySessionId');
});
assert.deepEqual(result.current[0], expectedCallsState);
assert.deepEqual(result.current[1], currentCallNoAlertNoDismissed);
// call quality goes bad
act(() => processMeanOpinionScore(3.4999));
assert.deepEqual((result.current[1])?.callQualityAlert, true);
assert.equal((result.current[1])?.callQualityAlertDismissed, 0);
// call quality goes good
act(() => processMeanOpinionScore(4));
assert.deepEqual(result.current[1], currentCallNoAlertNoDismissed);
// call quality goes bad
act(() => processMeanOpinionScore(3.499));
assert.deepEqual((result.current[1])?.callQualityAlert, true);
assert.equal((result.current[1])?.callQualityAlertDismissed, 0);
// dismiss call quality alert
const timeNow = Date.now();
act(() => setCallQualityAlertDismissed());
assert.deepEqual((result.current[1])?.callQualityAlert, false);
assert.equal((result.current[1]!).callQualityAlertDismissed >= timeNow &&
(result.current[1]!).callQualityAlertDismissed <= Date.now(), true);
// call quality goes bad, but we're not past the dismissed limit
act(() => processMeanOpinionScore(3.4999));
assert.deepEqual((result.current[1])?.callQualityAlert, false);
// test that the dismiss expired
await act(async () => {
await new Promise((r) => setTimeout(r, 101));
processMeanOpinionScore(3.499);
});
assert.deepEqual((result.current[1])?.callQualityAlert, true);
});
it('voiceOn and Off', async () => {
const initialCallsState = {
...DefaultCallsState,
myUserId: 'myUserId',
calls: {'channel-1': call1, 'channel-2': call2},
};
const initialCurrentCallState: CurrentCall = {
...DefaultCurrentCall,
serverUrl: 'server1',
myUserId: 'myUserId',
...call1,
};
// setup
const {result} = renderHook(() => {
return [useCallsState('server1'), useCurrentCall()];
});
act(() => {
setCallsState('server1', initialCallsState);
setCurrentCall(initialCurrentCallState);
});
assert.deepEqual(result.current[0], initialCallsState);
assert.deepEqual(result.current[1], initialCurrentCallState);
// test
act(() => setUserVoiceOn('channel-1', 'session1', true));
assert.deepEqual(result.current[1], {...initialCurrentCallState, voiceOn: {session1: true}});
assert.deepEqual(result.current[0], initialCallsState);
act(() => setUserVoiceOn('channel-1', 'session2', true));
assert.deepEqual(result.current[1], {...initialCurrentCallState, voiceOn: {session1: true, session2: true}});
assert.deepEqual(result.current[0], initialCallsState);
act(() => setUserVoiceOn('channel-1', 'session1', false));
assert.deepEqual(result.current[1], {...initialCurrentCallState, voiceOn: {session2: true}});
assert.deepEqual(result.current[0], initialCallsState);
// test that voice state is cleared on reconnect
await act(() => setCalls('server1', 'myUserId', initialCallsState.calls, {}));
assert.deepEqual(result.current[1], initialCurrentCallState);
assert.deepEqual(result.current[0], initialCallsState);
});
it('config', () => {
const newConfig = {
...DefaultCallsConfig,
ICEServers: [],
ICEServersConfigs: [
{
urls: ['stun:stun.example.com:3478'],
},
{
urls: ['turn:turn.example.com:3478'],
},
],
AllowEnableCalls: true,
DefaultEnabled: true,
NeedsTURNCredentials: false,
last_retrieved_at: 123,
sku_short_name: License.SKU_SHORT_NAME.Professional,
MaxCallParticipants: 8,
EnableRecordings: true,
bot_user_id: '',
};
// setup
const {result} = renderHook(() => useCallsConfig('server1'));
assert.deepEqual(result.current, DefaultCallsConfig);
// test
act(() => setConfig('server1', newConfig));
assert.deepEqual(result.current, {...newConfig, pluginEnabled: false});
act(() => setPluginEnabled('server1', true));
assert.deepEqual(result.current, {...newConfig, pluginEnabled: true});
act(() => setPluginEnabled('server1', false));
assert.deepEqual(result.current, {...newConfig, pluginEnabled: false});
});
it('user reactions', () => {
const initialCallsState = {
...DefaultCallsState,
serverUrl: 'server1',
myUserId: 'myUserId',
calls: {'channel-1': call1, 'channel-2': call2},
};
const initialCurrentCallState: CurrentCall = {
...DefaultCurrentCall,
serverUrl: 'server1',
myUserId: 'myUserId',
...call1,
};
const expectedCurrentCallState: CurrentCall = {
...initialCurrentCallState,
reactionStream: [
{name: 'smile', latestTimestamp: 202, count: 1, literal: undefined},
{name: '+1', latestTimestamp: 145, count: 2, literal: undefined},
],
sessions: {
...initialCurrentCallState.sessions,
session1: {
...initialCurrentCallState.sessions.session1,
reaction: {
user_id: 'user-1',
session_id: 'session1',
emoji: {name: 'smile', unified: 'something'},
timestamp: 202,
},
},
session2: {
...initialCurrentCallState.sessions.session2,
reaction: {
user_id: 'user-2',
session_id: 'session2',
emoji: {name: '+1', unified: 'something'},
timestamp: 145,
},
},
},
};
// setup
const {result} = renderHook(() => {
return [useCallsState('server1'), useCurrentCall()];
});
act(() => {
setCallsState('server1', initialCallsState);
setCurrentCall(initialCurrentCallState);
});
assert.deepEqual(result.current[0], initialCallsState);
assert.deepEqual(result.current[1], initialCurrentCallState);
// test
act(() => {
userReacted('server1', 'channel-1', {
user_id: 'user-2',
session_id: 'session2',
emoji: {name: '+1', unified: 'something'},
timestamp: 123,
});
userReacted('server1', 'channel-1', {
user_id: 'user-2',
session_id: 'session2',
emoji: {name: '+1', unified: 'something'},
timestamp: 145,
});
userReacted('server1', 'channel-1', {
user_id: 'user-1',
session_id: 'session1',
emoji: {name: 'smile', unified: 'something'},
timestamp: 202,
});
});
assert.deepEqual(result.current[0], initialCallsState);
assert.deepEqual(result.current[1], expectedCurrentCallState);
});
it('setRecordingState', () => {
const initialCallsState = {
...DefaultCallsState,
calls: {'channel-1': call1, 'channel-2': call2},
};
const initialCurrentCallState: CurrentCall = {
...DefaultCurrentCall,
connected: true,
serverUrl: 'server1',
myUserId: 'myUserId',
...call1,
};
const recState: CallJobState = {
type: Calls.JOB_TYPE_RECORDING,
init_at: 123,
start_at: 231,
end_at: 345,
};
const expectedCallsState: CallsState = {
...initialCallsState,
calls: {
...initialCallsState.calls,
'channel-1': {
...call1,
recState,
},
},
};
const expectedCurrentCallState: CurrentCall = {
...DefaultCurrentCall,
connected: true,
serverUrl: 'server1',
myUserId: 'myUserId',
...call1,
recState,
};
// setup
const {result} = renderHook(() => {
return [useCallsState('server1'), useCurrentCall()] as const;
});
act(() => {
setCallsState('server1', initialCallsState);
setCurrentCall(initialCurrentCallState);
});
assert.deepEqual(result.current[0], initialCallsState);
assert.deepEqual(result.current[1], initialCurrentCallState);
// test
act(() => setRecordingState('server1', 'channel-1', recState));
assert.deepEqual((result.current[0]), expectedCallsState);
assert.deepEqual((result.current[1]), expectedCurrentCallState);
act(() => setRecordingState('server1', 'channel-2', recState));
assert.deepEqual((result.current[0]).calls['channel-2'], {...call2, recState});
assert.deepEqual((result.current[1]), expectedCurrentCallState);
act(() => setRecordingState('server1', 'channel-1', {...recState, start_at: recState.start_at + 1}));
expect(needsRecordingAlert).toBeCalled();
});
it('setHost', () => {
const initialCallsState = {
...DefaultCallsState,
calls: {'channel-1': call1, 'channel-2': call2},
};
const initialCurrentCallState: CurrentCall = {
...DefaultCurrentCall,
connected: true,
serverUrl: 'server1',
myUserId: 'myUserId',
...call1,
};
const expectedCallsState: CallsState = {
...initialCallsState,
calls: {
...initialCallsState.calls,
'channel-1': {
...call1,
hostId: 'user-52',
},
},
};
const expectedCurrentCallState: CurrentCall = {
...DefaultCurrentCall,
connected: true,
serverUrl: 'server1',
myUserId: 'myUserId',
...call1,
hostId: 'user-52',
};
// setup
const {result} = renderHook(() => {
return [useCallsState('server1'), useCurrentCall()] as const;
});
act(() => {
setCallsState('server1', initialCallsState);
setCurrentCall(initialCurrentCallState);
});
assert.deepEqual(result.current[0], initialCallsState);
assert.deepEqual(result.current[1], initialCurrentCallState);
// test
act(() => setHost('server1', 'channel-1', 'user-52'));
assert.deepEqual((result.current[0]), expectedCallsState);
assert.deepEqual((result.current[1]), expectedCurrentCallState);
act(() => setHost('server1', 'channel-2', 'user-1923'));
assert.deepEqual((result.current[0]).calls['channel-2'], {...call2, hostId: 'user-1923'});
assert.deepEqual((result.current[1]), expectedCurrentCallState);
act(() => setHost('server1', 'channel-1', 'myUserId'));
expect(needsRecordingAlert).toBeCalled();
});
it('incoming calls', async () => {
const calls = {'channel-dm': callDM};
const afterLoadCallsState: CallsState = {
myUserId: 'myId',
calls,
enabled: {},
};
const initialCurrentCallState: CurrentCall | null = null;
const initialIncomingCalls = DefaultIncomingCalls;
const expectedIncomingCalls: IncomingCalls = {
...DefaultIncomingCalls,
incomingCalls: [{
callID: 'callDM',
callerID: 'user-5',
callerModel: user5,
channelID: 'channel-private',
myUserId: 'myId',
serverUrl: 'server1',
startAt: 123,
type: 0,
}],
};
const dismissedCalls = {
'channel-dm': {...callDM, dismissed: {myId: true}},
};
const callIStarted: Call = {
id: 'callIStartedid',
sessions: {
session5: {sessionId: 'session5', userId: 'user-5', muted: false, raisedHand: 0},
},
channelId: 'channel-private2',
startTime: 123,
screenOn: '',
threadId: 'thread-4',
ownerId: 'myId',
hostId: 'user-5',
dismissed: {},
};
const callImIn: Call = {
id: 'callImInId',
sessions: {},
channelId: 'channel-private2',
startTime: 123,
screenOn: '',
threadId: 'thread-4',
ownerId: 'user-5',
hostId: 'user-5',
dismissed: {},
};
const currentCallStateImIn: CurrentCall = {
...DefaultCurrentCall,
serverUrl: 'server1',
myUserId: 'myId',
...callImIn,
};
// setup
await DatabaseManager.init(['server1']);
const {result} = renderHook(() => {
return [
useCallsState('server1'),
useCurrentCall(),
useIncomingCalls(),
];
});
act(() => {
setCallsConfig('server1', {...DefaultCallsConfig, EnableRinging: true});
});
assert.deepEqual(result.current[0], DefaultCallsState);
assert.deepEqual(result.current[1], initialCurrentCallState);
assert.deepEqual(result.current[2], initialIncomingCalls);
// test incoming call on load
await act(async () => setCalls('server1', 'myId', afterLoadCallsState.calls, {}));
assert.deepEqual(result.current[0], afterLoadCallsState);
assert.deepEqual(result.current[1], initialCurrentCallState);
assert.deepEqual(result.current[2], expectedIncomingCalls);
// test dismissing (same path for manually dismissing, joining that call,
// or receiving ws event from dismissing/joining from another client)
act(() => removeIncomingCall('server1', 'callDM'));
assert.deepEqual(result.current[0], afterLoadCallsState);
assert.deepEqual(result.current[1], initialCurrentCallState);
assert.deepEqual(result.current[2], DefaultIncomingCalls);
// test load call, but call has been dismissed
await act(async () => setCalls('server1', 'myId', dismissedCalls, {}));
assert.deepEqual(result.current[2], DefaultIncomingCalls);
// test load call, then load same call again (eg from ws event): should only have one notification
await act(async () => setCalls('server1', 'myId', afterLoadCallsState.calls, {}));
assert.deepEqual(result.current[2], expectedIncomingCalls);
await act(async () => processIncomingCalls('server1', [calls['channel-dm']]));
assert.deepEqual(result.current[2], expectedIncomingCalls);
// test received ws event for a call I started
await act(async () => processIncomingCalls('server1', [callIStarted]));
assert.deepEqual(result.current[2], expectedIncomingCalls);
// test received ws event for a call I am in
await act(async () => {
setCurrentCall(currentCallStateImIn);
await processIncomingCalls('server1', [callImIn]);
});
assert.deepEqual(result.current[1], currentCallStateImIn);
assert.deepEqual(result.current[2], expectedIncomingCalls);
});
it('playIncomingCallsRinging', async () => {
const initialIncomingCalls = {
...DefaultIncomingCalls,
incomingCalls: [{
callID: 'callDM',
callerID: 'user-5',
callerModel: TestHelper.fakeUserModel({username: 'user-5'}),
channelID: 'channel-private',
myUserId: 'myId',
serverUrl: 'server1',
startAt: 123,
type: 0,
}],
currentRingingCallId: undefined,
};
// setup
await DatabaseManager.init(['server1']);
const {result} = renderHook(() => useIncomingCalls());
await act(async () => {
await setIncomingCalls(initialIncomingCalls);
});
assert.deepEqual(result.current, initialIncomingCalls);
AppState.currentState = 'active';
const getCurrentUser = require('@queries/servers/user').getCurrentUser;
getCurrentUser.mockResolvedValueOnce({
id: 'user-5',
roles: 'user',
notifyProps: {
calls_mobile_sound: 'true',
calls_mobile_notification_sound: 'Calm',
},
});
// test: should not ring when in DND
await act(async () => {
await playIncomingCallsRinging('server1', 'call1', 'dnd');
});
assert.deepEqual(result.current, initialIncomingCalls);
// test: should not ring when in OOO
await act(async () => {
await playIncomingCallsRinging('server1', 'call1', 'ooo');
});
assert.deepEqual(result.current, initialIncomingCalls);
// test: should ring when online
await act(async () => {
await playIncomingCallsRinging('server1', 'call1', 'online');
});
assert.deepEqual(result.current, {
...initialIncomingCalls,
currentRingingCallId: 'call1',
callIdHasRung: {call1: true},
});
// test: should not ring for same call again
await act(async () => {
setIncomingCalls(initialIncomingCalls);
await playIncomingCallsRinging('server1', 'call1', 'online');
});
assert.deepEqual(result.current, initialIncomingCalls);
// test: should not ring when already ringing
await act(async () => {
setIncomingCalls({
...initialIncomingCalls,
currentRingingCallId: 'call2',
});
await playIncomingCallsRinging('server1', 'call3', 'online');
});
assert.deepEqual(result.current.currentRingingCallId, 'call2');
});
it('callsOnAppStateChange', async () => {
const initialIncomingCalls = {
...DefaultIncomingCalls,
currentRingingCallId: 'call1',
};
// setup
const {result} = renderHook(() => useIncomingCalls());
act(() => {
setIncomingCalls(initialIncomingCalls);
});
assert.deepEqual(result.current, initialIncomingCalls);
// test going to background
await act(async () => {
await callsOnAppStateChange('background');
});
assert.deepEqual(result.current, {...initialIncomingCalls, currentRingingCallId: undefined});
// test going to inactive
await act(async () => {
setIncomingCalls(initialIncomingCalls);
await callsOnAppStateChange('inactive');
await TestHelper.wait(100);
});
assert.deepEqual(result.current, {...initialIncomingCalls, currentRingingCallId: undefined});
// test going to active (should not change state)
await act(async () => {
setIncomingCalls(initialIncomingCalls);
await callsOnAppStateChange('active');
await TestHelper.wait(100);
});
assert.deepEqual(result.current, initialIncomingCalls);
// test previous state
await act(async () => {
setIncomingCalls(initialIncomingCalls);
await callsOnAppStateChange('active');
await TestHelper.wait(100);
});
assert.deepEqual(result.current, initialIncomingCalls);
});
it('setCallForChannel', async () => {
const initialCallsState = {
...DefaultCallsState,
calls: {'channel-1': call1},
enabled: {'channel-1': true},
};
const initialChannelsWithCalls = {'channel-1': true};
const initialCurrentCallState: CurrentCall = {
...DefaultCurrentCall,
serverUrl: 'server1',
myUserId: 'myUserId',
...call1,
};
// setup
const {result} = renderHook(() => {
return [useCallsState('server1'), useChannelsWithCalls('server1'), useCurrentCall()] as const;
});
await act(async () => {
await setCallsState('server1', initialCallsState);
await setChannelsWithCalls('server1', initialChannelsWithCalls);
await setCurrentCall(initialCurrentCallState);
});
assert.deepEqual(result.current[0], initialCallsState);
assert.deepEqual(result.current[1], initialChannelsWithCalls);
assert.deepEqual(result.current[2], initialCurrentCallState);
// test: add new call
await act(async () => setCallForChannel('server1', 'channel-2', call2, true));
assert.deepEqual(result.current[0], {
...initialCallsState,
calls: {...initialCallsState.calls, 'channel-2': call2},
enabled: {...initialCallsState.enabled, 'channel-2': true},
});
assert.deepEqual(result.current[1], {...initialChannelsWithCalls, 'channel-2': true});
// test: update existing call
const updatedCall1 = {...call1, screenOn: 'newScreen'};
await act(async () => setCallForChannel('server1', 'channel-1', updatedCall1));
assert.deepEqual(result.current[0].calls['channel-1'], updatedCall1);
assert.deepEqual(result.current[2], {...initialCurrentCallState, screenOn: 'newScreen'});
// test: remove call
await act(async () => setCallForChannel('server1', 'channel-1', undefined));
assert.deepEqual(result.current[0], {
...initialCallsState,
calls: {'channel-2': call2},
enabled: {'channel-1': true, 'channel-2': true},
});
assert.deepEqual(result.current[1], {'channel-2': true});
// test: just update enabled state
await act(async () => setCallForChannel('server1', 'channel-3', undefined, true));
assert.deepEqual(result.current[0].enabled['channel-3'], true);
assert.deepEqual(result.current[1], {'channel-2': true});
});
it('captions', () => {
const initialCallsState = {
...DefaultCallsState,
serverUrl: 'server1',
myUserId: 'myUserId',
calls: {'channel-1': call1, 'channel-2': call2},
};
const initialCurrentCallState: CurrentCall = {
...DefaultCurrentCall,
serverUrl: 'server1',
myUserId: 'myUserId',
...call1,
};
const caption1user1Data: LiveCaptionData = {
session_id: 'session1',
user_id: 'user-1',
channel_id: 'channel-1',
text: 'caption 1',
};
const caption2user1Data: LiveCaptionData = {
session_id: 'session1',
user_id: 'user-1',
channel_id: 'channel-1',
text: 'caption 2',
};
const caption3user1Data: LiveCaptionData = {
session_id: 'session1',
user_id: 'user-1',
channel_id: 'channel-1',
text: 'caption 3',
};
const caption1user2Data: LiveCaptionData = {
session_id: 'session2',
user_id: 'user-2',
channel_id: 'channel-1',
text: 'caption 1 user 2',
};
const caption2user2Data: LiveCaptionData = {
session_id: 'session2',
user_id: 'user-2',
channel_id: 'channel-1',
text: 'caption 2 user 2',
};
// setup
const {result} = renderHook(() => {
return [useCallsState('server1'), useCurrentCall()] as const;
});
act(() => {
setCallsState('server1', initialCallsState);
setCurrentCall(initialCurrentCallState);
});
assert.deepEqual(result.current[0], initialCallsState);
assert.deepEqual(result.current[1], initialCurrentCallState);
// test sending the first 2 captions for user 1, 1 caption for user 2
act(() => {
receivedCaption('server1', caption1user1Data);
receivedCaption('server1', caption2user1Data);
receivedCaption('server1', caption1user2Data);
});
assert.deepEqual(result.current[0], initialCallsState);
let currentCall = result.current[1];
assert.equal(currentCall?.captions.session1.text, 'caption 2');
assert.equal(currentCall?.captions.session2.text, 'caption 1 user 2');
// test sending the next captions for users 1 and 2
act(() => {
receivedCaption('server1', caption3user1Data);
receivedCaption('server1', caption2user2Data);
});
assert.deepEqual(result.current[0], initialCallsState);
currentCall = result.current[1];
assert.equal(currentCall?.captions.session1.text, 'caption 3');
assert.equal(currentCall?.captions.session2.text, 'caption 2 user 2');
});
});