summaryrefslogtreecommitdiff
path: root/spec
diff options
context:
space:
mode:
authorJason Goodman <jgoodman@gitlab.com>2019-04-26 21:08:41 +0000
committerDouglas Barbosa Alexandre <dbalexandre@gmail.com>2019-04-26 21:08:41 +0000
commitfe86890b9d7a720648e7570d227c438d6ca7f25a (patch)
tree1c583b22cea6404de37ae6217f320d93cdf7cde9 /spec
parent265b789476479c29ea88db174aca1d80ddf24358 (diff)
downloadgitlab-ce-fe86890b9d7a720648e7570d227c438d6ca7f25a.tar.gz
Add deployment events to chat notification services
This enables sending a chat message to Slack or Mattermost upon a successful, failed, or canceled deployment
Diffstat (limited to 'spec')
-rw-r--r--spec/factories/deployments.rb2
-rw-r--r--spec/features/admin/admin_settings_spec.rb15
-rw-r--r--spec/lib/gitlab/data_builder/deployment_spec.rb36
-rw-r--r--spec/lib/gitlab/import_export/safe_model_attributes.yml1
-rw-r--r--spec/models/ci/build_spec.rb4
-rw-r--r--spec/models/deployment_spec.rb21
-rw-r--r--spec/models/project_services/chat_message/deployment_message_spec.rb150
-rw-r--r--spec/models/project_services/microsoft_teams_service_spec.rb6
-rw-r--r--spec/services/update_deployment_service_spec.rb1
-rw-r--r--spec/support/shared_examples/models/chat_service_spec.rb6
-rw-r--r--spec/support/shared_examples/slack_mattermost_notifications_shared_examples.rb8
-rw-r--r--spec/workers/build_success_worker_spec.rb1
-rw-r--r--spec/workers/deployments/finished_worker_spec.rb39
13 files changed, 287 insertions, 3 deletions
diff --git a/spec/factories/deployments.rb b/spec/factories/deployments.rb
index 011c98599a3..db438ad32d3 100644
--- a/spec/factories/deployments.rb
+++ b/spec/factories/deployments.rb
@@ -1,6 +1,6 @@
FactoryBot.define do
factory :deployment, class: Deployment do
- sha '97de212e80737a608d939f648d959671fb0a0142'
+ sha 'b83d6e391c22777fca1ed3012fce84f633d7fed0'
ref 'master'
tag false
user nil
diff --git a/spec/features/admin/admin_settings_spec.rb b/spec/features/admin/admin_settings_spec.rb
index 04f39b807d7..3c9a9d61756 100644
--- a/spec/features/admin/admin_settings_spec.rb
+++ b/spec/features/admin/admin_settings_spec.rb
@@ -230,6 +230,13 @@ describe 'Admin updates settings' do
expect(find_field('Username').value).to eq 'test_user'
expect(find('#service_push_channel').value).to eq '#test_channel'
end
+
+ it 'defaults Deployment events to false for chat notification template settings' do
+ first(:link, 'Service Templates').click
+ click_link 'Slack notifications'
+
+ expect(find_field('Deployment')).not_to be_checked
+ end
end
context 'CI/CD page' do
@@ -373,10 +380,14 @@ describe 'Admin updates settings' do
def check_all_events
page.check('Active')
page.check('Push')
- page.check('Tag push')
- page.check('Note')
page.check('Issue')
+ page.check('Confidential issue')
page.check('Merge request')
+ page.check('Note')
+ page.check('Confidential note')
+ page.check('Tag push')
page.check('Pipeline')
+ page.check('Wiki page')
+ page.check('Deployment')
end
end
diff --git a/spec/lib/gitlab/data_builder/deployment_spec.rb b/spec/lib/gitlab/data_builder/deployment_spec.rb
new file mode 100644
index 00000000000..b89a44e178b
--- /dev/null
+++ b/spec/lib/gitlab/data_builder/deployment_spec.rb
@@ -0,0 +1,36 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+describe Gitlab::DataBuilder::Deployment do
+ describe '.build' do
+ it 'returns the object kind for a deployment' do
+ deployment = build(:deployment)
+
+ data = described_class.build(deployment)
+
+ expect(data[:object_kind]).to eq('deployment')
+ end
+
+ it 'returns data for the given build' do
+ environment = create(:environment, name: "somewhere")
+ project = create(:project, :repository, name: 'myproj')
+ commit = project.commit('HEAD')
+ deployment = create(:deployment, status: :failed, environment: environment, sha: commit.sha, project: project)
+ deployable = deployment.deployable
+ expected_deployable_url = Gitlab::Routing.url_helpers.project_job_url(deployable.project, deployable)
+ expected_commit_url = Gitlab::UrlBuilder.build(commit)
+
+ data = described_class.build(deployment)
+
+ expect(data[:status]).to eq('failed')
+ expect(data[:deployable_id]).to eq(deployable.id)
+ expect(data[:deployable_url]).to eq(expected_deployable_url)
+ expect(data[:environment]).to eq("somewhere")
+ expect(data[:project]).to eq(project.hook_attrs)
+ expect(data[:short_sha]).to eq(deployment.short_sha)
+ expect(data[:user]).to eq(deployment.user.hook_attrs)
+ expect(data[:commit_url]).to eq(expected_commit_url)
+ end
+ end
+end
diff --git a/spec/lib/gitlab/import_export/safe_model_attributes.yml b/spec/lib/gitlab/import_export/safe_model_attributes.yml
index 591a3d296c2..9093d21647a 100644
--- a/spec/lib/gitlab/import_export/safe_model_attributes.yml
+++ b/spec/lib/gitlab/import_export/safe_model_attributes.yml
@@ -423,6 +423,7 @@ Service:
- wiki_page_events
- confidential_issues_events
- confidential_note_events
+- deployment_events
ProjectHook:
- id
- url
diff --git a/spec/models/ci/build_spec.rb b/spec/models/ci/build_spec.rb
index 3a7d20a58c8..339483d4f7d 100644
--- a/spec/models/ci/build_spec.rb
+++ b/spec/models/ci/build_spec.rb
@@ -856,6 +856,10 @@ describe Ci::Build do
let(:deployment) { build.deployment }
let(:environment) { deployment.environment }
+ before do
+ allow(Deployments::FinishedWorker).to receive(:perform_async)
+ end
+
it 'has deployments record with created status' do
expect(deployment).to be_created
expect(environment.name).to eq('review/master')
diff --git a/spec/models/deployment_spec.rb b/spec/models/deployment_spec.rb
index d9170d5fa07..0ca758429b8 100644
--- a/spec/models/deployment_spec.rb
+++ b/spec/models/deployment_spec.rb
@@ -102,6 +102,13 @@ describe Deployment do
deployment.succeed!
end
+
+ it 'executes Deployments::FinishedWorker asynchronously' do
+ expect(Deployments::FinishedWorker)
+ .to receive(:perform_async).with(deployment.id)
+
+ deployment.succeed!
+ end
end
context 'when deployment failed' do
@@ -115,6 +122,13 @@ describe Deployment do
expect(deployment.finished_at).to be_like_time(Time.now)
end
end
+
+ it 'executes Deployments::FinishedWorker asynchronously' do
+ expect(Deployments::FinishedWorker)
+ .to receive(:perform_async).with(deployment.id)
+
+ deployment.drop!
+ end
end
context 'when deployment was canceled' do
@@ -128,6 +142,13 @@ describe Deployment do
expect(deployment.finished_at).to be_like_time(Time.now)
end
end
+
+ it 'executes Deployments::FinishedWorker asynchronously' do
+ expect(Deployments::FinishedWorker)
+ .to receive(:perform_async).with(deployment.id)
+
+ deployment.cancel!
+ end
end
end
diff --git a/spec/models/project_services/chat_message/deployment_message_spec.rb b/spec/models/project_services/chat_message/deployment_message_spec.rb
new file mode 100644
index 00000000000..86565ce8b01
--- /dev/null
+++ b/spec/models/project_services/chat_message/deployment_message_spec.rb
@@ -0,0 +1,150 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+describe ChatMessage::DeploymentMessage do
+ describe '#pretext' do
+ it 'returns a message with the data returned by the deployment data builder' do
+ environment = create(:environment, name: "myenvironment")
+ project = create(:project, :repository)
+ commit = project.commit('HEAD')
+ deployment = create(:deployment, status: :success, environment: environment, project: project, sha: commit.sha)
+ data = Gitlab::DataBuilder::Deployment.build(deployment)
+
+ message = described_class.new(data)
+
+ expect(message.pretext).to eq("Deploy to myenvironment succeeded")
+ end
+
+ it 'returns a message for a successful deployment' do
+ data = {
+ status: 'success',
+ environment: 'production'
+ }
+
+ message = described_class.new(data)
+
+ expect(message.pretext).to eq('Deploy to production succeeded')
+ end
+
+ it 'returns a message for a failed deployment' do
+ data = {
+ status: 'failed',
+ environment: 'production'
+ }
+
+ message = described_class.new(data)
+
+ expect(message.pretext).to eq('Deploy to production failed')
+ end
+
+ it 'returns a message for a canceled deployment' do
+ data = {
+ status: 'canceled',
+ environment: 'production'
+ }
+
+ message = described_class.new(data)
+
+ expect(message.pretext).to eq('Deploy to production canceled')
+ end
+
+ it 'returns a message for a deployment to another environment' do
+ data = {
+ status: 'success',
+ environment: 'staging'
+ }
+
+ message = described_class.new(data)
+
+ expect(message.pretext).to eq('Deploy to staging succeeded')
+ end
+
+ it 'returns a message for a deployment with any other status' do
+ data = {
+ status: 'unknown',
+ environment: 'staging'
+ }
+
+ message = described_class.new(data)
+
+ expect(message.pretext).to eq('Deploy to staging unknown')
+ end
+ end
+
+ describe '#attachments' do
+ def deployment_data(params)
+ {
+ object_kind: "deployment",
+ status: "success",
+ deployable_id: 3,
+ deployable_url: "deployable_url",
+ environment: "sandbox",
+ project: {
+ name: "greatproject",
+ web_url: "project_web_url",
+ path_with_namespace: "project_path_with_namespace"
+ },
+ user: {
+ name: "Jane Person",
+ username: "jane"
+ },
+ short_sha: "12345678",
+ commit_url: "commit_url"
+ }.merge(params)
+ end
+
+ it 'returns attachments with the data returned by the deployment data builder' do
+ user = create(:user, name: "John Smith", username: "smith")
+ namespace = create(:namespace, name: "myspace")
+ project = create(:project, :repository, namespace: namespace, name: "myproject")
+ commit = project.commit('HEAD')
+ environment = create(:environment, name: "myenvironment", project: project)
+ ci_build = create(:ci_build, project: project)
+ deployment = create(:deployment, :success, deployable: ci_build, environment: environment, project: project, user: user, sha: commit.sha)
+ job_url = Gitlab::Routing.url_helpers.project_job_url(project, ci_build)
+ commit_url = Gitlab::UrlBuilder.build(deployment.commit)
+ data = Gitlab::DataBuilder::Deployment.build(deployment)
+
+ message = described_class.new(data)
+
+ expect(message.attachments).to eq([{
+ text: "[myspace/myproject](#{project.web_url})\n[Job ##{ci_build.id}](#{job_url}), SHA [#{deployment.short_sha}](#{commit_url}), by John Smith (smith)",
+ color: "good"
+ }])
+ end
+
+ it 'returns attachments for a failed deployment' do
+ data = deployment_data(status: 'failed')
+
+ message = described_class.new(data)
+
+ expect(message.attachments).to eq([{
+ text: "[project_path_with_namespace](project_web_url)\n[Job #3](deployable_url), SHA [12345678](commit_url), by Jane Person (jane)",
+ color: "danger"
+ }])
+ end
+
+ it 'returns attachments for a canceled deployment' do
+ data = deployment_data(status: 'canceled')
+
+ message = described_class.new(data)
+
+ expect(message.attachments).to eq([{
+ text: "[project_path_with_namespace](project_web_url)\n[Job #3](deployable_url), SHA [12345678](commit_url), by Jane Person (jane)",
+ color: "warning"
+ }])
+ end
+
+ it 'uses a neutral color for a deployment with any other status' do
+ data = deployment_data(status: 'some-new-status-we-make-in-the-future')
+
+ message = described_class.new(data)
+
+ expect(message.attachments).to eq([{
+ text: "[project_path_with_namespace](project_web_url)\n[Job #3](deployable_url), SHA [12345678](commit_url), by Jane Person (jane)",
+ color: "#334455"
+ }])
+ end
+ end
+end
diff --git a/spec/models/project_services/microsoft_teams_service_spec.rb b/spec/models/project_services/microsoft_teams_service_spec.rb
index 521d5265753..c025d7c882e 100644
--- a/spec/models/project_services/microsoft_teams_service_spec.rb
+++ b/spec/models/project_services/microsoft_teams_service_spec.rb
@@ -30,6 +30,12 @@ describe MicrosoftTeamsService do
end
end
+ describe '.supported_events' do
+ it 'does not support deployment_events' do
+ expect(described_class.supported_events).not_to include('deployment')
+ end
+ end
+
describe "#execute" do
let(:user) { create(:user) }
set(:project) { create(:project, :repository, :wiki_repo) }
diff --git a/spec/services/update_deployment_service_spec.rb b/spec/services/update_deployment_service_spec.rb
index c664bac39fc..7dc52f6816a 100644
--- a/spec/services/update_deployment_service_spec.rb
+++ b/spec/services/update_deployment_service_spec.rb
@@ -22,6 +22,7 @@ describe UpdateDeploymentService do
subject(:service) { described_class.new(deployment) }
before do
+ allow(Deployments::FinishedWorker).to receive(:perform_async)
job.success! # Create/Succeed deployment
end
diff --git a/spec/support/shared_examples/models/chat_service_spec.rb b/spec/support/shared_examples/models/chat_service_spec.rb
index cf1d52a9616..9d3ce5e2be1 100644
--- a/spec/support/shared_examples/models/chat_service_spec.rb
+++ b/spec/support/shared_examples/models/chat_service_spec.rb
@@ -25,6 +25,12 @@ shared_examples_for "chat service" do |service_name|
end
end
+ describe '.supported_events' do
+ it 'does not support deployment_events' do
+ expect(described_class.supported_events).not_to include('deployment')
+ end
+ end
+
describe "#execute" do
let(:user) { create(:user) }
let(:project) { create(:project, :repository) }
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 940c24c8d67..c31346374f4 100644
--- a/spec/support/shared_examples/slack_mattermost_notifications_shared_examples.rb
+++ b/spec/support/shared_examples/slack_mattermost_notifications_shared_examples.rb
@@ -106,6 +106,14 @@ RSpec.shared_examples 'slack or mattermost notifications' do
expect(WebMock).to have_requested(:post, webhook_url).once
end
+ it "calls Slack/Mattermost API for deployment events" do
+ deployment_event_data = { object_kind: 'deployment' }
+
+ chat_service.execute(deployment_event_data)
+
+ expect(WebMock).to have_requested(:post, webhook_url).once
+ end
+
it 'uses the username as an option for slack when configured' do
allow(chat_service).to receive(:username).and_return(username)
diff --git a/spec/workers/build_success_worker_spec.rb b/spec/workers/build_success_worker_spec.rb
index 065aeaf2b65..ffe8796ded9 100644
--- a/spec/workers/build_success_worker_spec.rb
+++ b/spec/workers/build_success_worker_spec.rb
@@ -15,6 +15,7 @@ describe BuildSuccessWorker do
let!(:build) { create(:ci_build, :deploy_to_production) }
before do
+ allow(Deployments::FinishedWorker).to receive(:perform_async)
Deployment.delete_all
build.reload
end
diff --git a/spec/workers/deployments/finished_worker_spec.rb b/spec/workers/deployments/finished_worker_spec.rb
new file mode 100644
index 00000000000..df62821e2cd
--- /dev/null
+++ b/spec/workers/deployments/finished_worker_spec.rb
@@ -0,0 +1,39 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+describe Deployments::FinishedWorker do
+ let(:worker) { described_class.new }
+
+ describe '#perform' do
+ before do
+ allow(ProjectServiceWorker).to receive(:perform_async)
+ end
+
+ it 'executes project services for deployment_hooks' do
+ deployment = create(:deployment)
+ project = deployment.project
+ service = create(:service, type: 'SlackService', project: project, deployment_events: true, active: true)
+
+ worker.perform(deployment.id)
+
+ expect(ProjectServiceWorker).to have_received(:perform_async).with(service.id, an_instance_of(Hash))
+ end
+
+ it 'does not execute an inactive service' do
+ deployment = create(:deployment)
+ project = deployment.project
+ create(:service, type: 'SlackService', project: project, deployment_events: true, active: false)
+
+ worker.perform(deployment.id)
+
+ expect(ProjectServiceWorker).not_to have_received(:perform_async)
+ end
+
+ it 'does nothing if a deployment with the given id does not exist' do
+ worker.perform(0)
+
+ expect(ProjectServiceWorker).not_to have_received(:perform_async)
+ end
+ end
+end