Index: includes/translation.node.inc
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/translation/includes/translation.node.inc,v
retrieving revision 1.2
diff -u -r1.2 translation.node.inc
--- includes/translation.node.inc 3 Oct 2010 16:36:14 -0000 1.2
+++ includes/translation.node.inc 26 Jan 2011 17:30:50 -0000
@@ -37,7 +37,7 @@
* Node specific access callback.
*/
function translation_node_tab_access($node) {
- return !empty($node->language) && (translation_supported_type($node->type) || translation_node('node', $node)) && translation_tab_access('node');
+ return !empty($node->language) && ((translation_supported_type($node->type) && translation_tab_access('node')) || translation_node('node', $node));
}
/**
Index: modules/translation_node/translation_node.pages.inc
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/translation/modules/translation_node/translation_node.pages.inc,v
retrieving revision 1.1
diff -u -r1.1 translation_node.pages.inc
--- modules/translation_node/translation_node.pages.inc 23 Sep 2010 11:58:28 -0000 1.1
+++ modules/translation_node/translation_node.pages.inc 26 Jan 2011 17:30:52 -0000
@@ -13,6 +13,8 @@
* Node object.
*/
function translation_node_overview($node) {
+ include_once DRUPAL_ROOT . '/includes/language.inc';
+
if ($node->tnid) {
// Already part of a set, grab that set.
$tnid = $node->tnid;
@@ -24,18 +26,24 @@
$translations = array($node->language => $node);
}
+ $type = variable_get('translation_language_type', LANGUAGE_TYPE_INTERFACE);
$header = array(t('Language'), t('Title'), t('Status'), t('Operations'));
- foreach (language_list() as $language) {
+ foreach (language_list() as $langcode => $language) {
$options = array();
$language_name = $language->name;
- if (isset($translations[$language->language])) {
+ if (isset($translations[$langcode])) {
// Existing translation in the translation set: display status.
// We load the full node to check whether the user can edit it.
- $translation_node = node_load($translations[$language->language]->nid);
- $title = l($translation_node->title, 'node/' . $translation_node->nid);
+ $translation_node = node_load($translations[$langcode]->nid);
+ $path = 'node/' . $translation_node->nid;
+ $links = language_negotiation_get_switch_links($type, $path);
+ $title = empty($links->links[$langcode]) ? l($translation_node->title, $path) : l($translation_node->title, $links->links[$langcode]['href'], $links->links[$langcode]);
if (node_access('update', $translation_node)) {
- $options[] = l(t('edit'), "node/$translation_node->nid/edit");
+ $text = t('edit');
+ $path = 'node/' . $translation_node->nid . '/edit';
+ $links = language_negotiation_get_switch_links($type, $path);
+ $options[] = empty($links->links[$langcode]) ? l($text, $path) : l($text, $links->links[$langcode]['href'], $links->links[$langcode]);
}
$status = $translation_node->status ? t('Published') : t('Not published');
$status .= $translation_node->translate ? ' - ' . t('outdated') . '' : '';
@@ -47,7 +55,11 @@
// No such translation in the set yet: help user to create it.
$title = t('n/a');
if (node_access('create', $node)) {
- $options[] = l(t('add translation'), 'node/add/' . str_replace('_', '-', $node->type), array('query' => array('translation' => $node->nid, 'target' => $language->language)));
+ $text = t('add translation');
+ $path = 'node/add/' . str_replace('_', '-', $node->type);
+ $links = language_negotiation_get_switch_links($type, $path);
+ $query = array('query' => array('translation' => $node->nid, 'target' => $langcode));
+ $options[] = empty($links->links[$langcode]) ? l($text, $path, $query) : l($text, $links->links[$langcode]['href'], array_merge_recursive($links->links[$langcode], $query));
}
$status = t('Not translated');
}
Index: modules/translation_node/translation_node.info
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/translation/modules/translation_node/translation_node.info,v
retrieving revision 1.1
diff -u -r1.1 translation_node.info
--- modules/translation_node/translation_node.info 23 Sep 2010 11:58:28 -0000 1.1
+++ modules/translation_node/translation_node.info 26 Jan 2011 17:30:50 -0000
@@ -5,6 +5,4 @@
dependencies[] = translation
package = Multilingual
core = 7.x
-files[] = translation_node.module
-files[] = translation_node.pages.inc
-;files[] = translation_node.test
+files[] = translation_node.test
Index: modules/translation_node/translation_node.module
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/translation/modules/translation_node/translation_node.module,v
retrieving revision 1.1
diff -u -r1.1 translation_node.module
--- modules/translation_node/translation_node.module 23 Sep 2010 11:58:28 -0000 1.1
+++ modules/translation_node/translation_node.module 26 Jan 2011 17:30:52 -0000
@@ -72,7 +72,7 @@
function translation_node_permission() {
return array(
'translate content' => array(
- 'title' => t('Translate content'),
+ 'title' => t('Create node translations'),
),
);
}
@@ -83,6 +83,7 @@
function translation_node_form_node_type_form_alter(&$form, &$form_state) {
// Add translation option to content type form.
$form['workflow']['language_content_type']['#options'][TRANSLATION_NODE_ENABLED] = t('Enabled, with node translation');
+ // Description based on text from locale.module.
$form['workflow']['language_content_type']['#description'] .= ' ' . t('If node translation is enabled every translation will be a different node.');
}
@@ -93,9 +94,27 @@
* - Alters language fields on node forms when a translation
* is about to be created.
*/
-function translation_node_form_alter(&$form, &$form_state, $form_id) {
- if (!empty($form['#node_edit_form']) && translation_node_supported_type($form['#node']->type)) {
+function translation_node_form_node_form_alter(&$form, &$form_state) {
+ if (translation_node_supported_type($form['#node']->type)) {
$node = $form['#node'];
+ $languages = language_list('enabled');
+ $disabled_languages = isset($languages[0]) ? $languages[0] : FALSE;
+ $translator_widget = $disabled_languages && user_access('translate content');
+ $groups = array(t('Disabled'), t('Enabled'));
+ // Allow translators to enter content in disabled languages. Translators
+ // might need to distinguish between enabled and disabled languages, hence
+ // we divide them in two option groups.
+ if ($translator_widget) {
+ $options = array();
+ $language_list = locale_language_list('name', TRUE);
+ foreach (array(1, 0) as $status) {
+ $group = $groups[$status];
+ foreach ($languages[$status] as $langcode => $language) {
+ $options[$group][$langcode] = $language_list[$langcode];
+ }
+ }
+ $form['language']['#options'] = $options;
+ }
if (!empty($node->translation_source)) {
// We are creating a translation. Add values and lock language field.
$form['translation_source'] = array('#type' => 'value', '#value' => $node->translation_source);
@@ -106,9 +125,15 @@
// node to some language which is already in the translation set. Also remove the
// language neutral option.
unset($form['language']['#options'][LANGUAGE_NONE]);
- foreach (translation_node_get_translations($node->tnid) as $translation) {
+ foreach (translation_node_get_translations($node->tnid) as $langcode => $translation) {
if ($translation->nid != $node->nid) {
- unset($form['language']['#options'][$translation->language]);
+ if ($translator_widget) {
+ $group = $groups[(int)!isset($disabled_languages[$langcode])];
+ unset($form['language']['#options'][$group][$langcode]);
+ }
+ else {
+ unset($form['language']['#options'][$langcode]);
+ }
}
}
// Add translation values and workflow options.
@@ -147,20 +172,61 @@
/**
* Implements hook_node_view().
*
- * Display translation links with native language names, if this node
- * is part of a translation set.
+ * Display translation links with native language names, if this node is part of
+ * a translation set. If no language provider is enabled "fall back" to the
+ * simple links built through the result of translation_node_get_translations().
*/
function translation_node_node_view($node, $view_mode) {
- if (isset($node->tnid) && drupal_multilingual() &&
- translation_node_supported_type($node->type) && $translations = translation_node_get_translations($node->tnid)) {
- $path = 'node/' . $node->nid;
- $links = language_negotiation_get_switch_links(LANGUAGE_TYPE_CONTENT, $path);
- if (is_object($links)) {
- $links = $links->links;
- // Do not show link to the same node.
- unset($links[$node->language]);
- $node->content['links']['#links'] = array_merge($node->content['links']['#links'], $links);
+ // If the site has no translations or is not multilingual we have no content
+ // translation links to display.
+ if (isset($node->tnid) && drupal_multilingual() && $translations = translation_node_get_translations($node->tnid)) {
+ $languages = language_list('enabled');
+ $languages = $languages[1];
+
+ // There might be a language provider enabled defining custom language
+ // switch links which need to be taken into account while generating the
+ // content translation links. As custom language switch links are available
+ // only for configurable language types and interface language is the only
+ // configurable language type in core, we use it as default. Contributed
+ // modules can change this behavior by setting the system variable below.
+ $type = variable_get('translation_language_type', LANGUAGE_TYPE_INTERFACE);
+ $custom_links = language_negotiation_get_switch_links($type, "node/$node->nid");
+ $links = array();
+
+ foreach ($translations as $langcode => $translation) {
+ // Do not show links to the same node, to unpublished translations or to
+ // translations in disabled languages.
+ if ($translation->status && isset($languages[$langcode]) && $langcode != $node->language) {
+ $language = $languages[$langcode];
+ $key = "translation_$langcode";
+
+ if (isset($custom_links->links[$langcode])) {
+ $links[$key] = $custom_links->links[$langcode];
+ }
+ else {
+ $links[$key] = array(
+ 'href' => "node/{$translation->nid}",
+ 'title' => $language->native,
+ 'language' => $language,
+ );
+ }
+
+ // Custom switch links are more generic than content translation links,
+ // hence we override existing attributes with the ones below.
+ $links[$key] += array('attributes' => array());
+ $attributes = array(
+ 'title' => $translation->title,
+ 'class' => array('translation-link'),
+ );
+ $links[$key]['attributes'] = $attributes + $links[$key]['attributes'];
+ }
}
+
+ $node->content['links']['translation'] = array(
+ '#theme' => 'links__node__translation',
+ '#links' => $links,
+ '#attributes' => array('class' => array('links', 'inline')),
+ );
}
}
@@ -243,6 +309,8 @@
))
->condition('nid', $node->nid)
->execute();
+ // Save tnid to avoid loss in case of resave.
+ $node->tnid = $tnid;
}
}
}
@@ -355,7 +423,7 @@
if (!isset($translations[$tnid])) {
$translations[$tnid] = array();
$result = db_select('node', 'n')
- ->fields('n', array('nid', 'title', 'language'))
+ ->fields('n', array('nid', 'type', 'uid', 'status', 'title', 'language'))
->condition('n.tnid', $tnid)
->addTag('node_access')
->execute();
@@ -391,7 +459,7 @@
function translation_node_path_get_translations($path) {
$paths = array();
// Check for a node related path, and for its translations.
- if ((preg_match("!^node/([0-9]+)(/.+|)$!", $path, $matches)) && ($node = node_load((int)$matches[1])) && !empty($node->tnid)) {
+ if ((preg_match("!^node/(\d+)(/.+|)$!", $path, $matches)) && ($node = node_load((int) $matches[1])) && !empty($node->tnid)) {
foreach (translation_node_get_translations($node->tnid) as $language => $translation_node) {
$paths[$language] = 'node/' . $translation_node->nid . $matches[2];
}
@@ -405,15 +473,19 @@
* Replaces links with pointers to translated versions of the content.
*/
function translation_node_language_switch_links_alter(array &$links, $type, $path) {
- if ($type == LANGUAGE_TYPE_CONTENT && $paths = translation_node_path_get_translations($path)) {
+ $language_type = variable_get('translation_language_type', LANGUAGE_TYPE_INTERFACE);
+ if ($type == $language_type && preg_match("!^node/(\d+)(/.+|)!", $path, $matches) && ($node = node_load((int) $matches[1]))) {
+ $translations = $node->tnid ? translation_node_get_translations($node->tnid) : array($node->language => $node);
+
foreach ($links as $langcode => $link) {
- if (isset($paths[$langcode])) {
+ if (isset($translations[$langcode]) && $translations[$langcode]->status) {
// Translation in a different node.
- $links[$langcode]['href'] = $paths[$langcode];
+ $links[$langcode]['href'] = 'node/' . $translations[$langcode]->nid . $matches[2];
}
else {
// No translation in this language, or no permission to view.
- unset($links[$langcode]);
+ unset($links[$langcode]['href']);
+ $links[$langcode]['attributes']['class'] = 'locale-untranslated';
}
}
}
Index: modules/translation_node/translation_node.test
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/translation/modules/translation_node/translation_node.test,v
retrieving revision 1.1
diff -u -r1.1 translation_node.test
--- modules/translation_node/translation_node.test 23 Sep 2010 11:58:28 -0000 1.1
+++ modules/translation_node/translation_node.test 26 Jan 2011 17:30:54 -0000
@@ -13,46 +13,74 @@
}
function setUp() {
- parent::setUp('locale', 'translation', 'translation_node');
- }
+ parent::setUp('locale', 'translation', 'translation_node', 'translation_node_test');
- /**
- * Create a basic page with translation, modify the basic page outdating translation, and update translation.
- */
- function testContentTranslation() {
// Setup users.
- $admin_user = $this->drupalCreateUser(array('administer languages', 'administer content types', 'access administration pages'));
- $translator = $this->drupalCreateUser(array('create page content', 'edit own page content', 'translate content'));
+ $this->admin_user = $this->drupalCreateUser(array('bypass node access', 'administer nodes', 'administer languages', 'administer content types', 'administer blocks', 'access administration pages'));
+ $this->translator = $this->drupalCreateUser(array('create page content', 'edit own page content', 'translate content'));
- $this->drupalLogin($admin_user);
+ $this->drupalLogin($this->admin_user);
// Add languages.
$this->addLanguage('en');
$this->addLanguage('es');
+ $this->addLanguage('it');
+
+ // Disable Italian to test the translation behavior with disabled languages.
+ $edit = array('enabled[it]' => FALSE);
+ $this->drupalPost('admin/config/regional/language', $edit, t('Save configuration'));
- // Set "Basic page" content type to use multilingual support with translation.
+ // Set "Basic page" content type to use multilingual support with
+ // translation.
$this->drupalGet('admin/structure/types/manage/page');
$edit = array();
$edit['language_content_type'] = 2;
$this->drupalPost('admin/structure/types/manage/page', $edit, t('Save content type'));
$this->assertRaw(t('The content type %type has been updated.', array('%type' => 'Basic page')), t('Basic page content type has been updated.'));
- $this->drupalLogout();
- $this->drupalLogin($translator);
+ // Enable the language switcher block.
+ $language_type = LANGUAGE_TYPE_INTERFACE;
+ $edit = array("blocks[locale_$language_type][region]" => 'sidebar_first');
+ $this->drupalPost('admin/structure/block', $edit, t('Save blocks'));
+
+ // Enable URL language detection and selection to make the language switcher
+ // block appear.
+ $edit = array('language[enabled][locale-url]' => TRUE);
+ $this->drupalPost('admin/config/regional/language/configure', $edit, t('Save settings'));
+ $this->assertRaw(t('Language negotiation configuration saved.'), t('URL language detection enabled.'));
+ $this->resetCaches();
+ $this->drupalLogin($this->translator);
+ }
+
+ /**
+ * Create a basic page with translation, modify the basic page outdating
+ * translation, and update translation.
+ */
+ function testContentTranslation() {
// Create Basic page in English.
$node_title = $this->randomName();
$node_body = $this->randomName();
$node = $this->createPage($node_title, $node_body, 'en');
+ // Check that the "add translation" link uses a localized path.
+ $languages = language_list();
+ $this->drupalGet('node/' . $node->nid . '/translate');
+ $this->assertLinkByHref($languages['es']->prefix . '/node/add/' . str_replace('_', '-', $node->type), 0, t('The "add translation" link for %language points to the localized path of the target language.', array('%language' => $languages['es']->name)));
+
// Submit translation in Spanish.
$node_translation_title = $this->randomName();
$node_translation_body = $this->randomName();
$node_translation = $this->createTranslation($node, $node_translation_title, $node_translation_body, 'es');
+ // Check that the "edit translation" and "view node" links use localized
+ // paths.
+ $this->drupalGet('node/' . $node->nid . '/translate');
+ $this->assertLinkByHref($languages['es']->prefix . '/node/' . $node_translation->nid . '/edit', 0, t('The "edit" link for the translation in %language points to the localized path of the translation language.', array('%language' => $languages['es']->name)));
+ $this->assertLinkByHref($languages['es']->prefix . '/node/' . $node_translation->nid, 0, t('The "view" link for the translation in %language points to the localized path of the translation language.', array('%language' => $languages['es']->name)));
+
// Attempt to submit a duplicate translation by visiting the node/add page
// with identical query string.
- $languages = language_list();
$this->drupalGet('node/add/page', array('query' => array('translation' => $node->nid, 'target' => 'es')));
$this->assertRaw(t('A translation of %title in %language already exists', array('%title' => $node_title, '%language' => $languages['es']->name)), t('Message regarding attempted duplicate translation is displayed.'));
@@ -67,13 +95,15 @@
$this->assertEqual($duplicate->tnid, 0, t('The node does not have a tnid.'));
// Update original and mark translation as outdated.
+ $node_body = $this->randomName();
+ $node->body[$node->language][0]['value'] = $node_body;
$edit = array();
- $edit["body[$node->language][0][value]"] = $this->randomName();
+ $edit["body[$node->language][0][value]"] = $node_body;
$edit['translation[retranslate]'] = TRUE;
$this->drupalPost('node/' . $node->nid . '/edit', $edit, t('Save'));
$this->assertRaw(t('Basic page %title has been updated.', array('%title' => $node_title)), t('Original node updated.'));
- // Check to make sure that interface shows translation as outdated
+ // Check to make sure that interface shows translation as outdated.
$this->drupalGet('node/' . $node->nid . '/translate');
$this->assertRaw('' . t('outdated') . '', t('Translation marked as outdated.'));
@@ -83,13 +113,115 @@
$edit['translation[status]'] = FALSE;
$this->drupalPost('node/' . $node_translation->nid . '/edit', $edit, t('Save'));
$this->assertRaw(t('Basic page %title has been updated.', array('%title' => $node_translation_title)), t('Translated node updated.'));
+
+ // Confirm that disabled languages are an option for translators when
+ // creating nodes.
+ $this->drupalGet('node/add/page');
+ $this->assertFieldByXPath('//select[@name="language"]//option', 'it', t('Italian (disabled) is available in language selection.'));
+ $translation_it = $this->createTranslation($node, $this->randomName(), $this->randomName(), 'it');
+ $this->assertRaw($translation_it->body['it'][0]['value'], t('Content created in Italian (disabled).'));
+
+ // Leave just one language enabled and check that the translation overview
+ // page is still accessible.
+ $this->drupalLogin($this->admin_user);
+ $edit = array('enabled[es]' => FALSE);
+ $this->drupalPost('admin/config/regional/language', $edit, t('Save configuration'));
+ $this->drupalLogin($this->translator);
+ $this->drupalGet('node/' . $node->nid . '/translate');
+ $this->assertRaw(t('Translations of %title', array('%title' => $node->title)), t('Translation overview page available with only one language enabled.'));
+ }
+
+ /**
+ * Check that language switch links behave properly.
+ */
+ function testLanguageSwitchLinks() {
+ // Create a Basic page in English and its translations in Spanish and
+ // Italian.
+ $node = $this->createPage($this->randomName(), $this->randomName(), 'en');
+ $translation_es = $this->createTranslation($node, $this->randomName(), $this->randomName(), 'es');
+ $translation_it = $this->createTranslation($node, $this->randomName(), $this->randomName(), 'it');
+
+ // Check that language switch links are correctly shown only for enabled
+ // languages.
+ $this->assertLanguageSwitchLinks($node, $translation_es);
+ $this->assertLanguageSwitchLinks($translation_es, $node);
+ $this->assertLanguageSwitchLinks($node, $translation_it, FALSE);
+
+ // Check that links to the displayed translation appear only in the language
+ // switcher block.
+ $this->assertLanguageSwitchLinks($node, $node, FALSE, 'node');
+ $this->assertLanguageSwitchLinks($node, $node, TRUE, 'block-locale');
+
+ // Unpublish the Spanish translation to check that the related language
+ // switch link is not shown.
+ $this->drupalLogin($this->admin_user);
+ $edit = array('status' => FALSE);
+ $this->drupalPost("node/$translation_es->nid/edit", $edit, t('Save'));
+ $this->drupalLogin($this->translator);
+ $this->assertLanguageSwitchLinks($node, $translation_es, FALSE);
+
+ // Check that content translation links are shown even when no language
+ // negotiation is configured.
+ $this->drupalLogin($this->admin_user);
+ $edit = array('language[enabled][locale-url]' => FALSE);
+ $this->drupalPost('admin/config/regional/language/configure', $edit, t('Save settings'));
+ $this->resetCaches();
+ $edit = array('status' => TRUE);
+ $this->drupalPost("node/$translation_es->nid/edit", $edit, t('Save'));
+ $this->drupalLogin($this->translator);
+ $this->assertLanguageSwitchLinks($node, $translation_es, TRUE, 'node');
+ }
+
+ /**
+ * Test that the language switcher block alterations work as intended.
+ */
+ function testLanguageSwitcherBlockIntegration() {
+ // Enable Italian to have three items in the language switcher block.
+ $this->drupalLogin($this->admin_user);
+ $edit = array('enabled[it]' => TRUE);
+ $this->drupalPost('admin/config/regional/language', $edit, t('Save configuration'));
+ $this->drupalLogin($this->translator);
+
+ // Create a Basic page in English.
+ $type = 'block-locale';
+ $node = $this->createPage($this->randomName(), $this->randomName(), 'en');
+ $this->assertLanguageSwitchLinks($node, $node, TRUE, $type);
+ $this->assertLanguageSwitchLinks($node, $this->emptyNode('es'), TRUE, $type);
+ $this->assertLanguageSwitchLinks($node, $this->emptyNode('it'), TRUE, $type);
+
+ // Create the Spanish translation.
+ $translation_es = $this->createTranslation($node, $this->randomName(), $this->randomName(), 'es');
+ $this->assertLanguageSwitchLinks($node, $node, TRUE, $type);
+ $this->assertLanguageSwitchLinks($node, $translation_es, TRUE, $type);
+ $this->assertLanguageSwitchLinks($node, $this->emptyNode('it'), TRUE, $type);
+
+ // Create the Italian translation.
+ $translation_it = $this->createTranslation($node, $this->randomName(), $this->randomName(), 'it');
+ $this->assertLanguageSwitchLinks($node, $node, TRUE, $type);
+ $this->assertLanguageSwitchLinks($node, $translation_es, TRUE, $type);
+ $this->assertLanguageSwitchLinks($node, $translation_it, TRUE, $type);
+ }
+
+ /**
+ * Reset static caches to make the test code match the client site behavior.
+ */
+ function resetCaches() {
+ drupal_static_reset('locale_url_outbound_alter');
+ }
+
+ /**
+ * Return an empty node data structure.
+ */
+ function emptyNode($langcode) {
+ return (object) array('nid' => NULL, 'language' => $langcode);
}
/**
* Install a the specified language if it has not been already. Otherwise make sure that
* the language is enabled.
*
- * @param string $language_code The language code the check.
+ * @param $language_code
+ * The language code the check.
*/
function addLanguage($language_code) {
// Check to make sure that language has not already been installed.
@@ -101,7 +233,7 @@
$edit['langcode'] = $language_code;
$this->drupalPost('admin/config/regional/language/add', $edit, t('Add language'));
- // Make sure we're not using a stale list.
+ // Make sure we are not using a stale list.
drupal_static_reset('language_list');
$languages = language_list('language');
$this->assertTrue(array_key_exists($language_code, $languages), t('Language was installed successfully.'));
@@ -125,9 +257,12 @@
/**
* Create a "Basic page" in the specified language.
*
- * @param string $title Title of basic page in specified language.
- * @param string $body Body of basic page in specified language.
- * @param string $language Language code.
+ * @param $title
+ * Title of basic page in specified language.
+ * @param $body
+ * Body of basic page in specified language.
+ * @param
+ * $language Language code.
*/
function createPage($title, $body, $language) {
$edit = array();
@@ -146,12 +281,17 @@
}
/**
- * Create a translation for the specified basic page in the specified language.
+ * Create a translation for the specified basic page in the specified
+ * language.
*
- * @param integer $nid Node id of basic page to create translation for.
- * @param string $title Title of basic page in specified language.
- * @param string $body Body of basic page in specified language.
- * @param string $language Language code.
+ * @param $node
+ * The basic page to create translation for.
+ * @param $title
+ * Title of basic page in specified language.
+ * @param $body
+ * Body of basic page in specified language.
+ * @param $language
+ * Language code.
*/
function createTranslation($node, $title, $body, $language) {
$this->drupalGet('node/add/page', array('query' => array('translation' => $node->nid, 'target' => $language)));
@@ -167,9 +307,108 @@
$this->assertRaw(t('Basic page %title has been created.', array('%title' => $title)), t('Translation created.'));
// Check to make sure that translation was successful.
- $node = $this->drupalGetNodeByTitle($title);
- $this->assertTrue($node, t('Node found in database.'));
+ $translation = $this->drupalGetNodeByTitle($title);
+ $this->assertTrue($translation, t('Node found in database.'));
+ $this->assertTrue($translation->tnid == $node->nid, t('Translation set id correctly stored.'));
- return $node;
+ return $translation;
+ }
+
+ /**
+ * Assert that an element identified by the given XPath has the given content.
+ *
+ * @param $xpath
+ * XPath used to find the element.
+ * @param array $arguments
+ * An array of arguments with keys in the form ':name' matching the
+ * placeholders in the query. The values may be either strings or numeric
+ * values.
+ * @param $value
+ * The text content of the matched element to assert.
+ * @param $message
+ * Message to display.
+ * @param $group
+ * The group this message belongs to.
+ *
+ * @return
+ * TRUE on pass, FALSE on fail.
+ */
+ function assertContentByXPath($xpath, array $arguments = array(), $value = NULL, $message = '', $group = 'Other') {
+ $found = $this->findContentByXPath($xpath, $arguments, $value);
+ return $this->assertTrue($found, $message, $group);
+ }
+
+ /**
+ * Check that the specified language switch links are found/not found.
+ *
+ * @param $node
+ * The node to display.
+ * @param $translation
+ * The translation whose link has to be checked.
+ * @param $find
+ * TRUE if the link must be present in the node page.
+ * @param $types
+ * The page areas to be checked.
+ *
+ * @return
+ * TRUE if the language switch links are found/not found.
+ */
+ function assertLanguageSwitchLinks($node, $translation, $find = TRUE, $types = NULL) {
+ if (empty($types)) {
+ $types = array('node', 'block-locale');
+ }
+ elseif (is_string($types)) {
+ $types = array($types);
+ }
+
+ $result = TRUE;
+ $languages = language_list();
+ $page_language = $languages[$node->language];
+ $translation_language = $languages[$translation->language];
+ $url = url("node/$translation->nid", array('language' => $translation_language));
+
+ $this->drupalGet("node/$node->nid", array('language' => $page_language));
+
+ foreach ($types as $type) {
+ $args = array('%translation_language' => $translation_language->native, '%page_language' => $page_language->native, '%type' => $type);
+ if ($find) {
+ $message = t('[%page_language] Language switch item found for %translation_language language in the %type page area.', $args);
+ }
+ else {
+ $message = t('[%page_language] Language switch item not found for %translation_language language in the %type page area.', $args);
+ }
+
+ if (!empty($translation->nid)) {
+ $xpath = '//div[contains(@class, :type)]//a[@href=:url]';
+ }
+ else {
+ $xpath = '//div[contains(@class, :type)]//span[@class="locale-untranslated"]';
+ }
+
+ $found = $this->findContentByXPath($xpath, array(':type' => $type, ':url' => $url), $translation_language->native);
+ $result = $this->assertTrue($found == $find, $message) && $result;
+ }
+
+ return $result;
+ }
+
+ /**
+ * Search for elements matching the given xpath and value.
+ */
+ function findContentByXPath($xpath, array $arguments = array(), $value = NULL) {
+ $elements = $this->xpath($xpath, $arguments);
+
+ $found = TRUE;
+ if ($value && $elements) {
+ $found = FALSE;
+ foreach ($elements as $element) {
+ if ((string) $element == $value) {
+ $found = TRUE;
+ break;
+ }
+ }
+ }
+
+ return $elements && $found;
}
}
Index: modules/translation_node/tests/translation_node_test.info
===================================================================
RCS file: modules/translation_node/tests/translation_node_test.info
diff -N modules/translation_node/tests/translation_node_test.info
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ modules/translation_node/tests/translation_node_test.info 1 Jan 1970 00:00:00 -0000
@@ -0,0 +1,6 @@
+; $Id$
+name = "Content translation (Node) Test"
+description = "Support module for the node translation tests."
+core = 7.x
+package = Testing
+hidden = TRUE
Index: modules/translation_node/tests/translation_node_test.module
===================================================================
RCS file: modules/translation_node/tests/translation_node_test.module
diff -N modules/translation_node/tests/translation_node_test.module
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ modules/translation_node/tests/translation_node_test.module 1 Jan 1970 00:00:00 -0000
@@ -0,0 +1,14 @@
+