slack-notifier 1.5.1 → 2.0.0
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 +35 -60
- data/lib/slack-notifier/config.rb +37 -0
- data/lib/slack-notifier/payload_middleware.rb +21 -0
- data/lib/slack-notifier/payload_middleware/base.rb +35 -0
- data/lib/slack-notifier/payload_middleware/format_attachments.rb +37 -0
- data/lib/slack-notifier/payload_middleware/format_message.rb +19 -0
- data/lib/slack-notifier/payload_middleware/stack.rb +35 -0
- data/lib/slack-notifier/util/escape.rb +15 -0
- data/lib/slack-notifier/util/http_client.rb +53 -0
- data/lib/slack-notifier/util/link_formatter.rb +63 -0
- data/lib/slack-notifier/version.rb +2 -1
- data/spec/end_to_end_spec.rb +84 -0
- data/spec/integration/ping_integration_test.rb +12 -5
- data/spec/lib/slack-notifier/config_spec.rb +71 -0
- data/spec/lib/slack-notifier/payload_middleware/base_spec.rb +75 -0
- data/spec/lib/slack-notifier/payload_middleware/format_attachments_spec.rb +35 -0
- data/spec/lib/slack-notifier/payload_middleware/format_message_spec.rb +26 -0
- data/spec/lib/slack-notifier/payload_middleware/stack_spec.rb +93 -0
- data/spec/lib/slack-notifier/payload_middleware_spec.rb +32 -0
- data/spec/lib/slack-notifier/util/http_client_spec.rb +34 -0
- data/spec/lib/slack-notifier/{link_formatter_spec.rb → util/link_formatter_spec.rb} +30 -19
- data/spec/lib/slack-notifier_spec.rb +62 -128
- data/spec/spec_helper.rb +20 -5
- metadata +30 -9
- data/lib/slack-notifier/default_http_client.rb +0 -51
- data/lib/slack-notifier/link_formatter.rb +0 -62
- data/spec/lib/slack-notifier/default_http_client_spec.rb +0 -37
@@ -0,0 +1,84 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
# encoding: utf-8
|
3
|
+
require "spec_helper"
|
4
|
+
|
5
|
+
RSpec.describe Slack::Notifier do
|
6
|
+
{
|
7
|
+
{ text: "hello" } =>
|
8
|
+
{ payload: { text: "hello" } },
|
9
|
+
|
10
|
+
{ text: "[hello](http://example.com/world)" } =>
|
11
|
+
{ payload: { text: "<http://example.com/world|hello>" } },
|
12
|
+
|
13
|
+
{ text: '<a href="http://example.com">example</a>' } =>
|
14
|
+
{ payload: { text: "<http://example.com|example>" } },
|
15
|
+
|
16
|
+
{ text: "hello/こんにちは from notifier test" } =>
|
17
|
+
{ payload: { text: "hello/こんにちは from notifier test" } },
|
18
|
+
|
19
|
+
{ text: "Hello World, enjoy [](http://example.com)." } =>
|
20
|
+
{ payload: { text: "Hello World, enjoy <http://example.com>." } },
|
21
|
+
|
22
|
+
{ text: "Hello World, enjoy [this](http://example.com)[this2](http://example2.com)" } =>
|
23
|
+
{ payload: { text: "Hello World, enjoy <http://example.com|this><http://example2.com|this2>" } },
|
24
|
+
|
25
|
+
{ text: "[John](mailto:john@example.com)" } =>
|
26
|
+
{ payload: { text: "<mailto:john@example.com|John>" } },
|
27
|
+
|
28
|
+
{ text: '<a href="mailto:john@example.com">John</a>' } =>
|
29
|
+
{ payload: { text: "<mailto:john@example.com|John>" } },
|
30
|
+
|
31
|
+
{ text: "hello", channel: "hodor" } =>
|
32
|
+
{ payload: { text: "hello", channel: "hodor" } },
|
33
|
+
|
34
|
+
{ text: "the message", channel: "foo", attachments: [{ color: "#000",
|
35
|
+
text: "attachment message",
|
36
|
+
fallback: "fallback message" }] } =>
|
37
|
+
{ payload: { text: "the message",
|
38
|
+
channel: "foo",
|
39
|
+
attachments: [{ color: "#000",
|
40
|
+
text: "attachment message",
|
41
|
+
fallback: "fallback message" }] } },
|
42
|
+
|
43
|
+
{ attachments: [{ color: "#000",
|
44
|
+
text: "attachment message",
|
45
|
+
fallback: "fallback message" }] } =>
|
46
|
+
{ payload: { attachments: [{ color: "#000",
|
47
|
+
text: "attachment message",
|
48
|
+
fallback: "fallback message" }] } },
|
49
|
+
|
50
|
+
{ attachments: { color: "#000",
|
51
|
+
text: "attachment message [hodor](http://winterfell.com)",
|
52
|
+
fallback: "fallback message" } } =>
|
53
|
+
{ payload: { attachments: { color: "#000",
|
54
|
+
text: "attachment message <http://winterfell.com|hodor>",
|
55
|
+
fallback: "fallback message" } } },
|
56
|
+
|
57
|
+
{ text: "hello", http_options: { timeout: 5 } } =>
|
58
|
+
{ http_options: { timeout: 5 }, payload: { text: "hello" } }
|
59
|
+
}.each do |args, payload|
|
60
|
+
it "sends correct payload for #post(#{args})" do
|
61
|
+
http_client = class_double("Slack::Notifier::Util::HTTPClient", post: nil)
|
62
|
+
notifier = Slack::Notifier.new "http://example.com", http_client: http_client
|
63
|
+
payload[:payload] = payload[:payload].to_json
|
64
|
+
|
65
|
+
expect(http_client).to receive(:post)
|
66
|
+
.with(URI.parse("http://example.com"), payload)
|
67
|
+
|
68
|
+
notifier.post(args)
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
it "applies options given to middleware" do
|
73
|
+
client = class_double("Slack::Notifier::Util::HTTPClient", post: nil)
|
74
|
+
notifier = Slack::Notifier.new "http://example.com" do
|
75
|
+
http_client client
|
76
|
+
middleware format_message: { formats: [] }
|
77
|
+
end
|
78
|
+
|
79
|
+
expect(client).to receive(:post)
|
80
|
+
.with(URI.parse("http://example.com"), payload: { text: "Hello [world](http://example.com)!" }.to_json)
|
81
|
+
|
82
|
+
notifier.post text: "Hello [world](http://example.com)!"
|
83
|
+
end
|
84
|
+
end
|
@@ -1,7 +1,14 @@
|
|
1
|
+
# frozen_string_literal: true
|
1
2
|
# encoding: utf-8
|
2
|
-
require_relative
|
3
|
+
require_relative "../../lib/slack-notifier"
|
3
4
|
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
5
|
+
ruby = if defined?(JRUBY_VERSION)
|
6
|
+
"jruby #{JRUBY_VERSION}"
|
7
|
+
else
|
8
|
+
"ruby #{RUBY_VERSION}"
|
9
|
+
end
|
10
|
+
puts "testing with #{ruby}"
|
11
|
+
|
12
|
+
notifier = Slack::Notifier.new ENV["SLACK_WEBHOOK_URL"], username: "notifier"
|
13
|
+
notifier.ping "hello/こんにちは from notifier test script on #{ruby}\225"
|
14
|
+
notifier.ping attachments: [{ color: "#1BF5AF", fallback: "fallback", text: "attachment" }]
|
@@ -0,0 +1,71 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
RSpec.describe Slack::Notifier::Config do
|
4
|
+
describe "#http_client" do
|
5
|
+
it "is Util::HTTPClient if not set" do
|
6
|
+
subject = described_class.new
|
7
|
+
expect(subject.http_client).to eq Slack::Notifier::Util::HTTPClient
|
8
|
+
end
|
9
|
+
|
10
|
+
it "sets a new client class if given one" do
|
11
|
+
new_client = class_double("Slack::Notifier::Util::HTTPClient", post: nil)
|
12
|
+
subject = described_class.new
|
13
|
+
subject.http_client new_client
|
14
|
+
expect(subject.http_client).to eq new_client
|
15
|
+
end
|
16
|
+
|
17
|
+
it "raises an ArgumentError if given class does not respond to ::post" do
|
18
|
+
subject = described_class.new
|
19
|
+
expect do
|
20
|
+
subject.http_client :nope
|
21
|
+
end.to raise_error ArgumentError
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
describe "#defaults" do
|
26
|
+
it "is an empty hash by default" do
|
27
|
+
subject = described_class.new
|
28
|
+
expect(subject.defaults).to eq({})
|
29
|
+
end
|
30
|
+
|
31
|
+
it "sets a hash to default if given" do
|
32
|
+
subject = described_class.new
|
33
|
+
subject.defaults foo: :bar
|
34
|
+
expect(subject.defaults).to eq foo: :bar
|
35
|
+
end
|
36
|
+
|
37
|
+
it "raises ArgumentError if not given a hash" do
|
38
|
+
subject = described_class.new
|
39
|
+
expect do
|
40
|
+
subject.defaults :nope
|
41
|
+
end.to raise_error ArgumentError
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
describe "#middleware" do
|
46
|
+
it "is [:format_message, :format_attachments] if not set" do
|
47
|
+
subject = described_class.new
|
48
|
+
|
49
|
+
expect(subject.middleware).to eq [:format_message, :format_attachments]
|
50
|
+
end
|
51
|
+
|
52
|
+
it "takes an array or a splat of args" do
|
53
|
+
subject = described_class.new
|
54
|
+
|
55
|
+
subject.middleware :layer, :two
|
56
|
+
expect(subject.middleware).to eq [:layer, :two]
|
57
|
+
|
58
|
+
subject.middleware [:one, :layer]
|
59
|
+
expect(subject.middleware).to eq [:one, :layer]
|
60
|
+
end
|
61
|
+
|
62
|
+
it "allows passing options to middleware stack" do
|
63
|
+
subject = described_class.new
|
64
|
+
subject.middleware one: { opts: :for_one },
|
65
|
+
two: { opts: :for_two }
|
66
|
+
|
67
|
+
expect(subject.middleware).to eq one: { opts: :for_one },
|
68
|
+
two: { opts: :for_two }
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
@@ -0,0 +1,75 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
RSpec.describe Slack::Notifier::PayloadMiddleware::Base do
|
3
|
+
before(:each) do
|
4
|
+
@registry_backup = Slack::Notifier::PayloadMiddleware.registry.dup
|
5
|
+
Slack::Notifier::PayloadMiddleware.send(:remove_instance_variable, :@registry)
|
6
|
+
end
|
7
|
+
|
8
|
+
after(:each) do
|
9
|
+
# cleanup middleware registry
|
10
|
+
Slack::Notifier::PayloadMiddleware.registry
|
11
|
+
Slack::Notifier::PayloadMiddleware.send(:remove_instance_variable, :@registry)
|
12
|
+
|
13
|
+
# cleanup object constants
|
14
|
+
Object.send(:remove_const, :Subject) if Object.constants.include?(:Subject)
|
15
|
+
Slack::Notifier::PayloadMiddleware.send(:instance_variable_set, :@registry, @registry_backup)
|
16
|
+
end
|
17
|
+
|
18
|
+
describe "::middleware_name" do
|
19
|
+
it "registers class w/ given name" do
|
20
|
+
class Subject < Slack::Notifier::PayloadMiddleware::Base
|
21
|
+
end
|
22
|
+
|
23
|
+
expect(Slack::Notifier::PayloadMiddleware)
|
24
|
+
.to receive(:register).with(Subject, :subject)
|
25
|
+
|
26
|
+
class Subject
|
27
|
+
middleware_name :subject
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
it "uses symbolized name to register" do
|
32
|
+
class Subject < Slack::Notifier::PayloadMiddleware::Base
|
33
|
+
end
|
34
|
+
|
35
|
+
expect(Slack::Notifier::PayloadMiddleware)
|
36
|
+
.to receive(:register).with(Subject, :subject)
|
37
|
+
|
38
|
+
class Subject
|
39
|
+
middleware_name "subject"
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
describe "::options" do
|
45
|
+
it "allows setting default options for a middleware" do
|
46
|
+
class Subject < Slack::Notifier::PayloadMiddleware::Base
|
47
|
+
options foo: :bar
|
48
|
+
end
|
49
|
+
|
50
|
+
subject = Subject.new(:notifier)
|
51
|
+
expect(subject.options).to eq foo: :bar
|
52
|
+
|
53
|
+
subject = Subject.new(:notifier, foo: :baz)
|
54
|
+
expect(subject.options).to eq foo: :baz
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
describe "#initialize" do
|
59
|
+
it "sets given notifier as notifier" do
|
60
|
+
expect(described_class.new(:notifier).notifier).to eq :notifier
|
61
|
+
end
|
62
|
+
|
63
|
+
it "sets given options as opts" do
|
64
|
+
expect(described_class.new(:notifier, opts: :options).options).to eq opts: :options
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
describe "#call" do
|
69
|
+
it "raises NoMethodError (expects subclass to define)" do
|
70
|
+
expect do
|
71
|
+
described_class.new(:notifier).call
|
72
|
+
end.to raise_exception NoMethodError
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
RSpec.describe Slack::Notifier::PayloadMiddleware::FormatAttachments do
|
3
|
+
it "passes the text of attachments through linkformatter with options[:formats]" do
|
4
|
+
subject = described_class.new(:notifier, formats: [:html])
|
5
|
+
expect(Slack::Notifier::Util::LinkFormatter).to receive(:format)
|
6
|
+
.with("hello", formats: [:html])
|
7
|
+
subject.call(attachments: [{ text: "hello" }])
|
8
|
+
end
|
9
|
+
|
10
|
+
it "searches through string or symbol keys" do
|
11
|
+
subject = described_class.new(:notifier)
|
12
|
+
expect(Slack::Notifier::Util::LinkFormatter).to receive(:format)
|
13
|
+
.with("hello", formats: [:html, :markdown])
|
14
|
+
subject.call("attachments" => [{ "text" => "hello" }])
|
15
|
+
|
16
|
+
subject = described_class.new(:notifier)
|
17
|
+
expect(Slack::Notifier::Util::LinkFormatter).to receive(:format)
|
18
|
+
.with("hello", formats: [:html, :markdown])
|
19
|
+
subject.call(attachments: [{ text: "hello" }])
|
20
|
+
end
|
21
|
+
|
22
|
+
it "can handle a single attachment" do
|
23
|
+
subject = described_class.new(:notifier)
|
24
|
+
expect(Slack::Notifier::Util::LinkFormatter).to receive(:format)
|
25
|
+
.with("hello", formats: [:html, :markdown])
|
26
|
+
subject.call(attachments: { text: "hello" })
|
27
|
+
end
|
28
|
+
|
29
|
+
it "returns the payload unmodified if not :attachments key" do
|
30
|
+
payload = { foo: :bar }
|
31
|
+
subject = described_class.new(:notifier)
|
32
|
+
|
33
|
+
expect(subject.call(payload)).to eq payload
|
34
|
+
end
|
35
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
RSpec.describe Slack::Notifier::PayloadMiddleware::FormatMessage do
|
3
|
+
it "passes the text through linkformatter with options[:formats]" do
|
4
|
+
subject = described_class.new(:notifier, formats: [:html])
|
5
|
+
expect(Slack::Notifier::Util::LinkFormatter).to receive(:format)
|
6
|
+
.with("hello", formats: [:html])
|
7
|
+
subject.call(text: "hello")
|
8
|
+
|
9
|
+
subject = described_class.new(:notifier)
|
10
|
+
expect(Slack::Notifier::Util::LinkFormatter).to receive(:format)
|
11
|
+
.with("hello", formats: [:html, :markdown])
|
12
|
+
subject.call(text: "hello")
|
13
|
+
|
14
|
+
subject = described_class.new(:notifier, formats: [:markdown])
|
15
|
+
expect(Slack::Notifier::Util::LinkFormatter).to receive(:format)
|
16
|
+
.with("hello", formats: [:markdown])
|
17
|
+
subject.call(text: "hello")
|
18
|
+
end
|
19
|
+
|
20
|
+
it "returns the payload unmodified if not :text key" do
|
21
|
+
payload = { foo: :bar }
|
22
|
+
subject = described_class.new(:notifier)
|
23
|
+
|
24
|
+
expect(subject.call(payload)).to eq payload
|
25
|
+
end
|
26
|
+
end
|
@@ -0,0 +1,93 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
RSpec.describe Slack::Notifier::PayloadMiddleware::Stack do
|
3
|
+
let(:return_one) do
|
4
|
+
double(call: 1)
|
5
|
+
end
|
6
|
+
|
7
|
+
let(:return_two) do
|
8
|
+
double(call: 2)
|
9
|
+
end
|
10
|
+
|
11
|
+
let(:return_three) do
|
12
|
+
double(call: 3)
|
13
|
+
end
|
14
|
+
|
15
|
+
before(:each) do
|
16
|
+
# setup our middleware in the registry
|
17
|
+
@registry_backup = Slack::Notifier::PayloadMiddleware.registry.dup
|
18
|
+
Slack::Notifier::PayloadMiddleware.send(:remove_instance_variable, :@registry)
|
19
|
+
|
20
|
+
Slack::Notifier::PayloadMiddleware.register return_one, :return_one
|
21
|
+
Slack::Notifier::PayloadMiddleware.register return_two, :return_two
|
22
|
+
Slack::Notifier::PayloadMiddleware.register return_three, :return_three
|
23
|
+
end
|
24
|
+
|
25
|
+
after(:each) do
|
26
|
+
# cleanup middleware registry
|
27
|
+
Slack::Notifier::PayloadMiddleware.send(:remove_instance_variable, :@registry)
|
28
|
+
Slack::Notifier::PayloadMiddleware.send(:instance_variable_set, :@registry, @registry_backup)
|
29
|
+
end
|
30
|
+
|
31
|
+
describe "::initialize" do
|
32
|
+
it "sets notifier to given notifier" do
|
33
|
+
expect(described_class.new(:notifier).notifier).to eq :notifier
|
34
|
+
end
|
35
|
+
|
36
|
+
it "has empty stack" do
|
37
|
+
expect(described_class.new(:notifier).stack).to match_array []
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
describe "#set" do
|
42
|
+
it "initializes each middleware w/ the notifier instance" do
|
43
|
+
expect(return_one).to receive(:new).with(:notifier)
|
44
|
+
expect(return_two).to receive(:new).with(:notifier)
|
45
|
+
|
46
|
+
described_class.new(:notifier).set(:return_one, :return_two)
|
47
|
+
end
|
48
|
+
|
49
|
+
it "creates the stack in an array" do
|
50
|
+
allow(return_one).to receive(:new).and_return(return_one)
|
51
|
+
allow(return_two).to receive(:new).and_return(return_two)
|
52
|
+
|
53
|
+
subject = described_class.new(:notifier)
|
54
|
+
subject.set(:return_one, :return_two)
|
55
|
+
|
56
|
+
expect(subject.stack).to be_a Array
|
57
|
+
expect(subject.stack.first.call).to eq 1
|
58
|
+
expect(subject.stack.last.call).to eq 2
|
59
|
+
end
|
60
|
+
|
61
|
+
it "creates a stack from hashes passing them as opts" do
|
62
|
+
expect(return_one).to receive(:new).with(:notifier, opts: :for_one)
|
63
|
+
expect(return_two).to receive(:new).with(:notifier, opts: :for_two)
|
64
|
+
|
65
|
+
subject = described_class.new(:notifier)
|
66
|
+
subject.set return_one: { opts: :for_one },
|
67
|
+
return_two: { opts: :for_two }
|
68
|
+
end
|
69
|
+
|
70
|
+
it "raises if a middleware is missing" do
|
71
|
+
expect do
|
72
|
+
described_class.new(:notifier).set(:missing)
|
73
|
+
end.to raise_exception KeyError
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
describe "#call" do
|
78
|
+
it "calls the middleware in order, passing return of each to the next" do
|
79
|
+
allow(return_one).to receive(:new).and_return(return_one)
|
80
|
+
allow(return_two).to receive(:new).and_return(return_two)
|
81
|
+
allow(return_three).to receive(:new).and_return(return_three)
|
82
|
+
|
83
|
+
subject = described_class.new(:notifier)
|
84
|
+
subject.set(:return_one, :return_three, :return_two)
|
85
|
+
|
86
|
+
expect(return_one).to receive(:call).with(5)
|
87
|
+
expect(return_three).to receive(:call).with(1)
|
88
|
+
expect(return_two).to receive(:call).with(3)
|
89
|
+
|
90
|
+
expect(subject.call(5)).to eq 2
|
91
|
+
end
|
92
|
+
end
|
93
|
+
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
RSpec.describe Slack::Notifier::PayloadMiddleware do
|
3
|
+
before(:each) do
|
4
|
+
@registry_backup = described_class.registry.dup
|
5
|
+
Slack::Notifier::PayloadMiddleware.send(:remove_instance_variable, :@registry)
|
6
|
+
end
|
7
|
+
|
8
|
+
after(:each) do
|
9
|
+
described_class.send(:remove_instance_variable, :@registry)
|
10
|
+
described_class.send(:instance_variable_set, :@registry, @registry_backup)
|
11
|
+
end
|
12
|
+
|
13
|
+
describe "::registry" do
|
14
|
+
it "returns a hash if nothing set" do
|
15
|
+
expect(described_class.registry).to eq({})
|
16
|
+
end
|
17
|
+
|
18
|
+
it "returns memoized version if already set" do
|
19
|
+
described_class.instance_variable_set(:@registry, "hodor")
|
20
|
+
expect(described_class.registry).to eq "hodor"
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
describe "::register" do
|
25
|
+
it "adds given class to key in registry" do
|
26
|
+
MyClass = Struct.new(:myclass)
|
27
|
+
described_class.register MyClass, :my_class
|
28
|
+
|
29
|
+
expect(described_class.registry[:my_class]).to eq MyClass
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|