From 15c041d0f849a8e89fb901a969659e7ee17f9f3d Mon Sep 17 00:00:00 2001 From: Juha Luoma <33253757+LuomaJuha@users.noreply.github.com> Date: Mon, 2 Jun 2025 12:41:19 +0300 Subject: [PATCH 1/3] Added resource list handler table --- module/Finna/config/module.config.php | 3 + module/Finna/sql/mysql.sql | 14 ++ ...innaResourceListHandlerEntityInterface.php | 96 +++++++++++++ .../Finna/Db/Row/FinnaResourceListHandler.php | 120 +++++++++++++++++ .../FinnaResourceListHandlerService.php | 64 +++++++++ ...nnaResourceListHandlerServiceInterface.php | 51 +++++++ .../Db/Table/FinnaResourceListHandler.php | 78 +++++++++++ .../ReservationListService.php | 33 +++-- .../ReservationListServiceFactory.php | 1 + ...api.yaml => ReservationList_database.yaml} | 38 +++--- .../ReservationList/ReservationListTest.php | 127 +++++++++++------- 11 files changed, 549 insertions(+), 76 deletions(-) create mode 100644 module/Finna/src/Finna/Db/Entity/FinnaResourceListHandlerEntityInterface.php create mode 100644 module/Finna/src/Finna/Db/Row/FinnaResourceListHandler.php create mode 100644 module/Finna/src/Finna/Db/Service/FinnaResourceListHandlerService.php create mode 100644 module/Finna/src/Finna/Db/Service/FinnaResourceListHandlerServiceInterface.php create mode 100644 module/Finna/src/Finna/Db/Table/FinnaResourceListHandler.php rename module/Finna/tests/fixtures/reservationlist/{ReservationList_api.yaml => ReservationList_database.yaml} (98%) diff --git a/module/Finna/config/module.config.php b/module/Finna/config/module.config.php index d9ce2e9c43e..b6eabf8c08c 100644 --- a/module/Finna/config/module.config.php +++ b/module/Finna/config/module.config.php @@ -610,6 +610,7 @@ 'Finna\Db\Row\UserCard' => 'VuFind\Db\Row\RowGatewayFactory', 'Finna\Db\Row\UserList' => 'VuFind\Db\Row\UserListFactory', \Finna\Db\Row\FinnaResourceList::class => \VuFind\Db\Row\RowGatewayFactory::class, + \Finna\Db\Row\FinnaResourceListHandler::class => \VuFind\Db\Row\RowGatewayFactory::class, \Finna\Db\Row\FinnaResourceListResource::class => \VuFind\Db\Row\RowGatewayFactory::class, 'Finna\Db\Row\UserResource' => 'VuFind\Db\Row\RowGatewayFactory', ], @@ -650,6 +651,7 @@ => \VuFind\Db\Service\AbstractDbServiceFactory::class, \Finna\Db\Service\RatingsService::class => \VuFind\Db\Service\AbstractDbServiceFactory::class, \Finna\Db\Service\RecordService::class => \VuFind\Db\Service\AbstractDbServiceFactory::class, + \Finna\Db\Service\FinnaResourceListHandlerService::class => \VuFind\Db\Service\AbstractDbServiceFactory::class, \Finna\Db\Service\FinnaResourceListService::class => \VuFind\Db\Service\AbstractDbServiceFactory::class, \Finna\Db\Service\FinnaResourceListResourceService::class => \VuFind\Db\Service\AbstractDbServiceFactory::class, \Finna\Db\Service\SearchService::class => \VuFind\Db\Service\AbstractDbServiceFactory::class, @@ -712,6 +714,7 @@ 'Finna\Db\Table\User' => 'VuFind\Db\Table\UserFactory', 'Finna\Db\Table\UserList' => 'VuFind\Db\Table\GatewayFactory', \Finna\Db\Table\FinnaResourceList::class => \VuFind\Db\Table\GatewayFactory::class, + \Finna\Db\Table\FinnaResourceListHandler::class => \VuFind\Db\Table\GatewayFactory::class, \Finna\Db\Table\FinnaResourceListResource::class => \VuFind\Db\Table\GatewayFactory::class, 'Finna\Db\Table\UserResource' => 'VuFind\Db\Table\GatewayFactory', ], diff --git a/module/Finna/sql/mysql.sql b/module/Finna/sql/mysql.sql index 26f642cdb04..03ac6fab034 100644 --- a/module/Finna/sql/mysql.sql +++ b/module/Finna/sql/mysql.sql @@ -348,6 +348,20 @@ CREATE TABLE `finna_resource_list` ( ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; /*!40101 SET character_set_client = @saved_cs_client */; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!40101 SET character_set_client = utf8mb4 */; +CREATE TABLE `finna_resource_list_handler` ( + `id` int(11) NOT NULL AUTO_INCREMENT, + `institution` int(10) unsigned NOT NULL, + `identifier` varchar(255) NOT NULL, + `enabled` int(1) NOT NULL DEFAULT 0, + `data` json DEFAULT '', + `created` datetime NOT NULL DEFAULT '2000-01-01 00:00:00', + PRIMARY KEY (`id`), + KEY `institution` (`institution`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; +/*!40101 SET character_set_client = @saved_cs_client */; + /*!40101 SET @saved_cs_client = @@character_set_client */; /*!40101 SET character_set_client = utf8mb4 */; CREATE TABLE `finna_resource_list_resource` ( diff --git a/module/Finna/src/Finna/Db/Entity/FinnaResourceListHandlerEntityInterface.php b/module/Finna/src/Finna/Db/Entity/FinnaResourceListHandlerEntityInterface.php new file mode 100644 index 00000000000..d8de736cbb5 --- /dev/null +++ b/module/Finna/src/Finna/Db/Entity/FinnaResourceListHandlerEntityInterface.php @@ -0,0 +1,96 @@ + + * @author Juha Luoma + * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License + * @link http://vufind.org Main Site + */ + +namespace Finna\Db\Entity; + +use DateTime; +use VuFind\Db\Entity\EntityInterface; + +/** + * Finna resource list handler entity interface + * + * @category VuFind + * @package Db_Interface + * @author Ere Maijala + * @author Juha Luoma + * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License + * @link http://vufind.org Main Site + * + * @property int $id + * @property string $institution + * @property string $identifier + * @property int $enabled + * @property string $data + * @property string $created + */ +interface FinnaResourceListHandlerEntityInterface extends EntityInterface +{ + /** + * Get the ID of the list. + * + * @return ?int + */ + public function getId(): ?int; + + /** + * Get user entity + * + * @return string + */ + public function getInstitution(): string; + + /** + * Get list identifier + * + * @return string; + */ + public function getIdentifier(): string; + + /** + * Is the list enabled + * + * @return bool + */ + public function getEnabled(): bool; + + /** + * Get list data as associative array + * + * @return array + */ + public function getData(): array; + + /** + * Get time when list has been created + * + * @return DateTime + */ + public function getCreated(): DateTime; +} diff --git a/module/Finna/src/Finna/Db/Row/FinnaResourceListHandler.php b/module/Finna/src/Finna/Db/Row/FinnaResourceListHandler.php new file mode 100644 index 00000000000..1c5b1b70058 --- /dev/null +++ b/module/Finna/src/Finna/Db/Row/FinnaResourceListHandler.php @@ -0,0 +1,120 @@ + + * @author Juha Luoma + * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License + * @link http://vufind.org Main Site + */ + +namespace Finna\Db\Row; + +use DateTime; +use Finna\Db\Entity\FinnaResourceListHandlerEntityInterface; +use VuFind\Db\Row\RowGateway; + +/** + * Finna resource list handler entity + * + * @category VuFind + * @package Db_Interface + * @author Ere Maijala + * @author Juha Luoma + * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License + * @link http://vufind.org Main Site + * + * @property int $id + * @property string $institution + * @property string $identifier + * @property int $enabled + * @property string $data + * @property string $created + */ +class FinnaResourceListHandler extends RowGateway implements + \VuFind\Db\Service\DbServiceAwareInterface, + FinnaResourceListHandlerEntityInterface +{ + use \VuFind\Db\Table\DbTableAwareTrait; + use \VuFind\Db\Service\DbServiceAwareTrait; + + /** + * Get the ID of the list handler. + * + * @return int + */ + public function getId(): int + { + return $this->id; + } + + /** + * Get user entity + * + * @return string + */ + public function getInstitution(): string + { + return $this->institution; + } + + /** + * Get list identifier + * + * @return string; + */ + public function getIdentifier(): string + { + return $this->identifier; + } + + /** + * Is the list enabled + * + * @return bool + */ + public function getEnabled(): bool + { + return (bool)$this->enabled; + } + + /** + * Get list data as associative array + * + * @return array + */ + public function getData(): array + { + return json_decode($this->data, true); + } + + /** + * Get time when list has been created + * + * @return DateTime + */ + public function getCreated(): DateTime + { + return DateTime::createFromFormat('Y-m-d H:i:s', $this->created); + } +} diff --git a/module/Finna/src/Finna/Db/Service/FinnaResourceListHandlerService.php b/module/Finna/src/Finna/Db/Service/FinnaResourceListHandlerService.php new file mode 100644 index 00000000000..9e75cb75145 --- /dev/null +++ b/module/Finna/src/Finna/Db/Service/FinnaResourceListHandlerService.php @@ -0,0 +1,64 @@ + + * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License + * @link http://vufind.org Main Site + */ + +namespace Finna\Db\Service; + +use VuFind\Db\Service\AbstractDbService; +use VuFind\Db\Service\DbServiceAwareTrait; +use VuFind\Db\Table\DbTableAwareInterface; +use VuFind\Db\Table\DbTableAwareTrait; + +/** + * Resource list handler service + * + * @category VuFind + * @package Db_Service + * @author Juha Luoma + * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License + * @link https://vufind.org/wiki/development Wiki + */ +class FinnaResourceListHandlerService extends AbstractDbService implements + DbTableAwareInterface, + FinnaResourceListHandlerServiceInterface +{ + use DbTableAwareTrait; + use DbServiceAwareTrait; + + /** + * Get resource list handlers + * + * @return array + */ + public function getResourceListHandlers(): array + { + return iterator_to_array( + $this->getDbTable(\Finna\Db\Table\FinnaResourceListHandler::class)->select(['enabled' => 1]) + ); + } +} diff --git a/module/Finna/src/Finna/Db/Service/FinnaResourceListHandlerServiceInterface.php b/module/Finna/src/Finna/Db/Service/FinnaResourceListHandlerServiceInterface.php new file mode 100644 index 00000000000..abc201f4ce2 --- /dev/null +++ b/module/Finna/src/Finna/Db/Service/FinnaResourceListHandlerServiceInterface.php @@ -0,0 +1,51 @@ + + * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License + * @link http://vufind.org Main Site + */ + +namespace Finna\Db\Service; + +use VuFind\Db\Service\DbServiceInterface; + +/** + * Resource list handler service interface + * + * @category VuFind + * @package Db_Service + * @author Juha Luoma + * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License + * @link http://vufind.org Main Site + */ +interface FinnaResourceListHandlerServiceInterface extends DbServiceInterface +{ + /** + * Get resource list handlers + * + * @return array + */ + public function getResourceListHandlers(): array; +} diff --git a/module/Finna/src/Finna/Db/Table/FinnaResourceListHandler.php b/module/Finna/src/Finna/Db/Table/FinnaResourceListHandler.php new file mode 100644 index 00000000000..5c66bb372f8 --- /dev/null +++ b/module/Finna/src/Finna/Db/Table/FinnaResourceListHandler.php @@ -0,0 +1,78 @@ + + * @author Demian Katz + * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License + * @link https://vufind.org Main Page + */ + +namespace Finna\Db\Table; + +use Laminas\Db\Adapter\Adapter; +use Laminas\Session\Container; +use VuFind\Db\Row\RowGateway; +use VuFind\Db\Service\DbServiceAwareInterface; +use VuFind\Db\Service\DbServiceAwareTrait; +use VuFind\Db\Table\Gateway; +use VuFind\Db\Table\PluginManager; + +/** + * Table Definition for finna_resource_list_handler + * + * @category VuFind + * @package Db_Table + * @author Juha Luoma + * @author Demian Katz + * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License + * @link https://vufind.org Main Page + */ +class FinnaResourceListHandler extends Gateway implements DbServiceAwareInterface +{ + use DbServiceAwareTrait; + + /** + * Constructor + * + * @param Adapter $adapter Database adapter + * @param PluginManager $tm Table manager + * @param array $cfg Laminas configuration + * @param ?RowGateway $rowObj Row prototype object (null for default) + * @param ?Container $session Session container (must use same + * namespace as container provided to \VuFind\View\Helper\Root\UserList). + * @param string $table Name of database table to interface with + */ + public function __construct( + Adapter $adapter, + PluginManager $tm, + $cfg, + ?RowGateway $rowObj = null, + protected $session = null, + $table = 'finna_resource_list_handler' + ) { + Gateway::__construct($adapter, $tm, $cfg, $rowObj, $table); + $this->session = $session; + } +} diff --git a/module/Finna/src/Finna/ReservationList/ReservationListService.php b/module/Finna/src/Finna/ReservationList/ReservationListService.php index 9f291b0d88e..2ea6471211e 100644 --- a/module/Finna/src/Finna/ReservationList/ReservationListService.php +++ b/module/Finna/src/Finna/ReservationList/ReservationListService.php @@ -35,6 +35,7 @@ use Exception; use Finna\Auth\ILSAuthenticator; use Finna\Db\Entity\FinnaResourceListEntityInterface; +use Finna\Db\Service\FinnaResourceListHandlerServiceInterface; use Finna\Db\Service\FinnaResourceListResourceServiceInterface; use Finna\Db\Service\FinnaResourceListServiceInterface; use Finna\ReservationList\Handler\HandlerInterface; @@ -93,6 +94,7 @@ class ReservationListService implements TranslatorAwareInterface, DbServiceAware * Constructor * * @param FinnaResourceListServiceInterface $resourceListService Resource list database service + * @param FinnaResourceListHandlerServiceInterface $resourceListHandlerService Resource list handler service * @param FinnaResourceListResourceServiceInterface $resourceListResourceService Resource and list relation * database service * @param ResourceServiceInterface $resourceService Resource database service @@ -110,6 +112,7 @@ class ReservationListService implements TranslatorAwareInterface, DbServiceAware */ public function __construct( protected FinnaResourceListServiceInterface $resourceListService, + protected FinnaResourceListHandlerServiceInterface $resourceListHandlerService, protected FinnaResourceListResourceServiceInterface $resourceListResourceService, protected ResourceServiceInterface $resourceService, protected UserServiceInterface $userService, @@ -609,7 +612,7 @@ protected function getListConfig(): array { if (($this->reservationListConfig['Settings']['method'] ??= 'yaml') === 'yaml') { return $this->reservationListConfig; - } elseif ($this->reservationListConfig['Settings']['method'] === 'api') { + } elseif ($this->reservationListConfig['Settings']['method'] === 'database') { $cacheDir = $this->cacheManager->getCache('object')->getOptions()->getCacheDir(); $cacheFile = "$cacheDir/ReservationList.json"; $maxAge = $this->reservationListConfig['Settings']['ttl'] ?? 60; @@ -621,18 +624,26 @@ protected function getListConfig(): array ) { return json_decode($content, true); } - $client = $this->httpService->createClient($this->reservationListConfig['Settings']['url']); - $response = $client->send(); - - if ($response->isSuccess()) { - $config = json_decode($response->getBody(), true); - $config = $config['data']; - // Cache only if ttl is set to over 0 - if ($maxAge > 0) { - file_put_contents($cacheFile, json_encode($config)); + $configuration = [ + 'Institutions' => [ + + ], + ]; + // Get Reservation List handlers from database and cache them into a file + foreach ($this->resourceListHandlerService->getResourceListHandlers() as $handler) { + if (!$handler->getEnabled()) { + continue; } - return $config; + $institution = $handler->getInstitution(); + $handlerAsArray = $handler->toArray(); + $configuration['Institutions'][$institution] ??= ['Lists' => []]; + $configuration['Institutions'][$institution]['Lists'][] = $handlerAsArray; } + // Cache only if ttl is set to over 0 + if ($maxAge > 0) { + file_put_contents($cacheFile, json_encode($configuration)); + } + return $configuration; } return []; } diff --git a/module/Finna/src/Finna/ReservationList/ReservationListServiceFactory.php b/module/Finna/src/Finna/ReservationList/ReservationListServiceFactory.php index 66a31a46c13..ecadced4ffb 100644 --- a/module/Finna/src/Finna/ReservationList/ReservationListServiceFactory.php +++ b/module/Finna/src/Finna/ReservationList/ReservationListServiceFactory.php @@ -62,6 +62,7 @@ public function __invoke(ContainerInterface $container, $name, ?array $options = ->getFinna('ReservationList.yaml', 'config/finna'); return new ReservationListService( $serviceManager->get(\Finna\Db\Service\FinnaResourceListServiceInterface::class), + $serviceManager->get(\Finna\Db\Service\FinnaResourceListHandlerServiceInterface::class), $serviceManager->get(\Finna\Db\Service\FinnaResourceListResourceServiceInterface::class), $serviceManager->get(\VuFind\Db\Service\ResourceServiceInterface::class), $serviceManager->get(\VuFind\Db\Service\UserServiceInterface::class), diff --git a/module/Finna/tests/fixtures/reservationlist/ReservationList_api.yaml b/module/Finna/tests/fixtures/reservationlist/ReservationList_database.yaml similarity index 98% rename from module/Finna/tests/fixtures/reservationlist/ReservationList_api.yaml rename to module/Finna/tests/fixtures/reservationlist/ReservationList_database.yaml index ab6ebad68a6..6aa72efbf1c 100644 --- a/module/Finna/tests/fixtures/reservationlist/ReservationList_api.yaml +++ b/module/Finna/tests/fixtures/reservationlist/ReservationList_database.yaml @@ -1,5 +1,5 @@ Settings: - method: api + method: database url: http//testapi.url.fi/getLists ttl: 0 Institutions: @@ -35,23 +35,6 @@ Institutions: name: sender_test email: sender_email@email.fi Subject: Reservation List - - Identifier: list_with_disec - Enabled: true - Datasources: - - datasource_1 - - datasource_2 - Information: - Address: teststreet 10 - Postal: 000001 - City: Test city - Forms: - PlaceOrder: default - LibraryCardSources: - - connection_established_to_use_lists - Connection: - type: disec - base_url: "http://disectest.url.fi/" - secret: verysecretphrase - Identifier: list_not_enabled Enabled: false Datasources: @@ -89,6 +72,25 @@ Institutions: name: Service sender email: test@noreply.fi Subject: Reservation List + Example Institution 2: + Lists: + - Identifier: list_with_disec + Enabled: true + Datasources: + - datasource_1 + - datasource_2 + Information: + Address: teststreet 10 + Postal: 000001 + City: Test city + Forms: + PlaceOrder: default + LibraryCardSources: + - connection_established_to_use_lists + Connection: + type: disec + base_url: "http://disectest.url.fi/" + secret: verysecretphrase Forms: PlaceOrder: default: diff --git a/module/Finna/tests/unit-tests/src/FinnaTest/ReservationList/ReservationListTest.php b/module/Finna/tests/unit-tests/src/FinnaTest/ReservationList/ReservationListTest.php index 27d95bde7ad..8ced81b4ec1 100644 --- a/module/Finna/tests/unit-tests/src/FinnaTest/ReservationList/ReservationListTest.php +++ b/module/Finna/tests/unit-tests/src/FinnaTest/ReservationList/ReservationListTest.php @@ -34,6 +34,8 @@ use Finna\Auth\ILSAuthenticator; use Finna\Cache\Manager; use Finna\Db\Row\FinnaResourceList; +use Finna\Db\Row\FinnaResourceListHandler; +use Finna\Db\Service\FinnaResourceListHandlerService; use Finna\Db\Service\FinnaResourceListResourceService; use Finna\Db\Service\FinnaResourceListService; use Finna\Db\Service\UserService; @@ -95,9 +97,10 @@ public function setup(): void /** * Get mocked reservation list service * - * @param ?MockObject $mockHttpService Http service - * @param ?MockObject $listPluginManager List plugin manager - * @param array $reservationListConfig Reservation list config + * @param ?MockObject $mockHttpService Http service + * @param ?MockObject $listPluginManager List plugin manager + * @param array $reservationListConfig Reservation list config + * @param ?MockObject $resourceListHandlerService Resource list handler service * * @return MockObject */ @@ -105,6 +108,7 @@ protected function getReservationListService( ?MockObject $mockHttpService = null, ?MockObject $listPluginManager = null, array $reservationListConfig = [], + ?MockObject $resourceListHandlerService = null ): MockObject { $adapterOptions = new FilesystemOptions(); $storage = $this->getMockBuilder(StorageInterface::class)->disableOriginalConstructor()->getMock(); @@ -112,21 +116,23 @@ protected function getReservationListService( $cacheManager = $this->getMockBuilder(Manager::class)->disableOriginalConstructor()->getMock(); $cacheManager->expects($this->any())->method('getCache')->willReturn($storage); $service = $this->getMockBuilder(ReservationListService::class)->onlyMethods(['createListForUser']) - ->setConstructorArgs([ - $this->container->createMock(FinnaResourceListService::class), - $this->container->createMock(FinnaResourceListResourceService::class), - $this->container->createMock(ResourceService::class), - $this->container->createMock(UserService::class), - $this->container->createMock(ResourcePopulator::class), - $this->container->createMock(RecordLoader::class), - $this->container->createMock(Cache::class), - $this->container->createMock(Container::class), - $mockHttpService ??= $this->container->createMock(HttpService::class), - $this->container->createMock(ILSAuthenticator::class), - $cacheManager, - $listPluginManager ??= $this->container->createMock(HandlerPluginManager::class), - $reservationListConfig, - ])->getMock(); + ->setConstructorArgs([ + $this->container->createMock(FinnaResourceListService::class), + $resourceListHandlerService ?? $this->container->createMock(FinnaResourceListHandlerService::class), + $this->container->createMock(FinnaResourceListResourceService::class), + $this->container->createMock(ResourceService::class), + $this->container->createMock(UserService::class), + $this->container->createMock(ResourcePopulator::class), + $this->container->createMock(RecordLoader::class), + $this->container->createMock(Cache::class), + $this->container->createMock(Container::class), + $mockHttpService ??= $this->container->createMock(HttpService::class), + $this->container->createMock(ILSAuthenticator::class), + $cacheManager, + $listPluginManager ??= $this->container->createMock(HandlerPluginManager::class), + $reservationListConfig, + ])->getMock(); + $newListTemplate = $this->getMockBuilder(FinnaResourceList::class)->onlyMethods(['getUser']) ->disableOriginalConstructor()->getMock(); $service->expects($this->any())->method('createListForUser')->willReturnCallback( @@ -788,15 +794,16 @@ public function testEmailPlaceOrder(): void } /** - * Data provider for testgetListHandlerFromApi + * Data provider for testGetListHandlersFromDatabase * * @return Generator */ - public static function getTestGetListHandlerFromApiData(): Generator + public static function getTestGetListHandlerFromDatabaseData(): Generator { - $fixturePath = 'reservationlist/ReservationList_api.yaml'; - yield 'test working url' => [ - true, + $fixturePath = 'reservationlist/ReservationList_database.yaml'; + yield 'test enabled list handler email' => [ + 'list_with_email', + 'Example Institution', $fixturePath, [ 'type' => 'email', @@ -807,44 +814,70 @@ public static function getTestGetListHandlerFromApiData(): Generator 'Subject' => 'Reservation List', ], ]; - yield 'test nonworking url' => [ - false, - $fixturePath, - [], + yield 'test enabled list handler disec' => [ + 'list_with_disec', + 'Example Institution 2', + $fixturePath, + [ + 'type' => 'disec', + 'base_url' => 'http://disectest.url.fi/', + 'secret' => 'verysecretphrase', + ], + ]; + yield 'test disabled list handler' => [ + 'list_not_enabled', + 'Example Institution', + $fixturePath, + [], ]; } /** - * Test list fetch from an api endpoint + * Test list fetch from database * - * @param bool $success Is the request successful - * @param string $fixturePath Fixture path - * @param array $expected Expected results + * @param string $listIdentifier List identifier + * @param string $institution Institution + * @param string $fixturePath Fixture path + * @param array $expected Expected results * * @return void - * @dataProvider getTestgetListHandlerFromApiData + * @dataProvider getTestGetListHandlerFromDatabaseData */ - public function testGetListHandlerFromApi(bool $success, string $fixturePath, array $expected): void - { + public function testGetListHandlersFromDatabase( + string $listIdentifier, + string $institution, + string $fixturePath, + array $expected + ): void { $config = Yaml::parse($this->getFixture($fixturePath, 'Finna')); - $configJSON = json_encode($config); - $urlAndClientMap = [ - $config['Settings']['url'] => [ - 'success' => $success, - 'body' => '{"data":' . $configJSON . '}', - ], - ]; - $httpService = $this->getHttpService($urlAndClientMap); - $listPluginManager = $this->getPluginManager( - httpService: $httpService + + $resourceListHandlerService = $this->getMockBuilder(FinnaResourceListHandlerService::class) + ->disableOriginalConstructor()->getMock(); + $resourceListHandlerService->expects($this->any())->method('getResourceListHandlers')->willReturnCallback( + function () use ($config) { + $handler = $this->getMockBuilder(FinnaResourceListHandler::class) + ->disableOriginalConstructor()->getMock(); + $result = []; + foreach ($config['Institutions'] as $institution => $values) { + $clone = clone $handler; + $clone->expects($this->any())->method('getInstitution')->willReturn($institution); + foreach ($values['Lists'] as $list) { + $clone->expects($this->any())->method('getEnabled')->willReturn($list['Enabled']); + $clone->expects($this->any())->method('toArray')->willReturn($list); + $result[] = $clone; + } + } + return $result; + } ); + $listPluginManager = $this->getPluginManager(); $service = $this->getReservationListService( + resourceListHandlerService: $resourceListHandlerService, listPluginManager: $listPluginManager, reservationListConfig: $config, - mockHttpService: $httpService ); - $listHandler = $service->getListHandler('Example Institution', 'list_with_email'); + $listHandler = $service->getListHandler($institution, $listIdentifier); $this->assertEquals($expected, $listHandler->getConnectionSettings()); - $this->assertEquals($success, $listHandler->isEnabled()); + $this->assertEquals($institution, $listHandler->getInstitution()); } } From 2496325747a8900080b2ee66832dce31d8dd727f Mon Sep 17 00:00:00 2001 From: Juha Luoma <33253757+LuomaJuha@users.noreply.github.com> Date: Mon, 2 Jun 2025 12:48:53 +0300 Subject: [PATCH 2/3] Removed api specific stuff from Service, adjusted code and sample --- local/config/finna/ReservationList.yaml.sample | 6 ++---- .../Finna/ReservationList/ReservationListService.php | 3 --- .../ReservationList/ReservationListServiceFactory.php | 1 - .../FinnaTest/ReservationList/ReservationListTest.php | 10 ++-------- 4 files changed, 4 insertions(+), 16 deletions(-) diff --git a/local/config/finna/ReservationList.yaml.sample b/local/config/finna/ReservationList.yaml.sample index cf8f70aee8c..e9a1ef3b7b7 100644 --- a/local/config/finna/ReservationList.yaml.sample +++ b/local/config/finna/ReservationList.yaml.sample @@ -31,14 +31,12 @@ # # General settings for how to fetch list configurations # Settings: -# Methods available yaml, api. If yaml is selected, will read list configurations from this file, -# method: [yaml, api] -# url: if api is selected, will fetch configurations from api endpoint +# Methods available yaml, database. If yaml is selected, will read list configurations from this file +# method: [yaml, database] # ttl: How long does cached config live, default is 60 minutes # Settings: method: yaml - #url: ttl: 60 Institutions: Example Institution: diff --git a/module/Finna/src/Finna/ReservationList/ReservationListService.php b/module/Finna/src/Finna/ReservationList/ReservationListService.php index 2ea6471211e..785eb56647f 100644 --- a/module/Finna/src/Finna/ReservationList/ReservationListService.php +++ b/module/Finna/src/Finna/ReservationList/ReservationListService.php @@ -59,7 +59,6 @@ use VuFind\Record\ResourcePopulator; use VuFind\RecordDriver\AbstractBase as RecordDriver; use VuFind\RecordDriver\DefaultRecord; -use VuFindHttp\HttpService; /** * Reservation list service @@ -104,7 +103,6 @@ class ReservationListService implements TranslatorAwareInterface, DbServiceAware * @param RecordCache $recordCache Record cache * @param Container $session Session container for remembering * state - * @param HttpService $httpService Http service * @param ILSAuthenticator $ilsAuthenticator Ils authenticator * @param Manager $cacheManager Cache manager * @param PluginManager $listPluginManager Plugin manager for lists @@ -120,7 +118,6 @@ public function __construct( protected RecordLoader $recordLoader, protected RecordCache $recordCache, protected Container $session, - protected HttpService $httpService, protected ILSAuthenticator $ilsAuthenticator, protected Manager $cacheManager, protected PluginManager $listPluginManager, diff --git a/module/Finna/src/Finna/ReservationList/ReservationListServiceFactory.php b/module/Finna/src/Finna/ReservationList/ReservationListServiceFactory.php index ecadced4ffb..995aab6489e 100644 --- a/module/Finna/src/Finna/ReservationList/ReservationListServiceFactory.php +++ b/module/Finna/src/Finna/ReservationList/ReservationListServiceFactory.php @@ -70,7 +70,6 @@ public function __invoke(ContainerInterface $container, $name, ?array $options = $container->get(\Finna\Record\Loader::class), $container->get(\VuFind\Record\Cache::class), $session, - $container->get(\VuFindHttp\HttpService::class), $container->get(\VuFind\Auth\ILSAuthenticator::class), $container->get(\VuFind\Cache\Manager::class), $container->get(PluginManager::class), diff --git a/module/Finna/tests/unit-tests/src/FinnaTest/ReservationList/ReservationListTest.php b/module/Finna/tests/unit-tests/src/FinnaTest/ReservationList/ReservationListTest.php index 8ced81b4ec1..5f7d58f844f 100644 --- a/module/Finna/tests/unit-tests/src/FinnaTest/ReservationList/ReservationListTest.php +++ b/module/Finna/tests/unit-tests/src/FinnaTest/ReservationList/ReservationListTest.php @@ -58,7 +58,6 @@ use VuFind\Db\Service\UserCardServiceInterface; use VuFind\Record\Cache; use VuFind\Record\ResourcePopulator; -use VuFindHttp\HttpService; use VuFindTest\Container\MockContainer; /** @@ -97,7 +96,6 @@ public function setup(): void /** * Get mocked reservation list service * - * @param ?MockObject $mockHttpService Http service * @param ?MockObject $listPluginManager List plugin manager * @param array $reservationListConfig Reservation list config * @param ?MockObject $resourceListHandlerService Resource list handler service @@ -105,7 +103,6 @@ public function setup(): void * @return MockObject */ protected function getReservationListService( - ?MockObject $mockHttpService = null, ?MockObject $listPluginManager = null, array $reservationListConfig = [], ?MockObject $resourceListHandlerService = null @@ -126,7 +123,6 @@ protected function getReservationListService( $this->container->createMock(RecordLoader::class), $this->container->createMock(Cache::class), $this->container->createMock(Container::class), - $mockHttpService ??= $this->container->createMock(HttpService::class), $this->container->createMock(ILSAuthenticator::class), $cacheManager, $listPluginManager ??= $this->container->createMock(HandlerPluginManager::class), @@ -723,8 +719,7 @@ public function testDisecPlaceOrder(): void ); $service = $this->getReservationListService( listPluginManager: $listPluginManager, - reservationListConfig: $reservationListConfig, - mockHttpService: $httpService + reservationListConfig: $reservationListConfig ); $handler = $service->getListHandler('Example Institution', 'list_with_disec'); $testValues = [ @@ -769,8 +764,7 @@ public function testEmailPlaceOrder(): void ); $service = $this->getReservationListService( listPluginManager: $listPluginManager, - reservationListConfig: $reservationListConfig, - mockHttpService: $httpService + reservationListConfig: $reservationListConfig ); $handler = $service->getListHandler('Example Institution', 'list_with_email'); $testValues = [ From 032337650ca29758a240b218fb5ca0c1dda3ea38 Mon Sep 17 00:00:00 2001 From: Juha Luoma <33253757+LuomaJuha@users.noreply.github.com> Date: Mon, 2 Jun 2025 16:59:17 +0300 Subject: [PATCH 3/3] Adjust institution type --- module/Finna/sql/mysql.sql | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/module/Finna/sql/mysql.sql b/module/Finna/sql/mysql.sql index 03ac6fab034..0934b538e69 100644 --- a/module/Finna/sql/mysql.sql +++ b/module/Finna/sql/mysql.sql @@ -352,11 +352,12 @@ CREATE TABLE `finna_resource_list` ( /*!40101 SET character_set_client = utf8mb4 */; CREATE TABLE `finna_resource_list_handler` ( `id` int(11) NOT NULL AUTO_INCREMENT, - `institution` int(10) unsigned NOT NULL, + `institution` varchar(255) NOT NULL, `identifier` varchar(255) NOT NULL, `enabled` int(1) NOT NULL DEFAULT 0, `data` json DEFAULT '', `created` datetime NOT NULL DEFAULT '2000-01-01 00:00:00', + `published` datetime NOT NULL DEFAULT '2000-01-01 00:00:00', PRIMARY KEY (`id`), KEY `institution` (`institution`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;