Refactor the way we check for if widget or not to make it easier to mock

This commit is contained in:
Hugh Nimmo-Smith
2024-12-02 11:59:20 +00:00
parent bc2281f7d2
commit 0395e5fdc9
7 changed files with 21 additions and 28 deletions

View File

@@ -10,7 +10,7 @@ import { logger } from "matrix-js-sdk/src/logger";
import { MatrixClient } from "matrix-js-sdk/src/matrix"; import { MatrixClient } from "matrix-js-sdk/src/matrix";
import { Buffer } from "buffer"; import { Buffer } from "buffer";
import { widget } from "../widget"; import { isRunningAsWidget } from "../widget";
import { import {
CallEndedTracker, CallEndedTracker,
CallStartedTracker, CallStartedTracker,
@@ -269,7 +269,7 @@ export class PosthogAnalytics {
private async getAnalyticsId(): Promise<string | null> { private async getAnalyticsId(): Promise<string | null> {
const client: MatrixClient = window.matrixclient; const client: MatrixClient = window.matrixclient;
let accountAnalyticsId; let accountAnalyticsId;
if (widget) { if (isRunningAsWidget) {
accountAnalyticsId = getUrlParams().analyticsID; accountAnalyticsId = getUrlParams().analyticsID;
} else { } else {
const accountData = await client.getAccountDataFromServer( const accountData = await client.getAccountDataFromServer(

View File

@@ -17,7 +17,7 @@ import { logger } from "matrix-js-sdk/src/logger";
import { initClient } from "../utils/matrix"; import { initClient } from "../utils/matrix";
import { Session } from "../ClientContext"; import { Session } from "../ClientContext";
import { Config } from "../config/Config"; import { Config } from "../config/Config";
import { widget } from "../widget"; import { isRunningAsWidget } from "../widget";
export const useInteractiveRegistration = ( export const useInteractiveRegistration = (
oldClient?: MatrixClient, oldClient?: MatrixClient,
@@ -47,7 +47,7 @@ export const useInteractiveRegistration = (
} }
useEffect(() => { useEffect(() => {
if (widget) return; if (isRunningAsWidget) return;
// An empty registerRequest is used to get the privacy policy and recaptcha key. // An empty registerRequest is used to get the privacy policy and recaptcha key.
authClient.current!.registerRequest({}).catch((error) => { authClient.current!.registerRequest({}).catch((error) => {
setPrivacyPolicyUrl( setPrivacyPolicyUrl(

View File

@@ -5,7 +5,7 @@ SPDX-License-Identifier: AGPL-3.0-only
Please see LICENSE in the repository root for full details. Please see LICENSE in the repository root for full details.
*/ */
import { afterAll, afterEach, describe, expect, it, vi } from "vitest"; import { afterEach, describe, expect, it, vi } from "vitest";
import React, { ReactNode } from "react"; import React, { ReactNode } from "react";
import { beforeEach } from "vitest"; import { beforeEach } from "vitest";
import { render, screen } from "@testing-library/react"; import { render, screen } from "@testing-library/react";
@@ -18,6 +18,7 @@ import {
MediaDevicesContext, MediaDevicesContext,
} from "../livekit/MediaDevicesContext"; } from "../livekit/MediaDevicesContext";
import { mockConfig } from "../utils/test"; import { mockConfig } from "../utils/test";
import * as widget from "../widget";
function TestComponent(): ReactNode { function TestComponent(): ReactNode {
const muteStates = useMuteStates(); const muteStates = useMuteStates();
@@ -98,10 +99,7 @@ describe("useMuteStates", () => {
afterEach(() => { afterEach(() => {
vi.restoreAllMocks(); vi.restoreAllMocks();
}); vi.unmock("../widget");
afterAll(() => {
vi.clearAllMocks();
}); });
it("disabled when no input devices", () => { it("disabled when no input devices", () => {
@@ -172,19 +170,7 @@ describe("useMuteStates", () => {
it("skipLobby does not mute inputs in widget mode", () => { it("skipLobby does not mute inputs in widget mode", () => {
mockConfig(); mockConfig();
vi.mock("../widget", () => { vi.spyOn(widget, "isRunningAsWidget", "get").mockImplementation(() => true);
return {
widget: {
api: {
transport: {
send: async (): Promise<void> => new Promise((r) => r()),
},
},
lazyActions: { on: vi.fn(), off: vi.fn() },
},
ElementWidgetActions: {},
};
});
render( render(
<MemoryRouter initialEntries={["/room/?skipLobby=true"]}> <MemoryRouter initialEntries={["/room/?skipLobby=true"]}>

View File

@@ -17,7 +17,7 @@ import { logger } from "matrix-js-sdk/src/logger";
import { MediaDevice, useMediaDevices } from "../livekit/MediaDevicesContext"; import { MediaDevice, useMediaDevices } from "../livekit/MediaDevicesContext";
import { useReactiveState } from "../useReactiveState"; import { useReactiveState } from "../useReactiveState";
import { ElementWidgetActions, widget } from "../widget"; import { ElementWidgetActions, isRunningAsWidget, widget } from "../widget";
import { Config } from "../config/Config"; import { Config } from "../config/Config";
import { useUrlParams } from "../UrlParams"; import { useUrlParams } from "../UrlParams";
@@ -75,7 +75,7 @@ export function useMuteStates(): MuteStates {
const { skipLobby } = useUrlParams(); const { skipLobby } = useUrlParams();
// In SPA without lobby we need to protect from unmuted joins for privacy. // In SPA without lobby we need to protect from unmuted joins for privacy.
const allowStartUnmuted = !skipLobby || !!widget; const allowStartUnmuted = !skipLobby || isRunningAsWidget;
const audio = useMuteState(devices.audioInput, () => { const audio = useMuteState(devices.audioInput, () => {
return Config.get().media_devices.enable_audio && allowStartUnmuted; return Config.get().media_devices.enable_audio && allowStartUnmuted;
}); });

View File

@@ -20,7 +20,7 @@ import { KnownMembership } from "matrix-js-sdk/src/types";
import { JoinRule, MatrixError } from "matrix-js-sdk/src/matrix"; import { JoinRule, MatrixError } from "matrix-js-sdk/src/matrix";
import { useTranslation } from "react-i18next"; import { useTranslation } from "react-i18next";
import { widget } from "../widget"; import { isRunningAsWidget } from "../widget";
export type GroupCallLoaded = { export type GroupCallLoaded = {
kind: "loaded"; kind: "loaded";
@@ -238,7 +238,7 @@ export const useLoadGroupCall = (
// room already joined so we are done here already. // room already joined so we are done here already.
return room!; return room!;
} }
if (widget) if (isRunningAsWidget)
// in widget mode we never should reach this point. (getRoom should return the room.) // in widget mode we never should reach this point. (getRoom should return the room.)
throw new Error( throw new Error(
"Room not found. The widget-api did not pass over the relevant room events/information.", "Room not found. The widget-api did not pass over the relevant room events/information.",

View File

@@ -21,7 +21,7 @@ import {
useMediaDevices, useMediaDevices,
useMediaDeviceNames, useMediaDeviceNames,
} from "../livekit/MediaDevicesContext"; } from "../livekit/MediaDevicesContext";
import { widget } from "../widget"; import { isRunningAsWidget } from "../widget";
import { import {
useSetting, useSetting,
developerSettingsTab as developerSettingsTabSetting, developerSettingsTab as developerSettingsTabSetting,
@@ -236,7 +236,7 @@ export const SettingsModal: FC<Props> = ({
}; };
const tabs = [audioTab, videoTab]; const tabs = [audioTab, videoTab];
if (widget === null) tabs.push(profileTab); if (!isRunningAsWidget) tabs.push(profileTab);
tabs.push(preferencesTab, feedbackTab, moreTab); tabs.push(preferencesTab, feedbackTab, moreTab);
if (developerSettingsTab) tabs.push(developerTab); if (developerSettingsTab) tabs.push(developerTab);

View File

@@ -181,3 +181,10 @@ export const widget = ((): WidgetHelpers | null => {
return null; return null;
} }
})(); })();
/**
* Whether or not we are running as a widget.
*
* @returns true if widget, false if SPA
*/
export const isRunningAsWidget: boolean = !!widget;