You've already forked matrix-react-sdk
mirror of
https://github.com/matrix-org/matrix-react-sdk.git
synced 2025-08-06 10:22:45 +03:00
Merge branch 'develop' of github.com:matrix-org/matrix-react-sdk into t3chguy/react18/context-hocs
This commit is contained in:
@@ -388,4 +388,60 @@ describe("DecryptionFailureTracker", function () {
|
||||
// should track remapped error code
|
||||
expect(counts["XEDNI_EGASSEM_NWONKNU_MLO"]).toBe(1);
|
||||
});
|
||||
|
||||
it("default error code mapper maps error codes correctly", async () => {
|
||||
const errorCodes: string[] = [];
|
||||
|
||||
// @ts-ignore access to private constructor
|
||||
const tracker = new DecryptionFailureTracker(
|
||||
(total: number, errorCode: string) => {
|
||||
errorCodes.push(errorCode);
|
||||
},
|
||||
// @ts-ignore access to private member
|
||||
DecryptionFailureTracker.instance.errorCodeMapFn,
|
||||
);
|
||||
|
||||
const event1 = await createFailedDecryptionEvent(DecryptionFailureCode.MEGOLM_UNKNOWN_INBOUND_SESSION_ID);
|
||||
tracker.addVisibleEvent(event1);
|
||||
tracker.eventDecrypted(event1);
|
||||
|
||||
const event2 = await createFailedDecryptionEvent(DecryptionFailureCode.OLM_UNKNOWN_MESSAGE_INDEX);
|
||||
tracker.addVisibleEvent(event2);
|
||||
tracker.eventDecrypted(event2);
|
||||
|
||||
const event3 = await createFailedDecryptionEvent(DecryptionFailureCode.HISTORICAL_MESSAGE_NO_KEY_BACKUP);
|
||||
tracker.addVisibleEvent(event3);
|
||||
tracker.eventDecrypted(event3);
|
||||
|
||||
const event4 = await createFailedDecryptionEvent(DecryptionFailureCode.HISTORICAL_MESSAGE_BACKUP_UNCONFIGURED);
|
||||
tracker.addVisibleEvent(event4);
|
||||
tracker.eventDecrypted(event4);
|
||||
|
||||
const event5 = await createFailedDecryptionEvent(DecryptionFailureCode.HISTORICAL_MESSAGE_WORKING_BACKUP);
|
||||
tracker.addVisibleEvent(event5);
|
||||
tracker.eventDecrypted(event5);
|
||||
|
||||
const event6 = await createFailedDecryptionEvent(DecryptionFailureCode.HISTORICAL_MESSAGE_USER_NOT_JOINED);
|
||||
tracker.addVisibleEvent(event6);
|
||||
tracker.eventDecrypted(event6);
|
||||
|
||||
const event7 = await createFailedDecryptionEvent(DecryptionFailureCode.UNKNOWN_ERROR);
|
||||
tracker.addVisibleEvent(event7);
|
||||
tracker.eventDecrypted(event7);
|
||||
|
||||
// Pretend "now" is Infinity
|
||||
tracker.checkFailures(Infinity);
|
||||
|
||||
tracker.trackFailures();
|
||||
|
||||
expect(errorCodes).toEqual([
|
||||
"OlmKeysNotSentError",
|
||||
"OlmIndexError",
|
||||
"HistoricalMessage",
|
||||
"HistoricalMessage",
|
||||
"HistoricalMessage",
|
||||
"ExpectedDueToMembership",
|
||||
"UnknownError",
|
||||
]);
|
||||
});
|
||||
});
|
||||
|
@@ -36,7 +36,7 @@ const getFakePosthog = (): PostHog =>
|
||||
register: jest.fn(),
|
||||
get_distinct_id: jest.fn(),
|
||||
persistence: {
|
||||
get_user_state: jest.fn(),
|
||||
get_property: jest.fn(),
|
||||
},
|
||||
identifyUser: jest.fn(),
|
||||
}) as unknown as PostHog;
|
||||
|
@@ -20,6 +20,8 @@ import { MatrixClient, MatrixEvent, Room } from "matrix-js-sdk/src/matrix";
|
||||
|
||||
import { SlidingSyncManager } from "../src/SlidingSyncManager";
|
||||
import { stubClient } from "./test-utils";
|
||||
import SlidingSyncController from "../src/settings/controllers/SlidingSyncController";
|
||||
import SettingsStore from "../src/settings/SettingsStore";
|
||||
|
||||
jest.mock("matrix-js-sdk/src/sliding-sync");
|
||||
const MockSlidingSync = <jest.Mock<SlidingSync>>(<unknown>SlidingSync);
|
||||
@@ -231,4 +233,53 @@ describe("SlidingSyncManager", () => {
|
||||
);
|
||||
});
|
||||
});
|
||||
describe("checkSupport", () => {
|
||||
beforeEach(() => {
|
||||
SlidingSyncController.serverSupportsSlidingSync = false;
|
||||
jest.spyOn(manager, "getProxyFromWellKnown").mockResolvedValue("proxy");
|
||||
});
|
||||
it("shorts out if the server has 'native' sliding sync support", async () => {
|
||||
jest.spyOn(manager, "nativeSlidingSyncSupport").mockResolvedValue(true);
|
||||
expect(SlidingSyncController.serverSupportsSlidingSync).toBeFalsy();
|
||||
await manager.checkSupport(client);
|
||||
expect(manager.getProxyFromWellKnown).not.toHaveBeenCalled(); // We return earlier
|
||||
expect(SlidingSyncController.serverSupportsSlidingSync).toBeTruthy();
|
||||
});
|
||||
it("tries to find a sliding sync proxy url from the client well-known if there's no 'native' support", async () => {
|
||||
jest.spyOn(manager, "nativeSlidingSyncSupport").mockResolvedValue(false);
|
||||
expect(SlidingSyncController.serverSupportsSlidingSync).toBeFalsy();
|
||||
await manager.checkSupport(client);
|
||||
expect(manager.getProxyFromWellKnown).toHaveBeenCalled();
|
||||
expect(SlidingSyncController.serverSupportsSlidingSync).toBeTruthy();
|
||||
});
|
||||
});
|
||||
describe("setup", () => {
|
||||
beforeEach(() => {
|
||||
jest.spyOn(manager, "configure");
|
||||
jest.spyOn(manager, "startSpidering");
|
||||
});
|
||||
it("uses the baseUrl as a proxy if no proxy is set in the client well-known and the server has no native support", async () => {
|
||||
await manager.setup(client);
|
||||
expect(manager.configure).toHaveBeenCalled();
|
||||
expect(manager.configure).toHaveBeenCalledWith(client, client.baseUrl);
|
||||
expect(manager.startSpidering).toHaveBeenCalled();
|
||||
});
|
||||
it("uses the proxy declared in the client well-known", async () => {
|
||||
jest.spyOn(manager, "getProxyFromWellKnown").mockResolvedValue("proxy");
|
||||
await manager.setup(client);
|
||||
expect(manager.configure).toHaveBeenCalled();
|
||||
expect(manager.configure).toHaveBeenCalledWith(client, "proxy");
|
||||
expect(manager.startSpidering).toHaveBeenCalled();
|
||||
});
|
||||
it("uses the legacy `feature_sliding_sync_proxy_url` if it was set", async () => {
|
||||
jest.spyOn(manager, "getProxyFromWellKnown").mockResolvedValue("proxy");
|
||||
jest.spyOn(SettingsStore, "getValue").mockImplementation((name: string) => {
|
||||
if (name === "feature_sliding_sync_proxy_url") return "legacy-proxy";
|
||||
});
|
||||
await manager.setup(client);
|
||||
expect(manager.configure).toHaveBeenCalled();
|
||||
expect(manager.configure).toHaveBeenCalledWith(client, "legacy-proxy");
|
||||
expect(manager.startSpidering).toHaveBeenCalled();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
@@ -61,6 +61,7 @@ import SettingsStore from "../../../src/settings/SettingsStore";
|
||||
import { SettingLevel } from "../../../src/settings/SettingLevel";
|
||||
import { MatrixClientPeg as peg } from "../../../src/MatrixClientPeg";
|
||||
import DMRoomMap from "../../../src/utils/DMRoomMap";
|
||||
import { ReleaseAnnouncementStore } from "../../../src/stores/ReleaseAnnouncementStore";
|
||||
|
||||
jest.mock("matrix-js-sdk/src/oidc/authorize", () => ({
|
||||
completeAuthorizationCodeGrant: jest.fn(),
|
||||
@@ -627,6 +628,12 @@ describe("<MatrixChat />", () => {
|
||||
(id) => [room, spaceRoom].find((room) => room.roomId === id) || null,
|
||||
);
|
||||
jest.spyOn(spaceRoom, "isSpaceRoom").mockReturnValue(true);
|
||||
|
||||
jest.spyOn(ReleaseAnnouncementStore.instance, "getReleaseAnnouncement").mockReturnValue(null);
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
jest.restoreAllMocks();
|
||||
});
|
||||
|
||||
describe("leave_room", () => {
|
||||
|
@@ -397,6 +397,7 @@ exports[`RoomView for a local room in state NEW should match the snapshot 1`] =
|
||||
<button
|
||||
aria-label="Bold"
|
||||
class="mx_AccessibleButton mx_MessageComposerFormatBar_button mx_MessageComposerFormatBar_buttonIconBold"
|
||||
data-state="closed"
|
||||
role="button"
|
||||
tabindex="0"
|
||||
type="button"
|
||||
@@ -404,6 +405,7 @@ exports[`RoomView for a local room in state NEW should match the snapshot 1`] =
|
||||
<button
|
||||
aria-label="Italics"
|
||||
class="mx_AccessibleButton mx_MessageComposerFormatBar_button mx_MessageComposerFormatBar_buttonIconItalic"
|
||||
data-state="closed"
|
||||
role="button"
|
||||
tabindex="-1"
|
||||
type="button"
|
||||
@@ -411,6 +413,7 @@ exports[`RoomView for a local room in state NEW should match the snapshot 1`] =
|
||||
<button
|
||||
aria-label="Strikethrough"
|
||||
class="mx_AccessibleButton mx_MessageComposerFormatBar_button mx_MessageComposerFormatBar_buttonIconStrikethrough"
|
||||
data-state="closed"
|
||||
role="button"
|
||||
tabindex="-1"
|
||||
type="button"
|
||||
@@ -418,6 +421,7 @@ exports[`RoomView for a local room in state NEW should match the snapshot 1`] =
|
||||
<button
|
||||
aria-label="Code block"
|
||||
class="mx_AccessibleButton mx_MessageComposerFormatBar_button mx_MessageComposerFormatBar_buttonIconCode"
|
||||
data-state="closed"
|
||||
role="button"
|
||||
tabindex="-1"
|
||||
type="button"
|
||||
@@ -425,6 +429,7 @@ exports[`RoomView for a local room in state NEW should match the snapshot 1`] =
|
||||
<button
|
||||
aria-label="Quote"
|
||||
class="mx_AccessibleButton mx_MessageComposerFormatBar_button mx_MessageComposerFormatBar_buttonIconQuote"
|
||||
data-state="closed"
|
||||
role="button"
|
||||
tabindex="-1"
|
||||
type="button"
|
||||
@@ -432,6 +437,7 @@ exports[`RoomView for a local room in state NEW should match the snapshot 1`] =
|
||||
<button
|
||||
aria-label="Insert link"
|
||||
class="mx_AccessibleButton mx_MessageComposerFormatBar_button mx_MessageComposerFormatBar_buttonIconInsertLink"
|
||||
data-state="closed"
|
||||
role="button"
|
||||
tabindex="-1"
|
||||
type="button"
|
||||
@@ -644,6 +650,7 @@ exports[`RoomView for a local room in state NEW that is encrypted should match t
|
||||
<button
|
||||
aria-label="Bold"
|
||||
class="mx_AccessibleButton mx_MessageComposerFormatBar_button mx_MessageComposerFormatBar_buttonIconBold"
|
||||
data-state="closed"
|
||||
role="button"
|
||||
tabindex="0"
|
||||
type="button"
|
||||
@@ -651,6 +658,7 @@ exports[`RoomView for a local room in state NEW that is encrypted should match t
|
||||
<button
|
||||
aria-label="Italics"
|
||||
class="mx_AccessibleButton mx_MessageComposerFormatBar_button mx_MessageComposerFormatBar_buttonIconItalic"
|
||||
data-state="closed"
|
||||
role="button"
|
||||
tabindex="-1"
|
||||
type="button"
|
||||
@@ -658,6 +666,7 @@ exports[`RoomView for a local room in state NEW that is encrypted should match t
|
||||
<button
|
||||
aria-label="Strikethrough"
|
||||
class="mx_AccessibleButton mx_MessageComposerFormatBar_button mx_MessageComposerFormatBar_buttonIconStrikethrough"
|
||||
data-state="closed"
|
||||
role="button"
|
||||
tabindex="-1"
|
||||
type="button"
|
||||
@@ -665,6 +674,7 @@ exports[`RoomView for a local room in state NEW that is encrypted should match t
|
||||
<button
|
||||
aria-label="Code block"
|
||||
class="mx_AccessibleButton mx_MessageComposerFormatBar_button mx_MessageComposerFormatBar_buttonIconCode"
|
||||
data-state="closed"
|
||||
role="button"
|
||||
tabindex="-1"
|
||||
type="button"
|
||||
@@ -672,6 +682,7 @@ exports[`RoomView for a local room in state NEW that is encrypted should match t
|
||||
<button
|
||||
aria-label="Quote"
|
||||
class="mx_AccessibleButton mx_MessageComposerFormatBar_button mx_MessageComposerFormatBar_buttonIconQuote"
|
||||
data-state="closed"
|
||||
role="button"
|
||||
tabindex="-1"
|
||||
type="button"
|
||||
@@ -679,6 +690,7 @@ exports[`RoomView for a local room in state NEW that is encrypted should match t
|
||||
<button
|
||||
aria-label="Insert link"
|
||||
class="mx_AccessibleButton mx_MessageComposerFormatBar_button mx_MessageComposerFormatBar_buttonIconInsertLink"
|
||||
data-state="closed"
|
||||
role="button"
|
||||
tabindex="-1"
|
||||
type="button"
|
||||
|
@@ -12,7 +12,6 @@ exports[`<UserMenu> <UserMenu> when video broadcast when rendered should render
|
||||
class="mx_AccessibleButton mx_UserMenu_contextMenuButton"
|
||||
role="button"
|
||||
tabindex="0"
|
||||
title="User menu"
|
||||
>
|
||||
<div
|
||||
class="mx_UserMenu_userAvatar"
|
||||
|
@@ -48,6 +48,7 @@ exports[`<BeaconListItem /> when a beacon is live and has locations renders beac
|
||||
<div
|
||||
aria-label="Copy"
|
||||
class="mx_AccessibleButton mx_CopyableText_copyButton"
|
||||
data-state="closed"
|
||||
role="button"
|
||||
tabindex="0"
|
||||
/>
|
||||
|
@@ -14,11 +14,12 @@ exports[`<DialogSidebar /> renders sidebar correctly with beacons 1`] = `
|
||||
View list
|
||||
</h4>
|
||||
<div
|
||||
aria-label="Close sidebar"
|
||||
class="mx_AccessibleButton mx_DialogSidebar_closeButton"
|
||||
data-state="closed"
|
||||
data-testid="dialog-sidebar-close"
|
||||
role="button"
|
||||
tabindex="0"
|
||||
title="Close sidebar"
|
||||
>
|
||||
<div
|
||||
class="mx_DialogSidebar_closeButtonIcon"
|
||||
@@ -81,6 +82,7 @@ exports[`<DialogSidebar /> renders sidebar correctly with beacons 1`] = `
|
||||
<div
|
||||
aria-label="Copy"
|
||||
class="mx_AccessibleButton mx_CopyableText_copyButton"
|
||||
data-state="closed"
|
||||
role="button"
|
||||
tabindex="0"
|
||||
/>
|
||||
@@ -113,11 +115,12 @@ exports[`<DialogSidebar /> renders sidebar correctly without beacons 1`] = `
|
||||
View list
|
||||
</h4>
|
||||
<div
|
||||
aria-label="Close sidebar"
|
||||
class="mx_AccessibleButton mx_DialogSidebar_closeButton"
|
||||
data-state="closed"
|
||||
data-testid="dialog-sidebar-close"
|
||||
role="button"
|
||||
tabindex="0"
|
||||
title="Close sidebar"
|
||||
>
|
||||
<div
|
||||
class="mx_DialogSidebar_closeButtonIcon"
|
||||
|
@@ -3,10 +3,11 @@
|
||||
exports[`<LeftPanelLiveShareWarning /> when user has live location monitor renders correctly when minimized 1`] = `
|
||||
<DocumentFragment>
|
||||
<div
|
||||
aria-label="You are sharing your live location"
|
||||
class="mx_AccessibleButton mx_LeftPanelLiveShareWarning mx_LeftPanelLiveShareWarning__minimized"
|
||||
data-state="closed"
|
||||
role="button"
|
||||
tabindex="0"
|
||||
title="You are sharing your live location"
|
||||
>
|
||||
<div
|
||||
height="10"
|
||||
|
@@ -109,11 +109,12 @@ exports[`<RoomLiveShareWarning /> when user has live beacons and geolocation is
|
||||
Retry
|
||||
</button>
|
||||
<button
|
||||
aria-label="Stop and close"
|
||||
class="mx_AccessibleButton mx_RoomLiveShareWarning_closeButton"
|
||||
data-state="closed"
|
||||
data-testid="room-live-share-wire-error-close-button"
|
||||
role="button"
|
||||
tabindex="0"
|
||||
title="Stop and close"
|
||||
>
|
||||
<div
|
||||
class="mx_RoomLiveShareWarning_closeButtonIcon"
|
||||
|
@@ -19,6 +19,7 @@ exports[`<ShareLatestLocation /> renders share buttons when there is a location
|
||||
<div
|
||||
aria-label="Copy"
|
||||
class="mx_AccessibleButton mx_CopyableText_copyButton"
|
||||
data-state="closed"
|
||||
role="button"
|
||||
tabindex="0"
|
||||
/>
|
||||
|
@@ -152,14 +152,17 @@ describe("<UserSettingsDialog />", () => {
|
||||
watchSettingCallbacks[settingName] = callback;
|
||||
return `mock-watcher-id-${settingName}`;
|
||||
});
|
||||
mockSettingsStore.getValue.mockReturnValue(false);
|
||||
|
||||
const { queryByTestId, unmount } = render(getComponent());
|
||||
expect(queryByTestId(`settings-tab-${UserTab.Mjolnir}`)).toBeFalsy();
|
||||
|
||||
expect(mockSettingsStore.watchSetting.mock.calls[0][0]).toEqual("feature_mjolnir");
|
||||
expect(mockSettingsStore.watchSetting).toHaveBeenCalledWith("feature_mjolnir", null, expect.anything());
|
||||
|
||||
// call the watch setting callback
|
||||
mockSettingsStore.getValue.mockReturnValue(true);
|
||||
watchSettingCallbacks["feature_mjolnir"]("feature_mjolnir", "", SettingLevel.ACCOUNT, true, true);
|
||||
|
||||
// tab is rendered now
|
||||
expect(queryByTestId(`settings-tab-${UserTab.Mjolnir}`)).toBeTruthy();
|
||||
|
||||
|
@@ -41,6 +41,7 @@ exports[`DevtoolsDialog renders the devtools dialog 1`] = `
|
||||
<div
|
||||
aria-label="Copy"
|
||||
class="mx_AccessibleButton mx_CopyableText_copyButton"
|
||||
data-state="closed"
|
||||
role="button"
|
||||
tabindex="0"
|
||||
/>
|
||||
|
@@ -377,12 +377,12 @@ describe("AppTile", () => {
|
||||
});
|
||||
|
||||
it("clicking 'minimise' should send the widget to the right", async () => {
|
||||
await userEvent.click(renderResult.getByTitle("Minimise"));
|
||||
await userEvent.click(renderResult.getByLabelText("Minimise"));
|
||||
expect(moveToContainerSpy).toHaveBeenCalledWith(r1, app1, Container.Right);
|
||||
});
|
||||
|
||||
it("clicking 'maximise' should send the widget to the center", async () => {
|
||||
await userEvent.click(renderResult.getByTitle("Maximise"));
|
||||
await userEvent.click(renderResult.getByLabelText("Maximise"));
|
||||
expect(moveToContainerSpy).toHaveBeenCalledWith(r1, app1, Container.Center);
|
||||
});
|
||||
|
||||
@@ -435,7 +435,7 @@ describe("AppTile", () => {
|
||||
});
|
||||
|
||||
it("clicking 'un-maximise' should send the widget to the top", async () => {
|
||||
await userEvent.click(renderResult.getByTitle("Un-maximise"));
|
||||
await userEvent.click(renderResult.getByLabelText("Un-maximise"));
|
||||
expect(moveToContainerSpy).toHaveBeenCalledWith(r1, app1, Container.Top);
|
||||
});
|
||||
});
|
||||
@@ -461,7 +461,7 @@ describe("AppTile", () => {
|
||||
});
|
||||
|
||||
it("should display the »Popout widget« button", () => {
|
||||
expect(renderResult.getByTitle("Popout widget")).toBeInTheDocument();
|
||||
expect(renderResult.getByLabelText("Popout widget")).toBeInTheDocument();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
29
test/components/views/elements/ImageView-test.tsx
Normal file
29
test/components/views/elements/ImageView-test.tsx
Normal file
@@ -0,0 +1,29 @@
|
||||
/*
|
||||
*
|
||||
* Copyright 2024 The Matrix.org Foundation C.I.C.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
* /
|
||||
*/
|
||||
|
||||
import React from "react";
|
||||
import { render } from "@testing-library/react";
|
||||
|
||||
import ImageView from "../../../../src/components/views/elements/ImageView";
|
||||
|
||||
describe("<ImageView />", () => {
|
||||
it("renders correctly", () => {
|
||||
const { container } = render(<ImageView src="https://example.com/image.png" onFinished={jest.fn()} />);
|
||||
expect(container).toMatchSnapshot();
|
||||
});
|
||||
});
|
@@ -13,11 +13,12 @@ exports[`AppTile destroys non-persisted right panel widget on room change 1`] =
|
||||
class="mx_BaseCard_header"
|
||||
>
|
||||
<div
|
||||
aria-label="Close"
|
||||
class="mx_AccessibleButton mx_BaseCard_close"
|
||||
data-state="closed"
|
||||
data-testid="base-card-close-button"
|
||||
role="button"
|
||||
tabindex="0"
|
||||
title="Close"
|
||||
/>
|
||||
<div
|
||||
class="mx_BaseCard_headerProp"
|
||||
@@ -37,7 +38,6 @@ exports[`AppTile destroys non-persisted right panel widget on room change 1`] =
|
||||
class="mx_AccessibleButton mx_BaseCard_header_title_button--option"
|
||||
role="button"
|
||||
tabindex="0"
|
||||
title="Options"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
@@ -136,20 +136,22 @@ exports[`AppTile for a pinned widget should render 1`] = `
|
||||
class="mx_AppTileMenuBar_widgets"
|
||||
>
|
||||
<div
|
||||
aria-label="Un-maximise"
|
||||
class="mx_AccessibleButton mx_AppTileMenuBar_widgets_button"
|
||||
data-state="closed"
|
||||
role="button"
|
||||
tabindex="0"
|
||||
title="Un-maximise"
|
||||
>
|
||||
<div
|
||||
class="mx_Icon mx_Icon_12"
|
||||
/>
|
||||
</div>
|
||||
<div
|
||||
aria-label="Minimise"
|
||||
class="mx_AccessibleButton mx_AppTileMenuBar_widgets_button"
|
||||
data-state="closed"
|
||||
role="button"
|
||||
tabindex="0"
|
||||
title="Minimise"
|
||||
>
|
||||
<div
|
||||
class="mx_Icon mx_Icon_12"
|
||||
@@ -162,7 +164,6 @@ exports[`AppTile for a pinned widget should render 1`] = `
|
||||
class="mx_AccessibleButton mx_AppTileMenuBar_widgets_button"
|
||||
role="button"
|
||||
tabindex="0"
|
||||
title="Options"
|
||||
>
|
||||
<div
|
||||
class="mx_Icon mx_Icon_12"
|
||||
@@ -223,20 +224,22 @@ exports[`AppTile for a pinned widget should render permission request 1`] = `
|
||||
class="mx_AppTileMenuBar_widgets"
|
||||
>
|
||||
<div
|
||||
aria-label="Un-maximise"
|
||||
class="mx_AccessibleButton mx_AppTileMenuBar_widgets_button"
|
||||
data-state="closed"
|
||||
role="button"
|
||||
tabindex="0"
|
||||
title="Un-maximise"
|
||||
>
|
||||
<div
|
||||
class="mx_Icon mx_Icon_12"
|
||||
/>
|
||||
</div>
|
||||
<div
|
||||
aria-label="Minimise"
|
||||
class="mx_AccessibleButton mx_AppTileMenuBar_widgets_button"
|
||||
data-state="closed"
|
||||
role="button"
|
||||
tabindex="0"
|
||||
title="Minimise"
|
||||
>
|
||||
<div
|
||||
class="mx_Icon mx_Icon_12"
|
||||
@@ -249,7 +252,6 @@ exports[`AppTile for a pinned widget should render permission request 1`] = `
|
||||
class="mx_AccessibleButton mx_AppTileMenuBar_widgets_button"
|
||||
role="button"
|
||||
tabindex="0"
|
||||
title="Options"
|
||||
>
|
||||
<div
|
||||
class="mx_Icon mx_Icon_12"
|
||||
@@ -377,20 +379,22 @@ exports[`AppTile preserves non-persisted widget on container move 1`] = `
|
||||
class="mx_AppTileMenuBar_widgets"
|
||||
>
|
||||
<div
|
||||
aria-label="Maximise"
|
||||
class="mx_AccessibleButton mx_AppTileMenuBar_widgets_button"
|
||||
data-state="closed"
|
||||
role="button"
|
||||
tabindex="0"
|
||||
title="Maximise"
|
||||
>
|
||||
<div
|
||||
class="mx_Icon mx_Icon_12"
|
||||
/>
|
||||
</div>
|
||||
<div
|
||||
aria-label="Minimise"
|
||||
class="mx_AccessibleButton mx_AppTileMenuBar_widgets_button"
|
||||
data-state="closed"
|
||||
role="button"
|
||||
tabindex="0"
|
||||
title="Minimise"
|
||||
>
|
||||
<div
|
||||
class="mx_Icon mx_Icon_12"
|
||||
@@ -403,7 +407,6 @@ exports[`AppTile preserves non-persisted widget on container move 1`] = `
|
||||
class="mx_AccessibleButton mx_AppTileMenuBar_widgets_button"
|
||||
role="button"
|
||||
tabindex="0"
|
||||
title="Options"
|
||||
>
|
||||
<div
|
||||
class="mx_Icon mx_Icon_12"
|
||||
|
@@ -0,0 +1,88 @@
|
||||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||
|
||||
exports[`<ImageView /> renders correctly 1`] = `
|
||||
<div>
|
||||
<div
|
||||
data-focus-guard="true"
|
||||
style="width: 1px; height: 0px; padding: 0px; overflow: hidden; position: fixed; top: 1px; left: 1px;"
|
||||
tabindex="0"
|
||||
/>
|
||||
<div
|
||||
aria-label="Image view"
|
||||
class="mx_ImageView"
|
||||
data-focus-lock-disabled="false"
|
||||
role="dialog"
|
||||
>
|
||||
<div
|
||||
class="mx_ImageView_panel"
|
||||
>
|
||||
<div />
|
||||
<div
|
||||
class="mx_ImageView_toolbar"
|
||||
>
|
||||
<div
|
||||
aria-describedby="floating-ui-2"
|
||||
aria-label="Zoom out"
|
||||
class="mx_AccessibleButton mx_ImageView_button mx_ImageView_button_zoomOut"
|
||||
data-state="open"
|
||||
role="button"
|
||||
tabindex="0"
|
||||
/>
|
||||
<div
|
||||
aria-label="Zoom in"
|
||||
class="mx_AccessibleButton mx_ImageView_button mx_ImageView_button_zoomIn"
|
||||
data-state="closed"
|
||||
role="button"
|
||||
tabindex="0"
|
||||
/>
|
||||
<div
|
||||
aria-label="Rotate Left"
|
||||
class="mx_AccessibleButton mx_ImageView_button mx_ImageView_button_rotateCCW"
|
||||
data-state="closed"
|
||||
role="button"
|
||||
tabindex="0"
|
||||
/>
|
||||
<div
|
||||
aria-label="Rotate Right"
|
||||
class="mx_AccessibleButton mx_ImageView_button mx_ImageView_button_rotateCW"
|
||||
data-state="closed"
|
||||
role="button"
|
||||
tabindex="0"
|
||||
/>
|
||||
<div
|
||||
aria-label="Download"
|
||||
class="mx_AccessibleButton mx_ImageView_button mx_ImageView_button_download"
|
||||
data-state="closed"
|
||||
role="button"
|
||||
tabindex="0"
|
||||
/>
|
||||
<div
|
||||
aria-label="Close"
|
||||
class="mx_AccessibleButton mx_ImageView_button mx_ImageView_button_close"
|
||||
data-state="closed"
|
||||
role="button"
|
||||
tabindex="0"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
class="mx_ImageView_image_wrapper"
|
||||
>
|
||||
<img
|
||||
class="mx_ImageView_image "
|
||||
draggable="true"
|
||||
src="https://example.com/image.png"
|
||||
style="transform: translateX(0px)
|
||||
translateY(0px)
|
||||
scale(0)
|
||||
rotate(0deg); cursor: zoom-out;"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
data-focus-guard="true"
|
||||
style="width: 1px; height: 0px; padding: 0px; overflow: hidden; position: fixed; top: 1px; left: 1px;"
|
||||
tabindex="0"
|
||||
/>
|
||||
</div>
|
||||
`;
|
@@ -23,22 +23,24 @@ exports[`<LocationViewDialog /> renders map correctly 1`] = `
|
||||
class="mx_ZoomButtons"
|
||||
>
|
||||
<div
|
||||
aria-label="Zoom in"
|
||||
class="mx_AccessibleButton mx_ZoomButtons_button"
|
||||
data-state="closed"
|
||||
data-testid="map-zoom-in-button"
|
||||
role="button"
|
||||
tabindex="0"
|
||||
title="Zoom in"
|
||||
>
|
||||
<div
|
||||
class="mx_ZoomButtons_icon"
|
||||
/>
|
||||
</div>
|
||||
<div
|
||||
aria-label="Zoom out"
|
||||
class="mx_AccessibleButton mx_ZoomButtons_button"
|
||||
data-state="closed"
|
||||
data-testid="map-zoom-out-button"
|
||||
role="button"
|
||||
tabindex="0"
|
||||
title="Zoom out"
|
||||
>
|
||||
<div
|
||||
class="mx_ZoomButtons_icon"
|
||||
|
@@ -6,22 +6,24 @@ exports[`<ZoomButtons /> renders buttons 1`] = `
|
||||
class="mx_ZoomButtons"
|
||||
>
|
||||
<div
|
||||
aria-label="Zoom in"
|
||||
class="mx_AccessibleButton mx_ZoomButtons_button"
|
||||
data-state="closed"
|
||||
data-testid="map-zoom-in-button"
|
||||
role="button"
|
||||
tabindex="0"
|
||||
title="Zoom in"
|
||||
>
|
||||
<div
|
||||
class="mx_ZoomButtons_icon"
|
||||
/>
|
||||
</div>
|
||||
<div
|
||||
aria-label="Zoom out"
|
||||
class="mx_AccessibleButton mx_ZoomButtons_button"
|
||||
data-state="closed"
|
||||
data-testid="map-zoom-out-button"
|
||||
role="button"
|
||||
tabindex="0"
|
||||
title="Zoom out"
|
||||
>
|
||||
<div
|
||||
class="mx_ZoomButtons_icon"
|
||||
|
@@ -17,13 +17,20 @@
|
||||
import React from "react";
|
||||
import { render } from "@testing-library/react";
|
||||
import { MatrixEvent } from "matrix-js-sdk/src/matrix";
|
||||
import { mkDecryptionFailureMatrixEvent } from "matrix-js-sdk/src/testing";
|
||||
import { DecryptionFailureCode } from "matrix-js-sdk/src/crypto-api";
|
||||
|
||||
import { mkEvent } from "../../../test-utils";
|
||||
import { DecryptionFailureBody } from "../../../../src/components/views/messages/DecryptionFailureBody";
|
||||
import { LocalDeviceVerificationStateContext } from "../../../../src/contexts/LocalDeviceVerificationStateContext";
|
||||
|
||||
describe("DecryptionFailureBody", () => {
|
||||
function customRender(event: MatrixEvent) {
|
||||
return render(<DecryptionFailureBody mxEvent={event} />);
|
||||
function customRender(event: MatrixEvent, localDeviceVerified: boolean = false) {
|
||||
return render(
|
||||
<LocalDeviceVerificationStateContext.Provider value={localDeviceVerified}>
|
||||
<DecryptionFailureBody mxEvent={event} />
|
||||
</LocalDeviceVerificationStateContext.Provider>,
|
||||
);
|
||||
}
|
||||
|
||||
it(`Should display "Unable to decrypt message"`, () => {
|
||||
@@ -60,4 +67,51 @@ describe("DecryptionFailureBody", () => {
|
||||
// Then
|
||||
expect(container).toMatchSnapshot();
|
||||
});
|
||||
|
||||
it("should handle historical messages with no key backup", async () => {
|
||||
// When
|
||||
const event = await mkDecryptionFailureMatrixEvent({
|
||||
code: DecryptionFailureCode.HISTORICAL_MESSAGE_NO_KEY_BACKUP,
|
||||
msg: "No backup",
|
||||
roomId: "fakeroom",
|
||||
sender: "fakesender",
|
||||
});
|
||||
const { container } = customRender(event);
|
||||
|
||||
// Then
|
||||
expect(container).toHaveTextContent("Historical messages are not available on this device");
|
||||
});
|
||||
|
||||
it.each([true, false])(
|
||||
"should handle historical messages when there is a backup and device verification is %s",
|
||||
async (verified) => {
|
||||
// When
|
||||
const event = await mkDecryptionFailureMatrixEvent({
|
||||
code: DecryptionFailureCode.HISTORICAL_MESSAGE_BACKUP_UNCONFIGURED,
|
||||
msg: "Failure",
|
||||
roomId: "fakeroom",
|
||||
sender: "fakesender",
|
||||
});
|
||||
const { container } = customRender(event, verified);
|
||||
|
||||
// Then
|
||||
expect(container).toHaveTextContent(
|
||||
verified ? "Unable to decrypt" : "You need to verify this device for access to historical messages",
|
||||
);
|
||||
},
|
||||
);
|
||||
|
||||
it("should handle undecryptable pre-join messages", async () => {
|
||||
// When
|
||||
const event = await mkDecryptionFailureMatrixEvent({
|
||||
code: DecryptionFailureCode.HISTORICAL_MESSAGE_USER_NOT_JOINED,
|
||||
msg: "Not joined",
|
||||
roomId: "fakeroom",
|
||||
sender: "fakesender",
|
||||
});
|
||||
const { container } = customRender(event);
|
||||
|
||||
// Then
|
||||
expect(container).toHaveTextContent("You don't have access to this message");
|
||||
});
|
||||
});
|
||||
|
@@ -293,7 +293,8 @@ describe("<UserInfo />", () => {
|
||||
|
||||
it("renders close button correctly when encryption panel with a pending verification request", () => {
|
||||
renderComponent({ phase: RightPanelPhases.EncryptionPanel, verificationRequest });
|
||||
expect(screen.getByTestId("base-card-close-button")).toHaveAttribute("title", "Cancel");
|
||||
screen.getByTestId("base-card-close-button").focus();
|
||||
expect(screen.getByRole("tooltip")).toHaveTextContent("Cancel");
|
||||
});
|
||||
});
|
||||
|
||||
@@ -387,11 +388,8 @@ describe("<UserInfo />", () => {
|
||||
// click it
|
||||
await userEvent.click(devicesButton);
|
||||
|
||||
// there should now be a button with the device id ...
|
||||
const deviceButton = screen.getByRole("button", { description: "d1" });
|
||||
|
||||
// ... which should contain the device name
|
||||
expect(within(deviceButton).getByText("my device")).toBeInTheDocument();
|
||||
// there should now be a button with the device id which should contain the device name
|
||||
expect(screen.getByRole("button", { name: "my device" })).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it("renders <BasicUserInfo />", async () => {
|
||||
@@ -444,10 +442,10 @@ describe("<UserInfo />", () => {
|
||||
});
|
||||
|
||||
// there should now be a button with the non-dehydrated device ID
|
||||
expect(screen.getByRole("button", { description: "d1" })).toBeInTheDocument();
|
||||
expect(screen.getByRole("button", { name: "my device" })).toBeInTheDocument();
|
||||
|
||||
// but not for the dehydrated device ID
|
||||
expect(screen.queryByRole("button", { description: "d2" })).not.toBeInTheDocument();
|
||||
expect(screen.queryByRole("button", { name: "dehydrated device" })).not.toBeInTheDocument();
|
||||
|
||||
// there should be a line saying that the user has "Offline device" enabled
|
||||
expect(screen.getByText("Offline device enabled")).toBeInTheDocument();
|
||||
@@ -530,7 +528,7 @@ describe("<UserInfo />", () => {
|
||||
|
||||
// the dehydrated device should be shown as an unverified device, which means
|
||||
// there should now be a button with the device id ...
|
||||
const deviceButton = screen.getByRole("button", { description: "d2" });
|
||||
const deviceButton = screen.getByRole("button", { name: "dehydrated device" });
|
||||
|
||||
// ... which should contain the device name
|
||||
expect(within(deviceButton).getByText("dehydrated device")).toBeInTheDocument();
|
||||
@@ -572,13 +570,15 @@ describe("<UserInfo />", () => {
|
||||
});
|
||||
|
||||
// the dehydrated devices should be shown as an unverified device, which means
|
||||
// there should now be a button with the first dehydrated device id ...
|
||||
const device1Button = screen.getByRole("button", { description: "d1" });
|
||||
// there should now be a button with the first dehydrated device...
|
||||
const device1Button = screen.getByRole("button", { name: "dehydrated device 1" });
|
||||
expect(device1Button).toBeVisible();
|
||||
|
||||
// ... which should contain the device name
|
||||
expect(within(device1Button).getByText("dehydrated device 1")).toBeInTheDocument();
|
||||
// and a button with the second dehydrated device id ...
|
||||
const device2Button = screen.getByRole("button", { description: "d2" });
|
||||
// and a button with the second dehydrated device...
|
||||
const device2Button = screen.getByRole("button", { name: "dehydrated device 2" });
|
||||
expect(device2Button).toBeVisible();
|
||||
|
||||
// ... which should contain the device name
|
||||
expect(within(device2Button).getByText("dehydrated device 2")).toBeInTheDocument();
|
||||
@@ -707,7 +707,8 @@ describe("<DeviceItem />", () => {
|
||||
renderComponent({ isUserVerified: true });
|
||||
await act(flushPromises);
|
||||
|
||||
expect(screen.getByRole("button", { name: `${device.displayName} Not trusted` })).toBeInTheDocument();
|
||||
const button = screen.getByRole("button", { name: device.displayName });
|
||||
expect(button).toHaveTextContent(`${device.displayName}Not trusted`);
|
||||
});
|
||||
|
||||
it("with verified device only, displays no button without a label", async () => {
|
||||
|
@@ -25,11 +25,12 @@ exports[`<RoomSummaryCard /> renders the room summary 1`] = `
|
||||
/>
|
||||
</button>
|
||||
<div
|
||||
aria-label="Close"
|
||||
class="mx_AccessibleButton mx_BaseCard_close"
|
||||
data-state="closed"
|
||||
data-testid="base-card-close-button"
|
||||
role="button"
|
||||
tabindex="0"
|
||||
title="Close"
|
||||
/>
|
||||
</header>
|
||||
<header
|
||||
|
@@ -3,10 +3,11 @@
|
||||
exports[`<DeviceItem /> ambiguous display name 1`] = `
|
||||
<div>
|
||||
<div
|
||||
aria-label="my display name (deviceId)"
|
||||
class="mx_AccessibleButton mx_UserInfo_device mx_UserInfo_device_unverified"
|
||||
data-state="closed"
|
||||
role="button"
|
||||
tabindex="0"
|
||||
title="deviceId"
|
||||
>
|
||||
<div
|
||||
class="mx_E2EIcon mx_E2EIcon_normal"
|
||||
@@ -26,10 +27,11 @@ exports[`<DeviceItem /> ambiguous display name 1`] = `
|
||||
exports[`<DeviceItem /> with display name 1`] = `
|
||||
<div>
|
||||
<div
|
||||
aria-label="deviceName"
|
||||
class="mx_AccessibleButton mx_UserInfo_device mx_UserInfo_device_unverified"
|
||||
data-state="closed"
|
||||
role="button"
|
||||
tabindex="0"
|
||||
title="deviceId"
|
||||
>
|
||||
<div
|
||||
class="mx_E2EIcon mx_E2EIcon_normal"
|
||||
@@ -49,10 +51,11 @@ exports[`<DeviceItem /> with display name 1`] = `
|
||||
exports[`<DeviceItem /> without display name 1`] = `
|
||||
<div>
|
||||
<div
|
||||
aria-label="deviceId"
|
||||
class="mx_AccessibleButton mx_UserInfo_device mx_UserInfo_device_unverified"
|
||||
data-state="closed"
|
||||
role="button"
|
||||
tabindex="0"
|
||||
title="deviceId"
|
||||
>
|
||||
<div
|
||||
class="mx_E2EIcon mx_E2EIcon_normal"
|
||||
@@ -78,11 +81,12 @@ exports[`<UserInfo /> with crypto enabled renders <BasicUserInfo /> 1`] = `
|
||||
class="mx_BaseCard_header"
|
||||
>
|
||||
<div
|
||||
aria-label="Close"
|
||||
class="mx_AccessibleButton mx_BaseCard_close"
|
||||
data-state="closed"
|
||||
data-testid="base-card-close-button"
|
||||
role="button"
|
||||
tabindex="0"
|
||||
title="Close"
|
||||
/>
|
||||
<div
|
||||
class="mx_BaseCard_headerProp"
|
||||
|
@@ -11,6 +11,7 @@ exports[`EventTileThreadToolbar renders 1`] = `
|
||||
<div
|
||||
aria-label="View in room"
|
||||
class="mx_AccessibleButton mx_MessageActionBar_iconButton"
|
||||
data-state="closed"
|
||||
role="button"
|
||||
tabindex="0"
|
||||
>
|
||||
@@ -19,6 +20,7 @@ exports[`EventTileThreadToolbar renders 1`] = `
|
||||
<div
|
||||
aria-label="Copy link to thread"
|
||||
class="mx_AccessibleButton mx_MessageActionBar_iconButton"
|
||||
data-state="closed"
|
||||
role="button"
|
||||
tabindex="-1"
|
||||
>
|
||||
|
@@ -92,7 +92,7 @@ describe("MemberList", () => {
|
||||
let prevMember: RoomMember | undefined;
|
||||
for (const tile of memberTiles) {
|
||||
const memberA = prevMember;
|
||||
const memberB = memberListRoom.currentState.members[tile.getAttribute("title")!.split(" ")[0]];
|
||||
const memberB = memberListRoom.currentState.members[tile.getAttribute("aria-label")!.split(" ")[0]];
|
||||
prevMember = memberB; // just in case an expect fails, set this early
|
||||
if (!memberA) {
|
||||
continue;
|
||||
|
@@ -4,10 +4,11 @@ exports[`MemberTile should display an verified E2EIcon when the e2E status = Ver
|
||||
<div>
|
||||
<div>
|
||||
<div
|
||||
aria-label="@userId:matrix.org (power 0)"
|
||||
class="mx_AccessibleButton mx_EntityTile mx_EntityTile_offline_neveractive"
|
||||
data-state="closed"
|
||||
role="button"
|
||||
tabindex="0"
|
||||
title="@userId:matrix.org (power 0)"
|
||||
>
|
||||
<div
|
||||
class="mx_EntityTile_avatar"
|
||||
@@ -57,10 +58,11 @@ exports[`MemberTile should display an warning E2EIcon when the e2E status = Warn
|
||||
<div>
|
||||
<div>
|
||||
<div
|
||||
aria-label="@userId:matrix.org (power 0)"
|
||||
class="mx_AccessibleButton mx_EntityTile mx_EntityTile_offline_neveractive"
|
||||
data-state="closed"
|
||||
role="button"
|
||||
tabindex="0"
|
||||
title="@userId:matrix.org (power 0)"
|
||||
>
|
||||
<div
|
||||
class="mx_EntityTile_avatar"
|
||||
@@ -110,10 +112,11 @@ exports[`MemberTile should not display an E2EIcon when the e2E status = normal 1
|
||||
<div>
|
||||
<div>
|
||||
<div
|
||||
aria-label="@userId:matrix.org (power 0)"
|
||||
class="mx_AccessibleButton mx_EntityTile mx_EntityTile_offline_neveractive"
|
||||
data-state="closed"
|
||||
role="button"
|
||||
tabindex="0"
|
||||
title="@userId:matrix.org (power 0)"
|
||||
>
|
||||
<div
|
||||
class="mx_EntityTile_avatar"
|
||||
|
@@ -20,7 +20,8 @@ import React from "react";
|
||||
import { MSC3906Rendezvous, RendezvousFailureReason } from "matrix-js-sdk/src/rendezvous";
|
||||
import { HTTPError, LoginTokenPostResponse } from "matrix-js-sdk/src/matrix";
|
||||
|
||||
import LoginWithQR, { Click, Mode, Phase } from "../../../../../src/components/views/auth/LoginWithQR";
|
||||
import LoginWithQR from "../../../../../src/components/views/auth/LoginWithQR";
|
||||
import { Click, Mode, Phase } from "../../../../../src/components/views/auth/LoginWithQR-types";
|
||||
import type { MatrixClient } from "matrix-js-sdk/src/matrix";
|
||||
|
||||
jest.mock("matrix-js-sdk/src/rendezvous");
|
||||
|
@@ -19,12 +19,8 @@ import React from "react";
|
||||
import { RendezvousFailureReason } from "matrix-js-sdk/src/rendezvous";
|
||||
|
||||
import LoginWithQRFlow from "../../../../../src/components/views/auth/LoginWithQRFlow";
|
||||
import {
|
||||
Click,
|
||||
Phase,
|
||||
LoginWithQRFailureReason,
|
||||
FailureReason,
|
||||
} from "../../../../../src/components/views/auth/LoginWithQR";
|
||||
import { LoginWithQRFailureReason, FailureReason } from "../../../../../src/components/views/auth/LoginWithQR";
|
||||
import { Click, Phase } from "../../../../../src/components/views/auth/LoginWithQR-types";
|
||||
|
||||
describe("<LoginWithQRFlow />", () => {
|
||||
const onClick = jest.fn();
|
||||
|
@@ -139,7 +139,9 @@ exports[`<CurrentDeviceSection /> handles when device is falsy 1`] = `
|
||||
aria-disabled="true"
|
||||
aria-expanded="false"
|
||||
aria-haspopup="true"
|
||||
aria-label="Options"
|
||||
class="mx_AccessibleButton mx_AccessibleButton_disabled"
|
||||
data-state="closed"
|
||||
data-testid="current-session-menu"
|
||||
disabled=""
|
||||
role="button"
|
||||
@@ -174,7 +176,9 @@ exports[`<CurrentDeviceSection /> renders device and correct security card when
|
||||
<div
|
||||
aria-expanded="false"
|
||||
aria-haspopup="true"
|
||||
aria-label="Options"
|
||||
class="mx_AccessibleButton"
|
||||
data-state="closed"
|
||||
data-testid="current-session-menu"
|
||||
role="button"
|
||||
tabindex="0"
|
||||
@@ -317,7 +321,9 @@ exports[`<CurrentDeviceSection /> renders device and correct security card when
|
||||
<div
|
||||
aria-expanded="false"
|
||||
aria-haspopup="true"
|
||||
aria-label="Options"
|
||||
class="mx_AccessibleButton"
|
||||
data-state="closed"
|
||||
data-testid="current-session-menu"
|
||||
role="button"
|
||||
tabindex="0"
|
||||
|
@@ -3,19 +3,28 @@
|
||||
exports[`<LoginWithQRFlow /> errors renders data_mismatch 1`] = `
|
||||
<div>
|
||||
<div
|
||||
class="mx_LoginWithQR"
|
||||
class="mx_LoginWithQR mx_LoginWithQR_error"
|
||||
data-testid="login-with-qr"
|
||||
>
|
||||
<div
|
||||
class="mx_LoginWithQR_centreTitle"
|
||||
/>
|
||||
<div
|
||||
class="mx_LoginWithQR_main"
|
||||
>
|
||||
<div
|
||||
class="mx_LoginWithQR_icon mx_LoginWithQR_icon--critical"
|
||||
>
|
||||
<div
|
||||
width="32px"
|
||||
/>
|
||||
</div>
|
||||
<h1
|
||||
class="_typography_yh5dq_162 _font-heading-sm-semibold_yh5dq_102"
|
||||
>
|
||||
Something went wrong!
|
||||
</h1>
|
||||
<p
|
||||
data-testid="cancellation-message"
|
||||
>
|
||||
The request was cancelled.
|
||||
An unexpected error occurred. The request to connect your other device has been cancelled.
|
||||
</p>
|
||||
</div>
|
||||
<div
|
||||
@@ -45,19 +54,28 @@ exports[`<LoginWithQRFlow /> errors renders data_mismatch 1`] = `
|
||||
exports[`<LoginWithQRFlow /> errors renders expired 1`] = `
|
||||
<div>
|
||||
<div
|
||||
class="mx_LoginWithQR"
|
||||
class="mx_LoginWithQR mx_LoginWithQR_error"
|
||||
data-testid="login-with-qr"
|
||||
>
|
||||
<div
|
||||
class="mx_LoginWithQR_centreTitle"
|
||||
/>
|
||||
<div
|
||||
class="mx_LoginWithQR_main"
|
||||
>
|
||||
<div
|
||||
class="mx_LoginWithQR_icon mx_LoginWithQR_icon--critical"
|
||||
>
|
||||
<div
|
||||
width="32px"
|
||||
/>
|
||||
</div>
|
||||
<h1
|
||||
class="_typography_yh5dq_162 _font-heading-sm-semibold_yh5dq_102"
|
||||
>
|
||||
The sign in was not completed in time
|
||||
</h1>
|
||||
<p
|
||||
data-testid="cancellation-message"
|
||||
>
|
||||
The linking wasn't completed in the required time.
|
||||
Sign in expired. Please try again.
|
||||
</p>
|
||||
</div>
|
||||
<div
|
||||
@@ -87,19 +105,28 @@ exports[`<LoginWithQRFlow /> errors renders expired 1`] = `
|
||||
exports[`<LoginWithQRFlow /> errors renders homeserver_lacks_support 1`] = `
|
||||
<div>
|
||||
<div
|
||||
class="mx_LoginWithQR"
|
||||
class="mx_LoginWithQR mx_LoginWithQR_error"
|
||||
data-testid="login-with-qr"
|
||||
>
|
||||
<div
|
||||
class="mx_LoginWithQR_centreTitle"
|
||||
/>
|
||||
<div
|
||||
class="mx_LoginWithQR_main"
|
||||
>
|
||||
<div
|
||||
class="mx_LoginWithQR_icon mx_LoginWithQR_icon--critical"
|
||||
>
|
||||
<div
|
||||
width="32px"
|
||||
/>
|
||||
</div>
|
||||
<h1
|
||||
class="_typography_yh5dq_162 _font-heading-sm-semibold_yh5dq_102"
|
||||
>
|
||||
Other device not compatible
|
||||
</h1>
|
||||
<p
|
||||
data-testid="cancellation-message"
|
||||
>
|
||||
The homeserver doesn't support signing in another device.
|
||||
This device does not support signing in to the other device with a QR code.
|
||||
</p>
|
||||
</div>
|
||||
<div
|
||||
@@ -129,20 +156,42 @@ exports[`<LoginWithQRFlow /> errors renders homeserver_lacks_support 1`] = `
|
||||
exports[`<LoginWithQRFlow /> errors renders invalid_code 1`] = `
|
||||
<div>
|
||||
<div
|
||||
class="mx_LoginWithQR"
|
||||
class="mx_LoginWithQR mx_LoginWithQR_error"
|
||||
data-testid="login-with-qr"
|
||||
>
|
||||
<div
|
||||
class="mx_LoginWithQR_centreTitle"
|
||||
/>
|
||||
<div
|
||||
class="mx_LoginWithQR_main"
|
||||
>
|
||||
<p
|
||||
<div
|
||||
class="mx_LoginWithQR_icon mx_LoginWithQR_icon--critical"
|
||||
>
|
||||
<div
|
||||
width="32px"
|
||||
/>
|
||||
</div>
|
||||
<h1
|
||||
class="_typography_yh5dq_162 _font-heading-sm-semibold_yh5dq_102"
|
||||
>
|
||||
Connection not secure
|
||||
</h1>
|
||||
A secure connection could not be made to the new device. Your existing devices are still safe and you don't need to worry about them.
|
||||
<h2
|
||||
class="_typography_yh5dq_162 _font-body-lg-semibold_yh5dq_83"
|
||||
data-testid="cancellation-message"
|
||||
>
|
||||
The scanned code is invalid.
|
||||
</p>
|
||||
Now what?
|
||||
</h2>
|
||||
<ol>
|
||||
<li>
|
||||
Try signing in to the other device again with a QR code in case this was a network problem
|
||||
</li>
|
||||
<li>
|
||||
If you encounter the same problem, try a different wifi network or use your mobile data instead of wifi
|
||||
</li>
|
||||
<li>
|
||||
If that doesn't work, sign in manually
|
||||
</li>
|
||||
</ol>
|
||||
</div>
|
||||
<div
|
||||
class="mx_LoginWithQR_buttons"
|
||||
@@ -171,19 +220,28 @@ exports[`<LoginWithQRFlow /> errors renders invalid_code 1`] = `
|
||||
exports[`<LoginWithQRFlow /> errors renders other_device_already_signed_in 1`] = `
|
||||
<div>
|
||||
<div
|
||||
class="mx_LoginWithQR"
|
||||
class="mx_LoginWithQR mx_LoginWithQR_error"
|
||||
data-testid="login-with-qr"
|
||||
>
|
||||
<div
|
||||
class="mx_LoginWithQR_centreTitle"
|
||||
/>
|
||||
<div
|
||||
class="mx_LoginWithQR_main"
|
||||
>
|
||||
<div
|
||||
class="mx_LoginWithQR_icon"
|
||||
>
|
||||
<div
|
||||
width="32px"
|
||||
/>
|
||||
</div>
|
||||
<h1
|
||||
class="_typography_yh5dq_162 _font-heading-sm-semibold_yh5dq_102"
|
||||
>
|
||||
Your other device is already signed in
|
||||
</h1>
|
||||
<p
|
||||
data-testid="cancellation-message"
|
||||
>
|
||||
The other device is already signed in.
|
||||
You don’t need to do anything else.
|
||||
</p>
|
||||
</div>
|
||||
<div
|
||||
@@ -213,19 +271,28 @@ exports[`<LoginWithQRFlow /> errors renders other_device_already_signed_in 1`] =
|
||||
exports[`<LoginWithQRFlow /> errors renders other_device_not_signed_in 1`] = `
|
||||
<div>
|
||||
<div
|
||||
class="mx_LoginWithQR"
|
||||
class="mx_LoginWithQR mx_LoginWithQR_error"
|
||||
data-testid="login-with-qr"
|
||||
>
|
||||
<div
|
||||
class="mx_LoginWithQR_centreTitle"
|
||||
/>
|
||||
<div
|
||||
class="mx_LoginWithQR_main"
|
||||
>
|
||||
<div
|
||||
class="mx_LoginWithQR_icon mx_LoginWithQR_icon--critical"
|
||||
>
|
||||
<div
|
||||
width="32px"
|
||||
/>
|
||||
</div>
|
||||
<h1
|
||||
class="_typography_yh5dq_162 _font-heading-sm-semibold_yh5dq_102"
|
||||
>
|
||||
Something went wrong!
|
||||
</h1>
|
||||
<p
|
||||
data-testid="cancellation-message"
|
||||
>
|
||||
The other device isn't signed in.
|
||||
An unexpected error occurred. The request to connect your other device has been cancelled.
|
||||
</p>
|
||||
</div>
|
||||
<div
|
||||
@@ -255,15 +322,24 @@ exports[`<LoginWithQRFlow /> errors renders other_device_not_signed_in 1`] = `
|
||||
exports[`<LoginWithQRFlow /> errors renders rate_limited 1`] = `
|
||||
<div>
|
||||
<div
|
||||
class="mx_LoginWithQR"
|
||||
class="mx_LoginWithQR mx_LoginWithQR_error"
|
||||
data-testid="login-with-qr"
|
||||
>
|
||||
<div
|
||||
class="mx_LoginWithQR_centreTitle"
|
||||
/>
|
||||
<div
|
||||
class="mx_LoginWithQR_main"
|
||||
>
|
||||
<div
|
||||
class="mx_LoginWithQR_icon mx_LoginWithQR_icon--critical"
|
||||
>
|
||||
<div
|
||||
width="32px"
|
||||
/>
|
||||
</div>
|
||||
<h1
|
||||
class="_typography_yh5dq_162 _font-heading-sm-semibold_yh5dq_102"
|
||||
>
|
||||
Something went wrong!
|
||||
</h1>
|
||||
<p
|
||||
data-testid="cancellation-message"
|
||||
>
|
||||
@@ -297,19 +373,28 @@ exports[`<LoginWithQRFlow /> errors renders rate_limited 1`] = `
|
||||
exports[`<LoginWithQRFlow /> errors renders unknown 1`] = `
|
||||
<div>
|
||||
<div
|
||||
class="mx_LoginWithQR"
|
||||
class="mx_LoginWithQR mx_LoginWithQR_error"
|
||||
data-testid="login-with-qr"
|
||||
>
|
||||
<div
|
||||
class="mx_LoginWithQR_centreTitle"
|
||||
/>
|
||||
<div
|
||||
class="mx_LoginWithQR_main"
|
||||
>
|
||||
<div
|
||||
class="mx_LoginWithQR_icon mx_LoginWithQR_icon--critical"
|
||||
>
|
||||
<div
|
||||
width="32px"
|
||||
/>
|
||||
</div>
|
||||
<h1
|
||||
class="_typography_yh5dq_162 _font-heading-sm-semibold_yh5dq_102"
|
||||
>
|
||||
Something went wrong!
|
||||
</h1>
|
||||
<p
|
||||
data-testid="cancellation-message"
|
||||
>
|
||||
An unexpected error occurred.
|
||||
An unexpected error occurred. The request to connect your other device has been cancelled.
|
||||
</p>
|
||||
</div>
|
||||
<div
|
||||
@@ -339,19 +424,28 @@ exports[`<LoginWithQRFlow /> errors renders unknown 1`] = `
|
||||
exports[`<LoginWithQRFlow /> errors renders unsupported_algorithm 1`] = `
|
||||
<div>
|
||||
<div
|
||||
class="mx_LoginWithQR"
|
||||
class="mx_LoginWithQR mx_LoginWithQR_error"
|
||||
data-testid="login-with-qr"
|
||||
>
|
||||
<div
|
||||
class="mx_LoginWithQR_centreTitle"
|
||||
/>
|
||||
<div
|
||||
class="mx_LoginWithQR_main"
|
||||
>
|
||||
<div
|
||||
class="mx_LoginWithQR_icon mx_LoginWithQR_icon--critical"
|
||||
>
|
||||
<div
|
||||
width="32px"
|
||||
/>
|
||||
</div>
|
||||
<h1
|
||||
class="_typography_yh5dq_162 _font-heading-sm-semibold_yh5dq_102"
|
||||
>
|
||||
Other device not compatible
|
||||
</h1>
|
||||
<p
|
||||
data-testid="cancellation-message"
|
||||
>
|
||||
Linking with this device is not supported.
|
||||
This device does not support signing in to the other device with a QR code.
|
||||
</p>
|
||||
</div>
|
||||
<div
|
||||
@@ -381,19 +475,28 @@ exports[`<LoginWithQRFlow /> errors renders unsupported_algorithm 1`] = `
|
||||
exports[`<LoginWithQRFlow /> errors renders unsupported_transport 1`] = `
|
||||
<div>
|
||||
<div
|
||||
class="mx_LoginWithQR"
|
||||
class="mx_LoginWithQR mx_LoginWithQR_error"
|
||||
data-testid="login-with-qr"
|
||||
>
|
||||
<div
|
||||
class="mx_LoginWithQR_centreTitle"
|
||||
/>
|
||||
<div
|
||||
class="mx_LoginWithQR_main"
|
||||
>
|
||||
<div
|
||||
class="mx_LoginWithQR_icon mx_LoginWithQR_icon--critical"
|
||||
>
|
||||
<div
|
||||
width="32px"
|
||||
/>
|
||||
</div>
|
||||
<h1
|
||||
class="_typography_yh5dq_162 _font-heading-sm-semibold_yh5dq_102"
|
||||
>
|
||||
Other device not compatible
|
||||
</h1>
|
||||
<p
|
||||
data-testid="cancellation-message"
|
||||
>
|
||||
The request was cancelled.
|
||||
This device does not support signing in to the other device with a QR code.
|
||||
</p>
|
||||
</div>
|
||||
<div
|
||||
@@ -423,19 +526,28 @@ exports[`<LoginWithQRFlow /> errors renders unsupported_transport 1`] = `
|
||||
exports[`<LoginWithQRFlow /> errors renders user_cancelled 1`] = `
|
||||
<div>
|
||||
<div
|
||||
class="mx_LoginWithQR"
|
||||
class="mx_LoginWithQR mx_LoginWithQR_error"
|
||||
data-testid="login-with-qr"
|
||||
>
|
||||
<div
|
||||
class="mx_LoginWithQR_centreTitle"
|
||||
/>
|
||||
<div
|
||||
class="mx_LoginWithQR_main"
|
||||
>
|
||||
<div
|
||||
class="mx_LoginWithQR_icon mx_LoginWithQR_icon--critical"
|
||||
>
|
||||
<div
|
||||
width="32px"
|
||||
/>
|
||||
</div>
|
||||
<h1
|
||||
class="_typography_yh5dq_162 _font-heading-sm-semibold_yh5dq_102"
|
||||
>
|
||||
Sign in request cancelled
|
||||
</h1>
|
||||
<p
|
||||
data-testid="cancellation-message"
|
||||
>
|
||||
The request was cancelled.
|
||||
The sign in was cancelled on the other device.
|
||||
</p>
|
||||
</div>
|
||||
<div
|
||||
@@ -465,19 +577,28 @@ exports[`<LoginWithQRFlow /> errors renders user_cancelled 1`] = `
|
||||
exports[`<LoginWithQRFlow /> errors renders user_declined 1`] = `
|
||||
<div>
|
||||
<div
|
||||
class="mx_LoginWithQR"
|
||||
class="mx_LoginWithQR mx_LoginWithQR_error"
|
||||
data-testid="login-with-qr"
|
||||
>
|
||||
<div
|
||||
class="mx_LoginWithQR_centreTitle"
|
||||
/>
|
||||
<div
|
||||
class="mx_LoginWithQR_main"
|
||||
>
|
||||
<div
|
||||
class="mx_LoginWithQR_icon mx_LoginWithQR_icon--critical"
|
||||
>
|
||||
<div
|
||||
width="32px"
|
||||
/>
|
||||
</div>
|
||||
<h1
|
||||
class="_typography_yh5dq_162 _font-heading-sm-semibold_yh5dq_102"
|
||||
>
|
||||
Sign in declined
|
||||
</h1>
|
||||
<p
|
||||
data-testid="cancellation-message"
|
||||
>
|
||||
The request was declined on the other device.
|
||||
You declined the request from your other device to sign in.
|
||||
</p>
|
||||
</div>
|
||||
<div
|
||||
@@ -511,33 +632,32 @@ exports[`<LoginWithQRFlow /> renders QR code 1`] = `
|
||||
data-testid="login-with-qr"
|
||||
>
|
||||
<div
|
||||
class=""
|
||||
class="mx_LoginWithQR_heading"
|
||||
>
|
||||
<div
|
||||
class="mx_LoginWithQR_heading"
|
||||
aria-label="Back"
|
||||
class="mx_AccessibleButton mx_LoginWithQR_BackButton"
|
||||
data-state="closed"
|
||||
data-testid="back-button"
|
||||
role="button"
|
||||
tabindex="0"
|
||||
>
|
||||
<div
|
||||
class="mx_AccessibleButton mx_LoginWithQR_BackButton"
|
||||
data-testid="back-button"
|
||||
role="button"
|
||||
tabindex="0"
|
||||
title="Back"
|
||||
>
|
||||
<div />
|
||||
</div>
|
||||
<div
|
||||
class="mx_LoginWithQR_breadcrumbs"
|
||||
>
|
||||
Sessions
|
||||
/
|
||||
Link new device
|
||||
</div>
|
||||
<div />
|
||||
</div>
|
||||
<div
|
||||
class="mx_LoginWithQR_breadcrumbs"
|
||||
>
|
||||
Sessions
|
||||
/
|
||||
Link new device
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
class="mx_LoginWithQR_main"
|
||||
>
|
||||
<h1>
|
||||
<h1
|
||||
class="_typography_yh5dq_162 _font-heading-sm-semibold_yh5dq_102"
|
||||
>
|
||||
Scan the QR code with another device
|
||||
</h1>
|
||||
<div
|
||||
@@ -561,7 +681,7 @@ exports[`<LoginWithQRFlow /> renders QR code 1`] = `
|
||||
<span>
|
||||
Select "
|
||||
<b>
|
||||
Scan QR code
|
||||
Sign in with QR code
|
||||
</b>
|
||||
"
|
||||
</span>
|
||||
@@ -570,7 +690,7 @@ exports[`<LoginWithQRFlow /> renders QR code 1`] = `
|
||||
Point the camera at the QR code shown here
|
||||
</li>
|
||||
<li>
|
||||
Follow the remaining instructions to verify your other device
|
||||
Follow the instructions to link your other device
|
||||
</li>
|
||||
</ol>
|
||||
</div>
|
||||
@@ -587,9 +707,6 @@ exports[`<LoginWithQRFlow /> renders code when connected 1`] = `
|
||||
class="mx_LoginWithQR"
|
||||
data-testid="login-with-qr"
|
||||
>
|
||||
<div
|
||||
class=""
|
||||
/>
|
||||
<div
|
||||
class="mx_LoginWithQR_main"
|
||||
>
|
||||
@@ -615,14 +732,6 @@ exports[`<LoginWithQRFlow /> renders code when connected 1`] = `
|
||||
<div
|
||||
class="mx_LoginWithQR_buttons"
|
||||
>
|
||||
<div
|
||||
class="mx_AccessibleButton mx_AccessibleButton_hasKind mx_AccessibleButton_kind_primary_outline"
|
||||
data-testid="decline-login-button"
|
||||
role="button"
|
||||
tabindex="0"
|
||||
>
|
||||
Cancel
|
||||
</div>
|
||||
<div
|
||||
class="mx_AccessibleButton mx_AccessibleButton_hasKind mx_AccessibleButton_kind_primary"
|
||||
data-testid="approve-login-button"
|
||||
@@ -631,6 +740,14 @@ exports[`<LoginWithQRFlow /> renders code when connected 1`] = `
|
||||
>
|
||||
Approve
|
||||
</div>
|
||||
<div
|
||||
class="mx_AccessibleButton mx_AccessibleButton_hasKind mx_AccessibleButton_kind_primary_outline"
|
||||
data-testid="decline-login-button"
|
||||
role="button"
|
||||
tabindex="0"
|
||||
>
|
||||
Cancel
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -643,27 +760,24 @@ exports[`<LoginWithQRFlow /> renders spinner while connecting 1`] = `
|
||||
data-testid="login-with-qr"
|
||||
>
|
||||
<div
|
||||
class=""
|
||||
class="mx_LoginWithQR_heading"
|
||||
>
|
||||
<div
|
||||
class="mx_LoginWithQR_heading"
|
||||
aria-label="Back"
|
||||
class="mx_AccessibleButton mx_LoginWithQR_BackButton"
|
||||
data-state="closed"
|
||||
data-testid="back-button"
|
||||
role="button"
|
||||
tabindex="0"
|
||||
>
|
||||
<div
|
||||
class="mx_AccessibleButton mx_LoginWithQR_BackButton"
|
||||
data-testid="back-button"
|
||||
role="button"
|
||||
tabindex="0"
|
||||
title="Back"
|
||||
>
|
||||
<div />
|
||||
</div>
|
||||
<div
|
||||
class="mx_LoginWithQR_breadcrumbs"
|
||||
>
|
||||
Sessions
|
||||
/
|
||||
Link new device
|
||||
</div>
|
||||
<div />
|
||||
</div>
|
||||
<div
|
||||
class="mx_LoginWithQR_breadcrumbs"
|
||||
>
|
||||
Sessions
|
||||
/
|
||||
Link new device
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
@@ -713,27 +827,24 @@ exports[`<LoginWithQRFlow /> renders spinner while loading 1`] = `
|
||||
data-testid="login-with-qr"
|
||||
>
|
||||
<div
|
||||
class=""
|
||||
class="mx_LoginWithQR_heading"
|
||||
>
|
||||
<div
|
||||
class="mx_LoginWithQR_heading"
|
||||
aria-label="Back"
|
||||
class="mx_AccessibleButton mx_LoginWithQR_BackButton"
|
||||
data-state="closed"
|
||||
data-testid="back-button"
|
||||
role="button"
|
||||
tabindex="0"
|
||||
>
|
||||
<div
|
||||
class="mx_AccessibleButton mx_LoginWithQR_BackButton"
|
||||
data-testid="back-button"
|
||||
role="button"
|
||||
tabindex="0"
|
||||
title="Back"
|
||||
>
|
||||
<div />
|
||||
</div>
|
||||
<div
|
||||
class="mx_LoginWithQR_breadcrumbs"
|
||||
>
|
||||
Sessions
|
||||
/
|
||||
Link new device
|
||||
</div>
|
||||
<div />
|
||||
</div>
|
||||
<div
|
||||
class="mx_LoginWithQR_breadcrumbs"
|
||||
>
|
||||
Sessions
|
||||
/
|
||||
Link new device
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
@@ -771,27 +882,24 @@ exports[`<LoginWithQRFlow /> renders spinner while signing in 1`] = `
|
||||
data-testid="login-with-qr"
|
||||
>
|
||||
<div
|
||||
class=""
|
||||
class="mx_LoginWithQR_heading"
|
||||
>
|
||||
<div
|
||||
class="mx_LoginWithQR_heading"
|
||||
aria-label="Back"
|
||||
class="mx_AccessibleButton mx_LoginWithQR_BackButton"
|
||||
data-state="closed"
|
||||
data-testid="back-button"
|
||||
role="button"
|
||||
tabindex="0"
|
||||
>
|
||||
<div
|
||||
class="mx_AccessibleButton mx_LoginWithQR_BackButton"
|
||||
data-testid="back-button"
|
||||
role="button"
|
||||
tabindex="0"
|
||||
title="Back"
|
||||
>
|
||||
<div />
|
||||
</div>
|
||||
<div
|
||||
class="mx_LoginWithQR_breadcrumbs"
|
||||
>
|
||||
Sessions
|
||||
/
|
||||
Link new device
|
||||
</div>
|
||||
<div />
|
||||
</div>
|
||||
<div
|
||||
class="mx_LoginWithQR_breadcrumbs"
|
||||
>
|
||||
Sessions
|
||||
/
|
||||
Link new device
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
@@ -841,27 +949,24 @@ exports[`<LoginWithQRFlow /> renders spinner while verifying 1`] = `
|
||||
data-testid="login-with-qr"
|
||||
>
|
||||
<div
|
||||
class="mx_LoginWithQR_centreTitle"
|
||||
class="mx_LoginWithQR_heading"
|
||||
>
|
||||
<div
|
||||
class="mx_LoginWithQR_heading"
|
||||
aria-label="Back"
|
||||
class="mx_AccessibleButton mx_LoginWithQR_BackButton"
|
||||
data-state="closed"
|
||||
data-testid="back-button"
|
||||
role="button"
|
||||
tabindex="0"
|
||||
>
|
||||
<div
|
||||
class="mx_AccessibleButton mx_LoginWithQR_BackButton"
|
||||
data-testid="back-button"
|
||||
role="button"
|
||||
tabindex="0"
|
||||
title="Back"
|
||||
>
|
||||
<div />
|
||||
</div>
|
||||
<div
|
||||
class="mx_LoginWithQR_breadcrumbs"
|
||||
>
|
||||
Sessions
|
||||
/
|
||||
Link new device
|
||||
</div>
|
||||
<div />
|
||||
</div>
|
||||
<div
|
||||
class="mx_LoginWithQR_breadcrumbs"
|
||||
>
|
||||
Sessions
|
||||
/
|
||||
Link new device
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
@@ -902,27 +1007,24 @@ exports[`<LoginWithQRFlow /> renders spinner whilst QR generating 1`] = `
|
||||
data-testid="login-with-qr"
|
||||
>
|
||||
<div
|
||||
class=""
|
||||
class="mx_LoginWithQR_heading"
|
||||
>
|
||||
<div
|
||||
class="mx_LoginWithQR_heading"
|
||||
aria-label="Back"
|
||||
class="mx_AccessibleButton mx_LoginWithQR_BackButton"
|
||||
data-state="closed"
|
||||
data-testid="back-button"
|
||||
role="button"
|
||||
tabindex="0"
|
||||
>
|
||||
<div
|
||||
class="mx_AccessibleButton mx_LoginWithQR_BackButton"
|
||||
data-testid="back-button"
|
||||
role="button"
|
||||
tabindex="0"
|
||||
title="Back"
|
||||
>
|
||||
<div />
|
||||
</div>
|
||||
<div
|
||||
class="mx_LoginWithQR_breadcrumbs"
|
||||
>
|
||||
Sessions
|
||||
/
|
||||
Link new device
|
||||
</div>
|
||||
<div />
|
||||
</div>
|
||||
<div
|
||||
class="mx_LoginWithQR_breadcrumbs"
|
||||
>
|
||||
Sessions
|
||||
/
|
||||
Link new device
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
|
@@ -45,6 +45,7 @@ exports[`AdvancedRoomSettingsTab should render as expected 1`] = `
|
||||
<div
|
||||
aria-label="Copy"
|
||||
class="mx_AccessibleButton mx_CopyableText_copyButton"
|
||||
data-state="closed"
|
||||
role="button"
|
||||
tabindex="0"
|
||||
/>
|
||||
|
@@ -68,10 +68,11 @@ exports[`PeopleRoomSettingsTab with requests to join renders requests fully 1`]
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
aria-label="Deny"
|
||||
class="mx_AccessibleButton mx_PeopleRoomSettingsTab_action mx_AccessibleButton_hasKind mx_AccessibleButton_kind_icon_primary_outline"
|
||||
data-state="closed"
|
||||
role="button"
|
||||
tabindex="0"
|
||||
title="Deny"
|
||||
>
|
||||
<div
|
||||
height="18"
|
||||
@@ -79,10 +80,11 @@ exports[`PeopleRoomSettingsTab with requests to join renders requests fully 1`]
|
||||
/>
|
||||
</div>
|
||||
<div
|
||||
aria-label="Approve"
|
||||
class="mx_AccessibleButton mx_PeopleRoomSettingsTab_action mx_AccessibleButton_hasKind mx_AccessibleButton_kind_icon_primary"
|
||||
data-state="closed"
|
||||
role="button"
|
||||
tabindex="0"
|
||||
title="Approve"
|
||||
>
|
||||
<div
|
||||
height="18"
|
||||
@@ -135,10 +137,11 @@ exports[`PeopleRoomSettingsTab with requests to join renders requests reduced 1`
|
||||
</span>
|
||||
</div>
|
||||
<div
|
||||
aria-label="Deny"
|
||||
class="mx_AccessibleButton mx_PeopleRoomSettingsTab_action mx_AccessibleButton_hasKind mx_AccessibleButton_kind_icon_primary_outline"
|
||||
data-state="closed"
|
||||
role="button"
|
||||
tabindex="0"
|
||||
title="Deny"
|
||||
>
|
||||
<div
|
||||
height="18"
|
||||
@@ -146,10 +149,11 @@ exports[`PeopleRoomSettingsTab with requests to join renders requests reduced 1`
|
||||
/>
|
||||
</div>
|
||||
<div
|
||||
aria-label="Approve"
|
||||
class="mx_AccessibleButton mx_PeopleRoomSettingsTab_action mx_AccessibleButton_hasKind mx_AccessibleButton_kind_icon_primary"
|
||||
data-state="closed"
|
||||
role="button"
|
||||
tabindex="0"
|
||||
title="Approve"
|
||||
>
|
||||
<div
|
||||
height="18"
|
||||
|
@@ -15,7 +15,8 @@ limitations under the License.
|
||||
*/
|
||||
|
||||
import React from "react";
|
||||
import { fireEvent, render, screen } from "@testing-library/react";
|
||||
import { render, screen, waitFor } from "@testing-library/react";
|
||||
import userEvent from "@testing-library/user-event";
|
||||
|
||||
import LabsUserSettingsTab from "../../../../../../src/components/views/settings/tabs/user/LabsUserSettingsTab";
|
||||
import SettingsStore from "../../../../../../src/settings/SettingsStore";
|
||||
@@ -60,7 +61,7 @@ describe("<LabsUserSettingsTab />", () => {
|
||||
// non-beta labs section
|
||||
expect(screen.getByText("Early previews")).toBeInTheDocument();
|
||||
const labsSections = container.getElementsByClassName("mx_SettingsSubsection");
|
||||
expect(labsSections).toHaveLength(11);
|
||||
expect(labsSections).toHaveLength(10);
|
||||
});
|
||||
|
||||
describe("Rust crypto setting", () => {
|
||||
@@ -113,12 +114,14 @@ describe("<LabsUserSettingsTab />", () => {
|
||||
expect(toggle.getAttribute("aria-checked")).toEqual("true");
|
||||
|
||||
// Hover over the toggle to make it show the tooltip
|
||||
fireEvent.mouseOver(toggle);
|
||||
await userEvent.hover(toggle);
|
||||
|
||||
const tooltip = rendered.getByRole("tooltip");
|
||||
expect(tooltip).toHaveTextContent(
|
||||
"Once enabled, Rust cryptography can only be disabled by logging out and in again",
|
||||
);
|
||||
await waitFor(() => {
|
||||
const tooltip = screen.getByRole("tooltip");
|
||||
expect(tooltip).toHaveTextContent(
|
||||
"Once enabled, Rust cryptography can only be disabled by logging out and in again",
|
||||
);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -150,12 +153,14 @@ describe("<LabsUserSettingsTab />", () => {
|
||||
expect(toggle.getAttribute("aria-checked")).toEqual("true");
|
||||
|
||||
// Hover over the toggle to make it show the tooltip
|
||||
fireEvent.mouseOver(toggle);
|
||||
await userEvent.hover(toggle);
|
||||
|
||||
const tooltip = rendered.getByRole("tooltip");
|
||||
expect(tooltip).toHaveTextContent(
|
||||
"Rust cryptography cannot be disabled on this deployment of BrandedClient",
|
||||
);
|
||||
await waitFor(() => {
|
||||
const tooltip = rendered.getByRole("tooltip");
|
||||
expect(tooltip).toHaveTextContent(
|
||||
"Rust cryptography cannot be disabled on this deployment of BrandedClient",
|
||||
);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
@@ -289,6 +289,7 @@ exports[`PreferencesUserSettingsTab should render 1`] = `
|
||||
aria-disabled="true"
|
||||
aria-label="Send read receipts"
|
||||
class="mx_AccessibleButton mx_ToggleSwitch mx_ToggleSwitch_on"
|
||||
data-state="closed"
|
||||
id="mx_SettingsFlag_GQvdMWe954DV"
|
||||
role="switch"
|
||||
tabindex="0"
|
||||
|
@@ -84,7 +84,9 @@ exports[`<SessionManagerTab /> current session section renders current session s
|
||||
<div
|
||||
aria-expanded="false"
|
||||
aria-haspopup="true"
|
||||
aria-label="Options"
|
||||
class="mx_AccessibleButton"
|
||||
data-state="closed"
|
||||
data-testid="current-session-menu"
|
||||
role="button"
|
||||
tabindex="0"
|
||||
@@ -213,7 +215,9 @@ exports[`<SessionManagerTab /> current session section renders current session s
|
||||
<div
|
||||
aria-expanded="false"
|
||||
aria-haspopup="true"
|
||||
aria-label="Options"
|
||||
class="mx_AccessibleButton"
|
||||
data-state="closed"
|
||||
data-testid="current-session-menu"
|
||||
role="button"
|
||||
tabindex="0"
|
||||
|
@@ -16,7 +16,6 @@ exports[`<SpacePanel /> should show all activated MetaSpaces in the correct orde
|
||||
class="mx_AccessibleButton mx_UserMenu_contextMenuButton"
|
||||
role="button"
|
||||
tabindex="0"
|
||||
title="User menu"
|
||||
>
|
||||
<div
|
||||
class="mx_UserMenu_userAvatar"
|
||||
@@ -226,6 +225,48 @@ exports[`<SpacePanel /> should show all activated MetaSpaces in the correct orde
|
||||
</div>
|
||||
</li>
|
||||
</ul>
|
||||
<div
|
||||
class="mx_ThreadsActivityCentre_container"
|
||||
>
|
||||
<button
|
||||
aria-controls="floating-ui-7"
|
||||
aria-expanded="true"
|
||||
aria-haspopup="dialog"
|
||||
aria-label="Threads"
|
||||
class="_icon-button_16nk7_17 mx_ThreadsActivityCentreButton"
|
||||
data-state="closed"
|
||||
role="button"
|
||||
style="--cpd-icon-button-size: 32px;"
|
||||
tabindex="0"
|
||||
>
|
||||
<div
|
||||
class="_indicator-icon_133tf_26"
|
||||
style="--cpd-icon-button-size: 100%;"
|
||||
>
|
||||
<div
|
||||
class="mx_ThreadsActivityCentreButton_Icon"
|
||||
/>
|
||||
</div>
|
||||
</button>
|
||||
<span
|
||||
data-floating-ui-focus-guard=""
|
||||
data-type="outside"
|
||||
role="button"
|
||||
style="border: 0px; height: 1px; margin: -1px; overflow: hidden; padding: 0px; position: fixed; white-space: nowrap; width: 1px; top: 0px; left: 0px;"
|
||||
tabindex="0"
|
||||
/>
|
||||
<span
|
||||
aria-owns="undefined"
|
||||
style="border: 0px; height: 1px; margin: -1px; overflow: hidden; padding: 0px; position: fixed; white-space: nowrap; width: 1px; top: 0px; left: 0px;"
|
||||
/>
|
||||
<span
|
||||
data-floating-ui-focus-guard=""
|
||||
data-type="outside"
|
||||
role="button"
|
||||
style="border: 0px; height: 1px; margin: -1px; overflow: hidden; padding: 0px; position: fixed; white-space: nowrap; width: 1px; top: 0px; left: 0px;"
|
||||
tabindex="0"
|
||||
/>
|
||||
</div>
|
||||
<div
|
||||
aria-expanded="false"
|
||||
aria-label="Quick settings"
|
||||
|
35
test/settings/controllers/AnalyticsController-test.ts
Normal file
35
test/settings/controllers/AnalyticsController-test.ts
Normal file
@@ -0,0 +1,35 @@
|
||||
/*
|
||||
Copyright 2024 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 PosthogTrackers from "../../../src/PosthogTrackers";
|
||||
import AnalyticsController from "../../../src/settings/controllers/AnalyticsController";
|
||||
import { SettingLevel } from "../../../src/settings/SettingLevel";
|
||||
|
||||
describe("AnalyticsController", () => {
|
||||
afterEach(() => {
|
||||
jest.restoreAllMocks();
|
||||
});
|
||||
|
||||
it("Tracks a Posthog interaction on change", () => {
|
||||
const trackInteractionSpy = jest.spyOn(PosthogTrackers, "trackInteraction");
|
||||
|
||||
const controller = new AnalyticsController("WebSettingsNotificationsTACOnlyNotificationsToggle");
|
||||
|
||||
controller.onChange(SettingLevel.DEVICE, null, false);
|
||||
|
||||
expect(trackInteractionSpy).toHaveBeenCalledWith("WebSettingsNotificationsTACOnlyNotificationsToggle");
|
||||
});
|
||||
});
|
@@ -15,7 +15,16 @@ limitations under the License.
|
||||
*/
|
||||
|
||||
import { Mocked, mocked } from "jest-mock";
|
||||
import { EventTimeline, EventType, MatrixClient, MatrixEvent, RelationType, Room } from "matrix-js-sdk/src/matrix";
|
||||
import {
|
||||
EventStatus,
|
||||
EventTimeline,
|
||||
EventType,
|
||||
MatrixClient,
|
||||
MatrixEvent,
|
||||
PendingEventOrdering,
|
||||
RelationType,
|
||||
Room,
|
||||
} from "matrix-js-sdk/src/matrix";
|
||||
|
||||
import { MessagePreviewStore } from "../../../src/stores/room-list/MessagePreviewStore";
|
||||
import { mkEvent, mkMessage, mkReaction, setupAsyncStoreWithClient, stubClient } from "../../test-utils";
|
||||
@@ -25,6 +34,7 @@ import { mkThread } from "../../test-utils/threads";
|
||||
describe("MessagePreviewStore", () => {
|
||||
let client: Mocked<MatrixClient>;
|
||||
let room: Room;
|
||||
let nonRenderedRoom: Room;
|
||||
let store: MessagePreviewStore;
|
||||
|
||||
async function addEvent(
|
||||
@@ -46,9 +56,35 @@ describe("MessagePreviewStore", () => {
|
||||
}
|
||||
}
|
||||
|
||||
async function addPendingEvent(
|
||||
store: MessagePreviewStore,
|
||||
room: Room,
|
||||
event: MatrixEvent,
|
||||
fireAction = true,
|
||||
): Promise<void> {
|
||||
room.addPendingEvent(event, "txid");
|
||||
if (fireAction) {
|
||||
// @ts-ignore private access
|
||||
await store.onLocalEchoUpdated(event, room);
|
||||
}
|
||||
}
|
||||
|
||||
async function updatePendingEvent(event: MatrixEvent, eventStatus: EventStatus, fireAction = true): Promise<void> {
|
||||
room.updatePendingEvent(event, eventStatus);
|
||||
if (fireAction) {
|
||||
// @ts-ignore private access
|
||||
await store.onLocalEchoUpdated(event, room);
|
||||
}
|
||||
}
|
||||
|
||||
beforeEach(async () => {
|
||||
client = mocked(stubClient());
|
||||
room = new Room("!roomId:server", client, client.getSafeUserId());
|
||||
room = new Room("!roomId:server", client, client.getSafeUserId(), {
|
||||
pendingEventOrdering: PendingEventOrdering.Detached,
|
||||
});
|
||||
nonRenderedRoom = new Room("!roomId2:server", client, client.getSafeUserId(), {
|
||||
pendingEventOrdering: PendingEventOrdering.Detached,
|
||||
});
|
||||
mocked(client.getRoom).mockReturnValue(room);
|
||||
|
||||
store = MessagePreviewStore.testInstance();
|
||||
@@ -286,4 +322,63 @@ describe("MessagePreviewStore", () => {
|
||||
expect(preview?.isThreadReply).toBe(false);
|
||||
expect(preview?.text).toContain("You reacted 🙃 to root event message");
|
||||
});
|
||||
|
||||
it("should handle local echos correctly", async () => {
|
||||
const firstMessage = mkMessage({
|
||||
user: "@sender:server",
|
||||
event: true,
|
||||
room: room.roomId,
|
||||
msg: "First message",
|
||||
});
|
||||
|
||||
await addEvent(store, room, firstMessage);
|
||||
|
||||
expect((await store.getPreviewForRoom(room, DefaultTagID.Untagged))?.text).toMatchInlineSnapshot(
|
||||
`"@sender:server: First message"`,
|
||||
);
|
||||
|
||||
const secondMessage = mkMessage({
|
||||
user: "@sender:server",
|
||||
event: true,
|
||||
room: room.roomId,
|
||||
msg: "Second message",
|
||||
});
|
||||
secondMessage.status = EventStatus.NOT_SENT;
|
||||
|
||||
await addPendingEvent(store, room, secondMessage);
|
||||
|
||||
expect((await store.getPreviewForRoom(room, DefaultTagID.Untagged))?.text).toMatchInlineSnapshot(
|
||||
`"@sender:server: Second message"`,
|
||||
);
|
||||
|
||||
await updatePendingEvent(secondMessage, EventStatus.CANCELLED);
|
||||
|
||||
expect((await store.getPreviewForRoom(room, DefaultTagID.Untagged))?.text).toMatchInlineSnapshot(
|
||||
`"@sender:server: First message"`,
|
||||
);
|
||||
});
|
||||
|
||||
it("should not generate previews for rooms not rendered", async () => {
|
||||
const firstMessage = mkMessage({
|
||||
user: "@sender:server",
|
||||
event: true,
|
||||
room: nonRenderedRoom.roomId,
|
||||
msg: "First message",
|
||||
});
|
||||
|
||||
await addEvent(store, room, firstMessage);
|
||||
|
||||
const secondMessage = mkMessage({
|
||||
user: "@sender:server",
|
||||
event: true,
|
||||
room: nonRenderedRoom.roomId,
|
||||
msg: "Second message",
|
||||
});
|
||||
secondMessage.status = EventStatus.NOT_SENT;
|
||||
|
||||
await addPendingEvent(store, room, secondMessage);
|
||||
|
||||
// @ts-ignore private access
|
||||
expect(store.previews.has(nonRenderedRoom.roomId)).toBeFalsy();
|
||||
});
|
||||
});
|
||||
|
@@ -622,6 +622,7 @@ export function mkStubRoom(
|
||||
getType: jest.fn().mockReturnValue(undefined),
|
||||
getUnfilteredTimelineSet: jest.fn(),
|
||||
getUnreadNotificationCount: jest.fn(() => 0),
|
||||
getRoomUnreadNotificationCount: jest.fn().mockReturnValue(0),
|
||||
getVersion: jest.fn().mockReturnValue("1"),
|
||||
hasMembershipState: () => false,
|
||||
isElementVideoRoom: jest.fn().mockReturnValue(false),
|
||||
|
Reference in New Issue
Block a user