Added active toggle to webhooks

To allow easy temporary de-activation without deletion or other
workarounds. Updated tests to cover.
This commit is contained in:
Dan Brown 2021-12-12 17:39:06 +00:00
parent 917598f7c8
commit dbd4281ae8
No known key found for this signature in database
GPG Key ID: 46D9F943C24A2EF9
10 changed files with 41 additions and 8 deletions

View File

@ -84,10 +84,13 @@ class ActivityLogger
*/
protected function dispatchWebhooks(string $type, $detail): void
{
$webhooks = Webhook::query()->whereHas('trackedEvents', function(Builder $query) use ($type) {
$query->where('event', '=', $type)
->orWhere('event', '=', 'all');
})->get();
$webhooks = Webhook::query()
->whereHas('trackedEvents', function(Builder $query) use ($type) {
$query->where('event', '=', $type)
->orWhere('event', '=', 'all');
})
->where('active', '=', true)
->get();
foreach ($webhooks as $webhook) {
dispatch(new DispatchWebhookJob($webhook, $type, $detail));

View File

@ -13,6 +13,7 @@ use Illuminate\Database\Eloquent\Relations\HasMany;
* @property string $name
* @property string $endpoint
* @property Collection $trackedEvents
* @property bool $active
*/
class Webhook extends Model implements Loggable
{

View File

@ -43,10 +43,12 @@ class WebhookController extends Controller
$validated = $this->validate($request, [
'name' => ['required', 'max:150'],
'endpoint' => ['required', 'url', 'max:500'],
'events' => ['required', 'array']
'events' => ['required', 'array'],
'active' => ['required'],
]);
$webhook = new Webhook($validated);
$webhook->active = $validated['active'] === 'true';
$webhook->save();
$webhook->updateTrackedEvents(array_values($validated['events']));
@ -75,12 +77,14 @@ class WebhookController extends Controller
$validated = $this->validate($request, [
'name' => ['required', 'max:150'],
'endpoint' => ['required', 'url', 'max:500'],
'events' => ['required', 'array']
'events' => ['required', 'array'],
'active' => ['required'],
]);
/** @var Webhook $webhook */
$webhook = Webhook::query()->findOrFail($id);
$webhook->active = $validated['active'] === 'true';
$webhook->fill($validated)->save();
$webhook->updateTrackedEvents($validated['events']);

View File

@ -20,6 +20,7 @@ class WebhookFactory extends Factory
return [
'name' => 'My webhook for ' . $this->faker->country(),
'endpoint' => $this->faker->url,
'active' => true,
];
}
}

View File

@ -16,10 +16,12 @@ class CreateWebhooksTable extends Migration
Schema::create('webhooks', function (Blueprint $table) {
$table->increments('id');
$table->string('name', 150);
$table->boolean('active');
$table->string('endpoint', 500);
$table->timestamps();
$table->index('name');
$table->index('active');
});
Schema::create('webhook_tracked_events', function (Blueprint $table) {

View File

@ -71,6 +71,9 @@ return [
'list_view' => 'List View',
'default' => 'Default',
'breadcrumb' => 'Breadcrumb',
'status' => 'Status',
'status_active' => 'Active',
'status_inactive' => 'Inactive',
// Header
'header_menu_expand' => 'Expand Header Menu',

View File

@ -236,6 +236,7 @@ return [
// Webhooks
'webhooks' => 'Webhooks',
'webhooks_create' => 'Create New Webhook',
'webhooks_none_created' => 'No webhooks have yet been created.',
'webhooks_edit' => 'Edit Webhook',
'webhooks_save' => 'Save Webhook',
'webhooks_details' => 'Webhook Details',
@ -246,6 +247,7 @@ return [
'webhooks_events_all' => 'All system events',
'webhooks_name' => 'Webhook Name',
'webhooks_endpoint' => 'Webhook Endpoint',
'webhooks_active' => 'Webhook Active',
'webhook_events_table_header' => 'Events',
'webhooks_delete' => 'Delete Webhook',
'webhooks_delete_warning' => 'This will fully delete this webhook, with the name \':webhookName\', from the system.',

View File

@ -25,6 +25,7 @@
<tr>
<th>{{ trans('common.name') }}</th>
<th>{{ trans('settings.webhook_events_table_header') }}</th>
<th>{{ trans('common.status') }}</th>
</tr>
@foreach($webhooks as $webhook)
<tr>
@ -39,12 +40,15 @@
{{ $webhook->trackedEvents->count() }}
@endif
</td>
<td>
{{ trans('common.status_' . ($webhook->active ? 'active' : 'inactive')) }}
</td>
</tr>
@endforeach
</table>
@else
<p class="text-muted empty-text">
{{ trans('common.no_items') }}
<p class="text-muted empty-text px-none">
{{ trans('settings.webhooks_none_created') }}
</p>
@endif

View File

@ -9,6 +9,14 @@
<div>
<label class="setting-list-label">{{ trans('settings.webhooks_details') }}</label>
<p class="small">{{ trans('settings.webhooks_details_desc') }}</p>
<div>
@include('form.toggle-switch', [
'name' => 'active',
'value' => old('active') ?? $model->active ?? true,
'label' => trans('settings.webhooks_active'),
])
@include('form.errors', ['name' => 'active'])
</div>
</div>
<div>
<div class="form-group">

View File

@ -22,6 +22,7 @@ class WebhookManagementTest extends TestCase
$resp->assertElementExists('a[href="' . $webhook->getUrl() . '"]', $webhook->name);
$resp->assertSee($webhook->endpoint);
$resp->assertSee('All system events');
$resp->assertSee('Active');
}
public function test_create_view()
@ -38,6 +39,7 @@ class WebhookManagementTest extends TestCase
'name' => 'My first webhook',
'endpoint' => 'https://example.com/webhook',
'events' => ['all'],
'active' => 'true'
]);
$resp->assertRedirect('/settings/webhooks');
@ -49,6 +51,7 @@ class WebhookManagementTest extends TestCase
$this->assertDatabaseHas('webhooks', [
'name' => 'My first webhook',
'endpoint' => 'https://example.com/webhook',
'active' => true,
]);
/** @var Webhook $webhook */
@ -79,6 +82,7 @@ class WebhookManagementTest extends TestCase
'name' => 'My updated webhook',
'endpoint' => 'https://example.com/updated-webhook',
'events' => [ActivityType::PAGE_CREATE, ActivityType::PAGE_UPDATE],
'active' => 'true'
]);
$resp->assertRedirect('/settings/webhooks');
@ -89,6 +93,7 @@ class WebhookManagementTest extends TestCase
'id' => $webhook->id,
'name' => 'My updated webhook',
'endpoint' => 'https://example.com/updated-webhook',
'active' => true,
]);
$trackedEvents = $webhook->trackedEvents()->get();