3 namespace Tests\Entity;
5 use BookStack\Entities\Models\Book;
6 use BookStack\Entities\Models\Chapter;
7 use BookStack\Entities\Models\Page;
8 use BookStack\Entities\Repos\PageRepo;
11 class SortTest extends TestCase
15 public function setUp(): void
18 $this->book = Book::first();
21 public function test_drafts_do_not_show_up()
24 $pageRepo = app(PageRepo::class);
25 $draft = $pageRepo->getNewDraftPage($this->book);
27 $resp = $this->get($this->book->getUrl());
28 $resp->assertSee($draft->name);
30 $resp = $this->get($this->book->getUrl() . '/sort');
31 $resp->assertDontSee($draft->name);
34 public function test_page_move_into_book()
36 $page = Page::first();
37 $currentBook = $page->book;
38 $newBook = Book::where('id', '!=', $currentBook->id)->first();
40 $resp = $this->asEditor()->get($page->getUrl('/move'));
41 $resp->assertSee('Move Page');
43 $movePageResp = $this->put($page->getUrl('/move'), [
44 'entity_selection' => 'book:' . $newBook->id,
46 $page = Page::find($page->id);
48 $movePageResp->assertRedirect($page->getUrl());
49 $this->assertTrue($page->book->id == $newBook->id, 'Page book is now the new book');
51 $newBookResp = $this->get($newBook->getUrl());
52 $newBookResp->assertSee('moved page');
53 $newBookResp->assertSee($page->name);
56 public function test_page_move_into_chapter()
58 $page = Page::first();
59 $currentBook = $page->book;
60 $newBook = Book::where('id', '!=', $currentBook->id)->first();
61 $newChapter = $newBook->chapters()->first();
63 $movePageResp = $this->actingAs($this->getEditor())->put($page->getUrl('/move'), [
64 'entity_selection' => 'chapter:' . $newChapter->id,
66 $page = Page::find($page->id);
68 $movePageResp->assertRedirect($page->getUrl());
69 $this->assertTrue($page->book->id == $newBook->id, 'Page parent is now the new chapter');
71 $newChapterResp = $this->get($newChapter->getUrl());
72 $newChapterResp->assertSee($page->name);
75 public function test_page_move_from_chapter_to_book()
77 $oldChapter = Chapter::first();
78 $page = $oldChapter->pages()->first();
79 $newBook = Book::where('id', '!=', $oldChapter->book_id)->first();
81 $movePageResp = $this->actingAs($this->getEditor())->put($page->getUrl('/move'), [
82 'entity_selection' => 'book:' . $newBook->id,
86 $movePageResp->assertRedirect($page->getUrl());
87 $this->assertTrue($page->book->id == $newBook->id, 'Page parent is now the new book');
88 $this->assertTrue($page->chapter === null, 'Page has no parent chapter');
90 $newBookResp = $this->get($newBook->getUrl());
91 $newBookResp->assertSee($page->name);
94 public function test_page_move_requires_create_permissions_on_parent()
96 $page = Page::query()->first();
97 $currentBook = $page->book;
98 $newBook = Book::query()->where('id', '!=', $currentBook->id)->first();
99 $editor = $this->getEditor();
101 $this->setEntityRestrictions($newBook, ['view', 'update', 'delete'], $editor->roles->all());
103 $movePageResp = $this->actingAs($editor)->put($page->getUrl('/move'), [
104 'entity_selection' => 'book:' . $newBook->id,
106 $this->assertPermissionError($movePageResp);
108 $this->setEntityRestrictions($newBook, ['view', 'update', 'delete', 'create'], $editor->roles->all());
109 $movePageResp = $this->put($page->getUrl('/move'), [
110 'entity_selection' => 'book:' . $newBook->id,
113 $page = Page::find($page->id);
114 $movePageResp->assertRedirect($page->getUrl());
116 $this->assertTrue($page->book->id == $newBook->id, 'Page book is now the new book');
119 public function test_page_move_requires_delete_permissions()
121 $page = Page::first();
122 $currentBook = $page->book;
123 $newBook = Book::where('id', '!=', $currentBook->id)->first();
124 $editor = $this->getEditor();
126 $this->setEntityRestrictions($newBook, ['view', 'update', 'create', 'delete'], $editor->roles->all());
127 $this->setEntityRestrictions($page, ['view', 'update', 'create'], $editor->roles->all());
129 $movePageResp = $this->actingAs($editor)->put($page->getUrl('/move'), [
130 'entity_selection' => 'book:' . $newBook->id,
132 $this->assertPermissionError($movePageResp);
133 $pageView = $this->get($page->getUrl());
134 $pageView->assertDontSee($page->getUrl('/move'));
136 $this->setEntityRestrictions($page, ['view', 'update', 'create', 'delete'], $editor->roles->all());
137 $movePageResp = $this->put($page->getUrl('/move'), [
138 'entity_selection' => 'book:' . $newBook->id,
141 $page = Page::find($page->id);
142 $movePageResp->assertRedirect($page->getUrl());
143 $this->assertTrue($page->book->id == $newBook->id, 'Page book is now the new book');
146 public function test_chapter_move()
148 $chapter = Chapter::first();
149 $currentBook = $chapter->book;
150 $pageToCheck = $chapter->pages->first();
151 $newBook = Book::where('id', '!=', $currentBook->id)->first();
153 $chapterMoveResp = $this->asEditor()->get($chapter->getUrl('/move'));
154 $chapterMoveResp->assertSee('Move Chapter');
156 $moveChapterResp = $this->put($chapter->getUrl('/move'), [
157 'entity_selection' => 'book:' . $newBook->id,
160 $chapter = Chapter::find($chapter->id);
161 $moveChapterResp->assertRedirect($chapter->getUrl());
162 $this->assertTrue($chapter->book->id === $newBook->id, 'Chapter Book is now the new book');
164 $newBookResp = $this->get($newBook->getUrl());
165 $newBookResp->assertSee('moved chapter');
166 $newBookResp->assertSee($chapter->name);
168 $pageToCheck = Page::find($pageToCheck->id);
169 $this->assertTrue($pageToCheck->book_id === $newBook->id, 'Chapter child page\'s book id has changed to the new book');
170 $pageCheckResp = $this->get($pageToCheck->getUrl());
171 $pageCheckResp->assertSee($newBook->name);
174 public function test_chapter_move_requires_delete_permissions()
176 $chapter = Chapter::first();
177 $currentBook = $chapter->book;
178 $newBook = Book::where('id', '!=', $currentBook->id)->first();
179 $editor = $this->getEditor();
181 $this->setEntityRestrictions($newBook, ['view', 'update', 'create', 'delete'], $editor->roles->all());
182 $this->setEntityRestrictions($chapter, ['view', 'update', 'create'], $editor->roles->all());
184 $moveChapterResp = $this->actingAs($editor)->put($chapter->getUrl('/move'), [
185 'entity_selection' => 'book:' . $newBook->id,
187 $this->assertPermissionError($moveChapterResp);
188 $pageView = $this->get($chapter->getUrl());
189 $pageView->assertDontSee($chapter->getUrl('/move'));
191 $this->setEntityRestrictions($chapter, ['view', 'update', 'create', 'delete'], $editor->roles->all());
192 $moveChapterResp = $this->put($chapter->getUrl('/move'), [
193 'entity_selection' => 'book:' . $newBook->id,
196 $chapter = Chapter::find($chapter->id);
197 $moveChapterResp->assertRedirect($chapter->getUrl());
198 $this->assertTrue($chapter->book->id == $newBook->id, 'Page book is now the new book');
201 public function test_chapter_move_changes_book_for_deleted_pages_within()
203 /** @var Chapter $chapter */
204 $chapter = Chapter::query()->whereHas('pages')->first();
205 $currentBook = $chapter->book;
206 $pageToCheck = $chapter->pages->first();
207 $newBook = Book::query()->where('id', '!=', $currentBook->id)->first();
209 $pageToCheck->delete();
211 $this->asEditor()->put($chapter->getUrl('/move'), [
212 'entity_selection' => 'book:' . $newBook->id,
215 $pageToCheck->refresh();
216 $this->assertEquals($newBook->id, $pageToCheck->book_id);
219 public function test_book_sort()
221 $oldBook = Book::query()->first();
222 $chapterToMove = $this->newChapter(['name' => 'chapter to move'], $oldBook);
223 $newBook = $this->newBook(['name' => 'New sort book']);
224 $pagesToMove = Page::query()->take(5)->get();
226 // Create request data
229 'id' => $chapterToMove->id,
231 'parentChapter' => false,
233 'book' => $newBook->id,
236 foreach ($pagesToMove as $index => $page) {
240 'parentChapter' => $index === count($pagesToMove) - 1 ? $chapterToMove->id : false,
242 'book' => $newBook->id,
246 $sortResp = $this->asEditor()->put($newBook->getUrl() . '/sort', ['sort-tree' => json_encode($reqData)]);
247 $sortResp->assertRedirect($newBook->getUrl());
248 $sortResp->assertStatus(302);
249 $this->assertDatabaseHas('chapters', [
250 'id' => $chapterToMove->id,
251 'book_id' => $newBook->id,
254 $this->assertTrue($newBook->chapters()->count() === 1);
255 $this->assertTrue($newBook->chapters()->first()->pages()->count() === 1);
257 $checkPage = $pagesToMove[1];
258 $checkResp = $this->get(Page::find($checkPage->id)->getUrl());
259 $checkResp->assertSee($newBook->name);