WebformConditionalsTestCase.test 8.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224
  1. <?php
  2. /**
  3. * Webform module conditional tests.
  4. */
  5. class WebformConditionalsTestCase extends WebformTestCase {
  6. /**
  7. * {@inheritdoc}
  8. */
  9. public static function getInfo() {
  10. return array(
  11. 'name' => t('Webform conditionals'),
  12. 'description' => t('Generates webforms to test conditional showing and hiding of fields.'),
  13. 'group' => t('Webform'),
  14. );
  15. }
  16. /**
  17. * Test that required fields with no default value can't be submitted as-is.
  18. */
  19. public function testWebformConditionals() {
  20. $this->drupalLogin($this->webform_users['admin']);
  21. $this->webformReset();
  22. $test_components = $this->webformComponents();
  23. $test_specs = array(
  24. 'match conditional values' => TRUE,
  25. 'mismatch conditional values' => FALSE,
  26. );
  27. // Test each component, processing all 'match conditional values' for TRUE
  28. // and all 'mismatch conditional values for FALSE.
  29. foreach ($test_components as $key => $component_info) {
  30. foreach ($test_specs as $values_key => $result) {
  31. if (isset($component_info[$values_key])) {
  32. foreach ($component_info[$values_key] as $operator => $match_value) {
  33. $this->webformTestConditionalComponent($component_info['component'], $component_info['sample values'], $operator, $match_value, $result);
  34. }
  35. }
  36. }
  37. }
  38. $this->drupalLogout();
  39. // Test that the whole conditional is deleted when all source components are
  40. // deleted. Inital setup: Two components. One source (c1) one target (c2).
  41. $node = (object) array(
  42. 'type' => 'webform',
  43. 'title' => 'Conditional test',
  44. );
  45. $default = array(
  46. 'type' => 'textfield',
  47. 'pid' => 0,
  48. );
  49. webform_component_defaults($default);
  50. node_object_prepare($node);
  51. $node->webform['components'][1] = array(
  52. 'cid' => 1,
  53. 'form_key' => 'c1',
  54. ) + $default;
  55. $node->webform['components'][2] = array(
  56. 'cid' => 2,
  57. 'form_key' => 'c2',
  58. ) + $default;
  59. $node->webform['conditionals'][0] = array(
  60. 'rgid' => 0,
  61. 'andor' => NULL,
  62. 'weight' => -1,
  63. 'rules' => array(array(
  64. 'source_type' => 'component',
  65. 'source' => 1,
  66. 'operator' => 'not_empty',
  67. ),
  68. ),
  69. 'actions' => array(array(
  70. 'target_type' => 'component',
  71. 'target' => 2,
  72. 'action' => 'show',
  73. ),
  74. ),
  75. );
  76. node_save($node);
  77. // Delete the source.
  78. unset($node->webform['components'][1]);
  79. node_save($node);
  80. $this->assertEqual(array(), $node->webform['conditionals'], 'The whole conditional is deleted when all source components are deleted.');
  81. }
  82. /**
  83. * Assembles a test node for checking if conditional properties are respected.
  84. *
  85. * @param $component
  86. * The sample component that should be tested as the source of a conditional
  87. * operator.
  88. * @param $input_values
  89. * @param $operator
  90. * The operator that will be used to check the source component, such as
  91. * "equal" or "starts_with". See _webform_conditional_operator_info().
  92. * @param $conditional_values
  93. * The string match value that will be entered into the source component's
  94. * conditional configuration. If passed in as an array, multiple rules
  95. * will be added to the conditional.
  96. * @param $should_match
  97. * Boolean value indicating if the source values will cause the conditional
  98. * operation to trigger or not. If TRUE, the submission should succeed.
  99. * If FALSE, validation errors are expected to be triggered. The input
  100. * $value will be compared against the "sample values" input provided by
  101. * webformComponents().
  102. */
  103. private function webformTestConditionalComponent($component, $input_values, $operator, $conditional_values, $should_match) {
  104. // Create the Webform test node and add a same-page conditional followed
  105. // by a second-page conditional. Insert page breaks between all components.
  106. $input_string = (is_array($input_values) ? print_r($input_values, 1) : $input_values);
  107. $match_string = (is_array($conditional_values) ? print_r($conditional_values, 1) : $conditional_values);
  108. $conditional_string = $should_match ? 'should' : 'should not';
  109. $settings = array(
  110. 'title' => 'Test conditional webform: ' . $component['type'] . ' "' . $input_string . '"' . $conditional_string . ' be ' . $operator . ' "' . $match_string . '"',
  111. 'type' => 'webform',
  112. 'webform' => webform_node_defaults(),
  113. );
  114. $components = array();
  115. $components[] = $component;
  116. $test_components = $this->webformComponents();
  117. $textfield = $test_components['textfield']['component'];
  118. // Add a test textfield on the first page.
  119. $textfield['weight'] = '199';
  120. $textfield['form_key'] = $this->randomName();
  121. $textfield['required'] = '1';
  122. $components[] = $textfield;
  123. // Then add a page break and another textfield on the second page.
  124. $components[] = array(
  125. 'type' => 'pagebreak',
  126. 'form_key' => 'pagebreak_' . $this->randomName(),
  127. 'pid' => 0,
  128. 'name' => 'Page break',
  129. 'weight' => '200',
  130. );
  131. $textfield['form_key'] = $this->randomName();
  132. $textfield['weight'] = '201';
  133. $components[] = $textfield;
  134. $settings['webform']['components'] = $components;
  135. $node = $this->drupalCreateNode($settings);
  136. // Needed to get a complete object.
  137. $node = node_load($node->nid);
  138. // We now have a new test node. First try checking same-page conditionals.
  139. $rules = array();
  140. $conditional_values = is_array($conditional_values) ? $conditional_values : array($conditional_values);
  141. foreach ($conditional_values as $conditional_value) {
  142. $rules[] = array(
  143. 'source_type' => 'component',
  144. // The first component in the form is always the source.
  145. 'source' => 1,
  146. 'operator' => $operator,
  147. 'value' => $conditional_value,
  148. );
  149. }
  150. $conditional = array(
  151. 'rgid' => 0,
  152. 'rules' => $rules,
  153. 'andor' => 'and',
  154. 'actions' => array(
  155. 0 => array(
  156. 'action' => 'show',
  157. // Target set individually.
  158. 'target' => NULL,
  159. 'target_type' => 'component',
  160. 'invert' => '1',
  161. 'argument' => NULL,
  162. ),
  163. ),
  164. 'weight' => 0,
  165. );
  166. // The same-page textfield test.
  167. $conditional['actions'][0]['target'] = 2;
  168. $node->webform['conditionals'] = array($conditional);
  169. node_save($node);
  170. // Submit our test data.
  171. $edit = $this->webformPost(array($component['form_key'] => $input_values));
  172. $this->drupalPost('node/' . $node->nid, $edit, 'Next Page >', array(), array(), 'webform-client-form-' . $node->nid);
  173. // Ensure we reached the second page for matched conditionals.
  174. $message = t('Conditional same-page skipping of validation passed for "%form_key": %input_values @conditional_string be @operator %match_string', array('%form_key' => $component['form_key'], '%input_values' => $input_string, '@conditional_string' => $conditional_string, '@operator' => $operator, '%match_string' => $match_string));
  175. if ($should_match) {
  176. $this->assertRaw('&lt; Previous Page', $message, t('Webform'));
  177. }
  178. // Or that we did not reach the second page for mismatched conditionals.
  179. else {
  180. $this->assertNoRaw('&lt; Previous Page', $message, t('Webform'));
  181. }
  182. // Adjust the conditionals to make them separate-page conditionals.
  183. // The separate-page textfield test.
  184. $conditional['actions'][0]['target'] = 3;
  185. $node->webform['conditionals'] = array($conditional);
  186. $node->webform['components'][2]['required'] = '0';
  187. node_save($node);
  188. // Re-submit the form again, this time checking for the field on the
  189. // second page.
  190. $this->drupalPost('node/' . $node->nid, $edit, 'Next Page >', array(), array(), 'webform-client-form-' . $node->nid);
  191. $string_match = 'name="submitted[' . $textfield['form_key'] . ']"';
  192. // Ensure that the field is properly hidden based on a match.
  193. $message = t('Conditional separate-page skipping of validation passed for "%form_key": %input_values @conditional_string be @operator %match_string', array('%form_key' => $component['form_key'], '%input_values' => $input_string, '@conditional_string' => $conditional_string, '@operator' => $operator, '%match_string' => $match_string));
  194. if ($should_match) {
  195. $this->assertNoRaw($string_match, $message, t('Webform'));
  196. }
  197. // Or that the field is still present on a mismatch.
  198. else {
  199. $this->assertRaw($string_match, $message, t('Webform'));
  200. }
  201. }
  202. }