You've already forked matrix-react-sdk
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:
@@ -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]);
|
||||
|
@@ -85,4 +85,3 @@ describe("ContextMenu", () => {
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
|
@@ -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();
|
||||
|
@@ -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);
|
||||
});
|
||||
});
|
||||
|
||||
|
@@ -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) {
|
||||
|
@@ -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");
|
||||
|
@@ -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);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
@@ -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(
|
||||
|
@@ -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",
|
||||
|
@@ -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",
|
||||
});
|
||||
});
|
||||
});
|
||||
|
@@ -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);
|
||||
|
@@ -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();
|
||||
});
|
||||
});
|
||||
|
@@ -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"),
|
||||
);
|
||||
});
|
||||
|
||||
|
@@ -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");
|
||||
|
@@ -42,10 +42,7 @@ describe("<UserMenu>", () => {
|
||||
client.getUserId() || "",
|
||||
client.getDeviceId() || "",
|
||||
);
|
||||
voiceBroadcastRecording = new VoiceBroadcastRecording(
|
||||
voiceBroadcastInfoEvent,
|
||||
client,
|
||||
);
|
||||
voiceBroadcastRecording = new VoiceBroadcastRecording(voiceBroadcastInfoEvent, client);
|
||||
});
|
||||
|
||||
beforeEach(() => {
|
||||
|
@@ -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();
|
||||
});
|
||||
});
|
||||
|
||||
|
@@ -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());
|
||||
|
@@ -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());
|
||||
|
Reference in New Issue
Block a user