Skip to content

Commit 368fb6d

Browse files
authored
Revert "Revert "3 feat support exclusion criteria""
1 parent 4ecbd10 commit 368fb6d

File tree

10 files changed

+137
-12
lines changed

10 files changed

+137
-12
lines changed

database/factories/WebhookFactory.php

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44

55
use Illuminate\Database\Eloquent\Factories\Factory;
66
use OnrampLab\Webhooks\Models\Webhook;
7-
use OnrampLab\Webhooks\ValueObjects\ExclusionCriteria;
7+
use OnrampLab\Webhooks\ValueObjects\ExclusionCriterion;
88

99
class WebhookFactory extends Factory
1010
{
@@ -27,13 +27,13 @@ public function definition()
2727
'http_verb' => 'POST',
2828
'enabled' => true,
2929
'exclusion_criteria' => [
30-
new ExclusionCriteria([
31-
'name' => 'campaign_ids',
30+
new ExclusionCriterion([
31+
'name' => 'account_ids',
3232
'values' => [1, 2]
3333
]),
34-
new ExclusionCriteria([
34+
new ExclusionCriterion([
3535
'name' => 'events',
36-
'values' => ['sms_sent', 'sms_delivered']
36+
'values' => ['test_event']
3737
])
3838
],
3939
'contextable_id' => $this->faker->randomNumber(),
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
<?php
2+
3+
namespace OnrampLab\Webhooks\AttributeCastors;
4+
5+
use Illuminate\Contracts\Database\Eloquent\CastsAttributes;
6+
use OnrampLab\Webhooks\ValueObjects\ExclusionCriterion;
7+
8+
class ExclusionCriteriaCastor implements CastsAttributes
9+
{
10+
public function get($model, string $key, $value, array $attributes)
11+
{
12+
if (is_null($value)) {
13+
return null;
14+
}
15+
// Convert the JSON string to an array of ExclusionCriterion objects
16+
$exclusionCriteria = json_decode($value, true);
17+
$casted = [];
18+
19+
foreach ($exclusionCriteria as $criterion) {
20+
$casted[] = new ExclusionCriterion([
21+
'name' => $criterion['name'],
22+
'values' => $criterion['values']
23+
]);
24+
}
25+
26+
return $casted;
27+
}
28+
29+
public function set($model, string $key, $value, array $attributes)
30+
{
31+
if (is_null($value)) {
32+
return null;
33+
}
34+
// Convert the array of ExclusionCriterion objects back to a JSON string
35+
$formatted = [];
36+
37+
foreach ($value as $criterion) {
38+
$formatted[] = [
39+
'name' => $criterion->getName(),
40+
'values' => $criterion->getValues(),
41+
];
42+
}
43+
44+
return json_encode($formatted);
45+
}
46+
}

src/Concerns/Webhookable.php

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,4 +26,9 @@ public function getWebhookPayload(): array
2626
{
2727
return [];
2828
}
29+
30+
public function getExclusionCriteria(): array
31+
{
32+
return [];
33+
}
2934
}

src/Contracts/Webhookable.php

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,4 +12,6 @@ public function getWebhookPayload(): array;
1212
public function getWebhookContext(): ?Model;
1313

1414
public function getEventOccurredAt(): ?Carbon;
15+
16+
public function getExclusionCriteria(): array;
1517
}

src/Models/Webhook.php

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
use Illuminate\Database\Eloquent\Model;
77
use Illuminate\Database\Eloquent\Factories\Factory;
88
use Illuminate\Database\Eloquent\Relations\HasMany;
9+
use OnrampLab\Webhooks\AttributeCastors\ExclusionCriteriaCastor;
910
use OnrampLab\Webhooks\Database\Factories\WebhookFactory;
1011

1112

@@ -36,7 +37,7 @@ class Webhook extends Model
3637
*/
3738
protected $casts = [
3839
'enabled' => 'boolean',
39-
'exclusion_criteria' => 'array',
40+
'exclusion_criteria' => ExclusionCriteriaCastor::class,
4041
'headers' => 'array'
4142
];
4243

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44

55
use JsonSerializable;
66

7-
class ExclusionCriteria implements JsonSerializable
7+
class ExclusionCriterion implements JsonSerializable
88
{
99
public string $name;
1010

@@ -33,4 +33,14 @@ public function jsonSerialize(): array
3333
{
3434
return $this->toArray();
3535
}
36+
37+
public function getName(): string
38+
{
39+
return $this->name;
40+
}
41+
42+
public function getValues(): array
43+
{
44+
return $this->values;
45+
}
3646
}

src/WebhookDispatcher.php

Lines changed: 26 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,13 @@ class WebhookDispatcher
1414

1515
public function handle(Webhookable $event)
1616
{
17-
$payload = $event->getWebhookPayload();
1817
$webhooks = $this->getWebhooks($event);
18+
19+
if ($webhooks->isEmpty()) {
20+
return;
21+
}
22+
23+
$payload = $event->getWebhookPayload();
1924
$this->eventOccurredAt = $event->getEventOccurredAt();
2025

2126
foreach ($webhooks as $webhook) {
@@ -45,7 +50,26 @@ protected function getWebhooks(Webhookable $event): Collection
4550

4651
protected function areExclusionCriteriaMatched(Webhookable $event, Webhook $webhook): bool
4752
{
48-
//to be implemented
53+
$webhookExclusionCriteria = $webhook->exclusion_criteria;
54+
$eventExclusionCriteria = $event->getExclusionCriteria();
55+
56+
if (is_null($webhookExclusionCriteria) || empty($eventExclusionCriteria)) {
57+
return false;
58+
}
59+
60+
foreach ($eventExclusionCriteria as $eventExclusionCriterion) {
61+
$eventExclusionCriteriaName = $eventExclusionCriterion->getName();
62+
$eventExclusionCriteriaValues = $eventExclusionCriterion->getValues();
63+
64+
foreach ($webhookExclusionCriteria as $webhookExclusionCriterion) {
65+
$webhookExclusionCriteriaName = $webhookExclusionCriterion->getName();
66+
$webhookExclusionCriteriaValues = $webhookExclusionCriterion->getValues();
67+
if ($eventExclusionCriteriaName === $webhookExclusionCriteriaName && count(array_intersect($webhookExclusionCriteriaValues, $eventExclusionCriteriaValues)) > 0) {
68+
return true;
69+
}
70+
}
71+
}
72+
4973
return false;
5074
}
5175

tests/Classes/TestEvent.php

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,9 @@
22

33
namespace OnrampLab\Webhooks\Tests\Classes;
44

5-
use Illuminate\Database\Eloquent\Model;
65
use OnrampLab\Webhooks\Contracts\Webhookable as WebhookableContract;
76
use \OnrampLab\Webhooks\Concerns\Webhookable as WebhookableTrait;
7+
use OnrampLab\Webhooks\ValueObjects\ExclusionCriterion;
88

99
class TestEvent implements WebhookableContract
1010
{
@@ -20,4 +20,14 @@ public function getWebhookContext(): ?Account
2020
{
2121
return $this->account;
2222
}
23+
24+
public function getExclusionCriteria(): array
25+
{
26+
return [
27+
new ExclusionCriterion([
28+
'name' => 'events',
29+
'values' => ['test_event']
30+
]),
31+
];
32+
}
2333
}

tests/Feature/WebhookDispatcherTest.php

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,6 @@ protected function setUp(): void
3131
*/
3232
public function should_dispatch_webhook_according_to_context(): void
3333
{
34-
3534
Queue::fake();
3635

3736
$dispatcher = new WebhookDispatcher();

tests/Unit/WebhookDispatcherTest.php

Lines changed: 29 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,35 @@
22

33
namespace OnrampLab\Webhooks\Tests\Unit;
44

5-
class WebhookDispatcherTest
5+
use OnrampLab\Webhooks\CallWebhookJob;
6+
use OnrampLab\Webhooks\Models\Webhook;
7+
use OnrampLab\Webhooks\Tests\Classes\Account;
8+
use OnrampLab\Webhooks\Tests\Classes\TestEvent;
9+
use OnrampLab\Webhooks\Tests\TestCase;
10+
use OnrampLab\Webhooks\WebhookDispatcher;
11+
12+
class WebhookDispatcherTest extends TestCase
613
{
14+
protected function setUp(): void
15+
{
16+
parent::setUp();
17+
$this->account = Account::factory()->create();
18+
$attributes = [
19+
'contextable_id' => $this->account->id,
20+
'contextable_type' => get_class($this->account)
21+
];
22+
$this->webhook = Webhook::factory()->create($attributes);
23+
$this->event = new TestEvent($this->account);
24+
$this->callWebhookJobMock = $this->mock(CallWebhookJob::class);
25+
}
726

27+
/**
28+
* @test
29+
*/
30+
public function should_not_dispatch_webhook_when_exclusion_criteria_are_matched(): void
31+
{
32+
$dispatcher = new WebhookDispatcher();
33+
$dispatcher->handle($this->event);
34+
}
835
}
36+

0 commit comments

Comments
 (0)