summaryrefslogtreecommitdiff
path: root/spec/observers/issue_observer_spec.rb
blob: b5943f2c5399c6733a6b5c7ac98f52ff03faafe5 (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
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
require 'spec_helper'

describe IssueObserver do
  let(:some_user) { double(:user, id: 1) }
  let(:assignee) { double(:user, id: 2) }
  let(:author) { double(:user, id: 3) }
  let(:issue)    { double(:issue, id: 42, assignee: assignee, author: author) }

  before(:each) { subject.stub(:current_user).and_return(some_user) }

  subject { IssueObserver.instance }

  describe '#after_create' do

    it 'is called when an issue is created' do
      subject.should_receive(:after_create)

      Issue.observers.enable :issue_observer do
        Factory.create(:issue, project: Factory.create(:project))
      end
    end

    it 'sends an email to the assignee' do
      Notify.should_receive(:new_issue_email).with(issue.id).
        and_return(double(deliver: true))

      subject.after_create(issue)
    end

    it 'does not send an email to the assignee if assignee created the issue' do
      subject.stub(:current_user).and_return(assignee)
      Notify.should_not_receive(:new_issue_email)

      subject.after_create(issue)
    end
  end

  context '#after_update' do
    before(:each) do
      issue.stub(:is_being_reassigned?).and_return(false)
      issue.stub(:is_being_closed?).and_return(false)
      issue.stub(:is_being_reopened?).and_return(false)
    end

    it 'is called when an issue is changed' do
      changed = Factory.create(:issue, project: Factory.create(:project))
      subject.should_receive(:after_update)

      Issue.observers.enable :issue_observer do
        changed.description = 'I changed'
        changed.save
      end
    end

    context 'a reassigned email' do
      it 'is sent if the issue is being reassigned' do
        issue.should_receive(:is_being_reassigned?).and_return(true)
        subject.should_receive(:send_reassigned_email).with(issue)

        subject.after_update(issue)
      end

      it 'is not sent if the issue is not being reassigned' do
        issue.should_receive(:is_being_reassigned?).and_return(false)
        subject.should_not_receive(:send_reassigned_email)

        subject.after_update(issue)
      end
    end

    context 'a status "closed"' do
      it 'note is created if the issue is being closed' do
        issue.should_receive(:is_being_closed?).and_return(true)
        Note.should_receive(:create_status_change_note).with(issue, some_user, 'closed')

        subject.after_update(issue)
      end

      it 'note is not created if the issue is not being closed' do
        issue.should_receive(:is_being_closed?).and_return(false)
        Note.should_not_receive(:create_status_change_note).with(issue, some_user, 'closed')

        subject.after_update(issue)
      end

      it 'notification is delivered if the issue being closed' do
        issue.stub(:is_being_closed?).and_return(true)
        Notify.should_receive(:issue_status_changed_email).twice
        Note.should_receive(:create_status_change_note).with(issue, some_user, 'closed')

        subject.after_update(issue)
      end

      it 'notification is not delivered if the issue not being closed' do
        issue.stub(:is_being_closed?).and_return(false)
        Notify.should_not_receive(:issue_status_changed_email)
        Note.should_not_receive(:create_status_change_note).with(issue, some_user, 'closed')

        subject.after_update(issue)
      end

      it 'notification is delivered only to author if the issue being closed' do
        issue_without_assignee = double(:issue, id: 42, author: author, assignee: nil)
        issue_without_assignee.stub(:is_being_reassigned?).and_return(false)
        issue_without_assignee.stub(:is_being_closed?).and_return(true)
        issue_without_assignee.stub(:is_being_reopened?).and_return(false)
        Notify.should_receive(:issue_status_changed_email).once
        Note.should_receive(:create_status_change_note).with(issue_without_assignee, some_user, 'closed')

        subject.after_update(issue_without_assignee)
      end
    end

    context 'a status "reopened"' do
      it 'note is created if the issue is being reopened' do
        issue.should_receive(:is_being_reopened?).and_return(true)
        Note.should_receive(:create_status_change_note).with(issue, some_user, 'reopened')

        subject.after_update(issue)
      end

      it 'note is not created if the issue is not being reopened' do
        issue.should_receive(:is_being_reopened?).and_return(false)
        Note.should_not_receive(:create_status_change_note).with(issue, some_user, 'reopened')

        subject.after_update(issue)
      end

      it 'notification is delivered if the issue being reopened' do
        issue.stub(:is_being_reopened?).and_return(true)
        Notify.should_receive(:issue_status_changed_email).twice
        Note.should_receive(:create_status_change_note).with(issue, some_user, 'reopened')

        subject.after_update(issue)
      end

      it 'notification is not delivered if the issue not being reopened' do
        issue.stub(:is_being_reopened?).and_return(false)
        Notify.should_not_receive(:issue_status_changed_email)
        Note.should_not_receive(:create_status_change_note).with(issue, some_user, 'reopened')

        subject.after_update(issue)
      end

      it 'notification is delivered only to author if the issue being reopened' do
        issue_without_assignee = double(:issue, id: 42, author: author, assignee: nil)
        issue_without_assignee.stub(:is_being_reassigned?).and_return(false)
        issue_without_assignee.stub(:is_being_closed?).and_return(false)
        issue_without_assignee.stub(:is_being_reopened?).and_return(true)
        Notify.should_receive(:issue_status_changed_email).once
        Note.should_receive(:create_status_change_note).with(issue_without_assignee, some_user, 'reopened')

        subject.after_update(issue_without_assignee)
      end
    end
  end

  describe '#send_reassigned_email' do
    let(:previous_assignee) { double(:user, id: 3) }

    before(:each) do
      issue.stub(:assignee_id).and_return(assignee.id)
      issue.stub(:assignee_id_was).and_return(previous_assignee.id)
    end

    def it_sends_a_reassigned_email_to(recipient)
      Notify.should_receive(:reassigned_issue_email).with(recipient, issue.id, previous_assignee.id).
        and_return(double(deliver: true))
    end

    def it_does_not_send_a_reassigned_email_to(recipient)
      Notify.should_not_receive(:reassigned_issue_email).with(recipient, issue.id, previous_assignee.id)
    end

    it 'sends a reassigned email to the previous and current assignees' do
      it_sends_a_reassigned_email_to assignee.id
      it_sends_a_reassigned_email_to previous_assignee.id

      subject.send(:send_reassigned_email, issue)
    end

    context 'does not send an email to the user who made the reassignment' do
      it 'if the user is the assignee' do
        subject.stub(:current_user).and_return(assignee)
        it_sends_a_reassigned_email_to previous_assignee.id
        it_does_not_send_a_reassigned_email_to assignee.id

        subject.send(:send_reassigned_email, issue)
      end
      it 'if the user is the previous assignee' do
        subject.stub(:current_user).and_return(previous_assignee)
        it_sends_a_reassigned_email_to assignee.id
        it_does_not_send_a_reassigned_email_to previous_assignee.id

        subject.send(:send_reassigned_email, issue)
      end
    end
  end
end