]> BookStack Code Mirror - bookstack/commitdiff
Extracted entity testcase methods to own class
authorDan Brown <redacted>
Thu, 29 Sep 2022 15:49:25 +0000 (16:49 +0100)
committerDan Brown <redacted>
Thu, 29 Sep 2022 15:49:25 +0000 (16:49 +0100)
Also added some new fetch helper methods for future use.

23 files changed:
tests/Api/AttachmentsApiTest.php
tests/Api/PagesApiTest.php
tests/Api/UsersApiTest.php
tests/Commands/CopyShelfPermissionsCommandTest.php
tests/Entity/BookShelfTest.php
tests/Entity/BookTest.php
tests/Entity/ChapterTest.php
tests/Entity/EntityAccessTest.php
tests/Entity/EntitySearchTest.php
tests/Entity/PageTest.php
tests/Entity/SortTest.php
tests/Entity/TagTest.php
tests/Helpers/EntityProvider.php [new file with mode: 0644]
tests/HomepageTest.php
tests/Permissions/EntityPermissionsTest.php
tests/Permissions/ExportPermissionsTest.php
tests/Permissions/RolesTest.php
tests/PublicActionTest.php
tests/References/CrossLinkParserTest.php
tests/References/ReferencesTest.php
tests/TestCase.php
tests/Uploads/ImageTest.php
tests/User/UserProfileTest.php

index 6077868b26cc60b907991c8b588abea3ad6c8879..dfd57deb8c3091a696eec28c720524e0bd9cb0ce 100644 (file)
@@ -53,7 +53,7 @@ class AttachmentsApiTest extends TestCase
 
         $page->restricted = true;
         $page->save();
-        $this->regenEntityPermissions($page);
+        $this->entities->regenPermissions($page);
 
         $resp = $this->getJson($this->baseEndpoint . '?count=1&sort=+id');
         $resp->assertJsonMissing(['data' => [
@@ -264,7 +264,7 @@ class AttachmentsApiTest extends TestCase
         $page->draft = true;
         $page->owned_by = $editor->id;
         $page->save();
-        $this->regenEntityPermissions($page);
+        $this->entities->regenPermissions($page);
 
         $attachment = $this->createAttachmentForPage($page, [
             'name'  => 'my attachment',
index 539a7da4e25087c6e1cf8c59e7421135ce81bf9a..20c6977ddac82556ad1761c07c3b31d8ec4faa96 100644 (file)
@@ -210,7 +210,7 @@ class PagesApiTest extends TestCase
         $this->actingAsApiEditor();
         $page = Page::visible()->first();
         $chapter = Chapter::visible()->where('book_id', '!=', $page->book_id)->first();
-        $this->setEntityRestrictions($chapter, ['view'], [$this->getEditor()->roles()->first()]);
+        $this->entities->setPermissions($chapter, ['view'], [$this->getEditor()->roles()->first()]);
         $details = [
             'name'       => 'My updated API page',
             'chapter_id' => $chapter->id,
index ddbdac0f8320c0b90fbf57a5e9edcee18a528bf8..739981f24b17d1cd883398715d4973fcc7395a1e 100644 (file)
@@ -239,7 +239,7 @@ class UsersApiTest extends TestCase
         $user = User::query()->where('id', '!=', $this->getAdmin()->id)
             ->whereNull('system_name')
             ->first();
-        $entityChain = $this->createEntityChainBelongingToUser($user);
+        $entityChain = $this->entities->createChainBelongingToUser($user);
         /** @var User $newOwner */
         $newOwner = User::query()->where('id', '!=', $user->id)->first();
 
index 5a60b8d55c550ea4b01164f40e1f150199117488..dd39317ae6f6879520716f66f86d2cd87ab264d3 100644 (file)
@@ -22,7 +22,7 @@ class CopyShelfPermissionsCommandTest extends TestCase
         $this->assertFalse(boolval($child->restricted), 'Child book should not be restricted by default');
         $this->assertTrue($child->permissions()->count() === 0, 'Child book should have no permissions by default');
 
-        $this->setEntityRestrictions($shelf, ['view', 'update'], [$editorRole]);
+        $this->entities->setPermissions($shelf, ['view', 'update'], [$editorRole]);
         $this->artisan('bookstack:copy-shelf-permissions', [
             '--slug' => $shelf->slug,
         ]);
@@ -43,7 +43,7 @@ class CopyShelfPermissionsCommandTest extends TestCase
         $this->assertFalse(boolval($child->restricted), 'Child book should not be restricted by default');
         $this->assertTrue($child->permissions()->count() === 0, 'Child book should have no permissions by default');
 
-        $this->setEntityRestrictions($shelf, ['view', 'update'], [$editorRole]);
+        $this->entities->setPermissions($shelf, ['view', 'update'], [$editorRole]);
         $this->artisan('bookstack:copy-shelf-permissions --all')
             ->expectsQuestion('Permission settings for all shelves will be cascaded. Books assigned to multiple shelves will receive only the permissions of it\'s last processed shelf. Are you sure you want to proceed?', 'y');
         $child = $shelf->books()->first();
index 4461c04899c0774eacd3dda91480ffc79e32321d..748f63da887dcc9e5b12fe9940520153595e1400 100644 (file)
@@ -45,7 +45,7 @@ class BookShelfTest extends TestCase
         $resp = $this->actingAs($user)->get('/');
         $this->withHtml($resp)->assertElementNotContains('header', 'Shelves');
 
-        $this->setEntityRestrictions($shelf, ['view'], [$userRole]);
+        $this->entities->setPermissions($shelf, ['view'], [$userRole]);
 
         $resp = $this->get('/');
         $this->withHtml($resp)->assertElementContains('header', 'Shelves');
@@ -69,7 +69,7 @@ class BookShelfTest extends TestCase
         $resp->assertSee($book->name);
         $resp->assertSee($book->getUrl());
 
-        $this->setEntityRestrictions($book, []);
+        $this->entities->setPermissions($book, []);
 
         $resp = $this->asEditor()->get('/shelves');
         $resp->assertDontSee($book->name);
@@ -298,7 +298,7 @@ class BookShelfTest extends TestCase
         $this->assertFalse(boolval($child->restricted), 'Child book should not be restricted by default');
         $this->assertTrue($child->permissions()->count() === 0, 'Child book should have no permissions by default');
 
-        $this->setEntityRestrictions($shelf, ['view', 'update'], [$editorRole]);
+        $this->entities->setPermissions($shelf, ['view', 'update'], [$editorRole]);
         $resp = $this->post($shelf->getUrl('/copy-permissions'));
         $child = $shelf->books()->first();
 
index 2f04fcf25aac765645e85d3ac12de122aa2dd160..ec430ae84b1a77ab9d4d2d2085e41a09e09ecc76 100644 (file)
@@ -246,13 +246,13 @@ class BookTest extends TestCase
 
     public function test_slug_multi_byte_url_safe()
     {
-        $book = $this->newBook([
+        $book = $this->entities->newBook([
             'name' => 'информация',
         ]);
 
         $this->assertEquals('informaciya', $book->slug);
 
-        $book = $this->newBook([
+        $book = $this->entities->newBook([
             'name' => '¿Qué?',
         ]);
 
@@ -261,7 +261,7 @@ class BookTest extends TestCase
 
     public function test_slug_format()
     {
-        $book = $this->newBook([
+        $book = $this->entities->newBook([
             'name' => 'PartA / PartB / PartC',
         ]);
 
@@ -311,7 +311,7 @@ class BookTest extends TestCase
         foreach ($book->getDirectChildren() as $child) {
             $child->restricted = true;
             $child->save();
-            $this->regenEntityPermissions($child);
+            $this->entities->regenPermissions($child);
         }
 
         $this->asEditor()->post($book->getUrl('/copy'), ['name' => 'My copy book']);
@@ -365,7 +365,7 @@ class BookTest extends TestCase
 
         $viewer = $this->getViewer();
         $this->giveUserPermissions($viewer, ['book-update-all', 'book-create-all', 'bookshelf-update-all']);
-        $this->setEntityRestrictions($shelfB);
+        $this->entities->setPermissions($shelfB);
 
 
         $this->asEditor()->post($book->getUrl('/copy'), ['name' => 'My copy book']);
index d58b83da9cd66a73b50d403c19cc78dc5cc61817..c1c746102557e58a02803cb09ccdad34a33bc83e 100644 (file)
@@ -107,7 +107,7 @@ class ChapterTest extends TestCase
         foreach ($chapter->pages as $page) {
             $page->restricted = true;
             $page->save();
-            $this->regenEntityPermissions($page);
+            $this->entities->regenPermissions($page);
         }
 
         $this->asEditor()->post($chapter->getUrl('/copy'), [
index f2f244538f474e97b6458bd6cb2e041657f1dc66..e3d129d5ed0074b0e3bf21ebd3ec8cd07d553eca 100644 (file)
@@ -14,7 +14,7 @@ class EntityAccessTest extends TestCase
         // Create required assets and revisions
         $creator = $this->getEditor();
         $updater = $this->getViewer();
-        $entities = $this->createEntityChainBelongingToUser($creator, $updater);
+        $entities = $this->entities->createChainBelongingToUser($creator, $updater);
         app()->make(UserRepo::class)->destroy($creator);
         app()->make(PageRepo::class)->update($entities['page'], ['html' => '<p>hello!</p>>']);
 
@@ -26,7 +26,7 @@ class EntityAccessTest extends TestCase
         // Create required assets and revisions
         $creator = $this->getViewer();
         $updater = $this->getEditor();
-        $entities = $this->createEntityChainBelongingToUser($creator, $updater);
+        $entities = $this->entities->createChainBelongingToUser($creator, $updater);
         app()->make(UserRepo::class)->destroy($updater);
         app()->make(PageRepo::class)->update($entities['page'], ['html' => '<p>Hello there!</p>']);
 
index 3a9b9f31ba477585092f1f9fbcccc1f35fa5d14d..eabcf6f76491a062f28bd549409ca7ca01f18a54 100644 (file)
@@ -47,7 +47,7 @@ class EntitySearchTest extends TestCase
 
     public function test_searching_accents_and_small_terms()
     {
-        $page = $this->newPage(['name' => 'My new test quaffleachits', 'html' => 'some áéííúü¿¡ test content a2 orange dog']);
+        $page = $this->entities->newPage(['name' => 'My new test quaffleachits', 'html' => 'some áéííúü¿¡ test content a2 orange dog']);
         $this->asEditor();
 
         $accentSearch = $this->get('/search?term=' . urlencode('áéíí'));
@@ -111,7 +111,7 @@ class EntitySearchTest extends TestCase
 
     public function test_exact_searches()
     {
-        $page = $this->newPage(['name' => 'My new test page', 'html' => 'this is a story about an orange donkey']);
+        $page = $this->entities->newPage(['name' => 'My new test page', 'html' => 'this is a story about an orange donkey']);
 
         $exactSearchA = $this->asEditor()->get('/search?term=' . urlencode('"story about an orange"'));
         $exactSearchA->assertStatus(200)->assertSee($page->name);
@@ -123,7 +123,7 @@ class EntitySearchTest extends TestCase
     public function test_search_terms_with_delimiters_are_converted_to_exact_matches()
     {
         $this->asEditor();
-        $page = $this->newPage(['name' => 'Delimiter test', 'html' => '<p>1.1 2,2 3?3 4:4 5;5 (8) &lt;9&gt; "10" \'11\' `12`</p>']);
+        $page = $this->entities->newPage(['name' => 'Delimiter test', 'html' => '<p>1.1 2,2 3?3 4:4 5;5 (8) &lt;9&gt; "10" \'11\' `12`</p>']);
         $terms = explode(' ', '1.1 2,2 3?3 4:4 5;5 (8) <9> "10" \'11\' `12`');
 
         foreach ($terms as $term) {
@@ -134,7 +134,7 @@ class EntitySearchTest extends TestCase
 
     public function test_search_filters()
     {
-        $page = $this->newPage(['name' => 'My new test quaffleachits', 'html' => 'this is about an orange donkey danzorbhsing']);
+        $page = $this->entities->newPage(['name' => 'My new test quaffleachits', 'html' => 'this is about an orange donkey danzorbhsing']);
         $this->asEditor();
         $editorId = $this->getEditor()->id;
         $editorSlug = $this->getEditor()->slug;
@@ -197,7 +197,7 @@ class EntitySearchTest extends TestCase
 
     public function test_ajax_entity_search()
     {
-        $page = $this->newPage(['name' => 'my ajax search test', 'html' => 'ajax test']);
+        $page = $this->entities->newPage(['name' => 'my ajax search test', 'html' => 'ajax test']);
         $notVisitedPage = Page::first();
 
         // Visit the page to make popular
@@ -334,15 +334,15 @@ class EntitySearchTest extends TestCase
 
     public function test_search_ranks_common_words_lower()
     {
-        $this->newPage(['name' => 'Test page A', 'html' => '<p>dog biscuit dog dog</p>']);
-        $this->newPage(['name' => 'Test page B', 'html' => '<p>cat biscuit</p>']);
+        $this->entities->newPage(['name' => 'Test page A', 'html' => '<p>dog biscuit dog dog</p>']);
+        $this->entities->newPage(['name' => 'Test page B', 'html' => '<p>cat biscuit</p>']);
 
         $search = $this->asEditor()->get('/search?term=cat+dog+biscuit');
         $this->withHtml($search)->assertElementContains('.entity-list > .page:nth-child(1)', 'Test page A');
         $this->withHtml($search)->assertElementContains('.entity-list > .page:nth-child(2)', 'Test page B');
 
         for ($i = 0; $i < 2; $i++) {
-            $this->newPage(['name' => 'Test page ' . $i, 'html' => '<p>dog</p>']);
+            $this->entities->newPage(['name' => 'Test page ' . $i, 'html' => '<p>dog</p>']);
         }
 
         $search = $this->asEditor()->get('/search?term=cat+dog+biscuit');
@@ -352,7 +352,7 @@ class EntitySearchTest extends TestCase
 
     public function test_terms_in_headers_have_an_adjusted_index_score()
     {
-        $page = $this->newPage(['name' => 'Test page A', 'html' => '
+        $page = $this->entities->newPage(['name' => 'Test page A', 'html' => '
             <p>TermA</p>
             <h1>TermB <strong>TermNested</strong></h1>
             <h2>TermC</h2>
@@ -377,7 +377,7 @@ class EntitySearchTest extends TestCase
 
     public function test_name_and_content_terms_are_merged_to_single_score()
     {
-        $page = $this->newPage(['name' => 'TermA', 'html' => '
+        $page = $this->entities->newPage(['name' => 'TermA', 'html' => '
             <p>TermA</p>
         ']);
 
@@ -389,7 +389,7 @@ class EntitySearchTest extends TestCase
 
     public function test_tag_names_and_values_are_indexed_for_search()
     {
-        $page = $this->newPage(['name' => 'PageA', 'html' => '<p>content</p>', 'tags' => [
+        $page = $this->entities->newPage(['name' => 'PageA', 'html' => '<p>content</p>', 'tags' => [
             ['name' => 'Animal', 'value' => 'MeowieCat'],
             ['name' => 'SuperImportant'],
         ]]);
@@ -402,7 +402,7 @@ class EntitySearchTest extends TestCase
 
     public function test_matching_terms_in_search_results_are_highlighted()
     {
-        $this->newPage(['name' => 'My Meowie Cat', 'html' => '<p>A superimportant page about meowieable animals</p>', 'tags' => [
+        $this->entities->newPage(['name' => 'My Meowie Cat', 'html' => '<p>A superimportant page about meowieable animals</p>', 'tags' => [
             ['name' => 'Animal', 'value' => 'MeowieCat'],
             ['name' => 'SuperImportant'],
         ]]);
@@ -420,7 +420,7 @@ class EntitySearchTest extends TestCase
 
     public function test_match_highlighting_works_with_multibyte_content()
     {
-        $this->newPage([
+        $this->entities->newPage([
             'name' => 'Test Page',
             'html' => '<p>На мен ми трябва нещо добро test</p>',
         ]);
@@ -431,7 +431,7 @@ class EntitySearchTest extends TestCase
 
     public function test_html_entities_in_item_details_remains_escaped_in_search_results()
     {
-        $this->newPage(['name' => 'My <cool> TestPageContent', 'html' => '<p>My supercool &lt;great&gt; TestPageContent page</p>']);
+        $this->entities->newPage(['name' => 'My <cool> TestPageContent', 'html' => '<p>My supercool &lt;great&gt; TestPageContent page</p>']);
 
         $search = $this->asEditor()->get('/search?term=TestPageContent');
         $search->assertSee('My &lt;cool&gt; <strong>TestPageContent</strong>', false);
@@ -440,7 +440,7 @@ class EntitySearchTest extends TestCase
 
     public function test_words_adjacent_to_lines_breaks_can_be_matched_with_normal_terms()
     {
-        $page = $this->newPage(['name' => 'TermA', 'html' => '
+        $page = $this->entities->newPage(['name' => 'TermA', 'html' => '
             <p>TermA<br>TermB<br>TermC</p>
         ']);
 
index 734516e872271ed6a6f22bf33377fe1ffcc41a42..0f906460b1fd74823b3be6c215957a10e589cd96 100644 (file)
@@ -201,7 +201,7 @@ class PageTest extends TestCase
         $newBook->owned_by = $viewer->id;
         $newBook->save();
         $this->giveUserPermissions($viewer, ['page-create-own']);
-        $this->regenEntityPermissions($newBook);
+        $this->entities->regenPermissions($newBook);
 
         $resp = $this->actingAs($viewer)->get($page->getUrl());
         $resp->assertSee($page->getUrl('/copy'));
@@ -255,7 +255,7 @@ class PageTest extends TestCase
     public function test_recently_updated_pages_view()
     {
         $user = $this->getEditor();
-        $content = $this->createEntityChainBelongingToUser($user);
+        $content = $this->entities->createChainBelongingToUser($user);
 
         $resp = $this->asAdmin()->get('/pages/recently-updated');
         $this->withHtml($resp)->assertElementContains('.entity-list .page:nth-child(1)', $content['page']->name);
@@ -303,8 +303,8 @@ class PageTest extends TestCase
             'html' => '<p>Updated content</p>',
         ]);
 
-        $this->setEntityRestrictions($page->book);
-        $this->setEntityRestrictions($page, ['view'], [$user->roles->first()]);
+        $this->entities->setPermissions($page->book);
+        $this->entities->setPermissions($page, ['view'], [$user->roles->first()]);
 
         $resp = $this->get('/pages/recently-updated');
         $resp->assertDontSee($page->book->getShortName(42));
index 8792e70db31b57d2b678d625533a51af83c4f67a..93b668a0e2c81680ae61daa1665b5043cf202c18 100644 (file)
@@ -98,14 +98,14 @@ class SortTest extends TestCase
         $newBook = Book::query()->where('id', '!=', $currentBook->id)->first();
         $editor = $this->getEditor();
 
-        $this->setEntityRestrictions($newBook, ['view', 'update', 'delete'], $editor->roles->all());
+        $this->entities->setPermissions($newBook, ['view', 'update', 'delete'], $editor->roles->all());
 
         $movePageResp = $this->actingAs($editor)->put($page->getUrl('/move'), [
             'entity_selection' => 'book:' . $newBook->id,
         ]);
         $this->assertPermissionError($movePageResp);
 
-        $this->setEntityRestrictions($newBook, ['view', 'update', 'delete', 'create'], $editor->roles->all());
+        $this->entities->setPermissions($newBook, ['view', 'update', 'delete', 'create'], $editor->roles->all());
         $movePageResp = $this->put($page->getUrl('/move'), [
             'entity_selection' => 'book:' . $newBook->id,
         ]);
@@ -123,8 +123,8 @@ class SortTest extends TestCase
         $newBook = Book::query()->where('id', '!=', $currentBook->id)->first();
         $editor = $this->getEditor();
 
-        $this->setEntityRestrictions($newBook, ['view', 'update', 'create', 'delete'], $editor->roles->all());
-        $this->setEntityRestrictions($page, ['view', 'update', 'create'], $editor->roles->all());
+        $this->entities->setPermissions($newBook, ['view', 'update', 'create', 'delete'], $editor->roles->all());
+        $this->entities->setPermissions($page, ['view', 'update', 'create'], $editor->roles->all());
 
         $movePageResp = $this->actingAs($editor)->put($page->getUrl('/move'), [
             'entity_selection' => 'book:' . $newBook->id,
@@ -133,7 +133,7 @@ class SortTest extends TestCase
         $pageView = $this->get($page->getUrl());
         $pageView->assertDontSee($page->getUrl('/move'));
 
-        $this->setEntityRestrictions($page, ['view', 'update', 'create', 'delete'], $editor->roles->all());
+        $this->entities->setPermissions($page, ['view', 'update', 'create', 'delete'], $editor->roles->all());
         $movePageResp = $this->put($page->getUrl('/move'), [
             'entity_selection' => 'book:' . $newBook->id,
         ]);
@@ -178,8 +178,8 @@ class SortTest extends TestCase
         $newBook = Book::query()->where('id', '!=', $currentBook->id)->first();
         $editor = $this->getEditor();
 
-        $this->setEntityRestrictions($newBook, ['view', 'update', 'create', 'delete'], $editor->roles->all());
-        $this->setEntityRestrictions($chapter, ['view', 'update', 'create'], $editor->roles->all());
+        $this->entities->setPermissions($newBook, ['view', 'update', 'create', 'delete'], $editor->roles->all());
+        $this->entities->setPermissions($chapter, ['view', 'update', 'create'], $editor->roles->all());
 
         $moveChapterResp = $this->actingAs($editor)->put($chapter->getUrl('/move'), [
             'entity_selection' => 'book:' . $newBook->id,
@@ -188,7 +188,7 @@ class SortTest extends TestCase
         $pageView = $this->get($chapter->getUrl());
         $pageView->assertDontSee($chapter->getUrl('/move'));
 
-        $this->setEntityRestrictions($chapter, ['view', 'update', 'create', 'delete'], $editor->roles->all());
+        $this->entities->setPermissions($chapter, ['view', 'update', 'create', 'delete'], $editor->roles->all());
         $moveChapterResp = $this->put($chapter->getUrl('/move'), [
             'entity_selection' => 'book:' . $newBook->id,
         ]);
@@ -205,15 +205,15 @@ class SortTest extends TestCase
         $newBook = Book::query()->where('id', '!=', $currentBook->id)->first();
         $editor = $this->getEditor();
 
-        $this->setEntityRestrictions($newBook, ['view', 'update', 'delete'], [$editor->roles->first()]);
-        $this->setEntityRestrictions($chapter, ['view', 'update', 'create', 'delete'], [$editor->roles->first()]);
+        $this->entities->setPermissions($newBook, ['view', 'update', 'delete'], [$editor->roles->first()]);
+        $this->entities->setPermissions($chapter, ['view', 'update', 'create', 'delete'], [$editor->roles->first()]);
 
         $moveChapterResp = $this->actingAs($editor)->put($chapter->getUrl('/move'), [
             'entity_selection' => 'book:' . $newBook->id,
         ]);
         $this->assertPermissionError($moveChapterResp);
 
-        $this->setEntityRestrictions($newBook, ['view', 'update', 'create', 'delete'], [$editor->roles->first()]);
+        $this->entities->setPermissions($newBook, ['view', 'update', 'create', 'delete'], [$editor->roles->first()]);
         $moveChapterResp = $this->put($chapter->getUrl('/move'), [
             'entity_selection' => 'book:' . $newBook->id,
         ]);
@@ -257,8 +257,8 @@ class SortTest extends TestCase
     public function test_book_sort()
     {
         $oldBook = Book::query()->first();
-        $chapterToMove = $this->newChapter(['name' => 'chapter to move'], $oldBook);
-        $newBook = $this->newBook(['name' => 'New sort book']);
+        $chapterToMove = $this->entities->newChapter(['name' => 'chapter to move'], $oldBook);
+        $newBook = $this->entities->newBook(['name' => 'New sort book']);
         $pagesToMove = Page::query()->take(5)->get();
 
         // Create request data
@@ -323,7 +323,7 @@ class SortTest extends TestCase
         $page = Page::query()->where('chapter_id', '!=', 0)->first();
         /** @var Chapter $otherChapter */
         $otherChapter = Chapter::query()->where('book_id', '!=', $page->book_id)->first();
-        $this->setEntityRestrictions($otherChapter);
+        $this->entities->setPermissions($otherChapter);
 
         $sortData = [
             'id'            => $page->id,
@@ -346,7 +346,7 @@ class SortTest extends TestCase
         /** @var Chapter $otherChapter */
         $otherChapter = Chapter::query()->where('book_id', '!=', $page->book_id)->first();
         $editor = $this->getEditor();
-        $this->setEntityRestrictions($otherChapter->book, ['update', 'delete'], [$editor->roles()->first()]);
+        $this->entities->setPermissions($otherChapter->book, ['update', 'delete'], [$editor->roles()->first()]);
 
         $sortData = [
             'id'            => $page->id,
@@ -369,7 +369,7 @@ class SortTest extends TestCase
         /** @var Chapter $otherChapter */
         $otherChapter = Chapter::query()->where('book_id', '!=', $page->book_id)->first();
         $editor = $this->getEditor();
-        $this->setEntityRestrictions($otherChapter, ['view', 'delete'], [$editor->roles()->first()]);
+        $this->entities->setPermissions($otherChapter, ['view', 'delete'], [$editor->roles()->first()]);
 
         $sortData = [
             'id'            => $page->id,
@@ -392,7 +392,7 @@ class SortTest extends TestCase
         /** @var Chapter $otherChapter */
         $otherChapter = Chapter::query()->where('book_id', '!=', $page->book_id)->first();
         $editor = $this->getEditor();
-        $this->setEntityRestrictions($page, ['view', 'delete'], [$editor->roles()->first()]);
+        $this->entities->setPermissions($page, ['view', 'delete'], [$editor->roles()->first()]);
 
         $sortData = [
             'id'            => $page->id,
@@ -415,7 +415,7 @@ class SortTest extends TestCase
         /** @var Chapter $otherChapter */
         $otherChapter = Chapter::query()->where('book_id', '!=', $page->book_id)->first();
         $editor = $this->getEditor();
-        $this->setEntityRestrictions($page, ['view', 'update'], [$editor->roles()->first()]);
+        $this->entities->setPermissions($page, ['view', 'update'], [$editor->roles()->first()]);
 
         $sortData = [
             'id'            => $page->id,
index 1d2c9124f9bc06dbe413c2a2fb8039fbc5dba196..d22dc2f4482c963d8f90c527f152997369268995 100644 (file)
@@ -188,7 +188,7 @@ class TagTest extends TestCase
         $resp->assertSee('GreatTestContent');
 
         $page->restricted = true;
-        $this->regenEntityPermissions($page);
+        $this->entities->regenPermissions($page);
 
         $resp = $this->asEditor()->get('/tags');
         $resp->assertDontSee('SuperCategory');
@@ -207,7 +207,7 @@ class TagTest extends TestCase
     {
         $this->asEditor();
 
-        foreach ($this->getEachEntityType() as $entity) {
+        foreach ($this->entities->all() as $entity) {
             $entity->tags()->create(['name' => 'My Super Tag Name', 'value' => 'An-awesome-value']);
             $html = $this->withHtml($this->get($entity->getUrl()));
             $html->assertElementExists('body.tag-name-mysupertagname.tag-value-anawesomevalue.tag-pair-mysupertagname-anawesomevalue');
diff --git a/tests/Helpers/EntityProvider.php b/tests/Helpers/EntityProvider.php
new file mode 100644 (file)
index 0000000..d3888e7
--- /dev/null
@@ -0,0 +1,201 @@
+<?php
+
+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\Page;
+use BookStack\Entities\Repos\BookRepo;
+use BookStack\Entities\Repos\BookshelfRepo;
+use BookStack\Entities\Repos\ChapterRepo;
+use BookStack\Entities\Repos\PageRepo;
+
+class EntityProvider
+{
+    /**
+     * @var array<string, int[]>
+     */
+    protected array $fetchCache = [
+        'book' => [],
+        'page' => [],
+        'bookshelf' => [],
+        'chapter' => [],
+    ];
+
+    /**
+     * Get an un-fetched page from the system.
+     */
+    public function page(): Page
+    {
+        /** @var Page $page */
+        $page = Page::query()->whereNotIn('id', $this->fetchCache['page'])->first();
+        $this->addToCache($page);
+        return $page;
+    }
+
+    /**
+     * Get an un-fetched chapter from the system.
+     */
+    public function chapter(): Chapter
+    {
+        /** @var Chapter $chapter */
+        $chapter = Chapter::query()->whereNotIn('id', $this->fetchCache['chapter'])->first();
+        $this->addToCache($chapter);
+        return $chapter;
+    }
+
+    /**
+     * Get an un-fetched book from the system.
+     */
+    public function book(): Book
+    {
+        /** @var Book $book */
+        $book = Book::query()->whereNotIn('id', $this->fetchCache['book'])->first();
+        $this->addToCache($book);
+        return $book;
+    }
+
+    /**
+     * Get an un-fetched shelf from the system.
+     */
+    public function shelf(): Bookshelf
+    {
+        /** @var Bookshelf $shelf */
+        $shelf = Bookshelf::query()->whereNotIn('id', $this->fetchCache['bookshelf'])->first();
+        $this->addToCache($shelf);
+        return $shelf;
+    }
+
+    /**
+     * Get all entity types from the system.
+     * @return array{page: Page, chapter: Chapter, book: Book, bookshelf: Bookshelf}
+     */
+    public function all(): array
+    {
+        return [
+            'page'      => $this->page(),
+            'chapter'   => $this->chapter(),
+            'book'      => $this->book(),
+            'bookshelf' => $this->shelf(),
+        ];
+    }
+
+    /**
+     * Create a book to page chain of entities that belong to a specific user.
+     * @return array{book: Book, chapter: Chapter, page: Page}
+     */
+    public function createChainBelongingToUser(User $creatorUser, ?User $updaterUser = null): array
+    {
+        if (empty($updaterUser)) {
+            $updaterUser = $creatorUser;
+        }
+
+        $userAttrs = ['created_by' => $creatorUser->id, 'owned_by' => $creatorUser->id, 'updated_by' => $updaterUser->id];
+        /** @var Book $book */
+        $book = Book::factory()->create($userAttrs);
+        $chapter = Chapter::factory()->create(array_merge(['book_id' => $book->id], $userAttrs));
+        $page = Page::factory()->create(array_merge(['book_id' => $book->id, 'chapter_id' => $chapter->id], $userAttrs));
+
+        $book->rebuildPermissions();
+        $this->addToCache([$page, $chapter, $book]);
+
+        return compact('book', 'chapter', 'page');
+    }
+
+    /**
+     * Create and return a new bookshelf.
+     */
+    public function newShelf(array $input = ['name' => 'test shelf', 'description' => 'My new test shelf']): Bookshelf
+    {
+        $shelf = app(BookshelfRepo::class)->create($input, []);
+        $this->addToCache($shelf);
+        return $shelf;
+    }
+
+    /**
+     * Create and return a new book.
+     */
+    public function newBook(array $input = ['name' => 'test book', 'description' => 'My new test book']): Book
+    {
+        $book = app(BookRepo::class)->create($input);
+        $this->addToCache($book);
+        return $book;
+    }
+
+    /**
+     * Create and return a new test chapter.
+     */
+    public function newChapter(array $input, Book $book): Chapter
+    {
+        $chapter = app(ChapterRepo::class)->create($input, $book);
+        $this->addToCache($chapter);
+        return $chapter;
+    }
+
+    /**
+     * 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);
+        $this->addToCache($draftPage);
+        return $pageRepo->publishDraft($draftPage, $input);
+    }
+
+    /**
+     * Regenerate the permission for an entity.
+     * Centralised to manage clearing of cached elements between requests.
+     */
+    public function regenPermissions(Entity $entity): void
+    {
+        $entity->rebuildPermissions();
+        $entity->load('jointPermissions');
+    }
+
+    /**
+     * Set the given entity as having restricted permissions, and apply the given
+     * permissions for the given roles.
+     * @param string[] $actions
+     * @param Role[] $roles
+     */
+    public function setPermissions(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->regenPermissions($entity);
+    }
+
+    /**
+     * @param Entity|Entity[] $entities
+     */
+    protected function addToCache($entities): void
+    {
+        if (!is_array($entities)) {
+            $entities = [$entities];
+        }
+
+        foreach ($entities as $entity) {
+            $this->fetchCache[$entity->getType()][] = $entity->id;
+        }
+    }
+}
index 1d968a2c92fdcf79ea009f6165eafd8a31b6fb01..bb42f49f2d353a56221fff53b540f42ee1dd4bf9 100644 (file)
@@ -24,7 +24,7 @@ class HomepageTest extends TestCase
         $this->asEditor();
         $name = 'My custom homepage';
         $content = str_repeat('This is the body content of my custom homepage.', 20);
-        $customPage = $this->newPage(['name' => $name, 'html' => $content]);
+        $customPage = $this->entities->newPage(['name' => $name, 'html' => $content]);
         $this->setSettings(['app-homepage' => $customPage->id]);
         $this->setSettings(['app-homepage-type' => 'page']);
 
@@ -41,7 +41,7 @@ class HomepageTest extends TestCase
         $this->asEditor();
         $name = 'My custom homepage';
         $content = str_repeat('This is the body content of my custom homepage.', 20);
-        $customPage = $this->newPage(['name' => $name, 'html' => $content]);
+        $customPage = $this->entities->newPage(['name' => $name, 'html' => $content]);
         $this->setSettings([
             'app-homepage'      => $customPage->id,
             'app-homepage-type' => 'page',
@@ -67,7 +67,7 @@ class HomepageTest extends TestCase
         $this->asEditor();
         $name = 'My custom homepage';
         $content = str_repeat('This is the body content of my custom homepage.', 20);
-        $customPage = $this->newPage(['name' => $name, 'html' => $content]);
+        $customPage = $this->entities->newPage(['name' => $name, 'html' => $content]);
         $this->setSettings([
             'app-homepage'      => $customPage->id,
             'app-homepage-type' => 'default',
@@ -107,7 +107,7 @@ class HomepageTest extends TestCase
         $included->save();
 
         $name = 'My custom homepage';
-        $customPage = $this->newPage(['name' => $name, 'html' => '{{@' . $included->id . '}}']);
+        $customPage = $this->entities->newPage(['name' => $name, 'html' => '{{@' . $included->id . '}}']);
         $this->setSettings(['app-homepage' => $customPage->id]);
         $this->setSettings(['app-homepage-type' => 'page']);
 
@@ -177,7 +177,7 @@ class HomepageTest extends TestCase
         $this->withHtml($homeVisit)->assertElementNotContains('.content-wrap', $book->name);
 
         // Ensure is visible again with entity-level view permission
-        $this->setEntityRestrictions($book, ['view'], [$editor->roles()->first()]);
+        $this->entities->setPermissions($book, ['view'], [$editor->roles()->first()]);
         $homeVisit = $this->get('/');
         $this->withHtml($homeVisit)->assertElementContains('.content-wrap', $shelf->name);
         $this->withHtml($homeVisit)->assertElementContains('.content-wrap', $book->name);
index ed037d3ac53c990fb7e7ab926cb761e4edda06ef..9e80b752adc31b4a067724576edd61ce1920400d 100644 (file)
@@ -36,7 +36,7 @@ class EntityPermissionsTest extends TestCase
             $this->user->roles->first(),
             $this->viewer->roles->first(),
         ];
-        $this->setEntityRestrictions($entity, $actions, $roles);
+        $this->entities->setPermissions($entity, $actions, $roles);
     }
 
     public function test_bookshelf_view_restriction()
index 2e3d84fa13e23a263870252f7201f2ed9818a827..7e9ce6100bfe2dc75c6ec694038f16508397f7d9 100644 (file)
@@ -27,7 +27,7 @@ class ExportPermissionsTest extends TestCase
             $resp->assertSee($pageContent);
         }
 
-        $this->setEntityRestrictions($page, []);
+        $this->entities->setPermissions($page, []);
 
         foreach ($formats as $format) {
             $resp = $this->get($chapter->getUrl("export/{$format}"));
@@ -55,7 +55,7 @@ class ExportPermissionsTest extends TestCase
             $resp->assertSee($pageContent);
         }
 
-        $this->setEntityRestrictions($page, []);
+        $this->entities->setPermissions($page, []);
 
         foreach ($formats as $format) {
             $resp = $this->get($book->getUrl("export/{$format}"));
index b992bfecc3f19fe8df717ba5a54904c295557366..a24d5f8d80fb70005b825c50e5ec70a23d9556b0 100644 (file)
@@ -285,7 +285,7 @@ class RolesTest extends TestCase
     {
         /** @var Page $otherUsersPage */
         $otherUsersPage = Page::query()->first();
-        $content = $this->createEntityChainBelongingToUser($this->user);
+        $content = $this->entities->createChainBelongingToUser($this->user);
 
         // Set a different creator on the page we're checking to ensure
         // that the owner fields are checked
@@ -355,9 +355,9 @@ class RolesTest extends TestCase
     {
         /** @var Bookshelf $otherShelf */
         $otherShelf = Bookshelf::query()->first();
-        $ownShelf = $this->newShelf(['name' => 'test-shelf', 'slug' => 'test-shelf']);
+        $ownShelf = $this->entities->newShelf(['name' => 'test-shelf', 'slug' => 'test-shelf']);
         $ownShelf->forceFill(['owned_by' => $this->user->id, 'updated_by' => $this->user->id])->save();
-        $this->regenEntityPermissions($ownShelf);
+        $this->entities->regenPermissions($ownShelf);
 
         $this->checkAccessPermission('bookshelf-update-own', [
             $ownShelf->getUrl('/edit'),
@@ -386,9 +386,9 @@ class RolesTest extends TestCase
         $this->giveUserPermissions($this->user, ['bookshelf-update-all']);
         /** @var Bookshelf $otherShelf */
         $otherShelf = Bookshelf::query()->first();
-        $ownShelf = $this->newShelf(['name' => 'test-shelf', 'slug' => 'test-shelf']);
+        $ownShelf = $this->entities->newShelf(['name' => 'test-shelf', 'slug' => 'test-shelf']);
         $ownShelf->forceFill(['owned_by' => $this->user->id, 'updated_by' => $this->user->id])->save();
-        $this->regenEntityPermissions($ownShelf);
+        $this->entities->regenPermissions($ownShelf);
 
         $this->checkAccessPermission('bookshelf-delete-own', [
             $ownShelf->getUrl('/delete'),
@@ -438,7 +438,7 @@ class RolesTest extends TestCase
     {
         /** @var Book $otherBook */
         $otherBook = Book::query()->take(1)->get()->first();
-        $ownBook = $this->createEntityChainBelongingToUser($this->user)['book'];
+        $ownBook = $this->entities->createChainBelongingToUser($this->user)['book'];
         $this->checkAccessPermission('book-update-own', [
             $ownBook->getUrl() . '/edit',
         ], [
@@ -466,7 +466,7 @@ class RolesTest extends TestCase
         $this->giveUserPermissions($this->user, ['book-update-all']);
         /** @var Book $otherBook */
         $otherBook = Book::query()->take(1)->get()->first();
-        $ownBook = $this->createEntityChainBelongingToUser($this->user)['book'];
+        $ownBook = $this->entities->createChainBelongingToUser($this->user)['book'];
         $this->checkAccessPermission('book-delete-own', [
             $ownBook->getUrl() . '/delete',
         ], [
@@ -501,7 +501,7 @@ class RolesTest extends TestCase
     {
         /** @var Book $book */
         $book = Book::query()->take(1)->get()->first();
-        $ownBook = $this->createEntityChainBelongingToUser($this->user)['book'];
+        $ownBook = $this->entities->createChainBelongingToUser($this->user)['book'];
         $this->checkAccessPermission('chapter-create-own', [
             $ownBook->getUrl('/create-chapter'),
         ], [
@@ -538,7 +538,7 @@ class RolesTest extends TestCase
     {
         /** @var Chapter $otherChapter */
         $otherChapter = Chapter::query()->first();
-        $ownChapter = $this->createEntityChainBelongingToUser($this->user)['chapter'];
+        $ownChapter = $this->entities->createChainBelongingToUser($this->user)['chapter'];
         $this->checkAccessPermission('chapter-update-own', [
             $ownChapter->getUrl() . '/edit',
         ], [
@@ -566,7 +566,7 @@ class RolesTest extends TestCase
         $this->giveUserPermissions($this->user, ['chapter-update-all']);
         /** @var Chapter $otherChapter */
         $otherChapter = Chapter::query()->first();
-        $ownChapter = $this->createEntityChainBelongingToUser($this->user)['chapter'];
+        $ownChapter = $this->entities->createChainBelongingToUser($this->user)['chapter'];
         $this->checkAccessPermission('chapter-delete-own', [
             $ownChapter->getUrl() . '/delete',
         ], [
@@ -608,7 +608,7 @@ class RolesTest extends TestCase
         /** @var Chapter $chapter */
         $chapter = Chapter::query()->first();
 
-        $entities = $this->createEntityChainBelongingToUser($this->user);
+        $entities = $this->entities->createChainBelongingToUser($this->user);
         $ownBook = $entities['book'];
         $ownChapter = $entities['chapter'];
 
@@ -699,7 +699,7 @@ class RolesTest extends TestCase
     {
         /** @var Page $otherPage */
         $otherPage = Page::query()->first();
-        $ownPage = $this->createEntityChainBelongingToUser($this->user)['page'];
+        $ownPage = $this->entities->createChainBelongingToUser($this->user)['page'];
         $this->checkAccessPermission('page-update-own', [
             $ownPage->getUrl() . '/edit',
         ], [
@@ -727,7 +727,7 @@ class RolesTest extends TestCase
         $this->giveUserPermissions($this->user, ['page-update-all']);
         /** @var Page $otherPage */
         $otherPage = Page::query()->first();
-        $ownPage = $this->createEntityChainBelongingToUser($this->user)['page'];
+        $ownPage = $this->entities->createChainBelongingToUser($this->user)['page'];
         $this->checkAccessPermission('page-delete-own', [
             $ownPage->getUrl() . '/delete',
         ], [
@@ -865,14 +865,14 @@ class RolesTest extends TestCase
         $admin = $this->getAdmin();
         // Book links
         $book = Book::factory()->create(['created_by' => $admin->id, 'updated_by' => $admin->id]);
-        $this->regenEntityPermissions($book);
+        $this->entities->regenPermissions($book);
         $this->actingAs($this->getViewer())->get($book->getUrl())
             ->assertDontSee('Create a new page')
             ->assertDontSee('Add a chapter');
 
         // Chapter links
         $chapter = Chapter::factory()->create(['created_by' => $admin->id, 'updated_by' => $admin->id, 'book_id' => $book->id]);
-        $this->regenEntityPermissions($chapter);
+        $this->entities->regenPermissions($chapter);
         $this->actingAs($this->getViewer())->get($chapter->getUrl())
             ->assertDontSee('Create a new page')
             ->assertDontSee('Sort the current book');
@@ -880,7 +880,7 @@ class RolesTest extends TestCase
 
     public function test_comment_create_permission()
     {
-        $ownPage = $this->createEntityChainBelongingToUser($this->user)['page'];
+        $ownPage = $this->entities->createChainBelongingToUser($this->user)['page'];
 
         $this->actingAs($this->user)
             ->addComment($ownPage)
@@ -895,7 +895,7 @@ class RolesTest extends TestCase
 
     public function test_comment_update_own_permission()
     {
-        $ownPage = $this->createEntityChainBelongingToUser($this->user)['page'];
+        $ownPage = $this->entities->createChainBelongingToUser($this->user)['page'];
         $this->giveUserPermissions($this->user, ['comment-create-all']);
         $this->actingAs($this->user)->addComment($ownPage);
         /** @var Comment $comment */
@@ -913,7 +913,7 @@ class RolesTest extends TestCase
     public function test_comment_update_all_permission()
     {
         /** @var Page $ownPage */
-        $ownPage = $this->createEntityChainBelongingToUser($this->user)['page'];
+        $ownPage = $this->entities->createChainBelongingToUser($this->user)['page'];
         $this->asAdmin()->addComment($ownPage);
         /** @var Comment $comment */
         $comment = $ownPage->comments()->latest()->first();
@@ -930,7 +930,7 @@ class RolesTest extends TestCase
     public function test_comment_delete_own_permission()
     {
         /** @var Page $ownPage */
-        $ownPage = $this->createEntityChainBelongingToUser($this->user)['page'];
+        $ownPage = $this->entities->createChainBelongingToUser($this->user)['page'];
         $this->giveUserPermissions($this->user, ['comment-create-all']);
         $this->actingAs($this->user)->addComment($ownPage);
 
@@ -949,7 +949,7 @@ class RolesTest extends TestCase
     public function test_comment_delete_all_permission()
     {
         /** @var Page $ownPage */
-        $ownPage = $this->createEntityChainBelongingToUser($this->user)['page'];
+        $ownPage = $this->entities->createChainBelongingToUser($this->user)['page'];
         $this->asAdmin()->addComment($ownPage);
         /** @var Comment $comment */
         $comment = $ownPage->comments()->latest()->first();
index 178e23e2ebc804fd5484ba93d5d8a3b8d3d9d5fe..309e09600c04c4d811dd4297f8779c91ae803fa1 100644 (file)
@@ -177,7 +177,7 @@ class PublicActionTest extends TestCase
         $this->setSettings(['app-public' => 'true']);
         /** @var Book $book */
         $book = Book::query()->first();
-        $this->setEntityRestrictions($book);
+        $this->entities->setPermissions($book);
 
         $resp = $this->get($book->getUrl());
         $resp->assertSee('Book not found');
index 856b699c3b0c2b203ecdb4fa2fbdb917cda80ae1..43b8a36ae3732e7b7c75faeeee0a86dbe17b2fc8 100644 (file)
@@ -10,7 +10,7 @@ class CrossLinkParserTest extends TestCase
 {
     public function test_instance_with_entity_resolvers_matches_entity_links()
     {
-        $entities = $this->getEachEntityType();
+        $entities = $this->entities->all();
         $otherPage = Page::query()->where('id', '!=', $entities['page']->id)->first();
 
         $html = '
index 3fd68d64750218c0ad483731eee170cecec997a8..59263ee0c5674015440695d71406b0b1ee21696e 100644 (file)
@@ -57,7 +57,7 @@ class ReferencesTest extends TestCase
 
     public function test_references_to_count_visible_on_entity_show_view()
     {
-        $entities = $this->getEachEntityType();
+        $entities = $this->entities->all();
         /** @var Page $otherPage */
         $otherPage = Page::query()->where('id', '!=', $entities['page']->id)->first();
 
@@ -79,7 +79,7 @@ class ReferencesTest extends TestCase
 
     public function test_references_to_visible_on_references_page()
     {
-        $entities = $this->getEachEntityType();
+        $entities = $this->entities->all();
         $this->asEditor();
         foreach ($entities as $entity) {
             $this->createReference($entities['page'], $entity);
@@ -101,7 +101,7 @@ class ReferencesTest extends TestCase
         $pageB = Page::query()->where('id', '!=', $page->id)->first();
         $this->createReference($pageB, $page);
 
-        $this->setEntityRestrictions($pageB);
+        $this->entities->setPermissions($pageB);
 
         $this->asEditor()->get($page->getUrl('/references'))->assertDontSee($pageB->name);
         $this->asAdmin()->get($page->getUrl('/references'))->assertSee($pageB->name);
index 5941941681d75bca4a9fdfdc2fe5c5d84de4f795..cc8e57453ea224834a0dbd1223dfc2e7a2111ba2 100644 (file)
@@ -7,15 +7,7 @@ use BookStack\Auth\Permissions\PermissionsRepo;
 use BookStack\Auth\Permissions\RolePermission;
 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\Page;
-use BookStack\Entities\Repos\BookRepo;
-use BookStack\Entities\Repos\BookshelfRepo;
-use BookStack\Entities\Repos\ChapterRepo;
-use BookStack\Entities\Repos\PageRepo;
 use BookStack\Settings\SettingService;
 use BookStack\Uploads\HttpFetcher;
 use GuzzleHttp\Client;
@@ -34,6 +26,7 @@ use Monolog\Handler\TestHandler;
 use Monolog\Logger;
 use Psr\Http\Client\ClientInterface;
 use Ssddanbrown\AssertHtml\TestsHtml;
+use Tests\Helpers\EntityProvider;
 
 abstract class TestCase extends BaseTestCase
 {
@@ -43,6 +36,13 @@ abstract class TestCase extends BaseTestCase
 
     protected ?User $admin = null;
     protected ?User $editor = null;
+    protected EntityProvider $entities;
+
+    protected function setUp(): void
+    {
+        $this->entities = new EntityProvider();
+        parent::setUp();
+    }
 
     /**
      * The base URL to use while testing the application.
@@ -135,51 +135,6 @@ abstract class TestCase extends BaseTestCase
         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.
      */
@@ -191,31 +146,6 @@ abstract class TestCase extends BaseTestCase
         }
     }
 
-    /**
-     * 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.
      */
@@ -262,27 +192,6 @@ abstract class TestCase extends BaseTestCase
         return $permissionRepo->saveNewRole($roleData);
     }
 
-    /**
-     * Create a group of entities that belong to a specific user.
-     *
-     * @return array{book: Book, chapter: Chapter, page: Page}
-     */
-    protected function createEntityChainBelongingToUser(User $creatorUser, ?User $updaterUser = null): array
-    {
-        if (empty($updaterUser)) {
-            $updaterUser = $creatorUser;
-        }
-
-        $userAttrs = ['created_by' => $creatorUser->id, 'owned_by' => $creatorUser->id, 'updated_by' => $updaterUser->id];
-        $book = Book::factory()->create($userAttrs);
-        $chapter = Chapter::factory()->create(array_merge(['book_id' => $book->id], $userAttrs));
-        $page = Page::factory()->create(array_merge(['book_id' => $book->id, 'chapter_id' => $chapter->id], $userAttrs));
-
-        $this->app->make(JointPermissionBuilder::class)->rebuildForEntity($book);
-
-        return compact('book', 'chapter', 'page');
-    }
-
     /**
      * Mock the HttpFetcher service and return the given data on fetch.
      */
@@ -460,17 +369,4 @@ abstract class TestCase extends BaseTestCase
 
         $this->assertDatabaseHas('activities', $detailsToCheck);
     }
-
-    /**
-     * @return array{page: Page, chapter: Chapter, book: Book, bookshelf: Bookshelf}
-     */
-    protected function getEachEntityType(): array
-    {
-        return [
-            'page'      => Page::query()->first(),
-            'chapter'   => Chapter::query()->first(),
-            'book'      => Book::query()->first(),
-            'bookshelf' => Bookshelf::query()->first(),
-        ];
-    }
 }
index 84f9e47f48deb804c14e56094e9daf9528e5d88b..184da214c4a5d8d03da6e8db63f7bd5aa45adf60 100644 (file)
@@ -342,7 +342,7 @@ class ImageTest extends TestCase
 
         $this->get($expectedUrl)->assertOk();
 
-        $this->setEntityRestrictions($page, [], []);
+        $this->entities->setPermissions($page, [], []);
 
         $resp = $this->get($expectedUrl);
         $resp->assertNotFound();
@@ -367,7 +367,7 @@ class ImageTest extends TestCase
 
         $this->get($expectedUrl)->assertOk();
 
-        $this->setEntityRestrictions($page, [], []);
+        $this->entities->setPermissions($page, [], []);
 
         $resp = $this->get($expectedUrl);
         $resp->assertNotFound();
@@ -400,7 +400,7 @@ class ImageTest extends TestCase
         $export = $this->get($pageB->getUrl('/export/html'));
         $this->assertStringContainsString($encodedImageContent, $export->getContent());
 
-        $this->setEntityRestrictions($pageA, [], []);
+        $this->entities->setPermissions($pageA, [], []);
 
         $export = $this->get($pageB->getUrl('/export/html'));
         $this->assertStringNotContainsString($encodedImageContent, $export->getContent());
index e6136962ad9c51fb45891b35130a5d8912f95221..77f1644a5e184335419e5ee121b1e9f816e2abbf 100644 (file)
@@ -29,7 +29,7 @@ class UserProfileTest extends TestCase
 
     public function test_profile_page_shows_recent_entities()
     {
-        $content = $this->createEntityChainBelongingToUser($this->user, $this->user);
+        $content = $this->entities->createChainBelongingToUser($this->user, $this->user);
 
         $resp = $this->asAdmin()->get('/user/' . $this->user->slug);
         // Check the recently created page is shown
@@ -50,7 +50,7 @@ class UserProfileTest extends TestCase
             ->assertElementContains('#content-counts', '0 Chapters')
             ->assertElementContains('#content-counts', '0 Pages');
 
-        $this->createEntityChainBelongingToUser($newUser, $newUser);
+        $this->entities->createChainBelongingToUser($newUser, $newUser);
 
         $resp = $this->asAdmin()->get('/user/' . $newUser->slug)
             ->assertSee($newUser->name);
@@ -63,7 +63,7 @@ class UserProfileTest extends TestCase
     {
         $newUser = User::factory()->create();
         $this->actingAs($newUser);
-        $entities = $this->createEntityChainBelongingToUser($newUser, $newUser);
+        $entities = $this->entities->createChainBelongingToUser($newUser, $newUser);
         Activity::add(ActivityType::BOOK_UPDATE, $entities['book']);
         Activity::add(ActivityType::PAGE_CREATE, $entities['page']);
 
@@ -77,7 +77,7 @@ class UserProfileTest extends TestCase
     {
         $newUser = User::factory()->create();
         $this->actingAs($newUser);
-        $entities = $this->createEntityChainBelongingToUser($newUser, $newUser);
+        $entities = $this->entities->createChainBelongingToUser($newUser, $newUser);
         Activity::add(ActivityType::BOOK_UPDATE, $entities['book']);
         Activity::add(ActivityType::PAGE_CREATE, $entities['page']);