]> BookStack Code Mirror - bookstack/blob - tests/Api/RecycleBinApiTest.php
Start recycle bin API endpoints: list, restore, delete
[bookstack] / tests / Api / RecycleBinApiTest.php
1 <?php
2
3 namespace Tests\Api;
4
5 use BookStack\Entities\Models\Book;
6 use BookStack\Entities\Models\Chapter;
7 use BookStack\Entities\Models\Deletion;
8 use BookStack\Entities\Models\Page;
9 use Carbon\Carbon;
10 use Illuminate\Support\Collection;
11 use Illuminate\Support\Facades\DB;
12 use Tests\TestCase;
13
14 class RecycleBinApiTest extends TestCase
15 {
16     use TestsApi;
17
18     protected string $baseEndpoint = '/api/recycle_bin';
19
20     protected array $endpointMap = [
21         ['get', '/api/recycle_bin'],
22         ['put', '/api/recycle_bin/1'],
23         ['delete', '/api/recycle_bin/1'],
24     ];
25
26     public function test_settings_manage_permission_needed_for_all_endpoints()
27     {
28         $editor = $this->getEditor();
29         $this->giveUserPermissions($editor, ['settings-manage']);
30         $this->actingAs($editor);
31
32         foreach ($this->endpointMap as [$method, $uri]) {
33             $resp = $this->json($method, $uri);
34             $resp->assertStatus(403);
35             $resp->assertJson($this->permissionErrorResponse());
36         }
37     }
38
39     public function test_restrictions_manage_all_permission_neeed_for_all_endpoints()
40     {
41         $editor = $this->getEditor();
42         $this->giveUserPermissions($editor, ['restrictions-manage-all']);
43         $this->actingAs($editor);
44         
45         foreach ($this->endpointMap as [$method, $uri]) {
46             $resp = $this->json($method, $uri);
47             $resp->assertStatus(403);
48             $resp->assertJson($this->permissionErrorResponse());
49         }
50     }
51
52     public function test_index_endpoint_returns_expected_page()
53     {
54         $this->actingAsAuthorizedUser();
55         
56         $page = Page::query()->first();
57         $book = Book::query()->whereHas('pages')->whereHas('chapters')->withCount(['pages', 'chapters'])->first();
58         $editor = $this->getEditor();
59         $this->actingAs($editor)->delete($page->getUrl());
60         $this->actingAs($editor)->delete($book->getUrl());
61
62         $deletions = Deletion::query()->orderBy('id')->get();
63
64         $resp = $this->getJson($this->baseEndpoint);
65
66         $expectedData = $deletions
67             ->zip([$page, $book])
68             ->map(function (Collection $data) use ($editor) {
69                 return [
70                     'id'                => $data[0]->id,
71                     'deleted_by'        => $editor->getKey(),
72                     'created_at'        => $data[0]->created_at->toJson(),
73                     'updated_at'        => $data[0]->updated_at->toJson(),
74                     'deletable_type'    => $data[1]->getMorphClass(),
75                     'deletable_id'      => $data[1]->getKey()
76                 ];
77             });
78
79         $resp->assertJson([
80             'data' => $expectedData->values()->all(), 
81             'total' => 2
82         ]);
83     }
84
85     public function test_restore_endpoint()
86     {
87         $this->actingAsAuthorizedUser();
88         
89         $page = Page::query()->first();
90         $editor = $this->getEditor();
91         $this->actingAs($editor)->delete($page->getUrl());
92         $page->refresh();
93
94         $deletion = Deletion::query()->orderBy('id')->first();
95
96         $this->assertDatabaseHas('pages', [
97             'id' => $page->getKey(),
98             'deleted_at' => $page->deleted_at
99         ]);
100
101         $this->putJson($this->baseEndpoint . '/' . $deletion->getKey());
102
103         $this->assertDatabaseHas('pages', [
104             'id' => $page->getKey(),
105             'deleted_at' => null
106         ]);
107     }
108
109     public function test_destroy_endpoint()
110     {
111         $this->actingAsAuthorizedUser();
112         
113         $page = Page::query()->first();
114         $editor = $this->getEditor();
115         $this->actingAs($editor)->delete($page->getUrl());
116         $page->refresh();
117
118         $deletion = Deletion::query()->orderBy('id')->first();
119
120         $this->assertDatabaseHas('pages', [
121             'id' => $page->getKey(),
122             'deleted_at' => $page->deleted_at
123         ]);
124
125         $this->deleteJson($this->baseEndpoint . '/' . $deletion->getKey());
126         $this->assertDatabaseMissing('pages', ['id' => $page->getKey()]);
127     }
128
129     private function actingAsAuthorizedUser()
130     {
131         $editor = $this->getEditor();
132         $this->giveUserPermissions($editor, ['restrictions-manage-all']);
133         $this->giveUserPermissions($editor, ['settings-manage']);
134         $this->actingAs($editor);
135     }
136 }