Prepare for repo merge
Signed-off-by: Michael Telatynski <7t3chguy@gmail.com>
This commit is contained in:
parent
0f670b8dc0
commit
b084ff2313
807 changed files with 0 additions and 0 deletions
616
test/unit-tests/TextForEvent-test.ts
Normal file
616
test/unit-tests/TextForEvent-test.ts
Normal file
|
@ -0,0 +1,616 @@
|
|||
/*
|
||||
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 {
|
||||
EventType,
|
||||
HistoryVisibility,
|
||||
JoinRule,
|
||||
MatrixClient,
|
||||
MatrixEvent,
|
||||
Room,
|
||||
RoomMember,
|
||||
} from "matrix-js-sdk/src/matrix";
|
||||
import { KnownMembership } from "matrix-js-sdk/src/types";
|
||||
import { render } from "jest-matrix-react";
|
||||
import { ReactElement } from "react";
|
||||
import { Mocked, mocked } from "jest-mock";
|
||||
|
||||
import { textForEvent } from "../src/TextForEvent";
|
||||
import SettingsStore from "../src/settings/SettingsStore";
|
||||
import { createTestClient, stubClient } from "./test-utils";
|
||||
import { MatrixClientPeg } from "../src/MatrixClientPeg";
|
||||
import UserIdentifierCustomisations from "../src/customisations/UserIdentifier";
|
||||
import { ElementCall } from "../src/models/Call";
|
||||
import { getSenderName } from "../src/utils/event/getSenderName";
|
||||
|
||||
jest.mock("../src/settings/SettingsStore");
|
||||
jest.mock("../src/customisations/UserIdentifier", () => ({
|
||||
getDisplayUserIdentifier: jest.fn().mockImplementation((userId) => userId),
|
||||
}));
|
||||
|
||||
function mockPinnedEvent(pinnedMessageIds?: string[], prevPinnedMessageIds?: string[]): MatrixEvent {
|
||||
return new MatrixEvent({
|
||||
type: "m.room.pinned_events",
|
||||
state_key: "",
|
||||
sender: "@foo:example.com",
|
||||
content: {
|
||||
pinned: pinnedMessageIds,
|
||||
},
|
||||
unsigned: {
|
||||
prev_content: {
|
||||
pinned: prevPinnedMessageIds,
|
||||
},
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
describe("TextForEvent", () => {
|
||||
const mockClient = createTestClient();
|
||||
|
||||
describe("getSenderName()", () => {
|
||||
it("Prefers sender.name", () => {
|
||||
expect(getSenderName({ sender: { name: "Alice" } } as MatrixEvent)).toBe("Alice");
|
||||
});
|
||||
it("Handles missing sender", () => {
|
||||
expect(getSenderName({ getSender: () => "Alice" } as MatrixEvent)).toBe("Alice");
|
||||
});
|
||||
it("Handles missing sender and get sender", () => {
|
||||
expect(getSenderName({ getSender: () => undefined } as MatrixEvent)).toBe("Someone");
|
||||
});
|
||||
});
|
||||
|
||||
describe("TextForPinnedEvent", () => {
|
||||
it("mentions message when a single message was pinned, with no previously pinned messages", () => {
|
||||
const event = mockPinnedEvent(["message-1"]);
|
||||
const plainText = textForEvent(event, mockClient);
|
||||
const component = render(textForEvent(event, mockClient, true) as ReactElement);
|
||||
|
||||
const expectedText = "@foo:example.com pinned a message to this room. See all pinned messages.";
|
||||
expect(plainText).toBe(expectedText);
|
||||
expect(component.container).toHaveTextContent(expectedText);
|
||||
});
|
||||
|
||||
it("mentions message when a single message was pinned, with multiple previously pinned messages", () => {
|
||||
const event = mockPinnedEvent(["message-1", "message-2", "message-3"], ["message-1", "message-2"]);
|
||||
const plainText = textForEvent(event, mockClient);
|
||||
const component = render(textForEvent(event, mockClient, true) as ReactElement);
|
||||
|
||||
const expectedText = "@foo:example.com pinned a message to this room. See all pinned messages.";
|
||||
expect(plainText).toBe(expectedText);
|
||||
expect(component.container).toHaveTextContent(expectedText);
|
||||
});
|
||||
|
||||
it("mentions message when a single message was unpinned, with a single message previously pinned", () => {
|
||||
const event = mockPinnedEvent([], ["message-1"]);
|
||||
const plainText = textForEvent(event, mockClient);
|
||||
const component = render(textForEvent(event, mockClient, true) as ReactElement);
|
||||
|
||||
const expectedText = "@foo:example.com unpinned a message from this room. See all pinned messages.";
|
||||
expect(plainText).toBe(expectedText);
|
||||
expect(component.container).toHaveTextContent(expectedText);
|
||||
});
|
||||
|
||||
it("mentions message when a single message was unpinned, with multiple previously pinned messages", () => {
|
||||
const event = mockPinnedEvent(["message-2"], ["message-1", "message-2"]);
|
||||
const plainText = textForEvent(event, mockClient);
|
||||
const component = render(textForEvent(event, mockClient, true) as ReactElement);
|
||||
|
||||
const expectedText = "@foo:example.com unpinned a message from this room. See all pinned messages.";
|
||||
expect(plainText).toBe(expectedText);
|
||||
expect(component.container).toHaveTextContent(expectedText);
|
||||
});
|
||||
|
||||
it("shows generic text when multiple messages were pinned", () => {
|
||||
const event = mockPinnedEvent(["message-1", "message-2", "message-3"], ["message-1"]);
|
||||
const plainText = textForEvent(event, mockClient);
|
||||
const component = render(textForEvent(event, mockClient, true) as ReactElement);
|
||||
|
||||
const expectedText = "@foo:example.com changed the pinned messages for the room.";
|
||||
expect(plainText).toBe(expectedText);
|
||||
expect(component.container).toHaveTextContent(expectedText);
|
||||
});
|
||||
|
||||
it("shows generic text when multiple messages were unpinned", () => {
|
||||
const event = mockPinnedEvent(["message-3"], ["message-1", "message-2", "message-3"]);
|
||||
const plainText = textForEvent(event, mockClient);
|
||||
const component = render(textForEvent(event, mockClient, true) as ReactElement);
|
||||
|
||||
const expectedText = "@foo:example.com changed the pinned messages for the room.";
|
||||
expect(plainText).toBe(expectedText);
|
||||
expect(component.container).toHaveTextContent(expectedText);
|
||||
});
|
||||
|
||||
it("shows generic text when one message was pinned, and another unpinned", () => {
|
||||
const event = mockPinnedEvent(["message-2"], ["message-1"]);
|
||||
const plainText = textForEvent(event, mockClient);
|
||||
const component = render(textForEvent(event, mockClient, true) as ReactElement);
|
||||
|
||||
const expectedText = "@foo:example.com changed the pinned messages for the room.";
|
||||
expect(plainText).toBe(expectedText);
|
||||
expect(component.container).toHaveTextContent(expectedText);
|
||||
});
|
||||
});
|
||||
|
||||
describe("textForPowerEvent()", () => {
|
||||
let mockClient: Mocked<MatrixClient>;
|
||||
const mockRoom = {
|
||||
getMember: jest.fn(),
|
||||
} as unknown as Mocked<Room>;
|
||||
|
||||
const userA = {
|
||||
userId: "@a",
|
||||
name: "Alice",
|
||||
rawDisplayName: "Alice",
|
||||
} as RoomMember;
|
||||
const userB = {
|
||||
userId: "@b",
|
||||
name: "Bob (@b)",
|
||||
rawDisplayName: "Bob",
|
||||
} as RoomMember;
|
||||
const userC = {
|
||||
userId: "@c",
|
||||
name: "Bob (@c)",
|
||||
rawDisplayName: "Bob",
|
||||
} as RoomMember;
|
||||
interface PowerEventProps {
|
||||
usersDefault?: number;
|
||||
prevDefault?: number;
|
||||
users: Record<string, number>;
|
||||
prevUsers: Record<string, number>;
|
||||
}
|
||||
const mockPowerEvent = ({ usersDefault, prevDefault, users, prevUsers }: PowerEventProps): MatrixEvent => {
|
||||
const mxEvent = new MatrixEvent({
|
||||
type: EventType.RoomPowerLevels,
|
||||
sender: userA.userId,
|
||||
state_key: "",
|
||||
content: {
|
||||
users_default: usersDefault,
|
||||
users,
|
||||
},
|
||||
unsigned: {
|
||||
prev_content: {
|
||||
users: prevUsers,
|
||||
users_default: prevDefault,
|
||||
},
|
||||
},
|
||||
});
|
||||
mxEvent.sender = { name: userA.name } as RoomMember;
|
||||
return mxEvent;
|
||||
};
|
||||
|
||||
beforeAll(() => {
|
||||
mockClient = createTestClient() as Mocked<MatrixClient>;
|
||||
MatrixClientPeg.get = () => mockClient;
|
||||
MatrixClientPeg.safeGet = () => mockClient;
|
||||
mockClient.getRoom.mockClear().mockReturnValue(mockRoom);
|
||||
mockRoom.getMember
|
||||
.mockClear()
|
||||
.mockImplementation((userId) => [userA, userB, userC].find((u) => u.userId === userId) || null);
|
||||
(SettingsStore.getValue as jest.Mock).mockReturnValue(true);
|
||||
});
|
||||
|
||||
beforeEach(() => {
|
||||
(UserIdentifierCustomisations.getDisplayUserIdentifier as jest.Mock)
|
||||
.mockClear()
|
||||
.mockImplementation((userId) => userId);
|
||||
});
|
||||
|
||||
it("returns falsy when no users have changed power level", () => {
|
||||
const event = mockPowerEvent({
|
||||
users: {
|
||||
[userA.userId]: 100,
|
||||
},
|
||||
prevUsers: {
|
||||
[userA.userId]: 100,
|
||||
},
|
||||
});
|
||||
expect(textForEvent(event, mockClient)).toBeFalsy();
|
||||
});
|
||||
|
||||
it("returns false when users power levels have been changed by default settings", () => {
|
||||
const event = mockPowerEvent({
|
||||
usersDefault: 100,
|
||||
prevDefault: 50,
|
||||
users: {
|
||||
[userA.userId]: 100,
|
||||
},
|
||||
prevUsers: {
|
||||
[userA.userId]: 50,
|
||||
},
|
||||
});
|
||||
expect(textForEvent(event, mockClient)).toBeFalsy();
|
||||
});
|
||||
|
||||
it("returns correct message for a single user with changed power level", () => {
|
||||
const event = mockPowerEvent({
|
||||
users: {
|
||||
[userB.userId]: 100,
|
||||
},
|
||||
prevUsers: {
|
||||
[userB.userId]: 50,
|
||||
},
|
||||
});
|
||||
const expectedText = "Alice changed the power level of Bob (@b) from Moderator to Admin.";
|
||||
expect(textForEvent(event, mockClient)).toEqual(expectedText);
|
||||
});
|
||||
|
||||
it("returns correct message for a single user with power level changed to the default", () => {
|
||||
const event = mockPowerEvent({
|
||||
usersDefault: 20,
|
||||
prevDefault: 101,
|
||||
users: {
|
||||
[userB.userId]: 20,
|
||||
},
|
||||
prevUsers: {
|
||||
[userB.userId]: 50,
|
||||
},
|
||||
});
|
||||
const expectedText = "Alice changed the power level of Bob (@b) from Moderator to Default.";
|
||||
expect(textForEvent(event, mockClient)).toEqual(expectedText);
|
||||
});
|
||||
|
||||
it("returns correct message for a single user with power level changed to a custom level", () => {
|
||||
const event = mockPowerEvent({
|
||||
users: {
|
||||
[userB.userId]: -1,
|
||||
},
|
||||
prevUsers: {
|
||||
[userB.userId]: 50,
|
||||
},
|
||||
});
|
||||
const expectedText = "Alice changed the power level of Bob (@b) from Moderator to Custom (-1).";
|
||||
expect(textForEvent(event, mockClient)).toEqual(expectedText);
|
||||
});
|
||||
|
||||
it("returns correct message for a multiple power level changes", () => {
|
||||
const event = mockPowerEvent({
|
||||
users: {
|
||||
[userB.userId]: 100,
|
||||
[userC.userId]: 50,
|
||||
},
|
||||
prevUsers: {
|
||||
[userB.userId]: 50,
|
||||
[userC.userId]: 101,
|
||||
},
|
||||
});
|
||||
const expectedText =
|
||||
"Alice changed the power level of Bob (@b) from Moderator to Admin," +
|
||||
" Bob (@c) from Custom (101) to Moderator.";
|
||||
expect(textForEvent(event, mockClient)).toEqual(expectedText);
|
||||
});
|
||||
});
|
||||
|
||||
describe("textForCanonicalAliasEvent()", () => {
|
||||
const userA = {
|
||||
userId: "@a",
|
||||
name: "Alice",
|
||||
};
|
||||
|
||||
interface AliasEventProps {
|
||||
alias?: string;
|
||||
prevAlias?: string;
|
||||
altAliases?: string[];
|
||||
prevAltAliases?: string[];
|
||||
}
|
||||
const mockEvent = ({ alias, prevAlias, altAliases, prevAltAliases }: AliasEventProps): MatrixEvent =>
|
||||
new MatrixEvent({
|
||||
type: EventType.RoomCanonicalAlias,
|
||||
sender: userA.userId,
|
||||
state_key: "",
|
||||
content: {
|
||||
alias,
|
||||
alt_aliases: altAliases,
|
||||
},
|
||||
unsigned: {
|
||||
prev_content: {
|
||||
alias: prevAlias,
|
||||
alt_aliases: prevAltAliases,
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
type TestCase = [string, AliasEventProps & { result: string }];
|
||||
const testCases: TestCase[] = [
|
||||
[
|
||||
"room alias didn't change",
|
||||
{
|
||||
result: "@a changed the addresses for this room.",
|
||||
},
|
||||
],
|
||||
[
|
||||
"room alias changed",
|
||||
{
|
||||
alias: "banana",
|
||||
prevAlias: "apple",
|
||||
result: "@a set the main address for this room to banana.",
|
||||
},
|
||||
],
|
||||
[
|
||||
"room alias was added",
|
||||
{
|
||||
alias: "banana",
|
||||
result: "@a set the main address for this room to banana.",
|
||||
},
|
||||
],
|
||||
[
|
||||
"room alias was removed",
|
||||
{
|
||||
prevAlias: "apple",
|
||||
result: "@a removed the main address for this room.",
|
||||
},
|
||||
],
|
||||
[
|
||||
"added an alt alias",
|
||||
{
|
||||
altAliases: ["canteloupe"],
|
||||
result: "@a added alternative address canteloupe for this room.",
|
||||
},
|
||||
],
|
||||
[
|
||||
"added multiple alt aliases",
|
||||
{
|
||||
altAliases: ["canteloupe", "date"],
|
||||
result: "@a added the alternative addresses canteloupe, date for this room.",
|
||||
},
|
||||
],
|
||||
[
|
||||
"removed an alt alias",
|
||||
{
|
||||
altAliases: ["canteloupe"],
|
||||
prevAltAliases: ["canteloupe", "date"],
|
||||
result: "@a removed alternative address date for this room.",
|
||||
},
|
||||
],
|
||||
[
|
||||
"added and removed an alt aliases",
|
||||
{
|
||||
altAliases: ["canteloupe", "elderberry"],
|
||||
prevAltAliases: ["canteloupe", "date"],
|
||||
result: "@a changed the alternative addresses for this room.",
|
||||
},
|
||||
],
|
||||
[
|
||||
"changed alias and added alt alias",
|
||||
{
|
||||
alias: "banana",
|
||||
prevAlias: "apple",
|
||||
altAliases: ["canteloupe"],
|
||||
result: "@a changed the main and alternative addresses for this room.",
|
||||
},
|
||||
],
|
||||
];
|
||||
|
||||
it.each(testCases)("returns correct message when %s", (_d, { result, ...eventProps }) => {
|
||||
const event = mockEvent(eventProps);
|
||||
expect(textForEvent(event, mockClient)).toEqual(result);
|
||||
});
|
||||
});
|
||||
|
||||
describe("textForPollStartEvent()", () => {
|
||||
let pollEvent: MatrixEvent;
|
||||
|
||||
beforeEach(() => {
|
||||
pollEvent = new MatrixEvent({
|
||||
type: "org.matrix.msc3381.poll.start",
|
||||
sender: "@a",
|
||||
content: {
|
||||
"org.matrix.msc3381.poll.start": {
|
||||
answers: [{ "org.matrix.msc1767.text": "option1" }, { "org.matrix.msc1767.text": "option2" }],
|
||||
question: {
|
||||
"body": "Test poll name",
|
||||
"msgtype": "m.text",
|
||||
"org.matrix.msc1767.text": "Test poll name",
|
||||
},
|
||||
},
|
||||
},
|
||||
});
|
||||
});
|
||||
|
||||
it("returns correct message for redacted poll start", () => {
|
||||
pollEvent.makeRedacted(pollEvent, new Room(pollEvent.getRoomId()!, mockClient, mockClient.getSafeUserId()));
|
||||
|
||||
expect(textForEvent(pollEvent, mockClient)).toEqual("@a: Message deleted");
|
||||
});
|
||||
|
||||
it("returns correct message for normal poll start", () => {
|
||||
expect(textForEvent(pollEvent, mockClient)).toEqual("@a has started a poll - ");
|
||||
});
|
||||
});
|
||||
|
||||
describe("textForMessageEvent()", () => {
|
||||
let messageEvent: MatrixEvent;
|
||||
|
||||
beforeEach(() => {
|
||||
messageEvent = new MatrixEvent({
|
||||
type: "m.room.message",
|
||||
sender: "@a",
|
||||
content: {
|
||||
"body": "test message",
|
||||
"msgtype": "m.text",
|
||||
"org.matrix.msc1767.text": "test message",
|
||||
},
|
||||
});
|
||||
});
|
||||
|
||||
it("returns correct message for redacted message", () => {
|
||||
messageEvent.makeRedacted(
|
||||
messageEvent,
|
||||
new Room(messageEvent.getRoomId()!, mockClient, mockClient.getSafeUserId()),
|
||||
);
|
||||
|
||||
expect(textForEvent(messageEvent, mockClient)).toEqual("@a: Message deleted");
|
||||
});
|
||||
|
||||
it("returns correct message for normal message", () => {
|
||||
expect(textForEvent(messageEvent, mockClient)).toEqual("@a: test message");
|
||||
});
|
||||
});
|
||||
|
||||
describe("textForCallEvent()", () => {
|
||||
let mockClient: MatrixClient;
|
||||
let callEvent: MatrixEvent;
|
||||
|
||||
beforeEach(() => {
|
||||
stubClient();
|
||||
mockClient = MatrixClientPeg.safeGet();
|
||||
|
||||
mocked(mockClient.getRoom).mockReturnValue({
|
||||
name: "Test room",
|
||||
} as unknown as Room);
|
||||
|
||||
callEvent = {
|
||||
getRoomId: jest.fn(),
|
||||
getType: jest.fn(),
|
||||
isState: jest.fn().mockReturnValue(true),
|
||||
} as unknown as MatrixEvent;
|
||||
});
|
||||
|
||||
describe.each(ElementCall.CALL_EVENT_TYPE.names)("eventType=%s", (eventType: string) => {
|
||||
beforeEach(() => {
|
||||
mocked(callEvent).getType.mockReturnValue(eventType);
|
||||
});
|
||||
|
||||
it("returns correct message for call event when supported", () => {
|
||||
expect(textForEvent(callEvent, mockClient)).toEqual("Video call started in Test room.");
|
||||
});
|
||||
|
||||
it("returns correct message for call event when not supported", () => {
|
||||
mocked(mockClient).supportsVoip.mockReturnValue(false);
|
||||
|
||||
expect(textForEvent(callEvent, mockClient)).toEqual(
|
||||
"Video call started in Test room. (not supported by this browser)",
|
||||
);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe("textForMemberEvent()", () => {
|
||||
beforeEach(() => {
|
||||
stubClient();
|
||||
});
|
||||
|
||||
it("should handle both displayname and avatar changing in one event", () => {
|
||||
expect(
|
||||
textForEvent(
|
||||
new MatrixEvent({
|
||||
type: "m.room.member",
|
||||
sender: "@a:foo",
|
||||
content: {
|
||||
membership: KnownMembership.Join,
|
||||
avatar_url: "b",
|
||||
displayname: "Bob",
|
||||
},
|
||||
unsigned: {
|
||||
prev_content: {
|
||||
membership: KnownMembership.Join,
|
||||
avatar_url: "a",
|
||||
displayname: "Andy",
|
||||
},
|
||||
},
|
||||
state_key: "@a:foo",
|
||||
}),
|
||||
mockClient,
|
||||
),
|
||||
).toMatchInlineSnapshot(`"Andy changed their display name and profile picture"`);
|
||||
});
|
||||
});
|
||||
|
||||
describe("textForJoinRulesEvent()", () => {
|
||||
type TestCase = [string, { result: string }];
|
||||
const testCases: TestCase[] = [
|
||||
[JoinRule.Public, { result: "@a made the room public to whoever knows the link." }],
|
||||
[JoinRule.Invite, { result: "@a made the room invite only." }],
|
||||
[JoinRule.Knock, { result: "@a changed the join rule to ask to join." }],
|
||||
[JoinRule.Restricted, { result: "@a changed who can join this room." }],
|
||||
];
|
||||
|
||||
it.each(testCases)("returns correct message when room join rule changed to %s", (joinRule, { result }) => {
|
||||
expect(
|
||||
textForEvent(
|
||||
new MatrixEvent({
|
||||
type: "m.room.join_rules",
|
||||
sender: "@a",
|
||||
content: {
|
||||
join_rule: joinRule,
|
||||
},
|
||||
state_key: "",
|
||||
}),
|
||||
mockClient,
|
||||
),
|
||||
).toEqual(result);
|
||||
});
|
||||
|
||||
it(`returns correct JSX message when room join rule changed to ${JoinRule.Restricted}`, () => {
|
||||
expect(
|
||||
textForEvent(
|
||||
new MatrixEvent({
|
||||
type: "m.room.join_rules",
|
||||
sender: "@a",
|
||||
content: {
|
||||
join_rule: JoinRule.Restricted,
|
||||
},
|
||||
state_key: "",
|
||||
}),
|
||||
mockClient,
|
||||
true,
|
||||
),
|
||||
).toMatchSnapshot();
|
||||
});
|
||||
|
||||
it("returns correct default message", () => {
|
||||
expect(
|
||||
textForEvent(
|
||||
new MatrixEvent({
|
||||
type: "m.room.join_rules",
|
||||
sender: "@a",
|
||||
content: {
|
||||
join_rule: "a not implemented one",
|
||||
},
|
||||
state_key: "",
|
||||
}),
|
||||
mockClient,
|
||||
),
|
||||
).toEqual("@a changed the join rule to a not implemented one");
|
||||
});
|
||||
});
|
||||
|
||||
describe("textForHistoryVisibilityEvent()", () => {
|
||||
type TestCase = [string, { result: string }];
|
||||
const testCases: TestCase[] = [
|
||||
[
|
||||
HistoryVisibility.Invited,
|
||||
{ result: "@a made future room history visible to all room members, from the point they are invited." },
|
||||
],
|
||||
[
|
||||
HistoryVisibility.Joined,
|
||||
{ result: "@a made future room history visible to all room members, from the point they joined." },
|
||||
],
|
||||
[HistoryVisibility.Shared, { result: "@a made future room history visible to all room members." }],
|
||||
[HistoryVisibility.WorldReadable, { result: "@a made future room history visible to anyone." }],
|
||||
];
|
||||
|
||||
it.each(testCases)(
|
||||
"returns correct message when room join rule changed to %s",
|
||||
(historyVisibility, { result }) => {
|
||||
expect(
|
||||
textForEvent(
|
||||
new MatrixEvent({
|
||||
type: "m.room.history_visibility",
|
||||
sender: "@a",
|
||||
content: {
|
||||
history_visibility: historyVisibility,
|
||||
},
|
||||
state_key: "",
|
||||
}),
|
||||
mockClient,
|
||||
),
|
||||
).toEqual(result);
|
||||
},
|
||||
);
|
||||
});
|
||||
});
|
Loading…
Add table
Add a link
Reference in a new issue