Updated Drupal to 8.6. This goes with the following updates because it's possible...
[yaffs-website] / web / core / tests / Drupal / Tests / Core / Session / PermissionsHashGeneratorTest.php
1 <?php
2
3 namespace Drupal\Tests\Core\Session;
4
5 use Drupal\Component\Utility\Crypt;
6 use Drupal\Core\Session\PermissionsHashGenerator;
7 use Drupal\Core\Site\Settings;
8 use Drupal\Tests\UnitTestCase;
9
10 /**
11  * @coversDefaultClass \Drupal\Core\Session\PermissionsHashGenerator
12  * @group Session
13  */
14 class PermissionsHashGeneratorTest extends UnitTestCase {
15
16   /**
17    * The mocked super user account.
18    *
19    * @var \Drupal\user\UserInterface|\PHPUnit_Framework_MockObject_MockObject
20    */
21   protected $account1;
22
23   /**
24    * A mocked account.
25    *
26    * @var \Drupal\user\UserInterface|\PHPUnit_Framework_MockObject_MockObject
27    */
28   protected $account2;
29
30   /**
31    * An "updated" mocked account.
32    *
33    * @var \Drupal\user\UserInterface|\PHPUnit_Framework_MockObject_MockObject
34    */
35   protected $account2Updated;
36
37   /**
38    * A different account.
39    *
40    * @var \Drupal\user\UserInterface|\PHPUnit_Framework_MockObject_MockObject
41    */
42   protected $account3;
43
44   /**
45    * The mocked private key service.
46    *
47    * @var \Drupal\Core\PrivateKey|\PHPUnit_Framework_MockObject_MockObject
48    */
49   protected $privateKey;
50
51   /**
52    * The mocked cache backend.
53    *
54    * @var \Drupal\Core\Cache\CacheBackendInterface|\PHPUnit_Framework_MockObject_MockObject
55    */
56   protected $cache;
57
58   /**
59    * The mocked cache backend.
60    *
61    * @var \Drupal\Core\Cache\CacheBackendInterface|\PHPUnit_Framework_MockObject_MockObject
62    */
63   protected $staticCache;
64
65   /**
66    * The permission hash class being tested.
67    *
68    * @var \Drupal\Core\Session\PermissionsHashGeneratorInterface
69    */
70   protected $permissionsHash;
71
72   /**
73    * {@inheritdoc}
74    */
75   protected function setUp() {
76     parent::setUp();
77
78     new Settings(['hash_salt' => 'test']);
79
80     // The mocked super user account, with the same roles as Account 2.
81     $this->account1 = $this->getMockBuilder('Drupal\user\Entity\User')
82       ->disableOriginalConstructor()
83       ->setMethods(['getRoles', 'id'])
84       ->getMock();
85     $this->account1->expects($this->any())
86       ->method('id')
87       ->willReturn(1);
88     $this->account1->expects($this->never())
89       ->method('getRoles');
90
91     // Account 2: 'administrator' and 'authenticated' roles.
92     $roles_1 = ['administrator', 'authenticated'];
93     $this->account2 = $this->getMockBuilder('Drupal\user\Entity\User')
94       ->disableOriginalConstructor()
95       ->setMethods(['getRoles', 'id'])
96       ->getMock();
97     $this->account2->expects($this->any())
98       ->method('getRoles')
99       ->will($this->returnValue($roles_1));
100     $this->account2->expects($this->any())
101       ->method('id')
102       ->willReturn(2);
103
104     // Account 3: 'authenticated' and 'administrator' roles (different order).
105     $roles_3 = ['authenticated', 'administrator'];
106     $this->account3 = $this->getMockBuilder('Drupal\user\Entity\User')
107       ->disableOriginalConstructor()
108       ->setMethods(['getRoles', 'id'])
109       ->getMock();
110     $this->account3->expects($this->any())
111       ->method('getRoles')
112       ->will($this->returnValue($roles_3));
113     $this->account3->expects($this->any())
114       ->method('id')
115       ->willReturn(3);
116
117     // Updated account 2: now also 'editor' role.
118     $roles_2_updated = ['editor', 'administrator', 'authenticated'];
119     $this->account2Updated = $this->getMockBuilder('Drupal\user\Entity\User')
120       ->disableOriginalConstructor()
121       ->setMethods(['getRoles', 'id'])
122       ->getMock();
123     $this->account2Updated->expects($this->any())
124       ->method('getRoles')
125       ->will($this->returnValue($roles_2_updated));
126     $this->account2Updated->expects($this->any())
127       ->method('id')
128       ->willReturn(2);
129
130     // Mocked private key + cache services.
131     $random = Crypt::randomBytesBase64(55);
132     $this->privateKey = $this->getMockBuilder('Drupal\Core\PrivateKey')
133       ->disableOriginalConstructor()
134       ->setMethods(['get'])
135       ->getMock();
136     $this->privateKey->expects($this->any())
137       ->method('get')
138       ->will($this->returnValue($random));
139     $this->cache = $this->getMockBuilder('Drupal\Core\Cache\CacheBackendInterface')
140       ->disableOriginalConstructor()
141       ->getMock();
142     $this->staticCache = $this->getMockBuilder('Drupal\Core\Cache\CacheBackendInterface')
143       ->disableOriginalConstructor()
144       ->getMock();
145
146     $this->permissionsHash = new PermissionsHashGenerator($this->privateKey, $this->cache, $this->staticCache);
147   }
148
149   /**
150    * @covers ::generate
151    */
152   public function testGenerate() {
153     // Ensure that the super user (user 1) always gets the same hash.
154     $super_user_hash = $this->permissionsHash->generate($this->account1);
155
156     // Ensure that two user accounts with the same roles generate the same hash.
157     $hash_2 = $this->permissionsHash->generate($this->account2);
158     $hash_3 = $this->permissionsHash->generate($this->account3);
159     $this->assertSame($hash_2, $hash_3, 'Different users with the same roles generate the same permissions hash.');
160
161     $this->assertNotSame($hash_2, $super_user_hash, 'User 1 has a different hash despite having the same roles');
162
163     // Compare with hash for user account 1 with an additional role.
164     $updated_hash_2 = $this->permissionsHash->generate($this->account2Updated);
165     $this->assertNotSame($hash_2, $updated_hash_2, 'Same user with updated roles generates different permissions hash.');
166   }
167
168   /**
169    * @covers ::generate
170    */
171   public function testGeneratePersistentCache() {
172     // Set expectations for the mocked cache backend.
173     $expected_cid = 'user_permissions_hash:administrator,authenticated';
174
175     $mock_cache = new \stdClass();
176     $mock_cache->data = 'test_hash_here';
177
178     $this->staticCache->expects($this->once())
179       ->method('get')
180       ->with($expected_cid)
181       ->will($this->returnValue(FALSE));
182     $this->staticCache->expects($this->once())
183       ->method('set')
184       ->with($expected_cid, $this->isType('string'));
185
186     $this->cache->expects($this->once())
187       ->method('get')
188       ->with($expected_cid)
189       ->will($this->returnValue($mock_cache));
190     $this->cache->expects($this->never())
191       ->method('set');
192
193     $this->permissionsHash->generate($this->account2);
194   }
195
196   /**
197    * @covers ::generate
198    */
199   public function testGenerateStaticCache() {
200     // Set expectations for the mocked cache backend.
201     $expected_cid = 'user_permissions_hash:administrator,authenticated';
202
203     $mock_cache = new \stdClass();
204     $mock_cache->data = 'test_hash_here';
205
206     $this->staticCache->expects($this->once())
207       ->method('get')
208       ->with($expected_cid)
209       ->will($this->returnValue($mock_cache));
210     $this->staticCache->expects($this->never())
211       ->method('set');
212
213     $this->cache->expects($this->never())
214       ->method('get');
215     $this->cache->expects($this->never())
216       ->method('set');
217
218     $this->permissionsHash->generate($this->account2);
219   }
220
221   /**
222    * Tests the generate method with no cache returned.
223    */
224   public function testGenerateNoCache() {
225     // Set expectations for the mocked cache backend.
226     $expected_cid = 'user_permissions_hash:administrator,authenticated';
227
228     $this->staticCache->expects($this->once())
229       ->method('get')
230       ->with($expected_cid)
231       ->will($this->returnValue(FALSE));
232     $this->staticCache->expects($this->once())
233       ->method('set')
234       ->with($expected_cid, $this->isType('string'));
235
236     $this->cache->expects($this->once())
237       ->method('get')
238       ->with($expected_cid)
239       ->will($this->returnValue(FALSE));
240     $this->cache->expects($this->once())
241       ->method('set')
242       ->with($expected_cid, $this->isType('string'));
243
244     $this->permissionsHash->generate($this->account2);
245   }
246
247 }
248
249 namespace Drupal\Core\Session;
250
251 // @todo remove once user_role_permissions() can be injected.
252 if (!function_exists('user_role_permissions')) {
253
254   function user_role_permissions(array $roles) {
255     $role_permissions = [];
256     foreach ($roles as $rid) {
257       $role_permissions[$rid] = [];
258     }
259     return $role_permissions;
260   }
261
262 }