slack-messenger 2.3.3

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.
Files changed (29) hide show
  1. checksums.yaml +7 -0
  2. data/lib/slack-messenger.rb +59 -0
  3. data/lib/slack-messenger/config.rb +43 -0
  4. data/lib/slack-messenger/payload_middleware.rb +24 -0
  5. data/lib/slack-messenger/payload_middleware/at.rb +36 -0
  6. data/lib/slack-messenger/payload_middleware/base.rb +34 -0
  7. data/lib/slack-messenger/payload_middleware/channels.rb +21 -0
  8. data/lib/slack-messenger/payload_middleware/format_attachments.rb +44 -0
  9. data/lib/slack-messenger/payload_middleware/format_message.rb +20 -0
  10. data/lib/slack-messenger/payload_middleware/stack.rb +50 -0
  11. data/lib/slack-messenger/util/escape.rb +16 -0
  12. data/lib/slack-messenger/util/http_client.rb +64 -0
  13. data/lib/slack-messenger/util/link_formatter.rb +81 -0
  14. data/lib/slack-messenger/version.rb +7 -0
  15. data/spec/end_to_end_spec.rb +95 -0
  16. data/spec/integration/ping_integration_test.rb +16 -0
  17. data/spec/lib/slack-messenger/config_spec.rb +71 -0
  18. data/spec/lib/slack-messenger/payload_middleware/at_spec.rb +25 -0
  19. data/spec/lib/slack-messenger/payload_middleware/base_spec.rb +76 -0
  20. data/spec/lib/slack-messenger/payload_middleware/channels_spec.rb +20 -0
  21. data/spec/lib/slack-messenger/payload_middleware/format_attachments_spec.rb +48 -0
  22. data/spec/lib/slack-messenger/payload_middleware/format_message_spec.rb +27 -0
  23. data/spec/lib/slack-messenger/payload_middleware/stack_spec.rb +119 -0
  24. data/spec/lib/slack-messenger/payload_middleware_spec.rb +33 -0
  25. data/spec/lib/slack-messenger/util/http_client_spec.rb +55 -0
  26. data/spec/lib/slack-messenger/util/link_formatter_spec.rb +155 -0
  27. data/spec/lib/slack-messenger_spec.rb +98 -0
  28. data/spec/spec_helper.rb +28 -0
  29. metadata +84 -0
@@ -0,0 +1,33 @@
1
+ # frozen_string_literal: true
2
+
3
+ RSpec.describe Slack::Messenger::PayloadMiddleware do
4
+ before(:each) do
5
+ @registry_backup = described_class.registry.dup
6
+ Slack::Messenger::PayloadMiddleware.send(:remove_instance_variable, :@registry)
7
+ end
8
+
9
+ after(:each) do
10
+ described_class.send(:remove_instance_variable, :@registry)
11
+ described_class.send(:instance_variable_set, :@registry, @registry_backup)
12
+ end
13
+
14
+ describe "::registry" do
15
+ it "returns a hash if nothing set" do
16
+ expect(described_class.registry).to eq({})
17
+ end
18
+
19
+ it "returns memoized version if already set" do
20
+ described_class.instance_variable_set(:@registry, "hodor")
21
+ expect(described_class.registry).to eq "hodor"
22
+ end
23
+ end
24
+
25
+ describe "::register" do
26
+ it "adds given class to key in registry" do
27
+ MyClass = Struct.new(:myclass)
28
+ described_class.register MyClass, :my_class
29
+
30
+ expect(described_class.registry[:my_class]).to eq MyClass
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,55 @@
1
+ # frozen_string_literal: true
2
+
3
+ RSpec.describe Slack::Messenger::Util::HTTPClient do
4
+ describe "::post" do
5
+ it "initializes Util::HTTPClient with the given uri and params then calls" do
6
+ http_post_double = instance_double("Slack::Messenger::Util::HTTPClient")
7
+
8
+ expect(described_class)
9
+ .to receive(:new).with("uri", "params")
10
+ .and_return(http_post_double)
11
+ expect(http_post_double).to receive(:call)
12
+
13
+ described_class.post "uri", "params"
14
+ end
15
+
16
+ # http_post is really tested in the integration spec,
17
+ # where the internals are run through
18
+ end
19
+
20
+ describe "#initialize" do
21
+ it "allows setting of options for Net::HTTP" do
22
+ net_http_double = instance_double("Net::HTTP")
23
+ http_client = described_class.new URI.parse("http://example.com"),
24
+ http_options: { open_timeout: 5 }
25
+
26
+ allow(Net::HTTP).to receive(:new).and_return(net_http_double)
27
+ allow(net_http_double).to receive(:use_ssl=)
28
+ allow(net_http_double).to receive(:request).with(anything) do
29
+ Net::HTTPOK.new("GET", "200", "OK")
30
+ end
31
+
32
+ expect(net_http_double).to receive(:open_timeout=).with(5)
33
+
34
+ http_client.call
35
+ end
36
+ end
37
+
38
+ describe "#call" do
39
+ it "raises an error when the response is unsuccessful" do
40
+ net_http_double = instance_double("Net::HTTP")
41
+ http_client = described_class.new URI.parse("http://example.com"), {}
42
+ bad_request = Net::HTTPBadRequest.new("GET", "400", "Bad Request")
43
+
44
+ allow(bad_request).to receive(:body).and_return("something_bad")
45
+ allow(Net::HTTP).to receive(:new).and_return(net_http_double)
46
+ allow(net_http_double).to receive(:use_ssl=)
47
+ allow(net_http_double).to receive(:request).with(anything) do
48
+ bad_request
49
+ end
50
+
51
+ expect { http_client.call }.to raise_error(Slack::Messenger::APIError,
52
+ /something_bad \(HTTP Code 400\)/)
53
+ end
54
+ end
55
+ end
@@ -0,0 +1,155 @@
1
+ # frozen_string_literal: true
2
+ # encoding: utf-8
3
+
4
+ # rubocop:disable Metrics/LineLength
5
+ RSpec.describe Slack::Messenger::Util::LinkFormatter do
6
+ describe "::format" do
7
+ it "formats html links" do
8
+ formatted = described_class.format("Hello World, enjoy <a href='http://example.com'>this</a>.")
9
+ expect(formatted).to include("<http://example.com|this>")
10
+ end
11
+
12
+ it "formats markdown links" do
13
+ formatted = described_class.format("Hello World, enjoy [this](http://example.com).")
14
+ expect(formatted).to include("<http://example.com|this>")
15
+ end
16
+
17
+ it "formats markdown links in brackets" do
18
+ formatted = described_class.format("Hello World, enjoy [[this](http://example.com) in brackets].")
19
+ expect(formatted).to eq("Hello World, enjoy [<http://example.com|this> in brackets].")
20
+ end
21
+
22
+ it "formats markdown links with no title" do
23
+ formatted = described_class.format("Hello World, enjoy [](http://example.com).")
24
+ expect(formatted).to include("<http://example.com>")
25
+ end
26
+
27
+ it "handles multiple html links" do
28
+ formatted = described_class.format("Hello World, enjoy <a href='http://example.com'>this</a><a href='http://example2.com'>this2</a>.")
29
+ expect(formatted).to include("<http://example.com|this>")
30
+ expect(formatted).to include("<http://example2.com|this2>")
31
+ end
32
+
33
+ it "handles multiple markdown links" do
34
+ formatted = described_class.format("Hello World, enjoy [this](http://example.com)[this2](http://example2.com).")
35
+ expect(formatted).to include("<http://example.com|this>")
36
+ expect(formatted).to include("<http://example2.com|this2>")
37
+ end
38
+
39
+ it "handles mixed html & markdown links" do
40
+ formatted = described_class.format("Hello World, enjoy [this](http://example.com)<a href='http://example2.com'>this2</a>.")
41
+ expect(formatted).to include("<http://example.com|this>")
42
+ expect(formatted).to include("<http://example2.com|this2>")
43
+ end
44
+
45
+ if "".respond_to? :scrub
46
+ context "when on ruby 2.1+ or have string-scrub installed" do
47
+ it "handles invalid unicode sequences" do
48
+ expect do
49
+ described_class.format("This sequence is invalid: \255")
50
+ end.not_to raise_error
51
+ end
52
+
53
+ it "replaces invalid unicode sequences with the unicode replacement character" do
54
+ formatted = described_class.format("\255")
55
+ expect(formatted).to eq "\uFFFD"
56
+ end
57
+ end
58
+ end
59
+
60
+ it "doesn't replace valid Japanese" do
61
+ formatted = described_class.format("こんにちは")
62
+ expect(formatted).to eq "こんにちは"
63
+ end
64
+
65
+ it "handles mailto links in markdown" do
66
+ formatted = described_class.format("[John](mailto:john@example.com)")
67
+ expect(formatted).to eq "<mailto:john@example.com|John>"
68
+ end
69
+
70
+ it "handles mailto links in html" do
71
+ formatted = described_class.format("<a href='mailto:john@example.com'>John</a>")
72
+ expect(formatted).to eq "<mailto:john@example.com|John>"
73
+ end
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 ([this](http://example.com))." =>
93
+ "Hello World, enjoy (<http://example.com|this>).",
94
+
95
+ "Hello World, enjoy [](http://example.com)." =>
96
+ "Hello World, enjoy <http://example.com>.",
97
+
98
+ "Hello World, enjoy [link with query](http://example.com?foo=bar)." =>
99
+ "Hello World, enjoy <http://example.com?foo=bar|link with query>.",
100
+
101
+ "Hello World, enjoy [link with fragment](http://example.com/#foo-bar)." =>
102
+ "Hello World, enjoy <http://example.com/#foo-bar|link with fragment>.",
103
+
104
+ "Hello World, enjoy [link with parens](http://example.com/foo(bar)/baz)." =>
105
+ "Hello World, enjoy <http://example.com/foo(bar)/baz|link with parens>.",
106
+
107
+ "Hello World, enjoy [link with query](http://example.com/(parens)?foo=bar)." =>
108
+ "Hello World, enjoy <http://example.com/(parens)?foo=bar|link with query>.",
109
+
110
+ "Hello World, enjoy [link with parens](http://example.com/baz?bang=foo(bar))." =>
111
+ "Hello World, enjoy <http://example.com/baz?bang=foo(bar)|link with parens>.",
112
+
113
+ "Hello World, enjoy [link with fragment](http://example.com/(parens)#foo-bar)." =>
114
+ "Hello World, enjoy <http://example.com/(parens)#foo-bar|link with fragment>.",
115
+
116
+ "Hello World, enjoy [link with fragment](http://example.com/#foo-bar=(baz))." =>
117
+ "Hello World, enjoy <http://example.com/#foo-bar=(baz)|link with fragment>.",
118
+
119
+ "Hello World, enjoy [this](http://example.com?foo=bar)[this2](http://example2.com)." =>
120
+ "Hello World, enjoy <http://example.com?foo=bar|this><http://example2.com|this2>.",
121
+
122
+ "Hello World, enjoy [this](http://example.com?foo=bar) [this2](http://example2.com/#fragment)." =>
123
+ "Hello World, enjoy <http://example.com?foo=bar|this> <http://example2.com/#fragment|this2>.",
124
+
125
+ "Hello World, enjoy [this](http://example.com)<a href='http://example2.com'>this2</a>." =>
126
+ "Hello World, enjoy <http://example.com|this><http://example2.com|this2>.",
127
+
128
+ "Hello world, [John](mailto:john@example.com)." =>
129
+ "Hello world, <mailto:john@example.com|John>.",
130
+
131
+ "Hello World, enjoy [foo(bar)](http://example.com/foo(bar))<a href='http://example.com/bar(foo)'>bar(foo)</a>" =>
132
+ "Hello World, enjoy <http://example.com/foo(bar)|foo(bar)><http://example.com/bar(foo)|bar(foo)>"
133
+ }
134
+
135
+ input_output.each do |input, output|
136
+ expect(described_class.format(input)).to eq output
137
+ end
138
+ end
139
+
140
+ context "with a configured stack" do
141
+ it "only formats html if html is the only item in formats" do
142
+ formatted = described_class.format("Hello World, enjoy [this](http://example.com)<a href='http://example2.com'>this2</a>.", formats: [:html])
143
+ expect(formatted).to eq "Hello World, enjoy [this](http://example.com)<http://example2.com|this2>."
144
+ end
145
+ it "only formats markdown if markdown is the only item in formats" do
146
+ formatted = described_class.format("Hello World, enjoy [this](http://example.com)<a href='http://example2.com'>this2</a>.", formats: [:markdown])
147
+ expect(formatted).to eq "Hello World, enjoy <http://example.com|this><a href='http://example2.com'>this2</a>."
148
+ end
149
+ it "doesn't format if formats is empty" do
150
+ formatted = described_class.format("Hello World, enjoy [this](http://example.com)<a href='http://example2.com'>this2</a>.", formats: [])
151
+ expect(formatted).to eq "Hello World, enjoy [this](http://example.com)<a href='http://example2.com'>this2</a>."
152
+ end
153
+ end
154
+ end
155
+ end
@@ -0,0 +1,98 @@
1
+ # frozen_string_literal: true
2
+
3
+ RSpec.describe Slack::Messenger do
4
+ let(:mock_http) do
5
+ class_double("Slack::Messenger::Util::HTTPClient", post: :posted)
6
+ end
7
+
8
+ subject { described_class.new "http://example.com", http_client: mock_http }
9
+
10
+ describe "#initialize" do
11
+ it "sets the given hook_url to the endpoint URI" do
12
+ expect(subject.endpoint).to eq URI.parse("http://example.com")
13
+ end
14
+
15
+ it "sets the default_payload options" do
16
+ subject = described_class.new "http://example.com", channel: "foo"
17
+ expect(subject.config.defaults[:channel]).to eq "foo"
18
+ end
19
+
20
+ it "sets a custom http client" do
21
+ subject = described_class.new "http://example.com", http_client: mock_http
22
+ expect(subject.config.http_client).to eq mock_http
23
+ end
24
+
25
+ describe "when given a block" do
26
+ it "yields the config object" do
27
+ test_double = double("Slack::Messenger::Config", defaults: {}, middleware: [])
28
+ allow_any_instance_of(Slack::Messenger).to receive(:config).and_return(test_double)
29
+
30
+ expect(test_double).to receive(:test_init_method).with("foo")
31
+
32
+ described_class.new "http://example.com" do
33
+ test_init_method "foo"
34
+ end
35
+ end
36
+ end
37
+ end
38
+
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"
43
+
44
+ subject.ping "message"
45
+ end
46
+ end
47
+
48
+ describe "#post" do
49
+ def messenger_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
55
+ end
56
+ end
57
+
58
+ it "uses the defaults set on initialization" do
59
+ subject = messenger_with_defaults
60
+
61
+ expect(mock_http).to receive(:post).with(
62
+ URI.parse("http://example.com"),
63
+ payload: '{"channel":"default","user":"rocket","text":"hello"}'
64
+ )
65
+
66
+ subject.post text: "hello"
67
+ end
68
+
69
+ it "allows overriding the set defaults" do
70
+ subject = messenger_with_defaults
71
+
72
+ expect(mock_http).to receive(:post).with(
73
+ URI.parse("http://example.com"),
74
+ payload: '{"channel":"new","user":"ship","text":"hello"}'
75
+ )
76
+
77
+ subject.post text: "hello", channel: "new", user: "ship"
78
+ end
79
+
80
+ it "calls the middleware stack with the payload" do
81
+ subject = messenger_with_defaults
82
+ stack = instance_double("Slack::Messenger::PayloadMiddleware::Stack")
83
+ subject.instance_variable_set(:@middleware, stack)
84
+
85
+ expect(stack).to receive(:call)
86
+ .with(channel: "default", user: "rocket")
87
+ .and_return([test: "stack"])
88
+
89
+ expect(mock_http).to receive(:post).with(
90
+ URI.parse("http://example.com"),
91
+ payload: '{"test":"stack"}'
92
+ )
93
+
94
+ responses = subject.post
95
+ expect(responses).to eq([:posted])
96
+ end
97
+ end
98
+ end
@@ -0,0 +1,28 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "rspec"
4
+ require "slack-messenger"
5
+ require "pry" if ENV["DEBUG"]
6
+
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
+
12
+ config.mock_with :rspec do |mocks|
13
+ mocks.verify_doubled_constant_names = true
14
+ mocks.verify_partial_doubles = true
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
28
+ end
metadata ADDED
@@ -0,0 +1,84 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: slack-messenger
3
+ version: !ruby/object:Gem::Version
4
+ version: 2.3.3
5
+ platform: ruby
6
+ authors:
7
+ - Steven Sloan
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2020-02-09 00:00:00.000000000 Z
12
+ dependencies: []
13
+ description: " A slim ruby wrapper for posting to slack webhooks "
14
+ email:
15
+ - stevenosloan@gmail.com
16
+ executables: []
17
+ extensions: []
18
+ extra_rdoc_files: []
19
+ files:
20
+ - lib/slack-messenger.rb
21
+ - lib/slack-messenger/config.rb
22
+ - lib/slack-messenger/payload_middleware.rb
23
+ - lib/slack-messenger/payload_middleware/at.rb
24
+ - lib/slack-messenger/payload_middleware/base.rb
25
+ - lib/slack-messenger/payload_middleware/channels.rb
26
+ - lib/slack-messenger/payload_middleware/format_attachments.rb
27
+ - lib/slack-messenger/payload_middleware/format_message.rb
28
+ - lib/slack-messenger/payload_middleware/stack.rb
29
+ - lib/slack-messenger/util/escape.rb
30
+ - lib/slack-messenger/util/http_client.rb
31
+ - lib/slack-messenger/util/link_formatter.rb
32
+ - lib/slack-messenger/version.rb
33
+ - spec/end_to_end_spec.rb
34
+ - spec/integration/ping_integration_test.rb
35
+ - spec/lib/slack-messenger/config_spec.rb
36
+ - spec/lib/slack-messenger/payload_middleware/at_spec.rb
37
+ - spec/lib/slack-messenger/payload_middleware/base_spec.rb
38
+ - spec/lib/slack-messenger/payload_middleware/channels_spec.rb
39
+ - spec/lib/slack-messenger/payload_middleware/format_attachments_spec.rb
40
+ - spec/lib/slack-messenger/payload_middleware/format_message_spec.rb
41
+ - spec/lib/slack-messenger/payload_middleware/stack_spec.rb
42
+ - spec/lib/slack-messenger/payload_middleware_spec.rb
43
+ - spec/lib/slack-messenger/util/http_client_spec.rb
44
+ - spec/lib/slack-messenger/util/link_formatter_spec.rb
45
+ - spec/lib/slack-messenger_spec.rb
46
+ - spec/spec_helper.rb
47
+ homepage: http://github.com/stevenosloan/slack-messenger
48
+ licenses:
49
+ - MIT
50
+ metadata: {}
51
+ post_install_message:
52
+ rdoc_options: []
53
+ require_paths:
54
+ - lib
55
+ required_ruby_version: !ruby/object:Gem::Requirement
56
+ requirements:
57
+ - - ">="
58
+ - !ruby/object:Gem::Version
59
+ version: '0'
60
+ required_rubygems_version: !ruby/object:Gem::Requirement
61
+ requirements:
62
+ - - ">="
63
+ - !ruby/object:Gem::Version
64
+ version: '0'
65
+ requirements: []
66
+ rubygems_version: 3.0.3
67
+ signing_key:
68
+ specification_version: 4
69
+ summary: A slim ruby wrapper for posting to slack webhooks
70
+ test_files:
71
+ - spec/spec_helper.rb
72
+ - spec/integration/ping_integration_test.rb
73
+ - spec/lib/slack-messenger_spec.rb
74
+ - spec/lib/slack-messenger/config_spec.rb
75
+ - spec/lib/slack-messenger/util/http_client_spec.rb
76
+ - spec/lib/slack-messenger/util/link_formatter_spec.rb
77
+ - spec/lib/slack-messenger/payload_middleware/at_spec.rb
78
+ - spec/lib/slack-messenger/payload_middleware/format_attachments_spec.rb
79
+ - spec/lib/slack-messenger/payload_middleware/channels_spec.rb
80
+ - spec/lib/slack-messenger/payload_middleware/stack_spec.rb
81
+ - spec/lib/slack-messenger/payload_middleware/format_message_spec.rb
82
+ - spec/lib/slack-messenger/payload_middleware/base_spec.rb
83
+ - spec/lib/slack-messenger/payload_middleware_spec.rb
84
+ - spec/end_to_end_spec.rb