You are here

i18n_node_reference.test in i18n node reference synch 7

Test node reference field synchronization.

File

i18n_node_reference.test
View source
<?php

/**
 * @file
 * Test node reference field synchronization.
 */

/**
 * Unit test for node reference field synchronisation.
 */
class Drupali18nSyncNodeReferenceTestCase extends Drupali18nTestCase {
  protected $field;
  protected $instance;

  /**
   * Returns test info.
   * @return array
   *   Test information.
   */
  public static function getInfo() {
    return array(
      'name' => 'Synchronize node reference field',
      'group' => 'Internationalization',
      'description' => 'Internationalization Content Synchronization: Node Reference Field',
    );
  }

  /**
   * Sets up the tests.
   */
  public function setUp() {
    parent::setUp('translation', 'i18n_string', 'i18n_sync', 'references', 'node_reference', 'i18n_node_reference');
    parent::setUpLanguages();

    // Add test languages.
    $this
      ->addLanguage('en');
    $this
      ->addLanguage('nl');
    $this
      ->addLanguage('fr');

    // Set up page content type.
    $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
      ->drupalGet('admin/structure/types/manage/page');

    // Set up article content type.
    $this
      ->drupalGet('admin/structure/types/manage/article');
    $edit = array();
    $edit['language_content_type'] = 2;
    $this
      ->drupalPost('admin/structure/types/manage/article', $edit, t('Save content type'));
    $this
      ->drupalGet('admin/structure/types/manage/article');

    // Set up untranslated content type.
    $settings = array(
      'type' => 'untranslated',
      'name' => 'untranslated',
    );
    $this
      ->drupalCreateContentType($settings);

    // Set up article content type.
    $this
      ->drupalGet('admin/structure/types/manage/untranslated');
    $edit = array();
    $edit['language_content_type'] = 1;

    // Languages enabled, but no translation.
    $this
      ->drupalPost('admin/structure/types/manage/untranslated', $edit, t('Save content type'));
    $this
      ->drupalGet('admin/structure/types/manage/untranslated');

    // Add user that has content edit permissions.
    $this->content_editor = $this
      ->drupalCreateUser(array(
      'create untranslated content',
      'edit own untranslated content',
      'create page content',
      'edit own page content',
      'create article content',
      'edit own article content',
      'translate content',
      'translate interface',
    ));
    $this
      ->createNodeRefField(array(
      'article',
      'untranslated',
    ), 'field_article');

    // Set up fields for synchronization: field_article.
    $this
      ->drupalLogin($this->admin_user);
    $edit = array(
      'i18n_sync_node_type[field_article]' => 1,
    );
    $this
      ->drupalPost('admin/structure/types/manage/page', $edit, t('Save content type'));
    $this
      ->drupalGet('admin/structure/types/manage/page');
  }

  /**
   * Full test for node synchronization.
   */
  public function testI18nSyncNodeReference() {

    // Log in as the content editor.
    $this
      ->drupalLogin($this->content_editor);

    // Create translatable articles for reference.
    $articles = array();
    $article_translations = array();
    $articles['en'] = $this
      ->createNode('article', 'English only article', $this
      ->randomString(20), language_default('language'));
    $articles['en_nl'] = $this
      ->createNode('article', 'English and Dutch article', $this
      ->randomString(20), 'en');
    $this
      ->drupalGet('node/' . $articles['en_nl']->nid . '/translate');
    $article_translations['en_nl'] = $this
      ->createNodeTranslationSet($articles['en_nl']);
    $articles['en_nl_2'] = $this
      ->createNode('article', 'English and Dutch 2 article', $this
      ->randomString(20), 'en');
    $this
      ->drupalGet('node/' . $articles['en_nl_2']->nid . '/translate');
    $article_translations['en_nl_2'] = $this
      ->createNodeTranslationSet($articles['en_nl_2']);
    $articles['und'] = $this
      ->createNode('article', 'Language independent', $this
      ->randomString(20), LANGUAGE_NONE);

    // Create untranslatable references.
    $untranslated = array();
    $untranslated['a'] = $this
      ->createNode('untranslated', 'A', $this
      ->randomString(20), 'en');
    $untranslated['b'] = $this
      ->createNode('untranslated', 'B', $this
      ->randomString(20), 'nl');
    $untranslated['c'] = $this
      ->createNode('untranslated', 'C', $this
      ->randomString(20), LANGUAGE_NONE);
    $pages = array();
    $page_translations = array();
    $pages['en'] = $this
      ->createNode('page', 'English only page', $this
      ->randomString(20), language_default('language'));
    $pages['en_nl'] = $this
      ->createNode('page', 'English and Dutch page', $this
      ->randomString(20), 'en', array(
      'title' => 'English and Dutch',
    ));
    $this
      ->drupalGet('node/' . $pages['en_nl']->nid . '/translate');
    $page_translations['en_nl'] = $this
      ->createNodeTranslationSet($pages['en_nl']);
    $pages['und'] = $this
      ->createNode('page', 'Untranslatable page', $this
      ->randomString(20), LANGUAGE_NONE);

    // Test if article references are saved.
    $nids = array(
      $articles['en']->nid,
      $article_translations['en_nl']['en']->nid,
      $articles['und']->nid,
      $untranslated['a']->nid,
      $untranslated['c']->nid,
    );
    $edit = array();
    foreach ($nids as $nid) {
      $edit["field_article[und][{$nid}]"] = $nid;
    }
    $this
      ->drupalPost('node/' . $pages['en']->nid . '/edit', $edit, t('Save'));
    $this
      ->assertPageReferencesNodes($pages['en']->nid, $nids, t("Test setting node references for page without translations"));

    // Test simple synchronization.
    $this
      ->drupalPost('node/' . $page_translations['en_nl']['en']->nid . '/edit', $edit, t('Save'));
    $this
      ->assertPageReferencesNodes($page_translations['en_nl']['en']->nid, $nids, t("Test setting node references for page with translations"));
    $trans_nids = array(
      $article_translations['en_nl']['nl']->nid,
      $articles['und']->nid,
      $untranslated['a']->nid,
      $untranslated['c']->nid,
    );
    $this
      ->assertPageReferencesNodes($page_translations['en_nl']['nl']->nid, $trans_nids, t("Test translated nids."));

    // Test if removed translations are really removed.
    $edit = array();
    foreach ($trans_nids as $nid) {
      $edit["field_article[und][{$nid}]"] = FALSE;
    }
    $this
      ->drupalPost('node/' . $page_translations['en_nl']['nl']->nid . '/edit', $edit, t('Save'));
    $this
      ->assertPageReferencesNodes($page_translations['en_nl']['nl']->nid, array(), t("Test removing node references in Dutch page"));
    $this
      ->assertPageReferencesNodes($page_translations['en_nl']['en']->nid, array(
      $articles['en']->nid,
    ), t("Test removed nids in the English version. Only the English-only article should remain"));

    // Test node with language 'undefined'.
    $nids = array(
      $article_translations['en_nl']['en']->nid,
      $articles['und']->nid,
      $untranslated['a']->nid,
      $untranslated['b']->nid,
      $untranslated['c']->nid,
    );
    $edit = array();
    foreach ($nids as $nid) {
      $edit["field_article[und][{$nid}]"] = $nid;
    }
    $this
      ->drupalPost('node/' . $pages['und']->nid . '/edit', $edit, t('Save'));
    $this
      ->assertPageReferencesNodes($pages['und']->nid, $nids, t("Test setting node references for untranslatable page"));
  }

  /**
   * Asserts that the page references the articles.
   *
   * @param int $page_nid
   *   Nid of the page that contains the references.
   * @param array $referenced_nids
   *   Nids of the articles that should be referenced.
   *
   * @param string $message
   *   Message to be shown in assertions.
   */
  protected function assertPageReferencesNodes($page_nid, $referenced_nids, $message) {
    $real_articles_nids = $this
      ->getReferencedNodes($page_nid);
    foreach ($referenced_nids as $article_nid) {
      $this
        ->assertTrue(in_array($article_nid, $real_articles_nids), $message . t(': Page @page_nid references node @article_nid.', array(
        '@page_nid' => $page_nid,
        '@article_nid' => $article_nid,
      )));
    }
    $diff = array_diff($real_articles_nids, $referenced_nids);
    $this
      ->assertTrue(count($real_articles_nids) == count($referenced_nids) && empty($diff), $message . t(': Page references no unexpected nodes, but found @diff.', array(
      'diff' => implode(',', $diff),
    )));
  }

  /**
   * Returns the nids of the referenced articles.
   *
   * @param int $page_nid
   *   Nid of the page to return the article references for.
   *
   * @return array
   *   Nids of all referenced articles.
   */
  protected function getReferencedNodes($page_nid) {
    $node = node_load($page_nid, NULL, TRUE);
    $items = field_get_items('node', $node, 'field_article');
    $nids = array();
    if ($items) {
      foreach ($items as $item) {
        $nids[] = $item['nid'];
      }
    }
    return $nids;
  }

  /**
   * Creates a node reference field to the specified types.
   *
   * @param array $target_types
   *   The node types that can be targeted (for example: 'article').
   *
   * @param string $field_name
   *   The name of the field to be created.
   *
   * @param string $widget
   *   The widget to be used.
   */
  protected function createNodeRefField($target_types, $field_name, $widget = 'options_buttons') {
    $this->field = array(
      'field_name' => $field_name,
      'type' => 'node_reference',
      'cardinality' => -1,
      'settings' => array(
        'referenceable_types' => array(
          drupal_map_assoc($target_types),
        ),
      ),
    );
    field_create_field($this->field);
    $this->instance = array(
      'field_name' => $field_name,
      'entity_type' => 'node',
      'bundle' => 'page',
      'widget' => array(
        'type' => $widget,
      ),
      'display' => array(
        'default' => array(
          'type' => 'node_reference_default',
        ),
      ),
    );
    field_create_instance($this->instance);
  }

}

Classes

Namesort descending Description
Drupali18nSyncNodeReferenceTestCase Unit test for node reference field synchronisation.