query_parameters_to_url.test in Query Parameters To URL 7
Query Arguments To URL tests.
File
query_parameters_to_url.testView source
<?php
/**
* @file
* Query Arguments To URL tests.
*/
/**
* General test cases.
*/
class QueryParametersToURLTestCase extends DrupalWebTestCase {
/**
* Returns test info.
*/
public static function getInfo() {
return array(
'name' => 'Query Parameters To URL Integration tests',
'description' => 'Test Query Parameters To URL functionality.',
'group' => 'Query Parameters To URL',
);
}
/**
* Initial setup.
*/
public function setUp() {
parent::setUp(array(
'query_parameters_to_url',
));
// Enable rewriting on all paths.
variable_set(QUERY_PARAMETERS_TO_URL_PATH_REG_EXP, '{.+}');
// Clean URLs should be enabled for testing.
variable_set('clean_url', 1);
// Create test node just for the sake of something being on the front page.
$node = array(
'type' => 'page',
'title' => 'Test Page Node',
'path' => array(
'alias' => 'test-node',
),
'language' => LANGUAGE_NONE,
'promote' => 1,
);
// Save the node.
$this
->drupalCreateNode($node);
}
/**
* Returns list of paths to test.
*/
public function pathsToTest() {
$paths = array();
$paths[] = array(
'path' => 'node',
'options' => array(
'query' => array(
'a' => array(
1,
2,
),
'b' => array(
'c' => 3,
),
),
),
'expected_path' => 'node/p/a/0__1--1__2/b/c__3',
);
return $paths;
}
/**
* Tests if a path with query parameters gets redirected to the clean path.
*/
public function testRedirectWithQueryParameters() {
$this
->pass('Test redirecting to clean url when url has query parameters.');
$test_cases = $this
->pathsToTest();
foreach ($test_cases as $test_case) {
list($path, $options, $expected_path) = $this
->unpackTestCase($test_case);
// Make sure they are absolute URLs.
$path = $this
->createRawUrl($path, $options);
$expected_path = $this
->createRawUrl($expected_path, array());
// Make HEAD request and check the headers.
$this
->drupalHeadRawURL($path);
$headers = $this
->drupalGetHeaders(TRUE);
$result = array(
'!initial_path' => $path,
'!expected_status' => '302',
'!expected_path' => $expected_path,
'!actual_path' => isset($headers[0]['location']) ? $headers[0]['location'] : 'N/A',
'!actual_status' => $headers[0][':status'],
);
$this
->assertStatusAndPath($result);
}
}
/**
* Tests if inbound/outbound hooks do their job.
*/
public function testURLRewriting() {
$this
->pass('Test if urls are properly rewritten.');
$test_cases = $this
->pathsToTest();
foreach ($test_cases as $test_case) {
list($path, $options, $expected_path) = $this
->unpackTestCase($test_case);
// Make sure they are absolute URLs.
$expected_path = $this
->createRawUrl($expected_path, array());
// Make GET request and check the headers.
$this
->drupalGet($path, $options);
$headers = $this
->drupalGetHeaders(TRUE);
$result = array(
'!initial_path' => $path,
'!expected_status' => '200',
'!expected_path' => $expected_path,
'!actual_path' => $this
->getUrl(),
'!actual_status' => $headers[0][':status'],
);
$this
->assertStatusAndPath($result);
}
}
/**
* Tests url() encoding and decoding, affected by inbound / outbound hooks.
*/
public function testUrlEncodingAndDecoding() {
$this
->pass('Test encoding / decoding affected by inbound / outbound hooks.');
$test_cases = array();
$test_cases[] = array(
'path' => 'node',
'query' => array(
'page' => 1,
'f' => array(
0 => 'bundle:standard_page',
1 => 'sm_og_group_ref:node:100',
2 => 'dm_field_date:[2014-11-01T00:00:00Z TO 2014-12-01T00:00:00Z]',
),
),
'expected_path' => 'node/p/page/1/f/0__bundle%3Astandard_page--1__sm_og_group_ref%3Anode%3A100--2__dm_field_date%3A%5B2014-11-01T00%3A00%3A00Z%20TO%202014-12-01T00%3A00%3A00Z%5D',
);
foreach ($test_cases as $test_case) {
$initial_url = $test_case['path'];
$initial_query = $test_case['query'];
$expected_path = $this
->createRawUrl($test_case['expected_path'], array());
$options = array(
'query' => $initial_query,
'absolute' => TRUE,
);
$encoded_url = url($initial_url, $options);
$message = 'Encoding initial URL:<br/>!url<br/>Initial Query:<br/>!query<br/>Encoded to:<br/>!encoded<br/>Expected:<br/>!expected';
$message = format_string($message, array(
'!url' => $initial_url,
'!query' => var_export($initial_query, TRUE),
'!encoded' => $encoded_url,
'!expected' => $expected_path,
));
$this
->assertEqual($encoded_url, $expected_path, $message);
$decoded_url = $encoded_url;
$path_language = 'en';
query_parameters_to_url_url_inbound_alter($decoded_url, $decoded_url, $path_language);
$initial_url_absolute = $this
->createRawUrl($initial_url, array());
$message = 'Decoding clean URL:<br/>!url<br/>Decoded to:<br/>!decoded<br/>Expected:<br/>!expected';
$message = format_string($message, array(
'!url' => $encoded_url,
'!decoded' => $decoded_url,
'!expected' => $initial_url_absolute,
));
$this
->assertEqual($decoded_url, $initial_url_absolute, $message);
// Get the query parameters set by the inbound hook in $_GET. Make sure
// they are URL decoded, and that only the same parameters that were set
// in the test case are used.
$query_parameters = drupal_get_query_parameters();
$query_parameters_cleaned = $query_parameters;
array_walk_recursive($query_parameters_cleaned, array(
'QueryParametersToURLTestCase',
'applyUrlDecode',
));
foreach ($query_parameters_cleaned as $key => $parameter) {
if (!isset($initial_query[$key])) {
unset($query_parameters_cleaned[$key]);
}
}
$message = 'Decoding clean URL:<br/>!url<br/>Decoded query parameters to:<br/>!decoded<br/>Expected query parameters:<br/>!expected';
$message = format_string($message, array(
'!url' => $encoded_url,
'!decoded' => var_export($query_parameters_cleaned, TRUE),
'!expected' => var_export($initial_query, TRUE),
));
$this
->assertEqual($query_parameters_cleaned, $initial_query, $message);
}
}
/**
* URL decodes an array value.
*/
protected static function applyUrlDecode(&$item, $key) {
$item = urldecode($item);
}
/**
* Creates full absolute URL without going through url function().
*/
public function createRawUrl($path, $options) {
global $base_url, $base_secure_url, $base_insecure_url;
// The base_url might be rewritten from the language rewrite in domain mode.
if (!isset($options['base_url'])) {
if (isset($options['https']) && variable_get('https', FALSE)) {
if ($options['https'] === TRUE) {
$options['base_url'] = $base_secure_url;
$options['absolute'] = TRUE;
}
elseif ($options['https'] === FALSE) {
$options['base_url'] = $base_insecure_url;
$options['absolute'] = TRUE;
}
}
else {
$options['base_url'] = $base_url;
}
}
$base = $options['base_url'] . '/';
if (isset($options['query']) && !empty($options['query'])) {
return $base . $path . '?' . drupal_http_build_query($options['query']);
}
else {
return $base . $path;
}
}
/**
* Unpacks test case.
*/
public function unpackTestCase($test_case) {
return array(
$test_case['path'],
$test_case['options'],
$test_case['expected_path'],
);
}
/**
* Similar to drupalHead, but without piping to the url() function.
*/
public function drupalHeadRawURL($path, array $headers = array()) {
$out = $this
->curlExec(array(
CURLOPT_NOBODY => TRUE,
CURLOPT_URL => $path,
CURLOPT_HTTPHEADER => $headers,
));
$this
->refreshVariables();
// Ensure that any changes to variables in the other thread are picked up.
return $out;
}
/**
* Success message.
*/
public function getSuccessMessage() {
return 'SUCCESS<br />Initial Path: !initial_path<br />Expected Path: !expected_path<br />Expected Status Code: !expected_status<br />Actual path: !actual_path<br />Actual Status: !actual_status';
}
/**
* Error message.
*/
public function getErrorMessage() {
return 'ERROR<br />Initial Path: !initial_path<br />Expected Path: !expected_path<br />Expected Status Code: !expected_status<br />Actual path: !actual_path<br />Actual Status: !actual_status';
}
/**
* Checks if HTTP status code matches.
*/
public function expectedStatus($status, $expected_status) {
return strpos($status, (string) $expected_status) !== FALSE;
}
/**
* Asserts that the status code and paths are equivalent.
*/
public function assertStatusAndPath($result) {
// Make sure status and paths actually match.
if ($this
->expectedStatus($result['!actual_status'], $result['!expected_status']) && $result['!actual_path'] == $result['!expected_path']) {
return $this
->pass(format_string($this
->getSuccessMessage(), $result));
}
else {
return $this
->fail(format_string($this
->getErrorMessage(), $result));
}
}
}
/**
* Class QueryParametersToURLUnitTestCase.
*/
class QueryParametersToURLUnitTestCase extends DrupalUnitTestCase {
/**
* Returns test info.
*/
public static function getInfo() {
return array(
'name' => 'Query Parameters To URL Unit tests',
'description' => 'Test query parameter values encoding / decoding.',
'group' => 'Query Parameters To URL',
);
}
/**
* Setup.
*/
public function setUp() {
drupal_load('module', 'query_parameters_to_url');
parent::setUp();
}
/**
* Returns a list of test cases.
*/
public function getTestCases() {
$test_cases = array();
// ?value[a][1][2]=3&value[a][1][6]=7&value[b]=4&value[c]=5
$test_cases[] = array(
'parameter_value_array' => array(
'a' => array(
1 => array(
2 => 3,
6 => 7,
),
),
'b' => 4,
'c' => 5,
),
'encoded_parameter_value_string' => 'a__1__2__3--a__1__6__7--b__4--c__5',
);
// ?f[0]=standard_page&f[1]=sm_og_group_ref:node:100
$test_cases[] = array(
'parameter_value_array' => array(
0 => 'standard_page',
1 => 'sm_og_group_ref:node:100',
),
'encoded_parameter_value_string' => '0__standard_page--1__sm_og_group_ref:node:100',
);
return $test_cases;
}
/**
* Unpacks a test case.
*/
public function unpackTestCase($test_case) {
return array(
$test_case['parameter_value_array'],
$test_case['encoded_parameter_value_string'],
);
}
/**
* Tests if a query parameter's values are properly encoded.
*/
public function testQueryParameterValuesEncoding() {
$test_cases = $this
->getTestCases();
foreach ($test_cases as $test_case) {
list($parameter_values, $expected_query_parameter_string) = $this
->unpackTestCase($test_case);
$encoded_query_parameter = query_parameters_to_url_encode_query_parameter_values($parameter_values);
$message = 'Query parameter values are encoded properly.<br/> Initial array:<br/>!initial<br/>Encoded to string:<br/>!string';
$message = format_string($message, array(
'!initial' => var_export($parameter_values, TRUE),
'!string' => var_export($encoded_query_parameter, TRUE),
));
$this
->assertEqual($encoded_query_parameter, $expected_query_parameter_string, $message);
}
}
/**
* Tests if an encoded query parameter's values is properly decoded.
*/
public function testQueryParameterValuesDecoding() {
$test_cases = $this
->getTestCases();
foreach ($test_cases as $test_case) {
list($expected_parameter_values, $encoded_parameter_string) = $this
->unpackTestCase($test_case);
$decoded_query_parameter_values = query_parameters_to_url_decode_query_parameter_values($encoded_parameter_string);
$message = 'Query parameter values are decoded properly.<br/> Initial string:<br/>!initial<br/>Decoded to array:<br/>!array';
$message = format_string($message, array(
'!initial' => var_export($encoded_parameter_string, TRUE),
'!array' => var_export($decoded_query_parameter_values, TRUE),
));
$this
->assertEqual($decoded_query_parameter_values, $expected_parameter_values, $message);
}
}
}
/**
* Global redirect module integration.
*/
class QueryParametersToURLGlobalRedirectTestCase extends QueryParametersToURLTestCase {
/**
* Returns test info.
*/
public static function getInfo() {
return array(
'name' => 'Query Parameters To URL Global Redirect integration tests',
'description' => 'Test Query Parameters To URL integration with global redirect module.',
'group' => 'Query Parameters To URL',
'dependencies' => array(
'globalredirect',
),
);
}
/**
* Initial setup.
*/
public function setUp() {
DrupalWebTestCase::setUp(array(
'globalredirect',
'query_parameters_to_url',
));
// Enable rewriting on all paths.
variable_set(QUERY_PARAMETERS_TO_URL_PATH_REG_EXP, '{.+}');
// Clean URLs should be enabled for testing.
variable_set('clean_url', 1);
// Create test node just for the sake of something being on the front page.
$node = array(
'type' => 'page',
'title' => 'Test Page Node',
'path' => array(
'alias' => 'test-node',
),
'language' => LANGUAGE_NONE,
'promote' => 1,
);
// Save the node.
$this
->drupalCreateNode($node);
}
/**
* Tests if a path with query parameters gets redirected to the clean path.
*/
public function testRedirectWithQueryParameters() {
$this
->pass('Test redirecting to clean url when url has query parameters.');
$test_cases = $this
->pathsToTest();
foreach ($test_cases as $test_case) {
list($path, $options, $expected_path) = $this
->unpackTestCase($test_case);
// Make sure they are absolute URLs.
$raw_path = $this
->createRawUrl($path, $options);
// The expected path in case when global redirect is enabled, and the path
// was the frontpage, is to remove the front page prefix, so it's empty.
$expected_path_parts = explode('/', $expected_path);
array_shift($expected_path_parts);
$expected_path = implode('/', $expected_path_parts);
$raw_expected_path = $this
->createRawUrl($expected_path, array());
// Make HEAD request and check the headers.
$this
->drupalHeadRawURL($raw_path);
$headers = $this
->drupalGetHeaders(TRUE);
// First Global Redirect does it's own redirect, to a clean front page,
// but with the query parameters present in usual form.
$expected_redirect_path = $this
->createRawUrl('', $options);
$result_from_global_redirect = array(
'!initial_path' => $path,
'!expected_status' => '301',
'!expected_path' => $expected_redirect_path,
'!actual_path' => isset($headers[0]['location']) ? $headers[0]['location'] : 'N/A',
'!actual_status' => $headers[0][':status'],
);
$this
->assertStatusAndPath($result_from_global_redirect);
// Then we check for query parameters to url redirect, which redirects
// to the clean URL form.
$result_from_our_module_redirect = array(
'!initial_path' => $path,
'!expected_status' => '302',
'!expected_path' => $raw_expected_path,
'!actual_path' => isset($headers[1]['location']) ? $headers[1]['location'] : 'N/A',
'!actual_status' => $headers[1][':status'],
);
$this
->assertStatusAndPath($result_from_our_module_redirect);
}
}
/**
* Tests if inbound/outbound hooks do their job.
*/
public function testURLRewriting() {
$this
->pass('Test if urls are properly rewritten.');
$test_cases = $this
->pathsToTest();
foreach ($test_cases as $test_case) {
list($path, $options, $expected_path) = $this
->unpackTestCase($test_case);
// The expected path in case when global redirect is enabled, and the path
// was the frontpage, is to remove the front page prefix, so it's empty.
$expected_path_parts = explode('/', $expected_path);
array_shift($expected_path_parts);
$expected_path = implode('/', $expected_path_parts);
$raw_expected_path = $this
->createRawUrl($expected_path, array());
// Make GET request and check the headers.
$this
->drupalGet($path, $options);
$headers = $this
->drupalGetHeaders(TRUE);
// First Global Redirect does it's own redirect, to a clean front page,
// but with the query parameters present in usual form.
$expected_redirect_path = $this
->createRawUrl('', $options);
$result = array(
'!initial_path' => $path,
'!expected_status' => '301',
'!expected_path' => $expected_redirect_path,
'!actual_path' => isset($headers[0]['location']) ? $headers[0]['location'] : 'N/A',
'!actual_status' => $headers[0][':status'],
);
$success = $this
->assertStatusAndPath($result);
if (!$success) {
$this
->fail('<pre>' . print_r($headers, TRUE) . '</pre>');
}
// Then we check for query parameters to url redirect, which redirects
// to the clean URL form.
$result = array(
'!initial_path' => $headers[0]['location'],
'!expected_status' => '302',
'!expected_path' => $raw_expected_path,
'!actual_path' => isset($headers[1]['location']) ? $headers[1]['location'] : 'N/A',
'!actual_status' => $headers[1][':status'],
);
$success = $this
->assertStatusAndPath($result);
if (!$success) {
$this
->fail('<pre>' . print_r($headers, TRUE) . '</pre>');
}
// Then we get to the actual clean URL.
$result = array(
'!initial_path' => $headers[1]['location'],
'!expected_status' => '200',
'!expected_path' => $raw_expected_path,
'!actual_path' => $this
->getUrl(),
'!actual_status' => $headers[2][':status'],
);
$success = $this
->assertStatusAndPath($result);
if (!$success) {
$this
->fail('<pre>' . print_r($headers, TRUE) . '</pre>');
}
}
}
}
/**
* Menu item save tests.
*/
class QueryParametersToURLMenuItemTestCase extends DrupalWebTestCase {
protected $admin_user;
/**
* Returns test info.
*/
public static function getInfo() {
return array(
'name' => 'Query Parameters To URL Menu Item tests',
'description' => 'Test saving menu items with rewritten URLs that contain encoded query parameters.',
'group' => 'Query Parameters To URL',
);
}
/**
* Initial setup.
*/
public function setUp() {
parent::setUp(array(
'menu',
'query_parameters_to_url',
));
// Enable rewriting on all paths.
variable_set(QUERY_PARAMETERS_TO_URL_PATH_REG_EXP, '{.+}');
// Clean URLs should be enabled for testing.
variable_set('clean_url', 1);
// Create privileged user.
$permissions = array(
'access administration pages',
'administer blocks',
'administer menu',
'administer site configuration',
'create page content',
'edit any page content',
'delete any page content',
);
$this->admin_user = $this
->drupalCreateUser($permissions);
}
/**
* Tests saving menu items that contain rewritten URLs with parameters.
*/
public function testMenuItemSave() {
$this
->drupalLogin($this->admin_user);
$alias = 'test-node';
// Create test node which will be inserted into the menu item.
$node = array(
'type' => 'page',
'title' => 'Test Page Node',
'path' => array(
'alias' => $alias,
),
'language' => LANGUAGE_NONE,
'promote' => 1,
);
// Save the node.
$saved_node = $this
->drupalCreateNode($node);
$encoded_url = 'node/' . $saved_node->nid . '/p/a/0__1--1__2/b/c__3';
$expected_stripped_url = 'node/' . $saved_node->nid;
$link_title = 'Test Menu Item';
// Add the menu item.
$edit = array();
$edit['link_title'] = $link_title;
$edit['link_path'] = $encoded_url;
$this
->drupalPost('admin/structure/menu/manage/main-menu/add', $edit, t('Save'));
// Check that the URL encoded parameters were stripped, because menu item
// saving was not enabled yet.
$this
->assertText(t('The menu system stores system paths only, but will use the URL alias for display. !link_path has been stored as !normal_path', array(
'!link_path' => $encoded_url,
'!normal_path' => $expected_stripped_url,
)));
// Enable menu item saving.
variable_set(QUERY_PARAMETERS_TO_URL_ALLOW_REWRITTEN_MENU_ITEM_SAVE, TRUE);
// Get the menu item listing page.
$this
->drupalGet('admin/structure/menu/manage/main-menu');
// Get the edit link for the created menu item.
$this
->clickLink('edit', 1);
$edit_menu_item_url = $this
->getUrl();
// Re-submit the proper URL.
$edit = array();
$edit['link_title'] = $link_title;
$edit['link_path'] = $encoded_url;
$this
->drupalPost($edit_menu_item_url, $edit, t('Save'));
// This time the message should not appear, because we enabled saving of
// menu items that contain rewritten URLs.
$this
->assertNoText(t('The menu system stores system paths only, but will use the URL alias for display. !link_path has been stored as !normal_path', array(
'!link_path' => $encoded_url,
'!normal_path' => $expected_stripped_url,
)));
// Get the URL saved for the menu link.
$this
->drupalGet('admin/structure/menu/manage/main-menu');
$this
->assertLinkByHref($encoded_url);
// Click on the link, and check that it led to the proper page.
$this
->clickLink($link_title);
$url = $this
->getUrl();
$this
->assertEqual($url, $this
->getAbsoluteUrl($encoded_url));
}
}
Classes
Name | Description |
---|---|
QueryParametersToURLGlobalRedirectTestCase | Global redirect module integration. |
QueryParametersToURLMenuItemTestCase | Menu item save tests. |
QueryParametersToURLTestCase | General test cases. |
QueryParametersToURLUnitTestCase | Class QueryParametersToURLUnitTestCase. |