Updated Drupal to 8.6. This goes with the following updates because it's possible...
[yaffs-website] / web / core / tests / Drupal / Tests / Core / Form / FormCacheTest.php
1 <?php
2
3 namespace Drupal\Tests\Core\Form;
4
5 use Drupal\Core\Form\FormCache;
6 use Drupal\Core\Form\FormState;
7 use Drupal\Tests\UnitTestCase;
8
9 /**
10  * @coversDefaultClass \Drupal\Core\Form\FormCache
11  * @group Form
12  */
13 class FormCacheTest extends UnitTestCase {
14
15   /**
16    * The form cache object under test.
17    *
18    * @var \Drupal\Core\Form\FormCache
19    */
20   protected $formCache;
21
22   /**
23    * The expirable key value factory.
24    *
25    * @var \Drupal\Core\KeyValueStore\KeyValueExpirableFactoryInterface|\PHPUnit_Framework_MockObject_MockObject
26    */
27   protected $keyValueExpirableFactory;
28
29   /**
30    * The current user.
31    *
32    * @var \Drupal\Core\Session\AccountInterface|\PHPUnit_Framework_MockObject_MockObject
33    */
34   protected $account;
35
36   /**
37    * The CSRF token generator.
38    *
39    * @var \Drupal\Core\Access\CsrfTokenGenerator|\PHPUnit_Framework_MockObject_MockObject
40    */
41   protected $csrfToken;
42
43   /**
44    * The mocked module handler.
45    *
46    * @var \Drupal\Core\Extension\ModuleHandlerInterface|\PHPUnit_Framework_MockObject_MockObject
47    */
48   protected $moduleHandler;
49
50   /**
51    * The expirable key value store used by form cache.
52    *
53    * @var \Drupal\Core\KeyValueStore\KeyValueStoreExpirableInterface|\PHPUnit_Framework_MockObject_MockObject
54    */
55   protected $formCacheStore;
56
57   /**
58    * The expirable key value store used by form state cache.
59    *
60    * @var \Drupal\Core\KeyValueStore\KeyValueStoreExpirableInterface|\PHPUnit_Framework_MockObject_MockObject
61    */
62   protected $formStateCacheStore;
63
64   /**
65    * The logger channel.
66    *
67    * @var \Psr\Log\LoggerInterface|\PHPUnit_Framework_MockObject_MockObject
68    */
69   protected $logger;
70
71   /**
72    * The request stack.
73    *
74    * @var \Symfony\Component\HttpFoundation\RequestStack|\PHPUnit_Framework_MockObject_MockObject
75    */
76   protected $requestStack;
77
78   /**
79    * A policy rule determining the cacheability of a request.
80    *
81    * @var \Drupal\Core\PageCache\RequestPolicyInterface|\PHPUnit_Framework_MockObject_MockObject
82    */
83   protected $requestPolicy;
84
85   /**
86    * {@inheritdoc}
87    */
88   protected $runTestInSeparateProcess = TRUE;
89
90   /**
91    * {@inheritdoc}
92    */
93   protected $preserveGlobalState = FALSE;
94
95   /**
96    * {@inheritdoc}
97    */
98   protected function setUp() {
99     parent::setUp();
100
101     $this->moduleHandler = $this->getMock('Drupal\Core\Extension\ModuleHandlerInterface');
102
103     $this->formCacheStore = $this->getMock('Drupal\Core\KeyValueStore\KeyValueStoreExpirableInterface');
104     $this->formStateCacheStore = $this->getMock('Drupal\Core\KeyValueStore\KeyValueStoreExpirableInterface');
105     $this->keyValueExpirableFactory = $this->getMock('Drupal\Core\KeyValueStore\KeyValueExpirableFactoryInterface');
106     $this->keyValueExpirableFactory->expects($this->any())
107       ->method('get')
108       ->will($this->returnValueMap([
109         ['form', $this->formCacheStore],
110         ['form_state', $this->formStateCacheStore],
111       ]));
112
113     $this->csrfToken = $this->getMockBuilder('Drupal\Core\Access\CsrfTokenGenerator')
114       ->disableOriginalConstructor()
115       ->getMock();
116     $this->account = $this->getMock('Drupal\Core\Session\AccountInterface');
117
118     $this->logger = $this->getMock('Psr\Log\LoggerInterface');
119     $this->requestStack = $this->getMock('\Symfony\Component\HttpFoundation\RequestStack');
120     $this->requestPolicy = $this->getMock('\Drupal\Core\PageCache\RequestPolicyInterface');
121
122     $this->formCache = new FormCache($this->root, $this->keyValueExpirableFactory, $this->moduleHandler, $this->account, $this->csrfToken, $this->logger, $this->requestStack, $this->requestPolicy);
123   }
124
125   /**
126    * @covers ::getCache
127    */
128   public function testGetCacheValidToken() {
129     $form_build_id = 'the_form_build_id';
130     $form_state = new FormState();
131     $cache_token = 'the_cache_token';
132     $cached_form = ['#cache_token' => $cache_token];
133
134     $this->formCacheStore->expects($this->once())
135       ->method('get')
136       ->with($form_build_id)
137       ->willReturn($cached_form);
138     $this->csrfToken->expects($this->once())
139       ->method('validate')
140       ->with($cache_token)
141       ->willReturn(TRUE);
142     $this->account->expects($this->never())
143       ->method('isAnonymous');
144
145     $form = $this->formCache->getCache($form_build_id, $form_state);
146     $this->assertSame($cached_form, $form);
147   }
148
149   /**
150    * @covers ::getCache
151    */
152   public function testGetCacheInvalidToken() {
153     $form_build_id = 'the_form_build_id';
154     $form_state = new FormState();
155     $cache_token = 'the_cache_token';
156     $cached_form = ['#cache_token' => $cache_token];
157
158     $this->formCacheStore->expects($this->once())
159       ->method('get')
160       ->with($form_build_id)
161       ->willReturn($cached_form);
162     $this->csrfToken->expects($this->once())
163       ->method('validate')
164       ->with($cache_token)
165       ->willReturn(FALSE);
166     $this->account->expects($this->never())
167       ->method('isAnonymous');
168
169     $form = $this->formCache->getCache($form_build_id, $form_state);
170     $this->assertNull($form);
171   }
172
173   /**
174    * @covers ::getCache
175    */
176   public function testGetCacheAnonUser() {
177     $form_build_id = 'the_form_build_id';
178     $form_state = new FormState();
179     $cached_form = ['#cache_token' => NULL];
180
181     $this->formCacheStore->expects($this->once())
182       ->method('get')
183       ->with($form_build_id)
184       ->willReturn($cached_form);
185     $this->account->expects($this->once())
186       ->method('isAnonymous')
187       ->willReturn(TRUE);
188     $this->csrfToken->expects($this->never())
189       ->method('validate');
190
191     $form = $this->formCache->getCache($form_build_id, $form_state);
192     $this->assertSame($cached_form, $form);
193   }
194
195   /**
196    * @covers ::getCache
197    */
198   public function testGetCacheAuthUser() {
199     $form_build_id = 'the_form_build_id';
200     $form_state = new FormState();
201     $cached_form = ['#cache_token' => NULL];
202
203     $this->formCacheStore->expects($this->once())
204       ->method('get')
205       ->with($form_build_id)
206       ->willReturn($cached_form);
207     $this->account->expects($this->once())
208       ->method('isAnonymous')
209       ->willReturn(FALSE);
210
211     $form = $this->formCache->getCache($form_build_id, $form_state);
212     $this->assertNull($form);
213   }
214
215   /**
216    * @covers ::getCache
217    */
218   public function testGetCacheNoForm() {
219     $form_build_id = 'the_form_build_id';
220     $form_state = new FormState();
221     $cached_form = NULL;
222
223     $this->formCacheStore->expects($this->once())
224       ->method('get')
225       ->with($form_build_id)
226       ->willReturn($cached_form);
227     $this->account->expects($this->never())
228       ->method('isAnonymous');
229
230     $form = $this->formCache->getCache($form_build_id, $form_state);
231     $this->assertNull($form);
232   }
233
234   /**
235    * @covers ::getCache
236    */
237   public function testGetCacheImmutableForm() {
238     $form_build_id = 'the_form_build_id';
239     $form_state = (new FormState())
240       ->addBuildInfo('immutable', TRUE);
241     $cached_form = [
242       '#build_id' => 'the_old_build_form_id',
243     ];
244
245     $this->account->expects($this->once())
246       ->method('isAnonymous')
247       ->willReturn(TRUE);
248     $this->formCacheStore->expects($this->once())
249       ->method('get')
250       ->with($form_build_id)
251       ->willReturn($cached_form);
252
253     $form = $this->formCache->getCache($form_build_id, $form_state);
254     $this->assertSame($cached_form['#build_id'], $form['#build_id_old']);
255     $this->assertNotSame($cached_form['#build_id'], $form['#build_id']);
256     $this->assertSame($form['#build_id'], $form['form_build_id']['#value']);
257     $this->assertSame($form['#build_id'], $form['form_build_id']['#id']);
258   }
259
260   /**
261    * @covers ::loadCachedFormState
262    */
263   public function testLoadCachedFormState() {
264     $form_build_id = 'the_form_build_id';
265     $form_state = new FormState();
266     $cached_form = ['#cache_token' => NULL];
267
268     $this->formCacheStore->expects($this->once())
269       ->method('get')
270       ->with($form_build_id)
271       ->willReturn($cached_form);
272     $this->account->expects($this->once())
273       ->method('isAnonymous')
274       ->willReturn(TRUE);
275
276     $cached_form_state = ['storage' => ['foo' => 'bar']];
277     $this->formStateCacheStore->expects($this->once())
278       ->method('get')
279       ->with($form_build_id)
280       ->willReturn($cached_form_state);
281
282     $this->formCache->getCache($form_build_id, $form_state);
283     $this->assertSame($cached_form_state['storage'], $form_state->getStorage());
284   }
285
286   /**
287    * @covers ::loadCachedFormState
288    */
289   public function testLoadCachedFormStateWithFiles() {
290     $form_build_id = 'the_form_build_id';
291     $form_state = new FormState();
292     $cached_form = ['#cache_token' => NULL];
293
294     $this->formCacheStore->expects($this->once())
295       ->method('get')
296       ->with($form_build_id)
297       ->willReturn($cached_form);
298     $this->account->expects($this->once())
299       ->method('isAnonymous')
300       ->willReturn(TRUE);
301
302     $cached_form_state = [
303       'build_info' => [
304         'files' => [
305           [
306             'module' => 'a_module',
307             'type' => 'the_type',
308             'name' => 'some_name',
309           ],
310           ['module' => 'another_module'],
311         ],
312       ],
313     ];
314     $this->moduleHandler->expects($this->at(0))
315       ->method('loadInclude')
316       ->with('a_module', 'the_type', 'some_name');
317     $this->moduleHandler->expects($this->at(1))
318       ->method('loadInclude')
319       ->with('another_module', 'inc', 'another_module');
320     $this->formStateCacheStore->expects($this->once())
321       ->method('get')
322       ->with($form_build_id)
323       ->willReturn($cached_form_state);
324
325     $this->formCache->getCache($form_build_id, $form_state);
326   }
327
328   /**
329    * @covers ::setCache
330    */
331   public function testSetCacheWithForm() {
332     $form_build_id = 'the_form_build_id';
333     $form = [
334       '#form_id' => 'the_form_id',
335     ];
336     $form_state = new FormState();
337
338     $this->formCacheStore->expects($this->once())
339       ->method('setWithExpire')
340       ->with($form_build_id, $form, $this->isType('int'));
341
342     $form_state_data = $form_state->getCacheableArray();
343     $this->formStateCacheStore->expects($this->once())
344       ->method('setWithExpire')
345       ->with($form_build_id, $form_state_data, $this->isType('int'));
346
347     $this->formCache->setCache($form_build_id, $form, $form_state);
348   }
349
350   /**
351    * @covers ::setCache
352    */
353   public function testSetCacheWithoutForm() {
354     $form_build_id = 'the_form_build_id';
355     $form = NULL;
356     $form_state = new FormState();
357
358     $this->formCacheStore->expects($this->never())
359       ->method('setWithExpire');
360
361     $form_state_data = $form_state->getCacheableArray();
362     $this->formStateCacheStore->expects($this->once())
363       ->method('setWithExpire')
364       ->with($form_build_id, $form_state_data, $this->isType('int'));
365
366     $this->formCache->setCache($form_build_id, $form, $form_state);
367   }
368
369   /**
370    * @covers ::setCache
371    */
372   public function testSetCacheAuthUser() {
373     $form_build_id = 'the_form_build_id';
374     $form = [];
375     $form_state = new FormState();
376
377     $cache_token = 'the_cache_token';
378     $form_data = $form;
379     $form_data['#cache_token'] = $cache_token;
380     $this->formCacheStore->expects($this->once())
381       ->method('setWithExpire')
382       ->with($form_build_id, $form_data, $this->isType('int'));
383
384     $form_state_data = $form_state->getCacheableArray();
385     $this->formStateCacheStore->expects($this->once())
386       ->method('setWithExpire')
387       ->with($form_build_id, $form_state_data, $this->isType('int'));
388
389     $this->csrfToken->expects($this->once())
390       ->method('get')
391       ->willReturn($cache_token);
392     $this->account->expects($this->once())
393       ->method('isAuthenticated')
394       ->willReturn(TRUE);
395
396     $this->formCache->setCache($form_build_id, $form, $form_state);
397   }
398
399   /**
400    * @covers ::setCache
401    */
402   public function testSetCacheBuildIdMismatch() {
403     $form_build_id = 'the_form_build_id';
404     $form = [
405       '#form_id' => 'the_form_id',
406       '#build_id' => 'stale_form_build_id',
407     ];
408     $form_state = new FormState();
409
410     $this->formCacheStore->expects($this->never())
411       ->method('setWithExpire');
412     $this->formStateCacheStore->expects($this->never())
413       ->method('setWithExpire');
414     $this->logger->expects($this->once())
415       ->method('error')
416       ->with('Form build-id mismatch detected while attempting to store a form in the cache.');
417     $this->formCache->setCache($form_build_id, $form, $form_state);
418   }
419
420   /**
421    * @covers ::deleteCache
422    */
423   public function testDeleteCache() {
424     $form_build_id = 'the_form_build_id';
425
426     $this->formCacheStore->expects($this->once())
427       ->method('delete')
428       ->with($form_build_id);
429     $this->formStateCacheStore->expects($this->once())
430       ->method('delete')
431       ->with($form_build_id);
432     $this->formCache->deleteCache($form_build_id);
433   }
434
435 }