From: Dan Brown Date: Fri, 18 Dec 2020 14:16:13 +0000 (+0000) Subject: Merge branch 'v0.30.x' X-Git-Tag: v0.31.0~3^2~20 X-Git-Url: http://source.bookstackapp.com/bookstack/commitdiff_plain/cf04a0d818b7c973ad20a7a49308629c738ca73d?hp=2acef3c2ecfae924204b7d0cef05d0a7916d81af Merge branch 'v0.30.x' --- diff --git a/.env.example.complete b/.env.example.complete index 45b1e1321..19643a49f 100644 --- a/.env.example.complete +++ b/.env.example.complete @@ -255,6 +255,14 @@ APP_VIEWS_BOOKSHELVES=grid # If set to 'false' a limit will not be enforced. REVISION_LIMIT=50 +# Recycle Bin Lifetime +# The number of days that content will remain in the recycle bin before +# being considered for auto-removal. It is not a guarantee that content will +# be removed after this time. +# Set to 0 for no recycle bin functionality. +# Set to -1 for unlimited recycle bin lifetime. +RECYCLE_BIN_LIFETIME=30 + # Allow

Hello

"; + $page->save(); + + $resp = $this->getJson($this->baseEndpoint . "/{$page->id}"); + $html = $resp->json('html'); + $this->assertStringNotContainsString('script', $html); + $this->assertStringContainsString('Hello', $html); + $this->assertStringContainsString('testing', $html); + } + + public function test_update_endpoint() + { + $this->actingAsApiEditor(); + $page = Page::visible()->first(); + $details = [ + 'name' => 'My updated API page', + 'html' => '

A page created via the API

', + 'tags' => [ + [ + 'name' => 'freshtag', + 'value' => 'freshtagval', + ] + ], + ]; + + $resp = $this->putJson($this->baseEndpoint . "/{$page->id}", $details); + $page->refresh(); + + $resp->assertStatus(200); + unset($details['html']); + $resp->assertJson(array_merge($details, [ + 'id' => $page->id, 'slug' => $page->slug, 'book_id' => $page->book_id + ])); + $this->assertActivityExists('page_update', $page); + } + + public function test_providing_new_chapter_id_on_update_will_move_page() + { + $this->actingAsApiEditor(); + $page = Page::visible()->first(); + $chapter = Chapter::visible()->where('book_id', '!=', $page->book_id)->first(); + $details = [ + 'name' => 'My updated API page', + 'chapter_id' => $chapter->id, + 'html' => '

A page created via the API

', + ]; + + $resp = $this->putJson($this->baseEndpoint . "/{$page->id}", $details); + $resp->assertStatus(200); + $resp->assertJson([ + 'chapter_id' => $chapter->id, + 'book_id' => $chapter->book_id, + ]); + } + + public function test_providing_move_via_update_requires_page_create_permission_on_new_parent() + { + $this->actingAsApiEditor(); + $page = Page::visible()->first(); + $chapter = Chapter::visible()->where('book_id', '!=', $page->book_id)->first(); + $this->setEntityRestrictions($chapter, ['view'], [$this->getEditor()->roles()->first()]); + $details = [ + 'name' => 'My updated API page', + 'chapter_id' => $chapter->id, + 'html' => '

A page created via the API

', + ]; + + $resp = $this->putJson($this->baseEndpoint . "/{$page->id}", $details); + $resp->assertStatus(403); + } + + public function test_delete_endpoint() + { + $this->actingAsApiEditor(); + $page = Page::visible()->first(); + $resp = $this->deleteJson($this->baseEndpoint . "/{$page->id}"); + + $resp->assertStatus(204); + $this->assertActivityExists('page_delete', $page); + } + + public function test_export_html_endpoint() + { + $this->actingAsApiEditor(); + $page = Page::visible()->first(); + + $resp = $this->get($this->baseEndpoint . "/{$page->id}/export/html"); + $resp->assertStatus(200); + $resp->assertSee($page->name); + $resp->assertHeader('Content-Disposition', 'attachment; filename="' . $page->slug . '.html"'); + } + + public function test_export_plain_text_endpoint() + { + $this->actingAsApiEditor(); + $page = Page::visible()->first(); + + $resp = $this->get($this->baseEndpoint . "/{$page->id}/export/plaintext"); + $resp->assertStatus(200); + $resp->assertSee($page->name); + $resp->assertHeader('Content-Disposition', 'attachment; filename="' . $page->slug . '.txt"'); + } + + public function test_export_pdf_endpoint() + { + $this->actingAsApiEditor(); + $page = Page::visible()->first(); + + $resp = $this->get($this->baseEndpoint . "/{$page->id}/export/pdf"); + $resp->assertStatus(200); + $resp->assertHeader('Content-Disposition', 'attachment; filename="' . $page->slug . '.pdf"'); + } +} \ No newline at end of file diff --git a/tests/Api/ShelvesApiTest.php b/tests/Api/ShelvesApiTest.php index 13e44d97d..4c5600d15 100644 --- a/tests/Api/ShelvesApiTest.php +++ b/tests/Api/ShelvesApiTest.php @@ -1,7 +1,7 @@ activityService = app(ActivityService::class); + } public function test_only_accessible_with_right_permissions() { @@ -33,14 +43,14 @@ class AuditLogTest extends TestCase $admin = $this->getAdmin(); $this->actingAs($admin); $page = Page::query()->first(); - app(ActivityService::class)->add($page, 'page_create', $page->book->id); + $this->activityService->addForEntity($page, ActivityType::PAGE_CREATE); $activity = Activity::query()->orderBy('id', 'desc')->first(); $resp = $this->get('settings/audit'); $resp->assertSeeText($page->name); $resp->assertSeeText('page_create'); $resp->assertSeeText($activity->created_at->toDateTimeString()); - $resp->assertElementContains('.audit-log-user', $admin->name); + $resp->assertElementContains('.table-user-item', $admin->name); } public function test_shows_name_for_deleted_items() @@ -48,9 +58,10 @@ class AuditLogTest extends TestCase $this->actingAs( $this->getAdmin()); $page = Page::query()->first(); $pageName = $page->name; - app(ActivityService::class)->add($page, 'page_create', $page->book->id); + $this->activityService->addForEntity($page, ActivityType::PAGE_CREATE); app(PageRepo::class)->destroy($page); + app(TrashCan::class)->empty(); $resp = $this->get('settings/audit'); $resp->assertSeeText('Deleted Item'); @@ -62,7 +73,7 @@ class AuditLogTest extends TestCase $viewer = $this->getViewer(); $this->actingAs($viewer); $page = Page::query()->first(); - app(ActivityService::class)->add($page, 'page_create', $page->book->id); + $this->activityService->addForEntity($page, ActivityType::PAGE_CREATE); $this->actingAs($this->getAdmin()); app(UserRepo::class)->destroy($viewer); @@ -75,7 +86,7 @@ class AuditLogTest extends TestCase { $this->actingAs($this->getAdmin()); $page = Page::query()->first(); - app(ActivityService::class)->add($page, 'page_create', $page->book->id); + $this->activityService->addForEntity($page, ActivityType::PAGE_CREATE); $resp = $this->get('settings/audit'); $resp->assertSeeText($page->name); @@ -88,7 +99,7 @@ class AuditLogTest extends TestCase { $this->actingAs($this->getAdmin()); $page = Page::query()->first(); - app(ActivityService::class)->add($page, 'page_create', $page->book->id); + $this->activityService->addForEntity($page, ActivityType::PAGE_CREATE); $yesterday = (Carbon::now()->subDay()->format('Y-m-d')); $tomorrow = (Carbon::now()->addDay()->format('Y-m-d')); diff --git a/tests/Auth/AuthTest.php b/tests/Auth/AuthTest.php index e2b1e0cd6..a0de7f803 100644 --- a/tests/Auth/AuthTest.php +++ b/tests/Auth/AuthTest.php @@ -2,7 +2,7 @@ use BookStack\Auth\Role; use BookStack\Auth\User; -use BookStack\Entities\Page; +use BookStack\Entities\Models\Page; use BookStack\Notifications\ConfirmEmail; use BookStack\Notifications\ResetPassword; use BookStack\Settings\SettingService; diff --git a/tests/BrowserKitTest.php b/tests/BrowserKitTest.php index b81afe311..bb5aaa031 100644 --- a/tests/BrowserKitTest.php +++ b/tests/BrowserKitTest.php @@ -1,6 +1,6 @@ create(['created_by' => $creatorUser->id, 'updated_by' => $updaterUser->id]); - $chapter = factory(\BookStack\Entities\Chapter::class)->create(['created_by' => $creatorUser->id, 'updated_by' => $updaterUser->id, 'book_id' => $book->id]); - $page = factory(\BookStack\Entities\Page::class)->create(['created_by' => $creatorUser->id, 'updated_by' => $updaterUser->id, 'book_id' => $book->id, 'chapter_id' => $chapter->id]); + $book = factory(\BookStack\Entities\Models\Book::class)->create(['created_by' => $creatorUser->id, 'updated_by' => $updaterUser->id]); + $chapter = factory(\BookStack\Entities\Models\Chapter::class)->create(['created_by' => $creatorUser->id, 'updated_by' => $updaterUser->id, 'book_id' => $book->id]); + $page = factory(\BookStack\Entities\Models\Page::class)->create(['created_by' => $creatorUser->id, 'updated_by' => $updaterUser->id, 'book_id' => $book->id, 'chapter_id' => $chapter->id]); $restrictionService = $this->app[PermissionService::class]; $restrictionService->buildJointPermissionsForEntity($book); return [ diff --git a/tests/CommandsTest.php b/tests/CommandsTest.php index bfc0ac0eb..8c6ea84bf 100644 --- a/tests/CommandsTest.php +++ b/tests/CommandsTest.php @@ -1,10 +1,11 @@ asEditor(); $page = Page::first(); - \Activity::add($page, 'page_update', $page->book->id); + \Activity::addForEntity($page, ActivityType::PAGE_UPDATE); $this->assertDatabaseHas('activities', [ - 'key' => 'page_update', + 'type' => 'page_update', 'entity_id' => $page->id, 'user_id' => $this->getEditor()->id ]); @@ -50,7 +51,7 @@ class CommandsTest extends TestCase $this->assertDatabaseMissing('activities', [ - 'key' => 'page_update' + 'type' => 'page_update' ]); } diff --git a/tests/Entity/BookShelfTest.php b/tests/Entity/BookShelfTest.php index cb3acfb1e..9b3290370 100644 --- a/tests/Entity/BookShelfTest.php +++ b/tests/Entity/BookShelfTest.php @@ -1,8 +1,8 @@ asEditor()->get($shelf->getUrl('/delete')); - $resp->assertSeeText('Delete Bookshelf'); - $resp->assertSee("action=\"{$shelf->getUrl()}\""); - - $resp = $this->delete($shelf->getUrl()); - $resp->assertRedirect('/shelves'); - $this->assertDatabaseMissing('bookshelves', ['id' => $shelf->id]); - $this->assertDatabaseMissing('bookshelves_books', ['bookshelf_id' => $shelf->id]); - $this->assertSessionHas('success'); + $shelf = Bookshelf::query()->whereHas('books')->first(); + $this->assertNull($shelf->deleted_at); + $bookCount = $shelf->books()->count(); + + $deleteViewReq = $this->asEditor()->get($shelf->getUrl('/delete')); + $deleteViewReq->assertSeeText('Are you sure you want to delete this bookshelf?'); + + $deleteReq = $this->delete($shelf->getUrl()); + $deleteReq->assertRedirect(url('/shelves')); + $this->assertActivityExists('bookshelf_delete', $shelf); + + $shelf->refresh(); + $this->assertNotNull($shelf->deleted_at); + + $this->assertTrue($shelf->books()->count() === $bookCount); + $this->assertTrue($shelf->deletions()->count() === 1); + + $redirectReq = $this->get($deleteReq->baseResponse->headers->get('location')); + $redirectReq->assertNotificationContains('Bookshelf Successfully Deleted'); } public function test_shelf_copy_permissions() diff --git a/tests/Entity/BookTest.php b/tests/Entity/BookTest.php new file mode 100644 index 000000000..6c2cf30d4 --- /dev/null +++ b/tests/Entity/BookTest.php @@ -0,0 +1,34 @@ +whereHas('pages')->whereHas('chapters')->first(); + $this->assertNull($book->deleted_at); + $pageCount = $book->pages()->count(); + $chapterCount = $book->chapters()->count(); + + $deleteViewReq = $this->asEditor()->get($book->getUrl('/delete')); + $deleteViewReq->assertSeeText('Are you sure you want to delete this book?'); + + $deleteReq = $this->delete($book->getUrl()); + $deleteReq->assertRedirect(url('/books')); + $this->assertActivityExists('book_delete', $book); + + $book->refresh(); + $this->assertNotNull($book->deleted_at); + + $this->assertTrue($book->pages()->count() === 0); + $this->assertTrue($book->chapters()->count() === 0); + $this->assertTrue($book->pages()->withTrashed()->count() === $pageCount); + $this->assertTrue($book->chapters()->withTrashed()->count() === $chapterCount); + $this->assertTrue($book->deletions()->count() === 1); + + $redirectReq = $this->get($deleteReq->baseResponse->headers->get('location')); + $redirectReq->assertNotificationContains('Book Successfully Deleted'); + } +} \ No newline at end of file diff --git a/tests/Entity/ChapterTest.php b/tests/Entity/ChapterTest.php new file mode 100644 index 000000000..e9350a32b --- /dev/null +++ b/tests/Entity/ChapterTest.php @@ -0,0 +1,31 @@ +whereHas('pages')->first(); + $this->assertNull($chapter->deleted_at); + $pageCount = $chapter->pages()->count(); + + $deleteViewReq = $this->asEditor()->get($chapter->getUrl('/delete')); + $deleteViewReq->assertSeeText('Are you sure you want to delete this chapter?'); + + $deleteReq = $this->delete($chapter->getUrl()); + $deleteReq->assertRedirect($chapter->getParent()->getUrl()); + $this->assertActivityExists('chapter_delete', $chapter); + + $chapter->refresh(); + $this->assertNotNull($chapter->deleted_at); + + $this->assertTrue($chapter->pages()->count() === 0); + $this->assertTrue($chapter->pages()->withTrashed()->count() === $pageCount); + $this->assertTrue($chapter->deletions()->count() === 1); + + $redirectReq = $this->get($deleteReq->baseResponse->headers->get('location')); + $redirectReq->assertNotificationContains('Chapter Successfully Deleted'); + } +} \ No newline at end of file diff --git a/tests/Entity/CommentSettingTest.php b/tests/Entity/CommentSettingTest.php index 3c8cae68c..49ceede9f 100644 --- a/tests/Entity/CommentSettingTest.php +++ b/tests/Entity/CommentSettingTest.php @@ -1,6 +1,6 @@ bookCreation(); $chapter = $this->chapterCreation($book); - $page = $this->pageCreation($chapter); + $this->pageCreation($chapter); // Test Updating - $book = $this->bookUpdate($book); - - // Test Deletion - $this->bookDelete($book); - } - - public function bookDelete(Book $book) - { - $this->asAdmin() - ->visit($book->getUrl()) - // Check link works correctly - ->click('Delete') - ->seePageIs($book->getUrl() . '/delete') - // Ensure the book name is show to user - ->see($book->name) - ->press('Confirm') - ->seePageIs('/books') - ->notSeeInDatabase('books', ['id' => $book->id]); + $this->bookUpdate($book); } public function bookUpdate(Book $book) @@ -332,34 +314,4 @@ class EntityTest extends BrowserKitTest ->seePageIs($chapter->getUrl()); } - public function test_page_delete_removes_entity_from_its_activity() - { - $page = Page::query()->first(); - - $this->asEditor()->put($page->getUrl(), [ - 'name' => 'My updated page', - 'html' => '

updated content

', - ]); - $page->refresh(); - - $this->seeInDatabase('activities', [ - 'entity_id' => $page->id, - 'entity_type' => $page->getMorphClass(), - ]); - - $resp = $this->delete($page->getUrl()); - $resp->assertResponseStatus(302); - - $this->dontSeeInDatabase('activities', [ - 'entity_id' => $page->id, - 'entity_type' => $page->getMorphClass(), - ]); - - $this->seeInDatabase('activities', [ - 'extra' => 'My updated page', - 'entity_id' => 0, - 'entity_type' => '', - ]); - } - } diff --git a/tests/Entity/ExportTest.php b/tests/Entity/ExportTest.php index b1e6eb5fb..1e44f015a 100644 --- a/tests/Entity/ExportTest.php +++ b/tests/Entity/ExportTest.php @@ -1,7 +1,8 @@ assertSee(''; + $page->save(); + + $resp = $this->asEditor()->get($page->getUrl('/export/html')); + Storage::disk('local')->delete('uploads/images/gallery/svg_test.svg'); + Storage::disk('local')->delete('uploads/images/gallery/svg_test2.svg'); + + $resp->assertDontSee('http://localhost/uploads/images/gallery/svg_test'); + } + public function test_page_export_contained_html_image_fetches_only_run_when_url_points_to_image_upload_folder() { $page = Page::first(); $page->html = '' - ."\n".'' - ."\n".''; + .'' + .''; $storageDisk = Storage::disk('local'); $storageDisk->makeDirectory('uploads/images/gallery'); $storageDisk->put('uploads/images/gallery/svg_test.svg', 'good'); @@ -188,4 +205,4 @@ class ExportTest extends TestCase $resp->assertSee('src="/uploads/svg_test.svg"'); } -} \ No newline at end of file +} diff --git a/tests/Entity/MarkdownTest.php b/tests/Entity/MarkdownTest.php index 452b4c07f..5e5fa8a0c 100644 --- a/tests/Entity/MarkdownTest.php +++ b/tests/Entity/MarkdownTest.php @@ -9,7 +9,7 @@ class MarkdownTest extends BrowserKitTest public function setUp(): void { parent::setUp(); - $this->page = \BookStack\Entities\Page::first(); + $this->page = \BookStack\Entities\Models\Page::first(); } protected function setMarkdownEditor() diff --git a/tests/Entity/PageContentTest.php b/tests/Entity/PageContentTest.php index e97df2c7e..51a8568bf 100644 --- a/tests/Entity/PageContentTest.php +++ b/tests/Entity/PageContentTest.php @@ -1,7 +1,7 @@ page = \BookStack\Entities\Page::first(); + $this->page = \BookStack\Entities\Models\Page::first(); $this->pageRepo = app(PageRepo::class); } @@ -56,7 +56,7 @@ class PageDraftTest extends BrowserKitTest public function test_alert_message_shows_if_someone_else_editing() { - $nonEditedPage = \BookStack\Entities\Page::take(10)->get()->last(); + $nonEditedPage = \BookStack\Entities\Models\Page::take(10)->get()->last(); $addedContent = '

test message content

'; $this->asAdmin()->visit($this->page->getUrl('/edit')) ->dontSeeInField('html', $addedContent); @@ -75,7 +75,7 @@ class PageDraftTest extends BrowserKitTest public function test_draft_pages_show_on_homepage() { - $book = \BookStack\Entities\Book::first(); + $book = \BookStack\Entities\Models\Book::first(); $this->asAdmin()->visit('/') ->dontSeeInElement('#recent-drafts', 'New Page') ->visit($book->getUrl() . '/create-page') @@ -85,7 +85,7 @@ class PageDraftTest extends BrowserKitTest public function test_draft_pages_not_visible_by_others() { - $book = \BookStack\Entities\Book::first(); + $book = \BookStack\Entities\Models\Book::first(); $chapter = $book->chapters->first(); $newUser = $this->getEditor(); diff --git a/tests/Entity/PageRevisionTest.php b/tests/Entity/PageRevisionTest.php index 1e9dbd626..6eaea129c 100644 --- a/tests/Entity/PageRevisionTest.php +++ b/tests/Entity/PageRevisionTest.php @@ -1,6 +1,6 @@ first(); + $this->assertNull($page->deleted_at); + + $deleteViewReq = $this->asEditor()->get($page->getUrl('/delete')); + $deleteViewReq->assertSeeText('Are you sure you want to delete this page?'); + + $deleteReq = $this->delete($page->getUrl()); + $deleteReq->assertRedirect($page->getParent()->getUrl()); + $this->assertActivityExists('page_delete', $page); + + $page->refresh(); + $this->assertNotNull($page->deleted_at); + $this->assertTrue($page->deletions()->count() === 1); + + $redirectReq = $this->get($deleteReq->baseResponse->headers->get('location')); + $redirectReq->assertNotificationContains('Page Successfully Deleted'); + } +} \ No newline at end of file diff --git a/tests/Entity/SearchOptionsTest.php b/tests/Entity/SearchOptionsTest.php index 727db5533..c9e116523 100644 --- a/tests/Entity/SearchOptionsTest.php +++ b/tests/Entity/SearchOptionsTest.php @@ -1,6 +1,6 @@ actingAs($this->getEditor())->put($page->getUrl('/move'), [ 'entity_selection' => 'book:' . $newBook->id ]); - $page = Page::find($page->id); + $page->refresh(); $movePageResp->assertRedirect($page->getUrl()); $this->assertTrue($page->book->id == $newBook->id, 'Page parent is now the new book'); diff --git a/tests/Entity/TagTest.php b/tests/Entity/TagTest.php index e8a99cf78..3ad10641e 100644 --- a/tests/Entity/TagTest.php +++ b/tests/Entity/TagTest.php @@ -1,10 +1,10 @@ actingAs($this->user) ->visit($shelf->getUrl('/edit')) diff --git a/tests/Permissions/RolesTest.php b/tests/Permissions/RolesTest.php index 73060c834..9f32a9f49 100644 --- a/tests/Permissions/RolesTest.php +++ b/tests/Permissions/RolesTest.php @@ -1,8 +1,13 @@ id; $this->asAdmin()->visit($deletePageUrl) ->press('Confirm') @@ -195,7 +200,7 @@ class RolesTest extends BrowserKitTest public function test_restrictions_manage_all_permission() { - $page = \BookStack\Entities\Page::take(1)->get()->first(); + $page = Page::take(1)->get()->first(); $this->actingAs($this->user)->visit($page->getUrl()) ->dontSee('Permissions') ->visit($page->getUrl() . '/permissions') @@ -209,7 +214,7 @@ class RolesTest extends BrowserKitTest public function test_restrictions_manage_own_permission() { - $otherUsersPage = \BookStack\Entities\Page::first(); + $otherUsersPage = Page::first(); $content = $this->createEntityChainBelongingToUser($this->user); // Check can't restrict other's content $this->actingAs($this->user)->visit($otherUsersPage->getUrl()) @@ -301,7 +306,7 @@ class RolesTest extends BrowserKitTest public function test_bookshelves_edit_all_permission() { - $otherShelf = \BookStack\Entities\Bookshelf::first(); + $otherShelf = Bookshelf::first(); $this->checkAccessPermission('bookshelf-update-all', [ $otherShelf->getUrl('/edit') ], [ @@ -312,7 +317,7 @@ class RolesTest extends BrowserKitTest public function test_bookshelves_delete_own_permission() { $this->giveUserPermissions($this->user, ['bookshelf-update-all']); - $otherShelf = \BookStack\Entities\Bookshelf::first(); + $otherShelf = Bookshelf::first(); $ownShelf = $this->newShelf(['name' => 'test-shelf', 'slug' => 'test-shelf']); $ownShelf->forceFill(['created_by' => $this->user->id, 'updated_by' => $this->user->id])->save(); $this->regenEntityPermissions($ownShelf); @@ -336,7 +341,7 @@ class RolesTest extends BrowserKitTest public function test_bookshelves_delete_all_permission() { $this->giveUserPermissions($this->user, ['bookshelf-update-all']); - $otherShelf = \BookStack\Entities\Bookshelf::first(); + $otherShelf = Bookshelf::first(); $this->checkAccessPermission('bookshelf-delete-all', [ $otherShelf->getUrl('/delete') ], [ @@ -366,7 +371,7 @@ class RolesTest extends BrowserKitTest public function test_books_edit_own_permission() { - $otherBook = \BookStack\Entities\Book::take(1)->get()->first(); + $otherBook = Book::take(1)->get()->first(); $ownBook = $this->createEntityChainBelongingToUser($this->user)['book']; $this->checkAccessPermission('book-update-own', [ $ownBook->getUrl() . '/edit' @@ -382,7 +387,7 @@ class RolesTest extends BrowserKitTest public function test_books_edit_all_permission() { - $otherBook = \BookStack\Entities\Book::take(1)->get()->first(); + $otherBook = Book::take(1)->get()->first(); $this->checkAccessPermission('book-update-all', [ $otherBook->getUrl() . '/edit' ], [ @@ -393,7 +398,7 @@ class RolesTest extends BrowserKitTest public function test_books_delete_own_permission() { $this->giveUserPermissions($this->user, ['book-update-all']); - $otherBook = \BookStack\Entities\Book::take(1)->get()->first(); + $otherBook = Book::take(1)->get()->first(); $ownBook = $this->createEntityChainBelongingToUser($this->user)['book']; $this->checkAccessPermission('book-delete-own', [ $ownBook->getUrl() . '/delete' @@ -414,7 +419,7 @@ class RolesTest extends BrowserKitTest public function test_books_delete_all_permission() { $this->giveUserPermissions($this->user, ['book-update-all']); - $otherBook = \BookStack\Entities\Book::take(1)->get()->first(); + $otherBook = Book::take(1)->get()->first(); $this->checkAccessPermission('book-delete-all', [ $otherBook->getUrl() . '/delete' ], [ @@ -429,7 +434,7 @@ class RolesTest extends BrowserKitTest public function test_chapter_create_own_permissions() { - $book = \BookStack\Entities\Book::take(1)->get()->first(); + $book = Book::take(1)->get()->first(); $ownBook = $this->createEntityChainBelongingToUser($this->user)['book']; $this->checkAccessPermission('chapter-create-own', [ $ownBook->getUrl('/create-chapter') @@ -451,7 +456,7 @@ class RolesTest extends BrowserKitTest public function test_chapter_create_all_permissions() { - $book = \BookStack\Entities\Book::take(1)->get()->first(); + $book = Book::take(1)->get()->first(); $this->checkAccessPermission('chapter-create-all', [ $book->getUrl('/create-chapter') ], [ @@ -467,7 +472,7 @@ class RolesTest extends BrowserKitTest public function test_chapter_edit_own_permission() { - $otherChapter = \BookStack\Entities\Chapter::take(1)->get()->first(); + $otherChapter = Chapter::take(1)->get()->first(); $ownChapter = $this->createEntityChainBelongingToUser($this->user)['chapter']; $this->checkAccessPermission('chapter-update-own', [ $ownChapter->getUrl() . '/edit' @@ -483,7 +488,7 @@ class RolesTest extends BrowserKitTest public function test_chapter_edit_all_permission() { - $otherChapter = \BookStack\Entities\Chapter::take(1)->get()->first(); + $otherChapter = Chapter::take(1)->get()->first(); $this->checkAccessPermission('chapter-update-all', [ $otherChapter->getUrl() . '/edit' ], [ @@ -494,7 +499,7 @@ class RolesTest extends BrowserKitTest public function test_chapter_delete_own_permission() { $this->giveUserPermissions($this->user, ['chapter-update-all']); - $otherChapter = \BookStack\Entities\Chapter::take(1)->get()->first(); + $otherChapter = Chapter::take(1)->get()->first(); $ownChapter = $this->createEntityChainBelongingToUser($this->user)['chapter']; $this->checkAccessPermission('chapter-delete-own', [ $ownChapter->getUrl() . '/delete' @@ -516,7 +521,7 @@ class RolesTest extends BrowserKitTest public function test_chapter_delete_all_permission() { $this->giveUserPermissions($this->user, ['chapter-update-all']); - $otherChapter = \BookStack\Entities\Chapter::take(1)->get()->first(); + $otherChapter = Chapter::take(1)->get()->first(); $this->checkAccessPermission('chapter-delete-all', [ $otherChapter->getUrl() . '/delete' ], [ @@ -532,8 +537,8 @@ class RolesTest extends BrowserKitTest public function test_page_create_own_permissions() { - $book = \BookStack\Entities\Book::first(); - $chapter = \BookStack\Entities\Chapter::first(); + $book = Book::first(); + $chapter = Chapter::first(); $entities = $this->createEntityChainBelongingToUser($this->user); $ownBook = $entities['book']; @@ -557,7 +562,7 @@ class RolesTest extends BrowserKitTest foreach ($accessUrls as $index => $url) { $this->actingAs($this->user)->visit($url); - $expectedUrl = \BookStack\Entities\Page::where('draft', '=', true)->orderBy('id', 'desc')->first()->getUrl(); + $expectedUrl = Page::where('draft', '=', true)->orderBy('id', 'desc')->first()->getUrl(); $this->seePageIs($expectedUrl); } @@ -579,8 +584,8 @@ class RolesTest extends BrowserKitTest public function test_page_create_all_permissions() { - $book = \BookStack\Entities\Book::take(1)->get()->first(); - $chapter = \BookStack\Entities\Chapter::take(1)->get()->first(); + $book = Book::take(1)->get()->first(); + $chapter = Chapter::take(1)->get()->first(); $baseUrl = $book->getUrl() . '/page'; $createUrl = $book->getUrl('/create-page'); @@ -601,7 +606,7 @@ class RolesTest extends BrowserKitTest foreach ($accessUrls as $index => $url) { $this->actingAs($this->user)->visit($url); - $expectedUrl = \BookStack\Entities\Page::where('draft', '=', true)->orderBy('id', 'desc')->first()->getUrl(); + $expectedUrl = Page::where('draft', '=', true)->orderBy('id', 'desc')->first()->getUrl(); $this->seePageIs($expectedUrl); } @@ -620,7 +625,7 @@ class RolesTest extends BrowserKitTest public function test_page_edit_own_permission() { - $otherPage = \BookStack\Entities\Page::take(1)->get()->first(); + $otherPage = Page::take(1)->get()->first(); $ownPage = $this->createEntityChainBelongingToUser($this->user)['page']; $this->checkAccessPermission('page-update-own', [ $ownPage->getUrl() . '/edit' @@ -636,7 +641,7 @@ class RolesTest extends BrowserKitTest public function test_page_edit_all_permission() { - $otherPage = \BookStack\Entities\Page::take(1)->get()->first(); + $otherPage = Page::take(1)->get()->first(); $this->checkAccessPermission('page-update-all', [ $otherPage->getUrl() . '/edit' ], [ @@ -647,7 +652,7 @@ class RolesTest extends BrowserKitTest public function test_page_delete_own_permission() { $this->giveUserPermissions($this->user, ['page-update-all']); - $otherPage = \BookStack\Entities\Page::take(1)->get()->first(); + $otherPage = Page::take(1)->get()->first(); $ownPage = $this->createEntityChainBelongingToUser($this->user)['page']; $this->checkAccessPermission('page-delete-own', [ $ownPage->getUrl() . '/delete' @@ -669,7 +674,7 @@ class RolesTest extends BrowserKitTest public function test_page_delete_all_permission() { $this->giveUserPermissions($this->user, ['page-update-all']); - $otherPage = \BookStack\Entities\Page::take(1)->get()->first(); + $otherPage = Page::take(1)->get()->first(); $this->checkAccessPermission('page-delete-all', [ $otherPage->getUrl() . '/delete' ], [ @@ -685,7 +690,7 @@ class RolesTest extends BrowserKitTest public function test_public_role_visible_in_user_edit_screen() { - $user = \BookStack\Auth\User::first(); + $user = User::first(); $adminRole = Role::getSystemRole('admin'); $publicRole = Role::getSystemRole('public'); $this->asAdmin()->visit('/settings/users/' . $user->id) @@ -721,8 +726,8 @@ class RolesTest extends BrowserKitTest public function test_image_delete_own_permission() { $this->giveUserPermissions($this->user, ['image-update-all']); - $page = \BookStack\Entities\Page::first(); - $image = factory(\BookStack\Uploads\Image::class)->create(['uploaded_to' => $page->id, 'created_by' => $this->user->id, 'updated_by' => $this->user->id]); + $page = Page::first(); + $image = factory(Image::class)->create(['uploaded_to' => $page->id, 'created_by' => $this->user->id, 'updated_by' => $this->user->id]); $this->actingAs($this->user)->json('delete', '/images/' . $image->id) ->seeStatusCode(403); @@ -738,8 +743,8 @@ class RolesTest extends BrowserKitTest { $this->giveUserPermissions($this->user, ['image-update-all']); $admin = $this->getAdmin(); - $page = \BookStack\Entities\Page::first(); - $image = factory(\BookStack\Uploads\Image::class)->create(['uploaded_to' => $page->id, 'created_by' => $admin->id, 'updated_by' => $admin->id]); + $page = Page::first(); + $image = factory(Image::class)->create(['uploaded_to' => $page->id, 'created_by' => $admin->id, 'updated_by' => $admin->id]); $this->actingAs($this->user)->json('delete', '/images/' . $image->id) ->seeStatusCode(403); @@ -760,7 +765,7 @@ class RolesTest extends BrowserKitTest { // To cover issue fixed in f99c8ff99aee9beb8c692f36d4b84dc6e651e50a. $page = Page::first(); - $viewerRole = \BookStack\Auth\Role::getRole('viewer'); + $viewerRole = Role::getRole('viewer'); $viewer = $this->getViewer(); $this->actingAs($viewer)->visit($page->getUrl())->assertResponseStatus(200); @@ -778,14 +783,14 @@ class RolesTest extends BrowserKitTest { $admin = $this->getAdmin(); // Book links - $book = factory(\BookStack\Entities\Book::class)->create(['created_by' => $admin->id, 'updated_by' => $admin->id]); + $book = factory(Book::class)->create(['created_by' => $admin->id, 'updated_by' => $admin->id]); $this->updateEntityPermissions($book); $this->actingAs($this->getViewer())->visit($book->getUrl()) ->dontSee('Create a new page') ->dontSee('Add a chapter'); // Chapter links - $chapter = factory(\BookStack\Entities\Chapter::class)->create(['created_by' => $admin->id, 'updated_by' => $admin->id, 'book_id' => $book->id]); + $chapter = factory(Chapter::class)->create(['created_by' => $admin->id, 'updated_by' => $admin->id, 'book_id' => $book->id]); $this->updateEntityPermissions($chapter); $this->actingAs($this->getViewer())->visit($chapter->getUrl()) ->dontSee('Create a new page') @@ -869,7 +874,7 @@ class RolesTest extends BrowserKitTest } private function addComment($page) { - $comment = factory(\BookStack\Actions\Comment::class)->make(); + $comment = factory(Comment::class)->make(); $url = "/comment/$page->id"; $request = [ 'text' => $comment->text, @@ -882,7 +887,7 @@ class RolesTest extends BrowserKitTest } private function updateComment($commentId) { - $comment = factory(\BookStack\Actions\Comment::class)->make(); + $comment = factory(Comment::class)->make(); $url = "/comment/$commentId"; $request = [ 'text' => $comment->text, diff --git a/tests/PublicActionTest.php b/tests/PublicActionTest.php index 3670df87d..194190124 100644 --- a/tests/PublicActionTest.php +++ b/tests/PublicActionTest.php @@ -5,9 +5,9 @@ use BookStack\Auth\Permissions\PermissionService; use BookStack\Auth\Permissions\RolePermission; use BookStack\Auth\Role; use BookStack\Auth\User; -use BookStack\Entities\Book; -use BookStack\Entities\Chapter; -use BookStack\Entities\Page; +use BookStack\Entities\Models\Book; +use BookStack\Entities\Models\Chapter; +use BookStack\Entities\Models\Page; class PublicActionTest extends BrowserKitTest { diff --git a/tests/RecycleBinTest.php b/tests/RecycleBinTest.php new file mode 100644 index 000000000..60f06cfc4 --- /dev/null +++ b/tests/RecycleBinTest.php @@ -0,0 +1,232 @@ +first(); + $editor = $this->getEditor(); + $this->actingAs($editor)->delete($page->getUrl()); + $deletion = Deletion::query()->firstOrFail(); + + $routes = [ + 'GET:/settings/recycle-bin', + 'POST:/settings/recycle-bin/empty', + "GET:/settings/recycle-bin/{$deletion->id}/destroy", + "GET:/settings/recycle-bin/{$deletion->id}/restore", + "POST:/settings/recycle-bin/{$deletion->id}/restore", + "DELETE:/settings/recycle-bin/{$deletion->id}", + ]; + + foreach($routes as $route) { + [$method, $url] = explode(':', $route); + $resp = $this->call($method, $url); + $this->assertPermissionError($resp); + } + + $this->giveUserPermissions($editor, ['restrictions-manage-all']); + + foreach($routes as $route) { + [$method, $url] = explode(':', $route); + $resp = $this->call($method, $url); + $this->assertPermissionError($resp); + } + + $this->giveUserPermissions($editor, ['settings-manage']); + + foreach($routes as $route) { + DB::beginTransaction(); + [$method, $url] = explode(':', $route); + $resp = $this->call($method, $url); + $this->assertNotPermissionError($resp); + DB::rollBack(); + } + + } + + public function test_recycle_bin_view() + { + $page = Page::query()->first(); + $book = Book::query()->whereHas('pages')->whereHas('chapters')->withCount(['pages', 'chapters'])->first(); + $editor = $this->getEditor(); + $this->actingAs($editor)->delete($page->getUrl()); + $this->actingAs($editor)->delete($book->getUrl()); + + $viewReq = $this->asAdmin()->get('/settings/recycle-bin'); + $viewReq->assertElementContains('table.table', $page->name); + $viewReq->assertElementContains('table.table', $editor->name); + $viewReq->assertElementContains('table.table', $book->name); + $viewReq->assertElementContains('table.table', $book->pages_count . ' Pages'); + $viewReq->assertElementContains('table.table', $book->chapters_count . ' Chapters'); + } + + public function test_recycle_bin_empty() + { + $page = Page::query()->first(); + $book = Book::query()->where('id' , '!=', $page->book_id)->whereHas('pages')->whereHas('chapters')->with(['pages', 'chapters'])->firstOrFail(); + $editor = $this->getEditor(); + $this->actingAs($editor)->delete($page->getUrl()); + $this->actingAs($editor)->delete($book->getUrl()); + + $this->assertTrue(Deletion::query()->count() === 2); + $emptyReq = $this->asAdmin()->post('/settings/recycle-bin/empty'); + $emptyReq->assertRedirect('/settings/recycle-bin'); + + $this->assertTrue(Deletion::query()->count() === 0); + $this->assertDatabaseMissing('books', ['id' => $book->id]); + $this->assertDatabaseMissing('pages', ['id' => $page->id]); + $this->assertDatabaseMissing('pages', ['id' => $book->pages->first()->id]); + $this->assertDatabaseMissing('chapters', ['id' => $book->chapters->first()->id]); + + $itemCount = 2 + $book->pages->count() + $book->chapters->count(); + $redirectReq = $this->get('/settings/recycle-bin'); + $redirectReq->assertNotificationContains('Deleted '.$itemCount.' total items from the recycle bin'); + } + + public function test_entity_restore() + { + $book = Book::query()->whereHas('pages')->whereHas('chapters')->with(['pages', 'chapters'])->firstOrFail(); + $this->asEditor()->delete($book->getUrl()); + $deletion = Deletion::query()->firstOrFail(); + + $this->assertEquals($book->pages->count(), DB::table('pages')->where('book_id', '=', $book->id)->whereNotNull('deleted_at')->count()); + $this->assertEquals($book->chapters->count(), DB::table('chapters')->where('book_id', '=', $book->id)->whereNotNull('deleted_at')->count()); + + $restoreReq = $this->asAdmin()->post("/settings/recycle-bin/{$deletion->id}/restore"); + $restoreReq->assertRedirect('/settings/recycle-bin'); + $this->assertTrue(Deletion::query()->count() === 0); + + $this->assertEquals($book->pages->count(), DB::table('pages')->where('book_id', '=', $book->id)->whereNull('deleted_at')->count()); + $this->assertEquals($book->chapters->count(), DB::table('chapters')->where('book_id', '=', $book->id)->whereNull('deleted_at')->count()); + + $itemCount = 1 + $book->pages->count() + $book->chapters->count(); + $redirectReq = $this->get('/settings/recycle-bin'); + $redirectReq->assertNotificationContains('Restored '.$itemCount.' total items from the recycle bin'); + } + + public function test_permanent_delete() + { + $book = Book::query()->whereHas('pages')->whereHas('chapters')->with(['pages', 'chapters'])->firstOrFail(); + $this->asEditor()->delete($book->getUrl()); + $deletion = Deletion::query()->firstOrFail(); + + $deleteReq = $this->asAdmin()->delete("/settings/recycle-bin/{$deletion->id}"); + $deleteReq->assertRedirect('/settings/recycle-bin'); + $this->assertTrue(Deletion::query()->count() === 0); + + $this->assertDatabaseMissing('books', ['id' => $book->id]); + $this->assertDatabaseMissing('pages', ['id' => $book->pages->first()->id]); + $this->assertDatabaseMissing('chapters', ['id' => $book->chapters->first()->id]); + + $itemCount = 1 + $book->pages->count() + $book->chapters->count(); + $redirectReq = $this->get('/settings/recycle-bin'); + $redirectReq->assertNotificationContains('Deleted '.$itemCount.' total items from the recycle bin'); + } + + public function test_permanent_entity_delete_updates_existing_activity_with_entity_name() + { + $page = Page::query()->firstOrFail(); + $this->asEditor()->delete($page->getUrl()); + $deletion = $page->deletions()->firstOrFail(); + + $this->assertDatabaseHas('activities', [ + 'type' => 'page_delete', + 'entity_id' => $page->id, + 'entity_type' => $page->getMorphClass(), + ]); + + $this->asAdmin()->delete("/settings/recycle-bin/{$deletion->id}"); + + $this->assertDatabaseMissing('activities', [ + 'type' => 'page_delete', + 'entity_id' => $page->id, + 'entity_type' => $page->getMorphClass(), + ]); + + $this->assertDatabaseHas('activities', [ + 'type' => 'page_delete', + 'entity_id' => null, + 'entity_type' => null, + 'detail' => $page->name, + ]); + } + + public function test_auto_clear_functionality_works() + { + config()->set('app.recycle_bin_lifetime', 5); + $page = Page::query()->firstOrFail(); + $otherPage = Page::query()->where('id', '!=', $page->id)->firstOrFail(); + + $this->asEditor()->delete($page->getUrl()); + $this->assertDatabaseHas('pages', ['id' => $page->id]); + $this->assertEquals(1, Deletion::query()->count()); + + Carbon::setTestNow(Carbon::now()->addDays(6)); + $this->asEditor()->delete($otherPage->getUrl()); + $this->assertEquals(1, Deletion::query()->count()); + + $this->assertDatabaseMissing('pages', ['id' => $page->id]); + } + + public function test_auto_clear_functionality_with_negative_time_keeps_forever() + { + config()->set('app.recycle_bin_lifetime', -1); + $page = Page::query()->firstOrFail(); + $otherPage = Page::query()->where('id', '!=', $page->id)->firstOrFail(); + + $this->asEditor()->delete($page->getUrl()); + $this->assertEquals(1, Deletion::query()->count()); + + Carbon::setTestNow(Carbon::now()->addDays(6000)); + $this->asEditor()->delete($otherPage->getUrl()); + $this->assertEquals(2, Deletion::query()->count()); + + $this->assertDatabaseHas('pages', ['id' => $page->id]); + } + + public function test_auto_clear_functionality_with_zero_time_deletes_instantly() + { + config()->set('app.recycle_bin_lifetime', 0); + $page = Page::query()->firstOrFail(); + + $this->asEditor()->delete($page->getUrl()); + $this->assertDatabaseMissing('pages', ['id' => $page->id]); + $this->assertEquals(0, Deletion::query()->count()); + } + + public function test_restore_flow_when_restoring_nested_delete_first() + { + $book = Book::query()->whereHas('pages')->whereHas('chapters')->with(['pages', 'chapters'])->firstOrFail(); + $chapter = $book->chapters->first(); + $this->asEditor()->delete($chapter->getUrl()); + $this->asEditor()->delete($book->getUrl()); + + $bookDeletion = $book->deletions()->first(); + $chapterDeletion = $chapter->deletions()->first(); + + $chapterRestoreView = $this->asAdmin()->get("/settings/recycle-bin/{$chapterDeletion->id}/restore"); + $chapterRestoreView->assertStatus(200); + $chapterRestoreView->assertSeeText($chapter->name); + + $chapterRestore = $this->post("/settings/recycle-bin/{$chapterDeletion->id}/restore"); + $chapterRestore->assertRedirect("/settings/recycle-bin"); + $this->assertDatabaseMissing("deletions", ["id" => $chapterDeletion->id]); + + $chapter->refresh(); + $this->assertNotNull($chapter->deleted_at); + + $bookRestoreView = $this->asAdmin()->get("/settings/recycle-bin/{$bookDeletion->id}/restore"); + $bookRestoreView->assertStatus(200); + $bookRestoreView->assertSeeText($chapter->name); + + $this->post("/settings/recycle-bin/{$bookDeletion->id}/restore"); + $chapter->refresh(); + $this->assertNull($chapter->deleted_at); + } +} \ No newline at end of file diff --git a/tests/SharedTestHelpers.php b/tests/SharedTestHelpers.php index c7659a02d..ffcc6f40c 100644 --- a/tests/SharedTestHelpers.php +++ b/tests/SharedTestHelpers.php @@ -1,11 +1,11 @@ response); - } + PHPUnit::assertTrue($this->isPermissionError($response->baseResponse ?? $response->response), "Failed asserting the response contains a permission error."); + } - $response->assertRedirect('/'); - $this->assertSessionHas('error'); - $error = session()->pull('error'); - $this->assertStringStartsWith('You do not have permission to access', $error); + /** + * Assert a permission error has occurred. + */ + protected function assertNotPermissionError($response) + { + PHPUnit::assertFalse($this->isPermissionError($response->baseResponse ?? $response->response), "Failed asserting the response does not contain a permission error."); + } + + /** + * Check if the given response is a permission error. + */ + private function isPermissionError($response): bool + { + return $response->status() === 302 + && $response->headers->get('Location') === url('/') + && strpos(session()->pull('error', ''), 'You do not have permission to access') === 0; } /** diff --git a/tests/TestCase.php b/tests/TestCase.php index 1f1d5ece7..2c901981a 100644 --- a/tests/TestCase.php +++ b/tests/TestCase.php @@ -1,6 +1,6 @@ $key]; + $detailsToCheck = ['type' => $type]; if ($entity) { $detailsToCheck['entity_type'] = $entity->getMorphClass(); diff --git a/tests/TestResponse.php b/tests/TestResponse.php index a68a5783f..9c6b78782 100644 --- a/tests/TestResponse.php +++ b/tests/TestResponse.php @@ -15,9 +15,8 @@ class TestResponse extends BaseTestResponse { /** * Get the DOM Crawler for the response content. - * @return Crawler */ - protected function crawler() + protected function crawler(): Crawler { if (!is_object($this->crawlerInstance)) { $this->crawlerInstance = new Crawler($this->getContent()); @@ -27,7 +26,6 @@ class TestResponse extends BaseTestResponse { /** * Assert the response contains the specified element. - * @param string $selector * @return $this */ public function assertElementExists(string $selector) @@ -45,7 +43,6 @@ class TestResponse extends BaseTestResponse { /** * Assert the response does not contain the specified element. - * @param string $selector * @return $this */ public function assertElementNotExists(string $selector) @@ -63,8 +60,6 @@ class TestResponse extends BaseTestResponse { /** * Assert the response includes a specific element containing the given text. - * @param string $selector - * @param string $text * @return $this */ public function assertElementContains(string $selector, string $text) @@ -95,8 +90,6 @@ class TestResponse extends BaseTestResponse { /** * Assert the response does not include a specific element containing the given text. - * @param string $selector - * @param string $text * @return $this */ public function assertElementNotContains(string $selector, string $text) @@ -125,12 +118,20 @@ class TestResponse extends BaseTestResponse { return $this; } + /** + * Assert there's a notification within the view containing the given text. + * @return $this + */ + public function assertNotificationContains(string $text) + { + return $this->assertElementContains('[notification]', $text); + } + /** * Get the escaped text pattern for the constraint. - * @param string $text * @return string */ - protected function getEscapedPattern($text) + protected function getEscapedPattern(string $text) { $rawPattern = preg_quote($text, '/'); $escapedPattern = preg_quote(e($text), '/'); diff --git a/tests/Uploads/AttachmentTest.php b/tests/Uploads/AttachmentTest.php index 5838b019e..1ca9ea23b 100644 --- a/tests/Uploads/AttachmentTest.php +++ b/tests/Uploads/AttachmentTest.php @@ -1,7 +1,9 @@ $fileName ]); - $this->call('DELETE', $page->getUrl()); + app(PageRepo::class)->destroy($page); + app(TrashCan::class)->empty(); $this->assertDatabaseMissing('attachments', [ 'name' => $fileName diff --git a/tests/Uploads/DrawioTest.php b/tests/Uploads/DrawioTest.php index 3fc009c8a..d134135aa 100644 --- a/tests/Uploads/DrawioTest.php +++ b/tests/Uploads/DrawioTest.php @@ -1,6 +1,6 @@ assertTrue(strlen($secret) === 32); $this->assertSessionHas('success'); + $this->assertActivityExists(ActivityType::API_TOKEN_CREATE); } public function test_create_with_no_expiry_sets_expiry_hundred_years_away() @@ -124,6 +126,7 @@ class UserApiTokenTest extends TestCase $this->assertDatabaseHas('api_tokens', array_merge($updateData, ['id' => $token->id])); $this->assertSessionHas('success'); + $this->assertActivityExists(ActivityType::API_TOKEN_UPDATE); } public function test_token_update_with_blank_expiry_sets_to_hundred_years_away() @@ -162,6 +165,7 @@ class UserApiTokenTest extends TestCase $resp = $this->delete($tokenUrl); $resp->assertRedirect($editor->getEditUrl('#api_tokens')); $this->assertDatabaseMissing('api_tokens', ['id' => $token->id]); + $this->assertActivityExists(ActivityType::API_TOKEN_DELETE); } public function test_user_manage_can_delete_token_without_api_permission_themselves() diff --git a/tests/User/UserPreferencesTest.php b/tests/User/UserPreferencesTest.php index 0db4f803a..7ffc8f9db 100644 --- a/tests/User/UserPreferencesTest.php +++ b/tests/User/UserPreferencesTest.php @@ -1,4 +1,4 @@ -getNewBlankUser(); $this->actingAs($newUser); $entities = $this->createEntityChainBelongingToUser($newUser, $newUser); - Activity::add($entities['book'], 'book_update', $entities['book']->id); - Activity::add($entities['page'], 'page_create', $entities['book']->id); + Activity::addForEntity($entities['book'], ActivityType::BOOK_UPDATE); + Activity::addForEntity($entities['page'], ActivityType::PAGE_CREATE); $this->asAdmin()->visit('/user/' . $newUser->id) ->seeInElement('#recent-user-activity', 'updated book') @@ -74,8 +75,8 @@ class UserProfileTest extends BrowserKitTest $newUser = $this->getNewBlankUser(); $this->actingAs($newUser); $entities = $this->createEntityChainBelongingToUser($newUser, $newUser); - Activity::add($entities['book'], 'book_update', $entities['book']->id); - Activity::add($entities['page'], 'page_create', $entities['book']->id); + Activity::addForEntity($entities['book'], ActivityType::BOOK_UPDATE); + Activity::addForEntity($entities['page'], ActivityType::PAGE_CREATE); $this->asAdmin()->visit('/')->clickInElement('#recent-activity', $newUser->name) ->seePageIs('/user/' . $newUser->id)