/** * Build all necessary things for child form (form state, etc.). * * @param \Drupal\Core\Entity\EntityFormInterface $controller * Entity form controller for child form. * @param \Drupal\Core\Form\FormStateInterface $form_state * Parent form state object. * @param \Drupal\Core\Entity\EntityInterface $entity * Entity object. * @param string $operation * Operation that is to be performed in inline form. * @param array $parents * Entity form #parents. * * @return \Drupal\Core\Form\FormStateInterface * Child form state object. */ public static function buildChildFormState(EntityFormInterface $controller, FormStateInterface $form_state, EntityInterface $entity, $operation, $parents) { $child_form_state = new FormState(); $child_form_state->addBuildInfo('callback_object', $controller); $child_form_state->addBuildInfo('base_form_id', $controller->getBaseFormID()); $child_form_state->addBuildInfo('form_id', $controller->getFormID()); $child_form_state->addBuildInfo('args', array()); // Copy values to child form. $child_form_state->setCompleteForm($form_state->getCompleteForm()); $child_form_state->setUserInput($form_state->getUserInput()); // Filter out all submitted values that are not directly relevant for this // IEF. Otherwise they might mess things up. $form_state_values = $form_state->getValues(); $form_state_values = static::extractArraySequence($form_state_values, $parents); $child_form_state->setValues($form_state_values); $child_form_state->setStorage($form_state->getStorage()); $value = \Drupal::entityTypeManager()->getStorage('entity_form_display')->load($entity->getEntityTypeId() . '.' . $entity->bundle() . '.' . $operation); $child_form_state->set('form_display', $value); // Since some of the submit handlers are run, redirects need to be disabled. $child_form_state->disableRedirect(); // When a form is rebuilt after Ajax processing, its #build_id and #action // should not change. // @see drupal_rebuild_form() $rebuild_info = $child_form_state->getRebuildInfo(); $rebuild_info['copy']['#build_id'] = TRUE; $rebuild_info['copy']['#action'] = TRUE; $child_form_state->setRebuildInfo($rebuild_info); $child_form_state->set('inline_entity_form', $form_state->get('inline_entity_form')); $child_form_state->set('langcode', $entity->language()->getId()); $child_form_state->set('field', $form_state->get('field')); $child_form_state->setTriggeringElement($form_state->getTriggeringElement()); $child_form_state->setSubmitHandlers($form_state->getSubmitHandlers()); return $child_form_state; }
/** * @covers ::buildResponse */ public function testBuildResponseWithUpdateCommand() { $triggering_element = ['#ajax' => ['callback' => function (array $form, FormStateInterface $form_state) { return new AjaxResponse([]); }]]; $request = new Request(); $form = ['#build_id' => 'the_build_id', '#build_id_old' => 'a_new_build_id', 'test' => ['#type' => 'textfield']]; $form_state = new FormState(); $form_state->setTriggeringElement($triggering_element); $commands = [new AlertCommand('alert!')]; $commands_expected = []; $commands_expected[] = ['command' => 'update_build_id', 'old' => 'a_new_build_id', 'new' => 'the_build_id']; $commands_expected[] = ['command' => 'alert', 'text' => 'alert!']; $this->renderer->expects($this->never())->method('renderResponse'); $result = $this->formAjaxResponseBuilder->buildResponse($request, $form, $form_state, $commands); $this->assertInstanceOf('\\Drupal\\Core\\Ajax\\AjaxResponse', $result); $this->assertSame($commands_expected, $result->getCommands()); }
/** * Build all necessary things for child form (form state, etc.). * * @param \Drupal\Core\Entity\EntityFormInterface $controller * Entity form controller for child form. * @param \Drupal\Core\Form\FormStateInterface $form_state * Parent form state object. * @param \Drupal\Core\Entity\EntityInterface $entity * Entity object. * @param string $operation * Operation that is to be performed in inline form. * * @return \Drupal\Core\Form\FormStateInterface * Child form state object. */ public static function buildChildFormState(EntityFormInterface $controller, FormStateInterface $form_state, EntityInterface $entity, $operation) { $child_form_state = new FormState(); $child_form_state->addBuildInfo('callback_object', $controller); $child_form_state->addBuildInfo('base_form_id', $controller->getBaseFormID()); $child_form_state->addBuildInfo('form_id', $controller->getFormID()); $child_form_state->addBuildInfo('args', array()); // Copy values to child form. $child_form_state->setUserInput($form_state->getUserInput()); $child_form_state->setValues($form_state->getValues()); $child_form_state->setStorage($form_state->getStorage()); $child_form_state->set('form_display', entity_get_form_display($entity->getEntityTypeId(), $entity->bundle(), $operation)); // Since some of the submit handlers are run, redirects need to be disabled. $child_form_state->disableRedirect(); // When a form is rebuilt after Ajax processing, its #build_id and #action // should not change. // @see drupal_rebuild_form() $rebuild_info = $child_form_state->getRebuildInfo(); $rebuild_info['copy']['#build_id'] = TRUE; $rebuild_info['copy']['#action'] = TRUE; $child_form_state->setRebuildInfo($rebuild_info); $child_form_state->set('inline_entity_form', $form_state->get('inline_entity_form')); $child_form_state->set('langcode', $entity->language()->getId()); $child_form_state->set('field', $form_state->get('field')); $child_form_state->setTriggeringElement($form_state->getTriggeringElement()); $child_form_state->setSubmitHandlers($form_state->getSubmitHandlers()); return $child_form_state; }
/** * @covers ::ajaxDeleteSubmit */ public function testAjaxDeleteSubmit() { $line_item_name = $this->randomMachineName(); $root_element_name = $this->randomMachineName(); $form_build = array('foo' => array('#id' => $this->randomMachineName(), '#name' => $root_element_name, 'line_items' => array($line_item_name => array('delete' => array('#array_parents' => array('foo', 'line_items', $line_item_name, 'delete'), '#parents' => []))))); $form_state = new FormState(); $form_state->setTriggeringElement($form_build['foo']['line_items'][$line_item_name]['delete']); $element = $this->sut; $response = $element::ajaxDeleteSubmit($form_build, $form_state); $this->assertInstanceOf(AjaxResponse::class, $response); }
/** * @covers ::ajaxPay * * @dataProvider providerTestAjaxPay */ public function testAjaxPay($is_completed, $number_of_commands) { $payment = $this->getMock(PaymentInterface::class); $result = $this->getMock(OperationResultInterface::class); $result->expects($this->atLeastOnce())->method('isCompleted')->willReturn($is_completed); $payment_method = $this->getMock(PaymentMethodInterface::class); $payment_method->expects($this->any())->method('getPayment')->willReturn($payment); $payment_method->expects($this->atLeastOnce())->method('getPaymentExecutionResult')->willReturn($result); $plugin_selector_plugin_id = $this->randomMachineName(); $plugin_selector = $this->getMock(PluginSelectorInterface::class); $plugin_selector->expects($this->atLeastOnce())->method('getSelectedPlugin')->willReturn($payment_method); $form = array('foo' => array('bar' => array('#limit_allowed_plugin_ids' => [], '#name' => $this->randomMachineName(), '#plugin_selector_id' => $plugin_selector_plugin_id, '#prototype_payment' => $payment, '#required' => TRUE, 'container' => array('#id' => $this->randomMachineName(), 'payment_form' => array('pay' => array('#array_parents' => array('foo', 'bar', 'container', 'payment_form', 'pay'))))))); $form_state = new FormState(); $form_state->set('payment_reference.element.payment_reference.plugin_selector.' . $form['foo']['bar']['#name'], $plugin_selector); $form_state->setTriggeringElement($form['foo']['bar']['container']['payment_form']['pay']); $response = $this->sut->ajaxPay($form, $form_state); $this->assertInstanceOf(AjaxResponse::class, $response); $this->assertCount($number_of_commands, $response->getCommands()); }
/** * Tests validateForm when the submit button is pressed. * * GIVEN the embridge search form * WHEN the validateForm function is run * THEN an error should be thrown when the asset chosen doesn't exist. * * @covers ::validateForm * * @test */ public function validateWithSubmitButtonPressedThrowsErrorForAssetThatDoesntExists() { // Mocking for FormState::setError. $form = ['search_results' => ['#parents' => []]]; $form_state = new FormState(); $triggering_element = ['#parents' => ['submit']]; $entity_id = 34298734897; $input = ['result_chosen' => $entity_id]; $form_state->setTriggeringElement($triggering_element); $form_state->setUserInput($input); $mock_asset_storage = $this->getMock(EntityStorageInterface::class); $mock_asset_storage->expects($this->once())->method('load')->with($entity_id)->willReturn(NULL); $this->entityTypeManager->expects($this->once())->method('getStorage')->with('embridge_asset_entity')->willReturn($mock_asset_storage); $this->form->validateForm($form, $form_state); $errors = $form_state->getErrors(); $this->assertNotEmpty($errors); }