]> BookStack Code Mirror - bookstack/blob - tests/CommandsTest.php
LDAP: Added TLS support
[bookstack] / tests / CommandsTest.php
1 <?php namespace Tests;
2
3 use BookStack\Actions\Comment;
4 use BookStack\Actions\CommentRepo;
5 use BookStack\Auth\Permissions\JointPermission;
6 use BookStack\Entities\Bookshelf;
7 use BookStack\Entities\Page;
8 use BookStack\Auth\User;
9 use BookStack\Entities\Repos\PageRepo;
10 use Symfony\Component\Console\Exception\RuntimeException;
11
12 class CommandsTest extends TestCase
13 {
14
15     public function test_clear_views_command()
16     {
17         $this->asEditor();
18         $page = Page::first();
19
20         $this->get($page->getUrl());
21
22         $this->assertDatabaseHas('views', [
23             'user_id' => $this->getEditor()->id,
24             'viewable_id' => $page->id,
25             'views' => 1
26         ]);
27
28         $exitCode = \Artisan::call('bookstack:clear-views');
29         $this->assertTrue($exitCode === 0, 'Command executed successfully');
30
31         $this->assertDatabaseMissing('views', [
32             'user_id' => $this->getEditor()->id
33         ]);
34     }
35
36     public function test_clear_activity_command()
37     {
38         $this->asEditor();
39         $page = Page::first();
40         \Activity::add($page, 'page_update', $page->book->id);
41
42         $this->assertDatabaseHas('activities', [
43             'key' => 'page_update',
44             'entity_id' => $page->id,
45             'user_id' => $this->getEditor()->id
46         ]);
47
48         $exitCode = \Artisan::call('bookstack:clear-activity');
49         $this->assertTrue($exitCode === 0, 'Command executed successfully');
50
51
52         $this->assertDatabaseMissing('activities', [
53             'key' => 'page_update'
54         ]);
55     }
56
57     public function test_clear_revisions_command()
58     {
59         $this->asEditor();
60         $pageRepo = app(PageRepo::class);
61         $page = Page::first();
62         $pageRepo->update($page, ['name' => 'updated page', 'html' => '<p>new content</p>', 'summary' => 'page revision testing']);
63         $pageRepo->updatePageDraft($page, ['name' => 'updated page', 'html' => '<p>new content in draft</p>', 'summary' => 'page revision testing']);
64
65         $this->assertDatabaseHas('page_revisions', [
66             'page_id' => $page->id,
67             'type' => 'version'
68         ]);
69         $this->assertDatabaseHas('page_revisions', [
70             'page_id' => $page->id,
71             'type' => 'update_draft'
72         ]);
73
74         $exitCode = \Artisan::call('bookstack:clear-revisions');
75         $this->assertTrue($exitCode === 0, 'Command executed successfully');
76
77         $this->assertDatabaseMissing('page_revisions', [
78             'page_id' => $page->id,
79             'type' => 'version'
80         ]);
81         $this->assertDatabaseHas('page_revisions', [
82             'page_id' => $page->id,
83             'type' => 'update_draft'
84         ]);
85
86         $exitCode = \Artisan::call('bookstack:clear-revisions', ['--all' => true]);
87         $this->assertTrue($exitCode === 0, 'Command executed successfully');
88
89         $this->assertDatabaseMissing('page_revisions', [
90             'page_id' => $page->id,
91             'type' => 'update_draft'
92         ]);
93     }
94
95     public function test_regen_permissions_command()
96     {
97         JointPermission::query()->truncate();
98         $page = Page::first();
99
100         $this->assertDatabaseMissing('joint_permissions', ['entity_id' => $page->id]);
101
102         $exitCode = \Artisan::call('bookstack:regenerate-permissions');
103         $this->assertTrue($exitCode === 0, 'Command executed successfully');
104
105         $this->assertDatabaseHas('joint_permissions', ['entity_id' => $page->id]);
106     }
107
108     public function test_add_admin_command()
109     {
110         $exitCode = \Artisan::call('bookstack:create-admin', [
111             '--email' => 'admintest@example.com',
112             '--name' => 'Admin Test',
113             '--password' => 'testing-4',
114         ]);
115         $this->assertTrue($exitCode === 0, 'Command executed successfully');
116
117         $this->assertDatabaseHas('users', [
118             'email' => 'admintest@example.com',
119             'name' => 'Admin Test'
120         ]);
121
122         $this->assertTrue(User::where('email', '=', 'admintest@example.com')->first()->hasSystemRole('admin'), 'User has admin role as expected');
123         $this->assertTrue(\Auth::attempt(['email' => 'admintest@example.com', 'password' => 'testing-4']), 'Password stored as expected');
124     }
125
126     public function test_copy_shelf_permissions_command_shows_error_when_no_required_option_given()
127     {
128         $this->artisan('bookstack:copy-shelf-permissions')
129             ->expectsOutput('Either a --slug or --all option must be provided.')
130             ->assertExitCode(0);
131     }
132
133     public function test_copy_shelf_permissions_command_using_slug()
134     {
135         $shelf = Bookshelf::first();
136         $child = $shelf->books()->first();
137         $editorRole = $this->getEditor()->roles()->first();
138         $this->assertFalse(boolval($child->restricted), "Child book should not be restricted by default");
139         $this->assertTrue($child->permissions()->count() === 0, "Child book should have no permissions by default");
140
141         $this->setEntityRestrictions($shelf, ['view', 'update'], [$editorRole]);
142         $this->artisan('bookstack:copy-shelf-permissions', [
143             '--slug' => $shelf->slug,
144         ]);
145         $child = $shelf->books()->first();
146
147         $this->assertTrue(boolval($child->restricted), "Child book should now be restricted");
148         $this->assertTrue($child->permissions()->count() === 2, "Child book should have copied permissions");
149         $this->assertDatabaseHas('entity_permissions', ['restrictable_id' => $child->id, 'action' => 'view', 'role_id' => $editorRole->id]);
150         $this->assertDatabaseHas('entity_permissions', ['restrictable_id' => $child->id, 'action' => 'update', 'role_id' => $editorRole->id]);
151     }
152
153     public function test_copy_shelf_permissions_command_using_all()
154     {
155         $shelf = Bookshelf::query()->first();
156         Bookshelf::query()->where('id', '!=', $shelf->id)->delete();
157         $child = $shelf->books()->first();
158         $editorRole = $this->getEditor()->roles()->first();
159         $this->assertFalse(boolval($child->restricted), "Child book should not be restricted by default");
160         $this->assertTrue($child->permissions()->count() === 0, "Child book should have no permissions by default");
161
162         $this->setEntityRestrictions($shelf, ['view', 'update'], [$editorRole]);
163         $this->artisan('bookstack:copy-shelf-permissions --all')
164             ->expectsQuestion('Permission settings for all shelves will be cascaded. Books assigned to multiple shelves will receive only the permissions of it\'s last processed shelf. Are you sure you want to proceed?', 'y');
165         $child = $shelf->books()->first();
166
167         $this->assertTrue(boolval($child->restricted), "Child book should now be restricted");
168         $this->assertTrue($child->permissions()->count() === 2, "Child book should have copied permissions");
169         $this->assertDatabaseHas('entity_permissions', ['restrictable_id' => $child->id, 'action' => 'view', 'role_id' => $editorRole->id]);
170         $this->assertDatabaseHas('entity_permissions', ['restrictable_id' => $child->id, 'action' => 'update', 'role_id' => $editorRole->id]);
171     }
172
173     public function test_update_url_command_updates_page_content()
174     {
175         $page = Page::query()->first();
176         $page->html = '<a href="https://example.com/donkeys"></a>';
177         $page->save();
178
179         $this->artisan('bookstack:update-url https://example.com https://cats.example.com')
180             ->expectsQuestion("This will search for \"https://example.com\" in your database and replace it with  \"https://cats.example.com\".\nAre you sure you want to proceed?", 'y')
181             ->expectsQuestion("This operation could cause issues if used incorrectly. Have you made a backup of your existing database?", 'y');
182
183         $this->assertDatabaseHas('pages', [
184             'id' => $page->id,
185             'html' => '<a href="https://cats.example.com/donkeys"></a>'
186         ]);
187     }
188
189     public function test_update_url_command_requires_valid_url()
190     {
191         $badUrlMessage = "The given urls are expected to be full urls starting with http:// or https://";
192         $this->artisan('bookstack:update-url //example.com https://cats.example.com')->expectsOutput($badUrlMessage);
193         $this->artisan('bookstack:update-url https://example.com htts://cats.example.com')->expectsOutput($badUrlMessage);
194         $this->artisan('bookstack:update-url example.com https://cats.example.com')->expectsOutput($badUrlMessage);
195
196         $this->expectException(RuntimeException::class);
197         $this->artisan('bookstack:update-url https://cats.example.com');
198     }
199
200     public function test_regenerate_comment_content_command()
201     {
202         Comment::query()->forceCreate([
203             'html' => 'some_old_content',
204             'text' => 'some_fresh_content',
205         ]);
206
207         $this->assertDatabaseHas('comments', [
208             'html' => 'some_old_content',
209         ]);
210
211         $exitCode = \Artisan::call('bookstack:regenerate-comment-content');
212         $this->assertTrue($exitCode === 0, 'Command executed successfully');
213
214         $this->assertDatabaseMissing('comments', [
215             'html' => 'some_old_content',
216         ]);
217         $this->assertDatabaseHas('comments', [
218             'html' => "<p>some_fresh_content</p>\n",
219         ]);
220     }
221 }
Morty Proxy This is a proxified and sanitized view of the page, visit original site.