notify_spec.rb 42.5 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 405 406 407 408
      context 'for a project in a user namespace' do
        let(:project) { create(:project).tap { |p| p.team << [p.owner, :master, p.owner] } }
        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 432 433 434 435
      context 'for a project in a group' do
        let(:group_owner) { create(:user) }
        let(:group) { create(:group).tap { |g| g.add_owner(group_owner) } }
        let(:project) { create(:project, namespace: group) }
        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 504 505 506 507 508 509 510 511
    def invite_to_project(project:, email:, inviter:)
      ProjectMember.add_user(project.project_members, 'toto@example.com', Gitlab::Access::DEVELOPER, inviter)

      project.project_members.invite.last
    end

    describe 'project invitation' do
      let(:project) { create(:project) }
      let(:master) { create(:user).tap { |u| project.team << [u, :master] } }
      let(:project_member) { invite_to_project(project: project, email: 'toto@example.com', inviter: master) }

      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 已提交
512 513 514 515 516 517 518
      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
519 520 521 522 523 524 525 526 527 528
    end

    describe 'project invitation accepted' do
      let(:project) { create(:project) }
      let(:invited_user) { create(:user) }
      let(:master) { create(:user).tap { |u| project.team << [u, :master] } }
      let(:project_member) do
        invitee = invite_to_project(project: project, email: 'toto@example.com', inviter: master)
        invitee.accept_invite!(invited_user)
        invitee
529
      end
530

531 532 533 534 535 536
      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 已提交
537 538 539 540 541 542 543
      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
544 545 546 547 548 549 550 551 552
    end

    describe 'project invitation declined' do
      let(:project) { create(:project) }
      let(:master) { create(:user).tap { |u| project.team << [u, :master] } }
      let(:project_member) do
        invitee = invite_to_project(project: project, email: 'toto@example.com', inviter: master)
        invitee.decline_invite!
        invitee
553
      end
554 555 556 557 558 559 560

      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 已提交
561 562 563 564 565 566
      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
567 568
    end

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

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

R
Robb Kidd 已提交
577
      shared_examples 'a note email' do
578 579
        it_behaves_like 'it should have Gmail Actions links'

580 581
        it 'is sent as the author' do
          sender = subject.header[:from].addrs[0]
582 583
          expect(sender.display_name).to eq(note_author.name)
          expect(sender.address).to eq(gitlab_sender)
584 585
        end

R
Robb Kidd 已提交
586
        it 'is sent to the given recipient' do
587
          is_expected.to deliver_to recipient.notification_email
R
Robb Kidd 已提交
588 589 590
        end

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

        it 'not contains note author' do
          is_expected.not_to have_body_text /wrote\:/
        end

        context 'when enabled email_author_in_body' do
          before do
600
            allow_any_instance_of(ApplicationSetting).to receive(:email_author_in_body).and_return(true)
601 602 603 604 605 606 607
          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 已提交
608 609 610
      end

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

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

D
Dmitriy Zaporozhets 已提交
615
        subject { Notify.note_commit_email(recipient.id, note.id) }
R
Robb Kidd 已提交
616 617

        it_behaves_like 'a note email'
618 619 620
        it_behaves_like 'an answer to an existing thread with reply-by-email enabled' do
          let(:model) { commit }
        end
621
        it_behaves_like 'it should show Gmail Actions View Commit link'
622
        it_behaves_like 'a user cannot unsubscribe through footer link'
R
Robb Kidd 已提交
623 624

        it 'has the correct subject' do
625
          is_expected.to have_subject /#{commit.title} \(#{commit.short_id}\)/
R
Robb Kidd 已提交
626 627 628
        end

        it 'contains a link to the commit' do
629
          is_expected.to have_body_text commit.short_id
R
Robb Kidd 已提交
630 631 632 633
        end
      end

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

638
        subject { Notify.note_merge_request_email(recipient.id, note.id) }
R
Robb Kidd 已提交
639 640

        it_behaves_like 'a note email'
641 642 643
        it_behaves_like 'an answer to an existing thread with reply-by-email enabled' do
          let(:model) { merge_request }
        end
644
        it_behaves_like 'it should show Gmail Actions View Merge request link'
645
        it_behaves_like 'an unsubscribeable thread'
R
Robb Kidd 已提交
646 647

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

        it 'contains a link to the merge request note' do
652
          is_expected.to have_body_text /#{note_on_merge_request_path}/
R
Robb Kidd 已提交
653 654 655 656
        end
      end

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

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

        it_behaves_like 'a note email'
664 665 666
        it_behaves_like 'an answer to an existing thread with reply-by-email enabled' do
          let(:model) { issue }
        end
667
        it_behaves_like 'it should show Gmail Actions View Issue link'
668
        it_behaves_like 'an unsubscribeable thread'
R
Robb Kidd 已提交
669 670

        it 'has the correct subject' do
671
          is_expected.to have_subject /#{issue.title} \(##{issue.iid}\)/
R
Robb Kidd 已提交
672 673 674
        end

        it 'contains a link to the issue note' do
675
          is_expected.to have_body_text /#{note_on_issue_path}/
R
Robb Kidd 已提交
676 677
        end
      end
678 679
    end
  end
680

681 682 683 684 685 686
  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)
687
        group.requesters.find_by(user_id: user.id)
688 689
      end
      subject { Notify.member_access_requested_email('group', group_member.id) }
R
Rémy Coutable 已提交
690

691 692 693
      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 已提交
694

R
Rémy Coutable 已提交
695 696 697 698 699 700
      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 已提交
701 702
    end

703 704 705 706 707
    describe 'group access denied' do
      let(:group) { create(:group) }
      let(:user) { create(:user) }
      let(:group_member) do
        group.request_access(user)
708
        group.requesters.find_by(user_id: user.id)
709 710
      end
      subject { Notify.member_access_denied_email('group', group.id, user.id) }
R
Rémy Coutable 已提交
711

712 713 714
      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 已提交
715

R
Rémy Coutable 已提交
716 717 718 719 720
      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 已提交
721 722
    end

723 724 725 726
    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 已提交
727

728 729 730 731 732 733
      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 已提交
734 735 736 737 738 739
      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 已提交
740 741
    end

742 743 744 745
    def invite_to_group(group:, email:, inviter:)
      GroupMember.add_user(group.group_members, 'toto@example.com', Gitlab::Access::DEVELOPER, inviter)

      group.group_members.invite.last
R
Rémy Coutable 已提交
746 747
    end

748 749 750 751
    describe 'group invitation' do
      let(:group) { create(:group) }
      let(:owner) { create(:user).tap { |u| group.add_user(u, Gitlab::Access::OWNER) } }
      let(:group_member) { invite_to_group(group: group, email: 'toto@example.com', inviter: owner) }
752

753
      subject { Notify.member_invited_email('group', group_member.id, group_member.invite_token) }
754

755 756 757
      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"
758

R
Rémy Coutable 已提交
759 760 761 762 763 764 765
      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
766 767
    end

768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783
    describe 'group invitation accepted' do
      let(:group) { create(:group) }
      let(:invited_user) { create(:user) }
      let(:owner) { create(:user).tap { |u| group.add_user(u, Gitlab::Access::OWNER) } }
      let(:group_member) do
        invitee = invite_to_group(group: group, email: 'toto@example.com', inviter: owner)
        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 已提交
784 785 786 787 788 789 790
      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
791 792
    end

793 794 795 796 797 798 799 800 801 802 803 804 805 806 807
    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
        invitee = invite_to_group(group: group, email: 'toto@example.com', inviter: owner)
        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 已提交
808 809 810 811 812 813
      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
814 815
    end
  end
816 817 818 819 820 821

  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 已提交
822 823 824 825
      perform_enqueued_jobs do
        user.email = "new-email@mail.com"
        user.save
      end
826 827 828 829
    end

    subject { ActionMailer::Base.deliveries.last }

830
    it_behaves_like 'an email sent from GitLab'
831
    it_behaves_like "a user cannot unsubscribe through footer link"
832

833
    it 'is sent to the new user' do
834
      is_expected.to deliver_to 'new-email@mail.com'
835 836 837
    end

    it 'has the correct subject' do
838
      is_expected.to have_subject "Confirmation instructions"
839 840 841
    end

    it 'includes a link to the site' do
842
      is_expected.to have_body_text /#{example_site_path}/
843 844
    end
  end
D
Dmitriy Zaporozhets 已提交
845

846 847 848 849 850
  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") }

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

853
    it_behaves_like 'it should not have Gmail Actions links'
854
    it_behaves_like "a user cannot unsubscribe through footer link"
855 856
    it_behaves_like 'an email with X-GitLab headers containing project details'
    it_behaves_like 'an email that contains a header with author username'
857

858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877
    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") }

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

880
    it_behaves_like 'it should not have Gmail Actions links'
881
    it_behaves_like "a user cannot unsubscribe through footer link"
882 883
    it_behaves_like 'an email with X-GitLab headers containing project details'
    it_behaves_like 'an email that contains a header with author username'
884

885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903
    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) }

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

906
    it_behaves_like 'it should not have Gmail Actions links'
907
    it_behaves_like "a user cannot unsubscribe through footer link"
908 909
    it_behaves_like 'an email with X-GitLab headers containing project details'
    it_behaves_like 'an email that contains a header with author username'
910

911 912 913 914 915 916 917 918 919 920 921 922 923 924 925
    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) }

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

928
    it_behaves_like 'it should not have Gmail Actions links'
929
    it_behaves_like "a user cannot unsubscribe through footer link"
930 931
    it_behaves_like 'an email with X-GitLab headers containing project details'
    it_behaves_like 'an email that contains a header with author username'
932

933 934 935 936 937 938 939 940 941 942 943
    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

944
  describe 'email on push with multiple commits' do
D
Dmitriy Zaporozhets 已提交
945 946
    let(:example_site_path) { root_path }
    let(:user) { create(:user) }
D
Dmitriy Zaporozhets 已提交
947
    let(:compare) { Gitlab::Git::Compare.new(project.repository.raw_repository, sample_image_commit.id, sample_commit.id) }
948 949
    let(:commits) { Commit.decorate(compare.commits, nil) }
    let(:diff_path) { namespace_project_compare_path(project.namespace, project, from: Commit.new(compare.base, project), to: Commit.new(compare.head, project)) }
950
    let(:send_from_committer_email) { false }
951
    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 已提交
952

953
    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 已提交
954

955
    it_behaves_like 'it should not have Gmail Actions links'
956
    it_behaves_like "a user cannot unsubscribe through footer link"
957 958
    it_behaves_like 'an email with X-GitLab headers containing project details'
    it_behaves_like 'an email that contains a header with author username'
959

960 961
    it 'is sent as the author' do
      sender = subject.header[:from].addrs[0]
962 963
      expect(sender.display_name).to eq(user.name)
      expect(sender.address).to eq(gitlab_sender)
964 965
    end

D
Dmitriy Zaporozhets 已提交
966
    it 'has the correct subject' do
967
      is_expected.to have_subject /\[#{project.path_with_namespace}\]\[master\] #{commits.length} commits:/
D
Dmitriy Zaporozhets 已提交
968 969 970
    end

    it 'includes commits list' do
971
      is_expected.to have_body_text /Change some files/
D
Dmitriy Zaporozhets 已提交
972 973
    end

974 975
    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 已提交
976
    end
977 978

    it 'contains a link to the diff' do
979
      is_expected.to have_body_text /#{diff_path}/
980
    end
981

982
    it 'does not contain the misleading footer' do
983 984
      is_expected.not_to have_body_text /you are a member of/
    end
985 986 987 988

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

989 990 991 992 993
      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
994
        before do
995
          user.update_attribute(:email, "user@company.com")
996
          user.confirm
997 998 999 1000 1001 1002
        end

        it "is sent from the committer email" do
          sender = subject.header[:from].addrs[0]
          expect(sender.address).to eq(user.email)
        end
1003 1004 1005 1006 1007

        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
1008 1009
      end

1010 1011 1012
      context "when the committer email domain is not completely within the GitLab domain" do
        before do
          user.update_attribute(:email, "user@something.company.com")
1013
          user.confirm
1014 1015 1016 1017 1018 1019
        end

        it "is sent from the default email" do
          sender = subject.header[:from].addrs[0]
          expect(sender.address).to eq(gitlab_sender)
        end
1020 1021 1022 1023 1024

        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
1025 1026 1027 1028 1029
      end

      context "when the committer email domain is outside the GitLab domain" do
        before do
          user.update_attribute(:email, "user@mpany.com")
1030
          user.confirm
1031
        end
1032 1033 1034 1035 1036

        it "is sent from the default email" do
          sender = subject.header[:from].addrs[0]
          expect(sender.address).to eq(gitlab_sender)
        end
1037 1038 1039 1040 1041

        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
1042 1043
      end
    end
D
Dmitriy Zaporozhets 已提交
1044
  end
1045 1046 1047 1048

  describe 'email on push with a single commit' do
    let(:example_site_path) { root_path }
    let(:user) { create(:user) }
D
Dmitriy Zaporozhets 已提交
1049
    let(:compare) { Gitlab::Git::Compare.new(project.repository.raw_repository, sample_commit.parent_id, sample_commit.id) }
1050
    let(:commits) { Commit.decorate(compare.commits, nil) }
V
Vinnie Okada 已提交
1051
    let(:diff_path) { namespace_project_commit_path(project.namespace, project, commits.first) }
1052
    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) }
1053

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

1056
    it_behaves_like 'it should show Gmail Actions View Commit link'
1057
    it_behaves_like "a user cannot unsubscribe through footer link"
1058 1059
    it_behaves_like 'an email with X-GitLab headers containing project details'
    it_behaves_like 'an email that contains a header with author username'
1060

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

    it 'has the correct subject' do
1068
      is_expected.to have_subject /#{commits.first.title}/
1069 1070 1071
    end

    it 'includes commits list' do
1072
      is_expected.to have_body_text /Change some files/
1073 1074
    end

1075 1076
    it 'includes diffs with character-level highlighting' do
      is_expected.to have_body_text /def<\/span> <span class=\"nf\">archive_formats_regex/
1077 1078 1079
    end

    it 'contains a link to the diff' do
1080
      is_expected.to have_body_text /#{diff_path}/
1081 1082
    end
  end
1083
end