Commit ad4910f8 authored by borisson_'s avatar borisson_ Committed by borisson_

Issue #2904952 by borisson_: Tests and cleanup for summaries

parent f1a7a8ee
......@@ -87,7 +87,7 @@ class FacetsSummary extends ConfigEntityBase implements FacetsSummaryInterface {
/**
* Cached information about the processors available for this facet.
*
* @var \Drupal\facets\Processor\ProcessorInterface[]|null
* @var \Drupal\facets_summary\Processor\ProcessorInterface[]|null
*
* @see loadProcessors()
*/
......@@ -137,7 +137,6 @@ class FacetsSummary extends ConfigEntityBase implements FacetsSummaryInterface {
* {@inheritdoc}
*/
public function getFacetSource() {
if (!$this->facet_source_instance && $this->facet_source_id) {
/* @var $facet_source_plugin_manager \Drupal\facets\FacetSource\FacetSourcePluginManager */
$facet_source_plugin_manager = \Drupal::service('plugin.manager.facets.facet_source');
......@@ -176,28 +175,30 @@ class FacetsSummary extends ConfigEntityBase implements FacetsSummaryInterface {
* The loaded processors, keyed by processor ID.
*/
protected function loadProcessors() {
if (!isset($this->processors)) {
/* @var $processor_plugin_manager \Drupal\facets\Processor\ProcessorPluginManager */
$processor_plugin_manager = \Drupal::service('plugin.manager.facets_summary.processor');
$processor_settings = $this->getProcessorConfigs();
foreach ($processor_plugin_manager->getDefinitions() as $name => $processor_definition) {
if (class_exists($processor_definition['class']) && empty($this->processors[$name])) {
// Create our settings for this processor.
$settings = empty($processor_settings[$name]['settings']) ? [] : $processor_settings[$name]['settings'];
$settings['facets_summary'] = $this;
/* @var $processor \Drupal\facets_summary\Processor\ProcessorInterface */
$processor = $processor_plugin_manager->createInstance($name, $settings);
$this->processors[$name] = $processor;
}
elseif (!class_exists($processor_definition['class'])) {
\Drupal::logger('facets_summary')
->warning('Processor @id specifies a non-existing @class.', [
'@id' => $name,
'@class' => $processor_definition['class'],
]);
}
if (is_array($this->processors)) {
return $this->processors;
}
/* @var $processor_plugin_manager \Drupal\facets\Processor\ProcessorPluginManager */
$processor_plugin_manager = \Drupal::service('plugin.manager.facets_summary.processor');
$processor_settings = $this->getProcessorConfigs();
foreach ($processor_plugin_manager->getDefinitions() as $name => $processor_definition) {
if (class_exists($processor_definition['class']) && empty($this->processors[$name])) {
// Create our settings for this processor.
$settings = empty($processor_settings[$name]['settings']) ? [] : $processor_settings[$name]['settings'];
$settings['facets_summary'] = $this;
/* @var $processor \Drupal\facets_summary\Processor\ProcessorInterface */
$processor = $processor_plugin_manager->createInstance($name, $settings);
$this->processors[$name] = $processor;
}
elseif (!class_exists($processor_definition['class'])) {
\Drupal::logger('facets_summary')
->warning('Processor @id specifies a non-existing @class.', [
'@id' => $name,
'@class' => $processor_definition['class'],
]);
}
}
......@@ -265,6 +266,7 @@ class FacetsSummary extends ConfigEntityBase implements FacetsSummaryInterface {
'weights' => $processor['weights'],
'settings' => $processor['settings'],
];
// Sort the processors so we won't have unnecessary changes.
ksort($this->processor_configs);
}
......
......@@ -13,11 +13,12 @@ use Drupal\facets_summary\Processor\ProcessorPluginManager;
use Drupal\facets_summary\FacetsSummaryInterface;
/**
* The facet manager.
* The facet summary manager.
*
* The manager is responsible for interactions with the Search backend, such as
* altering the query, it is also responsible for executing and building the
* facet. It is also responsible for running the processors.
* The manager wires everything together, it's responsible for gather the
* results and creating the summary.
* It also runs the processors and returns a renderable array from the build
* method.
*/
class DefaultFacetsSummaryManager {
......
......@@ -31,13 +31,6 @@ class FacetsSummaryForm extends EntityForm {
*/
protected $facetSummaryStorage;
/**
* The entity manager.
*
* @var \Drupal\Core\Entity\EntityTypeManagerInterface
*/
protected $entityTypeManager;
/**
* The plugin manager for facet sources.
*
......
......@@ -25,13 +25,6 @@ class FacetsSummarySettingsForm extends EntityForm {
*/
protected $facetSummaryStorage;
/**
* The entity manager.
*
* @var \Drupal\Core\Entity\EntityTypeManagerInterface
*/
protected $entityTypeManager;
/**
* The plugin manager for facet sources.
*
......@@ -60,13 +53,6 @@ class FacetsSummarySettingsForm extends EntityForm {
*/
protected $blockManager;
/**
* The url generator.
*
* @var \Drupal\Core\Routing\UrlGeneratorInterface
*/
protected $urlGenerator;
/**
* Constructs an FacetDisplayForm object.
*
......@@ -262,11 +248,4 @@ class FacetsSummarySettingsForm extends EntityForm {
return $facets_summary;
}
/**
* {@inheritdoc}
*/
public function delete(array $form, FormStateInterface $form_state) {
$form_state->setRedirect('entity.facets_summary.delete_form', ['facets_summary' => $this->getEntity()->id()]);
}
}
......@@ -32,18 +32,4 @@ class HideWhenNotRenderedProcessor extends ProcessorPluginBase implements BuildP
return $build;
}
/**
* {@inheritdoc}
*/
public function isHidden() {
return FALSE;
}
/**
* {@inheritdoc}
*/
public function isLocked() {
return FALSE;
}
}
......@@ -26,10 +26,10 @@ class ResetFacetsProcessor extends ProcessorPluginBase implements BuildProcessor
* {@inheritdoc}
*/
public function build(FacetsSummaryInterface $facets_summary, array $build, array $facets) {
$conf = $facets_summary->getProcessorConfigs()[$this->getPluginId()];
$configuration = $facets_summary->getProcessorConfigs()[$this->getPluginId()];
// Do nothing if there are no selected facets or reset text is empty.
if (empty($build['#items']) || empty($conf['settings']['link_text'])) {
if (empty($build['#items']) || empty($configuration['settings']['link_text'])) {
return $build;
}
......@@ -62,7 +62,7 @@ class ResetFacetsProcessor extends ProcessorPluginBase implements BuildProcessor
$first_item_url = clone ($first_item_url);
$first_item_url->setOptions(['query' => $query_params]);
$item = (new Link($conf['settings']['link_text'], $first_item_url))->toRenderable();
$item = (new Link($configuration['settings']['link_text'], $first_item_url))->toRenderable();
array_unshift($build['#items'], $item);
return $build;
}
......@@ -72,13 +72,12 @@ class ResetFacetsProcessor extends ProcessorPluginBase implements BuildProcessor
*/
public function buildConfigurationForm(array $form, FormStateInterface $form_state, FacetsSummaryInterface $facets_summary) {
// By default, there should be no config form.
$processors = $facets_summary->getProcessors();
$config = isset($processors[$this->getPluginId()]) ? $processors[$this->getPluginId()] : NULL;
$config = $this->getConfiguration();
$build['link_text'] = [
'#type' => 'textfield',
'#title' => $this->t('Reset facets link text'),
'#default_value' => !is_null($config) ? $config->getConfiguration()['link_text'] : $this->defaultConfiguration()['link_text'],
'#default_value' => $config['link_text'],
];
return $build;
......@@ -91,18 +90,4 @@ class ResetFacetsProcessor extends ProcessorPluginBase implements BuildProcessor
return ['link_text' => ''];
}
/**
* {@inheritdoc}
*/
public function isHidden() {
return FALSE;
}
/**
* {@inheritdoc}
*/
public function isLocked() {
return FALSE;
}
}
......@@ -38,18 +38,4 @@ class ShowCountProcessor extends ProcessorPluginBase implements BuildProcessorIn
return $build;
}
/**
* {@inheritdoc}
*/
public function isHidden() {
return FALSE;
}
/**
* {@inheritdoc}
*/
public function isLocked() {
return FALSE;
}
}
......@@ -43,18 +43,4 @@ class ShowSummaryProcessor extends ProcessorPluginBase implements BuildProcessor
return $build;
}
/**
* {@inheritdoc}
*/
public function isHidden() {
return FALSE;
}
/**
* {@inheritdoc}
*/
public function isLocked() {
return FALSE;
}
}
......@@ -26,16 +26,15 @@ class ShowTextWhenEmptyProcessor extends ProcessorPluginBase implements BuildPro
* {@inheritdoc}
*/
public function build(FacetsSummaryInterface $facets_summary, array $build, array $facets) {
$processors = $facets_summary->getProcessors();
$config = isset($processors[$this->getPluginId()]) ? $processors[$this->getPluginId()] : NULL;
$config = $this->getConfiguration();
if (!isset($build['#items'])) {
return [
'#theme' => 'facets_summary_empty',
'#message' => [
'#type' => 'processed_text',
'#text' => !is_null($config) ? $config->getConfiguration()['text']['value'] : $this->defaultConfiguration()['text']['value'],
'#format' => !is_null($config) ? $config->getConfiguration()['text']['format'] : $this->defaultConfiguration()['text']['format'],
'#text' => $config['text']['value'],
'#format' => $config['text']['format'],
],
];
}
......@@ -47,15 +46,14 @@ class ShowTextWhenEmptyProcessor extends ProcessorPluginBase implements BuildPro
*/
public function buildConfigurationForm(array $form, FormStateInterface $form_state, FacetsSummaryInterface $facets_summary) {
// By default, there should be no config form.
$processors = $facets_summary->getProcessors();
$config = isset($processors[$this->getPluginId()]) ? $processors[$this->getPluginId()] : NULL;
$config = $this->getConfiguration();
$build['text'] = [
'#type' => 'text_format',
'#title' => $this->t('Empty text'),
'#format' => !is_null($config) ? $config->getConfiguration()['text']['format'] : $this->defaultConfiguration()['text']['format'],
'#format' => $config['text']['format'],
'#editor' => TRUE,
'#default_value' => !is_null($config) ? $config->getConfiguration()['text']['value'] : $this->defaultConfiguration()['text']['value'],
'#default_value' => $config['text']['value'],
];
return $build;
......@@ -73,18 +71,4 @@ class ShowTextWhenEmptyProcessor extends ProcessorPluginBase implements BuildPro
];
}
/**
* {@inheritdoc}
*/
public function isHidden() {
return FALSE;
}
/**
* {@inheritdoc}
*/
public function isLocked() {
return FALSE;
}
}
......@@ -10,7 +10,7 @@ use Drupal\facets_summary\FacetsSummaryInterface;
interface BuildProcessorInterface extends ProcessorInterface {
/**
* Is able to alter the render array.
* Alter the items in the summary before creating the renderable array.
*
* @param \Drupal\facets_summary\FacetsSummaryInterface $facet
* The facet being changed.
......
......@@ -12,17 +12,11 @@ use Drupal\Component\Plugin\PluginInspectionInterface;
*/
interface ProcessorInterface extends ConfigurablePluginInterface, PluginInspectionInterface {
/**
* Processing stage: build.
*/
const STAGE_BUILD = 'build';
/**
* Processing stage: sort.
*/
const STAGE_SORT = 'sort';
/**
* Adds a configuration form for this processor.
*
......@@ -63,9 +57,8 @@ interface ProcessorInterface extends ConfigurablePluginInterface, PluginInspecti
* Checks whether this processor implements a particular stage.
*
* @param string $stage_identifier
* The stage to check: self::STAGE_PRE_QUERY,
* self::STAGE_POST_QUERY
* or self::STAGE_BUILD.
* The stage that can be supported by the processor, check the constants
* defined in this class for a list of options.
*
* @return bool
* TRUE if the processor runs on a particular stage; FALSE otherwise.
......
......@@ -81,7 +81,6 @@ class ProcessorPluginBase extends PluginBase implements ProcessorInterface {
*/
public function getConfiguration() {
unset($this->configuration['facets_summary']);
// TODO: Do we need this here anyway?
return $this->configuration + $this->defaultConfiguration();
}
......
......@@ -61,11 +61,6 @@ class HierarchicalFacetIntegrationTest extends FacetsTestBase {
*/
protected $terms = [];
/**
* {@inheritdoc}
*/
protected $strictConfigSchema = FALSE;
/**
* {@inheritdoc}
*/
......
......@@ -374,7 +374,12 @@ class IntegrationTest extends FacetsTestBase {
$this->resetAll();
// Place a block and test show_count processor.
$this->drupalPlaceBlock('facets_summary_block:show_count', ['region' => 'footer', 'id' => 'show-count']);
$blockConfig = [
'region' => 'footer',
'id' => 'show-count',
'label' => 'show-count-block',
];
$this->drupalPlaceBlock('facets_summary_block:show_count', $blockConfig);
$this->drupalGet('search-api-test-fulltext');
$this->assertSession()->pageTextContains('5 results found');
......@@ -424,19 +429,24 @@ class IntegrationTest extends FacetsTestBase {
$this->resetAll();
// Place a block and test reset facets processor.
$this->drupalPlaceBlock('facets_summary_block:reset_facets', ['region' => 'footer', 'id' => 'reset-facets']);
$blockConfig = [
'label' => 'Reset block',
'region' => 'footer',
'id' => 'reset-facets',
];
$this->drupalPlaceBlock('facets_summary_block:reset_facets', $blockConfig);
$this->drupalGet('search-api-test-fulltext');
$this->assertSession()->pageTextContains(t('Displaying 5 search results'));
$this->assertSession()->pageTextNotContains(t('Reset facets'));
$this->assertSession()->pageTextContains('Displaying 5 search results');
$this->assertSession()->pageTextNotContains('Reset facets');
$this->clickLink('apple');
$this->assertSession()->pageTextContains(t('Displaying 2 search results'));
$this->assertSession()->pageTextContains(t('Reset facets'));
$this->assertSession()->pageTextContains('Displaying 2 search results');
$this->assertSession()->pageTextContains('Reset facets');
$this->clickLink(t('Reset facets'));
$this->assertSession()->pageTextContains(t('Displaying 5 search results'));
$this->assertSession()->pageTextNotContains(t('Reset facets'));
$this->clickLink('Reset facets');
$this->assertSession()->pageTextContains('Displaying 5 search results');
$this->assertSession()->pageTextNotContains('Reset facets');
}
}
<?php
namespace Drupal\Tests\facets_summary\Kernel;
use Drupal\facets_summary\Entity\FacetsSummary;
use Drupal\facets_summary\Processor\ProcessorInterface;
use Drupal\KernelTests\KernelTestBase;
/**
* Class SummaryEntityTest.
*
* Tests getters and setters for the Summary entity.
*
* @group facets
* @coversDefaultClass \Drupal\facets_summary\Entity\FacetsSummary
*/
class SummaryEntityTest extends KernelTestBase {
/**
* {@inheritdoc}
*/
public static $modules = [
'facets',
'facets_summary',
];
/**
* {@inheritdoc}
*/
public function setUp() {
parent::setUp();
$this->installEntitySchema('facets_facet');
$this->installEntitySchema('facets_summary');
}
/**
* Tests for getName.
*
* @covers ::getName
*/
public function testName() {
$entity = new FacetsSummary(['description' => 'Owls', 'name' => 'owl'], 'facets_summary');
$this->assertEquals('owl', $entity->getName());
}
/**
* Tests for facet sources.
*
* @covers ::setFacetSourceId
* @covers ::getFacetSourceId
*/
public function testFacetSourceId() {
$entity = new FacetsSummary(['description' => 'Owls', 'name' => 'owl'], 'facets_summary');
$source = $entity->setFacetSourceId('foo');
$this->assertInstanceOf(FacetsSummary::class, $source);
$this->assertEquals('foo', $entity->getFacetSourceId());
}
/**
* Tests facets.
*
* @covers ::setFacets
* @covers ::getFacets
* @covers ::removeFacet
*/
public function testFacets() {
$entity = new FacetsSummary(['description' => 'Owls', 'name' => 'owl'], 'facets_summary');
$this->assertEmpty($entity->getFacets());
$facets = ['foo' => 'bar'];
$entity->setFacets($facets);
$this->assertEquals($facets, $entity->getFacets());
$entity->removeFacet('foo');
$this->assertEmpty($entity->getFacets());
}
/**
* Tests processor behavior.
*
* @covers ::getProcessorsByStage
* @covers ::getProcessors
* @covers ::getProcessorConfigs
* @covers ::addProcessor
* @covers ::removeProcessor
* @covers ::loadProcessors
*/
public function testProcessor() {
$entity = new FacetsSummary([], 'facets_summary');
$this->assertEmpty($entity->getProcessorConfigs());
$this->assertEmpty($entity->getProcessors());
$this->assertEmpty($entity->getProcessorsByStage(ProcessorInterface::STAGE_BUILD));
$id = 'hide_when_not_rendered';
$config = [
'processor_id' => $id,
'weights' => [],
'settings' => [],
];
$entity->addProcessor($config);
$this->assertEquals([$id => $config], $entity->getProcessorConfigs());
$this->assertNotEmpty($entity->getProcessorsByStage(ProcessorInterface::STAGE_BUILD));
$processors = $entity->getProcessors();
$this->assertArrayHasKey($id, $processors);
$this->assertInstanceOf('\Drupal\facets_summary\Plugin\facets_summary\processor\HideWhenNotRenderedProcessor', $processors[$id]);
$entity->removeProcessor($id);
$this->assertEmpty($entity->getProcessorsByStage(ProcessorInterface::STAGE_BUILD));
}
}
<?php
namespace Drupal\Tests\facets_summary\Unit\Plugin\Processors;
use Drupal\Core\DependencyInjection\ContainerBuilder;
use Drupal\facets\FacetSource\FacetSourcePluginInterface;
use Drupal\facets\FacetSource\FacetSourcePluginManager;
use Drupal\facets_summary\Entity\FacetsSummary;
use Drupal\facets_summary\Plugin\facets_summary\processor\HideWhenNotRenderedProcessor;
use Drupal\Tests\UnitTestCase;
/**
* Class HideWhenNotRenderedProcessorTest.
*
* @group facets
* @coversDefaultClass \Drupal\facets_summary\Plugin\facets_summary\processor\HideWhenNotRenderedProcessor
*/
class HideWhenNotRenderedProcessorTest extends UnitTestCase {
/**
* The processor we're testing.
*
* @var \Drupal\facets_summary\Processor\ProcessorInterface|\Drupal\facets_summary\Processor\BuildProcessorInterface
*/
protected $processor;
/**
* {@inheritdoc}
*/
public function setUp() {
parent::setUp();
$this->processor = new HideWhenNotRenderedProcessor([], 'hide_when_not_rendered', []);
}
/**
* Tests the is hidden method.
*
* @covers ::isHidden
*/
public function testIsHidden() {
$this->assertFalse($this->processor->isHidden());
}
/**
* Tests the is locked method.
*
* @covers ::isLocked
*/
public function testIsLocked() {
$this->assertFalse($this->processor->isLocked());
}
/**
* Tests the build method, containing the actual work of the processor.
*
* @covers ::build
*/
public function testBuild() {
$this->createContainer(TRUE);
$summary = new FacetsSummary([], 'facets_summary');
$summary->setFacetSourceId('foo');
$result = $this->processor->build($summary, ['foo'], []);
$this->assertEquals(['foo'], $result);
}