Address code smells from #30453 (#31083)

* check recents length

* Improve sorting logic in capabilities dialog

* Fix allowedHosts regex array check

* Remove double negative in filter checks

* prettier
This commit is contained in:
David Langley
2025-10-29 08:52:17 +00:00
committed by GitHub
parent 3e809cd661
commit 80a7de4314
7 changed files with 207 additions and 11 deletions

View File

@@ -664,4 +664,39 @@ describe("Spotlight Dialog", () => {
}),
);
});
describe("keyboard prompt filter and query checks", () => {
it("should show left and right arrow keys in keyboard hint when filter is null and no query", async () => {
render(<SpotlightDialog onFinished={() => null} />);
jest.advanceTimersByTime(200);
await flushPromisesWithFakeTimers();
const keyboardPrompt = document.querySelector("#mx_SpotlightDialog_keyboardPrompt");
expect(keyboardPrompt).toBeInTheDocument();
expect(keyboardPrompt?.textContent).toContain("←");
expect(keyboardPrompt?.textContent).toContain("→");
});
it("should not show left and right arrow keys in keyboard hint when filter is set", async () => {
render(<SpotlightDialog initialFilter={Filter.People} onFinished={() => null} />);
jest.advanceTimersByTime(200);
await flushPromisesWithFakeTimers();
const keyboardPrompt = document.querySelector("#mx_SpotlightDialog_keyboardPrompt");
expect(keyboardPrompt).toBeInTheDocument();
expect(keyboardPrompt?.textContent).not.toContain("←");
expect(keyboardPrompt?.textContent).not.toContain("→");
});
it("should not show left and right arrow keys in keyboard hint when query is present", async () => {
render(<SpotlightDialog initialText="test query" onFinished={() => null} />);
jest.advanceTimersByTime(200);
await flushPromisesWithFakeTimers();
const keyboardPrompt = document.querySelector("#mx_SpotlightDialog_keyboardPrompt");
expect(keyboardPrompt).toBeInTheDocument();
expect(keyboardPrompt?.textContent).not.toContain("←");
expect(keyboardPrompt?.textContent).not.toContain("→");
});
});
});

View File

@@ -0,0 +1,133 @@
/*
Copyright 2025 New Vector Ltd.
SPDX-License-Identifier: AGPL-3.0-only OR GPL-3.0-only OR LicenseRef-Element-Commercial
Please see LICENSE files in the repository root for full details.
*/
import React from "react";
import { render, screen } from "jest-matrix-react";
import { WidgetKind } from "matrix-widget-api";
import WidgetCapabilitiesPromptDialog from "../../../../../src/components/views/dialogs/WidgetCapabilitiesPromptDialog";
import { stubClient } from "../../../../test-utils";
describe("WidgetCapabilitiesPromptDialog", () => {
const mockWidget = {
id: "test-widget",
name: "Test Widget",
} as any;
const onFinished = jest.fn();
beforeEach(() => {
stubClient();
onFinished.mockClear();
});
describe("capability sorting", () => {
it("should sort non-timeline capabilities before timeline capabilities", () => {
// Create a mix of timeline and non-timeline capabilities
const capabilities = new Set([
"org.matrix.msc2762.timeline:*",
"org.matrix.msc2762.receive.event:m.room.message",
"org.matrix.msc2762.timeline:!room:example.com",
"org.matrix.msc2931.navigate",
"org.matrix.msc2762.receive.state_event:m.room.member#@user:example.com",
]);
const { container } = render(
<WidgetCapabilitiesPromptDialog
requestedCapabilities={capabilities}
widget={mockWidget}
widgetKind={WidgetKind.Room}
onFinished={onFinished}
/>,
);
const checkboxes = container.querySelectorAll(".mx_WidgetCapabilitiesPromptDialog_cap");
// Verify that we have all the capabilities rendered
expect(checkboxes.length).toBe(5);
// The dialog should render successfully with the mixed capabilities
expect(screen.getByText("Approve widget permissions")).toBeInTheDocument();
});
it("should sort capabilities lexicographically within the same type", () => {
// Create multiple non-timeline capabilities
const capabilities = new Set([
"org.matrix.msc2931.navigate",
"org.matrix.msc2762.receive.event:m.room.message",
"org.matrix.msc2762.receive.state_event:m.room.member",
]);
render(
<WidgetCapabilitiesPromptDialog
requestedCapabilities={capabilities}
widget={mockWidget}
widgetKind={WidgetKind.Room}
onFinished={onFinished}
/>,
);
// The dialog should render without errors and show the capabilities
expect(screen.getByText("Approve widget permissions")).toBeInTheDocument();
});
it("should handle only timeline capabilities", () => {
const capabilities = new Set([
"org.matrix.msc2762.timeline:!room1:example.com",
"org.matrix.msc2762.timeline:!room2:example.com",
"org.matrix.msc2762.timeline:*",
]);
const { container } = render(
<WidgetCapabilitiesPromptDialog
requestedCapabilities={capabilities}
widget={mockWidget}
widgetKind={WidgetKind.Room}
onFinished={onFinished}
/>,
);
const checkboxes = container.querySelectorAll(".mx_WidgetCapabilitiesPromptDialog_cap");
expect(checkboxes.length).toBe(3);
});
it("should handle only non-timeline capabilities", () => {
const capabilities = new Set([
"org.matrix.msc2931.navigate",
"org.matrix.msc2762.receive.event:m.room.message",
]);
const { container } = render(
<WidgetCapabilitiesPromptDialog
requestedCapabilities={capabilities}
widget={mockWidget}
widgetKind={WidgetKind.Room}
onFinished={onFinished}
/>,
);
const checkboxes = container.querySelectorAll(".mx_WidgetCapabilitiesPromptDialog_cap");
expect(checkboxes.length).toBe(2);
});
it("should handle empty capabilities", () => {
const capabilities = new Set<string>([]);
const { container } = render(
<WidgetCapabilitiesPromptDialog
requestedCapabilities={capabilities}
widget={mockWidget}
widgetKind={WidgetKind.Room}
onFinished={onFinished}
/>,
);
const checkboxes = container.querySelectorAll(".mx_WidgetCapabilitiesPromptDialog_cap");
expect(checkboxes.length).toBe(0);
});
});
});

View File

@@ -334,6 +334,33 @@ describe("Permalinks", function () {
expect(creator.serverCandidates![0]).toEqual("evilcorp.com");
});
it("should handle when ACL allow is not an array", function () {
const roomId = "!fake:example.org";
const room = mockRoom(roomId, [makeMemberWithPL(roomId, "@alice:goodcorp.com", 100)], {
deny: ["*.evilcorp.com"],
allow: "not-an-array" as any, // Test malformed data
});
const creator = new RoomPermalinkCreator(room);
creator.load();
// Should fall back to default behavior (no allowed servers list = allow none)
expect(creator.serverCandidates).toBeTruthy();
expect(creator.serverCandidates!.length).toBe(0);
});
it("should handle when ACL deny is not an array", function () {
const roomId = "!fake:example.org";
const room = mockRoom(roomId, [makeMemberWithPL(roomId, "@alice:goodcorp.com", 100)], {
deny: "not-an-array" as any, // Test malformed data
allow: ["*"],
});
const creator = new RoomPermalinkCreator(room);
creator.load();
// Should not crash and still allow the server
expect(creator.serverCandidates).toBeTruthy();
expect(creator.serverCandidates!.length).toBe(1);
expect(creator.serverCandidates![0]).toEqual("goodcorp.com");
});
it("should generate an event permalink for room IDs with no candidate servers", function () {
const room = mockRoom("!somewhere:example.org", []);
const creator = new RoomPermalinkCreator(room);