summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorZ.J. van de Weg <git@zjvandeweg.nl>2017-01-19 09:22:09 +0100
committerZ.J. van de Weg <git@zjvandeweg.nl>2017-01-24 12:27:24 +0100
commit52ca0d2c9ecb7e7d4d0130f19bf0fb7b772a357d (patch)
tree3d03d85486ea0ae3856d7eb71a5f66432b355084
parente9d163865bc6f987e7fa277536c6bc3950fbf1e0 (diff)
downloadgitlab-ce-52ca0d2c9ecb7e7d4d0130f19bf0fb7b772a357d.tar.gz
Incorporate feedback
-rw-r--r--changelogs/unreleased/zj-format-chat-messages.yml4
-rw-r--r--lib/gitlab/chat_commands/issue_create.rb2
-rw-r--r--lib/gitlab/chat_commands/presenters/access.rb36
-rw-r--r--lib/gitlab/chat_commands/presenters/base.rb112
-rw-r--r--lib/gitlab/chat_commands/presenters/deploy.rb39
-rw-r--r--lib/gitlab/chat_commands/presenters/help.rb31
-rw-r--r--lib/gitlab/chat_commands/presenters/issuable.rb66
-rw-r--r--lib/gitlab/chat_commands/presenters/list_issues.rb59
-rw-r--r--lib/gitlab/chat_commands/presenters/new_issue.rb42
-rw-r--r--lib/gitlab/chat_commands/presenters/show_issue.rb72
-rw-r--r--spec/lib/gitlab/chat_commands/issue_search_spec.rb2
-rw-r--r--spec/lib/gitlab/chat_commands/issue_show_spec.rb4
-rw-r--r--spec/lib/gitlab/chat_commands/presenters/deploy_spec.rb2
-rw-r--r--spec/lib/gitlab/chat_commands/presenters/list_issues_spec.rb5
-rw-r--r--spec/lib/gitlab/chat_commands/presenters/show_issue_spec.rb4
-rw-r--r--spec/lib/mattermost/client_spec.rb24
-rw-r--r--spec/lib/mattermost/command_spec.rb61
-rw-r--r--spec/lib/mattermost/session_spec.rb123
-rw-r--r--spec/lib/mattermost/team_spec.rb66
19 files changed, 565 insertions, 189 deletions
diff --git a/changelogs/unreleased/zj-format-chat-messages.yml b/changelogs/unreleased/zj-format-chat-messages.yml
new file mode 100644
index 00000000000..2494884f5c9
--- /dev/null
+++ b/changelogs/unreleased/zj-format-chat-messages.yml
@@ -0,0 +1,4 @@
+---
+title: Reformat messages ChatOps
+merge_request: 8528
+author:
diff --git a/lib/gitlab/chat_commands/issue_create.rb b/lib/gitlab/chat_commands/issue_create.rb
index a06f13b0f72..3f3d7de8b2e 100644
--- a/lib/gitlab/chat_commands/issue_create.rb
+++ b/lib/gitlab/chat_commands/issue_create.rb
@@ -35,7 +35,7 @@ module Gitlab
end
def presenter(issue)
- Gitlab::ChatCommands::Presenters::ShowIssue.new(issue)
+ Gitlab::ChatCommands::Presenters::NewIssue.new(issue)
end
end
end
diff --git a/lib/gitlab/chat_commands/presenters/access.rb b/lib/gitlab/chat_commands/presenters/access.rb
index 6d18d745608..b66ef48d6a8 100644
--- a/lib/gitlab/chat_commands/presenters/access.rb
+++ b/lib/gitlab/chat_commands/presenters/access.rb
@@ -1,22 +1,26 @@
-module Gitlab::ChatCommands::Presenters
- class Access < Gitlab::ChatCommands::Presenters::Base
- def access_denied
- ephemeral_response(text: "Whoops! This action is not allowed. This incident will be [reported](https://xkcd.com/838/).")
- end
-
- def not_found
- ephemeral_response(text: "404 not found! GitLab couldn't find what you were looking for! :boom:")
- end
+module Gitlab
+ module ChatCommands
+ module Presenters
+ class Access < Presenters::Base
+ def access_denied
+ ephemeral_response(text: "Whoops! This action is not allowed. This incident will be [reported](https://xkcd.com/838/).")
+ end
- def authorize
- message =
- if @resource
- ":wave: Hi there! Before I do anything for you, please [connect your GitLab account](#{@resource})."
- else
- ":sweat_smile: Couldn't identify you, nor can I autorize you!"
+ def not_found
+ ephemeral_response(text: "404 not found! GitLab couldn't find what you were looking for! :boom:")
end
- ephemeral_response(text: message)
+ def authorize
+ message =
+ if @resource
+ ":wave: Hi there! Before I do anything for you, please [connect your GitLab account](#{@resource})."
+ else
+ ":sweat_smile: Couldn't identify you, nor can I autorize you!"
+ end
+
+ ephemeral_response(text: message)
+ end
+ end
end
end
end
diff --git a/lib/gitlab/chat_commands/presenters/base.rb b/lib/gitlab/chat_commands/presenters/base.rb
index 0897025d85f..2700a5a2ad5 100644
--- a/lib/gitlab/chat_commands/presenters/base.rb
+++ b/lib/gitlab/chat_commands/presenters/base.rb
@@ -1,73 +1,77 @@
-module Gitlab::ChatCommands::Presenters
- class Base
- include Gitlab::Routing.url_helpers
+module Gitlab
+ module ChatCommands
+ module Presenters
+ class Base
+ include Gitlab::Routing.url_helpers
+
+ def initialize(resource = nil)
+ @resource = resource
+ end
- def initialize(resource = nil)
- @resource = resource
- end
+ def display_errors
+ message = header_with_list("The action was not successful, because:", @resource.errors.full_messages)
- def display_errors
- message = header_with_list("The action was not successful, because:", @resource.errors.full_messages)
+ ephemeral_response(text: message)
+ end
- ephemeral_response(text: message)
- end
+ private
- private
+ def header_with_list(header, items)
+ message = [header]
- def header_with_list(header, items)
- message = [header]
+ items.each do |item|
+ message << "- #{item}"
+ end
- items.each do |item|
- message << "- #{item}"
- end
+ message.join("\n")
+ end
- message.join("\n")
- end
+ def ephemeral_response(message)
+ response = {
+ response_type: :ephemeral,
+ status: 200
+ }.merge(message)
- def ephemeral_response(message)
- response = {
- response_type: :ephemeral,
- status: 200
- }.merge(message)
+ format_response(response)
+ end
- format_response(response)
- end
+ def in_channel_response(message)
+ response = {
+ response_type: :in_channel,
+ status: 200
+ }.merge(message)
- def in_channel_response(message)
- response = {
- response_type: :in_channel,
- status: 200
- }.merge(message)
+ format_response(response)
+ end
- format_response(response)
- end
+ def format_response(response)
+ response[:text] = format(response[:text]) if response.has_key?(:text)
- def format_response(response)
- response[:text] = format(response[:text]) if response.has_key?(:text)
+ if response.has_key?(:attachments)
+ response[:attachments].each do |attachment|
+ attachment[:pretext] = format(attachment[:pretext]) if attachment[:pretext]
+ attachment[:text] = format(attachment[:text]) if attachment[:text]
+ end
+ end
- if response.has_key?(:attachments)
- response[:attachments].each do |attachment|
- attachment[:pretext] = format(attachment[:pretext]) if attachment[:pretext]
- attachment[:text] = format(attachment[:text]) if attachment[:text]
+ response
end
- end
-
- response
- end
- # Convert Markdown to slacks format
- def format(string)
- Slack::Notifier::LinkFormatter.format(string)
- end
+ # Convert Markdown to slacks format
+ def format(string)
+ Slack::Notifier::LinkFormatter.format(string)
+ end
- def resource_url
- url_for(
- [
- @resource.project.namespace.becomes(Namespace),
- @resource.project,
- @resource
- ]
- )
+ def resource_url
+ url_for(
+ [
+ @resource.project.namespace.becomes(Namespace),
+ @resource.project,
+ @resource
+ ]
+ )
+ end
+ end
end
end
end
diff --git a/lib/gitlab/chat_commands/presenters/deploy.rb b/lib/gitlab/chat_commands/presenters/deploy.rb
index 4f6333812ff..b1cfaac15af 100644
--- a/lib/gitlab/chat_commands/presenters/deploy.rb
+++ b/lib/gitlab/chat_commands/presenters/deploy.rb
@@ -1,24 +1,29 @@
-module Gitlab::ChatCommands::Presenters
- class Deploy < Gitlab::ChatCommands::Presenters::Base
- def present(from, to)
- message = "Deployment started from #{from} to #{to}. [Follow its progress](#{resource_url})."
- in_channel_response(text: message)
- end
+module Gitlab
+ module ChatCommands
+ module Presenters
+ class Deploy < Presenters::Base
+ def present(from, to)
+ message = "Deployment started from #{from} to #{to}. [Follow its progress](#{resource_url})."
- def no_actions
- ephemeral_response(text: "No action found to be executed")
- end
+ in_channel_response(text: message)
+ end
- def too_many_actions
- ephemeral_response(text: "Too many actions defined")
- end
+ def no_actions
+ ephemeral_response(text: "No action found to be executed")
+ end
+
+ def too_many_actions
+ ephemeral_response(text: "Too many actions defined")
+ end
- private
+ private
- def resource_url
- polymorphic_url(
- [ @resource.project.namespace.becomes(Namespace), @resource.project, @resource]
- )
+ def resource_url
+ polymorphic_url(
+ [ @resource.project.namespace.becomes(Namespace), @resource.project, @resource]
+ )
+ end
+ end
end
end
end
diff --git a/lib/gitlab/chat_commands/presenters/help.rb b/lib/gitlab/chat_commands/presenters/help.rb
index 133b707231f..c7a67467b7e 100644
--- a/lib/gitlab/chat_commands/presenters/help.rb
+++ b/lib/gitlab/chat_commands/presenters/help.rb
@@ -1,20 +1,25 @@
-module Gitlab::ChatCommands::Presenters
- class Help < Gitlab::ChatCommands::Presenters::Base
- def present(trigger)
- message =
- if @resource.none?
- "No commands available :thinking_face:"
- else
- header_with_list("Available commands", full_commands(trigger))
+module Gitlab
+ module ChatCommands
+ module Presenters
+ class Help < Presenters::Base
+ def present(trigger)
+ ephemeral_response(text: help_message(trigger))
end
- ephemeral_response(text: message)
- end
+ private
- private
+ def help_message(trigger)
+ if @resource.none?
+ "No commands available :thinking_face:"
+ else
+ header_with_list("Available commands", full_commands(trigger))
+ end
+ end
- def full_commands(trigger)
- @resource.map { |command| "#{trigger} #{command.help_message}" }
+ def full_commands(trigger)
+ @resource.map { |command| "#{trigger} #{command.help_message}" }
+ end
+ end
end
end
end
diff --git a/lib/gitlab/chat_commands/presenters/issuable.rb b/lib/gitlab/chat_commands/presenters/issuable.rb
index 9623387f188..2cb6b1525fc 100644
--- a/lib/gitlab/chat_commands/presenters/issuable.rb
+++ b/lib/gitlab/chat_commands/presenters/issuable.rb
@@ -1,33 +1,45 @@
-module Gitlab::ChatCommands::Presenters
- class Issuable < Gitlab::ChatCommands::Presenters::Base
- private
+module Gitlab
+ module ChatCommands
+ module Presenters
+ class Issuable < Presenters::Base
+ private
- def project
- @resource.project
- end
+ def color(issuable)
+ issuable.open? ? '#38ae67' : '#d22852'
+ end
- def author
- @resource.author
- end
+ def status_text(issuable)
+ issuable.open? ? 'Open' : 'Closed'
+ end
+
+ def project
+ @resource.project
+ end
+
+ def author
+ @resource.author
+ end
- def fields
- [
- {
- title: "Assignee",
- value: @resource.assignee ? @resource.assignee.name : "_None_",
- short: true
- },
- {
- title: "Milestone",
- value: @resource.milestone ? @resource.milestone.title : "_None_",
- short: true
- },
- {
- title: "Labels",
- value: @resource.labels.any? ? @resource.label_names : "_None_",
- short: true
- }
- ]
+ def fields
+ [
+ {
+ title: "Assignee",
+ value: @resource.assignee ? @resource.assignee.name : "_None_",
+ short: true
+ },
+ {
+ title: "Milestone",
+ value: @resource.milestone ? @resource.milestone.title : "_None_",
+ short: true
+ },
+ {
+ title: "Labels",
+ value: @resource.labels.any? ? @resource.label_names : "_None_",
+ short: true
+ }
+ ]
+ end
+ end
end
end
end
diff --git a/lib/gitlab/chat_commands/presenters/list_issues.rb b/lib/gitlab/chat_commands/presenters/list_issues.rb
index 5a7b3fca5c2..2458b9356b7 100644
--- a/lib/gitlab/chat_commands/presenters/list_issues.rb
+++ b/lib/gitlab/chat_commands/presenters/list_issues.rb
@@ -1,32 +1,43 @@
-module Gitlab::ChatCommands::Presenters
- class ListIssues < Gitlab::ChatCommands::Presenters::Base
- def present
- ephemeral_response(text: "Here are the issues I found:", attachments: attachments)
- end
+module Gitlab
+ module ChatCommands
+ module Presenters
+ class ListIssues < Presenters::Issuable
+ def present
+ text = if @resource.count >= 5
+ "Here are the first 5 issues I found:"
+ else
+ "Here are the #{@resource.count} issues I found:"
+ end
- private
+ ephemeral_response(text: text, attachments: attachments)
+ end
- def attachments
- @resource.map do |issue|
- state = issue.open? ? "Open" : "Closed"
+ private
- {
- fallback: "Issue #{issue.to_reference}: #{issue.title}",
- color: "#d22852",
- text: "[#{issue.to_reference}](#{url_for([namespace, project, issue])}) · #{issue.title} (#{state})",
- mrkdwn_in: [
- "text"
- ]
- }
- end
- end
+ def attachments
+ @resource.map do |issue|
+ url = "[#{issue.to_reference}](#{url_for([namespace, project, issue])})"
- def project
- @project ||= @resource.first.project
- end
+ {
+ color: color(issue),
+ fallback: "#{issue.to_reference} #{issue.title}",
+ text: "#{url} · #{issue.title} (#{status_text(issue)})",
- def namespace
- @namespace ||= project.namespace.becomes(Namespace)
+ mrkdwn_in: [
+ "text"
+ ]
+ }
+ end
+ end
+
+ def project
+ @project ||= @resource.first.project
+ end
+
+ def namespace
+ @namespace ||= project.namespace.becomes(Namespace)
+ end
+ end
end
end
end
diff --git a/lib/gitlab/chat_commands/presenters/new_issue.rb b/lib/gitlab/chat_commands/presenters/new_issue.rb
new file mode 100644
index 00000000000..c7c6febb56e
--- /dev/null
+++ b/lib/gitlab/chat_commands/presenters/new_issue.rb
@@ -0,0 +1,42 @@
+module Gitlab
+ module ChatCommands
+ module Presenters
+ class NewIssue < Presenters::Issuable
+ def present
+ in_channel_response(show_issue)
+ end
+
+ private
+
+ def show_issue
+ {
+ attachments: [
+ {
+ title: "#{@resource.title} · #{@resource.to_reference}",
+ title_link: resource_url,
+ author_name: author.name,
+ author_icon: author.avatar_url,
+ fallback: "New issue #{@resource.to_reference}: #{@resource.title}",
+ pretext: pretext,
+ color: color(@resource),
+ fields: fields,
+ mrkdwn_in: [
+ :title,
+ :text
+ ]
+ }
+ ]
+ }
+ end
+
+ def pretext
+ "I opened an issue on behalf on #{author_profile_link}: *#{@resource.to_reference}* from #{project.name_with_namespace}"
+ end
+
+ def author_profile_link
+ "[#{author.to_reference}](#{url_for(author)})"
+ end
+ end
+ end
+ end
+end
diff --git a/lib/gitlab/chat_commands/presenters/show_issue.rb b/lib/gitlab/chat_commands/presenters/show_issue.rb
index 2a89c30b972..e5644a4ad7e 100644
--- a/lib/gitlab/chat_commands/presenters/show_issue.rb
+++ b/lib/gitlab/chat_commands/presenters/show_issue.rb
@@ -1,38 +1,54 @@
-module Gitlab::ChatCommands::Presenters
- class ShowIssue < Gitlab::ChatCommands::Presenters::Issuable
- def present
- in_channel_response(show_issue)
- end
+module Gitlab
+ module ChatCommands
+ module Presenters
+ class ShowIssue < Presenters::Issuable
+ def present
+ in_channel_response(show_issue)
+ end
- private
+ private
- def show_issue
- {
- attachments: [
+ def show_issue
{
- title: @resource.title,
- title_link: resource_url,
- author_name: author.name,
- author_icon: author.avatar_url,
- fallback: "#{@resource.to_reference}: #{@resource.title}",
- text: text,
- fields: fields,
- mrkdwn_in: [
- :title,
- :text
+ attachments: [
+ {
+ title: "#{@resource.title} · #{@resource.to_reference}",
+ title_link: resource_url,
+ author_name: author.name,
+ author_icon: author.avatar_url,
+ fallback: "New issue #{@resource.to_reference}: #{@resource.title}",
+ pretext: pretext,
+ text: text,
+ color: color(@resource),
+ fields: fields,
+ mrkdwn_in: [
+ :pretext,
+ :text
+ ]
+ }
]
}
- ]
- }
- end
+ end
+
+ def text
+ message = "**#{status_text(@resource)}**"
+
+ if @resource.upvotes.zero? && @resource.downvotes.zero? && @resource.user_notes_count.zero?
+ return message
+ end
+
+ message << " · "
+ message << ":+1: #{@resource.upvotes} " unless @resource.upvotes.zero?
+ message << ":-1: #{@resource.downvotes} " unless @resource.downvotes.zero?
+ message << ":speech_balloon: #{@resource.user_notes_count}" unless @resource.user_notes_count.zero?
- def text
- message = ""
- message << ":+1: #{@resource.upvotes} " unless @resource.upvotes.zero?
- message << ":-1: #{@resource.downvotes} " unless @resource.downvotes.zero?
- message << ":speech_balloon: #{@resource.user_notes_count}" unless @resource.user_notes_count.zero?
+ message
+ end
- message
+ def pretext
+ "Issue *#{@resource.to_reference} from #{project.name_with_namespace}"
+ end
+ end
end
end
end
diff --git a/spec/lib/gitlab/chat_commands/issue_search_spec.rb b/spec/lib/gitlab/chat_commands/issue_search_spec.rb
index 04d10ad52a1..551ccb79a58 100644
--- a/spec/lib/gitlab/chat_commands/issue_search_spec.rb
+++ b/spec/lib/gitlab/chat_commands/issue_search_spec.rb
@@ -26,7 +26,7 @@ describe Gitlab::ChatCommands::IssueSearch, service: true do
it 'returns all results' do
expect(subject).to have_key(:attachments)
- expect(subject[:text]).to match("Here are the issues I found:")
+ expect(subject[:text]).to eq("Here are the 2 issues I found:")
end
end
diff --git a/spec/lib/gitlab/chat_commands/issue_show_spec.rb b/spec/lib/gitlab/chat_commands/issue_show_spec.rb
index 89932c395c6..1f20d0a44ce 100644
--- a/spec/lib/gitlab/chat_commands/issue_show_spec.rb
+++ b/spec/lib/gitlab/chat_commands/issue_show_spec.rb
@@ -20,7 +20,7 @@ describe Gitlab::ChatCommands::IssueShow, service: true do
it 'returns the issue' do
expect(subject[:response_type]).to be(:in_channel)
- expect(title).to eq(issue.title)
+ expect(title).to start_with(issue.title)
end
context 'when its reference is given' do
@@ -28,7 +28,7 @@ describe Gitlab::ChatCommands::IssueShow, service: true do
it 'shows the issue' do
expect(subject[:response_type]).to be(:in_channel)
- expect(title).to eq(issue.title)
+ expect(title).to start_with(issue.title)
end
end
end
diff --git a/spec/lib/gitlab/chat_commands/presenters/deploy_spec.rb b/spec/lib/gitlab/chat_commands/presenters/deploy_spec.rb
index 1c48c727e30..dc2dd300072 100644
--- a/spec/lib/gitlab/chat_commands/presenters/deploy_spec.rb
+++ b/spec/lib/gitlab/chat_commands/presenters/deploy_spec.rb
@@ -32,7 +32,7 @@ describe Gitlab::ChatCommands::Presenters::Deploy do
end
describe '#too_many_actions' do
- subject { described_class.new(nil).too_many_actions }
+ subject { described_class.new([]).too_many_actions }
it { is_expected.to have_key(:text) }
it { is_expected.to have_key(:response_type) }
diff --git a/spec/lib/gitlab/chat_commands/presenters/list_issues_spec.rb b/spec/lib/gitlab/chat_commands/presenters/list_issues_spec.rb
index 1852395fc97..13a1f70fe78 100644
--- a/spec/lib/gitlab/chat_commands/presenters/list_issues_spec.rb
+++ b/spec/lib/gitlab/chat_commands/presenters/list_issues_spec.rb
@@ -3,13 +3,12 @@ require 'spec_helper'
describe Gitlab::ChatCommands::Presenters::ListIssues do
let(:project) { create(:empty_project) }
let(:message) { subject[:text] }
- let(:issue) { project.issues.first }
before { create_list(:issue, 2, project: project) }
subject { described_class.new(project.issues).present }
- it do
+ it 'formats the message correct' do
is_expected.to have_key(:text)
is_expected.to have_key(:status)
is_expected.to have_key(:response_type)
@@ -19,6 +18,6 @@ describe Gitlab::ChatCommands::Presenters::ListIssues do
it 'shows a list of results' do
expect(subject[:response_type]).to be(:ephemeral)
- expect(message).to start_with("Here are the issues I found")
+ expect(message).to start_with("Here are the 2 issues I found")
end
end
diff --git a/spec/lib/gitlab/chat_commands/presenters/show_issue_spec.rb b/spec/lib/gitlab/chat_commands/presenters/show_issue_spec.rb
index 13a318fe680..ca4062e692a 100644
--- a/spec/lib/gitlab/chat_commands/presenters/show_issue_spec.rb
+++ b/spec/lib/gitlab/chat_commands/presenters/show_issue_spec.rb
@@ -12,7 +12,7 @@ describe Gitlab::ChatCommands::Presenters::ShowIssue do
it 'shows the issue' do
expect(subject[:response_type]).to be(:in_channel)
expect(subject).to have_key(:attachments)
- expect(attachment[:title]).to eq(issue.title)
+ expect(attachment[:title]).to start_with(issue.title)
end
context 'with upvotes' do
@@ -21,7 +21,7 @@ describe Gitlab::ChatCommands::Presenters::ShowIssue do
end
it 'shows the upvote count' do
- expect(attachment[:text]).to start_with(":+1: 1")
+ expect(attachment[:text]).to start_with("**Open** · :+1: 1")
end
end
end
diff --git a/spec/lib/mattermost/client_spec.rb b/spec/lib/mattermost/client_spec.rb
new file mode 100644
index 00000000000..dc11a414717
--- /dev/null
+++ b/spec/lib/mattermost/client_spec.rb
@@ -0,0 +1,24 @@
+require 'spec_helper'
+
+describe Mattermost::Client do
+ let(:user) { build(:user) }
+
+ subject { described_class.new(user) }
+
+ context 'JSON parse error' do
+ before do
+ Struct.new("Request", :body, :success?)
+ end
+
+ it 'yields an error on malformed JSON' do
+ bad_json = Struct::Request.new("I'm not json", true)
+ expect { subject.send(:json_response, bad_json) }.to raise_error(Mattermost::ClientError)
+ end
+
+ it 'shows a client error if the request was unsuccessful' do
+ bad_request = Struct::Request.new("true", false)
+
+ expect { subject.send(:json_response, bad_request) }.to raise_error(Mattermost::ClientError)
+ end
+ end
+end
diff --git a/spec/lib/mattermost/command_spec.rb b/spec/lib/mattermost/command_spec.rb
new file mode 100644
index 00000000000..5ccf1100898
--- /dev/null
+++ b/spec/lib/mattermost/command_spec.rb
@@ -0,0 +1,61 @@
+require 'spec_helper'
+
+describe Mattermost::Command do
+ let(:params) { { 'token' => 'token', team_id: 'abc' } }
+
+ before do
+ Mattermost::Session.base_uri('http://mattermost.example.com')
+
+ allow_any_instance_of(Mattermost::Client).to receive(:with_session).
+ and_yield(Mattermost::Session.new(nil))
+ end
+
+ describe '#create' do
+ let(:params) do
+ { team_id: 'abc',
+ trigger: 'gitlab'
+ }
+ end
+
+ subject { described_class.new(nil).create(params) }
+
+ context 'for valid trigger word' do
+ before do
+ stub_request(:post, 'http://mattermost.example.com/api/v3/teams/abc/commands/create').
+ with(body: {
+ team_id: 'abc',
+ trigger: 'gitlab' }.to_json).
+ to_return(
+ status: 200,
+ headers: { 'Content-Type' => 'application/json' },
+ body: { token: 'token' }.to_json
+ )
+ end
+
+ it 'returns a token' do
+ is_expected.to eq('token')
+ end
+ end
+
+ context 'for error message' do
+ before do
+ stub_request(:post, 'http://mattermost.example.com/api/v3/teams/abc/commands/create').
+ to_return(
+ status: 500,
+ headers: { 'Content-Type' => 'application/json' },
+ body: {
+ id: 'api.command.duplicate_trigger.app_error',
+ message: 'This trigger word is already in use. Please choose another word.',
+ detailed_error: '',
+ request_id: 'obc374man7bx5r3dbc1q5qhf3r',
+ status_code: 500
+ }.to_json
+ )
+ end
+
+ it 'raises an error with message' do
+ expect { subject }.to raise_error(Mattermost::Error, 'This trigger word is already in use. Please choose another word.')
+ end
+ end
+ end
+end
diff --git a/spec/lib/mattermost/session_spec.rb b/spec/lib/mattermost/session_spec.rb
new file mode 100644
index 00000000000..74d12e37181
--- /dev/null
+++ b/spec/lib/mattermost/session_spec.rb
@@ -0,0 +1,123 @@
+require 'spec_helper'
+
+describe Mattermost::Session, type: :request do
+ let(:user) { create(:user) }
+
+ let(:gitlab_url) { "http://gitlab.com" }
+ let(:mattermost_url) { "http://mattermost.com" }
+
+ subject { described_class.new(user) }
+
+ # Needed for doorkeeper to function
+ it { is_expected.to respond_to(:current_resource_owner) }
+ it { is_expected.to respond_to(:request) }
+ it { is_expected.to respond_to(:authorization) }
+ it { is_expected.to respond_to(:strategy) }
+
+ before do
+ described_class.base_uri(mattermost_url)
+ end
+
+ describe '#with session' do
+ let(:location) { 'http://location.tld' }
+ let!(:stub) do
+ WebMock.stub_request(:get, "#{mattermost_url}/api/v3/oauth/gitlab/login").
+ to_return(headers: { 'location' => location }, status: 307)
+ end
+
+ context 'without oauth uri' do
+ it 'makes a request to the oauth uri' do
+ expect { subject.with_session }.to raise_error(Mattermost::NoSessionError)
+ end
+ end
+
+ context 'with oauth_uri' do
+ let!(:doorkeeper) do
+ Doorkeeper::Application.create(
+ name: "GitLab Mattermost",
+ redirect_uri: "#{mattermost_url}/signup/gitlab/complete\n#{mattermost_url}/login/gitlab/complete",
+ scopes: "")
+ end
+
+ context 'without token_uri' do
+ it 'can not create a session' do
+ expect do
+ subject.with_session
+ end.to raise_error(Mattermost::NoSessionError)
+ end
+ end
+
+ context 'with token_uri' do
+ let(:state) { "state" }
+ let(:params) do
+ { response_type: "code",
+ client_id: doorkeeper.uid,
+ redirect_uri: "#{mattermost_url}/signup/gitlab/complete",
+ state: state }
+ end
+ let(:location) do
+ "#{gitlab_url}/oauth/authorize?#{URI.encode_www_form(params)}"
+ end
+
+ before do
+ WebMock.stub_request(:get, "#{mattermost_url}/signup/gitlab/complete").
+ with(query: hash_including({ 'state' => state })).
+ to_return do |request|
+ post "/oauth/token",
+ client_id: doorkeeper.uid,
+ client_secret: doorkeeper.secret,
+ redirect_uri: params[:redirect_uri],
+ grant_type: 'authorization_code',
+ code: request.uri.query_values['code']
+
+ if response.status == 200
+ { headers: { 'token' => 'thisworksnow' }, status: 202 }
+ end
+ end
+
+ WebMock.stub_request(:post, "#{mattermost_url}/api/v3/users/logout").
+ to_return(headers: { Authorization: 'token thisworksnow' }, status: 200)
+ end
+
+ it 'can setup a session' do
+ subject.with_session do |session|
+ end
+
+ expect(subject.token).not_to be_nil
+ end
+
+ it 'returns the value of the block' do
+ result = subject.with_session do |session|
+ "value"
+ end
+
+ expect(result).to eq("value")
+ end
+ end
+ end
+
+ context 'with lease' do
+ before do
+ allow(subject).to receive(:lease_try_obtain).and_return('aldkfjsldfk')
+ end
+
+ it 'tries to obtain a lease' do
+ expect(subject).to receive(:lease_try_obtain)
+ expect(Gitlab::ExclusiveLease).to receive(:cancel)
+
+ # Cannot setup a session, but we should still cancel the lease
+ expect { subject.with_session }.to raise_error(Mattermost::NoSessionError)
+ end
+ end
+
+ context 'without lease' do
+ before do
+ allow(subject).to receive(:lease_try_obtain).and_return(nil)
+ end
+
+ it 'returns a NoSessionError error' do
+ expect { subject.with_session }.to raise_error(Mattermost::NoSessionError)
+ end
+ end
+ end
+end
diff --git a/spec/lib/mattermost/team_spec.rb b/spec/lib/mattermost/team_spec.rb
new file mode 100644
index 00000000000..2d14be6bcc2
--- /dev/null
+++ b/spec/lib/mattermost/team_spec.rb
@@ -0,0 +1,66 @@
+require 'spec_helper'
+
+describe Mattermost::Team do
+ before do
+ Mattermost::Session.base_uri('http://mattermost.example.com')
+
+ allow_any_instance_of(Mattermost::Client).to receive(:with_session).
+ and_yield(Mattermost::Session.new(nil))
+ end
+
+ describe '#all' do
+ subject { described_class.new(nil).all }
+
+ context 'for valid request' do
+ let(:response) do
+ [{
+ "id" => "xiyro8huptfhdndadpz8r3wnbo",
+ "create_at" => 1482174222155,
+ "update_at" => 1482174222155,
+ "delete_at" => 0,
+ "display_name" => "chatops",
+ "name" => "chatops",
+ "email" => "admin@example.com",
+ "type" => "O",
+ "company_name" => "",
+ "allowed_domains" => "",
+ "invite_id" => "o4utakb9jtb7imctdfzbf9r5ro",
+ "allow_open_invite" => false }]
+ end
+
+ before do
+ stub_request(:get, 'http://mattermost.example.com/api/v3/teams/all').
+ to_return(
+ status: 200,
+ headers: { 'Content-Type' => 'application/json' },
+ body: response.to_json
+ )
+ end
+
+ it 'returns a token' do
+ is_expected.to eq(response)
+ end
+ end
+
+ context 'for error message' do
+ before do
+ stub_request(:get, 'http://mattermost.example.com/api/v3/teams/all').
+ to_return(
+ status: 500,
+ headers: { 'Content-Type' => 'application/json' },
+ body: {
+ id: 'api.team.list.app_error',
+ message: 'Cannot list teams.',
+ detailed_error: '',
+ request_id: 'obc374man7bx5r3dbc1q5qhf3r',
+ status_code: 500
+ }.to_json
+ )
+ end
+
+ it 'raises an error with message' do
+ expect { subject }.to raise_error(Mattermost::Error, 'Cannot list teams.')
+ end
+ end
+ end
+end