emails_on_push_worker_spec.rb 5.46 KB
Newer Older
1 2
# frozen_string_literal: true

3 4
require 'spec_helper'

5
describe EmailsOnPushWorker, :mailer do
6
  include RepoHelpers
7
  include EmailSpec::Matchers
8

9
  let(:project) { create(:project, :repository) }
10
  let(:user) { create(:user) }
11
  let(:data) { Gitlab::DataBuilder::Push.build_sample(project, user) }
12 13
  let(:recipients) { user.email }
  let(:perform) { subject.perform(project.id, recipients, data.stringify_keys) }
14
  let(:email) { ActionMailer::Base.deliveries.last }
15

16
  subject { described_class.new }
17 18

  describe "#perform" do
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
    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

51 52 53 54 55 56 57 58 59 60 61
    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
62
        expect(email.subject).to include('adds bar folder and branch-test text file')
63
      end
64

65 66 67 68 69 70 71 72 73 74
      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
75 76 77
      before do
        perform
      end
78

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

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

87 88 89
      it "sends the mail to the correct recipient" do
        expect(email.to).to eq([user.email])
      end
90 91
    end

92 93 94
    context "when there is an SMTP error" do
      before do
        allow(Notify).to receive(:repository_push_email).and_raise(Net::SMTPFatalError)
Sean McGivern's avatar
Sean McGivern committed
95
        allow(subject).to receive_message_chain(:logger, :info)
96 97 98 99 100 101 102 103 104 105
        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
      before do
George Tsiolis's avatar
George Tsiolis committed
106
        # This is a hack because we modify the mail object before sending, for efficiency,
107 108 109 110 111 112 113
        # 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
      end
114

George Thomas's avatar
George Thomas committed
115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132
      context "when the recipient addresses are a list of email addresses" do
        let(:recipients) do
          1.upto(5).map { |i| user.email.sub('@', "+#{i}@") }.join("\n")
        end

        it "sends the mail to each of the recipients" do
          perform

          expect(ActionMailer::Base.deliveries.count).to eq(5)
          expect(email_recipients).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
133
      end
134

George Thomas's avatar
George Thomas committed
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
      context "when the recipient addresses contains angle brackets and are separated by spaces" do
        let(:recipients) { "John Doe <johndoe@example.com> Jane Doe <janedoe@example.com>" }

        it "accepts emails separated by whitespace" do
          perform

          expect(ActionMailer::Base.deliveries.count).to eq(2)
          expect(email_recipients).to contain_exactly("johndoe@example.com", "janedoe@example.com")
        end
      end

      context "when the recipient addresses contain a mix of emails with and without angle brackets" do
        let(:recipients) { "johndoe@example.com Jane Doe <janedoe@example.com>" }

        it "accepts both kind of emails" do
          perform

          expect(ActionMailer::Base.deliveries.count).to eq(2)
          expect(email_recipients).to contain_exactly("johndoe@example.com", "janedoe@example.com")
        end
      end

      context "when the recipient addresses contains angle brackets and are separated by newlines" do
        let(:recipients) { "John Doe <johndoe@example.com>\nJane Doe <janedoe@example.com>" }

        it "accepts emails separated by newlines" do
          perform

          expect(ActionMailer::Base.deliveries.count).to eq(2)
          expect(email_recipients).to contain_exactly("johndoe@example.com", "janedoe@example.com")
        end
166
      end
167 168 169
    end
  end
end