]> BookStack Code Mirror - bookstack/commitdiff
Notifications: Added testing to cover controls
authorDan Brown <redacted>
Tue, 15 Aug 2023 19:08:27 +0000 (20:08 +0100)
committerDan Brown <redacted>
Tue, 15 Aug 2023 19:08:27 +0000 (20:08 +0100)
app/Activity/Controllers/WatchController.php
database/seeders/DummyContentSeeder.php
tests/Activity/WatchTest.php [new file with mode: 0644]
tests/User/UserPreferencesTest.php

index e0596864cd195e0cfa6bdf5d0e6424b7ede6f7ff..e2e27ca4afe7eede3b30fdfb8e40d4355eba8aad 100644 (file)
@@ -15,6 +15,7 @@ class WatchController extends Controller
 {
     public function update(Request $request)
     {
+        // TODO - Require notification permission
         $requestData = $this->validate($request, [
             'level' => ['required', 'string'],
         ]);
index 0f030d671fad8e61c138e6c3846eda9052b8c6a6..f0d3ffcdb40871ba5aa3df36a23d4d8e79422b02 100644 (file)
@@ -27,6 +27,8 @@ class DummyContentSeeder extends Seeder
         // Create an editor user
         $editorUser = User::factory()->create();
         $editorRole = Role::getRole('editor');
+        $additionalEditorPerms = ['receive-notifications'];
+        $editorRole->permissions()->syncWithoutDetaching(RolePermission::whereIn('name', $additionalEditorPerms)->pluck('id'));
         $editorUser->attachRole($editorRole);
 
         // Create a viewer user
diff --git a/tests/Activity/WatchTest.php b/tests/Activity/WatchTest.php
new file mode 100644 (file)
index 0000000..919e526
--- /dev/null
@@ -0,0 +1,152 @@
+<?php
+
+namespace Tests\Activity;
+
+use BookStack\Activity\Tools\UserEntityWatchOptions;
+use BookStack\Activity\WatchLevels;
+use BookStack\Entities\Models\Entity;
+use Tests\TestCase;
+
+class WatchTest extends TestCase
+{
+    public function test_watch_action_exists_on_entity_unless_active()
+    {
+        $editor = $this->users->editor();
+        $this->actingAs($editor);
+
+        $entities = [$this->entities->book(), $this->entities->chapter(), $this->entities->page()];
+        /** @var Entity $entity */
+        foreach ($entities as $entity) {
+            $resp = $this->get($entity->getUrl());
+            $this->withHtml($resp)->assertElementContains('form[action$="/watching/update"] button.icon-list-item', 'Watch');
+
+            $watchOptions = new UserEntityWatchOptions($editor, $entity);
+            $watchOptions->updateWatchLevel('comments');
+
+            $resp = $this->get($entity->getUrl());
+            $this->withHtml($resp)->assertElementNotExists('form[action$="/watching/update"] button.icon-list-item');
+        }
+    }
+
+    public function test_watch_action_only_shows_with_permission()
+    {
+        $viewer = $this->users->viewer();
+        $this->actingAs($viewer);
+
+        $entities = [$this->entities->book(), $this->entities->chapter(), $this->entities->page()];
+        /** @var Entity $entity */
+        foreach ($entities as $entity) {
+            $resp = $this->get($entity->getUrl());
+            $this->withHtml($resp)->assertElementNotExists('form[action$="/watching/update"] button.icon-list-item');
+        }
+
+        $this->permissions->grantUserRolePermissions($viewer, ['receive-notifications']);
+
+        /** @var Entity $entity */
+        foreach ($entities as $entity) {
+            $resp = $this->get($entity->getUrl());
+            $this->withHtml($resp)->assertElementExists('form[action$="/watching/update"] button.icon-list-item');
+        }
+    }
+
+    public function test_watch_update()
+    {
+        $editor = $this->users->editor();
+        $book = $this->entities->book();
+
+        $this->actingAs($editor)->get($book->getUrl());
+        $resp = $this->put('/watching/update', [
+            'type' => get_class($book),
+            'id' => $book->id,
+            'level' => 'comments'
+        ]);
+
+        $resp->assertRedirect($book->getUrl());
+        $this->assertSessionHas('success');
+        $this->assertDatabaseHas('watches', [
+            'watchable_id' => $book->id,
+            'watchable_type' => $book->getMorphClass(),
+            'user_id' => $editor->id,
+            'level' => WatchLevels::COMMENTS,
+        ]);
+
+        $resp = $this->put('/watching/update', [
+            'type' => get_class($book),
+            'id' => $book->id,
+            'level' => 'default'
+        ]);
+        $resp->assertRedirect($book->getUrl());
+        $this->assertDatabaseMissing('watches', [
+            'watchable_id' => $book->id,
+            'watchable_type' => $book->getMorphClass(),
+            'user_id' => $editor->id,
+        ]);
+    }
+
+    public function test_watch_detail_display_reflects_state()
+    {
+        $editor = $this->users->editor();
+        $book = $this->entities->bookHasChaptersAndPages();
+        $chapter = $book->chapters()->first();
+        $page = $chapter->pages()->first();
+
+        (new UserEntityWatchOptions($editor, $book))->updateWatchLevel('updates');
+
+        $this->actingAs($editor)->get($book->getUrl())->assertSee('Watching new pages and updates');
+        $this->get($chapter->getUrl())->assertSee('Watching via parent book');
+        $this->get($page->getUrl())->assertSee('Watching via parent book');
+
+        (new UserEntityWatchOptions($editor, $chapter))->updateWatchLevel('comments');
+        $this->get($chapter->getUrl())->assertSee('Watching new pages, updates & comments');
+        $this->get($page->getUrl())->assertSee('Watching via parent chapter');
+
+        (new UserEntityWatchOptions($editor, $page))->updateWatchLevel('updates');
+        $this->get($page->getUrl())->assertSee('Watching new pages and updates');
+    }
+
+    public function test_watch_detail_ignore_indicator_cascades()
+    {
+        $editor = $this->users->editor();
+        $book = $this->entities->bookHasChaptersAndPages();
+        (new UserEntityWatchOptions($editor, $book))->updateWatchLevel('ignore');
+
+        $this->actingAs($editor)->get($book->getUrl())->assertSee('Ignoring notifications');
+        $this->get($book->chapters()->first()->getUrl())->assertSee('Ignoring via parent book');
+        $this->get($book->pages()->first()->getUrl())->assertSee('Ignoring via parent book');
+    }
+
+    public function test_watch_option_menu_shows_current_active_state()
+    {
+        $editor = $this->users->editor();
+        $book = $this->entities->book();
+        $options = new UserEntityWatchOptions($editor, $book);
+
+        $respHtml = $this->withHtml($this->actingAs($editor)->get($book->getUrl()));
+        $respHtml->assertElementNotExists('form[action$="/watching/update"] svg[data-icon="check-circle"]');
+
+        $options->updateWatchLevel('comments');
+        $respHtml = $this->withHtml($this->actingAs($editor)->get($book->getUrl()));
+        $respHtml->assertElementExists('form[action$="/watching/update"] button[value="comments"] svg[data-icon="check-circle"]');
+
+        $options->updateWatchLevel('ignore');
+        $respHtml = $this->withHtml($this->actingAs($editor)->get($book->getUrl()));
+        $respHtml->assertElementExists('form[action$="/watching/update"] button[value="ignore"] svg[data-icon="check-circle"]');
+    }
+
+    public function test_watch_option_menu_limits_options_for_pages()
+    {
+        $editor = $this->users->editor();
+        $book = $this->entities->bookHasChaptersAndPages();
+        (new UserEntityWatchOptions($editor, $book))->updateWatchLevel('ignore');
+
+        $respHtml = $this->withHtml($this->actingAs($editor)->get($book->getUrl()));
+        $respHtml->assertElementExists('form[action$="/watching/update"] button[name="level"][value="new"]');
+
+        $respHtml = $this->withHtml($this->get($book->pages()->first()->getUrl()));
+        $respHtml->assertElementExists('form[action$="/watching/update"] button[name="level"][value="updates"]');
+        $respHtml->assertElementNotExists('form[action$="/watching/update"] button[name="level"][value="new"]');
+    }
+
+    // TODO - Guest user cannot see/set notifications
+    // TODO - Actual notification testing
+}
index a30484bd220d9fe4d68b5ff06aba2f13ac94f144..a0e7e063f7297c5e5de823dd9c463c55558a2ad6 100644 (file)
@@ -2,6 +2,7 @@
 
 namespace Tests\User;
 
+use BookStack\Activity\Tools\UserEntityWatchOptions;
 use Tests\TestCase;
 
 class UserPreferencesTest extends TestCase
@@ -79,7 +80,6 @@ class UserPreferencesTest extends TestCase
     public function test_notification_preferences_updating()
     {
         $editor = $this->users->editor();
-        $this->permissions->grantUserRolePermissions($editor, ['receive-notifications']);
 
         // View preferences with defaults
         $resp = $this->actingAs($editor)->get('/preferences/notifications');
@@ -102,6 +102,25 @@ class UserPreferencesTest extends TestCase
         $html->assertFieldHasValue('preferences[comment-replies]', 'true');
     }
 
+    public function test_notification_preferences_show_watches()
+    {
+        $editor = $this->users->editor();
+        $book = $this->entities->book();
+
+        $options = new UserEntityWatchOptions($editor, $book);
+        $options->updateWatchLevel('comments');
+
+        $resp = $this->actingAs($editor)->get('/preferences/notifications');
+        $resp->assertSee($book->name);
+        $resp->assertSee('All Page Updates & Comments');
+
+        $options->updateWatchLevel('default');
+
+        $resp = $this->actingAs($editor)->get('/preferences/notifications');
+        $resp->assertDontSee($book->name);
+        $resp->assertDontSee('All Page Updates & Comments');
+    }
+
     public function test_update_sort_preference()
     {
         $editor = $this->users->editor();
Morty Proxy This is a proxified and sanitized view of the page, visit original site.