Commit 1f404065 authored by Tiago Botelho's avatar Tiago Botelho

adds relevant tests

parent 05f69ef2
......@@ -2,14 +2,24 @@ require 'slack-notifier'
module ChatMessage
class BaseMessage
attr_reader :markdown_format
attr_reader :markdown
attr_reader :user_name
attr_reader :user_avatar
attr_reader :project_name
attr_reader :project_url
def initialize(params)
@markdown_format = params[:markdown_format] || false
@markdown = params[:markdown] || false
@project_name = params.dig(:project, :path_with_namespace) || params[:project_name]
@project_url = params.dig(:project, :web_url) || params[:project_url]
@user_name = params.dig(:user, :username) || params[:user_name]
@user_avatar = params.dig(:user, :avatar_url) || params[:user_avatar]
end
def pretext
markdown_format ? message : format(message)
return message if markdown
format(message)
end
def fallback
......
module ChatMessage
class IssueMessage < BaseMessage
attr_reader :user_name
attr_reader :user_avatar
attr_reader :title
attr_reader :project_name
attr_reader :project_url
attr_reader :issue_iid
attr_reader :issue_url
attr_reader :action
......@@ -12,12 +8,7 @@ module ChatMessage
attr_reader :description
def initialize(params)
super(params)
@user_name = params[:user][:username]
@user_avatar = params[:user][:avatar_url]
@project_name = params[:project_name]
@project_url = params[:project_url]
super
obj_attr = params[:object_attributes]
obj_attr = HashWithIndifferentAccess.new(obj_attr)
......@@ -31,23 +22,28 @@ module ChatMessage
def attachments
return [] unless opened_issue?
return description if markdown
markdown_format ? description : description_message
description_message
end
def activity
MicrosoftTeams::Activity.new(
"Issue #{state} by #{user_name}",
"to: #{project_link}",
issue_link,
user_avatar
).to_json
{
title: "Issue #{state} by #{user_name}",
subtitle: "in #{project_link}",
text: issue_link,
image: user_avatar
}
end
private
def message
"[#{project_link}] Issue #{issue_link} #{state} by #{user_name}"
if state == 'opened'
"[#{project_link}] Issue #{state} by #{user_name}"
else
"[#{project_link}] Issue #{issue_link} #{state} by #{user_name}"
end
end
def opened_issue?
......@@ -72,7 +68,7 @@ module ChatMessage
end
def issue_title
"##{issue_iid} #{title}"
"#{Issue.reference_prefix}#{issue_iid} #{title}"
end
end
end
module ChatMessage
class MergeMessage < BaseMessage
attr_reader :user_name
attr_reader :user_avatar
attr_reader :project_name
attr_reader :project_url
attr_reader :merge_request_id
attr_reader :merge_request_iid
attr_reader :source_branch
attr_reader :target_branch
attr_reader :state
attr_reader :title
def initialize(params)
super(params)
@user_name = params[:user][:username]
@user_avatar = params[:user][:avatar_url]
@project_name = params[:project_name]
@project_url = params[:project_url]
super
obj_attr = params[:object_attributes]
obj_attr = HashWithIndifferentAccess.new(obj_attr)
@merge_request_id = obj_attr[:iid]
@merge_request_iid = obj_attr[:iid]
@source_branch = obj_attr[:source_branch]
@target_branch = obj_attr[:target_branch]
@state = obj_attr[:state]
@title = format_title(obj_attr[:title])
end
def activity
MicrosoftTeams::Activity.new(
"Merge Request #{state} by #{user_name}",
"to: #{project_link}",
merge_request_link,
user_avatar
).to_json
end
def attachments
[]
end
def activity
{
title: "Merge Request #{state} by #{user_name}",
subtitle: "in #{project_link}",
text: merge_request_link,
image: user_avatar
}
end
private
def format_title(title)
......@@ -59,11 +50,15 @@ module ChatMessage
end
def merge_request_link
link("merge request !#{merge_request_id}", merge_request_url)
link(merge_request_title, merge_request_url)
end
def merge_request_title
"#{MergeRequest.reference_prefix}#{merge_request_iid} #{title}"
end
def merge_request_url
"#{project_url}/merge_requests/#{merge_request_id}"
"#{project_url}/merge_requests/#{merge_request_iid}"
end
end
end
module ChatMessage
class NoteMessage < BaseMessage
attr_reader :user_name
attr_reader :user_avatar
attr_reader :project_name
attr_reader :project_url
attr_reader :note
attr_reader :note_url
attr_reader :comment_attrs
attr_reader :title
attr_reader :target
def initialize(params)
params = HashWithIndifferentAccess.new(params)
super(params)
super
@user_name = params[:user][:name]
@user_avatar = params[:user][:avatar_url]
@project_name = params[:project_name]
@project_url = params[:project_url]
obj_attr = HashWithIndifferentAccess.new(params[:object_attributes])
params = HashWithIndifferentAccess.new(params)
obj_attr = params[:object_attributes]
@note = obj_attr[:note]
@note_url = obj_attr[:url]
@comment_attrs = comment_params(obj_attr[:noteable_type], params)
@target, @title = case obj_attr[:noteable_type]
when "Commit"
create_commit_note(params[:commit])
when "Issue"
create_issue_note(params[:issue])
when "MergeRequest"
create_merge_note(params[:merge_request])
when "Snippet"
create_snippet_note(params[:snippet])
end
end
def activity
MicrosoftTeams::Activity.new(
"#{user_name} #{link('commented on ' + comment_attrs[:target], note_url)}",
"to: #{project_link}",
comment_attrs[:title],
user_avatar
).to_json
def attachments
return note if markdown
description_message
end
def attachments
markdown_format ? note : description_message
def activity
{
title: "#{user_name} #{link('commented on ' + target, note_url)}",
subtitle: "in #{project_link}",
text: formatted_title,
image: user_avatar
}
end
private
def message
"#{user_name} #{link('commented on ' + comment_attrs[:target], note_url)} in #{project_link}: *#{comment_attrs[:title]}*"
end
def comment_params(noteable_type, params)
params = HashWithIndifferentAccess.new(params)
case noteable_type
when "Commit"
create_commit_note(params[:commit])
when "Issue"
create_issue_note(params[:issue])
when "MergeRequest"
create_merge_note(params[:merge_request])
when "Snippet"
create_snippet_note(params[:snippet])
end
"#{user_name} #{link('commented on ' + target, note_url)} in #{project_link}: *#{formatted_title}*"
end
def format_title(title)
title.lines.first.chomp
end
def formatted_title
format_title(title)
end
def create_issue_note(issue)
{ target: "issue ##{issue[:iid]}", title: format_title(issue[:title]) }
["issue #{Issue.reference_prefix}#{issue[:iid]}", issue[:title]]
end
def create_commit_note(commit)
commit_sha = Commit.truncate_sha(commit[:id])
{ target: "commit #{commit_sha}", title: format_title(commit[:message]) }
["commit #{commit_sha}", commit[:message]]
end
def create_merge_note(merge_request)
{ target: "merge request !#{merge_request[:iid]}", title: format_title(merge_request[:title]) }
["merge request #{MergeRequest.reference_prefix}#{merge_request[:iid]}", merge_request[:title]]
end
def create_snippet_note(snippet)
{ target: "snippet ##{snippet[:id]}", title: format_title(snippet[:title]) }
["snippet #{Snippet.reference_prefix}#{snippet[:id]}", snippet[:title]]
end
def description_message
......
......@@ -3,27 +3,20 @@ module ChatMessage
attr_reader :ref_type
attr_reader :ref
attr_reader :status
attr_reader :project_name
attr_reader :project_url
attr_reader :user_name
attr_reader :duration
attr_reader :pipeline_id
attr_reader :user_avatar
def initialize(data)
super
@user_name = data.dig(:user, :name) || 'API'
pipeline_attributes = data[:object_attributes]
@ref_type = pipeline_attributes[:tag] ? 'tag' : 'branch'
@ref = pipeline_attributes[:ref]
@status = pipeline_attributes[:status]
@duration = pipeline_attributes[:duration]
@pipeline_id = pipeline_attributes[:id]
super(data)
@project_name = data[:project][:path_with_namespace]
@project_url = data[:project][:web_url]
@user_name = (data[:user] && data[:user][:name]) || 'API'
@user_avatar = data[:user][:avatar_url] || ''
end
def pretext
......@@ -34,17 +27,19 @@ module ChatMessage
format(message)
end
def activity
MicrosoftTeams::Activity.new(
"Pipeline #{pipeline_link} of #{branch_link} #{ref_type} by #{user_name} #{humanized_status}",
"to: #{project_link}",
"in #{duration} #{time_measure}",
user_avatar
).to_json
def attachments
return message if markdown
[{ text: format(message), color: attachment_color }]
end
def attachments
markdown_format ? message : [{ text: format(message), color: attachment_color }]
def activity
{
title: "Pipeline #{pipeline_link} of #{branch_link} #{ref_type} by #{user_name} #{humanized_status}",
subtitle: "in #{project_link}",
text: "in #{duration} #{time_measure}",
image: user_avatar || ''
}
end
private
......
......@@ -3,49 +3,41 @@ module ChatMessage
attr_reader :after
attr_reader :before
attr_reader :commits
attr_reader :project_name
attr_reader :project_url
attr_reader :ref
attr_reader :ref_type
attr_reader :user_name
attr_reader :user_avatar
def initialize(params)
super(params)
super
@after = params[:after]
@before = params[:before]
@commits = params.fetch(:commits, [])
@project_name = params[:project_name]
@project_url = params[:project_url]
@ref_type = Gitlab::Git.tag_ref?(params[:ref]) ? 'tag' : 'branch'
@ref = Gitlab::Git.ref_name(params[:ref])
@user_name = params[:user_name]
@user_avatar = params[:user_avatar]
end
def activity
action =
if new_branch?
"created"
elsif removed_branch?
"removed"
else
"pushed to"
end
MicrosoftTeams::Activity.new(
"#{user_name} #{action} #{ref_type}",
"to: #{project_link}",
compare_link,
user_avatar
).to_json
end
def attachments
return [] if new_branch? || removed_branch?
return commit_messages if markdown
markdown_format ? commit_messages : commit_message_attachments
commit_message_attachments
end
def activity
action = if new_branch?
"created"
elsif removed_branch?
"removed"
else
"pushed to"
end
{
title: "#{user_name} #{action} #{ref_type}",
subtitle: "in #{project_link}",
text: compare_link,
image: user_avatar
}
end
private
......
module ChatMessage
class WikiPageMessage < BaseMessage
attr_reader :user_name
attr_reader :title
attr_reader :project_name
attr_reader :project_url
attr_reader :wiki_page_url
attr_reader :action
attr_reader :description
def initialize(params)
super(params)
@user_name = params[:user][:username]
@user_avatar = params[:user][:avatar_url]
@project_name = params[:project_name]
@project_url = params[:project_url]
super
obj_attr = params[:object_attributes]
obj_attr = HashWithIndifferentAccess.new(obj_attr)
......@@ -31,17 +23,19 @@ module ChatMessage
end
end
def activity
MicrosoftTeams::Activity.new(
"#{user_name} #{action} #{wiki_page_link}",
"in: #{project_link}",
title,
user_avatar
).to_json
def attachments
return description if markdown
description_message
end
def attachments
markdown_format ? @description : description_message
def activity
{
title: "#{user_name} #{action} #{wiki_page_link}",
subtitle: "in #{project_link}",
text: title,
image: user_avatar
}
end
private
......
......@@ -49,10 +49,7 @@ class ChatNotificationService < Service
object_kind = data[:object_kind]
data = data.merge(
project_url: project_url,
project_name: project_name
)
data = custom_data(data)
# WebHook events often have an 'update' event that follows a 'open' or
# 'close' action. Ignore update events for now to prevent duplicate
......@@ -68,8 +65,7 @@ class ChatNotificationService < Service
opts[:channel] = channel_name if channel_name
opts[:username] = username if username
notifier = Slack::Notifier.new(webhook, opts)
notifier.ping(message.pretext, attachments: message.attachments, fallback: message.fallback)
return false unless notify(message, opts)
true
end
......@@ -92,6 +88,18 @@ class ChatNotificationService < Service
private
def notify(message, opts)
Slack::Notifier.new(webhook, opts).ping(
message.pretext,
attachments: message.attachments,
fallback: message.fallback
)
end
def custom_data(data)
data.merge(project_url: project_url, project_name: project_name)
end
def get_message(object_kind, data)
case object_kind
when "push", "tag_push"
......
......@@ -4,14 +4,13 @@ class MicrosoftTeamsService < ChatNotificationService
end
def description
'Receive event notifications in Microsoft Team'
'Receive event notifications in Microsoft Teams'
end
def self.to_param
'microsoft_teams'
end
#TODO: Setup the description accordingly
def help
'This service sends notifications about projects events to Microsoft Teams channels.<br />
To set up this service:
......@@ -22,10 +21,6 @@ class MicrosoftTeamsService < ChatNotificationService
</ol>'
end
def default_channel_placeholder
"Channel name (e.g. general)"
end
def webhook_placeholder
'https://outlook.office.com/webhook/…'
end
......@@ -33,6 +28,9 @@ class MicrosoftTeamsService < ChatNotificationService
def event_field(event)
end
def default_channel_placeholder
end
def default_fields
[
{ type: 'text', name: 'webhook', placeholder: "e.g. #{webhook_placeholder}" },
......@@ -41,27 +39,18 @@ class MicrosoftTeamsService < ChatNotificationService
]
end
def execute(data)
return unless supported_events.include?(data[:object_kind])
return unless webhook.present?
object_kind = data[:object_kind]
private
data = data.merge(
project_url: project_url,
project_name: project_name,
markdown_format: true
)
message = get_message(object_kind, data)
return false unless message
MicrosoftTeams::Notifier.new(webhook).ping({
def notify(message, opts)
MicrosoftTeams::Notifier.new(webhook).ping(
title: message.project_name,
pretext: message.pretext,
activity: message.activity,
attachments: message.attachments
})
)
end
def custom_data(data)
super(data).merge(markdown: true)
end
end
---
title: Integrates Microsoft Teams webhooks with GitLab
merge_request: 10412
author:
# Microsoft Teams Service
## On Microsoft Teams
To enable Microsoft Teams integration you must create an incoming webhook integration on Microsoft Teams by following the steps described in this [document](https://msdn.microsoft.com/en-us/microsoft-teams/connectors)
## On GitLab
After you set up Microsoft Teams, it's time to set up GitLab.
Navigate to the [Integrations page](project_services.md#accessing-the-project-services)
and select the **Microsoft Teams Notification** service to configure it.
There, you will see a checkbox with the following events that can be triggered:
- Push
- Issue
- Confidential issue
- Merge request
- Note
- Tag push
- Pipeline
- Wiki page
At the end fill in your Microsoft Teams details:
| Field | Description |
| ----- | ----------- |
| **Webhook** | The incoming webhook URL which you have to setup on Microsoft Teams. |
| **Notify only broken pipelines** | If you choose to enable the **Pipeline** event and you want to be only notified about failed pipelines. |
After you are all done, click **Save changes** for the changes to take effect.
![Microsoft Teams configuration](img/microsoft_teams_configuration.png)
\ No newline at end of file
......@@ -488,6 +488,14 @@ module API
desc: 'The channel name'
}
],
'microsoft-teams' => [
{
required: true,
name: :webhook,
type: String,
desc: 'The Microsoft Teams webhook. e.g. https://outlook.office.com/webhook/…'
}
],
'mattermost' => [
{
required: true,
......@@ -550,6 +558,7 @@ module API
RedmineService,
SlackService,
MattermostService,
MicrosoftTeamsService,
TeamcityService,
]
......
......@@ -501,6 +501,12 @@ module API
desc: 'The channel name'
}
],
'microsoft-teams' => [
required: true,
name: :webhook,
type: String,
desc: 'The Microsoft Teams webhook. e.g. https://outlook.office.com/webhook/…'
],
'mattermost' => [
{
required: true,
......
module MicrosoftTeams
class Activity
def initialize(title, subtitle, text, image)
def initialize(title:, subtitle:, text:, image:)
@title = title
@subtitle = subtitle
@text = text
@image = image
end
def to_json
def prepare
{
'activityTitle' => @title,
'activitySubtitle' => @subtitle,
'activityText' => @text,
'activityImage' => @image
}.to_json
}
end
end
end
......@@ -2,30 +2,43 @@ module MicrosoftTeams
class Notifier
def initialize(webhook)
@webhook = webhook
@header = { 'Content-type' => 'application/json' }
end
def ping(options = {})
HTTParty.post(
@webhook.to_str,
headers: { 'Content-type' => 'application/json' },
body: body(options)
)
result = false
begin
response = HTTParty.post(
@webhook.to_str,
headers: @header,
body: body(options)
)
result = true if response
rescue HTTParty::Error, StandardError => error
Rails.logger.info("#{self.class.name}: Error while connecting to #{@webhook}: #{error.message}")
end
result
end
private
def body(options = {})
attachments = options[:attachments]
result = { 'sections' => [] }
result['title'] = options[:title]
result['summary'] = options[:pretext]
result['sections'] << options[:activity]
result['sections'] << MicrosoftTeams::Activity.new(options[:activity]).prepare
result['sections'] << {
'title' => 'Details',
'facts' => [{ 'name' => 'Attachments', 'value' => attachments }]
} if attachments.present? && attachments.empty?
attachments = options[:attachments]
unless attachments.blank?
result['sections'] << {
'title' => 'Details',
'facts' => [{ 'name' => 'Attachments', 'value' => attachments }]
}
end
result.to_json
end
......
require 'spec_helper'
describe MicrosoftTeams::Activity do
subject { described_class.new(title: 'title', subtitle: 'subtitle', text: 'text', image: 'image') }
describe '#prepare' do
it 'returns the correct JSON object' do
expect(subject.prepare).to eq({
'activityTitle' => 'title',
'activitySubtitle' => 'subtitle',
'activityText' => 'text',
'activityImage' => 'image'
})
end
end
end
require 'spec_helper'
describe MicrosoftTeams::Notifier do
subject { described_class.new(webhook_url) }
let(:webhook_url) { 'https://example.gitlab.com/'}
let(:header) { { 'Content-Type' => 'application/json' } }
let(:options) do
{
title: 'JohnDoe4/project2',
pretext: '[[JohnDoe4/project2](http://localhost/namespace2/gitlabhq)] Issue [#1 Awesome issue](http://localhost/namespace2/gitlabhq/issues/1) opened by user6',
activity: {
title: 'Issue opened by user6',
subtitle: 'in [JohnDoe4/project2](http://localhost/namespace2/gitlabhq)',
text: '[#1 Awesome issue](http://localhost/namespace2/gitlabhq/issues/1)',
image: 'http://someimage.com'
},
attachments: 'please fix'
}
end
let(:body) do
{
'sections' => [
{
'activityTitle' => 'Issue opened by user6',
'activitySubtitle' => 'in [JohnDoe4/project2](http://localhost/namespace2/gitlabhq)',
'activityText' => '[#1 Awesome issue](http://localhost/namespace2/gitlabhq/issues/1)',
'activityImage' => 'http://someimage.com'
},
{
'title' => 'Details',
'facts' => [
{
'name' => 'Attachments',
'value' => 'please fix'
}
]
}
],
'title' => 'JohnDoe4/project2',
'summary' => '[[JohnDoe4/project2](http://localhost/namespace2/gitlabhq)] Issue [#1 Awesome issue](http://localhost/namespace2/gitlabhq/issues/1) opened by user6'
}
end
describe '#ping' do
before do
stub_request(:post, webhook_url).with(body: JSON(body), headers: { 'Content-Type' => 'application/json' }).to_return(status: 200, body: "", headers: {})
end
it 'expects to receive successfull answer' do
expect(subject.ping(options)).to be true
end
end
end
......@@ -7,7 +7,8 @@ describe ChatMessage::IssueMessage, models: true do
{
user: {
name: 'Test User',
username: 'test.user'
username: 'test.user',
avatar_url: 'http://someavatar.com'
},
project_name: 'project_name',
project_url: 'http://somewhere.com',
......@@ -25,43 +26,84 @@ describe ChatMessage::IssueMessage, models: true do
}
end
let(:color) { '#C95823' }
context 'without markdown' do
let(:color) { '#C95823' }
context '#initialize' do
before do
args[:object_attributes][:description] = nil
context '#initialize' do
before do
args[:object_attributes][:description] = nil
end
it 'returns a non-null description' do
expect(subject.description).to eq('')
end
end
it 'returns a non-null description' do
expect(subject.description).to eq('')
context 'open' do
it 'returns a message regarding opening of issues' do
expect(subject.pretext).to eq(
'[<http://somewhere.com|project_name>] Issue opened by test.user')
expect(subject.attachments).to eq([
{
title: "#100 Issue title",
title_link: "http://url.com",
text: "issue description",
color: color,
}
])
end
end
end
context 'open' do
it 'returns a message regarding opening of issues' do
expect(subject.pretext).to eq(
'[<http://somewhere.com|project_name>] Issue opened by test.user')
expect(subject.attachments).to eq([
{
title: "#100 Issue title",
title_link: "http://url.com",
text: "issue description",
color: color,
}
])
context 'close' do
before do
args[:object_attributes][:action] = 'close'
args[:object_attributes][:state] = 'closed'
end
it 'returns a message regarding closing of issues' do
expect(subject.pretext). to eq(
'[<http://somewhere.com|project_name>] Issue <http://url.com|#100 Issue title> closed by test.user')
expect(subject.attachments).to be_empty
end
end
end
context 'close' do
context 'with markdown' do
before do
args[:object_attributes][:action] = 'close'
args[:object_attributes][:state] = 'closed'
args[:markdown] = true
end
it 'returns a message regarding closing of issues' do
expect(subject.pretext). to eq(
'[<http://somewhere.com|project_name>] Issue <http://url.com|#100 Issue title> closed by test.user')
expect(subject.attachments).to be_empty
context 'open' do
it 'returns a message regarding opening of issues' do
expect(subject.pretext).to eq(
'[[project_name](http://somewhere.com)] Issue opened by test.user')
expect(subject.attachments).to eq('issue description')
expect(subject.activity).to eq({
title: 'Issue opened by test.user',
subtitle: 'in [project_name](http://somewhere.com)',
text: '[#100 Issue title](http://url.com)',
image: 'http://someavatar.com'
})
end
end
context 'close' do
before do
args[:object_attributes][:action] = 'close'
args[:object_attributes][:state] = 'closed'
end
it 'returns a message regarding closing of issues' do
expect(subject.pretext). to eq(
'[[project_name](http://somewhere.com)] Issue [#100 Issue title](http://url.com) closed by test.user')
expect(subject.attachments).to be_empty
expect(subject.activity).to eq({
title: 'Issue closed by test.user',
subtitle: 'in [project_name](http://somewhere.com)',
text: '[#100 Issue title](http://url.com)',
image: 'http://someavatar.com'
})
end
end
end
end
......@@ -7,45 +7,84 @@ describe ChatMessage::MergeMessage, models: true do
{
user: {
name: 'Test User',
username: 'test.user'
username: 'test.user',
avatar_url: 'http://someavatar.com'
},
project_name: 'project_name',
project_url: 'http://somewhere.com',
object_attributes: {
title: "Issue title\nSecond line",
title: "Merge Request title\nSecond line",
id: 10,
iid: 100,
assignee_id: 1,
url: 'http://url.com',
state: 'opened',
description: 'issue description',
description: 'merge request description',
source_branch: 'source_branch',
target_branch: 'target_branch',
}
}
end
let(:color) { '#345' }
context 'without markdown' do
let(:color) { '#345' }
context 'open' do
it 'returns a message regarding opening of merge requests' do
expect(subject.pretext).to eq(
'test.user opened <http://somewhere.com/merge_requests/100|merge request !100> '\
'in <http://somewhere.com|project_name>: *Issue title*')
expect(subject.attachments).to be_empty
context 'open' do
it 'returns a message regarding opening of merge requests' do
expect(subject.pretext).to eq(
'test.user opened <http://somewhere.com/merge_requests/100|!100 *Merge Request title*> in <http://somewhere.com|project_name>: *Merge Request title*')
expect(subject.attachments).to be_empty
end
end
context 'close' do
before do
args[:object_attributes][:state] = 'closed'
end
it 'returns a message regarding closing of merge requests' do
expect(subject.pretext).to eq(
'test.user closed <http://somewhere.com/merge_requests/100|!100 *Merge Request title*> in <http://somewhere.com|project_name>: *Merge Request title*')
expect(subject.attachments).to be_empty
end
end
end
context 'close' do
context 'with markdown' do
before do
args[:object_attributes][:state] = 'closed'
args[:markdown] = true
end
context 'open' do
it 'returns a message regarding opening of merge requests' do
expect(subject.pretext).to eq(
'test.user opened [!100 *Merge Request title*](http://somewhere.com/merge_requests/100) in [project_name](http://somewhere.com): *Merge Request title*')
expect(subject.attachments).to be_empty
expect(subject.activity).to eq({
title: 'Merge Request opened by test.user',
subtitle: 'in [project_name](http://somewhere.com)',
text: '[!100 *Merge Request title*](http://somewhere.com/merge_requests/100)',
image: 'http://someavatar.com'
})
end
end
it 'returns a message regarding closing of merge requests' do
expect(subject.pretext).to eq(
'test.user closed <http://somewhere.com/merge_requests/100|merge request !100> '\
'in <http://somewhere.com|project_name>: *Issue title*')
expect(subject.attachments).to be_empty
context 'close' do
before do
args[:object_attributes][:state] = 'closed'
end
it 'returns a message regarding closing of merge requests' do
expect(subject.pretext).to eq(
'test.user closed [!100 *Merge Request title*](http://somewhere.com/merge_requests/100) in [project_name](http://somewhere.com): *Merge Request title*')
expect(subject.attachments).to be_empty
expect(subject.activity).to eq({
title: 'Merge Request closed by test.user',
subtitle: 'in [project_name](http://somewhere.com)',
text: '[!100 *Merge Request title*](http://somewhere.com/merge_requests/100)',
image: 'http://someavatar.com'
})
end
end
end
end
require 'spec_helper'
describe ChatMessage::NoteMessage, models: true do
let(:color) { '#345' }
subject { described_class.new(args) }
before do
@args = {
user: {
name: 'Test User',
username: 'test.user',
avatar_url: 'http://fakeavatar'
},
project_name: 'project_name',
project_url: 'http://somewhere.com',
repository: {
name: 'project_name',
url: 'http://somewhere.com',
},
object_attributes: {
id: 10,
note: 'comment on a commit',
url: 'http://url.com',
noteable_type: 'Commit'
}
let(:color) { '#345' }
let(:args) do
{
user: {
name: 'Test User',
username: 'test.user',
avatar_url: 'http://fakeavatar'
},
project_name: 'project_name',
project_url: 'http://somewhere.com',
repository: {
name: 'project_name',
url: 'http://somewhere.com',
},
object_attributes: {
id: 10,
note: 'comment on a commit',
url: 'http://url.com',
noteable_type: 'Commit'
}
}
end
context 'commit notes' do
before do
@args[:object_attributes][:note] = 'comment on a commit'
@args[:object_attributes][:noteable_type] = 'Commit'
@args[:commit] = {
id: '5f163b2b95e6f53cbd428f5f0b103702a52b9a23',
message: "Added a commit message\ndetails\n123\n"
args[:object_attributes][:note] = 'comment on a commit'
args[:object_attributes][:noteable_type] = 'Commit'
args[:commit] = {
id: '5f163b2b95e6f53cbd428f5f0b103702a52b9a23',
message: "Added a commit message\ndetails\n123\n"
}
end
it 'returns a message regarding notes on commits' do
message = described_class.new(@args)
expect(message.pretext).to eq("test.user <http://url.com|commented on " \
"commit 5f163b2b> in <http://somewhere.com|project_name>: " \
"*Added a commit message*")
expected_attachments = [
{
text: "comment on a commit",
color: color,
}
]
expect(message.attachments).to eq(expected_attachments)
context 'without markdown' do
it 'returns a message regarding notes on commits' do
expect(subject.pretext).to eq("test.user <http://url.com|commented on " \
"commit 5f163b2b> in <http://somewhere.com|project_name>: " \
"*Added a commit message*")
expect(subject.attachments).to eq([{
text: 'comment on a commit',
color: color
}])
end
end
context 'with markdown' do
before do
args[:markdown] = true
end
it 'returns a message regarding notes on commits' do
expect(subject.pretext).to eq(
'test.user [commented on commit 5f163b2b](http://url.com) in [project_name](http://somewhere.com): *Added a commit message*'
)
expect(subject.attachments).to eq('comment on a commit')
expect(subject.activity).to eq({
title: 'test.user [commented on commit 5f163b2b](http://url.com)',
subtitle: 'in [project_name](http://somewhere.com)',
text: 'Added a commit message',
image: 'http://fakeavatar'
})
end
end
end
context 'merge request notes' do
before do
@args[:object_attributes][:note] = 'comment on a merge request'
@args[:object_attributes][:noteable_type] = 'MergeRequest'
@args[:merge_request] = {
id: 1,
iid: 30,
title: "merge request title\ndetails\n"
args[:object_attributes][:note] = 'comment on a merge request'
args[:object_attributes][:noteable_type] = 'MergeRequest'
args[:merge_request] = {
id: 1,
iid: 30,
title: "merge request title\ndetails\n"
}
end
it 'returns a message regarding notes on a merge request' do
message = described_class.new(@args)
expect(message.pretext).to eq("test.user <http://url.com|commented on " \
"merge request !30> in <http://somewhere.com|project_name>: " \
"*merge request title*")
expected_attachments = [
{
text: "comment on a merge request",
color: color,
}
]
expect(message.attachments).to eq(expected_attachments)
context 'without markdown' do
it 'returns a message regarding notes on a merge request' do
expect(subject.pretext).to eq("test.user <http://url.com|commented on " \
"merge request !30> in <http://somewhere.com|project_name>: " \
"*merge request title*")
expect(subject.attachments).to eq([{
text: 'comment on a merge request',
color: color
}])
end
end
context 'with markdown' do
before do
args[:markdown] = true
end
it 'returns a message regarding notes on a merge request' do
expect(subject.pretext).to eq(
'test.user [commented on merge request !30](http://url.com) in [project_name](http://somewhere.com): *merge request title*')
expect(subject.attachments).to eq('comment on a merge request')
expect(subject.activity).to eq({
title: 'test.user [commented on merge request !30](http://url.com)',
subtitle: 'in [project_name](http://somewhere.com)',
text: 'merge request title',
image: 'http://fakeavatar'
})
end
end
end
context 'issue notes' do
before do
@args[:object_attributes][:note] = 'comment on an issue'
@args[:object_attributes][:noteable_type] = 'Issue'
@args[:issue] = {
id: 1,
iid: 20,
title: "issue title\ndetails\n"
args[:object_attributes][:note] = 'comment on an issue'
args[:object_attributes][:noteable_type] = 'Issue'
args[:issue] = {
id: 1,
iid: 20,
title: "issue title\ndetails\n"
}
end
it 'returns a message regarding notes on an issue' do
message = described_class.new(@args)
expect(message.pretext).to eq(
"test.user <http://url.com|commented on " \
"issue #20> in <http://somewhere.com|project_name>: " \
"*issue title*")
expected_attachments = [
{
text: "comment on an issue",
color: color,
}
]
expect(message.attachments).to eq(expected_attachments)
context 'without markdown' do
it 'returns a message regarding notes on an issue' do
expect(subject.pretext).to eq(
"test.user <http://url.com|commented on " \
"issue #20> in <http://somewhere.com|project_name>: " \
"*issue title*")
expect(subject.attachments).to eq([{
text: 'comment on an issue',
color: color
}])
end
end
context 'with markdown' do
before do
args[:markdown] = true
end
it 'returns a message regarding notes on an issue' do
expect(subject.pretext).to eq(
'test.user [commented on issue #20](http://url.com) in [project_name](http://somewhere.com): *issue title*')
expect(subject.attachments).to eq('comment on an issue')
expect(subject.activity).to eq({
title: 'test.user [commented on issue #20](http://url.com)',
subtitle: 'in [project_name](http://somewhere.com)',
text: 'issue title',
image: 'http://fakeavatar'
})
end
end
end
context 'project snippet notes' do
before do
@args[:object_attributes][:note] = 'comment on a snippet'
@args[:object_attributes][:noteable_type] = 'Snippet'
@args[:snippet] = {
id: 5,
title: "snippet title\ndetails\n"
args[:object_attributes][:note] = 'comment on a snippet'
args[:object_attributes][:noteable_type] = 'Snippet'
args[:snippet] = {
id: 5,
title: "snippet title\ndetails\n"
}
end
it 'returns a message regarding notes on a project snippet' do
message = described_class.new(@args)
expect(message.pretext).to eq("test.user <http://url.com|commented on " \
"snippet #5> in <http://somewhere.com|project_name>: " \
"*snippet title*")
expected_attachments = [
{
text: "comment on a snippet",
color: color,
}
]
expect(message.attachments).to eq(expected_attachments)
context 'without markdown' do
it 'returns a message regarding notes on a project snippet' do
expect(subject.pretext).to eq("test.user <http://url.com|commented on " \
"snippet $5> in <http://somewhere.com|project_name>: " \
"*snippet title*")
expect(subject.attachments).to eq([{
text: 'comment on a snippet',
color: color
}])
end
end
context 'with markdown' do
before do
args[:markdown] = true
end
it 'returns a message regarding notes on a project snippet' do
expect(subject.pretext).to eq(
'test.user [commented on snippet $5](http://url.com) in [project_name](http://somewhere.com): *snippet title*')
expect(subject.attachments).to eq('comment on a snippet')
end
end
end
end
......@@ -2,8 +2,8 @@ require 'spec_helper'
describe ChatMessage::PipelineMessage do
subject { described_class.new(args) }
let(:user) { { name: 'hacker' } }
let(:user) { { name: 'hacker' } }
let(:args) do
{
object_attributes: {
......@@ -14,54 +14,122 @@ describe ChatMessage::PipelineMessage do
status: status,
duration: duration
},
project: { path_with_namespace: 'project_name',
web_url: 'http://example.gitlab.com' },
project: {
path_with_namespace: 'project_name',
web_url: 'http://example.gitlab.com'
},
user: user
}
end
let(:message) { build_message }
context 'without markdown' do
context 'pipeline succeeded' do
let(:status) { 'success' }
let(:color) { 'good' }
let(:duration) { 10 }
let(:message) { build_message('passed') }
it 'returns a message with information about succeeded build' do
expect(subject.pretext).to be_empty
expect(subject.fallback).to eq(message)
expect(subject.attachments).to eq([text: message, color: color])
end
end
context 'pipeline succeeded' do
let(:status) { 'success' }
let(:color) { 'good' }
let(:duration) { 10 }
let(:message) { build_message('passed') }
context 'pipeline failed' do
let(:status) { 'failed' }
let(:color) { 'danger' }
let(:duration) { 10 }
let(:message) { build_message }
it 'returns a message with information about succeeded build' do
verify_message
it 'returns a message with information about failed build' do
expect(subject.pretext).to be_empty
expect(subject.fallback).to eq(message)
expect(subject.attachments).to eq([text: message, color: color])
end
context 'when triggered by API therefore lacking user' do
let(:user) { nil }
let(:message) { build_message(status, 'API') }
it 'returns a message stating it is by API' do
expect(subject.pretext).to be_empty
expect(subject.fallback).to eq(message)
expect(subject.attachments).to eq([text: message, color: color])
end
end
end
end
context 'pipeline failed' do
let(:status) { 'failed' }
let(:color) { 'danger' }
let(:duration) { 10 }
def build_message(status_text = status, name = user[:name])
"<http://example.gitlab.com|project_name>:" \
" Pipeline <http://example.gitlab.com/pipelines/123|#123>" \
" of <http://example.gitlab.com/commits/develop|develop> branch" \
" by #{name} #{status_text} in #{duration} #{'second'.pluralize(duration)}"
end
end
it 'returns a message with information about failed build' do
verify_message
context 'with markdown' do
before do
args[:markdown] = true
end
context 'when triggered by API therefore lacking user' do
let(:user) { nil }
let(:message) { build_message(status, 'API') }
context 'pipeline succeeded' do
let(:status) { 'success' }
let(:color) { 'good' }
let(:duration) { 10 }
let(:message) { build_markdown_message('passed') }
it 'returns a message stating it is by API' do
verify_message
it 'returns a message with information about succeeded build' do
expect(subject.pretext).to be_empty
expect(subject.attachments).to eq(message)
expect(subject.activity).to eq({
title: 'Pipeline [#123](http://example.gitlab.com/pipelines/123) of [develop](http://example.gitlab.com/commits/develop) branch by hacker passed',
subtitle: 'in [project_name](http://example.gitlab.com)',
text: 'in 10 seconds',
image: ''
})
end
end
end
def verify_message
expect(subject.pretext).to be_empty
expect(subject.fallback).to eq(message)
expect(subject.attachments).to eq([text: message, color: color])
end
context 'pipeline failed' do
let(:status) { 'failed' }
let(:color) { 'danger' }
let(:duration) { 10 }
let(:message) { build_markdown_message }
it 'returns a message with information about failed build' do
expect(subject.pretext).to be_empty
expect(subject.attachments).to eq(message)
expect(subject.activity).to eq({
title: 'Pipeline [#123](http://example.gitlab.com/pipelines/123) of [develop](http://example.gitlab.com/commits/develop) branch by hacker failed',
subtitle: 'in [project_name](http://example.gitlab.com)',
text: 'in 10 seconds',
image: ''
})
end
def build_message(status_text = status, name = user[:name])
"<http://example.gitlab.com|project_name>:" \
" Pipeline <http://example.gitlab.com/pipelines/123|#123>" \
" of <http://example.gitlab.com/commits/develop|develop> branch" \
" by #{name} #{status_text} in #{duration} #{'second'.pluralize(duration)}"
context 'when triggered by API therefore lacking user' do
let(:user) { nil }
let(:message) { build_markdown_message(status, 'API') }
it 'returns a message stating it is by API' do
expect(subject.pretext).to be_empty
expect(subject.attachments).to eq(message)
expect(subject.activity).to eq({
title: 'Pipeline [#123](http://example.gitlab.com/pipelines/123) of [develop](http://example.gitlab.com/commits/develop) branch by API failed',
subtitle: 'in [project_name](http://example.gitlab.com)',
text: 'in 10 seconds',
image: ''
})
end
end
end
def build_markdown_message(status_text = status, name = user[:name])
"[project_name](http://example.gitlab.com):" \
" Pipeline [#123](http://example.gitlab.com/pipelines/123)" \
" of [develop](http://example.gitlab.com/commits/develop)" \
" branch by #{name} #{status_text} in #{duration} #{'second'.pluralize(duration)}"
end
end
end
......@@ -10,6 +10,7 @@ describe ChatMessage::PushMessage, models: true do
project_name: 'project_name',
ref: 'refs/heads/master',
user_name: 'test.user',
user_avatar: 'http://someavatar.com',
project_url: 'http://url.com'
}
end
......@@ -24,18 +25,36 @@ describe ChatMessage::PushMessage, models: true do
]
end
it 'returns a message regarding pushes' do
expect(subject.pretext).to eq(
'test.user pushed to branch <http://url.com/commits/master|master> of '\
'<http://url.com|project_name> (<http://url.com/compare/before...after|Compare changes>)'
)
expect(subject.attachments).to eq([
{
text: "<http://url1.com|abcdefgh>: message1 - author1\n"\
"<http://url2.com|12345678>: message2 - author2",
context 'without markdown' do
it 'returns a message regarding pushes' do
expect(subject.pretext).to eq(
'test.user pushed to branch <http://url.com/commits/master|master> of '\
'<http://url.com|project_name> (<http://url.com/compare/before...after|Compare changes>)')
expect(subject.attachments).to eq([{
text: "<http://url1.com|abcdefgh>: message1 - author1\n\n"\
"<http://url2.com|12345678>: message2 - author2",
color: color,
}
])
}])
end
end
context 'with markdown' do
before do
args[:markdown] = true
end
it 'returns a message regarding pushes' do
expect(subject.pretext).to eq(
'test.user pushed to branch [master](http://url.com/commits/master) of [project_name](http://url.com) ([Compare changes](http://url.com/compare/before...after))')
expect(subject.attachments).to eq(
"[abcdefgh](http://url1.com): message1 - author1\n\n[12345678](http://url2.com): message2 - author2")
expect(subject.activity).to eq({
title: 'test.user pushed to branch',
subtitle: 'in [project_name](http://url.com)',
text: '[Compare changes](http://url.com/compare/before...after)',
image: 'http://someavatar.com'
})
end
end
end
......@@ -47,15 +66,36 @@ describe ChatMessage::PushMessage, models: true do
project_name: 'project_name',
ref: 'refs/tags/new_tag',
user_name: 'test.user',
user_avatar: 'http://someavatar.com',
project_url: 'http://url.com'
}
end
it 'returns a message regarding pushes' do
expect(subject.pretext).to eq('test.user pushed new tag ' \
'<http://url.com/commits/new_tag|new_tag> to ' \
'<http://url.com|project_name>')
expect(subject.attachments).to be_empty
context 'without markdown' do
it 'returns a message regarding pushes' do
expect(subject.pretext).to eq('test.user pushed new tag ' \
'<http://url.com/commits/new_tag|new_tag> to ' \
'<http://url.com|project_name>')
expect(subject.attachments).to be_empty
end
end
context 'with markdown' do
before do
args[:markdown] = true
end
it 'returns a message regarding pushes' do
expect(subject.pretext).to eq(
'test.user pushed new tag [new_tag](http://url.com/commits/new_tag) to [project_name](http://url.com)')
expect(subject.attachments).to be_empty
expect(subject.activity).to eq({
title: 'test.user created tag',
subtitle: 'in [project_name](http://url.com)',
text: '[Compare changes](http://url.com/compare/0000000000000000000000000000000000000000...after)',
image: 'http://someavatar.com'
})
end
end
end
......@@ -64,12 +104,31 @@ describe ChatMessage::PushMessage, models: true do
args[:before] = Gitlab::Git::BLANK_SHA
end
it 'returns a message regarding a new branch' do
expect(subject.pretext).to eq(
'test.user pushed new branch <http://url.com/commits/master|master> to '\
'<http://url.com|project_name>'
)
expect(subject.attachments).to be_empty
context 'without markdown' do
it 'returns a message regarding a new branch' do
expect(subject.pretext).to eq(
'test.user pushed new branch <http://url.com/commits/master|master> to '\
'<http://url.com|project_name>')
expect(subject.attachments).to be_empty
end
end
context 'with markdown' do
before do
args[:markdown] = true
end
it 'returns a message regarding a new branch' do
expect(subject.pretext).to eq(
'test.user pushed new branch [master](http://url.com/commits/master) to [project_name](http://url.com)')
expect(subject.attachments).to be_empty
expect(subject.activity).to eq({
title: 'test.user created branch',
subtitle: 'in [project_name](http://url.com)',
text: '[Compare changes](http://url.com/compare/0000000000000000000000000000000000000000...after)',
image: 'http://someavatar.com'
})
end
end
end
......@@ -78,11 +137,30 @@ describe ChatMessage::PushMessage, models: true do
args[:after] = Gitlab::Git::BLANK_SHA
end
it 'returns a message regarding a removed branch' do
expect(subject.pretext).to eq(
'test.user removed branch master from <http://url.com|project_name>'
)
expect(subject.attachments).to be_empty
context 'without markdown' do
it 'returns a message regarding a removed branch' do
expect(subject.pretext).to eq(
'test.user removed branch master from <http://url.com|project_name>')
expect(subject.attachments).to be_empty
end
end
context 'with markdown' do
before do
args[:markdown] = true
end
it 'returns a message regarding a removed branch' do
expect(subject.pretext).to eq(
'test.user removed branch master from [project_name](http://url.com)')
expect(subject.attachments).to be_empty
expect(subject.activity).to eq({
title: 'test.user removed branch',
subtitle: 'in [project_name](http://url.com)',
text: '[Compare changes](http://url.com/compare/before...0000000000000000000000000000000000000000)',
image: 'http://someavatar.com'
})
end
end
end
end
......@@ -7,7 +7,8 @@ describe ChatMessage::WikiPageMessage, models: true do
{
user: {
name: 'Test User',
username: 'test.user'
username: 'test.user',
avatar_url: 'http://someavatar.com'
},
project_name: 'project_name',
project_url: 'http://somewhere.com',
......@@ -19,54 +20,128 @@ describe ChatMessage::WikiPageMessage, models: true do
}
end
describe '#pretext' do
context 'when :action == "create"' do
before { args[:object_attributes][:action] = 'create' }
context 'without markdown' do
describe '#pretext' do
context 'when :action == "create"' do
before { args[:object_attributes][:action] = 'create' }
it 'returns a message that a new wiki page was created' do
expect(subject.pretext).to eq(
'test.user created <http://url.com|wiki page> in <http://somewhere.com|project_name>: '\
'*Wiki page title*')
it 'returns a message that a new wiki page was created' do
expect(subject.pretext).to eq(
'test.user created <http://url.com|wiki page> in <http://somewhere.com|project_name>: '\
'*Wiki page title*')
end
end
context 'when :action == "update"' do
before { args[:object_attributes][:action] = 'update' }
it 'returns a message that a wiki page was updated' do
expect(subject.pretext).to eq(
'test.user edited <http://url.com|wiki page> in <http://somewhere.com|project_name>: '\
'*Wiki page title*')
end
end
end
context 'when :action == "update"' do
before { args[:object_attributes][:action] = 'update' }
describe '#attachments' do
let(:color) { '#345' }
it 'returns a message that a wiki page was updated' do
expect(subject.pretext).to eq(
'test.user edited <http://url.com|wiki page> in <http://somewhere.com|project_name>: '\
'*Wiki page title*')
context 'when :action == "create"' do
before { args[:object_attributes][:action] = 'create' }
it 'returns the attachment for a new wiki page' do
expect(subject.attachments).to eq([
{
text: "Wiki page description",
color: color,
}
])
end
end
context 'when :action == "update"' do
before { args[:object_attributes][:action] = 'update' }
it 'returns the attachment for an updated wiki page' do
expect(subject.attachments).to eq([
{
text: "Wiki page description",
color: color,
}
])
end
end
end
end
describe '#attachments' do
let(:color) { '#345' }
context 'with markdown' do
before do
args[:markdown] = true
end
describe '#pretext' do
context 'when :action == "create"' do
before { args[:object_attributes][:action] = 'create' }
it 'returns a message that a new wiki page was created' do
expect(subject.pretext).to eq(
'test.user created [wiki page](http://url.com) in [project_name](http://somewhere.com): *Wiki page title*')
end
end
context 'when :action == "create"' do
before { args[:object_attributes][:action] = 'create' }
context 'when :action == "update"' do
before { args[:object_attributes][:action] = 'update' }
it 'returns the attachment for a new wiki page' do
expect(subject.attachments).to eq([
{
text: "Wiki page description",
color: color,
}
])
it 'returns a message that a wiki page was updated' do
expect(subject.pretext).to eq(
'test.user edited [wiki page](http://url.com) in [project_name](http://somewhere.com): *Wiki page title*')
end
end
end
context 'when :action == "update"' do
before { args[:object_attributes][:action] = 'update' }
describe '#attachments' do
context 'when :action == "create"' do
before { args[:object_attributes][:action] = 'create' }
it 'returns the attachment for a new wiki page' do
expect(subject.attachments).to eq('Wiki page description')
end
end
context 'when :action == "update"' do
before { args[:object_attributes][:action] = 'update' }
it 'returns the attachment for an updated wiki page' do
expect(subject.attachments).to eq('Wiki page description')
end
end
end
describe '#activity' do
context 'when :action == "create"' do
before { args[:object_attributes][:action] = 'create' }
it 'returns the attachment for a new wiki page' do
expect(subject.activity).to eq({
title: 'test.user created [wiki page](http://url.com)',
subtitle: 'in [project_name](http://somewhere.com)',
text: 'Wiki page title',
image: 'http://someavatar.com'
})
end
end
context 'when :action == "update"' do
before { args[:object_attributes][:action] = 'update' }
it 'returns the attachment for an updated wiki page' do
expect(subject.attachments).to eq([
{
text: "Wiki page description",
color: color,
}
])
it 'returns the attachment for an updated wiki page' do
expect(subject.activity).to eq({
title: 'test.user edited [wiki page](http://url.com)',
subtitle: 'in [project_name](http://somewhere.com)',
text: 'Wiki page title',
image: 'http://someavatar.com'
})
end
end
end
end
......
require 'spec_helper'
describe MicrosoftTeamsService, models: true do
let(:chat_service) { described_class.new }
let(:webhook_url) { 'https://example.gitlab.com/' }
describe "Associations" do
it { is_expected.to belong_to :project }
it { is_expected.to have_one :service_hook }
end
describe 'Validations' do
context 'when service is active' do
before { subject.active = true }
it { is_expected.to validate_presence_of(:webhook) }
it_behaves_like 'issue tracker service URL attribute', :webhook
end
context 'when service is inactive' do
before { subject.active = false }
it { is_expected.not_to validate_presence_of(:webhook) }
end
end
describe "#execute" do
let(:user) { create(:user) }
let(:project) { create(:project, :repository) }
before do
allow(chat_service).to receive_messages(
project: project,
project_id: project.id,
service_hook: true,
webhook: webhook_url
)
WebMock.stub_request(:post, webhook_url)
end
context 'with push events' do
let(:push_sample_data) do
Gitlab::DataBuilder::Push.build_sample(project, user)
end
it "calls Microsoft Teams API for push events" do
chat_service.execute(push_sample_data)
expect(WebMock).to have_requested(:post, webhook_url).once
end
it 'specifies the webhook when it is configured' do
expect(MicrosoftTeams::Notifier).to receive(:new).with(webhook_url).and_return(double(:microsoft_teams_service).as_null_object)
chat_service.execute(push_sample_data)
end
end
context 'with issue events' do
let(:opts) { { title: 'Awesome issue', description: 'please fix' } }
let(:issues_sample_data) do
service = Issues::CreateService.new(project, user, opts)
issue = service.execute
service.hook_data(issue, 'open')
end
it "calls Microsoft Teams API" do
chat_service.execute(issues_sample_data)
expect(WebMock).to have_requested(:post, webhook_url).once
end
end
context 'with merge events' do
let(:opts) do
{
title: 'Awesome merge_request',
description: 'please fix',
source_branch: 'feature',
target_branch: 'master'
}
end
let(:merge_sample_data) do
service = MergeRequests::CreateService.new(project, user, opts)
merge_request = service.execute
service.hook_data(merge_request, 'open')
end
it "calls Microsoft Teams API" do
chat_service.execute(merge_sample_data)
expect(WebMock).to have_requested(:post, webhook_url).once
end
end
context 'with wiki page events' do
let(:opts) do
{
title: "Awesome wiki_page",
content: "Some text describing some thing or another",
format: "md",
message: "user created page: Awesome wiki_page"
}
end
let(:wiki_page_sample_data) do
service = WikiPages::CreateService.new(project, user, opts)
wiki_page = service.execute
service.hook_data(wiki_page, 'create')
end
it "calls Microsoft Teams API" do
chat_service.execute(wiki_page_sample_data)
expect(WebMock).to have_requested(:post, webhook_url).once
end
end
end
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
)
WebMock.stub_request(:post, webhook_url)
end
context 'when commit comment event executed' do
let(:commit_note) do
create(:note_on_commit, author: user,
project: project,
commit_id: project.repository.commit.id,
note: 'a comment on a commit')
end
it "calls Microsoft Teams 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
end
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")
end
it "calls Microsoft Teams 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
end
end
context 'when issue comment event executed' do
let(:issue_note) do
create(:note_on_issue, project: project, note: "issue note")
end
it "calls Microsoft Teams API for issue comment events" do
data = Gitlab::DataBuilder::Note.build(issue_note, user)
chat_service.execute(data)
expect(WebMock).to have_requested(:post, webhook_url).once
end
end
context 'when snippet comment event executed' do
let(:snippet_note) do
create(:note_on_project_snippet, project: project,
note: "snippet note")
end
it "calls Microsoft Teams 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
end
end
end
describe 'Pipeline events' do
let(:user) { create(:user) }
let(:project) { create(:project, :repository) }
let(:pipeline) do
create(:ci_pipeline,
project: project, status: status,
sha: project.commit.sha, ref: project.default_branch)
end
before do
allow(chat_service).to receive_messages(
project: project,
service_hook: true,
webhook: webhook_url
)
end
shared_examples 'call Microsoft Teams API' do
before do
WebMock.stub_request(:post, webhook_url)
end
it 'calls Microsoft Teams API for pipeline events' do
data = Gitlab::DataBuilder::Pipeline.build(pipeline)
chat_service.execute(data)
expect(WebMock).to have_requested(:post, webhook_url).once
end
end
context 'with failed pipeline' do
let(:status) { 'failed' }
it_behaves_like 'call Microsoft Teams API'
end
context 'with succeeded pipeline' do
let(:status) { 'success' }
context 'with default to notify_only_broken_pipelines' do
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 setting notify_only_broken_pipelines to false' do
before do
chat_service.notify_only_broken_pipelines = false
end
it_behaves_like 'call Microsoft Teams API'
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
before do
chat_service.notify_only_default_branch = true
end
it 'does not call the 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
end
end
end
......@@ -22,6 +22,7 @@ describe Project, models: true do
it { is_expected.to have_many(:protected_branches).dependent(:destroy) }
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(:microsoft_teams_service).dependent(:destroy) }
it { is_expected.to have_one(:mattermost_service).dependent(:destroy) }
it { is_expected.to have_one(:pushover_service).dependent(:destroy) }
it { is_expected.to have_one(:asana_service).dependent(:destroy) }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment