X-Git-Url: http://source.bookstackapp.com/bookstack/blobdiff_plain/068a8a068c5d7c7ab98a6ee95baae8d321c3c61f..refs/pull/5676/head:/tests/Helpers/EntityProvider.php diff --git a/tests/Helpers/EntityProvider.php b/tests/Helpers/EntityProvider.php index d3888e71f..22e554f74 100644 --- a/tests/Helpers/EntityProvider.php +++ b/tests/Helpers/EntityProvider.php @@ -2,18 +2,25 @@ namespace Tests\Helpers; -use BookStack\Auth\Role; -use BookStack\Auth\User; use BookStack\Entities\Models\Book; use BookStack\Entities\Models\Bookshelf; use BookStack\Entities\Models\Chapter; use BookStack\Entities\Models\Entity; +use BookStack\Entities\Models\HasCoverImage; use BookStack\Entities\Models\Page; use BookStack\Entities\Repos\BookRepo; use BookStack\Entities\Repos\BookshelfRepo; use BookStack\Entities\Repos\ChapterRepo; use BookStack\Entities\Repos\PageRepo; +use BookStack\Entities\Tools\TrashCan; +use BookStack\Users\Models\User; +use Illuminate\Database\Eloquent\Builder; +/** + * Class to provider and action entity models for common test case + * operations. Tracks handled models and only returns fresh models. + * Does not dedupe against nested/child/parent models. + */ class EntityProvider { /** @@ -29,43 +36,77 @@ class EntityProvider /** * Get an un-fetched page from the system. */ - public function page(): Page + public function page(callable $queryFilter = null): Page { /** @var Page $page */ - $page = Page::query()->whereNotIn('id', $this->fetchCache['page'])->first(); + $page = Page::query()->when($queryFilter, $queryFilter)->whereNotIn('id', $this->fetchCache['page'])->first(); $this->addToCache($page); return $page; } + public function pageWithinChapter(): Page + { + return $this->page(fn(Builder $query) => $query->whereHas('chapter')->with('chapter')); + } + + public function pageNotWithinChapter(): Page + { + return $this->page(fn(Builder $query) => $query->where('chapter_id', '=', 0)); + } + + public function templatePage(): Page + { + $page = $this->page(); + $page->template = true; + $page->save(); + + return $page; + } + /** * Get an un-fetched chapter from the system. */ - public function chapter(): Chapter + public function chapter(callable $queryFilter = null): Chapter { /** @var Chapter $chapter */ - $chapter = Chapter::query()->whereNotIn('id', $this->fetchCache['chapter'])->first(); + $chapter = Chapter::query()->when($queryFilter, $queryFilter)->whereNotIn('id', $this->fetchCache['chapter'])->first(); $this->addToCache($chapter); return $chapter; } + public function chapterHasPages(): Chapter + { + return $this->chapter(fn(Builder $query) => $query->whereHas('pages')); + } + /** * Get an un-fetched book from the system. */ - public function book(): Book + public function book(callable $queryFilter = null): Book { /** @var Book $book */ - $book = Book::query()->whereNotIn('id', $this->fetchCache['book'])->first(); + $book = Book::query()->when($queryFilter, $queryFilter)->whereNotIn('id', $this->fetchCache['book'])->first(); $this->addToCache($book); return $book; } + /** + * Get a book that has chapters and pages assigned. + */ + public function bookHasChaptersAndPages(): Book + { + return $this->book(function (Builder $query) { + $query->has('chapters')->has('pages')->with(['chapters', 'pages']); + }); + } + /** * Get an un-fetched shelf from the system. */ - public function shelf(): Bookshelf + public function shelf(callable $queryFilter = null): Bookshelf { /** @var Bookshelf $shelf */ - $shelf = Bookshelf::query()->whereNotIn('id', $this->fetchCache['bookshelf'])->first(); + $shelf = Bookshelf::query()->when($queryFilter, $queryFilter)->whereNotIn('id', $this->fetchCache['bookshelf'])->first(); $this->addToCache($shelf); return $shelf; } @@ -84,6 +125,12 @@ class EntityProvider ]; } + public function updatePage(Page $page, array $data): Page + { + $this->addToCache($page); + return app()->make(PageRepo::class)->update($page, $data); + } + /** * Create a book to page chain of entities that belong to a specific user. * @return array{book: Book, chapter: Chapter, page: Page} @@ -141,7 +188,7 @@ class EntityProvider */ public function newPage(array $input = ['name' => 'test page', 'html' => 'My new test page']): Page { - $book = Book::query()->first(); + $book = $this->book(); $pageRepo = app(PageRepo::class); $draftPage = $pageRepo->getNewDraftPage($book); $this->addToCache($draftPage); @@ -149,40 +196,49 @@ class EntityProvider } /** - * Regenerate the permission for an entity. - * Centralised to manage clearing of cached elements between requests. + * Create and return a new test draft page. */ - public function regenPermissions(Entity $entity): void + public function newDraftPage(array $input = ['name' => 'test page', 'html' => 'My new test page']): Page { - $entity->rebuildPermissions(); - $entity->load('jointPermissions'); + $book = $this->book(); + $pageRepo = app(PageRepo::class); + $draftPage = $pageRepo->getNewDraftPage($book); + $pageRepo->updatePageDraft($draftPage, $input); + $this->addToCache($draftPage); + return $draftPage; } /** - * Set the given entity as having restricted permissions, and apply the given - * permissions for the given roles. - * @param string[] $actions - * @param Role[] $roles + * Send an entity to the recycle bin. */ - public function setPermissions(Entity $entity, array $actions = [], array $roles = []): void + public function sendToRecycleBin(Entity $entity) { - $entity->restricted = true; - $entity->permissions()->delete(); + $trash = app()->make(TrashCan::class); + + if ($entity instanceof Page) { + $trash->softDestroyPage($entity); + } elseif ($entity instanceof Chapter) { + $trash->softDestroyChapter($entity); + } elseif ($entity instanceof Book) { + $trash->softDestroyBook($entity); + } elseif ($entity instanceof Bookshelf) { + $trash->softDestroyBookshelf($entity); + } - $permissions = []; - foreach ($actions as $action) { - foreach ($roles as $role) { - $permissions[] = [ - 'role_id' => $role->id, - 'action' => strtolower($action), - ]; - } + $entity->refresh(); + if (is_null($entity->deleted_at)) { + throw new \Exception("Could not send entity type [{$entity->getMorphClass()}] to the recycle bin"); } + } - $entity->permissions()->createMany($permissions); - $entity->save(); - $entity->load('permissions'); - $this->regenPermissions($entity); + /** + * Fully destroy the given entity from the system, bypassing the recycle bin + * stage. Still runs through main app deletion logic. + */ + public function destroy(Entity $entity) + { + $trash = app()->make(TrashCan::class); + $trash->destroyEntity($entity); } /**