3 namespace Tests\Helpers;
5 use BookStack\Auth\Role;
6 use BookStack\Auth\User;
7 use BookStack\Entities\Models\Book;
8 use BookStack\Entities\Models\Bookshelf;
9 use BookStack\Entities\Models\Chapter;
10 use BookStack\Entities\Models\Entity;
11 use BookStack\Entities\Models\Page;
12 use BookStack\Entities\Repos\BookRepo;
13 use BookStack\Entities\Repos\BookshelfRepo;
14 use BookStack\Entities\Repos\ChapterRepo;
15 use BookStack\Entities\Repos\PageRepo;
20 * @var array<string, int[]>
22 protected array $fetchCache = [
30 * Get an un-fetched page from the system.
32 public function page(): Page
34 /** @var Page $page */
35 $page = Page::query()->whereNotIn('id', $this->fetchCache['page'])->first();
36 $this->addToCache($page);
41 * Get an un-fetched chapter from the system.
43 public function chapter(): Chapter
45 /** @var Chapter $chapter */
46 $chapter = Chapter::query()->whereNotIn('id', $this->fetchCache['chapter'])->first();
47 $this->addToCache($chapter);
52 * Get an un-fetched book from the system.
54 public function book(): Book
56 /** @var Book $book */
57 $book = Book::query()->whereNotIn('id', $this->fetchCache['book'])->first();
58 $this->addToCache($book);
63 * Get an un-fetched shelf from the system.
65 public function shelf(): Bookshelf
67 /** @var Bookshelf $shelf */
68 $shelf = Bookshelf::query()->whereNotIn('id', $this->fetchCache['bookshelf'])->first();
69 $this->addToCache($shelf);
74 * Get all entity types from the system.
75 * @return array{page: Page, chapter: Chapter, book: Book, bookshelf: Bookshelf}
77 public function all(): array
80 'page' => $this->page(),
81 'chapter' => $this->chapter(),
82 'book' => $this->book(),
83 'bookshelf' => $this->shelf(),
88 * Create a book to page chain of entities that belong to a specific user.
89 * @return array{book: Book, chapter: Chapter, page: Page}
91 public function createChainBelongingToUser(User $creatorUser, ?User $updaterUser = null): array
93 if (empty($updaterUser)) {
94 $updaterUser = $creatorUser;
97 $userAttrs = ['created_by' => $creatorUser->id, 'owned_by' => $creatorUser->id, 'updated_by' => $updaterUser->id];
98 /** @var Book $book */
99 $book = Book::factory()->create($userAttrs);
100 $chapter = Chapter::factory()->create(array_merge(['book_id' => $book->id], $userAttrs));
101 $page = Page::factory()->create(array_merge(['book_id' => $book->id, 'chapter_id' => $chapter->id], $userAttrs));
103 $book->rebuildPermissions();
104 $this->addToCache([$page, $chapter, $book]);
106 return compact('book', 'chapter', 'page');
110 * Create and return a new bookshelf.
112 public function newShelf(array $input = ['name' => 'test shelf', 'description' => 'My new test shelf']): Bookshelf
114 $shelf = app(BookshelfRepo::class)->create($input, []);
115 $this->addToCache($shelf);
120 * Create and return a new book.
122 public function newBook(array $input = ['name' => 'test book', 'description' => 'My new test book']): Book
124 $book = app(BookRepo::class)->create($input);
125 $this->addToCache($book);
130 * Create and return a new test chapter.
132 public function newChapter(array $input, Book $book): Chapter
134 $chapter = app(ChapterRepo::class)->create($input, $book);
135 $this->addToCache($chapter);
140 * Create and return a new test page.
142 public function newPage(array $input = ['name' => 'test page', 'html' => 'My new test page']): Page
144 $book = Book::query()->first();
145 $pageRepo = app(PageRepo::class);
146 $draftPage = $pageRepo->getNewDraftPage($book);
147 $this->addToCache($draftPage);
148 return $pageRepo->publishDraft($draftPage, $input);
152 * Regenerate the permission for an entity.
153 * Centralised to manage clearing of cached elements between requests.
155 public function regenPermissions(Entity $entity): void
157 $entity->rebuildPermissions();
158 $entity->load('jointPermissions');
162 * Set the given entity as having restricted permissions, and apply the given
163 * permissions for the given roles.
164 * @param string[] $actions
165 * @param Role[] $roles
167 public function setPermissions(Entity $entity, array $actions = [], array $roles = []): void
169 $entity->restricted = true;
170 $entity->permissions()->delete();
173 foreach ($actions as $action) {
174 foreach ($roles as $role) {
176 'role_id' => $role->id,
177 'action' => strtolower($action),
182 $entity->permissions()->createMany($permissions);
184 $entity->load('permissions');
185 $this->regenPermissions($entity);
189 * @param Entity|Entity[] $entities
191 protected function addToCache($entities): void
193 if (!is_array($entities)) {
194 $entities = [$entities];
197 foreach ($entities as $entity) {
198 $this->fetchCache[$entity->getType()][] = $entity->id;