Skip to content
Closed

wip #2219

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
415 changes: 368 additions & 47 deletions __tests__/contexts/wave/MyStreamContext.test.tsx

Large diffs are not rendered by default.

72 changes: 72 additions & 0 deletions __tests__/hooks/usePinnedWavesServer.test.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
import { renderHook } from "@testing-library/react";
import React from "react";
import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query";

import { AuthContext } from "@/components/auth/Auth";
import { usePinnedWavesServer } from "@/hooks/usePinnedWavesServer";
import { useSeizeConnectContext } from "@/components/auth/SeizeConnectContext";

jest.mock("@tanstack/react-query", () => ({
useMutation: jest.fn(),
useQuery: jest.fn(),
useQueryClient: jest.fn(),
}));

jest.mock("@/components/auth/SeizeConnectContext", () => ({
useSeizeConnectContext: jest.fn(),
}));

const queryClientMock = {
cancelQueries: jest.fn(),
getQueriesData: jest.fn(() => []),
getQueryData: jest.fn(() => []),
invalidateQueries: jest.fn(),
setQueryData: jest.fn(),
};

const wrapper: React.FC<{ children: React.ReactNode }> = ({ children }) => (
<AuthContext.Provider
value={
{ connectedProfile: { handle: "me" }, activeProfileProxy: null } as any
}
>
{children}
</AuthContext.Provider>
);

describe("usePinnedWavesServer", () => {
beforeEach(() => {
jest.clearAllMocks();

(useQueryClient as jest.Mock).mockReturnValue(queryClientMock);
(useQuery as jest.Mock).mockReturnValue({
data: [],
isLoading: false,
isError: false,
error: null,
refetch: jest.fn(),
});
(useMutation as jest.Mock).mockReturnValue({
mutateAsync: jest.fn(),
error: null,
});
(useSeizeConnectContext as jest.Mock).mockReturnValue({
address: "0xabc",
});
});

it("uses the expected pinned waves cache policy", () => {
renderHook(() => usePinnedWavesServer(), { wrapper });

const queryOptions = (useQuery as jest.Mock).mock.calls[0]?.[0];

expect(queryOptions).toEqual(
expect.objectContaining({
gcTime: 10 * 60 * 1000,
refetchInterval: 2 * 60 * 1000,
refetchOnWindowFocus: "always",
staleTime: 5 * 60 * 1000,
})
);
});
});
28 changes: 20 additions & 8 deletions __tests__/hooks/useWaveData.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,18 @@ describe("useWaveData", () => {
it("calls useQuery with correct params", () => {
(useQuery as jest.Mock).mockReturnValue({ data: null });
renderHook(() =>
useWaveData({ waveId: "1", refetchInterval: 1000, onWaveNotFound: jest.fn() })
useWaveData({
waveId: "1",
refetchInterval: 1000,
onWaveNotFound: jest.fn(),
})
);
expect(useQuery).toHaveBeenCalledWith(
expect.objectContaining({
refetchOnWindowFocus: "always",
refetchInterval: 1000,
})
);
expect(useQuery).toHaveBeenCalled();
});

it("does not fetch when waveId is null", () => {
Expand All @@ -29,15 +38,18 @@ describe("useWaveData", () => {
expect(mockFetch).not.toHaveBeenCalled();
});

it('handles retry logic', () => {
it("handles retry logic", () => {
let options: any;
(useQuery as jest.Mock).mockImplementation((opts: any) => { options = opts; return { data: null }; });
(useQuery as jest.Mock).mockImplementation((opts: any) => {
options = opts;
return { data: null };
});
const onWaveNotFound = jest.fn();
renderHook(() => useWaveData({ waveId: '1', onWaveNotFound }));
expect(options.retry(1, 'Wave 1 not found')).toBe(false);
renderHook(() => useWaveData({ waveId: "1", onWaveNotFound }));
expect(options.retry(1, "Wave 1 not found")).toBe(false);
expect(onWaveNotFound).toHaveBeenCalled();
expect(options.retry(2, new Error('e'))).toBe(true);
expect(options.retry(4, new Error('e'))).toBe(false);
expect(options.retry(2, new Error("e"))).toBe(true);
expect(options.retry(4, new Error("e"))).toBe(false);
expect(options.retryDelay(3)).toBe(3000);
});
});
115 changes: 101 additions & 14 deletions __tests__/hooks/useWavesList.test.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { renderHook } from "@testing-library/react";
import { act, renderHook } from "@testing-library/react";
import React from "react";
import useWavesList from "@/hooks/useWavesList";
import { AuthContext } from "@/components/auth/Auth";
Expand All @@ -16,6 +16,10 @@ jest.mock("@/hooks/useWaveData", () => ({
useWaveData: jest.fn(),
}));

jest.mock("@/components/auth/SeizeConnectContext", () => ({
useSeizeConnectContext: jest.fn(() => ({ address: "0xabc" })),
}));

jest.mock("@/hooks/useShowFollowingWaves", () => ({
useShowFollowingWaves: jest.fn(() => [false]),
}));
Expand All @@ -25,16 +29,22 @@ const useWavesOverviewMock = require("@/hooks/useWavesOverview")
const usePinnedWavesServerMock = require("@/hooks/usePinnedWavesServer")
.usePinnedWavesServer as jest.Mock;
const useWaveDataMock = require("@/hooks/useWaveData").useWaveData as jest.Mock;
const useSeizeConnectContextMock =
require("@/components/auth/SeizeConnectContext")
.useSeizeConnectContext as jest.Mock;

const wrapper: React.FC<{ children: React.ReactNode }> = ({ children }) => (
<AuthContext.Provider
value={
{ connectedProfile: { handle: "me" }, activeProfileProxy: null } as any
}
>
{children}
</AuthContext.Provider>
);
const authContextValue = (overrides: Record<string, unknown> = {}) =>
({
connectedProfile: { handle: "me" },
activeProfileProxy: null,
...overrides,
}) as any;

const createWrapper =
(value = authContextValue()): React.FC<{ children: React.ReactNode }> =>
({ children }) => (
<AuthContext.Provider value={value}>{children}</AuthContext.Provider>
);

const dmWave = {
id: "1",
Expand All @@ -58,6 +68,9 @@ const pinnedExtra = {

beforeEach(() => {
jest.clearAllMocks();
useSeizeConnectContextMock.mockReturnValue({
address: "0xabc",
});
useWavesOverviewMock.mockReturnValue({
waves: [dmWave, mainWave],
isFetching: false,
Expand All @@ -74,7 +87,7 @@ beforeEach(() => {
unpinWave: jest.fn(),
isLoading: false,
isError: false,
refetch: jest.fn(),
refetch: jest.fn().mockResolvedValue({}),
});
useWaveDataMock.mockReturnValue({
data: pinnedExtra,
Expand All @@ -85,7 +98,9 @@ beforeEach(() => {
});

test("combines main and pinned waves, filtering DMs and flagging pinned", () => {
const { result } = renderHook(() => useWavesList(), { wrapper });
const { result } = renderHook(() => useWavesList(), {
wrapper: createWrapper(),
});
const waves = result.current.waves;
expect(waves.map((w: any) => w.id)).toEqual(["3", "2"]);
expect(waves.every((w: any) => w.isPinned)).toBe(true);
Expand All @@ -100,8 +115,80 @@ test("indicates loading when pinned wave is still loading", () => {
unpinWave: jest.fn(),
isLoading: true,
isError: false,
refetch: jest.fn(),
refetch: jest.fn().mockResolvedValue({}),
});
const { result } = renderHook(() => useWavesList(), {
wrapper: createWrapper(),
});
const { result } = renderHook(() => useWavesList(), { wrapper });
expect(result.current.isPinnedWavesLoading).toBe(true);
});

test("refetchAllWaves refetches pinned waves for authenticated sessions", () => {
const mainWavesRefetch = jest.fn();
const refetchPinnedWaves = jest.fn().mockResolvedValue({});

useWavesOverviewMock.mockReturnValue({
waves: [dmWave, mainWave],
isFetching: false,
isFetchingNextPage: false,
hasNextPage: false,
fetchNextPage: jest.fn(),
status: "success",
refetch: mainWavesRefetch,
});
usePinnedWavesServerMock.mockReturnValue({
pinnedIds: ["2", "3"],
pinnedWaves: [pinnedExtra],
pinWave: jest.fn(),
unpinWave: jest.fn(),
isLoading: false,
isError: false,
refetch: refetchPinnedWaves,
});

const { result } = renderHook(() => useWavesList(), {
wrapper: createWrapper(),
});

act(() => {
result.current.refetchAllWaves();
});

expect(mainWavesRefetch).toHaveBeenCalledTimes(1);
expect(refetchPinnedWaves).toHaveBeenCalledTimes(1);
});

test("refetchAllWaves skips pinned waves when the pinned query is disabled", () => {
const mainWavesRefetch = jest.fn();
const refetchPinnedWaves = jest.fn().mockResolvedValue({});

useWavesOverviewMock.mockReturnValue({
waves: [dmWave, mainWave],
isFetching: false,
isFetchingNextPage: false,
hasNextPage: false,
fetchNextPage: jest.fn(),
status: "success",
refetch: mainWavesRefetch,
});
usePinnedWavesServerMock.mockReturnValue({
pinnedIds: ["2", "3"],
pinnedWaves: [pinnedExtra],
pinWave: jest.fn(),
unpinWave: jest.fn(),
isLoading: false,
isError: false,
refetch: refetchPinnedWaves,
});

const { result } = renderHook(() => useWavesList(), {
wrapper: createWrapper(authContextValue({ connectedProfile: null })),
});

act(() => {
result.current.refetchAllWaves();
});

expect(mainWavesRefetch).toHaveBeenCalledTimes(1);
expect(refetchPinnedWaves).not.toHaveBeenCalled();
});
Loading
Loading