Chris@0: storage = $this->container->get('locale.storage'); Chris@0: // Create two languages: Spanish and German. Chris@0: foreach (['es', 'de'] as $langcode) { Chris@0: ConfigurableLanguage::createFromLangcode($langcode)->save(); Chris@0: } Chris@0: } Chris@0: Chris@0: /** Chris@0: * Test CRUD API. Chris@0: */ Chris@0: public function testStringCRUDAPI() { Chris@0: // Create source string. Chris@0: $source = $this->buildSourceString(); Chris@0: $source->save(); Chris@0: $this->assertTrue($source->lid, format_string('Successfully created string %string', ['%string' => $source->source])); Chris@0: Chris@0: // Load strings by lid and source. Chris@0: $string1 = $this->storage->findString(['lid' => $source->lid]); Chris@0: $this->assertEqual($source, $string1, 'Successfully retrieved string by identifier.'); Chris@0: $string2 = $this->storage->findString(['source' => $source->source, 'context' => $source->context]); Chris@0: $this->assertEqual($source, $string2, 'Successfully retrieved string by source and context.'); Chris@0: $string3 = $this->storage->findString(['source' => $source->source, 'context' => '']); Chris@0: $this->assertFalse($string3, 'Cannot retrieve string with wrong context.'); Chris@0: Chris@0: // Check version handling and updating. Chris@0: $this->assertEqual($source->version, 'none', 'String originally created without version.'); Chris@0: $string = $this->storage->findTranslation(['lid' => $source->lid]); Chris@0: $this->assertEqual($string->version, \Drupal::VERSION, 'Checked and updated string version to Drupal version.'); Chris@0: Chris@0: // Create translation and find it by lid and source. Chris@0: $langcode = 'es'; Chris@0: $translation = $this->createTranslation($source, $langcode); Chris@0: $this->assertEqual($translation->customized, LOCALE_NOT_CUSTOMIZED, 'Translation created as not customized by default.'); Chris@0: $string1 = $this->storage->findTranslation(['language' => $langcode, 'lid' => $source->lid]); Chris@0: $this->assertEqual($string1->translation, $translation->translation, 'Successfully loaded translation by string identifier.'); Chris@0: $string2 = $this->storage->findTranslation(['language' => $langcode, 'source' => $source->source, 'context' => $source->context]); Chris@0: $this->assertEqual($string2->translation, $translation->translation, 'Successfully loaded translation by source and context.'); Chris@0: $translation Chris@0: ->setCustomized() Chris@0: ->save(); Chris@0: $translation = $this->storage->findTranslation(['language' => $langcode, 'lid' => $source->lid]); Chris@0: $this->assertEqual($translation->customized, LOCALE_CUSTOMIZED, 'Translation successfully marked as customized.'); Chris@0: Chris@0: // Delete translation. Chris@0: $translation->delete(); Chris@0: $deleted = $this->storage->findTranslation(['language' => $langcode, 'lid' => $source->lid]); Chris@0: $this->assertFalse(isset($deleted->translation), 'Successfully deleted translation string.'); Chris@0: Chris@0: // Create some translations and then delete string and all of its Chris@0: // translations. Chris@0: $lid = $source->lid; Chris@0: $this->createAllTranslations($source); Chris@0: $search = $this->storage->getTranslations(['lid' => $source->lid]); Chris@0: $this->assertEqual(count($search), 3, 'Created and retrieved all translations for our source string.'); Chris@0: Chris@0: $source->delete(); Chris@0: $string = $this->storage->findString(['lid' => $lid]); Chris@0: $this->assertFalse($string, 'Successfully deleted source string.'); Chris@0: $deleted = $search = $this->storage->getTranslations(['lid' => $lid]); Chris@0: $this->assertFalse($deleted, 'Successfully deleted all translation strings.'); Chris@0: Chris@0: // Tests that locations of different types and arbitrary lengths can be Chris@0: // added to a source string. Too long locations will be cut off. Chris@0: $source_string = $this->buildSourceString(); Chris@0: $source_string->addLocation('javascript', $this->randomString(8)); Chris@0: $source_string->addLocation('configuration', $this->randomString(50)); Chris@0: $source_string->addLocation('code', $this->randomString(100)); Chris@0: $source_string->addLocation('path', $location = $this->randomString(300)); Chris@0: $source_string->save(); Chris@0: Chris@0: $rows = db_query('SELECT * FROM {locales_location} WHERE sid = :sid', [':sid' => $source_string->lid])->fetchAllAssoc('type'); Chris@0: $this->assertEqual(count($rows), 4, '4 source locations have been persisted.'); Chris@0: $this->assertEqual($rows['path']->name, substr($location, 0, 255), 'Too long location has been limited to 255 characters.'); Chris@0: } Chris@0: Chris@0: /** Chris@0: * Test Search API loading multiple objects. Chris@0: */ Chris@0: public function testStringSearchAPI() { Chris@0: $language_count = 3; Chris@0: // Strings 1 and 2 will have some common prefix. Chris@0: // Source 1 will have all translations, not customized. Chris@0: // Source 2 will have all translations, customized. Chris@0: // Source 3 will have no translations. Chris@0: $prefix = $this->randomMachineName(100); Chris@0: $source1 = $this->buildSourceString(['source' => $prefix . $this->randomMachineName(100)])->save(); Chris@0: $source2 = $this->buildSourceString(['source' => $prefix . $this->randomMachineName(100)])->save(); Chris@0: $source3 = $this->buildSourceString()->save(); Chris@0: // Load all source strings. Chris@0: $strings = $this->storage->getStrings([]); Chris@0: $this->assertEqual(count($strings), 3, 'Found 3 source strings in the database.'); Chris@0: // Load all source strings matching a given string. Chris@0: $filter_options['filters'] = ['source' => $prefix]; Chris@0: $strings = $this->storage->getStrings([], $filter_options); Chris@0: $this->assertEqual(count($strings), 2, 'Found 2 strings using some string filter.'); Chris@0: Chris@0: // Not customized translations. Chris@0: $translate1 = $this->createAllTranslations($source1); Chris@0: // Customized translations. Chris@0: $this->createAllTranslations($source2, ['customized' => LOCALE_CUSTOMIZED]); Chris@0: // Try quick search function with different field combinations. Chris@0: $langcode = 'es'; Chris@0: $found = $this->storage->findTranslation(['language' => $langcode, 'source' => $source1->source, 'context' => $source1->context]); Chris@0: $this->assertTrue($found && isset($found->language) && isset($found->translation) && !$found->isNew(), 'Translation found searching by source and context.'); Chris@0: $this->assertEqual($found->translation, $translate1[$langcode]->translation, 'Found the right translation.'); Chris@0: // Now try a translation not found. Chris@0: $found = $this->storage->findTranslation(['language' => $langcode, 'source' => $source3->source, 'context' => $source3->context]); Chris@0: $this->assertTrue($found && $found->lid == $source3->lid && !isset($found->translation) && $found->isNew(), 'Translation not found but source string found.'); Chris@0: Chris@0: // Load all translations. For next queries we'll be loading only translated Chris@0: // strings. Chris@0: $translations = $this->storage->getTranslations(['translated' => TRUE]); Chris@0: $this->assertEqual(count($translations), 2 * $language_count, 'Created and retrieved all translations for source strings.'); Chris@0: Chris@0: // Load all customized translations. Chris@0: $translations = $this->storage->getTranslations(['customized' => LOCALE_CUSTOMIZED, 'translated' => TRUE]); Chris@0: $this->assertEqual(count($translations), $language_count, 'Retrieved all customized translations for source strings.'); Chris@0: Chris@0: // Load all Spanish customized translations. Chris@0: $translations = $this->storage->getTranslations(['language' => 'es', 'customized' => LOCALE_CUSTOMIZED, 'translated' => TRUE]); Chris@0: $this->assertEqual(count($translations), 1, 'Found only Spanish and customized translations.'); Chris@0: Chris@0: // Load all source strings without translation (1). Chris@0: $translations = $this->storage->getStrings(['translated' => FALSE]); Chris@0: $this->assertEqual(count($translations), 1, 'Found 1 source string without translations.'); Chris@0: Chris@0: // Load Spanish translations using string filter. Chris@0: $filter_options['filters'] = ['source' => $prefix]; Chris@0: $translations = $this->storage->getTranslations(['language' => 'es'], $filter_options); Chris@0: $this->assertEqual(count($translations), 2, 'Found 2 translations using some string filter.'); Chris@0: Chris@0: } Chris@0: Chris@0: /** Chris@0: * Creates random source string object. Chris@0: * Chris@0: * @return \Drupal\locale\StringInterface Chris@0: * A locale string. Chris@0: */ Chris@0: public function buildSourceString($values = []) { Chris@0: return $this->storage->createString($values += [ Chris@0: 'source' => $this->randomMachineName(100), Chris@0: 'context' => $this->randomMachineName(20), Chris@0: ]); Chris@0: } Chris@0: Chris@0: /** Chris@0: * Creates translations for source string and all languages. Chris@0: */ Chris@0: public function createAllTranslations($source, $values = []) { Chris@0: $list = []; Chris@0: /* @var $language_manager \Drupal\Core\Language\LanguageManagerInterface */ Chris@0: $language_manager = $this->container->get('language_manager'); Chris@0: foreach ($language_manager->getLanguages() as $language) { Chris@0: $list[$language->getId()] = $this->createTranslation($source, $language->getId(), $values); Chris@0: } Chris@0: return $list; Chris@0: } Chris@0: Chris@0: /** Chris@0: * Creates single translation for source string. Chris@0: */ Chris@0: public function createTranslation($source, $langcode, $values = []) { Chris@0: return $this->storage->createTranslation($values + [ Chris@0: 'lid' => $source->lid, Chris@0: 'language' => $langcode, Chris@0: 'translation' => $this->randomMachineName(100), Chris@0: ])->save(); Chris@0: } Chris@0: Chris@0: }