diff --git a/module/VuFind/src/VuFind/Controller/Plugin/ResultScroller.php b/module/VuFind/src/VuFind/Controller/Plugin/ResultScroller.php index 6198ee3c8d2c93395c797339bd0abce112882972..f267e0cd16f7502fb682e20ba83b41829c4791a7 100644 --- a/module/VuFind/src/VuFind/Controller/Plugin/ResultScroller.php +++ b/module/VuFind/src/VuFind/Controller/Plugin/ResultScroller.php @@ -171,9 +171,11 @@ class ResultScroller extends AbstractPlugin */ protected function fetchNextPage($retVal, $lastSearch, $pos) { - // if the next page has not been fetched, then - // fetch the next page - if ($this->data->nextIds == null) { + // if the current page is NOT the last page, and the next page has not been + // fetched, then fetch the next page + if ($this->data->page < ceil($this->data->total / $this->data->limit) + && $this->data->nextIds == null + ) { $this->data->nextIds = $this->fetchPage( $lastSearch, $this->data->page + 1 ); diff --git a/module/VuFind/tests/unit-tests/src/VuFindTest/Controller/Plugin/ResultScrollerTest.php b/module/VuFind/tests/unit-tests/src/VuFindTest/Controller/Plugin/ResultScrollerTest.php index ec44cd34e8d8ddf0b8924b1c42b0ca1b9a20f03a..5168ef802aff4e445d4caad1ec6e6e511a05b511 100644 --- a/module/VuFind/tests/unit-tests/src/VuFindTest/Controller/Plugin/ResultScrollerTest.php +++ b/module/VuFind/tests/unit-tests/src/VuFindTest/Controller/Plugin/ResultScrollerTest.php @@ -42,6 +42,13 @@ use VuFindTest\Unit\TestCase as TestCase; */ class ResultScrollerTest extends TestCase { + /** + * Cache for record driver mocks. + * + * @var array + */ + protected $recordDrivers = array(); + /** * Test disabled behavior * @@ -58,6 +65,78 @@ class ResultScrollerTest extends TestCase $this->assertEquals($expected, $plugin->getScrollData($this->getMockRecordDriver('foo'))); } + /** + * Test scrolling for a record in the middle of the page + * + * @return void + */ + public function testScrollingInMiddleOfPage() + { + $results = $this->getMockResults(1, 10, 10); + $plugin = $this->getMockResultScroller(); + $plugin->expects($this->any())->method('restoreLastSearch')->will($this->returnValue($results)); + $this->assertTrue($plugin->init($results)); + $expected = array( + 'previousRecord'=>'VuFind|4', 'nextRecord'=>'VuFind|6', + 'currentPosition'=>5, 'resultTotal'=>10 + ); + $this->assertEquals($expected, $plugin->getScrollData($this->getMockRecordDriver(5))); + } + + /** + * Test scrolling for a record at the start of the first page + * + * @return void + */ + public function testScrollingAtStartOfFirstPage() + { + $results = $this->getMockResults(1, 10, 10); + $plugin = $this->getMockResultScroller(); + $plugin->expects($this->any())->method('restoreLastSearch')->will($this->returnValue($results)); + $this->assertTrue($plugin->init($results)); + $expected = array( + 'previousRecord'=>null, 'nextRecord'=>'VuFind|2', + 'currentPosition'=>1, 'resultTotal'=>10 + ); + $this->assertEquals($expected, $plugin->getScrollData($this->getMockRecordDriver(1))); + } + + /** + * Test scrolling for a record at the end of the last page (single-page example) + * + * @return void + */ + public function testScrollingAtEndOfLastPage() + { + $results = $this->getMockResults(1, 10, 10); + $plugin = $this->getMockResultScroller(); + $plugin->expects($this->any())->method('restoreLastSearch')->will($this->returnValue($results)); + $this->assertTrue($plugin->init($results)); + $expected = array( + 'previousRecord'=>'VuFind|9', 'nextRecord'=>null, + 'currentPosition'=>10, 'resultTotal'=>10 + ); + $this->assertEquals($expected, $plugin->getScrollData($this->getMockRecordDriver(10))); + } + + /** + * Test scrolling for a record at the end of the last page (multi-page example) + * + * @return void + */ + public function testScrollingAtEndOfLastPageInMultiPageScenario() + { + $results = $this->getMockResults(2, 10, 17); + $plugin = $this->getMockResultScroller(); + $plugin->expects($this->any())->method('restoreLastSearch')->will($this->returnValue($results)); + $this->assertTrue($plugin->init($results)); + $expected = array( + 'previousRecord'=>'VuFind|16', 'nextRecord'=>null, + 'currentPosition'=>17, 'resultTotal'=>17 + ); + $this->assertEquals($expected, $plugin->getScrollData($this->getMockRecordDriver(17))); + } + /** * Get mock record driver * @@ -68,24 +147,87 @@ class ResultScrollerTest extends TestCase */ protected function getMockRecordDriver($id, $source = 'VuFind') { - $driver = $this->getMockBuilder('VuFind\RecordDriver\AbstractBase') - ->disableOriginalConstructor() - ->getMock(); - $driver->expects($this->any())->method('getUniqueId')->will($this->returnValue($id)); - $driver->expects($this->any())->method('getResourceSource')->will($this->returnValue($source)); - return $driver; + if (!isset($this->recordDrivers["$source|$id"])) { + $driver = $this->getMockBuilder('VuFind\RecordDriver\AbstractBase') + ->disableOriginalConstructor() + ->getMock(); + $driver->expects($this->any())->method('getUniqueId')->will($this->returnValue($id)); + $driver->expects($this->any())->method('getResourceSource')->will($this->returnValue($source)); + $this->recordDrivers["$source|$id"] = $driver; + } + return $this->recordDrivers["$source|$id"]; } /** * Get mock search results * + * @param int $page Current page number + * @param int $limit Page size + * @param int $total Total size of fake result set + * * @return \VuFind\Search\Base\Results */ - protected function getMockResults() + protected function getMockResults($page = 0, $limit = 0, $total = 0) { $results = $this->getMockBuilder('VuFind\Search\Solr\Results') ->disableOriginalConstructor() ->getMock(); + $results->expects($this->any())->method('getSearchId')->will($this->returnValue('dummy-search-id')); + $results->expects($this->any())->method('getParams')->will($this->returnValue($this->getMockParams($page, $limit))); + $results->expects($this->any())->method('getResultTotal')->will($this->returnValue($total)); + $results->expects($this->any())->method('getResults')->will($this->returnValue($this->getResultSet($page, $limit, $total))); return $results; } + + /** + * Get mock search params + * + * @param int $page Current page number + * @param int $limit Page size + * + * @return \VuFind\Search\Base\Params + */ + protected function getMockParams($page = 0, $limit = 0) + { + $params = $this->getMockBuilder('VuFind\Search\Solr\Params') + ->disableOriginalConstructor() + ->getMock(); + $params->expects($this->any())->method('getPage')->will($this->returnValue($page)); + $params->expects($this->any())->method('getLimit')->will($this->returnValue($limit)); + return $params; + } + + /** + * Get mock result scroller + * + * @param array $methods Methods to mock + * + * @return ResultScroller + */ + protected function getMockResultScroller($methods = array('restoreLastSearch', 'rememberSearch')) + { + return $this->getMock('VuFind\Controller\Plugin\ResultScroller', $methods); + } + + /** + * Get set of fake record drivers. + * + * @param int $page Current page number + * @param int $limit Page size + * @param int $total Total size of fake result set + * + * @return array + */ + protected function getResultSet($page, $limit, $total) + { + $retVal = array(); + for ($i = 1; $i <= $limit; $i++) { + $current = ($page - 1) * $limit + $i; + if ($current > $total) { + break; + } + $retVal[] = $this->getMockRecordDriver($current); + } + return $retVal; + } } \ No newline at end of file