]> BookStack Code Mirror - bookstack/blob - tests/Api/RolesApiTest.php
Played around with a new app structure
[bookstack] / tests / Api / RolesApiTest.php
1 <?php
2
3 namespace Tests\Api;
4
5 use BookStack\Activity\ActivityType;
6 use BookStack\Users\Models\Role;
7 use BookStack\Users\Models\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                 'external_auth_id'  => $firstRole->external_auth_id,
48                 'permissions_count' => $firstRole->permissions()->count(),
49                 'users_count'       => $firstRole->users()->count(),
50                 'created_at'        => $firstRole->created_at->toJSON(),
51                 'updated_at'        => $firstRole->updated_at->toJSON(),
52             ],
53         ]]);
54
55         $resp->assertJson(['total' => Role::query()->count()]);
56     }
57
58     public function test_create_endpoint()
59     {
60         $this->actingAsApiAdmin();
61         /** @var Role $role */
62         $role = Role::query()->first();
63
64         $resp = $this->postJson($this->baseEndpoint, [
65             'display_name' => 'My awesome role',
66             'description'  => 'My great role description',
67             'mfa_enforced' => true,
68             'external_auth_id' => 'auth_id',
69             'permissions'  => [
70                 'content-export',
71                 'page-view-all',
72                 'page-view-own',
73                 'users-manage',
74             ]
75         ]);
76
77         $resp->assertStatus(200);
78         $resp->assertJson([
79             'display_name' => 'My awesome role',
80             'description'  => 'My great role description',
81             'mfa_enforced' => true,
82             'external_auth_id' => 'auth_id',
83             'permissions'  => [
84                 'content-export',
85                 'page-view-all',
86                 'page-view-own',
87                 'users-manage',
88             ]
89         ]);
90
91         $this->assertDatabaseHas('roles', [
92             'display_name' => 'My awesome role',
93             'description'  => 'My great role description',
94             'mfa_enforced' => true,
95             'external_auth_id' => 'auth_id',
96         ]);
97
98         /** @var Role $role */
99         $role = Role::query()->where('display_name', '=', 'My awesome role')->first();
100         $this->assertActivityExists(ActivityType::ROLE_CREATE, null, $role->logDescriptor());
101         $this->assertEquals(4, $role->permissions()->count());
102     }
103
104     public function test_create_name_and_description_validation()
105     {
106         $this->actingAsApiAdmin();
107         /** @var User $existingUser */
108         $existingUser = User::query()->first();
109
110         $resp = $this->postJson($this->baseEndpoint, [
111             'description' => 'My new role',
112         ]);
113         $resp->assertStatus(422);
114         $resp->assertJson($this->validationResponse(['display_name' => ['The display name field is required.']]));
115
116         $resp = $this->postJson($this->baseEndpoint, [
117             'name' => 'My great role with a too long desc',
118             'description' => str_repeat('My great desc', 20),
119         ]);
120         $resp->assertStatus(422);
121         $resp->assertJson($this->validationResponse(['description' => ['The description may not be greater than 180 characters.']]));
122     }
123
124     public function test_read_endpoint()
125     {
126         $this->actingAsApiAdmin();
127         $role = $this->users->editor()->roles()->first();
128         $resp = $this->getJson($this->baseEndpoint . "/{$role->id}");
129
130         $resp->assertStatus(200);
131         $resp->assertJson([
132             'display_name' => $role->display_name,
133             'description'  => $role->description,
134             'mfa_enforced' => $role->mfa_enforced,
135             'external_auth_id' => $role->external_auth_id,
136             'permissions'  => $role->permissions()->orderBy('name', 'asc')->pluck('name')->toArray(),
137             'users' => $role->users()->get()->map(function (User $user) {
138                 return [
139                     'id' => $user->id,
140                     'name' => $user->name,
141                     'slug' => $user->slug,
142                 ];
143             })->toArray(),
144         ]);
145     }
146
147     public function test_update_endpoint()
148     {
149         $this->actingAsApiAdmin();
150         $role = $this->users->editor()->roles()->first();
151         $resp = $this->putJson($this->baseEndpoint . "/{$role->id}", [
152             'display_name' => 'My updated role',
153             'description'  => 'My great role description',
154             'mfa_enforced' => true,
155             'external_auth_id' => 'updated_auth_id',
156             'permissions'  => [
157                 'content-export',
158                 'page-view-all',
159                 'page-view-own',
160                 'users-manage',
161             ]
162         ]);
163
164         $resp->assertStatus(200);
165         $resp->assertJson([
166             'id'           => $role->id,
167             'display_name' => 'My updated role',
168             'description'  => 'My great role description',
169             'mfa_enforced' => true,
170             'external_auth_id' => 'updated_auth_id',
171             'permissions'  => [
172                 'content-export',
173                 'page-view-all',
174                 'page-view-own',
175                 'users-manage',
176             ]
177         ]);
178
179         $role->refresh();
180         $this->assertEquals(4, $role->permissions()->count());
181         $this->assertActivityExists(ActivityType::ROLE_UPDATE);
182     }
183
184     public function test_update_endpoint_does_not_remove_info_if_not_provided()
185     {
186         $this->actingAsApiAdmin();
187         $role = $this->users->editor()->roles()->first();
188         $resp = $this->putJson($this->baseEndpoint . "/{$role->id}", []);
189         $permissionCount = $role->permissions()->count();
190
191         $resp->assertStatus(200);
192         $this->assertDatabaseHas('roles', [
193             'id'           => $role->id,
194             'display_name' => $role->display_name,
195             'description'  => $role->description,
196             'external_auth_id' => $role->external_auth_id,
197         ]);
198
199         $role->refresh();
200         $this->assertEquals($permissionCount, $role->permissions()->count());
201     }
202
203     public function test_delete_endpoint()
204     {
205         $this->actingAsApiAdmin();
206         $role = $this->users->editor()->roles()->first();
207
208         $resp = $this->deleteJson($this->baseEndpoint . "/{$role->id}");
209
210         $resp->assertStatus(204);
211         $this->assertActivityExists(ActivityType::ROLE_DELETE, null, $role->logDescriptor());
212     }
213
214     public function test_delete_endpoint_fails_deleting_system_role()
215     {
216         $this->actingAsApiAdmin();
217         $adminRole = Role::getSystemRole('admin');
218
219         $resp = $this->deleteJson($this->baseEndpoint . "/{$adminRole->id}");
220
221         $resp->assertStatus(500);
222         $resp->assertJson($this->errorResponse('This role is a system role and cannot be deleted', 500));
223     }
224
225     public function test_delete_endpoint_fails_deleting_default_registration_role()
226     {
227         $this->actingAsApiAdmin();
228         $role = $this->users->attachNewRole($this->users->editor());
229         $this->setSettings(['registration-role' => $role->id]);
230
231         $resp = $this->deleteJson($this->baseEndpoint . "/{$role->id}");
232
233         $resp->assertStatus(500);
234         $resp->assertJson($this->errorResponse('This role cannot be deleted while set as the default registration role', 500));
235     }
236 }