You are here

class CommonURLUnitTest in SimpleTest 7

Tests for URL generation functions.

Hierarchy

Expanded class hierarchy of CommonURLUnitTest

File

tests/common.test, line 59
Tests for common.inc functionality.

View source
class CommonURLUnitTest extends DrupalUnitTestCase {
  public static function getInfo() {
    return array(
      'name' => 'URL generation tests',
      'description' => 'Confirm that url(), drupal_get_query_parameters(), drupal_http_build_query(), and l() work correctly with various input.',
      'group' => 'System',
    );
  }

  /**
   * Confirm that invalid text given as $path is filtered.
   */
  function testLXSS() {
    $text = $this
      ->randomName();
    $path = "<SCRIPT>alert('XSS')</SCRIPT>";
    $link = l($text, $path);
    $sanitized_path = check_url(url($path));
    $this
      ->assertTrue(strpos($link, $sanitized_path) !== FALSE, t('XSS attack @path was filtered', array(
      '@path' => $path,
    )));
  }

  /**
   * Test drupal_get_query_parameters().
   */
  function testDrupalGetQueryParameters() {
    $original = array(
      'a' => 1,
      'b' => array(
        'd' => 4,
        'e' => array(
          'f' => 5,
        ),
      ),
      'c' => 3,
      'q' => 'foo/bar',
    );

    // Default arguments.
    $result = $_GET;
    unset($result['q']);
    $this
      ->assertEqual(drupal_get_query_parameters(), $result, t("\$_GET['q'] was removed."));

    // Default exclusion.
    $result = $original;
    unset($result['q']);
    $this
      ->assertEqual(drupal_get_query_parameters($original), $result, t("'q' was removed."));

    // First-level exclusion.
    $result = $original;
    unset($result['b']);
    $this
      ->assertEqual(drupal_get_query_parameters($original, array(
      'b',
    )), $result, t("'b' was removed."));

    // Second-level exclusion.
    $result = $original;
    unset($result['b']['d']);
    $this
      ->assertEqual(drupal_get_query_parameters($original, array(
      'b[d]',
    )), $result, t("'b[d]' was removed."));

    // Third-level exclusion.
    $result = $original;
    unset($result['b']['e']['f']);
    $this
      ->assertEqual(drupal_get_query_parameters($original, array(
      'b[e][f]',
    )), $result, t("'b[e][f]' was removed."));

    // Multiple exclusions.
    $result = $original;
    unset($result['a'], $result['b']['e'], $result['c']);
    $this
      ->assertEqual(drupal_get_query_parameters($original, array(
      'a',
      'b[e]',
      'c',
    )), $result, t("'a', 'b[e]', 'c' were removed."));
  }

  /**
   * Test drupal_http_build_query().
   */
  function testDrupalHttpBuildQuery() {
    $this
      ->assertEqual(drupal_http_build_query(array(
      'a' => ' &#//+%20@۞',
    )), 'a=%20%26%23//%2B%2520%40%DB%9E', t('Value was properly encoded.'));
    $this
      ->assertEqual(drupal_http_build_query(array(
      ' &#//+%20@۞' => 'a',
    )), '%20%26%23%2F%2F%2B%2520%40%DB%9E=a', t('Key was properly encoded.'));
    $this
      ->assertEqual(drupal_http_build_query(array(
      'a' => '1',
      'b' => '2',
      'c' => '3',
    )), 'a=1&b=2&c=3', t('Multiple values were properly concatenated.'));
    $this
      ->assertEqual(drupal_http_build_query(array(
      'a' => array(
        'b' => '2',
        'c' => '3',
      ),
      'd' => 'foo',
    )), 'a[b]=2&a[c]=3&d=foo', t('Nested array was properly encoded.'));
  }

  /**
   * Test drupal_parse_url().
   */
  function testDrupalParseUrl() {

    // Relative URL.
    $url = 'foo/bar?foo=bar&bar=baz&baz#foo';
    $result = array(
      'path' => 'foo/bar',
      'query' => array(
        'foo' => 'bar',
        'bar' => 'baz',
        'baz' => '',
      ),
      'fragment' => 'foo',
    );
    $this
      ->assertEqual(drupal_parse_url($url), $result, t('Relative URL parsed correctly.'));

    // Relative URL that is known to confuse parse_url().
    $url = 'foo/bar:1';
    $result = array(
      'path' => 'foo/bar:1',
      'query' => array(),
      'fragment' => '',
    );
    $this
      ->assertEqual(drupal_parse_url($url), $result, t('Relative URL parsed correctly.'));

    // Absolute URL.
    $url = '/foo/bar?foo=bar&bar=baz&baz#foo';
    $result = array(
      'path' => '/foo/bar',
      'query' => array(
        'foo' => 'bar',
        'bar' => 'baz',
        'baz' => '',
      ),
      'fragment' => 'foo',
    );
    $this
      ->assertEqual(drupal_parse_url($url), $result, t('Absolute URL parsed correctly.'));

    // External URL.
    $url = 'http://drupal.org/foo/bar?foo=bar&bar=baz&baz#foo';
    $result = array(
      'path' => 'http://drupal.org/foo/bar',
      'query' => array(
        'foo' => 'bar',
        'bar' => 'baz',
        'baz' => '',
      ),
      'fragment' => 'foo',
    );
    $this
      ->assertEqual(drupal_parse_url($url), $result, t('External URL parsed correctly.'));

    // Verify proper parsing of URLs when clean URLs are disabled.
    $result = array(
      'path' => 'foo/bar',
      'query' => array(
        'bar' => 'baz',
      ),
      'fragment' => 'foo',
    );

    // Non-clean URLs #1: Absolute URL generated by url().
    $url = $GLOBALS['base_url'] . '/?q=foo/bar&bar=baz#foo';
    $this
      ->assertEqual(drupal_parse_url($url), $result, t('Absolute URL with clean URLs disabled parsed correctly.'));

    // Non-clean URLs #2: Relative URL generated by url().
    $url = '?q=foo/bar&bar=baz#foo';
    $this
      ->assertEqual(drupal_parse_url($url), $result, t('Relative URL with clean URLs disabled parsed correctly.'));

    // Non-clean URLs #3: URL generated by url() on non-Apache webserver.
    $url = 'index.php?q=foo/bar&bar=baz#foo';
    $this
      ->assertEqual(drupal_parse_url($url), $result, t('Relative URL on non-Apache webserver with clean URLs disabled parsed correctly.'));
  }

  /**
   * Test url() with/without query, with/without fragment, absolute on/off and
   * assert all that works when clean URLs are on and off.
   */
  function testUrl() {
    global $base_url;
    foreach (array(
      FALSE,
      TRUE,
    ) as $absolute) {

      // Get the expected start of the path string.
      $base = $absolute ? $base_url . '/' : base_path();
      $absolute_string = $absolute ? 'absolute' : NULL;

      // Disable Clean URLs.
      $GLOBALS['conf']['clean_url'] = 0;
      $url = $base . '?q=node/123';
      $result = url('node/123', array(
        'absolute' => $absolute,
      ));
      $this
        ->assertEqual($url, $result, "{$url} == {$result}");
      $url = $base . '?q=node/123#foo';
      $result = url('node/123', array(
        'fragment' => 'foo',
        'absolute' => $absolute,
      ));
      $this
        ->assertEqual($url, $result, "{$url} == {$result}");
      $url = $base . '?q=node/123&foo';
      $result = url('node/123', array(
        'query' => array(
          'foo' => NULL,
        ),
        'absolute' => $absolute,
      ));
      $this
        ->assertEqual($url, $result, "{$url} == {$result}");
      $url = $base . '?q=node/123&foo=bar&bar=baz';
      $result = url('node/123', array(
        'query' => array(
          'foo' => 'bar',
          'bar' => 'baz',
        ),
        'absolute' => $absolute,
      ));
      $this
        ->assertEqual($url, $result, "{$url} == {$result}");
      $url = $base . '?q=node/123&foo#bar';
      $result = url('node/123', array(
        'query' => array(
          'foo' => NULL,
        ),
        'fragment' => 'bar',
        'absolute' => $absolute,
      ));
      $this
        ->assertEqual($url, $result, "{$url} == {$result}");
      $url = $base;
      $result = url('<front>', array(
        'absolute' => $absolute,
      ));
      $this
        ->assertEqual($url, $result, "{$url} == {$result}");

      // Enable Clean URLs.
      $GLOBALS['conf']['clean_url'] = 1;
      $url = $base . 'node/123';
      $result = url('node/123', array(
        'absolute' => $absolute,
      ));
      $this
        ->assertEqual($url, $result, "{$url} == {$result}");
      $url = $base . 'node/123#foo';
      $result = url('node/123', array(
        'fragment' => 'foo',
        'absolute' => $absolute,
      ));
      $this
        ->assertEqual($url, $result, "{$url} == {$result}");
      $url = $base . 'node/123?foo';
      $result = url('node/123', array(
        'query' => array(
          'foo' => NULL,
        ),
        'absolute' => $absolute,
      ));
      $this
        ->assertEqual($url, $result, "{$url} == {$result}");
      $url = $base . 'node/123?foo=bar&bar=baz';
      $result = url('node/123', array(
        'query' => array(
          'foo' => 'bar',
          'bar' => 'baz',
        ),
        'absolute' => $absolute,
      ));
      $this
        ->assertEqual($url, $result, "{$url} == {$result}");
      $url = $base . 'node/123?foo#bar';
      $result = url('node/123', array(
        'query' => array(
          'foo' => NULL,
        ),
        'fragment' => 'bar',
        'absolute' => $absolute,
      ));
      $this
        ->assertEqual($url, $result, "{$url} == {$result}");
      $url = $base;
      $result = url('<front>', array(
        'absolute' => $absolute,
      ));
      $this
        ->assertEqual($url, $result, "{$url} == {$result}");
    }
  }

  /**
   * Test external URL handling.
   */
  function testExternalUrls() {
    $test_url = 'http://drupal.org/';

    // Verify external URL can contain a fragment.
    $url = $test_url . '#drupal';
    $result = url($url);
    $this
      ->assertEqual($url, $result, t('External URL with fragment works without a fragment in $options.'));

    // Verify fragment can be overidden in an external URL.
    $url = $test_url . '#drupal';
    $fragment = $this
      ->randomName(10);
    $result = url($url, array(
      'fragment' => $fragment,
    ));
    $this
      ->assertEqual($test_url . '#' . $fragment, $result, t('External URL fragment is overidden with a custom fragment in $options.'));

    // Verify external URL can contain a query string.
    $url = $test_url . '?drupal=awesome';
    $result = url($url);
    $this
      ->assertEqual($url, $result, t('External URL with query string works without a query string in $options.'));

    // Verify external URL can be extended with a query string.
    $url = $test_url;
    $query = array(
      $this
        ->randomName(5) => $this
        ->randomName(5),
    );
    $result = url($url, array(
      'query' => $query,
    ));
    $this
      ->assertEqual($url . '?' . http_build_query($query, '', '&'), $result, t('External URL can be extended with a query string in $options.'));

    // Verify query string can be extended in an external URL.
    $url = $test_url . '?drupal=awesome';
    $query = array(
      $this
        ->randomName(5) => $this
        ->randomName(5),
    );
    $result = url($url, array(
      'query' => $query,
    ));
    $this
      ->assertEqual($url . '&' . http_build_query($query, '', '&'), $result, t('External URL query string can be extended with a custom query string in $options.'));
  }

}

Members

Namesort descending Modifiers Type Description Overrides
CommonURLUnitTest::getInfo public static function
CommonURLUnitTest::testDrupalGetQueryParameters function Test drupal_get_query_parameters().
CommonURLUnitTest::testDrupalHttpBuildQuery function Test drupal_http_build_query().
CommonURLUnitTest::testDrupalParseUrl function Test drupal_parse_url().
CommonURLUnitTest::testExternalUrls function Test external URL handling.
CommonURLUnitTest::testLXSS function Confirm that invalid text given as $path is filtered.
CommonURLUnitTest::testUrl function Test url() with/without query, with/without fragment, absolute on/off and assert all that works when clean URLs are on and off.
DrupalTestCase::$assertions protected property Assertions thrown in that test case.
DrupalTestCase::$originalFileDirectory protected property The original file directory, before it was changed for testing purposes.
DrupalTestCase::$originalPrefix protected property The original database prefix, before it was changed for testing purposes.
DrupalTestCase::$results public property Current results of this test case.
DrupalTestCase::$skipClasses protected property This class is skipped when looking for the source of an assertion.
DrupalTestCase::$testId protected property The test run ID.
DrupalTestCase::$timeLimit protected property Time limit for the test.
DrupalTestCase::assert protected function Internal helper: stores the assert.
DrupalTestCase::assertEqual protected function Check to see if two values are equal.
DrupalTestCase::assertFalse protected function Check to see if a value is false (an empty string, 0, NULL, or FALSE).
DrupalTestCase::assertIdentical protected function Check to see if two values are identical.
DrupalTestCase::assertNotEqual protected function Check to see if two values are not equal.
DrupalTestCase::assertNotIdentical protected function Check to see if two values are not identical.
DrupalTestCase::assertNotNull protected function Check to see if a value is not NULL.
DrupalTestCase::assertNull protected function Check to see if a value is NULL.
DrupalTestCase::assertTrue protected function Check to see if a value is not false (not an empty string, 0, NULL, or FALSE).
DrupalTestCase::error protected function Fire an error assertion. 1
DrupalTestCase::errorHandler public function Handle errors.
DrupalTestCase::exceptionHandler protected function Handle exceptions.
DrupalTestCase::fail protected function Fire an assertion that is always negative.
DrupalTestCase::getAssertionCall protected function Cycles through backtrace until the first non-assertion method is found.
DrupalTestCase::insertAssert public static function Store an assertion from outside the testing context.
DrupalTestCase::pass protected function Fire an assertion that is always positive.
DrupalTestCase::randomName public static function Generates a random string containing letters and numbers.
DrupalTestCase::randomString public static function Generates a random string of ASCII characters of codes 32 to 126.
DrupalTestCase::run public function Run all tests in this class.
DrupalUnitTestCase::setUp function 1
DrupalUnitTestCase::tearDown function
DrupalUnitTestCase::__construct function Constructor for DrupalUnitTestCase. Overrides DrupalTestCase::__construct