]> BookStack Code Mirror - bookstack/blob - tests/Entity/ConvertTest.php
Added tests for content conversion action permissions
[bookstack] / tests / Entity / ConvertTest.php
1 <?php
2
3 namespace Tests\Entity;
4
5 use BookStack\Actions\ActivityType;
6 use BookStack\Actions\Tag;
7 use BookStack\Entities\Models\Book;
8 use BookStack\Entities\Models\Bookshelf;
9 use BookStack\Entities\Models\Chapter;
10 use BookStack\Entities\Models\Page;
11 use Tests\TestCase;
12
13 class ConvertTest extends TestCase
14 {
15
16     public function test_chapter_edit_view_shows_convert_option()
17     {
18         /** @var Chapter $chapter */
19         $chapter = Chapter::query()->first();
20
21         $resp = $this->asEditor()->get($chapter->getUrl('/edit'));
22         $resp->assertSee('Convert to Book');
23         $resp->assertSee('Convert Chapter');
24         $resp->assertElementExists('form[action$="/convert-to-book"] button');
25     }
26
27     public function test_convert_chapter_to_book()
28     {
29         /** @var Chapter $chapter */
30         $chapter = Chapter::query()->whereHas('pages')->first();
31         $chapter->tags()->save(new Tag(['name' => 'Category', 'value' => 'Penguins']));
32         /** @var Page $childPage */
33         $childPage = $chapter->pages()->first();
34
35         $resp = $this->asEditor()->post($chapter->getUrl('/convert-to-book'));
36         $resp->assertRedirectContains('/books/');
37
38         /** @var Book $newBook */
39         $newBook = Book::query()->orderBy('id', 'desc')->first();
40
41         $this->assertDatabaseMissing('chapters', ['id' => $chapter->id]);
42         $this->assertDatabaseHas('pages', ['id' => $childPage->id, 'book_id' => $newBook->id, 'chapter_id' => 0]);
43         $this->assertCount(1, $newBook->tags);
44         $this->assertEquals('Category', $newBook->tags->first()->name);
45         $this->assertEquals('Penguins', $newBook->tags->first()->value);
46         $this->assertEquals($chapter->name, $newBook->name);
47         $this->assertEquals($chapter->description, $newBook->description);
48
49         $this->assertActivityExists(ActivityType::BOOK_CREATE_FROM_CHAPTER, $newBook);
50     }
51
52     public function test_convert_chapter_to_book_requires_permissions()
53     {
54         /** @var Chapter $chapter */
55         $chapter = Chapter::query()->first();
56         $user = $this->getViewer();
57
58         $permissions = ['chapter-delete-all', 'book-create-all', 'chapter-update-all'];
59         $this->giveUserPermissions($user, $permissions);
60
61         foreach ($permissions as $permission) {
62             $this->removePermissionFromUser($user, $permission);
63             $resp = $this->actingAs($user)->post($chapter->getUrl('/convert-to-book'));
64             $this->assertPermissionError($resp);
65             $this->giveUserPermissions($user, [$permission]);
66         }
67
68         $resp = $this->actingAs($user)->post($chapter->getUrl('/convert-to-book'));
69         $this->assertNotPermissionError($resp);
70         $resp->assertRedirect();
71     }
72
73     public function test_book_edit_view_shows_convert_option()
74     {
75         $book = Book::query()->first();
76
77         $resp = $this->asEditor()->get($book->getUrl('/edit'));
78         $resp->assertSee('Convert to Shelf');
79         $resp->assertSee('Convert Book');
80         $resp->assertSee('Note that permissions on shelves do not auto-cascade to content');
81         $resp->assertElementExists('form[action$="/convert-to-shelf"] button');
82     }
83
84     public function test_book_convert_to_shelf()
85     {
86         /** @var Book $book */
87         $book = Book::query()->whereHas('directPages')->whereHas('chapters')->firstOrFail();
88         $book->tags()->save(new Tag(['name' => 'Category', 'value' => 'Ducks']));
89         /** @var Page $childPage */
90         $childPage = $book->directPages()->first();
91         /** @var Chapter $childChapter */
92         $childChapter = $book->chapters()->whereHas('pages')->firstOrFail();
93         /** @var Page $chapterChildPage */
94         $chapterChildPage = $childChapter->pages()->firstOrFail();
95         $bookChapterCount = $book->chapters()->count();
96         $systemBookCount = Book::query()->count();
97
98         // Run conversion
99         $resp = $this->asEditor()->post($book->getUrl('/convert-to-shelf'));
100
101         /** @var Bookshelf $newShelf */
102         $newShelf = Bookshelf::query()->orderBy('id', 'desc')->first();
103
104         // Checks for new shelf
105         $resp->assertRedirectContains('/shelves/');
106         $this->assertDatabaseMissing('chapters', ['id' => $childChapter->id]);
107         $this->assertCount(1, $newShelf->tags);
108         $this->assertEquals('Category', $newShelf->tags->first()->name);
109         $this->assertEquals('Ducks', $newShelf->tags->first()->value);
110         $this->assertEquals($book->name, $newShelf->name);
111         $this->assertEquals($book->description, $newShelf->description);
112         $this->assertEquals($newShelf->books()->count(), $bookChapterCount + 1);
113         $this->assertEquals($systemBookCount + $bookChapterCount, Book::query()->count());
114         $this->assertActivityExists(ActivityType::BOOKSHELF_CREATE_FROM_BOOK, $newShelf);
115
116         // Checks for old book to contain child pages
117         $this->assertDatabaseHas('books', ['id' => $book->id, 'name' => $book->name . ' Pages']);
118         $this->assertDatabaseHas('pages', ['id' => $childPage->id, 'book_id' => $book->id, 'chapter_id' => 0]);
119
120         // Checks for nested page
121         $chapterChildPage->refresh();
122         $this->assertEquals(0, $chapterChildPage->chapter_id);
123         $this->assertEquals($childChapter->name, $chapterChildPage->book->name);
124     }
125
126     public function test_book_convert_to_shelf_requires_permissions()
127     {
128         /** @var Book $book */
129         $book = Book::query()->first();
130         $user = $this->getViewer();
131
132         $permissions = ['book-delete-all', 'bookshelf-create-all', 'book-update-all', 'book-create-all'];
133         $this->giveUserPermissions($user, $permissions);
134
135         foreach ($permissions as $permission) {
136             $this->removePermissionFromUser($user, $permission);
137             $resp = $this->actingAs($user)->post($book->getUrl('/convert-to-shelf'));
138             $this->assertPermissionError($resp);
139             $this->giveUserPermissions($user, [$permission]);
140         }
141
142         $resp = $this->actingAs($user)->post($book->getUrl('/convert-to-shelf'));
143         $this->assertNotPermissionError($resp);
144         $resp->assertRedirect();
145     }
146
147 }