diff --git a/src/settings/DeveloperSettingsTab.test.tsx b/src/settings/DeveloperSettingsTab.test.tsx index 7bdf7091..51255666 100644 --- a/src/settings/DeveloperSettingsTab.test.tsx +++ b/src/settings/DeveloperSettingsTab.test.tsx @@ -5,13 +5,17 @@ SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial Please see LICENSE in the repository root for full details. */ -import { describe, expect, it, vi } from "vitest"; -import { render, waitFor } from "@testing-library/react"; +import { afterEach, describe, expect, it, type Mock, vi } from "vitest"; +import { render, waitFor, screen } from "@testing-library/react"; +import userEvent from "@testing-library/user-event"; +import { TooltipProvider } from "@vector-im/compound-web"; import type { MatrixClient } from "matrix-js-sdk"; import type { Room as LivekitRoom } from "livekit-client"; +// import { DeveloperSettingsTab } from "./DeveloperSettingsTab"; import { DeveloperSettingsTab } from "./DeveloperSettingsTab"; - +import { getSFUConfigWithOpenID } from "../livekit/openIDSFU"; +import { customLivekitUrl as customLivekitUrlSetting } from "./settings"; // Mock url params hook to avoid environment-dependent snapshot churn. vi.mock("../UrlParams", () => ({ useUrlParams: (): { mocked: boolean; answer: number } => ({ @@ -20,6 +24,14 @@ vi.mock("../UrlParams", () => ({ }), })); +// IMPORTANT: mock the same specifier used by DeveloperSettingsTab +vi.mock("../livekit/openIDSFU", () => ({ + getSFUConfigWithOpenID: vi.fn().mockResolvedValue({ + url: "mock-url", + jwt: "mock-jwt", + }), +})); + // Provide a minimal mock of a Livekit Room structure used by the component. function createMockLivekitRoom( wsUrl: string, @@ -52,30 +64,30 @@ function createMockMatrixClient(): MatrixClient { } describe("DeveloperSettingsTab", () => { + const livekitRooms: { + room: LivekitRoom; + url: string; + isLocal?: boolean; + }[] = [ + createMockLivekitRoom( + "wss://local-sfu.example.org", + { region: "local", version: "1.2.3" }, + "local-metadata", + ), + { + isLocal: false, + url: "wss://remote-sfu.example.org", + room: { + serverInfo: { region: "remote", version: "4.5.6" }, + metadata: "remote-metadata", + engine: { client: { ws: { url: "wss://remote-sfu.example.org" } } }, + } as unknown as LivekitRoom, + }, + ]; + it("renders and matches snapshot", async () => { const client = createMockMatrixClient(); - const livekitRooms: { - room: LivekitRoom; - url: string; - isLocal?: boolean; - }[] = [ - createMockLivekitRoom( - "wss://local-sfu.example.org", - { region: "local", version: "1.2.3" }, - "local-metadata", - ), - { - isLocal: false, - url: "wss://remote-sfu.example.org", - room: { - serverInfo: { region: "remote", version: "4.5.6" }, - metadata: "remote-metadata", - engine: { client: { ws: { url: "wss://remote-sfu.example.org" } } }, - } as unknown as LivekitRoom, - }, - ]; - const { container } = render( { expect(container).toMatchSnapshot(); }); + describe("custom livekit url", () => { + afterEach(() => { + customLivekitUrlSetting.setValue(null); + }); + const client = { + doesServerSupportUnstableFeature: vi.fn().mockResolvedValue(true), + getCrypto: () => ({ getVersion: (): string => "x" }), + getUserId: () => "@u:hs", + getDeviceId: () => "DEVICE", + } as unknown as MatrixClient; + it("will not update custom livekit url without roomId", async () => { + const user = userEvent.setup(); + + render( + + + , + ); + + const input = screen.getByLabelText("Custom Livekit-url"); + await user.clear(input); + await user.type(input, "wss://example.livekit.invalid"); + + const saveButton = screen.getByRole("button", { name: "Save" }); + await user.click(saveButton); + expect(getSFUConfigWithOpenID).not.toHaveBeenCalled(); + + expect(customLivekitUrlSetting.getValue()).toBe(null); + }); + it("will not update custom livekit url without text in input", async () => { + const user = userEvent.setup(); + + render( + + + , + ); + + const input = screen.getByLabelText("Custom Livekit-url"); + await user.clear(input); + + const saveButton = screen.getByRole("button", { name: "Save" }); + await user.click(saveButton); + expect(getSFUConfigWithOpenID).not.toHaveBeenCalled(); + + expect(customLivekitUrlSetting.getValue()).toBe(null); + }); + it("will not update custom livekit url when pressing cancel", async () => { + const user = userEvent.setup(); + + render( + + + , + ); + + const input = screen.getByLabelText("Custom Livekit-url"); + await user.clear(input); + await user.type(input, "wss://example.livekit.invalid"); + + const cancelButton = screen.getByRole("button", { + name: "Reset overwrite", + }); + await user.click(cancelButton); + expect(getSFUConfigWithOpenID).not.toHaveBeenCalled(); + + expect(customLivekitUrlSetting.getValue()).toBe(null); + }); + it("will update custom livekit url", async () => { + const user = userEvent.setup(); + + render( + + + , + ); + + const input = screen.getByLabelText("Custom Livekit-url"); + await user.clear(input); + await user.type(input, "wss://example.livekit.valid"); + + const saveButton = screen.getByRole("button", { name: "Save" }); + await user.click(saveButton); + expect(getSFUConfigWithOpenID).toHaveBeenCalledWith( + expect.anything(), + "wss://example.livekit.valid", + "#testRoom", + ); + + expect(customLivekitUrlSetting.getValue()).toBe( + "wss://example.livekit.valid", + ); + }); + it("will show error on invalid url", async () => { + const user = userEvent.setup(); + + render( + + + , + ); + + const input = screen.getByLabelText("Custom Livekit-url"); + await user.clear(input); + await user.type(input, "wss://example.livekit.valid"); + + const saveButton = screen.getByRole("button", { name: "Save" }); + (getSFUConfigWithOpenID as Mock).mockImplementation(() => { + throw new Error("Invalid URL"); + }); + await user.click(saveButton); + expect( + screen.getByText("invalid URL (did not update)"), + ).toBeInTheDocument(); + expect(customLivekitUrlSetting.getValue()).toBe(null); + }); + }); });