Merge pull request #4919 from matrix-org/travis/room-list/enable
Enable the new room list by defaultpull/21833/head
						commit
						a70e575b96
					
				|  | @ -14,7 +14,7 @@ See the License for the specific language governing permissions and | |||
| limitations under the License. | ||||
| */ | ||||
| 
 | ||||
| // TODO: Rename on launch: https://github.com/vector-im/riot-web/issues/14231 | ||||
| // TODO: Rename on launch: https://github.com/vector-im/riot-web/issues/14367 | ||||
| 
 | ||||
| $tagPanelWidth: 70px; // only applies in this file, used for calculations | ||||
| 
 | ||||
|  |  | |||
|  | @ -14,7 +14,7 @@ See the License for the specific language governing permissions and | |||
| limitations under the License. | ||||
| */ | ||||
| 
 | ||||
| // TODO: Rename on launch: https://github.com/vector-im/riot-web/issues/14231 | ||||
| // TODO: Rename on launch: https://github.com/vector-im/riot-web/issues/14367 | ||||
| 
 | ||||
| .mx_RoomBreadcrumbs2 { | ||||
|     width: 100%; | ||||
|  |  | |||
|  | @ -14,7 +14,7 @@ See the License for the specific language governing permissions and | |||
| limitations under the License. | ||||
| */ | ||||
| 
 | ||||
| // TODO: Rename on launch: https://github.com/vector-im/riot-web/issues/14231 | ||||
| // TODO: Rename on launch: https://github.com/vector-im/riot-web/issues/14367 | ||||
| 
 | ||||
| .mx_RoomSublist2 { | ||||
|     // The sublist is a column of rows, essentially | ||||
|  |  | |||
|  | @ -14,7 +14,7 @@ See the License for the specific language governing permissions and | |||
| limitations under the License. | ||||
| */ | ||||
| 
 | ||||
| // TODO: Rename on launch: https://github.com/vector-im/riot-web/issues/14231 | ||||
| // TODO: Rename on launch: https://github.com/vector-im/riot-web/issues/14367 | ||||
| 
 | ||||
| // Note: the room tile expects to be in a flexbox column container | ||||
| .mx_RoomTile2 { | ||||
|  |  | |||
|  | @ -35,8 +35,8 @@ import RoomListStore, { LISTS_UPDATE_EVENT } from "../../stores/room-list/RoomLi | |||
| import {Key} from "../../Keyboard"; | ||||
| import IndicatorScrollbar from "../structures/IndicatorScrollbar"; | ||||
| 
 | ||||
| // TODO: Remove banner on launch: https://github.com/vector-im/riot-web/issues/14231
 | ||||
| // TODO: Rename on launch: https://github.com/vector-im/riot-web/issues/14231
 | ||||
| // TODO: Remove banner on launch: https://github.com/vector-im/riot-web/issues/14367
 | ||||
| // TODO: Rename on launch: https://github.com/vector-im/riot-web/issues/14367
 | ||||
| 
 | ||||
| /******************************************************************* | ||||
|  *   CAUTION                                                       * | ||||
|  |  | |||
|  | @ -668,8 +668,7 @@ class LoggedInView extends React.Component<IProps, IState> { | |||
|                 disabled={this.props.leftDisabled} | ||||
|             /> | ||||
|         ); | ||||
|         if (SettingsStore.isFeatureEnabled("feature_new_room_list")) { | ||||
|             // TODO: Supply props like collapsed and disabled to LeftPanel2
 | ||||
|         if (SettingsStore.getValue("feature_new_room_list")) { | ||||
|             leftPanel = ( | ||||
|                 <LeftPanel2 | ||||
|                     isMinimized={this.props.collapseLhs || false} | ||||
|  |  | |||
|  | @ -25,7 +25,7 @@ import { Key } from "../../Keyboard"; | |||
| import AccessibleButton from "../views/elements/AccessibleButton"; | ||||
| import { Action } from "../../dispatcher/actions"; | ||||
| 
 | ||||
| // TODO: Remove banner on launch: https://github.com/vector-im/riot-web/issues/14231
 | ||||
| // TODO: Remove banner on launch: https://github.com/vector-im/riot-web/issues/14367
 | ||||
| 
 | ||||
| /******************************************************************* | ||||
|  *   CAUTION                                                       * | ||||
|  |  | |||
|  | @ -27,8 +27,8 @@ import RoomListStore from "../../../stores/room-list/RoomListStore2"; | |||
| import { DefaultTagID } from "../../../stores/room-list/models"; | ||||
| import AccessibleTooltipButton from "../elements/AccessibleTooltipButton"; | ||||
| 
 | ||||
| // TODO: Remove banner on launch: https://github.com/vector-im/riot-web/issues/14231
 | ||||
| // TODO: Rename on launch: https://github.com/vector-im/riot-web/issues/14231
 | ||||
| // TODO: Remove banner on launch: https://github.com/vector-im/riot-web/issues/14367
 | ||||
| // TODO: Rename on launch: https://github.com/vector-im/riot-web/issues/14367
 | ||||
| 
 | ||||
| /******************************************************************* | ||||
|  *   CAUTION                                                       * | ||||
|  |  | |||
|  | @ -41,8 +41,8 @@ import { Action } from "../../../dispatcher/actions"; | |||
| import { ViewRoomDeltaPayload } from "../../../dispatcher/payloads/ViewRoomDeltaPayload"; | ||||
| import { RoomNotificationStateStore } from "../../../stores/notifications/RoomNotificationStateStore"; | ||||
| 
 | ||||
| // TODO: Remove banner on launch: https://github.com/vector-im/riot-web/issues/14231
 | ||||
| // TODO: Rename on launch: https://github.com/vector-im/riot-web/issues/14231
 | ||||
| // TODO: Remove banner on launch: https://github.com/vector-im/riot-web/issues/14367
 | ||||
| // TODO: Rename on launch: https://github.com/vector-im/riot-web/issues/14367
 | ||||
| 
 | ||||
| /******************************************************************* | ||||
|  *   CAUTION                                                       * | ||||
|  |  | |||
|  | @ -48,8 +48,8 @@ import { polyfillTouchEvent } from "../../../@types/polyfill"; | |||
| import { RoomNotificationStateStore } from "../../../stores/notifications/RoomNotificationStateStore"; | ||||
| import RoomListLayoutStore from "../../../stores/room-list/RoomListLayoutStore"; | ||||
| 
 | ||||
| // TODO: Remove banner on launch: https://github.com/vector-im/riot-web/issues/14231
 | ||||
| // TODO: Rename on launch: https://github.com/vector-im/riot-web/issues/14231
 | ||||
| // TODO: Remove banner on launch: https://github.com/vector-im/riot-web/issues/14367
 | ||||
| // TODO: Rename on launch: https://github.com/vector-im/riot-web/issues/14367
 | ||||
| 
 | ||||
| /******************************************************************* | ||||
|  *   CAUTION                                                       * | ||||
|  |  | |||
|  | @ -55,8 +55,8 @@ import {ActionPayload} from "../../../dispatcher/payloads"; | |||
| import { RoomNotificationStateStore } from "../../../stores/notifications/RoomNotificationStateStore"; | ||||
| import { NotificationState } from "../../../stores/notifications/NotificationState"; | ||||
| 
 | ||||
| // TODO: Remove banner on launch: https://github.com/vector-im/riot-web/issues/14231
 | ||||
| // TODO: Rename on launch: https://github.com/vector-im/riot-web/issues/14231
 | ||||
| // TODO: Remove banner on launch: https://github.com/vector-im/riot-web/issues/14367
 | ||||
| // TODO: Rename on launch: https://github.com/vector-im/riot-web/issues/14367
 | ||||
| 
 | ||||
| /******************************************************************* | ||||
|  *   CAUTION                                                       * | ||||
|  |  | |||
|  | @ -32,12 +32,12 @@ export default class PreferencesUserSettingsTab extends React.Component { | |||
|         'breadcrumbs', | ||||
|     ]; | ||||
| 
 | ||||
|     // TODO: Remove temp structures: https://github.com/vector-im/riot-web/issues/14231
 | ||||
|     // TODO: Remove temp structures: https://github.com/vector-im/riot-web/issues/14367
 | ||||
|     static ROOM_LIST_2_SETTINGS = [ | ||||
|         'breadcrumbs', | ||||
|     ]; | ||||
| 
 | ||||
|     // TODO: Remove temp structures: https://github.com/vector-im/riot-web/issues/14231
 | ||||
|     // TODO: Remove temp structures: https://github.com/vector-im/riot-web/issues/14367
 | ||||
|     static eligibleRoomListSettings = () => { | ||||
|         if (RoomListStoreTempProxy.isUsingNewStore()) { | ||||
|             return PreferencesUserSettingsTab.ROOM_LIST_2_SETTINGS; | ||||
|  |  | |||
|  | @ -147,7 +147,8 @@ export const SETTINGS = { | |||
|         default: false, | ||||
|     }, | ||||
|     "feature_new_room_list": { | ||||
|         isFeature: true, | ||||
|         // TODO: Remove setting: https://github.com/vector-im/riot-web/issues/14367
 | ||||
|         // XXX: We shouldn't have non-features appear like features.
 | ||||
|         displayName: _td("Use the improved room list (will refresh to apply changes)"), | ||||
|         supportedLevels: LEVELS_FEATURE, | ||||
|         default: true, | ||||
|  |  | |||
|  | @ -57,7 +57,7 @@ export class BreadcrumbsStore extends AsyncStoreWithClient<IState> { | |||
|     protected async onAction(payload: ActionPayload) { | ||||
|         if (!this.matrixClient) return; | ||||
| 
 | ||||
|         // TODO: Remove when new room list is made the default: https://github.com/vector-im/riot-web/issues/14231
 | ||||
|         // TODO: Remove when new room list is made the default: https://github.com/vector-im/riot-web/issues/14367
 | ||||
|         if (!RoomListStoreTempProxy.isUsingNewStore()) return; | ||||
| 
 | ||||
|         if (payload.action === 'setting_updated') { | ||||
|  | @ -80,7 +80,7 @@ export class BreadcrumbsStore extends AsyncStoreWithClient<IState> { | |||
|     } | ||||
| 
 | ||||
|     protected async onReady() { | ||||
|         // TODO: Remove when new room list is made the default: https://github.com/vector-im/riot-web/issues/14231
 | ||||
|         // TODO: Remove when new room list is made the default: https://github.com/vector-im/riot-web/issues/14367
 | ||||
|         if (!RoomListStoreTempProxy.isUsingNewStore()) return; | ||||
| 
 | ||||
|         await this.updateRooms(); | ||||
|  | @ -91,7 +91,7 @@ export class BreadcrumbsStore extends AsyncStoreWithClient<IState> { | |||
|     } | ||||
| 
 | ||||
|     protected async onNotReady() { | ||||
|         // TODO: Remove when new room list is made the default: https://github.com/vector-im/riot-web/issues/14231
 | ||||
|         // TODO: Remove when new room list is made the default: https://github.com/vector-im/riot-web/issues/14367
 | ||||
|         if (!RoomListStoreTempProxy.isUsingNewStore()) return; | ||||
| 
 | ||||
|         this.matrixClient.removeListener("Room.myMembership", this.onMyMembership); | ||||
|  |  | |||
|  | @ -99,7 +99,7 @@ class RoomListStore extends Store { | |||
|     } | ||||
| 
 | ||||
|     _checkDisabled() { | ||||
|         this.disabled = SettingsStore.isFeatureEnabled("feature_new_room_list"); | ||||
|         this.disabled = SettingsStore.getValue("feature_new_room_list"); | ||||
|         if (this.disabled) { | ||||
|             console.warn("👋 legacy room list store has been disabled"); | ||||
|         } | ||||
|  |  | |||
|  | @ -192,7 +192,7 @@ export class MessagePreviewStore extends AsyncStoreWithClient<IState> { | |||
|     protected async onAction(payload: ActionPayload) { | ||||
|         if (!this.matrixClient) return; | ||||
| 
 | ||||
|         // TODO: Remove when new room list is made the default: https://github.com/vector-im/riot-web/issues/14231
 | ||||
|         // TODO: Remove when new room list is made the default: https://github.com/vector-im/riot-web/issues/14367
 | ||||
|         if (!RoomListStoreTempProxy.isUsingNewStore()) return; | ||||
| 
 | ||||
|         if (payload.action === 'MatrixActions.Room.timeline' || payload.action === 'MatrixActions.Event.decrypted') { | ||||
|  |  | |||
|  | @ -46,6 +46,12 @@ interface IState { | |||
| export const LISTS_UPDATE_EVENT = "lists_update"; | ||||
| 
 | ||||
| export class RoomListStore2 extends AsyncStore<ActionPayload> { | ||||
|     /** | ||||
|      * Set to true if you're running tests on the store. Should not be touched in | ||||
|      * any other environment. | ||||
|      */ | ||||
|     public static TEST_MODE = false; | ||||
| 
 | ||||
|     private _matrixClient: MatrixClient; | ||||
|     private initialListsGenerated = false; | ||||
|     private enabled = false; | ||||
|  | @ -77,9 +83,43 @@ export class RoomListStore2 extends AsyncStore<ActionPayload> { | |||
|         return this._matrixClient; | ||||
|     } | ||||
| 
 | ||||
|     // TODO: Remove enabled flag with the old RoomListStore: https://github.com/vector-im/riot-web/issues/14231
 | ||||
|     // Intended for test usage
 | ||||
|     public async resetStore() { | ||||
|         await this.reset(); | ||||
|         this.tagWatcher = new TagWatcher(this); | ||||
|         this.filterConditions = []; | ||||
|         this.initialListsGenerated = false; | ||||
|         this._matrixClient = null; | ||||
| 
 | ||||
|         this.algorithm.off(LIST_UPDATED_EVENT, this.onAlgorithmListUpdated); | ||||
|         this.algorithm.off(FILTER_CHANGED, this.onAlgorithmListUpdated); | ||||
|         this.algorithm = new Algorithm(); | ||||
|         this.algorithm.on(LIST_UPDATED_EVENT, this.onAlgorithmListUpdated); | ||||
|         this.algorithm.on(FILTER_CHANGED, this.onAlgorithmListUpdated); | ||||
|     } | ||||
| 
 | ||||
|     // Public for test usage. Do not call this.
 | ||||
|     public async makeReady(client: MatrixClient) { | ||||
|         // TODO: Remove with https://github.com/vector-im/riot-web/issues/14367
 | ||||
|         this.checkEnabled(); | ||||
|         if (!this.enabled) return; | ||||
| 
 | ||||
|         this._matrixClient = client; | ||||
| 
 | ||||
|         // Update any settings here, as some may have happened before we were logically ready.
 | ||||
|         // Update any settings here, as some may have happened before we were logically ready.
 | ||||
|         console.log("Regenerating room lists: Startup"); | ||||
|         await this.readAndCacheSettingsFromStore(); | ||||
|         await this.regenerateAllLists({trigger: false}); | ||||
|         await this.handleRVSUpdate({trigger: false}); // fake an RVS update to adjust sticky room, if needed
 | ||||
| 
 | ||||
|         this.updateFn.mark(); // we almost certainly want to trigger an update.
 | ||||
|         this.updateFn.trigger(); | ||||
|     } | ||||
| 
 | ||||
|     // TODO: Remove enabled flag with the old RoomListStore: https://github.com/vector-im/riot-web/issues/14367
 | ||||
|     private checkEnabled() { | ||||
|         this.enabled = SettingsStore.isFeatureEnabled("feature_new_room_list"); | ||||
|         this.enabled = SettingsStore.getValue("feature_new_room_list"); | ||||
|         if (this.enabled) { | ||||
|             console.log("⚡ new room list store engaged"); | ||||
|         } | ||||
|  | @ -99,7 +139,7 @@ export class RoomListStore2 extends AsyncStore<ActionPayload> { | |||
|      * be used if the calling code will manually trigger the update. | ||||
|      */ | ||||
|     private async handleRVSUpdate({trigger = true}) { | ||||
|         if (!this.enabled) return; // TODO: Remove with https://github.com/vector-im/riot-web/issues/14231
 | ||||
|         if (!this.enabled) return; // TODO: Remove with https://github.com/vector-im/riot-web/issues/14367
 | ||||
|         if (!this.matrixClient) return; // We assume there won't be RVS updates without a client
 | ||||
| 
 | ||||
|         const activeRoomId = RoomViewStore.getRoomId(); | ||||
|  | @ -122,7 +162,14 @@ export class RoomListStore2 extends AsyncStore<ActionPayload> { | |||
|         if (trigger) this.updateFn.trigger(); | ||||
|     } | ||||
| 
 | ||||
|     protected onDispatch(payload: ActionPayload) { | ||||
|     protected async onDispatch(payload: ActionPayload) { | ||||
|         // When we're running tests we can't reliably use setImmediate out of timing concerns.
 | ||||
|         // As such, we use a more synchronous model.
 | ||||
|         if (RoomListStore2.TEST_MODE) { | ||||
|             await this.onDispatchAsync(payload); | ||||
|             return; | ||||
|         } | ||||
| 
 | ||||
|         // We do this to intentionally break out of the current event loop task, allowing
 | ||||
|         // us to instead wait for a more convenient time to run our updates.
 | ||||
|         setImmediate(() => this.onDispatchAsync(payload)); | ||||
|  | @ -135,19 +182,7 @@ export class RoomListStore2 extends AsyncStore<ActionPayload> { | |||
|                 return; | ||||
|             } | ||||
| 
 | ||||
|             // TODO: Remove with https://github.com/vector-im/riot-web/issues/14231
 | ||||
|             this.checkEnabled(); | ||||
|             if (!this.enabled) return; | ||||
| 
 | ||||
|             this._matrixClient = payload.matrixClient; | ||||
| 
 | ||||
|             // Update any settings here, as some may have happened before we were logically ready.
 | ||||
|             console.log("Regenerating room lists: Startup"); | ||||
|             await this.readAndCacheSettingsFromStore(); | ||||
|             await this.regenerateAllLists({trigger: false}); | ||||
|             await this.handleRVSUpdate({trigger: false}); // fake an RVS update to adjust sticky room, if needed
 | ||||
| 
 | ||||
|             this.updateFn.trigger(); | ||||
|             await this.makeReady(payload.matrixClient); | ||||
| 
 | ||||
|             return; // no point in running the next conditions - they won't match
 | ||||
|         } | ||||
|  | @ -496,10 +531,13 @@ export class RoomListStore2 extends AsyncStore<ActionPayload> { | |||
| 
 | ||||
|     /** | ||||
|      * Regenerates the room whole room list, discarding any previous results. | ||||
|      * | ||||
|      * Note: This is only exposed externally for the tests. Do not call this from within | ||||
|      * the app. | ||||
|      * @param trigger Set to false to prevent a list update from being sent. Should only | ||||
|      * be used if the calling code will manually trigger the update. | ||||
|      */ | ||||
|     private async regenerateAllLists({trigger = true}) { | ||||
|     public async regenerateAllLists({trigger = true}) { | ||||
|         console.warn("Regenerating all room lists"); | ||||
| 
 | ||||
|         const sorts: ITagSortingMap = {}; | ||||
|  |  | |||
|  | @ -24,11 +24,11 @@ import { ITagMap } from "./algorithms/models"; | |||
|  * Temporary RoomListStore proxy. Should be replaced with RoomListStore2 when | ||||
|  * it is available to everyone. | ||||
|  * | ||||
|  * TODO: Delete this: https://github.com/vector-im/riot-web/issues/14231
 | ||||
|  * TODO: Delete this: https://github.com/vector-im/riot-web/issues/14367
 | ||||
|  */ | ||||
| export class RoomListStoreTempProxy { | ||||
|     public static isUsingNewStore(): boolean { | ||||
|         return SettingsStore.isFeatureEnabled("feature_new_room_list"); | ||||
|         return SettingsStore.getValue("feature_new_room_list"); | ||||
|     } | ||||
| 
 | ||||
|     public static addListener(handler: () => void): RoomListStoreTempToken { | ||||
|  |  | |||
|  | @ -1,7 +1,6 @@ | |||
| import React from 'react'; | ||||
| import ReactTestUtils from 'react-dom/test-utils'; | ||||
| import ReactDOM from 'react-dom'; | ||||
| import lolex from 'lolex'; | ||||
| 
 | ||||
| import * as TestUtils from '../../../test-utils'; | ||||
| 
 | ||||
|  | @ -15,11 +14,18 @@ import GroupStore from '../../../../src/stores/GroupStore.js'; | |||
| 
 | ||||
| import { MatrixClient, Room, RoomMember } from 'matrix-js-sdk'; | ||||
| import {DefaultTagID} from "../../../../src/stores/room-list/models"; | ||||
| import RoomListStore, {LISTS_UPDATE_EVENT, RoomListStore2} from "../../../../src/stores/room-list/RoomListStore2"; | ||||
| import RoomListLayoutStore from "../../../../src/stores/room-list/RoomListLayoutStore"; | ||||
| 
 | ||||
| function generateRoomId() { | ||||
|     return '!' + Math.random().toString().slice(2, 10) + ':domain'; | ||||
| } | ||||
| 
 | ||||
| function waitForRoomListStoreUpdate() { | ||||
|     return new Promise((resolve) => { | ||||
|         RoomListStore.instance.once(LISTS_UPDATE_EVENT, () => resolve()); | ||||
|     }); | ||||
| } | ||||
| 
 | ||||
| describe('RoomList', () => { | ||||
|     function createRoom(opts) { | ||||
|  | @ -34,7 +40,6 @@ describe('RoomList', () => { | |||
|     let client = null; | ||||
|     let root = null; | ||||
|     const myUserId = '@me:domain'; | ||||
|     let clock = null; | ||||
| 
 | ||||
|     const movingRoomId = '!someroomid'; | ||||
|     let movingRoom; | ||||
|  | @ -43,25 +48,25 @@ describe('RoomList', () => { | |||
|     let myMember; | ||||
|     let myOtherMember; | ||||
| 
 | ||||
|     beforeEach(function() { | ||||
|     beforeEach(async function(done) { | ||||
|         RoomListStore2.TEST_MODE = true; | ||||
| 
 | ||||
|         TestUtils.stubClient(); | ||||
|         client = MatrixClientPeg.get(); | ||||
|         client.credentials = {userId: myUserId}; | ||||
|         //revert this to prototype method as the test-utils monkey-patches this to return a hardcoded value
 | ||||
|         client.getUserId = MatrixClient.prototype.getUserId; | ||||
| 
 | ||||
|         clock = lolex.install(); | ||||
| 
 | ||||
|         DMRoomMap.makeShared(); | ||||
| 
 | ||||
|         parentDiv = document.createElement('div'); | ||||
|         document.body.appendChild(parentDiv); | ||||
| 
 | ||||
|         const RoomList = sdk.getComponent('views.rooms.RoomList'); | ||||
|         const RoomList = sdk.getComponent('views.rooms.RoomList2'); | ||||
|         const WrappedRoomList = TestUtils.wrapInMatrixClientContext(RoomList); | ||||
|         root = ReactDOM.render( | ||||
|             <DragDropContext> | ||||
|                 <WrappedRoomList searchFilter="" /> | ||||
|                 <WrappedRoomList searchFilter="" onResize={() => {}} /> | ||||
|             </DragDropContext> | ||||
|         , parentDiv); | ||||
|         ReactTestUtils.findRenderedComponentWithType(root, RoomList); | ||||
|  | @ -102,23 +107,29 @@ describe('RoomList', () => { | |||
|         }); | ||||
| 
 | ||||
|         client.getRoom = (roomId) => roomMap[roomId]; | ||||
| 
 | ||||
|         // Now that everything has been set up, prepare and update the store
 | ||||
|         await RoomListStore.instance.makeReady(client); | ||||
| 
 | ||||
|         done(); | ||||
|     }); | ||||
| 
 | ||||
|     afterEach((done) => { | ||||
|     afterEach(async (done) => { | ||||
|         if (parentDiv) { | ||||
|             ReactDOM.unmountComponentAtNode(parentDiv); | ||||
|             parentDiv.remove(); | ||||
|             parentDiv = null; | ||||
|         } | ||||
| 
 | ||||
|         clock.uninstall(); | ||||
|         await RoomListLayoutStore.instance.resetLayouts(); | ||||
|         await RoomListStore.instance.resetStore(); | ||||
| 
 | ||||
|         done(); | ||||
|     }); | ||||
| 
 | ||||
|     function expectRoomInSubList(room, subListTest) { | ||||
|         const RoomSubList = sdk.getComponent('structures.RoomSubList'); | ||||
|         const RoomTile = sdk.getComponent('views.rooms.RoomTile'); | ||||
|         const RoomSubList = sdk.getComponent('views.rooms.RoomSublist2'); | ||||
|         const RoomTile = sdk.getComponent('views.rooms.RoomTile2'); | ||||
| 
 | ||||
|         const subLists = ReactTestUtils.scryRenderedComponentsWithType(root, RoomSubList); | ||||
|         const containingSubList = subLists.find(subListTest); | ||||
|  | @ -140,20 +151,20 @@ describe('RoomList', () => { | |||
|         expect(expectedRoomTile.props.room).toBe(room); | ||||
|     } | ||||
| 
 | ||||
|     function expectCorrectMove(oldTag, newTag) { | ||||
|         const getTagSubListTest = (tag) => { | ||||
|             if (tag === undefined) return (s) => s.props.label.endsWith('Rooms'); | ||||
|             return (s) => s.props.tagName === tag; | ||||
|     function expectCorrectMove(oldTagId, newTagId) { | ||||
|         const getTagSubListTest = (tagId) => { | ||||
|             return (s) => s.props.tagId === tagId; | ||||
|         }; | ||||
| 
 | ||||
|         // Default to finding the destination sublist with newTag
 | ||||
|         const destSubListTest = getTagSubListTest(newTag); | ||||
|         const srcSubListTest = getTagSubListTest(oldTag); | ||||
|         const destSubListTest = getTagSubListTest(newTagId); | ||||
|         const srcSubListTest = getTagSubListTest(oldTagId); | ||||
| 
 | ||||
|         // Set up the room that will be moved such that it has the correct state for a room in
 | ||||
|         // the section for oldTag
 | ||||
|         if (['m.favourite', 'm.lowpriority'].includes(oldTag)) movingRoom.tags = {[oldTag]: {}}; | ||||
|         if (oldTag === DefaultTagID.DM) { | ||||
|         // the section for oldTagId
 | ||||
|         if (oldTagId === DefaultTagID.Favourite || oldTagId === DefaultTagID.LowPriority) { | ||||
|             movingRoom.tags = {[oldTagId]: {}}; | ||||
|         } else if (oldTagId === DefaultTagID.DM) { | ||||
|             // Mock inverse m.direct
 | ||||
|             DMRoomMap.shared().roomToUser = { | ||||
|                 [movingRoom.roomId]: '@someotheruser:domain', | ||||
|  | @ -162,17 +173,12 @@ describe('RoomList', () => { | |||
| 
 | ||||
|         dis.dispatch({action: 'MatrixActions.sync', prevState: null, state: 'PREPARED', matrixClient: client}); | ||||
| 
 | ||||
|         clock.runAll(); | ||||
| 
 | ||||
|         expectRoomInSubList(movingRoom, srcSubListTest); | ||||
| 
 | ||||
|         dis.dispatch({action: 'RoomListActions.tagRoom.pending', request: { | ||||
|             oldTag, newTag, room: movingRoom, | ||||
|             oldTagId, newTagId, room: movingRoom, | ||||
|         }}); | ||||
| 
 | ||||
|         // Run all setTimeouts for dispatches and room list rate limiting
 | ||||
|         clock.runAll(); | ||||
| 
 | ||||
|         expectRoomInSubList(movingRoom, destSubListTest); | ||||
|     } | ||||
| 
 | ||||
|  | @ -269,6 +275,12 @@ describe('RoomList', () => { | |||
|             }; | ||||
|             GroupStore._notifyListeners(); | ||||
| 
 | ||||
|             // We also have to mock the client's getGroup function for the room list to filter it.
 | ||||
|             // It's not smart enough to tell the difference between a real group and a template though.
 | ||||
|             client.getGroup = (groupId) => { | ||||
|                 return {groupId}; | ||||
|             }; | ||||
| 
 | ||||
|             // Select tag
 | ||||
|             dis.dispatch({action: 'select_tag', tag: '+group:domain'}, true); | ||||
|         } | ||||
|  | @ -277,17 +289,14 @@ describe('RoomList', () => { | |||
|             setupSelectedTag(); | ||||
|         }); | ||||
| 
 | ||||
|         it('displays the correct rooms when the groups rooms are changed', () => { | ||||
|         it('displays the correct rooms when the groups rooms are changed', async () => { | ||||
|             GroupStore.getGroupRooms = (groupId) => { | ||||
|                 return [movingRoom, otherRoom]; | ||||
|             }; | ||||
|             GroupStore._notifyListeners(); | ||||
| 
 | ||||
|             // Run through RoomList debouncing
 | ||||
|             clock.runAll(); | ||||
| 
 | ||||
|             // By default, the test will
 | ||||
|             expectRoomInSubList(otherRoom, (s) => s.props.label.endsWith('Rooms')); | ||||
|             await waitForRoomListStoreUpdate(); | ||||
|             expectRoomInSubList(otherRoom, (s) => s.props.tagId === DefaultTagID.Untagged); | ||||
|         }); | ||||
| 
 | ||||
|         itDoesCorrectOptimisticUpdatesForDraggedRoomTiles(); | ||||
|  |  | |||
|  | @ -15,10 +15,12 @@ See the License for the specific language governing permissions and | |||
| limitations under the License. | ||||
| */ | ||||
| 
 | ||||
| const {findSublist} = require("./create-room"); | ||||
| 
 | ||||
| module.exports = async function acceptInvite(session, name) { | ||||
|     session.log.step(`accepts "${name}" invite`); | ||||
|     //TODO: brittle selector
 | ||||
|     const invitesHandles = await session.queryAll('.mx_RoomTile_name.mx_RoomTile_invite'); | ||||
|     const inviteSublist = await findSublist(session, "invites"); | ||||
|     const invitesHandles = await inviteSublist.$$(".mx_RoomTile2_name"); | ||||
|     const invitesWithText = await Promise.all(invitesHandles.map(async (inviteHandle) => { | ||||
|         const text = await session.innerText(inviteHandle); | ||||
|         return {inviteHandle, text}; | ||||
|  |  | |||
|  | @ -16,21 +16,27 @@ limitations under the License. | |||
| */ | ||||
| 
 | ||||
| async function openRoomDirectory(session) { | ||||
|     const roomDirectoryButton = await session.query('.mx_LeftPanel_explore .mx_AccessibleButton'); | ||||
|     const roomDirectoryButton = await session.query('.mx_LeftPanel2_exploreButton'); | ||||
|     await roomDirectoryButton.click(); | ||||
| } | ||||
| 
 | ||||
| async function findSublist(session, name) { | ||||
|     const sublists = await session.queryAll('.mx_RoomSublist2'); | ||||
|     for (const sublist of sublists) { | ||||
|         const header = await sublist.$('.mx_RoomSublist2_headerText'); | ||||
|         const headerText = await session.innerText(header); | ||||
|         if (headerText.toLowerCase().includes(name.toLowerCase())) { | ||||
|             return sublist; | ||||
|         } | ||||
|     } | ||||
|     throw new Error(`could not find room list section that contains '${name}' in header`); | ||||
| } | ||||
| 
 | ||||
| async function createRoom(session, roomName, encrypted=false) { | ||||
|     session.log.step(`creates room "${roomName}"`); | ||||
| 
 | ||||
|     const roomListHeaders = await session.queryAll('.mx_RoomSubList_labelContainer'); | ||||
|     const roomListHeaderLabels = await Promise.all(roomListHeaders.map(h => session.innerText(h))); | ||||
|     const roomsIndex = roomListHeaderLabels.findIndex(l => l.toLowerCase().includes("rooms")); | ||||
|     if (roomsIndex === -1) { | ||||
|         throw new Error("could not find room list section that contains 'rooms' in header"); | ||||
|     } | ||||
|     const roomsHeader = roomListHeaders[roomsIndex]; | ||||
|     const addRoomButton = await roomsHeader.$(".mx_RoomSubList_addRoom"); | ||||
|     const roomsSublist = await findSublist(session, "rooms"); | ||||
|     const addRoomButton = await roomsSublist.$(".mx_RoomSublist2_auxButton"); | ||||
|     await addRoomButton.click(); | ||||
| 
 | ||||
|     const roomNameInput = await session.query('.mx_CreateRoomDialog_name input'); | ||||
|  | @ -51,14 +57,8 @@ async function createRoom(session, roomName, encrypted=false) { | |||
| async function createDm(session, invitees) { | ||||
|     session.log.step(`creates DM with ${JSON.stringify(invitees)}`); | ||||
| 
 | ||||
|     const roomListHeaders = await session.queryAll('.mx_RoomSubList_labelContainer'); | ||||
|     const roomListHeaderLabels = await Promise.all(roomListHeaders.map(h => session.innerText(h))); | ||||
|     const dmsIndex = roomListHeaderLabels.findIndex(l => l.toLowerCase().includes('direct messages')); | ||||
|     if (dmsIndex === -1) { | ||||
|         throw new Error("could not find room list section that contains 'direct messages' in header"); | ||||
|     } | ||||
|     const dmsHeader = roomListHeaders[dmsIndex]; | ||||
|     const startChatButton = await dmsHeader.$(".mx_RoomSubList_addRoom"); | ||||
|     const dmsSublist = await findSublist(session, "people"); | ||||
|     const startChatButton = await dmsSublist.$(".mx_RoomSublist2_auxButton"); | ||||
|     await startChatButton.click(); | ||||
| 
 | ||||
|     const inviteesEditor = await session.query('.mx_InviteDialog_editor textarea'); | ||||
|  | @ -83,4 +83,4 @@ async function createDm(session, invitees) { | |||
|     session.log.done(); | ||||
| } | ||||
| 
 | ||||
| module.exports = {openRoomDirectory, createRoom, createDm}; | ||||
| module.exports = {openRoomDirectory, findSublist, createRoom, createDm}; | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue
	
	 Travis Ralston
						Travis Ralston