5 use BookStack\Entities\Models\Book;
6 use BookStack\Entities\Models\Deletion;
7 use BookStack\Entities\Models\Page;
8 use Illuminate\Support\Collection;
11 class RecycleBinApiTest extends TestCase
15 protected string $baseEndpoint = '/api/recycle_bin';
17 protected array $endpointMap = [
18 ['get', '/api/recycle_bin'],
19 ['put', '/api/recycle_bin/1'],
20 ['delete', '/api/recycle_bin/1'],
23 public function test_settings_manage_permission_needed_for_all_endpoints()
25 $editor = $this->getEditor();
26 $this->giveUserPermissions($editor, ['settings-manage']);
27 $this->actingAs($editor);
29 foreach ($this->endpointMap as [$method, $uri]) {
30 $resp = $this->json($method, $uri);
31 $resp->assertStatus(403);
32 $resp->assertJson($this->permissionErrorResponse());
36 public function test_restrictions_manage_all_permission_needed_for_all_endpoints()
38 $editor = $this->getEditor();
39 $this->giveUserPermissions($editor, ['restrictions-manage-all']);
40 $this->actingAs($editor);
42 foreach ($this->endpointMap as [$method, $uri]) {
43 $resp = $this->json($method, $uri);
44 $resp->assertStatus(403);
45 $resp->assertJson($this->permissionErrorResponse());
49 public function test_index_endpoint_returns_expected_page()
51 $this->actingAsAuthorizedUser();
53 $page = Page::query()->first();
54 $book = Book::query()->whereHas('pages')->whereHas('chapters')->withCount(['pages', 'chapters'])->first();
55 $editor = $this->getEditor();
56 $this->actingAs($editor)->delete($page->getUrl());
57 $this->actingAs($editor)->delete($book->getUrl());
59 $deletions = Deletion::query()->orderBy('id')->get();
61 $resp = $this->getJson($this->baseEndpoint);
63 $expectedData = $deletions
65 ->map(function (Collection $data) use ($editor) {
68 'deleted_by' => $editor->getKey(),
69 'created_at' => $data[0]->created_at->toJson(),
70 'updated_at' => $data[0]->updated_at->toJson(),
71 'deletable_type' => $data[1]->getMorphClass(),
72 'deletable_id' => $data[1]->getKey(),
77 'data' => $expectedData->values()->all(),
82 public function test_index_endpoint_returns_children()
84 $this->actingAsAuthorizedUser();
86 $book = Book::query()->whereHas('pages')->whereHas('chapters')->withCount(['pages', 'chapters'])->first();
87 $editor = $this->getEditor();
88 $this->actingAs($editor)->delete($book->getUrl());
90 $deletion = Deletion::query()->orderBy('id')->first();
92 $resp = $this->getJson($this->baseEndpoint);
96 'id' => $deletion->getKey(),
97 'deleted_by' => $editor->getKey(),
98 'created_at' => $deletion->created_at->toJson(),
99 'updated_at' => $deletion->updated_at->toJson(),
100 'deletable_type' => $book->getMorphClass(),
101 'deletable_id' => $book->getKey(),
103 'BookStack\Page' => $book->pages_count,
104 'BookStack\Chapter' => $book->chapters_count,
111 'data' => $expectedData,
116 public function test_index_endpoint_returns_parent()
118 $this->actingAsAuthorizedUser();
120 $page = Page::query()->whereHas('chapter')->with('chapter')->first();
122 $editor = $this->getEditor();
123 $this->actingAs($editor)->delete($page->getUrl());
125 $deletion = Deletion::query()->orderBy('id')->first();
127 $resp = $this->getJson($this->baseEndpoint);
131 'id' => $deletion->getKey(),
132 'deleted_by' => $editor->getKey(),
133 'created_at' => $deletion->created_at->toJson(),
134 'updated_at' => $deletion->updated_at->toJson(),
135 'deletable_type' => $page->getMorphClass(),
136 'deletable_id' => $page->getKey(),
138 'type' => 'BookStack\Chapter',
139 'id' => $page->chapter->getKey(),
146 'data' => $expectedData,
151 public function test_restore_endpoint()
153 $this->actingAsAuthorizedUser();
155 $page = Page::query()->first();
156 $editor = $this->getEditor();
157 $this->actingAs($editor)->delete($page->getUrl());
160 $deletion = Deletion::query()->orderBy('id')->first();
162 $this->assertDatabaseHas('pages', [
163 'id' => $page->getKey(),
164 'deleted_at' => $page->deleted_at,
167 $this->putJson($this->baseEndpoint . '/' . $deletion->getKey());
169 $this->assertDatabaseHas('pages', [
170 'id' => $page->getKey(),
171 'deleted_at' => null,
175 public function test_destroy_endpoint()
177 $this->actingAsAuthorizedUser();
179 $page = Page::query()->first();
180 $editor = $this->getEditor();
181 $this->actingAs($editor)->delete($page->getUrl());
184 $deletion = Deletion::query()->orderBy('id')->first();
186 $this->assertDatabaseHas('pages', [
187 'id' => $page->getKey(),
188 'deleted_at' => $page->deleted_at,
191 $this->deleteJson($this->baseEndpoint . '/' . $deletion->getKey());
192 $this->assertDatabaseMissing('pages', ['id' => $page->getKey()]);
195 private function actingAsAuthorizedUser()
197 $editor = $this->getEditor();
198 $this->giveUserPermissions($editor, ['restrictions-manage-all']);
199 $this->giveUserPermissions($editor, ['settings-manage']);
200 $this->actingAs($editor);