client = $this->createStub(Client::class); $this->logger = $this->createStub(LoggerInterface::class); $this->index = $this->createStub(Indexes::class); $this->service = new MeilisearchService($this->logger, 'http://localhost:7700', 'fake-key'); $ref = new \ReflectionProperty(MeilisearchService::class, 'client'); $ref->setValue($this->service, $this->client); $this->client->method('index')->willReturn($this->index); } private function createCustomer(): Customer { $user = new User(); $user->setEmail('customer@test.com'); $user->setFirstName('John'); $user->setLastName('Doe'); $user->setPassword('hashed'); return new Customer($user); } private function createRevendeur(): Revendeur { $user = new User(); $user->setEmail('reseller@test.com'); $user->setFirstName('Jane'); $user->setLastName('Smith'); $user->setPassword('hashed'); return new Revendeur($user, 'EC-0001'); } // --- indexCustomer --- public function testIndexCustomerSuccess(): void { $customer = $this->createCustomer(); // Should not throw $this->service->indexCustomer($customer); $this->addToAssertionCount(1); } public function testIndexCustomerThrows(): void { $customer = $this->createCustomer(); $this->index->method('addDocuments')->willThrowException(new \RuntimeException('fail')); $logger = $this->createStub(LoggerInterface::class); // No expects() means no notice if using createStub $service = new MeilisearchService($logger, 'http://localhost:7700', 'fake-key'); $ref = new \ReflectionProperty(MeilisearchService::class, 'client'); $ref->setValue($service, $this->client); $service->indexCustomer($customer); $this->addToAssertionCount(1); } // --- removeCustomer --- public function testRemoveCustomerSuccess(): void { $this->service->removeCustomer(1); $this->addToAssertionCount(1); } public function testRemoveCustomerThrows(): void { $this->index->method('deleteDocument')->willThrowException(new \RuntimeException('fail')); $logger = $this->createStub(LoggerInterface::class); $service = new MeilisearchService($logger, 'http://localhost:7700', 'fake-key'); $ref = new \ReflectionProperty(MeilisearchService::class, 'client'); $ref->setValue($service, $this->client); $service->removeCustomer(1); $this->addToAssertionCount(1); } // --- indexRevendeur --- public function testIndexRevendeurSuccess(): void { $revendeur = $this->createRevendeur(); $this->service->indexRevendeur($revendeur); $this->addToAssertionCount(1); } public function testIndexRevendeurThrows(): void { $revendeur = $this->createRevendeur(); $this->index->method('addDocuments')->willThrowException(new \RuntimeException('fail')); $logger = $this->createStub(LoggerInterface::class); $service = new MeilisearchService($logger, 'http://localhost:7700', 'fake-key'); $ref = new \ReflectionProperty(MeilisearchService::class, 'client'); $ref->setValue($service, $this->client); $service->indexRevendeur($revendeur); $this->addToAssertionCount(1); } // --- removeRevendeur --- public function testRemoveRevendeurSuccess(): void { $this->service->removeRevendeur(1); $this->addToAssertionCount(1); } public function testRemoveRevendeurThrows(): void { $this->index->method('deleteDocument')->willThrowException(new \RuntimeException('fail')); $logger = $this->createStub(LoggerInterface::class); $service = new MeilisearchService($logger, 'http://localhost:7700', 'fake-key'); $ref = new \ReflectionProperty(MeilisearchService::class, 'client'); $ref->setValue($service, $this->client); $service->removeRevendeur(1); $this->addToAssertionCount(1); } // --- searchCustomers --- public function testSearchCustomersSuccess(): void { $searchResult = $this->createStub(SearchResult::class); $searchResult->method('getHits')->willReturn([['id' => 1, 'fullName' => 'John Doe']]); $this->index->method('search')->willReturn($searchResult); $results = $this->service->searchCustomers('John'); $this->assertCount(1, $results); $this->assertSame('John Doe', $results[0]['fullName']); } public function testSearchCustomersThrows(): void { $this->index->method('search')->willThrowException(new \RuntimeException('fail')); $logger = $this->createStub(LoggerInterface::class); $service = new MeilisearchService($logger, 'http://localhost:7700', 'fake-key'); $ref = new \ReflectionProperty(MeilisearchService::class, 'client'); $ref->setValue($service, $this->client); $results = $service->searchCustomers('test'); $this->assertSame([], $results); } // --- searchRevendeurs --- public function testSearchRevendeursSuccess(): void { $searchResult = $this->createStub(SearchResult::class); $searchResult->method('getHits')->willReturn([['id' => 1, 'codeRevendeur' => 'EC-0001']]); $this->index->method('search')->willReturn($searchResult); $results = $this->service->searchRevendeurs('EC'); $this->assertCount(1, $results); } public function testSearchRevendeursThrows(): void { $this->index->method('search')->willThrowException(new \RuntimeException('fail')); $logger = $this->createStub(LoggerInterface::class); $service = new MeilisearchService($logger, 'http://localhost:7700', 'fake-key'); $ref = new \ReflectionProperty(MeilisearchService::class, 'client'); $ref->setValue($service, $this->client); $results = $service->searchRevendeurs('test'); $this->assertSame([], $results); } // --- indexPrice --- private function createPrice(): PriceAutomatic { $price = new PriceAutomatic(); $price->setType('esyweb_business'); $price->setTitle('Esy-Web Business'); $price->setDescription('Test'); $price->setPriceHt('500.00'); $price->setMonthPrice('100.00'); $price->setPeriod(1); return $price; } public function testIndexPriceSuccess(): void { $price = $this->createPrice(); $this->service->indexPrice($price); $this->addToAssertionCount(1); } public function testIndexPriceThrows(): void { $price = $this->createPrice(); $this->index->method('addDocuments')->willThrowException(new \RuntimeException('fail')); $logger = $this->createStub(LoggerInterface::class); $service = new MeilisearchService($logger, 'http://localhost:7700', 'fake-key'); $ref = new \ReflectionProperty(MeilisearchService::class, 'client'); $ref->setValue($service, $this->client); $service->indexPrice($price); $this->addToAssertionCount(1); } // --- removePrice --- public function testRemovePriceSuccess(): void { $this->service->removePrice(1); $this->addToAssertionCount(1); } public function testRemovePriceThrows(): void { $this->index->method('deleteDocument')->willThrowException(new \RuntimeException('fail')); $logger = $this->createStub(LoggerInterface::class); $service = new MeilisearchService($logger, 'http://localhost:7700', 'fake-key'); $ref = new \ReflectionProperty(MeilisearchService::class, 'client'); $ref->setValue($service, $this->client); $service->removePrice(1); $this->addToAssertionCount(1); } // --- searchPrices --- public function testSearchPricesSuccess(): void { $searchResult = $this->createStub(SearchResult::class); $searchResult->method('getHits')->willReturn([['id' => 1, 'type' => 'esyweb_business', 'title' => 'Esy-Web Business']]); $this->index->method('search')->willReturn($searchResult); $results = $this->service->searchPrices('business'); $this->assertCount(1, $results); $this->assertSame('esyweb_business', $results[0]['type']); } public function testSearchPricesThrows(): void { $this->index->method('search')->willThrowException(new \RuntimeException('fail')); $logger = $this->createStub(LoggerInterface::class); $service = new MeilisearchService($logger, 'http://localhost:7700', 'fake-key'); $ref = new \ReflectionProperty(MeilisearchService::class, 'client'); $ref->setValue($service, $this->client); $results = $service->searchPrices('test'); $this->assertSame([], $results); } // --- setupIndexes --- public function testSetupIndexesSuccess(): void { $this->service->setupIndexes(); $this->addToAssertionCount(1); } public function testSetupIndexesCreateIndexThrows(): void { $this->client->method('createIndex')->willThrowException(new \RuntimeException('already exists')); $logger = $this->createStub(LoggerInterface::class); $service = new MeilisearchService($logger, 'http://localhost:7700', 'fake-key'); $ref = new \ReflectionProperty(MeilisearchService::class, 'client'); $ref->setValue($service, $this->client); $service->setupIndexes(); $this->addToAssertionCount(1); } // --- indexContact / removeContact / searchContacts --- private function createContact(): CustomerContact { $user = new User(); $user->setEmail('contact@test.com'); $user->setFirstName('Alice'); $user->setLastName('Martin'); $user->setPassword('hashed'); $customer = new Customer($user); return new CustomerContact($customer, 'Alice', 'Martin'); } public function testIndexContactSuccess(): void { $contact = $this->createContact(); $this->service->indexContact($contact); $this->addToAssertionCount(1); } public function testIndexContactThrows(): void { $contact = $this->createContact(); $this->index->method('addDocuments')->willThrowException(new \RuntimeException('fail')); $logger = $this->createStub(LoggerInterface::class); $service = new MeilisearchService($logger, 'http://localhost:7700', 'fake-key'); $ref = new \ReflectionProperty(MeilisearchService::class, 'client'); $ref->setValue($service, $this->client); $service->indexContact($contact); $this->addToAssertionCount(1); } public function testRemoveContactSuccess(): void { $this->service->removeContact(1); $this->addToAssertionCount(1); } public function testRemoveContactThrows(): void { $this->index->method('deleteDocument')->willThrowException(new \RuntimeException('fail')); $logger = $this->createStub(LoggerInterface::class); $service = new MeilisearchService($logger, 'http://localhost:7700', 'fake-key'); $ref = new \ReflectionProperty(MeilisearchService::class, 'client'); $ref->setValue($service, $this->client); $service->removeContact(1); $this->addToAssertionCount(1); } public function testSearchContactsSuccess(): void { $searchResult = $this->createStub(SearchResult::class); $searchResult->method('getHits')->willReturn([['id' => 1, 'fullName' => 'Alice Martin']]); $this->index->method('search')->willReturn($searchResult); $results = $this->service->searchContacts('Alice'); $this->assertCount(1, $results); } public function testSearchContactsThrows(): void { $this->index->method('search')->willThrowException(new \RuntimeException('fail')); $logger = $this->createStub(LoggerInterface::class); $service = new MeilisearchService($logger, 'http://localhost:7700', 'fake-key'); $ref = new \ReflectionProperty(MeilisearchService::class, 'client'); $ref->setValue($service, $this->client); $results = $service->searchContacts('test'); $this->assertSame([], $results); } // --- indexDomain / removeDomain / searchDomains --- private function createDomain(): Domain { $user = new User(); $user->setEmail('d@test.com'); $user->setFirstName('Bob'); $user->setLastName('Doe'); $user->setPassword('hashed'); $customer = new Customer($user); return new Domain($customer, 'example.fr'); } public function testIndexDomainSuccess(): void { $domain = $this->createDomain(); $this->service->indexDomain($domain); $this->addToAssertionCount(1); } public function testIndexDomainThrows(): void { $domain = $this->createDomain(); $this->index->method('addDocuments')->willThrowException(new \RuntimeException('fail')); $logger = $this->createStub(LoggerInterface::class); $service = new MeilisearchService($logger, 'http://localhost:7700', 'fake-key'); $ref = new \ReflectionProperty(MeilisearchService::class, 'client'); $ref->setValue($service, $this->client); $service->indexDomain($domain); $this->addToAssertionCount(1); } public function testRemoveDomainSuccess(): void { $this->service->removeDomain(1); $this->addToAssertionCount(1); } public function testRemoveDomainThrows(): void { $this->index->method('deleteDocument')->willThrowException(new \RuntimeException('fail')); $logger = $this->createStub(LoggerInterface::class); $service = new MeilisearchService($logger, 'http://localhost:7700', 'fake-key'); $ref = new \ReflectionProperty(MeilisearchService::class, 'client'); $ref->setValue($service, $this->client); $service->removeDomain(1); $this->addToAssertionCount(1); } public function testSearchDomainsSuccess(): void { $searchResult = $this->createStub(SearchResult::class); $searchResult->method('getHits')->willReturn([['id' => 1, 'fqdn' => 'example.fr']]); $this->index->method('search')->willReturn($searchResult); $results = $this->service->searchDomains('example'); $this->assertCount(1, $results); } public function testSearchDomainsThrows(): void { $this->index->method('search')->willThrowException(new \RuntimeException('fail')); $logger = $this->createStub(LoggerInterface::class); $service = new MeilisearchService($logger, 'http://localhost:7700', 'fake-key'); $ref = new \ReflectionProperty(MeilisearchService::class, 'client'); $ref->setValue($service, $this->client); $results = $service->searchDomains('test'); $this->assertSame([], $results); } // --- indexWebsite / removeWebsite / searchWebsites --- private function createWebsite(): Website { $user = new User(); $user->setEmail('w@test.com'); $user->setFirstName('Carl'); $user->setLastName('Smith'); $user->setPassword('hashed'); $customer = new Customer($user); return new Website($customer, 'Mon Site', Website::TYPE_VITRINE); } public function testIndexWebsiteSuccess(): void { $website = $this->createWebsite(); $this->service->indexWebsite($website); $this->addToAssertionCount(1); } public function testIndexWebsiteThrows(): void { $website = $this->createWebsite(); $this->index->method('addDocuments')->willThrowException(new \RuntimeException('fail')); $logger = $this->createStub(LoggerInterface::class); $service = new MeilisearchService($logger, 'http://localhost:7700', 'fake-key'); $ref = new \ReflectionProperty(MeilisearchService::class, 'client'); $ref->setValue($service, $this->client); $service->indexWebsite($website); $this->addToAssertionCount(1); } public function testRemoveWebsiteSuccess(): void { $this->service->removeWebsite(1); $this->addToAssertionCount(1); } public function testRemoveWebsiteThrows(): void { $this->index->method('deleteDocument')->willThrowException(new \RuntimeException('fail')); $logger = $this->createStub(LoggerInterface::class); $service = new MeilisearchService($logger, 'http://localhost:7700', 'fake-key'); $ref = new \ReflectionProperty(MeilisearchService::class, 'client'); $ref->setValue($service, $this->client); $service->removeWebsite(1); $this->addToAssertionCount(1); } public function testSearchWebsitesSuccess(): void { $searchResult = $this->createStub(SearchResult::class); $searchResult->method('getHits')->willReturn([['id' => 1, 'name' => 'Mon Site']]); $this->index->method('search')->willReturn($searchResult); $results = $this->service->searchWebsites('site'); $this->assertCount(1, $results); } public function testSearchWebsitesThrows(): void { $this->index->method('search')->willThrowException(new \RuntimeException('fail')); $logger = $this->createStub(LoggerInterface::class); $service = new MeilisearchService($logger, 'http://localhost:7700', 'fake-key'); $ref = new \ReflectionProperty(MeilisearchService::class, 'client'); $ref->setValue($service, $this->client); $results = $service->searchWebsites('test'); $this->assertSame([], $results); } // --- indexDevis / removeDevis / searchDevis --- private function createDevis(): Devis { $orderNumber = new OrderNumber('04/2026-00001'); return new Devis($orderNumber, 'secret'); } public function testIndexDevisSuccess(): void { $devis = $this->createDevis(); $this->service->indexDevis($devis); $this->addToAssertionCount(1); } public function testIndexDevisThrows(): void { $devis = $this->createDevis(); $this->index->method('addDocuments')->willThrowException(new \RuntimeException('fail')); $logger = $this->createStub(LoggerInterface::class); $service = new MeilisearchService($logger, 'http://localhost:7700', 'fake-key'); $ref = new \ReflectionProperty(MeilisearchService::class, 'client'); $ref->setValue($service, $this->client); $service->indexDevis($devis); $this->addToAssertionCount(1); } public function testRemoveDevisSuccess(): void { $this->service->removeDevis(1); $this->addToAssertionCount(1); } public function testRemoveDevisThrows(): void { $this->index->method('deleteDocument')->willThrowException(new \RuntimeException('fail')); $logger = $this->createStub(LoggerInterface::class); $service = new MeilisearchService($logger, 'http://localhost:7700', 'fake-key'); $ref = new \ReflectionProperty(MeilisearchService::class, 'client'); $ref->setValue($service, $this->client); $service->removeDevis(1); $this->addToAssertionCount(1); } public function testSearchDevisSuccess(): void { $searchResult = $this->createStub(SearchResult::class); $searchResult->method('getHits')->willReturn([['id' => 1, 'numOrder' => '04/2026-00001']]); $this->index->method('search')->willReturn($searchResult); $results = $this->service->searchDevis('04/2026'); $this->assertCount(1, $results); } public function testSearchDevisWithCustomerFilter(): void { $searchResult = $this->createStub(SearchResult::class); $searchResult->method('getHits')->willReturn([]); $this->index->method('search')->willReturn($searchResult); $results = $this->service->searchDevis('test', 20, 42); $this->assertSame([], $results); } public function testSearchDevisThrows(): void { $this->index->method('search')->willThrowException(new \RuntimeException('fail')); $logger = $this->createStub(LoggerInterface::class); $service = new MeilisearchService($logger, 'http://localhost:7700', 'fake-key'); $ref = new \ReflectionProperty(MeilisearchService::class, 'client'); $ref->setValue($service, $this->client); $results = $service->searchDevis('test'); $this->assertSame([], $results); } // --- indexAdvert / removeAdvert / searchAdverts --- private function createAdvert(): Advert { $orderNumber = new OrderNumber('04/2026-00002'); return new Advert($orderNumber, 'secret'); } public function testIndexAdvertSuccess(): void { $advert = $this->createAdvert(); $this->service->indexAdvert($advert); $this->addToAssertionCount(1); } public function testIndexAdvertThrows(): void { $advert = $this->createAdvert(); $this->index->method('addDocuments')->willThrowException(new \RuntimeException('fail')); $logger = $this->createStub(LoggerInterface::class); $service = new MeilisearchService($logger, 'http://localhost:7700', 'fake-key'); $ref = new \ReflectionProperty(MeilisearchService::class, 'client'); $ref->setValue($service, $this->client); $service->indexAdvert($advert); $this->addToAssertionCount(1); } public function testRemoveAdvertSuccess(): void { $this->service->removeAdvert(1); $this->addToAssertionCount(1); } public function testRemoveAdvertThrows(): void { $this->index->method('deleteDocument')->willThrowException(new \RuntimeException('fail')); $logger = $this->createStub(LoggerInterface::class); $service = new MeilisearchService($logger, 'http://localhost:7700', 'fake-key'); $ref = new \ReflectionProperty(MeilisearchService::class, 'client'); $ref->setValue($service, $this->client); $service->removeAdvert(1); $this->addToAssertionCount(1); } public function testSearchAdvertsSuccess(): void { $searchResult = $this->createStub(SearchResult::class); $searchResult->method('getHits')->willReturn([['id' => 1, 'numOrder' => '04/2026-00002']]); $this->index->method('search')->willReturn($searchResult); $results = $this->service->searchAdverts('04/2026'); $this->assertCount(1, $results); } public function testSearchAdvertsWithCustomerFilter(): void { $searchResult = $this->createStub(SearchResult::class); $searchResult->method('getHits')->willReturn([]); $this->index->method('search')->willReturn($searchResult); $results = $this->service->searchAdverts('test', 20, 10); $this->assertSame([], $results); } public function testSearchAdvertsThrows(): void { $this->index->method('search')->willThrowException(new \RuntimeException('fail')); $logger = $this->createStub(LoggerInterface::class); $service = new MeilisearchService($logger, 'http://localhost:7700', 'fake-key'); $ref = new \ReflectionProperty(MeilisearchService::class, 'client'); $ref->setValue($service, $this->client); $results = $service->searchAdverts('test'); $this->assertSame([], $results); } // --- indexFacture / removeFacture / searchFactures --- private function createFacture(): Facture { $orderNumber = new OrderNumber('04/2026-00003'); return new Facture($orderNumber, 'secret'); } public function testIndexFactureSuccess(): void { $facture = $this->createFacture(); $this->service->indexFacture($facture); $this->addToAssertionCount(1); } public function testIndexFactureThrows(): void { $facture = $this->createFacture(); $this->index->method('addDocuments')->willThrowException(new \RuntimeException('fail')); $logger = $this->createStub(LoggerInterface::class); $service = new MeilisearchService($logger, 'http://localhost:7700', 'fake-key'); $ref = new \ReflectionProperty(MeilisearchService::class, 'client'); $ref->setValue($service, $this->client); $service->indexFacture($facture); $this->addToAssertionCount(1); } public function testRemoveFactureSuccess(): void { $this->service->removeFacture(1); $this->addToAssertionCount(1); } public function testRemoveFactureThrows(): void { $this->index->method('deleteDocument')->willThrowException(new \RuntimeException('fail')); $logger = $this->createStub(LoggerInterface::class); $service = new MeilisearchService($logger, 'http://localhost:7700', 'fake-key'); $ref = new \ReflectionProperty(MeilisearchService::class, 'client'); $ref->setValue($service, $this->client); $service->removeFacture(1); $this->addToAssertionCount(1); } public function testSearchFacturesSuccess(): void { $searchResult = $this->createStub(SearchResult::class); $searchResult->method('getHits')->willReturn([['id' => 1, 'invoiceNumber' => 'F-2026-001']]); $this->index->method('search')->willReturn($searchResult); $results = $this->service->searchFactures('2026'); $this->assertCount(1, $results); } public function testSearchFacturesWithCustomerFilter(): void { $searchResult = $this->createStub(SearchResult::class); $searchResult->method('getHits')->willReturn([]); $this->index->method('search')->willReturn($searchResult); $results = $this->service->searchFactures('test', 20, 5); $this->assertSame([], $results); } public function testSearchFacturesThrows(): void { $this->index->method('search')->willThrowException(new \RuntimeException('fail')); $logger = $this->createStub(LoggerInterface::class); $service = new MeilisearchService($logger, 'http://localhost:7700', 'fake-key'); $ref = new \ReflectionProperty(MeilisearchService::class, 'client'); $ref->setValue($service, $this->client); $results = $service->searchFactures('test'); $this->assertSame([], $results); } // --- purgeAllIndexes --- public function testPurgeAllIndexesSuccess(): void { $this->service->purgeAllIndexes(); $this->addToAssertionCount(1); } public function testPurgeAllIndexesThrows(): void { $this->index->method('deleteAllDocuments')->willThrowException(new \RuntimeException('fail')); $logger = $this->createStub(LoggerInterface::class); $service = new MeilisearchService($logger, 'http://localhost:7700', 'fake-key'); $ref = new \ReflectionProperty(MeilisearchService::class, 'client'); $ref->setValue($service, $this->client); $service->purgeAllIndexes(); $this->addToAssertionCount(1); } // --- getIndexCount --- public function testGetIndexCountSuccess(): void { $this->index->method('stats')->willReturn(['numberOfDocuments' => 42]); $count = $this->service->getIndexCount('customer'); $this->assertSame(42, $count); } public function testGetIndexCountMissingKey(): void { $this->index->method('stats')->willReturn([]); $count = $this->service->getIndexCount('customer'); $this->assertSame(0, $count); } public function testGetIndexCountThrows(): void { $this->index->method('stats')->willThrowException(new \RuntimeException('fail')); $logger = $this->createStub(LoggerInterface::class); $service = new MeilisearchService($logger, 'http://localhost:7700', 'fake-key'); $ref = new \ReflectionProperty(MeilisearchService::class, 'client'); $ref->setValue($service, $this->client); $count = $service->getIndexCount('customer'); $this->assertSame(0, $count); } }