Commit 83c727c550b1d07a8b9fd6313a258ca6c32a7d2e
Exists in
master
and in
4 other branches
Merge pull request #5216 from bladealslayer/feature/flowdock_integration
Added Flowdock integration support via a service.
Showing
7 changed files
with
129 additions
and
1 deletions
Show diff stats
Gemfile
| @@ -111,6 +111,9 @@ gem 'tinder', '~> 1.9.2' | @@ -111,6 +111,9 @@ gem 'tinder', '~> 1.9.2' | ||
| 111 | # HipChat integration | 111 | # HipChat integration |
| 112 | gem "hipchat", "~> 0.9.0" | 112 | gem "hipchat", "~> 0.9.0" |
| 113 | 113 | ||
| 114 | +# Flowdock integration | ||
| 115 | +gem "gitlab-flowdock-git-hook", "~> 0.4.2" | ||
| 116 | + | ||
| 114 | # d3 | 117 | # d3 |
| 115 | gem "d3_rails", "~> 3.1.4" | 118 | gem "d3_rails", "~> 3.1.4" |
| 116 | 119 |
Gemfile.lock
| @@ -156,6 +156,9 @@ GEM | @@ -156,6 +156,9 @@ GEM | ||
| 156 | pygments.rb (>= 0.2.13) | 156 | pygments.rb (>= 0.2.13) |
| 157 | github-markdown (0.5.3) | 157 | github-markdown (0.5.3) |
| 158 | github-markup (0.7.5) | 158 | github-markup (0.7.5) |
| 159 | + gitlab-flowdock-git-hook (0.4.2.2) | ||
| 160 | + gitlab-grit (>= 2.4.1) | ||
| 161 | + multi_json | ||
| 159 | gitlab-gollum-lib (1.0.1) | 162 | gitlab-gollum-lib (1.0.1) |
| 160 | github-markdown (~> 0.5.3) | 163 | github-markdown (~> 0.5.3) |
| 161 | github-markup (>= 0.7.5, < 1.0.0) | 164 | github-markup (>= 0.7.5, < 1.0.0) |
| @@ -571,6 +574,7 @@ DEPENDENCIES | @@ -571,6 +574,7 @@ DEPENDENCIES | ||
| 571 | gemoji (~> 1.2.1) | 574 | gemoji (~> 1.2.1) |
| 572 | github-linguist | 575 | github-linguist |
| 573 | github-markup (~> 0.7.4) | 576 | github-markup (~> 0.7.4) |
| 577 | + gitlab-flowdock-git-hook (~> 0.4.2) | ||
| 574 | gitlab-gollum-lib (~> 1.0.1) | 578 | gitlab-gollum-lib (~> 1.0.1) |
| 575 | gitlab-grack (~> 1.0.1) | 579 | gitlab-grack (~> 1.0.1) |
| 576 | gitlab-pygments.rb (~> 0.3.2) | 580 | gitlab-pygments.rb (~> 0.3.2) |
| @@ -0,0 +1,52 @@ | @@ -0,0 +1,52 @@ | ||
| 1 | +# == Schema Information | ||
| 2 | +# | ||
| 3 | +# Table name: services | ||
| 4 | +# | ||
| 5 | +# id :integer not null, primary key | ||
| 6 | +# type :string(255) | ||
| 7 | +# title :string(255) | ||
| 8 | +# token :string(255) | ||
| 9 | +# project_id :integer not null | ||
| 10 | +# created_at :datetime not null | ||
| 11 | +# updated_at :datetime not null | ||
| 12 | +# active :boolean default(FALSE), not null | ||
| 13 | +# project_url :string(255) | ||
| 14 | +# | ||
| 15 | + | ||
| 16 | +require "flowdock-git-hook" | ||
| 17 | + | ||
| 18 | +class FlowdockService < Service | ||
| 19 | + validates :token, presence: true, if: :activated? | ||
| 20 | + | ||
| 21 | + def title | ||
| 22 | + 'Flowdock' | ||
| 23 | + end | ||
| 24 | + | ||
| 25 | + def description | ||
| 26 | + 'Flowdock is a collaboration web app for technical teams.' | ||
| 27 | + end | ||
| 28 | + | ||
| 29 | + def to_param | ||
| 30 | + 'flowdock' | ||
| 31 | + end | ||
| 32 | + | ||
| 33 | + def fields | ||
| 34 | + [ | ||
| 35 | + { type: 'text', name: 'token', placeholder: '' } | ||
| 36 | + ] | ||
| 37 | + end | ||
| 38 | + | ||
| 39 | + def execute(push_data) | ||
| 40 | + repo_path = File.join(Gitlab.config.gitlab_shell.repos_path, "#{project.path_with_namespace}.git") | ||
| 41 | + Flowdock::Git.post( | ||
| 42 | + push_data[:ref], | ||
| 43 | + push_data[:before], | ||
| 44 | + push_data[:after], | ||
| 45 | + token: token, | ||
| 46 | + repo: repo_path, | ||
| 47 | + repo_url: "#{Gitlab.config.gitlab.url}/#{project.path_with_namespace}", | ||
| 48 | + commit_url: "#{Gitlab.config.gitlab.url}/#{project.path_with_namespace}/commit/%s", | ||
| 49 | + diff_url: "#{Gitlab.config.gitlab.url}/#{project.path_with_namespace}/compare/%s...%s", | ||
| 50 | + ) | ||
| 51 | + end | ||
| 52 | +end |
app/models/project.rb
| @@ -46,6 +46,7 @@ class Project < ActiveRecord::Base | @@ -46,6 +46,7 @@ class Project < ActiveRecord::Base | ||
| 46 | has_one :campfire_service, dependent: :destroy | 46 | has_one :campfire_service, dependent: :destroy |
| 47 | has_one :pivotaltracker_service, dependent: :destroy | 47 | has_one :pivotaltracker_service, dependent: :destroy |
| 48 | has_one :hipchat_service, dependent: :destroy | 48 | has_one :hipchat_service, dependent: :destroy |
| 49 | + has_one :flowdock_service, dependent: :destroy | ||
| 49 | has_one :forked_project_link, dependent: :destroy, foreign_key: "forked_to_project_id" | 50 | has_one :forked_project_link, dependent: :destroy, foreign_key: "forked_to_project_id" |
| 50 | has_one :forked_from_project, through: :forked_project_link | 51 | has_one :forked_from_project, through: :forked_project_link |
| 51 | 52 | ||
| @@ -219,7 +220,7 @@ class Project < ActiveRecord::Base | @@ -219,7 +220,7 @@ class Project < ActiveRecord::Base | ||
| 219 | end | 220 | end |
| 220 | 221 | ||
| 221 | def available_services_names | 222 | def available_services_names |
| 222 | - %w(gitlab_ci campfire hipchat pivotaltracker) | 223 | + %w(gitlab_ci campfire hipchat pivotaltracker flowdock) |
| 223 | end | 224 | end |
| 224 | 225 | ||
| 225 | def gitlab_ci? | 226 | def gitlab_ci? |
features/project/service.feature
| @@ -24,3 +24,9 @@ Feature: Project Services | @@ -24,3 +24,9 @@ Feature: Project Services | ||
| 24 | And I click pivotaltracker service link | 24 | And I click pivotaltracker service link |
| 25 | And I fill pivotaltracker settings | 25 | And I fill pivotaltracker settings |
| 26 | Then I should see pivotaltracker service settings saved | 26 | Then I should see pivotaltracker service settings saved |
| 27 | + | ||
| 28 | + Scenario: Activate Flowdock service | ||
| 29 | + When I visit project "Shop" services page | ||
| 30 | + And I click Flowdock service link | ||
| 31 | + And I fill Flowdock settings | ||
| 32 | + Then I should see Flowdock service settings saved |
features/steps/project/project_services.rb
| @@ -58,4 +58,18 @@ class ProjectServices < Spinach::FeatureSteps | @@ -58,4 +58,18 @@ class ProjectServices < Spinach::FeatureSteps | ||
| 58 | Then 'I should see pivotaltracker service settings saved' do | 58 | Then 'I should see pivotaltracker service settings saved' do |
| 59 | find_field('Token').value.should == 'verySecret' | 59 | find_field('Token').value.should == 'verySecret' |
| 60 | end | 60 | end |
| 61 | + | ||
| 62 | + And 'I click Flowdock service link' do | ||
| 63 | + click_link 'Flowdock' | ||
| 64 | + end | ||
| 65 | + | ||
| 66 | + And 'I fill Flowdock settings' do | ||
| 67 | + check 'Active' | ||
| 68 | + fill_in 'Token', with: 'verySecret' | ||
| 69 | + click_button 'Save' | ||
| 70 | + end | ||
| 71 | + | ||
| 72 | + Then 'I should see Flowdock service settings saved' do | ||
| 73 | + find_field('Token').value.should == 'verySecret' | ||
| 74 | + end | ||
| 61 | end | 75 | end |
| @@ -0,0 +1,48 @@ | @@ -0,0 +1,48 @@ | ||
| 1 | +# == Schema Information | ||
| 2 | +# | ||
| 3 | +# Table name: services | ||
| 4 | +# | ||
| 5 | +# id :integer not null, primary key | ||
| 6 | +# type :string(255) | ||
| 7 | +# title :string(255) | ||
| 8 | +# token :string(255) | ||
| 9 | +# project_id :integer not null | ||
| 10 | +# created_at :datetime not null | ||
| 11 | +# updated_at :datetime not null | ||
| 12 | +# active :boolean default(FALSE), not null | ||
| 13 | +# project_url :string(255) | ||
| 14 | +# | ||
| 15 | + | ||
| 16 | +require 'spec_helper' | ||
| 17 | + | ||
| 18 | +describe FlowdockService do | ||
| 19 | + describe "Associations" do | ||
| 20 | + it { should belong_to :project } | ||
| 21 | + it { should have_one :service_hook } | ||
| 22 | + end | ||
| 23 | + | ||
| 24 | + describe "Execute" do | ||
| 25 | + let(:user) { create(:user) } | ||
| 26 | + let(:project) { create(:project_with_code) } | ||
| 27 | + | ||
| 28 | + before do | ||
| 29 | + @flowdock_service = FlowdockService.new | ||
| 30 | + @flowdock_service.stub( | ||
| 31 | + project_id: project.id, | ||
| 32 | + project: project, | ||
| 33 | + service_hook: true, | ||
| 34 | + token: 'verySecret' | ||
| 35 | + ) | ||
| 36 | + @sample_data = GitPushService.new.sample_data(project, user) | ||
| 37 | + @api_url = 'https://api.flowdock.com/v1/git/verySecret' | ||
| 38 | + WebMock.stub_request(:post, @api_url) | ||
| 39 | + end | ||
| 40 | + | ||
| 41 | + it "should call FlowDock API" do | ||
| 42 | + @flowdock_service.execute(@sample_data) | ||
| 43 | + WebMock.should have_requested(:post, @api_url).with( | ||
| 44 | + body: /#{@sample_data[:before]}.*#{@sample_data[:after]}.*#{project.path}/ | ||
| 45 | + ).once | ||
| 46 | + end | ||
| 47 | + end | ||
| 48 | +end |