diff --git a/core/lib/Drupal/Core/Form/FormBase.php b/core/lib/Drupal/Core/Form/FormBase.php index 85470e7..f64b03f 100644 --- a/core/lib/Drupal/Core/Form/FormBase.php +++ b/core/lib/Drupal/Core/Form/FormBase.php @@ -45,13 +45,6 @@ protected $configFactory; /** - * The form error handler. - * - * @var \Drupal\Core\Form\FormErrorInterface - */ - protected $errorHandler; - - /** * {@inheritdoc} */ public static function create(ContainerInterface $container) { @@ -172,19 +165,6 @@ private function container() { } /** - * Returns the form error handler. - * - * @return \Drupal\Core\Form\FormErrorInterface - * The form error handler. - */ - protected function errorHandler() { - if (!$this->errorHandler) { - $this->errorHandler = \Drupal::service('form_builder'); - } - return $this->errorHandler; - } - - /** * Files an error against a form element. * * @param string $name @@ -194,12 +174,12 @@ protected function errorHandler() { * @param string $message * (optional) The error message to present to the user. * - * @see \Drupal\Core\Form\FormErrorInterface::setErrorByName() + * @deprecated Use \Drupal\Core\Form\FormStateInterface::setErrorByName(). * * @return $this */ protected function setFormError($name, FormStateInterface $form_state, $message = '') { - $this->errorHandler()->setErrorByName($name, $form_state, $message); + $form_state->setErrorByName($name, $message); return $this; } diff --git a/core/lib/Drupal/Core/Form/FormBuilder.php b/core/lib/Drupal/Core/Form/FormBuilder.php index 7382a18..a0f9e2f 100644 --- a/core/lib/Drupal/Core/Form/FormBuilder.php +++ b/core/lib/Drupal/Core/Form/FormBuilder.php @@ -171,9 +171,6 @@ public function getForm($form_arg) { * {@inheritdoc} */ public function buildForm($form_id, FormStateInterface &$form_state) { - // Ensure some defaults; if already set they will not be overridden. - $form_state->addFormStateDefaults(); - // Ensure the form ID is prepared. $form_id = $this->getFormId($form_id, $form_state); @@ -350,7 +347,7 @@ public function getCache($form_build_id, FormStateInterface &$form_state) { /** * {@inheritdoc} */ - public function setCache($form_build_id, $form, $form_state) { + public function setCache($form_build_id, $form, FormStateInterface $form_state) { // 6 hours cache life time for forms should be plenty. $expire = 21600; @@ -383,9 +380,6 @@ public function submitForm($form_arg, FormStateInterface &$form_state) { unset($args[0], $args[1]); $form_state['build_info']['args'] = array_values($args); } - // Merge in default values. - /** @var $form_state \Drupal\Core\Form\FormStateInterface */ - $form_state->addFormStateDefaults(); // Populate $form_state['input'] with the submitted values before retrieving // the form, to be consistent with what self::buildForm() does for @@ -663,7 +657,7 @@ public function validateForm($form_id, &$form, FormStateInterface &$form_state) /** * {@inheritdoc} */ - public function redirectForm($form_state) { + public function redirectForm(FormStateInterface $form_state) { return $this->formSubmitter->redirectForm($form_state); } diff --git a/core/lib/Drupal/Core/Form/FormBuilderInterface.php b/core/lib/Drupal/Core/Form/FormBuilderInterface.php index b437396..bb4d953 100644 --- a/core/lib/Drupal/Core/Form/FormBuilderInterface.php +++ b/core/lib/Drupal/Core/Form/FormBuilderInterface.php @@ -119,7 +119,7 @@ public function getCache($form_build_id, FormStateInterface &$form_state); /** * Stores a form in the cache. */ - public function setCache($form_build_id, $form, $form_state); + public function setCache($form_build_id, $form, FormStateInterface $form_state); /** * Retrieves, populates, and processes a form. diff --git a/core/lib/Drupal/Core/Form/FormState.php b/core/lib/Drupal/Core/Form/FormState.php index 8bba317..8f75d41 100644 --- a/core/lib/Drupal/Core/Form/FormState.php +++ b/core/lib/Drupal/Core/Form/FormState.php @@ -25,13 +25,8 @@ class FormState implements FormStateInterface, \ArrayAccess { * The internal storage of the form state. * * @var array - * An array which stores information about the form. This is passed as a - * reference so that the caller can use it to examine what in the form - * changed when the form submission process is complete. Furthermore, it may - * be used to store information related to the processed data in the form, - * which will persist across page requests when the 'cache' or 'rebuild' - * flag is set. The following parameters may be set in $form_state to affect - * how the form is rendered: + * An array which stores information about the form. The following + * parameters may be set in $form_state to affect how the form is rendered: * - build_info: Internal. An associative array of information stored by * Form API that is necessary to build and rebuild the form from cache * when the original context may no longer be available: @@ -177,57 +172,52 @@ class FormState implements FormStateInterface, \ArrayAccess { * data that needs to be accessed during the current form build process * only. There is no use-case for this functionality in Drupal core. */ - protected $formState = array(); + protected $internalStorage = array( + 'rebuild' => FALSE, + 'rebuild_info' => array(), + 'redirect' => NULL, + 'build_info' => array( + 'args' => array(), + 'files' => array(), + ), + 'temporary' => array(), + 'validation_complete' => FALSE, + 'submitted' => FALSE, + 'executed' => FALSE, + 'programmed' => FALSE, + 'programmed_bypass_access_check' => TRUE, + 'cache'=> FALSE, + 'method' => 'post', + 'groups' => array(), + 'buttons' => array(), + 'errors' => array(), + 'limit_validation_errors' => NULL, + 'storage' => array(), + ); /** - * The complete form array. + * The complete form structure. * * @see self::getCompleteForm() * * @var array */ - protected $form; + protected $complete_form; /** * @param array $form_state_additions */ public function __construct(array $form_state_additions = array()) { - $this->formState = $form_state_additions; - } - - /** - * {@inheritdoc} - */ - public function addFormStateDefaults() { - $this->formState += array( - 'rebuild' => FALSE, - 'rebuild_info' => array(), - 'redirect' => NULL, - 'build_info' => array( - 'args' => array(), - 'files' => array(), - ), - 'temporary' => array(), - 'validation_complete' => FALSE, - 'submitted' => FALSE, - 'executed' => FALSE, - 'programmed' => FALSE, - 'programmed_bypass_access_check' => TRUE, - 'cache'=> FALSE, - 'method' => 'post', - 'groups' => array(), - 'buttons' => array(), - 'errors' => array(), - 'limit_validation_errors' => NULL, - 'storage' => array(), - ); + $this->setFormState($form_state_additions); } /** * {@inheritdoc} */ public function setFormState(array $form_state_additions) { - $this->formState = $form_state_additions + $this->formState; + foreach ($form_state_additions as $key => $value) { + $this->set($key, $value); + } return $this; } @@ -236,7 +226,7 @@ public function setFormState(array $form_state_additions) { */ public function getCacheableArray($allowed_keys = array()) { $uncacheable_keys = array_diff($this->getUncacheableKeys(), $allowed_keys); - return array_diff_key($this->formState, array_flip($uncacheable_keys)); + return array_diff_key($this->internalStorage, array_flip($uncacheable_keys)); } /** @@ -274,8 +264,8 @@ protected function getUncacheableKeys() { /** * {@inheritdoc} */ - public function setCompleteForm(array &$form) { - $this->form = &$form; + public function setCompleteForm(array &$complete_form) { + $this->complete_form = &$complete_form; return $this; } @@ -283,30 +273,27 @@ public function setCompleteForm(array &$form) { * {@inheritdoc} */ public function &getCompleteForm() { - return $this->form; + return $this->complete_form; } /** * {@inheritdoc} */ public function offsetExists($offset) { - return isset($this->formState[$offset]); + return isset($this->internalStorage[$offset]); } /** * {@inheritdoc} */ public function &offsetGet($offset) { - if (!isset($this->formState[$offset])) { - $this->formState[$offset] = NULL; - } - // @todo Remove usages of $form_state['complete_form']. if ($offset == 'complete_form') { return $this->getCompleteForm(); } - return $this->formState[$offset]; + $value = &$this->get($offset); + return $value; } /** @@ -320,14 +307,14 @@ public function offsetSet($offset, $value) { * {@inheritdoc} */ public function offsetUnset($offset) { - unset($this->formState[$offset]); + unset($this->internalStorage[$offset]); } /** * {@inheritdoc} */ public function setIfNotExists($property, $value) { - if (!array_key_exists($property, $this->formState)) { + if (!array_key_exists($property, $this->internalStorage)) { $this->set($property, $value); } return $this; @@ -337,18 +324,17 @@ public function setIfNotExists($property, $value) { * {@inheritdoc} */ public function &get($property) { - $value = NULL; - if (isset($this->formState[$property])) { - $value = $this->formState[$property]; + if (!isset($this->internalStorage[$property])) { + $this->internalStorage[$property] = NULL; } - return $value; + return $this->internalStorage[$property]; } /** * {@inheritdoc} */ public function set($property, $value) { - $this->formState[$property] = $value; + $this->internalStorage[$property] = $value; return $this; } @@ -361,6 +347,42 @@ public function setRedirect(Url $url) { } /** + * {@inheritdoc} + */ + public function getRedirect() { + // Skip redirection for form submissions invoked via + // \Drupal\Core\Form\FormBuilderInterface::submitForm(). + if (!empty($this['programmed'])) { + return FALSE; + } + // Skip redirection if rebuild is activated. + if (!empty($this['rebuild'])) { + return FALSE; + } + // Skip redirection if it was explicitly disallowed. + if (!empty($this['no_redirect'])) { + return FALSE; + } + + // Check for a route-based redirection. + if (isset($this['redirect_route'])) { + // @todo Remove once all redirects are converted to Url. + if (!($this['redirect_route'] instanceof Url)) { + $this['redirect_route'] += array( + 'route_parameters' => array(), + 'options' => array(), + ); + $this['redirect_route'] = new Url($this['redirect_route']['route_name'], $this['redirect_route']['route_parameters'], $this['redirect_route']['options']); + } + + $this['redirect_route']->setAbsolute(); + return $this['redirect_route']; + } + + return $this['redirect']; + } + + /** * Sets the global status of errors. * * @param bool $errors diff --git a/core/lib/Drupal/Core/Form/FormStateInterface.php b/core/lib/Drupal/Core/Form/FormStateInterface.php index 1748fca..44fe619 100644 --- a/core/lib/Drupal/Core/Form/FormStateInterface.php +++ b/core/lib/Drupal/Core/Form/FormStateInterface.php @@ -11,15 +11,22 @@ /** * Provides an interface for an object containing the current state of a form. + * + * This is passed to all form related code so that the caller can use it to + * examine what in the form changed when the form submission process is + * complete. Furthermore, it may be used to store information related to the + * processed data in the form, which will persist across page requests when the + * 'cache' or 'rebuild' flag is set. See + * \Drupal\Core\Form\FormState::$internalStorage for documentation of the + * available flags. + * + * @see \Drupal\Core\Form\FormBuilderInterface + * @see \Drupal\Core\Form\FormValidatorInterface + * @see \Drupal\Core\Form\FormSubmitterInterface */ interface FormStateInterface { /** - * Adds the default values to the form state. - */ - public function addFormStateDefaults(); - - /** * Returns a reference to the complete form array. * * @return array @@ -30,12 +37,12 @@ public function &getCompleteForm(); /** * Stores the complete form array. * - * @param array $form + * @param array $complete_form * The complete form array. * * @return $this */ - public function setCompleteForm(array &$form); + public function setCompleteForm(array &$complete_form); /** * Returns an array representation of the cacheable portion of the form state. @@ -80,6 +87,25 @@ public function setIfNotExists($property, $value); public function setRedirect(Url $url); /** + * Gets the value to use for redirecting after the form has been executed. + * + * @see \Drupal\Core\Form\FormSubmitterInterface::redirectForm() + * + * @return mixed + * The value will be one of the following: + * - A fully prepared \Symfony\Component\HttpFoundation\RedirectResponse. + * - An instance of \Drupal\Core\Url to use for the redirect. + * - A numerically-indexed array where the first value is the path to use + * for the redirect, and the optional second value is an array of + * options for generating the URL from the path. + * - The path to use for the redirect. + * - NULL, to signify that no redirect was specified and that the current + * path should be used for the redirect. + * - FALSE, to signify that no redirect should take place. + */ + public function getRedirect(); + + /** * Gets any arbitrary property. * * @param string $property diff --git a/core/lib/Drupal/Core/Form/FormSubmitter.php b/core/lib/Drupal/Core/Form/FormSubmitter.php index b3797d2..97a9a20 100644 --- a/core/lib/Drupal/Core/Form/FormSubmitter.php +++ b/core/lib/Drupal/Core/Form/FormSubmitter.php @@ -126,76 +126,53 @@ public function executeSubmitHandlers(&$form, FormStateInterface &$form_state) { /** * {@inheritdoc} */ - public function redirectForm($form_state) { - // Skip redirection for form submissions invoked via - // \Drupal\Core\Form\FormBuilderInterface::submitForm(). - if (!empty($form_state['programmed'])) { - return; - } - // Skip redirection if rebuild is activated. - if (!empty($form_state['rebuild'])) { - return; - } - // Skip redirection if it was explicitly disallowed. - if (!empty($form_state['no_redirect'])) { - return; - } + public function redirectForm(FormStateInterface $form_state) { + // According to RFC 7231, 303 See Other status code must be used to redirect + // user agent (and not default 302 Found). + // @see http://tools.ietf.org/html/rfc7231#section-6.4.4 + $status_code = Response::HTTP_SEE_OTHER; + $redirect = $form_state->getRedirect(); // Allow using redirect responses directly if needed. - if (isset($form_state['redirect']) && $form_state['redirect'] instanceof RedirectResponse) { - return $form_state['redirect']; + if ($redirect instanceof RedirectResponse) { + return $redirect; } + $url = NULL; // Check for a route-based redirection. - if (isset($form_state['redirect_route'])) { - // @todo Remove once all redirects are converted to Url. - if (!($form_state['redirect_route'] instanceof Url)) { - $form_state['redirect_route'] += array( - 'route_parameters' => array(), - 'options' => array(), - ); - $form_state['redirect_route'] = new Url($form_state['redirect_route']['route_name'], $form_state['redirect_route']['route_parameters'], $form_state['redirect_route']['options']); - } - - $form_state['redirect_route']->setAbsolute(); - // According to RFC 7231, 303 See Other status code must be used - // to redirect user agent (and not default 302 Found). - // @see http://tools.ietf.org/html/rfc7231#section-6.4.4 - return new RedirectResponse($form_state['redirect_route']->toString(), Response::HTTP_SEE_OTHER); + if ($redirect instanceof Url) { + $url = $redirect->toString(); } - - // Only invoke a redirection if redirect value was not set to FALSE. - if (!isset($form_state['redirect']) || $form_state['redirect'] !== FALSE) { - if (isset($form_state['redirect'])) { - if (is_array($form_state['redirect'])) { - if (isset($form_state['redirect'][1])) { - $options = $form_state['redirect'][1]; - } - else { - $options = array(); - } - // Redirections should always use absolute URLs. - $options['absolute'] = TRUE; - if (isset($form_state['redirect'][2])) { - $status_code = $form_state['redirect'][2]; - } - else { - $status_code = Response::HTTP_SEE_OTHER; - } - return new RedirectResponse($this->urlGenerator->generateFromPath($form_state['redirect'][0], $options), $status_code); - } - else { - // This function can be called from the installer, which guarantees - // that $redirect will always be a string, so catch that case here - // and use the appropriate redirect function. - if ($this->drupalInstallationAttempted()) { - install_goto($form_state['redirect']); - } - else { - return new RedirectResponse($this->urlGenerator->generateFromPath($form_state['redirect'], array('absolute' => TRUE)), Response::HTTP_SEE_OTHER); - } - } + // An array contains the path to use for the redirect, as well as options to + // use for generating the URL. + elseif (is_array($redirect)) { + if (isset($redirect[1])) { + $options = $redirect[1]; } + else { + $options = array(); + } + // Redirections should always use absolute URLs. + $options['absolute'] = TRUE; + if (isset($redirect[2])) { + $status_code = $redirect[2]; + } + $url = $this->urlGenerator->generateFromPath($redirect[0], $options); + } + // A string represents the path to use for the redirect. + elseif (is_string($redirect)) { + // This function can be called from the installer, which guarantees + // that $redirect will always be a string, so catch that case here + // and use the appropriate redirect function. + if ($this->drupalInstallationAttempted()) { + install_goto($redirect); + } + else { + $url = $this->urlGenerator->generateFromPath($redirect, array('absolute' => TRUE)); + } + } + // If no redirect was specified, redirect to the current path. + elseif ($redirect === NULL) { $request = $this->requestStack->getCurrentRequest(); // @todo Remove dependency on the internal _system_path attribute: // https://www.drupal.org/node/2293521. @@ -203,7 +180,10 @@ public function redirectForm($form_state) { 'query' => $request->query->all(), 'absolute' => TRUE, )); - return new RedirectResponse($url, Response::HTTP_SEE_OTHER); + } + + if ($url) { + return new RedirectResponse($url, $status_code); } } diff --git a/core/lib/Drupal/Core/Form/FormSubmitterInterface.php b/core/lib/Drupal/Core/Form/FormSubmitterInterface.php index 6a1cd42..8a79fe0 100644 --- a/core/lib/Drupal/Core/Form/FormSubmitterInterface.php +++ b/core/lib/Drupal/Core/Form/FormSubmitterInterface.php @@ -58,11 +58,11 @@ public function executeSubmitHandlers(&$form, FormStateInterface &$form_state); * * Here is an example of how to set up a form to redirect to the path 'node': * @code - * $form_state['redirect'] = 'node'; + * $form_state->set('redirect', 'node'); * @endcode * And here is an example of how to redirect to 'node/123?foo=bar#baz': * @code - * $form_state['redirect'] = array( + * $form_state->set('redirect', array( * 'node/123', * array( * 'query' => array( @@ -70,7 +70,7 @@ public function executeSubmitHandlers(&$form, FormStateInterface &$form_state); * ), * 'fragment' => 'baz', * ), - * ); + * )); * @endcode * * There are several exceptions to the "usual" behavior described above: @@ -101,6 +101,6 @@ public function executeSubmitHandlers(&$form, FormStateInterface &$form_state); * @see \Drupal\Core\Form\FormBuilderInterface::processForm() * @see \Drupal\Core\Form\FormBuilderInterface::buildForm() */ - public function redirectForm($form_state); + public function redirectForm(FormStateInterface $form_state); } diff --git a/core/modules/field/src/Tests/FieldAttachOtherTest.php b/core/modules/field/src/Tests/FieldAttachOtherTest.php index cfc92c4..a74e4d2 100644 --- a/core/modules/field/src/Tests/FieldAttachOtherTest.php +++ b/core/modules/field/src/Tests/FieldAttachOtherTest.php @@ -267,7 +267,6 @@ function testEntityFormDisplayBuildForm() { $display = entity_get_form_display($entity_type, $this->instance->bundle, 'default'); $form = array(); $form_state = new FormState(); - $form_state->addFormStateDefaults(); $display->buildForm($entity, $form, $form_state); $this->assertEqual($form[$this->field_name]['widget']['#title'], $this->instance->getLabel(), "First field's form title is {$this->instance->getLabel()}"); @@ -290,7 +289,6 @@ function testEntityFormDisplayBuildForm() { } $form = array(); $form_state = new FormState(); - $form_state->addFormStateDefaults(); $display->buildForm($entity, $form, $form_state); $this->assertFalse(isset($form[$this->field_name]), 'The first field does not exist in the form'); @@ -314,7 +312,6 @@ function testEntityFormDisplayExtractFormValues() { $display = entity_get_form_display($entity_type, $this->instance->bundle, 'default'); $form = array(); $form_state = new FormState(); - $form_state->addFormStateDefaults(); $display->buildForm($entity_init, $form, $form_state); // Simulate incoming values. diff --git a/core/modules/field/src/Tests/FormTest.php b/core/modules/field/src/Tests/FormTest.php index e10e628..262a96d 100644 --- a/core/modules/field/src/Tests/FormTest.php +++ b/core/modules/field/src/Tests/FormTest.php @@ -533,7 +533,6 @@ function testFieldFormAccess() { $display = entity_get_form_display($entity_type, $entity_type, 'default'); $form = array(); $form_state = new FormState(); - $form_state->addFormStateDefaults(); $display->buildForm($entity, $form, $form_state); $this->assertFalse($form[$field_name_no_access]['#access'], 'Field #access is FALSE for the field without edit access.'); diff --git a/core/modules/system/src/Controller/FormAjaxController.php b/core/modules/system/src/Controller/FormAjaxController.php index 8c54517..be4c98d 100644 --- a/core/modules/system/src/Controller/FormAjaxController.php +++ b/core/modules/system/src/Controller/FormAjaxController.php @@ -72,7 +72,6 @@ public function content(Request $request) { */ protected function getForm(Request $request) { $form_state = new FormState(); - $form_state->addFormStateDefaults(); $form_build_id = $request->request->get('form_build_id'); // Get the form from the cache. diff --git a/core/modules/system/src/Tests/Form/ElementsTableSelectTest.php b/core/modules/system/src/Tests/Form/ElementsTableSelectTest.php index b81c56b..0ca830a 100644 --- a/core/modules/system/src/Tests/Form/ElementsTableSelectTest.php +++ b/core/modules/system/src/Tests/Form/ElementsTableSelectTest.php @@ -209,7 +209,6 @@ function testMultipleFalseOptionchecker() { private function formSubmitHelper($form, $edit) { $form_id = $this->randomName(); $form_state = new FormState(); - $form_state->addFormStateDefaults(); $form['op'] = array('#type' => 'submit', '#value' => t('Submit')); // The form token CSRF protection should not interfere with this test, so we diff --git a/core/modules/system/src/Tests/Form/FormCacheTest.php b/core/modules/system/src/Tests/Form/FormCacheTest.php index 398920d..f8056ba 100644 --- a/core/modules/system/src/Tests/Form/FormCacheTest.php +++ b/core/modules/system/src/Tests/Form/FormCacheTest.php @@ -34,7 +34,6 @@ public function setUp() { '#property' => $this->randomName(), ); $this->form_state = new FormState(); - $this->form_state->addFormStateDefaults(); $this->form_state['example'] = $this->randomName(); } @@ -46,7 +45,6 @@ function testCacheToken() { form_set_cache($this->form_build_id, $this->form, $this->form_state); $cached_form_state = new FormState(); - $cached_form_state->addFormStateDefaults(); $cached_form = form_get_cache($this->form_build_id, $cached_form_state); $this->assertEqual($this->form['#property'], $cached_form['#property']); $this->assertTrue(!empty($cached_form['#cache_token']), 'Form has a cache token'); @@ -57,7 +55,6 @@ function testCacheToken() { // will break the parent site test runner batch.) \Drupal::state()->set('system.private_key', 'invalid'); $cached_form_state = new FormState(); - $cached_form_state->addFormStateDefaults(); $cached_form = form_get_cache($this->form_build_id, $cached_form_state); $this->assertFalse($cached_form, 'No form returned from cache'); $this->assertTrue(empty($cached_form_state['example'])); @@ -65,7 +62,6 @@ function testCacheToken() { // Test that loading the cache with a different form_id fails. $wrong_form_build_id = $this->randomName(9); $cached_form_state = new FormState(); - $cached_form_state->addFormStateDefaults(); $this->assertFalse(form_get_cache($wrong_form_build_id, $cached_form_state), 'No form returned from cache'); $this->assertTrue(empty($cached_form_state['example']), 'Cached form state was not loaded'); } @@ -80,7 +76,6 @@ function testNoCacheToken() { form_set_cache($this->form_build_id, $this->form, $this->form_state); $cached_form_state = new FormState(); - $cached_form_state->addFormStateDefaults(); $cached_form = form_get_cache($this->form_build_id, $cached_form_state); $this->assertEqual($this->form['#property'], $cached_form['#property']); $this->assertTrue(empty($cached_form['#cache_token']), 'Form has no cache token'); diff --git a/core/modules/system/src/Tests/Form/FormTest.php b/core/modules/system/src/Tests/Form/FormTest.php index bfbda57..12d78ea 100644 --- a/core/modules/system/src/Tests/Form/FormTest.php +++ b/core/modules/system/src/Tests/Form/FormTest.php @@ -104,7 +104,6 @@ function testRequiredFields() { $form_id = $this->randomName(); $form = array(); $form_state = new FormState(); - $form_state->addFormStateDefaults(); $form['op'] = array('#type' => 'submit', '#value' => t('Submit')); $element = $data['element']['#title']; $form[$element] = $data['element']; diff --git a/core/tests/Drupal/Tests/Core/Form/FormBuilderTest.php b/core/tests/Drupal/Tests/Core/Form/FormBuilderTest.php index 4f70a31..fede0c1 100644 --- a/core/tests/Drupal/Tests/Core/Form/FormBuilderTest.php +++ b/core/tests/Drupal/Tests/Core/Form/FormBuilderTest.php @@ -9,6 +9,7 @@ use Drupal\Core\DependencyInjection\ContainerInjectionInterface; use Drupal\Core\Form\FormInterface; +use Drupal\Core\Form\FormState; use Drupal\Core\Form\FormStateInterface; use Symfony\Component\DependencyInjection\ContainerInterface; @@ -27,7 +28,8 @@ class FormBuilderTest extends FormTestBase { public function testGetFormIdWithString() { $form_arg = 'foo'; - $clean_form_state = $form_state = $this->prepareFormState(); + $clean_form_state = new FormState(); + $form_state = new FormState(); $form_id = $this->formBuilder->getFormId($form_arg, $form_state); $this->assertSame($form_arg, $form_id); @@ -40,7 +42,7 @@ public function testGetFormIdWithString() { public function testGetFormIdWithClassName() { $form_arg = 'Drupal\Tests\Core\Form\TestForm'; - $form_state = $this->prepareFormState(); + $form_state = new FormState(); $form_id = $this->formBuilder->getFormId($form_arg, $form_state); $this->assertSame('test_form', $form_id); @@ -56,7 +58,7 @@ public function testGetFormIdWithInjectedClassName() { $form_arg = 'Drupal\Tests\Core\Form\TestFormInjected'; - $form_state = $this->prepareFormState(); + $form_state = new FormState(); $form_id = $this->formBuilder->getFormId($form_arg, $form_state); $this->assertSame('test_form', $form_id); @@ -71,7 +73,7 @@ public function testGetFormIdWithObject() { $form_arg = $this->getMockForm($expected_form_id); - $form_state = $this->prepareFormState(); + $form_state = new FormState(); $form_id = $this->formBuilder->getFormId($form_arg, $form_state); $this->assertSame($expected_form_id, $form_id); @@ -93,7 +95,7 @@ public function testGetFormIdWithBaseForm() { ->method('getBaseFormId') ->will($this->returnValue($base_form_id)); - $form_state = $this->prepareFormState(); + $form_state = new FormState(); $form_id = $this->formBuilder->getFormId($form_arg, $form_state); $this->assertSame($expected_form_id, $form_id); @@ -124,7 +126,7 @@ public function testHandleFormStateResponse($class, $form_state_key) { $form_state[$form_state_key] = $response; })); - $form_state = $this->prepareFormState(); + $form_state = new FormState(); try { $form_state['values'] = array(); $form_state['input']['form_id'] = $form_id; @@ -178,7 +180,7 @@ public function testHandleRedirectWithResponse() { $form_state['redirect'] = $redirect; })); - $form_state = $this->prepareFormState(); + $form_state = new FormState(); try { $form_state['values'] = array(); $form_state['input']['form_id'] = $form_id; @@ -227,7 +229,7 @@ public function testGetFormWithClassString() { $form_id = '\Drupal\Tests\Core\Form\TestForm'; $object = new TestForm(); $form = array(); - $form_state = $this->prepareFormState(); + $form_state = new FormState(); $expected_form = $object->buildForm($form, $form_state); $form = $this->formBuilder->getForm($form_id); @@ -257,7 +259,7 @@ public function testBuildFormWithClassString() { $form_id = '\Drupal\Tests\Core\Form\TestForm'; $object = new TestForm(); $form = array(); - $form_state = $this->prepareFormState(); + $form_state = new FormState(); $expected_form = $object->buildForm($form, $form_state); $form = $this->formBuilder->buildForm($form_id, $form_state); @@ -274,7 +276,7 @@ public function testBuildFormWithObject() { $form_arg = $this->getMockForm($form_id, $expected_form); - $form_state = $this->prepareFormState(); + $form_state = new FormState(); $form = $this->formBuilder->buildForm($form_arg, $form_state); $this->assertFormElement($expected_form, $form, 'test'); $this->assertSame($form_id, $form_state['build_info']['form_id']); @@ -298,7 +300,7 @@ public function testRebuildForm() { ->will($this->returnValue($expected_form)); // Do an initial build of the form and track the build ID. - $form_state = $this->prepareFormState(); + $form_state = new FormState(); $form = $this->formBuilder->buildForm($form_arg, $form_state); $original_build_id = $form['#build_id']; @@ -349,7 +351,7 @@ public function testGetCache() { ->will($this->returnValue(TRUE)); // Do an initial build of the form and track the build ID. - $form_state = $this->prepareFormState(); + $form_state = new FormState(); $form_state['build_info']['args'] = array(); $form_state['build_info']['files'] = array(array('module' => 'node', 'type' => 'pages.inc')); $form_state['cache'] = TRUE; @@ -394,7 +396,7 @@ public function testSendResponse() { $form_arg = $this->getMockForm($form_id, $expected_form); // Do an initial build of the form and track the build ID. - $form_state = $this->prepareFormState(); + $form_state = new FormState(); $this->formBuilder->buildForm($form_arg, $form_state); } @@ -415,11 +417,15 @@ public function testUniqueHtmlId() { ->method('buildForm') ->will($this->returnValue($expected_form)); - $form_state = $this->prepareFormState(); + $form_state = $this->getMockBuilder('Drupal\Core\Form\FormState') + ->setMethods(array('drupalSetMessage')) + ->getMock(); $form = $this->simulateFormSubmission($form_id, $form_arg, $form_state); $this->assertSame($form_id, $form['#id']); - $form_state = $this->prepareFormState(); + $form_state = $this->getMockBuilder('Drupal\Core\Form\FormState') + ->setMethods(array('drupalSetMessage')) + ->getMock(); $form = $this->simulateFormSubmission($form_id, $form_arg, $form_state); $this->assertSame("$form_id--2", $form['#id']); } diff --git a/core/tests/Drupal/Tests/Core/Form/FormStateTest.php b/core/tests/Drupal/Tests/Core/Form/FormStateTest.php new file mode 100644 index 0000000..3c60ddf --- /dev/null +++ b/core/tests/Drupal/Tests/Core/Form/FormStateTest.php @@ -0,0 +1,162 @@ +getRedirect(); + $this->assertEquals($expected, $redirect); + } + + /** + * Provides test data for testing the getRedirect() method. + * + * @return array + * Returns some test data. + */ + public function providerTestGetRedirect() { + $data = array(); + $data[] = array(array(), NULL); + + $data[] = array(array('redirect' => 'foo'), 'foo'); + $data[] = array(array('redirect' => array('foo')), array('foo')); + $data[] = array(array('redirect' => array('bar', array('query' => array('foo' => 'baz')))), array('bar', array('query' => array('foo' => 'baz')))); + $data[] = array(array('redirect' => array('baz', array(), 301)), array('baz', array(), 301)); + + $redirect = new RedirectResponse('/example'); + $data[] = array(array('redirect' => $redirect), $redirect); + + $data[] = array(array('redirect_route' => array('route_name' => 'test_route_a')), new Url('test_route_a', array(), array('absolute' => TRUE))); + $data[] = array(array('redirect_route' => array('route_name' => 'test_route_b', 'route_parameters' => array('key' => 'value'))), new Url('test_route_b', array('key' => 'value'), array('absolute' => TRUE))); + $data[] = array(array('redirect_route' => new Url('test_route_b', array('key' => 'value'))), new Url('test_route_b', array('key' => 'value'), array('absolute' => TRUE))); + + $data[] = array(array('programmed' => TRUE), NULL); + $data[] = array(array('rebuild' => TRUE), NULL); + $data[] = array(array('no_redirect' => TRUE), NULL); + $data[] = array(array('redirect' => FALSE), NULL); + + return $data; + } + + /** + * Tests the setError() method. + * + * @covers ::setError + */ + public function testSetError() { + $form_state = $this->getMockBuilder('Drupal\Core\Form\FormState') + ->setMethods(array('drupalSetMessage')) + ->getMock(); + $form_state->expects($this->once()) + ->method('drupalSetMessage') + ->willReturn('Fail'); + + $element['#parents'] = array('foo', 'bar'); + $form_state->setError($element, 'Fail'); + } + + /** + * Tests the getError() method. + * + * @covers ::getError + * + * @dataProvider providerTestGetError + */ + public function testGetError($errors, $parents, $error = NULL) { + $element['#parents'] = $parents; + $form_state = new FormState(array( + 'errors' => $errors, + )); + $this->assertSame($error, $form_state->getError($element)); + } + + public function providerTestGetError() { + return array( + array(array(), array('foo')), + array(array('foo][bar' => 'Fail'), array()), + array(array('foo][bar' => 'Fail'), array('foo')), + array(array('foo][bar' => 'Fail'), array('bar')), + array(array('foo][bar' => 'Fail'), array('baz')), + array(array('foo][bar' => 'Fail'), array('foo', 'bar'), 'Fail'), + array(array('foo][bar' => 'Fail'), array('foo', 'bar', 'baz'), 'Fail'), + array(array('foo][bar' => 'Fail 2'), array('foo')), + array(array('foo' => 'Fail 1', 'foo][bar' => 'Fail 2'), array('foo'), 'Fail 1'), + array(array('foo' => 'Fail 1', 'foo][bar' => 'Fail 2'), array('foo', 'bar'), 'Fail 1'), + ); + } + + /** + * @covers ::setErrorByName + * + * @dataProvider providerTestSetErrorByName + */ + public function testSetErrorByName($limit_validation_errors, $expected_errors, $set_message = FALSE) { + $form_state = $this->getMockBuilder('Drupal\Core\Form\FormState') + ->setConstructorArgs(array(array('limit_validation_errors' => $limit_validation_errors))) + ->setMethods(array('drupalSetMessage')) + ->getMock(); + $form_state->clearErrors(); + $form_state->expects($set_message ? $this->once() : $this->never()) + ->method('drupalSetMessage'); + + $form_state->setErrorByName('test', 'Fail 1'); + $form_state->setErrorByName('test', 'Fail 2'); + $form_state->setErrorByName('options'); + + $this->assertSame(!empty($expected_errors), $form_state::hasAnyErrors()); + $this->assertSame($expected_errors, $form_state['errors']); + } + + public function providerTestSetErrorByName() { + return array( + // Only validate the 'options' element. + array(array(array('options')), array('options' => '')), + // Do not limit an validation, and, ensuring the first error is returned + // for the 'test' element. + array(NULL, array('test' => 'Fail 1', 'options' => ''), TRUE), + // Limit all validation. + array(array(), array()), + ); + } + + /** + * Tests that form errors during submission throw an exception. + * + * @covers ::setErrorByName + * + * @expectedException \LogicException + * @expectedExceptionMessage Form errors cannot be set after form validation has finished. + */ + public function testFormErrorsDuringSubmission() { + $form_state = $this->getMockBuilder('Drupal\Core\Form\FormState') + ->setConstructorArgs(array(array('validation_complete' => TRUE))) + ->setMethods(array('drupalSetMessage')) + ->getMock(); + $form_state->setErrorByName('test', 'message'); + } + +} diff --git a/core/tests/Drupal/Tests/Core/Form/FormSubmitterTest.php b/core/tests/Drupal/Tests/Core/Form/FormSubmitterTest.php index a02f362..0bdc009 100644 --- a/core/tests/Drupal/Tests/Core/Form/FormSubmitterTest.php +++ b/core/tests/Drupal/Tests/Core/Form/FormSubmitterTest.php @@ -42,7 +42,7 @@ public function setUp() { public function testHandleFormSubmissionNotSubmitted() { $form_submitter = $this->getFormSubmitter(); $form = array(); - $form_state = $this->prepareFormState(); + $form_state = new FormState(); $return = $form_submitter->doSubmitForm($form, $form_state); $this->assertFalse($form_state['executed']); @@ -55,9 +55,10 @@ public function testHandleFormSubmissionNotSubmitted() { public function testHandleFormSubmissionNoRedirect() { $form_submitter = $this->getFormSubmitter(); $form = array(); - $form_state = $this->prepareFormState(); - $form_state['submitted'] = TRUE; - $form_state['no_redirect'] = TRUE; + $form_state = new FormState(array( + 'submitted' => TRUE, + 'no_redirect' => TRUE, + )); $return = $form_submitter->doSubmitForm($form, $form_state); $this->assertTrue($form_state['executed']); @@ -77,9 +78,10 @@ public function testHandleFormSubmissionWithResponses($class, $form_state_key) { ->method('prepare') ->will($this->returnValue($response)); - $form_state = $this->prepareFormState(); - $form_state['submitted'] = TRUE; - $form_state[$form_state_key] = $response; + $form_state = new FormState(array( + 'submitted' => TRUE, + $form_state_key => $response, + )); $form_submitter = $this->getFormSubmitter(); $form = array(); @@ -102,7 +104,7 @@ public function providerTestHandleFormSubmissionWithResponses() { * * @dataProvider providerTestRedirectWithResult */ - public function testRedirectWithResult($form_state, $result, $status = 303) { + public function testRedirectWithResult($redirect_value, $result, $status = 303) { $form_submitter = $this->getFormSubmitter(); $this->urlGenerator->expects($this->once()) ->method('generateFromPath') @@ -114,20 +116,39 @@ public function testRedirectWithResult($form_state, $result, $status = 303) { )) ); - $form_state = $this->prepareFormState($form_state); + $form_state = $this->getMock('Drupal\Core\Form\FormStateInterface'); + $form_state->expects($this->once()) + ->method('getRedirect') + ->willReturn($redirect_value); $redirect = $form_submitter->redirectForm($form_state); $this->assertSame($result, $redirect->getTargetUrl()); $this->assertSame($status, $redirect->getStatusCode()); } /** + * Provides test data for testing the redirectForm() method with a redirect. + * + * @return array + * Returns some test data. + */ + public function providerTestRedirectWithResult() { + return array( + array(NULL, ''), + array('foo', 'foo'), + array(array('foo'), 'foo'), + array(array('bar', array('query' => array('foo' => 'baz'))), 'bar'), + array(array('baz', array(), 301), 'baz', 301), + ); + } + + /** * Tests the redirectForm() with redirect_route when a redirect is expected. * * @covers ::redirectForm * * @dataProvider providerTestRedirectWithRouteWithResult */ - public function testRedirectWithRouteWithResult($form_state, $result, $status = 303) { + public function testRedirectWithRouteWithResult($redirect_value, $result, $status = 303) { $container = new ContainerBuilder(); $container->set('url_generator', $this->urlGenerator); \Drupal::setContainer($container); @@ -140,64 +161,16 @@ public function testRedirectWithRouteWithResult($form_state, $result, $status = )) ); - $form_state = $this->prepareFormState($form_state); + $form_state = $this->getMock('Drupal\Core\Form\FormStateInterface'); + $form_state->expects($this->once()) + ->method('getRedirect') + ->willReturn($redirect_value); $redirect = $form_submitter->redirectForm($form_state); $this->assertSame($result, $redirect->getTargetUrl()); $this->assertSame($status, $redirect->getStatusCode()); } /** - * Tests the redirectForm() method with a response object. - * - * @covers ::redirectForm - */ - public function testRedirectWithResponseObject() { - $form_submitter = $this->getFormSubmitter(); - $redirect = new RedirectResponse('/example'); - $form_state['redirect'] = $redirect; - - $form_state = $this->prepareFormState($form_state); - $result_redirect = $form_submitter->redirectForm($form_state); - - $this->assertSame($redirect, $result_redirect); - } - - /** - * Tests the redirectForm() method when no redirect is expected. - * - * @covers ::redirectForm - * - * @dataProvider providerTestRedirectWithoutResult - */ - public function testRedirectWithoutResult($form_state) { - $form_submitter = $this->getFormSubmitter(); - $this->urlGenerator->expects($this->never()) - ->method('generateFromPath'); - $this->urlGenerator->expects($this->never()) - ->method('generateFromRoute'); - $form_state = $this->prepareFormState($form_state); - $redirect = $form_submitter->redirectForm($form_state); - $this->assertNull($redirect); - } - - /** - * Provides test data for testing the redirectForm() method with a redirect. - * - * @return array - * Returns some test data. - */ - public function providerTestRedirectWithResult() { - return array( - array(array(), ''), - array(array('redirect' => 'foo'), 'foo'), - array(array('redirect' => array('foo')), 'foo'), - array(array('redirect' => array('foo')), 'foo'), - array(array('redirect' => array('bar', array('query' => array('foo' => 'baz')))), 'bar'), - array(array('redirect' => array('baz', array(), 301)), 'baz', 301), - ); - } - - /** * Provides test data for testing the redirectForm() method with a route name. * * @return array @@ -205,25 +178,46 @@ public function providerTestRedirectWithResult() { */ public function providerTestRedirectWithRouteWithResult() { return array( - array(array('redirect_route' => array('route_name' => 'test_route_a')), 'test-route'), - array(array('redirect_route' => array('route_name' => 'test_route_b', 'route_parameters' => array('key' => 'value'))), 'test-route/value'), - array(array('redirect_route' => new Url('test_route_b', array('key' => 'value'))), 'test-route/value'), + array(new Url('test_route_a', array(), array('absolute' => TRUE)), 'test-route'), + array(new Url('test_route_b', array('key' => 'value'), array('absolute' => TRUE)), 'test-route/value'), ); } /** - * Provides test data for testing the redirectForm() method with no redirect. + * Tests the redirectForm() method with a response object. * - * @return array - * Returns some test data. + * @covers ::redirectForm */ - public function providerTestRedirectWithoutResult() { - return array( - array(array('programmed' => TRUE)), - array(array('rebuild' => TRUE)), - array(array('no_redirect' => TRUE)), - array(array('redirect' => FALSE)), - ); + public function testRedirectWithResponseObject() { + $form_submitter = $this->getFormSubmitter(); + $redirect = new RedirectResponse('/example'); + $form_state = $this->getMock('Drupal\Core\Form\FormStateInterface'); + $form_state->expects($this->once()) + ->method('getRedirect') + ->willReturn($redirect); + + $result_redirect = $form_submitter->redirectForm($form_state); + + $this->assertSame($redirect, $result_redirect); + } + + /** + * Tests the redirectForm() method when no redirect is expected. + * + * @covers ::redirectForm + */ + public function testRedirectWithoutResult() { + $form_submitter = $this->getFormSubmitter(); + $this->urlGenerator->expects($this->never()) + ->method('generateFromPath'); + $this->urlGenerator->expects($this->never()) + ->method('generateFromRoute'); + $form_state = $this->getMock('Drupal\Core\Form\FormStateInterface'); + $form_state->expects($this->once()) + ->method('getRedirect') + ->willReturn(FALSE); + $redirect = $form_submitter->redirectForm($form_state); + $this->assertNull($redirect); } /** @@ -240,7 +234,7 @@ public function testExecuteSubmitHandlers() { ->with($this->isType('array'), $this->isInstanceOf('Drupal\Core\Form\FormStateInterface')); $form = array(); - $form_state = $this->prepareFormState(); + $form_state = new FormState(); $form_submitter->executeSubmitHandlers($form, $form_state); $form['#submit'][] = array($mock, 'hash_submit'); @@ -252,25 +246,6 @@ public function testExecuteSubmitHandlers() { } /** - * Prepares a FormState object with defaults added. - * - * @param array $form_state_additions - * (optional) An array of additions for the form state. - * - * @return \Drupal\Core\Form\FormStateInterface|\PHPUnit_Framework_MockObject_MockObject - * The form state object. - */ - protected function prepareFormState(array $form_state_additions = array()) { - $form_state = $this->getMockBuilder('Drupal\Core\Form\FormState') - ->setConstructorArgs(array($form_state_additions)) - ->setMethods(array('drupalSetMessage')) - ->getMock(); - $form_state->clearErrors(); - $form_state->addFormStateDefaults(); - return $form_state; - } - - /** * @return \Drupal\Core\Form\FormSubmitterInterface */ protected function getFormSubmitter() { diff --git a/core/tests/Drupal/Tests/Core/Form/FormTestBase.php b/core/tests/Drupal/Tests/Core/Form/FormTestBase.php index d0c9181..08eaa31 100644 --- a/core/tests/Drupal/Tests/Core/Form/FormTestBase.php +++ b/core/tests/Drupal/Tests/Core/Form/FormTestBase.php @@ -258,25 +258,6 @@ protected function assertFormElement(array $expected_form, array $actual_form, $ $this->assertSame(array_intersect_key($expected_element, $actual_element), $expected_element); } - /** - * Prepares a FormState object with defaults added. - * - * @param array $form_state_additions - * (optional) An array of additions for the form state. - * - * @return \Drupal\Core\Form\FormStateInterface|\PHPUnit_Framework_MockObject_MockObject - * The form state object. - */ - protected function prepareFormState(array $form_state_additions = array()) { - $form_state = $this->getMockBuilder('Drupal\Core\Form\FormState') - ->setConstructorArgs(array($form_state_additions)) - ->setMethods(array('drupalSetMessage')) - ->getMock(); - $form_state->clearErrors(); - $form_state->addFormStateDefaults(); - return $form_state; - } - } /** diff --git a/core/tests/Drupal/Tests/Core/Form/FormValidatorTest.php b/core/tests/Drupal/Tests/Core/Form/FormValidatorTest.php index 207c47b..a0e9f47 100644 --- a/core/tests/Drupal/Tests/Core/Form/FormValidatorTest.php +++ b/core/tests/Drupal/Tests/Core/Form/FormValidatorTest.php @@ -8,8 +8,8 @@ namespace Drupal\Tests\Core\Form { use Drupal\Component\Utility\String; - use Drupal\Core\Form\FormState; - use Drupal\Tests\UnitTestCase; +use Drupal\Core\Form\FormState; +use Drupal\Tests\UnitTestCase; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\RequestStack; @@ -20,24 +20,6 @@ class FormValidatorTest extends UnitTestCase { /** - * Tests that form errors during submission throw an exception. - * - * @covers ::setErrorByName - * - * @expectedException \LogicException - * @expectedExceptionMessage Form errors cannot be set after form validation has finished. - */ - public function testFormErrorsDuringSubmission() { - $form_validator = $this->getMockBuilder('Drupal\Core\Form\FormValidator') - ->disableOriginalConstructor() - ->setMethods(NULL) - ->getMock(); - $form_state['validation_complete'] = TRUE; - $form_state = $this->prepareFormState($form_state); - $form_validator->setErrorByName('test', $form_state, 'message'); - } - - /** * Tests the 'validation_complete' $form_state flag. * * @covers ::validateForm @@ -50,7 +32,7 @@ public function testValidationComplete() { ->getMock(); $form = array(); - $form_state = $this->prepareFormState(); + $form_state = new FormState(); $this->assertFalse($form_state['validation_complete']); $form_validator->validateForm('test_form_id', $form, $form_state); $this->assertTrue($form_state['validation_complete']); @@ -70,7 +52,7 @@ public function testPreventDuplicateValidation() { ->method('doValidateForm'); $form = array(); - $form_state = $this->prepareFormState(); + $form_state = new FormState(); $form_state['validation_complete'] = TRUE; $form_validator->validateForm('test_form_id', $form, $form_state); $this->assertArrayNotHasKey('#errors', $form); @@ -90,7 +72,7 @@ public function testMustValidate() { ->method('doValidateForm'); $form = array(); - $form_state = $this->prepareFormState(); + $form_state = new FormState(); $form_state['validation_complete'] = TRUE; $form_state['must_validate'] = TRUE; $form_validator->validateForm('test_form_id', $form, $form_state); @@ -122,7 +104,7 @@ public function testValidateInvalidFormToken() { ->method('doValidateForm'); $form['#token'] = 'test_form_id'; - $form_state = $this->prepareFormState(); + $form_state = new FormState(); $form_state['values']['form_token'] = 'some_random_token'; $form_validator->validateForm('test_form_id', $form, $form_state); $this->assertTrue($form_state['validation_complete']); @@ -150,103 +132,13 @@ public function testValidateValidFormToken() { ->method('doValidateForm'); $form['#token'] = 'test_form_id'; - $form_state = $this->prepareFormState(); + $form_state = new FormState(); $form_state['values']['form_token'] = 'some_random_token'; $form_validator->validateForm('test_form_id', $form, $form_state); $this->assertTrue($form_state['validation_complete']); } /** - * Tests the setError() method. - * - * @covers ::setError - */ - public function testSetError() { - $form_state = $this->prepareFormState(); - - $element['#parents'] = array('foo', 'bar'); - - $form_validator = $this->getMockBuilder('Drupal\Core\Form\FormValidator') - ->disableOriginalConstructor() - ->setMethods(array('setError')) - ->getMock(); - $form_validator->expects($this->once()) - ->method('setError') - ->with($element, $form_state, 'Fail'); - - $form_validator->setError($element, $form_state, 'Fail'); - } - - /** - * Tests the getError() method. - * - * @covers ::getError - * - * @dataProvider providerTestGetError - */ - public function testGetError($errors, $parents, $error = NULL) { - $form_validator = $this->getMockBuilder('Drupal\Core\Form\FormValidator') - ->disableOriginalConstructor() - ->setMethods(NULL) - ->getMock(); - - $element['#parents'] = $parents; - $form_state = $this->prepareFormState(); - $form_state['errors'] = $errors; - $this->assertSame($error, $form_validator->getError($element, $form_state)); - } - - public function providerTestGetError() { - return array( - array(array(), array('foo')), - array(array('foo][bar' => 'Fail'), array()), - array(array('foo][bar' => 'Fail'), array('foo')), - array(array('foo][bar' => 'Fail'), array('bar')), - array(array('foo][bar' => 'Fail'), array('baz')), - array(array('foo][bar' => 'Fail'), array('foo', 'bar'), 'Fail'), - array(array('foo][bar' => 'Fail'), array('foo', 'bar', 'baz'), 'Fail'), - array(array('foo][bar' => 'Fail 2'), array('foo')), - array(array('foo' => 'Fail 1', 'foo][bar' => 'Fail 2'), array('foo'), 'Fail 1'), - array(array('foo' => 'Fail 1', 'foo][bar' => 'Fail 2'), array('foo', 'bar'), 'Fail 1'), - ); - } - - /** - * @covers ::setErrorByName - * - * @dataProvider providerTestSetErrorByName - */ - public function testSetErrorByName($limit_validation_errors, $expected_errors, $set_message = FALSE) { - $form_validator = $this->getMockBuilder('Drupal\Core\Form\FormValidator') - ->disableOriginalConstructor() - ->setMethods(NULL) - ->getMock(); - - $form_state = $this->prepareFormState(array('limit_validation_errors' => $limit_validation_errors)); - $form_state->expects($set_message ? $this->once() : $this->never()) - ->method('drupalSetMessage'); - - $form_validator->setErrorByName('test', $form_state, 'Fail 1'); - $form_validator->setErrorByName('test', $form_state, 'Fail 2'); - $form_validator->setErrorByName('options', $form_state); - - $this->assertSame(!empty($expected_errors), $form_state::hasAnyErrors()); - $this->assertSame($expected_errors, $form_state['errors']); - } - - public function providerTestSetErrorByName() { - return array( - // Only validate the 'options' element. - array(array(array('options')), array('options' => '')), - // Do not limit an validation, and, ensuring the first error is returned - // for the 'test' element. - array(NULL, array('test' => 'Fail 1', 'options' => ''), TRUE), - // Limit all validation. - array(array(), array()), - ); - } - - /** * @covers ::setElementErrorsFromFormState */ public function testSetElementErrorsFromFormState() { @@ -263,7 +155,9 @@ public function testSetElementErrorsFromFormState() { '#title' => 'Test', '#parents' => array('test'), ); - $form_state = $this->prepareFormState(); + $form_state = $this->getMockBuilder('Drupal\Core\Form\FormState') + ->setMethods(array('drupalSetMessage')) + ->getMock(); $form_validator->setErrorByName('test', $form_state, 'invalid'); $form_validator->validateForm('test_form_id', $form, $form_state); $this->assertSame('invalid', $form['test']['#errors']); @@ -281,7 +175,7 @@ public function testHandleErrorsWithLimitedValidation($sections, $triggering_ele ->getMock(); $form = array(); - $form_state = $this->prepareFormState(); + $form_state = new FormState(); $form_state['triggering_element'] = $triggering_element; $form_state['triggering_element']['#limit_validation_errors'] = $sections; @@ -384,7 +278,7 @@ public function testExecuteValidateHandlers() { ->with($this->isType('array'), $this->isInstanceOf('Drupal\Core\Form\FormStateInterface')); $form = array(); - $form_state = $this->prepareFormState(); + $form_state = new FormState(); $form_validator->executeValidateHandlers($form, $form_state); $form['#validate'][] = array($mock, 'hash_validate'); @@ -422,7 +316,7 @@ public function testRequiredErrorMessage($element, $expected_message) { '#required' => TRUE, '#parents' => array('test'), ); - $form_state = $this->prepareFormState(); + $form_state = new FormState(); $form_validator->validateForm('test_form_id', $form, $form_state); } @@ -468,7 +362,7 @@ public function testElementValidate() { '#parents' => array('test'), '#element_validate' => array(array($mock, 'element_validate')), ); - $form_state = $this->prepareFormState(); + $form_state = new FormState(); $form_validator->validateForm('test_form_id', $form, $form_state); } @@ -502,7 +396,7 @@ public function testPerformRequiredValidation($element, $expected_message, $call '#required' => FALSE, '#parents' => array('test'), ); - $form_state = $this->prepareFormState(); + $form_state = new FormState(); $form_state['values'] = array(); $form_validator->validateForm('test_form_id', $form, $form_state); } @@ -575,25 +469,6 @@ public function providerTestPerformRequiredValidation() { ); } - /** - * Prepares a FormState object with defaults added. - * - * @param array $form_state_additions - * (optional) An array of additions for the form state. - * - * @return \Drupal\Core\Form\FormStateInterface|\PHPUnit_Framework_MockObject_MockObject - * The form state object. - */ - protected function prepareFormState(array $form_state_additions = array()) { - $form_state = $this->getMockBuilder('Drupal\Core\Form\FormState') - ->setConstructorArgs(array($form_state_additions)) - ->setMethods(array('drupalSetMessage')) - ->getMock(); - $form_state->clearErrors(); - $form_state->addFormStateDefaults(); - return $form_state; - } - } }