Merge remote-tracking branch 'origin/develop' into feat/add-message-edition-wysiwyg-composer

This commit is contained in:
Florian Duros
2022-10-21 10:15:46 +02:00
109 changed files with 2374 additions and 1011 deletions

View File

@@ -0,0 +1,84 @@
/*
Copyright 2022 The Matrix.org Foundation C.I.C.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
import { getByTestId, render, screen } from "@testing-library/react";
import userEvent from "@testing-library/user-event";
import { mocked } from "jest-mock";
import { MatrixClient, PendingEventOrdering } from "matrix-js-sdk/src/client";
import { MatrixEvent } from "matrix-js-sdk/src/models/event";
import { Room } from "matrix-js-sdk/src/models/room";
import React from "react";
import ThreadListContextMenu, {
ThreadListContextMenuProps,
} from "../../../../src/components/views/context_menus/ThreadListContextMenu";
import { MatrixClientPeg } from "../../../../src/MatrixClientPeg";
import { RoomPermalinkCreator } from "../../../../src/utils/permalinks/Permalinks";
import { stubClient } from "../../../test-utils/test-utils";
import { mkThread } from "../../../test-utils/threads";
describe("ThreadListContextMenu", () => {
const ROOM_ID = "!123:matrix.org";
let room: Room;
let mockClient: MatrixClient;
let event: MatrixEvent;
function getComponent(props: Partial<ThreadListContextMenuProps>) {
return render(<ThreadListContextMenu
mxEvent={event}
{...props}
/>);
}
beforeEach(() => {
jest.clearAllMocks();
stubClient();
mockClient = mocked(MatrixClientPeg.get());
room = new Room(ROOM_ID, mockClient, mockClient.getUserId() ?? "", {
pendingEventOrdering: PendingEventOrdering.Detached,
});
const res = mkThread({
room,
client: mockClient,
authorId: mockClient.getUserId(),
participantUserIds: [mockClient.getUserId()],
});
event = res.rootEvent;
});
it("does not render the permalink", async () => {
const { container } = getComponent({});
const btn = getByTestId(container, "threadlist-dropdown-button");
await userEvent.click(btn);
expect(screen.queryByTestId("copy-thread-link")).toBeNull();
});
it("does render the permalink", async () => {
const { container } = getComponent({
permalinkCreator: new RoomPermalinkCreator(room, room.roomId, false),
});
const btn = getByTestId(container, "threadlist-dropdown-button");
await userEvent.click(btn);
expect(screen.queryByTestId("copy-thread-link")).not.toBeNull();
});
});

View File

@@ -17,7 +17,7 @@ limitations under the License.
import React from "react";
import { act } from "react-dom/test-utils";
import { sleep } from "matrix-js-sdk/src/utils";
import { ISendEventResponse, MatrixClient, MsgType } from "matrix-js-sdk/src/matrix";
import { ISendEventResponse, MatrixClient, MsgType, RelationType } from "matrix-js-sdk/src/matrix";
// eslint-disable-next-line deprecate/import
import { mount } from 'enzyme';
import { mocked } from "jest-mock";
@@ -291,7 +291,7 @@ describe('<SendMessageComposer/>', () => {
it('correctly sets the editorStateKey for threads', () => {
const relation = {
rel_type: "m.thread",
rel_type: RelationType.Thread,
event_id: "myFakeThreadId",
};
const includeReplyLegacyFallback = false;

View File

@@ -20,13 +20,12 @@ import { act, render, screen, waitFor } from "@testing-library/react";
import { InputEventProcessor, Wysiwyg, WysiwygProps } from "@matrix-org/matrix-wysiwyg";
import MatrixClientContext from "../../../../../src/contexts/MatrixClientContext";
import RoomContext, { TimelineRenderingType } from "../../../../../src/contexts/RoomContext";
import RoomContext from "../../../../../src/contexts/RoomContext";
import defaultDispatcher from "../../../../../src/dispatcher/dispatcher";
import { Action } from "../../../../../src/dispatcher/actions";
import { IRoomState } from "../../../../../src/components/structures/RoomView";
import { Layout } from "../../../../../src/settings/enums/Layout";
import { WysiwygComposer } from "../../../../../src/components/views/rooms/wysiwyg_composer/components/WysiwygComposer";
import { createTestClient, mkEvent, mkStubRoom } from "../../../../test-utils";
import { createTestClient, getRoomContext, mkEvent, mkStubRoom } from "../../../../test-utils";
import SettingsStore from "../../../../../src/settings/SettingsStore";
// Work around missing ClipboardEvent type
@@ -74,43 +73,7 @@ describe('WysiwygComposer', () => {
return eventId === mockEvent.getId() ? mockEvent : null;
});
const defaultRoomContext: IRoomState = {
room: mockRoom,
roomLoading: true,
peekLoading: false,
shouldPeek: true,
membersLoaded: false,
numUnreadMessages: 0,
canPeek: false,
showApps: false,
isPeeking: false,
showRightPanel: true,
joining: false,
atEndOfLiveTimeline: true,
showTopUnreadMessagesBar: false,
statusBarVisible: false,
canReact: false,
canSendMessages: false,
layout: Layout.Group,
lowBandwidth: false,
alwaysShowTimestamps: false,
showTwelveHourTimestamps: false,
readMarkerInViewThresholdMs: 3000,
readMarkerOutOfViewThresholdMs: 30000,
showHiddenEvents: false,
showReadReceipts: true,
showRedactions: true,
showJoinLeaves: true,
showAvatarChanges: true,
showDisplaynameChanges: true,
matrixClientIsReady: false,
timelineRenderingType: TimelineRenderingType.Room,
liveTimeline: undefined,
canSelfRedact: false,
resizing: false,
narrow: false,
activeCall: null,
};
const defaultRoomContext: IRoomState = getRoomContext(mockRoom, {});
let sendMessage: () => void;
const customRender = (onChange = (_content: string) => void 0, disabled = false) => {

View File

@@ -31,6 +31,7 @@ exports[`FontScalingPanel renders the font scaling UI 1`] = `
<div
aria-label="Loading..."
className="mx_Spinner_icon"
data-testid="spinner"
role="progressbar"
style={
Object {

View File

@@ -4,6 +4,7 @@ exports[`<LoginWithQR /> approves login and waits for new device 1`] = `
<div>
<div
class="mx_LoginWithQR"
data-testid="login-with-qr"
>
<div
class=""
@@ -32,6 +33,7 @@ exports[`<LoginWithQR /> approves login and waits for new device 1`] = `
<div
aria-label="Loading..."
class="mx_Spinner_icon"
data-testid="spinner"
role="progressbar"
style="width: 32px; height: 32px;"
/>
@@ -61,6 +63,7 @@ exports[`<LoginWithQR /> displays confirmation digits after connected to rendezv
<div>
<div
class="mx_LoginWithQR"
data-testid="login-with-qr"
>
<div
class=""
@@ -122,6 +125,7 @@ exports[`<LoginWithQR /> displays error when approving login fails 1`] = `
<div>
<div
class="mx_LoginWithQR"
data-testid="login-with-qr"
>
<div
class="mx_LoginWithQR_centreTitle"
@@ -168,6 +172,7 @@ exports[`<LoginWithQR /> displays qr code after it is created 1`] = `
<div>
<div
class="mx_LoginWithQR"
data-testid="login-with-qr"
>
<div
class=""
@@ -214,6 +219,7 @@ exports[`<LoginWithQR /> displays qr code after it is created 1`] = `
<div
aria-label="Loading..."
class="mx_Spinner_icon"
data-testid="spinner"
role="progressbar"
style="width: 32px; height: 32px;"
/>
@@ -232,6 +238,7 @@ exports[`<LoginWithQR /> displays unknown error if connection to rendezvous fail
<div>
<div
class="mx_LoginWithQR"
data-testid="login-with-qr"
>
<div
class="mx_LoginWithQR_centreTitle"
@@ -278,6 +285,7 @@ exports[`<LoginWithQR /> no content in case of no support 1`] = `
<div>
<div
class="mx_LoginWithQR"
data-testid="login-with-qr"
>
<div
class="mx_LoginWithQR_centreTitle"
@@ -324,6 +332,7 @@ exports[`<LoginWithQR /> renders spinner while generating code 1`] = `
<div>
<div
class="mx_LoginWithQR"
data-testid="login-with-qr"
>
<div
class=""
@@ -352,6 +361,7 @@ exports[`<LoginWithQR /> renders spinner while generating code 1`] = `
<div
aria-label="Loading..."
class="mx_Spinner_icon"
data-testid="spinner"
role="progressbar"
style="width: 32px; height: 32px;"
/>

View File

@@ -13,7 +13,7 @@ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
import { render } from '@testing-library/react';
import { fireEvent, render } from '@testing-library/react';
import React from 'react';
import SecurityUserSettingsTab from "../../../../../../src/components/views/settings/tabs/user/SecurityUserSettingsTab";
@@ -26,6 +26,7 @@ import {
mockClientMethodsCrypto,
mockClientMethodsDevice,
mockPlatformPeg,
flushPromises,
} from '../../../../../test-utils';
describe('<SecurityUserSettingsTab />', () => {
@@ -42,6 +43,12 @@ describe('<SecurityUserSettingsTab />', () => {
...mockClientMethodsCrypto(),
getRooms: jest.fn().mockReturnValue([]),
getIgnoredUsers: jest.fn(),
getVersions: jest.fn().mockResolvedValue({
unstable_features: {
'org.matrix.msc3882': true,
'org.matrix.msc3886': true,
},
}),
});
const getComponent = () =>
@@ -70,4 +77,34 @@ describe('<SecurityUserSettingsTab />', () => {
expect(queryByTestId('devices-section')).toBeFalsy();
});
it('does not render qr code login section when disabled', () => {
settingsValueSpy.mockReturnValue(false);
const { queryByText } = render(getComponent());
expect(settingsValueSpy).toHaveBeenCalledWith('feature_qr_signin_reciprocate_show');
expect(queryByText('Sign in with QR code')).toBeFalsy();
});
it('renders qr code login section when enabled', async () => {
settingsValueSpy.mockImplementation(settingName => settingName === 'feature_qr_signin_reciprocate_show');
const { getByText } = render(getComponent());
// wait for versions call to settle
await flushPromises();
expect(getByText('Sign in with QR code')).toBeTruthy();
});
it('enters qr code login section when show QR code button clicked', async () => {
settingsValueSpy.mockImplementation(settingName => settingName === 'feature_qr_signin_reciprocate_show');
const { getByText, getByTestId } = render(getComponent());
// wait for versions call to settle
await flushPromises();
fireEvent.click(getByText('Show QR code'));
expect(getByTestId("login-with-qr")).toBeTruthy();
});
});

View File

@@ -34,6 +34,7 @@ import {
import SessionManagerTab from '../../../../../../src/components/views/settings/tabs/user/SessionManagerTab';
import MatrixClientContext from '../../../../../../src/contexts/MatrixClientContext';
import {
flushPromises,
flushPromisesWithFakeTimers,
getMockClientWithEventEmitter,
mkPusher,
@@ -47,6 +48,7 @@ import {
ExtendedDevice,
} from '../../../../../../src/components/views/settings/devices/types';
import { INACTIVE_DEVICE_AGE_MS } from '../../../../../../src/components/views/settings/devices/filter';
import SettingsStore from '../../../../../../src/settings/SettingsStore';
mockPlatformPeg();
@@ -1142,4 +1144,50 @@ describe('<SessionManagerTab />', () => {
expect(checkbox.getAttribute('aria-checked')).toEqual("false");
});
describe('QR code login', () => {
const settingsValueSpy = jest.spyOn(SettingsStore, 'getValue');
beforeEach(() => {
settingsValueSpy.mockClear().mockReturnValue(false);
// enable server support for qr login
mockClient.getVersions.mockResolvedValue({
versions: [],
unstable_features: {
'org.matrix.msc3882': true,
'org.matrix.msc3886': true,
},
});
});
it('does not render qr code login section when disabled', () => {
settingsValueSpy.mockReturnValue(false);
const { queryByText } = render(getComponent());
expect(settingsValueSpy).toHaveBeenCalledWith('feature_qr_signin_reciprocate_show');
expect(queryByText('Sign in with QR code')).toBeFalsy();
});
it('renders qr code login section when enabled', async () => {
settingsValueSpy.mockImplementation(settingName => settingName === 'feature_qr_signin_reciprocate_show');
const { getByText } = render(getComponent());
// wait for versions call to settle
await flushPromises();
expect(getByText('Sign in with QR code')).toBeTruthy();
});
it('enters qr code login section when show QR code button clicked', async () => {
settingsValueSpy.mockImplementation(settingName => settingName === 'feature_qr_signin_reciprocate_show');
const { getByText, getByTestId } = render(getComponent());
// wait for versions call to settle
await flushPromises();
fireEvent.click(getByText('Show QR code'));
expect(getByTestId("login-with-qr")).toBeTruthy();
});
});
});