+ return $this->actingAs($this->getAdmin());
+ }
+
+ /**
+ * Get the current admin user.
+ */
+ public function getAdmin(): User
+ {
+ if (is_null($this->admin)) {
+ $adminRole = Role::getSystemRole('admin');
+ $this->admin = $adminRole->users->first();
+ }
+
+ return $this->admin;
+ }
+
+ /**
+ * Set the current user context to be an editor.
+ */
+ public function asEditor()
+ {
+ return $this->actingAs($this->getEditor());
+ }
+
+ /**
+ * Get a editor user.
+ */
+ protected function getEditor(): User
+ {
+ 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.
+ */
+ protected function getViewer(array $attributes = []): User
+ {
+ $user = Role::getRole('viewer')->users()->first();
+ if (!empty($attributes)) {
+ $user->forceFill($attributes)->save();
+ }
+
+ return $user;
+ }
+
+ /**
+ * Get a user that's not a system user such as the guest user.
+ */
+ public function getNormalUser(): User
+ {
+ return User::query()->where('system_name', '=', null)->get()->last();
+ }
+
+ /**
+ * Regenerate the permission for an entity.
+ */
+ protected function regenEntityPermissions(Entity $entity): void
+ {
+ $entity->rebuildPermissions();
+ $entity->load('jointPermissions');
+ }
+
+ /**
+ * Create and return a new bookshelf.
+ */
+ public function newShelf(array $input = ['name' => 'test shelf', 'description' => 'My new test shelf']): Bookshelf
+ {
+ return app(BookshelfRepo::class)->create($input, []);
+ }
+
+ /**
+ * Create and return a new book.
+ */
+ public function newBook(array $input = ['name' => 'test book', 'description' => 'My new test book']): Book
+ {
+ return app(BookRepo::class)->create($input);
+ }
+
+ /**
+ * Create and return a new test chapter.
+ */
+ public function newChapter(array $input, Book $book): Chapter
+ {
+ return app(ChapterRepo::class)->create($input, $book);
+ }
+
+ /**
+ * Create and return a new test page.
+ */
+ public function newPage(array $input = ['name' => 'test page', 'html' => 'My new test page']): Page
+ {
+ $book = Book::query()->first();
+ $pageRepo = app(PageRepo::class);
+ $draftPage = $pageRepo->getNewDraftPage($book);
+
+ return $pageRepo->publishDraft($draftPage, $input);
+ }
+
+ /**
+ * Quickly sets an array of settings.
+ */
+ protected function setSettings(array $settingsArray): void
+ {
+ $settings = app(SettingService::class);
+ foreach ($settingsArray as $key => $value) {
+ $settings->put($key, $value);
+ }
+ }
+
+ /**
+ * Manually set some permissions on an entity.
+ */
+ protected function setEntityRestrictions(Entity $entity, array $actions = [], array $roles = []): void
+ {
+ $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->make(JointPermissionBuilder::class)->rebuildForEntity($entity);
+ $entity->load('jointPermissions');
+ }
+
+ /**
+ * Give the given user some permissions.
+ */
+ protected function giveUserPermissions(User $user, array $permissions = []): void
+ {
+ $newRole = $this->createNewRole($permissions);
+ $user->attachRole($newRole);
+ $user->load('roles');
+ $user->clearPermissionCache();
+ }
+
+ /**
+ * Completely remove the given permission name from the given user.
+ */
+ protected function removePermissionFromUser(User $user, string $permissionName)
+ {
+ $permissionBuilder = app()->make(JointPermissionBuilder::class);
+
+ /** @var RolePermission $permission */
+ $permission = RolePermission::query()->where('name', '=', $permissionName)->firstOrFail();
+
+ $roles = $user->roles()->whereHas('permissions', function ($query) use ($permission) {
+ $query->where('id', '=', $permission->id);
+ })->get();
+
+ /** @var Role $role */
+ foreach ($roles as $role) {
+ $role->detachPermission($permission);
+ $permissionBuilder->rebuildForRole($role);
+ }
+
+ $user->clearPermissionCache();
+ }
+
+ /**
+ * Create a new basic role for testing purposes.
+ */
+ protected function createNewRole(array $permissions = []): Role
+ {
+ $permissionRepo = app(PermissionsRepo::class);
+ $roleData = Role::factory()->make()->toArray();
+ $roleData['permissions'] = array_flip($permissions);
+
+ return $permissionRepo->saveNewRole($roleData);