Tweak modules to be disabled if config is missing (#33806)

* Consolidate modules vitest coverage

* Use vite-common as base for modules vitest config

* Make knip happier

* Fix coverage paths

* Place modules unit tests alongside src

* Switch to defineProject for better type safety

* Consolidate vitest CI & coverage

Kills off vite-common

* Update comment

* Update lockfile

* Fix shared-components vitest config

* Soften eslint config for tests in modules

* Run eslint on modules/playwright dir too

* Make tsc happy

* Tweak modules to be disabled if config is missing

* Restore blank line

* Improve coverage

* Potential fix for pull request finding 'Unused variable, import, function or class'

Co-authored-by: Copilot Autofix powered by AI <223894421+github-code-quality[bot]@users.noreply.github.com>

---------

Co-authored-by: Copilot Autofix powered by AI <223894421+github-code-quality[bot]@users.noreply.github.com>
This commit is contained in:
Michael Telatynski
2026-06-16 08:41:40 +00:00
committed by GitHub
co-authored by Copilot Autofix powered by AI <223894421+github-code-quality[bot]@users.noreply.github.com>
parent d92e10f01a
commit 44c540eca0
16 changed files with 208 additions and 25 deletions
@@ -236,13 +236,29 @@ for (const auth of ["mas", "legacy"] as const) {
});
test.describe(`Restricted guests auth=${auth} guests=${guestsEnabled}`, () => {
test("should error if config is missing", async ({ page }) => {
test("should not error if config is missing", async ({ page }) => {
await page.goto("/");
await expect(page.getByText("Your Element is misconfigured")).toBeVisible();
await expect(page.getByText("Errors in module configuration")).toBeVisible();
await expect(page.getByText("Your Element is misconfigured")).not.toBeVisible();
await expect(page.getByText("Errors in module configuration")).not.toBeVisible();
});
test.describe("with config", () => {
test.describe("with invalid config", () => {
test.use({
config: {
"io.element.element-web-modules.restricted-guests": {
hs_url: "foo",
},
},
});
test("should render error", async ({ page }) => {
await page.goto("/");
await expect(page.getByText("Your Element is misconfigured")).toBeVisible();
await expect(page.getByText("Errors in module configuration")).toBeVisible();
});
});
test.describe("with valid config", () => {
test.beforeEach(async ({ config, guestHomeserver, page, testRoomId }) => {
config["io.element.element-web-modules.restricted-guests"] = {
guest_user_homeserver_url: guestHomeserver.baseUrl,
+1 -1
View File
@@ -39,7 +39,7 @@ export const CONFIG_KEY = "io.element.element-web-modules.restricted-guests";
declare module "@element-hq/element-web-module-api" {
export interface Config {
[CONFIG_KEY]: input<ConfigSchema>;
[CONFIG_KEY]?: input<ConfigSchema>;
sso_redirect_options?: {
immediate?: boolean; // incompatible option
};
@@ -0,0 +1,35 @@
/*
Copyright 2026 Element Creations Ltd.
SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial
Please see LICENSE files in the repository root for full details.
*/
import { describe, expect, it, vi } from "vitest";
import { type Api } from "@element-hq/element-web-module-api";
import RestrictedGuestsModule from "./index";
const makeApi = (config: unknown): Api => {
return {
config: {
get: vi.fn().mockReturnValue(config),
},
i18n: {
register: vi.fn(),
},
} as unknown as Api;
};
describe("RestrictedGuestsModule", () => {
describe("load", () => {
it("should do nothing if no config present", async () => {
const api = makeApi(null);
const module = new RestrictedGuestsModule(api);
await module.load();
expect(api.i18n.register).not.toHaveBeenCalled();
});
});
});
+7 -1
View File
@@ -31,12 +31,18 @@ class RestrictedGuestsModule implements Module {
public constructor(private api: Api) {}
public async load(): Promise<void> {
const rawConfig = this.api.config.get(CONFIG_KEY);
if (!rawConfig) {
console.debug(`No configuration found for module "${ModuleName}", skipping initialization.`);
return;
}
document.adoptedStyleSheets.push(compound);
this.api.i18n.register(Translations);
try {
this.config = ModuleConfig.parse(this.api.config.get(CONFIG_KEY));
this.config = ModuleConfig.parse(rawConfig);
} catch (e) {
console.error("Failed to init module", e);
throw new Error(`Errors in module configuration for "${ModuleName}"`);
@@ -0,0 +1,14 @@
/*
Copyright 2026 Element Creations Ltd.
SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial
Please see LICENSE files in the repository root for full details.
*/
import { defineProject } from "vitest/config";
export default defineProject({
test: {
exclude: ["./e2e/**/*", "./node_modules/**/*"],
},
});