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

Commit

Permalink
adds happy path test for <AddPriviligedUsers /> component
Browse files Browse the repository at this point in the history
  • Loading branch information
GoodGuyMarco committed Dec 8, 2022
1 parent 027a044 commit bd9e453
Show file tree
Hide file tree
Showing 3 changed files with 146 additions and 21 deletions.
11 changes: 10 additions & 1 deletion src/components/views/elements/PowerSelector.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -174,7 +174,15 @@ export default class PowerSelector extends React.Component<IProps, IState> {
});
options.push({ value: CUSTOM_VALUE, text: _t("Custom level") });
const optionsElements = options.map((op) => {
return <option value={op.value} key={op.value}>{ op.text }</option>;
return (
<option
value={op.value}
key={op.value}
data-testid={`power-level-option-${op.value}`}
>
{ op.text }
</option>
);
});

picker = (
Expand All @@ -184,6 +192,7 @@ export default class PowerSelector extends React.Component<IProps, IState> {
onChange={this.onSelectChange}
value={String(this.state.selectValue)}
disabled={this.props.disabled}
data-testid='power-level-select-element'
>
{ optionsElements }
</Field>
Expand Down
42 changes: 22 additions & 20 deletions src/components/views/settings/AddPrivilegedUsers.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ See the License for the specific language governing permissions and
limitations under the License.
*/

import React, { FormEvent, useCallback, useContext, useRef, useState } from 'react';
import React, { FormEvent, useContext, useRef, useState } from 'react';
import { Room } from 'matrix-js-sdk/src/models/room';
import { EventType } from "matrix-js-sdk/src/@types/event";

Expand All @@ -40,30 +40,31 @@ export const AddPrivilegedUsers: React.FC<AddPrivilegedUsersProps> = ({ room, de
const [isLoading, setIsLoading] = useState<boolean>(false);
const [powerLevel, setPowerLevel] = useState<number>(defaultUserLevel);
const [selectedUsers, setSelectedUsers] = useState<ICompletion[]>([]);
const filterSuggestions = useCallback(
(user: ICompletion) => {
if (user.completionId === undefined) {
return false;
}

const member = room.getMember(user.completionId);

if (member === null) {
return false;
}

return member.powerLevel <= defaultUserLevel;
},
[room, defaultUserLevel],
);
// const filterSuggestions = useCallback(
// (user: ICompletion) => {
// if (user.completionId === undefined) {
// return false;
// }
//
// const member = room.getMember(user.completionId);
//
// if (member === null) {
// return false;
// }
//
// return member.powerLevel <= defaultUserLevel;
// },
// [room, defaultUserLevel],
// );

const onSubmit = async (event: FormEvent) => {
event.preventDefault();
setIsLoading(true);

const userIds = selectedUsers
.map(selectedUser => selectedUser.completionId)
.filter(userId => userId !== undefined);
.filter(selectedUser => selectedUser.completionId !== undefined)
// undefined completionId's are filtered out but TypeScript does not seem to understand.
.map(selectedUser => selectedUser.completionId!);
const powerLevelEvent = room.currentState.getStateEvents(EventType.RoomPowerLevels, "");

try {
Expand Down Expand Up @@ -92,7 +93,7 @@ export const AddPrivilegedUsers: React.FC<AddPrivilegedUsersProps> = ({ room, de
placeholder={_t("Search users in this room…")}
onSelectionChange={setSelectedUsers}
selection={selectedUsers}
additionalFilter={filterSuggestions}
// additionalFilter={filterSuggestions}
/>
<PowerSelector value={powerLevel} onChange={setPowerLevel} />
<AccessibleButton
Expand All @@ -101,6 +102,7 @@ export const AddPrivilegedUsers: React.FC<AddPrivilegedUsersProps> = ({ room, de
kind='primary'
disabled={!selectedUsers.length || isLoading}
onClick={null}
data-testid='add-privileged-users-submit-button'
>
{ _t('Apply') }
</AccessibleButton>
Expand Down
114 changes: 114 additions & 0 deletions test/components/views/settings/AddPrivilegedUsers-test.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
/*
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.
*/
import React from 'react';
import { act, fireEvent, render, waitFor } from '@testing-library/react';
import userEvent from "@testing-library/user-event";
import { mocked } from "jest-mock";

import {
getMockClientWithEventEmitter,
makeRoomWithStateEvents,
} from "../../../test-utils";
import MatrixClientContext from '../../../../src/contexts/MatrixClientContext';
import { AddPrivilegedUsers } from "../../../../src/components/views/settings/AddPrivilegedUsers";
import UserProvider from "../../../../src/autocomplete/UserProvider";

jest.mock('../../../../src/autocomplete/UserProvider');

describe('<AddPrivilegedUsers />', () => {
const provider = mocked(UserProvider, { shallow: true });
provider.prototype.getCompletions.mockResolvedValue([
{ type: 'user', completion: 'user_1', completionId: '@user_1:host.local', range: { start: 1, end: 1 } },
{ type: 'user', completion: 'user_2', completionId: '@user_2:host.local', range: { start: 1, end: 1 } },
]);

const mockClient = getMockClientWithEventEmitter({
// `makeRoomWithStateEvents` only work's if `getRoom` is present.
getRoom: jest.fn(),
setPowerLevel: jest.fn(),
});
const room = makeRoomWithStateEvents([], { roomId: 'room_id', mockClient: mockClient });

const getComponent = () =>
<MatrixClientContext.Provider value={mockClient}>
<AddPrivilegedUsers
room={room}
defaultUserLevel={0}
/>
</MatrixClientContext.Provider>;

it('checks whether form submit works as intended', async () => {
const { getByTestId, queryAllByTestId } = render(getComponent());

// Verify that the submit button is disabled initially.
const submitButton = getByTestId('add-privileged-users-submit-button');
expect(submitButton).toBeDisabled();

// Find some suggestions and select them.
const autocompleteInput = getByTestId('autocomplete-input');

act(() => {
fireEvent.focus(autocompleteInput);
fireEvent.change(autocompleteInput, { target: { value: 'u' } });
});

await waitFor(() => expect(provider.mock.instances[0].getCompletions).toHaveBeenCalledTimes(1));
const matchOne = getByTestId('autocomplete-suggestion-item-@user_1:host.local');
const matchTwo = getByTestId('autocomplete-suggestion-item-@user_2:host.local');

act(() => {
fireEvent.mouseDown(matchOne);
});

act(() => {
fireEvent.mouseDown(matchTwo);
});

// Check that `defaultUserLevel` is initially set and select a higher power level.
expect((getByTestId('power-level-option-0') as HTMLOptionElement).selected).toBeTruthy();
expect((getByTestId('power-level-option-50') as HTMLOptionElement).selected).toBeFalsy();
expect((getByTestId('power-level-option-100') as HTMLOptionElement).selected).toBeFalsy();

const powerLevelSelect = getByTestId('power-level-select-element');
await userEvent.selectOptions(powerLevelSelect, "100");

expect((getByTestId('power-level-option-0') as HTMLOptionElement).selected).toBeFalsy();
expect((getByTestId('power-level-option-50') as HTMLOptionElement).selected).toBeFalsy();
expect((getByTestId('power-level-option-100') as HTMLOptionElement).selected).toBeTruthy();

// The submit button should be enabled now.
expect(submitButton).toBeEnabled();

// Submit the form.
act(() => {
fireEvent.submit(submitButton);
});

await waitFor(() => expect(mockClient.setPowerLevel).toHaveBeenCalledTimes(1));

// Verify that the submit button is disabled again.
expect(submitButton).toBeDisabled();

// Verify that previously selected items are reset.
const selectionItems = queryAllByTestId('autocomplete-selection-item', { exact: false });
expect(selectionItems).toHaveLength(0);

// Verify that power level select is reset to `defaultUserLevel`.
expect((getByTestId('power-level-option-0') as HTMLOptionElement).selected).toBeTruthy();
expect((getByTestId('power-level-option-50') as HTMLOptionElement).selected).toBeFalsy();
expect((getByTestId('power-level-option-100') as HTMLOptionElement).selected).toBeFalsy();
});
});

0 comments on commit bd9e453

Please sign in to comment.