Updated Drupal to 8.6. This goes with the following updates because it's possible...
[yaffs-website] / web / core / tests / Drupal / Tests / Core / Utility / TokenTest.php
1 <?php
2
3 namespace Drupal\Tests\Core\Utility;
4
5 use Drupal\Component\Utility\Html;
6 use Drupal\Core\Cache\Context\CacheContextsManager;
7 use Drupal\Core\DependencyInjection\ContainerBuilder;
8 use Drupal\Core\Language\LanguageInterface;
9 use Drupal\Core\Render\BubbleableMetadata;
10 use Drupal\Core\Render\Markup;
11 use Drupal\Core\Utility\Token;
12 use Drupal\Tests\UnitTestCase;
13
14 /**
15  * @coversDefaultClass \Drupal\Core\Utility\Token
16  * @group Utility
17  */
18 class TokenTest extends UnitTestCase {
19
20   /**
21    * The cache used for testing.
22    *
23    * @var \Drupal\Core\Cache\CacheBackendInterface|\PHPUnit_Framework_MockObject_MockObject
24    */
25   protected $cache;
26
27   /**
28    * The language manager used for testing.
29    *
30    * @var \Drupal\Core\Language\LanguageManagerInterface|\PHPUnit_Framework_MockObject_MockObject
31    */
32   protected $languageManager;
33
34   /**
35    * The module handler service used for testing.
36    *
37    * @var \Drupal\Core\Extension\ModuleHandlerInterface|\PHPUnit_Framework_MockObject_MockObject
38    */
39   protected $moduleHandler;
40
41   /**
42    * The language interface used for testing.
43    *
44    * @var \Drupal\Core\Language\LanguageInterface|\PHPUnit_Framework_MockObject_MockObject
45    */
46   protected $language;
47
48   /**
49    * The token service under test.
50    *
51    * @var \Drupal\Core\Utility\Token|\PHPUnit_Framework_MockObject_MockObject
52    */
53   protected $token;
54
55   /**
56    * The cache tags invalidator.
57    *
58    * @var \Drupal\Core\Cache\CacheTagsInvalidatorInterface|\PHPUnit_Framework_MockObject_MockObject
59    */
60   protected $cacheTagsInvalidator;
61
62   /**
63    * The cache contexts manager.
64    *
65    * @var \Drupal\Core\Cache\Context\CacheContextsManager
66    */
67   protected $cacheContextManager;
68
69   /**
70    * The renderer.
71    *
72    * @var \Drupal\Core\Render\RendererInterface|\PHPUnit_Framework_MockObject_MockObject
73    */
74   protected $renderer;
75
76   /**
77    * {@inheritdoc}
78    */
79   protected function setUp() {
80     $this->cache = $this->getMock('\Drupal\Core\Cache\CacheBackendInterface');
81
82     $this->languageManager = $this->getMock('Drupal\Core\Language\LanguageManagerInterface');
83
84     $this->moduleHandler = $this->getMock('\Drupal\Core\Extension\ModuleHandlerInterface');
85
86     $this->language = $this->getMock('\Drupal\Core\Language\LanguageInterface');
87
88     $this->cacheTagsInvalidator = $this->getMock('\Drupal\Core\Cache\CacheTagsInvalidatorInterface');
89
90     $this->renderer = $this->getMock('Drupal\Core\Render\RendererInterface');
91
92     $this->token = new Token($this->moduleHandler, $this->cache, $this->languageManager, $this->cacheTagsInvalidator, $this->renderer);
93
94     $container = new ContainerBuilder();
95     $this->cacheContextManager = new CacheContextsManager($container, [
96       'current_user',
97       'custom_context',
98     ]);
99     $container->set('cache_contexts_manager', $this->cacheContextManager);
100     \Drupal::setContainer($container);
101   }
102
103   /**
104    * @covers ::getInfo
105    */
106   public function testGetInfo() {
107     $token_info = [
108       'types' => [
109         'foo' => [
110           'name' => $this->randomMachineName(),
111         ],
112       ],
113     ];
114
115     $this->language->expects($this->atLeastOnce())
116       ->method('getId')
117       ->will($this->returnValue($this->randomMachineName()));
118
119     $this->languageManager->expects($this->once())
120       ->method('getCurrentLanguage')
121       ->with(LanguageInterface::TYPE_CONTENT)
122       ->will($this->returnValue($this->language));
123
124     // The persistent cache must only be hit once, after which the info is
125     // cached statically.
126     $this->cache->expects($this->once())
127       ->method('get');
128     $this->cache->expects($this->once())
129       ->method('set')
130       ->with('token_info:' . $this->language->getId(), $token_info);
131
132     $this->moduleHandler->expects($this->once())
133       ->method('invokeAll')
134       ->with('token_info')
135       ->will($this->returnValue($token_info));
136     $this->moduleHandler->expects($this->once())
137       ->method('alter')
138       ->with('token_info', $token_info);
139
140     // Get the information for the first time. The cache should be checked, the
141     // hooks invoked, and the info should be set to the cache should.
142     $this->token->getInfo();
143     // Get the information for the second time. The data must be returned from
144     // the static cache, so the persistent cache must not be accessed and the
145     // hooks must not be invoked.
146     $this->token->getInfo();
147   }
148
149   /**
150    * @covers ::replace
151    */
152   public function testReplaceWithBubbleableMetadataObject() {
153     $this->moduleHandler->expects($this->any())
154       ->method('invokeAll')
155       ->willReturn(['[node:title]' => 'hello world']);
156
157     $bubbleable_metadata = new BubbleableMetadata();
158     $bubbleable_metadata->setCacheContexts(['current_user']);
159     $bubbleable_metadata->setCacheMaxAge(12);
160
161     $node = $this->prophesize('Drupal\node\NodeInterface');
162     $node->getCacheTags()->willReturn(['node:1']);
163     $node->getCacheContexts()->willReturn(['custom_context']);
164     $node->getCacheMaxAge()->willReturn(10);
165     $node = $node->reveal();
166
167     $result = $this->token->replace('[node:title]', ['node' => $node], [], $bubbleable_metadata);
168     $this->assertEquals('hello world', $result);
169
170     $this->assertEquals(['node:1'], $bubbleable_metadata->getCacheTags());
171     $this->assertEquals([
172       'current_user',
173       'custom_context',
174     ], $bubbleable_metadata->getCacheContexts());
175     $this->assertEquals(10, $bubbleable_metadata->getCacheMaxAge());
176   }
177
178   /**
179    * @covers ::replace
180    */
181   public function testReplaceWithHookTokensWithBubbleableMetadata() {
182     $this->moduleHandler->expects($this->any())
183       ->method('invokeAll')
184       ->willReturnCallback(function ($hook_name, $args) {
185         $cacheable_metadata = $args[4];
186         $cacheable_metadata->addCacheContexts(['custom_context']);
187         $cacheable_metadata->addCacheTags(['node:1']);
188         $cacheable_metadata->setCacheMaxAge(10);
189
190         return ['[node:title]' => 'hello world'];
191       });
192
193     $node = $this->prophesize('Drupal\node\NodeInterface');
194     $node->getCacheContexts()->willReturn([]);
195     $node->getCacheTags()->willReturn([]);
196     $node->getCacheMaxAge()->willReturn(14);
197     $node = $node->reveal();
198
199     $bubbleable_metadata = new BubbleableMetadata();
200     $bubbleable_metadata->setCacheContexts(['current_user']);
201     $bubbleable_metadata->setCacheMaxAge(12);
202
203     $result = $this->token->replace('[node:title]', ['node' => $node], [], $bubbleable_metadata);
204     $this->assertEquals('hello world', $result);
205     $this->assertEquals(['node:1'], $bubbleable_metadata->getCacheTags());
206     $this->assertEquals([
207       'current_user',
208       'custom_context',
209     ], $bubbleable_metadata->getCacheContexts());
210     $this->assertEquals(10, $bubbleable_metadata->getCacheMaxAge());
211   }
212
213   /**
214    * @covers ::replace
215    * @covers ::replace
216    */
217   public function testReplaceWithHookTokensAlterWithBubbleableMetadata() {
218     $this->moduleHandler->expects($this->any())
219       ->method('invokeAll')
220       ->willReturn([]);
221
222     $this->moduleHandler->expects($this->any())
223       ->method('alter')
224       ->willReturnCallback(function ($hook_name, array &$replacements, array $context, BubbleableMetadata $bubbleable_metadata) {
225         $replacements['[node:title]'] = 'hello world';
226         $bubbleable_metadata->addCacheContexts(['custom_context']);
227         $bubbleable_metadata->addCacheTags(['node:1']);
228         $bubbleable_metadata->setCacheMaxAge(10);
229       });
230
231     $node = $this->prophesize('Drupal\node\NodeInterface');
232     $node->getCacheContexts()->willReturn([]);
233     $node->getCacheTags()->willReturn([]);
234     $node->getCacheMaxAge()->willReturn(14);
235     $node = $node->reveal();
236
237     $bubbleable_metadata = new BubbleableMetadata();
238     $bubbleable_metadata->setCacheContexts(['current_user']);
239     $bubbleable_metadata->setCacheMaxAge(12);
240
241     $result = $this->token->replace('[node:title]', ['node' => $node], [], $bubbleable_metadata);
242     $this->assertEquals('hello world', $result);
243     $this->assertEquals(['node:1'], $bubbleable_metadata->getCacheTags());
244     $this->assertEquals([
245       'current_user',
246       'custom_context',
247     ], $bubbleable_metadata->getCacheContexts());
248     $this->assertEquals(10, $bubbleable_metadata->getCacheMaxAge());
249   }
250
251   /**
252    * @covers ::resetInfo
253    */
254   public function testResetInfo() {
255     $this->cacheTagsInvalidator->expects($this->once())
256       ->method('invalidateTags')
257       ->with(['token_info']);
258
259     $this->token->resetInfo();
260   }
261
262   /**
263    * @covers ::replace
264    * @dataProvider providerTestReplaceEscaping
265    */
266   public function testReplaceEscaping($string, array $tokens, $expected) {
267     $this->moduleHandler->expects($this->any())
268       ->method('invokeAll')
269       ->willReturnCallback(function ($type, $args) {
270         return $args[2]['tokens'];
271       });
272
273     $result = $this->token->replace($string, ['tokens' => $tokens]);
274     $this->assertInternalType('string', $result);
275     $this->assertEquals($expected, $result);
276   }
277
278   public function providerTestReplaceEscaping() {
279     $data = [];
280
281     // No tokens. The first argument to Token::replace() should not be escaped.
282     $data['no-tokens'] = ['muh', [], 'muh'];
283     $data['html-in-string'] = ['<h1>Giraffe</h1>', [], '<h1>Giraffe</h1>'];
284     $data['html-in-string-quote'] = ['<h1>Giraffe"</h1>', [], '<h1>Giraffe"</h1>'];
285
286     $data['simple-placeholder-with-plain-text'] = ['<h1>[token:meh]</h1>', ['[token:meh]' => 'Giraffe"'], '<h1>' . Html::escape('Giraffe"') . '</h1>'];
287
288     $data['simple-placeholder-with-safe-html'] = [
289       '<h1>[token:meh]</h1>',
290       ['[token:meh]' => Markup::create('<em>Emphasized</em>')],
291       '<h1><em>Emphasized</em></h1>',
292     ];
293
294     return $data;
295   }
296
297 }