Merge branch 'issue_22269' into 'master'

Mattermost Notifications Service

## What does this MR do?
closes #22269 

## Screenshots 

![mattermost](/uploads/de71c121f544a91305b6dfa6dc4c5738/mattermost.png)  
![slack](/uploads/081d75d49239319d94332abda214fb98/slack.png)

## Does this MR meet the acceptance criteria?

- [x] [Changelog entry](https://docs.gitlab.com/ce/development/changelog.html) added
- [x] [Documentation created/updated](https://gitlab.com/gitlab-org/gitlab-ce/blob/master/doc/development/doc_styleguide.md)
- [x] API support added
- Tests
  - [x] Added for this feature/bug
  - [x] All builds are passing
- [x] Conform by the [merge request performance guides](http://docs.gitlab.com/ce/development/merge_request_performance_guidelines.html)
- [x] Conform by the [style guides](https://gitlab.com/gitlab-org/gitlab-ce/blob/master/CONTRIBUTING.md#style-guides)
- [x] Branch has no merge conflicts with `master` (if it does - rebase it please)
- [x] [Squashed related commits together](https://git-scm.com/book/en/Git-Tools-Rewriting-History#Squashing-Commits)


See merge request !7764
This commit is contained in:
Kamil Trzciński 2016-12-16 13:23:19 +00:00
commit bdb5e67718
39 changed files with 321 additions and 133 deletions

View file

@ -95,7 +95,8 @@ class Project < ActiveRecord::Base
has_one :asana_service, dependent: :destroy
has_one :gemnasium_service, dependent: :destroy
has_one :mattermost_slash_commands_service, dependent: :destroy
has_one :slack_service, dependent: :destroy
has_one :mattermost_notification_service, dependent: :destroy
has_one :slack_notification_service, dependent: :destroy
has_one :buildkite_service, dependent: :destroy
has_one :bamboo_service, dependent: :destroy
has_one :teamcity_service, dependent: :destroy

View file

@ -1,6 +1,6 @@
require 'slack-notifier'
class SlackService
module ChatMessage
class BaseMessage
def initialize(params)
raise NotImplementedError

View file

@ -1,4 +1,4 @@
class SlackService
module ChatMessage
class BuildMessage < BaseMessage
attr_reader :sha
attr_reader :ref_type

View file

@ -1,4 +1,4 @@
class SlackService
module ChatMessage
class IssueMessage < BaseMessage
attr_reader :user_name
attr_reader :title

View file

@ -1,4 +1,4 @@
class SlackService
module ChatMessage
class MergeMessage < BaseMessage
attr_reader :user_name
attr_reader :project_name

View file

@ -1,4 +1,4 @@
class SlackService
module ChatMessage
class NoteMessage < BaseMessage
attr_reader :message
attr_reader :user_name

View file

@ -1,4 +1,4 @@
class SlackService
module ChatMessage
class PipelineMessage < BaseMessage
attr_reader :ref_type, :ref, :status, :project_name, :project_url,
:user_name, :duration, :pipeline_id

View file

@ -1,4 +1,4 @@
class SlackService
module ChatMessage
class PushMessage < BaseMessage
attr_reader :after
attr_reader :before

View file

@ -1,4 +1,4 @@
class SlackService
module ChatMessage
class WikiPageMessage < BaseMessage
attr_reader :user_name
attr_reader :title

View file

@ -1,6 +1,13 @@
class SlackService < Service
# Base class for Chat notifications services
# This class is not meant to be used directly, but only to inherit from.
class ChatNotificationService < Service
include ChatMessage
default_value_for :category, 'chat'
prop_accessor :webhook, :username, :channel
boolean_accessor :notify_only_broken_builds, :notify_only_broken_pipelines
validates :webhook, presence: true, url: true, if: :activated?
def initialize_properties
@ -14,35 +21,8 @@ class SlackService < Service
end
end
def title
'Slack'
end
def description
'A team communication tool for the 21st century'
end
def to_param
'slack'
end
def help
'This service sends notifications to your Slack channel.<br/>
To setup this Service you need to create a new <b>"Incoming webhook"</b> in your Slack integration panel,
and enter the Webhook URL below.'
end
def fields
default_fields =
[
{ type: 'text', name: 'webhook', placeholder: 'https://hooks.slack.com/services/...' },
{ type: 'text', name: 'username', placeholder: 'username' },
{ type: 'text', name: 'channel', placeholder: "#general" },
{ type: 'checkbox', name: 'notify_only_broken_builds' },
{ type: 'checkbox', name: 'notify_only_broken_pipelines' },
]
default_fields + build_event_channels
def can_test?
valid?
end
def supported_events
@ -67,21 +47,16 @@ class SlackService < Service
message = get_message(object_kind, data)
if message
opt = {}
return false unless message
event_channel = get_channel_field(object_kind) || channel
opt = {}
opt[:channel] = event_channel if event_channel
opt[:username] = username if username
opt[:channel] = get_channel_field(object_kind).presence || channel || default_channel
opt[:username] = username if username
notifier = Slack::Notifier.new(webhook, opt)
notifier.ping(message.pretext, attachments: message.attachments, fallback: message.fallback)
notifier = Slack::Notifier.new(webhook, opt)
notifier.ping(message.pretext, attachments: message.attachments, fallback: message.fallback)
true
else
false
end
true
end
def event_channel_names
@ -96,6 +71,10 @@ class SlackService < Service
fields.reject { |field| field[:name].end_with?('channel') }
end
def default_channel
raise NotImplementedError
end
private
def get_message(object_kind, data)
@ -124,7 +103,7 @@ class SlackService < Service
def build_event_channels
supported_events.reduce([]) do |channels, event|
channels << { type: 'text', name: event_channel_name(event), placeholder: "#general" }
channels << { type: 'text', name: event_channel_name(event), placeholder: default_channel }
end
end
@ -166,11 +145,3 @@ class SlackService < Service
end
end
end
require "slack_service/issue_message"
require "slack_service/push_message"
require "slack_service/merge_message"
require "slack_service/note_message"
require "slack_service/build_message"
require "slack_service/pipeline_message"
require "slack_service/wiki_page_message"

View file

@ -1,5 +1,5 @@
# Base class for Chat services
# This class is not meant to be used directly, but only to inherrit from.
# This class is not meant to be used directly, but only to inherit from.
class ChatService < Service
default_value_for :category, 'chat'

View file

@ -0,0 +1,41 @@
class MattermostNotificationService < ChatNotificationService
def title
'Mattermost notifications'
end
def description
'Receive event notifications in Mattermost'
end
def to_param
'mattermost_notification'
end
def help
'This service sends notifications about projects events to Mattermost channels.<br />
To set up this service:
<ol>
<li><a href="https://docs.mattermost.com/developer/webhooks-incoming.html#enabling-incoming-webhooks">Enable incoming webhooks</a> in your Mattermost installation. </li>
<li><a href="https://docs.mattermost.com/developer/webhooks-incoming.html#creating-integrations-using-incoming-webhooks">Add an incoming webhook</a> in your Mattermost team. The default channel can be overridden for each event. </li>
<li>Paste the webhook <strong>URL</strong> into the field bellow. </li>
<li>Select events below to enable notifications. The channel and username are optional. </li>
</ol>'
end
def fields
default_fields + build_event_channels
end
def default_fields
[
{ type: 'text', name: 'webhook', placeholder: 'http://mattermost_host/hooks/...' },
{ type: 'text', name: 'username', placeholder: 'username' },
{ type: 'checkbox', name: 'notify_only_broken_builds' },
{ type: 'checkbox', name: 'notify_only_broken_pipelines' },
]
end
def default_channel
"#town-square"
end
end

View file

@ -0,0 +1,40 @@
class SlackNotificationService < ChatNotificationService
def title
'Slack notifications'
end
def description
'Receive event notifications in Slack'
end
def to_param
'slack_notification'
end
def help
'This service sends notifications about projects events to Slack channels.<br />
To setup this service:
<ol>
<li><a href="https://slack.com/apps/A0F7XDUAZ-incoming-webhooks">Add an incoming webhook</a> in your Slack team. The default channel can be overridden for each event. </li>
<li>Paste the <strong>Webhook URL</strong> into the field below. </li>
<li>Select events below to enable notifications. The channel and username are optional. </li>
</ol>'
end
def fields
default_fields + build_event_channels
end
def default_fields
[
{ type: 'text', name: 'webhook', placeholder: 'https://hooks.slack.com/services/...' },
{ type: 'text', name: 'username', placeholder: 'username' },
{ type: 'checkbox', name: 'notify_only_broken_builds' },
{ type: 'checkbox', name: 'notify_only_broken_pipelines' },
]
end
def default_channel
"#general"
end
end

View file

@ -220,7 +220,8 @@ class Service < ActiveRecord::Base
pivotaltracker
pushover
redmine
slack
mattermost_notification
slack_notification
teamcity
]
end

View file

@ -0,0 +1,4 @@
---
title: Create mattermost service
merge_request:
author:

View file

@ -1,7 +1,11 @@
# rubocop:disable all
class MoveSlackServiceToWebhook < ActiveRecord::Migration
DOWNTIME = true
DOWNTIME_REASON = 'Move old fields "token" and "subdomain" to one single field "webhook"'
def change
SlackService.all.each do |slack_service|
SlackNotificationService.all.each do |slack_service|
if ["token", "subdomain"].all? { |property| slack_service.properties.key? property }
token = slack_service.properties['token']
subdomain = slack_service.properties['subdomain']

View file

@ -0,0 +1,14 @@
class ChangeSlackServiceToSlackNotificationService < ActiveRecord::Migration
include Gitlab::Database::MigrationHelpers
DOWNTIME = true
DOWNTIME_REASON = 'Rename SlackService to SlackNotificationService'
def up
execute("UPDATE services SET type = 'SlackNotificationService' WHERE type = 'SlackService'")
end
def down
execute("UPDATE services SET type = 'SlackService' WHERE type = 'SlackNotificationService'")
end
end

View file

@ -11,7 +11,7 @@
#
# It's strongly recommended that you check this file into your version control system.
ActiveRecord::Schema.define(version: 20161212142807) do
ActiveRecord::Schema.define(version: 20161213172958) do
# These are extensions that must be enabled in order to support this database
enable_extension "plpgsql"

View file

@ -703,9 +703,9 @@ Get Redmine service settings for a project.
GET /projects/:id/services/redmine
```
## Slack
## Slack notifications
A team communication tool for the 21st century
Receive event notifications in Slack
### Create/Edit Slack service
@ -737,6 +737,40 @@ Get Slack service settings for a project.
GET /projects/:id/services/slack
```
## Mattermost notifications
Receive event notifications in Mattermost
### Create/Edit Mattermost notifications service
Set Mattermost service for a project.
```
PUT /projects/:id/services/mattermost
```
Parameters:
- `webhook` (**required**) - https://mattermost.example/hooks/1298aff...
- `username` (optional) - username
- `channel` (optional) - #channel
### Delete Mattermost notifications service
Delete Mattermost Notifications service for a project.
```
DELETE /projects/:id/services/mattermost
```
### Get Mattermost notifications service settings
Get Mattermost notifications service settings for a project.
```
GET /projects/:id/services/mattermost
```
## JetBrains TeamCity CI
A continuous integration and build server

Binary file not shown.

After

Width:  |  Height:  |  Size: 72 KiB

View file

@ -0,0 +1,45 @@
# Mattermost Notifications Service
## On Mattermost
To enable Mattermost integration you must create an incoming webhook integration:
1. Sign in to your Mattermost instance
1. Visit incoming webhooks, that will be something like: https://mattermost.example/your_team_name/integrations/incoming_webhooks/add
1. Choose a display name, description and channel, those can be overridden on GitLab
1. Save it, copy the **Webhook URL**, we'll need this later for GitLab.
There might be some cases that Incoming Webhooks are blocked by admin, ask your mattermost admin to enable
it on https://mattermost.example/admin_console/integrations/custom.
Display name override is not enabled by default, you need to ask your admin to enable it on that same section.
## On GitLab
After you set up Mattermost, it's time to set up GitLab.
Go to your project's **Settings > Services > Mattermost Notifications** and you will see a
checkbox with the following events that can be triggered:
- Push
- Issue
- Merge request
- Note
- Tag push
- Build
- Wiki page
Bellow each of these event checkboxes, you will have an input field to insert
which Mattermost channel you want to send that event message, with `#town-square`
being the default. The hash sign is optional.
At the end, fill in your Mattermost details:
| Field | Description |
| ----- | ----------- |
| **Webhook** | The incoming webhooks which you have to setup on Mattermost, it will be something like: http://mattermost.example/hooks/5xo... |
| **Username** | Optional username which can be on messages sent to Mattermost. Fill this in if you want to change the username of the bot. |
| **Notify only broken builds** | If you choose to enable the **Build** event and you want to be only notified about failed builds. |
![Mattermost configuration](img/mattermost_configuration.png)

View file

@ -44,10 +44,11 @@ further configuration instructions and details. Contributions are welcome.
| JetBrains TeamCity CI | A continuous integration and build server |
| [Kubernetes](kubernetes.md) | A containerized deployment service |
| [Mattermost slash commands](mattermost_slash_commands.md) | Mattermost chat and ChatOps slash commands |
| [Mattermost Notifications](mattermost.md) | Receive event notifications in Mattermost |
| [Slack Notifications](slack.md) | Receive event notifications in Slack |
| PivotalTracker | Project Management Software (Source Commits Endpoint) |
| Pushover | Pushover makes it easy to get real-time notifications on your Android device, iPhone, iPad, and Desktop |
| [Redmine](redmine.md) | Redmine issue tracker |
| [Slack](slack.md) | A team communication tool for the 21st century |
## Services Templates

View file

@ -1,4 +1,4 @@
# Slack Service
# Slack Notifications Service
## On Slack
@ -15,7 +15,7 @@ Slack:
After you set up Slack, it's time to set up GitLab.
Go to your project's **Settings > Services > Slack** and you will see a
Go to your project's **Settings > Services > Slack Notifications** and you will see a
checkbox with the following events that can be triggered:
- Push

View file

@ -473,7 +473,7 @@ module API
desc: 'The description of the tracker'
}
],
'slack' => [
'slack-notification' => [
{
required: true,
name: :webhook,
@ -493,6 +493,14 @@ module API
desc: 'The channel name'
}
],
'mattermost-notification' => [
{
required: true,
name: :webhook,
type: String,
desc: 'The Mattermost webhook. e.g. http://mattermost_host/hooks/...'
}
],
'teamcity' => [
{
required: true,

View file

@ -2,8 +2,8 @@ require 'spec_helper'
feature 'Projects > Slack service > Setup events', feature: true do
let(:user) { create(:user) }
let(:service) { SlackService.new }
let(:project) { create(:project, slack_service: service) }
let(:service) { SlackNotificationService.new }
let(:project) { create(:project, slack_notification_service: service) }
background do
service.fields

View file

@ -136,7 +136,8 @@ project:
- assembla_service
- asana_service
- gemnasium_service
- slack_service
- slack_notification_service
- mattermost_notification_service
- buildkite_service
- bamboo_service
- teamcity_service

View file

@ -1,7 +1,7 @@
require 'spec_helper'
describe SlackService::BuildMessage do
subject { SlackService::BuildMessage.new(args) }
describe ChatMessage::BuildMessage do
subject { described_class.new(args) }
let(:args) do
{

View file

@ -1,7 +1,7 @@
require 'spec_helper'
describe SlackService::IssueMessage, models: true do
subject { SlackService::IssueMessage.new(args) }
describe ChatMessage::IssueMessage, models: true do
subject { described_class.new(args) }
let(:args) do
{

View file

@ -1,7 +1,7 @@
require 'spec_helper'
describe SlackService::MergeMessage, models: true do
subject { SlackService::MergeMessage.new(args) }
describe ChatMessage::MergeMessage, models: true do
subject { described_class.new(args) }
let(:args) do
{

View file

@ -1,6 +1,6 @@
require 'spec_helper'
describe SlackService::NoteMessage, models: true do
describe ChatMessage::NoteMessage, models: true do
let(:color) { '#345' }
before do
@ -36,7 +36,7 @@ describe SlackService::NoteMessage, models: true do
end
it 'returns a message regarding notes on commits' do
message = SlackService::NoteMessage.new(@args)
message = described_class.new(@args)
expect(message.pretext).to eq("test.user <url|commented on " \
"commit 5f163b2b> in <somewhere.com|project_name>: " \
"*Added a commit message*")
@ -62,7 +62,7 @@ describe SlackService::NoteMessage, models: true do
end
it 'returns a message regarding notes on a merge request' do
message = SlackService::NoteMessage.new(@args)
message = described_class.new(@args)
expect(message.pretext).to eq("test.user <url|commented on " \
"merge request !30> in <somewhere.com|project_name>: " \
"*merge request title*")
@ -88,7 +88,7 @@ describe SlackService::NoteMessage, models: true do
end
it 'returns a message regarding notes on an issue' do
message = SlackService::NoteMessage.new(@args)
message = described_class.new(@args)
expect(message.pretext).to eq(
"test.user <url|commented on " \
"issue #20> in <somewhere.com|project_name>: " \
@ -114,7 +114,7 @@ describe SlackService::NoteMessage, models: true do
end
it 'returns a message regarding notes on a project snippet' do
message = SlackService::NoteMessage.new(@args)
message = described_class.new(@args)
expect(message.pretext).to eq("test.user <url|commented on " \
"snippet #5> in <somewhere.com|project_name>: " \
"*snippet title*")

View file

@ -1,7 +1,7 @@
require 'spec_helper'
describe SlackService::PipelineMessage do
subject { SlackService::PipelineMessage.new(args) }
describe ChatMessage::PipelineMessage do
subject { described_class.new(args) }
let(:user) { { name: 'hacker' } }
let(:args) do

View file

@ -1,7 +1,7 @@
require 'spec_helper'
describe SlackService::PushMessage, models: true do
subject { SlackService::PushMessage.new(args) }
describe ChatMessage::PushMessage, models: true do
subject { described_class.new(args) }
let(:args) do
{

View file

@ -1,6 +1,6 @@
require 'spec_helper'
describe SlackService::WikiPageMessage, models: true do
describe ChatMessage::WikiPageMessage, models: true do
subject { described_class.new(args) }
let(:args) do

View file

@ -0,0 +1,11 @@
require 'spec_helper'
describe ChatNotificationService, models: true do
describe "Associations" do
before do
allow(subject).to receive(:activated?).and_return(true)
end
it { is_expected.to validate_presence_of :webhook }
end
end

View file

@ -0,0 +1,5 @@
require 'spec_helper'
describe MattermostNotificationService, models: true do
it_behaves_like "slack or mattermost"
end

View file

@ -0,0 +1,5 @@
require 'spec_helper'
describe SlackNotificationService, models: true do
it_behaves_like "slack or mattermost"
end

View file

@ -22,7 +22,8 @@ describe Project, models: true do
it { is_expected.to have_many(:protected_branches).dependent(:destroy) }
it { is_expected.to have_many(:chat_services) }
it { is_expected.to have_one(:forked_project_link).dependent(:destroy) }
it { is_expected.to have_one(:slack_service).dependent(:destroy) }
it { is_expected.to have_one(:slack_notification_service).dependent(:destroy) }
it { is_expected.to have_one(:mattermost_notification_service).dependent(:destroy) }
it { is_expected.to have_one(:pushover_service).dependent(:destroy) }
it { is_expected.to have_one(:asana_service).dependent(:destroy) }
it { is_expected.to have_many(:boards).dependent(:destroy) }

View file

@ -1,7 +1,7 @@
require 'spec_helper'
Dir[Rails.root.join("app/models/project_services/chat_message/*.rb")].each { |f| require f }
describe SlackService, models: true do
let(:slack) { SlackService.new }
RSpec.shared_examples 'slack or mattermost' do
let(:chat_service) { described_class.new }
let(:webhook_url) { 'https://example.gitlab.com/' }
describe "Associations" do
@ -24,7 +24,7 @@ describe SlackService, models: true do
end
end
describe "Execute" do
describe "#execute" do
let(:user) { create(:user) }
let(:project) { create(:project) }
let(:username) { 'slack_username' }
@ -35,7 +35,7 @@ describe SlackService, models: true do
end
before do
allow(slack).to receive_messages(
allow(chat_service).to receive_messages(
project: project,
project_id: project.id,
service_hook: true,
@ -77,54 +77,55 @@ describe SlackService, models: true do
@wiki_page_sample_data = wiki_page_service.hook_data(@wiki_page, 'create')
end
it "calls Slack API for push events" do
slack.execute(push_sample_data)
it "calls Slack/Mattermost API for push events" do
chat_service.execute(push_sample_data)
expect(WebMock).to have_requested(:post, webhook_url).once
end
it "calls Slack API for issue events" do
slack.execute(@issues_sample_data)
it "calls Slack/Mattermost API for issue events" do
chat_service.execute(@issues_sample_data)
expect(WebMock).to have_requested(:post, webhook_url).once
end
it "calls Slack API for merge requests events" do
slack.execute(@merge_sample_data)
it "calls Slack/Mattermost 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 API for wiki page events" do
slack.execute(@wiki_page_sample_data)
it "calls Slack/Mattermost API for wiki page events" do
chat_service.execute(@wiki_page_sample_data)
expect(WebMock).to have_requested(:post, webhook_url).once
end
it 'uses the username as an option for slack when configured' do
allow(slack).to receive(:username).and_return(username)
allow(chat_service).to receive(:username).and_return(username)
expect(Slack::Notifier).to receive(:new).
with(webhook_url, username: username).
with(webhook_url, username: username, channel: chat_service.default_channel).
and_return(
double(:slack_service).as_null_object
)
slack.execute(push_sample_data)
chat_service.execute(push_sample_data)
end
it 'uses the channel as an option when it is configured' do
allow(slack).to receive(:channel).and_return(channel)
allow(chat_service).to receive(:channel).and_return(channel)
expect(Slack::Notifier).to receive(:new).
with(webhook_url, channel: channel).
and_return(
double(:slack_service).as_null_object
)
slack.execute(push_sample_data)
chat_service.execute(push_sample_data)
end
context "event channels" do
it "uses the right channel for push event" do
slack.update_attributes(push_channel: "random")
chat_service.update_attributes(push_channel: "random")
expect(Slack::Notifier).to receive(:new).
with(webhook_url, channel: "random").
@ -132,11 +133,11 @@ describe SlackService, models: true do
double(:slack_service).as_null_object
)
slack.execute(push_sample_data)
chat_service.execute(push_sample_data)
end
it "uses the right channel for merge request event" do
slack.update_attributes(merge_request_channel: "random")
chat_service.update_attributes(merge_request_channel: "random")
expect(Slack::Notifier).to receive(:new).
with(webhook_url, channel: "random").
@ -144,11 +145,11 @@ describe SlackService, models: true do
double(:slack_service).as_null_object
)
slack.execute(@merge_sample_data)
chat_service.execute(@merge_sample_data)
end
it "uses the right channel for issue event" do
slack.update_attributes(issue_channel: "random")
chat_service.update_attributes(issue_channel: "random")
expect(Slack::Notifier).to receive(:new).
with(webhook_url, channel: "random").
@ -156,11 +157,11 @@ describe SlackService, models: true do
double(:slack_service).as_null_object
)
slack.execute(@issues_sample_data)
chat_service.execute(@issues_sample_data)
end
it "uses the right channel for wiki event" do
slack.update_attributes(wiki_page_channel: "random")
chat_service.update_attributes(wiki_page_channel: "random")
expect(Slack::Notifier).to receive(:new).
with(webhook_url, channel: "random").
@ -168,7 +169,7 @@ describe SlackService, models: true do
double(:slack_service).as_null_object
)
slack.execute(@wiki_page_sample_data)
chat_service.execute(@wiki_page_sample_data)
end
context "note event" do
@ -177,7 +178,7 @@ describe SlackService, models: true do
end
it "uses the right channel" do
slack.update_attributes(note_channel: "random")
chat_service.update_attributes(note_channel: "random")
note_data = Gitlab::DataBuilder::Note.build(issue_note, user)
@ -187,7 +188,7 @@ describe SlackService, models: true do
double(:slack_service).as_null_object
)
slack.execute(note_data)
chat_service.execute(note_data)
end
end
end
@ -198,7 +199,7 @@ describe SlackService, models: true do
let(:project) { create(:project, creator_id: user.id) }
before do
allow(slack).to receive_messages(
allow(chat_service).to receive_messages(
project: project,
project_id: project.id,
service_hook: true,
@ -216,9 +217,9 @@ describe SlackService, models: true do
note: 'a comment on a commit')
end
it "calls Slack API for commit comment events" do
it "calls Slack/Mattermost API for commit comment events" do
data = Gitlab::DataBuilder::Note.build(commit_note, user)
slack.execute(data)
chat_service.execute(data)
expect(WebMock).to have_requested(:post, webhook_url).once
end
@ -232,7 +233,7 @@ describe SlackService, models: true do
it "calls Slack API for merge request comment events" do
data = Gitlab::DataBuilder::Note.build(merge_request_note, user)
slack.execute(data)
chat_service.execute(data)
expect(WebMock).to have_requested(:post, webhook_url).once
end
@ -245,7 +246,7 @@ describe SlackService, models: true do
it "calls Slack API for issue comment events" do
data = Gitlab::DataBuilder::Note.build(issue_note, user)
slack.execute(data)
chat_service.execute(data)
expect(WebMock).to have_requested(:post, webhook_url).once
end
@ -259,7 +260,7 @@ describe SlackService, models: true do
it "calls Slack API for snippet comment events" do
data = Gitlab::DataBuilder::Note.build(snippet_note, user)
slack.execute(data)
chat_service.execute(data)
expect(WebMock).to have_requested(:post, webhook_url).once
end
@ -277,21 +278,21 @@ describe SlackService, models: true do
end
before do
allow(slack).to receive_messages(
allow(chat_service).to receive_messages(
project: project,
service_hook: true,
webhook: webhook_url
)
end
shared_examples 'call Slack API' do
shared_examples 'call Slack/Mattermost API' do
before do
WebMock.stub_request(:post, webhook_url)
end
it 'calls Slack API for pipeline events' do
it 'calls Slack/Mattermost API for pipeline events' do
data = Gitlab::DataBuilder::Pipeline.build(pipeline)
slack.execute(data)
chat_service.execute(data)
expect(WebMock).to have_requested(:post, webhook_url).once
end
@ -300,16 +301,16 @@ describe SlackService, models: true do
context 'with failed pipeline' do
let(:status) { 'failed' }
it_behaves_like 'call Slack API'
it_behaves_like 'call Slack/Mattermost API'
end
context 'with succeeded pipeline' do
let(:status) { 'success' }
context 'with default to notify_only_broken_pipelines' do
it 'does not call Slack API for pipeline events' do
it 'does not call Slack/Mattermost API for pipeline events' do
data = Gitlab::DataBuilder::Pipeline.build(pipeline)
result = slack.execute(data)
result = chat_service.execute(data)
expect(result).to be_falsy
end
@ -317,10 +318,10 @@ describe SlackService, models: true do
context 'with setting notify_only_broken_pipelines to false' do
before do
slack.notify_only_broken_pipelines = false
chat_service.notify_only_broken_pipelines = false
end
it_behaves_like 'call Slack API'
it_behaves_like 'call Slack/Mattermost API'
end
end
end