forked from SmartDropLabs/smartdrop-frontend
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathNavbar.test.tsx
More file actions
178 lines (143 loc) · 5.63 KB
/
Copy pathNavbar.test.tsx
File metadata and controls
178 lines (143 loc) · 5.63 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
import { ChakraProvider } from "@chakra-ui/react";
import { fireEvent, render, screen, waitFor } from "@testing-library/react";
import { beforeEach, describe, expect, it, vi } from "vitest";
import Navbar from "./Navbar";
import { usePlatformStats } from "@/hooks/useSorobanQuery";
const walletMock = vi.hoisted(() => ({
publicKey: null as string | null,
walletApi: null,
networkName: "TESTNET",
isNetworkMismatch: false,
isConnected: false,
connect: vi.fn(),
disconnect: vi.fn(),
}));
vi.mock("@/context/StellarWalletContext", () => ({
useStellarWallet: vi.fn(() => walletMock),
}));
vi.mock("@/hooks/useSorobanQuery", () => ({
usePlatformStats: vi.fn(),
}));
vi.mock("next/navigation", () => ({
usePathname: vi.fn(),
}));
const usePathnameMock = vi.mocked(await import("next/navigation")).usePathname;
const usePlatformStatsMock = vi.mocked(usePlatformStats);
const TEST_PUBLIC_KEY =
"GA3CD2PYXOQCXW7ZVQW3MOA3JFZCE4F4IG2FD66I55TQASPCNKYYEFRN";
const SHORTENED_ADDRESS = "GA3C…EFRN";
function renderNavbar() {
return render(
<ChakraProvider>
<Navbar />
</ChakraProvider>,
);
}
function connectWallet() {
walletMock.publicKey = TEST_PUBLIC_KEY;
walletMock.isConnected = true;
}
beforeEach(() => {
vi.clearAllMocks();
// jsdom does not implement Element.scrollTo, which Chakra's MenuList
// calls when it mounts to focus the active item.
Element.prototype.scrollTo = vi.fn();
walletMock.publicKey = null;
walletMock.isConnected = false;
walletMock.isNetworkMismatch = false;
usePathnameMock.mockReturnValue("/");
usePlatformStatsMock.mockReturnValue({
data: undefined,
isLoading: false,
isError: false,
} as ReturnType<typeof usePlatformStats>);
// jsdom has no clipboard implementation; WalletMenu's copy action needs it.
Object.defineProperty(navigator, "clipboard", {
configurable: true,
value: { writeText: vi.fn().mockResolvedValue(undefined) },
});
});
describe("Navbar (disconnected)", () => {
it("shows public links but hides wallet-gated Farm/Leaderboard links", () => {
renderNavbar();
expect(screen.getByRole("link", { name: "Home" })).toBeTruthy();
expect(screen.getByRole("link", { name: "History" })).toBeTruthy();
expect(screen.getByRole("link", { name: "Contributors" })).toBeTruthy();
expect(screen.queryByRole("link", { name: "Farm" })).toBeNull();
expect(screen.queryByRole("link", { name: "Leaderboard" })).toBeNull();
});
it("shows platform stat pills instead of the wallet pill", () => {
renderNavbar();
expect(screen.getByText("Online")).toBeTruthy();
expect(screen.getByText("Users")).toBeTruthy();
expect(screen.getByText("TVL")).toBeTruthy();
expect(screen.queryByRole("button", { name: "Wallet menu" })).toBeNull();
});
it("renders placeholder dashes when stats have not loaded", () => {
renderNavbar();
const dashes = screen.getAllByText("—");
expect(dashes.length).toBeGreaterThanOrEqual(3);
});
});
describe("Navbar (connected)", () => {
beforeEach(connectWallet);
it("shows Farm/Leaderboard links once connected", () => {
renderNavbar();
expect(screen.getByRole("link", { name: "Farm" })).toBeTruthy();
expect(screen.getByRole("link", { name: "Leaderboard" })).toBeTruthy();
});
it("replaces stat pills with a wallet pill showing the shortened address", () => {
renderNavbar();
expect(screen.queryByText("Online")).toBeNull();
expect(screen.queryByText("TVL")).toBeNull();
const pill = screen.getByRole("button", { name: "Wallet menu" });
expect(pill.textContent).toContain(SHORTENED_ADDRESS);
});
it("disconnects from the wallet menu", async () => {
renderNavbar();
fireEvent.click(screen.getByRole("button", { name: "Wallet menu" }));
fireEvent.click(await screen.findByText("Disconnect"));
await waitFor(() => {
expect(walletMock.disconnect).toHaveBeenCalledTimes(1);
});
});
it("copies the full public key from the wallet menu and confirms", async () => {
renderNavbar();
fireEvent.click(screen.getByRole("button", { name: "Wallet menu" }));
fireEvent.click(await screen.findByText("Copy address"));
await waitFor(() => {
expect(navigator.clipboard.writeText).toHaveBeenCalledWith(TEST_PUBLIC_KEY);
});
expect(await screen.findByText("Copied!")).toBeTruthy();
});
});
describe("Navbar active-link highlighting", () => {
it("marks the link matching the current pathname as active", () => {
usePathnameMock.mockReturnValue("/history");
renderNavbar();
const home = screen.getByRole("link", { name: "Home" });
const history = screen.getByRole("link", { name: "History" });
expect(history.className).toContain("font-semibold");
expect(home.className).toContain("font-medium");
expect(history.className).not.toContain("font-medium");
expect(home.className).not.toContain("font-semibold");
});
});
describe("Navbar More menu", () => {
it("opens to show the secondary navigation links", async () => {
renderNavbar();
fireEvent.click(screen.getByRole("button", { name: "More navigation links" }));
// Chakra MenuItems render an explicit role="menuitem" (overriding the
// implicit link role), and jsdom has no layout so the positioned list
// stays visibility:hidden — both require querying with hidden: true.
const labels = ["Prices", "Airdrops", "Webhooks", "Alerts"];
const hrefs = ["/prices", "/airdrops", "/webhooks", "/alerts"];
for (let i = 0; i < labels.length; i++) {
const item = await screen.findByRole(
"menuitem",
{ name: labels[i], hidden: true },
);
expect(item.getAttribute("href")).toBe(hrefs[i]);
}
});
});