Prevent test emails going out to users in AdonisJS

Here’s a quick way to prevent emails from going out in test environments in AdonisJS.

We typically end up getting production data in part or in whole to test environments for a “proper” round of testing on real data. But all the data attributes cannot be so “real”.

We typically end up changing fields like emails so that customers do not start receiving emails from non-production environments.

In addition to the above change, we try to specify an explicit opt-in to communications so that people who are not associated with testing do not get confused with test transactions - even when the said people are within the client organization.

One of the fields impacted is the contact email (or login , if the application uses login id as email). I typically use @adonisjs/mail module to send emails and implement a quick opt-in filter to prevent emails from going out to anyone other than those specified in a list.

Another option that enables better testing is to pre-identify one or more test users, and redirect all emails from the test environment to those users. This will enable them to pick and chose any deal, contact or other records in testing and get notifications to their email ids. The script for such mail redirection to whitelisted testers is similar to the block below -

// Services/SendMailService.js

"use strict";

const Mail = use("Mail");
const Env = use("Env");

class SendMailService {
  async sendMail({ data, params }) {
    // NO EXTERNAL EMAILS TO BE SENT IN NON-PROD UNLESS WHITELISTED.
    if (
      Env.get("NODE_ENV")
        .toLowerCase()
        .indexOf("production") < 0
    ) {
      if (
        Env.get("EMAIL_WHITE_LIST")
          .toLowerCase()
          .indexOf(data.email) < 0
      )
        data.email = Env.get("EMAIL_TEST_USER");
    }

    params.template = params.template ? params.template : "hello";
    params.subject = params.subject ? params.subject : params.template;

    await Mail.send("emails." + params.template, data, message => {
      message
        .to(data.email)
        .from(Env.get("SMTP_USERNAME"))
        .subject(params.subject);
    });
  }
}

module.exports = new SendMailService();

We are doing three simple things here -

  • check whether environment is production using NODE_ENV. We let the request go as-is if it’s production
  • else, check whether the user is part of ids specified against EMAIL_WHITE_LIST in .env file. Let the email go if the id is white-listed
  • else, send email to the ids specified against EMAIL_TEST_USER in .env file

Since .env are specific to the environment, we can control the test users and white listing for different test environments.

comments powered by Disqus