Skip to content

Commit

Permalink
Refactor and fix multi-facet selection. (#4081)
Browse files Browse the repository at this point in the history
- Simplifies the code
- Fixes filter value handling when the value in URL is not enclosed in quotes
- Uses more CSS to hide and show elements
- Reduces JS manipulation of DOM
- Fixes display of selected facets in facet lightbox
- Improves the visuals of facet lightbox
- Doesn't cause errors if sidebar is not found
- Adds multiselection to standalone facet list page
- Fixes multi-selection after loading more facets in lightbox
- Fixes hiding of Set buttons loaded after activating multi-facet selection
- Adds more tests
  • Loading branch information
EreMaijala authored Nov 18, 2024
1 parent 4fe586d commit 3d78109
Show file tree
Hide file tree
Showing 40 changed files with 872 additions and 481 deletions.
1 change: 1 addition & 0 deletions module/VuFind/src/VuFind/Controller/AbstractSearch.php
Original file line number Diff line number Diff line change
Expand Up @@ -927,6 +927,7 @@ public function facetListAction()
'key' => $sort,
'urlBase' => $urlBase,
'searchAction' => $searchAction,
'multiFacetsSelection' => (bool)($config->Results_Settings->multiFacetsSelection ?? false),
];
$viewParams['delegateParams'] = $viewParams;
$view = $this->createViewModel($viewParams);
Expand Down
77 changes: 76 additions & 1 deletion module/VuFind/src/VuFindTest/Feature/SearchFacetFilterTrait.php
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
namespace VuFindTest\Feature;

use Behat\Mink\Element\Element;
use Behat\Mink\Element\NodeElement;

/**
* Trait for working with faceting and filtering of search results.
Expand All @@ -58,6 +59,13 @@ trait SearchFacetFilterTrait
*/
protected $activeFilterLabelSelector = '.active-filters.hidden-xs .filters .filters-title';

/**
* CSS selector for finding the active filter list
*
* @var string
*/
protected $activeFilterListSelector = '.active-filters.hidden-xs .filters .title-value-pair';

/**
* CSS selector for finding the first hierarchical facet expand button
*
Expand All @@ -84,7 +92,7 @@ trait SearchFacetFilterTrait
*
* @var string
*/
protected $facetSecondLevelActiveLinkSelector = '.facet-tree button[aria-expanded=true] ~ ul a.active';
protected $facetSecondLevelActiveLinkSelector = '.facet-tree button[aria-expanded=true] ~ ul .active a';

/**
* CSS selector for finding the first second level hierarchical facet
Expand All @@ -108,4 +116,71 @@ protected function assertAppliedFilter(Element $page, string $expectedFilter): v
$this->assertEquals('hierarchy:', $label->getText());
$this->assertEquals("Remove Filter $expectedFilter", $filter->getText());
}

/**
* Get textual content of a facet element by facet link CSS selector
*
* @param Element $page Page
* @param string $selector CSS selector for facet link
*
* @return string
*/
protected function getFacetTextByLinkSelector(Element $page, string $selector): string
{
return $this->findCssAndCallMethod(
$page,
$selector,
function (NodeElement $node): string {
return $node->getParent()->getText();
}
);
}

/**
* Assert that no filters are applied.
*
* @param Element $page Mink page object
*
* @return void
*/
protected function assertNoFilters(Element $page): void
{
$this->assertFilterCount($page, 0);
}

/**
* Assert that the given number of filters are applied.
*
* @param Element $page Mink page object
* @param int $expected Expected filter count
*
* @return void
*/
protected function assertFilterCount(Element $page, int $expected): void
{
$items = $page->findAll('css', $this->activeFilterSelector);
$this->assertCount($expected, $items);
}

/**
* Assert that the given number of facets are present in the full facet list
*
* @param Element $page Mink page object
* @param string $list List type ('count' or 'index')
* @param int $expected Expected filter count
* @param bool $exclusionActive Should exclude links be present?
*
* @return void
*/
protected function assertFullListFacetCount(
Element $page,
string $list,
int $expected,
bool $exclusionActive
): void {
$items = $page->findAll('css', "#modal #facet-list-$list .js-facet-item");
$this->assertCount($expected, $items);
$excludes = $page->findAll('css', "#modal #facet-list-$list .exclude");
$this->assertCount($exclusionActive ? $expected : 0, $excludes);
}
}
15 changes: 8 additions & 7 deletions module/VuFind/src/VuFindTest/Integration/MinkTestCase.php
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@
use function floatval;
use function in_array;
use function intval;
use function is_string;
use function strlen;

/**
Expand Down Expand Up @@ -758,12 +759,12 @@ protected function findCssAndGetHtml(
/**
* Return value of a method of an element selected via CSS; retry if it fails due to DOM change.
*
* @param Element $page Page element
* @param string $selector CSS selector
* @param string $method Method to call
* @param int $timeout Wait timeout for CSS selection (in ms)
* @param int $index Index of the element (0-based)
* @param int $retries Retry count for set loop
* @param Element $page Page element
* @param string $selector CSS selector
* @param string|callable $method Node's method to call (string) or callable that gets the node as parameter
* @param int $timeout Wait timeout for CSS selection (in ms)
* @param int $index Index of the element (0-based)
* @param int $retries Retry count for set loop
*
* @return string
*/
Expand All @@ -780,7 +781,7 @@ protected function findCssAndCallMethod(
for ($i = 1; $i <= $retries; $i++) {
try {
$element = $this->findCss($page, $selector, $timeout, $index);
return call_user_func([$element, $method]);
return is_string($method) ? call_user_func([$element, $method]) : $method($element);
} catch (\Exception $e) {
$this->logWarning(
'RETRY findCssAndGetText after exception in ' . $this->getTestName()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,8 @@

namespace VuFindTest\Mink;

use VuFindTest\Feature\SearchFacetFilterTrait;

/**
* Mink author search test class.
*
Expand All @@ -40,6 +42,8 @@
*/
class AuthorSearchTest extends \VuFindTest\Integration\MinkTestCase
{
use SearchFacetFilterTrait;

/**
* Test searching for a known corporate author
*
Expand All @@ -48,7 +52,7 @@ class AuthorSearchTest extends \VuFindTest\Integration\MinkTestCase
public function testCorporateAuthorSearch(): void
{
$page = $this->performSearch('corporate', 'Author');
$facets = $this->findCssAndGetText($page, '#side-collapse-building a');
$facets = $this->getFacetTextByLinkSelector($page, '#side-collapse-building a');
// We'll check for a known count from a known MARC file to confirm that
// results came back.
$this->assertStringContainsString('author_relators.mrc 10', $facets);
Expand All @@ -62,7 +66,7 @@ public function testCorporateAuthorSearch(): void
public function testPrimaryAuthorSearch(): void
{
$page = $this->performSearch('primary', 'Author');
$facets = $this->findCssAndGetText($page, '#side-collapse-building a');
$facets = $this->getFacetTextByLinkSelector($page, '#side-collapse-building a');
// We'll check for a known count from a known MARC file to confirm that
// results came back.
$this->assertStringContainsString('author_relators.mrc 11', $facets);
Expand Down
Loading

0 comments on commit 3d78109

Please sign in to comment.