Skip to content

feat(billing): implement polling for balance update after payment#1975

Merged
baktun14 merged 6 commits intomainfrom
features/refresh-balance-after-payment
Sep 29, 2025
Merged

feat(billing): implement polling for balance update after payment#1975
baktun14 merged 6 commits intomainfrom
features/refresh-balance-after-payment

Conversation

@baktun14
Copy link
Contributor

@baktun14 baktun14 commented Sep 26, 2025

#1967

Summary by CodeRabbit

  • New Features

    • Adds a payment polling provider to verify credited funds after payment; payment page treats polling as part of processing and shows loading/timeout/success notifications.
  • Tests

    • Comprehensive tests for polling lifecycle, timeouts, success/error flows, analytics, and cleanup.
  • Chores

    • Added test seed helpers and a new analytics event for trial completion.
  • Quality

    • Centralized cache key usage and surfaced an additional wallet-fetching status for consistency.

@baktun14 baktun14 requested a review from a team as a code owner September 26, 2025 17:38
@coderabbitai
Copy link
Contributor

coderabbitai bot commented Sep 26, 2025

Pre-merge checks and finishing touches

❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title Check ✅ Passed The title “feat(billing): implement polling for balance update after payment” concisely and accurately describes the primary feature introduced by this pull request, namely the implementation of a polling mechanism to refresh the user’s balance post-payment. It follows the conventional commit convention, keeps the focus on the billing context, and avoids extraneous detail.
✨ Finishing touches
  • 📝 Generate Docstrings
🧪 Generate unit tests
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch features/refresh-balance-after-payment

Comment @coderabbitai help to get the list of available commands and usage tips.

@codecov
Copy link

codecov bot commented Sep 26, 2025

Codecov Report

❌ Patch coverage is 77.77778% with 26 lines in your changes missing coverage. Please review.
✅ Project coverage is 45.44%. Comparing base (679d8e3) to head (4f73911).
⚠️ Report is 6 commits behind head on main.
✅ All tests successful. No failed tests found.

Files with missing lines Patch % Lines
.../PaymentPollingProvider/PaymentPollingProvider.tsx 84.61% 14 Missing and 2 partials ⚠️
apps/deploy-web/src/pages/payment.tsx 0.00% 5 Missing and 1 partial ⚠️
apps/deploy-web/src/hooks/useManagedWallet.ts 0.00% 2 Missing ⚠️
...oy-web/src/context/PaymentPollingProvider/index.ts 0.00% 1 Missing ⚠️
apps/deploy-web/src/pages/_app.tsx 0.00% 1 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main    #1975      +/-   ##
==========================================
+ Coverage   45.14%   45.44%   +0.29%     
==========================================
  Files         998     1003       +5     
  Lines       28224    28446     +222     
  Branches     7384     7451      +67     
==========================================
+ Hits        12741    12926     +185     
- Misses      14288    14312      +24     
- Partials     1195     1208      +13     
Flag Coverage Δ
api 81.57% <ø> (+0.07%) ⬆️
deploy-web 23.71% <77.77%> (+0.57%) ⬆️
log-collector 75.35% <ø> (ø)
notifications 87.94% <ø> (ø)
provider-console 81.48% <ø> (ø)
provider-proxy 84.98% <ø> (ø)
Files with missing lines Coverage Δ
apps/deploy-web/src/queries/queryKeys.ts 100.00% <100.00%> (ø)
...ps/deploy-web/src/queries/useManagedWalletQuery.ts 94.44% <100.00%> (-0.30%) ⬇️
...oy-web/src/services/analytics/analytics.service.ts 86.13% <ø> (ø)
...oy-web/src/context/PaymentPollingProvider/index.ts 0.00% <0.00%> (ø)
apps/deploy-web/src/pages/_app.tsx 0.00% <0.00%> (ø)
apps/deploy-web/src/hooks/useManagedWallet.ts 23.07% <0.00%> (ø)
apps/deploy-web/src/pages/payment.tsx 0.00% <0.00%> (ø)
.../PaymentPollingProvider/PaymentPollingProvider.tsx 84.61% <84.61%> (ø)

... and 19 files with indirect coverage changes

🚀 New features to boost your workflow:
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 5

🧹 Nitpick comments (5)
apps/deploy-web/tests/seeders/managedWallet.ts (2)

7-7: Ensure lowercase address characters

Akash addresses are lowercase; enforce casing to avoid sporadic uppercase from faker.

Apply this diff:

-  address: `akash${faker.string.alphanumeric({ length: 39 })}`,
+  address: `akash${faker.string.alphanumeric({ length: 39, casing: "lower" })}`,

Based on learnings


10-10: Minor: drop unnecessary literal assertion

The target type already constrains this to the literal; the assertion isn’t needed.

-  username: "Managed Wallet" as const,
+  username: "Managed Wallet",
apps/deploy-web/src/queries/queryKeys.ts (1)

76-77: Return an empty key when userId is absent to match existing patterns

Using an empty string creates a cache entry for “no user”; prefer [] like getBalancesKey does.

-  static getManagedWalletKey = (userId?: string) => ["MANAGED_WALLET", userId || ""];
+  static getManagedWalletKey = (userId?: string) => (userId ? ["MANAGED_WALLET", userId] : []);
apps/deploy-web/src/queries/useManagedWalletQuery.ts (1)

10-10: Avoid casting by tightening the key helper’s return type

If getManagedWalletKey returns a readonly unknown[] (or QueryKey), you can drop the cast here.

Possible signature in queryKeys.ts:

static getManagedWalletKey = (userId?: string): readonly unknown[] => (userId ? ["MANAGED_WALLET", userId] : []);
apps/deploy-web/src/pages/_app.tsx (1)

81-89: Avoid overlapping refetches inside the polling loop

setInterval without awaiting can stack concurrent requests; guard with an in‑flight flag and await both refetches.

Example change in PaymentPollingProvider:

const isTickingRef = useRef(false);

pollingRef.current = setInterval(async () => {
  if (isTickingRef.current) return;
  isTickingRef.current = true;
  try {
    const elapsed = Date.now() - (startTimeRef.current || 0);
    if (elapsed >= MAX_POLLING_DURATION_MS) {
      stopPolling();
      enqueueSnackbar(<d.Snackbar title="Payment processing timeout" subTitle="Please refresh the page to check your balance" iconVariant="warning" />, { variant: "warning" });
      return;
    }
    await Promise.all([refetchBalance(), refetchManagedWallet()]);
  } finally {
    isTickingRef.current = false;
  }
}, POLLING_INTERVAL_MS);
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 21fadad and a4a4dd0.

📒 Files selected for processing (13)
  • apps/deploy-web/src/context/PaymentPollingProvider/PaymentPollingProvider.spec.tsx (1 hunks)
  • apps/deploy-web/src/context/PaymentPollingProvider/PaymentPollingProvider.tsx (1 hunks)
  • apps/deploy-web/src/context/PaymentPollingProvider/index.ts (1 hunks)
  • apps/deploy-web/src/pages/_app.tsx (2 hunks)
  • apps/deploy-web/src/pages/payment.tsx (5 hunks)
  • apps/deploy-web/src/queries/queryKeys.ts (1 hunks)
  • apps/deploy-web/src/queries/useManagedWalletQuery.ts (2 hunks)
  • apps/deploy-web/src/services/analytics/analytics.service.ts (1 hunks)
  • apps/deploy-web/tests/seeders/analytics.ts (1 hunks)
  • apps/deploy-web/tests/seeders/index.ts (1 hunks)
  • apps/deploy-web/tests/seeders/managedWallet.ts (1 hunks)
  • apps/deploy-web/tests/seeders/snackbar.ts (1 hunks)
  • apps/deploy-web/tests/seeders/walletBalance.ts (1 hunks)
🧰 Additional context used
📓 Path-based instructions (4)
**/*.{ts,tsx}

📄 CodeRabbit inference engine (.cursor/rules/general.mdc)

Never use type any or cast to type any. Always define the proper TypeScript types.

Files:

  • apps/deploy-web/src/queries/queryKeys.ts
  • apps/deploy-web/tests/seeders/analytics.ts
  • apps/deploy-web/tests/seeders/index.ts
  • apps/deploy-web/src/context/PaymentPollingProvider/PaymentPollingProvider.tsx
  • apps/deploy-web/src/queries/useManagedWalletQuery.ts
  • apps/deploy-web/src/context/PaymentPollingProvider/index.ts
  • apps/deploy-web/src/services/analytics/analytics.service.ts
  • apps/deploy-web/tests/seeders/walletBalance.ts
  • apps/deploy-web/tests/seeders/snackbar.ts
  • apps/deploy-web/src/pages/payment.tsx
  • apps/deploy-web/src/context/PaymentPollingProvider/PaymentPollingProvider.spec.tsx
  • apps/deploy-web/src/pages/_app.tsx
  • apps/deploy-web/tests/seeders/managedWallet.ts
**/*.{js,ts,tsx}

📄 CodeRabbit inference engine (.cursor/rules/general.mdc)

**/*.{js,ts,tsx}: Never use deprecated methods from libraries.
Don't add unnecessary comments to the code

Files:

  • apps/deploy-web/src/queries/queryKeys.ts
  • apps/deploy-web/tests/seeders/analytics.ts
  • apps/deploy-web/tests/seeders/index.ts
  • apps/deploy-web/src/context/PaymentPollingProvider/PaymentPollingProvider.tsx
  • apps/deploy-web/src/queries/useManagedWalletQuery.ts
  • apps/deploy-web/src/context/PaymentPollingProvider/index.ts
  • apps/deploy-web/src/services/analytics/analytics.service.ts
  • apps/deploy-web/tests/seeders/walletBalance.ts
  • apps/deploy-web/tests/seeders/snackbar.ts
  • apps/deploy-web/src/pages/payment.tsx
  • apps/deploy-web/src/context/PaymentPollingProvider/PaymentPollingProvider.spec.tsx
  • apps/deploy-web/src/pages/_app.tsx
  • apps/deploy-web/tests/seeders/managedWallet.ts
**/*.spec.{ts,tsx}

📄 CodeRabbit inference engine (.cursor/rules/no-jest-mock.mdc)

Don't use jest.mock() to mock dependencies in test files. Instead, use jest-mock-extended to create mocks and pass mocks as dependencies to the service under test.

**/*.spec.{ts,tsx}: Use setup function instead of beforeEach in test files
setup function must be at the bottom of the root describe block in test files
setup function creates an object under test and returns it
setup function should accept a single parameter with inline type definition
Don't use shared state in setup function
Don't specify return type of setup function

Files:

  • apps/deploy-web/src/context/PaymentPollingProvider/PaymentPollingProvider.spec.tsx
apps/{deploy-web,provider-console}/**/*.spec.tsx

📄 CodeRabbit inference engine (.cursor/rules/query-by-in-tests.mdc)

Use queryBy methods instead of getBy methods in test expectations in .spec.tsx files

Files:

  • apps/deploy-web/src/context/PaymentPollingProvider/PaymentPollingProvider.spec.tsx
🧬 Code graph analysis (9)
apps/deploy-web/src/queries/queryKeys.ts (1)
apps/notifications/src/interfaces/rest/services/auth/auth.service.ts (1)
  • userId (18-25)
apps/deploy-web/tests/seeders/analytics.ts (1)
apps/deploy-web/src/services/analytics/analytics.service.ts (1)
  • AnalyticsService (142-271)
apps/deploy-web/src/context/PaymentPollingProvider/PaymentPollingProvider.tsx (1)
apps/deploy-web/src/services/analytics/analytics.service.ts (1)
  • analyticsService (278-295)
apps/deploy-web/src/queries/useManagedWalletQuery.ts (2)
apps/deploy-web/src/context/ServicesProvider/ServicesProvider.tsx (1)
  • useServices (27-29)
apps/deploy-web/src/queries/queryKeys.ts (1)
  • QueryKeys (1-123)
apps/deploy-web/tests/seeders/walletBalance.ts (1)
apps/deploy-web/src/hooks/useWalletBalance.ts (1)
  • WalletBalance (14-26)
apps/deploy-web/src/pages/payment.tsx (1)
apps/deploy-web/src/context/PaymentPollingProvider/PaymentPollingProvider.tsx (1)
  • usePaymentPolling (183-189)
apps/deploy-web/src/context/PaymentPollingProvider/PaymentPollingProvider.spec.tsx (6)
apps/deploy-web/src/context/PaymentPollingProvider/PaymentPollingProvider.tsx (3)
  • PaymentPollingProvider (45-181)
  • usePaymentPolling (183-189)
  • DEPENDENCIES (14-21)
apps/deploy-web/tests/seeders/analytics.ts (1)
  • buildAnalyticsService (5-8)
apps/deploy-web/tests/seeders/snackbar.ts (1)
  • buildSnackbarService (6-10)
apps/deploy-web/tests/seeders/wallet.ts (1)
  • buildWallet (7-25)
apps/deploy-web/tests/seeders/managedWallet.ts (1)
  • buildManagedWallet (4-13)
apps/deploy-web/tests/seeders/walletBalance.ts (1)
  • buildWalletBalance (5-18)
apps/deploy-web/src/pages/_app.tsx (1)
apps/deploy-web/src/context/PaymentPollingProvider/PaymentPollingProvider.tsx (1)
  • PaymentPollingProvider (45-181)
apps/deploy-web/tests/seeders/managedWallet.ts (1)
packages/http-sdk/src/managed-wallet-http/managed-wallet-http.service.ts (1)
  • ApiManagedWalletOutput (59-59)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (2)
  • GitHub Check: validate / validate-app
  • GitHub Check: test-build
🔇 Additional comments (8)
apps/deploy-web/tests/seeders/managedWallet.ts (1)

4-13: Seeder looks good

Good default shape and override precedence. Suits tests.

apps/deploy-web/src/queries/useManagedWalletQuery.ts (1)

10-10: Standardizing the query key via QueryKeys: LGTM

Consistent key construction in query and cache update.

Also applies to: 30-30

apps/deploy-web/tests/seeders/walletBalance.ts (1)

5-18: LGTM

Realistic ranges and override support look good for tests.

apps/deploy-web/src/services/analytics/analytics.service.ts (1)

72-72: LGTM: new event type

Adding "trial_completed" integrates cleanly; GA mapping safely falls back to the event name.

apps/deploy-web/src/pages/_app.tsx (1)

81-89: Provider placement looks correct

Wrapping with PaymentPollingProvider above CertificateProvider is sensible and preserves access to Services/Query/Snackbar providers from AppRoot.

apps/deploy-web/src/context/PaymentPollingProvider/index.ts (1)

1-2: Barrel re-exports: LGTM

Correctly exposes runtime and types for consumers.

apps/deploy-web/tests/seeders/index.ts (1)

2-2: Consolidated seeders export: LGTM

Centralized imports improve test ergonomics.

Also applies to: 9-9, 14-14, 18-18

apps/deploy-web/src/pages/payment.tsx (1)

48-52: Nice touch wiring polling into the 3DS success flow

Triggering pollForPayment() straight from the 3DS success callback keeps the wallet refresh consistent with the immediate-success path. Looks solid.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3

🧹 Nitpick comments (6)
apps/deploy-web/src/context/PaymentPollingProvider/PaymentPollingProvider.spec.tsx (2)

101-105: Avoid hard‑coding polling durations in tests

Using literal 1000/30000 couples tests to internal timings. Prefer advanceTimersToNextTimer() for intervals and runOnlyPendingTimers()/runAllTimers() for timeouts to reduce brittleness.

- jest.advanceTimersByTime(1000);
+ jest.advanceTimersToNextTimer();

- jest.advanceTimersByTime(30000);
+ jest.runAllTimers(); // or runOnlyPendingTimers(), depending on intent

Also applies to: 127-131, 167-169


139-153: Strengthen analytics assertion

This only checks the function exists. Consider simulating a balance increase and asserting analyticsService.track("trial_completed", ...) is called for trial users.

I can sketch a helper that updates the mocked useWalletBalance() return to trigger the success path.

apps/deploy-web/src/context/PaymentPollingProvider/PaymentPollingProvider.tsx (4)

53-54: Use environment‑agnostic timer type

NodeJS.Timeout can clash in browser builds. Prefer ReturnType<typeof setInterval>.

-  const pollingRef = useRef<NodeJS.Timeout | null>(null);
+  const pollingRef = useRef<ReturnType<typeof setInterval> | null>(null);

4-4: Type snackbar keys explicitly

Use SnackbarKey for better type safety.

-import { useSnackbar } from "notistack";
+import { useSnackbar, type SnackbarKey } from "notistack";
@@
-  const loadingSnackbarKeyRef = useRef<string | number | null>(null);
+  const loadingSnackbarKeyRef = useRef<SnackbarKey | null>(null);

Also applies to: 58-58


113-118: Remove unused wasTrialingRef and its effect

wasTrialingRef is written but never read. Drop it to reduce noise.

-  const wasTrialingRef = useRef<boolean>(wasTrialing);
   const initialTrialingRef = useRef<boolean>(wasTrialing);
@@
-  useEffect(
-    function updateWasTrialingRef() {
-      wasTrialingRef.current = wasTrialing;
-    },
-    [wasTrialing]
-  );

Also applies to: 56-56


96-96: Minor: prefer nullish coalescing

Avoid treating 0 specially; startTimeRef is number | null, so ?? better conveys intent.

-        const elapsed = Date.now() - (startTimeRef.current || 0);
+        const elapsed = Date.now() - (startTimeRef.current ?? 0);
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between a4a4dd0 and 51998d7.

📒 Files selected for processing (4)
  • apps/deploy-web/src/context/PaymentPollingProvider/PaymentPollingProvider.spec.tsx (1 hunks)
  • apps/deploy-web/src/context/PaymentPollingProvider/PaymentPollingProvider.tsx (1 hunks)
  • apps/deploy-web/tests/seeders/analytics.ts (1 hunks)
  • apps/deploy-web/tests/seeders/snackbar.ts (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • apps/deploy-web/tests/seeders/snackbar.ts
🧰 Additional context used
📓 Path-based instructions (4)
**/*.{ts,tsx}

📄 CodeRabbit inference engine (.cursor/rules/general.mdc)

Never use type any or cast to type any. Always define the proper TypeScript types.

Files:

  • apps/deploy-web/tests/seeders/analytics.ts
  • apps/deploy-web/src/context/PaymentPollingProvider/PaymentPollingProvider.tsx
  • apps/deploy-web/src/context/PaymentPollingProvider/PaymentPollingProvider.spec.tsx
**/*.{js,ts,tsx}

📄 CodeRabbit inference engine (.cursor/rules/general.mdc)

**/*.{js,ts,tsx}: Never use deprecated methods from libraries.
Don't add unnecessary comments to the code

Files:

  • apps/deploy-web/tests/seeders/analytics.ts
  • apps/deploy-web/src/context/PaymentPollingProvider/PaymentPollingProvider.tsx
  • apps/deploy-web/src/context/PaymentPollingProvider/PaymentPollingProvider.spec.tsx
**/*.spec.{ts,tsx}

📄 CodeRabbit inference engine (.cursor/rules/no-jest-mock.mdc)

Don't use jest.mock() to mock dependencies in test files. Instead, use jest-mock-extended to create mocks and pass mocks as dependencies to the service under test.

**/*.spec.{ts,tsx}: Use setup function instead of beforeEach in test files
setup function must be at the bottom of the root describe block in test files
setup function creates an object under test and returns it
setup function should accept a single parameter with inline type definition
Don't use shared state in setup function
Don't specify return type of setup function

Files:

  • apps/deploy-web/src/context/PaymentPollingProvider/PaymentPollingProvider.spec.tsx
apps/{deploy-web,provider-console}/**/*.spec.tsx

📄 CodeRabbit inference engine (.cursor/rules/query-by-in-tests.mdc)

Use queryBy methods instead of getBy methods in test expectations in .spec.tsx files

Files:

  • apps/deploy-web/src/context/PaymentPollingProvider/PaymentPollingProvider.spec.tsx
🧠 Learnings (6)
📚 Learning: 2025-07-27T12:16:08.566Z
Learnt from: CR
PR: akash-network/console#0
File: .cursor/rules/general.mdc:0-0
Timestamp: 2025-07-27T12:16:08.566Z
Learning: Applies to **/*.{ts,tsx} : Never use type any or cast to type any. Always define the proper TypeScript types.

Applied to files:

  • apps/deploy-web/tests/seeders/analytics.ts
📚 Learning: 2025-07-21T08:24:24.269Z
Learnt from: CR
PR: akash-network/console#0
File: .cursor/rules/no-jest-mock.mdc:0-0
Timestamp: 2025-07-21T08:24:24.269Z
Learning: Applies to **/*.spec.{ts,tsx} : Don't use `jest.mock()` to mock dependencies in test files. Instead, use `jest-mock-extended` to create mocks and pass mocks as dependencies to the service under test.

Applied to files:

  • apps/deploy-web/src/context/PaymentPollingProvider/PaymentPollingProvider.spec.tsx
📚 Learning: 2025-07-21T08:24:27.953Z
Learnt from: CR
PR: akash-network/console#0
File: .cursor/rules/query-by-in-tests.mdc:0-0
Timestamp: 2025-07-21T08:24:27.953Z
Learning: Applies to apps/{deploy-web,provider-console}/**/*.spec.tsx : Use `queryBy` methods instead of `getBy` methods in test expectations in `.spec.tsx` files

Applied to files:

  • apps/deploy-web/src/context/PaymentPollingProvider/PaymentPollingProvider.spec.tsx
📚 Learning: 2025-07-21T08:25:07.474Z
Learnt from: CR
PR: akash-network/console#0
File: .cursor/rules/setup-instead-of-before-each.mdc:0-0
Timestamp: 2025-07-21T08:25:07.474Z
Learning: Applies to **/*.spec.{ts,tsx} : Use `setup` function instead of `beforeEach` in test files

Applied to files:

  • apps/deploy-web/src/context/PaymentPollingProvider/PaymentPollingProvider.spec.tsx
📚 Learning: 2025-07-21T08:25:07.474Z
Learnt from: CR
PR: akash-network/console#0
File: .cursor/rules/setup-instead-of-before-each.mdc:0-0
Timestamp: 2025-07-21T08:25:07.474Z
Learning: Applies to **/*.spec.{ts,tsx} : Don't use shared state in `setup` function

Applied to files:

  • apps/deploy-web/src/context/PaymentPollingProvider/PaymentPollingProvider.spec.tsx
📚 Learning: 2025-07-21T08:25:07.474Z
Learnt from: CR
PR: akash-network/console#0
File: .cursor/rules/setup-instead-of-before-each.mdc:0-0
Timestamp: 2025-07-21T08:25:07.474Z
Learning: Applies to **/*.spec.{ts,tsx} : `setup` function must be at the bottom of the root `describe` block in test files

Applied to files:

  • apps/deploy-web/src/context/PaymentPollingProvider/PaymentPollingProvider.spec.tsx
🧬 Code graph analysis (3)
apps/deploy-web/tests/seeders/analytics.ts (1)
apps/deploy-web/src/services/analytics/analytics.service.ts (1)
  • AnalyticsService (142-271)
apps/deploy-web/src/context/PaymentPollingProvider/PaymentPollingProvider.tsx (1)
apps/deploy-web/src/services/analytics/analytics.service.ts (1)
  • analyticsService (278-295)
apps/deploy-web/src/context/PaymentPollingProvider/PaymentPollingProvider.spec.tsx (6)
apps/deploy-web/src/context/PaymentPollingProvider/PaymentPollingProvider.tsx (3)
  • PaymentPollingProvider (45-181)
  • usePaymentPolling (183-189)
  • DEPENDENCIES (14-21)
apps/deploy-web/tests/seeders/analytics.ts (1)
  • buildAnalyticsService (7-10)
apps/deploy-web/tests/seeders/snackbar.ts (1)
  • buildSnackbarService (14-23)
apps/deploy-web/tests/seeders/wallet.ts (1)
  • buildWallet (7-25)
apps/deploy-web/tests/seeders/managedWallet.ts (1)
  • buildManagedWallet (4-13)
apps/deploy-web/tests/seeders/walletBalance.ts (1)
  • buildWalletBalance (5-18)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (10)
  • GitHub Check: indexer-ci
  • GitHub Check: test-build
  • GitHub Check: test-build
  • GitHub Check: test-build
  • GitHub Check: validate / validate-app
  • GitHub Check: test-build
  • GitHub Check: validate / validate-app
  • GitHub Check: test-build
  • GitHub Check: validate / validate-app
  • GitHub Check: test-build
🔇 Additional comments (1)
apps/deploy-web/tests/seeders/analytics.ts (1)

3-10: Typed mock looks solid; no any usage

The seeder correctly types track against the real service and avoids any. This keeps tests aligned with production overloads.

If TS complains about overloads, I can adjust the mock to a concrete signature union for track.

stalniy
stalniy previously approved these changes Sep 29, 2025
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3

🧹 Nitpick comments (5)
apps/deploy-web/src/context/PaymentPollingProvider/PaymentPollingProvider.tsx (3)

99-109: Guard with ref to avoid start race.

Checking only state can race on rapid double‑click before setState flush. Also check the ref which is synchronous.

-    (initialBalance?: number | null) => {
-      if (isPolling) {
+    (initialBalance?: number | null) => {
+      if (isPolling || isPollingRef.current) {
         return;
       }

90-96: Refetch errors aren’t caught (async).

refetchBalance/refetchManagedWallet likely return promises; calling without await makes try/catch ineffective. Consider an async poll that awaits both and handles rejections, then schedules the next tick.

-  const executePoll = useCallback(() => {
+  const executePoll = useCallback(async () => {
     attemptCountRef.current++;
@@
-    try {
-      refetchBalance();
-      refetchManagedWallet();
-    } catch (error) {
-      console.error("Error during polling:", error);
-    }
+    try {
+      await Promise.allSettled([refetchBalance(), refetchManagedWallet()]);
+    } catch (error) {
+      console.error("Error during polling:", error);
+    }
   }, [stopPolling, enqueueSnackbar, refetchBalance, refetchManagedWallet, d]);

And trigger it with void executePoll() where called. This also aligns with the earlier “recursive setTimeout waits for work” guidance.


58-59: Remove unused wasTrialingRef.

The ref is written but never read; drop the ref and the effect to reduce noise.

-  const wasTrialingRef = useRef<boolean>(wasTrialing);
@@
-  useEffect(
-    function updateWasTrialingRef() {
-      wasTrialingRef.current = wasTrialing;
-    },
-    [wasTrialing]
-  );

Also applies to: 124-129

apps/deploy-web/src/context/PaymentPollingProvider/PaymentPollingProvider.spec.tsx (2)

270-293: Type the injected dependencies; remove the double cast.

Avoid unknown as. Give dependencies and mockSnackbar concrete types to satisfy typeof DEPENDENCIES.

-    const dependencies = {
+    const mockSnackbar: typeof DEPENDENCIES["Snackbar"] = ({ title, subTitle, iconVariant, showLoading }) => (
+      <div data-testid="snackbar" data-title={title} data-subtitle={subTitle} data-icon-variant={iconVariant} data-show-loading={showLoading} />
+    );
+
+    const dependencies: typeof DEPENDENCIES = {
       ...DEPENDENCIES,
       useWallet: jest.fn(() => wallet),
@@
-      useSnackbar: jest.fn(() => ({
+      useSnackbar: jest.fn((): ReturnType<typeof DEPENDENCIES["useSnackbar"]> => ({
         enqueueSnackbar: mockEnqueueSnackbar,
         closeSnackbar: mockCloseSnackbar
       })),
-      Snackbar: mockSnackbar
-    } as unknown as typeof DEPENDENCIES;
+      Snackbar: mockSnackbar
+    };

As per coding guidelines.


23-43: Minor: align timer advance with polling interval.

Advance by POLLING_INTERVAL_MS (2000) for clarity. Current 1000ms works only because of the immediate first poll.

-      jest.advanceTimersByTime(1000);
+      jest.advanceTimersByTime(2000);
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 51998d7 and 99b63d5.

📒 Files selected for processing (2)
  • apps/deploy-web/src/context/PaymentPollingProvider/PaymentPollingProvider.spec.tsx (1 hunks)
  • apps/deploy-web/src/context/PaymentPollingProvider/PaymentPollingProvider.tsx (1 hunks)
🧰 Additional context used
📓 Path-based instructions (4)
**/*.spec.{ts,tsx}

📄 CodeRabbit inference engine (.cursor/rules/no-jest-mock.mdc)

Don't use jest.mock() to mock dependencies in test files. Instead, use jest-mock-extended to create mocks and pass mocks as dependencies to the service under test.

**/*.spec.{ts,tsx}: Use setup function instead of beforeEach in test files
setup function must be at the bottom of the root describe block in test files
setup function creates an object under test and returns it
setup function should accept a single parameter with inline type definition
Don't use shared state in setup function
Don't specify return type of setup function

Files:

  • apps/deploy-web/src/context/PaymentPollingProvider/PaymentPollingProvider.spec.tsx
apps/{deploy-web,provider-console}/**/*.spec.tsx

📄 CodeRabbit inference engine (.cursor/rules/query-by-in-tests.mdc)

Use queryBy methods instead of getBy methods in test expectations in .spec.tsx files

Files:

  • apps/deploy-web/src/context/PaymentPollingProvider/PaymentPollingProvider.spec.tsx
**/*.{ts,tsx}

📄 CodeRabbit inference engine (.cursor/rules/general.mdc)

Never use type any or cast to type any. Always define the proper TypeScript types.

Files:

  • apps/deploy-web/src/context/PaymentPollingProvider/PaymentPollingProvider.spec.tsx
  • apps/deploy-web/src/context/PaymentPollingProvider/PaymentPollingProvider.tsx
**/*.{js,ts,tsx}

📄 CodeRabbit inference engine (.cursor/rules/general.mdc)

**/*.{js,ts,tsx}: Never use deprecated methods from libraries.
Don't add unnecessary comments to the code

Files:

  • apps/deploy-web/src/context/PaymentPollingProvider/PaymentPollingProvider.spec.tsx
  • apps/deploy-web/src/context/PaymentPollingProvider/PaymentPollingProvider.tsx
🧠 Learnings (5)
📚 Learning: 2025-07-21T08:24:24.269Z
Learnt from: CR
PR: akash-network/console#0
File: .cursor/rules/no-jest-mock.mdc:0-0
Timestamp: 2025-07-21T08:24:24.269Z
Learning: Applies to **/*.spec.{ts,tsx} : Don't use `jest.mock()` to mock dependencies in test files. Instead, use `jest-mock-extended` to create mocks and pass mocks as dependencies to the service under test.

Applied to files:

  • apps/deploy-web/src/context/PaymentPollingProvider/PaymentPollingProvider.spec.tsx
📚 Learning: 2025-07-21T08:24:27.953Z
Learnt from: CR
PR: akash-network/console#0
File: .cursor/rules/query-by-in-tests.mdc:0-0
Timestamp: 2025-07-21T08:24:27.953Z
Learning: Applies to apps/{deploy-web,provider-console}/**/*.spec.tsx : Use `queryBy` methods instead of `getBy` methods in test expectations in `.spec.tsx` files

Applied to files:

  • apps/deploy-web/src/context/PaymentPollingProvider/PaymentPollingProvider.spec.tsx
📚 Learning: 2025-07-21T08:25:07.474Z
Learnt from: CR
PR: akash-network/console#0
File: .cursor/rules/setup-instead-of-before-each.mdc:0-0
Timestamp: 2025-07-21T08:25:07.474Z
Learning: Applies to **/*.spec.{ts,tsx} : Use `setup` function instead of `beforeEach` in test files

Applied to files:

  • apps/deploy-web/src/context/PaymentPollingProvider/PaymentPollingProvider.spec.tsx
📚 Learning: 2025-07-21T08:25:07.474Z
Learnt from: CR
PR: akash-network/console#0
File: .cursor/rules/setup-instead-of-before-each.mdc:0-0
Timestamp: 2025-07-21T08:25:07.474Z
Learning: Applies to **/*.spec.{ts,tsx} : Don't use shared state in `setup` function

Applied to files:

  • apps/deploy-web/src/context/PaymentPollingProvider/PaymentPollingProvider.spec.tsx
📚 Learning: 2025-07-21T08:25:07.474Z
Learnt from: CR
PR: akash-network/console#0
File: .cursor/rules/setup-instead-of-before-each.mdc:0-0
Timestamp: 2025-07-21T08:25:07.474Z
Learning: Applies to **/*.spec.{ts,tsx} : `setup` function must be at the bottom of the root `describe` block in test files

Applied to files:

  • apps/deploy-web/src/context/PaymentPollingProvider/PaymentPollingProvider.spec.tsx
🧬 Code graph analysis (1)
apps/deploy-web/src/context/PaymentPollingProvider/PaymentPollingProvider.tsx (1)
apps/deploy-web/src/services/analytics/analytics.service.ts (1)
  • analyticsService (278-295)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (9)
  • GitHub Check: test-build
  • GitHub Check: validate / validate-app
  • GitHub Check: validate / validate-app
  • GitHub Check: test-build
  • GitHub Check: test-build
  • GitHub Check: test-build
  • GitHub Check: test-build
  • GitHub Check: validate / validate-app
  • GitHub Check: test-build
🔇 Additional comments (5)
apps/deploy-web/src/context/PaymentPollingProvider/PaymentPollingProvider.tsx (2)

152-155: Good fix: zero balance guard.

Switching to initialBalanceRef.current == null correctly allows an initial balance of 0.


160-173: Close the loading snackbar on success for both trial and non‑trial users.

Today the spinner persists for trial users until trial status flips, showing success and loading together. Close it immediately on success, regardless of trial state.

       if (currentTotalBalance > initialBalanceValue) {
         enqueueSnackbar(<d.Snackbar title="Payment successful!" subTitle="Your balance has been updated" iconVariant="success" />, { variant: "success" });
+        if (loadingSnackbarKeyRef.current) {
+          closeSnackbar(loadingSnackbarKeyRef.current);
+          loadingSnackbarKeyRef.current = null;
+        }
 
         // If user was not trialing, we can stop polling immediately
         if (!initialTrialingRef.current) {
           stopPolling();
           return;
         }
 
         analyticsService.track("trial_completed", {
           category: "user",
           label: "First payment completed"
         });
       }
apps/deploy-web/src/context/PaymentPollingProvider/PaymentPollingProvider.spec.tsx (3)

10-22: Ensure cleanup runs; restore timers deterministically.

Some tests don’t call cleanup(), leaving fake timers enabled across tests. Wrap each test that calls setup() in try/finally and always invoke cleanup.

-  it("provides polling context to children", () => {
-    setup({ ... });
-    expect(screen.queryByTestId("is-polling")).toHaveTextContent("false");
-    ...
-  });
+  it("provides polling context to children", () => {
+    const { cleanup } = setup({ ... });
+    try {
+      expect(screen.queryByTestId("is-polling")).toHaveTextContent("false");
+      ...
+    } finally {
+      cleanup();
+    }
+  });

Apply similarly to other tests invoking setup() without cleanup.


1-9: Good: module mocks removed; DI used instead.
This follows our “no jest.mock in specs” rule and prior feedback.


245-329: Good: timers are set up via setup; no beforeEach/afterEach.
Conforms to the testing guideline.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🧹 Nitpick comments (2)
apps/deploy-web/src/hooks/useManagedWallet.ts (2)

75-81: Minor: simplify constant truths inside the wallet branch.

Inside the truthy wallet branch, isConfigured is always true. Consider setting these literals directly to match the API type and avoid boolean widening:

-            isWalletConnected: isConfigured,
-            isWalletLoaded: isConfigured,
+            isWalletConnected: true,
+            isWalletLoaded: true,

This keeps the literal types aligned with ApiManagedWalletOutput and reduces type friction for consumers.


84-85: Annotate useManagedWallet with an explicit return type
In apps/deploy-web/src/hooks/useManagedWallet.ts export a UseManagedWalletResult type (or interface) and update the hook signature to (): UseManagedWalletResult to lock down its return shape—this will catch future additions (like isFetching) as type errors in all consumers.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 99b63d5 and 63bd5aa.

📒 Files selected for processing (3)
  • apps/deploy-web/src/context/PaymentPollingProvider/PaymentPollingProvider.spec.tsx (1 hunks)
  • apps/deploy-web/src/context/PaymentPollingProvider/PaymentPollingProvider.tsx (1 hunks)
  • apps/deploy-web/src/hooks/useManagedWallet.ts (3 hunks)
🚧 Files skipped from review as they are similar to previous changes (2)
  • apps/deploy-web/src/context/PaymentPollingProvider/PaymentPollingProvider.tsx
  • apps/deploy-web/src/context/PaymentPollingProvider/PaymentPollingProvider.spec.tsx
🧰 Additional context used
📓 Path-based instructions (2)
**/*.{ts,tsx}

📄 CodeRabbit inference engine (.cursor/rules/general.mdc)

Never use type any or cast to type any. Always define the proper TypeScript types.

Files:

  • apps/deploy-web/src/hooks/useManagedWallet.ts
**/*.{js,ts,tsx}

📄 CodeRabbit inference engine (.cursor/rules/general.mdc)

**/*.{js,ts,tsx}: Never use deprecated methods from libraries.
Don't add unnecessary comments to the code

Files:

  • apps/deploy-web/src/hooks/useManagedWallet.ts
🧬 Code graph analysis (1)
apps/deploy-web/src/hooks/useManagedWallet.ts (2)
apps/deploy-web/src/queries/useManagedWalletQuery.ts (2)
  • useManagedWalletQuery (7-20)
  • useCreateManagedWalletMutation (22-34)
packages/http-sdk/src/managed-wallet-http/managed-wallet-http.service.ts (1)
  • ApiManagedWalletOutput (59-59)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (9)
  • GitHub Check: test-build
  • GitHub Check: test-build
  • GitHub Check: validate / validate-app
  • GitHub Check: test-build
  • GitHub Check: test-build
  • GitHub Check: validate / validate-app
  • GitHub Check: validate / validate-app
  • GitHub Check: test-build
  • GitHub Check: test-build
🔇 Additional comments (3)
apps/deploy-web/src/hooks/useManagedWallet.ts (3)

38-38: Dependency array fix is correct.

Including setIsSignedInWithTrial removes a potential stale-closure pitfall. LGTM.


88-88: Memo deps updated correctly.

Including isFetching prevents stale values in the returned object. LGTM.


21-25: Semantics change — update callers that relied on isLoading to include background refetches.

useManagedWallet now sets isLoading = isInitialLoading || isCreating; background refetches are available via isFetching. Update callers that need refetches counted as “loading” (apps/deploy-web/src/context/WalletProvider/WalletProvider.tsx currently destructures isLoading) — add isFetching and combine (e.g. const isManagedWalletLoading = isManagedWalletLoading || isManagedWalletFetching).

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

🧹 Nitpick comments (3)
apps/deploy-web/src/context/PaymentPollingProvider/PaymentPollingProvider.spec.tsx (3)

220-222: Remove double assertion; type dependencies and Snackbar precisely.

Avoid as unknown as typeof DEPENDENCIES. Provide correctly typed mocks and a typed dependencies object; type Snackbar via the real dependency type.

As per coding guidelines

-    const mockSnackbar = ({ title, subTitle, iconVariant, showLoading }: { title: string; subTitle: string; iconVariant?: string; showLoading?: boolean }) => (
+    const mockSnackbar: typeof DEPENDENCIES["Snackbar"] = ({ title, subTitle, iconVariant, showLoading }) => (
       <div data-testid="snackbar" data-title={title} data-subtitle={subTitle} data-icon-variant={iconVariant} data-show-loading={showLoading} />
     );
@@
-    const dependencies = {
-      ...DEPENDENCIES,
-      useWallet: jest.fn(() => wallet),
-      useWalletBalance: jest.fn(() => ({
-        balance: walletBalance,
-        refetch: refetchBalance,
-        isLoading: input.isWalletBalanceLoading
-      })),
-      useManagedWallet: jest.fn(() => ({
-        wallet: mockManagedWallet,
-        isLoading: false,
-        isFetching: false,
-        createError: null,
-        refetch: refetchManagedWallet,
-        create: jest.fn()
-      })),
-      useServices: jest.fn(() => ({
-        analyticsService
-      })),
-      useSnackbar: jest.fn(() => ({
-        enqueueSnackbar: mockEnqueueSnackbar,
-        closeSnackbar: mockCloseSnackbar
-      })),
-      Snackbar: mockSnackbar
-    } as unknown as typeof DEPENDENCIES;
+    const useWalletMock: typeof DEPENDENCIES["useWallet"] = jest.fn(() => wallet);
+    const useWalletBalanceMock: typeof DEPENDENCIES["useWalletBalance"] = jest.fn(() => ({
+      balance: walletBalance,
+      refetch: refetchBalance,
+      isLoading: input.isWalletBalanceLoading
+    }));
+    const useManagedWalletMock: typeof DEPENDENCIES["useManagedWallet"] = jest.fn(() => ({
+      wallet: mockManagedWallet,
+      isLoading: false,
+      isFetching: false,
+      createError: null,
+      refetch: refetchManagedWallet,
+      create: jest.fn()
+    }));
+    const useServicesMock: typeof DEPENDENCIES["useServices"] = jest.fn(() => ({ analyticsService }));
+    const useSnackbarMock: typeof DEPENDENCIES["useSnackbar"] = jest.fn(() => ({
+      enqueueSnackbar: mockEnqueueSnackbar,
+      closeSnackbar: mockCloseSnackbar
+    }));
+
+    const dependencies: typeof DEPENDENCIES = {
+      ...DEPENDENCIES,
+      useWallet: useWalletMock,
+      useWalletBalance: useWalletBalanceMock,
+      useManagedWallet: useManagedWalletMock,
+      useServices: useServicesMock,
+      useSnackbar: useSnackbarMock,
+      Snackbar: mockSnackbar
+    };

Also applies to: 233-257


31-32: Optional: prefer userEvent over element.click for realistic interactions.

Switching to userEvent improves fidelity and auto‑act behavior. Since fake timers are in use, initialize user with advanceTimers.

Example:

-    await act(async () => {
-      screen.getByTestId("start-polling").click();
-    });
+    const user = userEvent.setup({ advanceTimers: jest.advanceTimersByTime });
+    await user.click(screen.getByTestId("start-polling"));

Add once at top:

+import userEvent from "@testing-library/user-event";

Also applies to: 37-38, 51-52, 72-73, 94-95, 118-119, 158-159, 178-179


135-149: Increase behavioral coverage: assert analytics fires on balance increase for trial users.

Add a test that starts polling with isTrialing=true and initial balance X, then re‑renders provider with balance > X; expect analyticsService.track("trial_completed", …) to be called.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 19a41e7 and 4f73911.

📒 Files selected for processing (1)
  • apps/deploy-web/src/context/PaymentPollingProvider/PaymentPollingProvider.spec.tsx (1 hunks)
🧰 Additional context used
📓 Path-based instructions (4)
**/*.spec.{ts,tsx}

📄 CodeRabbit inference engine (.cursor/rules/no-jest-mock.mdc)

Don't use jest.mock() to mock dependencies in test files. Instead, use jest-mock-extended to create mocks and pass mocks as dependencies to the service under test.

**/*.spec.{ts,tsx}: Use setup function instead of beforeEach in test files
setup function must be at the bottom of the root describe block in test files
setup function creates an object under test and returns it
setup function should accept a single parameter with inline type definition
Don't use shared state in setup function
Don't specify return type of setup function

Files:

  • apps/deploy-web/src/context/PaymentPollingProvider/PaymentPollingProvider.spec.tsx
apps/{deploy-web,provider-console}/**/*.spec.tsx

📄 CodeRabbit inference engine (.cursor/rules/query-by-in-tests.mdc)

Use queryBy methods instead of getBy methods in test expectations in .spec.tsx files

Files:

  • apps/deploy-web/src/context/PaymentPollingProvider/PaymentPollingProvider.spec.tsx
**/*.{ts,tsx}

📄 CodeRabbit inference engine (.cursor/rules/general.mdc)

Never use type any or cast to type any. Always define the proper TypeScript types.

Files:

  • apps/deploy-web/src/context/PaymentPollingProvider/PaymentPollingProvider.spec.tsx
**/*.{js,ts,tsx}

📄 CodeRabbit inference engine (.cursor/rules/general.mdc)

**/*.{js,ts,tsx}: Never use deprecated methods from libraries.
Don't add unnecessary comments to the code

Files:

  • apps/deploy-web/src/context/PaymentPollingProvider/PaymentPollingProvider.spec.tsx
🧠 Learnings (5)
📚 Learning: 2025-07-21T08:24:24.269Z
Learnt from: CR
PR: akash-network/console#0
File: .cursor/rules/no-jest-mock.mdc:0-0
Timestamp: 2025-07-21T08:24:24.269Z
Learning: Applies to **/*.spec.{ts,tsx} : Don't use `jest.mock()` to mock dependencies in test files. Instead, use `jest-mock-extended` to create mocks and pass mocks as dependencies to the service under test.

Applied to files:

  • apps/deploy-web/src/context/PaymentPollingProvider/PaymentPollingProvider.spec.tsx
📚 Learning: 2025-07-21T08:24:27.953Z
Learnt from: CR
PR: akash-network/console#0
File: .cursor/rules/query-by-in-tests.mdc:0-0
Timestamp: 2025-07-21T08:24:27.953Z
Learning: Applies to apps/{deploy-web,provider-console}/**/*.spec.tsx : Use `queryBy` methods instead of `getBy` methods in test expectations in `.spec.tsx` files

Applied to files:

  • apps/deploy-web/src/context/PaymentPollingProvider/PaymentPollingProvider.spec.tsx
📚 Learning: 2025-07-21T08:25:07.474Z
Learnt from: CR
PR: akash-network/console#0
File: .cursor/rules/setup-instead-of-before-each.mdc:0-0
Timestamp: 2025-07-21T08:25:07.474Z
Learning: Applies to **/*.spec.{ts,tsx} : Use `setup` function instead of `beforeEach` in test files

Applied to files:

  • apps/deploy-web/src/context/PaymentPollingProvider/PaymentPollingProvider.spec.tsx
📚 Learning: 2025-07-21T08:25:07.474Z
Learnt from: CR
PR: akash-network/console#0
File: .cursor/rules/setup-instead-of-before-each.mdc:0-0
Timestamp: 2025-07-21T08:25:07.474Z
Learning: Applies to **/*.spec.{ts,tsx} : Don't use shared state in `setup` function

Applied to files:

  • apps/deploy-web/src/context/PaymentPollingProvider/PaymentPollingProvider.spec.tsx
📚 Learning: 2025-07-21T08:25:07.474Z
Learnt from: CR
PR: akash-network/console#0
File: .cursor/rules/setup-instead-of-before-each.mdc:0-0
Timestamp: 2025-07-21T08:25:07.474Z
Learning: Applies to **/*.spec.{ts,tsx} : `setup` function must be at the bottom of the root `describe` block in test files

Applied to files:

  • apps/deploy-web/src/context/PaymentPollingProvider/PaymentPollingProvider.spec.tsx
🧬 Code graph analysis (1)
apps/deploy-web/src/context/PaymentPollingProvider/PaymentPollingProvider.spec.tsx (4)
apps/deploy-web/src/context/PaymentPollingProvider/PaymentPollingProvider.tsx (3)
  • PaymentPollingProvider (46-217)
  • usePaymentPolling (219-225)
  • DEPENDENCIES (15-22)
apps/deploy-web/tests/seeders/wallet.ts (1)
  • buildWallet (7-25)
apps/deploy-web/tests/seeders/managedWallet.ts (1)
  • buildManagedWallet (4-13)
apps/deploy-web/tests/seeders/walletBalance.ts (1)
  • buildWalletBalance (5-18)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (10)
  • GitHub Check: test-build
  • GitHub Check: validate / validate-app
  • GitHub Check: test-build
  • GitHub Check: validate / validate-app
  • GitHub Check: test-build
  • GitHub Check: validate / validate-app
  • GitHub Check: test-build
  • GitHub Check: test-build
  • GitHub Check: test-build
  • GitHub Check: test-build
🔇 Additional comments (2)
apps/deploy-web/src/context/PaymentPollingProvider/PaymentPollingProvider.spec.tsx (2)

10-21: Good structure: DI + setup + queryBy in expectations.

  • Uses dependency injection and a bottom‑placed setup helper.
  • No module‑level jest.mock.
  • Expectations use queryBy*. Nice.

As per coding guidelines


11-21: Make timer cleanup deterministic; call cleanup() in every test using setup() and strengthen cleanup.

Some tests call setup() but never invoke cleanup(), leaving fake timers active and the component mounted, which can cause cross‑test flakiness. Wrap each test body in try/finally and call cleanup(); also enhance setup’s cleanup to unmount and clear timers.

As per coding guidelines

Example fix for “provides polling context to children”:

-  it("provides polling context to children", () => {
-    setup({
+  it("provides polling context to children", () => {
+    const { cleanup } = setup({
       isTrialing: false,
       balance: { totalUsd: 100 },
       isWalletBalanceLoading: false
     });
-
-    expect(screen.queryByTestId("is-polling")).toHaveTextContent("false");
-    expect(screen.queryByTestId("start-polling")).toBeInTheDocument();
-    expect(screen.queryByTestId("stop-polling")).toBeInTheDocument();
+    try {
+      expect(screen.queryByTestId("is-polling")).toHaveTextContent("false");
+      expect(screen.queryByTestId("start-polling")).toBeInTheDocument();
+      expect(screen.queryByTestId("stop-polling")).toBeInTheDocument();
+    } finally {
+      cleanup();
+    }
   });

Repeat the pattern for the tests at these ranges: 23–41, 43–62, 64–84, 135–149.

Also upgrade setup’s cleanup to unmount and restore timers:

@@
-    return {
+    return {
       refetchBalance,
@@
-      cleanup: () => {
-        jest.useRealTimers();
-      }
+      cleanup: () => {
+        try {
+          unmount();
+        } finally {
+          jest.clearAllTimers();
+          jest.useRealTimers();
+        }
+      }
     };

Run to enumerate where setup() is used vs. cleanup() calls:

#!/bin/bash
rg -n 'setup\(' apps/deploy-web/src/context/PaymentPollingProvider/PaymentPollingProvider.spec.tsx
rg -n 'cleanup\(\)' apps/deploy-web/src/context/PaymentPollingProvider/PaymentPollingProvider.spec.tsx

Also applies to: 23-41, 43-62, 64-84, 135-149

@baktun14 baktun14 merged commit 9969a28 into main Sep 29, 2025
62 checks passed
@baktun14 baktun14 deleted the features/refresh-balance-after-payment branch September 29, 2025 17:51
stalniy pushed a commit that referenced this pull request Sep 30, 2025
)

* feat(billing): implement polling for balance update after payment

* fix(billing): pr fixes

* fix(billing): improve polling and tests

* fix(billing): pr fixes

* fix(billing): pr fix

* fix(billing): fix tests
stalniy pushed a commit that referenced this pull request Nov 20, 2025
)

* feat(billing): implement polling for balance update after payment

* fix(billing): pr fixes

* fix(billing): improve polling and tests

* fix(billing): pr fixes

* fix(billing): pr fix

* fix(billing): fix tests
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants

Comments