Question

I have a session variable, that once set changes block output of the system branding block. Normally this variable is intercepted from the query string by an inbound path processor, however that is a different test. In this test I just want to make sure the output is as expected.

So I set up my test as follows:

class ConfigOverrideCacheTest extends MyLabelTestBase {

  protected function setUp() {
    parent::setUp();

    $this->tokenOwner= $this->drupalCreateUser(['my permission']);
    $this->drupalLogin($this->tokenOwner);
  }

  public function testNotoken() {
    $this->drupalGet('<front>');
    // Check site name is Drupal.
    $this->assertSession()->elementTextContains('css', '.block-system-branding-block', 'Drupal');
  }

  public function testToken() {
    // Set session variable.
    \Drupal::service('session')->set('my_session_key', 'value');

    $this->drupalGet('<front>');
    // Check site name is NOT Drupal.
    $this->assertSession()->elementTextNotContains('css', '.block-system-branding-block', 'Drupal');
  }

}

This second test keeps failing, and the output is the same as in the first test. Which I suspect to be because it is set in the testrunner session, rather than the actual testing session.

How so set (or synchronize) session variables from the testrunner to the site that gets tested?

Was it helpful?

Solution

Referring SessionTest, there is a test-module (session_test) in place, which get's enabled:

  /**
   * Modules to enable.
   *
   * @var array
   */
  public static $modules = array('session_test');

And then called by GET request to set the session value:

 $this->drupalGet('session-test/set/' . $value_1);

I guess this procedure makes it really independent from the runner ..

So - make your module with one callback in .routing.yml, setting your session value in your controller. Your method afterwards could look like this:

public function testToken() {
  // Set session variable.
  $this->drupalGet('session-set/my-session-key/value');

  $this->drupalGet('<front>');
  // Check site name is NOT Drupal.
  $this->assertSession()->elementTextNotContains('css', '.block-system-branding-block', 'Drupal');
}

And, don't forget to enable the created module ;)


For completness, here the (above linked) SessionTest routing.yml:

session_test.set:
  path: '/session-test/set/{test_value}'
  defaults:
    _title: 'Set session value'
    _controller: '\Drupal\session_test\Controller\SessionTestController::set'
  options:
    no_cache: TRUE
    converters:
      test_value: '\s+'
  requirements:
    _access: 'TRUE'

and Controller:

public function set($test_value) {
  $_SESSION['session_test_value'] = $test_value;

  return ['#markup' => $this->t('The current value of the stored session variable has been set to %val', array('%val' => $test_value))];
}

OTHER TIPS

I am not sure if the storage you use to save the my_session_key attribute is shared between the testrunner and the site that gets tested, and that could explain why the test fails.

Why not test exactly the case of the inbound path processing, e.g.:

public function testToken() {
  $options = [
    'query' => [
      'param' => 'value',
    ]
  ];
  $this->drupalGet('<front>', $options);
  // Check site name is NOT Drupal.
  $this->assertSession()->elementTextNotContains('css', '.block-system-branding-block', 'Drupal');
}

Good luck in any case!

Licensed under: CC-BY-SA with attribution
Not affiliated with drupal.stackexchange
scroll top