]> BookStack Code Mirror - bookstack/blob - tests/User/UserPreferencesTest.php
Notifications: Add phpunit test for notification sending
[bookstack] / tests / User / UserPreferencesTest.php
1 <?php
2
3 namespace Tests\User;
4
5 use BookStack\Activity\Tools\UserEntityWatchOptions;
6 use Tests\TestCase;
7
8 class UserPreferencesTest extends TestCase
9 {
10     public function test_index_view()
11     {
12         $resp = $this->asEditor()->get('/preferences');
13         $resp->assertOk();
14         $resp->assertSee('Interface Keyboard Shortcuts');
15         $resp->assertSee('Edit Profile');
16     }
17
18     public function test_index_view_accessible_but_without_profile_for_guest_user()
19     {
20         $this->setSettings(['app-public' => 'true']);
21         $resp = $this->get('/preferences');
22         $resp->assertOk();
23         $resp->assertSee('Interface Keyboard Shortcuts');
24         $resp->assertDontSee('Edit Profile');
25     }
26     public function test_interface_shortcuts_updating()
27     {
28         $this->asEditor();
29
30         // View preferences with defaults
31         $resp = $this->get('/preferences/shortcuts');
32         $resp->assertSee('Interface Keyboard Shortcuts');
33
34         $html = $this->withHtml($resp);
35         $html->assertFieldHasValue('enabled', 'false');
36         $html->assertFieldHasValue('shortcut[home_view]', '1');
37
38         // Update preferences
39         $resp = $this->put('/preferences/shortcuts', [
40             'enabled' => 'true',
41             'shortcut' => ['home_view' => 'Ctrl + 1'],
42         ]);
43
44         $resp->assertRedirect('/preferences/shortcuts');
45         $resp->assertSessionHas('success', 'Shortcut preferences have been updated!');
46
47         // View updates to preferences page
48         $resp = $this->get('/preferences/shortcuts');
49         $html = $this->withHtml($resp);
50         $html->assertFieldHasValue('enabled', 'true');
51         $html->assertFieldHasValue('shortcut[home_view]', 'Ctrl + 1');
52     }
53
54     public function test_body_has_shortcuts_component_when_active()
55     {
56         $editor = $this->users->editor();
57         $this->actingAs($editor);
58
59         $this->withHtml($this->get('/'))->assertElementNotExists('body[component="shortcuts"]');
60
61         setting()->putUser($editor, 'ui-shortcuts-enabled', 'true');
62         $this->withHtml($this->get('/'))->assertElementExists('body[component="shortcuts"]');
63     }
64
65     public function test_notification_routes_requires_notification_permission()
66     {
67         $viewer = $this->users->viewer();
68         $resp = $this->actingAs($viewer)->get('/preferences/notifications');
69         $this->assertPermissionError($resp);
70
71         $resp = $this->put('/preferences/notifications');
72         $this->assertPermissionError($resp);
73
74         $this->permissions->grantUserRolePermissions($viewer, ['receive-notifications']);
75         $resp = $this->get('/preferences/notifications');
76         $resp->assertOk();
77         $resp->assertSee('Notification Preferences');
78     }
79
80     public function test_notification_preferences_updating()
81     {
82         $editor = $this->users->editor();
83
84         // View preferences with defaults
85         $resp = $this->actingAs($editor)->get('/preferences/notifications');
86         $resp->assertSee('Notification Preferences');
87
88         $html = $this->withHtml($resp);
89         $html->assertFieldHasValue('preferences[comment-replies]', 'false');
90
91         // Update preferences
92         $resp = $this->put('/preferences/notifications', [
93             'preferences' => ['comment-replies' => 'true'],
94         ]);
95
96         $resp->assertRedirect('/preferences/notifications');
97         $resp->assertSessionHas('success', 'Notification preferences have been updated!');
98
99         // View updates to preferences page
100         $resp = $this->get('/preferences/notifications');
101         $html = $this->withHtml($resp);
102         $html->assertFieldHasValue('preferences[comment-replies]', 'true');
103     }
104
105     public function test_notification_preferences_show_watches()
106     {
107         $editor = $this->users->editor();
108         $book = $this->entities->book();
109
110         $options = new UserEntityWatchOptions($editor, $book);
111         $options->updateWatchLevel('comments');
112
113         $resp = $this->actingAs($editor)->get('/preferences/notifications');
114         $resp->assertSee($book->name);
115         $resp->assertSee('All Page Updates & Comments');
116
117         $options->updateWatchLevel('default');
118
119         $resp = $this->actingAs($editor)->get('/preferences/notifications');
120         $resp->assertDontSee($book->name);
121         $resp->assertDontSee('All Page Updates & Comments');
122     }
123
124     public function test_notification_preferences_not_accessible_to_guest()
125     {
126         $this->setSettings(['app-public' => 'true']);
127         $guest = $this->users->guest();
128         $this->permissions->grantUserRolePermissions($guest, ['receive-notifications']);
129
130         $resp = $this->get('/preferences/notifications');
131         $this->assertPermissionError($resp);
132
133         $resp = $this->put('/preferences/notifications', [
134             'preferences' => ['comment-replies' => 'true'],
135         ]);
136         $this->assertPermissionError($resp);
137     }
138
139     public function test_update_sort_preference()
140     {
141         $editor = $this->users->editor();
142         $this->actingAs($editor);
143
144         $updateRequest = $this->patch('/preferences/change-sort/books', [
145             'sort'  => 'created_at',
146             'order' => 'desc',
147         ]);
148         $updateRequest->assertStatus(302);
149
150         $this->assertDatabaseHas('settings', [
151             'setting_key' => 'user:' . $editor->id . ':books_sort',
152             'value'       => 'created_at',
153         ]);
154         $this->assertDatabaseHas('settings', [
155             'setting_key' => 'user:' . $editor->id . ':books_sort_order',
156             'value'       => 'desc',
157         ]);
158         $this->assertEquals('created_at', setting()->getForCurrentUser('books_sort'));
159         $this->assertEquals('desc', setting()->getForCurrentUser('books_sort_order'));
160     }
161
162     public function test_update_sort_bad_entity_type_handled()
163     {
164         $editor = $this->users->editor();
165         $this->actingAs($editor);
166
167         $updateRequest = $this->patch('/preferences/change-sort/dogs', [
168             'sort'  => 'name',
169             'order' => 'asc',
170         ]);
171         $updateRequest->assertStatus(500);
172
173         $this->assertNotEmpty('name', setting()->getForCurrentUser('bookshelves_sort'));
174         $this->assertNotEmpty('asc', setting()->getForCurrentUser('bookshelves_sort_order'));
175     }
176
177     public function test_update_expansion_preference()
178     {
179         $editor = $this->users->editor();
180         $this->actingAs($editor);
181
182         $updateRequest = $this->patch('/preferences/change-expansion/home-details', ['expand' => 'true']);
183         $updateRequest->assertStatus(204);
184
185         $this->assertDatabaseHas('settings', [
186             'setting_key' => 'user:' . $editor->id . ':section_expansion#home-details',
187             'value'       => 'true',
188         ]);
189         $this->assertEquals(true, setting()->getForCurrentUser('section_expansion#home-details'));
190
191         $invalidKeyRequest = $this->patch('/preferences/change-expansion/my-home-details', ['expand' => 'true']);
192         $invalidKeyRequest->assertStatus(500);
193     }
194
195     public function test_toggle_dark_mode()
196     {
197         $home = $this->actingAs($this->users->editor())->get('/');
198         $home->assertSee('Dark Mode');
199         $this->withHtml($home)->assertElementNotExists('.dark-mode');
200
201         $this->assertEquals(false, setting()->getForCurrentUser('dark-mode-enabled', false));
202         $prefChange = $this->patch('/preferences/toggle-dark-mode');
203         $prefChange->assertRedirect();
204         $this->assertEquals(true, setting()->getForCurrentUser('dark-mode-enabled'));
205
206         $home = $this->actingAs($this->users->editor())->get('/');
207         $this->withHtml($home)->assertElementExists('.dark-mode');
208         $home->assertDontSee('Dark Mode');
209         $home->assertSee('Light Mode');
210     }
211
212     public function test_dark_mode_defaults_to_config_option()
213     {
214         config()->set('setting-defaults.user.dark-mode-enabled', false);
215         $this->assertEquals(false, setting()->getForCurrentUser('dark-mode-enabled'));
216         $home = $this->get('/login');
217         $this->withHtml($home)->assertElementNotExists('.dark-mode');
218
219         config()->set('setting-defaults.user.dark-mode-enabled', true);
220         $this->assertEquals(true, setting()->getForCurrentUser('dark-mode-enabled'));
221         $home = $this->get('/login');
222         $this->withHtml($home)->assertElementExists('.dark-mode');
223     }
224
225     public function test_books_view_type_preferences_when_list()
226     {
227         $editor = $this->users->editor();
228         setting()->putUser($editor, 'books_view_type', 'list');
229
230         $resp = $this->actingAs($editor)->get('/books');
231         $this->withHtml($resp)
232             ->assertElementNotExists('.featured-image-container')
233             ->assertElementExists('.content-wrap .entity-list-item');
234     }
235
236     public function test_books_view_type_preferences_when_grid()
237     {
238         $editor = $this->users->editor();
239         setting()->putUser($editor, 'books_view_type', 'grid');
240
241         $resp = $this->actingAs($editor)->get('/books');
242         $this->withHtml($resp)->assertElementExists('.featured-image-container');
243     }
244
245     public function test_shelf_view_type_change()
246     {
247         $editor = $this->users->editor();
248         $shelf = $this->entities->shelf();
249         setting()->putUser($editor, 'bookshelf_view_type', 'list');
250
251         $resp = $this->actingAs($editor)->get($shelf->getUrl())->assertSee('Grid View');
252         $this->withHtml($resp)
253             ->assertElementNotExists('.featured-image-container')
254             ->assertElementExists('.content-wrap .entity-list-item');
255
256         $req = $this->patch("/preferences/change-view/bookshelf", ['view' => 'grid']);
257         $req->assertRedirect($shelf->getUrl());
258
259         $resp = $this->actingAs($editor)->get($shelf->getUrl())
260             ->assertSee('List View');
261
262         $this->withHtml($resp)
263             ->assertElementExists('.featured-image-container')
264             ->assertElementNotExists('.content-wrap .entity-list-item');
265     }
266
267     public function test_update_code_language_favourite()
268     {
269         $editor = $this->users->editor();
270         $page = $this->entities->page();
271         $this->actingAs($editor);
272
273         $this->patch('/preferences/update-code-language-favourite', ['language' => 'php', 'active' => true]);
274         $this->patch('/preferences/update-code-language-favourite', ['language' => 'javascript', 'active' => true]);
275
276         $resp = $this->get($page->getUrl('/edit'));
277         $resp->assertSee('option:code-editor:favourites="php,javascript"', false);
278
279         $this->patch('/preferences/update-code-language-favourite', ['language' => 'ruby', 'active' => true]);
280         $this->patch('/preferences/update-code-language-favourite', ['language' => 'php', 'active' => false]);
281
282         $resp = $this->get($page->getUrl('/edit'));
283         $resp->assertSee('option:code-editor:favourites="javascript,ruby"', false);
284     }
285 }