notify_spec.rb 50.1 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
        let(:issue) { create(:issue, author: current_user, assignee: assignee, project: project) }
40
        let(:issue_with_description) { create(:issue, author: current_user, assignee: assignee, project: project, description: 'My awesome description') }
41

R
Robb Kidd 已提交
42
        describe 'that are new' do
43
          subject { Notify.new_issue_email(issue.assignee_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 72 73
        describe 'that are new with a description' do
          subject { Notify.new_issue_email(issue_with_description.assignee_id, issue_with_description.id) }

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
V
Valery Sizov 已提交
82
          subject { Notify.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 108 109 110
        describe 'that have been relabeled' do
          subject { Notify.relabeled_issue_email(recipient.id, issue.id, %w[foo bar baz], current_user.id) }

          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 131 132
          end
        end

A
Alex Denisov 已提交
133 134
        describe 'status changed' do
          let(:status) { 'closed' }
V
Valery Sizov 已提交
135
          subject { Notify.issue_status_changed_email(recipient.id, issue.id, status, current_user.id) }
136

137 138 139
          it_behaves_like 'an answer to an existing thread with reply-by-email enabled' do
            let(:model) { issue }
          end
140
          it_behaves_like 'it should show Gmail Actions View Issue link'
141
          it_behaves_like 'an unsubscribeable thread'
142

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

149 150 151 152 153 154 155
          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 已提交
156
          end
157
        end
158 159 160 161 162

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

163 164 165
          it_behaves_like 'an answer to an existing thread with reply-by-email enabled' do
            let(:model) { issue }
          end
166 167 168 169 170 171 172
          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

173
          it 'has the correct subject and body' do
174 175 176
            new_issue_url = namespace_project_issue_path(new_issue.project.namespace,
                                                         new_issue.project, new_issue)

177 178 179 180 181
            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
182 183
          end
        end
R
Robb Kidd 已提交
184 185 186
      end

      context 'for merge requests' do
187
        let(:project) { create(:project, :repository) }
188
        let(:merge_author) { create(:user) }
189
        let(:merge_request) { create(:merge_request, author: current_user, assignee: assignee, source_project: project, target_project: project) }
190
        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 已提交
191 192

        describe 'that are new' do
193
          subject { Notify.new_merge_request_email(merge_request.assignee_id, merge_request.id) }
R
Robb Kidd 已提交
194 195

          it_behaves_like 'an assignee email'
196 197 198
          it_behaves_like 'an email starting a new thread with reply-by-email enabled' do
            let(:model) { merge_request }
          end
199
          it_behaves_like 'it should show Gmail Actions View Merge request link'
200
          it_behaves_like 'an unsubscribeable thread'
R
Robb Kidd 已提交
201

202 203 204 205 206 207 208
          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 已提交
209
          end
P
Philip Blatter 已提交
210

211 212
          context 'when enabled email_author_in_body' do
            before do
S
Sean McGivern 已提交
213
              stub_application_setting(email_author_in_body: true)
214 215 216
            end

            it 'contains a link to note author' do
217
              is_expected.to have_html_escaped_body_text merge_request.author_name
D
Douwe Maan 已提交
218
              is_expected.to have_body_text 'created a merge request:'
219 220
            end
          end
R
Robb Kidd 已提交
221 222
        end

223 224 225
        describe 'that are new with a description' do
          subject { Notify.new_merge_request_email(merge_request_with_description.assignee_id, merge_request_with_description.id) }

226
          it_behaves_like 'it should show Gmail Actions View Merge request link'
227
          it_behaves_like "an unsubscribeable thread"
228

229
          it 'contains the description' do
230
            is_expected.to have_html_escaped_body_text merge_request_with_description.description
231 232 233
          end
        end

R
Robb Kidd 已提交
234
        describe 'that are reassigned' do
235
          subject { Notify.reassigned_merge_request_email(recipient.id, merge_request.id, previous_assignee.id, current_user.id) }
R
Robb Kidd 已提交
236 237

          it_behaves_like 'a multiple recipients email'
238 239 240
          it_behaves_like 'an answer to an existing thread with reply-by-email enabled' do
            let(:model) { merge_request }
          end
241
          it_behaves_like 'it should show Gmail Actions View Merge request link'
242
          it_behaves_like "an unsubscribeable thread"
R
Robb Kidd 已提交
243

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

250 251 252 253 254 255 256
          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 已提交
257
          end
258 259
        end

260 261 262 263
        describe 'that have been relabeled' do
          subject { Notify.relabeled_merge_request_email(recipient.id, merge_request.id, %w[foo bar baz], current_user.id) }

          it_behaves_like 'a multiple recipients email'
264 265 266
          it_behaves_like 'an answer to an existing thread with reply-by-email enabled' do
            let(:model) { merge_request }
          end
267 268 269 270 271 272 273 274 275 276
          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

277
          it 'has the correct subject and body' do
278
            is_expected.to have_referable_subject(merge_request, reply: true)
279 280
            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))
281 282 283
          end
        end

284 285
        describe 'status changed' do
          let(:status) { 'reopened' }
V
Valery Sizov 已提交
286
          subject { Notify.merge_request_status_email(recipient.id, merge_request.id, status, current_user.id) }
287

288 289 290
          it_behaves_like 'an answer to an existing thread with reply-by-email enabled' do
            let(:model) { merge_request }
          end
291
          it_behaves_like 'it should show Gmail Actions View Merge request link'
292
          it_behaves_like 'an unsubscribeable thread'
293 294 295

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

300 301 302 303 304 305 306
          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
307 308 309
          end
        end

310 311 312 313
        describe 'that are merged' do
          subject { Notify.merged_merge_request_email(recipient.id, merge_request.id, merge_author.id) }

          it_behaves_like 'a multiple recipients email'
314 315 316
          it_behaves_like 'an answer to an existing thread with reply-by-email enabled' do
            let(:model) { merge_request }
          end
317
          it_behaves_like 'it should show Gmail Actions View Merge request link'
318
          it_behaves_like 'an unsubscribeable thread'
319 320 321

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

326 327 328 329 330 331
          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
332
          end
R
Robb Kidd 已提交
333 334
        end
      end
335 336
    end

337
    describe 'project was moved' do
338
      let(:project) { create(:empty_project) }
339
      let(:user) { create(:user) }
340
      subject { Notify.project_was_moved_email(project.id, user.id, "gitlab/gitlab") }
341

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

346 347
      it 'has the correct subject and body' do
        is_expected.to have_subject("#{project.name} | Project was moved")
348
        is_expected.to have_html_escaped_body_text project.name_with_namespace
349
        is_expected.to have_body_text(project.ssh_url_to_repo)
350 351 352
      end
    end

R
Rémy Coutable 已提交
353
    describe 'project access requested' do
354
      context 'for a project in a user namespace' do
355 356 357 358 359 360
        let(:project) do
          create(:empty_project, :public, :access_requestable) do |project|
            project.team << [project.owner, :master, project.owner]
          end
        end

361 362 363
        let(:user) { create(:user) }
        let(:project_member) do
          project.request_access(user)
364
          project.requesters.find_by(user_id: user.id)
365 366 367 368 369 370 371 372 373 374 375 376 377
        end
        subject { Notify.member_access_requested_email('project', project_member.id) }

        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"
378
          is_expected.to have_html_escaped_body_text project.name_with_namespace
379 380
          is_expected.to have_body_text namespace_project_project_members_url(project.namespace, project)
          is_expected.to have_body_text project_member.human_access
381
        end
R
Rémy Coutable 已提交
382 383
      end

384 385 386
      context 'for a project in a group' do
        let(:group_owner) { create(:user) }
        let(:group) { create(:group).tap { |g| g.add_owner(group_owner) } }
387
        let(:project) { create(:empty_project, :public, :access_requestable, namespace: group) }
388 389 390
        let(:user) { create(:user) }
        let(:project_member) do
          project.request_access(user)
391
          project.requesters.find_by(user_id: user.id)
392 393
        end
        subject { Notify.member_access_requested_email('project', project_member.id) }
R
Rémy Coutable 已提交
394

395 396 397 398 399 400 401 402 403 404
        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"
405
          is_expected.to have_html_escaped_body_text project.name_with_namespace
406 407
          is_expected.to have_body_text namespace_project_project_members_url(project.namespace, project)
          is_expected.to have_body_text project_member.human_access
408
        end
R
Rémy Coutable 已提交
409
      end
R
Rémy Coutable 已提交
410 411 412
    end

    describe 'project access denied' do
413
      let(:project) { create(:empty_project, :public, :access_requestable) }
R
Rémy Coutable 已提交
414 415 416
      let(:user) { create(:user) }
      let(:project_member) do
        project.request_access(user)
417
        project.requesters.find_by(user_id: user.id)
R
Rémy Coutable 已提交
418
      end
419
      subject { Notify.member_access_denied_email('project', project.id, user.id) }
R
Rémy Coutable 已提交
420 421 422 423 424

      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 已提交
425 426
      it 'contains all the useful information' do
        is_expected.to have_subject "Access to the #{project.name_with_namespace} project was denied"
427
        is_expected.to have_html_escaped_body_text project.name_with_namespace
428
        is_expected.to have_body_text project.web_url
R
Rémy Coutable 已提交
429
      end
R
Rémy Coutable 已提交
430 431
    end

432
    describe 'project access changed' do
433 434
      let(:owner) { create(:user, name: "Chang O'Keefe") }
      let(:project) { create(:empty_project, :public, :access_requestable, namespace: owner.namespace) }
435
      let(:user) { create(:user) }
436
      let(:project_member) { create(:project_member, project: project, user: user) }
437
      subject { Notify.member_access_granted_email('project', project_member.id) }
438 439

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

R
Rémy Coutable 已提交
443 444
      it 'contains all the useful information' do
        is_expected.to have_subject "Access to the #{project.name_with_namespace} project was granted"
445
        is_expected.to have_html_escaped_body_text project.name_with_namespace
446 447
        is_expected.to have_body_text project.web_url
        is_expected.to have_body_text project_member.human_access
R
Rémy Coutable 已提交
448
      end
449
    end
450

451 452 453 454 455 456 457 458 459
    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
460
      )
461 462 463
    end

    describe 'project invitation' do
464
      let(:project) { create(:empty_project) }
465
      let(:master) { create(:user).tap { |u| project.team << [u, :master] } }
466
      let(:project_member) { invite_to_project(project, inviter: master) }
467 468 469 470 471 472 473

      subject { Notify.member_invited_email('project', project_member.id, project_member.invite_token) }

      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 已提交
474 475
      it 'contains all the useful information' do
        is_expected.to have_subject "Invitation to join the #{project.name_with_namespace} project"
476
        is_expected.to have_html_escaped_body_text project.name_with_namespace
477 478 479
        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 已提交
480
      end
481 482 483
    end

    describe 'project invitation accepted' do
484
      let(:project) { create(:empty_project) }
485
      let(:invited_user) { create(:user, name: 'invited user') }
486 487
      let(:master) { create(:user).tap { |u| project.team << [u, :master] } }
      let(:project_member) do
488
        invitee = invite_to_project(project, inviter: master)
489 490
        invitee.accept_invite!(invited_user)
        invitee
491
      end
492

493 494 495 496 497 498
      subject { Notify.member_invite_accepted_email('project', project_member.id) }

      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 已提交
499 500
      it 'contains all the useful information' do
        is_expected.to have_subject 'Invitation accepted'
501
        is_expected.to have_html_escaped_body_text project.name_with_namespace
502 503
        is_expected.to have_body_text project.web_url
        is_expected.to have_body_text project_member.invite_email
504
        is_expected.to have_html_escaped_body_text invited_user.name
R
Rémy Coutable 已提交
505
      end
506 507 508
    end

    describe 'project invitation declined' do
509
      let(:project) { create(:empty_project) }
510 511
      let(:master) { create(:user).tap { |u| project.team << [u, :master] } }
      let(:project_member) do
512
        invitee = invite_to_project(project, inviter: master)
513 514
        invitee.decline_invite!
        invitee
515
      end
516 517 518 519 520 521 522

      subject { Notify.member_invite_declined_email('project', project.id, project_member.invite_email, master.id) }

      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 已提交
523 524
      it 'contains all the useful information' do
        is_expected.to have_subject 'Invitation declined'
525
        is_expected.to have_html_escaped_body_text project.name_with_namespace
526 527
        is_expected.to have_body_text project.web_url
        is_expected.to have_body_text project_member.invite_email
R
Rémy Coutable 已提交
528
      end
529 530
    end

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

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

R
Robb Kidd 已提交
539
      shared_examples 'a note email' do
540 541
        it_behaves_like 'it should have Gmail Actions links'

542
        it 'is sent to the given recipient as the author' do
543 544
          sender = subject.header[:from].addrs[0]

545 546 547 548 549
          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 已提交
550 551 552
        end

        it 'contains the message from the note' do
553
          is_expected.to have_html_escaped_body_text note.note
R
Robb Kidd 已提交
554
        end
555

556
        it 'does not contain note author' do
D
Douwe Maan 已提交
557
          is_expected.not_to have_body_text note.author_name
558 559 560 561
        end

        context 'when enabled email_author_in_body' do
          before do
S
Sean McGivern 已提交
562
            stub_application_setting(email_author_in_body: true)
563 564 565
          end

          it 'contains a link to note author' do
566
            is_expected.to have_html_escaped_body_text note.author_name
567 568
          end
        end
R
Robb Kidd 已提交
569 570 571
      end

      describe 'on a commit' do
572
        let(:project) { create(:project, :repository) }
573
        let(:commit) { project.commit }
D
Dmitriy Zaporozhets 已提交
574

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

D
Dmitriy Zaporozhets 已提交
577
        subject { Notify.note_commit_email(recipient.id, note.id) }
R
Robb Kidd 已提交
578 579

        it_behaves_like 'a note email'
580 581 582
        it_behaves_like 'an answer to an existing thread with reply-by-email enabled' do
          let(:model) { commit }
        end
583
        it_behaves_like 'it should show Gmail Actions View Commit link'
584
        it_behaves_like 'a user cannot unsubscribe through footer link'
R
Robb Kidd 已提交
585

586 587 588 589 590
        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 已提交
591 592 593 594
        end
      end

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

599
        subject { Notify.note_merge_request_email(recipient.id, note.id) }
S
Sean McGivern 已提交
600

R
Robb Kidd 已提交
601
        it_behaves_like 'a note email'
602 603 604
        it_behaves_like 'an answer to an existing thread with reply-by-email enabled' do
          let(:model) { merge_request }
        end
605
        it_behaves_like 'it should show Gmail Actions View Merge request link'
606
        it_behaves_like 'an unsubscribeable thread'
R
Robb Kidd 已提交
607

608 609 610 611 612
        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 已提交
613 614 615 616
        end
      end

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

        subject { Notify.note_issue_email(recipient.id, note.id) }
R
Robb Kidd 已提交
622 623

        it_behaves_like 'a note email'
624 625 626
        it_behaves_like 'an answer to an existing thread with reply-by-email enabled' do
          let(:model) { issue }
        end
627
        it_behaves_like 'it should show Gmail Actions View Issue link'
628
        it_behaves_like 'an unsubscribeable thread'
R
Robb Kidd 已提交
629

630 631 632 633 634
        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 已提交
635 636
        end
      end
637
    end
638

D
Douwe Maan 已提交
639
    context 'items that are noteable, the email for a discussion note' do
640
      let(:project) { create(:project, :repository) }
641 642 643 644 645 646
      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 已提交
647 648 649
      shared_examples 'a discussion note email' do |model|
        it_behaves_like 'it should have Gmail Actions links'

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

D
Douwe Maan 已提交
653 654 655 656 657
          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 已提交
658 659 660 661 662 663 664 665 666 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 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757
        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) }

        subject { Notify.note_commit_email(recipient.id, note.id) }

        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) }

        subject { Notify.note_merge_request_email(recipient.id, note.id) }

        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) }

        subject { Notify.note_issue_email(recipient.id, note.id) }

        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 已提交
758
        let(:note) { create(model, author: note_author) }
759 760

        it "includes diffs with character-level highlighting" do
761
          is_expected.to have_body_text '<span class="p">}</span></span>'
762 763 764
        end

        it 'contains a link to the diff file' do
765
          is_expected.to have_body_text note.diff_file.file_path
766 767 768 769
        end

        it_behaves_like 'it should have Gmail Actions links'

770
        it 'is sent to the given recipient as the author' do
771 772
          sender = subject.header[:from].addrs[0]

773 774 775 776 777
          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
778 779 780
        end

        it 'contains the message from the note' do
781
          is_expected.to have_html_escaped_body_text note.note
782 783
        end

D
Douwe Maan 已提交
784 785
        it 'contains an introduction' do
          is_expected.to have_body_text 'started a new discussion on'
786 787
        end

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

D
Douwe Maan 已提交
791 792
          it 'contains an introduction' do
            is_expected.to have_body_text 'commented on a discussion on'
793 794 795 796 797 798 799 800 801 802
          end
        end
      end

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

        subject { Notify.note_commit_email(recipient.id, note.id) }

D
Douwe Maan 已提交
803
        it_behaves_like 'an email for a note on a diff discussion', :diff_note_on_commit
804 805 806 807 808 809 810 811 812 813
        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) }

        subject { Notify.note_merge_request_email(recipient.id, note.id) }

D
Douwe Maan 已提交
814
        it_behaves_like 'an email for a note on a diff discussion', :diff_note_on_merge_request
815 816 817 818
        it_behaves_like 'it should show Gmail Actions View Merge request link'
        it_behaves_like 'an unsubscribeable thread'
      end
    end
819
  end
820

821 822
  context 'for a group' do
    describe 'group access requested' do
823
      let(:group) { create(:group, :public, :access_requestable) }
824 825 826
      let(:user) { create(:user) }
      let(:group_member) do
        group.request_access(user)
827
        group.requesters.find_by(user_id: user.id)
828 829
      end
      subject { Notify.member_access_requested_email('group', group_member.id) }
R
Rémy Coutable 已提交
830

831 832 833
      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 已提交
834

R
Rémy Coutable 已提交
835 836
      it 'contains all the useful information' do
        is_expected.to have_subject "Request to join the #{group.name} group"
837
        is_expected.to have_html_escaped_body_text group.name
838 839
        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 已提交
840
      end
R
Rémy Coutable 已提交
841 842
    end

843 844 845 846 847
    describe 'group access denied' do
      let(:group) { create(:group) }
      let(:user) { create(:user) }
      let(:group_member) do
        group.request_access(user)
848
        group.requesters.find_by(user_id: user.id)
849 850
      end
      subject { Notify.member_access_denied_email('group', group.id, user.id) }
R
Rémy Coutable 已提交
851

852 853 854
      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 已提交
855

R
Rémy Coutable 已提交
856 857
      it 'contains all the useful information' do
        is_expected.to have_subject "Access to the #{group.name} group was denied"
858
        is_expected.to have_html_escaped_body_text group.name
859
        is_expected.to have_body_text group.web_url
R
Rémy Coutable 已提交
860
      end
R
Rémy Coutable 已提交
861 862
    end

863 864 865 866
    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 已提交
867

868 869 870 871 872 873
      subject { Notify.member_access_granted_email('group', group_member.id) }

      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 已提交
874 875
      it 'contains all the useful information' do
        is_expected.to have_subject "Access to the #{group.name} group was granted"
876
        is_expected.to have_html_escaped_body_text group.name
877 878
        is_expected.to have_body_text group.web_url
        is_expected.to have_body_text group_member.human_access
R
Rémy Coutable 已提交
879
      end
R
Rémy Coutable 已提交
880 881
    end

882 883 884 885 886 887 888 889 890
    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
891
      )
R
Rémy Coutable 已提交
892 893
    end

894 895 896
    describe 'group invitation' do
      let(:group) { create(:group) }
      let(:owner) { create(:user).tap { |u| group.add_user(u, Gitlab::Access::OWNER) } }
897
      let(:group_member) { invite_to_group(group, inviter: owner) }
898

899
      subject { Notify.member_invited_email('group', group_member.id, group_member.invite_token) }
900

901 902 903
      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"
904

R
Rémy Coutable 已提交
905 906
      it 'contains all the useful information' do
        is_expected.to have_subject "Invitation to join the #{group.name} group"
907
        is_expected.to have_html_escaped_body_text group.name
908 909 910
        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 已提交
911
      end
912 913
    end

914 915
    describe 'group invitation accepted' do
      let(:group) { create(:group) }
916
      let(:invited_user) { create(:user, name: 'invited user') }
917 918
      let(:owner) { create(:user).tap { |u| group.add_user(u, Gitlab::Access::OWNER) } }
      let(:group_member) do
919
        invitee = invite_to_group(group, inviter: owner)
920 921 922 923 924 925 926 927 928 929
        invitee.accept_invite!(invited_user)
        invitee
      end

      subject { Notify.member_invite_accepted_email('group', group_member.id) }

      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 已提交
930 931
      it 'contains all the useful information' do
        is_expected.to have_subject 'Invitation accepted'
932
        is_expected.to have_html_escaped_body_text group.name
933 934
        is_expected.to have_body_text group.web_url
        is_expected.to have_body_text group_member.invite_email
935
        is_expected.to have_html_escaped_body_text invited_user.name
R
Rémy Coutable 已提交
936
      end
937 938
    end

939 940 941 942
    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
943
        invitee = invite_to_group(group, inviter: owner)
944 945 946 947 948 949 950 951 952 953
        invitee.decline_invite!
        invitee
      end

      subject { Notify.member_invite_declined_email('group', group.id, group_member.invite_email, owner.id) }

      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 已提交
954 955
      it 'contains all the useful information' do
        is_expected.to have_subject 'Invitation declined'
956
        is_expected.to have_html_escaped_body_text group.name
957 958
        is_expected.to have_body_text group.web_url
        is_expected.to have_body_text group_member.invite_email
R
Rémy Coutable 已提交
959
      end
960 961
    end
  end
962 963 964 965 966 967

  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 已提交
968
      stub_config_setting(email_subject_suffix: 'A Nice Suffix')
V
Valery Sizov 已提交
969 970 971 972
      perform_enqueued_jobs do
        user.email = "new-email@mail.com"
        user.save
      end
973 974 975 976
    end

    subject { ActionMailer::Base.deliveries.last }

977
    it_behaves_like 'an email sent from GitLab'
978
    it_behaves_like "a user cannot unsubscribe through footer link"
979

980
    it 'is sent to the new user' do
981
      is_expected.to deliver_to 'new-email@mail.com'
982 983
    end

984 985 986 987 988
    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
989 990
    end
  end
D
Dmitriy Zaporozhets 已提交
991

992 993 994
  describe 'email on push for a created branch' do
    let(:example_site_path) { root_path }
    let(:user) { create(:user) }
995
    let(:tree_path) { namespace_project_tree_path(project.namespace, project, "empty-branch") }
996

997
    subject { Notify.repository_push_email(project.id, author_id: user.id, ref: 'refs/heads/empty-branch', action: :create) }
998

999
    it_behaves_like 'it should not have Gmail Actions links'
1000
    it_behaves_like 'a user cannot unsubscribe through footer link'
1001 1002
    it_behaves_like 'an email with X-GitLab headers containing project details'
    it_behaves_like 'an email that contains a header with author username'
1003

1004 1005 1006 1007 1008 1009
    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

1010 1011 1012 1013 1014
    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
1015 1016 1017 1018 1019 1020 1021 1022
    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") }

1023
    subject { Notify.repository_push_email(project.id, author_id: user.id, ref: 'refs/tags/v1.0', action: :create) }
1024

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

1030 1031 1032 1033 1034 1035
    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

1036 1037 1038 1039 1040
    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
1041 1042 1043 1044 1045 1046 1047
    end
  end

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

1048
    subject { Notify.repository_push_email(project.id, author_id: user.id, ref: 'refs/heads/master', action: :delete) }
1049

1050
    it_behaves_like 'it should not have Gmail Actions links'
1051
    it_behaves_like 'a user cannot unsubscribe through footer link'
1052 1053
    it_behaves_like 'an email with X-GitLab headers containing project details'
    it_behaves_like 'an email that contains a header with author username'
1054

1055 1056 1057 1058 1059 1060 1061
    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
1062
      is_expected.to have_subject "[Git][#{project.full_path}] Deleted branch master"
1063 1064 1065 1066 1067 1068 1069
    end
  end

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

1070
    subject { Notify.repository_push_email(project.id, author_id: user.id, ref: 'refs/tags/v1.0', action: :delete) }
1071

1072
    it_behaves_like 'it should not have Gmail Actions links'
1073
    it_behaves_like 'a user cannot unsubscribe through footer link'
1074 1075
    it_behaves_like 'an email with X-GitLab headers containing project details'
    it_behaves_like 'an email that contains a header with author username'
1076

1077 1078 1079 1080 1081 1082 1083
    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
1084
      is_expected.to have_subject "[Git][#{project.full_path}] Deleted tag v1.0"
1085 1086 1087
    end
  end

1088
  describe 'email on push with multiple commits' do
1089
    let(:project) { create(:project, :repository) }
D
Dmitriy Zaporozhets 已提交
1090 1091
    let(:example_site_path) { root_path }
    let(:user) { create(:user) }
1092 1093 1094
    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 }
1095
    let(:diff_path) { namespace_project_compare_path(project.namespace, project, from: Commit.new(compare.base, project), to: Commit.new(compare.head, project)) }
1096
    let(:send_from_committer_email) { false }
1097
    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 已提交
1098

1099
    subject { Notify.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 已提交
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
    it 'is sent as the author' do
      sender = subject.header[:from].addrs[0]
1108 1109
      expect(sender.display_name).to eq(user.name)
      expect(sender.address).to eq(gitlab_sender)
1110 1111
    end

1112 1113 1114 1115 1116 1117 1118 1119
    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
1120
    end
1121 1122 1123 1124

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

1125 1126 1127 1128 1129
      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
1130
        before do
1131
          user.update_attribute(:email, "user@company.com")
1132
          user.confirm
1133 1134 1135
        end

        it "is sent from the committer email" do
1136 1137
          from  = subject.header[:from].addrs.first
          reply = subject.header[:reply_to].addrs.first
1138

1139 1140 1141 1142
          aggregate_failures do
            expect(from.address).to eq(user.email)
            expect(reply.address).to eq(user.email)
          end
1143
        end
1144 1145
      end

1146 1147 1148
      context "when the committer email domain is not completely within the GitLab domain" do
        before do
          user.update_attribute(:email, "user@something.company.com")
1149
          user.confirm
1150 1151 1152
        end

        it "is sent from the default email" do
1153 1154
          from  = subject.header[:from].addrs.first
          reply = subject.header[:reply_to].addrs.first
1155

1156 1157 1158 1159
          aggregate_failures do
            expect(from.address).to eq(gitlab_sender)
            expect(reply.address).to eq(gitlab_sender_reply_to)
          end
1160
        end
1161 1162 1163 1164 1165
      end

      context "when the committer email domain is outside the GitLab domain" do
        before do
          user.update_attribute(:email, "user@mpany.com")
1166
          user.confirm
1167
        end
1168 1169

        it "is sent from the default email" do
1170 1171
          from = subject.header[:from].addrs.first
          reply = subject.header[:reply_to].addrs.first
1172

1173 1174 1175 1176
          aggregate_failures do
            expect(from.address).to eq(gitlab_sender)
            expect(reply.address).to eq(gitlab_sender_reply_to)
          end
1177
        end
1178 1179
      end
    end
D
Dmitriy Zaporozhets 已提交
1180
  end
1181 1182

  describe 'email on push with a single commit' do
1183
    let(:project) { create(:project, :repository) }
1184 1185
    let(:example_site_path) { root_path }
    let(:user) { create(:user) }
1186 1187 1188
    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 已提交
1189
    let(:diff_path) { namespace_project_commit_path(project.namespace, project, commits.first) }
1190
    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) }
1191

1192
    subject { Notify.repository_push_email(project.id, author_id: user.id, ref: 'refs/heads/master', action: :push, compare: compare, diff_refs: diff_refs) }
1193

1194
    it_behaves_like 'it should show Gmail Actions View Commit link'
1195
    it_behaves_like 'a user cannot unsubscribe through footer link'
1196 1197
    it_behaves_like 'an email with X-GitLab headers containing project details'
    it_behaves_like 'an email that contains a header with author username'
1198

1199 1200
    it 'is sent as the author' do
      sender = subject.header[:from].addrs[0]
1201 1202
      expect(sender.display_name).to eq(user.name)
      expect(sender.address).to eq(gitlab_sender)
1203 1204
    end

1205 1206 1207 1208 1209 1210 1211
    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
1212 1213
    end
  end
1214 1215

  describe 'HTML emails setting' do
1216
    let(:project) { create(:empty_project) }
1217 1218 1219 1220 1221 1222 1223 1224 1225 1226 1227 1228 1229 1230 1231 1232 1233 1234 1235 1236 1237 1238 1239 1240 1241 1242 1243 1244 1245 1246 1247
    let(:user) { create(:user) }
    let(:multipart_mail) { Notify.project_was_moved_email(project.id, user.id, "gitlab/gitlab") }

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