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 }
|