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

bugfix: fix an issue where the Notifier would incorrectly fire for non-timeline events #9664

Merged
merged 12 commits into from
Dec 1, 2022
15 changes: 12 additions & 3 deletions src/Notifier.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ import {
PermissionChanged as PermissionChangedEvent,
} from "@matrix-org/analytics-events/types/typescript/PermissionChanged";
import { ISyncStateData, SyncState } from "matrix-js-sdk/src/sync";
import { IRoomTimelineData } from "matrix-js-sdk/src/matrix";

import { MatrixClientPeg } from './MatrixClientPeg';
import { PosthogAnalytics } from "./PosthogAnalytics";
Expand Down Expand Up @@ -217,7 +218,7 @@ export const Notifier = {
this.boundOnRoomReceipt = this.boundOnRoomReceipt || this.onRoomReceipt.bind(this);
this.boundOnEventDecrypted = this.boundOnEventDecrypted || this.onEventDecrypted.bind(this);

MatrixClientPeg.get().on(ClientEvent.Event, this.boundOnEvent);
MatrixClientPeg.get().on(RoomEvent.Timeline, this.boundOnEvent);
MatrixClientPeg.get().on(RoomEvent.Receipt, this.boundOnRoomReceipt);
MatrixClientPeg.get().on(MatrixEventEvent.Decrypted, this.boundOnEventDecrypted);
MatrixClientPeg.get().on(ClientEvent.Sync, this.boundOnSyncStateChange);
Expand All @@ -227,7 +228,7 @@ export const Notifier = {

stop: function(this: typeof Notifier) {
if (MatrixClientPeg.get()) {
MatrixClientPeg.get().removeListener(ClientEvent.Event, this.boundOnEvent);
MatrixClientPeg.get().removeListener(RoomEvent.Timeline, this.boundOnEvent);
MatrixClientPeg.get().removeListener(RoomEvent.Receipt, this.boundOnRoomReceipt);
MatrixClientPeg.get().removeListener(MatrixEventEvent.Decrypted, this.boundOnEventDecrypted);
MatrixClientPeg.get().removeListener(ClientEvent.Sync, this.boundOnSyncStateChange);
Expand Down Expand Up @@ -368,7 +369,15 @@ export const Notifier = {
}
},

onEvent: function(this: typeof Notifier, ev: MatrixEvent) {
onEvent: function(
this: typeof Notifier,
ev: MatrixEvent,
room: Room | undefined,
toStartOfTimeline: boolean | undefined,
removed: boolean,
data: IRoomTimelineData,
t3chguy marked this conversation as resolved.
Show resolved Hide resolved
) {
if (!data.liveEvent) return; // on notify for new things, not old.
kegsay marked this conversation as resolved.
Show resolved Hide resolved
if (!this.isSyncing) return; // don't alert for any messages initially
if (ev.getSender() === MatrixClientPeg.get().getUserId()) return;

Expand Down
27 changes: 17 additions & 10 deletions test/Notifier-test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ limitations under the License.

import { mocked, MockedObject } from "jest-mock";
import { ClientEvent, MatrixClient } from "matrix-js-sdk/src/client";
import { Room } from "matrix-js-sdk/src/models/room";
import { Room, RoomEvent } 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";
Expand Down Expand Up @@ -60,12 +60,19 @@ describe("Notifier", () => {
let mockClient: MockedObject<MatrixClient>;
let testRoom: Room;
let accountDataEventKey: string;
let accountDataStore = {};
let accountDataStore: Record<string, MatrixEvent | undefined> = {};

let mockSettings: Record<string, boolean> = {};

const userId = "@bob:example.org";

const emitLiveEvent = (event: MatrixEvent): void => {
mockClient!.emit(RoomEvent.Timeline, event, testRoom, false, false, {
liveEvent: true,
timeline: testRoom.getLiveTimeline(),
});
};

beforeEach(() => {
accountDataStore = {};
mockClient = getMockClientWithEventEmitter({
Expand Down Expand Up @@ -150,7 +157,7 @@ describe("Notifier", () => {
});

it('does not create notifications before syncing has started', () => {
mockClient!.emit(ClientEvent.Event, event);
emitLiveEvent(event);

expect(MockPlatform.displayNotification).not.toHaveBeenCalled();
expect(MockPlatform.loudNotification).not.toHaveBeenCalled();
Expand All @@ -160,7 +167,7 @@ describe("Notifier", () => {
const ownEvent = new MatrixEvent({ sender: userId });

mockClient!.emit(ClientEvent.Sync, SyncState.Syncing, null);
mockClient!.emit(ClientEvent.Event, ownEvent);
emitLiveEvent(ownEvent);

expect(MockPlatform.displayNotification).not.toHaveBeenCalled();
expect(MockPlatform.loudNotification).not.toHaveBeenCalled();
Expand All @@ -175,15 +182,15 @@ describe("Notifier", () => {
});

mockClient!.emit(ClientEvent.Sync, SyncState.Syncing, null);
mockClient!.emit(ClientEvent.Event, event);
emitLiveEvent(event);

expect(MockPlatform.displayNotification).not.toHaveBeenCalled();
expect(MockPlatform.loudNotification).not.toHaveBeenCalled();
});

it('creates desktop notification when enabled', () => {
mockClient!.emit(ClientEvent.Sync, SyncState.Syncing, null);
mockClient!.emit(ClientEvent.Event, event);
emitLiveEvent(event);

expect(MockPlatform.displayNotification).toHaveBeenCalledWith(
testRoom.name,
Expand All @@ -196,7 +203,7 @@ describe("Notifier", () => {

it('creates a loud notification when enabled', () => {
mockClient!.emit(ClientEvent.Sync, SyncState.Syncing, null);
mockClient!.emit(ClientEvent.Event, event);
emitLiveEvent(event);

expect(MockPlatform.loudNotification).toHaveBeenCalledWith(
event, testRoom,
Expand All @@ -212,7 +219,7 @@ describe("Notifier", () => {
});

mockClient!.emit(ClientEvent.Sync, SyncState.Syncing, null);
mockClient!.emit(ClientEvent.Event, event);
emitLiveEvent(event);

// desktop notification created
expect(MockPlatform.displayNotification).toHaveBeenCalled();
Expand Down Expand Up @@ -267,7 +274,7 @@ describe("Notifier", () => {
notify: true,
tweaks: {},
});

Notifier.start();
Notifier.onSyncStateChange(SyncState.Syncing);
});

Expand All @@ -283,7 +290,7 @@ describe("Notifier", () => {
content: {},
event: true,
});
Notifier.onEvent(callEvent);
emitLiveEvent(callEvent);
return callEvent;
};

Expand Down