search_api_autocomplete-8.x-1.x-dev/tests/src/Kernel/DependencyRemovalTest.php
tests/src/Kernel/DependencyRemovalTest.php
<?php
namespace Drupal\Tests\search_api_autocomplete\Kernel;
use Drupal\KernelTests\KernelTestBase;
use Drupal\search_api\Entity\Server;
use Drupal\search_api_autocomplete\Entity\Search;
use Drupal\search_api_autocomplete\Tests\TestsHelper;
use Drupal\search_api_test\PluginTestTrait;
use Drupal\views\Entity\View;
/**
* Tests dependency handling of the search entity.
*
* @group search_api_autocomplete
*/
class DependencyRemovalTest extends KernelTestBase {
use PluginTestTrait;
/**
* {@inheritdoc}
*/
protected static $modules = [
'entity_test',
'search_api_autocomplete',
'search_api_autocomplete_test',
'search_api',
'search_api_test',
'search_api_test_example_content',
'system',
'user',
'views',
];
/**
* The autocomplete search entity used in this test.
*
* @var \Drupal\search_api_autocomplete\SearchInterface
*/
protected $search;
/**
* A config entity, to be used as a dependency in the tests.
*
* @var \Drupal\Core\Config\Entity\ConfigEntityInterface
*/
protected $dependency;
/**
* {@inheritdoc}
*/
protected function setUp(): void {
parent::setUp();
// Do not use a batch for tracking the initial items after creating an
// index when running the tests via the GUI. Otherwise, it seems Drupal's
// Batch API gets confused and the test fails.
if (php_sapi_name() != 'cli') {
\Drupal::state()->set('search_api_use_tracking_batch', FALSE);
}
$this->installEntitySchema('entity_test_mulrev_changed');
$this->installEntitySchema('search_api_task');
$this->installEntitySchema('user');
$this->installSchema('search_api', ['search_api_item']);
$this->installConfig('search_api');
$this->installConfig('search_api_autocomplete_test');
// Create our test search, but don't save it yet so individual tests can
// still easily change the settings.
$this->search = Search::create([
'id' => 'search_api_autocomplete_test_view',
'label' => 'Test',
'status' => TRUE,
'index_id' => 'autocomplete_search_index',
'suggester_settings' => [
'search_api_autocomplete_test' => [],
],
'search_settings' => [
'views:search_api_autocomplete_test_view' => [],
],
]);
// Use a search server as the dependency, since we have that available
// anyways. The entity type should not matter at all, though.
$this->dependency = Server::create([
'id' => 'dependency',
'name' => 'Test dependency',
'backend' => 'search_api_test',
]);
$this->dependency->save();
}
/**
* Tests that the dependency on the index works correctly.
*/
public function testIndexDependency() {
$this->search->save();
$index = $this->search->getIndex();
// Verify that the dependency is included.
$dependencies = $this->search->getDependencies();
$this->assertArrayHasKey('config', $dependencies);
$this->assertContains($index->getConfigDependencyName(), $dependencies['config']);
// Verify that deleting the index will also delete the search.
$index->delete();
$search = Search::load($this->search->id());
$this->assertNull($search);
}
/**
* Tests that the Views dependency works correctly for a search view.
*/
public function testViewsDependency() {
$this->search->save();
$view = View::load('search_api_autocomplete_test_view');
// Verify that the dependencies are both included.
$dependencies = $this->search->getDependencies();
$this->assertArrayHasKey('config', $dependencies);
$this->assertContains($view->getConfigDependencyName(), $dependencies['config']);
$this->assertArrayHasKey('module', $dependencies);
$this->assertContains('views', $dependencies['module']);
// Verify that deleting the view will also delete the search.
$view->delete();
$search = Search::load($this->search->id());
$this->assertNull($search);
}
/**
* Tests that a general search plugin dependency works correctly.
*
* @param bool $removable
* TRUE if the search plugin's dependency should be removable, FALSE
* otherwise.
*
* @dataProvider searchPluginDependencyDataProvider
*/
public function testSearchPluginDependency($removable) {
$dependency_key = $this->dependency->getConfigDependencyKey();
$dependency_name = $this->dependency->getConfigDependencyName();
$this->search->set('search_settings', [
'search_api_autocomplete_test' => [
'dependencies' => [
$dependency_key => [$dependency_name],
],
],
]);
$this->search->save();
$this->setReturnValue('search', 'onDependencyRemoval', $removable);
// Verify that the dependencies are all included.
$dependencies = $this->search->getDependencies();
$this->assertArrayHasKey($dependency_key, $dependencies);
$this->assertContains($dependency_name, $dependencies[$dependency_key]);
$this->assertArrayHasKey('module', $dependencies);
$this->assertContains('search_api_autocomplete_test', $dependencies['module']);
// Delete the dependency and verify that the result is as expected.
$this->dependency->delete();
$search = Search::load($this->search->id());
if ($removable) {
$this->assertNotNull($search);
$dependencies = $search->getDependencies();
$dependencies += [$dependency_key => []];
$this->assertNotContains($dependency_name, $dependencies[$dependency_key]);
}
else {
$this->assertNull($search);
}
}
/**
* Provides test data sets for testSearchPluginDependency().
*
* @return array[]
* An array of argument arrays for testSearchPluginDependency().
*
* @see \Drupal\Tests\search_api_autocomplete\Kernel\DependencyRemovalTest::testSearchPluginDependency()
*/
public static function searchPluginDependencyDataProvider(): array {
return [
'soft dependency' => [TRUE],
'hard dependency' => [FALSE],
];
}
/**
* Tests that a suggester dependency works correctly.
*
* @param bool $removable
* TRUE if the suggester's dependency should be removable, FALSE otherwise.
* @param bool $second_suggester
* TRUE if a second suggester, apart from the test suggester, should be
* included in the search, FALSE otherwise.
*
* @dataProvider suggesterDependencyDataProvider
*/
public function testSuggesterDependency($removable, $second_suggester) {
$dependency_key = $this->dependency->getConfigDependencyKey();
$dependency_name = $this->dependency->getConfigDependencyName();
$suggester_id = 'search_api_autocomplete_test';
$settings = [
$suggester_id => [
'dependencies' => [
$dependency_key => [$dependency_name],
],
],
];
if ($second_suggester) {
// Make the test backend support autocomplete so that the "Server"
// suggester becomes available.
$callback = [TestsHelper::class, 'getSupportedFeatures'];
$this->setMethodOverride('backend', 'getSupportedFeatures', $callback);
$callback = [TestsHelper::class, 'getAutocompleteSuggestions'];
$this->setMethodOverride('backend', 'getAutocompleteSuggestions', $callback);
$settings['server'] = [];
}
$this->search->set('suggester_settings', $settings);
$this->search->save();
$this->setReturnValue('suggester', 'onDependencyRemoval', $removable);
// Verify that the dependencies are all included.
$dependencies = $this->search->getDependencies();
$this->assertArrayHasKey($dependency_key, $dependencies);
$this->assertContains($dependency_name, $dependencies[$dependency_key]);
$this->assertArrayHasKey('module', $dependencies);
$this->assertContains('search_api_autocomplete_test', $dependencies['module']);
// Delete the dependency and verify that the result is as expected.
$this->dependency->delete();
$search = Search::load($this->search->id());
$this->assertNotNull($search);
$this->assertEquals($removable || $second_suggester, $search->status());
$dependencies = $search->getDependencies();
$dependencies += [$dependency_key => []];
$this->assertNotContains($dependency_name, $dependencies[$dependency_key]);
$this->assertEquals($removable, $search->isValidSuggester($suggester_id));
}
/**
* Provides test data sets for testSuggesterDependency().
*
* @return array[]
* An array of argument arrays for testSuggesterDependency().
*
* @see \Drupal\Tests\search_api_autocomplete\Kernel\DependencyRemovalTest::testSuggesterDependency()
*/
public static function suggesterDependencyDataProvider(): array {
return [
'soft dependency, one suggester' => [TRUE, FALSE],
'hard dependency, one suggester' => [FALSE, FALSE],
'soft dependency, two suggesters' => [TRUE, TRUE],
'hard dependency, two suggesters' => [FALSE, TRUE],
];
}
}
