235 lines
		
	
	
		
			8.4 KiB
		
	
	
	
		
			JavaScript
		
	
	
			
		
		
	
	
			235 lines
		
	
	
		
			8.4 KiB
		
	
	
	
		
			JavaScript
		
	
	
import React from 'react';
 | 
						|
import ReactTestUtils from 'react-dom/test-utils';
 | 
						|
import ReactDOM from 'react-dom';
 | 
						|
import { MatrixClient, Room, RoomMember } from 'matrix-js-sdk/src/matrix';
 | 
						|
 | 
						|
import * as TestUtils from '../../../test-utils';
 | 
						|
import { MatrixClientPeg } from '../../../../src/MatrixClientPeg';
 | 
						|
import sdk from '../../../skinned-sdk';
 | 
						|
import dis from '../../../../src/dispatcher/dispatcher';
 | 
						|
import DMRoomMap from '../../../../src/utils/DMRoomMap';
 | 
						|
import { DefaultTagID } from "../../../../src/stores/room-list/models";
 | 
						|
import RoomListStore, { RoomListStoreClass } from "../../../../src/stores/room-list/RoomListStore";
 | 
						|
import RoomListLayoutStore from "../../../../src/stores/room-list/RoomListLayoutStore";
 | 
						|
 | 
						|
function generateRoomId() {
 | 
						|
    return '!' + Math.random().toString().slice(2, 10) + ':domain';
 | 
						|
}
 | 
						|
 | 
						|
describe('RoomList', () => {
 | 
						|
    function createRoom(opts) {
 | 
						|
        const room = new Room(generateRoomId(), MatrixClientPeg.get(), client.getUserId(), {
 | 
						|
            // The room list now uses getPendingEvents(), so we need a detached ordering.
 | 
						|
            pendingEventOrdering: "detached",
 | 
						|
        });
 | 
						|
        if (opts) {
 | 
						|
            Object.assign(room, opts);
 | 
						|
        }
 | 
						|
        return room;
 | 
						|
    }
 | 
						|
 | 
						|
    let parentDiv = null;
 | 
						|
    let client = null;
 | 
						|
    let root = null;
 | 
						|
    const myUserId = '@me:domain';
 | 
						|
 | 
						|
    const movingRoomId = '!someroomid';
 | 
						|
    let movingRoom;
 | 
						|
    let otherRoom;
 | 
						|
 | 
						|
    let myMember;
 | 
						|
    let myOtherMember;
 | 
						|
 | 
						|
    beforeEach(async function(done) {
 | 
						|
        RoomListStoreClass.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;
 | 
						|
 | 
						|
        DMRoomMap.makeShared();
 | 
						|
 | 
						|
        parentDiv = document.createElement('div');
 | 
						|
        document.body.appendChild(parentDiv);
 | 
						|
 | 
						|
        const RoomList = sdk.getComponent('views.rooms.RoomList');
 | 
						|
        const WrappedRoomList = TestUtils.wrapInMatrixClientContext(RoomList);
 | 
						|
        root = ReactDOM.render(
 | 
						|
            <WrappedRoomList searchFilter="" onResize={() => {}} />,
 | 
						|
            parentDiv,
 | 
						|
        );
 | 
						|
        ReactTestUtils.findRenderedComponentWithType(root, RoomList);
 | 
						|
 | 
						|
        movingRoom = createRoom({ name: 'Moving room' });
 | 
						|
        expect(movingRoom.roomId).not.toBe(null);
 | 
						|
 | 
						|
        // Mock joined member
 | 
						|
        myMember = new RoomMember(movingRoomId, myUserId);
 | 
						|
        myMember.membership = 'join';
 | 
						|
        movingRoom.updateMyMembership('join');
 | 
						|
        movingRoom.getMember = (userId) => ({
 | 
						|
            [client.credentials.userId]: myMember,
 | 
						|
        }[userId]);
 | 
						|
 | 
						|
        otherRoom = createRoom({ name: 'Other room' });
 | 
						|
        myOtherMember = new RoomMember(otherRoom.roomId, myUserId);
 | 
						|
        myOtherMember.membership = 'join';
 | 
						|
        otherRoom.updateMyMembership('join');
 | 
						|
        otherRoom.getMember = (userId) => ({
 | 
						|
            [client.credentials.userId]: myOtherMember,
 | 
						|
        }[userId]);
 | 
						|
 | 
						|
        // Mock the matrix client
 | 
						|
        client.getRooms = () => [
 | 
						|
            movingRoom,
 | 
						|
            otherRoom,
 | 
						|
            createRoom({ tags: { 'm.favourite': { order: 0.1 } }, name: 'Some other room' }),
 | 
						|
            createRoom({ tags: { 'm.favourite': { order: 0.2 } }, name: 'Some other room 2' }),
 | 
						|
            createRoom({ tags: { 'm.lowpriority': {} }, name: 'Some unimportant room' }),
 | 
						|
            createRoom({ tags: { 'custom.tag': {} }, name: 'Some room customly tagged' }),
 | 
						|
        ];
 | 
						|
        client.getVisibleRooms = client.getRooms;
 | 
						|
 | 
						|
        const roomMap = {};
 | 
						|
        client.getRooms().forEach((r) => {
 | 
						|
            roomMap[r.roomId] = r;
 | 
						|
        });
 | 
						|
 | 
						|
        client.getRoom = (roomId) => roomMap[roomId];
 | 
						|
 | 
						|
        // Now that everything has been set up, prepare and update the store
 | 
						|
        await RoomListStore.instance.makeReady(client);
 | 
						|
 | 
						|
        done();
 | 
						|
    });
 | 
						|
 | 
						|
    afterEach(async (done) => {
 | 
						|
        if (parentDiv) {
 | 
						|
            ReactDOM.unmountComponentAtNode(parentDiv);
 | 
						|
            parentDiv.remove();
 | 
						|
            parentDiv = null;
 | 
						|
        }
 | 
						|
 | 
						|
        await RoomListLayoutStore.instance.resetLayouts();
 | 
						|
        await RoomListStore.instance.resetStore();
 | 
						|
 | 
						|
        done();
 | 
						|
    });
 | 
						|
 | 
						|
    function expectRoomInSubList(room, subListTest) {
 | 
						|
        const RoomSubList = sdk.getComponent('views.rooms.RoomSublist');
 | 
						|
        const RoomTile = sdk.getComponent('views.rooms.RoomTile');
 | 
						|
 | 
						|
        const subLists = ReactTestUtils.scryRenderedComponentsWithType(root, RoomSubList);
 | 
						|
        const containingSubList = subLists.find(subListTest);
 | 
						|
 | 
						|
        let expectedRoomTile;
 | 
						|
        try {
 | 
						|
            const roomTiles = ReactTestUtils.scryRenderedComponentsWithType(containingSubList, RoomTile);
 | 
						|
            console.info({ roomTiles: roomTiles.length });
 | 
						|
            expectedRoomTile = roomTiles.find((tile) => tile.props.room === room);
 | 
						|
        } catch (err) {
 | 
						|
            // truncate the error message because it's spammy
 | 
						|
            err.message = 'Error finding RoomTile for ' + room.roomId + ' in ' +
 | 
						|
                subListTest + ': ' +
 | 
						|
                err.message.split('componentType')[0] + '...';
 | 
						|
            throw err;
 | 
						|
        }
 | 
						|
 | 
						|
        expect(expectedRoomTile).toBeTruthy();
 | 
						|
        expect(expectedRoomTile.props.room).toBe(room);
 | 
						|
    }
 | 
						|
 | 
						|
    function expectCorrectMove(oldTagId, newTagId) {
 | 
						|
        const getTagSubListTest = (tagId) => {
 | 
						|
            return (s) => s.props.tagId === tagId;
 | 
						|
        };
 | 
						|
 | 
						|
        // Default to finding the destination sublist with newTag
 | 
						|
        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 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',
 | 
						|
            };
 | 
						|
        }
 | 
						|
 | 
						|
        dis.dispatch({ action: 'MatrixActions.sync', prevState: null, state: 'PREPARED', matrixClient: client });
 | 
						|
 | 
						|
        expectRoomInSubList(movingRoom, srcSubListTest);
 | 
						|
 | 
						|
        dis.dispatch({ action: 'RoomListActions.tagRoom.pending', request: {
 | 
						|
            oldTagId, newTagId, room: movingRoom,
 | 
						|
        } });
 | 
						|
 | 
						|
        expectRoomInSubList(movingRoom, destSubListTest);
 | 
						|
    }
 | 
						|
 | 
						|
    function itDoesCorrectOptimisticUpdatesForDraggedRoomTiles() {
 | 
						|
        // TODO: Re-enable dragging tests when we support dragging again.
 | 
						|
        describe.skip('does correct optimistic update when dragging from', () => {
 | 
						|
            it('rooms to people', () => {
 | 
						|
                expectCorrectMove(undefined, DefaultTagID.DM);
 | 
						|
            });
 | 
						|
 | 
						|
            it('rooms to favourites', () => {
 | 
						|
                expectCorrectMove(undefined, 'm.favourite');
 | 
						|
            });
 | 
						|
 | 
						|
            it('rooms to low priority', () => {
 | 
						|
                expectCorrectMove(undefined, 'm.lowpriority');
 | 
						|
            });
 | 
						|
 | 
						|
            // XXX: Known to fail - the view does not update immediately to reflect the change.
 | 
						|
            // Whe running the app live, it updates when some other event occurs (likely the
 | 
						|
            // m.direct arriving) that these tests do not fire.
 | 
						|
            xit('people to rooms', () => {
 | 
						|
                expectCorrectMove(DefaultTagID.DM, undefined);
 | 
						|
            });
 | 
						|
 | 
						|
            it('people to favourites', () => {
 | 
						|
                expectCorrectMove(DefaultTagID.DM, 'm.favourite');
 | 
						|
            });
 | 
						|
 | 
						|
            it('people to lowpriority', () => {
 | 
						|
                expectCorrectMove(DefaultTagID.DM, 'm.lowpriority');
 | 
						|
            });
 | 
						|
 | 
						|
            it('low priority to rooms', () => {
 | 
						|
                expectCorrectMove('m.lowpriority', undefined);
 | 
						|
            });
 | 
						|
 | 
						|
            it('low priority to people', () => {
 | 
						|
                expectCorrectMove('m.lowpriority', DefaultTagID.DM);
 | 
						|
            });
 | 
						|
 | 
						|
            it('low priority to low priority', () => {
 | 
						|
                expectCorrectMove('m.lowpriority', 'm.lowpriority');
 | 
						|
            });
 | 
						|
 | 
						|
            it('favourites to rooms', () => {
 | 
						|
                expectCorrectMove('m.favourite', undefined);
 | 
						|
            });
 | 
						|
 | 
						|
            it('favourites to people', () => {
 | 
						|
                expectCorrectMove('m.favourite', DefaultTagID.DM);
 | 
						|
            });
 | 
						|
 | 
						|
            it('favourites to low priority', () => {
 | 
						|
                expectCorrectMove('m.favourite', 'm.lowpriority');
 | 
						|
            });
 | 
						|
        });
 | 
						|
    }
 | 
						|
 | 
						|
    itDoesCorrectOptimisticUpdatesForDraggedRoomTiles();
 | 
						|
});
 | 
						|
 |