| 
									
										
										
										
											2022-06-19 23:57:33 +08:00
										 |  |  | <?php | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | namespace Tests\Entity; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-05-18 00:56:55 +08:00
										 |  |  | use BookStack\Activity\ActivityType; | 
					
						
							|  |  |  | use BookStack\Activity\Models\Tag; | 
					
						
							| 
									
										
										
										
											2022-06-19 23:57:33 +08:00
										 |  |  | use BookStack\Entities\Models\Book; | 
					
						
							|  |  |  | use BookStack\Entities\Models\Bookshelf; | 
					
						
							|  |  |  | use BookStack\Entities\Models\Chapter; | 
					
						
							|  |  |  | use BookStack\Entities\Models\Page; | 
					
						
							|  |  |  | use Tests\TestCase; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | class ConvertTest extends TestCase | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     public function test_chapter_edit_view_shows_convert_option() | 
					
						
							|  |  |  |     { | 
					
						
							| 
									
										
										
										
											2022-09-30 00:31:38 +08:00
										 |  |  |         $chapter = $this->entities->chapter(); | 
					
						
							| 
									
										
										
										
											2022-06-19 23:57:33 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  |         $resp = $this->asEditor()->get($chapter->getUrl('/edit')); | 
					
						
							|  |  |  |         $resp->assertSee('Convert to Book'); | 
					
						
							|  |  |  |         $resp->assertSee('Convert Chapter'); | 
					
						
							| 
									
										
										
										
											2022-07-23 22:10:18 +08:00
										 |  |  |         $this->withHtml($resp)->assertElementExists('form[action$="/convert-to-book"] button'); | 
					
						
							| 
									
										
										
										
											2022-06-19 23:57:33 +08:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     public function test_convert_chapter_to_book() | 
					
						
							|  |  |  |     { | 
					
						
							| 
									
										
										
										
											2022-09-30 05:11:16 +08:00
										 |  |  |         $chapter = $this->entities->chapterHasPages(); | 
					
						
							| 
									
										
										
										
											2022-06-19 23:57:33 +08:00
										 |  |  |         $chapter->tags()->save(new Tag(['name' => 'Category', 'value' => 'Penguins'])); | 
					
						
							|  |  |  |         /** @var Page $childPage */ | 
					
						
							|  |  |  |         $childPage = $chapter->pages()->first(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         $resp = $this->asEditor()->post($chapter->getUrl('/convert-to-book')); | 
					
						
							|  |  |  |         $resp->assertRedirectContains('/books/'); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         /** @var Book $newBook */ | 
					
						
							|  |  |  |         $newBook = Book::query()->orderBy('id', 'desc')->first(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         $this->assertDatabaseMissing('chapters', ['id' => $chapter->id]); | 
					
						
							|  |  |  |         $this->assertDatabaseHas('pages', ['id' => $childPage->id, 'book_id' => $newBook->id, 'chapter_id' => 0]); | 
					
						
							|  |  |  |         $this->assertCount(1, $newBook->tags); | 
					
						
							|  |  |  |         $this->assertEquals('Category', $newBook->tags->first()->name); | 
					
						
							|  |  |  |         $this->assertEquals('Penguins', $newBook->tags->first()->value); | 
					
						
							|  |  |  |         $this->assertEquals($chapter->name, $newBook->name); | 
					
						
							|  |  |  |         $this->assertEquals($chapter->description, $newBook->description); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         $this->assertActivityExists(ActivityType::BOOK_CREATE_FROM_CHAPTER, $newBook); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-06-20 01:12:36 +08:00
										 |  |  |     public function test_convert_chapter_to_book_requires_permissions() | 
					
						
							|  |  |  |     { | 
					
						
							| 
									
										
										
										
											2022-09-30 00:31:38 +08:00
										 |  |  |         $chapter = $this->entities->chapter(); | 
					
						
							| 
									
										
										
										
											2023-01-21 19:08:34 +08:00
										 |  |  |         $user = $this->users->viewer(); | 
					
						
							| 
									
										
										
										
											2022-06-20 01:12:36 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  |         $permissions = ['chapter-delete-all', 'book-create-all', 'chapter-update-all']; | 
					
						
							| 
									
										
										
										
											2023-01-21 19:08:34 +08:00
										 |  |  |         $this->permissions->grantUserRolePermissions($user, $permissions); | 
					
						
							| 
									
										
										
										
											2022-06-20 01:12:36 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  |         foreach ($permissions as $permission) { | 
					
						
							| 
									
										
										
										
											2023-01-21 19:08:34 +08:00
										 |  |  |             $this->permissions->removeUserRolePermissions($user, [$permission]); | 
					
						
							| 
									
										
										
										
											2022-06-20 01:12:36 +08:00
										 |  |  |             $resp = $this->actingAs($user)->post($chapter->getUrl('/convert-to-book')); | 
					
						
							|  |  |  |             $this->assertPermissionError($resp); | 
					
						
							| 
									
										
										
										
											2023-01-21 19:08:34 +08:00
										 |  |  |             $this->permissions->grantUserRolePermissions($user, [$permission]); | 
					
						
							| 
									
										
										
										
											2022-06-20 01:12:36 +08:00
										 |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         $resp = $this->actingAs($user)->post($chapter->getUrl('/convert-to-book')); | 
					
						
							|  |  |  |         $this->assertNotPermissionError($resp); | 
					
						
							|  |  |  |         $resp->assertRedirect(); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-06-19 23:57:33 +08:00
										 |  |  |     public function test_book_edit_view_shows_convert_option() | 
					
						
							|  |  |  |     { | 
					
						
							| 
									
										
										
										
											2022-09-30 00:31:38 +08:00
										 |  |  |         $book = $this->entities->book(); | 
					
						
							| 
									
										
										
										
											2022-06-19 23:57:33 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  |         $resp = $this->asEditor()->get($book->getUrl('/edit')); | 
					
						
							|  |  |  |         $resp->assertSee('Convert to Shelf'); | 
					
						
							|  |  |  |         $resp->assertSee('Convert Book'); | 
					
						
							|  |  |  |         $resp->assertSee('Note that permissions on shelves do not auto-cascade to content'); | 
					
						
							| 
									
										
										
										
											2022-07-23 22:10:18 +08:00
										 |  |  |         $this->withHtml($resp)->assertElementExists('form[action$="/convert-to-shelf"] button'); | 
					
						
							| 
									
										
										
										
											2022-06-19 23:57:33 +08:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     public function test_book_convert_to_shelf() | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         /** @var Book $book */ | 
					
						
							|  |  |  |         $book = Book::query()->whereHas('directPages')->whereHas('chapters')->firstOrFail(); | 
					
						
							|  |  |  |         $book->tags()->save(new Tag(['name' => 'Category', 'value' => 'Ducks'])); | 
					
						
							|  |  |  |         /** @var Page $childPage */ | 
					
						
							|  |  |  |         $childPage = $book->directPages()->first(); | 
					
						
							|  |  |  |         /** @var Chapter $childChapter */ | 
					
						
							|  |  |  |         $childChapter = $book->chapters()->whereHas('pages')->firstOrFail(); | 
					
						
							|  |  |  |         /** @var Page $chapterChildPage */ | 
					
						
							|  |  |  |         $chapterChildPage = $childChapter->pages()->firstOrFail(); | 
					
						
							|  |  |  |         $bookChapterCount = $book->chapters()->count(); | 
					
						
							|  |  |  |         $systemBookCount = Book::query()->count(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         // Run conversion
 | 
					
						
							|  |  |  |         $resp = $this->asEditor()->post($book->getUrl('/convert-to-shelf')); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         /** @var Bookshelf $newShelf */ | 
					
						
							|  |  |  |         $newShelf = Bookshelf::query()->orderBy('id', 'desc')->first(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         // Checks for new shelf
 | 
					
						
							|  |  |  |         $resp->assertRedirectContains('/shelves/'); | 
					
						
							|  |  |  |         $this->assertDatabaseMissing('chapters', ['id' => $childChapter->id]); | 
					
						
							|  |  |  |         $this->assertCount(1, $newShelf->tags); | 
					
						
							|  |  |  |         $this->assertEquals('Category', $newShelf->tags->first()->name); | 
					
						
							|  |  |  |         $this->assertEquals('Ducks', $newShelf->tags->first()->value); | 
					
						
							|  |  |  |         $this->assertEquals($book->name, $newShelf->name); | 
					
						
							|  |  |  |         $this->assertEquals($book->description, $newShelf->description); | 
					
						
							|  |  |  |         $this->assertEquals($newShelf->books()->count(), $bookChapterCount + 1); | 
					
						
							|  |  |  |         $this->assertEquals($systemBookCount + $bookChapterCount, Book::query()->count()); | 
					
						
							|  |  |  |         $this->assertActivityExists(ActivityType::BOOKSHELF_CREATE_FROM_BOOK, $newShelf); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         // Checks for old book to contain child pages
 | 
					
						
							|  |  |  |         $this->assertDatabaseHas('books', ['id' => $book->id, 'name' => $book->name . ' Pages']); | 
					
						
							|  |  |  |         $this->assertDatabaseHas('pages', ['id' => $childPage->id, 'book_id' => $book->id, 'chapter_id' => 0]); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         // Checks for nested page
 | 
					
						
							|  |  |  |         $chapterChildPage->refresh(); | 
					
						
							|  |  |  |         $this->assertEquals(0, $chapterChildPage->chapter_id); | 
					
						
							|  |  |  |         $this->assertEquals($childChapter->name, $chapterChildPage->book->name); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-06-20 01:12:36 +08:00
										 |  |  |     public function test_book_convert_to_shelf_requires_permissions() | 
					
						
							|  |  |  |     { | 
					
						
							| 
									
										
										
										
											2022-09-30 00:31:38 +08:00
										 |  |  |         $book = $this->entities->book(); | 
					
						
							| 
									
										
										
										
											2023-01-21 19:08:34 +08:00
										 |  |  |         $user = $this->users->viewer(); | 
					
						
							| 
									
										
										
										
											2022-06-20 01:12:36 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  |         $permissions = ['book-delete-all', 'bookshelf-create-all', 'book-update-all', 'book-create-all']; | 
					
						
							| 
									
										
										
										
											2023-01-21 19:08:34 +08:00
										 |  |  |         $this->permissions->grantUserRolePermissions($user, $permissions); | 
					
						
							| 
									
										
										
										
											2022-06-20 01:12:36 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  |         foreach ($permissions as $permission) { | 
					
						
							| 
									
										
										
										
											2023-01-21 19:08:34 +08:00
										 |  |  |             $this->permissions->removeUserRolePermissions($user, [$permission]); | 
					
						
							| 
									
										
										
										
											2022-06-20 01:12:36 +08:00
										 |  |  |             $resp = $this->actingAs($user)->post($book->getUrl('/convert-to-shelf')); | 
					
						
							|  |  |  |             $this->assertPermissionError($resp); | 
					
						
							| 
									
										
										
										
											2023-01-21 19:08:34 +08:00
										 |  |  |             $this->permissions->grantUserRolePermissions($user, [$permission]); | 
					
						
							| 
									
										
										
										
											2022-06-20 01:12:36 +08:00
										 |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         $resp = $this->actingAs($user)->post($book->getUrl('/convert-to-shelf')); | 
					
						
							|  |  |  |         $this->assertNotPermissionError($resp); | 
					
						
							|  |  |  |         $resp->assertRedirect(); | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2022-06-20 01:14:53 +08:00
										 |  |  | } |