slack-notifier-1.5.1/0000755000004100000410000000000012635260637014472 5ustar www-datawww-dataslack-notifier-1.5.1/spec/0000755000004100000410000000000012635260637015424 5ustar www-datawww-dataslack-notifier-1.5.1/spec/spec_helper.rb0000644000004100000410000000037012635260637020242 0ustar www-datawww-datarequire '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/0000755000004100000410000000000012635260637016172 5ustar www-datawww-dataslack-notifier-1.5.1/spec/lib/slack-notifier/0000755000004100000410000000000012635260637021104 5ustar www-datawww-dataslack-notifier-1.5.1/spec/lib/slack-notifier/default_http_client_spec.rb0000644000004100000410000000225212635260637026465 0ustar www-datawww-datarequire '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.rb0000644000004100000410000000566112635260637025473 0ustar www-datawww-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.rb0000644000004100000410000001340712635260637022450 0ustar www-datawww-datarequire '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/0000755000004100000410000000000012635260637017747 5ustar www-datawww-dataslack-notifier-1.5.1/spec/integration/ping_integration_test.rb0000644000004100000410000000055012635260637024673 0ustar www-datawww-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/0000755000004100000410000000000012635260637015240 5ustar www-datawww-dataslack-notifier-1.5.1/lib/slack-notifier/0000755000004100000410000000000012635260637020152 5ustar www-datawww-dataslack-notifier-1.5.1/lib/slack-notifier/default_http_client.rb0000644000004100000410000000202612635260637024520 0ustar www-datawww-datamodule 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.rb0000644000004100000410000000262412635260637023523 0ustar www-datawww-datamodule 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.rb0000644000004100000410000000007612635260637022167 0ustar www-datawww-datamodule Slack class Notifier VERSION = "1.5.1" end end slack-notifier-1.5.1/lib/slack-notifier.rb0000644000004100000410000000357512635260637020511 0ustar www-datawww-datarequire '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.yml0000644000004100000410000000277412635260637017007 0ustar www-datawww-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