]> BookStack Code Mirror - bookstack/blob - tests/Api/RolesApiTest.php
38026a40afeb145b5867c768bc7e1bd28f5f8cd8
[bookstack] / tests / Api / RolesApiTest.php
1 <?php
2
3 namespace Tests\Api;
4
5 use BookStack\Actions\ActivityType;
6 use BookStack\Auth\Role;
7 use BookStack\Auth\User;
8 use Tests\TestCase;
9
10 class RolesApiTest extends TestCase
11 {
12     use TestsApi;
13
14     protected string $baseEndpoint = '/api/roles';
15
16     protected array $endpointMap = [
17         ['get', '/api/roles'],
18         ['post', '/api/roles'],
19         ['get', '/api/roles/1'],
20         ['put', '/api/roles/1'],
21         ['delete', '/api/roles/1'],
22     ];
23
24     public function test_user_roles_manage_permission_needed_for_all_endpoints()
25     {
26         $this->actingAsApiEditor();
27         foreach ($this->endpointMap as [$method, $uri]) {
28             $resp = $this->json($method, $uri);
29             $resp->assertStatus(403);
30             $resp->assertJson($this->permissionErrorResponse());
31         }
32     }
33
34     public function test_index_endpoint_returns_expected_role_and_count()
35     {
36         $this->actingAsApiAdmin();
37         /** @var Role $firstRole */
38         $firstRole = Role::query()->orderBy('id', 'asc')->first();
39
40         $resp = $this->getJson($this->baseEndpoint . '?count=1&sort=+id');
41         $resp->assertJson(['data' => [
42             [
43                 'id'          => $firstRole->id,
44                 'display_name'        => $firstRole->display_name,
45                 'description'        => $firstRole->description,
46                 'mfa_enforced'       => $firstRole->mfa_enforced,
47                 'permissions_count' => $firstRole->permissions()->count(),
48                 'users_count'    => $firstRole->users()->count(),
49                 'created_at'    => $firstRole->created_at->toJSON(),
50                 'updated_at'    => $firstRole->updated_at->toJSON(),
51             ],
52         ]]);
53
54         $resp->assertJson(['total' => Role::query()->count()]);
55     }
56
57     public function test_create_endpoint()
58     {
59         $this->actingAsApiAdmin();
60         /** @var Role $role */
61         $role = Role::query()->first();
62
63         $resp = $this->postJson($this->baseEndpoint, [
64             'display_name' => 'My awesome role',
65             'description'  => 'My great role description',
66             'mfa_enforced' => true,
67             'permissions'  => [
68                 'content-export',
69                 'users-manage',
70                 'page-view-own',
71                 'page-view-all',
72             ]
73         ]);
74
75         $resp->assertStatus(200);
76         $resp->assertJson([
77             'display_name' => 'My awesome role',
78             'description'  => 'My great role description',
79             'mfa_enforced' => true,
80             'permissions'  => [
81                 'content-export',
82                 'users-manage',
83                 'page-view-own',
84                 'page-view-all',
85             ]
86         ]);
87
88         $this->assertDatabaseHas('roles', [
89             'display_name' => 'My awesome role',
90             'description'  => 'My great role description',
91             'mfa_enforced' => true,
92         ]);
93
94         /** @var Role $role */
95         $role = Role::query()->where('display_name', '=', 'My awesome role')->first();
96         $this->assertActivityExists(ActivityType::ROLE_CREATE, null, $role->logDescriptor());
97         $this->assertEquals(4, $role->permissions()->count());
98     }
99
100     public function test_create_name_and_description_validation()
101     {
102         $this->actingAsApiAdmin();
103         /** @var User $existingUser */
104         $existingUser = User::query()->first();
105
106         $resp = $this->postJson($this->baseEndpoint, [
107             'description' => 'My new role',
108         ]);
109         $resp->assertStatus(422);
110         $resp->assertJson($this->validationResponse(['display_name' => ['The display_name field is required.']]));
111
112         $resp = $this->postJson($this->baseEndpoint, [
113             'name' => 'My great role with a too long desc',
114             'description' => str_repeat('My great desc', 20),
115         ]);
116         $resp->assertStatus(422);
117         $resp->assertJson($this->validationResponse(['description' => ['The description may not be greater than 180 characters.']]));
118     }
119
120     public function test_read_endpoint()
121     {
122         $this->actingAsApiAdmin();
123         $role = $this->users->editor()->roles()->first();
124         $resp = $this->getJson($this->baseEndpoint . "/{$role->id}");
125
126         $resp->assertStatus(200);
127         $resp->assertJson([
128             'display_name' => $role->display_name,
129             'description'  => $role->description,
130             'mfa_enforced' => $role->mfa_enforced,
131             'permissions'  => $role->permissions()->pluck('name')->toArray(),
132             'users' => $role->users()->get()->map(function (User $user) {
133                 return [
134                     'id' => $user->id,
135                     'name' => $user->name,
136                     'slug' => $user->slug,
137                 ];
138             })->toArray(),
139         ]);
140     }
141
142     public function test_update_endpoint()
143     {
144         $this->actingAsApiAdmin();
145         $role = $this->users->editor()->roles()->first();
146         $resp = $this->putJson($this->baseEndpoint . "/{$role->id}", [
147             'display_name' => 'My updated role',
148             'description'  => 'My great role description',
149             'mfa_enforced' => true,
150             'permissions'  => [
151                 'content-export',
152                 'users-manage',
153                 'page-view-own',
154                 'page-view-all',
155             ]
156         ]);
157
158         $resp->assertStatus(200);
159         $resp->assertJson([
160             'id'           => $role->id,
161             'display_name' => 'My updated role',
162             'description'  => 'My great role description',
163             'mfa_enforced' => true,
164             'permissions'  => [
165                 'content-export',
166                 'users-manage',
167                 'page-view-own',
168                 'page-view-all',
169             ]
170         ]);
171
172         $role->refresh();
173         $this->assertEquals(4, $role->permissions()->count());
174     }
175
176     public function test_update_endpoint_does_not_remove_info_if_not_provided()
177     {
178         $this->actingAsApiAdmin();
179         $role = $this->users->editor()->roles()->first();
180         $resp = $this->putJson($this->baseEndpoint . "/{$role->id}", []);
181         $permissionCount = $role->permissions()->count();
182
183         $resp->assertStatus(200);
184         $this->assertDatabaseHas('users', [
185             'id'           => $role->id,
186             'display_name' => $role->display_name,
187             'description'  => $role->description,
188         ]);
189
190         $role->refresh();
191         $this->assertEquals($permissionCount, $role->permissions()->count());
192     }
193
194     public function test_delete_endpoint()
195     {
196         $this->actingAsApiAdmin();
197         $role = $this->users->editor()->roles()->first();
198
199         $resp = $this->deleteJson($this->baseEndpoint . "/{$role->id}");
200
201         $resp->assertStatus(204);
202         $this->assertActivityExists(ActivityType::ROLE_DELETE, null, $role->logDescriptor());
203     }
204
205     public function test_delete_endpoint_fails_deleting_system_role()
206     {
207         $this->actingAsApiAdmin();
208         $adminRole = Role::getSystemRole('admin');
209
210         $resp = $this->deleteJson($this->baseEndpoint . "/{$adminRole->id}");
211
212         $resp->assertStatus(500);
213         $resp->assertJson($this->errorResponse('This role is a system role and cannot be deleted', 500));
214     }
215
216     public function test_delete_endpoint_fails_deleting_default_registration_role()
217     {
218         $this->actingAsApiAdmin();
219         $role = $this->users->attachNewRole($this->users->editor());
220         $this->setSettings(['registration-role' => $role->id]);
221
222         $resp = $this->deleteJson($this->baseEndpoint . "/{$role->id}");
223
224         $resp->assertStatus(500);
225         $resp->assertJson($this->errorResponse('This role cannot be deleted while set as the default registration role', 500));
226     }
227 }