slack-notifier 1.5.0 → 2.4.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (33) hide show
  1. checksums.yaml +5 -5
  2. data/lib/slack-notifier/config.rb +43 -0
  3. data/lib/slack-notifier/payload_middleware/at.rb +36 -0
  4. data/lib/slack-notifier/payload_middleware/base.rb +34 -0
  5. data/lib/slack-notifier/payload_middleware/channels.rb +21 -0
  6. data/lib/slack-notifier/payload_middleware/format_attachments.rb +44 -0
  7. data/lib/slack-notifier/payload_middleware/format_message.rb +20 -0
  8. data/lib/slack-notifier/payload_middleware/stack.rb +50 -0
  9. data/lib/slack-notifier/payload_middleware.rb +24 -0
  10. data/lib/slack-notifier/util/escape.rb +16 -0
  11. data/lib/slack-notifier/util/http_client.rb +64 -0
  12. data/lib/slack-notifier/util/link_formatter.rb +80 -0
  13. data/lib/slack-notifier/version.rb +3 -1
  14. data/lib/slack-notifier.rb +39 -51
  15. data/spec/end_to_end_spec.rb +95 -0
  16. data/spec/integration/ping_integration_test.rb +14 -5
  17. data/spec/lib/slack-notifier/config_spec.rb +71 -0
  18. data/spec/lib/slack-notifier/payload_middleware/at_spec.rb +25 -0
  19. data/spec/lib/slack-notifier/payload_middleware/base_spec.rb +76 -0
  20. data/spec/lib/slack-notifier/payload_middleware/channels_spec.rb +20 -0
  21. data/spec/lib/slack-notifier/payload_middleware/format_attachments_spec.rb +48 -0
  22. data/spec/lib/slack-notifier/payload_middleware/format_message_spec.rb +27 -0
  23. data/spec/lib/slack-notifier/payload_middleware/stack_spec.rb +119 -0
  24. data/spec/lib/slack-notifier/payload_middleware_spec.rb +33 -0
  25. data/spec/lib/slack-notifier/util/http_client_spec.rb +55 -0
  26. data/spec/lib/slack-notifier/util/link_formatter_spec.rb +163 -0
  27. data/spec/lib/slack-notifier_spec.rb +63 -115
  28. data/spec/spec_helper.rb +20 -5
  29. metadata +39 -13
  30. data/lib/slack-notifier/default_http_client.rb +0 -51
  31. data/lib/slack-notifier/link_formatter.rb +0 -62
  32. data/spec/lib/slack-notifier/default_http_client_spec.rb +0 -37
  33. data/spec/lib/slack-notifier/link_formatter_spec.rb +0 -78
@@ -1,150 +1,98 @@
1
- require 'spec_helper'
1
+ # frozen_string_literal: true
2
2
 
3
- describe Slack::Notifier do
4
- subject { described_class.new 'http://example.com' }
3
+ RSpec.describe Slack::Notifier do
4
+ let(:mock_http) do
5
+ class_double("Slack::Notifier::Util::HTTPClient", post: :posted)
6
+ end
7
+
8
+ subject { described_class.new "http://example.com", http_client: mock_http }
5
9
 
6
10
  describe "#initialize" do
7
11
  it "sets the given hook_url to the endpoint URI" do
8
- expect( subject.endpoint ).to eq URI.parse 'http://example.com'
12
+ expect(subject.endpoint).to eq URI.parse("http://example.com")
9
13
  end
10
14
 
11
15
  it "sets the default_payload options" do
12
- subject = described_class.new 'http://example.com', channel: 'foo'
13
- expect( subject.channel ).to eq 'foo'
16
+ subject = described_class.new "http://example.com", channel: "foo"
17
+ expect(subject.config.defaults[:channel]).to eq "foo"
14
18
  end
15
19
 
16
20
  it "sets a custom http client" do
17
- client = double("CustomClient")
18
- subject = described_class.new 'http://example.com', http_client: client
19
- expect( subject.http_client ).to eq client
20
- end
21
- end
22
-
23
- describe "#ping" do
24
- before :each do
25
- allow( Slack::Notifier::DefaultHTTPClient ).to receive(:post)
21
+ subject = described_class.new "http://example.com", http_client: mock_http
22
+ expect(subject.config.http_client).to eq mock_http
26
23
  end
27
24
 
28
- it "passes the message through LinkFormatter" do
29
- expect( Slack::Notifier::LinkFormatter ).to receive(:format)
30
- .with("the message")
25
+ describe "when given a block" do
26
+ it "yields the config object" do
27
+ test_double = double("Slack::Notifier::Config", defaults: {}, middleware: [])
28
+ allow_any_instance_of(Slack::Notifier).to receive(:config).and_return(test_double)
31
29
 
32
- described_class.new('http://example.com').ping "the message", channel: 'foo'
33
- end
30
+ expect(test_double).to receive(:test_init_method).with("foo")
34
31
 
35
- it "passes attachment messages through LinkFormatter" do
36
- expect( Slack::Notifier::LinkFormatter ).to receive(:format)
37
- .with("the message")
38
- expect( Slack::Notifier::LinkFormatter ).to receive(:format)
39
- .with("attachment message")
40
-
41
- described_class.new('http://example.com').ping "the message", channel: 'foo',
42
- attachments: [{
43
- color: "#000",
44
- text: "attachment message",
45
- fallback: "fallback message"
46
- }]
32
+ described_class.new "http://example.com" do
33
+ test_init_method "foo"
34
+ end
35
+ end
47
36
  end
37
+ end
48
38
 
49
- it "allows sending only an attachment" do
50
- expect( Slack::Notifier::DefaultHTTPClient ).to receive(:post).with(
51
- URI.parse('http://example.com'),
52
- payload: '{"channel":"foo","attachments":[{"text":"attachment","fallback":"fallback"}]}'
53
- )
39
+ describe "#ping" do
40
+ it "calls #post with the message as the text key in #post" do
41
+ subject = described_class.new "http://example.com"
42
+ expect(subject).to receive(:post).with text: "message"
54
43
 
55
- expect{
56
- described_class.new('http://example.com')
57
- .ping channel: 'foo',
58
- attachments: [{
59
- text: 'attachment',
60
- fallback: 'fallback'
61
- }]
62
- }.not_to raise_error
44
+ subject.ping "message"
63
45
  end
46
+ end
64
47
 
65
- context "with a default channel set" do
66
-
67
- before :each do
68
- @endpoint_double = instance_double "URI::HTTP"
69
- allow( URI ).to receive(:parse)
70
- .and_return(@endpoint_double)
71
- subject.channel = '#default'
72
- end
73
-
74
- it "does not require a channel to ping" do
75
- expect{
76
- subject.ping "the message"
77
- }.not_to raise_error
78
- end
79
-
80
- it "uses default channel" do
81
- expect( Slack::Notifier::DefaultHTTPClient ).to receive(:post)
82
- .with @endpoint_double,
83
- payload: '{"channel":"#default","text":"the message"}'
84
-
85
- subject.ping "the message"
48
+ describe "#post" do
49
+ def notifier_with_defaults
50
+ mock_client = mock_http
51
+ described_class.new "http://example.com" do
52
+ defaults channel: "default",
53
+ user: "rocket"
54
+ http_client mock_client
86
55
  end
56
+ end
87
57
 
88
- it "allows override channel to be set" do
89
- expect( Slack::Notifier::DefaultHTTPClient ).to receive(:post)
90
- .with @endpoint_double,
91
- payload: '{"channel":"new","text":"the message"}'
58
+ it "uses the defaults set on initialization" do
59
+ subject = notifier_with_defaults
92
60
 
93
- subject.ping "the message", channel: "new"
94
- end
61
+ expect(mock_http).to receive(:post).with(
62
+ URI.parse("http://example.com"),
63
+ payload: '{"channel":"default","user":"rocket","text":"hello"}'
64
+ )
95
65
 
66
+ subject.post text: "hello"
96
67
  end
97
68
 
98
- context "with default webhook" do
99
- it "posts with the correct endpoint & data" do
100
- @endpoint_double = instance_double "URI::HTTP"
101
- allow( URI ).to receive(:parse)
102
- .with("http://example.com")
103
- .and_return(@endpoint_double)
69
+ it "allows overriding the set defaults" do
70
+ subject = notifier_with_defaults
104
71
 
105
- expect( Slack::Notifier::DefaultHTTPClient ).to receive(:post)
106
- .with @endpoint_double,
107
- payload: '{"channel":"channel","text":"the message"}'
72
+ expect(mock_http).to receive(:post).with(
73
+ URI.parse("http://example.com"),
74
+ payload: '{"channel":"new","user":"ship","text":"hello"}'
75
+ )
108
76
 
109
- described_class.new("http://example.com").ping "the message", channel: "channel"
110
- end
77
+ subject.post text: "hello", channel: "new", user: "ship"
111
78
  end
112
79
 
113
- context "with a custom http_client set" do
114
- it "uses it" do
115
- endpoint_double = instance_double "URI::HTTP"
116
- allow( URI ).to receive(:parse)
117
- .with("http://example.com")
118
- .and_return(endpoint_double)
119
- client = double("CustomClient")
120
- expect( client ).to receive(:post)
121
- .with endpoint_double,
122
- payload: '{"text":"the message"}'
123
-
124
- described_class.new('http://example.com',http_client: client).ping "the message"
125
- end
126
- end
127
- end
80
+ it "calls the middleware stack with the payload" do
81
+ subject = notifier_with_defaults
82
+ stack = instance_double("Slack::Notifier::PayloadMiddleware::Stack")
83
+ subject.instance_variable_set(:@middleware, stack)
128
84
 
129
- describe "#channel=" do
130
- it "sets the given channel" do
131
- subject.channel = "#foo"
132
- expect( subject.channel ).to eq "#foo"
133
- end
134
- end
85
+ expect(stack).to receive(:call)
86
+ .with(channel: "default", user: "rocket")
87
+ .and_return([test: "stack"])
135
88
 
136
- describe "#username=" do
137
- it "sets the given username" do
138
- subject.username = "foo"
139
- expect( subject.username ).to eq "foo"
140
- end
141
- end
89
+ expect(mock_http).to receive(:post).with(
90
+ URI.parse("http://example.com"),
91
+ payload: '{"test":"stack"}'
92
+ )
142
93
 
143
- describe "#escape" do
144
- it "escapes sequences of < > &, but not quotes" do
145
- message = %q(I've heard "Do > with <" & that sounds ridiculous.)
146
- expected = %q(I've heard "Do &gt; with &lt;" &amp; that sounds ridiculous.)
147
- expect( subject.escape(message) ).to eq expected
94
+ responses = subject.post
95
+ expect(responses).to eq([:posted])
148
96
  end
149
97
  end
150
98
  end
data/spec/spec_helper.rb CHANGED
@@ -1,13 +1,28 @@
1
- require 'rspec'
2
- require 'slack-notifier'
1
+ # frozen_string_literal: true
3
2
 
4
- if ENV['DEBUG']
5
- require 'pry'
6
- end
3
+ require "rspec"
4
+ require "slack-notifier"
5
+ require "pry" if ENV["DEBUG"]
7
6
 
8
7
  RSpec.configure do |config|
8
+ config.expect_with :rspec do |expectations|
9
+ expectations.include_chain_clauses_in_custom_matcher_descriptions = true
10
+ end
11
+
9
12
  config.mock_with :rspec do |mocks|
10
13
  mocks.verify_doubled_constant_names = true
11
14
  mocks.verify_partial_doubles = true
12
15
  end
16
+
17
+ config.filter_run :focus
18
+ config.run_all_when_everything_filtered = true
19
+ config.disable_monkey_patching!
20
+
21
+ config.example_status_persistence_file_path = "spec/examples.txt"
22
+ config.warnings = ENV["DEBUG"] ? false : true
23
+
24
+ config.default_formatter = "doc" if config.files_to_run.one?
25
+
26
+ config.order = :random
27
+ Kernel.srand config.seed
13
28
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: slack-notifier
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.5.0
4
+ version: 2.4.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Steven Sloan
8
- autorequire:
8
+ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-11-30 00:00:00.000000000 Z
11
+ date: 2021-05-07 00:00:00.000000000 Z
12
12
  dependencies: []
13
13
  description: " A slim ruby wrapper for posting to slack webhooks "
14
14
  email:
@@ -18,19 +18,37 @@ extensions: []
18
18
  extra_rdoc_files: []
19
19
  files:
20
20
  - lib/slack-notifier.rb
21
- - lib/slack-notifier/default_http_client.rb
22
- - lib/slack-notifier/link_formatter.rb
21
+ - lib/slack-notifier/config.rb
22
+ - lib/slack-notifier/payload_middleware.rb
23
+ - lib/slack-notifier/payload_middleware/at.rb
24
+ - lib/slack-notifier/payload_middleware/base.rb
25
+ - lib/slack-notifier/payload_middleware/channels.rb
26
+ - lib/slack-notifier/payload_middleware/format_attachments.rb
27
+ - lib/slack-notifier/payload_middleware/format_message.rb
28
+ - lib/slack-notifier/payload_middleware/stack.rb
29
+ - lib/slack-notifier/util/escape.rb
30
+ - lib/slack-notifier/util/http_client.rb
31
+ - lib/slack-notifier/util/link_formatter.rb
23
32
  - lib/slack-notifier/version.rb
33
+ - spec/end_to_end_spec.rb
24
34
  - spec/integration/ping_integration_test.rb
25
- - spec/lib/slack-notifier/default_http_client_spec.rb
26
- - spec/lib/slack-notifier/link_formatter_spec.rb
35
+ - spec/lib/slack-notifier/config_spec.rb
36
+ - spec/lib/slack-notifier/payload_middleware/at_spec.rb
37
+ - spec/lib/slack-notifier/payload_middleware/base_spec.rb
38
+ - spec/lib/slack-notifier/payload_middleware/channels_spec.rb
39
+ - spec/lib/slack-notifier/payload_middleware/format_attachments_spec.rb
40
+ - spec/lib/slack-notifier/payload_middleware/format_message_spec.rb
41
+ - spec/lib/slack-notifier/payload_middleware/stack_spec.rb
42
+ - spec/lib/slack-notifier/payload_middleware_spec.rb
43
+ - spec/lib/slack-notifier/util/http_client_spec.rb
44
+ - spec/lib/slack-notifier/util/link_formatter_spec.rb
27
45
  - spec/lib/slack-notifier_spec.rb
28
46
  - spec/spec_helper.rb
29
47
  homepage: http://github.com/stevenosloan/slack-notifier
30
48
  licenses:
31
49
  - MIT
32
50
  metadata: {}
33
- post_install_message:
51
+ post_install_message:
34
52
  rdoc_options: []
35
53
  require_paths:
36
54
  - lib
@@ -45,14 +63,22 @@ required_rubygems_version: !ruby/object:Gem::Requirement
45
63
  - !ruby/object:Gem::Version
46
64
  version: '0'
47
65
  requirements: []
48
- rubyforge_project:
49
- rubygems_version: 2.4.5.1
50
- signing_key:
66
+ rubygems_version: 3.2.15
67
+ signing_key:
51
68
  specification_version: 4
52
69
  summary: A slim ruby wrapper for posting to slack webhooks
53
70
  test_files:
71
+ - spec/end_to_end_spec.rb
54
72
  - spec/integration/ping_integration_test.rb
55
- - spec/lib/slack-notifier/default_http_client_spec.rb
56
- - spec/lib/slack-notifier/link_formatter_spec.rb
73
+ - spec/lib/slack-notifier/config_spec.rb
74
+ - spec/lib/slack-notifier/payload_middleware/at_spec.rb
75
+ - spec/lib/slack-notifier/payload_middleware/base_spec.rb
76
+ - spec/lib/slack-notifier/payload_middleware/channels_spec.rb
77
+ - spec/lib/slack-notifier/payload_middleware/format_attachments_spec.rb
78
+ - spec/lib/slack-notifier/payload_middleware/format_message_spec.rb
79
+ - spec/lib/slack-notifier/payload_middleware/stack_spec.rb
80
+ - spec/lib/slack-notifier/payload_middleware_spec.rb
81
+ - spec/lib/slack-notifier/util/http_client_spec.rb
82
+ - spec/lib/slack-notifier/util/link_formatter_spec.rb
57
83
  - spec/lib/slack-notifier_spec.rb
58
84
  - spec/spec_helper.rb
@@ -1,51 +0,0 @@
1
- module Slack
2
- class Notifier
3
-
4
- class DefaultHTTPClient
5
-
6
- class << self
7
- def post uri, params
8
- DefaultHTTPClient.new( uri, params ).call
9
- end
10
- end
11
-
12
- attr_reader :uri, :params, :http_options
13
-
14
- def initialize uri, params
15
- @uri = uri
16
- @http_options = params.delete(:http_options) || {}
17
- @params = params
18
- end
19
-
20
- def call
21
- http_obj.request request_obj
22
- end
23
-
24
- private
25
-
26
- def request_obj
27
- req = Net::HTTP::Post.new uri.request_uri
28
- req.set_form_data params
29
-
30
- return req
31
- end
32
-
33
- def http_obj
34
- http = Net::HTTP.new uri.host, uri.port
35
- http.use_ssl = (uri.scheme == "https")
36
-
37
- http_options.each do |opt, val|
38
- if http.respond_to? "#{opt}="
39
- http.send "#{opt}=", val
40
- else
41
- warn "Net::HTTP doesn't respond to `#{opt}=`, ignoring that option"
42
- end
43
- end
44
-
45
- return http
46
- end
47
-
48
- end
49
-
50
- end
51
- end
@@ -1,62 +0,0 @@
1
- module Slack
2
- class Notifier
3
- class LinkFormatter
4
-
5
- class << self
6
-
7
- def format string
8
- LinkFormatter.new(string).formatted
9
- end
10
-
11
- end
12
-
13
- def initialize string
14
- @orig = if string.respond_to? :scrub
15
- string.scrub
16
- else
17
- string
18
- end
19
- end
20
-
21
- def formatted
22
- @orig.gsub( html_pattern ) do |match|
23
- link = Regexp.last_match[1]
24
- text = Regexp.last_match[2]
25
- slack_link link, text
26
- end.gsub( markdown_pattern ) do |match|
27
- link = Regexp.last_match[2]
28
- text = Regexp.last_match[1]
29
- slack_link link, text
30
- end
31
-
32
- rescue => e
33
- if RUBY_VERSION < '2.1' && e.message.include?('invalid byte sequence')
34
- raise e, "#{e.message}. Consider including the 'string-scrub' gem to strip invalid characters"
35
- else
36
- raise e
37
- end
38
- end
39
-
40
- private
41
-
42
- def slack_link link, text=nil
43
- out = "<#{link}"
44
- out << "|#{text}" if text && !text.empty?
45
- out << ">"
46
-
47
- return out
48
- end
49
-
50
- # http://rubular.com/r/19cNXW5qbH
51
- def html_pattern
52
- / <a (?:.*?) href=['"](.+?)['"] (?:.*?)> (.+?) <\/a> /x
53
- end
54
-
55
- # http://rubular.com/r/guJbTK6x1f
56
- def markdown_pattern
57
- /\[ ([^\[\]]*?) \] \( ((https?:\/\/.*?) | (mailto:.*?)) \) /x
58
- end
59
-
60
- end
61
- end
62
- end
@@ -1,37 +0,0 @@
1
- require 'spec_helper'
2
-
3
- describe Slack::Notifier::DefaultHTTPClient do
4
-
5
- describe "::post" do
6
- it "initializes DefaultHTTPClient with the given uri and params then calls" do
7
- http_post_double = instance_double("Slack::Notifier::DefaultHTTPClient")
8
-
9
- expect( described_class ).to receive(:new)
10
- .with( 'uri', 'params' )
11
- .and_return( http_post_double )
12
- expect( http_post_double ).to receive(:call)
13
-
14
- described_class.post 'uri', 'params'
15
- end
16
-
17
- # http_post is really tested in the integration spec,
18
- # where the internals are run through
19
- end
20
-
21
- describe "#initialize" do
22
- it "allows setting of options for Net::HTTP" do
23
- net_http_double = instance_double("Net::HTTP")
24
- http_client = described_class.new( URI.parse('http://example.com'), http_options: { open_timeout: 5 })
25
-
26
- allow( Net::HTTP ).to receive(:new)
27
- .and_return(net_http_double)
28
- allow( net_http_double ).to receive(:use_ssl=)
29
- allow( net_http_double ).to receive(:request)
30
-
31
- expect( net_http_double ).to receive(:open_timeout=).with(5)
32
-
33
- http_client.call
34
- end
35
- end
36
-
37
- end
@@ -1,78 +0,0 @@
1
- # encoding: utf-8
2
- require 'spec_helper'
3
-
4
- describe Slack::Notifier::LinkFormatter do
5
-
6
- describe "::format" do
7
-
8
- it "formats html links" do
9
- formatted = described_class.format("Hello World, enjoy <a href='http://example.com'>this</a>.")
10
- expect( formatted ).to include("<http://example.com|this>")
11
- end
12
-
13
- it "formats markdown links" do
14
- formatted = described_class.format("Hello World, enjoy [this](http://example.com).")
15
- expect( formatted ).to include("<http://example.com|this>")
16
- end
17
-
18
- it "formats markdown links in brackets" do
19
- formatted = described_class.format("Hello World, enjoy [[this](http://example.com) in brackets].")
20
- expect( formatted ).to eq("Hello World, enjoy [<http://example.com|this> in brackets].")
21
- end
22
-
23
- it "formats markdown links with no title" do
24
- formatted = described_class.format("Hello World, enjoy [](http://example.com).")
25
- expect( formatted ).to include("<http://example.com>")
26
- end
27
-
28
- it "handles multiple html links" do
29
- formatted = described_class.format("Hello World, enjoy <a href='http://example.com'>this</a><a href='http://example2.com'>this2</a>.")
30
- expect( formatted ).to include("<http://example.com|this>")
31
- expect( formatted ).to include("<http://example2.com|this2>")
32
- end
33
-
34
- it "handles multiple markdown links" do
35
- formatted = described_class.format("Hello World, enjoy [this](http://example.com)[this2](http://example2.com).")
36
- expect( formatted ).to include("<http://example.com|this>")
37
- expect( formatted ).to include("<http://example2.com|this2>")
38
- end
39
-
40
- it "handles mixed html & markdown links" do
41
- formatted = described_class.format("Hello World, enjoy [this](http://example.com)<a href='http://example2.com'>this2</a>.")
42
- expect( formatted ).to include("<http://example.com|this>")
43
- expect( formatted ).to include("<http://example2.com|this2>")
44
- end
45
-
46
- if "".respond_to? :scrub
47
- context "when on ruby 2.1+ or have string-scrub installed" do
48
- it "handles invalid unicode sequences" do
49
- expect {
50
- described_class.format("This sequence is invalid: \255")
51
- }.not_to raise_error
52
- end
53
-
54
- it "replaces invalid unicode sequences with the unicode replacement character" do
55
- formatted = described_class.format("\255")
56
- expect(formatted).to eq "\uFFFD"
57
- end
58
- end
59
- end
60
-
61
- it "doesn't replace valid Japanese" do
62
- formatted = described_class.format("こんにちは")
63
- expect(formatted).to eq "こんにちは"
64
- end
65
-
66
- it "handles mailto links in markdown" do
67
- formatted = described_class.format("[John](mailto:john@example.com)")
68
- expect(formatted).to eq "<mailto:john@example.com|John>"
69
- end
70
-
71
- it "handles mailto links in html" do
72
- formatted = described_class.format("<a href='mailto:john@example.com'>John</a>")
73
- expect(formatted).to eq "<mailto:john@example.com|John>"
74
- end
75
-
76
- end
77
-
78
- end