diff --git a/app/Api/ListingResponseBuilder.php b/app/Api/ListingResponseBuilder.php
index 7de5ddf07..39752e6d4 100644
--- a/app/Api/ListingResponseBuilder.php
+++ b/app/Api/ListingResponseBuilder.php
@@ -2,7 +2,6 @@
 
 namespace BookStack\Api;
 
-use BookStack\Model;
 use Illuminate\Database\Eloquent\Builder;
 use Illuminate\Database\Eloquent\Collection;
 use Illuminate\Http\JsonResponse;
diff --git a/tests/Actions/AuditLogTest.php b/tests/Actions/AuditLogTest.php
index f4eebb364..987e23a45 100644
--- a/tests/Actions/AuditLogTest.php
+++ b/tests/Actions/AuditLogTest.php
@@ -6,8 +6,6 @@ use BookStack\Actions\Activity;
 use BookStack\Actions\ActivityLogger;
 use BookStack\Actions\ActivityType;
 use BookStack\Auth\UserRepo;
-use BookStack\Entities\Models\Chapter;
-use BookStack\Entities\Models\Page;
 use BookStack\Entities\Repos\PageRepo;
 use BookStack\Entities\Tools\TrashCan;
 use Carbon\Carbon;
@@ -15,8 +13,7 @@ use Tests\TestCase;
 
 class AuditLogTest extends TestCase
 {
-    /** @var ActivityLogger */
-    protected $activityService;
+    protected ActivityLogger $activityService;
 
     protected function setUp(): void
     {
diff --git a/tests/Actions/WebhookCallTest.php b/tests/Actions/WebhookCallTest.php
index 7964fd8af..7ca190200 100644
--- a/tests/Actions/WebhookCallTest.php
+++ b/tests/Actions/WebhookCallTest.php
@@ -7,7 +7,6 @@ use BookStack\Actions\ActivityType;
 use BookStack\Actions\DispatchWebhookJob;
 use BookStack\Actions\Webhook;
 use BookStack\Auth\User;
-use BookStack\Entities\Models\Page;
 use Illuminate\Http\Client\Request;
 use Illuminate\Support\Facades\Bus;
 use Illuminate\Support\Facades\Http;
diff --git a/tests/Actions/WebhookFormatTesting.php b/tests/Actions/WebhookFormatTesting.php
index 35467a76a..07341c75b 100644
--- a/tests/Actions/WebhookFormatTesting.php
+++ b/tests/Actions/WebhookFormatTesting.php
@@ -5,9 +5,6 @@ namespace Tests\Actions;
 use BookStack\Actions\ActivityType;
 use BookStack\Actions\Webhook;
 use BookStack\Actions\WebhookFormatter;
-use BookStack\Entities\Models\Book;
-use BookStack\Entities\Models\Chapter;
-use BookStack\Entities\Models\Page;
 use Illuminate\Support\Arr;
 use Tests\TestCase;
 
@@ -16,9 +13,9 @@ class WebhookFormatTesting extends TestCase
     public function test_entity_events_show_related_user_info()
     {
         $events = [
-            ActivityType::BOOK_UPDATE    => Book::query()->first(),
-            ActivityType::CHAPTER_CREATE => Chapter::query()->first(),
-            ActivityType::PAGE_MOVE      => Page::query()->first(),
+            ActivityType::BOOK_UPDATE    => $this->entities->book(),
+            ActivityType::CHAPTER_CREATE => $this->entities->chapter(),
+            ActivityType::PAGE_MOVE      => $this->entities->page(),
         ];
 
         foreach ($events as $event => $entity) {
diff --git a/tests/Api/BooksApiTest.php b/tests/Api/BooksApiTest.php
index 017322193..614185c93 100644
--- a/tests/Api/BooksApiTest.php
+++ b/tests/Api/BooksApiTest.php
@@ -68,7 +68,7 @@ class BooksApiTest extends TestCase
     public function test_read_endpoint()
     {
         $this->actingAsApiEditor();
-        $book = Book::visible()->first();
+        $book = $this->entities->book();
 
         $resp = $this->getJson($this->baseEndpoint . "/{$book->id}");
 
@@ -91,8 +91,7 @@ class BooksApiTest extends TestCase
     public function test_read_endpoint_includes_chapter_and_page_contents()
     {
         $this->actingAsApiEditor();
-        /** @var Book $book */
-        $book = Book::visible()->has('chapters')->has('pages')->first();
+        $book = $this->entities->bookHasChaptersAndPages();
         $chapter = $book->chapters()->first();
         $chapterPage = $chapter->pages()->first();
 
@@ -123,7 +122,7 @@ class BooksApiTest extends TestCase
     public function test_update_endpoint()
     {
         $this->actingAsApiEditor();
-        $book = Book::visible()->first();
+        $book = $this->entities->book();
         $details = [
             'name'        => 'My updated API book',
             'description' => 'A book created via the API',
@@ -140,7 +139,7 @@ class BooksApiTest extends TestCase
     public function test_update_increments_updated_date_if_only_tags_are_sent()
     {
         $this->actingAsApiEditor();
-        $book = Book::visible()->first();
+        $book = $this->entities->book();
         DB::table('books')->where('id', '=', $book->id)->update(['updated_at' => Carbon::now()->subWeek()]);
 
         $details = [
@@ -156,7 +155,7 @@ class BooksApiTest extends TestCase
     {
         $this->actingAsApiEditor();
         /** @var Book $book */
-        $book = Book::visible()->first();
+        $book = $this->entities->book();
         $this->assertNull($book->cover);
         $file = $this->getTestImage('image.png');
 
@@ -191,7 +190,7 @@ class BooksApiTest extends TestCase
     public function test_delete_endpoint()
     {
         $this->actingAsApiEditor();
-        $book = Book::visible()->first();
+        $book = $this->entities->book();
         $resp = $this->deleteJson($this->baseEndpoint . "/{$book->id}");
 
         $resp->assertStatus(204);
@@ -201,7 +200,7 @@ class BooksApiTest extends TestCase
     public function test_export_html_endpoint()
     {
         $this->actingAsApiEditor();
-        $book = Book::visible()->first();
+        $book = $this->entities->book();
 
         $resp = $this->get($this->baseEndpoint . "/{$book->id}/export/html");
         $resp->assertStatus(200);
@@ -212,7 +211,7 @@ class BooksApiTest extends TestCase
     public function test_export_plain_text_endpoint()
     {
         $this->actingAsApiEditor();
-        $book = Book::visible()->first();
+        $book = $this->entities->book();
 
         $resp = $this->get($this->baseEndpoint . "/{$book->id}/export/plaintext");
         $resp->assertStatus(200);
@@ -223,7 +222,7 @@ class BooksApiTest extends TestCase
     public function test_export_pdf_endpoint()
     {
         $this->actingAsApiEditor();
-        $book = Book::visible()->first();
+        $book = $this->entities->book();
 
         $resp = $this->get($this->baseEndpoint . "/{$book->id}/export/pdf");
         $resp->assertStatus(200);
@@ -249,7 +248,7 @@ class BooksApiTest extends TestCase
         $this->actingAsApiEditor();
         $this->removePermissionFromUser($this->getEditor(), 'content-export');
 
-        $book = Book::visible()->first();
+        $book = $this->entities->book();
         foreach ($types as $type) {
             $resp = $this->get($this->baseEndpoint . "/{$book->id}/export/{$type}");
             $this->assertPermissionError($resp);
diff --git a/tests/Api/ChaptersApiTest.php b/tests/Api/ChaptersApiTest.php
index 22be2482c..d2db0313f 100644
--- a/tests/Api/ChaptersApiTest.php
+++ b/tests/Api/ChaptersApiTest.php
@@ -2,7 +2,6 @@
 
 namespace Tests\Api;
 
-use BookStack\Entities\Models\Book;
 use BookStack\Entities\Models\Chapter;
 use Carbon\Carbon;
 use Illuminate\Support\Facades\DB;
@@ -95,7 +94,7 @@ class ChaptersApiTest extends TestCase
     public function test_read_endpoint()
     {
         $this->actingAsApiEditor();
-        $chapter = Chapter::visible()->first();
+        $chapter = $this->entities->chapter();
         $page = $chapter->pages()->first();
 
         $resp = $this->getJson($this->baseEndpoint . "/{$chapter->id}");
@@ -127,7 +126,7 @@ class ChaptersApiTest extends TestCase
     public function test_update_endpoint()
     {
         $this->actingAsApiEditor();
-        $chapter = Chapter::visible()->first();
+        $chapter = $this->entities->chapter();
         $details = [
             'name'        => 'My updated API chapter',
             'description' => 'A chapter created via the API',
@@ -152,7 +151,7 @@ class ChaptersApiTest extends TestCase
     public function test_update_increments_updated_date_if_only_tags_are_sent()
     {
         $this->actingAsApiEditor();
-        $chapter = Chapter::visible()->first();
+        $chapter = $this->entities->chapter();
         DB::table('chapters')->where('id', '=', $chapter->id)->update(['updated_at' => Carbon::now()->subWeek()]);
 
         $details = [
@@ -167,7 +166,7 @@ class ChaptersApiTest extends TestCase
     public function test_delete_endpoint()
     {
         $this->actingAsApiEditor();
-        $chapter = Chapter::visible()->first();
+        $chapter = $this->entities->chapter();
         $resp = $this->deleteJson($this->baseEndpoint . "/{$chapter->id}");
 
         $resp->assertStatus(204);
@@ -177,7 +176,7 @@ class ChaptersApiTest extends TestCase
     public function test_export_html_endpoint()
     {
         $this->actingAsApiEditor();
-        $chapter = Chapter::visible()->first();
+        $chapter = $this->entities->chapter();
 
         $resp = $this->get($this->baseEndpoint . "/{$chapter->id}/export/html");
         $resp->assertStatus(200);
@@ -188,7 +187,7 @@ class ChaptersApiTest extends TestCase
     public function test_export_plain_text_endpoint()
     {
         $this->actingAsApiEditor();
-        $chapter = Chapter::visible()->first();
+        $chapter = $this->entities->chapter();
 
         $resp = $this->get($this->baseEndpoint . "/{$chapter->id}/export/plaintext");
         $resp->assertStatus(200);
@@ -199,7 +198,7 @@ class ChaptersApiTest extends TestCase
     public function test_export_pdf_endpoint()
     {
         $this->actingAsApiEditor();
-        $chapter = Chapter::visible()->first();
+        $chapter = $this->entities->chapter();
 
         $resp = $this->get($this->baseEndpoint . "/{$chapter->id}/export/pdf");
         $resp->assertStatus(200);
diff --git a/tests/Api/PagesApiTest.php b/tests/Api/PagesApiTest.php
index fe1fc8d36..8c533680f 100644
--- a/tests/Api/PagesApiTest.php
+++ b/tests/Api/PagesApiTest.php
@@ -2,7 +2,6 @@
 
 namespace Tests\Api;
 
-use BookStack\Entities\Models\Book;
 use BookStack\Entities\Models\Chapter;
 use BookStack\Entities\Models\Page;
 use Carbon\Carbon;
@@ -95,11 +94,11 @@ class PagesApiTest extends TestCase
             'chapter_id' => ['The chapter id field is required when book id is not present.'],
         ]));
 
-        $chapter = Chapter::visible()->first();
+        $chapter = $this->entities->chapter();
         $resp = $this->postJson($this->baseEndpoint, array_merge($details, ['chapter_id' => $chapter->id]));
         $resp->assertStatus(200);
 
-        $book = Book::visible()->first();
+        $book = $this->entities->book();
         $resp = $this->postJson($this->baseEndpoint, array_merge($details, ['book_id' => $book->id]));
         $resp->assertStatus(200);
     }
@@ -107,7 +106,7 @@ class PagesApiTest extends TestCase
     public function test_markdown_can_be_provided_for_create()
     {
         $this->actingAsApiEditor();
-        $book = Book::visible()->first();
+        $book = $this->entities->book();
         $details = [
             'book_id'  => $book->id,
             'name'     => 'My api page',
@@ -126,7 +125,7 @@ class PagesApiTest extends TestCase
     public function test_read_endpoint()
     {
         $this->actingAsApiEditor();
-        $page = Page::visible()->first();
+        $page = $this->entities->page();
 
         $resp = $this->getJson($this->baseEndpoint . "/{$page->id}");
         $resp->assertStatus(200);
@@ -149,7 +148,7 @@ class PagesApiTest extends TestCase
     public function test_read_endpoint_provides_rendered_html()
     {
         $this->actingAsApiEditor();
-        $page = Page::visible()->first();
+        $page = $this->entities->page();
         $page->html = "<p>testing</p><script>alert('danger')</script><h1>Hello</h1>";
         $page->save();
 
@@ -163,7 +162,7 @@ class PagesApiTest extends TestCase
     public function test_update_endpoint()
     {
         $this->actingAsApiEditor();
-        $page = Page::visible()->first();
+        $page = $this->entities->page();
         $details = [
             'name' => 'My updated API page',
             'html' => '<p>A page created via the API</p>',
@@ -189,7 +188,7 @@ class PagesApiTest extends TestCase
     public function test_providing_new_chapter_id_on_update_will_move_page()
     {
         $this->actingAsApiEditor();
-        $page = Page::visible()->first();
+        $page = $this->entities->page();
         $chapter = Chapter::visible()->where('book_id', '!=', $page->book_id)->first();
         $details = [
             'name'       => 'My updated API page',
@@ -208,7 +207,7 @@ class PagesApiTest extends TestCase
     public function test_providing_move_via_update_requires_page_create_permission_on_new_parent()
     {
         $this->actingAsApiEditor();
-        $page = Page::visible()->first();
+        $page = $this->entities->page();
         $chapter = Chapter::visible()->where('book_id', '!=', $page->book_id)->first();
         $this->entities->setPermissions($chapter, ['view'], [$this->getEditor()->roles()->first()]);
         $details = [
@@ -224,7 +223,7 @@ class PagesApiTest extends TestCase
     public function test_update_endpoint_does_not_wipe_content_if_no_html_or_md_provided()
     {
         $this->actingAsApiEditor();
-        $page = Page::visible()->first();
+        $page = $this->entities->page();
         $originalContent = $page->html;
         $details = [
             'name' => 'My updated API page',
@@ -245,7 +244,7 @@ class PagesApiTest extends TestCase
     public function test_update_increments_updated_date_if_only_tags_are_sent()
     {
         $this->actingAsApiEditor();
-        $page = Page::visible()->first();
+        $page = $this->entities->page();
         DB::table('pages')->where('id', '=', $page->id)->update(['updated_at' => Carbon::now()->subWeek()]);
 
         $details = [
@@ -262,7 +261,7 @@ class PagesApiTest extends TestCase
     public function test_delete_endpoint()
     {
         $this->actingAsApiEditor();
-        $page = Page::visible()->first();
+        $page = $this->entities->page();
         $resp = $this->deleteJson($this->baseEndpoint . "/{$page->id}");
 
         $resp->assertStatus(204);
@@ -272,7 +271,7 @@ class PagesApiTest extends TestCase
     public function test_export_html_endpoint()
     {
         $this->actingAsApiEditor();
-        $page = Page::visible()->first();
+        $page = $this->entities->page();
 
         $resp = $this->get($this->baseEndpoint . "/{$page->id}/export/html");
         $resp->assertStatus(200);
@@ -283,7 +282,7 @@ class PagesApiTest extends TestCase
     public function test_export_plain_text_endpoint()
     {
         $this->actingAsApiEditor();
-        $page = Page::visible()->first();
+        $page = $this->entities->page();
 
         $resp = $this->get($this->baseEndpoint . "/{$page->id}/export/plaintext");
         $resp->assertStatus(200);
@@ -294,7 +293,7 @@ class PagesApiTest extends TestCase
     public function test_export_pdf_endpoint()
     {
         $this->actingAsApiEditor();
-        $page = Page::visible()->first();
+        $page = $this->entities->page();
 
         $resp = $this->get($this->baseEndpoint . "/{$page->id}/export/pdf");
         $resp->assertStatus(200);
@@ -304,7 +303,7 @@ class PagesApiTest extends TestCase
     public function test_export_markdown_endpoint()
     {
         $this->actingAsApiEditor();
-        $page = Page::visible()->first();
+        $page = $this->entities->page();
 
         $resp = $this->get($this->baseEndpoint . "/{$page->id}/export/markdown");
         $resp->assertStatus(200);
@@ -318,7 +317,7 @@ class PagesApiTest extends TestCase
         $this->actingAsApiEditor();
         $this->removePermissionFromUser($this->getEditor(), 'content-export');
 
-        $page = Page::visible()->first();
+        $page = $this->entities->page();
         foreach ($types as $type) {
             $resp = $this->get($this->baseEndpoint . "/{$page->id}/export/{$type}");
             $this->assertPermissionError($resp);
diff --git a/tests/Api/RecycleBinApiTest.php b/tests/Api/RecycleBinApiTest.php
index cdb51f85a..bc7249987 100644
--- a/tests/Api/RecycleBinApiTest.php
+++ b/tests/Api/RecycleBinApiTest.php
@@ -4,7 +4,6 @@ namespace Tests\Api;
 
 use BookStack\Entities\Models\Book;
 use BookStack\Entities\Models\Deletion;
-use BookStack\Entities\Models\Page;
 use Illuminate\Support\Collection;
 use Tests\TestCase;
 
@@ -111,7 +110,7 @@ class RecycleBinApiTest extends TestCase
     public function test_index_endpoint_returns_parent()
     {
         $admin = $this->getAdmin();
-        $page = Page::query()->whereHas('chapter')->with('chapter')->first();
+        $page = $this->entities->pageWithinChapter();
 
         $this->actingAs($admin)->delete($page->getUrl());
         $deletion = Deletion::query()->orderBy('id')->first();
diff --git a/tests/Auth/AuthTest.php b/tests/Auth/AuthTest.php
index 4456ed459..3220b2aac 100644
--- a/tests/Auth/AuthTest.php
+++ b/tests/Auth/AuthTest.php
@@ -3,7 +3,6 @@
 namespace Tests\Auth;
 
 use BookStack\Auth\Access\Mfa\MfaSession;
-use BookStack\Entities\Models\Page;
 use Illuminate\Testing\TestResponse;
 use Tests\TestCase;
 
diff --git a/tests/Commands/ClearActivityCommandTest.php b/tests/Commands/ClearActivityCommandTest.php
index abc8bc7f4..cf2fba0d6 100644
--- a/tests/Commands/ClearActivityCommandTest.php
+++ b/tests/Commands/ClearActivityCommandTest.php
@@ -3,7 +3,6 @@
 namespace Tests\Commands;
 
 use BookStack\Actions\ActivityType;
-use BookStack\Entities\Models\Page;
 use BookStack\Facades\Activity;
 use Illuminate\Support\Facades\Artisan;
 use Illuminate\Support\Facades\DB;
diff --git a/tests/Commands/CopyShelfPermissionsCommandTest.php b/tests/Commands/CopyShelfPermissionsCommandTest.php
index bd96f2cc5..55b710ba9 100644
--- a/tests/Commands/CopyShelfPermissionsCommandTest.php
+++ b/tests/Commands/CopyShelfPermissionsCommandTest.php
@@ -16,7 +16,7 @@ class CopyShelfPermissionsCommandTest extends TestCase
 
     public function test_copy_shelf_permissions_command_using_slug()
     {
-        $shelf = Bookshelf::first();
+        $shelf = $this->entities->shelf();
         $child = $shelf->books()->first();
         $editorRole = $this->getEditor()->roles()->first();
         $this->assertFalse(boolval($child->restricted), 'Child book should not be restricted by default');
diff --git a/tests/Commands/RegenerateReferencesCommandTest.php b/tests/Commands/RegenerateReferencesCommandTest.php
index 2c737712a..36af0d7cc 100644
--- a/tests/Commands/RegenerateReferencesCommandTest.php
+++ b/tests/Commands/RegenerateReferencesCommandTest.php
@@ -2,7 +2,6 @@
 
 namespace Tests\Commands;
 
-use BookStack\Entities\Models\Page;
 use Illuminate\Support\Facades\DB;
 use Tests\TestCase;
 
diff --git a/tests/Commands/UpdateUrlCommandTest.php b/tests/Commands/UpdateUrlCommandTest.php
index c4b09162e..c07a80312 100644
--- a/tests/Commands/UpdateUrlCommandTest.php
+++ b/tests/Commands/UpdateUrlCommandTest.php
@@ -2,7 +2,6 @@
 
 namespace Tests\Commands;
 
-use BookStack\Entities\Models\Page;
 use Symfony\Component\Console\Exception\RuntimeException;
 use Tests\TestCase;
 
diff --git a/tests/Entity/BookShelfTest.php b/tests/Entity/BookShelfTest.php
index 798edeadf..1e740b94e 100644
--- a/tests/Entity/BookShelfTest.php
+++ b/tests/Entity/BookShelfTest.php
@@ -39,7 +39,7 @@ class BookShelfTest extends TestCase
     {
         $user = User::factory()->create();
         $this->giveUserPermissions($user, ['image-create-all']);
-        $shelf = Bookshelf::first();
+        $shelf = $this->entities->shelf();
         $userRole = $user->roles()->first();
 
         $resp = $this->actingAs($user)->get('/');
@@ -130,7 +130,7 @@ class BookShelfTest extends TestCase
 
     public function test_shelf_view()
     {
-        $shelf = Bookshelf::first();
+        $shelf = $this->entities->shelf();
         $resp = $this->asEditor()->get($shelf->getUrl());
         $resp->assertStatus(200);
         $resp->assertSeeText($shelf->name);
@@ -143,7 +143,7 @@ class BookShelfTest extends TestCase
 
     public function test_shelf_view_shows_action_buttons()
     {
-        $shelf = Bookshelf::first();
+        $shelf = $this->entities->shelf();
         $resp = $this->asAdmin()->get($shelf->getUrl());
         $resp->assertSee($shelf->getUrl('/create-book'));
         $resp->assertSee($shelf->getUrl('/edit'));
@@ -201,7 +201,7 @@ class BookShelfTest extends TestCase
 
     public function test_shelf_edit()
     {
-        $shelf = Bookshelf::first();
+        $shelf = $this->entities->shelf();
         $resp = $this->asEditor()->get($shelf->getUrl('/edit'));
         $resp->assertSeeText('Edit Shelf');
 
@@ -239,7 +239,7 @@ class BookShelfTest extends TestCase
 
     public function test_shelf_create_new_book()
     {
-        $shelf = Bookshelf::first();
+        $shelf = $this->entities->shelf();
         $resp = $this->asEditor()->get($shelf->getUrl('/create-book'));
 
         $resp->assertSee('Create New Book');
@@ -288,7 +288,7 @@ class BookShelfTest extends TestCase
 
     public function test_shelf_copy_permissions()
     {
-        $shelf = Bookshelf::first();
+        $shelf = $this->entities->shelf();
         $resp = $this->asAdmin()->get($shelf->getUrl('/permissions'));
         $resp->assertSeeText('Copy Permissions');
         $resp->assertSee("action=\"{$shelf->getUrl('/copy-permissions')}\"", false);
@@ -311,14 +311,14 @@ class BookShelfTest extends TestCase
 
     public function test_permission_page_has_a_warning_about_no_cascading()
     {
-        $shelf = Bookshelf::first();
+        $shelf = $this->entities->shelf();
         $resp = $this->asAdmin()->get($shelf->getUrl('/permissions'));
         $resp->assertSeeText('Permissions on shelves do not automatically cascade to contained books.');
     }
 
     public function test_bookshelves_show_in_breadcrumbs_if_in_context()
     {
-        $shelf = Bookshelf::first();
+        $shelf = $this->entities->shelf();
         $shelfBook = $shelf->books()->first();
         $shelfPage = $shelfBook->pages()->first();
         $this->asAdmin();
diff --git a/tests/Entity/ChapterTest.php b/tests/Entity/ChapterTest.php
index fc8adb01d..afc60c20e 100644
--- a/tests/Entity/ChapterTest.php
+++ b/tests/Entity/ChapterTest.php
@@ -96,8 +96,7 @@ class ChapterTest extends TestCase
 
     public function test_copy_does_not_copy_non_visible_pages()
     {
-        /** @var Chapter $chapter */
-        $chapter = Chapter::query()->whereHas('pages')->first();
+        $chapter = $this->entities->chapterHasPages();
 
         // Hide pages to all non-admin roles
         /** @var Page $page */
@@ -118,8 +117,7 @@ class ChapterTest extends TestCase
 
     public function test_copy_does_not_copy_pages_if_user_cant_page_create()
     {
-        /** @var Chapter $chapter */
-        $chapter = Chapter::query()->whereHas('pages')->first();
+        $chapter = $this->entities->chapterHasPages();
         $viewer = $this->getViewer();
         $this->giveUserPermissions($viewer, ['chapter-create-all']);
 
diff --git a/tests/Entity/CommentSettingTest.php b/tests/Entity/CommentSettingTest.php
index 0e3199979..7de457441 100644
--- a/tests/Entity/CommentSettingTest.php
+++ b/tests/Entity/CommentSettingTest.php
@@ -2,34 +2,27 @@
 
 namespace Tests\Entity;
 
-use BookStack\Entities\Models\Page;
 use Tests\TestCase;
 
 class CommentSettingTest extends TestCase
 {
-    protected $page;
-
-    protected function setUp(): void
-    {
-        parent::setUp();
-        $this->page = Page::query()->first();
-    }
-
     public function test_comment_disable()
     {
+        $page = $this->entities->page();
         $this->setSettings(['app-disable-comments' => 'true']);
         $this->asAdmin();
 
-        $resp = $this->asAdmin()->get($this->page->getUrl());
+        $resp = $this->asAdmin()->get($page->getUrl());
         $this->withHtml($resp)->assertElementNotExists('.comments-list');
     }
 
     public function test_comment_enable()
     {
+        $page = $this->entities->page();
         $this->setSettings(['app-disable-comments' => 'false']);
         $this->asAdmin();
 
-        $resp = $this->asAdmin()->get($this->page->getUrl());
+        $resp = $this->asAdmin()->get($page->getUrl());
         $this->withHtml($resp)->assertElementExists('.comments-list');
     }
 }
diff --git a/tests/Entity/CommentTest.php b/tests/Entity/CommentTest.php
index 1e8ecbcac..99e3525a0 100644
--- a/tests/Entity/CommentTest.php
+++ b/tests/Entity/CommentTest.php
@@ -11,7 +11,7 @@ class CommentTest extends TestCase
     public function test_add_comment()
     {
         $this->asAdmin();
-        $page = Page::first();
+        $page = $this->entities->page();
 
         $comment = Comment::factory()->make(['parent_id' => 2]);
         $resp = $this->postJson("/comment/$page->id", $comment->getAttributes());
@@ -34,7 +34,7 @@ class CommentTest extends TestCase
     public function test_comment_edit()
     {
         $this->asAdmin();
-        $page = Page::first();
+        $page = $this->entities->page();
 
         $comment = Comment::factory()->make();
         $this->postJson("/comment/$page->id", $comment->getAttributes());
@@ -58,7 +58,7 @@ class CommentTest extends TestCase
     public function test_comment_delete()
     {
         $this->asAdmin();
-        $page = Page::first();
+        $page = $this->entities->page();
 
         $comment = Comment::factory()->make();
         $this->postJson("/comment/$page->id", $comment->getAttributes());
@@ -75,7 +75,7 @@ class CommentTest extends TestCase
 
     public function test_comments_converts_markdown_input_to_html()
     {
-        $page = Page::first();
+        $page = $this->entities->page();
         $this->asAdmin()->postJson("/comment/$page->id", [
             'text' => '# My Title',
         ]);
@@ -94,7 +94,7 @@ class CommentTest extends TestCase
     public function test_html_cannot_be_injected_via_comment_content()
     {
         $this->asAdmin();
-        $page = Page::first();
+        $page = $this->entities->page();
 
         $script = '<script>const a = "script";</script>\n\n# sometextinthecomment';
         $this->postJson("/comment/$page->id", [
diff --git a/tests/Entity/ConvertTest.php b/tests/Entity/ConvertTest.php
index 15205c9ad..16dd89068 100644
--- a/tests/Entity/ConvertTest.php
+++ b/tests/Entity/ConvertTest.php
@@ -24,8 +24,7 @@ class ConvertTest extends TestCase
 
     public function test_convert_chapter_to_book()
     {
-        /** @var Chapter $chapter */
-        $chapter = Chapter::query()->whereHas('pages')->first();
+        $chapter = $this->entities->chapterHasPages();
         $chapter->tags()->save(new Tag(['name' => 'Category', 'value' => 'Penguins']));
         /** @var Page $childPage */
         $childPage = $chapter->pages()->first();
diff --git a/tests/Entity/EntityAccessTest.php b/tests/Entity/EntityAccessTest.php
index e3d129d5e..2bb32fde8 100644
--- a/tests/Entity/EntityAccessTest.php
+++ b/tests/Entity/EntityAccessTest.php
@@ -4,7 +4,6 @@ namespace Tests\Entity;
 
 use BookStack\Auth\UserRepo;
 use BookStack\Entities\Models\Entity;
-use BookStack\Entities\Repos\PageRepo;
 use Tests\TestCase;
 
 class EntityAccessTest extends TestCase
@@ -16,7 +15,7 @@ class EntityAccessTest extends TestCase
         $updater = $this->getViewer();
         $entities = $this->entities->createChainBelongingToUser($creator, $updater);
         app()->make(UserRepo::class)->destroy($creator);
-        app()->make(PageRepo::class)->update($entities['page'], ['html' => '<p>hello!</p>>']);
+        $this->entities->updatePage($entities['page'], ['html' => '<p>hello!</p>>']);
 
         $this->checkEntitiesViewable($entities);
     }
@@ -28,7 +27,7 @@ class EntityAccessTest extends TestCase
         $updater = $this->getEditor();
         $entities = $this->entities->createChainBelongingToUser($creator, $updater);
         app()->make(UserRepo::class)->destroy($updater);
-        app()->make(PageRepo::class)->update($entities['page'], ['html' => '<p>Hello there!</p>']);
+        $this->entities->updatePage($entities['page'], ['html' => '<p>Hello there!</p>']);
 
         $this->checkEntitiesViewable($entities);
     }
diff --git a/tests/Entity/EntitySearchTest.php b/tests/Entity/EntitySearchTest.php
index 82b97e6f3..cdb500a45 100644
--- a/tests/Entity/EntitySearchTest.php
+++ b/tests/Entity/EntitySearchTest.php
@@ -5,15 +5,13 @@ namespace Tests\Entity;
 use BookStack\Actions\Tag;
 use BookStack\Entities\Models\Book;
 use BookStack\Entities\Models\Bookshelf;
-use BookStack\Entities\Models\Chapter;
-use BookStack\Entities\Models\Page;
 use Tests\TestCase;
 
 class EntitySearchTest extends TestCase
 {
     public function test_page_search()
     {
-        $book = Book::all()->first();
+        $book = $this->entities->book();
         $page = $book->pages->first();
 
         $search = $this->asEditor()->get('/search?term=' . urlencode($page->name));
@@ -71,7 +69,7 @@ class EntitySearchTest extends TestCase
 
     public function test_chapter_search()
     {
-        $chapter = Chapter::has('pages')->first();
+        $chapter = $this->entities->chapterHasPages();
         $page = $chapter->pages[0];
 
         $pageTestResp = $this->asEditor()->get('/search/chapter/' . $chapter->id . '?term=' . urlencode($page->name));
@@ -91,10 +89,10 @@ class EntitySearchTest extends TestCase
             ]),
         ];
 
-        $pageA = Page::first();
+        $pageA = $this->entities->page();
         $pageA->tags()->saveMany($newTags);
 
-        $pageB = Page::all()->last();
+        $pageB = $this->entities->page();
         $pageB->tags()->create(['name' => 'animal', 'value' => 'dog']);
 
         $this->asEditor();
@@ -197,7 +195,7 @@ class EntitySearchTest extends TestCase
     public function test_ajax_entity_search()
     {
         $page = $this->entities->newPage(['name' => 'my ajax search test', 'html' => 'ajax test']);
-        $notVisitedPage = Page::first();
+        $notVisitedPage = $this->entities->page();
 
         // Visit the page to make popular
         $this->asEditor()->get($page->getUrl());
@@ -215,7 +213,7 @@ class EntitySearchTest extends TestCase
 
     public function test_ajax_entity_search_shows_breadcrumbs()
     {
-        $chapter = Chapter::first();
+        $chapter = $this->entities->chapter();
         $page = $chapter->pages->first();
         $this->asEditor();
 
@@ -246,7 +244,7 @@ class EntitySearchTest extends TestCase
 
     public function test_sibling_search_for_pages()
     {
-        $chapter = Chapter::query()->with('pages')->first();
+        $chapter = $this->entities->chapterHasPages();
         $this->assertGreaterThan(2, count($chapter->pages), 'Ensure we\'re testing with at least 1 sibling');
         $page = $chapter->pages->first();
 
@@ -261,7 +259,7 @@ class EntitySearchTest extends TestCase
 
     public function test_sibling_search_for_pages_without_chapter()
     {
-        $page = Page::query()->where('chapter_id', '=', 0)->firstOrFail();
+        $page = $this->entities->pageNotWithinChapter();
         $bookChildren = $page->book->getDirectChildren();
         $this->assertGreaterThan(2, count($bookChildren), 'Ensure we\'re testing with at least 1 sibling');
 
@@ -276,7 +274,7 @@ class EntitySearchTest extends TestCase
 
     public function test_sibling_search_for_chapters()
     {
-        $chapter = Chapter::query()->firstOrFail();
+        $chapter = $this->entities->chapter();
         $bookChildren = $chapter->book->getDirectChildren();
         $this->assertGreaterThan(2, count($bookChildren), 'Ensure we\'re testing with at least 1 sibling');
 
diff --git a/tests/Entity/ExportTest.php b/tests/Entity/ExportTest.php
index 1d4a23560..0f80bdd49 100644
--- a/tests/Entity/ExportTest.php
+++ b/tests/Entity/ExportTest.php
@@ -311,7 +311,7 @@ class ExportTest extends TestCase
 
     public function test_page_pdf_export_opens_details_blocks()
     {
-        $page = Page::query()->first()->forceFill([
+        $page = $this->entities->page()->forceFill([
             'html'     => '<details><summary>Hello</summary><p>Content!</p></details>',
         ]);
         $page->save();
@@ -339,7 +339,7 @@ class ExportTest extends TestCase
 
     public function test_page_markdown_export_uses_existing_markdown_if_apparent()
     {
-        $page = Page::query()->first()->forceFill([
+        $page = $this->entities->page()->forceFill([
             'markdown' => '# A header',
             'html'     => '<h1>Dogcat</h1>',
         ]);
@@ -352,7 +352,7 @@ class ExportTest extends TestCase
 
     public function test_page_markdown_export_converts_html_where_no_markdown()
     {
-        $page = Page::query()->first()->forceFill([
+        $page = $this->entities->page()->forceFill([
             'markdown' => '',
             'html'     => '<h1>Dogcat</h1><p>Some <strong>bold</strong> text</p>',
         ]);
@@ -446,9 +446,9 @@ class ExportTest extends TestCase
     public function test_html_exports_contain_csp_meta_tag()
     {
         $entities = [
-            Page::query()->first(),
-            Book::query()->first(),
-            Chapter::query()->first(),
+            $this->entities->page(),
+            $this->entities->book(),
+            $this->entities->chapter(),
         ];
 
         foreach ($entities as $entity) {
diff --git a/tests/Entity/PageContentTest.php b/tests/Entity/PageContentTest.php
index c6de4dc51..0c9854206 100644
--- a/tests/Entity/PageContentTest.php
+++ b/tests/Entity/PageContentTest.php
@@ -16,7 +16,7 @@ class PageContentTest extends TestCase
     public function test_page_includes()
     {
         $page = $this->entities->page();
-        $secondPage = Page::query()->where('id', '!=', $page->id)->first();
+        $secondPage = $this->entities->page();
 
         $secondPage->html = "<p id='section1'>Hello, This is a test</p><p id='section2'>This is a second block of content</p>";
         $secondPage->save();
@@ -45,7 +45,7 @@ class PageContentTest extends TestCase
     public function test_saving_page_with_includes()
     {
         $page = $this->entities->page();
-        $secondPage = Page::query()->where('id', '!=', $page->id)->first();
+        $secondPage = $this->entities->page();
 
         $this->asEditor();
         $includeTag = '{{@' . $secondPage->id . '}}';
diff --git a/tests/Entity/PageDraftTest.php b/tests/Entity/PageDraftTest.php
index acf6b01e8..010173852 100644
--- a/tests/Entity/PageDraftTest.php
+++ b/tests/Entity/PageDraftTest.php
@@ -2,7 +2,6 @@
 
 namespace Tests\Entity;
 
-use BookStack\Entities\Models\Book;
 use BookStack\Entities\Models\Page;
 use BookStack\Entities\Models\PageRevision;
 use BookStack\Entities\Repos\PageRepo;
@@ -10,20 +9,13 @@ use Tests\TestCase;
 
 class PageDraftTest extends TestCase
 {
-    /**
-     * @var Page
-     */
-    protected $page;
-
-    /**
-     * @var PageRepo
-     */
-    protected $pageRepo;
+    protected Page $page;
+    protected PageRepo $pageRepo;
 
     protected function setUp(): void
     {
         parent::setUp();
-        $this->page = Page::query()->first();
+        $this->page = $this->entities->page();
         $this->pageRepo = app()->make(PageRepo::class);
     }
 
diff --git a/tests/Entity/PageEditorTest.php b/tests/Entity/PageEditorTest.php
index 6ce649a54..b2fb85955 100644
--- a/tests/Entity/PageEditorTest.php
+++ b/tests/Entity/PageEditorTest.php
@@ -2,20 +2,18 @@
 
 namespace Tests\Entity;
 
-use BookStack\Entities\Models\Book;
 use BookStack\Entities\Models\Chapter;
 use BookStack\Entities\Models\Page;
 use Tests\TestCase;
 
 class PageEditorTest extends TestCase
 {
-    /** @var Page */
-    protected $page;
+    protected Page $page;
 
     protected function setUp(): void
     {
         parent::setUp();
-        $this->page = Page::query()->first();
+        $this->page = $this->entities->page();
     }
 
     public function test_default_editor_is_wysiwyg_for_new_pages()
@@ -80,8 +78,7 @@ class PageEditorTest extends TestCase
 
     public function test_back_link_in_editor_has_correct_url()
     {
-        /** @var Book $book */
-        $book = Book::query()->whereHas('pages')->whereHas('chapters')->firstOrFail();
+        $book = $this->entities->bookHasChaptersAndPages();
         $this->asEditor()->get($book->getUrl('/create-page'));
         /** @var Chapter $chapter */
         $chapter = $book->chapters()->firstOrFail();
diff --git a/tests/Entity/PageRevisionTest.php b/tests/Entity/PageRevisionTest.php
index eabece4c6..d00ec5ce5 100644
--- a/tests/Entity/PageRevisionTest.php
+++ b/tests/Entity/PageRevisionTest.php
@@ -21,7 +21,7 @@ class PageRevisionTest extends TestCase
     public function test_page_revision_views_viewable()
     {
         $this->asEditor();
-        $page = Page::first();
+        $page = $this->entities->page();
         $this->createRevisions($page, 1, ['name' => 'updated page', 'html' => '<p>new content</p>']);
         $pageRevision = $page->revisions->last();
 
@@ -37,7 +37,7 @@ class PageRevisionTest extends TestCase
     public function test_page_revision_preview_shows_content_of_revision()
     {
         $this->asEditor();
-        $page = Page::first();
+        $page = $this->entities->page();
         $this->createRevisions($page, 1, ['name' => 'updated page', 'html' => '<p>new revision content</p>']);
         $pageRevision = $page->revisions->last();
         $this->createRevisions($page, 1, ['name' => 'updated page', 'html' => '<p>Updated content</p>']);
@@ -50,7 +50,7 @@ class PageRevisionTest extends TestCase
     public function test_page_revision_restore_updates_content()
     {
         $this->asEditor();
-        $page = Page::first();
+        $page = $this->entities->page();
         $this->createRevisions($page, 1, ['name' => 'updated page abc123', 'html' => '<p>new contente def456</p>']);
         $this->createRevisions($page, 1, ['name' => 'updated page again', 'html' => '<p>new content</p>']);
         $page = Page::find($page->id);
@@ -74,7 +74,7 @@ class PageRevisionTest extends TestCase
     public function test_page_revision_restore_with_markdown_retains_markdown_content()
     {
         $this->asEditor();
-        $page = Page::first();
+        $page = $this->entities->page();
         $this->createRevisions($page, 1, ['name' => 'updated page abc123', 'markdown' => '## New Content def456']);
         $this->createRevisions($page, 1, ['name' => 'updated page again', 'markdown' => '## New Content Updated']);
         $page = Page::find($page->id);
@@ -102,7 +102,7 @@ class PageRevisionTest extends TestCase
     public function test_page_revision_restore_sets_new_revision_with_summary()
     {
         $this->asEditor();
-        $page = Page::first();
+        $page = $this->entities->page();
         $this->createRevisions($page, 1, ['name' => 'updated page abc123', 'html' => '<p>new contente def456</p>', 'summary' => 'My first update']);
         $this->createRevisions($page, 1, ['html' => '<p>new content</p>']);
         $page->refresh();
@@ -124,7 +124,7 @@ class PageRevisionTest extends TestCase
 
     public function test_page_revision_count_increments_on_update()
     {
-        $page = Page::first();
+        $page = $this->entities->page();
         $startCount = $page->revision_count;
         $this->createRevisions($page, 1);
 
@@ -133,7 +133,7 @@ class PageRevisionTest extends TestCase
 
     public function test_revision_count_shown_in_page_meta()
     {
-        $page = Page::first();
+        $page = $this->entities->page();
         $this->createRevisions($page, 2);
 
         $pageView = $this->get($page->getUrl());
@@ -172,7 +172,7 @@ class PageRevisionTest extends TestCase
     public function test_revision_limit_enforced()
     {
         config()->set('app.revision_limit', 2);
-        $page = Page::first();
+        $page = $this->entities->page();
         $this->createRevisions($page, 12);
 
         $revisionCount = $page->revisions()->count();
@@ -182,7 +182,7 @@ class PageRevisionTest extends TestCase
     public function test_false_revision_limit_allows_many_revisions()
     {
         config()->set('app.revision_limit', false);
-        $page = Page::first();
+        $page = $this->entities->page();
         $this->createRevisions($page, 12);
 
         $revisionCount = $page->revisions()->count();
@@ -191,8 +191,7 @@ class PageRevisionTest extends TestCase
 
     public function test_revision_list_shows_editor_type()
     {
-        /** @var Page $page */
-        $page = Page::first();
+        $page = $this->entities->page();
         $this->createRevisions($page, 1, ['html' => 'new page html']);
 
         $resp = $this->asAdmin()->get($page->refresh()->getUrl('/revisions'));
diff --git a/tests/Entity/PageTemplateTest.php b/tests/Entity/PageTemplateTest.php
index 3d1689510..dc45fcfb8 100644
--- a/tests/Entity/PageTemplateTest.php
+++ b/tests/Entity/PageTemplateTest.php
@@ -9,7 +9,7 @@ class PageTemplateTest extends TestCase
 {
     public function test_active_templates_visible_on_page_view()
     {
-        $page = Page::first();
+        $page = $this->entities->page();
 
         $this->asEditor();
         $templateView = $this->get($page->getUrl());
@@ -24,7 +24,7 @@ class PageTemplateTest extends TestCase
 
     public function test_manage_templates_permission_required_to_change_page_template_status()
     {
-        $page = Page::first();
+        $page = $this->entities->page();
         $editor = $this->getEditor();
         $this->actingAs($editor);
 
@@ -52,7 +52,7 @@ class PageTemplateTest extends TestCase
     public function test_templates_content_should_be_fetchable_only_if_page_marked_as_template()
     {
         $content = '<div>my_custom_template_content</div>';
-        $page = Page::first();
+        $page = $this->entities->page();
         $editor = $this->getEditor();
         $this->actingAs($editor);
 
diff --git a/tests/Entity/PageTest.php b/tests/Entity/PageTest.php
index 067fceeb4..f481ffb61 100644
--- a/tests/Entity/PageTest.php
+++ b/tests/Entity/PageTest.php
@@ -3,7 +3,6 @@
 namespace Tests\Entity;
 
 use BookStack\Entities\Models\Book;
-use BookStack\Entities\Models\Chapter;
 use BookStack\Entities\Models\Page;
 use Carbon\Carbon;
 use Tests\TestCase;
@@ -128,7 +127,7 @@ class PageTest extends TestCase
 
     public function test_page_copy()
     {
-        $page = Page::first();
+        $page = $this->entities->page();
         $page->html = '<p>This is some test content</p>';
         $page->save();
 
@@ -151,7 +150,7 @@ class PageTest extends TestCase
 
     public function test_page_copy_with_markdown_has_both_html_and_markdown()
     {
-        $page = Page::first();
+        $page = $this->entities->page();
         $page->html = '<h1>This is some test content</h1>';
         $page->markdown = '# This is some test content';
         $page->save();
@@ -169,7 +168,7 @@ class PageTest extends TestCase
 
     public function test_page_copy_with_no_destination()
     {
-        $page = Page::first();
+        $page = $this->entities->page();
         $currentBook = $page->book;
 
         $resp = $this->asEditor()->get($page->getUrl('/copy'));
@@ -188,7 +187,7 @@ class PageTest extends TestCase
 
     public function test_page_can_be_copied_without_edit_permission()
     {
-        $page = Page::first();
+        $page = $this->entities->page();
         $currentBook = $page->book;
         $newBook = Book::where('id', '!=', $currentBook->id)->first();
         $viewer = $this->getViewer();
@@ -274,8 +273,7 @@ class PageTest extends TestCase
     public function test_recently_updated_pages_view_shows_parent_chain()
     {
         $user = $this->getEditor();
-        /** @var Page $page */
-        $page = Page::query()->whereNotNull('chapter_id')->first();
+        $page = $this->entities->pageWithinChapter();
 
         $this->actingAs($user)->put($page->getUrl(), [
             'name' => 'Updated title',
@@ -290,8 +288,7 @@ class PageTest extends TestCase
     public function test_recently_updated_pages_view_does_not_show_parent_if_not_visible()
     {
         $user = $this->getEditor();
-        /** @var Page $page */
-        $page = Page::query()->whereNotNull('chapter_id')->first();
+        $page = $this->entities->pageWithinChapter();
 
         $this->actingAs($user)->put($page->getUrl(), [
             'name' => 'Updated title',
diff --git a/tests/Entity/SortTest.php b/tests/Entity/SortTest.php
index 83a8f7005..f02e15d21 100644
--- a/tests/Entity/SortTest.php
+++ b/tests/Entity/SortTest.php
@@ -10,24 +10,17 @@ use Tests\TestCase;
 
 class SortTest extends TestCase
 {
-    protected $book;
-
-    protected function setUp(): void
-    {
-        parent::setUp();
-        $this->book = Book::first();
-    }
-
     public function test_drafts_do_not_show_up()
     {
         $this->asAdmin();
         $pageRepo = app(PageRepo::class);
-        $draft = $pageRepo->getNewDraftPage($this->book);
+        $book = $this->entities->book();
+        $draft = $pageRepo->getNewDraftPage($book);
 
-        $resp = $this->get($this->book->getUrl());
+        $resp = $this->get($book->getUrl());
         $resp->assertSee($draft->name);
 
-        $resp = $this->get($this->book->getUrl() . '/sort');
+        $resp = $this->get($book->getUrl() . '/sort');
         $resp->assertDontSee($draft->name);
     }
 
@@ -43,7 +36,7 @@ class SortTest extends TestCase
         $movePageResp = $this->put($page->getUrl('/move'), [
             'entity_selection' => 'book:' . $newBook->id,
         ]);
-        $page = Page::query()->find($page->id);
+        $page->refresh();
 
         $movePageResp->assertRedirect($page->getUrl());
         $this->assertTrue($page->book->id == $newBook->id, 'Page book is now the new book');
@@ -63,7 +56,7 @@ class SortTest extends TestCase
         $movePageResp = $this->actingAs($this->getEditor())->put($page->getUrl('/move'), [
             'entity_selection' => 'chapter:' . $newChapter->id,
         ]);
-        $page = Page::query()->find($page->id);
+        $page->refresh();
 
         $movePageResp->assertRedirect($page->getUrl());
         $this->assertTrue($page->book->id == $newBook->id, 'Page parent is now the new chapter');
@@ -110,7 +103,7 @@ class SortTest extends TestCase
             'entity_selection' => 'book:' . $newBook->id,
         ]);
 
-        $page = Page::query()->find($page->id);
+        $page->refresh();
         $movePageResp->assertRedirect($page->getUrl());
 
         $this->assertTrue($page->book->id == $newBook->id, 'Page book is now the new book');
@@ -138,7 +131,7 @@ class SortTest extends TestCase
             'entity_selection' => 'book:' . $newBook->id,
         ]);
 
-        $page = Page::query()->find($page->id);
+        $page->refresh();
         $movePageResp->assertRedirect($page->getUrl());
         $this->assertTrue($page->book->id == $newBook->id, 'Page book is now the new book');
     }
@@ -243,8 +236,7 @@ class SortTest extends TestCase
 
     public function test_book_sort_page_shows()
     {
-        /** @var Book $bookToSort */
-        $bookToSort = Book::query()->first();
+        $bookToSort = $this->entities->book();
 
         $resp = $this->asAdmin()->get($bookToSort->getUrl());
         $this->withHtml($resp)->assertElementExists('a[href="' . $bookToSort->getUrl('/sort') . '"]');
@@ -256,7 +248,7 @@ class SortTest extends TestCase
 
     public function test_book_sort()
     {
-        $oldBook = Book::query()->first();
+        $oldBook = $this->entities->book();
         $chapterToMove = $this->entities->newChapter(['name' => 'chapter to move'], $oldBook);
         $newBook = $this->entities->newBook(['name' => 'New sort book']);
         $pagesToMove = Page::query()->take(5)->get();
@@ -299,8 +291,7 @@ class SortTest extends TestCase
 
     public function test_book_sort_makes_no_changes_if_new_chapter_does_not_align_with_new_book()
     {
-        /** @var Page $page */
-        $page = Page::query()->where('chapter_id', '!=', 0)->first();
+        $page = $this->entities->pageWithinChapter();
         $otherChapter = Chapter::query()->where('book_id', '!=', $page->book_id)->first();
 
         $sortData = [
@@ -319,8 +310,7 @@ class SortTest extends TestCase
 
     public function test_book_sort_makes_no_changes_if_no_view_permissions_on_new_chapter()
     {
-        /** @var Page $page */
-        $page = Page::query()->where('chapter_id', '!=', 0)->first();
+        $page = $this->entities->pageWithinChapter();
         /** @var Chapter $otherChapter */
         $otherChapter = Chapter::query()->where('book_id', '!=', $page->book_id)->first();
         $this->entities->setPermissions($otherChapter);
@@ -341,8 +331,7 @@ class SortTest extends TestCase
 
     public function test_book_sort_makes_no_changes_if_no_view_permissions_on_new_book()
     {
-        /** @var Page $page */
-        $page = Page::query()->where('chapter_id', '!=', 0)->first();
+        $page = $this->entities->pageWithinChapter();
         /** @var Chapter $otherChapter */
         $otherChapter = Chapter::query()->where('book_id', '!=', $page->book_id)->first();
         $editor = $this->getEditor();
@@ -364,8 +353,7 @@ class SortTest extends TestCase
 
     public function test_book_sort_makes_no_changes_if_no_update_or_create_permissions_on_new_chapter()
     {
-        /** @var Page $page */
-        $page = Page::query()->where('chapter_id', '!=', 0)->first();
+        $page = $this->entities->pageWithinChapter();
         /** @var Chapter $otherChapter */
         $otherChapter = Chapter::query()->where('book_id', '!=', $page->book_id)->first();
         $editor = $this->getEditor();
@@ -387,8 +375,7 @@ class SortTest extends TestCase
 
     public function test_book_sort_makes_no_changes_if_no_update_permissions_on_moved_item()
     {
-        /** @var Page $page */
-        $page = Page::query()->where('chapter_id', '!=', 0)->first();
+        $page = $this->entities->pageWithinChapter();
         /** @var Chapter $otherChapter */
         $otherChapter = Chapter::query()->where('book_id', '!=', $page->book_id)->first();
         $editor = $this->getEditor();
@@ -410,8 +397,7 @@ class SortTest extends TestCase
 
     public function test_book_sort_makes_no_changes_if_no_delete_permissions_on_moved_item()
     {
-        /** @var Page $page */
-        $page = Page::query()->where('chapter_id', '!=', 0)->first();
+        $page = $this->entities->pageWithinChapter();
         /** @var Chapter $otherChapter */
         $otherChapter = Chapter::query()->where('book_id', '!=', $page->book_id)->first();
         $editor = $this->getEditor();
@@ -433,8 +419,7 @@ class SortTest extends TestCase
 
     public function test_book_sort_item_returns_book_content()
     {
-        $books = Book::all();
-        $bookToSort = $books[0];
+        $bookToSort = $this->entities->book();
         $firstPage = $bookToSort->pages[0];
         $firstChapter = $bookToSort->chapters[0];
 
@@ -448,8 +433,7 @@ class SortTest extends TestCase
 
     public function test_pages_in_book_show_sorted_by_priority()
     {
-        /** @var Book $book */
-        $book = Book::query()->whereHas('pages')->first();
+        $book = $this->entities->bookHasChaptersAndPages();
         $book->chapters()->forceDelete();
         /** @var Page[] $pages */
         $pages = $book->pages()->where('chapter_id', '=', 0)->take(2)->get();
diff --git a/tests/Entity/TagTest.php b/tests/Entity/TagTest.php
index 18ee31826..ab0627601 100644
--- a/tests/Entity/TagTest.php
+++ b/tests/Entity/TagTest.php
@@ -3,7 +3,6 @@
 namespace Tests\Entity;
 
 use BookStack\Actions\Tag;
-use BookStack\Entities\Models\Book;
 use BookStack\Entities\Models\Entity;
 use BookStack\Entities\Models\Page;
 use Tests\TestCase;
diff --git a/tests/ErrorTest.php b/tests/ErrorTest.php
index c46d65bde..ebd9874d3 100644
--- a/tests/ErrorTest.php
+++ b/tests/ErrorTest.php
@@ -2,7 +2,6 @@
 
 namespace Tests;
 
-use BookStack\Entities\Models\Book;
 use Illuminate\Support\Facades\Log;
 
 class ErrorTest extends TestCase
diff --git a/tests/FavouriteTest.php b/tests/FavouriteTest.php
index 03a712316..456f2213c 100644
--- a/tests/FavouriteTest.php
+++ b/tests/FavouriteTest.php
@@ -4,10 +4,6 @@ namespace Tests;
 
 use BookStack\Actions\Favourite;
 use BookStack\Auth\User;
-use BookStack\Entities\Models\Book;
-use BookStack\Entities\Models\Bookshelf;
-use BookStack\Entities\Models\Chapter;
-use BookStack\Entities\Models\Page;
 
 class FavouriteTest extends TestCase
 {
@@ -83,16 +79,11 @@ class FavouriteTest extends TestCase
         ]);
     }
 
-    public function test_book_chapter_shelf_pages_contain_favourite_button()
+    public function test_each_entity_type_shows_favourite_button()
     {
-        $entities = [
-            Bookshelf::query()->first(),
-            Book::query()->first(),
-            Chapter::query()->first(),
-        ];
         $this->actingAs($this->getEditor());
 
-        foreach ($entities as $entity) {
+        foreach ($this->entities->all() as $entity) {
             $resp = $this->get($entity->getUrl());
             $this->withHtml($resp)->assertElementExists('form[method="POST"][action$="/favourites/add"]');
         }
diff --git a/tests/Helpers/EntityProvider.php b/tests/Helpers/EntityProvider.php
index 152f7a3ac..05925909e 100644
--- a/tests/Helpers/EntityProvider.php
+++ b/tests/Helpers/EntityProvider.php
@@ -13,7 +13,13 @@ use BookStack\Entities\Repos\BookRepo;
 use BookStack\Entities\Repos\BookshelfRepo;
 use BookStack\Entities\Repos\ChapterRepo;
 use BookStack\Entities\Repos\PageRepo;
+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 +35,68 @@ 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));
+    }
+
     /**
      * 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 +115,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}
diff --git a/tests/TestServiceProvider.php b/tests/Helpers/TestServiceProvider.php
similarity index 96%
rename from tests/TestServiceProvider.php
rename to tests/Helpers/TestServiceProvider.php
index 9ad48c442..8b0e2ce16 100644
--- a/tests/TestServiceProvider.php
+++ b/tests/Helpers/TestServiceProvider.php
@@ -1,6 +1,6 @@
 <?php
 
-namespace Tests;
+namespace Tests\Helpers;
 
 use Illuminate\Support\Facades\Artisan;
 use Illuminate\Support\Facades\ParallelTesting;
diff --git a/tests/HomepageTest.php b/tests/HomepageTest.php
index 60e10a087..cf69425fb 100644
--- a/tests/HomepageTest.php
+++ b/tests/HomepageTest.php
@@ -4,8 +4,6 @@ namespace Tests;
 
 use BookStack\Auth\Role;
 use BookStack\Auth\User;
-use BookStack\Entities\Models\Bookshelf;
-use BookStack\Entities\Models\Page;
 
 class HomepageTest extends TestCase
 {
@@ -99,8 +97,7 @@ class HomepageTest extends TestCase
     public function test_custom_homepage_renders_includes()
     {
         $this->asEditor();
-        /** @var Page $included */
-        $included = Page::query()->first();
+        $included = $this->entities->page();
         $content = str_repeat('This is the body content of my custom homepage.', 20);
         $included->html = $content;
         $included->save();
@@ -138,7 +135,7 @@ class HomepageTest extends TestCase
     {
         $editor = $this->getEditor();
         setting()->putUser($editor, 'bookshelves_view_type', 'grid');
-        $shelf = Bookshelf::query()->firstOrFail();
+        $shelf = $this->entities->shelf();
 
         $this->setSettings(['app-homepage-type' => 'bookshelves']);
 
diff --git a/tests/OpenGraphTest.php b/tests/OpenGraphTest.php
index f3c439767..d6f535718 100644
--- a/tests/OpenGraphTest.php
+++ b/tests/OpenGraphTest.php
@@ -2,10 +2,6 @@
 
 namespace Tests;
 
-use BookStack\Entities\Models\Book;
-use BookStack\Entities\Models\Bookshelf;
-use BookStack\Entities\Models\Chapter;
-use BookStack\Entities\Models\Page;
 use BookStack\Entities\Repos\BaseRepo;
 use BookStack\Entities\Repos\BookRepo;
 use Illuminate\Support\Str;
diff --git a/tests/Permissions/EntityOwnerChangeTest.php b/tests/Permissions/EntityOwnerChangeTest.php
index 65a67dc0f..e94759760 100644
--- a/tests/Permissions/EntityOwnerChangeTest.php
+++ b/tests/Permissions/EntityOwnerChangeTest.php
@@ -3,10 +3,6 @@
 namespace Tests\Permissions;
 
 use BookStack\Auth\User;
-use BookStack\Entities\Models\Book;
-use BookStack\Entities\Models\Bookshelf;
-use BookStack\Entities\Models\Chapter;
-use BookStack\Entities\Models\Page;
 use Tests\TestCase;
 
 class EntityOwnerChangeTest extends TestCase
diff --git a/tests/Permissions/EntityPermissionsTest.php b/tests/Permissions/EntityPermissionsTest.php
index 9312b88cf..7f91e7887 100644
--- a/tests/Permissions/EntityPermissionsTest.php
+++ b/tests/Permissions/EntityPermissionsTest.php
@@ -13,15 +13,8 @@ use Tests\TestCase;
 
 class EntityPermissionsTest extends TestCase
 {
-    /**
-     * @var User
-     */
-    protected $user;
-
-    /**
-     * @var User
-     */
-    protected $viewer;
+    protected User $user;
+    protected User $viewer;
 
     protected function setUp(): void
     {
diff --git a/tests/Permissions/ExportPermissionsTest.php b/tests/Permissions/ExportPermissionsTest.php
index 44f1a35cc..642cf1beb 100644
--- a/tests/Permissions/ExportPermissionsTest.php
+++ b/tests/Permissions/ExportPermissionsTest.php
@@ -2,8 +2,6 @@
 
 namespace Tests\Permissions;
 
-use BookStack\Entities\Models\Book;
-use BookStack\Entities\Models\Chapter;
 use Illuminate\Support\Str;
 use Tests\TestCase;
 
diff --git a/tests/Permissions/RolesTest.php b/tests/Permissions/RolesTest.php
index 23bfde74c..7512c6d2f 100644
--- a/tests/Permissions/RolesTest.php
+++ b/tests/Permissions/RolesTest.php
@@ -17,7 +17,7 @@ use Tests\TestCase;
 
 class RolesTest extends TestCase
 {
-    protected $user;
+    protected User $user;
 
     protected function setUp(): void
     {
diff --git a/tests/PublicActionTest.php b/tests/PublicActionTest.php
index 14759c578..7e3f7be00 100644
--- a/tests/PublicActionTest.php
+++ b/tests/PublicActionTest.php
@@ -8,7 +8,6 @@ use BookStack\Auth\Role;
 use BookStack\Auth\User;
 use BookStack\Entities\Models\Book;
 use BookStack\Entities\Models\Chapter;
-use BookStack\Entities\Models\Page;
 use Illuminate\Support\Facades\Auth;
 use Illuminate\Support\Facades\View;
 
diff --git a/tests/References/CrossLinkParserTest.php b/tests/References/CrossLinkParserTest.php
index eb862a9fd..65eed9e70 100644
--- a/tests/References/CrossLinkParserTest.php
+++ b/tests/References/CrossLinkParserTest.php
@@ -2,7 +2,6 @@
 
 namespace Tests\References;
 
-use BookStack\Entities\Models\Page;
 use BookStack\References\CrossLinkParser;
 use Tests\TestCase;
 
@@ -11,7 +10,7 @@ class CrossLinkParserTest extends TestCase
     public function test_instance_with_entity_resolvers_matches_entity_links()
     {
         $entities = $this->entities->all();
-        $otherPage = Page::query()->where('id', '!=', $entities['page']->id)->first();
+        $otherPage = $this->entities->page();
 
         $html = '
 <a href="' . url('/link/' . $otherPage->id) . '#cat">Page Permalink</a>
diff --git a/tests/References/ReferencesTest.php b/tests/References/ReferencesTest.php
index 16ea19ac5..148b2197c 100644
--- a/tests/References/ReferencesTest.php
+++ b/tests/References/ReferencesTest.php
@@ -2,9 +2,6 @@
 
 namespace Tests\References;
 
-use BookStack\Entities\Models\Book;
-use BookStack\Entities\Models\Chapter;
-use BookStack\Entities\Models\Page;
 use BookStack\Entities\Repos\PageRepo;
 use BookStack\Entities\Tools\TrashCan;
 use BookStack\Model;
@@ -15,10 +12,8 @@ class ReferencesTest extends TestCase
 {
     public function test_references_created_on_page_update()
     {
-        /** @var Page $pageA */
-        /** @var Page $pageB */
-        $pageA = Page::query()->first();
-        $pageB = Page::query()->where('id', '!=', $pageA->id)->first();
+        $pageA = $this->entities->page();
+        $pageB = $this->entities->page();
 
         $this->assertDatabaseMissing('references', ['from_id' => $pageA->id, 'from_type' => $pageA->getMorphClass()]);
 
@@ -37,10 +32,8 @@ class ReferencesTest extends TestCase
 
     public function test_references_deleted_on_entity_delete()
     {
-        /** @var Page $pageA */
-        /** @var Page $pageB */
-        $pageA = Page::query()->first();
-        $pageB = Page::query()->where('id', '!=', $pageA->id)->first();
+        $pageA = $this->entities->page();
+        $pageB = $this->entities->page();
 
         $this->createReference($pageA, $pageB);
         $this->createReference($pageB, $pageA);
@@ -58,8 +51,7 @@ class ReferencesTest extends TestCase
     public function test_references_to_count_visible_on_entity_show_view()
     {
         $entities = $this->entities->all();
-        /** @var Page $otherPage */
-        $otherPage = Page::query()->where('id', '!=', $entities['page']->id)->first();
+        $otherPage = $this->entities->page();
 
         $this->asEditor();
         foreach ($entities as $entity) {
@@ -95,10 +87,8 @@ class ReferencesTest extends TestCase
 
     public function test_reference_not_visible_if_view_permission_does_not_permit()
     {
-        /** @var Page $page */
-        /** @var Page $pageB */
         $page = $this->entities->page();
-        $pageB = Page::query()->where('id', '!=', $page->id)->first();
+        $pageB = $this->entities->page();
         $this->createReference($pageB, $page);
 
         $this->entities->setPermissions($pageB);
@@ -118,11 +108,8 @@ class ReferencesTest extends TestCase
 
     public function test_pages_leading_to_entity_updated_on_url_change()
     {
-        /** @var Page $pageA */
-        /** @var Page $pageB */
-        /** @var Book $book */
-        $pageA = Page::query()->first();
-        $pageB = Page::query()->where('id', '!=', $pageA->id)->first();
+        $pageA = $this->entities->page();
+        $pageB = $this->entities->page();
         $book = $this->entities->book();
 
         foreach ([$pageA, $pageB] as $page) {
@@ -147,11 +134,8 @@ class ReferencesTest extends TestCase
 
     public function test_pages_linking_to_other_page_updated_on_parent_book_url_change()
     {
-        /** @var Page $bookPage */
-        /** @var Page $otherPage */
-        /** @var Book $book */
-        $bookPage = Page::query()->first();
-        $otherPage = Page::query()->where('id', '!=', $bookPage->id)->first();
+        $bookPage = $this->entities->page();
+        $otherPage = $this->entities->page();
         $book = $bookPage->book;
 
         $otherPage->html = '<a href="' . $bookPage->getUrl() . '">Link</a>';
@@ -172,11 +156,8 @@ class ReferencesTest extends TestCase
 
     public function test_pages_linking_to_chapter_updated_on_parent_book_url_change()
     {
-        /** @var Chapter $bookChapter */
-        /** @var Page $otherPage */
-        /** @var Book $book */
-        $bookChapter = Chapter::query()->first();
-        $otherPage = Page::query()->first();
+        $bookChapter = $this->entities->chapter();
+        $otherPage = $this->entities->page();
         $book = $bookChapter->book;
 
         $otherPage->html = '<a href="' . $bookChapter->getUrl() . '">Link</a>';
@@ -197,8 +178,6 @@ class ReferencesTest extends TestCase
 
     public function test_markdown_links_leading_to_entity_updated_on_url_change()
     {
-        /** @var Page $page */
-        /** @var Book $book */
         $page = $this->entities->page();
         $book = $this->entities->book();
 
diff --git a/tests/Settings/RecycleBinTest.php b/tests/Settings/RecycleBinTest.php
index 8b5705afd..3d27e9c8d 100644
--- a/tests/Settings/RecycleBinTest.php
+++ b/tests/Settings/RecycleBinTest.php
@@ -3,10 +3,7 @@
 namespace Tests\Settings;
 
 use BookStack\Entities\Models\Book;
-use BookStack\Entities\Models\Bookshelf;
-use BookStack\Entities\Models\Chapter;
 use BookStack\Entities\Models\Deletion;
-use BookStack\Entities\Models\Entity;
 use BookStack\Entities\Models\Page;
 use Illuminate\Support\Carbon;
 use Illuminate\Support\Facades\DB;
@@ -97,7 +94,7 @@ class RecycleBinTest extends TestCase
 
     public function test_entity_restore()
     {
-        $book = Book::query()->whereHas('pages')->whereHas('chapters')->with(['pages', 'chapters'])->firstOrFail();
+        $book = $this->entities->bookHasChaptersAndPages();
         $this->asEditor()->delete($book->getUrl());
         $deletion = Deletion::query()->firstOrFail();
 
@@ -118,7 +115,7 @@ class RecycleBinTest extends TestCase
 
     public function test_permanent_delete()
     {
-        $book = Book::query()->whereHas('pages')->whereHas('chapters')->with(['pages', 'chapters'])->firstOrFail();
+        $book = $this->entities->bookHasChaptersAndPages();
         $this->asEditor()->delete($book->getUrl());
         $deletion = Deletion::query()->firstOrFail();
 
@@ -137,9 +134,7 @@ class RecycleBinTest extends TestCase
 
     public function test_permanent_delete_for_each_type()
     {
-        /** @var Entity $entity */
-        foreach ([new Bookshelf(), new Book(), new Chapter(), new Page()] as $entity) {
-            $entity = $entity->newQuery()->first();
+        foreach ($this->entities->all() as $type => $entity) {
             $this->asEditor()->delete($entity->getUrl());
             $deletion = Deletion::query()->orderBy('id', 'desc')->firstOrFail();
 
@@ -152,7 +147,7 @@ class RecycleBinTest extends TestCase
 
     public function test_permanent_entity_delete_updates_existing_activity_with_entity_name()
     {
-        $page = Page::query()->firstOrFail();
+        $page = $this->entities->page();
         $this->asEditor()->delete($page->getUrl());
         $deletion = $page->deletions()->firstOrFail();
 
@@ -181,8 +176,8 @@ class RecycleBinTest extends TestCase
     public function test_auto_clear_functionality_works()
     {
         config()->set('app.recycle_bin_lifetime', 5);
-        $page = Page::query()->firstOrFail();
-        $otherPage = Page::query()->where('id', '!=', $page->id)->firstOrFail();
+        $page = $this->entities->page();
+        $otherPage = $this->entities->page();
 
         $this->asEditor()->delete($page->getUrl());
         $this->assertDatabaseHas('pages', ['id' => $page->id]);
@@ -198,8 +193,8 @@ class RecycleBinTest extends TestCase
     public function test_auto_clear_functionality_with_negative_time_keeps_forever()
     {
         config()->set('app.recycle_bin_lifetime', -1);
-        $page = Page::query()->firstOrFail();
-        $otherPage = Page::query()->where('id', '!=', $page->id)->firstOrFail();
+        $page = $this->entities->page();
+        $otherPage = $this->entities->page();
 
         $this->asEditor()->delete($page->getUrl());
         $this->assertEquals(1, Deletion::query()->count());
@@ -214,7 +209,7 @@ class RecycleBinTest extends TestCase
     public function test_auto_clear_functionality_with_zero_time_deletes_instantly()
     {
         config()->set('app.recycle_bin_lifetime', 0);
-        $page = Page::query()->firstOrFail();
+        $page = $this->entities->page();
 
         $this->asEditor()->delete($page->getUrl());
         $this->assertDatabaseMissing('pages', ['id' => $page->id]);
@@ -253,8 +248,7 @@ class RecycleBinTest extends TestCase
 
     public function test_restore_page_shows_link_to_parent_restore_if_parent_also_deleted()
     {
-        /** @var Book $book */
-        $book = Book::query()->whereHas('pages')->whereHas('chapters')->with(['pages', 'chapters'])->firstOrFail();
+        $book = $this->entities->bookHasChaptersAndPages();
         $chapter = $book->chapters->first();
         /** @var Page $page */
         $page = $chapter->pages->first();
diff --git a/tests/TestCase.php b/tests/TestCase.php
index cc8e57453..356fdaa37 100644
--- a/tests/TestCase.php
+++ b/tests/TestCase.php
@@ -27,6 +27,7 @@ use Monolog\Logger;
 use Psr\Http\Client\ClientInterface;
 use Ssddanbrown\AssertHtml\TestsHtml;
 use Tests\Helpers\EntityProvider;
+use Tests\Helpers\TestServiceProvider;
 
 abstract class TestCase extends BaseTestCase
 {
diff --git a/tests/UrlTest.php b/tests/UrlTest.php
index dd278c240..c1e133804 100644
--- a/tests/UrlTest.php
+++ b/tests/UrlTest.php
@@ -4,9 +4,6 @@ namespace Tests;
 
 use BookStack\Http\Request;
 
-use function request;
-use function url;
-
 class UrlTest extends TestCase
 {
     public function test_url_helper_takes_custom_url_into_account()
diff --git a/tests/User/UserManagementTest.php b/tests/User/UserManagementTest.php
index 114088338..e295034ce 100644
--- a/tests/User/UserManagementTest.php
+++ b/tests/User/UserManagementTest.php
@@ -6,7 +6,6 @@ use BookStack\Actions\ActivityType;
 use BookStack\Auth\Access\UserInviteService;
 use BookStack\Auth\Role;
 use BookStack\Auth\User;
-use BookStack\Entities\Models\Page;
 use Illuminate\Support\Facades\Hash;
 use Illuminate\Support\Str;
 use Mockery\MockInterface;
diff --git a/tests/User/UserPreferencesTest.php b/tests/User/UserPreferencesTest.php
index 2273be2b4..c65b11d7d 100644
--- a/tests/User/UserPreferencesTest.php
+++ b/tests/User/UserPreferencesTest.php
@@ -2,8 +2,6 @@
 
 namespace Tests\User;
 
-use BookStack\Entities\Models\Bookshelf;
-use BookStack\Entities\Models\Page;
 use Tests\TestCase;
 
 class UserPreferencesTest extends TestCase