1
0
mirror of https://github.com/matrix-org/matrix-react-sdk.git synced 2025-08-07 21:23:00 +03:00

Show thread notification if thread timeline is closed (#9495)

* Show thread notification if thread timeline is closed

* Simplify isViewingEventTimeline statement

Co-authored-by: Michael Telatynski <7t3chguy@gmail.com>

* Fix show desktop notifications

* Add RoomViewStore thread id assertions

* Add Notifier tests

* fix lint

* Remove it.only

Co-authored-by: Michael Telatynski <7t3chguy@gmail.com>
This commit is contained in:
Germain
2022-10-25 17:53:31 +01:00
committed by GitHub
parent d273441596
commit 306a2449e5
7 changed files with 178 additions and 21 deletions

View File

@@ -19,6 +19,7 @@ import { ClientEvent, MatrixClient } from "matrix-js-sdk/src/client";
import { Room } from "matrix-js-sdk/src/models/room";
import { MatrixEvent } from "matrix-js-sdk/src/models/event";
import { SyncState } from "matrix-js-sdk/src/sync";
import { waitFor } from "@testing-library/react";
import BasePlatform from "../src/BasePlatform";
import { ElementCall } from "../src/models/Call";
@@ -29,8 +30,15 @@ import {
createLocalNotificationSettingsIfNeeded,
getLocalNotificationAccountDataEventType,
} from "../src/utils/notifications";
import { getMockClientWithEventEmitter, mkEvent, mkRoom, mockClientMethodsUser, mockPlatformPeg } from "./test-utils";
import { getMockClientWithEventEmitter, mkEvent, mockClientMethodsUser, mockPlatformPeg } from "./test-utils";
import { IncomingCallToast } from "../src/toasts/IncomingCallToast";
import { SdkContextClass } from "../src/contexts/SDKContext";
import UserActivity from "../src/UserActivity";
import Modal from "../src/Modal";
import { mkThread } from "./test-utils/threads";
import dis from "../src/dispatcher/dispatcher";
import { ThreadPayload } from "../src/dispatcher/payloads/ThreadPayload";
import { Action } from "../src/dispatcher/actions";
jest.mock("../src/utils/notifications", () => ({
// @ts-ignore
@@ -50,10 +58,12 @@ describe("Notifier", () => {
let MockPlatform: MockedObject<BasePlatform>;
let mockClient: MockedObject<MatrixClient>;
let testRoom: MockedObject<Room>;
let testRoom: Room;
let accountDataEventKey: string;
let accountDataStore = {};
let mockSettings: Record<string, boolean> = {};
const userId = "@bob:example.org";
beforeEach(() => {
@@ -78,7 +88,7 @@ describe("Notifier", () => {
};
accountDataEventKey = getLocalNotificationAccountDataEventType(mockClient.deviceId);
testRoom = mkRoom(mockClient, roomId);
testRoom = new Room(roomId, mockClient, mockClient.getUserId());
MockPlatform = mockPlatformPeg({
supportsNotifications: jest.fn().mockReturnValue(true),
@@ -89,7 +99,9 @@ describe("Notifier", () => {
Notifier.isBodyEnabled = jest.fn().mockReturnValue(true);
mockClient.getRoom.mockReturnValue(testRoom);
mockClient.getRoom.mockImplementation(id => {
return id === roomId ? testRoom : new Room(id, mockClient, mockClient.getUserId());
});
});
describe('triggering notification from events', () => {
@@ -121,13 +133,14 @@ describe("Notifier", () => {
},
});
const enabledSettings = [
'notificationsEnabled',
'audioNotificationsEnabled',
];
mockSettings = {
'notificationsEnabled': true,
'audioNotificationsEnabled': true,
};
// enable notifications by default
jest.spyOn(SettingsStore, "getValue").mockImplementation(
settingName => enabledSettings.includes(settingName),
jest.spyOn(SettingsStore, "getValue").mockReset().mockImplementation(
settingName => mockSettings[settingName] ?? false,
);
});
@@ -253,16 +266,13 @@ describe("Notifier", () => {
});
const callOnEvent = (type?: string) => {
const callEvent = {
getContent: () => { },
getRoomId: () => roomId,
isBeingDecrypted: () => false,
isDecryptionFailure: () => false,
getSender: () => "@alice:foo",
getType: () => type ?? ElementCall.CALL_EVENT_TYPE.name,
getStateKey: () => "state_key",
} as unknown as MatrixEvent;
const callEvent = mkEvent({
type: type ?? ElementCall.CALL_EVENT_TYPE.name,
user: "@alice:foo",
room: roomId,
content: {},
event: true,
});
Notifier.onEvent(callEvent);
return callEvent;
};
@@ -345,4 +355,72 @@ describe("Notifier", () => {
expect(createLocalNotificationSettingsIfNeededMock).toHaveBeenCalled();
});
});
describe('_evaluateEvent', () => {
beforeEach(() => {
jest.spyOn(SdkContextClass.instance.roomViewStore, "getRoomId")
.mockReturnValue(testRoom.roomId);
jest.spyOn(UserActivity.sharedInstance(), "userActiveRecently")
.mockReturnValue(true);
jest.spyOn(Modal, "hasDialogs").mockReturnValue(false);
jest.spyOn(Notifier, "_displayPopupNotification").mockReset();
jest.spyOn(Notifier, "isEnabled").mockReturnValue(true);
mockClient.getPushActionsForEvent.mockReturnValue({
notify: true,
tweaks: {
sound: true,
},
});
});
it("should show a pop-up", () => {
expect(Notifier._displayPopupNotification).toHaveBeenCalledTimes(0);
Notifier._evaluateEvent(testEvent);
expect(Notifier._displayPopupNotification).toHaveBeenCalledTimes(0);
const eventFromOtherRoom = mkEvent({
event: true,
type: "m.room.message",
user: "@user1:server",
room: "!otherroom:example.org",
content: {},
});
Notifier._evaluateEvent(eventFromOtherRoom);
expect(Notifier._displayPopupNotification).toHaveBeenCalledTimes(1);
});
it("should a pop-up for thread event", async () => {
const { events, rootEvent } = mkThread({
room: testRoom,
client: mockClient,
authorId: "@bob:example.org",
participantUserIds: ["@bob:example.org"],
});
expect(Notifier._displayPopupNotification).toHaveBeenCalledTimes(0);
Notifier._evaluateEvent(rootEvent);
expect(Notifier._displayPopupNotification).toHaveBeenCalledTimes(0);
Notifier._evaluateEvent(events[1]);
expect(Notifier._displayPopupNotification).toHaveBeenCalledTimes(1);
dis.dispatch<ThreadPayload>({
action: Action.ViewThread,
thread_id: rootEvent.getId(),
});
await waitFor(() =>
expect(SdkContextClass.instance.roomViewStore.getThreadId()).toBe(rootEvent.getId()),
);
Notifier._evaluateEvent(events[1]);
expect(Notifier._displayPopupNotification).toHaveBeenCalledTimes(1);
});
});
});