Inheritance: extends Entity
Exemple #1
0
 public function test_draft_pages_not_visible_by_others()
 {
     $book = \BookStack\Book::first();
     $chapter = $book->chapters->first();
     $newUser = $this->getEditor();
     $this->actingAs($newUser)->visit('/')->visit($book->getUrl() . '/page/create')->visit($chapter->getUrl() . '/create-page')->visit($book->getUrl())->seeInElement('.page-list', 'New Page');
     $this->asAdmin()->visit($book->getUrl())->dontSeeInElement('.page-list', 'New Page')->visit($chapter->getUrl())->dontSeeInElement('.page-list', 'New Page');
 }
Exemple #2
0
 public function testBooksViewable()
 {
     $this->setSettings(['app-public' => 'true']);
     $books = \BookStack\Book::orderBy('name', 'asc')->take(10)->get();
     $bookToVisit = $books[1];
     // Check books index page is showing
     $this->visit('/books')->seeStatusCode(200)->see($books[0]->name)->click($bookToVisit->name)->seePageIs($bookToVisit->getUrl())->see($bookToVisit->name)->see($bookToVisit->chapters()->first()->name);
 }
Exemple #3
0
 public function bookCreation()
 {
     $book = factory(\BookStack\Book::class)->make(['name' => 'My First Book']);
     $this->asAdmin()->visit('/books')->click('Add new book')->seePageIs('/books/create')->type($book->name, '#name')->type($book->description, '#description')->press('Save Book')->seePageIs('/books/my-first-book')->see($book->name)->see($book->description);
     // Ensure duplicate names are given different slugs
     $this->asAdmin()->visit('/books/create')->type($book->name, '#name')->type($book->description, '#description')->press('Save Book')->seePageIs('/books/my-first-book-2');
     $book = \BookStack\Book::where('slug', '=', 'my-first-book')->first();
     return $book;
 }
Exemple #4
0
 public function bookCreation()
 {
     $book = factory(\BookStack\Book::class)->make(['name' => 'My First Book']);
     $this->asAdmin()->visit('/books')->click('Add new book')->seePageIs('/books/create')->type($book->name, '#name')->type($book->description, '#description')->press('Save Book')->seePageIs('/books/my-first-book')->see($book->name)->see($book->description);
     // Ensure duplicate names are given different slugs
     $this->asAdmin()->visit('/books/create')->type($book->name, '#name')->type($book->description, '#description')->press('Save Book');
     $expectedPattern = '/\\/books\\/my-first-book-[0-9a-zA-Z]{3}/';
     $this->assertRegExp($expectedPattern, $this->currentUri, "Did not land on expected page [{$expectedPattern}].\n");
     $book = \BookStack\Book::where('slug', '=', 'my-first-book')->first();
     return $book;
 }
Exemple #5
0
 public function test_chapter_move()
 {
     $chapter = \BookStack\Chapter::first();
     $currentBook = $chapter->book;
     $pageToCheck = $chapter->pages->first();
     $newBook = \BookStack\Book::where('id', '!=', $currentBook->id)->first();
     $this->asAdmin()->visit($chapter->getUrl() . '/move')->see('Move Chapter')->see($chapter->name)->type('book:' . $newBook->id, 'entity_selection')->press('Move Chapter');
     $chapter = \BookStack\Chapter::find($chapter->id);
     $this->seePageIs($chapter->getUrl());
     $this->assertTrue($chapter->book->id === $newBook->id, 'Chapter Book is now the new book');
     $this->visit($newBook->getUrl())->seeInNthElement('.activity-list-item', 0, 'moved chapter')->seeInNthElement('.activity-list-item', 0, $chapter->name);
     $pageToCheck = \BookStack\Page::find($pageToCheck->id);
     $this->assertTrue($pageToCheck->book_id === $newBook->id, 'Chapter child page\'s book id has changed to the new book');
     $this->visit($pageToCheck->getUrl())->see($newBook->name);
 }
 public function test_books_search_listing()
 {
     $book = \BookStack\Book::all()->last();
     $this->asAdmin()->visit('/search/books?term=' . $book->name)->see('Book Search Results')->see('.entity-list', $book->name);
 }
Exemple #7
0
 /**
  * Get all child objects of a book.
  * Returns a sorted collection of Pages and Chapters.
  * Loads the bookslug onto child elements to prevent access database access for getting the slug.
  * @param Book $book
  * @return mixed
  */
 public function getChildren(Book $book)
 {
     $pages = $book->pages()->where('chapter_id', '=', 0)->get();
     $chapters = $book->chapters()->with('pages')->get();
     $children = $pages->merge($chapters);
     $bookSlug = $book->slug;
     $children->each(function ($child) use($bookSlug) {
         $child->setAttribute('bookSlug', $bookSlug);
         if ($child->isA('chapter')) {
             $child->pages->each(function ($page) use($bookSlug) {
                 $page->setAttribute('bookSlug', $bookSlug);
             });
         }
     });
     return $children->sortBy('priority');
 }
Exemple #8
0
 public function test_empty_book_search_redirects_back()
 {
     $book = \BookStack\Book::all()->first();
     $this->asAdmin()->visit('/books')->visit('/search/book/' . $book->id . '?term=')->seePageIs('/books');
 }
Exemple #9
0
 public function testPageSearch()
 {
     $book = \BookStack\Book::all()->first();
     $page = $book->pages->first();
     $this->asAdmin()->visit('/')->type($page->name, 'term')->press('header-search-box-button')->see('Search Results')->see($page->name)->click($page->name)->seePageIs($page->getUrl());
 }
Exemple #10
0
 /**
  * Get all child objects of a book.
  * Returns a sorted collection of Pages and Chapters.
  * Loads the book slug onto child elements to prevent access database access for getting the slug.
  * @param Book $book
  * @param bool $filterDrafts
  * @return mixed
  */
 public function getChildren(Book $book, $filterDrafts = false)
 {
     $pageQuery = $book->pages()->where('chapter_id', '=', 0);
     $pageQuery = $this->permissionService->enforcePageRestrictions($pageQuery, 'view');
     if ($filterDrafts) {
         $pageQuery = $pageQuery->where('draft', '=', false);
     }
     $pages = $pageQuery->get();
     $chapterQuery = $book->chapters()->with(['pages' => function ($query) use($filterDrafts) {
         $this->permissionService->enforcePageRestrictions($query, 'view');
         if ($filterDrafts) {
             $query->where('draft', '=', false);
         }
     }]);
     $chapterQuery = $this->permissionService->enforceChapterRestrictions($chapterQuery, 'view');
     $chapters = $chapterQuery->get();
     $children = $pages->values();
     foreach ($chapters as $chapter) {
         $children->push($chapter);
     }
     $bookSlug = $book->slug;
     $children->each(function ($child) use($bookSlug) {
         $child->setAttribute('bookSlug', $bookSlug);
         if ($child->isA('chapter')) {
             $child->pages->each(function ($page) use($bookSlug) {
                 $page->setAttribute('bookSlug', $bookSlug);
             });
             $child->pages = $child->pages->sortBy(function ($child, $key) {
                 $score = $child->priority;
                 if ($child->draft) {
                     $score -= 100;
                 }
                 return $score;
             });
         }
     });
     // Sort items with drafts first then by priority.
     return $children->sortBy(function ($child, $key) {
         $score = $child->priority;
         if ($child->isA('page') && $child->draft) {
             $score -= 100;
         }
         return $score;
     });
 }
Exemple #11
0
 /**
  * Save a new page into the system.
  * Input validation must be done beforehand.
  * @param array $input
  * @param Book  $book
  * @param int   $chapterId
  * @return Page
  */
 public function saveNew(array $input, Book $book, $chapterId = null)
 {
     $page = $this->newFromInput($input);
     $page->slug = $this->findSuitableSlug($page->name, $book->id);
     if ($chapterId) {
         $page->chapter_id = $chapterId;
     }
     $page->html = $this->formatHtml($input['html']);
     $page->text = strip_tags($page->html);
     $page->created_by = auth()->user()->id;
     $page->updated_by = auth()->user()->id;
     $book->pages()->save($page);
     return $page;
 }
Exemple #12
0
 public function test_page_create_all_permissions()
 {
     $book = \BookStack\Book::take(1)->get()->first();
     $chapter = \BookStack\Chapter::take(1)->get()->first();
     $baseUrl = $book->getUrl() . '/page';
     $createUrl = $baseUrl . '/create';
     $createUrlChapter = $chapter->getUrl() . '/create-page';
     $accessUrls = [$createUrl, $createUrlChapter];
     foreach ($accessUrls as $url) {
         $this->actingAs($this->user)->visit('/')->visit($url)->seePageIs('/');
     }
     $this->checkAccessPermission('page-create-all', [], [$book->getUrl() => 'New Page', $chapter->getUrl() => 'New Page']);
     $this->giveUserPermissions($this->user, ['page-create-all']);
     foreach ($accessUrls as $index => $url) {
         $this->actingAs($this->user)->visit('/')->visit($url);
         $expectedUrl = \BookStack\Page::where('draft', '=', true)->orderBy('id', 'desc')->first()->getUrl();
         $this->seePageIs($expectedUrl);
     }
     $this->visit($baseUrl . '/create')->type('test page', 'name')->type('page desc', 'html')->press('Save Page')->seePageIs($baseUrl . '/test-page');
     $this->visit($chapter->getUrl() . '/create-page')->type('new test page', 'name')->type('page desc', 'html')->press('Save Page')->seePageIs($baseUrl . '/new-test-page');
 }
Exemple #13
0
 /**
  * Get a new draft page instance.
  * @param Book $book
  * @param Chapter|bool $chapter
  * @return static
  */
 public function getDraftPage(Book $book, $chapter = false)
 {
     $page = $this->page->newInstance();
     $page->name = 'New Page';
     $page->created_by = auth()->user()->id;
     $page->updated_by = auth()->user()->id;
     $page->draft = true;
     if ($chapter) {
         $page->chapter_id = $chapter->id;
     }
     $book->pages()->save($page);
     $this->permissionService->buildJointPermissionsForEntity($page);
     return $page;
 }
 public function test_popular_books()
 {
     $books = \BookStack\Book::all()->take(10);
     $this->asAdmin()->visit('/books')->dontSeeInElement('#popular', $books[0]->name)->dontSeeInElement('#popular', $books[1]->name)->visit($books[0]->getUrl())->visit($books[1]->getUrl())->visit($books[0]->getUrl())->visit('/books')->seeInNthElement('#popular .book', 0, $books[0]->name)->seeInNthElement('#popular .book', 1, $books[1]->name);
 }
Exemple #15
0
 /**
  * Create a new chapter from request input.
  * @param $input
  * @param Book $book
  * @return Chapter
  */
 public function createFromInput($input, Book $book)
 {
     $chapter = $this->chapter->newInstance($input);
     $chapter->slug = $this->findSuitableSlug($chapter->name, $book->id);
     $chapter->created_by = user()->id;
     $chapter->updated_by = user()->id;
     $chapter = $book->chapters()->save($chapter);
     $this->permissionService->buildJointPermissionsForEntity($chapter);
     return $chapter;
 }
 public function test_book_delete_restriction_override()
 {
     $book = \BookStack\Book::first();
     $bookPage = $book->pages->first();
     $bookChapter = $book->chapters->first();
     $bookUrl = $book->getUrl();
     $this->actingAs($this->viewer)->visit($bookUrl . '/delete')->dontSee('Delete Book');
     $this->setEntityRestrictions($book, ['view', 'update']);
     $this->forceVisit($bookUrl . '/delete')->see('You do not have permission')->seePageIs('/');
     $this->forceVisit($bookPage->getUrl() . '/delete')->see('You do not have permission')->seePageIs('/');
     $this->forceVisit($bookChapter->getUrl() . '/delete')->see('You do not have permission')->seePageIs('/');
     $this->setEntityRestrictions($book, ['view', 'delete']);
     $this->visit($bookUrl . '/delete')->seePageIs($bookUrl . '/delete')->see('Delete Book');
     $this->visit($bookPage->getUrl() . '/delete')->seePageIs($bookPage->getUrl() . '/delete')->see('Delete Page');
     $this->visit($bookChapter->getUrl() . '/delete')->see('Delete Chapter');
 }