notify_spec.rb 42.6 KB
Newer Older
1
require 'spec_helper'
R
Robert Speicher 已提交
2
require 'email_spec'
3
require 'mailers/shared/notify'
4 5 6 7

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

10
  include_context 'gitlab email notification'
11

R
Robb Kidd 已提交
12 13
  context 'for a project' do
    describe 'items that are assignable, the email' do
14
      let(:current_user) { create(:user, email: "current@email.com") }
15
      let(:assignee) { create(:user, email: 'assignee@example.com', name: 'John Doe') }
16
      let(:previous_assignee) { create(:user, name: 'Previous Assignee') }
17

R
Robb Kidd 已提交
18
      shared_examples 'an assignee email' do
19 20
        it 'is sent as the author' do
          sender = subject.header[:from].addrs[0]
21 22
          expect(sender.display_name).to eq(current_user.name)
          expect(sender.address).to eq(gitlab_sender)
23 24
        end

R
Robb Kidd 已提交
25
        it 'is sent to the assignee' do
26
          is_expected.to deliver_to assignee.email
R
Robb Kidd 已提交
27 28
        end
      end
29

R
Robb Kidd 已提交
30
      context 'for issues' do
31
        let(:issue) { create(:issue, author: current_user, assignee: assignee, project: project) }
R
Robert Speicher 已提交
32
        let(:issue_with_description) { create(:issue, author: current_user, assignee: assignee, project: project, description: FFaker::Lorem.sentence) }
33

R
Robb Kidd 已提交
34
        describe 'that are new' do
35
          subject { Notify.new_issue_email(issue.assignee_id, issue.id) }
36

R
Robb Kidd 已提交
37
          it_behaves_like 'an assignee email'
38 39 40
          it_behaves_like 'an email starting a new thread with reply-by-email enabled' do
            let(:model) { issue }
          end
41
          it_behaves_like 'it should show Gmail Actions View Issue link'
42
          it_behaves_like 'an unsubscribeable thread'
43

R
Robb Kidd 已提交
44
          it 'has the correct subject' do
45
            is_expected.to have_subject /#{project.name} \| #{issue.title} \(##{issue.iid}\)/
R
Robb Kidd 已提交
46
          end
47

R
Robb Kidd 已提交
48
          it 'contains a link to the new issue' do
V
Vinnie Okada 已提交
49
            is_expected.to have_body_text /#{namespace_project_issue_path project.namespace, project, issue}/
R
Robb Kidd 已提交
50
          end
51 52 53

          context 'when enabled email_author_in_body' do
            before do
54
              allow_any_instance_of(ApplicationSetting).to receive(:email_author_in_body).and_return(true)
55 56 57 58 59 60 61
            end

            it 'contains a link to note author' do
              is_expected.to have_body_text issue.author_name
              is_expected.to have_body_text /wrote\:/
            end
          end
R
Robb Kidd 已提交
62
        end
63

64 65 66
        describe 'that are new with a description' do
          subject { Notify.new_issue_email(issue_with_description.assignee_id, issue_with_description.id) }

67 68
          it_behaves_like 'it should show Gmail Actions View Issue link'

69
          it 'contains the description' do
70
            is_expected.to have_body_text /#{issue_with_description.description}/
71 72 73
          end
        end

R
Robb Kidd 已提交
74
        describe 'that have been reassigned' do
V
Valery Sizov 已提交
75
          subject { Notify.reassigned_issue_email(recipient.id, issue.id, previous_assignee.id, current_user.id) }
R
Robb Kidd 已提交
76 77

          it_behaves_like 'a multiple recipients email'
78 79 80
          it_behaves_like 'an answer to an existing thread with reply-by-email enabled' do
            let(:model) { issue }
          end
81
          it_behaves_like 'it should show Gmail Actions View Issue link'
82
          it_behaves_like 'an unsubscribeable thread'
R
Robb Kidd 已提交
83

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

R
Robb Kidd 已提交
90
          it 'has the correct subject' do
91
            is_expected.to have_subject /#{issue.title} \(##{issue.iid}\)/
R
Robb Kidd 已提交
92 93 94
          end

          it 'contains the name of the previous assignee' do
95
            is_expected.to have_body_text /#{previous_assignee.name}/
R
Robb Kidd 已提交
96 97 98
          end

          it 'contains the name of the new assignee' do
99
            is_expected.to have_body_text /#{assignee.name}/
R
Robb Kidd 已提交
100 101 102
          end

          it 'contains a link to the issue' do
V
Vinnie Okada 已提交
103
            is_expected.to have_body_text /#{namespace_project_issue_path project.namespace, project, issue}/
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 124 125 126 127 128 129 130 131 132 133 134 135 136
          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

          it 'has the correct subject' do
            is_expected.to have_subject /#{issue.title} \(##{issue.iid}\)/
          end

          it 'contains the names of the added labels' do
            is_expected.to have_body_text /foo, bar, and baz/
          end

          it 'contains a link to the issue' do
            is_expected.to have_body_text /#{namespace_project_issue_path project.namespace, project, issue}/
          end
        end

A
Alex Denisov 已提交
137 138
        describe 'status changed' do
          let(:status) { 'closed' }
V
Valery Sizov 已提交
139
          subject { Notify.issue_status_changed_email(recipient.id, issue.id, status, current_user.id) }
140

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

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

A
Alex Denisov 已提交
153
          it 'has the correct subject' do
154
            is_expected.to have_subject /#{issue.title} \(##{issue.iid}\)/i
A
Alex Denisov 已提交
155 156 157
          end

          it 'contains the new status' do
158
            is_expected.to have_body_text /#{status}/i
A
Alex Denisov 已提交
159 160 161
          end

          it 'contains the user name' do
162
            is_expected.to have_body_text /#{current_user.name}/i
A
Alex Denisov 已提交
163 164 165
          end

          it 'contains a link to the issue' do
V
Vinnie Okada 已提交
166
            is_expected.to have_body_text /#{namespace_project_issue_path project.namespace, project, issue}/
A
Alex Denisov 已提交
167
          end
168
        end
169 170 171 172 173

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

174 175 176
          it_behaves_like 'an answer to an existing thread with reply-by-email enabled' do
            let(:model) { issue }
          end
177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197
          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

          it 'has the correct subject' do
            is_expected.to have_subject /#{issue.title} \(##{issue.iid}\)/i
          end

          it 'contains link to new issue' do
            new_issue_url = namespace_project_issue_path(new_issue.project.namespace,
                                                         new_issue.project, new_issue)
            is_expected.to have_body_text new_issue_url
          end

          it 'contains a link to the original issue' do
            is_expected.to have_body_text /#{namespace_project_issue_path project.namespace, project, issue}/
          end
        end
R
Robb Kidd 已提交
198 199 200
      end

      context 'for merge requests' do
201
        let(:merge_author) { create(:user) }
202
        let(:merge_request) { create(:merge_request, author: current_user, assignee: assignee, source_project: project, target_project: project) }
R
Robert Speicher 已提交
203
        let(:merge_request_with_description) { create(:merge_request, author: current_user, assignee: assignee, source_project: project, target_project: project, description: FFaker::Lorem.sentence) }
R
Robb Kidd 已提交
204 205

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

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

          it 'has the correct subject' do
216
            is_expected.to have_subject /#{merge_request.title} \(#{merge_request.to_reference}\)/
R
Robb Kidd 已提交
217 218 219
          end

          it 'contains a link to the new merge request' do
V
Vinnie Okada 已提交
220
            is_expected.to have_body_text /#{namespace_project_merge_request_path(project.namespace, project, merge_request)}/
R
Robb Kidd 已提交
221 222 223
          end

          it 'contains the source branch for the merge request' do
224
            is_expected.to have_body_text /#{merge_request.source_branch}/
R
Robb Kidd 已提交
225 226 227
          end

          it 'contains the target branch for the merge request' do
228
            is_expected.to have_body_text /#{merge_request.target_branch}/
R
Robb Kidd 已提交
229
          end
P
Philip Blatter 已提交
230

231 232
          context 'when enabled email_author_in_body' do
            before do
233
              allow_any_instance_of(ApplicationSetting).to receive(:email_author_in_body).and_return(true)
234 235 236 237 238 239 240
            end

            it 'contains a link to note author' do
              is_expected.to have_body_text merge_request.author_name
              is_expected.to have_body_text /wrote\:/
            end
          end
R
Robb Kidd 已提交
241 242
        end

243 244 245
        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) }

246
          it_behaves_like 'it should show Gmail Actions View Merge request link'
247
          it_behaves_like "an unsubscribeable thread"
248

249
          it 'contains the description' do
250
            is_expected.to have_body_text /#{merge_request_with_description.description}/
251 252 253
          end
        end

R
Robb Kidd 已提交
254
        describe 'that are reassigned' do
255
          subject { Notify.reassigned_merge_request_email(recipient.id, merge_request.id, previous_assignee.id, current_user.id) }
R
Robb Kidd 已提交
256 257

          it_behaves_like 'a multiple recipients email'
258 259 260
          it_behaves_like 'an answer to an existing thread with reply-by-email enabled' do
            let(:model) { merge_request }
          end
261
          it_behaves_like 'it should show Gmail Actions View Merge request link'
262
          it_behaves_like "an unsubscribeable thread"
R
Robb Kidd 已提交
263

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

R
Robb Kidd 已提交
270
          it 'has the correct subject' do
271
            is_expected.to have_subject /#{merge_request.title} \(#{merge_request.to_reference}\)/
R
Robb Kidd 已提交
272 273 274
          end

          it 'contains the name of the previous assignee' do
275
            is_expected.to have_body_text /#{previous_assignee.name}/
R
Robb Kidd 已提交
276 277 278
          end

          it 'contains the name of the new assignee' do
279
            is_expected.to have_body_text /#{assignee.name}/
R
Robb Kidd 已提交
280 281 282
          end

          it 'contains a link to the merge request' do
V
Vinnie Okada 已提交
283
            is_expected.to have_body_text /#{namespace_project_merge_request_path project.namespace, project, merge_request}/
R
Robb Kidd 已提交
284
          end
285 286
        end

287 288 289 290
        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'
291 292 293
          it_behaves_like 'an answer to an existing thread with reply-by-email enabled' do
            let(:model) { merge_request }
          end
294 295 296 297 298 299 300 301 302 303 304
          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

          it 'has the correct subject' do
305
            is_expected.to have_subject /#{merge_request.title} \(#{merge_request.to_reference}\)/
306 307 308 309 310 311 312 313 314 315 316
          end

          it 'contains the names of the added labels' do
            is_expected.to have_body_text /foo, bar, and baz/
          end

          it 'contains a link to the merge request' do
            is_expected.to have_body_text /#{namespace_project_merge_request_path project.namespace, project, merge_request}/
          end
        end

317 318
        describe 'status changed' do
          let(:status) { 'reopened' }
V
Valery Sizov 已提交
319
          subject { Notify.merge_request_status_email(recipient.id, merge_request.id, status, current_user.id) }
320

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

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

          it 'has the correct subject' do
334
            is_expected.to have_subject /#{merge_request.title} \(#{merge_request.to_reference}\)/i
335 336 337
          end

          it 'contains the new status' do
338
            is_expected.to have_body_text /#{status}/i
339 340 341
          end

          it 'contains the user name' do
342
            is_expected.to have_body_text /#{current_user.name}/i
343 344 345
          end

          it 'contains a link to the merge request' do
V
Vinnie Okada 已提交
346
            is_expected.to have_body_text /#{namespace_project_merge_request_path project.namespace, project, merge_request}/
347 348 349
          end
        end

350 351 352 353
        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'
354 355 356
          it_behaves_like 'an answer to an existing thread with reply-by-email enabled' do
            let(:model) { merge_request }
          end
357
          it_behaves_like 'it should show Gmail Actions View Merge request link'
358
          it_behaves_like 'an unsubscribeable thread'
359 360 361

          it 'is sent as the merge author' do
            sender = subject.header[:from].addrs[0]
362 363
            expect(sender.display_name).to eq(merge_author.name)
            expect(sender.address).to eq(gitlab_sender)
364 365 366
          end

          it 'has the correct subject' do
367
            is_expected.to have_subject /#{merge_request.title} \(#{merge_request.to_reference}\)/
368
          end
R
Robb Kidd 已提交
369

370
          it 'contains the new status' do
371
            is_expected.to have_body_text /merged/i
372 373 374
          end

          it 'contains a link to the merge request' do
V
Vinnie Okada 已提交
375
            is_expected.to have_body_text /#{namespace_project_merge_request_path project.namespace, project, merge_request}/
376
          end
R
Robb Kidd 已提交
377 378
        end
      end
379 380
    end

381 382 383
    describe 'project was moved' do
      let(:project) { create(:project) }
      let(:user) { create(:user) }
384
      subject { Notify.project_was_moved_email(project.id, user.id, "gitlab/gitlab") }
385

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

390
      it 'has the correct subject' do
391
        is_expected.to have_subject /Project was moved/
392 393 394
      end

      it 'contains name of project' do
395
        is_expected.to have_body_text /#{project.name_with_namespace}/
396 397 398
      end

      it 'contains new user role' do
399
        is_expected.to have_body_text /#{project.ssh_url_to_repo}/
400 401 402
      end
    end

R
Rémy Coutable 已提交
403
    describe 'project access requested' do
404
      context 'for a project in a user namespace' do
405
        let(:project) { create(:project, :public).tap { |p| p.team << [p.owner, :master, p.owner] } }
406 407 408
        let(:user) { create(:user) }
        let(:project_member) do
          project.request_access(user)
409
          project.requesters.find_by(user_id: user.id)
410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426
        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"
          is_expected.to have_body_text /#{project.name_with_namespace}/
          is_expected.to have_body_text /#{namespace_project_project_members_url(project.namespace, project)}/
          is_expected.to have_body_text /#{project_member.human_access}/
        end
R
Rémy Coutable 已提交
427 428
      end

429 430 431
      context 'for a project in a group' do
        let(:group_owner) { create(:user) }
        let(:group) { create(:group).tap { |g| g.add_owner(group_owner) } }
432
        let(:project) { create(:project, :public, namespace: group) }
433 434 435
        let(:user) { create(:user) }
        let(:project_member) do
          project.request_access(user)
436
          project.requesters.find_by(user_id: user.id)
437 438
        end
        subject { Notify.member_access_requested_email('project', project_member.id) }
R
Rémy Coutable 已提交
439

440 441 442 443 444 445 446 447 448 449 450 451 452 453
        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"
          is_expected.to have_body_text /#{project.name_with_namespace}/
          is_expected.to have_body_text /#{namespace_project_project_members_url(project.namespace, project)}/
          is_expected.to have_body_text /#{project_member.human_access}/
        end
R
Rémy Coutable 已提交
454
      end
R
Rémy Coutable 已提交
455 456 457 458 459 460 461
    end

    describe 'project access denied' do
      let(:project) { create(:project) }
      let(:user) { create(:user) }
      let(:project_member) do
        project.request_access(user)
462
        project.requesters.find_by(user_id: user.id)
R
Rémy Coutable 已提交
463
      end
464
      subject { Notify.member_access_denied_email('project', project.id, user.id) }
R
Rémy Coutable 已提交
465 466 467 468 469

      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 已提交
470 471 472 473 474
      it 'contains all the useful information' do
        is_expected.to have_subject "Access to the #{project.name_with_namespace} project was denied"
        is_expected.to have_body_text /#{project.name_with_namespace}/
        is_expected.to have_body_text /#{project.web_url}/
      end
R
Rémy Coutable 已提交
475 476
    end

477
    describe 'project access changed' do
478
      let(:project) { create(:project) }
479
      let(:user) { create(:user) }
480
      let(:project_member) { create(:project_member, project: project, user: user) }
481
      subject { Notify.member_access_granted_email('project', project_member.id) }
482 483

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

R
Rémy Coutable 已提交
487 488 489 490 491 492
      it 'contains all the useful information' do
        is_expected.to have_subject "Access to the #{project.name_with_namespace} project was granted"
        is_expected.to have_body_text /#{project.name_with_namespace}/
        is_expected.to have_body_text /#{project.web_url}/
        is_expected.to have_body_text /#{project_member.human_access}/
      end
493
    end
494

495 496 497 498 499 500 501 502 503
    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
504
      )
505 506 507 508 509
    end

    describe 'project invitation' do
      let(:project) { create(:project) }
      let(:master) { create(:user).tap { |u| project.team << [u, :master] } }
510
      let(:project_member) { invite_to_project(project, inviter: master) }
511 512 513 514 515 516 517

      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 已提交
518 519 520 521 522 523 524
      it 'contains all the useful information' do
        is_expected.to have_subject "Invitation to join the #{project.name_with_namespace} project"
        is_expected.to have_body_text /#{project.name_with_namespace}/
        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}/
      end
525 526 527 528
    end

    describe 'project invitation accepted' do
      let(:project) { create(:project) }
529
      let(:invited_user) { create(:user, name: 'invited user') }
530 531
      let(:master) { create(:user).tap { |u| project.team << [u, :master] } }
      let(:project_member) do
532
        invitee = invite_to_project(project, inviter: master)
533 534
        invitee.accept_invite!(invited_user)
        invitee
535
      end
536

537 538 539 540 541 542
      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 已提交
543 544 545 546 547 548 549
      it 'contains all the useful information' do
        is_expected.to have_subject 'Invitation accepted'
        is_expected.to have_body_text /#{project.name_with_namespace}/
        is_expected.to have_body_text /#{project.web_url}/
        is_expected.to have_body_text /#{project_member.invite_email}/
        is_expected.to have_body_text /#{invited_user.name}/
      end
550 551 552 553 554 555
    end

    describe 'project invitation declined' do
      let(:project) { create(:project) }
      let(:master) { create(:user).tap { |u| project.team << [u, :master] } }
      let(:project_member) do
556
        invitee = invite_to_project(project, inviter: master)
557 558
        invitee.decline_invite!
        invitee
559
      end
560 561 562 563 564 565 566

      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 已提交
567 568 569 570 571 572
      it 'contains all the useful information' do
        is_expected.to have_subject 'Invitation declined'
        is_expected.to have_body_text /#{project.name_with_namespace}/
        is_expected.to have_body_text /#{project.web_url}/
        is_expected.to have_body_text /#{project_member.invite_email}/
      end
573 574
    end

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

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

R
Robb Kidd 已提交
583
      shared_examples 'a note email' do
584 585
        it_behaves_like 'it should have Gmail Actions links'

586 587
        it 'is sent as the author' do
          sender = subject.header[:from].addrs[0]
588 589
          expect(sender.display_name).to eq(note_author.name)
          expect(sender.address).to eq(gitlab_sender)
590 591
        end

R
Robb Kidd 已提交
592
        it 'is sent to the given recipient' do
593
          is_expected.to deliver_to recipient.notification_email
R
Robb Kidd 已提交
594 595 596
        end

        it 'contains the message from the note' do
597
          is_expected.to have_body_text /#{note.note}/
R
Robb Kidd 已提交
598
        end
599

600
        it 'does not contain note author' do
601 602 603 604 605
          is_expected.not_to have_body_text /wrote\:/
        end

        context 'when enabled email_author_in_body' do
          before do
606
            allow_any_instance_of(ApplicationSetting).to receive(:email_author_in_body).and_return(true)
607 608 609 610 611 612 613
          end

          it 'contains a link to note author' do
            is_expected.to have_body_text note.author_name
            is_expected.to have_body_text /wrote\:/
          end
        end
R
Robb Kidd 已提交
614 615 616
      end

      describe 'on a commit' do
617
        let(:commit) { project.commit }
D
Dmitriy Zaporozhets 已提交
618

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

D
Dmitriy Zaporozhets 已提交
621
        subject { Notify.note_commit_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) { commit }
        end
627
        it_behaves_like 'it should show Gmail Actions View Commit link'
628
        it_behaves_like 'a user cannot unsubscribe through footer link'
R
Robb Kidd 已提交
629 630

        it 'has the correct subject' do
631
          is_expected.to have_subject /#{commit.title} \(#{commit.short_id}\)/
R
Robb Kidd 已提交
632 633 634
        end

        it 'contains a link to the commit' do
635
          is_expected.to have_body_text commit.short_id
R
Robb Kidd 已提交
636 637 638 639
        end
      end

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

644
        subject { Notify.note_merge_request_email(recipient.id, note.id) }
R
Robb Kidd 已提交
645 646

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

        it 'has the correct subject' do
654
          is_expected.to have_subject /#{merge_request.title} \(#{merge_request.to_reference}\)/
R
Robb Kidd 已提交
655 656 657
        end

        it 'contains a link to the merge request note' do
658
          is_expected.to have_body_text /#{note_on_merge_request_path}/
R
Robb Kidd 已提交
659 660 661 662
        end
      end

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

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

        it_behaves_like 'a note email'
670 671 672
        it_behaves_like 'an answer to an existing thread with reply-by-email enabled' do
          let(:model) { issue }
        end
673
        it_behaves_like 'it should show Gmail Actions View Issue link'
674
        it_behaves_like 'an unsubscribeable thread'
R
Robb Kidd 已提交
675 676

        it 'has the correct subject' do
677
          is_expected.to have_subject /#{issue.title} \(##{issue.iid}\)/
R
Robb Kidd 已提交
678 679 680
        end

        it 'contains a link to the issue note' do
681
          is_expected.to have_body_text /#{note_on_issue_path}/
R
Robb Kidd 已提交
682 683
        end
      end
684 685
    end
  end
686

687 688 689 690 691 692
  context 'for a group' do
    describe 'group access requested' do
      let(:group) { create(:group) }
      let(:user) { create(:user) }
      let(:group_member) do
        group.request_access(user)
693
        group.requesters.find_by(user_id: user.id)
694 695
      end
      subject { Notify.member_access_requested_email('group', group_member.id) }
R
Rémy Coutable 已提交
696

697 698 699
      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 已提交
700

R
Rémy Coutable 已提交
701 702 703 704 705 706
      it 'contains all the useful information' do
        is_expected.to have_subject "Request to join the #{group.name} group"
        is_expected.to have_body_text /#{group.name}/
        is_expected.to have_body_text /#{group_group_members_url(group)}/
        is_expected.to have_body_text /#{group_member.human_access}/
      end
R
Rémy Coutable 已提交
707 708
    end

709 710 711 712 713
    describe 'group access denied' do
      let(:group) { create(:group) }
      let(:user) { create(:user) }
      let(:group_member) do
        group.request_access(user)
714
        group.requesters.find_by(user_id: user.id)
715 716
      end
      subject { Notify.member_access_denied_email('group', group.id, user.id) }
R
Rémy Coutable 已提交
717

718 719 720
      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 已提交
721

R
Rémy Coutable 已提交
722 723 724 725 726
      it 'contains all the useful information' do
        is_expected.to have_subject "Access to the #{group.name} group was denied"
        is_expected.to have_body_text /#{group.name}/
        is_expected.to have_body_text /#{group.web_url}/
      end
R
Rémy Coutable 已提交
727 728
    end

729 730 731 732
    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 已提交
733

734 735 736 737 738 739
      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 已提交
740 741 742 743 744 745
      it 'contains all the useful information' do
        is_expected.to have_subject "Access to the #{group.name} group was granted"
        is_expected.to have_body_text /#{group.name}/
        is_expected.to have_body_text /#{group.web_url}/
        is_expected.to have_body_text /#{group_member.human_access}/
      end
R
Rémy Coutable 已提交
746 747
    end

748 749 750 751 752 753 754 755 756
    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
757
      )
R
Rémy Coutable 已提交
758 759
    end

760 761 762
    describe 'group invitation' do
      let(:group) { create(:group) }
      let(:owner) { create(:user).tap { |u| group.add_user(u, Gitlab::Access::OWNER) } }
763
      let(:group_member) { invite_to_group(group, inviter: owner) }
764

765
      subject { Notify.member_invited_email('group', group_member.id, group_member.invite_token) }
766

767 768 769
      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"
770

R
Rémy Coutable 已提交
771 772 773 774 775 776 777
      it 'contains all the useful information' do
        is_expected.to have_subject "Invitation to join the #{group.name} group"
        is_expected.to have_body_text /#{group.name}/
        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}/
      end
778 779
    end

780 781
    describe 'group invitation accepted' do
      let(:group) { create(:group) }
782
      let(:invited_user) { create(:user, name: 'invited user') }
783 784
      let(:owner) { create(:user).tap { |u| group.add_user(u, Gitlab::Access::OWNER) } }
      let(:group_member) do
785
        invitee = invite_to_group(group, inviter: owner)
786 787 788 789 790 791 792 793 794 795
        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 已提交
796 797 798 799 800 801 802
      it 'contains all the useful information' do
        is_expected.to have_subject 'Invitation accepted'
        is_expected.to have_body_text /#{group.name}/
        is_expected.to have_body_text /#{group.web_url}/
        is_expected.to have_body_text /#{group_member.invite_email}/
        is_expected.to have_body_text /#{invited_user.name}/
      end
803 804
    end

805 806 807 808
    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
809
        invitee = invite_to_group(group, inviter: owner)
810 811 812 813 814 815 816 817 818 819
        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 已提交
820 821 822 823 824 825
      it 'contains all the useful information' do
        is_expected.to have_subject 'Invitation declined'
        is_expected.to have_body_text /#{group.name}/
        is_expected.to have_body_text /#{group.web_url}/
        is_expected.to have_body_text /#{group_member.invite_email}/
      end
826 827
    end
  end
828 829 830 831 832 833

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

    before do
V
Valery Sizov 已提交
834 835 836 837
      perform_enqueued_jobs do
        user.email = "new-email@mail.com"
        user.save
      end
838 839 840 841
    end

    subject { ActionMailer::Base.deliveries.last }

842
    it_behaves_like 'an email sent from GitLab'
843
    it_behaves_like "a user cannot unsubscribe through footer link"
844

845
    it 'is sent to the new user' do
846
      is_expected.to deliver_to 'new-email@mail.com'
847 848 849
    end

    it 'has the correct subject' do
850
      is_expected.to have_subject "Confirmation instructions"
851 852 853
    end

    it 'includes a link to the site' do
854
      is_expected.to have_body_text /#{example_site_path}/
855 856
    end
  end
D
Dmitriy Zaporozhets 已提交
857

858 859 860 861 862
  describe 'email on push for a created branch' do
    let(:example_site_path) { root_path }
    let(:user) { create(:user) }
    let(:tree_path) { namespace_project_tree_path(project.namespace, project, "master") }

863
    subject { Notify.repository_push_email(project.id, author_id: user.id, ref: 'refs/heads/master', action: :create) }
864

865
    it_behaves_like 'it should not have Gmail Actions links'
866
    it_behaves_like 'a user cannot unsubscribe through footer link'
867 868
    it_behaves_like 'an email with X-GitLab headers containing project details'
    it_behaves_like 'an email that contains a header with author username'
869

870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889
    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
      is_expected.to have_subject /Pushed new branch master/
    end

    it 'contains a link to the branch' do
      is_expected.to have_body_text /#{tree_path}/
    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") }

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

892
    it_behaves_like 'it should not have Gmail Actions links'
893
    it_behaves_like "a user cannot unsubscribe through footer link"
894 895
    it_behaves_like 'an email with X-GitLab headers containing project details'
    it_behaves_like 'an email that contains a header with author username'
896

897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 915
    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
      is_expected.to have_subject /Pushed new tag v1\.0/
    end

    it 'contains a link to the tag' do
      is_expected.to have_body_text /#{tree_path}/
    end
  end

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

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

918
    it_behaves_like 'it should not have Gmail Actions links'
919
    it_behaves_like 'a user cannot unsubscribe through footer link'
920 921
    it_behaves_like 'an email with X-GitLab headers containing project details'
    it_behaves_like 'an email that contains a header with author username'
922

923 924 925 926 927 928 929 930 931 932 933 934 935 936 937
    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
      is_expected.to have_subject /Deleted branch master/
    end
  end

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

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

940
    it_behaves_like 'it should not have Gmail Actions links'
941
    it_behaves_like 'a user cannot unsubscribe through footer link'
942 943
    it_behaves_like 'an email with X-GitLab headers containing project details'
    it_behaves_like 'an email that contains a header with author username'
944

945 946 947 948 949 950 951 952 953 954 955
    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
      is_expected.to have_subject /Deleted tag v1\.0/
    end
  end

956
  describe 'email on push with multiple commits' do
D
Dmitriy Zaporozhets 已提交
957 958
    let(:example_site_path) { root_path }
    let(:user) { create(:user) }
959 960 961
    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 }
962
    let(:diff_path) { namespace_project_compare_path(project.namespace, project, from: Commit.new(compare.base, project), to: Commit.new(compare.head, project)) }
963
    let(:send_from_committer_email) { false }
964
    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 已提交
965

966
    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 已提交
967

968
    it_behaves_like 'it should not have Gmail Actions links'
969
    it_behaves_like 'a user cannot unsubscribe through footer link'
970 971
    it_behaves_like 'an email with X-GitLab headers containing project details'
    it_behaves_like 'an email that contains a header with author username'
972

973 974
    it 'is sent as the author' do
      sender = subject.header[:from].addrs[0]
975 976
      expect(sender.display_name).to eq(user.name)
      expect(sender.address).to eq(gitlab_sender)
977 978
    end

D
Dmitriy Zaporozhets 已提交
979
    it 'has the correct subject' do
980
      is_expected.to have_subject /\[#{project.path_with_namespace}\]\[master\] #{commits.length} commits:/
D
Dmitriy Zaporozhets 已提交
981 982 983
    end

    it 'includes commits list' do
984
      is_expected.to have_body_text /Change some files/
D
Dmitriy Zaporozhets 已提交
985 986
    end

987 988
    it 'includes diffs with character-level highlighting' do
      is_expected.to have_body_text /def<\/span> <span class=\"nf\">archive_formats_regex/
D
Dmitriy Zaporozhets 已提交
989
    end
990 991

    it 'contains a link to the diff' do
992
      is_expected.to have_body_text /#{diff_path}/
993
    end
994

995
    it 'does not contain the misleading footer' do
996 997
      is_expected.not_to have_body_text /you are a member of/
    end
998 999 1000 1001

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

1002 1003 1004 1005 1006
      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
1007
        before do
1008
          user.update_attribute(:email, "user@company.com")
1009
          user.confirm
1010 1011 1012 1013 1014 1015
        end

        it "is sent from the committer email" do
          sender = subject.header[:from].addrs[0]
          expect(sender.address).to eq(user.email)
        end
1016 1017 1018 1019 1020

        it "is set to reply to the committer email" do
          sender = subject.header[:reply_to].addrs[0]
          expect(sender.address).to eq(user.email)
        end
1021 1022
      end

1023 1024 1025
      context "when the committer email domain is not completely within the GitLab domain" do
        before do
          user.update_attribute(:email, "user@something.company.com")
1026
          user.confirm
1027 1028 1029 1030 1031 1032
        end

        it "is sent from the default email" do
          sender = subject.header[:from].addrs[0]
          expect(sender.address).to eq(gitlab_sender)
        end
1033 1034 1035 1036 1037

        it "is set to reply to the default email" do
          sender = subject.header[:reply_to].addrs[0]
          expect(sender.address).to eq(gitlab_sender_reply_to)
        end
1038 1039 1040 1041 1042
      end

      context "when the committer email domain is outside the GitLab domain" do
        before do
          user.update_attribute(:email, "user@mpany.com")
1043
          user.confirm
1044
        end
1045 1046 1047 1048 1049

        it "is sent from the default email" do
          sender = subject.header[:from].addrs[0]
          expect(sender.address).to eq(gitlab_sender)
        end
1050 1051 1052 1053 1054

        it "is set to reply to the default email" do
          sender = subject.header[:reply_to].addrs[0]
          expect(sender.address).to eq(gitlab_sender_reply_to)
        end
1055 1056
      end
    end
D
Dmitriy Zaporozhets 已提交
1057
  end
1058 1059 1060 1061

  describe 'email on push with a single commit' do
    let(:example_site_path) { root_path }
    let(:user) { create(:user) }
1062 1063 1064
    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 已提交
1065
    let(:diff_path) { namespace_project_commit_path(project.namespace, project, commits.first) }
1066
    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) }
1067

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

1070
    it_behaves_like 'it should show Gmail Actions View Commit link'
1071
    it_behaves_like 'a user cannot unsubscribe through footer link'
1072 1073
    it_behaves_like 'an email with X-GitLab headers containing project details'
    it_behaves_like 'an email that contains a header with author username'
1074

1075 1076
    it 'is sent as the author' do
      sender = subject.header[:from].addrs[0]
1077 1078
      expect(sender.display_name).to eq(user.name)
      expect(sender.address).to eq(gitlab_sender)
1079 1080 1081
    end

    it 'has the correct subject' do
1082
      is_expected.to have_subject /#{commits.first.title}/
1083 1084 1085
    end

    it 'includes commits list' do
1086
      is_expected.to have_body_text /Change some files/
1087 1088
    end

1089 1090
    it 'includes diffs with character-level highlighting' do
      is_expected.to have_body_text /def<\/span> <span class=\"nf\">archive_formats_regex/
1091 1092 1093
    end

    it 'contains a link to the diff' do
1094
      is_expected.to have_body_text /#{diff_path}/
1095 1096
    end
  end
1097
end