search_api-8.x-1.15/tests/src/Kernel/Processor/LanguageWithFallbackTest.php
tests/src/Kernel/Processor/LanguageWithFallbackTest.php
<?php
namespace Drupal\Tests\search_api\Kernel\Processor;
use Drupal\node\Entity\NodeType;
use Drupal\language\Entity\ConfigurableLanguage;
use Drupal\node\Entity\Node;
use Drupal\search_api\Item\Field;
use Drupal\search_api\Utility\Utility;
use Drupal\Tests\search_api\Kernel\PostRequestIndexingTrait;
/**
* Tests the "Language (with fallback)" processor at a higher level.
*
* @group search_api
*
* @coversDefaultClass \Drupal\search_api\Plugin\search_api\processor\LanguageWithFallback
*/
class LanguageWithFallbackTest extends ProcessorTestBase {
use PostRequestIndexingTrait;
/**
* {@inheritdoc}
*/
public static $modules = [
'language',
'search_api_test_language_fallback',
'language_fallback_fix',
];
/**
* The test node.
*
* @var \Drupal\node\NodeInterface
*/
protected $node;
/**
* {@inheritdoc}
*/
public function setUp($processor = NULL) {
parent::setUp('language_with_fallback');
// search_api_test_language_fallback.module adds a fallback from 'fr' to
// 'es'. When we then leave 'en' as site default language and set 'de' as
// original node language, we are able to spot false fallbacks to either of
// those.
foreach (['de', 'fr', 'es'] as $langcode) {
ConfigurableLanguage::createFromLangcode($langcode)->enable()->save();
}
NodeType::create([
'type' => 'article',
])->save();
$lwf_field = new Field($this->index, 'language_with_fallback');
$lwf_field->setType('string');
$lwf_field->setPropertyPath('language_with_fallback');
$lwf_field->setLabel('Language (with fallback)');
$this->index->addField($lwf_field);
$this->index->setOption('index_directly', TRUE);
$this->index->save();
}
/**
* Tests indexing.
*
* Expected fallbacks: search_api_test_language_fallback.module has these:
* - no fallbacks
* - except 'fr' has fallback 'es'
*
* Note that language_fallback_fix.module (which is a test dependency) ensures
* that there can be languages without fallback, which we test here.
*
* @covers ::addFieldValues
*
* @throws \Drupal\Core\Entity\EntityStorageException
*/
public function testIndexing() {
$nodeValues = [
'title' => 'Test',
'type' => 'article',
];
// First test with a German node.
$node = Node::create($nodeValues + ['langcode' => 'de']);
$node->save();
$this->node = $node;
$this->triggerPostRequestIndexing();
$expected[$this->getItemIdForLanguage('de')] = ['de'];
$this->assertEquals($expected, $this->getLanguageWithFallbackValues(), 'Added default translation is indexed correctly.');
$node->addTranslation('es', $nodeValues);
$node->save();
$this->triggerPostRequestIndexing();
$expected[$this->getItemIdForLanguage('es')] = ['es', 'fr'];
$this->assertEquals($expected, $this->getLanguageWithFallbackValues(), 'Added translation with fallback is indexed correctly.');
$node->addTranslation('fr', $nodeValues);
$node->save();
$this->triggerPostRequestIndexing();
$expected[$this->getItemIdForLanguage('es')] = ['es'];
$expected[$this->getItemIdForLanguage('fr')] = ['fr'];
$this->assertEquals($expected, $this->getLanguageWithFallbackValues(), 'Added translation is indexed correctly and former fallback removed.');
$node->removeTranslation('fr');
$node->save();
$this->triggerPostRequestIndexing();
unset($expected[$this->getItemIdForLanguage('fr')]);
$expected[$this->getItemIdForLanguage('es')] = ['es', 'fr'];
$this->assertEquals($expected, $this->getLanguageWithFallbackValues(), 'Removed translation is unindexed correctly and fallback re-added.');
$node->removeTranslation('es');
$node->save();
$this->triggerPostRequestIndexing();
unset($expected[$this->getItemIdForLanguage('es')]);
$this->assertEquals($expected, $this->getLanguageWithFallbackValues(), 'Removed translation is unindexed correctly.');
$node->delete();
$this->triggerPostRequestIndexing();
$expected = [];
$this->assertEquals($expected, $this->getLanguageWithFallbackValues(), 'Removed default translation is unindexed correctly.');
// Then test with a Spanish node.
$node = Node::create($nodeValues + ['langcode' => 'es']);
$node->save();
$this->node = $node;
$this->triggerPostRequestIndexing();
$expected[$this->getItemIdForLanguage('es')] = ['es', 'fr'];
$this->assertEquals($expected, $this->getLanguageWithFallbackValues(), 'Added default translation with fallback is indexed correctly.');
$node->addTranslation('de', $nodeValues);
$node->save();
$this->triggerPostRequestIndexing();
$expected[$this->getItemIdForLanguage('de')] = ['de'];
$this->assertEquals($expected, $this->getLanguageWithFallbackValues(), 'Added translation is indexed correctly.');
$node->addTranslation('fr', $nodeValues);
$node->save();
$this->triggerPostRequestIndexing();
$expected[$this->getItemIdForLanguage('es')] = ['es'];
$expected[$this->getItemIdForLanguage('fr')] = ['fr'];
$this->assertEquals($expected, $this->getLanguageWithFallbackValues(), 'Added translation is indexed correctly and former fallback removed.');
$node->removeTranslation('de');
$node->save();
$this->triggerPostRequestIndexing();
unset($expected[$this->getItemIdForLanguage('de')]);
$this->assertEquals($expected, $this->getLanguageWithFallbackValues(), 'Removed translation is unindexed correctly.');
$node->removeTranslation('fr');
$node->save();
$this->triggerPostRequestIndexing();
unset($expected[$this->getItemIdForLanguage('fr')]);
$expected[$this->getItemIdForLanguage('es')] = ['es', 'fr'];
$this->assertEquals($expected, $this->getLanguageWithFallbackValues(), 'Removed translation is unindexed correctly and fallback re-added.');
$node->delete();
$this->triggerPostRequestIndexing();
$expected = [];
$this->assertEquals($expected, $this->getLanguageWithFallbackValues(), 'Removed default translation is unindexed correctly.');
}
/**
* Retrieves the indexed values.
*
* @return array
* The indexed "language_with_fallback" field values for all indexed items,
* keyed by item ID.
*/
protected function getLanguageWithFallbackValues() {
$query = $this->index->query();
// We don't need a query condition as we have only one node anyway.
$results = $query->execute();
$values = [];
/** @var \Drupal\search_api\Item\ItemInterface $result */
foreach ($results as $result) {
$fieldValues = $result->getField('language_with_fallback')->getValues();
sort($fieldValues);
$values[$result->getId()] = $fieldValues;
}
return $values;
}
/**
* Retrieves the test node's item ID for the given language.
*
* @param string $langcode
* The language's code.
*
* @return string
* The Search API item ID for the test node in the given language.
*/
protected function getItemIdForLanguage($langcode) {
$nid = $this->node->id();
return Utility::createCombinedId('entity:node', "$nid:$langcode");
}
}
