285 lines
10 KiB
PHP
285 lines
10 KiB
PHP
<?php
|
|
|
|
/**
|
|
* This program is free software; you can redistribute it and/or
|
|
* modify it under the terms of the GNU General Public License
|
|
* as published by the Free Software Foundation; under version 2
|
|
* of the License (non-upgradable).
|
|
*
|
|
* This program is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License
|
|
* along with this program; if not, write to the Free Software
|
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
|
*
|
|
* Copyright (c) 2019 (original work) Open Assessment Technologies SA;
|
|
*/
|
|
|
|
namespace oat\tao\test\unit\webhooks;
|
|
|
|
use oat\generis\test\TestCase;
|
|
use oat\oatbox\event\Event;
|
|
use oat\oatbox\event\EventManager;
|
|
use oat\tao\model\exceptions\WebhookConfigMissingException;
|
|
use oat\tao\model\webhooks\configEntity\WebhookInterface;
|
|
use oat\tao\model\webhooks\WebhookEventsService;
|
|
use oat\tao\model\webhooks\WebhookRegistryInterface;
|
|
use oat\tao\model\webhooks\WebhookSerializableEventInterface;
|
|
use oat\tao\model\webhooks\task\WebhookTaskParams;
|
|
use oat\tao\model\webhooks\WebhookTaskServiceInterface;
|
|
use oat\generis\test\MockObject;
|
|
use Psr\Log\LoggerInterface;
|
|
|
|
class WebhookEventsServiceTest extends TestCase
|
|
{
|
|
/** @var EventManager|MockObject */
|
|
private $eventManagerMock;
|
|
|
|
/** @var WebhookRegistryInterface|MockObject */
|
|
private $whConfigRegistryMock;
|
|
|
|
/** @var WebhookTaskServiceInterface|MockObject */
|
|
private $whTaskServiceMock;
|
|
|
|
/** @var string[] */
|
|
private $whRegistryData = [];
|
|
|
|
/** @var WebhookInterface|MockObject */
|
|
private $webhookConfigMock;
|
|
|
|
protected function setUp(): void
|
|
{
|
|
$this->eventManagerMock = $this->createMock(EventManager::class);
|
|
|
|
$this->whConfigRegistryMock = $this->createMock(WebhookRegistryInterface::class);
|
|
|
|
$this->webhookConfigMock = $this->createMock(WebhookInterface::class);
|
|
|
|
$this->whConfigRegistryMock
|
|
->method('getWebhookConfigIds')
|
|
->willReturnCallback(
|
|
function ($eventName) {
|
|
return isset($this->whRegistryData[$eventName])
|
|
? $this->whRegistryData[$eventName]
|
|
: [];
|
|
}
|
|
);
|
|
|
|
$this->whTaskServiceMock = $this->createMock(WebhookTaskServiceInterface::class);
|
|
}
|
|
|
|
public function testHandleEventMissingWebhookConfig()
|
|
{
|
|
$eventName = 'TestEvent';
|
|
|
|
$service = new WebhookEventsService([
|
|
WebhookEventsService::OPTION_SUPPORTED_EVENTS => [
|
|
$eventName => true
|
|
]
|
|
]);
|
|
|
|
$service->setServiceLocator($this->getServiceLocatorMock([
|
|
WebhookRegistryInterface::SERVICE_ID => $this->whConfigRegistryMock,
|
|
WebhookTaskServiceInterface::SERVICE_ID => $this->whTaskServiceMock
|
|
]));
|
|
|
|
$this->whRegistryData = [
|
|
$eventName => ['wh1', 'wh2']
|
|
];
|
|
|
|
$this->whConfigRegistryMock->method('getWebhookConfigIds')->willReturn(['wh1', 'wh2']);
|
|
$this->whConfigRegistryMock->method('getWebhookConfig')->willReturn(null);
|
|
|
|
$this->expectException(WebhookConfigMissingException::class);
|
|
|
|
/** @var Event|MockObject $eventMock */
|
|
$eventMock = $this->createMock(WebhookSerializableEventInterface::class);
|
|
$eventMock->method('getName')->willReturn($eventName);
|
|
$service->handleEvent($eventMock);
|
|
}
|
|
|
|
public function testRegisterEvent()
|
|
{
|
|
$eventName = 'TestEvent';
|
|
$this->eventManagerMock->expects($this->once())
|
|
->method('attach')
|
|
->with($eventName, [WebhookEventsService::SERVICE_ID, 'handleEvent']);
|
|
|
|
$service = new WebhookEventsService([
|
|
WebhookEventsService::OPTION_SUPPORTED_EVENTS => []
|
|
]);
|
|
|
|
$service->setServiceLocator($this->getServiceLocatorMock([
|
|
EventManager::SERVICE_ID => $this->eventManagerMock
|
|
]));
|
|
|
|
$this->assertFalse($service->isEventRegistered($eventName));
|
|
$service->registerEvent($eventName);
|
|
$this->assertTrue($service->isEventRegistered($eventName));
|
|
}
|
|
|
|
public function testUnregisterEvent()
|
|
{
|
|
$eventName = 'TestEvent';
|
|
$this->eventManagerMock->expects($this->once())
|
|
->method('detach')
|
|
->with($eventName, [WebhookEventsService::SERVICE_ID, 'handleEvent']);
|
|
|
|
$service = new WebhookEventsService([
|
|
WebhookEventsService::OPTION_SUPPORTED_EVENTS => [
|
|
$eventName => true
|
|
]
|
|
]);
|
|
|
|
$service->setServiceLocator($this->getServiceLocatorMock([
|
|
EventManager::SERVICE_ID => $this->eventManagerMock
|
|
]));
|
|
|
|
$this->assertTrue($service->isEventRegistered($eventName));
|
|
$service->unregisterEvent($eventName);
|
|
$this->assertFalse($service->isEventRegistered($eventName));
|
|
}
|
|
|
|
public function testHandleEventPositive()
|
|
{
|
|
$eventName = 'TestEvent';
|
|
$whEventName = 'WhTestEvent';
|
|
$extraPayload = [
|
|
'extra' => 'data'
|
|
];
|
|
|
|
/** @var WebhookSerializableEventInterface|MockObject $event */
|
|
$event = $this->createMock(WebhookSerializableEventInterface::class);
|
|
$event->method('getName')->willReturn($eventName);
|
|
$event->method('getWebhookEventName')->willReturn($whEventName);
|
|
$event->method('serializeForWebhook')->willReturn(['d' => 2]);
|
|
|
|
$this->whRegistryData = [
|
|
$eventName => ['wh1', 'wh2']
|
|
];
|
|
|
|
$service = new WebhookEventsService([
|
|
WebhookEventsService::OPTION_SUPPORTED_EVENTS => [
|
|
$eventName => true
|
|
]
|
|
]);
|
|
|
|
$service->setServiceLocator($this->getServiceLocatorMock([
|
|
WebhookRegistryInterface::SERVICE_ID => $this->whConfigRegistryMock,
|
|
WebhookTaskServiceInterface::SERVICE_ID => $this->whTaskServiceMock
|
|
]));
|
|
|
|
$passedParams = [];
|
|
$this->whTaskServiceMock
|
|
->expects($this->exactly(2))
|
|
->method('createTask')
|
|
->willReturnCallback(static function (WebhookTaskParams $whParams) use (&$passedParams) {
|
|
$passedParams[] = $whParams;
|
|
});
|
|
|
|
$this->webhookConfigMock->method('getMaxRetries')->willReturn(5);
|
|
$this->webhookConfigMock->method('getExtraPayload')->willReturn($extraPayload);
|
|
$this->whConfigRegistryMock->method('getWebhookConfig')->willReturn($this->webhookConfigMock);
|
|
|
|
$timestampStart = time();
|
|
$service->handleEvent($event);
|
|
$timestampEnd = time();
|
|
|
|
foreach (['wh1', 'wh2'] as $index => $whId) {
|
|
$whParams = $passedParams[$index];
|
|
$this->assertSame($whParams[WebhookTaskParams::EVENT_NAME], $whEventName);
|
|
$this->assertSame($whParams[WebhookTaskParams::WEBHOOK_CONFIG_ID], $whId);
|
|
$this->assertSame(
|
|
$whParams[WebhookTaskParams::EVENT_DATA],
|
|
array_merge(
|
|
$extraPayload,
|
|
[
|
|
'd' => 2
|
|
]
|
|
)
|
|
);
|
|
$this->assertGreaterThanOrEqual($whParams[WebhookTaskParams::TRIGGERED_TIMESTAMP], $timestampStart);
|
|
$this->assertLessThanOrEqual($whParams[WebhookTaskParams::TRIGGERED_TIMESTAMP], $timestampEnd);
|
|
$this->assertRegExp('/^([a-z0-9]{32})$/', $whParams[WebhookTaskParams::EVENT_ID]);
|
|
}
|
|
}
|
|
|
|
public function testHandleEventNotSupportedEvent()
|
|
{
|
|
/** @var WebhookSerializableEventInterface|MockObject $event */
|
|
$event = $this->createMock(WebhookSerializableEventInterface::class);
|
|
$event->method('getName')->willReturn('TestEvent');
|
|
$event->method('getWebhookEventName')->willReturn('WhTestEvent');
|
|
$event->expects($this->never())->method('serializeForWebhook');
|
|
|
|
$service = new WebhookEventsService([
|
|
WebhookEventsService::OPTION_SUPPORTED_EVENTS => [
|
|
'AnotherEvent' => true
|
|
]
|
|
]);
|
|
|
|
/** @var LoggerInterface|MockObject $logger */
|
|
$logger = $this->createMock(LoggerInterface::class);
|
|
$logger->expects($this->atLeast(1))->method('error');
|
|
$service->setLogger($logger);
|
|
|
|
$service->handleEvent($event);
|
|
}
|
|
|
|
public function testHandleEventNotSerializable()
|
|
{
|
|
/** @var Event|MockObject $event */
|
|
/** @noinspection PhpParamsInspection */
|
|
$event = $this->createMock(Event::class);
|
|
$event->method('getName')->willReturn('TestEvent');
|
|
|
|
$service = new WebhookEventsService([
|
|
WebhookEventsService::OPTION_SUPPORTED_EVENTS => [
|
|
'TestEvent' => true
|
|
]
|
|
]);
|
|
|
|
$service->setServiceLocator($this->getServiceLocatorMock([
|
|
WebhookTaskServiceInterface::SERVICE_ID => $this->whTaskServiceMock,
|
|
]));
|
|
|
|
/** @var LoggerInterface|MockObject $logger */
|
|
$logger = $this->createMock(LoggerInterface::class);
|
|
$logger->expects($this->atLeast(1))->method('error');
|
|
$service->setLogger($logger);
|
|
|
|
$this->whConfigRegistryMock->expects($this->never())->method('getWebhookConfigIds');
|
|
|
|
$service->handleEvent($event);
|
|
}
|
|
|
|
public function testHandleEventNoWebhooks()
|
|
{
|
|
$eventName = 'TestEvent';
|
|
|
|
/** @var WebhookSerializableEventInterface|MockObject $event */
|
|
$event = $this->createMock(WebhookSerializableEventInterface::class);
|
|
$event->method('getName')->willReturn($eventName);
|
|
$event->expects($this->never())->method('serializeForWebhook');
|
|
|
|
$this->whRegistryData = [
|
|
$eventName => []
|
|
];
|
|
|
|
$service = new WebhookEventsService([
|
|
WebhookEventsService::OPTION_SUPPORTED_EVENTS => [
|
|
$eventName => true
|
|
]
|
|
]);
|
|
|
|
$service->setServiceLocator($this->getServiceLocatorMock([
|
|
WebhookRegistryInterface::SERVICE_ID => $this->whConfigRegistryMock
|
|
]));
|
|
|
|
$service->handleEvent($event);
|
|
}
|
|
}
|