ILIAS  trunk Revision v11.0_alpha-3011-gc6b235a2e85
FormTest.php
Go to the documentation of this file.
1<?php
2
19declare(strict_types=1);
20
21require_once(__DIR__ . "/../../../../Base.php");
22
30use ILIAS\Data;
31use Psr\Http\Message\ServerRequestInterface;
34use ILIAS\Refinery\Factory as Refinery;
35use PHPUnit\Framework\MockObject\MockObject;
36
38{
39 public string $name = "name";
40
41 public function getNewName(): string
42 {
43 return $this->name;
44 }
45}
46
47class ConcreteForm extends Form
48{
49 public ?InputData $input_data = null;
52 protected array $inputs;
53
55 {
56 $this->input_factory = $input_factory;
58 }
59
60 public function _extractRequestData(ServerRequestInterface $request): InputData
61 {
62 return $this->extractRequestData($request);
63 }
64
65 public function extractRequestData(ServerRequestInterface $request): InputData
66 {
67 if ($this->input_data !== null) {
68 return $this->input_data;
69 }
70
71 return parent::extractRequestData($request);
72 }
73
74
75 public function setInputs(array $inputs): void
76 {
77 $this->input_group = $this->input_factory->group($inputs);
78 $this->inputs = $inputs;
79 }
80}
81
86{
90 protected $language;
91 protected array $inputs;
92
93 protected function buildFactory(): Input\Container\Form\Factory
94 {
96 $this->buildInputFactory(),
97 new SignalGenerator()
98 );
99 }
100
101 protected function buildInputFactory(): Input\Field\Factory
102 {
103 $df = new Data\Factory();
104 $this->language = $this->createMock(ILIAS\Language\Language::class);
105 return new Input\Field\Factory(
106 $this->createMock(\ILIAS\UI\Implementation\Component\Input\Field\Node\Factory::class),
107 $this->createMock(\ILIAS\UI\Implementation\Component\Input\UploadLimitResolver::class),
108 new SignalGenerator(),
109 $df,
110 new Refinery($df, $this->language),
111 $this->language
112 );
113 }
114
115 protected function buildButtonFactory(): I\Button\Factory
116 {
117 return new I\Button\Factory();
118 }
119
120 protected function buildTransformation(Closure $trafo): Transformation
121 {
122 $dataFactory = new Data\Factory();
123 $language = $this->createMock(ILIAS\Language\Language::class);
124 $refinery = new Refinery($dataFactory, $language);
125
126 return $refinery->custom()->transformation($trafo);
127 }
128
129 public function getUIFactory(): NoUIFactory
130 {
131 return new WithButtonNoUIFactory($this->buildButtonFactory());
132 }
133
134 public function buildDataFactory(): Data\Factory
135 {
136 return new Data\Factory();
137 }
138
139 public function testGetInputs(): void
140 {
141 $this->buildFactory();
142 $if = $this->buildInputFactory();
143 $name_source = new FixedNameSource();
144
145 $inputs = [$if->text(""), $if->text("")];
146 $form = new ConcreteForm($this->buildInputFactory(), new DefNamesource(), $inputs);
147
148 $seen_names = [];
149 $form_inputs = $form->getInputs();
150 $this->assertSameSize($inputs, $form_inputs);
151
152 foreach ($form_inputs as $input) {
153 $name = $input->getName();
154 $name_source->name = $name;
155
156 // name is a string
157 $this->assertIsString($name);
158
159 // only name is attached
160 $input = array_shift($form_inputs);
161 $this->assertEquals($input->withNameFrom($name_source), $input);
162
163 // every name can only be contained once.
164 $this->assertNotContains($name, $seen_names);
165 $seen_names[] = $name;
166 }
167 }
168
169 public function testExtractPostData(): void
170 {
171 $form = new ConcreteForm($this->buildInputFactory(), new DefNamesource(), []);
172 $request = $this->createMock(ServerRequestInterface::class);
173 $request
174 ->expects($this->once())
175 ->method("getParsedBody")
176 ->willReturn([]);
177 $input_data = $form->_extractRequestData($request);
178 $this->assertInstanceOf(InputData::class, $input_data);
179 }
180
181 public function testWithRequest(): void
182 {
183 $df = $this->buildDataFactory();
184 $request = $this->createMock(ServerRequestInterface::class);
185 $input_data = $this->createMock(InputData::class);
186
187 $input_1 = $this->inputMock();
188 $input_1
189 ->expects($this->once())
190 ->method("withInput")
191 ->with($input_data)
192 ->willReturn($input_1);
193 $input_1
194 ->expects($this->once())
195 ->method("getContent")
196 ->willReturn($df->ok(0));
197
198 $input_2 = $this->inputMock();
199 $input_2
200 ->expects($this->once())
201 ->method("withInput")
202 ->with($input_data)
203 ->willReturn($input_2);
204 $input_2
205 ->expects($this->once())
206 ->method("getContent")
207 ->willReturn($df->ok(0));
208
209 $form = new ConcreteForm($this->buildInputFactory(), new DefNamesource(), []);
210 $form->setInputs([$input_1, $input_2]);
211 $form->input_data = $input_data;
212
213 $form2 = $form->withRequest($request);
214
215 $this->assertNotSame($form2, $form);
216 $this->assertInstanceOf(Form::class, $form2);
217 $this->assertEquals([$input_1, $input_2], $form2->getInputs());
218 }
219
220 public function testWithRequestRespectsKeys(): void
221 {
222 $df = $this->buildDataFactory();
223 $request = $this->createMock(ServerRequestInterface::class);
224 $input_data = $this->createMock(InputData::class);
225
226 $input_1 = $this->inputMock();
227 $input_1
228 ->expects($this->once())
229 ->method("withInput")
230 ->with($input_data)
231 ->willReturn($input_1);
232 $input_1
233 ->expects($this->once())
234 ->method("getContent")
235 ->willReturn($df->ok(0));
236
237 $input_2 = $this->inputMock();
238 $input_2
239 ->expects($this->once())
240 ->method("withInput")
241 ->with($input_data)
242 ->willReturn($input_2);
243 $input_2
244 ->expects($this->once())
245 ->method("getContent")
246 ->willReturn($df->ok(0));
247
248 $form = new ConcreteForm($this->buildInputFactory(), new DefNamesource(), []);
249 $form->setInputs(["foo" => $input_1, "bar" => $input_2]);
250 $form->input_data = $input_data;
251
252 $form2 = $form->withRequest($request);
253
254 $this->assertNotSame($form2, $form);
255 $this->assertInstanceOf(Form::class, $form2);
256 $this->assertEquals(["foo" => $input_1, "bar" => $input_2], $form2->getInputs());
257 }
258
259 public function testGetData(): void
260 {
261 $df = $this->buildDataFactory();
262 $request = $this->createMock(ServerRequestInterface::class);
263 $request
264 ->expects($this->once())
265 ->method("getParsedBody")
266 ->willReturn([]);
267
268 $input_1 = $this->inputMock();
269 $input_1
270 ->expects($this->once())
271 ->method("getContent")
272 ->willReturn($df->ok(1));
273 $input_1
274 ->expects($this->once())
275 ->method("withInput")
276 ->willReturn($input_1);
277
278 $input_2 = $this->inputMock();
279 $input_2
280 ->expects($this->once())
281 ->method("getContent")
282 ->willReturn($df->ok(2));
283 $input_2
284 ->expects($this->once())
285 ->method("withInput")
286 ->willReturn($input_2);
287
288 $form = new ConcreteForm($this->buildInputFactory(), new DefNamesource(), []);
289 $form->setInputs([$input_1, $input_2]);
290 $form = $form->withRequest($request);
291 $this->assertEquals([1, 2], $form->getData());
292 }
293
294 public function testGetDataRespectsKeys(): void
295 {
296 $df = $this->buildDataFactory();
297 $request = $this->createMock(ServerRequestInterface::class);
298 $request
299 ->expects($this->once())
300 ->method("getParsedBody")
301 ->willReturn([]);
302
303 $input_1 = $this->inputMock();
304 $input_1
305 ->expects($this->once())
306 ->method("getContent")
307 ->willReturn($df->ok(1));
308 $input_1
309 ->expects($this->once())
310 ->method("withInput")
311 ->willReturn($input_1);
312
313 $input_2 = $this->inputMock();
314 $input_2
315 ->expects($this->once())
316 ->method("getContent")
317 ->willReturn($df->ok(2));
318 $input_2
319 ->expects($this->once())
320 ->method("withInput")
321 ->willReturn($input_2);
322
323 $form = new ConcreteForm($this->buildInputFactory(), new DefNamesource(), []);
324 $form->setInputs(["foo" => $input_1, "bar" => $input_2]);
325 $form = $form->withRequest($request);
326 $this->assertEquals(["foo" => 1, "bar" => 2], $form->getData());
327 }
328
329 public function testGetDataFaulty(): void
330 {
331 $df = $this->buildDataFactory();
332 $request = $this->createMock(ServerRequestInterface::class);
333 $request
334 ->expects($this->once())
335 ->method("getParsedBody")
336 ->willReturn([]);
337
338 $input_1 = $this->inputMock();
339 $input_1
340 ->expects($this->once())
341 ->method("getContent")
342 ->willReturn($df->error("error"));
343 $input_1
344 ->expects($this->once())
345 ->method("withInput")
346 ->willReturn($input_1);
347
348 $input_2 = $this->inputMock();
349 $input_2
350 ->expects($this->once())
351 ->method("getContent")
352 ->willReturn($df->ok(2));
353 $input_2
354 ->expects($this->once())
355 ->method("withInput")
356 ->willReturn($input_2);
357
358 $form = new ConcreteForm($this->buildInputFactory(), new DefNamesource(), []);
359 $form->setInputs(["foo" => $input_1, "bar" => $input_2]);
360
361 $i18n = "THERE IS SOME ERROR IN THIS GROUP";
362 $this->language
363 ->expects($this->once())
364 ->method("txt")
365 ->with("ui_error_in_group")
366 ->willReturn($i18n);
367
368 //Todo: This is not good, this should throw an error or similar.
369 $form = $form->withRequest($request);
370 $this->assertEquals(null, null);
371 }
372
373 public function testWithAdditionalTransformation(): void
374 {
375 $df = $this->buildDataFactory();
376 $request = $this->createMock(ServerRequestInterface::class);
377 $request
378 ->expects($this->once())
379 ->method("getParsedBody")
380 ->willReturn([]);
381
382 $input_1 = $this->inputMock();
383 $input_1
384 ->expects($this->once())
385 ->method("getContent")
386 ->willReturn($df->ok(1));
387 $input_1
388 ->expects($this->once())
389 ->method("withInput")
390 ->willReturn($input_1);
391
392 $input_2 = $this->inputMock();
393 $input_2
394 ->expects($this->once())
395 ->method("getContent")
396 ->willReturn($df->ok(2));
397 $input_2
398 ->expects($this->once())
399 ->method("withInput")
400 ->willReturn($input_2);
401
402 $form = new ConcreteForm($this->buildInputFactory(), new DefNamesource(), []);
403 $form->setInputs([$input_1, $input_2]);
404
405 $form2 = $form->withAdditionalTransformation($this->buildTransformation(function () {
406 return "transformed";
407 }));
408
409 $this->assertNotSame($form2, $form);
410 $form2 = $form2->withRequest($request);
411
412 $this->assertEquals("transformed", $form2->getData());
413 }
414
415 public function testNameInputsRespectsKeys(): void
416 {
417 $if = $this->buildInputFactory();
418 $inputs = [
419 2 => $if->text(""),
420 "foo" => $if->text(""),
421 1 => $if->text(""),
422 $if->text(""),
423 ];
424 $form = new ConcreteForm($this->buildInputFactory(), new DefNamesource(), []);
425 $form->setInputs($inputs);
426 $named_inputs = $form->getInputs();
427 $this->assertEquals(array_keys($inputs), array_keys($named_inputs));
428 }
429
433 protected function inputMock()
434 {
435 static $no = 1000;
436 return $this
437 ->getMockBuilder(Input\Field\FormInputInternal::class)
438 ->onlyMethods([
439 "getName",
440 "withDedicatedName",
441 "withNameFrom",
442 "withInput",
443 "getContent",
444 "getLabel",
445 "withLabel",
446 "getByline",
447 "withByline",
448 "isRequired",
449 "withRequired",
450 "isDisabled",
451 "withDisabled",
452 "getValue",
453 "withValue",
454 "getError",
455 "withError",
456 "withAdditionalTransformation",
457 "getUpdateOnLoadCode",
458 "getCanonicalName",
459 "withOnLoadCode",
460 "withAdditionalOnLoadCode",
461 "getOnLoadCode",
462 "withOnUpdate",
463 "appendOnUpdate",
464 "withResetTriggeredSignals",
465 "getTriggeredSignals",
466 "reduceWith"
467 ])
468 ->setMockClassName("Mock_InputNo" . ($no++))
469 ->getMock();
470 }
471
472 public function testFormWithoutRequiredField(): void
473 {
474 $f = $this->buildFactory();
475 $if = $this->buildInputFactory();
476 $inputs = [$if->text(""), $if->text("")];
477 $form = new ConcreteForm($this->buildInputFactory(), new DefNamesource(), $inputs);
478
479 $this->assertFalse($form->hasRequiredInputs());
480 }
481
482 public function testFormWithRequiredField(): void
483 {
484 $f = $this->buildFactory();
485 $if = $this->buildInputFactory();
486 $inputs = [
487 $if->text("")->withRequired(true),
488 $if->text("")
489 ];
490 $form = new ConcreteForm($this->buildInputFactory(), new DefNamesource(), $inputs);
491 $this->assertTrue($form->hasRequiredInputs());
492 }
493}
extractRequestData(ServerRequestInterface $request)
@inheritDoc
Definition: FormTest.php:65
Input Field Factory $input_factory
Definition: FormTest.php:50
array $inputs
Definition: FormTest.php:52
setInputs(array $inputs)
Definition: FormTest.php:75
__construct(Input\Field\Factory $input_factory, NameSource $name_source, array $inputs)
Definition: FormTest.php:54
InputData $input_data
Definition: FormTest.php:49
_extractRequestData(ServerRequestInterface $request)
Definition: FormTest.php:60
Group $input_group
Definition: FormTest.php:51
getNewName()
Generates a unique name on every call.
Definition: FormTest.php:41
string $name
Definition: FormTest.php:39
Test on form implementation.
Definition: FormTest.php:86
buildButtonFactory()
Definition: FormTest.php:115
testWithRequest()
Definition: FormTest.php:181
buildDataFactory()
Definition: FormTest.php:134
testFormWithRequiredField()
Definition: FormTest.php:482
buildFactory()
Definition: FormTest.php:93
buildTransformation(Closure $trafo)
Definition: FormTest.php:120
buildInputFactory()
Definition: FormTest.php:101
testGetDataFaulty()
Definition: FormTest.php:329
testNameInputsRespectsKeys()
Definition: FormTest.php:415
testGetDataRespectsKeys()
Definition: FormTest.php:294
testGetInputs()
Definition: FormTest.php:139
inputMock()
Definition: FormTest.php:433
array $inputs
Definition: FormTest.php:91
testFormWithoutRequiredField()
Definition: FormTest.php:472
testWithAdditionalTransformation()
Definition: FormTest.php:373
testExtractPostData()
Definition: FormTest.php:169
testGetData()
Definition: FormTest.php:259
getUIFactory()
Definition: FormTest.php:129
testWithRequestRespectsKeys()
Definition: FormTest.php:220
Builds a Color from either hex- or rgb values.
Definition: Factory.php:31
Factory for Date Formats.
Definition: Factory.php:27
Builds data types.
Definition: Factory.php:36
Transform values according to custom configuration.
This implements commonalities between all forms.
Definition: Form.php:34
Definition: UI.php:24
Provides common functionality for UI tests.
Definition: Base.php:337
This describes inputs that can be used in forms.
Definition: FormInput.php:33
Groups are a special kind of input because they are a monoid operation.
Definition: Group.php:38
Describes how Input-Elements want to interact with posted data.
Definition: InputData.php:30
This describes commonalities between all inputs.
Definition: Input.php:47
Describes a source for input names.
Definition: NameSource.php:27
__construct(Container $dic, ilPlugin $plugin)
@inheritDoc
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
Definition: Bulky.php:21
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
Interface Observer \BackgroundTasks Contains several chained tasks and infos about them.