You are here

class CsrfTokenGeneratorTest in Drupal 8

Same name and namespace in other branches
  1. 9 core/tests/Drupal/Tests/Core/Access/CsrfTokenGeneratorTest.php \Drupal\Tests\Core\Access\CsrfTokenGeneratorTest

Tests the CsrfTokenGenerator class.

@group Access @coversDefaultClass \Drupal\Core\Access\CsrfTokenGenerator

Hierarchy

Expanded class hierarchy of CsrfTokenGeneratorTest

File

core/tests/Drupal/Tests/Core/Access/CsrfTokenGeneratorTest.php, line 16

Namespace

Drupal\Tests\Core\Access
View source
class CsrfTokenGeneratorTest extends UnitTestCase {

  /**
   * The CSRF token generator.
   *
   * @var \Drupal\Core\Access\CsrfTokenGenerator
   */
  protected $generator;

  /**
   * The mock private key instance.
   *
   * @var \Drupal\Core\PrivateKey|\PHPUnit\Framework\MockObject\MockObject
   */
  protected $privateKey;

  /**
   * The mock session metadata bag.
   *
   * @var \Drupal\Core\Session\MetadataBag|\PHPUnit\Framework\MockObject\MockObject
   */
  protected $sessionMetadata;

  /**
   * {@inheritdoc}
   */
  protected function setUp() {
    parent::setUp();
    $this->privateKey = $this
      ->getMockBuilder('Drupal\\Core\\PrivateKey')
      ->disableOriginalConstructor()
      ->setMethods([
      'get',
    ])
      ->getMock();
    $this->sessionMetadata = $this
      ->getMockBuilder('Drupal\\Core\\Session\\MetadataBag')
      ->disableOriginalConstructor()
      ->getMock();
    $settings = [
      'hash_salt' => $this
        ->randomMachineName(),
    ];
    new Settings($settings);
    $this->generator = new CsrfTokenGenerator($this->privateKey, $this->sessionMetadata);
  }

  /**
   * Set up default expectations on the mocks.
   */
  protected function setupDefaultExpectations() {
    $key = Crypt::randomBytesBase64();
    $this->privateKey
      ->expects($this
      ->any())
      ->method('get')
      ->will($this
      ->returnValue($key));
    $seed = Crypt::randomBytesBase64();
    $this->sessionMetadata
      ->expects($this
      ->any())
      ->method('getCsrfTokenSeed')
      ->will($this
      ->returnValue($seed));
  }

  /**
   * Tests CsrfTokenGenerator::get().
   *
   * @covers ::get
   */
  public function testGet() {
    $this
      ->setupDefaultExpectations();
    $this
      ->assertIsString($this->generator
      ->get());
    $this
      ->assertNotSame($this->generator
      ->get(), $this->generator
      ->get($this
      ->randomMachineName()));
    $this
      ->assertNotSame($this->generator
      ->get($this
      ->randomMachineName()), $this->generator
      ->get($this
      ->randomMachineName()));
  }

  /**
   * Tests that a new token seed is generated upon first use.
   *
   * @covers ::get
   */
  public function testGenerateSeedOnGet() {
    $key = Crypt::randomBytesBase64();
    $this->privateKey
      ->expects($this
      ->any())
      ->method('get')
      ->will($this
      ->returnValue($key));
    $this->sessionMetadata
      ->expects($this
      ->once())
      ->method('getCsrfTokenSeed')
      ->will($this
      ->returnValue(NULL));
    $this->sessionMetadata
      ->expects($this
      ->once())
      ->method('setCsrfTokenSeed')
      ->with($this
      ->isType('string'));
    $this
      ->assertIsString($this->generator
      ->get());
  }

  /**
   * Tests CsrfTokenGenerator::validate().
   *
   * @covers ::validate
   */
  public function testValidate() {
    $this
      ->setupDefaultExpectations();
    $token = $this->generator
      ->get();
    $this
      ->assertTrue($this->generator
      ->validate($token));
    $this
      ->assertFalse($this->generator
      ->validate($token, 'foo'));
    $token = $this->generator
      ->get('bar');
    $this
      ->assertTrue($this->generator
      ->validate($token, 'bar'));
  }

  /**
   * Tests CsrfTokenGenerator::validate() with different parameter types.
   *
   * @param mixed $token
   *   The token to be validated.
   * @param mixed $value
   *   (optional) An additional value to base the token on.
   *
   * @covers ::validate
   * @dataProvider providerTestValidateParameterTypes
   */
  public function testValidateParameterTypes($token, $value) {
    $this
      ->setupDefaultExpectations();

    // The following check might throw PHP fatals and notices, so we disable
    // error assertions.
    set_error_handler(function () {
      return TRUE;
    });
    $this
      ->assertFalse($this->generator
      ->validate($token, $value));
    restore_error_handler();
  }

  /**
   * Provides data for testValidateParameterTypes.
   *
   * @return array
   *   An array of data used by the test.
   */
  public function providerTestValidateParameterTypes() {
    return [
      [
        [],
        '',
      ],
      [
        TRUE,
        'foo',
      ],
      [
        0,
        'foo',
      ],
    ];
  }

  /**
   * Tests CsrfTokenGenerator::validate() with invalid parameter types.
   *
   * @param mixed $token
   *   The token to be validated.
   * @param mixed $value
   *   (optional) An additional value to base the token on.
   *
   * @covers ::validate
   * @dataProvider providerTestInvalidParameterTypes
   */
  public function testInvalidParameterTypes($token, $value = '') {
    $this
      ->setupDefaultExpectations();
    $this
      ->expectException(\InvalidArgumentException::class);
    $this->generator
      ->validate($token, $value);
  }

  /**
   * Provides data for testInvalidParameterTypes.
   *
   * @return array
   *   An array of data used by the test.
   */
  public function providerTestInvalidParameterTypes() {
    return [
      [
        NULL,
        new \stdClass(),
      ],
      [
        0,
        [],
      ],
      [
        '',
        [],
      ],
      [
        [],
        [],
      ],
    ];
  }

  /**
   * Tests the exception thrown when no 'hash_salt' is provided in settings.
   *
   * @covers ::get
   */
  public function testGetWithNoHashSalt() {

    // Update settings with no hash salt.
    new Settings([]);
    $generator = new CsrfTokenGenerator($this->privateKey, $this->sessionMetadata);
    $this
      ->expectException(\RuntimeException::class);
    $generator
      ->get();
  }

}

Members

Namesort descending Modifiers Type Description Overrides
CsrfTokenGeneratorTest::$generator protected property The CSRF token generator.
CsrfTokenGeneratorTest::$privateKey protected property The mock private key instance.
CsrfTokenGeneratorTest::$sessionMetadata protected property The mock session metadata bag.
CsrfTokenGeneratorTest::providerTestInvalidParameterTypes public function Provides data for testInvalidParameterTypes.
CsrfTokenGeneratorTest::providerTestValidateParameterTypes public function Provides data for testValidateParameterTypes.
CsrfTokenGeneratorTest::setUp protected function Overrides UnitTestCase::setUp
CsrfTokenGeneratorTest::setupDefaultExpectations protected function Set up default expectations on the mocks.
CsrfTokenGeneratorTest::testGenerateSeedOnGet public function Tests that a new token seed is generated upon first use.
CsrfTokenGeneratorTest::testGet public function Tests CsrfTokenGenerator::get().
CsrfTokenGeneratorTest::testGetWithNoHashSalt public function Tests the exception thrown when no 'hash_salt' is provided in settings.
CsrfTokenGeneratorTest::testInvalidParameterTypes public function Tests CsrfTokenGenerator::validate() with invalid parameter types.
CsrfTokenGeneratorTest::testValidate public function Tests CsrfTokenGenerator::validate().
CsrfTokenGeneratorTest::testValidateParameterTypes public function Tests CsrfTokenGenerator::validate() with different parameter types.
PhpunitCompatibilityTrait::getMock Deprecated public function Returns a mock object for the specified class using the available method.
PhpunitCompatibilityTrait::setExpectedException Deprecated public function Compatibility layer for PHPUnit 6 to support PHPUnit 4 code.
UnitTestCase::$randomGenerator protected property The random generator.
UnitTestCase::$root protected property The app root. 1
UnitTestCase::assertArrayEquals protected function Asserts if two arrays are equal by sorting them first.
UnitTestCase::getBlockMockWithMachineName Deprecated protected function Mocks a block with a block plugin. 1
UnitTestCase::getClassResolverStub protected function Returns a stub class resolver.
UnitTestCase::getConfigFactoryStub public function Returns a stub config factory that behaves according to the passed array.
UnitTestCase::getConfigStorageStub public function Returns a stub config storage that returns the supplied configuration.
UnitTestCase::getContainerWithCacheTagsInvalidator protected function Sets up a container with a cache tags invalidator.
UnitTestCase::getRandomGenerator protected function Gets the random generator for the utility methods.
UnitTestCase::getStringTranslationStub public function Returns a stub translation manager that just returns the passed string.
UnitTestCase::randomMachineName public function Generates a unique random string containing letters and numbers.