mailgun-tracking 1.0.0 → 1.1.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 21d2fa7599f08ae635591938264cdfdd0dadf64e2baed939ef236e5dead989a2
4
- data.tar.gz: a6d7f4a3f6d1c87c08d14467608a02141dd40906d1b5172049662e8ae3ece203
3
+ metadata.gz: e61daca288034107cca6ca891a80fa601016a555fb1fb2d07ab9b9755d52a12e
4
+ data.tar.gz: 6bc9cac63844b3190418dbf6b2fa14964bfbe372bf6eb23ef55ea6d6aaf8b739
5
5
  SHA512:
6
- metadata.gz: 8238ebe57aabc593f7810d20a44fe2c3b8c3440aefcf07fb5a564d093304d1d37874e04dc22346d2dda996c4a9cac3596d4cf0f71af0aa4fd8f0bf5d256465cb
7
- data.tar.gz: b90c4aacd8d8f8cc6ad70482eae5e2e23d2fe288fc77b7d259f30ed279214efd4e7d0c691a85d4de34344cb22812913bd9b3bc51d62897880d520e5252acce08
6
+ metadata.gz: 6de25bb55ff82c27c8420111acd1c72d4ee390ead819abc2631b1196e6d37ed62637023ed5048287f0ab399b23d1b942b626d8de1c4c9c58e7d3b2cc69b94ad0
7
+ data.tar.gz: dcd30f8087f1fd233b33a20d843ef1517ce1678d51b79bd8570574dabca01ab8963f944501f3e3e3cff1a6f268b1f37329112e7c3392cef3e516bff2fbc7cd09
@@ -4,7 +4,7 @@ module Mailgun
4
4
  module Tracking
5
5
  # Creates the Mailgun Tracking initializer file for Rails apps.
6
6
  #
7
- # @example Invokation from terminal
7
+ # @example Invocation from terminal
8
8
  # rails generate mailgun:tracking:install API_KEY ENDPOINT
9
9
  class InstallGenerator < Rails::Generators::Base
10
10
  source_root File.expand_path('templates', __dir__)
@@ -6,6 +6,7 @@ require 'mailgun/tracking/listener'
6
6
  require 'mailgun/tracking/middleware'
7
7
  require 'mailgun/tracking/notifier'
8
8
  require 'mailgun/tracking/payload'
9
+ require 'mailgun/tracking/payload/legacy'
9
10
  require 'mailgun/tracking/signature'
10
11
  require 'mailgun/tracking/subscriber'
11
12
  require 'mailgun/tracking/util'
@@ -27,6 +27,7 @@ module Mailgun
27
27
  # @return [Array(Numeric,Hash,Array)] The Rack-style response.
28
28
  def call!(env)
29
29
  @request = Request.new(env)
30
+
30
31
  return @app.call(env) unless @request.mailgun_tracking?
31
32
 
32
33
  handle_event
@@ -45,7 +46,7 @@ module Mailgun
45
46
  end
46
47
 
47
48
  def handle_event
48
- Mailgun::Tracking.notifier.broadcast(@request.params.fetch('event'), @request.payload)
49
+ Mailgun::Tracking.notifier.broadcast(@request.payload.event, @request.payload)
49
50
  null_response
50
51
  rescue InvalidSignature
51
52
  bad_request
@@ -49,7 +49,7 @@ module Mailgun
49
49
  # @return [NilClass]
50
50
  def broadcast(event, payload)
51
51
  Signature.verify!(payload)
52
- listener.broadcast(event, payload)
52
+ listener.broadcast(event, payload.body)
53
53
  end
54
54
 
55
55
  private
@@ -1,50 +1,43 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'set'
3
+ require_relative 'payload/legacy'
4
4
 
5
5
  module Mailgun
6
6
  module Tracking
7
7
  # Payload object.
8
8
  class Payload
9
- # Initializes a new Payload object.
10
- #
11
- # @param options [Hash]
12
- #
13
- # @return [Mailgun::Tracking::Payload]
14
9
  def initialize(options = {})
15
- @options = Util.normalize(options)
16
- @original = options
17
- define_instance_methods(Set.new(@options.keys), @options)
10
+ @options = options
18
11
  end
19
12
 
20
- # Returns a value of the original payload with the given key.
21
- #
22
- # @param key [String]
23
- #
24
- # @return a value of the original payload.
25
- def [](key)
26
- @original[key]
13
+ def body
14
+ @options
27
15
  end
28
16
 
29
- private
17
+ def event
18
+ @event ||= __event_data.fetch('event')
19
+ end
30
20
 
31
- # @return [Class]
32
- def __metaclass__
33
- class << self
34
- self
35
- end
21
+ def token
22
+ @token ||= __signature.fetch('token')
36
23
  end
37
24
 
38
- # @return [void]
39
- def define_instance_methods(keys, options)
40
- __metaclass__.instance_eval do
41
- keys.each do |key|
42
- define_method(key) { @options[key] }
43
- next unless [FalseClass, TrueClass].include?(options[key].class)
25
+ def timestamp
26
+ @timestamp ||= __signature.fetch('timestamp')
27
+ end
28
+
29
+ def signature
30
+ @signature ||= __signature.fetch('signature')
31
+ end
32
+
33
+ private
34
+
35
+ def __signature
36
+ @__signature ||= @options.fetch('signature')
37
+ end
44
38
 
45
- define_method(:"#{key}?") { @options[key] }
46
- end
47
- end
39
+ def __event_data
40
+ @__event_data ||= @options.fetch('event-data')
48
41
  end
49
42
  end
50
43
  end
@@ -0,0 +1,38 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Mailgun
4
+ module Tracking
5
+ class Payload
6
+ # Legacy payload object.
7
+ class Legacy
8
+ def initialize(options = {})
9
+ @options = options
10
+ warn(<<~DEPRECATION)
11
+ [Mailgun::Tracking] The Legacy class refers to a previous version of the API
12
+ which is deprecated and it will be removed in the next major version.
13
+ DEPRECATION
14
+ end
15
+
16
+ def body
17
+ @options
18
+ end
19
+
20
+ def event
21
+ @event ||= @options.fetch('event')
22
+ end
23
+
24
+ def token
25
+ @token ||= @options.fetch('token')
26
+ end
27
+
28
+ def timestamp
29
+ @timestamp ||= @options.fetch('timestamp')
30
+ end
31
+
32
+ def signature
33
+ @signature ||= @options.fetch('signature')
34
+ end
35
+ end
36
+ end
37
+ end
38
+ end
@@ -15,10 +15,38 @@ module Mailgun
15
15
  path == Configuration.instance.endpoint
16
16
  end
17
17
 
18
- # @return [Mailgun::Tracking::Payload]
18
+ # @return [Mailgun::Tracking::Payload, Mailgun::Tracking::Payload::Legacy]
19
19
  def payload
20
- @payload ||= Payload.new(params)
20
+ @payload ||= begin
21
+ if params.key?('timestamp')
22
+ ::Mailgun::Tracking::Payload::Legacy.new(params)
23
+ else
24
+ ::Mailgun::Tracking::Payload.new(params)
25
+ end
26
+ end
21
27
  end
28
+
29
+ # A Mailgun::Tracking::Request::JSON is used to parsing JSON requests.
30
+ module JSON
31
+ APPLICATION_JSON = 'application/json'
32
+ FORM_HASH = 'rack.request.form_hash'
33
+ FORM_INPUT = 'rack.request.form_input'
34
+
35
+ # Returns the data received in the request body.
36
+ #
37
+ # @return [Hash]
38
+ def POST
39
+ return super unless media_type == APPLICATION_JSON
40
+
41
+ body = self.body.read
42
+ self.body.rewind
43
+ env.update(FORM_HASH => ::JSON.parse(body), FORM_INPUT => body)
44
+
45
+ get_header(FORM_HASH)
46
+ end
47
+ end
48
+
49
+ include JSON
22
50
  end
23
51
  end
24
52
  end
@@ -26,14 +26,12 @@ module Mailgun
26
26
  #
27
27
  # @return [Mailgun::Tracking::Signature]
28
28
  def initialize(payload)
29
- @token = payload['token']
30
- @timestamp = payload['timestamp']
31
- @signature = payload['signature']
29
+ @payload = payload
32
30
  end
33
31
 
34
32
  # @return [Boolean]
35
33
  def valid?
36
- @signature == OpenSSL::HMAC.hexdigest(digest, Configuration.instance.api_key, data)
34
+ @payload.signature == OpenSSL::HMAC.hexdigest(digest, Configuration.instance.api_key, data)
37
35
  end
38
36
 
39
37
  private
@@ -47,7 +45,7 @@ module Mailgun
47
45
  #
48
46
  # @return [String]
49
47
  def data
50
- [@timestamp, @token].join
48
+ [@payload.timestamp, @payload.token].join
51
49
  end
52
50
  end
53
51
  end
@@ -19,7 +19,7 @@ module Mailgun
19
19
  #
20
20
  # @return [Integer]
21
21
  def minor
22
- 0
22
+ 1
23
23
  end
24
24
 
25
25
  # Patch version.
@@ -36,3 +36,18 @@ SystemExit (exit):
36
36
  lib/mailgun/tracking/middleware.rb:29:in `_call'
37
37
  lib/mailgun/tracking/middleware.rb:22:in `call'
38
38
  I, [2019-10-16T17:18:16.198543 #12320] INFO -- : Started POST "/mailgun" for 127.0.0.1 at 2019-10-16 17:18:16 +0300
39
+ I, [2019-11-07T18:53:57.134697 #53967] INFO -- : Started POST "/mailgun" for 127.0.0.1 at 2019-11-07 18:53:57 +0200
40
+ I, [2019-11-07T18:53:57.158453 #53967] INFO -- : Started POST "/mailgun" for 127.0.0.1 at 2019-11-07 18:53:57 +0200
41
+ F, [2019-11-07T18:53:57.160416 #53967] FATAL -- :
42
+ KeyError (key not found: "event"):
43
+ lib/mailgun/tracking/payload/legacy.rb:17:in `fetch'
44
+ lib/mailgun/tracking/payload/legacy.rb:17:in `event'
45
+ lib/mailgun/tracking/middleware.rb:60:in `handle_event'
46
+ lib/mailgun/tracking/middleware.rb:43:in `call!'
47
+ lib/mailgun/tracking/middleware.rb:20:in `call'
48
+
49
+
50
+ I, [2019-11-07T18:55:50.036561 #53989] INFO -- : Started POST "/mailgun" for 127.0.0.1 at 2019-11-07 18:55:50 +0200
51
+ I, [2019-11-07T18:55:50.076942 #53989] INFO -- : Started POST "/mailgun" for 127.0.0.1 at 2019-11-07 18:55:50 +0200
52
+ I, [2019-11-07T18:56:17.648709 #53999] INFO -- : Started POST "/mailgun" for 127.0.0.1 at 2019-11-07 18:56:17 +0200
53
+ I, [2019-11-07T18:56:17.662346 #53999] INFO -- : Started POST "/mailgun" for 127.0.0.1 at 2019-11-07 18:56:17 +0200
@@ -1,8 +1,65 @@
1
1
  {
2
- "domain": "mail.example.com",
3
- "Message-Id": "<20160329071939.35138.9413.6915422C@mail.example.com>",
4
- "event": "delivered",
5
- "timestamp": "1499697910",
6
- "token": "b5751a49a024483da8d41c3684f98b8f",
7
- "signature": "374e0b1a3deeb57318c783d43ff71093fbf26406a452761dab91bf346a93b49e"
2
+ "signature": {
3
+ "timestamp": "1572632560",
4
+ "token": "e71ad7ff8d6f43b62d31615083bde85fb55e4e2b5121cb1239",
5
+ "signature": "9d21d1689889ec5f4ffa3c7e5e6598c8450c3eada8f6cc03e47b2342a9c9da61"
6
+ },
7
+ "event-data": {
8
+ "tags": [
9
+ "my_tag_1",
10
+ "my_tag_2"
11
+ ],
12
+ "timestamp": 1521472262.908181,
13
+ "storage": {
14
+ "url": "https://se.api.mailgun.net/v3/domains/sandboxfb0641fa1b904bb28ba00cba62dca7f1.mailgun.org/messages/message_key",
15
+ "key": "message_key"
16
+ },
17
+ "envelope": {
18
+ "sending-ip": "209.61.154.250",
19
+ "sender": "bob@sandboxfb0641fa1b904bb28ba00cba62dca7f1.mailgun.org",
20
+ "transport": "smtp",
21
+ "targets": "alice@example.com"
22
+ },
23
+ "recipient-domain": "example.com",
24
+ "id": "CPgfbmQMTCKtHW6uIWtuVe",
25
+ "campaigns": [
26
+
27
+ ],
28
+ "user-variables": {
29
+ "my_var_1": "Mailgun Variable #1",
30
+ "my-var-2": "awesome"
31
+ },
32
+ "flags": {
33
+ "is-routed": false,
34
+ "is-authenticated": true,
35
+ "is-system-test": false,
36
+ "is-test-mode": false
37
+ },
38
+ "log-level": "info",
39
+ "message": {
40
+ "headers": {
41
+ "to": "Alice <alice@example.com>",
42
+ "message-id": "20130503182626.18666.16540@sandboxfb0641fa1b904bb28ba00cba62dca7f1.mailgun.org",
43
+ "from": "Bob <bob@sandboxfb0641fa1b904bb28ba00cba62dca7f1.mailgun.org>",
44
+ "subject": "Test delivered webhook"
45
+ },
46
+ "attachments": [
47
+
48
+ ],
49
+ "size": 111
50
+ },
51
+ "recipient": "alice@example.com",
52
+ "event": "delivered",
53
+ "delivery-status": {
54
+ "tls": true,
55
+ "mx-host": "smtp-in.example.com",
56
+ "attempt-no": 1,
57
+ "description": "",
58
+ "session-seconds": 0.4331989288330078,
59
+ "utf8": true,
60
+ "code": 250,
61
+ "message": "OK",
62
+ "certificate-verified": true
63
+ }
64
+ }
8
65
  }
@@ -0,0 +1,13 @@
1
+ {
2
+ "timestamp": "1499697910",
3
+ "token": "b5751a49a024483da8d41c3684f98b8f",
4
+ "signature": "374e0b1a3deeb57318c783d43ff71093fbf26406a452761dab91bf346a93b49e",
5
+ "domain": "mail.example.com",
6
+ "my_var_1": "Mailgun Variable #1",
7
+ "my-var-2": "awesome",
8
+ "message-headers": "[[\"Received\", \"by luna.mailgun.net with SMTP mgrt 8734663311733; Fri, 03 May 2013 18:26:27 +0000\"], [\"Content-Type\", [\"multipart/alternative\", {\"boundary\": \"eb663d73ae0a4d6c9153cc0aec8b7520\"}]], [\"Mime-Version\", \"1.0\"], [\"Subject\", \"Test deliver webhook\"], [\"From\", \"Bob <bob@sandboxfb0641fa1b904bb28ba00cba62dca7f1.mailgun.org>\"], [\"To\", \"Alice <alice@example.com>\"], [\"Message-Id\", \"<20130503182626.18666.16540@sandboxfb0641fa1b904bb28ba00cba62dca7f1.mailgun.org>\"], [\"X-Mailgun-Variables\", \"{\\\"my_var_1\\\": \\\"Mailgun Variable #1\\\", \\\"my-var-2\\\": \\\"awesome\\\"}\"], [\"Date\", \"Fri, 03 May 2013 18:26:27 +0000\"], [\"Sender\", \"bob@sandboxfb0641fa1b904bb28ba00cba62dca7f1.mailgun.org\"]]",
9
+ "Message-Id": "<20160329071939.35138.9413.6915422C@mail.example.com>",
10
+ "recipient": "alice@example.com",
11
+ "event": "delivered",
12
+ "body-plain": ""
13
+ }
@@ -24,7 +24,7 @@ RSpec.describe Mailgun::Tracking::Listener do
24
24
  end
25
25
 
26
26
  describe '#broadcast' do
27
- let(:payload) { fixture('delivered.json') }
27
+ let(:payload) { fixture('legacy/delivered.json') }
28
28
 
29
29
  before do
30
30
  allow(subscriber).to receive(:call)
@@ -5,12 +5,13 @@ RSpec.describe Mailgun::Tracking::Middleware do
5
5
 
6
6
  let(:app) { proc { [200, {}, []] } }
7
7
  let(:notifier) { instance_double(Mailgun::Tracking::Notifier) }
8
- let(:request) { instance_double(Mailgun::Tracking::Request) }
8
+ let(:request) do
9
+ instance_double(Mailgun::Tracking::Request, payload: payload, media_type: 'application/x-www-form-urlencoded')
10
+ end
9
11
  let(:env) { env_for('http://localhost:3000') }
10
- let(:payload) { instance_double(Mailgun::Tracking::Payload) }
12
+ let(:payload) { instance_double(Mailgun::Tracking::Payload::Legacy, event: 'delivered') }
11
13
 
12
14
  before do
13
- allow(request).to receive(:payload).and_return(payload)
14
15
  allow(Mailgun::Tracking).to receive(:notifier).and_return(notifier)
15
16
  allow(Mailgun::Tracking::Request).to receive(:new).with(env).and_return(request)
16
17
  end
@@ -31,7 +32,7 @@ RSpec.describe Mailgun::Tracking::Middleware do
31
32
  end
32
33
 
33
34
  context 'when request is respond to the specified URL and the signature comparison is unsuccessful' do
34
- let(:params) { fixture('delivered.json') }
35
+ let(:params) { fixture('legacy/delivered.json') }
35
36
 
36
37
  before do
37
38
  allow(notifier).to receive(:broadcast).and_raise(Mailgun::Tracking::InvalidSignature)
@@ -48,7 +49,7 @@ RSpec.describe Mailgun::Tracking::Middleware do
48
49
  end
49
50
 
50
51
  context 'when request is respond to the specified URL and the signature comparison is successful' do
51
- let(:params) { fixture('delivered.json') }
52
+ let(:params) { fixture('legacy/delivered.json') }
52
53
 
53
54
  before do
54
55
  allow(request).to receive(:mailgun_tracking?).and_return(true)
@@ -47,7 +47,7 @@ RSpec.describe Mailgun::Tracking::Notifier do
47
47
  end
48
48
 
49
49
  describe '#broadcast' do
50
- let(:payload) { fixture('delivered.json') }
50
+ let(:payload) { instance_double(Mailgun::Tracking::Payload, body: fixture('legacy/delivered.json')) }
51
51
 
52
52
  before do
53
53
  allow(Mailgun::Tracking::Signature).to receive(:verify!)
@@ -60,7 +60,7 @@ RSpec.describe Mailgun::Tracking::Notifier do
60
60
  end
61
61
 
62
62
  it 'broadcasts an event' do
63
- expect(listener).to have_received(:broadcast).with(:delivered, payload)
63
+ expect(listener).to have_received(:broadcast).with(:delivered, fixture('legacy/delivered.json'))
64
64
  end
65
65
  end
66
66
  end
@@ -0,0 +1,37 @@
1
+ # frozen_string_literal: true
2
+
3
+ RSpec.describe Mailgun::Tracking::Payload::Legacy do
4
+ subject(:legacy) { described_class.new(options) }
5
+
6
+ let(:options) { fixture('legacy/delivered.json') }
7
+
8
+ describe '#body' do
9
+ it 'returns body' do
10
+ expect(legacy.body).to eq(options)
11
+ end
12
+ end
13
+
14
+ describe '#event' do
15
+ it 'returns event' do
16
+ expect(legacy.event).to eq(options.fetch('event'))
17
+ end
18
+ end
19
+
20
+ describe '#token' do
21
+ it 'returns token' do
22
+ expect(legacy.token).to eq(options.fetch('token'))
23
+ end
24
+ end
25
+
26
+ describe '#timestamp' do
27
+ it 'returns timestamp' do
28
+ expect(legacy.timestamp).to eq(options.fetch('timestamp'))
29
+ end
30
+ end
31
+
32
+ describe '#signature' do
33
+ it 'returns signature' do
34
+ expect(legacy.signature).to eq(options.fetch('signature'))
35
+ end
36
+ end
37
+ end
@@ -3,38 +3,35 @@
3
3
  RSpec.describe Mailgun::Tracking::Payload do
4
4
  subject(:payload) { described_class.new(options) }
5
5
 
6
- describe '#[]' do
7
- let(:options) do
8
- {
9
- 'Message-Id' => '<payload@mailgun-tracking.com>'
10
- }
11
- end
6
+ let(:options) { fixture('delivered.json') }
12
7
 
13
- it 'returns the value object from original payload' do
14
- expect(payload['Message-Id']).to eq(options['Message-Id'])
8
+ describe '#body' do
9
+ it 'returns body' do
10
+ expect(payload.body).to eq(options)
15
11
  end
16
12
  end
17
13
 
18
- describe '#respond_to?' do
19
- let(:options) do
20
- {
21
- 'Message-Id' => '<payload@mailgun-tracking.com>'
22
- }
14
+ describe '#event' do
15
+ it 'returns event' do
16
+ expect(payload.event).to eq(options.fetch('event-data').fetch('event'))
23
17
  end
18
+ end
24
19
 
25
- it { is_expected.to respond_to(:message_id) }
26
- it { expect(payload.message_id).to eq(options['Message-Id']) }
20
+ describe '#token' do
21
+ it 'returns token' do
22
+ expect(payload.token).to eq(options.fetch('signature').fetch('token'))
23
+ end
27
24
  end
28
25
 
29
- context 'when the options include a boolean data type' do
30
- let(:options) do
31
- {
32
- boolean: true,
33
- string: 'string'
34
- }
26
+ describe '#timestamp' do
27
+ it 'returns timestamp' do
28
+ expect(payload.timestamp).to eq(options.fetch('signature').fetch('timestamp'))
35
29
  end
30
+ end
36
31
 
37
- it { is_expected.to be_boolean }
38
- it { is_expected.to respond_to(:boolean?) }
32
+ describe '#signature' do
33
+ it 'returns signature' do
34
+ expect(payload.signature).to eq(options.fetch('signature').fetch('signature'))
35
+ end
39
36
  end
40
37
  end
@@ -22,4 +22,40 @@ RSpec.describe Mailgun::Tracking::Request do
22
22
  it { is_expected.not_to be_mailgun_tracking }
23
23
  end
24
24
  end
25
+
26
+ describe '#payload' do
27
+ context 'when the parameters contain the timestamp' do
28
+ let(:env) { env_for('http://localhost:3000/mailgun', method: :post, params: { 'timestamp' => '1572632560' }) }
29
+
30
+ it 'returns legacy payload' do
31
+ expect(request.payload).to be_an_instance_of(Mailgun::Tracking::Payload::Legacy)
32
+ end
33
+ end
34
+
35
+ context 'when the parameters do not contain the timestamp' do
36
+ let(:env) { env_for('http://localhost:3000/mailgun', method: :post, params: { 'signature' => {} }) }
37
+
38
+ it 'returns payload' do
39
+ expect(request.payload).to be_an_instance_of(Mailgun::Tracking::Payload)
40
+ end
41
+ end
42
+ end
43
+
44
+ context 'when application/json request' do
45
+ let(:env) { env_for('/', method: :post, input: input, 'CONTENT_TYPE' => content_type) }
46
+ let(:input) { 'foo=bar' }
47
+ let(:content_type) { 'application/json; charset=utf-8' }
48
+
49
+ it 'rewinds input' do
50
+ expect(request.body.read).to eq(input)
51
+ end
52
+
53
+ context 'when input is a hash' do
54
+ let(:input) { '{"qux": "bin"}' }
55
+
56
+ it 'adds a parsed hash to POST params' do
57
+ expect(request.params['qux']).to eq('bin')
58
+ end
59
+ end
60
+ end
25
61
  end
@@ -3,15 +3,29 @@
3
3
  RSpec.describe Mailgun::Tracking::Signature do
4
4
  subject(:signature) { described_class.new(payload) }
5
5
 
6
- let(:payload) { fixture('delivered.json') }
7
-
8
6
  describe '.verify!' do
9
7
  context 'when the signature comparison is successful' do
8
+ let(:payload) do
9
+ instance_double(
10
+ Mailgun::Tracking::Payload,
11
+ timestamp: '1499697910',
12
+ token: 'b5751a49a024483da8d41c3684f98b8f',
13
+ signature: '374e0b1a3deeb57318c783d43ff71093fbf26406a452761dab91bf346a93b49e'
14
+ )
15
+ end
16
+
10
17
  it { expect(described_class.verify!(payload)).to be true }
11
18
  end
12
19
 
13
20
  context 'when the signature comparison is unsuccessful' do
14
- before { payload['timestamp'] = '' }
21
+ let(:payload) do
22
+ instance_double(
23
+ Mailgun::Tracking::Payload,
24
+ timestamp: '',
25
+ token: 'b5751a49a024483da8d41c3684f98b8f',
26
+ signature: '374e0b1a3deeb57318c783d43ff71093fbf26406a452761dab91bf346a93b49e'
27
+ )
28
+ end
15
29
 
16
30
  it { expect { described_class.verify!(payload) }.to raise_error(Mailgun::Tracking::InvalidSignature) }
17
31
  end
@@ -19,11 +33,27 @@ RSpec.describe Mailgun::Tracking::Signature do
19
33
 
20
34
  describe '#valid?' do
21
35
  context 'when the signature comparison is successful' do
36
+ let(:payload) do
37
+ instance_double(
38
+ Mailgun::Tracking::Payload,
39
+ timestamp: '1499697910',
40
+ token: 'b5751a49a024483da8d41c3684f98b8f',
41
+ signature: '374e0b1a3deeb57318c783d43ff71093fbf26406a452761dab91bf346a93b49e'
42
+ )
43
+ end
44
+
22
45
  it { is_expected.to be_valid }
23
46
  end
24
47
 
25
48
  context 'when the signature comparison is unsuccessful' do
26
- before { payload['timestamp'] = '' }
49
+ let(:payload) do
50
+ instance_double(
51
+ Mailgun::Tracking::Payload,
52
+ timestamp: '',
53
+ token: 'b5751a49a024483da8d41c3684f98b8f',
54
+ signature: '374e0b1a3deeb57318c783d43ff71093fbf26406a452761dab91bf346a93b49e'
55
+ )
56
+ end
27
57
 
28
58
  it { is_expected.not_to be_valid }
29
59
  end
@@ -6,6 +6,12 @@ RSpec.describe Mailgun::Tracking do
6
6
  it { is_expected.to respond_to(:api_key=) }
7
7
  it { is_expected.to respond_to(:endpoint=) }
8
8
 
9
+ it do
10
+ expect do
11
+ described_class.non_existent_method
12
+ end.to raise_error(NoMethodError)
13
+ end
14
+
9
15
  describe '.configure' do
10
16
  before do
11
17
  described_class.configure do |config|
@@ -1,5 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require 'simplecov' if ENV['COVERAGE']
4
+
3
5
  require 'rack/test'
4
6
  require 'bundler/setup'
5
7
  require 'mailgun/tracking'
@@ -6,7 +6,7 @@ end
6
6
 
7
7
  RSpec.shared_examples 'acts as rack' do
8
8
  let(:app) { Dummy::Application }
9
- let(:payload) { fixture('delivered.json') }
9
+ let(:payload) { fixture('legacy/delivered.json') }
10
10
  let(:delivered) { instance_double(Delivered) }
11
11
 
12
12
  before do
@@ -24,7 +24,7 @@ RSpec.shared_examples 'acts as rack' do
24
24
 
25
25
  it do
26
26
  post('/mailgun', payload)
27
- expect(delivered).to have_received(:call).with(instance_of(Mailgun::Tracking::Payload)).twice
27
+ expect(delivered).to have_received(:call).with(payload).twice
28
28
  end
29
29
 
30
30
  context 'when the signature comparison is unsuccessful' do
@@ -3,7 +3,7 @@
3
3
  RSpec.shared_examples 'subscriber' do
4
4
  describe '#call' do
5
5
  let(:callable) { proc {} }
6
- let(:payload) { fixture('delivered.json') }
6
+ let(:payload) { fixture('legacy/delivered.json') }
7
7
 
8
8
  before { allow(callable).to receive(:call).with(payload) }
9
9
 
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: mailgun-tracking
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.0
4
+ version: 1.1.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-10-16 00:00:00.000000000 Z
11
+ date: 2019-11-15 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rack
@@ -100,14 +100,14 @@ dependencies:
100
100
  requirements:
101
101
  - - "~>"
102
102
  - !ruby/object:Gem::Version
103
- version: 0.75.1
103
+ version: 0.76.0
104
104
  type: :development
105
105
  prerelease: false
106
106
  version_requirements: !ruby/object:Gem::Requirement
107
107
  requirements:
108
108
  - - "~>"
109
109
  - !ruby/object:Gem::Version
110
- version: 0.75.1
110
+ version: 0.76.0
111
111
  - !ruby/object:Gem::Dependency
112
112
  name: rubocop-performance
113
113
  requirement: !ruby/object:Gem::Requirement
@@ -166,6 +166,7 @@ files:
166
166
  - lib/mailgun/tracking/middleware.rb
167
167
  - lib/mailgun/tracking/notifier.rb
168
168
  - lib/mailgun/tracking/payload.rb
169
+ - lib/mailgun/tracking/payload/legacy.rb
169
170
  - lib/mailgun/tracking/railtie.rb
170
171
  - lib/mailgun/tracking/request.rb
171
172
  - lib/mailgun/tracking/signature.rb
@@ -179,6 +180,7 @@ files:
179
180
  - spec/dummy/rails/logs/test.log
180
181
  - spec/dummy/sinatra/application.rb
181
182
  - spec/fixtures/delivered.json
183
+ - spec/fixtures/legacy/delivered.json
182
184
  - spec/integration/rack/rack_spec.rb
183
185
  - spec/integration/rails/rails_spec.rb
184
186
  - spec/integration/sinatra/sinatra_spec.rb
@@ -186,6 +188,7 @@ files:
186
188
  - spec/mailgun/tracking/listener_spec.rb
187
189
  - spec/mailgun/tracking/middleware_spec.rb
188
190
  - spec/mailgun/tracking/notifier_spec.rb
191
+ - spec/mailgun/tracking/payload/legacy_spec.rb
189
192
  - spec/mailgun/tracking/payload_spec.rb
190
193
  - spec/mailgun/tracking/request_spec.rb
191
194
  - spec/mailgun/tracking/signature_spec.rb
@@ -200,11 +203,13 @@ files:
200
203
  - spec/support/rack_helpers.rb
201
204
  - spec/support/shared_examples/integration/acts_as_rack.rb
202
205
  - spec/support/shared_examples/subscriber.rb
203
- - spec/support/simplecov.rb
204
206
  homepage: https://github.com/chubchenko/mailgun-tracking
205
207
  licenses:
206
208
  - MIT
207
- metadata: {}
209
+ metadata:
210
+ bug_tracker_uri: https://github.com/chubchenko/mailgun-tracking/issues
211
+ changelog_uri: https://github.com/chubchenko/mailgun-tracking/blob/master/CHANGELOG.md
212
+ source_code_uri: https://github.com/chubchenko/mailgun-tracking
208
213
  post_install_message:
209
214
  rdoc_options: []
210
215
  require_paths:
@@ -220,7 +225,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
220
225
  - !ruby/object:Gem::Version
221
226
  version: '0'
222
227
  requirements: []
223
- rubygems_version: 3.0.6
228
+ rubygems_version: 3.0.2
224
229
  signing_key:
225
230
  specification_version: 4
226
231
  summary: Integration with Mailgun Webhooks
@@ -233,16 +238,17 @@ test_files:
233
238
  - spec/integration/sinatra/sinatra_spec.rb
234
239
  - spec/integration/rack/rack_spec.rb
235
240
  - spec/integration/rails/rails_spec.rb
236
- - spec/support/simplecov.rb
237
241
  - spec/support/rack_helpers.rb
238
242
  - spec/support/fixture.rb
239
243
  - spec/support/shared_examples/integration/acts_as_rack.rb
240
244
  - spec/support/shared_examples/subscriber.rb
245
+ - spec/fixtures/legacy/delivered.json
241
246
  - spec/fixtures/delivered.json
242
247
  - spec/mailgun/tracking_spec.rb
243
248
  - spec/mailgun/tracking/configuration_spec.rb
244
249
  - spec/mailgun/tracking/version_spec.rb
245
250
  - spec/mailgun/tracking/signature_spec.rb
251
+ - spec/mailgun/tracking/payload/legacy_spec.rb
246
252
  - spec/mailgun/tracking/notifier_spec.rb
247
253
  - spec/mailgun/tracking/subscriber_spec.rb
248
254
  - spec/mailgun/tracking/middleware_spec.rb
@@ -1,9 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- if ENV['COVERAGE'] == 'true'
4
- require 'simplecov'
5
-
6
- SimpleCov.start do
7
- add_filter('integration')
8
- end
9
- end