slack-notifier 1.5.1 → 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 +38 -60
  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 -128
  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,163 +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
21
+ subject = described_class.new "http://example.com", http_client: mock_http
22
+ expect(subject.config.http_client).to eq mock_http
20
23
  end
21
- end
22
24
 
23
- describe "#ping" do
24
- before :each do
25
- allow( Slack::Notifier::DefaultHTTPClient ).to receive(:post)
26
- end
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)
27
29
 
28
- it "passes the message through LinkFormatter" do
29
- expect( Slack::Notifier::LinkFormatter ).to receive(:format)
30
- .with("the message")
30
+ expect(test_double).to receive(:test_init_method).with("foo")
31
31
 
32
- described_class.new('http://example.com').ping "the message", channel: 'foo'
33
- end
34
-
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
- )
54
-
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
63
- end
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"
64
43
 
65
- it "passes attachment messages through LinkFormatter, even if a single value is passed" do
66
- expect( Slack::Notifier::LinkFormatter ).to receive(:format)
67
- .with("a random message")
68
- expect( Slack::Notifier::LinkFormatter ).to receive(:format)
69
- .with("attachment message")
70
- attachment = {
71
- color: "#000",
72
- text: "attachment message",
73
- fallback: "fallback message"
74
- }
75
- subject.ping "a random message", attachments: attachment
44
+ subject.ping "message"
76
45
  end
46
+ end
77
47
 
78
- context "with a default channel set" do
79
-
80
- before :each do
81
- @endpoint_double = instance_double "URI::HTTP"
82
- allow( URI ).to receive(:parse)
83
- .and_return(@endpoint_double)
84
- subject.channel = '#default'
85
- end
86
-
87
- it "does not require a channel to ping" do
88
- expect{
89
- subject.ping "the message"
90
- }.not_to raise_error
91
- end
92
-
93
- it "uses default channel" do
94
- expect( Slack::Notifier::DefaultHTTPClient ).to receive(:post)
95
- .with @endpoint_double,
96
- payload: '{"channel":"#default","text":"the message"}'
97
-
98
- 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
99
55
  end
56
+ end
100
57
 
101
- it "allows override channel to be set" do
102
- expect( Slack::Notifier::DefaultHTTPClient ).to receive(:post)
103
- .with @endpoint_double,
104
- payload: '{"channel":"new","text":"the message"}'
58
+ it "uses the defaults set on initialization" do
59
+ subject = notifier_with_defaults
105
60
 
106
- subject.ping "the message", channel: "new"
107
- end
61
+ expect(mock_http).to receive(:post).with(
62
+ URI.parse("http://example.com"),
63
+ payload: '{"channel":"default","user":"rocket","text":"hello"}'
64
+ )
108
65
 
66
+ subject.post text: "hello"
109
67
  end
110
68
 
111
- context "with default webhook" do
112
- it "posts with the correct endpoint & data" do
113
- @endpoint_double = instance_double "URI::HTTP"
114
- allow( URI ).to receive(:parse)
115
- .with("http://example.com")
116
- .and_return(@endpoint_double)
69
+ it "allows overriding the set defaults" do
70
+ subject = notifier_with_defaults
117
71
 
118
- expect( Slack::Notifier::DefaultHTTPClient ).to receive(:post)
119
- .with @endpoint_double,
120
- 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
+ )
121
76
 
122
- described_class.new("http://example.com").ping "the message", channel: "channel"
123
- end
77
+ subject.post text: "hello", channel: "new", user: "ship"
124
78
  end
125
79
 
126
- context "with a custom http_client set" do
127
- it "uses it" do
128
- endpoint_double = instance_double "URI::HTTP"
129
- allow( URI ).to receive(:parse)
130
- .with("http://example.com")
131
- .and_return(endpoint_double)
132
- client = double("CustomClient")
133
- expect( client ).to receive(:post)
134
- .with endpoint_double,
135
- payload: '{"text":"the message"}'
136
-
137
- described_class.new('http://example.com',http_client: client).ping "the message"
138
- end
139
- end
140
- 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)
141
84
 
142
- describe "#channel=" do
143
- it "sets the given channel" do
144
- subject.channel = "#foo"
145
- expect( subject.channel ).to eq "#foo"
146
- end
147
- end
85
+ expect(stack).to receive(:call)
86
+ .with(channel: "default", user: "rocket")
87
+ .and_return([test: "stack"])
148
88
 
149
- describe "#username=" do
150
- it "sets the given username" do
151
- subject.username = "foo"
152
- expect( subject.username ).to eq "foo"
153
- end
154
- end
89
+ expect(mock_http).to receive(:post).with(
90
+ URI.parse("http://example.com"),
91
+ payload: '{"test":"stack"}'
92
+ )
155
93
 
156
- describe "#escape" do
157
- it "escapes sequences of < > &, but not quotes" do
158
- message = %q(I've heard "Do > with <" & that sounds ridiculous.)
159
- expected = %q(I've heard "Do &gt; with &lt;" &amp; that sounds ridiculous.)
160
- expect( subject.escape(message) ).to eq expected
94
+ responses = subject.post
95
+ expect(responses).to eq([:posted])
161
96
  end
162
97
  end
163
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.1
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-12-01 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