Commit 5d197230 authored by Z.J. van de Weg's avatar Z.J. van de Weg

Merge remote-tracking branch 'origin/zj-mattermost-slash-config' into zj-mattermost-slash-config

parents d2153560 05d04d04
...@@ -294,4 +294,8 @@ module ApplicationHelper ...@@ -294,4 +294,8 @@ module ApplicationHelper
def page_class def page_class
"issue-boards-page" if current_controller?(:boards) "issue-boards-page" if current_controller?(:boards)
end end
def pretty_url(url)
url.gsub(/\A.*?:\/\//, '')
end
end end
...@@ -153,7 +153,7 @@ module ProjectsHelper ...@@ -153,7 +153,7 @@ module ProjectsHelper
return nil unless team['display_name'] && team['id'] return nil unless team['display_name'] && team['id']
[team['display_name'], team['id']] [team['display_name'], team['id']]
end.compact end.compact
teams_options.unshift(['Select a team...', '0']) unless teams_options.count === 1 teams_options.unshift(['Select team...', '0']) unless teams_options.one?
teams_options teams_options
end end
......
...@@ -39,8 +39,8 @@ class MattermostSlashCommandsService < ChatService ...@@ -39,8 +39,8 @@ class MattermostSlashCommandsService < ChatService
def list_teams def list_teams
begin begin
response = Mattermost::Mattermost.new(current_user).with_session do |session| response = Mattermost::Session.new(current_user).with_session do |session|
Mattermost::Team.teams(session) Mattermost::Team.all(session)
end end
# We ignore the error message as we can't display it # We ignore the error message as we can't display it
......
%p
You aren’t a member of any team on the Mattermost instance at
%strong= Gitlab.config.mattermost.host
%p
To install this service,
= link_to "#{Gitlab.config.mattermost.host}/select_team", target: '__blank' do
join a team
= icon('external-link')
and try again.
%hr
.clearfix
= link_to 'Go back', edit_namespace_project_service_path(@project.namespace, @project, @service), class: 'btn btn-lg pull-right'
%p
This service will be installed on the Mattermost instance at
%strong= Gitlab.config.mattermost.host
%hr
= form_for(:create, method: :post, url: configure_namespace_project_mattermost_index_path(@project.namespace, @project)) do |f|
%h4 Team
%p Select or create the team where the slash commands will be used in
- options = mattermost_teams_options(@teams)
= f.select(:team_id, options, {}, { class: 'form-control', selected: "#{options.first[1] if options.count.one?}", disabled: options.count.one? })
.help-block
- if options.count.one?
This is the only team where you are an administrator.
- else
The list shows teams where you are administrator
To create a team, ask your Mattermost system administrator.
To create a team,
= link_to "#{Gitlab.config.mattermost.host}/create_team" do
use Mattermost's interface
= icon('external-link')
%hr
%h4 Command trigger word
%p Choose the word that will trigger commands
= f.text_field(:trigger, value: @project.path, class: 'form-control')
.help-block
%p Trigger word must be unique, and cannot begin with a slash or contain any spaces. Use the word that works best for your team.
%p Fill in the word that works best for your team.
%p
Suggestions:
%code= 'gitlab'
%code= @project.path # Path contains no spaces, but dashes
%code= @project.path_with_namespace
%p
Reserved:
= link_to 'https://docs.mattermost.com/help/messaging/executing-commands.html#built-in-commands', target: '__blank' do
see list of built-in slash commands
= icon('external-link')
%hr
.clearfix
.pull-right
= link_to 'Cancel', edit_namespace_project_service_path(@project.namespace, @project, @service), class: 'btn btn-lg'
= f.submit 'Install', class: 'btn btn-save btn-lg'
- twoTeams = [{"id"=>"w59qt5a817f69jkxdz6xe7y4ir", "create_at"=>1481835484179, "update_at"=>1481835484179, "delete_at"=>0, "display_name"=>"new_team", "name"=>"new-team", "email"=>"", "type"=>"O", "company_name"=>"", "allowed_domains"=>"", "invite_id"=>"mfgsqnmpiby18eepo6jd6pq3oh", "allow_open_invite"=>false}, {"id"=>"my9oujxf5jy1zqdgu9rihd66do", "create_at"=>1481826062406, "update_at"=>1481826062406, "delete_at"=>0, "display_name"=>"chatops", "name"=>"chatops", "email"=>"", "type"=>"O", "company_name"=>"", "allowed_domains"=>"", "invite_id"=>"s7c1phenmi8udkybcyytc3pxuh", "allow_open_invite"=>false}]
- oneTeams = [{"id"=>"w59qt5a817f69jkxdz6xe7y4ir", "create_at"=>1481835484179, "update_at"=>1481835484179, "delete_at"=>0, "display_name"=>"new_team", "name"=>"new-team", "email"=>"", "type"=>"O", "company_name"=>"", "allowed_domains"=>"", "invite_id"=>"mfgsqnmpiby18eepo6jd6pq3oh", "allow_open_invite"=>false}]
- noTeams = []
- teams = twoTeams
.service-installation .service-installation
.inline.pull-right .inline.pull-right
= custom_icon('mattermost_logo', size: 48) = custom_icon('mattermost_logo', size: 48)
%h3 Install Mattermost Command %h3 Install Mattermost Command
- if teams.count === 0 - if @teams.empty?
%p = render 'no_teams'
To install this service, you must be administrator of a team in the Mattermost instance at
%strong some_path.url
%p Ask your Mattermost system administrator for permissions.
%hr
.clearfix
= link_to 'Go back', 'some_url', class: 'btn btn-lg pull-right'
- else - else
%p = render 'team_selection'
This service will be installed on the Mattermost instance at
%strong some_path.url
%hr
= form_for(:create, method: :post, url: configure_namespace_project_mattermost_index_path(@project.namespace, @project, )) do |f|
%h4 Team
%p Select or create the team where the slash commands will be used in
- options = mattermost_teams_options(teams)
- isOneTeam = options.count === 1
= f.select(:team_id, options, {}, {class: 'form-control', selected: "#{options.first[1] if isOneTeam}", disabled: isOneTeam})
- if isOneTeam
.help-block
This is the only team where you are an administrator.
To create a team, ask your Mattermost system administrator.
- else
.help-block
The list shows teams where you are administrator
To create a team, ask your Mattermost system administrator.
%hr
%h4 Command trigger word
%p Choose the word that will trigger commands
= f.text_field(:trigger, value: @project.path, class: 'form-control')
.help-block
%p Trigger word must be unique, and cannot begin with a slash or contain any spaces. Use the word that works best for your team.
%p Fill in the word that works best for your team.
%p
Suggestions:
%code= 'gitlab'
%code= @project.path # Path contains no spaces, but dashes
%code= @project.path_with_namespace
%p
Reserved:
= link_to 'see list of built-in slash commands', 'some_url'
%hr
.clearfix
.pull-right
= link_to 'Cancel', 'some_url', class: 'btn btn-lg'
= f.submit 'Install', class: 'btn btn-save btn-lg'
...@@ -8,7 +8,6 @@ ...@@ -8,7 +8,6 @@
.col-lg-9 .col-lg-9
= form_for(@service, as: :service, url: namespace_project_service_path(@project.namespace, @project, @service.to_param), method: :put, html: { class: 'form-horizontal' }) do |form| = form_for(@service, as: :service, url: namespace_project_service_path(@project.namespace, @project, @service.to_param), method: :put, html: { class: 'form-horizontal' }) do |form|
= render 'shared/service_settings', form: form, subject: @service = render 'shared/service_settings', form: form, subject: @service
- if @service.to_param != 'mattermost_slash_commands'
.footer-block.row-content-block .footer-block.row-content-block
= form.submit 'Save changes', class: 'btn btn-save' = form.submit 'Save changes', class: 'btn btn-save'
&nbsp; &nbsp;
......
- run_actions_text = "Perform common operations on this project: #{@project.name_with_namespace}"
To setup this service:
%ul.list-unstyled
%li
1.
= link_to 'Enable custom slash commands', 'https://docs.mattermost.com/developer/slash-commands.html#enabling-custom-commands'
on your Mattermost installation
%li
2.
= link_to 'Add a slash command', 'https://docs.mattermost.com/developer/slash-commands.html#set-up-a-custom-command'
in Mattermost with these options:
%hr
.help-form
.form-group
= label_tag :display_name, 'Display name', class: 'col-sm-2 col-xs-12 control-label'
.col-sm-10.col-xs-12.input-group
= text_field_tag :display_name, "GitLab / #{@project.name_with_namespace}", class: 'form-control input-sm', readonly: 'readonly'
.input-group-btn
= clipboard_button(clipboard_target: '#display_name')
.form-group
= label_tag :description, 'Description', class: 'col-sm-2 col-xs-12 control-label'
.col-sm-10.col-xs-12.input-group
= text_field_tag :description, run_actions_text, class: 'form-control input-sm', readonly: 'readonly'
.input-group-btn
= clipboard_button(clipboard_target: '#description')
.form-group
= label_tag nil, 'Command trigger word', class: 'col-sm-2 col-xs-12 control-label'
.col-sm-10.col-xs-12.text-block
%p Fill in the word that works best for your team.
%p
Suggestions:
%code= 'gitlab'
%code= @project.path # Path contains no spaces, but dashes
%code= @project.path_with_namespace
.form-group
= label_tag :request_url, 'Request URL', class: 'col-sm-2 col-xs-12 control-label'
.col-sm-10.col-xs-12.input-group
= text_field_tag :request_url, service_trigger_url(subject), class: 'form-control input-sm', readonly: 'readonly'
.input-group-btn
= clipboard_button(clipboard_target: '#request_url')
.form-group
= label_tag nil, 'Request method', class: 'col-sm-2 col-xs-12 control-label'
.col-sm-10.col-xs-12.text-block POST
.form-group
= label_tag :response_username, 'Response username', class: 'col-sm-2 col-xs-12 control-label'
.col-sm-10.col-xs-12.input-group
= text_field_tag :response_username, 'GitLab', class: 'form-control input-sm', readonly: 'readonly'
.input-group-btn
= clipboard_button(clipboard_target: '#response_username')
.form-group
= label_tag :response_icon, 'Response icon', class: 'col-sm-2 col-xs-12 control-label'
.col-sm-10.col-xs-12.input-group
= text_field_tag :response_icon, asset_url('gitlab_logo.png'), class: 'form-control input-sm', readonly: 'readonly'
.input-group-btn
= clipboard_button(clipboard_target: '#response_icon')
.form-group
= label_tag nil, 'Autocomplete', class: 'col-sm-2 col-xs-12 control-label'
.col-sm-10.col-xs-12.text-block Yes
.form-group
= label_tag :autocomplete_hint, 'Autocomplete hint', class: 'col-sm-2 col-xs-12 control-label'
.col-sm-10.col-xs-12.input-group
= text_field_tag :autocomplete_hint, '[help]', class: 'form-control input-sm', readonly: 'readonly'
.input-group-btn
= clipboard_button(clipboard_target: '#autocomplete_hint')
.form-group
= label_tag :autocomplete_description, 'Autocomplete description', class: 'col-sm-2 col-xs-12 control-label'
.col-sm-10.col-xs-12.input-group
= text_field_tag :autocomplete_description, run_actions_text, class: 'form-control input-sm', readonly: 'readonly'
.input-group-btn
= clipboard_button(clipboard_target: '#autocomplete_description')
%hr
%ul.list-unstyled
%li
3. After adding the slash command, paste the
%strong token
into the field below
- enabled = Gitlab.config.mattermost.enabled
.well .well
This service allows GitLab users to perform common operations on this This service allows GitLab users to perform common operations on this
project by entering slash commands in Mattermost. project by entering slash commands in Mattermost.
...@@ -5,5 +7,6 @@ ...@@ -5,5 +7,6 @@
See list of available commands in Mattermost after setting up this service, See list of available commands in Mattermost after setting up this service,
by entering by entering
%code /&lt;command_trigger_word&gt; help %code /&lt;command_trigger_word&gt; help
= render 'projects/services/mattermost_slash_commands/detailed_help', subject: @service unless enabled
= render 'projects/services/mattermost_slash_commands/installation_info' = render 'projects/services/mattermost_slash_commands/installation_info' if enabled
-# THE ALERT BOX...
-# .alert.alert-info
-# Mattermost Command was successfully installed. You can now use GitLab inside Mattermost
-# = emoji_icon('')
.services-installation-info .services-installation-info
.row .row
%strong.col-sm-3.text-right Status %strong.col-sm-3.text-right Status
.col-sm-9= @service.activated? ? 'Installed' : 'Not installed' .col-sm-9= @service.activated? ? 'Installed' : 'Not installed'
.row .row
%strong.col-sm-3.text-right Mattermost %strong.col-sm-3.text-right Mattermost
= link_to 'some_path.url', 'some_path.url', class: 'col-sm-9' = link_to pretty_url(Gitlab.config.mattermost.host), Gitlab.config.mattermost.host, class: 'col-sm-9', target: '__blank'
- if @service.activated?
.row
%strong.col-sm-3.text-right Team
.col-sm-9 some_team.name
.row .row
%strong.col-sm-3.text-right Installation %strong.col-sm-3.text-right Installation
.col-sm-9 .col-sm-9
......
...@@ -7,8 +7,7 @@ ...@@ -7,8 +7,7 @@
= preserve do = preserve do
= markdown @service.help = markdown @service.help
- if @service.to_param != 'mattermost_slash_commands' .service-settings
.service-settings
.form-group .form-group
= form.label :active, "Active", class: "control-label" = form.label :active, "Active", class: "control-label"
.col-sm-10 .col-sm-10
......
module Mattermost module Mattermost
class Team class Team
def self.all(session) def self.all(session)
response_body = retreive_teams(session) retreive_teams(session)
response_body.has_key?('message') ? response_body : response_body.values
end end
def self.retreive_teams(session) def self.retreive_teams(session)
......
...@@ -10,23 +10,18 @@ feature 'Setup Mattermost slash commands', feature: true do ...@@ -10,23 +10,18 @@ feature 'Setup Mattermost slash commands', feature: true do
before do before do
project.team << [user, :master] project.team << [user, :master]
login_as(user) login_as(user)
visit edit_namespace_project_service_path(project.namespace, project, service)
end end
describe 'user visites the mattermost slash command config page', js: true do describe 'user visits the mattermost slash command config page', js: true do
it 'shows a help message' do it 'shows a help message' do
visit edit_namespace_project_service_path(project.namespace, project, service)
wait_for_ajax wait_for_ajax
expect(page).to have_content("This service allows GitLab users to perform common") expect(page).to have_content("This service allows GitLab users to perform common")
end end
end
describe 'saving a token' do
let(:token) { ('a'..'z').to_a.join }
it 'shows the token after saving' do it 'shows the token after saving' do
visit edit_namespace_project_service_path(project.namespace, project, service) token = ('a'..'z').to_a.join
fill_in 'service_token', with: token fill_in 'service_token', with: token
click_on 'Save' click_on 'Save'
...@@ -35,14 +30,58 @@ feature 'Setup Mattermost slash commands', feature: true do ...@@ -35,14 +30,58 @@ feature 'Setup Mattermost slash commands', feature: true do
expect(value).to eq(token) expect(value).to eq(token)
end end
describe 'mattermost service is enabled' do
let(:info) { find('.services-installation-info') }
before do
Gitlab.config.mattermost.enabled = true
end end
describe 'the trigger url' do it 'shows the correct mattermost url' do
it 'shows the correct url' do expect(page).to have_content Gitlab.config.mattermost.host
visit edit_namespace_project_service_path(project.namespace, project, service) end
describe 'mattermost service is active' do
before do
service.active = true
end
it 'shows that mattermost is active' do
expect(info).to have_content 'Installed'
expect(info).not_to have_content 'Not installed'
end
it 'shows the edit mattermost button' do
expect(info).to have_button 'Edit Mattermost'
end
end
describe 'mattermost service is not active' do
before do
service.active = false
end
it 'shows that mattermost is not active' do
expect(info).to have_content 'Not installed'
end
it 'shows the add to mattermost button' do
expect(info).to have_button 'Add to Mattermost'
end
end
end
describe 'mattermost service is not enabled' do
before do
Gitlab.config.mattermost.enabled = false
end
it 'shows the correct trigger url' do
value = find_field('request_url').value value = find_field('request_url').value
expect(value).to match("api/v3/projects/#{project.id}/services/mattermost_slash_commands/trigger") expect(value).to match("api/v3/projects/#{project.id}/services/mattermost_slash_commands/trigger")
end end
end end
end
end end
{"user":{"id":"78nm4euoc7dypergdc13ekxgpo","create_at":1481826051672,"update_at":1481835484207,"delete_at":0,"username":"root","auth_data":"","auth_service":"gitlab","email":"admin@example.com","email_verified":true,"nickname":"","first_name":"Administrator","last_name":"","roles":"system_admin system_user","notify_props":{"channel":"true","desktop":"all","desktop_sound":"true","email":"true","first_name":"true","mention_keys":"root,@root","push":"mention"},"last_password_update":1481826051672,"locale":"en"},"team_members":[{"team_id":"w59qt5a817f69jkxdz6xe7y4ir","user_id":"78nm4euoc7dypergdc13ekxgpo","roles":"team_user team_admin","delete_at":0},{"team_id":"my9oujxf5jy1zqdgu9rihd66do","user_id":"78nm4euoc7dypergdc13ekxgpo","roles":"team_user team_admin","delete_at":0}],"teams":[{"id":"w59qt5a817f69jkxdz6xe7y4ir","create_at":1481835484179,"update_at":1481835484179,"delete_at":0,"display_name":"new_team","name":"new-team","email":"","type":"O","company_name":"","allowed_domains":"","invite_id":"mfgsqnmpiby18eepo6jd6pq3oh","allow_open_invite":false},{"id":"my9oujxf5jy1zqdgu9rihd66do","create_at":1481826062406,"update_at":1481826062406,"delete_at":0,"display_name":"chatops","name":"chatops","email":"","type":"O","company_name":"","allowed_domains":"","invite_id":"s7c1phenmi8udkybcyytc3pxuh","allow_open_invite":false}],"preferences":[{"user_id":"78nm4euoc7dypergdc13ekxgpo","category":"last","name":"channel","value":"u4j58zgjyt8zd8nwwhaqjkyqzw"},{"user_id":"78nm4euoc7dypergdc13ekxgpo","category":"tutorial_step","name":"78nm4euoc7dypergdc13ekxgpo","value":"999"}],"client_cfg":{"AboutLink":"/static/help/about.html","AndroidAppDownloadLink":"https://about.mattermost.com/mattermost-android-app/","AppDownloadLink":"https://about.mattermost.com/downloads/","AvailableLocales":"","BuildDate":"Wed Nov 23 19:43:58 UTC 2016","BuildEnterpriseReady":"false","BuildHash":"36f62c9e82350f58c902f64a5d3304872431ad41","BuildHashEnterprise":"none","BuildNumber":"3.5.1","DefaultClientLocale":"en","EnableCommands":"true","EnableCustomEmoji":"false","EnableDeveloper":"false","EnableDiagnostics":"true","EnableEmailBatching":"false","EnableIncomingWebhooks":"false","EnableOAuthServiceProvider":"false","EnableOnlyAdminIntegrations":"true","EnableOpenServer":"false","EnableOutgoingWebhooks":"false","EnablePostIconOverride":"true","EnablePostUsernameOverride":"true","EnablePublicLink":"true","EnableSignInWithEmail":"true","EnableSignInWithUsername":"false","EnableSignUpWithEmail":"false","EnableSignUpWithGitLab":"true","EnableTeamCreation":"true","EnableTesting":"false","EnableUserCreation":"true","EnableWebrtc":"false","GoogleDeveloperKey":"","HelpLink":"","IosAppDownloadLink":"https://about.mattermost.com/mattermost-ios-app/","MaxFileSize":"52428800","PrivacyPolicyLink":"/static/help/privacy.html","ProfileHeight":"128","ProfileWidth":"128","ReportAProblemLink":"/static/help/report_problem.html","RequireEmailVerification":"false","RestrictCustomEmojiCreation":"all","RestrictDirectMessage":"any","RestrictPrivateChannelManagement":"all","RestrictPublicChannelManagement":"all","RestrictTeamInvite":"all","SQLDriverName":"postgres","SegmentDeveloperKey":"","SendEmailNotifications":"false","SendPushNotifications":"false","ShowEmailAddress":"true","SiteName":"GitLab Mattermost","SiteURL":"","SupportEmail":"support@example.com","TermsOfServiceLink":"/static/help/terms.html","Version":"3.5.0","WebsocketPort":"80","WebsocketSecurePort":"443"},"license_cfg":{"IsLicensed":"false"},"no_accounts":false}
...@@ -10,16 +10,10 @@ describe Mattermost::Command do ...@@ -10,16 +10,10 @@ describe Mattermost::Command do
allow(hash).to receive(:parsed_response).and_return(hash) allow(hash).to receive(:parsed_response).and_return(hash)
end end
context 'with access' do
it 'gets the teams' do it 'gets the teams' do
expect(session).to receive(:post) expect(session).to receive(:post)
described_class.create(session, 'abc', url: 'http://trigger.com') described_class.create(session, 'abc', url: 'http://trigger.com')
end end
end end
context 'on an error' do
end
end
end end
...@@ -3,22 +3,39 @@ require 'spec_helper' ...@@ -3,22 +3,39 @@ require 'spec_helper'
describe Mattermost::Team do describe Mattermost::Team do
describe '.team_admin' do describe '.team_admin' do
let(:session) { double("session") } let(:session) { double("session") }
# TODO fix fixture
let(:json) { File.read(Rails.root.join('spec/fixtures/', 'mattermost_initial_load.json')) } let(:response) do
let(:parsed_response) { JSON.parse(json) } [{
"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
let(:json) { nil }
before do before do
allow(session).to receive(:get).with('/api/v3/teams/all'). allow(session).to receive(:get).with('/api/v3/teams/all').
and_return(json) and_return(json)
allow(json).to receive(:parsed_response).and_return(parsed_response) allow(json).to receive(:parsed_response).and_return(response)
end end
xit 'gets the teams' do it 'gets the teams' do
expect(described_class.all(session).count).to be(2) expect(described_class.all(session).count).to be(1)
end end
xit 'filters on being team admin' do it 'filters on being team admin' do
expect(ids).to include("w59qt5a817f69jkxdz6xe7y4ir", "my9oujxf5jy1zqdgu9rihd66do") ids = described_class.all(session).map { |team| team['id'] }
expect(ids).to include("xiyro8huptfhdndadpz8r3wnbo")
end end
end end
end end
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