Add Pushover service integration
That introduce select field type for services options.
This commit is contained in:
parent
43217dd5dd
commit
d1fa3b336d
9 changed files with 223 additions and 2 deletions
|
@ -15,6 +15,8 @@ v 7.4.0
|
|||
- Zen mode for wiki and milestones (Robert Schilling)
|
||||
- Move Emoji parsing to html-pipeline-gitlab (Robert Schilling)
|
||||
- Font Awesome 4.2 integration (Sullivan Senechal)
|
||||
- Add Pushover service integration (Sullivan Senechal)
|
||||
- Add select field type for services options (Sullivan Senechal)
|
||||
|
||||
v 7.3.2
|
||||
- Fix creating new file via web editor
|
||||
|
|
|
@ -40,7 +40,8 @@ class Projects::ServicesController < Projects::ApplicationController
|
|||
def service_params
|
||||
params.require(:service).permit(
|
||||
:title, :token, :type, :active, :api_key, :subdomain,
|
||||
:room, :recipients, :project_url
|
||||
:room, :recipients, :project_url,
|
||||
:user_key, :device, :priority, :sound
|
||||
)
|
||||
end
|
||||
end
|
||||
|
|
|
@ -64,6 +64,7 @@ class Project < ActiveRecord::Base
|
|||
has_one :assembla_service, dependent: :destroy
|
||||
has_one :gemnasium_service, dependent: :destroy
|
||||
has_one :slack_service, dependent: :destroy
|
||||
has_one :pushover_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
|
||||
# Merge Requests for target project should be removed with it
|
||||
|
@ -311,7 +312,7 @@ class Project < ActiveRecord::Base
|
|||
end
|
||||
|
||||
def available_services_names
|
||||
%w(gitlab_ci campfire hipchat pivotaltracker flowdock assembla emails_on_push gemnasium slack)
|
||||
%w(gitlab_ci campfire hipchat pivotaltracker flowdock assembla emails_on_push gemnasium slack pushover)
|
||||
end
|
||||
|
||||
def gitlab_ci?
|
||||
|
|
113
app/models/project_services/pushover_service.rb
Normal file
113
app/models/project_services/pushover_service.rb
Normal file
|
@ -0,0 +1,113 @@
|
|||
# == Schema Information
|
||||
#
|
||||
# Table name: services
|
||||
#
|
||||
# id :integer not null, primary key
|
||||
# type :string(255)
|
||||
# title :string(255)
|
||||
# project_id :integer not null
|
||||
# created_at :datetime
|
||||
# updated_at :datetime
|
||||
# active :boolean default(FALSE), not null
|
||||
# properties :text
|
||||
#
|
||||
|
||||
class PushoverService < Service
|
||||
include HTTParty
|
||||
base_uri 'https://api.pushover.net/1'
|
||||
|
||||
prop_accessor :api_key, :user_key, :device, :priority, :sound
|
||||
validates :api_key, :user_key, :priority, presence: true, if: :activated?
|
||||
|
||||
def title
|
||||
'Pushover'
|
||||
end
|
||||
|
||||
def description
|
||||
'Pushover makes it easy to get real-time notifications on your Android device, iPhone, iPad, and Desktop.'
|
||||
end
|
||||
|
||||
def to_param
|
||||
'pushover'
|
||||
end
|
||||
|
||||
def fields
|
||||
[
|
||||
{ type: 'text', name: 'api_key', placeholder: 'Your application key' },
|
||||
{ type: 'text', name: 'user_key', placeholder: 'Your user key' },
|
||||
{ type: 'text', name: 'device', placeholder: 'Leave blank for all active devices' },
|
||||
{ type: 'select', name: 'priority', choices:
|
||||
[
|
||||
['Lowest Priority', -2],
|
||||
['Low Priority', -1],
|
||||
['Normal Priority', 0],
|
||||
['High Priority', 1]
|
||||
],
|
||||
default_choice: 0
|
||||
},
|
||||
{ type: 'select', name: 'sound', choices:
|
||||
[
|
||||
['Device default sound', nil],
|
||||
['Pushover (default)', 'pushover'],
|
||||
['Bike', 'bike'],
|
||||
['Bugle', 'bugle'],
|
||||
['Cash Register', 'cashregister'],
|
||||
['Classical', 'classical'],
|
||||
['Cosmic', 'cosmic'],
|
||||
['Falling', 'falling'],
|
||||
['Gamelan', 'gamelan'],
|
||||
['Incoming', 'incoming'],
|
||||
['Intermission', 'intermission'],
|
||||
['Magic', 'magic'],
|
||||
['Mechanical', 'mechanical'],
|
||||
['Piano Bar', 'pianobar'],
|
||||
['Siren', 'siren'],
|
||||
['Space Alarm', 'spacealarm'],
|
||||
['Tug Boat', 'tugboat'],
|
||||
['Alien Alarm (long)', 'alien'],
|
||||
['Climb (long)', 'climb'],
|
||||
['Persistent (long)', 'persistent'],
|
||||
['Pushover Echo (long)', 'echo'],
|
||||
['Up Down (long)', 'updown'],
|
||||
['None (silent)', 'none']
|
||||
]
|
||||
},
|
||||
]
|
||||
end
|
||||
|
||||
def execute(push_data)
|
||||
ref = push_data[:ref].gsub('refs/heads/', '')
|
||||
before = push_data[:before]
|
||||
after = push_data[:after]
|
||||
|
||||
if before =~ /000000/
|
||||
message = "#{push_data[:user_name]} pushed new branch \"#{ref}\"."
|
||||
elsif after =~ /000000/
|
||||
message = "#{push_data[:user_name]} deleted branch \"#{ref}\"."
|
||||
else
|
||||
message = "#{push_data[:user_name]} push to branch \"#{ref}\"."
|
||||
end
|
||||
|
||||
if push_data[:total_commits_count] > 0
|
||||
message << "\nTotal commits count: #{push_data[:total_commits_count]}"
|
||||
end
|
||||
|
||||
pushover_data = {
|
||||
token: api_key,
|
||||
user: user_key,
|
||||
device: device,
|
||||
priority: priority,
|
||||
title: "#{project.name_with_namespace}",
|
||||
message: message,
|
||||
url: push_data[:repository][:homepage],
|
||||
url_title: "See project #{project.name_with_namespace}"
|
||||
}
|
||||
|
||||
# Sound parameter MUST NOT be sent to API if not selected
|
||||
if sound
|
||||
pushover_data.merge!(sound: sound)
|
||||
end
|
||||
|
||||
PushoverService.post('/messages.json', body: pushover_data)
|
||||
end
|
||||
end
|
|
@ -28,8 +28,11 @@
|
|||
|
||||
- @service.fields.each do |field|
|
||||
- name = field[:name]
|
||||
- value = @service.send(name)
|
||||
- type = field[:type]
|
||||
- placeholder = field[:placeholder]
|
||||
- choices = field[:choices]
|
||||
- default_choice = field[:default_choice]
|
||||
|
||||
.form-group
|
||||
= f.label name, class: "control-label"
|
||||
|
@ -40,6 +43,8 @@
|
|||
= f.text_area name, rows: 5, class: "form-control", placeholder: placeholder
|
||||
- elsif type == 'checkbox'
|
||||
= f.check_box name
|
||||
- elsif type == 'select'
|
||||
= f.select name, options_for_select(choices, value ? value : default_choice), {}, { class: "form-control" }
|
||||
|
||||
.form-actions
|
||||
= f.submit 'Save', class: 'btn btn-save'
|
||||
|
|
|
@ -43,6 +43,12 @@ Feature: Project Services
|
|||
And I fill Slack settings
|
||||
Then I should see Slack service settings saved
|
||||
|
||||
Scenario: Activate Pushover service
|
||||
When I visit project "Shop" services page
|
||||
And I click Pushover service link
|
||||
And I fill Pushover settings
|
||||
Then I should see Pushover service settings saved
|
||||
|
||||
Scenario: Activate email on push service
|
||||
When I visit project "Shop" services page
|
||||
And I click email on push service link
|
||||
|
|
|
@ -13,6 +13,7 @@ class Spinach::Features::ProjectServices < Spinach::FeatureSteps
|
|||
page.should have_content 'Hipchat'
|
||||
page.should have_content 'GitLab CI'
|
||||
page.should have_content 'Assembla'
|
||||
page.should have_content 'Pushover'
|
||||
end
|
||||
|
||||
step 'I click gitlab-ci service link' do
|
||||
|
@ -118,4 +119,26 @@ class Spinach::Features::ProjectServices < Spinach::FeatureSteps
|
|||
find_field('Room').value.should == '#gitlab'
|
||||
find_field('Token').value.should == 'verySecret'
|
||||
end
|
||||
|
||||
step 'I click Pushover service link' do
|
||||
click_link 'Pushover'
|
||||
end
|
||||
|
||||
step 'I fill Pushover settings' do
|
||||
check 'Active'
|
||||
fill_in 'Api key', with: 'verySecret'
|
||||
fill_in 'User key', with: 'verySecret'
|
||||
fill_in 'Device', with: 'myDevice'
|
||||
select 'High Priority', from: 'Priority'
|
||||
select 'Bike', from: 'Sound'
|
||||
click_button 'Save'
|
||||
end
|
||||
|
||||
step 'I should see Pushover service settings saved' do
|
||||
find_field('Api key').value.should == 'verySecret'
|
||||
find_field('User key').value.should == 'verySecret'
|
||||
find_field('Device').value.should == 'myDevice'
|
||||
find_field('Priority').find('option[selected]').value.should == '1'
|
||||
find_field('Sound').find('option[selected]').value.should == 'bike'
|
||||
end
|
||||
end
|
||||
|
|
|
@ -47,6 +47,7 @@ describe Project do
|
|||
it { should have_many(:protected_branches).dependent(:destroy) }
|
||||
it { should have_one(:forked_project_link).dependent(:destroy) }
|
||||
it { should have_one(:slack_service).dependent(:destroy) }
|
||||
it { should have_one(:pushover_service).dependent(:destroy) }
|
||||
end
|
||||
|
||||
describe "Mass assignment" do
|
||||
|
|
69
spec/models/pushover_service_spec.rb
Normal file
69
spec/models/pushover_service_spec.rb
Normal file
|
@ -0,0 +1,69 @@
|
|||
# == Schema Information
|
||||
#
|
||||
# Table name: services
|
||||
#
|
||||
# id :integer not null, primary key
|
||||
# type :string(255)
|
||||
# title :string(255)
|
||||
# project_id :integer not null
|
||||
# created_at :datetime
|
||||
# updated_at :datetime
|
||||
# active :boolean default(FALSE), not null
|
||||
# properties :text
|
||||
#
|
||||
|
||||
require 'spec_helper'
|
||||
|
||||
describe PushoverService do
|
||||
describe 'Associations' do
|
||||
it { should belong_to :project }
|
||||
it { should have_one :service_hook }
|
||||
end
|
||||
|
||||
describe 'Validations' do
|
||||
context 'active' do
|
||||
before do
|
||||
subject.active = true
|
||||
end
|
||||
|
||||
it { should validate_presence_of :api_key }
|
||||
it { should validate_presence_of :user_key }
|
||||
it { should validate_presence_of :priority }
|
||||
end
|
||||
end
|
||||
|
||||
describe 'Execute' do
|
||||
let(:pushover) { PushoverService.new }
|
||||
let(:user) { create(:user) }
|
||||
let(:project) { create(:project) }
|
||||
let(:sample_data) { GitPushService.new.sample_data(project, user) }
|
||||
|
||||
let(:api_key) { 'verySecret' }
|
||||
let(:user_key) { 'verySecret' }
|
||||
let(:device) { 'myDevice' }
|
||||
let(:priority) { 0 }
|
||||
let(:sound) { 'bike' }
|
||||
let(:api_url) { 'https://api.pushover.net/1/messages.json' }
|
||||
|
||||
before do
|
||||
pushover.stub(
|
||||
project: project,
|
||||
project_id: project.id,
|
||||
service_hook: true,
|
||||
api_key: api_key,
|
||||
user_key: user_key,
|
||||
device: device,
|
||||
priority: priority,
|
||||
sound: sound
|
||||
)
|
||||
|
||||
WebMock.stub_request(:post, api_url)
|
||||
end
|
||||
|
||||
it 'should call Pushover API' do
|
||||
pushover.execute(sample_data)
|
||||
|
||||
WebMock.should have_requested(:post, api_url).once
|
||||
end
|
||||
end
|
||||
end
|
Loading…
Reference in a new issue