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

Implement MSC3575: Sliding Sync #8328

Merged
merged 99 commits into from
Sep 7, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
99 commits
Select commit Hold shift + click to select a range
bea9d83
Add labs flag for sliding sync; add sliding_sync_proxy_url to config.…
kegsay Mar 16, 2022
7fb8656
Disable the labs toggle if sliding_sync_proxy_url is not set
kegsay Mar 16, 2022
c735976
Do validation checks on the sliding sync proxy URL before enabling it…
kegsay Mar 16, 2022
bebc9f2
Merge branch 'develop' into kegan/sliding-sync
kegsay Mar 17, 2022
bddf053
Enable sliding sync and add SlidingSyncManager
kegsay Mar 17, 2022
eb76ff4
Get room subscriptions working
kegsay Mar 17, 2022
9b59f05
Hijack renderSublists in sliding sync mode
kegsay Mar 18, 2022
e75b48a
Add support for sorting alphabetically/recency and room name filters
kegsay Mar 21, 2022
18cd70b
Filter out tombstoned rooms; start adding show more logic
kegsay Mar 22, 2022
5572292
update the UI when the list is updated
kegsay Mar 22, 2022
12fa287
bugfix: make sure the list sorts numerically
kegsay Mar 25, 2022
dbc0d57
Get invites transitioning correctly
kegsay Mar 29, 2022
4efc389
Merge tag 'v3.42.3' into kegan/sync-v3
kegsay Apr 14, 2022
04602c3
Force enable sliding sync and labs for now
kegsay Apr 14, 2022
b769779
Linting
kegsay Apr 14, 2022
4369e43
Merge branch 'develop' into kegan/sync-v3
kegsay Apr 14, 2022
92a93f2
Merge branch 'develop' into kegan/sync-v3
kegsay Apr 14, 2022
086c678
Disable spotlight search
kegsay Apr 26, 2022
bc3d9f6
Initial cypress plugins for Sliding Sync Proxy
t3chguy May 30, 2022
56598cb
Use --rm when running Synapse in Docker for Cypress tests
t3chguy May 30, 2022
ed6fd78
Merge branch 'develop' of github.com:matrix-org/matrix-react-sdk into…
t3chguy Jun 9, 2022
f2751ec
Merge branch 'develop' into kegan/sync-v3
kegsay Jun 15, 2022
71eb8ad
Update src/MatrixClientPeg.ts
kegsay Jun 15, 2022
e393185
Update src/components/views/rooms/RoomSublist.tsx
kegsay Jun 15, 2022
aa26456
Update src/settings/controllers/SlidingSyncController.ts
kegsay Jun 15, 2022
8613591
Update src/components/views/rooms/RoomSublist.tsx
kegsay Jun 15, 2022
0040bbb
Merge branch 'develop' into kegan/sync-v3
kegsay Jul 11, 2022
9e8a80a
WIP add room searching to spotlight search
kegsay Jul 12, 2022
a03c172
Only read sliding sync results when there is a result, else use the l…
kegsay Jul 14, 2022
fb1e9c0
Use feature_sliding_sync not slidingSync
kegsay Jul 14, 2022
4143d13
Some review comments
kegsay Jul 14, 2022
79e6ee9
More review comments
kegsay Jul 20, 2022
8f818e4
Use RoomViewStore to set room subscriptions
kegsay Jul 21, 2022
050903d
Comment why any
kegsay Jul 21, 2022
64d941e
Update src/components/views/rooms/RoomSublist.tsx
kegsay Jul 26, 2022
b5a7a06
Merge branch 'develop' into t3chguy/cypress-sliding-sync
t3chguy Jul 27, 2022
246a5f4
Merge branch 'develop' of github.com:matrix-org/matrix-react-sdk into…
t3chguy Jul 27, 2022
2ea6b66
Merge branch 't3chguy/cypress-sliding-sync' of github.com:matrix-org/…
t3chguy Jul 27, 2022
332b136
Fix cypress docker abstraction
t3chguy Jul 27, 2022
1ba5bf5
Iterate sliding sync proxy support
t3chguy Jul 27, 2022
0542589
Stash mostly functional test
t3chguy Jul 27, 2022
be146ef
Update sliding sync proxy image
t3chguy Jul 27, 2022
2ed801d
i18n
t3chguy Jul 27, 2022
da4001f
Add support for spaces; use list ID -> index mappings
kegsay Aug 2, 2022
af5018d
When the active space is updated, update the list registration
kegsay Aug 2, 2022
a72da80
Set spaces filter in the correct place
kegsay Aug 2, 2022
f65637d
Skeleton placeholder whilst loading the space
kegsay Aug 5, 2022
0dc7004
Filter out spaces from the room list
kegsay Aug 5, 2022
c22aeb7
Use the new txn_id promises
kegsay Aug 5, 2022
a81a6ea
Ensure we actually resolve list registrations
kegsay Aug 5, 2022
34df9d6
Fix matrix-org/sliding-sync#30: don't show tombstoned search results
kegsay Aug 8, 2022
8fd8b84
Merge branch 'develop' into kegan/sync-v3
kegsay Aug 8, 2022
2d1385a
Remove unused imports
kegsay Aug 8, 2022
0e1272c
Add SYNCV3_SECRET to proxy to ensure it starts up; correct aliases fo…
kegsay Aug 8, 2022
6dd3cd4
Add another basic sliding sync e2e test
kegsay Aug 10, 2022
67e1e97
Merge branch 'develop' into kegan/sync-v3
kegsay Aug 10, 2022
c670db2
Merge branch 'develop' into kegan/sync-v3
kegsay Aug 11, 2022
b6ac97c
Unbreak netlify
kegsay Aug 11, 2022
d9368d9
Add more logging for debugging duplicate rooms
kegsay Aug 11, 2022
cda609d
If sliding sync is enabled, always use the rooms result even if it's …
kegsay Aug 11, 2022
d44b31d
Drop-in copy of RoomListStore for sliding sync
kegsay Aug 12, 2022
4a6579f
Remove conditionals from RoomListStore - we have SlidingRoomListStore…
kegsay Aug 12, 2022
831efa4
WIP SlidingRoomListStore
kegsay Aug 12, 2022
b7e1bd0
Add most sliding sync logic to SlidingRoomListStore
kegsay Aug 12, 2022
150b012
Migrate joined count to SS RLS
kegsay Aug 17, 2022
347ffa1
Reinstate the skeleton UI when the list is loading
kegsay Aug 17, 2022
5e976fa
linting
kegsay Aug 17, 2022
bc92ab2
Merge branch 'develop' into kegan/sync-v3
kegsay Aug 17, 2022
328713c
Add support for sticky rooms based on the currently active room
kegsay Aug 18, 2022
c545b35
Add a bunch of passing SS E2E tests; some WIP
kegsay Aug 18, 2022
d0e60eb
Unbreak build from git merge
kegsay Aug 18, 2022
ee42af1
Suppress unread indicators in sliding sync mode
kegsay Aug 18, 2022
80c5047
Merge branch 'develop' into kegan/sync-v3
t3chguy Aug 19, 2022
43ba625
Add regression test for https://github.com/matrix-org/sliding-sync/is…
kegsay Aug 19, 2022
7a6b754
Add invite test flows; show the invite list
kegsay Aug 19, 2022
f737cbf
Remove show more click as it wasn't the bug
kegsay Aug 22, 2022
bd9d41c
Linting and i18n
kegsay Aug 22, 2022
cae0c5a
only enable SS by default on netlify
kegsay Aug 22, 2022
3347657
Jest fixes; merge conflict fixes; remove debug logging; use right sor…
kegsay Aug 22, 2022
410d90d
Actually fix jest tests
kegsay Aug 22, 2022
5e308b4
Add support for favourites and low priority
kegsay Aug 23, 2022
cf728ce
Bump sliding sync version
kegsay Aug 25, 2022
70eaa23
Update sliding sync labs to be user configurable
t3chguy Aug 25, 2022
aa89bb4
delint
t3chguy Aug 25, 2022
d089c1e
To disable SS or change proxy URL the user has to log out
t3chguy Aug 26, 2022
3889bd4
Review comments
kegsay Aug 30, 2022
f1481c6
Linting
kegsay Aug 30, 2022
4d3fcab
Apply suggestions from code review
kegsay Sep 5, 2022
54e5763
Update src/stores/room-list/SlidingRoomListStore.ts
kegsay Sep 5, 2022
c2598aa
Review comments
kegsay Sep 5, 2022
a1f14a8
Add issue link for TODO markers
kegsay Sep 5, 2022
de82bf5
Merge branch 'develop' into kegan/sync-v3
kegsay Sep 5, 2022
3ebb9a1
Linting
kegsay Sep 5, 2022
002e00e
Apply suggestions from code review
kegsay Sep 7, 2022
6de02e2
More review comments
kegsay Sep 7, 2022
63334de
More review comments
kegsay Sep 7, 2022
f9a8cfb
stricter types
kegsay Sep 7, 2022
ef8af86
Merge branch 'develop' into kegan/sync-v3
kegsay Sep 7, 2022
1450ccd
Merge branch 'develop' into kegan/sync-v3
t3chguy Sep 7, 2022
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
322 changes: 322 additions & 0 deletions cypress/e2e/sliding-sync/sliding-sync.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,322 @@
/*
Copyright 2022 The Matrix.org Foundation C.I.C.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

/// <reference types="cypress" />

import _ from "lodash";
import { MatrixClient } from "matrix-js-sdk/src/matrix";

import { SynapseInstance } from "../../plugins/synapsedocker";
import { SettingLevel } from "../../../src/settings/SettingLevel";
import { Layout } from "../../../src/settings/enums/Layout";
import { ProxyInstance } from "../../plugins/sliding-sync";

describe("Sliding Sync", () => {
beforeEach(() => {
cy.startSynapse("default").as("synapse").then(synapse => {
cy.startProxy(synapse).as("proxy");
});

cy.all([
cy.get<SynapseInstance>("@synapse"),
cy.get<ProxyInstance>("@proxy"),
]).then(([synapse, proxy]) => {
cy.enableLabsFeature("feature_sliding_sync");

cy.intercept("/config.json?cachebuster=*", req => {
return req.continue(res => {
res.send(200, {
...res.body,
setting_defaults: {
feature_sliding_sync_proxy_url: `http://localhost:${proxy.port}`,
},
});
});
});

cy.initTestUser(synapse, "Sloth").then(() => {
return cy.window({ log: false }).then(() => {
cy.createRoom({ name: "Test Room" }).as("roomId");
});
});
});
});

afterEach(() => {
cy.get<SynapseInstance>("@synapse").then(cy.stopSynapse);
cy.get<ProxyInstance>("@proxy").then(cy.stopProxy);
});

// assert order
const checkOrder = (wantOrder: string[]) => {
cy.contains(".mx_RoomSublist", "Rooms").find(".mx_RoomTile_title").should((elements) => {
expect(_.map(elements, (e) => {
return e.textContent;
}), "rooms are sorted").to.deep.equal(wantOrder);
});
};
const bumpRoom = (alias: string) => {
// Send a message into the given room, this should bump the room to the top
cy.get<string>(alias).then((roomId) => {
return cy.sendEvent(roomId, null, "m.room.message", {
body: "Hello world",
msgtype: "m.text",
});
});
};
const createAndJoinBob = () => {
// create a Bob user
cy.get<SynapseInstance>("@synapse").then((synapse) => {
kegsay marked this conversation as resolved.
Show resolved Hide resolved
return cy.getBot(synapse, {
displayName: "Bob",
}).as("bob");
});

// invite Bob to Test Room and accept then send a message.
cy.all([cy.get<string>("@roomId"), cy.get<MatrixClient>("@bob")]).then(([roomId, bob]) => {
kegsay marked this conversation as resolved.
Show resolved Hide resolved
return cy.inviteUser(roomId, bob.getUserId()).then(() => {
return bob.joinRoom(roomId);
});
});
};

// sanity check everything works
it("should correctly render expected messages", () => {
cy.get<string>("@roomId").then(roomId => cy.visit("/#/room/" + roomId));
cy.setSettingValue("layout", null, SettingLevel.DEVICE, Layout.IRC);

// Wait until configuration is finished
cy.contains(
".mx_RoomView_body .mx_GenericEventListSummary .mx_GenericEventListSummary_summary",
"created and configured the room.",
);

// Click "expand" link button
cy.get(".mx_GenericEventListSummary_toggle[aria-expanded=false]").click();
});

it("should render the Rooms list in reverse chronological order by default and allowing sorting A-Z", () => {
// create rooms and check room names are correct
cy.createRoom({ name: "Apple" }).then(() => cy.contains(".mx_RoomSublist", "Apple"));
cy.createRoom({ name: "Pineapple" }).then(() => cy.contains(".mx_RoomSublist", "Pineapple"));
cy.createRoom({ name: "Orange" }).then(() => cy.contains(".mx_RoomSublist", "Orange"));
// check the rooms are in the right order
cy.get(".mx_RoomTile").should('have.length', 4); // due to the Test Room in beforeEach
checkOrder([
"Orange", "Pineapple", "Apple", "Test Room",
]);

cy.contains(".mx_RoomSublist", "Rooms").find(".mx_RoomSublist_menuButton").click({ force: true });
cy.contains("A-Z").click();
cy.get('.mx_StyledRadioButton_checked').should("contain.text", "A-Z");
weeman1337 marked this conversation as resolved.
Show resolved Hide resolved
checkOrder([
"Apple", "Orange", "Pineapple", "Test Room",
]);
});

it("should move rooms around as new events arrive", () => {
// create rooms and check room names are correct
cy.createRoom({ name: "Apple" }).as("roomA").then(() => cy.contains(".mx_RoomSublist", "Apple"));
cy.createRoom({ name: "Pineapple" }).as("roomP").then(() => cy.contains(".mx_RoomSublist", "Pineapple"));
cy.createRoom({ name: "Orange" }).as("roomO").then(() => cy.contains(".mx_RoomSublist", "Orange"));

// Select the Test Room
cy.contains(".mx_RoomTile", "Test Room").click();

checkOrder([
"Orange", "Pineapple", "Apple", "Test Room",
]);
bumpRoom("@roomA");
checkOrder([
"Apple", "Orange", "Pineapple", "Test Room",
]);
bumpRoom("@roomO");
checkOrder([
"Orange", "Apple", "Pineapple", "Test Room",
]);
bumpRoom("@roomO");
checkOrder([
"Orange", "Apple", "Pineapple", "Test Room",
]);
bumpRoom("@roomP");
checkOrder([
"Pineapple", "Orange", "Apple", "Test Room",
]);
});

it("should not move the selected room: it should be sticky", () => {
// create rooms and check room names are correct
cy.createRoom({ name: "Apple" }).as("roomA").then(() => cy.contains(".mx_RoomSublist", "Apple"));
cy.createRoom({ name: "Pineapple" }).as("roomP").then(() => cy.contains(".mx_RoomSublist", "Pineapple"));
cy.createRoom({ name: "Orange" }).as("roomO").then(() => cy.contains(".mx_RoomSublist", "Orange"));

// Given a list of Orange, Pineapple, Apple - if Pineapple is active and a message is sent in Apple, the list should
// turn into Apple, Pineapple, Orange - the index position of Pineapple never changes even though the list should technically
// be Apple, Orange Pineapple - only when you click on a different room do things reshuffle.

// Select the Pineapple room
cy.contains(".mx_RoomTile", "Pineapple").click();
checkOrder([
"Orange", "Pineapple", "Apple", "Test Room",
]);

// Move Apple
bumpRoom("@roomA");
checkOrder([
"Apple", "Pineapple", "Orange", "Test Room",
]);

// Select the Test Room
cy.contains(".mx_RoomTile", "Test Room").click();

// the rooms reshuffle to match reality
checkOrder([
"Apple", "Orange", "Pineapple", "Test Room",
]);
});

it("should show the right unread notifications", () => {
createAndJoinBob();

// send a message in the test room: unread notif count shoould increment
cy.all([cy.get<string>("@roomId"), cy.get<MatrixClient>("@bob")]).then(([roomId, bob]) => {
return bob.sendTextMessage(roomId, "Hello World");
});

// check that there is an unread notification (grey) as 1
cy.contains(".mx_RoomTile", "Test Room").contains(".mx_NotificationBadge_count", "1");
cy.get(".mx_NotificationBadge").should("not.have.class", "mx_NotificationBadge_highlighted");

// send an @mention: highlight count (red) should be 2.
cy.all([cy.get<string>("@roomId"), cy.get<MatrixClient>("@bob")]).then(([roomId, bob]) => {
return bob.sendTextMessage(roomId, "Hello Sloth");
});
cy.contains(".mx_RoomTile", "Test Room").contains(".mx_NotificationBadge_count", "2");
cy.get(".mx_NotificationBadge").should("have.class", "mx_NotificationBadge_highlighted");

// click on the room, the notif counts should disappear
cy.contains(".mx_RoomTile", "Test Room").click();
cy.contains(".mx_RoomTile", "Test Room").should("not.have.class", "mx_NotificationBadge_count");
});

it("should not show unread indicators", () => { // TODO: for now. Later we should.
createAndJoinBob();

// disable notifs in this room (TODO: CS API call?)
cy.contains(".mx_RoomTile", "Test Room").find(".mx_RoomTile_notificationsButton").click({ force: true });
cy.contains("None").click();

// create a new room so we know when the message has been received as it'll re-shuffle the room list
cy.createRoom({
name: "Dummy",
});
checkOrder([
"Dummy", "Test Room",
]);

cy.all([cy.get<string>("@roomId"), cy.get<MatrixClient>("@bob")]).then(([roomId, bob]) => {
return bob.sendTextMessage(roomId, "Do you read me?");
});
// wait for this message to arrive, tell by the room list resorting
checkOrder([
"Test Room", "Dummy",
]);

cy.contains(".mx_RoomTile", "Test Room").get(".mx_NotificationBadge").should("not.exist");
});

it("should update user settings promptly", () => {
kegsay marked this conversation as resolved.
Show resolved Hide resolved
cy.get(".mx_UserMenu_userAvatar").click();
cy.contains("All settings").click();
cy.contains("Preferences").click();
cy.contains(".mx_SettingsFlag", "Show timestamps in 12 hour format").should("exist").find(
".mx_ToggleSwitch_on").should("not.exist");
cy.contains(".mx_SettingsFlag", "Show timestamps in 12 hour format").should("exist").find(
".mx_ToggleSwitch_ball").click();
cy.contains(".mx_SettingsFlag", "Show timestamps in 12 hour format", { timeout: 2000 }).should("exist").find(
".mx_ToggleSwitch_on", { timeout: 2000 },
).should("exist");
});

it("should show and be able to accept/reject/rescind invites", () => {
createAndJoinBob();

let clientUserId;
cy.getClient().then((cli) => {
clientUserId = cli.getUserId();
});

// invite Sloth into 3 rooms:
// - roomJoin: will join this room
// - roomReject: will reject the invite
// - roomRescind: will make Bob rescind the invite
let roomJoin; let roomReject; let roomRescind; let bobClient;
cy.get<MatrixClient>("@bob").then((bob) => {
bobClient = bob;
return Promise.all([
bob.createRoom({ name: "Join" }),
bob.createRoom({ name: "Reject" }),
bob.createRoom({ name: "Rescind" }),
]);
}).then(([join, reject, rescind]) => {
roomJoin = join.room_id;
roomReject = reject.room_id;
roomRescind = rescind.room_id;
return Promise.all([
bobClient.invite(roomJoin, clientUserId),
bobClient.invite(roomReject, clientUserId),
bobClient.invite(roomRescind, clientUserId),
]);
});

// wait for them all to be on the UI
cy.get(".mx_RoomTile").should('have.length', 4); // due to the Test Room in beforeEach

cy.contains(".mx_RoomTile", "Join").click();
cy.contains(".mx_AccessibleButton", "Accept").click();

checkOrder([
"Join", "Test Room",
]);

cy.contains(".mx_RoomTile", "Reject").click();
cy.get(".mx_RoomView").contains(".mx_AccessibleButton", "Reject").click();

// wait for the rejected room to disappear
cy.get(".mx_RoomTile").should('have.length', 3);

// check the lists are correct
checkOrder([
"Join", "Test Room",
]);
cy.contains(".mx_RoomSublist", "Invites").find(".mx_RoomTile_title").should((elements) => {
expect(_.map(elements, (e) => {
return e.textContent;
}), "rooms are sorted").to.deep.equal(["Rescind"]);
});

// now rescind the invite
cy.get<MatrixClient>("@bob").then((bob) => {
return bob.kick(roomRescind, clientUserId);
});

// wait for the rescind to take effect and check the joined list once more
cy.get(".mx_RoomTile").should('have.length', 2);
checkOrder([
"Join", "Test Room",
]);
});
});
2 changes: 2 additions & 0 deletions cypress/global.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ import type {
RoomStateEvent,
Visibility,
RoomMemberEvent,
ICreateClientOpts,
} from "matrix-js-sdk/src/matrix";
import type { MatrixDispatcher } from "../src/dispatcher/dispatcher";
import type PerformanceMonitor from "../src/performance";
Expand Down Expand Up @@ -55,6 +56,7 @@ declare global {
MemoryCryptoStore: typeof MemoryCryptoStore;
Visibility: typeof Visibility;
Preset: typeof Preset;
createClient(opts: ICreateClientOpts | string);
};
}
}
Expand Down
Loading