mailgun-tracking 2.0.0 → 3.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.
Files changed (36) hide show
  1. checksums.yaml +4 -4
  2. data/lib/generators/mailgun/tracking/templates/mailgun_tracking.rb.erb +1 -1
  3. data/lib/mailgun-tracking.rb +3 -0
  4. data/lib/mailgun/tracking.rb +65 -33
  5. data/lib/mailgun/tracking/auth.rb +52 -0
  6. data/lib/mailgun/tracking/configuration.rb +5 -9
  7. data/lib/mailgun/tracking/fanout.rb +18 -0
  8. data/lib/mailgun/tracking/middleware.rb +10 -47
  9. data/lib/mailgun/tracking/railtie.rb +2 -2
  10. data/lib/mailgun/tracking/version.rb +8 -7
  11. data/spec/dummy/logs/test.log +77 -0
  12. data/spec/dummy/rails/logs/test.log +19 -11
  13. data/spec/mailgun/tracking/auth_spec.rb +31 -0
  14. data/spec/mailgun/tracking/middleware_spec.rb +43 -51
  15. data/spec/mailgun/tracking_spec.rb +11 -4
  16. data/spec/support/shared_examples/integration/acts_as_rack.rb +6 -4
  17. metadata +18 -53
  18. data/lib/mailgun/tracking/exceptions.rb +0 -11
  19. data/lib/mailgun/tracking/listener.rb +0 -55
  20. data/lib/mailgun/tracking/notifier.rb +0 -61
  21. data/lib/mailgun/tracking/payload.rb +0 -96
  22. data/lib/mailgun/tracking/request.rb +0 -47
  23. data/lib/mailgun/tracking/signature.rb +0 -48
  24. data/lib/mailgun/tracking/subscriber.rb +0 -26
  25. data/lib/mailgun/tracking/subscriber/all_messages.rb +0 -37
  26. data/lib/mailgun/tracking/subscriber/evented.rb +0 -40
  27. data/lib/mailgun/tracking/util.rb +0 -67
  28. data/spec/mailgun/tracking/listener_spec.rb +0 -48
  29. data/spec/mailgun/tracking/notifier_spec.rb +0 -66
  30. data/spec/mailgun/tracking/payload_spec.rb +0 -73
  31. data/spec/mailgun/tracking/request_spec.rb +0 -63
  32. data/spec/mailgun/tracking/signature_spec.rb +0 -65
  33. data/spec/mailgun/tracking/subscriber/all_messages_spec.rb +0 -13
  34. data/spec/mailgun/tracking/subscriber/evented_spec.rb +0 -14
  35. data/spec/mailgun/tracking/subscriber_spec.rb +0 -15
  36. data/spec/mailgun/tracking/util_spec.rb +0 -155
@@ -1,11 +1,19 @@
1
- # Logfile created on 2019-11-18 19:44:22 +0200 by logger.rb/66358
2
- I, [2019-11-18T19:44:22.794652 #78850] INFO -- : Started POST "/mailgun" for 127.0.0.1 at 2019-11-18 19:44:22 +0200
3
- I, [2019-11-18T19:44:22.822729 #78850] INFO -- : Started POST "/mailgun" for 127.0.0.1 at 2019-11-18 19:44:22 +0200
4
- I, [2019-11-18T19:45:24.283699 #78864] INFO -- : Started POST "/mailgun" for 127.0.0.1 at 2019-11-18 19:45:24 +0200
5
- I, [2019-11-18T19:45:24.287326 #78864] INFO -- : Started POST "/mailgun" for 127.0.0.1 at 2019-11-18 19:45:24 +0200
6
- I, [2019-11-18T19:45:51.702415 #78878] INFO -- : Started POST "/mailgun" for 127.0.0.1 at 2019-11-18 19:45:51 +0200
7
- I, [2019-11-18T19:45:51.710237 #78878] INFO -- : Started POST "/mailgun" for 127.0.0.1 at 2019-11-18 19:45:51 +0200
8
- I, [2019-11-18T19:46:04.908573 #78887] INFO -- : Started POST "/mailgun" for 127.0.0.1 at 2019-11-18 19:46:04 +0200
9
- I, [2019-11-18T19:46:04.912208 #78887] INFO -- : Started POST "/mailgun" for 127.0.0.1 at 2019-11-18 19:46:04 +0200
10
- I, [2019-11-18T19:58:57.597641 #78976] INFO -- : Started POST "/mailgun" for 127.0.0.1 at 2019-11-18 19:58:57 +0200
11
- I, [2019-11-18T19:58:57.608212 #78976] INFO -- : Started POST "/mailgun" for 127.0.0.1 at 2019-11-18 19:58:57 +0200
1
+ # Logfile created on 2019-12-20 18:03:14 +0200 by logger.rb/66358
2
+ I, [2019-12-20T18:03:15.184026 #36064] INFO -- : Started POST "/mailgun" for 127.0.0.1 at 2019-12-20 18:03:15 +0200
3
+ I, [2019-12-20T18:03:15.189876 #36064] INFO -- : Started POST "/mailgun" for 127.0.0.1 at 2019-12-20 18:03:15 +0200
4
+ I, [2019-12-20T18:03:41.598392 #36073] INFO -- : Started POST "/mailgun" for 127.0.0.1 at 2019-12-20 18:03:41 +0200
5
+ I, [2019-12-20T18:03:41.601914 #36073] INFO -- : Started POST "/mailgun" for 127.0.0.1 at 2019-12-20 18:03:41 +0200
6
+ I, [2019-12-20T18:07:46.230295 #36150] INFO -- : Started POST "/mailgun" for 127.0.0.1 at 2019-12-20 18:07:46 +0200
7
+ I, [2019-12-20T18:07:46.235394 #36150] INFO -- : Started POST "/mailgun" for 127.0.0.1 at 2019-12-20 18:07:46 +0200
8
+ I, [2020-01-21T11:50:39.988463 #10847] INFO -- : Started POST "/mailgun" for 127.0.0.1 at 2020-01-21 11:50:39 +0200
9
+ F, [2020-01-21T11:50:39.990083 #10847] FATAL -- :
10
+ ArgumentError (wrong number of arguments (given 2, expected 1)):
11
+ lib/mailgun/tracking/auth.rb:8:in `call'
12
+
13
+
14
+ I, [2020-01-21T11:50:40.022428 #10847] INFO -- : Started POST "/mailgun" for 127.0.0.1 at 2020-01-21 11:50:40 +0200
15
+ F, [2020-01-21T11:50:40.023107 #10847] FATAL -- :
16
+ ArgumentError (wrong number of arguments (given 2, expected 1)):
17
+ lib/mailgun/tracking/auth.rb:8:in `call'
18
+
19
+
@@ -0,0 +1,31 @@
1
+ # frozen_string_literal: true
2
+
3
+ RSpec.describe Mailgun::Tracking::Auth do
4
+ let(:payload) { fixture('delivered.json') }
5
+
6
+ describe '.call' do
7
+ let(:auth) { instance_double(described_class) }
8
+
9
+ before do
10
+ allow(described_class).to receive(:new).and_return(auth).with(payload)
11
+ allow(auth).to receive(:valid?).and_return(true)
12
+ described_class.call(payload)
13
+ end
14
+
15
+ it { expect(auth).to have_received(:valid?) }
16
+ end
17
+
18
+ describe '#valid?' do
19
+ subject(:auth) { described_class.new(payload) }
20
+
21
+ context 'when the signature comparison is successful' do
22
+ it { is_expected.to be_valid }
23
+ end
24
+
25
+ context 'when the signature comparison is unsuccessful' do
26
+ before { payload['signature']['timestamp'] = '' }
27
+
28
+ it { is_expected.not_to be_valid }
29
+ end
30
+ end
31
+ end
@@ -1,68 +1,60 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  RSpec.describe Mailgun::Tracking::Middleware do
4
- subject(:rack) { described_class.new(app) }
5
-
6
- let(:app) { proc { [200, {}, []] } }
7
- let(:notifier) { instance_double(Mailgun::Tracking::Notifier) }
8
- let(:request) do
9
- instance_double(Mailgun::Tracking::Request, payload: payload, media_type: 'application/x-www-form-urlencoded')
10
- end
11
- let(:env) { env_for('http://localhost:3000') }
12
- let(:payload) { Mailgun::Tracking::Payload.new('event-data' => { event: 'delivered' }) }
13
-
14
- before do
15
- allow(Mailgun::Tracking).to receive(:notifier).and_return(notifier)
16
- allow(Mailgun::Tracking::Request).to receive(:new).with(env).and_return(request)
4
+ let(:app) do
5
+ lambda do |_env|
6
+ [200, { 'Content-Type' => 'text/plain' }, ['^_^']]
7
+ end
17
8
  end
9
+ let(:middleware) { described_class.new(app) }
18
10
 
19
- describe '#call' do
20
- context 'when request is not respond to the specified URL' do
21
- before do
22
- allow(request).to receive(:mailgun_tracking?).and_return(false)
23
- allow(notifier).to receive(:broadcast)
24
- end
11
+ context 'when a request is not respond to the specified URL' do
12
+ let(:env) { env_for('http://localhost:3000') }
25
13
 
26
- it { expect(rack.call(env)).to include(200) }
14
+ it { expect(middleware.call(env)).to eq([200, { 'Content-Type' => 'text/plain' }, ['^_^']]) }
15
+ end
27
16
 
28
- it do
29
- rack.call(env)
30
- expect(Mailgun::Tracking).not_to have_received(:notifier)
31
- end
17
+ context 'when a request is done not as an HTTP POST request' do
18
+ let(:env) do
19
+ env_for(
20
+ 'http://localhost:3000/mailgun',
21
+ 'REQUEST_METHOD' => 'GET',
22
+ 'CONTENT_TYPE' => 'application/json',
23
+ input: payload.to_json
24
+ )
32
25
  end
26
+ let(:payload) { fixture('delivered.json') }
33
27
 
34
- context 'when request is respond to the specified URL and the signature comparison is unsuccessful' do
35
- let(:params) { fixture('delivered.json') }
36
-
37
- before do
38
- allow(notifier).to receive(:broadcast).and_raise(Mailgun::Tracking::InvalidSignature)
39
- allow(request).to receive(:mailgun_tracking?).and_return(true)
40
- allow(request).to receive(:params).and_return(params)
41
- end
42
-
43
- it { expect(rack.call(env)).to include(400) }
28
+ it { expect(middleware.call(env)).to eq([200, { 'Content-Type' => 'text/plain' }, ['^_^']]) }
29
+ end
44
30
 
45
- it do
46
- rack.call(env)
47
- expect(Mailgun::Tracking).to have_received(:notifier)
48
- end
31
+ context 'when request is respond to the specified URL, POST request and the signature comparison is unsuccessful' do
32
+ let(:env) do
33
+ env_for(
34
+ 'http://localhost:3000/mailgun',
35
+ 'REQUEST_METHOD' => 'POST',
36
+ 'CONTENT_TYPE' => 'application/json',
37
+ input: payload.to_json
38
+ )
49
39
  end
40
+ let(:payload) { fixture('delivered.json') }
50
41
 
51
- context 'when request is respond to the specified URL and the signature comparison is successful' do
52
- let(:params) { fixture('delivered.json') }
53
-
54
- before do
55
- allow(request).to receive(:mailgun_tracking?).and_return(true)
56
- allow(request).to receive(:params).and_return(params)
57
- allow(notifier).to receive(:broadcast)
58
- end
42
+ before { payload['signature']['timestamp'] = '' }
59
43
 
60
- it { expect(rack.call(env)).to include(200) }
44
+ it { expect(middleware.call(env)).to eq([400, {}, []]) }
45
+ end
61
46
 
62
- it do
63
- rack.call(env)
64
- expect(Mailgun::Tracking).to have_received(:notifier)
65
- end
47
+ context 'when everything matches (URL, POST, Signature)' do
48
+ let(:env) do
49
+ env_for(
50
+ 'http://localhost:3000/mailgun',
51
+ 'REQUEST_METHOD' => 'POST',
52
+ 'CONTENT_TYPE' => 'application/json',
53
+ input: payload.to_json
54
+ )
66
55
  end
56
+ let(:payload) { fixture('delivered.json') }
57
+
58
+ it { expect(middleware.call(env)).to eq([200, {}, []]) }
67
59
  end
68
60
  end
@@ -12,13 +12,20 @@ RSpec.describe Mailgun::Tracking do
12
12
  end.to raise_error(NoMethodError)
13
13
  end
14
14
 
15
+ it { is_expected.not_to respond_to(:non_existent_method) }
16
+
15
17
  describe '.configure' do
16
18
  before do
19
+ allow(Mailgun::Tracking::Fanout).to receive(:on)
20
+ allow(Mailgun::Tracking::Fanout).to receive(:all)
21
+
17
22
  described_class.configure do |config|
18
23
  config.api_key = 'dab36017-478a-4373-9378-7070eb5968b5'
19
24
  config.endpoint = '/mailgun-tracking'
20
25
 
21
- config.notifier.all(proc {})
26
+ config.on('delivered', proc {})
27
+
28
+ config.all(proc {})
22
29
  end
23
30
  end
24
31
 
@@ -30,8 +37,8 @@ RSpec.describe Mailgun::Tracking do
30
37
  expect(described_class.endpoint).to eq('/mailgun-tracking')
31
38
  end
32
39
 
33
- it 'adds subscribers' do
34
- expect(described_class.notifier).not_to be_empty
35
- end
40
+ it { expect(Mailgun::Tracking::Fanout).to have_received(:on).with('delivered', instance_of(Proc)) }
41
+
42
+ it { expect(Mailgun::Tracking::Fanout).to have_received(:all).with(instance_of(Proc)) }
36
43
  end
37
44
  end
@@ -13,18 +13,20 @@ RSpec.shared_examples 'acts as rack' do
13
13
  allow(delivered).to receive(:call)
14
14
  allow(Delivered).to receive(:new).and_return(delivered)
15
15
 
16
- Mailgun::Tracking.notifier.subscribe(:delivered, Delivered.new)
16
+ Mailgun::Tracking.on(:delivered, Delivered.new)
17
17
 
18
- Mailgun::Tracking.notifier.subscribe :bounced do |payload|
18
+ Mailgun::Tracking.on :bounced do |payload|
19
19
  Delivered.new.call(payload)
20
20
  end
21
21
 
22
- Mailgun::Tracking.notifier.all(Delivered.new)
22
+ Mailgun::Tracking.all(Delivered.new)
23
23
  end
24
24
 
25
25
  it do
26
26
  post('/mailgun', payload.to_json, 'CONTENT_TYPE' => 'application/json')
27
- expect(delivered).to have_received(:call).with(Mailgun::Tracking::Payload.new(payload)).twice
27
+ expect(delivered).to have_received(:call).with(
28
+ payload
29
+ ).twice
28
30
  end
29
31
 
30
32
  context 'when the signature comparison is unsuccessful' do
metadata CHANGED
@@ -1,29 +1,29 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: mailgun-tracking
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.0.0
4
+ version: 3.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Artem Chubchenko
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2019-11-19 00:00:00.000000000 Z
11
+ date: 2020-01-30 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
- name: rack
14
+ name: catch_box
15
15
  requirement: !ruby/object:Gem::Requirement
16
16
  requirements:
17
- - - ">="
17
+ - - "~>"
18
18
  - !ruby/object:Gem::Version
19
- version: 1.6.0
19
+ version: 0.1.2
20
20
  type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
- - - ">="
24
+ - - "~>"
25
25
  - !ruby/object:Gem::Version
26
- version: 1.6.0
26
+ version: 0.1.2
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: appraisal
29
29
  requirement: !ruby/object:Gem::Requirement
@@ -38,32 +38,18 @@ dependencies:
38
38
  - - "~>"
39
39
  - !ruby/object:Gem::Version
40
40
  version: '2.2'
41
- - !ruby/object:Gem::Dependency
42
- name: bundler
43
- requirement: !ruby/object:Gem::Requirement
44
- requirements:
45
- - - "~>"
46
- - !ruby/object:Gem::Version
47
- version: '1.16'
48
- type: :development
49
- prerelease: false
50
- version_requirements: !ruby/object:Gem::Requirement
51
- requirements:
52
- - - "~>"
53
- - !ruby/object:Gem::Version
54
- version: '1.16'
55
41
  - !ruby/object:Gem::Dependency
56
42
  name: rack-test
57
43
  requirement: !ruby/object:Gem::Requirement
58
44
  requirements:
59
- - - "~>"
45
+ - - ">="
60
46
  - !ruby/object:Gem::Version
61
47
  version: '0'
62
48
  type: :development
63
49
  prerelease: false
64
50
  version_requirements: !ruby/object:Gem::Requirement
65
51
  requirements:
66
- - - "~>"
52
+ - - ">="
67
53
  - !ruby/object:Gem::Version
68
54
  version: '0'
69
55
  - !ruby/object:Gem::Dependency
@@ -100,14 +86,14 @@ dependencies:
100
86
  requirements:
101
87
  - - "~>"
102
88
  - !ruby/object:Gem::Version
103
- version: 0.76.0
89
+ version: 0.79.0
104
90
  type: :development
105
91
  prerelease: false
106
92
  version_requirements: !ruby/object:Gem::Requirement
107
93
  requirements:
108
94
  - - "~>"
109
95
  - !ruby/object:Gem::Version
110
- version: 0.76.0
96
+ version: 0.79.0
111
97
  - !ruby/object:Gem::Dependency
112
98
  name: rubocop-performance
113
99
  requirement: !ruby/object:Gem::Requirement
@@ -159,22 +145,16 @@ extra_rdoc_files: []
159
145
  files:
160
146
  - lib/generators/mailgun/tracking/install_generator.rb
161
147
  - lib/generators/mailgun/tracking/templates/mailgun_tracking.rb.erb
148
+ - lib/mailgun-tracking.rb
162
149
  - lib/mailgun/tracking.rb
150
+ - lib/mailgun/tracking/auth.rb
163
151
  - lib/mailgun/tracking/configuration.rb
164
- - lib/mailgun/tracking/exceptions.rb
165
- - lib/mailgun/tracking/listener.rb
152
+ - lib/mailgun/tracking/fanout.rb
166
153
  - lib/mailgun/tracking/middleware.rb
167
- - lib/mailgun/tracking/notifier.rb
168
- - lib/mailgun/tracking/payload.rb
169
154
  - lib/mailgun/tracking/railtie.rb
170
- - lib/mailgun/tracking/request.rb
171
- - lib/mailgun/tracking/signature.rb
172
- - lib/mailgun/tracking/subscriber.rb
173
- - lib/mailgun/tracking/subscriber/all_messages.rb
174
- - lib/mailgun/tracking/subscriber/evented.rb
175
- - lib/mailgun/tracking/util.rb
176
155
  - lib/mailgun/tracking/version.rb
177
156
  - spec/dummy/hanami/application.rb
157
+ - spec/dummy/logs/test.log
178
158
  - spec/dummy/rack/application.rb
179
159
  - spec/dummy/rails/application.rb
180
160
  - spec/dummy/rails/logs/test.log
@@ -184,17 +164,9 @@ files:
184
164
  - spec/integration/rack/rack_spec.rb
185
165
  - spec/integration/rails/rails_spec.rb
186
166
  - spec/integration/sinatra/sinatra_spec.rb
167
+ - spec/mailgun/tracking/auth_spec.rb
187
168
  - spec/mailgun/tracking/configuration_spec.rb
188
- - spec/mailgun/tracking/listener_spec.rb
189
169
  - spec/mailgun/tracking/middleware_spec.rb
190
- - spec/mailgun/tracking/notifier_spec.rb
191
- - spec/mailgun/tracking/payload_spec.rb
192
- - spec/mailgun/tracking/request_spec.rb
193
- - spec/mailgun/tracking/signature_spec.rb
194
- - spec/mailgun/tracking/subscriber/all_messages_spec.rb
195
- - spec/mailgun/tracking/subscriber/evented_spec.rb
196
- - spec/mailgun/tracking/subscriber_spec.rb
197
- - spec/mailgun/tracking/util_spec.rb
198
170
  - spec/mailgun/tracking/version_spec.rb
199
171
  - spec/mailgun/tracking_spec.rb
200
172
  - spec/spec_helper.rb
@@ -232,6 +204,7 @@ test_files:
232
204
  - spec/spec_helper.rb
233
205
  - spec/dummy/sinatra/application.rb
234
206
  - spec/dummy/hanami/application.rb
207
+ - spec/dummy/logs/test.log
235
208
  - spec/dummy/rack/application.rb
236
209
  - spec/dummy/rails/application.rb
237
210
  - spec/dummy/rails/logs/test.log
@@ -247,13 +220,5 @@ test_files:
247
220
  - spec/mailgun/tracking_spec.rb
248
221
  - spec/mailgun/tracking/configuration_spec.rb
249
222
  - spec/mailgun/tracking/version_spec.rb
250
- - spec/mailgun/tracking/signature_spec.rb
251
- - spec/mailgun/tracking/notifier_spec.rb
252
- - spec/mailgun/tracking/subscriber_spec.rb
253
223
  - spec/mailgun/tracking/middleware_spec.rb
254
- - spec/mailgun/tracking/util_spec.rb
255
- - spec/mailgun/tracking/listener_spec.rb
256
- - spec/mailgun/tracking/payload_spec.rb
257
- - spec/mailgun/tracking/request_spec.rb
258
- - spec/mailgun/tracking/subscriber/evented_spec.rb
259
- - spec/mailgun/tracking/subscriber/all_messages_spec.rb
224
+ - spec/mailgun/tracking/auth_spec.rb
@@ -1,11 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Mailgun
4
- module Tracking
5
- # A general Mailgun Tracking exception.
6
- Error = Class.new(StandardError)
7
-
8
- # Raised when signature is invalid.
9
- InvalidSignature = Class.new(Error)
10
- end
11
- end
@@ -1,55 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Mailgun
4
- module Tracking
5
- # Represents a mechanism for event listeners to subscribe to events and for event broadcasts.
6
- class Listener
7
- # List of subscribers.
8
- #
9
- # @return [Array<Mailgun::Tracking::Subscriber::AllMessages, Mailgun::Tracking::Subscriber::Evented>]
10
- attr_reader :subscribers
11
-
12
- # Initializes a new Listener object.
13
- #
14
- # @return [Mailgun::Tracking::Listener]
15
- def initialize
16
- @subscribers = []
17
- end
18
-
19
- # Adds a subscriber to the list of subscribers for the specified event.
20
- #
21
- # @param event [Symbol, String] The name of event.
22
- # @param callable [Proc, Class] The listener of event.
23
- # The callable objects should respond to call.
24
- #
25
- # @return [Array<Mailgun::Tracking::Subscriber::AllMessages, Mailgun::Tracking::Subscriber::Evented>]
26
- # The list of subscribers.
27
- def add_subscriber(event, callable)
28
- @subscribers << Subscriber.for(event, callable)
29
- end
30
-
31
- # Broadcasts an event to the subscribers.
32
- #
33
- # @param event [String] The name of event.
34
- # @param payload [Hash] The response parameters.
35
- #
36
- # @return [Array<Mailgun::Tracking::Subscriber::AllMessages, Mailgun::Tracking::Subscriber::Evented>]
37
- # The list of subscribers.
38
- def broadcast(event, payload)
39
- subscribers_for(event).each { |subscriber| subscriber.call(payload) }
40
- end
41
-
42
- private
43
-
44
- # Selects the subscribers for the specified event.
45
- #
46
- # @param event [String] The name of event.
47
- #
48
- # @return [Array<Mailgun::Tracking::Subscriber::AllMessages, Mailgun::Tracking::Subscriber::Evented>]
49
- # The list of subscribers.
50
- def subscribers_for(event)
51
- @subscribers.select { |subscriber| subscriber.subscribed_to?(event) }
52
- end
53
- end
54
- end
55
- end