feat: show call participants in room list (Discord-style)
Docker / Docker Buildx (push) Has been cancelled
Build Debian package / Build package (release) Has been cancelled
Build and Deploy / prepare (release) Has been cancelled
Deploy release / Deploy to Cloudflare Pages (release) Has been cancelled
Build and Deploy / Trigger Pro pipeline (release) Has been cancelled
Build and Deploy / Windows arm64 (release) Has been cancelled
Build and Deploy / Windows x64 (release) Has been cancelled
Build and Deploy / macOS (release) Has been cancelled
Build and Deploy / Linux amd64 (sqlcipher static) (release) Has been cancelled
Build and Deploy / Linux arm64 (sqlcipher static) (release) Has been cancelled
Build and Deploy / ${{ needs.prepare.outputs.deploy == 'true' && 'Deploy' || 'Deploy (dry-run)' }} (release) Has been cancelled
Build and Deploy / Deploy builds to ESS (release) Has been cancelled

This commit is contained in:
sorB
2026-05-10 14:25:35 +02:00
parent b797925316
commit 3da363517f
4610 changed files with 827237 additions and 1 deletions
+28
View File
@@ -0,0 +1,28 @@
/*
Copyright 2024 New Vector Ltd.
Copyright 2024 The Matrix.org Foundation C.I.C.
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.
*/
export const mocks = {
AudioBufferSourceNode: {
connect: jest.fn(),
start: jest.fn(),
stop: jest.fn(),
} as unknown as AudioBufferSourceNode,
AudioContext: {
close: jest.fn(),
createMediaElementSource: jest.fn(),
createMediaStreamDestination: jest.fn(),
createMediaStreamSource: jest.fn(),
createStreamTrackSource: jest.fn(),
createBufferSource: jest.fn((): AudioBufferSourceNode => ({ ...mocks.AudioBufferSourceNode })),
getOutputTimestamp: jest.fn(),
resume: jest.fn(),
setSinkId: jest.fn(),
suspend: jest.fn(),
decodeAudioData: jest.fn(),
} as unknown as AudioContext,
};
+13
View File
@@ -0,0 +1,13 @@
/*
Copyright 2024 New Vector Ltd.
Copyright 2022 The Matrix.org Foundation C.I.C.
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 SdkConfig, { DEFAULTS } from "../../src/SdkConfig";
// uninitialised SdkConfig causes lots of warnings in console
// init with defaults
SdkConfig.put(DEFAULTS);
+72
View File
@@ -0,0 +1,72 @@
/*
Copyright 2024 New Vector Ltd.
Copyright 2022 The Matrix.org Foundation C.I.C.
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 fetchMock from "@fetch-mock/jest";
import { ModuleLoader } from "@element-hq/element-web-module-api";
import { merge } from "lodash";
import * as languageHandler from "../../src/languageHandler";
import enElementWeb from "../../src/i18n/strings/en_EN.json";
import deElementWeb from "../../src/i18n/strings/de_DE.json";
// Cheat and import relatively here as these aren't exported by the module (should they be?)
// eslint-disable-next-line no-restricted-imports
import enSharedComponents from "../../../../packages/shared-components/src/i18n/strings/en_EN.json";
// eslint-disable-next-line no-restricted-imports
import deSharedComponents from "../../../../packages/shared-components/src/i18n/strings/de_DE.json";
import { ModuleApi } from "../../src/modules/Api";
const lv = {
Save: "Saglabāt",
room: {
upload: {
uploading_multiple_file: {
one: "Качване на %(filename)s и %(count)s друг",
},
},
},
};
// Fake languages.json containing references to en_EN, de_DE and lv
// en_EN.json
// de_DE.json
// lv.json - mock version with few translations, used to test fallback translation
export function setupLanguageMock() {
// Pull the translations from shared components too as they have
// the strings for things like `humanizeTime` which do appear in
// snapshots (needs 'merge' which does a deep-merge rather than just
// replacing top-level keys).
const enTranslations = merge(enElementWeb, enSharedComponents);
const deTranslations = merge(deElementWeb, deSharedComponents);
fetchMock.mockGlobal();
fetchMock
.get(
"end:/i18n/languages.json",
{
en: "en_EN.json",
de: "de_DE.json",
lv: "lv.json",
},
{ name: "languages" },
)
.get("end:en_EN.json", enTranslations)
.get("end:de_DE.json", deTranslations)
.get("end:lv.json", lv);
}
beforeEach(setupLanguageMock);
afterEach(() => fetchMock.callHistory.flush());
// Initialise the fetchMock before the test starts so the languageHandler.setLanguage call below can function
setupLanguageMock();
languageHandler.setLanguage("en");
languageHandler.setMissingEntryGenerator((key) => key.split("|", 2)[1]);
// Set up the module API (so the i18n API exists)
const moduleLoader = new ModuleLoader(ModuleApi.instance);
window.mxModuleLoader = moduleLoader;
+91
View File
@@ -0,0 +1,91 @@
/*
Copyright 2024 New Vector Ltd.
Copyright 2022 The Matrix.org Foundation C.I.C.
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 fetchMock, { manageFetchMockGlobally } from "@fetch-mock/jest";
import { jest } from "@jest/globals";
import { mocks } from "./mocks";
// Stub ResizeObserver
// @ts-ignore - we know it's a duplicate (that's why we're stubbing it)
class ResizeObserver {
observe() {} // do nothing
unobserve() {} // do nothing
disconnect() {} // do nothing
}
window.ResizeObserver = ResizeObserver;
// Stub DOMRect
class DOMRect {
x = 0;
y = 0;
top = 0;
bottom = 0;
left = 0;
right = 0;
height = 0;
width = 0;
static fromRect() {
return new DOMRect();
}
toJSON() {}
}
window.DOMRect = DOMRect;
// Work around missing ClipboardEvent type
class MyClipboardEvent extends Event {}
window.ClipboardEvent = MyClipboardEvent as any;
// matchMedia is not included in jsdom
// TODO: Extract this to a function and have tests that need it opt into it.
global.matchMedia = (query: string) => ({
matches: false,
media: query,
onchange: null,
addListener: jest.fn(), // Deprecated
removeListener: jest.fn(), // Deprecated
addEventListener: jest.fn(),
removeEventListener: jest.fn(),
dispatchEvent: jest.fn<(event: Event) => boolean>(),
});
// maplibre requires a createObjectURL mock
global.URL.createObjectURL = jest.fn((obj) => "blob");
global.URL.revokeObjectURL = jest.fn();
// prevent errors whenever a component tries to manually scroll.
window.HTMLElement.prototype.scrollIntoView = jest.fn();
window.HTMLAudioElement.prototype.canPlayType = jest.fn((format) => (format === "audio/mpeg" ? "probably" : ""));
function setupFileStubMocks() {
fetchMock.get("end:/image-file-stub", "image file stub", { sticky: true });
}
setupFileStubMocks();
beforeEach(() => {
// set up fetch API mock
fetchMock.hardReset();
fetchMock.catch(404);
setupFileStubMocks();
fetchMock.get("/_matrix/client/versions", {}, { sticky: true });
fetchMock.mockGlobal();
});
afterEach(() => {
fetchMock.removeRoutes();
window.sessionStorage?.clear();
window.localStorage?.clear();
});
fetchMock.config.allowRelativeUrls = true;
manageFetchMockGlobally(jest);
// set up AudioContext API mock
global.AudioContext = jest.fn<() => AudioContext>().mockImplementation(() => ({ ...mocks.AudioContext }));