]> BookStack Code Mirror - bookstack/blobdiff - tests/Activity/WatchTest.php
respective book and chapter structure added.
[bookstack] / tests / Activity / WatchTest.php
index fd86029d32c740f07d1ffac5298f681c3bba7e92..605b60fd498e26cf95d37daa06e95d1c7a6035e4 100644 (file)
@@ -2,9 +2,13 @@
 
 namespace Tests\Activity;
 
+use BookStack\Activity\ActivityType;
+use BookStack\Activity\Models\Comment;
+use BookStack\Activity\Notifications\Messages\BaseActivityNotification;
 use BookStack\Activity\Notifications\Messages\CommentCreationNotification;
 use BookStack\Activity\Notifications\Messages\PageCreationNotification;
 use BookStack\Activity\Notifications\Messages\PageUpdateNotification;
+use BookStack\Activity\Tools\ActivityLogger;
 use BookStack\Activity\Tools\UserEntityWatchOptions;
 use BookStack\Activity\WatchLevels;
 use BookStack\Entities\Models\Entity;
@@ -59,9 +63,8 @@ class WatchTest extends TestCase
         $editor = $this->users->editor();
         $book = $this->entities->book();
 
-        $this->actingAs($editor)->get($book->getUrl());
-        $resp = $this->put('/watching/update', [
-            'type' => get_class($book),
+        $resp = $this->actingAs($editor)->put('/watching/update', [
+            'type' => $book->getMorphClass(),
             'id' => $book->id,
             'level' => 'comments'
         ]);
@@ -76,7 +79,7 @@ class WatchTest extends TestCase
         ]);
 
         $resp = $this->put('/watching/update', [
-            'type' => get_class($book),
+            'type' => $book->getMorphClass(),
             'id' => $book->id,
             'level' => 'default'
         ]);
@@ -96,7 +99,7 @@ class WatchTest extends TestCase
         $book = $this->entities->book();
 
         $resp = $this->put('/watching/update', [
-            'type' => get_class($book),
+            'type' => $book->getMorphClass(),
             'id' => $book->id,
             'level' => 'comments'
         ]);
@@ -193,7 +196,7 @@ class WatchTest extends TestCase
         $notifications = Notification::fake();
 
         $this->asAdmin()->post("/comment/{$entities['page']->id}", [
-            'text' => 'My new comment'
+            'html' => '<p>My new comment</p>'
         ]);
         $notifications->assertSentTo($editor, CommentCreationNotification::class);
     }
@@ -205,16 +208,22 @@ class WatchTest extends TestCase
         $prefs = new UserNotificationPreferences($editor);
         $prefs->updateFromSettingsArray(['comment-replies' => 'true']);
 
+        // Create some existing comments to pad IDs to help potentially error
+        // on mis-identification of parent via ids used.
+        Comment::factory()->count(5)
+            ->for($entities['page'], 'entity')
+            ->create(['created_by' => $this->users->admin()->id]);
+
         $notifications = Notification::fake();
 
         $this->actingAs($editor)->post("/comment/{$entities['page']->id}", [
-            'text' => 'My new comment'
+            'html' => '<p>My new comment</p>'
         ]);
-        $comment = $entities['page']->comments()->first();
+        $comment = $entities['page']->comments()->orderBy('id', 'desc')->first();
 
         $this->asAdmin()->post("/comment/{$entities['page']->id}", [
-            'text' => 'My new comment response',
-            'parent_id' => $comment->id,
+            'html' => '<p>My new comment response</p>',
+            'parent_id' => $comment->local_id,
         ]);
         $notifications->assertSentTo($editor, CommentCreationNotification::class);
     }
@@ -248,15 +257,16 @@ class WatchTest extends TestCase
 
         // Comment post
         $this->actingAs($admin)->post("/comment/{$entities['page']->id}", [
-            'text' => 'My new comment response',
+            'html' => '<p>My new comment response</p>',
         ]);
 
         $notifications->assertSentTo($editor, function (CommentCreationNotification $notification) use ($editor, $admin, $entities) {
             $mail = $notification->toMail($editor);
-            $mailContent = html_entity_decode(strip_tags($mail->render()));
+            $mailContent = html_entity_decode(strip_tags($mail->render()), ENT_QUOTES);
             return $mail->subject === 'New comment on page: ' . $entities['page']->getShortName()
                 && str_contains($mailContent, 'View Comment')
                 && str_contains($mailContent, 'Page Name: ' . $entities['page']->name)
+                && str_contains($mailContent, 'Page Path: ' . $entities['book']->getShortName(24) . ' > ' . $entities['chapter']->getShortName(24))
                 && str_contains($mailContent, 'Commenter: ' . $admin->name)
                 && str_contains($mailContent, 'Comment: My new comment response');
         });
@@ -274,12 +284,13 @@ class WatchTest extends TestCase
         $this->actingAs($admin);
         $this->entities->updatePage($entities['page'], ['name' => 'Updated page', 'html' => 'new page content']);
 
-        $notifications->assertSentTo($editor, function (PageUpdateNotification $notification) use ($editor, $admin) {
+        $notifications->assertSentTo($editor, function (PageUpdateNotification $notification) use ($editor, $admin, $entities) {
             $mail = $notification->toMail($editor);
-            $mailContent = html_entity_decode(strip_tags($mail->render()));
+            $mailContent = html_entity_decode(strip_tags($mail->render()), ENT_QUOTES);
             return $mail->subject === 'Updated page: Updated page'
                 && str_contains($mailContent, 'View Page')
                 && str_contains($mailContent, 'Page Name: Updated page')
+                && str_contains($mailContent, 'Page Path: ' . $entities['book']->getShortName(24) . ' > ' . $entities['chapter']->getShortName(24))
                 && str_contains($mailContent, 'Updated By: ' . $admin->name)
                 && str_contains($mailContent, 'you won\'t be sent notifications for further edits to this page by the same editor');
         });
@@ -303,16 +314,57 @@ class WatchTest extends TestCase
         $page = $entities['chapter']->pages()->where('draft', '=', true)->first();
         $this->post($page->getUrl(), ['name' => 'My new page', 'html' => 'My new page content']);
 
-        $notifications->assertSentTo($editor, function (PageCreationNotification $notification) use ($editor, $admin) {
+        $notifications->assertSentTo($editor, function (PageCreationNotification $notification) use ($editor, $admin, $entities) {
             $mail = $notification->toMail($editor);
-            $mailContent = html_entity_decode(strip_tags($mail->render()));
+            $mailContent = html_entity_decode(strip_tags($mail->render()), ENT_QUOTES);
             return $mail->subject === 'New page: My new page'
                 && str_contains($mailContent, 'View Page')
                 && str_contains($mailContent, 'Page Name: My new page')
+                && str_contains($mailContent, 'Page Path: ' . $entities['book']->getShortName(24) . ' > ' . $entities['chapter']->getShortName(24))
                 && str_contains($mailContent, 'Created By: ' . $admin->name);
         });
     }
 
+    public function test_notifications_sent_in_right_language()
+    {
+        $editor = $this->users->editor();
+        $admin = $this->users->admin();
+        setting()->putUser($editor, 'language', 'de');
+        $entities = $this->entities->createChainBelongingToUser($editor);
+        $watches = new UserEntityWatchOptions($editor, $entities['book']);
+        $watches->updateLevelByValue(WatchLevels::COMMENTS);
+
+        $activities = [
+            ActivityType::PAGE_CREATE => $entities['page'],
+            ActivityType::PAGE_UPDATE => $entities['page'],
+            ActivityType::COMMENT_CREATE => Comment::factory()->make([
+                'entity_id' => $entities['page']->id,
+                'entity_type' => $entities['page']->getMorphClass(),
+            ]),
+        ];
+
+        $notifications = Notification::fake();
+        $logger = app()->make(ActivityLogger::class);
+        $this->actingAs($admin);
+
+        foreach ($activities as $activityType => $detail) {
+            $logger->add($activityType, $detail);
+        }
+
+        $sent = $notifications->sentNotifications()[get_class($editor)][$editor->id];
+        $this->assertCount(3, $sent);
+
+        foreach ($sent as $notificationInfo) {
+            $notification = $notificationInfo[0]['notification'];
+            $this->assertInstanceOf(BaseActivityNotification::class, $notification);
+            $mail = $notification->toMail($editor);
+            $mailContent = html_entity_decode(strip_tags($mail->render()), ENT_QUOTES);
+            $this->assertStringContainsString('Name der Seite:', $mailContent);
+            $this->assertStringContainsString('Diese Benachrichtigung wurde', $mailContent);
+            $this->assertStringContainsString('Sollte es beim Anklicken der Schaltfläche', $mailContent);
+        }
+    }
+
     public function test_notifications_not_sent_if_lacking_view_permission_for_related_item()
     {
         $notifications = Notification::fake();
@@ -324,9 +376,65 @@ class WatchTest extends TestCase
         $this->permissions->disableEntityInheritedPermissions($page);
 
         $this->asAdmin()->post("/comment/{$page->id}", [
-            'text' => 'My new comment response',
+            'html' => '<p>My new comment response</p>',
         ])->assertOk();
 
         $notifications->assertNothingSentTo($editor);
     }
+
+    public function test_watches_deleted_on_user_delete()
+    {
+        $editor = $this->users->editor();
+        $page = $this->entities->page();
+
+        $watches = new UserEntityWatchOptions($editor, $page);
+        $watches->updateLevelByValue(WatchLevels::COMMENTS);
+        $this->assertDatabaseHas('watches', ['user_id' => $editor->id]);
+
+        $this->asAdmin()->delete($editor->getEditUrl());
+
+        $this->assertDatabaseMissing('watches', ['user_id' => $editor->id]);
+    }
+
+    public function test_watches_deleted_on_item_delete()
+    {
+        $editor = $this->users->editor();
+        $page = $this->entities->page();
+
+        $watches = new UserEntityWatchOptions($editor, $page);
+        $watches->updateLevelByValue(WatchLevels::COMMENTS);
+        $this->assertDatabaseHas('watches', ['watchable_type' => 'page', 'watchable_id' => $page->id]);
+
+        $this->entities->destroy($page);
+
+        $this->assertDatabaseMissing('watches', ['watchable_type' => 'page', 'watchable_id' => $page->id]);
+    }
+
+    public function test_page_path_in_notifications_limited_by_permissions()
+    {
+        $chapter = $this->entities->chapterHasPages();
+        $page = $chapter->pages()->first();
+        $book = $chapter->book;
+        $notification = new PageCreationNotification($page, $this->users->editor());
+
+        $viewer = $this->users->viewer();
+        $viewerRole = $viewer->roles()->first();
+
+        $content = html_entity_decode(strip_tags($notification->toMail($viewer)->render()), ENT_QUOTES);
+        $this->assertStringContainsString('Page Path: ' . $book->getShortName(24) . ' > ' . $chapter->getShortName(24), $content);
+
+        $this->permissions->setEntityPermissions($page, ['view'], [$viewerRole]);
+        $this->permissions->setEntityPermissions($chapter, [], [$viewerRole]);
+
+        $content = html_entity_decode(strip_tags($notification->toMail($viewer)->render()), ENT_QUOTES);
+        $this->assertStringContainsString('Page Path: ' . $book->getShortName(24), $content);
+        $this->assertStringNotContainsString(' > ' . $chapter->getShortName(24), $content);
+
+        $this->permissions->setEntityPermissions($book, [], [$viewerRole]);
+
+        $content = html_entity_decode(strip_tags($notification->toMail($viewer)->render()), ENT_QUOTES);
+        $this->assertStringNotContainsString('Page Path:', $content);
+        $this->assertStringNotContainsString($book->getShortName(24), $content);
+        $this->assertStringNotContainsString($chapter->getShortName(24), $content);
+    }
 }