slack-notifier 2.3.1 → 2.3.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/lib/slack-notifier.rb +1 -0
- data/lib/slack-notifier/config.rb +6 -5
- data/lib/slack-notifier/payload_middleware.rb +1 -0
- data/lib/slack-notifier/payload_middleware/base.rb +1 -0
- data/lib/slack-notifier/payload_middleware/format_attachments.rb +3 -2
- data/lib/slack-notifier/payload_middleware/format_message.rb +2 -1
- data/lib/slack-notifier/payload_middleware/stack.rb +1 -0
- data/lib/slack-notifier/util/escape.rb +1 -0
- data/lib/slack-notifier/util/http_client.rb +2 -1
- data/lib/slack-notifier/util/link_formatter.rb +26 -11
- data/lib/slack-notifier/version.rb +2 -1
- data/spec/end_to_end_spec.rb +5 -4
- data/spec/integration/ping_integration_test.rb +1 -0
- data/spec/lib/slack-notifier/config_spec.rb +4 -4
- data/spec/lib/slack-notifier/payload_middleware/at_spec.rb +1 -1
- data/spec/lib/slack-notifier/payload_middleware/base_spec.rb +1 -0
- data/spec/lib/slack-notifier/payload_middleware/format_attachments_spec.rb +6 -5
- data/spec/lib/slack-notifier/payload_middleware/format_message_spec.rb +2 -1
- data/spec/lib/slack-notifier/payload_middleware/stack_spec.rb +1 -1
- data/spec/lib/slack-notifier/payload_middleware_spec.rb +1 -0
- data/spec/lib/slack-notifier/util/http_client_spec.rb +2 -1
- data/spec/lib/slack-notifier/util/link_formatter_spec.rb +64 -1
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 2912c5289963e0ecbc66d6b89fb0bbfb288ab43a
|
4
|
+
data.tar.gz: 78e320255b7ffc02f5dcc363acae1154f40c2b5f
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 714ae944d20a181d147bbd88b62a42e73763f6f204c958ac69581fc33bdd91f406ee7c8f495c34028e936340ffea988cb3fe3bff32a09bb43db73e35ba89127a
|
7
|
+
data.tar.gz: c0138c50280c0f56ec1c3bd0094650f3c39a323be3acd818cca361f41febf920b2f63a6d36157c84612ba455625b2ae3c563891df746585e993bfa832cd8f447
|
data/lib/slack-notifier.rb
CHANGED
@@ -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
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
9
|
+
@middleware = %i[
|
10
|
+
format_message
|
11
|
+
format_attachments
|
12
|
+
at
|
13
|
+
channels
|
13
14
|
]
|
14
15
|
end
|
15
16
|
|
@@ -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: [
|
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
|
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: [
|
9
|
+
options formats: %i[html markdown]
|
9
10
|
|
10
11
|
def call payload={}
|
11
12
|
return payload unless payload[:text]
|
@@ -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 =
|
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
|
-
#
|
10
|
-
|
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: [
|
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
|
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
|
-
|
32
|
-
|
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
|
52
|
+
# rubocop:enable Lint/RescueWithoutErrorClass
|
38
53
|
|
39
54
|
private
|
40
55
|
|
data/spec/end_to_end_spec.rb
CHANGED
@@ -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
|
-
|
58
|
-
|
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
|
-
|
65
|
-
|
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" } }
|
@@ -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 [
|
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 [
|
56
|
+
expect(subject.middleware).to eq %i[layer two]
|
57
57
|
|
58
|
-
subject.middleware [
|
59
|
-
expect(subject.middleware).to eq [
|
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: [
|
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::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: [
|
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: [
|
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: [
|
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: [
|
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::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
|
-
|
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
|
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.
|
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:
|
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:
|