Commit 59ceca0c authored by webchick's avatar webchick
Browse files

#633156 follow-up by effulgentsia and yched: Clean up AJAX tests, add sister...

#633156 follow-up by effulgentsia and yched: Clean up AJAX tests, add sister function to drupal_js_encode().
parent 34119ba9
......@@ -4342,10 +4342,22 @@ function drupal_clear_js_cache() {
* Converts a PHP variable into its Javascript equivalent.
*
* We use HTML-safe strings, i.e. with <, > and & escaped.
*
* @see drupal_json_decode()
*/
function drupal_json_encode($var) {
// json_encode() does not escape <, > and &, so we do it with str_replace()
return str_replace(array("<", ">", "&"), array('\x3c', '\x3e', '\x26'), json_encode($var));
// json_encode() does not escape <, > and &, so we do it with str_replace().
return str_replace(array('<', '>', '&'), array('\x3c', '\x3e', '\x26'), json_encode($var));
}
/**
* Converts an HTML-safe JSON string into its PHP equivalent.
*
* @see drupal_json_encode()
*/
function drupal_json_decode($var) {
// json_decode() does not unescape <, > and &, so we do it with str_replace().
return json_decode(str_replace(array('\x3c', '\x3e', '\x26'), array('<', '>', '&'), $var), TRUE);
}
/**
......
......@@ -1552,8 +1552,8 @@ class FieldFormTestCase extends FieldTestCase {
$this->drupalGet('test-entity/add/test-bundle');
// Press 'add more' button a couple times -> 3 widgets.
// The drupalPostAhah() helper will not work iteratively, so we add those.
// through non-'JS' submission.
// drupalPostAJAX() will not work iteratively, so we add those through
// non-JS submission.
$this->drupalPost(NULL, array(), t('Add another item'));
$this->drupalPost(NULL, array(), t('Add another item'));
......@@ -1575,8 +1575,10 @@ class FieldFormTestCase extends FieldTestCase {
$field_values[$weight]['value'] = (string)$value;
$pattern[$weight] = "<input [^>]*value=\"$value\" [^>]*";
}
// Press 'add more' button through AHAH.
$this->_fieldPostAhah($edit, t('Add another item'));
// Press 'add more' button through AJAX, and place the expected HTML result
// as the tested content.
$commands = $this->drupalPostAJAX(NULL, $edit, $this->field_name . '_add_more');
$this->content = $commands[1]['data'];
ksort($values);
$values = array_values($values);
......@@ -1650,39 +1652,6 @@ class FieldFormTestCase extends FieldTestCase {
$this->assertEqual($entity->{$field_name_no_access}[$langcode][0]['value'], 99, t('New revision has the expected value for the field with no edit access.'));
$this->assertEqual($entity->{$field_name}[$langcode][0]['value'], 2, t('New revision has the expected value for the field with edit access.'));
}
/**
* Execute a POST request on a AHAH callback.
*
* Stolen from poll.test. The JSON result is parsed into HTML and placed in
* $this->content, so that regular asserts can be performed.
*
* Since the result is generally not a full-fledged form, this cannot be
* called iteratively.
*/
function _fieldPostAhah($edit, $submit, array $options = array(), array $headers = array()) {
$this->additionalCurlOptions[CURLOPT_URL] = url('system/ajax', array('absolute' => TRUE));
$this->drupalPost(NULL, $edit, $submit);
unset($this->additionalCurlOptions[CURLOPT_URL]);
// The response is drupal_json_output, so we need to undo some escaping.
$commands = json_decode(str_replace(array('\x3c', '\x3e', '\x26'), array("<", ">", "&"), $this->drupalGetContent()));
// The JSON response will be two AJAX commands. The first is a settings
// command and the second is the replace command.
$settings = reset($commands);
$replace = next($commands);
$this->assertTrue(is_object($settings), t('The response settings command is an object'));
$this->assertTrue(is_object($replace), t('The response replace command is an object'));
// This response data is valid HTML so we will can reuse everything we have
// for HTML pages.
$this->content = $replace->data;
// Needs to be emptied out so the new content will be parsed.
$this->elements = '';
}
}
class FieldCrudTestCase extends FieldTestCase {
......
......@@ -339,30 +339,11 @@ class PollJSAddChoice extends DrupalWebTestCase {
'choice[new:1][chtext]' => $this->randomName(),
);
// @TODO: the framework should make it possible to submit a form to a
// different URL than its action or the current. For now, we can just force
// it.
$this->additionalCurlOptions[CURLOPT_URL] = url('system/ajax', array('absolute' => TRUE));
$this->drupalPost(NULL, $edit, t('More choices'));
unset($this->additionalCurlOptions[CURLOPT_URL]);
// The response is drupal_json_output, so we need to undo some escaping.
$commands = json_decode(str_replace(array('\x3c', '\x3e', '\x26'), array("<", ">", "&"), $this->drupalGetContent()));
// The JSON response will be two AJAX commands. The first is a settings
// command and the second is the replace command.
$settings = reset($commands);
$replace = next($commands);
$this->assertTrue(is_object($settings), t('The response settings command is an object'));
$this->assertTrue(is_object($replace), t('The response replace command is an object'));
// This replace data is valid HTML so we will can reuse everything we have
// for HTML pages.
$this->content = $replace->data;
// Needs to be emptied out so the new content will be parsed.
$this->elements = '';
// Press 'add choice' button through AJAX, and place the expected HTML result
// as the tested content.
$commands = $this->drupalPostAJAX(NULL, $edit, 'poll_more');
$this->content = $commands[1]['data'];
$this->assertFieldByName('choice[chid:0][chtext]', $edit['choice[new:0][chtext]'], t('Field !i found', array('!i' => 0)));
$this->assertFieldByName('choice[chid:1][chtext]', $edit['choice[new:1][chtext]'], t('Field !i found', array('!i' => 1)));
$this->assertFieldByName('choice[new:0][chtext]', '', t('Field !i found', array('!i' => 2)));
......
......@@ -1404,8 +1404,7 @@ protected function drupalGet($path, array $options = array(), array $headers = a
* Retrieve a Drupal path or an absolute path and JSON decode the result.
*/
function drupalGetAJAX($path, array $options = array(), array $headers = array()) {
$out = $this->drupalGet($path, $options, $headers);
return json_decode($out, TRUE);
return drupal_json_decode($this->drupalGet($path, $options, $headers));
}
/**
......@@ -1545,8 +1544,7 @@ protected function drupalPost($path, $edit, $submit, array $options = array(), a
* Execute a POST request on an AJAX path and JSON decode the result.
*/
protected function drupalPostAJAX($path, $edit, $triggering_element, $ajax_path = 'system/ajax', array $options = array(), array $headers = array()) {
$out = $this->drupalPost($path, $edit, array('path' => $ajax_path, 'triggering_element' => $triggering_element), $options, $headers);
return json_decode($out, TRUE);
return drupal_json_decode($this->drupalPost($path, $edit, array('path' => $ajax_path, 'triggering_element' => $triggering_element), $options, $headers));
}
/**
......
......@@ -1723,3 +1723,55 @@ class DrupalAttributesUnitTest extends DrupalUnitTestCase {
$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.'));
}
}
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment