ILIAS  trunk Revision v11.0_alpha-1846-g895b5f47236
All Data Structures Namespaces Files Functions Variables Enumerations Enumerator Modules Pages
HarvesterTest.php
Go to the documentation of this file.
1 <?php
2 
19 declare(strict_types=1);
20 
22 
29 use ILIAS\MetaData\OERHarvester\Export\NullHandler as NullExportHandler;
48 
49 class HarvesterTest extends TestCase
50 {
51  protected function getSettings(
52  array $types = [],
53  array $copyright_ids = [],
54  int $harvesting_target_ref_id = 0,
55  int $exposed_source_ref_id = 0
57  return new class (
58  $types,
59  $copyright_ids,
60  $harvesting_target_ref_id,
61  $exposed_source_ref_id
62  ) extends NullSettings {
63  public function __construct(
64  protected array $types,
65  protected array $copyright_ids,
66  protected int $harvesting_target_ref_id,
67  protected int $exposed_source_ref_id
68  ) {
69  }
70 
71  public function getObjectTypesSelectedForHarvesting(): array
72  {
73  return $this->types;
74  }
75 
76  public function getCopyrightEntryIDsSelectedForHarvesting(): array
77  {
78  return $this->copyright_ids;
79  }
80 
81  public function getContainerRefIDForHarvesting(): int
82  {
83  return $this->harvesting_target_ref_id;
84  }
85 
86  public function getContainerRefIDForExposing(): int
87  {
88  return $this->exposed_source_ref_id;
89  }
90  };
91  }
92 
97  protected function getObjectHandler(
98  array $deleted_obj_ids = [],
99  int $valid_source_container = 0,
100  array $obj_ids_referenced_in_container = [],
101  ?int $throw_error_on_deletion_ref_id = null,
102  ?int $throw_error_on_ref_creation_obj_id = null
103  ): ObjectHandler {
104  return new class (
105  $deleted_obj_ids,
106  $valid_source_container,
107  $obj_ids_referenced_in_container,
108  $throw_error_on_deletion_ref_id,
109  $throw_error_on_ref_creation_obj_id
110  ) extends NullObjectHandler {
111  public array $exposed_ref_creations = [];
112  public array $exposed_ref_deletions = [];
113 
114  public function __construct(
115  protected array $deleted_obj_ids,
116  protected int $valid_target_container,
117  protected array $obj_ids_referenced_in_container,
118  protected ?int $throw_error_on_deletion_ref_id = null,
119  protected ?int $throw_error_on_ref_creation_obj_id = null
120  ) {
121  }
122 
123  public function referenceObjectInTargetContainer(int $obj_id, int $container_ref_id): int
124  {
125  if ($obj_id === $this->throw_error_on_ref_creation_obj_id) {
126  throw new \ilMDOERHarvesterException('error');
127  }
128  $new_ref_id = (int) ($container_ref_id . $obj_id);
129  $this->exposed_ref_creations[] = [
130  'obj_id' => $obj_id,
131  'container_ref_id' => $container_ref_id,
132  'new_ref_id' => $new_ref_id
133  ];
134  return $new_ref_id;
135  }
136 
137  public function getObjectReferenceIDInContainer(int $obj_id, int $container_ref_id): ?int
138  {
139  if (in_array($obj_id, $this->obj_ids_referenced_in_container)) {
140  return (int) ($container_ref_id . $obj_id);
141  }
142  return null;
143  }
144 
145  public function isObjectDeleted(int $obj_id): bool
146  {
147  return in_array($obj_id, $this->deleted_obj_ids);
148  }
149 
150  public function deleteReference(int $ref_id): void
151  {
152  if ($ref_id === $this->throw_error_on_deletion_ref_id) {
153  throw new \ilMDOERHarvesterException('error');
154  }
155  $this->exposed_ref_deletions[] = $ref_id;
156  }
157 
158  public function getTypeOfReferencedObject(int $ref_id): string
159  {
160  return 'type_' . $ref_id;
161  }
162  };
163  }
164 
165  protected function getExportHandler(
166  ?int $throw_exception_for_id = null,
167  int ...$already_have_export_obj_ids
168  ): ExportHandler {
169  return new class ($throw_exception_for_id, $already_have_export_obj_ids) extends NullExportHandler {
170  public array $exposed_created_exports_obj_ids = [];
171 
172  public function __construct(
173  protected ?int $throw_exception_for_id,
174  protected array $already_have_export_obj_ids
175  ) {
176  }
177 
178  public function hasPublicAccessExport(int $obj_id): bool
179  {
180  if ($this->throw_exception_for_id === $obj_id) {
181  throw new \Exception('error');
182  }
183  return in_array($obj_id, $this->already_have_export_obj_ids);
184  }
185 
186  public function createPublicAccessExport(int $obj_id): void
187  {
188  if ($this->throw_exception_for_id === $obj_id) {
189  throw new \Exception('error');
190  }
191  $this->exposed_created_exports_obj_ids[] = $obj_id;
192  }
193  };
194  }
195 
199  protected function getStatusRepository(
200  array $currently_harvested = [],
201  array $blocked_obj_ids = [],
202  bool $throw_error = false
203  ): StatusRepository {
204  return new class ($currently_harvested, $blocked_obj_ids, $throw_error) extends NullStatusRepository {
205  public array $exposed_deletions = [];
206  public array $exposed_creations = [];
207 
208  public function __construct(
209  protected array $currently_harvested,
210  protected array $blocked_obj_ids,
211  protected bool $throw_error
212  ) {
213  }
214 
215  public function getAllHarvestedObjIDs(): \Generator
216  {
217  if ($this->throw_error === true) {
218  throw new \ilMDOERHarvesterException('error');
219  }
220  yield from array_keys($this->currently_harvested);
221  }
222 
223  public function filterOutBlockedObjects(int ...$obj_ids): \Generator
224  {
225  foreach ($obj_ids as $obj_id) {
226  if (!in_array($obj_id, $this->blocked_obj_ids)) {
227  yield $obj_id;
228  }
229  }
230  }
231 
232  public function getHarvestRefID(int $obj_id): int
233  {
234  return $this->currently_harvested[$obj_id];
235  }
236 
237  public function deleteHarvestRefID(int $obj_id): void
238  {
239  $this->exposed_deletions[] = $obj_id;
240  }
241 
242  public function setHarvestRefID(int $obj_id, int $harvested_ref_id): void
243  {
244  $this->exposed_creations[] = [
245  'obj_id' => $obj_id,
246  'href_id' => $harvested_ref_id
247  ];
248  }
249  };
250  }
251 
255  protected function getExposedRecordRepository(array $returned_records = []): ExposedRecordRepository
256  {
257  return new class ($returned_records) extends NullExposedRecordRepository {
258  public array $exposed_deletions = [];
259  public array $exposed_updates = [];
260  public array $exposed_creations = [];
261 
262  public function __construct(protected array $returned_records)
263  {
264  }
265 
266  public function getRecords(
267  ?\DateTimeImmutable $from = null,
268  ?\DateTimeImmutable $until = null,
269  ?int $limit = null,
270  ?int $offset = null
271  ): \Generator {
272  foreach ($this->returned_records as $obj_id => $metadata) {
273  yield new class ($obj_id, $metadata) extends NullRecord {
274  public function __construct(
275  protected int $obj_id,
276  protected string $metadata
277  ) {
278  }
279 
280  public function infos(): RecordInfosInterface
281  {
282  return new class ($this->obj_id) extends NullRecordInfos {
283  public function __construct(protected int $obj_id)
284  {
285  }
286 
287  public function objID(): int
288  {
289  return $this->obj_id;
290  }
291  };
292  }
293 
294  public function metadata(): \DOMDocument
295  {
296  $xml = new \DOMDocument();
297  $xml->loadXML($this->metadata);
298  return $xml;
299  }
300  };
301  }
302  }
303 
304  public function deleteRecord(int $obj_id): void
305  {
306  $this->exposed_deletions[] = ['obj_id' => $obj_id];
307  }
308 
309  public function updateRecord(int $obj_id, \DOMDocument $metadata): void
310  {
311  $this->exposed_updates[] = [
312  'obj_id' => $obj_id,
313  'metadata' => $metadata->saveXML()
314  ];
315  }
316 
317  public function createRecord(int $obj_id, string $identifier, \DOMDocument $metadata): void
318  {
319  $this->exposed_creations[] = [
320  'obj_id' => $obj_id,
321  'identifier' => $identifier,
322  'metadata' => $metadata->saveXML()
323  ];
324  }
325  };
326  }
327 
328  protected function getSearchFactory(int ...$search_result_obj_ids): SearchFactory
329  {
330  return new class ($search_result_obj_ids) extends NullFactory {
331  public array $exposed_search_params;
332 
333  public function __construct(public array $search_result_obj_ids)
334  {
335  }
336 
337  public function get(): SearcherInterface
338  {
339  return new class ($this) extends NullSearcher {
340  protected array $types = [];
341  protected bool $restricted_to_repository = false;
342 
343  public function __construct(protected SearchFactory $factory)
344  {
345  }
346 
347  public function withRestrictionToRepositoryObjects(bool $restricted): SearcherInterface
348  {
349  $clone = clone $this;
350  $clone->restricted_to_repository = $restricted;
351  return $clone;
352  }
353 
354  public function withAdditionalTypeFilter(string $type): SearcherInterface
355  {
356  $clone = clone $this;
357  $clone->types[] = $type;
358  return $clone;
359  }
360 
361  public function search(
362  LOMRepository $lom_repository,
363  int $first_entry_id,
364  int ...$further_entry_ids
365  ): \Generator {
366  $this->factory->exposed_search_params[] = [
367  'restricted' => $this->restricted_to_repository,
368  'types' => $this->types,
369  'entries' => [$first_entry_id, ...$further_entry_ids]
370  ];
371  foreach ($this->factory->search_result_obj_ids as $obj_id) {
372  yield new class ($obj_id) extends NullRessourceID {
373  public function __construct(protected int $obj_id)
374  {
375  }
376 
377  public function objID(): int
378  {
379  return $this->obj_id;
380  }
381  };
382  }
383  }
384  };
385  }
386  };
387  }
388 
392  protected function getXMLWriter(array $returned_md = []): SimpleDCXMLWriter
393  {
394  return new class ($returned_md) extends NullWriter {
395  public array $exposed_params = [];
396 
397  public function __construct(protected array $returned_md)
398  {
399  }
400 
401  public function writeSimpleDCMetaData(int $obj_id, int $ref_id, string $type): \DOMDocument
402  {
403  $this->exposed_params[] = [
404  'obj_id' => $obj_id,
405  'ref_id' => $ref_id,
406  'type' => $type
407  ];
408 
409  $xml = new \DOMDocument();
410  $xml->loadXML($this->returned_md[$obj_id]);
411  return $xml;
412  }
413  };
414  }
415 
416  protected function getNullLogger(): \ilLogger
417  {
418  return $this->createMock(\ilLogger::class);
419  }
420 
422  {
423  return new class () extends NullWrapper {
424  public int $exposed_status;
425  public string $exposed_message;
426 
427  public function withMessage(string $message): WrapperInterface
428  {
429  $clone = clone $this;
430  $clone->exposed_message = $message;
431  return $clone;
432  }
433 
434  public function withStatus(int $status): WrapperInterface
435  {
436  $clone = clone $this;
437  $clone->exposed_status = $status;
438  return $clone;
439  }
440  };
441  }
442 
444  {
445  $harvester = new Harvester(
446  $this->getSettings(['type', 'second type'], [12, 5], 123, 456),
447  $object_handler = $this->getObjectHandler(),
448  $this->getExportHandler(),
449  $status_repo = $this->getStatusRepository([32 => 12332, 45 => 12345]),
451  $search_factory = $this->getSearchFactory(45),
452  new NullLOMRepository(),
453  $this->getXMLWriter(),
454  $this->getNullLogger()
455  );
456 
457  $result = $harvester->run($this->getCronResultWrapper());
458 
459  $this->assertSame(\ILIAS\Cron\Job\JobResult::STATUS_OK, $result->exposed_status);
460  $this->assertSame(
461  'Deleted 1 deprecated references.<br>' .
462  'Created 0 new references.<br>' .
463  'Created, updated, or deleted 0 exposed records.',
464  $result->exposed_message
465  );
466  $this->assertSame(
467  [['restricted' => true, 'types' => ['type', 'second type'], 'entries' => [12, 5]]],
468  $search_factory->exposed_search_params
469  );
470  $this->assertSame([32], $status_repo->exposed_deletions);
471  $this->assertSame([12332], $object_handler->exposed_ref_deletions);
472  }
473 
475  {
476  $harvester = new Harvester(
477  $this->getSettings(['type', 'second type'], [12, 5], 123, 456),
478  $object_handler = $this->getObjectHandler(),
479  $this->getExportHandler(),
480  $status_repo = $this->getStatusRepository([32 => 12332, 45 => 12345], [32]),
482  $this->getSearchFactory(45, 32),
483  new NullLOMRepository(),
484  $this->getXMLWriter(),
485  $this->getNullLogger()
486  );
487 
488  $result = $harvester->run($this->getCronResultWrapper());
489 
490  $this->assertSame(\ILIAS\Cron\Job\JobResult::STATUS_OK, $result->exposed_status);
491  $this->assertSame(
492  'Deleted 1 deprecated references.<br>' .
493  'Created 0 new references.<br>' .
494  'Created, updated, or deleted 0 exposed records.',
495  $result->exposed_message
496  );
497  $this->assertSame([32], $status_repo->exposed_deletions);
498  $this->assertSame([12332], $object_handler->exposed_ref_deletions);
499  }
500 
502  {
503  $harvester = new Harvester(
504  $this->getSettings(['type', 'second type'], [12, 5], 123, 456),
505  $object_handler = $this->getObjectHandler([32]),
506  $this->getExportHandler(),
507  $status_repo = $this->getStatusRepository([32 => 12332, 45 => 12345]),
509  $this->getSearchFactory(45, 32),
510  new NullLOMRepository(),
511  $this->getXMLWriter(),
512  $this->getNullLogger()
513  );
514 
515  $result = $harvester->run($this->getCronResultWrapper());
516 
517  $this->assertSame(\ILIAS\Cron\Job\JobResult::STATUS_OK, $result->exposed_status);
518  $this->assertSame(
519  'Deleted 1 deprecated references.<br>' .
520  'Created 0 new references.<br>' .
521  'Created, updated, or deleted 0 exposed records.',
522  $result->exposed_message
523  );
524  $this->assertSame([32], $status_repo->exposed_deletions);
525  $this->assertSame([12332], $object_handler->exposed_ref_deletions);
526  }
527 
529  {
530  $harvester = new Harvester(
531  $this->getSettings(['type', 'second type'], [12, 5], 123, 456),
532  $object_handler = $this->getObjectHandler([], 0, [], 12345),
533  $this->getExportHandler(),
534  $status_repo = $this->getStatusRepository([32 => 12332, 45 => 12345, 67 => 12367]),
536  $this->getSearchFactory(),
537  new NullLOMRepository(),
538  $this->getXMLWriter(),
539  $this->getNullLogger()
540  );
541 
542  $result = $harvester->run($this->getCronResultWrapper());
543 
544  $this->assertSame(\ILIAS\Cron\Job\JobResult::STATUS_OK, $result->exposed_status);
545  $this->assertSame(
546  'Deleted 2 deprecated references.<br>' .
547  'Created 0 new references.<br>' .
548  'Created, updated, or deleted 0 exposed records.',
549  $result->exposed_message
550  );
551  $this->assertSame([32, 67], $status_repo->exposed_deletions);
552  $this->assertSame([12332, 12367], $object_handler->exposed_ref_deletions);
553  }
554 
555  public function testRunHarvestObject(): void
556  {
557  $harvester = new Harvester(
558  $this->getSettings(['type', 'second type'], [12, 5], 123, 456),
559  $object_handler = $this->getObjectHandler(),
560  $export_handler = $this->getExportHandler(),
561  $status_repo = $this->getStatusRepository([32 => 12332]),
563  $search_factory = $this->getSearchFactory(32, 45),
564  new NullLOMRepository(),
565  $this->getXMLWriter(),
566  $this->getNullLogger()
567  );
568 
569  $result = $harvester->run($this->getCronResultWrapper());
570 
571  $this->assertSame(\ILIAS\Cron\Job\JobResult::STATUS_OK, $result->exposed_status);
572  $this->assertSame(
573  'Deleted 0 deprecated references.<br>' .
574  'Created 1 new references.<br>' .
575  'Created, updated, or deleted 0 exposed records.',
576  $result->exposed_message
577  );
578  $this->assertSame(
579  [[
580  'restricted' => true,
581  'types' => ['type', 'second type'],
582  'entries' => [12, 5]
583  ]],
584  $search_factory->exposed_search_params
585  );
586  $this->assertSame(
587  [['obj_id' => 45, 'href_id' => 12345]],
588  $status_repo->exposed_creations
589  );
590  $this->assertSame(
591  [['obj_id' => 45, 'container_ref_id' => 123, 'new_ref_id' => 12345]],
592  $object_handler->exposed_ref_creations
593  );
594  $this->assertSame([45], $export_handler->exposed_created_exports_obj_ids);
595  }
596 
597  public function testRunDoNotHarvestBlockedObject(): void
598  {
599  $harvester = new Harvester(
600  $this->getSettings(['type', 'second type'], [12, 5], 123, 456),
601  $object_handler = $this->getObjectHandler(),
602  $export_handler = $this->getExportHandler(),
603  $status_repo = $this->getStatusRepository([32 => 12332], [45]),
605  $this->getSearchFactory(32, 45),
606  new NullLOMRepository(),
607  $this->getXMLWriter(),
608  $this->getNullLogger()
609  );
610 
611  $result = $harvester->run($this->getCronResultWrapper());
612 
613  $this->assertSame(\ILIAS\Cron\Job\JobResult::STATUS_NO_ACTION, $result->exposed_status);
614  $this->assertSame(
615  'Deleted 0 deprecated references.<br>' .
616  'Created 0 new references.<br>' .
617  'Created, updated, or deleted 0 exposed records.',
618  $result->exposed_message
619  );
620  $this->assertEmpty($status_repo->exposed_creations);
621  $this->assertEmpty($object_handler->exposed_ref_creations);
622  $this->assertEmpty($export_handler->exposed_created_exports_obj_ids);
623  }
624 
625  public function testRunDoNotHarvestDeletedObject(): void
626  {
627  $harvester = new Harvester(
628  $this->getSettings(['type', 'second type'], [12, 5], 123, 456),
629  $object_handler = $this->getObjectHandler([45]),
630  $export_handler = $this->getExportHandler(),
631  $status_repo = $this->getStatusRepository([32 => 12332]),
633  $this->getSearchFactory(32, 45),
634  new NullLOMRepository(),
635  $this->getXMLWriter(),
636  $this->getNullLogger()
637  );
638 
639  $result = $harvester->run($this->getCronResultWrapper());
640 
641  $this->assertSame(\ILIAS\Cron\Job\JobResult::STATUS_NO_ACTION, $result->exposed_status);
642  $this->assertSame(
643  'Deleted 0 deprecated references.<br>' .
644  'Created 0 new references.<br>' .
645  'Created, updated, or deleted 0 exposed records.',
646  $result->exposed_message
647  );
648  $this->assertEmpty($status_repo->exposed_creations);
649  $this->assertEmpty($object_handler->exposed_ref_creations);
650  $this->assertEmpty($export_handler->exposed_created_exports_obj_ids);
651  }
652 
654  {
655  $harvester = new Harvester(
656  $this->getSettings(['type', 'second type'], [12, 5], 123, 456),
657  $object_handler = $this->getObjectHandler(),
658  $export_handler = $this->getExportHandler(),
659  $status_repo = $this->getStatusRepository([32 => 12332, 45 => 12345]),
661  $this->getSearchFactory(32, 45),
662  new NullLOMRepository(),
663  $this->getXMLWriter(),
664  $this->getNullLogger()
665  );
666 
667  $result = $harvester->run($this->getCronResultWrapper());
668 
669  $this->assertSame(\ILIAS\Cron\Job\JobResult::STATUS_NO_ACTION, $result->exposed_status);
670  $this->assertSame(
671  'Deleted 0 deprecated references.<br>' .
672  'Created 0 new references.<br>' .
673  'Created, updated, or deleted 0 exposed records.',
674  $result->exposed_message
675  );
676  $this->assertEmpty($status_repo->exposed_creations);
677  $this->assertEmpty($object_handler->exposed_ref_creations);
678  $this->assertEmpty($export_handler->exposed_created_exports_obj_ids);
679  }
680 
682  {
683  $harvester = new Harvester(
684  $this->getSettings(['type', 'second type'], [12, 5], 0, 456),
685  $object_handler = $this->getObjectHandler(),
686  $export_handler = $this->getExportHandler(),
687  $status_repo = $this->getStatusRepository([32 => 12332]),
689  $this->getSearchFactory(32, 45),
690  new NullLOMRepository(),
691  $this->getXMLWriter(),
692  $this->getNullLogger()
693  );
694 
695  $result = $harvester->run($this->getCronResultWrapper());
696 
697  $this->assertSame(\ILIAS\Cron\Job\JobResult::STATUS_NO_ACTION, $result->exposed_status);
698  $this->assertSame(
699  'Deleted 0 deprecated references.<br>' .
700  'Created 0 new references.<br>' .
701  'Created, updated, or deleted 0 exposed records.',
702  $result->exposed_message
703  );
704  $this->assertEmpty($status_repo->exposed_creations);
705  $this->assertEmpty($object_handler->exposed_ref_creations);
706  $this->assertEmpty($export_handler->exposed_created_exports_obj_ids);
707  }
708 
710  {
711  $harvester = new Harvester(
712  $this->getSettings(['type', 'second type'], [12, 5], 123, 456),
713  $object_handler = $this->getObjectHandler([], 0, [], null, 45),
714  $export_handler = $this->getExportHandler(),
715  $status_repo = $this->getStatusRepository(),
717  $this->getSearchFactory(32, 45, 67),
718  new NullLOMRepository(),
719  $this->getXMLWriter(),
720  $this->getNullLogger()
721  );
722 
723  $result = $harvester->run($this->getCronResultWrapper());
724 
725  $this->assertSame(\ILIAS\Cron\Job\JobResult::STATUS_OK, $result->exposed_status);
726  $this->assertSame(
727  'Deleted 0 deprecated references.<br>' .
728  'Created 2 new references.<br>' .
729  'Created, updated, or deleted 0 exposed records.',
730  $result->exposed_message
731  );
732  $this->assertSame(
733  [
734  ['obj_id' => 32, 'href_id' => 12332],
735  ['obj_id' => 67, 'href_id' => 12367]
736  ],
737  $status_repo->exposed_creations
738  );
739  $this->assertSame(
740  [
741  ['obj_id' => 32, 'container_ref_id' => 123, 'new_ref_id' => 12332],
742  ['obj_id' => 67, 'container_ref_id' => 123, 'new_ref_id' => 12367]
743  ],
744  $object_handler->exposed_ref_creations
745  );
746  $this->assertSame([32, 67], $export_handler->exposed_created_exports_obj_ids);
747  }
748 
750  {
751  $harvester = new Harvester(
752  $this->getSettings(['type', 'second type'], [12, 5], 123, 456),
753  $object_handler = $this->getObjectHandler(),
754  $export_handler = $this->getExportHandler(null, 45),
755  $status_repo = $this->getStatusRepository([32 => 12332]),
757  $search_factory = $this->getSearchFactory(32, 45),
758  new NullLOMRepository(),
759  $this->getXMLWriter(),
760  $this->getNullLogger()
761  );
762 
763  $result = $harvester->run($this->getCronResultWrapper());
764 
765  $this->assertSame(\ILIAS\Cron\Job\JobResult::STATUS_OK, $result->exposed_status);
766  $this->assertSame(
767  'Deleted 0 deprecated references.<br>' .
768  'Created 1 new references.<br>' .
769  'Created, updated, or deleted 0 exposed records.',
770  $result->exposed_message
771  );
772  $this->assertSame(
773  [[
774  'restricted' => true,
775  'types' => ['type', 'second type'],
776  'entries' => [12, 5]
777  ]],
778  $search_factory->exposed_search_params
779  );
780  $this->assertSame(
781  [['obj_id' => 45, 'href_id' => 12345]],
782  $status_repo->exposed_creations
783  );
784  $this->assertSame(
785  [['obj_id' => 45, 'container_ref_id' => 123, 'new_ref_id' => 12345]],
786  $object_handler->exposed_ref_creations
787  );
788  $this->assertEmpty($export_handler->exposed_created_exports_obj_ids);
789  }
790 
792  {
793  $harvester = new Harvester(
794  $this->getSettings(['type', 'second type'], [12, 5], 123, 456),
795  $object_handler = $this->getObjectHandler(),
796  $export_handler = $this->getExportHandler(45),
797  $status_repo = $this->getStatusRepository(),
799  $this->getSearchFactory(32, 45, 67),
800  new NullLOMRepository(),
801  $this->getXMLWriter(),
802  $this->getNullLogger()
803  );
804 
805  $result = $harvester->run($this->getCronResultWrapper());
806 
807  $this->assertSame(\ILIAS\Cron\Job\JobResult::STATUS_OK, $result->exposed_status);
808  $this->assertSame(
809  'Deleted 0 deprecated references.<br>' .
810  'Created 3 new references.<br>' .
811  'Created, updated, or deleted 0 exposed records.',
812  $result->exposed_message
813  );
814  $this->assertSame(
815  [
816  ['obj_id' => 32, 'href_id' => 12332],
817  ['obj_id' => 45, 'href_id' => 12345],
818  ['obj_id' => 67, 'href_id' => 12367]
819  ],
820  $status_repo->exposed_creations
821  );
822  $this->assertSame(
823  [
824  ['obj_id' => 32, 'container_ref_id' => 123, 'new_ref_id' => 12332],
825  ['obj_id' => 45, 'container_ref_id' => 123, 'new_ref_id' => 12345],
826  ['obj_id' => 67, 'container_ref_id' => 123, 'new_ref_id' => 12367]
827  ],
828  $object_handler->exposed_ref_creations
829  );
830  $this->assertSame([32, 67], $export_handler->exposed_created_exports_obj_ids);
831  }
832 
834  {
835  $harvester = new Harvester(
836  $this->getSettings(['type', 'second type'], [12, 5], 123, 456),
837  $this->getObjectHandler([], 456, [32, 45]),
838  $this->getExportHandler(),
839  $this->getStatusRepository([32 => 12332]),
840  $record_repo = $this->getExposedRecordRepository([32 => '<el>32</el>', 45 => '<el>45</el>']),
841  $search_factory = $this->getSearchFactory(32),
842  new NullLOMRepository(),
843  $this->getXMLWriter([32 => '<el>32</el>', 45 => '<el>45</el>']),
844  $this->getNullLogger()
845  );
846 
847  $result = $harvester->run($this->getCronResultWrapper());
848 
849  $this->assertSame(\ILIAS\Cron\Job\JobResult::STATUS_OK, $result->exposed_status);
850  $this->assertSame(
851  'Deleted 0 deprecated references.<br>' .
852  'Created 0 new references.<br>' .
853  'Created, updated, or deleted 1 exposed records.',
854  $result->exposed_message
855  );
856  $this->assertSame(
857  [[
858  'restricted' => true,
859  'types' => ['type', 'second type'],
860  'entries' => [12, 5]
861  ]],
862  $search_factory->exposed_search_params
863  );
864  $this->assertEmpty($record_repo->exposed_creations);
865  $this->assertEmpty($record_repo->exposed_updates);
866  $this->assertSame(
867  [['obj_id' => 45]],
868  $record_repo->exposed_deletions
869  );
870  }
871 
872  public function testRunDeleteExposedRecordBlocked(): void
873  {
874  $harvester = new Harvester(
875  $this->getSettings(['type', 'second type'], [12, 5], 123, 456),
876  $this->getObjectHandler([], 456, [32, 45]),
877  $this->getExportHandler(),
878  $this->getStatusRepository([32 => 12332], [45]),
879  $record_repo = $this->getExposedRecordRepository([32 => '<el>32</el>', 45 => '<el>45</el>']),
880  $this->getSearchFactory(32, 45),
881  new NullLOMRepository(),
882  $this->getXMLWriter([32 => '<el>32</el>', 45 => '<el>45</el>']),
883  $this->getNullLogger()
884  );
885 
886  $result = $harvester->run($this->getCronResultWrapper());
887 
888  $this->assertSame(\ILIAS\Cron\Job\JobResult::STATUS_OK, $result->exposed_status);
889  $this->assertSame(
890  'Deleted 0 deprecated references.<br>' .
891  'Created 0 new references.<br>' .
892  'Created, updated, or deleted 1 exposed records.',
893  $result->exposed_message
894  );
895  $this->assertEmpty($record_repo->exposed_creations);
896  $this->assertEmpty($record_repo->exposed_updates);
897  $this->assertSame(
898  [['obj_id' => 45]],
899  $record_repo->exposed_deletions
900  );
901  }
902 
904  {
905  $harvester = new Harvester(
906  $this->getSettings(['type', 'second type'], [12, 5], 123, 456),
907  $this->getObjectHandler([45], 456, [32, 45]),
908  $this->getExportHandler(),
909  $this->getStatusRepository([32 => 12332]),
910  $record_repo = $this->getExposedRecordRepository([32 => '<el>32</el>', 45 => '<el>45</el>']),
911  $this->getSearchFactory(32, 45),
912  new NullLOMRepository(),
913  $this->getXMLWriter([32 => '<el>32</el>', 45 => '<el>45</el>']),
914  $this->getNullLogger()
915  );
916 
917  $result = $harvester->run($this->getCronResultWrapper());
918 
919  $this->assertSame(\ILIAS\Cron\Job\JobResult::STATUS_OK, $result->exposed_status);
920  $this->assertSame(
921  'Deleted 0 deprecated references.<br>' .
922  'Created 0 new references.<br>' .
923  'Created, updated, or deleted 1 exposed records.',
924  $result->exposed_message
925  );
926  $this->assertEmpty($record_repo->exposed_creations);
927  $this->assertEmpty($record_repo->exposed_updates);
928  $this->assertSame(
929  [['obj_id' => 45]],
930  $record_repo->exposed_deletions
931  );
932  }
933 
935  {
936  $harvester = new Harvester(
937  $this->getSettings(['type', 'second type'], [12, 5], 123, 456),
938  $this->getObjectHandler([], 456, [32]),
939  $this->getExportHandler(),
940  $this->getStatusRepository([32 => 12332, 45 => 12345]),
941  $record_repo = $this->getExposedRecordRepository([32 => '<el>32</el>', 45 => '<el>45</el>']),
942  $this->getSearchFactory(32, 45),
943  new NullLOMRepository(),
944  $this->getXMLWriter([32 => '<el>32</el>', 45 => '<el>45</el>']),
945  $this->getNullLogger()
946  );
947 
948  $result = $harvester->run($this->getCronResultWrapper());
949 
950  $this->assertSame(\ILIAS\Cron\Job\JobResult::STATUS_OK, $result->exposed_status);
951  $this->assertSame(
952  'Deleted 0 deprecated references.<br>' .
953  'Created 0 new references.<br>' .
954  'Created, updated, or deleted 1 exposed records.',
955  $result->exposed_message
956  );
957  $this->assertEmpty($record_repo->exposed_creations);
958  $this->assertEmpty($record_repo->exposed_updates);
959  $this->assertSame(
960  [['obj_id' => 45]],
961  $record_repo->exposed_deletions
962  );
963  }
964 
965  public function testRunUpdateExposedRecord(): void
966  {
967  $harvester = new Harvester(
968  $this->getSettings(['type', 'second type'], [12, 5], 123, 456),
969  $this->getObjectHandler([], 456, [32, 45]),
970  $this->getExportHandler(),
971  $this->getStatusRepository([32 => 12332, 45 => 12345]),
972  $record_repo = $this->getExposedRecordRepository([32 => '<el>32</el>', 45 => '<el>45</el>']),
973  $this->getSearchFactory(32, 45),
974  new NullLOMRepository(),
975  $writer = $this->getXMLWriter([32 => '<el>32</el>', 45 => '<el>45 changed</el>']),
976  $this->getNullLogger()
977  );
978 
979  $result = $harvester->run($this->getCronResultWrapper());
980 
981  $this->assertSame(\ILIAS\Cron\Job\JobResult::STATUS_OK, $result->exposed_status);
982  $this->assertSame(
983  'Deleted 0 deprecated references.<br>' .
984  'Created 0 new references.<br>' .
985  'Created, updated, or deleted 1 exposed records.',
986  $result->exposed_message
987  );
988  $this->assertEmpty($record_repo->exposed_creations);
989  $this->assertCount(1, $record_repo->exposed_updates);
990  $this->assertSame(45, $record_repo->exposed_updates[0]['obj_id']);
991  $this->assertXmlStringEqualsXmlString(
992  '<el>45 changed</el>',
993  $record_repo->exposed_updates[0]['metadata']
994  );
995  $this->assertEmpty($record_repo->exposed_deletions);
996  $this->assertEquals(
997  [
998  ['obj_id' => 32, 'ref_id' => 45632, 'type' => 'type_45632'],
999  ['obj_id' => 45, 'ref_id' => 45645, 'type' => 'type_45645']
1000  ],
1001  $writer->exposed_params
1002  );
1003  }
1004 
1005  public function testRunCreateNewExposedRecord(): void
1006  {
1007  $harvester = new Harvester(
1008  $this->getSettings(['type', 'second type'], [12, 5], 123, 456),
1009  $this->getObjectHandler([], 456, [32, 45]),
1010  $this->getExportHandler(),
1011  $this->getStatusRepository([32 => 12332, 45 => 12345]),
1012  $record_repo = $this->getExposedRecordRepository([32 => '<el>32</el>']),
1013  $this->getSearchFactory(32, 45),
1014  new NullLOMRepository(),
1015  $writer = $this->getXMLWriter([32 => '<el>32</el>', 45 => '<el>45 new</el>']),
1016  $this->getNullLogger()
1017  );
1018 
1019  $result = $harvester->run($this->getCronResultWrapper());
1020 
1021  $this->assertSame(\ILIAS\Cron\Job\JobResult::STATUS_OK, $result->exposed_status);
1022  $this->assertSame(
1023  'Deleted 0 deprecated references.<br>' .
1024  'Created 0 new references.<br>' .
1025  'Created, updated, or deleted 1 exposed records.',
1026  $result->exposed_message
1027  );
1028  $this->assertEmpty($record_repo->exposed_updates);
1029  $this->assertCount(1, $record_repo->exposed_creations);
1030  $this->assertSame(45, $record_repo->exposed_creations[0]['obj_id']);
1031  $this->assertSame('il__type_45645_45', $record_repo->exposed_creations[0]['identifier']);
1032  $this->assertXmlStringEqualsXmlString(
1033  '<el>45 new</el>',
1034  $record_repo->exposed_creations[0]['metadata']
1035  );
1036  $this->assertEmpty($record_repo->exposed_deletions);
1037  $this->assertEquals(
1038  [
1039  ['obj_id' => 32, 'ref_id' => 45632, 'type' => 'type_45632'],
1040  ['obj_id' => 45, 'ref_id' => 45645, 'type' => 'type_45645']
1041  ],
1042  $writer->exposed_params
1043  );
1044  }
1045 
1047  {
1048  $harvester = new Harvester(
1049  $this->getSettings(['type', 'second type'], [12, 5], 123, 456),
1050  $this->getObjectHandler([], 456, [32, 45]),
1051  $this->getExportHandler(),
1052  $this->getStatusRepository([32 => 12332], [45]),
1053  $record_repo = $this->getExposedRecordRepository([32 => '<el>32</el>']),
1054  $this->getSearchFactory(32, 45),
1055  new NullLOMRepository(),
1056  $writer = $this->getXMLWriter([32 => '<el>32</el>', 45 => '<el>45 new</el>']),
1057  $this->getNullLogger()
1058  );
1059 
1060  $result = $harvester->run($this->getCronResultWrapper());
1061 
1062  $this->assertSame(\ILIAS\Cron\Job\JobResult::STATUS_NO_ACTION, $result->exposed_status);
1063  $this->assertSame(
1064  'Deleted 0 deprecated references.<br>' .
1065  'Created 0 new references.<br>' .
1066  'Created, updated, or deleted 0 exposed records.',
1067  $result->exposed_message
1068  );
1069  $this->assertEmpty($record_repo->exposed_updates);
1070  $this->assertEmpty($record_repo->exposed_creations);
1071  $this->assertEmpty($record_repo->exposed_deletions);
1072  }
1073 
1075  {
1076  $harvester = new Harvester(
1077  $this->getSettings(['type', 'second type'], [12, 5], 123, 456),
1078  $this->getObjectHandler([45], 456, [32, 45]),
1079  $this->getExportHandler(),
1080  $this->getStatusRepository([32 => 12332]),
1081  $record_repo = $this->getExposedRecordRepository([32 => '<el>32</el>']),
1082  $this->getSearchFactory(32, 45),
1083  new NullLOMRepository(),
1084  $writer = $this->getXMLWriter([32 => '<el>32</el>', 45 => '<el>45 new</el>']),
1085  $this->getNullLogger()
1086  );
1087 
1088  $result = $harvester->run($this->getCronResultWrapper());
1089 
1090  $this->assertSame(\ILIAS\Cron\Job\JobResult::STATUS_NO_ACTION, $result->exposed_status);
1091  $this->assertSame(
1092  'Deleted 0 deprecated references.<br>' .
1093  'Created 0 new references.<br>' .
1094  'Created, updated, or deleted 0 exposed records.',
1095  $result->exposed_message
1096  );
1097  $this->assertEmpty($record_repo->exposed_updates);
1098  $this->assertEmpty($record_repo->exposed_creations);
1099  $this->assertEmpty($record_repo->exposed_deletions);
1100  }
1101 
1103  {
1104  $harvester = new Harvester(
1105  $this->getSettings(['type', 'second type'], [12, 5], 123, 456),
1106  $this->getObjectHandler([], 456, [32]),
1107  $this->getExportHandler(),
1108  $this->getStatusRepository([32 => 12332, 45 => 12345]),
1109  $record_repo = $this->getExposedRecordRepository([32 => '<el>32</el>']),
1110  $this->getSearchFactory(32, 45),
1111  new NullLOMRepository(),
1112  $writer = $this->getXMLWriter([32 => '<el>32</el>', 45 => '<el>45 new</el>']),
1113  $this->getNullLogger()
1114  );
1115 
1116  $result = $harvester->run($this->getCronResultWrapper());
1117 
1118  $this->assertSame(\ILIAS\Cron\Job\JobResult::STATUS_NO_ACTION, $result->exposed_status);
1119  $this->assertSame(
1120  'Deleted 0 deprecated references.<br>' .
1121  'Created 0 new references.<br>' .
1122  'Created, updated, or deleted 0 exposed records.',
1123  $result->exposed_message
1124  );
1125  $this->assertEmpty($record_repo->exposed_updates);
1126  $this->assertEmpty($record_repo->exposed_creations);
1127  $this->assertEmpty($record_repo->exposed_deletions);
1128  }
1129 
1131  {
1132  $harvester = new Harvester(
1133  $this->getSettings(['type', 'second type'], [12, 5], 123, 0),
1134  $this->getObjectHandler([], 456, [32, 45]),
1135  $this->getExportHandler(),
1136  $this->getStatusRepository([32 => 12332, 45 => 12345]),
1137  $record_repo = $this->getExposedRecordRepository([32 => '<el>32</el>']),
1138  $this->getSearchFactory(32, 45),
1139  new NullLOMRepository(),
1140  $writer = $this->getXMLWriter([32 => '<el>32</el>', 45 => '<el>45 new</el>']),
1141  $this->getNullLogger()
1142  );
1143 
1144  $result = $harvester->run($this->getCronResultWrapper());
1145 
1146  $this->assertSame(\ILIAS\Cron\Job\JobResult::STATUS_NO_ACTION, $result->exposed_status);
1147  $this->assertSame(
1148  'Deleted 0 deprecated references.<br>' .
1149  'Created 0 new references.<br>' .
1150  'Created, updated, or deleted 0 exposed records.',
1151  $result->exposed_message
1152  );
1153  $this->assertEmpty($record_repo->exposed_updates);
1154  $this->assertEmpty($record_repo->exposed_creations);
1155  $this->assertEmpty($record_repo->exposed_deletions);
1156  }
1157 
1158  public function testRunWithUnforeseenError(): void
1159  {
1160  $harvester = new Harvester(
1161  $this->getSettings(['type', 'second type'], [12, 5]),
1162  $object_handler = $this->getObjectHandler(),
1163  $this->getExportHandler(),
1164  $status_repo = $this->getStatusRepository([], [], true),
1165  $this->getExposedRecordRepository(),
1166  $search_factory = $this->getSearchFactory(),
1167  new NullLOMRepository(),
1168  $this->getXMLWriter(),
1169  $this->getNullLogger()
1170  );
1171 
1172  $result = $harvester->run($this->getCronResultWrapper());
1173 
1174  $this->assertSame(\ILIAS\Cron\Job\JobResult::STATUS_FAIL, $result->exposed_status);
1175  $this->assertSame(
1176  'error',
1177  $result->exposed_message
1178  );
1179  }
1180 }
search()
description: > Example for rendring a search glyph.
Definition: search.php:41
Interface Observer Contains several chained tasks and infos about them.
factory()
getExposedRecordRepository(array $returned_records=[])
Records are passed as array via obj_id => metadata-xml as string.
while($session_entry=$r->fetchRow(ilDBConstants::FETCHMODE_ASSOC)) return null
getSearchFactory(int ... $search_result_obj_ids)
getExportHandler(?int $throw_exception_for_id=null, int ... $already_have_export_obj_ids)
$ref_id
Definition: ltiauth.php:65
getSettings(array $types=[], array $copyright_ids=[], int $harvesting_target_ref_id=0, int $exposed_source_ref_id=0)
getObjectHandler(array $deleted_obj_ids=[], int $valid_source_container=0, array $obj_ids_referenced_in_container=[], ?int $throw_error_on_deletion_ref_id=null, ?int $throw_error_on_ref_creation_obj_id=null)
Returned ref_ids are always given by concatenation of target ref_id and obj_id.
__construct()
Constructor setup ILIAS global object public.
Definition: class.ilias.php:76
$message
Definition: xapiexit.php:31
getXMLWriter(array $returned_md=[])
Metadata is passed as array via obj_id => metadata-xml as string.
getStatusRepository(array $currently_harvested=[], array $blocked_obj_ids=[], bool $throw_error=false)
Currently harvested objects are passed as obj_id => href_id.