]> BookStack Code Mirror - bookstack/blob - tests/Entity/PageRevisionTest.php
Updated page revisions link visibility
[bookstack] / tests / Entity / PageRevisionTest.php
1 <?php
2
3 namespace Tests\Entity;
4
5 use BookStack\Actions\ActivityType;
6 use BookStack\Entities\Models\Page;
7 use BookStack\Entities\Repos\PageRepo;
8 use Tests\TestCase;
9
10 class PageRevisionTest extends TestCase
11 {
12
13     public function test_revision_links_visible_to_viewer()
14     {
15         /** @var Page $page */
16         $page = Page::query()->first();
17
18         $html = $this->withHtml($this->asViewer()->get($page->getUrl()));
19         $html->assertLinkExists($page->getUrl('/revisions'));
20         $html->assertElementContains('a', 'Revisions');
21         $html->assertElementContains('a', 'Revision #1');
22     }
23
24     public function test_page_revision_views_viewable()
25     {
26         $this->asEditor();
27
28         $pageRepo = app(PageRepo::class);
29         $page = Page::first();
30         $pageRepo->update($page, ['name' => 'updated page', 'html' => '<p>new content</p>', 'summary' => 'page revision testing']);
31         $pageRevision = $page->revisions->last();
32
33         $revisionView = $this->get($page->getUrl() . '/revisions/' . $pageRevision->id);
34         $revisionView->assertStatus(200);
35         $revisionView->assertSee('new content');
36
37         $revisionView = $this->get($page->getUrl() . '/revisions/' . $pageRevision->id . '/changes');
38         $revisionView->assertStatus(200);
39         $revisionView->assertSee('new content');
40     }
41
42     public function test_page_revision_preview_shows_content_of_revision()
43     {
44         $this->asEditor();
45
46         $pageRepo = app(PageRepo::class);
47         $page = Page::first();
48         $pageRepo->update($page, ['name' => 'updated page', 'html' => '<p>new revision content</p>', 'summary' => 'page revision testing']);
49         $pageRevision = $page->revisions->last();
50         $pageRepo->update($page, ['name' => 'updated page', 'html' => '<p>Updated content</p>', 'summary' => 'page revision testing 2']);
51
52         $revisionView = $this->get($page->getUrl() . '/revisions/' . $pageRevision->id);
53         $revisionView->assertStatus(200);
54         $revisionView->assertSee('new revision content');
55     }
56
57     public function test_page_revision_restore_updates_content()
58     {
59         $this->asEditor();
60
61         $pageRepo = app(PageRepo::class);
62         $page = Page::first();
63         $pageRepo->update($page, ['name' => 'updated page abc123', 'html' => '<p>new contente def456</p>', 'summary' => 'initial page revision testing']);
64         $pageRepo->update($page, ['name' => 'updated page again', 'html' => '<p>new content</p>', 'summary' => 'page revision testing']);
65         $page = Page::find($page->id);
66
67         $pageView = $this->get($page->getUrl());
68         $pageView->assertDontSee('abc123');
69         $pageView->assertDontSee('def456');
70
71         $revToRestore = $page->revisions()->where('name', 'like', '%abc123')->first();
72         $restoreReq = $this->put($page->getUrl() . '/revisions/' . $revToRestore->id . '/restore');
73         $page = Page::find($page->id);
74
75         $restoreReq->assertStatus(302);
76         $restoreReq->assertRedirect($page->getUrl());
77
78         $pageView = $this->get($page->getUrl());
79         $pageView->assertSee('abc123');
80         $pageView->assertSee('def456');
81     }
82
83     public function test_page_revision_restore_with_markdown_retains_markdown_content()
84     {
85         $this->asEditor();
86
87         $pageRepo = app(PageRepo::class);
88         $page = Page::first();
89         $pageRepo->update($page, ['name' => 'updated page abc123', 'markdown' => '## New Content def456', 'summary' => 'initial page revision testing']);
90         $pageRepo->update($page, ['name' => 'updated page again', 'markdown' => '## New Content Updated', 'summary' => 'page revision testing']);
91         $page = Page::find($page->id);
92
93         $pageView = $this->get($page->getUrl());
94         $pageView->assertDontSee('abc123');
95         $pageView->assertDontSee('def456');
96
97         $revToRestore = $page->revisions()->where('name', 'like', '%abc123')->first();
98         $restoreReq = $this->put($page->getUrl() . '/revisions/' . $revToRestore->id . '/restore');
99         $page = Page::find($page->id);
100
101         $restoreReq->assertStatus(302);
102         $restoreReq->assertRedirect($page->getUrl());
103
104         $pageView = $this->get($page->getUrl());
105         $this->assertDatabaseHas('pages', [
106             'id'       => $page->id,
107             'markdown' => '## New Content def456',
108         ]);
109         $pageView->assertSee('abc123');
110         $pageView->assertSee('def456');
111     }
112
113     public function test_page_revision_restore_sets_new_revision_with_summary()
114     {
115         $this->asEditor();
116
117         $pageRepo = app(PageRepo::class);
118         $page = Page::first();
119         $pageRepo->update($page, ['name' => 'updated page abc123', 'html' => '<p>new contente def456</p>', 'summary' => 'My first update']);
120         $pageRepo->update($page, ['name' => 'updated page again', 'html' => '<p>new content</p>', 'summary' => '']);
121         $page->refresh();
122
123         $revToRestore = $page->revisions()->where('name', 'like', '%abc123')->first();
124         $this->put($page->getUrl() . '/revisions/' . $revToRestore->id . '/restore');
125         $page->refresh();
126
127         $this->assertDatabaseHas('page_revisions', [
128             'page_id' => $page->id,
129             'text'    => 'new contente def456',
130             'type'    => 'version',
131             'summary' => "Restored from #{$revToRestore->id}; My first update",
132         ]);
133
134         $detail = "Revision #{$revToRestore->revision_number} (ID: {$revToRestore->id}) for page ID {$revToRestore->page_id}";
135         $this->assertActivityExists(ActivityType::REVISION_RESTORE, null, $detail);
136     }
137
138     public function test_page_revision_count_increments_on_update()
139     {
140         $page = Page::first();
141         $startCount = $page->revision_count;
142         $resp = $this->asEditor()->put($page->getUrl(), ['name' => 'Updated page', 'html' => 'new page html', 'summary' => 'Update a']);
143         $resp->assertStatus(302);
144
145         $this->assertTrue(Page::find($page->id)->revision_count === $startCount + 1);
146     }
147
148     public function test_revision_count_shown_in_page_meta()
149     {
150         $page = Page::first();
151         $this->asEditor()->put($page->getUrl(), ['name' => 'Updated page', 'html' => 'new page html', 'summary' => 'Update a']);
152
153         $page = Page::find($page->id);
154         $this->asEditor()->put($page->getUrl(), ['name' => 'Updated page', 'html' => 'new page html', 'summary' => 'Update a']);
155
156         $page = Page::find($page->id);
157         $pageView = $this->get($page->getUrl());
158         $pageView->assertSee('Revision #' . $page->revision_count);
159     }
160
161     public function test_revision_deletion()
162     {
163         /** @var Page $page */
164         $page = Page::query()->first();
165         $this->asEditor()->put($page->getUrl(), ['name' => 'Updated page', 'html' => 'new page html', 'summary' => 'Update a']);
166
167         $page->refresh();
168         $this->asEditor()->put($page->getUrl(), ['name' => 'Updated page', 'html' => 'new page html', 'summary' => 'Update a']);
169
170         $page->refresh();
171         $beforeRevisionCount = $page->revisions->count();
172
173         // Delete the first revision
174         $revision = $page->revisions->get(1);
175         $resp = $this->asEditor()->delete($revision->getUrl('/delete/'));
176         $resp->assertRedirect($page->getUrl('/revisions'));
177
178         $page->refresh();
179         $afterRevisionCount = $page->revisions->count();
180
181         $this->assertTrue($beforeRevisionCount === ($afterRevisionCount + 1));
182
183         $detail = "Revision #{$revision->revision_number} (ID: {$revision->id}) for page ID {$revision->page_id}";
184         $this->assertActivityExists(ActivityType::REVISION_DELETE, null, $detail);
185
186         // Try to delete the latest revision
187         $beforeRevisionCount = $page->revisions->count();
188         $resp = $this->asEditor()->delete($page->currentRevision->getUrl('/delete/'));
189         $resp->assertRedirect($page->getUrl('/revisions'));
190
191         $page->refresh();
192         $afterRevisionCount = $page->revisions->count();
193         $this->assertTrue($beforeRevisionCount === $afterRevisionCount);
194     }
195
196     public function test_revision_limit_enforced()
197     {
198         config()->set('app.revision_limit', 2);
199         $page = Page::first();
200         $this->asEditor()->put($page->getUrl(), ['name' => 'Updated page', 'html' => 'new page html', 'summary' => 'Update a']);
201         $page = Page::find($page->id);
202         $this->asEditor()->put($page->getUrl(), ['name' => 'Updated page', 'html' => 'new page html', 'summary' => 'Update a']);
203         for ($i = 0; $i < 10; $i++) {
204             $this->asEditor()->put($page->getUrl(), ['name' => 'Updated page', 'html' => 'new page html', 'summary' => 'Update a']);
205         }
206
207         $revisionCount = $page->revisions()->count();
208         $this->assertEquals(2, $revisionCount);
209     }
210
211     public function test_false_revision_limit_allows_many_revisions()
212     {
213         config()->set('app.revision_limit', false);
214         $page = Page::first();
215         $this->asEditor()->put($page->getUrl(), ['name' => 'Updated page', 'html' => 'new page html', 'summary' => 'Update a']);
216         $page = Page::find($page->id);
217         $this->asEditor()->put($page->getUrl(), ['name' => 'Updated page', 'html' => 'new page html', 'summary' => 'Update a']);
218         for ($i = 0; $i < 10; $i++) {
219             $this->asEditor()->put($page->getUrl(), ['name' => 'Updated page', 'html' => 'new page html', 'summary' => 'Update a']);
220         }
221
222         $revisionCount = $page->revisions()->count();
223         $this->assertEquals(12, $revisionCount);
224     }
225
226     public function test_revision_list_shows_editor_type()
227     {
228         /** @var Page $page */
229         $page = Page::first();
230         $this->asAdmin()->put($page->getUrl(), ['name' => 'Updated page', 'html' => 'new page html']);
231
232         $resp = $this->get($page->refresh()->getUrl('/revisions'));
233         $this->withHtml($resp)->assertElementContains('td', '(WYSIWYG)');
234         $this->withHtml($resp)->assertElementNotContains('td', '(Markdown)');
235
236         $this->asAdmin()->put($page->getUrl(), ['name' => 'Updated page', 'markdown' => '# Some markdown content']);
237         $resp = $this->get($page->refresh()->getUrl('/revisions'));
238         $this->withHtml($resp)->assertElementContains('td', '(Markdown)');
239     }
240 }