Skip to content

feat(billing): add composable guard for usage page#1710

Merged
baktun14 merged 5 commits intoakash-network:mainfrom
domhhv:feat/billing-usage-page-guard
Jul 30, 2025
Merged

feat(billing): add composable guard for usage page#1710
baktun14 merged 5 commits intoakash-network:mainfrom
domhhv:feat/billing-usage-page-guard

Conversation

@domhhv
Copy link
Contributor

@domhhv domhhv commented Jul 20, 2025

Updates #1348

Summary by CodeRabbit

  • New Features

    • Introduced a flexible access control system allowing multiple conditions to be combined for page access.
    • Enhanced "Billing & Usage" menu item visibility by requiring users to have a managed wallet and be registered, alongside the existing feature flag.
    • Added new user status checks for managed wallet users and registered users to support access controls.
    • Added utilities to generate realistic user data for testing purposes.
  • Refactor

    • Updated the usage and billing pages to use the new composable guard system for improved access management.
  • Tests

    • Added unit tests for the registered user status check hook.

@domhhv domhhv requested a review from a team as a code owner July 20, 2025 19:26
@coderabbitai
Copy link
Contributor

coderabbitai bot commented Jul 20, 2025

Walkthrough

The changes introduce a new higher-order component (HOC) system for access control, featuring a generic Guard HOC and a composeGuards utility. The usage and billing pages now utilize this new guard system, requiring both managed wallet and registered user status. The account menu's "Billing & Usage" item is further gated by wallet management status and user ID presence. New hooks useIsManagedWalletUser and useIsRegisteredUser were added to support these checks. Additionally, tests and seeders for user-related hooks and data were introduced.

Changes

File(s) Change Summary
Account Menu Update
apps/deploy-web/src/components/layout/AccountMenu.tsx
Enhanced conditional rendering of "Billing & Usage" menu item to check for managed wallet and user ID in addition to feature flag.
Guard HOC and Utilities
apps/deploy-web/src/hoc/guard/guard.hoc.tsx
Introduced Guard HOC for access control and composeGuards utility for combining guard hooks.
Usage Page Guard Integration
apps/deploy-web/src/pages/usage/index.tsx
Switched from RegisteredUsersOnly HOC to Guard HOC using composed guard hooks for access control on the usage page.
Billing Page Guard Integration
apps/deploy-web/src/pages/billing/index.tsx
Replaced RegisteredUsersOnly guard with Guard HOC using composed guard hooks for access control on the billing page.
Wallet Context Enhancements
apps/deploy-web/src/context/WalletProvider/WalletProvider.tsx, apps/deploy-web/src/context/WalletProvider/index.ts
Added and exported useIsManagedWalletUser hook to check if wallet is managed.
User Hook Addition
apps/deploy-web/src/hooks/useUser.ts
Added useIsRegisteredUser hook to check if user is registered (has userId).
User Hook Tests
apps/deploy-web/src/hooks/useUser.spec.tsx
Added unit tests for useIsRegisteredUser hook with mocked dependencies and context providers.
User Test Seeders
apps/deploy-web/tests/seeders/user.ts
Added factory functions to generate fake user and anonymous user data for tests using Faker.

Sequence Diagram(s)

sequenceDiagram
    participant User
    participant UsagePage
    participant BillingPage
    participant GuardHOC
    participant useIsManagedWalletUser
    participant useIsRegisteredUser

    User->>GuardHOC: Request UsagePage or BillingPage
    GuardHOC->>useIsManagedWalletUser: Check managed wallet
    GuardHOC->>useIsRegisteredUser: Check registered user
    alt Both checks pass
        GuardHOC->>UsagePage: Render UsagePage
        GuardHOC->>BillingPage: Render BillingPage
    else Any check fails
        GuardHOC->>User: Render fallback (404)
    end
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related PRs

Suggested reviewers

  • baktun14
  • ygrishajev

Poem

In the garden of code, where permissions grow,
New guards now bloom, in a flexible row.
Usage is gated, by wallet and name,
Only the worthy may enter this game.
With hops and with checks, the rabbits agree,
Access is earned, as it ought to be! 🐇✨

Note

⚡️ Unit Test Generation is now available in beta!

Learn more here, or try it out under "Finishing Touches" below.


📜 Recent review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between a174f9c and c8c9505.

📒 Files selected for processing (2)
  • apps/deploy-web/src/hooks/useUser.spec.tsx (1 hunks)
  • apps/deploy-web/src/pages/billing/index.tsx (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • apps/deploy-web/src/hooks/useUser.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/pages/billing/index.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/pages/billing/index.tsx
🧠 Learnings (2)
📓 Common learnings
Learnt from: baktun14
PR: akash-network/console#1725
File: apps/api/src/utils/constants.ts:5-5
Timestamp: 2025-07-24T17:00:52.361Z
Learning: In the Akash Network Console project, when cross-cutting concerns or broader refactoring issues are identified during PR review, the preferred approach is to create a separate GitHub issue to track the work rather than expanding the scope of the current PR. This maintains focus and allows for proper planning of architectural improvements.
apps/deploy-web/src/pages/billing/index.tsx (1)

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

🔇 Additional comments (2)
apps/deploy-web/src/pages/billing/index.tsx (2)

2-4: LGTM: Clean imports for the new guard system.

The imports are well-structured and follow the project's conventions. The separation of concerns is clear with hooks imported from their respective modules and the guard system properly imported from the HOC module.


8-8: Approved: Guard HOC and composeGuards correctly implemented

I’ve confirmed that:

  • Guard HOC invokes the provided useCheck hook at the top level of its returned component.
  • composeGuards returns a single hook that runs each guard (useIsManagedWalletUser, useIsRegisteredUser) in order and short-circuits on failure.
  • Hook ordering and React rules of hooks are preserved.

No further changes are needed here; the billing page now correctly requires both managed-wallet and registered-user status.

✨ Finishing Touches
  • 📝 Generate Docstrings
🧪 Generate unit tests
  • Create PR with unit tests
  • Post copyable unit tests in a comment

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Explain this complex logic.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai explain this code block.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and explain its main purpose.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Support

Need help? Create a ticket on our support page for assistance with any issues or questions.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai generate docstrings to generate docstrings for this PR.
  • @coderabbitai generate sequence diagram to generate a sequence diagram of the changes in this PR.
  • @coderabbitai generate unit tests to generate unit tests for this PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

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 (1)
apps/deploy-web/src/hoc/guard/guard.hoc.tsx (1)

21-23: Consider adding input validation for the composeGuards utility.

The implementation is clean but could benefit from runtime validation to ensure all guards are functions.

 export const composeGuards = (...guards: (() => boolean)[]) => {
+  if (guards.some(guard => typeof guard !== 'function')) {
+    throw new Error('All guards must be functions');
+  }
   return () => guards.every(guard => guard());
 };
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 21c9c9d and a4bf8a3.

📒 Files selected for processing (3)
  • apps/deploy-web/src/components/layout/AccountMenu.tsx (3 hunks)
  • apps/deploy-web/src/hoc/guard/guard.hoc.tsx (1 hunks)
  • apps/deploy-web/src/pages/usage/index.tsx (1 hunks)
🧰 Additional context used
🧠 Learnings (1)
apps/deploy-web/src/components/layout/AccountMenu.tsx (1)
Learnt from: baktun14
PR: akash-network/console#1432
File: apps/deploy-web/src/components/deployments/DeploymentAlerts/DeploymentCloseAlert.tsx:38-38
Timestamp: 2025-06-05T21:07:51.985Z
Learning: The ContactPointSelect component in apps/deploy-web/src/components/alerts/ContactPointSelectForm/ContactPointSelect.tsx uses the useFormContext hook internally to connect to React Hook Form, so it doesn't need to be wrapped in a FormField component.
🧬 Code Graph Analysis (2)
apps/deploy-web/src/components/layout/AccountMenu.tsx (1)
apps/deploy-web/src/context/WalletProvider/WalletProvider.tsx (1)
  • useWallet (352-354)
apps/deploy-web/src/pages/usage/index.tsx (2)
apps/deploy-web/src/hooks/useUser.ts (1)
  • useUser (8-24)
apps/deploy-web/src/hoc/guard/guard.hoc.tsx (2)
  • Guard (3-19)
  • composeGuards (21-23)
⏰ 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/src/hoc/guard/guard.hoc.tsx (1)

3-19: Well-implemented Guard HOC with proper React patterns.

The Guard HOC implementation follows React best practices with proper generic typing, display name preservation, and clean conditional rendering logic.

apps/deploy-web/src/components/layout/AccountMenu.tsx (3)

17-17: LGTM: Proper import of useWallet hook.

The import is correctly placed and follows the existing import pattern.


29-29: LGTM: Clean wallet context usage.

The wallet context is properly initialized and follows the existing pattern.


95-99: Excellent consistency with page-level access controls.

The menu item gating logic now perfectly aligns with the composable guards used in the usage page, ensuring users only see navigation options they can actually access.

apps/deploy-web/src/pages/usage/index.tsx (4)

2-4: LGTM: Clean imports for the new guard system.

All necessary dependencies are properly imported for the composable guard implementation.


8-11: LGTM: Well-implemented managed wallet check.

The hook correctly extracts and returns the isManaged property from the wallet context.


13-16: LGTM: Proper registered user validation.

The hook correctly checks for the presence of userId to determine if a user is registered, using proper boolean coercion.


18-18: Excellent composable guard implementation.

The migration from a single guard to a composable system is well-executed. The two guards (useIsManagedWalletUser and useIsRegisteredUser) are properly composed and will only allow access when both conditions are met.

ygrishajev
ygrishajev previously approved these changes Jul 22, 2025
baktun14
baktun14 previously approved these changes Jul 24, 2025
@domhhv domhhv dismissed stale reviews from baktun14 and ygrishajev via 564cf3f July 24, 2025 22:14
Copy link
Contributor

@ygrishajev ygrishajev left a comment

Choose a reason for hiding this comment

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

I think it wouldn't take much effort to achieve required level of coverage for this PR. Please add some

baktun14
baktun14 previously approved these changes Jul 30, 2025
@domhhv domhhv force-pushed the feat/billing-usage-page-guard branch from 669e177 to 359b7dc Compare July 30, 2025 20:17
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: 2

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 359b7dc and a174f9c.

📒 Files selected for processing (2)
  • apps/deploy-web/src/hooks/useUser.spec.tsx (1 hunks)
  • apps/deploy-web/tests/seeders/user.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/tests/seeders/user.ts
  • apps/deploy-web/src/hooks/useUser.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/user.ts
  • apps/deploy-web/src/hooks/useUser.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/hooks/useUser.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/hooks/useUser.spec.tsx
🧠 Learnings (3)
📓 Common learnings
Learnt from: baktun14
PR: akash-network/console#1725
File: apps/api/src/utils/constants.ts:5-5
Timestamp: 2025-07-24T17:00:52.361Z
Learning: In the Akash Network Console project, when cross-cutting concerns or broader refactoring issues are identified during PR review, the preferred approach is to create a separate GitHub issue to track the work rather than expanding the scope of the current PR. This maintains focus and allows for proper planning of architectural improvements.
apps/deploy-web/tests/seeders/user.ts (4)

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 creates an object under test and returns it

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

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

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 should accept a single parameter with inline type definition

apps/deploy-web/src/hooks/useUser.spec.tsx (9)

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

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.

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 creates an object under test and returns it

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

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

Learnt from: stalniy
PR: #1660
File: apps/deploy-web/src/components/alerts/DeploymentAlertsContainer/DeploymentAlertsContainer.spec.tsx:54-56
Timestamp: 2025-07-11T10:46:43.711Z
Learning: In apps/{deploy-web,provider-console}/**/*.spec.tsx files: Use getBy methods instead of queryBy methods when testing element presence with toBeInTheDocument() because getBy throws an error and shows DOM state when element is not found, providing better debugging information than queryBy which returns null.

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 should accept a single parameter with inline type definition

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

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 specify return type of setup function

⏰ 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 (3)
apps/deploy-web/src/hooks/useUser.spec.tsx (2)

55-70: LGTM - Well-structured test cases.

The test cases appropriately cover both scenarios for the useIsRegisteredUser hook - when userId is present and when it's falsy. The test logic and assertions are correct.


22-32: Fix incorrect mock implementation.

The mock calls using mock<typeof moduleType>() don't actually mock the modules. This syntax creates mock objects but doesn't replace the actual module imports.

You need to properly mock the hooks. Consider using jest.doMock() or restructure the mocking approach:

-    mock<typeof useCustomUserModule.useCustomUser>(() => ({
-      user: customUser || buildUser(),
-      isLoading: false,
-      error: undefined,
-      checkSession: mock()
-    }));
-
-    mock<typeof useStoredAnonymousUserModule.useStoredAnonymousUser>(() => ({
-      user: anonymousUser || buildAnonymousUser(),
-      isLoading: false
-    }));
+    jest.doMock("@src/hooks/useCustomUser", () => ({
+      useCustomUser: jest.fn(() => ({
+        user: customUser || buildUser(),
+        isLoading: false,
+        error: undefined,
+        checkSession: jest.fn()
+      }))
+    }));
+
+    jest.doMock("@src/hooks/useStoredAnonymousUser", () => ({
+      useStoredAnonymousUser: jest.fn(() => ({
+        user: anonymousUser || buildAnonymousUser(),
+        isLoading: false
+      }))
+    }));
⛔ Skipped due to learnings
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.
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
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
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 creates an object under test and returns it
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
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 specify return type of `setup` function
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 should accept a single parameter with inline type definition
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
apps/deploy-web/tests/seeders/user.ts (1)

7-40: Excellent seeder implementation.

The factory functions are well-structured with:

  • Proper TypeScript typing with partial overrides support
  • Consistent use of faker for realistic test data generation
  • Good separation between registered and anonymous user data
  • Clean, reusable design that will serve the testing needs well

Comment on lines +21 to +23
planCode: "COMMUNITY",
plan: plans.find(plan => plan.code === "COMMUNITY"),
...overrides
Copy link
Contributor

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Handle potential undefined plan resolution.

The plans.find() call could return undefined if no plan with code "COMMUNITY" exists, which might not match the expected type for CustomUserProfile.plan.

Consider adding a fallback or assertion to ensure the plan is found:

-    planCode: "COMMUNITY",
-    plan: plans.find(plan => plan.code === "COMMUNITY"),
+    planCode: "COMMUNITY",
+    plan: plans.find(plan => plan.code === "COMMUNITY") || plans[0],

Or use a more explicit approach:

-    planCode: "COMMUNITY",
-    plan: plans.find(plan => plan.code === "COMMUNITY"),
+    planCode: "COMMUNITY",
+    plan: (() => {
+      const plan = plans.find(p => p.code === "COMMUNITY");
+      if (!plan) throw new Error("COMMUNITY plan not found in test setup");
+      return plan;
+    })(),
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
planCode: "COMMUNITY",
plan: plans.find(plan => plan.code === "COMMUNITY"),
...overrides
planCode: "COMMUNITY",
plan: plans.find(plan => plan.code === "COMMUNITY") || plans[0],
...overrides
Suggested change
planCode: "COMMUNITY",
plan: plans.find(plan => plan.code === "COMMUNITY"),
...overrides
planCode: "COMMUNITY",
plan: (() => {
const plan = plans.find(p => p.code === "COMMUNITY");
if (!plan) throw new Error("COMMUNITY plan not found in test setup");
return plan;
})(),
...overrides
🤖 Prompt for AI Agents
In apps/deploy-web/tests/seeders/user.ts around lines 21 to 23, the plans.find
call may return undefined if no plan with code "COMMUNITY" exists, which can
cause type errors or runtime issues. To fix this, add a fallback value or an
assertion to ensure the plan variable is never undefined before assigning it to
the plan property. For example, throw an error if the plan is not found or
provide a default plan object to guarantee the plan property is always valid.

Copy link
Contributor Author

@domhhv domhhv left a comment

Choose a reason for hiding this comment

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

Sure, added the tests

@domhhv domhhv requested a review from ygrishajev July 30, 2025 20:59
@baktun14 baktun14 merged commit a397e64 into akash-network:main Jul 30, 2025
62 checks passed
stalniy pushed a commit that referenced this pull request Nov 20, 2025
* feat(billing): add composable guard for usage page

* refactor: move custom hooks

* test: cover useIsRegisteredUser hook

* feat: guard billing route
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.

3 participants

Comments