ILIAS  release_8 Revision v8.24
SwitchableGroupInputTest.php
Go to the documentation of this file.
1<?php
2
3declare(strict_types=1);
4
21require_once(__DIR__ . "/../../../../../libs/composer/vendor/autoload.php");
22require_once(__DIR__ . "/../../../Base.php");
23
29use ILIAS\Data;
31use ILIAS\Refinery\Factory as Refinery;
32use PHPUnit\Framework\MockObject\MockObject;
34
35class Group1 extends Group
36{
37}
38
39class Group2 extends Group
40{
41}
42
44{
48 protected $child1;
49
53 protected $child2;
54
58 protected $nested_child;
59
63 protected $lng;
64
66 protected Refinery $refinery;
69
70 public function setUp(): void
71 {
72 $this->nested_child = $this->createMock(I\Input\Field\FormInputInternal::class);
73 $this->child1 = $this->createMock(Group1::class);
74 $this->child2 = $this->createMock(Group2::class);
75 $this->data_factory = new Data\Factory();
76 $this->refinery = new Refinery($this->data_factory, $this->createMock(ilLanguage::class));
77 $this->lng = $this->createMock(ilLanguage::class);
78
79 $this->nested_child
80 ->method("withNameFrom")
81 ->willReturn($this->nested_child);
82
83 $this->child1
84 ->method("withNameFrom")
85 ->willReturn($this->child1);
86 $this->child1
87 ->method("getInputs")
88 ->willReturn([$this->nested_child]);
89
90 $this->child2
91 ->method("withNameFrom")
92 ->willReturn($this->child2);
93 $this->child2
94 ->method("getInputs")
95 ->willReturn([$this->nested_child]);
96
97 $this->switchable_group = (new SwitchableGroup(
98 $this->data_factory,
99 $this->refinery,
100 $this->lng,
101 ["child1" => $this->child1, "child2" => $this->child2],
102 "LABEL",
103 "BYLINE"
104 ))->withNameFrom(new class () implements NameSource {
105 public function getNewName(): string
106 {
107 return "name0";
108 }
109 });
110 }
111
112 protected function buildFactory(): I\Input\Field\Factory
113 {
114 return new I\Input\Field\Factory(
115 $this->createMock(\ILIAS\UI\Implementation\Component\Input\UploadLimitResolver::class),
116 new SignalGenerator(),
117 $this->data_factory,
118 $this->refinery,
119 $this->lng
120 );
121 }
122
123 public function testWithDisabledDisablesChildren(): void
124 {
125 $this->assertNotSame($this->child1, $this->child2);
126
127 $this->child1
128 ->expects($this->once())
129 ->method("withDisabled")
130 ->with(true)
131 ->willReturn($this->child2);
132 $this->child2
133 ->expects($this->once())
134 ->method("withDisabled")
135 ->with(true)
136 ->willReturn($this->child1);
137
138 $new_group = $this->switchable_group->withDisabled(true);
139
140 $this->assertEquals(["child1" => $this->child2, "child2" => $this->child1], $new_group->getInputs());
141 $this->assertInstanceOf(SwitchableGroup::class, $new_group);
142 $this->assertNotSame($this->switchable_group, $new_group);
143 }
144
145 public function testWithRequiredDoesNotRequire(): void
146 {
147 $this->assertNotSame($this->child1, $this->child2);
148
149 $this->child1
150 ->expects($this->never())
151 ->method("withRequired");
152 $this->child2
153 ->expects($this->never())
154 ->method("withRequired");
155
156 $new_group = $this->switchable_group->withRequired(true);
157
158 $this->assertEquals(["child1" => $this->child1, "child2" => $this->child2], $new_group->getInputs());
159 $this->assertInstanceOf(SwitchableGroup::class, $new_group);
160 $this->assertNotSame($this->switchable_group, $new_group);
161 }
162
164 {
165 $this->expectException(InvalidArgumentException::class);
166
167 $this->group = new SwitchableGroup(
168 $this->data_factory,
169 $this->refinery,
170 $this->lng,
171 [$this->createMock(I\Input\Field\FormInput::class)],
172 "LABEL",
173 "BYLINE"
174 );
175 }
176
178 {
179 $this->assertNotSame($this->child1, $this->child2);
180
181 $this->child1
182 ->expects($this->never())
183 ->method("withValue");
184 $this->child2
185 ->expects($this->once())
186 ->method("withValue")
187 ->with(2)
188 ->willReturn($this->child2);
189
190 $new_group = $this->switchable_group->withValue(["child2", 2]);
191
192 $this->assertEquals(["child1" => $this->child1, "child2" => $this->child2], $new_group->getInputs());
193 $this->assertInstanceOf(SwitchableGroup::class, $new_group);
194 $this->assertNotSame($this->switchable_group, $new_group);
195 }
196
198 {
199 $this->expectException(InvalidArgumentException::class);
200 $this->switchable_group->withValue(null);
201 }
202
204 {
205 $this->expectException(InvalidArgumentException::class);
206 $this->switchable_group->withValue([1, 2, 3]);
207 }
208
209 public function testGroupOnlyDoesAcceptKeyOnly(): void
210 {
211 $new_group = $this->switchable_group->withValue("child1");
212 $this->assertEquals(["child1" => $this->child1, "child2" => $this->child2], $new_group->getInputs());
213 $this->assertInstanceOf(SwitchableGroup::class, $new_group);
214 $this->assertNotSame($this->switchable_group, $new_group);
215 }
216
218 {
219 $this->expectException(InvalidArgumentException::class);
220 $this->switchable_group->withValue("child3");
221 }
222
223 public function testGroupForwardsValuesOnGetValue(): void
224 {
225 $this->assertNotSame($this->child1, $this->child2);
226
227 $this->child1
228 ->expects($this->once())
229 ->method("getValue")
230 ->with()
231 ->willReturn("one");
232 $this->child2
233 ->expects($this->never())
234 ->method("getValue");
235
236 $vals = $this->switchable_group->withValue("child1")->getValue();
237
238 $this->assertEquals(["child1", "one"], $vals);
239 }
240
242 {
243 $this->assertNotSame($this->child1, $this->child2);
244
245 $input_data = $this->createMock(InputData::class);
246
247 $input_data
248 ->expects($this->once())
249 ->method("getOr")
250 ->with("name0")
251 ->willReturn("child1");
252
253 $expected_result = $this->data_factory->ok("one");
254
255 $this->child1
256 ->expects($this->once())
257 ->method("withInput")
258 ->with($input_data)
259 ->willReturn($this->child1);
260 $this->child1
261 ->expects($this->once())
262 ->method("getContent")
263 ->with()
264 ->willReturn($expected_result);
265 $this->nested_child
266 ->expects($this->once())
267 ->method("getContent")
268 ->with()
269 ->willReturn($expected_result);
270 $this->child2
271 ->expects($this->never())
272 ->method("withInput");
273 $this->child2
274 ->expects($this->never())
275 ->method("getContent");
276
277 $called = false;
278 $new_group = $this->switchable_group
279 ->withAdditionalTransformation($this->refinery->custom()->transformation(function ($v) use (&$called): string {
280 $called = true;
281 $this->assertEquals(["child1", ["one"]], $v);
282 return "result";
283 }))
284 ->withInput($input_data);
285
286 $this->assertTrue($called);
287 $this->assertEquals(["child1" => $this->child1, "child2" => $this->child2], $new_group->getInputs());
288 $this->assertInstanceOf(SwitchableGroup::class, $new_group);
289 $this->assertNotSame($this->switchable_group, $new_group);
290 $this->assertEquals($this->data_factory->ok("result"), $new_group->getContent());
291 }
292
294 {
295 $this->assertNotSame($this->child1, $this->child2);
296
297 $input_data = $this->createMock(InputData::class);
298
299 $input_data
300 ->expects($this->once())
301 ->method("getOr")
302 ->with("name0")
303 ->willReturn("child2");
304
305 $this->child1
306 ->expects($this->never())
307 ->method("withInput");
308 $this->child1
309 ->expects($this->never())
310 ->method("getContent");
311 $this->child2
312 ->expects($this->once())
313 ->method("withInput")
314 ->with($input_data)
315 ->willReturn($this->child2);
316 $this->child2
317 ->expects($this->once())
318 ->method("getContent")
319 ->willReturn($this->data_factory->error(""));
320
321 $i18n = "THERE IS SOME ERROR IN THIS GROUP";
322 $this->lng
323 ->expects($this->once())
324 ->method("txt")
325 ->with("ui_error_in_group")
326 ->willReturn($i18n);
327
328 $new_group = $this->switchable_group
329 ->withAdditionalTransformation($this->refinery->custom()->transformation(function (): void {
330 $this->fail("This should not happen.");
331 }))
332 ->withInput($input_data);
333
334 $this->assertEquals(["child1" => $this->child1, "child2" => $this->child2], $new_group->getInputs());
335 $this->assertInstanceOf(SwitchableGroup::class, $new_group);
336 $this->assertNotSame($this->switchable_group, $new_group);
337 $this->assertTrue($new_group->getContent()->isError());
338 }
339
340 public function testErrorIsI18NOnError(): void
341 {
342 $this->assertNotSame($this->child1, $this->child2);
343
344 $input_data = $this->createMock(InputData::class);
345
346 $input_data
347 ->expects($this->once())
348 ->method("getOr")
349 ->with("name0")
350 ->willReturn("child2");
351
352 $this->child2
353 ->method("withInput")
354 ->willReturn($this->child2);
355 $this->child2
356 ->method("getContent")
357 ->willReturn($this->data_factory->error(""));
358
359 $i18n = "THERE IS SOME ERROR IN THIS GROUP";
360 $this->lng
361 ->expects($this->once())
362 ->method("txt")
363 ->with("ui_error_in_group")
364 ->willReturn($i18n);
365
366 $switchable_group = $this->switchable_group
367 ->withInput($input_data);
368
369 $this->assertTrue($switchable_group->getContent()->isError());
370 $this->assertEquals($i18n, $switchable_group->getContent()->error());
371 }
372
374 {
375 $this->expectException(InvalidArgumentException::class);
376
377 $input_data = $this->createMock(InputData::class);
378
379 $input_data
380 ->expects($this->once())
381 ->method("getOr")
382 ->with("name0")
383 ->willReturn(123);
384
385 $this->child1
386 ->expects($this->never())
387 ->method("withInput");
388 $this->child1
389 ->expects($this->never())
390 ->method("getContent");
391 $this->child2
392 ->expects($this->never())
393 ->method("withInput");
394 $this->child2
395 ->expects($this->never())
396 ->method("getContent");
397
398 $this->switchable_group
399 ->withAdditionalTransformation($this->refinery->custom()->transformation(function () use (&$called): void {
400 $this->fail("This should not happen.");
401 }))
402 ->withInput($input_data);
403 }
404
405 public function testRender(): SG
406 {
407 $f = $this->buildFactory();
408 $label = "label";
409 $byline = "byline";
410
411 $group1 = $f->group([
412 "field_1" => $f->text("f", "some field")
413 ]);
414 $group2 = $f->group([
415 "field_2" => $f->text("f2", "some other field")
416 ]);
417
418 $sg = $f->switchableGroup(
419 [
420 "g1" => $group1,
421 "g2" => $group2
422 ],
423 $label,
424 $byline
425 );
426
427 $r = $this->getDefaultRenderer();
428 $html = $r->render($sg);
429 $expected = <<<EOT
430<div class="form-group row">
431 <label class="control-label col-sm-4 col-md-3 col-lg-2">label</label>
432 <div class="col-sm-8 col-md-9 col-lg-10">
433 <div id="id_1" class="il-input-radio">
434 <div class="form-control form-control-sm il-input-radiooption">
435 <input type="radio" id="id_1_g1_opt" name="" value="g1" /><label for="id_1_g1_opt"></label>
436 <div class="form-group row">
437 <label for="id_2" class="control-label col-sm-4 col-md-3 col-lg-2">f</label>
438 <div class="col-sm-8 col-md-9 col-lg-10">
439 <input id="id_2" type="text" name="" class="form-control form-control-sm" />
440 <div class="help-block">some field</div>
441 </div>
442 </div>
443 </div>
444 <div class="form-control form-control-sm il-input-radiooption">
445 <input type="radio" id="id_1_g2_opt" name="" value="g2" /><label for="id_1_g2_opt"></label>
446 <div class="form-group row">
447 <label for="id_3" class="control-label col-sm-4 col-md-3 col-lg-2">f2</label>
448 <div class="col-sm-8 col-md-9 col-lg-10">
449 <input id="id_3" type="text" name="" class="form-control form-control-sm" />
450 <div class="help-block">some other field</div>
451 </div>
452 </div>
453 </div>
454 </div>
455 <div class="help-block">byline</div>
456 </div>
457</div>
458
459EOT;
460 $this->assertEquals(
461 $this->brutallyTrimHTML($expected),
462 $this->brutallyTrimHTML($html)
463 );
464 return $sg;
465 }
466
470 public function testRenderWithValue(SG $sg): void
471 {
472 $r = $this->getDefaultRenderer();
473 $html = $r->render($sg->withValue('g2'));
474 $expected = <<<EOT
475<div class="form-group row">
476 <label class="control-label col-sm-4 col-md-3 col-lg-2">label</label>
477 <div class="col-sm-8 col-md-9 col-lg-10">
478 <div id="id_1" class="il-input-radio">
479 <div class="form-control form-control-sm il-input-radiooption">
480 <input type="radio" id="id_1_g1_opt" name="" value="g1" /><label for="id_1_g1_opt"></label>
481 <div class="form-group row">
482 <label for="id_2" class="control-label col-sm-4 col-md-3 col-lg-2">f</label>
483 <div class="col-sm-8 col-md-9 col-lg-10">
484 <input id="id_2" type="text" name="" class="form-control form-control-sm" />
485 <div class="help-block">some field</div>
486 </div>
487 </div>
488 </div>
489 <div class="form-control form-control-sm il-input-radiooption">
490 <input type="radio" id="id_1_g2_opt" name="" value="g2" checked="checked" /><label for="id_1_g2_opt"></label>
491 <div class="form-group row">
492 <label for="id_3" class="control-label col-sm-4 col-md-3 col-lg-2">f2</label>
493 <div class="col-sm-8 col-md-9 col-lg-10">
494 <input id="id_3" type="text" name="" class="form-control form-control-sm" />
495 <div class="help-block">some other field</div>
496 </div>
497 </div>
498 </div>
499 </div>
500 <div class="help-block">byline</div>
501 </div>
502</div>
503
504EOT;
505 $this->assertEquals(
506 $this->brutallyTrimHTML($expected),
507 $this->brutallyTrimHTML($html)
508 );
509 }
510
511 public function testRenderWithValueByIndex(): void
512 {
513 $f = $this->buildFactory();
514 $label = "label";
515 $byline = "byline";
516
517 $group1 = $f->group([
518 "field_1" => $f->text("f", "some field")
519 ]);
520 $group2 = $f->group([
521 "field_2" => $f->text("f2", "some other field")
522 ]);
523 $empty_group_title = 'empty group, the title';
524 $empty_group_byline = 'empty group, the byline';
525 $group3 = $f->group([], $empty_group_title, $empty_group_byline);
526
527 $sg = $f->switchableGroup([$group1, $group2, $group3], $label, $byline);
528 $r = $this->getDefaultRenderer();
529 $html = $r->render($sg->withValue('1'));
530
531 $expected = <<<EOT
532<div class="form-group row">
533 <label class="control-label col-sm-4 col-md-3 col-lg-2">label</label>
534 <div class="col-sm-8 col-md-9 col-lg-10">
535 <div id="id_1" class="il-input-radio">
536 <div class="form-control form-control-sm il-input-radiooption">
537 <input type="radio" id="id_1_0_opt" name="" value="0" /><label for="id_1_0_opt"></label>
538 <div class="form-group row">
539 <label for="id_2" class="control-label col-sm-4 col-md-3 col-lg-2">f</label>
540 <div class="col-sm-8 col-md-9 col-lg-10">
541 <input id="id_2" type="text" name="" class="form-control form-control-sm" />
542 <div class="help-block">some field</div>
543 </div>
544 </div>
545 </div>
546 <div class="form-control form-control-sm il-input-radiooption">
547 <input type="radio" id="id_1_1_opt" name="" value="1" checked="checked" /><label for="id_1_1_opt"></label>
548 <div class="form-group row">
549 <label for="id_3" class="control-label col-sm-4 col-md-3 col-lg-2">f2</label>
550 <div class="col-sm-8 col-md-9 col-lg-10">
551 <input id="id_3" type="text" name="" class="form-control form-control-sm" />
552 <div class="help-block">some other field</div>
553 </div>
554 </div>
555 </div>
556
557 <div class="form-control form-control-sm il-input-radiooption">
558 <input type="radio" id="id_1_2_opt" name="" value="2" /><label for="id_1_2_opt">empty group, the title</label>
559 <div class="help-block">empty group, the byline</div>
560 </div>
561 </div>
562 <div class="help-block">byline</div>
563 </div>
564</div>
565EOT;
566 $this->assertEquals(
567 $this->brutallyTrimHTML($expected),
568 $this->brutallyTrimHTML($html)
569 );
570 }
571}
static return function(ContainerConfigurator $containerConfigurator)
Definition: basic_rector.php:9
Builds data types.
Definition: Factory.php:21
This implements the group input.
Definition: Group.php:43
Provides common functionality for UI tests.
Definition: Base.php:299
brutallyTrimHTML(string $html)
A more radical version of normalizeHTML.
Definition: Base.php:444
getDefaultRenderer(JavaScriptBinding $js_binding=null, array $with_stub_renderings=[])
Definition: Base.php:355
ILIAS UI Component Input Field Group $switchable_group
testRenderWithValue(SG $sg)
@depends testRender
This describes switchable group inputs.
Describes how Input-Elements want to interact with posted data.
Definition: InputData.php:30
Describes a source for input names.
Definition: NameSource.php:27
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
withNameFrom(NameSource $source, ?string $parent_name=null)
@inheritDoc
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
Class ChatMainBarProvider \MainMenu\Provider.
Class Factory.