From 52ca0d2c9ecb7e7d4d0130f19bf0fb7b772a357d Mon Sep 17 00:00:00 2001 From: "Z.J. van de Weg" Date: Thu, 19 Jan 2017 09:22:09 +0100 Subject: Incorporate feedback --- changelogs/unreleased/zj-format-chat-messages.yml | 4 + lib/gitlab/chat_commands/issue_create.rb | 2 +- lib/gitlab/chat_commands/presenters/access.rb | 36 +++--- lib/gitlab/chat_commands/presenters/base.rb | 112 ++++++++++--------- lib/gitlab/chat_commands/presenters/deploy.rb | 39 ++++--- lib/gitlab/chat_commands/presenters/help.rb | 31 +++--- lib/gitlab/chat_commands/presenters/issuable.rb | 66 ++++++----- lib/gitlab/chat_commands/presenters/list_issues.rb | 59 ++++++---- lib/gitlab/chat_commands/presenters/new_issue.rb | 42 +++++++ lib/gitlab/chat_commands/presenters/show_issue.rb | 72 +++++++----- spec/lib/gitlab/chat_commands/issue_search_spec.rb | 2 +- spec/lib/gitlab/chat_commands/issue_show_spec.rb | 4 +- .../gitlab/chat_commands/presenters/deploy_spec.rb | 2 +- .../chat_commands/presenters/list_issues_spec.rb | 5 +- .../chat_commands/presenters/show_issue_spec.rb | 4 +- spec/lib/mattermost/client_spec.rb | 24 ++++ spec/lib/mattermost/command_spec.rb | 61 ++++++++++ spec/lib/mattermost/session_spec.rb | 123 +++++++++++++++++++++ spec/lib/mattermost/team_spec.rb | 66 +++++++++++ 19 files changed, 565 insertions(+), 189 deletions(-) create mode 100644 changelogs/unreleased/zj-format-chat-messages.yml create mode 100644 lib/gitlab/chat_commands/presenters/new_issue.rb create mode 100644 spec/lib/mattermost/client_spec.rb create mode 100644 spec/lib/mattermost/command_spec.rb create mode 100644 spec/lib/mattermost/session_spec.rb create mode 100644 spec/lib/mattermost/team_spec.rb 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 -- cgit v1.2.1