diff --git a/.github/workflows/php.yml b/.github/workflows/php.yml
index 25d0c41..ef59d25 100644
--- a/.github/workflows/php.yml
+++ b/.github/workflows/php.yml
@@ -9,7 +9,7 @@ on:
jobs:
build:
- runs-on: ubuntu-22.04
+ runs-on: ubuntu-24.04
strategy:
matrix:
@@ -18,7 +18,7 @@ jobs:
name: PHP ${{ matrix.php-versions }} Test
steps:
- - uses: actions/checkout@v3
+ - uses: actions/checkout@v5
- name: Setup PHP ${{ matrix.php-versions }}
uses: shivammathur/setup-php@v2
diff --git a/composer.json b/composer.json
index 0fcd4bc..f3bd7b1 100644
--- a/composer.json
+++ b/composer.json
@@ -13,6 +13,7 @@
"ext-dom": "*",
"ext-fileinfo": "*",
"ext-libxml": "*",
+ "ext-mbstring": "*",
"ext-zip": "*",
"opus4-repo/opus4-common": "dev-master as 4.8.1",
"opus4-repo/opus4-app-common": "dev-main",
diff --git a/src/ArrayImport.php b/src/ArrayImport.php
index 2b8c689..d060e41 100644
--- a/src/ArrayImport.php
+++ b/src/ArrayImport.php
@@ -33,6 +33,13 @@
use Opus\Common\Document;
+/**
+ * Imports documents from array.
+ *
+ * TODO What is the use case, besides an easy way to test import mechanisms.
+ * TODO Interface?
+ * TODO support multiple documents?
+ */
class ArrayImport
{
/**
diff --git a/src/ImportRuleConditionInterface.php b/src/ImportRuleConditionInterface.php
new file mode 100644
index 0000000..b0a9206
--- /dev/null
+++ b/src/ImportRuleConditionInterface.php
@@ -0,0 +1,43 @@
+getConfig();
+
+ if (
+ ! isset($config->sword->enableImportRules) ||
+ ! filter_var($config->sword->enableImportRules, FILTER_VALIDATE_BOOLEAN)
+ ) {
+ // TODO does this belong here? There should not be anything SWORD specific here!
+ return; // don't load any rules
+ }
+
+ $rulesConfig = null;
+
+ if (isset($config->import->rulesConfigFile)) {
+ $rulesConfigFile = $config->import->rulesConfigFile;
+ if (is_readable($rulesConfigFile)) {
+ $rulesConfig = new Zend_Config_Ini($rulesConfigFile);
+ $rulesConfig = $rulesConfig->toArray();
+ }
+ }
+
+ // Get rules from main configuration as fallback
+ if ($rulesConfig === null && isset($config->import->rules)) {
+ $rulesConfig = $config->import->rules->toArray();
+ }
+
+ if (is_array($rulesConfig)) {
+ foreach ($rulesConfig as $name => $options) {
+ $type = $options['type'];
+
+ $rule = $this->createRule($type, $options);
+
+ if ($rule !== null) {
+ $this->rules[] = $rule;
+ }
+ }
+ }
+ }
+
+ /**
+ * @return ImportRuleInterface[]
+ */
+ public function getRules()
+ {
+ return $this->rules;
+ }
+
+ /**
+ * @param string $type
+ * @param array $options
+ * @return ImportRuleInterface|null
+ */
+ public function createRule($type, $options)
+ {
+ if (class_exists($type)) {
+ $ruleClass = $type;
+ } else {
+ $ruleClass = self::IMPORT_RULE_CLASS_PREFIX . $type;
+ if (! class_exists($ruleClass)) {
+ // TODO throw exception
+ return null;
+ }
+ }
+
+ $rule = new $ruleClass();
+ $rule->setOptions($options);
+
+ return $rule;
+ }
+
+ /**
+ * @param DocumentInterface $document
+ */
+ public function apply($document)
+ {
+ foreach ($this->getRules() as $rule) {
+ $rule->apply($document);
+ }
+ }
+}
diff --git a/src/Importer.php b/src/Importer.php
index a92a2ae..12d1c69 100644
--- a/src/Importer.php
+++ b/src/Importer.php
@@ -127,6 +127,9 @@ class Importer
/** @var XmlDocument */
private $xmlDocument;
+ /** @var ImportRules */
+ private $importRules;
+
/** @var bool */
private $updateExistingDocuments = true;
@@ -319,6 +322,9 @@ public function run()
continue;
}
+ $importRules = $this->getImportRules();
+ $importRules->apply($doc);
+
try {
// TODO post "import" processing before storing!
$newDocId = $doc->store();
@@ -713,9 +719,11 @@ protected function handleKeywords($node, $doc)
{
foreach ($node->childNodes as $childNode) {
if ($childNode instanceof DOMElement) {
- $s = Subject::new();
- $s->setLanguage(trim($childNode->getAttribute('language')));
- $s->setType($childNode->getAttribute('type'));
+ $s = Subject::new();
+ $language = $childNode->getAttribute('language');
+ $s->setLanguage($language ?: 'deu');
+ $type = $childNode->getAttribute('type');
+ $s->setType($type ?: 'uncontrolled');
$s->setValue(trim($childNode->textContent));
$doc->addSubject($s);
}
@@ -1128,6 +1136,19 @@ public function getDocument(): DocumentInterface
return $this->document;
}
+ /**
+ * @return ImportRules
+ */
+ public function getImportRules()
+ {
+ if ($this->importRules === null) {
+ $this->importRules = new ImportRules();
+ $this->importRules->init();
+ }
+
+ return $this->importRules;
+ }
+
protected function setSingleDocImport(bool $singleDoc): self
{
$this->singleDocImport = $singleDoc;
diff --git a/src/Rules/AbstractImportRule.php b/src/Rules/AbstractImportRule.php
new file mode 100644
index 0000000..631dc69
--- /dev/null
+++ b/src/Rules/AbstractImportRule.php
@@ -0,0 +1,80 @@
+condition = new AccountCondition($condition);
+ }
+ if (isset($condition['keyword'])) {
+ $this->condition = new KeywordCondition($condition);
+ }
+ }
+ }
+
+ /**
+ * @return ImportRuleConditionInterface
+ */
+ public function getCondition()
+ {
+ return $this->condition;
+ }
+
+ /**
+ * @param DocumentInterface $document
+ */
+ public function apply($document)
+ {
+ // TODO condition check in base class?
+ }
+}
diff --git a/src/Rules/AddCollection.php b/src/Rules/AddCollection.php
new file mode 100644
index 0000000..927c7c3
--- /dev/null
+++ b/src/Rules/AddCollection.php
@@ -0,0 +1,77 @@
+collection = new CollectionOption($options['collection']);
+ }
+ }
+
+ /**
+ * @return CollectionInterface|null
+ */
+ public function getCollection()
+ {
+ return $this->collection->getCollection() ?? null;
+ }
+
+ /**
+ * @param DocumentInterface $document
+ */
+ public function apply($document)
+ {
+ $condition = $this->getCondition();
+
+ if ($condition === null || $condition->applies($document)) {
+ $col = $this->getCollection();
+ if ($col !== null) {
+ $document->addCollection($col);
+ }
+ }
+ }
+}
diff --git a/src/Rules/AddKeyword.php b/src/Rules/AddKeyword.php
new file mode 100644
index 0000000..0515bd2
--- /dev/null
+++ b/src/Rules/AddKeyword.php
@@ -0,0 +1,104 @@
+subjectType = $config['type'] ?? Subject::TYPE_UNCONTROLLED;
+ $this->language = $config['lang'] ?? 'deu';
+ } else {
+ $keyword = $config;
+ }
+
+ if (! empty($keyword)) {
+ $subject = Subject::new();
+ $subject->setValue($keyword);
+ $subject->setType($this->subjectType);
+ $subject->setLanguage($this->language);
+ $this->subject = $subject;
+ }
+ }
+ }
+
+ /**
+ * @return SubjectInterface|null
+ */
+ public function getSubject()
+ {
+ return $this->subject;
+ }
+
+ /**
+ * @param DocumentInterface $document
+ */
+ public function apply($document)
+ {
+ $condition = $this->getCondition();
+ if ($condition === null || $condition->applies($document)) {
+ $subject = $this->getSubject();
+ if ($subject !== null) {
+ $document->addSubject($subject);
+ }
+ }
+ }
+}
diff --git a/src/Rules/AddLicence.php b/src/Rules/AddLicence.php
new file mode 100644
index 0000000..1fab238
--- /dev/null
+++ b/src/Rules/AddLicence.php
@@ -0,0 +1,79 @@
+licence = Licence::get($options['licenceId']);
+ }
+ }
+
+ /**
+ * @return LicenceInterface|null
+ */
+ public function getLicence()
+ {
+ return $this->licence;
+ }
+
+ /**
+ * @param DocumentInterface $document
+ */
+ public function apply($document)
+ {
+ $condition = $this->getCondition();
+ if ($condition === null || $condition->applies($document)) {
+ $licence = $this->getLicence();
+ if ($licence !== null) {
+ $document->addLicence($licence);
+ }
+ }
+ }
+}
diff --git a/src/Rules/Conditions/AccountCondition.php b/src/Rules/Conditions/AccountCondition.php
new file mode 100644
index 0000000..141ac07
--- /dev/null
+++ b/src/Rules/Conditions/AccountCondition.php
@@ -0,0 +1,107 @@
+setOptions($options);
+ }
+
+ /**
+ * @param array|null $options
+ */
+ public function setOptions($options)
+ {
+ if (isset($options['account'])) {
+ $this->expectedUser = $options['account'];
+ }
+ }
+
+ /**
+ * @param DocumentInterface $document
+ * @return bool
+ */
+ public function applies($document)
+ {
+ $currentUser = $this->getUserName();
+ if ($this->expectedUser !== null && $currentUser !== null) {
+ return strcasecmp($this->expectedUser, $currentUser) === 0;
+ } else {
+ return false;
+ }
+ }
+
+ /**
+ * @return string|null
+ */
+ protected function getUserName()
+ {
+ $identity = Zend_Auth::getInstance()->getIdentity();
+ if (isset($identity['username'])) {
+ return $identity['username'];
+ } else {
+ return null;
+ }
+ }
+
+ /**
+ * @return string|null
+ */
+ public function getExpectedUser()
+ {
+ return $this->expectedUser;
+ }
+
+ /**
+ * @param string|null $user
+ */
+ public function setExpectedUser($user)
+ {
+ $this->expectedUser = $user;
+ }
+}
diff --git a/src/Rules/Conditions/KeywordCondition.php b/src/Rules/Conditions/KeywordCondition.php
new file mode 100644
index 0000000..dc9e5ad
--- /dev/null
+++ b/src/Rules/Conditions/KeywordCondition.php
@@ -0,0 +1,184 @@
+setOptions($options);
+ }
+
+ /**
+ * @param array|null $options
+ */
+ public function setOptions($options)
+ {
+ if (isset($options['keyword'])) {
+ $keyword = $options['keyword'];
+ if (is_array($keyword)) {
+ $this->expectedKeyword = $keyword['value'] ?? null;
+ $this->keywordType = $keyword['type'] ?? null;
+ if (isset($keyword['remove'])) {
+ $this->removeKeyword = filter_var($keyword['remove'], FILTER_VALIDATE_BOOLEAN);
+ }
+ if (isset($keyword['caseSensitive'])) {
+ $this->caseSensitive = filter_var($keyword['caseSensitive'], FILTER_VALIDATE_BOOLEAN);
+ }
+ } else {
+ $this->expectedKeyword = $options['keyword'];
+ }
+ }
+ }
+
+ /**
+ * @param DocumentInterface $document
+ * @return bool
+ *
+ * TODO remove keywords
+ */
+ public function applies($document)
+ {
+ $caseSensitive = $this->isCaseSensitive();
+ $expectedKeyword = $this->getExpectedKeyword();
+ $keywordType = $this->getKeywordType();
+
+ if ($document->hasSubject($expectedKeyword, $keywordType, $caseSensitive)) {
+ if ($this->isRemoveEnabled()) {
+ $document->removeSubject($expectedKeyword, $keywordType, $caseSensitive);
+ }
+ return true;
+ }
+
+ return false;
+ }
+
+ /**
+ * @return string|null
+ */
+ public function getExpectedKeyword()
+ {
+ return $this->expectedKeyword;
+ }
+
+ /**
+ * @param string|null $keyword
+ * @return $this
+ */
+ public function setExpectedKeyword($keyword)
+ {
+ $this->expectedKeyword = $keyword;
+ return $this;
+ }
+
+ /**
+ * @return bool
+ */
+ public function isRemoveEnabled()
+ {
+ return $this->removeKeyword;
+ }
+
+ /**
+ * @param bool $enabled
+ * @return $this
+ */
+ public function setRemoveEnabled($enabled)
+ {
+ $this->removeKeyword = $enabled;
+ return $this;
+ }
+
+ /**
+ * @return bool
+ */
+ public function isCaseSensitive()
+ {
+ return $this->caseSensitive;
+ }
+
+ /**
+ * @param bool $enabled
+ * @return $this
+ */
+ public function setCaseSensitive($enabled)
+ {
+ $this->caseSensitive = $enabled;
+ return $this;
+ }
+
+ /**
+ * @return string|null
+ */
+ public function getKeywordType()
+ {
+ return $this->keywordType;
+ }
+
+ /**
+ * @param string|null $type
+ * @return $this
+ */
+ public function setKeywordType($type)
+ {
+ $this->keywordType = $type;
+ return $this;
+ }
+}
diff --git a/src/Rules/Options/CollectionOption.php b/src/Rules/Options/CollectionOption.php
new file mode 100644
index 0000000..d51f2b3
--- /dev/null
+++ b/src/Rules/Options/CollectionOption.php
@@ -0,0 +1,126 @@
+setOptions($options);
+ }
+
+ /**
+ * @param string[]|null $options
+ */
+ public function setOptions($options)
+ {
+ $this->options = $options;
+ }
+
+ /**
+ * @return CollectionInterface|null
+ */
+ public function getCollection()
+ {
+ if ($this->collection === null) {
+ $this->collection = $this->loadCollection();
+ }
+ return $this->collection;
+ }
+
+ /**
+ * @return CollectionInterface|null
+ * @throws NotFoundException
+ */
+ protected function loadCollection()
+ {
+ // if collection ID is configured, load collection directly
+ if (isset($this->options['id']) && is_numeric($this->options['id'])) {
+ return Collection::get($this->options['id']);
+ }
+
+ $role = null;
+
+ // try to get collection role ('roleName' or 'roleOaiName')
+ if (isset($this->options['roleName'])) {
+ $role = CollectionRole::fetchByName($this->options['roleName']);
+ } elseif (isset($this->options['roleOaiName'])) {
+ $role = CollectionRole::fetchByOaiName($this->options['roleOaiName']);
+ }
+
+ if ($role === null) {
+ // TODO log, throw exception?
+ return null;
+ }
+
+ $collections = [];
+
+ // try to get collection ('number' or 'name')
+ if (isset($this->options['number'])) {
+ $collections = Collection::fetchCollectionsByRoleNumber($role->getId(), $this->options['number']);
+ } elseif (isset($this->options['name'])) {
+ $collections = Collection::fetchCollectionsByRoleName($role->getId(), $this->options['name']);
+ }
+
+ if (count($collections) > 0) {
+ return $collections[0];
+ }
+
+ return null;
+ }
+}
diff --git a/src/Rules/RemoveKeywords.php b/src/Rules/RemoveKeywords.php
new file mode 100644
index 0000000..b8cfabc
--- /dev/null
+++ b/src/Rules/RemoveKeywords.php
@@ -0,0 +1,130 @@
+getCondition();
+ if ($condition === null || $condition->applies($document)) {
+ $keywords = $this->getKeywords();
+ if ($keywords !== null) {
+ $caseSensitive = $this->isCaseSensitive();
+ $keywordType = $this->getKeywordType();
+ foreach ($keywords as $keyword) {
+ $document->removeSubject($keyword, $keywordType, $caseSensitive);
+ }
+ }
+ }
+ }
+
+ /**
+ * @return string[]
+ */
+ public function getKeywords()
+ {
+ return $this->keywords;
+ }
+
+ /**
+ * @param string|string[] $keywords
+ * @return $this
+ */
+ public function setKeywords($keywords)
+ {
+ if (is_array($keywords) || $keywords === null) {
+ $this->keywords = $keywords;
+ } else {
+ $this->keywords = array_map('trim', mb_split(',', $keywords));
+ }
+ return $this;
+ }
+
+ /**
+ * @return null|string
+ */
+ public function getKeywordType()
+ {
+ return $this->keywordType;
+ }
+
+ /**
+ * @param null|string $type
+ * @return $this
+ */
+ public function setKeywordType($type)
+ {
+ $this->keywordType = $type;
+ return $this;
+ }
+
+ /**
+ * @return bool
+ */
+ public function isCaseSensitive()
+ {
+ return $this->caseSensitive;
+ }
+
+ /**
+ * @param bool $caseSensitive
+ * @return $this
+ */
+ public function setCaseSensitive($caseSensitive)
+ {
+ $this->caseSensitive = $caseSensitive;
+ return $this;
+ }
+}
diff --git a/src/Sword/ImportCollection.php b/src/Sword/ImportCollection.php
index 875805a..694f055 100644
--- a/src/Sword/ImportCollection.php
+++ b/src/Sword/ImportCollection.php
@@ -41,6 +41,9 @@
use function trim;
/**
+ * TODO rename this class - is is not a collection, it is a helper class for getting the "import collection" - Is this
+ * class necessary at all? Couldn't it be just a function, somewhere? What is the purpose, the reasoning behind
+ * it?
* TODO make generic or move to opus4-sword (What is the concept here? Is SWORD specific?)
*/
class ImportCollection
diff --git a/src/Xml/opus-import.xsd b/src/Xml/opus-import.xsd
index 217c11d..dd71b1a 100644
--- a/src/Xml/opus-import.xsd
+++ b/src/Xml/opus-import.xsd
@@ -212,8 +212,8 @@
-
-
+
+
@@ -224,6 +224,7 @@
+
diff --git a/test/ImportRulesTest.php b/test/ImportRulesTest.php
new file mode 100644
index 0000000..baba5cf
--- /dev/null
+++ b/test/ImportRulesTest.php
@@ -0,0 +1,156 @@
+prepareCollections();
+
+ $this->adjustConfiguration([
+ 'import' => [
+ 'rules' => [
+ 'addCol' => [
+ 'type' => 'AddCollection',
+ 'collection' => [
+ 'id' => $this->colId,
+ ],
+ ],
+ ],
+ 'rulesConfigFile' => null,
+ ],
+ 'sword' => [
+ 'enableImportRules' => true,
+ ],
+ ]);
+
+ $importRules = new ImportRules();
+ $importRules->init();
+
+ $rules = $importRules->getRules();
+
+ $this->assertCount(1, $rules);
+
+ $rule = $rules[0];
+
+ $this->assertInstanceOf(AddCollection::class, $rule);
+
+ $col = $rule->getCollection();
+
+ $this->assertInstanceOf(CollectionInterface::class, $col);
+ $this->assertEquals('col1', $col->getName());
+ }
+
+ public function testConfigFullClassname()
+ {
+ $this->prepareCollections();
+
+ $this->adjustConfiguration([
+ 'import' => [
+ 'rules' => [
+ 'addCol' => [
+ 'type' => AddCollection::class,
+ 'collection' => [
+ 'id' => $this->colId,
+ ],
+ ],
+ ],
+ 'rulesConfigFile' => null,
+ ],
+ 'sword' => [
+ 'enableImportRules' => true,
+ ],
+ ]);
+
+ $importRules = new ImportRules();
+ $importRules->init();
+
+ $rules = $importRules->getRules();
+
+ $this->assertCount(1, $rules);
+
+ $rule = $rules[0];
+
+ $this->assertInstanceOf(AddCollection::class, $rule);
+
+ $col = $rule->getCollection();
+
+ $this->assertInstanceOf(CollectionInterface::class, $col);
+ $this->assertEquals('col1', $col->getName());
+ }
+
+ public function testLoadConfigIni()
+ {
+ $this->adjustConfiguration([
+ 'sword' => ['enableImportRules' => true],
+ 'import' => ['rulesConfigFile' => APPLICATION_PATH . '/test/_files/import-rules.ini'],
+ ]);
+
+ $importRules = new ImportRules();
+ $importRules->init();
+
+ $rules = $importRules->getRules();
+
+ $this->assertCount(2, $rules);
+ $this->assertInstanceOf(AddCollection::class, $rules[0]);
+ }
+
+ protected function prepareCollections()
+ {
+ $role = CollectionRole::new();
+ $role->setName('import');
+ $role->setOaiName('oaiImport');
+ $role->addRootCollection();
+
+ $col = Collection::new();
+ $col->setName('col1');
+ $col->setNumber('col1number');
+ $role->getRootCollection()->addFirstChild($col);
+ $role->store();
+
+ $this->colId = $col->getId();
+ }
+}
diff --git a/test/ImporterTest.php b/test/ImporterTest.php
index dff2644..b9eed48 100644
--- a/test/ImporterTest.php
+++ b/test/ImporterTest.php
@@ -31,13 +31,21 @@
namespace OpusTest\Import;
+use Opus\Common\Collection;
+use Opus\Common\CollectionRole;
use Opus\Common\Document;
use Opus\Common\DocumentInterface;
use Opus\Common\EnrichmentKey;
+use Opus\Common\Licence;
use Opus\Common\Log;
+use Opus\Common\Model\ModelException;
+use Opus\Common\Security\SecurityException;
+use Opus\Common\Subject;
use Opus\Import\Importer;
+use Opus\Import\Xml\MetadataImportInvalidXmlException;
use Opus\Import\Xml\MetadataImportSkippedDocumentsException;
use OpusTest\Import\TestAsset\TestCase;
+use Zend_Exception;
use function file_get_contents;
@@ -57,6 +65,8 @@ public function setUp(): void
$enrichmentKey = EnrichmentKey::new();
$enrichmentKey->setName('validtestkey');
$enrichmentKey->store();
+
+ // TODO enable import rules here?
}
public function tearDown(): void
@@ -131,4 +141,213 @@ public function testFromArray()
// var_dump($doc->toArray());
}
+
+ /**
+ * @return DocumentInterface
+ * @throws MetadataImportSkippedDocumentsException
+ * @throws ModelException
+ * @throws SecurityException
+ * @throws MetadataImportInvalidXmlException
+ * @throws Zend_Exception
+ */
+ protected function getTestImportDocument()
+ {
+ $xml = file_get_contents(APPLICATION_PATH . '/test/_files/import-rules-test.xml');
+
+ $importer = new Importer($xml, false, Log::get());
+
+ $importer->run();
+
+ $document = $importer->getDocument();
+
+ $this->assertNotNull($document);
+ $this->assertInstanceOf(DocumentInterface::class, $document);
+
+ return $document;
+ }
+
+ public function testImport()
+ {
+ $document = $this->getTestImportDocument();
+
+ $authors = $document->getPersonAuthor();
+
+ $this->assertCount(1, $authors);
+
+ $this->assertEquals('deu', $document->getLanguage());
+ $this->assertEquals('Der Titel', $document->getMainTitle()->getValue());
+ }
+
+ public function testImportRulesAddCollectionByAccount()
+ {
+ $doc = $this->getTestImportDocument();
+ }
+
+ public function testImportRulesAddCollectionForKeyword()
+ {
+ $this->prepareCollections();
+
+ $this->adjustConfiguration([
+ 'sword' => ['enableImportRules' => true],
+ 'import' => ['rulesConfigFile' => APPLICATION_PATH . '/test/_files/import-rules-keywords.ini'],
+ ]);
+
+ $doc = $this->getTestImportDocument();
+
+ $collections = $doc->getCollection();
+
+ $this->assertCount(1, $collections);
+ $this->assertEquals('col1', $collections[0]->getName());
+ }
+
+ public function testImportRulesAddLicenceForKeyword()
+ {
+ $licence = Licence::new();
+ $licence->setName('CC BY');
+ $licence->setNameLong('CC BY Test Licence');
+ $licence->setLinkLicence('URL');
+ $licenceId = $licence->store();
+
+ $this->adjustConfiguration([
+ 'sword' => ['enableImportRules' => true],
+ 'import' => [
+ 'rulesConfigFile' => null,
+ 'rules' => [
+ 'licence' => [
+ 'type' => 'AddLicence',
+ 'condition' => [
+ 'keyword' => 'ccby',
+ ],
+ 'licenceId' => $licenceId,
+ ],
+ ],
+ ],
+ ]);
+
+ $doc = $this->getTestImportDocument();
+
+ $licences = $doc->getLicence();
+
+ $this->assertCount(1, $licences);
+ $this->assertEquals('CC BY', $licences[0]->getName());
+ }
+
+ public function testImportRulesRemoveKeyword()
+ {
+ $this->markTestIncomplete('TODO implement test');
+ }
+
+ public function testImportRulesAddCollectionAndRemoveKeyword()
+ {
+ $this->prepareCollections();
+
+ $this->adjustConfiguration([
+ 'sword' => ['enableImportRules' => true],
+ 'import' => ['rulesConfigFile' => APPLICATION_PATH . '/test/_files/import-rules-keywords.ini'],
+ ]);
+
+ $doc = $this->getTestImportDocument();
+
+ $collections = $doc->getCollection();
+
+ $this->assertCount(1, $collections);
+
+ $this->markTestIncomplete('TODO check if collection was added and keyword removed');
+ }
+
+ public function testImportRulesDisabled()
+ {
+ $this->adjustConfiguration([
+ 'sword' => ['enableImportRules' => false],
+ 'import' => ['rulesConfigFile' => APPLICATION_PATH . '/test/_files/import-rules-keywords.ini'],
+ ]);
+ $doc = $this->getTestImportDocument();
+ $this->assertFalse($doc->hasSubject('RulesEnabled'));
+ }
+
+ public function testKeywordTypeDefaultUncontrolled()
+ {
+ $doc = $this->getTestImportDocument();
+
+ $keywords = $doc->getSubject();
+
+ $this->assertCount(4, $keywords);
+
+ $this->assertTrue($doc->hasSubject('oa-green', Subject::TYPE_UNCONTROLLED));
+ $this->assertTrue($doc->hasSubject('oa-gold', Subject::TYPE_UNCONTROLLED));
+ }
+
+ public function testAddKeyword()
+ {
+ $this->adjustConfiguration([
+ 'sword' => ['enableImportRules' => true],
+ 'import' => ['rulesConfigFile' => APPLICATION_PATH . '/test/_files/import-rules-keywords.ini'],
+ ]);
+
+ $doc = $this->getTestImportDocument();
+
+ $this->assertTrue($doc->hasSubject('RulesEnabled'));
+ }
+
+ protected function prepareCollections()
+ {
+ $role = CollectionRole::new();
+ $role->setName('import');
+ $role->setOaiName('oaiImport');
+ $role->addRootCollection();
+ $role->store();
+
+ $rootCol = $role->getRootCollection();
+
+ $col = Collection::new();
+ $col->setName('col1');
+ $col->setNumber('col1number');
+ $rootCol->addFirstChild($col);
+
+ $col = Collection::new();
+ $col->setName('green');
+ $col->setNumber('col2number');
+ $rootCol->addLastChild($col);
+ $role->store();
+ }
+
+ public function testImportKeywordDefaults()
+ {
+ $xml = file_get_contents(APPLICATION_PATH . '/test/_files/import2.xml');
+
+ $importer = new Importer($xml, false, Log::get());
+
+ $importer->run();
+
+ $doc = $importer->getDocument();
+
+ $this->assertNotNull($doc);
+ $this->assertInstanceOf(DocumentInterface::class, $doc);
+
+ $subjects = $doc->getSubject();
+
+ $this->assertCount(3, $subjects);
+
+ // TODO this result check is overly complicated - better way?
+ foreach ($subjects as $subject) {
+ switch ($subject->getType()) {
+ case Subject::TYPE_SWD:
+ $this->assertEquals('Test', $subject->getValue());
+ $this->assertEquals('deu', $subject->getLanguage());
+ break;
+ case Subject::TYPE_UNCONTROLLED:
+ switch ($subject->getValue()) {
+ case 'engTest':
+ $this->assertEquals('eng', $subject->getLanguage());
+ break;
+ case 'testWithDefaults':
+ $this->assertEquals('deu', $subject->getLanguage());
+ break;
+ }
+ break;
+ default:
+ $this->fail('Unexpected subject type ' . $subject->getType());
+ }
+ }
+ }
}
diff --git a/test/Rules/AddCollectionTest.php b/test/Rules/AddCollectionTest.php
new file mode 100644
index 0000000..210b361
--- /dev/null
+++ b/test/Rules/AddCollectionTest.php
@@ -0,0 +1,175 @@
+authStorage = new Zend_Auth_Storage_NonPersistent();
+ Zend_Auth::getInstance()->setStorage($this->authStorage);
+ }
+
+ public function tearDown(): void
+ {
+ Zend_Auth::getInstance()
+ ->setStorage($this->authStorage)
+ ->clearIdentity();
+ parent::tearDown();
+ }
+
+ public function testAddCollection()
+ {
+ $this->prepareCollections();
+
+ $this->adjustConfiguration([
+ 'sword' => ['enableImportRules' => true],
+ 'import' => [
+ 'rules' => [
+ 'addCol' => [
+ 'type' => AddCollection::class,
+ 'collection' => [
+ 'id' => $this->colId,
+ ],
+ ],
+ ],
+ 'rulesConfigFile' => null,
+ ],
+ ]);
+
+ $importRules = new ImportRules();
+ $importRules->init();
+
+ $doc = Document::new();
+
+ $importRules->apply($doc);
+
+ $collections = $doc->getCollection();
+
+ $this->assertCount(1, $collections);
+ $this->assertEquals($this->colId, $collections[0]->getId());
+ }
+
+ public function testAddCollectionForAccount()
+ {
+ $this->prepareCollections();
+
+ $col1 = Collection::get($this->colId);
+ $role = $col1->getRole();
+
+ $col1id = $col1->getId();
+
+ $col2 = Collection::new();
+ $col2->setName('col1');
+ $col2->setNumber('col1number');
+ $role->getRootCollection()->addFirstChild($col2);
+ $role->store();
+
+ $col2id = $col2->getId();
+
+ $this->adjustConfiguration([
+ 'sword' => ['enableImportRules' => true],
+ 'import' => [
+ 'rules' => [
+ 'addCol1' => [
+ 'type' => 'AddCollection',
+ 'condition' => [
+ 'account' => 'sword1',
+ ],
+ 'collection' => [
+ 'id' => $this->colId,
+ ],
+ ],
+ 'addCol2' => [
+ 'type' => 'AddCollection',
+ 'condition' => [
+ 'account' => 'sword2',
+ ],
+ 'collection' => [
+ 'id' => $col2id,
+ ],
+ ],
+ ],
+ 'rulesConfigFile' => null,
+ ],
+ ]);
+
+ $rules = new ImportRules();
+ $rules->init();
+
+ Zend_Auth::getInstance()->authenticate(new MockAuthAdapter('sword1'));
+
+ $doc = Document::new();
+
+ $rules->apply($doc);
+
+ $collections = $doc->getCollection();
+
+ $this->assertCount(1, $collections);
+ $this->assertEquals($col1id, $collections[0]->getId());
+ }
+
+ protected function prepareCollections()
+ {
+ $role = CollectionRole::new();
+ $role->setName('import');
+ $role->setOaiName('oaiImport');
+ $role->addRootCollection();
+
+ $col = Collection::new();
+ $col->setName('col1');
+ $col->setNumber('col1number');
+ $role->getRootCollection()->addFirstChild($col);
+ $role->store();
+
+ $this->colId = $col->getId();
+ }
+}
diff --git a/test/Rules/AddLicenceTest.php b/test/Rules/AddLicenceTest.php
new file mode 100644
index 0000000..a9556f5
--- /dev/null
+++ b/test/Rules/AddLicenceTest.php
@@ -0,0 +1,193 @@
+adjustConfiguration([
+ 'sword' => [
+ 'enableImportRules' => true,
+ ],
+ ]);
+ }
+
+ public function testAddLicence()
+ {
+ $this->prepareLicences();
+
+ $this->adjustConfiguration([
+ 'import' => [
+ 'rules' => [
+ 'addLicence' => [
+ 'type' => AddLicence::class,
+ 'licenceId' => $this->licenceId1,
+ ],
+ ],
+ ],
+ ]);
+
+ $importRules = new ImportRules();
+ $importRules->init();
+
+ $doc = Document::new();
+
+ $importRules->apply($doc);
+
+ $licences = $doc->getLicence();
+
+ $this->assertCount(1, $licences);
+ $this->assertEquals($this->licenceId1, $licences[0]->getModel()->getId());
+ }
+
+ public function testAddLicenceForKeyword()
+ {
+ $this->prepareLicences();
+
+ $this->adjustConfiguration([
+ 'import' => [
+ 'rules' => [
+ 'addLicence1' => [
+ 'type' => 'AddLicence',
+ 'licenceId' => $this->licenceId1,
+ 'condition' => [
+ 'keyword' => 'ccby',
+ ],
+ ],
+ 'addLicence2' => [
+ 'type' => 'AddLicence',
+ 'licenceId' => $this->licenceId2,
+ 'condition' => [
+ 'keyword' => 'ccbyna',
+ ],
+ ],
+ ],
+ ],
+ ]);
+
+ $importRules = new ImportRules();
+ $importRules->init();
+
+ $doc = Document::new();
+ $subject = $doc->addSubject();
+ $subject->setValue('ccbyna');
+ $subject->setType(Subject::TYPE_UNCONTROLLED);
+
+ $importRules->apply($doc);
+
+ $licences = $doc->getLicence();
+
+ $this->assertCount(1, $licences);
+ $this->assertEquals($this->licenceId2, $licences[0]->getModel()->getId());
+ }
+
+ public function testAddMultipleLicences()
+ {
+ $this->prepareLicences();
+
+ $this->adjustConfiguration([
+ 'import' => [
+ 'rules' => [
+ 'addLicence1' => [
+ 'type' => 'AddLicence',
+ 'licenceId' => $this->licenceId1,
+ 'condition' => [
+ 'keyword' => 'ccby',
+ ],
+ ],
+ 'addLicence2' => [
+ 'type' => 'AddLicence',
+ 'licenceId' => $this->licenceId2,
+ 'condition' => [
+ 'keyword' => 'ccbyna',
+ ],
+ ],
+ ],
+ ],
+ ]);
+
+ $importRules = new ImportRules();
+ $importRules->init();
+
+ $doc = Document::new();
+ $subject = $doc->addSubject();
+ $subject->setValue('ccbyna');
+ $subject->setType(Subject::TYPE_UNCONTROLLED);
+ $subject = $doc->addSubject();
+ $subject->setValue('ccby');
+ $subject->setType(Subject::TYPE_PSYNDEX);
+
+ $importRules->apply($doc);
+
+ $licences = $doc->getLicence();
+
+ $this->assertCount(2, $licences);
+ $this->assertNotEquals($licences[0]->getModel()->getId(), $licences[1]->getModel()->getId());
+ $this->assertContains($licences[0]->getModel()->getId(), [$this->licenceId1, $this->licenceId2]);
+ $this->assertContains($licences[1]->getModel()->getId(), [$this->licenceId1, $this->licenceId2]);
+ }
+
+ protected function prepareLicences()
+ {
+ $licence = Licence::fromArray([
+ 'Name' => 'CC BY',
+ 'NameLong' => 'Test Licence 1',
+ 'LinkLicence' => 'https://www.kobv.de/licence1',
+ ]);
+
+ $this->licenceId1 = $licence->store();
+
+ $licence = Licence::fromArray([
+ 'name' => 'CC BY NA',
+ 'NameLong' => 'Test Licence 2',
+ 'LinkLicence' => 'https://www.kobv.de/licence2',
+ ]);
+
+ $this->licenceId2 = $licence->store();
+ }
+}
diff --git a/test/Rules/Conditions/AccountConditionTest.php b/test/Rules/Conditions/AccountConditionTest.php
new file mode 100644
index 0000000..32e451e
--- /dev/null
+++ b/test/Rules/Conditions/AccountConditionTest.php
@@ -0,0 +1,101 @@
+authStorage = new Zend_Auth_Storage_NonPersistent();
+ Zend_Auth::getInstance()->setStorage($this->authStorage);
+ }
+
+ public function tearDown(): void
+ {
+ Zend_Auth::getInstance()
+ ->setStorage($this->authStorage)
+ ->clearIdentity();
+ parent::tearDown();
+ }
+
+ public function testConstruct()
+ {
+ $condition = new AccountCondition([
+ 'account' => 'sword1',
+ ]);
+
+ $this->assertEquals('sword1', $condition->getExpectedUser());
+ }
+
+ public function testAppliesTrue()
+ {
+ Zend_Auth::getInstance()->authenticate(new MockAuthAdapter('sword1'));
+
+ $condition = new AccountCondition([
+ 'account' => 'sword1',
+ ]);
+
+ $doc = Document::new();
+
+ $this->assertTrue($condition->applies($doc));
+ }
+
+ public function testAppliesFalse()
+ {
+ Zend_Auth::getInstance()->authenticate(new MockAuthAdapter('sword2'));
+
+ $condition = new AccountCondition([
+ 'account' => 'sword1',
+ ]);
+
+ $doc = Document::new();
+
+ $this->assertFalse($condition->applies($doc));
+
+ $condition->setExpectedUser('sword2');
+
+ $this->assertTrue($condition->applies($doc));
+ }
+}
diff --git a/test/Rules/Conditions/KeywordConditionTest.php b/test/Rules/Conditions/KeywordConditionTest.php
new file mode 100644
index 0000000..dd5c4a3
--- /dev/null
+++ b/test/Rules/Conditions/KeywordConditionTest.php
@@ -0,0 +1,257 @@
+ [
+ 'value' => 'ccby',
+ 'remove' => true,
+ 'caseSensitive' => 1,
+ 'type' => 'uncontrolled',
+ ],
+ ]);
+
+ $this->assertEquals('ccby', $condition->getExpectedKeyword());
+ $this->assertTrue($condition->isCaseSensitive());
+ $this->assertEquals('uncontrolled', $condition->getKeywordType());
+ $this->assertTrue($condition->isRemoveEnabled());
+ }
+
+ public function testConstructSimpleConfig()
+ {
+ $condition = new KeywordCondition([
+ 'keyword' => 'ccby',
+ ]);
+
+ $this->assertEquals('ccby', $condition->getExpectedKeyword());
+ $this->assertFalse($condition->isCaseSensitive());
+ $this->assertNull($condition->getKeywordType());
+ $this->assertFalse($condition->isRemoveEnabled());
+ }
+
+ public function testAppliesTrue()
+ {
+ $condition = new KeywordCondition([
+ 'keyword' => 'ccby',
+ ]);
+
+ $doc = Document::new();
+ $subject = $doc->addSubject();
+ $subject->setValue('ccby');
+ $subject->setType(Subject::TYPE_UNCONTROLLED);
+
+ $this->assertTrue($condition->applies($doc));
+ }
+
+ public function testAppliesFalse()
+ {
+ $condition = new KeywordCondition([
+ 'keyword' => 'ccbyna',
+ ]);
+
+ $doc = Document::new();
+ $subject = $doc->addSubject();
+ $subject->setValue('ccby');
+ $subject->setType(Subject::TYPE_UNCONTROLLED);
+
+ $this->assertFalse($condition->applies($doc));
+ }
+
+ public function testUsingKeywordType()
+ {
+ $condition = new KeywordCondition([
+ 'keyword' => [
+ 'value' => 'ccby',
+ 'type' => 'psyndex',
+ ],
+ ]);
+
+ $doc = Document::new();
+ $subject = $doc->addSubject();
+ $subject->setValue('ccby');
+ $subject->setType(Subject::TYPE_UNCONTROLLED);
+
+ $this->assertFalse($condition->applies($doc));
+
+ $subject = $doc->addSubject();
+ $subject->setValue('ccby');
+ $subject->setType(Subject::TYPE_PSYNDEX);
+
+ $this->assertTrue($condition->applies($doc));
+ }
+
+ public function testNotCaseSensitive()
+ {
+ $condition = new KeywordCondition([
+ 'keyword' => 'ccby',
+ ]);
+
+ $doc = Document::new();
+ $subject = $doc->addSubject();
+ $subject->setValue('CCBY');
+ $subject->setType(Subject::TYPE_UNCONTROLLED);
+
+ $this->assertTrue($condition->applies($doc));
+ }
+
+ public function testCaseSensitive()
+ {
+ $condition = new KeywordCondition([
+ 'keyword' => [
+ 'value' => 'ccby',
+ 'caseSensitive' => true,
+ ],
+ ]);
+
+ $doc = Document::new();
+ $subject = $doc->addSubject();
+ $subject->setValue('CCBY');
+ $subject->setType(Subject::TYPE_UNCONTROLLED);
+
+ $this->assertFalse($condition->applies($doc));
+ }
+
+ public function testDoNotRemoveKeyword()
+ {
+ $condition = new KeywordCondition([
+ 'keyword' => 'ccby',
+ ]);
+
+ $doc = Document::new();
+ $subject = $doc->addSubject();
+ $subject->setValue('ccby');
+ $subject->setType(Subject::TYPE_UNCONTROLLED);
+
+ $this->assertTrue($condition->applies($doc));
+
+ $this->assertCount(1, $doc->getSubject());
+ }
+
+ public function testDoNotRemoveKeywordIfConditionDoesNotApply()
+ {
+ $condition = new KeywordCondition([
+ 'keyword' => [
+ 'value' => 'ccby',
+ 'remove' => true,
+ ],
+ ]);
+
+ $doc = Document::new();
+ $subject = $doc->addSubject();
+ $subject->setValue('ccbyna');
+ $subject->setType(Subject::TYPE_UNCONTROLLED);
+
+ $this->assertFalse($condition->applies($doc));
+
+ $this->assertCount(1, $doc->getSubject());
+ }
+
+ public function testRemoveKeyword()
+ {
+ $condition = new KeywordCondition([
+ 'keyword' => [
+ 'value' => 'ccby',
+ 'remove' => true,
+ ],
+ ]);
+
+ $doc = Document::new();
+ $subject = $doc->addSubject();
+ $subject->setValue('ccby');
+ $subject->setType(Subject::TYPE_UNCONTROLLED);
+
+ $this->assertTrue($condition->applies($doc));
+
+ $this->assertCount(0, $doc->getSubject());
+ }
+
+ public function testRemoveOnlyKeywordWithMatchingType()
+ {
+ $condition = new KeywordCondition([
+ 'keyword' => [
+ 'value' => 'ccby',
+ 'type' => Subject::TYPE_PSYNDEX,
+ 'remove' => true,
+ ],
+ ]);
+
+ $doc = Document::new();
+ $subject = $doc->addSubject();
+ $subject->setValue('ccby');
+ $subject->setType(Subject::TYPE_UNCONTROLLED);
+
+ $subject = $doc->addSubject();
+ $subject->setValue('ccby');
+ $subject->setType(Subject::TYPE_PSYNDEX);
+
+ $this->assertTrue($condition->applies($doc));
+
+ $subjects = $doc->getSubject();
+
+ $this->assertCount(1, $subjects);
+ $this->assertEquals(Subject::TYPE_UNCONTROLLED, $subjects[0]->getType());
+ }
+
+ public function testRemoveAllMatchingKeywords()
+ {
+ $condition = new KeywordCondition([
+ 'keyword' => [
+ 'value' => 'ccby',
+ 'remove' => true,
+ ],
+ ]);
+
+ $doc = Document::new();
+ $subject = $doc->addSubject();
+ $subject->setValue('ccby');
+ $subject->setType(Subject::TYPE_UNCONTROLLED);
+
+ $subject = $doc->addSubject();
+ $subject->setValue('ccby');
+ $subject->setType(Subject::TYPE_PSYNDEX);
+
+ $this->assertTrue($condition->applies($doc));
+
+ $subjects = $doc->getSubject();
+
+ $this->assertCount(0, $subjects);
+ }
+}
diff --git a/test/Rules/Options/CollectionOptionTest.php b/test/Rules/Options/CollectionOptionTest.php
new file mode 100644
index 0000000..a7c4444
--- /dev/null
+++ b/test/Rules/Options/CollectionOptionTest.php
@@ -0,0 +1,144 @@
+prepareCollections();
+
+ $colId = $this->colId;
+
+ $option = new CollectionOption();
+ $option->setOptions([
+ 'id' => $colId,
+ ]);
+
+ $col = $option->getCollection();
+
+ $this->assertNotNull($col);
+ $this->assertEquals($colId, $col->getId());
+ }
+
+ public function testConfigRoleNameColNumber()
+ {
+ $this->prepareCollections();
+
+ $option = new CollectionOption();
+ $option->setOptions([
+ 'roleName' => 'import',
+ 'number' => 'col1number',
+ ]);
+
+ $col = $option->getCollection();
+
+ $this->assertNotNull($col);
+ $this->assertEquals($this->colId, $col->getId());
+ }
+
+ public function testConfigRoleNameColName()
+ {
+ $this->prepareCollections();
+
+ $option = new CollectionOption();
+ $option->setOptions([
+ 'roleName' => 'import',
+ 'name' => 'col1',
+ ]);
+
+ $col = $option->getCollection();
+
+ $this->assertNotNull($col);
+ $this->assertEquals($this->colId, $col->getId());
+ }
+
+ public function testConfigRoleOaiNameColNumber()
+ {
+ $this->prepareCollections();
+
+ $option = new CollectionOption();
+ $option->setOptions([
+ 'roleOaiName' => 'oaiImport',
+ 'number' => 'col1number',
+ ]);
+
+ $col = $option->getCollection();
+
+ $this->assertNotNull($col);
+ $this->assertEquals($this->colId, $col->getId());
+ }
+
+ public function testConfigRoleOaiNameColName()
+ {
+ $this->prepareCollections();
+
+ $option = new CollectionOption();
+ $option->setOptions([
+ 'roleOaiName' => 'oaiImport',
+ 'name' => 'col1',
+ ]);
+
+ $col = $option->getCollection();
+
+ $this->assertNotNull($col);
+ $this->assertEquals($this->colId, $col->getId());
+ }
+
+ protected function prepareCollections()
+ {
+ $role = CollectionRole::new();
+ $role->setName('import');
+ $role->setOaiName('oaiImport');
+ $role->addRootCollection();
+ $this->roleId = $role->store();
+
+ $col = Collection::new();
+ $col->setName('col1');
+ $col->setNumber('col1number');
+ $role->getRootCollection()->addFirstChild($col);
+ $role->store();
+
+ $this->colId = $col->getId();
+ }
+}
diff --git a/test/Rules/RemoveKeywordsTest.php b/test/Rules/RemoveKeywordsTest.php
new file mode 100644
index 0000000..f5b192a
--- /dev/null
+++ b/test/Rules/RemoveKeywordsTest.php
@@ -0,0 +1,217 @@
+adjustConfiguration([
+ 'sword' => ['enableImportRules' => true],
+ ]);
+ }
+
+ public function testRemoveKeywordUsingCondition()
+ {
+ $this->adjustConfiguration([
+ 'import' => [
+ 'rules' => [
+ 'keyword1' => [
+ 'type' => 'RemoveKeywords',
+ 'condition' => [
+ 'keyword' => [
+ 'value' => 'RemoveMe',
+ 'remove' => true,
+ ],
+ ],
+ ],
+ ],
+ 'rulesConfigFile' => null,
+ ],
+ ]);
+
+ $doc = Document::new();
+ $keyword = $doc->addSubject();
+ $keyword->setValue('RemoveMe');
+ $keyword->setType('uncontrolled');
+ $keyword->setLanguage('eng');
+
+ $rules = new ImportRules();
+ $rules->init();
+
+ $rules->apply($doc);
+
+ $keywords = $doc->getSubject();
+
+ $this->assertCount(0, $keywords);
+ }
+
+ public function testSetKeywordsSingleValue()
+ {
+ $rule = new RemoveKeywords();
+ $rule->setKeywords('RemoveMe');
+ $this->assertEquals(['RemoveMe'], $rule->getKeywords());
+ }
+
+ public function testSetKeywordsNull()
+ {
+ $rule = new RemoveKeywords();
+ $rule->setKeywords(null);
+ $this->assertNull($rule->getKeywords());
+ }
+
+ public function testSetKeywordsCsv()
+ {
+ $rule = new RemoveKeywords();
+ $rule->setKeywords('keyword1,keyword2,keyword3');
+ $this->assertEquals(['keyword1', 'keyword2', 'keyword3'], $rule->getKeywords());
+ }
+
+ public function testSetKeywordsArray()
+ {
+ $rule = new RemoveKeywords();
+ $rule->setKeywords(['keyword1', 'keyword2', 'keyword3']);
+ $this->assertEquals(['keyword1', 'keyword2', 'keyword3'], $rule->getKeywords());
+ }
+
+ public function testRemoveKeyword()
+ {
+ $doc = Document::new();
+ $keyword = $doc->addSubject();
+ $keyword->setValue('RemoveMe');
+ $keyword->setType('uncontrolled');
+ $keyword->setLanguage('eng');
+
+ $rule = new RemoveKeywords();
+ $rule->setKeywords('RemoveMe');
+
+ $rule->apply($doc);
+
+ $keywords = $doc->getSubject();
+
+ $this->assertCount(0, $keywords);
+ }
+
+ public function testRemoveMultipleKeywords()
+ {
+ $doc = Document::fromArray([
+ 'Subject' => [
+ [
+ 'Language' => 'eng',
+ 'Value' => 'key1',
+ 'Type' => 'uncontrolled',
+ ],
+ [
+ 'Language' => 'eng',
+ 'Value' => 'key2',
+ 'Type' => 'psyndex',
+ ],
+ ],
+ ]);
+
+ $this->assertCount(2, $doc->getSubject());
+
+ $rule = new RemoveKeywords();
+ $rule->setCaseSensitive(false);
+ $rule->setKeywords(['key1', 'KEY2']);
+
+ $rule->apply($doc);
+
+ $this->assertCount(0, $doc->getSubject());
+ }
+
+ public function testRemoveKeywordsUsingType()
+ {
+ $doc = Document::fromArray([
+ 'Subject' => [
+ [
+ 'Language' => 'eng',
+ 'Value' => 'key1',
+ 'Type' => 'uncontrolled',
+ ],
+ [
+ 'Language' => 'eng',
+ 'Value' => 'key2',
+ 'Type' => 'psyndex',
+ ],
+ ],
+ ]);
+
+ $this->assertCount(2, $doc->getSubject());
+
+ $rule = new RemoveKeywords();
+ $rule->setCaseSensitive(false);
+ $rule->setKeywords(['key1', 'KEY2']);
+ $rule->setKeywordType('psyndex');
+
+ $rule->apply($doc);
+
+ $this->assertCount(1, $doc->getSubject());
+ $this->assertEquals('key1', $doc->getSubject(0)->getValue());
+ }
+
+ public function testRemoveKeywordsCaseSensitive()
+ {
+ $doc = Document::fromArray([
+ 'Subject' => [
+ [
+ 'Language' => 'eng',
+ 'Value' => 'key1',
+ 'Type' => 'uncontrolled',
+ ],
+ [
+ 'Language' => 'eng',
+ 'Value' => 'key2',
+ 'Type' => 'psyndex',
+ ],
+ ],
+ ]);
+
+ $this->assertCount(2, $doc->getSubject());
+
+ $rule = new RemoveKeywords();
+ $rule->setCaseSensitive(true);
+ $rule->setKeywords(['key1', 'KEY2']);
+
+ $rule->apply($doc);
+
+ $this->assertCount(1, $doc->getSubject());
+ $this->assertEquals('key2', $doc->getSubject(0)->getValue());
+ }
+}
diff --git a/test/TestAsset/MockAuthAdapter.php b/test/TestAsset/MockAuthAdapter.php
new file mode 100644
index 0000000..007d387
--- /dev/null
+++ b/test/TestAsset/MockAuthAdapter.php
@@ -0,0 +1,58 @@
+user = $user;
+ }
+
+ /**
+ * @return Zend_Auth_Result
+ */
+ public function authenticate()
+ {
+ $identity = ['username' => $this->user];
+ return new Zend_Auth_Result(Zend_Auth_Result::SUCCESS, $identity);
+ }
+}
diff --git a/test/Xml/XmlDocumentTest.php b/test/Xml/XmlDocumentTest.php
index 32f700c..0cb1bc9 100644
--- a/test/Xml/XmlDocumentTest.php
+++ b/test/Xml/XmlDocumentTest.php
@@ -48,7 +48,7 @@ public function testValidation()
{
foreach (new DirectoryIterator(APPLICATION_PATH . '/test/_files') as $fileInfo) {
if (
- $fileInfo->getExtension() !== 'xsd' && ! $fileInfo->isDot()
+ $fileInfo->getExtension() === 'xml' && ! $fileInfo->isDot()
&& strpos($fileInfo->getBasename(), 'import') === 0
) {
$xml = file_get_contents($fileInfo->getRealPath());
diff --git a/test/_files/import-rules-keywords.ini b/test/_files/import-rules-keywords.ini
new file mode 100644
index 0000000..009e519
--- /dev/null
+++ b/test/_files/import-rules-keywords.ini
@@ -0,0 +1,14 @@
+enabledCheck.type = 'AddKeyword'
+enabledCheck.keyword = 'RulesEnabled'
+
+addCol.type = 'AddCollection'
+addCol.condition.keyword = 'oa-gold'
+addCol.collection.roleName = 'import'
+addCol.collection.name = 'col1'
+
+; TODO add rules just for specific tests
+; addCol2.type = 'AddCollection'
+; addCol2.condition.keyword.value = 'oa-green'
+; addCol2.condition.keyword.remove = true
+; addCol2.collection.roleName = 'import'
+; addCol2.collection.name = 'green'
diff --git a/test/_files/import-rules-test.xml b/test/_files/import-rules-test.xml
new file mode 100644
index 0000000..61f11c1
--- /dev/null
+++ b/test/_files/import-rules-test.xml
@@ -0,0 +1,29 @@
+
+
+
+
+ Der Titel
+
+
+ The Title
+
+
+ Deutsch Zusammenfassung
+
+
+
+
+
+ Test
+ oa-green
+ oa-gold
+ ccby
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/test/_files/import-rules.ini b/test/_files/import-rules.ini
new file mode 100644
index 0000000..d60e6ff
--- /dev/null
+++ b/test/_files/import-rules.ini
@@ -0,0 +1,6 @@
+institute1.type = 'AddCollection'
+institute1.condition.account = 'sword'
+institute1.collection.id = [COLLECTION ID]
+
+enabledCheck.type = 'AddKeyword'
+enabledCheck.keyword = 'RulesEnabled'
\ No newline at end of file
diff --git a/test/_files/import2.xml b/test/_files/import2.xml
index a155a68..ffd7320 100644
--- a/test/_files/import2.xml
+++ b/test/_files/import2.xml
@@ -4,5 +4,10 @@
Der Titel
+
+ Test
+ engTest
+ testWithDefaults
+
\ No newline at end of file
diff --git a/test/test.ini b/test/test.ini
index 4174084..f0fa4c7 100644
--- a/test/test.ini
+++ b/test/test.ini
@@ -99,3 +99,6 @@ filetypes.html.mimeType = 'text/html'
; Allow displaying of PDF directly in browser (default for other types 'attachment')
filetypes.pdf.contentDisposition = 'inline'
+
+sword.enableImportRules = 0
+import.rulesConfigFile =