Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,42 +1,57 @@
import { render, screen } from '@testing-library/react';
import userEvent from '@testing-library/user-event';
import BrainLeftSidebarWave from '@/components/brain/left-sidebar/waves/BrainLeftSidebarWave';
import { ApiWaveType } from '@/generated/models/ApiWaveType';
import { usePrefetchWaveData } from '@/hooks/usePrefetchWaveData';
import { useMyStream } from '@/contexts/wave/MyStreamContext';
import { render, screen } from "@testing-library/react";
import userEvent from "@testing-library/user-event";
import BrainLeftSidebarWave from "@/components/brain/left-sidebar/waves/BrainLeftSidebarWave";
import { ApiWaveType } from "@/generated/models/ApiWaveType";
import { usePrefetchWaveData } from "@/hooks/usePrefetchWaveData";
import { useMyStream } from "@/contexts/wave/MyStreamContext";

jest.mock('next/link', () => ({
jest.mock("next/link", () => ({
__esModule: true,
default: ({ href, children, onMouseEnter, onClick, className }: any) => (
<a href={href} onMouseEnter={onMouseEnter} onClick={onClick} className={className}>{children}</a>
<a
href={href}
onMouseEnter={onMouseEnter}
onClick={onClick}
className={className}
>
{children}
</a>
),
}));
jest.mock('@/hooks/useDeviceInfo', () => ({
jest.mock("@/hooks/useDeviceInfo", () => ({
__esModule: true,
default: () => ({ isApp: false }),
}));
jest.mock('@/contexts/wave/MyStreamContext', () => ({
jest.mock("@/contexts/wave/MyStreamContext", () => ({
useMyStream: jest.fn(),
}));
jest.mock('@/hooks/usePrefetchWaveData');
jest.mock('@/components/waves/WavePicture', () => (props: any) => <img data-testid="wave-picture" alt={props.name} />);
jest.mock('@/components/brain/left-sidebar/waves/BrainLeftSidebarWaveDropTime', () => (props: any) => <span data-testid="drop-time">{props.time}</span>);
jest.mock('@/components/brain/left-sidebar/waves/BrainLeftSidebarWavePin', () => (props: any) => <div data-testid="pin">{String(props.isPinned)}</div>);
jest.mock("@/hooks/usePrefetchWaveData");
jest.mock("@/components/waves/WavePicture", () => (props: any) => (
<img data-testid="wave-picture" alt={props.name} />
));
jest.mock(
"@/components/brain/left-sidebar/waves/BrainLeftSidebarWaveDropTime",
() => (props: any) => <span data-testid="drop-time">{props.time}</span>
);
jest.mock(
"@/components/brain/left-sidebar/waves/BrainLeftSidebarWavePin",
() => (props: any) => <div data-testid="pin">{String(props.isPinned)}</div>
);

const mockedPrefetch = usePrefetchWaveData as jest.Mock;
const mockedUseMyStream = useMyStream as jest.Mock;

describe('BrainLeftSidebarWave', () => {
describe("BrainLeftSidebarWave", () => {
const prefetch = jest.fn();
const onHover = jest.fn();
const setActiveWave = jest.fn();
let activeWaveId: string | null = null;

const baseWave = {
id: '1',
id: "1",
type: ApiWaveType.Chat,
name: 'Chat Wave',
picture: '',
name: "Chat Wave",
picture: "",
contributors: [],
newDropsCount: { count: 2, latestDropTimestamp: 123 },
isPinned: false,
Expand All @@ -55,72 +70,92 @@ describe('BrainLeftSidebarWave', () => {
}));
});

it('prefetches wave data on hover when not active', async () => {
it("prefetches wave data on hover when not active", async () => {
render(<BrainLeftSidebarWave wave={baseWave} onHover={onHover} />);
const link = screen.getByRole('link');
const link = screen.getByRole("link");
await userEvent.hover(link);
expect(onHover).toHaveBeenCalledWith('1');
expect(prefetch).toHaveBeenCalledWith('1');
expect(onHover).toHaveBeenCalledWith("1");
expect(prefetch).toHaveBeenCalledWith("1");
});

it('does not prefetch when hovering active wave', async () => {
activeWaveId = '1';
it("does not prefetch when hovering active wave", async () => {
activeWaveId = "1";
mockedUseMyStream.mockImplementation(() => ({
activeWave: { id: activeWaveId, set: setActiveWave },
}));
render(<BrainLeftSidebarWave wave={baseWave} onHover={onHover} />);
await userEvent.hover(screen.getByRole('link'));
await userEvent.hover(screen.getByRole("link"));
expect(onHover).not.toHaveBeenCalled();
expect(prefetch).not.toHaveBeenCalled();
});

it('computes href based on current wave', () => {
const { rerender } = render(<BrainLeftSidebarWave wave={baseWave} onHover={onHover} />);
expect(screen.getByRole('link')).toHaveAttribute('href', '/waves?wave=1');
activeWaveId = '1';
it("computes href based on current wave", () => {
const { rerender } = render(
<BrainLeftSidebarWave wave={baseWave} onHover={onHover} />
);
expect(screen.getByRole("link")).toHaveAttribute("href", "/waves?wave=1");
activeWaveId = "1";
mockedUseMyStream.mockImplementation(() => ({
activeWave: { id: activeWaveId, set: setActiveWave },
}));
rerender(<BrainLeftSidebarWave wave={baseWave} onHover={onHover} />);
expect(screen.getByRole('link')).toHaveAttribute('href', '/waves');
expect(screen.getByRole("link")).toHaveAttribute("href", "/waves");
});

it('pushes shallow route on click', async () => {
it("pushes shallow route on click", async () => {
render(<BrainLeftSidebarWave wave={baseWave} onHover={onHover} />);
const link = screen.getByRole('link');
const link = screen.getByRole("link");
await userEvent.click(link);
expect(setActiveWave).toHaveBeenCalledWith('1', { isDirectMessage: false, divider: null });
expect(setActiveWave).toHaveBeenCalledWith("1", {
isDirectMessage: false,
divider: null,
});
});

it('shows drop indicators for non-chat waves', () => {
const dropWave = { ...baseWave, id: '2', type: ApiWaveType.Approve };
it("shows drop indicators for non-chat waves", () => {
const dropWave = { ...baseWave, id: "2", type: ApiWaveType.Approve };
render(<BrainLeftSidebarWave wave={dropWave} onHover={onHover} />);
expect(screen.getByTestId('drop-time')).toHaveTextContent('123');
expect(screen.getByTestId("drop-time")).toHaveTextContent("123");
});

it('includes firstUnreadDropSerialNo in href when present', () => {
const waveWithUnread = { ...baseWave, id: '3', firstUnreadDropSerialNo: 42 };
it("includes firstUnreadDropSerialNo in href when present", () => {
const waveWithUnread = {
...baseWave,
id: "3",
firstUnreadDropSerialNo: 42,
};
render(<BrainLeftSidebarWave wave={waveWithUnread} onHover={onHover} />);
expect(screen.getByRole('link')).toHaveAttribute('href', '/waves?divider=42&wave=3');
expect(screen.getByRole("link")).toHaveAttribute(
"href",
"/waves?divider=42&wave=3"
);
});

it('does not include serialNo in href when firstUnreadDropSerialNo is null', () => {
const waveWithoutUnread = { ...baseWave, id: '4', firstUnreadDropSerialNo: null };
it("does not include serialNo in href when firstUnreadDropSerialNo is null", () => {
const waveWithoutUnread = {
...baseWave,
id: "4",
firstUnreadDropSerialNo: null,
};
render(<BrainLeftSidebarWave wave={waveWithoutUnread} onHover={onHover} />);
expect(screen.getByRole('link')).toHaveAttribute('href', '/waves?wave=4');
expect(screen.getByRole("link")).toHaveAttribute("href", "/waves?wave=4");
});

it('shows muted indicator when wave is muted', () => {
const mutedWave = { ...baseWave, id: '5', isMuted: true };
it("shows muted indicator when wave is muted", () => {
const mutedWave = { ...baseWave, id: "5", isMuted: true };
render(<BrainLeftSidebarWave wave={mutedWave} onHover={onHover} />);
const bellSlashIcons = document.querySelectorAll('[data-icon="bell-slash"]');
const bellSlashIcons = document.querySelectorAll(
'[data-icon="bell-slash"]'
);
expect(bellSlashIcons.length).toBeGreaterThan(0);
});

it('does not show muted indicator when wave is not muted', () => {
const unmutedWave = { ...baseWave, id: '6', isMuted: false };
it("does not show muted indicator when wave is not muted", () => {
const unmutedWave = { ...baseWave, id: "6", isMuted: false };
render(<BrainLeftSidebarWave wave={unmutedWave} onHover={onHover} />);
const bellSlashIcons = document.querySelectorAll('[data-icon="bell-slash"]');
const bellSlashIcons = document.querySelectorAll(
'[data-icon="bell-slash"]'
);
expect(bellSlashIcons.length).toBe(0);
});
});
46 changes: 31 additions & 15 deletions __tests__/components/waves/drops/DropMobileMenuHandler.test.tsx
Original file line number Diff line number Diff line change
@@ -1,33 +1,49 @@
import { render, fireEvent, act } from '@testing-library/react';
import React from 'react';
import DropMobileMenuHandler from '@/components/waves/drops/DropMobileMenuHandler';
import { DropSize } from '@/helpers/waves/drop.helpers';
import { render, fireEvent, act } from "@testing-library/react";
import React from "react";
import DropMobileMenuHandler from "@/components/waves/drops/DropMobileMenuHandler";
import { DropSize } from "@/helpers/waves/drop.helpers";

jest.mock('@/hooks/isMobileDevice', () => () => true);
jest.mock('@/hooks/useIsTouchDevice', () => ({ __esModule: true, default: () => true }));
jest.mock("@/hooks/isMobileDevice", () => () => true);
jest.mock("@/hooks/useIsTouchDevice", () => ({
__esModule: true,
default: () => true,
}));

jest.mock('@/components/waves/drops/WaveDropMobileMenu', () => ({
jest.mock("@/components/waves/drops/WaveDropMobileMenu", () => ({
__esModule: true,
default: (props: any) => (
<div data-testid="menu" data-open={props.isOpen} onClick={() => props.onReply()} />
<button
type="button"
aria-label="menu"
data-testid="menu"
data-open={props.isOpen}
onClick={() => props.onReply()}
/>
),
}));

const drop = { id: 'drop', type: DropSize.FULL } as any;
const drop = { id: "drop", type: DropSize.FULL } as any;

test('opens menu on long press', () => {
test("opens menu on long press", () => {
jest.useFakeTimers();
const { getByTestId } = render(
<DropMobileMenuHandler drop={drop} showReplyAndQuote onReply={jest.fn()} onQuote={jest.fn()}>
<DropMobileMenuHandler
drop={drop}
showReplyAndQuote
onReply={jest.fn()}
onQuote={jest.fn()}
>
<div data-testid="child" />
</DropMobileMenuHandler>
);
fireEvent.touchStart(getByTestId('child'), { touches: [{ clientX:0, clientY:0 }] });
fireEvent.touchStart(getByTestId("child"), {
touches: [{ clientX: 0, clientY: 0 }],
});
act(() => {
jest.advanceTimersByTime(600);
});
const menu = getByTestId('menu');
expect(menu.getAttribute('data-open')).toBe('true');
const menu = getByTestId("menu");
expect(menu.dataset.open).toBe("true");
fireEvent.click(menu);
expect(menu.getAttribute('data-open')).toBe('false');
expect(menu.dataset.open).toBe("false");
});
Loading