skipTest = true; $this->markTestSkipped("These tests need the Phockito module installed to run"); return; } // Check versioned available if (!class_exists('Versioned')) { $this->skipTest = true; $this->markTestSkipped('The versioned decorator is not installed'); return; } if (self::$index === null) { self::$index = singleton('SolrVersionedTest_Index'); } SearchUpdater::bind_manipulation_capture(); Config::inst()->update('Injector', 'SearchUpdateProcessor', array( 'class' => 'SearchUpdateImmediateProcessor' )); FullTextSearch::force_index_list(self::$index); SearchUpdater::clear_dirty_indexes(); $this->oldMode = Versioned::get_reading_mode(); Versioned::reading_stage('Stage'); } public function tearDown() { Versioned::set_reading_mode($this->oldMode); parent::tearDown(); } protected function getServiceMock() { return Phockito::mock('Solr3Service'); } /** * @param DataObject $object Item being added * @param string $stage * @return string */ protected function getExpectedDocumentId($object, $stage) { $id = $object->ID; $class = ClassInfo::baseDataClass($object); // Prevent subsites from breaking tests $subsites = ''; if(class_exists('Subsite') && $object->hasOne('Subsite')) { $subsites = '"SearchVariantSubsites":"0",'; } return $id.'-'.$class.'-{'.$subsites.'"SearchVariantVersioned":"'.$stage.'"}'; } public function testPublishing() { // Setup mocks $serviceMock = $this->getServiceMock(); self::$index->setService($serviceMock); // Check that write updates Stage Versioned::reading_stage('Stage'); Phockito::reset($serviceMock); $item = new SearchVariantVersionedTest_Item(array('TestText' => 'Foo')); $item->write(); $object = new SolrIndexVersionedTest_Object(array('TestText' => 'Bar')); $object->write(); SearchUpdater::flush_dirty_indexes(); $doc1 = new SolrDocumentMatcher(array( '_documentid' => $this->getExpectedDocumentId($item, 'Stage'), 'ClassName' => 'SearchVariantVersionedTest_Item', 'SearchVariantVersionedTest_Item_TestText' => 'Foo', '_versionedstage' => 'Stage' )); $doc2 = new SolrDocumentMatcher(array( '_documentid' => $this->getExpectedDocumentId($object, 'Stage'), 'ClassName' => 'SolrIndexVersionedTest_Object', 'SolrIndexVersionedTest_Object_TestText' => 'Bar', '_versionedstage' => 'Stage' )); Phockito::verify($serviceMock)->addDocument($doc1); Phockito::verify($serviceMock)->addDocument($doc2); // Check that write updates Live Versioned::reading_stage('Stage'); Phockito::reset($serviceMock); $item = new SearchVariantVersionedTest_Item(array('TestText' => 'Foo')); $item->write(); $item->publish('Stage', 'Live'); $object = new SolrIndexVersionedTest_Object(array('TestText' => 'Bar')); $object->write(); $object->publish('Stage', 'Live'); SearchUpdater::flush_dirty_indexes(); $doc = new SolrDocumentMatcher(array( '_documentid' => $this->getExpectedDocumentId($item, 'Live'), 'ClassName' => 'SearchVariantVersionedTest_Item', 'SearchVariantVersionedTest_Item_TestText' => 'Foo', '_versionedstage' => 'Live' )); $doc2 = new SolrDocumentMatcher(array( '_documentid' => $this->getExpectedDocumentId($object, 'Live'), 'ClassName' => 'SolrIndexVersionedTest_Object', 'SolrIndexVersionedTest_Object_TestText' => 'Bar', '_versionedstage' => 'Live' )); Phockito::verify($serviceMock)->addDocument($doc); Phockito::verify($serviceMock)->addDocument($doc2); } public function testDelete() { // Setup mocks $serviceMock = $this->getServiceMock(); self::$index->setService($serviceMock); // Delete the live record (not the stage) Versioned::reading_stage('Stage'); Phockito::reset($serviceMock); $item = new SearchVariantVersionedTest_Item(array('TestText' => 'Too')); $item->write(); $item->publish('Stage', 'Live'); Versioned::reading_stage('Live'); $id = clone $item; $item->delete(); SearchUpdater::flush_dirty_indexes(); Phockito::verify($serviceMock, 1) ->deleteById($this->getExpectedDocumentId($id, 'Live')); Phockito::verify($serviceMock, 0) ->deleteById($this->getExpectedDocumentId($id, 'Stage')); // Delete the stage record Versioned::reading_stage('Stage'); Phockito::reset($serviceMock); $item = new SearchVariantVersionedTest_Item(array('TestText' => 'Too')); $item->write(); $item->publish('Stage', 'Live'); $id = clone $item; $item->delete(); SearchUpdater::flush_dirty_indexes(); Phockito::verify($serviceMock, 1) ->deleteById($this->getExpectedDocumentId($id, 'Stage')); Phockito::verify($serviceMock, 0) ->deleteById($this->getExpectedDocumentId($id, 'Live')); } } class SolrVersionedTest_Index extends SolrIndex { public function init() { $this->addClass('SearchVariantVersionedTest_Item'); $this->addClass('SolrIndexVersionedTest_Object'); $this->addFilterField('TestText'); $this->addFulltextField('Content'); } } if (!class_exists('Phockito')) { return; } class SolrDocumentMatcher extends Hamcrest_BaseMatcher { protected $properties; public function __construct($properties) { $this->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; } } /** * Non-sitetree versioned dataobject */ class SolrIndexVersionedTest_Object extends DataObject implements TestOnly { private static $extensions = array( 'Versioned' ); private static $db = array( 'Title' => 'Varchar', 'Content' => 'Text', 'TestText' => 'Varchar', ); }