annotate core/modules/locale/tests/src/Kernel/LocaleConfigSubscriberTest.php @ 19:fa3358dc1485 tip

Add ndrum files
author Chris Cannam
date Wed, 28 Aug 2019 13:14:47 +0100
parents af1871eacc83
children
rev   line source
Chris@0 1 <?php
Chris@0 2
Chris@0 3 namespace Drupal\Tests\locale\Kernel;
Chris@0 4
Chris@0 5 use Drupal\language\Entity\ConfigurableLanguage;
Chris@0 6 use Drupal\locale\Locale;
Chris@0 7 use Drupal\locale\StringInterface;
Chris@0 8 use Drupal\locale\TranslationString;
Chris@0 9 use Drupal\KernelTests\KernelTestBase;
Chris@0 10
Chris@0 11 /**
Chris@0 12 * Tests that shipped configuration translations are updated correctly.
Chris@0 13 *
Chris@0 14 * @group locale
Chris@0 15 */
Chris@0 16 class LocaleConfigSubscriberTest extends KernelTestBase {
Chris@0 17
Chris@0 18 /**
Chris@0 19 * {@inheritdoc}
Chris@0 20 */
Chris@0 21 public static $modules = ['language', 'locale', 'system', 'locale_test'];
Chris@0 22
Chris@0 23 /**
Chris@0 24 * The configurable language manager used in this test.
Chris@0 25 *
Chris@0 26 * @var \Drupal\language\ConfigurableLanguageManagerInterface
Chris@0 27 */
Chris@0 28 protected $languageManager;
Chris@0 29
Chris@0 30 /**
Chris@0 31 * The configuration factory used in this test.
Chris@0 32 *
Chris@0 33 * @var \Drupal\Core\Config\ConfigFactoryInterface
Chris@0 34 */
Chris@0 35 protected $configFactory;
Chris@0 36
Chris@0 37 /**
Chris@0 38 * The string storage used in this test.
Chris@0 39 *
Chris@17 40 * @var \Drupal\locale\StringStorageInterface
Chris@0 41 */
Chris@0 42 protected $stringStorage;
Chris@0 43
Chris@0 44 /**
Chris@0 45 * The locale configuration manager used in this test.
Chris@0 46 *
Chris@0 47 * @var \Drupal\locale\LocaleConfigManager
Chris@0 48 */
Chris@0 49 protected $localeConfigManager;
Chris@0 50
Chris@0 51 /**
Chris@0 52 * {@inheritdoc}
Chris@0 53 */
Chris@0 54 protected function setUp() {
Chris@0 55 parent::setUp();
Chris@0 56
Chris@0 57 $this->setUpDefaultLanguage();
Chris@0 58
Chris@0 59 $this->installSchema('locale', ['locales_source', 'locales_target', 'locales_location']);
Chris@0 60
Chris@0 61 $this->setupLanguages();
Chris@0 62
Chris@0 63 $this->installConfig(['locale_test']);
Chris@0 64 // Simulate this hook invoked which would happen if in a non-kernel test
Chris@0 65 // or normal environment.
Chris@0 66 // @see locale_modules_installed()
Chris@0 67 // @see locale_system_update()
Chris@0 68 locale_system_set_config_langcodes();
Chris@0 69 $langcodes = array_keys(\Drupal::languageManager()->getLanguages());
Chris@0 70 $names = Locale::config()->getComponentNames();
Chris@0 71 Locale::config()->updateConfigTranslations($names, $langcodes);
Chris@0 72
Chris@0 73 $this->configFactory = $this->container->get('config.factory');
Chris@0 74 $this->stringStorage = $this->container->get('locale.storage');
Chris@0 75 $this->localeConfigManager = $this->container->get('locale.config_manager');
Chris@0 76 $this->languageManager = $this->container->get('language_manager');
Chris@0 77
Chris@0 78 $this->setUpLocale();
Chris@0 79 }
Chris@0 80
Chris@0 81 /**
Chris@0 82 * Sets up default language for this test.
Chris@0 83 */
Chris@0 84 protected function setUpDefaultLanguage() {
Chris@0 85 // Keep the default English.
Chris@0 86 }
Chris@0 87
Chris@0 88 /**
Chris@0 89 * Sets up languages needed for this test.
Chris@0 90 */
Chris@0 91 protected function setUpLanguages() {
Chris@0 92 ConfigurableLanguage::createFromLangcode('de')->save();
Chris@0 93 }
Chris@0 94
Chris@0 95 /**
Chris@0 96 * Sets up the locale storage strings to be in line with configuration.
Chris@0 97 */
Chris@0 98 protected function setUpLocale() {
Chris@0 99 // Set up the locale database the same way we have in the config samples.
Chris@0 100 $this->setUpNoTranslation('locale_test.no_translation', 'test', 'Test', 'de');
Chris@0 101 $this->setUpTranslation('locale_test.translation', 'test', 'English test', 'German test', 'de');
Chris@0 102 }
Chris@0 103
Chris@0 104 /**
Chris@0 105 * Tests creating translations of shipped configuration.
Chris@0 106 */
Chris@0 107 public function testCreateTranslation() {
Chris@0 108 $config_name = 'locale_test.no_translation';
Chris@0 109
Chris@0 110 $this->saveLanguageOverride($config_name, 'test', 'Test (German)', 'de');
Chris@0 111 $this->assertTranslation($config_name, 'Test (German)', 'de');
Chris@0 112 }
Chris@0 113
Chris@0 114 /**
Chris@0 115 * Tests importing community translations of shipped configuration.
Chris@0 116 */
Chris@0 117 public function testLocaleCreateTranslation() {
Chris@0 118 $config_name = 'locale_test.no_translation';
Chris@0 119
Chris@0 120 $this->saveLocaleTranslationData($config_name, 'test', 'Test', 'Test (German)', 'de');
Chris@0 121 $this->assertTranslation($config_name, 'Test (German)', 'de', FALSE);
Chris@0 122 }
Chris@0 123
Chris@0 124 /**
Chris@0 125 * Tests updating translations of shipped configuration.
Chris@0 126 */
Chris@0 127 public function testUpdateTranslation() {
Chris@0 128 $config_name = 'locale_test.translation';
Chris@0 129
Chris@0 130 $this->saveLanguageOverride($config_name, 'test', 'Updated German test', 'de');
Chris@0 131 $this->assertTranslation($config_name, 'Updated German test', 'de');
Chris@0 132 }
Chris@0 133
Chris@0 134 /**
Chris@0 135 * Tests updating community translations of shipped configuration.
Chris@0 136 */
Chris@0 137 public function testLocaleUpdateTranslation() {
Chris@0 138 $config_name = 'locale_test.translation';
Chris@0 139
Chris@0 140 $this->saveLocaleTranslationData($config_name, 'test', 'English test', 'Updated German test', 'de');
Chris@0 141 $this->assertTranslation($config_name, 'Updated German test', 'de', FALSE);
Chris@0 142 }
Chris@0 143
Chris@0 144 /**
Chris@0 145 * Tests deleting translations of shipped configuration.
Chris@0 146 */
Chris@0 147 public function testDeleteTranslation() {
Chris@0 148 $config_name = 'locale_test.translation';
Chris@0 149
Chris@0 150 $this->deleteLanguageOverride($config_name, 'test', 'English test', 'de');
Chris@0 151 // Instead of deleting the translation, we need to keep a translation with
Chris@0 152 // the source value and mark it as customized to prevent the deletion being
Chris@0 153 // reverted by importing community translations.
Chris@0 154 $this->assertTranslation($config_name, 'English test', 'de');
Chris@0 155 }
Chris@0 156
Chris@0 157 /**
Chris@0 158 * Tests deleting community translations of shipped configuration.
Chris@0 159 */
Chris@0 160 public function testLocaleDeleteTranslation() {
Chris@0 161 $config_name = 'locale_test.translation';
Chris@0 162
Chris@0 163 $this->deleteLocaleTranslationData($config_name, 'test', 'English test', 'de');
Chris@0 164 $this->assertNoTranslation($config_name, 'de');
Chris@0 165 }
Chris@0 166
Chris@0 167 /**
Chris@0 168 * Sets up a configuration string without a translation.
Chris@0 169 *
Chris@0 170 * The actual configuration is already available by installing locale_test
Chris@0 171 * module, as it is done in LocaleConfigSubscriberTest::setUp(). This sets up
Chris@0 172 * the necessary source string and verifies that everything is as expected to
Chris@0 173 * avoid false positives.
Chris@0 174 *
Chris@0 175 * @param string $config_name
Chris@0 176 * The configuration name.
Chris@0 177 * @param string $key
Chris@0 178 * The configuration key.
Chris@0 179 * @param string $source
Chris@0 180 * The source string.
Chris@0 181 * @param string $langcode
Chris@0 182 * The language code.
Chris@0 183 */
Chris@0 184 protected function setUpNoTranslation($config_name, $key, $source, $langcode) {
Chris@0 185 $this->localeConfigManager->updateConfigTranslations([$config_name], [$langcode]);
Chris@0 186 $this->assertNoConfigOverride($config_name, $key, $source, $langcode);
Chris@0 187 $this->assertNoTranslation($config_name, $langcode);
Chris@0 188 }
Chris@0 189
Chris@0 190 /**
Chris@0 191 * Sets up a configuration string with a translation.
Chris@0 192 *
Chris@0 193 * The actual configuration is already available by installing locale_test
Chris@0 194 * module, as it is done in LocaleConfigSubscriberTest::setUp(). This sets up
Chris@0 195 * the necessary source and translation strings and verifies that everything
Chris@0 196 * is as expected to avoid false positives.
Chris@0 197 *
Chris@0 198 * @param string $config_name
Chris@0 199 * The configuration name.
Chris@0 200 * @param string $key
Chris@0 201 * The configuration key.
Chris@0 202 * @param string $source
Chris@0 203 * The source string.
Chris@0 204 * @param string $translation
Chris@0 205 * The translation string.
Chris@0 206 * @param string $langcode
Chris@0 207 * The language code.
Chris@0 208 * @param bool $is_active
Chris@0 209 * Whether the update will affect the active configuration.
Chris@0 210 */
Chris@0 211 protected function setUpTranslation($config_name, $key, $source, $translation, $langcode, $is_active = FALSE) {
Chris@0 212 // Create source and translation strings for the configuration value and add
Chris@0 213 // the configuration name as a location. This would be performed by
Chris@0 214 // locale_translate_batch_import() invoking
Chris@0 215 // LocaleConfigManager::updateConfigTranslations() normally.
Chris@0 216 $this->localeConfigManager->reset();
Chris@0 217 $this->localeConfigManager
Chris@0 218 ->getStringTranslation($config_name, $langcode, $source, '')
Chris@0 219 ->setString($translation)
Chris@0 220 ->setCustomized(FALSE)
Chris@0 221 ->save();
Chris@0 222 $this->configFactory->reset($config_name);
Chris@0 223 $this->localeConfigManager->reset();
Chris@0 224 $this->localeConfigManager->updateConfigTranslations([$config_name], [$langcode]);
Chris@0 225
Chris@0 226 if ($is_active) {
Chris@0 227 $this->assertActiveConfig($config_name, $key, $translation, $langcode);
Chris@0 228 }
Chris@0 229 else {
Chris@0 230 $this->assertConfigOverride($config_name, $key, $translation, $langcode);
Chris@0 231 }
Chris@0 232 $this->assertTranslation($config_name, $translation, $langcode, FALSE);
Chris@0 233 }
Chris@0 234
Chris@0 235 /**
Chris@0 236 * Saves a language override.
Chris@0 237 *
Chris@0 238 * This will invoke LocaleConfigSubscriber through the event dispatcher. To
Chris@0 239 * make sure the configuration was persisted correctly, the configuration
Chris@0 240 * value is checked. Because LocaleConfigSubscriber temporarily disables the
Chris@0 241 * override state of the configuration factory we check that the correct value
Chris@0 242 * is restored afterwards.
Chris@0 243 *
Chris@0 244 * @param string $config_name
Chris@0 245 * The configuration name.
Chris@0 246 * @param string $key
Chris@0 247 * The configuration key.
Chris@0 248 * @param string $value
Chris@0 249 * The configuration value to save.
Chris@0 250 * @param string $langcode
Chris@0 251 * The language code.
Chris@0 252 */
Chris@0 253 protected function saveLanguageOverride($config_name, $key, $value, $langcode) {
Chris@0 254 $translation_override = $this->languageManager
Chris@0 255 ->getLanguageConfigOverride($langcode, $config_name);
Chris@0 256 $translation_override
Chris@0 257 ->set($key, $value)
Chris@0 258 ->save();
Chris@0 259 $this->configFactory->reset($config_name);
Chris@0 260
Chris@0 261 $this->assertConfigOverride($config_name, $key, $value, $langcode);
Chris@0 262 }
Chris@0 263
Chris@0 264 /**
Chris@0 265 * Saves translation data from locale module.
Chris@0 266 *
Chris@0 267 * This will invoke LocaleConfigSubscriber through the event dispatcher. To
Chris@0 268 * make sure the configuration was persisted correctly, the configuration
Chris@0 269 * value is checked. Because LocaleConfigSubscriber temporarily disables the
Chris@0 270 * override state of the configuration factory we check that the correct value
Chris@0 271 * is restored afterwards.
Chris@0 272 *
Chris@0 273 * @param string $config_name
Chris@0 274 * The configuration name.
Chris@0 275 * @param string $key
Chris@0 276 * The configuration key.
Chris@0 277 * @param string $source
Chris@0 278 * The source string.
Chris@0 279 * @param string $translation
Chris@0 280 * The translation string to save.
Chris@0 281 * @param string $langcode
Chris@0 282 * The language code.
Chris@0 283 * @param bool $is_active
Chris@0 284 * Whether the update will affect the active configuration.
Chris@0 285 */
Chris@0 286 protected function saveLocaleTranslationData($config_name, $key, $source, $translation, $langcode, $is_active = FALSE) {
Chris@0 287 $this->localeConfigManager->reset();
Chris@0 288 $this->localeConfigManager
Chris@0 289 ->getStringTranslation($config_name, $langcode, $source, '')
Chris@0 290 ->setString($translation)
Chris@0 291 ->save();
Chris@0 292 $this->localeConfigManager->reset();
Chris@0 293 $this->localeConfigManager->updateConfigTranslations([$config_name], [$langcode]);
Chris@0 294 $this->configFactory->reset($config_name);
Chris@0 295
Chris@0 296 if ($is_active) {
Chris@0 297 $this->assertActiveConfig($config_name, $key, $translation, $langcode);
Chris@0 298 }
Chris@0 299 else {
Chris@0 300 $this->assertConfigOverride($config_name, $key, $translation, $langcode);
Chris@0 301 }
Chris@0 302 }
Chris@0 303
Chris@0 304 /**
Chris@0 305 * Deletes a language override.
Chris@0 306 *
Chris@0 307 * This will invoke LocaleConfigSubscriber through the event dispatcher. To
Chris@0 308 * make sure the configuration was persisted correctly, the configuration
Chris@0 309 * value is checked. Because LocaleConfigSubscriber temporarily disables the
Chris@0 310 * override state of the configuration factory we check that the correct value
Chris@0 311 * is restored afterwards.
Chris@0 312 *
Chris@0 313 * @param string $config_name
Chris@0 314 * The configuration name.
Chris@0 315 * @param string $key
Chris@0 316 * The configuration key.
Chris@0 317 * @param string $source_value
Chris@0 318 * The source configuration value to verify the correct value is returned
Chris@0 319 * from the configuration factory after the deletion.
Chris@0 320 * @param string $langcode
Chris@0 321 * The language code.
Chris@0 322 */
Chris@0 323 protected function deleteLanguageOverride($config_name, $key, $source_value, $langcode) {
Chris@0 324 $translation_override = $this->languageManager
Chris@0 325 ->getLanguageConfigOverride($langcode, $config_name);
Chris@0 326 $translation_override
Chris@0 327 ->clear($key)
Chris@0 328 ->save();
Chris@0 329 $this->configFactory->reset($config_name);
Chris@0 330
Chris@0 331 $this->assertNoConfigOverride($config_name, $key, $source_value, $langcode);
Chris@0 332 }
Chris@0 333
Chris@0 334 /**
Chris@0 335 * Deletes translation data from locale module.
Chris@0 336 *
Chris@0 337 * This will invoke LocaleConfigSubscriber through the event dispatcher. To
Chris@0 338 * make sure the configuration was persisted correctly, the configuration
Chris@0 339 * value is checked. Because LocaleConfigSubscriber temporarily disables the
Chris@0 340 * override state of the configuration factory we check that the correct value
Chris@0 341 * is restored afterwards.
Chris@0 342 *
Chris@0 343 * @param string $config_name
Chris@0 344 * The configuration name.
Chris@0 345 * @param string $key
Chris@0 346 * The configuration key.
Chris@0 347 * @param string $source_value
Chris@0 348 * The source configuration value to verify the correct value is returned
Chris@0 349 * from the configuration factory after the deletion.
Chris@0 350 * @param string $langcode
Chris@0 351 * The language code.
Chris@0 352 */
Chris@0 353 protected function deleteLocaleTranslationData($config_name, $key, $source_value, $langcode) {
Chris@0 354 $this->localeConfigManager
Chris@0 355 ->getStringTranslation($config_name, $langcode, $source_value, '')
Chris@0 356 ->delete();
Chris@0 357 $this->localeConfigManager->reset();
Chris@0 358 $this->localeConfigManager->updateConfigTranslations([$config_name], [$langcode]);
Chris@0 359 $this->configFactory->reset($config_name);
Chris@0 360
Chris@0 361 $this->assertNoConfigOverride($config_name, $key, $source_value, $langcode);
Chris@0 362 }
Chris@0 363
Chris@0 364 /**
Chris@0 365 * Ensures configuration override is not present anymore.
Chris@0 366 *
Chris@0 367 * @param string $config_name
Chris@0 368 * The configuration name.
Chris@0 369 * @param string $langcode
Chris@0 370 * The language code.
Chris@0 371 *
Chris@0 372 * @return bool
Chris@0 373 * TRUE if the assertion succeeded, FALSE otherwise.
Chris@0 374 */
Chris@0 375 protected function assertNoConfigOverride($config_name, $langcode) {
Chris@0 376 $config_langcode = $this->configFactory->getEditable($config_name)->get('langcode');
Chris@0 377 $override = $this->languageManager->getLanguageConfigOverride($langcode, $config_name);
Chris@0 378 return $this->assertNotEqual($config_langcode, $langcode) && $this->assertEqual($override->isNew(), TRUE);
Chris@0 379 }
Chris@0 380
Chris@0 381 /**
Chris@0 382 * Ensures configuration was saved correctly.
Chris@0 383 *
Chris@0 384 * @param string $config_name
Chris@0 385 * The configuration name.
Chris@0 386 * @param string $key
Chris@0 387 * The configuration key.
Chris@0 388 * @param string $value
Chris@0 389 * The configuration value.
Chris@0 390 * @param string $langcode
Chris@0 391 * The language code.
Chris@0 392 *
Chris@0 393 * @return bool
Chris@0 394 * TRUE if the assertion succeeded, FALSE otherwise.
Chris@0 395 */
Chris@0 396 protected function assertConfigOverride($config_name, $key, $value, $langcode) {
Chris@0 397 $config_langcode = $this->configFactory->getEditable($config_name)->get('langcode');
Chris@0 398 $override = $this->languageManager->getLanguageConfigOverride($langcode, $config_name);
Chris@0 399 return $this->assertNotEqual($config_langcode, $langcode) && $this->assertEqual($override->get($key), $value);
Chris@0 400 }
Chris@0 401
Chris@0 402 /**
Chris@0 403 * Ensures configuration was saved correctly.
Chris@0 404 *
Chris@0 405 * @param string $config_name
Chris@0 406 * The configuration name.
Chris@0 407 * @param string $key
Chris@0 408 * The configuration key.
Chris@0 409 * @param string $value
Chris@0 410 * The configuration value.
Chris@0 411 * @param string $langcode
Chris@0 412 * The language code.
Chris@0 413 *
Chris@0 414 * @return bool
Chris@0 415 * TRUE if the assertion succeeded, FALSE otherwise.
Chris@0 416 */
Chris@0 417 protected function assertActiveConfig($config_name, $key, $value, $langcode) {
Chris@0 418 $config = $this->configFactory->getEditable($config_name);
Chris@18 419 return $this->assertEqual($config->get('langcode'), $langcode) &&
Chris@0 420 $this->assertIdentical($config->get($key), $value);
Chris@0 421 }
Chris@0 422
Chris@0 423 /**
Chris@0 424 * Ensures no translation exists.
Chris@0 425 *
Chris@0 426 * @param string $config_name
Chris@0 427 * The configuration name.
Chris@0 428 * @param string $langcode
Chris@0 429 * The language code.
Chris@0 430 *
Chris@0 431 * @return bool
Chris@0 432 * TRUE if the assertion succeeded, FALSE otherwise.
Chris@0 433 */
Chris@0 434 protected function assertNoTranslation($config_name, $langcode) {
Chris@0 435 $strings = $this->stringStorage->getTranslations([
Chris@0 436 'type' => 'configuration',
Chris@0 437 'name' => $config_name,
Chris@0 438 'language' => $langcode,
Chris@0 439 'translated' => TRUE,
Chris@0 440 ]);
Chris@0 441 return $this->assertIdentical([], $strings);
Chris@0 442 }
Chris@0 443
Chris@0 444 /**
Chris@0 445 * Ensures a translation exists and is marked as customized.
Chris@0 446 *
Chris@0 447 * @param string $config_name
Chris@0 448 * The configuration name.
Chris@0 449 * @param string $translation
Chris@0 450 * The translation.
Chris@0 451 * @param string $langcode
Chris@0 452 * The language code.
Chris@0 453 * @param bool $customized
Chris@0 454 * Whether or not the string should be asserted to be customized or not
Chris@0 455 * customized.
Chris@0 456 *
Chris@0 457 * @return bool
Chris@0 458 * TRUE if the assertion succeeded, FALSE otherwise.
Chris@0 459 */
Chris@0 460 protected function assertTranslation($config_name, $translation, $langcode, $customized = TRUE) {
Chris@0 461 // Make sure a string exists.
Chris@0 462 $strings = $this->stringStorage->getTranslations([
Chris@0 463 'type' => 'configuration',
Chris@0 464 'name' => $config_name,
Chris@0 465 'language' => $langcode,
Chris@0 466 'translated' => TRUE,
Chris@0 467 ]);
Chris@0 468 $pass = $this->assertIdentical(1, count($strings));
Chris@0 469 $string = reset($strings);
Chris@0 470 if ($this->assertTrue($string instanceof StringInterface)) {
Chris@0 471 /** @var \Drupal\locale\StringInterface $string */
Chris@0 472 $pass = $pass && $this->assertIdentical($translation, $string->getString());
Chris@0 473 $pass = $pass && $this->assertTrue($string->isTranslation());
Chris@0 474 if ($this->assertTrue($string instanceof TranslationString)) {
Chris@0 475 /** @var \Drupal\locale\TranslationString $string */
Chris@0 476 // Make sure the string is marked as customized so that it does not get
Chris@0 477 // overridden when the string translations are updated.
Chris@0 478 return $pass && $this->assertEqual($customized, $string->customized);
Chris@0 479 }
Chris@0 480 }
Chris@0 481 return FALSE;
Chris@0 482 }
Chris@0 483
Chris@0 484 }