search_api_meilisearch-1.0.x-dev/tests/src/Kernel/Backend/LimitOffsetSearchTest.php
tests/src/Kernel/Backend/LimitOffsetSearchTest.php
<?php
namespace Drupal\Tests\search_api_meilisearch\Kernel\Backend;
use Drupal\entity_test\Entity\EntityTest;
use Drupal\search_api_meilisearch\Api\MeilisearchApiService;
use Meilisearch\Search\SearchResult;
use PHPUnit\Framework\Attributes\Group;
/**
* Tests search with different limit values.
*
* @group search_api_meilisearch
*/
#[Group('search_api_meilisearch')]
class LimitOffsetSearchTest extends BackendKernelTestBase {
protected const TEST_INDEX = 'kernel_backend_limit_test_index';
/**
* Test that search with known limit values will have one search call.
*/
public function testSearchWithKnownLimit(): void {
// The number of calls is directly connected to the number of queries.
$this->mockMeiliService(3);
$this->prepareTestIndex(self::TEST_INDEX);
$this->index->query()
->range(0, 5)
->execute();
$this->index->query()
->range(5, 5)
->execute();
$this->index->query()
->range(10, 5)
->execute();
}
/**
* Test that search with unknown limit values will have two search calls.
*/
public function testSearchWithUnknownLimit(): void {
$this->mockMeiliService(2);
$this->prepareTestIndex(self::TEST_INDEX);
$this->index->query()
->range()
->execute();
}
/**
* Test offset and limit values.
*/
public function testSearchWithOffsetAndLimit(): void {
$this->prepareTestIndex(self::TEST_INDEX);
$this->populateIndex();
// Gets first 10 items.
$results = $this->index->query()
->range(0, 10)
->sort('weight', 'ASC')
->execute();
$ids = array_keys($results->getResultItems());
foreach (range(1, 10) as $key) {
$this->assertEquals('entity:entity_test/' . $key . ':en', $ids[$key - 1]);
}
// Gets next 10 items.
$results = $this->index->query()
->range(10, 10)
->sort('weight', 'ASC')
->execute();
$ids = array_keys($results->getResultItems());
foreach (range(11, 20) as $key) {
$this->assertEquals('entity:entity_test/' . $key . ':en', $ids[$key - 11]);
}
// Offset is greater than the number of items. Should return empty result.
$results = $this->index->query()
->range(200, 10)
->sort('weight', 'ASC')
->execute();
$ids = array_keys($results->getResultItems());
$this->assertCount(0, $ids);
}
/**
* Populates the index with entities.
*/
protected function populateIndex(): void {
foreach (range(1, 100) as $key => $weight) {
EntityTest::create([
'name' => 'Test entity ' . $key,
'body' => 'This is the body of entity' . $key,
'weight' => $weight,
])->save();
}
$this->index->indexItems();
}
/**
* Mocks the Meilisearch service. And sets expectations.
*
* @param int $numOfSearchCalls
* Number of times the search method will be called.
*/
protected function mockMeiliService(int $numOfSearchCalls): void {
$mockMeilisearchApiService = $this->getMockBuilder(MeilisearchApiService::class)
->disableOriginalConstructor()
->getMock();
$mockMeilisearchApiService->expects($this->any())
->method('createIndex')
->willReturn(['taskUid' => 1111]);
$mockMeilisearchApiService->expects($this->any())
->method('waitForUpdate')
->willReturn([
'taskUid' => 1111,
'indexUid' => self::TEST_INDEX,
'status' => 'succeeded',
'type' => 'indexCreation',
]);
$mockMeilisearchApiService->expects($this->any())
->method('addDocuments')
->willReturn(['taskUid' => 1111]);
$mockMeilisearchApiService->expects($this->exactly($numOfSearchCalls))
->method('search')
->willReturnCallback(function ($index, $query, $options) {
$limit = $options['limit'] ?? 20;
$offset = $options['offset'] ?? 0;
$results = [];
foreach (range($offset, $offset + $limit - 1) as $key) {
$results[] = [
'id' => 'entity_entity_test_' . $key . '_en',
'search_api_id' => 'entity:entity_test/' . $key . ':en',
'body' => 'This is the body of entity ' . $key,
'name' => 'Test entity ' . $key,
'weight' => $key,
'_rankingScore' => 1.0,
];
}
return new SearchResult([
'hits' => $results,
'offset' => $offset,
'limit' => $limit,
'estimatedTotalHits' => 100,
'processingTimeMs' => 1,
'query' => $query,
'facetDistribution' => [],
]);
});
$this->container->set('search_api_meilisearch.api', $mockMeilisearchApiService);
}
/**
* {@inheritdoc}
*/
protected function getTestIndexes(): array {
return [self::TEST_INDEX];
}
}
