180 lines
5.9 KiB
TypeScript
180 lines
5.9 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 { ClientEvent, MatrixClient, MatrixEvent, RelationType, Room, SyncState } from "matrix-js-sdk/src/matrix";
|
|
|
|
import {
|
|
VoiceBroadcastInfoEventContent,
|
|
VoiceBroadcastInfoEventType,
|
|
VoiceBroadcastInfoState,
|
|
VoiceBroadcastResumer,
|
|
} from "../../../../src/voice-broadcast";
|
|
import { stubClient } from "../../../test-utils";
|
|
import { mkVoiceBroadcastInfoStateEvent } from "./test-utils";
|
|
|
|
describe("VoiceBroadcastResumer", () => {
|
|
const roomId = "!room:example.com";
|
|
let client: MatrixClient;
|
|
let room: Room;
|
|
let resumer: VoiceBroadcastResumer;
|
|
let startedInfoEvent: MatrixEvent;
|
|
let pausedInfoEvent: MatrixEvent;
|
|
|
|
const itShouldNotSendAStateEvent = (): void => {
|
|
it("should not send a state event", () => {
|
|
expect(client.sendStateEvent).not.toHaveBeenCalled();
|
|
});
|
|
};
|
|
|
|
const itShouldSendAStoppedStateEvent = (): void => {
|
|
it("should send a stopped state event", () => {
|
|
expect(client.sendStateEvent).toHaveBeenCalledWith(
|
|
startedInfoEvent.getRoomId(),
|
|
VoiceBroadcastInfoEventType,
|
|
{
|
|
"device_id": client.getDeviceId(),
|
|
"state": VoiceBroadcastInfoState.Stopped,
|
|
"m.relates_to": {
|
|
rel_type: RelationType.Reference,
|
|
event_id: startedInfoEvent.getId(),
|
|
},
|
|
} as VoiceBroadcastInfoEventContent,
|
|
client.getUserId()!,
|
|
);
|
|
});
|
|
};
|
|
|
|
const itShouldDeregisterFromTheClient = () => {
|
|
it("should deregister from the client", () => {
|
|
expect(client.off).toHaveBeenCalledWith(ClientEvent.Sync, expect.any(Function));
|
|
});
|
|
};
|
|
|
|
beforeEach(() => {
|
|
client = stubClient();
|
|
jest.spyOn(client, "off");
|
|
room = new Room(roomId, client, client.getUserId()!);
|
|
mocked(client.getRoom).mockImplementation((getRoomId: string | undefined) => {
|
|
if (getRoomId === roomId) return room;
|
|
|
|
return null;
|
|
});
|
|
mocked(client.getRooms).mockReturnValue([room]);
|
|
startedInfoEvent = mkVoiceBroadcastInfoStateEvent(
|
|
roomId,
|
|
VoiceBroadcastInfoState.Started,
|
|
client.getUserId()!,
|
|
client.getDeviceId()!,
|
|
);
|
|
pausedInfoEvent = mkVoiceBroadcastInfoStateEvent(
|
|
roomId,
|
|
VoiceBroadcastInfoState.Paused,
|
|
client.getUserId()!,
|
|
client.getDeviceId()!,
|
|
startedInfoEvent,
|
|
);
|
|
});
|
|
|
|
afterEach(() => {
|
|
jest.clearAllMocks();
|
|
});
|
|
|
|
describe("when the initial sync is completed", () => {
|
|
beforeEach(() => {
|
|
mocked(client.isInitialSyncComplete).mockReturnValue(true);
|
|
});
|
|
|
|
describe("and there is no info event", () => {
|
|
beforeEach(() => {
|
|
resumer = new VoiceBroadcastResumer(client);
|
|
});
|
|
|
|
itShouldNotSendAStateEvent();
|
|
|
|
describe("and calling destroy", () => {
|
|
beforeEach(() => {
|
|
resumer.destroy();
|
|
});
|
|
|
|
itShouldDeregisterFromTheClient();
|
|
});
|
|
});
|
|
|
|
describe("and there is a started info event", () => {
|
|
beforeEach(() => {
|
|
room.currentState.setStateEvents([startedInfoEvent]);
|
|
});
|
|
|
|
describe("and the client knows about the user and device", () => {
|
|
beforeEach(() => {
|
|
resumer = new VoiceBroadcastResumer(client);
|
|
});
|
|
|
|
itShouldSendAStoppedStateEvent();
|
|
});
|
|
|
|
describe("and the client doesn't know about the user", () => {
|
|
beforeEach(() => {
|
|
mocked(client.getUserId).mockReturnValue(null);
|
|
resumer = new VoiceBroadcastResumer(client);
|
|
});
|
|
|
|
itShouldNotSendAStateEvent();
|
|
});
|
|
|
|
describe("and the client doesn't know about the device", () => {
|
|
beforeEach(() => {
|
|
mocked(client.getDeviceId).mockReturnValue(null);
|
|
resumer = new VoiceBroadcastResumer(client);
|
|
});
|
|
|
|
itShouldNotSendAStateEvent();
|
|
});
|
|
});
|
|
|
|
describe("and there is a paused info event", () => {
|
|
beforeEach(() => {
|
|
room.currentState.setStateEvents([pausedInfoEvent]);
|
|
resumer = new VoiceBroadcastResumer(client);
|
|
});
|
|
|
|
itShouldSendAStoppedStateEvent();
|
|
});
|
|
});
|
|
|
|
describe("when the initial sync is not completed", () => {
|
|
beforeEach(() => {
|
|
room.currentState.setStateEvents([pausedInfoEvent]);
|
|
mocked(client.isInitialSyncComplete).mockReturnValue(false);
|
|
mocked(client.getSyncState).mockReturnValue(SyncState.Prepared);
|
|
resumer = new VoiceBroadcastResumer(client);
|
|
});
|
|
|
|
itShouldNotSendAStateEvent();
|
|
|
|
describe("and a sync event appears", () => {
|
|
beforeEach(() => {
|
|
client.emit(ClientEvent.Sync, SyncState.Prepared, SyncState.Stopped);
|
|
});
|
|
|
|
itShouldNotSendAStateEvent();
|
|
|
|
describe("and the initial sync completed and a sync event appears", () => {
|
|
beforeEach(() => {
|
|
mocked(client.getSyncState).mockReturnValue(SyncState.Syncing);
|
|
client.emit(ClientEvent.Sync, SyncState.Syncing, SyncState.Prepared);
|
|
});
|
|
|
|
itShouldSendAStoppedStateEvent();
|
|
itShouldDeregisterFromTheClient();
|
|
});
|
|
});
|
|
});
|
|
});
|