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+ }
0 commit comments