Call link admin key fix and in-call approve, deny, remove
This commit is contained in:
parent
5df8924197
commit
8ec585d54c
20 changed files with 599 additions and 43 deletions
|
@ -10,12 +10,15 @@ import { reducer as rootReducer } from '../../../state/reducer';
|
|||
import { noopAction } from '../../../state/ducks/noop';
|
||||
import type {
|
||||
ActiveCallStateType,
|
||||
CallingActionType,
|
||||
CallingStateType,
|
||||
DirectCallStateType,
|
||||
GroupCallReactionsReceivedActionType,
|
||||
GroupCallStateChangeActionType,
|
||||
GroupCallStateType,
|
||||
HandleCallLinkUpdateType,
|
||||
SendGroupCallReactionActionType,
|
||||
StartCallLinkLobbyType,
|
||||
} from '../../../state/ducks/calling';
|
||||
import {
|
||||
actions,
|
||||
|
@ -36,8 +39,11 @@ import {
|
|||
import { generateAci } from '../../../types/ServiceId';
|
||||
import { getDefaultConversation } from '../../../test-both/helpers/getDefaultConversation';
|
||||
import type { UnwrapPromise } from '../../../types/Util';
|
||||
import { CallLinkRestrictions } from '../../../types/CallLink';
|
||||
import { FAKE_CALL_LINK } from '../../../test-both/helpers/fakeCallLink';
|
||||
import {
|
||||
FAKE_CALL_LINK,
|
||||
FAKE_CALL_LINK_WITH_ADMIN_KEY,
|
||||
getCallLinkState,
|
||||
} from '../../../test-both/helpers/fakeCallLink';
|
||||
|
||||
const ACI_1 = generateAci();
|
||||
const NOW = new Date('2020-01-23T04:56:00.000');
|
||||
|
@ -109,6 +115,7 @@ describe('calling duck', () => {
|
|||
localDemuxId: 1,
|
||||
peekInfo: {
|
||||
acis: [creatorAci],
|
||||
pendingAcis: [],
|
||||
creatorAci,
|
||||
eraId: 'xyz',
|
||||
maxDevices: 16,
|
||||
|
@ -902,6 +909,7 @@ describe('calling duck', () => {
|
|||
hasLocalVideo: false,
|
||||
peekInfo: {
|
||||
acis: [creatorAci],
|
||||
pendingAcis: [],
|
||||
creatorAci,
|
||||
eraId: 'xyz',
|
||||
maxDevices: 16,
|
||||
|
@ -932,6 +940,7 @@ describe('calling duck', () => {
|
|||
localDemuxId: 1,
|
||||
peekInfo: {
|
||||
acis: [creatorAci],
|
||||
pendingAcis: [],
|
||||
creatorAci,
|
||||
eraId: 'xyz',
|
||||
maxDevices: 16,
|
||||
|
@ -967,6 +976,7 @@ describe('calling duck', () => {
|
|||
hasLocalVideo: false,
|
||||
peekInfo: {
|
||||
acis: [ACI_1],
|
||||
pendingAcis: [],
|
||||
maxDevices: 16,
|
||||
deviceCount: 1,
|
||||
},
|
||||
|
@ -995,6 +1005,7 @@ describe('calling duck', () => {
|
|||
localDemuxId: 1,
|
||||
peekInfo: {
|
||||
acis: [ACI_1],
|
||||
pendingAcis: [],
|
||||
maxDevices: 16,
|
||||
deviceCount: 1,
|
||||
},
|
||||
|
@ -1041,6 +1052,7 @@ describe('calling duck', () => {
|
|||
hasLocalVideo: false,
|
||||
peekInfo: {
|
||||
acis: [ACI_1],
|
||||
pendingAcis: [],
|
||||
maxDevices: 16,
|
||||
deviceCount: 1,
|
||||
},
|
||||
|
@ -1095,6 +1107,7 @@ describe('calling duck', () => {
|
|||
hasLocalVideo: false,
|
||||
peekInfo: {
|
||||
acis: [ACI_1],
|
||||
pendingAcis: [],
|
||||
maxDevices: 16,
|
||||
deviceCount: 1,
|
||||
},
|
||||
|
@ -1136,6 +1149,7 @@ describe('calling duck', () => {
|
|||
hasLocalVideo: false,
|
||||
peekInfo: {
|
||||
acis: [ACI_1],
|
||||
pendingAcis: [],
|
||||
maxDevices: 16,
|
||||
deviceCount: 1,
|
||||
},
|
||||
|
@ -1170,6 +1184,7 @@ describe('calling duck', () => {
|
|||
hasLocalVideo: true,
|
||||
peekInfo: {
|
||||
acis: [ACI_1],
|
||||
pendingAcis: [],
|
||||
maxDevices: 16,
|
||||
deviceCount: 1,
|
||||
},
|
||||
|
@ -1216,6 +1231,7 @@ describe('calling duck', () => {
|
|||
hasLocalVideo: true,
|
||||
peekInfo: {
|
||||
acis: [ACI_1],
|
||||
pendingAcis: [],
|
||||
maxDevices: 16,
|
||||
deviceCount: 1,
|
||||
},
|
||||
|
@ -1262,6 +1278,7 @@ describe('calling duck', () => {
|
|||
hasLocalVideo: true,
|
||||
peekInfo: {
|
||||
acis: [],
|
||||
pendingAcis: [],
|
||||
maxDevices: 16,
|
||||
deviceCount: 0,
|
||||
},
|
||||
|
@ -1292,6 +1309,7 @@ describe('calling duck', () => {
|
|||
hasLocalVideo: true,
|
||||
peekInfo: {
|
||||
acis: [ACI_1],
|
||||
pendingAcis: [],
|
||||
maxDevices: 16,
|
||||
deviceCount: 1,
|
||||
},
|
||||
|
@ -1304,42 +1322,42 @@ describe('calling duck', () => {
|
|||
});
|
||||
|
||||
describe('handleCallLinkUpdate', () => {
|
||||
const { roomId, rootKey, expiration } = FAKE_CALL_LINK;
|
||||
const {
|
||||
roomId,
|
||||
name,
|
||||
restrictions,
|
||||
expiration,
|
||||
revoked,
|
||||
rootKey,
|
||||
adminKey,
|
||||
} = FAKE_CALL_LINK;
|
||||
|
||||
beforeEach(function (this: Mocha.Context) {
|
||||
this.callingServiceReadCallLink = this.sandbox
|
||||
.stub(callingService, 'readCallLink')
|
||||
.resolves({
|
||||
callLinkState: {
|
||||
name: 'Signal Call',
|
||||
restrictions: CallLinkRestrictions.None,
|
||||
expiration,
|
||||
revoked: false,
|
||||
},
|
||||
callLinkState: getCallLinkState(FAKE_CALL_LINK),
|
||||
errorStatusCode: undefined,
|
||||
});
|
||||
});
|
||||
|
||||
it('reads the call link from calling service', async function (this: Mocha.Context) {
|
||||
const doAction = async (
|
||||
payload: HandleCallLinkUpdateType
|
||||
): Promise<{ dispatch: sinon.SinonSpy }> => {
|
||||
const { handleCallLinkUpdate } = actions;
|
||||
const dispatch = sinon.spy();
|
||||
await handleCallLinkUpdate({ rootKey, adminKey: null })(
|
||||
dispatch,
|
||||
getEmptyRootState,
|
||||
null
|
||||
);
|
||||
await handleCallLinkUpdate(payload)(dispatch, getEmptyRootState, null);
|
||||
return { dispatch };
|
||||
};
|
||||
|
||||
it('reads the call link from calling service', async function (this: Mocha.Context) {
|
||||
await doAction({ rootKey, adminKey: null });
|
||||
|
||||
sinon.assert.calledOnce(this.callingServiceReadCallLink);
|
||||
});
|
||||
|
||||
it('dispatches HANDLE_CALL_LINK_UPDATE', async () => {
|
||||
const { handleCallLinkUpdate } = actions;
|
||||
const dispatch = sinon.spy();
|
||||
await handleCallLinkUpdate({ rootKey, adminKey: null })(
|
||||
dispatch,
|
||||
getEmptyRootState,
|
||||
null
|
||||
);
|
||||
const { dispatch } = await doAction({ rootKey, adminKey: null });
|
||||
|
||||
sinon.assert.calledOnce(dispatch);
|
||||
sinon.assert.calledWith(dispatch, {
|
||||
|
@ -1347,16 +1365,115 @@ describe('calling duck', () => {
|
|||
payload: {
|
||||
roomId,
|
||||
callLinkDetails: {
|
||||
name: 'Signal Call',
|
||||
restrictions: CallLinkRestrictions.None,
|
||||
name,
|
||||
restrictions,
|
||||
expiration,
|
||||
revoked: false,
|
||||
revoked,
|
||||
rootKey,
|
||||
adminKey: null,
|
||||
adminKey,
|
||||
},
|
||||
},
|
||||
});
|
||||
});
|
||||
|
||||
it('can save adminKey', async () => {
|
||||
const { dispatch } = await doAction({ rootKey, adminKey: 'banana' });
|
||||
|
||||
sinon.assert.calledOnce(dispatch);
|
||||
sinon.assert.calledWith(dispatch, {
|
||||
type: 'calling/HANDLE_CALL_LINK_UPDATE',
|
||||
payload: {
|
||||
roomId,
|
||||
callLinkDetails: {
|
||||
name,
|
||||
restrictions,
|
||||
expiration,
|
||||
revoked,
|
||||
rootKey,
|
||||
adminKey: 'banana',
|
||||
},
|
||||
},
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('startCallLinkLobby', () => {
|
||||
const callLobbyData = {
|
||||
callMode: CallMode.Adhoc,
|
||||
connectionState: GroupCallConnectionState.NotConnected,
|
||||
hasLocalAudio: true,
|
||||
hasLocalVideo: true,
|
||||
joinState: GroupCallJoinState.NotJoined,
|
||||
peekInfo: [],
|
||||
remoteParticipants: [],
|
||||
};
|
||||
const callLinkState = getCallLinkState(FAKE_CALL_LINK);
|
||||
|
||||
const getStateWithAdminKey = (): RootStateType => ({
|
||||
...getEmptyRootState(),
|
||||
calling: {
|
||||
...getEmptyState(),
|
||||
callLinks: {
|
||||
[FAKE_CALL_LINK_WITH_ADMIN_KEY.roomId]:
|
||||
FAKE_CALL_LINK_WITH_ADMIN_KEY,
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
beforeEach(function (this: Mocha.Context) {
|
||||
this.callingServiceReadCallLink = this.sandbox
|
||||
.stub(callingService, 'readCallLink')
|
||||
.resolves({
|
||||
callLinkState,
|
||||
errorStatusCode: undefined,
|
||||
});
|
||||
this.callingServiceStartCallLinkLobby = this.sandbox
|
||||
.stub(callingService, 'startCallLinkLobby')
|
||||
.resolves(callLobbyData);
|
||||
});
|
||||
|
||||
const doAction = async (
|
||||
payload: StartCallLinkLobbyType
|
||||
): Promise<{ dispatch: sinon.SinonSpy }> => {
|
||||
const { startCallLinkLobby } = actions;
|
||||
const dispatch = sinon.spy();
|
||||
await startCallLinkLobby(payload)(dispatch, getEmptyRootState, null);
|
||||
return { dispatch };
|
||||
};
|
||||
|
||||
it('reads the link and dispatches START_CALL_LINK_LOBBY', async function (this: Mocha.Context) {
|
||||
const { roomId, rootKey } = FAKE_CALL_LINK;
|
||||
const { dispatch } = await doAction({ rootKey });
|
||||
|
||||
sinon.assert.calledOnce(dispatch);
|
||||
sinon.assert.calledWith(dispatch, {
|
||||
type: 'calling/START_CALL_LINK_LOBBY',
|
||||
payload: {
|
||||
...callLobbyData,
|
||||
callLinkState,
|
||||
callLinkRootKey: rootKey,
|
||||
conversationId: roomId,
|
||||
isConversationTooBigToRing: false,
|
||||
},
|
||||
});
|
||||
});
|
||||
|
||||
it('preserves adminKey', () => {
|
||||
const { startCallLinkLobby } = actions;
|
||||
const { roomId, rootKey, adminKey } = FAKE_CALL_LINK_WITH_ADMIN_KEY;
|
||||
const dispatch = sinon.spy();
|
||||
const result = reducer(
|
||||
getStateWithAdminKey().calling,
|
||||
startCallLinkLobby({
|
||||
rootKey,
|
||||
})(
|
||||
dispatch,
|
||||
getStateWithAdminKey,
|
||||
null
|
||||
) as unknown as Readonly<CallingActionType>
|
||||
);
|
||||
assert.equal(result.callLinks[roomId]?.adminKey, adminKey);
|
||||
});
|
||||
});
|
||||
|
||||
describe('peekNotConnectedGroupCall', () => {
|
||||
|
@ -1503,6 +1620,7 @@ describe('calling duck', () => {
|
|||
localDemuxId: undefined,
|
||||
peekInfo: {
|
||||
acis: [],
|
||||
pendingAcis: [],
|
||||
maxDevices: Infinity,
|
||||
deviceCount: 0,
|
||||
},
|
||||
|
@ -1956,6 +2074,7 @@ describe('calling duck', () => {
|
|||
joinState: GroupCallJoinState.NotJoined,
|
||||
peekInfo: {
|
||||
acis: [creatorAci],
|
||||
pendingAcis: [],
|
||||
creatorAci,
|
||||
eraId: 'xyz',
|
||||
maxDevices: 16,
|
||||
|
@ -1983,6 +2102,7 @@ describe('calling duck', () => {
|
|||
localDemuxId: undefined,
|
||||
peekInfo: {
|
||||
acis: [creatorAci],
|
||||
pendingAcis: [],
|
||||
creatorAci,
|
||||
eraId: 'xyz',
|
||||
maxDevices: 16,
|
||||
|
@ -2022,6 +2142,7 @@ describe('calling duck', () => {
|
|||
const call = result.callsByConversation['fake-conversation-id'];
|
||||
assert.deepEqual(call?.callMode === CallMode.Group && call.peekInfo, {
|
||||
acis: [],
|
||||
pendingAcis: [],
|
||||
maxDevices: Infinity,
|
||||
deviceCount: 0,
|
||||
});
|
||||
|
@ -2053,6 +2174,7 @@ describe('calling duck', () => {
|
|||
result.callsByConversation['fake-group-call-conversation-id'];
|
||||
assert.deepEqual(call?.callMode === CallMode.Group && call.peekInfo, {
|
||||
acis: [creatorAci],
|
||||
pendingAcis: [],
|
||||
creatorAci,
|
||||
eraId: 'xyz',
|
||||
maxDevices: 16,
|
||||
|
@ -2081,6 +2203,7 @@ describe('calling duck', () => {
|
|||
joinState: GroupCallJoinState.NotJoined,
|
||||
peekInfo: {
|
||||
acis: [differentCreatorAci],
|
||||
pendingAcis: [],
|
||||
creatorAci: differentCreatorAci,
|
||||
eraId: 'abc',
|
||||
maxDevices: 5,
|
||||
|
@ -2103,6 +2226,7 @@ describe('calling duck', () => {
|
|||
const call = result.callsByConversation['fake-conversation-id'];
|
||||
assert.deepEqual(call?.callMode === CallMode.Group && call.peekInfo, {
|
||||
acis: [differentCreatorAci],
|
||||
pendingAcis: [],
|
||||
creatorAci: differentCreatorAci,
|
||||
eraId: 'abc',
|
||||
maxDevices: 5,
|
||||
|
|
|
@ -100,6 +100,7 @@ describe('state/selectors/calling', () => {
|
|||
localDemuxId: undefined,
|
||||
peekInfo: {
|
||||
acis: [ACI_1],
|
||||
pendingAcis: [],
|
||||
creatorAci: ACI_1,
|
||||
maxDevices: Infinity,
|
||||
deviceCount: 1,
|
||||
|
@ -180,6 +181,7 @@ describe('state/selectors/calling', () => {
|
|||
...incomingGroupCall,
|
||||
peekInfo: {
|
||||
acis: [],
|
||||
pendingAcis: [],
|
||||
maxDevices: Infinity,
|
||||
deviceCount: 1,
|
||||
},
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue