diff --git a/conf/datasources.ini.sample b/conf/datasources.ini.sample index 23b43e4e4..48841338a 100644 --- a/conf/datasources.ini.sample +++ b/conf/datasources.ini.sample @@ -120,7 +120,7 @@ ; authority[] Map to authority index sources where is authority record type ; (corporateBody, person) or * for any; ; authority_id_regex[] Regex for filtering allowed authority ids -; (used when indexing authority ids and when enriching biblio records with MarcAuthEnrichment) +; (used when indexing authority ids and when enriching biblio records with AuthEnrichment) ; fullTextXPaths XPath expression denoting full text fields ; fullTextUrlXPaths XPath expression denoting fields that contain URLs to full text content (plain text only at the moment) @@ -173,7 +173,7 @@ ;driverParams[] = "idIn999=true" ;driverParams[] = "003InLinkingID=true" ;driverParams[] = "kohaNormalization=true" -;enrichments[] = MarcAuthEnrichment,final +;enrichments[] = AuthEnrichment,final ; Sample DSpace configuration ;[dspace] diff --git a/src/RecordManager/Base/Enrichment/AuthEnrichment.php b/src/RecordManager/Base/Enrichment/AuthEnrichment.php index 9b8040468..ffa639ef2 100644 --- a/src/RecordManager/Base/Enrichment/AuthEnrichment.php +++ b/src/RecordManager/Base/Enrichment/AuthEnrichment.php @@ -52,7 +52,7 @@ * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License * @link https://github.com/NatLibFi/RecordManager */ -abstract class AuthEnrichment extends AbstractEnrichment +class AuthEnrichment extends AbstractEnrichment { use \RecordManager\Base\Record\CreateRecordTrait; @@ -63,6 +63,21 @@ abstract class AuthEnrichment extends AbstractEnrichment */ protected $authorityDb; + /** + * Enrichment specifications. Key is the array in solrArray and value contains following: + * - pref, preferred field in solr + * - check, check field for existing values + * + * @var array + */ + protected array $enrichmentSpecs = [ + 'author2_id_str_mv' => [ + 'pref' => 'author_variant', + 'check' => 'author_variant', + 'includeInAllFields' => true, + ], + ]; + /** * Constructor * @@ -95,6 +110,36 @@ public function __construct( $this->authorityDb = $authorityDb; } + /** + * Enrich the record and return any additions in solrArray + * + * @param string $sourceId Source ID + * @param object $record Metadata Record + * @param array $solrArray Metadata to be sent to Solr + * + * @throws \Exception + * @return void + */ + public function enrich($sourceId, $record, &$solrArray) + { + foreach ($this->enrichmentSpecs as $key => $specs) { + if (empty($solrArray[$key])) { + continue; + } + foreach ($solrArray[$key] as $id) { + $this->enrichField( + $sourceId, + $record, + $solrArray, + $id, + $specs['pref'], + $specs['check'], + $specs['includeInAllFields'] ?? false + ); + } + } + } + /** * Enrich the record and return any additions in solrArray * diff --git a/src/RecordManager/Base/Enrichment/Ead3SkosmosEnrichment.php b/src/RecordManager/Base/Enrichment/Ead3SkosmosEnrichment.php deleted file mode 100644 index be6492794..000000000 --- a/src/RecordManager/Base/Enrichment/Ead3SkosmosEnrichment.php +++ /dev/null @@ -1,97 +0,0 @@ - - * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License - * @link https://github.com/NatLibFi/RecordManager - */ - -namespace RecordManager\Base\Enrichment; - -/** - * Ead3SkosmosEnrichment Class - * - * This is a class for enrichment of EAD3 records from a Skosmos instance. - * - * @category DataManagement - * @package RecordManager - * @author Ere Maijala - * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License - * @link https://github.com/NatLibFi/RecordManager - */ -class Ead3SkosmosEnrichment extends SkosmosEnrichment -{ - /** - * Default fields to enrich. Key is the method in driver and value is array - * - pref, preferred field in solr - * - alt, alternative field in solr - * - check, check field for existing values - * - * @var array - */ - protected $defaultFields = [ - 'getRawTopicIds' => [ - 'pref' => 'topic_add_txt_mv', - 'alt' => 'topic_alt_txt_mv', - 'check' => 'topic', - ], - 'getRawGeographicTopicIds' => [ - 'pref' => 'geographic_add_txt_mv', - 'alt' => 'geographic_alt_txt_mv', - 'check' => 'geographic', - ], - 'getCorporateAuthorIds' => [ - 'pref' => 'author_corporate', - 'alt' => 'author_variant', - 'check' => 'author_corporate', - ], - 'getAuthorIds' => [ - 'pref' => 'author', - 'alt' => 'author_variant', - 'check' => 'author', - ], - 'getSecondaryAuthorIds' => [ - 'pref' => 'author2', - 'alt' => 'author2_variant', - 'check' => 'author2', - ], - ]; - - /** - * Enrich the record and return any additions in solrArray - * - * @param string $sourceId Source ID - * @param object $record Metadata Record - * @param array $solrArray Metadata to be sent to Solr - * - * @return void - */ - public function enrich($sourceId, $record, &$solrArray) - { - if (!($record instanceof \RecordManager\Base\Record\Ead3)) { - return; - } - parent::enrich($sourceId, $record, $solrArray); - } -} diff --git a/src/RecordManager/Base/Enrichment/EadSkosmosEnrichment.php b/src/RecordManager/Base/Enrichment/EadSkosmosEnrichment.php deleted file mode 100644 index 1bf12b180..000000000 --- a/src/RecordManager/Base/Enrichment/EadSkosmosEnrichment.php +++ /dev/null @@ -1,61 +0,0 @@ - - * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License - * @link https://github.com/NatLibFi/RecordManager - */ - -namespace RecordManager\Base\Enrichment; - -/** - * EadSkosmosEnrichment Class - * - * This is a class for enrichment of EAD records from a Skosmos instance. - * - * @category DataManagement - * @package RecordManager - * @author Samuli Sillanpää - * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License - * @link https://github.com/NatLibFi/RecordManager - */ -class EadSkosmosEnrichment extends SkosmosEnrichment -{ - /** - * Enrich the record and return any additions in solrArray - * - * @param string $sourceId Source ID - * @param object $record Metadata Record - * @param array $solrArray Metadata to be sent to Solr - * - * @return void - */ - public function enrich($sourceId, $record, &$solrArray) - { - if (!($record instanceof \RecordManager\Base\Record\Ead)) { - return; - } - parent::enrich($sourceId, $record, $solrArray); - } -} diff --git a/src/RecordManager/Base/Enrichment/LidoSkosmosEnrichment.php b/src/RecordManager/Base/Enrichment/LidoSkosmosEnrichment.php deleted file mode 100644 index cfb1183ce..000000000 --- a/src/RecordManager/Base/Enrichment/LidoSkosmosEnrichment.php +++ /dev/null @@ -1,92 +0,0 @@ - - * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License - * @link https://github.com/NatLibFi/RecordManager - */ - -namespace RecordManager\Base\Enrichment; - -/** - * LidoSkosmosEnrichment Class - * - * This is a class for enrichment of LIDO records from a Skosmos instance. - * - * @category DataManagement - * @package RecordManager - * @author Ere Maijala - * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License - * @link https://github.com/NatLibFi/RecordManager - */ -class LidoSkosmosEnrichment extends SkosmosEnrichment -{ - /** - * Default fields to enrich. Key is the method in driver and value is array - * - pref, preferred field in solr - * - alt, alternative field in solr - * - check, check field for existing values - * - * @var array - */ - protected $defaultFields = [ - 'getRawTopicIds' => [ - 'pref' => 'topic_add_txt_mv', - 'alt' => 'topic_alt_txt_mv', - 'check' => 'topic', - ], - 'getRawGeographicTopicIds' => [ - 'pref' => 'geographic_add_txt_mv', - 'alt' => 'geographic_alt_txt_mv', - 'check' => 'geographic', - ], - 'getAuthorIds' => [ - 'pref' => 'author', - 'alt' => 'author_variant', - 'check' => 'author', - ], - 'getSecondaryAuthorIds' => [ - 'pref' => 'author2', - 'alt' => 'author2_variant', - 'check' => 'author2', - ], - ]; - - /** - * Enrich the record and return any additions in solrArray - * - * @param string $sourceId Source ID - * @param object $record Metadata Record - * @param array $solrArray Metadata to be sent to Solr - * - * @return void - */ - public function enrich($sourceId, $record, &$solrArray) - { - if (!($record instanceof \RecordManager\Base\Record\Lido)) { - return; - } - parent::enrich($sourceId, $record, $solrArray); - } -} diff --git a/src/RecordManager/Base/Enrichment/LrmiSkosmosEnrichment.php b/src/RecordManager/Base/Enrichment/LrmiSkosmosEnrichment.php deleted file mode 100644 index 2787f7a84..000000000 --- a/src/RecordManager/Base/Enrichment/LrmiSkosmosEnrichment.php +++ /dev/null @@ -1,63 +0,0 @@ - - * @author Samuli Sillanpää - * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License - * @link https://github.com/NatLibFi/RecordManager - */ - -namespace RecordManager\Base\Enrichment; - -/** - * LrmiSkosmosEnrichment Class - * - * This is a class for enrichment of MARC records from a Skosmos instance. - * - * @category DataManagement - * @package RecordManager - * @author Ere Maijala - * @author Samuli Sillanpää - * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License - * @link https://github.com/NatLibFi/RecordManager - */ -class LrmiSkosmosEnrichment extends SkosmosEnrichment -{ - /** - * Enrich the record and return any additions in solrArray - * - * @param string $sourceId Source ID - * @param object $record Metadata Record - * @param array $solrArray Metadata to be sent to Solr - * - * @return void - */ - public function enrich($sourceId, $record, &$solrArray) - { - if (!($record instanceof \RecordManager\Base\Record\Lrmi)) { - return; - } - parent::enrich($sourceId, $record, $solrArray); - } -} diff --git a/src/RecordManager/Base/Enrichment/MarcAuthEnrichment.php b/src/RecordManager/Base/Enrichment/MarcAuthEnrichment.php deleted file mode 100644 index e32c79caa..000000000 --- a/src/RecordManager/Base/Enrichment/MarcAuthEnrichment.php +++ /dev/null @@ -1,71 +0,0 @@ - - * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License - * @link https://github.com/NatLibFi/RecordManager - */ - -namespace RecordManager\Base\Enrichment; - -/** - * Enrich Marc biblio records with authority record data. - * - * @category DataManagement - * @package RecordManager - * @author Samuli Sillanpää - * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License - * @link https://github.com/NatLibFi/RecordManager - */ -class MarcAuthEnrichment extends AuthEnrichment -{ - /** - * Enrich the record and return any additions in solrArray - * - * @param string $sourceId Source ID - * @param object $record Metadata Record - * @param array $solrArray Metadata to be sent to Solr - * - * @throws \Exception - * @return void - */ - public function enrich($sourceId, $record, &$solrArray) - { - if (!($record instanceof \RecordManager\Base\Record\Marc)) { - return; - } - - foreach ($solrArray['author2_id_str_mv'] ?? [] as $id) { - $this->enrichField( - $sourceId, - $record, - $solrArray, - $id, - 'author_variant', - 'author_variant', - true - ); - } - } -} diff --git a/src/RecordManager/Base/Enrichment/MarcAuthSkosmosEnrichment.php b/src/RecordManager/Base/Enrichment/MarcAuthSkosmosEnrichment.php deleted file mode 100644 index 09fd512cc..000000000 --- a/src/RecordManager/Base/Enrichment/MarcAuthSkosmosEnrichment.php +++ /dev/null @@ -1,71 +0,0 @@ - - * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License - * @link https://github.com/NatLibFi/RecordManager - */ - -namespace RecordManager\Base\Enrichment; - -/** - * Enrich Marc authority records with data from a Skosmos instance. - * - * @category DataManagement - * @package RecordManager - * @author Samuli Sillanpää - * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License - * @link https://github.com/NatLibFi/RecordManager - */ -class MarcAuthSkosmosEnrichment extends SkosmosEnrichment -{ - /** - * Enrich the record and return any additions in solrArray - * - * @param string $sourceId Source ID - * @param object $record Metadata Record - * @param array $solrArray Metadata to be sent to Solr - * - * @throws \Exception - * @return void - */ - public function enrich($sourceId, $record, &$solrArray) - { - if (!($record instanceof \RecordManager\Base\Record\MarcAuthority)) { - return; - } - foreach ($record->getOccupationIds() as $id) { - $this->enrichField( - $sourceId, - $record, - $solrArray, - $id, - 'occupation_str_mv', - '', - '', - true - ); - } - } -} diff --git a/src/RecordManager/Base/Enrichment/MarcSkosmosEnrichment.php b/src/RecordManager/Base/Enrichment/MarcSkosmosEnrichment.php deleted file mode 100644 index 4f7d8357d..000000000 --- a/src/RecordManager/Base/Enrichment/MarcSkosmosEnrichment.php +++ /dev/null @@ -1,63 +0,0 @@ - - * @author Samuli Sillanpää - * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License - * @link https://github.com/NatLibFi/RecordManager - */ - -namespace RecordManager\Base\Enrichment; - -/** - * MarcSkosmosEnrichment Class - * - * This is a class for enrichment of MARC records from a Skosmos instance. - * - * @category DataManagement - * @package RecordManager - * @author Ere Maijala - * @author Samuli Sillanpää - * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License - * @link https://github.com/NatLibFi/RecordManager - */ -class MarcSkosmosEnrichment extends SkosmosEnrichment -{ - /** - * Enrich the record and return any additions in solrArray - * - * @param string $sourceId Source ID - * @param object $record Metadata Record - * @param array $solrArray Metadata to be sent to Solr - * - * @return void - */ - public function enrich($sourceId, $record, &$solrArray) - { - if (!($record instanceof \RecordManager\Base\Record\Marc)) { - return; - } - parent::enrich($sourceId, $record, $solrArray); - } -} diff --git a/src/RecordManager/Base/Enrichment/SkosmosEnrichment.php b/src/RecordManager/Base/Enrichment/SkosmosEnrichment.php index a61c60a64..bcdbc235d 100644 --- a/src/RecordManager/Base/Enrichment/SkosmosEnrichment.php +++ b/src/RecordManager/Base/Enrichment/SkosmosEnrichment.php @@ -5,7 +5,7 @@ * * PHP version 8 * - * Copyright (C) The National Library of Finland 2014-2023. + * Copyright (C) The National Library of Finland 2014-2025. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2, @@ -24,6 +24,7 @@ * @package RecordManager * @author Ere Maijala * @author Samuli Sillanpää + * @author Juha Luoma * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License * @link https://github.com/NatLibFi/RecordManager */ @@ -48,6 +49,7 @@ * @package RecordManager * @author Ere Maijala * @author Samuli Sillanpää + * @author Juha Luoma * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License * @link https://github.com/NatLibFi/RecordManager */ @@ -72,14 +74,14 @@ class SkosmosEnrichment extends AbstractEnrichment * * @var string */ - protected $apiBaseURL; + protected string $apiBaseURL; /** * List of allowed URL prefixes to try to fetch * * @var array */ - protected $urlPrefixAllowedList; + protected array $urlPrefixAllowedList; /** * List of URI prefixes for which to process other vocabularies with @@ -87,52 +89,52 @@ class SkosmosEnrichment extends AbstractEnrichment * * @var array */ - protected $uriPrefixExactMatches; + protected array $uriPrefixExactMatches; /** * Solr field to use for the location data * * @var string */ - protected $solrLocationField = ''; + protected string $solrLocationField = ''; /** * Solr field to use for the center coordinates of locations * * @var string */ - protected $solrCenterField = ''; + protected string $solrCenterField = ''; /** * Languages to allow * * @var array */ - protected $languages = []; + protected array $languages = []; /** * Cache for recent records * * @var ?\cash\LRUCache */ - protected $recordCache = null; + protected ?\cash\LRUCache $recordCache = null; /** * Cache for recent enrichment results * * @var ?\cash\LRUCache */ - protected $enrichmentCache = null; + protected ?\cash\LRUCache $enrichmentCache = null; /** - * Default fields to enrich. Key is the method in driver and value is array + * Enrichment specifications. Key is the method in driver and value is array * - pref, preferred field in solr * - alt, alternative field in solr * - check, check field for existing values * * @var array */ - protected $defaultFields = [ + protected array $enrichmentSpecs = [ 'getRawTopicIds' => [ 'pref' => 'topic_add_txt_mv', 'alt' => 'topic_alt_txt_mv', @@ -143,6 +145,27 @@ class SkosmosEnrichment extends AbstractEnrichment 'alt' => 'geographic_alt_txt_mv', 'check' => 'geographic', ], + 'getCorporateAuthorIds' => [ + 'pref' => 'author_corporate', + 'alt' => 'author_variant', + 'check' => 'author_corporate', + ], + 'getAuthorIds' => [ + 'pref' => 'author', + 'alt' => 'author_variant', + 'check' => 'author', + ], + 'getSecondaryAuthorIds' => [ + 'pref' => 'author2', + 'alt' => 'author2_variant', + 'check' => 'author2', + ], + 'getOccupationIds' => [ + 'pref' => 'occupation_str_mv', + 'alt' => '', + 'check' => '', + 'includeInAllFields' => true, + ], ]; /** @@ -153,7 +176,7 @@ class SkosmosEnrichment extends AbstractEnrichment * * @var array */ - protected $excludedLocationMatches = []; + protected array $excludedLocationMatches = []; /** * Initialize settings @@ -196,7 +219,6 @@ public function init() if ($cacheSize = $settings['enrichment_cache_size'] ?? 10000) { $this->enrichmentCache = new \cash\LRUCache((int)$cacheSize); } - foreach ((array)($settings['excluded_location_matches'] ?? []) as $type => $file) { $listFile = RECMAN_BASE_PATH . "/conf/$file"; $ids = file($listFile, FILE_IGNORE_NEW_LINES); @@ -210,7 +232,7 @@ public function init() } /** - * Enrich the record and return any additions in solrArray + * Enrich the record and save any additions in solrArray * * @param string $sourceId Source ID * @param object $record Metadata Record @@ -219,9 +241,9 @@ public function init() * @throws \Exception * @return void */ - public function enrich($sourceId, $record, &$solrArray) + public function enrich($sourceId, $record, &$solrArray): void { - foreach ($this->defaultFields as $method => $spec) { + foreach ($this->enrichmentSpecs as $method => $spec) { if (!is_callable([$record, $method])) { continue; } @@ -233,7 +255,8 @@ public function enrich($sourceId, $record, &$solrArray) $id, $spec['pref'], $spec['alt'], - $spec['check'] + $spec['check'], + $spec['includeInAllFields'] ?? false ); } } @@ -407,7 +430,6 @@ protected function getEnrichmentData(string $id, string $recordId): array if (!$this->isConceptNode($node)) { continue; } - if ($node->getId() === $id) { if ($locs = $this->processLocationWgs84($node, $recordId)) { $result['locations'] = [ diff --git a/src/RecordManager/Base/Solr/SolrUpdater.php b/src/RecordManager/Base/Solr/SolrUpdater.php index 064ae3ee8..81c53b005 100644 --- a/src/RecordManager/Base/Solr/SolrUpdater.php +++ b/src/RecordManager/Base/Solr/SolrUpdater.php @@ -3136,23 +3136,34 @@ protected function enrich($source, $settings, $record, &$data, $stage = '') /** @psalm-var list $dsEnrichments */ $dsEnrichments = (array)($settings['enrichments'] ?? []); $enrichments = array_unique( - [ - ...$globalEnrichments, - ...$dsEnrichments, - ] + array_map( + function ($enrichment) use ($stage) { + $exploded = explode(',', $enrichment, 2); + $name = $exploded[0]; + $stage = $exploded[1] ?? ''; + return compact('name', 'stage'); + }, + [ + ...$globalEnrichments, + ...$dsEnrichments, + ] + ), + SORT_REGULAR ); - foreach ($enrichments as $enrichmentSettings) { - $parts = explode(',', $enrichmentSettings); - $enrichment = $parts[0]; - $enrichmentStage = $parts[1] ?? ''; - if ($stage !== $enrichmentStage) { + foreach ($enrichments as $enrichment) { + if ($stage !== $enrichment['stage']) { + continue; + } + $enrichmentName = $enrichment['name']; + if (!$this->enrichmentPluginManager->has($enrichmentName)) { continue; } - if (!isset($this->enrichments[$enrichment])) { - $this->enrichments[$enrichment] - = $this->enrichmentPluginManager->get($enrichment); + $enrichmentService = $this->enrichmentPluginManager->get($enrichmentName); + $enrichmentServiceName = $enrichmentService::class; + if (!isset($this->enrichments[$enrichmentServiceName])) { + $this->enrichments[$enrichmentServiceName] = $enrichmentService; } - $this->enrichments[$enrichment]->enrich($source, $record, $data); + $this->enrichments[$enrichmentServiceName]->enrich($source, $record, $data); } } diff --git a/src/RecordManager/Base/config/module.config.php b/src/RecordManager/Base/config/module.config.php index 1cc04b092..e2d1daddf 100644 --- a/src/RecordManager/Base/config/module.config.php +++ b/src/RecordManager/Base/config/module.config.php @@ -70,37 +70,32 @@ 'enrichment' => [ 'factories' => [ \RecordManager\Base\Enrichment\AuthEnrichment::class => \RecordManager\Base\Enrichment\AuthEnrichmentFactory::class, - \RecordManager\Base\Enrichment\EadSkosmosEnrichment::class => \RecordManager\Base\Enrichment\AbstractEnrichmentFactory::class, - \RecordManager\Base\Enrichment\Ead3SkosmosEnrichment::class => \RecordManager\Base\Enrichment\AbstractEnrichmentFactory::class, - \RecordManager\Base\Enrichment\LidoSkosmosEnrichment::class => \RecordManager\Base\Enrichment\AbstractEnrichmentFactory::class, - \RecordManager\Base\Enrichment\LrmiSkosmosEnrichment::class => \RecordManager\Base\Enrichment\AbstractEnrichmentFactory::class, - \RecordManager\Base\Enrichment\MarcAuthEnrichment::class => \RecordManager\Base\Enrichment\AuthEnrichmentFactory::class, - \RecordManager\Base\Enrichment\MarcAuthSkosmosEnrichment::class => \RecordManager\Base\Enrichment\AbstractEnrichmentFactory::class, - \RecordManager\Base\Enrichment\MarcSkosmosEnrichment::class => \RecordManager\Base\Enrichment\AbstractEnrichmentFactory::class, \RecordManager\Base\Enrichment\MusicBrainzEnrichment::class => \RecordManager\Base\Enrichment\AbstractEnrichmentFactory::class, \RecordManager\Base\Enrichment\NominatimGeocoder::class => \RecordManager\Base\Enrichment\AbstractEnrichmentFactory::class, \RecordManager\Base\Enrichment\SkosmosEnrichment::class => \RecordManager\Base\Enrichment\AbstractEnrichmentFactory::class, ], 'aliases' => [ 'AuthEnrichment' => \RecordManager\Base\Enrichment\AuthEnrichment::class, - 'EadSkosmosEnrichment' => \RecordManager\Base\Enrichment\EadSkosmosEnrichment::class, - 'Ead3SkosmosEnrichment' => \RecordManager\Base\Enrichment\Ead3SkosmosEnrichment::class, - 'LidoSkosmosEnrichment' => \RecordManager\Base\Enrichment\LidoSkosmosEnrichment::class, - 'LrmiSkosmosEnrichment' => \RecordManager\Base\Enrichment\LrmiSkosmosEnrichment::class, - 'MarcAuthEnrichment' => \RecordManager\Base\Enrichment\MarcAuthEnrichment::class, - 'MarcAuthSkosmosEnrichment' => \RecordManager\Base\Enrichment\MarcAuthSkosmosEnrichment::class, - 'MarcSkosmosEnrichment' => \RecordManager\Base\Enrichment\MarcSkosmosEnrichment::class, 'MusicBrainzEnrichment' => \RecordManager\Base\Enrichment\MusicBrainzEnrichment::class, 'NominatimGeocoder' => \RecordManager\Base\Enrichment\NominatimGeocoder::class, 'SkosmosEnrichment' => \RecordManager\Base\Enrichment\SkosmosEnrichment::class, - 'EadOnkiLightEnrichment' => 'EadSkosmosEnrichment', - 'Ead3OnkiLightEnrichment' => 'Ead3SkosmosEnrichment', - 'LidoOnkiLightEnrichment' => 'LidoSkosmosEnrichment', - 'LrmiOnkiLightEnrichment' => 'LrmiSkosmosEnrichment', - 'MarcAuthOnkiLightEnrichment' => 'MarcAuthSkosmosEnrichment', - 'MarcOnkiLightEnrichment' => 'MarcSkosmosEnrichment', - 'OnkiLightEnrichment' => 'SkosmosEnrichment', + // Legacy aliases: + 'EadOnkiLightEnrichment' => \RecordManager\Base\Enrichment\SkosmosEnrichment::class, + 'Ead3OnkiLightEnrichment' => \RecordManager\Base\Enrichment\SkosmosEnrichment::class, + 'LidoOnkiLightEnrichment' => \RecordManager\Base\Enrichment\SkosmosEnrichment::class, + 'LrmiOnkiLightEnrichment' => \RecordManager\Base\Enrichment\SkosmosEnrichment::class, + 'MarcAuthOnkiLightEnrichment' => \RecordManager\Base\Enrichment\SkosmosEnrichment::class, + 'MarcOnkiLightEnrichment' => \RecordManager\Base\Enrichment\SkosmosEnrichment::class, + 'OnkiLightEnrichment' => \RecordManager\Base\Enrichment\SkosmosEnrichment::class, + 'EadSkosmosEnrichment' => \RecordManager\Base\Enrichment\SkosmosEnrichment::class, + 'Ead3SkosmosEnrichment' => \RecordManager\Base\Enrichment\SkosmosEnrichment::class, + 'LidoSkosmosEnrichment' => \RecordManager\Base\Enrichment\SkosmosEnrichment::class, + 'LrmiSkosmosEnrichment' => \RecordManager\Base\Enrichment\SkosmosEnrichment::class, + 'MarcAuthSkosmosEnrichment' => \RecordManager\Base\Enrichment\SkosmosEnrichment::class, + 'MarcSkosmosEnrichment' => \RecordManager\Base\Enrichment\SkosmosEnrichment::class, + + 'MarcAuthEnrichment' => \RecordManager\Base\Enrichment\AuthEnrichment::class, ], ], 'harvest' => [ diff --git a/tests/RecordManagerTest/Base/Enrichment/AuthEnrichmentTest.php b/tests/RecordManagerTest/Base/Enrichment/AuthEnrichmentTest.php new file mode 100644 index 000000000..fe1ebc2ac --- /dev/null +++ b/tests/RecordManagerTest/Base/Enrichment/AuthEnrichmentTest.php @@ -0,0 +1,206 @@ + + * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License + * @link https://github.com/NatLibFi/RecordManager + */ + +namespace RecordManagerTest\Base\Enrichment; + +use Generator; +use RecordManager\Base\Enrichment\AuthEnrichment; +use RecordManager\Base\Http\HttpService; +use RecordManager\Base\Record\Marc; +use RecordManager\Base\Record\PluginManager; +use RecordManager\Base\Utils\Logger; +use RecordManager\Base\Utils\MetadataUtils; +use RecordManagerTest\Base\Record\RecordTestBase; + +/** + * Auth enrichment test class + * + * @category DataManagement + * @package RecordManager + * @author Juha Luoma + * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License + * @link https://github.com/NatLibFi/RecordManager + */ +class AuthEnrichmentTest extends RecordTestBase +{ + /** + * Data provider for testing Auth enrichment + * + * @return Generator + */ + public static function getAuthEnrichmentData(): Generator + { + yield 'basic author enrichment' => [ + 'fixture' => 'marc_auth_1.xml', + 'authorityRecords' => [ + '(FIN11)authority_001' => 'marc_authority_1.xml', + ], + 'config' => [], + 'authorIds' => ['(FIN11)authority_001'], + 'expected' => [ + 'author_variant' => ['p a pa', 'Alternative Name 1', 'Alternative Name 2'], + ], + ]; + yield 'no author IDs' => [ + 'fixture' => 'marc_auth_no_ids.xml', + 'authorityRecords' => [], + 'config' => [], + 'authorIds' => [], + 'expected' => [ + 'author2' => ['Second Author Without ID'], + ], + ]; + yield 'missing authority record' => [ + 'fixture' => 'marc_auth_missing_authority.xml', + 'authorityRecords' => [], + 'config' => [], + 'authorIds' => ['(FIN11)nonexistent_authority', '(FIN11)another_missing'], + 'expected' => [ + 'author2' => ['Secondary Author With Missing Authority'], + ], + ]; + } + + /** + * Test Auth enrichment + * + * @param string $fixture Fixture filename + * @param array $authorityRecords Authority record fixtures (id => filename) + * @param array $config Custom config + * @param array $authorIds Author IDs to add to author2_id_str_mv + * @param array $expected Expected results + * + * @return void + */ + #[\PHPUnit\Framework\Attributes\DataProvider('getAuthEnrichmentData')] + public function testAuthEnrichment( + string $fixture, + array $authorityRecords, + array $config, + array $authorIds, + array $expected + ): void { + $record = $this->createMarcRecord(Marc::class, $fixture, []); + $record->normalize(); + $fields = $record->toSolrArray(); + + // Add author IDs to the solr array (simulating what would be there in production) + if (!empty($authorIds)) { + $fields['author2_id_str_mv'] = $authorIds; + } + + $enricher = $this->getAuthEnricher($authorityRecords, $config); + $enricher->enrich('test', $record, $fields); + + foreach ($expected as $key => $value) { + $this->assertEquals($value, $fields[$key] ?? null, "Field '$key' did not match expected value."); + } + } + + /** + * Get an Auth enrichment object + * + * @param array $authorityRecords Authority record fixtures + * @param array $config Main config + * + * @return AuthEnrichment + */ + protected function getAuthEnricher(array $authorityRecords, array $config = []): AuthEnrichment + { + if (empty($config)) { + $config = [ + 'AuthEnrichment' => [ + 'enabled' => true, + ], + ]; + } + + $db = $this->createMock(\RecordManager\Base\Database\DatabaseInterface::class); + $authorityDb = $this->createMock(\RecordManager\Base\Database\DatabaseInterface::class); + + // Mock authority database records + $authorityDbRecords = []; + foreach ($authorityRecords as $id => $filename) { + $authorityRecord = $this->createMarcRecord( + \RecordManager\Base\Record\MarcAuthority::class, + $filename, + [] + ); + $authorityDbRecords[$id] = [ + '_id' => $id, + 'source_id' => 'test', + 'oai_id' => $id, + 'deleted' => false, + 'format' => 'marc', + 'original_data' => $authorityRecord->serialize(), + 'normalized_data' => $authorityRecord->serialize(), + ]; + } + + $authorityDb->expects($this->any()) + ->method('getRecord') + ->willReturnCallback(function ($id) use ($authorityDbRecords) { + return $authorityDbRecords[$id] ?? null; + }); + + $metadataUtils = $this->getMockBuilder(MetadataUtils::class) + ->onlyMethods([]) + ->disableOriginalConstructor() + ->getMock(); + + $recordPluginManager = $this->createMock(PluginManager::class); + $recordPluginManager->expects($this->any()) + ->method('get') + ->willReturnCallback(function ($format) { + if ($format === 'marc') { + return $this->createMarcRecord( + \RecordManager\Base\Record\MarcAuthority::class, + 'marc_authority_1.xml', // Dummy, will be replaced + [] + ); + } + return null; + }); + + $enricher = $this->getMockBuilder(AuthEnrichment::class) + ->onlyMethods([]) + ->setConstructorArgs([ + $config, + $db, + $this->createMock(Logger::class), + $recordPluginManager, + $this->createMock(HttpService::class), + $metadataUtils, + $authorityDb, + ]) + ->getMock(); + + return $enricher; + } +} diff --git a/tests/RecordManagerTest/Base/Enrichment/PluginManagerTest.php b/tests/RecordManagerTest/Base/Enrichment/PluginManagerTest.php new file mode 100644 index 000000000..e0c851406 --- /dev/null +++ b/tests/RecordManagerTest/Base/Enrichment/PluginManagerTest.php @@ -0,0 +1,106 @@ + + * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License + * @link https://github.com/NatLibFi/RecordManager + */ + +namespace RecordManagerTest\Base\Enrichment; + +use Psr\Container\ContainerInterface; + +/** + * Tests for enrichment plugin manager + * + * @category DataManagement + * @package RecordManager + * @author Juha Luoma + * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License + * @link https://github.com/NatLibFi/RecordManager + */ +class PluginManagerTest extends \PHPUnit\Framework\TestCase +{ + protected array $moduleConfig = []; + + /** + * Standard setup method. + * + * @return void + */ + public function setUp(): void + { + $this->moduleConfig + = include realpath('./') . '/src/RecordManager/Base/config/module.config.php'; + } + + /** + * Test plugin manager aliases + * + * @return void + */ + public function testAliases(): void + { + $serviceAliases = [ + 'AuthEnrichment', + 'MusicBrainzEnrichment', + 'NominatimGeocoder', + 'SkosmosEnrichment', + 'EadOnkiLightEnrichment', + 'Ead3OnkiLightEnrichment', + 'LidoOnkiLightEnrichment', + 'LrmiOnkiLightEnrichment', + 'MarcAuthOnkiLightEnrichment', + 'MarcOnkiLightEnrichment', + 'OnkiLightEnrichment', + 'EadSkosmosEnrichment', + 'Ead3SkosmosEnrichment', + 'LidoSkosmosEnrichment', + 'LrmiSkosmosEnrichment', + 'MarcAuthSkosmosEnrichment', + 'MarcSkosmosEnrichment', + 'MarcAuthEnrichment', + ]; + $serviceManager = $this->createMock(ContainerInterface::class); + $serviceManager->expects($this->any())->method('get')->willReturnMap( + [ + ['Config', $this->moduleConfig], + ] + ); + $enrichmentPluginManagerFactory = new \RecordManager\Base\ServiceManager\AbstractPluginManagerFactory(); + $enrichmentPluginManager = ($enrichmentPluginManagerFactory)( + $serviceManager, + \RecordManager\Base\Enrichment\PluginManager::class, + ); + $reflectionClass = new \ReflectionClass($enrichmentPluginManager); + $aliasesProperty = $reflectionClass->getProperty('aliases'); + + $aliasesConfig = $this->moduleConfig['recordmanager']['plugin_managers']['enrichment']['aliases'] ?? []; + $aliasesValue = $aliasesProperty->getValue($enrichmentPluginManager); + $this->assertEquals($aliasesConfig, $aliasesValue); + foreach ($serviceAliases as $alias) { + $this->assertTrue($enrichmentPluginManager->has($alias)); + } + } +} diff --git a/tests/RecordManagerTest/Base/Enrichment/SkosmosEnrichmentTest.php b/tests/RecordManagerTest/Base/Enrichment/SkosmosEnrichmentTest.php new file mode 100644 index 000000000..d88c60c3e --- /dev/null +++ b/tests/RecordManagerTest/Base/Enrichment/SkosmosEnrichmentTest.php @@ -0,0 +1,303 @@ + + * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License + * @link https://github.com/NatLibFi/RecordManager + */ + +namespace RecordManagerTest\Base\Enrichment; + +use Generator; +use RecordManager\Base\Enrichment\SkosmosEnrichment; +use RecordManager\Base\Http\HttpService; +use RecordManager\Base\Record\Marc; +use RecordManager\Base\Record\MarcAuthority; +use RecordManager\Base\Record\PluginManager; +use RecordManager\Base\Utils\Logger; +use RecordManager\Base\Utils\MetadataUtils; +use RecordManagerTest\Base\Record\RecordTestBase; + +use function is_array; + +/** + * Skosmos enrichment test class + * + * @category DataManagement + * @package RecordManager + * @author Juha Luoma + * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License + * @link https://github.com/NatLibFi/RecordManager + */ +class SkosmosEnrichmentTest extends RecordTestBase +{ + /** + * Data provider for testing Skosmos enrichment + * + * @return Generator + */ + public static function getSkosmosEnrichmentData(): Generator + { + yield 'basic topic enrichment' => [ + 'fixture' => 'marc_skosmos_1.xml', + 'enrichmentFixture' => 'Enrichment/skosmos_results.json', + 'config' => [], + 'expected' => [ + 'topic_add_txt_mv' => ['Enhanced Topic', 'Förbättrat ämne'], + 'topic_alt_txt_mv' => ['Alternative Topic'], + ], + ]; + yield 'geographic enrichment' => [ + 'fixture' => 'marc_skosmos_2.xml', + 'enrichmentFixture' => 'Enrichment/skosmos_results.json', + 'config' => [], + 'expected' => [ + 'geographic_add_txt_mv' => ['Helsinki', 'Helsingfors'], + 'location_geo' => ['POINT(24.9384 60.1699)'], + 'center_coords' => '60.1699, 24.9384', + ], + ]; + yield 'author enrichment (no method in Marc)' => [ + 'fixture' => 'marc_skosmos_3.xml', + 'enrichmentFixture' => 'Enrichment/skosmos_results.json', + 'config' => [], + 'expected' => [ + 'author' => ['Test Author'], + ], + ]; + yield 'authority record enrichment' => [ + 'fixture' => 'marc_authority_skosmos.xml', + 'enrichmentFixture' => 'Enrichment/skosmos_authority_results.json', + 'config' => [], + 'expected' => [ + 'occupation_str_mv' => [ + 'Test Occupation', + ], + ], + ]; + yield 'URI prefix filtering (invalid URI)' => [ + 'fixture' => 'marc_skosmos_invalid_uri.xml', + 'enrichmentFixture' => null, + 'config' => [], + 'expected' => [ + 'topic_add_txt_mv' => null, + ], + ]; + yield 'exact match enrichment' => [ + 'fixture' => 'marc_skosmos_exactmatch.xml', + 'enrichmentFixture' => 'Enrichment/skosmos_exactmatch_results.json', + 'config' => [], + 'expected' => [ + 'topic_add_txt_mv' => [ + 'Exact Match Enhanced Topic', + ], + ], + ]; + yield 'language filtering' => [ + 'fixture' => 'marc_skosmos_multilang.xml', + 'enrichmentFixture' => 'Enrichment/skosmos_multilang_results.json', + 'config' => [ + 'SkosmosEnrichment' => [ + 'base_url' => 'http://test.skosmos.url', + 'url_prefix_allowed_list' => ['http://www.yso.fi/onto/yso/'], + 'languages' => ['en', 'fi'], + ], + ], + 'expected' => [ + 'topic_add_txt_mv' => [ + 'Multilingual Topic English', + 'Monikielinen aihe suomeksi', + ], + ], + ]; + yield 'excluded location matches' => [ + 'fixture' => 'marc_skosmos_excluded_location.xml', + 'enrichmentFixture' => 'Enrichment/skosmos_excluded_location_results.json', + 'config' => [], + 'expected' => [ + 'location_geo' => ['POINT(23.7610 61.4978)'], + ], + ]; + yield 'EAD3 with topic enrichment' => [ + 'fixture' => 'ead3_skosmos.xml', + 'enrichmentFixture' => 'Enrichment/skosmos_results.json', + 'config' => [], + 'expected' => [ + 'topic_add_txt_mv' => ['Enhanced Topic', 'Förbättrat ämne'], + ], + ]; + yield 'LIDO with topic enrichment' => [ + 'fixture' => 'lido_skosmos.xml', + 'enrichmentFixture' => 'Enrichment/skosmos_results.json', + 'config' => [], + 'expected' => [ + 'topic_add_txt_mv' => ['Enhanced Topic', 'Förbättrat ämne'], + ], + ]; + yield 'QDC without enrichment methods' => [ + 'fixture' => 'qdc_skosmos.xml', + 'enrichmentFixture' => 'Enrichment/skosmos_results.json', + 'config' => [], + 'expected' => [ + 'topic_add_txt_mv' => null, + ], + ]; + yield 'Forward without enrichment methods' => [ + 'fixture' => 'forward_skosmos.xml', + 'enrichmentFixture' => 'Enrichment/skosmos_results.json', + 'config' => [], + 'expected' => [ + 'topic_add_txt_mv' => null, + ], + ]; + } + + /** + * Test Skosmos enrichment + * + * @param string $fixture Fixture filename + * @param string|null $enrichmentFixture Enrichment data fixture filename + * @param array $config Custom config + * @param array $expected Expected results + * + * @return void + */ + #[\PHPUnit\Framework\Attributes\DataProvider('getSkosmosEnrichmentData')] + public function testSkosmosEnrichment( + string $fixture, + ?string $enrichmentFixture, + array $config, + array $expected, + ): void { + $httpService = $this->createMock(HttpService::class); + $record = match (true) { + str_starts_with($fixture, 'marc_authority_') => + $this->createMarcRecord(MarcAuthority::class, $fixture, []), + str_starts_with($fixture, 'marc_') => + $this->createMarcRecord(Marc::class, $fixture, []), + str_starts_with($fixture, 'ead3_') => + $this->createRecord( + \RecordManager\Base\Record\Ead3::class, + $fixture, + constructorParams: [$httpService] + ), + str_starts_with($fixture, 'lido_') => + $this->createRecord( + \RecordManager\Base\Record\Lido::class, + $fixture, + constructorParams: [$httpService] + ), + str_starts_with($fixture, 'qdc_') => + $this->createRecord( + \RecordManager\Base\Record\Qdc::class, + $fixture, + constructorParams: [$httpService] + ), + str_starts_with($fixture, 'forward_') => + $this->createRecord( + \RecordManager\Base\Record\Forward::class, + $fixture, + [] + ), + default => null, + }; + + $record->normalize(); + $fields = $record->toSolrArray(); + + $dbEntities = []; + if ($enrichmentFixture) { + $enrichmentData = $this->getFixture($enrichmentFixture); + $dbEntities = json_decode($enrichmentData, true); + } + + $enricher = $this->getSkosmosEnricher($dbEntities, $config); + $enricher->enrich('test', $record, $fields); + + foreach ($expected as $field => $values) { + $this->assertEquals($values, $fields[$field] ?? null); + } + } + + /** + * Get a Skosmos enrichment object + * + * @param array $dbEntities Database entities + * @param array $config Main config + * + * @return SkosmosEnrichment + */ + protected function getSkosmosEnricher(array $dbEntities, array $config = []): SkosmosEnrichment + { + if (empty($config)) { + $config = [ + 'SkosmosEnrichment' => [ + 'base_url' => 'http://test.skosmos.url', + 'url_prefix_allowed_list' => ['http://www.yso.fi/onto/yso/'], + 'uri_prefix_exact_matches' => ['http://www.yso.fi/onto/yso/'], + 'solr_location_field' => 'location_geo', + 'solr_center_field' => 'center_coords', + ], + ]; + } + + $db = $this->createMock( + \RecordManager\Base\Database\MongoDatabase::class, + ); + + foreach ($dbEntities as &$entity) { + if (isset($entity['data']) && is_array($entity['data'])) { + $entity['data'] = serialize(\ML\JsonLD\JsonLD::getDocument(json_encode($entity['data']))); + } + } + unset($entity); + + $db->expects($this->any())->method('findLinkedDataEnrichment') + ->willReturnCallback(function ($params) use ($dbEntities) { + return $dbEntities[$params['_id']] ?? null; + }); + + $db->expects($this->any())->method('saveLinkedDataEnrichment') + ->willReturn(true); + + $metadataUtils = $this->getMockBuilder(MetadataUtils::class) + ->onlyMethods([]) + ->disableOriginalConstructor() + ->getMock(); + + $enricher = $this->getMockBuilder(SkosmosEnrichment::class) + ->onlyMethods([]) + ->setConstructorArgs([ + $config, + $db, + $this->createMock(Logger::class), + $this->createMock(PluginManager::class), + $this->createMock(HttpService::class), + $metadataUtils, + ]) + ->getMock(); + + return $enricher; + } +} diff --git a/tests/RecordManagerTest/Base/Solr/SolrUpdaterTest.php b/tests/RecordManagerTest/Base/Solr/SolrUpdaterTest.php index ea3ee0ba9..e59499e21 100644 --- a/tests/RecordManagerTest/Base/Solr/SolrUpdaterTest.php +++ b/tests/RecordManagerTest/Base/Solr/SolrUpdaterTest.php @@ -32,7 +32,9 @@ use ArrayIterator; use RecordManager\Base\Database\DatabaseInterface; use RecordManager\Base\Database\MongoDatabase; +use RecordManager\Base\Enrichment\AuthEnrichment; use RecordManager\Base\Enrichment\PluginManager as EnrichmentPluginManager; +use RecordManager\Base\Enrichment\SkosmosEnrichment; use RecordManager\Base\Http\HttpService as HttpService; use RecordManager\Base\Record\Marc\FormatCalculator; use RecordManager\Base\Record\PluginManager as RecordPluginManager; @@ -40,9 +42,11 @@ use RecordManager\Base\Solr\SolrUpdater; use RecordManager\Base\Utils\FieldMapper; use RecordManager\Base\Utils\Logger; +use RecordManager\Base\Utils\MetadataUtils; use RecordManager\Base\Utils\WorkerPoolManager; use RecordManagerTest\Base\Feature\FixtureTrait; use RecordManagerTest\Base\Record\CreateSampleRecordTrait; +use ReflectionClass; /** * Tests for SolrUpdater @@ -450,6 +454,60 @@ public function testFieldProcessingRules(array $rules, array $expected): void } } + /** + * Test enrichments using legacy names and new names. + * + * @return void + */ + public function testLegacyEnrichments(): void + { + $dsOverride = [ + 'test' => [ + 'enrichments' => [ + 'MarcOnkiLightEnrichment', + 'LidoOnkiLightEnrichment', + 'Ead3SkosmosEnrichment', + 'EadSkosmosEnrichment', + 'OnkiLightEnrichment', + 'MarcAuthEnrichment', + 'SomeAuthEnrichment,final', + 'BrokenEnrichment', + ], + ], + ]; + $this->config['Solr']['enrichment'] = [ + 'LidoSkosmosEnrichment', + 'LidoAuthEnrichment', + 'EadOnkiLightEnrichment,start', + ]; + $solrUpdater = $this->getSolrUpdater( + $dsOverride, + ); + $record = $this->createMarcRecord( + \RecordManager\Base\Record\Marc::class, + 'marc-broken.xml' + ); + + $date = strtotime('2020-10-20 13:01:00'); + $dbRecord = [ + '_id' => $record->getID(), + 'oai_id' => '', + 'linking_id' => $record->getLinkingIDs(), + 'source_id' => 'test', + 'deleted' => false, + 'created' => $date, + 'updated' => $date, + 'date' => $date, + 'format' => 'marc', + 'original_data' => $record->serialize(), + 'normalized_data' => null, + ]; + $solrUpdater->processSingleRecord($dbRecord); + $reflectionClass = new ReflectionClass($solrUpdater); + $enrichments = array_keys($reflectionClass->getProperty('enrichments')->getValue($solrUpdater)); + $this->assertEquals([SkosmosEnrichment::class, AuthEnrichment::class], $enrichments); + } + /** * Create SolrUpdater * @@ -491,13 +549,55 @@ function ($data) { [], $this->dataSourceConfig ); + $enrichmentTable = [ + 'AuthEnrichment' => \RecordManager\Base\Enrichment\AuthEnrichment::class, + 'MusicBrainzEnrichment' => \RecordManager\Base\Enrichment\MusicBrainzEnrichment::class, + 'NominatimGeocoder' => \RecordManager\Base\Enrichment\NominatimGeocoder::class, + 'SkosmosEnrichment' => \RecordManager\Base\Enrichment\SkosmosEnrichment::class, + + // Legacy aliases: + 'EadOnkiLightEnrichment' => \RecordManager\Base\Enrichment\SkosmosEnrichment::class, + 'Ead3OnkiLightEnrichment' => \RecordManager\Base\Enrichment\SkosmosEnrichment::class, + 'LidoOnkiLightEnrichment' => \RecordManager\Base\Enrichment\SkosmosEnrichment::class, + 'LrmiOnkiLightEnrichment' => \RecordManager\Base\Enrichment\SkosmosEnrichment::class, + 'MarcAuthOnkiLightEnrichment' => \RecordManager\Base\Enrichment\SkosmosEnrichment::class, + 'MarcOnkiLightEnrichment' => \RecordManager\Base\Enrichment\SkosmosEnrichment::class, + 'OnkiLightEnrichment' => \RecordManager\Base\Enrichment\SkosmosEnrichment::class, + 'EadSkosmosEnrichment' => \RecordManager\Base\Enrichment\SkosmosEnrichment::class, + 'Ead3SkosmosEnrichment' => \RecordManager\Base\Enrichment\SkosmosEnrichment::class, + 'LidoSkosmosEnrichment' => \RecordManager\Base\Enrichment\SkosmosEnrichment::class, + 'LrmiSkosmosEnrichment' => \RecordManager\Base\Enrichment\SkosmosEnrichment::class, + 'MarcAuthSkosmosEnrichment' => \RecordManager\Base\Enrichment\SkosmosEnrichment::class, + 'MarcSkosmosEnrichment' => \RecordManager\Base\Enrichment\SkosmosEnrichment::class, + + 'MarcAuthEnrichment' => \RecordManager\Base\Enrichment\AuthEnrichment::class, + ]; + $enrichmentPluginManager = $this->createMock(EnrichmentPluginManager::class); + $enrichmentPluginManager->expects($this->any())->method('get')->willReturnCallback( + function ($name, $options = null) use ($enrichmentTable) { + return new $enrichmentTable[$name]( + [], + $this->createMock(DatabaseInterface::class), + $this->createMock(Logger::class), + $this->createMock(RecordPluginManager::class), + $this->createMock(HttpService::class), + $this->createMock(MetadataUtils::class), + $this->createMock(DatabaseInterface::class) + ); + } + ); + $enrichmentPluginManager->expects($this->any())->method('has')->willReturnCallback( + function ($name) use ($enrichmentTable) { + return isset($enrichmentTable[$name]); + } + ); $solrUpdater = new SolrUpdater( $this->config, $dsConfig, $database, $logger, $recordPM, - $this->createMock(EnrichmentPluginManager::class), + $enrichmentPluginManager, $this->createMock(HttpService::class), $this->createMock(Ini::class), $fieldMapper, diff --git a/tests/fixtures/Base/Enrichment/skosmos_author_results.json b/tests/fixtures/Base/Enrichment/skosmos_author_results.json new file mode 100644 index 000000000..43ad4f106 --- /dev/null +++ b/tests/fixtures/Base/Enrichment/skosmos_author_results.json @@ -0,0 +1,14 @@ +{ + "http://www.yso.fi/onto/yso/p99999": { + "_id": "http://www.yso.fi/onto/yso/p99999", + "data": { + "prefLabel": { + "en": "Enriched Author Name", + "fi": "Rikastettu tekijän nimi" + }, + "altLabel": { + "en": "Author Variant" + } + } + } +} diff --git a/tests/fixtures/Base/Enrichment/skosmos_authority_results.json b/tests/fixtures/Base/Enrichment/skosmos_authority_results.json new file mode 100644 index 000000000..a1aa812cc --- /dev/null +++ b/tests/fixtures/Base/Enrichment/skosmos_authority_results.json @@ -0,0 +1,25 @@ +{ + "http://www.yso.fi/onto/yso/p11111": { + "_id": "http://www.yso.fi/onto/yso/p11111", + "data": { + "@context": { + "skos": "http://www.w3.org/2004/02/skos/core#", + "uri": "@id", + "type": "@type", + "lang": "@language", + "value": "@value", + "graph": "@graph", + "prefLabel": "skos:prefLabel" + }, + "graph": [ + { + "uri": "http://www.yso.fi/onto/yso/p11111", + "type": "skos:Concept", + "prefLabel": [ + {"lang": "en", "value": "Test Occupation"} + ] + } + ] + } + } +} diff --git a/tests/fixtures/Base/Enrichment/skosmos_exactmatch_results.json b/tests/fixtures/Base/Enrichment/skosmos_exactmatch_results.json new file mode 100644 index 000000000..4fbac5601 --- /dev/null +++ b/tests/fixtures/Base/Enrichment/skosmos_exactmatch_results.json @@ -0,0 +1,25 @@ +{ + "http://www.yso.fi/onto/yso/p22222": { + "_id": "http://www.yso.fi/onto/yso/p22222", + "data": { + "@context": { + "skos": "http://www.w3.org/2004/02/skos/core#", + "uri": "@id", + "type": "@type", + "lang": "@language", + "value": "@value", + "graph": "@graph", + "prefLabel": "skos:prefLabel" + }, + "graph": [ + { + "uri": "http://www.yso.fi/onto/yso/p22222", + "type": "skos:Concept", + "prefLabel": [ + {"lang": "en", "value": "Exact Match Enhanced Topic"} + ] + } + ] + } + } +} diff --git a/tests/fixtures/Base/Enrichment/skosmos_excluded_location_results.json b/tests/fixtures/Base/Enrichment/skosmos_excluded_location_results.json new file mode 100644 index 000000000..57a95c6a3 --- /dev/null +++ b/tests/fixtures/Base/Enrichment/skosmos_excluded_location_results.json @@ -0,0 +1,28 @@ +{ + "http://www.yso.fi/onto/yso/p44444": { + "_id": "http://www.yso.fi/onto/yso/p44444", + "data": { + "@context": { + "skos": "http://www.w3.org/2004/02/skos/core#", + "wgs84": "http://www.w3.org/2003/01/geo/wgs84_pos#", + "uri": "@id", + "type": "@type", + "lang": "@language", + "value": "@value", + "graph": "@graph", + "prefLabel": "skos:prefLabel" + }, + "graph": [ + { + "uri": "http://www.yso.fi/onto/yso/p44444", + "type": "skos:Concept", + "prefLabel": [ + {"lang": "en", "value": "Excluded Location"} + ], + "wgs84:lat": "61.4978", + "wgs84:long": "23.7610" + } + ] + } + } +} diff --git a/tests/fixtures/Base/Enrichment/skosmos_geographic_results.json b/tests/fixtures/Base/Enrichment/skosmos_geographic_results.json new file mode 100644 index 000000000..9cc99d9a7 --- /dev/null +++ b/tests/fixtures/Base/Enrichment/skosmos_geographic_results.json @@ -0,0 +1,14 @@ +{ + "http://www.yso.fi/onto/yso/p94426": { + "_id": "http://www.yso.fi/onto/yso/p94426", + "data": { + "prefLabel": { + "en": "Helsinki", + "fi": "Helsinki", + "sv": "Helsingfors" + }, + "latitude": "60.1699", + "longitude": "24.9384" + } + } +} diff --git a/tests/fixtures/Base/Enrichment/skosmos_multilang_results.json b/tests/fixtures/Base/Enrichment/skosmos_multilang_results.json new file mode 100644 index 000000000..b8971af8b --- /dev/null +++ b/tests/fixtures/Base/Enrichment/skosmos_multilang_results.json @@ -0,0 +1,28 @@ +{ + "http://www.yso.fi/onto/yso/p33333": { + "_id": "http://www.yso.fi/onto/yso/p33333", + "data": { + "@context": { + "skos": "http://www.w3.org/2004/02/skos/core#", + "uri": "@id", + "type": "@type", + "lang": "@language", + "value": "@value", + "graph": "@graph", + "prefLabel": "skos:prefLabel" + }, + "graph": [ + { + "uri": "http://www.yso.fi/onto/yso/p33333", + "type": "skos:Concept", + "prefLabel": [ + {"lang": "en", "value": "Multilingual Topic English"}, + {"lang": "fi", "value": "Monikielinen aihe suomeksi"}, + {"lang": "sv", "value": "Flerspråkigt ämne på svenska"}, + {"lang": "de", "value": "Mehrsprachiges Thema auf Deutsch"} + ] + } + ] + } + } +} diff --git a/tests/fixtures/Base/Enrichment/skosmos_results.json b/tests/fixtures/Base/Enrichment/skosmos_results.json new file mode 100644 index 000000000..0587e6329 --- /dev/null +++ b/tests/fixtures/Base/Enrichment/skosmos_results.json @@ -0,0 +1,84 @@ +{ + "http://www.yso.fi/onto/yso/p12345": { + "_id": "http://www.yso.fi/onto/yso/p12345", + "data": { + "@context": { + "skos": "http://www.w3.org/2004/02/skos/core#", + "uri": "@id", + "type": "@type", + "lang": "@language", + "value": "@value", + "graph": "@graph", + "prefLabel": "skos:prefLabel", + "altLabel": "skos:altLabel" + }, + "graph": [ + { + "uri": "http://www.yso.fi/onto/yso/p12345", + "type": "skos:Concept", + "prefLabel": [ + {"lang": "en", "value": "Enhanced Topic"}, + {"lang": "sv", "value": "Förbättrat ämne"} + ], + "altLabel": [ + {"lang": "en", "value": "Alternative Topic"} + ] + } + ] + } + }, + "http://www.yso.fi/onto/yso/p94426": { + "_id": "http://www.yso.fi/onto/yso/p94426", + "data": { + "@context": { + "skos": "http://www.w3.org/2004/02/skos/core#", + "wgs84": "http://www.w3.org/2003/01/geo/wgs84_pos#", + "uri": "@id", + "type": "@type", + "lang": "@language", + "value": "@value", + "graph": "@graph", + "prefLabel": "skos:prefLabel" + }, + "graph": [ + { + "uri": "http://www.yso.fi/onto/yso/p94426", + "type": "skos:Concept", + "prefLabel": [ + {"lang": "en", "value": "Helsinki"}, + {"lang": "sv", "value": "Helsingfors"} + ], + "wgs84:lat": "60.1699", + "wgs84:long": "24.9384" + } + ] + } + }, + "http://www.yso.fi/onto/yso/p99999": { + "_id": "http://www.yso.fi/onto/yso/p99999", + "data": { + "@context": { + "skos": "http://www.w3.org/2004/02/skos/core#", + "uri": "@id", + "type": "@type", + "lang": "@language", + "value": "@value", + "graph": "@graph", + "prefLabel": "skos:prefLabel", + "altLabel": "skos:altLabel" + }, + "graph": [ + { + "uri": "http://www.yso.fi/onto/yso/p99999", + "type": "skos:Concept", + "prefLabel": [ + {"lang": "en", "value": "Enriched Author Name"} + ], + "altLabel": [ + {"lang": "en", "value": "Author Variant"} + ] + } + ] + } + } +} diff --git a/tests/fixtures/Base/record/ead3_skosmos.xml b/tests/fixtures/Base/record/ead3_skosmos.xml new file mode 100644 index 000000000..ade41c60f --- /dev/null +++ b/tests/fixtures/Base/record/ead3_skosmos.xml @@ -0,0 +1,23 @@ + + + + ead3-test-001 + + + Test EAD3 Document with Skosmos Subject + ead3-test-001 + + + Test Repository + + + + + + Test Subject + + + +

This is a test EAD3 document for Skosmos enrichment testing.

+
+
diff --git a/tests/fixtures/Base/record/forward_skosmos.xml b/tests/fixtures/Base/record/forward_skosmos.xml new file mode 100644 index 000000000..076e16c98 --- /dev/null +++ b/tests/fixtures/Base/record/forward_skosmos.xml @@ -0,0 +1,17 @@ + + + + forward-test-001 + + Test Archive + + + <TitleText>Test Forward Document</TitleText> + <TitleRelationship>original</TitleRelationship> + + Test Forward Document + + Test Subject + + + diff --git a/tests/fixtures/Base/record/lido_skosmos.xml b/tests/fixtures/Base/record/lido_skosmos.xml new file mode 100644 index 000000000..fe6dd5a68 --- /dev/null +++ b/tests/fixtures/Base/record/lido_skosmos.xml @@ -0,0 +1,44 @@ + + + + lido-test-001 + + + + + Test LIDO Document with Skosmos Subject + + + + + + + Test Museum + + + + + + + + + + + http://www.yso.fi/onto/yso/p12345 + Test Subject + + + + + + + + + lido-test-001 + + Archive + + + + + diff --git a/tests/fixtures/Base/record/marc_auth_1.xml b/tests/fixtures/Base/record/marc_auth_1.xml new file mode 100644 index 000000000..f5d513986 --- /dev/null +++ b/tests/fixtures/Base/record/marc_auth_1.xml @@ -0,0 +1,19 @@ + + + 00000nam a2200000 i 4500 + marc_auth_test_1 + 20251215000000.0 + 251215s2025 fi 000 0 eng d + + Primary Author + (FIN11)authority_001 + + + Test Book Title + + + Secondary Author + (FIN11)authority_001 + + + diff --git a/tests/fixtures/Base/record/marc_auth_missing_authority.xml b/tests/fixtures/Base/record/marc_auth_missing_authority.xml new file mode 100644 index 000000000..62f83cf71 --- /dev/null +++ b/tests/fixtures/Base/record/marc_auth_missing_authority.xml @@ -0,0 +1,19 @@ + + + 00000nam a2200000 i 4500 + marc_auth_test_missing + 20251215000000.0 + 251215s2025 fi 000 0 eng d + + Author With Missing Authority + (FIN11)nonexistent_authority + + + Test Book With Missing Authority + + + Secondary Author With Missing Authority + (FIN11)another_missing + + + diff --git a/tests/fixtures/Base/record/marc_auth_no_ids.xml b/tests/fixtures/Base/record/marc_auth_no_ids.xml new file mode 100644 index 000000000..12b1cf6c7 --- /dev/null +++ b/tests/fixtures/Base/record/marc_auth_no_ids.xml @@ -0,0 +1,17 @@ + + + 00000nam a2200000 i 4500 + marc_auth_test_no_ids + 20251215000000.0 + 251215s2025 fi 000 0 eng d + + Author Without ID + + + Test Book Without Authority IDs + + + Second Author Without ID + + + diff --git a/tests/fixtures/Base/record/marc_authority_1.xml b/tests/fixtures/Base/record/marc_authority_1.xml new file mode 100644 index 000000000..edc9feb62 --- /dev/null +++ b/tests/fixtures/Base/record/marc_authority_1.xml @@ -0,0 +1,17 @@ + + + 00000nz a2200000n 4500 + authority_001 + 20251215000000.0 + 251215n| azannaabn |a aaa + + Primary Author + + + Alternative Name 1 + + + Alternative Name 2 + + + diff --git a/tests/fixtures/Base/record/marc_authority_skosmos.xml b/tests/fixtures/Base/record/marc_authority_skosmos.xml new file mode 100644 index 000000000..5170f692b --- /dev/null +++ b/tests/fixtures/Base/record/marc_authority_skosmos.xml @@ -0,0 +1,16 @@ + + + 00000nz a2200000n 4500 + authority_skosmos_test + 20251215000000.0 + 251215n| azannaabn |a aaa + + Test Authority Name + + + Test Occupation + http://www.yso.fi/onto/yso/p11111 + yso + + + diff --git a/tests/fixtures/Base/record/marc_skosmos_1.xml b/tests/fixtures/Base/record/marc_skosmos_1.xml new file mode 100644 index 000000000..a0f25306f --- /dev/null +++ b/tests/fixtures/Base/record/marc_skosmos_1.xml @@ -0,0 +1,19 @@ + + + 01195cam a22004094i 4500 + skosmos_test_1 + 20251215000000.0 + 251215s2025 fi 000 0 fin d + + Test Author. + + + Test Title for Skosmos Enrichment + + + Test Topic + http://www.yso.fi/onto/yso/p12345 + yso + + + diff --git a/tests/fixtures/Base/record/marc_skosmos_2.xml b/tests/fixtures/Base/record/marc_skosmos_2.xml new file mode 100644 index 000000000..5c4bfeb5c --- /dev/null +++ b/tests/fixtures/Base/record/marc_skosmos_2.xml @@ -0,0 +1,19 @@ + + + 01195cam a22004094i 4500 + skosmos_test_2 + 20251215000000.0 + 251215s2025 fi 000 0 fin d + + Test Author. + + + Test Title for Geographic Enrichment + + + Test Geographic Place + http://www.yso.fi/onto/yso/p94426 + yso + + + diff --git a/tests/fixtures/Base/record/marc_skosmos_3.xml b/tests/fixtures/Base/record/marc_skosmos_3.xml new file mode 100644 index 000000000..c8540e7f3 --- /dev/null +++ b/tests/fixtures/Base/record/marc_skosmos_3.xml @@ -0,0 +1,15 @@ + + + 01195cam a22004094i 4500 + skosmos_test_3 + 20251215000000.0 + 251215s2025 fi 000 0 fin d + + Test Author + http://www.yso.fi/onto/yso/p99999 + + + Test Title for Author Enrichment + + + diff --git a/tests/fixtures/Base/record/marc_skosmos_exactmatch.xml b/tests/fixtures/Base/record/marc_skosmos_exactmatch.xml new file mode 100644 index 000000000..de3d0a00d --- /dev/null +++ b/tests/fixtures/Base/record/marc_skosmos_exactmatch.xml @@ -0,0 +1,19 @@ + + + 01195cam a22004094i 4500 + skosmos_test_exactmatch + 20251215000000.0 + 251215s2025 fi 000 0 fin d + + Test Author. + + + Test Title for Exact Match + + + Exact Match Topic + http://www.yso.fi/onto/yso/p22222 + yso + + + diff --git a/tests/fixtures/Base/record/marc_skosmos_excluded_location.xml b/tests/fixtures/Base/record/marc_skosmos_excluded_location.xml new file mode 100644 index 000000000..e7cd9f7ec --- /dev/null +++ b/tests/fixtures/Base/record/marc_skosmos_excluded_location.xml @@ -0,0 +1,19 @@ + + + 01195cam a22004094i 4500 + skosmos_test_excluded + 20251215000000.0 + 251215s2025 fi 000 0 fin d + + Test Author. + + + Test Title for Excluded Location + + + Excluded Location + http://www.yso.fi/onto/yso/p44444 + yso + + + diff --git a/tests/fixtures/Base/record/marc_skosmos_invalid_uri.xml b/tests/fixtures/Base/record/marc_skosmos_invalid_uri.xml new file mode 100644 index 000000000..21cf3c20f --- /dev/null +++ b/tests/fixtures/Base/record/marc_skosmos_invalid_uri.xml @@ -0,0 +1,19 @@ + + + 01195cam a22004094i 4500 + skosmos_test_invalid + 20251215000000.0 + 251215s2025 fi 000 0 fin d + + Test Author. + + + Test Title with Invalid URI + + + Test Topic + http://invalid.uri.example.com/p12345 + other + + + diff --git a/tests/fixtures/Base/record/marc_skosmos_multilang.xml b/tests/fixtures/Base/record/marc_skosmos_multilang.xml new file mode 100644 index 000000000..d2bd4731a --- /dev/null +++ b/tests/fixtures/Base/record/marc_skosmos_multilang.xml @@ -0,0 +1,19 @@ + + + 01195cam a22004094i 4500 + skosmos_test_multilang + 20251215000000.0 + 251215s2025 fi 000 0 fin d + + Test Author. + + + Test Title for Multilingual + + + Multilang Topic + http://www.yso.fi/onto/yso/p33333 + yso + + + diff --git a/tests/fixtures/Base/record/qdc_skosmos.xml b/tests/fixtures/Base/record/qdc_skosmos.xml new file mode 100644 index 000000000..95bb09796 --- /dev/null +++ b/tests/fixtures/Base/record/qdc_skosmos.xml @@ -0,0 +1,9 @@ + + + Test QDC Document + Test Subject + This is a test QDC document for Skosmos enrichment testing. + Text + qdc-test-001 +