Drupal PHP Cross Reference Content Management Systems

Source: /modules/path/path.test - 537 lines - 20206 bytes - Summary - Text - Print

   1  <?php
   2  
   3  /**
   4   * @file
   5   * Tests for the Path module.
   6   */
   7  
   8  /**
   9   * Provides a base class for testing the Path module.
  10   */
  11  class PathTestCase extends DrupalWebTestCase {
  12    public static function getInfo() {
  13      return array(
  14        'name' => 'Path alias functionality',
  15        'description' => 'Add, edit, delete, and change alias and verify its consistency in the database.',
  16        'group' => 'Path',
  17      );
  18    }
  19  
  20    function setUp() {
  21      parent::setUp('path');
  22  
  23      // Create test user and login.
  24      $web_user = $this->drupalCreateUser(array('create page content', 'edit own page content', 'administer url aliases', 'create url aliases'));
  25      $this->drupalLogin($web_user);
  26    }
  27  
  28    /**
  29     * Tests the path cache.
  30     */
  31    function testPathCache() {
  32      // Create test node.
  33      $node1 = $this->drupalCreateNode();
  34  
  35      // Create alias.
  36      $edit = array();
  37      $edit['source'] = 'node/' . $node1->nid;
  38      $edit['alias'] = $this->randomName(8);
  39      $this->drupalPost('admin/config/search/path/add', $edit, t('Save'));
  40  
  41      // Visit the system path for the node and confirm a cache entry is
  42      // created.
  43      cache_clear_all('*', 'cache_path', TRUE);
  44      $this->drupalGet($edit['source']);
  45      $this->assertTrue(cache_get($edit['source'], 'cache_path'), t('Cache entry was created.'));
  46  
  47      // Visit the alias for the node and confirm a cache entry is created.
  48      cache_clear_all('*', 'cache_path', TRUE);
  49      $this->drupalGet($edit['alias']);
  50      $this->assertTrue(cache_get($edit['source'], 'cache_path'), t('Cache entry was created.'));
  51    }
  52  
  53    /**
  54     * Tests alias functionality through the admin interfaces.
  55     */
  56    function testAdminAlias() {
  57      // Create test node.
  58      $node1 = $this->drupalCreateNode();
  59  
  60      // Create alias.
  61      $edit = array();
  62      $edit['source'] = 'node/' . $node1->nid;
  63      $edit['alias'] = $this->randomName(8);
  64      $this->drupalPost('admin/config/search/path/add', $edit, t('Save'));
  65  
  66      // Confirm that the alias works.
  67      $this->drupalGet($edit['alias']);
  68      $this->assertText($node1->title, 'Alias works.');
  69      $this->assertResponse(200);
  70  
  71      // Change alias to one containing "exotic" characters.
  72      $pid = $this->getPID($edit['alias']);
  73  
  74      $previous = $edit['alias'];
  75      $edit['alias'] = "- ._~!$'\"()*@[]?&+%#,;=:" . // "Special" ASCII characters.
  76        "%23%25%26%2B%2F%3F" . // Characters that look like a percent-escaped string.
  77        "éøïвβ中國書۞"; // Characters from various non-ASCII alphabets.
  78      $this->drupalPost('admin/config/search/path/edit/' . $pid, $edit, t('Save'));
  79  
  80      // Confirm that the alias works.
  81      $this->drupalGet($edit['alias']);
  82      $this->assertText($node1->title, 'Changed alias works.');
  83      $this->assertResponse(200);
  84  
  85      drupal_static_reset('drupal_lookup_path');
  86      // Confirm that previous alias no longer works.
  87      $this->drupalGet($previous);
  88      $this->assertNoText($node1->title, 'Previous alias no longer works.');
  89      $this->assertResponse(404);
  90  
  91      // Create second test node.
  92      $node2 = $this->drupalCreateNode();
  93  
  94      // Set alias to second test node.
  95      $edit['source'] = 'node/' . $node2->nid;
  96      // leave $edit['alias'] the same
  97      $this->drupalPost('admin/config/search/path/add', $edit, t('Save'));
  98  
  99      // Confirm no duplicate was created.
 100      $this->assertRaw(t('The alias %alias is already in use in this language.', array('%alias' => $edit['alias'])), 'Attempt to move alias was rejected.');
 101  
 102      // Delete alias.
 103      $this->drupalPost('admin/config/search/path/edit/' . $pid, array(), t('Delete'));
 104      $this->drupalPost(NULL, array(), t('Confirm'));
 105  
 106      // Confirm that the alias no longer works.
 107      $this->drupalGet($edit['alias']);
 108      $this->assertNoText($node1->title, 'Alias was successfully deleted.');
 109      $this->assertResponse(404);
 110    }
 111  
 112    /**
 113     * Tests alias functionality through the node interfaces.
 114     */
 115    function testNodeAlias() {
 116      // Create test node.
 117      $node1 = $this->drupalCreateNode();
 118  
 119      // Create alias.
 120      $edit = array();
 121      $edit['path[alias]'] = $this->randomName(8);
 122      $this->drupalPost('node/' . $node1->nid . '/edit', $edit, t('Save'));
 123  
 124      // Confirm that the alias works.
 125      $this->drupalGet($edit['path[alias]']);
 126      $this->assertText($node1->title, 'Alias works.');
 127      $this->assertResponse(200);
 128  
 129      // Change alias to one containing "exotic" characters.
 130      $previous = $edit['path[alias]'];
 131      $edit['path[alias]'] = "- ._~!$'\"()*@[]?&+%#,;=:" . // "Special" ASCII characters.
 132        "%23%25%26%2B%2F%3F" . // Characters that look like a percent-escaped string.
 133        "éøïвβ中國書۞"; // Characters from various non-ASCII alphabets.
 134      $this->drupalPost('node/' . $node1->nid . '/edit', $edit, t('Save'));
 135  
 136      // Confirm that the alias works.
 137      $this->drupalGet($edit['path[alias]']);
 138      $this->assertText($node1->title, 'Changed alias works.');
 139      $this->assertResponse(200);
 140  
 141      // Make sure that previous alias no longer works.
 142      $this->drupalGet($previous);
 143      $this->assertNoText($node1->title, 'Previous alias no longer works.');
 144      $this->assertResponse(404);
 145  
 146      // Create second test node.
 147      $node2 = $this->drupalCreateNode();
 148  
 149      // Set alias to second test node.
 150      // Leave $edit['path[alias]'] the same.
 151      $this->drupalPost('node/' . $node2->nid . '/edit', $edit, t('Save'));
 152  
 153      // Confirm that the alias didn't make a duplicate.
 154      $this->assertText(t('The alias is already in use.'), 'Attempt to moved alias was rejected.');
 155  
 156      // Delete alias.
 157      $this->drupalPost('node/' . $node1->nid . '/edit', array('path[alias]' => ''), t('Save'));
 158  
 159      // Confirm that the alias no longer works.
 160      $this->drupalGet($edit['path[alias]']);
 161      $this->assertNoText($node1->title, 'Alias was successfully deleted.');
 162      $this->assertResponse(404);
 163    }
 164  
 165    /**
 166     * Returns the path ID.
 167     *
 168     * @param $alias
 169     *   A string containing an aliased path.
 170     *
 171     * @return int
 172     *   Integer representing the path ID.
 173     */
 174    function getPID($alias) {
 175      return db_query("SELECT pid FROM {url_alias} WHERE alias = :alias", array(':alias' => $alias))->fetchField();
 176    }
 177  
 178    /**
 179     * Tests that duplicate aliases fail validation.
 180     */
 181    function testDuplicateNodeAlias() {
 182      // Create one node with a random alias.
 183      $node_one = $this->drupalCreateNode();
 184      $edit = array();
 185      $edit['path[alias]'] = $this->randomName();
 186      $this->drupalPost('node/' . $node_one->nid . '/edit', $edit, t('Save'));
 187  
 188      // Now create another node and try to set the same alias.
 189      $node_two = $this->drupalCreateNode();
 190      $this->drupalPost('node/' . $node_two->nid . '/edit', $edit, t('Save'));
 191      $this->assertText(t('The alias is already in use.'));
 192      $this->assertFieldByXPath("//input[@name='path[alias]' and contains(@class, 'error')]", $edit['path[alias]'], 'Textfield exists and has the error class.');
 193    }
 194  }
 195  
 196  /**
 197   * Tests URL aliases for taxonomy terms.
 198   */
 199  class PathTaxonomyTermTestCase extends DrupalWebTestCase {
 200    public static function getInfo() {
 201      return array(
 202        'name' => 'Taxonomy term URL aliases',
 203        'description' => 'Tests URL aliases for taxonomy terms.',
 204        'group' => 'Path',
 205      );
 206    }
 207  
 208    function setUp() {
 209      parent::setUp('path', 'taxonomy');
 210  
 211      // Create and login user.
 212      $web_user = $this->drupalCreateUser(array('administer url aliases', 'administer taxonomy', 'access administration pages'));
 213      $this->drupalLogin($web_user);
 214    }
 215  
 216    /**
 217     * Tests alias functionality through the admin interfaces.
 218     */
 219    function testTermAlias() {
 220      // Create a term in the default 'Tags' vocabulary with URL alias.
 221      $vocabulary = taxonomy_vocabulary_load(1);
 222      $description = $this->randomName();;
 223      $edit = array();
 224      $edit['name'] = $this->randomName();
 225      $edit['description[value]'] = $description;
 226      $edit['path[alias]'] = $this->randomName();
 227      $this->drupalPost('admin/structure/taxonomy/' . $vocabulary->machine_name . '/add', $edit, t('Save'));
 228  
 229      // Confirm that the alias works.
 230      $this->drupalGet($edit['path[alias]']);
 231      $this->assertText($description, 'Term can be accessed on URL alias.');
 232  
 233      // Change the term's URL alias.
 234      $tid = db_query("SELECT tid FROM {taxonomy_term_data} WHERE name = :name", array(':name' => $edit['name']))->fetchField();
 235      $edit2 = array();
 236      $edit2['path[alias]'] = $this->randomName();
 237      $this->drupalPost('taxonomy/term/' . $tid . '/edit', $edit2, t('Save'));
 238  
 239      // Confirm that the changed alias works.
 240      $this->drupalGet($edit2['path[alias]']);
 241      $this->assertText($description, 'Term can be accessed on changed URL alias.');
 242  
 243      // Confirm that the old alias no longer works.
 244      $this->drupalGet($edit['path[alias]']);
 245      $this->assertNoText($description, 'Old URL alias has been removed after altering.');
 246      $this->assertResponse(404, 'Old URL alias returns 404.');
 247  
 248      // Remove the term's URL alias.
 249      $edit3 = array();
 250      $edit3['path[alias]'] = '';
 251      $this->drupalPost('taxonomy/term/' . $tid . '/edit', $edit3, t('Save'));
 252  
 253      // Confirm that the alias no longer works.
 254      $this->drupalGet($edit2['path[alias]']);
 255      $this->assertNoText($description, 'Old URL alias has been removed after altering.');
 256      $this->assertResponse(404, 'Old URL alias returns 404.');
 257    }
 258  }
 259  
 260  /**
 261   * Tests URL aliases for translated nodes.
 262   */
 263  class PathLanguageTestCase extends DrupalWebTestCase {
 264    public static function getInfo() {
 265      return array(
 266        'name' => 'Path aliases with translated nodes',
 267        'description' => 'Confirm that paths work with translated nodes',
 268        'group' => 'Path',
 269      );
 270    }
 271  
 272    function setUp() {
 273      parent::setUp('path', 'locale', 'translation');
 274  
 275      // Create and login user.
 276      $this->web_user = $this->drupalCreateUser(array('edit any page content', 'create page content', 'administer url aliases', 'create url aliases', 'administer languages', 'translate content', 'access administration pages'));
 277      $this->drupalLogin($this->web_user);
 278  
 279      // Enable French language.
 280      $edit = array();
 281      $edit['langcode'] = 'fr';
 282  
 283      $this->drupalPost('admin/config/regional/language/add', $edit, t('Add language'));
 284  
 285      // Enable URL language detection and selection.
 286      $edit = array('language[enabled][locale-url]' => 1);
 287      $this->drupalPost('admin/config/regional/language/configure', $edit, t('Save settings'));
 288    }
 289  
 290    /**
 291     * Test alias functionality through the admin interfaces.
 292     */
 293    function testAliasTranslation() {
 294      // Set 'page' content type to enable translation.
 295      variable_set('language_content_type_page', 2);
 296  
 297      $english_node = $this->drupalCreateNode(array('type' => 'page'));
 298      $english_alias = $this->randomName();
 299  
 300      // Edit the node to set language and path.
 301      $edit = array();
 302      $edit['language'] = 'en';
 303      $edit['path[alias]'] = $english_alias;
 304      $this->drupalPost('node/' . $english_node->nid . '/edit', $edit, t('Save'));
 305  
 306      // Confirm that the alias works.
 307      $this->drupalGet($english_alias);
 308      $this->assertText($english_node->title, 'Alias works.');
 309  
 310      // Translate the node into French.
 311      $this->drupalGet('node/' . $english_node->nid . '/translate');
 312      $this->clickLink(t('add translation'));
 313      $edit = array();
 314      $langcode = LANGUAGE_NONE;
 315      $edit["title"] = $this->randomName();
 316      $edit["body[$langcode][0][value]"] = $this->randomName();
 317      $french_alias = $this->randomName();
 318      $edit['path[alias]'] = $french_alias;
 319      $this->drupalPost(NULL, $edit, t('Save'));
 320  
 321      // Clear the path lookup cache.
 322      drupal_lookup_path('wipe');
 323  
 324      // Ensure the node was created.
 325      $french_node = $this->drupalGetNodeByTitle($edit["title"]);
 326      $this->assertTrue(($french_node), 'Node found in database.');
 327  
 328      // Confirm that the alias works.
 329      $this->drupalGet('fr/' . $edit['path[alias]']);
 330      $this->assertText($french_node->title, 'Alias for French translation works.');
 331  
 332      // Confirm that the alias is returned by url().
 333      drupal_static_reset('language_list');
 334      drupal_static_reset('locale_url_outbound_alter');
 335      $languages = language_list();
 336      $url = url('node/' . $french_node->nid, array('language' => $languages[$french_node->language]));
 337      $this->assertTrue(strpos($url, $edit['path[alias]']), t('URL contains the path alias.'));
 338  
 339      // Confirm that the alias works even when changing language negotiation
 340      // options. Enable User language detection and selection over URL one.
 341      $edit = array(
 342        'language[enabled][locale-user]' => 1,
 343        'language[weight][locale-user]' => -9,
 344        'language[enabled][locale-url]' => 1,
 345        'language[weight][locale-url]' => -8,
 346      );
 347      $this->drupalPost('admin/config/regional/language/configure', $edit, t('Save settings'));
 348  
 349      // Change user language preference.
 350      $edit = array('language' => 'fr');
 351      $this->drupalPost("user/{$this->web_user->uid}/edit", $edit, t('Save'));
 352  
 353      // Check that the English alias works. In this situation French is the
 354      // current UI and content language, while URL language is English (since we
 355      // do not have a path prefix we fall back to the site's default language).
 356      // We need to ensure that the user language preference is not taken into
 357      // account while determining the path alias language, because if this
 358      // happens we have no way to check that the path alias is valid: there is no
 359      // path alias for French matching the english alias. So drupal_lookup_path()
 360      // needs to use the URL language to check whether the alias is valid.
 361      $this->drupalGet($english_alias);
 362      $this->assertText($english_node->title, 'Alias for English translation works.');
 363  
 364      // Check that the French alias works.
 365      $this->drupalGet("fr/$french_alias");
 366      $this->assertText($french_node->title, 'Alias for French translation works.');
 367  
 368      // Disable URL language negotiation.
 369      $edit = array('language[enabled][locale-url]' => FALSE);
 370      $this->drupalPost('admin/config/regional/language/configure', $edit, t('Save settings'));
 371  
 372      // Check that the English alias still works.
 373      $this->drupalGet($english_alias);
 374      $this->assertText($english_node->title, 'Alias for English translation works.');
 375  
 376      // Check that the French alias is not available. We check the unprefixed
 377      // alias because we disabled URL language negotiation above. In this
 378      // situation only aliases in the default language and language neutral ones
 379      // should keep working.
 380      $this->drupalGet($french_alias);
 381      $this->assertResponse(404, t('Alias for French translation is unavailable when URL language negotiation is disabled.'));
 382  
 383      // drupal_lookup_path() has an internal static cache. Check to see that
 384      // it has the appropriate contents at this point.
 385      drupal_lookup_path('wipe');
 386      $french_node_path = drupal_lookup_path('source', $french_alias, $french_node->language);
 387      $this->assertEqual($french_node_path, 'node/' . $french_node->nid, t('Normal path works.'));
 388      // Second call should return the same path.
 389      $french_node_path = drupal_lookup_path('source', $french_alias, $french_node->language);
 390      $this->assertEqual($french_node_path, 'node/' . $french_node->nid, t('Normal path is the same.'));
 391  
 392      // Confirm that the alias works.
 393      $french_node_alias = drupal_lookup_path('alias', 'node/' . $french_node->nid, $french_node->language);
 394      $this->assertEqual($french_node_alias, $french_alias, t('Alias works.'));
 395      // Second call should return the same alias.
 396      $french_node_alias = drupal_lookup_path('alias', 'node/' . $french_node->nid, $french_node->language);
 397      $this->assertEqual($french_node_alias, $french_alias, t('Alias is the same.'));
 398    }
 399  }
 400  
 401  /**
 402   * Tests the user interface for creating path aliases, with languages.
 403   */
 404  class PathLanguageUITestCase extends DrupalWebTestCase {
 405    public static function getInfo() {
 406      return array(
 407        'name' => 'Path aliases with languages',
 408        'description' => 'Confirm that the Path module user interface works with languages.',
 409        'group' => 'Path',
 410      );
 411    }
 412  
 413    function setUp() {
 414      parent::setUp('path', 'locale');
 415  
 416      // Create and login user.
 417      $web_user = $this->drupalCreateUser(array('edit any page content', 'create page content', 'administer url aliases', 'create url aliases', 'administer languages', 'access administration pages'));
 418      $this->drupalLogin($web_user);
 419  
 420      // Enable French language.
 421      $edit = array();
 422      $edit['langcode'] = 'fr';
 423  
 424      $this->drupalPost('admin/config/regional/language/add', $edit, t('Add language'));
 425  
 426      // Enable URL language detection and selection.
 427      $edit = array('language[enabled][locale-url]' => 1);
 428      $this->drupalPost('admin/config/regional/language/configure', $edit, t('Save settings'));
 429    }
 430  
 431    /**
 432     * Tests that a language-neutral URL alias works.
 433     */
 434    function testLanguageNeutralURLs() {
 435      $name = $this->randomName(8);
 436      $edit = array();
 437      $edit['source'] = 'admin/config/search/path';
 438      $edit['alias'] = $name;
 439      $this->drupalPost('admin/config/search/path/add', $edit, t('Save'));
 440  
 441      $this->drupalGet($name);
 442      $this->assertText(t('Filter aliases'), 'Language-neutral URL alias works');
 443    }
 444  
 445    /**
 446     * Tests that a default language URL alias works.
 447     */
 448    function testDefaultLanguageURLs() {
 449      $name = $this->randomName(8);
 450      $edit = array();
 451      $edit['source'] = 'admin/config/search/path';
 452      $edit['alias'] = $name;
 453      $edit['language'] = 'en';
 454      $this->drupalPost('admin/config/search/path/add', $edit, t('Save'));
 455  
 456      $this->drupalGet($name);
 457      $this->assertText(t('Filter aliases'), 'English URL alias works');
 458    }
 459  
 460    /**
 461     * Tests that a non-default language URL alias works.
 462     */
 463    function testNonDefaultURLs() {
 464      $name = $this->randomName(8);
 465      $edit = array();
 466      $edit['source'] = 'admin/config/search/path';
 467      $edit['alias'] = $name;
 468      $edit['language'] = 'fr';
 469      $this->drupalPost('admin/config/search/path/add', $edit, t('Save'));
 470  
 471      $this->drupalGet('fr/' . $name);
 472      $this->assertText(t('Filter aliases'), 'Foreign URL alias works');
 473    }
 474  
 475  }
 476  
 477  /**
 478   * Tests that paths are not prefixed on a monolingual site.
 479   */
 480  class PathMonolingualTestCase extends DrupalWebTestCase {
 481    public static function getInfo() {
 482      return array(
 483        'name' => 'Paths on non-English monolingual sites',
 484        'description' => 'Confirm that paths are not changed on monolingual non-English sites',
 485        'group' => 'Path',
 486      );
 487    }
 488  
 489    function setUp() {
 490      global $language;
 491      parent::setUp('path', 'locale', 'translation');
 492  
 493      // Create and login user.
 494      $web_user = $this->drupalCreateUser(array('administer languages', 'access administration pages'));
 495      $this->drupalLogin($web_user);
 496  
 497      // Enable French language.
 498      $edit = array();
 499      $edit['langcode'] = 'fr';
 500      $this->drupalPost('admin/config/regional/language/add', $edit, t('Add language'));
 501  
 502      // Make French the default language.
 503      $edit = array('site_default' => 'fr');
 504      $this->drupalPost('admin/config/regional/language', $edit, t('Save configuration'));
 505  
 506      // Disable English.
 507      $edit = array('enabled[en]' => FALSE);
 508      $this->drupalPost('admin/config/regional/language', $edit, t('Save configuration'));
 509  
 510      // Verify that French is the only language.
 511      $this->assertFalse(drupal_multilingual(), t('Site is mono-lingual'));
 512      $this->assertEqual(language_default('language'), 'fr', t('French is the default language'));
 513  
 514      // Set language detection to URL.
 515      $edit = array('language[enabled][locale-url]' => TRUE);
 516      $this->drupalPost('admin/config/regional/language/configure', $edit, t('Save settings'));
 517  
 518      // Force languages to be initialized.
 519      drupal_language_initialize();
 520    }
 521  
 522    /**
 523     * Verifies that links do not have language prefixes in them.
 524     */
 525    function testPageLinks() {
 526      // Navigate to 'admin/config' path.
 527      $this->drupalGet('admin/config');
 528  
 529      // Verify that links in this page do not have a 'fr/' prefix.
 530      $this->assertNoLinkByHref('/fr/', 'Links do not contain language prefix');
 531  
 532      // Verify that links in this page can be followed and work.
 533      $this->clickLink(t('Languages'));
 534      $this->assertResponse(200, 'Clicked link results in a valid page');
 535      $this->assertText(t('Add language'), 'Page contains the add language text');
 536    }
 537  }

title

Description

title

Description

title

Description

title

title

Body