summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--modules/field/field.form.inc15
-rw-r--r--modules/field/field.test82
2 files changed, 87 insertions, 10 deletions
diff --git a/modules/field/field.form.inc b/modules/field/field.form.inc
index 234eb69c2..bc7b1426d 100644
--- a/modules/field/field.form.inc
+++ b/modules/field/field.form.inc
@@ -184,7 +184,7 @@ function field_multiple_value_form($field, $instance, $items, &$form, &$form_sta
}
// Add AHAH add more button, if not working with a programmed form.
- if ($field['cardinality'] == FIELD_CARDINALITY_UNLIMITED && empty($form['#programmed'])) {
+ if ($field['cardinality'] == FIELD_CARDINALITY_UNLIMITED && empty($form_state['programmed'])) {
// Make sure the form is cached so ahah can work.
$form['#cache'] = TRUE;
$bundle_name_url_str = str_replace('_', '-', $instance['bundle']);
@@ -351,7 +351,7 @@ function field_add_more_js($bundle_name, $field_name) {
}
// Retrieve the cached form.
- $form_state = array('submitted' => FALSE);
+ $form_state = form_state_defaults();
$form_build_id = $_POST['form_build_id'];
$form = form_get_cache($form_build_id, $form_state);
if (!$form) {
@@ -387,7 +387,7 @@ function field_add_more_js($bundle_name, $field_name) {
// $form_state, so we use copies of $form and $form_state.
$form_copy = $form;
$form_state_copy = $form_state;
- $form_copy['#post'] = array();
+ $form_state_copy['input'] = array();
form_builder($_POST['form_id'], $form_copy, $form_state_copy);
// Just grab the data we need.
$form_state['values'] = $form_state_copy['values'];
@@ -425,15 +425,12 @@ function field_add_more_js($bundle_name, $field_name) {
// render the new element.
$delta = max(array_keys($_POST[$field_name])) + 1;
$_POST[$field_name][$delta]['_weight'] = $delta;
- $form_state = array('submitted' => FALSE);
- $form += array(
- '#post' => $_POST,
- '#programmed' => FALSE,
- );
+ $form_state = form_state_defaults();
+ $form_state['input'] = $_POST;
$form = form_builder($_POST['form_id'], $form, $form_state);
// Render the new output.
- // We get fetch the form element from the built $form.
+ // We fetch the form element from the built $form.
$field_form = $form;
foreach ($form_path as $key) {
$field_form = $field_form[$key];
diff --git a/modules/field/field.test b/modules/field/field.test
index 64a13f323..8af8aa55b 100644
--- a/modules/field/field.test
+++ b/modules/field/field.test
@@ -856,7 +856,7 @@ class FieldFormTestCase extends DrupalWebTestCase {
// We'll need three slightly different formats to check the values.
$values[$weight] = $value;
$field_values[$weight]['value'] = (string)$value;
- $pattern[$weight] = " value=\"$value\"";
+ $pattern[$weight] = "<input [^>]*value=\"$value\" [^>]*";
}
// Press 'add more' button -> 4 widgets
@@ -896,6 +896,86 @@ class FieldFormTestCase extends DrupalWebTestCase {
// check inaccessible fields are preserved on update
// check inaccessible fields get default value on insert (not implemented yet)
+ function testFieldFormJSAddMore() {
+ $this->field = $this->field_unlimited;
+ $this->field_name = $this->field['field_name'];
+ $this->instance['field_name'] = $this->field_name;
+ field_create_field($this->field);
+ field_create_instance($this->instance);
+
+ // Display creation form -> 1 widget.
+ $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.
+ $this->drupalPost(NULL, array(), t('Add another item'));
+ $this->drupalPost(NULL, array(), t('Add another item'));
+
+ // Prepare values and weights.
+ $count = 3;
+ $delta_range = $count - 1;
+ $values = $weights = $pattern = $expected_values = $edit = array();
+ for ($delta = 0; $delta <= $delta_range; $delta++) {
+ // Assign unique random weights.
+ do {
+ $weight = mt_rand(-$delta_range, $delta_range);
+ } while (in_array($weight, $weights));
+ $weights[] = $weight;
+ $value = mt_rand(1, 127);
+ $edit["$this->field_name[$delta][value]"] = $value;
+ $edit["$this->field_name[$delta][_weight]"] = $weight;
+ // We'll need three slightly different formats to check the values.
+ $values[$weight] = $value;
+ $field_values[$weight]['value'] = (string)$value;
+ $pattern[$weight] = "<input [^>]*value=\"$value\" [^>]*";
+ }
+ // Press 'add more' button through AHAH.
+ $path = 'field/js_add_more/' . str_replace('_', '-', $this->instance['bundle']) . '/' . str_replace('_', '-', $this->instance['field_name']);
+ $this->_fieldPostAhah($path, $edit, t('Add another item'));
+
+ ksort($values);
+ $values = array_values($values);
+ for ($delta = 0; $delta <= $delta_range; $delta++) {
+ $this->assertFieldByName("$this->field_name[$delta][value]", $values[$delta], "Widget $delta is displayed and has the right value");
+ $this->assertFieldByName("$this->field_name[$delta][_weight]", $delta, "Widget $delta has the right weight");
+ }
+ ksort($pattern);
+ $pattern = implode('.*', array_values($pattern));
+ $this->assertPattern("|$pattern|s", 'Widgets are displayed in the correct order');
+ $this->assertFieldByName("$this->field_name[$delta][value]", '', "New widget is displayed");
+ $this->assertFieldByName("$this->field_name[$delta][_weight]", $delta, "New widget has the right weight");
+ $this->assertNoField("$this->field_name[". ($delta + 1) . '][value]', 'No extraneous widget is displayed');
+ }
+
+ /**
+ * 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($path, $edit, $submit, array $options = array(), array $headers = array()) {
+ // @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($path, array('absolute' => TRUE));
+ $this->drupalPost(NULL, $edit, $submit);
+ unset($this->additionalCurlOptions[CURLOPT_URL]);
+
+ // The response is drupal_json, so we need to undo some escaping.
+ $response = json_decode(str_replace(array('\x3c', '\x3e', '\x26'), array("<", ">", "&"), $this->drupalGetContent()));
+ $this->assertTrue(is_object($response), t('The response is an object'));
+ $this->assertIdentical($response->status, TRUE, t('Response status is true'));
+ // This response data is valid HTML so we will can reuse everything we have
+ // for HTML pages.
+ $this->content = $response->data;
+
+ // Needs to be emptied out so the new content will be parsed.
+ $this->elements = '';
+ }
}
class FieldTestCase extends DrupalWebTestCase {