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
def page_class
"issue-boards-page" if current_controller?(:boards)
end
def pretty_url(url)
url.gsub(/\A.*?:\/\//, '')
end
end
......@@ -153,7 +153,7 @@ module ProjectsHelper
return nil unless team['display_name'] && team['id']
[team['display_name'], team['id']]
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
end
......
......@@ -39,8 +39,8 @@ class MattermostSlashCommandsService < ChatService
def list_teams
begin
response = Mattermost::Mattermost.new(current_user).with_session do |session|
Mattermost::Team.teams(session)
response = Mattermost::Session.new(current_user).with_session do |session|
Mattermost::Team.all(session)
end
# 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
.inline.pull-right
= custom_icon('mattermost_logo', size: 48)
%h3 Install Mattermost Command
- if teams.count === 0
%p
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'
- if @teams.empty?
= render 'no_teams'
- else
%p
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'
= render 'team_selection'
......@@ -8,14 +8,13 @@
.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|
= render 'shared/service_settings', form: form, subject: @service
- if @service.to_param != 'mattermost_slash_commands'
.footer-block.row-content-block
= form.submit 'Save changes', class: 'btn btn-save'
&nbsp;
- if @service.valid? && @service.activated?
- unless @service.can_test?
- disabled_class = 'disabled'
- disabled_title = @service.disabled_title
.footer-block.row-content-block
= form.submit 'Save changes', class: 'btn btn-save'
&nbsp;
- if @service.valid? && @service.activated?
- unless @service.can_test?
- disabled_class = 'disabled'
- disabled_title = @service.disabled_title
= link_to 'Test settings', test_namespace_project_service_path(@project.namespace, @project, @service), class: "btn #{disabled_class}", title: disabled_title
= link_to "Cancel", namespace_project_services_path(@project.namespace, @project), class: "btn btn-cancel"
= link_to 'Test settings', test_namespace_project_service_path(@project.namespace, @project, @service), class: "btn #{disabled_class}", title: disabled_title
= link_to "Cancel", namespace_project_services_path(@project.namespace, @project), class: "btn btn-cancel"
- 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
This service allows GitLab users to perform common operations on this
project by entering slash commands in Mattermost.
......@@ -5,5 +7,6 @@
See list of available commands in Mattermost after setting up this service,
by entering
%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
.row
%strong.col-sm-3.text-right Status
.col-sm-9= @service.activated? ? 'Installed' : 'Not installed'
.row
%strong.col-sm-3.text-right Mattermost
= link_to 'some_path.url', 'some_path.url', class: 'col-sm-9'
- if @service.activated?
.row
%strong.col-sm-3.text-right Team
.col-sm-9 some_team.name
= link_to pretty_url(Gitlab.config.mattermost.host), Gitlab.config.mattermost.host, class: 'col-sm-9', target: '__blank'
.row
%strong.col-sm-3.text-right Installation
.col-sm-9
......
......@@ -7,45 +7,44 @@
= preserve do
= markdown @service.help
- if @service.to_param != 'mattermost_slash_commands'
.service-settings
.service-settings
.form-group
= form.label :active, "Active", class: "control-label"
.col-sm-10
= form.check_box :active
- if @service.supported_events.present?
.form-group
= form.label :active, "Active", class: "control-label"
= form.label :url, "Trigger", class: 'control-label'
.col-sm-10
= form.check_box :active
- if @service.supported_events.present?
.form-group
= form.label :url, "Trigger", class: 'control-label'
.col-sm-10
- @service.supported_events.each do |event|
%div
= form.check_box service_event_field_name(event), class: 'pull-left'
.prepend-left-20
= form.label service_event_field_name(event), class: 'list-label' do
%strong
= event.humanize
- field = @service.event_field(event)
- if field
%p
= form.text_field field[:name], class: "form-control", placeholder: field[:placeholder]
%p.light
= service_event_description(event)
- @service.global_fields.each do |field|
- type = field[:type]
- if type == 'fieldset'
- fields = field[:fields]
- legend = field[:legend]
%fieldset
%legend= legend
- fields.each do |subfield|
= render 'shared/field', form: form, field: subfield
- else
= render 'shared/field', form: form, field: field
- @service.supported_events.each do |event|
%div
= form.check_box service_event_field_name(event), class: 'pull-left'
.prepend-left-20
= form.label service_event_field_name(event), class: 'list-label' do
%strong
= event.humanize
- field = @service.event_field(event)
- if field
%p
= form.text_field field[:name], class: "form-control", placeholder: field[:placeholder]
%p.light
= service_event_description(event)
- @service.global_fields.each do |field|
- type = field[:type]
- if type == 'fieldset'
- fields = field[:fields]
- legend = field[:legend]
%fieldset
%legend= legend
- fields.each do |subfield|
= render 'shared/field', form: form, field: subfield
- else
= render 'shared/field', form: form, field: field
module Mattermost
class Team
def self.all(session)
response_body = retreive_teams(session)
response_body.has_key?('message') ? response_body : response_body.values
retreive_teams(session)
end
def self.retreive_teams(session)
......
......@@ -10,23 +10,18 @@ feature 'Setup Mattermost slash commands', feature: true do
before do
project.team << [user, :master]
login_as(user)
visit edit_namespace_project_service_path(project.namespace, project, service)
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
visit edit_namespace_project_service_path(project.namespace, project, service)
wait_for_ajax
expect(page).to have_content("This service allows GitLab users to perform common")
end
end
describe 'saving a token' do
let(:token) { ('a'..'z').to_a.join }
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
click_on 'Save'
......@@ -35,14 +30,58 @@ feature 'Setup Mattermost slash commands', feature: true do
expect(value).to eq(token)
end
end
describe 'the trigger url' do
it 'shows the correct url' do
visit edit_namespace_project_service_path(project.namespace, project, service)
describe 'mattermost service is enabled' do
let(:info) { find('.services-installation-info') }
before do
Gitlab.config.mattermost.enabled = true
end
it 'shows the correct mattermost url' do
expect(page).to have_content Gitlab.config.mattermost.host
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
{"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
allow(hash).to receive(:parsed_response).and_return(hash)
end
context 'with access' do
it 'gets the teams' do
expect(session).to receive(:post)
described_class.create(session, 'abc', url: 'http://trigger.com')
end
end
context 'on an error' do
it 'gets the teams' do
expect(session).to receive(:post)
described_class.create(session, 'abc', url: 'http://trigger.com')
end
end
end
......@@ -3,22 +3,39 @@ require 'spec_helper'
describe Mattermost::Team do
describe '.team_admin' do
let(:session) { double("session") }
# TODO fix fixture
let(:json) { File.read(Rails.root.join('spec/fixtures/', 'mattermost_initial_load.json')) }
let(:parsed_response) { JSON.parse(json) }
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
let(:json) { nil }
before do
allow(session).to receive(:get).with('/api/v3/teams/all').
and_return(json)
allow(json).to receive(:parsed_response).and_return(parsed_response)
allow(json).to receive(:parsed_response).and_return(response)
end
xit 'gets the teams' do
expect(described_class.all(session).count).to be(2)
it 'gets the teams' do
expect(described_class.all(session).count).to be(1)
end
xit 'filters on being team admin' do
expect(ids).to include("w59qt5a817f69jkxdz6xe7y4ir", "my9oujxf5jy1zqdgu9rihd66do")
it 'filters on being team admin' do
ids = described_class.all(session).map { |team| team['id'] }
expect(ids).to include("xiyro8huptfhdndadpz8r3wnbo")
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