ILIAS  trunk Revision v11.0_alpha-2662-g519ff7d528f
ElementHelperTest.php
Go to the documentation of this file.
1 <?php
2 
19 declare(strict_types=1);
20 
22 
42 
43 class 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 
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(
123  BaseElementInterface $from,
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 = []
188  ): HandlerInterface {
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')]
467  public function testFindElementOfCondition(
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 }
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)
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)
$path
Definition: ltiservices.php:29
while($session_entry=$r->fetchRow(ilDBConstants::FETCHMODE_ASSOC)) return null
__construct()
Constructor setup ILIAS global object public.
Definition: class.ilias.php:76
testFindElementOfCondition(string $element_name, array $all_elements, Identifier $identifier, bool $conditional, ?ElementInterface $navigator_returns_element, ?string $expected_element_name)
getDefinition()
Defining properties of the metadata element.
getMockNavigatorFactory(string $expected_path='', string $expected_start_element_name='', ?ElementInterface $returned_element=null)
testSlotsForElementWithoutCondition(string $element_name, array $expected_identifiers)