diff --git a/README.md b/README.md index ad48caf..3533e3a 100644 --- a/README.md +++ b/README.md @@ -280,14 +280,14 @@ Solid Errors _can_ send email notifications whenever an error occurs, if your ap There are two ways to configure email notifications. First, you can use environment variables: -```ruby -ENV["SOLIDERRORS_SEND_EMAILS"] = true # defaults to false -ENV["SOLIDERRORS_EMAIL_FROM"] = "errors@myapp.com" # defaults to "solid_errors@noreply.com" -ENV["SOLIDERRORS_EMAIL_TO"] = "devs@myapp.com" # no default, must be set -ENV["SOLIDERRORS_EMAIL_SUBJECT_PREFIX"] = "[Application name][Environment]" # no default, optional +```sh +SOLIDERRORS_SEND_EMAILS=true # defaults to false +SOLIDERRORS_EMAIL_FROM=errors@myapp.com # defaults to solid_errors@noreply.com +SOLIDERRORS_EMAIL_TO=devs@myapp.com # no default, must be set +SOLIDERRORS_EMAIL_SUBJECT_PREFIX="[Application name][Environment]" # no default, optional ``` -Second, you can set the values via the configuration object: +Second, you can set the values via the configuration object, which takes precedence over the environment variables: ```ruby # Set authentication credentials and optional subject prefix for Solid Errors diff --git a/lib/solid_errors.rb b/lib/solid_errors.rb index 458ab4c..c4faa29 100644 --- a/lib/solid_errors.rb +++ b/lib/solid_errors.rb @@ -11,10 +11,7 @@ module SolidErrors mattr_accessor :base_controller_class, default: "::ActionController::Base" mattr_writer :username mattr_writer :password - mattr_accessor :send_emails, default: false - mattr_accessor :email_from, default: "solid_errors@noreply.com" - mattr_accessor :email_to - mattr_accessor :email_subject_prefix + mattr_writer :send_emails, :email_from, :email_to, :email_subject_prefix, default: nil mattr_accessor :email_every_occurrence, default: true # Builds the error email's subject, before email_subject_prefix. reason is :created or :reopened when # the occurrence opened its error, nil for any other occurrence, or the app's own reason when it sends the email itself @@ -39,6 +36,23 @@ def password @password ||= ENV["SOLIDERRORS_PASSWORD"] || @@password end + # Each email setting falls back to its SOLIDERRORS_* environment variable when not configured + def send_emails + @@send_emails.nil? ? ActiveModel::Type::Boolean.new.cast(ENV["SOLIDERRORS_SEND_EMAILS"]) || false : @@send_emails + end + + def email_from + @@email_from || ENV["SOLIDERRORS_EMAIL_FROM"] || "solid_errors@noreply.com" + end + + def email_to + @@email_to || ENV["SOLIDERRORS_EMAIL_TO"] + end + + def email_subject_prefix + @@email_subject_prefix || ENV["SOLIDERRORS_EMAIL_SUBJECT_PREFIX"] + end + # Whether the errors database has every table and column this version reads and writes. # Assert it in your test suite to catch a schema change you haven't applied yet. def migrated? diff --git a/test/solid_errors/email_configuration_test.rb b/test/solid_errors/email_configuration_test.rb new file mode 100644 index 0000000..53a7b19 --- /dev/null +++ b/test/solid_errors/email_configuration_test.rb @@ -0,0 +1,44 @@ +require "test_helper" + +class SolidErrors::EmailConfigurationTest < ActiveSupport::TestCase + SETTINGS = %i[send_emails email_from email_to email_subject_prefix] + ENV_VARS = %w[SOLIDERRORS_SEND_EMAILS SOLIDERRORS_EMAIL_FROM SOLIDERRORS_EMAIL_TO SOLIDERRORS_EMAIL_SUBJECT_PREFIX] + + setup do + @settings = SETTINGS.to_h { |name| [name, SolidErrors.class_variable_get(:"@@#{name}")] } + @env = ENV.to_h.slice(*ENV_VARS) + SETTINGS.each { |name| SolidErrors.public_send(:"#{name}=", nil) } + end + + teardown do + @settings.each { |name, value| SolidErrors.public_send(:"#{name}=", value) } + ENV_VARS.each { |var| ENV.delete(var) } + ENV.update(@env) + end + + test "email settings fall back to their environment variables" do + ENV.update( + "SOLIDERRORS_SEND_EMAILS" => "true", + "SOLIDERRORS_EMAIL_FROM" => "errors@example.com", + "SOLIDERRORS_EMAIL_TO" => "devs@example.com", + "SOLIDERRORS_EMAIL_SUBJECT_PREFIX" => "[App]" + ) + + assert_equal [true, "errors@example.com", "devs@example.com", "[App]"], + SETTINGS.map { |name| SolidErrors.public_send(name) } + assert SolidErrors.send_emails? + end + + test "configured email settings win over their environment variables" do + ENV.update("SOLIDERRORS_SEND_EMAILS" => "true", "SOLIDERRORS_EMAIL_FROM" => "env@example.com") + SolidErrors.send_emails = false + SolidErrors.email_from = "config@example.com" + + assert_equal [false, "config@example.com"], [SolidErrors.send_emails, SolidErrors.email_from] + end + + test "email settings keep their defaults when neither is set" do + assert_equal [false, "solid_errors@noreply.com", nil, nil], + SETTINGS.map { |name| SolidErrors.public_send(name) } + end +end