diff options
-rw-r--r-- | modules/field/field.form.inc | 15 | ||||
-rw-r--r-- | modules/field/field.test | 82 |
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 { |