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