Skip to content

Fix/quotas 404 bootstrap#99

Merged
ginccc merged 3 commits into
mainfrom
fix/quotas-404-bootstrap
Jun 22, 2026
Merged

Fix/quotas 404 bootstrap#99
ginccc merged 3 commits into
mainfrom
fix/quotas-404-bootstrap

Conversation

@ginccc

@ginccc ginccc commented Jun 22, 2026

Copy link
Copy Markdown
Member

This pull request significantly improves the test coverage and robustness of the quotas feature, and enhances the user experience for handling tenant quotas. The main changes include comprehensive tests for quotas hooks and page, improved API error handling with sensible fallbacks, and UI improvements for quota configuration and enforcement state.

The most important changes are:

Testing Improvements:

  • Added a full test suite for all quota-related hooks in src/hooks/__tests__/use-quotas.test.tsx, covering normal fetches, error handling, and 404 fallback logic.
  • Greatly expanded the quotas page tests in src/pages/__tests__/quotas.test.tsx, including rendering, field values, user interactions (form changes, toggling, saving, reset usage), and error states. [1] [2] [3] [4] [5] [6]

API Robustness:

  • Updated src/lib/api/quotas.ts to return default quota values or zeroed usage when the backend returns 404 (no record), preventing UI crashes and allowing the UI to render with sensible defaults. [1] [2] [3]
  • Added helper functions defaultQuota and emptyUsage for these fallback values.

UI/UX Improvements:

  • Added a prominent enforcement disabled banner to the quotas page when quotas are not enabled, improving clarity for users.
  • Improved loading state by introducing a skeleton loader and enhanced form dirty state indicator for better feedback. [1] [2]

Minor Enhancements:

  • Added new icons to the quotas page for better visual cues.

These changes make the quotas feature more reliable, user-friendly, and maintainable.

Summary by CodeRabbit

  • New Features
    • Added a two-column loading skeleton for quota retrieval.
    • Shows an amber “Enforcement is off” banner when quotas are disabled.
    • Updated quota inputs with dedicated icons and dimmed visuals when disabled.
  • Bug Fixes
    • Improved quota and usage handling for API 404s by returning sensible default values (e.g., “disabled/unlimited” quota and zeroed usage) instead of failing.
    • Prevents the Quotas page from disappearing on non-404 server errors.
  • Tests
    • Expanded React Query hook and Quotas page tests, including update/reset flows and 404/500 scenarios.

@coderabbitai

coderabbitai Bot commented Jun 22, 2026

Copy link
Copy Markdown

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: e95c5059-3fdb-4387-be7e-0b1509b7be7d

📥 Commits

Reviewing files that changed from the base of the PR and between 510ff42 and 51dac29.

📒 Files selected for processing (4)
  • src/hooks/__tests__/use-quotas.test.tsx
  • src/lib/api/quotas.ts
  • src/pages/__tests__/quotas.test.tsx
  • src/pages/quotas.tsx
💤 Files with no reviewable changes (4)
  • src/lib/api/quotas.ts
  • src/pages/tests/quotas.test.tsx
  • src/pages/quotas.tsx
  • src/hooks/tests/use-quotas.test.tsx

📝 Walkthrough

Walkthrough

Adds defaultQuota and emptyUsage fallback constructors to src/lib/api/quotas.ts, making getQuota and getUsage return local defaults on 404 instead of throwing. The Quotas page gains a LoadingSkeleton, a conditional enforcement-off banner, and an updated QuotaField with icon/dimmed props. Both hook-level and page-level test suites are substantially expanded with MSW per-test handlers and comprehensive assertions.

Changes

Quotas 404 Fallback, UI, and Tests

Layer / File(s) Summary
API 404 fallback helpers and error handling
src/lib/api/quotas.ts
Adds isApiError import, exports defaultQuota and emptyUsage fallback constructors that synthesize default/zeroed quota and usage records, and wraps getQuota/getUsage in try/catch blocks that return those fallbacks on 404 instead of rethrowing. updateQuota and resetUsage remain direct API passthroughs.
QuotasPage UI: LoadingSkeleton, enforcement banner, QuotaField
src/pages/quotas.tsx
Expands lucide-react icon imports, replaces the old loading state with a new LoadingSkeleton two-column skeleton, adds a conditional amber enforcement-off banner when form.enabled is false, adds data-testid to the dirty indicator, and refactors QuotaField to accept icon and dimmed props for visual dimming when enforcement is disabled.
Hook-level tests
src/hooks/__tests__/use-quotas.test.tsx
New Vitest suite with QueryClientProvider wrapper and MSW per-test handlers covering useQuotas, useQuota, useQuotaUsage, useUpdateQuota, and useResetUsage with success cases, idle behavior when tenantId is empty, 404 fallback behavior asserting default/zeroed values, non-404 error propagation, and mutation success assertions including returned fields.
QuotasPage integration tests
src/pages/__tests__/quotas.test.tsx
Reorganizes and expands tests to cover rendering header/description/save button, loading skeleton display, field population from server data, usage tenant ID display, interaction tests for dirty state/enforcement toggle/save flow/reset-usage, 404 fallback display for both quota and usage endpoints, enforcement banner visibility in disabled and enabled states, and non-404 server error resilience.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Poem

🐇 Hoppin' through quotas, no crash on 404,
A skeleton loading while data's in store.
The banner glows amber when limits are off,
Each field gets an icon — the bunny won't scoff.
Tests mock the backend from every which way,
This warren of quotas is tidier today! ✨

🚥 Pre-merge checks | ✅ 3 | ❌ 2

❌ Failed checks (1 warning, 1 inconclusive)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 77.78% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
Title check ❓ Inconclusive The title 'Fix/quotas 404 bootstrap' is vague and does not clearly communicate the main changes; '404 bootstrap' is cryptic terminology that doesn't convey what actually happens when a 404 occurs or why this matters. Use a clearer title like 'Handle 404 gracefully in quotas with default fallback values' or 'Add quota 404 fallback handling and improve test coverage' to better reflect the actual changes.
✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix/quotas-404-bootstrap

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

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

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Pull request overview

Improves the tenant quotas feature by making quota/usage fetching resilient to missing backend records (404), enhancing the quotas UI feedback (loading skeleton, enforcement-off banner, icons, dirty indicator), and substantially expanding unit test coverage for both hooks and the quotas page.

Changes:

  • Add 404 fallbacks in the quotas API layer to return sensible defaults instead of failing.
  • Update the quotas page UI with clearer states (loading skeleton, enforcement disabled banner, improved dirty indicator).
  • Add/expand Vitest + MSW test suites for quota hooks and the quotas page, covering interactions and error scenarios.

Reviewed changes

Copilot reviewed 4 out of 4 changed files in this pull request and generated 1 comment.

File Description
src/pages/quotas.tsx UI polish: loading skeleton, enforcement-off banner, icons, dirty indicator test id, and reorganized config/usage layout.
src/pages/tests/quotas.test.tsx Expanded page-level tests: loading, rendering, interactions (toggle/save/reset), 404 fallbacks, and server-error resilience.
src/lib/api/quotas.ts Add 404-specific handling to return defaultQuota / emptyUsage instead of throwing, enabling UI to render for “no record yet” tenants.
src/hooks/tests/use-quotas.test.tsx New hook test suite covering list/detail/usage queries, 404 fallbacks, and mutation hooks.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread src/hooks/__tests__/use-quotas.test.tsx Outdated

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 2

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
src/pages/__tests__/quotas.test.tsx (1)

12-28: 🛠️ Refactor suggestion | 🟠 Major | ⚡ Quick win

Use the renderPage(type) helper instead of a custom render function.

The coding guidelines require using a shared renderPage(type) helper with MemoryRouter, QueryClient, and ThemeProvider in unit tests. This ensures consistency across test files and reduces duplication.

As per coding guidelines: "**/*.test.{ts,tsx}: Use renderPage(type) helper with MemoryRouter, QueryClient, and ThemeProvider in unit tests"

♻️ Refactor to use the shared helper

Replace the renderQuotas() function with the project's renderPage helper. You may need to adjust the helper to accept custom QueryClient options for test-specific configuration like gcTime: 0.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/pages/__tests__/quotas.test.tsx` around lines 12 - 28, Replace the custom
renderQuotas() function with the shared renderPage(type) helper from the
project's test utilities. The renderPage helper should be called with the
appropriate page type for the QuotasPage component, which will handle the setup
of MemoryRouter, QueryClient, and ThemeProvider automatically. If the helper
does not support custom QueryClient options like gcTime: 0, extend it to accept
optional configuration parameters that can be merged with the default
QueryClient settings.

Source: Coding guidelines

🧹 Nitpick comments (1)
src/pages/__tests__/quotas.test.tsx (1)

215-216: 🧹 Nitpick | 🔵 Trivial | 💤 Low value

Consider adding a comment explaining the "count" guard.

The conditional check if (params.tenantId === "count") return; appears to prevent overriding a different endpoint, but the intent isn't immediately clear.

📝 Suggested clarification
 http.get("*/administration/quotas/:tenantId/usage", ({ params }) => {
+  // Skip override for the quotas count endpoint at /administration/quotas/count
   if (params.tenantId === "count") return;
   return HttpResponse.json({
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/pages/__tests__/quotas.test.tsx` around lines 215 - 216, The conditional
guard `if (params.tenantId === "count") return;` in the http.get handler for the
quotas endpoint lacks clarity on its purpose. Add a clarifying comment above
this guard condition that explains why the check for "count" is needed and what
endpoint it's protecting against. The comment should indicate that this guard
prevents the handler from overriding a different endpoint that uses "count" as
part of its path.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@src/hooks/__tests__/use-quotas.test.tsx`:
- Around line 19-31: The test file is using a custom createWrapper function
instead of the repository's shared test harness. Replace the createWrapper
function and its usage with the renderPage(type) helper, which already provides
all required providers including MemoryRouter, QueryClient, and ThemeProvider.
This ensures provider setup consistency across all unit tests and aligns with
the coding guidelines for test files matching the *.test.{ts,tsx} pattern.

In `@src/lib/api/quotas.ts`:
- Around line 44-45: The emptyUsage object is calling new Date().toISOString()
separately for both minuteWindowStart and dayStart fields, which creates two
different timestamps instead of one consistent value. Capture the result of new
Date().toISOString() into a single variable (e.g., currentTimestamp) before
defining the emptyUsage object, then use that variable for both the
minuteWindowStart and dayStart fields to ensure they have the same timestamp
value.

---

Outside diff comments:
In `@src/pages/__tests__/quotas.test.tsx`:
- Around line 12-28: Replace the custom renderQuotas() function with the shared
renderPage(type) helper from the project's test utilities. The renderPage helper
should be called with the appropriate page type for the QuotasPage component,
which will handle the setup of MemoryRouter, QueryClient, and ThemeProvider
automatically. If the helper does not support custom QueryClient options like
gcTime: 0, extend it to accept optional configuration parameters that can be
merged with the default QueryClient settings.

---

Nitpick comments:
In `@src/pages/__tests__/quotas.test.tsx`:
- Around line 215-216: The conditional guard `if (params.tenantId === "count")
return;` in the http.get handler for the quotas endpoint lacks clarity on its
purpose. Add a clarifying comment above this guard condition that explains why
the check for "count" is needed and what endpoint it's protecting against. The
comment should indicate that this guard prevents the handler from overriding a
different endpoint that uses "count" as part of its path.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 21153646-9bce-4dc0-b810-1c720ba250cf

📥 Commits

Reviewing files that changed from the base of the PR and between 7c63966 and 2f134cf.

📒 Files selected for processing (4)
  • src/hooks/__tests__/use-quotas.test.tsx
  • src/lib/api/quotas.ts
  • src/pages/__tests__/quotas.test.tsx
  • src/pages/quotas.tsx

Comment thread src/hooks/__tests__/use-quotas.test.tsx
Comment thread src/lib/api/quotas.ts Outdated
@ginccc ginccc force-pushed the fix/quotas-404-bootstrap branch from 510ff42 to 51dac29 Compare June 22, 2026 21:08
@ginccc ginccc merged commit 95891a5 into main Jun 22, 2026
4 checks passed
@ginccc ginccc deleted the fix/quotas-404-bootstrap branch June 22, 2026 21:32
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