There currently is no test for the "Follow redirects" (FOLLOW_REDIRECTS) config.

Command icon Show commands

Start within a Git clone of the project using the version control instructions.

Or, if you do not have SSH keys set up on git.drupalcode.org:

Comments

loopduplicate created an issue. See original summary.

loopduplicate’s picture

Assigned: loopduplicate » Unassigned
Status: Active » Needs review
Issue tags: -Needs test

csakiistvan made their first commit to this issue’s fork.

csakiistvan’s picture

@loopduplicate the test needed a fix, and the now-red pipeline points at a real module bug rather than a test problem.

Environment

  • Drupal: 11.4.4
  • PHP: 8.5.5
  • Database: MariaDB 10.11.16
  • DDEV: v1.25.2
  • Easy Breadcrumb: 2.x (commit 5bfef4e)
  • Redirect: 8.x-1.13 and 1.x-dev (both checked)

1. The original test did not cover the config

As committed, the test created a redirect from test-page-2 to the requested page itself, so the test browser simply followed the 301 and the breadcrumb was built for the target page. It passed with the redirect-following branch in EasyBreadcrumbBuilder disabled and with FOLLOW_REDIRECTS set to FALSE — the assertion was vacuous. FOLLOW_REDIRECTS only matters when an intermediate path segment is a redirect source.

I pushed an updated version to the MR branch: a node aliased /test-page-1, a second node aliased /test-page-2/test-page-3, and a 301 from test-page-2 to the first node, plus a negative assertion for the disabled setting. Locally this passes on unmodified 2.x (1 test, 7 assertions) and fails with ElementHtmlException: The string "Test Page 1" was not found ... once the redirect-following branch is disabled, so it does cover the config. phpcs --standard=Drupal,DrupalPractice is clean.

2. The remaining CI failure is a module bug

The phpunit job fails at the positive assertion, while the same test passes locally against a root-level install (with both Redirect 8.x-1.13 and 1.x-dev). The difference is the base path: the GitLab templates run the site in a subdirectory (SIMPLETEST_BASE_URL: http://localhost/$_WEB_ROOT).

In EasyBreadcrumbBuilder::getRequestForPath() the redirect lookup path gets the base path prepended:

$base_path = $request->getBasePath();
if (!empty($base_path) && $base_path != '/') {
  if (strpos($redirect_path, $base_path) !== 0) {
    $redirect_path = rtrim($base_path, '/') . '/' . $redirect_path;
  }
}
...
$redirect = \Drupal::service('redirect.repository')
  ->findMatchingRedirect($redirect_path, [], $langcode);

The Redirect module stores sources without the base path (test-page-2), and $path here already comes from getPathInfo(), which excludes the base path. So on a subdirectory install the lookup is done for web/test-page-2, never matches, and Follow redirects silently does nothing.

Reproduced deterministically: forcing $base_path = '/web' on my local root-level install makes the test fail with exactly the CI error, and removing the forced value makes it pass again.

Since this MR is test-only, I would suggest opening a separate issue for the base-path handling in the redirect lookup, and marking this one as blocked by it.


Testing produced with the assistance of an LLM.

loopduplicate’s picture

Assigned: Unassigned » loopduplicate
Status: Needs review » Active

Thanks @csakiistvan. This one bugged me so bad yesterday. I was having trouble with the local passing and the remote failing too. I'm going to read over what you posted and think about it.

loopduplicate’s picture

@csakiistvan, do you know how I can reproduce this locally with ddev? I'm having a heck of a time. I just can't seem to get the test to fail locally by, as you wrote "forcing $base_path = '/web' on my local root-level install". I've tried a lot of things but it's been... probably a couple of hours now and I need to just ask for help or try again later. I use https://addons.ddev.com/addons/ddev/ddev-drupal-contrib .

loopduplicate’s picture

Assigned: loopduplicate » Unassigned
Status: Active » Needs work
csakiistvan’s picture

@loopduplicate here is how to reproduce the base-path problem behind the red pipeline.

Summary

Follow redirects only works when Drupal is installed at the web root. When the site runs in a subdirectory (https://example.com/drupal), EasyBreadcrumbBuilder looks the redirect up with the base path prepended, while the Redirect module stores its sources without it, so nothing matches and the feature silently does nothing. The GitLab CI job runs the site in a subdirectory (SIMPLETEST_BASE_URL: http://localhost/$_WEB_ROOT, i.e. http://localhost/web), which is why the new test fails there but passes locally on a root-level install.

The code

EasyBreadcrumbBuilder::getRequestForPath():

$base_path = $request->getBasePath();
if (!empty($base_path) && $base_path != '/') {
  if (strpos($redirect_path, $base_path) !== 0) {
    $redirect_path = rtrim($base_path, '/') . '/' . $redirect_path;
  }
}
...
$redirect = \Drupal::service('redirect.repository')
  ->findMatchingRedirect($redirect_path, [], $langcode);

$path here originates from $this->context->getPathInfo(), which already excludes the base path, and redirect sources are stored without it too (the Redirect module matches on $request->getPathInfo()). So on a subdirectory install the lookup runs for web/test-page-2 instead of test-page-2.

Reproduction A — deterministic, no subdirectory install needed

This is the quickest way to see the exact CI failure on a normal root-level install:

  1. Check out the MR branch 3615339-test-follow-redirects.
  2. In src/EasyBreadcrumbBuilder.php, right after $base_path = $request->getBasePath();, add a temporary line simulating a subdirectory install:
    $base_path = '/web';
  3. Run the test:
    ddev exec 'cd web/core && SIMPLETEST_BASE_URL=http://web SIMPLETEST_DB=mysql://db:db@db/db BROWSERTEST_OUTPUT_DIRECTORY=/tmp ../../vendor/bin/phpunit -c phpunit.xml.dist ../modules/contrib/easy_breadcrumb/tests/src/Functional/EasyBreadcrumbFollowRedirectsTest.php'
  4. Remove the temporary line and run the test again.

With the line in place the test fails with exactly the CI error — Behat\Mink\Exception\ElementHtmlException: The string "Test Page 1" was not found in the HTML of the element matching css "#block-breadcrumb li:nth-child(2)" — and without it the test passes. Nothing else differs between the two runs.

Reproduction B — real site in a subdirectory

On a Drupal site served from a subdirectory (e.g. https://example.com/drupal), with Easy Breadcrumb and Redirect enabled and Follow redirects checked:

  1. Create a node with the alias /eb-target, titled Redirect Target.
  2. Create a second node with the alias /eb-old/child, titled Child.
  3. Add a 301 redirect from eb-old to the first node.
  4. Visit https://example.com/drupal/eb-old/child.

Expected: Home / Redirect Target / Child — the intermediate segment is resolved through the redirect. Actual on a subdirectory install: the Redirect Target segment is missing, because the lookup is performed for drupal/eb-old. The very same content on a root-level install renders the expected breadcrumb; I verified that side with Easy Breadcrumb 2.x (commit 5bfef4e) and Redirect 1.x.

Reproduction C — CI

The MR pipeline itself is a reproduction: job 11392668 fails only on this test, at the positive assertion, while every other test in the suite passes. Local runs of the full suite (21 tests) are green.

Suggested direction

Since $path is already base-path free, the base-path block looks unnecessary for the redirect lookup — dropping it (or stripping the base path instead of adding it) should make the feature work in both setups. As this MR is test-only, I would open a separate issue for that change and mark this one as blocked by it.

loopduplicate’s picture

OK, finally, with your help, can reproduce locally. First, at src/EasyBreadcrumbBuilder.php:965, I added the override $base_path = '/web';

Then, I had to modify the command in the terminal so that it points to modules/custom instead of modules/contrib, as that's how https://addons.ddev.com/addons/ddev/ddev-drupal-contrib symlinks it. So my command is:

ddev exec 'cd web/core && SIMPLETEST_BASE_URL=http://web SIMPLETEST_DB=mysql://db:db@db/db BROWSERTEST_OUTPUT_DIRECTORY=/tmp ../../vendor/bin/phpunit -c phpunit.xml.dist ../modules/custom/easy_breadcrumb/tests/src/Functional/EasyBreadcrumbFollowRedirectsTest.php'

loopduplicate’s picture

Status: Needs work » Closed (outdated)

Now that this issue is closed, review the contribution record.

As a contributor, attribute any organization that helped you, or if you volunteered your own time.

Maintainers, credit people who helped resolve this issue.