Backup of db before drupal security update
[yaffs-website] / web / core / modules / config_translation / tests / src / Unit / ConfigNamesMapperTest.php
1 <?php
2
3 /**
4  * @file
5  * Contains \Drupal\Tests\config_translation\Unit\ConfigNamesMapperTest.
6  */
7
8 namespace Drupal\Tests\config_translation\Unit;
9
10 use Drupal\config_translation\ConfigNamesMapper;
11 use Drupal\Core\Config\ConfigFactoryInterface;
12 use Drupal\Core\DependencyInjection\ContainerBuilder;
13 use Drupal\Core\Language\Language;
14 use Drupal\Core\Routing\RouteMatch;
15 use Drupal\Core\Url;
16 use Drupal\Tests\UnitTestCase;
17 use Symfony\Component\Routing\Route;
18
19 /**
20  * Tests the functionality provided by the configuration names mapper.
21  *
22  * @group config_translation
23  */
24 class ConfigNamesMapperTest extends UnitTestCase {
25
26   /**
27    * The plugin definition of the test mapper.
28    *
29    * @var array
30    */
31   protected $pluginDefinition;
32
33   /**
34    * The configuration names mapper to test.
35    *
36    * @see \Drupal\config_translation\ConfigNamesMapper
37    *
38    * @var \Drupal\Tests\config_translation\Unit\TestConfigNamesMapper
39    */
40   protected $configNamesMapper;
41
42   /**
43    * The locale configuration manager.
44    *
45    * @var \Drupal\locale\LocaleConfigManager|\PHPUnit_Framework_MockObject_MockObject
46    */
47   protected $localeConfigManager;
48
49   /**
50    * The locale configuration manager.
51    *
52    * @var \Drupal\locale\LocaleConfigManager|\PHPUnit_Framework_MockObject_MockObject
53    */
54   protected $typedConfigManager;
55
56   /**
57    * The configuration mapper manager.
58    *
59    * @var \Drupal\config_translation\ConfigMapperManagerInterface|\PHPUnit_Framework_MockObject_MockObject
60    */
61   protected $configMapperManager;
62
63   /**
64    * The base route used for testing.
65    *
66    * @var \Symfony\Component\Routing\Route
67    */
68   protected $baseRoute;
69
70   /**
71    * The route provider used for testing.
72    *
73    * @var \Drupal\Core\Routing\RouteProviderInterface|\PHPUnit_Framework_MockObject_MockObject
74    */
75   protected $routeProvider;
76
77   /**
78    * The mocked URL generator.
79    *
80    * @var \Drupal\Core\Routing\UrlGeneratorInterface|\PHPUnit_Framework_MockObject_MockObject
81    */
82   protected $urlGenerator;
83
84   /**
85    * The mocked language manager.
86    *
87    * @var \Drupal\Core\Language\LanguageManagerInterface $language_manager|\PHPUnit_Framework_MockObject_MockObject
88    */
89   protected $languageManager;
90
91   protected function setUp() {
92     $this->routeProvider = $this->getMock('Drupal\Core\Routing\RouteProviderInterface');
93
94     $this->pluginDefinition = [
95       'class' => '\Drupal\config_translation\ConfigNamesMapper',
96       'base_route_name' => 'system.site_information_settings',
97       'title' => 'System information',
98       'names' => ['system.site'],
99       'weight' => 42,
100     ];
101
102     $this->typedConfigManager = $this->getMock('Drupal\Core\Config\TypedConfigManagerInterface');
103
104     $this->localeConfigManager = $this->getMockBuilder('Drupal\locale\LocaleConfigManager')
105       ->disableOriginalConstructor()
106       ->getMock();
107
108     $this->configMapperManager = $this->getMock('Drupal\config_translation\ConfigMapperManagerInterface');
109
110     $this->urlGenerator = $this->getMock('Drupal\Core\Routing\UrlGeneratorInterface');
111     $container = new ContainerBuilder();
112     $container->set('url_generator', $this->urlGenerator);
113     \Drupal::setContainer($container);
114
115     $this->baseRoute = new Route('/admin/config/system/site-information');
116
117     $this->routeProvider
118       ->expects($this->any())
119       ->method('getRouteByName')
120       ->with('system.site_information_settings')
121       ->will($this->returnValue($this->baseRoute));
122
123     $this->languageManager = $this->getMock('Drupal\Core\Language\LanguageManagerInterface');
124
125     $this->configNamesMapper = new TestConfigNamesMapper(
126       'system.site_information_settings',
127       $this->pluginDefinition,
128       $this->getConfigFactoryStub(),
129       $this->typedConfigManager,
130       $this->localeConfigManager,
131       $this->configMapperManager,
132       $this->routeProvider,
133       $this->getStringTranslationStub(),
134       $this->languageManager
135     );
136   }
137
138   /**
139    * Tests ConfigNamesMapper::getTitle().
140    */
141   public function testGetTitle() {
142     $result = $this->configNamesMapper->getTitle();
143     $this->assertSame($this->pluginDefinition['title'], (string) $result);
144   }
145
146   /**
147    * Tests ConfigNamesMapper::getBaseRouteName().
148    */
149   public function testGetBaseRouteName() {
150     $result = $this->configNamesMapper->getBaseRouteName();
151     $this->assertSame($this->pluginDefinition['base_route_name'], $result);
152   }
153
154   /**
155    * Tests ConfigNamesMapper::getBaseRouteParameters().
156    */
157   public function testGetBaseRouteParameters() {
158     $result = $this->configNamesMapper->getBaseRouteParameters();
159     $this->assertSame([], $result);
160   }
161
162   /**
163    * Tests ConfigNamesMapper::getBaseRoute().
164    */
165   public function testGetBaseRoute() {
166     $result = $this->configNamesMapper->getBaseRoute();
167     $this->assertSame($this->baseRoute, $result);
168   }
169
170   /**
171    * Tests ConfigNamesMapper::getBasePath().
172    */
173   public function testGetBasePath() {
174     $this->urlGenerator->expects($this->once())
175       ->method('getPathFromRoute')
176       ->with('system.site_information_settings', [])
177       ->willReturn('/admin/config/system/site-information');
178     $result = $this->configNamesMapper->getBasePath();
179     $this->assertSame('/admin/config/system/site-information', $result);
180   }
181
182   /**
183    * Tests ConfigNamesMapper::getOverviewRouteName().
184    */
185   public function testGetOverviewRouteName() {
186     $result = $this->configNamesMapper->getOverviewRouteName();
187     $expected = 'config_translation.item.overview.' . $this->pluginDefinition['base_route_name'];
188     $this->assertSame($expected, $result);
189   }
190
191   /**
192    * Tests ConfigNamesMapper::getOverviewRouteParameters().
193    */
194   public function testGetOverviewRouteParameters() {
195     $result = $this->configNamesMapper->getOverviewRouteParameters();
196     $this->assertSame([], $result);
197   }
198
199   /**
200    * Tests ConfigNamesMapper::getOverviewRoute().
201    */
202   public function testGetOverviewRoute() {
203     $expected = new Route('/admin/config/system/site-information/translate',
204       [
205         '_controller' => '\Drupal\config_translation\Controller\ConfigTranslationController::itemPage',
206         'plugin_id' => 'system.site_information_settings',
207       ],
208       [
209         '_config_translation_overview_access' => 'TRUE',
210       ]
211     );
212     $result = $this->configNamesMapper->getOverviewRoute();
213     $this->assertSame(serialize($expected), serialize($result));
214   }
215
216   /**
217    * Tests ConfigNamesMapper::getOverviewPath().
218    */
219   public function testGetOverviewPath() {
220     $this->urlGenerator->expects($this->once())
221       ->method('getPathFromRoute')
222       ->with('config_translation.item.overview.system.site_information_settings', [])
223       ->willReturn('/admin/config/system/site-information/translate');
224
225     $result = $this->configNamesMapper->getOverviewPath();
226     $this->assertSame('/admin/config/system/site-information/translate', $result);
227   }
228
229   /**
230    * Tests ConfigNamesMapper::getAddRouteName().
231    */
232   public function testGetAddRouteName() {
233     $result = $this->configNamesMapper->getAddRouteName();
234     $expected = 'config_translation.item.add.' . $this->pluginDefinition['base_route_name'];
235     $this->assertSame($expected, $result);
236   }
237
238   /**
239    * Tests ConfigNamesMapper::getAddRouteParameters().
240    */
241   public function testGetAddRouteParameters() {
242     $route_match = new RouteMatch('example', new Route('/test/{langcode}'), ['langcode' => 'xx']);
243     $this->configNamesMapper->populateFromRouteMatch($route_match);
244
245     $expected = ['langcode' => 'xx'];
246     $result = $this->configNamesMapper->getAddRouteParameters();
247     $this->assertSame($expected, $result);
248   }
249
250   /**
251    * Tests ConfigNamesMapper::getAddRoute().
252    */
253   public function testGetAddRoute() {
254     $expected = new Route('/admin/config/system/site-information/translate/{langcode}/add',
255       [
256         '_form' => '\Drupal\config_translation\Form\ConfigTranslationAddForm',
257         'plugin_id' => 'system.site_information_settings',
258       ],
259       [
260         '_config_translation_form_access' => 'TRUE',
261       ]
262     );
263     $result = $this->configNamesMapper->getAddRoute();
264     $this->assertSame(serialize($expected), serialize($result));
265   }
266
267   /**
268    * Tests ConfigNamesMapper::getEditRouteName().
269    */
270   public function testGetEditRouteName() {
271     $result = $this->configNamesMapper->getEditRouteName();
272     $expected = 'config_translation.item.edit.' . $this->pluginDefinition['base_route_name'];
273     $this->assertSame($expected, $result);
274   }
275
276   /**
277    * Tests ConfigNamesMapper::getEditRouteParameters().
278    */
279   public function testGetEditRouteParameters() {
280     $route_match = new RouteMatch('example', new Route('/test/{langcode}'), ['langcode' => 'xx']);
281     $this->configNamesMapper->populateFromRouteMatch($route_match);
282
283     $expected = ['langcode' => 'xx'];
284     $result = $this->configNamesMapper->getEditRouteParameters();
285     $this->assertSame($expected, $result);
286   }
287
288   /**
289    * Tests ConfigNamesMapper::getEditRoute().
290    */
291   public function testGetEditRoute() {
292     $expected = new Route('/admin/config/system/site-information/translate/{langcode}/edit',
293       [
294         '_form' => '\Drupal\config_translation\Form\ConfigTranslationEditForm',
295         'plugin_id' => 'system.site_information_settings',
296       ],
297       [
298         '_config_translation_form_access' => 'TRUE',
299       ]
300     );
301     $result = $this->configNamesMapper->getEditRoute();
302     $this->assertSame(serialize($expected), serialize($result));
303   }
304
305   /**
306    * Tests ConfigNamesMapper::getDeleteRouteName().
307    */
308   public function testGetDeleteRouteName() {
309     $result = $this->configNamesMapper->getDeleteRouteName();
310     $expected = 'config_translation.item.delete.' . $this->pluginDefinition['base_route_name'];
311     $this->assertSame($expected, $result);
312   }
313
314   /**
315    * Tests ConfigNamesMapper::getDeleteRouteParameters().
316    */
317   public function testGetDeleteRouteParameters() {
318     $route_match = new RouteMatch('example', new Route('/test/{langcode}'), ['langcode' => 'xx']);
319     $this->configNamesMapper->populateFromRouteMatch($route_match);
320
321     $expected = ['langcode' => 'xx'];    $result = $this->configNamesMapper->getDeleteRouteParameters();
322     $this->assertSame($expected, $result);
323   }
324
325   /**
326    * Tests ConfigNamesMapper::getRoute().
327    */
328   public function testGetDeleteRoute() {
329     $expected = new Route('/admin/config/system/site-information/translate/{langcode}/delete',
330       [
331         '_form' => '\Drupal\config_translation\Form\ConfigTranslationDeleteForm',
332         'plugin_id' => 'system.site_information_settings',
333       ],
334       [
335         '_config_translation_form_access' => 'TRUE',
336       ]
337     );
338     $result = $this->configNamesMapper->getDeleteRoute();
339     $this->assertSame(serialize($expected), serialize($result));
340   }
341
342   /**
343    * Tests ConfigNamesMapper::getConfigNames().
344    */
345   public function testGetConfigNames() {
346     $result = $this->configNamesMapper->getConfigNames();
347     $this->assertSame($this->pluginDefinition['names'], $result);
348   }
349
350   /**
351    * Tests ConfigNamesMapper::addConfigName().
352    */
353   public function testAddConfigName() {
354     $names = $this->configNamesMapper->getConfigNames();
355     $this->configNamesMapper->addConfigName('test');
356     $names[] = 'test';
357     $result = $this->configNamesMapper->getConfigNames();
358     $this->assertSame($names, $result);
359   }
360
361   /**
362    * Tests ConfigNamesMapper::getWeight().
363    */
364   public function testGetWeight() {
365     $result = $this->configNamesMapper->getWeight();
366     $this->assertSame($this->pluginDefinition['weight'], $result);
367   }
368
369   /**
370    * Tests ConfigNamesMapper::populateFromRouteMatch().
371    */
372   public function testPopulateFromRouteMatch() {
373     // Make sure the language code is not set initially.
374     $this->assertSame(NULL, $this->configNamesMapper->getInternalLangcode());
375
376     // Test that an empty request does not set the language code.
377     $route_match = new RouteMatch('example', new Route('/test/{langcode}'));
378     $this->configNamesMapper->populateFromRouteMatch($route_match);
379     $this->assertSame(NULL, $this->configNamesMapper->getInternalLangcode());
380
381     // Test that a request with a 'langcode' attribute sets the language code.
382     $route_match = new RouteMatch('example', new Route('/test/{langcode}'), ['langcode' => 'xx']);
383     $this->configNamesMapper->populateFromRouteMatch($route_match);
384     $this->assertSame('xx', $this->configNamesMapper->getInternalLangcode());
385
386     // Test that the language code gets unset with the wrong request.
387     $route_match = new RouteMatch('example', new Route('/test/{langcode}'));
388     $this->configNamesMapper->populateFromRouteMatch($route_match);
389     $this->assertSame(NULL, $this->configNamesMapper->getInternalLangcode());
390   }
391
392   /**
393    * Tests ConfigNamesMapper::getTypeLabel().
394    */
395   public function testGetTypeLabel() {
396     $result = $this->configNamesMapper->getTypeLabel();
397     $this->assertSame($this->pluginDefinition['title'], (string) $result);
398   }
399
400   /**
401    * Tests ConfigNamesMapper::getLangcode().
402    */
403   public function testGetLangcode() {
404     // Test that the getLangcode() falls back to 'en', if no explicit language
405     // code is provided.
406     $config_factory = $this->getConfigFactoryStub([
407       'system.site' => ['key' => 'value'],
408     ]);
409     $this->configNamesMapper->setConfigFactory($config_factory);
410     $result = $this->configNamesMapper->getLangcode();
411     $this->assertSame('en', $result);
412
413     // Test that getLangcode picks up the language code provided by the
414     // configuration.
415     $config_factory = $this->getConfigFactoryStub([
416       'system.site' => ['langcode' => 'xx'],
417     ]);
418     $this->configNamesMapper->setConfigFactory($config_factory);
419     $result = $this->configNamesMapper->getLangcode();
420     $this->assertSame('xx', $result);
421
422     // Test that getLangcode() works for multiple configuration names.
423     $this->configNamesMapper->addConfigName('system.maintenance');
424     $config_factory = $this->getConfigFactoryStub([
425       'system.site' => ['langcode' => 'xx'],
426       'system.maintenance' => ['langcode' => 'xx'],
427     ]);
428     $this->configNamesMapper->setConfigFactory($config_factory);
429     $result = $this->configNamesMapper->getLangcode();
430     $this->assertSame('xx', $result);
431
432     // Test that getLangcode() throws an exception when different language codes
433     // are given.
434     $config_factory = $this->getConfigFactoryStub([
435       'system.site' => ['langcode' => 'xx'],
436       'system.maintenance' => ['langcode' => 'yy'],
437     ]);
438     $this->configNamesMapper->setConfigFactory($config_factory);
439     try {
440       $this->configNamesMapper->getLangcode();
441       $this->fail();
442     }
443     catch (\RuntimeException $e) {
444     }
445   }
446
447   /**
448    * Tests ConfigNamesMapper::getConfigData().
449    */
450   public function testGetConfigData() {
451     $configs = [
452       'system.site' => [
453         'name' => 'Drupal',
454         'slogan' => 'Come for the software, stay for the community!',
455       ],
456       'system.maintenance' => [
457         'enabled' => FALSE,
458         'message' => '@site is currently under maintenance.',
459       ],
460       'system.rss' => [
461         'items' => [
462           'limit' => 10,
463           'view_mode' => 'rss',
464         ],
465       ],
466     ];
467
468     $this->configNamesMapper->setConfigNames(array_keys($configs));
469     $config_factory = $this->getConfigFactoryStub($configs);
470     $this->configNamesMapper->setConfigFactory($config_factory);
471
472     $result = $this->configNamesMapper->getConfigData();
473     $this->assertSame($configs, $result);
474   }
475
476   /**
477    * Tests ConfigNamesMapper::hasSchema().
478    *
479    * @param array $mock_return_values
480    *   An array of values that the mocked locale configuration manager should
481    *   return for hasConfigSchema().
482    * @param bool $expected
483    *   The expected return value of ConfigNamesMapper::hasSchema().
484    *
485    * @dataProvider providerTestHasSchema
486    */
487   public function testHasSchema(array $mock_return_values, $expected) {
488     // As the configuration names are arbitrary, simply use integers.
489     $config_names = range(1, count($mock_return_values));
490     $this->configNamesMapper->setConfigNames($config_names);
491
492     $map = [];
493     foreach ($config_names as $i => $config_name) {
494       $map[] = [$config_name, $mock_return_values[$i]];
495     }
496     $this->typedConfigManager
497       ->expects($this->any())
498       ->method('hasConfigSchema')
499       ->will($this->returnValueMap($map));
500
501     $result = $this->configNamesMapper->hasSchema();
502     $this->assertSame($expected, $result);
503   }
504
505   /**
506    * Provides data for ConfigMapperTest::testHasSchema().
507    *
508    * @return array
509    *   An array of arrays, where each inner array has an array of values that
510    *   the mocked locale configuration manager should return for
511    *   hasConfigSchema() as the first value and the expected return value of
512    *   ConfigNamesMapper::hasSchema() as the second value.
513    */
514   public function providerTestHasSchema() {
515     return [
516       [[TRUE], TRUE],
517       [[FALSE], FALSE],
518       [[TRUE, TRUE, TRUE], TRUE],
519       [[TRUE, FALSE, TRUE], FALSE],
520     ];
521   }
522
523   /**
524    * Tests ConfigNamesMapper::hasTranslatable().
525    *
526    * @param array $mock_return_values
527    *   An array of values that the mocked configuration mapper manager should
528    *   return for hasTranslatable().
529    * @param bool $expected
530    *   The expected return value of ConfigNamesMapper::hasTranslatable().
531    *
532    * @dataProvider providerTestHasTranslatable
533    */
534   public function testHasTranslatable(array $mock_return_values, $expected) {
535     // As the configuration names are arbitrary, simply use integers.
536     $config_names = range(1, count($mock_return_values));
537     $this->configNamesMapper->setConfigNames($config_names);
538
539     $map = [];
540     foreach ($config_names as $i => $config_name) {
541       $map[] = isset($mock_return_values[$i]) ? [$config_name, $mock_return_values[$i]] : [];
542     }
543     $this->configMapperManager
544       ->expects($this->any())
545       ->method('hasTranslatable')
546       ->will($this->returnValueMap($map));
547
548     $result = $this->configNamesMapper->hasTranslatable();
549     $this->assertSame($expected, $result);
550   }
551
552   /**
553    * Provides data for ConfigNamesMapperTest::testHasTranslatable().
554    *
555    * @return array
556    *   An array of arrays, where each inner array has an array of values that
557    *   the mocked configuration mapper manager should return for
558    *   hasTranslatable() as the first value and the expected return value of
559    *   ConfigNamesMapper::hasTranslatable() as the second value.
560    */
561   public function providerTestHasTranslatable() {
562     return [
563       [[], FALSE],
564       [[TRUE], TRUE],
565       [[FALSE], FALSE],
566       [[TRUE, TRUE, TRUE], TRUE],
567       [[FALSE, FALSE, FALSE], FALSE],
568       [[TRUE, FALSE, TRUE], TRUE],
569     ];
570   }
571
572   /**
573    * Tests ConfigNamesMapper::hasTranslation().
574    *
575    * @param array $mock_return_values
576    *   An array of values that the mocked configuration mapper manager should
577    *   return for hasTranslation().
578    * @param bool $expected
579    *   The expected return value of ConfigNamesMapper::hasTranslation().
580    *
581    * @dataProvider providerTestHasTranslation
582    */
583   public function testHasTranslation(array $mock_return_values, $expected) {
584     $language = new Language();
585
586     // As the configuration names are arbitrary, simply use integers.
587     $config_names = range(1, count($mock_return_values));
588     $this->configNamesMapper->setConfigNames($config_names);
589
590     $map = [];
591     foreach ($config_names as $i => $config_name) {
592       $map[] = [$config_name, $language->getId(), $mock_return_values[$i]];
593     }
594     $this->localeConfigManager
595       ->expects($this->any())
596       ->method('hasTranslation')
597       ->will($this->returnValueMap($map));
598
599     $result = $this->configNamesMapper->hasTranslation($language);
600     $this->assertSame($expected, $result);
601   }
602
603   /**
604    * Provides data for for ConfigNamesMapperTest::testHasTranslation().
605    *
606    * @return array
607    *   An array of arrays, where each inner array has an array of values that
608    *   the mocked configuration mapper manager should return for
609    *   hasTranslation() as the first value and the expected return value of
610    *   ConfigNamesMapper::hasTranslation() as the second value.
611    */
612   public function providerTestHasTranslation() {
613     return [
614       [[TRUE], TRUE],
615       [[FALSE], FALSE],
616       [[TRUE, TRUE, TRUE], TRUE],
617       [[FALSE, FALSE, TRUE], TRUE],
618       [[FALSE, FALSE, FALSE], FALSE],
619     ];
620   }
621
622   /**
623    * Tests ConfigNamesMapper::getTypeName().
624    */
625   public function testGetTypeName() {
626     $result = $this->configNamesMapper->getTypeName();
627     $this->assertSame('Settings', (string) $result);
628   }
629
630   /**
631    * Tests ConfigNamesMapper::hasTranslation().
632    */
633   public function testGetOperations() {
634     $expected = [
635       'translate' => [
636         'title' => 'Translate',
637         'url' => Url::fromRoute('config_translation.item.overview.system.site_information_settings'),
638       ],
639     ];
640     $result = $this->configNamesMapper->getOperations();
641     $this->assertEquals($expected, $result);
642   }
643
644 }
645
646 /**
647  * Defines a test mapper class.
648  */
649 class TestConfigNamesMapper extends ConfigNamesMapper {
650
651   /**
652    * Gets the internal language code of this mapper, if any.
653    *
654    * This method is not to be confused with
655    * ConfigMapperInterface::getLangcode().
656    *
657    * @return string|null
658    *   The language code of this mapper if it is set; NULL otherwise.
659    */
660   public function getInternalLangcode() {
661     return isset($this->langcode) ? $this->langcode : NULL;
662   }
663
664   /**
665    * Sets the list of configuration names.
666    *
667    * @param array $config_names
668    */
669   public function setConfigNames(array $config_names) {
670     $this->pluginDefinition['names'] = $config_names;
671   }
672
673   /**
674    * Sets the configuration factory.
675    *
676    * @var \Drupal\Core\Config\ConfigFactoryInterface $config_factory
677    *   The config factory to set.
678    */
679   public function setConfigFactory(ConfigFactoryInterface $config_factory) {
680     $this->configFactory = $config_factory;
681   }
682
683 }