ILIAS  trunk Revision v11.0_alpha-3011-gc6b235a2e85
ElementHelperTest.php
Go to the documentation of this file.
1<?php
2
19declare(strict_types=1);
20
22
23use PHPUnit\Framework\TestCase;
28use ILIAS\MetaData\Paths\FactoryInterface as PathFactoryInterface;
29use ILIAS\MetaData\Paths\NullFactory as NullPathFactory;
42
43class ElementHelperTest extends TestCase
44{
45 protected static function getMockElement(string $name): ElementInterface
46 {
47 return new class ($name) extends NullElement {
48 public function __construct(
49 protected string $name
50 ) {
51 }
52
53 public function getDefinition(): DefinitionInterface
54 {
55 return new class ($this->name) extends NullDefinition {
56 public function __construct(
57 protected string $name
58 ) {
59 }
60
61 public function name(): string
62 {
63 return $this->name;
64 }
65 };
66 }
67 };
68 }
69
70 protected function getMockConditionChecker(
71 string $element_name = '',
72 ?Identifier $fits_slot = null
73 ): ConditionCheckerInterface {
74 return new class ($element_name, $fits_slot) extends NullConditionChecker {
75 public function __construct(
76 protected string $element_name,
77 protected ?Identifier $fits_slot
78 ) {
79 }
80
81 public function doesElementFitSlot(
82 ElementInterface $element,
83 SlotIdentifier $slot,
84 bool $ignore_markers = true
85 ): bool {
86 if ($element->getDefinition()->name() !== $this->element_name) {
87 return false;
88 }
89 if ($slot !== $this->fits_slot) {
90 return false;
91 }
92 return true;
93 }
94 };
95 }
96
97 protected function getMockPathFactory(): PathFactoryInterface
98 {
99 return new class () extends NullPathFactory {
100 public function toElement(
102 bool $leads_to_exactly_one = false
103 ): PathInterface {
104 $string = '';
105 if ($leads_to_exactly_one) {
106 $string = 'exactly ';
107 }
108 $string .= 'to ' . $to->getDefinition()->name();
109 return new class ($string) extends NullPath {
110 public function __construct(
111 protected string $string
112 ) {
113 }
114
115 public function toString(): string
116 {
117 return $this->string;
118 }
119 };
120 }
121
122 public function betweenElements(
125 bool $leads_to_exactly_one = false
126 ): PathInterface {
127 $string = '';
128 if ($leads_to_exactly_one) {
129 $string = 'exactly ';
130 }
131 $string .= 'from ' . $from->getDefinition()->name() . ' to ' . $to->getDefinition()->name();
132 return new class ($string) extends NullPath {
133 public function __construct(
134 protected string $string
135 ) {
136 }
137
138 public function toString(): string
139 {
140 return $this->string;
141 }
142 };
143 }
144 };
145 }
146
147 public function getMockNavigatorFactory(
148 string $expected_path = '',
149 string $expected_start_element_name = '',
150 ?ElementInterface $returned_element = null
152 return new class ($expected_path, $expected_start_element_name, $returned_element) extends NullNavigatorFactory {
153 public function __construct(
154 protected string $expected_path,
155 protected string $expected_start_element_name,
156 protected ?ElementInterface $expected_element
157 ) {
158 }
159
160 public function navigator(PathInterface $path, ElementInterface $start_element): NavigatorInterface
161 {
162 if (
163 $path->toString() !== $this->expected_path &&
164 $start_element->getDefinition()->name() !== $this->expected_start_element_name
165 ) {
166 throw new \Exception('wrong path or element name');
167 }
168 return new class ($this->expected_element) extends NullNavigator {
169 public function __construct(
170 protected ?ElementInterface $leads_to
171 ) {
172 }
173
174 public function lastElementAtFinalStep(): ?ElementInterface
175 {
176 return $this->leads_to;
177 }
178 };
179 }
180 };
181 }
182
183 public function getMockHandler(
184 string $expected_path = '',
185 array $identifiers = [],
186 array $condition_paths_by_identifer = [],
187 array $condition_values_by_identifer = []
189 return new class ($expected_path, $identifiers, $condition_paths_by_identifer, $condition_values_by_identifer) extends NullHandler {
190 public function __construct(
191 protected string $expected_path,
192 protected array $identifiers,
193 protected array $condition_paths_by_identifer,
194 protected array $condition_values_by_identifer
195 ) {
196 }
197
198 public function allSlotsForPath(PathInterface $path_to_element): \Generator
199 {
200 if ($path_to_element->toString() !== $this->expected_path) {
201 throw new \Exception('wrong path');
202 }
203 yield from $this->identifiers;
204 }
205
206 public function identiferFromPathAndCondition(
207 PathInterface $path_to_element,
208 ?PathInterface $path_to_condition,
209 ?string $condition_value
210 ): Identifier {
211 if ($path_to_element->toString() !== $this->expected_path) {
212 throw new \Exception('wrong path');
213 }
214 foreach ($this->identifiers as $identifier) {
215 if (
216 ($this->condition_paths_by_identifer[$identifier->value] ?? null) !== $path_to_condition->toString() ||
217 ($this->condition_values_by_identifer[$identifier->value] ?? null) !== $condition_value
218 ) {
219 continue;
220 }
221 return $identifier;
222 };
223 return Identifier::NULL;
224 }
225
226 public function isSlotConditional(Identifier $identifier): bool
227 {
228 return isset($this->condition_paths_by_identifer[$identifier->value]) &&
229 isset($this->condition_values_by_identifer[$identifier->value]);
230 }
231
232 public function conditionForSlot(Identifier $identifier): ?ConditionInterface
233 {
234 $condition_path = $this->condition_paths_by_identifer[$identifier->value] ?? null;
235 if ($condition_path === null) {
236 return null;
237 }
238 // sometimes null
239 return new class ($condition_path) extends NullCondition {
240 public function __construct(
241 protected string $condition_path
242 ) {
243 }
244
245 public function path(): PathInterface
246 {
247 return new class ($this->condition_path) extends NullPath {
248 public function __construct(
249 protected string $string
250 ) {
251 }
252
253 public function toString(): string
254 {
255 return $this->string;
256 }
257 };
258 }
259 };
260 }
261 };
262 }
263
264 public static function slotsForElementWithoutConditionProvider(): array
265 {
266 return [
267 [
268 'some element',
269 []
270 ],
271 [
272 'some element',
273 [Identifier::EDUCATIONAL_CONTEXT, Identifier::GENERAL_STRUCTURE, Identifier::LIFECYCLE_STATUS]
274 ]
275 ];
276 }
277
278 #[\PHPUnit\Framework\Attributes\DataProvider('slotsForElementWithoutConditionProvider')]
280 string $element_name,
281 array $expected_identifiers
282 ): void {
283 $helper = new ElementHelper(
284 $this->getMockHandler('to ' . $element_name, $expected_identifiers),
285 $this->getMockPathFactory(),
286 $this->getMockNavigatorFactory(),
287 $this->getMockConditionChecker()
288 );
289 $element = self::getMockElement($element_name);
290
291 $actual_identifiers = iterator_to_array($helper->slotsForElementWithoutCondition($element));
292
293 $this->assertSame($expected_identifiers, $actual_identifiers);
294 }
295
296 public static function slotsForElementProvider(): array
297 {
298 return [
299 [
300 'some element',
301 [],
302 null
303 ],
304 [
305 'some element',
306 [Identifier::EDUCATIONAL_CONTEXT, Identifier::GENERAL_STRUCTURE, Identifier::LIFECYCLE_STATUS],
307 null
308 ],
309 [
310 'some element',
311 [Identifier::EDUCATIONAL_CONTEXT, Identifier::GENERAL_STRUCTURE, Identifier::LIFECYCLE_STATUS],
312 Identifier::GENERAL_STRUCTURE
313 ]
314 ];
315 }
316
317 #[\PHPUnit\Framework\Attributes\DataProvider('slotsForElementProvider')]
318 public function testSlotForElement(
319 string $element_name,
320 array $all_identifiers,
321 ?Identifier $matching_identifier
322 ): void {
323 $helper = new ElementHelper(
324 $this->getMockHandler('to ' . $element_name, $all_identifiers),
325 $this->getMockPathFactory(),
326 $this->getMockNavigatorFactory(),
327 $this->getMockConditionChecker($element_name, $matching_identifier)
328 );
329 $element = self::getMockElement($element_name);
330
331 $actual_identifier = $helper->slotForElement($element);
332
333 $this->assertSame($matching_identifier ?? Identifier::NULL, $actual_identifier);
334 }
335
336 public static function potentialSlotForElementByConditionProvider(): array
337 {
338 return [
339 [
340 'some element',
341 'element in condition',
342 'condition value',
343 [],
344 [],
345 [],
346 null
347 ],
348 [
349 'some element',
350 'element in condition',
351 'condition value',
352 [Identifier::EDUCATIONAL_CONTEXT, Identifier::GENERAL_STRUCTURE, Identifier::LIFECYCLE_STATUS],
353 [],
354 [],
355 null
356 ],
357 [
358 'some element',
359 'element in condition',
360 'condition value',
361 [Identifier::EDUCATIONAL_CONTEXT, Identifier::GENERAL_STRUCTURE, Identifier::LIFECYCLE_STATUS],
362 [Identifier::GENERAL_STRUCTURE->value => 'from some element to element in condition'],
363 [Identifier::GENERAL_STRUCTURE->value => 'condition value'],
364 Identifier::GENERAL_STRUCTURE
365 ],
366 [
367 'some element',
368 'element in condition',
369 'wrong value',
370 [Identifier::EDUCATIONAL_CONTEXT, Identifier::GENERAL_STRUCTURE, Identifier::LIFECYCLE_STATUS],
371 [Identifier::GENERAL_STRUCTURE->value => 'from some element to element in condition'],
372 [Identifier::GENERAL_STRUCTURE->value => 'condition value'],
373 null
374 ],
375 [
376 'some element',
377 'wrong element in condition',
378 'condition value',
379 [Identifier::EDUCATIONAL_CONTEXT, Identifier::GENERAL_STRUCTURE, Identifier::LIFECYCLE_STATUS],
380 [Identifier::GENERAL_STRUCTURE->value => 'from some element to element in condition'],
381 [Identifier::GENERAL_STRUCTURE->value => 'condition value'],
382 null
383 ],
384 [
385 'some element',
386 'element in condition',
387 'condition value',
388 [Identifier::EDUCATIONAL_CONTEXT, Identifier::GENERAL_STRUCTURE, Identifier::LIFECYCLE_STATUS],
389 [Identifier::GENERAL_STRUCTURE->value => 'from some element to element in condition', Identifier::LIFECYCLE_STATUS->value => 'different path'],
390 [Identifier::GENERAL_STRUCTURE->value => 'condition value', Identifier::LIFECYCLE_STATUS->value => 'different value'],
391 Identifier::GENERAL_STRUCTURE
392 ]
393 ];
394 }
395
396 #[\PHPUnit\Framework\Attributes\DataProvider('potentialSlotForElementByConditionProvider')]
398 string $element_name,
399 string $element_in_condition_name,
400 string $condition_value,
401 array $all_identifiers,
402 array $condition_paths_by_identifer,
403 array $condition_values_by_identifer,
404 ?Identifier $matching_identifier
405 ): void {
406 $helper = new ElementHelper(
407 $this->getMockHandler('to ' . $element_name, $all_identifiers, $condition_paths_by_identifer, $condition_values_by_identifer),
408 $this->getMockPathFactory(),
409 $this->getMockNavigatorFactory(),
410 $this->getMockConditionChecker()
411 );
412 $element = self::getMockElement($element_name);
413 $element_in_condition = self::getMockElement($element_in_condition_name);
414
415 $actual_identifier = $helper->potentialSlotForElementByCondition(
416 $element,
417 $element_in_condition,
418 $condition_value
419 );
420
421 $this->assertSame($matching_identifier ?? Identifier::NULL, $actual_identifier);
422 }
423
424 public static function findElementOfConditionProvider(): array
425 {
426 $el1 = self::getMockElement('el1');
427 $el2 = self::getMockElement('el2');
428 $el3 = self::getMockElement('el3');
429 $other_element = self::getMockElement('other_element');
430 return [
431 [
432 'some element',
433 [$el1, $el2, $el3],
434 Identifier::EDUCATIONAL_CONTEXT,
435 false,
436 $el1,
437 null
438 ],
439 [
440 'some element',
441 [$el1, $el2, $el3],
442 Identifier::EDUCATIONAL_CONTEXT,
443 true,
444 null,
445 null
446 ],
447 [
448 'some element',
449 [$el1, $el2, $el3],
450 Identifier::EDUCATIONAL_CONTEXT,
451 true,
452 $other_element,
453 null
454 ],
455 [
456 'some element',
457 [$el1, $el2, $el3],
458 Identifier::EDUCATIONAL_CONTEXT,
459 true,
460 $el2,
461 'el2'
462 ],
463 ];
464 }
465
466 #[\PHPUnit\Framework\Attributes\DataProvider('findElementOfConditionProvider')]
468 string $element_name,
469 array $all_elements,
470 Identifier $identifier,
471 bool $conditional,
472 ?ElementInterface $navigator_returns_element,
473 ?string $expected_element_name
474 ): void {
475 $condition_paths_by_identifer = [];
476 $condition_values_by_identifer = [];
477 if ($conditional) {
478 $condition_paths_by_identifer[$identifier->value] = 'some path';
479 $condition_values_by_identifer[$identifier->value] = 'some value';
480 }
481 $helper = new ElementHelper(
482 $this->getMockHandler('', [$identifier], $condition_paths_by_identifer, $condition_values_by_identifer),
483 $this->getMockPathFactory(),
484 $this->getMockNavigatorFactory('some path', $element_name, $navigator_returns_element),
485 $this->getMockConditionChecker()
486 );
487
488 $found = $helper->findElementOfCondition(
489 $identifier,
490 self::getMockElement($element_name),
491 ...$all_elements
492 );
493
494 $this->assertSame($expected_element_name, $found?->getDefinition()?->name());
495 }
496}
testPotentialSlotForElementByCondition(string $element_name, string $element_in_condition_name, string $condition_value, array $all_identifiers, array $condition_paths_by_identifer, array $condition_values_by_identifer, ?Identifier $matching_identifier)
testSlotsForElementWithoutCondition(string $element_name, array $expected_identifiers)
getMockHandler(string $expected_path='', array $identifiers=[], array $condition_paths_by_identifer=[], array $condition_values_by_identifer=[])
getMockConditionChecker(string $element_name='', ?Identifier $fits_slot=null)
testSlotForElement(string $element_name, array $all_identifiers, ?Identifier $matching_identifier)
getMockNavigatorFactory(string $expected_path='', string $expected_start_element_name='', ?ElementInterface $returned_element=null)
testFindElementOfCondition(string $element_name, array $all_elements, Identifier $identifier, bool $conditional, ?ElementInterface $navigator_returns_element, ?string $expected_element_name)
__construct()
Constructor setup ILIAS global object @access public.
Definition: class.ilias.php:76
return['delivery_method'=> 'php',]
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
getDefinition()
Defining properties of the metadata element.
$path
Definition: ltiservices.php:30
__construct(Container $dic, ilPlugin $plugin)
@inheritDoc
if(!file_exists('../ilias.ini.php'))