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
{
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);
+ }
+}
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
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();
'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
]);
}
$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,
]);
}
$this->assertDatabaseHas('pages', [
'id' => $page->getKey(),
- 'deleted_at' => $page->deleted_at
+ 'deleted_at' => $page->deleted_at,
]);
$this->deleteJson($this->baseEndpoint . '/' . $deletion->getKey());