Problem/Motivation

I tried looking for an existing issue but couldn't quite locate one. I recently ran into an issue when testing custom code around cookies and logging in/out with functional tests, outlined here:

https://drupal.stackexchange.com/questions/317324/drupal-unable-to-login...

It came down to the Mink driver not properly clearing cookies / session related data when logging out a user until I used $this->getSession()->reset();

drupalLogout does not seem to account for this:

  protected function drupalLogout() {
    // Make a request to the logout page, and redirect to the user page, the
    // idea being if you were properly logged out you should be seeing a login
    // screen.
    $assert_session = $this->assertSession();
    $destination = Url::fromRoute('user.page')->toString();
    $this->drupalGet(Url::fromRoute('user.logout', [], ['query' => ['destination' => $destination]]));
    $assert_session->fieldExists('name');
    $assert_session->fieldExists('pass');

    // @see BrowserTestBase::drupalUserIsLoggedIn()
    unset($this->loggedInUser->sessionId);
    $this->loggedInUser = FALSE;
    \Drupal::currentUser()->setAccount(new AnonymousUserSession());
  }

Steps to reproduce

With code that sets cookies, trying to log in a user that gets those cookies, logging them out and then using drupalLogin will produce the following error:

User <em class="placeholder">NAME</em> successfully logged in.
Failed asserting that false is true.

In my case I am doing a redirect because of the logic required and so the assert in drupalLogin fails, whereas the drupalGet/submitForm method works. This should work either way, as the code (in this example) does work in a real browser / real human testing it.

Proposed resolution

Ensure the session is reset/cleared cleanly when using drupalLogout for functional tests or provide a note in the docs on this behavior to know to call $this->getSession()->reset() in certain scenarios.

Comments

kevinquillen created an issue. See original summary.

kevinquillen’s picture

Issue summary: View changes
pbonnefoi’s picture

I have a similar problem trying to fix a unit test on a contrib module, but adding $this->getSession()->reset(); did not work. Do you add it right after drupalLogout() ?

An improvement on the error message would be very nice as well because it does not make much sense.

The unit test causing problem is from the redirect_after_login contrib module.

kevinquillen’s picture

Calling drupalLogout() in this scenario is the problem because assert() fails (its in one of the test traits) - it thinks the session is still authenticated. This does not happen outside of a test.

I believe if the test method was updated to this, it would resolve the issue:

  protected function drupalLogout() {
    // Make a request to the logout page, and redirect to the user page, the
    // idea being if you were properly logged out you should be seeing a login
    // screen.
    $assert_session = $this->assertSession();
    $destination = Url::fromRoute('user.page')->toString();
    $this->drupalGet(Url::fromRoute('user.logout', [], ['query' => ['destination' => $destination]]));
    $assert_session->fieldExists('name');
    $assert_session->fieldExists('pass');

    // @see BrowserTestBase::drupalUserIsLoggedIn()
    unset($this->loggedInUser->sessionId);
    $this->loggedInUser = FALSE;
    $this->getSession()->reset();
    \Drupal::currentUser()->setAccount(new AnonymousUserSession());
  }

Multiple login/logouts in a single test method that alters or adds to user session data or cookie data is otherwise problematic to test.

pbonnefoi’s picture

Ok good to know, thank you very much for the insights !

Version: 10.1.x-dev » 11.x-dev

Drupal core is moving towards using a “main” branch. As an interim step, a new 11.x branch has been opened, as Drupal.org infrastructure cannot currently fully support a branch named main. New developments and disruptive changes should now be targeted for the 11.x branch. For more information, see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.

fenstrat’s picture

Just noting here that I saw these same odd failures, especially when running multiple drupalLogin() calls:

User <em class="placeholder">NAME</em> successfully logged in.
Failed asserting that false is true.

And that calling $this->getSession()->reset() didn't solve it.

Instead it was related to dumping the container, and the container differing while under test. In my case this was using Drupal Test Traits, see
#3436284: DTT can use different cached container than running site causing issues with testing.

Version: 11.x-dev » main

Drupal core is now using the main branch as the primary development branch. New developments and disruptive changes should now be targeted to the main branch.

Read more in the announcement.