More updates to stop using dev or alpha or beta versions.
[yaffs-website] / web / core / tests / Drupal / Tests / Core / Form / FormSubmitterTest.php
1 <?php
2
3 namespace Drupal\Tests\Core\Form;
4
5 use Drupal\Core\DependencyInjection\ContainerBuilder;
6 use Drupal\Core\Form\FormState;
7 use Drupal\Core\Routing\UrlGeneratorInterface;
8 use Drupal\Core\Url;
9 use Drupal\Core\Utility\UnroutedUrlAssemblerInterface;
10 use Drupal\Tests\UnitTestCase;
11 use Symfony\Component\HttpFoundation\RedirectResponse;
12 use Symfony\Component\HttpFoundation\Request;
13 use Symfony\Component\HttpFoundation\RequestStack;
14
15 /**
16  * @coversDefaultClass \Drupal\Core\Form\FormSubmitter
17  * @group Form
18  */
19 class FormSubmitterTest extends UnitTestCase {
20
21   /**
22    * The mocked URL generator.
23    *
24    * @var \PHPUnit_Framework_MockObject_MockObject|\Drupal\Core\Routing\UrlGeneratorInterface
25    */
26   protected $urlGenerator;
27
28   /**
29    * The mocked unrouted URL assembler.
30    *
31    * @var \PHPUnit_Framework_MockObject_MockObject|\Drupal\Core\Utility\UnroutedUrlAssemblerInterface
32    */
33   protected $unroutedUrlAssembler;
34
35   /**
36    * {@inheritdoc}
37    */
38   protected function setUp() {
39     parent::setUp();
40     $this->urlGenerator = $this->getMock(UrlGeneratorInterface::class);
41     $this->unroutedUrlAssembler = $this->getMock(UnroutedUrlAssemblerInterface::class);
42   }
43
44   /**
45    * @covers ::doSubmitForm
46    */
47   public function testHandleFormSubmissionNotSubmitted() {
48     $form_submitter = $this->getFormSubmitter();
49     $form = [];
50     $form_state = new FormState();
51
52     $return = $form_submitter->doSubmitForm($form, $form_state);
53     $this->assertFalse($form_state->isExecuted());
54     $this->assertNull($return);
55   }
56
57   /**
58    * @covers ::doSubmitForm
59    */
60   public function testHandleFormSubmissionNoRedirect() {
61     $form_submitter = $this->getFormSubmitter();
62     $form = [];
63     $form_state = (new FormState())
64       ->setSubmitted()
65       ->disableRedirect();
66
67     $return = $form_submitter->doSubmitForm($form, $form_state);
68     $this->assertTrue($form_state->isExecuted());
69     $this->assertNull($return);
70   }
71
72   /**
73    * @covers ::doSubmitForm
74    *
75    * @dataProvider providerTestHandleFormSubmissionWithResponses
76    */
77   public function testHandleFormSubmissionWithResponses($class, $form_state_key) {
78     $response = $this->getMockBuilder($class)
79       ->disableOriginalConstructor()
80       ->getMock();
81     $response->expects($this->any())
82       ->method('prepare')
83       ->will($this->returnValue($response));
84
85     $form_state = (new FormState())
86       ->setSubmitted()
87       ->setFormState([$form_state_key => $response]);
88
89     $form_submitter = $this->getFormSubmitter();
90     $form = [];
91     $return = $form_submitter->doSubmitForm($form, $form_state);
92
93     $this->assertInstanceOf('Symfony\Component\HttpFoundation\Response', $return);
94   }
95
96   public function providerTestHandleFormSubmissionWithResponses() {
97     return [
98       ['Symfony\Component\HttpFoundation\Response', 'response'],
99       ['Symfony\Component\HttpFoundation\RedirectResponse', 'redirect'],
100     ];
101   }
102
103   /**
104    * Tests the redirectForm() method when the redirect is NULL.
105    *
106    * @covers ::redirectForm
107    */
108   public function testRedirectWithNull() {
109     $form_submitter = $this->getFormSubmitter();
110
111     $form_state = $this->getMock('Drupal\Core\Form\FormStateInterface');
112     $form_state->expects($this->once())
113       ->method('getRedirect')
114       ->willReturn(NULL);
115
116     $this->urlGenerator->expects($this->once())
117       ->method('generateFromRoute')
118       ->with('<current>', [], ['query' => [], 'absolute' => TRUE])
119       ->willReturn('http://localhost/test-path');
120
121     $redirect = $form_submitter->redirectForm($form_state);
122     // If we have no redirect, we redirect to the current URL.
123     $this->assertSame('http://localhost/test-path', $redirect->getTargetUrl());
124     $this->assertSame(303, $redirect->getStatusCode());
125   }
126
127   /**
128    * Tests redirectForm() when a redirect is a Url object.
129    *
130    * @covers ::redirectForm
131    *
132    * @dataProvider providerTestRedirectWithUrl
133    */
134   public function testRedirectWithUrl(Url $redirect_value, $result, $status = 303) {
135     $container = new ContainerBuilder();
136     $container->set('url_generator', $this->urlGenerator);
137     \Drupal::setContainer($container);
138     $form_submitter = $this->getFormSubmitter();
139     $this->urlGenerator->expects($this->once())
140       ->method('generateFromRoute')
141       ->will($this->returnValueMap([
142           ['test_route_a', [], ['absolute' => TRUE], FALSE, 'test-route'],
143           ['test_route_b', ['key' => 'value'], ['absolute' => TRUE], FALSE, 'test-route/value'],
144         ])
145       );
146
147     $form_state = $this->getMock('Drupal\Core\Form\FormStateInterface');
148     $form_state->expects($this->once())
149       ->method('getRedirect')
150       ->willReturn($redirect_value);
151     $redirect = $form_submitter->redirectForm($form_state);
152     $this->assertSame($result, $redirect->getTargetUrl());
153     $this->assertSame($status, $redirect->getStatusCode());
154   }
155
156   /**
157    * Provides test data for testing the redirectForm() method with a route name.
158    *
159    * @return array
160    *   Returns some test data.
161    */
162   public function providerTestRedirectWithUrl() {
163     return [
164       [new Url('test_route_a', [], ['absolute' => TRUE]), 'test-route'],
165       [new Url('test_route_b', ['key' => 'value'], ['absolute' => TRUE]), 'test-route/value'],
166     ];
167   }
168
169   /**
170    * Tests the redirectForm() method with a response object.
171    *
172    * @covers ::redirectForm
173    */
174   public function testRedirectWithResponseObject() {
175     $form_submitter = $this->getFormSubmitter();
176     $redirect = new RedirectResponse('/example');
177     $form_state = $this->getMock('Drupal\Core\Form\FormStateInterface');
178     $form_state->expects($this->once())
179       ->method('getRedirect')
180       ->willReturn($redirect);
181
182     $result_redirect = $form_submitter->redirectForm($form_state);
183
184     $this->assertSame($redirect, $result_redirect);
185   }
186
187   /**
188    * Tests the redirectForm() method when no redirect is expected.
189    *
190    * @covers ::redirectForm
191    */
192   public function testRedirectWithoutResult() {
193     $form_submitter = $this->getFormSubmitter();
194     $this->urlGenerator->expects($this->never())
195       ->method('generateFromRoute');
196     $this->unroutedUrlAssembler->expects($this->never())
197       ->method('assemble');
198     $container = new ContainerBuilder();
199     $container->set('url_generator', $this->urlGenerator);
200     $container->set('unrouted_url_assembler', $this->unroutedUrlAssembler);
201     \Drupal::setContainer($container);
202     $form_state = $this->getMock('Drupal\Core\Form\FormStateInterface');
203     $form_state->expects($this->once())
204       ->method('getRedirect')
205       ->willReturn(FALSE);
206     $redirect = $form_submitter->redirectForm($form_state);
207     $this->assertNull($redirect);
208   }
209
210   /**
211    * @covers ::executeSubmitHandlers
212    */
213   public function testExecuteSubmitHandlers() {
214     $form_submitter = $this->getFormSubmitter();
215     $mock = $this->getMockForAbstractClass('Drupal\Core\Form\FormBase', [], '', TRUE, TRUE, TRUE, ['submit_handler', 'hash_submit', 'simple_string_submit']);
216     $mock->expects($this->once())
217       ->method('submit_handler')
218       ->with($this->isType('array'), $this->isInstanceOf('Drupal\Core\Form\FormStateInterface'));
219     $mock->expects($this->once())
220       ->method('hash_submit')
221       ->with($this->isType('array'), $this->isInstanceOf('Drupal\Core\Form\FormStateInterface'));
222     $mock->expects($this->once())
223       ->method('simple_string_submit')
224       ->with($this->isType('array'), $this->isInstanceOf('Drupal\Core\Form\FormStateInterface'));
225
226     $form = [];
227     $form_state = new FormState();
228     $form_submitter->executeSubmitHandlers($form, $form_state);
229
230     $form['#submit'][] = [$mock, 'hash_submit'];
231     $form_submitter->executeSubmitHandlers($form, $form_state);
232
233     // $form_state submit handlers will supersede $form handlers.
234     $form_state->setSubmitHandlers([[$mock, 'submit_handler']]);
235     $form_submitter->executeSubmitHandlers($form, $form_state);
236
237     // Methods directly on the form object can be specified as a string.
238     $form_state = (new FormState())
239       ->setFormObject($mock)
240       ->setSubmitHandlers(['::simple_string_submit']);
241     $form_submitter->executeSubmitHandlers($form, $form_state);
242   }
243
244   /**
245    * @return \Drupal\Core\Form\FormSubmitterInterface
246    */
247   protected function getFormSubmitter() {
248     $request_stack = new RequestStack();
249     $request_stack->push(Request::create('/test-path'));
250     return $this->getMockBuilder('Drupal\Core\Form\FormSubmitter')
251       ->setConstructorArgs([$request_stack, $this->urlGenerator])
252       ->setMethods(['batchGet', 'drupalInstallationAttempted'])
253       ->getMock();
254   }
255
256 }