t('Webform submission'), 'description' => t('Submits a sample webform and checks the database integrity.'), 'group' => t('Webform'), ); } /** * Test sending a submission and check database integrity. */ public function testWebformSubmission() { $this->drupalLogin($this->webform_users['admin']); $this->webformReset(); $this->webformSubmissionExecute('sample'); $loggedInUser = $this->loggedInUser; $this->drupalLogout(); // Test webform_get_submission_count(). // Counting the anonymous submission doesn't work because // $_SESSION['webform_submission'] is not populated in testing. $this->webformSubmissionExecute('sample'); $count = webform_get_submission_count($this->webformForm()->nid); $this->assertIdentical((int) $count, 2, 'webform_get_submission_count() counts 2 total submissions.'); $count = webform_get_submission_count($this->webformForm()->nid, $loggedInUser->uid); $this->assertIdentical((int) $count, 1, 'webform_get_submission_count() counts 1 submission from loggedInUser.'); // Test _webform_submission_prepare_mail(). $node = node_load($this->webformForm()->nid); $submission = webform_get_submissions($node->nid); $submission = array_pop($submission); $email = array( 'status' => TRUE, 'html' => FALSE, 'template' => 'default', 'from_address' => 'Test From', 'from_name' => 'from@example.com', 'subject' => 'Test Subject', 'email' => 'to@example.com', ); variable_set('webform_email_replyto', TRUE); variable_set('webform_email_address_format', 'long'); variable_set('webform_default_from_name', 'Default "From" Name'); variable_set('webform_default_from_address', 'default-from@example.com'); $prepared_email = _webform_submission_prepare_mail($node, $submission, $email); $this->assertIdentical($prepared_email['mail_params']['email']['from'], '"from@example.com via Default \'From\' Name" ', 'From address is correctly set in _webform_submission_prepare_mail().'); } /** * Test that the correct submissions are offered for download. */ public function testWebformSubmissionDownload() { $this->drupalLogin($this->webform_users['userAccess']); $this->webformReset(); // Create Webform which allows drafts and submit a draft. $webform_settings = array( 'allow_draft' => '1', ); $this->webformSubmissionExecute('sample', TRUE, $webform_settings); $nid = $this->webformForm()->nid; // This submit should complete the draft. $this->webformSubmissionExecute('sample'); // Create another draft. $this->webformSubmissionExecute('sample', TRUE); // Create finished and draft submission as another user. $this->drupalLogin($this->webform_users['editor']); $this->webformSubmissionExecute('sample'); $this->webformSubmissionExecute('sample', TRUE); // Create finished submission as anonymous. $this->drupalLogout(); $this->webformSubmissionExecute('sample'); $this->drupalLogin($this->webform_users['editor']); // Test webform_download_sids(). $sids = webform_download_sids($nid, array('range_type' => 'new', 'completion_type' => 'finished'), (int) $this->webform_users['editor']->uid); $this->assertIdentical($sids, array('1', '3', '5'), 'webform_download_sids() shows correct finished submissions.'); $sids = webform_download_sids($nid, array('range_type' => 'new', 'completion_type' => 'draft'), (int) $this->webform_users['editor']->uid); $this->assertIdentical($sids, array('2', '4'), 'webform_download_sids() shows correct draft submissions.'); // The timestamp of the Webform results download simulated by the call to // webform_update_webform_last_download() needs to be after the timestamps // of the submissions made above. This ensures that the call to time() will // be after the submission timestamps. sleep(1); // Record that submissions so-far have been downloaded. // Parameter $sid is not used, so it's value doesn't matter. webform_update_webform_last_download($this->webformForm(), (int) $this->webform_users['editor']->uid, 0, time()); // Following the simulated download, there are none to download. $sids = webform_download_sids($nid, array('range_type' => 'new', 'completion_type' => 'finished'), (int) $this->webform_users['editor']->uid); $this->assertIdentical($sids, array(), 'webform_download_sids() shows correct finished submissions.'); $sids = webform_download_sids($nid, array('range_type' => 'new', 'completion_type' => 'draft'), (int) $this->webform_users['editor']->uid); $this->assertIdentical($sids, array(), 'webform_download_sids() shows correct draft submissions.'); // Finish the draft, add a new draft, and re-check submission lists. $this->webformSubmissionExecute('sample'); $this->webformSubmissionExecute('sample', TRUE); $sids = webform_download_sids($nid, array('range_type' => 'new', 'completion_type' => 'finished'), (int) $this->webform_users['editor']->uid); $this->assertIdentical($sids, array('4'), 'webform_download_sids() shows correct finished submissions.'); $sids = webform_download_sids($nid, array('range_type' => 'new', 'completion_type' => 'draft'), (int) $this->webform_users['editor']->uid); $this->assertIdentical($sids, array('6'), 'webform_download_sids() shows correct draft submissions.'); } /** * Test Webform submission utility functions. * * Test webform_update_webform_last_download() and * webform_download_last_download_info(). */ public function testWebformSubmissionFunctions() { $node = (object) array('nid' => 1); $uid = 1; $result = webform_update_webform_last_download($node, $uid, 10, 1000); $this->assertIdentical($result, MergeQuery::STATUS_INSERT, 'webform_update_webform_last_download() reports successful insert.'); $result = webform_download_last_download_info($node->nid, $uid); $test = array( 'nid' => '1', 'uid' => '1', 'sid' => '10', 'requested' => '1000', 'serial' => NULL, ); $this->assertIdentical($result, $test, 'webform_download_last_download_info() returned correct result.'); $result = webform_update_webform_last_download($node, $uid, 20, 2000); $this->assertIdentical($result, MergeQuery::STATUS_UPDATE, 'webform_update_webform_last_download() reports successful update.'); $result = webform_download_last_download_info($node->nid, $uid); $test = array( 'nid' => '1', 'uid' => '1', 'sid' => '20', 'requested' => '2000', 'serial' => NULL, ); $this->assertIdentical($result, $test, 'webform_download_last_download_info() returned correct result.'); } /** * Test a submission that uses default values, and check database integrity. */ public function testWebformSubmissionDefault() { $this->drupalLogin($this->webform_users['admin']); $this->webformReset(); $this->webformSubmissionExecute('default'); $this->drupalLogout(); } /** * Test validation errors on each component that has specialized validation. */ public function testWebformSubmissionValidate() { $this->drupalLogin($this->webform_users['admin']); $this->webformReset(); $this->webformSubmissionValidateExecute(); $this->drupalLogout(); } /** * Test that required fields with no default value can't be submitted as-is. */ public function testWebformSubmissionRequiredComponents() { $this->drupalLogin($this->webform_users['admin']); $this->webformReset(); // Create the Webform test node, and set all components to be required // with no default value. $node = $this->webformForm(); $node = node_load($node->nid); foreach ($node->webform['components'] as &$component) { $component['value'] = ''; $component['required'] = '1'; } node_save($node); // Submit the webform with no data. We should get a message that all the // components are required. The exceptions are hidden fields, which can't be // made required, and date fields, which default to the current date when no // default value is provided; therefore, we don't expect a message for // those. $this->drupalPost('node/' . $node->nid, array(), 'Submit', array(), array(), 'webform-client-form-' . $node->nid); foreach ($node->webform['components'] as $component) { if ($component['type'] != 'hidden' && $component['type'] != 'date') { $this->assertText(t('!name field is required.', array('!name' => $component['name']))); } } $this->drupalLogout(); } /** * Test length validation. */ public function testWebformSubmissionComponentLength() { $this->drupalLogin($this->webform_users['admin']); $this->webformReset(); // Create the Webform test node. $node = $this->webformForm(); $node = node_load($node->nid); // Get the cid of the textfield component. foreach ($node->webform['components'] as &$component) { if ($component['form_key'] === 'textfield') { $textfield_cid = $component['cid']; break; } } // Set length validation rules. $node->webform['components'][$textfield_cid]['extra']['maxlength'] = 5; $node->webform['components'][$textfield_cid]['extra']['minlength'] = 4; node_save($node); // Text value that is too long. $this->drupalPost('node/' . $node->nid, array('submitted[textfield]' => '123456'), 'Submit', array(), array(), 'webform-client-form-' . $node->nid); $this->assertRaw(t('!name cannot be longer than %max characters but is currently %length characters long.', array('!name' => $node->webform['components'][$textfield_cid]['name'], '%max' => 5, '%length' => 6))); // Text value that is too short. $this->drupalPost('node/' . $node->nid, array('submitted[textfield]' => '123'), 'Submit', array(), array(), 'webform-client-form-' . $node->nid); $this->assertRaw(t('!name cannot be shorter than %min characters but is currently %length characters long.', array('!name' => $node->webform['components'][$textfield_cid]['name'], '%min' => 4, '%length' => 3))); // Test value that meets validation rules has no error message. $this->drupalPost('node/' . $node->nid, array('submitted[textfield]' => '12345'), 'Submit', array(), array(), 'webform-client-form-' . $node->nid); $this->assertNoPattern('/ cannot be (longer|shorter) than /'); } /** * Test webform_submission_data() function. * * Do not save components that do not collect data, for example, markup. */ public function testPlainComponentsSubmission() { $node = (object) [ 'webform' => [ 'components' => [ ['type' => 'date'], ['type' => 'email'], ['type' => 'grid'], ['type' => 'hidden'], ['type' => 'number'], ['type' => 'select'], ['type' => 'textarea'], ['type' => 'textfield'], ['type' => 'time'], ['type' => 'fieldset'], ['type' => 'markup'], ['type' => 'pagebreak'], ], ], ]; $submitted = [ 'date', 'email', ['value' => 'grid'], 'hidden', 'number', 'select', 'textarea', 'textfield', 'time', 'fieldset', 'markup', 'pagebreak', ]; $test_data = webform_submission_data($node, $submitted); $sample_data = [ ['date'], ['email'], ['value' => 'grid'], ['hidden'], ['number'], ['select'], ['textarea'], ['textfield'], ['time'], ]; $this->assertIdentical($test_data, $sample_data, 'webform_submission_data() generates correct data array.'); } /** * Execute the submission test. * * @param string $value_type * The values to be submitted to the webform. Either "sample" or "default". * @param bool $save_draft * Whether to save a draft or a final submission. * @param array $webform_settings * Settings to use for this form. Any unspecific settings will be default. */ public function webformSubmissionExecute($value_type = 'sample', $save_draft = FALSE, array $webform_settings = array()) { $path = drupal_get_path('module', 'webform'); module_load_include('inc', 'webform', 'includes/webform.submissions'); // Create a new Webform test node. $node = $this->webformForm($webform_settings); $submission_values = $value_type == 'sample' ? $this->webformPost() : array(); // Visit the node page with the "foo=bar" query, to test // [current-page:query:?] default values. $this->drupalGet('node/' . $node->nid, array('query' => array('foo' => 'bar'))); $this->assertText($node->title, t('Webform node created and accessible at !url', array('!url' => 'node/' . $node->nid)), t('Webform')); // Submit our test data. $this->drupalPost(NULL, $submission_values, $save_draft ? 'Save Draft' : 'Submit', array(), array(), 'webform-client-form-' . $node->nid); if ($save_draft) { $this->assertText(t('Submission saved. You may return to this form later and it will restore the current values.'), t('Save draft message displayed.'), t('Webform')); return; } // Confirm that the submission has been created. $this->assertText($node->webform['confirmation'], t('Confirmation message "@confirmation" received.', array('@confirmation' => $node->webform['confirmation'])), t('Webform')); // Get the SID of the new submission. $matches = array(); preg_match('/sid=([0-9]+)/', $this->getUrl(), $matches); $sid = isset($matches[1]) ? $matches[1] : NULL; // Pull in the database submission and check the values. drupal_static_reset('webform_get_submission'); $actual_submission = webform_get_submission($node->nid, $sid); $component_info = $this->webformComponents(); foreach ($node->webform['components'] as $cid => $component) { $stable_value = $value_type == 'sample' ? $component_info[$component['form_key']]['database values'] : $component_info[$component['form_key']]['database default values']; $actual_value = isset($actual_submission->data[$cid]) ? $actual_submission->data[$cid] : NULL; $result = $this->assertEqual($stable_value, $actual_value, t('Component @form_key data integrity check when using @type values.', array('@form_key' => $component['form_key'], '@type' => $value_type)), t('Webform')); if (!$result || $result === 'fail') { $this->fail(t("Expected !expected\n\nRecieved !recieved", array('!expected' => print_r($stable_value, TRUE), '!recieved' => print_r($actual_value, TRUE))), t('Webform')); } } } /** * Execute a validation check for a single component. */ public function webformSubmissionValidateExecute() { $path = drupal_get_path('module', 'webform'); module_load_include('inc', 'webform', 'includes/webform.submissions'); // Create a new Webform test node. $node = $this->webformForm(); // Visit the node page. $this->drupalGet('node/' . $node->nid); foreach ($this->webformComponents() as $key => $component_info) { if (isset($component_info['error values'])) { foreach ($component_info['error values'] as $value => $error_message) { $submission_values = array(); $submission_values["submitted[$key]"] = $value; // Submit our test data. $this->drupalPost('node/' . $node->nid, $submission_values, 'Submit', array(), array(), 'webform-client-form-' . $node->nid); // Confirm that the validation error occurred and the submission did // not save. $this->assertRaw($error_message, t('Validation message properly thrown: "%message".', array('%message' => $error_message)), t('Webform')); $this->assertFalse(preg_match('/sid=([0-9]+)/', $this->getUrl()), t('Submission not saved.')); } } } } }