notify_spec.rb 40.3 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 16
      let(:assignee) { create(:user, email: 'assignee@example.com') }
      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 404 405 406 407 408 409
    describe 'project access requested' do
      let(:project) { create(:project) }
      let(:user) { create(:user) }
      let(:project_member) do
        project.request_access(user)
        project.project_members.find_by(created_by_id: user.id)
      end
410
      subject { Notify.member_access_requested_email('project', project_member.id) }
R
Rémy Coutable 已提交
411 412 413 414 415

      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"

416 417 418 419
      it { is_expected.to have_subject "Request to join the #{project.name_with_namespace} project" }
      it { is_expected.to have_body_text /#{project.name_with_namespace}/ }
      it { is_expected.to have_body_text /#{project.web_url}/ }
      it { is_expected.to have_body_text /#{project_member.human_access}/ }
R
Rémy Coutable 已提交
420 421 422 423 424 425 426 427 428
    end

    describe 'project access denied' do
      let(:project) { create(:project) }
      let(:user) { create(:user) }
      let(:project_member) do
        project.request_access(user)
        project.project_members.find_by(created_by_id: user.id)
      end
429
      subject { Notify.member_access_denied_email('project', project.id, user.id) }
R
Rémy Coutable 已提交
430 431 432 433 434

      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"

435 436 437
      it { is_expected.to have_subject "Access to the #{project.name_with_namespace} project was denied" }
      it { is_expected.to have_body_text /#{project.name_with_namespace}/ }
      it { is_expected.to have_body_text /#{project.web_url}/ }
R
Rémy Coutable 已提交
438 439
    end

440
    describe 'project access changed' do
441
      let(:project) { create(:project) }
442
      let(:user) { create(:user) }
443
      let(:project_member) { create(:project_member, project: project, user: user) }
444
      subject { Notify.member_access_granted_email('project', project_member.id) }
445 446

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

450 451 452 453 454
      it { is_expected.to have_subject "Access to the #{project.name_with_namespace} project was granted" }
      it { is_expected.to have_body_text /#{project.name_with_namespace}/ }
      it { is_expected.to have_body_text /#{project.web_url}/ }
      it { is_expected.to have_body_text /#{project_member.human_access}/ }
    end
455

456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487
    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"

      it { is_expected.to have_subject "Invitation to join the #{project.name_with_namespace} project" }
      it { is_expected.to have_body_text /#{project.name_with_namespace}/ }
      it { is_expected.to have_body_text /#{project.web_url}/ }
      it { is_expected.to have_body_text /#{project_member.human_access}/ }
      it { is_expected.to have_body_text /#{project_member.invite_token}/ }
    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
488
      end
489

490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509
      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"

      it { is_expected.to have_subject 'Invitation accepted' }
      it { is_expected.to have_body_text /#{project.name_with_namespace}/ }
      it { is_expected.to have_body_text /#{project.web_url}/ }
      it { is_expected.to have_body_text /#{project_member.invite_email}/ }
      it { is_expected.to have_body_text /#{invited_user.name}/ }
    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
510
      end
511 512 513 514 515 516 517 518 519 520 521

      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"

      it { is_expected.to have_subject 'Invitation declined' }
      it { is_expected.to have_body_text /#{project.name_with_namespace}/ }
      it { is_expected.to have_body_text /#{project.web_url}/ }
      it { is_expected.to have_body_text /#{project_member.invite_email}/ }
522 523
    end

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

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

R
Robb Kidd 已提交
532
      shared_examples 'a note email' do
533 534
        it_behaves_like 'it should have Gmail Actions links'

535 536
        it 'is sent as the author' do
          sender = subject.header[:from].addrs[0]
537 538
          expect(sender.display_name).to eq(note_author.name)
          expect(sender.address).to eq(gitlab_sender)
539 540
        end

R
Robb Kidd 已提交
541
        it 'is sent to the given recipient' do
542
          is_expected.to deliver_to recipient.notification_email
R
Robb Kidd 已提交
543 544 545
        end

        it 'contains the message from the note' do
546
          is_expected.to have_body_text /#{note.note}/
R
Robb Kidd 已提交
547
        end
548 549 550 551 552 553 554

        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
555
            allow_any_instance_of(ApplicationSetting).to receive(:email_author_in_body).and_return(true)
556 557 558 559 560 561 562
          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 已提交
563 564 565
      end

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

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

D
Dmitriy Zaporozhets 已提交
570
        subject { Notify.note_commit_email(recipient.id, note.id) }
R
Robb Kidd 已提交
571 572

        it_behaves_like 'a note email'
573 574 575
        it_behaves_like 'an answer to an existing thread with reply-by-email enabled' do
          let(:model) { commit }
        end
576
        it_behaves_like 'it should show Gmail Actions View Commit link'
577
        it_behaves_like 'a user cannot unsubscribe through footer link'
R
Robb Kidd 已提交
578 579

        it 'has the correct subject' do
580
          is_expected.to have_subject /#{commit.title} \(#{commit.short_id}\)/
R
Robb Kidd 已提交
581 582 583
        end

        it 'contains a link to the commit' do
584
          is_expected.to have_body_text commit.short_id
R
Robb Kidd 已提交
585 586 587 588
        end
      end

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

593
        subject { Notify.note_merge_request_email(recipient.id, note.id) }
R
Robb Kidd 已提交
594 595

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

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

        it 'contains a link to the merge request note' do
607
          is_expected.to have_body_text /#{note_on_merge_request_path}/
R
Robb Kidd 已提交
608 609 610 611
        end
      end

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

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

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

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

        it 'contains a link to the issue note' do
630
          is_expected.to have_body_text /#{note_on_issue_path}/
R
Robb Kidd 已提交
631 632
        end
      end
633 634
    end
  end
635

636 637 638 639 640 641 642 643 644
  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)
        group.group_members.find_by(created_by_id: user.id)
      end
      subject { Notify.member_access_requested_email('group', group_member.id) }
R
Rémy Coutable 已提交
645

646 647 648
      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 已提交
649

650 651 652 653
      it { is_expected.to have_subject "Request to join the #{group.name} group" }
      it { is_expected.to have_body_text /#{group.name}/ }
      it { is_expected.to have_body_text /#{group.web_url}/ }
      it { is_expected.to have_body_text /#{group_member.human_access}/ }
R
Rémy Coutable 已提交
654 655
    end

656 657 658 659 660 661 662 663
    describe 'group access denied' do
      let(:group) { create(:group) }
      let(:user) { create(:user) }
      let(:group_member) do
        group.request_access(user)
        group.group_members.find_by(created_by_id: user.id)
      end
      subject { Notify.member_access_denied_email('group', group.id, user.id) }
R
Rémy Coutable 已提交
664

665 666 667
      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 已提交
668

669 670 671
      it { is_expected.to have_subject "Access to the #{group.name} group was denied" }
      it { is_expected.to have_body_text /#{group.name}/ }
      it { is_expected.to have_body_text /#{group.web_url}/ }
R
Rémy Coutable 已提交
672 673
    end

674 675 676 677
    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 已提交
678

679 680 681 682 683 684 685 686 687 688
      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"

      it { is_expected.to have_subject "Access to the #{group.name} group was granted" }
      it { is_expected.to have_body_text /#{group.name}/ }
      it { is_expected.to have_body_text /#{group.web_url}/ }
      it { is_expected.to have_body_text /#{group_member.human_access}/ }
R
Rémy Coutable 已提交
689 690
    end

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

697 698 699 700
    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) }
701

702
      subject { Notify.member_invited_email('group', group_member.id, group_member.invite_token) }
703

704 705 706
      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"
707

708 709 710 711 712
      it { is_expected.to have_subject "Invitation to join the #{group.name} group" }
      it { is_expected.to have_body_text /#{group.name}/ }
      it { is_expected.to have_body_text /#{group.web_url}/ }
      it { is_expected.to have_body_text /#{group_member.human_access}/ }
      it { is_expected.to have_body_text /#{group_member.invite_token}/ }
713 714
    end

715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735
    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"

      it { is_expected.to have_subject 'Invitation accepted' }
      it { is_expected.to have_body_text /#{group.name}/ }
      it { is_expected.to have_body_text /#{group.web_url}/ }
      it { is_expected.to have_body_text /#{group_member.invite_email}/ }
      it { is_expected.to have_body_text /#{invited_user.name}/ }
736 737
    end

738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756
    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"

      it { is_expected.to have_subject 'Invitation declined' }
      it { is_expected.to have_body_text /#{group.name}/ }
      it { is_expected.to have_body_text /#{group.web_url}/ }
      it { is_expected.to have_body_text /#{group_member.invite_email}/ }
757 758
    end
  end
759 760 761 762 763 764

  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 已提交
765 766 767 768
      perform_enqueued_jobs do
        user.email = "new-email@mail.com"
        user.save
      end
769 770 771 772
    end

    subject { ActionMailer::Base.deliveries.last }

773
    it_behaves_like 'an email sent from GitLab'
774
    it_behaves_like "a user cannot unsubscribe through footer link"
775

776
    it 'is sent to the new user' do
777
      is_expected.to deliver_to 'new-email@mail.com'
778 779 780
    end

    it 'has the correct subject' do
781
      is_expected.to have_subject "Confirmation instructions"
782 783 784
    end

    it 'includes a link to the site' do
785
      is_expected.to have_body_text /#{example_site_path}/
786 787
    end
  end
D
Dmitriy Zaporozhets 已提交
788

789 790 791 792 793
  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") }

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

796
    it_behaves_like 'it should not have Gmail Actions links'
797
    it_behaves_like "a user cannot unsubscribe through footer link"
798 799
    it_behaves_like 'an email with X-GitLab headers containing project details'
    it_behaves_like 'an email that contains a header with author username'
800

801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820
    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") }

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

823
    it_behaves_like 'it should not have Gmail Actions links'
824
    it_behaves_like "a user cannot unsubscribe through footer link"
825 826
    it_behaves_like 'an email with X-GitLab headers containing project details'
    it_behaves_like 'an email that contains a header with author username'
827

828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846
    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) }

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

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

854 855 856 857 858 859 860 861 862 863 864 865 866 867 868
    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) }

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

871
    it_behaves_like 'it should not have Gmail Actions links'
872
    it_behaves_like "a user cannot unsubscribe through footer link"
873 874
    it_behaves_like 'an email with X-GitLab headers containing project details'
    it_behaves_like 'an email that contains a header with author username'
875

876 877 878 879 880 881 882 883 884 885 886
    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

887
  describe 'email on push with multiple commits' do
D
Dmitriy Zaporozhets 已提交
888 889
    let(:example_site_path) { root_path }
    let(:user) { create(:user) }
D
Dmitriy Zaporozhets 已提交
890
    let(:compare) { Gitlab::Git::Compare.new(project.repository.raw_repository, sample_image_commit.id, sample_commit.id) }
891 892
    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)) }
893
    let(:send_from_committer_email) { false }
894
    let(:diff_refs) { [project.merge_base_commit(sample_image_commit.id, sample_commit.id), project.commit(sample_commit.id)] }
D
Dmitriy Zaporozhets 已提交
895

896
    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 已提交
897

898
    it_behaves_like 'it should not have Gmail Actions links'
899
    it_behaves_like "a user cannot unsubscribe through footer link"
900 901
    it_behaves_like 'an email with X-GitLab headers containing project details'
    it_behaves_like 'an email that contains a header with author username'
902

903 904
    it 'is sent as the author' do
      sender = subject.header[:from].addrs[0]
905 906
      expect(sender.display_name).to eq(user.name)
      expect(sender.address).to eq(gitlab_sender)
907 908
    end

D
Dmitriy Zaporozhets 已提交
909
    it 'has the correct subject' do
910
      is_expected.to have_subject /\[#{project.path_with_namespace}\]\[master\] #{commits.length} commits:/
D
Dmitriy Zaporozhets 已提交
911 912 913
    end

    it 'includes commits list' do
914
      is_expected.to have_body_text /Change some files/
D
Dmitriy Zaporozhets 已提交
915 916
    end

917 918
    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 已提交
919
    end
920 921

    it 'contains a link to the diff' do
922
      is_expected.to have_body_text /#{diff_path}/
923
    end
924

925
    it 'does not contain the misleading footer' do
926 927
      is_expected.not_to have_body_text /you are a member of/
    end
928 929 930 931 932

    context "when set to send from committer email if domain matches" do

      let(:send_from_committer_email) { true }

933 934 935 936 937
      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
938 939

        before do
940
          user.update_attribute(:email, "user@company.com")
941
          user.confirm
942 943 944 945 946 947
        end

        it "is sent from the committer email" do
          sender = subject.header[:from].addrs[0]
          expect(sender.address).to eq(user.email)
        end
948 949 950 951 952

        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
953 954
      end

955 956 957 958
      context "when the committer email domain is not completely within the GitLab domain" do

        before do
          user.update_attribute(:email, "user@something.company.com")
959
          user.confirm
960 961 962 963 964 965
        end

        it "is sent from the default email" do
          sender = subject.header[:from].addrs[0]
          expect(sender.address).to eq(gitlab_sender)
        end
966 967 968 969 970

        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
971 972 973 974 975 976
      end

      context "when the committer email domain is outside the GitLab domain" do

        before do
          user.update_attribute(:email, "user@mpany.com")
977
          user.confirm
978
        end
979 980 981 982 983

        it "is sent from the default email" do
          sender = subject.header[:from].addrs[0]
          expect(sender.address).to eq(gitlab_sender)
        end
984 985 986 987 988

        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
989 990
      end
    end
D
Dmitriy Zaporozhets 已提交
991
  end
992 993 994 995

  describe 'email on push with a single commit' do
    let(:example_site_path) { root_path }
    let(:user) { create(:user) }
D
Dmitriy Zaporozhets 已提交
996
    let(:compare) { Gitlab::Git::Compare.new(project.repository.raw_repository, sample_commit.parent_id, sample_commit.id) }
997
    let(:commits) { Commit.decorate(compare.commits, nil) }
V
Vinnie Okada 已提交
998
    let(:diff_path) { namespace_project_commit_path(project.namespace, project, commits.first) }
999
    let(:diff_refs) { [project.merge_base_commit(sample_commit.parent_id, sample_commit.id), project.commit(sample_commit.id)] }
1000

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

1003
    it_behaves_like 'it should show Gmail Actions View Commit link'
1004
    it_behaves_like "a user cannot unsubscribe through footer link"
1005 1006
    it_behaves_like 'an email with X-GitLab headers containing project details'
    it_behaves_like 'an email that contains a header with author username'
1007

1008 1009
    it 'is sent as the author' do
      sender = subject.header[:from].addrs[0]
1010 1011
      expect(sender.display_name).to eq(user.name)
      expect(sender.address).to eq(gitlab_sender)
1012 1013 1014
    end

    it 'has the correct subject' do
1015
      is_expected.to have_subject /#{commits.first.title}/
1016 1017 1018
    end

    it 'includes commits list' do
1019
      is_expected.to have_body_text /Change some files/
1020 1021
    end

1022 1023
    it 'includes diffs with character-level highlighting' do
      is_expected.to have_body_text /def<\/span> <span class=\"nf\">archive_formats_regex/
1024 1025 1026
    end

    it 'contains a link to the diff' do
1027
      is_expected.to have_body_text /#{diff_path}/
1028 1029
    end
  end
1030

1031
end