diff options
Diffstat (limited to 'spec')
10 files changed, 694 insertions, 224 deletions
diff --git a/spec/features/admin/admin_settings_spec.rb b/spec/features/admin/admin_settings_spec.rb index eb59de2e132..be34315118d 100644 --- a/spec/features/admin/admin_settings_spec.rb +++ b/spec/features/admin/admin_settings_spec.rb @@ -216,7 +216,7 @@ describe 'Admin updates settings' do fill_in 'Username', with: 'test_user' fill_in 'service_push_channel', with: '#test_channel' page.check('Notify only broken pipelines') - page.check('Notify only default branch') + page.select 'All branches', from: 'Branches to be notified' check_all_events click_on 'Save' diff --git a/spec/models/ci/build_spec.rb b/spec/models/ci/build_spec.rb index bc853d45085..5c0f8bd392a 100644 --- a/spec/models/ci/build_spec.rb +++ b/spec/models/ci/build_spec.rb @@ -2215,6 +2215,7 @@ describe Ci::Build do { key: 'CI_PROJECT_NAMESPACE', value: project.namespace.full_path, public: true, masked: false }, { key: 'CI_PROJECT_URL', value: project.web_url, public: true, masked: false }, { key: 'CI_PROJECT_VISIBILITY', value: 'private', public: true, masked: false }, + { key: 'CI_PROJECT_REPOSITORY_LANGUAGES', value: project.repository_languages.map(&:name).join(',').downcase, public: true, masked: false }, { key: 'CI_PAGES_DOMAIN', value: Gitlab.config.pages.host, public: true, masked: false }, { key: 'CI_PAGES_URL', value: project.pages_url, public: true, masked: false }, { key: 'CI_API_V4_URL', value: 'http://localhost/api/v4', public: true, masked: false }, diff --git a/spec/models/project_services/mattermost_service_spec.rb b/spec/models/project_services/mattermost_service_spec.rb index 6261c70f266..5b974985706 100644 --- a/spec/models/project_services/mattermost_service_spec.rb +++ b/spec/models/project_services/mattermost_service_spec.rb @@ -3,5 +3,5 @@ require 'spec_helper' describe MattermostService do - it_behaves_like "slack or mattermost notifications" + it_behaves_like "slack or mattermost notifications", "Mattermost" end diff --git a/spec/models/project_services/microsoft_teams_service_spec.rb b/spec/models/project_services/microsoft_teams_service_spec.rb index 73c20359091..275244fa5fd 100644 --- a/spec/models/project_services/microsoft_teams_service_spec.rb +++ b/spec/models/project_services/microsoft_teams_service_spec.rb @@ -226,9 +226,10 @@ describe MicrosoftTeamsService do ) end - shared_examples 'call Microsoft Teams API' do + shared_examples 'call Microsoft Teams API' do |branches_to_be_notified: nil| before do WebMock.stub_request(:post, webhook_url) + chat_service.branches_to_be_notified = branches_to_be_notified if branches_to_be_notified end it 'calls Microsoft Teams API for pipeline events' do @@ -245,6 +246,18 @@ describe MicrosoftTeamsService do end end + shared_examples 'does not call Microsoft Teams API' do |branches_to_be_notified: nil| + before do + chat_service.branches_to_be_notified = branches_to_be_notified if branches_to_be_notified + end + it 'does not call Microsoft Teams API for pipeline events' do + data = Gitlab::DataBuilder::Pipeline.build(pipeline) + result = chat_service.execute(data) + + expect(result).to be_falsy + end + end + context 'with failed pipeline' do let(:status) { 'failed' } @@ -272,35 +285,73 @@ describe MicrosoftTeamsService do end end - context 'only notify for the default branch' do - context 'when enabled' do - let(:pipeline) do - create(:ci_pipeline, project: project, status: 'failed', ref: 'not-the-default-branch') - end + context 'with default branch' do + let(:pipeline) do + create(:ci_pipeline, project: project, status: 'failed', sha: project.commit.sha, ref: project.default_branch) + end - before do - chat_service.notify_only_default_branch = true - end + context 'only notify for the default branch' do + it_behaves_like 'call Microsoft Teams API', branches_to_be_notified: "default" + end - it 'does not call the Microsoft Teams API for pipeline events' do - data = Gitlab::DataBuilder::Pipeline.build(pipeline) - result = chat_service.execute(data) + context 'notify for only protected branches' do + it_behaves_like 'does not call Microsoft Teams API', branches_to_be_notified: "protected" + end - expect(result).to be_falsy - end + context 'notify for only default and protected branches' do + it_behaves_like 'call Microsoft Teams API', branches_to_be_notified: "default_and_protected" end - context 'when disabled' do - let(:pipeline) do - create(:ci_pipeline, :failed, project: project, - sha: project.commit.sha, ref: 'not-the-default-branch') - end + context 'notify for all branches' do + it_behaves_like 'call Microsoft Teams API', branches_to_be_notified: "all" + end + end - before do - chat_service.notify_only_default_branch = false - end + context 'with protected branch' do + before do + create(:protected_branch, project: project, name: 'a-protected-branch') + end - it_behaves_like 'call Microsoft Teams API' + let(:pipeline) do + create(:ci_pipeline, project: project, status: 'failed', sha: project.commit.sha, ref: 'a-protected-branch') + end + + context 'only notify for the default branch' do + it_behaves_like 'does not call Microsoft Teams API', branches_to_be_notified: "default" + end + + context 'notify for only protected branches' do + it_behaves_like 'call Microsoft Teams API', branches_to_be_notified: "protected" + end + + context 'notify for only default and protected branches' do + it_behaves_like 'call Microsoft Teams API', branches_to_be_notified: "default_and_protected" + end + + context 'notify for all branches' do + it_behaves_like 'call Microsoft Teams API', branches_to_be_notified: "all" + end + end + + context 'with neither protected nor default branch' do + let(:pipeline) do + create(:ci_pipeline, project: project, status: 'failed', sha: project.commit.sha, ref: 'a-random-branch') + end + + context 'only notify for the default branch' do + it_behaves_like 'does not call Microsoft Teams API', branches_to_be_notified: "default" + end + + context 'notify for only protected branches' do + it_behaves_like 'does not call Microsoft Teams API', branches_to_be_notified: "protected" + end + + context 'notify for only default and protected branches' do + it_behaves_like 'does not call Microsoft Teams API', branches_to_be_notified: "default_and_protected" + end + + context 'notify for all branches' do + it_behaves_like 'call Microsoft Teams API', branches_to_be_notified: "all" end end end diff --git a/spec/models/project_services/pipelines_email_service_spec.rb b/spec/models/project_services/pipelines_email_service_spec.rb index b85565e0c25..67358d6c3d6 100644 --- a/spec/models/project_services/pipelines_email_service_spec.rb +++ b/spec/models/project_services/pipelines_email_service_spec.rb @@ -53,9 +53,10 @@ describe PipelinesEmailService, :mailer do end end - shared_examples 'sending email' do + shared_examples 'sending email' do |branches_to_be_notified: nil| before do subject.recipients = recipients + subject.branches_to_be_notified = branches_to_be_notified if branches_to_be_notified perform_enqueued_jobs do run @@ -69,9 +70,10 @@ describe PipelinesEmailService, :mailer do end end - shared_examples 'not sending email' do + shared_examples 'not sending email' do |branches_to_be_notified: nil| before do subject.recipients = recipients + subject.branches_to_be_notified = branches_to_be_notified if branches_to_be_notified perform_enqueued_jobs do run @@ -101,27 +103,84 @@ describe PipelinesEmailService, :mailer do it_behaves_like 'sending email' end - context 'when pipeline is failed and on a non-default branch' do - before do - data[:object_attributes][:ref] = 'not-the-default-branch' - pipeline.update(ref: 'not-the-default-branch') + context 'when the pipeline failed' do + context 'on default branch' do + before do + data[:object_attributes][:ref] = project.default_branch + pipeline.update(ref: project.default_branch) + end + + context 'notifications are enabled only for default branch' do + it_behaves_like 'sending email', branches_to_be_notified: "default" + end + + context 'notifications are enabled only for protected branch' do + it_behaves_like 'sending email', branches_to_be_notified: "protected" + end + + context 'notifications are enabled only for default and protected branches ' do + it_behaves_like 'sending email', branches_to_be_notified: "default_and_protected" + end + + context 'notifications are enabled only for all branches' do + it_behaves_like 'sending email', branches_to_be_notified: "all" + end end - context 'with notify_only_default branch on' do + context 'on a protected branch' do before do - subject.notify_only_default_branch = true + create(:protected_branch, project: project, name: 'a-protected-branch') + data[:object_attributes][:ref] = 'a-protected-branch' + pipeline.update(ref: 'a-protected-branch') end - it_behaves_like 'sending email' + context 'notifications are enabled only for default branch' do + it_behaves_like 'sending email', branches_to_be_notified: "default" + end + + context 'notifications are enabled only for protected branch' do + it_behaves_like 'sending email', branches_to_be_notified: "protected" + end + + context 'notifications are enabled only for default and protected branches ' do + it_behaves_like 'sending email', branches_to_be_notified: "default_and_protected" + end + + context 'notifications are enabled only for all branches' do + it_behaves_like 'sending email', branches_to_be_notified: "all" + end end - context 'with notify_only_default_branch off' do - it_behaves_like 'sending email' + context 'on a neither protected nor default branch' do + before do + data[:object_attributes][:ref] = 'a-random-branch' + pipeline.update(ref: 'a-random-branch') + end + + context 'notifications are enabled only for default branch' do + it_behaves_like 'sending email', branches_to_be_notified: "default" + end + + context 'notifications are enabled only for protected branch' do + it_behaves_like 'sending email', branches_to_be_notified: "protected" + end + + context 'notifications are enabled only for default and protected branches ' do + it_behaves_like 'sending email', branches_to_be_notified: "default_and_protected" + end + + context 'notifications are enabled only for all branches' do + it_behaves_like 'sending email', branches_to_be_notified: "all" + end end end end describe '#execute' do + before do + subject.project = project + end + def run subject.execute(data) end @@ -159,37 +218,75 @@ describe PipelinesEmailService, :mailer do end end - context 'with notify_only_default_branch off' do - context 'with default branch' do - it_behaves_like 'sending email' + context 'when the pipeline failed' do + context 'on default branch' do + before do + data[:object_attributes][:ref] = project.default_branch + pipeline.update(ref: project.default_branch) + end + + context 'notifications are enabled only for default branch' do + it_behaves_like 'sending email', branches_to_be_notified: "default" + end + + context 'notifications are enabled only for protected branch' do + it_behaves_like 'not sending email', branches_to_be_notified: "protected" + end + + context 'notifications are enabled only for default and protected branches ' do + it_behaves_like 'sending email', branches_to_be_notified: "default_and_protected" + end + + context 'notifications are enabled only for all branches' do + it_behaves_like 'sending email', branches_to_be_notified: "all" + end end - context 'with non default branch' do + context 'on a protected branch' do before do - data[:object_attributes][:ref] = 'not-the-default-branch' - pipeline.update(ref: 'not-the-default-branch') + create(:protected_branch, project: project, name: 'a-protected-branch') + data[:object_attributes][:ref] = 'a-protected-branch' + pipeline.update(ref: 'a-protected-branch') end - it_behaves_like 'sending email' - end - end + context 'notifications are enabled only for default branch' do + it_behaves_like 'not sending email', branches_to_be_notified: "default" + end - context 'with notify_only_default_branch on' do - before do - subject.notify_only_default_branch = true - end + context 'notifications are enabled only for protected branch' do + it_behaves_like 'sending email', branches_to_be_notified: "protected" + end - context 'with default branch' do - it_behaves_like 'sending email' + context 'notifications are enabled only for default and protected branches ' do + it_behaves_like 'sending email', branches_to_be_notified: "default_and_protected" + end + + context 'notifications are enabled only for all branches' do + it_behaves_like 'sending email', branches_to_be_notified: "all" + end end - context 'with non default branch' do + context 'on a neither protected nor default branch' do before do - data[:object_attributes][:ref] = 'not-the-default-branch' - pipeline.update(ref: 'not-the-default-branch') + data[:object_attributes][:ref] = 'a-random-branch' + pipeline.update(ref: 'a-random-branch') end - it_behaves_like 'not sending email' + context 'notifications are enabled only for default branch' do + it_behaves_like 'not sending email', branches_to_be_notified: "default" + end + + context 'notifications are enabled only for protected branch' do + it_behaves_like 'not sending email', branches_to_be_notified: "protected" + end + + context 'notifications are enabled only for default and protected branches ' do + it_behaves_like 'not sending email', branches_to_be_notified: "default_and_protected" + end + + context 'notifications are enabled only for all branches' do + it_behaves_like 'sending email', branches_to_be_notified: "all" + end end end end diff --git a/spec/models/project_services/slack_service_spec.rb b/spec/models/project_services/slack_service_spec.rb index 01f580c5d01..f751dd6ffb9 100644 --- a/spec/models/project_services/slack_service_spec.rb +++ b/spec/models/project_services/slack_service_spec.rb @@ -3,5 +3,5 @@ require 'spec_helper' describe SlackService do - it_behaves_like "slack or mattermost notifications" + it_behaves_like "slack or mattermost notifications", "Slack" end diff --git a/spec/rubocop/cop/migration/add_reference_spec.rb b/spec/rubocop/cop/migration/add_reference_spec.rb index c348fc0efac..0b56fe8ed83 100644 --- a/spec/rubocop/cop/migration/add_reference_spec.rb +++ b/spec/rubocop/cop/migration/add_reference_spec.rb @@ -25,38 +25,86 @@ describe RuboCop::Cop::Migration::AddReference do allow(cop).to receive(:in_migration?).and_return(true) end - it 'registers an offense when using add_reference without index' do - expect_offense(<<~RUBY) - call do - add_reference(:projects, :users) - ^^^^^^^^^^^^^ `add_reference` requires `index: true` or `index: { options... }` + let(:offense) { '`add_reference` requires downtime for existing tables, use `add_concurrent_foreign_key` instead. When used for new tables, `index: true` or `index: { options... } is required.`' } + + context 'when the table existed before' do + it 'registers an offense when using add_reference' do + expect_offense(<<~RUBY) + def up + add_reference(:projects, :users) + ^^^^^^^^^^^^^ #{offense} + end + RUBY + end + + it 'registers an offense when using add_reference with index enabled' do + expect_offense(<<~RUBY) + def up + add_reference(:projects, :users, index: true) + ^^^^^^^^^^^^^ #{offense} end - RUBY + RUBY + end + + it 'registers an offense if only a different table was created' do + expect_offense(<<~RUBY) + def up + create_table(:foo) do |t| + t.string :name + end + add_reference(:projects, :users, index: true) + ^^^^^^^^^^^^^ #{offense} + end + RUBY + end end - it 'registers an offense when using add_reference index disabled' do - expect_offense(<<~RUBY) + context 'when creating the table at the same time' do + let(:create_table_statement) do + <<~RUBY + create_table(:projects) do |t| + t.string :name + end + RUBY + end + + it 'registers an offense when using add_reference without index' do + expect_offense(<<~RUBY) def up + #{create_table_statement} + add_reference(:projects, :users) + ^^^^^^^^^^^^^ #{offense} + end + RUBY + end + + it 'registers an offense when using add_reference index disabled' do + expect_offense(<<~RUBY) + def up + #{create_table_statement} add_reference(:projects, :users, index: false) - ^^^^^^^^^^^^^ `add_reference` requires `index: true` or `index: { options... }` + ^^^^^^^^^^^^^ #{offense} end - RUBY - end + RUBY + end - it 'does not register an offense when using add_reference with index enabled' do - expect_no_offenses(<<~RUBY) + it 'does not register an offense when using add_reference with index enabled' do + expect_no_offenses(<<~RUBY) def up + #{create_table_statement} add_reference(:projects, :users, index: true) end - RUBY - end + RUBY + end - it 'does not register an offense when the index is unique' do - expect_no_offenses(<<~RUBY) + it 'does not register an offense when the index is unique' do + expect_no_offenses(<<~RUBY) def up + #{create_table_statement} add_reference(:projects, :users, index: { unique: true } ) end - RUBY + RUBY + end end end end diff --git a/spec/rubocop/cop/qa/ambiguous_page_object_name_spec.rb b/spec/rubocop/cop/qa/ambiguous_page_object_name_spec.rb new file mode 100644 index 00000000000..8ee720af9a5 --- /dev/null +++ b/spec/rubocop/cop/qa/ambiguous_page_object_name_spec.rb @@ -0,0 +1,54 @@ +# frozen_string_literal: true + +require 'spec_helper' + +require 'rubocop' +require 'rubocop/rspec/support' + +require_relative '../../../../rubocop/cop/qa/ambiguous_page_object_name' + +describe RuboCop::Cop::QA::AmbiguousPageObjectName do + include CopHelper + + let(:source_file) { 'qa/page.rb' } + + subject(:cop) { described_class.new } + + context 'in a QA file' do + before do + allow(cop).to receive(:in_qa_file?).and_return(true) + end + + it "registers an offense for pages named `page`" do + expect_offense(<<-RUBY) + Page::Layout::Bar.perform do |page| + ^^^^ Don't use 'page' as a name for a Page Object. Use `bar` instead. + expect(page).to have_performance_bar + expect(page).to have_detailed_metrics + end + RUBY + end + + it "doesnt offend if the page object is named otherwise" do + expect_no_offenses(<<-RUBY) + Page::Object.perform do |obj| + obj.whatever + end + RUBY + end + end + + context 'outside of a QA file' do + before do + allow(cop).to receive(:in_qa_file?).and_return(false) + end + + it "does not register an offense" do + expect_no_offenses(<<-RUBY) + Page::Object.perform do |page| + page.do_something + end + RUBY + end + end +end diff --git a/spec/support/shared_examples/models/chat_service_shared_examples.rb b/spec/support/shared_examples/models/chat_service_shared_examples.rb index b6a3d50d14a..98bf647a9bc 100644 --- a/spec/support/shared_examples/models/chat_service_shared_examples.rb +++ b/spec/support/shared_examples/models/chat_service_shared_examples.rb @@ -49,7 +49,11 @@ shared_examples_for "chat service" do |service_name| WebMock.stub_request(:post, webhook_url) end - shared_examples "#{service_name} service" do + shared_examples "triggered #{service_name} service" do |branches_to_be_notified: nil| + before do + subject.branches_to_be_notified = branches_to_be_notified if branches_to_be_notified + end + it "calls #{service_name} API" do subject.execute(sample_data) @@ -57,12 +61,24 @@ shared_examples_for "chat service" do |service_name| end end + shared_examples "untriggered #{service_name} service" do |branches_to_be_notified: nil| + before do + subject.branches_to_be_notified = branches_to_be_notified if branches_to_be_notified + end + + it "does not call #{service_name} API" do + result = subject.execute(sample_data) + + expect(result).to be_falsy + end + end + context "with push events" do let(:sample_data) do Gitlab::DataBuilder::Push.build_sample(project, user) end - it_behaves_like "#{service_name} service" + it_behaves_like "triggered #{service_name} service" it "specifies the webhook when it is configured" do expect(client).to receive(:new).with(client_arguments).and_return(double(:chat_service).as_null_object) @@ -70,29 +86,73 @@ shared_examples_for "chat service" do |service_name| subject.execute(sample_data) end - context "with not default branch" do + context "with default branch" do let(:sample_data) do - Gitlab::DataBuilder::Push.build(project: project, user: user, ref: "not-the-default-branch") + Gitlab::DataBuilder::Push.build(project: project, user: user, ref: project.default_branch) end - context "when notify_only_default_branch enabled" do - before do - subject.notify_only_default_branch = true - end + context "when only default branch are to be notified" do + it_behaves_like "triggered #{service_name} service", branches_to_be_notified: "default" + end - it "does not call the Discord Webhooks API" do - result = subject.execute(sample_data) + context "when only protected branches are to be notified" do + it_behaves_like "untriggered #{service_name} service", branches_to_be_notified: "protected" + end - expect(result).to be_falsy - end + context "when default and protected branches are to be notified" do + it_behaves_like "triggered #{service_name} service", branches_to_be_notified: "default_and_protected" end - context "when notify_only_default_branch disabled" do - before do - subject.notify_only_default_branch = false - end + context "when all branches are to be notified" do + it_behaves_like "triggered #{service_name} service", branches_to_be_notified: "all" + end + end + + context "with protected branch" do + before do + create(:protected_branch, project: project, name: "a-protected-branch") + end + + let(:sample_data) do + Gitlab::DataBuilder::Push.build(project: project, user: user, ref: "a-protected-branch") + end + + context "when only default branch are to be notified" do + it_behaves_like "untriggered #{service_name} service", branches_to_be_notified: "default" + end + + context "when only protected branches are to be notified" do + it_behaves_like "triggered #{service_name} service", branches_to_be_notified: "protected" + end - it_behaves_like "#{service_name} service" + context "when default and protected branches are to be notified" do + it_behaves_like "triggered #{service_name} service", branches_to_be_notified: "default_and_protected" + end + + context "when all branches are to be notified" do + it_behaves_like "triggered #{service_name} service", branches_to_be_notified: "all" + end + end + + context "with neither default nor protected branch" do + let(:sample_data) do + Gitlab::DataBuilder::Push.build(project: project, user: user, ref: "a-random-branch") + end + + context "when only default branch are to be notified" do + it_behaves_like "untriggered #{service_name} service", branches_to_be_notified: "default" + end + + context "when only protected branches are to be notified" do + it_behaves_like "untriggered #{service_name} service", branches_to_be_notified: "protected" + end + + context "when default and protected branches are to be notified" do + it_behaves_like "untriggered #{service_name} service", branches_to_be_notified: "default_and_protected" + end + + context "when all branches are to be notified" do + it_behaves_like "triggered #{service_name} service", branches_to_be_notified: "all" end end end @@ -105,7 +165,7 @@ shared_examples_for "chat service" do |service_name| service.hook_data(issue, "open") end - it_behaves_like "#{service_name} service" + it_behaves_like "triggered #{service_name} service" end context "with merge events" do @@ -128,7 +188,7 @@ shared_examples_for "chat service" do |service_name| project.add_developer(user) end - it_behaves_like "#{service_name} service" + it_behaves_like "triggered #{service_name} service" end context "with wiki page events" do @@ -143,7 +203,7 @@ shared_examples_for "chat service" do |service_name| let(:wiki_page) { create(:wiki_page, wiki: project.wiki, attrs: opts) } let(:sample_data) { Gitlab::DataBuilder::WikiPage.build(wiki_page, user, "create") } - it_behaves_like "#{service_name} service" + it_behaves_like "triggered #{service_name} service" end context "with note events" do @@ -158,7 +218,7 @@ shared_examples_for "chat service" do |service_name| note: "a comment on a commit") end - it_behaves_like "#{service_name} service" + it_behaves_like "triggered #{service_name} service" end context "with merge request comment" do @@ -166,7 +226,7 @@ shared_examples_for "chat service" do |service_name| create(:note_on_merge_request, project: project, note: "merge request note") end - it_behaves_like "#{service_name} service" + it_behaves_like "triggered #{service_name} service" end context "with issue comment" do @@ -174,7 +234,7 @@ shared_examples_for "chat service" do |service_name| create(:note_on_issue, project: project, note: "issue note") end - it_behaves_like "#{service_name} service" + it_behaves_like "triggered #{service_name} service" end context "with snippet comment" do @@ -182,7 +242,7 @@ shared_examples_for "chat service" do |service_name| create(:note_on_project_snippet, project: project, note: "snippet note") end - it_behaves_like "#{service_name} service" + it_behaves_like "triggered #{service_name} service" end end @@ -197,14 +257,14 @@ shared_examples_for "chat service" do |service_name| context "with failed pipeline" do let(:status) { "failed" } - it_behaves_like "#{service_name} service" + it_behaves_like "triggered #{service_name} service" end context "with succeeded pipeline" do let(:status) { "success" } context "with default notify_only_broken_pipelines" do - it "does not call Discord Webhooks API" do + it "does not call #{service_name} API" do result = subject.execute(sample_data) expect(result).to be_falsy @@ -216,34 +276,77 @@ shared_examples_for "chat service" do |service_name| subject.notify_only_broken_pipelines = false end - it_behaves_like "#{service_name} service" + it_behaves_like "triggered #{service_name} service" end end - context "with not default branch" do - let(:pipeline) do - create(:ci_pipeline, :failed, project: project, - sha: project.commit.sha, ref: "not-the-default-branch") + context "with default branch" do + let(:sample_data) do + Gitlab::DataBuilder::Push.build(project: project, user: user, ref: project.default_branch) end - context "when notify_only_default_branch enabled" do - before do - subject.notify_only_default_branch = true - end + context "when only default branch are to be notified" do + it_behaves_like "triggered #{service_name} service", branches_to_be_notified: "default" + end - it "does not call the Discord Webhooks API" do - result = subject.execute(sample_data) + context "when only protected branches are to be notified" do + it_behaves_like "untriggered #{service_name} service", branches_to_be_notified: "protected" + end - expect(result).to be_falsy - end + context "when default and protected branches are to be notified" do + it_behaves_like "triggered #{service_name} service", branches_to_be_notified: "default_and_protected" end - context "when notify_only_default_branch disabled" do - before do - subject.notify_only_default_branch = false - end + context "when all branches are to be notified" do + it_behaves_like "triggered #{service_name} service", branches_to_be_notified: "all" + end + end + + context "with protected branch" do + before do + create(:protected_branch, project: project, name: "a-protected-branch") + end + + let(:sample_data) do + Gitlab::DataBuilder::Push.build(project: project, user: user, ref: "a-protected-branch") + end + + context "when only default branch are to be notified" do + it_behaves_like "untriggered #{service_name} service", branches_to_be_notified: "default" + end + + context "when only protected branches are to be notified" do + it_behaves_like "triggered #{service_name} service", branches_to_be_notified: "protected" + end + + context "when default and protected branches are to be notified" do + it_behaves_like "triggered #{service_name} service", branches_to_be_notified: "default_and_protected" + end + + context "when all branches are to be notified" do + it_behaves_like "triggered #{service_name} service", branches_to_be_notified: "all" + end + end + + context "with neither default nor protected branch" do + let(:sample_data) do + Gitlab::DataBuilder::Push.build(project: project, user: user, ref: "a-random-branch") + end + + context "when only default branch are to be notified" do + it_behaves_like "untriggered #{service_name} service", branches_to_be_notified: "default" + end + + context "when only protected branches are to be notified" do + it_behaves_like "untriggered #{service_name} service", branches_to_be_notified: "protected" + end + + context "when default and protected branches are to be notified" do + it_behaves_like "untriggered #{service_name} service", branches_to_be_notified: "default_and_protected" + end - it_behaves_like "#{service_name} service" + context "when all branches are to be notified" do + it_behaves_like "triggered #{service_name} service", branches_to_be_notified: "all" end end end diff --git a/spec/support/shared_examples/slack_mattermost_notifications_shared_examples.rb b/spec/support/shared_examples/slack_mattermost_notifications_shared_examples.rb index 8ce94064dc3..455f7b117b2 100644 --- a/spec/support/shared_examples/slack_mattermost_notifications_shared_examples.rb +++ b/spec/support/shared_examples/slack_mattermost_notifications_shared_examples.rb @@ -2,7 +2,7 @@ Dir[Rails.root.join("app/models/project_services/chat_message/*.rb")].each { |f| require f } -RSpec.shared_examples 'slack or mattermost notifications' do +RSpec.shared_examples 'slack or mattermost notifications' do |service_name| let(:chat_service) { described_class.new } let(:webhook_url) { 'https://example.gitlab.com/' } @@ -35,6 +35,28 @@ RSpec.shared_examples 'slack or mattermost notifications' do end end + shared_examples "triggered #{service_name} service" do |event_type: nil, branches_to_be_notified: nil| + before do + chat_service.branches_to_be_notified = branches_to_be_notified if branches_to_be_notified + end + + it "notifies about #{event_type} events" do + chat_service.execute(data) + expect(WebMock).to have_requested(:post, webhook_url) + end + end + + shared_examples "untriggered #{service_name} service" do |event_type: nil, branches_to_be_notified: nil| + before do + chat_service.branches_to_be_notified = branches_to_be_notified if branches_to_be_notified + end + + it "notifies about #{event_type} events" do + chat_service.execute(data) + expect(WebMock).not_to have_requested(:post, webhook_url) + end + end + describe "#execute" do let(:user) { create(:user) } let(:project) { create(:project, :repository, :wiki_repo) } @@ -42,7 +64,7 @@ RSpec.shared_examples 'slack or mattermost notifications' do let(:channel) { 'slack_channel' } let(:issue_service_options) { { title: 'Awesome issue', description: 'please fix' } } - let(:push_sample_data) do + let(:data) do Gitlab::DataBuilder::Push.build_sample(project, user) end @@ -84,31 +106,31 @@ RSpec.shared_examples 'slack or mattermost notifications' do @wiki_page_sample_data = Gitlab::DataBuilder::WikiPage.build(@wiki_page, user, 'create') end - it "calls Slack/Mattermost API for push events" do - chat_service.execute(push_sample_data) + it "calls #{service_name} API for push events" do + chat_service.execute(data) expect(WebMock).to have_requested(:post, webhook_url).once end - it "calls Slack/Mattermost API for issue events" do + it "calls #{service_name} API for issue events" do chat_service.execute(@issues_sample_data) expect(WebMock).to have_requested(:post, webhook_url).once end - it "calls Slack/Mattermost API for merge requests events" do + it "calls #{service_name} API for merge requests events" do chat_service.execute(@merge_sample_data) expect(WebMock).to have_requested(:post, webhook_url).once end - it "calls Slack/Mattermost API for wiki page events" do + it "calls #{service_name} API for wiki page events" do chat_service.execute(@wiki_page_sample_data) expect(WebMock).to have_requested(:post, webhook_url).once end - it "calls Slack/Mattermost API for deployment events" do + it "calls #{service_name} API for deployment events" do deployment_event_data = { object_kind: 'deployment' } chat_service.execute(deployment_event_data) @@ -125,7 +147,7 @@ RSpec.shared_examples 'slack or mattermost notifications' do double(:slack_service).as_null_object ) - chat_service.execute(push_sample_data) + chat_service.execute(data) end it 'uses the channel as an option when it is configured' do @@ -135,7 +157,7 @@ RSpec.shared_examples 'slack or mattermost notifications' do .and_return( double(:slack_service).as_null_object ) - chat_service.execute(push_sample_data) + chat_service.execute(data) end context "event channels" do @@ -148,7 +170,7 @@ RSpec.shared_examples 'slack or mattermost notifications' do double(:slack_service).as_null_object ) - chat_service.execute(push_sample_data) + chat_service.execute(data) end it "uses the right channel for merge request event" do @@ -269,64 +291,132 @@ RSpec.shared_examples 'slack or mattermost notifications' do WebMock.stub_request(:post, webhook_url) end - context 'only notify for the default branch' do - context 'when enabled' do - before do - chat_service.notify_only_default_branch = true + context 'on default branch' do + let(:data) do + Gitlab::DataBuilder::Push.build( + project: project, + user: user, + ref: project.default_branch + ) + end + + context 'pushing tags' do + let(:data) do + Gitlab::DataBuilder::Push.build( + project: project, + user: user, + ref: "#{Gitlab::Git::TAG_REF_PREFIX}test" + ) end - it 'does not notify push events if they are not for the default branch' do - ref = "#{Gitlab::Git::BRANCH_REF_PREFIX}test" - push_sample_data = Gitlab::DataBuilder::Push.build(project: project, user: user, ref: ref) + it_behaves_like "triggered #{service_name} service", event_type: "push" + end - chat_service.execute(push_sample_data) + context 'notification enabled only for default branch' do + it_behaves_like "triggered #{service_name} service", event_type: "push", branches_to_be_notified: "default" + end - expect(WebMock).not_to have_requested(:post, webhook_url) - end + context 'notification enabled only for protected branches' do + it_behaves_like "untriggered #{service_name} service", event_type: "push", branches_to_be_notified: "protected" + end + + context 'notification enabled only for default and protected branches' do + it_behaves_like "triggered #{service_name} service", event_type: "push", branches_to_be_notified: "default_and_protected" + end + + context 'notification enabled for all branches' do + it_behaves_like "triggered #{service_name} service", event_type: "push", branches_to_be_notified: "all" + end + end - it 'notifies about push events for the default branch' do - push_sample_data = Gitlab::DataBuilder::Push.build_sample(project, user) + context 'on a protected branch' do + before do + create(:protected_branch, project: project, name: 'a-protected-branch') + end - chat_service.execute(push_sample_data) + let(:data) do + Gitlab::DataBuilder::Push.build( + project: project, + user: user, + ref: 'a-protected-branch' + ) + end - expect(WebMock).to have_requested(:post, webhook_url).once + context 'pushing tags' do + let(:data) do + Gitlab::DataBuilder::Push.build( + project: project, + user: user, + ref: "#{Gitlab::Git::TAG_REF_PREFIX}test" + ) end - it 'still notifies about pushed tags' do - ref = "#{Gitlab::Git::TAG_REF_PREFIX}test" - push_sample_data = Gitlab::DataBuilder::Push.build(project: project, user: user, ref: ref) + it_behaves_like "triggered #{service_name} service", event_type: "push" + end - chat_service.execute(push_sample_data) + context 'notification enabled only for default branch' do + it_behaves_like "untriggered #{service_name} service", event_type: "push", branches_to_be_notified: "default" + end - expect(WebMock).to have_requested(:post, webhook_url).once - end + context 'notification enabled only for protected branches' do + it_behaves_like "triggered #{service_name} service", event_type: "push", branches_to_be_notified: "protected" end - context 'when disabled' do - before do - chat_service.notify_only_default_branch = false - end + context 'notification enabled only for default and protected branches' do + it_behaves_like "triggered #{service_name} service", event_type: "push", branches_to_be_notified: "default_and_protected" + end - it 'notifies about all push events' do - ref = "#{Gitlab::Git::BRANCH_REF_PREFIX}test" - push_sample_data = Gitlab::DataBuilder::Push.build(project: project, user: user, ref: ref) + context 'notification enabled for all branches' do + it_behaves_like "triggered #{service_name} service", event_type: "push", branches_to_be_notified: "all" + end + end - chat_service.execute(push_sample_data) + context 'on a neither protected nor default branch' do + let(:data) do + Gitlab::DataBuilder::Push.build( + project: project, + user: user, + ref: 'a-random-branch' + ) + end - expect(WebMock).to have_requested(:post, webhook_url).once + context 'pushing tags' do + let(:data) do + Gitlab::DataBuilder::Push.build( + project: project, + user: user, + ref: "#{Gitlab::Git::TAG_REF_PREFIX}test" + ) end + + it_behaves_like "triggered #{service_name} service", event_type: "push" + end + + context 'notification enabled only for default branch' do + it_behaves_like "untriggered #{service_name} service", event_type: "push", branches_to_be_notified: "default" + end + + context 'notification enabled only for protected branches' do + it_behaves_like "untriggered #{service_name} service", event_type: "push", branches_to_be_notified: "protected" + end + + context 'notification enabled only for default and protected branches' do + it_behaves_like "untriggered #{service_name} service", event_type: "push", branches_to_be_notified: "default_and_protected" + end + + context 'notification enabled for all branches' do + it_behaves_like "triggered #{service_name} service", event_type: "push", branches_to_be_notified: "all" end end end - describe "Note events" do + describe 'Note events' do let(:user) { create(:user) } let(:project) { create(:project, :repository, creator: user) } before do allow(chat_service).to receive_messages( project: project, - project_id: project.id, service_hook: true, webhook: webhook_url ) @@ -342,61 +432,56 @@ RSpec.shared_examples 'slack or mattermost notifications' do note: 'a comment on a commit') end - it "calls Slack/Mattermost API for commit comment events" do - data = Gitlab::DataBuilder::Note.build(commit_note, user) - chat_service.execute(data) - - expect(WebMock).to have_requested(:post, webhook_url).once + let(:data) do + Gitlab::DataBuilder::Note.build(commit_note, user) end + + it_behaves_like "triggered #{service_name} service", event_type: "commit comment" end context 'when merge request comment event executed' do let(:merge_request_note) do create(:note_on_merge_request, project: project, - note: "merge request note") + note: 'a comment on a merge request') end - it "calls Slack API for merge request comment events" do - data = Gitlab::DataBuilder::Note.build(merge_request_note, user) - chat_service.execute(data) - - expect(WebMock).to have_requested(:post, webhook_url).once + let(:data) do + Gitlab::DataBuilder::Note.build(merge_request_note, user) end + + it_behaves_like "triggered #{service_name} service", event_type: "merge request comment" end context 'when issue comment event executed' do let(:issue_note) do - create(:note_on_issue, project: project, note: "issue note") + create(:note_on_issue, project: project, + note: 'a comment on an issue') end - let(:data) { Gitlab::DataBuilder::Note.build(issue_note, user) } - - it "calls Slack API for issue comment events" do - chat_service.execute(data) - - expect(WebMock).to have_requested(:post, webhook_url).once + let(:data) do + Gitlab::DataBuilder::Note.build(issue_note, user) end + + it_behaves_like "triggered #{service_name} service", event_type: "issue comment" end context 'when snippet comment event executed' do let(:snippet_note) do create(:note_on_project_snippet, project: project, - note: "snippet note") + note: 'a comment on a snippet') end - it "calls Slack API for snippet comment events" do - data = Gitlab::DataBuilder::Note.build(snippet_note, user) - chat_service.execute(data) - - expect(WebMock).to have_requested(:post, webhook_url).once + let(:data) do + Gitlab::DataBuilder::Note.build(snippet_note, user) end + + it_behaves_like "triggered #{service_name} service", event_type: "snippet comment" end end describe 'Pipeline events' do let(:user) { create(:user) } - let(:project) { create(:project, :repository) } - + let(:project) { create(:project, :repository, creator: user) } let(:pipeline) do create(:ci_pipeline, project: project, status: status, @@ -409,77 +494,108 @@ RSpec.shared_examples 'slack or mattermost notifications' do service_hook: true, webhook: webhook_url ) + + WebMock.stub_request(:post, webhook_url) end - shared_examples 'call Slack/Mattermost API' do - before do - WebMock.stub_request(:post, webhook_url) + context 'with succeeded pipeline' do + let(:status) { 'success' } + let(:data) { Gitlab::DataBuilder::Pipeline.build(pipeline) } + + context 'with default to notify_only_broken_pipelines' do + it_behaves_like "untriggered #{service_name} service", event_type: "pipeline" end - it 'calls Slack/Mattermost API for pipeline events' do - data = Gitlab::DataBuilder::Pipeline.build(pipeline) - chat_service.execute(data) + context 'with setting notify_only_broken_pipelines to false' do + before do + chat_service.notify_only_broken_pipelines = false + end - expect(WebMock).to have_requested(:post, webhook_url).once + it_behaves_like "triggered #{service_name} service", event_type: "pipeline" end end context 'with failed pipeline' do - let(:status) { 'failed' } + context 'on default branch' do + let(:pipeline) do + create(:ci_pipeline, + project: project, status: :failed, + sha: project.commit.sha, ref: project.default_branch) + end - it_behaves_like 'call Slack/Mattermost API' - end + let(:data) { Gitlab::DataBuilder::Pipeline.build(pipeline) } - context 'with succeeded pipeline' do - let(:status) { 'success' } + context 'notification enabled only for default branch' do + it_behaves_like "triggered #{service_name} service", event_type: "pipeline", branches_to_be_notified: "default" + end - context 'with default to notify_only_broken_pipelines' do - it 'does not call Slack/Mattermost API for pipeline events' do - data = Gitlab::DataBuilder::Pipeline.build(pipeline) - result = chat_service.execute(data) + context 'notification enabled only for protected branches' do + it_behaves_like "untriggered #{service_name} service", event_type: "pipeline", branches_to_be_notified: "protected" + end - expect(result).to be_falsy + context 'notification enabled only for default and protected branches' do + it_behaves_like "triggered #{service_name} service", event_type: "pipeline", branches_to_be_notified: "default_and_protected" + end + + context 'notification enabled for all branches' do + it_behaves_like "triggered #{service_name} service", event_type: "pipeline", branches_to_be_notified: "all" end end - context 'with setting notify_only_broken_pipelines to false' do + context 'on a protected branch' do before do - chat_service.notify_only_broken_pipelines = false + create(:protected_branch, project: project, name: 'a-protected-branch') end - it_behaves_like 'call Slack/Mattermost API' - end - end - - context 'only notify for the default branch' do - context 'when enabled' do let(:pipeline) do - create(:ci_pipeline, :failed, project: project, sha: project.commit.sha, ref: 'not-the-default-branch') + create(:ci_pipeline, + project: project, status: :failed, + sha: project.commit.sha, ref: 'a-protected-branch') end - before do - chat_service.notify_only_default_branch = true - WebMock.stub_request(:post, webhook_url) + let(:data) { Gitlab::DataBuilder::Pipeline.build(pipeline) } + + context 'notification enabled only for default branch' do + it_behaves_like "untriggered #{service_name} service", event_type: "pipeline", branches_to_be_notified: "default" end - it 'does not call the Slack/Mattermost API for pipeline events' do - data = Gitlab::DataBuilder::Pipeline.build(pipeline) - result = chat_service.execute(data) + context 'notification enabled only for protected branches' do + it_behaves_like "triggered #{service_name} service", event_type: "pipeline", branches_to_be_notified: "protected" + end - expect(result).to be_falsy + context 'notification enabled only for default and protected branches' do + it_behaves_like "triggered #{service_name} service", event_type: "pipeline", branches_to_be_notified: "default_and_protected" + end + + context 'notification enabled for all branches' do + it_behaves_like "triggered #{service_name} service", event_type: "pipeline", branches_to_be_notified: "all" end end - context 'when disabled' do + context 'on a neither protected nor default branch' do let(:pipeline) do - create(:ci_pipeline, :failed, project: project, sha: project.commit.sha, ref: 'not-the-default-branch') + create(:ci_pipeline, + project: project, status: :failed, + sha: project.commit.sha, ref: 'a-random-branch') end - before do - chat_service.notify_only_default_branch = false + let(:data) { Gitlab::DataBuilder::Pipeline.build(pipeline) } + + context 'notification enabled only for default branch' do + it_behaves_like "untriggered #{service_name} service", event_type: "pipeline", branches_to_be_notified: "default" + end + + context 'notification enabled only for protected branches' do + it_behaves_like "untriggered #{service_name} service", event_type: "pipeline", branches_to_be_notified: "protected" end - it_behaves_like 'call Slack/Mattermost API' + context 'notification enabled only for default and protected branches' do + it_behaves_like "untriggered #{service_name} service", event_type: "pipeline", branches_to_be_notified: "default_and_protected" + end + + context 'notification enabled for all branches' do + it_behaves_like "triggered #{service_name} service", event_type: "pipeline", branches_to_be_notified: "all" + end end end end |