You are here

redirect.test in Redirect 7

Same filename and directory in other branches
  1. 7.2 redirect.test

Unit tests for the redirect module.

File

redirect.test
View source
<?php

/**
 * @file
 * Unit tests for the redirect module.
 */
class RedirectTestHelper extends DrupalWebTestCase {
  function setUp(array $modules = array()) {
    array_unshift($modules, 'redirect');
    parent::setUp($modules);
  }
  protected function assertRedirect($redirect) {
    $source_url = url($redirect->source, array(
      'absolute' => TRUE,
    ) + $redirect->source_options);
    $redirect_url = url($redirect->redirect, array(
      'absolute' => TRUE,
    ) + $redirect->redirect_options);
    $this
      ->drupalGet($source_url);
    $this
      ->assertEqual($this
      ->getUrl(), $redirect_url, t('Page %source was redirected to %redirect.', array(
      '%source' => $source_url,
      '%redirect' => $redirect_url,
    )));

    // Reload the redirect.
    if (!empty($redirect->rid)) {
      return redirect_load($redirect->rid);
    }
  }
  protected function assertNoRedirect($redirect) {
    $source_url = url($redirect->source, array(
      'absolute' => TRUE,
    ) + $redirect->source_options);
    $this
      ->drupalGet($source_url);
    $this
      ->assertEqual($this
      ->getUrl(), $source_url, t('Page %url was not redirected.', array(
      '%url' => $source_url,
    )));
  }

  /**
   * Add an URL redirection
   *
   * @param $source
   *   A source path.
   * @param $redirect
   *   A redirect path.
   */
  protected function addRedirect($source_path, $redirect_path, array $redirect = array()) {
    $source_parsed = redirect_parse_url($source_path);
    $redirect['source'] = $source_parsed['url'];
    if (isset($source_parsed['query'])) {
      $redirect['source_options']['query'] = $source_parsed['query'];
    }
    $redirect_parsed = redirect_parse_url($redirect_path);
    $redirect['redirect'] = $redirect_parsed['url'];
    if (isset($redirect_parsed['query'])) {
      $redirect['redirect_options']['query'] = $redirect_parsed['query'];
    }
    if (isset($redirect_parsed['fragment'])) {
      $redirect['redirect_options']['fragment'] = $redirect_parsed['fragment'];
    }
    $redirect_object = new stdClass();
    redirect_object_prepare($redirect_object, $redirect);
    redirect_save($redirect_object);
    return $redirect_object;
  }
  protected function assertPageCached($url, array $options = array()) {
    $options['absolute'] = TRUE;
    $url = url($url, $options);
    $cache = cache_get($url, 'cache_page');
    $this
      ->assertTrue($cache, t('Page %url was cached.', array(
      '%url' => $url,
    )));
    return $cache;
  }
  protected function assertPageNotCached($url, array $options = array()) {
    $options['absolute'] = TRUE;
    $url = url($url, $options);
    $cache = cache_get($url, 'cache_page');
    $this
      ->assertFalse($cache, t('Page %url was not cached.', array(
      '%url' => $url,
    )));
  }
  protected function assertHeader($name, $expected, $headers = NULL) {
    if (!isset($headers)) {
      $headers = $this
        ->drupalGetHeaders();
      $name = strtolower($name);
    }
    return $this
      ->assertIdentical($headers[$name], $expected);
  }

}
class RedirectUnitTest extends RedirectTestHelper {
  public static function getInfo() {
    return array(
      'name' => 'Redirect unit tests',
      'description' => 'Test basic functions and functionality.',
      'group' => 'Redirect',
    );
  }

  /**
   * Test the redirect_compare_array_recursive() function.
   */
  function testCompareArrayRecursive() {
    $haystack = array(
      'a' => 'aa',
      'b' => 'bb',
      'c' => array(
        'c1' => 'cc1',
        'c2' => 'cc2',
      ),
    );
    $cases = array(
      array(
        'query' => array(
          'a' => 'aa',
          'b' => 'invalid',
        ),
        'result' => FALSE,
      ),
      array(
        'query' => array(
          'b' => 'bb',
          'b' => 'bb',
        ),
        'result' => TRUE,
      ),
      array(
        'query' => array(
          'b' => 'bb',
          'c' => 'invalid',
        ),
        'result' => FALSE,
      ),
      array(
        'query' => array(
          'b' => 'bb',
          'c' => array(),
        ),
        'result' => TRUE,
      ),
      array(
        'query' => array(
          'b' => 'bb',
          'c' => array(
            'invalid',
          ),
        ),
        'result' => FALSE,
      ),
      array(
        'query' => array(
          'b' => 'bb',
          'c' => array(
            'c2' => 'invalid',
          ),
        ),
        'result' => FALSE,
      ),
      array(
        'query' => array(
          'b' => 'bb',
          'c' => array(
            'c2' => 'cc2',
          ),
        ),
        'result' => TRUE,
      ),
    );
    foreach ($cases as $index => $case) {
      $this
        ->assertEqual($case['result'], redirect_compare_array_recursive($case['query'], $haystack));
    }
  }

  /**
   * Test redirect_sort_recursive().
   */
  function testSortRecursive() {
    $test_cases = array(
      array(
        'input' => array(
          'b' => 'aa',
          'c' => array(
            'c2' => 'aa',
            'c1' => 'aa',
          ),
          'a' => 'aa',
        ),
        'expected' => array(
          'a' => 'aa',
          'b' => 'aa',
          'c' => array(
            'c1' => 'aa',
            'c2' => 'aa',
          ),
        ),
        'callback' => 'ksort',
      ),
    );
    foreach ($test_cases as $index => $test_case) {
      $output = $test_case['input'];
      redirect_sort_recursive($output, $test_case['callback']);
      $this
        ->assertIdentical($output, $test_case['expected']);
    }
  }

  /**
   * Test redirect_load_by_source().
   */
  public function testLoadRedirectsBySource() {
    $redirects = array(
      'source-path?param1=1&param2=2' => 'redirect-path-1',
      'source-path' => 'redirect-path-2',
      'source-path?param1=1' => 'redirect-path-3',
    );

    // Add redirects.
    foreach ($redirects as $source_path => $redirect_path) {
      $this
        ->addRedirect($source_path, $redirect_path);
    }

    // Load redirects by source.
    foreach ($redirects as $source_path => $redirect_path) {
      $source_parsed = redirect_parse_url($source_path);
      if (!isset($source_parsed['query'])) {
        $source_parsed['query'] = array();
      }
      $redirect = redirect_load_by_source($source_parsed['url'], LANGUAGE_NONE, $source_parsed['query']);
      $this
        ->assertEqual($redirect->redirect, $redirect_path, t('The redirect path %redirect equals expected result %result.', array(
        '%redirect' => $redirect->redirect,
        '%result' => $redirect_path,
      )));
    }
  }

  /**
   * Test redirect_parse_url().
   */
  function testParseURL() {
    $clean_url = variable_get('clean_url', 0);
    $test_case_groups = array(
      // Tests to be run with Clean URLs on.
      array(
        'clean_url' => 1,
        'test_cases' => array(
          array(
            'input' => 'base?param1=1',
            'expected' => array(
              'path' => 'base',
              'query' => array(
                'param1' => '1',
              ),
              'url' => 'base',
            ),
          ),
        ),
      ),
      // Tests to be run with Clean URLs off.
      array(
        'clean_url' => 0,
        'test_cases' => array(
          array(
            'input' => 'base&param1=1',
            'expected' => array(
              'path' => 'base',
              'query' => array(
                'param1' => '1',
              ),
              'url' => 'base',
            ),
          ),
        ),
      ),
    );
    foreach ($test_case_groups as $test_case_group) {
      variable_set('clean_url', $test_case_group['clean_url']);
      foreach ($test_case_group['test_cases'] as $index => $test_case) {
        $output = redirect_parse_url($test_case['input']);
        $this
          ->assertIdentical($output, $test_case['expected']);
      }
    }

    // Return 'clean_url' to the value it had before testing.
    variable_set('clean_url', $clean_url);
  }

}
class RedirectFunctionalTest extends RedirectTestHelper {
  private $admin_user;
  public static function getInfo() {
    return array(
      'name' => 'Redirect functional tests',
      'description' => 'Test interface functionality.',
      'group' => 'Redirect',
    );
  }
  function setUp(array $modules = array()) {
    parent::setUp($modules);
    $this->admin_user = $this
      ->drupalCreateUser(array(
      'administer redirects',
      'access site reports',
      'access content',
      'create article content',
      'edit any article content',
      'create url aliases',
    ));
    $this
      ->drupalLogin($this->admin_user);
  }
  function test404Interface() {

    // Check that 404 pages do get add redirect links for admin users.
    $this
      ->drupalGet('invalid-path1');
    $this
      ->drupalGet('invalid-path2');
    $this
      ->assertLink('Add URL redirect from this page to another location');

    // Check that 403 pages do not get the add redirect link at all.
    $this
      ->drupalGet('admin/config/system/actions');
    $this
      ->assertNoLink('Add URL redirect from this page to another location');
    $this
      ->drupalGet('admin/reports/page-not-found');
    $this
      ->clickLink('Fix file not found (404) errors with URL redirects');

    // Check that normal users do not see the add redirect link on 404 pages.
    $this
      ->drupalLogout();
    $this
      ->drupalGet('invalid-path3');
    $this
      ->assertNoLink('Add an URL redirect from this page to another location');
  }
  function testPageCache() {

    // Set up cache variables.
    variable_set('cache', 1);
    $edit = array(
      'redirect_page_cache' => TRUE,
      'redirect_purge_inactive' => 604800,
    );
    $this
      ->drupalPost('admin/config/search/redirect/settings', $edit, 'Save configuration');
    $this
      ->assertText('The configuration options have been saved.');
    $this
      ->drupalLogout();

    // Add a new redirect.
    $redirect = $this
      ->addRedirect('redirect', 'node');
    $this
      ->assertEqual($redirect->access, 0);
    $this
      ->assertEqual($redirect->count, 0);
    $this
      ->assertPageNotCached('redirect');

    // Perform the redirect and check that last_used
    $redirect = $this
      ->assertRedirect($redirect);
    $this
      ->assertEqual($redirect->count, 1);
    $this
      ->assertTrue($redirect->access > 0);
    $cache = $this
      ->assertPageCached('redirect');
    $this
      ->assertHeader('Location', url('node', array(
      'absolute' => TRUE,
    )), $cache->data['headers']);
    $this
      ->assertHeader('X-Redirect-ID', $redirect->rid, $cache->data['headers']);

    // Set a redirect to not used in a while and disable running bootstrap
    // hooks during cache page serve. Running cron to remove inactive redirects
    // should not remove since they cannot be tracked.
    $redirect->access = 1;
    redirect_save($redirect);
    variable_set('page_cache_invoke_hooks', FALSE);
    $this
      ->cronRun();
    $this
      ->assertRedirect($redirect);
    $redirect->access = 1;
    redirect_save($redirect);
    variable_set('page_cache_invoke_hooks', TRUE);
    $this
      ->cronRun();
    $this
      ->assertNoRedirect($redirect);
  }
  function testPathChangeRedirects() {

    // Create an initial article node with a path alias.
    $node = $this
      ->drupalCreateNode(array(
      'type' => 'article',
      'path' => array(
        'alias' => 'first-alias',
      ),
    ));

    // Change the node's alias will create an automatic redirect from 'first-alias' to the node.
    $this
      ->drupalPost("node/{$node->nid}/edit", array(
      'path[alias]' => 'second-alias',
    ), t('Save'));
    $this
      ->drupalGet('first-alias');
    $this
      ->assertText($node->title);
    $this
      ->drupalPost("node/{$node->nid}/edit", array(
      'path[alias]' => 'first-alias',
    ), t('Save'));
    $this
      ->assertResponse(200, "Changing node's alias back to 'first-alias' does not break page load with a circular redirect.");
    $this
      ->assertNoText('Infinite redirect loop prevented.');
    $this
      ->drupalGet('second-alias');
    $this
      ->assertText($node->title);
    $this
      ->drupalPost("node/{$node->nid}/edit", array(
      'path[alias]' => 'second-alias',
    ), t('Save'));
    $this
      ->assertResponse(200, "Changing node's alias back to 'second-alias' does not break page load with a circular redirect.");
    $this
      ->assertNoText('Infinite redirect loop prevented.');

    // Check that first-alias redirect has been re-enabled.
    $this
      ->drupalGet('first-alias');
    $this
      ->assertText($node->title);
  }
  function testPathAddOverwriteRedirects() {

    // Create an initial article node with a path alias.
    $first_node = $this
      ->drupalCreateNode(array(
      'type' => 'article',
      'path' => array(
        'alias' => 'first-alias',
      ),
    ));

    // Change the node's alias will create an automatic redirect from 'first-alias' to the node.
    $this
      ->drupalPost("node/{$first_node->nid}/edit", array(
      'path[alias]' => 'second-alias',
    ), t('Save'));

    // Now create a second article node with the same alias as the redirect
    // created above.
    $second_node = $this
      ->drupalCreateNode(array(
      'type' => 'article',
      'path' => array(
        'alias' => 'first-alias',
      ),
    ));

    // Visit the path 'first-alias' which should be an alias for $second_node.
    $this
      ->drupalGet('first-alias');
    $this
      ->assertNoText($first_node->title, 'Adding a new path alias that matches an existing redirect disables the redirect.');
    $this
      ->assertText($second_node->title, 'Adding a new path alias that matches an existing redirect disables the redirect.');
  }
  function testDisableEnableRedirect() {

    // Add a new redirect.
    $redirect = $this
      ->addRedirect('redirect', 'node');

    // Check that it is enabled.
    $this
      ->assertEqual($redirect->status, 1);

    // Disable the redirect.
    $edit = array(
      'status' => FALSE,
    );
    $this
      ->drupalPost("admin/config/search/redirect/edit/{$redirect->rid}", $edit, t('Save'));
    $redirect = redirect_load($redirect->rid);

    // Check that it has been disabled.
    $this
      ->assertEqual($redirect->status, 0);
    $this
      ->drupalGet("admin/config/search/redirect/edit/{$redirect->rid}");
    $this
      ->assertNoFieldChecked('edit-status', 'status is unchecked');
    $this
      ->assertNoRedirect($redirect);

    // Re-enable the redirect.
    $edit = array(
      'status' => 1,
    );
    $this
      ->drupalPost("admin/config/search/redirect/edit/{$redirect->rid}", $edit, t('Save'));
    $this
      ->assertRedirect($redirect);
  }

}

Classes

Namesort descending Description
RedirectFunctionalTest
RedirectTestHelper @file Unit tests for the redirect module.
RedirectUnitTest