Skip to content

Commit

Permalink
Cleaning
Browse files Browse the repository at this point in the history
  • Loading branch information
GromNaN committed Dec 2, 2024
1 parent bebdd1d commit ee6edd2
Show file tree
Hide file tree
Showing 4 changed files with 39 additions and 35 deletions.
27 changes: 14 additions & 13 deletions src/Scout/ScoutEngine.php
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ final class ScoutEngine extends Engine
];

public function __construct(
private Database $mongodb,
private Database $database,
private bool $softDelete,
private string $prefix,
) {
Expand Down Expand Up @@ -203,6 +203,7 @@ protected function performSearch(Builder $builder, ?int $offset = null): array
],
],
],
'minimumShouldMatch' => 1,
];

// "filter" specifies conditions on exact values to match
Expand Down Expand Up @@ -238,7 +239,7 @@ protected function performSearch(Builder $builder, ?int $offset = null): array
],
[
'$addFields' => [
'search_meta' => '$$SEARCH_META',
'__count' => '$$SEARCH_META.count.lowerBound',
],
],
];
Expand Down Expand Up @@ -298,7 +299,7 @@ public function map(Builder $builder, $results, $model): Collection
$result = $results[$objectIdPositions[$model->getScoutKey()]] ?? [];

foreach ($result as $key => $value) {
if (substr($key, 0, 1) === '_') {
if ($key[0] === '_') {
$model->withScoutMetadata($key, $value);
}
}
Expand All @@ -321,7 +322,7 @@ public function getTotalCount($results): int
return 0;
}

return $results[0]->search_meta['count']['lowerBound'];
return $results[0]->__count;
}

/**
Expand Down Expand Up @@ -393,9 +394,9 @@ public function createIndex($name, array $options = []): void
assert(is_string($name), new TypeError(sprintf('Argument #1 ($name) must be of type string, %s given', get_debug_type($name))));

// Ensure the collection exists before creating the search index
$this->mongodb->createCollection($name);
$this->database->createCollection($name);

$collection = $this->mongodb->selectCollection($name);
$collection = $this->database->selectCollection($name);
$collection->createSearchIndex(
self::DEFAULT_DEFINITION,
['name' => self::INDEX_NAME],
Expand All @@ -420,22 +421,22 @@ public function deleteIndex($name): void
{
assert(is_string($name), new TypeError(sprintf('Argument #1 ($name) must be of type string, %s given', get_debug_type($name))));

$this->mongodb->selectCollection($name)->drop();
$this->database->selectCollection($name)->drop();
}

/**
* Delete all "search indexes", i.e. all MongoDB collections.
*/
public function deleteAllIndexes()
{
$collectionNames = $this->mongodb->listCollectionNames([
$collectionNames = $this->database->listCollectionNames([
'filter' => [
'name' => new Regex('^' . preg_quote($this->prefix)),
],
]);

foreach ($collectionNames as $collectionName) {
$this->mongodb->selectCollection($collectionName)->drop();
$this->database->selectCollection($collectionName)->drop();
}
}

Expand All @@ -448,7 +449,7 @@ private function getSearchableCollection(Model|EloquentCollection $model): Mongo

assert(in_array(Searchable::class, class_uses_recursive($model)), sprintf('Model "%s" must use "%s" trait', $model::class, Searchable::class));

return $this->mongodb->selectCollection($model->searchableAs());
return $this->database->selectCollection($model->searchableAs());
}

/** Get the MongoDB collection used to index the provided model */
Expand All @@ -463,13 +464,13 @@ private function getIndexableCollection(Model|EloquentCollection $model): MongoD

if (
$model->getConnection() instanceof Connection
&& $model->getConnection()->getDatabaseName() === $this->mongodb->getDatabaseName()
&& $model->getConnection()->getDatabaseName() === $this->database->getDatabaseName()
&& $model->getTable() === $model->indexableAs()
) {
throw new LogicException(sprintf('The MongoDB Scout collection "%s.%s" must use a different collection from the collection name of the model "%s". Set the "scout.prefix" configuration or use a distinct MongoDB database', $this->mongodb->getDatabaseName(), $model->indexableAs(), $model::class));
throw new LogicException(sprintf('The MongoDB Scout collection "%s.%s" must use a different collection from the collection name of the model "%s". Set the "scout.prefix" configuration or use a distinct MongoDB database', $this->database->getDatabaseName(), $model->indexableAs(), $model::class));
}

return $this->mongodb->selectCollection($model->indexableAs());
return $this->database->selectCollection($model->indexableAs());
}

private static function serialize(mixed $value): mixed
Expand Down
3 changes: 2 additions & 1 deletion tests/ModelTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -406,8 +406,9 @@ public function testSoftDelete(): void
$this->assertEquals(2, Soft::count());
}

/** @param class-string<Model> $model */
#[DataProvider('provideId')]
public function testPrimaryKey(string $model, $id, $expected, bool $expectedFound): void
public function testPrimaryKey(string $model, mixed $id, mixed $expected, bool $expectedFound): void
{
$model::truncate();
$expectedType = get_debug_type($expected);
Expand Down
26 changes: 22 additions & 4 deletions tests/Scout/ScoutEngineTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
use Illuminate\Support\Collection as IlluminateCollection;
use Laravel\Scout\Builder;
use Laravel\Scout\Jobs\RemoveFromSearch;
use LogicException;
use Mockery as m;
use MongoDB\BSON\Document;
use MongoDB\BSON\Regex;
Expand All @@ -17,13 +18,16 @@
use MongoDB\Database;
use MongoDB\Driver\CursorInterface;
use MongoDB\Laravel\Scout\ScoutEngine;
use MongoDB\Laravel\Tests\Models\SearchableInSameNamespace;
use MongoDB\Laravel\Tests\Models\SearchableModel;
use MongoDB\Laravel\Tests\TestCase;
use MongoDB\Model\BSONDocument;
use PHPUnit\Framework\Attributes\DataProvider;

use function array_replace_recursive;
use function env;
use function serialize;
use function sprintf;
use function unserialize;

/** Unit tests that do not require an Atlas Search cluster */
Expand All @@ -35,7 +39,7 @@ class ScoutEngineTest extends TestCase
#[DataProvider('provideSearchPipelines')]
public function testSearch(Closure $builder, array $expectedPipeline): void
{
$data = [['_id' => 'key_1'], ['_id' => 'key_2']];
$data = [['_id' => 'key_1', '__count' => 15], ['_id' => 'key_2', '__count' => 15]];
$database = m::mock(Database::class);
$collection = m::mock(Collection::class);
$database->shouldReceive('selectCollection')
Expand Down Expand Up @@ -83,6 +87,7 @@ public function provideSearchPipelines(): iterable
],
],
],
'minimumShouldMatch' => 1,
],
'count' => [
'type' => 'lowerBound',
Expand All @@ -91,7 +96,7 @@ public function provideSearchPipelines(): iterable
],
[
'$addFields' => [
'search_meta' => '$$SEARCH_META',
'__count' => '$$SEARCH_META.count.lowerBound',
],
],
];
Expand Down Expand Up @@ -361,6 +366,7 @@ public function testPaginate()
],
],
],
'minimumShouldMatch' => 1,
],
'count' => [
'type' => 'lowerBound',
Expand All @@ -372,7 +378,7 @@ public function testPaginate()
],
[
'$addFields' => [
'search_meta' => '$$SEARCH_META',
'__count' => '$$SEARCH_META.count.lowerBound',
],
],
[
Expand All @@ -391,7 +397,7 @@ public function testPaginate()
$cursor->shouldReceive('toArray')
->once()
->with()
->andReturn([['_id' => 'key_1'], ['_id' => 'key_2']]);
->andReturn([['_id' => 'key_1', '__count' => 17], ['_id' => 'key_2', '__count' => 17]]);

$engine = new ScoutEngine($database, softDelete: false, prefix: '');
$builder = new Builder(new SearchableModel(), 'mustang');
Expand Down Expand Up @@ -564,4 +570,16 @@ public function testDeleteAll(): void
$engine = new ScoutEngine($database, softDelete: false, prefix: 'scout-prefix-');
$engine->deleteAllIndexes();
}

public function testItCannotIndexInTheSameNamespace()
{
self::expectException(LogicException::class);
self::expectExceptionMessage(sprintf(
'The MongoDB Scout collection "%s.searchable_in_same_namespaces" must use a different collection from the collection name of the model "%s". Set the "scout.prefix" configuration or use a distinct MongoDB database',
env('MONGODB_DATABASE', 'unittest'),
SearchableInSameNamespace::class,
),);

SearchableInSameNamespace::create(['name' => 'test']);
}
}
18 changes: 1 addition & 17 deletions tests/Scout/ScoutIntegrationTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,20 +5,16 @@
use Illuminate\Database\Eloquent\Factories\Sequence;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\LazyCollection;
use LogicException;
use MongoDB\Driver\Exception\ServerException;
use MongoDB\Laravel\Tests\Models\SearchableInSameNamespace;
use MongoDB\Laravel\Tests\Models\SqlUser;
use MongoDB\Laravel\Tests\TestCase;
use Orchestra\Testbench\Factories\UserFactory;
use PHPUnit\Framework\Attributes\Depends;

use function count;
use function env;
use function in_array;
use function Orchestra\Testbench\artisan;
use function range;
use function sprintf;
use function usleep;

class ScoutIntegrationTest extends TestCase
Expand All @@ -40,7 +36,7 @@ public function testItCanCreateTheCollection()
} catch (ServerException $exception) {
if (
in_array($exception->getCode(), [
40324, // Old version: Unrecognized pipeline stage name: '$listSearchIndexes'
40324, // Prior to MongoDB 6: Unrecognized pipeline stage name: '$listSearchIndexes'
31082, // Community Server: Using Atlas Search Database Commands and the $listSearchIndexes aggregation stage requires additional configuration.
115, // Enterprise Server: PlanExecutor error during aggregation :: caused by :: Search index commands are only supported with Atlas.
])
Expand Down Expand Up @@ -241,16 +237,4 @@ public function testItCanUsePaginatedSearchWithQueryCallback()
41 => 'Gudrun Larkin',
], $page2->pluck('name', 'id')->all());
}

public function testItCannotIndexInTheSameNamespace()
{
self::expectException(LogicException::class);
self::expectExceptionMessage(sprintf(
'The MongoDB Scout collection "%s.searchable_in_same_namespaces" must use a different collection from the collection name of the model "%s". Set the "scout.prefix" configuration or use a distinct MongoDB database',
env('MONGODB_DATABASE', 'unittest'),
SearchableInSameNamespace::class,
),);

SearchableInSameNamespace::create(['name' => 'test']);
}
}

0 comments on commit ee6edd2

Please sign in to comment.