Commit c0bb3f5a authored by Dmitriy Zaporozhets's avatar Dmitriy Zaporozhets

Merge pull request #7931 from Soullivaneuh/pushover

Add Pushover service integration
parents 43217dd5 d1fa3b33
......@@ -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?
......
# == 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
......
# == 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
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