diff --git a/Tests/Fixtures/Repository/collections.xml b/Tests/Fixtures/Repository/collections.xml
new file mode 100644
index 000000000..cb42c2339
--- /dev/null
+++ b/Tests/Fixtures/Repository/collections.xml
@@ -0,0 +1,116 @@
+
+
+
+
+ 1101
+ 20000
+ 1631279509
+ 1631279509
+ 2
+ 0
+ 0
+ 0
+
+ a:8:{s:5:"label";N;s:10:"index_name";N;s:8:"oai_name";N;s:11:"description";N;s:9:"documents";N;s:5:"owner";N;s:6:"status";N;s:16:"sys_language_uid";N;}
+
+ 0
+
+ 0
+ 0
+
+ Musik
+
+ music
+
+
+ 3
+ 0
+ 0
+ 0
+
+
+
+ 1102
+ 20000
+ 1631279509
+ 1631279509
+ 2
+ 0
+ 0
+ 0
+
+ a:8:{s:5:"label";N;s:10:"index_name";N;s:8:"oai_name";N;s:11:"description";N;s:9:"documents";N;s:5:"owner";N;s:6:"status";N;s:16:"sys_language_uid";N;}
+
+ 0
+
+ 0
+ 0
+
+ collection-with-single-document
+
+ collection-with-single-document
+
+
+ 4
+ 0
+ 0
+ 0
+
+
+
+ 1103
+ 20000
+ 1631279509
+ 1631279509
+ 2
+ 0
+ 0
+ 0
+
+ a:8:{s:5:"label";N;s:10:"index_name";N;s:8:"oai_name";N;s:11:"description";N;s:9:"documents";N;s:5:"owner";N;s:6:"status";N;s:16:"sys_language_uid";N;}
+
+ 0
+
+ 1
+ 0
+
+ Geschichte
+ *:*
+ history
+
+
+ 3
+ 0
+ 0
+ 0
+
+
+
+ 1104
+ 20000
+ 1631279509
+ 1631279509
+ 2
+ 0
+ 0
+ 0
+
+ a:8:{s:5:"label";N;s:10:"index_name";N;s:8:"oai_name";N;s:11:"description";N;s:9:"documents";N;s:5:"owner";N;s:6:"status";N;s:16:"sys_language_uid";N;}
+
+ 0
+
+ 1
+ 0
+
+ bildende-kunst
+
+
+
+
+ 4
+ 0
+ 0
+ 0
+
+
+
diff --git a/Tests/Fixtures/Repository/mail.xml b/Tests/Fixtures/Repository/mail.xml
new file mode 100644
index 000000000..6cfb51dad
--- /dev/null
+++ b/Tests/Fixtures/Repository/mail.xml
@@ -0,0 +1,39 @@
+
+
+
+ 101
+ 30000
+ 0
+ 10
+ Mail
+ Name
+
+
+
+ 102
+ 30000
+ 0
+ 10
+ Mail
+ Name
+
+
+
+ 103
+ 20000
+ 0
+ 10
+ Mail
+ Name
+
+
+
+ 104
+ 20000
+ 0
+ 10
+ Mail
+ Name
+
+
+
diff --git a/Tests/Fixtures/Repository/metadata.xml b/Tests/Fixtures/Repository/metadata.xml
new file mode 100644
index 000000000..5c012c908
--- /dev/null
+++ b/Tests/Fixtures/Repository/metadata.xml
@@ -0,0 +1,223 @@
+
+
+
+ 5001
+ 20000
+ 1638557803
+ 1631532810
+ 1
+ 0
+ 0
+ 0
+
+ 0
+ 32
+
+ title
+ 1
+
+
+ 0
+ 1
+ 1
+ 1
+ 1
+ 0
+ 1
+ 1
+ 0
+
+
+
+ 5002
+ 20000
+ 1638557803
+ 1631532810
+ 1
+ 0
+ 0
+ 0
+
+ 0
+ 31
+
+ collection
+ 1
+
+
+ 1
+ 0
+ 1
+ 1
+ 0
+ 1
+ 0
+ 1
+ 0
+
+
+
+ 5003
+ 20000
+ 1638557803
+ 1631532810
+ 1
+ 0
+ 0
+ 0
+
+ 0
+ 30
+
+ untertitel
+ 1
+
+
+ 0
+ 1
+ 1
+ 1
+ 1
+ 0
+ 0
+ 1
+ 0
+
+
+
+ 5004
+ 20000
+ 1638557803
+ 1631532810
+ 1
+ 0
+ 0
+ 0
+
+ 0
+ 29
+
+ ort
+ 1
+
+
+ 0
+ 1
+ 1
+ 1
+ 1
+ 0
+ 0
+ 1
+ 0
+
+
+
+ 5005
+ 20000
+ 1638557803
+ 1631532810
+ 1
+ 0
+ 0
+ 0
+
+ 0
+ 30
+
+ autor
+ 1
+
+
+ 0
+ 1
+ 1
+ 1
+ 1
+ 0
+ 1
+ 1
+ 0
+
+
+
+ 5006
+ 20000
+ 1638557803
+ 1631532810
+ 1
+ 0
+ 0
+ 0
+
+ 0
+ 30
+
+ institution
+ 1
+
+
+ 0
+ 1
+ 1
+ 1
+ 0
+ 0
+ 1
+ 1
+ 0
+
+
+
+ 5101
+ 20000
+ 1638557803
+ 1631532810
+ 1
+ 0
+ 5001
+ 5202
+ concat(./mods:titleInfo/mods:nonSort," ",./mods:titleInfo/mods:title)
+ ./mods:titleInfo/mods:title
+ 0
+
+
+
+ 5102
+ 20000
+ 1638557803
+ 1631532810
+ 1
+ 0
+ 5002
+ 5202
+ ./mods:relatedItem[@type="series"]/mods:titleInfo/mods:title[@lang="ger"]
+
+ 0
+
+
+
+ 5201
+ 0
+ 1638557803
+ 1631532810
+ 1
+ 0
+ ALTO
+ alto
+ http://www.loc.gov/standards/alto/ns-v2#
+ Kitodo\Dlf\Format\Alto
+
+
+ 5202
+ 0
+ 1638557803
+ 1631532810
+ 1
+ 0
+ MODS
+ mods
+ http://www.loc.gov/mods/v3
+ Kitodo\Dlf\Format\Mods
+
+
diff --git a/Tests/Fixtures/Repository/token.xml b/Tests/Fixtures/Repository/token.xml
new file mode 100644
index 000000000..1d226f25b
--- /dev/null
+++ b/Tests/Fixtures/Repository/token.xml
@@ -0,0 +1,35 @@
+
+
+
+ 101
+ 20000
+ 1631279509
+ token101
+ Options text 101
+ ident1
+
+
+ 102
+ 20000
+ 1631289509
+ token102
+ Options text 102
+ ident1
+
+
+ 103
+ 20000
+ 1631279509
+ token103
+ Options text 103
+ ident1
+
+
+ 104
+ 20000
+ 1631281509
+ token104
+ Options text 104
+ ident1
+
+
diff --git a/Tests/Functional/Repository/CollectionRepositoryTest.php b/Tests/Functional/Repository/CollectionRepositoryTest.php
new file mode 100644
index 000000000..ac7149e6b
--- /dev/null
+++ b/Tests/Functional/Repository/CollectionRepositoryTest.php
@@ -0,0 +1,200 @@
+
+ *
+ * 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\Repository;
+
+use TYPO3\CMS\Extbase\Persistence\Generic\QueryResult;
+use Kitodo\Dlf\Domain\Repository\CollectionRepository;
+use Kitodo\Dlf\Tests\Functional\FunctionalTestCase;
+
+class CollectionRepositoryTest extends FunctionalTestCase
+{
+ /**
+ * @var CollectionRepository
+ */
+ protected $collectionRepository;
+
+ public function setUp(): void
+ {
+ parent::setUp();
+
+ $this->collectionRepository = $this->initializeRepository(
+ CollectionRepository::class,
+ 20000
+ );
+
+ $this->importDataSet(__DIR__ . '/../../Fixtures/Repository/collections.xml');
+ }
+
+ /**
+ *
+ * @group find
+ */
+ public function canFindAllByUids(): void
+ {
+ $collections = $this->collectionRepository->findAllByUids([1101, 1102]);
+ $this->assertNotNull($collections);
+ $this->assertInstanceOf(QueryResult::class, $collections);
+
+ $collectionsByLabel = [];
+ foreach ($collections as $collection) {
+ $collectionsByLabel[$collection->getLabel()] = $collection;
+ }
+
+ $this->assertArrayHasKey('Musik', $collectionsByLabel);
+ $this->assertArrayHasKey('Collection with single document', $collectionsByLabel);
+ }
+
+ /**
+ * @test
+ * @group find
+ */
+ public function canGetCollectionForMetadata(): void
+ {
+ $collections = $this->collectionRepository->getCollectionForMetadata("20000");
+ $this->assertNotNull($collections);
+ $this->assertInstanceOf(QueryResult::class, $collections);
+
+ $collectionsByLabel = [];
+ foreach ($collections as $collection) {
+ $collectionsByLabel[$collection->getLabel()] = $collection;
+ }
+
+ $this->assertArrayHasKey('Musik', $collectionsByLabel);
+ $this->assertArrayHasKey('Collection with single document', $collectionsByLabel);
+ $this->assertArrayHasKey('Geschichte', $collectionsByLabel);
+ $this->assertArrayHasKey('Bildende Kunst', $collectionsByLabel);
+ }
+
+ /**
+ * @param $settings
+ * @return array
+ */
+ protected function findCollectionsBySettings($settings): array
+ {
+ $collections = $this->collectionRepository->findCollectionsBySettings($settings);
+ $this->assertNotNull($collections);
+ $this->assertInstanceOf(QueryResult::class, $collections);
+
+ $collectionsByLabel = [];
+ foreach ($collections as $collection) {
+ $collectionsByLabel[$collection->getLabel()] = $collection;
+ }
+
+ return $collectionsByLabel;
+ }
+
+ /**
+ * @test
+ * @group find
+ */
+ public function canFindCollectionsBySettings(): void
+ {
+ $collectionsByLabel = $this->findCollectionsBySettings(['collections' => '1101, 1102']);
+ $this->assertCount(2, $collectionsByLabel);
+ $this->assertArrayHasKey('Collection with single document', $collectionsByLabel);
+ $this->assertArrayHasKey('Musik', $collectionsByLabel);
+
+ $collectionsByLabel = $this->findCollectionsBySettings(
+ [
+ 'index_name' => ['Geschichte', 'collection-with-single-document'],
+ 'show_userdefined' => true
+ ]
+ );
+ $this->assertCount(2, $collectionsByLabel);
+ $this->assertArrayHasKey('Geschichte', $collectionsByLabel);
+ $this->assertArrayHasKey('Collection with single document', $collectionsByLabel);
+
+ $collectionsByLabel = $this->findCollectionsBySettings(['show_userdefined' => true]);
+ $this->assertCount(4, $collectionsByLabel);
+ $this->assertArrayHasKey('Musik', $collectionsByLabel);
+ $this->assertArrayHasKey('Collection with single document', $collectionsByLabel);
+ $this->assertArrayHasKey('Geschichte', $collectionsByLabel);
+ $this->assertArrayHasKey('Bildende Kunst', $collectionsByLabel);
+ $this->assertEquals(
+ 'Bildende Kunst, Collection with single document, Geschichte, Musik',
+ implode(', ', array_keys($collectionsByLabel))
+ );
+
+ $collectionsByLabel = $this->findCollectionsBySettings(['show_userdefined' => false]);
+ $this->assertCount(2, $collectionsByLabel);
+ $this->assertArrayHasKey('Musik', $collectionsByLabel);
+ $this->assertArrayHasKey('Collection with single document', $collectionsByLabel);
+
+ $collectionsByLabel = $this->findCollectionsBySettings(['hideEmptyOaiNames' => true]);
+ $this->assertCount(2, $collectionsByLabel);
+ $this->assertArrayHasKey('Musik', $collectionsByLabel);
+ $this->assertArrayHasKey('Collection with single document', $collectionsByLabel);
+
+ $collectionsByLabel = $this->findCollectionsBySettings(
+ [
+ 'hideEmptyOaiNames' => true,
+ 'show_userdefined' => true
+ ]
+ );
+ $this->assertCount(3, $collectionsByLabel);
+ $this->assertArrayHasKey('Musik', $collectionsByLabel);
+ $this->assertArrayHasKey('Collection with single document', $collectionsByLabel);
+ $this->assertArrayHasKey('Geschichte', $collectionsByLabel);
+
+ $collectionsByLabel = $this->findCollectionsBySettings(
+ [
+ 'hideEmptyOaiNames' => false,
+ 'show_userdefined' => true
+ ]
+ );
+ $this->assertCount(4, $collectionsByLabel);
+ $this->assertArrayHasKey('Musik', $collectionsByLabel);
+ $this->assertArrayHasKey('Collection with single document', $collectionsByLabel);
+ $this->assertArrayHasKey('Geschichte', $collectionsByLabel);
+ $this->assertArrayHasKey('Bildende Kunst', $collectionsByLabel);
+
+ $collectionsByLabel = $this->findCollectionsBySettings(
+ [
+ 'collections' => '1101, 1102, 1103, 1104',
+ 'show_userdefined' => true,
+ 'hideEmptyOaiNames' => false,
+ 'index_name' => ['Geschichte', 'collection-with-single-document']
+ ]
+ );
+
+ $this->assertCount(2, $collectionsByLabel);
+ $this->assertArrayHasKey('Collection with single document', $collectionsByLabel);
+ $this->assertArrayHasKey('Geschichte', $collectionsByLabel);
+ }
+
+ /**
+ * @test
+ * @group find
+ */
+ public function canGetIndexNameForSolr(): void
+ {
+ $indexName = $this->collectionRepository->getIndexNameForSolr(
+ ['show_userdefined' => true, 'storagePid' => '20000'], 'history'
+ );
+ $result = $indexName->fetchAllAssociative();
+ $this->assertEquals(1, $indexName->rowCount());
+ $this->assertEquals('Geschichte', $result[0]['index_name']);
+ $this->assertEquals('*:*', $result[0]['index_query']);
+ $this->assertEquals('1103', $result[0]['uid']);
+
+ $indexName = $this->collectionRepository->getIndexNameForSolr(
+ ['show_userdefined' => false, 'storagePid' => '20000'], 'history'
+ );
+ $this->assertEquals(0, $indexName->rowCount());
+
+ $indexName = $this->collectionRepository->getIndexNameForSolr(
+ ['show_userdefined' => false, 'storagePid' => '20000'], 'collection-with-single-document'
+ );
+ $this->assertEquals(1, $indexName->rowCount());
+ $this->assertEquals('collection-with-single-document', $indexName->fetchOne());
+ }
+}
diff --git a/Tests/Functional/Repository/MailRepositoryTest.php b/Tests/Functional/Repository/MailRepositoryTest.php
new file mode 100644
index 000000000..5aff084f7
--- /dev/null
+++ b/Tests/Functional/Repository/MailRepositoryTest.php
@@ -0,0 +1,56 @@
+
+ *
+ * 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\Repository;
+
+use TYPO3\CMS\Extbase\Persistence\Generic\QueryResult;
+use Kitodo\Dlf\Domain\Repository\MailRepository;
+use Kitodo\Dlf\Tests\Functional\FunctionalTestCase;
+
+class MailRepositoryTest extends FunctionalTestCase
+{
+ /**
+ * @var MailRepository
+ */
+ protected $mailRepository;
+
+ public function setUp(): void
+ {
+ parent::setUp();
+
+ $this->mailRepository = $this->initializeRepository(
+ MailRepository::class,
+ 20000
+ );
+
+ $this->importDataSet(__DIR__ . '/../../Fixtures/Repository/mail.xml');
+ }
+
+ /**
+ * @test
+ * @group find
+ */
+ public function canFindAllWithPid(): void
+ {
+ $mails = $this->mailRepository->findAllWithPid(30000);
+ $this->assertNotNull($mails);
+ $this->assertInstanceOf(QueryResult::class, $mails);
+
+ $mailByLabel = [];
+ foreach ($mails as $mail) {
+ $mailByLabel[$mail->getLabel()] = $mail;
+ }
+
+ $this->assertEquals(2, $mails->count());
+ $this->assertArrayHasKey('Mail-Label-1', $mailByLabel);
+ $this->assertArrayHasKey('Mail-Label-2', $mailByLabel);
+ }
+}
diff --git a/Tests/Functional/Repository/MetatdataRepositoryTest.php b/Tests/Functional/Repository/MetatdataRepositoryTest.php
new file mode 100644
index 000000000..0e78feec0
--- /dev/null
+++ b/Tests/Functional/Repository/MetatdataRepositoryTest.php
@@ -0,0 +1,95 @@
+
+ *
+ * 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\Repository;
+
+use TYPO3\CMS\Extbase\Persistence\Generic\QueryResult;
+use Kitodo\Dlf\Domain\Repository\MetadataRepository;
+use Kitodo\Dlf\Tests\Functional\FunctionalTestCase;
+
+class MetadataRepositoryTest extends FunctionalTestCase
+{
+ /**
+ * @var MetadataRepository
+ */
+ protected $metadataRepository;
+
+ public function setUp(): void
+ {
+ parent::setUp();
+
+ $this->metadataRepository = $this->initializeRepository(
+ MetadataRepository::class,
+ 20000
+ );
+
+ $this->importDataSet(__DIR__ . '/../../Fixtures/Repository/metadata.xml');
+ }
+
+
+ /**
+ * @param $settings
+ * @return array
+ */
+ protected function findBySettings($settings)
+ {
+ $metadata = $this->metadataRepository->findBySettings($settings);
+ $this->assertNotNull($metadata);
+ $this->assertInstanceOf(QueryResult::class, $metadata);
+
+ $metadataByLabel = [];
+ foreach ($metadata as $mdata) {
+ $metadataByLabel[$mdata->getLabel()] = $mdata;
+ }
+
+ return $metadataByLabel;
+ }
+
+ /**
+ * @test
+ * @group find
+ */
+ public function canFindBySettings(): void
+ {
+ $metadataByLabel = $this->findBySettings([]);
+ $this->assertCount(6, $metadataByLabel);
+ $this->assertEquals(
+ 'Ort, Untertitel, Autor, Institution, Sammlungen, Titel',
+ implode(', ', array_keys($metadataByLabel))
+ );
+
+ $metadataByLabel = $this->findBySettings(['is_listed' => true]);
+ $this->assertCount(3, $metadataByLabel);
+ $this->assertEquals(
+ 'Autor, Institution, Titel',
+ implode(', ', array_keys($metadataByLabel))
+ );
+
+ $metadataByLabel = $this->findBySettings(['is_sortable' => true]);
+ $this->assertCount(4, $metadataByLabel);
+ $this->assertEquals(
+ 'Ort, Untertitel, Autor, Titel',
+ implode(', ', array_keys($metadataByLabel))
+ );
+
+ $metadataByLabel = $this->findBySettings(
+ [
+ 'is_sortable' => true,
+ 'is_listed' => true
+ ]
+ );
+ $this->assertCount(2, $metadataByLabel);
+ $this->assertEquals(
+ 'Autor, Titel',
+ implode(', ', array_keys($metadataByLabel))
+ );
+ }
+}
diff --git a/Tests/Functional/Repository/TokenRepositoryTest.php b/Tests/Functional/Repository/TokenRepositoryTest.php
new file mode 100644
index 000000000..f30957a1e
--- /dev/null
+++ b/Tests/Functional/Repository/TokenRepositoryTest.php
@@ -0,0 +1,88 @@
+
+ *
+ * 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\Repository;
+
+use Kitodo\Dlf\Domain\Repository\TokenRepository;
+use Kitodo\Dlf\Tests\Functional\FunctionalTestCase;
+use TYPO3\CMS\Extbase\Persistence\Generic\PersistenceManager;
+
+class TokenRepositoryTest extends FunctionalTestCase
+{
+ /**
+ * @var TokenRepository
+ */
+ protected $tokenRepository;
+
+ /**
+ * @var PersistenceManager
+ */
+ protected $persistenceManager;
+
+ public function setUp(): void
+ {
+ parent::setUp();
+
+ $this->persistenceManager = $this->objectManager->get(PersistenceManager::class);
+
+ $this->tokenRepository = $this->initializeRepository(
+ TokenRepository::class,
+ 20000
+ );
+ }
+
+ public function tearDown(): void
+ {
+ parent::tearDown();
+
+ unlink(__DIR__ . '/../../Fixtures/Repository/tokenTemp.xml');
+ }
+
+ /**
+ * @test
+ * @group delete
+ */
+ public function deleteExpiredTokens(): void
+ {
+ $xml = simplexml_load_file(__DIR__ . '/../../Fixtures/Repository/token.xml');
+
+ $expireTime = 3600;
+ $i = 1;
+ foreach ($xml as $node) {
+ if ($i % 2 == 0) {
+ $node->tstamp = time() - $expireTime - random_int(10, 3600);
+ } else {
+ $node->tstamp = time() - $expireTime + random_int(10, 3600);
+ }
+ $i++;
+ }
+
+ $xml->saveXML(__DIR__ . '/../../Fixtures/Repository/tokenTemp.xml');
+
+ $this->importDataSet(__DIR__ . '/../../Fixtures/Repository/tokenTemp.xml');
+
+ $this->tokenRepository->deleteExpiredTokens($expireTime);
+
+ $this->persistenceManager->persistAll();
+
+ $tokens = $this->tokenRepository->findAll();
+
+ $this->assertEquals(2, $tokens->count());
+
+ $tokenUids = [];
+ foreach ($tokens as $token) {
+ $tokenUids[$token->getUid()] = $token;
+ }
+
+ $this->assertArrayHasKey('101', $tokenUids);
+ $this->assertArrayHasKey('103', $tokenUids);
+ }
+}