You've already forked matrix-js-sdk
mirror of
https://github.com/matrix-org/matrix-js-sdk.git
synced 2025-07-30 04:23:07 +03:00
Merge pull request #3798 from matrix-org/andybalaam/move-redacted-message-to-main
Move redacted messages out of any thread, into main timeline.
This commit is contained in:
@ -14,10 +14,19 @@ See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
import { MockedObject } from "jest-mock";
|
||||
|
||||
import { MatrixEvent, MatrixEventEvent } from "../../../src/models/event";
|
||||
import { emitPromise } from "../../test-utils/test-utils";
|
||||
import { Crypto, IEventDecryptionResult } from "../../../src/crypto";
|
||||
import { IAnnotatedPushRule, PushRuleActionName, TweakName } from "../../../src";
|
||||
import {
|
||||
IAnnotatedPushRule,
|
||||
MatrixClient,
|
||||
PushRuleActionName,
|
||||
Room,
|
||||
THREAD_RELATION_TYPE,
|
||||
TweakName,
|
||||
} from "../../../src";
|
||||
|
||||
describe("MatrixEvent", () => {
|
||||
it("should create copies of itself", () => {
|
||||
@ -77,17 +86,98 @@ describe("MatrixEvent", () => {
|
||||
expect(ev.getWireContent().body).toBeUndefined();
|
||||
expect(ev.getWireContent().ciphertext).toBe("xyz");
|
||||
|
||||
const mockClient = {} as unknown as MockedObject<MatrixClient>;
|
||||
const room = new Room("!roomid:e.xyz", mockClient, "myname");
|
||||
const redaction = new MatrixEvent({
|
||||
type: "m.room.redaction",
|
||||
redacts: ev.getId(),
|
||||
});
|
||||
|
||||
ev.makeRedacted(redaction);
|
||||
ev.makeRedacted(redaction, room);
|
||||
expect(ev.getContent().body).toBeUndefined();
|
||||
expect(ev.getWireContent().body).toBeUndefined();
|
||||
expect(ev.getWireContent().ciphertext).toBeUndefined();
|
||||
});
|
||||
|
||||
it("should remain in the main timeline when redacted", async () => {
|
||||
// Given an event in the main timeline
|
||||
const mockClient = {
|
||||
supportsThreads: jest.fn().mockReturnValue(true),
|
||||
decryptEventIfNeeded: jest.fn().mockReturnThis(),
|
||||
getUserId: jest.fn().mockReturnValue("@user:server"),
|
||||
} as unknown as MockedObject<MatrixClient>;
|
||||
const room = new Room("!roomid:e.xyz", mockClient, "myname");
|
||||
const ev = new MatrixEvent({
|
||||
type: "m.room.message",
|
||||
content: {
|
||||
body: "Test",
|
||||
},
|
||||
event_id: "$event1:server",
|
||||
});
|
||||
|
||||
await room.addLiveEvents([ev]);
|
||||
await room.createThreadsTimelineSets();
|
||||
expect(ev.threadRootId).toBeUndefined();
|
||||
expect(mainTimelineLiveEventIds(room)).toEqual(["$event1:server"]);
|
||||
|
||||
// When I redact it
|
||||
const redaction = new MatrixEvent({
|
||||
type: "m.room.redaction",
|
||||
redacts: ev.getId(),
|
||||
});
|
||||
ev.makeRedacted(redaction, room);
|
||||
|
||||
// Then it remains in the main timeline
|
||||
expect(ev.threadRootId).toBeUndefined();
|
||||
expect(mainTimelineLiveEventIds(room)).toEqual(["$event1:server"]);
|
||||
});
|
||||
|
||||
it("should move into the main timeline when redacted", async () => {
|
||||
// Given an event in a thread
|
||||
const mockClient = {
|
||||
supportsThreads: jest.fn().mockReturnValue(true),
|
||||
decryptEventIfNeeded: jest.fn().mockReturnThis(),
|
||||
getUserId: jest.fn().mockReturnValue("@user:server"),
|
||||
} as unknown as MockedObject<MatrixClient>;
|
||||
const room = new Room("!roomid:e.xyz", mockClient, "myname");
|
||||
const threadRoot = new MatrixEvent({
|
||||
type: "m.room.message",
|
||||
content: {
|
||||
body: "threadRoot",
|
||||
},
|
||||
event_id: "$threadroot:server",
|
||||
});
|
||||
const ev = new MatrixEvent({
|
||||
type: "m.room.message",
|
||||
content: {
|
||||
"body": "Test",
|
||||
"m.relates_to": {
|
||||
rel_type: THREAD_RELATION_TYPE.name,
|
||||
event_id: "$threadroot:server",
|
||||
},
|
||||
},
|
||||
event_id: "$event1:server",
|
||||
});
|
||||
|
||||
await room.addLiveEvents([threadRoot, ev]);
|
||||
await room.createThreadsTimelineSets();
|
||||
expect(ev.threadRootId).toEqual("$threadroot:server");
|
||||
expect(mainTimelineLiveEventIds(room)).toEqual(["$threadroot:server"]);
|
||||
expect(threadLiveEventIds(room, 0)).toEqual(["$threadroot:server", "$event1:server"]);
|
||||
|
||||
// When I redact it
|
||||
const redaction = new MatrixEvent({
|
||||
type: "m.room.redaction",
|
||||
redacts: ev.getId(),
|
||||
});
|
||||
ev.makeRedacted(redaction, room);
|
||||
|
||||
// Then it disappears from the thread and appears in the main timeline
|
||||
expect(ev.threadRootId).toBeUndefined();
|
||||
expect(mainTimelineLiveEventIds(room)).toEqual(["$threadroot:server", "$event1:server"]);
|
||||
expect(threadLiveEventIds(room, 0)).not.toContain("$event1:server");
|
||||
});
|
||||
|
||||
describe("applyVisibilityEvent", () => {
|
||||
it("should emit VisibilityChange if a change was made", async () => {
|
||||
const ev = new MatrixEvent({
|
||||
@ -330,3 +420,19 @@ describe("MatrixEvent", () => {
|
||||
expect(stateEvent.threadRootId).toBeUndefined();
|
||||
});
|
||||
});
|
||||
|
||||
function mainTimelineLiveEventIds(room: Room): Array<string> {
|
||||
return room
|
||||
.getLiveTimeline()
|
||||
.getEvents()
|
||||
.map((e) => e.getId()!);
|
||||
}
|
||||
|
||||
function threadLiveEventIds(room: Room, threadIndex: number): Array<string> {
|
||||
return room
|
||||
.getThreads()
|
||||
[threadIndex].getUnfilteredTimelineSet()
|
||||
.getLiveTimeline()
|
||||
.getEvents()
|
||||
.map((e) => e.getId()!);
|
||||
}
|
||||
|
@ -27,6 +27,7 @@ import { M_BEACON } from "../../src/@types/beacon";
|
||||
import { MatrixClient } from "../../src/client";
|
||||
import { DecryptionError } from "../../src/crypto/algorithms";
|
||||
import { defer } from "../../src/utils";
|
||||
import { Room } from "../../src/models/room";
|
||||
|
||||
describe("RoomState", function () {
|
||||
const roomId = "!foo:bar";
|
||||
@ -362,9 +363,11 @@ describe("RoomState", function () {
|
||||
});
|
||||
|
||||
it("does not add redacted beacon info events to state", () => {
|
||||
const mockClient = {} as unknown as MockedObject<MatrixClient>;
|
||||
const redactedBeaconEvent = makeBeaconInfoEvent(userA, roomId);
|
||||
const redactionEvent = new MatrixEvent({ type: "m.room.redaction" });
|
||||
redactedBeaconEvent.makeRedacted(redactionEvent);
|
||||
const room = new Room(roomId, mockClient, userA);
|
||||
redactedBeaconEvent.makeRedacted(redactionEvent, room);
|
||||
const emitSpy = jest.spyOn(state, "emit");
|
||||
|
||||
state.setStateEvents([redactedBeaconEvent]);
|
||||
@ -394,11 +397,13 @@ describe("RoomState", function () {
|
||||
});
|
||||
|
||||
it("destroys and removes redacted beacon events", () => {
|
||||
const mockClient = {} as unknown as MockedObject<MatrixClient>;
|
||||
const beaconId = "$beacon1";
|
||||
const beaconEvent = makeBeaconInfoEvent(userA, roomId, { isLive: true }, beaconId);
|
||||
const redactedBeaconEvent = makeBeaconInfoEvent(userA, roomId, { isLive: true }, beaconId);
|
||||
const redactionEvent = new MatrixEvent({ type: "m.room.redaction", redacts: beaconEvent.getId() });
|
||||
redactedBeaconEvent.makeRedacted(redactionEvent);
|
||||
const room = new Room(roomId, mockClient, userA);
|
||||
redactedBeaconEvent.makeRedacted(redactionEvent, room);
|
||||
|
||||
state.setStateEvents([beaconEvent]);
|
||||
const beaconInstance = state.beacons.get(getBeaconInfoIdentifier(beaconEvent));
|
||||
|
@ -3564,7 +3564,7 @@ describe("Room", function () {
|
||||
expect(room.polls.get(pollStartEvent.getId()!)).toBeTruthy();
|
||||
|
||||
const redactedEvent = new MatrixEvent({ type: "m.room.redaction" });
|
||||
pollStartEvent.makeRedacted(redactedEvent);
|
||||
pollStartEvent.makeRedacted(redactedEvent, room);
|
||||
|
||||
await flushPromises();
|
||||
|
||||
|
Reference in New Issue
Block a user