2011-09-22 01:36:45 +08:00
|
|
|
#
|
|
|
|
# Copyright (C) 2011 Instructure, Inc.
|
|
|
|
#
|
|
|
|
# This file is part of Canvas.
|
|
|
|
#
|
|
|
|
# Canvas is free software: you can redistribute it and/or modify it under
|
|
|
|
# the terms of the GNU Affero General Public License as published by the Free
|
|
|
|
# Software Foundation, version 3 of the License.
|
|
|
|
#
|
|
|
|
# Canvas is distributed in the hope that it will be useful, but WITHOUT ANY
|
|
|
|
# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
|
|
|
|
# A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
|
|
|
|
# details.
|
|
|
|
#
|
|
|
|
# You should have received a copy of the GNU Affero General Public License along
|
|
|
|
# with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
|
|
#
|
|
|
|
|
2011-10-13 07:28:30 +08:00
|
|
|
require 'skip_callback'
|
|
|
|
|
2011-09-22 01:36:45 +08:00
|
|
|
module StickySisFields
|
|
|
|
|
|
|
|
module InstanceMethods
|
|
|
|
|
2011-10-13 07:28:30 +08:00
|
|
|
# this method is set as a before_update callback
|
2011-09-22 01:36:45 +08:00
|
|
|
def set_sis_stickiness
|
2011-10-13 07:28:30 +08:00
|
|
|
self.class.sis_stickiness_options ||= {}
|
|
|
|
currently_stuck_sis_fields = if self.class.sis_stickiness_options[:clear_sis_stickiness]
|
|
|
|
[].to_set
|
|
|
|
else
|
|
|
|
calculate_currently_stuck_sis_fields
|
|
|
|
end
|
|
|
|
if load_stuck_sis_fields_cache != currently_stuck_sis_fields
|
|
|
|
write_attribute(:stuck_sis_fields, currently_stuck_sis_fields.map(&:to_s).sort.join(','))
|
|
|
|
end
|
2011-09-22 01:36:45 +08:00
|
|
|
@stuck_sis_fields_cache = currently_stuck_sis_fields
|
2011-10-13 07:28:30 +08:00
|
|
|
@sis_fields_to_stick = [].to_set
|
2011-09-22 01:36:45 +08:00
|
|
|
@sis_fields_to_unstick = [].to_set
|
|
|
|
end
|
|
|
|
|
2011-10-13 07:28:30 +08:00
|
|
|
# this method is what you want to use to determine which fields are currently stuck
|
2011-09-22 01:36:45 +08:00
|
|
|
def stuck_sis_fields
|
2011-10-13 07:28:30 +08:00
|
|
|
self.class.sis_stickiness_options ||= {}
|
|
|
|
if self.class.sis_stickiness_options[:override_sis_stickiness]
|
2011-09-22 01:36:45 +08:00
|
|
|
return [].to_set
|
|
|
|
else
|
2011-10-13 07:28:30 +08:00
|
|
|
return calculate_currently_stuck_sis_fields
|
2011-09-22 01:36:45 +08:00
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2011-10-13 07:28:30 +08:00
|
|
|
def stuck_sis_fields=(fields)
|
[#5773] Ruby 1.9.3 spec fixes
[#5773] correctly evaluate the custom_fields_string
My impression is that order is not enforced in the
hash being used to build the fields string, as
this was failing in 1.8.7 for me (but not in
1.9.3), because the string being checked was
"b=456\na=123" while the string being returned
from the custom_fields_string method was
"a=123\nb=456". Testing with a regex instead
confirms the content is there without relying on
any particular order. [EDIT: Per Brian P, decided
to sort the params instead to enforce order]
[#5773] fix admin_settings_tab_spec for ruby 1.9.3
String's "each" method was being used, which is
gone in 1.9. Fixed by performing a guard clause
in the check_box_verifier in the spec file to
conditionally take a string argument and convert
it to an array. Also converted the rest of the
method to assume an array value for that argument.
[#5773] fix collaborations selenium spec for 1.9.3
This is an instance of using the "each" method
of the string class which is no longer present in
1.9 in one of the helper methods in this spec.
Erected a guard clause to check for Array-ness
and to replace the argument with an
array if necessary.
[#5773] fix courses show view
There was a spot in this view where it was
interpolating "self.id" into an html attribute
rather than "@instance_model.id". This sort
of worked in ruby 1.8, where it would interpolate
the object id of the view instance. In 1.9,
that id becomes "object_id", which is what
one would have to change the code to in order
to preserve the current behavior.
However, it seems more correct to simply pull the
correct id of the contextual model object instead
(which is what I did).
[#5773] fix teacher_wiki_and_tiny_images spec
This is an instance of using a string as an
enumerable; adding a guard clause to
lib/sticky_sis_fields.rb to transform the string
argument into an array fixes it
[#5773] fix selenium/student_submissions_spec.rb
This is an issue with SSLCommon's use of
net/https. In older ruby versions there are 2
parameters returned (the response, and the body).
Now only the response is returned,
so the response object has to be asked for the
body explicitly. This fix was made in
spec/selenium/helpers/files_common.rb
Change-Id: I66a25ebbc1d8e5af7b7117375210172d287a77c7
Reviewed-on: https://gerrit.instructure.com/14641
Tested-by: Jenkins <jenkins@instructure.com>
Reviewed-by: Brian Palmer <brianp@instructure.com>
2012-10-24 05:08:56 +08:00
|
|
|
fields = [fields] if (fields.is_a? String)
|
2011-10-13 07:28:30 +08:00
|
|
|
clear_sis_stickiness(*(stuck_sis_fields.to_a))
|
|
|
|
add_sis_stickiness(*(fields.map(&:to_sym).to_set))
|
|
|
|
end
|
|
|
|
|
|
|
|
# clear stickiness on a set of fields
|
2011-09-22 01:36:45 +08:00
|
|
|
def clear_sis_stickiness(*fields)
|
2011-10-13 07:28:30 +08:00
|
|
|
@sis_fields_to_stick ||= [].to_set
|
2011-09-22 01:36:45 +08:00
|
|
|
@sis_fields_to_unstick ||= [].to_set
|
2011-10-13 07:28:30 +08:00
|
|
|
fields.map(&:to_sym).each do |field|
|
|
|
|
@sis_fields_to_stick.delete field
|
|
|
|
@sis_fields_to_unstick.add field
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
# make some fields sticky
|
|
|
|
def add_sis_stickiness(*fields)
|
|
|
|
@sis_fields_to_stick ||= [].to_set
|
|
|
|
@sis_fields_to_unstick ||= [].to_set
|
|
|
|
fields.map(&:to_sym).each do |field|
|
|
|
|
@sis_fields_to_stick.add field
|
|
|
|
@sis_fields_to_unstick.delete field
|
2011-09-22 01:36:45 +08:00
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
private
|
|
|
|
def load_stuck_sis_fields_cache
|
|
|
|
@stuck_sis_fields_cache ||= (read_attribute(:stuck_sis_fields) || '').split(',').map(&:to_sym).to_set
|
|
|
|
end
|
2011-10-13 07:28:30 +08:00
|
|
|
|
|
|
|
def calculate_currently_stuck_sis_fields
|
|
|
|
@sis_fields_to_stick ||= [].to_set
|
|
|
|
@sis_fields_to_unstick ||= [].to_set
|
|
|
|
changed_sis_fields = self.class.sticky_sis_fields & (self.changed.map(&:to_sym).to_set | @sis_fields_to_stick)
|
|
|
|
return (load_stuck_sis_fields_cache | changed_sis_fields) - @sis_fields_to_unstick
|
|
|
|
end
|
2012-07-03 07:55:58 +08:00
|
|
|
|
|
|
|
def reload_with_sis_stickiness(*a)
|
|
|
|
@stuck_sis_fields_cache = @sis_fields_to_stick = @sis_fields_to_unstick = nil
|
|
|
|
reload_without_sis_stickiness(*a)
|
|
|
|
end
|
2011-09-22 01:36:45 +08:00
|
|
|
end
|
|
|
|
|
|
|
|
module ClassMethods
|
|
|
|
|
2011-10-13 07:28:30 +08:00
|
|
|
# specify which fields are able to be stuck
|
2011-09-22 01:36:45 +08:00
|
|
|
def are_sis_sticky(*fields)
|
|
|
|
self.sticky_sis_fields = fields.map(&:to_sym).to_set
|
|
|
|
end
|
|
|
|
|
2011-10-13 07:28:30 +08:00
|
|
|
# takes a block and runs it with the following options:
|
|
|
|
# override_sis_stickiness: default false,
|
|
|
|
# if true, all code inside the block will be run as if the class
|
|
|
|
# mixing in this module has no stuck sis fields
|
|
|
|
# add_sis_stickiness: default false,
|
|
|
|
# unless add_sis_stickiness (or clear_sis_stickiness) is true, the
|
|
|
|
# set_sis_stickiness callback is skipped, so no sis stickiness is
|
|
|
|
# modified. if true, the set_sis_stickiness is enabled like normal,
|
|
|
|
# such that everything is processed like non-sis. it doesn't really
|
|
|
|
# make tons of sense to use this feature without
|
|
|
|
# override_sis_stickiness.
|
|
|
|
# clear_sis_stickiness: default false,
|
|
|
|
# if true, the set_sis_stickiness callback is enabled and configured
|
|
|
|
# to write out an empty stickiness list on every save.
|
|
|
|
def process_as_sis(opts={})
|
|
|
|
self.sis_stickiness_options ||= {}
|
|
|
|
old_options = self.sis_stickiness_options.clone
|
|
|
|
[:override_sis_stickiness, :clear_sis_stickiness].each do |option|
|
|
|
|
self.sis_stickiness_options[option] = opts[option]
|
|
|
|
end
|
2011-09-22 01:36:45 +08:00
|
|
|
begin
|
2011-10-13 07:28:30 +08:00
|
|
|
if opts[:add_sis_stickiness] || opts[:clear_sis_stickiness]
|
2011-09-22 01:36:45 +08:00
|
|
|
yield
|
2011-10-13 07:28:30 +08:00
|
|
|
else
|
|
|
|
self.skip_callback(:set_sis_stickiness) do
|
|
|
|
yield
|
|
|
|
end
|
2011-09-22 01:36:45 +08:00
|
|
|
end
|
|
|
|
ensure
|
2011-10-13 07:28:30 +08:00
|
|
|
self.sis_stickiness_options = old_options
|
2011-09-22 01:36:45 +08:00
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
end
|
|
|
|
|
|
|
|
def self.included(klass)
|
|
|
|
if klass < ActiveRecord::Base
|
|
|
|
klass.send :extend, ClassMethods
|
|
|
|
klass.send :include, InstanceMethods
|
|
|
|
klass.cattr_accessor :sticky_sis_fields
|
2011-10-13 07:28:30 +08:00
|
|
|
klass.cattr_accessor :sis_stickiness_options
|
2011-09-22 01:36:45 +08:00
|
|
|
klass.before_update :set_sis_stickiness
|
2012-07-03 07:55:58 +08:00
|
|
|
klass.alias_method_chain :reload, :sis_stickiness
|
2011-09-22 01:36:45 +08:00
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
end
|