diff --git a/composer.json b/composer.json index 647cf3fb..a484ec3b 100644 --- a/composer.json +++ b/composer.json @@ -26,6 +26,7 @@ "require-dev": { "meilisearch/meilisearch-php": "^0.17", "mockery/mockery": "^1.0", + "orchestra/testbench": "^6.17", "phpunit/phpunit": "^9.3" }, "autoload": { diff --git a/phpunit.xml.dist b/phpunit.xml.dist index 167e3f85..6696a097 100644 --- a/phpunit.xml.dist +++ b/phpunit.xml.dist @@ -11,8 +11,17 @@ stopOnFailure="false" > - - ./tests/ + + ./tests/Unit + + + ./tests/Feature + + + + + + diff --git a/src/Builder.php b/src/Builder.php index 9b606c6a..31cf6db3 100644 --- a/src/Builder.php +++ b/src/Builder.php @@ -320,7 +320,7 @@ public function paginate($perPage = null, $pageName = 'page', $page = null) $paginator = Container::getInstance()->makeWith(LengthAwarePaginator::class, [ 'items' => $results, - 'total' => $engine->getTotalCount($rawResults), + 'total' => $this->getTotalCount($rawResults), 'perPage' => $perPage, 'currentPage' => $page, 'options' => [ @@ -352,7 +352,7 @@ public function paginateRaw($perPage = null, $pageName = 'page', $page = null) $paginator = Container::getInstance()->makeWith(LengthAwarePaginator::class, [ 'items' => $results, - 'total' => $engine->getTotalCount($results), + 'total' => $this->getTotalCount($results), 'perPage' => $perPage, 'currentPage' => $page, 'options' => [ @@ -364,6 +364,25 @@ public function paginateRaw($perPage = null, $pageName = 'page', $page = null) return $paginator->appends('query', $this->query); } + /** + * Get the total number of results from the Scout engine, or fallback to query builder. + * + * @param mixed $results + * @return int + */ + protected function getTotalCount($results) + { + $engine = $this->engine(); + + if (is_null($this->queryCallback)) { + return $engine->getTotalCount($results); + } + + return $this->model->queryScoutModelsByIds( + $this, $engine->mapIds($results)->all() + )->toBase()->getCountForPagination(); + } + /** * Get the engine that should handle the query. * diff --git a/tests/Feature/BuilderTest.php b/tests/Feature/BuilderTest.php new file mode 100644 index 00000000..b3a29d4c --- /dev/null +++ b/tests/Feature/BuilderTest.php @@ -0,0 +1,89 @@ +make('config')->set('scout.driver', 'fake'); + } + + protected function defineDatabaseMigrations() + { + $this->setUpFaker(); + $this->loadLaravelMigrations(); + + UserFactory::new()->count(50)->state(new Sequence(function () { + return ['name' => 'Laravel '.$this->faker()->name()]; + }))->create(); + + UserFactory::new()->times(50)->create(); + } + + public function test_it_can_paginate_without_custom_query_callback() + { + $this->prepareScoutSearchMockUsing('Laravel'); + + $paginator = SearchableUserModel::search('Laravel')->paginate(); + + $this->assertSame(50, $paginator->total()); + $this->assertSame(4, $paginator->lastPage()); + $this->assertSame(15, $paginator->perPage()); + } + + public function test_it_can_paginate_with_custom_query_callback() + { + $this->prepareScoutSearchMockUsing('Laravel'); + + $paginator = SearchableUserModel::search('Laravel')->query(function ($builder) { + return $builder->where('id', '<', 11); + })->paginate(); + + $this->assertSame(10, $paginator->total()); + $this->assertSame(1, $paginator->lastPage()); + $this->assertSame(15, $paginator->perPage()); + } + + protected function prepareScoutSearchMockUsing($searchQuery) + { + $engine = m::mock('MeiliSearch\Client'); + $indexes = m::mock('MeiliSearch\Endpoints\Indexes'); + + $manager = $this->app->make(EngineManager::class); + $manager->extend('fake', function () use ($engine) { + return new MeiliSearchEngine($engine); + }); + + $query = User::where('name', 'like', $searchQuery.'%'); + + $engine->shouldReceive('index')->with('users')->andReturn($indexes); + $indexes->shouldReceive('rawSearch')->with($searchQuery, ['limit' => 15])->andReturn([ + 'hits' => $query->get()->transform(function ($result) { + return [ + 'id' => $result->getKey(), + 'name' => $result->name, + ]; + }), + 'nbHits' => $query->count(), + ]); + } +} diff --git a/tests/SearchableTest.php b/tests/Feature/SearchableTest.php similarity index 91% rename from tests/SearchableTest.php rename to tests/Feature/SearchableTest.php index a8a0abaa..3504bec4 100644 --- a/tests/SearchableTest.php +++ b/tests/Feature/SearchableTest.php @@ -1,19 +1,14 @@