Expose SDKContext on the window & avoid using singleton store .instance (#34098)
* Expose SDKContextClass via window for debugging * Remove stores from window if they are exposed via sdkContext * Avoid usages of global store instance where React context is accessible * Fix tests by adding SDKContext.Provider * Fix tests by adding SDKContext.Provider * Fix tests by adding SDKContext.Provider * Fix tests by adding SDKContext.Provider * Iterate * Discard changes to apps/web/src/components/views/elements/AppTile.tsx
This commit is contained in:
@@ -24,7 +24,6 @@ import { clientAndSDKContextRenderOptions, stubClient } from "../../../../test-u
|
||||
import { Action } from "../../../../../src/dispatcher/actions";
|
||||
import dis from "../../../../../src/dispatcher/dispatcher";
|
||||
import DMRoomMap from "../../../../../src/utils/DMRoomMap";
|
||||
import MatrixClientContext from "../../../../../src/contexts/MatrixClientContext";
|
||||
import SettingsStore from "../../../../../src/settings/SettingsStore";
|
||||
import { RightPanelPhases } from "../../../../../src/stores/right-panel/RightPanelStorePhases";
|
||||
import RightPanelStore from "../../../../../src/stores/right-panel/RightPanelStore";
|
||||
@@ -194,13 +193,11 @@ describe("AppTile", () => {
|
||||
);
|
||||
|
||||
renderResult.rerender(
|
||||
<MatrixClientContext.Provider value={cli}>
|
||||
<RightPanel
|
||||
room={r2}
|
||||
resizeNotifier={resizeNotifier}
|
||||
permalinkCreator={new RoomPermalinkCreator(r2, r2.roomId)}
|
||||
/>
|
||||
</MatrixClientContext.Provider>,
|
||||
<RightPanel
|
||||
room={r2}
|
||||
resizeNotifier={resizeNotifier}
|
||||
permalinkCreator={new RoomPermalinkCreator(r2, r2.roomId)}
|
||||
/>,
|
||||
);
|
||||
|
||||
expect(renderResult.queryByText("Example 1")).not.toBeInTheDocument();
|
||||
@@ -278,13 +275,11 @@ describe("AppTile", () => {
|
||||
}),
|
||||
);
|
||||
renderResult.rerender(
|
||||
<MatrixClientContext.Provider value={cli}>
|
||||
<RightPanel
|
||||
room={r2}
|
||||
resizeNotifier={resizeNotifier}
|
||||
permalinkCreator={new RoomPermalinkCreator(r2, r2.roomId)}
|
||||
/>
|
||||
</MatrixClientContext.Provider>,
|
||||
<RightPanel
|
||||
room={r2}
|
||||
resizeNotifier={resizeNotifier}
|
||||
permalinkCreator={new RoomPermalinkCreator(r2, r2.roomId)}
|
||||
/>,
|
||||
);
|
||||
|
||||
await waitFor(() => {
|
||||
|
||||
+8
@@ -283,6 +283,14 @@ exports[`<ExtensionsCard /> should render widgets 1`] = `
|
||||
</svg>
|
||||
</div>
|
||||
</div>
|
||||
<a
|
||||
class="_link_k9ljz_8"
|
||||
data-kind="primary"
|
||||
data-size="md"
|
||||
rel="noreferrer noopener"
|
||||
>
|
||||
Set layout for everyone
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</DocumentFragment>
|
||||
|
||||
@@ -20,6 +20,7 @@ import { CommandPartCreator } from "../../../../../src/editor/parts";
|
||||
import DocumentOffset from "../../../../../src/editor/offset";
|
||||
import { SDKContextClass } from "../../../../../src/contexts/SDKContextClass";
|
||||
import SettingsStore from "../../../../../src/settings/SettingsStore";
|
||||
import { SDKContext } from "../../../../../src/contexts/SDKContext.ts";
|
||||
|
||||
describe("BasicMessageComposer", () => {
|
||||
const renderer = createRenderer();
|
||||
@@ -35,7 +36,11 @@ describe("BasicMessageComposer", () => {
|
||||
|
||||
it("should allow a user to paste a URL without it being mangled", async () => {
|
||||
const model = new EditorModel([], pc, renderer);
|
||||
render(<BasicMessageComposer model={model} room={room} />);
|
||||
render(<BasicMessageComposer model={model} room={room} />, {
|
||||
wrapper: ({ children }) => (
|
||||
<SDKContext.Provider value={SDKContextClass.instance}>{children}</SDKContext.Provider>
|
||||
),
|
||||
});
|
||||
const testUrl = "https://element.io";
|
||||
const mockDataTransfer = generateMockDataTransferForString(testUrl);
|
||||
await userEvent.paste(mockDataTransfer);
|
||||
@@ -51,7 +56,11 @@ describe("BasicMessageComposer", () => {
|
||||
});
|
||||
userEvent.setup();
|
||||
const model = new EditorModel([], pc, renderer);
|
||||
render(<BasicMessageComposer model={model} room={room} />);
|
||||
render(<BasicMessageComposer model={model} room={room} />, {
|
||||
wrapper: ({ children }) => (
|
||||
<SDKContext.Provider value={SDKContextClass.instance}>{children}</SDKContext.Provider>
|
||||
),
|
||||
});
|
||||
|
||||
const tranformations = [
|
||||
{ before: "4:3 video", after: "4:3 video" },
|
||||
@@ -81,7 +90,11 @@ describe("BasicMessageComposer", () => {
|
||||
|
||||
it("should not mangle shift-enter when the autocomplete is open", async () => {
|
||||
const model = new EditorModel([], pc, renderer);
|
||||
render(<BasicMessageComposer model={model} room={room} />);
|
||||
render(<BasicMessageComposer model={model} room={room} />, {
|
||||
wrapper: ({ children }) => (
|
||||
<SDKContext.Provider value={SDKContextClass.instance}>{children}</SDKContext.Provider>
|
||||
),
|
||||
});
|
||||
|
||||
const input = screen.getByRole("textbox");
|
||||
|
||||
@@ -93,7 +106,11 @@ describe("BasicMessageComposer", () => {
|
||||
|
||||
it("should escape single quote in placeholder", async () => {
|
||||
const model = new EditorModel([], pc, renderer);
|
||||
const composer = render(<BasicMessageComposer placeholder="Don't" model={model} room={room} />);
|
||||
const composer = render(<BasicMessageComposer placeholder="Don't" model={model} room={room} />, {
|
||||
wrapper: ({ children }) => (
|
||||
<SDKContext.Provider value={SDKContextClass.instance}>{children}</SDKContext.Provider>
|
||||
),
|
||||
});
|
||||
const input = composer.queryAllByRole("textbox");
|
||||
const placeholder = input[0].style.getPropertyValue("--placeholder");
|
||||
expect(placeholder).toMatch("'Don\\'t'");
|
||||
@@ -101,7 +118,11 @@ describe("BasicMessageComposer", () => {
|
||||
|
||||
it("should escape backslash in placeholder", async () => {
|
||||
const model = new EditorModel([], pc, renderer);
|
||||
const composer = render(<BasicMessageComposer placeholder={"w\\e"} model={model} room={room} />);
|
||||
const composer = render(<BasicMessageComposer placeholder={"w\\e"} model={model} room={room} />, {
|
||||
wrapper: ({ children }) => (
|
||||
<SDKContext.Provider value={SDKContextClass.instance}>{children}</SDKContext.Provider>
|
||||
),
|
||||
});
|
||||
const input = composer.queryAllByRole("textbox");
|
||||
const placeholder = input[0].style.getPropertyValue("--placeholder");
|
||||
expect(placeholder).toMatch("'w\\\\e'");
|
||||
@@ -116,7 +137,11 @@ describe("BasicMessageComposer", () => {
|
||||
// spy on typingStore.setSelfTyping
|
||||
const spy = jest.spyOn(SDKContextClass.instance.typingStore, "setSelfTyping");
|
||||
|
||||
render(<BasicMessageComposer model={model} room={room} />);
|
||||
render(<BasicMessageComposer model={model} room={room} />, {
|
||||
wrapper: ({ children }) => (
|
||||
<SDKContext.Provider value={SDKContextClass.instance}>{children}</SDKContext.Provider>
|
||||
),
|
||||
});
|
||||
|
||||
// simulate typing by updating the model - this will call the component's update callback
|
||||
await model.update(commandPart.text, "insertText", new DocumentOffset(commandPart.text.length, true));
|
||||
@@ -128,7 +153,11 @@ describe("BasicMessageComposer", () => {
|
||||
|
||||
it("should ignore keydown events during IME composition", () => {
|
||||
const model = new EditorModel([], pc, renderer);
|
||||
render(<BasicMessageComposer model={model} room={room} />);
|
||||
render(<BasicMessageComposer model={model} room={room} />, {
|
||||
wrapper: ({ children }) => (
|
||||
<SDKContext.Provider value={SDKContextClass.instance}>{children}</SDKContext.Provider>
|
||||
),
|
||||
});
|
||||
const input = screen.getByRole("textbox");
|
||||
|
||||
// Start IME composition
|
||||
@@ -167,7 +196,11 @@ describe("BasicMessageComposer", () => {
|
||||
|
||||
it("should handle keydown events normally when not composing", () => {
|
||||
const model = new EditorModel([], pc, renderer);
|
||||
render(<BasicMessageComposer model={model} room={room} />);
|
||||
render(<BasicMessageComposer model={model} room={room} />, {
|
||||
wrapper: ({ children }) => (
|
||||
<SDKContext.Provider value={SDKContextClass.instance}>{children}</SDKContext.Provider>
|
||||
),
|
||||
});
|
||||
const input = screen.getByRole("textbox");
|
||||
|
||||
// Simulate Tab key when NOT composing
|
||||
|
||||
@@ -33,6 +33,8 @@ import NotifProvider from "../../../../../src/autocomplete/NotifProvider";
|
||||
import DMRoomMap from "../../../../../src/utils/DMRoomMap";
|
||||
import { ScopedRoomContextProvider } from "../../../../../src/contexts/ScopedRoomContext.tsx";
|
||||
import type { RoomContextType } from "../../../../../src/contexts/RoomContext.ts";
|
||||
import { SDKContext } from "../../../../../src/contexts/SDKContext.ts";
|
||||
import { SDKContextClass } from "../../../../../src/contexts/SDKContextClass.ts";
|
||||
|
||||
describe("<EditMessageComposer/>", () => {
|
||||
const userId = "@alice:server.org";
|
||||
@@ -78,9 +80,11 @@ describe("<EditMessageComposer/>", () => {
|
||||
const getComponent = (editState: EditorStateTransfer, roomContext: RoomContextType = defaultRoomContext) =>
|
||||
render(<EditMessageComposerWithMatrixClient editState={editState} />, {
|
||||
wrapper: ({ children }) => (
|
||||
<MatrixClientContext.Provider value={mockClient}>
|
||||
<ScopedRoomContextProvider {...roomContext}>{children}</ScopedRoomContextProvider>
|
||||
</MatrixClientContext.Provider>
|
||||
<SDKContext.Provider value={SDKContextClass.instance}>
|
||||
<MatrixClientContext.Provider value={mockClient}>
|
||||
<ScopedRoomContextProvider {...roomContext}>{children}</ScopedRoomContextProvider>
|
||||
</MatrixClientContext.Provider>
|
||||
</SDKContext.Provider>
|
||||
),
|
||||
});
|
||||
|
||||
|
||||
@@ -51,6 +51,8 @@ import SettingsStore from "../../../../../src/settings/SettingsStore";
|
||||
import EditorStateTransfer from "../../../../../src/utils/EditorStateTransfer";
|
||||
import { RoomPermalinkCreator } from "../../../../../src/utils/permalinks/Permalinks";
|
||||
import PlatformPeg from "../../../../../src/PlatformPeg";
|
||||
import { SDKContextClass } from "../../../../../src/contexts/SDKContextClass.ts";
|
||||
import { SDKContext } from "../../../../../src/contexts/SDKContext.ts";
|
||||
|
||||
function getTile(container: HTMLElement): HTMLElement {
|
||||
const tile = container.querySelector(".mx_EventTile");
|
||||
@@ -1652,7 +1654,11 @@ describe("EventTile", () => {
|
||||
return Element.prototype.matches.call(this, selector);
|
||||
});
|
||||
|
||||
const { container, rerender } = render(<WrappedEventTiles events={events} editEvent={firstEvent} />);
|
||||
const { container, rerender } = render(<WrappedEventTiles events={events} editEvent={firstEvent} />, {
|
||||
wrapper: ({ children }) => (
|
||||
<SDKContext.Provider value={SDKContextClass.instance}>{children}</SDKContext.Provider>
|
||||
),
|
||||
});
|
||||
const editingTile = container.querySelector(".mx_EventTile_isEditing");
|
||||
|
||||
expect(editingTile).not.toBeNull();
|
||||
|
||||
@@ -37,6 +37,8 @@ import { Action } from "../../../../../src/dispatcher/actions";
|
||||
import { ScopedRoomContextProvider } from "../../../../../src/contexts/ScopedRoomContext.tsx";
|
||||
import { TimelineRenderingType, type RoomContextType } from "../../../../../src/contexts/RoomContext.ts";
|
||||
import { RoomUploadContextProvider } from "../../../../../src/viewmodels/room/RoomUploadViewModel.tsx";
|
||||
import { SDKContext } from "../../../../../src/contexts/SDKContext.ts";
|
||||
import { SDKContextClass } from "../../../../../src/contexts/SDKContextClass.ts";
|
||||
|
||||
const openStickerPicker = async (): Promise<void> => {
|
||||
await userEvent.click(screen.getByLabelText("More options"));
|
||||
@@ -469,13 +471,15 @@ function wrapAndRender(
|
||||
};
|
||||
|
||||
const getRawComponent = (props = {}, context = roomContext, client = mockClient) => (
|
||||
<MatrixClientContext.Provider value={client}>
|
||||
<ScopedRoomContextProvider {...context}>
|
||||
<RoomUploadContextProvider>
|
||||
<MessageComposer {...defaultProps} {...props} />
|
||||
</RoomUploadContextProvider>
|
||||
</ScopedRoomContextProvider>
|
||||
</MatrixClientContext.Provider>
|
||||
<SDKContext.Provider value={SDKContextClass.instance}>
|
||||
<MatrixClientContext.Provider value={client}>
|
||||
<ScopedRoomContextProvider {...context}>
|
||||
<RoomUploadContextProvider>
|
||||
<MessageComposer {...defaultProps} {...props} />
|
||||
</RoomUploadContextProvider>
|
||||
</ScopedRoomContextProvider>
|
||||
</MatrixClientContext.Provider>
|
||||
</SDKContext.Provider>
|
||||
);
|
||||
return {
|
||||
rawComponent: getRawComponent(props, roomContext, mockClient),
|
||||
|
||||
@@ -59,6 +59,7 @@ import WidgetStore, { type IApp } from "../../../../../../src/stores/WidgetStore
|
||||
import { UIFeature } from "../../../../../../src/settings/UIFeature";
|
||||
import { SettingLevel } from "../../../../../../src/settings/SettingLevel";
|
||||
import { ElementCallMemberEventType } from "../../../../../../src/call-types";
|
||||
import { SDKContext } from "../../../../../../src/contexts/SDKContext";
|
||||
import { SDKContextClass } from "../../../../../../src/contexts/SDKContextClass.ts";
|
||||
|
||||
jest.mock("../../../../../../src/utils/ShieldUtils");
|
||||
@@ -93,9 +94,11 @@ describe("RoomHeader", () => {
|
||||
function getWrapper(): RenderOptions {
|
||||
return {
|
||||
wrapper: ({ children }) => (
|
||||
<MatrixClientContext.Provider value={client}>
|
||||
<ScopedRoomContextProvider {...roomContext}>{children}</ScopedRoomContextProvider>
|
||||
</MatrixClientContext.Provider>
|
||||
<SDKContext.Provider value={SDKContextClass.instance}>
|
||||
<MatrixClientContext.Provider value={client}>
|
||||
<ScopedRoomContextProvider {...roomContext}>{children}</ScopedRoomContextProvider>
|
||||
</MatrixClientContext.Provider>
|
||||
</SDKContext.Provider>
|
||||
),
|
||||
};
|
||||
}
|
||||
|
||||
@@ -10,9 +10,10 @@ import React from "react";
|
||||
import { MatrixEvent, Room, EventType } from "matrix-js-sdk/src/matrix";
|
||||
import { render, type RenderResult } from "jest-matrix-react";
|
||||
|
||||
import { stubClient, withClientContextRenderOptions } from "../../../../test-utils";
|
||||
import { clientAndSDKContextRenderOptions, stubClient } from "../../../../test-utils";
|
||||
import SearchResultTile from "../../../../../src/components/views/rooms/SearchResultTile";
|
||||
import { MatrixClientPeg } from "../../../../../src/MatrixClientPeg";
|
||||
import { SDKContextClass } from "../../../../../src/contexts/SDKContextClass.ts";
|
||||
|
||||
const ROOM_ID = "!qPewotXpIctQySfjSy:localhost";
|
||||
|
||||
@@ -30,7 +31,7 @@ describe("SearchResultTile", () => {
|
||||
function renderComponent(props: Partial<Props>): RenderResult {
|
||||
return render(
|
||||
<SearchResultTile timeline={[]} ourEventsIndexes={[1]} {...props} />,
|
||||
withClientContextRenderOptions(MatrixClientPeg.safeGet()),
|
||||
clientAndSDKContextRenderOptions(MatrixClientPeg.safeGet(), SDKContextClass.instance),
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -35,6 +35,7 @@ import { addTextToComposer } from "../../../../test-utils/composer";
|
||||
import { ScopedRoomContextProvider } from "../../../../../src/contexts/ScopedRoomContext.tsx";
|
||||
import { SDKContextClass } from "../../../../../src/contexts/SDKContextClass";
|
||||
import { RoomUploadContextProvider } from "../../../../../src/viewmodels/room/RoomUploadViewModel.tsx";
|
||||
import { SDKContext } from "../../../../../src/contexts/SDKContext.ts";
|
||||
|
||||
jest.mock("../../../../../src/utils/local-room", () => ({
|
||||
doMaybeLocalRoomAction: jest.fn(),
|
||||
@@ -199,7 +200,11 @@ describe("<SendMessageComposer/>", () => {
|
||||
</MatrixClientContext.Provider>
|
||||
);
|
||||
const getComponent = (props = {}, roomContext = defaultRoomContext, client = mockClient) => {
|
||||
return render(getRawComponent(props, roomContext, client));
|
||||
return render(getRawComponent(props, roomContext, client), {
|
||||
wrapper: ({ children }) => (
|
||||
<SDKContext.Provider value={SDKContextClass.instance}>{children}</SDKContext.Provider>
|
||||
),
|
||||
});
|
||||
};
|
||||
|
||||
it("renders text and placeholder correctly", () => {
|
||||
@@ -447,6 +452,11 @@ describe("<SendMessageComposer/>", () => {
|
||||
</RoomUploadContextProvider>
|
||||
</ScopedRoomContextProvider>
|
||||
</MatrixClientContext.Provider>,
|
||||
{
|
||||
wrapper: ({ children }) => (
|
||||
<SDKContext.Provider value={SDKContextClass.instance}>{children}</SDKContext.Provider>
|
||||
),
|
||||
},
|
||||
);
|
||||
|
||||
const composer = container.querySelector<HTMLDivElement>(".mx_BasicMessageComposer_input")!;
|
||||
|
||||
@@ -14,12 +14,17 @@ import { mocked } from "jest-mock";
|
||||
import QuickSettingsButton from "../../../../../src/components/views/spaces/QuickSettingsButton";
|
||||
import SettingsStore from "../../../../../src/settings/SettingsStore";
|
||||
import { SDKContextClass } from "../../../../../src/contexts/SDKContextClass";
|
||||
import { SDKContext } from "../../../../../src/contexts/SDKContext.ts";
|
||||
|
||||
describe("QuickSettingsButton", () => {
|
||||
const roomId = "!room:example.com";
|
||||
|
||||
const renderQuickSettingsButton = () => {
|
||||
render(<QuickSettingsButton isPanelCollapsed={true} />);
|
||||
render(<QuickSettingsButton isPanelCollapsed={true} />, {
|
||||
wrapper: ({ children }) => (
|
||||
<SDKContext.Provider value={SDKContextClass.instance}>{children}</SDKContext.Provider>
|
||||
),
|
||||
});
|
||||
};
|
||||
|
||||
const getQuickSettingsButton = () => {
|
||||
@@ -37,7 +42,11 @@ describe("QuickSettingsButton", () => {
|
||||
});
|
||||
|
||||
it("should render the quick settings button in expanded mode", () => {
|
||||
const { asFragment } = render(<QuickSettingsButton isPanelCollapsed={false} />);
|
||||
const { asFragment } = render(<QuickSettingsButton isPanelCollapsed={false} />, {
|
||||
wrapper: ({ children }) => (
|
||||
<SDKContext.Provider value={SDKContextClass.instance}>{children}</SDKContext.Provider>
|
||||
),
|
||||
});
|
||||
expect(asFragment()).toMatchSnapshot();
|
||||
});
|
||||
|
||||
|
||||
Reference in New Issue
Block a user