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
6 changes: 6 additions & 0 deletions __tests__/components/brain/BrainMobile.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,12 @@ jest.mock("@/hooks/useWaveTimers", () => ({
}),
}));

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

jest.mock("@/components/brain/BrainDesktopDrop", () => ({
__esModule: true,
default: (props: any) => (
Expand Down
33 changes: 33 additions & 0 deletions __tests__/components/brain/ContentTabContext.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ describe("ContentTabContext", () => {
result.current.updateAvailableTabs({
waveId: "chat-wave",
isChatWave: true,
isConnected: true,
isMemesWave: false,
isCurationWave: false,
votingState: WaveVotingState.NOT_STARTED,
Expand All @@ -44,6 +45,7 @@ describe("ContentTabContext", () => {
result.current.updateAvailableTabs({
waveId: "meme-wave",
isChatWave: false,
isConnected: true,
isMemesWave: true,
isCurationWave: false,
votingState: WaveVotingState.NOT_STARTED,
Expand All @@ -59,12 +61,34 @@ describe("ContentTabContext", () => {
]);
});

it("omits My Votes for disconnected memes waves", () => {
const { result } = setup();
act(() =>
result.current.updateAvailableTabs({
waveId: "meme-wave",
isChatWave: false,
isConnected: false,
isMemesWave: true,
isCurationWave: false,
votingState: WaveVotingState.NOT_STARTED,
hasFirstDecisionPassed: false,
})
);
expect(result.current.availableTabs).toEqual([
MyStreamWaveTab.LEADERBOARD,
MyStreamWaveTab.CHAT,
MyStreamWaveTab.OUTCOME,
MyStreamWaveTab.FAQ,
]);
});

it("defaults to LEADERBOARD for memes waves", () => {
const { result } = setup();
act(() =>
result.current.updateAvailableTabs({
waveId: "meme-wave",
isChatWave: false,
isConnected: true,
isMemesWave: true,
isCurationWave: false,
votingState: WaveVotingState.NOT_STARTED,
Expand All @@ -80,6 +104,7 @@ describe("ContentTabContext", () => {
result.current.updateAvailableTabs({
waveId: "default-wave",
isChatWave: false,
isConnected: true,
isMemesWave: false,
isCurationWave: false,
votingState: WaveVotingState.NOT_STARTED,
Expand All @@ -95,6 +120,7 @@ describe("ContentTabContext", () => {
result.current.updateAvailableTabs({
waveId: "curation-wave",
isChatWave: false,
isConnected: true,
isMemesWave: false,
isCurationWave: true,
votingState: WaveVotingState.NOT_STARTED,
Expand All @@ -116,6 +142,7 @@ describe("ContentTabContext", () => {
result.current.updateAvailableTabs({
waveId: "meme-wave",
isChatWave: false,
isConnected: true,
isMemesWave: true,
isCurationWave: false,
votingState: WaveVotingState.NOT_STARTED,
Expand All @@ -127,6 +154,7 @@ describe("ContentTabContext", () => {
result.current.updateAvailableTabs({
waveId: "default-wave",
isChatWave: false,
isConnected: true,
isMemesWave: false,
isCurationWave: false,
votingState: WaveVotingState.NOT_STARTED,
Expand All @@ -137,6 +165,7 @@ describe("ContentTabContext", () => {
result.current.updateAvailableTabs({
waveId: "meme-wave",
isChatWave: false,
isConnected: true,
isMemesWave: true,
isCurationWave: false,
votingState: WaveVotingState.NOT_STARTED,
Expand All @@ -152,6 +181,7 @@ describe("ContentTabContext", () => {
result.current.updateAvailableTabs({
waveId: "default-wave",
isChatWave: false,
isConnected: true,
isMemesWave: false,
isCurationWave: false,
votingState: WaveVotingState.NOT_STARTED,
Expand All @@ -163,6 +193,7 @@ describe("ContentTabContext", () => {
result.current.updateAvailableTabs({
waveId: "default-wave",
isChatWave: false,
isConnected: true,
isMemesWave: false,
isCurationWave: false,
votingState: WaveVotingState.NOT_STARTED,
Expand All @@ -179,6 +210,7 @@ describe("ContentTabContext", () => {
result.current.updateAvailableTabs({
waveId: "wave-1",
isChatWave: false,
isConnected: true,
isMemesWave: false,
isCurationWave: false,
votingState: WaveVotingState.NOT_STARTED,
Expand All @@ -191,6 +223,7 @@ describe("ContentTabContext", () => {
result.current.updateAvailableTabs({
waveId: "wave-1",
isChatWave: false,
isConnected: true,
isMemesWave: false,
isCurationWave: true,
votingState: WaveVotingState.NOT_STARTED,
Expand Down
38 changes: 38 additions & 0 deletions __tests__/components/brain/mobile/BrainMobileTabs.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,10 @@ jest.mock("@/components/auth/Auth", () => ({
useAuth: () => ({ connectedProfile: { handle: "alice" } }),
}));

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

const leaderboardMock = jest.fn();
jest.mock("@/components/brain/my-stream/MyStreamWaveTabsLeaderboard", () => ({
__esModule: true,
Expand All @@ -71,6 +75,9 @@ jest.mock("@/components/brain/my-stream/MyStreamWaveTabsLeaderboard", () => ({
const { useWave } = require("@/hooks/useWave");
const { useUnreadIndicator } = require("@/hooks/useUnreadIndicator");
const { useUnreadNotifications } = require("@/hooks/useUnreadNotifications");
const {
useSeizeConnectContext,
} = require("@/components/auth/SeizeConnectContext");

describe("BrainMobileTabs", () => {
const onViewChange = jest.fn();
Expand All @@ -85,6 +92,9 @@ describe("BrainMobileTabs", () => {
(useUnreadNotifications as jest.Mock).mockReturnValue({
haveUnreadNotifications: false,
});
(useSeizeConnectContext as jest.Mock).mockReturnValue({
isConnected: true,
});
});

it("renders back button and navigates to My Stream", async () => {
Expand Down Expand Up @@ -203,6 +213,34 @@ describe("BrainMobileTabs", () => {
expect(screen.queryByText("FAQ")).toBeNull();
});

it("hides My Votes for disconnected memes rank wave", () => {
(useWave as jest.Mock).mockReturnValue({
isMemesWave: true,
isCurationWave: false,
isRankWave: true,
});
(useSeizeConnectContext as jest.Mock).mockReturnValue({
isConnected: false,
});

render(
<BrainMobileTabs
activeView={BrainView.ABOUT}
onViewChange={onViewChange}
waveActive={true}
showWavesTab={false}
showStreamBack={false}
isApp={false}
wave={{ id: "1" } as any}
/>
);

expect(screen.getByTestId("leaderboard")).toBeInTheDocument();
expect(screen.queryByText("My Votes")).toBeNull();
expect(screen.getByText("Outcome")).toBeInTheDocument();
expect(screen.getByText("FAQ")).toBeInTheDocument();
});

it("renders Sales for non-rank curation waves", () => {
(useWave as jest.Mock).mockReturnValue({
isMemesWave: false,
Expand Down
31 changes: 31 additions & 0 deletions __tests__/components/brain/my-stream/MyStreamWaveChat.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ const mockRemoveAllDeliveredNotifications = jest
.fn()
.mockResolvedValue(undefined);
const invalidateNotificationsMock = jest.fn();
const mockUseAuth = jest.fn();

jest.mock("next/navigation", () => ({
useRouter: () => ({ replace: replaceMock }),
Expand Down Expand Up @@ -91,6 +92,10 @@ jest.mock("@/components/notifications/NotificationsContext", () => ({
}),
}));

jest.mock("@/components/auth/Auth", () => ({
useAuth: () => mockUseAuth(),
}));

jest.mock("@/services/api/common-api", () => ({
commonApiPostWithoutBodyAndResponse: jest.fn().mockResolvedValue(undefined),
}));
Expand All @@ -114,6 +119,9 @@ describe("MyStreamWaveChat", () => {
mockRemoveWaveDeliveredNotifications.mockClear();
mockRemoveAllDeliveredNotifications.mockClear();
invalidateNotificationsMock.mockClear();
mockUseAuth.mockReturnValue({
connectedProfile: { handle: "tester" },
});
(
commonApiPostWithoutBodyAndResponse as jest.MockedFunction<
typeof commonApiPostWithoutBodyAndResponse
Expand Down Expand Up @@ -196,4 +204,27 @@ describe("MyStreamWaveChat", () => {
expect(invalidateNotificationsMock).toHaveBeenCalled();
});
});

it("skips notification cleanup on unmount for anonymous viewers", async () => {
mockUseAuth.mockReturnValue({
connectedProfile: null,
});

const { unmount } = renderWithProvider(
<MyStreamWaveChat
wave={wave}
firstUnreadSerialNo={null}
viewMode="chat"
onDropClick={mockOnDropClick}
/>
);

await act(async () => {
unmount();
});

expect(mockRemoveWaveDeliveredNotifications).not.toHaveBeenCalled();
expect(commonApiPostWithoutBodyAndResponse).not.toHaveBeenCalled();
expect(invalidateNotificationsMock).not.toHaveBeenCalled();
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,10 @@ jest.mock("@/components/waves/leaderboard/time/CompactTimeCountdown", () => ({
),
}));

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

import MyStreamWaveDesktopTabs from "@/components/brain/my-stream/MyStreamWaveDesktopTabs";

let mockAvailableTabs: MyStreamWaveTab[] = [];
Expand All @@ -71,6 +75,9 @@ let mockWaveInfo: any = {
};
let mockVoting = { isUpcoming: false, isCompleted: false, isInProgress: true };
let mockDecisions: { timestamp: number }[] = [];
const {
useSeizeConnectContext,
} = require("@/components/auth/SeizeConnectContext");

function renderComponent(activeTab: MyStreamWaveTab = MyStreamWaveTab.CHAT) {
return render(
Expand All @@ -93,6 +100,9 @@ beforeEach(() => {
};
mockVoting = { isUpcoming: false, isCompleted: false, isInProgress: true };
mockDecisions = [];
(useSeizeConnectContext as jest.Mock).mockReturnValue({
isConnected: true,
});
});

describe("MyStreamWaveDesktopTabs", () => {
Expand Down Expand Up @@ -146,6 +156,32 @@ describe("MyStreamWaveDesktopTabs", () => {
expect(setActiveTab).not.toHaveBeenCalled();
});

it("hides My Votes for disconnected memes waves", () => {
mockWaveInfo = {
isChatWave: false,
isMemesWave: true,
isCurationWave: false,
isRankWave: false,
};
mockAvailableTabs = [
MyStreamWaveTab.LEADERBOARD,
MyStreamWaveTab.CHAT,
MyStreamWaveTab.MY_VOTES,
MyStreamWaveTab.OUTCOME,
MyStreamWaveTab.FAQ,
];
(useSeizeConnectContext as jest.Mock).mockReturnValue({
isConnected: false,
});

renderComponent(MyStreamWaveTab.MY_VOTES);

expect(screen.getByText("Leaderboard")).toBeInTheDocument();
expect(screen.getByText("Chat")).toBeInTheDocument();
expect(screen.queryByText("My Votes")).toBeNull();
expect(setActiveTab).toHaveBeenCalledWith(MyStreamWaveTab.LEADERBOARD);
});

it("keeps Sales hidden outside curation waves", () => {
mockWaveInfo = {
isChatWave: false,
Expand Down
14 changes: 14 additions & 0 deletions __tests__/components/drops/view/DropsList.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -235,6 +235,20 @@ describe("DropsList", () => {
rank: 1,
variant: "chat",
});

const boostedCard = screen.getByTestId("boosted-card");

expect(boostedCard.parentElement).toHaveClass(
"tw-rounded-2xl",
"tw-bg-iron-900/50",
"tw-p-2",
"sm:tw-p-3"
);
expect(boostedCard.parentElement?.parentElement).toHaveClass(
"tw-px-3",
"tw-py-4",
"sm:tw-px-4"
);
});

it("clicking an inline boosted card calls onBoostedDropClick with the drop serial", () => {
Expand Down
32 changes: 32 additions & 0 deletions __tests__/components/home/boosted/BoostedDropCardHome.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -446,6 +446,35 @@ describe("BoostedDropCardHome", () => {
variant: "chat",
})
);

expect(screen.getByTestId("link-preview").parentElement).toHaveClass(
"tw-px-3",
"sm:tw-px-4"
);
});

it("adds bottom spacing to preview-only chat cards", () => {
renderWithAuth(
<BoostedDropCardHome
drop={createDrop({
parts: [
{
content: "https://example.com/article",
media: [],
},
],
})}
onClick={jest.fn()}
variant="chat"
rank={1}
/>
);

expect(screen.getByTestId("link-preview").parentElement).toHaveClass(
"tw-px-3",
"sm:tw-px-4",
"tw-pb-4"
);
});

it("keeps caption content for chat cards with lead media", () => {
Expand Down Expand Up @@ -587,6 +616,9 @@ describe("BoostedDropCardHome", () => {
/>
);

expect(
screen.getByTestId("boosted-drop-media-frame").parentElement
).toHaveClass("tw-px-3", "sm:tw-px-4", "tw-pb-4");
expect(screen.getByTestId("boosted-drop-media-frame")).toHaveStyle({
aspectRatio: "8 / 5",
});
Expand Down
Loading
Loading