createStub(RequestStack::class); $stack->method('getSession')->willReturn($session); $twig = $this->createStub(Environment::class); $twig->method('render')->willReturn(''); $router = $this->createStub(RouterInterface::class); $router->method('generate')->willReturn('/admin/sync'); $container = $this->createStub(ContainerInterface::class); $container->method('has')->willReturn(true); $container->method('get')->willReturnMap([ ['twig', $twig], ['router', $router], ['security.authorization_checker', $this->createStub(AuthorizationCheckerInterface::class)], ['security.token_storage', $this->createStub(TokenStorageInterface::class)], ['request_stack', $stack], ['parameter_bag', $this->createStub(\Symfony\Component\DependencyInjection\ParameterBag\ParameterBagInterface::class)], ]); return $container; } private function createPriceWithStripe(): PriceAutomatic { $price = new PriceAutomatic(); $price->setType('esy-web'); $price->setTitle('Esy-Web'); $price->setPriceHt('100.00'); $price->setStripeId('price_abc123'); return $price; } private function createPriceWithoutStripe(): PriceAutomatic { $price = new PriceAutomatic(); $price->setType('esy-mail'); $price->setTitle('Esy-Mail'); $price->setPriceHt('50.00'); return $price; } public function testIndexWithMixedPrices(): void { $customerRepo = $this->createStub(CustomerRepository::class); $customerRepo->method('count')->willReturn(10); $revendeurRepo = $this->createStub(RevendeurRepository::class); $revendeurRepo->method('count')->willReturn(3); $priceRepo = $this->createStub(PriceAutomaticRepository::class); $priceRepo->method('findAll')->willReturn([ $this->createPriceWithStripe(), $this->createPriceWithoutStripe(), ]); $secretRepo = $this->createStub(StripeWebhookSecretRepository::class); $secretRepo->method('findAll')->willReturn([]); $controller = new SyncController(); $controller->setContainer($this->createContainer()); $contactRepo = $this->createStub(\Doctrine\ORM\EntityRepository::class); $contactRepo->method('count')->willReturn(0); $em = $this->createStub(\Doctrine\ORM\EntityManagerInterface::class); $em->method('getRepository')->willReturn($contactRepo); $meilisearch = $this->createStub(MeilisearchService::class); $response = $controller->index($customerRepo, $revendeurRepo, $priceRepo, $secretRepo, $em, $meilisearch); $this->assertSame(200, $response->getStatusCode()); } public function testSyncCustomersSuccess(): void { $customer = $this->createStub(Customer::class); $customerRepo = $this->createStub(CustomerRepository::class); $customerRepo->method('findAll')->willReturn([$customer]); $meilisearch = $this->createStub(MeilisearchService::class); $controller = new SyncController(); $controller->setContainer($this->createContainer()); $response = $controller->syncCustomers($customerRepo, $meilisearch); $this->assertSame(302, $response->getStatusCode()); } public function testSyncCustomersError(): void { $customerRepo = $this->createStub(CustomerRepository::class); $customerRepo->method('findAll')->willThrowException(new \RuntimeException('Connection refused')); $meilisearch = $this->createStub(MeilisearchService::class); $controller = new SyncController(); $controller->setContainer($this->createContainer()); $response = $controller->syncCustomers($customerRepo, $meilisearch); $this->assertSame(302, $response->getStatusCode()); } public function testSyncRevendeursSuccess(): void { $revendeur = $this->createStub(Revendeur::class); $revendeurRepo = $this->createStub(RevendeurRepository::class); $revendeurRepo->method('findAll')->willReturn([$revendeur]); $meilisearch = $this->createStub(MeilisearchService::class); $controller = new SyncController(); $controller->setContainer($this->createContainer()); $response = $controller->syncRevendeurs($revendeurRepo, $meilisearch); $this->assertSame(302, $response->getStatusCode()); } public function testSyncRevendeursError(): void { $revendeurRepo = $this->createStub(RevendeurRepository::class); $revendeurRepo->method('findAll')->willThrowException(new \RuntimeException('Timeout')); $meilisearch = $this->createStub(MeilisearchService::class); $controller = new SyncController(); $controller->setContainer($this->createContainer()); $response = $controller->syncRevendeurs($revendeurRepo, $meilisearch); $this->assertSame(302, $response->getStatusCode()); } public function testSyncPricesSuccess(): void { $price = $this->createPriceWithStripe(); $priceRepo = $this->createStub(PriceAutomaticRepository::class); $priceRepo->method('findAll')->willReturn([$price]); $meilisearch = $this->createStub(MeilisearchService::class); $controller = new SyncController(); $controller->setContainer($this->createContainer()); $response = $controller->syncPrices($priceRepo, $meilisearch); $this->assertSame(302, $response->getStatusCode()); } public function testSyncPricesError(): void { $priceRepo = $this->createStub(PriceAutomaticRepository::class); $priceRepo->method('findAll')->willThrowException(new \RuntimeException('Error')); $meilisearch = $this->createStub(MeilisearchService::class); $controller = new SyncController(); $controller->setContainer($this->createContainer()); $response = $controller->syncPrices($priceRepo, $meilisearch); $this->assertSame(302, $response->getStatusCode()); } public function testSyncStripeWebhooksEmptyUrl(): void { $webhookService = $this->createStub(StripeWebhookService::class); $secretRepo = $this->createStub(StripeWebhookSecretRepository::class); $em = $this->createStub(EntityManagerInterface::class); $controller = new SyncController(); $controller->setContainer($this->createContainer()); $response = $controller->syncStripeWebhooks($webhookService, $secretRepo, $em, ''); $this->assertSame(302, $response->getStatusCode()); } public function testSyncStripeWebhooksCreatedNew(): void { $webhookService = $this->createStub(StripeWebhookService::class); $webhookService->method('createAllWebhooks')->willReturn([ 'created' => [ ['type' => 'Main Light', 'id' => 'we_123', 'status' => 'created', 'secret' => 'whsec_abc'], ['type' => 'Main Instant', 'id' => 'we_456', 'status' => 'exists'], ], 'errors' => [], ]); $secretRepo = $this->createStub(StripeWebhookSecretRepository::class); $secretRepo->method('findByType')->willReturn(null); $em = $this->createStub(EntityManagerInterface::class); $controller = new SyncController(); $controller->setContainer($this->createContainer()); $response = $controller->syncStripeWebhooks($webhookService, $secretRepo, $em, 'https://crm.e-cosplay.fr'); $this->assertSame(302, $response->getStatusCode()); } public function testSyncStripeWebhooksUpdateExisting(): void { $existing = new StripeWebhookSecret(StripeWebhookSecret::TYPE_MAIN_LIGHT, 'old_secret', 'we_old'); $webhookService = $this->createStub(StripeWebhookService::class); $webhookService->method('createAllWebhooks')->willReturn([ 'created' => [ ['type' => 'Main Light', 'id' => 'we_new', 'status' => 'created', 'secret' => 'whsec_new'], ], 'errors' => ['Connect webhook failed'], ]); $secretRepo = $this->createStub(StripeWebhookSecretRepository::class); $secretRepo->method('findByType')->willReturn($existing); $em = $this->createStub(EntityManagerInterface::class); $controller = new SyncController(); $controller->setContainer($this->createContainer()); $response = $controller->syncStripeWebhooks($webhookService, $secretRepo, $em, 'https://crm.e-cosplay.fr/'); $this->assertSame(302, $response->getStatusCode()); $this->assertSame('whsec_new', $existing->getSecret()); $this->assertSame('we_new', $existing->getEndpointId()); } public function testSyncStripePricesNoErrors(): void { $stripePriceService = $this->createStub(StripePriceService::class); $stripePriceService->method('syncAll')->willReturn(['synced' => 5, 'errors' => []]); $controller = new SyncController(); $controller->setContainer($this->createContainer()); $response = $controller->syncStripePrices($stripePriceService); $this->assertSame(302, $response->getStatusCode()); } public function testSyncStripePricesWithErrors(): void { $stripePriceService = $this->createStub(StripePriceService::class); $stripePriceService->method('syncAll')->willReturn(['synced' => 3, 'errors' => ['Price X failed', 'Price Y failed']]); $controller = new SyncController(); $controller->setContainer($this->createContainer()); $response = $controller->syncStripePrices($stripePriceService); $this->assertSame(302, $response->getStatusCode()); } public function testSyncAllSuccess(): void { $customerRepo = $this->createStub(CustomerRepository::class); $customerRepo->method('findAll')->willReturn([$this->createStub(Customer::class)]); $revendeurRepo = $this->createStub(RevendeurRepository::class); $revendeurRepo->method('findAll')->willReturn([$this->createStub(Revendeur::class)]); $priceRepo = $this->createStub(PriceAutomaticRepository::class); $priceRepo->method('findAll')->willReturn([$this->createPriceWithStripe()]); $meilisearch = $this->createStub(MeilisearchService::class); $controller = new SyncController(); $controller->setContainer($this->createContainer()); $response = $controller->syncAll($customerRepo, $revendeurRepo, $priceRepo, $meilisearch); $this->assertSame(302, $response->getStatusCode()); } public function testSyncAllError(): void { $customerRepo = $this->createStub(CustomerRepository::class); $customerRepo->method('findAll')->willReturn([]); $revendeurRepo = $this->createStub(RevendeurRepository::class); $revendeurRepo->method('findAll')->willReturn([]); $priceRepo = $this->createStub(PriceAutomaticRepository::class); $priceRepo->method('findAll')->willReturn([]); $meilisearch = $this->createStub(MeilisearchService::class); $meilisearch->method('setupIndexes')->willThrowException(new \RuntimeException('Meilisearch down')); $controller = new SyncController(); $controller->setContainer($this->createContainer()); $response = $controller->syncAll($customerRepo, $revendeurRepo, $priceRepo, $meilisearch); $this->assertSame(302, $response->getStatusCode()); } private function createEntityRepo(array $items = []): \Doctrine\ORM\EntityRepository { $repo = $this->createStub(\Doctrine\ORM\EntityRepository::class); $repo->method('findAll')->willReturn($items); return $repo; } public function testSyncContactsSuccess(): void { $repo = $this->createEntityRepo([$this->createStub(\App\Entity\CustomerContact::class)]); $em = $this->createStub(EntityManagerInterface::class); $em->method('getRepository')->willReturn($repo); $meilisearch = $this->createStub(MeilisearchService::class); $controller = new SyncController(); $controller->setContainer($this->createContainer()); $response = $controller->syncContacts($em, $meilisearch); $this->assertSame(302, $response->getStatusCode()); } public function testSyncContactsError(): void { $repo = $this->createEntityRepo([]); $em = $this->createStub(EntityManagerInterface::class); $em->method('getRepository')->willReturn($repo); $meilisearch = $this->createStub(MeilisearchService::class); $meilisearch->method('setupIndexes')->willThrowException(new \RuntimeException('down')); $controller = new SyncController(); $controller->setContainer($this->createContainer()); $response = $controller->syncContacts($em, $meilisearch); $this->assertSame(302, $response->getStatusCode()); } public function testSyncDomainsSuccess(): void { $repo = $this->createEntityRepo([$this->createStub(\App\Entity\Domain::class)]); $em = $this->createStub(EntityManagerInterface::class); $em->method('getRepository')->willReturn($repo); $meilisearch = $this->createStub(MeilisearchService::class); $controller = new SyncController(); $controller->setContainer($this->createContainer()); $response = $controller->syncDomains($em, $meilisearch); $this->assertSame(302, $response->getStatusCode()); } public function testSyncDomainsError(): void { $repo = $this->createEntityRepo([]); $em = $this->createStub(EntityManagerInterface::class); $em->method('getRepository')->willReturn($repo); $meilisearch = $this->createStub(MeilisearchService::class); $meilisearch->method('setupIndexes')->willThrowException(new \RuntimeException('down')); $controller = new SyncController(); $controller->setContainer($this->createContainer()); $response = $controller->syncDomains($em, $meilisearch); $this->assertSame(302, $response->getStatusCode()); } public function testSyncWebsitesSuccess(): void { $repo = $this->createEntityRepo([$this->createStub(\App\Entity\Website::class)]); $em = $this->createStub(EntityManagerInterface::class); $em->method('getRepository')->willReturn($repo); $meilisearch = $this->createStub(MeilisearchService::class); $controller = new SyncController(); $controller->setContainer($this->createContainer()); $response = $controller->syncWebsites($em, $meilisearch); $this->assertSame(302, $response->getStatusCode()); } public function testSyncWebsitesError(): void { $repo = $this->createEntityRepo([]); $em = $this->createStub(EntityManagerInterface::class); $em->method('getRepository')->willReturn($repo); $meilisearch = $this->createStub(MeilisearchService::class); $meilisearch->method('setupIndexes')->willThrowException(new \RuntimeException('down')); $controller = new SyncController(); $controller->setContainer($this->createContainer()); $response = $controller->syncWebsites($em, $meilisearch); $this->assertSame(302, $response->getStatusCode()); } public function testSyncDevisSuccess(): void { $repo = $this->createEntityRepo([$this->createStub(\App\Entity\Devis::class)]); $em = $this->createStub(EntityManagerInterface::class); $em->method('getRepository')->willReturn($repo); $meilisearch = $this->createStub(MeilisearchService::class); $controller = new SyncController(); $controller->setContainer($this->createContainer()); $response = $controller->syncDevis($em, $meilisearch); $this->assertSame(302, $response->getStatusCode()); } public function testSyncDevisError(): void { $repo = $this->createEntityRepo([]); $em = $this->createStub(EntityManagerInterface::class); $em->method('getRepository')->willReturn($repo); $meilisearch = $this->createStub(MeilisearchService::class); $meilisearch->method('setupIndexes')->willThrowException(new \RuntimeException('down')); $controller = new SyncController(); $controller->setContainer($this->createContainer()); $response = $controller->syncDevis($em, $meilisearch); $this->assertSame(302, $response->getStatusCode()); } public function testSyncAdvertsSuccess(): void { $repo = $this->createEntityRepo([$this->createStub(\App\Entity\Advert::class)]); $em = $this->createStub(EntityManagerInterface::class); $em->method('getRepository')->willReturn($repo); $meilisearch = $this->createStub(MeilisearchService::class); $controller = new SyncController(); $controller->setContainer($this->createContainer()); $response = $controller->syncAdverts($em, $meilisearch); $this->assertSame(302, $response->getStatusCode()); } public function testSyncAdvertsError(): void { $repo = $this->createEntityRepo([]); $em = $this->createStub(EntityManagerInterface::class); $em->method('getRepository')->willReturn($repo); $meilisearch = $this->createStub(MeilisearchService::class); $meilisearch->method('setupIndexes')->willThrowException(new \RuntimeException('down')); $controller = new SyncController(); $controller->setContainer($this->createContainer()); $response = $controller->syncAdverts($em, $meilisearch); $this->assertSame(302, $response->getStatusCode()); } public function testSyncFacturesSuccess(): void { $repo = $this->createEntityRepo([$this->createStub(\App\Entity\Facture::class)]); $em = $this->createStub(EntityManagerInterface::class); $em->method('getRepository')->willReturn($repo); $meilisearch = $this->createStub(MeilisearchService::class); $controller = new SyncController(); $controller->setContainer($this->createContainer()); $response = $controller->syncFactures($em, $meilisearch); $this->assertSame(302, $response->getStatusCode()); } public function testSyncFacturesError(): void { $repo = $this->createEntityRepo([]); $em = $this->createStub(EntityManagerInterface::class); $em->method('getRepository')->willReturn($repo); $meilisearch = $this->createStub(MeilisearchService::class); $meilisearch->method('setupIndexes')->willThrowException(new \RuntimeException('down')); $controller = new SyncController(); $controller->setContainer($this->createContainer()); $response = $controller->syncFactures($em, $meilisearch); $this->assertSame(302, $response->getStatusCode()); } public function testPurgeIndexesRedirects(): void { $meilisearch = $this->createStub(MeilisearchService::class); $controller = new SyncController(); $controller->setContainer($this->createContainer()); $response = $controller->purgeIndexes($meilisearch); $this->assertSame(302, $response->getStatusCode()); } }