Testing Multipart Email Templates in Rails

The majority of our email templates require both a text and HTML version so that we can send multipart emails. We ran in to a few instances where a new template was added, but the text version was forgotten. I wrote up a quick spec that will ensure a text version exists for every HTML template in the user_mailer directory. Notice that break takes an argument, so it will return the template for which the text version is missing, giving you a little more debugging info.

describe UserMailer do
  it "has a text email template for each HTML template" do
    # Path to the mailer templates
    mailers_path = "#{Rails.root}/app/views/user_mailer/"

    result = Dir.foreach(mailers_path) do |template|
      # Ignore partials
      next if template.match /^_/

      # Check if it is an HTML template
      html_version = template.match(/.+\.html\..+/)

      # Skip if it isn't an HTML template
      next unless html_version && html_version[0].present?

      # Construct the text version file name
      text_version = html_version[0].gsub! "html", "text"

      # Check for the text version of the HTML template and return the HTML template if it doesn't exist
      break "#{mailers_path}#{html_version}" unless File.exist?("#{mailers_path}#{text_version}")
    end
    # The block should not return a template with a missing text version
    result.should be_nil
  end
end