From 7363a7d3b5804493f86531bebb1610afb91b5293 Mon Sep 17 00:00:00 2001
From: "Z.J. van de Weg" <git@zjvandeweg.nl>
Date: Fri, 16 Dec 2016 15:45:56 +0100
Subject: [PATCH] Add tests for auto configure slash commands

---
 .../projects/services_controller.rb           | 26 -------
 app/helpers/mattermost_helper.rb              | 13 ----
 app/views/projects/services/_form.html.haml   | 20 +++--
 .../mattermost_slash_commands/_form.html.haml |  3 -
 app/views/shared/_service_settings.html.haml  | 73 +++++++++----------
 config/routes/project.rb                      |  1 -
 lib/mattermost/command.rb                     |  8 +-
 lib/mattermost/team.rb                        | 14 ++--
 spec/fixtures/mattermost_initial_load.json    |  1 +
 spec/fixtures/mattermost_new_command.json     |  1 +
 spec/lib/mattermost/command_spec.rb           | 17 +++++
 spec/lib/mattermost/team_spec.rb              | 19 +++--
 .../mattermost_slash_commands_service_spec.rb | 31 ++++++++
 13 files changed, 123 insertions(+), 104 deletions(-)
 delete mode 100644 app/helpers/mattermost_helper.rb
 delete mode 100644 app/views/projects/services/mattermost_slash_commands/_form.html.haml
 create mode 100644 spec/fixtures/mattermost_initial_load.json
 create mode 100644 spec/fixtures/mattermost_new_command.json
 create mode 100644 spec/lib/mattermost/command_spec.rb

diff --git a/app/controllers/projects/services_controller.rb b/app/controllers/projects/services_controller.rb
index 94ea36bbdd9..b4f5750b0a4 100644
--- a/app/controllers/projects/services_controller.rb
+++ b/app/controllers/projects/services_controller.rb
@@ -44,35 +44,9 @@ class Projects::ServicesController < Projects::ApplicationController
     redirect_back_or_default(options: message)
   end
 
-  def configure
-    host = Gitlab.config.mattermost.host
-    if @service.auto_config? && host
-      @service.configure(host, current_user, params)
-
-      redirect_to(
-        edit_namespace_project_service_path(@project.namespace, @project, @service.to_param),
-        notice: 'This service is now configured.'
-      )
-    else
-      redirect_to(
-        edit_namespace_project_service_path(@project.namespace, @project, @service.to_param),
-        alert: 'This service can not be automatticly configured.'
-      )
-    end
-  rescue Mattermost::NoSessionError
-    redirect_to(
-      edit_namespace_project_service_path(@project.namespace, @project, @service.to_param),
-      alert: 'An error occurred, is Mattermost configured with Single Sign on?'
-    )
-  end
-
   private
 
   def service
     @service ||= @project.find_or_initialize_service(params[:id])
   end
-
-  def configure_params
-    params.require(:auto_configure).permit(:trigger, :team_id)
-  end
 end
diff --git a/app/helpers/mattermost_helper.rb b/app/helpers/mattermost_helper.rb
deleted file mode 100644
index 83434c20c2b..00000000000
--- a/app/helpers/mattermost_helper.rb
+++ /dev/null
@@ -1,13 +0,0 @@
-module MattermostHelper
-  def mattermost_teams_for(current_user)
-    return unless Gitlab.config.mattermost.enabled
-    # Hack to make frontend work better
-    return [{"id"=>"qz8gdr1fopncueb8n9on8ohk3h", "create_at"=>1479992105904, "update_at"=>1479992105904, "delete_at"=>0, "display_name"=>"chatops", "name"=>"chatops", "email"=>"admin@example.com", "type"=>"O", "company_name"=>"", "allowed_domains"=>"", "invite_id"=>"gthxi47gj7rxtcx6zama63zd1w", "allow_open_invite"=>false}]
-
-
-    host = Gitlab.config.mattermost.host
-    Mattermost::Mattermost.new(host, current_user).with_session do
-      Mattermost::Team.all
-    end
-  end
-end
diff --git a/app/views/projects/services/_form.html.haml b/app/views/projects/services/_form.html.haml
index 0160a366aaa..db51c4f8a4e 100644
--- a/app/views/projects/services/_form.html.haml
+++ b/app/views/projects/services/_form.html.haml
@@ -6,12 +6,16 @@
 
     %p= @service.description
   .col-lg-9
-    - # This returns an array of hashes, could you make a fancy dropdown :D
-    - # Also, this is mocked for now, checkout the MattermostHelper to edit the data
-    = mattermost_teams_for(current_user)
-    = form_for(:auto_configure, method: :post, url: configure_namespace_project_service_path(@project.namespace, @project, @service.to_param)) do |f|
-      = "Team ID"
-      = f.text_field(:team_id)
-      = "Team ID"
-      = f.submit 'Save changes', class: 'btn btn-save'
+    = 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
 
+      .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"
diff --git a/app/views/projects/services/mattermost_slash_commands/_form.html.haml b/app/views/projects/services/mattermost_slash_commands/_form.html.haml
deleted file mode 100644
index 9d9c877e791..00000000000
--- a/app/views/projects/services/mattermost_slash_commands/_form.html.haml
+++ /dev/null
@@ -1,3 +0,0 @@
-- teams = Mattermost::Mattermost.new(Gitlab.config.mattermost.host, current_user).with_session do
-  Mattermost::Mattermost::Team.all
-  end
diff --git a/app/views/shared/_service_settings.html.haml b/app/views/shared/_service_settings.html.haml
index e8ab1b2ed46..9c5053dace5 100644
--- a/app/views/shared/_service_settings.html.haml
+++ b/app/views/shared/_service_settings.html.haml
@@ -13,41 +13,38 @@
     .col-sm-10
       = form.check_box :active
 
-  - if @service.auto_config?
-
-  - else
-    - 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
+  - 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
diff --git a/config/routes/project.rb b/config/routes/project.rb
index 4ce09b603a2..3e210a75df5 100644
--- a/config/routes/project.rb
+++ b/config/routes/project.rb
@@ -61,7 +61,6 @@ constraints(ProjectUrlConstrainer.new) do
       resources :services, constraints: { id: /[^\/]+/ }, only: [:index, :edit, :update] do
         member do
           get :test
-          post :configure
         end
       end
 
diff --git a/lib/mattermost/command.rb b/lib/mattermost/command.rb
index 108a2a47a4b..7d4710bb94d 100644
--- a/lib/mattermost/command.rb
+++ b/lib/mattermost/command.rb
@@ -14,9 +14,13 @@ module Mattermost
         icon_url: icon_url
       }
 
-      response = post( "/teams/#{team_id}/commands/create", body: command.to_json)
+      post_command(command)['token']
+    end
+
+    private
 
-      response.parsed_response['token']
+    def post_command(command)
+      post( "/teams/#{team_id}/commands/create", body: command.to_json).parsed_response
     end
   end
 end
diff --git a/lib/mattermost/team.rb b/lib/mattermost/team.rb
index 54d029cb022..714748aea3c 100644
--- a/lib/mattermost/team.rb
+++ b/lib/mattermost/team.rb
@@ -1,17 +1,21 @@
 module Mattermost
   class Team < Session
     def self.team_admin
-      body = get('/users/initial_load').parsed_response
+      return [] unless initial_load['team_members']
 
-      return [] unless body['team_members']
-
-      team_ids = body['team_members'].map do |team|
+      team_ids = initial_load['team_members'].map do |team|
         team['team_id'] if team['roles'].split.include?('team_admin')
       end.compact
 
-      body['teams'].select do |team|
+      initial_load['teams'].select do |team|
         team_ids.include?(team['id'])
       end
     end
+
+    private
+
+    def initial_load
+      @initial_load ||= get('/users/initial_load').parsed_response
+    end
   end
 end
diff --git a/spec/fixtures/mattermost_initial_load.json b/spec/fixtures/mattermost_initial_load.json
new file mode 100644
index 00000000000..89e35f8ff15
--- /dev/null
+++ b/spec/fixtures/mattermost_initial_load.json
@@ -0,0 +1 @@
+{"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}
diff --git a/spec/fixtures/mattermost_new_command.json b/spec/fixtures/mattermost_new_command.json
new file mode 100644
index 00000000000..4b827f19926
--- /dev/null
+++ b/spec/fixtures/mattermost_new_command.json
@@ -0,0 +1 @@
+{"id":"y8j1nexrdirj5nubq5uzdwwidr","token":"pzajm5hfbtni3r49ujpt8betpc","create_at":1481897117122,"update_at":1481897117122,"delete_at":0,"creator_id":"78nm4euoc7dypergdc13ekxgpo","team_id":"w59qt5a817f69jkxdz6xe7y4ir","trigger":"display","method":"P","username":"GitLab","icon_url":"","auto_complete":false,"auto_complete_desc":"","auto_complete_hint":"","display_name":"Display name","description":"the description","url":"http://trigger.url/trigger"}
diff --git a/spec/lib/mattermost/command_spec.rb b/spec/lib/mattermost/command_spec.rb
new file mode 100644
index 00000000000..7c6457f639d
--- /dev/null
+++ b/spec/lib/mattermost/command_spec.rb
@@ -0,0 +1,17 @@
+require 'spec_helper'
+
+describe Mattermost::Command do
+  describe '.create' do
+    let(:new_command) do
+      JSON.parse(File.read(Rails.root.join('spec/fixtures/', 'mattermost_new_command.json')))
+    end
+
+    it 'gets the teams' do
+      allow(described_class).to receive(:post_command).and_return(new_command)
+
+      token = described_class.create('abc', url: 'http://trigger.url/trigger', icon_url: 'http://myicon.com/icon.png')
+
+      expect(token).to eq('pzajm5hfbtni3r49ujpt8betpc')
+    end
+  end
+end
diff --git a/spec/lib/mattermost/team_spec.rb b/spec/lib/mattermost/team_spec.rb
index a3b0831659f..0fe6163900d 100644
--- a/spec/lib/mattermost/team_spec.rb
+++ b/spec/lib/mattermost/team_spec.rb
@@ -1,19 +1,22 @@
 require 'spec_helper'
 
 describe Mattermost::Team do
-  let(:session) { Mattermost::Session.new('http://localhost:8065/', nil) }
+  describe '.team_admin' do
+    let(:init_load) do
+      JSON.parse(File.read(Rails.root.join('spec/fixtures/', 'mattermost_initial_load.json')))
+    end
 
-  describe '.all' do
-    let(:result)  { {id: 'abc', display_name: 'team'} }
     before do
-      WebMock.stub_request(:get, 'http://localhost:8065/api/v3/teams/all').
-        and_return({ abc: result }.to_json)
+      allow(described_class).to receive(:initial_load).and_return(init_load)
     end
 
-    xit 'gets the teams' do
-      allow(session).to receive(:with_session) { yield }
+    it 'gets the teams' do
+      expect(described_class.team_admin.count).to be(2)
+    end
 
-      expect(described_class.all).to eq(result)
+    it 'filters on being team admin' do
+      ids = described_class.team_admin.map { |team| team['id'] }
+      expect(ids).to include("w59qt5a817f69jkxdz6xe7y4ir", "my9oujxf5jy1zqdgu9rihd66do")
     end
   end
 end
diff --git a/spec/models/project_services/mattermost_slash_commands_service_spec.rb b/spec/models/project_services/mattermost_slash_commands_service_spec.rb
index 4a1037e950b..43b2c2c1302 100644
--- a/spec/models/project_services/mattermost_slash_commands_service_spec.rb
+++ b/spec/models/project_services/mattermost_slash_commands_service_spec.rb
@@ -96,4 +96,35 @@ describe MattermostSlashCommandsService, models: true do
       end
     end
   end
+
+  describe '#configure' do
+    let(:project) { create(:empty_project) }
+    let(:service) { project.build_mattermost_slash_commands_service }
+
+    subject do
+      service.configure('http://localhost:8065', nil, team_id: 'abc', trigger: 'gitlab', url: 'http://trigger.url', icon_url: 'http://icon.url/icon.png')
+    end
+
+    it 'creates a new Mattermost session' do
+      expect_any_instance_of(Mattermost::Session).to receive(:with_session)
+
+      subject
+    end
+
+    it 'saves the service' do
+      allow_any_instance_of(Mattermost::Session).to receive(:with_session).
+        and_return('mynewtoken')
+
+      expect { subject }.to change { project.services.count }.by(1)
+    end
+
+    it 'saves the token' do
+      allow_any_instance_of(Mattermost::Session).to receive(:with_session).
+        and_return('mynewtoken')
+
+      subject
+
+      expect(service.reload.token).to eq('mynewtoken')
+    end
+  end
 end
-- 
GitLab