3 use BookStack\Entities\Book;
4 use BookStack\Entities\Deletion;
5 use BookStack\Entities\Page;
7 class RecycleBinTest extends TestCase
9 public function test_recycle_bin_routes_permissions()
11 $page = Page::query()->first();
12 $editor = $this->getEditor();
13 $this->actingAs($editor)->delete($page->getUrl());
14 $deletion = Deletion::query()->firstOrFail();
17 'GET:/settings/recycle-bin',
18 'POST:/settings/recycle-bin/empty',
19 "GET:/settings/recycle-bin/{$deletion->id}/destroy",
20 "GET:/settings/recycle-bin/{$deletion->id}/restore",
21 "POST:/settings/recycle-bin/{$deletion->id}/restore",
22 "DELETE:/settings/recycle-bin/{$deletion->id}",
25 foreach($routes as $route) {
26 [$method, $url] = explode(':', $route);
27 $resp = $this->call($method, $url);
28 $this->assertPermissionError($resp);
31 $this->giveUserPermissions($editor, ['restrictions-manage-all']);
33 foreach($routes as $route) {
34 [$method, $url] = explode(':', $route);
35 $resp = $this->call($method, $url);
36 $this->assertPermissionError($resp);
39 $this->giveUserPermissions($editor, ['settings-manage']);
41 foreach($routes as $route) {
42 \DB::beginTransaction();
43 [$method, $url] = explode(':', $route);
44 $resp = $this->call($method, $url);
45 $this->assertNotPermissionError($resp);
51 public function test_recycle_bin_view()
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 $viewReq = $this->asAdmin()->get('/settings/recycle-bin');
60 $viewReq->assertElementContains('table.table', $page->name);
61 $viewReq->assertElementContains('table.table', $editor->name);
62 $viewReq->assertElementContains('table.table', $book->name);
63 $viewReq->assertElementContains('table.table', $book->pages_count . ' Pages');
64 $viewReq->assertElementContains('table.table', $book->chapters_count . ' Chapters');
67 public function test_recycle_bin_empty()
69 $page = Page::query()->first();
70 $book = Book::query()->where('id' , '!=', $page->book_id)->whereHas('pages')->whereHas('chapters')->with(['pages', 'chapters'])->firstOrFail();
71 $editor = $this->getEditor();
72 $this->actingAs($editor)->delete($page->getUrl());
73 $this->actingAs($editor)->delete($book->getUrl());
75 $this->assertTrue(Deletion::query()->count() === 2);
76 $emptyReq = $this->asAdmin()->post('/settings/recycle-bin/empty');
77 $emptyReq->assertRedirect('/settings/recycle-bin');
79 $this->assertTrue(Deletion::query()->count() === 0);
80 $this->assertDatabaseMissing('books', ['id' => $book->id]);
81 $this->assertDatabaseMissing('pages', ['id' => $page->id]);
82 $this->assertDatabaseMissing('pages', ['id' => $book->pages->first()->id]);
83 $this->assertDatabaseMissing('chapters', ['id' => $book->chapters->first()->id]);
85 $itemCount = 2 + $book->pages->count() + $book->chapters->count();
86 $redirectReq = $this->get('/settings/recycle-bin');
87 $redirectReq->assertNotificationContains('Deleted '.$itemCount.' total items from the recycle bin');
90 public function test_entity_restore()
92 $book = Book::query()->whereHas('pages')->whereHas('chapters')->with(['pages', 'chapters'])->firstOrFail();
93 $this->asEditor()->delete($book->getUrl());
94 $deletion = Deletion::query()->firstOrFail();
96 $this->assertEquals($book->pages->count(), \DB::table('pages')->where('book_id', '=', $book->id)->whereNotNull('deleted_at')->count());
97 $this->assertEquals($book->chapters->count(), \DB::table('chapters')->where('book_id', '=', $book->id)->whereNotNull('deleted_at')->count());
99 $restoreReq = $this->asAdmin()->post("/settings/recycle-bin/{$deletion->id}/restore");
100 $restoreReq->assertRedirect('/settings/recycle-bin');
101 $this->assertTrue(Deletion::query()->count() === 0);
103 $this->assertEquals($book->pages->count(), \DB::table('pages')->where('book_id', '=', $book->id)->whereNull('deleted_at')->count());
104 $this->assertEquals($book->chapters->count(), \DB::table('chapters')->where('book_id', '=', $book->id)->whereNull('deleted_at')->count());
106 $itemCount = 1 + $book->pages->count() + $book->chapters->count();
107 $redirectReq = $this->get('/settings/recycle-bin');
108 $redirectReq->assertNotificationContains('Restored '.$itemCount.' total items from the recycle bin');
111 public function test_permanent_delete()
113 $book = Book::query()->whereHas('pages')->whereHas('chapters')->with(['pages', 'chapters'])->firstOrFail();
114 $this->asEditor()->delete($book->getUrl());
115 $deletion = Deletion::query()->firstOrFail();
117 $deleteReq = $this->asAdmin()->delete("/settings/recycle-bin/{$deletion->id}");
118 $deleteReq->assertRedirect('/settings/recycle-bin');
119 $this->assertTrue(Deletion::query()->count() === 0);
121 $this->assertDatabaseMissing('books', ['id' => $book->id]);
122 $this->assertDatabaseMissing('pages', ['id' => $book->pages->first()->id]);
123 $this->assertDatabaseMissing('chapters', ['id' => $book->chapters->first()->id]);
125 $itemCount = 1 + $book->pages->count() + $book->chapters->count();
126 $redirectReq = $this->get('/settings/recycle-bin');
127 $redirectReq->assertNotificationContains('Deleted '.$itemCount.' total items from the recycle bin');
130 public function test_permanent_entity_delete_updates_existing_activity_with_entity_name()
132 $page = Page::query()->firstOrFail();
133 $this->asEditor()->delete($page->getUrl());
134 $deletion = $page->deletions()->firstOrFail();
136 $this->assertDatabaseHas('activities', [
137 'key' => 'page_delete',
138 'entity_id' => $page->id,
139 'entity_type' => $page->getMorphClass(),
142 $this->asAdmin()->delete("/settings/recycle-bin/{$deletion->id}");
144 $this->assertDatabaseMissing('activities', [
145 'key' => 'page_delete',
146 'entity_id' => $page->id,
147 'entity_type' => $page->getMorphClass(),
150 $this->assertDatabaseHas('activities', [
151 'key' => 'page_delete',
154 'extra' => $page->name,