Files
element-call/src/useCallViewKeyboardShortcuts.test.tsx
T

97 lines
2.5 KiB
TypeScript
Raw Normal View History

2024-07-24 18:42:21 -04:00
/*
Copyright 2024 New Vector Ltd.
2024-07-24 18:42:21 -04:00
SPDX-License-Identifier: AGPL-3.0-only
Please see LICENSE in the repository root for full details.
2024-07-24 18:42:21 -04:00
*/
import { render } from "@testing-library/react";
import { FC, useRef } from "react";
import { expect, test, vi } from "vitest";
2024-07-24 18:42:21 -04:00
import { Button } from "@vector-im/compound-web";
import userEvent from "@testing-library/user-event";
import { useCallViewKeyboardShortcuts } from "../src/useCallViewKeyboardShortcuts";
2024-08-30 15:40:09 +02:00
// Test Explanation:
// - The main objective is to test `useCallViewKeyboardShortcuts`.
// The TestComponent just wraps a button around that hook.
2024-07-24 18:42:21 -04:00
interface TestComponentProps {
setMicrophoneMuted: (muted: boolean) => void;
onButtonClick?: () => void;
}
const TestComponent: FC<TestComponentProps> = ({
setMicrophoneMuted,
onButtonClick = (): void => {},
}) => {
const ref = useRef<HTMLDivElement | null>(null);
useCallViewKeyboardShortcuts(
ref,
() => {},
() => {},
setMicrophoneMuted,
);
return (
<div ref={ref}>
2024-08-30 15:40:09 +02:00
<Button onClick={onButtonClick}>TEST</Button>
2024-07-24 18:42:21 -04:00
</div>
);
};
test("spacebar unmutes", async () => {
2024-09-05 16:55:38 -04:00
const user = userEvent.setup();
2024-07-24 18:42:21 -04:00
let muted = true;
2024-08-30 15:40:09 +02:00
render(
<TestComponent
onButtonClick={() => (muted = false)}
setMicrophoneMuted={(m) => {
muted = m;
}}
/>,
);
2024-07-24 18:42:21 -04:00
await user.keyboard("[Space>]");
expect(muted).toBe(false);
await user.keyboard("[/Space]");
2024-08-30 15:40:09 +02:00
2024-07-24 18:42:21 -04:00
expect(muted).toBe(true);
});
test("spacebar prioritizes pressing a button", async () => {
2024-09-05 16:55:38 -04:00
const user = userEvent.setup();
2024-08-30 15:40:09 +02:00
2024-07-24 18:42:21 -04:00
const setMuted = vi.fn();
const onClick = vi.fn();
render(
<TestComponent setMicrophoneMuted={setMuted} onButtonClick={onClick} />,
);
await user.tab(); // Focus the button
await user.keyboard("[Space]");
expect(setMuted).not.toBeCalled();
expect(onClick).toBeCalled();
});
test("unmuting happens in place of the default action", async () => {
2024-09-05 16:55:38 -04:00
const user = userEvent.setup();
2024-07-24 18:42:21 -04:00
const defaultPrevented = vi.fn();
// In the real application, we mostly just want the spacebar shortcut to avoid
// scrolling the page. But to test that here in JSDOM, we need some kind of
// container element that can be interactive and receive focus / keydown
// events. <video> is kind of a weird choice, but it'll do the job.
render(
<video
tabIndex={0}
onKeyDown={(e) => defaultPrevented(e.isDefaultPrevented())}
>
<TestComponent setMicrophoneMuted={() => {}} />
</video>,
);
await user.tab(); // Focus the <video>
await user.keyboard("[Space]");
expect(defaultPrevented).toBeCalledWith(true);
});