notify_spec.rb 50.2 KB
Newer Older
1
require 'spec_helper'
R
Robert Speicher 已提交
2
require 'email_spec'
3 4 5 6

describe Notify do
  include EmailSpec::Helpers
  include EmailSpec::Matchers
D
Dmitriy Zaporozhets 已提交
7
  include RepoHelpers
8

9
  include_context 'gitlab email notification'
10

11 12 13 14 15 16 17 18 19
  def have_referable_subject(referable, reply: false)
    prefix = referable.project.name if referable.project
    prefix = "Re: #{prefix}" if reply

    suffix = "#{referable.title} (#{referable.to_reference})"

    have_subject [prefix, suffix].compact.join(' | ')
  end

R
Robb Kidd 已提交
20 21
  context 'for a project' do
    describe 'items that are assignable, the email' do
22
      let(:current_user) { create(:user, email: "current@email.com") }
23
      let(:assignee) { create(:user, email: 'assignee@example.com', name: 'John Doe') }
24
      let(:previous_assignee) { create(:user, name: 'Previous Assignee') }
25

R
Robb Kidd 已提交
26
      shared_examples 'an assignee email' do
27 28
        it 'is sent to the assignee as the author' do
          sender = subject.header[:from].addrs.first
29

30 31 32 33 34
          aggregate_failures do
            expect(sender.display_name).to eq(current_user.name)
            expect(sender.address).to eq(gitlab_sender)
            expect(subject).to deliver_to(assignee.email)
          end
R
Robb Kidd 已提交
35 36
        end
      end
37

R
Robb Kidd 已提交
38
      context 'for issues' do
39 40
        let(:issue) { create(:issue, author: current_user, assignees: [assignee], project: project) }
        let(:issue_with_description) { create(:issue, author: current_user, assignees: [assignee], project: project, description: 'My awesome description') }
41

R
Robb Kidd 已提交
42
        describe 'that are new' do
43
          subject { described_class.new_issue_email(issue.assignees.first.id, issue.id) }
44

R
Robb Kidd 已提交
45
          it_behaves_like 'an assignee email'
46 47 48
          it_behaves_like 'an email starting a new thread with reply-by-email enabled' do
            let(:model) { issue }
          end
49
          it_behaves_like 'it should show Gmail Actions View Issue link'
50
          it_behaves_like 'an unsubscribeable thread'
51

52 53 54
          it 'has the correct subject and body' do
            aggregate_failures do
              is_expected.to have_referable_subject(issue)
55
              is_expected.to have_body_text(project_issue_path(project, issue))
56
            end
R
Robb Kidd 已提交
57
          end
58 59 60

          context 'when enabled email_author_in_body' do
            before do
S
Sean McGivern 已提交
61
              stub_application_setting(email_author_in_body: true)
62 63 64
            end

            it 'contains a link to note author' do
65
              is_expected.to have_html_escaped_body_text(issue.author_name)
D
Douwe Maan 已提交
66
              is_expected.to have_body_text 'created an issue:'
67 68
            end
          end
R
Robb Kidd 已提交
69
        end
70

71
        describe 'that are new with a description' do
72
          subject { described_class.new_issue_email(issue_with_description.assignees.first.id, issue_with_description.id) }
73

74 75
          it_behaves_like 'it should show Gmail Actions View Issue link'

76
          it 'contains the description' do
77
            is_expected.to have_html_escaped_body_text issue_with_description.description
78 79 80
          end
        end

R
Robb Kidd 已提交
81
        describe 'that have been reassigned' do
82
          subject { described_class.reassigned_issue_email(recipient.id, issue.id, [previous_assignee.id], current_user.id) }
R
Robb Kidd 已提交
83 84

          it_behaves_like 'a multiple recipients email'
85 86 87
          it_behaves_like 'an answer to an existing thread with reply-by-email enabled' do
            let(:model) { issue }
          end
88
          it_behaves_like 'it should show Gmail Actions View Issue link'
89
          it_behaves_like 'an unsubscribeable thread'
R
Robb Kidd 已提交
90

91 92
          it 'is sent as the author' do
            sender = subject.header[:from].addrs[0]
93 94
            expect(sender.display_name).to eq(current_user.name)
            expect(sender.address).to eq(gitlab_sender)
95 96
          end

97 98 99 100 101
          it 'has the correct subject and body' do
            aggregate_failures do
              is_expected.to have_referable_subject(issue, reply: true)
              is_expected.to have_html_escaped_body_text(previous_assignee.name)
              is_expected.to have_html_escaped_body_text(assignee.name)
102
              is_expected.to have_body_text(project_issue_path(project, issue))
103
            end
R
Robb Kidd 已提交
104 105
          end
        end
A
Alex Denisov 已提交
106

107
        describe 'that have been relabeled' do
108
          subject { described_class.relabeled_issue_email(recipient.id, issue.id, %w[foo bar baz], current_user.id) }
109 110

          it_behaves_like 'a multiple recipients email'
111 112 113
          it_behaves_like 'an answer to an existing thread with reply-by-email enabled' do
            let(:model) { issue }
          end
114 115 116 117 118 119 120 121 122 123
          it_behaves_like 'it should show Gmail Actions View Issue link'
          it_behaves_like 'a user cannot unsubscribe through footer link'
          it_behaves_like 'an email with a labels subscriptions link in its footer'

          it 'is sent as the author' do
            sender = subject.header[:from].addrs[0]
            expect(sender.display_name).to eq(current_user.name)
            expect(sender.address).to eq(gitlab_sender)
          end

124 125 126 127
          it 'has the correct subject and body' do
            aggregate_failures do
              is_expected.to have_referable_subject(issue, reply: true)
              is_expected.to have_body_text('foo, bar, and baz')
128
              is_expected.to have_body_text(project_issue_path(project, issue))
129
            end
130
          end
131 132

          context 'with a preferred language' do
133 134 135 136 137 138 139
            before do
              Gitlab::I18n.locale = :es
            end

            after do
              Gitlab::I18n.use_default_locale
            end
140 141 142 143 144

            it 'always generates the email using the default language' do
              is_expected.to have_body_text('foo, bar, and baz')
            end
          end
145 146
        end

A
Alex Denisov 已提交
147 148
        describe 'status changed' do
          let(:status) { 'closed' }
149
          subject { described_class.issue_status_changed_email(recipient.id, issue.id, status, current_user.id) }
150

151 152 153
          it_behaves_like 'an answer to an existing thread with reply-by-email enabled' do
            let(:model) { issue }
          end
154
          it_behaves_like 'it should show Gmail Actions View Issue link'
155
          it_behaves_like 'an unsubscribeable thread'
156

157 158
          it 'is sent as the author' do
            sender = subject.header[:from].addrs[0]
159 160
            expect(sender.display_name).to eq(current_user.name)
            expect(sender.address).to eq(gitlab_sender)
161 162
          end

163 164 165 166 167
          it 'has the correct subject and body' do
            aggregate_failures do
              is_expected.to have_referable_subject(issue, reply: true)
              is_expected.to have_body_text(status)
              is_expected.to have_html_escaped_body_text(current_user.name)
168
              is_expected.to have_body_text(project_issue_path project, issue)
169
            end
A
Alex Denisov 已提交
170
          end
171
        end
172 173 174

        describe 'moved to another project' do
          let(:new_issue) { create(:issue) }
175
          subject { described_class.issue_moved_email(recipient, issue, new_issue, current_user) }
176

177 178 179
          it_behaves_like 'an answer to an existing thread with reply-by-email enabled' do
            let(:model) { issue }
          end
180 181 182 183 184 185 186
          it_behaves_like 'it should show Gmail Actions View Issue link'
          it_behaves_like 'an unsubscribeable thread'

          it 'contains description about action taken' do
            is_expected.to have_body_text 'Issue was moved to another project'
          end

187
          it 'has the correct subject and body' do
188
            new_issue_url = project_issue_path(new_issue.project, new_issue)
189

190 191 192
            aggregate_failures do
              is_expected.to have_referable_subject(issue, reply: true)
              is_expected.to have_body_text(new_issue_url)
193
              is_expected.to have_body_text(project_issue_path(project, issue))
194
            end
195 196
          end
        end
R
Robb Kidd 已提交
197 198 199
      end

      context 'for merge requests' do
200
        let(:project) { create(:project, :repository) }
201
        let(:merge_author) { create(:user) }
202
        let(:merge_request) { create(:merge_request, author: current_user, assignee: assignee, source_project: project, target_project: project) }
203
        let(:merge_request_with_description) { create(:merge_request, author: current_user, assignee: assignee, source_project: project, target_project: project, description: 'My awesome description') }
R
Robb Kidd 已提交
204 205

        describe 'that are new' do
206
          subject { described_class.new_merge_request_email(merge_request.assignee_id, merge_request.id) }
R
Robb Kidd 已提交
207 208

          it_behaves_like 'an assignee email'
209 210 211
          it_behaves_like 'an email starting a new thread with reply-by-email enabled' do
            let(:model) { merge_request }
          end
212
          it_behaves_like 'it should show Gmail Actions View Merge request link'
213
          it_behaves_like 'an unsubscribeable thread'
R
Robb Kidd 已提交
214

215 216 217
          it 'has the correct subject and body' do
            aggregate_failures do
              is_expected.to have_referable_subject(merge_request)
218
              is_expected.to have_body_text(project_merge_request_path(project, merge_request))
219 220 221
              is_expected.to have_body_text(merge_request.source_branch)
              is_expected.to have_body_text(merge_request.target_branch)
            end
R
Robb Kidd 已提交
222
          end
P
Philip Blatter 已提交
223

224 225
          context 'when enabled email_author_in_body' do
            before do
S
Sean McGivern 已提交
226
              stub_application_setting(email_author_in_body: true)
227 228 229
            end

            it 'contains a link to note author' do
230
              is_expected.to have_html_escaped_body_text merge_request.author_name
D
Douwe Maan 已提交
231
              is_expected.to have_body_text 'created a merge request:'
232 233
            end
          end
R
Robb Kidd 已提交
234 235
        end

236
        describe 'that are new with a description' do
237
          subject { described_class.new_merge_request_email(merge_request_with_description.assignee_id, merge_request_with_description.id) }
238

239
          it_behaves_like 'it should show Gmail Actions View Merge request link'
240
          it_behaves_like "an unsubscribeable thread"
241

242
          it 'contains the description' do
243
            is_expected.to have_html_escaped_body_text merge_request_with_description.description
244 245 246
          end
        end

R
Robb Kidd 已提交
247
        describe 'that are reassigned' do
248
          subject { described_class.reassigned_merge_request_email(recipient.id, merge_request.id, previous_assignee.id, current_user.id) }
R
Robb Kidd 已提交
249 250

          it_behaves_like 'a multiple recipients email'
251 252 253
          it_behaves_like 'an answer to an existing thread with reply-by-email enabled' do
            let(:model) { merge_request }
          end
254
          it_behaves_like 'it should show Gmail Actions View Merge request link'
255
          it_behaves_like "an unsubscribeable thread"
R
Robb Kidd 已提交
256

257 258
          it 'is sent as the author' do
            sender = subject.header[:from].addrs[0]
259 260
            expect(sender.display_name).to eq(current_user.name)
            expect(sender.address).to eq(gitlab_sender)
261 262
          end

263 264 265 266
          it 'has the correct subject and body' do
            aggregate_failures do
              is_expected.to have_referable_subject(merge_request, reply: true)
              is_expected.to have_html_escaped_body_text(previous_assignee.name)
267
              is_expected.to have_body_text(project_merge_request_path(project, merge_request))
268 269
              is_expected.to have_html_escaped_body_text(assignee.name)
            end
R
Robb Kidd 已提交
270
          end
271 272
        end

273
        describe 'that have been relabeled' do
274
          subject { described_class.relabeled_merge_request_email(recipient.id, merge_request.id, %w[foo bar baz], current_user.id) }
275 276

          it_behaves_like 'a multiple recipients email'
277 278 279
          it_behaves_like 'an answer to an existing thread with reply-by-email enabled' do
            let(:model) { merge_request }
          end
280 281 282 283 284 285 286 287 288 289
          it_behaves_like 'it should show Gmail Actions View Merge request link'
          it_behaves_like 'a user cannot unsubscribe through footer link'
          it_behaves_like 'an email with a labels subscriptions link in its footer'

          it 'is sent as the author' do
            sender = subject.header[:from].addrs[0]
            expect(sender.display_name).to eq(current_user.name)
            expect(sender.address).to eq(gitlab_sender)
          end

290
          it 'has the correct subject and body' do
291
            is_expected.to have_referable_subject(merge_request, reply: true)
292
            is_expected.to have_body_text('foo, bar, and baz')
293
            is_expected.to have_body_text(project_merge_request_path(project, merge_request))
294 295 296
          end
        end

297 298
        describe 'status changed' do
          let(:status) { 'reopened' }
299
          subject { described_class.merge_request_status_email(recipient.id, merge_request.id, status, current_user.id) }
300

301 302 303
          it_behaves_like 'an answer to an existing thread with reply-by-email enabled' do
            let(:model) { merge_request }
          end
304
          it_behaves_like 'it should show Gmail Actions View Merge request link'
305
          it_behaves_like 'an unsubscribeable thread'
306 307 308

          it 'is sent as the author' do
            sender = subject.header[:from].addrs[0]
309 310
            expect(sender.display_name).to eq(current_user.name)
            expect(sender.address).to eq(gitlab_sender)
311 312
          end

313 314 315 316 317
          it 'has the correct subject and body' do
            aggregate_failures do
              is_expected.to have_referable_subject(merge_request, reply: true)
              is_expected.to have_body_text(status)
              is_expected.to have_html_escaped_body_text(current_user.name)
318
              is_expected.to have_body_text(project_merge_request_path(project, merge_request))
319
            end
320 321 322
          end
        end

323
        describe 'that are merged' do
324
          subject { described_class.merged_merge_request_email(recipient.id, merge_request.id, merge_author.id) }
325 326

          it_behaves_like 'a multiple recipients email'
327 328 329
          it_behaves_like 'an answer to an existing thread with reply-by-email enabled' do
            let(:model) { merge_request }
          end
330
          it_behaves_like 'it should show Gmail Actions View Merge request link'
331
          it_behaves_like 'an unsubscribeable thread'
332 333 334

          it 'is sent as the merge author' do
            sender = subject.header[:from].addrs[0]
335 336
            expect(sender.display_name).to eq(merge_author.name)
            expect(sender.address).to eq(gitlab_sender)
337 338
          end

339 340 341 342
          it 'has the correct subject and body' do
            aggregate_failures do
              is_expected.to have_referable_subject(merge_request, reply: true)
              is_expected.to have_body_text('merged')
343
              is_expected.to have_body_text(project_merge_request_path(project, merge_request))
344
            end
345
          end
R
Robb Kidd 已提交
346 347
        end
      end
348 349
    end

350
    describe 'project was moved' do
351
      let(:project) { create(:project) }
352
      let(:user) { create(:user) }
353
      subject { described_class.project_was_moved_email(project.id, user.id, "gitlab/gitlab") }
354

355
      it_behaves_like 'an email sent from GitLab'
356
      it_behaves_like 'it should not have Gmail Actions links'
357
      it_behaves_like "a user cannot unsubscribe through footer link"
358

359 360
      it 'has the correct subject and body' do
        is_expected.to have_subject("#{project.name} | Project was moved")
361
        is_expected.to have_html_escaped_body_text project.name_with_namespace
362
        is_expected.to have_body_text(project.ssh_url_to_repo)
363 364 365
      end
    end

R
Rémy Coutable 已提交
366
    describe 'project access requested' do
367
      context 'for a project in a user namespace' do
368
        let(:project) do
369
          create(:project, :public, :access_requestable) do |project|
370 371 372 373
            project.team << [project.owner, :master, project.owner]
          end
        end

374 375 376
        let(:user) { create(:user) }
        let(:project_member) do
          project.request_access(user)
377
          project.requesters.find_by(user_id: user.id)
378
        end
379
        subject { described_class.member_access_requested_email('project', project_member.id) }
380 381 382 383 384 385 386 387 388 389 390

        it_behaves_like 'an email sent from GitLab'
        it_behaves_like 'it should not have Gmail Actions links'
        it_behaves_like "a user cannot unsubscribe through footer link"

        it 'contains all the useful information' do
          to_emails = subject.header[:to].addrs
          expect(to_emails.size).to eq(1)
          expect(to_emails[0].address).to eq(project.members.owners_and_masters.first.user.notification_email)

          is_expected.to have_subject "Request to join the #{project.name_with_namespace} project"
391
          is_expected.to have_html_escaped_body_text project.name_with_namespace
392
          is_expected.to have_body_text project_project_members_url(project)
393
          is_expected.to have_body_text project_member.human_access
394
        end
R
Rémy Coutable 已提交
395 396
      end

397 398 399
      context 'for a project in a group' do
        let(:group_owner) { create(:user) }
        let(:group) { create(:group).tap { |g| g.add_owner(group_owner) } }
400
        let(:project) { create(:project, :public, :access_requestable, namespace: group) }
401 402 403
        let(:user) { create(:user) }
        let(:project_member) do
          project.request_access(user)
404
          project.requesters.find_by(user_id: user.id)
405
        end
406
        subject { described_class.member_access_requested_email('project', project_member.id) }
R
Rémy Coutable 已提交
407

408 409 410 411 412 413 414 415 416 417
        it_behaves_like 'an email sent from GitLab'
        it_behaves_like 'it should not have Gmail Actions links'
        it_behaves_like "a user cannot unsubscribe through footer link"

        it 'contains all the useful information' do
          to_emails = subject.header[:to].addrs
          expect(to_emails.size).to eq(1)
          expect(to_emails[0].address).to eq(group.members.owners_and_masters.first.user.notification_email)

          is_expected.to have_subject "Request to join the #{project.name_with_namespace} project"
418
          is_expected.to have_html_escaped_body_text project.name_with_namespace
419
          is_expected.to have_body_text project_project_members_url(project)
420
          is_expected.to have_body_text project_member.human_access
421
        end
R
Rémy Coutable 已提交
422
      end
R
Rémy Coutable 已提交
423 424 425
    end

    describe 'project access denied' do
426
      let(:project) { create(:project, :public, :access_requestable) }
R
Rémy Coutable 已提交
427 428 429
      let(:user) { create(:user) }
      let(:project_member) do
        project.request_access(user)
430
        project.requesters.find_by(user_id: user.id)
R
Rémy Coutable 已提交
431
      end
432
      subject { described_class.member_access_denied_email('project', project.id, user.id) }
R
Rémy Coutable 已提交
433 434 435 436 437

      it_behaves_like 'an email sent from GitLab'
      it_behaves_like 'it should not have Gmail Actions links'
      it_behaves_like "a user cannot unsubscribe through footer link"

R
Rémy Coutable 已提交
438 439
      it 'contains all the useful information' do
        is_expected.to have_subject "Access to the #{project.name_with_namespace} project was denied"
440
        is_expected.to have_html_escaped_body_text project.name_with_namespace
441
        is_expected.to have_body_text project.web_url
R
Rémy Coutable 已提交
442
      end
R
Rémy Coutable 已提交
443 444
    end

445
    describe 'project access changed' do
446
      let(:owner) { create(:user, name: "Chang O'Keefe") }
447
      let(:project) { create(:project, :public, :access_requestable, namespace: owner.namespace) }
448
      let(:user) { create(:user) }
449
      let(:project_member) { create(:project_member, project: project, user: user) }
450
      subject { described_class.member_access_granted_email('project', project_member.id) }
451 452

      it_behaves_like 'an email sent from GitLab'
453
      it_behaves_like 'it should not have Gmail Actions links'
454
      it_behaves_like "a user cannot unsubscribe through footer link"
455

R
Rémy Coutable 已提交
456 457
      it 'contains all the useful information' do
        is_expected.to have_subject "Access to the #{project.name_with_namespace} project was granted"
458
        is_expected.to have_html_escaped_body_text project.name_with_namespace
459 460
        is_expected.to have_body_text project.web_url
        is_expected.to have_body_text project_member.human_access
R
Rémy Coutable 已提交
461
      end
462
    end
463

464 465 466 467 468 469 470 471 472
    def invite_to_project(project, inviter:)
      create(
        :project_member,
        :developer,
        project: project,
        invite_token: '1234',
        invite_email: 'toto@example.com',
        user: nil,
        created_by: inviter
473
      )
474 475 476
    end

    describe 'project invitation' do
477
      let(:project) { create(:project) }
478
      let(:master) { create(:user).tap { |u| project.team << [u, :master] } }
479
      let(:project_member) { invite_to_project(project, inviter: master) }
480

481
      subject { described_class.member_invited_email('project', project_member.id, project_member.invite_token) }
482 483 484 485 486

      it_behaves_like 'an email sent from GitLab'
      it_behaves_like 'it should not have Gmail Actions links'
      it_behaves_like "a user cannot unsubscribe through footer link"

R
Rémy Coutable 已提交
487 488
      it 'contains all the useful information' do
        is_expected.to have_subject "Invitation to join the #{project.name_with_namespace} project"
489
        is_expected.to have_html_escaped_body_text project.name_with_namespace
490 491 492
        is_expected.to have_body_text project.web_url
        is_expected.to have_body_text project_member.human_access
        is_expected.to have_body_text project_member.invite_token
R
Rémy Coutable 已提交
493
      end
494 495 496
    end

    describe 'project invitation accepted' do
497
      let(:project) { create(:project) }
498
      let(:invited_user) { create(:user, name: 'invited user') }
499 500
      let(:master) { create(:user).tap { |u| project.team << [u, :master] } }
      let(:project_member) do
501
        invitee = invite_to_project(project, inviter: master)
502 503
        invitee.accept_invite!(invited_user)
        invitee
504
      end
505

506
      subject { described_class.member_invite_accepted_email('project', project_member.id) }
507 508 509 510 511

      it_behaves_like 'an email sent from GitLab'
      it_behaves_like 'it should not have Gmail Actions links'
      it_behaves_like "a user cannot unsubscribe through footer link"

R
Rémy Coutable 已提交
512 513
      it 'contains all the useful information' do
        is_expected.to have_subject 'Invitation accepted'
514
        is_expected.to have_html_escaped_body_text project.name_with_namespace
515 516
        is_expected.to have_body_text project.web_url
        is_expected.to have_body_text project_member.invite_email
517
        is_expected.to have_html_escaped_body_text invited_user.name
R
Rémy Coutable 已提交
518
      end
519 520 521
    end

    describe 'project invitation declined' do
522
      let(:project) { create(:project) }
523 524
      let(:master) { create(:user).tap { |u| project.team << [u, :master] } }
      let(:project_member) do
525
        invitee = invite_to_project(project, inviter: master)
526 527
        invitee.decline_invite!
        invitee
528
      end
529

530
      subject { described_class.member_invite_declined_email('project', project.id, project_member.invite_email, master.id) }
531 532 533 534 535

      it_behaves_like 'an email sent from GitLab'
      it_behaves_like 'it should not have Gmail Actions links'
      it_behaves_like "a user cannot unsubscribe through footer link"

R
Rémy Coutable 已提交
536 537
      it 'contains all the useful information' do
        is_expected.to have_subject 'Invitation declined'
538
        is_expected.to have_html_escaped_body_text project.name_with_namespace
539 540
        is_expected.to have_body_text project.web_url
        is_expected.to have_body_text project_member.invite_email
R
Rémy Coutable 已提交
541
      end
542 543
    end

R
Robb Kidd 已提交
544
    context 'items that are noteable, the email for a note' do
545 546
      let(:note_author) { create(:user, name: 'author_name') }
      let(:note) { create(:note, project: project, author: note_author) }
R
Robb Kidd 已提交
547

548 549
      before :each do
        allow(Note).to receive(:find).with(note.id).and_return(note)
550 551
      end

R
Robb Kidd 已提交
552
      shared_examples 'a note email' do
553 554
        it_behaves_like 'it should have Gmail Actions links'

555
        it 'is sent to the given recipient as the author' do
556 557
          sender = subject.header[:from].addrs[0]

558 559 560 561 562
          aggregate_failures do
            expect(sender.display_name).to eq(note_author.name)
            expect(sender.address).to eq(gitlab_sender)
            expect(subject).to deliver_to(recipient.notification_email)
          end
R
Robb Kidd 已提交
563 564 565
        end

        it 'contains the message from the note' do
566
          is_expected.to have_html_escaped_body_text note.note
R
Robb Kidd 已提交
567
        end
568

569
        it 'does not contain note author' do
D
Douwe Maan 已提交
570
          is_expected.not_to have_body_text note.author_name
571 572 573 574
        end

        context 'when enabled email_author_in_body' do
          before do
S
Sean McGivern 已提交
575
            stub_application_setting(email_author_in_body: true)
576 577 578
          end

          it 'contains a link to note author' do
579
            is_expected.to have_html_escaped_body_text note.author_name
580 581
          end
        end
R
Robb Kidd 已提交
582 583 584
      end

      describe 'on a commit' do
585
        let(:project) { create(:project, :repository) }
586
        let(:commit) { project.commit }
D
Dmitriy Zaporozhets 已提交
587

588 589 590
        before do
          allow(note).to receive(:noteable).and_return(commit)
        end
R
Robb Kidd 已提交
591

592
        subject { described_class.note_commit_email(recipient.id, note.id) }
R
Robb Kidd 已提交
593 594

        it_behaves_like 'a note email'
595 596 597
        it_behaves_like 'an answer to an existing thread with reply-by-email enabled' do
          let(:model) { commit }
        end
598
        it_behaves_like 'it should show Gmail Actions View Commit link'
599
        it_behaves_like 'a user cannot unsubscribe through footer link'
R
Robb Kidd 已提交
600

601 602 603 604 605
        it 'has the correct subject and body' do
          aggregate_failures do
            is_expected.to have_subject("Re: #{project.name} | #{commit.title.strip} (#{commit.short_id})")
            is_expected.to have_body_text(commit.short_id)
          end
R
Robb Kidd 已提交
606 607 608 609
        end
      end

      describe 'on a merge request' do
I
Izaak Alpert 已提交
610
        let(:merge_request) { create(:merge_request, source_project: project, target_project: project) }
611
        let(:note_on_merge_request_path) { project_merge_request_path(project, merge_request, anchor: "note_#{note.id}") }
612 613 614 615

        before do
          allow(note).to receive(:noteable).and_return(merge_request)
        end
R
Robb Kidd 已提交
616

617
        subject { described_class.note_merge_request_email(recipient.id, note.id) }
S
Sean McGivern 已提交
618

R
Robb Kidd 已提交
619
        it_behaves_like 'a note email'
620 621 622
        it_behaves_like 'an answer to an existing thread with reply-by-email enabled' do
          let(:model) { merge_request }
        end
623
        it_behaves_like 'it should show Gmail Actions View Merge request link'
624
        it_behaves_like 'an unsubscribeable thread'
R
Robb Kidd 已提交
625

626 627 628 629 630
        it 'has the correct subject and body' do
          aggregate_failures do
            is_expected.to have_referable_subject(merge_request, reply: true)
            is_expected.to have_body_text note_on_merge_request_path
          end
R
Robb Kidd 已提交
631 632 633 634
        end
      end

      describe 'on an issue' do
635
        let(:issue) { create(:issue, project: project) }
636
        let(:note_on_issue_path) { project_issue_path(project, issue, anchor: "note_#{note.id}") }
637 638 639 640

        before do
          allow(note).to receive(:noteable).and_return(issue)
        end
641

642
        subject { described_class.note_issue_email(recipient.id, note.id) }
R
Robb Kidd 已提交
643 644

        it_behaves_like 'a note email'
645 646 647
        it_behaves_like 'an answer to an existing thread with reply-by-email enabled' do
          let(:model) { issue }
        end
648
        it_behaves_like 'it should show Gmail Actions View Issue link'
649
        it_behaves_like 'an unsubscribeable thread'
R
Robb Kidd 已提交
650

651 652 653 654 655
        it 'has the correct subject and body' do
          aggregate_failures do
            is_expected.to have_referable_subject(issue, reply: true)
            is_expected.to have_body_text(note_on_issue_path)
          end
R
Robb Kidd 已提交
656 657
        end
      end
658
    end
659

D
Douwe Maan 已提交
660
    context 'items that are noteable, the email for a discussion note' do
661
      let(:project) { create(:project, :repository) }
662 663 664 665 666 667
      let(:note_author) { create(:user, name: 'author_name') }

      before :each do
        allow(Note).to receive(:find).with(note.id).and_return(note)
      end

D
Douwe Maan 已提交
668 669 670
      shared_examples 'a discussion note email' do |model|
        it_behaves_like 'it should have Gmail Actions links'

D
Douwe Maan 已提交
671
        it 'is sent to the given recipient as the author' do
D
Douwe Maan 已提交
672 673
          sender = subject.header[:from].addrs[0]

D
Douwe Maan 已提交
674 675 676 677 678
          aggregate_failures do
            expect(sender.display_name).to eq(note_author.name)
            expect(sender.address).to eq(gitlab_sender)
            expect(subject).to deliver_to(recipient.notification_email)
          end
D
Douwe Maan 已提交
679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701
        end

        it 'contains the message from the note' do
          is_expected.to have_body_text note.note
        end

        it 'contains an introduction' do
          is_expected.to have_body_text 'started a new discussion'
        end

        context 'when a comment on an existing discussion' do
          let!(:second_note) { create(model, author: note_author, noteable: nil, in_reply_to: note) }

          it 'contains an introduction' do
            is_expected.to have_body_text 'commented on a'
          end
        end
      end

      describe 'on a commit' do
        let(:commit) { project.commit }
        let(:note) { create(:discussion_note_on_commit, commit_id: commit.id, project: project, author: note_author) }

702 703 704
        before do
          allow(note).to receive(:noteable).and_return(commit)
        end
D
Douwe Maan 已提交
705

706
        subject { described_class.note_commit_email(recipient.id, note.id) }
D
Douwe Maan 已提交
707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726

        it_behaves_like 'a discussion note email', :discussion_note_on_commit
        it_behaves_like 'an answer to an existing thread with reply-by-email enabled' do
          let(:model) { commit }
        end
        it_behaves_like 'it should show Gmail Actions View Commit link'
        it_behaves_like 'a user cannot unsubscribe through footer link'

        it 'has the correct subject' do
          is_expected.to have_subject "Re: #{project.name} | #{commit.title.strip} (#{commit.short_id})"
        end

        it 'contains a link to the commit' do
          is_expected.to have_body_text commit.short_id
        end
      end

      describe 'on a merge request' do
        let(:merge_request) { create(:merge_request, source_project: project, target_project: project) }
        let(:note) { create(:discussion_note_on_merge_request, noteable: merge_request, project: project, author: note_author) }
727
        let(:note_on_merge_request_path) { project_merge_request_path(project, merge_request, anchor: "note_#{note.id}") }
728 729 730 731

        before do
          allow(note).to receive(:noteable).and_return(merge_request)
        end
D
Douwe Maan 已提交
732

733
        subject { described_class.note_merge_request_email(recipient.id, note.id) }
D
Douwe Maan 已提交
734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753

        it_behaves_like 'a discussion note email', :discussion_note_on_merge_request
        it_behaves_like 'an answer to an existing thread with reply-by-email enabled' do
          let(:model) { merge_request }
        end
        it_behaves_like 'it should show Gmail Actions View Merge request link'
        it_behaves_like 'an unsubscribeable thread'

        it 'has the correct subject' do
          is_expected.to have_referable_subject(merge_request, reply: true)
        end

        it 'contains a link to the merge request note' do
          is_expected.to have_body_text note_on_merge_request_path
        end
      end

      describe 'on an issue' do
        let(:issue) { create(:issue, project: project) }
        let(:note) { create(:discussion_note_on_issue, noteable: issue, project: project, author: note_author) }
754
        let(:note_on_issue_path) { project_issue_path(project, issue, anchor: "note_#{note.id}") }
755 756 757 758

        before do
          allow(note).to receive(:noteable).and_return(issue)
        end
D
Douwe Maan 已提交
759

760
        subject { described_class.note_issue_email(recipient.id, note.id) }
D
Douwe Maan 已提交
761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786

        it_behaves_like 'a discussion note email', :discussion_note_on_issue
        it_behaves_like 'an answer to an existing thread with reply-by-email enabled' do
          let(:model) { issue }
        end
        it_behaves_like 'it should show Gmail Actions View Issue link'
        it_behaves_like 'an unsubscribeable thread'

        it 'has the correct subject' do
          is_expected.to have_referable_subject(issue, reply: true)
        end

        it 'contains a link to the issue note' do
          is_expected.to have_body_text note_on_issue_path
        end
      end
    end

    context 'items that are noteable, the email for a diff discussion note' do
      let(:note_author) { create(:user, name: 'author_name') }

      before :each do
        allow(Note).to receive(:find).with(note.id).and_return(note)
      end

      shared_examples 'an email for a note on a diff discussion' do  |model|
D
Douwe Maan 已提交
787
        let(:note) { create(model, author: note_author) }
788 789

        it "includes diffs with character-level highlighting" do
790
          is_expected.to have_body_text '<span class="p">}</span></span>'
791 792 793
        end

        it 'contains a link to the diff file' do
794
          is_expected.to have_body_text note.diff_file.file_path
795 796 797 798
        end

        it_behaves_like 'it should have Gmail Actions links'

799
        it 'is sent to the given recipient as the author' do
800 801
          sender = subject.header[:from].addrs[0]

802 803 804 805 806
          aggregate_failures do
            expect(sender.display_name).to eq(note_author.name)
            expect(sender.address).to eq(gitlab_sender)
            expect(subject).to deliver_to(recipient.notification_email)
          end
807 808 809
        end

        it 'contains the message from the note' do
810
          is_expected.to have_html_escaped_body_text note.note
811 812
        end

D
Douwe Maan 已提交
813 814
        it 'contains an introduction' do
          is_expected.to have_body_text 'started a new discussion on'
815 816
        end

D
Douwe Maan 已提交
817 818
        context 'when a comment on an existing discussion' do
          let!(:second_note) { create(model, author: note_author, noteable: nil, in_reply_to: note) }
819

D
Douwe Maan 已提交
820 821
          it 'contains an introduction' do
            is_expected.to have_body_text 'commented on a discussion on'
822 823 824 825 826 827 828 829
          end
        end
      end

      describe 'on a commit' do
        let(:commit) { project.commit }
        let(:note) { create(:diff_note_on_commit) }

830
        subject { described_class.note_commit_email(recipient.id, note.id) }
831

D
Douwe Maan 已提交
832
        it_behaves_like 'an email for a note on a diff discussion', :diff_note_on_commit
833 834 835 836 837 838 839 840
        it_behaves_like 'it should show Gmail Actions View Commit link'
        it_behaves_like 'a user cannot unsubscribe through footer link'
      end

      describe 'on a merge request' do
        let(:merge_request) { create(:merge_request, source_project: project, target_project: project) }
        let(:note) { create(:diff_note_on_merge_request) }

841
        subject { described_class.note_merge_request_email(recipient.id, note.id) }
842

D
Douwe Maan 已提交
843
        it_behaves_like 'an email for a note on a diff discussion', :diff_note_on_merge_request
844 845 846 847
        it_behaves_like 'it should show Gmail Actions View Merge request link'
        it_behaves_like 'an unsubscribeable thread'
      end
    end
848
  end
849

850 851
  context 'for a group' do
    describe 'group access requested' do
852
      let(:group) { create(:group, :public, :access_requestable) }
853 854 855
      let(:user) { create(:user) }
      let(:group_member) do
        group.request_access(user)
856
        group.requesters.find_by(user_id: user.id)
857
      end
858
      subject { described_class.member_access_requested_email('group', group_member.id) }
R
Rémy Coutable 已提交
859

860 861 862
      it_behaves_like 'an email sent from GitLab'
      it_behaves_like 'it should not have Gmail Actions links'
      it_behaves_like "a user cannot unsubscribe through footer link"
R
Rémy Coutable 已提交
863

R
Rémy Coutable 已提交
864 865
      it 'contains all the useful information' do
        is_expected.to have_subject "Request to join the #{group.name} group"
866
        is_expected.to have_html_escaped_body_text group.name
867 868
        is_expected.to have_body_text group_group_members_url(group)
        is_expected.to have_body_text group_member.human_access
R
Rémy Coutable 已提交
869
      end
R
Rémy Coutable 已提交
870 871
    end

872 873 874 875 876
    describe 'group access denied' do
      let(:group) { create(:group) }
      let(:user) { create(:user) }
      let(:group_member) do
        group.request_access(user)
877
        group.requesters.find_by(user_id: user.id)
878
      end
879
      subject { described_class.member_access_denied_email('group', group.id, user.id) }
R
Rémy Coutable 已提交
880

881 882 883
      it_behaves_like 'an email sent from GitLab'
      it_behaves_like 'it should not have Gmail Actions links'
      it_behaves_like "a user cannot unsubscribe through footer link"
R
Rémy Coutable 已提交
884

R
Rémy Coutable 已提交
885 886
      it 'contains all the useful information' do
        is_expected.to have_subject "Access to the #{group.name} group was denied"
887
        is_expected.to have_html_escaped_body_text group.name
888
        is_expected.to have_body_text group.web_url
R
Rémy Coutable 已提交
889
      end
R
Rémy Coutable 已提交
890 891
    end

892 893 894 895
    describe 'group access changed' do
      let(:group) { create(:group) }
      let(:user) { create(:user) }
      let(:group_member) { create(:group_member, group: group, user: user) }
R
Rémy Coutable 已提交
896

897
      subject { described_class.member_access_granted_email('group', group_member.id) }
898 899 900 901 902

      it_behaves_like 'an email sent from GitLab'
      it_behaves_like 'it should not have Gmail Actions links'
      it_behaves_like "a user cannot unsubscribe through footer link"

R
Rémy Coutable 已提交
903 904
      it 'contains all the useful information' do
        is_expected.to have_subject "Access to the #{group.name} group was granted"
905
        is_expected.to have_html_escaped_body_text group.name
906 907
        is_expected.to have_body_text group.web_url
        is_expected.to have_body_text group_member.human_access
R
Rémy Coutable 已提交
908
      end
R
Rémy Coutable 已提交
909 910
    end

911 912 913 914 915 916 917 918 919
    def invite_to_group(group, inviter:)
      create(
        :group_member,
        :developer,
        group: group,
        invite_token: '1234',
        invite_email: 'toto@example.com',
        user: nil,
        created_by: inviter
920
      )
R
Rémy Coutable 已提交
921 922
    end

923 924 925
    describe 'group invitation' do
      let(:group) { create(:group) }
      let(:owner) { create(:user).tap { |u| group.add_user(u, Gitlab::Access::OWNER) } }
926
      let(:group_member) { invite_to_group(group, inviter: owner) }
927

928
      subject { described_class.member_invited_email('group', group_member.id, group_member.invite_token) }
929

930 931 932
      it_behaves_like 'an email sent from GitLab'
      it_behaves_like 'it should not have Gmail Actions links'
      it_behaves_like "a user cannot unsubscribe through footer link"
933

R
Rémy Coutable 已提交
934 935
      it 'contains all the useful information' do
        is_expected.to have_subject "Invitation to join the #{group.name} group"
936
        is_expected.to have_html_escaped_body_text group.name
937 938 939
        is_expected.to have_body_text group.web_url
        is_expected.to have_body_text group_member.human_access
        is_expected.to have_body_text group_member.invite_token
R
Rémy Coutable 已提交
940
      end
941 942
    end

943 944
    describe 'group invitation accepted' do
      let(:group) { create(:group) }
945
      let(:invited_user) { create(:user, name: 'invited user') }
946 947
      let(:owner) { create(:user).tap { |u| group.add_user(u, Gitlab::Access::OWNER) } }
      let(:group_member) do
948
        invitee = invite_to_group(group, inviter: owner)
949 950 951 952
        invitee.accept_invite!(invited_user)
        invitee
      end

953
      subject { described_class.member_invite_accepted_email('group', group_member.id) }
954 955 956 957 958

      it_behaves_like 'an email sent from GitLab'
      it_behaves_like 'it should not have Gmail Actions links'
      it_behaves_like "a user cannot unsubscribe through footer link"

R
Rémy Coutable 已提交
959 960
      it 'contains all the useful information' do
        is_expected.to have_subject 'Invitation accepted'
961
        is_expected.to have_html_escaped_body_text group.name
962 963
        is_expected.to have_body_text group.web_url
        is_expected.to have_body_text group_member.invite_email
964
        is_expected.to have_html_escaped_body_text invited_user.name
R
Rémy Coutable 已提交
965
      end
966 967
    end

968 969 970 971
    describe 'group invitation declined' do
      let(:group) { create(:group) }
      let(:owner) { create(:user).tap { |u| group.add_user(u, Gitlab::Access::OWNER) } }
      let(:group_member) do
972
        invitee = invite_to_group(group, inviter: owner)
973 974 975 976
        invitee.decline_invite!
        invitee
      end

977
      subject { described_class.member_invite_declined_email('group', group.id, group_member.invite_email, owner.id) }
978 979 980 981 982

      it_behaves_like 'an email sent from GitLab'
      it_behaves_like 'it should not have Gmail Actions links'
      it_behaves_like "a user cannot unsubscribe through footer link"

R
Rémy Coutable 已提交
983 984
      it 'contains all the useful information' do
        is_expected.to have_subject 'Invitation declined'
985
        is_expected.to have_html_escaped_body_text group.name
986 987
        is_expected.to have_body_text group.web_url
        is_expected.to have_body_text group_member.invite_email
R
Rémy Coutable 已提交
988
      end
989 990
    end
  end
991 992 993 994 995 996

  describe 'confirmation if email changed' do
    let(:example_site_path) { root_path }
    let(:user) { create(:user, email: 'old-email@mail.com') }

    before do
F
Fu Xu 已提交
997
      stub_config_setting(email_subject_suffix: 'A Nice Suffix')
V
Valery Sizov 已提交
998 999 1000 1001
      perform_enqueued_jobs do
        user.email = "new-email@mail.com"
        user.save
      end
1002 1003 1004 1005
    end

    subject { ActionMailer::Base.deliveries.last }

1006
    it_behaves_like 'an email sent from GitLab'
1007
    it_behaves_like "a user cannot unsubscribe through footer link"
1008

1009
    it 'is sent to the new user' do
1010
      is_expected.to deliver_to 'new-email@mail.com'
1011 1012
    end

1013 1014 1015 1016 1017
    it 'has the correct subject and body' do
      aggregate_failures do
        is_expected.to have_subject('Confirmation instructions | A Nice Suffix')
        is_expected.to have_body_text(example_site_path)
      end
1018 1019
    end
  end
D
Dmitriy Zaporozhets 已提交
1020

1021 1022 1023
  describe 'email on push for a created branch' do
    let(:example_site_path) { root_path }
    let(:user) { create(:user) }
1024
    let(:tree_path) { project_tree_path(project, "empty-branch") }
1025

1026
    subject { described_class.repository_push_email(project.id, author_id: user.id, ref: 'refs/heads/empty-branch', action: :create) }
1027

1028
    it_behaves_like 'it should not have Gmail Actions links'
1029
    it_behaves_like 'a user cannot unsubscribe through footer link'
1030 1031
    it_behaves_like 'an email with X-GitLab headers containing project details'
    it_behaves_like 'an email that contains a header with author username'
1032

1033 1034 1035 1036 1037 1038
    it 'is sent as the author' do
      sender = subject.header[:from].addrs[0]
      expect(sender.display_name).to eq(user.name)
      expect(sender.address).to eq(gitlab_sender)
    end

1039 1040 1041 1042 1043
    it 'has the correct subject and body' do
      aggregate_failures do
        is_expected.to have_subject("[Git][#{project.full_path}] Pushed new branch empty-branch")
        is_expected.to have_body_text(tree_path)
      end
1044 1045 1046 1047 1048 1049
    end
  end

  describe 'email on push for a created tag' do
    let(:example_site_path) { root_path }
    let(:user) { create(:user) }
1050
    let(:tree_path) { project_tree_path(project, "v1.0") }
1051

1052
    subject { described_class.repository_push_email(project.id, author_id: user.id, ref: 'refs/tags/v1.0', action: :create) }
1053

1054
    it_behaves_like 'it should not have Gmail Actions links'
1055
    it_behaves_like "a user cannot unsubscribe through footer link"
1056 1057
    it_behaves_like 'an email with X-GitLab headers containing project details'
    it_behaves_like 'an email that contains a header with author username'
1058

1059 1060 1061 1062 1063 1064
    it 'is sent as the author' do
      sender = subject.header[:from].addrs[0]
      expect(sender.display_name).to eq(user.name)
      expect(sender.address).to eq(gitlab_sender)
    end

1065 1066 1067 1068 1069
    it 'has the correct subject and body' do
      aggregate_failures do
        is_expected.to have_subject("[Git][#{project.full_path}] Pushed new tag v1.0")
        is_expected.to have_body_text(tree_path)
      end
1070 1071 1072 1073 1074 1075 1076
    end
  end

  describe 'email on push for a deleted branch' do
    let(:example_site_path) { root_path }
    let(:user) { create(:user) }

1077
    subject { described_class.repository_push_email(project.id, author_id: user.id, ref: 'refs/heads/master', action: :delete) }
1078

1079
    it_behaves_like 'it should not have Gmail Actions links'
1080
    it_behaves_like 'a user cannot unsubscribe through footer link'
1081 1082
    it_behaves_like 'an email with X-GitLab headers containing project details'
    it_behaves_like 'an email that contains a header with author username'
1083

1084 1085 1086 1087 1088 1089 1090
    it 'is sent as the author' do
      sender = subject.header[:from].addrs[0]
      expect(sender.display_name).to eq(user.name)
      expect(sender.address).to eq(gitlab_sender)
    end

    it 'has the correct subject' do
1091
      is_expected.to have_subject "[Git][#{project.full_path}] Deleted branch master"
1092 1093 1094 1095 1096 1097 1098
    end
  end

  describe 'email on push for a deleted tag' do
    let(:example_site_path) { root_path }
    let(:user) { create(:user) }

1099
    subject { described_class.repository_push_email(project.id, author_id: user.id, ref: 'refs/tags/v1.0', action: :delete) }
1100

1101
    it_behaves_like 'it should not have Gmail Actions links'
1102
    it_behaves_like 'a user cannot unsubscribe through footer link'
1103 1104
    it_behaves_like 'an email with X-GitLab headers containing project details'
    it_behaves_like 'an email that contains a header with author username'
1105

1106 1107 1108 1109 1110 1111 1112
    it 'is sent as the author' do
      sender = subject.header[:from].addrs[0]
      expect(sender.display_name).to eq(user.name)
      expect(sender.address).to eq(gitlab_sender)
    end

    it 'has the correct subject' do
1113
      is_expected.to have_subject "[Git][#{project.full_path}] Deleted tag v1.0"
1114 1115 1116
    end
  end

1117
  describe 'email on push with multiple commits' do
1118
    let(:project) { create(:project, :repository) }
D
Dmitriy Zaporozhets 已提交
1119 1120
    let(:example_site_path) { root_path }
    let(:user) { create(:user) }
1121 1122 1123
    let(:raw_compare) { Gitlab::Git::Compare.new(project.repository.raw_repository, sample_image_commit.id, sample_commit.id) }
    let(:compare) { Compare.decorate(raw_compare, project) }
    let(:commits) { compare.commits }
1124
    let(:diff_path) { project_compare_path(project, from: Commit.new(compare.base, project), to: Commit.new(compare.head, project)) }
1125
    let(:send_from_committer_email) { false }
1126
    let(:diff_refs) { Gitlab::Diff::DiffRefs.new(base_sha: project.merge_base_commit(sample_image_commit.id, sample_commit.id).id, head_sha: sample_commit.id) }
D
Dmitriy Zaporozhets 已提交
1127

1128
    subject { described_class.repository_push_email(project.id, author_id: user.id, ref: 'refs/heads/master', action: :push, compare: compare, reverse_compare: false, diff_refs: diff_refs, send_from_committer_email: send_from_committer_email) }
D
Dmitriy Zaporozhets 已提交
1129

1130
    it_behaves_like 'it should not have Gmail Actions links'
1131
    it_behaves_like 'a user cannot unsubscribe through footer link'
1132 1133
    it_behaves_like 'an email with X-GitLab headers containing project details'
    it_behaves_like 'an email that contains a header with author username'
1134

1135 1136
    it 'is sent as the author' do
      sender = subject.header[:from].addrs[0]
1137 1138
      expect(sender.display_name).to eq(user.name)
      expect(sender.address).to eq(gitlab_sender)
1139 1140
    end

1141 1142 1143 1144 1145 1146 1147 1148
    it 'has the correct subject and body' do
      aggregate_failures do
        is_expected.to have_subject("[Git][#{project.full_path}][master] #{commits.length} commits: Ruby files modified")
        is_expected.to have_body_text('Change some files')
        is_expected.to have_body_text('def</span> <span class="nf">archive_formats_regex')
        is_expected.to have_body_text(diff_path)
        is_expected.not_to have_body_text('you are a member of')
      end
1149
    end
1150 1151 1152 1153

    context "when set to send from committer email if domain matches" do
      let(:send_from_committer_email) { true }

1154 1155 1156 1157 1158
      before do
        allow(Gitlab.config.gitlab).to receive(:host).and_return("gitlab.corp.company.com")
      end

      context "when the committer email domain is within the GitLab domain" do
1159
        before do
1160
          user.update_attribute(:email, "user@company.com")
1161
          user.confirm
1162 1163 1164
        end

        it "is sent from the committer email" do
1165 1166
          from  = subject.header[:from].addrs.first
          reply = subject.header[:reply_to].addrs.first
1167

1168 1169 1170 1171
          aggregate_failures do
            expect(from.address).to eq(user.email)
            expect(reply.address).to eq(user.email)
          end
1172
        end
1173 1174
      end

1175 1176 1177
      context "when the committer email domain is not completely within the GitLab domain" do
        before do
          user.update_attribute(:email, "user@something.company.com")
1178
          user.confirm
1179 1180 1181
        end

        it "is sent from the default email" do
1182 1183
          from  = subject.header[:from].addrs.first
          reply = subject.header[:reply_to].addrs.first
1184

1185 1186 1187 1188
          aggregate_failures do
            expect(from.address).to eq(gitlab_sender)
            expect(reply.address).to eq(gitlab_sender_reply_to)
          end
1189
        end
1190 1191 1192 1193 1194
      end

      context "when the committer email domain is outside the GitLab domain" do
        before do
          user.update_attribute(:email, "user@mpany.com")
1195
          user.confirm
1196
        end
1197 1198

        it "is sent from the default email" do
1199 1200
          from = subject.header[:from].addrs.first
          reply = subject.header[:reply_to].addrs.first
1201

1202 1203 1204 1205
          aggregate_failures do
            expect(from.address).to eq(gitlab_sender)
            expect(reply.address).to eq(gitlab_sender_reply_to)
          end
1206
        end
1207 1208
      end
    end
D
Dmitriy Zaporozhets 已提交
1209
  end
1210 1211

  describe 'email on push with a single commit' do
1212
    let(:project) { create(:project, :repository) }
1213 1214
    let(:example_site_path) { root_path }
    let(:user) { create(:user) }
1215 1216 1217
    let(:raw_compare) { Gitlab::Git::Compare.new(project.repository.raw_repository, sample_commit.parent_id, sample_commit.id) }
    let(:compare) { Compare.decorate(raw_compare, project) }
    let(:commits) { compare.commits }
1218
    let(:diff_path) { project_commit_path(project, commits.first) }
1219
    let(:diff_refs) { Gitlab::Diff::DiffRefs.new(base_sha: project.merge_base_commit(sample_image_commit.id, sample_commit.id).id, head_sha: sample_commit.id) }
1220

1221
    subject { described_class.repository_push_email(project.id, author_id: user.id, ref: 'refs/heads/master', action: :push, compare: compare, diff_refs: diff_refs) }
1222

1223
    it_behaves_like 'it should show Gmail Actions View Commit link'
1224
    it_behaves_like 'a user cannot unsubscribe through footer link'
1225 1226
    it_behaves_like 'an email with X-GitLab headers containing project details'
    it_behaves_like 'an email that contains a header with author username'
1227

1228 1229
    it 'is sent as the author' do
      sender = subject.header[:from].addrs[0]
1230 1231
      expect(sender.display_name).to eq(user.name)
      expect(sender.address).to eq(gitlab_sender)
1232 1233
    end

1234 1235 1236 1237 1238 1239 1240
    it 'has the correct subject and body' do
      aggregate_failures do
        is_expected.to have_subject("[Git][#{project.full_path}][master] #{commits.first.title}")
        is_expected.to have_body_text('Change some files')
        is_expected.to have_body_text('def</span> <span class="nf">archive_formats_regex')
        is_expected.to have_body_text(diff_path)
      end
1241 1242
    end
  end
1243 1244

  describe 'HTML emails setting' do
1245
    let(:project) { create(:project) }
1246
    let(:user) { create(:user) }
1247
    let(:multipart_mail) { described_class.project_was_moved_email(project.id, user.id, "gitlab/gitlab") }
1248 1249 1250 1251 1252 1253 1254 1255 1256 1257 1258 1259 1260 1261 1262 1263 1264 1265 1266 1267 1268 1269 1270 1271 1272 1273 1274 1275 1276

    context 'when disabled' do
      it 'only sends the text template' do
        stub_application_setting(html_emails_enabled: false)

        EmailTemplateInterceptor.delivering_email(multipart_mail)

        expect(multipart_mail).to have_part_with('text/plain')
        expect(multipart_mail).not_to have_part_with('text/html')
      end
    end

    context 'when enabled' do
      it 'sends a multipart message' do
        stub_application_setting(html_emails_enabled: true)

        EmailTemplateInterceptor.delivering_email(multipart_mail)

        expect(multipart_mail).to have_part_with('text/plain')
        expect(multipart_mail).to have_part_with('text/html')
      end
    end

    matcher :have_part_with do |expected|
      match do |actual|
        actual.body.parts.any? { |part| part.content_type.try(:match, %r(#{expected})) }
      end
    end
  end
1277
end