mailgun-tracking 0.2.4 → 0.3.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: ef73193085f12611cf7f9c32ac0899a1ae957fda
4
- data.tar.gz: 0e9985c4fd7f5e3141369b0a0570f469d924c3cb
3
+ metadata.gz: b2f00cf238e43fe1fbe4b3da28f0ba82c14ddb46
4
+ data.tar.gz: abb5171204c548e64e0088385b0bd8df1da7dd1a
5
5
  SHA512:
6
- metadata.gz: d1fe1de3a718c8305736d3761549e970af99203f753285ca660a88483e6a48a2c5ba025e95e696b602cf07da9568c05a9c6055923cbfb15a6626971f46e34731
7
- data.tar.gz: fd581cea2524c5ac9abd56439f01607d71d55aeae088db1feaf4eaef907aec6259f752263f5b9bfcc5f3627aedfcc49b36dae0e5d4fe708108aea64337cd36a1
6
+ metadata.gz: 97249174916ea976f68d3f3c4db86efcc3b711751acd3f4d63806e03097c08ceb3916e4a34ea650043b406f1fd46ef231ca9c8658c1e16910e7765f93f8a91a9
7
+ data.tar.gz: c105354cd61ec52b16fab64eb7daf95af8164723fa451c1a2810887091f8760166f913ecf1c583ddf0dc86360a4e379cc215f9e120b6b043c0795692b84b2447
@@ -3,10 +3,13 @@ require 'mailgun/tracking/exceptions'
3
3
  require 'mailgun/tracking/listener'
4
4
  require 'mailgun/tracking/middleware'
5
5
  require 'mailgun/tracking/notifier'
6
+ require 'mailgun/tracking/payload'
6
7
  require 'mailgun/tracking/signature'
7
8
  require 'mailgun/tracking/subscriber'
9
+ require 'mailgun/tracking/util'
8
10
  require 'mailgun/tracking/version'
9
11
  require 'mailgun/tracking/railtie' if defined?(Rails)
12
+ require 'mailgun/tracking/request'
10
13
 
11
14
  # Module for interacting with the Mailgun.
12
15
  module Mailgun
@@ -15,37 +15,28 @@ module Mailgun
15
15
  #
16
16
  # @return [Array(Numeric,Hash,Array)] The Rack-style response.
17
17
  def call(env)
18
- @env = env
19
-
20
- if mailgun_tracking_request?
21
- Mailgun::Tracking.notifier.broadcast(request.params.fetch('event'), request.params)
22
- null_response
23
- else
24
- @app.call(env)
25
- end
18
+ @request = Request.new(env)
19
+ return @app.call(env) unless @request.mailgun_tracking?
20
+ handle_event
26
21
  end
27
22
 
28
23
  private
29
24
 
30
- # Interface to a Rack environment.
31
- #
32
- # @return [Rack::Request]
33
- def request
34
- ::Rack::Request.new(@env)
25
+ # @return [Array(Numeric,Hash,Array)] The Rack-style response.
26
+ def null_response
27
+ [200, {}, []]
35
28
  end
36
29
 
37
- # Checks if the path of the request is equal to the endpoint.
38
- #
39
- # @return [Boolean]
40
- def mailgun_tracking_request?
41
- return false unless request.post?
42
- return false unless request.path == Configuration.instance.endpoint
43
- true
30
+ # @return [Array(Numeric,Hash,Array)] The Rack-style response.
31
+ def bad_request
32
+ [400, {}, []]
44
33
  end
45
34
 
46
- # @return [Array(Numeric,Hash,Array)] The Rack-style response.
47
- def null_response
48
- [200, {}, []]
35
+ def handle_event
36
+ Mailgun::Tracking.notifier.broadcast(@request.params.fetch('event'), @request.payload)
37
+ null_response
38
+ rescue InvalidSignature
39
+ bad_request
49
40
  end
50
41
  end
51
42
  end
@@ -0,0 +1,48 @@
1
+ require 'set'
2
+
3
+ module Mailgun
4
+ module Tracking
5
+ # Payload object.
6
+ class Payload
7
+ # Initializes a new Payload object.
8
+ #
9
+ # @param options [Hash]
10
+ #
11
+ # @return [Mailgun::Tracking::Payload]
12
+ def initialize(options = {})
13
+ @options = Util.normalize(options)
14
+ @original = options
15
+ define_instance_methods(Set.new(@options.keys), @options)
16
+ end
17
+
18
+ # Returns a value of the original payload with the given key.
19
+ #
20
+ # @param key [String]
21
+ #
22
+ # @return a value of the original payload.
23
+ def [](key)
24
+ @original[key]
25
+ end
26
+
27
+ private
28
+
29
+ # @return [Class]
30
+ def __metaclass__
31
+ class << self
32
+ self
33
+ end
34
+ end
35
+
36
+ # @return [void]
37
+ def define_instance_methods(keys, options)
38
+ __metaclass__.instance_eval do
39
+ keys.each do |key|
40
+ define_method(key) { @options[key] }
41
+ next unless [FalseClass, TrueClass].include?(options[key].class)
42
+ define_method(:"#{key}?") { @options[key] }
43
+ end
44
+ end
45
+ end
46
+ end
47
+ end
48
+ end
@@ -0,0 +1,19 @@
1
+ module Mailgun
2
+ module Tracking
3
+ # Provides a convenient interface to a Rack environment.
4
+ class Request < ::Rack::Request
5
+ # Checks if the request is respond to the specified URL.
6
+ #
7
+ # @return [Boolean]
8
+ def mailgun_tracking?
9
+ return false unless post?
10
+ path == Configuration.instance.endpoint
11
+ end
12
+
13
+ # @return [Mailgun::Tracking::Payload]
14
+ def payload
15
+ @payload ||= Payload.new(params)
16
+ end
17
+ end
18
+ end
19
+ end
@@ -23,9 +23,9 @@ module Mailgun
23
23
  #
24
24
  # @return [Mailgun::Tracking::Signature]
25
25
  def initialize(payload)
26
- @token = payload.fetch('token')
27
- @timestamp = payload.fetch('timestamp')
28
- @signature = payload.fetch('signature')
26
+ @token = payload['token']
27
+ @timestamp = payload['timestamp']
28
+ @signature = payload['signature']
29
29
  end
30
30
 
31
31
  # @return [Boolean]
@@ -0,0 +1,46 @@
1
+ module Mailgun
2
+ module Tracking
3
+ # Utility methods.
4
+ module Util
5
+ class << self
6
+ # Returns a new hash with all keys converted to symbols in downcase.
7
+ #
8
+ # @param options [Hash]
9
+ #
10
+ # @return [Hash]
11
+ def normalize(options = {})
12
+ object = normalize_keys(options.dup)
13
+ object
14
+ end
15
+
16
+ private
17
+
18
+ def normalize_keys(options)
19
+ return from_h(options) if options.is_a?(Hash)
20
+ return from_ary(options) if options.is_a?(Array)
21
+ options
22
+ end
23
+
24
+ def from_h(options)
25
+ Hash[options.map do |key, value|
26
+ [underscore(key), normalize_keys(value)]
27
+ end]
28
+ end
29
+
30
+ def from_ary(options)
31
+ options.map(&method(:normalize_keys))
32
+ end
33
+
34
+ def underscore(key)
35
+ return key unless key.respond_to?(:to_sym)
36
+
37
+ key.to_s
38
+ .dup
39
+ .tr('-', '_')
40
+ .downcase
41
+ .to_sym
42
+ end
43
+ end
44
+ end
45
+ end
46
+ end
@@ -17,14 +17,14 @@ module Mailgun
17
17
  #
18
18
  # @return [Integer]
19
19
  def minor
20
- 2
20
+ 3
21
21
  end
22
22
 
23
23
  # Patch version.
24
24
  #
25
25
  # @return [Integer]
26
26
  def patch
27
- 4
27
+ 0
28
28
  end
29
29
 
30
30
  # Returns a hash representation of version.
@@ -0,0 +1,13 @@
1
+ module Dummy
2
+ Application = Rack::Builder.new do
3
+ use Mailgun::Tracking::Middleware
4
+
5
+ map '/' do
6
+ run(
7
+ proc do
8
+ [200, { 'Content-Type' => 'text/plain' }, ['^_^']]
9
+ end
10
+ )
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,21 @@
1
+ ENV['RAILS_ENV'] = 'test'
2
+
3
+ require 'rails'
4
+ require 'mailgun/tracking/railtie'
5
+
6
+ module Dummy
7
+ class Application < Rails::Application
8
+ if Gem::Version.new(Rails.version) < Gem::Version.new('5.2')
9
+ config.secret_token = '6e394142b6fb6349707ea48841f9cb5898c182c855c002689866aac50d6d4bda'
10
+ config.secret_key_base = '08e540044922f3ecef8e4e1e672d0f7d1cfa56a80d20e5ee68d8006aab5afb83'
11
+ end
12
+
13
+ log_path = File.join(File.dirname(__FILE__), 'logs', 'test.log')
14
+ config.logger = Logger.new(log_path)
15
+ Rails.logger = config.logger
16
+
17
+ config.eager_load = false
18
+ end
19
+ end
20
+
21
+ Dummy::Application.initialize!
@@ -0,0 +1,265 @@
1
+ # Logfile created on 2018-03-13 02:09:24 +0200 by logger.rb/56438
2
+ I, [2018-03-13T02:09:24.712282 #62428] INFO -- : Started POST "/mailgun" for 127.0.0.1 at 2018-03-13 02:09:24 +0200
3
+ I, [2018-03-13T02:09:24.722710 #62428] INFO -- : Started POST "/mailgun" for 127.0.0.1 at 2018-03-13 02:09:24 +0200
4
+ F, [2018-03-13T02:09:24.725562 #62428] FATAL -- :
5
+ Mailgun::Tracking::InvalidSignature (Mailgun::Tracking::InvalidSignature):
6
+ lib/mailgun/tracking/signature.rb:16:in `verify!'
7
+ lib/mailgun/tracking/notifier.rb:49:in `broadcast'
8
+ lib/mailgun/tracking/middleware.rb:21:in `call'
9
+
10
+
11
+ I, [2018-03-13T02:10:59.655696 #62449] INFO -- : Started POST "/mailgun" for 127.0.0.1 at 2018-03-13 02:10:59 +0200
12
+ I, [2018-03-13T02:10:59.667026 #62449] INFO -- : Started POST "/mailgun" for 127.0.0.1 at 2018-03-13 02:10:59 +0200
13
+ F, [2018-03-13T02:10:59.669988 #62449] FATAL -- :
14
+ Mailgun::Tracking::InvalidSignature (Mailgun::Tracking::InvalidSignature):
15
+ lib/mailgun/tracking/signature.rb:16:in `verify!'
16
+ lib/mailgun/tracking/notifier.rb:49:in `broadcast'
17
+ lib/mailgun/tracking/middleware.rb:21:in `call'
18
+
19
+
20
+ I, [2018-03-13T08:38:40.694094 #64748] INFO -- : Started POST "/mailgun" for 127.0.0.1 at 2018-03-13 08:38:40 +0200
21
+ I, [2018-03-13T08:38:40.704042 #64748] INFO -- : Started POST "/mailgun" for 127.0.0.1 at 2018-03-13 08:38:40 +0200
22
+ F, [2018-03-13T08:38:40.705522 #64748] FATAL -- :
23
+ Mailgun::Tracking::InvalidSignature (Mailgun::Tracking::InvalidSignature):
24
+ lib/mailgun/tracking/signature.rb:16:in `verify!'
25
+ lib/mailgun/tracking/notifier.rb:49:in `broadcast'
26
+ lib/mailgun/tracking/middleware.rb:21:in `call'
27
+
28
+
29
+ I, [2018-03-13T08:39:03.847726 #64765] INFO -- : Started POST "/mailgun" for 127.0.0.1 at 2018-03-13 08:39:03 +0200
30
+ I, [2018-03-13T08:39:03.852023 #64765] INFO -- : Started POST "/mailgun" for 127.0.0.1 at 2018-03-13 08:39:03 +0200
31
+ F, [2018-03-13T08:39:03.852909 #64765] FATAL -- :
32
+ Mailgun::Tracking::InvalidSignature (Mailgun::Tracking::InvalidSignature):
33
+ lib/mailgun/tracking/signature.rb:16:in `verify!'
34
+ lib/mailgun/tracking/notifier.rb:49:in `broadcast'
35
+ lib/mailgun/tracking/middleware.rb:21:in `call'
36
+
37
+
38
+ I, [2018-03-13T08:39:17.294931 #64774] INFO -- : Started POST "/mailgun" for 127.0.0.1 at 2018-03-13 08:39:17 +0200
39
+ I, [2018-03-13T08:39:17.298928 #64774] INFO -- : Started POST "/mailgun" for 127.0.0.1 at 2018-03-13 08:39:17 +0200
40
+ F, [2018-03-13T08:39:17.299795 #64774] FATAL -- :
41
+ Mailgun::Tracking::InvalidSignature (Mailgun::Tracking::InvalidSignature):
42
+ lib/mailgun/tracking/signature.rb:16:in `verify!'
43
+ lib/mailgun/tracking/notifier.rb:49:in `broadcast'
44
+ lib/mailgun/tracking/middleware.rb:21:in `call'
45
+
46
+
47
+ I, [2018-03-13T08:41:25.137308 #64797] INFO -- : Started POST "/mailgun" for 127.0.0.1 at 2018-03-13 08:41:25 +0200
48
+ I, [2018-03-13T08:41:25.142976 #64797] INFO -- : Started POST "/mailgun" for 127.0.0.1 at 2018-03-13 08:41:25 +0200
49
+ F, [2018-03-13T08:41:25.144406 #64797] FATAL -- :
50
+ Mailgun::Tracking::InvalidSignature (my body):
51
+ lib/mailgun/tracking/signature.rb:16:in `verify!'
52
+ lib/mailgun/tracking/notifier.rb:49:in `broadcast'
53
+ lib/mailgun/tracking/middleware.rb:21:in `call'
54
+
55
+
56
+ I, [2018-03-13T22:25:16.416799 #69766] INFO -- : Started POST "/mailgun" for 127.0.0.1 at 2018-03-13 22:25:16 +0200
57
+ I, [2018-03-13T22:25:16.424802 #69766] INFO -- : Started POST "/mailgun" for 127.0.0.1 at 2018-03-13 22:25:16 +0200
58
+ I, [2018-03-13T22:25:19.501498 #69773] INFO -- : Started POST "/mailgun" for 127.0.0.1 at 2018-03-13 22:25:19 +0200
59
+ I, [2018-03-13T22:25:19.505520 #69773] INFO -- : Started POST "/mailgun" for 127.0.0.1 at 2018-03-13 22:25:19 +0200
60
+ I, [2018-03-13T22:25:22.425417 #69780] INFO -- : Started POST "/mailgun" for 127.0.0.1 at 2018-03-13 22:25:22 +0200
61
+ I, [2018-03-13T22:25:22.429369 #69780] INFO -- : Started POST "/mailgun" for 127.0.0.1 at 2018-03-13 22:25:22 +0200
62
+ I, [2018-04-24T23:54:45.990614 #56787] INFO -- : Started POST "/mailgun" for 127.0.0.1 at 2018-04-24 23:54:45 +0300
63
+ I, [2018-04-24T23:54:46.000997 #56787] INFO -- : Started POST "/mailgun" for 127.0.0.1 at 2018-04-24 23:54:46 +0300
64
+ I, [2018-04-24T23:54:51.691821 #56835] INFO -- : Started POST "/mailgun" for 127.0.0.1 at 2018-04-24 23:54:51 +0300
65
+ I, [2018-04-24T23:54:51.703559 #56835] INFO -- : Started POST "/mailgun" for 127.0.0.1 at 2018-04-24 23:54:51 +0300
66
+ I, [2018-04-24T23:54:55.783263 #56885] INFO -- : Started POST "/mailgun" for 127.0.0.1 at 2018-04-24 23:54:55 +0300
67
+ I, [2018-04-24T23:54:55.787896 #56885] INFO -- : Started POST "/mailgun" for 127.0.0.1 at 2018-04-24 23:54:55 +0300
68
+ I, [2018-04-25T00:00:15.262401 #59573] INFO -- : Started POST "/mailgun" for 127.0.0.1 at 2018-04-25 00:00:15 +0300
69
+ I, [2018-04-25T00:00:15.268608 #59573] INFO -- : Started POST "/mailgun" for 127.0.0.1 at 2018-04-25 00:00:15 +0300
70
+ I, [2018-04-25T00:07:31.673037 #63234] INFO -- : Started POST "/mailgun" for 127.0.0.1 at 2018-04-25 00:07:31 +0300
71
+ I, [2018-04-25T00:07:31.682855 #63234] INFO -- : Started POST "/mailgun" for 127.0.0.1 at 2018-04-25 00:07:31 +0300
72
+ I, [2018-04-25T00:08:47.589229 #63857] INFO -- : Started POST "/mailgun" for 127.0.0.1 at 2018-04-25 00:08:47 +0300
73
+ I, [2018-04-25T00:08:47.596643 #63857] INFO -- : Started POST "/mailgun" for 127.0.0.1 at 2018-04-25 00:08:47 +0300
74
+ I, [2018-04-25T00:08:58.855994 #63961] INFO -- : Started POST "/mailgun" for 127.0.0.1 at 2018-04-25 00:08:58 +0300
75
+ I, [2018-04-25T00:08:58.863090 #63961] INFO -- : Started POST "/mailgun" for 127.0.0.1 at 2018-04-25 00:08:58 +0300
76
+ I, [2018-04-25T00:38:43.511002 #78948] INFO -- : Started POST "/mailgun" for 127.0.0.1 at 2018-04-25 00:38:43 +0300
77
+ F, [2018-04-25T00:38:43.512861 #78948] FATAL -- :
78
+ F, [2018-04-25T00:38:43.514548 #78948] FATAL -- : NoMethodError (undefined method `fetch' for #<Mailgun::Tracking::Payload:0x007f8ceba814a0>):
79
+ F, [2018-04-25T00:38:43.514605 #78948] FATAL -- :
80
+ F, [2018-04-25T00:38:43.514635 #78948] FATAL -- : lib/mailgun/tracking/signature.rb:26:in `initialize'
81
+ lib/mailgun/tracking/signature.rb:15:in `new'
82
+ lib/mailgun/tracking/signature.rb:15:in `verify!'
83
+ lib/mailgun/tracking/notifier.rb:49:in `broadcast'
84
+ lib/mailgun/tracking/middleware.rb:36:in `handle_event'
85
+ lib/mailgun/tracking/middleware.rb:20:in `call'
86
+ I, [2018-04-25T00:38:43.547794 #78948] INFO -- : Started POST "/mailgun" for 127.0.0.1 at 2018-04-25 00:38:43 +0300
87
+ F, [2018-04-25T00:38:43.549697 #78948] FATAL -- :
88
+ F, [2018-04-25T00:38:43.551181 #78948] FATAL -- : NoMethodError (undefined method `fetch' for #<Mailgun::Tracking::Payload:0x007f8cecdae438>):
89
+ F, [2018-04-25T00:38:43.551248 #78948] FATAL -- :
90
+ F, [2018-04-25T00:38:43.551277 #78948] FATAL -- : lib/mailgun/tracking/signature.rb:26:in `initialize'
91
+ lib/mailgun/tracking/signature.rb:15:in `new'
92
+ lib/mailgun/tracking/signature.rb:15:in `verify!'
93
+ lib/mailgun/tracking/notifier.rb:49:in `broadcast'
94
+ lib/mailgun/tracking/middleware.rb:36:in `handle_event'
95
+ lib/mailgun/tracking/middleware.rb:20:in `call'
96
+ I, [2018-04-25T00:48:43.869200 #83812] INFO -- : Started POST "/mailgun" for 127.0.0.1 at 2018-04-25 00:48:43 +0300
97
+ F, [2018-04-25T00:48:43.870774 #83812] FATAL -- :
98
+ F, [2018-04-25T00:48:43.872805 #83812] FATAL -- : NameError (undefined local variable or method `byebug' for Mailgun::Tracking::Signature:Class):
99
+ F, [2018-04-25T00:48:43.872870 #83812] FATAL -- :
100
+ F, [2018-04-25T00:48:43.872901 #83812] FATAL -- : lib/mailgun/tracking/signature.rb:15:in `verify!'
101
+ lib/mailgun/tracking/notifier.rb:49:in `broadcast'
102
+ lib/mailgun/tracking/middleware.rb:36:in `handle_event'
103
+ lib/mailgun/tracking/middleware.rb:20:in `call'
104
+ I, [2018-04-25T00:48:43.889608 #83812] INFO -- : Started POST "/mailgun" for 127.0.0.1 at 2018-04-25 00:48:43 +0300
105
+ F, [2018-04-25T00:48:43.890865 #83812] FATAL -- :
106
+ F, [2018-04-25T00:48:43.893656 #83812] FATAL -- : NameError (undefined local variable or method `byebug' for Mailgun::Tracking::Signature:Class):
107
+ F, [2018-04-25T00:48:43.893905 #83812] FATAL -- :
108
+ F, [2018-04-25T00:48:43.893958 #83812] FATAL -- : lib/mailgun/tracking/signature.rb:15:in `verify!'
109
+ lib/mailgun/tracking/notifier.rb:49:in `broadcast'
110
+ lib/mailgun/tracking/middleware.rb:36:in `handle_event'
111
+ lib/mailgun/tracking/middleware.rb:20:in `call'
112
+ I, [2018-04-25T00:53:34.805027 #86157] INFO -- : Started POST "/mailgun" for 127.0.0.1 at 2018-04-25 00:53:34 +0300
113
+ F, [2018-04-25T00:53:34.807247 #86157] FATAL -- :
114
+ F, [2018-04-25T00:53:34.810283 #86157] FATAL -- : NameError (undefined local variable or method `byebug' for Mailgun::Tracking::Signature:Class):
115
+ F, [2018-04-25T00:53:34.810349 #86157] FATAL -- :
116
+ F, [2018-04-25T00:53:34.810377 #86157] FATAL -- : lib/mailgun/tracking/signature.rb:15:in `verify!'
117
+ lib/mailgun/tracking/notifier.rb:49:in `broadcast'
118
+ lib/mailgun/tracking/middleware.rb:40:in `handle_event'
119
+ lib/mailgun/tracking/middleware.rb:24:in `call'
120
+ I, [2018-04-25T00:53:34.843504 #86157] INFO -- : Started POST "/mailgun" for 127.0.0.1 at 2018-04-25 00:53:34 +0300
121
+ F, [2018-04-25T00:53:34.844661 #86157] FATAL -- :
122
+ F, [2018-04-25T00:53:34.846829 #86157] FATAL -- : NameError (undefined local variable or method `byebug' for Mailgun::Tracking::Signature:Class):
123
+ F, [2018-04-25T00:53:34.846880 #86157] FATAL -- :
124
+ F, [2018-04-25T00:53:34.846916 #86157] FATAL -- : lib/mailgun/tracking/signature.rb:15:in `verify!'
125
+ lib/mailgun/tracking/notifier.rb:49:in `broadcast'
126
+ lib/mailgun/tracking/middleware.rb:40:in `handle_event'
127
+ lib/mailgun/tracking/middleware.rb:24:in `call'
128
+ I, [2018-04-25T00:53:52.418577 #86317] INFO -- : Started POST "/mailgun" for 127.0.0.1 at 2018-04-25 00:53:52 +0300
129
+ F, [2018-04-25T00:53:52.421746 #86317] FATAL -- :
130
+ F, [2018-04-25T00:53:52.422655 #86317] FATAL -- : NoMethodError (undefined method `fetch' for #<Mailgun::Tracking::Payload:0x007f805be0b748>):
131
+ F, [2018-04-25T00:53:52.422713 #86317] FATAL -- :
132
+ F, [2018-04-25T00:53:52.422754 #86317] FATAL -- : lib/mailgun/tracking/middleware.rb:20:in `call'
133
+ I, [2018-04-25T00:53:52.440588 #86317] INFO -- : Started POST "/mailgun" for 127.0.0.1 at 2018-04-25 00:53:52 +0300
134
+ F, [2018-04-25T00:53:52.442091 #86317] FATAL -- :
135
+ F, [2018-04-25T00:53:52.443770 #86317] FATAL -- : NoMethodError (undefined method `fetch' for #<Mailgun::Tracking::Payload:0x007f805bbf0e90>):
136
+ F, [2018-04-25T00:53:52.443907 #86317] FATAL -- :
137
+ F, [2018-04-25T00:53:52.443978 #86317] FATAL -- : lib/mailgun/tracking/middleware.rb:20:in `call'
138
+ I, [2018-04-25T00:54:12.690958 #86480] INFO -- : Started POST "/mailgun" for 127.0.0.1 at 2018-04-25 00:54:12 +0300
139
+ F, [2018-04-25T00:54:12.693626 #86480] FATAL -- :
140
+ F, [2018-04-25T00:54:12.695061 #86480] FATAL -- : NoMethodError (undefined method `fetch' for #<Mailgun::Tracking::Payload:0x007ff19b999e38>):
141
+ F, [2018-04-25T00:54:12.695282 #86480] FATAL -- :
142
+ F, [2018-04-25T00:54:12.695543 #86480] FATAL -- : lib/mailgun/tracking/middleware.rb:20:in `call'
143
+ I, [2018-04-25T00:54:12.720314 #86480] INFO -- : Started POST "/mailgun" for 127.0.0.1 at 2018-04-25 00:54:12 +0300
144
+ F, [2018-04-25T00:54:12.724327 #86480] FATAL -- :
145
+ F, [2018-04-25T00:54:12.726678 #86480] FATAL -- : NoMethodError (undefined method `fetch' for #<Mailgun::Tracking::Payload:0x007ff19aac9728>):
146
+ F, [2018-04-25T00:54:12.726765 #86480] FATAL -- :
147
+ F, [2018-04-25T00:54:12.726807 #86480] FATAL -- : lib/mailgun/tracking/middleware.rb:20:in `call'
148
+ I, [2018-04-25T00:54:35.111183 #86674] INFO -- : Started POST "/mailgun" for 127.0.0.1 at 2018-04-25 00:54:35 +0300
149
+ F, [2018-04-25T00:54:35.112388 #86674] FATAL -- :
150
+ F, [2018-04-25T00:54:35.118882 #86674] FATAL -- : NoMethodError (undefined method `fetch' for #<Mailgun::Tracking::Payload:0x007fc9d6beb2a0>):
151
+ F, [2018-04-25T00:54:35.119460 #86674] FATAL -- :
152
+ F, [2018-04-25T00:54:35.119694 #86674] FATAL -- : lib/mailgun/tracking/middleware.rb:20:in `call'
153
+ I, [2018-04-25T00:54:35.162204 #86674] INFO -- : Started POST "/mailgun" for 127.0.0.1 at 2018-04-25 00:54:35 +0300
154
+ F, [2018-04-25T00:54:35.163190 #86674] FATAL -- :
155
+ F, [2018-04-25T00:54:35.167260 #86674] FATAL -- : NoMethodError (undefined method `fetch' for #<Mailgun::Tracking::Payload:0x007fc9d72497c8>):
156
+ F, [2018-04-25T00:54:35.167365 #86674] FATAL -- :
157
+ F, [2018-04-25T00:54:35.167403 #86674] FATAL -- : lib/mailgun/tracking/middleware.rb:20:in `call'
158
+ I, [2018-04-25T00:56:19.898594 #87530] INFO -- : Started POST "/mailgun" for 127.0.0.1 at 2018-04-25 00:56:19 +0300
159
+ F, [2018-04-25T00:56:19.899799 #87530] FATAL -- :
160
+ F, [2018-04-25T00:56:19.901352 #87530] FATAL -- : NoMethodError (undefined method `fetch' for #<Mailgun::Tracking::Payload:0x007fceee989300>):
161
+ F, [2018-04-25T00:56:19.901480 #87530] FATAL -- :
162
+ F, [2018-04-25T00:56:19.901564 #87530] FATAL -- : lib/mailgun/tracking/middleware.rb:20:in `call'
163
+ I, [2018-04-25T00:56:19.920298 #87530] INFO -- : Started POST "/mailgun" for 127.0.0.1 at 2018-04-25 00:56:19 +0300
164
+ F, [2018-04-25T00:56:19.921323 #87530] FATAL -- :
165
+ F, [2018-04-25T00:56:19.923080 #87530] FATAL -- : NoMethodError (undefined method `fetch' for #<Mailgun::Tracking::Payload:0x007fceee15e630>):
166
+ F, [2018-04-25T00:56:19.923140 #87530] FATAL -- :
167
+ F, [2018-04-25T00:56:19.923170 #87530] FATAL -- : lib/mailgun/tracking/middleware.rb:20:in `call'
168
+ I, [2018-04-25T00:56:40.364193 #87701] INFO -- : Started POST "/mailgun" for 127.0.0.1 at 2018-04-25 00:56:40 +0300
169
+ F, [2018-04-25T00:56:40.369388 #87701] FATAL -- :
170
+ F, [2018-04-25T00:56:40.372063 #87701] FATAL -- : NameError (undefined local variable or method `byebug' for Mailgun::Tracking::Signature:Class):
171
+ F, [2018-04-25T00:56:40.372275 #87701] FATAL -- :
172
+ F, [2018-04-25T00:56:40.372395 #87701] FATAL -- : lib/mailgun/tracking/signature.rb:15:in `verify!'
173
+ lib/mailgun/tracking/notifier.rb:49:in `broadcast'
174
+ lib/mailgun/tracking/middleware.rb:40:in `handle_event'
175
+ lib/mailgun/tracking/middleware.rb:24:in `call'
176
+ I, [2018-04-25T00:56:40.397076 #87701] INFO -- : Started POST "/mailgun" for 127.0.0.1 at 2018-04-25 00:56:40 +0300
177
+ F, [2018-04-25T00:56:40.410666 #87701] FATAL -- :
178
+ F, [2018-04-25T00:56:40.412877 #87701] FATAL -- : NameError (undefined local variable or method `byebug' for Mailgun::Tracking::Signature:Class):
179
+ F, [2018-04-25T00:56:40.412945 #87701] FATAL -- :
180
+ F, [2018-04-25T00:56:40.412976 #87701] FATAL -- : lib/mailgun/tracking/signature.rb:15:in `verify!'
181
+ lib/mailgun/tracking/notifier.rb:49:in `broadcast'
182
+ lib/mailgun/tracking/middleware.rb:40:in `handle_event'
183
+ lib/mailgun/tracking/middleware.rb:24:in `call'
184
+ I, [2018-04-25T00:57:36.260230 #88155] INFO -- : Started POST "/mailgun" for 127.0.0.1 at 2018-04-25 00:57:36 +0300
185
+ F, [2018-04-25T00:57:36.262725 #88155] FATAL -- :
186
+ F, [2018-04-25T00:57:36.265357 #88155] FATAL -- : NameError (undefined local variable or method `byebug' for Mailgun::Tracking::Signature:Class):
187
+ F, [2018-04-25T00:57:36.265430 #88155] FATAL -- :
188
+ F, [2018-04-25T00:57:36.265463 #88155] FATAL -- : lib/mailgun/tracking/signature.rb:15:in `verify!'
189
+ lib/mailgun/tracking/notifier.rb:49:in `broadcast'
190
+ lib/mailgun/tracking/middleware.rb:40:in `handle_event'
191
+ lib/mailgun/tracking/middleware.rb:24:in `call'
192
+ I, [2018-04-25T00:57:36.285782 #88155] INFO -- : Started POST "/mailgun" for 127.0.0.1 at 2018-04-25 00:57:36 +0300
193
+ F, [2018-04-25T00:57:36.286942 #88155] FATAL -- :
194
+ F, [2018-04-25T00:57:36.290573 #88155] FATAL -- : NameError (undefined local variable or method `byebug' for Mailgun::Tracking::Signature:Class):
195
+ F, [2018-04-25T00:57:36.290683 #88155] FATAL -- :
196
+ F, [2018-04-25T00:57:36.290738 #88155] FATAL -- : lib/mailgun/tracking/signature.rb:15:in `verify!'
197
+ lib/mailgun/tracking/notifier.rb:49:in `broadcast'
198
+ lib/mailgun/tracking/middleware.rb:40:in `handle_event'
199
+ lib/mailgun/tracking/middleware.rb:24:in `call'
200
+ I, [2018-04-25T01:00:24.482163 #89518] INFO -- : Started POST "/mailgun" for 127.0.0.1 at 2018-04-25 01:00:24 +0300
201
+ F, [2018-04-25T01:00:24.483351 #89518] FATAL -- :
202
+ F, [2018-04-25T01:00:24.484093 #89518] FATAL -- : NoMethodError (undefined method `aaaaa' for #<Mailgun::Tracking::Payload:0x007f7fec629350>):
203
+ F, [2018-04-25T01:00:24.484132 #89518] FATAL -- :
204
+ F, [2018-04-25T01:00:24.484160 #89518] FATAL -- : lib/mailgun/tracking/middleware.rb:20:in `call'
205
+ I, [2018-04-25T01:00:24.500588 #89518] INFO -- : Started POST "/mailgun" for 127.0.0.1 at 2018-04-25 01:00:24 +0300
206
+ F, [2018-04-25T01:00:24.501884 #89518] FATAL -- :
207
+ F, [2018-04-25T01:00:24.503478 #89518] FATAL -- : NoMethodError (undefined method `aaaaa' for #<Mailgun::Tracking::Payload:0x007f7fec98fd00>):
208
+ F, [2018-04-25T01:00:24.503569 #89518] FATAL -- :
209
+ F, [2018-04-25T01:00:24.503604 #89518] FATAL -- : lib/mailgun/tracking/middleware.rb:20:in `call'
210
+ I, [2018-04-25T01:06:18.020376 #92376] INFO -- : Started POST "/mailgun" for 127.0.0.1 at 2018-04-25 01:06:18 +0300
211
+ F, [2018-04-25T01:06:18.022654 #92376] FATAL -- :
212
+ F, [2018-04-25T01:06:18.023686 #92376] FATAL -- : NoMethodError (undefined method `aaaaa' for #<Mailgun::Tracking::Payload:0x007fe17257e8f0>):
213
+ F, [2018-04-25T01:06:18.023752 #92376] FATAL -- :
214
+ F, [2018-04-25T01:06:18.023782 #92376] FATAL -- : lib/mailgun/tracking/middleware.rb:20:in `call'
215
+ I, [2018-04-25T01:06:18.046236 #92376] INFO -- : Started POST "/mailgun" for 127.0.0.1 at 2018-04-25 01:06:18 +0300
216
+ F, [2018-04-25T01:06:18.050229 #92376] FATAL -- :
217
+ F, [2018-04-25T01:06:18.051960 #92376] FATAL -- : NoMethodError (undefined method `aaaaa' for #<Mailgun::Tracking::Payload:0x007fe17227f6e0>):
218
+ F, [2018-04-25T01:06:18.052053 #92376] FATAL -- :
219
+ F, [2018-04-25T01:06:18.052166 #92376] FATAL -- : lib/mailgun/tracking/middleware.rb:20:in `call'
220
+ I, [2018-04-25T01:08:11.572026 #93296] INFO -- : Started POST "/mailgun" for 127.0.0.1 at 2018-04-25 01:08:11 +0300
221
+ F, [2018-04-25T01:08:11.573663 #93296] FATAL -- :
222
+ F, [2018-04-25T01:08:11.574775 #93296] FATAL -- : NoMethodError (undefined method `aaaaa' for #<Mailgun::Tracking::Payload:0x007faf30b14068>):
223
+ F, [2018-04-25T01:08:11.574851 #93296] FATAL -- :
224
+ F, [2018-04-25T01:08:11.574881 #93296] FATAL -- : lib/mailgun/tracking/middleware.rb:20:in `call'
225
+ I, [2018-04-25T01:08:11.616464 #93296] INFO -- : Started POST "/mailgun" for 127.0.0.1 at 2018-04-25 01:08:11 +0300
226
+ F, [2018-04-25T01:08:11.618955 #93296] FATAL -- :
227
+ F, [2018-04-25T01:08:11.621841 #93296] FATAL -- : NoMethodError (undefined method `aaaaa' for #<Mailgun::Tracking::Payload:0x007faf3121d0f8>):
228
+ F, [2018-04-25T01:08:11.621983 #93296] FATAL -- :
229
+ F, [2018-04-25T01:08:11.622034 #93296] FATAL -- : lib/mailgun/tracking/middleware.rb:20:in `call'
230
+ I, [2018-04-25T01:13:21.005144 #95792] INFO -- : Started POST "/mailgun" for 127.0.0.1 at 2018-04-25 01:13:21 +0300
231
+ F, [2018-04-25T01:13:21.006914 #95792] FATAL -- :
232
+ F, [2018-04-25T01:13:21.008123 #95792] FATAL -- : NoMethodError (undefined method `aaaaa' for #<Mailgun::Tracking::Payload:0x007fd8ffb037b0>):
233
+ F, [2018-04-25T01:13:21.008248 #95792] FATAL -- :
234
+ F, [2018-04-25T01:13:21.008302 #95792] FATAL -- : lib/mailgun/tracking/middleware.rb:20:in `call'
235
+ I, [2018-04-25T01:13:21.038503 #95792] INFO -- : Started POST "/mailgun" for 127.0.0.1 at 2018-04-25 01:13:21 +0300
236
+ F, [2018-04-25T01:13:21.039845 #95792] FATAL -- :
237
+ F, [2018-04-25T01:13:21.040729 #95792] FATAL -- : NoMethodError (undefined method `aaaaa' for #<Mailgun::Tracking::Payload:0x007fd900937958>):
238
+ F, [2018-04-25T01:13:21.040800 #95792] FATAL -- :
239
+ F, [2018-04-25T01:13:21.040831 #95792] FATAL -- : lib/mailgun/tracking/middleware.rb:20:in `call'
240
+ I, [2018-04-25T01:17:15.396272 #97683] INFO -- : Started POST "/mailgun" for 127.0.0.1 at 2018-04-25 01:17:15 +0300
241
+ F, [2018-04-25T01:17:15.403730 #97683] FATAL -- :
242
+ F, [2018-04-25T01:17:15.405512 #97683] FATAL -- : NoMethodError (undefined method `aaaaa' for #<Mailgun::Tracking::Payload:0x007fcde4c50d78>):
243
+ F, [2018-04-25T01:17:15.405604 #97683] FATAL -- :
244
+ F, [2018-04-25T01:17:15.405647 #97683] FATAL -- : lib/mailgun/tracking/middleware.rb:20:in `call'
245
+ I, [2018-04-25T01:17:15.445812 #97683] INFO -- : Started POST "/mailgun" for 127.0.0.1 at 2018-04-25 01:17:15 +0300
246
+ F, [2018-04-25T01:17:15.447281 #97683] FATAL -- :
247
+ F, [2018-04-25T01:17:15.448444 #97683] FATAL -- : NoMethodError (undefined method `aaaaa' for #<Mailgun::Tracking::Payload:0x007fcde621f640>):
248
+ F, [2018-04-25T01:17:15.448509 #97683] FATAL -- :
249
+ F, [2018-04-25T01:17:15.448548 #97683] FATAL -- : lib/mailgun/tracking/middleware.rb:20:in `call'
250
+ I, [2018-04-25T01:21:59.959527 #107] INFO -- : Started POST "/mailgun" for 127.0.0.1 at 2018-04-25 01:21:59 +0300
251
+ F, [2018-04-25T01:21:59.960780 #107] FATAL -- :
252
+ F, [2018-04-25T01:21:59.961522 #107] FATAL -- : NoMethodError (undefined method `aaaaa' for #<Mailgun::Tracking::Payload:0x007ff84c37c6d8>):
253
+ F, [2018-04-25T01:21:59.961581 #107] FATAL -- :
254
+ F, [2018-04-25T01:21:59.961614 #107] FATAL -- : lib/mailgun/tracking/middleware.rb:20:in `call'
255
+ I, [2018-04-25T01:21:59.979076 #107] INFO -- : Started POST "/mailgun" for 127.0.0.1 at 2018-04-25 01:21:59 +0300
256
+ F, [2018-04-25T01:21:59.980047 #107] FATAL -- :
257
+ F, [2018-04-25T01:21:59.980745 #107] FATAL -- : NoMethodError (undefined method `aaaaa' for #<Mailgun::Tracking::Payload:0x007ff84bafc2d8>):
258
+ F, [2018-04-25T01:21:59.980776 #107] FATAL -- :
259
+ F, [2018-04-25T01:21:59.980798 #107] FATAL -- : lib/mailgun/tracking/middleware.rb:20:in `call'
260
+ I, [2018-04-25T01:25:18.509356 #1957] INFO -- : Started POST "/mailgun" for 127.0.0.1 at 2018-04-25 01:25:18 +0300
261
+ I, [2018-04-25T01:25:18.512813 #1957] INFO -- : Started POST "/mailgun" for 127.0.0.1 at 2018-04-25 01:25:18 +0300
262
+ I, [2018-04-26T21:42:44.416704 #41944] INFO -- : Started POST "/mailgun" for 127.0.0.1 at 2018-04-26 21:42:44 +0300
263
+ I, [2018-04-26T21:42:44.428936 #41944] INFO -- : Started POST "/mailgun" for 127.0.0.1 at 2018-04-26 21:42:44 +0300
264
+ I, [2018-04-26T22:52:44.142521 #49169] INFO -- : Started POST "/mailgun" for 127.0.0.1 at 2018-04-26 22:52:44 +0300
265
+ I, [2018-04-26T22:52:44.146943 #49169] INFO -- : Started POST "/mailgun" for 127.0.0.1 at 2018-04-26 22:52:44 +0300
@@ -0,0 +1,7 @@
1
+ require 'sinatra/base'
2
+
3
+ module Dummy
4
+ class Application < Sinatra::Base
5
+ use Mailgun::Tracking::Middleware
6
+ end
7
+ end
@@ -0,0 +1,6 @@
1
+ require 'spec_helper'
2
+ require 'dummy/rack/application'
3
+
4
+ RSpec.describe 'Rack', type: :integration do
5
+ it_behaves_like 'acts as rack'
6
+ end
@@ -0,0 +1,6 @@
1
+ require 'spec_helper'
2
+ require 'dummy/rails/application'
3
+
4
+ RSpec.describe 'Rails', type: :integration do
5
+ it_behaves_like 'acts as rack'
6
+ end
@@ -0,0 +1,6 @@
1
+ require 'spec_helper'
2
+ require 'dummy/sinatra/application'
3
+
4
+ RSpec.describe 'Sinatra', type: :integration do
5
+ it_behaves_like 'acts as rack'
6
+ end
@@ -3,45 +3,61 @@ require 'spec_helper'
3
3
  RSpec.describe Mailgun::Tracking::Middleware do
4
4
  subject(:rack) { described_class.new(app) }
5
5
 
6
- describe '#call' do
7
- let(:app) { proc { [200, {}, []] } }
8
- let(:payload) { fixture('delivered.json') }
9
- let(:code) { rack.call(env)[0] }
10
- let(:notifier) { instance_double(Mailgun::Tracking::Notifier) }
11
-
12
- before do
13
- allow(notifier).to receive(:broadcast)
14
- allow(Mailgun::Tracking).to receive(:notifier) { notifier }
15
- end
6
+ let(:app) { proc { [200, {}, []] } }
7
+ let(:notifier) { instance_double(Mailgun::Tracking::Notifier) }
8
+ let(:request) { instance_double(Mailgun::Tracking::Request) }
9
+ let(:env) { env_for('http://localhost:3000') }
10
+ let(:payload) { instance_double(Mailgun::Tracking::Payload) }
16
11
 
17
- context 'when a request to a endpoint with a POST method' do
18
- let(:env) { env_for('http://localhost:3000/mailgun', method: :post, params: payload) }
12
+ before do
13
+ allow(request).to receive(:payload).and_return(payload)
14
+ allow(Mailgun::Tracking).to receive(:notifier).and_return(notifier)
15
+ allow(Mailgun::Tracking::Request).to receive(:new).with(env).and_return(request)
16
+ end
19
17
 
20
- it { expect(code).to eq(200) }
18
+ describe '#call' do
19
+ context 'when request is not respond to the specified URL' do
20
+ before do
21
+ allow(request).to receive(:mailgun_tracking?).and_return(false)
22
+ allow(notifier).to receive(:broadcast)
23
+ end
24
+
25
+ it { expect(rack.call(env)).to include(200) }
21
26
  it do
22
- code
23
- expect(notifier).to have_received(:broadcast).with('delivered', payload)
27
+ rack.call(env)
28
+ expect(Mailgun::Tracking).not_to have_received(:notifier)
24
29
  end
25
30
  end
26
31
 
27
- context 'when a request to a endpoint with a POST method' do
28
- let(:env) { env_for('http://localhost:3000/mailgun', method: :get, params: payload) }
32
+ context 'when request is respond to the specified URL and the signature comparison is unsuccessful' do
33
+ let(:params) { fixture('delivered.json') }
29
34
 
30
- it { expect(code).to eq(200) }
35
+ before do
36
+ allow(notifier).to receive(:broadcast).and_raise(Mailgun::Tracking::InvalidSignature)
37
+ allow(request).to receive(:mailgun_tracking?).and_return(true)
38
+ allow(request).to receive(:params).and_return(params)
39
+ end
40
+
41
+ it { expect(rack.call(env)).to include(400) }
31
42
  it do
32
- code
33
- expect(Mailgun::Tracking).not_to have_received(:notifier)
43
+ rack.call(env)
44
+ expect(Mailgun::Tracking).to have_received(:notifier)
34
45
  end
35
46
  end
36
47
 
37
- context 'when the request is not to the endpoint' do
38
- let(:env) { env_for('http://localhost:3000') }
39
- let(:code) { rack.call(env)[0] }
48
+ context 'when request is respond to the specified URL and the signature comparison is successful' do
49
+ let(:params) { fixture('delivered.json') }
40
50
 
41
- it { expect(code).to eq(200) }
51
+ before do
52
+ allow(request).to receive(:mailgun_tracking?).and_return(true)
53
+ allow(request).to receive(:params).and_return(params)
54
+ allow(notifier).to receive(:broadcast)
55
+ end
56
+
57
+ it { expect(rack.call(env)).to include(200) }
42
58
  it do
43
- code
44
- expect(Mailgun::Tracking).not_to have_received(:notifier)
59
+ rack.call(env)
60
+ expect(Mailgun::Tracking).to have_received(:notifier)
45
61
  end
46
62
  end
47
63
  end
@@ -0,0 +1,40 @@
1
+ require 'spec_helper'
2
+
3
+ RSpec.describe Mailgun::Tracking::Payload do
4
+ subject(:payload) { described_class.new(options) }
5
+
6
+ describe '#[]' do
7
+ let(:options) do
8
+ {
9
+ 'Message-Id' => '<payload@mailgun-tracking.com>'
10
+ }
11
+ end
12
+
13
+ it 'returns the value object from original payload' do
14
+ expect(payload['Message-Id']).to eq(options['Message-Id'])
15
+ end
16
+ end
17
+
18
+ describe '#respond_to?' do
19
+ let(:options) do
20
+ {
21
+ 'Message-Id' => '<payload@mailgun-tracking.com>'
22
+ }
23
+ end
24
+
25
+ it { is_expected.to respond_to(:message_id) }
26
+ it { expect(payload.message_id).to eq(options['Message-Id']) }
27
+ end
28
+
29
+ context 'when the options include a boolean data type' do
30
+ let(:options) do
31
+ {
32
+ boolean: true,
33
+ string: 'string'
34
+ }
35
+ end
36
+
37
+ it { is_expected.to be_boolean }
38
+ it { is_expected.to respond_to(:boolean?) }
39
+ end
40
+ end
@@ -0,0 +1,25 @@
1
+ require 'spec_helper'
2
+
3
+ RSpec.describe Mailgun::Tracking::Request do
4
+ subject(:request) { described_class.new(env) }
5
+
6
+ describe '#mailgun_tracking?' do
7
+ context 'when a request to a endpoint with a POST method' do
8
+ let(:env) { env_for('http://localhost:3000/mailgun', method: :post) }
9
+
10
+ it { is_expected.to be_mailgun_tracking }
11
+ end
12
+
13
+ context 'when a request to a endpoint with a POST method' do
14
+ let(:env) { env_for('http://localhost:3000/mailgun', method: :get) }
15
+
16
+ it { is_expected.not_to be_mailgun_tracking }
17
+ end
18
+
19
+ context 'when the request is not to the endpoint' do
20
+ let(:env) { env_for('http://localhost:3000') }
21
+
22
+ it { is_expected.not_to be_mailgun_tracking }
23
+ end
24
+ end
25
+ end
@@ -3,7 +3,7 @@ require 'spec_helper'
3
3
  RSpec.describe Mailgun::Tracking::Subscriber::AllMessages do
4
4
  subject(:subscriber) { described_class.new(callable) }
5
5
 
6
- it_behaves_like :subscriber
6
+ it_behaves_like 'subscriber'
7
7
 
8
8
  describe '#subscribed_to?' do
9
9
  let(:callable) { proc {} }
@@ -3,7 +3,7 @@ require 'spec_helper'
3
3
  RSpec.describe Mailgun::Tracking::Subscriber::Evented do
4
4
  subject(:subscriber) { described_class.new('delivered', callable) }
5
5
 
6
- it_behaves_like :subscriber
6
+ it_behaves_like 'subscriber'
7
7
 
8
8
  describe '#subscribed_to?' do
9
9
  let(:callable) { proc {} }
@@ -0,0 +1,155 @@
1
+ require 'spec_helper'
2
+
3
+ RSpec.describe Mailgun::Tracking::Util do
4
+ describe '.normalize' do
5
+ context 'when the keys of the object are strings' do
6
+ let(:object) do
7
+ { 'a' => 1, 'b' => 2 }
8
+ end
9
+
10
+ it 'returns normalized object' do
11
+ expect(described_class.normalize(object)).to eq(a: 1, b: 2)
12
+ end
13
+ end
14
+
15
+ context 'when the object has deep string keys' do
16
+ let(:object) do
17
+ { 'a' => { 'b' => { 'c' => 3 } } }
18
+ end
19
+
20
+ it 'returns normalized object' do
21
+ expect(described_class.normalize(object)).to eq(a: { b: { c: 3 } })
22
+ end
23
+ end
24
+
25
+ context 'when the keys of the object are symbols' do
26
+ let(:object) do
27
+ { a: 1, b: 2 }
28
+ end
29
+
30
+ it 'returns normalized object' do
31
+ expect(described_class.normalize(object)).to eq(object)
32
+ end
33
+ end
34
+
35
+ context 'when an object has deep symbol keys' do
36
+ let(:object) do
37
+ { a: { b: { c: 3 } } }
38
+ end
39
+
40
+ it 'returns normalized object' do
41
+ expect(described_class.normalize(object)).to eq(object)
42
+ end
43
+ end
44
+
45
+ context 'when the keys of the object are mixed' do
46
+ let(:object) do
47
+ { :a => 1, 'b' => 2 }
48
+ end
49
+
50
+ it 'returns normalized object' do
51
+ expect(described_class.normalize(object)).to eq(a: 1, b: 2)
52
+ end
53
+ end
54
+
55
+ context 'when the keys of the object are integers' do
56
+ let(:object) do
57
+ { 0 => 1, 1 => 2 }
58
+ end
59
+
60
+ it 'returns normalized object' do
61
+ expect(described_class.normalize(object)).to eq(0 => 1, 1 => 2)
62
+ end
63
+ end
64
+
65
+ context 'when an object has deep integer keys' do
66
+ let(:object) do
67
+ { 0 => { 1 => { 2 => 3 } } }
68
+ end
69
+
70
+ it 'returns normalized object' do
71
+ expect(described_class.normalize(object)).to eq(0 => { 1 => { 2 => 3 } })
72
+ end
73
+ end
74
+
75
+ context 'when the key of the object is illegal symbol' do
76
+ let(:object) do
77
+ { [] => 3 }
78
+ end
79
+
80
+ it 'returns normalized object' do
81
+ expect(described_class.normalize(object)).to eq([] => 3)
82
+ end
83
+ end
84
+
85
+ context 'when an object has deep illegal symbol keys' do
86
+ let(:object) do
87
+ { [] => { [] => 3 } }
88
+ end
89
+
90
+ it 'returns normalized object' do
91
+ expect(described_class.normalize(object)).to eq([] => { [] => 3 })
92
+ end
93
+ end
94
+
95
+ context 'when the keys of the object are upcase strings' do
96
+ let(:object) do
97
+ { 'A' => 1, 'B' => 2 }
98
+ end
99
+
100
+ it 'returns normalized object' do
101
+ expect(described_class.normalize(object)).to eq(a: 1, b: 2)
102
+ end
103
+ end
104
+
105
+ context 'when an object has deep upcase string keys' do
106
+ let(:object) do
107
+ { 'A' => { 'B' => { 'C' => 3 } } }
108
+ end
109
+
110
+ it 'returns normalized object' do
111
+ expect(described_class.normalize(object)).to eq(a: { b: { c: 3 } })
112
+ end
113
+ end
114
+
115
+ context 'when the object value is an array of stringified hashes' do
116
+ let(:object) do
117
+ { 'a' => [{ 'b' => 2 }, { 'c' => 3 }, 4] }
118
+ end
119
+
120
+ it 'returns normalized object' do
121
+ expect(described_class.normalize(object)).to eq(a: [{ b: 2 }, { c: 3 }, 4])
122
+ end
123
+ end
124
+
125
+ context 'when the object value is an array of symbolized hashes' do
126
+ let(:object) do
127
+ { a: [{ b: 2 }, { c: 3 }, 4] }
128
+ end
129
+
130
+ it 'returns normalized object' do
131
+ expect(described_class.normalize(object)).to eq(object)
132
+ end
133
+ end
134
+
135
+ context 'when the object value is an array of mixed hashes' do
136
+ let(:object) do
137
+ { a: [{ b: 2 }, { 'c' => 3 }, 4] }
138
+ end
139
+
140
+ it 'returns normalized object' do
141
+ expect(described_class.normalize(object)).to eq(a: [{ b: 2 }, { c: 3 }, 4])
142
+ end
143
+ end
144
+
145
+ context 'when the object value is an array of upcased hashes' do
146
+ let(:object) do
147
+ { 'A' => [{ 'B' => 2 }, { 'C' => 3 }, 4] }
148
+ end
149
+
150
+ it 'returns normalized object' do
151
+ expect(described_class.normalize(object)).to eq(a: [{ b: 2 }, { c: 3 }, 4])
152
+ end
153
+ end
154
+ end
155
+ end
@@ -1,16 +1,12 @@
1
- require 'rack'
2
- require 'simplecov'
1
+ require 'rack/test'
3
2
  require 'bundler/setup'
4
3
  require 'mailgun/tracking'
5
4
 
6
- require_relative 'support/fixture'
7
- require_relative 'support/rack_helpers'
8
- require_relative 'support/shared_examples/subscriber'
9
-
10
- SimpleCov.start
5
+ Dir.glob(File.expand_path('support/**/*.rb', __dir__), &method(:require))
11
6
 
12
7
  RSpec.configure do |config|
13
8
  config.include(RackHelpers)
9
+ config.include(Rack::Test::Methods, type: :integration)
14
10
 
15
11
  config.before do
16
12
  Mailgun::Tracking.configure do |c|
@@ -0,0 +1,36 @@
1
+ class Delivered
2
+ def call(payload); end
3
+ end
4
+
5
+ RSpec.shared_examples 'acts as rack' do
6
+ let(:app) { Dummy::Application }
7
+ let(:payload) { fixture('delivered.json') }
8
+ let(:delivered) { instance_double(Delivered) }
9
+
10
+ before do
11
+ allow(delivered).to receive(:call)
12
+ allow(Delivered).to receive(:new).and_return(delivered)
13
+
14
+ Mailgun::Tracking.notifier.subscribe(:delivered, Delivered.new)
15
+
16
+ Mailgun::Tracking.notifier.subscribe :bounced do |payload|
17
+ Delivered.new.call(payload)
18
+ end
19
+
20
+ Mailgun::Tracking.notifier.all(Delivered.new)
21
+ end
22
+
23
+ it do
24
+ post('/mailgun', payload)
25
+ expect(delivered).to have_received(:call).with(instance_of(Mailgun::Tracking::Payload)).twice
26
+ end
27
+
28
+ context 'when the signature comparison is unsuccessful' do
29
+ before { payload['timestamp'] = '' }
30
+
31
+ it do
32
+ post('/mailgun', payload)
33
+ expect(last_response).to be_bad_request
34
+ end
35
+ end
36
+ end
@@ -1,4 +1,4 @@
1
- RSpec.shared_examples :subscriber do
1
+ RSpec.shared_examples 'subscriber' do
2
2
  describe '#call' do
3
3
  let(:callable) { proc {} }
4
4
  let(:payload) { fixture('delivered.json') }
@@ -0,0 +1,5 @@
1
+ require 'simplecov'
2
+
3
+ SimpleCov.start do
4
+ add_filter('integration')
5
+ end
metadata CHANGED
@@ -1,15 +1,153 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: mailgun-tracking
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.4
4
+ version: 0.3.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: 2018-03-07 00:00:00.000000000 Z
12
- dependencies: []
11
+ date: 2018-05-11 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: appraisal
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '2.2'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '2.2'
27
+ - !ruby/object:Gem::Dependency
28
+ name: bundler
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '1.16'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '1.16'
41
+ - !ruby/object:Gem::Dependency
42
+ name: codeclimate-test-reporter
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '1.0'
48
+ - - ">="
49
+ - !ruby/object:Gem::Version
50
+ version: 1.0.8
51
+ type: :development
52
+ prerelease: false
53
+ version_requirements: !ruby/object:Gem::Requirement
54
+ requirements:
55
+ - - "~>"
56
+ - !ruby/object:Gem::Version
57
+ version: '1.0'
58
+ - - ">="
59
+ - !ruby/object:Gem::Version
60
+ version: 1.0.8
61
+ - !ruby/object:Gem::Dependency
62
+ name: rack-test
63
+ requirement: !ruby/object:Gem::Requirement
64
+ requirements:
65
+ - - "~>"
66
+ - !ruby/object:Gem::Version
67
+ version: '0'
68
+ type: :development
69
+ prerelease: false
70
+ version_requirements: !ruby/object:Gem::Requirement
71
+ requirements:
72
+ - - "~>"
73
+ - !ruby/object:Gem::Version
74
+ version: '0'
75
+ - !ruby/object:Gem::Dependency
76
+ name: rake
77
+ requirement: !ruby/object:Gem::Requirement
78
+ requirements:
79
+ - - "~>"
80
+ - !ruby/object:Gem::Version
81
+ version: '10.0'
82
+ type: :development
83
+ prerelease: false
84
+ version_requirements: !ruby/object:Gem::Requirement
85
+ requirements:
86
+ - - "~>"
87
+ - !ruby/object:Gem::Version
88
+ version: '10.0'
89
+ - !ruby/object:Gem::Dependency
90
+ name: rspec
91
+ requirement: !ruby/object:Gem::Requirement
92
+ requirements:
93
+ - - "~>"
94
+ - !ruby/object:Gem::Version
95
+ version: '3.7'
96
+ type: :development
97
+ prerelease: false
98
+ version_requirements: !ruby/object:Gem::Requirement
99
+ requirements:
100
+ - - "~>"
101
+ - !ruby/object:Gem::Version
102
+ version: '3.7'
103
+ - !ruby/object:Gem::Dependency
104
+ name: rubocop
105
+ requirement: !ruby/object:Gem::Requirement
106
+ requirements:
107
+ - - "~>"
108
+ - !ruby/object:Gem::Version
109
+ version: 0.55.0
110
+ type: :development
111
+ prerelease: false
112
+ version_requirements: !ruby/object:Gem::Requirement
113
+ requirements:
114
+ - - "~>"
115
+ - !ruby/object:Gem::Version
116
+ version: 0.55.0
117
+ - !ruby/object:Gem::Dependency
118
+ name: rubocop-rspec
119
+ requirement: !ruby/object:Gem::Requirement
120
+ requirements:
121
+ - - "~>"
122
+ - !ruby/object:Gem::Version
123
+ version: '1.25'
124
+ - - ">="
125
+ - !ruby/object:Gem::Version
126
+ version: 1.25.1
127
+ type: :development
128
+ prerelease: false
129
+ version_requirements: !ruby/object:Gem::Requirement
130
+ requirements:
131
+ - - "~>"
132
+ - !ruby/object:Gem::Version
133
+ version: '1.25'
134
+ - - ">="
135
+ - !ruby/object:Gem::Version
136
+ version: 1.25.1
137
+ - !ruby/object:Gem::Dependency
138
+ name: simplecov
139
+ requirement: !ruby/object:Gem::Requirement
140
+ requirements:
141
+ - - "~>"
142
+ - !ruby/object:Gem::Version
143
+ version: 0.12.0
144
+ type: :development
145
+ prerelease: false
146
+ version_requirements: !ruby/object:Gem::Requirement
147
+ requirements:
148
+ - - "~>"
149
+ - !ruby/object:Gem::Version
150
+ version: 0.12.0
13
151
  description: Integration with Mailgun Webhooks
14
152
  email:
15
153
  - artem.chubchenko@gmail.com
@@ -25,27 +163,42 @@ files:
25
163
  - lib/mailgun/tracking/listener.rb
26
164
  - lib/mailgun/tracking/middleware.rb
27
165
  - lib/mailgun/tracking/notifier.rb
166
+ - lib/mailgun/tracking/payload.rb
28
167
  - lib/mailgun/tracking/railtie.rb
168
+ - lib/mailgun/tracking/request.rb
29
169
  - lib/mailgun/tracking/signature.rb
30
170
  - lib/mailgun/tracking/subscriber.rb
31
171
  - lib/mailgun/tracking/subscriber/all_messages.rb
32
172
  - lib/mailgun/tracking/subscriber/evented.rb
173
+ - lib/mailgun/tracking/util.rb
33
174
  - lib/mailgun/tracking/version.rb
175
+ - spec/dummy/rack/application.rb
176
+ - spec/dummy/rails/application.rb
177
+ - spec/dummy/rails/logs/test.log
178
+ - spec/dummy/sinatra/application.rb
34
179
  - spec/fixtures/delivered.json
180
+ - spec/integration/rack/rack_spec.rb
181
+ - spec/integration/rails/rails_spec.rb
182
+ - spec/integration/sinatra/sinatra_spec.rb
35
183
  - spec/mailgun/tracking/configuration_spec.rb
36
184
  - spec/mailgun/tracking/listener_spec.rb
37
185
  - spec/mailgun/tracking/middleware_spec.rb
38
186
  - spec/mailgun/tracking/notifier_spec.rb
187
+ - spec/mailgun/tracking/payload_spec.rb
188
+ - spec/mailgun/tracking/request_spec.rb
39
189
  - spec/mailgun/tracking/signature_spec.rb
40
190
  - spec/mailgun/tracking/subscriber/all_messages_spec.rb
41
191
  - spec/mailgun/tracking/subscriber/evented_spec.rb
42
192
  - spec/mailgun/tracking/subscriber_spec.rb
193
+ - spec/mailgun/tracking/util_spec.rb
43
194
  - spec/mailgun/tracking/version_spec.rb
44
195
  - spec/mailgun/tracking_spec.rb
45
196
  - spec/spec_helper.rb
46
197
  - spec/support/fixture.rb
47
198
  - spec/support/rack_helpers.rb
199
+ - spec/support/shared_examples/integration/acts_as_rack.rb
48
200
  - spec/support/shared_examples/subscriber.rb
201
+ - spec/support/simplecov.rb
49
202
  homepage: https://github.com/chubchenko/mailgun-tracking
50
203
  licenses:
51
204
  - MIT
@@ -58,7 +211,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
58
211
  requirements:
59
212
  - - ">="
60
213
  - !ruby/object:Gem::Version
61
- version: 2.1.0
214
+ version: 2.2.0
62
215
  required_rubygems_version: !ruby/object:Gem::Requirement
63
216
  requirements:
64
217
  - - ">="
@@ -66,14 +219,23 @@ required_rubygems_version: !ruby/object:Gem::Requirement
66
219
  version: '0'
67
220
  requirements: []
68
221
  rubyforge_project:
69
- rubygems_version: 2.6.14
222
+ rubygems_version: 2.6.12
70
223
  signing_key:
71
224
  specification_version: 4
72
225
  summary: Integration with Mailgun Webhooks
73
226
  test_files:
74
227
  - spec/spec_helper.rb
228
+ - spec/dummy/sinatra/application.rb
229
+ - spec/dummy/rack/application.rb
230
+ - spec/dummy/rails/application.rb
231
+ - spec/dummy/rails/logs/test.log
232
+ - spec/integration/sinatra/sinatra_spec.rb
233
+ - spec/integration/rack/rack_spec.rb
234
+ - spec/integration/rails/rails_spec.rb
235
+ - spec/support/simplecov.rb
75
236
  - spec/support/rack_helpers.rb
76
237
  - spec/support/fixture.rb
238
+ - spec/support/shared_examples/integration/acts_as_rack.rb
77
239
  - spec/support/shared_examples/subscriber.rb
78
240
  - spec/fixtures/delivered.json
79
241
  - spec/mailgun/tracking_spec.rb
@@ -83,6 +245,9 @@ test_files:
83
245
  - spec/mailgun/tracking/notifier_spec.rb
84
246
  - spec/mailgun/tracking/subscriber_spec.rb
85
247
  - spec/mailgun/tracking/middleware_spec.rb
248
+ - spec/mailgun/tracking/util_spec.rb
86
249
  - spec/mailgun/tracking/listener_spec.rb
250
+ - spec/mailgun/tracking/payload_spec.rb
251
+ - spec/mailgun/tracking/request_spec.rb
87
252
  - spec/mailgun/tracking/subscriber/evented_spec.rb
88
253
  - spec/mailgun/tracking/subscriber/all_messages_spec.rb