Remove dead test files
While we still ought to eventually port these tests in some way, the presence of these empty test files is causing a Vitest failure, so it's easiest to just let them go and refer to Git history when we do want to reference them next.
This commit is contained in:
@@ -1,187 +0,0 @@
|
|||||||
/*
|
|
||||||
Copyright 2025 New Vector Ltd.
|
|
||||||
|
|
||||||
SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial
|
|
||||||
Please see LICENSE in the repository root for full details.
|
|
||||||
*/
|
|
||||||
|
|
||||||
// TODO-MULTI-SFU: Make sure all these tests are ported in some way to the Connection tests
|
|
||||||
/*
|
|
||||||
import { type FC, useCallback, useState } from "react";
|
|
||||||
import { describe, expect, test, vi, vitest } from "vitest";
|
|
||||||
import {
|
|
||||||
ConnectionError,
|
|
||||||
ConnectionErrorReason,
|
|
||||||
type Room,
|
|
||||||
} from "livekit-client";
|
|
||||||
import userEvent from "@testing-library/user-event";
|
|
||||||
import { render, screen } from "@testing-library/react";
|
|
||||||
import { MemoryRouter } from "react-router-dom";
|
|
||||||
import { sleep } from "matrix-js-sdk/lib/utils";
|
|
||||||
|
|
||||||
import { useECConnectionState } from "./useECConnectionState";
|
|
||||||
import { type SFUConfig } from "./openIDSFU";
|
|
||||||
import { GroupCallErrorBoundary } from "../room/GroupCallErrorBoundary.tsx";
|
|
||||||
|
|
||||||
test.each<[string, ConnectionError]>([
|
|
||||||
[
|
|
||||||
"LiveKit hits track limit",
|
|
||||||
new ConnectionError("", ConnectionErrorReason.InternalError, 503),
|
|
||||||
],
|
|
||||||
[
|
|
||||||
"LiveKit hits room participant limit",
|
|
||||||
new ConnectionError("", ConnectionErrorReason.ServerUnreachable, 200),
|
|
||||||
],
|
|
||||||
[
|
|
||||||
"LiveKit Cloud hits connection limit",
|
|
||||||
new ConnectionError("", ConnectionErrorReason.NotAllowed, 429),
|
|
||||||
],
|
|
||||||
])(
|
|
||||||
"useECConnectionState throws error when %s hits track limit",
|
|
||||||
async (_server, error) => {
|
|
||||||
const mockRoom = {
|
|
||||||
on: () => {},
|
|
||||||
off: () => {},
|
|
||||||
once: () => {},
|
|
||||||
connect: () => {
|
|
||||||
throw error;
|
|
||||||
},
|
|
||||||
localParticipant: {
|
|
||||||
getTrackPublication: () => {},
|
|
||||||
createTracks: () => [],
|
|
||||||
},
|
|
||||||
} as unknown as Room;
|
|
||||||
|
|
||||||
const TestComponent: FC = () => {
|
|
||||||
const [sfuConfig, setSfuConfig] = useState<SFUConfig | undefined>(
|
|
||||||
undefined,
|
|
||||||
);
|
|
||||||
const connect = useCallback(
|
|
||||||
() => setSfuConfig({ url: "URL", jwt: "JWT token" }),
|
|
||||||
[],
|
|
||||||
);
|
|
||||||
useECConnectionState("default", false, mockRoom, sfuConfig);
|
|
||||||
return <button onClick={connect}>Connect</button>;
|
|
||||||
};
|
|
||||||
|
|
||||||
const user = userEvent.setup();
|
|
||||||
render(
|
|
||||||
<MemoryRouter>
|
|
||||||
<GroupCallErrorBoundary recoveryActionHandler={vi.fn()} widget={null}>
|
|
||||||
<TestComponent />
|
|
||||||
</GroupCallErrorBoundary>
|
|
||||||
</MemoryRouter>,
|
|
||||||
);
|
|
||||||
await user.click(screen.getByRole("button", { name: "Connect" }));
|
|
||||||
screen.getByText("Insufficient capacity");
|
|
||||||
},
|
|
||||||
);
|
|
||||||
|
|
||||||
describe("Leaking connection prevention", () => {
|
|
||||||
function createTestComponent(mockRoom: Room): FC {
|
|
||||||
const TestComponent: FC = () => {
|
|
||||||
const [sfuConfig, setSfuConfig] = useState<SFUConfig | undefined>(
|
|
||||||
undefined,
|
|
||||||
);
|
|
||||||
const connect = useCallback(
|
|
||||||
() => setSfuConfig({ url: "URL", jwt: "JWT token" }),
|
|
||||||
[],
|
|
||||||
);
|
|
||||||
useECConnectionState("default", false, mockRoom, sfuConfig);
|
|
||||||
return <button onClick={connect}>Connect</button>;
|
|
||||||
};
|
|
||||||
return TestComponent;
|
|
||||||
}
|
|
||||||
|
|
||||||
test("Should cancel pending connections when the component is unmounted", async () => {
|
|
||||||
const connectCall = vi.fn();
|
|
||||||
const pendingConnection = Promise.withResolvers<void>();
|
|
||||||
// let pendingDisconnection = Promise.withResolvers<void>()
|
|
||||||
const disconnectMock = vi.fn();
|
|
||||||
|
|
||||||
const mockRoom = {
|
|
||||||
on: () => {},
|
|
||||||
off: () => {},
|
|
||||||
once: () => {},
|
|
||||||
connect: async () => {
|
|
||||||
connectCall.call(undefined);
|
|
||||||
return await pendingConnection.promise;
|
|
||||||
},
|
|
||||||
disconnect: disconnectMock,
|
|
||||||
localParticipant: {
|
|
||||||
getTrackPublication: () => {},
|
|
||||||
createTracks: () => [],
|
|
||||||
},
|
|
||||||
} as unknown as Room;
|
|
||||||
|
|
||||||
const TestComponent = createTestComponent(mockRoom);
|
|
||||||
|
|
||||||
const { unmount } = render(<TestComponent />);
|
|
||||||
const user = userEvent.setup();
|
|
||||||
await user.click(screen.getByRole("button", { name: "Connect" }));
|
|
||||||
|
|
||||||
expect(connectCall).toHaveBeenCalled();
|
|
||||||
// unmount while the connection is pending
|
|
||||||
unmount();
|
|
||||||
|
|
||||||
// resolve the pending connection
|
|
||||||
pendingConnection.resolve();
|
|
||||||
|
|
||||||
await vitest.waitUntil(
|
|
||||||
() => {
|
|
||||||
return disconnectMock.mock.calls.length > 0;
|
|
||||||
},
|
|
||||||
{
|
|
||||||
timeout: 1000,
|
|
||||||
interval: 100,
|
|
||||||
},
|
|
||||||
);
|
|
||||||
|
|
||||||
// There should be some cleaning up to avoid leaking an open connection
|
|
||||||
expect(disconnectMock).toHaveBeenCalledTimes(1);
|
|
||||||
});
|
|
||||||
|
|
||||||
test("Should cancel about to open but not yet opened connection", async () => {
|
|
||||||
const createTracksCall = vi.fn();
|
|
||||||
const pendingCreateTrack = Promise.withResolvers<void>();
|
|
||||||
// let pendingDisconnection = Promise.withResolvers<void>()
|
|
||||||
const disconnectMock = vi.fn();
|
|
||||||
const connectMock = vi.fn();
|
|
||||||
|
|
||||||
const mockRoom = {
|
|
||||||
on: () => {},
|
|
||||||
off: () => {},
|
|
||||||
once: () => {},
|
|
||||||
connect: connectMock,
|
|
||||||
disconnect: disconnectMock,
|
|
||||||
localParticipant: {
|
|
||||||
getTrackPublication: () => {},
|
|
||||||
createTracks: async () => {
|
|
||||||
createTracksCall.call(undefined);
|
|
||||||
await pendingCreateTrack.promise;
|
|
||||||
return [];
|
|
||||||
},
|
|
||||||
},
|
|
||||||
} as unknown as Room;
|
|
||||||
|
|
||||||
const TestComponent = createTestComponent(mockRoom);
|
|
||||||
|
|
||||||
const { unmount } = render(<TestComponent />);
|
|
||||||
const user = userEvent.setup();
|
|
||||||
await user.click(screen.getByRole("button", { name: "Connect" }));
|
|
||||||
|
|
||||||
expect(createTracksCall).toHaveBeenCalled();
|
|
||||||
// unmount while createTracks is pending
|
|
||||||
unmount();
|
|
||||||
|
|
||||||
// resolve createTracks
|
|
||||||
pendingCreateTrack.resolve();
|
|
||||||
|
|
||||||
// Yield to the event loop to let the connection attempt finish
|
|
||||||
await sleep(100);
|
|
||||||
|
|
||||||
// The operation should have been aborted before even calling connect.
|
|
||||||
expect(connectMock).not.toHaveBeenCalled();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
*/
|
|
||||||
@@ -1,325 +0,0 @@
|
|||||||
/*
|
|
||||||
Copyright 2024 New Vector Ltd.
|
|
||||||
|
|
||||||
SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial
|
|
||||||
Please see LICENSE in the repository root for full details.
|
|
||||||
*/
|
|
||||||
|
|
||||||
// TODO-MULTI-SFU: These tests need to be ported to the new MuteStates class.
|
|
||||||
/*
|
|
||||||
|
|
||||||
import {
|
|
||||||
afterAll,
|
|
||||||
afterEach,
|
|
||||||
beforeEach,
|
|
||||||
describe,
|
|
||||||
expect,
|
|
||||||
it,
|
|
||||||
onTestFinished,
|
|
||||||
vi,
|
|
||||||
} from "vitest";
|
|
||||||
import { type FC, useCallback, useState } from "react";
|
|
||||||
import { render, screen } from "@testing-library/react";
|
|
||||||
import { MemoryRouter } from "react-router-dom";
|
|
||||||
import userEvent from "@testing-library/user-event";
|
|
||||||
import { createMediaDeviceObserver } from "@livekit/components-core";
|
|
||||||
import { of } from "rxjs";
|
|
||||||
|
|
||||||
import { useMuteStates } from "./MuteStates";
|
|
||||||
import { MediaDevicesContext } from "../MediaDevicesContext";
|
|
||||||
import { mockConfig } from "../utils/test";
|
|
||||||
import { MediaDevices } from "../state/MediaDevices";
|
|
||||||
import { ObservableScope } from "../state/ObservableScope";
|
|
||||||
vi.mock("@livekit/components-core");
|
|
||||||
|
|
||||||
interface TestComponentProps {
|
|
||||||
isJoined?: boolean;
|
|
||||||
}
|
|
||||||
|
|
||||||
const TestComponent: FC<TestComponentProps> = ({ isJoined = false }) => {
|
|
||||||
const muteStates = useMuteStates(isJoined);
|
|
||||||
const onToggleAudio = useCallback(
|
|
||||||
() => muteStates.audio.setEnabled?.(!muteStates.audio.enabled),
|
|
||||||
[muteStates],
|
|
||||||
);
|
|
||||||
return (
|
|
||||||
<div>
|
|
||||||
<div data-testid="audio-enabled">
|
|
||||||
{muteStates.audio.enabled.toString()}
|
|
||||||
</div>
|
|
||||||
<button onClick={onToggleAudio}>Toggle audio</button>
|
|
||||||
<div data-testid="video-enabled">
|
|
||||||
{muteStates.video.enabled.toString()}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
const mockMicrophone: MediaDeviceInfo = {
|
|
||||||
deviceId: "",
|
|
||||||
kind: "audioinput",
|
|
||||||
label: "",
|
|
||||||
groupId: "",
|
|
||||||
toJSON() {
|
|
||||||
return {};
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
const mockSpeaker: MediaDeviceInfo = {
|
|
||||||
deviceId: "",
|
|
||||||
kind: "audiooutput",
|
|
||||||
label: "",
|
|
||||||
groupId: "",
|
|
||||||
toJSON() {
|
|
||||||
return {};
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
const mockCamera: MediaDeviceInfo = {
|
|
||||||
deviceId: "",
|
|
||||||
kind: "videoinput",
|
|
||||||
label: "",
|
|
||||||
groupId: "",
|
|
||||||
toJSON() {
|
|
||||||
return {};
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
function mockMediaDevices(
|
|
||||||
{
|
|
||||||
microphone,
|
|
||||||
speaker,
|
|
||||||
camera,
|
|
||||||
}: {
|
|
||||||
microphone?: boolean;
|
|
||||||
speaker?: boolean;
|
|
||||||
camera?: boolean;
|
|
||||||
} = { microphone: true, speaker: true, camera: true },
|
|
||||||
): MediaDevices {
|
|
||||||
vi.mocked(createMediaDeviceObserver).mockImplementation((kind) => {
|
|
||||||
switch (kind) {
|
|
||||||
case "audioinput":
|
|
||||||
return of(microphone ? [mockMicrophone] : []);
|
|
||||||
case "audiooutput":
|
|
||||||
return of(speaker ? [mockSpeaker] : []);
|
|
||||||
case "videoinput":
|
|
||||||
return of(camera ? [mockCamera] : []);
|
|
||||||
case undefined:
|
|
||||||
throw new Error("Unimplemented");
|
|
||||||
}
|
|
||||||
});
|
|
||||||
return new MediaDevices(testScope());
|
|
||||||
}
|
|
||||||
|
|
||||||
describe("useMuteStates VITE_PACKAGE='full' (SPA) mode", () => {
|
|
||||||
afterEach(() => {
|
|
||||||
vi.clearAllMocks();
|
|
||||||
vi.stubEnv("VITE_PACKAGE", "full");
|
|
||||||
});
|
|
||||||
|
|
||||||
afterAll(() => {
|
|
||||||
vi.resetAllMocks();
|
|
||||||
});
|
|
||||||
|
|
||||||
it("disabled when no input devices", () => {
|
|
||||||
mockConfig();
|
|
||||||
|
|
||||||
render(
|
|
||||||
<MemoryRouter>
|
|
||||||
<MediaDevicesContext
|
|
||||||
value={mockMediaDevices({
|
|
||||||
microphone: false,
|
|
||||||
camera: false,
|
|
||||||
})}
|
|
||||||
>
|
|
||||||
<TestComponent />
|
|
||||||
</MediaDevicesContext>
|
|
||||||
</MemoryRouter>,
|
|
||||||
);
|
|
||||||
expect(screen.getByTestId("audio-enabled").textContent).toBe("false");
|
|
||||||
expect(screen.getByTestId("video-enabled").textContent).toBe("false");
|
|
||||||
});
|
|
||||||
|
|
||||||
it("enables devices by default in the lobby", () => {
|
|
||||||
mockConfig();
|
|
||||||
|
|
||||||
render(
|
|
||||||
<MemoryRouter>
|
|
||||||
<MediaDevicesContext value={mockMediaDevices()}>
|
|
||||||
<TestComponent />
|
|
||||||
</MediaDevicesContext>
|
|
||||||
</MemoryRouter>,
|
|
||||||
);
|
|
||||||
expect(screen.getByTestId("audio-enabled").textContent).toBe("true");
|
|
||||||
expect(screen.getByTestId("video-enabled").textContent).toBe("true");
|
|
||||||
});
|
|
||||||
|
|
||||||
it("disables devices by default in the call", () => {
|
|
||||||
// Disabling new devices in the call ensures that connecting a webcam
|
|
||||||
// mid-call won't cause it to suddenly be enabled without user input
|
|
||||||
mockConfig();
|
|
||||||
|
|
||||||
render(
|
|
||||||
<MemoryRouter>
|
|
||||||
<MediaDevicesContext value={mockMediaDevices()}>
|
|
||||||
<TestComponent isJoined />
|
|
||||||
</MediaDevicesContext>
|
|
||||||
</MemoryRouter>,
|
|
||||||
);
|
|
||||||
expect(screen.getByTestId("audio-enabled").textContent).toBe("false");
|
|
||||||
expect(screen.getByTestId("video-enabled").textContent).toBe("false");
|
|
||||||
});
|
|
||||||
|
|
||||||
it("uses defaults from config", () => {
|
|
||||||
mockConfig({
|
|
||||||
media_devices: {
|
|
||||||
enable_audio: false,
|
|
||||||
enable_video: false,
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
render(
|
|
||||||
<MemoryRouter>
|
|
||||||
<MediaDevicesContext value={mockMediaDevices()}>
|
|
||||||
<TestComponent />
|
|
||||||
</MediaDevicesContext>
|
|
||||||
</MemoryRouter>,
|
|
||||||
);
|
|
||||||
expect(screen.getByTestId("audio-enabled").textContent).toBe("false");
|
|
||||||
expect(screen.getByTestId("video-enabled").textContent).toBe("false");
|
|
||||||
});
|
|
||||||
|
|
||||||
it("skipLobby mutes inputs", () => {
|
|
||||||
mockConfig();
|
|
||||||
|
|
||||||
render(
|
|
||||||
<MemoryRouter
|
|
||||||
initialEntries={[
|
|
||||||
"/room/?skipLobby=true&widgetId=1234&parentUrl=www.parent.org",
|
|
||||||
]}
|
|
||||||
>
|
|
||||||
<MediaDevicesContext value={mockMediaDevices()}>
|
|
||||||
<TestComponent />
|
|
||||||
</MediaDevicesContext>
|
|
||||||
</MemoryRouter>,
|
|
||||||
);
|
|
||||||
expect(screen.getByTestId("audio-enabled").textContent).toBe("false");
|
|
||||||
expect(screen.getByTestId("video-enabled").textContent).toBe("false");
|
|
||||||
});
|
|
||||||
|
|
||||||
it("remembers previous state when devices disappear and reappear", async () => {
|
|
||||||
const user = userEvent.setup();
|
|
||||||
mockConfig();
|
|
||||||
const noDevices = mockMediaDevices({ microphone: false, camera: false });
|
|
||||||
// Warm up these Observables before making further changes to the
|
|
||||||
// createMediaDevicesObserver mock
|
|
||||||
noDevices.audioInput.available$.subscribe(() => {}).unsubscribe();
|
|
||||||
noDevices.videoInput.available$.subscribe(() => {}).unsubscribe();
|
|
||||||
const someDevices = mockMediaDevices();
|
|
||||||
|
|
||||||
const ReappearanceTest: FC = () => {
|
|
||||||
const [devices, setDevices] = useState(someDevices);
|
|
||||||
const onConnectDevicesClick = useCallback(
|
|
||||||
() => setDevices(someDevices),
|
|
||||||
[],
|
|
||||||
);
|
|
||||||
const onDisconnectDevicesClick = useCallback(
|
|
||||||
() => setDevices(noDevices),
|
|
||||||
[],
|
|
||||||
);
|
|
||||||
|
|
||||||
return (
|
|
||||||
<MemoryRouter>
|
|
||||||
<MediaDevicesContext value={devices}>
|
|
||||||
<TestComponent />
|
|
||||||
<button onClick={onConnectDevicesClick}>Connect devices</button>
|
|
||||||
<button onClick={onDisconnectDevicesClick}>
|
|
||||||
Disconnect devices
|
|
||||||
</button>
|
|
||||||
</MediaDevicesContext>
|
|
||||||
</MemoryRouter>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
render(<ReappearanceTest />);
|
|
||||||
expect(screen.getByTestId("audio-enabled").textContent).toBe("true");
|
|
||||||
expect(screen.getByTestId("video-enabled").textContent).toBe("true");
|
|
||||||
await user.click(screen.getByRole("button", { name: "Toggle audio" }));
|
|
||||||
expect(screen.getByTestId("audio-enabled").textContent).toBe("false");
|
|
||||||
expect(screen.getByTestId("video-enabled").textContent).toBe("true");
|
|
||||||
await user.click(
|
|
||||||
screen.getByRole("button", { name: "Disconnect devices" }),
|
|
||||||
);
|
|
||||||
expect(screen.getByTestId("audio-enabled").textContent).toBe("false");
|
|
||||||
expect(screen.getByTestId("video-enabled").textContent).toBe("false");
|
|
||||||
await user.click(screen.getByRole("button", { name: "Connect devices" }));
|
|
||||||
// Audio should remember that it was muted, while video should re-enable
|
|
||||||
expect(screen.getByTestId("audio-enabled").textContent).toBe("false");
|
|
||||||
expect(screen.getByTestId("video-enabled").textContent).toBe("true");
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe("useMuteStates in VITE_PACKAGE='embedded' (widget) mode", () => {
|
|
||||||
beforeEach(() => {
|
|
||||||
vi.stubEnv("VITE_PACKAGE", "embedded");
|
|
||||||
});
|
|
||||||
|
|
||||||
it("uses defaults from config", () => {
|
|
||||||
mockConfig({
|
|
||||||
media_devices: {
|
|
||||||
enable_audio: false,
|
|
||||||
enable_video: false,
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
render(
|
|
||||||
<MemoryRouter>
|
|
||||||
<MediaDevicesContext value={mockMediaDevices()}>
|
|
||||||
<TestComponent />
|
|
||||||
</MediaDevicesContext>
|
|
||||||
</MemoryRouter>,
|
|
||||||
);
|
|
||||||
expect(screen.getByTestId("audio-enabled").textContent).toBe("false");
|
|
||||||
expect(screen.getByTestId("video-enabled").textContent).toBe("false");
|
|
||||||
});
|
|
||||||
|
|
||||||
it("skipLobby does not mute inputs", () => {
|
|
||||||
mockConfig();
|
|
||||||
|
|
||||||
render(
|
|
||||||
<MemoryRouter
|
|
||||||
initialEntries={[
|
|
||||||
"/room/?skipLobby=true&widgetId=1234&parentUrl=www.parent.org",
|
|
||||||
]}
|
|
||||||
>
|
|
||||||
<MediaDevicesContext value={mockMediaDevices()}>
|
|
||||||
<TestComponent />
|
|
||||||
</MediaDevicesContext>
|
|
||||||
</MemoryRouter>,
|
|
||||||
);
|
|
||||||
expect(screen.getByTestId("audio-enabled").textContent).toBe("true");
|
|
||||||
expect(screen.getByTestId("video-enabled").textContent).toBe("true");
|
|
||||||
});
|
|
||||||
|
|
||||||
it("url params win over config", () => {
|
|
||||||
// The config sets audio and video to disabled
|
|
||||||
mockConfig({ media_devices: { enable_audio: false, enable_video: false } });
|
|
||||||
|
|
||||||
render(
|
|
||||||
<MemoryRouter
|
|
||||||
initialEntries={[
|
|
||||||
// The Intent sets both audio and video enabled to true via the url param configuration
|
|
||||||
"/room/?intent=start_call_dm&widgetId=1234&parentUrl=www.parent.org",
|
|
||||||
]}
|
|
||||||
>
|
|
||||||
<MediaDevicesContext value={mockMediaDevices()}>
|
|
||||||
<TestComponent />
|
|
||||||
</MediaDevicesContext>
|
|
||||||
</MemoryRouter>,
|
|
||||||
);
|
|
||||||
// At the end we expect the url param to take precedence, resulting in true
|
|
||||||
expect(screen.getByTestId("audio-enabled").textContent).toBe("true");
|
|
||||||
expect(screen.getByTestId("video-enabled").textContent).toBe("true");
|
|
||||||
});
|
|
||||||
});
|
|
||||||
*/
|
|
||||||
Reference in New Issue
Block a user