Merge branch 'add-irker-service' of https://github.com/Aorimn/gitlabhq into Aorimn-add-irker-service
Conflicts: app/controllers/projects/services_controller.rb
This commit is contained in:
commit
f00feb14ec
|
@ -14,6 +14,7 @@ v 7.9.0 (unreleased)
|
||||||
- Generalize image upload in drag and drop in markdown to all files (Hannes Rosenögger)
|
- Generalize image upload in drag and drop in markdown to all files (Hannes Rosenögger)
|
||||||
- Fix mass-unassignment of issues (Robert Speicher)
|
- Fix mass-unassignment of issues (Robert Speicher)
|
||||||
- Allow user confirmation to be skipped for new users via API
|
- Allow user confirmation to be skipped for new users via API
|
||||||
|
- Add a service to send updates to an Irker gateway (Romain Coltel)
|
||||||
|
|
||||||
v 7.8.1
|
v 7.8.1
|
||||||
- Fix run of custom post receive hooks
|
- Fix run of custom post receive hooks
|
||||||
|
|
|
@ -50,7 +50,8 @@ class Projects::ServicesController < Projects::ApplicationController
|
||||||
:room, :recipients, :project_url, :webhook,
|
:room, :recipients, :project_url, :webhook,
|
||||||
:user_key, :device, :priority, :sound, :bamboo_url, :username, :password,
|
:user_key, :device, :priority, :sound, :bamboo_url, :username, :password,
|
||||||
:build_key, :server, :teamcity_url, :build_type,
|
:build_key, :server, :teamcity_url, :build_type,
|
||||||
:description, :issues_url, :new_issue_url, :restrict_to_branch, :channel
|
:description, :issues_url, :new_issue_url, :restrict_to_branch, :channel,
|
||||||
|
:colorize_messages, :channels
|
||||||
)
|
)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -73,6 +73,7 @@ class Project < ActiveRecord::Base
|
||||||
has_one :gitlab_ci_service, dependent: :destroy
|
has_one :gitlab_ci_service, dependent: :destroy
|
||||||
has_one :campfire_service, dependent: :destroy
|
has_one :campfire_service, dependent: :destroy
|
||||||
has_one :emails_on_push_service, dependent: :destroy
|
has_one :emails_on_push_service, dependent: :destroy
|
||||||
|
has_one :irker_service, dependent: :destroy
|
||||||
has_one :pivotaltracker_service, dependent: :destroy
|
has_one :pivotaltracker_service, dependent: :destroy
|
||||||
has_one :hipchat_service, dependent: :destroy
|
has_one :hipchat_service, dependent: :destroy
|
||||||
has_one :flowdock_service, dependent: :destroy
|
has_one :flowdock_service, dependent: :destroy
|
||||||
|
|
|
@ -0,0 +1,152 @@
|
||||||
|
# == Schema Information
|
||||||
|
#
|
||||||
|
# Table name: services
|
||||||
|
#
|
||||||
|
# id :integer not null, primary key
|
||||||
|
# type :string(255)
|
||||||
|
# title :string(255)
|
||||||
|
# project_id :integer
|
||||||
|
# created_at :datetime
|
||||||
|
# updated_at :datetime
|
||||||
|
# active :boolean default(FALSE), not null
|
||||||
|
# properties :text
|
||||||
|
# template :boolean default(FALSE)
|
||||||
|
|
||||||
|
require 'uri'
|
||||||
|
|
||||||
|
class IrkerService < Service
|
||||||
|
prop_accessor :colorize_messages, :recipients, :channels
|
||||||
|
validates :recipients, presence: true, if: :activated?
|
||||||
|
validate :check_recipients_count, if: :activated?
|
||||||
|
|
||||||
|
before_validation :get_channels
|
||||||
|
after_initialize :initialize_settings
|
||||||
|
|
||||||
|
# Writer for RSpec tests
|
||||||
|
attr_writer :settings
|
||||||
|
|
||||||
|
def initialize_settings
|
||||||
|
# See the documentation (doc/project_services/irker.md) for possible values
|
||||||
|
# here
|
||||||
|
@settings ||= {
|
||||||
|
server_ip: 'localhost',
|
||||||
|
server_port: 6659,
|
||||||
|
max_channels: 3,
|
||||||
|
default_irc_uri: nil
|
||||||
|
}
|
||||||
|
end
|
||||||
|
|
||||||
|
def title
|
||||||
|
'Irker (IRC gateway)'
|
||||||
|
end
|
||||||
|
|
||||||
|
def description
|
||||||
|
'Send IRC messages, on update, to a list of recipients through an Irker '\
|
||||||
|
'gateway.'
|
||||||
|
end
|
||||||
|
|
||||||
|
def help
|
||||||
|
msg = 'Recipients have to be specified with a full URI: '\
|
||||||
|
'irc[s]://irc.network.net[:port]/#channel. Special cases: if you want '\
|
||||||
|
'the channel to be a nickname instead, append ",isnick" to the channel '\
|
||||||
|
'name; if the channel is protected by a secret password, append '\
|
||||||
|
'"?key=secretpassword" to the URI.'
|
||||||
|
|
||||||
|
unless @settings[:default_irc].nil?
|
||||||
|
msg += ' Note that a default IRC URI is provided by this service\'s '\
|
||||||
|
"administrator: #{default_irc}. You can thus just give a channel name."
|
||||||
|
end
|
||||||
|
msg
|
||||||
|
end
|
||||||
|
|
||||||
|
def to_param
|
||||||
|
'irker'
|
||||||
|
end
|
||||||
|
|
||||||
|
def execute(push_data)
|
||||||
|
IrkerWorker.perform_async(project_id, channels,
|
||||||
|
colorize_messages, push_data, @settings)
|
||||||
|
end
|
||||||
|
|
||||||
|
def fields
|
||||||
|
[
|
||||||
|
{ type: 'textarea', name: 'recipients',
|
||||||
|
placeholder: 'Recipients/channels separated by whitespaces' },
|
||||||
|
{ type: 'checkbox', name: 'colorize_messages' },
|
||||||
|
]
|
||||||
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
|
||||||
|
def check_recipients_count
|
||||||
|
return true if recipients.nil? || recipients.empty?
|
||||||
|
|
||||||
|
if recipients.split(/\s+/).count > max_chans
|
||||||
|
errors.add(:recipients, "are limited to #{max_chans}")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def max_chans
|
||||||
|
@settings[:max_channels]
|
||||||
|
end
|
||||||
|
|
||||||
|
def get_channels
|
||||||
|
return true unless :activated?
|
||||||
|
return true if recipients.nil? || recipients.empty?
|
||||||
|
|
||||||
|
map_recipients
|
||||||
|
|
||||||
|
errors.add(:recipients, 'are all invalid') if channels.empty?
|
||||||
|
true
|
||||||
|
end
|
||||||
|
|
||||||
|
def map_recipients
|
||||||
|
self.channels = recipients.split(/\s+/).map do |recipient|
|
||||||
|
format_channel default_irc_uri, recipient
|
||||||
|
end
|
||||||
|
channels.reject! &:nil?
|
||||||
|
end
|
||||||
|
|
||||||
|
def default_irc_uri
|
||||||
|
default_irc = @settings[:default_irc_uri]
|
||||||
|
if !(default_irc.nil? || default_irc[-1] == '/')
|
||||||
|
default_irc += '/'
|
||||||
|
end
|
||||||
|
default_irc
|
||||||
|
end
|
||||||
|
|
||||||
|
def format_channel(default_irc, recipient)
|
||||||
|
cnt = 0
|
||||||
|
url = nil
|
||||||
|
|
||||||
|
# Try to parse the chan as a full URI
|
||||||
|
begin
|
||||||
|
uri = URI.parse(recipient)
|
||||||
|
raise URI::InvalidURIError if uri.scheme.nil? && cnt == 0
|
||||||
|
rescue URI::InvalidURIError
|
||||||
|
unless default_irc.nil?
|
||||||
|
cnt += 1
|
||||||
|
recipient = "#{default_irc}#{recipient}"
|
||||||
|
retry if cnt == 1
|
||||||
|
end
|
||||||
|
else
|
||||||
|
url = consider_uri uri
|
||||||
|
end
|
||||||
|
url
|
||||||
|
end
|
||||||
|
|
||||||
|
def consider_uri(uri)
|
||||||
|
# Authorize both irc://domain.com/#chan and irc://domain.com/chan
|
||||||
|
if uri.is_a?(URI) && uri.scheme[/^ircs?$/] && !uri.path.nil?
|
||||||
|
# Do not authorize irc://domain.com/
|
||||||
|
if uri.fragment.nil? && uri.path.length > 1
|
||||||
|
uri.to_s
|
||||||
|
else
|
||||||
|
# Authorize irc://domain.com/smthg#chan
|
||||||
|
# The irker daemon will deal with it by concatenating smthg and
|
||||||
|
# chan, thus sending messages on #smthgchan
|
||||||
|
uri.to_s
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
|
@ -100,7 +100,8 @@ class Service < ActiveRecord::Base
|
||||||
|
|
||||||
def self.available_services_names
|
def self.available_services_names
|
||||||
%w(gitlab_ci campfire hipchat pivotaltracker flowdock assembla asana
|
%w(gitlab_ci campfire hipchat pivotaltracker flowdock assembla asana
|
||||||
emails_on_push gemnasium slack pushover buildbox bamboo teamcity jira redmine custom_issue_tracker)
|
emails_on_push gemnasium slack pushover buildbox bamboo teamcity jira
|
||||||
|
redmine custom_issue_tracker irker)
|
||||||
end
|
end
|
||||||
|
|
||||||
def self.create_from_template(project_id, template)
|
def self.create_from_template(project_id, template)
|
||||||
|
|
|
@ -0,0 +1,169 @@
|
||||||
|
require 'json'
|
||||||
|
require 'socket'
|
||||||
|
|
||||||
|
class IrkerWorker
|
||||||
|
include Sidekiq::Worker
|
||||||
|
|
||||||
|
def perform(project_id, chans, colors, push_data, settings)
|
||||||
|
project = Project.find(project_id)
|
||||||
|
|
||||||
|
# Get config parameters
|
||||||
|
return false unless init_perform settings, chans, colors
|
||||||
|
|
||||||
|
repo_name = push_data['repository']['name']
|
||||||
|
committer = push_data['user_name']
|
||||||
|
branch = push_data['ref'].gsub(%r'refs/[^/]*/', '')
|
||||||
|
|
||||||
|
if @colors
|
||||||
|
repo_name = "\x0304#{repo_name}\x0f"
|
||||||
|
branch = "\x0305#{branch}\x0f"
|
||||||
|
end
|
||||||
|
|
||||||
|
# Firsts messages are for branch creation/deletion
|
||||||
|
send_branch_updates push_data, project, repo_name, committer, branch
|
||||||
|
|
||||||
|
# Next messages are for commits
|
||||||
|
send_commits push_data, project, repo_name, committer, branch
|
||||||
|
|
||||||
|
close_connection
|
||||||
|
true
|
||||||
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
|
||||||
|
def init_perform(set, chans, colors)
|
||||||
|
@colors = colors
|
||||||
|
@channels = chans
|
||||||
|
start_connection set['server_ip'], set['server_port']
|
||||||
|
end
|
||||||
|
|
||||||
|
def start_connection(irker_server, irker_port)
|
||||||
|
begin
|
||||||
|
@socket = TCPSocket.new irker_server, irker_port
|
||||||
|
rescue Errno::ECONNREFUSED => e
|
||||||
|
logger.fatal "Can't connect to Irker daemon: #{e}"
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
true
|
||||||
|
end
|
||||||
|
|
||||||
|
def sendtoirker(privmsg)
|
||||||
|
to_send = { to: @channels, privmsg: privmsg }
|
||||||
|
@socket.puts JSON.dump(to_send)
|
||||||
|
end
|
||||||
|
|
||||||
|
def close_connection
|
||||||
|
@socket.close
|
||||||
|
end
|
||||||
|
|
||||||
|
def send_branch_updates(push_data, project, repo_name, committer, branch)
|
||||||
|
if push_data['before'] =~ /^000000/
|
||||||
|
send_new_branch project, repo_name, committer, branch
|
||||||
|
elsif push_data['after'] =~ /^000000/
|
||||||
|
send_del_branch repo_name, committer, branch
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def send_new_branch(project, repo_name, committer, branch)
|
||||||
|
repo_path = project.path_with_namespace
|
||||||
|
newbranch = "#{Gitlab.config.gitlab.url}/#{repo_path}/branches"
|
||||||
|
newbranch = "\x0302\x1f#{newbranch}\x0f" if @colors
|
||||||
|
|
||||||
|
privmsg = "[#{repo_name}] #{committer} has created a new branch "
|
||||||
|
privmsg += "#{branch}: #{newbranch}"
|
||||||
|
sendtoirker privmsg
|
||||||
|
end
|
||||||
|
|
||||||
|
def send_del_branch(repo_name, committer, branch)
|
||||||
|
privmsg = "[#{repo_name}] #{committer} has deleted the branch #{branch}"
|
||||||
|
sendtoirker privmsg
|
||||||
|
end
|
||||||
|
|
||||||
|
def send_commits(push_data, project, repo_name, committer, branch)
|
||||||
|
return if push_data['total_commits_count'] == 0
|
||||||
|
|
||||||
|
# Next message is for number of commit pushed, if any
|
||||||
|
if push_data['before'] =~ /^000000/
|
||||||
|
# Tweak on push_data["before"] in order to have a nice compare URL
|
||||||
|
push_data['before'] = before_on_new_branch push_data, project
|
||||||
|
end
|
||||||
|
|
||||||
|
send_commits_count(push_data, project, repo_name, committer, branch)
|
||||||
|
|
||||||
|
# One message per commit, limited by 3 messages (same limit as the
|
||||||
|
# github irc hook)
|
||||||
|
commits = push_data['commits'].first(3)
|
||||||
|
commits.each do |hook_attrs|
|
||||||
|
send_one_commit project, hook_attrs, repo_name, branch
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def before_on_new_branch(push_data, project)
|
||||||
|
commit = commit_from_id project, push_data['commits'][0]['id']
|
||||||
|
parents = commit.parents
|
||||||
|
# Return old value if there's no new one
|
||||||
|
return push_data['before'] if parents.empty?
|
||||||
|
# Or return the first parent-commit
|
||||||
|
parents[0].id
|
||||||
|
end
|
||||||
|
|
||||||
|
def send_commits_count(data, project, repo, committer, branch)
|
||||||
|
url = compare_url data, project.path_with_namespace
|
||||||
|
commits = colorize_commits data['total_commits_count']
|
||||||
|
|
||||||
|
new_commits = 'new commit'
|
||||||
|
new_commits += 's' if data['total_commits_count'] > 1
|
||||||
|
|
||||||
|
sendtoirker "[#{repo}] #{committer} pushed #{commits} #{new_commits} " \
|
||||||
|
"to #{branch}: #{url}"
|
||||||
|
end
|
||||||
|
|
||||||
|
def compare_url(data, repo_path)
|
||||||
|
sha1 = Commit::truncate_sha(data['before'])
|
||||||
|
sha2 = Commit::truncate_sha(data['after'])
|
||||||
|
compare_url = "#{Gitlab.config.gitlab.url}/#{repo_path}/compare"
|
||||||
|
compare_url += "/#{sha1}...#{sha2}"
|
||||||
|
colorize_url compare_url
|
||||||
|
end
|
||||||
|
|
||||||
|
def send_one_commit(project, hook_attrs, repo_name, branch)
|
||||||
|
commit = commit_from_id project, hook_attrs['id']
|
||||||
|
sha = colorize_sha Commit::truncate_sha(hook_attrs['id'])
|
||||||
|
author = hook_attrs['author']['name']
|
||||||
|
files = colorize_nb_files(files_count commit)
|
||||||
|
title = commit.title
|
||||||
|
|
||||||
|
sendtoirker "#{repo_name}/#{branch} #{sha} #{author} (#{files}): #{title}"
|
||||||
|
end
|
||||||
|
|
||||||
|
def commit_from_id(project, id)
|
||||||
|
commit = Gitlab::Git::Commit.find(project.repository, id)
|
||||||
|
Commit.new(commit)
|
||||||
|
end
|
||||||
|
|
||||||
|
def files_count(commit)
|
||||||
|
files = "#{commit.diffs.count} file"
|
||||||
|
files += 's' if commit.diffs.count > 1
|
||||||
|
files
|
||||||
|
end
|
||||||
|
|
||||||
|
def colorize_sha(sha)
|
||||||
|
sha = "\x0314#{sha}\x0f" if @colors
|
||||||
|
sha
|
||||||
|
end
|
||||||
|
|
||||||
|
def colorize_nb_files(nb_files)
|
||||||
|
nb_files = "\x0312#{nb_files}\x0f" if @colors
|
||||||
|
nb_files
|
||||||
|
end
|
||||||
|
|
||||||
|
def colorize_url(url)
|
||||||
|
url = "\x0302\x1f#{url}\x0f" if @colors
|
||||||
|
url
|
||||||
|
end
|
||||||
|
|
||||||
|
def colorize_commits(commits)
|
||||||
|
commits = "\x02#{commits}\x0f" if @colors
|
||||||
|
commits
|
||||||
|
end
|
||||||
|
end
|
|
@ -0,0 +1,46 @@
|
||||||
|
# Irker IRC Gateway
|
||||||
|
|
||||||
|
GitLab provides a way to push update messages to an Irker server. When
|
||||||
|
configured, pushes to a project will trigger the service to send data directly
|
||||||
|
to the Irker server.
|
||||||
|
|
||||||
|
See the project homepage for further info: http://www.catb.org/esr/irker/
|
||||||
|
|
||||||
|
## Needed setup
|
||||||
|
|
||||||
|
You will first need an Irker daemon. You can download the Irker code from its
|
||||||
|
gitorious repository on https://gitorious.org/irker: `git clone
|
||||||
|
git@gitorious.org:irker/irker.git`. Once you have downloaded the code, you can
|
||||||
|
run the python script named `irkerd`. This script is the gateway script, it acts
|
||||||
|
both as an IRC client, for sending messages to an IRC server obviously, and as a
|
||||||
|
TCP server, for receiving messages from the GitLab service.
|
||||||
|
|
||||||
|
If the Irker server runs on the same machine, you are done. If not, you will
|
||||||
|
need to follow the firsts steps of the next section.
|
||||||
|
|
||||||
|
## Optional setup
|
||||||
|
|
||||||
|
In the `app/models/project_services/irker_service.rb` file, you can modify some
|
||||||
|
options in the `initialize_settings` method:
|
||||||
|
- **server_ip** (defaults to `localhost`): the server IP address where the
|
||||||
|
`irkerd` daemon runs;
|
||||||
|
- **server_port** (defaults to `6659`): the server port of the `irkerd` daemon;
|
||||||
|
- **max_channels** (defaults to `3`): the maximum number of recipients the
|
||||||
|
client is authorized to join, per project;
|
||||||
|
- **default_irc_uri** (no default) : if this option is set, it has to be in the
|
||||||
|
format `irc[s]://domain.name` and will be prepend to each and every channel
|
||||||
|
provided by the user which is not a full URI.
|
||||||
|
|
||||||
|
If the Irker server and the GitLab application do not run on the same host, you
|
||||||
|
will **need** to setup at least the **server_ip** option.
|
||||||
|
|
||||||
|
## Note on Irker recipients
|
||||||
|
|
||||||
|
Irker accepts channel names of the form `chan` and `#chan`, both for the
|
||||||
|
`#chan` channel. If you want to send messages in query, you will need to add
|
||||||
|
`,isnick` avec the channel name, in this form: `Aorimn,isnick`. In this latter
|
||||||
|
case, `Aorimn` is treated as a nick and no more as a channel name.
|
||||||
|
|
||||||
|
Irker can also join password-protected channels. Users need to append
|
||||||
|
`?key=thesecretpassword` to the chan name.
|
||||||
|
|
|
@ -13,6 +13,7 @@ __Project integrations with external services for continuous integration and mor
|
||||||
- Gemnasium
|
- Gemnasium
|
||||||
- GitLab CI
|
- GitLab CI
|
||||||
- HipChat
|
- HipChat
|
||||||
|
- [Irker](irker.md) An IRC gateway to receive messages on repository updates.
|
||||||
- Pivotal Tracker
|
- Pivotal Tracker
|
||||||
- Pushover
|
- Pushover
|
||||||
- Slack
|
- Slack
|
||||||
|
|
|
@ -61,6 +61,12 @@ Feature: Project Services
|
||||||
And I fill email on push settings
|
And I fill email on push settings
|
||||||
Then I should see email on push service settings saved
|
Then I should see email on push service settings saved
|
||||||
|
|
||||||
|
Scenario: Activate Irker (IRC Gateway) service
|
||||||
|
When I visit project "Shop" services page
|
||||||
|
And I click Irker service link
|
||||||
|
And I fill Irker settings
|
||||||
|
Then I should see Irker service settings saved
|
||||||
|
|
||||||
Scenario: Activate Atlassian Bamboo CI service
|
Scenario: Activate Atlassian Bamboo CI service
|
||||||
When I visit project "Shop" services page
|
When I visit project "Shop" services page
|
||||||
And I click Atlassian Bamboo CI service link
|
And I click Atlassian Bamboo CI service link
|
||||||
|
|
|
@ -17,6 +17,7 @@ class Spinach::Features::ProjectServices < Spinach::FeatureSteps
|
||||||
page.should have_content 'Atlassian Bamboo'
|
page.should have_content 'Atlassian Bamboo'
|
||||||
page.should have_content 'JetBrains TeamCity'
|
page.should have_content 'JetBrains TeamCity'
|
||||||
page.should have_content 'Asana'
|
page.should have_content 'Asana'
|
||||||
|
page.should have_content 'Irker (IRC gateway)'
|
||||||
end
|
end
|
||||||
|
|
||||||
step 'I click gitlab-ci service link' do
|
step 'I click gitlab-ci service link' do
|
||||||
|
@ -132,6 +133,22 @@ class Spinach::Features::ProjectServices < Spinach::FeatureSteps
|
||||||
find_field('Recipients').value.should == 'qa@company.name'
|
find_field('Recipients').value.should == 'qa@company.name'
|
||||||
end
|
end
|
||||||
|
|
||||||
|
step 'I click Irker service link' do
|
||||||
|
click_link 'Irker (IRC gateway)'
|
||||||
|
end
|
||||||
|
|
||||||
|
step 'I fill Irker settings' do
|
||||||
|
check 'Active'
|
||||||
|
fill_in 'Recipients', with: 'irc://chat.freenode.net/#commits'
|
||||||
|
check 'Colorize messages'
|
||||||
|
click_button 'Save'
|
||||||
|
end
|
||||||
|
|
||||||
|
step 'I should see Irker service settings saved' do
|
||||||
|
find_field('Recipients').value.should == 'irc://chat.freenode.net/#commits'
|
||||||
|
find_field('Colorize messages').value.should == '1'
|
||||||
|
end
|
||||||
|
|
||||||
step 'I click Slack service link' do
|
step 'I click Slack service link' do
|
||||||
click_link 'Slack'
|
click_link 'Slack'
|
||||||
end
|
end
|
||||||
|
|
|
@ -0,0 +1,103 @@
|
||||||
|
# == 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'
|
||||||
|
require 'socket'
|
||||||
|
require 'json'
|
||||||
|
|
||||||
|
describe IrkerService do
|
||||||
|
describe 'Associations' do
|
||||||
|
it { should belong_to :project }
|
||||||
|
it { should have_one :service_hook }
|
||||||
|
end
|
||||||
|
|
||||||
|
describe 'Validations' do
|
||||||
|
before do
|
||||||
|
subject.active = true
|
||||||
|
subject.properties['recipients'] = _recipients
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'active' do
|
||||||
|
let(:_recipients) { nil }
|
||||||
|
it { should validate_presence_of :recipients }
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'too many recipients' do
|
||||||
|
let(:_recipients) { 'a b c d' }
|
||||||
|
it 'should add an error if there is too many recipients' do
|
||||||
|
subject.send :check_recipients_count
|
||||||
|
subject.errors.should_not be_blank
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
context '3 recipients' do
|
||||||
|
let(:_recipients) { 'a b c' }
|
||||||
|
it 'should not add an error if there is 3 recipients' do
|
||||||
|
subject.send :check_recipients_count
|
||||||
|
subject.errors.should be_blank
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
describe 'Execute' do
|
||||||
|
let(:irker) { IrkerService.new }
|
||||||
|
let(:user) { create(:user) }
|
||||||
|
let(:project) { create(:project) }
|
||||||
|
let(:sample_data) { Gitlab::PushDataBuilder.build_sample(project, user) }
|
||||||
|
|
||||||
|
let(:recipients) { '#commits' }
|
||||||
|
let(:colorize_messages) { '1' }
|
||||||
|
|
||||||
|
before do
|
||||||
|
irker.stub(
|
||||||
|
active: true,
|
||||||
|
project: project,
|
||||||
|
project_id: project.id,
|
||||||
|
service_hook: true,
|
||||||
|
properties: {
|
||||||
|
'recipients' => recipients,
|
||||||
|
'colorize_messages' => colorize_messages
|
||||||
|
}
|
||||||
|
)
|
||||||
|
irker.settings = {
|
||||||
|
server_ip: 'localhost',
|
||||||
|
server_port: 6659,
|
||||||
|
max_channels: 3,
|
||||||
|
default_irc_uri: 'irc://chat.freenode.net/'
|
||||||
|
}
|
||||||
|
irker.valid?
|
||||||
|
@irker_server = TCPServer.new 'localhost', 6659
|
||||||
|
end
|
||||||
|
|
||||||
|
after do
|
||||||
|
@irker_server.close
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'should send valid JSON messages to an Irker listener' do
|
||||||
|
irker.execute(sample_data)
|
||||||
|
|
||||||
|
conn = @irker_server.accept
|
||||||
|
conn.readlines.each do |line|
|
||||||
|
msg = JSON.load(line.chomp("\n"))
|
||||||
|
msg.keys.should match_array(['to', 'privmsg'])
|
||||||
|
if msg['to'].is_a?(String)
|
||||||
|
msg['to'].should == 'irc://chat.freenode.net/#commits'
|
||||||
|
else
|
||||||
|
msg['to'].should match_array(['irc://chat.freenode.net/#commits'])
|
||||||
|
end
|
||||||
|
end
|
||||||
|
conn.close
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
Loading…
Reference in New Issue