Skip to content

Commit

Permalink
test: add more webhook tests
Browse files Browse the repository at this point in the history
  • Loading branch information
EdieLemoine committed Nov 15, 2024
1 parent 6e05b9c commit f1b666a
Show file tree
Hide file tree
Showing 2 changed files with 91 additions and 24 deletions.
12 changes: 11 additions & 1 deletion tests/Bootstrap/MockLogger.php
Original file line number Diff line number Diff line change
Expand Up @@ -80,10 +80,20 @@ public function getLogFiles(): array
}

/**
* @param null|string $level
*
* @return array
*/
public function getLogs(): array
public function getLogs(string $level = null): array
{
if ($level) {
$byLevel = array_filter($this->logs, static function (array $log) use ($level) {
return $log['level'] === $level;
});

return array_values($byLevel);
}

return $this->logs;
}

Expand Down
103 changes: 80 additions & 23 deletions tests/Unit/App/Webhook/PdkWebhookManagerTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
use MyParcelNL\Pdk\Base\Support\Arr;
use MyParcelNL\Pdk\Facade\Pdk;
use MyParcelNL\Pdk\Tests\Uses\UsesMockEachCron;
use MyParcelNL\Pdk\Tests\Uses\UsesMockEachLogger;
use MyParcelNL\Pdk\Tests\Uses\UsesMockPdkInstance;
use MyParcelNL\Pdk\Webhook\Collection\WebhookSubscriptionCollection;
use MyParcelNL\Pdk\Webhook\Model\WebhookSubscription;
Expand All @@ -27,23 +28,19 @@

uses()->group('webhook');

usesShared(new UsesMockPdkInstance(), new UsesMockEachCron());

it('dispatches and executes webhooks', function (string $hook, string $calledClass, bool $useHeader) {
/** @var \MyParcelNL\Pdk\App\Webhook\Contract\PdkWebhooksRepositoryInterface $repository */
$repository = Pdk::get(PdkWebhooksRepositoryInterface::class);
/** @var \MyParcelNL\Pdk\Tests\Bootstrap\MockPdkWebhookManager $webhookManager */
$webhookManager = Pdk::get(PdkWebhookManagerInterface::class);
/** @var \MyParcelNL\Pdk\Tests\Bootstrap\MockCronService $cronService */
$cronService = Pdk::get(CronServiceInterface::class);

$repository->storeHashedUrl('https://example.com/hashed-url');
$repository->store(new WebhookSubscriptionCollection([['hook' => $hook, 'url' => $repository->getHashedUrl()]]));

$time = time();

$request = Request::create(
$repository->getHashedUrl(),
usesShared(new UsesMockPdkInstance(), new UsesMockEachCron(), new UsesMockEachLogger());

/**
* @param string $url
* @param string $hook
* @param bool $useHeader
*
* @return \Symfony\Component\HttpFoundation\Request
*/
function createWebhookRequest(string $url, string $hook, bool $useHeader = false): Request
{
return Request::create(
$url,
Request::METHOD_POST,
[],
[],
Expand All @@ -57,16 +54,42 @@
],
])
);
}

$response = $webhookManager->call($request);
function sendWebhook(string $hook, bool $useHeader = false): Response
{
/** @var \MyParcelNL\Pdk\App\Webhook\Contract\PdkWebhooksRepositoryInterface $webhooksRepository */
$webhooksRepository = Pdk::get(PdkWebhooksRepositoryInterface::class);
/** @var \MyParcelNL\Pdk\Tests\Bootstrap\MockPdkWebhookManager $webhookManager */
$webhookManager = Pdk::get(PdkWebhookManagerInterface::class);

$subscriptions = new WebhookSubscriptionCollection([
[
'hook' => $hook,
'url' => $webhooksRepository->getHashedUrl(),
],
]);

$webhooksRepository->storeHashedUrl('https://example.com/hashed-url');
$webhooksRepository->store($subscriptions);

return $webhookManager->call(createWebhookRequest($webhooksRepository->getHashedUrl(), $hook, $useHeader));
}

it('dispatches and executes webhooks', function (string $hook, string $calledClass, bool $useHeader) {
/** @var \MyParcelNL\Pdk\Tests\Bootstrap\MockPdkWebhookManager $webhookManager */
$webhookManager = Pdk::get(PdkWebhookManagerInterface::class);
/** @var \MyParcelNL\Pdk\Tests\Bootstrap\MockCronService $cronService */
$cronService = Pdk::get(CronServiceInterface::class);

$time = time();
$response = sendWebhook($hook, $useHeader);

$scheduled = $cronService->getScheduledTasks();
$timestamp = $scheduled->first()['timestamp'];

expect($response->getStatusCode())
->toBe(Response::HTTP_ACCEPTED)
->and($request->headers->get('x-myparcel-hook'))
->toBe($hook)
->and($response->getStatusCode())
->toBe(Response::HTTP_ACCEPTED)
->and($scheduled->all())
Expand All @@ -77,9 +100,7 @@
->and($timestamp)
->toBeLessThanOrEqual($time + 10)
->and($scheduled->first()['callback'])
->toBe([$webhookManager, 'processWebhook'])
->and($scheduled->first()['args'])
->toBe([$request]);
->toBe([$webhookManager, 'processWebhook']);

$cronService->executeScheduledTask();

Expand Down Expand Up @@ -130,3 +151,39 @@
'no header' => [false],
'header' => [true],
]);

it('throws error if webhook is not found', function () {
/** @var \MyParcelNL\Pdk\App\Webhook\Contract\PdkWebhooksRepositoryInterface $repository */
$repository = Pdk::get(PdkWebhooksRepositoryInterface::class);
/** @var \MyParcelNL\Pdk\Tests\Bootstrap\MockPdkWebhookManager $webhookManager */
$webhookManager = Pdk::get(PdkWebhookManagerInterface::class);

$repository->storeHashedUrl('https://example.com/hashed-url');

$request = createWebhookRequest($repository->getHashedUrl(), 'unknown');

$response = $webhookManager->call($request);

expect($response->getStatusCode())->toBe(Response::HTTP_ACCEPTED);
});

it('does nothing if webhook is called with invalid context', function () {
/** @var \MyParcelNL\Pdk\App\Webhook\Contract\PdkWebhooksRepositoryInterface $repository */
$repository = Pdk::get(PdkWebhooksRepositoryInterface::class);
/** @var \MyParcelNL\Pdk\Tests\Bootstrap\MockPdkWebhookManager $webhookManager */
$webhookManager = Pdk::get(PdkWebhookManagerInterface::class);
/** @var \MyParcelNL\Pdk\Tests\Bootstrap\MockCronService $cronService */
$cronService = Pdk::get(CronServiceInterface::class);

$repository->storeHashedUrl('https://example.com/hashed-url');

$request = createWebhookRequest($repository->getHashedUrl(), 'unknown');
$response = $webhookManager->call($request, 'invalid_context');

$scheduledTasks = $cronService->getScheduledTasks();

expect($response->getStatusCode())
->toBe(Response::HTTP_ACCEPTED)
->and($scheduledTasks)
->toBeEmpty();
});

0 comments on commit f1b666a

Please sign in to comment.