commit fd6c58d717274ed59a69a1fca8ad4a9961c5c551 Author: Erik Stielstra Date: Tue Dec 4 18:03:10 2012 +0100 Ready for patch diff --git a/core/modules/locale/lib/Drupal/locale/Tests/LocaleUpdateInterfaceTest.php b/core/modules/locale/lib/Drupal/locale/Tests/LocaleUpdateInterfaceTest.php new file mode 100644 index 0000000..c30c707 --- /dev/null +++ b/core/modules/locale/lib/Drupal/locale/Tests/LocaleUpdateInterfaceTest.php @@ -0,0 +1,107 @@ + 'Update translations user interface', + 'description' => 'Tests for the user interface of project interface translations.', + 'group' => 'Locale', + ); + } + + /** + * Setup the test environment. + * + * We use German as default test language. Due to hardcoded configurations in + * the locale_test module, the language can not be chosen randomly. + */ + function setUp() { + parent::setUp(); + $admin_user = $this->drupalCreateUser(array('administer modules', 'administer site configuration', 'administer languages', 'access administration pages', 'translate interface')); + $this->drupalLogin($admin_user); + } + + /** + * Tests the user interfaces of the interface translation update system. + * + * Testing the Available updates summary on the side wide status page and the + * Avaiable translation updates page. + */ + function testInterface() { + // No language added. + // Check status page and Available translation updates page. + $this->drupalGet('admin/reports/status'); + $this->assertNoText(t('Translation update status'), 'No status message'); + + $this->drupalGet('admin/reports/translations'); + $this->assertRaw(t('No translatable languages available. Add a language first.', array('@add_language' => url('admin/config/regional/language'))), 'Language message'); + + // Add German language + $edit = array( + 'predefined_langcode' => 'de', + ); + $this->drupalPost('admin/config/regional/language/add', $edit, t('Add language')); + + // Drupal core is probably in 8.x, but tests may also be executed with + // stable releases. Therefore we will just ignore it here to make sure we + // have a controlled environment. + $status = state()->get('locale.translation_status'); + unset($status['drupal']); + state()->set('locale.translation_status', $status); + + // One language added, all translations up to date. + $this->drupalGet('admin/reports/status'); + $this->assertText(t('Translation update status'), 'Status message'); + $this->assertText(t('Up to date'), 'Translations up to date'); + $this->drupalGet('admin/reports/translations'); + $this->assertText(t('All translations up to date.'), 'Translations up to date'); + + // Set locale_test_translate module to have a local translation available. + $status = state()->get('locale.translation_status'); + $status['locale_test_translate']['de']->type = 'local'; + state()->set('locale.translation_status', $status); + + // Check if updates are available for German. + $this->drupalGet('admin/reports/status'); + $this->assertText(t('Translation update status'), 'Status message'); + $this->assertRaw(t('Updates available for: @languages. See the Available translation updates page for more information.', array('@languages' => t('German'), '@updates' => url('admin/reports/translations'))), 'Updates available message'); + $this->drupalGet('admin/reports/translations'); + $this->assertText(t('Updates for: @modules', array('@modules' => 'Locale test translate')), 'Translations avaiable'); + + // Set locale_test_translate module to have a dev release and no + // translation found. + $status = state()->get('locale.translation_status'); + $status['locale_test_translate']['de']->version = '1.3-dev'; + unset($status['locale_test_translate']['de']->type); + state()->set('locale.translation_status', $status); + + // Check if no updates were found. + $this->drupalGet('admin/reports/status'); + $this->assertText(t('Translation update status'), 'Status message'); + $this->assertRaw(t('Updates not found for: @languages. See the Available translation updates page for more information.', array('@languages' => t('German'), '@updates' => url('admin/reports/translations'))), 'Updates not found message'); + $this->drupalGet('admin/reports/translations'); + $this->assertText(t('No updates found for 1 project'), 'No updates found'); + $this->assertText(t('@module (@version).', array('@module' => 'Locale test translate', '@version' => '1.3-dev')), 'Release details'); + $this->assertText(t('No translation files are provided for development releases.'), 'Release info'); + } +} \ No newline at end of file diff --git a/core/modules/locale/lib/Drupal/locale/Tests/LocaleUpdateTest.php b/core/modules/locale/lib/Drupal/locale/Tests/LocaleUpdateTest.php index 6f96943..9896aa7 100644 --- a/core/modules/locale/lib/Drupal/locale/Tests/LocaleUpdateTest.php +++ b/core/modules/locale/lib/Drupal/locale/Tests/LocaleUpdateTest.php @@ -2,7 +2,7 @@ /** * @file - * Definition of Drupal\locale\Tests\LocaleCompareTest. + * Definition of Drupal\locale\Tests\LocaleUpdateTest. */ namespace Drupal\locale\Tests; @@ -51,7 +51,7 @@ class LocaleUpdateTest extends WebTestBase { public static function getInfo() { return array( - 'name' => 'Update Interface translations', + 'name' => 'Update translations', 'description' => 'Tests for updating the interface translations of projects.', 'group' => 'Locale', ); @@ -429,9 +429,18 @@ function testUpdateImportSourceRemote() { ); $this->drupalPost('admin/config/regional/translate/settings', $edit, t('Save configuration')); - // Execute the translation update. + // Get the translation status. $this->drupalGet('admin/reports/translations/check'); - $this->drupalPost('admin/reports/translations', array(), t('Update')); + + // Check the status on the Available translation status page. + $this->assertRaw('', 'German language found'); + $this->assertText('Updates for: Contributed module one, Contributed module two, Custom module one, Locale test', 'Updates found'); + $this->assertText('Updates for: Contributed module one, Contributed module two, Custom module one, Locale test', 'Updates found'); + $this->assertText('Contributed module one (' . format_date($this->timestamp_now, 'html_date') . ')', 'Updates for Contrib module one'); + $this->assertText('Contributed module two (' . format_date($this->timestamp_new, 'html_date') . ')', 'Updates for Contrib module two'); + + // Execute the translation update. + $this->drupalPost('admin/reports/translations', array(), t('Update translations')); // Check if the translation has been updated, using the status cache. $status = state()->get('locale.translation_status'); @@ -486,7 +495,7 @@ function testUpdateImportSourceLocal() { // Execute the translation update. $this->drupalGet('admin/reports/translations/check'); - $this->drupalPost('admin/reports/translations', array(), t('Update')); + $this->drupalPost('admin/reports/translations', array(), t('Update translations')); // Check if the translation has been updated, using the status cache. $status = state()->get('locale.translation_status'); @@ -542,7 +551,7 @@ function testUpdateImportWithoutDirectory() { // Execute the translation update. $this->drupalGet('admin/reports/translations/check'); - $this->drupalPost('admin/reports/translations', array(), t('Update')); + $this->drupalPost('admin/reports/translations', array(), t('Update translations')); // Check if the translation has been updated, using the status cache. $status = state()->get('locale.translation_status'); @@ -597,7 +606,7 @@ function testUpdateImportModeNonCustomized() { // Execute translation update. $this->drupalGet('admin/reports/translations/check'); - $this->drupalPost('admin/reports/translations', array(), t('Update')); + $this->drupalPost('admin/reports/translations', array(), t('Update translations')); // Check whether existing translations have (not) been overwritten. $this->assertEqual(t('January', array(), array('langcode' => 'de')), 'Januar_customized', 'Translation of January'); @@ -635,7 +644,7 @@ function testUpdateImportModeNone() { // Execute translation update. $this->drupalGet('admin/reports/translations/check'); - $this->drupalPost('admin/reports/translations', array(), t('Update')); + $this->drupalPost('admin/reports/translations', array(), t('Update translations')); // Check whether existing translations have (not) been overwritten. $this->assertTranslation('January', 'Januar_customized', 'de'); diff --git a/core/modules/locale/locale.admin.css b/core/modules/locale/locale.admin.css index 74ee14d..3a632b0 100644 --- a/core/modules/locale/locale.admin.css +++ b/core/modules/locale/locale.admin.css @@ -51,7 +51,7 @@ /** * Available translation updates page. */ -#system-modules table { +#locale-translation-status table { table-layout: fixed; } #locale-translation-status th.select-all { @@ -73,6 +73,7 @@ #locale-translation-status .expanded .expand .inner { background: transparent url(../../misc/menu-expanded.png) left .6em no-repeat; } + #locale-translation-status label { color: #1d1d1d; font-size: 1.15em; @@ -83,10 +84,20 @@ #locale-translation-status .description .inner { color: #5c5c5b; line-height: 20px; - overflow: hidden; /* truncates descriptions if too long */ + overflow: hidden; text-overflow: ellipsis; white-space: nowrap; } +#locale-translation-status .expanded .description .inner { + height: auto; + overflow: visible; + white-space: normal; +} +#locale-translation-status .expanded .description .text { + -webkit-hyphens: auto; + -moz-hyphens: auto; + hyphens: auto; +} .js #locale-translation-status .description .inner { height: 20px; } @@ -95,6 +106,13 @@ overflow: visible; white-space: normal; } +#locale-translation-status .details { + padding: 5px 0; + max-width: 490px; + white-space: normal; + font-size: 0.9em; + color: #666; +} @media screen and (max-width: 40em) { #locale-translation-status th.title { width: 20%; diff --git a/core/modules/locale/locale.pages.inc b/core/modules/locale/locale.pages.inc index 3004458..86e333b 100644 --- a/core/modules/locale/locale.pages.inc +++ b/core/modules/locale/locale.pages.inc @@ -619,17 +619,17 @@ function locale_translation_status($form, &$form_state) { $updates[$langcode]['not_found'][] = array( 'name' => $project_data[$project_info->name]->info['name'], 'version' => $project_info->version, - 'info' => _locale_translation_status_debug_info($project_info->version, $project_info->files['remote']->uri, $project_info->files['local']->uri), + 'info' => _locale_translation_status_debug_info($project_info), ); $languages_not_found[$langcode] = $langcode; } // Translation update found for this project-language combination. elseif ($project_info->type == LOCALE_TRANSLATION_LOCAL || $project_info->type == LOCALE_TRANSLATION_REMOTE ) { - $local = $project_info->files[LOCALE_TRANSLATION_LOCAL]; - $remote = $project_info->files[LOCALE_TRANSLATION_REMOTE]; - $recent = _locale_translation_source_compare($local, $remote) == LOCALE_TRANSLATION_SOURCE_COMPARE_LT ? $remote : $local ; + $local = isset($project_info->files[LOCALE_TRANSLATION_LOCAL]) ? $project_info->files[LOCALE_TRANSLATION_LOCAL] : NULL; + $remote = isset($project_info->files[LOCALE_TRANSLATION_REMOTE]) ? $project_info->files[LOCALE_TRANSLATION_REMOTE] : NULL; + $recent = _locale_translation_source_compare($local, $remote) == LOCALE_TRANSLATION_SOURCE_COMPARE_LT ? $remote : $local; $updates[$langcode]['updates'][] = array( - 'name' => $project_info->name, + 'name' => $project_data[$project_info->name]->info['name'], 'version' => $project_info->version, 'timestamp' => $recent->timestamp, ); @@ -643,7 +643,7 @@ function locale_translation_status($form, &$form_state) { foreach($updates as $langcode => $update) { $options[$langcode] = array( 'title' => check_plain($languages[$langcode]->name), - 'status' => array('class' => array('description', 'expand'), 'data' => theme('locale_translation_update_info', $update)), + 'status' => array('class' => array('description', 'expand', 'priority-low'), 'data' => theme('locale_translation_update_info', $update)), ); } // Sort the table data on language name. @@ -662,14 +662,17 @@ function locale_translation_status($form, &$form_state) { ), 'status' => array( 'data' => t('Status'), - 'class' => array('status'), + 'class' => array('status', 'priority-low'), ), ); if (!$languages) { $empty = t('No translatable languages available. Add a language first.', array('@add_language' => url('admin/config/regional/language'))); } - else { + elseif ($status) { + $empty = t('All translations up to date.'); + } + else { $empty = t('No translation status available. Check manually.', array('@check' => url('admin/reports/translations/check'))); } @@ -739,10 +742,18 @@ function locale_translation_status_submit($form, &$form_state) { /** * Form element callback: After build changes to the language update table. * - * Removes checkboxes from languages which have no updates ane one or more - * translation files could not be found. + * Adds labels to the languages and removes checkboxes from languages which have + * no updates ane one or more translation files could not be found. */ function locale_translation_language_table($form_element) { + // Add labels to Language names. + foreach ($form_element['#options'] as $langcode => $option) { + $id = $form_element[$langcode]['#id']; + $title = $option['title']; + $form_element['#options'][$langcode]['title'] = ''; + } + + // Remove checkboxes of languages without updates. if ($form_element['#not_found']) { foreach ($form_element['#not_found'] as $langcode) { $form_element[$langcode] = array(); @@ -769,20 +780,23 @@ function locale_translation_language_table($form_element) { * @param string $local_path * Local path where the translation file was tried to load from. */ -function _locale_translation_status_debug_info($version, $remote_path, $local_path) { - if (strpos($version, 'dev') !== FALSE) { +function _locale_translation_status_debug_info($source) { + $remote_path = isset($source->files['remote']->uri) ? $source->files['remote']->uri : ''; + $local_path = isset($source->files['local']->uri) ? $source->files['local']->uri : ''; + + if (strpos($source->version, 'dev') !== FALSE) { return t('No translation files are provided for development releases.'); } - $config = config('locale.settings'); - if ($config->get('translation.use_source') == LOCALE_TRANSLATION_USE_SOURCE_REMOTE_AND_LOCAL) { + if (locale_translation_use_remote_source() && $remote_path && $local_path) { return t('File not found at %remote_path nor at %local_path', array( '%remote_path' => $remote_path, '%local_path' => $local_path, )); } - elseif ($config->get('translation.use_source') == LOCALE_TRANSLATION_USE_SOURCE_LOCAL) { + elseif ($local_path) { return t('File not found at %local_path', array('%local_path' => $local_path)); } + return t('Translation file location could not be determined.'); } /** @@ -841,14 +855,14 @@ function theme_locale_translation_update_info($variables) { $releases[] = t('@module (@date)', array('@module' => $update['name'], '@date' => format_date($update['timestamp'], 'html_date'))); } } - $description = t('Updates for: @modules', array('@modules' => implode(', ', $modules))); + $description = '' . t('Updates for: @modules', array('@modules' => implode(', ', $modules))) . ''; $details = theme('item_list', array('items' => $releases)); } // Build output for updates not found. if (isset($variables['not_found'])) { if (empty($description)) { - $description = format_plural(count($variables['not_found']), 'No updates found for 1 project', 'No updates found for @count projects'); + $description = '' . format_plural(count($variables['not_found']), 'No updates found for 1 project', 'No updates found for @count projects') . ''; } if ($variables['not_found']) { $releases = array(); diff --git a/core/modules/locale/tests/modules/locale_test_translate/locale_test_translate.module b/core/modules/locale/tests/modules/locale_test_translate/locale_test_translate.module index f4f1972..98eb358 100644 --- a/core/modules/locale/tests/modules/locale_test_translate/locale_test_translate.module +++ b/core/modules/locale/tests/modules/locale_test_translate/locale_test_translate.module @@ -4,3 +4,17 @@ * @file * Simulates a custom module with a local po file. */ + +/** + * Implements hook_system_info_alter(). + * + * By default this modules is hidden but once enabled it behaves like a normal + * (not hidden) module. This hook implementation changes the .info data by + * setting the hidden status to FALSE. + */ +function locale_test_translate_system_info_alter(&$info, $file, $type) { + if ($file->name == 'locale_test_translate') { + // Don't hide the module. + $info['hidden'] = FALSE; + } +}