diff options
-rw-r--r-- | app/models/sent_notification.rb | 6 | ||||
-rw-r--r-- | changelogs/unreleased/23888-fix-unsubscription-link-for-snippet-notification.yml | 5 | ||||
-rw-r--r-- | spec/mailers/notify_spec.rb | 491 | ||||
-rw-r--r-- | spec/models/sent_notification_spec.rb | 122 |
4 files changed, 390 insertions, 234 deletions
diff --git a/app/models/sent_notification.rb b/app/models/sent_notification.rb index 298569cb7a6..6e311806be1 100644 --- a/app/models/sent_notification.rb +++ b/app/models/sent_notification.rb @@ -53,13 +53,17 @@ class SentNotification < ActiveRecord::Base end def unsubscribable? - !for_commit? + !(for_commit? || for_snippet?) end def for_commit? noteable_type == "Commit" end + def for_snippet? + noteable_type.end_with?('Snippet') + end + def noteable if for_commit? project.commit(commit_id) rescue nil diff --git a/changelogs/unreleased/23888-fix-unsubscription-link-for-snippet-notification.yml b/changelogs/unreleased/23888-fix-unsubscription-link-for-snippet-notification.yml new file mode 100644 index 00000000000..36bed037160 --- /dev/null +++ b/changelogs/unreleased/23888-fix-unsubscription-link-for-snippet-notification.yml @@ -0,0 +1,5 @@ +--- +title: Don't show an "Unsubscribe" link in snippet comment notifications +merge_request: 14764 +author: +type: fixed diff --git a/spec/mailers/notify_spec.rb b/spec/mailers/notify_spec.rb index 932e2fd8c95..c832cee965b 100644 --- a/spec/mailers/notify_spec.rb +++ b/spec/mailers/notify_spec.rb @@ -28,319 +28,334 @@ describe Notify do end def have_referable_subject(referable, reply: false) - prefix = referable.project.name if referable.project - prefix = "Re: #{prefix}" if reply + prefix = referable.project ? "#{referable.project.name} | " : '' + prefix.prepend('Re: ') if reply suffix = "#{referable.title} (#{referable.to_reference})" - have_subject [prefix, suffix].compact.join(' | ') + have_subject [prefix, suffix].compact.join end context 'for a project' do - describe 'items that are assignable, the email' do - let(:previous_assignee) { create(:user, name: 'Previous Assignee') } + shared_examples 'an assignee email' do + it 'is sent to the assignee as the author' do + sender = subject.header[:from].addrs.first + + aggregate_failures do + expect(sender.display_name).to eq(current_user.name) + expect(sender.address).to eq(gitlab_sender) + expect(subject).to deliver_to(assignee.email) + end + end + end - shared_examples 'an assignee email' do - it 'is sent to the assignee as the author' do - sender = subject.header[:from].addrs.first + context 'for issues' do + describe 'that are new' do + subject { described_class.new_issue_email(issue.assignees.first.id, issue.id) } + it_behaves_like 'an assignee email' + it_behaves_like 'an email starting a new thread with reply-by-email enabled' do + let(:model) { issue } + end + it_behaves_like 'it should show Gmail Actions View Issue link' + it_behaves_like 'an unsubscribeable thread' + + it 'has the correct subject and body' do aggregate_failures do - expect(sender.display_name).to eq(current_user.name) - expect(sender.address).to eq(gitlab_sender) - expect(subject).to deliver_to(assignee.email) + is_expected.to have_referable_subject(issue) + is_expected.to have_body_text(project_issue_path(project, issue)) end end - end - context 'for issues' do - describe 'that are new' do - subject { described_class.new_issue_email(issue.assignees.first.id, issue.id) } + it 'contains the description' do + is_expected.to have_html_escaped_body_text issue.description + end - it_behaves_like 'an assignee email' - it_behaves_like 'an email starting a new thread with reply-by-email enabled' do - let(:model) { issue } - end - it_behaves_like 'it should show Gmail Actions View Issue link' - it_behaves_like 'an unsubscribeable thread' - - it 'has the correct subject and body' do - aggregate_failures do - is_expected.to have_referable_subject(issue) - is_expected.to have_body_text(project_issue_path(project, issue)) - end + context 'when enabled email_author_in_body' do + before do + stub_application_setting(email_author_in_body: true) end - it 'contains the description' do - is_expected.to have_html_escaped_body_text issue.description + it 'contains a link to note author' do + is_expected.to have_html_escaped_body_text(issue.author_name) + is_expected.to have_body_text 'created an issue:' end + end + end - context 'when enabled email_author_in_body' do - before do - stub_application_setting(email_author_in_body: true) - end + describe 'that are reassigned' do + let(:previous_assignee) { create(:user, name: 'Previous Assignee') } + subject { described_class.reassigned_issue_email(recipient.id, issue.id, [previous_assignee.id], current_user.id) } - it 'contains a link to note author' do - is_expected.to have_html_escaped_body_text(issue.author_name) - is_expected.to have_body_text 'created an issue:' - end - end + it_behaves_like 'a multiple recipients email' + it_behaves_like 'an answer to an existing thread with reply-by-email enabled' do + let(:model) { issue } end + it_behaves_like 'it should show Gmail Actions View Issue link' + it_behaves_like 'an unsubscribeable thread' - describe 'that have been reassigned' do - subject { described_class.reassigned_issue_email(recipient.id, issue.id, [previous_assignee.id], current_user.id) } + 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_behaves_like 'a multiple recipients email' - it_behaves_like 'an answer to an existing thread with reply-by-email enabled' do - let(:model) { issue } + it 'has the correct subject and body' do + aggregate_failures do + is_expected.to have_referable_subject(issue, reply: true) + is_expected.to have_html_escaped_body_text(previous_assignee.name) + is_expected.to have_html_escaped_body_text(assignee.name) + is_expected.to have_body_text(project_issue_path(project, issue)) end - it_behaves_like 'it should show Gmail Actions View Issue link' - it_behaves_like 'an unsubscribeable thread' + end + end - 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 + describe 'that have been relabeled' do + subject { described_class.relabeled_issue_email(recipient.id, issue.id, %w[foo bar baz], current_user.id) } - it 'has the correct subject and body' do - aggregate_failures do - is_expected.to have_referable_subject(issue, reply: true) - is_expected.to have_html_escaped_body_text(previous_assignee.name) - is_expected.to have_html_escaped_body_text(assignee.name) - is_expected.to have_body_text(project_issue_path(project, issue)) - end - end + it_behaves_like 'a multiple recipients email' + it_behaves_like 'an answer to an existing thread with reply-by-email enabled' do + let(:model) { issue } end + it_behaves_like 'it should show Gmail Actions View Issue link' + it_behaves_like 'a user cannot unsubscribe through footer link' + it_behaves_like 'an email with a labels subscriptions link in its footer' - describe 'that have been relabeled' do - subject { described_class.relabeled_issue_email(recipient.id, issue.id, %w[foo bar baz], current_user.id) } + 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_behaves_like 'a multiple recipients email' - it_behaves_like 'an answer to an existing thread with reply-by-email enabled' do - let(:model) { issue } + it 'has the correct subject and body' do + aggregate_failures do + is_expected.to have_referable_subject(issue, reply: true) + is_expected.to have_body_text('foo, bar, and baz') + is_expected.to have_body_text(project_issue_path(project, issue)) end - 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' + end - 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) + context 'with a preferred language' do + before do + Gitlab::I18n.locale = :es end - it 'has the correct subject and body' do - aggregate_failures do - is_expected.to have_referable_subject(issue, reply: true) - is_expected.to have_body_text('foo, bar, and baz') - is_expected.to have_body_text(project_issue_path(project, issue)) - end + after do + Gitlab::I18n.use_default_locale end - context 'with a preferred language' do - before do - Gitlab::I18n.locale = :es - end - - after do - Gitlab::I18n.use_default_locale - end - - it 'always generates the email using the default language' do - is_expected.to have_body_text('foo, bar, and baz') - end + it 'always generates the email using the default language' do + is_expected.to have_body_text('foo, bar, and baz') end end + end - describe 'status changed' do - let(:status) { 'closed' } - subject { described_class.issue_status_changed_email(recipient.id, issue.id, status, current_user.id) } + describe 'status changed' do + let(:status) { 'closed' } + subject { described_class.issue_status_changed_email(recipient.id, issue.id, status, current_user.id) } - it_behaves_like 'an answer to an existing thread with reply-by-email enabled' do - let(:model) { issue } - end - it_behaves_like 'it should show Gmail Actions View Issue link' - it_behaves_like 'an unsubscribeable thread' + it_behaves_like 'an answer to an existing thread with reply-by-email enabled' do + let(:model) { issue } + end + it_behaves_like 'it should show Gmail Actions View Issue link' + it_behaves_like 'an unsubscribeable thread' - it '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 '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 and body' do - aggregate_failures do - is_expected.to have_referable_subject(issue, reply: true) - is_expected.to have_body_text(status) - is_expected.to have_html_escaped_body_text(current_user.name) - is_expected.to have_body_text(project_issue_path project, issue) - end + it 'has the correct subject and body' do + aggregate_failures do + is_expected.to have_referable_subject(issue, reply: true) + is_expected.to have_body_text(status) + is_expected.to have_html_escaped_body_text(current_user.name) + is_expected.to have_body_text(project_issue_path project, issue) end end + end - describe 'moved to another project' do - let(:new_issue) { create(:issue) } - subject { described_class.issue_moved_email(recipient, issue, new_issue, current_user) } + describe 'moved to another project' do + let(:new_issue) { create(:issue) } + subject { described_class.issue_moved_email(recipient, issue, new_issue, current_user) } - it_behaves_like 'an answer to an existing thread with reply-by-email enabled' do - let(:model) { issue } - end - it_behaves_like 'it should show Gmail Actions View Issue link' - it_behaves_like 'an unsubscribeable thread' + it_behaves_like 'an answer to an existing thread with reply-by-email enabled' do + let(:model) { issue } + end + it_behaves_like 'it should show Gmail Actions View Issue link' + it_behaves_like 'an unsubscribeable thread' - it 'contains description about action taken' do - is_expected.to have_body_text 'Issue was moved to another project' - end + 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 and body' do - new_issue_url = project_issue_path(new_issue.project, new_issue) + it 'has the correct subject and body' do + new_issue_url = project_issue_path(new_issue.project, new_issue) - aggregate_failures do - is_expected.to have_referable_subject(issue, reply: true) - is_expected.to have_body_text(new_issue_url) - is_expected.to have_body_text(project_issue_path(project, issue)) - end + aggregate_failures do + is_expected.to have_referable_subject(issue, reply: true) + is_expected.to have_body_text(new_issue_url) + is_expected.to have_body_text(project_issue_path(project, issue)) end end end + end - context 'for merge requests' do - describe 'that are new' do - subject { described_class.new_merge_request_email(merge_request.assignee_id, merge_request.id) } + context 'for merge requests' do + describe 'that are new' do + subject { described_class.new_merge_request_email(merge_request.assignee_id, merge_request.id) } + + it_behaves_like 'an assignee email' + it_behaves_like 'an email starting a new thread with reply-by-email enabled' do + let(:model) { merge_request } + end + it_behaves_like 'it should show Gmail Actions View Merge request link' + it_behaves_like 'an unsubscribeable thread' - it_behaves_like 'an assignee email' - it_behaves_like 'an email starting a new thread with reply-by-email enabled' do - let(:model) { merge_request } + it 'has the correct subject and body' do + aggregate_failures do + is_expected.to have_referable_subject(merge_request) + is_expected.to have_body_text(project_merge_request_path(project, merge_request)) + is_expected.to have_body_text(merge_request.source_branch) + is_expected.to have_body_text(merge_request.target_branch) end - it_behaves_like 'it should show Gmail Actions View Merge request link' - it_behaves_like 'an unsubscribeable thread' - - it 'has the correct subject and body' do - aggregate_failures do - is_expected.to have_referable_subject(merge_request) - is_expected.to have_body_text(project_merge_request_path(project, merge_request)) - is_expected.to have_body_text(merge_request.source_branch) - is_expected.to have_body_text(merge_request.target_branch) - end + end + + it 'contains the description' do + is_expected.to have_html_escaped_body_text merge_request.description + end + + context 'when enabled email_author_in_body' do + before do + stub_application_setting(email_author_in_body: true) end - it 'contains the description' do - is_expected.to have_html_escaped_body_text merge_request.description + it 'contains a link to note author' do + is_expected.to have_html_escaped_body_text merge_request.author_name + is_expected.to have_body_text 'created a merge request:' end + end + end - context 'when enabled email_author_in_body' do - before do - stub_application_setting(email_author_in_body: true) - end + describe 'that are reassigned' do + let(:previous_assignee) { create(:user, name: 'Previous Assignee') } + subject { described_class.reassigned_merge_request_email(recipient.id, merge_request.id, previous_assignee.id, current_user.id) } - it 'contains a link to note author' do - is_expected.to have_html_escaped_body_text merge_request.author_name - is_expected.to have_body_text 'created a merge request:' - end - end + it_behaves_like 'a multiple recipients email' + it_behaves_like 'an answer to an existing thread with reply-by-email enabled' do + let(:model) { merge_request } end + it_behaves_like 'it should show Gmail Actions View Merge request link' + it_behaves_like "an unsubscribeable thread" - describe 'that are reassigned' do - subject { described_class.reassigned_merge_request_email(recipient.id, merge_request.id, previous_assignee.id, current_user.id) } + 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_behaves_like 'a multiple recipients email' - it_behaves_like 'an answer to an existing thread with reply-by-email enabled' do - let(:model) { merge_request } + it 'has the correct subject and body' do + aggregate_failures do + is_expected.to have_referable_subject(merge_request, reply: true) + is_expected.to have_html_escaped_body_text(previous_assignee.name) + is_expected.to have_body_text(project_merge_request_path(project, merge_request)) + is_expected.to have_html_escaped_body_text(assignee.name) end - it_behaves_like 'it should show Gmail Actions View Merge request link' - it_behaves_like "an unsubscribeable thread" + end + end - 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 + describe 'that have been relabeled' do + subject { described_class.relabeled_merge_request_email(recipient.id, merge_request.id, %w[foo bar baz], current_user.id) } - it 'has the correct subject and body' do - aggregate_failures do - is_expected.to have_referable_subject(merge_request, reply: true) - is_expected.to have_html_escaped_body_text(previous_assignee.name) - is_expected.to have_body_text(project_merge_request_path(project, merge_request)) - is_expected.to have_html_escaped_body_text(assignee.name) - end - end + it_behaves_like 'a multiple recipients email' + it_behaves_like 'an answer to an existing thread with reply-by-email enabled' do + let(:model) { merge_request } end + it_behaves_like 'it should show Gmail Actions View Merge request link' + it_behaves_like 'a user cannot unsubscribe through footer link' + it_behaves_like 'an email with a labels subscriptions link in its footer' - describe 'that have been relabeled' do - subject { described_class.relabeled_merge_request_email(recipient.id, merge_request.id, %w[foo bar baz], current_user.id) } + 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_behaves_like 'a multiple recipients email' - it_behaves_like 'an answer to an existing thread with reply-by-email enabled' do - let(:model) { merge_request } - end - it_behaves_like 'it should show Gmail Actions View Merge request link' - it_behaves_like 'a user cannot unsubscribe through footer link' - it_behaves_like 'an email with a labels subscriptions link in its footer' + it 'has the correct subject and body' do + is_expected.to have_referable_subject(merge_request, reply: true) + is_expected.to have_body_text('foo, bar, and baz') + is_expected.to have_body_text(project_merge_request_path(project, merge_request)) + end + end - 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 + describe 'status changed' do + let(:status) { 'reopened' } + subject { described_class.merge_request_status_email(recipient.id, merge_request.id, status, current_user.id) } - it 'has the correct subject and body' do + it_behaves_like 'an answer to an existing thread with reply-by-email enabled' do + let(:model) { merge_request } + end + it_behaves_like 'it should show Gmail Actions View Merge request link' + it_behaves_like 'an unsubscribeable thread' + + it '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 and body' do + aggregate_failures do is_expected.to have_referable_subject(merge_request, reply: true) - is_expected.to have_body_text('foo, bar, and baz') + is_expected.to have_body_text(status) + is_expected.to have_html_escaped_body_text(current_user.name) is_expected.to have_body_text(project_merge_request_path(project, merge_request)) end end + end - describe 'status changed' do - let(:status) { 'reopened' } - subject { described_class.merge_request_status_email(recipient.id, merge_request.id, status, current_user.id) } + describe 'that are merged' do + let(:merge_author) { create(:user) } + subject { described_class.merged_merge_request_email(recipient.id, merge_request.id, merge_author.id) } - it_behaves_like 'an answer to an existing thread with reply-by-email enabled' do - let(:model) { merge_request } - end - it_behaves_like 'it should show Gmail Actions View Merge request link' - it_behaves_like 'an unsubscribeable thread' + it_behaves_like 'a multiple recipients email' + it_behaves_like 'an answer to an existing thread with reply-by-email enabled' do + let(:model) { merge_request } + end + it_behaves_like 'it should show Gmail Actions View Merge request link' + it_behaves_like 'an unsubscribeable thread' - it '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 'is sent as the merge author' do + sender = subject.header[:from].addrs[0] + expect(sender.display_name).to eq(merge_author.name) + expect(sender.address).to eq(gitlab_sender) + end - it 'has the correct subject and body' do - aggregate_failures do - is_expected.to have_referable_subject(merge_request, reply: true) - is_expected.to have_body_text(status) - is_expected.to have_html_escaped_body_text(current_user.name) - is_expected.to have_body_text(project_merge_request_path(project, merge_request)) - end + it 'has the correct subject and body' do + aggregate_failures do + is_expected.to have_referable_subject(merge_request, reply: true) + is_expected.to have_body_text('merged') + is_expected.to have_body_text(project_merge_request_path(project, merge_request)) end end + end + end - describe 'that are merged' do - let(:merge_author) { create(:user) } - subject { described_class.merged_merge_request_email(recipient.id, merge_request.id, merge_author.id) } + context 'for snippet notes' do + let(:project_snippet) { create(:project_snippet, project: project) } + let(:project_snippet_note) { create(:note_on_project_snippet, project: project, noteable: project_snippet) } - it_behaves_like 'a multiple recipients email' - it_behaves_like 'an answer to an existing thread with reply-by-email enabled' do - let(:model) { merge_request } - end - it_behaves_like 'it should show Gmail Actions View Merge request link' - it_behaves_like 'an unsubscribeable thread' + subject { described_class.note_snippet_email(project_snippet_note.author_id, project_snippet_note.id) } - it 'is sent as the merge author' do - sender = subject.header[:from].addrs[0] - expect(sender.display_name).to eq(merge_author.name) - expect(sender.address).to eq(gitlab_sender) - end + it_behaves_like 'an answer to an existing thread with reply-by-email enabled' do + let(:model) { project_snippet } + end + it_behaves_like 'a user cannot unsubscribe through footer link' - it 'has the correct subject and body' do - aggregate_failures do - is_expected.to have_referable_subject(merge_request, reply: true) - is_expected.to have_body_text('merged') - is_expected.to have_body_text(project_merge_request_path(project, merge_request)) - end - end - end + it 'has the correct subject and body' do + is_expected.to have_referable_subject(project_snippet, reply: true) + is_expected.to have_html_escaped_body_text project_snippet_note.note end end @@ -1239,4 +1254,18 @@ describe Notify do end end end + + context 'for personal snippet notes' do + let(:personal_snippet) { create(:personal_snippet) } + let(:personal_snippet_note) { create(:note_on_personal_snippet, noteable: personal_snippet) } + + subject { described_class.note_personal_snippet_email(personal_snippet_note.author_id, personal_snippet_note.id) } + + it_behaves_like 'a user cannot unsubscribe through footer link' + + it 'has the correct subject and body' do + is_expected.to have_referable_subject(personal_snippet, reply: true) + is_expected.to have_html_escaped_body_text personal_snippet_note.note + end + end end diff --git a/spec/models/sent_notification_spec.rb b/spec/models/sent_notification_spec.rb index 8f05deb8b15..5ec04b99957 100644 --- a/spec/models/sent_notification_spec.rb +++ b/spec/models/sent_notification_spec.rb @@ -1,6 +1,9 @@ require 'spec_helper' describe SentNotification do + set(:user) { create(:user) } + set(:project) { create(:project) } + describe 'validation' do describe 'note validity' do context "when the project doesn't match the noteable's project" do @@ -34,7 +37,6 @@ describe SentNotification do end describe '.record' do - let(:user) { create(:user) } let(:issue) { create(:issue) } it 'creates a new SentNotification' do @@ -43,7 +45,6 @@ describe SentNotification do end describe '.record_note' do - let(:user) { create(:user) } let(:note) { create(:diff_note_on_merge_request) } it 'creates a new SentNotification' do @@ -51,6 +52,123 @@ describe SentNotification do end end + describe '#unsubscribable?' do + shared_examples 'an unsubscribable notification' do |noteable_type| + subject { described_class.record(noteable, user.id) } + + context "for #{noteable_type}" do + it { expect(subject).to be_unsubscribable } + end + end + + shared_examples 'a non-unsubscribable notification' do |noteable_type| + subject { described_class.record(noteable, user.id) } + + context "for a #{noteable_type}" do + it { expect(subject).not_to be_unsubscribable } + end + end + + it_behaves_like 'an unsubscribable notification', 'issue' do + let(:noteable) { create(:issue, project: project) } + end + + it_behaves_like 'an unsubscribable notification', 'merge request' do + let(:noteable) { create(:merge_request, source_project: project) } + end + + it_behaves_like 'a non-unsubscribable notification', 'commit' do + let(:project) { create(:project, :repository) } + let(:noteable) { project.commit } + end + + it_behaves_like 'a non-unsubscribable notification', 'personal snippet' do + let(:noteable) { create(:personal_snippet, project: project) } + end + + it_behaves_like 'a non-unsubscribable notification', 'project snippet' do + let(:noteable) { create(:project_snippet, project: project) } + end + end + + describe '#for_commit?' do + shared_examples 'a commit notification' do |noteable_type| + subject { described_class.record(noteable, user.id) } + + context "for #{noteable_type}" do + it { expect(subject).to be_for_commit } + end + end + + shared_examples 'a non-commit notification' do |noteable_type| + subject { described_class.record(noteable, user.id) } + + context "for a #{noteable_type}" do + it { expect(subject).not_to be_for_commit } + end + end + + it_behaves_like 'a non-commit notification', 'issue' do + let(:noteable) { create(:issue, project: project) } + end + + it_behaves_like 'a non-commit notification', 'merge request' do + let(:noteable) { create(:merge_request, source_project: project) } + end + + it_behaves_like 'a commit notification', 'commit' do + let(:project) { create(:project, :repository) } + let(:noteable) { project.commit } + end + + it_behaves_like 'a non-commit notification', 'personal snippet' do + let(:noteable) { create(:personal_snippet, project: project) } + end + + it_behaves_like 'a non-commit notification', 'project snippet' do + let(:noteable) { create(:project_snippet, project: project) } + end + end + + describe '#for_snippet?' do + shared_examples 'a snippet notification' do |noteable_type| + subject { described_class.record(noteable, user.id) } + + context "for #{noteable_type}" do + it { expect(subject).to be_for_snippet } + end + end + + shared_examples 'a non-snippet notification' do |noteable_type| + subject { described_class.record(noteable, user.id) } + + context "for a #{noteable_type}" do + it { expect(subject).not_to be_for_snippet } + end + end + + it_behaves_like 'a non-snippet notification', 'issue' do + let(:noteable) { create(:issue, project: project) } + end + + it_behaves_like 'a non-snippet notification', 'merge request' do + let(:noteable) { create(:merge_request, source_project: project) } + end + + it_behaves_like 'a non-snippet notification', 'commit' do + let(:project) { create(:project, :repository) } + let(:noteable) { project.commit } + end + + it_behaves_like 'a snippet notification', 'personal snippet' do + let(:noteable) { create(:personal_snippet, project: project) } + end + + it_behaves_like 'a snippet notification', 'project snippet' do + let(:noteable) { create(:project_snippet, project: project) } + end + end + describe '#create_reply' do context 'for issue' do let(:issue) { create(:issue) } |