]> BookStack Code Mirror - bookstack/commitdiff
Complete list endpoint and add some tests
authorjulesdevops <redacted>
Wed, 20 Apr 2022 20:58:16 +0000 (22:58 +0200)
committerjulesdevops <redacted>
Thu, 21 Apr 2022 20:23:24 +0000 (22:23 +0200)
app/Entities/Repos/DeletionRepo.php
app/Http/Controllers/Api/RecycleBinApiController.php
tests/Api/RecycleBinApiTest.php

index 8fad4e6b0468740d354039e45e7e0abbba7dc835..5d53013dc33deb51fd748fe3f429fb6f0e59bb41 100644 (file)
@@ -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);
     }
 }
index 162b27adbc6abf9a82ce6446a3d578c1d35a33c1..f60115c167a5fe6b4b423cdae88be71659e2ed75 100644 (file)
@@ -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);
+    }
+}
index 9371e06e81841131a97001cdd34e605e7af1afb1..28622789642fbb9608c222339c318dcc8dcb0c3e 100644 (file)
@@ -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());