3 namespace Drupal\Tests\Core\Access;
5 use Drupal\Core\Site\Settings;
6 use Drupal\Tests\UnitTestCase;
7 use Drupal\Core\Access\CsrfTokenGenerator;
8 use Drupal\Component\Utility\Crypt;
11 * Tests the CsrfTokenGenerator class.
14 * @coversDefaultClass \Drupal\Core\Access\CsrfTokenGenerator
16 class CsrfTokenGeneratorTest extends UnitTestCase {
19 * The CSRF token generator.
21 * @var \Drupal\Core\Access\CsrfTokenGenerator
26 * The mock private key instance.
28 * @var \Drupal\Core\PrivateKey|\PHPUnit_Framework_MockObject_MockObject
30 protected $privateKey;
33 * The mock session metadata bag.
35 * @var \Drupal\Core\Session\MetadataBag|\PHPUnit_Framework_MockObject_MockObject
37 protected $sessionMetadata;
42 protected function setUp() {
45 $this->privateKey = $this->getMockBuilder('Drupal\Core\PrivateKey')
46 ->disableOriginalConstructor()
50 $this->sessionMetadata = $this->getMockBuilder('Drupal\Core\Session\MetadataBag')
51 ->disableOriginalConstructor()
55 'hash_salt' => $this->randomMachineName(),
58 new Settings($settings);
60 $this->generator = new CsrfTokenGenerator($this->privateKey, $this->sessionMetadata);
64 * Set up default expectations on the mocks.
66 protected function setupDefaultExpectations() {
67 $key = Crypt::randomBytesBase64();
68 $this->privateKey->expects($this->any())
70 ->will($this->returnValue($key));
72 $seed = Crypt::randomBytesBase64();
73 $this->sessionMetadata->expects($this->any())
74 ->method('getCsrfTokenSeed')
75 ->will($this->returnValue($seed));
79 * Tests CsrfTokenGenerator::get().
83 public function testGet() {
84 $this->setupDefaultExpectations();
86 $this->assertInternalType('string', $this->generator->get());
87 $this->assertNotSame($this->generator->get(), $this->generator->get($this->randomMachineName()));
88 $this->assertNotSame($this->generator->get($this->randomMachineName()), $this->generator->get($this->randomMachineName()));
92 * Tests that a new token seed is generated upon first use.
96 public function testGenerateSeedOnGet() {
97 $key = Crypt::randomBytesBase64();
98 $this->privateKey->expects($this->any())
100 ->will($this->returnValue($key));
102 $this->sessionMetadata->expects($this->once())
103 ->method('getCsrfTokenSeed')
104 ->will($this->returnValue(NULL));
106 $this->sessionMetadata->expects($this->once())
107 ->method('setCsrfTokenSeed')
108 ->with($this->isType('string'));
110 $this->assertInternalType('string', $this->generator->get());
114 * Tests CsrfTokenGenerator::validate().
118 public function testValidate() {
119 $this->setupDefaultExpectations();
121 $token = $this->generator->get();
122 $this->assertTrue($this->generator->validate($token));
123 $this->assertFalse($this->generator->validate($token, 'foo'));
125 $token = $this->generator->get('bar');
126 $this->assertTrue($this->generator->validate($token, 'bar'));
130 * Tests CsrfTokenGenerator::validate() with different parameter types.
132 * @param mixed $token
133 * The token to be validated.
134 * @param mixed $value
135 * (optional) An additional value to base the token on.
138 * @dataProvider providerTestValidateParameterTypes
140 public function testValidateParameterTypes($token, $value) {
141 $this->setupDefaultExpectations();
143 // The following check might throw PHP fatals and notices, so we disable
145 set_error_handler(function () {return TRUE;});
146 $this->assertFalse($this->generator->validate($token, $value));
147 restore_error_handler();
151 * Provides data for testValidateParameterTypes.
154 * An array of data used by the test.
156 public function providerTestValidateParameterTypes() {
165 * Tests CsrfTokenGenerator::validate() with invalid parameter types.
167 * @param mixed $token
168 * The token to be validated.
169 * @param mixed $value
170 * (optional) An additional value to base the token on.
173 * @dataProvider providerTestInvalidParameterTypes
175 public function testInvalidParameterTypes($token, $value = '') {
176 $this->setupDefaultExpectations();
178 $this->setExpectedException(\InvalidArgumentException::class);
179 $this->generator->validate($token, $value);
183 * Provides data for testInvalidParameterTypes.
186 * An array of data used by the test.
188 public function providerTestInvalidParameterTypes() {
190 [NULL, new \stdClass()],
198 * Tests the exception thrown when no 'hash_salt' is provided in settings.
202 public function testGetWithNoHashSalt() {
203 // Update settings with no hash salt.
205 $generator = new CsrfTokenGenerator($this->privateKey, $this->sessionMetadata);
206 $this->setExpectedException(\RuntimeException::class);