summaryrefslogtreecommitdiff
path: root/test/models/notification_test.rb
blob: e9ecfaa908201da75f1d5710e297a60fa507d57f (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
# frozen_string_literal: true

# == Schema Information
#
# Table name: notifications
#
#  id               :integer          not null, primary key
#  action           :string           not null
#  actor_child_type :string
#  actor_type       :string           not null
#  created_at       :datetime         not null
#  updated_at       :datetime         not null
#  actor_child_id   :integer
#  actor_id         :integer          not null
#
# Indexes
#
#  index_notifications_on_actor_id_and_actor_type  (actor_id,actor_type)
#
require 'test_helper'

class NotificationTest < ActiveSupport::TestCase
  setup do
    @topic = create(:topic_with_posts)
    @post = @topic.posts.first
    @user = create(:user)
    @creator = create(:user)
  end

  test 'has an actor and an actor_child' do
    Notification.watch(@topic, @user)

    assert_difference('Notification.count') { immediate_notify(@topic, 'ran the tests', @post) }

    n = Notification.first
    assert_equal @topic, n.actor
    assert_equal @post, n.actor_child
  end

  test '.watch should add the user to the watcher list' do
    Notification.watch(@topic, @user)

    @topic.reload
    assert_includes @topic.subscribers, @user
  end

  test '.unwatch should remove the user from the watcher list' do
    Notification.watch(@topic, @user)
    Notification.unwatch(@topic, @user)
    assert_not_includes @topic.subscribers, @user
  end

  test '.watching? should return true if the user is watching the actor' do
    Notification.watch(@topic, @user)
    assert Notification.watching?(@topic, @user)
  end

  test '.watching? should return false if the user is not watching the actor' do
    assert_not Notification.watching?(@topic, @user)
  end

  test 'a tree should not make a sound if nobody hears it' do
    assert_no_difference('Notification.count') { immediate_notify(@topic, '*sound of tree falling*', @post) }
  end

  test 'should notify any subscribed users except the creator' do
    Notification.watch(@topic, @user)
    assert_difference('Notification.count') { immediate_notify(@topic, 'replied', @creator) }

    @user.reload
    @creator.reload
    assert_empty @creator.unread_notifications
    assert_not_empty @user.unread_notifications
  end

  test 'should not allow duplicates to form' do
    Notification.watch(@topic, @user)
    4.times { immediate_notify(@topic, 'replied', create(:user)) }
    @user.reload
    assert_equal 1, @user.unread_notifications.count
    assert_equal 1, Notification.count
  end

  test '.mark_read should remove a notification from the user' do
    Notification.watch(@topic, @user)
    immediate_notify(@topic, 'replied', @creator)
    n1 = Notification.find_by(actor: @topic)
    Notification.mark_read(n1, @user)

    @user.reload
    assert_equal 0, @user.unread_notifications.count
  end

  test '.mark_all_read should remove all notifications for an actor for a user' do
    Notification.watch(@topic, @user)
    immediate_notify(@topic, 'replied', @creator)
    Notification.mark_all_read(@topic, @user)

    @user.reload
    assert_equal 0, @user.unread_notifications.count
  end

  test 'cleanup should remove all notifications for an actor' do
    4.times { Notification.watch(@topic, create(:user)) }
    immediate_notify(@topic, 'replied', @creator)
    assert_difference('Notification.count', -1) do
      NotificationCleanupJob.perform_now(@topic.id, 'Topic')
    end
  end

  def immediate_notify(actor, action, actor_child)
    NotificationJob.perform_now(actor.id, actor.class.to_s, action, actor_child&.id, actor_child&.class&.to_s)
  end
end