diff options
author | Z.J. van de Weg <git@zjvandeweg.nl> | 2016-11-16 20:28:38 +0300 |
---|---|---|
committer | Z.J. van de Weg <git@zjvandeweg.nl> | 2016-11-17 23:34:24 +0300 |
commit | 1b4fdb9893af28606b7594ee656438c7ef21e9d8 (patch) | |
tree | 420a687514aedcc68c5a2dbe649123e3a52fdb02 | |
parent | 8c8bc07d32f1103bb7996b499ead6ad6eb5bd337 (diff) |
Rename from service, and move to lib/gitlab
23 files changed, 233 insertions, 177 deletions
diff --git a/app/services/mattermost/commands/base_service.rb b/app/services/mattermost/commands/base_service.rb deleted file mode 100644 index c6bfd7c9ab4..00000000000 --- a/app/services/mattermost/commands/base_service.rb +++ /dev/null @@ -1,47 +0,0 @@ -module Mattermost - module Commands - class BaseService < ::BaseService - QUERY_LIMIT = 5 - - def execute - raise NotImplementedError - end - - def available? - raise NotImplementedError - end - - def collection - raise NotImplementedError - end - - private - - def present(resource) - Mattermost::Presenter.present(resource) - end - - def find_by_iid - resource = collection.find_by(iid: iid) - - readable?(resource) ? resource : nil - end - - def search_results - collection.search(query).limit(QUERY_LIMIT).select do |resource| - readable?(resource) - end - end - - # params[:text] = issue search <search query> - def query - params[:text].split[2..-1].join(' ') - end - - # params[:text] = 'mergerequest show 123' - def iid - params[:text].split[2] - end - end - end -end diff --git a/app/services/mattermost/commands/issue_create_service.rb b/app/services/mattermost/commands/issue_create_service.rb deleted file mode 100644 index db3f868fc09..00000000000 --- a/app/services/mattermost/commands/issue_create_service.rb +++ /dev/null @@ -1,21 +0,0 @@ -module Mattermost - module Commands - class IssueCreateService < IssueService - def execute - title, description = parse_command - - present Issues::CreateService.new(project, current_user, title: title, description: description).execute - end - - private - - def parse_command - match = params[:text].match(/\Aissue create (?<title>.*)\n*/) - title = match[:title] - description = match.post_match - - [title, description] - end - end - end -end diff --git a/app/services/mattermost/commands/issue_search_service.rb b/app/services/mattermost/commands/issue_search_service.rb deleted file mode 100644 index 072cb8e2590..00000000000 --- a/app/services/mattermost/commands/issue_search_service.rb +++ /dev/null @@ -1,9 +0,0 @@ -module Mattermost - module Commands - class IssueSearchService < IssueService - def execute - present search_results - end - end - end -end diff --git a/app/services/mattermost/commands/issue_show_service.rb b/app/services/mattermost/commands/issue_show_service.rb deleted file mode 100644 index 100b2780d0e..00000000000 --- a/app/services/mattermost/commands/issue_show_service.rb +++ /dev/null @@ -1,9 +0,0 @@ -module Mattermost - module Commands - class IssueShowService < IssueService - def execute - present find_by_iid - end - end - end -end diff --git a/app/services/mattermost/commands/merge_request_search_service.rb b/app/services/mattermost/commands/merge_request_search_service.rb deleted file mode 100644 index f675320ddae..00000000000 --- a/app/services/mattermost/commands/merge_request_search_service.rb +++ /dev/null @@ -1,9 +0,0 @@ -module Mattermost - module Commands - class MergeRequestSearchService < MergeRequestService - def execute - present search_results - end - end - end -end diff --git a/app/services/mattermost/commands/merge_request_show_service.rb b/app/services/mattermost/commands/merge_request_show_service.rb deleted file mode 100644 index c5b2850169a..00000000000 --- a/app/services/mattermost/commands/merge_request_show_service.rb +++ /dev/null @@ -1,9 +0,0 @@ -module Mattermost - module Commands - class MergeRequestShowService < MergeRequestService - def execute - present find_by_iid - end - end - end -end diff --git a/app/services/mattermost/slash_command_service.rb b/app/services/mattermost/slash_command_service.rb deleted file mode 100644 index 0e74c929b9b..00000000000 --- a/app/services/mattermost/slash_command_service.rb +++ /dev/null @@ -1,39 +0,0 @@ -module Mattermost - class SlashCommandService < BaseService - def self.registry - @registry ||= Hash.new({}) - end - - def self.command(command, sub_command, klass, help_message) - registry[command][sub_command] = { klass: klass, help_message: help_message } - end - - command 'issue', 'show', Mattermost::Commands::IssueShowService, 'issue show <id>' - command 'issue', 'search', Mattermost::Commands::IssueSearchService, 'issue search <query>' - command 'issue', 'create', Mattermost::Commands::IssueCreateService, 'issue create my title' - - command 'mergerequest', 'show', Mattermost::Commands::MergeRequestShowService, 'mergerequest show <id>' - command 'mergerequest', 'search', Mattermost::Commands::MergeRequestSearchService, 'mergerequest search <query>' - - def execute - command, subcommand = parse_command - - #TODO think how to do this to support ruby 2.1 - service = registry.dig(command, subcommand, :klass) - - return help_messages(registry) unless service.try(:available?, project) - - service.new(project, current_user, params).execute - end - - private - - def parse_command - params[:text].split.first(2) - end - - def registry - self.class.registry - end - end -end diff --git a/lib/gitlab/chat_commands/base_command.rb b/lib/gitlab/chat_commands/base_command.rb new file mode 100644 index 00000000000..13dc2a0f3e8 --- /dev/null +++ b/lib/gitlab/chat_commands/base_command.rb @@ -0,0 +1,55 @@ +module Gitlab + module ChatCommands + class BaseCommand + QUERY_LIMIT = 5 + + def self.match(_) + raise NotImplementedError + end + + def self.help_message + raise NotImplementedError + end + + def self.available?(_) + raise NotImplementedError + end + + def execute(_) + raise NotImplementedError + end + + def collection + raise NotImplementedError + end + + attr_accessor :project, :current_user, :params + + def initialize(project, user, params = {}) + @project, @current_user, @params = project, user, params.dup + end + + private + + def can?(object, action, subject) + Ability.allowed?(object, action, subject) + end + + def present(resource) + Mattermost::Presenter.present(resource) + end + + def find_by_iid(iid) + resource = collection.find_by(iid: iid) + + readable?(resource) ? resource : nil + end + + def search_results(query) + collection.search(query).limit(QUERY_LIMIT).select do |resource| + readable?(resource) + end + end + end + end +end diff --git a/lib/gitlab/chat_commands/command.rb b/lib/gitlab/chat_commands/command.rb new file mode 100644 index 00000000000..06d09ab0e24 --- /dev/null +++ b/lib/gitlab/chat_commands/command.rb @@ -0,0 +1,49 @@ +module Gitlab + module ChatCommands + class Command < BaseCommand + COMMANDS = [ + Gitlab::ChatCommands::IssueShow, + Gitlab::ChatCommands::IssueSearch, + Gitlab::ChatCommands::IssueCreate, + + Gitlab::ChatCommands::MergeRequestShow, + Gitlab::ChatCommands::MergeRequestSearch, + ].freeze + + def execute + klass, match = fetch_klass + + return help(help_messages) unless klass.try(:available?, project) + + klass.new(project, current_user, params).execute(match) + end + + private + + def fetch_klass + match = nil + service = COMMANDS.find do |klass| + if klass.available?(project) + false + else + match = klass.match(command) + end + end + + [service, match] + end + + def help_messages + COMMANDS.map do |klass| + next unless klass.available?(project) + + klass.help_message + end.compact + end + + def command + params[:text] + end + end + end +end diff --git a/app/services/mattermost/commands/issue_service.rb b/lib/gitlab/chat_commands/issue_command.rb index d27dcda21c4..2426b3714b7 100644 --- a/app/services/mattermost/commands/issue_service.rb +++ b/lib/gitlab/chat_commands/issue_command.rb @@ -1,6 +1,6 @@ -module Mattermost - module Commands - class IssueService < Mattermost::Commands::BaseService +module Gitlab + module ChatCommands + class IssueCommand < BaseCommand def self.available?(project) project.issues_enabled? && project.default_issues_tracker? end diff --git a/lib/gitlab/chat_commands/issue_create.rb b/lib/gitlab/chat_commands/issue_create.rb new file mode 100644 index 00000000000..c424e845402 --- /dev/null +++ b/lib/gitlab/chat_commands/issue_create.rb @@ -0,0 +1,16 @@ +module Gitlab + module ChatCommands + class IssueCreate < BaseCommand + def self.match(text) + /\Aissue\s+create\s+(?<title>[^\n]*)\n*(?<description>.*)\z/.match(text) + end + + def execute(match) + title = match[:title] + description = match[:description] + + present Issues::CreateService.new(project, current_user, title: title, description: description).execute + end + end + end +end diff --git a/lib/gitlab/chat_commands/issue_search.rb b/lib/gitlab/chat_commands/issue_search.rb new file mode 100644 index 00000000000..4169e2a7a88 --- /dev/null +++ b/lib/gitlab/chat_commands/issue_search.rb @@ -0,0 +1,17 @@ +module Gitlab + module ChatCommands + class IssueSearch < IssueCommand + def self.match(text) + /\Aissue\s+search\s+(?<query>.*)/.match(text) + end + + def self.help_message + "issue search <query>" + end + + def execute(match) + present search_results(match[:query]) + end + end + end +end diff --git a/lib/gitlab/chat_commands/issue_show.rb b/lib/gitlab/chat_commands/issue_show.rb new file mode 100644 index 00000000000..e5530df31cc --- /dev/null +++ b/lib/gitlab/chat_commands/issue_show.rb @@ -0,0 +1,17 @@ +module Gitlab + module ChatCommands + class IssueShow < IssueCommand + def self.match(text) + /\Aissue\s+show\s+(?<iid>\d+)/.match(text) + end + + def self.help_message + "issue show <id>" + end + + def execute(match) + present find_by_iid(match[:iid]) + end + end + end +end diff --git a/app/services/mattermost/commands/merge_request_service.rb b/lib/gitlab/chat_commands/merge_request_command.rb index 8b81c9bbfd9..e0f69a49afd 100644 --- a/app/services/mattermost/commands/merge_request_service.rb +++ b/lib/gitlab/chat_commands/merge_request_command.rb @@ -1,6 +1,6 @@ -module Mattermost - module Commands - class MergeRequestService < Mattermost::Commands::BaseService +module Gitlab + module ChatCommands + class MergeRequestCommand < BaseCommand def self.available?(project) project.merge_requests_enabled? end diff --git a/lib/gitlab/chat_commands/merge_request_search.rb b/lib/gitlab/chat_commands/merge_request_search.rb new file mode 100644 index 00000000000..caecb1a788e --- /dev/null +++ b/lib/gitlab/chat_commands/merge_request_search.rb @@ -0,0 +1,17 @@ +module Gitlab + module ChatCommands + class MergeRequestSearch < MergeRequestCommand + def self.match(text) + /\Amergerequest\s+search\s+(?<query>.*)/.match(text) + end + + def self.help_message + "mergerequest search <query>" + end + + def execute(match) + present search_results(match[:query]) + end + end + end +end diff --git a/lib/gitlab/chat_commands/merge_request_show.rb b/lib/gitlab/chat_commands/merge_request_show.rb new file mode 100644 index 00000000000..7ed5445e4c2 --- /dev/null +++ b/lib/gitlab/chat_commands/merge_request_show.rb @@ -0,0 +1,17 @@ +module Gitlab + module ChatCommands + class MergeRequestShow < MergeRequestCommand + def self.match(text) + /\Amergerequest\s+show\s+(?<iid>\d+)/.match(text) + end + + def self.help_message + "mergerequest show <id>" + end + + def execute(match) + present find_by_iid(match[:iid]) + end + end + end +end diff --git a/lib/mattermost/presenter.rb b/lib/mattermost/presenter.rb index e1502e3f9ba..3db55d6bd51 100644 --- a/lib/mattermost/presenter.rb +++ b/lib/mattermost/presenter.rb @@ -12,12 +12,11 @@ module Mattermost } end - # TODO figure out how I know which are available or not - def help_message(commands) + def help(messages) messages = ["Available commands:"] - commands.each do |sub_command, attrs| - messages << "\t#{COMMAND_PREFIX} #{attrs[:help_message]}" + messages.each do |messsage| + messages << "- #{message}" end { diff --git a/spec/services/mattermost/slash_command_service_spec.rb b/spec/lib/gitlab/chat_commands/command_spec.rb index 14c2d9b7c37..d28349ff1d8 100644 --- a/spec/services/mattermost/slash_command_service_spec.rb +++ b/spec/lib/gitlab/chat_commands/command_spec.rb @@ -1,8 +1,8 @@ require 'spec_helper' -describe Mattermost::SlashCommandService, service: true do - let(:project) { build(:project) } - let(:user) { build(:user) } +describe Gitlab::ChatCommands::Command, service: true do + let(:project) { create(:project) } + let(:user) { create(:user) } let(:params) { { text: 'issue show 1' } } subject { described_class.new(project, user, params).execute } diff --git a/spec/services/mattermost/commands/issue_create_service_spec.rb b/spec/lib/gitlab/chat_commands/issue_create_spec.rb index 5ed86606b8f..184c09708a4 100644 --- a/spec/services/mattermost/commands/issue_create_service_spec.rb +++ b/spec/lib/gitlab/chat_commands/issue_create_spec.rb @@ -1,14 +1,14 @@ require 'spec_helper' -describe Mattermost::Commands::IssueCreateService, service: true do +describe Gitlab::ChatCommands::IssueCreate, service: true do describe '#execute' do let(:project) { create(:empty_project) } let(:user) { create(:user) } - let(:params) { { text: "issue create bird is the word" } } + let(:regex_match) { described_class.match("issue create bird is the word") } before { project.team << [user, :master] } - subject { described_class.new(project, user, params).execute } + subject { described_class.new(project, user).execute(regex_match) } context 'without description' do it 'creates the issue' do @@ -23,7 +23,7 @@ describe Mattermost::Commands::IssueCreateService, service: true do context 'with description' do let(:description) { "Surfin bird" } - let(:params) { { text: "issue create The bird is the word\n#{description}" } } + let(:regex_match) { described_class.match("issue create bird is the word\n#{description}") } before { subject } diff --git a/spec/services/mattermost/commands/issue_search_service_spec.rb b/spec/lib/gitlab/chat_commands/issue_search_spec.rb index 21934dfcdd0..3e54333528a 100644 --- a/spec/services/mattermost/commands/issue_search_service_spec.rb +++ b/spec/lib/gitlab/chat_commands/issue_search_spec.rb @@ -1,18 +1,18 @@ require 'spec_helper' -describe Mattermost::Commands::IssueSearchService, service: true do +describe Gitlab::ChatCommands::IssueSearch, service: true do describe '#execute' do let!(:issue) { create(:issue, title: 'The bird is the word') } let(:project) { issue.project } let(:user) { issue.author } - let(:params) { { text: "issue search bird is the" } } + let(:regex_match) { described_class.match("issue search bird is the") } before { project.team << [user, :master] } - subject { described_class.new(project, user, params).execute } + subject { described_class.new(project, user).execute(regex_match) } context 'without results' do - let(:params) { { text: "issue search no results for this one" } } + let(:regex_match) { described_class.match("issue search no results for this one") } it "returns nil" do expect(subject[:response_type]).to be :ephemeral diff --git a/spec/services/mattermost/commands/issue_show_service_spec.rb b/spec/lib/gitlab/chat_commands/issue_show_spec.rb index 7578cd3a22c..ddf7fc87c36 100644 --- a/spec/services/mattermost/commands/issue_show_service_spec.rb +++ b/spec/lib/gitlab/chat_commands/issue_show_spec.rb @@ -1,26 +1,25 @@ require 'spec_helper' -describe Mattermost::Commands::IssueShowService, service: true do +describe Gitlab::ChatCommands::IssueShow, service: true do describe '#execute' do let(:issue) { create(:issue) } let(:project) { issue.project } let(:user) { issue.author } - let(:params) { { text: "issue show #{issue.iid}" } } + let(:regex_match) { described_class.match("issue show #{issue.iid}") } before { project.team << [user, :master] } - subject { described_class.new(project, user, params).execute } + subject { described_class.new(project, user).execute(regex_match) } context 'the issue exists' do it 'returns the issue' do - expect(subject[:response_type]).to be :in_channel expect(subject[:text]).to match issue.title end end context 'the issue does not exist' do - let(:params) { { text: "issue show 12345" } } + let(:regex_match) { described_class.match("issue show 1234") } it "returns nil" do expect(subject[:response_type]).to be :ephemeral diff --git a/spec/services/mattermost/commands/merge_request_search_service_spec.rb b/spec/lib/gitlab/chat_commands/merge_request_search_spec.rb index 5212dc206a6..4cb4563e589 100644 --- a/spec/services/mattermost/commands/merge_request_search_service_spec.rb +++ b/spec/lib/gitlab/chat_commands/merge_request_search_spec.rb @@ -1,15 +1,15 @@ require 'spec_helper' -describe Mattermost::Commands::MergeRequestSearchService, service: true do +describe Gitlab::ChatCommands::MergeRequestSearch, service: true do describe '#execute' do let!(:merge_request) { create(:merge_request, title: 'The bird is the word') } let(:project) { merge_request.source_project } let(:user) { merge_request.author } - let(:params) { { text: "mergerequest search #{merge_request.title}" } } + let(:regex_match) { described_class.match("mergerequest search #{merge_request.title}") } before { project.team << [user, :master] } - subject { described_class.new(project, user, params).execute } + subject { described_class.new(project, user, {}).execute(regex_match) } context 'the merge request exists' do it 'returns the merge request' do @@ -19,7 +19,7 @@ describe Mattermost::Commands::MergeRequestSearchService, service: true do end context 'no results can be found' do - let(:params) { { text: "mergerequest search 12345" } } + let(:regex_match) { described_class.match("mergerequest search 12334") } it "returns a 404 message" do expect(subject[:response_type]).to be :ephemeral @@ -27,4 +27,10 @@ describe Mattermost::Commands::MergeRequestSearchService, service: true do end end end + + describe 'self.match' do + it 'matches a valid query' do + expect(described_class.match("mergerequest search my title here")).to be_truthy + end + end end diff --git a/spec/services/mattermost/commands/merge_request_show_service_spec.rb b/spec/lib/gitlab/chat_commands/merge_request_show_spec.rb index 688737df0f5..ed63ffa5f85 100644 --- a/spec/services/mattermost/commands/merge_request_show_service_spec.rb +++ b/spec/lib/gitlab/chat_commands/merge_request_show_spec.rb @@ -1,15 +1,15 @@ require 'spec_helper' -describe Mattermost::Commands::MergeRequestShowService, service: true do +describe Gitlab::ChatCommands::MergeRequestShow, service: true do describe '#execute' do let!(:merge_request) { create(:merge_request) } let(:project) { merge_request.source_project } let(:user) { merge_request.author } - let(:params) { { text: "mergerequest show #{merge_request.iid}" } } + let(:regex_match) { described_class.match("mergerequest show #{merge_request.iid}") } before { project.team << [user, :master] } - subject { described_class.new(project, user, params).execute } + subject { described_class.new(project, user).execute(regex_match) } context 'the merge request exists' do it 'returns the merge request' do @@ -19,7 +19,7 @@ describe Mattermost::Commands::MergeRequestShowService, service: true do end context 'the merge request does not exist' do - let(:params) { { text: "mergerequest show 12345" } } + let(:regex_match) { described_class.match("mergerequest show 12345") } it "returns nil" do expect(subject[:response_type]).to be :ephemeral @@ -27,4 +27,11 @@ describe Mattermost::Commands::MergeRequestShowService, service: true do end end end + + describe "self.match" do + it 'matches valid strings' do + expect(described_class.match("mergerequest show 123")).to be_truthy + expect(described_class.match("mergerequest show sdf23")).to be_falsy + end + end end |