make [quiz|assignment].locked_for? vdd aware

fixes #CNVS-517
fixes #CNVS-761

test plan
- start with a course with students in different sections
- create a quiz with a lock date that locks the quiz currently
- create a lock date override that unlocks the quiz for one section
- ensure that a student from a section that the override does not apply to
  does see a lock icon on the course's quizzes list for the quiz
- ensure that a student from the section that the override does apply to
  does not see a lock icon on the course's quizzes list for the quiz

Change-Id: Ic1f553818ff106e1d29a8f1b66d8445b99aecffc
Reviewed-on: https://gerrit.instructure.com/16228
Tested-by: Jenkins <jenkins@instructure.com>
QA-Review: Marc LeGendre <marc@instructure.com>
Reviewed-by: Simon Williams <simon@instructure.com>
This commit is contained in:
Joel Hough 2012-12-19 13:38:12 -07:00
parent 15b465dd18
commit a9626310f8
5 changed files with 60 additions and 17 deletions

View File

@ -731,14 +731,14 @@ class Assignment < ActiveRecord::Base
end
def locked_for?(user=nil, opts={})
locked = false
return false if opts[:check_policies] && self.grants_right?(user, nil, :update)
Rails.cache.fetch(locked_cache_key(user), :expires_in => 1.minute) do
locked = false
if (self.unlock_at && self.unlock_at > Time.now)
locked = {:asset_string => self.asset_string, :unlock_at => self.unlock_at}
elsif (self.lock_at && self.lock_at <= Time.now)
locked = {:asset_string => self.asset_string, :lock_at => self.lock_at}
assignment_for_user = self.overridden_for(user)
if (assignment_for_user.unlock_at && assignment_for_user.unlock_at > Time.now)
locked = {:asset_string => self.asset_string, :unlock_at => assignment_for_user.unlock_at}
elsif (assignment_for_user.lock_at && assignment_for_user.lock_at <= Time.now)
locked = {:asset_string => self.asset_string, :lock_at => assignment_for_user.lock_at}
elsif self.could_be_locked && item = locked_by_module_item?(user, opts[:deep_check_if_needed])
locked = {:asset_string => self.asset_string, :context_module => item.context_module.attributes}
end

View File

@ -626,15 +626,16 @@ class Quiz < ActiveRecord::Base
return false if opts[:check_policies] && self.grants_right?(user, nil, :update)
Rails.cache.fetch(locked_cache_key(user), :expires_in => 1.minute) do
locked = false
if (self.unlock_at && self.unlock_at > Time.now)
quiz_for_user = self.overridden_for(user)
if (quiz_for_user.unlock_at && quiz_for_user.unlock_at > Time.now)
sub = user && quiz_submissions.find_by_user_id(user.id)
if !sub || !sub.manually_unlocked
locked = {:asset_string => self.asset_string, :unlock_at => self.unlock_at}
locked = {:asset_string => self.asset_string, :unlock_at => quiz_for_user.unlock_at}
end
elsif (self.lock_at && self.lock_at <= Time.now)
elsif (quiz_for_user.lock_at && quiz_for_user.lock_at <= Time.now)
sub = user && quiz_submissions.find_by_user_id(user.id)
if !sub || !sub.manually_unlocked
locked = {:asset_string => self.asset_string, :lock_at => self.lock_at}
locked = {:asset_string => self.asset_string, :lock_at => quiz_for_user.lock_at}
end
elsif (self.for_assignment? && l = self.assignment.locked_for?(user, opts))
sub = user && quiz_submissions.find_by_user_id(user.id)

View File

@ -21,13 +21,14 @@ module AssignmentOverrideApplicator
# version) and user, determine the list of overrides, apply them to the
# assignment or quiz, and return the overridden stand-in.
def self.assignment_overridden_for(assignment_or_quiz, user)
return assignment_or_quiz if user.nil? or assignment_or_quiz.overridden_for_user_id == user.id
overrides = self.overrides_for_assignment_and_user(assignment_or_quiz, user)
if overrides.empty?
assignment_or_quiz
else
self.assignment_with_overrides(assignment_or_quiz, overrides)
end
result_assignment_or_quiz = self.assignment_with_overrides(assignment_or_quiz, overrides) unless overrides.empty?
result_assignment_or_quiz ||= assignment_or_quiz
result_assignment_or_quiz.overridden_for_user_id = user.id
result_assignment_or_quiz
end
def self.quiz_overridden_for(quiz, user)

View File

@ -1,6 +1,7 @@
module DatesOverridable
attr_accessor :applied_overrides
attr_accessor :overridden_for_user_id
def self.included(base)
base.has_many :assignment_overrides, :dependent => :destroy
base.has_many :active_assignment_overrides, :class_name => 'AssignmentOverride', :conditions => {:workflow_state => 'active'}
@ -168,4 +169,4 @@ module DatesOverridable
return as_student, as_instructor
end
end
end

View File

@ -661,6 +661,46 @@ describe AssignmentOverrideApplicator do
end
end
describe "assignment_overridden_for" do
before :each do
student_in_course
@assignment = assignment_model(:course => @course)
end
it "should note the user id for whom overrides were applied" do
@adhoc_override = assignment_override_model(:assignment => @assignment)
@override_student = @adhoc_override.assignment_override_students.build
@override_student.user = @student
@override_student.save!
@adhoc_override.override_due_at(7.days.from_now)
@adhoc_override.save!
@overridden_assignment = AssignmentOverrideApplicator.assignment_overridden_for(@assignment, @student)
@overridden_assignment.overridden_for_user_id.should == @student.id
end
it "should note the user id for whom overrides were not found" do
@overridden_assignment = AssignmentOverrideApplicator.assignment_overridden_for(@assignment, @student)
@overridden_assignment.overridden_for_user_id.should == @student.id
end
it "should apply new overrides if an overridden assignment is overridden for a new user" do
@student1 = @student
@overridden_assignment = AssignmentOverrideApplicator.assignment_overridden_for(@assignment, @student1)
@overridden_assignment.overridden_for_user_id.should == @student1.id
student_in_course
@student2 = @student
AssignmentOverrideApplicator.expects(:overrides_for_assignment_and_user).with(@overridden_assignment, @student2).returns([])
@reoverridden_assignment = AssignmentOverrideApplicator.assignment_overridden_for(@overridden_assignment, @student2)
end
it "should not attempt to apply overrides if an overridden assignment is overridden for the same user" do
@overridden_assignment = AssignmentOverrideApplicator.assignment_overridden_for(@assignment, @student)
@overridden_assignment.overridden_for_user_id.should == @student.id
AssignmentOverrideApplicator.expects(:overrides_for_assignment_and_user).never
@reoverridden_assignment = AssignmentOverrideApplicator.assignment_overridden_for(@overridden_assignment, @student)
end
end
it "should use the full stack" do
student_in_course
original_due_at = 3.days.from_now