Skip to content
This repository was archived by the owner on Sep 11, 2024. It is now read-only.

Commit 130bd6a

Browse files
author
Kerry
authored
manage voicerecording state when deleting or sending a voice message (#7896)
* manage voicerecording state when deleting or sending a voice message Signed-off-by: Kerry Archibald <kerrya@element.io> * comment Signed-off-by: Kerry Archibald <kerrya@element.io>
1 parent 5167b30 commit 130bd6a

File tree

2 files changed

+108
-1
lines changed

2 files changed

+108
-1
lines changed

src/stores/VoiceRecordingStore.ts

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,15 @@ export class VoiceRecordingStore extends AsyncStoreWithClient<IState> {
8282
if (this.state[roomId]) {
8383
this.state[roomId].destroy(); // stops internally
8484
}
85-
return this.updateState(Object.fromEntries(Object.entries(this.state).filter(e => e[0] !== roomId)));
85+
86+
const {
87+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
88+
[roomId]: _toDelete,
89+
...newState
90+
} = this.state;
91+
// unexpectedly AsyncStore.updateState merges state
92+
// AsyncStore.reset actually just *sets*
93+
return this.reset(newState);
8694
}
8795
}
8896

Lines changed: 99 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,99 @@
1+
2+
/*
3+
Copyright 2022 The Matrix.org Foundation C.I.C.
4+
5+
Licensed under the Apache License, Version 2.0 (the "License");
6+
you may not use this file except in compliance with the License.
7+
You may obtain a copy of the License at
8+
9+
http://www.apache.org/licenses/LICENSE-2.0
10+
11+
Unless required by applicable law or agreed to in writing, software
12+
distributed under the License is distributed on an "AS IS" BASIS,
13+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
See the License for the specific language governing permissions and
15+
limitations under the License.
16+
*/
17+
18+
import { MatrixClient } from "matrix-js-sdk";
19+
20+
import "../skinned-sdk"; // Must be first for skinning to work
21+
import { VoiceRecording } from '../../src/audio/VoiceRecording';
22+
import { VoiceRecordingStore } from '../../src/stores/VoiceRecordingStore';
23+
import { MatrixClientPeg } from "../../src/MatrixClientPeg";
24+
import { flushPromises } from "../test-utils";
25+
26+
const stubClient = {} as undefined as MatrixClient;
27+
jest.spyOn(MatrixClientPeg, 'get').mockReturnValue(stubClient);
28+
29+
describe('VoiceRecordingStore', () => {
30+
const room1Id = '!room1:server.org';
31+
const room2Id = '!room2:server.org';
32+
const room3Id = '!room3:server.org';
33+
const room1Recording = { destroy: jest.fn() } as unknown as VoiceRecording;
34+
const room2Recording = { destroy: jest.fn() } as unknown as VoiceRecording;
35+
36+
const state = {
37+
[room1Id]: room1Recording,
38+
[room2Id]: room2Recording,
39+
[room3Id]: undefined,
40+
};
41+
42+
describe('startRecording()', () => {
43+
it('throws when roomId is falsy', () => {
44+
const store = new VoiceRecordingStore();
45+
expect(() => store.startRecording(undefined)).toThrow("Recording must be associated with a room");
46+
});
47+
48+
it('throws when room already has a recording', () => {
49+
const store = new VoiceRecordingStore();
50+
// @ts-ignore
51+
store.storeState = state;
52+
expect(() => store.startRecording(room2Id)).toThrow("A recording is already in progress");
53+
});
54+
55+
it('creates and adds recording to state', async () => {
56+
const store = new VoiceRecordingStore();
57+
const result = store.startRecording(room2Id);
58+
59+
await flushPromises();
60+
61+
expect(result).toBeInstanceOf(VoiceRecording);
62+
expect(store.getActiveRecording(room2Id)).toEqual(result);
63+
});
64+
});
65+
66+
describe('disposeRecording()', () => {
67+
it('destroys recording for a room if it exists in state', async () => {
68+
const store = new VoiceRecordingStore();
69+
// @ts-ignore
70+
store.storeState = state;
71+
72+
await store.disposeRecording(room1Id);
73+
74+
expect(room1Recording.destroy).toHaveBeenCalled();
75+
});
76+
77+
it('removes room from state when it has a recording', async () => {
78+
const store = new VoiceRecordingStore();
79+
// @ts-ignore
80+
store.storeState = state;
81+
82+
await store.disposeRecording(room2Id);
83+
84+
expect(store.getActiveRecording(room2Id)).toBeFalsy();
85+
});
86+
87+
it('removes room from state when it has a falsy recording', async () => {
88+
const store = new VoiceRecordingStore();
89+
// @ts-ignore
90+
store.storeState = state;
91+
92+
await store.disposeRecording(room3Id);
93+
94+
expect(store.getActiveRecording(room1Id)).toEqual(room1Recording);
95+
expect(store.getActiveRecording(room2Id)).toEqual(room2Recording);
96+
expect(store.getActiveRecording(room3Id)).toBeFalsy();
97+
});
98+
});
99+
});

0 commit comments

Comments
 (0)