Commit 0485f292 authored by Dries's avatar Dries

Issue #1804702 by Sutharsan, balintk, YesCT, Jose Reyero, Gábor Hojtsy:...

Issue #1804702 by Sutharsan, balintk, YesCT, Jose Reyero, Gábor Hojtsy: Display interface translation status.
parent 4116dc4a
<?php
/**
* @file
* Contains Drupal\locale\Tests\LocaleUpdateInterfaceTest.
*/
namespace Drupal\locale\Tests;
use Drupal\simpletest\WebTestBase;
/**
* Tests for the locale translation update status user interfaces.
*/
class LocaleUpdateInterfaceTest extends WebTestBase {
/**
* Modules to enable.
*
* @var array
*/
public static $modules = array('update', 'locale', 'locale_test_translate');
public static function getInfo() {
return array(
'name' => 'Update translations user interface',
'description' => 'Tests for the user interface of project interface translations.',
'group' => 'Locale',
);
}
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. <a href="@add_language">Add a language</a> 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. As this is an uncontrolled factor in the test, we will
// ignore Drupal core here and continue with the prepared modules.
$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 <a href="@updates">Available translation updates</a> 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('Missing translations for: @languages. See the <a href="@updates">Available translation updates</a> page for more information.', array('@languages' => t('German'), '@updates' => url('admin/reports/translations'))), 'Missing translations message');
$this->drupalGet('admin/reports/translations');
$this->assertText(t('Missing translations for one project'), 'No translations 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');
}
}
......@@ -2,7 +2,7 @@
/**
* @file
* Definition of Drupal\locale\Tests\LocaleCompareTest.
* Contains Drupal\locale\Tests\LocaleUpdateTest.
*/
namespace Drupal\locale\Tests;
......@@ -10,7 +10,7 @@
use Drupal\simpletest\WebTestBase;
/**
* Tests for comparing status of existing project translations with available translations.
* Tests for update translations.
*/
class LocaleUpdateTest extends WebTestBase {
......@@ -51,24 +51,21 @@ 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',
);
}
/**
* 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();
module_load_include('compare.inc', 'locale');
module_load_include('fetch.inc', 'locale');
$admin_user = $this->drupalCreateUser(array('administer modules', 'administer site configuration', 'administer languages', 'access administration pages', 'translate interface'));
$this->drupalLogin($admin_user);
// We use German as test language. This language must match the translation
// file that come with the locale_test module (test.de.po) and can therefore
// not be chosen randomly.
$this->drupalPost('admin/config/regional/language/add', array('predefined_langcode' => 'de'), t('Add language'));
// Setup timestamps to identify old and new translation sources.
......@@ -429,9 +426,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('<label for="edit-langcodes-de" class="language-name">German</label>', '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 +492,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 +548,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 +603,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 +641,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');
......@@ -794,4 +800,5 @@ function testEnableCustomLanguage() {
$this->assertText('Allowed HTML source string', t('String successfully imported.'));
$this->assertNoText('Another allowed HTML source string', t('String with disallowed translation not imported.'));
}
}
......@@ -47,3 +47,77 @@
.locale-translate-edit-form table.changed {
margin-top: 0;
}
/**
* Available translation updates page.
*/
#locale-translation-status-form table {
table-layout: fixed;
}
#locale-translation-status-form th.select-all {
width: 4%;
}
#locale-translation-status-form th.title {
width: 25%;
}
#locale-translation-status-form th.description {
}
#locale-translation-status-form td {
vertical-align: top;
}
#locale-translation-status-form .expand .inner {
background: transparent url(../../misc/menu-collapsed.png) left .6em no-repeat;
margin-left: -12px;
padding-left: 12px;
}
#locale-translation-status-form .expanded .expand .inner {
background: transparent url(../../misc/menu-expanded.png) left .6em no-repeat;
}
#locale-translation-status-form label {
color: #1d1d1d;
font-size: 1.15em;
}
#locale-translation-status-form .description {
cursor: pointer;
}
#locale-translation-status-form .description .inner {
color: #5c5c5b;
line-height: 20px;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
#locale-translation-status-form .expanded .description .inner {
height: auto;
overflow: visible;
white-space: normal;
}
#locale-translation-status-form .expanded .description .text {
-webkit-hyphens: auto;
-moz-hyphens: auto;
hyphens: auto;
}
.js #locale-translation-status-form .description .inner {
height: 20px;
}
#locale-translation-status-form .expanded .description .inner {
height: auto;
overflow: visible;
white-space: normal;
}
#locale-translation-status-form .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-form th.title {
width: 20%;
}
#locale-translation-status-form th.status {
width: 40%;
}
}
......@@ -40,6 +40,41 @@ Drupal.behaviors.localeTranslateDirty = {
}
};
/**
* Show/hide the description details on Available translation updates page.
*/
Drupal.behaviors.hideUpdateInformation = {
attach: function (context, settings) {
var $table = $('#locale-translation-status-form').once('expand-updates');
var effect = settings.hideUpdates;
if ($table.length) {
var $tbodies = $table.find('tbody');
// Open/close the description details by toggling a tr class.
$tbodies.on('click keydown', '.description', function (e) {
if (e.keyCode && (e.keyCode !== 13 && e.keyCode !== 32)) {
return;
}
e.preventDefault();
var $tr = $(this).closest('tr');
$tr.toggleClass('expanded');
// Change screen reader text.
$tr.find('.update-description-prefix').text(function () {
if ($tr.hasClass('expanded')) {
return Drupal.t('Hide description');
}
else {
return Drupal.t('Show description');
}
});
});
}
$table.find('.requirements, .links').hide();
}
};
$.extend(Drupal.theme, {
localeTranslateChangedMarker: function () {
return '<abbr class="warning ajax-changed" title="' + Drupal.t('Changed') + '">*</abbr>';
......
......@@ -282,6 +282,70 @@ function locale_schema() {
return $schema;
}
/**
* Implements hook_requirements().
*/
function locale_requirements($phase) {
$requirements = array();
if ($phase == 'runtime') {
$available_updates = array();
$updates_not_found = array();
$languages = locale_translatable_language_list();
if ($languages) {
// Determine the status of the translation updates per lanuage.
$status = state()->get('locale.translation_status');
if ($status) {
foreach ($status as $project_id => $project) {
foreach ($project as $langcode => $project_info) {
if (!isset($project_info->type)) {
$updates_not_found[$langcode] = $languages[$langcode]->name;
}
elseif ($project_info->type == LOCALE_TRANSLATION_LOCAL || $project_info->type == LOCALE_TRANSLATION_REMOTE) {
$available_updates[$langcode] = $languages[$langcode]->name;
}
}
}
if ($available_updates || $updates_not_found) {
if ($available_updates) {
$requirements['locale_translation'] = array(
'title' => 'Translation update status',
'value' => l(t('Updates available'), 'admin/reports/translations'),
'severity' => REQUIREMENT_WARNING,
'description' => t('Updates available for: @languages. See the <a href="@updates">Available translation updates</a> page for more information.', array('@languages' => implode(', ', $available_updates), '@updates' => url('admin/reports/translations'))),
);
}
else {
$requirements['locale_translation'] = array(
'title' => 'Translation update status',
'value' => t('Missing translations'),
'severity' => REQUIREMENT_INFO,
'description' => t('Missing translations for: @languages. See the <a href="@updates">Available translation updates</a> page for more information.', array('@languages' => implode(', ', $updates_not_found), '@updates' => url('admin/reports/translations'))),
);
}
}
else {
$requirements['locale_translation'] = array(
'title' => 'Translation update status',
'value' => t('Up to date'),
'severity' => REQUIREMENT_OK,
);
}
}
else {
$requirements['locale_translation'] = array(
'title' => 'Translation update status',
'value' => l(t('Can not determine status'), 'admin/reports/translations'),
'severity' => REQUIREMENT_WARNING,
'description' => t('No translation status is available. See the <a href="@updates">Available translation updates</a> page for more information.', array('@updates' => url('admin/reports/translations'))),
);
}
}
}
return $requirements;
}
/**
* @addtogroup updates-7.x-to-8.x
* @{
......
......@@ -263,6 +263,14 @@ function locale_theme() {
'render element' => 'form',
'file' => 'locale.pages.inc',
),
'locale_translation_last_check' => array(
'variables' => array('last' => NULL),
'file' => 'locale.pages.inc',
),
'locale_translation_update_info' => array(
'arguments' => array('updates' => array(), 'not_found' => array()),
'file' => 'locale.pages.inc',
),
);
}
......
This diff is collapsed.
......@@ -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;
}
}
......@@ -1006,23 +1006,29 @@ div.add-or-remove-shortcuts {
#system-modules .fieldset-wrapper {
padding: 0;
}
#system-modules table {
#system-modules table,
#locale-translation-status-form table {
border: 0;
}
#system-modules tr.even,
#system-modules tr.odd {
#system-modules tr.odd,
#locale-translation-status-form tr.even,
#locale-translation-status-form tr.odd {
background: #f3f4ee;
border: 0;
border-bottom: 10px solid #fff;
}
#system-modules tr td:last-child {
#system-modules tr td:last-child,
#locale-translation-status-form tr td:last-child {
border: 0;
}
#system-modules table th {
#system-modules table th,
#locale-translation-status-form table th {
border: 0;
border-bottom: 10px solid #fff;
}
#system-modules .sticky-header th {
#system-modules .sticky-header th,
#locale-translation-status-form .sticky-header th {
border: 0;
}
/* Recent content block */
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment