diff --git a/module/VuFind/tests/unit-tests/src/VuFindTest/Recommend/RandomRecommendTest.php b/module/VuFind/tests/unit-tests/src/VuFindTest/Recommend/RandomRecommendTest.php index 9bffc41c3098a363d6be2ca7eb5615f737b1c44f..c7f317634767aab9ecf79d178210aef574115587 100644 --- a/module/VuFind/tests/unit-tests/src/VuFindTest/Recommend/RandomRecommendTest.php +++ b/module/VuFind/tests/unit-tests/src/VuFindTest/Recommend/RandomRecommendTest.php @@ -57,13 +57,173 @@ class RandomRecommendTest extends TestCase } /** - * Test load + * Test settings + * + * @return void + */ + public function testCanSetSettings() + { + //[backend]:[limit]:[display mode]:[random mode]:[minimumset]:[facet1]:[facetvalue1] + $this->recommend->setConfig("Solr:10:mixed:disregard:20:facet1:value1:facet2:value2"); + $this->assertEquals( + "Solr", \PHPUnit_Framework_Assert::readAttribute( + $this->recommend, 'backend' + ) + ); + $this->assertEquals( + "10", \PHPUnit_Framework_Assert::readAttribute( + $this->recommend, 'limit' + ) + ); + $this->assertEquals( + "mixed", \PHPUnit_Framework_Assert::readAttribute( + $this->recommend, 'displayMode' + ) + ); + $this->assertEquals( + "disregard", \PHPUnit_Framework_Assert::readAttribute( + $this->recommend, 'mode' + ) + ); + $this->assertEquals( + "20", \PHPUnit_Framework_Assert::readAttribute( + $this->recommend, 'minimum' + ) + ); + $filters = \PHPUnit_Framework_Assert::readAttribute($this->recommend, 'filters'); + $this->assertInternalType("array", $filters); + $this->assertCount(2, $filters); + $this->assertEquals("facet1:value1", $filters[0]); + $this->assertEquals("facet2:value2", $filters[1]); + } + + /** + * Test initialisation + * + * @return void + */ + public function testCanInitialise() + { + $service = $this->getMock('VuFindSearch\Service'); + $paramManager = $this->getMock('VuFind\Search\Params\PluginManager'); + $recommend = new Random($service, $paramManager); + + // Use Solr since some Base components are abstract: + $params = $this->getServiceManager()->get('VuFind\SearchParamsPluginManager') + ->get('Solr'); + $query = $this->getFixture('query'); + $params->setBasicSearch($query->getString(), $query->getHandler()); + $request = $this->getMock('\Zend\StdLib\Parameters'); + + $service->expects($this->once())->method('random') + ->with( + $this->equalTo("Solr"), + $this->equalTo($params->getQuery()), + $this->equalTo(10) + )->will($this->returnValue($this->getMock('VuFindTest\Recommend\TestSearchResultsForRandom'))); + + + $recommend->setConfig("Solr:10:mixed:retain:20:facet1:value1:facet2:value2"); + $recommend->init($params, $request); + } + + /** + * Test initialisation + * + * @return void + */ + public function testCanInitialiseInDisregardMode() + { + $service = $this->getMock('VuFindSearch\Service'); + $paramManager = $this->getMock('VuFind\Search\Params\PluginManager'); + $recommend = new Random($service, $paramManager); + + $paramManager->expects($this->once())->method('get') + ->with($this->equalTo("Solr")) + ->will($this->returnValue( + $this->getServiceManager()->get('VuFind\SearchParamsPluginManager') + ->get('Solr') + ) + ); + + // Use Solr since some Base components are abstract: + $params = $this->getServiceManager()->get('VuFind\SearchParamsPluginManager') + ->get('Solr'); + $query = $this->getFixture('query'); + $params->setBasicSearch($query->getString(), $query->getHandler()); + $request = $this->getMock('\Zend\StdLib\Parameters'); + + $service->expects($this->once())->method('random') + ->with($this->equalTo("Solr")) + ->will($this->returnValue($this->getMock('VuFindTest\Recommend\TestSearchResultsForRandom'))); + + $recommend->setConfig("Solr:10:mixed:disregard:20:facet1:value1:facet2:value2"); + $recommend->init($params, $request); + } + + /** + * Test initialisation + * + * @return void + */ + public function testWillReturnEmptyForMinimumResultLimit() + { + $service = $this->getMock('VuFindSearch\Service'); + $paramManager = $this->getMock('VuFind\Search\Params\PluginManager'); + $recommend = new Random($service, $paramManager); + $records = array("1", "2", "3", "4", "5"); + + // Use Solr since some Base components are abstract: + $params = $this->getServiceManager()->get('VuFind\SearchParamsPluginManager') + ->get('Solr'); + $query = $this->getFixture('query'); + $params->setBasicSearch($query->getString(), $query->getHandler()); + $request = $this->getMock('\Zend\StdLib\Parameters'); + + $results = $this->getMock('VuFindTest\Recommend\TestSearchResultsForRandom'); + $results->expects($this->once())->method('getRecords') + ->will($this->returnValue($records)); + + $service->expects($this->once())->method('random') + ->with( + $this->equalTo("Solr"), + $this->equalTo($params->getQuery()), + $this->equalTo(10) + )->will($this->returnValue($results)); + + $recommend->setConfig("Solr:10:mixed:retain:20:facet1:value1:facet2:value2"); + $recommend->init($params, $request); + $output = $recommend->getResults(); + $this->assertEmpty($output); + } + + /** + * Test displaymode * * @return void */ public function testCanSetDisplayMode() { - $this->recommend->setConfig("Solr:10:disregard"); - $this->assertEquals("disregard", $this->recommend->getDisplayMode()); + $this->recommend->setConfig("Solr:10:mixed"); + $this->assertEquals("mixed", $this->recommend->getDisplayMode()); + } + + /** + * Get a fixture object + * + * @return mixed + */ + protected function getFixture($file) + { + $fixturePath = realpath(__DIR__ . '/../../../../fixtures/searches/basic') . '/'; + return unserialize(file_get_contents($fixturePath . $file)); } } + +/** + * Stub class to test random. + */ +abstract class TestSearchResultsForRandom +{ + abstract function getRecords(); +} diff --git a/module/VuFindSearch/src/VuFindSearch/Service.php b/module/VuFindSearch/src/VuFindSearch/Service.php index 1618c7aaa62d513b34df2b8bd944fd5381404088..3a7ee5c2f98ffbd3d2a6bc3f856043a138d89ad0 100644 --- a/module/VuFindSearch/src/VuFindSearch/Service.php +++ b/module/VuFindSearch/src/VuFindSearch/Service.php @@ -256,9 +256,14 @@ class Service $nextIndex = rand(0, $total_records - 1); } $retrievedIndexes[] = $nextIndex; - $currentBatch = $backend->search( - $query, $nextIndex, 1, $params - ); + try { + $currentBatch = $backend->search( + $query, $nextIndex, 1, $params + ); + } catch (BackendException $e) { + $this->triggerError($e, $args); + throw $e; + } if (!$response) { $response = $currentBatch; } else if ($record = $currentBatch->first()) { diff --git a/module/VuFindSearch/tests/unit-tests/src/VuFindTest/SearchServiceTest.php b/module/VuFindSearch/tests/unit-tests/src/VuFindTest/SearchServiceTest.php index b3b0f15ebff1e4513b7e3c8eceffdec6a5f0d7dc..17b817d42dde25aacfc392479802c80510c387b6 100644 --- a/module/VuFindSearch/tests/unit-tests/src/VuFindTest/SearchServiceTest.php +++ b/module/VuFindSearch/tests/unit-tests/src/VuFindTest/SearchServiceTest.php @@ -452,7 +452,7 @@ class SearchServiceTest extends TestCase * @expectedException VuFindSearch\Backend\Exception\BackendException * @expectedExceptionMessage test */ - public function testRandomNoInterfaceWithException() + public function testRandomNoInterfaceWithExceptionAtFirstSearch() { $service = $this->getService(); $backend = $this->getBackend(); @@ -460,6 +460,7 @@ class SearchServiceTest extends TestCase $params = new ParamBag(array('x' => 'y')); $query = new Query('test'); + // Exception at first search $backend->expects($this->once())->method('search') ->will($this->throwException($exception)); $em = $service->getEventManager(); @@ -470,6 +471,92 @@ class SearchServiceTest extends TestCase $service->random('foo', $query, "10", $params); } + /** + * Test random (without RandomInterface) exception at item retrieval search. + * + * @return void + * @expectedException VuFindSearch\Backend\Exception\BackendException + * @expectedExceptionMessage test + */ + public function testRandomNoInterfaceWithExceptionAtItemSearch() + { + $limit = 10; + $total = 20; + $service = $this->getService(); + $backend = $this->getBackend(); + $responseForZero = $this->getRecordCollection(); + $exception = new BackendException('test'); + + $params = new ParamBag(array('x' => 'y')); + $query = new Query('test'); + + // First Search Grabs 0 records but uses get total method + $backend->expects($this->at(0))->method('search') + ->with( + $this->equalTo($query), + $this->equalTo("0"), + $this->equalTo("0"), + $this->equalTo($params) + )->will($this->returnValue($responseForZero)); + + $responseForZero->expects($this->once())->method('getTotal') + ->will($this->returnValue($total)); + + // Exception at item search + $backend->expects($this->at(1))->method('search') + ->will($this->throwException($exception)); + $em = $service->getEventManager(); + $em->expects($this->at(0))->method('trigger') + ->with($this->equalTo('pre'), $this->equalTo($backend)); + $em->expects($this->at(1))->method('trigger') + ->with($this->equalTo('error'), $this->equalTo($exception)); + $service->random('foo', $query, "10", $params); + } + + /** + * Test random (without RandomInterface) exception with less results than limit. + * + * @return void + * @expectedException VuFindSearch\Backend\Exception\BackendException + * @expectedExceptionMessage test + */ + public function testRandomNoInterfaceExceptionWithLessResultsThanLimit() + { + $limit = 10; + $total = 5; + $service = $this->getService(); + $backend = $this->getBackend(); + $responseForZero = $this->getRecordCollection(); + $response = $this->getRecordCollection(); + $exception = new BackendException('test'); + + $params = new ParamBag(array('x' => 'y')); + $query = new Query('test'); + + // First Search Grabs 0 records but uses get total method + $backend->expects($this->at(0))->method('search') + ->with( + $this->equalTo($query), + $this->equalTo("0"), + $this->equalTo("0"), + $this->equalTo($params) + )->will($this->returnValue($responseForZero)); + + $responseForZero->expects($this->once())->method('getTotal') + ->will($this->returnValue($total)); + + // Second search grabs all the records + $backend->expects($this->at(1))->method('search') + ->will($this->throwException($exception)); + + $em = $service->getEventManager(); + $em->expects($this->at(0))->method('trigger') + ->with($this->equalTo('pre'), $this->equalTo($backend)); + $em->expects($this->at(1))->method('trigger') + ->with($this->equalTo('error'), $this->equalTo($exception)); + $service->random('foo', $query, $limit, $params); + } + /** * Test similar action. *