postageapp 1.3.1 → 1.4.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (72) hide show
  1. checksums.yaml +5 -5
  2. data/.gitignore +6 -0
  3. data/.travis.yml +9 -40
  4. data/LICENSE.md +1 -1
  5. data/README.md +117 -13
  6. data/Rakefile +15 -4
  7. data/VERSION +1 -0
  8. data/app/ingresses/action_mailbox/ingresses/postage_app.rb +2 -0
  9. data/app/ingresses/action_mailbox/ingresses/postage_app/inbound_emails_controller.rb +50 -0
  10. data/config/routes.rb +6 -0
  11. data/exe/postageapp +37 -0
  12. data/lib/generators/postageapp/postageapp_generator.rb +9 -6
  13. data/lib/postageapp.rb +53 -35
  14. data/lib/postageapp/cli.rb +14 -0
  15. data/lib/postageapp/cli/command.rb +110 -0
  16. data/lib/postageapp/cli/command/config.rb +74 -0
  17. data/lib/postageapp/cli/command/create_mailbox.rb +21 -0
  18. data/lib/postageapp/cli/command/env.rb +58 -0
  19. data/lib/postageapp/cli/command/get_project_info.rb +3 -0
  20. data/lib/postageapp/configuration.rb +237 -74
  21. data/lib/postageapp/engine.rb +9 -0
  22. data/lib/postageapp/env.rb +9 -0
  23. data/lib/postageapp/mailer.rb +1 -11
  24. data/lib/postageapp/mailer/mailer_4.rb +30 -14
  25. data/lib/postageapp/rails/railtie.rb +1 -3
  26. data/lib/postageapp/request.rb +6 -1
  27. data/log/.gitignore +1 -0
  28. data/postageapp.gemspec +8 -10
  29. data/script/with +2 -2
  30. data/test/gemfiles/Gemfile.rails-2.3.x +1 -1
  31. data/test/gemfiles/Gemfile.rails-3.0.x +1 -1
  32. data/test/gemfiles/Gemfile.rails-3.1.x +1 -1
  33. data/test/gemfiles/Gemfile.rails-3.2.x +1 -1
  34. data/test/gemfiles/Gemfile.rails-4.0.x +1 -1
  35. data/test/gemfiles/Gemfile.rails-4.1.x +1 -1
  36. data/test/gemfiles/Gemfile.rails-4.2.x +1 -2
  37. data/test/gemfiles/Gemfile.rails-5.0.x +2 -3
  38. data/test/gemfiles/Gemfile.rails-5.2.x +12 -0
  39. data/test/gemfiles/Gemfile.rails-6.0.x +12 -0
  40. data/test/gemfiles/Gemfile.rails-6.1.x +12 -0
  41. data/test/gemfiles/Gemfile.ruby +2 -3
  42. data/test/helper.rb +3 -3
  43. data/test/log/.gitignore +1 -0
  44. data/test/mailer/action_mailer_3/notifier.rb +1 -1
  45. data/test/tmp/.gitignore +1 -0
  46. data/test/travis_test.rb +58 -40
  47. data/test/{configuration_test.rb → unit/configuration_test.rb} +5 -3
  48. data/test/{failed_request_test.rb → unit/failed_request_test.rb} +6 -6
  49. data/test/{live_test.rb → unit/live_test.rb} +1 -36
  50. data/test/{mail_delivery_method_test.rb → unit/mail_delivery_method_test.rb} +1 -1
  51. data/test/{mailer_4_test.rb → unit/mailer_4_test.rb} +2 -2
  52. data/test/{mailer_helper_methods_test.rb → unit/mailer_helper_methods_test.rb} +4 -4
  53. data/test/{postageapp_test.rb → unit/postageapp_test.rb} +7 -1
  54. data/test/{rails_initialization_test.rb → unit/rails_initialization_test.rb} +2 -2
  55. data/test/{request_test.rb → unit/request_test.rb} +15 -15
  56. data/test/{response_test.rb → unit/response_test.rb} +4 -4
  57. data/test/unit/tmp/.gitignore +1 -0
  58. data/tmp/.gitignore +1 -0
  59. metadata +40 -46
  60. data/lib/postageapp/mailer/mailer_2.rb +0 -140
  61. data/lib/postageapp/mailer/mailer_3.rb +0 -190
  62. data/lib/postageapp/version.rb +0 -3
  63. data/test/mailer/action_mailer_2/notifier.rb +0 -77
  64. data/test/mailer/action_mailer_2/notifier/with_body_and_attachment.erb +0 -1
  65. data/test/mailer/action_mailer_2/notifier/with_custom_postage_variables.text.html.erb +0 -1
  66. data/test/mailer/action_mailer_2/notifier/with_custom_postage_variables.text.plain.erb +0 -1
  67. data/test/mailer/action_mailer_2/notifier/with_html_and_text_views.text.html.erb +0 -1
  68. data/test/mailer/action_mailer_2/notifier/with_html_and_text_views.text.plain.erb +0 -1
  69. data/test/mailer/action_mailer_2/notifier/with_simple_view.erb +0 -1
  70. data/test/mailer/action_mailer_2/notifier/with_text_only_view.text.plain.erb +0 -1
  71. data/test/mailer_2_test.rb +0 -95
  72. data/test/mailer_3_test.rb +0 -118
@@ -1,140 +0,0 @@
1
- # Postage::Mailer allows you to use/re-use existing mailers set up using
2
- # ActionMailer. The only catch is to change inheritance from ActionMailer::Base
3
- # to PostageApp::Mailer. Also don't forget to require 'postageapp/mailer'
4
- #
5
- # Here's an example of a valid PostageApp::Mailer class
6
- #
7
- # require 'postageapp/mailer'
8
- #
9
- # class Notifier < PostageApp::Mailer
10
- # def signup_notification(recipient)
11
- # recipients recipient.email_address
12
- # from 'system@example.com'
13
- # subject 'New Account Information'
14
- # end
15
- # end
16
- #
17
- # Postage::Mailer introduces a few mailer methods specific to Postage:
18
- #
19
- # * template - template name that is defined in your PostageApp project
20
- # * variables - extra variables you want to send along with the message
21
- #
22
- # Sending email
23
- #
24
- # Notifier.deliver_signup_notification(user) # attempts to deliver to PostageApp (depending on env)
25
- # request = Notifier.create_signup_notification(user) # creates PostageApp::Request object
26
- #
27
- class PostageApp::Mailer < ActionMailer::Base
28
- # Using :test as a delivery method if set somewhere else
29
- unless (self.delivery_method == :test)
30
- self.delivery_method = :postage
31
- end
32
-
33
- adv_attr_accessor :postageapp_uid
34
- adv_attr_accessor :postageapp_api_key
35
- adv_attr_accessor :postageapp_template
36
- adv_attr_accessor :postageapp_variables
37
-
38
- def perform_delivery_postage(mail)
39
- mail.send
40
- end
41
-
42
- def deliver!(mail = @mail)
43
- unless (mail)
44
- raise 'PostageApp::Request object not present, cannot deliver'
45
- end
46
-
47
- if (perform_deliveries)
48
- __send__("perform_delivery_#{delivery_method}", mail)
49
- end
50
- end
51
-
52
- # Creating a Postage::Request object unlike TMail one in ActionMailer::Base
53
- def create_mail
54
- params = { }
55
-
56
- unless (self.recipients.blank?)
57
- params['recipients'] = self.recipients
58
- end
59
-
60
- params['headers'] = { }
61
-
62
- unless (self.subject.blank?)
63
- params['headers']['subject'] = self.subject
64
- end
65
-
66
- unless (self.subject.blank?)
67
- params['headers']['from'] = self.from
68
- end
69
-
70
- unless (self.headers.blank?)
71
- params['headers'].merge!(self.headers)
72
- end
73
-
74
- params['content'] = { }
75
- params['attachments'] = { }
76
-
77
- if (@parts.empty?)
78
- unless (self.body.blank?)
79
- params['content'][self.content_type] = self.body
80
- end
81
- else
82
- self.parts.each do |part|
83
- case (part.content_disposition)
84
- when 'inline'
85
- if (part.content_type.blank? && String === part.body)
86
- part.content_type = 'text/plain'
87
- end
88
-
89
- params['content'][part.content_type] = part.body
90
- when 'attachment'
91
- params['attachments'][part.filename] = {
92
- 'content_type' => part.content_type,
93
- 'content' => Base64.encode64(part.body)
94
- }
95
- end
96
- end
97
- end
98
-
99
- unless (self.postageapp_template.blank?)
100
- params['template'] = self.postageapp_template
101
- end
102
-
103
- unless (self.postageapp_variables.blank?)
104
- params['variables'] = self.postageapp_variables
105
- end
106
-
107
- if (params['headers'].blank?)
108
- params.delete('headers')
109
- end
110
-
111
- if (params['content'].blank?)
112
- params.delete('content')
113
- end
114
-
115
- if (params['attachments'].blank?)
116
- params.delete('attachments')
117
- end
118
-
119
- @mail = PostageApp::Request.new('send_message', params)
120
-
121
- unless (self.postageapp_uid.blank?)
122
- @mail.uid = self.postageapp_uid
123
- end
124
-
125
- unless (self.postageapp_api_key.blank?)
126
- @mail.api_key = self.postageapp_api_key
127
- end
128
-
129
- @mail
130
- end
131
-
132
- # Not insisting rendering a view if it's not there. PostageApp gem can send blank content
133
- # provided that the template is defined.
134
- def render(opts)
135
- super(opts)
136
-
137
- rescue ActionView::MissingTemplate
138
- # do nothing
139
- end
140
- end
@@ -1,190 +0,0 @@
1
- # Postage::Mailer allows you to use/re-use existing mailers set up using
2
- # ActionMailer. The only catch is to change inheritance from ActionMailer::Base
3
- # to PostageApp::Mailer. Also don't forget to require 'postageapp/mailer'
4
- #
5
- # Here's an example of a valid PostageApp::Mailer class
6
- #
7
- # require 'postageapp/mailer'
8
- #
9
- # class Notifier < PostageApp::Mailer
10
- # def signup_notification(recipient)
11
- # mail(
12
- # :to => recipient.email,
13
- # :from => 'sender@test.test',
14
- # :subject => 'Test Message'
15
- # )
16
- # end
17
- # end
18
- #
19
- # Postage::Mailer introduces a few mailer methods specific to Postage:
20
- #
21
- # * postageapp_template - template name that is defined in your PostageApp project
22
- # * postageapp_variables - extra variables you want to send along with the message
23
- #
24
- # Sending email
25
- #
26
- # request = Notifier.signup_notification(user) # creates PostageApp::Request object
27
- # response = request.deliver # attempts to deliver the message and creates a PostageApp::Response
28
-
29
- class PostageApp::Mailer < ActionMailer::Base
30
- # Wrapper for creating attachments
31
- # Attachments sent to PostageApp are in the following format:
32
- # 'filename.ext' => {
33
- # 'content_type' => 'content/type',
34
- # 'content' => 'base64_encoded_content'
35
- # }
36
-
37
- class Attachments < Hash
38
- def initialize(message)
39
- @_message = message
40
-
41
- message.arguments['attachments'] ||= { }
42
- end
43
-
44
- def []=(filename, attachment)
45
- default_content_type = MIME::Types.type_for(filename).first.content_type rescue ''
46
-
47
- case (attachment)
48
- when Hash
49
- content_type = attachment[:content_type] || default_content_type
50
- content = Base64.encode64(attachment[:body])
51
- else
52
- content_type = default_content_type
53
- content = Base64.encode64(attachment)
54
- end
55
-
56
- @_message.arguments['attachments'][filename] = {
57
- 'content_type' => content_type,
58
- 'content' => content
59
- }
60
- end
61
- end
62
-
63
- # Instead of initializing Mail object, we prepare PostageApp::Request
64
- def initialize(method_name = nil, *args)
65
- super()
66
-
67
- @_message = PostageApp::Request.new(:send_message)
68
-
69
- if method_name
70
- process(method_name, *args)
71
- end
72
- end
73
-
74
- # Possible to define custom uid. Should be sufficiently unique
75
- def postageapp_uid(value = nil)
76
- value ? @_message.uid = value : @_message.uid
77
- end
78
-
79
- def postageapp_api_key(value = nil)
80
- value ? @_message.api_key = value : @_message.api_key
81
- end
82
-
83
- # In API call we can specify PostageApp template that will be used
84
- # to generate content of the message
85
- def postageapp_template(value = nil)
86
- if (value)
87
- @_message.arguments['template'] = value
88
- else
89
- @_message.arguments['template']
90
- end
91
- end
92
-
93
- # Hash of variables that will be used to inject into the content
94
- def postageapp_variables(value = nil)
95
- if (value)
96
- @_message.arguments['variables'] = value
97
- else
98
- @_message.arguments['variables']
99
- end
100
- end
101
-
102
- def attachments
103
- @_attachments ||= Attachments.new(@_message)
104
- end
105
-
106
- # Override for headers assignment
107
- def headers(args = nil)
108
- @_message.headers(args)
109
- end
110
-
111
- # Overriding method that prepares Mail object. This time we'll be
112
- # contructing PostageApp::Request payload.
113
- def mail(headers = { }, &block)
114
- # Guard flag to prevent both the old and the new API from firing
115
- # Should be removed when old API is removed
116
- @mail_was_called = true
117
- m = @_message
118
-
119
- # At the beginning, do not consider class default for parts order neither content_type
120
- content_type = headers[:content_type]
121
- parts_order = headers[:parts_order]
122
-
123
- # Call all the procs (if any)
124
- default_values = self.class.default.merge(self.class.default) do |k,v|
125
- if (v.respond_to?(:call))
126
- v.bind(self).call
127
- else
128
- v
129
- end
130
- end
131
-
132
- # Handle defaults
133
- headers = headers.reverse_merge(default_values)
134
-
135
- # Set configure delivery behavior
136
- wrap_delivery_behavior!(headers.delete(:delivery_method))
137
-
138
- # Assigning recipients
139
- m.arguments['recipients'] = headers.delete(:to)
140
-
141
- # Assign all headers except parts_order, content_type and body
142
- assignable = headers.except(:parts_order, :content_type, :body, :template_name, :template_path)
143
- m.headers.merge!(assignable)
144
-
145
- # Render the templates and blocks
146
- responses, explicit_order = collect_responses_and_parts_order(headers, &block)
147
- create_parts_from_responses(m, responses)
148
-
149
- m
150
- end
151
-
152
- protected
153
- def create_parts_from_responses(m, responses) #:nodoc:
154
- content = m.arguments['content'] ||= { }
155
-
156
- responses.each do |part|
157
- content[part[:content_type]] = part[:body]
158
- end
159
- end
160
- end
161
-
162
- # A set of methods that are useful when request needs to behave as Mail
163
- class PostageApp::Request
164
- attr_accessor :delivery_handler
165
- attr_accessor :perform_deliveries
166
- attr_accessor :raise_delivery_errors
167
-
168
- def inform_interceptors
169
- Mail.inform_interceptors(self)
170
- end
171
-
172
- # Either doing an actual send, or passing it along to Mail::TestMailer
173
- # Probably not the best way as we're skipping way too many intermediate methods
174
- def deliver
175
- inform_interceptors
176
-
177
- if (perform_deliveries)
178
- if (@delivery_method == Mail::TestMailer)
179
- @delivery_method.deliveries << self
180
- else
181
- self.send
182
- end
183
- end
184
- end
185
-
186
- # Not 100% on this, but I need to assign this so I can properly handle deliver method
187
- def delivery_method(method = nil, settings = { })
188
- @delivery_method = method
189
- end
190
- end
@@ -1,3 +0,0 @@
1
- module PostageApp
2
- VERSION = '1.3.1'.freeze
3
- end
@@ -1,77 +0,0 @@
1
- # Test mailer for ActionMailer 2.x
2
-
3
- class Notifier < PostageApp::Mailer
4
- self.template_root = File.dirname(__FILE__)
5
-
6
- def blank
7
- # Empty method
8
- end
9
-
10
- def with_no_content
11
- setup_headers
12
- end
13
-
14
- def with_text_only_view
15
- setup_headers
16
- end
17
-
18
- def with_html_and_text_views
19
- setup_headers
20
- end
21
-
22
- def with_simple_view
23
- setup_headers
24
- end
25
-
26
- def with_manual_parts
27
- setup_headers
28
-
29
- part(
30
- :content_type => 'text/html',
31
- :body => 'html content'
32
- )
33
-
34
- part(
35
- content_type: 'text/plain',
36
- body: 'text content'
37
- )
38
-
39
- attachment(
40
- content_type: 'image/jpeg',
41
- filename: 'foo.jpg',
42
- body: '123456789'
43
- )
44
- end
45
-
46
- def with_body_and_attachment
47
- setup_headers
48
-
49
- attachment(
50
- content_type: 'image/jpeg',
51
- filename: 'foo.jpg',
52
- body: '123456789'
53
- )
54
- end
55
-
56
- def with_custom_postage_variables
57
- postageapp_template 'test-template'
58
- postageapp_variables 'variable' => 'value'
59
- postageapp_uid 'custom_uid'
60
- postageapp_api_key 'custom_api_key'
61
-
62
- from 'sender@example.com'
63
- subject 'Test Email'
64
-
65
- recipients(
66
- 'test1@example.net' => { 'name' => 'Test 1' },
67
- 'test2@example.net' => { 'name' => 'Test 2' }
68
- )
69
- end
70
-
71
- private
72
- def setup_headers
73
- recipients 'recipient@example.net'
74
- from 'sender@example.com'
75
- subject 'Test Email'
76
- end
77
- end
@@ -1 +0,0 @@
1
- html and text: plain text
@@ -1 +0,0 @@
1
- simple view content
@@ -1 +0,0 @@
1
- text only: plain text
@@ -1,95 +0,0 @@
1
- require_relative './helper'
2
-
3
- class Mailer2Test < MiniTest::Test
4
- require_action_mailer(2) do
5
- require File.expand_path('mailer/action_mailer_2/notifier', File.dirname(__FILE__))
6
-
7
- puts "\e[0m\e[32mRunning #{File.basename(__FILE__)} for action_mailer #{ActionMailer::VERSION::STRING}\e[0m"
8
-
9
- def test_create_blank
10
- assert mail = Notifier.create_blank
11
-
12
- assert_equal 'send_message', mail.method
13
- assert_equal 'https://api.postageapp.com/v.1.0/send_message.json', mail.url.to_s
14
- assert mail.arguments.blank?
15
- end
16
-
17
- def test_create_with_no_content
18
- assert mail = Notifier.create_with_no_content
19
-
20
- assert_equal 'recipient@example.net', mail.arguments['recipients']
21
- assert_equal({ 'from' => 'sender@example.com', 'subject' => 'Test Email' }, mail.arguments['headers'])
22
- assert mail.arguments['content'].blank?
23
- end
24
-
25
- def test_create_with_text_only_view
26
- assert mail = Notifier.create_with_text_only_view
27
-
28
- assert_equal 'text only: plain text', mail.arguments['content']['text/plain']
29
- end
30
-
31
- def test_create_with_html_and_text_views
32
- assert mail = Notifier.create_with_html_and_text_views
33
-
34
- assert_equal 'html and text: plain text', mail.arguments['content']['text/plain']
35
- assert_equal 'html and text: html', mail.arguments['content']['text/html']
36
- end
37
-
38
- def test_deliver_with_html_and_text_views
39
- mock_successful_send
40
-
41
- assert response = Notifier.deliver_with_html_and_text_views
42
-
43
- assert response.is_a?(PostageApp::Response)
44
- assert response.ok?
45
- end
46
-
47
- def test_create_with_simple_view
48
- assert mail = Notifier.create_with_simple_view
49
- assert_equal 'simple view content', mail.arguments['content']['text/plain']
50
- end
51
-
52
- def test_create_with_manual_parts
53
- assert mail = Notifier.create_with_manual_parts
54
-
55
- assert_equal 'text content', mail.arguments['content']['text/plain']
56
- assert_equal 'html content', mail.arguments['content']['text/html']
57
- assert !mail.arguments['attachments'].blank?
58
- assert !mail.arguments['attachments']['foo.jpg']['content'].blank?
59
- assert_equal 'image/jpeg', mail.arguments['attachments']['foo.jpg']['content_type']
60
- end
61
-
62
- def test_create_with_body_and_attachment
63
- assert mail = Notifier.create_with_body_and_attachment
64
-
65
- assert !mail.arguments['content'].blank?
66
- assert !mail.arguments['content']['text/plain'].blank?
67
- assert_equal 'body text', mail.arguments['content']['text/plain']
68
- assert !mail.arguments['attachments'].blank?
69
- assert !mail.arguments['attachments']['foo.jpg']['content'].blank?
70
- assert_equal 'image/jpeg', mail.arguments['attachments']['foo.jpg']['content_type']
71
- end
72
-
73
- def test_create_with_custom_postage_variables
74
- assert mail = Notifier.create_with_custom_postage_variables
75
-
76
- assert_equal 'custom_uid', mail.uid
77
- assert_equal 'custom_api_key', mail.api_key
78
- assert_equal 'test-template', mail.arguments['template']
79
- assert_equal({ 'variable' => 'value' }, mail.arguments['variables'])
80
- assert_equal({ 'test2@example.net' => { 'name' => 'Test 2'},
81
- 'test1@example.net' => { 'name' => 'Test 1'}}, mail.arguments['recipients'])
82
- assert_equal 'text content', mail.arguments['content']['text/plain']
83
- assert_equal 'html content', mail.arguments['content']['text/html']
84
- end
85
-
86
- def test_create_with_recipient_override
87
- PostageApp.configuration.recipient_override = 'override@example.net'
88
-
89
- assert mail = Notifier.create_with_html_and_text_views
90
-
91
- assert_equal 'recipient@example.net', mail.arguments['recipients']
92
- assert_equal 'override@example.net', mail.arguments_to_send['arguments']['recipient_override']
93
- end
94
- end
95
- end