slack-notifier 2.3.1 → 2.3.2

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: b26d815a68d346fe2726a68a896d54276b91b6f9
4
- data.tar.gz: 92803f407f329b8b908062a033adc583b86f00cc
3
+ metadata.gz: 2912c5289963e0ecbc66d6b89fb0bbfb288ab43a
4
+ data.tar.gz: 78e320255b7ffc02f5dcc363acae1154f40c2b5f
5
5
  SHA512:
6
- metadata.gz: b08f9faeb71b9cd2d20fc96d30f8585ca530b16c6a02af6ed13b14ef47c7fca513c2173aae7cb344e02f247df40b4d258d4cf35d6c2251d7250d7a8aafc53af5
7
- data.tar.gz: f611a92dbe367be0cced5b590b58fbaddde92f17fc9eb50e170086bda195291569906956d4b6d1000279fbfb1b14f6456d23e11c40df566ee0edf3fd0092ce8c
6
+ metadata.gz: 714ae944d20a181d147bbd88b62a42e73763f6f204c958ac69581fc33bdd91f406ee7c8f495c34028e936340ffea988cb3fe3bff32a09bb43db73e35ba89127a
7
+ data.tar.gz: c0138c50280c0f56ec1c3bd0094650f3c39a323be3acd818cca361f41febf920b2f63a6d36157c84612ba455625b2ae3c563891df746585e993bfa832cd8f447
@@ -1,4 +1,5 @@
1
1
  # frozen_string_literal: true
2
+
2
3
  require "uri"
3
4
  require "json"
4
5
 
@@ -1,15 +1,16 @@
1
1
  # frozen_string_literal: true
2
+
2
3
  module Slack
3
4
  class Notifier
4
5
  class Config
5
6
  def initialize
6
7
  @http_client = Util::HTTPClient
7
8
  @defaults = {}
8
- @middleware = [
9
- :format_message,
10
- :format_attachments,
11
- :at,
12
- :channels,
9
+ @middleware = %i[
10
+ format_message
11
+ format_attachments
12
+ at
13
+ channels
13
14
  ]
14
15
  end
15
16
 
@@ -1,4 +1,5 @@
1
1
  # frozen_string_literal: true
2
+
2
3
  module Slack
3
4
  class Notifier
4
5
  class PayloadMiddleware
@@ -1,4 +1,5 @@
1
1
  # frozen_string_literal: true
2
+
2
3
  module Slack
3
4
  class Notifier
4
5
  class PayloadMiddleware
@@ -1,16 +1,17 @@
1
1
  # frozen_string_literal: true
2
+
2
3
  module Slack
3
4
  class Notifier
4
5
  class PayloadMiddleware
5
6
  class FormatAttachments < Base
6
7
  middleware_name :format_attachments
7
8
 
8
- options formats: [:html, :markdown]
9
+ options formats: %i[html markdown]
9
10
 
10
11
  def call payload={}
11
12
  payload = payload.dup
12
13
  attachments = payload.delete(:attachments)
13
- attachments = payload.delete("attachments") unless attachments
14
+ attachments ||= payload.delete("attachments")
14
15
 
15
16
  attachments = wrap_array(attachments).map do |attachment|
16
17
  ["text", :text].each do |key|
@@ -1,11 +1,12 @@
1
1
  # frozen_string_literal: true
2
+
2
3
  module Slack
3
4
  class Notifier
4
5
  class PayloadMiddleware
5
6
  class FormatMessage < Base
6
7
  middleware_name :format_message
7
8
 
8
- options formats: [:html, :markdown]
9
+ options formats: %i[html markdown]
9
10
 
10
11
  def call payload={}
11
12
  return payload unless payload[:text]
@@ -1,4 +1,5 @@
1
1
  # frozen_string_literal: true
2
+
2
3
  module Slack
3
4
  class Notifier
4
5
  class PayloadMiddleware
@@ -1,4 +1,5 @@
1
1
  # frozen_string_literal: true
2
+
2
3
  module Slack
3
4
  class Notifier
4
5
  module Util
@@ -2,7 +2,6 @@
2
2
 
3
3
  require "net/http"
4
4
 
5
-
6
5
  module Slack
7
6
  class Notifier
8
7
  class APIError < StandardError; end
@@ -23,6 +22,7 @@ module Slack
23
22
  @params = params
24
23
  end
25
24
 
25
+ # rubocop:disable Layout/IndentHeredoc
26
26
  def call
27
27
  http_obj.request(request_obj).tap do |response|
28
28
  unless response.is_a?(Net::HTTPSuccess)
@@ -33,6 +33,7 @@ MSG
33
33
  end
34
34
  end
35
35
  end
36
+ # rubocop:enable Layout/IndentHeredoc
36
37
 
37
38
  private
38
39
 
@@ -1,13 +1,31 @@
1
1
  # frozen_string_literal: true
2
+
2
3
  module Slack
3
4
  class Notifier
4
5
  module Util
5
6
  class LinkFormatter
6
7
  # http://rubular.com/r/19cNXW5qbH
7
- HTML_PATTERN = / <a (?:.*?) href=['"](.+?)['"] (?:.*?)> (.+?) <\/a> /x
8
+ HTML_PATTERN = %r{
9
+ <a
10
+ (?:.*?)
11
+ href=['"](.+?)['"]
12
+ (?:.*?)>
13
+ (.+?)
14
+ </a>
15
+ }x
16
+
17
+ # the path portion of a url can contain these characters
18
+ VALID_PATH_CHARS = '\w\-\.\~\/\?\#\='
8
19
 
9
- # http://rubular.com/r/guJbTK6x1f
10
- MARKDOWN_PATTERN = /\[ ([^\[\]]*?) \] \( ((https?:\/\/.*?) | (mailto:.*?)) \) /x
20
+ # Attempt at only matching pairs of parens per
21
+ # the markdown spec http://spec.commonmark.org/0.27/#links
22
+ #
23
+ # http://rubular.com/r/y107aevxqT
24
+ MARKDOWN_PATTERN = %r{
25
+ \[ ([^\[\]]*?) \]
26
+ \( ((https?://.*?) | (mailto:.*?)) \)
27
+ (?! [#{VALID_PATH_CHARS}]* \) )
28
+ }x
11
29
 
12
30
  class << self
13
31
  def format string, opts={}
@@ -17,24 +35,21 @@ module Slack
17
35
 
18
36
  attr_reader :formats
19
37
 
20
- def initialize string, formats: [:html, :markdown]
38
+ def initialize string, formats: %i[html markdown]
21
39
  @formats = formats
22
40
  @orig = string.respond_to?(:scrub) ? string.scrub : string
23
41
  end
24
42
 
25
- # rubocop:disable Style/GuardClause
43
+ # rubocop:disable Lint/RescueWithoutErrorClass
26
44
  def formatted
27
45
  return @orig unless @orig.respond_to?(:gsub)
28
46
 
29
47
  sub_markdown_links(sub_html_links(@orig))
30
48
  rescue => e
31
- if RUBY_VERSION < "2.1" && e.message.include?("invalid byte sequence")
32
- raise e, "#{e.message}. Consider including the 'string-scrub' gem to strip invalid characters"
33
- else
34
- raise e
35
- end
49
+ raise e unless RUBY_VERSION < "2.1" && e.message.include?("invalid byte sequence")
50
+ raise e, "#{e.message}. Consider including the 'string-scrub' gem to strip invalid characters"
36
51
  end
37
- # rubocop:enable Style/GuardClause
52
+ # rubocop:enable Lint/RescueWithoutErrorClass
38
53
 
39
54
  private
40
55
 
@@ -1,6 +1,7 @@
1
1
  # frozen_string_literal: true
2
+
2
3
  module Slack
3
4
  class Notifier
4
- VERSION = "2.3.1".freeze # rubocop:disable Style/RedundantFreeze
5
+ VERSION = "2.3.2".freeze # rubocop:disable Style/RedundantFreeze
5
6
  end
6
7
  end
@@ -1,5 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
  # encoding: utf-8
3
+
3
4
  require "spec_helper"
4
5
 
5
6
  RSpec.describe Slack::Notifier do
@@ -54,15 +55,15 @@ RSpec.describe Slack::Notifier do
54
55
  text: "attachment message [hodor](http://winterfell.com)",
55
56
  fallback: "fallback message" } } =>
56
57
  { payload: { attachments: [{ color: "#000",
57
- text: "attachment message <http://winterfell.com|hodor>",
58
- fallback: "fallback message" }] } },
58
+ text: "attachment message <http://winterfell.com|hodor>",
59
+ fallback: "fallback message" }] } },
59
60
 
60
61
  { attachments: { color: "#000",
61
62
  text: nil,
62
63
  fallback: "fallback message" } } =>
63
64
  { payload: { attachments: [{ color: "#000",
64
- text: nil,
65
- fallback: "fallback message" }] } },
65
+ text: nil,
66
+ fallback: "fallback message" }] } },
66
67
 
67
68
  { text: "hello", http_options: { timeout: 5 } } =>
68
69
  { http_options: { timeout: 5 }, payload: { text: "hello" } }
@@ -1,5 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
  # encoding: utf-8
3
+
3
4
  require_relative "../../lib/slack-notifier"
4
5
 
5
6
  ruby = if defined?(JRUBY_VERSION)
@@ -46,17 +46,17 @@ RSpec.describe Slack::Notifier::Config do
46
46
  it "is [:format_message, :format_attachments, :at] if not set" do
47
47
  subject = described_class.new
48
48
 
49
- expect(subject.middleware).to eq [:format_message, :format_attachments, :at, :channels]
49
+ expect(subject.middleware).to eq %i[format_message format_attachments at channels]
50
50
  end
51
51
 
52
52
  it "takes an array or a splat of args" do
53
53
  subject = described_class.new
54
54
 
55
55
  subject.middleware :layer, :two
56
- expect(subject.middleware).to eq [:layer, :two]
56
+ expect(subject.middleware).to eq %i[layer two]
57
57
 
58
- subject.middleware [:one, :layer]
59
- expect(subject.middleware).to eq [:one, :layer]
58
+ subject.middleware %i[one layer]
59
+ expect(subject.middleware).to eq %i[one layer]
60
60
  end
61
61
 
62
62
  it "allows passing options to middleware stack" do
@@ -3,7 +3,7 @@
3
3
  RSpec.describe Slack::Notifier::PayloadMiddleware::At do
4
4
  it "can handle array at" do
5
5
  subject = described_class.new(:notifier)
6
- payload = { text: "hello", at: [:john, :ken, :here] }
6
+ payload = { text: "hello", at: %i[john ken here] }
7
7
 
8
8
  expect(subject.call(payload)).to eq text: "<@john> <@ken> <!here> hello"
9
9
  end
@@ -1,4 +1,5 @@
1
1
  # frozen_string_literal: true
2
+
2
3
  RSpec.describe Slack::Notifier::PayloadMiddleware::Base do
3
4
  before(:each) do
4
5
  @registry_backup = Slack::Notifier::PayloadMiddleware.registry.dup
@@ -1,4 +1,5 @@
1
1
  # frozen_string_literal: true
2
+
2
3
  RSpec.describe Slack::Notifier::PayloadMiddleware::FormatAttachments do
3
4
  it "passes the text of attachments through linkformatter with options[:formats]" do
4
5
  subject = described_class.new(:notifier, formats: [:html])
@@ -10,30 +11,30 @@ RSpec.describe Slack::Notifier::PayloadMiddleware::FormatAttachments do
10
11
  it "searches through string or symbol keys" do
11
12
  subject = described_class.new(:notifier)
12
13
  expect(Slack::Notifier::Util::LinkFormatter).to receive(:format)
13
- .with("hello", formats: [:html, :markdown])
14
+ .with("hello", formats: %i[html markdown])
14
15
  subject.call("attachments" => [{ "text" => "hello" }])
15
16
 
16
17
  subject = described_class.new(:notifier)
17
18
  expect(Slack::Notifier::Util::LinkFormatter).to receive(:format)
18
- .with("hello", formats: [:html, :markdown])
19
+ .with("hello", formats: %i[html markdown])
19
20
  subject.call(attachments: [{ text: "hello" }])
20
21
  end
21
22
 
22
23
  it "can handle a single attachment" do
23
24
  subject = described_class.new(:notifier)
24
25
  expect(Slack::Notifier::Util::LinkFormatter).to receive(:format)
25
- .with("hello", formats: [:html, :markdown])
26
+ .with("hello", formats: %i[html markdown])
26
27
  subject.call(attachments: { text: "hello" })
27
28
  end
28
29
 
29
30
  it "wraps attachment into array if given as a single hash" do
30
- params = {
31
+ params = {
31
32
  attachments: { text: "hello" }
32
33
  }
33
34
  payload = {
34
35
  attachments: [{ text: "hello" }]
35
36
  }
36
- subject = described_class.new(:notifier);
37
+ subject = described_class.new(:notifier)
37
38
 
38
39
  expect(subject.call(params)).to eq payload
39
40
  end
@@ -1,4 +1,5 @@
1
1
  # frozen_string_literal: true
2
+
2
3
  RSpec.describe Slack::Notifier::PayloadMiddleware::FormatMessage do
3
4
  it "passes the text through linkformatter with options[:formats]" do
4
5
  subject = described_class.new(:notifier, formats: [:html])
@@ -8,7 +9,7 @@ RSpec.describe Slack::Notifier::PayloadMiddleware::FormatMessage do
8
9
 
9
10
  subject = described_class.new(:notifier)
10
11
  expect(Slack::Notifier::Util::LinkFormatter).to receive(:format)
11
- .with("hello", formats: [:html, :markdown])
12
+ .with("hello", formats: %i[html markdown])
12
13
  subject.call(text: "hello")
13
14
 
14
15
  subject = described_class.new(:notifier, formats: [:markdown])
@@ -1,4 +1,5 @@
1
1
  # frozen_string_literal: true
2
+
2
3
  RSpec.describe Slack::Notifier::PayloadMiddleware::Stack do
3
4
  let(:return_one) do
4
5
  double(call: 1)
@@ -113,7 +114,6 @@ RSpec.describe Slack::Notifier::PayloadMiddleware::Stack do
113
114
  subject.set(:return_one_twice, :return_one_twice, :return_two)
114
115
 
115
116
  expect(subject.call(5)).to eq [2, 2, 2, 2]
116
-
117
117
  end
118
118
  end
119
119
  end
@@ -1,4 +1,5 @@
1
1
  # frozen_string_literal: true
2
+
2
3
  RSpec.describe Slack::Notifier::PayloadMiddleware do
3
4
  before(:each) do
4
5
  @registry_backup = described_class.registry.dup
@@ -1,4 +1,5 @@
1
1
  # frozen_string_literal: true
2
+
2
3
  RSpec.describe Slack::Notifier::Util::HTTPClient do
3
4
  describe "::post" do
4
5
  it "initializes Util::HTTPClient with the given uri and params then calls" do
@@ -6,7 +7,7 @@ RSpec.describe Slack::Notifier::Util::HTTPClient do
6
7
 
7
8
  expect(described_class)
8
9
  .to receive(:new).with("uri", "params")
9
- .and_return(http_post_double)
10
+ .and_return(http_post_double)
10
11
  expect(http_post_double).to receive(:call)
11
12
 
12
13
  described_class.post "uri", "params"
@@ -1,5 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
  # encoding: utf-8
3
+
3
4
  # rubocop:disable Metrics/LineLength
4
5
  RSpec.describe Slack::Notifier::Util::LinkFormatter do
5
6
  describe "::format" do
@@ -56,7 +57,7 @@ RSpec.describe Slack::Notifier::Util::LinkFormatter do
56
57
  end
57
58
  end
58
59
 
59
- it 'doesn\'t replace valid Japanese' do
60
+ it "doesn't replace valid Japanese" do
60
61
  formatted = described_class.format("こんにちは")
61
62
  expect(formatted).to eq "こんにちは"
62
63
  end
@@ -71,6 +72,68 @@ RSpec.describe Slack::Notifier::Util::LinkFormatter do
71
72
  expect(formatted).to eq "<mailto:john@example.com|John>"
72
73
  end
73
74
 
75
+ it "handles links with trailing parentheses" do
76
+ formatted = described_class.format("Hello World, enjoy [foo(bar)](http://example.com/foo(bar))<a href='http://example.com/bar(foo)'>bar(foo)</a>")
77
+ expect(formatted).to include("http://example.com/foo(bar)|foo(bar)")
78
+ expect(formatted).to include("http://example.com/bar(foo)|bar(foo)")
79
+ end
80
+
81
+ it "formats a number of differently formatted links" do
82
+ input_output = {
83
+ "Hello World, enjoy [this](http://example.com)." =>
84
+ "Hello World, enjoy <http://example.com|this>.",
85
+
86
+ "Hello World, enjoy [[this](http://example.com) in brackets]." =>
87
+ "Hello World, enjoy [<http://example.com|this> in brackets].",
88
+
89
+ "Hello World, enjoy ([this](http://example.com) in parens)." =>
90
+ "Hello World, enjoy (<http://example.com|this> in parens).",
91
+
92
+ "Hello World, enjoy [](http://example.com)." =>
93
+ "Hello World, enjoy <http://example.com>.",
94
+
95
+ "Hello World, enjoy [link with query](http://example.com?foo=bar)." =>
96
+ "Hello World, enjoy <http://example.com?foo=bar|link with query>.",
97
+
98
+ "Hello World, enjoy [link with fragment](http://example.com/#foo-bar)." =>
99
+ "Hello World, enjoy <http://example.com/#foo-bar|link with fragment>.",
100
+
101
+ "Hello World, enjoy [link with parens](http://example.com/foo(bar)/baz)." =>
102
+ "Hello World, enjoy <http://example.com/foo(bar)/baz|link with parens>.",
103
+
104
+ "Hello World, enjoy [link with query](http://example.com/(parens)?foo=bar)." =>
105
+ "Hello World, enjoy <http://example.com/(parens)?foo=bar|link with query>.",
106
+
107
+ "Hello World, enjoy [link with parens](http://example.com/baz?bang=foo(bar))." =>
108
+ "Hello World, enjoy <http://example.com/baz?bang=foo(bar)|link with parens>.",
109
+
110
+ "Hello World, enjoy [link with fragment](http://example.com/(parens)#foo-bar)." =>
111
+ "Hello World, enjoy <http://example.com/(parens)#foo-bar|link with fragment>.",
112
+
113
+ "Hello World, enjoy [link with fragment](http://example.com/#foo-bar=(baz))." =>
114
+ "Hello World, enjoy <http://example.com/#foo-bar=(baz)|link with fragment>.",
115
+
116
+ "Hello World, enjoy [this](http://example.com?foo=bar)[this2](http://example2.com)." =>
117
+ "Hello World, enjoy <http://example.com?foo=bar|this><http://example2.com|this2>.",
118
+
119
+ "Hello World, enjoy [this](http://example.com?foo=bar) [this2](http://example2.com/#fragment)." =>
120
+ "Hello World, enjoy <http://example.com?foo=bar|this> <http://example2.com/#fragment|this2>.",
121
+
122
+ "Hello World, enjoy [this](http://example.com)<a href='http://example2.com'>this2</a>." =>
123
+ "Hello World, enjoy <http://example.com|this><http://example2.com|this2>.",
124
+
125
+ "Hello world, [John](mailto:john@example.com)." =>
126
+ "Hello world, <mailto:john@example.com|John>.",
127
+
128
+ "Hello World, enjoy [foo(bar)](http://example.com/foo(bar))<a href='http://example.com/bar(foo)'>bar(foo)</a>" =>
129
+ "Hello World, enjoy <http://example.com/foo(bar)|foo(bar)><http://example.com/bar(foo)|bar(foo)>"
130
+ }
131
+
132
+ input_output.each do |input, output|
133
+ expect(described_class.format(input)).to eq output
134
+ end
135
+ end
136
+
74
137
  context "with a configured stack" do
75
138
  it "only formats html if html is the only item in formats" do
76
139
  formatted = described_class.format("Hello World, enjoy [this](http://example.com)<a href='http://example2.com'>this2</a>.", formats: [:html])
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: 2.3.1
4
+ version: 2.3.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Steven Sloan
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2017-08-12 00:00:00.000000000 Z
11
+ date: 2018-01-11 00:00:00.000000000 Z
12
12
  dependencies: []
13
13
  description: " A slim ruby wrapper for posting to slack webhooks "
14
14
  email: