diff --git a/app/controllers/concerns/conditional_user_mailer.rb b/app/controllers/concerns/conditional_user_mailer.rb new file mode 100644 index 0000000..aa7622b --- /dev/null +++ b/app/controllers/concerns/conditional_user_mailer.rb @@ -0,0 +1,35 @@ +module ConditionalUserMailer + extend ActiveSupport::Concern + + # Adds following methods as class methods for the class that include this module + included do + # Executes a given block passed if the recipient user has the preference email key enabled + # @param recipients {User | Enumerable } User object or any object that includes Enumerable class + # @param key {String} - A key (dot notation) whose value is true/false and belongs to prefences.email (see config/branding.yml) + def deliver_if(recipients: [], key:) + raise(ArgumentError, 'key must be String') unless key.is_a?(String) + if block_given? + split_key = key.split('.') + if !recipients.respond_to?(:each) + recipients = Array(recipients) + end + recipients.each do |r| + if r.respond_to?(:get_preferences) + email_hash = r.get_preferences('email') + should_deliver = split_key.reduce(email_hash) do |m,o| + if m.is_a?(Hash) + m[o.to_sym] + else + break + end + end + yield r if should_deliver.is_a?(TrueClass) + end + end + true + else # Block not given + false + end + end + end +end \ No newline at end of file diff --git a/app/controllers/notes_controller.rb b/app/controllers/notes_controller.rb index d128345..cce8567 100644 --- a/app/controllers/notes_controller.rb +++ b/app/controllers/notes_controller.rb @@ -1,9 +1,9 @@ class NotesController < ApplicationController + include ConditionalUserMailer + require "pp" after_action :verify_authorized respond_to :html - require "pp" - def create @note = Note.new @note.user_id = params[:note][:user_id] @@ -36,6 +36,12 @@ if @note.save @status = true + answer = @note.answer + plan = answer.plan + owner = plan.owner + deliver_if(recipients: owner, key: 'users.new_comment') do |r| + UserMailer.new_comment(r, plan).deliver_now() + end @notice = success_message(_('comment'), _('created')) render(json: { "notes" => { diff --git a/app/controllers/plans_controller.rb b/app/controllers/plans_controller.rb index a38cd5d..a5ee45a 100644 --- a/app/controllers/plans_controller.rb +++ b/app/controllers/plans_controller.rb @@ -1,4 +1,5 @@ class PlansController < ApplicationController + include ConditionalUserMailer require 'pp' helper PaginableHelper helper SettingsTemplateHelper @@ -312,7 +313,9 @@ if plan.visibility_allowed? plan.visibility = plan_params[:visibility] if plan.save - UserMailer.plan_visibility(User.find_by(email: "jose.lloret@ed.ac.uk"),plan).deliver_now() + deliver_if(recipients: plan.owner_and_coowners, key: 'owners_and_coowners.visibility_changed') do |r| + UserMailer.plan_visibility(r,plan).deliver_now() + end render status: :ok, json: { msg: success_message(_('plan\'s visibility'), _('changed')) } else render status: :internal_server_error, json: { msg: _('Error raised while saving the visibility for plan id %{plan_id}') %{ :plan_id => params[:id]} } diff --git a/app/controllers/roles_controller.rb b/app/controllers/roles_controller.rb index 58b34f6..05ee86c 100644 --- a/app/controllers/roles_controller.rb +++ b/app/controllers/roles_controller.rb @@ -1,4 +1,5 @@ class RolesController < ApplicationController + include ConditionalUserMailer respond_to :html after_action :verify_authorized @@ -27,7 +28,11 @@ message += _('Plan shared with %{email}.') % {email: user.email} @role.user = user if @role.save - if registered then UserMailer.sharing_notification(@role, current_user).deliver_now end + if registered + deliver_if(recipients: user, key: 'users.added_as_coowner') do |r| + UserMailer.sharing_notification(@role, r).deliver_now + end + end flash[:notice] = message else flash[:alert] = failed_create_error(@role, _('role')) @@ -105,4 +110,4 @@ end end -end +end \ No newline at end of file diff --git a/app/models/note.rb b/app/models/note.rb index e20cc04..4341c2a 100644 --- a/app/models/note.rb +++ b/app/models/note.rb @@ -11,10 +11,4 @@ :answer, :user, :as => [:default, :admin] validates :text, :answer, :user, presence: {message: _("can't be blank")} - - # Active Record Callbacks - after_create do - # Sends an email to the plan owner regarding a new comment created by new note user - UserMailer.new_comment(self.user, self.answer.plan).deliver_now() - end end diff --git a/app/models/plan.rb b/app/models/plan.rb index fe5bc49..cdc9882 100644 --- a/app/models/plan.rb +++ b/app/models/plan.rb @@ -1,5 +1,5 @@ class Plan < ActiveRecord::Base - + include ConditionalUserMailer before_validation :set_creation_defaults ## @@ -216,8 +216,9 @@ if user.org.contact_email.present? admins << User.new(email: user.org.contact_email, firstname: user.org.contact_name) end - admins.each do |admin| - UserMailer.feedback_notification(admin, self, user).deliver_now + + deliver_if(recipients: admins, key: 'admins.feedback_requested') do |r| + UserMailer.feedback_notification(r, self, user).deliver_now end true else diff --git a/app/models/user.rb b/app/models/user.rb index ea34e83..c028a92 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -266,7 +266,7 @@ if self.pref.present? && self.pref.settings[key.to_s].present? return self.pref.settings[key.to_s].deep_symbolize_keys elsif Pref.default_settings - return Pref.default_settings[key] + return Pref.default_settings[key.to_sym] || Pref.default_settings[key.to_s] else return nil end diff --git a/test/unit/concerns/conditional_user_mailer_test.rb b/test/unit/concerns/conditional_user_mailer_test.rb new file mode 100644 index 0000000..9700ae1 --- /dev/null +++ b/test/unit/concerns/conditional_user_mailer_test.rb @@ -0,0 +1,67 @@ +require 'test_helper' + +class ConditionalUserMailerTest < ActiveSupport::TestCase + include ConditionalUserMailer + + def save_email_users_new_comment(user, value) + settings = Pref.default_settings + settings[:email][:users][:new_comment] = value + Pref.new(user: user, settings: settings).save + end + + setup do + @super_admin = User.find_by(email: 'super_admin@example.com') + @funder = User.find_by(email: 'funder_admin@example.com') + @org_admin = User.find_by(email: 'org_admin@example.com') + @org_user = User.find_by(email: 'org_user@example.com') + end + test 'raises ArgumentError for a non-valid key' do + e = assert_raises(ArgumentError) do + deliver_if(recipients: @super_admin, key: nil) + end + assert_equal('key must be String', e.message) + end + test 'returns false when a block is not given' do + assert_equal(deliver_if(recipients: @super_admin, key: 'foo'), false) + end + test 'block is NOT executed when an email preference does not exist' do + block = false + assert_equal(deliver_if(recipients: @super_admin, key: 'foo'){ block = true }, true) + refute block + end + test 'block is NOT executed when an email preference is disabled' do + save_email_users_new_comment(@super_admin, false) + block = false + assert_equal(deliver_if(recipients: @super_admin, key: 'users.new_comment') { block = true }, true) + refute block + end + test 'block is executed when an email preference is enabled' do + save_email_users_new_comment(@super_admin, true) + block = false + assert_equal(deliver_if(recipients: @super_admin, key: 'users.new_comment') { block = true }, true) + assert block + end + test 'block is executed for those users from an array with an email preference enabled' do + save_email_users_new_comment(@super_admin, true) + save_email_users_new_comment(@funder, false) + save_email_users_new_comment(@org_admin, false) + save_email_users_new_comment(@org_user, true) + block = {} + recipients = [ @super_admin, @funder, @org_admin, @org_user ] + assert_equal(deliver_if(recipients: recipients, key: 'users.new_comment') { |r| block[r.email] = true }, true) + assert_equal({ 'super_admin@example.com' => true, 'org_user@example.com' => true }, block) + end + test 'block is executed for those users from an ActiveRecord::Relation with an email preference enabled' do + users = User.where(id: [@super_admin.id, @funder.id, @org_admin.id, @org_user.id]) + save_email_users_new_comment(users.first, true) + save_email_users_new_comment(users.second, false) + save_email_users_new_comment(users.third, false) + save_email_users_new_comment(users.fourth, true) + expected = {} + expected[users.first.email] = true + expected[users.fourth.email] = true + block = {} + assert_equal(deliver_if(recipients: users, key: 'users.new_comment'){ |r| block[r.email] = true }, true) + assert_equal(expected, block) + end +end \ No newline at end of file