forked from SmartDropLabs/smartdrop-frontend
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathOwnConnectButtonContext.test.tsx
More file actions
152 lines (131 loc) · 5.11 KB
/
Copy pathOwnConnectButtonContext.test.tsx
File metadata and controls
152 lines (131 loc) · 5.11 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
/**
* Tests for OwnConnectButtonContext (Issue #69)
*
* Verifies that pages correctly signal their own inline Connect Wallet CTA
* so AppShell can suppress the duplicate floating button.
*
* Acceptance criteria:
* - /farm → exactly one CTA (floating suppressed) when disconnected
* - /farm connected → floating CTA shown (context cleared)
* - /farm/[poolId] modal closed → floating CTA visible
* - /farm/[poolId] modal open + disconnected → floating CTA suppressed
* - unmount cleans up → floating CTA returns after navigation
* - idempotent double-signal
*/
import { render, screen, act } from "@testing-library/react";
import { describe, expect, it } from "vitest";
import { useEffect, useState } from "react";
import {
OwnConnectButtonProvider,
useHasOwnConnectButton,
useOwnConnectButton,
} from "@/context/OwnConnectButtonContext";
// ─── Test harness components ──────────────────────────────────────────────────
/**
* Renders a data-testid element whose text reflects whether AppShell would
* suppress the floating button.
*/
function FloatingButtonObserver() {
const hasOwnCTA = useHasOwnConnectButton();
return (
<div data-testid="floating-suppressed">{hasOwnCTA ? "yes" : "no"}</div>
);
}
/**
* Simulates a page that signals it has its own CTA based on the `active` prop.
* Uses useEffect exactly as production pages do.
*/
function PageSignaller({ active }: { active: boolean }) {
const signal = useOwnConnectButton();
useEffect(() => {
signal(active);
return () => signal(false);
}, [active, signal]);
return null;
}
function Tree({ showSignaller, active }: { showSignaller: boolean; active: boolean }) {
return (
<OwnConnectButtonProvider>
<FloatingButtonObserver />
{showSignaller && <PageSignaller active={active} />}
</OwnConnectButtonProvider>
);
}
// ─── Controlled tree for testing state transitions ────────────────────────────
function ControlledTree() {
const [active, setActive] = useState(false);
return (
<OwnConnectButtonProvider>
<FloatingButtonObserver />
<PageSignaller active={active} />
<button onClick={() => setActive(true)}>signal-true</button>
<button onClick={() => setActive(false)}>signal-false</button>
</OwnConnectButtonProvider>
);
}
// ─── Tests ────────────────────────────────────────────────────────────────────
function floatingSuppressed() {
return screen.getByTestId("floating-suppressed").textContent === "yes";
}
describe("OwnConnectButtonContext", () => {
it("floating button is visible when no page signals its own CTA", () => {
render(
<OwnConnectButtonProvider>
<FloatingButtonObserver />
</OwnConnectButtonProvider>,
);
expect(floatingSuppressed()).toBe(false);
});
it("/farm disconnected → floating button suppressed (exactly one CTA)", () => {
// Page is disconnected → active=true (inline CTA visible)
render(<Tree showSignaller active />);
expect(floatingSuppressed()).toBe(true);
});
it("/farm connected → floating button shown (inline CTA gone)", () => {
render(<ControlledTree />);
// Initially not signalling
expect(floatingSuppressed()).toBe(false);
// Wallet disconnects → inline CTA appears
act(() => {
screen.getByText("signal-true").click();
});
expect(floatingSuppressed()).toBe(true);
// Wallet connects → inline CTA gone, floating returns
act(() => {
screen.getByText("signal-false").click();
});
expect(floatingSuppressed()).toBe(false);
});
it("/farm/[poolId] modal closed → floating button visible", () => {
// isOpen=false → active=false
render(<Tree showSignaller={false} active={false} />);
expect(floatingSuppressed()).toBe(false);
});
it("/farm/[poolId] modal open + disconnected → floating suppressed (inline CTA in modal)", () => {
// isOpen=true && !isConnected → active=true
render(<Tree showSignaller active />);
expect(floatingSuppressed()).toBe(true);
});
it("unmount of page component releases the signal (floating returns after navigation)", () => {
const { rerender } = render(<Tree showSignaller active />);
expect(floatingSuppressed()).toBe(true);
// Simulate navigation away: signaller unmounts
rerender(<Tree showSignaller={false} active={false} />);
expect(floatingSuppressed()).toBe(false);
});
it("idempotent: signalling true twice and false once fully releases", () => {
render(<ControlledTree />);
act(() => {
screen.getByText("signal-true").click();
});
act(() => {
// Second true — should not double-count
screen.getByText("signal-true").click();
});
expect(floatingSuppressed()).toBe(true);
act(() => {
screen.getByText("signal-false").click();
});
expect(floatingSuppressed()).toBe(false);
});
});