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