Confirm listen to a broadcast while recording (#9831)
This commit is contained in:
parent
91e078d96b
commit
0f7a2ce6df
20 changed files with 213 additions and 29 deletions
|
@ -26,6 +26,7 @@ import {
|
|||
VoiceBroadcastRecording,
|
||||
VoiceBroadcastPlaybackBody,
|
||||
VoiceBroadcastPlayback,
|
||||
VoiceBroadcastRecordingsStore,
|
||||
} from "../../../src/voice-broadcast";
|
||||
import { stubClient, wrapInSdkContext } from "../../test-utils";
|
||||
import { mkVoiceBroadcastInfoStateEvent } from "../utils/test-utils";
|
||||
|
@ -91,7 +92,7 @@ describe("VoiceBroadcastBody", () => {
|
|||
);
|
||||
room.addEventsToTimeline([infoEvent], true, room.getLiveTimeline());
|
||||
testRecording = new VoiceBroadcastRecording(infoEvent, client);
|
||||
testPlayback = new VoiceBroadcastPlayback(infoEvent, client);
|
||||
testPlayback = new VoiceBroadcastPlayback(infoEvent, client, new VoiceBroadcastRecordingsStore());
|
||||
mocked(VoiceBroadcastRecordingBody).mockImplementation(({ recording }): ReactElement | null => {
|
||||
if (testRecording === recording) {
|
||||
return <div data-testid="voice-broadcast-recording-body" />;
|
||||
|
|
|
@ -32,6 +32,7 @@ import { stubClient } from "../../../test-utils";
|
|||
import { mkVoiceBroadcastInfoStateEvent } from "../../utils/test-utils";
|
||||
import dis from "../../../../src/dispatcher/dispatcher";
|
||||
import { Action } from "../../../../src/dispatcher/actions";
|
||||
import { SdkContextClass } from "../../../../src/contexts/SDKContext";
|
||||
|
||||
jest.mock("../../../../src/dispatcher/dispatcher");
|
||||
|
||||
|
@ -66,7 +67,11 @@ describe("VoiceBroadcastPlaybackBody", () => {
|
|||
});
|
||||
|
||||
beforeEach(() => {
|
||||
playback = new VoiceBroadcastPlayback(infoEvent, client);
|
||||
playback = new VoiceBroadcastPlayback(
|
||||
infoEvent,
|
||||
client,
|
||||
SdkContextClass.instance.voiceBroadcastRecordingsStore,
|
||||
);
|
||||
jest.spyOn(playback, "toggle").mockImplementation(() => Promise.resolve());
|
||||
jest.spyOn(playback, "getLiveness");
|
||||
jest.spyOn(playback, "getState");
|
||||
|
|
|
@ -66,8 +66,8 @@ describe("VoiceBroadcastPreRecordingPip", () => {
|
|||
client = stubClient();
|
||||
room = new Room("!room@example.com", client, client.getUserId() || "");
|
||||
sender = new RoomMember(room.roomId, client.getUserId() || "");
|
||||
playbacksStore = new VoiceBroadcastPlaybacksStore();
|
||||
recordingsStore = new VoiceBroadcastRecordingsStore();
|
||||
playbacksStore = new VoiceBroadcastPlaybacksStore(recordingsStore);
|
||||
mocked(requestMediaPermissions).mockResolvedValue({
|
||||
getTracks: (): Array<MediaStreamTrack> => [],
|
||||
} as unknown as MediaStream);
|
||||
|
|
|
@ -29,6 +29,7 @@ import {
|
|||
} from "../../../../src/voice-broadcast";
|
||||
import { stubClient } from "../../../test-utils";
|
||||
import { mkVoiceBroadcastInfoStateEvent } from "../../utils/test-utils";
|
||||
import { SdkContextClass } from "../../../../src/contexts/SDKContext";
|
||||
|
||||
// mock RoomAvatar, because it is doing too much fancy stuff
|
||||
jest.mock("../../../../src/components/views/avatars/RoomAvatar", () => ({
|
||||
|
@ -60,7 +61,11 @@ describe("<VoiceBroadcastSmallPlaybackBody />", () => {
|
|||
});
|
||||
|
||||
beforeEach(() => {
|
||||
playback = new VoiceBroadcastPlayback(infoEvent, client);
|
||||
playback = new VoiceBroadcastPlayback(
|
||||
infoEvent,
|
||||
client,
|
||||
SdkContextClass.instance.voiceBroadcastRecordingsStore,
|
||||
);
|
||||
jest.spyOn(playback, "toggle").mockImplementation(() => Promise.resolve());
|
||||
jest.spyOn(playback, "getLiveness");
|
||||
jest.spyOn(playback, "getState");
|
||||
|
|
|
@ -15,10 +15,13 @@ limitations under the License.
|
|||
*/
|
||||
|
||||
import { mocked } from "jest-mock";
|
||||
import { screen } from "@testing-library/react";
|
||||
import userEvent from "@testing-library/user-event";
|
||||
import { MatrixClient, MatrixEvent, Room } from "matrix-js-sdk/src/matrix";
|
||||
|
||||
import { Playback, PlaybackState } from "../../../src/audio/Playback";
|
||||
import { PlaybackManager } from "../../../src/audio/PlaybackManager";
|
||||
import { SdkContextClass } from "../../../src/contexts/SDKContext";
|
||||
import { MediaEventHelper } from "../../../src/utils/MediaEventHelper";
|
||||
import {
|
||||
VoiceBroadcastInfoState,
|
||||
|
@ -26,6 +29,7 @@ import {
|
|||
VoiceBroadcastPlayback,
|
||||
VoiceBroadcastPlaybackEvent,
|
||||
VoiceBroadcastPlaybackState,
|
||||
VoiceBroadcastRecording,
|
||||
} from "../../../src/voice-broadcast";
|
||||
import { flushPromises, stubClient } from "../../test-utils";
|
||||
import { createTestPlayback } from "../../test-utils/audio";
|
||||
|
@ -65,6 +69,17 @@ describe("VoiceBroadcastPlayback", () => {
|
|||
let chunk2Playback: Playback;
|
||||
let chunk3Playback: Playback;
|
||||
|
||||
const queryConfirmListeningDialog = () => {
|
||||
return screen.queryByText(
|
||||
"If you start listening to this live broadcast, your current live broadcast recording will be ended.",
|
||||
);
|
||||
};
|
||||
|
||||
const waitForDialog = async () => {
|
||||
await flushPromises();
|
||||
await flushPromises();
|
||||
};
|
||||
|
||||
const itShouldSetTheStateTo = (state: VoiceBroadcastPlaybackState) => {
|
||||
it(`should set the state to ${state}`, () => {
|
||||
expect(playback.getState()).toBe(state);
|
||||
|
@ -119,7 +134,11 @@ describe("VoiceBroadcastPlayback", () => {
|
|||
};
|
||||
|
||||
const mkPlayback = async () => {
|
||||
const playback = new VoiceBroadcastPlayback(infoEvent, client);
|
||||
const playback = new VoiceBroadcastPlayback(
|
||||
infoEvent,
|
||||
client,
|
||||
SdkContextClass.instance.voiceBroadcastRecordingsStore,
|
||||
);
|
||||
jest.spyOn(playback, "removeAllListeners");
|
||||
jest.spyOn(playback, "destroy");
|
||||
playback.on(VoiceBroadcastPlaybackEvent.StateChanged, onStateChanged);
|
||||
|
@ -178,7 +197,11 @@ describe("VoiceBroadcastPlayback", () => {
|
|||
onStateChanged = jest.fn();
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
afterEach(async () => {
|
||||
SdkContextClass.instance.voiceBroadcastPlaybacksStore.getCurrent()?.stop();
|
||||
SdkContextClass.instance.voiceBroadcastPlaybacksStore.clearCurrent();
|
||||
await SdkContextClass.instance.voiceBroadcastRecordingsStore.getCurrent()?.stop();
|
||||
SdkContextClass.instance.voiceBroadcastRecordingsStore.clearCurrent();
|
||||
playback.destroy();
|
||||
});
|
||||
|
||||
|
@ -347,6 +370,59 @@ describe("VoiceBroadcastPlayback", () => {
|
|||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe("and currently recording a broadcast", () => {
|
||||
let recording: VoiceBroadcastRecording;
|
||||
|
||||
beforeEach(async () => {
|
||||
recording = new VoiceBroadcastRecording(
|
||||
mkVoiceBroadcastInfoStateEvent(
|
||||
roomId,
|
||||
VoiceBroadcastInfoState.Started,
|
||||
client.getSafeUserId(),
|
||||
client.deviceId,
|
||||
),
|
||||
client,
|
||||
);
|
||||
jest.spyOn(recording, "stop");
|
||||
SdkContextClass.instance.voiceBroadcastRecordingsStore.setCurrent(recording);
|
||||
playback.start();
|
||||
await waitForDialog();
|
||||
});
|
||||
|
||||
it("should display a confirm modal", () => {
|
||||
expect(queryConfirmListeningDialog()).toBeInTheDocument();
|
||||
});
|
||||
|
||||
describe("when confirming the dialog", () => {
|
||||
beforeEach(async () => {
|
||||
await userEvent.click(screen.getByText("Yes, end my recording"));
|
||||
});
|
||||
|
||||
it("should stop the recording", () => {
|
||||
expect(recording.stop).toHaveBeenCalled();
|
||||
expect(SdkContextClass.instance.voiceBroadcastRecordingsStore.getCurrent()).toBeNull();
|
||||
});
|
||||
|
||||
it("should not start the playback", () => {
|
||||
expect(playback.getState()).toBe(VoiceBroadcastPlaybackState.Playing);
|
||||
});
|
||||
});
|
||||
|
||||
describe("when not confirming the dialog", () => {
|
||||
beforeEach(async () => {
|
||||
await userEvent.click(screen.getByText("No"));
|
||||
});
|
||||
|
||||
it("should not stop the recording", () => {
|
||||
expect(recording.stop).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it("should start the playback", () => {
|
||||
expect(playback.getState()).toBe(VoiceBroadcastPlaybackState.Stopped);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe("when there is a stopped voice broadcast", () => {
|
||||
|
@ -375,6 +451,12 @@ describe("VoiceBroadcastPlayback", () => {
|
|||
expect(chunk2Playback.play).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
describe("and calling start again", () => {
|
||||
it("should not play the first chunk a second time", () => {
|
||||
expect(chunk1Playback.play).toHaveBeenCalledTimes(1);
|
||||
});
|
||||
});
|
||||
|
||||
describe("and the chunk playback progresses", () => {
|
||||
beforeEach(() => {
|
||||
chunk1Playback.clockInfo.liveData.update([11]);
|
|
@ -40,8 +40,8 @@ describe("VoiceBroadcastPreRecording", () => {
|
|||
client = stubClient();
|
||||
room = new Room(roomId, client, client.getUserId() || "");
|
||||
sender = new RoomMember(roomId, client.getUserId() || "");
|
||||
playbacksStore = new VoiceBroadcastPlaybacksStore();
|
||||
recordingsStore = new VoiceBroadcastRecordingsStore();
|
||||
playbacksStore = new VoiceBroadcastPlaybacksStore(recordingsStore);
|
||||
});
|
||||
|
||||
beforeEach(() => {
|
||||
|
|
|
@ -24,6 +24,7 @@ import {
|
|||
VoiceBroadcastPlaybacksStore,
|
||||
VoiceBroadcastPlaybacksStoreEvent,
|
||||
VoiceBroadcastPlaybackState,
|
||||
VoiceBroadcastRecordingsStore,
|
||||
} from "../../../src/voice-broadcast";
|
||||
import { mkStubRoom, stubClient } from "../../test-utils";
|
||||
import { mkVoiceBroadcastInfoStateEvent } from "../utils/test-utils";
|
||||
|
@ -59,12 +60,13 @@ describe("VoiceBroadcastPlaybacksStore", () => {
|
|||
|
||||
infoEvent1 = mkVoiceBroadcastInfoStateEvent(roomId, VoiceBroadcastInfoState.Started, userId, deviceId);
|
||||
infoEvent2 = mkVoiceBroadcastInfoStateEvent(roomId, VoiceBroadcastInfoState.Started, userId, deviceId);
|
||||
playback1 = new VoiceBroadcastPlayback(infoEvent1, client);
|
||||
const recordings = new VoiceBroadcastRecordingsStore();
|
||||
playback1 = new VoiceBroadcastPlayback(infoEvent1, client, recordings);
|
||||
jest.spyOn(playback1, "off");
|
||||
playback2 = new VoiceBroadcastPlayback(infoEvent2, client);
|
||||
playback2 = new VoiceBroadcastPlayback(infoEvent2, client, recordings);
|
||||
jest.spyOn(playback2, "off");
|
||||
|
||||
playbacks = new VoiceBroadcastPlaybacksStore();
|
||||
playbacks = new VoiceBroadcastPlaybacksStore(recordings);
|
||||
jest.spyOn(playbacks, "removeAllListeners");
|
||||
onCurrentChanged = jest.fn();
|
||||
playbacks.on(VoiceBroadcastPlaybacksStoreEvent.CurrentChanged, onCurrentChanged);
|
||||
|
|
|
@ -25,8 +25,6 @@ import {
|
|||
} from "../../../src/voice-broadcast";
|
||||
import { stubClient } from "../../test-utils";
|
||||
|
||||
jest.mock("../../../src/voice-broadcast/stores/VoiceBroadcastRecordingsStore");
|
||||
|
||||
describe("VoiceBroadcastPreRecordingStore", () => {
|
||||
const roomId = "!room:example.com";
|
||||
let client: MatrixClient;
|
||||
|
@ -41,8 +39,8 @@ describe("VoiceBroadcastPreRecordingStore", () => {
|
|||
client = stubClient();
|
||||
room = new Room(roomId, client, client.getUserId() || "");
|
||||
sender = new RoomMember(roomId, client.getUserId() || "");
|
||||
playbacksStore = new VoiceBroadcastPlaybacksStore();
|
||||
recordingsStore = new VoiceBroadcastRecordingsStore();
|
||||
playbacksStore = new VoiceBroadcastPlaybacksStore(recordingsStore);
|
||||
});
|
||||
|
||||
beforeEach(() => {
|
||||
|
|
|
@ -20,6 +20,7 @@ import {
|
|||
VoiceBroadcastInfoState,
|
||||
VoiceBroadcastPlayback,
|
||||
VoiceBroadcastPlaybacksStore,
|
||||
VoiceBroadcastRecordingsStore,
|
||||
} from "../../../src/voice-broadcast";
|
||||
import { pauseNonLiveBroadcastFromOtherRoom } from "../../../src/voice-broadcast/utils/pauseNonLiveBroadcastFromOtherRoom";
|
||||
import { stubClient } from "../../test-utils";
|
||||
|
@ -32,6 +33,7 @@ describe("pauseNonLiveBroadcastFromOtherRoom", () => {
|
|||
let client: MatrixClient;
|
||||
let playback: VoiceBroadcastPlayback;
|
||||
let playbacks: VoiceBroadcastPlaybacksStore;
|
||||
let recordings: VoiceBroadcastRecordingsStore;
|
||||
|
||||
const mkPlayback = (infoState: VoiceBroadcastInfoState, roomId: string): VoiceBroadcastPlayback => {
|
||||
const infoEvent = mkVoiceBroadcastInfoStateEvent(
|
||||
|
@ -40,7 +42,7 @@ describe("pauseNonLiveBroadcastFromOtherRoom", () => {
|
|||
client.getSafeUserId(),
|
||||
client.getDeviceId()!,
|
||||
);
|
||||
const playback = new VoiceBroadcastPlayback(infoEvent, client);
|
||||
const playback = new VoiceBroadcastPlayback(infoEvent, client, recordings);
|
||||
jest.spyOn(playback, "pause");
|
||||
playbacks.setCurrent(playback);
|
||||
return playback;
|
||||
|
@ -49,7 +51,8 @@ describe("pauseNonLiveBroadcastFromOtherRoom", () => {
|
|||
beforeEach(() => {
|
||||
client = stubClient();
|
||||
room = new Room(roomId, client, client.getSafeUserId());
|
||||
playbacks = new VoiceBroadcastPlaybacksStore();
|
||||
recordings = new VoiceBroadcastRecordingsStore();
|
||||
playbacks = new VoiceBroadcastPlaybacksStore(recordings);
|
||||
jest.spyOn(playbacks, "clearCurrent");
|
||||
});
|
||||
|
||||
|
|
|
@ -80,10 +80,10 @@ describe("setUpVoiceBroadcastPreRecording", () => {
|
|||
);
|
||||
preRecording = null;
|
||||
preRecordingStore = new VoiceBroadcastPreRecordingStore();
|
||||
playback = new VoiceBroadcastPlayback(infoEvent, client);
|
||||
jest.spyOn(playback, "pause");
|
||||
playbacksStore = new VoiceBroadcastPlaybacksStore();
|
||||
recordingsStore = new VoiceBroadcastRecordingsStore();
|
||||
playback = new VoiceBroadcastPlayback(infoEvent, client, recordingsStore);
|
||||
jest.spyOn(playback, "pause");
|
||||
playbacksStore = new VoiceBroadcastPlaybacksStore(recordingsStore);
|
||||
});
|
||||
|
||||
describe("when the preconditions fail", () => {
|
||||
|
|
|
@ -84,7 +84,7 @@ describe("startNewVoiceBroadcastRecording", () => {
|
|||
skey: "",
|
||||
});
|
||||
|
||||
playbacksStore = new VoiceBroadcastPlaybacksStore();
|
||||
playbacksStore = new VoiceBroadcastPlaybacksStore(recordingsStore);
|
||||
recordingsStore = {
|
||||
setCurrent: jest.fn(),
|
||||
getCurrent: jest.fn(),
|
||||
|
@ -112,7 +112,7 @@ describe("startNewVoiceBroadcastRecording", () => {
|
|||
let playback: VoiceBroadcastPlayback;
|
||||
|
||||
beforeEach(() => {
|
||||
playback = new VoiceBroadcastPlayback(infoEvent, client);
|
||||
playback = new VoiceBroadcastPlayback(infoEvent, client, recordingsStore);
|
||||
jest.spyOn(playback, "pause");
|
||||
playbacksStore.setCurrent(playback);
|
||||
});
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue