From 8a159bfd32171370beb23cb2480eefe357b06b96 Mon Sep 17 00:00:00 2001 From: David Baker Date: Tue, 18 Jun 2024 12:02:18 +0100 Subject: [PATCH 1/8] Disable profile controls if the HS doesn't allow them to be set Also updates to the js-sdk interface changes in https://github.com/matrix-org/matrix-js-sdk/pull/4246 --- .../views/settings/UserProfileSettings.tsx | 19 +++++++++++++-- .../tabs/user/GeneralUserSettingsTab.tsx | 23 ++++++++++++++++--- .../settings/tabs/user/SessionManagerTab.tsx | 2 +- src/i18n/strings/en_EN.json | 1 + .../settings/UserProfileSettings-test.tsx | 2 +- .../tabs/user/GeneralUserSettingsTab-test.tsx | 10 ++++---- .../tabs/user/SessionManagerTab-test.tsx | 4 ++-- test/test-utils/client.ts | 2 +- 8 files changed, 48 insertions(+), 15 deletions(-) diff --git a/src/components/views/settings/UserProfileSettings.tsx b/src/components/views/settings/UserProfileSettings.tsx index bd61f762ff5..6d1bccb30e9 100644 --- a/src/components/views/settings/UserProfileSettings.tsx +++ b/src/components/views/settings/UserProfileSettings.tsx @@ -55,10 +55,17 @@ const UsernameBox: React.FC = ({ username }) => { ); }; +interface UserProfileSettingsProps { + // Whether the homeserver allows the user to set their display name. + canSetDisplayName: boolean; + // Whether the homeserver allows the user to set their avatar. + canSetAvatar: boolean; +} + /** * A group of settings views to allow the user to set their profile information. */ -const UserProfileSettings: React.FC = () => { +const UserProfileSettings: React.FC = ({ canSetDisplayName, canSetAvatar }) => { const [avatarURL, setAvatarURL] = useState(OwnProfileStore.instance.avatarMxc); const [displayName, setDisplayName] = useState(OwnProfileStore.instance.displayName ?? ""); const [initialDisplayName, setInitialDisplayName] = useState(OwnProfileStore.instance.displayName ?? ""); @@ -143,10 +150,16 @@ const UserProfileSettings: React.FC = () => { [client], ); + const someFieldsDisabled = !canSetDisplayName || !canSetAvatar; + return (

{_t("common|profile")}

-
{_t("settings|general|profile_subtitle")}
+
+ {someFieldsDisabled + ? _t("settings|general|profile_subtitle_oidc") + : _t("settings|general|profile_subtitle")} +
{ removeAvatar={avatarURL ? onAvatarRemove : undefined} placeholderName={displayName} placeholderId={client.getUserId() ?? ""} + disabled={!canSetAvatar} /> { onCancel={onDisplayNameCancel} onSave={onDisplayNameSave} error={displayNameError ? _t("settings|general|display_name_error") : undefined} + disabled={!canSetDisplayName} />
{avatarError && ( diff --git a/src/components/views/settings/tabs/user/GeneralUserSettingsTab.tsx b/src/components/views/settings/tabs/user/GeneralUserSettingsTab.tsx index 0e32b9126c3..3292d8bc11d 100644 --- a/src/components/views/settings/tabs/user/GeneralUserSettingsTab.tsx +++ b/src/components/views/settings/tabs/user/GeneralUserSettingsTab.tsx @@ -90,6 +90,8 @@ interface IState { idServerName?: string; externalAccountManagementUrl?: string; canMake3pidChanges: boolean; + canSetDisplayName: boolean; + canSetAvatar: boolean; } export default class GeneralUserSettingsTab extends React.Component { @@ -122,6 +124,8 @@ export default class GeneralUserSettingsTab extends React.Component { const cli = this.context.client!; - const capabilities = await cli.getCapabilities(); // this is cached + const capabilities = (await cli.getCachedCapabilities()) ?? {}; const changePasswordCap = capabilities["m.change_password"]; // You can change your password so long as the capability isn't explicitly disabled. The implicit @@ -182,7 +186,17 @@ export default class GeneralUserSettingsTab extends React.Component { @@ -561,7 +575,10 @@ export default class GeneralUserSettingsTab extends React.Component - + {this.renderAccountSection()} {this.renderLanguageSection()} {supportsMultiLanguageSpellCheck ? this.renderSpellCheckSection() : null} diff --git a/src/components/views/settings/tabs/user/SessionManagerTab.tsx b/src/components/views/settings/tabs/user/SessionManagerTab.tsx index ee51d0680fb..c733b53f7a0 100644 --- a/src/components/views/settings/tabs/user/SessionManagerTab.tsx +++ b/src/components/views/settings/tabs/user/SessionManagerTab.tsx @@ -189,7 +189,7 @@ const SessionManagerTab: React.FC<{ const userId = matrixClient?.getUserId(); const currentUserMember = (userId && matrixClient?.getUser(userId)) || undefined; const clientVersions = useAsyncMemo(() => matrixClient.getVersions(), [matrixClient]); - const capabilities = useAsyncMemo(async () => matrixClient?.getCapabilities(), [matrixClient]); + const capabilities = matrixClient.getCachedCapabilities(); const wellKnown = useMemo(() => matrixClient?.getClientWellKnown(), [matrixClient]); const oidcClientConfig = useAsyncMemo(async () => { try { diff --git a/src/i18n/strings/en_EN.json b/src/i18n/strings/en_EN.json index 4550cfdad15..85933566251 100644 --- a/src/i18n/strings/en_EN.json +++ b/src/i18n/strings/en_EN.json @@ -2529,6 +2529,7 @@ "password_change_section": "Set a new account password…", "password_change_success": "Your password was successfully changed.", "profile_subtitle": "This is how you appear to others on the app.", + "profile_subtitle_oidc": "Your account is managed separately by an identity provider and so some of your personal information can’t be changed here.", "remove_email_prompt": "Remove %(email)s?", "remove_msisdn_prompt": "Remove %(phone)s?", "spell_check_locale_placeholder": "Choose a locale", diff --git a/test/components/views/settings/UserProfileSettings-test.tsx b/test/components/views/settings/UserProfileSettings-test.tsx index fd727729772..6b7f278e5a2 100644 --- a/test/components/views/settings/UserProfileSettings-test.tsx +++ b/test/components/views/settings/UserProfileSettings-test.tsx @@ -67,7 +67,7 @@ const renderProfileSettings = (toastRack: Partial, client: MatrixClie return render( - + , ); diff --git a/test/components/views/settings/tabs/user/GeneralUserSettingsTab-test.tsx b/test/components/views/settings/tabs/user/GeneralUserSettingsTab-test.tsx index 2532e98c600..57344b10e4f 100644 --- a/test/components/views/settings/tabs/user/GeneralUserSettingsTab-test.tsx +++ b/test/components/views/settings/tabs/user/GeneralUserSettingsTab-test.tsx @@ -40,7 +40,7 @@ describe("", () => { const mockClient = getMockClientWithEventEmitter({ ...mockClientMethodsUser(userId), ...mockClientMethodsServer(), - getCapabilities: jest.fn(), + getCachedCapabilities: jest.fn(), getThreePids: jest.fn(), getIdentityServerUrl: jest.fn(), deleteThreePid: jest.fn(), @@ -63,7 +63,7 @@ describe("", () => { jest.spyOn(SettingsStore, "getValue").mockRestore(); jest.spyOn(logger, "error").mockRestore(); - mockClient.getCapabilities.mockResolvedValue({}); + mockClient.getCachedCapabilities.mockReturnValue({}); mockClient.getThreePids.mockResolvedValue({ threepids: [], }); @@ -198,7 +198,7 @@ describe("", () => { describe("3pids", () => { beforeEach(() => { - mockClient.getCapabilities.mockResolvedValue({ + mockClient.getCachedCapabilities.mockReturnValue({ "m.3pid_changes": { enabled: true, }, @@ -300,7 +300,7 @@ describe("", () => { it("should allow 3pid changes when capabilities does not have 3pid_changes", async () => { // We support as far back as v1.1 which doesn't have m.3pid_changes // so the behaviour for when it is missing has to be assume true - mockClient.getCapabilities.mockResolvedValue({}); + mockClient.getCachedCapabilities.mockReturnValue({}); render(getComponent()); @@ -315,7 +315,7 @@ describe("", () => { describe("when 3pid changes capability is disabled", () => { beforeEach(() => { - mockClient.getCapabilities.mockResolvedValue({ + mockClient.getCachedCapabilities.mockReturnValue({ "m.3pid_changes": { enabled: false, }, diff --git a/test/components/views/settings/tabs/user/SessionManagerTab-test.tsx b/test/components/views/settings/tabs/user/SessionManagerTab-test.tsx index a88c322361c..8ce148ca786 100644 --- a/test/components/views/settings/tabs/user/SessionManagerTab-test.tsx +++ b/test/components/views/settings/tabs/user/SessionManagerTab-test.tsx @@ -1684,7 +1684,7 @@ describe("", () => { "org.matrix.msc3886": true, }, }); - mockClient.getCapabilities.mockResolvedValue({ + mockClient.getCachedCapabilities.mockReturnValue({ [GET_LOGIN_TOKEN_CAPABILITY.name]: { enabled: true, }, @@ -1726,7 +1726,7 @@ describe("", () => { "org.matrix.msc4108": true, }, }); - mockClient.getCapabilities.mockResolvedValue({ + mockClient.getCachedCapabilities.mockReturnValue({ [GET_LOGIN_TOKEN_CAPABILITY.name]: { enabled: true, }, diff --git a/test/test-utils/client.ts b/test/test-utils/client.ts index 00f5aa3f7b8..cf78f9b529e 100644 --- a/test/test-utils/client.ts +++ b/test/test-utils/client.ts @@ -129,7 +129,7 @@ export const mockClientMethodsEvents = () => ({ export const mockClientMethodsServer = (): Partial, unknown>> => ({ getIdentityServerUrl: jest.fn(), getHomeserverUrl: jest.fn(), - getCapabilities: jest.fn().mockReturnValue({}), + getCachedCapabilities: jest.fn().mockReturnValue({}), getClientWellKnown: jest.fn().mockReturnValue({}), waitForClientWellKnown: jest.fn().mockResolvedValue({}), doesServerSupportUnstableFeature: jest.fn().mockResolvedValue(false), From b88c78a8c2fee0da577af383a45a39cfc71f01d3 Mon Sep 17 00:00:00 2001 From: David Baker Date: Wed, 19 Jun 2024 12:58:19 +0100 Subject: [PATCH 2/8] Remove unnecessary await --- .../views/settings/tabs/user/GeneralUserSettingsTab.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/views/settings/tabs/user/GeneralUserSettingsTab.tsx b/src/components/views/settings/tabs/user/GeneralUserSettingsTab.tsx index 3292d8bc11d..8859fd067bb 100644 --- a/src/components/views/settings/tabs/user/GeneralUserSettingsTab.tsx +++ b/src/components/views/settings/tabs/user/GeneralUserSettingsTab.tsx @@ -171,7 +171,7 @@ export default class GeneralUserSettingsTab extends React.Component { const cli = this.context.client!; - const capabilities = (await cli.getCachedCapabilities()) ?? {}; + const capabilities = cli.getCachedCapabilities() ?? {}; const changePasswordCap = capabilities["m.change_password"]; // You can change your password so long as the capability isn't explicitly disabled. The implicit From 28adbf4c55f398dc8ade5f35a4dcdcb76ba3a4e2 Mon Sep 17 00:00:00 2001 From: David Baker Date: Wed, 19 Jun 2024 13:18:50 +0100 Subject: [PATCH 3/8] Pass disabled prop to accessiblebutton in avatarsetting --- src/components/views/settings/AvatarSetting.tsx | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/components/views/settings/AvatarSetting.tsx b/src/components/views/settings/AvatarSetting.tsx index 81f1cd5201c..0e95deed382 100644 --- a/src/components/views/settings/AvatarSetting.tsx +++ b/src/components/views/settings/AvatarSetting.tsx @@ -170,6 +170,7 @@ const AvatarSetting: React.FC = ({ aria-labelledby={disabled ? undefined : a11yId} // Inhibit tab stop as we have explicit upload/remove buttons tabIndex={-1} + disabled={disabled} > @@ -184,6 +185,7 @@ const AvatarSetting: React.FC = ({ onClick={uploadAvatar} // Inhibit tab stop as we have explicit upload/remove buttons tabIndex={-1} + disabled={disabled} /> ); } From 1032539e0641212aea624af97f7bc5c7975b5d7c Mon Sep 17 00:00:00 2001 From: David Baker Date: Wed, 19 Jun 2024 17:36:36 +0100 Subject: [PATCH 4/8] Move the account management button The section it lives in with the server name goes, and the button just lives on its own in the profile section. --- .../views/settings/_UserProfileSettings.pcss | 9 +++++ .../views/settings/UserProfileSettings.tsx | 34 ++++++++++++++++++- .../tabs/user/GeneralUserSettingsTab.tsx | 29 +--------------- src/i18n/strings/en_EN.json | 1 - 4 files changed, 43 insertions(+), 30 deletions(-) diff --git a/res/css/views/settings/_UserProfileSettings.pcss b/res/css/views/settings/_UserProfileSettings.pcss index f9ca149bf78..6c9585c9ea9 100644 --- a/res/css/views/settings/_UserProfileSettings.pcss +++ b/res/css/views/settings/_UserProfileSettings.pcss @@ -46,6 +46,15 @@ limitations under the License. font-size: 15px; font-weight: 500; } + + .mx_UserProfileSettings_profile_buttons { + margin-top: var(--cpd-space-8x); + margin-bottom: var(--cpd-space-8x); + } + + .mx_UserProfileSettings_accountmanageIcon { + margin-right: var(--cpd-space-2x); + } } @media (max-width: 768px) { diff --git a/src/components/views/settings/UserProfileSettings.tsx b/src/components/views/settings/UserProfileSettings.tsx index 6d1bccb30e9..03bf693697b 100644 --- a/src/components/views/settings/UserProfileSettings.tsx +++ b/src/components/views/settings/UserProfileSettings.tsx @@ -17,6 +17,7 @@ limitations under the License. import React, { ChangeEvent, useCallback, useEffect, useMemo, useState } from "react"; import { logger } from "matrix-js-sdk/src/logger"; import { EditInPlace, Alert } from "@vector-im/compound-web"; +import { Icon as PopOutIcon } from "@vector-im/compound-design-tokens/icons/pop-out.svg"; import { _t } from "../../../languageHandler"; import { OwnProfileStore } from "../../../stores/OwnProfileStore"; @@ -29,6 +30,7 @@ import UserIdentifierCustomisations from "../../../customisations/UserIdentifier import { useId } from "../../../utils/useId"; import CopyableText from "../elements/CopyableText"; import { useMatrixClientContext } from "../../../contexts/MatrixClientContext"; +import AccessibleButton from "../elements/AccessibleButton"; const SpinnerToast: React.FC = ({ children }) => ( <> @@ -55,7 +57,28 @@ const UsernameBox: React.FC = ({ username }) => { ); }; +interface ManageAccountButtonProps { + externalAccountManagementUrl: string; +} + +const ManageAccountButton: React.FC = ({ externalAccountManagementUrl }) => ( + + + {_t("settings|general|oidc_manage_button")} + +); + interface UserProfileSettingsProps { + // The URL to redirect the user to in order to manage their account. + externalAccountManagementUrl?: string; // Whether the homeserver allows the user to set their display name. canSetDisplayName: boolean; // Whether the homeserver allows the user to set their avatar. @@ -65,7 +88,11 @@ interface UserProfileSettingsProps { /** * A group of settings views to allow the user to set their profile information. */ -const UserProfileSettings: React.FC = ({ canSetDisplayName, canSetAvatar }) => { +const UserProfileSettings: React.FC = ({ + externalAccountManagementUrl, + canSetDisplayName, + canSetAvatar, +}) => { const [avatarURL, setAvatarURL] = useState(OwnProfileStore.instance.avatarMxc); const [displayName, setDisplayName] = useState(OwnProfileStore.instance.displayName ?? ""); const [initialDisplayName, setInitialDisplayName] = useState(OwnProfileStore.instance.displayName ?? ""); @@ -194,6 +221,11 @@ const UserProfileSettings: React.FC = ({ canSetDisplay )} {userIdentifier && } + {externalAccountManagementUrl && ( +
+ +
+ )}
); }; diff --git a/src/components/views/settings/tabs/user/GeneralUserSettingsTab.tsx b/src/components/views/settings/tabs/user/GeneralUserSettingsTab.tsx index 8859fd067bb..8fdead7784f 100644 --- a/src/components/views/settings/tabs/user/GeneralUserSettingsTab.tsx +++ b/src/components/views/settings/tabs/user/GeneralUserSettingsTab.tsx @@ -396,33 +396,6 @@ export default class GeneralUserSettingsTab extends React.Component - - {_t( - "settings|general|external_account_management", - { hostname }, - { code: (sub) => {sub} }, - )} - - - {_t("settings|general|oidc_manage_button")} - - - ); - } return ( <> - {externalAccountManagement} {passwordChangeSection} {threepidSection} @@ -576,6 +548,7 @@ export default class GeneralUserSettingsTab extends React.Component diff --git a/src/i18n/strings/en_EN.json b/src/i18n/strings/en_EN.json index 85933566251..45453fbb54a 100644 --- a/src/i18n/strings/en_EN.json +++ b/src/i18n/strings/en_EN.json @@ -2514,7 +2514,6 @@ "error_revoke_msisdn_discovery": "Unable to revoke sharing for phone number", "error_share_email_discovery": "Unable to share email address", "error_share_msisdn_discovery": "Unable to share phone number", - "external_account_management": "Your account details are managed separately at %(hostname)s.", "identity_server_no_token": "No identity access token found", "identity_server_not_set": "Identity server not set", "incorrect_msisdn_verification": "Incorrect verification code", From 853fc8d4723d8ea9b5dcb257e9cecdf34d15428b Mon Sep 17 00:00:00 2001 From: David Baker Date: Thu, 20 Jun 2024 11:43:39 +0100 Subject: [PATCH 5/8] Update test --- .../settings/tabs/user/GeneralUserSettingsTab-test.tsx | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/test/components/views/settings/tabs/user/GeneralUserSettingsTab-test.tsx b/test/components/views/settings/tabs/user/GeneralUserSettingsTab-test.tsx index 57344b10e4f..b33432382c3 100644 --- a/test/components/views/settings/tabs/user/GeneralUserSettingsTab-test.tsx +++ b/test/components/views/settings/tabs/user/GeneralUserSettingsTab-test.tsx @@ -92,13 +92,10 @@ describe("", () => { } as unknown as OidcClientStore; jest.spyOn(stores, "oidcClientStore", "get").mockReturnValue(mockOidcClientStore); - const { getByTestId } = render(getComponent()); + render(getComponent()); - // wait for well-known call to settle - await flushPromises(); - - expect(getByTestId("external-account-management-outer").textContent).toMatch(/.*id\.server\.org/); - expect(getByTestId("external-account-management-link").getAttribute("href")).toMatch(accountManagementLink); + const manageAccountLink = await screen.findByRole("button", { name: "Manage account" }); + expect(manageAccountLink.getAttribute("href")).toMatch(accountManagementLink); }); describe("Manage integrations", () => { From 2747c4cf44155b4e40af4423afbeffed9e3886b0 Mon Sep 17 00:00:00 2001 From: David Baker Date: Tue, 2 Jul 2024 11:54:18 +0100 Subject: [PATCH 6/8] Revert bits of previous PR that are no longer wanted because we squash merge so git can no longer make sense of what changes have been applied. --- .../settings/tabs/user/GeneralUserSettingsTab-test.tsx | 6 +++--- .../views/settings/tabs/user/SessionManagerTab-test.tsx | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/test/components/views/settings/tabs/user/GeneralUserSettingsTab-test.tsx b/test/components/views/settings/tabs/user/GeneralUserSettingsTab-test.tsx index b33432382c3..f062bc92a4b 100644 --- a/test/components/views/settings/tabs/user/GeneralUserSettingsTab-test.tsx +++ b/test/components/views/settings/tabs/user/GeneralUserSettingsTab-test.tsx @@ -195,7 +195,7 @@ describe("", () => { describe("3pids", () => { beforeEach(() => { - mockClient.getCachedCapabilities.mockReturnValue({ + mockClient.getCapabilities.mockResolvedValue({ "m.3pid_changes": { enabled: true, }, @@ -297,7 +297,7 @@ describe("", () => { it("should allow 3pid changes when capabilities does not have 3pid_changes", async () => { // We support as far back as v1.1 which doesn't have m.3pid_changes // so the behaviour for when it is missing has to be assume true - mockClient.getCachedCapabilities.mockReturnValue({}); + mockClient.getCapabilities.mockResolvedValue({}); render(getComponent()); @@ -312,7 +312,7 @@ describe("", () => { describe("when 3pid changes capability is disabled", () => { beforeEach(() => { - mockClient.getCachedCapabilities.mockReturnValue({ + mockClient.getCapabilities.mockResolvedValue({ "m.3pid_changes": { enabled: false, }, diff --git a/test/components/views/settings/tabs/user/SessionManagerTab-test.tsx b/test/components/views/settings/tabs/user/SessionManagerTab-test.tsx index 8ce148ca786..a88c322361c 100644 --- a/test/components/views/settings/tabs/user/SessionManagerTab-test.tsx +++ b/test/components/views/settings/tabs/user/SessionManagerTab-test.tsx @@ -1684,7 +1684,7 @@ describe("", () => { "org.matrix.msc3886": true, }, }); - mockClient.getCachedCapabilities.mockReturnValue({ + mockClient.getCapabilities.mockResolvedValue({ [GET_LOGIN_TOKEN_CAPABILITY.name]: { enabled: true, }, @@ -1726,7 +1726,7 @@ describe("", () => { "org.matrix.msc4108": true, }, }); - mockClient.getCachedCapabilities.mockReturnValue({ + mockClient.getCapabilities.mockResolvedValue({ [GET_LOGIN_TOKEN_CAPABILITY.name]: { enabled: true, }, From 7afc8f10ca887bcee1c7c79f3e4fd228d543a7a2 Mon Sep 17 00:00:00 2001 From: David Baker Date: Tue, 2 Jul 2024 12:13:35 +0100 Subject: [PATCH 7/8] More squash-merge fails --- src/components/views/settings/tabs/user/SessionManagerTab.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/views/settings/tabs/user/SessionManagerTab.tsx b/src/components/views/settings/tabs/user/SessionManagerTab.tsx index c733b53f7a0..ee51d0680fb 100644 --- a/src/components/views/settings/tabs/user/SessionManagerTab.tsx +++ b/src/components/views/settings/tabs/user/SessionManagerTab.tsx @@ -189,7 +189,7 @@ const SessionManagerTab: React.FC<{ const userId = matrixClient?.getUserId(); const currentUserMember = (userId && matrixClient?.getUser(userId)) || undefined; const clientVersions = useAsyncMemo(() => matrixClient.getVersions(), [matrixClient]); - const capabilities = matrixClient.getCachedCapabilities(); + const capabilities = useAsyncMemo(async () => matrixClient?.getCapabilities(), [matrixClient]); const wellKnown = useMemo(() => matrixClient?.getClientWellKnown(), [matrixClient]); const oidcClientConfig = useAsyncMemo(async () => { try { From cc0fa7d137c02a7a10df6f693b32c7048277ad59 Mon Sep 17 00:00:00 2001 From: David Baker Date: Tue, 2 Jul 2024 12:16:26 +0100 Subject: [PATCH 8/8] More more squash merge fails --- .../views/settings/tabs/user/GeneralUserSettingsTab-test.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/components/views/settings/tabs/user/GeneralUserSettingsTab-test.tsx b/test/components/views/settings/tabs/user/GeneralUserSettingsTab-test.tsx index f062bc92a4b..17016e0df20 100644 --- a/test/components/views/settings/tabs/user/GeneralUserSettingsTab-test.tsx +++ b/test/components/views/settings/tabs/user/GeneralUserSettingsTab-test.tsx @@ -40,7 +40,7 @@ describe("", () => { const mockClient = getMockClientWithEventEmitter({ ...mockClientMethodsUser(userId), ...mockClientMethodsServer(), - getCachedCapabilities: jest.fn(), + getCapabilities: jest.fn(), getThreePids: jest.fn(), getIdentityServerUrl: jest.fn(), deleteThreePid: jest.fn(), @@ -63,7 +63,7 @@ describe("", () => { jest.spyOn(SettingsStore, "getValue").mockRestore(); jest.spyOn(logger, "error").mockRestore(); - mockClient.getCachedCapabilities.mockReturnValue({}); + mockClient.getCapabilities.mockResolvedValue({}); mockClient.getThreePids.mockResolvedValue({ threepids: [], });