diff --git a/src/Search/Algolia/Index.php b/src/Search/Algolia/Index.php index 6eab453935b..c054e117cf6 100644 --- a/src/Search/Algolia/Index.php +++ b/src/Search/Algolia/Index.php @@ -26,8 +26,14 @@ public function __construct(SearchClient $client, $name, $config, $locale) protected function client(): SearchClient { - if (! $this->settingsInitialized && isset($this->config['settings']) && ! $this->exists()) { - $this->client->setSettings($this->name, $this->config['settings']); + if (! $this->settingsInitialized && isset($this->config['settings'])) { + if (! $this->exists()) { + $this->client->setSettings($this->name, $this->config['settings']); + } + + // Mark as initialized either way. Otherwise, when the index already + // exists, we'd never stop checking and every write would spend an + // extra API call on listIndices(). $this->settingsInitialized = true; } diff --git a/tests/Search/AlgoliaIndexTest.php b/tests/Search/AlgoliaIndexTest.php index 06470f3d0e3..510cde1dc70 100644 --- a/tests/Search/AlgoliaIndexTest.php +++ b/tests/Search/AlgoliaIndexTest.php @@ -2,8 +2,11 @@ namespace Tests\Search; +use Algolia\AlgoliaSearch\Api\SearchClient; use Mockery; +use PHPUnit\Framework\Attributes\Test; use Statamic\Search\Algolia\Index as AlgoliaIndex; +use Statamic\Search\Documents; use Tests\TestCase; class AlgoliaIndexTest extends TestCase @@ -21,4 +24,33 @@ public function getIndex($name, $config, $locale) return new AlgoliaIndex($client, $name, $config, $locale); } + + #[Test] + public function it_only_checks_whether_an_existing_index_exists_once() + { + $client = Mockery::mock(SearchClient::class); + $client->shouldReceive('listIndices')->once()->andReturn(['items' => [['name' => 'test']]]); + $client->shouldNotReceive('setSettings'); + $client->shouldReceive('saveObjects')->times(3); + + $index = new AlgoliaIndex($client, 'test', ['settings' => ['hitsPerPage' => 20]], null); + + $index->insertDocuments(new Documents(collect(['one' => ['title' => 'One']]))); + $index->insertDocuments(new Documents(collect(['two' => ['title' => 'Two']]))); + $index->insertDocuments(new Documents(collect(['three' => ['title' => 'Three']]))); + } + + #[Test] + public function it_applies_settings_once_when_the_index_does_not_exist() + { + $client = Mockery::mock(SearchClient::class); + $client->shouldReceive('listIndices')->once()->andReturn(['items' => []]); + $client->shouldReceive('setSettings')->once()->with('test', ['hitsPerPage' => 20]); + $client->shouldReceive('saveObjects')->twice(); + + $index = new AlgoliaIndex($client, 'test', ['settings' => ['hitsPerPage' => 20]], null); + + $index->insertDocuments(new Documents(collect(['one' => ['title' => 'One']]))); + $index->insertDocuments(new Documents(collect(['two' => ['title' => 'Two']]))); + } }