163 lines
		
	
	
		
			5.7 KiB
		
	
	
	
		
			TypeScript
		
	
	
			
		
		
	
	
			163 lines
		
	
	
		
			5.7 KiB
		
	
	
	
		
			TypeScript
		
	
	
/*
 | 
						|
Copyright 2024 New Vector Ltd.
 | 
						|
Copyright 2022 The Matrix.org Foundation C.I.C.
 | 
						|
 | 
						|
SPDX-License-Identifier: AGPL-3.0-only OR GPL-3.0-only
 | 
						|
Please see LICENSE files in the repository root for full details.
 | 
						|
*/
 | 
						|
 | 
						|
import { mocked } from "jest-mock";
 | 
						|
import { MatrixClient, MatrixEvent, Room } from "matrix-js-sdk/src/matrix";
 | 
						|
 | 
						|
import {
 | 
						|
    VoiceBroadcastInfoState,
 | 
						|
    VoiceBroadcastPlayback,
 | 
						|
    VoiceBroadcastPlaybackEvent,
 | 
						|
    VoiceBroadcastPlaybacksStore,
 | 
						|
    VoiceBroadcastPlaybacksStoreEvent,
 | 
						|
    VoiceBroadcastPlaybackState,
 | 
						|
    VoiceBroadcastRecordingsStore,
 | 
						|
} from "../../../src/voice-broadcast";
 | 
						|
import { mkStubRoom, stubClient } from "../../test-utils";
 | 
						|
import { mkVoiceBroadcastInfoStateEvent } from "../utils/test-utils";
 | 
						|
 | 
						|
describe("VoiceBroadcastPlaybacksStore", () => {
 | 
						|
    const roomId = "!room:example.com";
 | 
						|
    let client: MatrixClient;
 | 
						|
    let userId: string;
 | 
						|
    let deviceId: string;
 | 
						|
    let room: Room;
 | 
						|
    let infoEvent1: MatrixEvent;
 | 
						|
    let infoEvent2: MatrixEvent;
 | 
						|
    let playback1: VoiceBroadcastPlayback;
 | 
						|
    let playback2: VoiceBroadcastPlayback;
 | 
						|
    let playbacks: VoiceBroadcastPlaybacksStore;
 | 
						|
    let onCurrentChanged: (playback: VoiceBroadcastPlayback | null) => void;
 | 
						|
 | 
						|
    beforeEach(() => {
 | 
						|
        client = stubClient();
 | 
						|
        userId = client.getUserId() || "";
 | 
						|
        deviceId = client.getDeviceId() || "";
 | 
						|
        mocked(client.relations).mockClear();
 | 
						|
        mocked(client.relations).mockResolvedValue({ events: [] });
 | 
						|
 | 
						|
        room = mkStubRoom(roomId, "test room", client);
 | 
						|
        mocked(client.getRoom).mockImplementation((roomId: string): Room | null => {
 | 
						|
            if (roomId === room.roomId) {
 | 
						|
                return room;
 | 
						|
            }
 | 
						|
 | 
						|
            return null;
 | 
						|
        });
 | 
						|
 | 
						|
        infoEvent1 = mkVoiceBroadcastInfoStateEvent(roomId, VoiceBroadcastInfoState.Started, userId, deviceId);
 | 
						|
        infoEvent2 = mkVoiceBroadcastInfoStateEvent(roomId, VoiceBroadcastInfoState.Started, userId, deviceId);
 | 
						|
        const recordings = new VoiceBroadcastRecordingsStore();
 | 
						|
        playback1 = new VoiceBroadcastPlayback(infoEvent1, client, recordings);
 | 
						|
        jest.spyOn(playback1, "off");
 | 
						|
        playback2 = new VoiceBroadcastPlayback(infoEvent2, client, recordings);
 | 
						|
        jest.spyOn(playback2, "off");
 | 
						|
 | 
						|
        playbacks = new VoiceBroadcastPlaybacksStore(recordings);
 | 
						|
        jest.spyOn(playbacks, "removeAllListeners");
 | 
						|
        onCurrentChanged = jest.fn();
 | 
						|
        playbacks.on(VoiceBroadcastPlaybacksStoreEvent.CurrentChanged, onCurrentChanged);
 | 
						|
    });
 | 
						|
 | 
						|
    afterEach(() => {
 | 
						|
        playbacks.off(VoiceBroadcastPlaybacksStoreEvent.CurrentChanged, onCurrentChanged);
 | 
						|
    });
 | 
						|
 | 
						|
    describe("when setting a current Voice Broadcast playback", () => {
 | 
						|
        beforeEach(() => {
 | 
						|
            playbacks.setCurrent(playback1);
 | 
						|
        });
 | 
						|
 | 
						|
        it("should return it as current", () => {
 | 
						|
            expect(playbacks.getCurrent()).toBe(playback1);
 | 
						|
        });
 | 
						|
 | 
						|
        it("should return it by id", () => {
 | 
						|
            expect(playbacks.getByInfoEvent(infoEvent1, client)).toBe(playback1);
 | 
						|
        });
 | 
						|
 | 
						|
        it("should emit a CurrentChanged event", () => {
 | 
						|
            expect(onCurrentChanged).toHaveBeenCalledWith(playback1);
 | 
						|
        });
 | 
						|
 | 
						|
        describe("and setting the same again", () => {
 | 
						|
            beforeEach(() => {
 | 
						|
                mocked(onCurrentChanged).mockClear();
 | 
						|
                playbacks.setCurrent(playback1);
 | 
						|
            });
 | 
						|
 | 
						|
            it("should not emit a CurrentChanged event", () => {
 | 
						|
                expect(onCurrentChanged).not.toHaveBeenCalled();
 | 
						|
            });
 | 
						|
        });
 | 
						|
 | 
						|
        describe("and setting another playback and start both", () => {
 | 
						|
            beforeEach(() => {
 | 
						|
                playbacks.setCurrent(playback2);
 | 
						|
                playback1.start();
 | 
						|
                playback2.start();
 | 
						|
            });
 | 
						|
 | 
						|
            it("should set playback1 to paused", () => {
 | 
						|
                expect(playback1.getState()).toBe(VoiceBroadcastPlaybackState.Paused);
 | 
						|
            });
 | 
						|
 | 
						|
            it("should set playback2 to buffering", () => {
 | 
						|
                // buffering because there are no chunks, yet
 | 
						|
                expect(playback2.getState()).toBe(VoiceBroadcastPlaybackState.Buffering);
 | 
						|
            });
 | 
						|
 | 
						|
            describe("and calling destroy", () => {
 | 
						|
                beforeEach(() => {
 | 
						|
                    playbacks.destroy();
 | 
						|
                });
 | 
						|
 | 
						|
                it("should remove all listeners", () => {
 | 
						|
                    expect(playbacks.removeAllListeners).toHaveBeenCalled();
 | 
						|
                });
 | 
						|
 | 
						|
                it("should deregister the listeners on the playbacks", () => {
 | 
						|
                    expect(playback1.off).toHaveBeenCalledWith(
 | 
						|
                        VoiceBroadcastPlaybackEvent.StateChanged,
 | 
						|
                        expect.any(Function),
 | 
						|
                    );
 | 
						|
                    expect(playback2.off).toHaveBeenCalledWith(
 | 
						|
                        VoiceBroadcastPlaybackEvent.StateChanged,
 | 
						|
                        expect.any(Function),
 | 
						|
                    );
 | 
						|
                });
 | 
						|
            });
 | 
						|
        });
 | 
						|
    });
 | 
						|
 | 
						|
    describe("getByInfoEventId", () => {
 | 
						|
        let returnedPlayback: VoiceBroadcastPlayback;
 | 
						|
 | 
						|
        describe("when retrieving a known playback", () => {
 | 
						|
            beforeEach(() => {
 | 
						|
                playbacks.setCurrent(playback1);
 | 
						|
                returnedPlayback = playbacks.getByInfoEvent(infoEvent1, client);
 | 
						|
            });
 | 
						|
 | 
						|
            it("should return the playback", () => {
 | 
						|
                expect(returnedPlayback).toBe(playback1);
 | 
						|
            });
 | 
						|
        });
 | 
						|
 | 
						|
        describe("when retrieving an unknown playback", () => {
 | 
						|
            beforeEach(() => {
 | 
						|
                returnedPlayback = playbacks.getByInfoEvent(infoEvent1, client);
 | 
						|
            });
 | 
						|
 | 
						|
            it("should return the playback", () => {
 | 
						|
                expect(returnedPlayback.infoEvent).toBe(infoEvent1);
 | 
						|
            });
 | 
						|
        });
 | 
						|
    });
 | 
						|
});
 |