1
0
mirror of https://github.com/matrix-org/matrix-react-sdk.git synced 2025-08-07 21:23:00 +03:00

Apply prettier formatting

This commit is contained in:
Michael Weimann
2022-12-12 12:24:14 +01:00
parent 1cac306093
commit 526645c791
1576 changed files with 65385 additions and 62478 deletions

View File

@@ -14,43 +14,44 @@ See the License for the specific language governing permissions and
limitations under the License.
*/
import React from 'react';
import { screen, render, fireEvent, waitFor, within, act } from '@testing-library/react';
import React from "react";
import { screen, render, fireEvent, waitFor, within, act } from "@testing-library/react";
import * as TestUtils from '../../test-utils';
import AutocompleteProvider from '../../../src/autocomplete/AutocompleteProvider';
import { ICompletion } from '../../../src/autocomplete/Autocompleter';
import * as TestUtils from "../../test-utils";
import AutocompleteProvider from "../../../src/autocomplete/AutocompleteProvider";
import { ICompletion } from "../../../src/autocomplete/Autocompleter";
import { AutocompleteInput } from "../../../src/components/structures/AutocompleteInput";
describe('AutocompleteInput', () => {
describe("AutocompleteInput", () => {
const mockCompletion: ICompletion[] = [
{ 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 } },
{ 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 constructMockProvider = (data: ICompletion[]) => ({
getCompletions: jest.fn().mockImplementation(async () => data),
}) as unknown as AutocompleteProvider;
const constructMockProvider = (data: ICompletion[]) =>
({
getCompletions: jest.fn().mockImplementation(async () => data),
} as unknown as AutocompleteProvider);
beforeEach(() => {
TestUtils.stubClient();
});
const getEditorInput = () => {
const input = screen.getByTestId('autocomplete-input');
const input = screen.getByTestId("autocomplete-input");
expect(input).toBeDefined();
return input;
};
it('should render suggestions when a query is set', async () => {
it("should render suggestions when a query is set", async () => {
const mockProvider = constructMockProvider(mockCompletion);
const onSelectionChangeMock = jest.fn();
render(
<AutocompleteInput
provider={mockProvider}
placeholder='Search ...'
placeholder="Search ..."
selection={[]}
onSelectionChange={onSelectionChangeMock}
/>,
@@ -60,45 +61,45 @@ describe('AutocompleteInput', () => {
act(() => {
fireEvent.focus(input);
fireEvent.change(input, { target: { value: 'user' } });
fireEvent.change(input, { target: { value: "user" } });
});
await waitFor(() => expect(mockProvider.getCompletions).toHaveBeenCalledTimes(1));
expect(screen.getByTestId('autocomplete-matches').childNodes).toHaveLength(mockCompletion.length);
expect(screen.getByTestId("autocomplete-matches").childNodes).toHaveLength(mockCompletion.length);
});
it('should render selected items passed in via props', () => {
it("should render selected items passed in via props", () => {
const mockProvider = constructMockProvider(mockCompletion);
const onSelectionChangeMock = jest.fn();
render(
<AutocompleteInput
provider={mockProvider}
placeholder='Search ...'
placeholder="Search ..."
selection={mockCompletion}
onSelectionChange={onSelectionChangeMock}
/>,
);
const editor = screen.getByTestId('autocomplete-editor');
const editor = screen.getByTestId("autocomplete-editor");
const selection = within(editor).getAllByTestId("autocomplete-selection-item", { exact: false });
expect(selection).toHaveLength(mockCompletion.length);
});
it('should call onSelectionChange() when an item is removed from selection', () => {
it("should call onSelectionChange() when an item is removed from selection", () => {
const mockProvider = constructMockProvider(mockCompletion);
const onSelectionChangeMock = jest.fn();
render(
<AutocompleteInput
provider={mockProvider}
placeholder='Search ...'
placeholder="Search ..."
selection={mockCompletion}
onSelectionChange={onSelectionChangeMock}
/>,
);
const editor = screen.getByTestId('autocomplete-editor');
const editor = screen.getByTestId("autocomplete-editor");
const removeButtons = within(editor).getAllByTestId("autocomplete-selection-remove-button", { exact: false });
expect(removeButtons).toHaveLength(mockCompletion.length);
@@ -110,39 +111,35 @@ describe('AutocompleteInput', () => {
expect(onSelectionChangeMock).toHaveBeenCalledWith([mockCompletion[1]]);
});
it('should render custom selection element when renderSelection() is defined', () => {
it("should render custom selection element when renderSelection() is defined", () => {
const mockProvider = constructMockProvider(mockCompletion);
const onSelectionChangeMock = jest.fn();
const renderSelection = () => (
<span data-testid='custom-selection-element'>custom selection element</span>
);
const renderSelection = () => <span data-testid="custom-selection-element">custom selection element</span>;
render(
<AutocompleteInput
provider={mockProvider}
placeholder='Search ...'
placeholder="Search ..."
selection={mockCompletion}
onSelectionChange={onSelectionChangeMock}
renderSelection={renderSelection}
/>,
);
expect(screen.getAllByTestId('custom-selection-element')).toHaveLength(mockCompletion.length);
expect(screen.getAllByTestId("custom-selection-element")).toHaveLength(mockCompletion.length);
});
it('should render custom suggestion element when renderSuggestion() is defined', async () => {
it("should render custom suggestion element when renderSuggestion() is defined", async () => {
const mockProvider = constructMockProvider(mockCompletion);
const onSelectionChangeMock = jest.fn();
const renderSuggestion = () => (
<span data-testid='custom-suggestion-element'>custom suggestion element</span>
);
const renderSuggestion = () => <span data-testid="custom-suggestion-element">custom suggestion element</span>;
render(
<AutocompleteInput
provider={mockProvider}
placeholder='Search ...'
placeholder="Search ..."
selection={mockCompletion}
onSelectionChange={onSelectionChangeMock}
renderSuggestion={renderSuggestion}
@@ -153,21 +150,21 @@ describe('AutocompleteInput', () => {
act(() => {
fireEvent.focus(input);
fireEvent.change(input, { target: { value: 'user' } });
fireEvent.change(input, { target: { value: "user" } });
});
await waitFor(() => expect(mockProvider.getCompletions).toHaveBeenCalledTimes(1));
expect(screen.getAllByTestId('custom-suggestion-element')).toHaveLength(mockCompletion.length);
expect(screen.getAllByTestId("custom-suggestion-element")).toHaveLength(mockCompletion.length);
});
it('should mark selected suggestions as selected', async () => {
it("should mark selected suggestions as selected", async () => {
const mockProvider = constructMockProvider(mockCompletion);
const onSelectionChangeMock = jest.fn();
const { container } = render(
<AutocompleteInput
provider={mockProvider}
placeholder='Search ...'
placeholder="Search ..."
selection={mockCompletion}
onSelectionChange={onSelectionChangeMock}
/>,
@@ -177,23 +174,23 @@ describe('AutocompleteInput', () => {
act(() => {
fireEvent.focus(input);
fireEvent.change(input, { target: { value: 'user' } });
fireEvent.change(input, { target: { value: "user" } });
});
await waitFor(() => expect(mockProvider.getCompletions).toHaveBeenCalledTimes(1));
const suggestions = await within(container).findAllByTestId('autocomplete-suggestion-item', { exact: false });
const suggestions = await within(container).findAllByTestId("autocomplete-suggestion-item", { exact: false });
expect(suggestions).toHaveLength(mockCompletion.length);
suggestions.map(suggestion => expect(suggestion).toHaveClass('mx_AutocompleteInput_suggestion--selected'));
suggestions.map((suggestion) => expect(suggestion).toHaveClass("mx_AutocompleteInput_suggestion--selected"));
});
it('should remove the last added selection when backspace is pressed in empty input', () => {
it("should remove the last added selection when backspace is pressed in empty input", () => {
const mockProvider = constructMockProvider(mockCompletion);
const onSelectionChangeMock = jest.fn();
render(
<AutocompleteInput
provider={mockProvider}
placeholder='Search ...'
placeholder="Search ..."
selection={mockCompletion}
onSelectionChange={onSelectionChangeMock}
/>,
@@ -202,20 +199,20 @@ describe('AutocompleteInput', () => {
const input = getEditorInput();
act(() => {
fireEvent.keyDown(input, { key: 'Backspace' });
fireEvent.keyDown(input, { key: "Backspace" });
});
expect(onSelectionChangeMock).toHaveBeenCalledWith([mockCompletion[0]]);
});
it('should toggle a selected item when a suggestion is clicked', async () => {
it("should toggle a selected item when a suggestion is clicked", async () => {
const mockProvider = constructMockProvider(mockCompletion);
const onSelectionChangeMock = jest.fn();
const { container } = render(
<AutocompleteInput
provider={mockProvider}
placeholder='Search ...'
placeholder="Search ..."
selection={[]}
onSelectionChange={onSelectionChangeMock}
/>,
@@ -225,10 +222,10 @@ describe('AutocompleteInput', () => {
act(() => {
fireEvent.focus(input);
fireEvent.change(input, { target: { value: 'user' } });
fireEvent.change(input, { target: { value: "user" } });
});
const suggestions = await within(container).findAllByTestId('autocomplete-suggestion-item', { exact: false });
const suggestions = await within(container).findAllByTestId("autocomplete-suggestion-item", { exact: false });
act(() => {
fireEvent.mouseDown(suggestions[0]);

View File

@@ -85,4 +85,3 @@ describe("ContextMenu", () => {
});
});
});

View File

@@ -14,12 +14,12 @@ See the License for the specific language governing permissions and
limitations under the License.
*/
import { MatrixClient, MatrixEvent } from 'matrix-js-sdk/src/matrix';
import { MatrixClient, MatrixEvent } from "matrix-js-sdk/src/matrix";
import { EventType } from "matrix-js-sdk/src/@types/event";
import { CallState } from "matrix-js-sdk/src/webrtc/call";
import { stubClient } from '../../test-utils';
import { MatrixClientPeg } from '../../../src/MatrixClientPeg';
import { stubClient } from "../../test-utils";
import { MatrixClientPeg } from "../../../src/MatrixClientPeg";
import LegacyCallEventGrouper, { CustomCallState } from "../../../src/components/structures/LegacyCallEventGrouper";
const MY_USER_ID = "@me:here";
@@ -27,7 +27,7 @@ const THEIR_USER_ID = "@they:here";
let client: MatrixClient;
describe('LegacyCallEventGrouper', () => {
describe("LegacyCallEventGrouper", () => {
beforeEach(() => {
stubClient();
client = MatrixClientPeg.get();

View File

@@ -15,13 +15,13 @@ See the License for the specific language governing permissions and
limitations under the License.
*/
import React from 'react';
import React from "react";
import ReactDOM from "react-dom";
import { EventEmitter } from "events";
import { Room, RoomMember } from 'matrix-js-sdk/src/matrix';
import FakeTimers from '@sinonjs/fake-timers';
import { render } from '@testing-library/react';
import { Thread } from 'matrix-js-sdk/src/models/thread';
import { Room, RoomMember } from "matrix-js-sdk/src/matrix";
import FakeTimers from "@sinonjs/fake-timers";
import { render } from "@testing-library/react";
import { Thread } from "matrix-js-sdk/src/models/thread";
import MessagePanel, { shouldFormContinuation } from "../../../src/components/structures/MessagePanel";
import SettingsStore from "../../../src/settings/SettingsStore";
@@ -34,21 +34,21 @@ import {
makeBeaconInfoEvent,
mockClientMethodsEvents,
mockClientMethodsUser,
} from '../../test-utils';
import ResizeNotifier from '../../../src/utils/ResizeNotifier';
import { IRoomState } from '../../../src/components/structures/RoomView';
} from "../../test-utils";
import ResizeNotifier from "../../../src/utils/ResizeNotifier";
import { IRoomState } from "../../../src/components/structures/RoomView";
jest.mock('../../../src/utils/beacon', () => ({
jest.mock("../../../src/utils/beacon", () => ({
useBeacon: jest.fn(),
}));
const roomId = "!roomId:server_name";
describe('MessagePanel', function() {
describe("MessagePanel", function () {
let clock = null;
const realSetTimeout = window.setTimeout;
const events = mkEvents();
const userId = '@me:here';
const userId = "@me:here";
const client = getMockClientWithEventEmitter({
...mockClientMethodsUser(userId),
...mockClientMethodsEvents(),
@@ -61,22 +61,22 @@ describe('MessagePanel', function() {
const room = new Room(roomId, client, userId);
const bobMember = new RoomMember(roomId, '@bob:id');
bobMember.name = 'Bob';
jest.spyOn(bobMember, 'getAvatarUrl').mockReturnValue('avatar.jpeg');
jest.spyOn(bobMember, 'getMxcAvatarUrl').mockReturnValue('mxc://avatar.url/image.png');
const bobMember = new RoomMember(roomId, "@bob:id");
bobMember.name = "Bob";
jest.spyOn(bobMember, "getAvatarUrl").mockReturnValue("avatar.jpeg");
jest.spyOn(bobMember, "getMxcAvatarUrl").mockReturnValue("mxc://avatar.url/image.png");
const alice = "@alice:example.org";
const aliceMember = new RoomMember(roomId, alice);
aliceMember.name = 'Alice';
jest.spyOn(aliceMember, 'getAvatarUrl').mockReturnValue('avatar.jpeg');
jest.spyOn(aliceMember, 'getMxcAvatarUrl').mockReturnValue('mxc://avatar.url/image.png');
aliceMember.name = "Alice";
jest.spyOn(aliceMember, "getAvatarUrl").mockReturnValue("avatar.jpeg");
jest.spyOn(aliceMember, "getMxcAvatarUrl").mockReturnValue("mxc://avatar.url/image.png");
const defaultProps = {
resizeNotifier: new EventEmitter as unknown as ResizeNotifier,
resizeNotifier: new EventEmitter() as unknown as ResizeNotifier,
callEventGroupers: new Map(),
room,
className: 'cls',
className: "cls",
events: [],
};
@@ -95,24 +95,26 @@ describe('MessagePanel', function() {
showHiddenEvents: false,
} as unknown as IRoomState;
const getComponent = (props = {}, roomContext: Partial<IRoomState> = {}) =>
const getComponent = (props = {}, roomContext: Partial<IRoomState> = {}) => (
<MatrixClientContext.Provider value={client}>
<RoomContext.Provider value={{ ...defaultRoomContext, ...roomContext }}>
<MessagePanel {...defaultProps} {...props} />
</RoomContext.Provider>);
</MatrixClientContext.Provider>;
</RoomContext.Provider>
);
</MatrixClientContext.Provider>
);
beforeEach(function() {
beforeEach(function () {
jest.clearAllMocks();
// HACK: We assume all settings want to be disabled
jest.spyOn(SettingsStore, 'getValue').mockImplementation((arg) => {
jest.spyOn(SettingsStore, "getValue").mockImplementation((arg) => {
return arg === "showDisplaynameChanges";
});
DMRoomMap.makeShared();
});
afterEach(function() {
afterEach(function () {
if (clock) {
clock.uninstall();
clock = null;
@@ -123,11 +125,14 @@ describe('MessagePanel', function() {
const events = [];
const ts0 = Date.now();
for (let i = 0; i < 10; i++) {
events.push(TestUtilsMatrix.mkMessage(
{
event: true, room: "!room:id", user: "@user:id",
events.push(
TestUtilsMatrix.mkMessage({
event: true,
room: "!room:id",
user: "@user:id",
ts: ts0 + i * 1000,
}));
}),
);
}
return events;
}
@@ -135,13 +140,16 @@ describe('MessagePanel', function() {
// Just to avoid breaking Dateseparator tests that might run at 00hrs
function mkOneDayEvents() {
const events = [];
const ts0 = Date.parse('09 May 2004 00:12:00 GMT');
const ts0 = Date.parse("09 May 2004 00:12:00 GMT");
for (let i = 0; i < 10; i++) {
events.push(TestUtilsMatrix.mkMessage(
{
event: true, room: "!room:id", user: "@user:id",
events.push(
TestUtilsMatrix.mkMessage({
event: true,
room: "!room:id",
user: "@user:id",
ts: ts0 + i * 1000,
}));
}),
);
}
return events;
}
@@ -152,26 +160,38 @@ describe('MessagePanel', function() {
const ts0 = Date.now();
let i = 0;
events.push(TestUtilsMatrix.mkMessage({
event: true, room: "!room:id", user: "@user:id",
ts: ts0 + ++i * 1000,
}));
events.push(
TestUtilsMatrix.mkMessage({
event: true,
room: "!room:id",
user: "@user:id",
ts: ts0 + ++i * 1000,
}),
);
for (i = 0; i < 10; i++) {
events.push(TestUtilsMatrix.mkMembership({
event: true, room: "!room:id", user: "@user:id",
target: bobMember,
ts: ts0 + i*1000,
mship: 'join',
prevMship: 'join',
name: 'A user',
}));
events.push(
TestUtilsMatrix.mkMembership({
event: true,
room: "!room:id",
user: "@user:id",
target: bobMember,
ts: ts0 + i * 1000,
mship: "join",
prevMship: "join",
name: "A user",
}),
);
}
events.push(TestUtilsMatrix.mkMessage({
event: true, room: "!room:id", user: "@user:id",
ts: ts0 + ++i*1000,
}));
events.push(
TestUtilsMatrix.mkMessage({
event: true,
room: "!room:id",
user: "@user:id",
ts: ts0 + ++i * 1000,
}),
);
return events;
}
@@ -184,14 +204,18 @@ describe('MessagePanel', function() {
let i = 0;
for (i = 0; i < 10; i++) {
events.push(TestUtilsMatrix.mkMembership({
event: true, room: "!room:id", user: "@user:id",
target: bobMember,
ts: ts0 + i * 1000,
mship: 'join',
prevMship: 'join',
name: 'A user',
}));
events.push(
TestUtilsMatrix.mkMembership({
event: true,
room: "!room:id",
user: "@user:id",
target: bobMember,
ts: ts0 + i * 1000,
mship: "join",
prevMship: "join",
name: "A user",
}),
);
}
return events;
@@ -227,8 +251,8 @@ describe('MessagePanel', function() {
user: alice,
target: aliceMember,
ts: ts0 + 1,
mship: 'join',
name: 'Alice',
mship: "join",
name: "Alice",
}),
mkEvent({
event: true,
@@ -236,7 +260,7 @@ describe('MessagePanel', function() {
room: roomId,
user: alice,
content: {
"join_rule": "invite",
join_rule: "invite",
},
ts: ts0 + 2,
}),
@@ -246,7 +270,7 @@ describe('MessagePanel', function() {
room: roomId,
user: alice,
content: {
"history_visibility": "invited",
history_visibility: "invited",
},
ts: ts0 + 3,
}),
@@ -256,7 +280,7 @@ describe('MessagePanel', function() {
room: roomId,
user: alice,
content: {
"algorithm": "m.megolm.v1.aes-sha2",
algorithm: "m.megolm.v1.aes-sha2",
},
ts: ts0 + 4,
}),
@@ -267,8 +291,8 @@ describe('MessagePanel', function() {
skey: "@bob:example.org",
target: bobMember,
ts: ts0 + 5,
mship: 'invite',
name: 'Bob',
mship: "invite",
name: "Bob",
}),
];
}
@@ -300,52 +324,58 @@ describe('MessagePanel', function() {
return rmContainer && rmContainer.children.length > 0;
}
it('should show the events', function() {
it("should show the events", function () {
const { container } = render(getComponent({ events }));
// just check we have the right number of tiles for now
const tiles = container.getElementsByClassName('mx_EventTile');
const tiles = container.getElementsByClassName("mx_EventTile");
expect(tiles.length).toEqual(10);
});
it('should collapse adjacent member events', function() {
it("should collapse adjacent member events", function () {
const { container } = render(getComponent({ events: mkMelsEvents() }));
// just check we have the right number of tiles for now
const tiles = container.getElementsByClassName('mx_EventTile');
const tiles = container.getElementsByClassName("mx_EventTile");
expect(tiles.length).toEqual(2);
const summaryTiles = container.getElementsByClassName('mx_GenericEventListSummary');
const summaryTiles = container.getElementsByClassName("mx_GenericEventListSummary");
expect(summaryTiles.length).toEqual(1);
});
it('should insert the read-marker in the right place', function() {
const { container } = render(getComponent({
events, readMarkerEventId: events[4].getId(), readMarkerVisible: true,
}));
it("should insert the read-marker in the right place", function () {
const { container } = render(
getComponent({
events,
readMarkerEventId: events[4].getId(),
readMarkerVisible: true,
}),
);
const tiles = container.getElementsByClassName('mx_EventTile');
const tiles = container.getElementsByClassName("mx_EventTile");
// find the <li> which wraps the read marker
const [rm] = container.getElementsByClassName('mx_RoomView_myReadMarker_container');
const [rm] = container.getElementsByClassName("mx_RoomView_myReadMarker_container");
// it should follow the <li> which wraps the event tile for event 4
const eventContainer = ReactDOM.findDOMNode(tiles[4]);
expect(rm.previousSibling).toEqual(eventContainer);
});
it('should show the read-marker that fall in summarised events after the summary', function() {
it("should show the read-marker that fall in summarised events after the summary", function () {
const melsEvents = mkMelsEvents();
const { container } = render(getComponent({
events: melsEvents,
readMarkerEventId: melsEvents[4].getId(),
readMarkerVisible: true,
}));
const { container } = render(
getComponent({
events: melsEvents,
readMarkerEventId: melsEvents[4].getId(),
readMarkerVisible: true,
}),
);
const [summary] = container.getElementsByClassName('mx_GenericEventListSummary');
const [summary] = container.getElementsByClassName("mx_GenericEventListSummary");
// find the <li> which wraps the read marker
const [rm] = container.getElementsByClassName('mx_RoomView_myReadMarker_container');
const [rm] = container.getElementsByClassName("mx_RoomView_myReadMarker_container");
expect(rm.previousSibling).toEqual(summary);
@@ -353,19 +383,21 @@ describe('MessagePanel', function() {
expect(isReadMarkerVisible(rm)).toBeTruthy();
});
it('should hide the read-marker at the end of summarised events', function() {
it("should hide the read-marker at the end of summarised events", function () {
const melsEvents = mkMelsEventsOnly();
const { container } = render(getComponent({
events: melsEvents,
readMarkerEventId: melsEvents[9].getId(),
readMarkerVisible: true,
}));
const { container } = render(
getComponent({
events: melsEvents,
readMarkerEventId: melsEvents[9].getId(),
readMarkerVisible: true,
}),
);
const [summary] = container.getElementsByClassName('mx_GenericEventListSummary');
const [summary] = container.getElementsByClassName("mx_GenericEventListSummary");
// find the <li> which wraps the read marker
const [rm] = container.getElementsByClassName('mx_RoomView_myReadMarker_container');
const [rm] = container.getElementsByClassName("mx_RoomView_myReadMarker_container");
expect(rm.previousSibling).toEqual(summary);
@@ -373,34 +405,38 @@ describe('MessagePanel', function() {
expect(isReadMarkerVisible(rm)).toBeFalsy();
});
it('shows a ghost read-marker when the read-marker moves', function(done) {
it("shows a ghost read-marker when the read-marker moves", function (done) {
// fake the clock so that we can test the velocity animation.
clock = FakeTimers.install();
const { container, rerender } = render(<div>
{ getComponent({
events,
readMarkerEventId: events[4].getId(),
readMarkerVisible: true,
}) }
</div>);
const { container, rerender } = render(
<div>
{getComponent({
events,
readMarkerEventId: events[4].getId(),
readMarkerVisible: true,
})}
</div>,
);
const tiles = container.getElementsByClassName('mx_EventTile');
const tiles = container.getElementsByClassName("mx_EventTile");
// find the <li> which wraps the read marker
const [rm] = container.getElementsByClassName('mx_RoomView_myReadMarker_container');
const [rm] = container.getElementsByClassName("mx_RoomView_myReadMarker_container");
expect(rm.previousSibling).toEqual(tiles[4]);
rerender(<div>
{ getComponent({
events,
readMarkerEventId: events[6].getId(),
readMarkerVisible: true,
}) }
</div>);
rerender(
<div>
{getComponent({
events,
readMarkerEventId: events[6].getId(),
readMarkerVisible: true,
})}
</div>,
);
// now there should be two RM containers
const readMarkers = container.getElementsByClassName('mx_RoomView_myReadMarker_container');
const readMarkers = container.getElementsByClassName("mx_RoomView_myReadMarker_container");
expect(readMarkers.length).toEqual(2);
@@ -420,72 +456,72 @@ describe('MessagePanel', function() {
clock.tick(1000);
realSetTimeout(() => {
// the ghost should now have finished
expect(hr.style.opacity).toEqual('0');
expect(hr.style.opacity).toEqual("0");
done();
}, 100);
}, 100);
});
it('should collapse creation events', function() {
it("should collapse creation events", function () {
const events = mkCreationEvents();
TestUtilsMatrix.upsertRoomStateEvents(room, events);
const { container } = render(getComponent({ events }));
const createEvent = events.find(event => event.getType() === 'm.room.create');
const encryptionEvent = events.find(event => event.getType() === 'm.room.encryption');
const createEvent = events.find((event) => event.getType() === "m.room.create");
const encryptionEvent = events.find((event) => event.getType() === "m.room.encryption");
// we expect that
// - the room creation event, the room encryption event, and Alice inviting Bob,
// should be outside of the room creation summary
// - all other events should be inside the room creation summary
const tiles = container.getElementsByClassName('mx_EventTile');
const tiles = container.getElementsByClassName("mx_EventTile");
expect(tiles[0].getAttribute('data-event-id')).toEqual(createEvent.getId());
expect(tiles[1].getAttribute('data-event-id')).toEqual(encryptionEvent.getId());
expect(tiles[0].getAttribute("data-event-id")).toEqual(createEvent.getId());
expect(tiles[1].getAttribute("data-event-id")).toEqual(encryptionEvent.getId());
const [summaryTile] = container.getElementsByClassName('mx_GenericEventListSummary');
const [summaryTile] = container.getElementsByClassName("mx_GenericEventListSummary");
const summaryEventTiles = summaryTile.getElementsByClassName('mx_EventTile');
const summaryEventTiles = summaryTile.getElementsByClassName("mx_EventTile");
// every event except for the room creation, room encryption, and Bob's
// invite event should be in the event summary
expect(summaryEventTiles.length).toEqual(tiles.length - 3);
});
it('should not collapse beacons as part of creation events', function() {
it("should not collapse beacons as part of creation events", function () {
const events = mkCreationEvents();
const creationEvent = events.find(event => event.getType() === 'm.room.create');
const beaconInfoEvent = makeBeaconInfoEvent(
creationEvent.getSender(),
creationEvent.getRoomId(),
{ isLive: true },
);
const creationEvent = events.find((event) => event.getType() === "m.room.create");
const beaconInfoEvent = makeBeaconInfoEvent(creationEvent.getSender(), creationEvent.getRoomId(), {
isLive: true,
});
const combinedEvents = [...events, beaconInfoEvent];
TestUtilsMatrix.upsertRoomStateEvents(room, combinedEvents);
const { container } = render(getComponent({ events: combinedEvents }));
const [summaryTile] = container.getElementsByClassName('mx_GenericEventListSummary');
const [summaryTile] = container.getElementsByClassName("mx_GenericEventListSummary");
// beacon body is not in the summary
expect(summaryTile.getElementsByClassName('mx_MBeaconBody').length).toBe(0);
expect(summaryTile.getElementsByClassName("mx_MBeaconBody").length).toBe(0);
// beacon tile is rendered
expect(container.getElementsByClassName('mx_MBeaconBody').length).toBe(1);
expect(container.getElementsByClassName("mx_MBeaconBody").length).toBe(1);
});
it('should hide read-marker at the end of creation event summary', function() {
it("should hide read-marker at the end of creation event summary", function () {
const events = mkCreationEvents();
TestUtilsMatrix.upsertRoomStateEvents(room, events);
const { container } = render(getComponent({
events,
readMarkerEventId: events[5].getId(),
readMarkerVisible: true,
}));
const { container } = render(
getComponent({
events,
readMarkerEventId: events[5].getId(),
readMarkerVisible: true,
}),
);
// find the <li> which wraps the read marker
const [rm] = container.getElementsByClassName('mx_RoomView_myReadMarker_container');
const [rm] = container.getElementsByClassName("mx_RoomView_myReadMarker_container");
const [messageList] = container.getElementsByClassName('mx_RoomView_MessageList');
const [messageList] = container.getElementsByClassName("mx_RoomView_MessageList");
const rows = messageList.children;
expect(rows.length).toEqual(7); // 6 events + the NewRoomIntro
expect(rm.previousSibling).toEqual(rows[5]);
@@ -494,22 +530,22 @@ describe('MessagePanel', function() {
expect(isReadMarkerVisible(rm)).toBeFalsy();
});
it('should render Date separators for the events', function() {
it("should render Date separators for the events", function () {
const events = mkOneDayEvents();
const { queryAllByRole } = render(getComponent({ events }));
const dates = queryAllByRole('separator');
const dates = queryAllByRole("separator");
expect(dates.length).toEqual(1);
});
it('appends events into summaries during forward pagination without changing key', () => {
it("appends events into summaries during forward pagination without changing key", () => {
const events = mkMelsEvents().slice(1, 11);
const { container, rerender } = render(getComponent({ events }));
let els = container.getElementsByClassName('mx_GenericEventListSummary');
let els = container.getElementsByClassName("mx_GenericEventListSummary");
expect(els.length).toEqual(1);
expect(els[0].getAttribute('data-testid')).toEqual("eventlistsummary-" + events[0].getId());
expect(els[0].getAttribute("data-scroll-tokens").split(',').length).toEqual(10);
expect(els[0].getAttribute("data-testid")).toEqual("eventlistsummary-" + events[0].getId());
expect(els[0].getAttribute("data-scroll-tokens").split(",").length).toEqual(10);
const updatedEvents = [
...events,
@@ -519,27 +555,27 @@ describe('MessagePanel', function() {
user: "@user:id",
target: bobMember,
ts: Date.now(),
mship: 'join',
prevMship: 'join',
name: 'A user',
mship: "join",
prevMship: "join",
name: "A user",
}),
];
rerender(getComponent({ events: updatedEvents }));
els = container.getElementsByClassName('mx_GenericEventListSummary');
els = container.getElementsByClassName("mx_GenericEventListSummary");
expect(els.length).toEqual(1);
expect(els[0].getAttribute('data-testid')).toEqual("eventlistsummary-" + events[0].getId());
expect(els[0].getAttribute("data-scroll-tokens").split(',').length).toEqual(11);
expect(els[0].getAttribute("data-testid")).toEqual("eventlistsummary-" + events[0].getId());
expect(els[0].getAttribute("data-scroll-tokens").split(",").length).toEqual(11);
});
it('prepends events into summaries during backward pagination without changing key', () => {
it("prepends events into summaries during backward pagination without changing key", () => {
const events = mkMelsEvents().slice(1, 11);
const { container, rerender } = render(getComponent({ events }));
let els = container.getElementsByClassName('mx_GenericEventListSummary');
let els = container.getElementsByClassName("mx_GenericEventListSummary");
expect(els.length).toEqual(1);
expect(els[0].getAttribute('data-testid')).toEqual("eventlistsummary-" + events[0].getId());
expect(els[0].getAttribute("data-scroll-tokens").split(',').length).toEqual(10);
expect(els[0].getAttribute("data-testid")).toEqual("eventlistsummary-" + events[0].getId());
expect(els[0].getAttribute("data-scroll-tokens").split(",").length).toEqual(10);
const updatedEvents = [
TestUtilsMatrix.mkMembership({
@@ -548,28 +584,28 @@ describe('MessagePanel', function() {
user: "@user:id",
target: bobMember,
ts: Date.now(),
mship: 'join',
prevMship: 'join',
name: 'A user',
mship: "join",
prevMship: "join",
name: "A user",
}),
...events,
];
rerender(getComponent({ events: updatedEvents }));
els = container.getElementsByClassName('mx_GenericEventListSummary');
els = container.getElementsByClassName("mx_GenericEventListSummary");
expect(els.length).toEqual(1);
expect(els[0].getAttribute('data-testid')).toEqual("eventlistsummary-" + events[0].getId());
expect(els[0].getAttribute("data-scroll-tokens").split(',').length).toEqual(11);
expect(els[0].getAttribute("data-testid")).toEqual("eventlistsummary-" + events[0].getId());
expect(els[0].getAttribute("data-scroll-tokens").split(",").length).toEqual(11);
});
it('assigns different keys to summaries that get split up', () => {
it("assigns different keys to summaries that get split up", () => {
const events = mkMelsEvents().slice(1, 11);
const { container, rerender } = render(getComponent({ events }));
let els = container.getElementsByClassName('mx_GenericEventListSummary');
let els = container.getElementsByClassName("mx_GenericEventListSummary");
expect(els.length).toEqual(1);
expect(els[0].getAttribute('data-testid')).toEqual(`eventlistsummary-${events[0].getId()}`);
expect(els[0].getAttribute("data-scroll-tokens").split(',').length).toEqual(10);
expect(els[0].getAttribute("data-testid")).toEqual(`eventlistsummary-${events[0].getId()}`);
expect(els[0].getAttribute("data-scroll-tokens").split(",").length).toEqual(10);
const updatedEvents = [
...events.slice(0, 5),
@@ -584,13 +620,13 @@ describe('MessagePanel', function() {
rerender(getComponent({ events: updatedEvents }));
// summaries split becuase room messages are not summarised
els = container.getElementsByClassName('mx_GenericEventListSummary');
els = container.getElementsByClassName("mx_GenericEventListSummary");
expect(els.length).toEqual(2);
expect(els[0].getAttribute('data-testid')).toEqual(`eventlistsummary-${events[0].getId()}`);
expect(els[0].getAttribute("data-scroll-tokens").split(',').length).toEqual(5);
expect(els[0].getAttribute("data-testid")).toEqual(`eventlistsummary-${events[0].getId()}`);
expect(els[0].getAttribute("data-scroll-tokens").split(",").length).toEqual(5);
expect(els[1].getAttribute('data-testid')).toEqual(`eventlistsummary-${events[5].getId()}`);
expect(els[1].getAttribute("data-scroll-tokens").split(',').length).toEqual(5);
expect(els[1].getAttribute("data-testid")).toEqual(`eventlistsummary-${events[5].getId()}`);
expect(els[1].getAttribute("data-scroll-tokens").split(",").length).toEqual(5);
});
// We test this because setting lookups can be *slow*, and we don't want
@@ -638,9 +674,9 @@ describe('MessagePanel', function() {
];
const { container } = render(getComponent({ events }, { showHiddenEvents: true }));
const els = container.getElementsByClassName('mx_GenericEventListSummary');
const els = container.getElementsByClassName("mx_GenericEventListSummary");
expect(els.length).toEqual(1);
expect(els[0].getAttribute("data-scroll-tokens").split(',').length).toEqual(3);
expect(els[0].getAttribute("data-scroll-tokens").split(",").length).toEqual(3);
});
});

View File

@@ -55,8 +55,8 @@ describe("RightPanel", () => {
});
afterEach(async () => {
const roomChanged = new Promise<void>(resolve => {
const ref = dis.register(payload => {
const roomChanged = new Promise<void>((resolve) => {
const ref = dis.register((payload) => {
if (payload.action === Action.ActiveRoomChanged) {
dis.unregister(ref);
resolve();
@@ -84,12 +84,11 @@ describe("RightPanel", () => {
await RightPanelStore.instance.onReady();
};
const waitForRpsUpdate = () =>
new Promise<void>(resolve => RightPanelStore.instance.once(UPDATE_EVENT, resolve));
const waitForRpsUpdate = () => new Promise<void>((resolve) => RightPanelStore.instance.once(UPDATE_EVENT, resolve));
it("navigates from room summary to member list", async () => {
const r1 = mkRoom(cli, "r1");
cli.getRoom.mockImplementation(roomId => roomId === "r1" ? r1 : null);
cli.getRoom.mockImplementation((roomId) => (roomId === "r1" ? r1 : null));
// Set up right panel state
const realGetValue = SettingsStore.getValue;
@@ -127,7 +126,7 @@ describe("RightPanel", () => {
const r1 = mkRoom(cli, "r1");
const r2 = mkRoom(cli, "r2");
cli.getRoom.mockImplementation(roomId => {
cli.getRoom.mockImplementation((roomId) => {
if (roomId === "r1") return r1;
if (roomId === "r2") return r2;
return null;
@@ -168,7 +167,7 @@ describe("RightPanel", () => {
// We want to verify that as we change to room 2, we should always have
// the correct right panel state for whichever room we are showing.
const instance = wrapper.find(_RightPanel).instance() as _RightPanel;
const rendered = new Promise<void>(resolve => {
const rendered = new Promise<void>((resolve) => {
jest.spyOn(instance, "render").mockImplementation(() => {
const { props, state } = instance;
if (props.room.roomId === "r2" && state.phase === RightPanelPhases.RoomMemberList) {

View File

@@ -63,7 +63,7 @@ describe("<RoomSearchView/>", () => {
it("should show a spinner before the promise resolves", async () => {
const deferred = defer<ISearchResults>();
render((
render(
<RoomSearchView
term="search term"
scope={SearchScope.All}
@@ -72,50 +72,57 @@ describe("<RoomSearchView/>", () => {
permalinkCreator={permalinkCreator}
className="someClass"
onUpdate={jest.fn()}
/>
));
/>,
);
await screen.findByTestId("messagePanelSearchSpinner");
});
it("should render results when the promise resolves", async () => {
render((
render(
<MatrixClientContext.Provider value={client}>
<RoomSearchView
term="search term"
scope={SearchScope.All}
promise={Promise.resolve<ISearchResults>({
results: [
SearchResult.fromJson({
rank: 1,
result: {
room_id: room.roomId,
event_id: "$2",
sender: client.getUserId(),
origin_server_ts: 1,
content: { body: "Foo Test Bar", msgtype: "m.text" },
type: EventType.RoomMessage,
},
context: {
profile_info: {},
events_before: [{
SearchResult.fromJson(
{
rank: 1,
result: {
room_id: room.roomId,
event_id: "$1",
event_id: "$2",
sender: client.getUserId(),
origin_server_ts: 1,
content: { body: "Before", msgtype: "m.text" },
content: { body: "Foo Test Bar", msgtype: "m.text" },
type: EventType.RoomMessage,
}],
events_after: [{
room_id: room.roomId,
event_id: "$3",
sender: client.getUserId(),
origin_server_ts: 1,
content: { body: "After", msgtype: "m.text" },
type: EventType.RoomMessage,
}],
},
context: {
profile_info: {},
events_before: [
{
room_id: room.roomId,
event_id: "$1",
sender: client.getUserId(),
origin_server_ts: 1,
content: { body: "Before", msgtype: "m.text" },
type: EventType.RoomMessage,
},
],
events_after: [
{
room_id: room.roomId,
event_id: "$3",
sender: client.getUserId(),
origin_server_ts: 1,
content: { body: "After", msgtype: "m.text" },
type: EventType.RoomMessage,
},
],
},
},
}, eventMapper),
eventMapper,
),
],
highlights: [],
count: 1,
@@ -125,8 +132,8 @@ describe("<RoomSearchView/>", () => {
className="someClass"
onUpdate={jest.fn()}
/>
</MatrixClientContext.Provider>
));
</MatrixClientContext.Provider>,
);
await screen.findByText("Before");
await screen.findByText("Foo Test Bar");
@@ -134,29 +141,32 @@ describe("<RoomSearchView/>", () => {
});
it("should highlight words correctly", async () => {
render((
render(
<MatrixClientContext.Provider value={client}>
<RoomSearchView
term="search term"
scope={SearchScope.Room}
promise={Promise.resolve<ISearchResults>({
results: [
SearchResult.fromJson({
rank: 1,
result: {
room_id: room.roomId,
event_id: "$2",
sender: client.getUserId(),
origin_server_ts: 1,
content: { body: "Foo Test Bar", msgtype: "m.text" },
type: EventType.RoomMessage,
SearchResult.fromJson(
{
rank: 1,
result: {
room_id: room.roomId,
event_id: "$2",
sender: client.getUserId(),
origin_server_ts: 1,
content: { body: "Foo Test Bar", msgtype: "m.text" },
type: EventType.RoomMessage,
},
context: {
profile_info: {},
events_before: [],
events_after: [],
},
},
context: {
profile_info: {},
events_before: [],
events_after: [],
},
}, eventMapper),
eventMapper,
),
],
highlights: ["test"],
count: 1,
@@ -166,8 +176,8 @@ describe("<RoomSearchView/>", () => {
className="someClass"
onUpdate={jest.fn()}
/>
</MatrixClientContext.Provider>
));
</MatrixClientContext.Provider>,
);
const text = await screen.findByText("Test");
expect(text).toHaveClass("mx_EventTile_searchHighlight");
@@ -176,22 +186,25 @@ describe("<RoomSearchView/>", () => {
it("should show spinner above results when backpaginating", async () => {
const searchResults: ISearchResults = {
results: [
SearchResult.fromJson({
rank: 1,
result: {
room_id: room.roomId,
event_id: "$2",
sender: client.getUserId(),
origin_server_ts: 1,
content: { body: "Foo Test Bar", msgtype: "m.text" },
type: EventType.RoomMessage,
SearchResult.fromJson(
{
rank: 1,
result: {
room_id: room.roomId,
event_id: "$2",
sender: client.getUserId(),
origin_server_ts: 1,
content: { body: "Foo Test Bar", msgtype: "m.text" },
type: EventType.RoomMessage,
},
context: {
profile_info: {},
events_before: [],
events_after: [],
},
},
context: {
profile_info: {},
events_before: [],
events_after: [],
},
}, eventMapper),
eventMapper,
),
],
highlights: ["test"],
next_batch: "next_batch",
@@ -202,27 +215,30 @@ describe("<RoomSearchView/>", () => {
...searchResults,
results: [
...searchResults.results,
SearchResult.fromJson({
rank: 1,
result: {
room_id: room.roomId,
event_id: "$4",
sender: client.getUserId(),
origin_server_ts: 4,
content: { body: "Potato", msgtype: "m.text" },
type: EventType.RoomMessage,
SearchResult.fromJson(
{
rank: 1,
result: {
room_id: room.roomId,
event_id: "$4",
sender: client.getUserId(),
origin_server_ts: 4,
content: { body: "Potato", msgtype: "m.text" },
type: EventType.RoomMessage,
},
context: {
profile_info: {},
events_before: [],
events_after: [],
},
},
context: {
profile_info: {},
events_before: [],
events_after: [],
},
}, eventMapper),
eventMapper,
),
],
next_batch: undefined,
});
render((
render(
<MatrixClientContext.Provider value={client}>
<RoomSearchView
term="search term"
@@ -233,8 +249,8 @@ describe("<RoomSearchView/>", () => {
className="someClass"
onUpdate={jest.fn()}
/>
</MatrixClientContext.Provider>
));
</MatrixClientContext.Provider>,
);
await screen.findByRole("progressbar");
await screen.findByText("Potato");
@@ -244,7 +260,7 @@ describe("<RoomSearchView/>", () => {
it("should handle resolutions after unmounting sanely", async () => {
const deferred = defer<ISearchResults>();
const { unmount } = render((
const { unmount } = render(
<MatrixClientContext.Provider value={client}>
<RoomSearchView
term="search term"
@@ -255,8 +271,8 @@ describe("<RoomSearchView/>", () => {
className="someClass"
onUpdate={jest.fn()}
/>
</MatrixClientContext.Provider>
));
</MatrixClientContext.Provider>,
);
unmount();
deferred.resolve({
@@ -268,7 +284,7 @@ describe("<RoomSearchView/>", () => {
it("should handle rejections after unmounting sanely", async () => {
const deferred = defer<ISearchResults>();
const { unmount } = render((
const { unmount } = render(
<MatrixClientContext.Provider value={client}>
<RoomSearchView
term="search term"
@@ -279,8 +295,8 @@ describe("<RoomSearchView/>", () => {
className="someClass"
onUpdate={jest.fn()}
/>
</MatrixClientContext.Provider>
));
</MatrixClientContext.Provider>,
);
unmount();
deferred.reject({
@@ -292,7 +308,7 @@ describe("<RoomSearchView/>", () => {
it("should show modal if error is encountered", async () => {
const deferred = defer<ISearchResults>();
render((
render(
<MatrixClientContext.Provider value={client}>
<RoomSearchView
term="search term"
@@ -303,8 +319,8 @@ describe("<RoomSearchView/>", () => {
className="someClass"
onUpdate={jest.fn()}
/>
</MatrixClientContext.Provider>
));
</MatrixClientContext.Provider>,
);
deferred.reject(new Error("Some error"));
await screen.findByText("Search failed");

View File

@@ -85,7 +85,7 @@ describe("RoomStatusBar", () => {
expect(pendingEvents[2].threadRootId).toBe(rootEvent.getId());
// Filters out the non thread events
expect(pendingEvents.every(ev => ev.getId() !== event.getId())).toBe(true);
expect(pendingEvents.every((ev) => ev.getId() !== event.getId())).toBe(true);
});
});
});

View File

@@ -24,7 +24,7 @@ describe("RoomStatusBarUnsentMessages", () => {
const title = "test title";
const description = "test description";
const buttonsText = "test buttons";
const buttons = <div>{ buttonsText }</div>;
const buttons = <div>{buttonsText}</div>;
beforeEach(() => {
render(

View File

@@ -75,7 +75,7 @@ describe("RoomView", () => {
stores.client = cli;
stores.rightPanelStore.useUnitTestClient(cli);
jest.spyOn(VoipUserMapper.sharedInstance(), 'getVirtualRoomForRoom').mockResolvedValue(null);
jest.spyOn(VoipUserMapper.sharedInstance(), "getVirtualRoomForRoom").mockResolvedValue(null);
});
afterEach(async () => {
@@ -85,7 +85,7 @@ describe("RoomView", () => {
const mountRoomView = async (): Promise<ReactWrapper> => {
if (stores.roomViewStore.getRoomId() !== room.roomId) {
const switchedRoom = new Promise<void>(resolve => {
const switchedRoom = new Promise<void>((resolve) => {
const subFn = () => {
if (stores.roomViewStore.getRoomId()) {
stores.roomViewStore.off(UPDATE_EVENT, subFn);
@@ -121,7 +121,7 @@ describe("RoomView", () => {
const renderRoomView = async (): Promise<ReturnType<typeof render>> => {
if (stores.roomViewStore.getRoomId() !== room.roomId) {
const switchedRoom = new Promise<void>(resolve => {
const switchedRoom = new Promise<void>((resolve) => {
const subFn = () => {
if (stores.roomViewStore.getRoomId()) {
stores.roomViewStore.off(UPDATE_EVENT, subFn);
@@ -180,13 +180,15 @@ describe("RoomView", () => {
cli.isRoomEncrypted.mockReturnValue(true);
// and fake an encryption event into the room to prompt it to re-check
room.addLiveEvents([new MatrixEvent({
type: "m.room.encryption",
sender: cli.getUserId()!,
content: {},
event_id: "someid",
room_id: room.roomId,
})]);
room.addLiveEvents([
new MatrixEvent({
type: "m.room.encryption",
sender: cli.getUserId()!,
content: {},
event_id: "someid",
room_id: room.roomId,
}),
]);
// URL previews should now be disabled
expect(roomViewInstance.state.showUrlPreview).toBe(false);
@@ -200,13 +202,13 @@ describe("RoomView", () => {
expect(roomViewInstance.state.liveTimeline).not.toEqual(oldTimeline);
});
describe('with virtual rooms', () => {
describe("with virtual rooms", () => {
it("checks for a virtual room on initial load", async () => {
const { container } = await renderRoomView();
expect(VoipUserMapper.sharedInstance().getVirtualRoomForRoom).toHaveBeenCalledWith(room.roomId);
// quick check that rendered without error
expect(container.querySelector('.mx_ErrorBoundary')).toBeFalsy();
expect(container.querySelector(".mx_ErrorBoundary")).toBeFalsy();
});
it("checks for a virtual room on room event", async () => {
@@ -307,7 +309,7 @@ describe("RoomView", () => {
it("clicking retry should set the room state to new dispatch a local room event", async () => {
jest.spyOn(defaultDispatcher, "dispatch");
const { getByText } = await renderRoomView();
fireEvent.click(getByText('Retry'));
fireEvent.click(getByText("Retry"));
expect(localRoom.state).toBe(LocalRoomState.NEW);
expect(defaultDispatcher.dispatch).toHaveBeenCalledWith({
action: "local_room_event",

View File

@@ -53,17 +53,17 @@ describe("SpaceHierarchy", () => {
it("shows room", () => {
showRoom(client, hierarchy, "room-id2");
expect(dispatcher.dispatch).toHaveBeenCalledWith({
"action": Action.ViewRoom,
"should_peek": true,
"room_alias": "canonical-alias",
"room_id": "room-id2",
"via_servers": [],
"oob_data": {
action: Action.ViewRoom,
should_peek: true,
room_alias: "canonical-alias",
room_id: "room-id2",
via_servers: [],
oob_data: {
avatarUrl: undefined,
name: "canonical-alias",
},
"roomType": undefined,
"metricsTrigger": "RoomDirectory",
roomType: undefined,
metricsTrigger: "RoomDirectory",
});
});
});

View File

@@ -14,31 +14,16 @@ See the License for the specific language governing permissions and
limitations under the License.
*/
import React from 'react';
import React from "react";
import { fireEvent, render } from "@testing-library/react";
import { act } from 'react-dom/test-utils';
import { act } from "react-dom/test-utils";
import TabbedView, { Tab, TabLocation } from "../../../src/components/structures/TabbedView";
describe('<TabbedView />', () => {
const generalTab = new Tab(
'GENERAL',
'General',
'general',
<div>general</div>,
);
const labsTab = new Tab(
'LABS',
'Labs',
'labs',
<div>labs</div>,
);
const securityTab = new Tab(
'SECURITY',
'Security',
'security',
<div>security</div>,
);
describe("<TabbedView />", () => {
const generalTab = new Tab("GENERAL", "General", "general", <div>general</div>);
const labsTab = new Tab("LABS", "Labs", "labs", <div>labs</div>);
const securityTab = new Tab("SECURITY", "Security", "security", <div>security</div>);
const defaultProps = {
tabLocation: TabLocation.LEFT,
tabs: [generalTab, labsTab, securityTab],
@@ -47,39 +32,39 @@ describe('<TabbedView />', () => {
const getTabTestId = (tab: Tab): string => `settings-tab-${tab.id}`;
const getActiveTab = (container: HTMLElement): Element | undefined =>
container.getElementsByClassName('mx_TabbedView_tabLabel_active')[0];
container.getElementsByClassName("mx_TabbedView_tabLabel_active")[0];
const getActiveTabBody = (container: HTMLElement): Element | undefined =>
container.getElementsByClassName('mx_TabbedView_tabPanel')[0];
container.getElementsByClassName("mx_TabbedView_tabPanel")[0];
it('renders tabs', () => {
it("renders tabs", () => {
const { container } = render(getComponent());
expect(container).toMatchSnapshot();
});
it('renders first tab as active tab when no initialTabId', () => {
it("renders first tab as active tab when no initialTabId", () => {
const { container } = render(getComponent());
expect(getActiveTab(container).textContent).toEqual(generalTab.label);
expect(getActiveTabBody(container).textContent).toEqual('general');
expect(getActiveTabBody(container).textContent).toEqual("general");
});
it('renders first tab as active tab when initialTabId is not valid', () => {
const { container } = render(getComponent({ initialTabId: 'bad-tab-id' }));
it("renders first tab as active tab when initialTabId is not valid", () => {
const { container } = render(getComponent({ initialTabId: "bad-tab-id" }));
expect(getActiveTab(container).textContent).toEqual(generalTab.label);
expect(getActiveTabBody(container).textContent).toEqual('general');
expect(getActiveTabBody(container).textContent).toEqual("general");
});
it('renders initialTabId tab as active when valid', () => {
it("renders initialTabId tab as active when valid", () => {
const { container } = render(getComponent({ initialTabId: securityTab.id }));
expect(getActiveTab(container).textContent).toEqual(securityTab.label);
expect(getActiveTabBody(container).textContent).toEqual('security');
expect(getActiveTabBody(container).textContent).toEqual("security");
});
it('renders without error when there are no tabs', () => {
it("renders without error when there are no tabs", () => {
const { container } = render(getComponent({ tabs: [] }));
expect(container).toMatchSnapshot();
});
it('sets active tab on tab click', () => {
it("sets active tab on tab click", () => {
const { container, getByTestId } = render(getComponent());
act(() => {
@@ -87,10 +72,10 @@ describe('<TabbedView />', () => {
});
expect(getActiveTab(container).textContent).toEqual(securityTab.label);
expect(getActiveTabBody(container).textContent).toEqual('security');
expect(getActiveTabBody(container).textContent).toEqual("security");
});
it('calls onchange on on tab click', () => {
it("calls onchange on on tab click", () => {
const onChange = jest.fn();
const { getByTestId } = render(getComponent({ onChange }));
@@ -101,7 +86,7 @@ describe('<TabbedView />', () => {
expect(onChange).toHaveBeenCalledWith(securityTab.id);
});
it('keeps same tab active when order of tabs changes', () => {
it("keeps same tab active when order of tabs changes", () => {
// start with middle tab active
const { container, rerender } = render(getComponent({ initialTabId: labsTab.id }));
@@ -113,7 +98,7 @@ describe('<TabbedView />', () => {
expect(getActiveTab(container).textContent).toEqual(labsTab.label);
});
it('does not reactivate inititalTabId on rerender', () => {
it("does not reactivate inititalTabId on rerender", () => {
const { container, getByTestId, rerender } = render(getComponent());
expect(getActiveTab(container).textContent).toEqual(generalTab.label);

View File

@@ -14,22 +14,22 @@ See the License for the specific language governing permissions and
limitations under the License.
*/
import React from 'react';
import React from "react";
import { render, screen, fireEvent } from "@testing-library/react";
import { mocked } from "jest-mock";
import 'focus-visible'; // to fix context menus
import "focus-visible"; // to fix context menus
import ThreadPanel, { ThreadFilterType, ThreadPanelHeader } from '../../../src/components/structures/ThreadPanel';
import { _t } from '../../../src/languageHandler';
import ResizeNotifier from '../../../src/utils/ResizeNotifier';
import { RoomPermalinkCreator } from '../../../src/utils/permalinks/Permalinks';
import { createTestClient, mkStubRoom } from '../../test-utils';
import ThreadPanel, { ThreadFilterType, ThreadPanelHeader } from "../../../src/components/structures/ThreadPanel";
import { _t } from "../../../src/languageHandler";
import ResizeNotifier from "../../../src/utils/ResizeNotifier";
import { RoomPermalinkCreator } from "../../../src/utils/permalinks/Permalinks";
import { createTestClient, mkStubRoom } from "../../test-utils";
import { shouldShowFeedback } from "../../../src/utils/Feedback";
import MatrixClientContext from "../../../src/contexts/MatrixClientContext";
jest.mock("../../../src/utils/Feedback");
describe('ThreadPanel', () => {
describe("ThreadPanel", () => {
describe("Feedback prompt", () => {
const cli = createTestClient();
const room = mkStubRoom("!room:server", "room", cli);
@@ -38,59 +38,66 @@ describe('ThreadPanel', () => {
it("should show feedback prompt if feedback is enabled", () => {
mocked(shouldShowFeedback).mockReturnValue(true);
render(<MatrixClientContext.Provider value={cli}>
<ThreadPanel
roomId="!room:server"
onClose={jest.fn()}
resizeNotifier={new ResizeNotifier()}
permalinkCreator={new RoomPermalinkCreator(room)}
/>
</MatrixClientContext.Provider>);
render(
<MatrixClientContext.Provider value={cli}>
<ThreadPanel
roomId="!room:server"
onClose={jest.fn()}
resizeNotifier={new ResizeNotifier()}
permalinkCreator={new RoomPermalinkCreator(room)}
/>
</MatrixClientContext.Provider>,
);
expect(screen.queryByText("Give feedback")).toBeTruthy();
});
it("should hide feedback prompt if feedback is disabled", () => {
mocked(shouldShowFeedback).mockReturnValue(false);
render(<MatrixClientContext.Provider value={cli}>
<ThreadPanel
roomId="!room:server"
onClose={jest.fn()}
resizeNotifier={new ResizeNotifier()}
permalinkCreator={new RoomPermalinkCreator(room)}
/>
</MatrixClientContext.Provider>);
render(
<MatrixClientContext.Provider value={cli}>
<ThreadPanel
roomId="!room:server"
onClose={jest.fn()}
resizeNotifier={new ResizeNotifier()}
permalinkCreator={new RoomPermalinkCreator(room)}
/>
</MatrixClientContext.Provider>,
);
expect(screen.queryByText("Give feedback")).toBeFalsy();
});
});
describe('Header', () => {
it('expect that All filter for ThreadPanelHeader properly renders Show: All threads', () => {
describe("Header", () => {
it("expect that All filter for ThreadPanelHeader properly renders Show: All threads", () => {
const { asFragment } = render(
<ThreadPanelHeader
empty={false}
filterOption={ThreadFilterType.All}
setFilterOption={() => undefined} />,
setFilterOption={() => undefined}
/>,
);
expect(asFragment()).toMatchSnapshot();
});
it('expect that My filter for ThreadPanelHeader properly renders Show: My threads', () => {
it("expect that My filter for ThreadPanelHeader properly renders Show: My threads", () => {
const { asFragment } = render(
<ThreadPanelHeader
empty={false}
filterOption={ThreadFilterType.My}
setFilterOption={() => undefined} />,
setFilterOption={() => undefined}
/>,
);
expect(asFragment()).toMatchSnapshot();
});
it('expect that ThreadPanelHeader properly opens a context menu when clicked on the button', () => {
it("expect that ThreadPanelHeader properly opens a context menu when clicked on the button", () => {
const { container } = render(
<ThreadPanelHeader
empty={false}
filterOption={ThreadFilterType.All}
setFilterOption={() => undefined} />,
setFilterOption={() => undefined}
/>,
);
const found = container.querySelector(".mx_ThreadPanel_dropdown");
expect(found).toBeTruthy();
@@ -99,18 +106,19 @@ describe('ThreadPanel', () => {
expect(screen.queryByRole("menu")).toBeTruthy();
});
it('expect that ThreadPanelHeader has the correct option selected in the context menu', () => {
it("expect that ThreadPanelHeader has the correct option selected in the context menu", () => {
const { container } = render(
<ThreadPanelHeader
empty={false}
filterOption={ThreadFilterType.All}
setFilterOption={() => undefined} />,
setFilterOption={() => undefined}
/>,
);
fireEvent.click(container.querySelector(".mx_ThreadPanel_dropdown"));
const found = screen.queryAllByRole("menuitemradio");
expect(found).toHaveLength(2);
const foundButton = screen.queryByRole("menuitemradio", { checked: true });
expect(foundButton.textContent).toEqual(`${_t("All threads")}${_t('Shows all threads from current room')}`);
expect(foundButton.textContent).toEqual(`${_t("All threads")}${_t("Shows all threads from current room")}`);
expect(foundButton).toMatchSnapshot();
});
});

View File

@@ -51,27 +51,25 @@ describe("ThreadView", () => {
const [event, setEvent] = useState(rootEvent);
changeEvent = setEvent;
return <MatrixClientContext.Provider value={mockClient}>
<RoomContext.Provider value={getRoomContext(room, {
canSendMessages: true,
})}>
<ThreadView
room={room}
onClose={jest.fn()}
mxEvent={event}
resizeNotifier={new ResizeNotifier()}
/>
</RoomContext.Provider>,
</MatrixClientContext.Provider>;
return (
<MatrixClientContext.Provider value={mockClient}>
<RoomContext.Provider
value={getRoomContext(room, {
canSendMessages: true,
})}
>
<ThreadView room={room} onClose={jest.fn()} mxEvent={event} resizeNotifier={new ResizeNotifier()} />
</RoomContext.Provider>
,
</MatrixClientContext.Provider>
);
}
async function getComponent(): Promise<RenderResult> {
const renderResult = render(
<TestThreadView />,
);
const renderResult = render(<TestThreadView />);
await waitFor(() => {
expect(() => getByTestId(renderResult.container, 'spinner')).toThrow();
expect(() => getByTestId(renderResult.container, "spinner")).toThrow();
});
return renderResult;
@@ -92,9 +90,12 @@ describe("ThreadView", () => {
"event_id": rootEvent.getId(),
"is_falling_back": true,
"m.in_reply_to": {
"event_id": rootEvent.getThread().lastReply((ev: MatrixEvent) => {
return ev.isRelation(THREAD_RELATION_TYPE.name);
}).getId(),
event_id: rootEvent
.getThread()
.lastReply((ev: MatrixEvent) => {
return ev.isRelation(THREAD_RELATION_TYPE.name);
})
.getId(),
},
"rel_type": RelationType.Thread,
},
@@ -133,7 +134,9 @@ describe("ThreadView", () => {
await sendMessage(container, "Hello world!");
expect(mockClient.sendMessage).toHaveBeenCalledWith(
ROOM_ID, rootEvent.getId(), expectedMessageBody(rootEvent, "Hello world!"),
ROOM_ID,
rootEvent.getId(),
expectedMessageBody(rootEvent, "Hello world!"),
);
});
@@ -154,7 +157,9 @@ describe("ThreadView", () => {
await sendMessage(container, "yolo");
expect(mockClient.sendMessage).toHaveBeenCalledWith(
ROOM_ID, rootEvent2.getId(), expectedMessageBody(rootEvent2, "yolo"),
ROOM_ID,
rootEvent2.getId(),
expectedMessageBody(rootEvent2, "yolo"),
);
});

View File

@@ -17,7 +17,7 @@ limitations under the License.
import { render, RenderResult } from "@testing-library/react";
// eslint-disable-next-line deprecate/import
import { mount, ReactWrapper } from "enzyme";
import { MessageEvent } from 'matrix-events-sdk';
import { MessageEvent } from "matrix-events-sdk";
import { ReceiptType } from "matrix-js-sdk/src/@types/read_receipts";
import {
EventTimelineSet,
@@ -28,7 +28,7 @@ import {
Room,
RoomEvent,
TimelineWindow,
} from 'matrix-js-sdk/src/matrix';
} from "matrix-js-sdk/src/matrix";
import { EventTimeline } from "matrix-js-sdk/src/models/event-timeline";
import {
FeatureSupport,
@@ -37,13 +37,13 @@ import {
ThreadEvent,
ThreadFilterType,
} from "matrix-js-sdk/src/models/thread";
import React from 'react';
import React from "react";
import TimelinePanel from '../../../src/components/structures/TimelinePanel';
import TimelinePanel from "../../../src/components/structures/TimelinePanel";
import MatrixClientContext from "../../../src/contexts/MatrixClientContext";
import { MatrixClientPeg } from '../../../src/MatrixClientPeg';
import { MatrixClientPeg } from "../../../src/MatrixClientPeg";
import SettingsStore from "../../../src/settings/SettingsStore";
import { isCallEvent } from '../../../src/components/structures/LegacyCallEventGrouper';
import { isCallEvent } from "../../../src/components/structures/LegacyCallEventGrouper";
import { flushPromises, mkRoom, stubClient } from "../../test-utils";
const newReceipt = (eventId: string, userId: string, readTs: number, fullyReadTs: number): MatrixEvent => {
@@ -81,13 +81,15 @@ const renderPanel = (room: Room, events: MatrixEvent[]): RenderResult => {
const mockEvents = (room: Room, count = 2): MatrixEvent[] => {
const events: MatrixEvent[] = [];
for (let index = 0; index < count; index++) {
events.push(new MatrixEvent({
room_id: room.roomId,
event_id: `${room.roomId}_event_${index}`,
type: EventType.RoomMessage,
user_id: "userId",
content: MessageEvent.from(`Event${index}`).serialize().content,
}));
events.push(
new MatrixEvent({
room_id: room.roomId,
event_id: `${room.roomId}_event_${index}`,
type: EventType.RoomMessage,
user_id: "userId",
content: MessageEvent.from(`Event${index}`).serialize().content,
}),
);
}
return events;
@@ -100,13 +102,13 @@ const setupTestData = (): [MatrixClient, Room, MatrixEvent[]] => {
return [client, room, events];
};
describe('TimelinePanel', () => {
describe("TimelinePanel", () => {
beforeEach(() => {
stubClient();
});
describe('read receipts and markers', () => {
it('should forget the read marker when asked to', () => {
describe("read receipts and markers", () => {
it("should forget the read marker when asked to", () => {
const cli = MatrixClientPeg.get();
const readMarkersSent: string[] = [];
@@ -131,22 +133,19 @@ describe('TimelinePanel', () => {
const roomId = "#room:example.com";
const userId = cli.credentials.userId!;
const room = new Room(
roomId,
cli,
userId,
{ pendingEventOrdering: PendingEventOrdering.Detached },
);
const room = new Room(roomId, cli, userId, { pendingEventOrdering: PendingEventOrdering.Detached });
// Create a TimelinePanel with ev0 already present
const timelineSet = new EventTimelineSet(room, {});
timelineSet.addLiveEvent(ev0);
const component: ReactWrapper<TimelinePanel> = mount(<TimelinePanel
timelineSet={timelineSet}
manageReadMarkers={true}
manageReadReceipts={true}
eventId={ev0.getId()}
/>);
const component: ReactWrapper<TimelinePanel> = mount(
<TimelinePanel
timelineSet={timelineSet}
manageReadMarkers={true}
manageReadReceipts={true}
eventId={ev0.getId()}
/>,
);
const timelinePanel = component.instance() as TimelinePanel;
// An event arrived, and we read it
@@ -208,8 +207,8 @@ describe('TimelinePanel', () => {
expect(props.onEventScrolledIntoView).toHaveBeenCalledWith(events[1].getId());
});
describe('onRoomTimeline', () => {
it('ignores events for other timelines', () => {
describe("onRoomTimeline", () => {
it("ignores events for other timelines", () => {
const [client, room, events] = setupTestData();
const otherTimelineSet = { room: room as Room } as EventTimelineSet;
@@ -220,7 +219,7 @@ describe('TimelinePanel', () => {
onEventScrolledIntoView: jest.fn(),
};
const paginateSpy = jest.spyOn(TimelineWindow.prototype, 'paginate').mockClear();
const paginateSpy = jest.spyOn(TimelineWindow.prototype, "paginate").mockClear();
render(<TimelinePanel {...props} />);
@@ -231,12 +230,12 @@ describe('TimelinePanel', () => {
expect(paginateSpy).not.toHaveBeenCalled();
});
it('ignores timeline updates without a live event', () => {
it("ignores timeline updates without a live event", () => {
const [client, room, events] = setupTestData();
const props = getProps(room, events);
const paginateSpy = jest.spyOn(TimelineWindow.prototype, 'paginate').mockClear();
const paginateSpy = jest.spyOn(TimelineWindow.prototype, "paginate").mockClear();
render(<TimelinePanel {...props} />);
@@ -247,12 +246,12 @@ describe('TimelinePanel', () => {
expect(paginateSpy).not.toHaveBeenCalled();
});
it('ignores timeline where toStartOfTimeline is true', () => {
it("ignores timeline where toStartOfTimeline is true", () => {
const [client, room, events] = setupTestData();
const props = getProps(room, events);
const paginateSpy = jest.spyOn(TimelineWindow.prototype, 'paginate').mockClear();
const paginateSpy = jest.spyOn(TimelineWindow.prototype, "paginate").mockClear();
render(<TimelinePanel {...props} />);
@@ -264,12 +263,12 @@ describe('TimelinePanel', () => {
expect(paginateSpy).not.toHaveBeenCalled();
});
it('advances the timeline window', () => {
it("advances the timeline window", () => {
const [client, room, events] = setupTestData();
const props = getProps(room, events);
const paginateSpy = jest.spyOn(TimelineWindow.prototype, 'paginate').mockClear();
const paginateSpy = jest.spyOn(TimelineWindow.prototype, "paginate").mockClear();
render(<TimelinePanel {...props} />);
@@ -280,7 +279,7 @@ describe('TimelinePanel', () => {
expect(paginateSpy).toHaveBeenCalledWith(EventTimeline.FORWARDS, 1, false);
});
it('advances the overlay timeline window', async () => {
it("advances the overlay timeline window", async () => {
const [client, room, events] = setupTestData();
const virtualRoom = mkRoom(client, "virtualRoomId");
@@ -292,7 +291,7 @@ describe('TimelinePanel', () => {
overlayTimelineSet,
};
const paginateSpy = jest.spyOn(TimelineWindow.prototype, 'paginate').mockClear();
const paginateSpy = jest.spyOn(TimelineWindow.prototype, "paginate").mockClear();
render(<TimelinePanel {...props} />);
@@ -306,25 +305,21 @@ describe('TimelinePanel', () => {
});
});
describe('with overlayTimeline', () => {
it('renders merged timeline', () => {
describe("with overlayTimeline", () => {
it("renders merged timeline", () => {
const [client, room, events] = setupTestData();
const virtualRoom = mkRoom(client, "virtualRoomId");
const virtualCallInvite = new MatrixEvent({
type: 'm.call.invite',
type: "m.call.invite",
room_id: virtualRoom.roomId,
event_id: `virtualCallEvent1`,
});
const virtualCallMetaEvent = new MatrixEvent({
type: 'org.matrix.call.sdp_stream_metadata_changed',
type: "org.matrix.call.sdp_stream_metadata_changed",
room_id: virtualRoom.roomId,
event_id: `virtualCallEvent2`,
});
const virtualEvents = [
virtualCallInvite,
...mockEvents(virtualRoom),
virtualCallMetaEvent,
];
const virtualEvents = [virtualCallInvite, ...mockEvents(virtualRoom), virtualCallMetaEvent];
const { timelineSet: overlayTimelineSet } = getProps(virtualRoom, virtualEvents);
const props = {
@@ -335,8 +330,8 @@ describe('TimelinePanel', () => {
const { container } = render(<TimelinePanel {...props} />);
const eventTiles = container.querySelectorAll('.mx_EventTile');
const eventTileIds = [...eventTiles].map(tileElement => tileElement.getAttribute('data-event-id'));
const eventTiles = container.querySelectorAll(".mx_EventTile");
const eventTileIds = [...eventTiles].map((tileElement) => tileElement.getAttribute("data-event-id"));
expect(eventTileIds).toEqual([
// main timeline events are included
events[1].getId(),
@@ -368,16 +363,22 @@ describe('TimelinePanel', () => {
});
room = new Room("roomId", client, "userId");
allThreads = new EventTimelineSet(room, {
pendingEvents: false,
}, undefined, undefined, ThreadFilterType.All);
allThreads = new EventTimelineSet(
room,
{
pendingEvents: false,
},
undefined,
undefined,
ThreadFilterType.All,
);
const timeline = new EventTimeline(allThreads);
allThreads.getLiveTimeline = () => timeline;
allThreads.getTimelineForEvent = () => timeline;
reply1 = new MatrixEvent({
room_id: room.roomId,
event_id: 'event_reply_1',
event_id: "event_reply_1",
type: EventType.RoomMessage,
user_id: "userId",
content: MessageEvent.from(`ReplyEvent1`).serialize().content,
@@ -385,7 +386,7 @@ describe('TimelinePanel', () => {
reply2 = new MatrixEvent({
room_id: room.roomId,
event_id: 'event_reply_2',
event_id: "event_reply_2",
type: EventType.RoomMessage,
user_id: "userId",
content: MessageEvent.from(`ReplyEvent2`).serialize().content,
@@ -393,7 +394,7 @@ describe('TimelinePanel', () => {
root = new MatrixEvent({
room_id: room.roomId,
event_id: 'event_root_1',
event_id: "event_root_1",
type: EventType.RoomMessage,
user_id: "userId",
content: MessageEvent.from(`RootEvent`).serialize().content,
@@ -410,13 +411,13 @@ describe('TimelinePanel', () => {
roomId === room.roomId ? eventMap[eventId]?.event : {};
});
it('updates thread previews', async () => {
it("updates thread previews", async () => {
root.setUnsigned({
"m.relations": {
[THREAD_RELATION_TYPE.name]: {
"latest_event": reply1.event,
"count": 1,
"current_user_participated": true,
latest_event: reply1.event,
count: 1,
current_user_participated: true,
},
},
});
@@ -432,11 +433,7 @@ describe('TimelinePanel', () => {
const dom = render(
<MatrixClientContext.Provider value={client}>
<TimelinePanel
timelineSet={allThreads}
manageReadReceipts
sendReadReceiptOnLoad
/>
<TimelinePanel timelineSet={allThreads} manageReadReceipts sendReadReceiptOnLoad />
</MatrixClientContext.Provider>,
);
await dom.findByText("RootEvent");
@@ -446,9 +443,9 @@ describe('TimelinePanel', () => {
root.setUnsigned({
"m.relations": {
[THREAD_RELATION_TYPE.name]: {
"latest_event": reply2.event,
"count": 2,
"current_user_participated": true,
latest_event: reply2.event,
count: 2,
current_user_participated: true,
},
},
});
@@ -460,13 +457,13 @@ describe('TimelinePanel', () => {
expect(replyToEvent).toHaveBeenCalled();
});
it('ignores thread updates for unknown threads', async () => {
it("ignores thread updates for unknown threads", async () => {
root.setUnsigned({
"m.relations": {
[THREAD_RELATION_TYPE.name]: {
"latest_event": reply1.event,
"count": 1,
"current_user_participated": true,
latest_event: reply1.event,
count: 1,
current_user_participated: true,
},
},
});
@@ -499,11 +496,7 @@ describe('TimelinePanel', () => {
const dom = render(
<MatrixClientContext.Provider value={client}>
<TimelinePanel
timelineSet={allThreads}
manageReadReceipts
sendReadReceiptOnLoad
/>
<TimelinePanel timelineSet={allThreads} manageReadReceipts sendReadReceiptOnLoad />
</MatrixClientContext.Provider>,
);
await dom.findByText("RootEvent");

View File

@@ -42,10 +42,7 @@ describe("<UserMenu>", () => {
client.getUserId() || "",
client.getDeviceId() || "",
);
voiceBroadcastRecording = new VoiceBroadcastRecording(
voiceBroadcastInfoEvent,
client,
);
voiceBroadcastRecording = new VoiceBroadcastRecording(voiceBroadcastInfoEvent, client);
});
beforeEach(() => {

View File

@@ -100,11 +100,9 @@ describe("<ForgotPassword>", () => {
describe("when starting a password reset flow", () => {
beforeEach(() => {
renderResult = render(<ForgotPassword
serverConfig={serverConfig}
onComplete={onComplete}
onLoginClick={onLoginClick}
/>);
renderResult = render(
<ForgotPassword serverConfig={serverConfig} onComplete={onComplete} onLoginClick={onLoginClick} />,
);
});
it("should show the email input and mention the homeserver", () => {
@@ -115,11 +113,9 @@ describe("<ForgotPassword>", () => {
describe("and updating the server config", () => {
beforeEach(() => {
serverConfig.hsName = "example2.com";
renderResult.rerender(<ForgotPassword
serverConfig={serverConfig}
onComplete={onComplete}
onLoginClick={onLoginClick}
/>);
renderResult.rerender(
<ForgotPassword serverConfig={serverConfig} onComplete={onComplete} onLoginClick={onLoginClick} />,
);
});
it("should show the new homeserver server name", () => {
@@ -171,10 +167,12 @@ describe("<ForgotPassword>", () => {
});
it("should show an info about that", () => {
expect(screen.getByText(
"Cannot reach homeserver: "
+ "Ensure you have a stable internet connection, or get in touch with the server admin",
)).toBeInTheDocument();
expect(
screen.getByText(
"Cannot reach homeserver: " +
"Ensure you have a stable internet connection, or get in touch with the server admin",
),
).toBeInTheDocument();
});
});

View File

@@ -14,13 +14,13 @@ See the License for the specific language governing permissions and
limitations under the License.
*/
import React from 'react';
import React from "react";
import { fireEvent, render, screen, waitForElementToBeRemoved } from "@testing-library/react";
import { mocked, MockedObject } from 'jest-mock';
import { mocked, MockedObject } from "jest-mock";
import { createClient, MatrixClient } from "matrix-js-sdk/src/matrix";
import fetchMock from "fetch-mock-jest";
import SdkConfig from '../../../../src/SdkConfig';
import SdkConfig from "../../../../src/SdkConfig";
import { mkServerConfig, mockPlatformPeg, unmockPlatformPeg } from "../../../test-utils";
import Login from "../../../../src/components/structures/auth/Login";
import BasePlatform from "../../../../src/BasePlatform";
@@ -29,7 +29,7 @@ jest.mock("matrix-js-sdk/src/matrix");
jest.useRealTimers();
describe('Login', function() {
describe("Login", function () {
let platform: MockedObject<BasePlatform>;
const mockClient = mocked({
@@ -37,14 +37,14 @@ describe('Login', function() {
loginFlows: jest.fn(),
} as unknown as MatrixClient);
beforeEach(function() {
beforeEach(function () {
SdkConfig.put({
brand: "test-brand",
disable_custom_urls: true,
});
mockClient.login.mockClear().mockResolvedValue({});
mockClient.loginFlows.mockClear().mockResolvedValue({ flows: [{ type: "m.login.password" }] });
mocked(createClient).mockImplementation(opts => {
mocked(createClient).mockImplementation((opts) => {
mockClient.idBaseUrl = opts.idBaseUrl;
mockClient.baseUrl = opts.baseUrl;
return mockClient;
@@ -58,26 +58,28 @@ describe('Login', function() {
});
});
afterEach(function() {
afterEach(function () {
fetchMock.restore();
SdkConfig.unset(); // we touch the config, so clean up
unmockPlatformPeg();
});
function getRawComponent(hsUrl = "https://matrix.org", isUrl = "https://vector.im") {
return <Login
serverConfig={mkServerConfig(hsUrl, isUrl)}
onLoggedIn={() => { }}
onRegisterClick={() => { }}
onServerConfigChange={() => { }}
/>;
return (
<Login
serverConfig={mkServerConfig(hsUrl, isUrl)}
onLoggedIn={() => {}}
onRegisterClick={() => {}}
onServerConfigChange={() => {}}
/>
);
}
function getComponent(hsUrl?: string, isUrl?: string) {
return render(getRawComponent(hsUrl, isUrl));
}
it('should show form with change server link', async () => {
it("should show form with change server link", async () => {
SdkConfig.put({
brand: "test-brand",
disable_custom_urls: false,
@@ -90,7 +92,7 @@ describe('Login', function() {
expect(container.querySelector(".mx_ServerPicker_change")).toBeTruthy();
});
it('should show form without change server link when custom URLs disabled', async () => {
it("should show form without change server link when custom URLs disabled", async () => {
const { container } = getComponent();
await waitForElementToBeRemoved(() => screen.queryAllByLabelText("Loading..."));
@@ -122,19 +124,25 @@ describe('Login', function() {
it("should show multiple SSO buttons if multiple identity_providers are available", async () => {
mockClient.loginFlows.mockResolvedValue({
flows: [{
"type": "m.login.sso",
"identity_providers": [{
id: "a",
name: "Provider 1",
}, {
id: "b",
name: "Provider 2",
}, {
id: "c",
name: "Provider 3",
}],
}],
flows: [
{
type: "m.login.sso",
identity_providers: [
{
id: "a",
name: "Provider 1",
},
{
id: "b",
name: "Provider 2",
},
{
id: "c",
name: "Provider 3",
},
],
},
],
});
const { container } = getComponent();
@@ -146,9 +154,11 @@ describe('Login', function() {
it("should show single SSO button if identity_providers is null", async () => {
mockClient.loginFlows.mockResolvedValue({
flows: [{
"type": "m.login.sso",
}],
flows: [
{
type: "m.login.sso",
},
],
});
const { container } = getComponent();
@@ -160,9 +170,11 @@ describe('Login', function() {
it("should handle serverConfig updates correctly", async () => {
mockClient.loginFlows.mockResolvedValue({
flows: [{
"type": "m.login.sso",
}],
flows: [
{
type: "m.login.sso",
},
],
});
const { container, rerender } = render(getRawComponent());

View File

@@ -15,37 +15,42 @@ See the License for the specific language governing permissions and
limitations under the License.
*/
import React from 'react';
import React from "react";
import { fireEvent, render, screen, waitForElementToBeRemoved } from "@testing-library/react";
import { createClient, MatrixClient } from 'matrix-js-sdk/src/matrix';
import { MatrixError } from 'matrix-js-sdk/src/http-api/errors';
import { mocked } from 'jest-mock';
import { createClient, MatrixClient } from "matrix-js-sdk/src/matrix";
import { MatrixError } from "matrix-js-sdk/src/http-api/errors";
import { mocked } from "jest-mock";
import fetchMock from "fetch-mock-jest";
import SdkConfig, { DEFAULTS } from '../../../../src/SdkConfig';
import SdkConfig, { DEFAULTS } from "../../../../src/SdkConfig";
import { mkServerConfig, mockPlatformPeg, unmockPlatformPeg } from "../../../test-utils";
import Registration from "../../../../src/components/structures/auth/Registration";
jest.mock('matrix-js-sdk/src/matrix');
jest.mock("matrix-js-sdk/src/matrix");
jest.useFakeTimers();
describe('Registration', function() {
describe("Registration", function () {
const registerRequest = jest.fn();
const mockClient = mocked({
registerRequest,
loginFlows: jest.fn(),
} as unknown as MatrixClient);
beforeEach(function() {
beforeEach(function () {
SdkConfig.put({
...DEFAULTS,
disable_custom_urls: true,
});
mockClient.registerRequest.mockRejectedValueOnce(new MatrixError({
flows: [{ stages: [] }],
}, 401));
mockClient.registerRequest.mockRejectedValueOnce(
new MatrixError(
{
flows: [{ stages: [] }],
},
401,
),
);
mockClient.loginFlows.mockClear().mockResolvedValue({ flows: [{ type: "m.login.password" }] });
mocked(createClient).mockImplementation(opts => {
mocked(createClient).mockImplementation((opts) => {
mockClient.idBaseUrl = opts.idBaseUrl;
mockClient.baseUrl = opts.baseUrl;
return mockClient;
@@ -59,14 +64,14 @@ describe('Registration', function() {
});
});
afterEach(function() {
afterEach(function () {
fetchMock.restore();
SdkConfig.unset(); // we touch the config, so clean up
unmockPlatformPeg();
});
const defaultProps = {
defaultDeviceDisplayName: 'test-device-display-name',
defaultDeviceDisplayName: "test-device-display-name",
makeRegistrationUrl: jest.fn(),
onLoggedIn: jest.fn(),
onLoginClick: jest.fn(),
@@ -74,22 +79,19 @@ describe('Registration', function() {
};
function getRawComponent(hsUrl = "https://matrix.org", isUrl = "https://vector.im") {
return <Registration
{...defaultProps}
serverConfig={mkServerConfig(hsUrl, isUrl)}
/>;
return <Registration {...defaultProps} serverConfig={mkServerConfig(hsUrl, isUrl)} />;
}
function getComponent(hsUrl?: string, isUrl?: string) {
return render(getRawComponent(hsUrl, isUrl));
}
it('should show server picker', async function() {
it("should show server picker", async function () {
const { container } = getComponent();
expect(container.querySelector(".mx_ServerPicker")).toBeTruthy();
});
it('should show form when custom URLs disabled', async function() {
it("should show form when custom URLs disabled", async function () {
const { container } = getComponent();
await waitForElementToBeRemoved(() => screen.queryAllByLabelText("Loading..."));
expect(container.querySelector("form")).toBeTruthy();
@@ -106,9 +108,11 @@ describe('Registration', function() {
it("should handle serverConfig updates correctly", async () => {
mockClient.loginFlows.mockResolvedValue({
flows: [{
"type": "m.login.sso",
}],
flows: [
{
type: "m.login.sso",
},
],
});
const { container, rerender } = render(getRawComponent());