This repository was archived by the owner on Sep 11, 2024. It is now read-only.
-
-
Notifications
You must be signed in to change notification settings - Fork 808
Implement MSC3575: Sliding Sync #8328
Merged
Merged
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 7fb8656
Disable the labs toggle if sliding_sync_proxy_url is not set
kegsay c735976
Do validation checks on the sliding sync proxy URL before enabling it…
kegsay bebc9f2
Merge branch 'develop' into kegan/sliding-sync
kegsay bddf053
Enable sliding sync and add SlidingSyncManager
kegsay eb76ff4
Get room subscriptions working
kegsay 9b59f05
Hijack renderSublists in sliding sync mode
kegsay e75b48a
Add support for sorting alphabetically/recency and room name filters
kegsay 18cd70b
Filter out tombstoned rooms; start adding show more logic
kegsay 5572292
update the UI when the list is updated
kegsay 12fa287
bugfix: make sure the list sorts numerically
kegsay dbc0d57
Get invites transitioning correctly
kegsay 4efc389
Merge tag 'v3.42.3' into kegan/sync-v3
kegsay 04602c3
Force enable sliding sync and labs for now
kegsay b769779
Linting
kegsay 4369e43
Merge branch 'develop' into kegan/sync-v3
kegsay 92a93f2
Merge branch 'develop' into kegan/sync-v3
kegsay 086c678
Disable spotlight search
kegsay bc3d9f6
Initial cypress plugins for Sliding Sync Proxy
t3chguy 56598cb
Use --rm when running Synapse in Docker for Cypress tests
t3chguy ed6fd78
Merge branch 'develop' of github.com:matrix-org/matrix-react-sdk into…
t3chguy f2751ec
Merge branch 'develop' into kegan/sync-v3
kegsay 71eb8ad
Update src/MatrixClientPeg.ts
kegsay e393185
Update src/components/views/rooms/RoomSublist.tsx
kegsay aa26456
Update src/settings/controllers/SlidingSyncController.ts
kegsay 8613591
Update src/components/views/rooms/RoomSublist.tsx
kegsay 0040bbb
Merge branch 'develop' into kegan/sync-v3
kegsay 9e8a80a
WIP add room searching to spotlight search
kegsay a03c172
Only read sliding sync results when there is a result, else use the l…
kegsay fb1e9c0
Use feature_sliding_sync not slidingSync
kegsay 4143d13
Some review comments
kegsay 79e6ee9
More review comments
kegsay 8f818e4
Use RoomViewStore to set room subscriptions
kegsay 050903d
Comment why any
kegsay 64d941e
Update src/components/views/rooms/RoomSublist.tsx
kegsay b5a7a06
Merge branch 'develop' into t3chguy/cypress-sliding-sync
t3chguy 246a5f4
Merge branch 'develop' of github.com:matrix-org/matrix-react-sdk into…
t3chguy 2ea6b66
Merge branch 't3chguy/cypress-sliding-sync' of github.com:matrix-org/…
t3chguy 332b136
Fix cypress docker abstraction
t3chguy 1ba5bf5
Iterate sliding sync proxy support
t3chguy 0542589
Stash mostly functional test
t3chguy be146ef
Update sliding sync proxy image
t3chguy 2ed801d
i18n
t3chguy da4001f
Add support for spaces; use list ID -> index mappings
kegsay af5018d
When the active space is updated, update the list registration
kegsay a72da80
Set spaces filter in the correct place
kegsay f65637d
Skeleton placeholder whilst loading the space
kegsay 0dc7004
Filter out spaces from the room list
kegsay c22aeb7
Use the new txn_id promises
kegsay a81a6ea
Ensure we actually resolve list registrations
kegsay 34df9d6
Fix matrix-org/sliding-sync#30: don't show tombstoned search results
kegsay 8fd8b84
Merge branch 'develop' into kegan/sync-v3
kegsay 2d1385a
Remove unused imports
kegsay 0e1272c
Add SYNCV3_SECRET to proxy to ensure it starts up; correct aliases fo…
kegsay 6dd3cd4
Add another basic sliding sync e2e test
kegsay 67e1e97
Merge branch 'develop' into kegan/sync-v3
kegsay c670db2
Merge branch 'develop' into kegan/sync-v3
kegsay b6ac97c
Unbreak netlify
kegsay d9368d9
Add more logging for debugging duplicate rooms
kegsay cda609d
If sliding sync is enabled, always use the rooms result even if it's …
kegsay d44b31d
Drop-in copy of RoomListStore for sliding sync
kegsay 4a6579f
Remove conditionals from RoomListStore - we have SlidingRoomListStore…
kegsay 831efa4
WIP SlidingRoomListStore
kegsay b7e1bd0
Add most sliding sync logic to SlidingRoomListStore
kegsay 150b012
Migrate joined count to SS RLS
kegsay 347ffa1
Reinstate the skeleton UI when the list is loading
kegsay 5e976fa
linting
kegsay bc92ab2
Merge branch 'develop' into kegan/sync-v3
kegsay 328713c
Add support for sticky rooms based on the currently active room
kegsay c545b35
Add a bunch of passing SS E2E tests; some WIP
kegsay d0e60eb
Unbreak build from git merge
kegsay ee42af1
Suppress unread indicators in sliding sync mode
kegsay 80c5047
Merge branch 'develop' into kegan/sync-v3
t3chguy 43ba625
Add regression test for https://github.com/matrix-org/sliding-sync/is…
kegsay 7a6b754
Add invite test flows; show the invite list
kegsay f737cbf
Remove show more click as it wasn't the bug
kegsay bd9d41c
Linting and i18n
kegsay cae0c5a
only enable SS by default on netlify
kegsay 3347657
Jest fixes; merge conflict fixes; remove debug logging; use right sor…
kegsay 410d90d
Actually fix jest tests
kegsay 5e308b4
Add support for favourites and low priority
kegsay cf728ce
Bump sliding sync version
kegsay 70eaa23
Update sliding sync labs to be user configurable
t3chguy aa89bb4
delint
t3chguy d089c1e
To disable SS or change proxy URL the user has to log out
t3chguy 3889bd4
Review comments
kegsay f1481c6
Linting
kegsay 4d3fcab
Apply suggestions from code review
kegsay 54e5763
Update src/stores/room-list/SlidingRoomListStore.ts
kegsay c2598aa
Review comments
kegsay a1f14a8
Add issue link for TODO markers
kegsay de82bf5
Merge branch 'develop' into kegan/sync-v3
kegsay 3ebb9a1
Linting
kegsay 002e00e
Apply suggestions from code review
kegsay 6de02e2
More review comments
kegsay 63334de
More review comments
kegsay f9a8cfb
stricter types
kegsay ef8af86
Merge branch 'develop' into kegan/sync-v3
kegsay 1450ccd
Merge branch 'develop' into kegan/sync-v3
t3chguy File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| 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) => { | ||
| 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.
|
||
| 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.
|
||
| 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.
|
||
| 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", | ||
| ]); | ||
| }); | ||
| }); | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.