RocketChat/Rocket.Chat

View on GitHub
apps/meteor/client/sidebar/header/MatrixFederationSearch/MatrixFederationSearch.spec.tsx

Summary

Maintainability
A
0 mins
Test Coverage
import { mockAppRoot } from '@rocket.chat/mock-providers';
import { render, screen, within } from '@testing-library/react';
import userEvent from '@testing-library/user-event';
import React from 'react';
import { VirtuosoMockContext } from 'react-virtuoso';

import MatrixFederationSearch from './MatrixFederationSearch';

jest.mock('../../../lib/rooms/roomCoordinator', () => ({
    roomCoordinator: {},
}));

const renderMatrixFederationSearch = (
    serverList = [
        { name: `server-1`, default: true, local: false },
        { name: `server-2`, default: false, local: false },
        { name: `server-3`, default: false, local: false },
    ],
) => {
    return render(<></>, {
        legacyRoot: true,
        wrapper: mockAppRoot()
            .withEndpoint('GET', '/v1/federation/listServersByUser', () => ({
                servers: serverList,
            }))
            .withEndpoint('GET', '/v1/federation/searchPublicRooms', ({ serverName, roomName, count }) => ({
                rooms: Array.from({ length: count || 100 }, (_, index) => ({
                    id: `Matrix${index}`,
                    name: `${roomName || 'Matrix'}${index + 1}`,
                    canJoin: true,
                    canonicalAlias: `#${serverName}:matrix.org`,
                    joinedMembers: 44461,
                    topic:
                        'The Official Matrix HQ - chat about Matrix here! | https://matrix.org | https://spec.matrix.org | To support Matrix.org development: https://patreon.com/matrixdotorg | Code of Conduct: https://matrix.org/legal/code-of-conduct/ | This is an English speaking room | The Official Matrix HQ - chat about Matrix here! | https://matrix.org | https://spec.matrix.org | To support Matrix.org development: https://patreon.com/matrixdotorg | Code of Conduct: https://matrix.org/legal/code-of-conduct/ | This is an English speaking room The Official Matrix HQ - chat about Matrix here! | https://matrix.org | https://spec.matrix.org | To support Matrix.org development: https://patreon.com/matrixdotorg | Code of Conduct: https://matrix.org/legal/code-of-conduct/ | This is an English speaking room | The Official Matrix HQ - chat about Matrix here! | https://matrix.org | https://spec.matrix.org | To support Matrix.org development: https://patreon.com/matrixdotorg | Code of Conduct: https://matrix.org/legal/code-of-conduct/ | This is an English speaking room',
                })),
                count: 1,
                total: 73080,
                nextPageToken: 'g6FtzZa3oXK+IUpkemFiTlVQUFh6bENKQWhFbDpmYWJyaWMucHVioWTD',
            }))
            .withEndpoint('POST', '/v1/federation/joinExternalPublicRoom', () => null)
            .withEndpoint('POST', '/v1/federation/addServerByUser', ({ serverName }) => {
                serverList.push({ name: serverName, default: false, local: false });
                return null;
            })
            .withEndpoint('POST', '/v1/federation/removeServerByUser', ({ serverName }) => {
                serverList = serverList.filter((server) => server.name !== serverName);
                return null;
            })
            .withOpenModal(<MatrixFederationSearch onClose={jest.fn()} />)
            .wrap((children) => (
                <VirtuosoMockContext.Provider value={{ viewportHeight: 300, itemHeight: 100 }}>{children}</VirtuosoMockContext.Provider>
            ))
            .build(),
    });
};

const openManageServers = async () => {
    const manageServerLink = await screen.findByRole('button', { name: 'Manage_server_list' });
    await userEvent.click(manageServerLink);
};

it('should render Federated Room search modal', async () => {
    renderMatrixFederationSearch();

    expect(await screen.findByRole('dialog', { name: 'Federation_Federated_room_search' })).toBeInTheDocument();

    expect(await screen.findByRole('listitem', { name: 'Matrix1' }, { timeout: 2000 })).toBeInTheDocument(); // TODO: remove flakyness
    expect(await screen.findByRole('listitem', { name: 'Matrix2' })).toBeInTheDocument();
});

it('should search for rooms', async () => {
    renderMatrixFederationSearch();

    const input = await screen.findByRole('searchbox', { name: 'Search_rooms' });
    expect(input).toBeInTheDocument();
    await userEvent.type(input, 'NotMatrix');

    expect(await screen.findByRole('listitem', { name: 'NotMatrix1' }, { timeout: 2000 })).toBeInTheDocument(); // TODO: remove flakyness
    expect(await screen.findByRole('listitem', { name: 'NotMatrix2' })).toBeInTheDocument();
});

it('should close the modal when joining a room', async () => {
    renderMatrixFederationSearch();

    const firstListItem = await screen.findByRole('listitem', { name: 'Matrix1' });
    const joinButton = await within(firstListItem).findByRole('button', { name: 'Join' });

    await userEvent.click(joinButton);

    expect(screen.queryByRole('dialog')).not.toBeInTheDocument();
});

// TODO: should be a unit test for `MatrixFederationAddServerModal`
describe('server management', () => {
    it('should open the manage server modal', async () => {
        renderMatrixFederationSearch();

        await openManageServers();

        expect(await screen.findByRole('dialog', { name: 'Manage_servers' })).toBeInTheDocument();

        expect(await screen.findByText('server-1')).toBeInTheDocument();
        expect(await screen.findByText('server-2')).toBeInTheDocument();
        expect(await screen.findByText('server-3')).toBeInTheDocument();
    });

    it('should return to the Search modal when clicking cancel', async () => {
        renderMatrixFederationSearch();

        await openManageServers();

        const cancelButton = await screen.findByRole('button', { name: 'Cancel' });
        await userEvent.click(cancelButton);

        expect(await screen.findByRole('dialog', { name: 'Federation_Federated_room_search' })).toBeInTheDocument();
    });

    it('should return to the Search modal with the new server selected', async () => {
        renderMatrixFederationSearch();

        await openManageServers();

        const input = await screen.findByRole('textbox', { name: 'Server_name' });
        await userEvent.type(input, 'server-4');

        const addButton = await screen.findByRole('button', { name: 'Add' });
        await userEvent.click(addButton);

        expect(await screen.findByRole('dialog', { name: 'Federation_Federated_room_search' })).toBeInTheDocument();
        expect(await screen.findByRole('button', { name: 'server-4' })).toBeInTheDocument();
    });

    it('should remove servers from the list', async () => {
        renderMatrixFederationSearch([
            { name: `server-1`, default: true, local: false },
            { name: `server-2`, default: false, local: false },
            { name: `server-3`, default: false, local: false },
            { name: `server-4`, default: false, local: false },
        ]);

        await openManageServers();

        const defaultItem = await screen.findByRole('listitem', { name: 'server-1' });
        await userEvent.hover(defaultItem);
        expect(within(defaultItem).queryByRole('button', { name: 'Remove' })).not.toBeInTheDocument();

        const lastItem = await screen.findByRole('listitem', { name: 'server-4' });
        await userEvent.hover(lastItem);
        const removeButton = await within(lastItem).findByRole('button', { name: 'Remove' });
        await userEvent.click(removeButton);

        expect(screen.queryByRole('listitem', { name: 'server-4' })).not.toBeInTheDocument();
    });
});