Developing mailers - otwcode/otwarchive GitHub Wiki

Developing mails and mailers can be challenging because they're difficult to test in the browser. That makes mailers the perfect use for Test-Driven Development (TDD), as the automated tests can take over the bulk of testing work during development. This page provides some tips for formatting emails and an overview of how to test mailers both automatically and manually.

Table of Contents

Formatting and styling mails

Refer to the Internationalization (i18n) Standards page for all information about formatting and styling translatable text in mailers.

In text mails, don't indent the erb tags for code style. The indentation is not stripped and will end up in the final mail.

When using Ruby to format HTML, prefer methods from the TagHelper, e.g. tag.em, over writing out HTML tags in strings. Prefer methods from the OutputSafetyHelper like to_sentence over calling html_safe manually.

RSpec mailer tests

The RSpec tests for mailers are most useful for checking basic assumptions when creating a new mail, such as whether it is a multipart mail. The existing tests in user_mailer_spec.rb show uses of the shared examples for mailers as well as various other checks:

  • Presence of HTML tags for formatting
  • Subject text
  • No missing translations
  • Behavior with various parameters, especially invalid input

Cucumber mailer tests

Cucumber tests are integration tests, so they are useful for checking whether the mail with the correct content is sent when doing certain actions. Furthermore, most mails should have an integration test for sending a translated mail when a user uses a non-English locale. The steps for this are defined in email_custom_steps.rb and the claim_notification can serve as an example for using them. Take note of the "all emails have been delivered" step, which makes sure that mails sent before the step, such as user verification mails, don't interfere with the test.

Cucumber tests can't test whether mail content is formatted correctly. The cucumber mail steps run for both the text and HTML version of mails, so Cucumber can't be used to check any HTML tags or text that contains HTML tags.

Mailer previews

Mailer previews make it possible to easily manually test mail content, formatting/styling and translations by viewing the mail in your browser, without manually going through the steps of sending it. The previews are defined in test/mailers/previews/ and can be viewed at http://localhost:3000/rails/mailers after starting your local otwarchive server or at the same path in the staging environment. Use FactoryBot factories to create the data shown in the preview mails. You need to refresh the page with the preview after modifying the mail to view the changes.

When adding a mailer preview, there are the following guidelines:

  • Give the preview method the same name as the mailer method, e.g. create UserMailerPreview.change_email for UserMailer.change_email.
  • If the email has variants:
    • If there are finite variants, e.g. different subscription types like Work and Chapter for the subscription email, create separate methods for each variant and tack the variant onto the end of the preview method name, e.g. batch_subscription_notification_work for the Work variant of batch_subscription_notification.
    • If there are infinite variants, e.g. amount of guest kudos in a kudos email, use URL parameters instead.
      • Because previews are only accessible in local dev and in the staging environment and will mostly be used by scripts, input validation is not a major concern.
      • However, the URL parameters are strings. So when using URL parameters as numbers (e.g. for pluralization), make sure to convert them to a number (e.g. with to_i) before passing them to the mailer.
  • Make sure the I18n.with_locale call for the email is outside of the mailer class. Instead it should be where deliver/deliver_later is called on the mailer. Otherwise the locale dropdown in the preview will not have any effect. Refer to #5044 for an example of moving with_locale to the correct spot.

Mails sent by the development archive

When manually testing mails in your local development environment, you can find the sent mails in log/development.log. If the file is very long, try searching for Delivered mail to find the mails. Alternatively, set config.action_mailer.delivery_method = :file in config/environments/development.rb and the mails will also be saved to tmp/mails/.

For mails sent with deliver_later, a Resque worker needs to be running to send the emails. Some mails are sent out on a schedule defined in resque_schedule.yml. The Resque scheduler needs to be running to send these mails. Other mails, such as the kudos mail, are sent by rake tasks. You can find these rake tasks in config/schedule.rb and run them locally.

⚠️ **GitHub.com Fallback** ⚠️