summaryrefslogtreecommitdiff
path: root/spec/workers/emails_on_push_worker_spec.rb
blob: a0ed85cc0b37fdfec1acfaf429a926a291cc0c47 (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
require 'spec_helper'

describe EmailsOnPushWorker do
  include RepoHelpers
  include EmailHelpers
  include EmailSpec::Matchers

  let(:project) { create(:project, :repository) }
  let(:user) { create(:user) }
  let(:data) { Gitlab::DataBuilder::Push.build_sample(project, user) }
  let(:recipients) { user.email }
  let(:perform) { subject.perform(project.id, recipients, data.stringify_keys) }
  let(:email) { ActionMailer::Base.deliveries.last }

  subject { described_class.new }

  describe "#perform" do
    context "when push is a new branch" do
      before do
        data_new_branch = data.stringify_keys.merge("before" => Gitlab::Git::BLANK_SHA)

        subject.perform(project.id, recipients, data_new_branch)
      end

      it "sends a mail with the correct subject" do
        expect(email.subject).to include("Pushed new branch")
      end

      it "sends the mail to the correct recipient" do
        expect(email.to).to eq([user.email])
      end
    end

    context "when push is a deleted branch" do
      before do
        data_deleted_branch = data.stringify_keys.merge("after" => Gitlab::Git::BLANK_SHA)

        subject.perform(project.id, recipients, data_deleted_branch)
      end

      it "sends a mail with the correct subject" do
        expect(email.subject).to include("Deleted branch")
      end

      it "sends the mail to the correct recipient" do
        expect(email.to).to eq([user.email])
      end
    end

    context "when push is a force push to delete commits" do
      before do
        data_force_push = data.stringify_keys.merge(
          "after"  => data[:before],
          "before" => data[:after]
        )

        subject.perform(project.id, recipients, data_force_push)
      end

      it "sends a mail with the correct subject" do
        expect(email.subject).to include('adds bar folder and branch-test text file')
      end

      it "mentions force pushing in the body" do
        expect(email).to have_body_text("force push")
      end

      it "sends the mail to the correct recipient" do
        expect(email.to).to eq([user.email])
      end
    end

    context "when there are no errors in sending" do
      before { perform }

      it "sends a mail with the correct subject" do
        expect(email.subject).to include('adds bar folder and branch-test text file')
      end

      it "does not mention force pushing in the body" do
        expect(email).not_to have_body_text("force push")
      end

      it "sends the mail to the correct recipient" do
        expect(email.to).to eq([user.email])
      end
    end

    context "when there is an SMTP error" do
      before do
        reset_delivered_emails!
        allow(Notify).to receive(:repository_push_email).and_raise(Net::SMTPFatalError)
        allow(subject).to receive_message_chain(:logger, :info)
        perform
      end

      it "gracefully handles an input SMTP error" do
        expect(ActionMailer::Base.deliveries.count).to eq(0)
      end
    end

    context "when there are multiple recipients" do
      let(:recipients) do
        1.upto(5).map { |i| user.email.sub('@', "+#{i}@") }.join("\n")
      end

      before do
        # This is a hack because we modify the mail object before sending, for efficency,
        # but the TestMailer adapter just appends the objects to an array. To clone a mail
        # object, create a new one!
        #   https://github.com/mikel/mail/issues/314#issuecomment-12750108
        allow_any_instance_of(Mail::TestMailer).to receive(:deliver!).and_wrap_original do |original, mail|
          original.call(Mail.new(mail.encoded))
        end

        reset_delivered_emails!
      end

      it "sends the mail to each of the recipients" do
        perform
        expect(ActionMailer::Base.deliveries.count).to eq(5)
        expect(ActionMailer::Base.deliveries.map(&:to).flatten).to contain_exactly(*recipients.split)
      end

      it "only generates the mail once" do
        expect(Notify).to receive(:repository_push_email).once.and_call_original
        expect(Premailer::Rails::CustomizedPremailer).to receive(:new).once.and_call_original
        perform
      end
    end
  end
end