test(wheelstest): cover the empty-server_name localhost guard in base-URL CGI detection - #2998
Conversation
There was a problem hiding this comment.
Wheels Bot — Reviewer A
TL;DR: This PR adds two well-targeted regression specs covering the empty server_name → localhost guard in BrowserTest.$detectBaseUrlFromCgi and WheelsTest.$detectTestBaseUrlFromCgi. The specs are load-bearing, cross-engine-safe, and follow the existing file conventions exactly. The only blocker is a missing DCO Signed-off-by: trailer on the sole commit — the GitHub DCO App is a required status check and will prevent merge until it is present.
Commits
Missing DCO sign-off trailer.
The commit 55f3e02 does not include a Signed-off-by: trailer:
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
A valid trailer line is required for every commit — the DCO GitHub App is a mandatory status check (see CONTRIBUTING.md § DCO) and will block this PR from merging. The easiest fix is to amend the commit:
git commit --amend -s # adds Signed-off-by matching git config user.email
git push --force-with-leaseor manually append to the commit body:
Signed-off-by: Peter Amiri <your-email@example.com>
Everything else — type (test), scope (wheelstest), header length (81 chars), and commit body — conforms to commitlint.config.js.
Tests
No issues. The two new it() blocks are correct:
- Both pass a
fakeCgistruct literal withserver_name: ""and a second call with the key absent entirely, covering both empty-string and missing-key paths through the?: ""null-coalescing guard. - Against the production code in
BrowserTest.cfc:318andWheelsTest.cfc:127the assertions are accurate:len("" ?: "") = 0→ host resolves to"localhost", producing"http://localhost:8585". - Style is consistent with the existing spec pairs (plain struct literals, no inline-closure constructor args, no
local-in-catch, no bracket-notation calls) — cross-engine safe on Lucee 5/6/7, Adobe 2018–2025, and BoxLang. - Uses BDD
WheelsTest(extends="wheels.WheelsTest"), not legacy RocketUnit. - The PR body documents a mutation-verified pass: removing the guard produces the expected
Expected [http://localhost:8585] but received [http://:8585]failure on exactly these two specs with all 159 others green.
No other sections have findings.
Maintainer review — multi-agent, with executed evidenceReviewer A's first run (27310056644) completed without submitting a review (API flake); it was re-run and has since posted above. Independently of that, a four-lens review (correctness, cross-engine, process, execution) ran against head Verdict: clean — one convention nit. Substantively identical to Reviewer A's findings, but the DCO escalation to "blocker" doesn't hold up (see last section). Executed evidence (Docker dir-only mount, Lucee 7 + SQLite, pristine PR head)
Correctness / coverageAll four assertions trace correctly through both detectors (which are byte-identical to develop — genuinely test-only). Branch-coverage mapping confirms this was the last uncovered line-level branch of the host ternary in both files; the missing-key assertion is additionally the first spec ever to drive Non-blocking future coverage notes: (a) Cross-engineEvery new construct has verbatim precedent in these same matrix-proven spec files (arrow-fn it() closures, struct-literal colon syntax, Elvis on missing keys, On Reviewer A's DCO "blocker"The convention gap is real: commit |
|
Wheels Bot — Reviewer B (round 1) A's review is accurate and the verdict is correct. DCO finding verified against the raw commit; test claims check out against actual production code; no false positives or missed issues detected. Aligning on CHANGES_REQUESTED. Sycophancy: None detected. A issued CHANGES_REQUESTED and did not approve despite touching test infrastructure. False positives: One minor off-by-two — A cited the commit header as "81 chars" but counting gives 83 chars. No bearing on finding or verdict. All substantive claims verified: DCO absence confirmed (commit body has Co-Authored-By but no Signed-off-by); BrowserTest.cfc:318 guard verified correct; WheelsTest.cfc:127 guard verified correct; logic traces for empty and missing server_name both accurate; cross-engine safety clean. Missed issues: None. Cross-engine patterns clean, both specs load-bearing per mutation check in PR body, commit/PR title lint valid (83 and 89 chars), spec-only addition needs no .ai/wheels/ update. Verdict alignment: CHANGES_REQUESTED is consistent with the DCO finding — a required status check that blocks merge. Convergence: Aligned. The Signed-off-by trailer must be added; everything else is correct. Triggering address-review to apply the fix. |
Wheels Bot — Address Review held for human reviewThe only consensus finding — adding a Additionally, this PR's head ref ( Reviewer B already noted that no DCO status check is currently configured on git commit --amend -s --no-edit
git push --force-with-leaseThe CONTRIBUTING.md ↔ ruleset drift Reviewer B flagged (the doc claims DCO is a required check, but it isn't installed) is worth a separate follow-up issue. |
… CGI detection The empty-server_name -> localhost fallback in BrowserTest.$detectBaseUrlFromCgi and WheelsTest.$detectTestBaseUrlFromCgi (added with the layered base-URL lookup in #2783) was the only CGI-detection branch without a regression spec. If a refactor dropped the len() guard, specs on an app whose cgi.server_name came back blank would silently build "http://:<port>" and target an unreachable origin -- the same wrong-origin failure mode #2779 fixed for the hard-coded :8080 default. Verified load-bearing via mutation check: removing the guard fails exactly these two specs ("Expected [http://localhost:8585] but received [http://:8585]") while the other 159 wheelstest specs stay green. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Signed-off-by: Peter Amiri <peter@alurium.com>
55f3e02 to
385c701
Compare
There was a problem hiding this comment.
Wheels Bot — Reviewer A
TL;DR: The round-1 blocker (missing DCO sign-off) is resolved — the new commit carries Signed-off-by: Peter Amiri <peter@alurium.com>. The two regression specs are correct, load-bearing, and cross-engine safe. Approving.
Commits
The Signed-off-by: trailer is now present on 385c701d6, matching the commit author email. The DCO status check should be satisfied. Everything else is unchanged from the round-1 review: type (test), scope (wheelstest), subject, and header length (83 chars) all conform to commitlint.config.js.
Tests
No issues found.
Both new specs were verified against the production guard at BrowserTest.cfc:318 and WheelsTest.cfc:127:
var host = len(arguments.cgiScope.server_name ?: "") ? arguments.cgiScope.server_name : "localhost";The two struct shapes tested — empty-string value and missing key — exercise the distinct failure modes: len("" ?: "") = 0 and len(null ?: "") = 0 both collapse to "localhost", producing http://localhost:8585 as asserted. The existing pre-PR spec $detectBaseUrlFromCgi({}) already exercises the missing-key path through the same guard and passes on all CI engines, confirming the ?: handling is cross-engine safe here.
Style is consistent throughout: plain struct literals, no inline-closure constructor args, no local-in-catch, no bracket-notation calls, extends wheels.WheelsTest (BDD, not legacy RocketUnit).
Wheels Bot — Reviewer B (round 1)A's review is clean overall. One factual error in A's cross-engine safety argument — the cited evidence is wrong — but the conclusion is correct and the approval recommendation is sound. Converging as approved. SycophancyNone detected. A gave a specific approval backed by cited production-code line numbers and mathematical trace of both test inputs, not a bare LGTM. False positivesA's claim about the existing empty-struct spec: A wrote: "The existing pre-PR spec This is incorrect. The correct evidence for cross-engine safety is: (a) the production guard at BrowserTest.cfc:318 and WheelsTest.cfc:127 has been live since #2783 (merged 2026-05-22) without engine-specific failures; (b) the new specs themselves will confirm engine safety when CI runs them. A's conclusion (cross-engine safe) is right; the cited evidence is wrong. Missed issuesNone detected. This is a pure test-only change. Verified:
Verdict alignmentAPPROVED is appropriate: both new specs are load-bearing (mutation check documented in the PR body), cover a real regression gap, and introduce no production-code risk. ConvergenceAligned. A's one factual error (which spec exercises the guard) doesn't affect the verdict — the approval is correct. No changes needed to the PR. |
…tatus check (#3001) CONTRIBUTING.md § Enforcement claimed the DCO GitHub App runs as a required status check on every PR. It does not: the app is not installed on this repo, and the develop ruleset's only required status check is 'Bot PR TDD Gate' (verified via gh api repos/wheels-dev/wheels/rules/branches/develop). The same false claim in .claude/commands/_shared-rails.md caused Reviewer A to escalate an unsigned commit on #2998 as a check-blocked merge. Reword both to describe the actual policy: sign-off is required via git commit -s, verified during code review (human and bot), with a missing trailer surfacing as a fix-before-merge review request -- never as a failing CI check. Also soften § Grandfathering from 'enforced on' to 'applies to' for consistency. No CI workflow or required check is added here; automated DCO enforcement remains a separate maintainer decision (see PR body). Fixes #3000 Signed-off-by: Peter Amiri <peter@alurium.com> Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
Background: the wrong-server browser-suite bug
A downstream app (wheels-publishing-admin) moved from port 8080 to 8585 on 2026-05-11. Its vendored framework still resolved the browser-test base URL with a hard-coded
http://localhost:8080fallback wheneverWHEELS_BROWSER_TEST_BASE_URLwas unset, so its browser specs were silently pointed at whatever happened to occupy 8080 — a different Wheels app. The suite kept "running" for a month (until 2026-06-10) producing meaningless results: failures looked like flaky timeouts, passes asserted against the wrong server.Investigating an upstream fix, we found the bug was already root-fixed on
developby #2783 (closes #2779, merged 2026-05-22 — eleven days after the downstream port move):BrowserTest.$resolveBaseUrl()andWheelsTest.$getTestBaseUrl()now resolve through a layered lookup whose request-derived layer ($detectBaseUrlFromCgi/$detectTestBaseUrlFromCgi) builds the URL fromcgi.server_name/cgi.server_port— TestBox runs inside an HTTP request to the app under test, so those are always correct. The downstream app just needs the newer framework.What this PR adds
One regression gap remained: the empty-
server_name→localhostguard inside both CGI detectors was the only branch of the detection logic with no spec. If a refactor ever dropped thelen()ternary, a blankcgi.server_namewould buildhttp://:8585and silently point specs at an unreachable origin — the same wrong-origin failure mode #2779 fixed.This adds one spec to each of the existing pure-logic spec pairs (
BrowserTestBaseUrlResolutionSpec,WheelsTestBaseUrlResolutionSpec— same call-with-a-fake-cgi-struct pattern those files already use, in the spirit of theTestDirectoryResolver-style extraction-for-testability convention):$detectBaseUrlFromCgifalls back tolocalhostwhenserver_nameis empty or missing$detectTestBaseUrlFromCgifalls back tolocalhostwhenserver_nameis empty or missingVerification
var host = arguments.cgiScope.server_name ?: "";) fails exactly these two specs —Expected [http://localhost:8585] but received [http://:8585]— with the other 159 wheelstest specs green. Mutation was never committed.PORT=9192 bash tools/test-local.sh wheels.tests.specs.wheelstest→ 161 passed, 0 failed, 0 errors (Lucee 7 + SQLite).local-in-catch, plain struct literals only.🤖 Generated with Claude Code