Quick run through of applying new test entity helper class
This commit is contained in:
		
							parent
							
								
									b56f7355aa
								
							
						
					
					
						commit
						900e853b15
					
				| 
						 | 
					@ -2,7 +2,6 @@
 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace BookStack\Api;
 | 
					namespace BookStack\Api;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
use BookStack\Model;
 | 
					 | 
				
			||||||
use Illuminate\Database\Eloquent\Builder;
 | 
					use Illuminate\Database\Eloquent\Builder;
 | 
				
			||||||
use Illuminate\Database\Eloquent\Collection;
 | 
					use Illuminate\Database\Eloquent\Collection;
 | 
				
			||||||
use Illuminate\Http\JsonResponse;
 | 
					use Illuminate\Http\JsonResponse;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -6,8 +6,6 @@ use BookStack\Actions\Activity;
 | 
				
			||||||
use BookStack\Actions\ActivityLogger;
 | 
					use BookStack\Actions\ActivityLogger;
 | 
				
			||||||
use BookStack\Actions\ActivityType;
 | 
					use BookStack\Actions\ActivityType;
 | 
				
			||||||
use BookStack\Auth\UserRepo;
 | 
					use BookStack\Auth\UserRepo;
 | 
				
			||||||
use BookStack\Entities\Models\Chapter;
 | 
					 | 
				
			||||||
use BookStack\Entities\Models\Page;
 | 
					 | 
				
			||||||
use BookStack\Entities\Repos\PageRepo;
 | 
					use BookStack\Entities\Repos\PageRepo;
 | 
				
			||||||
use BookStack\Entities\Tools\TrashCan;
 | 
					use BookStack\Entities\Tools\TrashCan;
 | 
				
			||||||
use Carbon\Carbon;
 | 
					use Carbon\Carbon;
 | 
				
			||||||
| 
						 | 
					@ -15,8 +13,7 @@ use Tests\TestCase;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class AuditLogTest extends TestCase
 | 
					class AuditLogTest extends TestCase
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    /** @var ActivityLogger */
 | 
					    protected ActivityLogger $activityService;
 | 
				
			||||||
    protected $activityService;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    protected function setUp(): void
 | 
					    protected function setUp(): void
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -7,7 +7,6 @@ use BookStack\Actions\ActivityType;
 | 
				
			||||||
use BookStack\Actions\DispatchWebhookJob;
 | 
					use BookStack\Actions\DispatchWebhookJob;
 | 
				
			||||||
use BookStack\Actions\Webhook;
 | 
					use BookStack\Actions\Webhook;
 | 
				
			||||||
use BookStack\Auth\User;
 | 
					use BookStack\Auth\User;
 | 
				
			||||||
use BookStack\Entities\Models\Page;
 | 
					 | 
				
			||||||
use Illuminate\Http\Client\Request;
 | 
					use Illuminate\Http\Client\Request;
 | 
				
			||||||
use Illuminate\Support\Facades\Bus;
 | 
					use Illuminate\Support\Facades\Bus;
 | 
				
			||||||
use Illuminate\Support\Facades\Http;
 | 
					use Illuminate\Support\Facades\Http;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -5,9 +5,6 @@ namespace Tests\Actions;
 | 
				
			||||||
use BookStack\Actions\ActivityType;
 | 
					use BookStack\Actions\ActivityType;
 | 
				
			||||||
use BookStack\Actions\Webhook;
 | 
					use BookStack\Actions\Webhook;
 | 
				
			||||||
use BookStack\Actions\WebhookFormatter;
 | 
					use BookStack\Actions\WebhookFormatter;
 | 
				
			||||||
use BookStack\Entities\Models\Book;
 | 
					 | 
				
			||||||
use BookStack\Entities\Models\Chapter;
 | 
					 | 
				
			||||||
use BookStack\Entities\Models\Page;
 | 
					 | 
				
			||||||
use Illuminate\Support\Arr;
 | 
					use Illuminate\Support\Arr;
 | 
				
			||||||
use Tests\TestCase;
 | 
					use Tests\TestCase;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -16,9 +13,9 @@ class WebhookFormatTesting extends TestCase
 | 
				
			||||||
    public function test_entity_events_show_related_user_info()
 | 
					    public function test_entity_events_show_related_user_info()
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        $events = [
 | 
					        $events = [
 | 
				
			||||||
            ActivityType::BOOK_UPDATE    => Book::query()->first(),
 | 
					            ActivityType::BOOK_UPDATE    => $this->entities->book(),
 | 
				
			||||||
            ActivityType::CHAPTER_CREATE => Chapter::query()->first(),
 | 
					            ActivityType::CHAPTER_CREATE => $this->entities->chapter(),
 | 
				
			||||||
            ActivityType::PAGE_MOVE      => Page::query()->first(),
 | 
					            ActivityType::PAGE_MOVE      => $this->entities->page(),
 | 
				
			||||||
        ];
 | 
					        ];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        foreach ($events as $event => $entity) {
 | 
					        foreach ($events as $event => $entity) {
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -68,7 +68,7 @@ class BooksApiTest extends TestCase
 | 
				
			||||||
    public function test_read_endpoint()
 | 
					    public function test_read_endpoint()
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        $this->actingAsApiEditor();
 | 
					        $this->actingAsApiEditor();
 | 
				
			||||||
        $book = Book::visible()->first();
 | 
					        $book = $this->entities->book();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        $resp = $this->getJson($this->baseEndpoint . "/{$book->id}");
 | 
					        $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()
 | 
					    public function test_read_endpoint_includes_chapter_and_page_contents()
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        $this->actingAsApiEditor();
 | 
					        $this->actingAsApiEditor();
 | 
				
			||||||
        /** @var Book $book */
 | 
					        $book = $this->entities->bookHasChaptersAndPages();
 | 
				
			||||||
        $book = Book::visible()->has('chapters')->has('pages')->first();
 | 
					 | 
				
			||||||
        $chapter = $book->chapters()->first();
 | 
					        $chapter = $book->chapters()->first();
 | 
				
			||||||
        $chapterPage = $chapter->pages()->first();
 | 
					        $chapterPage = $chapter->pages()->first();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -123,7 +122,7 @@ class BooksApiTest extends TestCase
 | 
				
			||||||
    public function test_update_endpoint()
 | 
					    public function test_update_endpoint()
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        $this->actingAsApiEditor();
 | 
					        $this->actingAsApiEditor();
 | 
				
			||||||
        $book = Book::visible()->first();
 | 
					        $book = $this->entities->book();
 | 
				
			||||||
        $details = [
 | 
					        $details = [
 | 
				
			||||||
            'name'        => 'My updated API book',
 | 
					            'name'        => 'My updated API book',
 | 
				
			||||||
            'description' => 'A book created via the API',
 | 
					            '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()
 | 
					    public function test_update_increments_updated_date_if_only_tags_are_sent()
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        $this->actingAsApiEditor();
 | 
					        $this->actingAsApiEditor();
 | 
				
			||||||
        $book = Book::visible()->first();
 | 
					        $book = $this->entities->book();
 | 
				
			||||||
        DB::table('books')->where('id', '=', $book->id)->update(['updated_at' => Carbon::now()->subWeek()]);
 | 
					        DB::table('books')->where('id', '=', $book->id)->update(['updated_at' => Carbon::now()->subWeek()]);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        $details = [
 | 
					        $details = [
 | 
				
			||||||
| 
						 | 
					@ -156,7 +155,7 @@ class BooksApiTest extends TestCase
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        $this->actingAsApiEditor();
 | 
					        $this->actingAsApiEditor();
 | 
				
			||||||
        /** @var Book $book */
 | 
					        /** @var Book $book */
 | 
				
			||||||
        $book = Book::visible()->first();
 | 
					        $book = $this->entities->book();
 | 
				
			||||||
        $this->assertNull($book->cover);
 | 
					        $this->assertNull($book->cover);
 | 
				
			||||||
        $file = $this->getTestImage('image.png');
 | 
					        $file = $this->getTestImage('image.png');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -191,7 +190,7 @@ class BooksApiTest extends TestCase
 | 
				
			||||||
    public function test_delete_endpoint()
 | 
					    public function test_delete_endpoint()
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        $this->actingAsApiEditor();
 | 
					        $this->actingAsApiEditor();
 | 
				
			||||||
        $book = Book::visible()->first();
 | 
					        $book = $this->entities->book();
 | 
				
			||||||
        $resp = $this->deleteJson($this->baseEndpoint . "/{$book->id}");
 | 
					        $resp = $this->deleteJson($this->baseEndpoint . "/{$book->id}");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        $resp->assertStatus(204);
 | 
					        $resp->assertStatus(204);
 | 
				
			||||||
| 
						 | 
					@ -201,7 +200,7 @@ class BooksApiTest extends TestCase
 | 
				
			||||||
    public function test_export_html_endpoint()
 | 
					    public function test_export_html_endpoint()
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        $this->actingAsApiEditor();
 | 
					        $this->actingAsApiEditor();
 | 
				
			||||||
        $book = Book::visible()->first();
 | 
					        $book = $this->entities->book();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        $resp = $this->get($this->baseEndpoint . "/{$book->id}/export/html");
 | 
					        $resp = $this->get($this->baseEndpoint . "/{$book->id}/export/html");
 | 
				
			||||||
        $resp->assertStatus(200);
 | 
					        $resp->assertStatus(200);
 | 
				
			||||||
| 
						 | 
					@ -212,7 +211,7 @@ class BooksApiTest extends TestCase
 | 
				
			||||||
    public function test_export_plain_text_endpoint()
 | 
					    public function test_export_plain_text_endpoint()
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        $this->actingAsApiEditor();
 | 
					        $this->actingAsApiEditor();
 | 
				
			||||||
        $book = Book::visible()->first();
 | 
					        $book = $this->entities->book();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        $resp = $this->get($this->baseEndpoint . "/{$book->id}/export/plaintext");
 | 
					        $resp = $this->get($this->baseEndpoint . "/{$book->id}/export/plaintext");
 | 
				
			||||||
        $resp->assertStatus(200);
 | 
					        $resp->assertStatus(200);
 | 
				
			||||||
| 
						 | 
					@ -223,7 +222,7 @@ class BooksApiTest extends TestCase
 | 
				
			||||||
    public function test_export_pdf_endpoint()
 | 
					    public function test_export_pdf_endpoint()
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        $this->actingAsApiEditor();
 | 
					        $this->actingAsApiEditor();
 | 
				
			||||||
        $book = Book::visible()->first();
 | 
					        $book = $this->entities->book();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        $resp = $this->get($this->baseEndpoint . "/{$book->id}/export/pdf");
 | 
					        $resp = $this->get($this->baseEndpoint . "/{$book->id}/export/pdf");
 | 
				
			||||||
        $resp->assertStatus(200);
 | 
					        $resp->assertStatus(200);
 | 
				
			||||||
| 
						 | 
					@ -249,7 +248,7 @@ class BooksApiTest extends TestCase
 | 
				
			||||||
        $this->actingAsApiEditor();
 | 
					        $this->actingAsApiEditor();
 | 
				
			||||||
        $this->removePermissionFromUser($this->getEditor(), 'content-export');
 | 
					        $this->removePermissionFromUser($this->getEditor(), 'content-export');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        $book = Book::visible()->first();
 | 
					        $book = $this->entities->book();
 | 
				
			||||||
        foreach ($types as $type) {
 | 
					        foreach ($types as $type) {
 | 
				
			||||||
            $resp = $this->get($this->baseEndpoint . "/{$book->id}/export/{$type}");
 | 
					            $resp = $this->get($this->baseEndpoint . "/{$book->id}/export/{$type}");
 | 
				
			||||||
            $this->assertPermissionError($resp);
 | 
					            $this->assertPermissionError($resp);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -2,7 +2,6 @@
 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace Tests\Api;
 | 
					namespace Tests\Api;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
use BookStack\Entities\Models\Book;
 | 
					 | 
				
			||||||
use BookStack\Entities\Models\Chapter;
 | 
					use BookStack\Entities\Models\Chapter;
 | 
				
			||||||
use Carbon\Carbon;
 | 
					use Carbon\Carbon;
 | 
				
			||||||
use Illuminate\Support\Facades\DB;
 | 
					use Illuminate\Support\Facades\DB;
 | 
				
			||||||
| 
						 | 
					@ -95,7 +94,7 @@ class ChaptersApiTest extends TestCase
 | 
				
			||||||
    public function test_read_endpoint()
 | 
					    public function test_read_endpoint()
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        $this->actingAsApiEditor();
 | 
					        $this->actingAsApiEditor();
 | 
				
			||||||
        $chapter = Chapter::visible()->first();
 | 
					        $chapter = $this->entities->chapter();
 | 
				
			||||||
        $page = $chapter->pages()->first();
 | 
					        $page = $chapter->pages()->first();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        $resp = $this->getJson($this->baseEndpoint . "/{$chapter->id}");
 | 
					        $resp = $this->getJson($this->baseEndpoint . "/{$chapter->id}");
 | 
				
			||||||
| 
						 | 
					@ -127,7 +126,7 @@ class ChaptersApiTest extends TestCase
 | 
				
			||||||
    public function test_update_endpoint()
 | 
					    public function test_update_endpoint()
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        $this->actingAsApiEditor();
 | 
					        $this->actingAsApiEditor();
 | 
				
			||||||
        $chapter = Chapter::visible()->first();
 | 
					        $chapter = $this->entities->chapter();
 | 
				
			||||||
        $details = [
 | 
					        $details = [
 | 
				
			||||||
            'name'        => 'My updated API chapter',
 | 
					            'name'        => 'My updated API chapter',
 | 
				
			||||||
            'description' => 'A chapter created via the API',
 | 
					            '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()
 | 
					    public function test_update_increments_updated_date_if_only_tags_are_sent()
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        $this->actingAsApiEditor();
 | 
					        $this->actingAsApiEditor();
 | 
				
			||||||
        $chapter = Chapter::visible()->first();
 | 
					        $chapter = $this->entities->chapter();
 | 
				
			||||||
        DB::table('chapters')->where('id', '=', $chapter->id)->update(['updated_at' => Carbon::now()->subWeek()]);
 | 
					        DB::table('chapters')->where('id', '=', $chapter->id)->update(['updated_at' => Carbon::now()->subWeek()]);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        $details = [
 | 
					        $details = [
 | 
				
			||||||
| 
						 | 
					@ -167,7 +166,7 @@ class ChaptersApiTest extends TestCase
 | 
				
			||||||
    public function test_delete_endpoint()
 | 
					    public function test_delete_endpoint()
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        $this->actingAsApiEditor();
 | 
					        $this->actingAsApiEditor();
 | 
				
			||||||
        $chapter = Chapter::visible()->first();
 | 
					        $chapter = $this->entities->chapter();
 | 
				
			||||||
        $resp = $this->deleteJson($this->baseEndpoint . "/{$chapter->id}");
 | 
					        $resp = $this->deleteJson($this->baseEndpoint . "/{$chapter->id}");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        $resp->assertStatus(204);
 | 
					        $resp->assertStatus(204);
 | 
				
			||||||
| 
						 | 
					@ -177,7 +176,7 @@ class ChaptersApiTest extends TestCase
 | 
				
			||||||
    public function test_export_html_endpoint()
 | 
					    public function test_export_html_endpoint()
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        $this->actingAsApiEditor();
 | 
					        $this->actingAsApiEditor();
 | 
				
			||||||
        $chapter = Chapter::visible()->first();
 | 
					        $chapter = $this->entities->chapter();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        $resp = $this->get($this->baseEndpoint . "/{$chapter->id}/export/html");
 | 
					        $resp = $this->get($this->baseEndpoint . "/{$chapter->id}/export/html");
 | 
				
			||||||
        $resp->assertStatus(200);
 | 
					        $resp->assertStatus(200);
 | 
				
			||||||
| 
						 | 
					@ -188,7 +187,7 @@ class ChaptersApiTest extends TestCase
 | 
				
			||||||
    public function test_export_plain_text_endpoint()
 | 
					    public function test_export_plain_text_endpoint()
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        $this->actingAsApiEditor();
 | 
					        $this->actingAsApiEditor();
 | 
				
			||||||
        $chapter = Chapter::visible()->first();
 | 
					        $chapter = $this->entities->chapter();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        $resp = $this->get($this->baseEndpoint . "/{$chapter->id}/export/plaintext");
 | 
					        $resp = $this->get($this->baseEndpoint . "/{$chapter->id}/export/plaintext");
 | 
				
			||||||
        $resp->assertStatus(200);
 | 
					        $resp->assertStatus(200);
 | 
				
			||||||
| 
						 | 
					@ -199,7 +198,7 @@ class ChaptersApiTest extends TestCase
 | 
				
			||||||
    public function test_export_pdf_endpoint()
 | 
					    public function test_export_pdf_endpoint()
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        $this->actingAsApiEditor();
 | 
					        $this->actingAsApiEditor();
 | 
				
			||||||
        $chapter = Chapter::visible()->first();
 | 
					        $chapter = $this->entities->chapter();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        $resp = $this->get($this->baseEndpoint . "/{$chapter->id}/export/pdf");
 | 
					        $resp = $this->get($this->baseEndpoint . "/{$chapter->id}/export/pdf");
 | 
				
			||||||
        $resp->assertStatus(200);
 | 
					        $resp->assertStatus(200);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -2,7 +2,6 @@
 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace Tests\Api;
 | 
					namespace Tests\Api;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
use BookStack\Entities\Models\Book;
 | 
					 | 
				
			||||||
use BookStack\Entities\Models\Chapter;
 | 
					use BookStack\Entities\Models\Chapter;
 | 
				
			||||||
use BookStack\Entities\Models\Page;
 | 
					use BookStack\Entities\Models\Page;
 | 
				
			||||||
use Carbon\Carbon;
 | 
					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_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 = $this->postJson($this->baseEndpoint, array_merge($details, ['chapter_id' => $chapter->id]));
 | 
				
			||||||
        $resp->assertStatus(200);
 | 
					        $resp->assertStatus(200);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        $book = Book::visible()->first();
 | 
					        $book = $this->entities->book();
 | 
				
			||||||
        $resp = $this->postJson($this->baseEndpoint, array_merge($details, ['book_id' => $book->id]));
 | 
					        $resp = $this->postJson($this->baseEndpoint, array_merge($details, ['book_id' => $book->id]));
 | 
				
			||||||
        $resp->assertStatus(200);
 | 
					        $resp->assertStatus(200);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
| 
						 | 
					@ -107,7 +106,7 @@ class PagesApiTest extends TestCase
 | 
				
			||||||
    public function test_markdown_can_be_provided_for_create()
 | 
					    public function test_markdown_can_be_provided_for_create()
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        $this->actingAsApiEditor();
 | 
					        $this->actingAsApiEditor();
 | 
				
			||||||
        $book = Book::visible()->first();
 | 
					        $book = $this->entities->book();
 | 
				
			||||||
        $details = [
 | 
					        $details = [
 | 
				
			||||||
            'book_id'  => $book->id,
 | 
					            'book_id'  => $book->id,
 | 
				
			||||||
            'name'     => 'My api page',
 | 
					            'name'     => 'My api page',
 | 
				
			||||||
| 
						 | 
					@ -126,7 +125,7 @@ class PagesApiTest extends TestCase
 | 
				
			||||||
    public function test_read_endpoint()
 | 
					    public function test_read_endpoint()
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        $this->actingAsApiEditor();
 | 
					        $this->actingAsApiEditor();
 | 
				
			||||||
        $page = Page::visible()->first();
 | 
					        $page = $this->entities->page();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        $resp = $this->getJson($this->baseEndpoint . "/{$page->id}");
 | 
					        $resp = $this->getJson($this->baseEndpoint . "/{$page->id}");
 | 
				
			||||||
        $resp->assertStatus(200);
 | 
					        $resp->assertStatus(200);
 | 
				
			||||||
| 
						 | 
					@ -149,7 +148,7 @@ class PagesApiTest extends TestCase
 | 
				
			||||||
    public function test_read_endpoint_provides_rendered_html()
 | 
					    public function test_read_endpoint_provides_rendered_html()
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        $this->actingAsApiEditor();
 | 
					        $this->actingAsApiEditor();
 | 
				
			||||||
        $page = Page::visible()->first();
 | 
					        $page = $this->entities->page();
 | 
				
			||||||
        $page->html = "<p>testing</p><script>alert('danger')</script><h1>Hello</h1>";
 | 
					        $page->html = "<p>testing</p><script>alert('danger')</script><h1>Hello</h1>";
 | 
				
			||||||
        $page->save();
 | 
					        $page->save();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -163,7 +162,7 @@ class PagesApiTest extends TestCase
 | 
				
			||||||
    public function test_update_endpoint()
 | 
					    public function test_update_endpoint()
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        $this->actingAsApiEditor();
 | 
					        $this->actingAsApiEditor();
 | 
				
			||||||
        $page = Page::visible()->first();
 | 
					        $page = $this->entities->page();
 | 
				
			||||||
        $details = [
 | 
					        $details = [
 | 
				
			||||||
            'name' => 'My updated API page',
 | 
					            'name' => 'My updated API page',
 | 
				
			||||||
            'html' => '<p>A page created via the API</p>',
 | 
					            '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()
 | 
					    public function test_providing_new_chapter_id_on_update_will_move_page()
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        $this->actingAsApiEditor();
 | 
					        $this->actingAsApiEditor();
 | 
				
			||||||
        $page = Page::visible()->first();
 | 
					        $page = $this->entities->page();
 | 
				
			||||||
        $chapter = Chapter::visible()->where('book_id', '!=', $page->book_id)->first();
 | 
					        $chapter = Chapter::visible()->where('book_id', '!=', $page->book_id)->first();
 | 
				
			||||||
        $details = [
 | 
					        $details = [
 | 
				
			||||||
            'name'       => 'My updated API page',
 | 
					            '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()
 | 
					    public function test_providing_move_via_update_requires_page_create_permission_on_new_parent()
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        $this->actingAsApiEditor();
 | 
					        $this->actingAsApiEditor();
 | 
				
			||||||
        $page = Page::visible()->first();
 | 
					        $page = $this->entities->page();
 | 
				
			||||||
        $chapter = Chapter::visible()->where('book_id', '!=', $page->book_id)->first();
 | 
					        $chapter = Chapter::visible()->where('book_id', '!=', $page->book_id)->first();
 | 
				
			||||||
        $this->entities->setPermissions($chapter, ['view'], [$this->getEditor()->roles()->first()]);
 | 
					        $this->entities->setPermissions($chapter, ['view'], [$this->getEditor()->roles()->first()]);
 | 
				
			||||||
        $details = [
 | 
					        $details = [
 | 
				
			||||||
| 
						 | 
					@ -224,7 +223,7 @@ class PagesApiTest extends TestCase
 | 
				
			||||||
    public function test_update_endpoint_does_not_wipe_content_if_no_html_or_md_provided()
 | 
					    public function test_update_endpoint_does_not_wipe_content_if_no_html_or_md_provided()
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        $this->actingAsApiEditor();
 | 
					        $this->actingAsApiEditor();
 | 
				
			||||||
        $page = Page::visible()->first();
 | 
					        $page = $this->entities->page();
 | 
				
			||||||
        $originalContent = $page->html;
 | 
					        $originalContent = $page->html;
 | 
				
			||||||
        $details = [
 | 
					        $details = [
 | 
				
			||||||
            'name' => 'My updated API page',
 | 
					            '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()
 | 
					    public function test_update_increments_updated_date_if_only_tags_are_sent()
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        $this->actingAsApiEditor();
 | 
					        $this->actingAsApiEditor();
 | 
				
			||||||
        $page = Page::visible()->first();
 | 
					        $page = $this->entities->page();
 | 
				
			||||||
        DB::table('pages')->where('id', '=', $page->id)->update(['updated_at' => Carbon::now()->subWeek()]);
 | 
					        DB::table('pages')->where('id', '=', $page->id)->update(['updated_at' => Carbon::now()->subWeek()]);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        $details = [
 | 
					        $details = [
 | 
				
			||||||
| 
						 | 
					@ -262,7 +261,7 @@ class PagesApiTest extends TestCase
 | 
				
			||||||
    public function test_delete_endpoint()
 | 
					    public function test_delete_endpoint()
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        $this->actingAsApiEditor();
 | 
					        $this->actingAsApiEditor();
 | 
				
			||||||
        $page = Page::visible()->first();
 | 
					        $page = $this->entities->page();
 | 
				
			||||||
        $resp = $this->deleteJson($this->baseEndpoint . "/{$page->id}");
 | 
					        $resp = $this->deleteJson($this->baseEndpoint . "/{$page->id}");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        $resp->assertStatus(204);
 | 
					        $resp->assertStatus(204);
 | 
				
			||||||
| 
						 | 
					@ -272,7 +271,7 @@ class PagesApiTest extends TestCase
 | 
				
			||||||
    public function test_export_html_endpoint()
 | 
					    public function test_export_html_endpoint()
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        $this->actingAsApiEditor();
 | 
					        $this->actingAsApiEditor();
 | 
				
			||||||
        $page = Page::visible()->first();
 | 
					        $page = $this->entities->page();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        $resp = $this->get($this->baseEndpoint . "/{$page->id}/export/html");
 | 
					        $resp = $this->get($this->baseEndpoint . "/{$page->id}/export/html");
 | 
				
			||||||
        $resp->assertStatus(200);
 | 
					        $resp->assertStatus(200);
 | 
				
			||||||
| 
						 | 
					@ -283,7 +282,7 @@ class PagesApiTest extends TestCase
 | 
				
			||||||
    public function test_export_plain_text_endpoint()
 | 
					    public function test_export_plain_text_endpoint()
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        $this->actingAsApiEditor();
 | 
					        $this->actingAsApiEditor();
 | 
				
			||||||
        $page = Page::visible()->first();
 | 
					        $page = $this->entities->page();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        $resp = $this->get($this->baseEndpoint . "/{$page->id}/export/plaintext");
 | 
					        $resp = $this->get($this->baseEndpoint . "/{$page->id}/export/plaintext");
 | 
				
			||||||
        $resp->assertStatus(200);
 | 
					        $resp->assertStatus(200);
 | 
				
			||||||
| 
						 | 
					@ -294,7 +293,7 @@ class PagesApiTest extends TestCase
 | 
				
			||||||
    public function test_export_pdf_endpoint()
 | 
					    public function test_export_pdf_endpoint()
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        $this->actingAsApiEditor();
 | 
					        $this->actingAsApiEditor();
 | 
				
			||||||
        $page = Page::visible()->first();
 | 
					        $page = $this->entities->page();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        $resp = $this->get($this->baseEndpoint . "/{$page->id}/export/pdf");
 | 
					        $resp = $this->get($this->baseEndpoint . "/{$page->id}/export/pdf");
 | 
				
			||||||
        $resp->assertStatus(200);
 | 
					        $resp->assertStatus(200);
 | 
				
			||||||
| 
						 | 
					@ -304,7 +303,7 @@ class PagesApiTest extends TestCase
 | 
				
			||||||
    public function test_export_markdown_endpoint()
 | 
					    public function test_export_markdown_endpoint()
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        $this->actingAsApiEditor();
 | 
					        $this->actingAsApiEditor();
 | 
				
			||||||
        $page = Page::visible()->first();
 | 
					        $page = $this->entities->page();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        $resp = $this->get($this->baseEndpoint . "/{$page->id}/export/markdown");
 | 
					        $resp = $this->get($this->baseEndpoint . "/{$page->id}/export/markdown");
 | 
				
			||||||
        $resp->assertStatus(200);
 | 
					        $resp->assertStatus(200);
 | 
				
			||||||
| 
						 | 
					@ -318,7 +317,7 @@ class PagesApiTest extends TestCase
 | 
				
			||||||
        $this->actingAsApiEditor();
 | 
					        $this->actingAsApiEditor();
 | 
				
			||||||
        $this->removePermissionFromUser($this->getEditor(), 'content-export');
 | 
					        $this->removePermissionFromUser($this->getEditor(), 'content-export');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        $page = Page::visible()->first();
 | 
					        $page = $this->entities->page();
 | 
				
			||||||
        foreach ($types as $type) {
 | 
					        foreach ($types as $type) {
 | 
				
			||||||
            $resp = $this->get($this->baseEndpoint . "/{$page->id}/export/{$type}");
 | 
					            $resp = $this->get($this->baseEndpoint . "/{$page->id}/export/{$type}");
 | 
				
			||||||
            $this->assertPermissionError($resp);
 | 
					            $this->assertPermissionError($resp);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -4,7 +4,6 @@ namespace Tests\Api;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
use BookStack\Entities\Models\Book;
 | 
					use BookStack\Entities\Models\Book;
 | 
				
			||||||
use BookStack\Entities\Models\Deletion;
 | 
					use BookStack\Entities\Models\Deletion;
 | 
				
			||||||
use BookStack\Entities\Models\Page;
 | 
					 | 
				
			||||||
use Illuminate\Support\Collection;
 | 
					use Illuminate\Support\Collection;
 | 
				
			||||||
use Tests\TestCase;
 | 
					use Tests\TestCase;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -111,7 +110,7 @@ class RecycleBinApiTest extends TestCase
 | 
				
			||||||
    public function test_index_endpoint_returns_parent()
 | 
					    public function test_index_endpoint_returns_parent()
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        $admin = $this->getAdmin();
 | 
					        $admin = $this->getAdmin();
 | 
				
			||||||
        $page = Page::query()->whereHas('chapter')->with('chapter')->first();
 | 
					        $page = $this->entities->pageWithinChapter();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        $this->actingAs($admin)->delete($page->getUrl());
 | 
					        $this->actingAs($admin)->delete($page->getUrl());
 | 
				
			||||||
        $deletion = Deletion::query()->orderBy('id')->first();
 | 
					        $deletion = Deletion::query()->orderBy('id')->first();
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -3,7 +3,6 @@
 | 
				
			||||||
namespace Tests\Auth;
 | 
					namespace Tests\Auth;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
use BookStack\Auth\Access\Mfa\MfaSession;
 | 
					use BookStack\Auth\Access\Mfa\MfaSession;
 | 
				
			||||||
use BookStack\Entities\Models\Page;
 | 
					 | 
				
			||||||
use Illuminate\Testing\TestResponse;
 | 
					use Illuminate\Testing\TestResponse;
 | 
				
			||||||
use Tests\TestCase;
 | 
					use Tests\TestCase;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -3,7 +3,6 @@
 | 
				
			||||||
namespace Tests\Commands;
 | 
					namespace Tests\Commands;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
use BookStack\Actions\ActivityType;
 | 
					use BookStack\Actions\ActivityType;
 | 
				
			||||||
use BookStack\Entities\Models\Page;
 | 
					 | 
				
			||||||
use BookStack\Facades\Activity;
 | 
					use BookStack\Facades\Activity;
 | 
				
			||||||
use Illuminate\Support\Facades\Artisan;
 | 
					use Illuminate\Support\Facades\Artisan;
 | 
				
			||||||
use Illuminate\Support\Facades\DB;
 | 
					use Illuminate\Support\Facades\DB;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -16,7 +16,7 @@ class CopyShelfPermissionsCommandTest extends TestCase
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    public function test_copy_shelf_permissions_command_using_slug()
 | 
					    public function test_copy_shelf_permissions_command_using_slug()
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        $shelf = Bookshelf::first();
 | 
					        $shelf = $this->entities->shelf();
 | 
				
			||||||
        $child = $shelf->books()->first();
 | 
					        $child = $shelf->books()->first();
 | 
				
			||||||
        $editorRole = $this->getEditor()->roles()->first();
 | 
					        $editorRole = $this->getEditor()->roles()->first();
 | 
				
			||||||
        $this->assertFalse(boolval($child->restricted), 'Child book should not be restricted by default');
 | 
					        $this->assertFalse(boolval($child->restricted), 'Child book should not be restricted by default');
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -2,7 +2,6 @@
 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace Tests\Commands;
 | 
					namespace Tests\Commands;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
use BookStack\Entities\Models\Page;
 | 
					 | 
				
			||||||
use Illuminate\Support\Facades\DB;
 | 
					use Illuminate\Support\Facades\DB;
 | 
				
			||||||
use Tests\TestCase;
 | 
					use Tests\TestCase;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -2,7 +2,6 @@
 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace Tests\Commands;
 | 
					namespace Tests\Commands;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
use BookStack\Entities\Models\Page;
 | 
					 | 
				
			||||||
use Symfony\Component\Console\Exception\RuntimeException;
 | 
					use Symfony\Component\Console\Exception\RuntimeException;
 | 
				
			||||||
use Tests\TestCase;
 | 
					use Tests\TestCase;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -39,7 +39,7 @@ class BookShelfTest extends TestCase
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        $user = User::factory()->create();
 | 
					        $user = User::factory()->create();
 | 
				
			||||||
        $this->giveUserPermissions($user, ['image-create-all']);
 | 
					        $this->giveUserPermissions($user, ['image-create-all']);
 | 
				
			||||||
        $shelf = Bookshelf::first();
 | 
					        $shelf = $this->entities->shelf();
 | 
				
			||||||
        $userRole = $user->roles()->first();
 | 
					        $userRole = $user->roles()->first();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        $resp = $this->actingAs($user)->get('/');
 | 
					        $resp = $this->actingAs($user)->get('/');
 | 
				
			||||||
| 
						 | 
					@ -130,7 +130,7 @@ class BookShelfTest extends TestCase
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    public function test_shelf_view()
 | 
					    public function test_shelf_view()
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        $shelf = Bookshelf::first();
 | 
					        $shelf = $this->entities->shelf();
 | 
				
			||||||
        $resp = $this->asEditor()->get($shelf->getUrl());
 | 
					        $resp = $this->asEditor()->get($shelf->getUrl());
 | 
				
			||||||
        $resp->assertStatus(200);
 | 
					        $resp->assertStatus(200);
 | 
				
			||||||
        $resp->assertSeeText($shelf->name);
 | 
					        $resp->assertSeeText($shelf->name);
 | 
				
			||||||
| 
						 | 
					@ -143,7 +143,7 @@ class BookShelfTest extends TestCase
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    public function test_shelf_view_shows_action_buttons()
 | 
					    public function test_shelf_view_shows_action_buttons()
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        $shelf = Bookshelf::first();
 | 
					        $shelf = $this->entities->shelf();
 | 
				
			||||||
        $resp = $this->asAdmin()->get($shelf->getUrl());
 | 
					        $resp = $this->asAdmin()->get($shelf->getUrl());
 | 
				
			||||||
        $resp->assertSee($shelf->getUrl('/create-book'));
 | 
					        $resp->assertSee($shelf->getUrl('/create-book'));
 | 
				
			||||||
        $resp->assertSee($shelf->getUrl('/edit'));
 | 
					        $resp->assertSee($shelf->getUrl('/edit'));
 | 
				
			||||||
| 
						 | 
					@ -201,7 +201,7 @@ class BookShelfTest extends TestCase
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    public function test_shelf_edit()
 | 
					    public function test_shelf_edit()
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        $shelf = Bookshelf::first();
 | 
					        $shelf = $this->entities->shelf();
 | 
				
			||||||
        $resp = $this->asEditor()->get($shelf->getUrl('/edit'));
 | 
					        $resp = $this->asEditor()->get($shelf->getUrl('/edit'));
 | 
				
			||||||
        $resp->assertSeeText('Edit Shelf');
 | 
					        $resp->assertSeeText('Edit Shelf');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -239,7 +239,7 @@ class BookShelfTest extends TestCase
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    public function test_shelf_create_new_book()
 | 
					    public function test_shelf_create_new_book()
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        $shelf = Bookshelf::first();
 | 
					        $shelf = $this->entities->shelf();
 | 
				
			||||||
        $resp = $this->asEditor()->get($shelf->getUrl('/create-book'));
 | 
					        $resp = $this->asEditor()->get($shelf->getUrl('/create-book'));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        $resp->assertSee('Create New Book');
 | 
					        $resp->assertSee('Create New Book');
 | 
				
			||||||
| 
						 | 
					@ -288,7 +288,7 @@ class BookShelfTest extends TestCase
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    public function test_shelf_copy_permissions()
 | 
					    public function test_shelf_copy_permissions()
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        $shelf = Bookshelf::first();
 | 
					        $shelf = $this->entities->shelf();
 | 
				
			||||||
        $resp = $this->asAdmin()->get($shelf->getUrl('/permissions'));
 | 
					        $resp = $this->asAdmin()->get($shelf->getUrl('/permissions'));
 | 
				
			||||||
        $resp->assertSeeText('Copy Permissions');
 | 
					        $resp->assertSeeText('Copy Permissions');
 | 
				
			||||||
        $resp->assertSee("action=\"{$shelf->getUrl('/copy-permissions')}\"", false);
 | 
					        $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()
 | 
					    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 = $this->asAdmin()->get($shelf->getUrl('/permissions'));
 | 
				
			||||||
        $resp->assertSeeText('Permissions on shelves do not automatically cascade to contained books.');
 | 
					        $resp->assertSeeText('Permissions on shelves do not automatically cascade to contained books.');
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    public function test_bookshelves_show_in_breadcrumbs_if_in_context()
 | 
					    public function test_bookshelves_show_in_breadcrumbs_if_in_context()
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        $shelf = Bookshelf::first();
 | 
					        $shelf = $this->entities->shelf();
 | 
				
			||||||
        $shelfBook = $shelf->books()->first();
 | 
					        $shelfBook = $shelf->books()->first();
 | 
				
			||||||
        $shelfPage = $shelfBook->pages()->first();
 | 
					        $shelfPage = $shelfBook->pages()->first();
 | 
				
			||||||
        $this->asAdmin();
 | 
					        $this->asAdmin();
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -96,8 +96,7 @@ class ChapterTest extends TestCase
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    public function test_copy_does_not_copy_non_visible_pages()
 | 
					    public function test_copy_does_not_copy_non_visible_pages()
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        /** @var Chapter $chapter */
 | 
					        $chapter = $this->entities->chapterHasPages();
 | 
				
			||||||
        $chapter = Chapter::query()->whereHas('pages')->first();
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
        // Hide pages to all non-admin roles
 | 
					        // Hide pages to all non-admin roles
 | 
				
			||||||
        /** @var Page $page */
 | 
					        /** @var Page $page */
 | 
				
			||||||
| 
						 | 
					@ -118,8 +117,7 @@ class ChapterTest extends TestCase
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    public function test_copy_does_not_copy_pages_if_user_cant_page_create()
 | 
					    public function test_copy_does_not_copy_pages_if_user_cant_page_create()
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        /** @var Chapter $chapter */
 | 
					        $chapter = $this->entities->chapterHasPages();
 | 
				
			||||||
        $chapter = Chapter::query()->whereHas('pages')->first();
 | 
					 | 
				
			||||||
        $viewer = $this->getViewer();
 | 
					        $viewer = $this->getViewer();
 | 
				
			||||||
        $this->giveUserPermissions($viewer, ['chapter-create-all']);
 | 
					        $this->giveUserPermissions($viewer, ['chapter-create-all']);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -2,34 +2,27 @@
 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace Tests\Entity;
 | 
					namespace Tests\Entity;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
use BookStack\Entities\Models\Page;
 | 
					 | 
				
			||||||
use Tests\TestCase;
 | 
					use Tests\TestCase;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class CommentSettingTest extends TestCase
 | 
					class CommentSettingTest extends TestCase
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    protected $page;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    protected function setUp(): void
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        parent::setUp();
 | 
					 | 
				
			||||||
        $this->page = Page::query()->first();
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    public function test_comment_disable()
 | 
					    public function test_comment_disable()
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
 | 
					        $page = $this->entities->page();
 | 
				
			||||||
        $this->setSettings(['app-disable-comments' => 'true']);
 | 
					        $this->setSettings(['app-disable-comments' => 'true']);
 | 
				
			||||||
        $this->asAdmin();
 | 
					        $this->asAdmin();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        $resp = $this->asAdmin()->get($this->page->getUrl());
 | 
					        $resp = $this->asAdmin()->get($page->getUrl());
 | 
				
			||||||
        $this->withHtml($resp)->assertElementNotExists('.comments-list');
 | 
					        $this->withHtml($resp)->assertElementNotExists('.comments-list');
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    public function test_comment_enable()
 | 
					    public function test_comment_enable()
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
 | 
					        $page = $this->entities->page();
 | 
				
			||||||
        $this->setSettings(['app-disable-comments' => 'false']);
 | 
					        $this->setSettings(['app-disable-comments' => 'false']);
 | 
				
			||||||
        $this->asAdmin();
 | 
					        $this->asAdmin();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        $resp = $this->asAdmin()->get($this->page->getUrl());
 | 
					        $resp = $this->asAdmin()->get($page->getUrl());
 | 
				
			||||||
        $this->withHtml($resp)->assertElementExists('.comments-list');
 | 
					        $this->withHtml($resp)->assertElementExists('.comments-list');
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -11,7 +11,7 @@ class CommentTest extends TestCase
 | 
				
			||||||
    public function test_add_comment()
 | 
					    public function test_add_comment()
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        $this->asAdmin();
 | 
					        $this->asAdmin();
 | 
				
			||||||
        $page = Page::first();
 | 
					        $page = $this->entities->page();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        $comment = Comment::factory()->make(['parent_id' => 2]);
 | 
					        $comment = Comment::factory()->make(['parent_id' => 2]);
 | 
				
			||||||
        $resp = $this->postJson("/comment/$page->id", $comment->getAttributes());
 | 
					        $resp = $this->postJson("/comment/$page->id", $comment->getAttributes());
 | 
				
			||||||
| 
						 | 
					@ -34,7 +34,7 @@ class CommentTest extends TestCase
 | 
				
			||||||
    public function test_comment_edit()
 | 
					    public function test_comment_edit()
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        $this->asAdmin();
 | 
					        $this->asAdmin();
 | 
				
			||||||
        $page = Page::first();
 | 
					        $page = $this->entities->page();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        $comment = Comment::factory()->make();
 | 
					        $comment = Comment::factory()->make();
 | 
				
			||||||
        $this->postJson("/comment/$page->id", $comment->getAttributes());
 | 
					        $this->postJson("/comment/$page->id", $comment->getAttributes());
 | 
				
			||||||
| 
						 | 
					@ -58,7 +58,7 @@ class CommentTest extends TestCase
 | 
				
			||||||
    public function test_comment_delete()
 | 
					    public function test_comment_delete()
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        $this->asAdmin();
 | 
					        $this->asAdmin();
 | 
				
			||||||
        $page = Page::first();
 | 
					        $page = $this->entities->page();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        $comment = Comment::factory()->make();
 | 
					        $comment = Comment::factory()->make();
 | 
				
			||||||
        $this->postJson("/comment/$page->id", $comment->getAttributes());
 | 
					        $this->postJson("/comment/$page->id", $comment->getAttributes());
 | 
				
			||||||
| 
						 | 
					@ -75,7 +75,7 @@ class CommentTest extends TestCase
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    public function test_comments_converts_markdown_input_to_html()
 | 
					    public function test_comments_converts_markdown_input_to_html()
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        $page = Page::first();
 | 
					        $page = $this->entities->page();
 | 
				
			||||||
        $this->asAdmin()->postJson("/comment/$page->id", [
 | 
					        $this->asAdmin()->postJson("/comment/$page->id", [
 | 
				
			||||||
            'text' => '# My Title',
 | 
					            'text' => '# My Title',
 | 
				
			||||||
        ]);
 | 
					        ]);
 | 
				
			||||||
| 
						 | 
					@ -94,7 +94,7 @@ class CommentTest extends TestCase
 | 
				
			||||||
    public function test_html_cannot_be_injected_via_comment_content()
 | 
					    public function test_html_cannot_be_injected_via_comment_content()
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        $this->asAdmin();
 | 
					        $this->asAdmin();
 | 
				
			||||||
        $page = Page::first();
 | 
					        $page = $this->entities->page();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        $script = '<script>const a = "script";</script>\n\n# sometextinthecomment';
 | 
					        $script = '<script>const a = "script";</script>\n\n# sometextinthecomment';
 | 
				
			||||||
        $this->postJson("/comment/$page->id", [
 | 
					        $this->postJson("/comment/$page->id", [
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -24,8 +24,7 @@ class ConvertTest extends TestCase
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    public function test_convert_chapter_to_book()
 | 
					    public function test_convert_chapter_to_book()
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        /** @var Chapter $chapter */
 | 
					        $chapter = $this->entities->chapterHasPages();
 | 
				
			||||||
        $chapter = Chapter::query()->whereHas('pages')->first();
 | 
					 | 
				
			||||||
        $chapter->tags()->save(new Tag(['name' => 'Category', 'value' => 'Penguins']));
 | 
					        $chapter->tags()->save(new Tag(['name' => 'Category', 'value' => 'Penguins']));
 | 
				
			||||||
        /** @var Page $childPage */
 | 
					        /** @var Page $childPage */
 | 
				
			||||||
        $childPage = $chapter->pages()->first();
 | 
					        $childPage = $chapter->pages()->first();
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -4,7 +4,6 @@ namespace Tests\Entity;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
use BookStack\Auth\UserRepo;
 | 
					use BookStack\Auth\UserRepo;
 | 
				
			||||||
use BookStack\Entities\Models\Entity;
 | 
					use BookStack\Entities\Models\Entity;
 | 
				
			||||||
use BookStack\Entities\Repos\PageRepo;
 | 
					 | 
				
			||||||
use Tests\TestCase;
 | 
					use Tests\TestCase;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class EntityAccessTest extends TestCase
 | 
					class EntityAccessTest extends TestCase
 | 
				
			||||||
| 
						 | 
					@ -16,7 +15,7 @@ class EntityAccessTest extends TestCase
 | 
				
			||||||
        $updater = $this->getViewer();
 | 
					        $updater = $this->getViewer();
 | 
				
			||||||
        $entities = $this->entities->createChainBelongingToUser($creator, $updater);
 | 
					        $entities = $this->entities->createChainBelongingToUser($creator, $updater);
 | 
				
			||||||
        app()->make(UserRepo::class)->destroy($creator);
 | 
					        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);
 | 
					        $this->checkEntitiesViewable($entities);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
| 
						 | 
					@ -28,7 +27,7 @@ class EntityAccessTest extends TestCase
 | 
				
			||||||
        $updater = $this->getEditor();
 | 
					        $updater = $this->getEditor();
 | 
				
			||||||
        $entities = $this->entities->createChainBelongingToUser($creator, $updater);
 | 
					        $entities = $this->entities->createChainBelongingToUser($creator, $updater);
 | 
				
			||||||
        app()->make(UserRepo::class)->destroy($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);
 | 
					        $this->checkEntitiesViewable($entities);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -5,15 +5,13 @@ namespace Tests\Entity;
 | 
				
			||||||
use BookStack\Actions\Tag;
 | 
					use BookStack\Actions\Tag;
 | 
				
			||||||
use BookStack\Entities\Models\Book;
 | 
					use BookStack\Entities\Models\Book;
 | 
				
			||||||
use BookStack\Entities\Models\Bookshelf;
 | 
					use BookStack\Entities\Models\Bookshelf;
 | 
				
			||||||
use BookStack\Entities\Models\Chapter;
 | 
					 | 
				
			||||||
use BookStack\Entities\Models\Page;
 | 
					 | 
				
			||||||
use Tests\TestCase;
 | 
					use Tests\TestCase;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class EntitySearchTest extends TestCase
 | 
					class EntitySearchTest extends TestCase
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    public function test_page_search()
 | 
					    public function test_page_search()
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        $book = Book::all()->first();
 | 
					        $book = $this->entities->book();
 | 
				
			||||||
        $page = $book->pages->first();
 | 
					        $page = $book->pages->first();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        $search = $this->asEditor()->get('/search?term=' . urlencode($page->name));
 | 
					        $search = $this->asEditor()->get('/search?term=' . urlencode($page->name));
 | 
				
			||||||
| 
						 | 
					@ -71,7 +69,7 @@ class EntitySearchTest extends TestCase
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    public function test_chapter_search()
 | 
					    public function test_chapter_search()
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        $chapter = Chapter::has('pages')->first();
 | 
					        $chapter = $this->entities->chapterHasPages();
 | 
				
			||||||
        $page = $chapter->pages[0];
 | 
					        $page = $chapter->pages[0];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        $pageTestResp = $this->asEditor()->get('/search/chapter/' . $chapter->id . '?term=' . urlencode($page->name));
 | 
					        $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);
 | 
					        $pageA->tags()->saveMany($newTags);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        $pageB = Page::all()->last();
 | 
					        $pageB = $this->entities->page();
 | 
				
			||||||
        $pageB->tags()->create(['name' => 'animal', 'value' => 'dog']);
 | 
					        $pageB->tags()->create(['name' => 'animal', 'value' => 'dog']);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        $this->asEditor();
 | 
					        $this->asEditor();
 | 
				
			||||||
| 
						 | 
					@ -197,7 +195,7 @@ class EntitySearchTest extends TestCase
 | 
				
			||||||
    public function test_ajax_entity_search()
 | 
					    public function test_ajax_entity_search()
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        $page = $this->entities->newPage(['name' => 'my ajax search test', 'html' => 'ajax test']);
 | 
					        $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
 | 
					        // Visit the page to make popular
 | 
				
			||||||
        $this->asEditor()->get($page->getUrl());
 | 
					        $this->asEditor()->get($page->getUrl());
 | 
				
			||||||
| 
						 | 
					@ -215,7 +213,7 @@ class EntitySearchTest extends TestCase
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    public function test_ajax_entity_search_shows_breadcrumbs()
 | 
					    public function test_ajax_entity_search_shows_breadcrumbs()
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        $chapter = Chapter::first();
 | 
					        $chapter = $this->entities->chapter();
 | 
				
			||||||
        $page = $chapter->pages->first();
 | 
					        $page = $chapter->pages->first();
 | 
				
			||||||
        $this->asEditor();
 | 
					        $this->asEditor();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -246,7 +244,7 @@ class EntitySearchTest extends TestCase
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    public function test_sibling_search_for_pages()
 | 
					    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');
 | 
					        $this->assertGreaterThan(2, count($chapter->pages), 'Ensure we\'re testing with at least 1 sibling');
 | 
				
			||||||
        $page = $chapter->pages->first();
 | 
					        $page = $chapter->pages->first();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -261,7 +259,7 @@ class EntitySearchTest extends TestCase
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    public function test_sibling_search_for_pages_without_chapter()
 | 
					    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();
 | 
					        $bookChildren = $page->book->getDirectChildren();
 | 
				
			||||||
        $this->assertGreaterThan(2, count($bookChildren), 'Ensure we\'re testing with at least 1 sibling');
 | 
					        $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()
 | 
					    public function test_sibling_search_for_chapters()
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        $chapter = Chapter::query()->firstOrFail();
 | 
					        $chapter = $this->entities->chapter();
 | 
				
			||||||
        $bookChildren = $chapter->book->getDirectChildren();
 | 
					        $bookChildren = $chapter->book->getDirectChildren();
 | 
				
			||||||
        $this->assertGreaterThan(2, count($bookChildren), 'Ensure we\'re testing with at least 1 sibling');
 | 
					        $this->assertGreaterThan(2, count($bookChildren), 'Ensure we\'re testing with at least 1 sibling');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -311,7 +311,7 @@ class ExportTest extends TestCase
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    public function test_page_pdf_export_opens_details_blocks()
 | 
					    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>',
 | 
					            'html'     => '<details><summary>Hello</summary><p>Content!</p></details>',
 | 
				
			||||||
        ]);
 | 
					        ]);
 | 
				
			||||||
        $page->save();
 | 
					        $page->save();
 | 
				
			||||||
| 
						 | 
					@ -339,7 +339,7 @@ class ExportTest extends TestCase
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    public function test_page_markdown_export_uses_existing_markdown_if_apparent()
 | 
					    public function test_page_markdown_export_uses_existing_markdown_if_apparent()
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        $page = Page::query()->first()->forceFill([
 | 
					        $page = $this->entities->page()->forceFill([
 | 
				
			||||||
            'markdown' => '# A header',
 | 
					            'markdown' => '# A header',
 | 
				
			||||||
            'html'     => '<h1>Dogcat</h1>',
 | 
					            'html'     => '<h1>Dogcat</h1>',
 | 
				
			||||||
        ]);
 | 
					        ]);
 | 
				
			||||||
| 
						 | 
					@ -352,7 +352,7 @@ class ExportTest extends TestCase
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    public function test_page_markdown_export_converts_html_where_no_markdown()
 | 
					    public function test_page_markdown_export_converts_html_where_no_markdown()
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        $page = Page::query()->first()->forceFill([
 | 
					        $page = $this->entities->page()->forceFill([
 | 
				
			||||||
            'markdown' => '',
 | 
					            'markdown' => '',
 | 
				
			||||||
            'html'     => '<h1>Dogcat</h1><p>Some <strong>bold</strong> text</p>',
 | 
					            '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()
 | 
					    public function test_html_exports_contain_csp_meta_tag()
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        $entities = [
 | 
					        $entities = [
 | 
				
			||||||
            Page::query()->first(),
 | 
					            $this->entities->page(),
 | 
				
			||||||
            Book::query()->first(),
 | 
					            $this->entities->book(),
 | 
				
			||||||
            Chapter::query()->first(),
 | 
					            $this->entities->chapter(),
 | 
				
			||||||
        ];
 | 
					        ];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        foreach ($entities as $entity) {
 | 
					        foreach ($entities as $entity) {
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -16,7 +16,7 @@ class PageContentTest extends TestCase
 | 
				
			||||||
    public function test_page_includes()
 | 
					    public function test_page_includes()
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        $page = $this->entities->page();
 | 
					        $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->html = "<p id='section1'>Hello, This is a test</p><p id='section2'>This is a second block of content</p>";
 | 
				
			||||||
        $secondPage->save();
 | 
					        $secondPage->save();
 | 
				
			||||||
| 
						 | 
					@ -45,7 +45,7 @@ class PageContentTest extends TestCase
 | 
				
			||||||
    public function test_saving_page_with_includes()
 | 
					    public function test_saving_page_with_includes()
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        $page = $this->entities->page();
 | 
					        $page = $this->entities->page();
 | 
				
			||||||
        $secondPage = Page::query()->where('id', '!=', $page->id)->first();
 | 
					        $secondPage = $this->entities->page();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        $this->asEditor();
 | 
					        $this->asEditor();
 | 
				
			||||||
        $includeTag = '{{@' . $secondPage->id . '}}';
 | 
					        $includeTag = '{{@' . $secondPage->id . '}}';
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -2,7 +2,6 @@
 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace Tests\Entity;
 | 
					namespace Tests\Entity;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
use BookStack\Entities\Models\Book;
 | 
					 | 
				
			||||||
use BookStack\Entities\Models\Page;
 | 
					use BookStack\Entities\Models\Page;
 | 
				
			||||||
use BookStack\Entities\Models\PageRevision;
 | 
					use BookStack\Entities\Models\PageRevision;
 | 
				
			||||||
use BookStack\Entities\Repos\PageRepo;
 | 
					use BookStack\Entities\Repos\PageRepo;
 | 
				
			||||||
| 
						 | 
					@ -10,20 +9,13 @@ use Tests\TestCase;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class PageDraftTest extends TestCase
 | 
					class PageDraftTest extends TestCase
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    /**
 | 
					    protected Page $page;
 | 
				
			||||||
     * @var Page
 | 
					    protected PageRepo $pageRepo;
 | 
				
			||||||
     */
 | 
					 | 
				
			||||||
    protected $page;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    /**
 | 
					 | 
				
			||||||
     * @var PageRepo
 | 
					 | 
				
			||||||
     */
 | 
					 | 
				
			||||||
    protected $pageRepo;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    protected function setUp(): void
 | 
					    protected function setUp(): void
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        parent::setUp();
 | 
					        parent::setUp();
 | 
				
			||||||
        $this->page = Page::query()->first();
 | 
					        $this->page = $this->entities->page();
 | 
				
			||||||
        $this->pageRepo = app()->make(PageRepo::class);
 | 
					        $this->pageRepo = app()->make(PageRepo::class);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -2,20 +2,18 @@
 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace Tests\Entity;
 | 
					namespace Tests\Entity;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
use BookStack\Entities\Models\Book;
 | 
					 | 
				
			||||||
use BookStack\Entities\Models\Chapter;
 | 
					use BookStack\Entities\Models\Chapter;
 | 
				
			||||||
use BookStack\Entities\Models\Page;
 | 
					use BookStack\Entities\Models\Page;
 | 
				
			||||||
use Tests\TestCase;
 | 
					use Tests\TestCase;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class PageEditorTest extends TestCase
 | 
					class PageEditorTest extends TestCase
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    /** @var Page */
 | 
					    protected Page $page;
 | 
				
			||||||
    protected $page;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    protected function setUp(): void
 | 
					    protected function setUp(): void
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        parent::setUp();
 | 
					        parent::setUp();
 | 
				
			||||||
        $this->page = Page::query()->first();
 | 
					        $this->page = $this->entities->page();
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    public function test_default_editor_is_wysiwyg_for_new_pages()
 | 
					    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()
 | 
					    public function test_back_link_in_editor_has_correct_url()
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        /** @var Book $book */
 | 
					        $book = $this->entities->bookHasChaptersAndPages();
 | 
				
			||||||
        $book = Book::query()->whereHas('pages')->whereHas('chapters')->firstOrFail();
 | 
					 | 
				
			||||||
        $this->asEditor()->get($book->getUrl('/create-page'));
 | 
					        $this->asEditor()->get($book->getUrl('/create-page'));
 | 
				
			||||||
        /** @var Chapter $chapter */
 | 
					        /** @var Chapter $chapter */
 | 
				
			||||||
        $chapter = $book->chapters()->firstOrFail();
 | 
					        $chapter = $book->chapters()->firstOrFail();
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -21,7 +21,7 @@ class PageRevisionTest extends TestCase
 | 
				
			||||||
    public function test_page_revision_views_viewable()
 | 
					    public function test_page_revision_views_viewable()
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        $this->asEditor();
 | 
					        $this->asEditor();
 | 
				
			||||||
        $page = Page::first();
 | 
					        $page = $this->entities->page();
 | 
				
			||||||
        $this->createRevisions($page, 1, ['name' => 'updated page', 'html' => '<p>new content</p>']);
 | 
					        $this->createRevisions($page, 1, ['name' => 'updated page', 'html' => '<p>new content</p>']);
 | 
				
			||||||
        $pageRevision = $page->revisions->last();
 | 
					        $pageRevision = $page->revisions->last();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -37,7 +37,7 @@ class PageRevisionTest extends TestCase
 | 
				
			||||||
    public function test_page_revision_preview_shows_content_of_revision()
 | 
					    public function test_page_revision_preview_shows_content_of_revision()
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        $this->asEditor();
 | 
					        $this->asEditor();
 | 
				
			||||||
        $page = Page::first();
 | 
					        $page = $this->entities->page();
 | 
				
			||||||
        $this->createRevisions($page, 1, ['name' => 'updated page', 'html' => '<p>new revision content</p>']);
 | 
					        $this->createRevisions($page, 1, ['name' => 'updated page', 'html' => '<p>new revision content</p>']);
 | 
				
			||||||
        $pageRevision = $page->revisions->last();
 | 
					        $pageRevision = $page->revisions->last();
 | 
				
			||||||
        $this->createRevisions($page, 1, ['name' => 'updated page', 'html' => '<p>Updated content</p>']);
 | 
					        $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()
 | 
					    public function test_page_revision_restore_updates_content()
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        $this->asEditor();
 | 
					        $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 abc123', 'html' => '<p>new contente def456</p>']);
 | 
				
			||||||
        $this->createRevisions($page, 1, ['name' => 'updated page again', 'html' => '<p>new content</p>']);
 | 
					        $this->createRevisions($page, 1, ['name' => 'updated page again', 'html' => '<p>new content</p>']);
 | 
				
			||||||
        $page = Page::find($page->id);
 | 
					        $page = Page::find($page->id);
 | 
				
			||||||
| 
						 | 
					@ -74,7 +74,7 @@ class PageRevisionTest extends TestCase
 | 
				
			||||||
    public function test_page_revision_restore_with_markdown_retains_markdown_content()
 | 
					    public function test_page_revision_restore_with_markdown_retains_markdown_content()
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        $this->asEditor();
 | 
					        $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 abc123', 'markdown' => '## New Content def456']);
 | 
				
			||||||
        $this->createRevisions($page, 1, ['name' => 'updated page again', 'markdown' => '## New Content Updated']);
 | 
					        $this->createRevisions($page, 1, ['name' => 'updated page again', 'markdown' => '## New Content Updated']);
 | 
				
			||||||
        $page = Page::find($page->id);
 | 
					        $page = Page::find($page->id);
 | 
				
			||||||
| 
						 | 
					@ -102,7 +102,7 @@ class PageRevisionTest extends TestCase
 | 
				
			||||||
    public function test_page_revision_restore_sets_new_revision_with_summary()
 | 
					    public function test_page_revision_restore_sets_new_revision_with_summary()
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        $this->asEditor();
 | 
					        $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, ['name' => 'updated page abc123', 'html' => '<p>new contente def456</p>', 'summary' => 'My first update']);
 | 
				
			||||||
        $this->createRevisions($page, 1, ['html' => '<p>new content</p>']);
 | 
					        $this->createRevisions($page, 1, ['html' => '<p>new content</p>']);
 | 
				
			||||||
        $page->refresh();
 | 
					        $page->refresh();
 | 
				
			||||||
| 
						 | 
					@ -124,7 +124,7 @@ class PageRevisionTest extends TestCase
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    public function test_page_revision_count_increments_on_update()
 | 
					    public function test_page_revision_count_increments_on_update()
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        $page = Page::first();
 | 
					        $page = $this->entities->page();
 | 
				
			||||||
        $startCount = $page->revision_count;
 | 
					        $startCount = $page->revision_count;
 | 
				
			||||||
        $this->createRevisions($page, 1);
 | 
					        $this->createRevisions($page, 1);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -133,7 +133,7 @@ class PageRevisionTest extends TestCase
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    public function test_revision_count_shown_in_page_meta()
 | 
					    public function test_revision_count_shown_in_page_meta()
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        $page = Page::first();
 | 
					        $page = $this->entities->page();
 | 
				
			||||||
        $this->createRevisions($page, 2);
 | 
					        $this->createRevisions($page, 2);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        $pageView = $this->get($page->getUrl());
 | 
					        $pageView = $this->get($page->getUrl());
 | 
				
			||||||
| 
						 | 
					@ -172,7 +172,7 @@ class PageRevisionTest extends TestCase
 | 
				
			||||||
    public function test_revision_limit_enforced()
 | 
					    public function test_revision_limit_enforced()
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        config()->set('app.revision_limit', 2);
 | 
					        config()->set('app.revision_limit', 2);
 | 
				
			||||||
        $page = Page::first();
 | 
					        $page = $this->entities->page();
 | 
				
			||||||
        $this->createRevisions($page, 12);
 | 
					        $this->createRevisions($page, 12);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        $revisionCount = $page->revisions()->count();
 | 
					        $revisionCount = $page->revisions()->count();
 | 
				
			||||||
| 
						 | 
					@ -182,7 +182,7 @@ class PageRevisionTest extends TestCase
 | 
				
			||||||
    public function test_false_revision_limit_allows_many_revisions()
 | 
					    public function test_false_revision_limit_allows_many_revisions()
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        config()->set('app.revision_limit', false);
 | 
					        config()->set('app.revision_limit', false);
 | 
				
			||||||
        $page = Page::first();
 | 
					        $page = $this->entities->page();
 | 
				
			||||||
        $this->createRevisions($page, 12);
 | 
					        $this->createRevisions($page, 12);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        $revisionCount = $page->revisions()->count();
 | 
					        $revisionCount = $page->revisions()->count();
 | 
				
			||||||
| 
						 | 
					@ -191,8 +191,7 @@ class PageRevisionTest extends TestCase
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    public function test_revision_list_shows_editor_type()
 | 
					    public function test_revision_list_shows_editor_type()
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        /** @var Page $page */
 | 
					        $page = $this->entities->page();
 | 
				
			||||||
        $page = Page::first();
 | 
					 | 
				
			||||||
        $this->createRevisions($page, 1, ['html' => 'new page html']);
 | 
					        $this->createRevisions($page, 1, ['html' => 'new page html']);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        $resp = $this->asAdmin()->get($page->refresh()->getUrl('/revisions'));
 | 
					        $resp = $this->asAdmin()->get($page->refresh()->getUrl('/revisions'));
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -9,7 +9,7 @@ class PageTemplateTest extends TestCase
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    public function test_active_templates_visible_on_page_view()
 | 
					    public function test_active_templates_visible_on_page_view()
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        $page = Page::first();
 | 
					        $page = $this->entities->page();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        $this->asEditor();
 | 
					        $this->asEditor();
 | 
				
			||||||
        $templateView = $this->get($page->getUrl());
 | 
					        $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()
 | 
					    public function test_manage_templates_permission_required_to_change_page_template_status()
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        $page = Page::first();
 | 
					        $page = $this->entities->page();
 | 
				
			||||||
        $editor = $this->getEditor();
 | 
					        $editor = $this->getEditor();
 | 
				
			||||||
        $this->actingAs($editor);
 | 
					        $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()
 | 
					    public function test_templates_content_should_be_fetchable_only_if_page_marked_as_template()
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        $content = '<div>my_custom_template_content</div>';
 | 
					        $content = '<div>my_custom_template_content</div>';
 | 
				
			||||||
        $page = Page::first();
 | 
					        $page = $this->entities->page();
 | 
				
			||||||
        $editor = $this->getEditor();
 | 
					        $editor = $this->getEditor();
 | 
				
			||||||
        $this->actingAs($editor);
 | 
					        $this->actingAs($editor);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -3,7 +3,6 @@
 | 
				
			||||||
namespace Tests\Entity;
 | 
					namespace Tests\Entity;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
use BookStack\Entities\Models\Book;
 | 
					use BookStack\Entities\Models\Book;
 | 
				
			||||||
use BookStack\Entities\Models\Chapter;
 | 
					 | 
				
			||||||
use BookStack\Entities\Models\Page;
 | 
					use BookStack\Entities\Models\Page;
 | 
				
			||||||
use Carbon\Carbon;
 | 
					use Carbon\Carbon;
 | 
				
			||||||
use Tests\TestCase;
 | 
					use Tests\TestCase;
 | 
				
			||||||
| 
						 | 
					@ -128,7 +127,7 @@ class PageTest extends TestCase
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    public function test_page_copy()
 | 
					    public function test_page_copy()
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        $page = Page::first();
 | 
					        $page = $this->entities->page();
 | 
				
			||||||
        $page->html = '<p>This is some test content</p>';
 | 
					        $page->html = '<p>This is some test content</p>';
 | 
				
			||||||
        $page->save();
 | 
					        $page->save();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -151,7 +150,7 @@ class PageTest extends TestCase
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    public function test_page_copy_with_markdown_has_both_html_and_markdown()
 | 
					    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->html = '<h1>This is some test content</h1>';
 | 
				
			||||||
        $page->markdown = '# This is some test content';
 | 
					        $page->markdown = '# This is some test content';
 | 
				
			||||||
        $page->save();
 | 
					        $page->save();
 | 
				
			||||||
| 
						 | 
					@ -169,7 +168,7 @@ class PageTest extends TestCase
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    public function test_page_copy_with_no_destination()
 | 
					    public function test_page_copy_with_no_destination()
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        $page = Page::first();
 | 
					        $page = $this->entities->page();
 | 
				
			||||||
        $currentBook = $page->book;
 | 
					        $currentBook = $page->book;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        $resp = $this->asEditor()->get($page->getUrl('/copy'));
 | 
					        $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()
 | 
					    public function test_page_can_be_copied_without_edit_permission()
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        $page = Page::first();
 | 
					        $page = $this->entities->page();
 | 
				
			||||||
        $currentBook = $page->book;
 | 
					        $currentBook = $page->book;
 | 
				
			||||||
        $newBook = Book::where('id', '!=', $currentBook->id)->first();
 | 
					        $newBook = Book::where('id', '!=', $currentBook->id)->first();
 | 
				
			||||||
        $viewer = $this->getViewer();
 | 
					        $viewer = $this->getViewer();
 | 
				
			||||||
| 
						 | 
					@ -274,8 +273,7 @@ class PageTest extends TestCase
 | 
				
			||||||
    public function test_recently_updated_pages_view_shows_parent_chain()
 | 
					    public function test_recently_updated_pages_view_shows_parent_chain()
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        $user = $this->getEditor();
 | 
					        $user = $this->getEditor();
 | 
				
			||||||
        /** @var Page $page */
 | 
					        $page = $this->entities->pageWithinChapter();
 | 
				
			||||||
        $page = Page::query()->whereNotNull('chapter_id')->first();
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
        $this->actingAs($user)->put($page->getUrl(), [
 | 
					        $this->actingAs($user)->put($page->getUrl(), [
 | 
				
			||||||
            'name' => 'Updated title',
 | 
					            '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()
 | 
					    public function test_recently_updated_pages_view_does_not_show_parent_if_not_visible()
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        $user = $this->getEditor();
 | 
					        $user = $this->getEditor();
 | 
				
			||||||
        /** @var Page $page */
 | 
					        $page = $this->entities->pageWithinChapter();
 | 
				
			||||||
        $page = Page::query()->whereNotNull('chapter_id')->first();
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
        $this->actingAs($user)->put($page->getUrl(), [
 | 
					        $this->actingAs($user)->put($page->getUrl(), [
 | 
				
			||||||
            'name' => 'Updated title',
 | 
					            'name' => 'Updated title',
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -10,24 +10,17 @@ use Tests\TestCase;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class SortTest extends 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()
 | 
					    public function test_drafts_do_not_show_up()
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        $this->asAdmin();
 | 
					        $this->asAdmin();
 | 
				
			||||||
        $pageRepo = app(PageRepo::class);
 | 
					        $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->assertSee($draft->name);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        $resp = $this->get($this->book->getUrl() . '/sort');
 | 
					        $resp = $this->get($book->getUrl() . '/sort');
 | 
				
			||||||
        $resp->assertDontSee($draft->name);
 | 
					        $resp->assertDontSee($draft->name);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -43,7 +36,7 @@ class SortTest extends TestCase
 | 
				
			||||||
        $movePageResp = $this->put($page->getUrl('/move'), [
 | 
					        $movePageResp = $this->put($page->getUrl('/move'), [
 | 
				
			||||||
            'entity_selection' => 'book:' . $newBook->id,
 | 
					            'entity_selection' => 'book:' . $newBook->id,
 | 
				
			||||||
        ]);
 | 
					        ]);
 | 
				
			||||||
        $page = Page::query()->find($page->id);
 | 
					        $page->refresh();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        $movePageResp->assertRedirect($page->getUrl());
 | 
					        $movePageResp->assertRedirect($page->getUrl());
 | 
				
			||||||
        $this->assertTrue($page->book->id == $newBook->id, 'Page book is now the new book');
 | 
					        $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'), [
 | 
					        $movePageResp = $this->actingAs($this->getEditor())->put($page->getUrl('/move'), [
 | 
				
			||||||
            'entity_selection' => 'chapter:' . $newChapter->id,
 | 
					            'entity_selection' => 'chapter:' . $newChapter->id,
 | 
				
			||||||
        ]);
 | 
					        ]);
 | 
				
			||||||
        $page = Page::query()->find($page->id);
 | 
					        $page->refresh();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        $movePageResp->assertRedirect($page->getUrl());
 | 
					        $movePageResp->assertRedirect($page->getUrl());
 | 
				
			||||||
        $this->assertTrue($page->book->id == $newBook->id, 'Page parent is now the new chapter');
 | 
					        $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,
 | 
					            'entity_selection' => 'book:' . $newBook->id,
 | 
				
			||||||
        ]);
 | 
					        ]);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        $page = Page::query()->find($page->id);
 | 
					        $page->refresh();
 | 
				
			||||||
        $movePageResp->assertRedirect($page->getUrl());
 | 
					        $movePageResp->assertRedirect($page->getUrl());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        $this->assertTrue($page->book->id == $newBook->id, 'Page book is now the new book');
 | 
					        $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,
 | 
					            'entity_selection' => 'book:' . $newBook->id,
 | 
				
			||||||
        ]);
 | 
					        ]);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        $page = Page::query()->find($page->id);
 | 
					        $page->refresh();
 | 
				
			||||||
        $movePageResp->assertRedirect($page->getUrl());
 | 
					        $movePageResp->assertRedirect($page->getUrl());
 | 
				
			||||||
        $this->assertTrue($page->book->id == $newBook->id, 'Page book is now the new book');
 | 
					        $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()
 | 
					    public function test_book_sort_page_shows()
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        /** @var Book $bookToSort */
 | 
					        $bookToSort = $this->entities->book();
 | 
				
			||||||
        $bookToSort = Book::query()->first();
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
        $resp = $this->asAdmin()->get($bookToSort->getUrl());
 | 
					        $resp = $this->asAdmin()->get($bookToSort->getUrl());
 | 
				
			||||||
        $this->withHtml($resp)->assertElementExists('a[href="' . $bookToSort->getUrl('/sort') . '"]');
 | 
					        $this->withHtml($resp)->assertElementExists('a[href="' . $bookToSort->getUrl('/sort') . '"]');
 | 
				
			||||||
| 
						 | 
					@ -256,7 +248,7 @@ class SortTest extends TestCase
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    public function test_book_sort()
 | 
					    public function test_book_sort()
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        $oldBook = Book::query()->first();
 | 
					        $oldBook = $this->entities->book();
 | 
				
			||||||
        $chapterToMove = $this->entities->newChapter(['name' => 'chapter to move'], $oldBook);
 | 
					        $chapterToMove = $this->entities->newChapter(['name' => 'chapter to move'], $oldBook);
 | 
				
			||||||
        $newBook = $this->entities->newBook(['name' => 'New sort book']);
 | 
					        $newBook = $this->entities->newBook(['name' => 'New sort book']);
 | 
				
			||||||
        $pagesToMove = Page::query()->take(5)->get();
 | 
					        $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()
 | 
					    public function test_book_sort_makes_no_changes_if_new_chapter_does_not_align_with_new_book()
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        /** @var Page $page */
 | 
					        $page = $this->entities->pageWithinChapter();
 | 
				
			||||||
        $page = Page::query()->where('chapter_id', '!=', 0)->first();
 | 
					 | 
				
			||||||
        $otherChapter = Chapter::query()->where('book_id', '!=', $page->book_id)->first();
 | 
					        $otherChapter = Chapter::query()->where('book_id', '!=', $page->book_id)->first();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        $sortData = [
 | 
					        $sortData = [
 | 
				
			||||||
| 
						 | 
					@ -319,8 +310,7 @@ class SortTest extends TestCase
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    public function test_book_sort_makes_no_changes_if_no_view_permissions_on_new_chapter()
 | 
					    public function test_book_sort_makes_no_changes_if_no_view_permissions_on_new_chapter()
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        /** @var Page $page */
 | 
					        $page = $this->entities->pageWithinChapter();
 | 
				
			||||||
        $page = Page::query()->where('chapter_id', '!=', 0)->first();
 | 
					 | 
				
			||||||
        /** @var Chapter $otherChapter */
 | 
					        /** @var Chapter $otherChapter */
 | 
				
			||||||
        $otherChapter = Chapter::query()->where('book_id', '!=', $page->book_id)->first();
 | 
					        $otherChapter = Chapter::query()->where('book_id', '!=', $page->book_id)->first();
 | 
				
			||||||
        $this->entities->setPermissions($otherChapter);
 | 
					        $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()
 | 
					    public function test_book_sort_makes_no_changes_if_no_view_permissions_on_new_book()
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        /** @var Page $page */
 | 
					        $page = $this->entities->pageWithinChapter();
 | 
				
			||||||
        $page = Page::query()->where('chapter_id', '!=', 0)->first();
 | 
					 | 
				
			||||||
        /** @var Chapter $otherChapter */
 | 
					        /** @var Chapter $otherChapter */
 | 
				
			||||||
        $otherChapter = Chapter::query()->where('book_id', '!=', $page->book_id)->first();
 | 
					        $otherChapter = Chapter::query()->where('book_id', '!=', $page->book_id)->first();
 | 
				
			||||||
        $editor = $this->getEditor();
 | 
					        $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()
 | 
					    public function test_book_sort_makes_no_changes_if_no_update_or_create_permissions_on_new_chapter()
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        /** @var Page $page */
 | 
					        $page = $this->entities->pageWithinChapter();
 | 
				
			||||||
        $page = Page::query()->where('chapter_id', '!=', 0)->first();
 | 
					 | 
				
			||||||
        /** @var Chapter $otherChapter */
 | 
					        /** @var Chapter $otherChapter */
 | 
				
			||||||
        $otherChapter = Chapter::query()->where('book_id', '!=', $page->book_id)->first();
 | 
					        $otherChapter = Chapter::query()->where('book_id', '!=', $page->book_id)->first();
 | 
				
			||||||
        $editor = $this->getEditor();
 | 
					        $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()
 | 
					    public function test_book_sort_makes_no_changes_if_no_update_permissions_on_moved_item()
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        /** @var Page $page */
 | 
					        $page = $this->entities->pageWithinChapter();
 | 
				
			||||||
        $page = Page::query()->where('chapter_id', '!=', 0)->first();
 | 
					 | 
				
			||||||
        /** @var Chapter $otherChapter */
 | 
					        /** @var Chapter $otherChapter */
 | 
				
			||||||
        $otherChapter = Chapter::query()->where('book_id', '!=', $page->book_id)->first();
 | 
					        $otherChapter = Chapter::query()->where('book_id', '!=', $page->book_id)->first();
 | 
				
			||||||
        $editor = $this->getEditor();
 | 
					        $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()
 | 
					    public function test_book_sort_makes_no_changes_if_no_delete_permissions_on_moved_item()
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        /** @var Page $page */
 | 
					        $page = $this->entities->pageWithinChapter();
 | 
				
			||||||
        $page = Page::query()->where('chapter_id', '!=', 0)->first();
 | 
					 | 
				
			||||||
        /** @var Chapter $otherChapter */
 | 
					        /** @var Chapter $otherChapter */
 | 
				
			||||||
        $otherChapter = Chapter::query()->where('book_id', '!=', $page->book_id)->first();
 | 
					        $otherChapter = Chapter::query()->where('book_id', '!=', $page->book_id)->first();
 | 
				
			||||||
        $editor = $this->getEditor();
 | 
					        $editor = $this->getEditor();
 | 
				
			||||||
| 
						 | 
					@ -433,8 +419,7 @@ class SortTest extends TestCase
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    public function test_book_sort_item_returns_book_content()
 | 
					    public function test_book_sort_item_returns_book_content()
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        $books = Book::all();
 | 
					        $bookToSort = $this->entities->book();
 | 
				
			||||||
        $bookToSort = $books[0];
 | 
					 | 
				
			||||||
        $firstPage = $bookToSort->pages[0];
 | 
					        $firstPage = $bookToSort->pages[0];
 | 
				
			||||||
        $firstChapter = $bookToSort->chapters[0];
 | 
					        $firstChapter = $bookToSort->chapters[0];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -448,8 +433,7 @@ class SortTest extends TestCase
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    public function test_pages_in_book_show_sorted_by_priority()
 | 
					    public function test_pages_in_book_show_sorted_by_priority()
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        /** @var Book $book */
 | 
					        $book = $this->entities->bookHasChaptersAndPages();
 | 
				
			||||||
        $book = Book::query()->whereHas('pages')->first();
 | 
					 | 
				
			||||||
        $book->chapters()->forceDelete();
 | 
					        $book->chapters()->forceDelete();
 | 
				
			||||||
        /** @var Page[] $pages */
 | 
					        /** @var Page[] $pages */
 | 
				
			||||||
        $pages = $book->pages()->where('chapter_id', '=', 0)->take(2)->get();
 | 
					        $pages = $book->pages()->where('chapter_id', '=', 0)->take(2)->get();
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -3,7 +3,6 @@
 | 
				
			||||||
namespace Tests\Entity;
 | 
					namespace Tests\Entity;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
use BookStack\Actions\Tag;
 | 
					use BookStack\Actions\Tag;
 | 
				
			||||||
use BookStack\Entities\Models\Book;
 | 
					 | 
				
			||||||
use BookStack\Entities\Models\Entity;
 | 
					use BookStack\Entities\Models\Entity;
 | 
				
			||||||
use BookStack\Entities\Models\Page;
 | 
					use BookStack\Entities\Models\Page;
 | 
				
			||||||
use Tests\TestCase;
 | 
					use Tests\TestCase;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -2,7 +2,6 @@
 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace Tests;
 | 
					namespace Tests;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
use BookStack\Entities\Models\Book;
 | 
					 | 
				
			||||||
use Illuminate\Support\Facades\Log;
 | 
					use Illuminate\Support\Facades\Log;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class ErrorTest extends TestCase
 | 
					class ErrorTest extends TestCase
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -4,10 +4,6 @@ namespace Tests;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
use BookStack\Actions\Favourite;
 | 
					use BookStack\Actions\Favourite;
 | 
				
			||||||
use BookStack\Auth\User;
 | 
					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
 | 
					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());
 | 
					        $this->actingAs($this->getEditor());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        foreach ($entities as $entity) {
 | 
					        foreach ($this->entities->all() as $entity) {
 | 
				
			||||||
            $resp = $this->get($entity->getUrl());
 | 
					            $resp = $this->get($entity->getUrl());
 | 
				
			||||||
            $this->withHtml($resp)->assertElementExists('form[method="POST"][action$="/favourites/add"]');
 | 
					            $this->withHtml($resp)->assertElementExists('form[method="POST"][action$="/favourites/add"]');
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -13,7 +13,13 @@ use BookStack\Entities\Repos\BookRepo;
 | 
				
			||||||
use BookStack\Entities\Repos\BookshelfRepo;
 | 
					use BookStack\Entities\Repos\BookshelfRepo;
 | 
				
			||||||
use BookStack\Entities\Repos\ChapterRepo;
 | 
					use BookStack\Entities\Repos\ChapterRepo;
 | 
				
			||||||
use BookStack\Entities\Repos\PageRepo;
 | 
					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
 | 
					class EntityProvider
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    /**
 | 
					    /**
 | 
				
			||||||
| 
						 | 
					@ -29,43 +35,68 @@ class EntityProvider
 | 
				
			||||||
    /**
 | 
					    /**
 | 
				
			||||||
     * Get an un-fetched page from the system.
 | 
					     * Get an un-fetched page from the system.
 | 
				
			||||||
     */
 | 
					     */
 | 
				
			||||||
    public function page(): Page
 | 
					    public function page(callable $queryFilter = null): Page
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        /** @var Page $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);
 | 
					        $this->addToCache($page);
 | 
				
			||||||
        return $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.
 | 
					     * Get an un-fetched chapter from the system.
 | 
				
			||||||
     */
 | 
					     */
 | 
				
			||||||
    public function chapter(): Chapter
 | 
					    public function chapter(callable $queryFilter = null): Chapter
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        /** @var Chapter $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);
 | 
					        $this->addToCache($chapter);
 | 
				
			||||||
        return $chapter;
 | 
					        return $chapter;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public function chapterHasPages(): Chapter
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        return $this->chapter(fn(Builder $query) => $query->whereHas('pages'));
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /**
 | 
					    /**
 | 
				
			||||||
     * Get an un-fetched book from the system.
 | 
					     * Get an un-fetched book from the system.
 | 
				
			||||||
     */
 | 
					     */
 | 
				
			||||||
    public function book(): Book
 | 
					    public function book(callable $queryFilter = null): Book
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        /** @var Book $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);
 | 
					        $this->addToCache($book);
 | 
				
			||||||
        return $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.
 | 
					     * Get an un-fetched shelf from the system.
 | 
				
			||||||
     */
 | 
					     */
 | 
				
			||||||
    public function shelf(): Bookshelf
 | 
					    public function shelf(callable $queryFilter = null): Bookshelf
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        /** @var Bookshelf $shelf */
 | 
					        /** @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);
 | 
					        $this->addToCache($shelf);
 | 
				
			||||||
        return $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.
 | 
					     * Create a book to page chain of entities that belong to a specific user.
 | 
				
			||||||
     * @return array{book: Book, chapter: Chapter, page: Page}
 | 
					     * @return array{book: Book, chapter: Chapter, page: Page}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,6 +1,6 @@
 | 
				
			||||||
<?php
 | 
					<?php
 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace Tests;
 | 
					namespace Tests\Helpers;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
use Illuminate\Support\Facades\Artisan;
 | 
					use Illuminate\Support\Facades\Artisan;
 | 
				
			||||||
use Illuminate\Support\Facades\ParallelTesting;
 | 
					use Illuminate\Support\Facades\ParallelTesting;
 | 
				
			||||||
| 
						 | 
					@ -4,8 +4,6 @@ namespace Tests;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
use BookStack\Auth\Role;
 | 
					use BookStack\Auth\Role;
 | 
				
			||||||
use BookStack\Auth\User;
 | 
					use BookStack\Auth\User;
 | 
				
			||||||
use BookStack\Entities\Models\Bookshelf;
 | 
					 | 
				
			||||||
use BookStack\Entities\Models\Page;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
class HomepageTest extends TestCase
 | 
					class HomepageTest extends TestCase
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
| 
						 | 
					@ -99,8 +97,7 @@ class HomepageTest extends TestCase
 | 
				
			||||||
    public function test_custom_homepage_renders_includes()
 | 
					    public function test_custom_homepage_renders_includes()
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        $this->asEditor();
 | 
					        $this->asEditor();
 | 
				
			||||||
        /** @var Page $included */
 | 
					        $included = $this->entities->page();
 | 
				
			||||||
        $included = Page::query()->first();
 | 
					 | 
				
			||||||
        $content = str_repeat('This is the body content of my custom homepage.', 20);
 | 
					        $content = str_repeat('This is the body content of my custom homepage.', 20);
 | 
				
			||||||
        $included->html = $content;
 | 
					        $included->html = $content;
 | 
				
			||||||
        $included->save();
 | 
					        $included->save();
 | 
				
			||||||
| 
						 | 
					@ -138,7 +135,7 @@ class HomepageTest extends TestCase
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        $editor = $this->getEditor();
 | 
					        $editor = $this->getEditor();
 | 
				
			||||||
        setting()->putUser($editor, 'bookshelves_view_type', 'grid');
 | 
					        setting()->putUser($editor, 'bookshelves_view_type', 'grid');
 | 
				
			||||||
        $shelf = Bookshelf::query()->firstOrFail();
 | 
					        $shelf = $this->entities->shelf();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        $this->setSettings(['app-homepage-type' => 'bookshelves']);
 | 
					        $this->setSettings(['app-homepage-type' => 'bookshelves']);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -2,10 +2,6 @@
 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace Tests;
 | 
					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\BaseRepo;
 | 
				
			||||||
use BookStack\Entities\Repos\BookRepo;
 | 
					use BookStack\Entities\Repos\BookRepo;
 | 
				
			||||||
use Illuminate\Support\Str;
 | 
					use Illuminate\Support\Str;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -3,10 +3,6 @@
 | 
				
			||||||
namespace Tests\Permissions;
 | 
					namespace Tests\Permissions;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
use BookStack\Auth\User;
 | 
					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;
 | 
					use Tests\TestCase;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class EntityOwnerChangeTest extends TestCase
 | 
					class EntityOwnerChangeTest extends TestCase
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -13,15 +13,8 @@ use Tests\TestCase;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class EntityPermissionsTest extends TestCase
 | 
					class EntityPermissionsTest extends TestCase
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    /**
 | 
					    protected User $user;
 | 
				
			||||||
     * @var User
 | 
					    protected User $viewer;
 | 
				
			||||||
     */
 | 
					 | 
				
			||||||
    protected $user;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    /**
 | 
					 | 
				
			||||||
     * @var User
 | 
					 | 
				
			||||||
     */
 | 
					 | 
				
			||||||
    protected $viewer;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    protected function setUp(): void
 | 
					    protected function setUp(): void
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -2,8 +2,6 @@
 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace Tests\Permissions;
 | 
					namespace Tests\Permissions;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
use BookStack\Entities\Models\Book;
 | 
					 | 
				
			||||||
use BookStack\Entities\Models\Chapter;
 | 
					 | 
				
			||||||
use Illuminate\Support\Str;
 | 
					use Illuminate\Support\Str;
 | 
				
			||||||
use Tests\TestCase;
 | 
					use Tests\TestCase;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -17,7 +17,7 @@ use Tests\TestCase;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class RolesTest extends TestCase
 | 
					class RolesTest extends TestCase
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    protected $user;
 | 
					    protected User $user;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    protected function setUp(): void
 | 
					    protected function setUp(): void
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -8,7 +8,6 @@ use BookStack\Auth\Role;
 | 
				
			||||||
use BookStack\Auth\User;
 | 
					use BookStack\Auth\User;
 | 
				
			||||||
use BookStack\Entities\Models\Book;
 | 
					use BookStack\Entities\Models\Book;
 | 
				
			||||||
use BookStack\Entities\Models\Chapter;
 | 
					use BookStack\Entities\Models\Chapter;
 | 
				
			||||||
use BookStack\Entities\Models\Page;
 | 
					 | 
				
			||||||
use Illuminate\Support\Facades\Auth;
 | 
					use Illuminate\Support\Facades\Auth;
 | 
				
			||||||
use Illuminate\Support\Facades\View;
 | 
					use Illuminate\Support\Facades\View;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -2,7 +2,6 @@
 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace Tests\References;
 | 
					namespace Tests\References;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
use BookStack\Entities\Models\Page;
 | 
					 | 
				
			||||||
use BookStack\References\CrossLinkParser;
 | 
					use BookStack\References\CrossLinkParser;
 | 
				
			||||||
use Tests\TestCase;
 | 
					use Tests\TestCase;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -11,7 +10,7 @@ class CrossLinkParserTest extends TestCase
 | 
				
			||||||
    public function test_instance_with_entity_resolvers_matches_entity_links()
 | 
					    public function test_instance_with_entity_resolvers_matches_entity_links()
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        $entities = $this->entities->all();
 | 
					        $entities = $this->entities->all();
 | 
				
			||||||
        $otherPage = Page::query()->where('id', '!=', $entities['page']->id)->first();
 | 
					        $otherPage = $this->entities->page();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        $html = '
 | 
					        $html = '
 | 
				
			||||||
<a href="' . url('/link/' . $otherPage->id) . '#cat">Page Permalink</a>
 | 
					<a href="' . url('/link/' . $otherPage->id) . '#cat">Page Permalink</a>
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -2,9 +2,6 @@
 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace Tests\References;
 | 
					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\Repos\PageRepo;
 | 
				
			||||||
use BookStack\Entities\Tools\TrashCan;
 | 
					use BookStack\Entities\Tools\TrashCan;
 | 
				
			||||||
use BookStack\Model;
 | 
					use BookStack\Model;
 | 
				
			||||||
| 
						 | 
					@ -15,10 +12,8 @@ class ReferencesTest extends TestCase
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    public function test_references_created_on_page_update()
 | 
					    public function test_references_created_on_page_update()
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        /** @var Page $pageA */
 | 
					        $pageA = $this->entities->page();
 | 
				
			||||||
        /** @var Page $pageB */
 | 
					        $pageB = $this->entities->page();
 | 
				
			||||||
        $pageA = Page::query()->first();
 | 
					 | 
				
			||||||
        $pageB = Page::query()->where('id', '!=', $pageA->id)->first();
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
        $this->assertDatabaseMissing('references', ['from_id' => $pageA->id, 'from_type' => $pageA->getMorphClass()]);
 | 
					        $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()
 | 
					    public function test_references_deleted_on_entity_delete()
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        /** @var Page $pageA */
 | 
					        $pageA = $this->entities->page();
 | 
				
			||||||
        /** @var Page $pageB */
 | 
					        $pageB = $this->entities->page();
 | 
				
			||||||
        $pageA = Page::query()->first();
 | 
					 | 
				
			||||||
        $pageB = Page::query()->where('id', '!=', $pageA->id)->first();
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
        $this->createReference($pageA, $pageB);
 | 
					        $this->createReference($pageA, $pageB);
 | 
				
			||||||
        $this->createReference($pageB, $pageA);
 | 
					        $this->createReference($pageB, $pageA);
 | 
				
			||||||
| 
						 | 
					@ -58,8 +51,7 @@ class ReferencesTest extends TestCase
 | 
				
			||||||
    public function test_references_to_count_visible_on_entity_show_view()
 | 
					    public function test_references_to_count_visible_on_entity_show_view()
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        $entities = $this->entities->all();
 | 
					        $entities = $this->entities->all();
 | 
				
			||||||
        /** @var Page $otherPage */
 | 
					        $otherPage = $this->entities->page();
 | 
				
			||||||
        $otherPage = Page::query()->where('id', '!=', $entities['page']->id)->first();
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
        $this->asEditor();
 | 
					        $this->asEditor();
 | 
				
			||||||
        foreach ($entities as $entity) {
 | 
					        foreach ($entities as $entity) {
 | 
				
			||||||
| 
						 | 
					@ -95,10 +87,8 @@ class ReferencesTest extends TestCase
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    public function test_reference_not_visible_if_view_permission_does_not_permit()
 | 
					    public function test_reference_not_visible_if_view_permission_does_not_permit()
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        /** @var Page $page */
 | 
					 | 
				
			||||||
        /** @var Page $pageB */
 | 
					 | 
				
			||||||
        $page = $this->entities->page();
 | 
					        $page = $this->entities->page();
 | 
				
			||||||
        $pageB = Page::query()->where('id', '!=', $page->id)->first();
 | 
					        $pageB = $this->entities->page();
 | 
				
			||||||
        $this->createReference($pageB, $page);
 | 
					        $this->createReference($pageB, $page);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        $this->entities->setPermissions($pageB);
 | 
					        $this->entities->setPermissions($pageB);
 | 
				
			||||||
| 
						 | 
					@ -118,11 +108,8 @@ class ReferencesTest extends TestCase
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    public function test_pages_leading_to_entity_updated_on_url_change()
 | 
					    public function test_pages_leading_to_entity_updated_on_url_change()
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        /** @var Page $pageA */
 | 
					        $pageA = $this->entities->page();
 | 
				
			||||||
        /** @var Page $pageB */
 | 
					        $pageB = $this->entities->page();
 | 
				
			||||||
        /** @var Book $book */
 | 
					 | 
				
			||||||
        $pageA = Page::query()->first();
 | 
					 | 
				
			||||||
        $pageB = Page::query()->where('id', '!=', $pageA->id)->first();
 | 
					 | 
				
			||||||
        $book = $this->entities->book();
 | 
					        $book = $this->entities->book();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        foreach ([$pageA, $pageB] as $page) {
 | 
					        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()
 | 
					    public function test_pages_linking_to_other_page_updated_on_parent_book_url_change()
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        /** @var Page $bookPage */
 | 
					        $bookPage = $this->entities->page();
 | 
				
			||||||
        /** @var Page $otherPage */
 | 
					        $otherPage = $this->entities->page();
 | 
				
			||||||
        /** @var Book $book */
 | 
					 | 
				
			||||||
        $bookPage = Page::query()->first();
 | 
					 | 
				
			||||||
        $otherPage = Page::query()->where('id', '!=', $bookPage->id)->first();
 | 
					 | 
				
			||||||
        $book = $bookPage->book;
 | 
					        $book = $bookPage->book;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        $otherPage->html = '<a href="' . $bookPage->getUrl() . '">Link</a>';
 | 
					        $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()
 | 
					    public function test_pages_linking_to_chapter_updated_on_parent_book_url_change()
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        /** @var Chapter $bookChapter */
 | 
					        $bookChapter = $this->entities->chapter();
 | 
				
			||||||
        /** @var Page $otherPage */
 | 
					        $otherPage = $this->entities->page();
 | 
				
			||||||
        /** @var Book $book */
 | 
					 | 
				
			||||||
        $bookChapter = Chapter::query()->first();
 | 
					 | 
				
			||||||
        $otherPage = Page::query()->first();
 | 
					 | 
				
			||||||
        $book = $bookChapter->book;
 | 
					        $book = $bookChapter->book;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        $otherPage->html = '<a href="' . $bookChapter->getUrl() . '">Link</a>';
 | 
					        $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()
 | 
					    public function test_markdown_links_leading_to_entity_updated_on_url_change()
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        /** @var Page $page */
 | 
					 | 
				
			||||||
        /** @var Book $book */
 | 
					 | 
				
			||||||
        $page = $this->entities->page();
 | 
					        $page = $this->entities->page();
 | 
				
			||||||
        $book = $this->entities->book();
 | 
					        $book = $this->entities->book();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -3,10 +3,7 @@
 | 
				
			||||||
namespace Tests\Settings;
 | 
					namespace Tests\Settings;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
use BookStack\Entities\Models\Book;
 | 
					use BookStack\Entities\Models\Book;
 | 
				
			||||||
use BookStack\Entities\Models\Bookshelf;
 | 
					 | 
				
			||||||
use BookStack\Entities\Models\Chapter;
 | 
					 | 
				
			||||||
use BookStack\Entities\Models\Deletion;
 | 
					use BookStack\Entities\Models\Deletion;
 | 
				
			||||||
use BookStack\Entities\Models\Entity;
 | 
					 | 
				
			||||||
use BookStack\Entities\Models\Page;
 | 
					use BookStack\Entities\Models\Page;
 | 
				
			||||||
use Illuminate\Support\Carbon;
 | 
					use Illuminate\Support\Carbon;
 | 
				
			||||||
use Illuminate\Support\Facades\DB;
 | 
					use Illuminate\Support\Facades\DB;
 | 
				
			||||||
| 
						 | 
					@ -97,7 +94,7 @@ class RecycleBinTest extends TestCase
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    public function test_entity_restore()
 | 
					    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());
 | 
					        $this->asEditor()->delete($book->getUrl());
 | 
				
			||||||
        $deletion = Deletion::query()->firstOrFail();
 | 
					        $deletion = Deletion::query()->firstOrFail();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -118,7 +115,7 @@ class RecycleBinTest extends TestCase
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    public function test_permanent_delete()
 | 
					    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());
 | 
					        $this->asEditor()->delete($book->getUrl());
 | 
				
			||||||
        $deletion = Deletion::query()->firstOrFail();
 | 
					        $deletion = Deletion::query()->firstOrFail();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -137,9 +134,7 @@ class RecycleBinTest extends TestCase
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    public function test_permanent_delete_for_each_type()
 | 
					    public function test_permanent_delete_for_each_type()
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        /** @var Entity $entity */
 | 
					        foreach ($this->entities->all() as $type => $entity) {
 | 
				
			||||||
        foreach ([new Bookshelf(), new Book(), new Chapter(), new Page()] as $entity) {
 | 
					 | 
				
			||||||
            $entity = $entity->newQuery()->first();
 | 
					 | 
				
			||||||
            $this->asEditor()->delete($entity->getUrl());
 | 
					            $this->asEditor()->delete($entity->getUrl());
 | 
				
			||||||
            $deletion = Deletion::query()->orderBy('id', 'desc')->firstOrFail();
 | 
					            $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()
 | 
					    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());
 | 
					        $this->asEditor()->delete($page->getUrl());
 | 
				
			||||||
        $deletion = $page->deletions()->firstOrFail();
 | 
					        $deletion = $page->deletions()->firstOrFail();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -181,8 +176,8 @@ class RecycleBinTest extends TestCase
 | 
				
			||||||
    public function test_auto_clear_functionality_works()
 | 
					    public function test_auto_clear_functionality_works()
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        config()->set('app.recycle_bin_lifetime', 5);
 | 
					        config()->set('app.recycle_bin_lifetime', 5);
 | 
				
			||||||
        $page = Page::query()->firstOrFail();
 | 
					        $page = $this->entities->page();
 | 
				
			||||||
        $otherPage = Page::query()->where('id', '!=', $page->id)->firstOrFail();
 | 
					        $otherPage = $this->entities->page();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        $this->asEditor()->delete($page->getUrl());
 | 
					        $this->asEditor()->delete($page->getUrl());
 | 
				
			||||||
        $this->assertDatabaseHas('pages', ['id' => $page->id]);
 | 
					        $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()
 | 
					    public function test_auto_clear_functionality_with_negative_time_keeps_forever()
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        config()->set('app.recycle_bin_lifetime', -1);
 | 
					        config()->set('app.recycle_bin_lifetime', -1);
 | 
				
			||||||
        $page = Page::query()->firstOrFail();
 | 
					        $page = $this->entities->page();
 | 
				
			||||||
        $otherPage = Page::query()->where('id', '!=', $page->id)->firstOrFail();
 | 
					        $otherPage = $this->entities->page();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        $this->asEditor()->delete($page->getUrl());
 | 
					        $this->asEditor()->delete($page->getUrl());
 | 
				
			||||||
        $this->assertEquals(1, Deletion::query()->count());
 | 
					        $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()
 | 
					    public function test_auto_clear_functionality_with_zero_time_deletes_instantly()
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        config()->set('app.recycle_bin_lifetime', 0);
 | 
					        config()->set('app.recycle_bin_lifetime', 0);
 | 
				
			||||||
        $page = Page::query()->firstOrFail();
 | 
					        $page = $this->entities->page();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        $this->asEditor()->delete($page->getUrl());
 | 
					        $this->asEditor()->delete($page->getUrl());
 | 
				
			||||||
        $this->assertDatabaseMissing('pages', ['id' => $page->id]);
 | 
					        $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()
 | 
					    public function test_restore_page_shows_link_to_parent_restore_if_parent_also_deleted()
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        /** @var Book $book */
 | 
					        $book = $this->entities->bookHasChaptersAndPages();
 | 
				
			||||||
        $book = Book::query()->whereHas('pages')->whereHas('chapters')->with(['pages', 'chapters'])->firstOrFail();
 | 
					 | 
				
			||||||
        $chapter = $book->chapters->first();
 | 
					        $chapter = $book->chapters->first();
 | 
				
			||||||
        /** @var Page $page */
 | 
					        /** @var Page $page */
 | 
				
			||||||
        $page = $chapter->pages->first();
 | 
					        $page = $chapter->pages->first();
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -27,6 +27,7 @@ use Monolog\Logger;
 | 
				
			||||||
use Psr\Http\Client\ClientInterface;
 | 
					use Psr\Http\Client\ClientInterface;
 | 
				
			||||||
use Ssddanbrown\AssertHtml\TestsHtml;
 | 
					use Ssddanbrown\AssertHtml\TestsHtml;
 | 
				
			||||||
use Tests\Helpers\EntityProvider;
 | 
					use Tests\Helpers\EntityProvider;
 | 
				
			||||||
 | 
					use Tests\Helpers\TestServiceProvider;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
abstract class TestCase extends BaseTestCase
 | 
					abstract class TestCase extends BaseTestCase
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -4,9 +4,6 @@ namespace Tests;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
use BookStack\Http\Request;
 | 
					use BookStack\Http\Request;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
use function request;
 | 
					 | 
				
			||||||
use function url;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
class UrlTest extends TestCase
 | 
					class UrlTest extends TestCase
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    public function test_url_helper_takes_custom_url_into_account()
 | 
					    public function test_url_helper_takes_custom_url_into_account()
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -6,7 +6,6 @@ use BookStack\Actions\ActivityType;
 | 
				
			||||||
use BookStack\Auth\Access\UserInviteService;
 | 
					use BookStack\Auth\Access\UserInviteService;
 | 
				
			||||||
use BookStack\Auth\Role;
 | 
					use BookStack\Auth\Role;
 | 
				
			||||||
use BookStack\Auth\User;
 | 
					use BookStack\Auth\User;
 | 
				
			||||||
use BookStack\Entities\Models\Page;
 | 
					 | 
				
			||||||
use Illuminate\Support\Facades\Hash;
 | 
					use Illuminate\Support\Facades\Hash;
 | 
				
			||||||
use Illuminate\Support\Str;
 | 
					use Illuminate\Support\Str;
 | 
				
			||||||
use Mockery\MockInterface;
 | 
					use Mockery\MockInterface;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -2,8 +2,6 @@
 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace Tests\User;
 | 
					namespace Tests\User;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
use BookStack\Entities\Models\Bookshelf;
 | 
					 | 
				
			||||||
use BookStack\Entities\Models\Page;
 | 
					 | 
				
			||||||
use Tests\TestCase;
 | 
					use Tests\TestCase;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class UserPreferencesTest extends TestCase
 | 
					class UserPreferencesTest extends TestCase
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in New Issue