]> BookStack Code Mirror - bookstack/blob - tests/Entity/ChapterTest.php
Opensearch: Fixed XML declaration when php short tags enabled
[bookstack] / tests / Entity / ChapterTest.php
1 <?php
2
3 namespace Tests\Entity;
4
5 use BookStack\Entities\Models\Book;
6 use BookStack\Entities\Models\Chapter;
7 use BookStack\Entities\Models\Page;
8 use Tests\TestCase;
9
10 class ChapterTest extends TestCase
11 {
12     public function test_create()
13     {
14         $book = $this->entities->book();
15
16         $chapter = Chapter::factory()->make([
17             'name' => 'My First Chapter',
18         ]);
19
20         $resp = $this->asEditor()->get($book->getUrl());
21         $this->withHtml($resp)->assertElementContains('a[href="' . $book->getUrl('/create-chapter') . '"]', 'New Chapter');
22
23         $resp = $this->get($book->getUrl('/create-chapter'));
24         $this->withHtml($resp)->assertElementContains('form[action="' . $book->getUrl('/create-chapter') . '"][method="POST"]', 'Save Chapter');
25
26         $resp = $this->post($book->getUrl('/create-chapter'), $chapter->only('name', 'description_html'));
27         $resp->assertRedirect($book->getUrl('/chapter/my-first-chapter'));
28
29         $resp = $this->get($book->getUrl('/chapter/my-first-chapter'));
30         $resp->assertSee($chapter->name);
31         $resp->assertSee($chapter->description_html, false);
32     }
33
34     public function test_show_view_displays_description_if_no_description_html_set()
35     {
36         $chapter = $this->entities->chapter();
37         $chapter->description_html = '';
38         $chapter->description = "My great\ndescription\n\nwith newlines";
39         $chapter->save();
40
41         $resp = $this->asEditor()->get($chapter->getUrl());
42         $resp->assertSee("<p>My great<br>\ndescription<br>\n<br>\nwith newlines</p>", false);
43     }
44
45     public function test_delete()
46     {
47         $chapter = Chapter::query()->whereHas('pages')->first();
48         $this->assertNull($chapter->deleted_at);
49         $pageCount = $chapter->pages()->count();
50
51         $deleteViewReq = $this->asEditor()->get($chapter->getUrl('/delete'));
52         $deleteViewReq->assertSeeText('Are you sure you want to delete this chapter?');
53
54         $deleteReq = $this->delete($chapter->getUrl());
55         $deleteReq->assertRedirect($chapter->getParent()->getUrl());
56         $this->assertActivityExists('chapter_delete', $chapter);
57
58         $chapter->refresh();
59         $this->assertNotNull($chapter->deleted_at);
60
61         $this->assertTrue($chapter->pages()->count() === 0);
62         $this->assertTrue($chapter->pages()->withTrashed()->count() === $pageCount);
63         $this->assertTrue($chapter->deletions()->count() === 1);
64
65         $redirectReq = $this->get($deleteReq->baseResponse->headers->get('location'));
66         $this->assertNotificationContains($redirectReq, 'Chapter Successfully Deleted');
67     }
68
69     public function test_show_view_has_copy_button()
70     {
71         $chapter = $this->entities->chapter();
72
73         $resp = $this->asEditor()->get($chapter->getUrl());
74         $this->withHtml($resp)->assertElementContains("a[href$=\"{$chapter->getUrl('/copy')}\"]", 'Copy');
75     }
76
77     public function test_copy_view()
78     {
79         $chapter = $this->entities->chapter();
80
81         $resp = $this->asEditor()->get($chapter->getUrl('/copy'));
82         $resp->assertOk();
83         $resp->assertSee('Copy Chapter');
84         $this->withHtml($resp)->assertElementExists("input[name=\"name\"][value=\"{$chapter->name}\"]");
85         $this->withHtml($resp)->assertElementExists('input[name="entity_selection"]');
86     }
87
88     public function test_copy()
89     {
90         /** @var Chapter $chapter */
91         $chapter = Chapter::query()->whereHas('pages')->first();
92         /** @var Book $otherBook */
93         $otherBook = Book::query()->where('id', '!=', $chapter->book_id)->first();
94
95         $resp = $this->asEditor()->post($chapter->getUrl('/copy'), [
96             'name'             => 'My copied chapter',
97             'entity_selection' => 'book:' . $otherBook->id,
98         ]);
99
100         /** @var Chapter $newChapter */
101         $newChapter = Chapter::query()->where('name', '=', 'My copied chapter')->first();
102
103         $resp->assertRedirect($newChapter->getUrl());
104         $this->assertEquals($otherBook->id, $newChapter->book_id);
105         $this->assertEquals($chapter->pages->count(), $newChapter->pages->count());
106     }
107
108     public function test_copy_does_not_copy_non_visible_pages()
109     {
110         $chapter = $this->entities->chapterHasPages();
111
112         // Hide pages to all non-admin roles
113         /** @var Page $page */
114         foreach ($chapter->pages as $page) {
115             $this->permissions->setEntityPermissions($page, [], []);
116         }
117
118         $this->asEditor()->post($chapter->getUrl('/copy'), [
119             'name' => 'My copied chapter',
120         ]);
121
122         /** @var Chapter $newChapter */
123         $newChapter = Chapter::query()->where('name', '=', 'My copied chapter')->first();
124         $this->assertEquals(0, $newChapter->pages()->count());
125     }
126
127     public function test_copy_does_not_copy_pages_if_user_cant_page_create()
128     {
129         $chapter = $this->entities->chapterHasPages();
130         $viewer = $this->users->viewer();
131         $this->permissions->grantUserRolePermissions($viewer, ['chapter-create-all']);
132
133         // Lacking permission results in no copied pages
134         $this->actingAs($viewer)->post($chapter->getUrl('/copy'), [
135             'name' => 'My copied chapter',
136         ]);
137
138         /** @var Chapter $newChapter */
139         $newChapter = Chapter::query()->where('name', '=', 'My copied chapter')->first();
140         $this->assertEquals(0, $newChapter->pages()->count());
141
142         $this->permissions->grantUserRolePermissions($viewer, ['page-create-all']);
143
144         // Having permission rules in copied pages
145         $this->actingAs($viewer)->post($chapter->getUrl('/copy'), [
146             'name' => 'My copied again chapter',
147         ]);
148
149         /** @var Chapter $newChapter2 */
150         $newChapter2 = Chapter::query()->where('name', '=', 'My copied again chapter')->first();
151         $this->assertEquals($chapter->pages()->count(), $newChapter2->pages()->count());
152     }
153
154     public function test_sort_book_action_visible_if_permissions_allow()
155     {
156         $chapter = $this->entities->chapter();
157
158         $resp = $this->actingAs($this->users->viewer())->get($chapter->getUrl());
159         $this->withHtml($resp)->assertLinkNotExists($chapter->book->getUrl('sort'));
160
161         $resp = $this->asEditor()->get($chapter->getUrl());
162         $this->withHtml($resp)->assertLinkExists($chapter->book->getUrl('sort'));
163     }
164 }