Added testing for webhook management interface · yuhw2001/BookStack@6381041 · GitHub
Skip to content

Commit 6381041

Browse files
committed
Added testing for webhook management interface
1 parent 8716b19 commit 6381041

5 files changed

Lines changed: 204 additions & 3 deletions

File tree

database/factories/WebhookFactory.php renamed to database/factories/Actions/WebhookFactory.php

Lines changed: 5 additions & 1 deletion
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
<?php
2+
3+
namespace Database\Factories;
4+
5+
use BookStack\Actions\ActivityType;
6+
use BookStack\Actions\Webhook;
7+
use Illuminate\Database\Eloquent\Factories\Factory;
8+
9+
class WebhookTrackedEventFactory extends Factory
10+
{
11+
/**
12+
* Define the model's default state.
13+
*
14+
* @return array
15+
*/
16+
public function definition()
17+
{
18+
return [
19+
'webhook_id' => Webhook::factory(),
20+
'event' => ActivityType::all()[array_rand(ActivityType::all())],
21+
];
22+
}
23+
}
Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
<?php
22

3-
namespace Tests;
3+
namespace Tests\Actions;
44

55
use BookStack\Actions\Activity;
66
use BookStack\Actions\ActivityService;
@@ -11,6 +11,9 @@
1111
use BookStack\Entities\Repos\PageRepo;
1212
use BookStack\Entities\Tools\TrashCan;
1313
use Carbon\Carbon;
14+
use Tests\TestCase;
15+
use function app;
16+
use function config;
1417

1518
class AuditLogTest extends TestCase
1619
{
Lines changed: 168 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,168 @@
1+
<?php
2+
3+
namespace Tests\Actions;
4+
5+
use BookStack\Actions\ActivityType;
6+
use BookStack\Actions\Webhook;
7+
use Tests\TestCase;
8+
9+
class WebhookManagementTest extends TestCase
10+
{
11+
12+
public function test_index_view()
13+
{
14+
$webhook = $this->newWebhook([
15+
'name' => 'My awesome webhook',
16+
'endpoint' => 'https://example.com/donkey/webhook',
17+
], ['all']);
18+
19+
$resp = $this->asAdmin()->get('/settings/webhooks');
20+
$resp->assertOk();
21+
$resp->assertElementContains('a[href$="/settings/webhooks/create"]', 'Create New Webhook');
22+
$resp->assertElementExists('a[href="' . $webhook->getUrl() . '"]', $webhook->name);
23+
$resp->assertSee($webhook->endpoint);
24+
$resp->assertSee('All system events');
25+
}
26+
27+
public function test_create_view()
28+
{
29+
$resp = $this->asAdmin()->get('/settings/webhooks/create');
30+
$resp->assertOk();
31+
$resp->assertSee('Create New Webhook');
32+
$resp->assertElementContains('form[action$="/settings/webhooks/create"] button', 'Save Webhook');
33+
}
34+
35+
public function test_store()
36+
{
37+
$resp = $this->asAdmin()->post('/settings/webhooks/create', [
38+
'name' => 'My first webhook',
39+
'endpoint' => 'https://example.com/webhook',
40+
'events' => ['all'],
41+
]);
42+
43+
$resp->assertRedirect('/settings/webhooks');
44+
$this->assertActivityExists(ActivityType::WEBHOOK_CREATE);
45+
46+
$resp = $this->followRedirects($resp);
47+
$resp->assertSee('Webhook successfully created');
48+
49+
$this->assertDatabaseHas('webhooks', [
50+
'name' => 'My first webhook',
51+
'endpoint' => 'https://example.com/webhook',
52+
]);
53+
54+
/** @var Webhook $webhook */
55+
$webhook = Webhook::query()->where('name', '=', 'My first webhook')->first();
56+
$this->assertDatabaseHas('webhook_tracked_events', [
57+
'webhook_id' => $webhook->id,
58+
'event' => 'all',
59+
]);
60+
}
61+
62+
public function test_edit_view()
63+
{
64+
$webhook = $this->newWebhook();
65+
66+
$resp = $this->asAdmin()->get('/settings/webhooks/' . $webhook->id);
67+
$resp->assertOk();
68+
$resp->assertSee('Edit Webhook');
69+
$resp->assertElementContains('form[action="' . $webhook->getUrl() . '"] button', 'Save Webhook');
70+
$resp->assertElementContains('a[href="' . $webhook->getUrl('/delete') . '"]', 'Delete Webhook');
71+
$resp->assertElementExists('input[type="checkbox"][value="all"][name="events[]"]');
72+
}
73+
74+
public function test_update()
75+
{
76+
$webhook = $this->newWebhook();
77+
78+
$resp = $this->asAdmin()->put('/settings/webhooks/' . $webhook->id, [
79+
'name' => 'My updated webhook',
80+
'endpoint' => 'https://example.com/updated-webhook',
81+
'events' => [ActivityType::PAGE_CREATE, ActivityType::PAGE_UPDATE],
82+
]);
83+
$resp->assertRedirect('/settings/webhooks');
84+
85+
$resp = $this->followRedirects($resp);
86+
$resp->assertSee('Webhook successfully updated');
87+
88+
$this->assertDatabaseHas('webhooks', [
89+
'id' => $webhook->id,
90+
'name' => 'My updated webhook',
91+
'endpoint' => 'https://example.com/updated-webhook',
92+
]);
93+
94+
$trackedEvents = $webhook->trackedEvents()->get();
95+
$this->assertCount(2, $trackedEvents);
96+
$this->assertEquals(['page_create', 'page_update'], $trackedEvents->pluck('event')->values()->all());
97+
98+
$this->assertActivityExists(ActivityType::WEBHOOK_UPDATE);
99+
}
100+
101+
public function test_delete_view()
102+
{
103+
$webhook = $this->newWebhook(['name' => 'Webhook to delete']);
104+
105+
$resp = $this->asAdmin()->get('/settings/webhooks/' . $webhook->id . '/delete');
106+
$resp->assertOk();
107+
$resp->assertSee('Delete Webhook');
108+
$resp->assertSee('This will fully delete this webhook, with the name \'Webhook to delete\', from the system.');
109+
$resp->assertElementContains('form[action$="/settings/webhooks/' . $webhook->id . '"]', 'Delete');
110+
}
111+
112+
public function test_destroy()
113+
{
114+
$webhook = $this->newWebhook();
115+
116+
$resp = $this->asAdmin()->delete('/settings/webhooks/' . $webhook->id);
117+
$resp->assertRedirect('/settings/webhooks');
118+
119+
$resp = $this->followRedirects($resp);
120+
$resp->assertSee('Webhook successfully deleted');
121+
122+
$this->assertDatabaseMissing('webhooks', ['id' => $webhook->id]);
123+
$this->assertDatabaseMissing('webhook_tracked_events', ['webhook_id' => $webhook->id]);
124+
125+
$this->assertActivityExists(ActivityType::WEBHOOK_DELETE);
126+
}
127+
128+
public function test_settings_manage_permission_required_for_webhook_routes()
129+
{
130+
$editor = $this->getEditor();
131+
$this->actingAs($editor);
132+
133+
$routes = [
134+
['GET', '/settings/webhooks'],
135+
['GET', '/settings/webhooks/create'],
136+
['POST', '/settings/webhooks/create'],
137+
['GET', '/settings/webhooks/1'],
138+
['PUT', '/settings/webhooks/1'],
139+
['DELETE', '/settings/webhooks/1'],
140+
['GET', '/settings/webhooks/1/delete'],
141+
];
142+
143+
foreach ($routes as [$method, $endpoint]) {
144+
$resp = $this->call($method, $endpoint);
145+
$this->assertPermissionError($resp);
146+
}
147+
148+
$this->giveUserPermissions($editor, ['settings-manage']);
149+
150+
foreach ($routes as [$method, $endpoint]) {
151+
$resp = $this->call($method, $endpoint);
152+
$this->assertNotPermissionError($resp);
153+
}
154+
}
155+
156+
protected function newWebhook(array $attrs = [], array $events = ['all']): Webhook
157+
{
158+
/** @var Webhook $webhook */
159+
$webhook = Webhook::factory()->create($attrs);
160+
161+
foreach ($events as $event) {
162+
$webhook->trackedEvents()->create(['event' => $event]);
163+
}
164+
165+
return $webhook;
166+
}
167+
168+
}

tests/StatusTest.php

Lines changed: 4 additions & 1 deletion

0 commit comments

Comments
 (0)