search_api_meilisearch-1.0.x-dev/tests/src/Kernel/Update/UpdateHook9002Test.php
tests/src/Kernel/Update/UpdateHook9002Test.php
<?php
namespace Drupal\Tests\search_api_meilisearch\Kernel\Update;
use Drupal\Component\Utility\Html;
use Drupal\Core\Field\BaseFieldDefinition;
use Drupal\Core\Logger\LoggerChannel;
use Drupal\Core\Messenger\MessengerInterface;
use Drupal\entity_test\Entity\EntityTest;
use Drupal\search_api\Entity\Index;
use Drupal\search_api\Entity\Server;
use Drupal\Tests\search_api_meilisearch\Kernel\MeilisearchKernelTestBase;
use Drupal\Tests\search_api_meilisearch\Traits\UpdateHookTrait;
use PHPUnit\Framework\Attributes\Group;
/**
* Provides tests for hook_update_9002.
*
* @group search_api_meilisearch
*/
#[Group('search_api_meilisearch')]
class UpdateHook9002Test extends MeilisearchKernelTestBase {
use UpdateHookTrait;
/**
* {@inheritdoc}
*/
protected static $modules = [
'user',
'system',
'entity_test',
'search_api',
'search_api_test',
'search_api_meilisearch',
];
/**
* {@inheritdoc}
*/
protected static $configSchemaCheckerExclusions = [
'search_api_meilisearch.settings',
];
/**
* The list of various indexes.
*
* @var \Drupal\search_api\IndexInterface[]
*/
protected array $indexes = [];
/**
* {@inheritdoc}
*/
protected function setUp(): void {
parent::setUp();
$definitions['weight'] = BaseFieldDefinition::create('integer')->setLabel('Weight');
$definitions['body'] = BaseFieldDefinition::create('string')->setLabel('Optional body');
$this->container->get('state')->set(
'entity_test.additional_base_field_definitions',
$definitions
);
$this->apiService = $this->getInstance();
$this->installConfig('search_api');
$this->installSchema('search_api', ['search_api_item']);
$this->installEntitySchema('search_api_task');
$this->installEntitySchema('entity_test');
}
/**
* Tests the update hook.
*/
public function testUpdateHook(): void {
// Expect only one error to be logged for the index without mappings that
// does not have the proper backend_config set. The third index uses a
// different backend plugin.
$mockLogger = $this->createMock(LoggerChannel::class);
$mockLogger->expects($this->once())->method('error');
$this->container->set('logger.channel.search_api_meilisearch', $mockLogger);
$this->prepareTestIndexes();
$this->prepareOldConfiguration();
$meilisearchIndex = $this->apiService
->getIndex($this->indexes['index_with_mapped_ids']->id());
// Set the primary key as before id mappings were removed.
$task = $meilisearchIndex->update(['primaryKey' => 'id']);
$this->apiService->waitForUpdate($task['taskUid']);
// Create a test entity but bypass backend logic and mimic it being inserted
// before the updates.
EntityTest::create([
'name' => 'Test entity',
'body' => 'This is the test body',
'weight' => 1,
])->save();
$task = $meilisearchIndex->addDocuments([
'id' => 'entity_entity_test_1_en',
'name' => 'Test entity',
'body' => 'This is the test body',
'weight' => 1,
]);
$this->apiService->waitForUpdate($task['taskUid']);
$this->runUpdateHook(9002);
// Test that meilisearch indexes are scheduled for reindex.
$this->assertTrue($this->indexes['index_with_mapped_ids']->isReindexing());
$this->assertTrue($this->indexes['index_without_mapped_ids']->isReindexing());
// Test that non-meilisearch index is not scheduled for reindex.
$this->assertFalse($this->indexes['index_test_backend']->isReindexing());
// Test that notice message is set.
$messages = $this->container
->get('messenger')
->messagesByType(MessengerInterface::TYPE_STATUS);
$this->assertCount(1, $messages);
$decodedMessage = Html::decodeEntities($messages[0]);
$this->assertStringContainsString(
$this->indexes['index_with_mapped_ids']->id(),
$decodedMessage
);
$this->assertStringContainsString(
$this->indexes['index_without_mapped_ids']->id(),
$decodedMessage
);
$this->assertStringNotContainsString(
$this->indexes['index_test_backend']->id(),
$decodedMessage
);
// Test that configuration was removed from module configuration.
$config = $this->config('search_api_meilisearch.settings');
$this->assertArrayNotHasKey('meilisearch_id_mappings', $config->getRawData());
// Test that the entire configuration has been deleted.
$this->assertTrue($config->isNew());
// Reindex and verify that new fields are present in the document.
$this->indexes['index_with_mapped_ids']->indexItems();
$documents = $meilisearchIndex->getDocuments();
$this->assertEquals(1, $documents->count());
$this->assertArrayHasKey('search_api_id', $documents->offsetGet(0));
$this->assertArrayHasKey('search_api_datasource', $documents->offsetGet(0));
$this->assertArrayHasKey('search_api_language', $documents->offsetGet(0));
}
/**
* Sets up a test index.
*/
protected function prepareTestIndexes(): void {
$server = Server::create([
'id' => 'test_server_1',
'name' => 'Test server',
'backend' => 'search_api_meilisearch',
'backend_config' => [
'meilisearch_host_address' => getenv('MEILI_TEST_HOST') ?: 'http://meilisearch',
'meilisearch_host_port' => getenv('MEILI_TEST_PORT') ?: '7700',
'meilisearch_master_key' => getenv('MEILI_TEST_MASTER_KEY') ?: 'MASTER_KEY',
],
]);
$server->save();
$index = Index::create([
'id' => 'test_update_9002_mapped_ids_index',
'name' => 'Test index with mapped ids',
'server' => $server->id(),
'datasource_settings' => [
'entity:entity_test' => [],
],
'field_settings' => [
'name' => [
'type' => 'string',
'datasource_id' => 'entity:entity_test',
'property_path' => 'name',
],
'weight' => [
'type' => 'integer',
'datasource_id' => 'entity:entity_test',
'property_path' => 'weight',
],
'body' => [
'type' => 'string',
'datasource_id' => 'entity:entity_test',
'property_path' => 'body',
],
],
'tracker_settings' => [
'default' => [],
],
]);
$index->save();
$this->indexes['index_with_mapped_ids'] = $index;
$server = Server::create([
'id' => 'test_server_2',
'name' => 'Test server',
'backend' => 'search_api_meilisearch',
'backend_config' => [],
]);
$server->save();
$index = Index::create([
'id' => 'test_index_no_ids',
'name' => 'Test index without mapped ids',
'server' => $server->id(),
]);
$index->save();
$this->indexes['index_without_mapped_ids'] = $index;
$server = Server::create([
'id' => 'test_server_3',
'name' => 'Test server other',
'backend' => 'search_api_test',
'backend_config' => [],
]);
$server->save();
$index = Index::create([
'id' => 'test_index_search_api_test',
'name' => 'Test index with test backend plugin',
'server' => $server->id(),
]);
$index->save();
$this->indexes['index_test_backend'] = $index;
// Mark all indexes as not scheduled for reindex.
$state = $this->container->get('state');
foreach ($this->indexes as $index) {
$key = "search_api.index.{$index->id()}.has_reindexed";
$state->set($key, FALSE);
}
}
/**
* Sets the old configuration before updates are run.
*/
protected function prepareOldConfiguration(): void {
$this->config('search_api_meilisearch.settings')
->set('meilisearch_id_mappings', [
'test_index' => [
'entity_node_1_en' => 'entity:node/1:en',
'entity_node_2_en' => 'entity:node/2:en',
'entity_node_3_en' => 'entity:node/3:en',
],
])->save(TRUE);
}
/**
* {@inheritdoc}
*/
protected function getTestIndexes(): array {
// Other indexes do not have a proper backend_config set and are not created
// in Meilisearch the test instance.
return [$this->indexes['index_with_mapped_ids']->id()];
}
}
