slack-notifier-1.5.1/ 0000755 0000041 0000041 00000000000 12635260637 014472 5 ustar www-data www-data slack-notifier-1.5.1/spec/ 0000755 0000041 0000041 00000000000 12635260637 015424 5 ustar www-data www-data slack-notifier-1.5.1/spec/spec_helper.rb 0000644 0000041 0000041 00000000370 12635260637 020242 0 ustar www-data www-data require 'rspec'
require 'slack-notifier'
if ENV['DEBUG']
require 'pry'
end
RSpec.configure do |config|
config.mock_with :rspec do |mocks|
mocks.verify_doubled_constant_names = true
mocks.verify_partial_doubles = true
end
end
slack-notifier-1.5.1/spec/lib/ 0000755 0000041 0000041 00000000000 12635260637 016172 5 ustar www-data www-data slack-notifier-1.5.1/spec/lib/slack-notifier/ 0000755 0000041 0000041 00000000000 12635260637 021104 5 ustar www-data www-data slack-notifier-1.5.1/spec/lib/slack-notifier/default_http_client_spec.rb 0000644 0000041 0000041 00000002252 12635260637 026465 0 ustar www-data www-data require 'spec_helper'
describe Slack::Notifier::DefaultHTTPClient do
describe "::post" do
it "initializes DefaultHTTPClient with the given uri and params then calls" do
http_post_double = instance_double("Slack::Notifier::DefaultHTTPClient")
expect( described_class ).to receive(:new)
.with( 'uri', 'params' )
.and_return( http_post_double )
expect( http_post_double ).to receive(:call)
described_class.post 'uri', 'params'
end
# http_post is really tested in the integration spec,
# where the internals are run through
end
describe "#initialize" do
it "allows setting of options for Net::HTTP" do
net_http_double = instance_double("Net::HTTP")
http_client = described_class.new( URI.parse('http://example.com'), http_options: { open_timeout: 5 })
allow( Net::HTTP ).to receive(:new)
.and_return(net_http_double)
allow( net_http_double ).to receive(:use_ssl=)
allow( net_http_double ).to receive(:request)
expect( net_http_double ).to receive(:open_timeout=).with(5)
http_client.call
end
end
end
slack-notifier-1.5.1/spec/lib/slack-notifier/link_formatter_spec.rb 0000644 0000041 0000041 00000005661 12635260637 025473 0 ustar www-data www-data # encoding: utf-8
require 'spec_helper'
describe Slack::Notifier::LinkFormatter do
describe "::format" do
it "formats html links" do
formatted = described_class.format("Hello World, enjoy this.")
expect( formatted ).to include("")
end
it "formats markdown links" do
formatted = described_class.format("Hello World, enjoy [this](http://example.com).")
expect( formatted ).to include("")
end
it "formats markdown links in brackets" do
formatted = described_class.format("Hello World, enjoy [[this](http://example.com) in brackets].")
expect( formatted ).to eq("Hello World, enjoy [ in brackets].")
end
it "formats markdown links with no title" do
formatted = described_class.format("Hello World, enjoy [](http://example.com).")
expect( formatted ).to include("")
end
it "handles multiple html links" do
formatted = described_class.format("Hello World, enjoy thisthis2.")
expect( formatted ).to include("")
expect( formatted ).to include("")
end
it "handles multiple markdown links" do
formatted = described_class.format("Hello World, enjoy [this](http://example.com)[this2](http://example2.com).")
expect( formatted ).to include("")
expect( formatted ).to include("")
end
it "handles mixed html & markdown links" do
formatted = described_class.format("Hello World, enjoy [this](http://example.com)this2.")
expect( formatted ).to include("")
expect( formatted ).to include("")
end
if "".respond_to? :scrub
context "when on ruby 2.1+ or have string-scrub installed" do
it "handles invalid unicode sequences" do
expect {
described_class.format("This sequence is invalid: \255")
}.not_to raise_error
end
it "replaces invalid unicode sequences with the unicode replacement character" do
formatted = described_class.format("\255")
expect(formatted).to eq "\uFFFD"
end
end
end
it "doesn't replace valid Japanese" do
formatted = described_class.format("こんにちは")
expect(formatted).to eq "こんにちは"
end
it "handles mailto links in markdown" do
formatted = described_class.format("[John](mailto:john@example.com)")
expect(formatted).to eq ""
end
it "handles mailto links in html" do
formatted = described_class.format("John")
expect(formatted).to eq ""
end
end
end
slack-notifier-1.5.1/spec/lib/slack-notifier_spec.rb 0000644 0000041 0000041 00000013407 12635260637 022450 0 ustar www-data www-data require 'spec_helper'
describe Slack::Notifier do
subject { described_class.new 'http://example.com' }
describe "#initialize" do
it "sets the given hook_url to the endpoint URI" do
expect( subject.endpoint ).to eq URI.parse 'http://example.com'
end
it "sets the default_payload options" do
subject = described_class.new 'http://example.com', channel: 'foo'
expect( subject.channel ).to eq 'foo'
end
it "sets a custom http client" do
client = double("CustomClient")
subject = described_class.new 'http://example.com', http_client: client
expect( subject.http_client ).to eq client
end
end
describe "#ping" do
before :each do
allow( Slack::Notifier::DefaultHTTPClient ).to receive(:post)
end
it "passes the message through LinkFormatter" do
expect( Slack::Notifier::LinkFormatter ).to receive(:format)
.with("the message")
described_class.new('http://example.com').ping "the message", channel: 'foo'
end
it "passes attachment messages through LinkFormatter" do
expect( Slack::Notifier::LinkFormatter ).to receive(:format)
.with("the message")
expect( Slack::Notifier::LinkFormatter ).to receive(:format)
.with("attachment message")
described_class.new('http://example.com').ping "the message", channel: 'foo',
attachments: [{
color: "#000",
text: "attachment message",
fallback: "fallback message"
}]
end
it "allows sending only an attachment" do
expect( Slack::Notifier::DefaultHTTPClient ).to receive(:post).with(
URI.parse('http://example.com'),
payload: '{"channel":"foo","attachments":[{"text":"attachment","fallback":"fallback"}]}'
)
expect{
described_class.new('http://example.com')
.ping channel: 'foo',
attachments: [{
text: 'attachment',
fallback: 'fallback'
}]
}.not_to raise_error
end
it "passes attachment messages through LinkFormatter, even if a single value is passed" do
expect( Slack::Notifier::LinkFormatter ).to receive(:format)
.with("a random message")
expect( Slack::Notifier::LinkFormatter ).to receive(:format)
.with("attachment message")
attachment = {
color: "#000",
text: "attachment message",
fallback: "fallback message"
}
subject.ping "a random message", attachments: attachment
end
context "with a default channel set" do
before :each do
@endpoint_double = instance_double "URI::HTTP"
allow( URI ).to receive(:parse)
.and_return(@endpoint_double)
subject.channel = '#default'
end
it "does not require a channel to ping" do
expect{
subject.ping "the message"
}.not_to raise_error
end
it "uses default channel" do
expect( Slack::Notifier::DefaultHTTPClient ).to receive(:post)
.with @endpoint_double,
payload: '{"channel":"#default","text":"the message"}'
subject.ping "the message"
end
it "allows override channel to be set" do
expect( Slack::Notifier::DefaultHTTPClient ).to receive(:post)
.with @endpoint_double,
payload: '{"channel":"new","text":"the message"}'
subject.ping "the message", channel: "new"
end
end
context "with default webhook" do
it "posts with the correct endpoint & data" do
@endpoint_double = instance_double "URI::HTTP"
allow( URI ).to receive(:parse)
.with("http://example.com")
.and_return(@endpoint_double)
expect( Slack::Notifier::DefaultHTTPClient ).to receive(:post)
.with @endpoint_double,
payload: '{"channel":"channel","text":"the message"}'
described_class.new("http://example.com").ping "the message", channel: "channel"
end
end
context "with a custom http_client set" do
it "uses it" do
endpoint_double = instance_double "URI::HTTP"
allow( URI ).to receive(:parse)
.with("http://example.com")
.and_return(endpoint_double)
client = double("CustomClient")
expect( client ).to receive(:post)
.with endpoint_double,
payload: '{"text":"the message"}'
described_class.new('http://example.com',http_client: client).ping "the message"
end
end
end
describe "#channel=" do
it "sets the given channel" do
subject.channel = "#foo"
expect( subject.channel ).to eq "#foo"
end
end
describe "#username=" do
it "sets the given username" do
subject.username = "foo"
expect( subject.username ).to eq "foo"
end
end
describe "#escape" do
it "escapes sequences of < > &, but not quotes" do
message = %q(I've heard "Do > with <" & that sounds ridiculous.)
expected = %q(I've heard "Do > with <" & that sounds ridiculous.)
expect( subject.escape(message) ).to eq expected
end
end
end
slack-notifier-1.5.1/spec/integration/ 0000755 0000041 0000041 00000000000 12635260637 017747 5 ustar www-data www-data slack-notifier-1.5.1/spec/integration/ping_integration_test.rb 0000644 0000041 0000041 00000000550 12635260637 024673 0 ustar www-data www-data # encoding: utf-8
require_relative '../../lib/slack-notifier'
notifier = Slack::Notifier.new ENV['SLACK_WEBHOOK_URL'], username: 'notifier'
puts "testing with ruby #{RUBY_VERSION}"
notifier.ping "hello/こんにちは from notifier test script on ruby: #{RUBY_VERSION}\225"
notifier.ping attachments: [{color:"#1BF5AF",fallback:"fallback",text:"attachment"}]
slack-notifier-1.5.1/lib/ 0000755 0000041 0000041 00000000000 12635260637 015240 5 ustar www-data www-data slack-notifier-1.5.1/lib/slack-notifier/ 0000755 0000041 0000041 00000000000 12635260637 020152 5 ustar www-data www-data slack-notifier-1.5.1/lib/slack-notifier/default_http_client.rb 0000644 0000041 0000041 00000002026 12635260637 024520 0 ustar www-data www-data module Slack
class Notifier
class DefaultHTTPClient
class << self
def post uri, params
DefaultHTTPClient.new( uri, params ).call
end
end
attr_reader :uri, :params, :http_options
def initialize uri, params
@uri = uri
@http_options = params.delete(:http_options) || {}
@params = params
end
def call
http_obj.request request_obj
end
private
def request_obj
req = Net::HTTP::Post.new uri.request_uri
req.set_form_data params
return req
end
def http_obj
http = Net::HTTP.new uri.host, uri.port
http.use_ssl = (uri.scheme == "https")
http_options.each do |opt, val|
if http.respond_to? "#{opt}="
http.send "#{opt}=", val
else
warn "Net::HTTP doesn't respond to `#{opt}=`, ignoring that option"
end
end
return http
end
end
end
end
slack-notifier-1.5.1/lib/slack-notifier/link_formatter.rb 0000644 0000041 0000041 00000002624 12635260637 023523 0 ustar www-data www-data module Slack
class Notifier
class LinkFormatter
class << self
def format string
LinkFormatter.new(string).formatted
end
end
def initialize string
@orig = if string.respond_to? :scrub
string.scrub
else
string
end
end
def formatted
@orig.gsub( html_pattern ) do |match|
link = Regexp.last_match[1]
text = Regexp.last_match[2]
slack_link link, text
end.gsub( markdown_pattern ) do |match|
link = Regexp.last_match[2]
text = Regexp.last_match[1]
slack_link link, text
end
rescue => e
if RUBY_VERSION < '2.1' && e.message.include?('invalid byte sequence')
raise e, "#{e.message}. Consider including the 'string-scrub' gem to strip invalid characters"
else
raise e
end
end
private
def slack_link link, text=nil
out = "<#{link}"
out << "|#{text}" if text && !text.empty?
out << ">"
return out
end
# http://rubular.com/r/19cNXW5qbH
def html_pattern
/ (.+?) <\/a> /x
end
# http://rubular.com/r/guJbTK6x1f
def markdown_pattern
/\[ ([^\[\]]*?) \] \( ((https?:\/\/.*?) | (mailto:.*?)) \) /x
end
end
end
end
slack-notifier-1.5.1/lib/slack-notifier/version.rb 0000644 0000041 0000041 00000000076 12635260637 022167 0 ustar www-data www-data module Slack
class Notifier
VERSION = "1.5.1"
end
end
slack-notifier-1.5.1/lib/slack-notifier.rb 0000644 0000041 0000041 00000003575 12635260637 020511 0 ustar www-data www-data require 'net/http'
require 'uri'
require 'json'
require_relative 'slack-notifier/default_http_client'
require_relative 'slack-notifier/link_formatter'
module Slack
class Notifier
attr_reader :endpoint, :default_payload
def initialize webhook_url, options={}
@endpoint = URI.parse webhook_url
@default_payload = options
end
def ping message, options={}
if message.is_a?(Hash)
message, options = nil, message
end
if attachments = options[:attachments] || options["attachments"]
wrap_array(attachments).each do |attachment|
["text", :text].each do |key|
attachment[key] = LinkFormatter.format(attachment[key]) if attachment.has_key?(key)
end
end
end
payload = default_payload.merge(options)
client = payload.delete(:http_client) || http_client
http_options = payload.delete(:http_options)
unless message.nil?
payload.merge!(text: LinkFormatter.format(message))
end
params = { payload: payload.to_json }
params[:http_options] = http_options if http_options
client.post endpoint, params
end
def http_client
default_payload.fetch :http_client, DefaultHTTPClient
end
def channel
default_payload[:channel]
end
def channel= channel
default_payload[:channel] = channel
end
def username
default_payload[:username]
end
def username= username
default_payload[:username] = username
end
HTML_ESCAPE_REGEXP = /[&><]/
HTML_ESCAPE = { '&' => '&', '>' => '>', '<' => '<' }
def escape(text)
text.gsub(HTML_ESCAPE_REGEXP, HTML_ESCAPE)
end
def wrap_array(object)
if object.nil?
[]
elsif object.respond_to?(:to_ary)
object.to_ary || [object]
else
[object]
end
end
end
end
slack-notifier-1.5.1/metadata.yml 0000644 0000041 0000041 00000002774 12635260637 017007 0 ustar www-data www-data --- !ruby/object:Gem::Specification
name: slack-notifier
version: !ruby/object:Gem::Version
version: 1.5.1
platform: ruby
authors:
- Steven Sloan
autorequire:
bindir: bin
cert_chain: []
date: 2015-12-01 00:00:00.000000000 Z
dependencies: []
description: " A slim ruby wrapper for posting to slack webhooks "
email:
- stevenosloan@gmail.com
executables: []
extensions: []
extra_rdoc_files: []
files:
- lib/slack-notifier.rb
- lib/slack-notifier/default_http_client.rb
- lib/slack-notifier/link_formatter.rb
- lib/slack-notifier/version.rb
- spec/integration/ping_integration_test.rb
- spec/lib/slack-notifier/default_http_client_spec.rb
- spec/lib/slack-notifier/link_formatter_spec.rb
- spec/lib/slack-notifier_spec.rb
- spec/spec_helper.rb
homepage: http://github.com/stevenosloan/slack-notifier
licenses:
- MIT
metadata: {}
post_install_message:
rdoc_options: []
require_paths:
- lib
required_ruby_version: !ruby/object:Gem::Requirement
requirements:
- - ">="
- !ruby/object:Gem::Version
version: '0'
required_rubygems_version: !ruby/object:Gem::Requirement
requirements:
- - ">="
- !ruby/object:Gem::Version
version: '0'
requirements: []
rubyforge_project:
rubygems_version: 2.4.5.1
signing_key:
specification_version: 4
summary: A slim ruby wrapper for posting to slack webhooks
test_files:
- spec/integration/ping_integration_test.rb
- spec/lib/slack-notifier/default_http_client_spec.rb
- spec/lib/slack-notifier/link_formatter_spec.rb
- spec/lib/slack-notifier_spec.rb
- spec/spec_helper.rb