annotate core/modules/locale/tests/src/Functional/LocaleStringTest.php @ 17:129ea1e6d783

Update, including to Drupal core 8.6.10
author Chris Cannam
date Thu, 28 Feb 2019 13:21:36 +0000
parents 4c8ae668cc8c
children
rev   line source
Chris@0 1 <?php
Chris@0 2
Chris@0 3 namespace Drupal\Tests\locale\Functional;
Chris@0 4
Chris@0 5 use Drupal\language\Entity\ConfigurableLanguage;
Chris@0 6 use Drupal\Tests\BrowserTestBase;
Chris@0 7
Chris@0 8 /**
Chris@0 9 * Tests the locale string storage, string objects and data API.
Chris@0 10 *
Chris@0 11 * @group locale
Chris@0 12 */
Chris@0 13 class LocaleStringTest extends BrowserTestBase {
Chris@0 14
Chris@0 15 /**
Chris@0 16 * Modules to enable.
Chris@0 17 *
Chris@0 18 * @var array
Chris@0 19 */
Chris@0 20 public static $modules = ['locale'];
Chris@0 21
Chris@0 22 /**
Chris@0 23 * The locale storage.
Chris@0 24 *
Chris@0 25 * @var \Drupal\locale\StringStorageInterface
Chris@0 26 */
Chris@0 27 protected $storage;
Chris@0 28
Chris@0 29 /**
Chris@0 30 * {@inheritdoc}
Chris@0 31 */
Chris@0 32 protected function setUp() {
Chris@0 33 parent::setUp();
Chris@0 34 // Add a default locale storage for all these tests.
Chris@0 35 $this->storage = $this->container->get('locale.storage');
Chris@0 36 // Create two languages: Spanish and German.
Chris@0 37 foreach (['es', 'de'] as $langcode) {
Chris@0 38 ConfigurableLanguage::createFromLangcode($langcode)->save();
Chris@0 39 }
Chris@0 40 }
Chris@0 41
Chris@0 42 /**
Chris@0 43 * Test CRUD API.
Chris@0 44 */
Chris@0 45 public function testStringCRUDAPI() {
Chris@0 46 // Create source string.
Chris@0 47 $source = $this->buildSourceString();
Chris@0 48 $source->save();
Chris@0 49 $this->assertTrue($source->lid, format_string('Successfully created string %string', ['%string' => $source->source]));
Chris@0 50
Chris@0 51 // Load strings by lid and source.
Chris@0 52 $string1 = $this->storage->findString(['lid' => $source->lid]);
Chris@0 53 $this->assertEqual($source, $string1, 'Successfully retrieved string by identifier.');
Chris@0 54 $string2 = $this->storage->findString(['source' => $source->source, 'context' => $source->context]);
Chris@0 55 $this->assertEqual($source, $string2, 'Successfully retrieved string by source and context.');
Chris@0 56 $string3 = $this->storage->findString(['source' => $source->source, 'context' => '']);
Chris@0 57 $this->assertFalse($string3, 'Cannot retrieve string with wrong context.');
Chris@0 58
Chris@0 59 // Check version handling and updating.
Chris@0 60 $this->assertEqual($source->version, 'none', 'String originally created without version.');
Chris@0 61 $string = $this->storage->findTranslation(['lid' => $source->lid]);
Chris@0 62 $this->assertEqual($string->version, \Drupal::VERSION, 'Checked and updated string version to Drupal version.');
Chris@0 63
Chris@0 64 // Create translation and find it by lid and source.
Chris@0 65 $langcode = 'es';
Chris@0 66 $translation = $this->createTranslation($source, $langcode);
Chris@0 67 $this->assertEqual($translation->customized, LOCALE_NOT_CUSTOMIZED, 'Translation created as not customized by default.');
Chris@0 68 $string1 = $this->storage->findTranslation(['language' => $langcode, 'lid' => $source->lid]);
Chris@0 69 $this->assertEqual($string1->translation, $translation->translation, 'Successfully loaded translation by string identifier.');
Chris@0 70 $string2 = $this->storage->findTranslation(['language' => $langcode, 'source' => $source->source, 'context' => $source->context]);
Chris@0 71 $this->assertEqual($string2->translation, $translation->translation, 'Successfully loaded translation by source and context.');
Chris@0 72 $translation
Chris@0 73 ->setCustomized()
Chris@0 74 ->save();
Chris@0 75 $translation = $this->storage->findTranslation(['language' => $langcode, 'lid' => $source->lid]);
Chris@0 76 $this->assertEqual($translation->customized, LOCALE_CUSTOMIZED, 'Translation successfully marked as customized.');
Chris@0 77
Chris@0 78 // Delete translation.
Chris@0 79 $translation->delete();
Chris@0 80 $deleted = $this->storage->findTranslation(['language' => $langcode, 'lid' => $source->lid]);
Chris@0 81 $this->assertFalse(isset($deleted->translation), 'Successfully deleted translation string.');
Chris@0 82
Chris@0 83 // Create some translations and then delete string and all of its
Chris@0 84 // translations.
Chris@0 85 $lid = $source->lid;
Chris@0 86 $this->createAllTranslations($source);
Chris@0 87 $search = $this->storage->getTranslations(['lid' => $source->lid]);
Chris@0 88 $this->assertEqual(count($search), 3, 'Created and retrieved all translations for our source string.');
Chris@0 89
Chris@0 90 $source->delete();
Chris@0 91 $string = $this->storage->findString(['lid' => $lid]);
Chris@0 92 $this->assertFalse($string, 'Successfully deleted source string.');
Chris@0 93 $deleted = $search = $this->storage->getTranslations(['lid' => $lid]);
Chris@0 94 $this->assertFalse($deleted, 'Successfully deleted all translation strings.');
Chris@0 95
Chris@0 96 // Tests that locations of different types and arbitrary lengths can be
Chris@0 97 // added to a source string. Too long locations will be cut off.
Chris@0 98 $source_string = $this->buildSourceString();
Chris@0 99 $source_string->addLocation('javascript', $this->randomString(8));
Chris@0 100 $source_string->addLocation('configuration', $this->randomString(50));
Chris@0 101 $source_string->addLocation('code', $this->randomString(100));
Chris@0 102 $source_string->addLocation('path', $location = $this->randomString(300));
Chris@0 103 $source_string->save();
Chris@0 104
Chris@0 105 $rows = db_query('SELECT * FROM {locales_location} WHERE sid = :sid', [':sid' => $source_string->lid])->fetchAllAssoc('type');
Chris@0 106 $this->assertEqual(count($rows), 4, '4 source locations have been persisted.');
Chris@0 107 $this->assertEqual($rows['path']->name, substr($location, 0, 255), 'Too long location has been limited to 255 characters.');
Chris@0 108 }
Chris@0 109
Chris@0 110 /**
Chris@0 111 * Test Search API loading multiple objects.
Chris@0 112 */
Chris@0 113 public function testStringSearchAPI() {
Chris@0 114 $language_count = 3;
Chris@0 115 // Strings 1 and 2 will have some common prefix.
Chris@0 116 // Source 1 will have all translations, not customized.
Chris@0 117 // Source 2 will have all translations, customized.
Chris@0 118 // Source 3 will have no translations.
Chris@0 119 $prefix = $this->randomMachineName(100);
Chris@0 120 $source1 = $this->buildSourceString(['source' => $prefix . $this->randomMachineName(100)])->save();
Chris@0 121 $source2 = $this->buildSourceString(['source' => $prefix . $this->randomMachineName(100)])->save();
Chris@0 122 $source3 = $this->buildSourceString()->save();
Chris@0 123 // Load all source strings.
Chris@0 124 $strings = $this->storage->getStrings([]);
Chris@0 125 $this->assertEqual(count($strings), 3, 'Found 3 source strings in the database.');
Chris@0 126 // Load all source strings matching a given string.
Chris@0 127 $filter_options['filters'] = ['source' => $prefix];
Chris@0 128 $strings = $this->storage->getStrings([], $filter_options);
Chris@0 129 $this->assertEqual(count($strings), 2, 'Found 2 strings using some string filter.');
Chris@0 130
Chris@0 131 // Not customized translations.
Chris@0 132 $translate1 = $this->createAllTranslations($source1);
Chris@0 133 // Customized translations.
Chris@0 134 $this->createAllTranslations($source2, ['customized' => LOCALE_CUSTOMIZED]);
Chris@0 135 // Try quick search function with different field combinations.
Chris@0 136 $langcode = 'es';
Chris@0 137 $found = $this->storage->findTranslation(['language' => $langcode, 'source' => $source1->source, 'context' => $source1->context]);
Chris@0 138 $this->assertTrue($found && isset($found->language) && isset($found->translation) && !$found->isNew(), 'Translation found searching by source and context.');
Chris@0 139 $this->assertEqual($found->translation, $translate1[$langcode]->translation, 'Found the right translation.');
Chris@0 140 // Now try a translation not found.
Chris@0 141 $found = $this->storage->findTranslation(['language' => $langcode, 'source' => $source3->source, 'context' => $source3->context]);
Chris@0 142 $this->assertTrue($found && $found->lid == $source3->lid && !isset($found->translation) && $found->isNew(), 'Translation not found but source string found.');
Chris@0 143
Chris@0 144 // Load all translations. For next queries we'll be loading only translated
Chris@0 145 // strings.
Chris@0 146 $translations = $this->storage->getTranslations(['translated' => TRUE]);
Chris@0 147 $this->assertEqual(count($translations), 2 * $language_count, 'Created and retrieved all translations for source strings.');
Chris@0 148
Chris@0 149 // Load all customized translations.
Chris@0 150 $translations = $this->storage->getTranslations(['customized' => LOCALE_CUSTOMIZED, 'translated' => TRUE]);
Chris@0 151 $this->assertEqual(count($translations), $language_count, 'Retrieved all customized translations for source strings.');
Chris@0 152
Chris@0 153 // Load all Spanish customized translations.
Chris@0 154 $translations = $this->storage->getTranslations(['language' => 'es', 'customized' => LOCALE_CUSTOMIZED, 'translated' => TRUE]);
Chris@0 155 $this->assertEqual(count($translations), 1, 'Found only Spanish and customized translations.');
Chris@0 156
Chris@0 157 // Load all source strings without translation (1).
Chris@0 158 $translations = $this->storage->getStrings(['translated' => FALSE]);
Chris@0 159 $this->assertEqual(count($translations), 1, 'Found 1 source string without translations.');
Chris@0 160
Chris@0 161 // Load Spanish translations using string filter.
Chris@0 162 $filter_options['filters'] = ['source' => $prefix];
Chris@0 163 $translations = $this->storage->getTranslations(['language' => 'es'], $filter_options);
Chris@0 164 $this->assertEqual(count($translations), 2, 'Found 2 translations using some string filter.');
Chris@0 165
Chris@0 166 }
Chris@0 167
Chris@0 168 /**
Chris@0 169 * Creates random source string object.
Chris@0 170 *
Chris@0 171 * @return \Drupal\locale\StringInterface
Chris@0 172 * A locale string.
Chris@0 173 */
Chris@0 174 public function buildSourceString($values = []) {
Chris@0 175 return $this->storage->createString($values += [
Chris@0 176 'source' => $this->randomMachineName(100),
Chris@0 177 'context' => $this->randomMachineName(20),
Chris@0 178 ]);
Chris@0 179 }
Chris@0 180
Chris@0 181 /**
Chris@0 182 * Creates translations for source string and all languages.
Chris@0 183 */
Chris@0 184 public function createAllTranslations($source, $values = []) {
Chris@0 185 $list = [];
Chris@0 186 /* @var $language_manager \Drupal\Core\Language\LanguageManagerInterface */
Chris@0 187 $language_manager = $this->container->get('language_manager');
Chris@0 188 foreach ($language_manager->getLanguages() as $language) {
Chris@0 189 $list[$language->getId()] = $this->createTranslation($source, $language->getId(), $values);
Chris@0 190 }
Chris@0 191 return $list;
Chris@0 192 }
Chris@0 193
Chris@0 194 /**
Chris@0 195 * Creates single translation for source string.
Chris@0 196 */
Chris@0 197 public function createTranslation($source, $langcode, $values = []) {
Chris@0 198 return $this->storage->createTranslation($values + [
Chris@0 199 'lid' => $source->lid,
Chris@0 200 'language' => $langcode,
Chris@0 201 'translation' => $this->randomMachineName(100),
Chris@0 202 ])->save();
Chris@0 203 }
Chris@0 204
Chris@0 205 }