You are here

language_hierarchy_paths.test in Language Hierarchy 7

File

modules/language_hierarchy_paths/language_hierarchy_paths.test
View source
<?php

/**
 * @file
 * Tests for language_hierarchy_paths.module.
 */

/**
 * Functional tests for configuring a different path alias per language.
 */
class LanguageHierarchyPathsFunctionalTest extends DrupalWebTestCase {

  /** @var PathincInterface $singleton */
  protected $pathinc_singleton;
  protected $languages;
  public static function getInfo() {
    return array(
      'name' => 'Language Hierarchy in Paths',
      'description' => 'Checks individual URL aliases can fallback through language hierarchies.',
      'group' => 'Language Hierarchy',
    );
  }
  function setUp() {
    parent::setUp('language_hierarchy_paths', 'pathinc', 'locale', 'path');
    $class_name = variable_get('pathinc_class_name', 'DrupalPathinc');
    $this->pathinc_singleton = new $class_name();
    $this->languages = array(
      'xx' => array(
        'name' => 'Custom parent language',
        'native' => $this
          ->randomName(16),
      ),
      'xx-xx' => array(
        'name' => 'Custom sublanguage',
        'native' => $this
          ->randomName(16),
        'parent_language_list' => 'xx',
      ),
      'en-xx' => array(
        'name' => 'English sublanguage',
        'native' => $this
          ->randomName(16),
        'parent_language_list' => 'en',
      ),
    );
  }

  /**
   * Test if language hierarchies are used for path aliases associated with
   * language.
   *
   * @see LocalePathFunctionalTest::testPathLanguageConfiguration()
   */
  function testLanguageHierarchyPathsLookup() {

    // 1. Set up admin user & languages.
    $this
      ->createAdminUserAndLanguages();

    // 2. Set up a node with paths in parent languages & LANGUAGE_NONE.
    $page_node = $this
      ->drupalCreateNode(array(
      'type' => 'page',
    ));
    $page_node_paths = array(
      // Create a path alias in default language (English).
      'en' => array(
        'source' => 'node/' . $page_node->nid,
        'alias' => $this
          ->randomName(8),
        'language' => 'en',
      ),
      // Create a path alias in new custom language.
      'xx' => array(
        'source' => 'node/' . $page_node->nid,
        'alias' => $this
          ->randomName(8),
        'language' => 'xx',
      ),
    );
    $this
      ->createPathsThroughUI($page_node_paths);

    // Also create a custom path in LANGUAGE_NONE, which should not be
    // prioritized over the specific language even though it is newer.
    $edit = array(
      'source' => 'node/' . $page_node->nid,
      'alias' => $this
        ->randomName(8),
      'language' => LANGUAGE_NONE,
    );
    path_save($edit);

    // 3. Check sublanguages inherit aliases from parent languages, including
    //    priority of languages for alias by source path.
    $lookups = array(
      'en',
      'xx',
      'xx-xx',
      'en-xx',
    );
    $this
      ->checkLookups($lookups, $page_node->title, $page_node_paths, 'node/' . $page_node->nid);

    // 4. Check direct lookups too, to be sure.
    foreach ($lookups as $langcode) {
      if (isset($this->languages[$langcode]['parent_language_list'])) {
        $language_name = $this->languages[$langcode]['name'];
        $parent_langcode = $this->languages[$langcode]['parent_language_list'];
        $alias = $page_node_paths[$parent_langcode]['alias'];
      }
      else {
        $language_name = isset($this->languages[$langcode]) ? $this->languages[$langcode]['name'] : 'English';
        if (isset($page_node_paths[$langcode]['alias'])) {
          $alias = $page_node_paths[$langcode]['alias'];
        }
        else {
          $this
            ->fail($language_name . ' has no alias.');
          continue;
        }
      }
      $this
        ->checkDirectLookup($langcode, 'node/' . $page_node->nid, $alias, $language_name . ' sublanguage alias has priority.');
    }

    // 5. Repeat test from step 3 to use cache, since the first page visits
    //    would have missed the cache, which uses different code to get path
    //    aliases in bulk.
    $this
      ->checkLookups($lookups, $page_node->title, $page_node_paths, NULL);
  }

  /**
   * Set up admin user and languages.
   */
  function createAdminUserAndLanguages() {

    // User to add and remove language.
    $admin_user = $this
      ->drupalCreateUser(array(
      'administer languages',
      'create page content',
      'administer url aliases',
      'create url aliases',
      'access administration pages',
    ));
    $this
      ->drupalLogin($admin_user);
    $this
      ->addLanguagesWithHierarchy($this->languages);
    drupal_static_reset('language_list');

    // Enable URL language detection and selection.
    $edit = array(
      'language[enabled][locale-url]' => 1,
    );
    $this
      ->drupalPost('admin/config/regional/language/configure', $edit, t('Save settings'));
  }

  /**
   * Test path lookups via the page canonical path and node title.
   *
   * Canonical paths are used for the test as those are produced by
   * node_page_view() via calls to url(), which uses drupal_get_path_alias() and
   * therefore drupal_lookup_path().
   * Testing the node title is done to check that the reverse lookup,
   * drupal_get_normal_path() worked correctly - i.e. that on visiting the
   * alias, the correct system path was found.
   */
  function checkLookups($paths, $node_title, $page_node_paths, $clear_path_cache = NULL) {
    foreach ($paths as $langcode) {
      if (isset($this->languages[$langcode])) {
        $language_name = $this->languages[$langcode]['name'];
        if (isset($this->languages[$langcode]['parent_language_list'])) {
          $parent_langcode = $this->languages[$langcode]['parent_language_list'];
          $alias = $page_node_paths[$parent_langcode]['alias'];
        }
        elseif (isset($page_node_paths[$langcode]['alias'])) {
          $alias = $page_node_paths[$langcode]['alias'];
        }
        else {
          $this
            ->fail($language_name . ' has no alias.');
          continue;
        }
        $alias = $langcode . '/' . $alias;
      }
      else {
        $language_name = 'English';
        $alias = $page_node_paths[$langcode]['alias'];
      }
      $this
        ->checkCanonicalPathAndText($alias, $node_title, $language_name, $clear_path_cache);
    }
  }

  /**
   * Add each language via the UI
   */
  function addLanguagesWithHierarchy($languages) {
    foreach ($languages as $langcode => $edit) {
      $edit += array(
        'langcode' => $langcode,
        'direction' => '0',
        // The domain prefix.
        'prefix' => $langcode,
      );
      $this
        ->drupalPost('admin/config/regional/language/add', $edit, t('Add custom language'));
    }
  }

  /**
   * Create paths through the UI (as opposed to calling path_save()).
   */
  function createPathsThroughUI($paths) {
    foreach ($paths as $edit) {
      $this
        ->drupalPost('admin/config/search/path/add', $edit, t('Save'));
    }
  }

  /**
   * Check that the canonical path of a path is that path, and that the
   * necessary text was found on it, proving the lookup worked in both
   * directions.
   *
   * @param string $path Path to test.
   * @param string $text Text to check.
   * @param string $language_name Language name to use in messages to display.
   * @param null $clear_path_cache If specified, clear the cache for this path.
   */
  function checkCanonicalPathAndText($path, $text, $language_name, $clear_path_cache = NULL) {
    global $base_path;
    if ($clear_path_cache) {
      cache_clear_all($clear_path_cache, 'cache_path');
    }
    $this
      ->drupalGet($path);
    $message = $language_name . ' alias';
    if (!$clear_path_cache) {
      $message .= ' from cache';
    }
    $message .= ' is correctly matched for the canonical URL.';
    $href = $path;
    if (empty($this->originalCleanUrl)) {
      $href = '?q=' . $href;
    }
    $href = $base_path . $href;
    $this
      ->assertRaw('<link rel="canonical" href="' . $href . '" />', $message);
    $this
      ->assertText($text, $language_name . ' alias was matched to the correct page.');
  }

  /**
   * Directly check the alias for a system path in a given language.
   */
  function checkDirectLookup($langcode, $system_path, $alias, $message = '') {
    $lookup_path = $this->pathinc_singleton
      ->drupal_lookup_path('alias', $system_path, $langcode);
    $this
      ->assertEqual($alias, $lookup_path, $message);
  }

}

Classes

Namesort descending Description
LanguageHierarchyPathsFunctionalTest Functional tests for configuring a different path alias per language.