You've already forked matrix-js-sdk
mirror of
https://github.com/matrix-org/matrix-js-sdk.git
synced 2025-07-31 15:24:23 +03:00
Delete knocked room when knock membership changes (#3729)
* Store leave state when knock is denied Signed-off-by: Mikhail Aheichyk <mikhail.aheichyk@nordeck.net> * Delete knocked room when knock request is cancelled or denied Signed-off-by: Mikhail Aheichyk <mikhail.aheichyk@nordeck.net> * Test is updated Signed-off-by: Mikhail Aheichyk <mikhail.aheichyk@nordeck.net> --------- Signed-off-by: Mikhail Aheichyk <mikhail.aheichyk@nordeck.net> Co-authored-by: Mikhail Aheichyk <mikhail.aheichyk@nordeck.net>
This commit is contained in:
@ -16,7 +16,19 @@ limitations under the License.
|
||||
*/
|
||||
|
||||
import { ReceiptType } from "../../src/@types/read_receipts";
|
||||
import { IJoinedRoom, IKnockedRoom, IStrippedState, ISyncResponse, SyncAccumulator } from "../../src/sync-accumulator";
|
||||
import {
|
||||
IJoinedRoom,
|
||||
IInvitedRoom,
|
||||
IKnockedRoom,
|
||||
IKnockState,
|
||||
ILeftRoom,
|
||||
IRoomEvent,
|
||||
IStateEvent,
|
||||
IStrippedState,
|
||||
ISyncResponse,
|
||||
SyncAccumulator,
|
||||
IInviteState,
|
||||
} from "../../src/sync-accumulator";
|
||||
import { IRoomSummary } from "../../src";
|
||||
import * as utils from "../test-utils/test-utils";
|
||||
|
||||
@ -295,12 +307,71 @@ describe("SyncAccumulator", function () {
|
||||
expect(sa.getJSON().accountData[0]).toEqual(acc2);
|
||||
});
|
||||
|
||||
it("should delete invite room when invite request is rejected", () => {
|
||||
const initInviteState: IInviteState = {
|
||||
events: [
|
||||
{
|
||||
content: {
|
||||
membership: "invite",
|
||||
},
|
||||
state_key: "bob",
|
||||
sender: "alice",
|
||||
type: "m.room.member",
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
sa.accumulate(
|
||||
syncSkeleton(
|
||||
{},
|
||||
{
|
||||
"!invite:bar": {
|
||||
invite_state: initInviteState,
|
||||
},
|
||||
},
|
||||
),
|
||||
);
|
||||
expect(sa.getJSON().roomsData.invite["!invite:bar"].invite_state).toBe(initInviteState);
|
||||
|
||||
const rejectMemberEvent: IStateEvent = {
|
||||
event_id: "$" + Math.random(),
|
||||
content: {
|
||||
membership: "leave",
|
||||
},
|
||||
origin_server_ts: 123456789,
|
||||
state_key: "bob",
|
||||
sender: "bob",
|
||||
type: "m.room.member",
|
||||
unsigned: {
|
||||
prev_content: {
|
||||
membership: "invite",
|
||||
},
|
||||
},
|
||||
};
|
||||
const leftRoomState = leftRoomSkeleton([rejectMemberEvent]);
|
||||
|
||||
// bob rejects invite
|
||||
sa.accumulate(
|
||||
syncSkeleton(
|
||||
{},
|
||||
{},
|
||||
{
|
||||
"!invite:bar": leftRoomState,
|
||||
},
|
||||
),
|
||||
);
|
||||
|
||||
expect(sa.getJSON().roomsData.invite["!invite:bar"]).toBeUndefined();
|
||||
});
|
||||
|
||||
it("should accumulate knock state", () => {
|
||||
const initKnockState = {
|
||||
events: [member("alice", "knock")],
|
||||
};
|
||||
sa.accumulate(
|
||||
syncSkeleton(
|
||||
{},
|
||||
{},
|
||||
{},
|
||||
{
|
||||
knock_state: initKnockState,
|
||||
@ -311,6 +382,8 @@ describe("SyncAccumulator", function () {
|
||||
|
||||
sa.accumulate(
|
||||
syncSkeleton(
|
||||
{},
|
||||
{},
|
||||
{},
|
||||
{
|
||||
knock_state: {
|
||||
@ -336,6 +409,8 @@ describe("SyncAccumulator", function () {
|
||||
|
||||
sa.accumulate(
|
||||
syncSkeleton(
|
||||
{},
|
||||
{},
|
||||
{},
|
||||
{
|
||||
knock_state: {
|
||||
@ -360,6 +435,140 @@ describe("SyncAccumulator", function () {
|
||||
).toEqual("Room 2");
|
||||
});
|
||||
|
||||
it("should delete knocked room when knock request is approved", () => {
|
||||
const initKnockState = makeKnockState();
|
||||
sa.accumulate(
|
||||
syncSkeleton(
|
||||
{},
|
||||
{},
|
||||
{},
|
||||
{
|
||||
knock_state: initKnockState,
|
||||
},
|
||||
),
|
||||
);
|
||||
expect(sa.getJSON().roomsData.knock["!knock:bar"].knock_state).toBe(initKnockState);
|
||||
|
||||
// alice approves bob's knock request
|
||||
const inviteStateEvents = [
|
||||
{
|
||||
content: {
|
||||
membership: "invite",
|
||||
},
|
||||
state_key: "bob",
|
||||
sender: "alice",
|
||||
type: "m.room.member",
|
||||
},
|
||||
];
|
||||
sa.accumulate(
|
||||
syncSkeleton(
|
||||
{},
|
||||
{
|
||||
"!knock:bar": {
|
||||
invite_state: {
|
||||
events: inviteStateEvents,
|
||||
},
|
||||
},
|
||||
},
|
||||
),
|
||||
);
|
||||
|
||||
expect(sa.getJSON().roomsData.knock["!knock:bar"]).toBeUndefined();
|
||||
expect(sa.getJSON().roomsData.invite["!knock:bar"].invite_state.events).toEqual(inviteStateEvents);
|
||||
});
|
||||
|
||||
it("should delete knocked room when knock request is cancelled by user himself", () => {
|
||||
// bob cancels his knock state
|
||||
const memberEvent: IStateEvent = {
|
||||
event_id: "$" + Math.random(),
|
||||
content: {
|
||||
membership: "leave",
|
||||
},
|
||||
origin_server_ts: 123456789,
|
||||
state_key: "bob",
|
||||
sender: "bob",
|
||||
type: "m.room.member",
|
||||
unsigned: {
|
||||
prev_content: {
|
||||
membership: "knock",
|
||||
},
|
||||
},
|
||||
};
|
||||
const leftRoomState = leftRoomSkeleton([memberEvent]);
|
||||
|
||||
const initKnockState = makeKnockState();
|
||||
sa.accumulate(
|
||||
syncSkeleton(
|
||||
{},
|
||||
{},
|
||||
{},
|
||||
{
|
||||
knock_state: initKnockState,
|
||||
},
|
||||
),
|
||||
);
|
||||
expect(sa.getJSON().roomsData.knock["!knock:bar"].knock_state).toBe(initKnockState);
|
||||
|
||||
// bob cancels his knock request
|
||||
sa.accumulate(
|
||||
syncSkeleton(
|
||||
{},
|
||||
{},
|
||||
{
|
||||
"!knock:bar": leftRoomState,
|
||||
},
|
||||
),
|
||||
);
|
||||
|
||||
expect(sa.getJSON().roomsData.knock["!knock:bar"]).toBeUndefined();
|
||||
});
|
||||
|
||||
it("should delete knocked room when knock request is denied by another user", () => {
|
||||
// alice denies bob knock state
|
||||
const memberEvent: IStateEvent = {
|
||||
event_id: "$" + Math.random(),
|
||||
content: {
|
||||
membership: "leave",
|
||||
},
|
||||
origin_server_ts: 123456789,
|
||||
state_key: "bob",
|
||||
sender: "alice",
|
||||
type: "m.room.member",
|
||||
unsigned: {
|
||||
prev_content: {
|
||||
membership: "knock",
|
||||
},
|
||||
},
|
||||
};
|
||||
const leftRoomState = leftRoomSkeleton([memberEvent]);
|
||||
|
||||
const initKnockState = makeKnockState();
|
||||
sa.accumulate(
|
||||
syncSkeleton(
|
||||
{},
|
||||
{},
|
||||
{},
|
||||
{
|
||||
knock_state: initKnockState,
|
||||
},
|
||||
),
|
||||
);
|
||||
expect(sa.getJSON().roomsData.knock["!knock:bar"].knock_state).toBe(initKnockState);
|
||||
|
||||
// alice denies bob's knock request
|
||||
sa.accumulate(
|
||||
syncSkeleton(
|
||||
{},
|
||||
{},
|
||||
{
|
||||
"!knock:bar": leftRoomState,
|
||||
},
|
||||
),
|
||||
);
|
||||
|
||||
expect(sa.getJSON().roomsData.knock["!knock:bar"]).toBeUndefined();
|
||||
});
|
||||
|
||||
it("should accumulate read receipts", () => {
|
||||
const receipt1 = {
|
||||
type: "m.receipt",
|
||||
@ -674,7 +883,12 @@ describe("SyncAccumulator", function () {
|
||||
});
|
||||
});
|
||||
|
||||
function syncSkeleton(joinObj: Partial<IJoinedRoom>, knockObj?: Partial<IKnockedRoom>): ISyncResponse {
|
||||
function syncSkeleton(
|
||||
joinObj: Partial<IJoinedRoom>,
|
||||
invite?: Record<string, IInvitedRoom>,
|
||||
leave?: Record<string, ILeftRoom>,
|
||||
knockObj?: Partial<IKnockedRoom>,
|
||||
): ISyncResponse {
|
||||
joinObj = joinObj || {};
|
||||
return {
|
||||
next_batch: "abc",
|
||||
@ -682,6 +896,8 @@ function syncSkeleton(joinObj: Partial<IJoinedRoom>, knockObj?: Partial<IKnocked
|
||||
join: {
|
||||
"!foo:bar": joinObj,
|
||||
},
|
||||
invite,
|
||||
leave,
|
||||
knock: knockObj
|
||||
? {
|
||||
"!knock:bar": knockObj,
|
||||
@ -691,6 +907,37 @@ function syncSkeleton(joinObj: Partial<IJoinedRoom>, knockObj?: Partial<IKnocked
|
||||
} as unknown as ISyncResponse;
|
||||
}
|
||||
|
||||
function leftRoomSkeleton(timelineEvents: Array<IRoomEvent | IStateEvent> = []): ILeftRoom {
|
||||
return {
|
||||
state: {
|
||||
events: [],
|
||||
},
|
||||
timeline: {
|
||||
events: timelineEvents,
|
||||
prev_batch: "something",
|
||||
},
|
||||
account_data: {
|
||||
events: [],
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
function makeKnockState(): IKnockState {
|
||||
return {
|
||||
events: [
|
||||
utils.mkEvent({
|
||||
user: "alice",
|
||||
room: "!knock:bar",
|
||||
type: "m.room.name",
|
||||
content: {
|
||||
name: "Room",
|
||||
},
|
||||
}) as IStrippedState,
|
||||
member("bob", "knock"),
|
||||
],
|
||||
};
|
||||
}
|
||||
|
||||
function msg(localpart: string, text: string) {
|
||||
return {
|
||||
event_id: "$" + Math.random(),
|
||||
|
@ -283,6 +283,10 @@ export class SyncAccumulator {
|
||||
// * equivalent to "no state"
|
||||
switch (category) {
|
||||
case Category.Invite: // (5)
|
||||
if (this.knockRooms[roomId]) {
|
||||
// was previously knock, now invite, need to delete knock state
|
||||
delete this.knockRooms[roomId];
|
||||
}
|
||||
this.accumulateInviteState(roomId, data as IInvitedRoom);
|
||||
break;
|
||||
|
||||
@ -303,7 +307,10 @@ export class SyncAccumulator {
|
||||
break;
|
||||
|
||||
case Category.Leave:
|
||||
if (this.inviteRooms[roomId]) {
|
||||
if (this.knockRooms[roomId]) {
|
||||
// delete knock state on leave
|
||||
delete this.knockRooms[roomId];
|
||||
} else if (this.inviteRooms[roomId]) {
|
||||
// (4)
|
||||
delete this.inviteRooms[roomId];
|
||||
} else {
|
||||
|
Reference in New Issue
Block a user