mail-ses 0.1.2 → 1.0.2
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 +4 -4
- data/CHANGELOG.md +31 -12
- data/README.md +15 -13
- data/lib/mail/ses/message_validator.rb +42 -0
- data/lib/mail/ses/options_builder.rb +48 -0
- data/lib/mail/ses/version.rb +7 -0
- data/lib/mail/ses.rb +69 -89
- data/lib/mail-ses.rb +5 -4
- metadata +46 -20
- data/VERSION +0 -1
- data/spec/mail_ses_spec.rb +0 -182
- data/spec/spec_helper.rb +0 -18
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: fddb2a3546aea105c83d8821c73028dcd48916aef5975b78705eeb0de42ea4be
|
4
|
+
data.tar.gz: 0a6b2112dfc47c42e79c904f15a2afd0f084d8fd30e8e98a1705199b836ed848
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: f0efeb27830cdecb58aa115f9c5ff81e3ee1c9cbdda2bbf1ed7e274ed15cee139e3339e43d5d49056553fa0aa9c412f024000757b751ab6a6f9f1cc2f4c6347c
|
7
|
+
data.tar.gz: 0d1d76a3b7d37cf440438013271a7f177098c120dc019a51fc8c976ff8662d73739860913e842fe665a483c8cb1c5b59f402527237d1bb29a32f2cc0bde31d4d
|
data/CHANGELOG.md
CHANGED
@@ -1,12 +1,31 @@
|
|
1
|
-
#
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
1
|
+
# Changelog
|
2
|
+
|
3
|
+
### 1.0.2
|
4
|
+
|
5
|
+
- Fix labels in being stripped from email addresses.
|
6
|
+
- Support Reply-To address.
|
7
|
+
|
8
|
+
### 1.0.1
|
9
|
+
|
10
|
+
- Add compatibility with Mail gem 2.8.0.
|
11
|
+
|
12
|
+
### 1.0.0
|
13
|
+
|
14
|
+
- BREAKING CHANGE: Upgrade to AWS Ruby SDK v3 - SESv2 API ([@khrvi](https://github.com/khrvi))
|
15
|
+
- Drop support for Ruby 2.5 and earlier.
|
16
|
+
- Switch CI from Travis to Github Actions.
|
17
|
+
- Add Rubocop to CI.
|
18
|
+
- Refactor code.
|
19
|
+
|
20
|
+
### 0.1.2
|
21
|
+
|
22
|
+
- Fix: Add #settings method for conformity with other Mail delivery methods.
|
23
|
+
|
24
|
+
### 0.1.1
|
25
|
+
|
26
|
+
- Fix: Remove Base64 encoding from message body.
|
27
|
+
|
28
|
+
### 0.1.0
|
29
|
+
|
30
|
+
- Initial release of gem.
|
31
|
+
- Support for sending ActionMailer mails via AWS SDK v3.
|
data/README.md
CHANGED
@@ -1,23 +1,21 @@
|
|
1
1
|
[](http://badge.fury.io/rb/mail-ses)
|
2
|
-
[](https://github.com/tablecheck/mail-ses/actions/workflows/test.yml)
|
3
3
|
|
4
4
|
# Mail::SES
|
5
5
|
|
6
6
|
Mail::SES is a mail delivery method handler for Amazon SES (Simple Email Service) which can be used with Rails' [Action Mailer](https://guides.rubyonrails.org/action_mailer_basics.html).
|
7
7
|
|
8
8
|
This gem is inspired by [Drew Blas' AWS::SES gem](https://github.com/drewblas/aws-ses),
|
9
|
-
but uses the official [AWS SDK v3
|
9
|
+
but uses the official [AWS SDK for Ruby v3 - SESv2](https://docs.aws.amazon.com/sdk-for-ruby/v3/api/Aws/SESV2.html) under-the-hood.
|
10
10
|
By passing parameters through to the SDK, this gem supports greater flexibility with less code (including IAM instance profiles, retry parameters, etc.)
|
11
11
|
|
12
12
|
### Compatibility
|
13
13
|
|
14
|
-
* Ruby 2.
|
14
|
+
* Ruby 2.6+
|
15
15
|
* Ruby on Rails 3.2+
|
16
|
-
* AWS SDK v3
|
16
|
+
* AWS SDK for Ruby v3 - SESv2
|
17
17
|
|
18
|
-
|
19
|
-
|
20
|
-
ActionMailer::SES is sponsored by [TableCheck](http://corp.tablecheck.com/), Japan's leading restaurant management app. If **you** are a ninja-level Javascript/Ruby coder, designer, project manager, etc. and are eager to work in Tokyo with other ninjas, Japan in a dynamic environment, please get in touch at [careers@tablecheck.com](mailto:careers@tablecheck.com).
|
18
|
+
Please use version 0.1.x of this gem for legacy Ruby and AWS SDK support.
|
21
19
|
|
22
20
|
## Getting Started
|
23
21
|
|
@@ -46,7 +44,7 @@ config.action_mailer.delivery_method = :ses
|
|
46
44
|
|
47
45
|
### AWS SES Client Options
|
48
46
|
|
49
|
-
Any options supported by the `Aws::
|
47
|
+
Any options supported by the `Aws::SESV2::Client` class can be passed into the initializer, for example:
|
50
48
|
|
51
49
|
```ruby
|
52
50
|
ActionMailer::Base.add_delivery_method :ses, Mail::SES,
|
@@ -72,8 +70,8 @@ In the initializer you can set `:mail_options (Hash)` which are default options
|
|
72
70
|
ActionMailer::Base.add_delivery_method :ses, Mail::SES,
|
73
71
|
# ...
|
74
72
|
mail_options: {
|
75
|
-
|
76
|
-
|
73
|
+
from_email_address_identity_arn: 'arn:aws:ses:us-east-1:123456789012:identity/example.com',
|
74
|
+
email_tags: [
|
77
75
|
{ name: 'MessageTagName', value: 'MessageTagValue' },
|
78
76
|
],
|
79
77
|
}
|
@@ -105,7 +103,7 @@ ses = Mail::SES.new(region: 'us-east-1',
|
|
105
103
|
access_key_id: 'abc',
|
106
104
|
secret_access_key: '123')
|
107
105
|
|
108
|
-
options = {
|
106
|
+
options = { from_email_address_identity_arn: 'arn:aws:ses:us-east-1:123456789012:identity/example.com' }
|
109
107
|
|
110
108
|
ses.deliver!(mail, options) #=> returns AWS API response
|
111
109
|
|
@@ -114,10 +112,14 @@ mail.message_id #=> "00000138111222aa-33322211-cccc-cccc-cccc-ddddaaaa0680-00000
|
|
114
112
|
|
115
113
|
Please also see the [AWS SDK v3 for SES](https://docs.aws.amazon.com/ses/latest/DeveloperGuide/send-using-sdk-ruby.html) for alternate approaches.
|
116
114
|
|
117
|
-
|
115
|
+
### Statistics, Verified Addresses, Bounce Rate, etc.
|
118
116
|
|
119
117
|
Please use the official [AWS SDK v3 for SES](https://docs.aws.amazon.com/ses/latest/DeveloperGuide/send-using-sdk-ruby.html).
|
120
118
|
|
119
|
+
## Shameless Plug
|
120
|
+
|
121
|
+
Mail::SES is sponsored by [TableCheck](http://www.tablecheck.com/en/company/), Japan's leading restaurant management app. If **you** are a ninja-level Javascript/Ruby coder, designer, project manager, etc. and are eager to work in Tokyo with other ninjas, Japan in a dynamic environment, please get in touch at [careers@tablecheck.com](mailto:careers@tablecheck.com).
|
122
|
+
|
121
123
|
## Copyright
|
122
124
|
|
123
|
-
Copyright (c) 2018 TableCheck Inc. See LICENSE for further details.
|
125
|
+
Copyright (c) 2018 [TableCheck Inc.](http://www.tablecheck.com/en/company/) See LICENSE for further details.
|
@@ -0,0 +1,42 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Mail
|
4
|
+
class SES
|
5
|
+
# Validates a Mail::Message object before sending
|
6
|
+
class MessageValidator
|
7
|
+
# message - The Mail::Message object to be validated.
|
8
|
+
def initialize(message)
|
9
|
+
@message = message
|
10
|
+
end
|
11
|
+
|
12
|
+
# Validate the message.
|
13
|
+
def validate
|
14
|
+
validate_class
|
15
|
+
validate_delivery_params
|
16
|
+
validate_attachments
|
17
|
+
end
|
18
|
+
|
19
|
+
private
|
20
|
+
|
21
|
+
def validate_class
|
22
|
+
return if @message.is_a?(Mail::Message)
|
23
|
+
|
24
|
+
raise ArgumentError.new('mail must be an instance of Mail::Message class')
|
25
|
+
end
|
26
|
+
|
27
|
+
def validate_delivery_params
|
28
|
+
if defined?(Mail::CheckDeliveryParams) # mail gem < 2.7.0
|
29
|
+
Mail::CheckDeliveryParams.check(@message)
|
30
|
+
elsif defined?(Mail::SmtpEnvelope) # mail gem >= 2.8.0
|
31
|
+
Mail::SmtpEnvelope.new(@message)
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
def validate_attachments
|
36
|
+
return unless @message.has_attachments? && @message.text_part.nil? && @message.html_part.nil?
|
37
|
+
|
38
|
+
raise ArgumentError.new('Attachment provided without message body')
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
@@ -0,0 +1,48 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Mail
|
4
|
+
class SES
|
5
|
+
# Builds options for Aws::SESV2::Client#send_email
|
6
|
+
class OptionsBuilder
|
7
|
+
# message - The Mail::Message object to be sent.
|
8
|
+
# options - The Hash options which override any defaults
|
9
|
+
# from the message.
|
10
|
+
def initialize(message, options = {})
|
11
|
+
@message = message
|
12
|
+
@options = options
|
13
|
+
end
|
14
|
+
|
15
|
+
# Returns the options for Aws::SESV2::Client#send_email.
|
16
|
+
def build
|
17
|
+
message_options.merge(ses_options)
|
18
|
+
end
|
19
|
+
|
20
|
+
private
|
21
|
+
|
22
|
+
def ses_options
|
23
|
+
slice_hash(@options, *RAW_EMAIL_ATTRS)
|
24
|
+
end
|
25
|
+
|
26
|
+
def message_options
|
27
|
+
{
|
28
|
+
from_email_address: extract_value(:from)&.first,
|
29
|
+
reply_to_addresses: extract_value(:reply_to),
|
30
|
+
destination: {
|
31
|
+
to_addresses: extract_value(:to) || [],
|
32
|
+
cc_addresses: extract_value(:cc) || [],
|
33
|
+
bcc_addresses: extract_value(:bcc) || []
|
34
|
+
},
|
35
|
+
content: { raw: { data: @message.to_s } }
|
36
|
+
}.compact
|
37
|
+
end
|
38
|
+
|
39
|
+
def slice_hash(hash, *keys)
|
40
|
+
keys.each_with_object({}) { |k, h| h[k] = hash[k] if hash.key?(k) }
|
41
|
+
end
|
42
|
+
|
43
|
+
def extract_value(key)
|
44
|
+
@message.header[key]&.formatted
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
data/lib/mail/ses.rb
CHANGED
@@ -1,89 +1,69 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
#
|
22
|
-
#
|
23
|
-
#
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
options[:credentials] = Aws::InstanceProfileCredentials.new if options.delete(:use_iam_profile)
|
71
|
-
options
|
72
|
-
end
|
73
|
-
|
74
|
-
def build_raw_email_options(message, options = {})
|
75
|
-
output = slice_hash(options, *RAW_EMAIL_ATTRS)
|
76
|
-
output[:source] ||= message.from.first
|
77
|
-
output[:destinations] = [message.to, message.cc, message.bcc].flatten.compact
|
78
|
-
output[:raw_message] = { data: message.to_s }
|
79
|
-
output
|
80
|
-
end
|
81
|
-
|
82
|
-
protected
|
83
|
-
|
84
|
-
def slice_hash(hash, *keys)
|
85
|
-
keys.each_with_object({}) { |k, h| h[k] = hash[k] if hash.key?(k) }
|
86
|
-
end
|
87
|
-
end
|
88
|
-
end
|
89
|
-
end
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'mail/ses/version'
|
4
|
+
require 'mail/ses/message_validator'
|
5
|
+
require 'mail/ses/options_builder'
|
6
|
+
|
7
|
+
module Mail
|
8
|
+
# Mail delivery method handler for AWS SES
|
9
|
+
class SES
|
10
|
+
RAW_EMAIL_ATTRS = %i[ from_email_address
|
11
|
+
from_email_address_identity_arn
|
12
|
+
reply_to_addresses
|
13
|
+
feedback_forwarding_email_address
|
14
|
+
feedback_forwarding_email_address_identity_arn
|
15
|
+
email_tags
|
16
|
+
configuration_set_name ].freeze
|
17
|
+
|
18
|
+
attr_accessor :settings
|
19
|
+
attr_reader :client
|
20
|
+
|
21
|
+
# Initializes the Mail::SES object.
|
22
|
+
#
|
23
|
+
# options - The Hash options (optional, default: {}):
|
24
|
+
# :mail_options - (Hash) Default AWS options to set on each mail object.
|
25
|
+
# :error_handler - (Proc<Error, Hash>) Handler for AWS API errors.
|
26
|
+
# :use_iam_profile - Shortcut to use AWS IAM instance profile.
|
27
|
+
# All other options are passed-thru to Aws::SESV2::Client.
|
28
|
+
def initialize(options = {})
|
29
|
+
@mail_options = options.delete(:mail_options) || {}
|
30
|
+
|
31
|
+
@error_handler = options.delete(:error_handler)
|
32
|
+
raise ArgumentError.new(':error_handler must be a Proc') if @error_handler && !@error_handler.is_a?(Proc)
|
33
|
+
|
34
|
+
@settings = { return_response: options.delete(:return_response) }
|
35
|
+
|
36
|
+
options[:credentials] = Aws::InstanceProfileCredentials.new if options.delete(:use_iam_profile)
|
37
|
+
@client = Aws::SESV2::Client.new(options)
|
38
|
+
end
|
39
|
+
|
40
|
+
# Delivers a Mail::Message object via SES.
|
41
|
+
#
|
42
|
+
# message - The Mail::Message object to deliver (required).
|
43
|
+
# options - The Hash options which override any defaults set in :mail_options
|
44
|
+
# in the initializer (optional, default: {}). Refer to
|
45
|
+
# Aws::SESV2::Client#send_email
|
46
|
+
def deliver!(message, options = {})
|
47
|
+
MessageValidator.new(message).validate
|
48
|
+
|
49
|
+
options = @mail_options.merge(options || {})
|
50
|
+
send_options = OptionsBuilder.new(message, options).build
|
51
|
+
|
52
|
+
begin
|
53
|
+
response = client.send_email(send_options)
|
54
|
+
message.message_id = "#{response.to_h[:message_id]}@email.amazonses.com"
|
55
|
+
settings[:return_response] ? response : self
|
56
|
+
rescue StandardError => e
|
57
|
+
handle_error(e, send_options)
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
private
|
62
|
+
|
63
|
+
def handle_error(error, send_options)
|
64
|
+
raise(error) unless @error_handler
|
65
|
+
|
66
|
+
@error_handler.call(error, send_options.dup)
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
data/lib/mail-ses.rb
CHANGED
@@ -1,4 +1,5 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require '
|
4
|
-
require 'mail
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'aws-sdk-sesv2'
|
4
|
+
require 'mail'
|
5
|
+
require 'mail/ses'
|
metadata
CHANGED
@@ -1,29 +1,29 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: mail-ses
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 1.0.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Johnny Shields
|
8
|
-
autorequire:
|
8
|
+
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2022-06-29 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
|
-
name: aws-sdk-
|
14
|
+
name: aws-sdk-sesv2
|
15
15
|
requirement: !ruby/object:Gem::Requirement
|
16
16
|
requirements:
|
17
17
|
- - ">="
|
18
18
|
- !ruby/object:Gem::Version
|
19
|
-
version: '1.
|
19
|
+
version: '1.27'
|
20
20
|
type: :runtime
|
21
21
|
prerelease: false
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
23
23
|
requirements:
|
24
24
|
- - ">="
|
25
25
|
- !ruby/object:Gem::Version
|
26
|
-
version: '1.
|
26
|
+
version: '1.27'
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
28
|
name: mail
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
@@ -38,6 +38,34 @@ dependencies:
|
|
38
38
|
- - ">="
|
39
39
|
- !ruby/object:Gem::Version
|
40
40
|
version: 2.2.5
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: net-smtp
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - ">="
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '0'
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - ">="
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '0'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: nokogiri
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - ">="
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0'
|
62
|
+
type: :development
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - ">="
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '0'
|
41
69
|
- !ruby/object:Gem::Dependency
|
42
70
|
name: rake
|
43
71
|
requirement: !ruby/object:Gem::Requirement
|
@@ -72,14 +100,14 @@ dependencies:
|
|
72
100
|
requirements:
|
73
101
|
- - "~>"
|
74
102
|
- !ruby/object:Gem::Version
|
75
|
-
version:
|
103
|
+
version: 1.30.1
|
76
104
|
type: :development
|
77
105
|
prerelease: false
|
78
106
|
version_requirements: !ruby/object:Gem::Requirement
|
79
107
|
requirements:
|
80
108
|
- - "~>"
|
81
109
|
- !ruby/object:Gem::Version
|
82
|
-
version:
|
110
|
+
version: 1.30.1
|
83
111
|
description: Ruby Mail delivery method handler for Amazon SES
|
84
112
|
email: info@tablecheck.com
|
85
113
|
executables: []
|
@@ -89,16 +117,17 @@ files:
|
|
89
117
|
- CHANGELOG.md
|
90
118
|
- LICENSE
|
91
119
|
- README.md
|
92
|
-
- VERSION
|
93
120
|
- lib/mail-ses.rb
|
94
121
|
- lib/mail/ses.rb
|
95
|
-
-
|
96
|
-
-
|
122
|
+
- lib/mail/ses/message_validator.rb
|
123
|
+
- lib/mail/ses/options_builder.rb
|
124
|
+
- lib/mail/ses/version.rb
|
97
125
|
homepage: https://github.com/tablecheck/mail-ses
|
98
126
|
licenses:
|
99
127
|
- MIT
|
100
|
-
metadata:
|
101
|
-
|
128
|
+
metadata:
|
129
|
+
rubygems_mfa_required: 'true'
|
130
|
+
post_install_message:
|
102
131
|
rdoc_options: []
|
103
132
|
require_paths:
|
104
133
|
- lib
|
@@ -106,18 +135,15 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
106
135
|
requirements:
|
107
136
|
- - ">="
|
108
137
|
- !ruby/object:Gem::Version
|
109
|
-
version:
|
138
|
+
version: 2.6.0
|
110
139
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
111
140
|
requirements:
|
112
141
|
- - ">="
|
113
142
|
- !ruby/object:Gem::Version
|
114
143
|
version: '0'
|
115
144
|
requirements: []
|
116
|
-
|
117
|
-
|
118
|
-
signing_key:
|
145
|
+
rubygems_version: 3.3.13
|
146
|
+
signing_key:
|
119
147
|
specification_version: 4
|
120
148
|
summary: Ruby Mail delivery method handler for Amazon SES
|
121
|
-
test_files:
|
122
|
-
- spec/mail_ses_spec.rb
|
123
|
-
- spec/spec_helper.rb
|
149
|
+
test_files: []
|
data/VERSION
DELETED
@@ -1 +0,0 @@
|
|
1
|
-
0.1.2
|
data/spec/mail_ses_spec.rb
DELETED
@@ -1,182 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
require 'spec_helper'
|
3
|
-
|
4
|
-
RSpec.describe Mail::SES do
|
5
|
-
let(:ses_options) { { stub_responses: true } }
|
6
|
-
|
7
|
-
let(:ses) do
|
8
|
-
described_class.new(ses_options)
|
9
|
-
end
|
10
|
-
|
11
|
-
let(:mail) do
|
12
|
-
Mail.new do
|
13
|
-
from 'from@abc.com'
|
14
|
-
to %w[to1@def.com to2@xyz.com]
|
15
|
-
cc %w[cc1@xyz.com cc2@def.com]
|
16
|
-
bcc %w[bcc1@abc.com bcc2@def.com]
|
17
|
-
body 'This is the body'
|
18
|
-
end
|
19
|
-
end
|
20
|
-
|
21
|
-
describe '::VERSION' do
|
22
|
-
it { expect(described_class::VERSION).to match(/\A\d+\.\d+\.\d+/) }
|
23
|
-
end
|
24
|
-
|
25
|
-
describe '#settings' do
|
26
|
-
it do
|
27
|
-
expect(ses).to respond_to(:settings, :settings=)
|
28
|
-
expect(ses.settings).to eq(return_response: nil)
|
29
|
-
end
|
30
|
-
end
|
31
|
-
|
32
|
-
describe '#initialize' do
|
33
|
-
it 'accepts valid :error_handler' do
|
34
|
-
expect(described_class.new(ses_options)).to be_a(Mail::SES)
|
35
|
-
end
|
36
|
-
|
37
|
-
it 'accepts valid :error_handler' do
|
38
|
-
expect(described_class.new(ses_options.merge(error_handler: ->(a, b) {}))).to be_a(Mail::SES)
|
39
|
-
end
|
40
|
-
|
41
|
-
it 'rejects invalid :error_handler' do
|
42
|
-
expect { described_class.new(ses_options.merge(error_handler: 'foobar')) }.to raise_error(ArgumentError, ':error_handler must be a Proc')
|
43
|
-
end
|
44
|
-
|
45
|
-
it 'handles :use_iam_profile option' do
|
46
|
-
allow_any_instance_of(Aws::InstanceProfileCredentials).to receive(:get_credentials).and_return('{}')
|
47
|
-
ses = described_class.new(ses_options.merge(use_iam_profile: true))
|
48
|
-
expect(ses.client.config.credentials).to be_a(Aws::InstanceProfileCredentials)
|
49
|
-
end
|
50
|
-
|
51
|
-
it 'passes through options to AWS' do
|
52
|
-
ses = described_class.new(ses_options.merge(log_level: :debug, retry_limit: 5))
|
53
|
-
expect(ses.client.config.log_level).to eq :debug
|
54
|
-
expect(ses.client.config.retry_limit).to eq 5
|
55
|
-
end
|
56
|
-
end
|
57
|
-
|
58
|
-
describe '#deliver!' do
|
59
|
-
it 'validates that mail is a Mail' do
|
60
|
-
expect { ses.deliver!(foo: :bar) }.to raise_error(ArgumentError, 'mail must be an instance of Mail::Message class')
|
61
|
-
end
|
62
|
-
|
63
|
-
it 'validates integrity of Mail' do
|
64
|
-
expect { ses.deliver!(Mail.new) }.to raise_error(ArgumentError, 'SMTP From address may not be blank: nil')
|
65
|
-
expect { ses.deliver!(Mail.new { from 'foo@bar.com' }) }.to raise_error(ArgumentError, 'SMTP To address may not be blank: []')
|
66
|
-
end
|
67
|
-
|
68
|
-
it 'validates attachment without body' do
|
69
|
-
mail.body = nil
|
70
|
-
mail.add_file __FILE__
|
71
|
-
expect { ses.deliver!(mail) }.to raise_error(ArgumentError, 'Attachment provided without message body')
|
72
|
-
end
|
73
|
-
|
74
|
-
context 'when options set' do
|
75
|
-
before { allow(mail).to receive(:to_s).and_return('Fixed message body') }
|
76
|
-
let(:ses_options) { { stub_responses: true, mail_options: { source: 'foo@bar.com', source_arn: 'sa1' } } }
|
77
|
-
|
78
|
-
let(:exp) do
|
79
|
-
{
|
80
|
-
source: 'foo@bar.com',
|
81
|
-
source_arn: 'sa2',
|
82
|
-
destinations: %w[to1@def.com to2@xyz.com cc1@xyz.com cc2@def.com bcc1@abc.com bcc2@def.com],
|
83
|
-
raw_message: {
|
84
|
-
data: 'Fixed message body'
|
85
|
-
}
|
86
|
-
}
|
87
|
-
end
|
88
|
-
|
89
|
-
it 'allows pass-thru and override of default options' do
|
90
|
-
expect(ses.client).to receive(:send_raw_email).with(exp)
|
91
|
-
ses.deliver!(mail, source_arn: 'sa2')
|
92
|
-
end
|
93
|
-
end
|
94
|
-
|
95
|
-
it 'sets mail.message_id' do
|
96
|
-
ses.deliver!(mail)
|
97
|
-
expect(mail.message_id).to eq('MessageId@email.amazonses.com')
|
98
|
-
end
|
99
|
-
|
100
|
-
it 'returns the AWS response' do
|
101
|
-
expect(ses.deliver!(mail)).to be_a(Mail::SES)
|
102
|
-
end
|
103
|
-
|
104
|
-
context 'when :return_response set' do
|
105
|
-
let(:ses_options) { { stub_responses: true, return_response: true } }
|
106
|
-
|
107
|
-
it 'returns the AWS response' do
|
108
|
-
expect(ses.deliver!(mail)).to be_a(Seahorse::Client::Response)
|
109
|
-
end
|
110
|
-
end
|
111
|
-
|
112
|
-
context 'error handling' do
|
113
|
-
before { allow_any_instance_of(Aws::SES::Client).to receive(:send_raw_email).and_raise(RuntimeError.new('test')) }
|
114
|
-
|
115
|
-
context 'when :error_handler not set' do
|
116
|
-
it 'raises the error' do
|
117
|
-
expect { ses.deliver!(mail) }.to raise_error(RuntimeError, 'test')
|
118
|
-
end
|
119
|
-
end
|
120
|
-
|
121
|
-
context 'when :error_handler set' do
|
122
|
-
let(:ses_options) { { stub_responses: true, error_handler: ->(a, b) {} } }
|
123
|
-
|
124
|
-
it 'calls the error handler' do
|
125
|
-
expect(ses_options[:error_handler]).to receive(:call).and_call_original
|
126
|
-
ses.deliver!(mail)
|
127
|
-
end
|
128
|
-
end
|
129
|
-
end
|
130
|
-
end
|
131
|
-
|
132
|
-
describe '::build_raw_email_options' do
|
133
|
-
let(:options) { {} }
|
134
|
-
subject { described_class.build_raw_email_options(mail, options) }
|
135
|
-
before { allow(mail).to receive(:to_s).and_return('Fixed message body') }
|
136
|
-
|
137
|
-
context 'without options' do
|
138
|
-
let(:exp) do
|
139
|
-
{
|
140
|
-
source: 'from@abc.com',
|
141
|
-
destinations: %w[to1@def.com to2@xyz.com cc1@xyz.com cc2@def.com bcc1@abc.com bcc2@def.com],
|
142
|
-
raw_message: {
|
143
|
-
data: 'Fixed message body'
|
144
|
-
}
|
145
|
-
}
|
146
|
-
end
|
147
|
-
|
148
|
-
it { expect(subject).to eq(exp) }
|
149
|
-
end
|
150
|
-
|
151
|
-
context 'with options' do
|
152
|
-
let(:options) do
|
153
|
-
{ source: 'source@source.com',
|
154
|
-
source_arn: 'source_arn',
|
155
|
-
from_arn: 'from_arn',
|
156
|
-
return_path_arn: 'return_path_arn',
|
157
|
-
tags: [{ name: 'Name', value: 'Value' }],
|
158
|
-
configuration_set_name: 'configuration_set_name',
|
159
|
-
other: 'other' }
|
160
|
-
end
|
161
|
-
|
162
|
-
let(:exp) do
|
163
|
-
{
|
164
|
-
source: 'source@source.com',
|
165
|
-
source_arn: 'source_arn',
|
166
|
-
from_arn: 'from_arn',
|
167
|
-
return_path_arn: 'return_path_arn',
|
168
|
-
tags: [
|
169
|
-
{ name: 'Name', value: 'Value' }
|
170
|
-
],
|
171
|
-
configuration_set_name: 'configuration_set_name',
|
172
|
-
destinations: %w[to1@def.com to2@xyz.com cc1@xyz.com cc2@def.com bcc1@abc.com bcc2@def.com],
|
173
|
-
raw_message: {
|
174
|
-
data: 'Fixed message body'
|
175
|
-
}
|
176
|
-
}
|
177
|
-
end
|
178
|
-
|
179
|
-
it { expect(subject).to eq(exp) }
|
180
|
-
end
|
181
|
-
end
|
182
|
-
end
|
data/spec/spec_helper.rb
DELETED
@@ -1,18 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
require 'rubygems'
|
3
|
-
require 'bundler/setup'
|
4
|
-
require 'rspec'
|
5
|
-
|
6
|
-
Bundler.setup
|
7
|
-
|
8
|
-
require 'mail-ses'
|
9
|
-
|
10
|
-
RSpec.configure do |config|
|
11
|
-
config.disable_monkey_patching!
|
12
|
-
|
13
|
-
config.default_formatter = 'doc' if config.files_to_run.one?
|
14
|
-
|
15
|
-
config.order = :random
|
16
|
-
|
17
|
-
Kernel.srand config.seed
|
18
|
-
end
|