mirror of
https://github.com/vector-im/element-call.git
synced 2026-03-31 07:00:26 +00:00
Add tests for ReactionToggleButton
This commit is contained in:
195
src/button/ReactionToggleButton.test.tsx
Normal file
195
src/button/ReactionToggleButton.test.tsx
Normal file
@@ -0,0 +1,195 @@
|
||||
import { act, render } from "@testing-library/react";
|
||||
import { expect, test } from "vitest";
|
||||
import {
|
||||
MockRoom,
|
||||
MockRTCSession,
|
||||
TestReactionsWrapper,
|
||||
} from "../utils/testReactions";
|
||||
import { ReactionToggleButton } from "./ReactionToggleButton";
|
||||
import { MatrixRTCSession } from "matrix-js-sdk/src/matrixrtc";
|
||||
import { TooltipProvider } from "@vector-im/compound-web";
|
||||
import { ElementCallReactionEventType } from "../reactions";
|
||||
import { userEvent } from "@testing-library/user-event";
|
||||
|
||||
const memberUserIdAlice = "@alice:example.org";
|
||||
const memberEventAlice = "$membership-alice:example.org";
|
||||
|
||||
const membership: Record<string, string> = {
|
||||
[memberEventAlice]: memberUserIdAlice,
|
||||
};
|
||||
|
||||
function TestComponent({
|
||||
rtcSession,
|
||||
room,
|
||||
}: {
|
||||
rtcSession: MockRTCSession;
|
||||
room: MockRoom;
|
||||
}) {
|
||||
return (
|
||||
<TooltipProvider>
|
||||
<TestReactionsWrapper rtcSession={rtcSession}>
|
||||
<ReactionToggleButton
|
||||
rtcSession={rtcSession as unknown as MatrixRTCSession}
|
||||
client={room.client}
|
||||
></ReactionToggleButton>
|
||||
</TestReactionsWrapper>
|
||||
</TooltipProvider>
|
||||
);
|
||||
}
|
||||
|
||||
test("Can open menu", async () => {
|
||||
const room = new MockRoom(memberUserIdAlice);
|
||||
const rtcSession = new MockRTCSession(room, membership);
|
||||
const { getByRole, container } = render(
|
||||
<TestComponent rtcSession={rtcSession} room={room} />,
|
||||
);
|
||||
act(() => getByRole("button").click());
|
||||
expect(container).toMatchSnapshot();
|
||||
});
|
||||
|
||||
test("Can close menu", async () => {
|
||||
const room = new MockRoom(memberUserIdAlice);
|
||||
const rtcSession = new MockRTCSession(room, membership);
|
||||
const { getByRole, container } = render(
|
||||
<TestComponent rtcSession={rtcSession} room={room} />,
|
||||
);
|
||||
act(() => {
|
||||
getByRole("button").click();
|
||||
});
|
||||
act(() => getByRole("button", { expanded: true }).click());
|
||||
expect(container).toMatchSnapshot();
|
||||
});
|
||||
|
||||
test("Can raise hand", async () => {
|
||||
const room = new MockRoom(memberUserIdAlice);
|
||||
const rtcSession = new MockRTCSession(room, membership);
|
||||
const { getByRole, getByText, container } = render(
|
||||
<TestComponent rtcSession={rtcSession} room={room} />,
|
||||
);
|
||||
act(() => {
|
||||
getByRole("button").click();
|
||||
});
|
||||
act(() => {
|
||||
getByText("🖐️").click();
|
||||
});
|
||||
expect(room.testSentEvents).toEqual([
|
||||
[
|
||||
undefined,
|
||||
"m.reaction",
|
||||
{
|
||||
"m.relates_to": {
|
||||
event_id: memberEventAlice,
|
||||
key: "🖐️",
|
||||
rel_type: "m.annotation",
|
||||
},
|
||||
},
|
||||
],
|
||||
]);
|
||||
expect(container).toMatchSnapshot();
|
||||
});
|
||||
|
||||
test("Can can lower hand", async () => {
|
||||
const room = new MockRoom(memberUserIdAlice);
|
||||
const rtcSession = new MockRTCSession(room, membership);
|
||||
const { getByRole, getByText, container } = render(
|
||||
<TestComponent rtcSession={rtcSession} room={room} />,
|
||||
);
|
||||
const reactionEvent = room.testSendReaction(memberEventAlice, membership);
|
||||
act(() => {
|
||||
getByRole("button").click();
|
||||
});
|
||||
act(() => {
|
||||
getByText("🖐️").click();
|
||||
});
|
||||
expect(room.testRedactedEvents).toEqual([[undefined, reactionEvent]]);
|
||||
expect(container).toMatchSnapshot();
|
||||
});
|
||||
|
||||
test("Can react with emoji", async () => {
|
||||
const room = new MockRoom(memberUserIdAlice);
|
||||
const rtcSession = new MockRTCSession(room, membership);
|
||||
const { getByRole, getByText } = render(
|
||||
<TestComponent rtcSession={rtcSession} room={room} />,
|
||||
);
|
||||
act(() => {
|
||||
getByRole("button").click();
|
||||
});
|
||||
act(() => {
|
||||
getByText("🐶").click();
|
||||
});
|
||||
expect(room.testSentEvents).toEqual([
|
||||
[
|
||||
undefined,
|
||||
ElementCallReactionEventType,
|
||||
{
|
||||
"m.relates_to": {
|
||||
event_id: memberEventAlice,
|
||||
rel_type: "m.reference",
|
||||
},
|
||||
name: "dog",
|
||||
emoji: "🐶",
|
||||
},
|
||||
],
|
||||
]);
|
||||
});
|
||||
|
||||
test("Can search for and send emoji", async () => {
|
||||
const user = userEvent.setup();
|
||||
const room = new MockRoom(memberUserIdAlice);
|
||||
const rtcSession = new MockRTCSession(room, membership);
|
||||
const { getByText, getByRole, getByPlaceholderText, container } = render(
|
||||
<TestComponent rtcSession={rtcSession} room={room} />,
|
||||
);
|
||||
act(() => {
|
||||
getByRole("button").click();
|
||||
});
|
||||
act(() => {
|
||||
getByRole("button", {
|
||||
name: "Search",
|
||||
}).click();
|
||||
});
|
||||
await act(async () => {
|
||||
getByPlaceholderText("Search reactions…").focus();
|
||||
await user.keyboard("crickets");
|
||||
});
|
||||
expect(container).toMatchSnapshot();
|
||||
act(() => {
|
||||
getByText("🦗").click();
|
||||
});
|
||||
expect(room.testSentEvents).toEqual([
|
||||
[
|
||||
undefined,
|
||||
ElementCallReactionEventType,
|
||||
{
|
||||
"m.relates_to": {
|
||||
event_id: memberEventAlice,
|
||||
rel_type: "m.reference",
|
||||
},
|
||||
name: "crickets",
|
||||
emoji: "🦗",
|
||||
},
|
||||
],
|
||||
]);
|
||||
});
|
||||
|
||||
test("Can close search", async () => {
|
||||
const room = new MockRoom(memberUserIdAlice);
|
||||
const rtcSession = new MockRTCSession(room, membership);
|
||||
const { getByRole, container } = render(
|
||||
<TestComponent rtcSession={rtcSession} room={room} />,
|
||||
);
|
||||
act(() => {
|
||||
getByRole("button").click();
|
||||
});
|
||||
act(() => {
|
||||
getByRole("button", {
|
||||
name: "Search",
|
||||
}).click();
|
||||
});
|
||||
act(() => {
|
||||
getByRole("button", {
|
||||
name: "close search",
|
||||
}).click();
|
||||
});
|
||||
expect(container).toMatchSnapshot();
|
||||
});
|
||||
@@ -53,6 +53,7 @@ const InnerButton: FC<InnerButtonProps> = ({ raised, ...props }) => {
|
||||
<Tooltip label={t("action.raise_hand_or_send_reaction")}>
|
||||
<CpdButton
|
||||
className={classNames(raised && styles.raisedButton)}
|
||||
aria-expanded={raised}
|
||||
kind={raised ? "primary" : "secondary"}
|
||||
iconOnly
|
||||
Icon={RaisedHandSolidIcon}
|
||||
@@ -99,6 +100,8 @@ export function ReactionPopupMenu({
|
||||
<Tooltip label={t("common.raise_hand")}>
|
||||
<CpdButton
|
||||
kind={isHandRaised ? "primary" : "secondary"}
|
||||
aria-pressed={isHandRaised}
|
||||
aria-label="Toggle hand raised"
|
||||
className={styles.reactionButton}
|
||||
key="raise-hand"
|
||||
onClick={() => toggleRaisedHand()}
|
||||
@@ -124,6 +127,7 @@ export function ReactionPopupMenu({
|
||||
/>
|
||||
<CpdButton
|
||||
Icon={CloseIcon}
|
||||
aria-label="close search"
|
||||
size="sm"
|
||||
kind="destructive"
|
||||
onClick={() => setIsSearching(false)}
|
||||
@@ -134,12 +138,11 @@ export function ReactionPopupMenu({
|
||||
) : null}
|
||||
<menu>
|
||||
{filteredReactionSet.map((reaction) => (
|
||||
<li className={styles.reactionPopupMenuItem}>
|
||||
<li className={styles.reactionPopupMenuItem} key={reaction.name}>
|
||||
<Tooltip label={reaction.name}>
|
||||
<CpdButton
|
||||
kind="secondary"
|
||||
className={styles.reactionButton}
|
||||
key={reaction.name}
|
||||
disabled={!canReact}
|
||||
onClick={() => sendRelation(reaction)}
|
||||
>
|
||||
@@ -153,6 +156,7 @@ export function ReactionPopupMenu({
|
||||
<Tooltip label="Search">
|
||||
<CpdButton
|
||||
iconOnly
|
||||
aria-label="Open reactions search"
|
||||
Icon={SearchIcon}
|
||||
kind="tertiary"
|
||||
onClick={() => setIsSearching(true)}
|
||||
@@ -196,7 +200,6 @@ export function ReactionToggleButton({
|
||||
setBusy(true);
|
||||
await client.sendEvent(
|
||||
rtcSession.room.roomId,
|
||||
null,
|
||||
ElementCallReactionEventType,
|
||||
{
|
||||
"m.relates_to": {
|
||||
@@ -206,7 +209,6 @@ export function ReactionToggleButton({
|
||||
emoji: reaction.emoji,
|
||||
name: reaction.name,
|
||||
},
|
||||
undefined,
|
||||
);
|
||||
// Do NOT close the menu after this.
|
||||
} catch (ex) {
|
||||
|
||||
839
src/button/__snapshots__/ReactionToggleButton.test.tsx.snap
Normal file
839
src/button/__snapshots__/ReactionToggleButton.test.tsx.snap
Normal file
@@ -0,0 +1,839 @@
|
||||
// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
|
||||
|
||||
exports[`Can can lower hand 1`] = `
|
||||
<div>
|
||||
<button
|
||||
aria-disabled="true"
|
||||
aria-expanded="true"
|
||||
aria-labelledby=":r52:"
|
||||
class="_button_i91xf_17 raisedButton _has-icon_i91xf_66 _icon-only_i91xf_59"
|
||||
data-kind="primary"
|
||||
data-size="lg"
|
||||
role="button"
|
||||
tabindex="0"
|
||||
>
|
||||
<svg
|
||||
aria-hidden="true"
|
||||
fill="currentColor"
|
||||
height="24"
|
||||
viewBox="0 0 24 24"
|
||||
width="24"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
>
|
||||
<path
|
||||
d="M11 3a1 1 0 1 1 2 0v8.5a.5.5 0 0 0 1 0V4a1 1 0 1 1 2 0v10.2l3.284-2.597a1.081 1.081 0 0 1 1.47 1.577c-.613.673-1.214 1.367-1.818 2.064-1.267 1.463-2.541 2.934-3.944 4.235A6 6 0 0 1 5 15V7a1 1 0 0 1 2 0v5.5a.5.5 0 0 0 1 0V4a1 1 0 0 1 2 0v7.5a.5.5 0 0 0 1 0V3Z"
|
||||
/>
|
||||
</svg>
|
||||
</button>
|
||||
<div
|
||||
class="reactionPopupMenu"
|
||||
>
|
||||
<section
|
||||
class="handRaiseSection"
|
||||
>
|
||||
<button
|
||||
aria-label="Toggle hand raised"
|
||||
aria-labelledby=":r58:"
|
||||
aria-pressed="true"
|
||||
class="_button_i91xf_17 reactionButton"
|
||||
data-kind="primary"
|
||||
data-size="lg"
|
||||
role="button"
|
||||
tabindex="0"
|
||||
>
|
||||
🖐️
|
||||
</button>
|
||||
</section>
|
||||
<div
|
||||
class="verticalSeperator"
|
||||
/>
|
||||
<section>
|
||||
<menu>
|
||||
<li
|
||||
class="reactionPopupMenuItem"
|
||||
>
|
||||
<button
|
||||
aria-disabled="false"
|
||||
aria-labelledby=":r5d:"
|
||||
class="_button_i91xf_17 reactionButton"
|
||||
data-kind="secondary"
|
||||
data-size="lg"
|
||||
role="button"
|
||||
tabindex="0"
|
||||
>
|
||||
👍
|
||||
</button>
|
||||
</li>
|
||||
<li
|
||||
class="reactionPopupMenuItem"
|
||||
>
|
||||
<button
|
||||
aria-disabled="false"
|
||||
aria-labelledby=":r5i:"
|
||||
class="_button_i91xf_17 reactionButton"
|
||||
data-kind="secondary"
|
||||
data-size="lg"
|
||||
role="button"
|
||||
tabindex="0"
|
||||
>
|
||||
🎉
|
||||
</button>
|
||||
</li>
|
||||
<li
|
||||
class="reactionPopupMenuItem"
|
||||
>
|
||||
<button
|
||||
aria-disabled="false"
|
||||
aria-labelledby=":r5n:"
|
||||
class="_button_i91xf_17 reactionButton"
|
||||
data-kind="secondary"
|
||||
data-size="lg"
|
||||
role="button"
|
||||
tabindex="0"
|
||||
>
|
||||
👏
|
||||
</button>
|
||||
</li>
|
||||
<li
|
||||
class="reactionPopupMenuItem"
|
||||
>
|
||||
<button
|
||||
aria-disabled="false"
|
||||
aria-labelledby=":r5s:"
|
||||
class="_button_i91xf_17 reactionButton"
|
||||
data-kind="secondary"
|
||||
data-size="lg"
|
||||
role="button"
|
||||
tabindex="0"
|
||||
>
|
||||
🐶
|
||||
</button>
|
||||
</li>
|
||||
<li
|
||||
class="reactionPopupMenuItem"
|
||||
>
|
||||
<button
|
||||
aria-disabled="false"
|
||||
aria-labelledby=":r61:"
|
||||
class="_button_i91xf_17 reactionButton"
|
||||
data-kind="secondary"
|
||||
data-size="lg"
|
||||
role="button"
|
||||
tabindex="0"
|
||||
>
|
||||
🐱
|
||||
</button>
|
||||
</li>
|
||||
<li
|
||||
class="reactionPopupMenuItem"
|
||||
>
|
||||
<button
|
||||
aria-disabled="false"
|
||||
aria-labelledby=":r66:"
|
||||
class="_button_i91xf_17 reactionButton"
|
||||
data-kind="secondary"
|
||||
data-size="lg"
|
||||
role="button"
|
||||
tabindex="0"
|
||||
>
|
||||
💡
|
||||
</button>
|
||||
</li>
|
||||
<li
|
||||
class="reactionPopupMenuItem"
|
||||
>
|
||||
<button
|
||||
aria-label="Open reactions search"
|
||||
aria-labelledby=":r6b:"
|
||||
class="_button_i91xf_17 _has-icon_i91xf_66 _icon-only_i91xf_59"
|
||||
data-kind="tertiary"
|
||||
data-size="lg"
|
||||
role="button"
|
||||
tabindex="0"
|
||||
>
|
||||
<svg
|
||||
aria-hidden="true"
|
||||
fill="currentColor"
|
||||
height="24"
|
||||
viewBox="0 0 24 24"
|
||||
width="24"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
>
|
||||
<path
|
||||
d="M15.05 16.463a7.5 7.5 0 1 1 1.414-1.414l3.243 3.244a1 1 0 0 1-1.414 1.414l-3.244-3.244ZM16 10.5a5.5 5.5 0 1 0-11 0 5.5 5.5 0 0 0 11 0Z"
|
||||
/>
|
||||
</svg>
|
||||
</button>
|
||||
</li>
|
||||
</menu>
|
||||
</section>
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
|
||||
exports[`Can close menu 1`] = `
|
||||
<div>
|
||||
<button
|
||||
aria-disabled="false"
|
||||
aria-expanded="false"
|
||||
aria-labelledby=":r1m:"
|
||||
class="_button_i91xf_17 _has-icon_i91xf_66 _icon-only_i91xf_59"
|
||||
data-kind="secondary"
|
||||
data-size="lg"
|
||||
role="button"
|
||||
tabindex="0"
|
||||
>
|
||||
<svg
|
||||
aria-hidden="true"
|
||||
fill="currentColor"
|
||||
height="24"
|
||||
viewBox="0 0 24 24"
|
||||
width="24"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
>
|
||||
<path
|
||||
d="M11 3a1 1 0 1 1 2 0v8.5a.5.5 0 0 0 1 0V4a1 1 0 1 1 2 0v10.2l3.284-2.597a1.081 1.081 0 0 1 1.47 1.577c-.613.673-1.214 1.367-1.818 2.064-1.267 1.463-2.541 2.934-3.944 4.235A6 6 0 0 1 5 15V7a1 1 0 0 1 2 0v5.5a.5.5 0 0 0 1 0V4a1 1 0 0 1 2 0v7.5a.5.5 0 0 0 1 0V3Z"
|
||||
/>
|
||||
</svg>
|
||||
</button>
|
||||
</div>
|
||||
`;
|
||||
|
||||
exports[`Can close search 1`] = `
|
||||
<div>
|
||||
<button
|
||||
aria-disabled="false"
|
||||
aria-expanded="true"
|
||||
aria-labelledby=":rba:"
|
||||
class="_button_i91xf_17 raisedButton _has-icon_i91xf_66 _icon-only_i91xf_59"
|
||||
data-kind="primary"
|
||||
data-size="lg"
|
||||
role="button"
|
||||
tabindex="0"
|
||||
>
|
||||
<svg
|
||||
aria-hidden="true"
|
||||
fill="currentColor"
|
||||
height="24"
|
||||
viewBox="0 0 24 24"
|
||||
width="24"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
>
|
||||
<path
|
||||
d="M11 3a1 1 0 1 1 2 0v8.5a.5.5 0 0 0 1 0V4a1 1 0 1 1 2 0v10.2l3.284-2.597a1.081 1.081 0 0 1 1.47 1.577c-.613.673-1.214 1.367-1.818 2.064-1.267 1.463-2.541 2.934-3.944 4.235A6 6 0 0 1 5 15V7a1 1 0 0 1 2 0v5.5a.5.5 0 0 0 1 0V4a1 1 0 0 1 2 0v7.5a.5.5 0 0 0 1 0V3Z"
|
||||
/>
|
||||
</svg>
|
||||
</button>
|
||||
<div
|
||||
class="reactionPopupMenu"
|
||||
>
|
||||
<section
|
||||
class="handRaiseSection"
|
||||
>
|
||||
<button
|
||||
aria-label="Toggle hand raised"
|
||||
aria-labelledby=":rbg:"
|
||||
aria-pressed="false"
|
||||
class="_button_i91xf_17 reactionButton"
|
||||
data-kind="secondary"
|
||||
data-size="lg"
|
||||
role="button"
|
||||
tabindex="0"
|
||||
>
|
||||
🖐️
|
||||
</button>
|
||||
</section>
|
||||
<div
|
||||
class="verticalSeperator"
|
||||
/>
|
||||
<section>
|
||||
<menu>
|
||||
<li
|
||||
class="reactionPopupMenuItem"
|
||||
>
|
||||
<button
|
||||
aria-disabled="false"
|
||||
aria-labelledby=":rd2:"
|
||||
class="_button_i91xf_17 reactionButton"
|
||||
data-kind="secondary"
|
||||
data-size="lg"
|
||||
role="button"
|
||||
tabindex="0"
|
||||
>
|
||||
👍
|
||||
</button>
|
||||
</li>
|
||||
<li
|
||||
class="reactionPopupMenuItem"
|
||||
>
|
||||
<button
|
||||
aria-disabled="false"
|
||||
aria-labelledby=":rd7:"
|
||||
class="_button_i91xf_17 reactionButton"
|
||||
data-kind="secondary"
|
||||
data-size="lg"
|
||||
role="button"
|
||||
tabindex="0"
|
||||
>
|
||||
🎉
|
||||
</button>
|
||||
</li>
|
||||
<li
|
||||
class="reactionPopupMenuItem"
|
||||
>
|
||||
<button
|
||||
aria-disabled="false"
|
||||
aria-labelledby=":rdc:"
|
||||
class="_button_i91xf_17 reactionButton"
|
||||
data-kind="secondary"
|
||||
data-size="lg"
|
||||
role="button"
|
||||
tabindex="0"
|
||||
>
|
||||
👏
|
||||
</button>
|
||||
</li>
|
||||
<li
|
||||
class="reactionPopupMenuItem"
|
||||
>
|
||||
<button
|
||||
aria-disabled="false"
|
||||
aria-labelledby=":rdh:"
|
||||
class="_button_i91xf_17 reactionButton"
|
||||
data-kind="secondary"
|
||||
data-size="lg"
|
||||
role="button"
|
||||
tabindex="0"
|
||||
>
|
||||
🐶
|
||||
</button>
|
||||
</li>
|
||||
<li
|
||||
class="reactionPopupMenuItem"
|
||||
>
|
||||
<button
|
||||
aria-disabled="false"
|
||||
aria-labelledby=":rdm:"
|
||||
class="_button_i91xf_17 reactionButton"
|
||||
data-kind="secondary"
|
||||
data-size="lg"
|
||||
role="button"
|
||||
tabindex="0"
|
||||
>
|
||||
🐱
|
||||
</button>
|
||||
</li>
|
||||
<li
|
||||
class="reactionPopupMenuItem"
|
||||
>
|
||||
<button
|
||||
aria-disabled="false"
|
||||
aria-labelledby=":rdr:"
|
||||
class="_button_i91xf_17 reactionButton"
|
||||
data-kind="secondary"
|
||||
data-size="lg"
|
||||
role="button"
|
||||
tabindex="0"
|
||||
>
|
||||
💡
|
||||
</button>
|
||||
</li>
|
||||
<li
|
||||
class="reactionPopupMenuItem"
|
||||
>
|
||||
<button
|
||||
aria-label="Open reactions search"
|
||||
aria-labelledby=":re0:"
|
||||
class="_button_i91xf_17 _has-icon_i91xf_66 _icon-only_i91xf_59"
|
||||
data-kind="tertiary"
|
||||
data-size="lg"
|
||||
role="button"
|
||||
tabindex="0"
|
||||
>
|
||||
<svg
|
||||
aria-hidden="true"
|
||||
fill="currentColor"
|
||||
height="24"
|
||||
viewBox="0 0 24 24"
|
||||
width="24"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
>
|
||||
<path
|
||||
d="M15.05 16.463a7.5 7.5 0 1 1 1.414-1.414l3.243 3.244a1 1 0 0 1-1.414 1.414l-3.244-3.244ZM16 10.5a5.5 5.5 0 1 0-11 0 5.5 5.5 0 0 0 11 0Z"
|
||||
/>
|
||||
</svg>
|
||||
</button>
|
||||
</li>
|
||||
</menu>
|
||||
</section>
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
|
||||
exports[`Can open menu 1`] = `
|
||||
<div>
|
||||
<button
|
||||
aria-disabled="false"
|
||||
aria-expanded="true"
|
||||
aria-labelledby=":r0:"
|
||||
class="_button_i91xf_17 raisedButton _has-icon_i91xf_66 _icon-only_i91xf_59"
|
||||
data-kind="primary"
|
||||
data-size="lg"
|
||||
role="button"
|
||||
tabindex="0"
|
||||
>
|
||||
<svg
|
||||
aria-hidden="true"
|
||||
fill="currentColor"
|
||||
height="24"
|
||||
viewBox="0 0 24 24"
|
||||
width="24"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
>
|
||||
<path
|
||||
d="M11 3a1 1 0 1 1 2 0v8.5a.5.5 0 0 0 1 0V4a1 1 0 1 1 2 0v10.2l3.284-2.597a1.081 1.081 0 0 1 1.47 1.577c-.613.673-1.214 1.367-1.818 2.064-1.267 1.463-2.541 2.934-3.944 4.235A6 6 0 0 1 5 15V7a1 1 0 0 1 2 0v5.5a.5.5 0 0 0 1 0V4a1 1 0 0 1 2 0v7.5a.5.5 0 0 0 1 0V3Z"
|
||||
/>
|
||||
</svg>
|
||||
</button>
|
||||
<div
|
||||
class="reactionPopupMenu"
|
||||
>
|
||||
<section
|
||||
class="handRaiseSection"
|
||||
>
|
||||
<button
|
||||
aria-label="Toggle hand raised"
|
||||
aria-labelledby=":r6:"
|
||||
aria-pressed="false"
|
||||
class="_button_i91xf_17 reactionButton"
|
||||
data-kind="secondary"
|
||||
data-size="lg"
|
||||
role="button"
|
||||
tabindex="0"
|
||||
>
|
||||
🖐️
|
||||
</button>
|
||||
</section>
|
||||
<div
|
||||
class="verticalSeperator"
|
||||
/>
|
||||
<section>
|
||||
<menu>
|
||||
<li
|
||||
class="reactionPopupMenuItem"
|
||||
>
|
||||
<button
|
||||
aria-disabled="false"
|
||||
aria-labelledby=":rb:"
|
||||
class="_button_i91xf_17 reactionButton"
|
||||
data-kind="secondary"
|
||||
data-size="lg"
|
||||
role="button"
|
||||
tabindex="0"
|
||||
>
|
||||
👍
|
||||
</button>
|
||||
</li>
|
||||
<li
|
||||
class="reactionPopupMenuItem"
|
||||
>
|
||||
<button
|
||||
aria-disabled="false"
|
||||
aria-labelledby=":rg:"
|
||||
class="_button_i91xf_17 reactionButton"
|
||||
data-kind="secondary"
|
||||
data-size="lg"
|
||||
role="button"
|
||||
tabindex="0"
|
||||
>
|
||||
🎉
|
||||
</button>
|
||||
</li>
|
||||
<li
|
||||
class="reactionPopupMenuItem"
|
||||
>
|
||||
<button
|
||||
aria-disabled="false"
|
||||
aria-labelledby=":rl:"
|
||||
class="_button_i91xf_17 reactionButton"
|
||||
data-kind="secondary"
|
||||
data-size="lg"
|
||||
role="button"
|
||||
tabindex="0"
|
||||
>
|
||||
👏
|
||||
</button>
|
||||
</li>
|
||||
<li
|
||||
class="reactionPopupMenuItem"
|
||||
>
|
||||
<button
|
||||
aria-disabled="false"
|
||||
aria-labelledby=":rq:"
|
||||
class="_button_i91xf_17 reactionButton"
|
||||
data-kind="secondary"
|
||||
data-size="lg"
|
||||
role="button"
|
||||
tabindex="0"
|
||||
>
|
||||
🐶
|
||||
</button>
|
||||
</li>
|
||||
<li
|
||||
class="reactionPopupMenuItem"
|
||||
>
|
||||
<button
|
||||
aria-disabled="false"
|
||||
aria-labelledby=":rv:"
|
||||
class="_button_i91xf_17 reactionButton"
|
||||
data-kind="secondary"
|
||||
data-size="lg"
|
||||
role="button"
|
||||
tabindex="0"
|
||||
>
|
||||
🐱
|
||||
</button>
|
||||
</li>
|
||||
<li
|
||||
class="reactionPopupMenuItem"
|
||||
>
|
||||
<button
|
||||
aria-disabled="false"
|
||||
aria-labelledby=":r14:"
|
||||
class="_button_i91xf_17 reactionButton"
|
||||
data-kind="secondary"
|
||||
data-size="lg"
|
||||
role="button"
|
||||
tabindex="0"
|
||||
>
|
||||
💡
|
||||
</button>
|
||||
</li>
|
||||
<li
|
||||
class="reactionPopupMenuItem"
|
||||
>
|
||||
<button
|
||||
aria-label="Open reactions search"
|
||||
aria-labelledby=":r19:"
|
||||
class="_button_i91xf_17 _has-icon_i91xf_66 _icon-only_i91xf_59"
|
||||
data-kind="tertiary"
|
||||
data-size="lg"
|
||||
role="button"
|
||||
tabindex="0"
|
||||
>
|
||||
<svg
|
||||
aria-hidden="true"
|
||||
fill="currentColor"
|
||||
height="24"
|
||||
viewBox="0 0 24 24"
|
||||
width="24"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
>
|
||||
<path
|
||||
d="M15.05 16.463a7.5 7.5 0 1 1 1.414-1.414l3.243 3.244a1 1 0 0 1-1.414 1.414l-3.244-3.244ZM16 10.5a5.5 5.5 0 1 0-11 0 5.5 5.5 0 0 0 11 0Z"
|
||||
/>
|
||||
</svg>
|
||||
</button>
|
||||
</li>
|
||||
</menu>
|
||||
</section>
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
|
||||
exports[`Can raise hand 1`] = `
|
||||
<div>
|
||||
<button
|
||||
aria-disabled="true"
|
||||
aria-expanded="true"
|
||||
aria-labelledby=":r3c:"
|
||||
class="_button_i91xf_17 raisedButton _has-icon_i91xf_66 _icon-only_i91xf_59"
|
||||
data-kind="primary"
|
||||
data-size="lg"
|
||||
role="button"
|
||||
tabindex="0"
|
||||
>
|
||||
<svg
|
||||
aria-hidden="true"
|
||||
fill="currentColor"
|
||||
height="24"
|
||||
viewBox="0 0 24 24"
|
||||
width="24"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
>
|
||||
<path
|
||||
d="M11 3a1 1 0 1 1 2 0v8.5a.5.5 0 0 0 1 0V4a1 1 0 1 1 2 0v10.2l3.284-2.597a1.081 1.081 0 0 1 1.47 1.577c-.613.673-1.214 1.367-1.818 2.064-1.267 1.463-2.541 2.934-3.944 4.235A6 6 0 0 1 5 15V7a1 1 0 0 1 2 0v5.5a.5.5 0 0 0 1 0V4a1 1 0 0 1 2 0v7.5a.5.5 0 0 0 1 0V3Z"
|
||||
/>
|
||||
</svg>
|
||||
</button>
|
||||
<div
|
||||
class="reactionPopupMenu"
|
||||
>
|
||||
<section
|
||||
class="handRaiseSection"
|
||||
>
|
||||
<button
|
||||
aria-label="Toggle hand raised"
|
||||
aria-labelledby=":r3i:"
|
||||
aria-pressed="false"
|
||||
class="_button_i91xf_17 reactionButton"
|
||||
data-kind="secondary"
|
||||
data-size="lg"
|
||||
role="button"
|
||||
tabindex="0"
|
||||
>
|
||||
🖐️
|
||||
</button>
|
||||
</section>
|
||||
<div
|
||||
class="verticalSeperator"
|
||||
/>
|
||||
<section>
|
||||
<menu>
|
||||
<li
|
||||
class="reactionPopupMenuItem"
|
||||
>
|
||||
<button
|
||||
aria-disabled="false"
|
||||
aria-labelledby=":r3n:"
|
||||
class="_button_i91xf_17 reactionButton"
|
||||
data-kind="secondary"
|
||||
data-size="lg"
|
||||
role="button"
|
||||
tabindex="0"
|
||||
>
|
||||
👍
|
||||
</button>
|
||||
</li>
|
||||
<li
|
||||
class="reactionPopupMenuItem"
|
||||
>
|
||||
<button
|
||||
aria-disabled="false"
|
||||
aria-labelledby=":r3s:"
|
||||
class="_button_i91xf_17 reactionButton"
|
||||
data-kind="secondary"
|
||||
data-size="lg"
|
||||
role="button"
|
||||
tabindex="0"
|
||||
>
|
||||
🎉
|
||||
</button>
|
||||
</li>
|
||||
<li
|
||||
class="reactionPopupMenuItem"
|
||||
>
|
||||
<button
|
||||
aria-disabled="false"
|
||||
aria-labelledby=":r41:"
|
||||
class="_button_i91xf_17 reactionButton"
|
||||
data-kind="secondary"
|
||||
data-size="lg"
|
||||
role="button"
|
||||
tabindex="0"
|
||||
>
|
||||
👏
|
||||
</button>
|
||||
</li>
|
||||
<li
|
||||
class="reactionPopupMenuItem"
|
||||
>
|
||||
<button
|
||||
aria-disabled="false"
|
||||
aria-labelledby=":r46:"
|
||||
class="_button_i91xf_17 reactionButton"
|
||||
data-kind="secondary"
|
||||
data-size="lg"
|
||||
role="button"
|
||||
tabindex="0"
|
||||
>
|
||||
🐶
|
||||
</button>
|
||||
</li>
|
||||
<li
|
||||
class="reactionPopupMenuItem"
|
||||
>
|
||||
<button
|
||||
aria-disabled="false"
|
||||
aria-labelledby=":r4b:"
|
||||
class="_button_i91xf_17 reactionButton"
|
||||
data-kind="secondary"
|
||||
data-size="lg"
|
||||
role="button"
|
||||
tabindex="0"
|
||||
>
|
||||
🐱
|
||||
</button>
|
||||
</li>
|
||||
<li
|
||||
class="reactionPopupMenuItem"
|
||||
>
|
||||
<button
|
||||
aria-disabled="false"
|
||||
aria-labelledby=":r4g:"
|
||||
class="_button_i91xf_17 reactionButton"
|
||||
data-kind="secondary"
|
||||
data-size="lg"
|
||||
role="button"
|
||||
tabindex="0"
|
||||
>
|
||||
💡
|
||||
</button>
|
||||
</li>
|
||||
<li
|
||||
class="reactionPopupMenuItem"
|
||||
>
|
||||
<button
|
||||
aria-label="Open reactions search"
|
||||
aria-labelledby=":r4l:"
|
||||
class="_button_i91xf_17 _has-icon_i91xf_66 _icon-only_i91xf_59"
|
||||
data-kind="tertiary"
|
||||
data-size="lg"
|
||||
role="button"
|
||||
tabindex="0"
|
||||
>
|
||||
<svg
|
||||
aria-hidden="true"
|
||||
fill="currentColor"
|
||||
height="24"
|
||||
viewBox="0 0 24 24"
|
||||
width="24"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
>
|
||||
<path
|
||||
d="M15.05 16.463a7.5 7.5 0 1 1 1.414-1.414l3.243 3.244a1 1 0 0 1-1.414 1.414l-3.244-3.244ZM16 10.5a5.5 5.5 0 1 0-11 0 5.5 5.5 0 0 0 11 0Z"
|
||||
/>
|
||||
</svg>
|
||||
</button>
|
||||
</li>
|
||||
</menu>
|
||||
</section>
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
|
||||
exports[`Can search for and send emoji 1`] = `
|
||||
<div>
|
||||
<button
|
||||
aria-disabled="false"
|
||||
aria-expanded="true"
|
||||
aria-labelledby=":r8e:"
|
||||
class="_button_i91xf_17 raisedButton _has-icon_i91xf_66 _icon-only_i91xf_59"
|
||||
data-kind="primary"
|
||||
data-size="lg"
|
||||
role="button"
|
||||
tabindex="0"
|
||||
>
|
||||
<svg
|
||||
aria-hidden="true"
|
||||
fill="currentColor"
|
||||
height="24"
|
||||
viewBox="0 0 24 24"
|
||||
width="24"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
>
|
||||
<path
|
||||
d="M11 3a1 1 0 1 1 2 0v8.5a.5.5 0 0 0 1 0V4a1 1 0 1 1 2 0v10.2l3.284-2.597a1.081 1.081 0 0 1 1.47 1.577c-.613.673-1.214 1.367-1.818 2.064-1.267 1.463-2.541 2.934-3.944 4.235A6 6 0 0 1 5 15V7a1 1 0 0 1 2 0v5.5a.5.5 0 0 0 1 0V4a1 1 0 0 1 2 0v7.5a.5.5 0 0 0 1 0V3Z"
|
||||
/>
|
||||
</svg>
|
||||
</button>
|
||||
<div
|
||||
class="reactionPopupMenu"
|
||||
>
|
||||
<section
|
||||
class="handRaiseSection"
|
||||
>
|
||||
<button
|
||||
aria-label="Toggle hand raised"
|
||||
aria-labelledby=":r8k:"
|
||||
aria-pressed="false"
|
||||
class="_button_i91xf_17 reactionButton"
|
||||
data-kind="secondary"
|
||||
data-size="lg"
|
||||
role="button"
|
||||
tabindex="0"
|
||||
>
|
||||
🖐️
|
||||
</button>
|
||||
</section>
|
||||
<div
|
||||
class="verticalSeperator"
|
||||
/>
|
||||
<section>
|
||||
<form
|
||||
class="_root_dgy0u_24 searchForm"
|
||||
>
|
||||
<label
|
||||
class="_label_dgy0u_67 _field_dgy0u_34 _search_qztja_17"
|
||||
for=":ra4:"
|
||||
>
|
||||
<svg
|
||||
class="_icon_qztja_46"
|
||||
fill="currentColor"
|
||||
height="20"
|
||||
viewBox="0 0 24 24"
|
||||
width="20"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
>
|
||||
<path
|
||||
d="M15.05 16.463a7.5 7.5 0 1 1 1.414-1.414l3.243 3.244a1 1 0 0 1-1.414 1.414l-3.244-3.244ZM16 10.5a5.5 5.5 0 1 0-11 0 5.5 5.5 0 0 0 11 0Z"
|
||||
/>
|
||||
</svg>
|
||||
<input
|
||||
class="_input_qztja_61"
|
||||
id=":ra4:"
|
||||
name="reactionSearch"
|
||||
placeholder="Search reactions…"
|
||||
type="search"
|
||||
value="crickets"
|
||||
/>
|
||||
</label>
|
||||
<button
|
||||
aria-label="close search"
|
||||
class="_button_i91xf_17 _has-icon_i91xf_66 _destructive_i91xf_116"
|
||||
data-kind="secondary"
|
||||
data-size="sm"
|
||||
role="button"
|
||||
tabindex="0"
|
||||
>
|
||||
<svg
|
||||
aria-hidden="true"
|
||||
fill="currentColor"
|
||||
height="20"
|
||||
viewBox="0 0 24 24"
|
||||
width="20"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
>
|
||||
<path
|
||||
d="M6.293 6.293a1 1 0 0 1 1.414 0L12 10.586l4.293-4.293a1 1 0 1 1 1.414 1.414L13.414 12l4.293 4.293a1 1 0 0 1-1.414 1.414L12 13.414l-4.293 4.293a1 1 0 0 1-1.414-1.414L10.586 12 6.293 7.707a1 1 0 0 1 0-1.414Z"
|
||||
/>
|
||||
</svg>
|
||||
</button>
|
||||
</form>
|
||||
<div
|
||||
class="_separator_144s5_17"
|
||||
data-kind="primary"
|
||||
data-orientation="horizontal"
|
||||
role="separator"
|
||||
/>
|
||||
<menu>
|
||||
<li
|
||||
class="reactionPopupMenuItem"
|
||||
>
|
||||
<button
|
||||
aria-disabled="false"
|
||||
aria-labelledby=":rag:"
|
||||
class="_button_i91xf_17 reactionButton"
|
||||
data-kind="secondary"
|
||||
data-size="lg"
|
||||
role="button"
|
||||
tabindex="0"
|
||||
>
|
||||
🦗
|
||||
</button>
|
||||
</li>
|
||||
</menu>
|
||||
</section>
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
@@ -15,8 +15,8 @@ import {
|
||||
createRedaction,
|
||||
MockRoom,
|
||||
MockRTCSession,
|
||||
TestComponentWrapper,
|
||||
} from "./utils/test-reactions";
|
||||
TestReactionsWrapper,
|
||||
} from "./utils/testReactions";
|
||||
import { RoomEvent } from "matrix-js-sdk/src/matrix";
|
||||
|
||||
const memberUserIdAlice = "@alice:example.org";
|
||||
@@ -61,9 +61,9 @@ describe("useReactions", () => {
|
||||
membership,
|
||||
);
|
||||
const { queryByRole } = render(
|
||||
<TestComponentWrapper rtcSession={rtcSession}>
|
||||
<TestReactionsWrapper rtcSession={rtcSession}>
|
||||
<TestComponent />
|
||||
</TestComponentWrapper>,
|
||||
</TestReactionsWrapper>,
|
||||
);
|
||||
expect(queryByRole("list")?.children).to.have.lengthOf(0);
|
||||
});
|
||||
@@ -71,9 +71,9 @@ describe("useReactions", () => {
|
||||
const room = new MockRoom(memberUserIdAlice);
|
||||
const rtcSession = new MockRTCSession(room, membership);
|
||||
const { queryByText } = render(
|
||||
<TestComponentWrapper rtcSession={rtcSession}>
|
||||
<TestReactionsWrapper rtcSession={rtcSession}>
|
||||
<TestComponent />
|
||||
</TestComponentWrapper>,
|
||||
</TestReactionsWrapper>,
|
||||
);
|
||||
await act(() => room.testSendReaction(memberEventAlice, membership));
|
||||
expect(queryByText("Local reaction")).toBeTruthy();
|
||||
@@ -82,9 +82,9 @@ describe("useReactions", () => {
|
||||
const room = new MockRoom(memberUserIdAlice);
|
||||
const rtcSession = new MockRTCSession(room, membership);
|
||||
const { queryByRole } = render(
|
||||
<TestComponentWrapper rtcSession={rtcSession}>
|
||||
<TestReactionsWrapper rtcSession={rtcSession}>
|
||||
<TestComponent />
|
||||
</TestComponentWrapper>,
|
||||
</TestReactionsWrapper>,
|
||||
);
|
||||
await act(() => room.testSendReaction(memberEventAlice, membership));
|
||||
expect(queryByRole("list")?.children).to.have.lengthOf(1);
|
||||
@@ -95,9 +95,9 @@ describe("useReactions", () => {
|
||||
const room = new MockRoom(memberUserIdAlice);
|
||||
const rtcSession = new MockRTCSession(room, membership);
|
||||
const { queryByRole } = render(
|
||||
<TestComponentWrapper rtcSession={rtcSession}>
|
||||
<TestReactionsWrapper rtcSession={rtcSession}>
|
||||
<TestComponent />
|
||||
</TestComponentWrapper>,
|
||||
</TestReactionsWrapper>,
|
||||
);
|
||||
const reactionEventId = await act(() =>
|
||||
room.testSendReaction(memberEventAlice, membership),
|
||||
@@ -119,9 +119,9 @@ describe("useReactions", () => {
|
||||
]);
|
||||
const rtcSession = new MockRTCSession(room, membership);
|
||||
const { queryByRole } = render(
|
||||
<TestComponentWrapper rtcSession={rtcSession}>
|
||||
<TestReactionsWrapper rtcSession={rtcSession}>
|
||||
<TestComponent />
|
||||
</TestComponentWrapper>,
|
||||
</TestReactionsWrapper>,
|
||||
);
|
||||
expect(queryByRole("list")?.children).to.have.lengthOf(1);
|
||||
});
|
||||
@@ -133,9 +133,9 @@ describe("useReactions", () => {
|
||||
]);
|
||||
const rtcSession = new MockRTCSession(room, membership);
|
||||
const { queryByRole } = render(
|
||||
<TestComponentWrapper rtcSession={rtcSession}>
|
||||
<TestReactionsWrapper rtcSession={rtcSession}>
|
||||
<TestComponent />
|
||||
</TestComponentWrapper>,
|
||||
</TestReactionsWrapper>,
|
||||
);
|
||||
expect(queryByRole("list")?.children).to.have.lengthOf(1);
|
||||
act(() => rtcSession.testRemoveMember(memberUserIdAlice));
|
||||
@@ -147,9 +147,9 @@ describe("useReactions", () => {
|
||||
]);
|
||||
const rtcSession = new MockRTCSession(room, membership);
|
||||
const { queryByRole } = render(
|
||||
<TestComponentWrapper rtcSession={rtcSession}>
|
||||
<TestReactionsWrapper rtcSession={rtcSession}>
|
||||
<TestComponent />
|
||||
</TestComponentWrapper>,
|
||||
</TestReactionsWrapper>,
|
||||
);
|
||||
expect(queryByRole("list")?.children).to.have.lengthOf(1);
|
||||
// Simulate leaving and rejoining
|
||||
@@ -161,13 +161,13 @@ describe("useReactions", () => {
|
||||
});
|
||||
test("ignores invalid sender for historic event", () => {
|
||||
const room = new MockRoom(memberUserIdAlice, [
|
||||
createReaction(memberEventAlice, membership),
|
||||
createReaction(memberEventAlice, memberUserIdBob),
|
||||
]);
|
||||
const rtcSession = new MockRTCSession(room, membership);
|
||||
const { queryByRole } = render(
|
||||
<TestComponentWrapper rtcSession={rtcSession}>
|
||||
<TestReactionsWrapper rtcSession={rtcSession}>
|
||||
<TestComponent />
|
||||
</TestComponentWrapper>,
|
||||
</TestReactionsWrapper>,
|
||||
);
|
||||
expect(queryByRole("list")?.children).to.have.lengthOf(0);
|
||||
});
|
||||
@@ -175,9 +175,9 @@ describe("useReactions", () => {
|
||||
const room = new MockRoom(memberUserIdAlice);
|
||||
const rtcSession = new MockRTCSession(room, membership);
|
||||
const { queryByRole } = render(
|
||||
<TestComponentWrapper rtcSession={rtcSession}>
|
||||
<TestReactionsWrapper rtcSession={rtcSession}>
|
||||
<TestComponent />
|
||||
</TestComponentWrapper>,
|
||||
</TestReactionsWrapper>,
|
||||
);
|
||||
await act(() => room.testSendReaction(memberEventAlice, memberUserIdBob));
|
||||
expect(queryByRole("list")?.children).to.have.lengthOf(0);
|
||||
|
||||
@@ -15,7 +15,7 @@ import {
|
||||
MatrixRTCSessionEvent,
|
||||
} from "matrix-js-sdk/src/matrixrtc";
|
||||
|
||||
export const TestComponentWrapper = ({
|
||||
export const TestReactionsWrapper = ({
|
||||
rtcSession,
|
||||
children,
|
||||
}: PropsWithChildren<{
|
||||
@@ -98,6 +98,9 @@ export function createRedaction(
|
||||
}
|
||||
|
||||
export class MockRoom extends EventEmitter {
|
||||
public readonly testSentEvents: Parameters<MatrixClient["sendEvent"]>[] = [];
|
||||
public readonly testRedactedEvents: Parameters<MatrixClient["redactEvent"]>[] = [];
|
||||
|
||||
public constructor(
|
||||
private readonly ownUserId: string,
|
||||
private readonly existingRelations: MatrixEvent[] = [],
|
||||
@@ -108,6 +111,18 @@ export class MockRoom extends EventEmitter {
|
||||
public get client(): MatrixClient {
|
||||
return {
|
||||
getUserId: (): string => this.ownUserId,
|
||||
sendEvent: async (
|
||||
...props: Parameters<MatrixClient["sendEvent"]>
|
||||
): ReturnType<MatrixClient["sendEvent"]> => {
|
||||
this.testSentEvents.push(props);
|
||||
return { event_id: randomUUID() };
|
||||
},
|
||||
redactEvent: async (
|
||||
...props: Parameters<MatrixClient["redactEvent"]>
|
||||
): ReturnType<MatrixClient["redactEvent"]> => {
|
||||
this.testRedactedEvents.push(props);
|
||||
return { event_id: randomUUID() };
|
||||
},
|
||||
} as unknown as MatrixClient;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user