Use semantic headings in user settings - integrations and account deletion (#10837)

* allow testids in settings sections

* use semantic headings in LabsUserSettingsTab

* put back margin var

* use SettingsTab wrapper

* use semantic headings for deactivate acc section

* use semantic heading in manage integratios

* i18n

* explicit cast to boolean

* Update src/components/views/settings/shared/SettingsSubsection.tsx

Co-authored-by: Richard van der Hoff <1389908+richvdh@users.noreply.github.com>

* test manage integration settings

* test deactivate account section display

* remove debug

* fix cypress test

---------

Co-authored-by: Richard van der Hoff <1389908+richvdh@users.noreply.github.com>
This commit is contained in:
Kerry 2023-05-17 19:52:44 +12:00 committed by GitHub
parent c3687489dd
commit 8cd84b0e7b
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
7 changed files with 232 additions and 54 deletions

View file

@ -10,9 +10,11 @@ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
import { render } from "@testing-library/react";
import { fireEvent, render, screen, within } from "@testing-library/react";
import React from "react";
import { M_AUTHENTICATION } from "matrix-js-sdk/src/matrix";
import { logger } from "matrix-js-sdk/src/logger";
import GeneralUserSettingsTab from "../../../../../../src/components/views/settings/tabs/user/GeneralUserSettingsTab";
import MatrixClientContext from "../../../../../../src/contexts/MatrixClientContext";
@ -24,6 +26,8 @@ import {
mockPlatformPeg,
flushPromises,
} from "../../../../../test-utils";
import { UIFeature } from "../../../../../../src/settings/UIFeature";
import { SettingLevel } from "../../../../../../src/settings/SettingLevel";
describe("<GeneralUserSettingsTab />", () => {
const defaultProps = {
@ -49,6 +53,8 @@ describe("<GeneralUserSettingsTab />", () => {
mockPlatformPeg();
jest.clearAllMocks();
clientWellKnownSpy.mockReturnValue({});
jest.spyOn(SettingsStore, "getValue").mockRestore();
jest.spyOn(logger, "error").mockRestore();
});
it("does not show account management link when not available", () => {
@ -74,4 +80,83 @@ describe("<GeneralUserSettingsTab />", () => {
expect(getByTestId("external-account-management-outer").textContent).toMatch(/.*id\.server\.org/);
expect(getByTestId("external-account-management-link").getAttribute("href")).toMatch(accountManagementLink);
});
describe("Manage integrations", () => {
it("should not render manage integrations section when widgets feature is disabled", () => {
jest.spyOn(SettingsStore, "getValue").mockImplementation(
(settingName) => settingName !== UIFeature.Widgets,
);
render(getComponent());
expect(screen.queryByTestId("mx_SetIntegrationManager")).not.toBeInTheDocument();
expect(SettingsStore.getValue).toHaveBeenCalledWith(UIFeature.Widgets);
});
it("should render manage integrations sections", () => {
jest.spyOn(SettingsStore, "getValue").mockImplementation(
(settingName) => settingName === UIFeature.Widgets,
);
render(getComponent());
expect(screen.getByTestId("mx_SetIntegrationManager")).toMatchSnapshot();
});
it("should update integrations provisioning on toggle", () => {
jest.spyOn(SettingsStore, "getValue").mockImplementation(
(settingName) => settingName === UIFeature.Widgets,
);
jest.spyOn(SettingsStore, "setValue").mockResolvedValue(undefined);
render(getComponent());
const integrationSection = screen.getByTestId("mx_SetIntegrationManager");
fireEvent.click(within(integrationSection).getByRole("switch"));
expect(SettingsStore.setValue).toHaveBeenCalledWith(
"integrationProvisioning",
null,
SettingLevel.ACCOUNT,
true,
);
expect(within(integrationSection).getByRole("switch")).toBeChecked();
});
it("handles error when updating setting fails", async () => {
jest.spyOn(SettingsStore, "getValue").mockImplementation(
(settingName) => settingName === UIFeature.Widgets,
);
jest.spyOn(logger, "error").mockImplementation(() => {});
jest.spyOn(SettingsStore, "setValue").mockRejectedValue("oups");
render(getComponent());
const integrationSection = screen.getByTestId("mx_SetIntegrationManager");
fireEvent.click(within(integrationSection).getByRole("switch"));
await flushPromises();
expect(logger.error).toHaveBeenCalledWith("Error changing integration manager provisioning");
expect(logger.error).toHaveBeenCalledWith("oups");
expect(within(integrationSection).getByRole("switch")).not.toBeChecked();
});
});
describe("deactive account", () => {
it("should not render section when account deactivation feature is disabled", () => {
jest.spyOn(SettingsStore, "getValue").mockImplementation(
(settingName) => settingName !== UIFeature.Deactivate,
);
render(getComponent());
expect(screen.queryByText("Deactivate account")).not.toBeInTheDocument();
expect(SettingsStore.getValue).toHaveBeenCalledWith(UIFeature.Deactivate);
});
it("should render section when account deactivation feature is enabled", () => {
jest.spyOn(SettingsStore, "getValue").mockImplementation(
(settingName) => settingName === UIFeature.Deactivate,
);
render(getComponent());
expect(screen.getByText("Deactivate account").parentElement!).toMatchSnapshot();
});
});
});

View file

@ -0,0 +1,106 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`<GeneralUserSettingsTab /> Manage integrations should render manage integrations sections 1`] = `
<label
class="mx_SetIntegrationManager"
data-testid="mx_SetIntegrationManager"
for="toggle_integration"
>
<div
class="mx_SettingsFlag"
>
<div
class="mx_SetIntegrationManager_heading_manager"
>
<h2
class="mx_Heading_h2"
>
Manage integrations
</h2>
<h3
class="mx_Heading_h3"
>
(scalar.vector.im)
</h3>
</div>
<div
aria-checked="false"
aria-disabled="false"
class="mx_AccessibleButton mx_ToggleSwitch mx_ToggleSwitch_enabled"
id="toggle_integration"
role="switch"
tabindex="0"
>
<div
class="mx_ToggleSwitch_ball"
/>
</div>
</div>
<div
class="mx_SettingsSubsection_text"
>
<span>
Use an integration manager
<b>
(scalar.vector.im)
</b>
to manage bots, widgets, and sticker packs.
</span>
</div>
<div
class="mx_SettingsSubsection_text"
>
Integration managers receive configuration data, and can modify widgets, send room invites, and set power levels on your behalf.
</div>
</label>
`;
exports[`<GeneralUserSettingsTab /> deactive account should render section when account deactivation feature is enabled 1`] = `
<div
class="mx_SettingsSection"
>
<h2
class="mx_Heading_h2"
>
Deactivate account
</h2>
<div
class="mx_SettingsSection_subSections"
>
<div
class="mx_SettingsSubsection"
data-testid="account-management-section"
>
<div
class="mx_SettingsSubsectionHeading"
>
<h3
class="mx_Heading_h3 mx_SettingsSubsectionHeading_heading"
>
Account management
</h3>
</div>
<div
class="mx_SettingsSubsection_description"
>
<div
class="mx_SettingsSubsection_text"
>
Deactivating your account is a permanent action — be careful!
</div>
</div>
<div
class="mx_SettingsSubsection_content"
>
<div
class="mx_AccessibleButton mx_AccessibleButton_hasKind mx_AccessibleButton_kind_danger"
role="button"
tabindex="0"
>
Deactivate Account
</div>
</div>
</div>
</div>
</div>
`;