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

Use findPredecessor in RoomNotifs#getUnreadNotificationCount #10067

Merged
merged 2 commits into from
Feb 3, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 5 additions & 5 deletions src/RoomNotifs.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@ limitations under the License.
import { PushProcessor } from "matrix-js-sdk/src/pushprocessor";
import { NotificationCountType } from "matrix-js-sdk/src/models/room";
import { ConditionKind, PushRuleActionName, PushRuleKind, TweakName } from "matrix-js-sdk/src/@types/PushRules";
import { EventType } from "matrix-js-sdk/src/@types/event";

import type { IPushRule } from "matrix-js-sdk/src/@types/PushRules";
import type { Room } from "matrix-js-sdk/src/models/room";
Expand All @@ -27,6 +26,7 @@ import { NotificationColor } from "./stores/notifications/NotificationColor";
import { getUnsentMessages } from "./components/structures/RoomStatusBar";
import { doesRoomHaveUnreadMessages, doesRoomOrThreadHaveUnreadMessages } from "./Unread";
import { EffectiveMembership, getEffectiveMembership } from "./utils/membership";
import SettingsStore from "./settings/SettingsStore";

export enum RoomNotifState {
AllMessagesLoud = "all_messages_loud",
Expand Down Expand Up @@ -86,11 +86,11 @@ export function getUnreadNotificationCount(room: Room, type: NotificationCountTy
// Check notification counts in the old room just in case there's some lost
// there. We only go one level down to avoid performance issues, and theory
// is that 1st generation rooms will have already been read by the 3rd generation.
const createEvent = room.currentState.getStateEvents(EventType.RoomCreate, "");
const predecessor = createEvent?.getContent().predecessor;
const msc3946ProcessDynamicPredecessor = SettingsStore.getValue("feature_dynamic_room_predecessors");
const predecessor = room.findPredecessor(msc3946ProcessDynamicPredecessor);
// Exclude threadId, as the same thread can't continue over a room upgrade
if (!threadId && predecessor) {
const oldRoomId = predecessor.room_id;
if (!threadId && predecessor?.roomId) {
const oldRoomId = predecessor.roomId;
const oldRoom = MatrixClientPeg.get().getRoom(oldRoomId);
if (oldRoom) {
// We only ever care if there's highlights in the old room. No point in
Expand Down
130 changes: 103 additions & 27 deletions test/RoomNotifs-test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,17 +17,18 @@ limitations under the License.
import { mocked } from "jest-mock";
import { PushRuleActionName, TweakName } from "matrix-js-sdk/src/@types/PushRules";
import { NotificationCountType, Room } from "matrix-js-sdk/src/models/room";
import { EventStatus, PendingEventOrdering } from "matrix-js-sdk/src/matrix";
import { EventStatus, EventType, MatrixEvent, PendingEventOrdering } from "matrix-js-sdk/src/matrix";

import type { MatrixClient } from "matrix-js-sdk/src/matrix";
import { mkEvent, mkRoom, muteRoom, stubClient } from "./test-utils";
import { mkEvent, mkRoom, muteRoom, stubClient, upsertRoomStateEvents } from "./test-utils";
import {
getRoomNotifsState,
RoomNotifState,
getUnreadNotificationCount,
determineUnreadState,
} from "../src/RoomNotifs";
import { NotificationColor } from "../src/stores/notifications/NotificationColor";
import SettingsStore from "../src/settings/SettingsStore";

describe("RoomNotifs test", () => {
let client: jest.Mocked<MatrixClient>;
Expand Down Expand Up @@ -105,36 +106,111 @@ describe("RoomNotifs test", () => {
expect(getUnreadNotificationCount(room, NotificationCountType.Highlight)).toBe(1);
});

it("counts predecessor highlight", () => {
room.setUnreadNotificationCount(NotificationCountType.Total, 2);
room.setUnreadNotificationCount(NotificationCountType.Highlight, 1);

describe("when there is a room predecessor", () => {
const OLD_ROOM_ID = "!oldRoomId:example.org";
const oldRoom = new Room(OLD_ROOM_ID, client, client.getUserId()!);
oldRoom.setUnreadNotificationCount(NotificationCountType.Total, 10);
oldRoom.setUnreadNotificationCount(NotificationCountType.Highlight, 6);
const mkCreateEvent = (predecessorId?: string): MatrixEvent => {
return mkEvent({
event: true,
type: "m.room.create",
room: ROOM_ID,
user: client.getUserId()!,
content: {
...(predecessorId ? { predecessor: { room_id: predecessorId, event_id: "$someevent" } } : {}),
creator: client.getUserId(),
room_version: "5",
},
ts: Date.now(),
});
};

const mkPredecessorEvent = (predecessorId: string): MatrixEvent => {
return mkEvent({
event: true,
type: EventType.RoomPredecessor,
room: ROOM_ID,
user: client.getUserId()!,
skey: "",
content: {
predecessor_room_id: predecessorId,
},
ts: Date.now(),
});
};

const itShouldCountPredecessorHighlightWhenThereIsAPredecessorInTheCreateEvent = (): void => {
it("and there is a predecessor in the create event, it should count predecessor highlight", () => {
room.addLiveEvents([mkCreateEvent(OLD_ROOM_ID)]);

expect(getUnreadNotificationCount(room, NotificationCountType.Total)).toBe(8);
expect(getUnreadNotificationCount(room, NotificationCountType.Highlight)).toBe(7);
});
};

const itShouldCountPredecessorHighlightWhenThereIsAPredecessorEvent = (): void => {
it("and there is a predecessor event, it should count predecessor highlight", () => {
client.getVisibleRooms();
room.addLiveEvents([mkCreateEvent(OLD_ROOM_ID)]);
upsertRoomStateEvents(room, [mkPredecessorEvent(OLD_ROOM_ID)]);

expect(getUnreadNotificationCount(room, NotificationCountType.Total)).toBe(8);
expect(getUnreadNotificationCount(room, NotificationCountType.Highlight)).toBe(7);
});
};

beforeEach(() => {
room.setUnreadNotificationCount(NotificationCountType.Total, 2);
room.setUnreadNotificationCount(NotificationCountType.Highlight, 1);

const oldRoom = new Room(OLD_ROOM_ID, client, client.getUserId()!);
oldRoom.setUnreadNotificationCount(NotificationCountType.Total, 10);
oldRoom.setUnreadNotificationCount(NotificationCountType.Highlight, 6);

client.getRoom.mockImplementation((roomId: string | undefined): Room | null => {
if (roomId === room.roomId) return room;
if (roomId === OLD_ROOM_ID) return oldRoom;
return null;
});
});

client.getRoom.mockReset().mockReturnValue(oldRoom);
describe("and dynamic room predecessors are disabled", () => {
itShouldCountPredecessorHighlightWhenThereIsAPredecessorInTheCreateEvent();
itShouldCountPredecessorHighlightWhenThereIsAPredecessorEvent();

const predecessorEvent = mkEvent({
event: true,
type: "m.room.create",
room: ROOM_ID,
user: client.getUserId()!,
content: {
creator: client.getUserId(),
room_version: "5",
predecessor: {
room_id: OLD_ROOM_ID,
event_id: "$someevent",
},
},
ts: Date.now(),
it("and there is only a predecessor event, it should not count predecessor highlight", () => {
room.addLiveEvents([mkCreateEvent()]);
upsertRoomStateEvents(room, [mkPredecessorEvent(OLD_ROOM_ID)]);

expect(getUnreadNotificationCount(room, NotificationCountType.Total)).toBe(2);
expect(getUnreadNotificationCount(room, NotificationCountType.Highlight)).toBe(1);
});
});
room.addLiveEvents([predecessorEvent]);

expect(getUnreadNotificationCount(room, NotificationCountType.Total)).toBe(8);
expect(getUnreadNotificationCount(room, NotificationCountType.Highlight)).toBe(7);
describe("and dynamic room predecessors are enabled", () => {
beforeEach(() => {
jest.spyOn(SettingsStore, "getValue").mockImplementation(
(settingName) => settingName === "feature_dynamic_room_predecessors",
);
});

itShouldCountPredecessorHighlightWhenThereIsAPredecessorInTheCreateEvent();
itShouldCountPredecessorHighlightWhenThereIsAPredecessorEvent();

it("and there is only a predecessor event, it should count predecessor highlight", () => {
room.addLiveEvents([mkCreateEvent()]);
upsertRoomStateEvents(room, [mkPredecessorEvent(OLD_ROOM_ID)]);

expect(getUnreadNotificationCount(room, NotificationCountType.Total)).toBe(8);
expect(getUnreadNotificationCount(room, NotificationCountType.Highlight)).toBe(7);
});

it("and there is an unknown room in the predecessor event, it should not count predecessor highlight", () => {
room.addLiveEvents([mkCreateEvent()]);
upsertRoomStateEvents(room, [mkPredecessorEvent("!unknon:example.com")]);

expect(getUnreadNotificationCount(room, NotificationCountType.Total)).toBe(2);
expect(getUnreadNotificationCount(room, NotificationCountType.Highlight)).toBe(1);
});
});
});

it("counts thread notification type", () => {
Expand Down