Skip to content

Commit a5895a2

Browse files
committed
Fix AggregatorObserver sync status
1 parent 127f03c commit a5895a2

File tree

2 files changed

+110
-8
lines changed

2 files changed

+110
-8
lines changed

src/Searchable/AggregatorObserver.php

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -85,10 +85,6 @@ public function saved($model): void
8585
*/
8686
public function deleted($model): void
8787
{
88-
if (static::syncingDisabledFor($model)) {
89-
return;
90-
}
91-
9288
if ($this->usesSoftDelete($model) && config('scout.soft_delete', false)) {
9389
$this->saved($model);
9490
} else {
@@ -112,10 +108,6 @@ public function deleted($model): void
112108
*/
113109
public function forceDeleted($model): void
114110
{
115-
if (static::syncingDisabledFor($model)) {
116-
return;
117-
}
118-
119111
$class = get_class($model);
120112

121113
if (! array_key_exists($class, $this->aggregators)) {

tests/Features/AggregatorTest.php

Lines changed: 110 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
use App\Thread;
1616
use App\User;
1717
use App\Wall;
18+
use Laravel\Scout\ModelObserver;
1819
use Laravel\Scout\Scout;
1920
use Mockery;
2021
use RuntimeException;
@@ -582,6 +583,115 @@ public function testWhenAggregatorIsBootedBeforePlainScoutSearchableTrait(): voi
582583

583584
$user->delete();
584585
}
586+
587+
public function testSkipDeletedWhenDisableSyncingFor(): void
588+
{
589+
$this->app['config']->set('scout.algolia.use_deprecated_delete_by', false);
590+
591+
$wallIndexMock = $this->mockIndex('wall');
592+
$usersIndexMock = $this->mockIndex('users');
593+
594+
$usersIndexMock->shouldReceive('saveObjects')->once();
595+
596+
$user = factory(User::class)->create();
597+
598+
ModelObserver::disableSyncingFor(User::class);
599+
600+
Wall::bootSearchable();
601+
602+
try {
603+
// Expect browseObjects and deleteObjects to be called on the wall index
604+
$wallIndexMock->shouldReceive('browseObjects')->once()->with([
605+
'attributesToRetrieve' => ['objectID'],
606+
'tagFilters' => [['App\User::1']],
607+
])->andReturn([['objectID' => 'App\User::1']]);
608+
$wallIndexMock->shouldReceive('deleteObjects')->once()->with(['App\User::1']);
609+
610+
// Ensure browseObjects and deleteObjects are NOT called on the users index
611+
$usersIndexMock->shouldNotReceive('browseObjects')->with([
612+
'attributesToRetrieve' => ['objectID'],
613+
'tagFilters' => [['App\User::1']],
614+
])->andReturn([['objectID' => 'App\User::1']]);
615+
$usersIndexMock->shouldNotReceive('deleteObjects')->with(['App\User::1']);
616+
617+
$user->delete();
618+
} finally {
619+
ModelObserver::enableSyncingFor(User::class);
620+
}
621+
}
622+
623+
public function testSkipForceDeletedWhenDisableSyncingFor(): void
624+
{
625+
$this->app['config']->set('scout.algolia.use_deprecated_delete_by', false);
626+
627+
$wallIndexMock = $this->mockIndex('wall');
628+
$usersIndexMock = $this->mockIndex('users');
629+
630+
$usersIndexMock->shouldReceive('saveObjects')->once();
631+
$user = factory(User::class)->create();
632+
633+
ModelObserver::disableSyncingFor(User::class);
634+
635+
Wall::bootSearchable();
636+
637+
try {
638+
// Expect browseObjects and deleteObjects to be called on the wall index
639+
$wallIndexMock->shouldReceive('browseObjects')->once()->with([
640+
'attributesToRetrieve' => ['objectID',],
641+
'tagFilters' => [['App\User::1'],],
642+
])->andReturn([['objectID' => 'App\User::1']]);
643+
$wallIndexMock->shouldReceive('deleteObjects')->once()->with(['App\User::1']);
644+
645+
// Ensure browseObjects and deleteObjects are NOT called on the users index
646+
$usersIndexMock->shouldNotReceive('browseObjects')->with([
647+
'attributesToRetrieve' => ['objectID'],
648+
'tagFilters' => [['App\User::1']],
649+
])->andReturn([['objectID' => 'App\User::1']]);
650+
$usersIndexMock->shouldNotReceive('deleteObjects')->with(['App\User::1']);
651+
652+
$user->forceDelete();
653+
654+
ModelObserver::enableSyncingFor(User::class);
655+
} finally {
656+
// Ensure that the ModelObserver is re-enabled even if an exception occurs
657+
ModelObserver::enableSyncingFor(User::class);
658+
}
659+
}
660+
661+
public function testSkipSavedWhenDisableSyncingFor(): void
662+
{
663+
$wallIndexMock = $this->mockIndex('wall');
664+
$usersIndexMock = $this->mockIndex('users');
665+
666+
$usersIndexMock->shouldReceive('saveObjects')->once();
667+
668+
$user = factory(User::class)->create();
669+
670+
ModelObserver::disableSyncingFor(User::class);
671+
672+
try {
673+
// Expect saveObjects to be called once for the wall index
674+
$wallIndexMock->shouldReceive('saveObjects')
675+
->once()
676+
->with(Mockery::on(function ($argument) {
677+
return count($argument) === 1 && array_key_exists('email', $argument[0]) &&
678+
$argument[0]['objectID'] === 'App\User::1';
679+
}));
680+
681+
// Ensure saveObjects is NOT called for the users index
682+
$usersIndexMock->shouldNotReceive('saveObjects')
683+
->with(Mockery::on(function ($argument) {
684+
return count($argument) === 1 && array_key_exists('email', $argument[0]) &&
685+
$argument[0]['objectID'] === 'App\User::1';
686+
}));
687+
688+
Wall::bootSearchable();
689+
690+
$user->save();
691+
} finally {
692+
ModelObserver::enableSyncingFor(User::class);
693+
}
694+
}
585695
}
586696

587697
class DummyRemoveFromSearch {

0 commit comments

Comments
 (0)