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