discord-notifier 0.1.0 → 1.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: e41269eca4f21db07c035912dad45faad3c539e1
4
- data.tar.gz: a21a0062df3506c83a23f5e5e896903bce6af3a1
3
+ metadata.gz: 7b3fbe0ad1ca1e827db62d6a6f607b072980026d
4
+ data.tar.gz: 055e7d9f3efe5851775a2daece7100a90ade56a5
5
5
  SHA512:
6
- metadata.gz: 65b4a8566e174b2bf25a246a58c07c31f3590dea6cc88c5f60c34343286a6cc722abb429d519b3df30f95880b164b5887435fd2d6275bea33b5e9036d7c4eff7
7
- data.tar.gz: e712272a5e281853adea41d595a255935759978daa3d9b2ff03d15dd7643bc5bd01828ca964710b25106fed7e49295009014c17c2a0da735a32b53a0ddc2d684
6
+ metadata.gz: dabdedca9c9e8969da6ee244e2f3b27fc47e156d201c9a5350cb380090edc3cc781c01e656cfa169dbf08982c8f469227a7131f7d13b15ec1c80426ada4000f7
7
+ data.tar.gz: b67f80ecb556bf27d1a28c8ea84cc407a65a5bb438f11adeead927d15758e792b12e7d8b10baedc1b1ef150c33ca382362f744a84589a27f646676d7c5bf1dc3
@@ -1,11 +1,17 @@
1
1
  require 'json'
2
2
  require 'net/http'
3
+ require 'net/https'
3
4
  require_relative 'discord_notifier/embed'
5
+ require_relative 'discord_notifier/form_data'
6
+ require_relative 'discord_notifier/backports/hash'
7
+ require_relative 'discord_notifier/backports/http'
4
8
 
5
9
  module Discord
10
+ using Backports
11
+
6
12
  Config = Struct.new(:url, :username, :avatar_url, :wait)
7
13
 
8
- class Notifier
14
+ module Notifier
9
15
  @@config = Config.new
10
16
 
11
17
  def self.setup
@@ -13,22 +19,48 @@ module Discord
13
19
  end
14
20
 
15
21
  def self.message(content, config = {})
16
- params = @@config.to_h.merge(config).compact
22
+ params = payload(content, config)
23
+
24
+ if params[:file]
25
+ send_form(params)
26
+ else
27
+ send_request(params)
28
+ end
29
+ end
30
+
31
+ def self.payload(content, config)
32
+ payload = @@config.to_h.merge(config)
17
33
 
18
34
  case content
19
35
  when String
20
- params[:content] = content
36
+ payload[:content] = content
21
37
  when Embed
22
- params[:embeds] = [content.data]
38
+ payload[:embeds] = [content.data]
23
39
  when Array
24
- params[:embeds] = content.map { |embed| embed.data }
25
- # when Attachment
40
+ payload[:embeds] = content.map { |embed| embed.data }
41
+ when File
42
+ payload[:file] = content
26
43
  else
27
44
  raise ArgumentError, 'Unsupported content type'
28
45
  end
29
46
 
47
+ payload.compact
48
+ end
49
+
50
+ def self.send_request(params)
51
+ Net::HTTP.post endpoint(params),
52
+ params.to_json,
53
+ 'Content-Type': 'application/json'
54
+ end
55
+
56
+ def self.send_form(params)
30
57
  uri = endpoint(params)
31
- Net::HTTP.post(uri, params.to_json, "Content-Type": "application/json")
58
+
59
+ req = Discord.form_data_request(uri, params)
60
+
61
+ http = Net::HTTP.new(uri.host, uri.port)
62
+ http.use_ssl = true
63
+ http.request(req)
32
64
  end
33
65
 
34
66
  def self.endpoint(config)
@@ -0,0 +1,11 @@
1
+ module Discord
2
+ module Backports
3
+ unless Hash.instance_methods(false).include?(:compact)
4
+ refine Hash do
5
+ def compact
6
+ select { |_, value| !value.nil? }
7
+ end
8
+ end
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,16 @@
1
+ require 'net/http'
2
+
3
+ module Discord
4
+ module Backports
5
+ unless Net::HTTP.methods.include?(:post)
6
+ refine Net::HTTP.singleton_class do
7
+ def post(url, data, header = nil)
8
+ start(url.hostname, url.port,
9
+ :use_ssl => url.scheme == 'https' ) {|http|
10
+ http.post(url.path, data, header)
11
+ }
12
+ end
13
+ end
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,35 @@
1
+ require 'net/http'
2
+
3
+ module Discord
4
+ BOUNDARY = "DiscordNotifier"
5
+
6
+ def self.form_data_request(uri, params)
7
+ req = Net::HTTP::Post.new(uri)
8
+ req.add_field "Content-Type", "multipart/form-data; boundary=#{BOUNDARY}"
9
+ req.body = Discord.multipart_form_data(params)
10
+ return req
11
+ end
12
+
13
+ def self.multipart_form_data(config)
14
+ file = config[:file]
15
+ filename = File.basename(file.path)
16
+ file_contents = File.read(file)
17
+ payload = config.select {|k, v| k != :file}
18
+
19
+ form = <<~eos
20
+ --#{BOUNDARY}
21
+ Content-Disposition: form-data; name="file"; filename="#{filename}"
22
+
23
+ #{file_contents}
24
+
25
+ --#{BOUNDARY}
26
+ Content-Disposition: form-data; name="payload_json"
27
+
28
+ #{payload.to_json}
29
+
30
+ --#{BOUNDARY}--
31
+ eos
32
+
33
+ form.encode crlf_newline: true
34
+ end
35
+ end
@@ -1,5 +1,5 @@
1
1
  module Discord
2
- class Notifier
3
- VERSION = '0.1.0'.freeze
2
+ module Notifier
3
+ VERSION = '1.0.0'.freeze
4
4
  end
5
5
  end
@@ -1,4 +1,5 @@
1
1
  require 'test_helper'
2
+ require 'date'
2
3
 
3
4
  class Discord::EmbedTest < Minitest::Test
4
5
  def test_that_it_has_a_data_hash
@@ -0,0 +1,37 @@
1
+ require 'test_helper'
2
+
3
+ class Discord::FormDataTest < Minitest::Test
4
+ def expected_form_body
5
+ Dir.chdir(File.dirname(__FILE__))
6
+ File.read('../../form_body.txt')
7
+ end
8
+
9
+ def test_that_boundary_is_defined
10
+ refute_nil Discord::BOUNDARY
11
+ end
12
+
13
+ def test_form_data_request_has_correct_header
14
+ params = {
15
+ url: 'http://test.com',
16
+ username: 'Gem Test',
17
+ avatar_url: 'http://avatar.com/discord.png',
18
+ file: test_attachment
19
+ }
20
+
21
+ request = Discord.form_data_request(URI('http://test.com'), params)
22
+ assert_equal 'multipart/form-data', request.content_type
23
+ end
24
+
25
+ def test_multipart_form_data_has_correct_format
26
+ expected_body = expected_form_body
27
+ params = {
28
+ url: 'http://test.com',
29
+ username: 'Gem Test',
30
+ avatar_url: 'http://avatar.com/discord.png',
31
+ file: test_attachment
32
+ }
33
+
34
+ body = Discord.multipart_form_data(params)
35
+ assert_equal expected_body, body
36
+ end
37
+ end
@@ -3,6 +3,14 @@ require 'net/http'
3
3
  require 'json'
4
4
 
5
5
  class Discord::NotifierTest < Minitest::Test
6
+ def setup
7
+ Discord::Notifier.setup do |config|
8
+ config.url = 'http://test.com'
9
+ config.username = 'Gem Test'
10
+ config.avatar_url = 'http://avatar.com/discord.png'
11
+ end
12
+ end
13
+
6
14
  def teardown
7
15
  Discord::Notifier.setup do |config|
8
16
  config.url = nil
@@ -13,12 +21,6 @@ class Discord::NotifierTest < Minitest::Test
13
21
  end
14
22
 
15
23
  def test_configuration
16
- Discord::Notifier.setup do |config|
17
- config.url = 'http://test.com'
18
- config.username = 'Gem Test'
19
- config.avatar_url = 'http://avatar.com/discord.png'
20
- end
21
-
22
24
  expected_config = Discord::Config.new 'http://test.com',
23
25
  'Gem Test',
24
26
  'http://avatar.com/discord.png',
@@ -29,34 +31,44 @@ class Discord::NotifierTest < Minitest::Test
29
31
  end
30
32
  end
31
33
 
32
- def test_string_message
33
- expected_payload = {
34
- url: 'http://test.com',
35
- username: 'Gem Test',
36
- avatar_url: 'http://avatar.com/discord.png',
37
- content: 'String Message'
38
- }.to_json
34
+ def test_has_message
35
+ assert Discord::Notifier.methods.include? :message
36
+ end
39
37
 
40
- @mock = Minitest::Mock.new
41
- @mock.expect(:post, true, [JSON.parse(expected_payload)])
38
+ def test_message_responds_to_correct_format
39
+ form_params = nil
40
+ request_params = nil
41
+ file = test_attachment
42
42
 
43
- Discord::Notifier.setup do |config|
44
- config.url = 'http://test.com'
45
- config.username = 'Gem Test'
46
- config.avatar_url = 'http://avatar.com/discord.png'
43
+ Discord::Notifier.stub :send_form, ->(args) { form_params = args } do
44
+ Discord::Notifier.message file
47
45
  end
48
46
 
49
- Net::HTTP.stub :post, ->(uri, params, headers) {
50
- @mock.post JSON.parse(params)
51
- } do
47
+ assert form_params
48
+
49
+ Discord::Notifier.stub :send_request, ->(args) { request_params = args } do
52
50
  Discord::Notifier.message "String Message"
53
51
  end
54
52
 
55
- @mock.verify
53
+ assert request_params
54
+ end
55
+
56
+ def test_string_message
57
+ actual_params = nil
58
+ expected_params = {
59
+ url: 'http://test.com',
60
+ username: 'Gem Test',
61
+ avatar_url: 'http://avatar.com/discord.png',
62
+ content: 'String Message'
63
+ }
64
+
65
+ actual_params = Discord::Notifier.payload "String Message", {}
66
+ assert_equal expected_params, actual_params
56
67
  end
57
68
 
58
69
  def test_embed_message
59
- expected_payload = {
70
+ actual_params = nil
71
+ expected_params = {
60
72
  url: 'http://test.com',
61
73
  username: 'Gem Test',
62
74
  avatar_url: 'http://avatar.com/discord.png',
@@ -86,72 +98,44 @@ class Discord::NotifierTest < Minitest::Test
86
98
  }
87
99
  ]
88
100
  }]
89
- }.to_json
90
-
91
- @mock = Minitest::Mock.new
92
- @mock.expect(:post, true, [JSON.parse(expected_payload)])
93
-
94
- Discord::Notifier.setup do |config|
95
- config.url = 'http://test.com'
96
- config.username = 'Gem Test'
97
- config.avatar_url = 'http://avatar.com/discord.png'
98
- end
101
+ }
99
102
 
100
- Net::HTTP.stub :post, ->(uri, params, headers) {
101
- @mock.post JSON.parse(params)
102
- } do
103
- embed = Discord::Embed.new do
104
- title 'Embed Message Test'
105
- description 'Sending an embed through Discord Notifier'
106
- url 'http://github.com/ianmitchell/discord_notifier'
107
- color 0x008000
108
- thumbnail url: 'http://avatar.com/discord.png'
109
- author name: 'Ian Mitchell',
110
- url: 'http://ianmitchell.io'
111
- footer text: 'Mini MiniTest Test'
112
- add_field name: 'Content', value: 'This is a content section'
113
- add_field name: 'Subsection', value: 'This is a content subsection'
114
- end
115
-
116
- Discord::Notifier.message embed
103
+ embed = Discord::Embed.new do
104
+ title 'Embed Message Test'
105
+ description 'Sending an embed through Discord Notifier'
106
+ url 'http://github.com/ianmitchell/discord_notifier'
107
+ color 0x008000
108
+ thumbnail url: 'http://avatar.com/discord.png'
109
+ author name: 'Ian Mitchell',
110
+ url: 'http://ianmitchell.io'
111
+ footer text: 'Mini MiniTest Test'
112
+ add_field name: 'Content', value: 'This is a content section'
113
+ add_field name: 'Subsection', value: 'This is a content subsection'
117
114
  end
118
115
 
119
- @mock.verify
116
+ actual_params = Discord::Notifier.payload embed, {}
117
+ assert_equal expected_params, actual_params
120
118
  end
121
119
 
122
120
  def test_custom_config_message
123
- @custom_config = {
121
+ custom_config = {
124
122
  url: 'http://custom.com',
125
123
  username: 'Gem Config Test',
126
124
  avatar_url: 'http://avatar.com/slack.png',
127
125
  wait: true
128
126
  }
129
-
130
- expected_payload = {
127
+ actual_params = nil
128
+ expected_params = {
131
129
  content: 'String Message'
132
- }.merge(@custom_config).to_json
133
-
134
- @mock = Minitest::Mock.new
135
- @mock.expect(:post, true, [JSON.parse(expected_payload)])
136
-
137
- Discord::Notifier.setup do |config|
138
- config.url = 'http://test.com'
139
- config.username = 'Gem Test'
140
- config.avatar_url = 'http://avatar.com/discord.png'
141
- config.wait = true
142
- end
143
-
144
- Net::HTTP.stub :post, ->(uri, params, headers) {
145
- @mock.post JSON.parse(params)
146
- } do
147
- Discord::Notifier.message "String Message", @custom_config
148
- end
130
+ }.merge(custom_config)
149
131
 
150
- @mock.verify
132
+ actual_params = Discord::Notifier.payload "String Message", custom_config
133
+ assert_equal expected_params, actual_params
151
134
  end
152
135
 
153
136
  def test_multiple_embeds
154
- expected_payload = {
137
+ actual_params = nil
138
+ expected_params = {
155
139
  url: 'http://test.com',
156
140
  username: 'Gem Test',
157
141
  avatar_url: 'http://avatar.com/discord.png',
@@ -167,36 +151,36 @@ class Discord::NotifierTest < Minitest::Test
167
151
  url: 'http://github.com/ianmitchell/discord_notifier',
168
152
  }
169
153
  ]
170
- }.to_json
171
-
172
- @mock = Minitest::Mock.new
173
- @mock.expect(:post, true, [JSON.parse(expected_payload)])
154
+ }
174
155
 
175
- Discord::Notifier.setup do |config|
176
- config.url = 'http://test.com'
177
- config.username = 'Gem Test'
178
- config.avatar_url = 'http://avatar.com/discord.png'
156
+ embed_one = Discord::Embed.new do
157
+ title 'Embed Message Test'
158
+ description 'Sending an embed through Discord Notifier'
159
+ url 'http://github.com/ianmitchell/discord_notifier'
179
160
  end
180
161
 
181
- Net::HTTP.stub :post, ->(uri, params, headers) {
182
- @mock.post JSON.parse(params)
183
- } do
184
- embed_one = Discord::Embed.new do
185
- title 'Embed Message Test'
186
- description 'Sending an embed through Discord Notifier'
187
- url 'http://github.com/ianmitchell/discord_notifier'
188
- end
189
-
190
- embed_two = Discord::Embed.new do
191
- title 'Second Embed Message Test'
192
- description 'Sending an embed through Discord Notifier'
193
- url 'http://github.com/ianmitchell/discord_notifier'
194
- end
195
-
196
- Discord::Notifier.message [embed_one, embed_two]
162
+ embed_two = Discord::Embed.new do
163
+ title 'Second Embed Message Test'
164
+ description 'Sending an embed through Discord Notifier'
165
+ url 'http://github.com/ianmitchell/discord_notifier'
197
166
  end
198
167
 
199
- @mock.verify
168
+ actual_params = Discord::Notifier.payload [embed_one, embed_two], {}
169
+ assert_equal expected_params, actual_params
170
+ end
171
+
172
+ def test_file_attachment
173
+ file = test_attachment
174
+ actual_params = nil
175
+ expected_params = {
176
+ url: 'http://test.com',
177
+ username: 'Gem Test',
178
+ avatar_url: 'http://avatar.com/discord.png',
179
+ file: file
180
+ }
181
+
182
+ actual_params = Discord::Notifier.payload file, {}
183
+ assert_equal expected_params, actual_params
200
184
  end
201
185
 
202
186
  def test_incorrect_message_type
@@ -206,10 +190,10 @@ class Discord::NotifierTest < Minitest::Test
206
190
  end
207
191
 
208
192
  def test_endpoint
209
- endpoint = Discord::Notifier.endpoint(url: 'http://test.com')
193
+ endpoint = Discord::Notifier.endpoint url: 'http://test.com'
210
194
  assert endpoint.eql? URI('http://test.com')
211
195
 
212
- endpoint = Discord::Notifier.endpoint(url: 'http://test.com', wait: true)
196
+ endpoint = Discord::Notifier.endpoint url: 'http://test.com', wait: true
213
197
  assert endpoint.eql? URI('http://test.com?wait=true')
214
198
  end
215
199
  end
@@ -1,5 +1,26 @@
1
+ require 'net/http'
2
+
3
+ # Since refinements don't work with `respond_to` which
4
+ # Minitest uses when it stubs methods, we need to monkey
5
+ # patch Net::HTTP here for our tests.
6
+ unless Net::HTTP.methods.include?(:post)
7
+ class Net::HTTP
8
+ def self.post(url, data, header = nil)
9
+ start(url.hostname, url.port,
10
+ :use_ssl => url.scheme == 'https' ) {|http|
11
+ http.post(url.path, data, header)
12
+ }
13
+ end
14
+ end
15
+ end
16
+
1
17
  $LOAD_PATH.unshift File.expand_path('../../lib', __FILE__)
2
18
  require 'discord_notifier'
3
19
  require 'discord_notifier/version'
4
20
 
5
21
  require 'minitest/autorun'
22
+
23
+ def test_attachment
24
+ Dir.chdir(File.dirname(__FILE__))
25
+ File.open('test_attachment.txt')
26
+ end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: discord-notifier
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 1.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ian Mitchell
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2017-07-11 00:00:00.000000000 Z
11
+ date: 2017-07-19 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -60,9 +60,13 @@ extensions: []
60
60
  extra_rdoc_files: []
61
61
  files:
62
62
  - lib/discord_notifier.rb
63
+ - lib/discord_notifier/backports/hash.rb
64
+ - lib/discord_notifier/backports/http.rb
63
65
  - lib/discord_notifier/embed.rb
66
+ - lib/discord_notifier/form_data.rb
64
67
  - lib/discord_notifier/version.rb
65
68
  - test/discord/discord_notifier/embed_test.rb
69
+ - test/discord/discord_notifier/form_data_test.rb
66
70
  - test/discord/discord_notifier/version_test.rb
67
71
  - test/discord/discord_notifier_test.rb
68
72
  - test/test_helper.rb
@@ -78,7 +82,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
78
82
  requirements:
79
83
  - - ">="
80
84
  - !ruby/object:Gem::Version
81
- version: '0'
85
+ version: 2.3.0
82
86
  required_rubygems_version: !ruby/object:Gem::Requirement
83
87
  requirements:
84
88
  - - ">="
@@ -92,6 +96,7 @@ specification_version: 4
92
96
  summary: A minimal wrapper for posting Discord Webhooks and Embeds
93
97
  test_files:
94
98
  - test/discord/discord_notifier/embed_test.rb
99
+ - test/discord/discord_notifier/form_data_test.rb
95
100
  - test/discord/discord_notifier/version_test.rb
96
101
  - test/discord/discord_notifier_test.rb
97
102
  - test/test_helper.rb