From f14e6e8f2dbfac04829c1819398038ec99166d8f Mon Sep 17 00:00:00 2001 From: julesdevops Date: Wed, 20 Apr 2022 22:58:16 +0200 Subject: [PATCH] Complete list endpoint and add some tests --- app/Entities/Repos/DeletionRepo.php | 2 + .../Api/RecycleBinApiController.php | 46 ++++++++-- tests/Api/RecycleBinApiTest.php | 84 +++++++++++++++++-- 3 files changed, 116 insertions(+), 16 deletions(-) diff --git a/app/Entities/Repos/DeletionRepo.php b/app/Entities/Repos/DeletionRepo.php index 8fad4e6b0..5d53013dc 100644 --- a/app/Entities/Repos/DeletionRepo.php +++ b/app/Entities/Repos/DeletionRepo.php @@ -21,6 +21,7 @@ class DeletionRepo /** @var Deletion $deletion */ $deletion = Deletion::query()->findOrFail($id); Activity::add(ActivityType::RECYCLE_BIN_RESTORE, $deletion); + return $this->trashCan->restoreFromDeletion($deletion); } @@ -29,6 +30,7 @@ class DeletionRepo /** @var Deletion $deletion */ $deletion = Deletion::query()->findOrFail($id); Activity::add(ActivityType::RECYCLE_BIN_DESTROY, $deletion); + return $this->trashCan->destroyFromDeletion($deletion); } } diff --git a/app/Http/Controllers/Api/RecycleBinApiController.php b/app/Http/Controllers/Api/RecycleBinApiController.php index 162b27adb..f60115c16 100644 --- a/app/Http/Controllers/Api/RecycleBinApiController.php +++ b/app/Http/Controllers/Api/RecycleBinApiController.php @@ -2,10 +2,11 @@ namespace BookStack\Http\Controllers\Api; -use BookStack\Actions\ActivityType; +use BookStack\Entities\Models\Book; +use BookStack\Entities\Models\Chapter; use BookStack\Entities\Models\Deletion; use BookStack\Entities\Repos\DeletionRepo; -use BookStack\Entities\Tools\TrashCan; +use Closure; class RecycleBinApiController extends ApiController { @@ -22,24 +23,55 @@ class RecycleBinApiController extends ApiController public function list() { return $this->apiListingResponse(Deletion::query(), [ - 'id', - 'deleted_by', + 'id', + 'deleted_by', 'created_at', 'updated_at', 'deletable_type', - 'deletable_id' - ]); + 'deletable_id', + ], [Closure::fromCallable([$this, 'listFormatter'])]); } public function restore(DeletionRepo $deletionRepo, string $id) { $restoreCount = $deletionRepo->restore((int) $id); + return response()->json(['restore_count' => $restoreCount]); } public function destroy(DeletionRepo $deletionRepo, string $id) { $deleteCount = $deletionRepo->destroy((int) $id); + return response()->json(['delete_count' => $deleteCount]); } -} \ No newline at end of file + + protected function listFormatter(Deletion $deletion) + { + $deletable = $deletion->deletable; + $isBook = $deletable instanceof Book; + $parent = null; + $children = null; + + if ($isBook) { + $chapterCount = $deletable->chapters()->withTrashed()->count(); + $children['Bookstack\Chapter'] = $chapterCount; + } + + if ($isBook || $deletion->deletable instanceof Chapter) { + $pageCount = $deletable->pages()->withTrashed()->count(); + $children['Bookstack\Page'] = $pageCount; + } + + $parentEntity = $deletable->getParent(); + $parent = []; + + if ($parentEntity) { + $parent['type'] = $parentEntity->getMorphClass(); + $parent['id'] = $parentEntity->getKey(); + } + + $deletion->setAttribute('parent', $parent); + $deletion->setAttribute('children', $children); + } +} diff --git a/tests/Api/RecycleBinApiTest.php b/tests/Api/RecycleBinApiTest.php index 9371e06e8..286227896 100644 --- a/tests/Api/RecycleBinApiTest.php +++ b/tests/Api/RecycleBinApiTest.php @@ -3,12 +3,9 @@ namespace Tests\Api; use BookStack\Entities\Models\Book; -use BookStack\Entities\Models\Chapter; use BookStack\Entities\Models\Deletion; use BookStack\Entities\Models\Page; -use Carbon\Carbon; use Illuminate\Support\Collection; -use Illuminate\Support\Facades\DB; use Tests\TestCase; class RecycleBinApiTest extends TestCase @@ -52,7 +49,7 @@ class RecycleBinApiTest extends TestCase public function test_index_endpoint_returns_expected_page() { $this->actingAsAuthorizedUser(); - + $page = Page::query()->first(); $book = Book::query()->whereHas('pages')->whereHas('chapters')->withCount(['pages', 'chapters'])->first(); $editor = $this->getEditor(); @@ -72,13 +69,82 @@ class RecycleBinApiTest extends TestCase 'created_at' => $data[0]->created_at->toJson(), 'updated_at' => $data[0]->updated_at->toJson(), 'deletable_type' => $data[1]->getMorphClass(), - 'deletable_id' => $data[1]->getKey() + 'deletable_id' => $data[1]->getKey(), ]; }); $resp->assertJson([ 'data' => $expectedData->values()->all(), - 'total' => 2 + 'total' => 2, + ]); + } + + public function test_index_endpoint_returns_children() + { + $this->actingAsAuthorizedUser(); + + $book = Book::query()->whereHas('pages')->whereHas('chapters')->withCount(['pages', 'chapters'])->first(); + $editor = $this->getEditor(); + $this->actingAs($editor)->delete($book->getUrl()); + + $deletion = Deletion::query()->orderBy('id')->first(); + + $resp = $this->getJson($this->baseEndpoint); + + $expectedData = [ + [ + 'id' => $deletion->getKey(), + 'deleted_by' => $editor->getKey(), + 'created_at' => $deletion->created_at->toJson(), + 'updated_at' => $deletion->updated_at->toJson(), + 'deletable_type' => $book->getMorphClass(), + 'deletable_id' => $book->getKey(), + 'children' => [ + 'Bookstack\Page' => $book->pages_count, + 'Bookstack\Chapter' => $book->chapters_count, + ], + 'parent' => null, + ] + ]; + + $resp->assertJson([ + 'data' => $expectedData, + 'total' => 1, + ]); + } + + public function test_index_endpoint_returns_parent() + { + $this->actingAsAuthorizedUser(); + + $page = Page::query()->whereHas('chapter')->with('chapter')->first(); + + $editor = $this->getEditor(); + $this->actingAs($editor)->delete($page->getUrl()); + + $deletion = Deletion::query()->orderBy('id')->first(); + + $resp = $this->getJson($this->baseEndpoint); + + $expectedData = [ + [ + 'id' => $deletion->getKey(), + 'deleted_by' => $editor->getKey(), + 'created_at' => $deletion->created_at->toJson(), + 'updated_at' => $deletion->updated_at->toJson(), + 'deletable_type' => $page->getMorphClass(), + 'deletable_id' => $page->getKey(), + 'parent' => [ + 'type' => 'BookStack\Chapter', + 'id' => $page->chapter->getKey() + ], + 'children' => null, + ] + ]; + + $resp->assertJson([ + 'data' => $expectedData, + 'total' => 1 ]); } @@ -95,14 +161,14 @@ class RecycleBinApiTest extends TestCase $this->assertDatabaseHas('pages', [ 'id' => $page->getKey(), - 'deleted_at' => $page->deleted_at + 'deleted_at' => $page->deleted_at, ]); $this->putJson($this->baseEndpoint . '/' . $deletion->getKey()); $this->assertDatabaseHas('pages', [ 'id' => $page->getKey(), - 'deleted_at' => null + 'deleted_at' => null, ]); } @@ -119,7 +185,7 @@ class RecycleBinApiTest extends TestCase $this->assertDatabaseHas('pages', [ 'id' => $page->getKey(), - 'deleted_at' => $page->deleted_at + 'deleted_at' => $page->deleted_at, ]); $this->deleteJson($this->baseEndpoint . '/' . $deletion->getKey());