Skip to content

Issue/190 rate limit config and feature tests#191

Merged
armanist merged 4 commits into
softberg:masterfrom
armanist:issue/190-rate-limit-config-and-feature-tests
May 13, 2026
Merged

Issue/190 rate limit config and feature tests#191
armanist merged 4 commits into
softberg:masterfrom
armanist:issue/190-rate-limit-config-and-feature-tests

Conversation

@armanist
Copy link
Copy Markdown
Member

@armanist armanist commented May 13, 2026

Closes #190

Summary by CodeRabbit

New Features

  • API endpoints now support rate limiting with configurable storage options (file-based or Redis).
  • Rate limits are applied per route to independently throttle different endpoints.

Tests

  • Added comprehensive test coverage for rate-limit functionality, including HTTP 429 response validation and route-specific limiting behavior.

Review Change Stack

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented May 13, 2026

Warning

Rate limit exceeded

@armanist has exceeded the limit for the number of commits that can be reviewed per hour. Please wait 16 minutes and 32 seconds before requesting another review.

You’ve run out of usage credits. Purchase more in the billing tab.

⌛ How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

Please see our FAQ for further information.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 0b82e8a7-aed6-47dc-beb7-024fa9699980

📥 Commits

Reviewing files that changed from the base of the PR and between 6f393ef and b5f8ae6.

📒 Files selected for processing (3)
  • tests/Feature/AppTestCase.php
  • tests/Feature/modules/Api/RateLimitTest.php
  • tests/_root/shared/config/rate_limit.php
📝 Walkthrough

Walkthrough

The PR introduces rate-limit configuration and feature tests for the API. A new shared/config/rate_limit.php defines adapter settings, the test base class gains cleanup methods to isolate rate-limit state between tests, and a comprehensive test suite validates HTTP 429 blocking, response headers, and route-specific rate-limit isolation.

Changes

Rate-limit configuration and feature tests

Layer / File(s) Summary
Rate-limit configuration
shared/config/rate_limit.php
Defines default adapter selection via RATE_LIMIT_ADAPTER environment variable (defaulting to file), plus file and redis adapter configurations with shared prefix (from APP_NAME), ttl (60 seconds), and adapter-specific connection settings.
Test base infrastructure for rate-limit cleanup
tests/Feature/AppTestCase.php
setUp() and tearDown() now call clearRateLimitStorage() to remove *.rate and *.lock cache files before and after each test, ensuring rate-limit state isolation.
Rate-limit feature tests
tests/Feature/modules/Api/RateLimitTest.php
Feature tests validate that repeated failed sign-in requests return HTTP 429 with X-RateLimit-Limit, X-RateLimit-Remaining, and Retry-After headers, and confirm that rate-limit buckets are route-specific (sign-in blocking does not affect other endpoints like posts).

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~12 minutes

Poem

🐰 A config blooms, rate limits take form,
Tests spring to life, validating the norm,
Four hundred and twenty-nine stands tall,
Protecting each route—no leaks at all! 🛡️

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ 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%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly and specifically summarizes the main changes: adding rate-limit configuration and feature tests as referenced in the linked issue.
Linked Issues check ✅ Passed The PR fulfills all coding requirements: shared rate_limit.php config added [#190], API feature tests validate HTTP 429 responses and route-specific buckets [#190], storage cleanup implemented for deterministic tests [#190].
Out of Scope Changes check ✅ Passed All changes directly align with issue #190 objectives: rate-limit configuration, feature tests, and test cleanup infrastructure are all in scope.

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

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

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 and usage tips.

Copy link
Copy Markdown

@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

🧹 Nitpick comments (1)
tests/Feature/modules/Api/RateLimitTest.php (1)

64-75: ⚡ Quick win

Remove duplicated rate-limit cleanup logic from this test class.

This re-implements cleanup already handled in AppTestCase, and the two versions can drift. Promote the base helper to protected and reuse it here to keep isolation behavior centralized.

Refactor direction
-    private function clearRateLimitStorage(): void
-    {
-        $rateLimitDir = PROJECT_ROOT . DS . 'cache' . DS . 'data';
-
-        foreach (glob($rateLimitDir . DS . '*.rate') ?: [] as $file) {
-            `@unlink`($file);
-        }
-
-        foreach (glob($rateLimitDir . DS . '*.lock') ?: [] as $file) {
-            `@unlink`($file);
-        }
-    }
+    // Use inherited AppTestCase::clearRateLimitStorage()
-    private function clearRateLimitStorage(): void
+    protected function clearRateLimitStorage(): void
🤖 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 `@tests/Feature/modules/Api/RateLimitTest.php` around lines 64 - 75, The
private clearRateLimitStorage() in RateLimitTest duplicates cleanup logic
already in AppTestCase; remove this method from
tests/Feature/modules/Api/RateLimitTest.php and instead call the base helper.
Make the base helper in AppTestCase protected (rename/ensure method name
clearRateLimitStorage exists there) so subclasses can reuse it, and update
RateLimitTest to rely on parent::clearRateLimitStorage() or simply omit the
duplicate implementation so the centralized cleanup is used.
🤖 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 `@tests/Feature/AppTestCase.php`:
- Around line 68-74: The cleanup loops that remove limiter files currently use
error suppression (`@unlink`) on $file which can hide failures; update the two
loops that iterate glob($rateLimitDir . DS . '*.rate') and glob($rateLimitDir .
DS . '*.lock') to remove the "@" and explicitly check unlink($file) return
value, and if unlink returns false throw an exception (e.g., RuntimeException)
or call the test failure helper (e.g., $this->fail) with a message including
$file so the test fails fast when a file cannot be removed.

In `@tests/Feature/modules/Api/RateLimitTest.php`:
- Around line 81-83: The setup currently calls mkdir($rateLimitDir, 0777, true)
without verifying success; update RateLimitTest to assert the directory was
created by checking the mkdir return (or is_dir afterwards) and fail the test if
creation failed. Specifically, after the existing is_dir check and mkdir call
for $rateLimitDir, add an assertion (e.g., using $this->assertTrue or
$this->assertDirectoryExists) that the directory exists or that mkdir returned
true, and include a clear message so the test stops immediately on creation
failure.

---

Nitpick comments:
In `@tests/Feature/modules/Api/RateLimitTest.php`:
- Around line 64-75: The private clearRateLimitStorage() in RateLimitTest
duplicates cleanup logic already in AppTestCase; remove this method from
tests/Feature/modules/Api/RateLimitTest.php and instead call the base helper.
Make the base helper in AppTestCase protected (rename/ensure method name
clearRateLimitStorage exists there) so subclasses can reuse it, and update
RateLimitTest to rely on parent::clearRateLimitStorage() or simply omit the
duplicate implementation so the centralized cleanup is used.
🪄 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: 68b55c37-11aa-4674-a14b-21227977b280

📥 Commits

Reviewing files that changed from the base of the PR and between ce4e908 and 6f393ef.

📒 Files selected for processing (3)
  • shared/config/rate_limit.php
  • tests/Feature/AppTestCase.php
  • tests/Feature/modules/Api/RateLimitTest.php

Comment thread tests/Feature/AppTestCase.php
Comment thread tests/Feature/modules/Api/RateLimitTest.php Outdated
Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 6f393ef6df

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread tests/Feature/modules/Api/RateLimitTest.php
@armanist armanist added this to the 3.0.0 milestone May 13, 2026
@armanist armanist merged commit a3c1182 into softberg:master May 13, 2026
4 of 5 checks passed
@armanist armanist deleted the issue/190-rate-limit-config-and-feature-tests branch May 13, 2026 16:11
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Add shared rate_limit config and feature tests for API rate limiting

1 participant