1771 lines
69 KiB
Plaintext
1771 lines
69 KiB
Plaintext
<?php
|
||
// $Id$
|
||
|
||
/**
|
||
* @file
|
||
* Tests for common.inc functionality.
|
||
*/
|
||
|
||
/**
|
||
* Tests for URL generation functions.
|
||
*/
|
||
class DrupalAlterTestCase extends DrupalWebTestCase {
|
||
public static function getInfo() {
|
||
return array(
|
||
'name' => 'drupal_alter() tests',
|
||
'description' => 'Confirm that alteration of arguments passed to drupal_alter() works correctly.',
|
||
'group' => 'System',
|
||
);
|
||
}
|
||
|
||
function setUp() {
|
||
parent::setUp('common_test');
|
||
}
|
||
|
||
function testDrupalAlter() {
|
||
$array = array('foo' => 'bar');
|
||
$object = new stdClass;
|
||
$object->foo = 'bar';
|
||
|
||
// Verify alteration of a single argument.
|
||
$array_copy = $array;
|
||
$array_expected = array('foo' => 'Drupal theme');
|
||
drupal_alter('drupal_alter', $array_copy);
|
||
$this->assertEqual($array_copy, $array_expected, t('Single array was altered.'));
|
||
|
||
$object_copy = clone $object;
|
||
$object_expected = clone $object;
|
||
$object_expected->foo = 'Drupal theme';
|
||
drupal_alter('drupal_alter', $object_copy);
|
||
$this->assertEqual($object_copy, $object_expected, t('Single object was altered.'));
|
||
|
||
// Verify alteration of multiple arguments.
|
||
$array_copy = $array;
|
||
$array_expected = array('foo' => 'Drupal theme');
|
||
$object_copy = clone $object;
|
||
$object_expected = clone $object;
|
||
$object_expected->foo = 'Drupal theme';
|
||
$array2_copy = $array;
|
||
$array2_expected = array('foo' => 'Drupal theme');
|
||
drupal_alter('drupal_alter', $array_copy, $object_copy, $array2_copy);
|
||
$this->assertEqual($array_copy, $array_expected, t('First argument to drupal_alter() was altered.'));
|
||
$this->assertEqual($object_copy, $object_expected, t('Second argument to drupal_alter() was altered.'));
|
||
$this->assertEqual($array2_copy, $array2_expected, t('Third argument to drupal_alter() was altered.'));
|
||
}
|
||
}
|
||
|
||
/**
|
||
* Tests for URL generation functions.
|
||
*
|
||
* url() calls module_implements(), which may issue a db query, which requires
|
||
* inheriting from a web test case rather than a unit test case.
|
||
*/
|
||
class CommonURLUnitTest extends DrupalWebTestCase {
|
||
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.'));
|
||
}
|
||
}
|
||
|
||
/**
|
||
* Tests for the check_plain() and filter_xss() functions.
|
||
*/
|
||
class CommonXssUnitTest extends DrupalUnitTestCase {
|
||
|
||
public static function getInfo() {
|
||
return array(
|
||
'name' => 'String filtering tests',
|
||
'description' => 'Confirm that check_plain() and filter_xss() work correctly, including invalid multi-byte sequences.',
|
||
'group' => 'System',
|
||
);
|
||
}
|
||
|
||
/**
|
||
* Check that invalid multi-byte sequences are rejected.
|
||
*/
|
||
function testInvalidMultiByte() {
|
||
$text = check_plain("Foo\xC0barbaz");
|
||
$this->assertEqual($text, '', 'check_plain() rejects invalid sequence "Foo\xC0barbaz"');
|
||
$text = check_plain("Fooÿñ");
|
||
$this->assertEqual($text, "Fooÿñ", 'check_plain() accepts valid sequence "Fooÿñ"');
|
||
$text = filter_xss("Foo\xC0barbaz");
|
||
$this->assertEqual($text, '', 'filter_xss() rejects invalid sequence "Foo\xC0barbaz"');
|
||
$text = filter_xss("Fooÿñ");
|
||
$this->assertEqual($text, "Fooÿñ", 'filter_xss() accepts valid sequence Fooÿñ');
|
||
}
|
||
|
||
/**
|
||
* Check that special characters are escaped.
|
||
*/
|
||
function testEscaping() {
|
||
$text = check_plain("<script>");
|
||
$this->assertEqual($text, '<script>', 'check_plain() escapes <script>');
|
||
}
|
||
}
|
||
|
||
class CommonSizeTestCase extends DrupalUnitTestCase {
|
||
protected $exact_test_cases;
|
||
protected $rounded_test_cases;
|
||
|
||
public static function getInfo() {
|
||
return array(
|
||
'name' => 'Size parsing test',
|
||
'description' => 'Parse a predefined amount of bytes and compare the output with the expected value.',
|
||
'group' => 'System'
|
||
);
|
||
}
|
||
|
||
function setUp() {
|
||
$kb = DRUPAL_KILOBYTE;
|
||
$this->exact_test_cases = array(
|
||
'1 byte' => 1,
|
||
'1 KB' => $kb,
|
||
'1 MB' => $kb * $kb,
|
||
'1 GB' => $kb * $kb * $kb,
|
||
'1 TB' => $kb * $kb * $kb * $kb,
|
||
'1 PB' => $kb * $kb * $kb * $kb * $kb,
|
||
'1 EB' => $kb * $kb * $kb * $kb * $kb * $kb,
|
||
'1 ZB' => $kb * $kb * $kb * $kb * $kb * $kb * $kb,
|
||
'1 YB' => $kb * $kb * $kb * $kb * $kb * $kb * $kb * $kb,
|
||
);
|
||
$this->rounded_test_cases = array(
|
||
'2 bytes' => 2,
|
||
'1 MB' => ($kb * $kb) - 1, // rounded to 1 MB (not 1000 or 1024 kilobyte!)
|
||
round(3623651 / ($this->exact_test_cases['1 MB']), 2) . ' MB' => 3623651, // megabytes
|
||
round(67234178751368124 / ($this->exact_test_cases['1 PB']), 2) . ' PB' => 67234178751368124, // petabytes
|
||
round(235346823821125814962843827 / ($this->exact_test_cases['1 YB']), 2) . ' YB' => 235346823821125814962843827, // yottabytes
|
||
);
|
||
parent::setUp();
|
||
}
|
||
|
||
/**
|
||
* Check that format_size() returns the expected string.
|
||
*/
|
||
function testCommonFormatSize() {
|
||
foreach (array($this->exact_test_cases, $this->rounded_test_cases) as $test_cases) {
|
||
foreach ($test_cases as $expected => $input) {
|
||
$this->assertEqual(
|
||
($result = format_size($input, NULL)),
|
||
$expected,
|
||
$expected . ' == ' . $result . ' (' . $input . ' bytes)'
|
||
);
|
||
}
|
||
}
|
||
}
|
||
|
||
/**
|
||
* Check that parse_size() returns the proper byte sizes.
|
||
*/
|
||
function testCommonParseSize() {
|
||
foreach ($this->exact_test_cases as $string => $size) {
|
||
$this->assertEqual(
|
||
$parsed_size = parse_size($string),
|
||
$size,
|
||
$size . ' == ' . $parsed_size . ' (' . $string . ')'
|
||
);
|
||
}
|
||
|
||
// Some custom parsing tests
|
||
$string = '23476892 bytes';
|
||
$this->assertEqual(
|
||
($parsed_size = parse_size($string)),
|
||
$size = 23476892,
|
||
$string . ' == ' . $parsed_size . ' bytes'
|
||
);
|
||
$string = '76MRandomStringThatShouldBeIgnoredByParseSize.'; // 76 MB
|
||
$this->assertEqual(
|
||
$parsed_size = parse_size($string),
|
||
$size = 79691776,
|
||
$string . ' == ' . $parsed_size . ' bytes'
|
||
);
|
||
$string = '76.24 Giggabyte'; // Misspeld text -> 76.24 GB
|
||
$this->assertEqual(
|
||
$parsed_size = parse_size($string),
|
||
$size = 81862076662,
|
||
$string . ' == ' . $parsed_size . ' bytes'
|
||
);
|
||
}
|
||
|
||
/**
|
||
* Cross-test parse_size() and format_size().
|
||
*/
|
||
function testCommonParseSizeFormatSize() {
|
||
foreach ($this->exact_test_cases as $size) {
|
||
$this->assertEqual(
|
||
$size,
|
||
($parsed_size = parse_size($string = format_size($size, NULL))),
|
||
$size . ' == ' . $parsed_size . ' (' . $string . ')'
|
||
);
|
||
}
|
||
}
|
||
}
|
||
|
||
/**
|
||
* Test drupal_explode_tags() and drupal_implode_tags().
|
||
*/
|
||
class DrupalTagsHandlingTestCase extends DrupalWebTestCase {
|
||
var $validTags = array(
|
||
'Drupal' => 'Drupal',
|
||
'Drupal with some spaces' => 'Drupal with some spaces',
|
||
'"Legendary Drupal mascot of doom: ""Druplicon"""' => 'Legendary Drupal mascot of doom: "Druplicon"',
|
||
'"Drupal, although it rhymes with sloopal, is as awesome as a troopal!"' => 'Drupal, although it rhymes with sloopal, is as awesome as a troopal!',
|
||
);
|
||
|
||
public static function getInfo() {
|
||
return array(
|
||
'name' => 'Drupal tags handling',
|
||
'description' => "Performs tests on Drupal's handling of tags, both explosion and implosion tactics used.",
|
||
'group' => 'System'
|
||
);
|
||
}
|
||
|
||
/**
|
||
* Explode a series of tags.
|
||
*/
|
||
function testDrupalExplodeTags() {
|
||
$string = implode(', ', array_keys($this->validTags));
|
||
$tags = drupal_explode_tags($string);
|
||
$this->assertTags($tags);
|
||
}
|
||
|
||
/**
|
||
* Implode a series of tags.
|
||
*/
|
||
function testDrupalImplodeTags() {
|
||
$tags = array_values($this->validTags);
|
||
// Let's explode and implode to our heart's content.
|
||
for ($i = 0; $i < 10; $i++) {
|
||
$string = drupal_implode_tags($tags);
|
||
$tags = drupal_explode_tags($string);
|
||
}
|
||
$this->assertTags($tags);
|
||
}
|
||
|
||
/**
|
||
* Helper function: asserts that the ending array of tags is what we wanted.
|
||
*/
|
||
function assertTags($tags) {
|
||
$original = $this->validTags;
|
||
foreach ($tags as $tag) {
|
||
$key = array_search($tag, $original);
|
||
$this->assertTrue($key, t('Make sure tag %tag shows up in the final tags array (originally %original)', array('%tag' => $tag, '%original' => $key)));
|
||
unset($original[$key]);
|
||
}
|
||
foreach ($original as $leftover) {
|
||
$this->fail(t('Leftover tag %leftover was left over.', array('%leftover' => $leftover)));
|
||
}
|
||
}
|
||
}
|
||
|
||
/**
|
||
* Test the Drupal CSS system.
|
||
*/
|
||
class CascadingStylesheetsTestCase extends DrupalWebTestCase {
|
||
public static function getInfo() {
|
||
return array(
|
||
'name' => 'Cascading stylesheets',
|
||
'description' => 'Tests adding various cascading stylesheets to the page.',
|
||
'group' => 'System',
|
||
);
|
||
}
|
||
|
||
function setUp() {
|
||
parent::setUp('php', 'locale');
|
||
// Reset drupal_add_css() before each test.
|
||
drupal_static_reset('drupal_add_css');
|
||
}
|
||
|
||
/**
|
||
* Check default stylesheets as empty.
|
||
*/
|
||
function testDefault() {
|
||
$this->assertEqual(array(), drupal_add_css(), t('Default CSS is empty.'));
|
||
}
|
||
|
||
/**
|
||
* Tests adding a file stylesheet.
|
||
*/
|
||
function testAddFile() {
|
||
$path = drupal_get_path('module', 'simpletest') . '/simpletest.css';
|
||
$css = drupal_add_css($path);
|
||
$this->assertEqual($css[$path]['data'], $path, t('Adding a CSS file caches it properly.'));
|
||
}
|
||
|
||
/**
|
||
* Tests adding an external stylesheet.
|
||
*/
|
||
function testAddExternal() {
|
||
$path = 'http://example.com/style.css';
|
||
$css = drupal_add_css($path, 'external');
|
||
$this->assertEqual($css[$path]['type'], 'external', t('Adding an external CSS file caches it properly.'));
|
||
}
|
||
|
||
/**
|
||
* Makes sure that reseting the CSS empties the cache.
|
||
*/
|
||
function testReset() {
|
||
drupal_static_reset('drupal_add_css');
|
||
$this->assertEqual(array(), drupal_add_css(), t('Resetting the CSS empties the cache.'));
|
||
}
|
||
|
||
/**
|
||
* Tests rendering the stylesheets.
|
||
*/
|
||
function testRenderFile() {
|
||
$css = drupal_get_path('module', 'simpletest') . '/simpletest.css';
|
||
drupal_add_css($css);
|
||
$styles = drupal_get_css();
|
||
$this->assertTrue(strpos($styles, $css) > 0, t('Rendered CSS includes the added stylesheet.'));
|
||
}
|
||
|
||
/**
|
||
* Tests rendering an external stylesheet.
|
||
*/
|
||
function testRenderExternal() {
|
||
$css = 'http://example.com/style.css';
|
||
drupal_add_css($css, 'external');
|
||
$styles = drupal_get_css();
|
||
$this->assertTrue(strpos($styles, 'href="' . $css) > 0, t('Rendering an external CSS file.'));
|
||
}
|
||
|
||
/**
|
||
* Tests rendering inline stylesheets with preprocessing on.
|
||
*/
|
||
function testRenderInlinePreprocess() {
|
||
$css = 'body { padding: 0px; }';
|
||
$css_preprocessed = '<style type="text/css">' . drupal_load_stylesheet_content($css, TRUE) . '</style>';
|
||
drupal_add_css($css, 'inline');
|
||
$styles = drupal_get_css();
|
||
$this->assertEqual($styles, "\n" . $css_preprocessed . "\n", t('Rendering preprocessed inline CSS adds it to the page.'));
|
||
}
|
||
|
||
/**
|
||
* Tests rendering inline stylesheets with preprocessing off.
|
||
*/
|
||
function testRenderInlineNoPreprocess() {
|
||
$css = 'body { padding: 0px; }';
|
||
drupal_add_css($css, array('type' => 'inline', 'preprocess' => FALSE));
|
||
$styles = drupal_get_css();
|
||
$this->assertTrue(strpos($styles, $css) > 0, t('Rendering non-preprocessed inline CSS adds it to the page.'));
|
||
}
|
||
|
||
/**
|
||
* Tests rendering inline stylesheets through a full page request.
|
||
*/
|
||
function testRenderInlineFullPage() {
|
||
$css = 'body { font-size: 254px; }';
|
||
$expected = 'font-size:254px;';
|
||
|
||
// Create a node, using the PHP filter that tests drupal_add_css().
|
||
$php_format_id = db_query_range('SELECT format FROM {filter_format} WHERE name = :name', 0, 1, array(':name' => 'PHP code'))->fetchField();
|
||
$settings = array(
|
||
'type' => 'page',
|
||
'body' => array(
|
||
LANGUAGE_NONE => array(
|
||
array(
|
||
'value' => t('This tests the inline CSS!') . "<?php drupal_add_css('$css', 'inline'); ?>",
|
||
'format' => $php_format_id,
|
||
),
|
||
),
|
||
),
|
||
'promote' => 1,
|
||
);
|
||
$node = $this->drupalCreateNode($settings);
|
||
|
||
// Fetch the page.
|
||
$this->drupalGet('node/' . $node->nid);
|
||
$this->assertRaw($expected, t('Inline stylesheets appear in the full page rendering.'));
|
||
}
|
||
|
||
/**
|
||
* Test CSS ordering.
|
||
*/
|
||
function testRenderOrder() {
|
||
// A module CSS file.
|
||
drupal_add_css(drupal_get_path('module', 'simpletest') . '/simpletest.css');
|
||
// A few system CSS files, ordered in a strange way.
|
||
$system_path = drupal_get_path('module', 'system');
|
||
drupal_add_css($system_path . '/defaults.css', array('weight' => CSS_SYSTEM));
|
||
drupal_add_css($system_path . '/system.css', array('weight' => CSS_SYSTEM - 10));
|
||
drupal_add_css($system_path . '/system-menus.css', array('weight' => CSS_SYSTEM));
|
||
|
||
$expected = array(
|
||
$system_path . '/system.css',
|
||
$system_path . '/defaults.css',
|
||
$system_path . '/system-menus.css',
|
||
drupal_get_path('module', 'simpletest') . '/simpletest.css',
|
||
);
|
||
|
||
|
||
$styles = drupal_get_css();
|
||
if (preg_match_all('/href="' . preg_quote($GLOBALS['base_url'] . '/', '/') . '([^?]+)\?/', $styles, $matches)) {
|
||
$result = $matches[1];
|
||
}
|
||
else {
|
||
$result = array();
|
||
}
|
||
|
||
$this->assertIdentical($result, $expected, t('The CSS files are in the expected order.'));
|
||
}
|
||
|
||
/**
|
||
* Test CSS override.
|
||
*/
|
||
function testRenderOverride() {
|
||
drupal_add_css(drupal_get_path('module', 'system') . '/system.css');
|
||
drupal_add_css(drupal_get_path('module', 'simpletest') . '/tests/system.css');
|
||
|
||
// The dummy stylesheet should be the only one included.
|
||
$styles = drupal_get_css();
|
||
$this->assert(strpos($styles, drupal_get_path('module', 'simpletest') . '/tests/system.css') !== FALSE, t('The overriding CSS file is output.'));
|
||
$this->assert(strpos($styles, drupal_get_path('module', 'system') . '/system.css') === FALSE, t('The overriden CSS file is not output.'));
|
||
|
||
drupal_add_css(drupal_get_path('module', 'simpletest') . '/tests/system.css');
|
||
drupal_add_css(drupal_get_path('module', 'system') . '/system.css');
|
||
|
||
// The standard stylesheet should be the only one included.
|
||
$styles = drupal_get_css();
|
||
$this->assert(strpos($styles, drupal_get_path('module', 'system') . '/system.css') !== FALSE, t('The overriding CSS file is output.'));
|
||
$this->assert(strpos($styles, drupal_get_path('module', 'simpletest') . '/tests/system.css') === FALSE, t('The overriden CSS file is not output.'));
|
||
}
|
||
|
||
/**
|
||
* Tests Locale module's CSS Alter to include RTL overrides.
|
||
*/
|
||
function testAlter() {
|
||
// Switch the language to a right to left language and add system.css.
|
||
global $language;
|
||
$language->direction = LANGUAGE_RTL;
|
||
drupal_add_css(drupal_get_path('module', 'system') . '/system.css');
|
||
|
||
// Check to see if system-rtl.css was also added.
|
||
$styles = drupal_get_css();
|
||
$this->assert(strpos($styles, drupal_get_path('module', 'system') . '/system-rtl.css') !== FALSE, t('CSS is alterable as right to left overrides are added.'));
|
||
|
||
// Change the language back to left to right.
|
||
$language->direction = LANGUAGE_LTR;
|
||
}
|
||
}
|
||
|
||
/**
|
||
* Test for cleaning HTML identifiers.
|
||
*/
|
||
class DrupalHTMLIdentifierTestCase extends DrupalUnitTestCase {
|
||
public static function getInfo() {
|
||
return array(
|
||
'name' => 'HTML identifiers',
|
||
'description' => 'Test the functions drupal_html_class(), drupal_html_id() and drupal_clean_css_identifier() for expected behavior',
|
||
'group' => 'System',
|
||
);
|
||
}
|
||
|
||
/**
|
||
* Tests that drupal_clean_css_identifier() cleans the identifier properly.
|
||
*/
|
||
function testDrupalCleanCSSIdentifier() {
|
||
// Verify that no valid ASCII characters are stripped from the identifier.
|
||
$identifier = 'abcdefghijklmnopqrstuvwxyz_ABCDEFGHIJKLMNOPQRSTUVWXYZ-0123456789';
|
||
$this->assertIdentical(drupal_clean_css_identifier($identifier, array()), $identifier, t('Verify valid ASCII characters pass through.'));
|
||
|
||
// Verify that valid UTF-8 characters are not stripped from the identifier.
|
||
$identifier = '¡¢£¤¥';
|
||
$this->assertIdentical(drupal_clean_css_identifier($identifier, array()), $identifier, t('Verify valid UTF-8 characters pass through.'));
|
||
|
||
// Verify that invalid characters (including non-breaking space) are stripped from the identifier.
|
||
$this->assertIdentical(drupal_clean_css_identifier('invalid !"#$%&\'()*+,./:;<=>?@[\\]^`{|}~ identifier', array()), 'invalididentifier', t('Strip invalid characters.'));
|
||
}
|
||
|
||
/**
|
||
* Tests that drupal_html_class() cleans the class name properly.
|
||
*/
|
||
function testDrupalHTMLClass() {
|
||
// Verify Drupal coding standards are enforced.
|
||
$this->assertIdentical(drupal_html_class('CLASS NAME_[Ü]'), 'class-name--ü', t('Enforce Drupal coding standards.'));
|
||
}
|
||
|
||
/**
|
||
* Tests that drupal_html_id() cleans the ID properly.
|
||
*/
|
||
function testDrupalHTMLId() {
|
||
// Verify that letters, digits, and hyphens are not stripped from the ID.
|
||
$id = 'abcdefghijklmnopqrstuvwxyz-0123456789';
|
||
$this->assertIdentical(drupal_html_id($id), $id, t('Verify valid characters pass through.'));
|
||
|
||
// Verify that invalid characters are stripped from the ID.
|
||
$this->assertIdentical(drupal_html_id('invalid,./:@\\^`{Üidentifier'), 'invalididentifier', t('Strip invalid characters.'));
|
||
|
||
// Verify Drupal coding standards are enforced.
|
||
$this->assertIdentical(drupal_html_id('ID NAME_[1]'), 'id-name--1', t('Enforce Drupal coding standards.'));
|
||
|
||
// Reset the static cache so we can ensure the unique id count is at zero.
|
||
drupal_static_reset('drupal_html_id');
|
||
|
||
// Clean up IDs with invalid starting characters.
|
||
$this->assertIdentical(drupal_html_id('test-unique-id'), 'test-unique-id', t('Test the uniqueness of IDs #1.'));
|
||
$this->assertIdentical(drupal_html_id('test-unique-id'), 'test-unique-id-2', t('Test the uniqueness of IDs #2.'));
|
||
$this->assertIdentical(drupal_html_id('test-unique-id'), 'test-unique-id-3', t('Test the uniqueness of IDs #3.'));
|
||
}
|
||
}
|
||
|
||
/**
|
||
* CSS Unit Tests.
|
||
*/
|
||
class CascadingStylesheetsUnitTest extends DrupalUnitTestCase {
|
||
public static function getInfo() {
|
||
return array(
|
||
'name' => 'CSS Unit Tests',
|
||
'description' => 'Unit tests on CSS functions like aggregation.',
|
||
'group' => 'System',
|
||
);
|
||
}
|
||
|
||
/**
|
||
* Tests basic CSS loading with and without optimization via drupal_load_stylesheet().
|
||
*
|
||
* This can be enhanced by adding additional CSS files with variant test cases.
|
||
* Currently, this is specifically testing to make sure that whitespace
|
||
* is treated with adequate respect (not arbitrarily removing linefeeds).
|
||
*/
|
||
function testLoadCssBasic() {
|
||
// Array of files to test living in 'simpletest/files/css_test_files/'.
|
||
// - Original: name.css
|
||
// - Unoptimized expected content: name.css.unoptimized.css
|
||
// - Optimized expected content: name.css.optimized.css
|
||
$testfiles = array(
|
||
'css_input_without_import.css',
|
||
);
|
||
$path = drupal_get_path('module', 'simpletest') . '/files/css_test_files';
|
||
foreach ($testfiles as $file) {
|
||
$expected = file_get_contents("$path/$file.unoptimized.css");
|
||
$unoptimized_output = drupal_load_stylesheet("$path/$file.unoptimized.css", FALSE);
|
||
$this->assertEqual($unoptimized_output, $expected, t('Unoptimized CSS file has expected contents (@file)', array('@file' => $file)));
|
||
|
||
$expected = file_get_contents("$path/$file.optimized.css");
|
||
$optimized_output = drupal_load_stylesheet("$path/$file", TRUE);
|
||
$this->assertEqual($optimized_output, $expected, t('Optimized CSS file has expected contents (@file)', array('@file' => $file)));
|
||
}
|
||
}
|
||
}
|
||
|
||
/**
|
||
* Test drupal_http_request().
|
||
*/
|
||
class DrupalHTTPRequestTestCase extends DrupalWebTestCase {
|
||
public static function getInfo() {
|
||
return array(
|
||
'name' => 'Drupal HTTP request',
|
||
'description' => "Performs tests on Drupal's HTTP request mechanism.",
|
||
'group' => 'System'
|
||
);
|
||
}
|
||
|
||
function setUp() {
|
||
parent::setUp('system_test');
|
||
}
|
||
|
||
function testDrupalHTTPRequest() {
|
||
global $is_https;
|
||
|
||
// Parse URL schema.
|
||
$missing_scheme = drupal_http_request('example.com/path');
|
||
$this->assertEqual($missing_scheme->code, -1002, t('Returned with "-1002" error code.'));
|
||
$this->assertEqual($missing_scheme->error, 'missing schema', t('Returned with "missing schema" error message.'));
|
||
|
||
$unable_to_parse = drupal_http_request('http:///path');
|
||
$this->assertEqual($unable_to_parse->code, -1001, t('Returned with "-1001" error code.'));
|
||
$this->assertEqual($unable_to_parse->error, 'unable to parse URL', t('Returned with "unable to parse URL" error message.'));
|
||
|
||
// Fetch page.
|
||
$result = drupal_http_request(url('node', array('absolute' => TRUE)));
|
||
$this->assertEqual($result->code, 200, t('Fetched page successfully.'));
|
||
$this->drupalSetContent($result->data);
|
||
$this->assertTitle(t('Welcome to @site-name | @site-name', array('@site-name' => variable_get('site_name', 'Drupal'))), t('Site title matches.'));
|
||
|
||
// Test that code and status message is returned.
|
||
$result = drupal_http_request(url('pagedoesnotexist', array('absolute' => TRUE)));
|
||
$this->assertTrue(!empty($result->protocol), t('Result protocol is returned.'));
|
||
$this->assertEqual($result->code, '404', t('Result code is 404'));
|
||
$this->assertEqual($result->status_message, 'Not Found', t('Result status message is "Not Found"'));
|
||
|
||
// Skip the timeout tests when the testing environment is HTTPS because
|
||
// stream_set_timeout() does not work for SSL connections.
|
||
// @link http://bugs.php.net/bug.php?id=47929
|
||
if (!$is_https) {
|
||
// Test that timeout is respected. The test machine is expected to be able
|
||
// to make the connection (i.e. complete the fsockopen()) in 2 seconds and
|
||
// return within a total of 5 seconds. If the test machine is extremely
|
||
// slow, the test will fail. fsockopen() has been seen to time out in
|
||
// slightly less than the specified timeout, so allow a little slack on
|
||
// the minimum expected time (i.e. 1.8 instead of 2).
|
||
timer_start(__METHOD__);
|
||
$result = drupal_http_request(url('system-test/sleep/10', array('absolute' => TRUE)), array('timeout' => 2));
|
||
$time = timer_read(__METHOD__) / 1000;
|
||
$this->assertTrue(1.8 < $time && $time < 5, t('Request timed out (%time seconds).', array('%time' => $time)));
|
||
$this->assertTrue($result->error, t('An error message was returned.'));
|
||
$this->assertEqual($result->code, HTTP_REQUEST_TIMEOUT, t('Proper error code was returned.'));
|
||
}
|
||
}
|
||
|
||
function testDrupalHTTPRequestBasicAuth() {
|
||
$username = $this->randomName();
|
||
$password = $this->randomName();
|
||
$url = url('system-test/auth', array('absolute' => TRUE));
|
||
|
||
$auth = str_replace('://', '://' . $username . ':' . $password . '@', $url);
|
||
$result = drupal_http_request($auth);
|
||
|
||
$this->drupalSetContent($result->data);
|
||
$this->assertRaw($username, t('$_SERVER["PHP_AUTH_USER"] is passed correctly.'));
|
||
$this->assertRaw($password, t('$_SERVER["PHP_AUTH_PW"] is passed correctly.'));
|
||
}
|
||
|
||
function testDrupalHTTPRequestRedirect() {
|
||
$redirect_301 = drupal_http_request(url('system-test/redirect/301', array('absolute' => TRUE)), array('max_redirects' => 1));
|
||
$this->assertEqual($redirect_301->redirect_code, 301, t('drupal_http_request follows the 301 redirect.'));
|
||
|
||
$redirect_301 = drupal_http_request(url('system-test/redirect/301', array('absolute' => TRUE)), array('max_redirects' => 0));
|
||
$this->assertFalse(isset($redirect_301->redirect_code), t('drupal_http_request does not follow 301 redirect if max_redirects = 0.'));
|
||
|
||
$redirect_invalid = drupal_http_request(url('system-test/redirect-noscheme', array('absolute' => TRUE)), array('max_redirects' => 1));
|
||
$this->assertEqual($redirect_invalid->code, -1002, t('301 redirect to invalid URL returned with error code !error.', array('!error' => $redirect_invalid->error)));
|
||
$this->assertEqual($redirect_invalid->error, 'missing schema', t('301 redirect to invalid URL returned with error message "!error".', array('!error' => $redirect_invalid->error)));
|
||
|
||
$redirect_invalid = drupal_http_request(url('system-test/redirect-noparse', array('absolute' => TRUE)), array('max_redirects' => 1));
|
||
$this->assertEqual($redirect_invalid->code, -1001, t('301 redirect to invalid URL returned with error message code "!error".', array('!error' => $redirect_invalid->error)));
|
||
$this->assertEqual($redirect_invalid->error, 'unable to parse URL', t('301 redirect to invalid URL returned with error message "!error".', array('!error' => $redirect_invalid->error)));
|
||
|
||
$redirect_invalid = drupal_http_request(url('system-test/redirect-invalid-scheme', array('absolute' => TRUE)), array('max_redirects' => 1));
|
||
$this->assertEqual($redirect_invalid->code, -1003, t('301 redirect to invalid URL returned with error code !error.', array('!error' => $redirect_invalid->error)));
|
||
$this->assertEqual($redirect_invalid->error, 'invalid schema ftp', t('301 redirect to invalid URL returned with error message "!error".', array('!error' => $redirect_invalid->error)));
|
||
|
||
$redirect_302 = drupal_http_request(url('system-test/redirect/302', array('absolute' => TRUE)), array('max_redirects' => 1));
|
||
$this->assertEqual($redirect_302->redirect_code, 302, t('drupal_http_request follows the 302 redirect.'));
|
||
|
||
$redirect_302 = drupal_http_request(url('system-test/redirect/302', array('absolute' => TRUE)), array('max_redirects' => 0));
|
||
$this->assertFalse(isset($redirect_302->redirect_code), t('drupal_http_request does not follow 302 redirect if $retry = 0.'));
|
||
|
||
$redirect_307 = drupal_http_request(url('system-test/redirect/307', array('absolute' => TRUE)), array('max_redirects' => 1));
|
||
$this->assertEqual($redirect_307->redirect_code, 307, t('drupal_http_request follows the 307 redirect.'));
|
||
|
||
$redirect_307 = drupal_http_request(url('system-test/redirect/307', array('absolute' => TRUE)), array('max_redirects' => 0));
|
||
$this->assertFalse(isset($redirect_307->redirect_code), t('drupal_http_request does not follow 307 redirect if max_redirects = 0.'));
|
||
}
|
||
|
||
function testDrupalGetDestination() {
|
||
$query = $this->randomName(10);
|
||
|
||
// Verify that a 'destination' query string is used as destination.
|
||
$this->drupalGet('system-test/destination', array('query' => array('destination' => $query)));
|
||
$this->assertText('The destination: ' . $query, t('The given query string destination is determined as destination.'));
|
||
|
||
// Verify that the current path is used as destination.
|
||
$this->drupalGet('system-test/destination', array('query' => array($query => NULL)));
|
||
$url = 'system-test/destination?' . $query;
|
||
$this->assertText('The destination: ' . $url, t('The current path is determined as destination.'));
|
||
}
|
||
}
|
||
|
||
/**
|
||
* Testing drupal_add_region_content and drupal_get_region_content.
|
||
*/
|
||
class DrupalSetContentTestCase extends DrupalWebTestCase {
|
||
public static function getInfo() {
|
||
return array(
|
||
'name' => 'Drupal set/get regions',
|
||
'description' => 'Performs tests on setting and retrieiving content from theme regions.',
|
||
'group' => 'System'
|
||
);
|
||
}
|
||
|
||
|
||
/**
|
||
* Test setting and retrieving content for theme regions.
|
||
*/
|
||
function testRegions() {
|
||
global $theme_key;
|
||
|
||
$block_regions = array_keys(system_region_list($theme_key));
|
||
$delimiter = $this->randomName(32);
|
||
$values = array();
|
||
// Set some random content for each region available.
|
||
foreach ($block_regions as $region) {
|
||
$first_chunk = $this->randomName(32);
|
||
drupal_add_region_content($region, $first_chunk);
|
||
$second_chunk = $this->randomName(32);
|
||
drupal_add_region_content($region, $second_chunk);
|
||
// Store the expected result for a drupal_get_region_content call for this region.
|
||
$values[$region] = $first_chunk . $delimiter . $second_chunk;
|
||
}
|
||
|
||
// Ensure drupal_get_region_content returns expected results when fetching all regions.
|
||
$content = drupal_get_region_content(NULL, $delimiter);
|
||
foreach ($content as $region => $region_content) {
|
||
$this->assertEqual($region_content, $values[$region], t('@region region text verified when fetching all regions', array('@region' => $region)));
|
||
}
|
||
|
||
// Ensure drupal_get_region_content returns expected results when fetching a single region.
|
||
foreach ($block_regions as $region) {
|
||
$region_content = drupal_get_region_content($region, $delimiter);
|
||
$this->assertEqual($region_content, $values[$region], t('@region region text verified when fetching single region.', array('@region' => $region)));
|
||
}
|
||
}
|
||
}
|
||
|
||
/**
|
||
* Testing drupal_goto and hook_drupal_goto_alter().
|
||
*/
|
||
class DrupalGotoTest extends DrupalWebTestCase {
|
||
public static function getInfo() {
|
||
return array(
|
||
'name' => 'Drupal goto',
|
||
'description' => 'Performs tests on the drupal_goto function and hook_drupal_goto_alter',
|
||
'group' => 'System'
|
||
);
|
||
}
|
||
|
||
function setUp() {
|
||
parent::setUp('common_test');
|
||
}
|
||
|
||
/**
|
||
* Test setting and retrieving content for theme regions.
|
||
*/
|
||
function testDrupalGoto() {
|
||
$this->drupalGet('common-test/drupal_goto/redirect');
|
||
|
||
$this->assertNoText(t("Drupal goto failed to stop program"), t("Drupal goto stopped program."));
|
||
$this->assertText('drupal_goto', t("Drupal goto redirect failed."));
|
||
}
|
||
|
||
/**
|
||
* Test setting and retrieving content for theme regions.
|
||
*/
|
||
function testDrupalGotoAlter() {
|
||
$this->drupalGet('common-test/drupal_goto/redirect_fail');
|
||
|
||
$this->assertNoText(t("Drupal goto failed to stop program"), t("Drupal goto stopped program."));
|
||
$this->assertNoText('drupal_goto_fail', t("Drupal goto redirect failed."));
|
||
}
|
||
}
|
||
|
||
/**
|
||
* Tests for the JavaScript system.
|
||
*/
|
||
class JavaScriptTestCase extends DrupalWebTestCase {
|
||
/**
|
||
* Store configured value for JavaScript preprocessing.
|
||
*/
|
||
protected $preprocess_js = NULL;
|
||
|
||
public static function getInfo() {
|
||
return array(
|
||
'name' => 'JavaScript',
|
||
'description' => 'Tests the JavaScript system.',
|
||
'group' => 'System'
|
||
);
|
||
}
|
||
|
||
function setUp() {
|
||
// Enable Locale and SimpleTest in the test environment.
|
||
parent::setUp('locale', 'simpletest', 'common_test');
|
||
|
||
// Disable preprocessing
|
||
$this->preprocess_js = variable_get('preprocess_js', 0);
|
||
variable_set('preprocess_js', 0);
|
||
|
||
// Reset drupal_add_js() and drupal_add_library() statics before each test.
|
||
drupal_static_reset('drupal_add_js');
|
||
drupal_static_reset('drupal_add_library');
|
||
}
|
||
|
||
function tearDown() {
|
||
// Restore configured value for JavaScript preprocessing.
|
||
variable_set('preprocess_js', $this->preprocess_js);
|
||
parent::tearDown();
|
||
}
|
||
|
||
/**
|
||
* Test default JavaScript is empty.
|
||
*/
|
||
function testDefault() {
|
||
$this->assertEqual(array(), drupal_add_js(), t('Default JavaScript is empty.'));
|
||
}
|
||
|
||
/**
|
||
* Test adding a JavaScript file.
|
||
*/
|
||
function testAddFile() {
|
||
$javascript = drupal_add_js('misc/collapse.js');
|
||
$this->assertTrue(array_key_exists('misc/jquery.js', $javascript), t('jQuery is added when a file is added.'));
|
||
$this->assertTrue(array_key_exists('misc/drupal.js', $javascript), t('Drupal.js is added when file is added.'));
|
||
$this->assertTrue(array_key_exists('misc/collapse.js', $javascript), t('JavaScript files are correctly added.'));
|
||
$this->assertEqual(base_path(), $javascript['settings']['data'][0]['basePath'], t('Base path JavaScript setting is correctly set.'));
|
||
}
|
||
|
||
/**
|
||
* Test adding settings.
|
||
*/
|
||
function testAddSetting() {
|
||
$javascript = drupal_add_js(array('drupal' => 'rocks', 'dries' => 280342800), 'setting');
|
||
$this->assertEqual(280342800, $javascript['settings']['data'][1]['dries'], t('JavaScript setting is set correctly.'));
|
||
$this->assertEqual('rocks', $javascript['settings']['data'][1]['drupal'], t('The other JavaScript setting is set correctly.'));
|
||
}
|
||
|
||
/**
|
||
* Tests adding an external JavaScript File.
|
||
*/
|
||
function testAddExternal() {
|
||
$path = 'http://example.com/script.js';
|
||
$javascript = drupal_add_js($path, 'external');
|
||
$this->assertTrue(array_key_exists('http://example.com/script.js', $javascript), t('Added an external JavaScript file.'));
|
||
}
|
||
|
||
/**
|
||
* Test drupal_get_js() for JavaScript settings.
|
||
*/
|
||
function testHeaderSetting() {
|
||
drupal_add_js(array('testSetting' => 'testValue'), 'setting');
|
||
$javascript = drupal_get_js('header');
|
||
$this->assertTrue(strpos($javascript, 'basePath') > 0, t('Rendered JavaScript header returns basePath setting.'));
|
||
$this->assertTrue(strpos($javascript, 'testSetting') > 0, t('Rendered JavaScript header returns custom setting.'));
|
||
$this->assertTrue(strpos($javascript, 'misc/jquery.js') > 0, t('Rendered JavaScript header includes jQuery.'));
|
||
}
|
||
|
||
/**
|
||
* Test to see if resetting the JavaScript empties the cache.
|
||
*/
|
||
function testReset() {
|
||
drupal_add_js('misc/collapse.js');
|
||
drupal_static_reset('drupal_add_js');
|
||
$this->assertEqual(array(), drupal_add_js(), t('Resetting the JavaScript correctly empties the cache.'));
|
||
}
|
||
|
||
/**
|
||
* Test adding inline scripts.
|
||
*/
|
||
function testAddInline() {
|
||
$inline = 'jQuery(function () { });';
|
||
$javascript = drupal_add_js($inline, array('type' => 'inline', 'scope' => 'footer'));
|
||
$this->assertTrue(array_key_exists('misc/jquery.js', $javascript), t('jQuery is added when inline scripts are added.'));
|
||
$data = end($javascript);
|
||
$this->assertEqual($inline, $data['data'], t('Inline JavaScript is correctly added to the footer.'));
|
||
}
|
||
|
||
/**
|
||
* Test rendering an external JavaScript file.
|
||
*/
|
||
function testRenderExternal() {
|
||
$external = 'http://example.com/example.js';
|
||
drupal_add_js($external, 'external');
|
||
$javascript = drupal_get_js();
|
||
// Local files have a base_path() prefix, external files should not.
|
||
$this->assertTrue(strpos($javascript, 'src="' . $external) > 0, t('Rendering an external JavaScript file.'));
|
||
}
|
||
|
||
/**
|
||
* Test drupal_get_js() with a footer scope.
|
||
*/
|
||
function testFooterHTML() {
|
||
$inline = 'jQuery(function () { });';
|
||
drupal_add_js($inline, array('type' => 'inline', 'scope' => 'footer'));
|
||
$javascript = drupal_get_js('footer');
|
||
$this->assertTrue(strpos($javascript, $inline) > 0, t('Rendered JavaScript footer returns the inline code.'));
|
||
}
|
||
|
||
/**
|
||
* Test drupal_add_js() sets preproccess to false when cache is set to false.
|
||
*/
|
||
function testNoCache() {
|
||
$javascript = drupal_add_js('misc/collapse.js', array('cache' => FALSE));
|
||
$this->assertFalse($javascript['misc/collapse.js']['preprocess'], t('Setting cache to FALSE sets proprocess to FALSE when adding JavaScript.'));
|
||
}
|
||
|
||
/**
|
||
* Test adding a JavaScript file with a different weight.
|
||
*/
|
||
function testDifferentWeight() {
|
||
$javascript = drupal_add_js('misc/collapse.js', array('weight' => JS_THEME));
|
||
$this->assertEqual($javascript['misc/collapse.js']['weight'], JS_THEME, t('Adding a JavaScript file with a different weight caches the given weight.'));
|
||
}
|
||
|
||
/**
|
||
* Test JavaScript ordering.
|
||
*/
|
||
function testRenderOrder() {
|
||
// Add a bunch of JavaScript in strange ordering.
|
||
drupal_add_js('(function($){alert("Weight 5 #1");})(jQuery);', array('type' => 'inline', 'scope' => 'footer', 'weight' => 5));
|
||
drupal_add_js('(function($){alert("Weight 0 #1");})(jQuery);', array('type' => 'inline', 'scope' => 'footer'));
|
||
drupal_add_js('(function($){alert("Weight 0 #2");})(jQuery);', array('type' => 'inline', 'scope' => 'footer'));
|
||
drupal_add_js('(function($){alert("Weight -8 #1");})(jQuery);', array('type' => 'inline', 'scope' => 'footer', 'weight' => -8));
|
||
drupal_add_js('(function($){alert("Weight -8 #2");})(jQuery);', array('type' => 'inline', 'scope' => 'footer', 'weight' => -8));
|
||
drupal_add_js('(function($){alert("Weight -8 #3");})(jQuery);', array('type' => 'inline', 'scope' => 'footer', 'weight' => -8));
|
||
drupal_add_js('(function($){alert("Weight -8 #4");})(jQuery);', array('type' => 'inline', 'scope' => 'footer', 'weight' => -8));
|
||
drupal_add_js('(function($){alert("Weight 5 #2");})(jQuery);', array('type' => 'inline', 'scope' => 'footer', 'weight' => 5));
|
||
drupal_add_js('(function($){alert("Weight 0 #3");})(jQuery);', array('type' => 'inline', 'scope' => 'footer'));
|
||
|
||
// Construct the expected result from the regex.
|
||
$expected = array(
|
||
"-8 #1",
|
||
"-8 #2",
|
||
"-8 #3",
|
||
"-8 #4",
|
||
"0 #1",
|
||
"0 #2",
|
||
"0 #3",
|
||
"5 #1",
|
||
"5 #2",
|
||
);
|
||
|
||
// Retrieve the rendered JavaScript and test against the regex.
|
||
$js = drupal_get_js('footer');
|
||
$matches = array();
|
||
if (preg_match_all('/Weight\s([-0-9]+\s[#0-9]+)/', $js, $matches)) {
|
||
$result = $matches[1];
|
||
}
|
||
else {
|
||
$result = array();
|
||
}
|
||
$this->assertIdentical($result, $expected, t('JavaScript is added in the expected weight order.'));
|
||
}
|
||
|
||
/**
|
||
* Test rendering the JavaScript with a file's weight above jQuery's.
|
||
*/
|
||
function testRenderDifferentWeight() {
|
||
drupal_add_js('misc/collapse.js', array('weight' => JS_LIBRARY - 21));
|
||
$javascript = drupal_get_js();
|
||
$this->assertTrue(strpos($javascript, 'misc/collapse.js') < strpos($javascript, 'misc/jquery.js'), t('Rendering a JavaScript file above jQuery.'));
|
||
}
|
||
|
||
/**
|
||
* Test altering a JavaScript's weight via hook_js_alter().
|
||
*
|
||
* @see simpletest_js_alter()
|
||
*/
|
||
function testAlter() {
|
||
// Add both tableselect.js and simpletest.js, with a larger weight on SimpleTest.
|
||
drupal_add_js('misc/tableselect.js');
|
||
drupal_add_js(drupal_get_path('module', 'simpletest') . '/simpletest.js', array('weight' => JS_THEME));
|
||
|
||
// Render the JavaScript, testing if simpletest.js was altered to be before
|
||
// tableselect.js. See simpletest_js_alter() to see where this alteration
|
||
// takes place.
|
||
$javascript = drupal_get_js();
|
||
$this->assertTrue(strpos($javascript, 'simpletest.js') < strpos($javascript, 'misc/tableselect.js'), t('Altering JavaScript weight through the alter hook.'));
|
||
}
|
||
|
||
/**
|
||
* Adds a library to the page and tests for both its JavaScript and its CSS.
|
||
*/
|
||
function testLibraryRender() {
|
||
$result = drupal_add_library('system', 'farbtastic');
|
||
$this->assertTrue($result !== FALSE, t('Library was added without errors.'));
|
||
$scripts = drupal_get_js();
|
||
$styles = drupal_get_css();
|
||
$this->assertTrue(strpos($scripts, 'misc/farbtastic/farbtastic.js'), t('JavaScript of library was added to the page.'));
|
||
$this->assertTrue(strpos($styles, 'misc/farbtastic/farbtastic.css'), t('Stylesheet of library was added to the page.'));
|
||
}
|
||
|
||
/**
|
||
* Adds a JavaScript library to the page and alters it.
|
||
*
|
||
* @see common_test_library_alter()
|
||
*/
|
||
function testLibraryAlter() {
|
||
// Verify that common_test altered the title of Farbtastic.
|
||
$library = drupal_get_library('system', 'farbtastic');
|
||
$this->assertEqual($library['title'], 'Farbtastic: Altered Library', t('Registered libraries were altered.'));
|
||
|
||
// common_test_library_alter() also added a dependency on jQuery Form.
|
||
drupal_add_library('system', 'farbtastic');
|
||
$scripts = drupal_get_js();
|
||
$this->assertTrue(strpos($scripts, 'misc/jquery.form.js'), t('Altered library dependencies are added to the page.'));
|
||
}
|
||
|
||
/**
|
||
* Tests that multiple modules can implement the same library.
|
||
*
|
||
* @see common_test_library()
|
||
*/
|
||
function testLibraryNameConflicts() {
|
||
$farbtastic = drupal_get_library('common_test', 'farbtastic');
|
||
$this->assertEqual($farbtastic['title'], 'Custom Farbtastic Library', t('Alternative libraries can be added to the page.'));
|
||
}
|
||
|
||
/**
|
||
* Tests non-existing libraries.
|
||
*/
|
||
function testLibraryUnknown() {
|
||
$result = drupal_get_library('unknown', 'unknown');
|
||
$this->assertFalse($result, t('Unknown library returned FALSE.'));
|
||
drupal_static_reset('drupal_get_library');
|
||
|
||
$result = drupal_add_library('unknown', 'unknown');
|
||
$this->assertFalse($result, t('Unknown library returned FALSE.'));
|
||
$scripts = drupal_get_js();
|
||
$this->assertTrue(strpos($scripts, 'unknown') === FALSE, t('Unknown library was not added to the page.'));
|
||
}
|
||
|
||
/**
|
||
* Tests the addition of libraries through the #attached['library'] property.
|
||
*/
|
||
function testAttachedLibrary() {
|
||
$element['#attached']['library'][] = array('system', 'farbtastic');
|
||
drupal_render($element);
|
||
$scripts = drupal_get_js();
|
||
$this->assertTrue(strpos($scripts, 'misc/farbtastic/farbtastic.js'), t('The attached_library property adds the additional libraries.'));
|
||
}
|
||
}
|
||
|
||
/**
|
||
* Tests for drupal_render().
|
||
*/
|
||
class DrupalRenderUnitTestCase extends DrupalWebTestCase {
|
||
public static function getInfo() {
|
||
return array(
|
||
'name' => 'Drupal render',
|
||
'description' => 'Performs unit tests on drupal_render().',
|
||
'group' => 'System',
|
||
);
|
||
}
|
||
|
||
function setUp() {
|
||
parent::setUp('common_test');
|
||
}
|
||
|
||
/**
|
||
* Test sorting by weight.
|
||
*/
|
||
function testDrupalRenderSorting() {
|
||
$first = $this->randomName();
|
||
$second = $this->randomName();
|
||
// Build an array with '#weight' set for each element.
|
||
$elements = array(
|
||
'second' => array(
|
||
'#weight' => 10,
|
||
'#markup' => $second,
|
||
),
|
||
'first' => array(
|
||
'#weight' => 0,
|
||
'#markup' => $first,
|
||
),
|
||
);
|
||
$output = drupal_render($elements);
|
||
|
||
// The lowest weight element should appear last in $output.
|
||
$this->assertTrue(strpos($output, $second) > strpos($output, $first), t('Elements were sorted correctly by weight.'));
|
||
|
||
// Confirm that the $elements array has '#sorted' set to TRUE.
|
||
$this->assertTrue($elements['#sorted'], t("'#sorted' => TRUE was added to the array"));
|
||
|
||
// Pass $elements through element_children() and ensure it remains
|
||
// sorted in the correct order. drupal_render() will return an empty string
|
||
// if used on the same array in the same request.
|
||
$children = element_children($elements);
|
||
$this->assertTrue(array_shift($children) == 'first', t('Child found in the correct order.'));
|
||
$this->assertTrue(array_shift($children) == 'second', t('Child found in the correct order.'));
|
||
|
||
|
||
// The same array structure again, but with #sorted set to TRUE.
|
||
$elements = array(
|
||
'second' => array(
|
||
'#weight' => 10,
|
||
'#markup' => $second,
|
||
),
|
||
'first' => array(
|
||
'#weight' => 0,
|
||
'#markup' => $first,
|
||
),
|
||
'#sorted' => TRUE,
|
||
);
|
||
$output = drupal_render($elements);
|
||
|
||
// The elements should appear in output in the same order as the array.
|
||
$this->assertTrue(strpos($output, $second) < strpos($output, $first), t('Elements were not sorted.'));
|
||
}
|
||
|
||
/**
|
||
* Test passing arguments to the theme function.
|
||
*/
|
||
function testDrupalRenderThemeArguments() {
|
||
$element = array(
|
||
'#theme' => 'common_test_foo',
|
||
);
|
||
// Test that defaults work.
|
||
$this->assertEqual(drupal_render($element), 'foobar', 'Defaults work');
|
||
$element = array(
|
||
'#theme' => 'common_test_foo',
|
||
'#foo' => $this->randomName(),
|
||
'#bar' => $this->randomName(),
|
||
);
|
||
// Test that passing arguments to the theme function works.
|
||
$this->assertEqual(drupal_render($element), $element['#foo'] . $element['#bar'], 'Passing arguments to theme functions works');
|
||
}
|
||
}
|
||
|
||
/**
|
||
* Test for valid_url().
|
||
*/
|
||
class ValidUrlTestCase extends DrupalUnitTestCase {
|
||
public static function getInfo() {
|
||
return array(
|
||
'name' => 'Valid Url',
|
||
'description' => "Performs tests on Drupal's valid url function.",
|
||
'group' => 'System'
|
||
);
|
||
}
|
||
|
||
/**
|
||
* Test valid absolute urls.
|
||
*/
|
||
function testValidAbsolute() {
|
||
$url_schemes = array('http', 'https', 'ftp');
|
||
$valid_absolute_urls = array(
|
||
'example.com',
|
||
'www.example.com',
|
||
'ex-ample.com',
|
||
'3xampl3.com',
|
||
'example.com/paren(the)sis',
|
||
'example.com/index.html#pagetop',
|
||
'example.com:8080',
|
||
'subdomain.example.com',
|
||
'example.com/index.php?q=node',
|
||
'example.com/index.php?q=node¶m=false',
|
||
'user@www.example.com',
|
||
'user:pass@www.example.com:8080/login.php?do=login&style=%23#pagetop',
|
||
'127.0.0.1',
|
||
'example.org?',
|
||
'john%20doe:secret:foo@example.org/',
|
||
'example.org/~,$\'*;',
|
||
'caf%C3%A9.example.org',
|
||
'[FEDC:BA98:7654:3210:FEDC:BA98:7654:3210]:80/index.html',
|
||
);
|
||
|
||
foreach ($url_schemes as $scheme) {
|
||
foreach ($valid_absolute_urls as $url) {
|
||
$test_url = $scheme . '://' . $url;
|
||
$valid_url = valid_url($test_url, TRUE);
|
||
$this->assertTrue($valid_url, t('@url is a valid url.', array('@url' => $test_url)));
|
||
}
|
||
}
|
||
}
|
||
|
||
/**
|
||
* Test invalid absolute urls.
|
||
*/
|
||
function testInvalidAbsolute() {
|
||
$url_schemes = array('http', 'https', 'ftp');
|
||
$invalid_ablosule_urls = array(
|
||
'',
|
||
'ex!ample.com',
|
||
'ex%ample.com',
|
||
);
|
||
|
||
foreach ($url_schemes as $scheme) {
|
||
foreach ($invalid_ablosule_urls as $url) {
|
||
$test_url = $scheme . '://' . $url;
|
||
$valid_url = valid_url($test_url, TRUE);
|
||
$this->assertFalse($valid_url, t('@url is NOT a valid url.', array('@url' => $test_url)));
|
||
}
|
||
}
|
||
}
|
||
|
||
/**
|
||
* Test valid relative urls.
|
||
*/
|
||
function testValidRelative() {
|
||
$valid_relative_urls = array(
|
||
'paren(the)sis',
|
||
'index.html#pagetop',
|
||
'index.php?q=node',
|
||
'index.php?q=node¶m=false',
|
||
'login.php?do=login&style=%23#pagetop',
|
||
);
|
||
|
||
foreach (array('', '/') as $front) {
|
||
foreach ($valid_relative_urls as $url) {
|
||
$test_url = $front . $url;
|
||
$valid_url = valid_url($test_url);
|
||
$this->assertTrue($valid_url, t('@url is a valid url.', array('@url' => $test_url)));
|
||
}
|
||
}
|
||
}
|
||
|
||
/**
|
||
* Test invalid relative urls.
|
||
*/
|
||
function testInvalidRelative() {
|
||
$invalid_relative_urls = array(
|
||
'ex^mple',
|
||
'example<>',
|
||
'ex%ample',
|
||
);
|
||
|
||
foreach (array('', '/') as $front) {
|
||
foreach ($invalid_relative_urls as $url) {
|
||
$test_url = $front . $url;
|
||
$valid_url = valid_url($test_url);
|
||
$this->assertFALSE($valid_url, t('@url is NOT a valid url.', array('@url' => $test_url)));
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
/**
|
||
* Tests for CRUD API functions.
|
||
*/
|
||
class DrupalDataApiTest extends DrupalWebTestCase {
|
||
public static function getInfo() {
|
||
return array(
|
||
'name' => 'Data API functions',
|
||
'description' => 'Tests the performance of CRUD APIs.',
|
||
'group' => 'System',
|
||
);
|
||
}
|
||
|
||
function setUp() {
|
||
parent::setUp('taxonomy');
|
||
}
|
||
|
||
/**
|
||
* Test the drupal_write_record() API function.
|
||
*/
|
||
function testDrupalWriteRecord() {
|
||
// Insert an object record for a table with a single-field primary key.
|
||
$vocabulary = new stdClass();
|
||
$vocabulary->name = 'test';
|
||
$insert_result = drupal_write_record('taxonomy_vocabulary', $vocabulary);
|
||
$this->assertTrue($insert_result == SAVED_NEW, t('Correct value returned when a record is inserted with drupal_write_record() for a table with a single-field primary key.'));
|
||
$this->assertTrue(isset($vocabulary->vid), t('Primary key is set on record created with drupal_write_record().'));
|
||
|
||
// Update the initial record after changing a property.
|
||
$vocabulary->name = 'testing';
|
||
$update_result = drupal_write_record('taxonomy_vocabulary', $vocabulary, array('vid'));
|
||
$this->assertTrue($update_result == SAVED_UPDATED, t('Correct value returned when a record updated with drupal_write_record() for table with single-field primary key.'));
|
||
|
||
// Run an update query where no field values are changed. The database
|
||
// layer should return zero for number of affected rows, but
|
||
// db_write_record() should still return SAVED_UPDATED.
|
||
$update_result = drupal_write_record('taxonomy_vocabulary', $vocabulary, array('vid'));
|
||
$this->assertTrue($update_result == SAVED_UPDATED, t('Correct value returned when a valid update is run without changing any values.'));
|
||
|
||
// Insert an object record for a table with a multi-field primary key.
|
||
$node_access = new stdClass();
|
||
$node_access->nid = mt_rand();
|
||
$node_access->gid = mt_rand();
|
||
$node_access->realm = $this->randomName();
|
||
$insert_result = drupal_write_record('node_access', $node_access);
|
||
$this->assertTrue($insert_result == SAVED_NEW, t('Correct value returned when a record is inserted with drupal_write_record() for a table with a multi-field primary key.'));
|
||
|
||
// Update the record.
|
||
$update_result = drupal_write_record('node_access', $node_access, array('nid', 'gid', 'realm'));
|
||
$this->assertTrue($update_result == SAVED_UPDATED, t('Correct value returned when a record is updated with drupal_write_record() for a table with a multi-field primary key.'));
|
||
}
|
||
|
||
}
|
||
|
||
/**
|
||
* Tests Simpletest error and exception collector.
|
||
*/
|
||
class DrupalErrorCollectionUnitTest extends DrupalWebTestCase {
|
||
|
||
/**
|
||
* Errors triggered during the test.
|
||
*
|
||
* Errors are intercepted by the overriden implementation
|
||
* of DrupalWebTestCase::error below.
|
||
*
|
||
* @var Array
|
||
*/
|
||
protected $collectedErrors = array();
|
||
|
||
public static function getInfo() {
|
||
return array(
|
||
'name' => 'SimpleTest error collector',
|
||
'description' => 'Performs tests on the Simpletest error and exception collector.',
|
||
'group' => 'SimpleTest',
|
||
);
|
||
}
|
||
|
||
function setUp() {
|
||
parent::setUp('system_test', 'error_test');
|
||
}
|
||
|
||
/**
|
||
* Test that simpletest collects errors from the tested site.
|
||
*/
|
||
function testErrorCollect() {
|
||
$this->collectedErrors = array();
|
||
$this->drupalGet('error-test/generate-warnings-with-report');
|
||
$this->assertEqual(count($this->collectedErrors), 3, t('Three errors were collected'));
|
||
|
||
if (count($this->collectedErrors) == 3) {
|
||
$this->assertError($this->collectedErrors[0], 'Notice', 'error_test_generate_warnings()', 'error_test.module', 'Undefined variable: bananas');
|
||
$this->assertError($this->collectedErrors[1], 'Warning', 'error_test_generate_warnings()', 'error_test.module', 'Division by zero');
|
||
$this->assertError($this->collectedErrors[2], 'User warning', 'error_test_generate_warnings()', 'error_test.module', 'Drupal is awesome');
|
||
}
|
||
else {
|
||
// Give back the errors to the log report.
|
||
foreach ($this->collectedErrors as $error) {
|
||
parent::error($error['message'], $error['group'], $error['caller']);
|
||
}
|
||
}
|
||
}
|
||
|
||
protected function error($message = '', $group = 'Other', array $caller = NULL) {
|
||
// This function overiddes DrupalWebTestCase::error(). We collect an error...
|
||
$this->collectedErrors[] = array(
|
||
'message' => $message,
|
||
'group' => $group,
|
||
'caller' => $caller
|
||
);
|
||
// ... and ignore it.
|
||
}
|
||
|
||
/**
|
||
* Assert that a collected error matches what we are expecting.
|
||
*/
|
||
function assertError($error, $group, $function, $file, $message = NULL) {
|
||
$this->assertEqual($error['group'], $group, t("Group was %group", array('%group' => $group)));
|
||
$this->assertEqual($error['caller']['function'], $function, t("Function was %function", array('%function' => $function)));
|
||
$this->assertEqual(basename($error['caller']['file']), $file, t("File was %file", array('%file' => $file)));
|
||
if (isset($message)) {
|
||
$this->assertEqual($error['message'], $message, t("Message was %message", array('%message' => $message)));
|
||
}
|
||
}
|
||
}
|
||
|
||
/**
|
||
* Test the drupal_parse_info_file() API function.
|
||
*/
|
||
class ParseInfoFilesTestCase extends DrupalWebTestCase {
|
||
public static function getInfo() {
|
||
return array(
|
||
'name' => 'Parsing .info files',
|
||
'description' => 'Tests parsing .info files.',
|
||
'group' => 'System',
|
||
);
|
||
}
|
||
|
||
/**
|
||
* Parse an example .info file an verify the results.
|
||
*/
|
||
function testParseInfoFile() {
|
||
$info_values = drupal_parse_info_file(drupal_get_path('module', 'simpletest') . '/tests/common_test_info.txt');
|
||
$this->assertEqual($info_values['simple_string'], 'A simple string', t('Simple string value was parsed correctly.'), t('System'));
|
||
$this->assertEqual($info_values['simple_constant'], WATCHDOG_INFO, t('Constant value was parsed correctly.'), t('System'));
|
||
$this->assertEqual($info_values['double_colon'], 'dummyClassName::', t('Value containing double-colon was parsed correctly.'), t('System'));
|
||
}
|
||
}
|
||
|
||
/**
|
||
* Tests for the format_date() function.
|
||
*/
|
||
class FormatDateUnitTest extends DrupalWebTestCase {
|
||
|
||
/**
|
||
* Arbitrary langcode for a custom language.
|
||
*/
|
||
const LANGCODE = 'xx';
|
||
|
||
public static function getInfo() {
|
||
return array(
|
||
'name' => 'Format date',
|
||
'description' => 'Test the format_date() function.',
|
||
'group' => 'System',
|
||
);
|
||
}
|
||
|
||
function setUp() {
|
||
parent::setUp('locale');
|
||
variable_set('configurable_timezones', 1);
|
||
variable_set('date_format_long', 'l, j. F Y - G:i');
|
||
variable_set('date_format_medium', 'j. F Y - G:i');
|
||
variable_set('date_format_short', 'Y M j - g:ia');
|
||
variable_set('locale_custom_strings_' . self::LANGCODE, array(
|
||
'' => array('Sunday' => 'domingo'),
|
||
'Long month name' => array('March' => 'marzo'),
|
||
));
|
||
$this->refreshVariables();
|
||
}
|
||
|
||
/**
|
||
* Tests for the format_date() function.
|
||
*/
|
||
function testFormatDate() {
|
||
global $user, $language;
|
||
|
||
$timestamp = strtotime('2007-03-26T00:00:00+00:00');
|
||
$this->assertIdentical(format_date($timestamp, 'custom', 'l, d-M-y H:i:s T', 'America/Los_Angeles', 'en'), 'Sunday, 25-Mar-07 17:00:00 PDT', t('Test all parameters.'));
|
||
$this->assertIdentical(format_date($timestamp, 'custom', 'l, d-M-y H:i:s T', 'America/Los_Angeles', self::LANGCODE), 'domingo, 25-Mar-07 17:00:00 PDT', t('Test translated format.'));
|
||
$this->assertIdentical(format_date($timestamp, 'custom', '\\l, d-M-y H:i:s T', 'America/Los_Angeles', self::LANGCODE), 'l, 25-Mar-07 17:00:00 PDT', t('Test an escaped format string.'));
|
||
$this->assertIdentical(format_date($timestamp, 'custom', '\\\\l, d-M-y H:i:s T', 'America/Los_Angeles', self::LANGCODE), '\\domingo, 25-Mar-07 17:00:00 PDT', t('Test format containing backslash character.'));
|
||
$this->assertIdentical(format_date($timestamp, 'custom', '\\\\\\l, d-M-y H:i:s T', 'America/Los_Angeles', self::LANGCODE), '\\l, 25-Mar-07 17:00:00 PDT', t('Test format containing backslash followed by escaped format string.'));
|
||
$this->assertIdentical(format_date($timestamp, 'custom', 'l, d-M-y H:i:s T', 'Europe/London', 'en'), 'Monday, 26-Mar-07 01:00:00 BST', t('Test a different time zone.'));
|
||
|
||
// Create an admin user and add Spanish language.
|
||
$admin_user = $this->drupalCreateUser(array('administer languages'));
|
||
$this->drupalLogin($admin_user);
|
||
$edit = array(
|
||
'langcode' => self::LANGCODE,
|
||
'name' => self::LANGCODE,
|
||
'native' => self::LANGCODE,
|
||
'direction' => LANGUAGE_LTR,
|
||
'prefix' => self::LANGCODE,
|
||
);
|
||
$this->drupalPost('admin/config/regional/language/add', $edit, t('Add custom language'));
|
||
|
||
// Create a test user to carry out the tests.
|
||
$test_user = $this->drupalCreateUser();
|
||
$this->drupalLogin($test_user);
|
||
$edit = array('language' => self::LANGCODE, 'mail' => $test_user->mail, 'timezone' => 'America/Los_Angeles');
|
||
$this->drupalPost('user/' . $test_user->uid . '/edit', $edit, t('Save'));
|
||
|
||
// Disable session saving as we are about to modify the global $user.
|
||
drupal_save_session(FALSE);
|
||
// Save the original user and language and then replace it with the test user and language.
|
||
$real_user = $user;
|
||
$user = user_load($test_user->uid, TRUE);
|
||
$real_language = $language->language;
|
||
$language->language = $user->language;
|
||
|
||
$this->assertIdentical(format_date($timestamp, 'custom', 'l, d-M-y H:i:s T', 'America/Los_Angeles', 'en'), 'Sunday, 25-Mar-07 17:00:00 PDT', t('Test a different language.'));
|
||
$this->assertIdentical(format_date($timestamp, 'custom', 'l, d-M-y H:i:s T', 'Europe/London'), 'Monday, 26-Mar-07 01:00:00 BST', t('Test a different time zone.'));
|
||
$this->assertIdentical(format_date($timestamp, 'custom', 'l, d-M-y H:i:s T'), 'domingo, 25-Mar-07 17:00:00 PDT', t('Test custom date format.'));
|
||
$this->assertIdentical(format_date($timestamp, 'long'), 'domingo, 25. marzo 2007 - 17:00', t('Test long date format.'));
|
||
$this->assertIdentical(format_date($timestamp, 'medium'), '25. marzo 2007 - 17:00', t('Test medium date format.'));
|
||
$this->assertIdentical(format_date($timestamp, 'short'), '2007 Mar 25 - 5:00pm', t('Test short date format.'));
|
||
$this->assertIdentical(format_date($timestamp), '25. marzo 2007 - 17:00', t('Test default date format.'));
|
||
|
||
// Restore the original user and language, and enable session saving.
|
||
$user = $real_user;
|
||
$language->language = $real_language;
|
||
drupal_save_session(TRUE);
|
||
}
|
||
}
|
||
|
||
/**
|
||
* Tests for the format_date() function.
|
||
*/
|
||
class DrupalAttributesUnitTest extends DrupalUnitTestCase {
|
||
public static function getInfo() {
|
||
return array(
|
||
'name' => 'HTML Attributes',
|
||
'description' => 'Perform unit tests on the drupal_attributes() function.',
|
||
'group' => 'System',
|
||
);
|
||
}
|
||
|
||
/**
|
||
* Tests that drupal_html_class() cleans the class name properly.
|
||
*/
|
||
function testDrupalAttributes() {
|
||
// Verify that special characters are HTML encoded.
|
||
$this->assertIdentical(drupal_attributes(array('title' => '&"\'<>')), ' title="&"'<>"', t('HTML encode attribute values.'));
|
||
|
||
// Verify multi-value attributes are concatenated with spaces.
|
||
$attributes = array('class' => array('first', 'last'));
|
||
$this->assertIdentical(drupal_attributes(array('class' => array('first', 'last'))), ' class="first last"', t('Concatenate multi-value attributes.'));
|
||
|
||
// Verify empty attribute values are rendered.
|
||
$this->assertIdentical(drupal_attributes(array('alt' => '')), ' alt=""', t('Empty attribute value #1.'));
|
||
$this->assertIdentical(drupal_attributes(array('alt' => NULL)), ' alt=""', t('Empty attribute value #2.'));
|
||
|
||
// Verify multiple attributes are rendered.
|
||
$attributes = array(
|
||
'id' => 'id-test',
|
||
'class' => array('first', 'last'),
|
||
'alt' => 'Alternate',
|
||
);
|
||
$this->assertIdentical(drupal_attributes($attributes), ' id="id-test" class="first last" alt="Alternate"', t('Multiple attributes.'));
|
||
|
||
// Verify empty attributes array is rendered.
|
||
$this->assertIdentical(drupal_attributes(array()), '', t('Empty attributes array.'));
|
||
}
|
||
}
|
||
|
||
/**
|
||
* Tests converting PHP variables to JSON strings and back.
|
||
*/
|
||
class DrupalJSONTest extends DrupalUnitTestCase {
|
||
public static function getInfo() {
|
||
return array(
|
||
'name' => 'JSON',
|
||
'description' => 'Perform unit tests on the drupal_json_encode() and drupal_json_decode() functions.',
|
||
'group' => 'System',
|
||
);
|
||
}
|
||
|
||
/**
|
||
* Tests converting PHP variables to JSON strings and back.
|
||
*/
|
||
function testJSON() {
|
||
// Setup a string with the full ASCII table.
|
||
// @todo: Add tests for non-ASCII characters and Unicode.
|
||
$str = '';
|
||
for ($i=0; $i < 128; $i++) {
|
||
$str .= chr($i);
|
||
}
|
||
// Characters that must be escaped.
|
||
$html_unsafe = array('<', '>', '&');
|
||
|
||
// Verify there aren't character encoding problems with the source string.
|
||
$this->assertIdentical(strlen($str), 128, t('A string with the full ASCII table has the correct length.'));
|
||
foreach ($html_unsafe as $char) {
|
||
$this->assertTrue(strpos($str, $char) > 0, t('A string with the full ASCII table includes @s.', array('@s' => $char)));
|
||
}
|
||
|
||
// Verify that JSON encoding produces a string with all of the characters.
|
||
$json = drupal_json_encode($str);
|
||
$this->assertTrue(strlen($json) > strlen($str), t('A JSON encoded string is larger than the source string.'));
|
||
|
||
// Verify that encoding/decoding is reversible.
|
||
$json_decoded = drupal_json_decode($json);
|
||
$this->assertIdentical($str, $json_decoded, t('Encoding a string to JSON and decoding back results in the original string.'));
|
||
|
||
// Verify reversibility for structured data. Also verify that necessary
|
||
// characters are escaped.
|
||
$source = array(TRUE, FALSE, 0, 1, '0', '1', $str, array('key1' => $str, 'key2' => array('nested' => TRUE)));
|
||
$json = drupal_json_encode($source);
|
||
foreach ($html_unsafe as $char) {
|
||
$this->assertTrue(strpos($json, $char) === FALSE, t('A JSON encoded string does not contain @s.', array('@s' => $char)));
|
||
}
|
||
$json_decoded = drupal_json_decode($json);
|
||
$this->assertNotIdentical($source, $json, t('An array encoded in JSON is not identical to the source.'));
|
||
$this->assertIdentical($source, $json_decoded, t('Encoding structured data to JSON and decoding back results in the original data.'));
|
||
}
|
||
}
|