From d8562cc9a141917e5b0adc1f33f2ec8da8ab10d4 Mon Sep 17 00:00:00 2001
From: Boyan Tabakov <boyan.tabakov@futurice.com>
Date: Mon, 19 Aug 2013 12:11:36 +0300
Subject: [PATCH] Added Flowdock integration support via a service.

Added test for the FlowdockService.
---
 Gemfile                                    |  3 ++
 Gemfile.lock                               |  8 ++++
 app/models/flowdock_service.rb             | 50 ++++++++++++++++++++++
 app/models/project.rb                      |  3 +-
 features/project/service.feature           |  6 +++
 features/steps/project/project_services.rb | 14 ++++++
 spec/models/flowdock_service_spec.rb       | 48 +++++++++++++++++++++
 7 files changed, 131 insertions(+), 1 deletion(-)
 create mode 100644 app/models/flowdock_service.rb
 create mode 100644 spec/models/flowdock_service_spec.rb

diff --git a/Gemfile b/Gemfile
index ccefe0af7a5..2d0a11de890 100644
--- a/Gemfile
+++ b/Gemfile
@@ -111,6 +111,9 @@ gem 'tinder', '~> 1.9.2'
 # HipChat integration
 gem "hipchat", "~> 0.9.0"
 
+# Flowdock integration
+gem "flowdock-git-hook", "~> 0.4.2"
+
 # d3
 gem "d3_rails", "~> 3.1.4"
 
diff --git a/Gemfile.lock b/Gemfile.lock
index 97a8129ed3d..319e19167d4 100644
--- a/Gemfile.lock
+++ b/Gemfile.lock
@@ -135,6 +135,9 @@ GEM
       faraday (>= 0.7.4, < 0.9)
     ffaker (1.18.0)
     ffi (1.9.0)
+    flowdock-git-hook (0.4.2)
+      grit (>= 2.4.1)
+      multi_json
     fog (1.3.1)
       builder
       excon (~> 0.13.0)
@@ -205,6 +208,10 @@ GEM
     grape-entity (0.3.0)
       activesupport
       multi_json (>= 1.3.2)
+    grit (2.5.0)
+      diff-lcs (~> 1.1)
+      mime-types (~> 1.15)
+      posix-spawn (~> 0.3.6)
     growl (1.0.3)
     guard (1.8.1)
       formatador (>= 0.2.4)
@@ -568,6 +575,7 @@ DEPENDENCIES
   enumerize
   factory_girl_rails
   ffaker
+  flowdock-git-hook (~> 0.4.2)
   fog (~> 1.3.1)
   font-awesome-rails
   foreman
diff --git a/app/models/flowdock_service.rb b/app/models/flowdock_service.rb
new file mode 100644
index 00000000000..143e986ca75
--- /dev/null
+++ b/app/models/flowdock_service.rb
@@ -0,0 +1,50 @@
+# == Schema Information
+#
+# Table name: services
+#
+#  id          :integer          not null, primary key
+#  type        :string(255)
+#  title       :string(255)
+#  token       :string(255)
+#  project_id  :integer          not null
+#  created_at  :datetime         not null
+#  updated_at  :datetime         not null
+#  active      :boolean          default(FALSE), not null
+#  project_url :string(255)
+#
+
+class FlowdockService < Service
+  validates :token, presence: true, if: :activated?
+
+  def title
+    'Flowdock'
+  end
+
+  def description
+    'Flowdock is a collaboration web app for technical teams.'
+  end
+
+  def to_param
+    'flowdock'
+  end
+
+  def fields
+    [
+      { type: 'text', name: 'token',     placeholder: '' }
+    ]
+  end
+
+  def execute(push_data)
+    repo_path = File.join(Gitlab.config.gitlab_shell.repos_path, "#{project.path_with_namespace}.git")
+    Flowdock::Git.post(
+      push_data[:ref],
+      push_data[:before],
+      push_data[:after],
+      token: token,
+      repo: repo_path,
+      repo_url: "#{Gitlab.config.gitlab.url}/#{project.path_with_namespace}",
+      commit_url: "#{Gitlab.config.gitlab.url}/#{project.path_with_namespace}/commit/%s",
+      diff_url: "#{Gitlab.config.gitlab.url}/#{project.path_with_namespace}/compare/%s...%s",
+      )
+  end
+end
diff --git a/app/models/project.rb b/app/models/project.rb
index c4f4b06713d..49802fa1720 100644
--- a/app/models/project.rb
+++ b/app/models/project.rb
@@ -48,6 +48,7 @@ class Project < ActiveRecord::Base
   has_one :campfire_service, dependent: :destroy
   has_one :pivotaltracker_service, dependent: :destroy
   has_one :hipchat_service, dependent: :destroy
+  has_one :flowdock_service, dependent: :destroy
   has_one :forked_project_link, dependent: :destroy, foreign_key: "forked_to_project_id"
   has_one :forked_from_project, through: :forked_project_link
 
@@ -221,7 +222,7 @@ class Project < ActiveRecord::Base
   end
 
   def available_services_names
-    %w(gitlab_ci campfire hipchat pivotaltracker)
+    %w(gitlab_ci campfire hipchat pivotaltracker flowdock)
   end
 
   def gitlab_ci?
diff --git a/features/project/service.feature b/features/project/service.feature
index e685c385d1d..4805d2befbe 100644
--- a/features/project/service.feature
+++ b/features/project/service.feature
@@ -24,3 +24,9 @@ Feature: Project Services
     And I click pivotaltracker service link
     And I fill pivotaltracker settings
     Then I should see pivotaltracker service settings saved
+
+  Scenario: Activate Flowdock service
+    When I visit project "Shop" services page
+    And I click Flowdock service link
+    And I fill Flowdock settings
+    Then I should see Flowdock service settings saved
diff --git a/features/steps/project/project_services.rb b/features/steps/project/project_services.rb
index a24100ff8c0..70eafc875d4 100644
--- a/features/steps/project/project_services.rb
+++ b/features/steps/project/project_services.rb
@@ -58,4 +58,18 @@ class ProjectServices < Spinach::FeatureSteps
   Then 'I should see pivotaltracker service settings saved' do
     find_field('Token').value.should == 'verySecret'
   end
+
+  And 'I click Flowdock service link' do
+    click_link 'Flowdock'
+  end
+
+  And 'I fill Flowdock settings' do
+    check 'Active'
+    fill_in 'Token', with: 'verySecret'
+    click_button 'Save'
+  end
+
+  Then 'I should see Flowdock service settings saved' do
+    find_field('Token').value.should == 'verySecret'
+  end
 end
diff --git a/spec/models/flowdock_service_spec.rb b/spec/models/flowdock_service_spec.rb
new file mode 100644
index 00000000000..b22193c9e93
--- /dev/null
+++ b/spec/models/flowdock_service_spec.rb
@@ -0,0 +1,48 @@
+# == Schema Information
+#
+# Table name: services
+#
+#  id          :integer          not null, primary key
+#  type        :string(255)
+#  title       :string(255)
+#  token       :string(255)
+#  project_id  :integer          not null
+#  created_at  :datetime         not null
+#  updated_at  :datetime         not null
+#  active      :boolean          default(FALSE), not null
+#  project_url :string(255)
+#
+
+require 'spec_helper'
+
+describe FlowdockService do
+  describe "Associations" do
+    it { should belong_to :project }
+    it { should have_one :service_hook }
+  end
+
+  describe "Execute" do
+    let(:user)    { create(:user) }
+    let(:project) { create(:project_with_code) }
+
+    before do
+      @flowdock_service = FlowdockService.new
+      @flowdock_service.stub(
+        project_id: project.id,
+        project: project,
+        service_hook: true,
+        token: 'verySecret'
+      )
+      @sample_data = GitPushService.new.sample_data(project, user)
+      @api_url = 'https://api.flowdock.com/v1/git/verySecret'
+      WebMock.stub_request(:post, @api_url)
+    end
+
+    it "should call FlowDock API" do
+      @flowdock_service.execute(@sample_data)
+      WebMock.should have_requested(:post, @api_url).with(
+        body: /#{@sample_data[:before]}.*#{@sample_data[:after]}.*#{project.path}/
+      ).once
+    end
+  end
+end
-- 
2.30.9