diff --git a/CHANGELOG.md b/CHANGELOG.md index 276f5c1c..fef55a14 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -19,6 +19,10 @@ Unreleased Changes * Issue - Do not skip autoload modules for `Aws::Rails.instrument_sdk_operations`. +* Issue - Add deprecation warning to `Aws::Rails.add_action_mailer_delivery_method` to instead use `ActionMailer::Base.add_delivery_method`. + +* Feature - New namespace and class names for SES and SESV2 mailers. Existing namespace has temporarily been kept for backward compatibility. These now live in the `aws-actionmailer-ses` gem. + 4.1.0 (2024-09-27) ------------------ diff --git a/Gemfile b/Gemfile index 7d2b5aeb..60171840 100644 --- a/Gemfile +++ b/Gemfile @@ -4,6 +4,8 @@ source 'https://rubygems.org' gemspec +gem 'aws-actionmailer-ses', git: 'https://github.com/aws/aws-actionmailer-ses-ruby' + group :development, :test do gem 'pry' end diff --git a/README.md b/README.md index 9b7704d9..bbc3c885 100644 --- a/README.md +++ b/README.md @@ -202,14 +202,24 @@ use the provided Rake task: rake dynamo_db:session_store:clean ``` -## Amazon Simple Email Service (SES) as an ActionMailer Delivery Method +## ActionMailer delivery with Amazon Simple Email Service -This gem will automatically register SES and SESV2 as ActionMailer delivery methods. -You simply need to configure Rails to use it in your environment configuration: +This gem contains Mailer classes for Amazon SES and SESV2. To use these mailers +as a delivery method, you need to register them with ActionMailer. +You can create a Rails initializer `config/initializers/action_mailer.rb` +with contents similar to the following: ```ruby -# for e.g.: config/environments/production.rb -config.action_mailer.delivery_method = :ses # or :sesv2 +options = { region: 'us-west-2' } +ActionMailer::Base.add_delivery_method :ses, Aws::ActionMailer::SESMailer, **options +ActionMailer::Base.add_delivery_method :ses_v2, Aws::ActionMailer::SESV2Mailer, **options +``` + +In your environment configuration, set the delivery method to +`:ses` or `:ses_v2`. + +```ruby +config.action_mailer.delivery_method = :ses # or :ses_v2 ``` ## Amazon Simple Email Service (SES) as an ActionMailbox Method @@ -297,32 +307,6 @@ You may also pass the following keyword arguments to both helpers: * `topic`: The _SNS_ topic used for each notification (default: `topic:arn:default`). * `authentic`: The `Aws::SNS::MessageVerifier` class is stubbed by these helpers; set `authentic` to `true` or `false` to define how it will verify incoming notifications (default: `true`). -### Override credentials or other client options - -Client options can be overridden by re-registering the mailer with any set of -SES or SESV2 Client options. You can create a Rails initializer -`config/initializers/aws.rb` with contents similar to the following: - -```ruby -require 'json' - -# Assuming a file "path/to/aws_secrets.json" with contents like: -# -# { "AccessKeyId": "YOUR_KEY_ID", "SecretAccessKey": "YOUR_ACCESS_KEY" } -# -# Remember to exclude "path/to/aws_secrets.json" from version control, e.g. by -# adding it to .gitignore -secrets = JSON.load(File.read('path/to/aws_secrets.json')) -creds = Aws::Credentials.new(secrets['AccessKeyId'], secrets['SecretAccessKey']) - -Aws::Rails.add_action_mailer_delivery_method( - :ses, # or :sesv2 - credentials: creds, - region: 'us-east-1', - # some other config -) -``` - ### Using ARNs with SES This gem uses [\`Aws::SES::Client#send_raw_email\`](https://docs.aws.amazon.com/sdk-for-ruby/v3/api/Aws/SES/Client.html#send_raw_email-instance_method) diff --git a/aws-sdk-rails.gemspec b/aws-sdk-rails.gemspec index b1410ec5..1472c556 100644 --- a/aws-sdk-rails.gemspec +++ b/aws-sdk-rails.gemspec @@ -15,13 +15,12 @@ Gem::Specification.new do |spec| spec.executables = ['aws_sqs_active_job'] # These will be removed in aws-sdk-rails ~> 5 + spec.add_dependency('aws-actionmailer-ses', '~> 0') spec.add_dependency('aws-record', '~> 2') # for Aws::Record integration spec.add_dependency('aws-sessionstore-dynamodb', '~> 3') # includes DynamoDB # Require these versions for user_agent_framework configs spec.add_dependency('aws-sdk-s3', '~> 1', '>= 1.123.0') - spec.add_dependency('aws-sdk-ses', '~> 1', '>= 1.50.0') # for ActionMailer - spec.add_dependency('aws-sdk-sesv2', '~> 1', '>= 1.34.0') # for ActionMailer spec.add_dependency('aws-sdk-sns', '~> 1', '>= 1.61.0') # for ActionMailbox spec.add_dependency('aws-sdk-sqs', '~> 1', '>= 1.56.0') # for ActiveJob diff --git a/lib/action_dispatch/session/dynamo_db_store.rb b/lib/action_dispatch/session/dynamo_db_store.rb index bfc02943..ce4df481 100644 --- a/lib/action_dispatch/session/dynamo_db_store.rb +++ b/lib/action_dispatch/session/dynamo_db_store.rb @@ -18,9 +18,11 @@ module Session # @see https://docs.aws.amazon.com/sdk-for-ruby/aws-sessionstore-dynamodb/api/Aws/SessionStore/DynamoDB/Configuration.html class DynamoDbStore < ActionDispatch::Session::AbstractStore def initialize(app, options = {}) - Rails.logger.warn('** aws-sessionstore-dynamodb will no longer be a direct dependency of aws-sdk-rails ~> 5. ' \ - 'To avoid disruption, please add aws-sessionstore-dynamodb ~> 3 to your Gemfile to enable ' \ - 'this feature when upgrading to aws-sdk-rails ~> 5. **') + Rails.logger.warn(<<~MSG) + ** aws-sessionstore-dynamodb will no longer be a direct dependency of aws-sdk-rails ~> 5. + If you are using this feature, please add aws-sessionstore-dynamodb ~> 3 to your Gemfile to enable + this feature when upgrading to aws-sdk-rails ~> 5. ** + MSG options[:config_file] ||= config_file options[:secret_key] ||= Rails.application.secret_key_base @middleware = Aws::SessionStore::DynamoDB::RackMiddleware.new(app, options) diff --git a/lib/aws-sdk-rails.rb b/lib/aws-sdk-rails.rb index 50969feb..e37f368a 100644 --- a/lib/aws-sdk-rails.rb +++ b/lib/aws-sdk-rails.rb @@ -1,7 +1,5 @@ # frozen_string_literal: true -require_relative 'aws/rails/ses_mailer' -require_relative 'aws/rails/sesv2_mailer' require_relative 'aws/rails/railtie' require_relative 'aws/rails/action_mailbox/engine' require_relative 'aws/rails/notifications' @@ -10,6 +8,7 @@ # remove this in aws-sdk-rails 5 require 'aws-sessionstore-dynamodb' +require 'aws-actionmailer-ses' require_relative 'action_dispatch/session/dynamo_db_store' if defined?(Aws::SessionStore::DynamoDB::RackMiddleware) @@ -18,3 +17,10 @@ module Rails VERSION = File.read(File.expand_path('../VERSION', __dir__)).strip end end + +# Remove these in aws-sdk-rails ~> 5 +Aws::Rails::SesMailer = Aws::ActionMailer::SES::Mailer +Aws::Rails::Sesv2Mailer = Aws::ActionMailer::SESV2::Mailer +# This is for backwards compatibility after introducing support for SESv2. +# The old mailer is now replaced with the new SES (v1) mailer. +Aws::Rails::Mailer = Aws::Rails::SesMailer diff --git a/lib/aws/rails/railtie.rb b/lib/aws/rails/railtie.rb index b20b18c2..c496bcae 100644 --- a/lib/aws/rails/railtie.rb +++ b/lib/aws/rails/railtie.rb @@ -12,6 +12,20 @@ class Railtie < ::Rails::Railtie Aws::Rails.use_rails_encrypted_credentials Aws::Rails.add_action_mailer_delivery_method Aws::Rails.add_action_mailer_delivery_method(:sesv2) + + if %i[ses sesv2].include?(::Rails.application.config.action_mailer.delivery_method) + ::Rails.logger.warn(<<~MSG) + ** Aws::Rails.add_action_mailer_delivery_method will be removed in aws-sdk-rails ~> 5. + If you are using this feature, please add your desired delivery methods in an initializer + (such as config/initializers/action_mailer.rb): + + options = { ... SES client options ... } + ActionMailer::Base.add_delivery_method :ses, Aws::ActionMailer::SESMailer, **options + ActionMailer::Base.add_delivery_method :ses_v2, Aws::ActionMailer::SESV2Mailer, **options + + Existing Mailer classes have moved namespaces but will continue to work in this major version. ** + MSG + end end initializer 'aws-sdk-rails.insert_middleware' do |app| @@ -64,8 +78,7 @@ def self.use_rails_encrypted_credentials # @param [Hash] client_options The options you wish to pass on to the # Aws::SES[V2]::Client initialization method. def self.add_action_mailer_delivery_method(name = :ses, client_options = {}) - # TODO: on the next major version, add a "mailer" param to this method - # and use it to determine which mailer to use, keeping name free-form. + # TODO: remove this method in aws-sdk-rails ~> 5 ActiveSupport.on_load(:action_mailer) do if name == :sesv2 add_delivery_method(name, Aws::Rails::Sesv2Mailer, client_options) diff --git a/lib/aws/rails/ses_mailer.rb b/lib/aws/rails/ses_mailer.rb deleted file mode 100644 index 0fd83824..00000000 --- a/lib/aws/rails/ses_mailer.rb +++ /dev/null @@ -1,49 +0,0 @@ -# frozen_string_literal: true - -require 'aws-sdk-ses' - -module Aws - module Rails - # Provides a delivery method for ActionMailer that uses Amazon Simple Email - # Service. - # - # Once you have an SES delivery method you can configure Rails to - # use this for ActionMailer in your environment configuration - # (e.g. RAILS_ROOT/config/environments/production.rb) - # - # config.action_mailer.delivery_method = :ses - # - # Uses the AWS SDK for Ruby's credential provider chain when creating an SES - # client instance. - class SesMailer - # @param [Hash] options Passes along initialization options to - # [Aws::SES::Client.new](https://docs.aws.amazon.com/sdk-for-ruby/v3/api/Aws/SES/Client.html#initialize-instance_method). - def initialize(options = {}) - @client = SES::Client.new(options) - @client.config.user_agent_frameworks << 'aws-sdk-rails' - end - - # Rails expects this method to exist, and to handle a Mail::Message object - # correctly. Called during mail delivery. - def deliver!(message) - params = { - raw_message: { data: message.to_s }, - source: message.smtp_envelope_from, # defaults to From header - destinations: message.smtp_envelope_to # defaults to destinations (To,Cc,Bcc) - } - @client.send_raw_email(params).tap do |response| - message.header[:ses_message_id] = response.message_id - end - end - - # ActionMailer expects this method to be present and to return a hash. - def settings - {} - end - end - end -end - -# This is for backwards compatibility after introducing support for SESv2. -# The old mailer is now replaced with the new SES (v1) mailer. -Aws::Rails::Mailer = Aws::Rails::SesMailer diff --git a/lib/aws/rails/sesv2_mailer.rb b/lib/aws/rails/sesv2_mailer.rb deleted file mode 100644 index b6f2852d..00000000 --- a/lib/aws/rails/sesv2_mailer.rb +++ /dev/null @@ -1,60 +0,0 @@ -# frozen_string_literal: true - -require 'aws-sdk-sesv2' - -module Aws - module Rails - # Provides a delivery method for ActionMailer that uses Amazon Simple Email - # Service V2. - # - # Once you have an SESv2 delivery method you can configure Rails to - # use this for ActionMailer in your environment configuration - # (e.g. RAILS_ROOT/config/environments/production.rb) - # - # config.action_mailer.delivery_method = :sesv2 - # - # Uses the AWS SDK for Ruby's credential provider chain when creating an SESV2 - # client instance. - class Sesv2Mailer - # @param [Hash] options Passes along initialization options to - # [Aws::SESV2::Client.new](https://docs.aws.amazon.com/sdk-for-ruby/v3/api/Aws/SESV2/Client.html#initialize-instance_method). - def initialize(options = {}) - @client = SESV2::Client.new(options) - @client.config.user_agent_frameworks << 'aws-sdk-rails' - end - - # Rails expects this method to exist, and to handle a Mail::Message object - # correctly. Called during mail delivery. - def deliver!(message) - params = { content: { raw: { data: message.to_s } } } - # smtp_envelope_from will default to the From address *without* sender names. - # By omitting this param, SESv2 will correctly use sender names from the mail headers. - # We should only use smtp_envelope_from when it was explicitly set (instance variable set) - params[:from_email_address] = message.smtp_envelope_from if message.instance_variable_get(:@smtp_envelope_from) - params[:destination] = { - to_addresses: to_addresses(message), - cc_addresses: message.cc, - bcc_addresses: message.bcc - } - - @client.send_email(params).tap do |response| - message.header[:ses_message_id] = response.message_id - end - end - - # ActionMailer expects this method to be present and to return a hash. - def settings - {} - end - - private - - # smtp_envelope_to will default to the full destinations (To, Cc, Bcc) - # SES v2 API prefers each component split out into a destination hash. - # When smtp_envelope_to was set, use it explicitly for to_address only. - def to_addresses(message) - message.instance_variable_get(:@smtp_envelope_to) ? message.smtp_envelope_to : message.to - end - end - end -end diff --git a/sample-app/Gemfile b/sample-app/Gemfile index 9b7ba44c..f7a52193 100644 --- a/sample-app/Gemfile +++ b/sample-app/Gemfile @@ -3,6 +3,7 @@ source "https://rubygems.org" # Our gems gem 'aws-sdk-rails', path: '../' gem 'aws-sessionstore-dynamodb' #, path: '../../aws-sessionstore-dynamodb-ruby' +gem 'aws-actionmailer-ses', git: 'https://github.com/aws/aws-actionmailer-ses-ruby', branch: 'init' # Use Active Model has_secure_password [https://guides.rubyonrails.org/active_model_basics.html#securepassword] gem 'bcrypt' diff --git a/sample-app/README.md b/sample-app/README.md index fcd66614..d0db864a 100644 --- a/sample-app/README.md +++ b/sample-app/README.md @@ -87,4 +87,30 @@ To override changes, change this app's Gemfile to use the local path. Start the service with `bundle exec rails server` and visit `http://127.0.0.1:3000/users`. -In the logs, you should see a notification for DynamoDB `update_item` with a `session_id`. This key should exist in your DynamoDB `sessions` table. Refreshing the page should update the session `updated_at` and/or `expired_at` and not create a new session. \ No newline at end of file +In the logs, you should see a notification for DynamoDB `update_item` with a `session_id`. This key should exist in your DynamoDB `sessions` table. Refreshing the page should update the session `updated_at` and/or `expired_at` and not create a new session. + +## Action Mailer mailers + +### Setup + +The mailer was generated with `bundle exec rails generate mailer Test`. + +An empty controller scaffold was generated with `bundle exec rails generate controller Mailer`. + +`ApplicationMailer` was set to use `ENV['ACTION_MAILER_EMAIL']`. + +`TestMailer` implemented SES and SESv2 mailer methods. + +`MailerController` (and routes) were added to send mail. + +`config/application.rb` added `require "action_mailer/railtie"`. + +Delivery methods are configured in `config/initializers/action_mailer.rb`. + +### Testing + +Start the service with `ACTION_MAILER_EMAIL= bundle exec rails server`. + +> **Important**: The email address in SES must be verified. + +Visit `http://127.0.0.1:3000/send_ses_email` or `http://127.0.0.1:3000/send_ses_v2_email` and check your email. diff --git a/sample-app/app/controllers/mailer_controller.rb b/sample-app/app/controllers/mailer_controller.rb new file mode 100644 index 00000000..6246c63d --- /dev/null +++ b/sample-app/app/controllers/mailer_controller.rb @@ -0,0 +1,11 @@ +class MailerController < ApplicationController + def send_ses_email + TestMailer.send_ses_email.deliver_now + render plain: 'Email sent using SES' + end + + def send_ses_v2_email + TestMailer.send_ses_v2_email.deliver_now + render plain: 'Email sent using SES V2' + end +end diff --git a/sample-app/app/helpers/mailer_helper.rb b/sample-app/app/helpers/mailer_helper.rb new file mode 100644 index 00000000..6156b950 --- /dev/null +++ b/sample-app/app/helpers/mailer_helper.rb @@ -0,0 +1,2 @@ +module MailerHelper +end diff --git a/sample-app/app/mailers/application_mailer.rb b/sample-app/app/mailers/application_mailer.rb new file mode 100644 index 00000000..90642b34 --- /dev/null +++ b/sample-app/app/mailers/application_mailer.rb @@ -0,0 +1,5 @@ +class ApplicationMailer < ActionMailer::Base + default from: ENV['ACTION_MAILER_EMAIL'] + layout 'mailer' +end + diff --git a/sample-app/app/mailers/test_mailer.rb b/sample-app/app/mailers/test_mailer.rb new file mode 100644 index 00000000..98232763 --- /dev/null +++ b/sample-app/app/mailers/test_mailer.rb @@ -0,0 +1,19 @@ +class TestMailer < ApplicationMailer + def send_ses_email + mail( + to: ENV['ACTION_MAILER_EMAIL'], + subject: 'Amazon SES Email', + body: 'This is a test email from Amazon SES', + delivery_method: :ses + ) + end + + def send_ses_v2_email + mail( + to: ENV['ACTION_MAILER_EMAIL'], + subject: 'Amazon SES V2 Email', + body: 'This is a test email from Amazon SES V2', + delivery_method: :ses_v2 + ) + end +end diff --git a/sample-app/app/views/layouts/mailer.html.erb b/sample-app/app/views/layouts/mailer.html.erb new file mode 100644 index 00000000..3aac9002 --- /dev/null +++ b/sample-app/app/views/layouts/mailer.html.erb @@ -0,0 +1,13 @@ + + + + + + + + + <%= yield %> + + diff --git a/sample-app/app/views/layouts/mailer.text.erb b/sample-app/app/views/layouts/mailer.text.erb new file mode 100644 index 00000000..37f0bddb --- /dev/null +++ b/sample-app/app/views/layouts/mailer.text.erb @@ -0,0 +1 @@ +<%= yield %> diff --git a/sample-app/config/application.rb b/sample-app/config/application.rb index c7ef4362..aa86af21 100644 --- a/sample-app/config/application.rb +++ b/sample-app/config/application.rb @@ -7,7 +7,7 @@ require "active_record/railtie" # require "active_storage/engine" require "action_controller/railtie" -# require "action_mailer/railtie" +require "action_mailer/railtie" # require "action_mailbox/engine" # require "action_text/engine" require "action_view/railtie" diff --git a/sample-app/config/initializers/action_mailer.rb b/sample-app/config/initializers/action_mailer.rb new file mode 100644 index 00000000..f0104bae --- /dev/null +++ b/sample-app/config/initializers/action_mailer.rb @@ -0,0 +1,3 @@ +options = {} +ActionMailer::Base.add_delivery_method :ses, Aws::ActionMailer::SESMailer, **options +ActionMailer::Base.add_delivery_method :ses_v2, Aws::ActionMailer::SESV2Mailer, **options diff --git a/sample-app/config/routes.rb b/sample-app/config/routes.rb index cc559f5b..ded4a684 100644 --- a/sample-app/config/routes.rb +++ b/sample-app/config/routes.rb @@ -12,4 +12,8 @@ # Defines the root path route ("/") # root "posts#index" + + # Action Mailer routes + get '/send_ses_email', to: 'mailer#send_ses_email' + get '/send_ses_v2_email', to: 'mailer#send_ses_v2_email' end diff --git a/sample-app/test/controllers/mailer_controller_test.rb b/sample-app/test/controllers/mailer_controller_test.rb new file mode 100644 index 00000000..28105067 --- /dev/null +++ b/sample-app/test/controllers/mailer_controller_test.rb @@ -0,0 +1,7 @@ +require "test_helper" + +class MailerControllerTest < ActionDispatch::IntegrationTest + # test "the truth" do + # assert true + # end +end diff --git a/sample-app/test/mailers/previews/test_mailer_preview.rb b/sample-app/test/mailers/previews/test_mailer_preview.rb new file mode 100644 index 00000000..e603a7f4 --- /dev/null +++ b/sample-app/test/mailers/previews/test_mailer_preview.rb @@ -0,0 +1,3 @@ +# Preview all emails at http://localhost:3000/rails/mailers/test_mailer +class TestMailerPreview < ActionMailer::Preview +end diff --git a/sample-app/test/mailers/test_mailer_test.rb b/sample-app/test/mailers/test_mailer_test.rb new file mode 100644 index 00000000..fb07116c --- /dev/null +++ b/sample-app/test/mailers/test_mailer_test.rb @@ -0,0 +1,7 @@ +require "test_helper" + +class TestMailerTest < ActionMailer::TestCase + # test "the truth" do + # assert true + # end +end diff --git a/sample_app_old/README.md b/sample_app_old/README.md index 896062e7..c12d6529 100644 --- a/sample_app_old/README.md +++ b/sample_app_old/README.md @@ -10,20 +10,6 @@ Sample app using `aws-sdk-rails` features. Used for development and testing. `rails db:migrate` -## ActiveStorage - -Start rails with `ACTIVE_STORAGE_BUCKET=my_bucket rails server` - -Upload an `:avatar` using the `/users` route. - -## SES (Outbound) - -Start rails with `ACTION_MAILER_EMAIL=my@email.com rails server` - -Send an email using the `/emails/index` route. - -Make sure your email address is verified in SES. - ## SES (Inbound) Fixture based testing of SES is possible via RSpec request helpers that this gem offers. How to use them is documented within the main README. How to setup inbound emails with SES is also covered there. @@ -33,9 +19,3 @@ Fixture based testing of SES is possible via RSpec request helpers that this gem * Start rails with `AWS_ACTIVE_JOB_QUEUE_URL=https://my_sqs_queue_url rails server` * Visit/curl `http://127.0.0.1:3000/test-job?name=my_name` - This will queue a job up * Poll for and process jobs with: `AWS_ACTIVE_JOB_QUEUE_URL=https://my_sqs_queue_url bundle exec aws_sqs_active_job --queue default` - -## AWS Record Generators - -Run `rails g aws_record:model Forum --table-config primary:10-5` - -To migrate run `rails aws_record:migrate` diff --git a/spec/aws/rails/ses_mailer_spec.rb b/spec/aws/rails/ses_mailer_spec.rb deleted file mode 100644 index 045a6fac..00000000 --- a/spec/aws/rails/ses_mailer_spec.rb +++ /dev/null @@ -1,88 +0,0 @@ -# frozen_string_literal: true - -require 'test_helper' -require 'mail' - -module Aws - module Rails - describe SesMailer do - let(:client_options) do - { - stub_responses: { - send_raw_email: { - message_id: ses_message_id - } - } - } - end - - let(:mailer) { SesMailer.new(client_options) } - - let(:sample_message) do - TestMailer.deliverable( - delivery_method: :ses, - body: 'Hallo', - from: 'Sender ', - subject: 'This is a test', - to: 'Recipient ', - cc: 'Recipient CC ', - bcc: 'Recipient BCC ', - headers: { - 'X-SES-CONFIGURATION-SET' => 'TestConfigSet', - 'X-SES-LIST-MANAGEMENT-OPTIONS' => 'contactListName; topic=topic' - } - ) - end - - let(:ses_message_id) do - '0000000000000000-1111111-2222-3333-4444-555555555555-666666' - end - - before do - Aws::Rails.add_action_mailer_delivery_method(:ses, client_options) - end - - describe '#settings' do - it 'returns an empty hash' do - expect(mailer.settings).to eq({}) - end - end - - describe '#deliver' do - it 'delivers the message' do - mailer_data = mailer.deliver!(sample_message).context.params - raw = mailer_data[:raw_message][:data].to_s - raw.gsub!("\r\nHallo", "ses-message-id: #{ses_message_id}\r\n\r\nHallo") - expect(raw).to eq sample_message.to_s - expect(mailer_data[:source]).to eq 'sender@example.com' - expect(mailer_data[:destinations]).to eq( - ['recipient@example.com', - 'recipient_cc@example.com', - 'recipient_bcc@example.com'] - ) - end - - it 'delivers the message with SMTP envelope sender and recipient' do - message = sample_message.message - message.smtp_envelope_from = 'envelope-sender@example.com' - message.smtp_envelope_to = 'envelope-recipient@example.com' - mailer_data = mailer.deliver!(message).context.params - expect(mailer_data[:source]).to eq 'envelope-sender@example.com' - expect(mailer_data[:destinations]).to eq ['envelope-recipient@example.com'] - end - - it 'delivers with action mailer' do - message = sample_message.deliver_now - expect(message.header[:ses_message_id].value).to eq ses_message_id - end - - it 'passes through SES headers' do - mailer_data = mailer.deliver!(sample_message).context.params - raw = mailer_data[:raw_message][:data].to_s - expect(raw).to include('X-SES-CONFIGURATION-SET: TestConfigSet') - expect(raw).to include('X-SES-LIST-MANAGEMENT-OPTIONS: contactListName; topic=topic') - end - end - end - end -end diff --git a/spec/aws/rails/sesv2_mailer_spec.rb b/spec/aws/rails/sesv2_mailer_spec.rb deleted file mode 100644 index 982e5a10..00000000 --- a/spec/aws/rails/sesv2_mailer_spec.rb +++ /dev/null @@ -1,92 +0,0 @@ -# frozen_string_literal: true - -require 'test_helper' -require 'mail' - -module Aws - module Rails - describe Sesv2Mailer do - let(:client_options) do - { - stub_responses: { - send_email: { - message_id: ses_message_id - } - } - } - end - - let(:mailer) { Sesv2Mailer.new(client_options) } - - let(:sample_message) do - TestMailer.deliverable( - delivery_method: :sesv2, - body: 'Hallo', - from: 'Sender ', - subject: 'This is a test', - to: 'Recipient ', - cc: 'Recipient CC ', - bcc: 'Recipient BCC ', - headers: { - 'X-SES-CONFIGURATION-SET' => 'TestConfigSet', - 'X-SES-LIST-MANAGEMENT-OPTIONS' => 'contactListName; topic=topic' - } - ) - end - - let(:ses_message_id) do - '0000000000000000-1111111-2222-3333-4444-555555555555-666666' - end - - before do - Aws::Rails.add_action_mailer_delivery_method(:sesv2, client_options) - end - - describe '#settings' do - it 'returns an empty hash' do - expect(mailer.settings).to eq({}) - end - end - - describe '#deliver' do - it 'delivers the message' do - mailer_data = mailer.deliver!(sample_message).context.params - raw = mailer_data[:content][:raw][:data].to_s - raw.gsub!("\r\nHallo", "ses-message-id: #{ses_message_id}\r\n\r\nHallo") - expect(raw).to eq sample_message.to_s - expect(mailer_data[:from_email_address]).to eq nil # Optional for raw messages - expect(mailer_data[:destination]).to eq( - to_addresses: ['recipient@example.com'], # Default to To header - cc_addresses: ['recipient_cc@example.com'], - bcc_addresses: ['recipient_bcc@example.com'] - ) - end - - it 'delivers the message with SMTP envelope sender and recipient' do - message = sample_message.message - message.smtp_envelope_from = 'envelope-sender@example.com' - message.smtp_envelope_to = 'envelope-recipient@example.com' - mailer_data = mailer.deliver!(message).context.params - expect(mailer_data[:from_email_address]).to eq 'envelope-sender@example.com' - expect(mailer_data[:destination]).to eq( - to_addresses: ['envelope-recipient@example.com'], - cc_addresses: ['recipient_cc@example.com'], - bcc_addresses: ['recipient_bcc@example.com'] - ) - end - - it 'delivers with action mailer' do - message = sample_message.deliver_now - expect(message.header[:ses_message_id].value).to eq ses_message_id - end - - it 'passes through SES headers' do - mailer_data = mailer.deliver!(sample_message).context.params - raw = mailer_data[:content][:raw][:data].to_s - expect(raw).to include('X-SES-CONFIGURATION-SET: TestConfigSet') - expect(raw).to include('X-SES-LIST-MANAGEMENT-OPTIONS: contactListName; topic=topic') - end - end - end - end -end diff --git a/test/aws/rails/railtie_test.rb b/test/aws/rails/railtie_test.rb index 435fed22..b7fe5759 100644 --- a/test/aws/rails/railtie_test.rb +++ b/test/aws/rails/railtie_test.rb @@ -32,8 +32,8 @@ module Rails end it 'adds action mailer delivery methods' do - expect(ActionMailer::Base.delivery_methods[:ses]).to eq Aws::Rails::SesMailer - expect(ActionMailer::Base.delivery_methods[:sesv2]).to eq Aws::Rails::Sesv2Mailer + expect(::ActionMailer::Base.delivery_methods[:ses]).to eq Aws::Rails::SesMailer + expect(::ActionMailer::Base.delivery_methods[:sesv2]).to eq Aws::Rails::Sesv2Mailer end it 'sets the Rails logger to Aws global config' do diff --git a/test/test_helper.rb b/test/test_helper.rb index 53af6d6f..71689b62 100644 --- a/test/test_helper.rb +++ b/test/test_helper.rb @@ -11,3 +11,12 @@ require_relative 'dummy/config/application' Rails.application.initialize! + +class TestMailer < ActionMailer::Base + layout nil + + def deliverable(options = {}) + headers(options.delete(:headers)) + mail(options) + end +end