From 2814efc95a699ce2eec9b9d44d0b3c60d953564b Mon Sep 17 00:00:00 2001 From: Lorenzo Ruozzi Date: Tue, 27 Aug 2024 09:33:41 +0200 Subject: [PATCH] Check for duplicated contact email if creation fails due to validation (#86) --- .../Contact/ContactCreateHandlerSpec.php | 23 +++++++++++++++++++ .../Contact/ContactCreateHandler.php | 18 +++++++++++++-- .../Contact/ContactCreateHandlerTest.php | 1 - 3 files changed, 39 insertions(+), 3 deletions(-) diff --git a/spec/MessageHandler/Contact/ContactCreateHandlerSpec.php b/spec/MessageHandler/Contact/ContactCreateHandlerSpec.php index f6868d4..87f872a 100644 --- a/spec/MessageHandler/Contact/ContactCreateHandlerSpec.php +++ b/spec/MessageHandler/Contact/ContactCreateHandlerSpec.php @@ -4,6 +4,7 @@ namespace spec\Webgriffe\SyliusActiveCampaignPlugin\MessageHandler\Contact; +use Symfony\Component\HttpKernel\Exception\UnprocessableEntityHttpException; use Tests\Webgriffe\SyliusActiveCampaignPlugin\App\Entity\Customer\CustomerInterface; use InvalidArgumentException; use PhpSpec\ObjectBehavior; @@ -16,6 +17,7 @@ use Webgriffe\SyliusActiveCampaignPlugin\Model\ActiveCampaign\ContactInterface; use Webgriffe\SyliusActiveCampaignPlugin\Model\ActiveCampaignAwareInterface; use Webgriffe\SyliusActiveCampaignPlugin\ValueObject\Response\CreateResourceResponseInterface; +use Webgriffe\SyliusActiveCampaignPlugin\ValueObject\Response\ListResourcesResponseInterface; use Webgriffe\SyliusActiveCampaignPlugin\ValueObject\Response\ResourceResponseInterface; class ContactCreateHandlerSpec extends ObjectBehavior @@ -30,6 +32,7 @@ public function let( $contactMapper->mapFromCustomer($customer)->willReturn($contact); $customer->getActiveCampaignId()->willReturn(null); + $customer->getEmail()->willReturn('email'); $customerRepository->find(12)->willReturn($customer); @@ -91,4 +94,24 @@ public function it_creates_contact_on_active_campaign( $this->__invoke(new ContactCreate(12)); } + + public function it_search_for_contact_id_if_validation_fails_due_to_duplicated_email( + ContactInterface $contact, + ActiveCampaignResourceClientInterface $activeCampaignContactClient, + CustomerInterface $customer, + CustomerRepositoryInterface $customerRepository, + ResourceResponseInterface $contactResponse, + ListResourcesResponseInterface $searchContactsForEmail, + ): void { + $contactResponse->getId()->willReturn(3423); + $activeCampaignContactClient->create($contact)->shouldBeCalledOnce()->willThrow(new UnprocessableEntityHttpException()); + $activeCampaignContactClient->list(['email' => 'email'])->shouldBeCalledOnce()->willReturn($searchContactsForEmail); + + $searchContactsForEmail->getResourceResponseLists()->willReturn([$contactResponse]); + + $customer->setActiveCampaignId(3423)->shouldBeCalledOnce(); + $customerRepository->add($customer)->shouldBeCalledOnce(); + + $this->__invoke(new ContactCreate(12)); + } } diff --git a/src/MessageHandler/Contact/ContactCreateHandler.php b/src/MessageHandler/Contact/ContactCreateHandler.php index f57b3b4..245793a 100644 --- a/src/MessageHandler/Contact/ContactCreateHandler.php +++ b/src/MessageHandler/Contact/ContactCreateHandler.php @@ -7,10 +7,12 @@ use InvalidArgumentException; use Sylius\Component\Core\Model\CustomerInterface; use Sylius\Component\Core\Repository\CustomerRepositoryInterface; +use Symfony\Component\HttpKernel\Exception\UnprocessableEntityHttpException; use Webgriffe\SyliusActiveCampaignPlugin\Client\ActiveCampaignResourceClientInterface; use Webgriffe\SyliusActiveCampaignPlugin\Mapper\ContactMapperInterface; use Webgriffe\SyliusActiveCampaignPlugin\Message\Contact\ContactCreate; use Webgriffe\SyliusActiveCampaignPlugin\Model\ActiveCampaignAwareInterface; +use Webgriffe\SyliusActiveCampaignPlugin\ValueObject\Response\Contact\ContactResponse; final class ContactCreateHandler { @@ -37,8 +39,20 @@ public function __invoke(ContactCreate $message): void if ($activeCampaignId !== null) { throw new InvalidArgumentException(sprintf('The Customer with id "%s" has been already created on ActiveCampaign on the contact with id "%s"', $customerId, $activeCampaignId)); } - $createContactResponse = $this->activeCampaignContactClient->create($this->contactMapper->mapFromCustomer($customer)); - $customer->setActiveCampaignId($createContactResponse->getResourceResponse()->getId()); + try { + $createContactResponse = $this->activeCampaignContactClient->create($this->contactMapper->mapFromCustomer($customer)); + $activeCampaignContactId = $createContactResponse->getResourceResponse()->getId(); + } catch (UnprocessableEntityHttpException $e) { + // If validation fails try to check if contact already exists + $searchContactsForEmail = $this->activeCampaignContactClient->list(['email' => (string) $customer->getEmail()])->getResourceResponseLists(); + if (count($searchContactsForEmail) < 1) { + throw $e; + } + /** @var ContactResponse $contact */ + $contact = reset($searchContactsForEmail); + $activeCampaignContactId = $contact->getId(); + } + $customer->setActiveCampaignId($activeCampaignContactId); $this->customerRepository->add($customer); } } diff --git a/tests/Integration/MessageHandler/Contact/ContactCreateHandlerTest.php b/tests/Integration/MessageHandler/Contact/ContactCreateHandlerTest.php index 70af0db..8deea5d 100644 --- a/tests/Integration/MessageHandler/Contact/ContactCreateHandlerTest.php +++ b/tests/Integration/MessageHandler/Contact/ContactCreateHandlerTest.php @@ -34,7 +34,6 @@ protected function setUp(): void self::getContainer()->get('webgriffe.sylius_active_campaign_plugin.mapper.contact'), self::getContainer()->get('webgriffe.sylius_active_campaign_plugin.client_stub.active_campaign.contact'), $this->customerRepository, - self::getContainer()->get('messenger.default_bus'), ); }