Spaces:
No application file
No application file
| namespace Mautic\WebhookBundle\Tests\Model; | |
| use Doctrine\ORM\EntityManager; | |
| use GuzzleHttp\Psr7\Response; | |
| use JMS\Serializer\SerializerInterface; | |
| use Mautic\CoreBundle\Helper\CoreParametersHelper; | |
| use Mautic\CoreBundle\Helper\UserHelper; | |
| use Mautic\CoreBundle\Security\Permissions\CorePermissions; | |
| use Mautic\CoreBundle\Translation\Translator; | |
| use Mautic\WebhookBundle\Entity\Event; | |
| use Mautic\WebhookBundle\Entity\Log; | |
| use Mautic\WebhookBundle\Entity\LogRepository; | |
| use Mautic\WebhookBundle\Entity\Webhook; | |
| use Mautic\WebhookBundle\Entity\WebhookQueue; | |
| use Mautic\WebhookBundle\Entity\WebhookQueueRepository; | |
| use Mautic\WebhookBundle\Entity\WebhookRepository; | |
| use Mautic\WebhookBundle\Http\Client; | |
| use Mautic\WebhookBundle\Model\WebhookModel; | |
| use PHPUnit\Framework\MockObject\MockObject; | |
| use PHPUnit\Framework\TestCase; | |
| use Psr\Log\LoggerInterface; | |
| use Symfony\Component\EventDispatcher\EventDispatcher; | |
| use Symfony\Component\EventDispatcher\EventDispatcherInterface; | |
| use Symfony\Component\Routing\Generator\UrlGeneratorInterface; | |
| class WebhookModelTest extends TestCase | |
| { | |
| /** | |
| * @var MockObject&CoreParametersHelper | |
| */ | |
| private MockObject $parametersHelperMock; | |
| /** | |
| * @var MockObject&SerializerInterface | |
| */ | |
| private MockObject $serializerMock; | |
| /** | |
| * @var MockObject&EntityManager | |
| */ | |
| private MockObject $entityManagerMock; | |
| /** | |
| * @var MockObject&WebhookRepository | |
| */ | |
| private MockObject $webhookRepository; | |
| /** | |
| * @var MockObject&WebhookQueueRepository | |
| */ | |
| private $webhookQueueRepository; | |
| /** | |
| * @var MockObject&UserHelper | |
| */ | |
| private MockObject $userHelper; | |
| /** | |
| * @var MockObject&EventDispatcherInterface | |
| */ | |
| private MockObject $eventDispatcherMock; | |
| private WebhookModel $model; | |
| /** | |
| * @var MockObject&Client | |
| */ | |
| private MockObject $httpClientMock; | |
| protected function setUp(): void | |
| { | |
| $this->parametersHelperMock = $this->createMock(CoreParametersHelper::class); | |
| $this->serializerMock = $this->createMock(SerializerInterface::class); | |
| $this->entityManagerMock = $this->createMock(EntityManager::class); | |
| $this->userHelper = $this->createMock(UserHelper::class); | |
| $this->webhookRepository = $this->createMock(WebhookRepository::class); | |
| $this->webhookQueueRepository = $this->createMock(WebhookQueueRepository::class); | |
| $this->httpClientMock = $this->createMock(Client::class); | |
| $this->eventDispatcherMock = $this->createMock(EventDispatcher::class); | |
| $this->model = $this->initModel(); | |
| } | |
| public function testSaveEntity(): void | |
| { | |
| $entity = new Webhook(); | |
| // The secret hash is null at first. | |
| $this->assertNull($entity->getSecret()); | |
| $this->entityManagerMock->expects($this->once()) | |
| ->method('getRepository') | |
| ->with(Webhook::class) | |
| ->willReturn($this->webhookRepository); | |
| $this->webhookRepository->expects($this->once()) | |
| ->method('saveEntity') | |
| ->with($this->callback(function (Webhook $entity) { | |
| // The secret hash is not empty on save. | |
| $this->assertNotEmpty($entity->getSecret()); | |
| return true; | |
| })); | |
| $this->model->saveEntity($entity); | |
| } | |
| public function testGetEventsOrderbyDirWhenSetInWebhook(): void | |
| { | |
| $webhook = (new Webhook())->setEventsOrderbyDir('DESC'); | |
| $this->assertEquals('DESC', $this->model->getEventsOrderbyDir($webhook)); | |
| } | |
| public function testGetEventsOrderbyDirWhenNotSetInWebhook(): void | |
| { | |
| $this->parametersHelperMock->method('get')->willReturn('DESC'); | |
| $this->assertEquals('DESC', $this->initModel()->getEventsOrderbyDir()); | |
| } | |
| public function testGetEventsOrderbyDirWhenWebhookNotProvided(): void | |
| { | |
| $this->parametersHelperMock->method('get')->willReturn('DESC'); | |
| $this->assertEquals('DESC', $this->initModel()->getEventsOrderbyDir()); | |
| } | |
| public function testGetWebhookPayloadForPayloadInWebhook(): void | |
| { | |
| $payload = ['the' => 'payload']; | |
| $webhook = new Webhook(); | |
| $webhook->setPayload($payload); | |
| $this->assertEquals($payload, $this->model->getWebhookPayload($webhook)); | |
| } | |
| public function testGetWebhookPayloadForQueueLoadedFromDatabase(): void | |
| { | |
| $queueMock = $this->createMock(WebhookQueue::class); | |
| $webhook = new Webhook(); | |
| $event = new Event(); | |
| $event->setEventType('leads'); | |
| $queueMock->method('getPayload')->willReturn('{"the": "payload"}'); | |
| $queueMock->method('getEvent')->willReturn($event); | |
| $queueMock->method('getDateAdded')->willReturn(new \DateTime('2018-04-10T15:04:57+00:00')); | |
| $queueMock->method('getId')->willReturn(12); | |
| $queueRepositoryMock = $this->createMock(WebhookQueueRepository::class); | |
| $this->parametersHelperMock->method('get') | |
| ->willReturnCallback(function ($param) { | |
| if ('queue_mode' === $param) { | |
| return WebhookModel::COMMAND_PROCESS; | |
| } | |
| return null; | |
| }); | |
| $this->entityManagerMock->expects($this->once()) | |
| ->method('getRepository') | |
| ->with(WebhookQueue::class) | |
| ->willReturn($queueRepositoryMock); | |
| $this->entityManagerMock->expects($this->once()) | |
| ->method('detach') | |
| ->with($queueMock); | |
| $queueRepositoryMock->expects($this->once()) | |
| ->method('getEntities') | |
| ->willReturn([$queueMock]); | |
| $expectedPayload = [ | |
| 'leads' => [ | |
| [ | |
| 'the' => 'payload', | |
| 'timestamp' => '2018-04-10T15:04:57+00:00', | |
| ], | |
| ], | |
| ]; | |
| $this->assertEquals($expectedPayload, $this->initModel()->getWebhookPayload($webhook)); | |
| } | |
| public function testGetWebhookPayloadForQueueInWebhook(): void | |
| { | |
| $queue = new WebhookQueue(); | |
| $webhook = new Webhook(); | |
| $event = new Event(); | |
| $event->setEventType('leads'); | |
| $queue->setPayload('{"the": "payload"}'); | |
| $queue->setEvent($event); | |
| $queue->setDateAdded(new \DateTime('2018-04-10T15:04:57+00:00')); | |
| $this->parametersHelperMock->method('get') | |
| ->willReturnCallback(function ($param) { | |
| if ('queue_mode' === $param) { | |
| return WebhookModel::IMMEDIATE_PROCESS; | |
| } | |
| return null; | |
| }); | |
| $expectedPayload = [ | |
| 'leads' => [ | |
| [ | |
| 'the' => 'payload', | |
| 'timestamp' => '2018-04-10T15:04:57+00:00', | |
| ], | |
| ], | |
| ]; | |
| $this->assertEquals($expectedPayload, $this->initModel()->getWebhookPayload($webhook, $queue)); | |
| } | |
| public function testProcessWebhook(): void | |
| { | |
| $webhook = new class() extends Webhook { | |
| public function getId(): ?int | |
| { | |
| return 1; | |
| } | |
| }; | |
| $webhook->setWebhookUrl('test-webhook.com'); | |
| $event = new Event(); | |
| $event->setEventType('mautic.email_on_send'); | |
| $queue = new class() extends WebhookQueue { | |
| public function getId(): int | |
| { | |
| return 1; | |
| } | |
| }; | |
| $queue->setPayload('{"payload": "some data"}'); | |
| $queue->setEvent($event); | |
| $queue->setDateAdded(new \DateTime('2021-04-01T16:00:00+00:00')); | |
| $webhookQueueRepoMock = $this->createMock(WebhookQueueRepository::class); | |
| $webhookLogRepoMock = $this->createMock(LogRepository::class); | |
| $webhookRepoMock = $this->createMock(WebhookRepository::class); | |
| $this->entityManagerMock->method('getRepository') | |
| ->willReturnMap([ | |
| [WebhookQueue::class, $webhookQueueRepoMock], | |
| [Log::class, $webhookLogRepoMock], | |
| [Webhook::class, $webhookRepoMock], | |
| ]); | |
| $webhookQueueRepoMock | |
| ->method('deleteQueuesById') | |
| ->with([1]); | |
| $responsePayload = [ | |
| 'mautic.email_on_send' => [ | |
| [ | |
| 'payload' => 'some data', | |
| 'timestamp' => '2021-04-01T16:00:00+00:00', | |
| ], | |
| ], | |
| ]; | |
| $this->httpClientMock | |
| ->method('post') | |
| ->with('test-webhook.com', $responsePayload) | |
| ->willReturn(new Response(200, [], 'Success')); | |
| self::assertTrue($this->model->processWebhook($webhook, $queue)); | |
| } | |
| public function testMinAndMaxQueueIdWhenNoneIsSet(): void | |
| { | |
| $webhook = new class() extends Webhook { | |
| public function getId(): ?int | |
| { | |
| return 1; | |
| } | |
| }; | |
| $webhook->setEventsOrderbyDir('ASC'); | |
| $this->entityManagerMock->expects($this->once()) | |
| ->method('getRepository') | |
| ->with(WebhookQueue::class) | |
| ->willReturn($this->webhookQueueRepository); | |
| $this->webhookQueueRepository->method('getTableAlias')->willReturn('w'); | |
| $this->webhookQueueRepository->expects($this->once()) | |
| ->method('getEntities') | |
| ->with( | |
| [ | |
| 'filter' => [ | |
| 'force' => [ | |
| [ | |
| 'column' => 'IDENTITY(w.webhook)', | |
| 'expr' => 'eq', | |
| 'value' => 1, | |
| ], | |
| ], | |
| ], | |
| 'limit' => 0, | |
| 'iterable_mode' => true, | |
| 'start' => 0, | |
| 'orderBy' => 'w.id', | |
| 'orderByDir' => 'ASC', | |
| ] | |
| ); | |
| $this->initModel()->getWebhookQueues($webhook); | |
| } | |
| public function testMinAndMaxQueueIdWhenBothSet(): void | |
| { | |
| $webhook = new class() extends Webhook { | |
| public function getId(): ?int | |
| { | |
| return 1; | |
| } | |
| }; | |
| $webhook->setEventsOrderbyDir('ASC'); | |
| $this->entityManagerMock->expects($this->once()) | |
| ->method('getRepository') | |
| ->with(WebhookQueue::class) | |
| ->willReturn($this->webhookQueueRepository); | |
| $this->webhookQueueRepository->method('getTableAlias')->willReturn('w'); | |
| $this->webhookQueueRepository->expects($this->once()) | |
| ->method('getEntities') | |
| ->with( | |
| [ | |
| 'filter' => [ | |
| 'force' => [ | |
| [ | |
| 'column' => 'IDENTITY(w.webhook)', | |
| 'expr' => 'eq', | |
| 'value' => 1, | |
| ], | |
| [ | |
| 'column' => 'w.id', | |
| 'expr' => 'gte', | |
| 'value' => 20, | |
| ], | |
| [ | |
| 'column' => 'w.id', | |
| 'expr' => 'lte', | |
| 'value' => 30, | |
| ], | |
| ], | |
| ], | |
| 'iterable_mode' => true, | |
| 'orderBy' => 'w.id', | |
| 'orderByDir' => 'ASC', | |
| ] | |
| ); | |
| $model = $this->initModel(); | |
| $model->setMinQueueId(20); | |
| $model->setMaxQueueId(30); | |
| $model->getWebhookQueues($webhook); | |
| } | |
| private function initModel(): WebhookModel | |
| { | |
| $model = new WebhookModel( | |
| $this->parametersHelperMock, | |
| $this->serializerMock, | |
| $this->httpClientMock, | |
| $this->entityManagerMock, | |
| $this->createMock(CorePermissions::class), | |
| $this->eventDispatcherMock, | |
| $this->createMock(UrlGeneratorInterface::class), | |
| $this->createMock(Translator::class), | |
| $this->userHelper, | |
| $this->createMock(LoggerInterface::class) | |
| ); | |
| return $model; | |
| } | |
| } | |