Load system notification policy defaults for new user. Fixes

When a new user visits /profile/communication, load the
system defaults for frequency settings.

Test Plan
=======
* Create a new user and visit /profile/communication.
  Verify that there are default settings loaded.
* Verify that after adding a new communication channel
  that defaults are not applied.
* Verify that changing a setting and reloading
  preserves the user-selected value and is not
  overriden by a default.

Change-Id: I9d87b316510fd08bdf40380e05b327bed7e0e95c
Reviewed-on: https://gerrit.instructure.com/12720
Reviewed-by: Jon Jensen <jon@instructure.com>
Tested-by: Jenkins <jenkins@instructure.com>
This commit is contained in:
Mark Ericksen 2012-08-03 13:08:13 -06:00
parent c1ea206aa7
commit 2ce8bee3ca
3 changed files with 76 additions and 2 deletions

View File

@ -119,13 +119,16 @@ class ProfileController < ApplicationController
def communication
@user = @current_user
@user = User.find(params[:id]) if params[:id]
@current_user.used_feature(:cc_prefs)
@context = @user.profile
@active_tab = 'notifications'
# Get the list of Notification models (that are treated like categories) that make up the full list of Categories.
full_category_list = Notification.dashboard_categories(@user)
js_env :NOTIFICATION_PREFERENCES_OPTIONS => {
:channels => @user.communication_channels.all_ordered_for_display(@user).map { |c| communication_channel_json(c, @user, session) },
:policies => NotificationPolicy.scoped(:include => :notification).for(@user).map{ |p| notification_policy_json(p, @user, session) },
:categories => Notification.dashboard_categories(@user).map{ |c| notification_category_json(c, @user, session) },
:policies => NotificationPolicy.setup_with_default_policies(@user, full_category_list).map{ |p| notification_policy_json(p, @user, session) },
:categories => full_category_list.map{ |c| notification_category_json(c, @user, session) },
:update_url => communication_update_profile_path
}
end

View File

@ -131,4 +131,33 @@ class NotificationPolicy < ActiveRecord::Base
end #if..else
nil
end
# Fetch the user's NotificationPolicies but whenever a category is not represented, create a NotificationPolicy on the primary
# CommunicationChannel with a default frequency set.
# Returns the full list of policies for the user
#
# ===== Arguments
# * <tt>user</tt> - The User instance to load the values for.
# * <tt>full_category_list</tt> - An array of Notification models that represent the unique list of categories that should be displayed for the user.
#
# ===== Returns
# A list of NotificationPolicy entries for the user. May include newly created entries if defaults were needed.
def self.setup_with_default_policies(user, full_category_list)
categories = {}
# Get the list of notification categories and its default. Like this: {"Announcement" => 'immediately'}
full_category_list.each {|c| categories[c.category] = c.default_frequency}
default_channel_id = user.communication_channel.try(:id)
# Load unique list of categories that the user currently has settings for.
user_categories = NotificationPolicy.for(user).scoped(:joins => :notification,
:select => 'DISTINCT notifications.category').all.map{|c| c.category}
missing_categories = (categories.keys - user_categories)
missing_categories.each do |need_category|
# Create the settings for a completely unrepresented category. Use default communication_channel (primary email)
self.setup_for(user, {:category => need_category,
:channel_id => default_channel_id,
:frequency => categories[need_category]})
end
# Load and return user's policies after defaults may or may not have been set.
NotificationPolicy.scoped(:include => :notification).for(user)
end
end

View File

@ -225,6 +225,48 @@ describe NotificationPolicy do
n2.frequency.should == Notification::FREQ_IMMEDIATELY
end
end
describe "setup_with_default_policies" do
before :each do
user_model
communication_channel_model(:user_id => @user.id)
@announcement = notification_model(:name => 'Setting 1', :category => 'Announcement')
end
it "should create default NotificationPolicy entries if missing" do
# Ensure no existing policies
NotificationPolicy.delete_all
policies = NotificationPolicy.setup_with_default_policies(@user, [@announcement])
policies.length.should == 1
policies.first.frequency.should == @announcement.default_frequency
end
it "should not overwrite an existing setting with a default" do
# Create an existing policy entry
NotificationPolicy.delete_all
n1 = notification_policy_model({:communication_channel => @communication_channel,
:notification => @announcement,
:frequency => Notification::FREQ_NEVER})
@announcement.default_frequency.should_not == Notification::FREQ_NEVER # verify that it differs from the default
policies = NotificationPolicy.setup_with_default_policies(@user, [@announcement])
policies.length.should == 1
policies.first.frequency.should == Notification::FREQ_NEVER
end
it "should not set defaults on secondary communication channel" do
NotificationPolicy.delete_all
# Setup the second channel (higher position)
primary_channel = @user.communication_channel
secondary_channel = communication_channel_model(:user_id => @user.id, :path => 'secondary@example.com')
# start out with 0 on primary and secondary
primary_channel.notification_policies.count.should == 0
secondary_channel.notification_policies.count.should == 0
# Load data
NotificationPolicy.setup_with_default_policies(@user, [@announcement])
# Primary should have 1 created and secondary should be left alone.
primary_channel.notification_policies.count.should == 1
secondary_channel.notification_policies.count.should == 0
end
end
end
def policy_setup