Skip to content

test(request): use order-insensitive Set comparison for Allow header assertions#1380

Open
terminalchai wants to merge 6 commits into
h3js:mainfrom
terminalchai:fix/assert-method-allow-header
Open

test(request): use order-insensitive Set comparison for Allow header assertions#1380
terminalchai wants to merge 6 commits into
h3js:mainfrom
terminalchai:fix/assert-method-allow-header

Conversation

@terminalchai

@terminalchai terminalchai commented May 5, 2026

Copy link
Copy Markdown
Contributor

Problem

The Allow header assertions in test/utils.test.ts used strict string equality:

expect(res405.headers.get("Allow")).toBe("POST, HEAD");
expect(res405.headers.get("Allow")).toBe("GET, POST");

The HTTP spec (RFC 9110 §10.2.1) doesn't mandate any particular ordering for method tokens in the Allow header. Pinning the test to a specific order makes it brittle — if the internal method set iteration order ever changes, the tests fail even though the response is completely valid.

Fix

Convert both assertions to order-insensitive Set comparisons:

expect(new Set(res405.headers.get("Allow")?.split(/\s*,\s*/))).toEqual(
  new Set(["POST", "HEAD"]),
);

Same values, no ordering assumption.

Summary by CodeRabbit

  • New Features

    • The assertMethod function now includes an Allow response header in 405 error responses, listing the permitted HTTP methods in compliance with RFC 9110.
  • Documentation

    • Updated documentation to reflect the new Allow header behavior included in 405 error responses.
  • Tests

    • Expanded test coverage to validate the Allow header presence and contents for 405 error scenarios.

@terminalchai terminalchai requested a review from pi0 as a code owner May 5, 2026 20:04
@coderabbitai

coderabbitai Bot commented May 5, 2026

Copy link
Copy Markdown
📝 Walkthrough

Walkthrough

The assertMethod utility function now throws 405 HTTP errors with an Allow response header listing permitted methods (RFC 9110 compliant). Implementation, tests, and documentation are updated to support and verify this behavior.

Changes

HTTP 405 Allow Header

Layer / File(s) Summary
Core Implementation
src/utils/request.ts
assertMethod computes allowed methods (normalizing single expected method into array), appends HEAD if allowHead is enabled, and throws HTTPError with status 405 and Allow header listing permitted methods.
Tests
test/utils.test.ts
Expanded test suite to assert 405 responses include correct Allow header values; added test case for multiple allowed methods.
Documentation
docs/2.utils/1.request.md
Updated documentation to reflect that assertMethod now includes Allow header with permitted methods in 405 response per RFC 9110.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related PRs

  • h3js/h3#1314: Adds Allow header to assertMethod 405 responses with matching implementation and test coverage.

Suggested reviewers

  • pi0

Poem

🐇 A rabbit hops through status codes,
When method fails on loaded roads,
Now 405 says "Here's the way!"
With Allow headers on display,
RFC 9110 guides the play! 🐰✨

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately describes the main change: updating test assertions to use order-insensitive Set comparison for Allow header assertions, which is the primary focus of the test file modifications.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.
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 unit tests (beta)
  • Create PR with unit tests

Tip

💬 Introducing Slack Agent: The best way for teams to turn conversations into code.

Slack Agent is built on CodeRabbit's deep understanding of your code, so your team can collaborate across the entire SDLC without losing context.

  • Generate code and open pull requests
  • Plan features and break down work
  • Investigate incidents and troubleshoot customer tickets together
  • Automate recurring tasks and respond to alerts with triggers
  • Summarize progress and report instantly

Built for teams:

  • Shared memory across your entire org—no repeating context
  • Per-thread sandboxes to safely plan and execute work
  • Governance built-in—scoped access, auditability, and budget controls

One agent for your entire SDLC. Right inside Slack.

👉 Get started


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.

@pkg-pr-new

pkg-pr-new Bot commented May 5, 2026

Copy link
Copy Markdown

Open in StackBlitz

npm i https://pkg.pr.new/h3@1380

commit: 1c71697

@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: 1

🤖 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/utils/request.ts`:
- Around line 340-345: The Allow header construction can emit duplicate "HEAD"
entries when allowHead is true and expected already contains "HEAD"; modify the
code that builds the Allow header (around variables allowed, expected, allowHead
and the HTTPError construction) to deduplicate methods before joining—e.g.,
compute a set/unique array from [...allowed, allowHead ? "HEAD" : ...[]] and
then join that unique list into the Allow header string so duplicate tokens are
not emitted in the thrown HTTPError.
🪄 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: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 64d1ee0d-2dbe-4087-90ea-9376b8785080

📥 Commits

Reviewing files that changed from the base of the PR and between 84244b4 and 9711854.

📒 Files selected for processing (3)
  • docs/2.utils/1.request.md
  • src/utils/request.ts
  • test/utils.test.ts

Comment thread src/utils/request.ts
Comment on lines +340 to +345
const allowed = Array.isArray(expected) ? expected : [expected];
throw new HTTPError({
status: 405,
headers: {
Allow: allowHead ? [...allowed, "HEAD"].join(", ") : allowed.join(", "),
},

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Deduplicate Allow methods before joining.

At Line 344, allowHead can produce duplicate HEAD tokens when expected already contains "HEAD" (for example ["GET", "HEAD"] + allowHead=true).

Suggested patch
   if (!isMethod(event, expected, allowHead)) {
     const allowed = Array.isArray(expected) ? expected : [expected];
+    const allowSet = new Set(allowed);
+    if (allowHead) {
+      allowSet.add("HEAD");
+    }
     throw new HTTPError({
       status: 405,
       headers: {
-        Allow: allowHead ? [...allowed, "HEAD"].join(", ") : allowed.join(", "),
+        Allow: [...allowSet].join(", "),
       },
     });
   }
 }
📝 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
const allowed = Array.isArray(expected) ? expected : [expected];
throw new HTTPError({
status: 405,
headers: {
Allow: allowHead ? [...allowed, "HEAD"].join(", ") : allowed.join(", "),
},
const allowed = Array.isArray(expected) ? expected : [expected];
const allowSet = new Set(allowed);
if (allowHead) {
allowSet.add("HEAD");
}
throw new HTTPError({
status: 405,
headers: {
Allow: [...allowSet].join(", "),
},
🤖 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/utils/request.ts` around lines 340 - 345, The Allow header construction
can emit duplicate "HEAD" entries when allowHead is true and expected already
contains "HEAD"; modify the code that builds the Allow header (around variables
allowed, expected, allowHead and the HTTPError construction) to deduplicate
methods before joining—e.g., compute a set/unique array from [...allowed,
allowHead ? "HEAD" : ...[]] and then join that unique list into the Allow header
string so duplicate tokens are not emitted in the thrown HTTPError.

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