ILIAS  trunk Revision v11.0_alpha-1753-gb21ca8c4367
All Data Structures Namespaces Files Functions Variables Enumerations Enumerator Modules Pages
ButtonTest.php
Go to the documentation of this file.
1 <?php
2 
19 declare(strict_types=1);
20 
21 require_once(__DIR__ . "/../../../../../../vendor/composer/vendor/autoload.php");
22 require_once(__DIR__ . "/../../Base.php");
23 
24 use ILIAS\UI\Component as C;
27 use ILIAS\UI\Help;
29 
34 {
35  public const NOT_APPLICABLE = true;
36 
37  public function getButtonFactory(): Factory
38  {
39  return new Factory();
40  }
41 
42  public static array $canonical_css_classes = [
43  "standard" => "btn btn-default",
44  "primary" => "btn btn-default btn-primary",
45  "shy" => "btn btn-link",
46  "tag" => "btn btn-tag btn-tag-relevance-veryhigh"
47  ];
48 
49  public function testImplementsFactoryInterface(): void
50  {
51  $f = $this->getButtonFactory();
52 
53  $this->assertInstanceOf("ILIAS\\UI\\Component\\Button\\Factory", $f);
54  $this->assertInstanceOf(
55  "ILIAS\\UI\\Component\\Button\\Standard",
56  $f->standard("label", "http://www.ilias.de")
57  );
58  $this->assertInstanceOf(
59  "ILIAS\\UI\\Component\\Button\\Primary",
60  $f->primary("label", "http://www.ilias.de")
61  );
62  $this->assertInstanceOf(
63  "ILIAS\\UI\\Component\\Button\\Close",
64  $f->close()
65  );
66  $this->assertInstanceOf(
67  "ILIAS\\UI\\Component\\Button\\Shy",
68  $f->shy("label", "http://www.ilias.de")
69  );
70  }
71 
75  public function testButtonLabelOrGlyphOnly(string $factory_method): void
76  {
77  $this->expectException(TypeError::class);
78  $f = $this->getButtonFactory();
79  $f->$factory_method($this, "http://www.ilias.de");
80  }
81 
85  public function testButtonStringActionOnly(string $factory_method): void
86  {
87  $this->expectException(InvalidArgumentException::class);
88  $f = $this->getButtonFactory();
89  $f->$factory_method("label", $this);
90  }
91 
95  public function testButtonLabel(string $factory_method): void
96  {
97  $f = $this->getButtonFactory();
98  $b = $f->$factory_method("label", "http://www.ilias.de");
99 
100  $this->assertEquals("label", $b->getLabel());
101  }
102 
106  public function testButtonWithLabel(string $factory_method): void
107  {
108  $f = $this->getButtonFactory();
109  $b = $f->$factory_method("label", "http://www.ilias.de");
110 
111  $b2 = $b->withLabel("label2");
112 
113  $this->assertEquals("label", $b->getLabel());
114  $this->assertEquals("label2", $b2->getLabel());
115  }
116 
120  public function testButtonWithGlyphLabel(string $factory_method): void
121  {
122  $f = $this->getButtonFactory();
123  $glyph = new Glyph(C\Symbol\Glyph\Glyph::LIKE, '');
124  $b = $f->$factory_method('', '')
125  ->withSymbol($glyph);
126  $this->assertEquals($glyph, $b->getSymbol());
127  }
128 
132  public function testButtonAction(string $factory_method): void
133  {
134  $f = $this->getButtonFactory();
135  $b = $f->$factory_method("label", "http://www.ilias.de");
136 
137  $this->assertEquals("http://www.ilias.de", $b->getAction());
138  }
139 
143  public function testButtonActivatedOnDefault(string $factory_method): void
144  {
145  $f = $this->getButtonFactory();
146  $b = $f->$factory_method("label", "http://www.ilias.de");
147 
148  $this->assertTrue($b->isActive());
149  }
150 
154  public function testButtonDeactivation(string $factory_method): void
155  {
156  $f = $this->getButtonFactory();
157  $b = $f->$factory_method("label", "http://www.ilias.de")
158  ->withUnavailableAction();
159 
160  $this->assertFalse($b->isActive());
161  $this->assertEquals("http://www.ilias.de", $b->getAction());
162 
163  $b = $b->withUnavailableAction(false);
164  $this->assertTrue($b->isActive());
165  }
166 
170  public function testButtonWithLoadingAnimation(): void
171  {
172  $f = $this->getButtonFactory();
173  foreach (["standard", "primary"] as $method) {
174  $b = $f->$method("label", "http://www.ilias.de");
175 
176  $this->assertFalse($b->hasLoadingAnimationOnClick());
177 
178  $b = $b->withLoadingAnimationOnClick(true);
179 
180  $this->assertTrue($b->hasLoadingAnimationOnClick());
181  }
182  }
183 
187  public function testRenderButtonLabel(string $factory_method): void
188  {
189  $ln = "http://www.ilias.de";
190  $f = $this->getButtonFactory();
191  $b = $f->$factory_method("label", $ln);
192  $r = $this->getDefaultRenderer();
193 
194  $html = $this->normalizeHTML($r->render($b));
195 
196  $css_classes = self::$canonical_css_classes[$factory_method];
197  $expected = "<button class=\"$css_classes\" data-action=\"$ln\" id=\"id_1\">" .
198  "label" .
199  "</button>";
200  $this->assertHTMLEquals($expected, $html);
201  }
202 
206  public function testRenderButtonDisabled(string $factory_method): void
207  {
208  $ln = "http://www.ilias.de";
209  $f = $this->getButtonFactory();
210  $b = $f->$factory_method("label", $ln)
211  ->withUnavailableAction();
212  $r = $this->getDefaultRenderer();
213 
214  $html = $this->normalizeHTML($r->render($b));
215 
216  $css_classes = self::$canonical_css_classes[$factory_method];
217  $expected = "<button class=\"$css_classes\" data-action=\"$ln\" disabled=\"disabled\">" .
218  "label" .
219  "</button>";
220  $this->assertHTMLEquals($expected, $html);
221  }
222 
223  public function testRenderCloseButton(): void
224  {
225  $f = $this->getButtonFactory();
226  $r = $this->getDefaultRenderer();
227  $b = $f->close();
228 
229  $html = $this->normalizeHTML($r->render($b));
230 
231  $expected = "<button type=\"button\" class=\"close\" aria-label=\"close\">" .
232  " <span aria-hidden=\"true\">&times;</span>" .
233  "</button>";
234  $this->assertEquals($expected, $html);
235  }
236 
237  public function testRenderMinimizeButton(): void
238  {
239  $f = $this->getButtonFactory();
240  $r = $this->getDefaultRenderer();
241  $b = $f->minimize();
242 
243  $html = $this->normalizeHTML($r->render($b));
244 
245  $expected = "<button type=\"button\" class=\"minimize\" aria-label=\"minimize\">" .
246  " <span aria-hidden=\"true\">−</span>" .
247  "</button>";
248  $this->assertEquals($expected, $html);
249  }
250 
254  public function testRenderButtonWithOnLoadCode(string $factory_method): void
255  {
256  $ln = "http://www.ilias.de";
257  $f = $this->getButtonFactory();
258  $r = $this->getDefaultRenderer();
259  $ids = array();
260  $b = $f->$factory_method("label", $ln)
261  ->withOnLoadCode(function ($id) use (&$ids): string {
262  $ids[] = $id;
263  return "";
264  });
265 
266  $html = $this->normalizeHTML($r->render($b));
267 
268  $this->assertCount(1, $ids);
269 
270  $id = $ids[0];
271  $css_classes = self::$canonical_css_classes[$factory_method];
272  $expected = "<button class=\"$css_classes\" data-action=\"$ln\" id=\"$id\">" .
273  "label" .
274  "</button>";
275  $this->assertHTMLEquals($expected, $html);
276  }
277 
278  public function testRenderCloseButtonWithOnLoadCode(): void
279  {
280  $f = $this->getButtonFactory();
281  $r = $this->getDefaultRenderer();
282  $ids = array();
283  $b = $f->close()
284  ->withOnLoadCode(function ($id) use (&$ids): string {
285  $ids[] = $id;
286  return "";
287  });
288 
289  $html = $this->normalizeHTML($r->render($b));
290 
291  $this->assertCount(1, $ids);
292 
293  $id = $ids[0];
294  $expected = "<button type=\"button\" class=\"close\" aria-label=\"close\" id=\"$id\">" .
295  " <span aria-hidden=\"true\">&times;</span>" .
296  "</button>";
297  $this->assertEquals($expected, $html);
298  }
299 
300  public function testBtnTagRelevance(): void
301  {
302  $f = $this->getButtonFactory();
303  $b = $f->tag('tag', '#');
304 
305  $this->expectException(TypeError::class);
306  $b->withRelevance(0);
307 
308  $this->expectException(TypeError::class);
309  $b->withRelevance('notsoimportant');
310  }
311 
312  public function testRenderBtnTagRelevance(): void
313  {
314  $expectations = array(
315  '<button class="btn btn-tag btn-tag-relevance-verylow" data-action="#" id="id_1">tag</button>',
316  '<button class="btn btn-tag btn-tag-relevance-low" data-action="#" id="id_2">tag</button>',
317  '<button class="btn btn-tag btn-tag-relevance-middle" data-action="#" id="id_3">tag</button>',
318  '<button class="btn btn-tag btn-tag-relevance-high" data-action="#" id="id_4">tag</button>',
319  '<button class="btn btn-tag btn-tag-relevance-veryhigh" data-action="#" id="id_5">tag</button>'
320  );
321 
322  $f = $this->getButtonFactory();
323  $r = $this->getDefaultRenderer();
324  $t = $f->tag('tag', '#');
325  $possible_relevances = array(
326  $t::REL_VERYLOW,
327  $t::REL_LOW,
328  $t::REL_MID,
329  $t::REL_HIGH,
330  $t::REL_VERYHIGH
331  );
332  foreach ($possible_relevances as $w) {
333  $html = $this->normalizeHTML(
334  $r->render($t->withRelevance($w))
335  );
336  $expected = $expectations[array_search($w, $possible_relevances)];
337  $this->assertEquals($expected, $html);
338  }
339  }
340 
341  public function testRenderBtnTagColors(): void
342  {
343  $f = $this->getButtonFactory();
344  $r = $this->getDefaultRenderer();
345  $df = new \ILIAS\Data\Factory();
346 
347  $bgcol = $df->color('#00ff00');
348 
349  $b = $f->tag('tag', '#')
350  ->withBackgroundColor($bgcol);
351  $html = $this->normalizeHTML($r->render($b));
352  $expected = '<button class="btn btn-tag btn-tag-relevance-veryhigh" style="background-color: #00ff00; color: #000000;" data-action="#" id="id_1">tag</button>';
353  $this->assertEquals($expected, $html);
354 
355  $fcol = $df->color('#ddd');
356  $b = $b->withForegroundColor($fcol);
357  $html = $this->normalizeHTML($r->render($b));
358  $expected = '<button class="btn btn-tag btn-tag-relevance-veryhigh" style="background-color: #00ff00; color: #dddddd;" data-action="#" id="id_2">tag</button>';
359  $this->assertEquals($expected, $html);
360  }
361 
362  public function testRenderBtnTagClasses(): void
363  {
364  $f = $this->getButtonFactory();
365  $r = $this->getDefaultRenderer();
366  $df = new \ILIAS\Data\Factory();
367 
368  $classes = array('cl1', 'cl2');
369  $b = $f->tag('tag', '#')
370  ->withClasses($classes);
371  $this->assertEquals($classes, $b->getClasses());
372 
373  $html = $this->normalizeHTML($r->render($b));
374  $expected = '<button class="btn btn-tag btn-tag-relevance-veryhigh cl1 cl2" data-action="#" id="id_1">tag</button>';
375  $this->assertEquals($expected, $html);
376  }
377 
381  public function testButtonWithAriaLabel(string $factory_method): void
382  {
383  $f = $this->getButtonFactory();
384  $b = $f->$factory_method("label", "http://www.ilias.de")->withAriaLabel("ariatext");
385  $this->assertEquals("ariatext", $b->getAriaLabel());
386  }
387 
391  public function testButtonWithEngageable(string $factory_method): void
392  {
393  $f = $this->getButtonFactory();
394  $b = $f->$factory_method("label", "http://www.ilias.de");
395  if ($b instanceof C\Button\Engageable) {
396  $this->assertEquals(false, $b->isEngageable());
397  $b2 = $f->$factory_method("label", "http://www.ilias.de")->withEngagedState(false);
398  $this->assertEquals(true, $b2->isEngageable());
399  } else {
400  $this->assertTrue(self::NOT_APPLICABLE);
401  }
402  }
403 
407  public function testButtonWithEngaged(string $factory_method): void
408  {
409  $f = $this->getButtonFactory();
410  $b = $f->$factory_method("label", "http://www.ilias.de");
411  if ($b instanceof C\Button\Engageable) {
412  $b = $b->withEngagedState(false);
413  $this->assertEquals(false, $b->isEngaged());
414  $b2 = $f->$factory_method("label", "http://www.ilias.de")->withEngagedState(true);
415  $this->assertEquals(true, $b2->isEngaged());
416  } else {
417  $this->assertTrue(self::NOT_APPLICABLE);
418  }
419  }
420 
424  public function testRenderButtonWithAriaLabel(string $factory_method): void
425  {
426  $ln = "http://www.ilias.de";
427  $f = $this->getButtonFactory();
428  $r = $this->getDefaultRenderer();
429  $b = $f->$factory_method("label", $ln)->withAriaLabel("aria label text");
430  $aria_label = $b->getAriaLabel();
431 
432  $html = $this->normalizeHTML($r->render($b));
433  $css_classes = self::$canonical_css_classes[$factory_method];
434  $expected = "<button class=\"$css_classes\" aria-label=\"$aria_label\" data-action=\"$ln\" id=\"id_1\">" .
435  "label" .
436  "</button>";
437  $this->assertHTMLEquals($expected, $html);
438  }
439 
443  public function testRenderButtonWithAriaPressed(string $factory_method): void
444  {
445  $ln = "http://www.ilias.de";
446  $f = $this->getButtonFactory();
447  $r = $this->getDefaultRenderer();
448  $b = $f->$factory_method("label", $ln);
449  if ($b instanceof C\Button\Engageable) {
450  $b = $b->withEngagedState(true);
451 
452  $html = $this->normalizeHTML($r->render($b));
453  $css_classes = self::$canonical_css_classes[$factory_method];
454  $css_classes .= ' engaged';
455  $expected = "<button class=\"$css_classes\" aria-pressed=\"true\" data-action=\"$ln\" id=\"id_1\">" .
456  "label" .
457  "</button>";
458  $this->assertHTMLEquals($expected, $html);
459  } else {
460  $this->assertTrue(self::NOT_APPLICABLE);
461  }
462  }
463 
467  public function testWithOnClickRemovesAction(string $factory_method): void
468  {
469  $f = $this->getButtonFactory();
470  $signal = $this->createMock(C\Signal::class);
471  $button = $f->$factory_method("label", "http://www.example.com");
472  $this->assertEquals("http://www.example.com", $button->getAction());
473 
474  $button = $button->withOnClick($signal);
475 
476  $this->assertEquals([$signal], $button->getAction());
477  }
478 
482  public function testAppendOnClickAppendsToAction(string $factory_method): void
483  {
484  $f = $this->getButtonFactory();
485  $signal1 = $this->createMock(C\Signal::class);
486  $signal2 = $this->createMock(C\Signal::class);
487  $button = $f->$factory_method("label", "http://www.example.com");
488 
489  $button = $button->withOnClick($signal1)->appendOnClick($signal2);
490 
491  $this->assertEquals([$signal1, $signal2], $button->getAction());
492  }
493 
497  public function testRenderButtonWithSignal(string $factory_method): void
498  {
499  $ln = "http://www.ilias.de";
500  $f = $this->getButtonFactory();
501  $signal = $this->createMock(Signal::class);
502  $signal->method("__toString")
503  ->willReturn("MOCK_SIGNAL");
504 
505  $b = $f->$factory_method("label", $ln)
506  ->withOnClick($signal);
507  $r = $this->getDefaultRenderer();
508 
509  $html = $this->normalizeHTML($r->render($b));
510 
511  $css_classes = self::$canonical_css_classes[$factory_method];
512  $expected = "<button class=\"$css_classes\" id=\"id_1\">" .
513  "label" .
514  "</button>";
515  $this->assertHTMLEquals($expected, $html);
516  }
517 
521  public function testRenderButtonWithOnClickAnimation(): void
522  {
523  foreach (["primary", "standard"] as $method) {
524  $ln = "http://www.ilias.de";
525  $f = $this->getButtonFactory();
526  $r = $this->getDefaultRenderer();
527  $b = $f->$method("label", $ln)
528  ->withLoadingAnimationOnClick(true);
529 
530  $html = $this->normalizeHTML($r->render($b));
531 
532  $css_classes = self::$canonical_css_classes[$method];
533  $expected = "<button class=\"$css_classes\" data-action=\"$ln\" id=\"id_1\">" .
534  "label" .
535  "</button>";
536  $this->assertHTMLEquals($expected, $html);
537  }
538  }
539 
543  public function testButtonRendersTooltip(string $factory_method): void
544  {
545  $f = $this->getButtonFactory();
546  $r = $this->getDefaultRenderer();
547  $ln = "http://www.ilias.de";
548 
549  $button =
550  $f->$factory_method("label", $ln)
551  ->withHelpTopics(new Help\Topic("a"), new Help\Topic("b"));
552 
553  $css_classes = self::$canonical_css_classes[$factory_method];
554  $expected =
555  "<div class=\"c-tooltip__container\">" .
556  "<button class=\"$css_classes\" aria-describedby=\"id_2\" data-action=\"$ln\" id=\"id_1\" >" .
557  "label" .
558  "</button>" .
559  "<div id=\"id_2\" role=\"tooltip\" class=\"c-tooltip c-tooltip--hidden\">" .
560  "<p>tooltip: a</p>" .
561  "<p>tooltip: b</p>" .
562  "</div>" .
563  "</div>";
564 
565  $html = $this->normalizeHTML($r->render($button));
566  $this->assertHTMLEquals($expected, $html);
567  }
568 
569 
570  // TODO: We are missing a test for the rendering of a button with an signal
571  // here. Does it still render the action js?
572 
576  public function testFactoryAcceptsSignalAsAction(string $factory_method): void
577  {
578  $f = $this->getButtonFactory();
579  $signal = $this->createMock(C\Signal::class);
580 
581  $button = $f->$factory_method("label", $signal);
582 
583  $this->assertEquals([$signal], $button->getAction());
584  }
585 
586  public static function getButtonTypeProvider(): array
587  {
588  return [
589  ['standard'],
590  ['primary'],
591  ['shy'],
592  ['tag']
593  ];
594  }
595 
596  public function testRenderButtonWithSymbolAndLabel(): void
597  {
598  $f = $this->getButtonFactory();
599  $r = $this->getDefaultRenderer();
600  $glyph = new Glyph(C\Symbol\Glyph\Glyph::LIKE, 'The Glyph Label');
601  $button = $f->standard('The Button Label', '')
602  ->withSymbol($glyph);
603 
604  // the glyph still contains its aria-label
605  $this->assertStringContainsString(
606  'aria-label="The Glyph Label"',
607  $r->render($glyph)
608  );
609 
610  //but not in button context
611  $expected = $this->brutallyTrimHTML(
612  '
613  <button class="btn btn-default" data-action="">
614  <span class="glyph" role="img">
615  <span class="glyphicon il-glyphicon-like" aria-hidden="true"></span>
616  </span>
617  The Button Label
618  </button>'
619  );
620  $html = $this->brutallyTrimHTML($r->render($button));
621  $this->assertHTMLEquals($expected, $html);
622  }
623 
624 }
testRenderButtonWithOnLoadCode(string $factory_method)
getButtonTypeProvider
Definition: ButtonTest.php:254
testButtonWithAriaLabel(string $factory_method)
getButtonTypeProvider
Definition: ButtonTest.php:381
static getButtonTypeProvider()
Definition: ButtonTest.php:586
testButtonRendersTooltip(string $factory_method)
getButtonTypeProvider
Definition: ButtonTest.php:543
testButtonWithGlyphLabel(string $factory_method)
getButtonTypeProvider
Definition: ButtonTest.php:120
This is just a class that marks a string as a help topic.
Definition: Topic.php:26
testFactoryAcceptsSignalAsAction(string $factory_method)
getButtonTypeProvider
Definition: ButtonTest.php:576
testButtonWithEngaged(string $factory_method)
getButtonTypeProvider
Definition: ButtonTest.php:407
testRenderBtnTagRelevance()
Definition: ButtonTest.php:312
testRenderCloseButton()
Definition: ButtonTest.php:223
testButtonLabelOrGlyphOnly(string $factory_method)
getButtonTypeProvider
Definition: ButtonTest.php:75
testButtonWithLabel(string $factory_method)
getButtonTypeProvider
Definition: ButtonTest.php:106
testAppendOnClickAppendsToAction(string $factory_method)
getButtonTypeProvider
Definition: ButtonTest.php:482
Test on button implementation.
Definition: ButtonTest.php:33
testRenderButtonWithAriaLabel(string $factory_method)
getButtonTypeProvider
Definition: ButtonTest.php:424
testButtonWithLoadingAnimation()
test loading animation
Definition: ButtonTest.php:170
testImplementsFactoryInterface()
Definition: ButtonTest.php:49
testRenderButtonDisabled(string $factory_method)
getButtonTypeProvider
Definition: ButtonTest.php:206
testRenderBtnTagClasses()
Definition: ButtonTest.php:362
testButtonActivatedOnDefault(string $factory_method)
getButtonTypeProvider
Definition: ButtonTest.php:143
testRenderCloseButtonWithOnLoadCode()
Definition: ButtonTest.php:278
getButtonFactory()
Definition: ButtonTest.php:37
testBtnTagRelevance()
Definition: ButtonTest.php:300
testWithOnClickRemovesAction(string $factory_method)
getButtonTypeProvider
Definition: ButtonTest.php:467
static array $canonical_css_classes
Definition: ButtonTest.php:42
testRenderButtonWithOnClickAnimation()
test rendering with on click animation
Definition: ButtonTest.php:521
testRenderButtonWithSymbolAndLabel()
Definition: ButtonTest.php:596
testRenderButtonLabel(string $factory_method)
getButtonTypeProvider
Definition: ButtonTest.php:187
testRenderButtonWithSignal(string $factory_method)
getButtonTypeProvider
Definition: ButtonTest.php:497
testRenderMinimizeButton()
Definition: ButtonTest.php:237
testButtonStringActionOnly(string $factory_method)
getButtonTypeProvider
Definition: ButtonTest.php:85
testRenderButtonWithAriaPressed(string $factory_method)
getButtonTypeProvider
Definition: ButtonTest.php:443
const NOT_APPLICABLE
Definition: ButtonTest.php:35
testButtonWithEngageable(string $factory_method)
getButtonTypeProvider
Definition: ButtonTest.php:391
$id
plugin.php for ilComponentBuildPluginInfoObjectiveTest::testAddPlugins
Definition: plugin.php:23
testRenderBtnTagColors()
Definition: ButtonTest.php:341
testButtonDeactivation(string $factory_method)
getButtonTypeProvider
Definition: ButtonTest.php:154
testButtonLabel(string $factory_method)
getButtonTypeProvider
Definition: ButtonTest.php:95
testButtonAction(string $factory_method)
getButtonTypeProvider
Definition: ButtonTest.php:132
$r