From 861f87514da5ca1da537073fde3df002db1d5661 Mon Sep 17 00:00:00 2001 From: Robbie Averill Date: Tue, 5 Dec 2017 09:11:51 +1300 Subject: [PATCH] API Update Subsite integration, remove Polyhome variant Add a method to clear cached variants from SearchVariant, and a configuration flag for whether a variant should be enabled or not. Add a FullTextSearch TestState class which will globally disable the queuedjobs and fulltextsearch shutdown handlers during tests, and is not used to clear cached variants on each test to prevent global state leakage. Also removes Phockito as a test dependency. --- .travis.yml | 4 +- .upgrade.yml | 1 - README.md | 1 - _config/tests.yml | 8 + src/Search/FullTextSearch.php | 1 + src/Search/Variants/SearchVariant.php | 25 +- .../SearchVariantSiteTreeSubsitesPolyhome.php | 103 -------- src/Search/Variants/SearchVariantSubsites.php | 91 ++++--- .../Variants/SearchVariantVersioned.php | 11 +- src/Solr/Services/Solr4Service.php | 1 + tests/BatchedProcessorTest.php | 41 ++-- tests/SearchUpdaterTest.php | 2 - ...rchVariantSiteTreeSubsitesPolyhomeTest.php | 74 ------ ...iantSiteTreeSubsitesPolyhomeTest_Index.php | 14 -- ...riantSiteTreeSubsitesPolyhomeTest_Item.php | 15 -- tests/SearchVariantSubsitesTest.php | 30 ++- tests/SearchVariantVersionedTest.php | 13 +- tests/SolrIndexSubsitesTest.php | 226 ++++++++++-------- .../SolrIndexSubsitesTest.yml | 9 +- .../SolrIndexSubsitesTest_Index.php | 2 +- tests/SolrIndexTest.php | 27 ++- tests/SolrIndexVersionedTest.php | 118 ++++----- .../SolrDocumentMatcher.php | 39 --- tests/SolrReindexQueuedTest.php | 6 +- tests/SolrReindexTest.php | 2 - tests/State/FullTextSearchState.php | 37 +++ 26 files changed, 377 insertions(+), 524 deletions(-) create mode 100644 _config/tests.yml delete mode 100644 src/Search/Variants/SearchVariantSiteTreeSubsitesPolyhome.php delete mode 100644 tests/SearchVariantSiteTreeSubsitesPolyhomeTest.php delete mode 100644 tests/SearchVariantSiteTreeSubsitesPolyhomeTest/SearchVariantSiteTreeSubsitesPolyhomeTest_Index.php delete mode 100644 tests/SearchVariantSiteTreeSubsitesPolyhomeTest/SearchVariantSiteTreeSubsitesPolyhomeTest_Item.php delete mode 100644 tests/SolrIndexVersionedTest/SolrDocumentMatcher.php create mode 100644 tests/State/FullTextSearchState.php diff --git a/.travis.yml b/.travis.yml index 425ed8a..1fd551e 100644 --- a/.travis.yml +++ b/.travis.yml @@ -12,6 +12,8 @@ matrix: env: DB=MYSQL PHPUNIT_TEST=1 - php: 7.1 env: DB=MYSQL PHPUNIT_COVERAGE_TEST=1 + - php: 7.1 + env: DB=MYSQL PHPUNIT_TEST=1 SUBSITES=1 - php: 7.2 env: DB=MYSQL PHPUNIT_TEST=1 @@ -21,7 +23,7 @@ before_script: - composer validate - composer require --no-update symbiote/silverstripe-queuedjobs ^4.0 - # todo: Add Subsites in + - if [[ $SUBSITES ]]; then composer require --no-update silverstripe/subsites 2.0.x-dev; fi - composer require --no-update silverstripe/installer 4.0.x-dev - composer install --prefer-dist --no-interaction --no-progress --no-suggest --optimize-autoloader --verbose --profile diff --git a/.upgrade.yml b/.upgrade.yml index 76b2360..1210089 100644 --- a/.upgrade.yml +++ b/.upgrade.yml @@ -16,7 +16,6 @@ mappings: SearchUpdater_ObjectHandler: SilverStripe\FullTextSearch\Search\Updaters\SearchUpdater_ObjectHandler SearchVariant: SilverStripe\FullTextSearch\Search\Variants\SearchVariant SearchVariant_Caller: SilverStripe\FullTextSearch\Search\Variants\SearchVariant_Caller - SearchVariantSiteTreeSubsitesPolyhome: SilverStripe\FullTextSearch\Search\Variants\SearchVariantSiteTreeSubsitesPolyhome SearchVariantSubsites: SilverStripe\FullTextSearch\Search\Variants\SearchVariantSubsites SearchVariantVersioned: SilverStripe\FullTextSearch\Search\Variants\SearchVariantVersioned SolrReindexBase: SilverStripe\FullTextSearch\Solr\Reindex\Handlers\SolrReindexBase diff --git a/README.md b/README.md index c6a4dcd..5b3f449 100644 --- a/README.md +++ b/README.md @@ -13,7 +13,6 @@ Adds support for fulltext search engines like Sphinx and Solr to SilverStripe CM ## Requirements * SilverStripe 4.0+ -* (optional) [silverstripe-phockito](https://github.com/hafriedlander/silverstripe-phockito) (for testing) **Note:** For SilverStripe 3.x, please use the [2.x release line](https://github.com/silverstripe/silverstripe-fulltextsearch/tree/2). diff --git a/_config/tests.yml b/_config/tests.yml new file mode 100644 index 0000000..3df630d --- /dev/null +++ b/_config/tests.yml @@ -0,0 +1,8 @@ +--- +Name: fulltextsearchtests +--- +SilverStripe\Core\Injector\Injector: + SilverStripe\Dev\State\SapphireTestState: + properties: + States: + fulltextsearch: '%$SilverStripe\FullTextSearch\Tests\State\FullTextSearchState' diff --git a/src/Search/FullTextSearch.php b/src/Search/FullTextSearch.php index cd80926..c81ec5b 100644 --- a/src/Search/FullTextSearch.php +++ b/src/Search/FullTextSearch.php @@ -1,4 +1,5 @@ config()->get('enabled'); } /** @@ -117,6 +128,14 @@ abstract class SearchVariant } } + /** + * Clear the cached variants + */ + public static function clear_variant_cache() + { + self::$class_variants = []; + } + /** Holds a cache of SearchVariant_Caller instances, one for each class/includeSubclasses setting */ protected static $call_instances = array(); @@ -175,14 +194,14 @@ abstract class SearchVariant /** * Activate all the states in the passed argument * @static - * @param (array) $state. A set of (string)$variantClass => (any)$state pairs , e.g. as returned by + * @param array $state A set of (string)$variantClass => (any)$state pairs , e.g. as returned by * SearchVariant::current_state() * @return void */ public static function activate_state($state) { foreach (self::variants() as $variant => $instance) { - if (isset($state[$variant])) { + if (isset($state[$variant]) && $instance->appliesToEnvironment()) { $instance->activateState($state[$variant]); } } diff --git a/src/Search/Variants/SearchVariantSiteTreeSubsitesPolyhome.php b/src/Search/Variants/SearchVariantSiteTreeSubsitesPolyhome.php deleted file mode 100644 index 54604cc..0000000 --- a/src/Search/Variants/SearchVariantSiteTreeSubsitesPolyhome.php +++ /dev/null @@ -1,103 +0,0 @@ -ID; - } - } - - return $ids; - } - public function activateState($state) - { - if (Controller::has_curr()) { - Subsite::changeSubsite($state); - } else { - // TODO: This is a nasty hack - calling Subsite::changeSubsite after request ends - // throws error because no current controller to access session on - $_REQUEST['SubsiteID'] = $state; - } - } - - public function alterDefinition($class, $index) - { - $self = get_class($this); - - $this->addFilterField($index, '_subsite', array( - 'name' => '_subsite', - 'field' => '_subsite', - 'fullfield' => '_subsite', - 'base' => DataObject::getSchema()->baseDataClass($class), - 'origin' => $class, - 'type' => 'Int', - 'lookup_chain' => array(array('call' => 'variant', 'variant' => $self, 'method' => 'currentState')) - )); - } - - public function alterQuery($query, $index) - { - $subsite = Subsite::currentSubsiteID(); - $query->filter('_subsite', array($subsite, SearchQuery::$missing)); - } - - public static $subsites = null; - - /** - * We need _really_ complicated logic to find just the changed subsites (because we use versions there's no explicit - * deletes, just new versions with different members) so just always use all of them - */ - public function extractManipulationWriteState(&$writes) - { - $self = get_class($this); - - foreach ($writes as $key => $write) { - if (!$this->appliesTo($write['class'], true)) { - continue; - } - - if (self::$subsites === null) { - $query = new SQLSelect('ID', 'Subsite'); - self::$subsites = array_merge(array('0'), $query->execute()->column()); - } - - $next = array(); - - foreach ($write['statefulids'] as $i => $statefulid) { - foreach (self::$subsites as $subsiteID) { - $next[] = array('id' => $statefulid['id'], 'state' => array_merge($statefulid['state'], array($self => $subsiteID))); - } - } - - $writes[$key]['statefulids'] = $next; - } - } -} diff --git a/src/Search/Variants/SearchVariantSubsites.php b/src/Search/Variants/SearchVariantSubsites.php index 5c96ed4..dc55db3 100644 --- a/src/Search/Variants/SearchVariantSubsites.php +++ b/src/Search/Variants/SearchVariantSubsites.php @@ -2,13 +2,21 @@ namespace SilverStripe\FullTextSearch\Search\Variants; +use SilverStripe\Assets\File; +use SilverStripe\CMS\Model\SiteTree; +use SilverStripe\FullTextSearch\Search\SearchIntrospection; +use SilverStripe\FullTextSearch\Search\Queries\SearchQuery; use SilverStripe\ORM\Queries\SQLSelect; use SilverStripe\ORM\DataObject; use SilverStripe\Security\Permission; -use SilverStripe\FullTextSearch\Search\SearchIntrospection; -use SilverStripe\FullTextSearch\Search\Queries\SearchQuery; +use SilverStripe\Subsites\Model\Subsite; +use SilverStripe\Subsites\Extensions\SiteTreeSubsites; +use SilverStripe\Subsites\Extensions\GroupSubsites; +use SilverStripe\Subsites\Extensions\FileSubsites; +use SilverStripe\Subsites\Extensions\SiteConfigSubsites; +use SilverStripe\Subsites\State\SubsiteState; -if (!class_exists('Subsite')) { +if (!class_exists(Subsite::class)) { return; } @@ -16,22 +24,26 @@ class SearchVariantSubsites extends SearchVariant { public function appliesToEnvironment() { - return class_exists('Subsite'); + return class_exists(Subsite::class) && parent::appliesToEnvironment(); } public function appliesTo($class, $includeSubclasses) { + if (!$this->appliesToEnvironment()) { + return false; + } + // Include all DataExtensions that contain a SubsiteID. // TODO: refactor subsites to inherit a common interface, so we can run introspection once only. - return SearchIntrospection::has_extension($class, 'SiteTreeSubsites', $includeSubclasses) || - SearchIntrospection::has_extension($class, 'GroupSubsites', $includeSubclasses) || - SearchIntrospection::has_extension($class, 'FileSubsites', $includeSubclasses) || - SearchIntrospection::has_extension($class, 'SiteConfigSubsites', $includeSubclasses); + return SearchIntrospection::has_extension($class, SiteTreeSubsites::class, $includeSubclasses) + || SearchIntrospection::has_extension($class, GroupSubsites::class, $includeSubclasses) + || SearchIntrospection::has_extension($class, FileSubsites::class, $includeSubclasses) + || SearchIntrospection::has_extension($class, SiteConfigSubsites::class, $includeSubclasses); } public function currentState() { - return (string)Subsite::currentSubsiteID(); + return (string) SubsiteState::singleton()->getSubsiteId(); } public function reindexStates() @@ -39,9 +51,9 @@ class SearchVariantSubsites extends SearchVariant static $ids = null; if ($ids === null) { - $ids = array('0'); - foreach (DataObject::get('Subsite') as $subsite) { - $ids[] = (string)$subsite->ID; + $ids = ['0']; + foreach (Subsite::get() as $subsite) { + $ids[] = (string) $subsite->ID; } } @@ -50,26 +62,34 @@ class SearchVariantSubsites extends SearchVariant public function activateState($state) { - // We always just set the $_GET variable rather than store in Session - this always works, has highest priority - // in Subsite::currentSubsiteID() and doesn't persist unlike Subsite::changeSubsite - $_GET['SubsiteID'] = $state; - Permission::flush_permission_cache(); + if (!$this->appliesToEnvironment()) { + return; + } + + // Note: Setting directly to the SubsiteState because we don't want the subsite ID to be persisted + // like Subsite::changeSubsite would do. + SubsiteState::singleton()->setSubsiteId($state); + Permission::reset(); } public function alterDefinition($class, $index) { $self = get_class($this); + if (!$this->appliesTo($class, true)) { + return; + } + // Add field to root - $this->addFilterField($index, '_subsite', array( + $this->addFilterField($index, '_subsite', [ 'name' => '_subsite', 'field' => '_subsite', 'fullfield' => '_subsite', 'base' => DataObject::getSchema()->baseDataClass($class), 'origin' => $class, 'type' => 'Int', - 'lookup_chain' => array(array('call' => 'variant', 'variant' => $self, 'method' => 'currentState')) - )); + 'lookup_chain' => [['call' => 'variant', 'variant' => $self, 'method' => 'currentState']], + ]); } /** @@ -83,12 +103,12 @@ class SearchVariantSubsites extends SearchVariant */ public function alterQuery($query, $index) { - if ($this->isFieldFiltered('_subsite', $query)) { + if ($this->isFieldFiltered('_subsite', $query) || !$this->appliesToEnvironment()) { return; } - $subsite = Subsite::currentSubsiteID(); - $query->filter('_subsite', array($subsite, SearchQuery::$missing)); + $subsite = $this->currentState(); + $query->filter('_subsite', [$subsite, SearchQuery::$missing]); } /** @@ -98,8 +118,9 @@ class SearchVariantSubsites extends SearchVariant public function extractManipulationWriteState(&$writes) { $self = get_class($this); - $query = new SQLSelect('"ID"', '"Subsite"'); - $subsites = array_merge(array('0'), $query->execute()->column()); + $tableName = DataObject::getSchema()->tableName(Subsite::class); + $query = SQLSelect::create('"ID"', '"' . $tableName . '"'); + $subsites = array_merge(['0'], $query->execute()->column()); foreach ($writes as $key => $write) { $applies = $this->appliesTo($write['class'], true); @@ -107,25 +128,27 @@ class SearchVariantSubsites extends SearchVariant continue; } - if (isset($write['fields']['SiteTree:SubsiteID'])) { - $subsitesForWrite = array($write['fields']['SiteTree:SubsiteID']); - } // files in subsite 0 should be in all subsites as they are global - elseif (isset($write['fields']['File:SubsiteID']) && intval($write['fields']['File:SubsiteID']) !== 0) { - $subsitesForWrite = array($write['fields']['File:SubsiteID']); + if (isset($write['fields'][SiteTree::class . ':SubsiteID'])) { + $subsitesForWrite = [$write['fields'][SiteTree::class . ':SubsiteID']]; + } elseif (isset($write['fields'][File::class . ':SubsiteID']) + && (int) $write['fields'][File::class . ':SubsiteID'] !== 0 + ) { + // files in subsite 0 should be in all subsites as they are global + $subsitesForWrite = [$write['fields'][File::class . ':SubsiteID']]; } else { $subsitesForWrite = $subsites; } - $next = array(); + $next = []; foreach ($write['statefulids'] as $i => $statefulid) { foreach ($subsitesForWrite as $subsiteID) { - $next[] = array( + $next[] = [ 'id' => $statefulid['id'], 'state' => array_merge( $statefulid['state'], - array($self => (string)$subsiteID) - ) - ); + [$self => (string) $subsiteID] + ), + ]; } } $writes[$key]['statefulids'] = $next; diff --git a/src/Search/Variants/SearchVariantVersioned.php b/src/Search/Variants/SearchVariantVersioned.php index 7e98eee..2c60659 100644 --- a/src/Search/Variants/SearchVariantVersioned.php +++ b/src/Search/Variants/SearchVariantVersioned.php @@ -12,6 +12,10 @@ class SearchVariantVersioned extends SearchVariant { public function appliesTo($class, $includeSubclasses) { + if (!$this->appliesToEnvironment()) { + return false; + } + return SearchIntrospection::has_extension($class, Versioned::class, $includeSubclasses); } @@ -57,8 +61,6 @@ class SearchVariantVersioned extends SearchVariant public function extractManipulationState(&$manipulation) { - $self = get_class($this); - foreach ($manipulation as $table => $details) { $class = $details['class']; $stage = Versioned::DRAFT; @@ -70,7 +72,7 @@ class SearchVariantVersioned extends SearchVariant if (ClassInfo::exists($class) && $this->appliesTo($class, false)) { $manipulation[$table]['class'] = $class; - $manipulation[$table]['state'][$self] = $stage; + $manipulation[$table]['state'][get_class($this)] = $stage; } } } @@ -83,10 +85,9 @@ class SearchVariantVersioned extends SearchVariant if (ClassInfo::exists($class) && $this->appliesTo($class, false)) { $table = $class; - $self = get_class($this); foreach ($ids as $i => $statefulid) { - $ids[$i]['state'][$self] = $suffix ? $suffix : Versioned::DRAFT; + $ids[$i]['state'][get_class($this)] = $suffix ?: Versioned::DRAFT; } } } diff --git a/src/Solr/Services/Solr4Service.php b/src/Solr/Services/Solr4Service.php index 73ded53..ab7f42d 100644 --- a/src/Solr/Services/Solr4Service.php +++ b/src/Solr/Services/Solr4Service.php @@ -1,4 +1,5 @@ array( - 'SiteTreeSubsites', - 'Translatable' - ) - ); + protected static $illegal_extensions = [ + SiteTree::class => [ + SiteTreeSubsites::class, + ], + ]; - public function setUpOnce() + public static function setUpBeforeClass() { // Disable illegal extensions if skipping this test - if (class_exists('Subsite') || !interface_exists('Symbiote\QueuedJobs\Services\QueuedJob')) { - $this->illegalExtensions = array(); + if (class_exists(Subsite::class) || !interface_exists(QueuedJob::class)) { + static::$illegal_extensions = []; } - parent::setUpOnce(); + parent::setUpBeforeClass(); } protected function setUp() { - Config::modify()->set(SearchUpdater::class, 'flush_on_shutdown', false); - parent::setUp(); - if (!interface_exists('Symbiote\QueuedJobs\Services\QueuedJob')) { - $this->skipTest = true; + if (!interface_exists(QueuedJob::class)) { $this->markTestSkipped("These tests need the QueuedJobs module installed to run"); } - Config::modify()->set(QueuedJobService::class, 'use_shutdown_function', false); - - if (class_exists('Subsite')) { - $this->skipTest = true; + if (class_exists(Subsite::class)) { $this->markTestSkipped(get_class() . ' skipped when running with subsites'); } @@ -69,7 +64,7 @@ class BatchedProcessorTest extends SapphireTest Config::modify()->set(SearchUpdateBatchedProcessor::class, 'batch_soft_cap', 0); Config::modify()->set(SearchUpdateCommitJobProcessor::class, 'cooldown', 600); - Versioned::set_stage("Stage"); + Versioned::set_stage(Versioned::DRAFT); Injector::inst()->registerService(new BatchedProcessor_QueuedJobService(), QueuedJobService::class); diff --git a/tests/SearchUpdaterTest.php b/tests/SearchUpdaterTest.php index a89077f..f88cea6 100644 --- a/tests/SearchUpdaterTest.php +++ b/tests/SearchUpdaterTest.php @@ -22,8 +22,6 @@ class SearchUpdaterTest extends SapphireTest protected function setUp() { - Config::modify()->set(SearchUpdater::class, 'flush_on_shutdown', false); - parent::setUp(); if (self::$index === null) { diff --git a/tests/SearchVariantSiteTreeSubsitesPolyhomeTest.php b/tests/SearchVariantSiteTreeSubsitesPolyhomeTest.php deleted file mode 100644 index 49cd4ce..0000000 --- a/tests/SearchVariantSiteTreeSubsitesPolyhomeTest.php +++ /dev/null @@ -1,74 +0,0 @@ -markTestSkipped('The subsites polyhome module is not installed'); - } - - if (self::$index === null) { - self::$index = singleton('SearchVariantSiteTreeSubsitesPolyhomeTest_Index'); - } - - if (self::$subsite_a === null) { - self::$subsite_a = new Subsite(); - self::$subsite_a->write(); - self::$subsite_b = new Subsite(); - self::$subsite_b->write(); - } - - FullTextSearch::force_index_list(self::$index); - SearchUpdater::clear_dirty_indexes(); - } - - public function testSavingDirect() - { - // Initial add - - $item = new SearchVariantSiteTreeSubsitesPolyhomeTest_Item(); - $item->write(); - - SearchUpdater::flush_dirty_indexes(); - $this->assertEquals(self::$index->getAdded(array('ID', '_subsite')), array( - array('ID' => $item->ID, '_subsite' => 0) - )); - - // Check that adding to subsites works - - self::$index->reset(); - - $item->setField('AddToSubsite[0]', 1); - $item->setField('AddToSubsite['.(self::$subsite_a->ID).']', 1); - - $item->write(); - - SearchUpdater::flush_dirty_indexes(); - $this->assertEquals(self::$index->getAdded(array('ID', '_subsite')), array( - array('ID' => $item->ID, '_subsite' => 0), - array('ID' => $item->ID, '_subsite' => self::$subsite_a->ID) - )); - $this->assertEquals(self::$index->deleted, array( - array('base' => 'SiteTree', 'id' => $item->ID, 'state' => array( - 'SearchVariantVersioned' => 'Stage', 'SearchVariantSiteTreeSubsitesPolyhome' => self::$subsite_b->ID - )) - )); - } -} diff --git a/tests/SearchVariantSiteTreeSubsitesPolyhomeTest/SearchVariantSiteTreeSubsitesPolyhomeTest_Index.php b/tests/SearchVariantSiteTreeSubsitesPolyhomeTest/SearchVariantSiteTreeSubsitesPolyhomeTest_Index.php deleted file mode 100644 index 4991e6c..0000000 --- a/tests/SearchVariantSiteTreeSubsitesPolyhomeTest/SearchVariantSiteTreeSubsitesPolyhomeTest_Index.php +++ /dev/null @@ -1,14 +0,0 @@ -addClass(SearchVariantSiteTreeSubsitesPolyhomeTest_Item::class); - $this->addFilterField('TestText'); - } -} diff --git a/tests/SearchVariantSiteTreeSubsitesPolyhomeTest/SearchVariantSiteTreeSubsitesPolyhomeTest_Item.php b/tests/SearchVariantSiteTreeSubsitesPolyhomeTest/SearchVariantSiteTreeSubsitesPolyhomeTest_Item.php deleted file mode 100644 index f037d77..0000000 --- a/tests/SearchVariantSiteTreeSubsitesPolyhomeTest/SearchVariantSiteTreeSubsitesPolyhomeTest_Item.php +++ /dev/null @@ -1,15 +0,0 @@ - 'Varchar' - ); -} diff --git a/tests/SearchVariantSubsitesTest.php b/tests/SearchVariantSubsitesTest.php index b90fe77..428bb39 100644 --- a/tests/SearchVariantSubsitesTest.php +++ b/tests/SearchVariantSubsitesTest.php @@ -2,32 +2,40 @@ namespace SilverStripe\FullTextSearch\Tests; +use SilverStripe\Core\Config\Config; +use SilverStripe\Core\Injector\Injector; use SilverStripe\Dev\SapphireTest; +use SilverStripe\FullTextSearch\Search\FullTextSearch; +use SilverStripe\FullTextSearch\Search\Processors\SearchUpdateProcessor; +use SilverStripe\FullTextSearch\Search\Queries\SearchQuery; +use SilverStripe\FullTextSearch\Search\Updaters\SearchUpdater; +use SilverStripe\FullTextSearch\Search\Variants\SearchVariantSubsites; +use SilverStripe\FullTextSearch\Tests\SearchUpdaterTest\SearchUpdaterTest_Container; +use SilverStripe\FullTextSearch\Tests\SolrIndexTest\SolrIndexTest_FakeIndex; +use SilverStripe\Subsites\Model\Subsite; class SearchVariantSubsiteTest extends SapphireTest { - private static $index = null; - - public function setUp() + protected function setUp() { parent::setUp(); // Check versioned available - if (!class_exists('Subsite')) { + if (!class_exists(Subsite::class)) { return $this->markTestSkipped('The subsites module is not installed'); } if (self::$index === null) { - self::$index = singleton('SearchVariantSubsiteTest'); + self::$index = singleton(static::class); } SearchUpdater::bind_manipulation_capture(); - Config::inst()->update('Injector', 'SearchUpdateProcessor', array( - 'class' => 'SearchUpdateImmediateProcessor' - )); + Config::modify()->set(Injector::class, SearchUpdateProcessor::class, [ + 'class' => SearchUpdateImmediateProcessor::class + ]); FullTextSearch::force_index_list(self::$index); SearchUpdater::clear_dirty_indexes(); @@ -41,13 +49,13 @@ class SearchVariantSubsiteTest extends SapphireTest //typical behaviour: nobody is explicitly filtering on subsite, so the search variant adds a filter to the query $this->assertArrayNotHasKey('_subsite', $query->require); $variant = new SearchVariantSubsites(); - $variant->alterDefinition('SearchUpdaterTest_Container', $index); + $variant->alterDefinition(SearchUpdaterTest_Container::class, $index); $variant->alterQuery($query, $index); //check that the "default" query has been put in place: it's not empty, and we're searching on Subsite ID:0 and // an object of SearchQuery::missing $this->assertNotEmpty($query->require['_subsite']); - $this->assertEquals(0, $query->require['_subsite'][0]); + $this->assertEmpty($query->require['_subsite'][0]); //check that SearchQuery::missing is set (by default, it is an object of stdClass) $this->assertInstanceOf('stdClass', $query->require['_subsite'][1]); @@ -71,7 +79,7 @@ class SearchVariantSubsiteTest extends SapphireTest //apply the search variant's definition and query $variant = new SearchVariantSubsites(); - $variant->alterDefinition('SearchUpdaterTest_Container', $index); + $variant->alterDefinition(SearchUpdaterTest_Container::class, $index); //the protected function isFieldFiltered is implicitly tested here $variant->alterQuery($query, $index); diff --git a/tests/SearchVariantVersionedTest.php b/tests/SearchVariantVersionedTest.php index 133d01b..ecda9d3 100644 --- a/tests/SearchVariantVersionedTest.php +++ b/tests/SearchVariantVersionedTest.php @@ -28,8 +28,6 @@ class SearchVariantVersionedTest extends SapphireTest protected function setUp() { - Config::modify()->set(SearchUpdater::class, 'flush_on_shutdown', false); - parent::setUp(); if (self::$index === null) { @@ -130,4 +128,15 @@ class SearchVariantVersionedTest extends SapphireTest array('ID' => $item->ID, '_versionedstage' => 'Live') ), $index->getAdded(array('ID', '_versionedstage'))); } + + public function testCanBeDisabledViaConfig() + { + $variant = new SearchVariantVersioned; + + Config::modify()->set(SearchVariantVersioned::class, 'enabled', true); + $this->assertTrue($variant->appliesToEnvironment()); + + Config::modify()->set(SearchVariantVersioned::class, 'enabled', false); + $this->assertFalse($variant->appliesToEnvironment()); + } } diff --git a/tests/SolrIndexSubsitesTest.php b/tests/SolrIndexSubsitesTest.php index e7ce6ca..d17f2f8 100644 --- a/tests/SolrIndexSubsitesTest.php +++ b/tests/SolrIndexSubsitesTest.php @@ -2,20 +2,32 @@ namespace SilverStripe\FullTextSearch\Tests; +use Apache_Solr_Document; +use Page; +use SilverStripe\Assets\File; +use SilverStripe\Assets\Image; +use SilverStripe\CMS\Model\SiteTree; +use SilverStripe\Core\Config\Config; +use SilverStripe\Core\Injector\Injector; use SilverStripe\Dev\SapphireTest; +use SilverStripe\FullTextSearch\Search\FullTextSearch; +use SilverStripe\FullTextSearch\Search\Processors\SearchUpdateImmediateProcessor; +use SilverStripe\FullTextSearch\Search\Processors\SearchUpdateProcessor; +use SilverStripe\FullTextSearch\Search\Updaters\SearchUpdater; +use SilverStripe\FullTextSearch\Search\Variants\SearchVariantSubsites; +use SilverStripe\FullTextSearch\Solr\Services\Solr4Service; use SilverStripe\FullTextSearch\Tests\SolrIndexSubsitesTest\SolrIndexSubsitesTest_Index; - -if (class_exists('\Phockito')) { - \Phockito::include_hamcrest(false); -} +use SilverStripe\FullTextSearch\Tests\SolrIndexVersionedTest\SolrDocumentMatcher; +use SilverStripe\ORM\DataObject; +use SilverStripe\Subsites\Model\Subsite; +use SilverStripe\Versioned\Versioned; /** * Subsite specific solr testing */ class SolrIndexSubsitesTest extends SapphireTest { - // @todo - // protected static $fixture_file = 'SolrIndexSubsitesTest/SolrIndexSubsitesTest.yml'; + protected static $fixture_file = 'SolrIndexSubsitesTest/SolrIndexSubsitesTest.yml'; /** * @var SolrIndexSubsitesTest_Index @@ -26,31 +38,28 @@ class SolrIndexSubsitesTest extends SapphireTest protected function setUp() { + // Prevent parent::setUp() crashing on db build + if (!class_exists(Subsite::class)) { + static::$fixture_file = null; + } + parent::setUp(); - // Prevent parent::setUp() crashing on db build - if (!class_exists('Subsite')) { - $this->skipTest = true; + if (!class_exists(Subsite::class)) { $this->markTestSkipped("These tests need the Subsite module installed to run"); } $this->server = $_SERVER; - if (!class_exists('\Phockito')) { - $this->skipTest = true; - $this->markTestSkipped("These tests need the \Phockito module installed to run"); - return; - } - if (self::$index === null) { - self::$index = singleton('SolrIndexSubsitesTest_Index'); + self::$index = singleton(SolrIndexSubsitesTest_Index::class); } SearchUpdater::bind_manipulation_capture(); - Config::modify()->set('Injector', 'SearchUpdateProcessor', array( - 'class' => 'SearchUpdateImmediateProcessor' - )); + Config::modify()->set(Injector::class, SearchUpdateProcessor::class, [ + 'class' => SearchUpdateImmediateProcessor::class, + ]); FullTextSearch::force_index_list(self::$index); SearchUpdater::clear_dirty_indexes(); @@ -67,7 +76,9 @@ class SolrIndexSubsitesTest extends SapphireTest protected function getServiceMock() { - return \Phockito::mock('Solr4Service'); + return $this->getMockBuilder(Solr4Service::class) + ->setMethods(['addDocument', 'commit']) + ->getMock(); } /** @@ -83,7 +94,9 @@ class SolrIndexSubsitesTest extends SapphireTest $variants = array(); // Check subsite - if (class_exists('Subsite') && DataObject::getSchema()->hasOneComponent($object->getClassName(), 'Subsite')) { + if (class_exists(Subsite::class) + && DataObject::getSchema()->hasOneComponent($object->getClassName(), 'Subsite') + ) { $variants[] = '"SearchVariantSubsites":"' . $subsiteID. '"'; } @@ -91,7 +104,7 @@ class SolrIndexSubsitesTest extends SapphireTest if ($stage) { $variants[] = '"SearchVariantVersioned":"' . $stage . '"'; } - return $id.'-'.$class.'-{'.implode(',', $variants).'}'; + return $id . '-' . $class . '-{' . implode(',', $variants) . '}'; } public function testPublishing() @@ -100,146 +113,163 @@ class SolrIndexSubsitesTest extends SapphireTest $serviceMock = $this->getServiceMock(); self::$index->setService($serviceMock); - $subsite1 = $this->objFromFixture('Subsite', 'subsite1'); + $subsite1 = $this->objFromFixture(Subsite::class, 'subsite1'); // Add records to first subsite - Versioned::reading_stage('Stage'); + Versioned::set_stage(Versioned::DRAFT); $_SERVER['HTTP_HOST'] = 'www.subsite1.com'; - \Phockito::reset($serviceMock); + $file = new File(); $file->Title = 'My File'; $file->SubsiteID = $subsite1->ID; $file->write(); + $page = new Page(); $page->Title = 'My Page'; $page->SubsiteID = $subsite1->ID; $page->write(); - SearchUpdater::flush_dirty_indexes(); - $doc1 = new SolrDocumentMatcher(array( + + $doc1 = new Apache_Solr_Document([ '_documentid' => $this->getExpectedDocumentId($page, $subsite1->ID, 'Stage'), 'ClassName' => 'Page', 'SiteTree_Title' => 'My Page', '_versionedstage' => 'Stage', - '_subsite' => $subsite1->ID - )); - $doc2 = new SolrDocumentMatcher(array( + '_subsite' => $subsite1->ID, + ]); + + $doc2 = new Apache_Solr_Document([ '_documentid' => $this->getExpectedDocumentId($file, $subsite1->ID), - 'ClassName' => 'File', + 'ClassName' => File::class, 'File_Title' => 'My File', - '_subsite' => $subsite1->ID - )); - \Phockito::verify($serviceMock)->addDocument($doc1); - \Phockito::verify($serviceMock)->addDocument($doc2); + '_subsite' => $subsite1->ID, + ]); + + $serviceMock + ->expects($this->exactly(2)) + ->method('addDocument') + ->withConsecutive($doc1, $doc2); + + SearchUpdater::flush_dirty_indexes(); } public function testCorrectSubsiteIDOnPageWrite() { - $mockWrites = array( - '3367:SiteTree:a:1:{s:22:"SearchVariantVersioned";s:4:"Live";}' => array( - 'base' => 'SiteTree', + $mockWrites = [ + '3367:SiteTree:a:1:{s:22:"SearchVariantVersioned";s:4:"Live";}' => [ + 'base' => 'SilverStripe\\CMS\\Model\\SiteTree', 'class' => 'Page', 'id' => 3367, - 'statefulids' => array( - array( + 'statefulids' => [ + [ 'id' => 3367, - 'state' => array( + 'state' => [ 'SearchVariantVersioned' => 'Live', - ), - ), - ), - 'fields' => array( - 'SiteTree:ClassName' => 'Page', - 'SiteTree:LastEdited' => '2016-12-08 23:55:30', - 'SiteTree:Created' => '2016-11-30 05:23:58', - 'SiteTree:URLSegment' => 'test', - 'SiteTree:Title' => 'Test Title', - 'SiteTree:Content' => '

test content

', - 'SiteTree:MetaDescription' => 'a solr test', - 'SiteTree:ShowInMenus' => 1, - 'SiteTree:ShowInSearch' => 1, - 'SiteTree:Sort' => 77, - 'SiteTree:HasBrokenFile' => 0, - 'SiteTree:HasBrokenLink' => 0, - 'SiteTree:CanViewType' => 'Inherit', - 'SiteTree:CanEditType' => 'Inherit', - 'SiteTree:Locale' => 'en_NZ', - 'SiteTree:SubsiteID' => 0, + ], + ], + ], + 'fields' => [ + 'SilverStripe\\CMS\\Model\\SiteTree:ClassName' => 'Page', + 'SilverStripe\\CMS\\Model\\SiteTree:LastEdited' => '2016-12-08 23:55:30', + 'SilverStripe\\CMS\\Model\\SiteTree:Created' => '2016-11-30 05:23:58', + 'SilverStripe\\CMS\\Model\\SiteTree:URLSegment' => 'test', + 'SilverStripe\\CMS\\Model\\SiteTree:Title' => 'Test Title', + 'SilverStripe\\CMS\\Model\\SiteTree:Content' => '

test content

', + 'SilverStripe\\CMS\\Model\\SiteTree:MetaDescription' => 'a solr test', + 'SilverStripe\\CMS\\Model\\SiteTree:ShowInMenus' => 1, + 'SilverStripe\\CMS\\Model\\SiteTree:ShowInSearch' => 1, + 'SilverStripe\\CMS\\Model\\SiteTree:Sort' => 77, + 'SilverStripe\\CMS\\Model\\SiteTree:HasBrokenFile' => 0, + 'SilverStripe\\CMS\\Model\\SiteTree:HasBrokenLink' => 0, + 'SilverStripe\\CMS\\Model\\SiteTree:CanViewType' => 'Inherit', + 'SilverStripe\\CMS\\Model\\SiteTree:CanEditType' => 'Inherit', + 'SilverStripe\\CMS\\Model\\SiteTree:Locale' => 'en_NZ', + 'SilverStripe\\CMS\\Model\\SiteTree:SubsiteID' => 0, 'Page:ID' => 3367, 'Page:MetaKeywords' => null, - ), - ), - ); + ], + ], + ]; $variant = new SearchVariantSubsites(); $tmpMockWrites = $mockWrites; $variant->extractManipulationWriteState($tmpMockWrites); + foreach ($tmpMockWrites as $mockWrite) { $this->assertCount(1, $mockWrite['statefulids']); $statefulIDs = array_shift($mockWrite['statefulids']); - $this->assertEquals(0, $statefulIDs['state']['SearchVariantSubsites']); + + $this->assertArrayHasKey(SearchVariantSubsites::class, $statefulIDs['state']); + $this->assertEquals(0, $statefulIDs['state'][SearchVariantSubsites::class]); } - $subsite = $this->objFromFixture('Subsite', 'subsite1'); + $subsite = $this->objFromFixture(Subsite::class, 'subsite1'); $tmpMockWrites = $mockWrites; - $tmpMockWrites['3367:SiteTree:a:1:{s:22:"SearchVariantVersioned";s:4:"Live";}']['fields']['SiteTree:SubsiteID'] = $subsite->ID; + $tmpMockWrites['3367:SiteTree:a:1:{s:22:"SearchVariantVersioned";s:4:"Live";}']['fields'][SiteTree::class . ':SubsiteID'] = $subsite->ID; $variant->extractManipulationWriteState($tmpMockWrites); foreach ($tmpMockWrites as $mockWrite) { $this->assertCount(1, $mockWrite['statefulids']); $statefulIDs = array_shift($mockWrite['statefulids']); - $this->assertEquals($subsite->ID, $statefulIDs['state']['SearchVariantSubsites']); + + $this->assertArrayHasKey(SearchVariantSubsites::class, $statefulIDs['state']); + $this->assertEquals($subsite->ID, $statefulIDs['state'][SearchVariantSubsites::class]); } } public function testCorrectSubsiteIDOnFileWrite() { - $subsiteIDs = array('0') + $this->allFixtureIDs('Subsite'); - $mockWrites = array( - '35910:File:a:0:{}' => array( - 'base' => 'File', - 'class' => 'File', + $subsiteIDs = ['0'] + $this->allFixtureIDs(Subsite::class); + $mockWrites = [ + '35910:File:a:0:{}' => [ + 'base' => File::class, + 'class' => File::class, 'id' => 35910, - 'statefulids' => array( - array( + 'statefulids' => [ + [ 'id' => 35910, - 'state' => array(), - ), - ), - 'fields' => array( - 'File:ClassName' => 'Image', - 'File:ShowInSearch' => 1, - 'File:ParentID' => 26470, - 'File:Filename' => 'assets/Uploads/pic.jpg', - 'File:Name' => 'pic.jpg', - 'File:Title' => 'pic', - 'File:SubsiteID' => 0, - 'File:OwnerID' => 661, - 'File:CurrentVersionID' => 22038, - 'File:LastEdited' => '2016-12-09 00:35:13', - ), - ), - ); + 'state' => [], + ], + ], + 'fields' => [ + File::class . ':ClassName' => Image::class, + File::class . ':ShowInSearch' => 1, + File::class . ':ParentID' => 26470, + File::class . ':Filename' => 'assets/Uploads/pic.jpg', + File::class . ':Name' => 'pic.jpg', + File::class . ':Title' => 'pic', + File::class . ':SubsiteID' => 0, + File::class . ':OwnerID' => 661, + File::class . ':CurrentVersionID' => 22038, + File::class . ':LastEdited' => '2016-12-09 00:35:13', + ], + ], + ]; $variant = new SearchVariantSubsites(); $tmpMockWrites = $mockWrites; $variant->extractManipulationWriteState($tmpMockWrites); foreach ($tmpMockWrites as $mockWrite) { $this->assertCount(count($subsiteIDs), $mockWrite['statefulids']); foreach ($mockWrite['statefulids'] as $statefulIDs) { - $this->assertTrue( - in_array($statefulIDs['state']['SearchVariantSubsites'], $subsiteIDs), - sprintf('Failed to assert that %s is in list of valid subsites: %s', $statefulIDs['state']['SearchVariantSubsites'], implode(', ', $subsiteIDs)) + $this->assertContains( + $statefulIDs['state'][SearchVariantSubsites::class], + $subsiteIDs, + sprintf( + 'Failed to assert that %s is in list of valid subsites: %s', + $statefulIDs['state'][SearchVariantSubsites::class], + implode(', ', $subsiteIDs) + ) ); } } - $subsite = $this->objFromFixture('Subsite', 'subsite1'); + $subsite = $this->objFromFixture(Subsite::class, 'subsite1'); $tmpMockWrites = $mockWrites; - $tmpMockWrites['35910:File:a:0:{}']['fields']['File:SubsiteID'] = $subsite->ID; + $tmpMockWrites['35910:File:a:0:{}']['fields'][File::class . ':SubsiteID'] = $subsite->ID; $variant->extractManipulationWriteState($tmpMockWrites); foreach ($tmpMockWrites as $mockWrite) { $this->assertCount(1, $mockWrite['statefulids']); $statefulIDs = array_shift($mockWrite['statefulids']); - $this->assertEquals($subsite->ID, $statefulIDs['state']['SearchVariantSubsites']); + $this->assertEquals($subsite->ID, $statefulIDs['state'][SearchVariantSubsites::class]); } } } diff --git a/tests/SolrIndexSubsitesTest/SolrIndexSubsitesTest.yml b/tests/SolrIndexSubsitesTest/SolrIndexSubsitesTest.yml index 2975e83..dc67bbe 100644 --- a/tests/SolrIndexSubsitesTest/SolrIndexSubsitesTest.yml +++ b/tests/SolrIndexSubsitesTest/SolrIndexSubsitesTest.yml @@ -1,16 +1,17 @@ -Subsite: +SilverStripe\Subsites\Model\Subsite: main: Title: Template subsite1: Title: 'Subsite1 Template' subsite2: Title: 'Subsite2 Template' -SubsiteDomain: + +SilverStripe\Subsites\Model\SubsiteDomain: subsite1: - SubsiteID: =>Subsite.subsite1 + SubsiteID: =>SilverStripe\Subsites\Model\Subsite.subsite1 Domain: www.subsite1.com Protocol: automatic subsite2: - SubsiteID: =>Subsite.subsite2 + SubsiteID: =>SilverStripe\Subsites\Model\Subsite.subsite2 Domain: www.subsite2.com Protocol: automatic diff --git a/tests/SolrIndexSubsitesTest/SolrIndexSubsitesTest_Index.php b/tests/SolrIndexSubsitesTest/SolrIndexSubsitesTest_Index.php index 620f632..1d16d7d 100644 --- a/tests/SolrIndexSubsitesTest/SolrIndexSubsitesTest_Index.php +++ b/tests/SolrIndexSubsitesTest/SolrIndexSubsitesTest_Index.php @@ -2,9 +2,9 @@ namespace SilverStripe\FullTextSearch\Tests\SolrIndexSubsitesTest; -use SilverStripe\FullTextSearch\Solr\SolrIndex; use SilverStripe\Assets\File; use SilverStripe\CMS\Model\SiteTree; +use SilverStripe\FullTextSearch\Solr\SolrIndex; class SolrIndexSubsitesTest_Index extends SolrIndex { diff --git a/tests/SolrIndexTest.php b/tests/SolrIndexTest.php index 7be2fc5..3b55387 100644 --- a/tests/SolrIndexTest.php +++ b/tests/SolrIndexTest.php @@ -7,18 +7,20 @@ use SilverStripe\Core\Environment; use SilverStripe\Core\Injector\Injector; use SilverStripe\Core\Kernel; use SilverStripe\Dev\SapphireTest; -use SilverStripe\FullTextSearch\Tests\SolrIndexTest\SolrIndexTest_AmbiguousRelationIndex; -use SilverStripe\FullTextSearch\Tests\SolrIndexTest\SolrIndexTest_AmbiguousRelationInheritedIndex; -use SilverStripe\FullTextSearch\Tests\SolrIndexTest\SolrIndexTest_FakeIndex; -use SilverStripe\FullTextSearch\Tests\SolrIndexTest\SolrIndexTest_FakeIndex2; -use SilverStripe\FullTextSearch\Tests\SolrIndexTest\SolrIndexTest_BoostedIndex; +use SilverStripe\FullTextSearch\Search\Queries\SearchQuery; +use SilverStripe\FullTextSearch\Search\Variants\SearchVariantSubsites; +use SilverStripe\FullTextSearch\Solr\Services\Solr3Service; use SilverStripe\FullTextSearch\Tests\SearchUpdaterTest\SearchUpdaterTest_Container; use SilverStripe\FullTextSearch\Tests\SearchUpdaterTest\SearchUpdaterTest_HasOne; use SilverStripe\FullTextSearch\Tests\SearchUpdaterTest\SearchUpdaterTest_HasMany; use SilverStripe\FullTextSearch\Tests\SearchUpdaterTest\SearchUpdaterTest_ManyMany; use SilverStripe\FullTextSearch\Tests\SearchUpdaterTest\SearchUpdaterTest_OtherContainer; -use SilverStripe\FullTextSearch\Search\Queries\SearchQuery; -use SilverStripe\FullTextSearch\Solr\Services\Solr3Service; +use SilverStripe\FullTextSearch\Tests\SolrIndexTest\SolrIndexTest_AmbiguousRelationIndex; +use SilverStripe\FullTextSearch\Tests\SolrIndexTest\SolrIndexTest_AmbiguousRelationInheritedIndex; +use SilverStripe\FullTextSearch\Tests\SolrIndexTest\SolrIndexTest_BoostedIndex; +use SilverStripe\FullTextSearch\Tests\SolrIndexTest\SolrIndexTest_FakeIndex; +use SilverStripe\FullTextSearch\Tests\SolrIndexTest\SolrIndexTest_FakeIndex2; +use SilverStripe\Subsites\Model\Subsite; class SolrIndexTest extends SapphireTest { @@ -151,6 +153,10 @@ class SolrIndexTest extends SapphireTest */ public function testBoostedField() { + if (class_exists(Subsite::class)) { + Config::modify()->set(SearchVariantSubsites::class, 'enabled', false); + } + /** @var Solr3Service|PHPUnit_Framework_MockObject_MockObject $serviceMock */ $serviceMock = $this->getMockBuilder(Solr3Service::class) ->setMethods(['search']) @@ -162,8 +168,11 @@ class SolrIndexTest extends SapphireTest $this->equalTo('+term'), $this->anything(), $this->anything(), - $this->equalTo(['qf' => SearchUpdaterTest_Container::class . '_Field1^1.5 ' . SearchUpdaterTest_Container::class . '_Field2^2.1 _text', - 'fq' => '+(_versionedstage:"" (*:* -_versionedstage:[* TO *]))']), + $this->equalTo([ + 'qf' => SearchUpdaterTest_Container::class . '_Field1^1.5 ' + . SearchUpdaterTest_Container::class . '_Field2^2.1 _text', + 'fq' => '+(_versionedstage:"" (*:* -_versionedstage:[* TO *]))', + ]), $this->anything() )->willReturn($this->getFakeRawSolrResponse()); diff --git a/tests/SolrIndexVersionedTest.php b/tests/SolrIndexVersionedTest.php index 50c004c..14af82d 100644 --- a/tests/SolrIndexVersionedTest.php +++ b/tests/SolrIndexVersionedTest.php @@ -2,8 +2,10 @@ namespace SilverStripe\FullTextSearch\Tests; +use Apache_Solr_Document; use SilverStripe\Dev\SapphireTest; use SilverStripe\Core\Config\Config; +use SilverStripe\Core\Injector\Injector; use SilverStripe\ORM\DataObject; use SilverStripe\FullTextSearch\Search\FullTextSearch; use SilverStripe\FullTextSearch\Search\SearchIntrospection; @@ -15,23 +17,28 @@ use SilverStripe\FullTextSearch\Tests\SolrIndexVersionedTest\SolrVersionedTest_I use SilverStripe\FullTextSearch\Search\Processors\SearchUpdateProcessor; use SilverStripe\FullTextSearch\Search\Processors\SearchUpdateImmediateProcessor; use SilverStripe\FullTextSearch\Search\Updaters\SearchUpdater; +use SilverStripe\FullTextSearch\Search\Variants\SearchVariantSubsites; use SilverStripe\FullTextSearch\Search\Variants\SearchVariantVersioned; +use SilverStripe\Subsites\Model\Subsite; use SilverStripe\Versioned\Versioned; class SolrIndexVersionedTest extends SapphireTest { + protected $usesDatabase = true; + protected $oldMode = null; protected static $index = null; - protected static $extra_dataobjects = array( + protected static $extra_dataobjects = [ SearchVariantVersionedTest_Item::class, - SolrIndexVersionedTest_Object::class - ); + SolrIndexVersionedTest_Object::class, + ]; protected function setUp() { - Config::modify()->set(SearchUpdater::class, 'flush_on_shutdown', false); + // Need to be set before parent::setUp() since they're executed before the tests start + Config::modify()->set(SearchVariantSubsites::class, 'enabled', false); parent::setUp(); @@ -41,18 +48,18 @@ class SolrIndexVersionedTest extends SapphireTest SearchUpdater::bind_manipulation_capture(); - Config::modify()->set(Injector::class, SearchUpdateProcessor::class, array( + Config::modify()->set(Injector::class, SearchUpdateProcessor::class, [ 'class' => SearchUpdateImmediateProcessor::class - )); + ]); FullTextSearch::force_index_list(self::$index); SearchUpdater::clear_dirty_indexes(); $this->oldMode = Versioned::get_reading_mode(); - Versioned::set_stage('Stage'); + Versioned::set_stage(Versioned::DRAFT); } - public function tearDown() + protected function tearDown() { Versioned::set_reading_mode($this->oldMode); parent::tearDown(); @@ -80,13 +87,7 @@ class SolrIndexVersionedTest extends SapphireTest { $id = $object->ID; $class = DataObject::getSchema()->baseDataClass($object); - // Prevent subsites from breaking tests - // TODO: Subsites currently isn't migrated. This needs to be fixed when subsites is fixed. - $subsites = ''; - if (class_exists('Subsite') && DataObject::getSchema()->hasOneComponent($object->getClassName(), 'Subsite')) { - $subsites = '"SearchVariantSubsites":"0",'; - } - return $id.'-'.$class.'-{'.$subsites. json_encode(SearchVariantVersioned::class) . ':"'.$stage.'"}'; + return $id.'-'.$class.'-{'.json_encode(SearchVariantVersioned::class).':"'.$stage.'"}'; } /** @@ -98,12 +99,12 @@ class SolrIndexVersionedTest extends SapphireTest */ protected function getSolrDocument($class, $object, $value, $stage) { - $doc = new \Apache_Solr_Document(); + $doc = new Apache_Solr_Document(); $doc->setField('_documentid', $this->getExpectedDocumentId($object, $stage)); $doc->setField('ClassName', $class); $doc->setField(DataObject::getSchema()->baseDataClass($class) . '_TestText', $value); $doc->setField('_versionedstage', $stage); - $doc->setField('ID', $object->ID); + $doc->setField('ID', (int) $object->ID); $doc->setField('ClassHierarchy', SearchIntrospection::hierarchy($class)); $doc->setFieldBoost('ID', false); $doc->setFieldBoost('ClassHierarchy', false); @@ -114,89 +115,52 @@ class SolrIndexVersionedTest extends SapphireTest public function testPublishing() { // Check that write updates Stage - Versioned::set_stage('Stage'); + Versioned::set_stage(Versioned::DRAFT); $item = new SearchVariantVersionedTest_Item(array('TestText' => 'Foo')); $item->write(); $object = new SolrIndexVersionedTest_Object(array('TestText' => 'Bar')); $object->write(); - $doc1 = $this->getSolrDocument(SearchVariantVersionedTest_Item::class, $item, 'Foo', 'Stage'); - $doc2 = $this->getSolrDocument(SolrIndexVersionedTest_Object::class, $object, 'Bar', 'Stage'); + $doc1 = $this->getSolrDocument(SearchVariantVersionedTest_Item::class, $item, 'Foo', Versioned::DRAFT); + $doc2 = $this->getSolrDocument(SolrIndexVersionedTest_Object::class, $object, 'Bar', Versioned::DRAFT); // Ensure correct call is made to Solr $this->getServiceMock(['addDocument', 'commit']) ->expects($this->exactly(2)) ->method('addDocument') ->withConsecutive( - [ - $this->equalTo($doc1), - $this->anything(), - $this->anything(), - $this->anything(), - $this->anything() - ], - [ - $this->equalTo($doc2), - $this->anything(), - $this->anything(), - $this->anything(), - $this->anything() - ] + [$this->equalTo($doc1)], + [$this->equalTo($doc2)] ); SearchUpdater::flush_dirty_indexes(); - // Check that write updates Live - Versioned::set_stage('Stage'); + Versioned::set_stage(Versioned::DRAFT); $item = new SearchVariantVersionedTest_Item(array('TestText' => 'Foo')); $item->write(); - $item->copyVersionToStage('Stage', 'Live'); + $item->copyVersionToStage(Versioned::DRAFT, Versioned::LIVE); $object = new SolrIndexVersionedTest_Object(array('TestText' => 'Bar')); $object->write(); - $object->copyVersionToStage('Stage', 'Live'); + $object->copyVersionToStage(Versioned::DRAFT, Versioned::LIVE); - $doc1 = $this->getSolrDocument(SearchVariantVersionedTest_Item::class, $item, 'Foo', 'Stage'); - $doc2 = $this->getSolrDocument(SearchVariantVersionedTest_Item::class, $item, 'Foo', 'Live'); - $doc3 = $this->getSolrDocument(SolrIndexVersionedTest_Object::class, $object, 'Bar', 'Stage'); - $doc4 = $this->getSolrDocument(SolrIndexVersionedTest_Object::class, $object, 'Bar', 'Live'); + $doc1 = $this->getSolrDocument(SearchVariantVersionedTest_Item::class, $item, 'Foo', Versioned::DRAFT); + $doc2 = $this->getSolrDocument(SearchVariantVersionedTest_Item::class, $item, 'Foo', Versioned::LIVE); + $doc3 = $this->getSolrDocument(SolrIndexVersionedTest_Object::class, $object, 'Bar', Versioned::DRAFT); + $doc4 = $this->getSolrDocument(SolrIndexVersionedTest_Object::class, $object, 'Bar', Versioned::LIVE); // Ensure correct call is made to Solr $this->getServiceMock(['addDocument', 'commit']) ->expects($this->exactly(4)) ->method('addDocument') ->withConsecutive( - [ - $this->equalTo($doc1), - $this->anything(), - $this->anything(), - $this->anything(), - $this->anything() - ], - [ - $this->equalTo($doc2), - $this->anything(), - $this->anything(), - $this->anything(), - $this->anything() - ], - [ - $this->equalTo($doc3), - $this->anything(), - $this->anything(), - $this->anything(), - $this->anything() - ], - [ - $this->equalTo($doc4), - $this->anything(), - $this->anything(), - $this->anything(), - $this->anything() - ] + [$doc1], + [$doc2], + [$doc3], + [$doc4] ); SearchUpdater::flush_dirty_indexes(); @@ -205,12 +169,12 @@ class SolrIndexVersionedTest extends SapphireTest public function testDelete() { // Delete the live record (not the stage) - Versioned::set_stage('Stage'); + Versioned::set_stage(Versioned::DRAFT); $item = new SearchVariantVersionedTest_Item(array('TestText' => 'Too')); $item->write(); - $item->copyVersionToStage('Stage', 'Live'); - Versioned::set_stage('Live'); + $item->copyVersionToStage(Versioned::DRAFT, Versioned::LIVE); + Versioned::set_stage(Versioned::LIVE); $id = clone $item; $item->delete(); @@ -218,16 +182,16 @@ class SolrIndexVersionedTest extends SapphireTest $this->getServiceMock(['addDocument', 'commit', 'deleteById']) ->expects($this->exactly(1)) ->method('deleteById') - ->with($this->equalTo($this->getExpectedDocumentId($id, 'Live'))); + ->with($this->getExpectedDocumentId($id, Versioned::LIVE)); SearchUpdater::flush_dirty_indexes(); // Delete the stage record - Versioned::set_stage('Stage'); + Versioned::set_stage(Versioned::DRAFT); $item = new SearchVariantVersionedTest_Item(array('TestText' => 'Too')); $item->write(); - $item->copyVersionToStage('Stage', 'Live'); + $item->copyVersionToStage(Versioned::DRAFT, Versioned::LIVE); $id = clone $item; $item->delete(); @@ -235,7 +199,7 @@ class SolrIndexVersionedTest extends SapphireTest $this->getServiceMock(['addDocument', 'commit', 'deleteById']) ->expects($this->exactly(1)) ->method('deleteById') - ->with($this->equalTo($this->getExpectedDocumentId($id, 'Stage'))); + ->with($this->getExpectedDocumentId($id, Versioned::DRAFT)); SearchUpdater::flush_dirty_indexes(); } diff --git a/tests/SolrIndexVersionedTest/SolrDocumentMatcher.php b/tests/SolrIndexVersionedTest/SolrDocumentMatcher.php deleted file mode 100644 index f264010..0000000 --- a/tests/SolrIndexVersionedTest/SolrDocumentMatcher.php +++ /dev/null @@ -1,39 +0,0 @@ -properties = $properties; - } - - public function describeTo(\Hamcrest_Description $description) - { - $description->appendText('\Apache_Solr_Document with properties '.var_export($this->properties, true)); - } - - public function matches($item) - { - if (! ($item instanceof \Apache_Solr_Document)) { - return false; - } - - foreach ($this->properties as $key => $value) { - if ($item->{$key} != $value) { - return false; - } - } - - return true; - } -} diff --git a/tests/SolrReindexQueuedTest.php b/tests/SolrReindexQueuedTest.php index 1328692..d269007 100644 --- a/tests/SolrReindexQueuedTest.php +++ b/tests/SolrReindexQueuedTest.php @@ -49,17 +49,13 @@ class SolrReindexQueuedTest extends SapphireTest protected function setUp() { - Config::modify()->set(SearchUpdater::class, 'flush_on_shutdown', false); - parent::setUp(); - if (!interface_exists('Symbiote\QueuedJobs\Services\QueuedJob')) { + if (!interface_exists(QueuedJob::class)) { $this->skipTest = true; return $this->markTestSkipped("These tests need the QueuedJobs module installed to run"); } - Config::modify()->set(QueuedJobService::class, 'use_shutdown_function', false); - // Set queued handler for reindex Config::modify()->set(Injector::class, SolrReindexHandler::class, array( 'class' => SolrReindexQueuedHandler::class diff --git a/tests/SolrReindexTest.php b/tests/SolrReindexTest.php index 75ef79a..c88614e 100644 --- a/tests/SolrReindexTest.php +++ b/tests/SolrReindexTest.php @@ -43,8 +43,6 @@ class SolrReindexTest extends SapphireTest protected function setUp() { - Config::modify()->set(SearchUpdater::class, 'flush_on_shutdown', false); - parent::setUp(); // Set test handler for reindex diff --git a/tests/State/FullTextSearchState.php b/tests/State/FullTextSearchState.php new file mode 100644 index 0000000..abb098e --- /dev/null +++ b/tests/State/FullTextSearchState.php @@ -0,0 +1,37 @@ +set(SearchUpdater::class, 'flush_on_shutdown', false); + + if (class_exists(QueuedJobService::class)) { + Config::modify()->set(QueuedJobService::class, 'use_shutdown_function', false); + } + } + + public function tearDownOnce($class) + { + // noop + } +}