Skip to content

fix(tests/redirection): check HTTPS redirects properly#495

Open
caugner wants to merge 7 commits intomainfrom
fix-https-redirects
Open

fix(tests/redirection): check HTTPS redirects properly#495
caugner wants to merge 7 commits intomainfrom
fix-https-redirects

Conversation

@caugner
Copy link
Copy Markdown
Contributor

@caugner caugner commented Apr 10, 2026

Description

Fixes an assignment in the retriever, where the redirects from the HTTP session were assigned to the HTTPS redirects.

Motivation

With both chains identical, the redirection test logic produced wrong results for any site where the HTTP and HTTPS redirect chains actually differ.

Additional details

Correcting httpsRedirects revealed three latent bugs in the redirection tests:

  1. Wrong chain for pass/fail when httpRedirects is empty — the httpRedirects OR httpsRedirects fallback was used for both display and all pass/fail checks. With an empty httpRedirects, the off-host and initial-redirection checks silently evaluated against an https: URL for route[0], always falling through to a pass.

  2. Vacuous truth in allRedirectsPreloaded[].every(...) returns true, so an empty httpRedirects could produce RedirectionAllRedirectsPreloaded when the HTTP server didn't redirect at all.

  3. HTTPS chain redirecting back to HTTP went undetected — the "not to HTTPS" check only inspected the end of the HTTP chain. If the independent HTTPS session redirected back to HTTP, it passed.

All three are fixed and covered by new tests.

Related issues and pull requests

caugner added 6 commits April 10, 2026 17:32
…oute

After the retriever fix, `httpRedirects` and `httpsRedirects`
can differ. Unify both fields under a single `redirects` variable
(HTTP preferred, HTTPS fallback) so destination and route always
describe the same chain.
Two cases were not covered:
- HTTPS chain redirecting back to HTTP while the HTTP chain looked fine
- Empty httpRedirects with a live HTTP response producing a spurious pass
  (vacuous truth on .every() + wrong chain used for pass/fail checks)
Previously `redirects` was computed as httpRedirects OR httpsRedirects
(fallback), and then used for both display and all pass/fail logic.
This caused three bugs:

- When httpRedirects was empty but an HTTP response existed, the
  OR-fallback ran httpsRedirects through checks designed for an HTTP
  chain (e.g. route[0].protocol === "http:" is always false for an
  https: URL), producing a spurious pass.

- allRedirectsPreloaded called .every() on an empty httpRedirects
  array, which vacuously returns true and gave RedirectionAllRedirectsPreloaded
  for sites with no HTTP redirects.

- The "not to HTTPS" check only inspected the end of the HTTP chain.
  If the independent HTTPS session redirected back to HTTP, it went
  undetected.

Fix: separate httpRoute (used for all pass/fail checks) from
displayRoute (httpRoute with httpsRoute fallback, used only for
output.destination and output.route). Guard allRedirectsPreloaded
with httpRoute.length > 1. Extend the "not to HTTPS" check to also
test httpsRoute.at(-1).
@caugner caugner changed the title fix(retriever): assign HTTPS redirects properly fix(retriever): test HTTPS redirects properly Apr 16, 2026
@caugner caugner changed the title fix(retriever): test HTTPS redirects properly fix(tests/redirection): check HTTPS redirects properly Apr 16, 2026
@caugner caugner marked this pull request as ready for review April 16, 2026 12:34
@caugner caugner requested a review from a team as a code owner April 16, 2026 12:34
@caugner caugner requested a review from LeoMcA April 16, 2026 12:34
// Check to see if every redirection was covered by the preload list.
// Guard httpRoute.length > 1 to avoid vacuous truth on an empty array.
const allRedirectsPreloaded =
httpRoute.length > 1 &&
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Could we add a test for the "route is 1" condition here?

Comment thread test/redirection.test.js
it("fails with redirection-missing when http redirects are empty but http response exists", function () {
// The OR fallback previously caused httpsRedirects to be used for pass/fail
// logic when httpRedirects is empty, which could produce a spurious pass.
reqs.responses.httpRedirects = [];
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Is this possible? Wouldn't a site returning a http response have at least one value in this array with a 200 status?

// use the http redirect chain
retrievals.responses.httpRedirects = httpSession.redirectHistory;
retrievals.responses.httpsRedirects = httpSession.redirectHistory;
retrievals.responses.httpsRedirects = httpsSession.redirectHistory;
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Can we add a test for this change specifically?

Comment thread test/redirection.test.js
assert.isFalse(res.pass);
});

it("uses https redirects as fallback for destination and route when http redirects are empty", function () {
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

I don't think this is possible in practice, if httpRedirects is empty, then responses.http should be undefined, and that's already covered by the first test in the file.

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