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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 91f1a759b15653521f07851f6706c4b9ed80eca19856e80033cb2052b42c0780
4
- data.tar.gz: 923dacd96e29ca65e552214e8113e1ab56da0f5d27d0a0e28792a6d6e980eee4
3
+ metadata.gz: fddb2a3546aea105c83d8821c73028dcd48916aef5975b78705eeb0de42ea4be
4
+ data.tar.gz: 0a6b2112dfc47c42e79c904f15a2afd0f084d8fd30e8e98a1705199b836ed848
5
5
  SHA512:
6
- metadata.gz: 1b7321575bb49c5da7599a7c79e2db8f74cb18a5536eb78f40e49b774bec91c638dd59d91ef64a757b18fe879b65f90c6bb3b64038e9514fb881b419262dc475
7
- data.tar.gz: 4e5c2cf40f609d9fe5ecfceb47b43f83a7c25a58d20c978ae4d26f5393f5c7a6688bb90a25fabd2222cb2f41e6d6e2064137c9c33a3ac08276a9d7a404233519
6
+ metadata.gz: f0efeb27830cdecb58aa115f9c5ff81e3ee1c9cbdda2bbf1ed7e274ed15cee139e3339e43d5d49056553fa0aa9c412f024000757b751ab6a6f9f1cc2f4c6347c
7
+ data.tar.gz: 0d1d76a3b7d37cf440438013271a7f177098c120dc019a51fc8c976ff8662d73739860913e842fe665a483c8cb1c5b59f402527237d1bb29a32f2cc0bde31d4d
data/CHANGELOG.md CHANGED
@@ -1,12 +1,31 @@
1
- # 0.1.2
2
-
3
- - Fix: Add #settings method for conformity with other Mail delivery methods.
4
-
5
- # 0.1.1
6
-
7
- - Fix: Remove Base64 encoding from message body.
8
-
9
- # 0.1.0
10
-
11
- - Initial release of gem.
12
- - Support for sending ActionMailer mails via AWS SDK v3.
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
  [![Gem Version](https://badge.fury.io/rb/mail-ses.svg)](http://badge.fury.io/rb/mail-ses)
2
- [![Travis Status](https://travis-ci.org/tablecheck/mail-ses.svg?branch=master)](https://travis-ci.org/tablecheck/mail-ses)
2
+ [![Github Actions](https://github.com/tablecheck/mail-ses/actions/workflows/test.yml/badge.svg)](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 for SES](https://docs.aws.amazon.com/ses/latest/DeveloperGuide/send-using-sdk-ruby.html) under-the-hood.
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.1+
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
- ### Shameless Plug
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::SES::Client` class can be passed into the initializer, for example:
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
- source_arn: 'arn:aws:ses:us-east-1:123456789012:identity/example.com',
76
- tags: [
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 = { source_arn: 'arn:aws:ses:us-east-1:123456789012:identity/example.com' }
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
- ## Statistics, Verified Addresses, Bounce Rate, etc.
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
@@ -0,0 +1,7 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Mail
4
+ class SES
5
+ VERSION = '1.0.2'
6
+ end
7
+ end
data/lib/mail/ses.rb CHANGED
@@ -1,89 +1,69 @@
1
- # frozen_string_literal: true
2
- module Mail
3
- # Mail delivery method handler for AWS SES
4
- class SES
5
- VERSION = File.read(File.join(File.dirname(__FILE__), '../../VERSION')).strip.freeze
6
-
7
- RAW_EMAIL_ATTRS = %i[ source
8
- source_arn
9
- from_arn
10
- return_path_arn
11
- tags
12
- configuration_set_name ].freeze
13
-
14
- attr_accessor :settings
15
- attr_reader :client
16
-
17
- # Initializes the Mail::SES object.
18
- #
19
- # options - The Hash options (optional, default: {}):
20
- # :mail_options - (Hash) Default AWS options to set on each mail object.
21
- # :error_handler - (Proc<Error, Hash>) Handler for AWS API errors.
22
- # :use_iam_profile - Shortcut to use AWS IAM instance profile.
23
- # All other options are passed-thru to Aws::SES::Client.
24
- def initialize(options = {})
25
- @mail_options = options.delete(:mail_options) || {}
26
- @error_handler = options.delete(:error_handler)
27
- @settings = { return_response: options.delete(:return_response) }
28
- self.class.validate_error_handler(@error_handler)
29
- options = self.class.build_client_options(options)
30
- @client = Aws::SES::Client.new(options)
31
- end
32
-
33
- # Delivers a Mail object via SES.
34
- #
35
- # mail - The Mail object to deliver (required).
36
- # options - The Hash options which override any defaults set in :mail_options
37
- # in the initializer (optional, default: {}). Refer to
38
- # Aws::SES::Client#send_raw_email
39
- def deliver!(mail, options = {})
40
- self.class.validate_mail(mail)
41
- options = @mail_options.merge(options || {})
42
- raw_email_options = self.class.build_raw_email_options(mail, options)
43
- begin
44
- response = client.send_raw_email(raw_email_options)
45
- mail.message_id = "#{response.to_h[:message_id]}@email.amazonses.com"
46
- settings[:return_response] ? response : self
47
- rescue StandardError => e
48
- @error_handler ? @error_handler.call(e, raw_email_options.dup) : raise(e)
49
- end
50
- end
51
-
52
- class << self
53
- def validate_error_handler(error_handler)
54
- raise ArgumentError.new(':error_handler must be a Proc') if error_handler && !error_handler.is_a?(Proc)
55
- end
56
-
57
- def validate_mail(mail)
58
- unless mail.is_a?(Mail::Message)
59
- raise ArgumentError.new('mail must be an instance of Mail::Message class')
60
- end
61
-
62
- Mail::CheckDeliveryParams.check(mail)
63
-
64
- if mail.has_attachments? && mail.text_part.nil? && mail.html_part.nil?
65
- raise ArgumentError.new('Attachment provided without message body')
66
- end
67
- end
68
-
69
- def build_client_options(options)
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
- require 'aws-sdk-ses'
3
- require 'mail'
4
- require 'mail/ses'
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.1.2
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: 2018-08-19 00:00:00.000000000 Z
11
+ date: 2022-06-29 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
- name: aws-sdk-ses
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.8'
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.8'
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: 0.57.0
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: 0.57.0
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
- - spec/mail_ses_spec.rb
96
- - spec/spec_helper.rb
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
- post_install_message:
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: '0'
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
- rubyforge_project:
117
- rubygems_version: 2.7.3
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
@@ -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