+ public function test_bookshelf_update_restriction_override()
+ {
+ $shelf = Bookshelf::first();
+
+ $this->actingAs($this->viewer)
+ ->visit($shelf->getUrl('/edit'))
+ ->dontSee('Edit Book');
+
+ $this->setEntityRestrictions($shelf, ['view', 'delete']);
+
+ $this->forceVisit($shelf->getUrl('/edit'))
+ ->see('You do not have permission')->seePageIs('/');
+
+ $this->setEntityRestrictions($shelf, ['view', 'update']);
+
+ $this->visit($shelf->getUrl('/edit'))
+ ->seePageIs($shelf->getUrl('/edit'));
+ }
+
+ public function test_bookshelf_delete_restriction_override()
+ {
+ $shelf = Bookshelf::first();
+
+ $this->actingAs($this->viewer)
+ ->visit($shelf->getUrl('/delete'))
+ ->dontSee('Delete Book');
+
+ $this->setEntityRestrictions($shelf, ['view', 'update']);
+
+ $this->forceVisit($shelf->getUrl('/delete'))
+ ->see('You do not have permission')->seePageIs('/');
+
+ $this->setEntityRestrictions($shelf, ['view', 'delete']);
+
+ $this->visit($shelf->getUrl('/delete'))
+ ->seePageIs($shelf->getUrl('/delete'))->see('Delete Book');
+ }
+
+ public function test_book_create_restriction_override()
+ {
+ $book = Book::first();
+
+ $bookUrl = $book->getUrl();
+ $this->actingAs($this->viewer)
+ ->visit($bookUrl)
+ ->dontSeeInElement('.actions', 'New Page')
+ ->dontSeeInElement('.actions', 'New Chapter');
+
+ $this->setEntityRestrictions($book, ['view', 'delete', 'update']);
+
+ $this->forceVisit($bookUrl . '/create-chapter')
+ ->see('You do not have permission')->seePageIs('/');
+ $this->forceVisit($bookUrl . '/create-page')
+ ->see('You do not have permission')->seePageIs('/');
+ $this->visit($bookUrl)->dontSeeInElement('.actions', 'New Page')
+ ->dontSeeInElement('.actions', 'New Chapter');
+
+ $this->setEntityRestrictions($book, ['view', 'create']);
+
+ $this->visit($bookUrl . '/create-chapter')
+ ->type('test chapter', 'name')
+ ->type('test description for chapter', 'description')
+ ->press('Save Chapter')
+ ->seePageIs($bookUrl . '/chapter/test-chapter');
+ $this->visit($bookUrl . '/create-page')
+ ->type('test page', 'name')
+ ->type('test content', 'html')
+ ->press('Save Page')
+ ->seePageIs($bookUrl . '/page/test-page');
+ $this->visit($bookUrl)->seeInElement('.actions', 'New Page')
+ ->seeInElement('.actions', 'New Chapter');
+ }
+
+ public function test_book_update_restriction_override()
+ {
+ $book = Book::first();
+ $bookPage = $book->pages->first();
+ $bookChapter = $book->chapters->first();
+
+ $bookUrl = $book->getUrl();
+ $this->actingAs($this->viewer)
+ ->visit($bookUrl . '/edit')
+ ->dontSee('Edit Book');
+
+ $this->setEntityRestrictions($book, ['view', 'delete']);
+
+ $this->forceVisit($bookUrl . '/edit')
+ ->see('You do not have permission')->seePageIs('/');
+ $this->forceVisit($bookPage->getUrl() . '/edit')
+ ->see('You do not have permission')->seePageIs('/');
+ $this->forceVisit($bookChapter->getUrl() . '/edit')
+ ->see('You do not have permission')->seePageIs('/');
+
+ $this->setEntityRestrictions($book, ['view', 'update']);
+
+ $this->visit($bookUrl . '/edit')
+ ->seePageIs($bookUrl . '/edit');
+ $this->visit($bookPage->getUrl() . '/edit')
+ ->seePageIs($bookPage->getUrl() . '/edit');
+ $this->visit($bookChapter->getUrl() . '/edit')
+ ->see('Edit Chapter');
+ }
+
+ public function test_book_delete_restriction_override()
+ {
+ $book = 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');
+ }
+
+ public function test_page_visible_if_has_permissions_when_book_not_visible()
+ {
+ $book = Book::first();
+
+ $this->setEntityRestrictions($book, []);
+
+ $bookChapter = $book->chapters->first();
+ $bookPage = $bookChapter->pages->first();
+ $this->setEntityRestrictions($bookPage, ['view']);
+
+ $this->actingAs($this->viewer);
+ $this->get($bookPage->getUrl());
+ $this->assertResponseOk();
+ $this->see($bookPage->name);
+ $this->dontSee(substr($book->name, 0, 15));
+ $this->dontSee(substr($bookChapter->name, 0, 15));
+ }
+
+ public function test_book_sort_view_permission()
+ {
+ $firstBook = Book::first();
+ $secondBook = Book::find(2);
+
+ $this->setEntityRestrictions($firstBook, ['view', 'update']);
+ $this->setEntityRestrictions($secondBook, ['view']);
+
+ // Test sort page visibility
+ $this->actingAs($this->user)->visit($secondBook->getUrl() . '/sort')
+ ->see('You do not have permission')
+ ->seePageIs('/');
+
+ // Check sort page on first book
+ $this->actingAs($this->user)->visit($firstBook->getUrl() . '/sort');
+ }
+
+ public function test_book_sort_permission() {
+ $firstBook = Book::first();
+ $secondBook = Book::find(2);
+
+ $this->setEntityRestrictions($firstBook, ['view', 'update']);
+ $this->setEntityRestrictions($secondBook, ['view']);
+
+ $firstBookChapter = $this->app[EntityRepo::class]->createFromInput('chapter',
+ ['name' => 'first book chapter'], $firstBook);
+ $secondBookChapter = $this->app[EntityRepo::class]->createFromInput('chapter',
+ ['name' => 'second book chapter'], $secondBook);
+
+ // Create request data
+ $reqData = [
+ [
+ 'id' => $firstBookChapter->id,
+ 'sort' => 0,
+ 'parentChapter' => false,
+ 'type' => 'chapter',
+ 'book' => $secondBook->id
+ ]
+ ];
+
+ // Move chapter from first book to a second book
+ $this->actingAs($this->user)->put($firstBook->getUrl() . '/sort', ['sort-tree' => json_encode($reqData)])
+ ->followRedirects()
+ ->see('You do not have permission')
+ ->seePageIs('/');
+
+ $reqData = [
+ [
+ 'id' => $secondBookChapter->id,
+ 'sort' => 0,
+ 'parentChapter' => false,
+ 'type' => 'chapter',
+ 'book' => $firstBook->id
+ ]
+ ];
+
+ // Move chapter from second book to first book
+ $this->actingAs($this->user)->put($firstBook->getUrl() . '/sort', ['sort-tree' => json_encode($reqData)])
+ ->followRedirects()
+ ->see('You do not have permission')
+ ->seePageIs('/');
+ }
+
+ public function test_can_create_page_if_chapter_has_permissions_when_book_not_visible()
+ {
+ $book = Book::first();
+ $this->setEntityRestrictions($book, []);
+ $bookChapter = $book->chapters->first();
+ $this->setEntityRestrictions($bookChapter, ['view']);
+
+ $this->actingAs($this->user)->visit($bookChapter->getUrl())
+ ->dontSee('New Page');
+
+ $this->setEntityRestrictions($bookChapter, ['view', 'create']);
+
+ $this->actingAs($this->user)->visit($bookChapter->getUrl())
+ ->click('New Page')
+ ->seeStatusCode(200)
+ ->type('test page', 'name')
+ ->type('test content', 'html')
+ ->press('Save Page')
+ ->seePageIs($book->getUrl('/page/test-page'))
+ ->seeStatusCode(200);
+ }