Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix result limit and sort templates. #3031

Merged
merged 5 commits into from
Aug 18, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
* PHP version 8
*
* Copyright (C) Villanova University 2021.
* Copyright (C) The National Library of Finland 2023.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2,
Expand Down Expand Up @@ -37,6 +38,7 @@
* @category VuFind
* @package Tests
* @author Demian Katz <demian.katz@villanova.edu>
* @author Ere Maijala <ere.maijala@helsinki.fi>
* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License
* @link https://vufind.org Main Page
* @retry 4
Expand Down Expand Up @@ -67,7 +69,7 @@ protected function setUpLimitedSearch(
$config = ['default_limit' => $default, 'limit_options' => $options];
$this->changeConfigs(['searches' => ['General' => $config]]);
$session = $this->getMinkSession();
$session->visit($this->getVuFindUrl() . '/Search/Results?limit=' . $limitParam);
$session->visit($this->getVuFindUrl() . "/Search/Results?filter[]=building%3A%22geo.mrc%22&limit=$limitParam");
return $session->getPage();
}

Expand Down Expand Up @@ -120,6 +122,24 @@ protected function assertNoLimitControl(Element $page)
$this->assertNull($page->find('css', $this->limitControlSelector));
}

/**
* Check that first and last record of the results are correct
*
* @param Element $page Current page
* @param string $first Expected first title
* @param string $last Expected last title
* @param int $count Expected result count
*
* @return void
*/
protected function assertResultTitles($page, string $first, string $last, int $count): void
{
$titles = $page->findAll('css', '.result a.title');
$this->assertCount($count, $titles);
$this->assertEquals($first, $titles[0]->getText());
$this->assertEquals($last, $titles[$count - 1]->getText());
}

/**
* Test that default page size is 20, with no limit controls displayed.
*
Expand Down Expand Up @@ -191,4 +211,29 @@ public function testNonNumericLimitValues(): void
$this->assertResultSize($page, 6);
$this->assertLimitControl($page, [3, 6, 9], 6);
}

/**
* Test the limit control
*
* @return void
*/
public function testLimitChange(): void
{
$page = $this->setUpLimitedSearch('20', '20,40', '20');

// Check expected first and last record on first page:
$this->assertResultTitles($page, 'Test Publication 20001', 'Test Publication 20020', 20);

// Go to second page:
$this->clickCss($page, '.pagination li > a');
$this->assertResultTitles($page, 'Test Publication 20021', 'Test Publication 20040', 20);

// Change limit and verify:
$this->clickCss($page, $this->limitControlSelector . ' option', null, 1);
$this->waitForPageLoad($page);
// Check expected first and last record (page should be reset):
$this->assertResultTitles($page, 'Test Publication 20001', 'Test Publication 20040', 40);
// Check that url no longer contains the page parameter:
$this->assertStringNotContainsString('&page', $this->getCurrentQueryString());
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,185 @@
<?php

/**
* Test for sorting of search results.
*
* PHP version 8
*
* Copyright (C) Villanova University 2021.
* Copyright (C) The National Library of Finland 2023.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2,
* as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*
* @category VuFind
* @package Tests
* @author Demian Katz <demian.katz@villanova.edu>
* @author Ere Maijala <ere.maijala@helsinki.fi>
* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License
* @link https://vufind.org Main Page
*/

namespace VuFindTest\Mink;

use Behat\Mink\Element\Element;

/**
* Test for sorting of search results.
*
* @category VuFind
* @package Tests
* @author Demian Katz <demian.katz@villanova.edu>
* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License
* @link https://vufind.org Main Page
* @retry 4
*/
class SearchSortTest extends \VuFindTest\Integration\MinkTestCase
{
/**
* Selector for sort control
*
* @var string
*/
protected $sortControlSelector = '#sort_options_1';

/**
* VuFind default sort options
*
* @var string[]
*/
protected $defaultSortOptions = [
'Relevance',
'Date Descending',
'Date Ascending',
'Call Number',
'Author',
];

/**
* Test that an invalid sort option sends us to the default value.
*
* @return void
*/
public function testInvalidSort(): void
{
$page = $this->setUpSearch('foobar', 'relevance');
$this->assertSortControl($page, 'relevance');
}

/**
* Test default sort
*
* @return void
*/
public function testDefaultSort(): void
{
$page = $this->setUpSearch('', 'title desc');
$this->assertSortControl($page, 'title desc');
}

/**
* Test the sort control
*
* @return void
*/
public function testSortChange(): void
{
$page = $this->setUpSearch('title', 'title');

// Check current sort:
$this->assertSortControl($page, 'title');

// Check expected first and last record on first page:
$this->assertResultTitles($page, 'Test Publication 20001', 'Test Publication 20020');

// Go to second page:
$this->clickCss($page, '.pagination li > a');
$this->waitForPageLoad($page);
$this->assertResultTitles($page, 'Test Publication 20021', 'Test Publication 20040');

// Change sort to title reversed (last option) and verify:
$this->clickCss($page, $this->sortControlSelector . ' option', null, count($this->defaultSortOptions) + 1);
$this->waitForPageLoad($page);
// Check current sort:
$this->assertSortControl($page, 'title desc');
// Check expected first and last record (page should be reset):
$this->assertResultTitles($page, 'Test Publication 20177', 'Test Publication 201738');
// Check that url no longer contains the page parameter:
$this->assertStringNotContainsString('&page', $this->getCurrentQueryString());
}

/**
* Set up a search page with sorting configured
*
* @param string $sortParam Requested sort option
* @param string $default default_sort setting for searches.ini
*
* @return Element
*/
protected function setUpSearch(string $sortParam, string $default): Element
{
$this->changeConfigs(
[
'searches' => [
'General' => [
'default_sort' => $default,
],
'Sorting' => [
'title' => 'Title',
'title desc' => 'Title Reversed',
],
],
]
);
$session = $this->getMinkSession();
$session->visit($this->getVuFindUrl() . "/Search/Results?filter[]=building%3A%22geo.mrc%22&sort=$sortParam");
return $session->getPage();
}

/**
* Assert the contents and selected element of the sort control.
*
* @param Element $page Current page
* @param string $active Expected active option
*
* @return void
*/
protected function assertSortControl(Element $page, string $active)
{
$sort = $this->findCss($page, $this->sortControlSelector);
$this->assertEquals((string)$active, $sort->getValue());
$optionElements = $page->findAll('css', $this->sortControlSelector . ' option');
$callback = function (Element $element): string {
return $element->getText();
};
$actualOptions = array_map($callback, $optionElements);
$this->assertEquals([...$this->defaultSortOptions, 'Title', 'Title Reversed'], $actualOptions);
}

/**
* Check that first and last record of the results are correct
*
* @param Element $page Current page
* @param string $first Expected first title
* @param string $last Expected last title
*
* @return void
*/
protected function assertResultTitles($page, string $first, string $last): void
{
$titles = $page->findAll('css', '.result a.title');
$this->assertCount(20, $titles);
$this->assertEquals($first, $titles[0]->getText());
$this->assertEquals($last, $titles[19]->getText());
}
}
4 changes: 2 additions & 2 deletions themes/bootstrap3/templates/search/controls/limit.phtml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<?php $limitList = $this->params->getLimitList(); ?>
<?php if (count($limitList) > 1): ?>
<form class="form-inline search-result-limit" action="<?=$this->currentPath() . $this->results->getUrlQuery()->setLimit(null)?>" method="get">
<?=$this->results->getUrlQuery()->asHiddenFields(['sort' => '/.*/']);?>
<form class="form-inline search-result-limit" action="<?=$this->currentPath()?>" method="get">
<?=$this->results->getUrlQuery()->asHiddenFields(['limit' => '/.*/', 'page' => '/.*/']);?>
<label for="limit"><?=$this->transEsc('Results per page')?></label>
<select id="limit" name="limit" class="jumpMenu form-control">
<?php foreach ($limitList as $limitVal => $limitData): ?>
Expand Down
2 changes: 1 addition & 1 deletion themes/bootstrap3/templates/search/controls/sort.phtml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<?php $list = $this->params->getSortList(); ?>
<?php if (!empty($list)): ?>
<form class="search-sort" action="<?=$this->currentPath()?>" method="get" name="sort">
<?=$this->results->getUrlQuery()->asHiddenFields(['sort' => '/.*/']);?>
<?=$this->results->getUrlQuery()->asHiddenFields(['sort' => '/.*/', 'page' => '/.*/']);?>
<label for="sort_options_1"><?=$this->transEsc('Sort')?></label>
<select id="sort_options_1" name="sort" class="jumpMenu form-control">
<?php foreach ($list as $sortType => $sortData): ?>
Expand Down