notify_spec.rb 50.8 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 55 56
          it 'has the correct subject and body' do
            aggregate_failures do
              is_expected.to have_referable_subject(issue)
              is_expected.to have_body_text(namespace_project_issue_path(project.namespace, project, issue))
            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 102 103
          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)
              is_expected.to have_body_text(namespace_project_issue_path(project.namespace, project, issue))
            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 128 129
          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')
              is_expected.to have_body_text(namespace_project_issue_path(project.namespace, project, issue))
            end
130
          end
131 132 133 134 135 136 137 138 139

          context 'with a preferred language' do
            before { Gitlab::I18n.locale = :es }
            after { Gitlab::I18n.use_default_locale }

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

A
Alex Denisov 已提交
142 143
        describe 'status changed' do
          let(:status) { 'closed' }
144
          subject { described_class.issue_status_changed_email(recipient.id, issue.id, status, current_user.id) }
145

146 147 148
          it_behaves_like 'an answer to an existing thread with reply-by-email enabled' do
            let(:model) { issue }
          end
149
          it_behaves_like 'it should show Gmail Actions View Issue link'
150
          it_behaves_like 'an unsubscribeable thread'
151

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

158 159 160 161 162 163 164
          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)
              is_expected.to have_body_text(namespace_project_issue_path project.namespace, project, issue)
            end
A
Alex Denisov 已提交
165
          end
166
        end
167 168 169

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

172 173 174
          it_behaves_like 'an answer to an existing thread with reply-by-email enabled' do
            let(:model) { issue }
          end
175 176 177 178 179 180 181
          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

182
          it 'has the correct subject and body' do
183 184 185
            new_issue_url = namespace_project_issue_path(new_issue.project.namespace,
                                                         new_issue.project, new_issue)

186 187 188 189 190
            aggregate_failures do
              is_expected.to have_referable_subject(issue, reply: true)
              is_expected.to have_body_text(new_issue_url)
              is_expected.to have_body_text(namespace_project_issue_path(project.namespace, project, issue))
            end
191 192
          end
        end
R
Robb Kidd 已提交
193 194 195
      end

      context 'for merge requests' do
196
        let(:project) { create(:project, :repository) }
197
        let(:merge_author) { create(:user) }
198
        let(:merge_request) { create(:merge_request, author: current_user, assignee: assignee, source_project: project, target_project: project) }
199
        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 已提交
200 201

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

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

211 212 213 214 215 216 217
          it 'has the correct subject and body' do
            aggregate_failures do
              is_expected.to have_referable_subject(merge_request)
              is_expected.to have_body_text(namespace_project_merge_request_path(project.namespace, project, merge_request))
              is_expected.to have_body_text(merge_request.source_branch)
              is_expected.to have_body_text(merge_request.target_branch)
            end
R
Robb Kidd 已提交
218
          end
P
Philip Blatter 已提交
219

220 221
          context 'when enabled email_author_in_body' do
            before do
S
Sean McGivern 已提交
222
              stub_application_setting(email_author_in_body: true)
223 224 225
            end

            it 'contains a link to note author' do
226
              is_expected.to have_html_escaped_body_text merge_request.author_name
D
Douwe Maan 已提交
227
              is_expected.to have_body_text 'created a merge request:'
228 229
            end
          end
R
Robb Kidd 已提交
230 231
        end

232
        describe 'that are new with a description' do
233
          subject { described_class.new_merge_request_email(merge_request_with_description.assignee_id, merge_request_with_description.id) }
234

235
          it_behaves_like 'it should show Gmail Actions View Merge request link'
236
          it_behaves_like "an unsubscribeable thread"
237

238
          it 'contains the description' do
239
            is_expected.to have_html_escaped_body_text merge_request_with_description.description
240 241 242
          end
        end

R
Robb Kidd 已提交
243
        describe 'that are reassigned' do
244
          subject { described_class.reassigned_merge_request_email(recipient.id, merge_request.id, previous_assignee.id, current_user.id) }
R
Robb Kidd 已提交
245 246

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

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

259 260 261 262 263 264 265
          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)
              is_expected.to have_body_text(namespace_project_merge_request_path(project.namespace, project, merge_request))
              is_expected.to have_html_escaped_body_text(assignee.name)
            end
R
Robb Kidd 已提交
266
          end
267 268
        end

269
        describe 'that have been relabeled' do
270
          subject { described_class.relabeled_merge_request_email(recipient.id, merge_request.id, %w[foo bar baz], current_user.id) }
271 272

          it_behaves_like 'a multiple recipients email'
273 274 275
          it_behaves_like 'an answer to an existing thread with reply-by-email enabled' do
            let(:model) { merge_request }
          end
276 277 278 279 280 281 282 283 284 285
          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

286
          it 'has the correct subject and body' do
287
            is_expected.to have_referable_subject(merge_request, reply: true)
288 289
            is_expected.to have_body_text('foo, bar, and baz')
            is_expected.to have_body_text(namespace_project_merge_request_path(project.namespace, project, merge_request))
290 291 292
          end
        end

293 294
        describe 'status changed' do
          let(:status) { 'reopened' }
295
          subject { described_class.merge_request_status_email(recipient.id, merge_request.id, status, current_user.id) }
296

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

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

309 310 311 312 313 314 315
          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)
              is_expected.to have_body_text(namespace_project_merge_request_path(project.namespace, project, merge_request))
            end
316 317 318
          end
        end

319
        describe 'that are merged' do
320
          subject { described_class.merged_merge_request_email(recipient.id, merge_request.id, merge_author.id) }
321 322

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

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

335 336 337 338 339 340
          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')
              is_expected.to have_body_text(namespace_project_merge_request_path(project.namespace, project, merge_request))
            end
341
          end
R
Robb Kidd 已提交
342 343
        end
      end
344 345
    end

346
    describe 'project was moved' do
347
      let(:project) { create(:empty_project) }
348
      let(:user) { create(:user) }
349
      subject { described_class.project_was_moved_email(project.id, user.id, "gitlab/gitlab") }
350

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

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

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

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

        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"
387
          is_expected.to have_html_escaped_body_text project.name_with_namespace
388 389
          is_expected.to have_body_text namespace_project_project_members_url(project.namespace, project)
          is_expected.to have_body_text project_member.human_access
390
        end
R
Rémy Coutable 已提交
391 392
      end

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

404 405 406 407 408 409 410 411 412 413
        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"
414
          is_expected.to have_html_escaped_body_text project.name_with_namespace
415 416
          is_expected.to have_body_text namespace_project_project_members_url(project.namespace, project)
          is_expected.to have_body_text project_member.human_access
417
        end
R
Rémy Coutable 已提交
418
      end
R
Rémy Coutable 已提交
419 420 421
    end

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

      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 已提交
434 435
      it 'contains all the useful information' do
        is_expected.to have_subject "Access to the #{project.name_with_namespace} project was denied"
436
        is_expected.to have_html_escaped_body_text project.name_with_namespace
437
        is_expected.to have_body_text project.web_url
R
Rémy Coutable 已提交
438
      end
R
Rémy Coutable 已提交
439 440
    end

441
    describe 'project access changed' do
442 443
      let(:owner) { create(:user, name: "Chang O'Keefe") }
      let(:project) { create(:empty_project, :public, :access_requestable, namespace: owner.namespace) }
444
      let(:user) { create(:user) }
445
      let(:project_member) { create(:project_member, project: project, user: user) }
446
      subject { described_class.member_access_granted_email('project', project_member.id) }
447 448

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

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

460 461 462 463 464 465 466 467 468
    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
469
      )
470 471 472
    end

    describe 'project invitation' do
473
      let(:project) { create(:empty_project) }
474
      let(:master) { create(:user).tap { |u| project.team << [u, :master] } }
475
      let(:project_member) { invite_to_project(project, inviter: master) }
476

477
      subject { described_class.member_invited_email('project', project_member.id, project_member.invite_token) }
478 479 480 481 482

      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 已提交
483 484
      it 'contains all the useful information' do
        is_expected.to have_subject "Invitation to join the #{project.name_with_namespace} project"
485
        is_expected.to have_html_escaped_body_text project.name_with_namespace
486 487 488
        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 已提交
489
      end
490 491 492
    end

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

502
      subject { described_class.member_invite_accepted_email('project', project_member.id) }
503 504 505 506 507

      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 已提交
508 509
      it 'contains all the useful information' do
        is_expected.to have_subject 'Invitation accepted'
510
        is_expected.to have_html_escaped_body_text project.name_with_namespace
511 512
        is_expected.to have_body_text project.web_url
        is_expected.to have_body_text project_member.invite_email
513
        is_expected.to have_html_escaped_body_text invited_user.name
R
Rémy Coutable 已提交
514
      end
515 516 517
    end

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

526
      subject { described_class.member_invite_declined_email('project', project.id, project_member.invite_email, master.id) }
527 528 529 530 531

      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 已提交
532 533
      it 'contains all the useful information' do
        is_expected.to have_subject 'Invitation declined'
534
        is_expected.to have_html_escaped_body_text project.name_with_namespace
535 536
        is_expected.to have_body_text project.web_url
        is_expected.to have_body_text project_member.invite_email
R
Rémy Coutable 已提交
537
      end
538 539
    end

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

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

R
Robb Kidd 已提交
548
      shared_examples 'a note email' do
549 550
        it_behaves_like 'it should have Gmail Actions links'

551
        it 'is sent to the given recipient as the author' do
552 553
          sender = subject.header[:from].addrs[0]

554 555 556 557 558
          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 已提交
559 560 561
        end

        it 'contains the message from the note' do
562
          is_expected.to have_html_escaped_body_text note.note
R
Robb Kidd 已提交
563
        end
564

565
        it 'does not contain note author' do
D
Douwe Maan 已提交
566
          is_expected.not_to have_body_text note.author_name
567 568 569 570
        end

        context 'when enabled email_author_in_body' do
          before do
S
Sean McGivern 已提交
571
            stub_application_setting(email_author_in_body: true)
572 573 574
          end

          it 'contains a link to note author' do
575
            is_expected.to have_html_escaped_body_text note.author_name
576 577
          end
        end
R
Robb Kidd 已提交
578 579 580
      end

      describe 'on a commit' do
581
        let(:project) { create(:project, :repository) }
582
        let(:commit) { project.commit }
D
Dmitriy Zaporozhets 已提交
583

584
        before(:each) { allow(note).to receive(:noteable).and_return(commit) }
R
Robb Kidd 已提交
585

586
        subject { described_class.note_commit_email(recipient.id, note.id) }
R
Robb Kidd 已提交
587 588

        it_behaves_like 'a note email'
589 590 591
        it_behaves_like 'an answer to an existing thread with reply-by-email enabled' do
          let(:model) { commit }
        end
592
        it_behaves_like 'it should show Gmail Actions View Commit link'
593
        it_behaves_like 'a user cannot unsubscribe through footer link'
R
Robb Kidd 已提交
594

595 596 597 598 599
        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 已提交
600 601 602 603
        end
      end

      describe 'on a merge request' do
I
Izaak Alpert 已提交
604
        let(:merge_request) { create(:merge_request, source_project: project, target_project: project) }
V
Vinnie Okada 已提交
605
        let(:note_on_merge_request_path) { namespace_project_merge_request_path(project.namespace, project, merge_request, anchor: "note_#{note.id}") }
606
        before(:each) { allow(note).to receive(:noteable).and_return(merge_request) }
R
Robb Kidd 已提交
607

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

R
Robb Kidd 已提交
610
        it_behaves_like 'a note email'
611 612 613
        it_behaves_like 'an answer to an existing thread with reply-by-email enabled' do
          let(:model) { merge_request }
        end
614
        it_behaves_like 'it should show Gmail Actions View Merge request link'
615
        it_behaves_like 'an unsubscribeable thread'
R
Robb Kidd 已提交
616

617 618 619 620 621
        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 已提交
622 623 624 625
        end
      end

      describe 'on an issue' do
626
        let(:issue) { create(:issue, project: project) }
V
Vinnie Okada 已提交
627
        let(:note_on_issue_path) { namespace_project_issue_path(project.namespace, project, issue, anchor: "note_#{note.id}") }
628
        before(:each) { allow(note).to receive(:noteable).and_return(issue) }
629

630
        subject { described_class.note_issue_email(recipient.id, note.id) }
R
Robb Kidd 已提交
631 632

        it_behaves_like 'a note email'
633 634 635
        it_behaves_like 'an answer to an existing thread with reply-by-email enabled' do
          let(:model) { issue }
        end
636
        it_behaves_like 'it should show Gmail Actions View Issue link'
637
        it_behaves_like 'an unsubscribeable thread'
R
Robb Kidd 已提交
638

639 640 641 642 643
        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 已提交
644 645
        end
      end
646
    end
647

D
Douwe Maan 已提交
648
    context 'items that are noteable, the email for a discussion note' do
649
      let(:project) { create(:project, :repository) }
650 651 652 653 654 655
      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 已提交
656 657 658
      shared_examples 'a discussion note email' do |model|
        it_behaves_like 'it should have Gmail Actions links'

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

D
Douwe Maan 已提交
662 663 664 665 666
          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 已提交
667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691
        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) }

        before(:each) { allow(note).to receive(:noteable).and_return(commit) }

692
        subject { described_class.note_commit_email(recipient.id, note.id) }
D
Douwe Maan 已提交
693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715

        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) }
        let(:note_on_merge_request_path) { namespace_project_merge_request_path(project.namespace, project, merge_request, anchor: "note_#{note.id}") }
        before(:each) { allow(note).to receive(:noteable).and_return(merge_request) }

716
        subject { described_class.note_merge_request_email(recipient.id, note.id) }
D
Douwe Maan 已提交
717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739

        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) }
        let(:note_on_issue_path) { namespace_project_issue_path(project.namespace, project, issue, anchor: "note_#{note.id}") }
        before(:each) { allow(note).to receive(:noteable).and_return(issue) }

740
        subject { described_class.note_issue_email(recipient.id, note.id) }
D
Douwe Maan 已提交
741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766

        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 已提交
767
        let(:note) { create(model, author: note_author) }
768 769

        it "includes diffs with character-level highlighting" do
770
          is_expected.to have_body_text '<span class="p">}</span></span>'
771 772 773
        end

        it 'contains a link to the diff file' do
774
          is_expected.to have_body_text note.diff_file.file_path
775 776 777 778
        end

        it_behaves_like 'it should have Gmail Actions links'

779
        it 'is sent to the given recipient as the author' do
780 781
          sender = subject.header[:from].addrs[0]

782 783 784 785 786
          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
787 788 789
        end

        it 'contains the message from the note' do
790
          is_expected.to have_html_escaped_body_text note.note
791 792
        end

D
Douwe Maan 已提交
793 794
        it 'contains an introduction' do
          is_expected.to have_body_text 'started a new discussion on'
795 796
        end

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

D
Douwe Maan 已提交
800 801
          it 'contains an introduction' do
            is_expected.to have_body_text 'commented on a discussion on'
802 803 804 805 806 807 808 809
          end
        end
      end

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

810
        subject { described_class.note_commit_email(recipient.id, note.id) }
811

D
Douwe Maan 已提交
812
        it_behaves_like 'an email for a note on a diff discussion', :diff_note_on_commit
813 814 815 816 817 818 819 820
        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) }

821
        subject { described_class.note_merge_request_email(recipient.id, note.id) }
822

D
Douwe Maan 已提交
823
        it_behaves_like 'an email for a note on a diff discussion', :diff_note_on_merge_request
824 825 826 827
        it_behaves_like 'it should show Gmail Actions View Merge request link'
        it_behaves_like 'an unsubscribeable thread'
      end
    end
828
  end
829

830 831
  context 'for a group' do
    describe 'group access requested' do
832
      let(:group) { create(:group, :public, :access_requestable) }
833 834 835
      let(:user) { create(:user) }
      let(:group_member) do
        group.request_access(user)
836
        group.requesters.find_by(user_id: user.id)
837
      end
838
      subject { described_class.member_access_requested_email('group', group_member.id) }
R
Rémy Coutable 已提交
839

840 841 842
      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 已提交
843

R
Rémy Coutable 已提交
844 845
      it 'contains all the useful information' do
        is_expected.to have_subject "Request to join the #{group.name} group"
846
        is_expected.to have_html_escaped_body_text group.name
847 848
        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 已提交
849
      end
R
Rémy Coutable 已提交
850 851
    end

852 853 854 855 856
    describe 'group access denied' do
      let(:group) { create(:group) }
      let(:user) { create(:user) }
      let(:group_member) do
        group.request_access(user)
857
        group.requesters.find_by(user_id: user.id)
858
      end
859
      subject { described_class.member_access_denied_email('group', group.id, user.id) }
R
Rémy Coutable 已提交
860

861 862 863
      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 已提交
864

R
Rémy Coutable 已提交
865 866
      it 'contains all the useful information' do
        is_expected.to have_subject "Access to the #{group.name} group was denied"
867
        is_expected.to have_html_escaped_body_text group.name
868
        is_expected.to have_body_text group.web_url
R
Rémy Coutable 已提交
869
      end
R
Rémy Coutable 已提交
870 871
    end

872 873 874 875
    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 已提交
876

877
      subject { described_class.member_access_granted_email('group', group_member.id) }
878 879 880 881 882

      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 已提交
883 884
      it 'contains all the useful information' do
        is_expected.to have_subject "Access to the #{group.name} group was granted"
885
        is_expected.to have_html_escaped_body_text group.name
886 887
        is_expected.to have_body_text group.web_url
        is_expected.to have_body_text group_member.human_access
R
Rémy Coutable 已提交
888
      end
R
Rémy Coutable 已提交
889 890
    end

891 892 893 894 895 896 897 898 899
    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
900
      )
R
Rémy Coutable 已提交
901 902
    end

903 904 905
    describe 'group invitation' do
      let(:group) { create(:group) }
      let(:owner) { create(:user).tap { |u| group.add_user(u, Gitlab::Access::OWNER) } }
906
      let(:group_member) { invite_to_group(group, inviter: owner) }
907

908
      subject { described_class.member_invited_email('group', group_member.id, group_member.invite_token) }
909

910 911 912
      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"
913

R
Rémy Coutable 已提交
914 915
      it 'contains all the useful information' do
        is_expected.to have_subject "Invitation to join the #{group.name} group"
916
        is_expected.to have_html_escaped_body_text group.name
917 918 919
        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 已提交
920
      end
921 922
    end

923 924
    describe 'group invitation accepted' do
      let(:group) { create(:group) }
925
      let(:invited_user) { create(:user, name: 'invited user') }
926 927
      let(:owner) { create(:user).tap { |u| group.add_user(u, Gitlab::Access::OWNER) } }
      let(:group_member) do
928
        invitee = invite_to_group(group, inviter: owner)
929 930 931 932
        invitee.accept_invite!(invited_user)
        invitee
      end

933
      subject { described_class.member_invite_accepted_email('group', group_member.id) }
934 935 936 937 938

      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 已提交
939 940
      it 'contains all the useful information' do
        is_expected.to have_subject 'Invitation accepted'
941
        is_expected.to have_html_escaped_body_text group.name
942 943
        is_expected.to have_body_text group.web_url
        is_expected.to have_body_text group_member.invite_email
944
        is_expected.to have_html_escaped_body_text invited_user.name
R
Rémy Coutable 已提交
945
      end
946 947
    end

948 949 950 951
    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
952
        invitee = invite_to_group(group, inviter: owner)
953 954 955 956
        invitee.decline_invite!
        invitee
      end

957
      subject { described_class.member_invite_declined_email('group', group.id, group_member.invite_email, owner.id) }
958 959 960 961 962

      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 已提交
963 964
      it 'contains all the useful information' do
        is_expected.to have_subject 'Invitation declined'
965
        is_expected.to have_html_escaped_body_text group.name
966 967
        is_expected.to have_body_text group.web_url
        is_expected.to have_body_text group_member.invite_email
R
Rémy Coutable 已提交
968
      end
969 970
    end
  end
971 972 973 974 975 976

  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 已提交
977
      stub_config_setting(email_subject_suffix: 'A Nice Suffix')
V
Valery Sizov 已提交
978 979 980 981
      perform_enqueued_jobs do
        user.email = "new-email@mail.com"
        user.save
      end
982 983 984 985
    end

    subject { ActionMailer::Base.deliveries.last }

986
    it_behaves_like 'an email sent from GitLab'
987
    it_behaves_like "a user cannot unsubscribe through footer link"
988

989
    it 'is sent to the new user' do
990
      is_expected.to deliver_to 'new-email@mail.com'
991 992
    end

993 994 995 996 997
    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
998 999
    end
  end
D
Dmitriy Zaporozhets 已提交
1000

1001 1002 1003
  describe 'email on push for a created branch' do
    let(:example_site_path) { root_path }
    let(:user) { create(:user) }
1004
    let(:tree_path) { namespace_project_tree_path(project.namespace, project, "empty-branch") }
1005

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

1008
    it_behaves_like 'it should not have Gmail Actions links'
1009
    it_behaves_like 'a user cannot unsubscribe through footer link'
1010 1011
    it_behaves_like 'an email with X-GitLab headers containing project details'
    it_behaves_like 'an email that contains a header with author username'
1012

1013 1014 1015 1016 1017 1018
    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

1019 1020 1021 1022 1023
    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
1024 1025 1026 1027 1028 1029 1030 1031
    end
  end

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

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

1034
    it_behaves_like 'it should not have Gmail Actions links'
1035
    it_behaves_like "a user cannot unsubscribe through footer link"
1036 1037
    it_behaves_like 'an email with X-GitLab headers containing project details'
    it_behaves_like 'an email that contains a header with author username'
1038

1039 1040 1041 1042 1043 1044
    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

1045 1046 1047 1048 1049
    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
1050 1051 1052 1053 1054 1055 1056
    end
  end

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

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

1059
    it_behaves_like 'it should not have Gmail Actions links'
1060
    it_behaves_like 'a user cannot unsubscribe through footer link'
1061 1062
    it_behaves_like 'an email with X-GitLab headers containing project details'
    it_behaves_like 'an email that contains a header with author username'
1063

1064 1065 1066 1067 1068 1069 1070
    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
1071
      is_expected.to have_subject "[Git][#{project.full_path}] Deleted branch master"
1072 1073 1074 1075 1076 1077 1078
    end
  end

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

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

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

1086 1087 1088 1089 1090 1091 1092
    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
1093
      is_expected.to have_subject "[Git][#{project.full_path}] Deleted tag v1.0"
1094 1095 1096
    end
  end

1097
  describe 'email on push with multiple commits' do
1098
    let(:project) { create(:project, :repository) }
D
Dmitriy Zaporozhets 已提交
1099 1100
    let(:example_site_path) { root_path }
    let(:user) { create(:user) }
1101 1102 1103
    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 }
1104
    let(:diff_path) { namespace_project_compare_path(project.namespace, project, from: Commit.new(compare.base, project), to: Commit.new(compare.head, project)) }
1105
    let(:send_from_committer_email) { false }
1106
    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 已提交
1107

1108
    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 已提交
1109

1110
    it_behaves_like 'it should not have Gmail Actions links'
1111
    it_behaves_like 'a user cannot unsubscribe through footer link'
1112 1113
    it_behaves_like 'an email with X-GitLab headers containing project details'
    it_behaves_like 'an email that contains a header with author username'
1114

1115 1116
    it 'is sent as the author' do
      sender = subject.header[:from].addrs[0]
1117 1118
      expect(sender.display_name).to eq(user.name)
      expect(sender.address).to eq(gitlab_sender)
1119 1120
    end

1121 1122 1123 1124 1125 1126 1127 1128
    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
1129
    end
1130 1131 1132 1133

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

1134 1135 1136 1137 1138
      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
1139
        before do
1140
          user.update_attribute(:email, "user@company.com")
1141
          user.confirm
1142 1143 1144
        end

        it "is sent from the committer email" do
1145 1146
          from  = subject.header[:from].addrs.first
          reply = subject.header[:reply_to].addrs.first
1147

1148 1149 1150 1151
          aggregate_failures do
            expect(from.address).to eq(user.email)
            expect(reply.address).to eq(user.email)
          end
1152
        end
1153 1154
      end

1155 1156 1157
      context "when the committer email domain is not completely within the GitLab domain" do
        before do
          user.update_attribute(:email, "user@something.company.com")
1158
          user.confirm
1159 1160 1161
        end

        it "is sent from the default email" do
1162 1163
          from  = subject.header[:from].addrs.first
          reply = subject.header[:reply_to].addrs.first
1164

1165 1166 1167 1168
          aggregate_failures do
            expect(from.address).to eq(gitlab_sender)
            expect(reply.address).to eq(gitlab_sender_reply_to)
          end
1169
        end
1170 1171 1172 1173 1174
      end

      context "when the committer email domain is outside the GitLab domain" do
        before do
          user.update_attribute(:email, "user@mpany.com")
1175
          user.confirm
1176
        end
1177 1178

        it "is sent from the default email" do
1179 1180
          from = subject.header[:from].addrs.first
          reply = subject.header[:reply_to].addrs.first
1181

1182 1183 1184 1185
          aggregate_failures do
            expect(from.address).to eq(gitlab_sender)
            expect(reply.address).to eq(gitlab_sender_reply_to)
          end
1186
        end
1187 1188
      end
    end
D
Dmitriy Zaporozhets 已提交
1189
  end
1190 1191

  describe 'email on push with a single commit' do
1192
    let(:project) { create(:project, :repository) }
1193 1194
    let(:example_site_path) { root_path }
    let(:user) { create(:user) }
1195 1196 1197
    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 }
V
Vinnie Okada 已提交
1198
    let(:diff_path) { namespace_project_commit_path(project.namespace, project, commits.first) }
1199
    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) }
1200

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

1203
    it_behaves_like 'it should show Gmail Actions View Commit link'
1204
    it_behaves_like 'a user cannot unsubscribe through footer link'
1205 1206
    it_behaves_like 'an email with X-GitLab headers containing project details'
    it_behaves_like 'an email that contains a header with author username'
1207

1208 1209
    it 'is sent as the author' do
      sender = subject.header[:from].addrs[0]
1210 1211
      expect(sender.display_name).to eq(user.name)
      expect(sender.address).to eq(gitlab_sender)
1212 1213
    end

1214 1215 1216 1217 1218 1219 1220
    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
1221 1222
    end
  end
1223 1224

  describe 'HTML emails setting' do
1225
    let(:project) { create(:empty_project) }
1226
    let(:user) { create(:user) }
1227
    let(:multipart_mail) { described_class.project_was_moved_email(project.id, user.id, "gitlab/gitlab") }
1228 1229 1230 1231 1232 1233 1234 1235 1236 1237 1238 1239 1240 1241 1242 1243 1244 1245 1246 1247 1248 1249 1250 1251 1252 1253 1254 1255 1256

    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
1257
end