diff --git a/Tests/Fixtures/Common/pages.csv b/Tests/Fixtures/Common/pages.csv new file mode 100644 index 000000000..b8ec5a4ed --- /dev/null +++ b/Tests/Fixtures/Common/pages.csv @@ -0,0 +1,4 @@ +pages,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,uid,pid,tstamp,crdate,cruser_id,deleted,hidden,starttime,endtime,fe_group,sorting,rowDescription,editlock,sys_language_uid,l10n_parent,l10n_source,t3_origuid,l10n_diffsource,t3ver_oid,t3ver_wsid,t3ver_state,t3ver_stage,perms_userid,perms_groupid,perms_user,perms_group,perms_everybody,title,slug,doktype,TSconfig,is_siteroot,php_tree_stop,url,shortcut,shortcut_mode,subtitle,layout,target,media,lastUpdated,keywords,cache_timeout,cache_tags,newUntil,description,no_search,SYS_LASTCHANGED,abstract,module,extendToSubpages,author,author_email,nav_title,nav_hide,content_from_pid,mount_pid,mount_pid_ol,l18n_cfg,fe_login_mode,backend_layout,backend_layout_next_level,tsconfig_includes,categories +,19999,0,1644840191,1644840051,1,0,0,0,0,,764,,0,0,0,0,0,a:47:{s:7:"doktype";N;s:5:"title";N;s:4:"slug";N;s:9:"nav_title";N;s:8:"subtitle";N;s:9:"seo_title";N;s:8:"no_index";N;s:9:"no_follow";N;s:14:"canonical_link";N;s:8:"og_title";N;s:14:"og_description";N;s:8:"og_image";N;s:13:"twitter_title";N;s:19:"twitter_description";N;s:13:"twitter_image";N;s:8:"abstract";N;s:8:"keywords";N;s:11:"description";N;s:6:"author";N;s:12:"author_email";N;s:11:"lastUpdated";N;s:6:"layout";N;s:8:"newUntil";N;s:14:"backend_layout";N;s:25:"backend_layout_next_level";N;s:16:"content_from_pid";N;s:6:"target";N;s:13:"cache_timeout";N;s:10:"cache_tags";N;s:11:"is_siteroot";N;s:9:"no_search";N;s:13:"php_tree_stop";N;s:6:"module";N;s:5:"media";N;s:17:"tsconfig_includes";N;s:8:"TSconfig";N;s:8:"l18n_cfg";N;s:6:"hidden";N;s:8:"nav_hide";N;s:9:"starttime";N;s:7:"endtime";N;s:16:"extendToSubpages";N;s:8:"fe_group";N;s:13:"fe_login_mode";N;s:8:"editlock";N;s:10:"categories";N;s:14:"rowDescription";N;},0,0,0,0,1,0,31,27,0,DLF Testing Site,,254,,1,0,,0,0,,0,,0,0,,0,,0,,0,1644840191,,,0,,,,0,0,0,0,0,0,,,,0 +,20000,19999,1644840191,1644840051,1,0,0,0,0,,764,,0,0,0,0,0,a:47:{s:7:"doktype";N;s:5:"title";N;s:4:"slug";N;s:9:"nav_title";N;s:8:"subtitle";N;s:9:"seo_title";N;s:8:"no_index";N;s:9:"no_follow";N;s:14:"canonical_link";N;s:8:"og_title";N;s:14:"og_description";N;s:8:"og_image";N;s:13:"twitter_title";N;s:19:"twitter_description";N;s:13:"twitter_image";N;s:8:"abstract";N;s:8:"keywords";N;s:11:"description";N;s:6:"author";N;s:12:"author_email";N;s:11:"lastUpdated";N;s:6:"layout";N;s:8:"newUntil";N;s:14:"backend_layout";N;s:25:"backend_layout_next_level";N;s:16:"content_from_pid";N;s:6:"target";N;s:13:"cache_timeout";N;s:10:"cache_tags";N;s:11:"is_siteroot";N;s:9:"no_search";N;s:13:"php_tree_stop";N;s:6:"module";N;s:5:"media";N;s:17:"tsconfig_includes";N;s:8:"TSconfig";N;s:8:"l18n_cfg";N;s:6:"hidden";N;s:8:"nav_hide";N;s:9:"starttime";N;s:7:"endtime";N;s:16:"extendToSubpages";N;s:8:"fe_group";N;s:13:"fe_login_mode";N;s:8:"editlock";N;s:10:"categories";N;s:14:"rowDescription";N;},0,0,0,0,1,0,31,27,0,Data,/data,254,,0,0,,0,0,,0,,0,0,,0,,0,,0,1644840191,,,0,,,,0,0,0,0,0,0,,,,0 diff --git a/Tests/Fixtures/Common/solrcores.csv b/Tests/Fixtures/Common/solrcores.csv new file mode 100644 index 000000000..ce3386f10 --- /dev/null +++ b/Tests/Fixtures/Common/solrcores.csv @@ -0,0 +1,4 @@ +"tx_dlf_solrcores",,,,,,,, +,"uid","pid","tstamp","crdate","cruser_id","deleted","label","index_name" +,4,0,1631254345,1631186030,1,0,"Common Solr Testing Core", +,5,0,1631254346,1631186030,1,0,"Common Solr Testing Core 2", diff --git a/Tests/Functional/Api/OaiPmhTest.php b/Tests/Functional/Api/OaiPmhTest.php index ed5a3550a..01ac83acd 100644 --- a/Tests/Functional/Api/OaiPmhTest.php +++ b/Tests/Functional/Api/OaiPmhTest.php @@ -47,7 +47,7 @@ public function setUp(): void $this->importCSVDataSet(__DIR__ . '/../../Fixtures/Common/documents_1.csv'); $this->importCSVDataSet(__DIR__ . '/../../Fixtures/Common/metadata.csv'); $this->importCSVDataSet(__DIR__ . '/../../Fixtures/Common/libraries.csv'); - $this->importDataSet(__DIR__ . '/../../Fixtures/Common/pages.xml'); + $this->importCSVDataSet(__DIR__ . '/../../Fixtures/Common/pages.csv'); $this->importDataSet(__DIR__ . '/../../Fixtures/OaiPmh/pages.xml'); $this->importCSVDataSet(__DIR__ . '/../../Fixtures/OaiPmh/solrcores.csv'); diff --git a/Tests/Functional/Common/SolrIndexingTest.php b/Tests/Functional/Common/SolrIndexingTest.php index aa29ccb63..25937f933 100644 --- a/Tests/Functional/Common/SolrIndexingTest.php +++ b/Tests/Functional/Common/SolrIndexingTest.php @@ -152,6 +152,16 @@ public function canSearchInCollections() self::assertGreaterThan($metadataSearch->getNumFound(), $fulltextSearch->getNumFound()); } + /** + * @test + */ + public function canGetIndexFieldName() + { + $this->assertEquals('title_usi', Indexer::getIndexFieldName('title', 20000)); + $this->assertEquals('year_uuu', Indexer::getIndexFieldName('year', 20000)); + $this->assertEquals('', Indexer::getIndexFieldName('title')); + } + protected function createSolrCore(): object { $coreName = Solr::createCore(); diff --git a/Tests/Functional/Common/SolrSearchQueryTest.php b/Tests/Functional/Common/SolrSearchQueryTest.php new file mode 100644 index 000000000..fe145bb32 --- /dev/null +++ b/Tests/Functional/Common/SolrSearchQueryTest.php @@ -0,0 +1,93 @@ + + * + * This file is part of the Kitodo and TYPO3 projects. + * + * @license GNU General Public License version 3 or later. + * For the full copyright and license information, please read the + * LICENSE.txt file that was distributed with this source code. + */ + +namespace Kitodo\Dlf\Tests\Functional\Common; + +use Kitodo\Dlf\Common\Solr\Solr; +use Kitodo\Dlf\Common\Solr\SolrSearch; +use Kitodo\Dlf\Domain\Repository\DocumentRepository; +use Kitodo\Dlf\Domain\Repository\SolrCoreRepository; +use Kitodo\Dlf\Tests\Functional\FunctionalTestCase; +use TYPO3\CMS\Extbase\Persistence\Generic\PersistenceManager; + +class SolrSearchQueryTest extends FunctionalTestCase +{ + + private static array $databaseFixtures = [ + __DIR__ . '/../../Fixtures/Common/documents_1.csv', + __DIR__ . '/../../Fixtures/Common/pages.csv', + __DIR__ . '/../../Fixtures/Common/solrcores.csv' + ]; + + private static array $solrFixtures = [ + __DIR__ . '/../../Fixtures/Common/documents_1.solr.json' + ]; + + public function setUp(): void + { + parent::setUp(); + $this->setUpData(self::$databaseFixtures); + $this->setUpSolr(4, 0, self::$solrFixtures); + } + + /** + * @test + * @ignore + */ + public function canExecute() + { + $documentRepository = $this->initializeRepository(DocumentRepository::class, 0); + $settings = ['solrcore' => 4, 'storagePid' => 0]; + + $params = ['query' => '10 Keyboard pieces']; + $search = new SolrSearch($documentRepository, null, $settings, $params); + $search->prepare(); + $solrSearchQuery = $search->getQuery(); + $result = $solrSearchQuery->execute(); + // FIXME: test would fail because it is not possible to set $this->settings['storagePid'] for the + // documentRepository used in DocumentRepository.php:502 + + $this->assertCount(0, $result); + $this->assertEquals(0, $solrSearchQuery->getLimit()); + } + + protected function setUpData($databaseFixtures): void + { + foreach ($databaseFixtures as $filePath) { + $this->importCSVDataSet($filePath); + } + $this->persistenceManager = $this->objectManager->get(PersistenceManager::class); + $this->initializeRepository(DocumentRepository::class, 0); + } + + protected function setUpSolr($uid, $storagePid, $solrFixtures) + { + $this->solrCoreRepository = $this->initializeRepository(SolrCoreRepository::class, $storagePid); + + // Setup Solr only once for all tests in this suite + static $solr = null; + + if ($solr === null) { + $coreName = Solr::createCore(); + $solr = Solr::getInstance($coreName); + foreach ($solrFixtures as $filePath) { + $this->importSolrDocuments($solr, $filePath); + } + } + + $coreModel = $this->solrCoreRepository->findByUid($uid); + $coreModel->setIndexName($solr->core); + $this->solrCoreRepository->update($coreModel); + $this->persistenceManager->persistAll(); + return $solr; + } +} diff --git a/Tests/Functional/Common/SolrSearchTest.php b/Tests/Functional/Common/SolrSearchTest.php new file mode 100644 index 000000000..4029823f5 --- /dev/null +++ b/Tests/Functional/Common/SolrSearchTest.php @@ -0,0 +1,106 @@ + + * + * This file is part of the Kitodo and TYPO3 projects. + * + * @license GNU General Public License version 3 or later. + * For the full copyright and license information, please read the + * LICENSE.txt file that was distributed with this source code. + */ + +namespace Kitodo\Dlf\Tests\Functional\Common; + +use Kitodo\Dlf\Common\Solr\Solr; +use Kitodo\Dlf\Common\Solr\SolrSearch; +use Kitodo\Dlf\Domain\Repository\DocumentRepository; +use Kitodo\Dlf\Domain\Repository\SolrCoreRepository; +use Kitodo\Dlf\Tests\Functional\FunctionalTestCase; +use TYPO3\CMS\Extbase\Persistence\Generic\PersistenceManager; + +class SolrSearchTest extends FunctionalTestCase +{ + private static array $databaseFixtures = [ + __DIR__ . '/../../Fixtures/Common/solrcores.csv' + ]; + + private static array $solrFixtures = [ + __DIR__ . '/../../Fixtures/Common/documents_1.solr.json' + ]; + + private Solr $solr; + private SolrCoreRepository $solrCoreRepository; + + public function setUp(): void + { + parent::setUp(); + $this->setUpData(self::$databaseFixtures); + $this->solr = $this->setUpSolr(5, 0, self::$solrFixtures); + } + + /** + * @test + */ + public function canPrepareAndSubmit() + { + $documentRepository = $this->initializeRepository(DocumentRepository::class, 0); + $solrCoreName = $this->solrCoreRepository->findByUid(5)->getIndexName(); + $settings = ['solrcore' => $solrCoreName, 'storagePid' => 0]; + + $resultSet = $this->solr->searchRaw(['core' => 5, 'collection' => 1]); + $this->assertCount(33, $resultSet); + + $params1 = ['query' => '*']; + $search = new SolrSearch($documentRepository, null, $settings, $params1); + $search->prepare(); + $this->assertEquals(33, $search->getNumFound()); + $this->assertEquals(3, $search->getSolrResults()['numberOfToplevels']); + $this->assertCount(15, $search->getSolrResults()['documents']); + + $params2 = ['query' => '10 Keyboard pieces']; + $search2 = new SolrSearch($documentRepository, null, $settings, $params2); + $search2->prepare(); + $this->assertEquals(1, $search2->getNumFound()); + $this->assertEquals(1, $search2->getSolrResults()['numberOfToplevels']); + $this->assertCount(1, $search2->getSolrResults()['documents']); + + $params3 = ['query' => 'foobar']; + $search3 = new SolrSearch($documentRepository, null, $settings, $params3); + $search3->prepare(); + $this->assertEquals(0, $search3->getNumFound()); + $this->assertEquals(0, $search3->getSolrResults()['numberOfToplevels']); + $this->assertCount(0, $search3->getSolrResults()['documents']); + } + + protected function setUpData($databaseFixtures): void + { + foreach ($databaseFixtures as $filePath) { + $this->importCSVDataSet($filePath); + } + $this->persistenceManager = $this->objectManager->get(PersistenceManager::class); + $this->initializeRepository(DocumentRepository::class, 0); + } + + protected function setUpSolr($uid, $storagePid, $solrFixtures) + { + $this->solrCoreRepository = $this->initializeRepository(SolrCoreRepository::class, $storagePid); + + // Setup Solr only once for all tests in this suite + static $solr = null; + + if ($solr === null) { + $coreName = Solr::createCore(); + $solr = Solr::getInstance($coreName); + foreach ($solrFixtures as $filePath) { + $this->importSolrDocuments($solr, $filePath); + } + } + + $coreModel = $this->solrCoreRepository->findByUid($uid); + $coreModel->setIndexName($solr->core); + $this->solrCoreRepository->update($coreModel); + $this->persistenceManager->persistAll(); + return $solr; + } +} diff --git a/Tests/Functional/Common/SolrTest.php b/Tests/Functional/Common/SolrTest.php new file mode 100644 index 000000000..4a597bcf9 --- /dev/null +++ b/Tests/Functional/Common/SolrTest.php @@ -0,0 +1,118 @@ + + * + * This file is part of the Kitodo and TYPO3 projects. + * + * @license GNU General Public License version 3 or later. + * For the full copyright and license information, please read the + * LICENSE.txt file that was distributed with this source code. + */ + +namespace Kitodo\Dlf\Tests\Functional\Common; + +use Kitodo\Dlf\Common\Solr\Solr; +use Kitodo\Dlf\Domain\Repository\DocumentRepository; +use Kitodo\Dlf\Domain\Repository\SolrCoreRepository; +use Kitodo\Dlf\Tests\Functional\FunctionalTestCase; +use TYPO3\CMS\Extbase\Persistence\Generic\PersistenceManager; + +class SolrTest extends FunctionalTestCase +{ + + private static array $databaseFixtures = [ + __DIR__ . '/../../Fixtures/Common/documents_1.csv', + __DIR__ . '/../../Fixtures/Common/pages.csv', + __DIR__ . '/../../Fixtures/Common/solrcores.csv' + ]; + + private static array $solrFixtures = [ + __DIR__ . '/../../Fixtures/Common/documents_1.solr.json' + ]; + + /** + * @test + */ + public function canCreateCore() + { + $this->assertEquals('newCoreName', Solr::createCore('newCoreName')); + $this->assertEquals('newCoreName', Solr::getInstance('newCoreName')->core); + } + + /** + * @test + */ + public function canEscapeQuery() + { + $query1 = Solr::escapeQuery('"custom query with special characters: "testvalue"\n"'); + $this->assertEquals('"custom query with special characters\: "testvalue"\\\\n"', $query1); + + $query2 = Solr::escapeQuery('+ - && || ! ( ) { } [ ] ^ " ~ * ? : \ /'); + $this->assertEquals('+ - && || ! ( ) \{ \} \[ \] ^ " ~ * ? \: \\\ \/', $query2); + } + + /** + * @test + */ + public function canEscapeQueryKeepField() + { + $query1 = Solr::escapeQueryKeepField('abc_uui:(abc)', 0); + $this->assertEquals('abc_uui\:(abc)', $query1); + } + + /** + * @test + */ + public function canGetNextCoreNumber() + { + $this->assertEquals(5, Solr::getNextCoreNumber()); + $this->assertEquals(5, Solr::getNextCoreNumber()); + Solr::createCore(); + $this->assertEquals(6, Solr::getNextCoreNumber()); + } + + /** + * @test + */ + public function canSearchRaw() + { + $this->setUpData(self::$databaseFixtures); + $solr = $this->setUpSolr(4, 0, self::$solrFixtures); + $resultSet = $solr->searchRaw(['core' => 4, 'collection' => 1]); + + $this->assertCount(33, $resultSet); + $this->assertEquals('Solarium\QueryType\Select\Result\Document', get_class($resultSet[0])); + } + + protected function setUpData($databaseFixtures): void + { + foreach ($databaseFixtures as $filePath) { + $this->importCSVDataSet($filePath); + } + $this->persistenceManager = $this->objectManager->get(PersistenceManager::class); + $this->initializeRepository(DocumentRepository::class, 0); + } + + protected function setUpSolr($uid, $storagePid, $solrFixtures) + { + $this->solrCoreRepository = $this->initializeRepository(SolrCoreRepository::class, $storagePid); + + // Setup Solr only once for all tests in this suite + static $solr = null; + + if ($solr === null) { + $coreName = Solr::createCore(); + $solr = Solr::getInstance($coreName); + foreach ($solrFixtures as $filePath) { + $this->importSolrDocuments($solr, $filePath); + } + } + + $coreModel = $this->solrCoreRepository->findByUid($uid); + $coreModel->setIndexName($solr->core); + $this->solrCoreRepository->update($coreModel); + $this->persistenceManager->persistAll(); + return $solr; + } +}