3 namespace Tests\Activity;
5 use BookStack\Activity\Tools\UserEntityWatchOptions;
6 use BookStack\Activity\WatchLevels;
7 use BookStack\Entities\Models\Entity;
10 class WatchTest extends TestCase
12 public function test_watch_action_exists_on_entity_unless_active()
14 $editor = $this->users->editor();
15 $this->actingAs($editor);
17 $entities = [$this->entities->book(), $this->entities->chapter(), $this->entities->page()];
18 /** @var Entity $entity */
19 foreach ($entities as $entity) {
20 $resp = $this->get($entity->getUrl());
21 $this->withHtml($resp)->assertElementContains('form[action$="/watching/update"] button.icon-list-item', 'Watch');
23 $watchOptions = new UserEntityWatchOptions($editor, $entity);
24 $watchOptions->updateWatchLevel('comments');
26 $resp = $this->get($entity->getUrl());
27 $this->withHtml($resp)->assertElementNotExists('form[action$="/watching/update"] button.icon-list-item');
31 public function test_watch_action_only_shows_with_permission()
33 $viewer = $this->users->viewer();
34 $this->actingAs($viewer);
36 $entities = [$this->entities->book(), $this->entities->chapter(), $this->entities->page()];
37 /** @var Entity $entity */
38 foreach ($entities as $entity) {
39 $resp = $this->get($entity->getUrl());
40 $this->withHtml($resp)->assertElementNotExists('form[action$="/watching/update"] button.icon-list-item');
43 $this->permissions->grantUserRolePermissions($viewer, ['receive-notifications']);
45 /** @var Entity $entity */
46 foreach ($entities as $entity) {
47 $resp = $this->get($entity->getUrl());
48 $this->withHtml($resp)->assertElementExists('form[action$="/watching/update"] button.icon-list-item');
52 public function test_watch_update()
54 $editor = $this->users->editor();
55 $book = $this->entities->book();
57 $this->actingAs($editor)->get($book->getUrl());
58 $resp = $this->put('/watching/update', [
59 'type' => get_class($book),
64 $resp->assertRedirect($book->getUrl());
65 $this->assertSessionHas('success');
66 $this->assertDatabaseHas('watches', [
67 'watchable_id' => $book->id,
68 'watchable_type' => $book->getMorphClass(),
69 'user_id' => $editor->id,
70 'level' => WatchLevels::COMMENTS,
73 $resp = $this->put('/watching/update', [
74 'type' => get_class($book),
78 $resp->assertRedirect($book->getUrl());
79 $this->assertDatabaseMissing('watches', [
80 'watchable_id' => $book->id,
81 'watchable_type' => $book->getMorphClass(),
82 'user_id' => $editor->id,
86 public function test_watch_detail_display_reflects_state()
88 $editor = $this->users->editor();
89 $book = $this->entities->bookHasChaptersAndPages();
90 $chapter = $book->chapters()->first();
91 $page = $chapter->pages()->first();
93 (new UserEntityWatchOptions($editor, $book))->updateWatchLevel('updates');
95 $this->actingAs($editor)->get($book->getUrl())->assertSee('Watching new pages and updates');
96 $this->get($chapter->getUrl())->assertSee('Watching via parent book');
97 $this->get($page->getUrl())->assertSee('Watching via parent book');
99 (new UserEntityWatchOptions($editor, $chapter))->updateWatchLevel('comments');
100 $this->get($chapter->getUrl())->assertSee('Watching new pages, updates & comments');
101 $this->get($page->getUrl())->assertSee('Watching via parent chapter');
103 (new UserEntityWatchOptions($editor, $page))->updateWatchLevel('updates');
104 $this->get($page->getUrl())->assertSee('Watching new pages and updates');
107 public function test_watch_detail_ignore_indicator_cascades()
109 $editor = $this->users->editor();
110 $book = $this->entities->bookHasChaptersAndPages();
111 (new UserEntityWatchOptions($editor, $book))->updateWatchLevel('ignore');
113 $this->actingAs($editor)->get($book->getUrl())->assertSee('Ignoring notifications');
114 $this->get($book->chapters()->first()->getUrl())->assertSee('Ignoring via parent book');
115 $this->get($book->pages()->first()->getUrl())->assertSee('Ignoring via parent book');
118 public function test_watch_option_menu_shows_current_active_state()
120 $editor = $this->users->editor();
121 $book = $this->entities->book();
122 $options = new UserEntityWatchOptions($editor, $book);
124 $respHtml = $this->withHtml($this->actingAs($editor)->get($book->getUrl()));
125 $respHtml->assertElementNotExists('form[action$="/watching/update"] svg[data-icon="check-circle"]');
127 $options->updateWatchLevel('comments');
128 $respHtml = $this->withHtml($this->actingAs($editor)->get($book->getUrl()));
129 $respHtml->assertElementExists('form[action$="/watching/update"] button[value="comments"] svg[data-icon="check-circle"]');
131 $options->updateWatchLevel('ignore');
132 $respHtml = $this->withHtml($this->actingAs($editor)->get($book->getUrl()));
133 $respHtml->assertElementExists('form[action$="/watching/update"] button[value="ignore"] svg[data-icon="check-circle"]');
136 public function test_watch_option_menu_limits_options_for_pages()
138 $editor = $this->users->editor();
139 $book = $this->entities->bookHasChaptersAndPages();
140 (new UserEntityWatchOptions($editor, $book))->updateWatchLevel('ignore');
142 $respHtml = $this->withHtml($this->actingAs($editor)->get($book->getUrl()));
143 $respHtml->assertElementExists('form[action$="/watching/update"] button[name="level"][value="new"]');
145 $respHtml = $this->withHtml($this->get($book->pages()->first()->getUrl()));
146 $respHtml->assertElementExists('form[action$="/watching/update"] button[name="level"][value="updates"]');
147 $respHtml->assertElementNotExists('form[action$="/watching/update"] button[name="level"][value="new"]');
150 // TODO - Guest user cannot see/set notifications
151 // TODO - Actual notification testing