postageapp 1.0.24 → 1.2.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 (54) hide show
  1. checksums.yaml +7 -0
  2. data/.travis.yml +13 -12
  3. data/Gemfile +6 -1
  4. data/LICENSE +1 -1
  5. data/README.md +122 -70
  6. data/Rakefile +19 -4
  7. data/generators/postageapp/postageapp_generator.rb +5 -7
  8. data/lib/generators/postageapp/postageapp_generator.rb +15 -9
  9. data/lib/postageapp.rb +42 -36
  10. data/lib/postageapp/configuration.rb +34 -21
  11. data/lib/postageapp/failed_request.rb +60 -36
  12. data/lib/postageapp/logger.rb +6 -7
  13. data/lib/postageapp/mail.rb +3 -0
  14. data/lib/postageapp/mail/arguments.rb +75 -0
  15. data/lib/postageapp/mail/delivery_method.rb +32 -0
  16. data/lib/postageapp/mail/extensions.rb +21 -0
  17. data/lib/postageapp/mailer.rb +72 -20
  18. data/lib/postageapp/mailer/mailer_2.rb +65 -22
  19. data/lib/postageapp/mailer/mailer_3.rb +45 -28
  20. data/lib/postageapp/mailer/mailer_4.rb +72 -40
  21. data/lib/postageapp/rails/rails.rb +17 -7
  22. data/lib/postageapp/rails/railtie.rb +22 -7
  23. data/lib/postageapp/request.rb +67 -43
  24. data/lib/postageapp/response.rb +11 -8
  25. data/lib/postageapp/utils.rb +11 -3
  26. data/lib/postageapp/version.rb +2 -2
  27. data/postageapp.gemspec +13 -11
  28. data/rails/init.rb +1 -1
  29. data/test/configuration_test.rb +35 -38
  30. data/test/failed_request_test.rb +33 -18
  31. data/test/gemfiles/Gemfile.rails-2.3.x +4 -1
  32. data/test/gemfiles/Gemfile.rails-3.0.x +4 -1
  33. data/test/gemfiles/Gemfile.rails-3.1.x +4 -1
  34. data/test/gemfiles/Gemfile.rails-3.2.x +4 -1
  35. data/test/gemfiles/Gemfile.rails-4.0.x +4 -1
  36. data/test/gemfiles/Gemfile.rails-4.1.x +12 -0
  37. data/test/gemfiles/Gemfile.rails-4.2.x +12 -0
  38. data/test/gemfiles/Gemfile.ruby +11 -0
  39. data/test/helper.rb +52 -33
  40. data/test/live_test.rb +11 -8
  41. data/test/mail_delivery_method_test.rb +161 -0
  42. data/test/mailer/action_mailer_2/notifier.rb +37 -28
  43. data/test/mailer/action_mailer_3/notifier.rb +28 -22
  44. data/test/mailer_2_test.rb +20 -16
  45. data/test/mailer_3_test.rb +16 -22
  46. data/test/mailer_4_test.rb +28 -28
  47. data/test/mailer_helper_methods_test.rb +17 -14
  48. data/test/postageapp_test.rb +8 -9
  49. data/test/rails_initialization_test.rb +14 -14
  50. data/test/request_test.rb +35 -35
  51. data/test/response_test.rb +20 -19
  52. data/test/travis_test.rb +168 -0
  53. data/test/with_environment.rb +27 -0
  54. metadata +23 -17
@@ -1,15 +1,25 @@
1
1
  require 'postageapp'
2
- require 'postageapp/mailer' if defined?(ActionMailer)
3
2
 
4
- module PostageApp::Rails
5
-
3
+ if (defined?(ActionMailer))
4
+ require 'postageapp/mailer'
5
+ end
6
+
7
+ module PostageApp::Rails
6
8
  def self.initialize
7
9
  PostageApp.configure do |config|
8
- config.framework = "Rails #{::Rails.version}" if defined?(::Rails.version)
9
- config.project_root = ::Rails.root if defined?(::Rails.root)
10
- config.environment = ::Rails.env if defined?(::Rails.env)
10
+ if (defined?(::Rails.version))
11
+ config.framework = "Rails #{::Rails.version}"
12
+ end
13
+
14
+ if (defined?(::Rails.root))
15
+ config.project_root = ::Rails.root
16
+ end
17
+
18
+ if (defined?(::Rails.env))
19
+ config.environment = ::Rails.env
20
+ end
11
21
  end
12
22
  end
13
23
  end
14
24
 
15
- PostageApp::Rails.initialize
25
+ PostageApp::Rails.initialize
@@ -1,14 +1,29 @@
1
1
  require 'postageapp'
2
- require 'postageapp/mailer' if defined?(ActionMailer)
2
+
3
+ if (defined?(ActionMailer))
4
+ require 'postageapp/mailer'
5
+
6
+ # Register as a delivery method with ActionMailer
7
+ ActionMailer::Base.add_delivery_method(
8
+ :postageapp,
9
+ PostageApp::Mail::DeliveryMethod
10
+ )
11
+ end
3
12
 
4
13
  class PostageApp::Railtie < Rails::Railtie
5
-
6
14
  config.after_initialize do
7
15
  PostageApp.configure do |config|
8
- config.framework = "Rails #{::Rails.version}" if defined?(::Rails.version)
9
- config.project_root = ::Rails.root if defined?(::Rails.root)
10
- config.environment = ::Rails.env if defined?(::Rails.env)
16
+ if (defined?(::Rails.version))
17
+ config.framework = "Rails #{::Rails.version}"
18
+ end
19
+
20
+ if (defined?(::Rails.root))
21
+ config.project_root = ::Rails.root
22
+ end
23
+
24
+ if (defined?(::Rails.env))
25
+ config.environment = ::Rails.env
26
+ end
11
27
  end
12
28
  end
13
-
14
- end
29
+ end
@@ -1,12 +1,12 @@
1
1
  class PostageApp::Request
2
2
  API_VERSION = '1.0'
3
3
 
4
- HEADERS = {
5
- 'Content-type' => 'application/json',
6
- 'Accept' => 'text/json, application/json'
4
+ HEADERS_DEFAULT = {
5
+ 'Content-type' => 'application/json',
6
+ 'Accept' => 'text/json, application/json'
7
7
  }
8
8
 
9
- # Unique ID of the request
9
+ # Unique ID (UID) for the request
10
10
  attr_accessor :uid
11
11
 
12
12
  # The API method being called (example: send_message)
@@ -16,38 +16,44 @@ class PostageApp::Request
16
16
  # A list of arguments in a Hash format passed along with the request
17
17
  attr_accessor :arguments
18
18
 
19
- # Ability to set api_key with eash request
19
+ # Assigns the API key to be used for the request
20
20
  attr_accessor :api_key
21
+
22
+ # Returns a user-agent string used for identification when making API calls.
23
+ def self.user_agent
24
+ @user_agent ||=
25
+ "PostageApp (Gem %s, Ruby %s, %s)" % [
26
+ PostageApp::VERSION,
27
+ RUBY_VERSION,
28
+ PostageApp.configuration.framework
29
+ ]
30
+ end
21
31
 
22
- def initialize(method, arguments = {})
23
- @method = method
24
- @uid = arguments.delete('uid')
25
- @api_key = arguments.delete('api_key') || PostageApp.configuration.api_key
26
- @arguments = arguments
32
+ # Creates a new Request with the given API call method and arguments.
33
+ def initialize(method, arguments = { })
34
+ @method = method
35
+ @arguments = arguments.dup
36
+
37
+ @uid = @arguments.delete('uid')
38
+ @api_key = @arguments.delete('api_key') || PostageApp.configuration.api_key
27
39
  end
28
40
 
29
41
  # Skipping resend doesn't trigger PostageApp::FailedRequest.resend_all
30
42
  # it's needed so the request being resend doesn't create duplicate queue
31
43
  def send(skip_failed_requests_processing = false)
32
- http = Net::HTTP::Proxy(
33
- PostageApp.configuration.proxy_host,
34
- PostageApp.configuration.proxy_port,
35
- PostageApp.configuration.proxy_user,
36
- PostageApp.configuration.proxy_pass
37
- ).new(url.host, url.port)
38
-
39
- http.read_timeout = PostageApp.configuration.http_read_timeout
40
- http.open_timeout = PostageApp.configuration.http_open_timeout
41
- http.use_ssl = PostageApp.configuration.secure?
42
-
44
+ http = PostageApp.configuration.http
45
+
43
46
  PostageApp.logger.info(self)
44
47
 
45
48
  http_response = begin
46
49
  http.post(
47
50
  url.path,
48
51
  self.arguments_to_send.to_json,
49
- HEADERS.merge('User-Agent' => "PostageApp-RubyGem #{PostageApp::VERSION} (Ruby #{RUBY_VERSION}, #{PostageApp.configuration.framework})")
52
+ HEADERS_DEFAULT.merge(
53
+ 'User-Agent' => self.class.user_agent
54
+ )
50
55
  )
56
+
51
57
  rescue TimeoutError, Errno::ECONNREFUSED
52
58
  nil
53
59
  end
@@ -56,10 +62,10 @@ class PostageApp::Request
56
62
 
57
63
  PostageApp.logger.info(response)
58
64
 
59
- unless skip_failed_requests_processing
60
- if response.fail?
65
+ unless (skip_failed_requests_processing)
66
+ if (response.fail?)
61
67
  PostageApp::FailedRequest.store(self)
62
- elsif response.ok?
68
+ elsif (response.ok?)
63
69
  PostageApp::FailedRequest.resend_all
64
70
  end
65
71
  end
@@ -67,16 +73,6 @@ class PostageApp::Request
67
73
  response
68
74
  end
69
75
 
70
- # Emulates Mail::Message#html_part
71
- def html_part
72
- self.arguments && self.arguments['content'] && self.arguments['content']['text/html']
73
- end
74
-
75
- # Emulates Mail::Message#text_part
76
- def text_part
77
- self.arguments && self.arguments['content'] && self.arguments['content']['text/plain']
78
- end
79
-
80
76
  # URL of the where PostageApp::Request will be directed at
81
77
  def url
82
78
  URI.parse("#{PostageApp.configuration.url}/v.#{API_VERSION}/#{self.method}.json")
@@ -84,20 +80,48 @@ class PostageApp::Request
84
80
 
85
81
  # Unique ID of the request
86
82
  def uid(reload = false)
87
- @uid = nil if reload
83
+ @uid = nil if (reload)
84
+
88
85
  @uid ||= Digest::SHA1.hexdigest("#{rand}#{Time.now.to_f}#{self.arguments}")
89
86
  end
90
87
 
91
- # Arguments need to be appended with some some stuff before it's ready to be send out
88
+ # Returns the arguments that will be used to send this request.
92
89
  def arguments_to_send
93
- hash = { 'uid' => self.uid, 'api_key' => self.api_key }
94
-
95
- if !self.arguments.nil? && !self.arguments.empty?
96
- if !PostageApp.configuration.recipient_override.nil? && self.method.to_sym == :send_message
97
- self.arguments.merge!('recipient_override' => PostageApp.configuration.recipient_override)
90
+ hash = {
91
+ 'uid' => self.uid,
92
+ 'api_key' => self.api_key
93
+ }
94
+
95
+ if (self.arguments && !self.arguments.empty?)
96
+ case (self.method.to_sym)
97
+ when :send_message
98
+ if (PostageApp.configuration.recipient_override)
99
+ self.arguments.merge!(
100
+ 'recipient_override' => PostageApp.configuration.recipient_override
101
+ )
102
+ end
98
103
  end
99
- hash.merge!('arguments' => self.arguments.recursive_stringify_keys!)
104
+
105
+ hash.merge!(
106
+ 'arguments' => self.arguments.recursive_stringify_keys!
107
+ )
100
108
  end
109
+
101
110
  hash
102
111
  end
112
+
113
+ # Emulation of Mail::Message interface
114
+ def body
115
+ self.arguments and self.arguments['content'] and (self.arguments['content']['text/html'] or self.arguments['content']['text/plain'])
116
+ end
117
+
118
+ # Emulates Mail::Message#html_part
119
+ def html_part
120
+ self.arguments and self.arguments['content'] and self.arguments['content']['text/html']
121
+ end
122
+
123
+ # Emulates Mail::Message#text_part
124
+ def text_part
125
+ self.arguments and self.arguments['content'] and self.arguments['content']['text/plain']
126
+ end
103
127
  end
@@ -1,5 +1,4 @@
1
1
  class PostageApp::Response
2
-
3
2
  # The UID should match the Request's UID. If Request didn't provide with one
4
3
  # PostageApp service should generate it for the Response
5
4
  attr_reader :uid
@@ -19,12 +18,17 @@ class PostageApp::Response
19
18
  # If something goes wrong Response will be thought of as failed
20
19
  def initialize(http_response)
21
20
  hash = JSON::parse(http_response.body)
22
- @status = hash['response']['status']
23
- @uid = hash['response']['uid']
24
- @message = hash['response']['message']
25
- @data = hash['data']
21
+
22
+ _response = hash['response']
23
+
24
+ @status = _response['status']
25
+ @uid = _response['uid']
26
+ @message = _response['message']
27
+
28
+ @data = hash['data']
29
+
26
30
  rescue
27
- @status = 'fail'
31
+ @status = 'fail'
28
32
  end
29
33
 
30
34
  # Little helper that checks for the Response status
@@ -35,5 +39,4 @@ class PostageApp::Response
35
39
  def method_missing(method)
36
40
  /.*?\?$/.match(method.to_s) ? "#{self.status}?" == method.to_s : super(method)
37
41
  end
38
-
39
- end
42
+ end
@@ -1,5 +1,4 @@
1
1
  class Hash
2
-
3
2
  # Example usage:
4
3
  # @hash.dig(:k1) # same as @hash[:k1]
5
4
  # @hash.dig(:k1, :k2) # same as @hash[:k1] && @hash[:k1][:k2]
@@ -14,8 +13,16 @@ class Hash
14
13
  def recursive_stringify_keys!
15
14
  keys.each do |key|
16
15
  value = delete(key)
17
- self[key.to_s] = value.is_a?(Hash) ? value.recursive_stringify_keys! : value
16
+
17
+ self[key.to_s] =
18
+ case (value)
19
+ when Hash
20
+ value.recursive_stringify_keys!
21
+ else
22
+ value
23
+ end
18
24
  end
25
+
19
26
  self
20
27
  end
21
28
  end
@@ -25,7 +32,8 @@ class Net::HTTP
25
32
  alias_method :old_initialize, :initialize
26
33
  def initialize(*args)
27
34
  old_initialize(*args)
35
+
28
36
  @ssl_context = OpenSSL::SSL::SSLContext.new
29
37
  @ssl_context.verify_mode = OpenSSL::SSL::VERIFY_NONE
30
38
  end
31
- end
39
+ end
@@ -1,3 +1,3 @@
1
1
  module PostageApp
2
- VERSION = "1.0.24"
3
- end
2
+ VERSION = "1.2.0"
3
+ end
@@ -4,18 +4,20 @@ $:.unshift File.expand_path('../lib', __FILE__)
4
4
  require 'postageapp/version'
5
5
 
6
6
  Gem::Specification.new do |s|
7
- s.name = "postageapp"
8
- s.version = PostageApp::VERSION
9
- s.authors = ["Oleg Khabarov", "Scott Tadman", "The Working Group Inc."]
10
- s.email = ["oleg@khabarov.ca", "scott@twg.ca"]
11
- s.homepage = "http://github.com/postageapp/postageapp-ruby"
12
- s.summary = "Easier way to send email from web apps"
13
- s.description = "Gem that interfaces with PostageApp.com service to send emails from web apps"
14
- s.license = 'MIT'
7
+ s.name = "postageapp"
8
+ s.version = PostageApp::VERSION
9
+ s.authors = [ "Oleg Khabarov", "Scott Tadman", "The Working Group Inc." ]
10
+ s.email = [ "oleg@khabarov.ca", "tadman@postageapp.com" ]
11
+ s.homepage = "http://github.com/postageapp/postageapp-ruby"
12
+ s.summary = "Easier way to send email from web apps"
13
+ s.description = "Gem that interfaces with PostageApp.com service to send emails from web apps"
14
+ s.license = 'MIT'
15
15
 
16
- s.files = `git ls-files`.split("\n")
17
- s.platform = Gem::Platform::RUBY
18
- s.require_paths = ['lib']
16
+ s.files = `git ls-files`.split("\n")
17
+ s.platform = Gem::Platform::RUBY
18
+ s.require_paths = [ 'lib' ]
19
+
20
+ s.required_ruby_version = '>= 1.9.3'
19
21
 
20
22
  s.add_dependency 'json'
21
23
  end
@@ -1,2 +1,2 @@
1
1
  # Loading for Rails 2
2
- require 'postageapp/rails/rails'
2
+ require 'postageapp/rails/rails'
@@ -1,27 +1,26 @@
1
- require File.expand_path('../helper', __FILE__)
1
+ require File.expand_path('helper', File.dirname(__FILE__))
2
2
 
3
- class ConfigurationTest < Minitest::Test
4
-
3
+ class ConfigurationTest < MiniTest::Test
5
4
  def test_initialization_defaults
6
5
  config = PostageApp::Configuration.new
7
6
 
8
- assert_equal true, config.secure
9
- assert_equal nil, config.api_key
10
- assert_equal 'https', config.protocol
11
- assert_equal 'api.postageapp.com', config.host
12
- assert_equal 443, config.port
13
- assert_equal nil, config.proxy_host
14
- assert_equal nil, config.proxy_port
15
- assert_equal nil, config.proxy_user
16
- assert_equal nil, config.proxy_pass
17
- assert_equal 5, config.http_open_timeout
18
- assert_equal 10, config.http_read_timeout
19
- assert_equal nil, config.recipient_override
20
- assert_equal %w( send_message ), config.requests_to_resend
21
- assert_equal nil, config.project_root
22
- assert_equal 'production', config.environment
23
- assert_equal nil, config.logger
24
- assert_equal 'undefined framework', config.framework
7
+ assert_equal true, config.secure
8
+ assert_equal nil,config.api_key
9
+ assert_equal 'https', config.protocol
10
+ assert_equal 'api.postageapp.com', config.host
11
+ assert_equal 443, config.port
12
+ assert_equal nil, config.proxy_host
13
+ assert_equal nil, config.proxy_port
14
+ assert_equal nil, config.proxy_user
15
+ assert_equal nil, config.proxy_pass
16
+ assert_equal 5, config.http_open_timeout
17
+ assert_equal 10, config.http_read_timeout
18
+ assert_equal nil, config.recipient_override
19
+ assert_equal %w( send_message ), config.requests_to_resend
20
+ assert_equal nil, config.project_root
21
+ assert_equal 'production', config.environment
22
+ assert_equal nil, config.logger
23
+ assert_equal 'undefined framework', config.framework
25
24
  end
26
25
 
27
26
  def test_initialization_overrides
@@ -30,17 +29,17 @@ class ConfigurationTest < Minitest::Test
30
29
  config.protocol = 'http'
31
30
  config.port = 999
32
31
 
33
- assert_equal 'http', config.protocol
34
- assert_equal 999, config.port
32
+ assert_equal 'http', config.protocol
33
+ assert_equal 999, config.port
35
34
  end
36
35
 
37
36
  def test_initialization_for_secure
38
37
  config = PostageApp::Configuration.new
39
38
 
40
39
  config.secure = true
41
- assert_equal true, config.secure
40
+ assert_equal true, config.secure
42
41
  assert_equal 'https', config.protocol
43
- assert_equal 443, config.port
42
+ assert_equal 443, config.port
44
43
 
45
44
  assert config.secure?
46
45
  end
@@ -49,23 +48,22 @@ class ConfigurationTest < Minitest::Test
49
48
  config = PostageApp::Configuration.new
50
49
 
51
50
  config.secure = false
52
- assert_equal false, config.secure
53
- assert_equal 'http', config.protocol
54
- assert_equal 80, config.port
51
+ assert_equal false, config.secure
52
+ assert_equal 'http', config.protocol
53
+ assert_equal 80, config.port
55
54
 
56
55
  assert !config.secure?
57
56
  end
58
57
 
59
58
  def test_initialization_with_env_api_key
60
- ENV['POSTAGEAPP_API_KEY'] = 'env_api_key'
61
-
62
- config = PostageApp::Configuration.new
63
- assert_equal 'env_api_key', config.api_key
64
-
65
- config.api_key = 'config_api_key'
66
- assert_equal 'config_api_key', config.api_key
67
-
68
- ENV['POSTAGEAPP_API_KEY'] = nil # must unset for other methods to run properly
59
+ with_environment('POSTAGEAPP_API_KEY' => 'env_api_key') do
60
+ config = PostageApp::Configuration.new
61
+
62
+ assert_equal 'env_api_key', config.api_key
63
+
64
+ config.api_key = 'config_api_key'
65
+ assert_equal 'config_api_key', config.api_key
66
+ end
69
67
  end
70
68
 
71
69
  def test_method_url
@@ -74,5 +72,4 @@ class ConfigurationTest < Minitest::Test
74
72
  config.host = 'api.postageapp.com'
75
73
  assert_equal 'https://api.postageapp.com:443', config.url
76
74
  end
77
-
78
- end
75
+ end