|
1 | 1 | import "fake-indexeddb/auto"; |
2 | 2 | import { describe, it, expect, vi, beforeEach, afterEach } from "vitest"; |
3 | 3 | import { createRoot } from "solid-js"; |
4 | | -import { createPollCoordinator, type DashboardData } from "../../src/app/services/poll"; |
| 4 | +import { createPollCoordinator, disableNotifGate, resetPollState, type DashboardData } from "../../src/app/services/poll"; |
5 | 5 |
|
6 | 6 | // Mock pushError so we can spy on it |
7 | 7 | const mockPushError = vi.fn(); |
@@ -29,6 +29,7 @@ vi.mock("../../src/app/lib/errors", () => ({ |
29 | 29 | vi.mock("../../src/app/lib/notifications", () => ({ |
30 | 30 | detectNewItems: vi.fn(() => []), |
31 | 31 | dispatchNotifications: vi.fn(), |
| 32 | + _resetNotificationState: vi.fn(), |
32 | 33 | })); |
33 | 34 |
|
34 | 35 | // Mock config so doFetch doesn't fail when accessing config.selectedRepos |
@@ -119,7 +120,7 @@ describe("createPollCoordinator", () => { |
119 | 120 | }); |
120 | 121 | }); |
121 | 122 |
|
122 | | - it("continues polling when document is hidden", async () => { |
| 123 | + it("continues polling when document is hidden (notifications gate enabled)", async () => { |
123 | 124 | const fetchAll = makeFetchAll(); |
124 | 125 |
|
125 | 126 | await createRoot(async (dispose) => { |
@@ -167,6 +168,31 @@ describe("createPollCoordinator", () => { |
167 | 168 | }); |
168 | 169 | }); |
169 | 170 |
|
| 171 | + it("pauses background polling when hidden and notifications gate is disabled", async () => { |
| 172 | + disableNotifGate(); |
| 173 | + const fetchAll = makeFetchAll(); |
| 174 | + |
| 175 | + await createRoot(async (dispose) => { |
| 176 | + createPollCoordinator(makeGetInterval(60), fetchAll); |
| 177 | + await Promise.resolve(); // initial fetch |
| 178 | + |
| 179 | + const callsAfterInit = fetchAll.mock.calls.length; |
| 180 | + |
| 181 | + // Hide document |
| 182 | + setDocumentVisible(false); |
| 183 | + |
| 184 | + // Advance past the interval |
| 185 | + vi.advanceTimersByTime(90_000); |
| 186 | + await Promise.resolve(); |
| 187 | + |
| 188 | + // Should NOT have fetched — gate disabled means no cheap 304, skip background polls |
| 189 | + expect(fetchAll.mock.calls.length).toBe(callsAfterInit); |
| 190 | + dispose(); |
| 191 | + }); |
| 192 | + |
| 193 | + resetPollState(); // restore gate for other tests |
| 194 | + }); |
| 195 | + |
170 | 196 | it("does NOT trigger immediate refresh on re-visible within 2 minutes", async () => { |
171 | 197 | // Pin jitter to 0 so 300s interval is exactly 300s (no background poll in 90s) |
172 | 198 | const randomSpy = vi.spyOn(Math, "random").mockReturnValue(0.5); |
|
0 commit comments