ILIAS  trunk Revision v11.0_alpha-3011-gc6b235a2e85
HarvesterTest.php
Go to the documentation of this file.
1<?php
2
19declare(strict_types=1);
20
22
23use PHPUnit\Framework\TestCase;
33use ILIAS\MetaData\OERHarvester\ExposedRecords\NullRepository as NullExposedRecordRepository;
47use ILIAS\MetaData\Repository\NullRepository as NullLOMRepository;
48
49class 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]),
450 $this->getExposedRecordRepository(),
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]),
481 $this->getExposedRecordRepository(),
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]),
508 $this->getExposedRecordRepository(),
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]),
535 $this->getExposedRecordRepository(),
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]),
562 $this->getExposedRecordRepository(),
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]),
604 $this->getExposedRecordRepository(),
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]),
632 $this->getExposedRecordRepository(),
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]),
660 $this->getExposedRecordRepository(),
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]),
688 $this->getExposedRecordRepository(),
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(),
716 $this->getExposedRecordRepository(),
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]),
756 $this->getExposedRecordRepository(),
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(),
798 $this->getExposedRecordRepository(),
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}
factory()
getSettings(array $types=[], array $copyright_ids=[], int $harvesting_target_ref_id=0, int $exposed_source_ref_id=0)
getSearchFactory(int ... $search_result_obj_ids)
getStatusRepository(array $currently_harvested=[], array $blocked_obj_ids=[], bool $throw_error=false)
Currently harvested objects are passed as obj_id => href_id.
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.
getExportHandler(?int $throw_exception_for_id=null, int ... $already_have_export_obj_ids)
getExposedRecordRepository(array $returned_records=[])
Records are passed as array via obj_id => metadata-xml as string.
getXMLWriter(array $returned_md=[])
Metadata is passed as array via obj_id => metadata-xml as string.
__construct()
Constructor setup ILIAS global object @access public.
Definition: class.ilias.php:76
Component logger with individual log levels by component id.
return['delivery_method'=> 'php',]
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
$ref_id
Definition: ltiauth.php:66
__construct(Container $dic, ilPlugin $plugin)
@inheritDoc
Interface Observer \BackgroundTasks Contains several chained tasks and infos about them.
$message
Definition: xapiexit.php:31