diff --git a/resources/views/pages/move.blade.php b/resources/views/pages/move.blade.php
index 2bbefaae0..5a5c7e3f9 100644
--- a/resources/views/pages/move.blade.php
+++ b/resources/views/pages/move.blade.php
@@ -17,7 +17,7 @@
{!! csrf_field() !!}
- @include('components.entity-selector', ['name' => 'entity_selection', 'selectorSize' => 'large', 'entityTypes' => 'book,chapter'])
+ @include('components.entity-selector', ['name' => 'entity_selection', 'selectorSize' => 'large', 'entityTypes' => 'book,chapter', 'entityPermission' => 'page-create'])
{{ trans('common.cancel') }}
diff --git a/tests/BrowserKitTest.php b/tests/BrowserKitTest.php
index a8ff03044..86f61a764 100644
--- a/tests/BrowserKitTest.php
+++ b/tests/BrowserKitTest.php
@@ -12,10 +12,7 @@ abstract class BrowserKitTest extends TestCase
{
use DatabaseTransactions;
-
- // Local user instances
- private $admin;
- private $editor;
+ use SharedTestHelpers;
/**
* The base URL to use while testing the application.
@@ -43,38 +40,6 @@ abstract class BrowserKitTest extends TestCase
return $app;
}
- /**
- * Set the current user context to be an admin.
- * @return $this
- */
- public function asAdmin()
- {
- return $this->actingAs($this->getAdmin());
- }
-
- /**
- * Get the current admin user.
- * @return mixed
- */
- public function getAdmin() {
- if($this->admin === null) {
- $adminRole = Role::getSystemRole('admin');
- $this->admin = $adminRole->users->first();
- }
- return $this->admin;
- }
-
- /**
- * Set the current editor context to be an editor.
- * @return $this
- */
- public function asEditor()
- {
- if ($this->editor === null) {
- $this->editor = $this->getEditor();
- }
- return $this->actingAs($this->editor);
- }
/**
* Get a user that's not a system user such as the guest user.
@@ -127,28 +92,6 @@ abstract class BrowserKitTest extends TestCase
$restrictionService->buildJointPermissionsForEntity($entity);
}
- /**
- * Get an instance of a user with 'editor' permissions
- * @param array $attributes
- * @return mixed
- */
- protected function getEditor($attributes = [])
- {
- $user = \BookStack\Role::getRole('editor')->users()->first();
- if (!empty($attributes)) $user->forceFill($attributes)->save();
- return $user;
- }
-
- /**
- * Get an instance of a user with 'viewer' permissions
- * @return mixed
- */
- protected function getViewer()
- {
- $user = \BookStack\Role::getRole('viewer')->users()->first();
- if (!empty($attributes)) $user->forceFill($attributes)->save();
- return $user;
- }
/**
* Quick way to create a new user without any permissions
diff --git a/tests/Entity/SortTest.php b/tests/Entity/SortTest.php
index 6e2b7c34e..ea5ab665d 100644
--- a/tests/Entity/SortTest.php
+++ b/tests/Entity/SortTest.php
@@ -34,10 +34,10 @@ class SortTest extends TestCase
$currentBook = $page->book;
$newBook = Book::where('id', '!=', $currentBook->id)->first();
- $resp = $this->asAdmin()->get($page->getUrl() . '/move');
+ $resp = $this->asEditor()->get($page->getUrl('/move'));
$resp->assertSee('Move Page');
- $movePageResp = $this->put($page->getUrl() . '/move', [
+ $movePageResp = $this->put($page->getUrl('/move'), [
'entity_selection' => 'book:' . $newBook->id
]);
$page = Page::find($page->id);
@@ -50,6 +50,31 @@ class SortTest extends TestCase
$newBookResp->assertSee($page->name);
}
+ public function test_page_move_requires_create_permissions_on_parent()
+ {
+ $page = Page::first();
+ $currentBook = $page->book;
+ $newBook = Book::where('id', '!=', $currentBook->id)->first();
+ $editor = $this->getEditor();
+
+ $this->setEntityRestrictions($newBook, ['view', 'edit', 'delete'], $editor->roles);
+
+ $movePageResp = $this->actingAs($editor)->put($page->getUrl('/move'), [
+ 'entity_selection' => 'book:' . $newBook->id
+ ]);
+ $this->assertPermissionError($movePageResp);
+
+ $this->setEntityRestrictions($newBook, ['view', 'edit', 'delete', 'create'], $editor->roles);
+ $movePageResp = $this->put($page->getUrl('/move'), [
+ 'entity_selection' => 'book:' . $newBook->id
+ ]);
+
+ $page = Page::find($page->id);
+ $movePageResp->assertRedirect($page->getUrl());
+
+ $this->assertTrue($page->book->id == $newBook->id, 'Page book is now the new book');
+ }
+
public function test_chapter_move()
{
$chapter = Chapter::first();
@@ -57,10 +82,10 @@ class SortTest extends TestCase
$pageToCheck = $chapter->pages->first();
$newBook = Book::where('id', '!=', $currentBook->id)->first();
- $chapterMoveResp = $this->asAdmin()->get($chapter->getUrl() . '/move');
+ $chapterMoveResp = $this->asEditor()->get($chapter->getUrl('/move'));
$chapterMoveResp->assertSee('Move Chapter');
- $moveChapterResp = $this->put($chapter->getUrl() . '/move', [
+ $moveChapterResp = $this->put($chapter->getUrl('/move'), [
'entity_selection' => 'book:' . $newBook->id
]);
@@ -105,7 +130,7 @@ class SortTest extends TestCase
];
}
- $sortResp = $this->asAdmin()->put($newBook->getUrl() . '/sort', ['sort-tree' => json_encode($reqData)]);
+ $sortResp = $this->asEditor()->put($newBook->getUrl() . '/sort', ['sort-tree' => json_encode($reqData)]);
$sortResp->assertRedirect($newBook->getUrl());
$sortResp->assertStatus(302);
$this->assertDatabaseHas('chapters', [
diff --git a/tests/Permissions/RestrictionsTest.php b/tests/Permissions/RestrictionsTest.php
index 433ae7ff9..53e7ad3f3 100644
--- a/tests/Permissions/RestrictionsTest.php
+++ b/tests/Permissions/RestrictionsTest.php
@@ -1,7 +1,7 @@
user = $this->getEditor();
$this->viewer = $this->getViewer();
- $this->permissionService = $this->app[PermissionService::class];
}
- /**
- * Manually set some permissions on an entity.
- * @param \BookStack\Entity $entity
- * @param $actions
- */
- protected function setEntityRestrictions(\BookStack\Entity $entity, $actions)
+ protected function setEntityRestrictions(Entity $entity, $actions = [], $roles = [])
{
- $entity->restricted = true;
- $entity->permissions()->delete();
-
- $role = $this->user->roles->first();
- $viewerRole = $this->viewer->roles->first();
-
- $permissions = [];
- foreach ($actions as $action) {
- $permissions[] = [
- 'role_id' => $role->id,
- 'action' => strtolower($action)
- ];
- $permissions[] = [
- 'role_id' => $viewerRole->id,
- 'action' => strtolower($action)
- ];
- }
- $entity->permissions()->createMany($permissions);
-
- $entity->save();
- $entity->load('permissions');
- $this->permissionService->buildJointPermissionsForEntity($entity);
- $entity->load('jointPermissions');
+ $roles = [
+ $this->user->roles->first(),
+ $this->viewer->roles->first(),
+ ];
+ parent::setEntityRestrictions($entity, $actions, $roles);
}
public function test_book_view_restriction()
diff --git a/tests/Permissions/RolesTest.php b/tests/Permissions/RolesTest.php
index 5bc66986b..f076e6734 100644
--- a/tests/Permissions/RolesTest.php
+++ b/tests/Permissions/RolesTest.php
@@ -16,14 +16,6 @@ class RolesTest extends BrowserKitTest
$this->user = $this->getViewer();
}
- protected function getViewer()
- {
- $role = \BookStack\Role::getRole('viewer');
- $viewer = $this->getNewBlankUser();
- $viewer->attachRole($role);;
- return $viewer;
- }
-
/**
* Give the given user some permissions.
* @param \BookStack\User $user
diff --git a/tests/SharedTestHelpers.php b/tests/SharedTestHelpers.php
new file mode 100644
index 000000000..325979e74
--- /dev/null
+++ b/tests/SharedTestHelpers.php
@@ -0,0 +1,143 @@
+actingAs($this->getAdmin());
+ }
+
+ /**
+ * Get the current admin user.
+ * @return mixed
+ */
+ public function getAdmin() {
+ if($this->admin === null) {
+ $adminRole = Role::getSystemRole('admin');
+ $this->admin = $adminRole->users->first();
+ }
+ return $this->admin;
+ }
+
+ /**
+ * Set the current user context to be an editor.
+ * @return $this
+ */
+ public function asEditor()
+ {
+ return $this->actingAs($this->getEditor());
+ }
+
+
+ /**
+ * Get a editor user.
+ * @return mixed
+ */
+ protected function getEditor() {
+ if($this->editor === null) {
+ $editorRole = Role::getRole('editor');
+ $this->editor = $editorRole->users->first();
+ }
+ return $this->editor;
+ }
+
+ /**
+ * Get an instance of a user with 'viewer' permissions
+ * @param $attributes
+ * @return mixed
+ */
+ protected function getViewer($attributes = [])
+ {
+ $user = \BookStack\Role::getRole('viewer')->users()->first();
+ if (!empty($attributes)) $user->forceFill($attributes)->save();
+ return $user;
+ }
+
+ /**
+ * Create and return a new book.
+ * @param array $input
+ * @return Book
+ */
+ public function newBook($input = ['name' => 'test book', 'description' => 'My new test book']) {
+ return $this->app[EntityRepo::class]->createFromInput('book', $input, false);
+ }
+
+ /**
+ * Create and return a new test chapter
+ * @param array $input
+ * @param Book $book
+ * @return Chapter
+ */
+ public function newChapter($input = ['name' => 'test chapter', 'description' => 'My new test chapter'], Book $book) {
+ return $this->app[EntityRepo::class]->createFromInput('chapter', $input, $book);
+ }
+
+ /**
+ * Create and return a new test page
+ * @param array $input
+ * @return Chapter
+ */
+ public function newPage($input = ['name' => 'test page', 'html' => 'My new test page']) {
+ $book = Book::first();
+ $entityRepo = $this->app[EntityRepo::class];
+ $draftPage = $entityRepo->getDraftPage($book);
+ return $entityRepo->publishPageDraft($draftPage, $input);
+ }
+
+ /**
+ * Quickly sets an array of settings.
+ * @param $settingsArray
+ */
+ protected function setSettings($settingsArray)
+ {
+ $settings = app(SettingService::class);
+ foreach ($settingsArray as $key => $value) {
+ $settings->put($key, $value);
+ }
+ }
+
+ /**
+ * Manually set some permissions on an entity.
+ * @param Entity $entity
+ * @param array $actions
+ * @param array $roles
+ */
+ protected function setEntityRestrictions(Entity $entity, $actions = [], $roles = [])
+ {
+ $entity->restricted = true;
+ $entity->permissions()->delete();
+
+ $permissions = [];
+ foreach ($actions as $action) {
+ foreach ($roles as $role) {
+ $permissions[] = [
+ 'role_id' => $role->id,
+ 'action' => strtolower($action)
+ ];
+ }
+ }
+ $entity->permissions()->createMany($permissions);
+
+ $entity->save();
+ $entity->load('permissions');
+ $this->app[PermissionService::class]->buildJointPermissionsForEntity($entity);
+ $entity->load('jointPermissions');
+ }
+
+}
\ No newline at end of file
diff --git a/tests/TestCase.php b/tests/TestCase.php
index 5c37b6179..e0f160eed 100644
--- a/tests/TestCase.php
+++ b/tests/TestCase.php
@@ -1,21 +1,14 @@
actingAs($this->getAdmin());
- }
-
- /**
- * Get the current admin user.
- * @return mixed
- */
- public function getAdmin() {
- if($this->admin === null) {
- $adminRole = Role::getSystemRole('admin');
- $this->admin = $adminRole->users->first();
- }
- return $this->admin;
- }
-
- /**
- * Set the current user context to be an editor.
- * @return $this
- */
- public function asEditor()
- {
- return $this->actingAs($this->getEditor());
- }
-
-
- /**
- * Get a editor user.
- * @return mixed
- */
- public function getEditor() {
- if($this->editor === null) {
- $editorRole = Role::getRole('editor');
- $this->editor = $editorRole->users->first();
- }
- return $this->editor;
- }
-
- /**
- * Get an instance of a user with 'viewer' permissions
- * @param $attributes
- * @return mixed
- */
- protected function getViewer($attributes = [])
- {
- $user = \BookStack\Role::getRole('viewer')->users()->first();
- if (!empty($attributes)) $user->forceFill($attributes)->save();
- return $user;
- }
-
- /**
- * Create and return a new book.
- * @param array $input
- * @return Book
- */
- public function newBook($input = ['name' => 'test book', 'description' => 'My new test book']) {
- return $this->app[EntityRepo::class]->createFromInput('book', $input, false);
- }
-
- /**
- * Create and return a new test chapter
- * @param array $input
- * @param Book $book
- * @return Chapter
- */
- public function newChapter($input = ['name' => 'test chapter', 'description' => 'My new test chapter'], Book $book) {
- return $this->app[EntityRepo::class]->createFromInput('chapter', $input, $book);
- }
-
- /**
- * Create and return a new test page
- * @param array $input
- * @return Chapter
- */
- public function newPage($input = ['name' => 'test page', 'html' => 'My new test page']) {
- $book = Book::first();
- $entityRepo = $this->app[EntityRepo::class];
- $draftPage = $entityRepo->getDraftPage($book);
- return $entityRepo->publishPageDraft($draftPage, $input);
- }
-
- /**
- * Quickly sets an array of settings.
- * @param $settingsArray
- */
- protected function setSettings($settingsArray)
- {
- $settings = app(SettingService::class);
- foreach ($settingsArray as $key => $value) {
- $settings->put($key, $value);
- }
+ $response->assertRedirect('/');
+ $this->assertTrue(session()->has('error'));
+ session()->remove('error');
}
}
\ No newline at end of file