<commit_before>#
# 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/>.
#

class Quiz < ActiveRecord::Base
  include Workflow
  include HasContentTags
  include CopyAuthorizedLinks
  include ActionView::Helpers::SanitizeHelper
  extend ActionView::Helpers::SanitizeHelper::ClassMethods
  attr_accessible :title, :description, :points_possible, :assignment_id, :shuffle_answers,
    :show_correct_answers, :time_limit, :allowed_attempts, :scoring_policy, :quiz_type,
    :lock_at, :unlock_at, :due_at, :access_code, :anonymous_submissions, :assignment_group_id,
    :hide_results, :locked, :ip_filter, :require_lockdown_browser,
    :require_lockdown_browser_for_results, :context

  attr_readonly :context_id, :context_type
  
  has_many :quiz_questions, :dependent => :destroy, :order => 'position'
  has_many :quiz_submissions, :dependent => :destroy
  has_many :quiz_groups, :dependent => :destroy, :order => 'position'
  has_one :context_module_tag, :as => :content, :class_name => 'ContentTag', :conditions => ['content_tags.tag_type = ? AND workflow_state != ?', 'context_module', 'deleted'], :include => {:context_module => [:context_module_progressions, :content_tags]}
  belongs_to :context, :polymorphic => true
  belongs_to :assignment
  belongs_to :cloned_item
  adheres_to_policy
  validates_length_of :description, :maximum => maximum_long_text_length, :allow_nil => true, :allow_blank => true
  validates_length_of :title, :maximum => maximum_string_length, :allow_nil => true
  validates_presence_of :context_id
  validates_presence_of :context_type
  
  sanitize_field :description, Instructure::SanitizeField::SANITIZE
  copy_authorized_links(:description) { [self.context, nil] }
  before_save :set_defaults
  before_save :build_assignment
  after_save :update_assignment
  after_save :touch_context
  
  serialize :quiz_data
  
  simply_versioned

  def infer_times
    # set the time to 11:59 pm in the creator's time zone, if none given
    self.due_at += ((60 * 60 * 24) - 60) if self.due_at && self.due_at.hour == 0 && self.due_at.min == 0
    self.lock_at += ((60 * 60 * 24) - 60) if self.lock_at && self.lock_at.hour == 0 && self.lock_at.min == 0
  end

  def set_defaults
    self.shuffle_answers = false if self.shuffle_answers == nil
    self.show_correct_answers = true if self.show_correct_answers == nil
    self.allowed_attempts = 1 if self.allowed_attempts == nil
    self.scoring_policy = "keep_highest" if self.scoring_policy == nil
    self.due_at ||= [[self.lock_at, self.due_at].compact.min, self.unlock_at].compact.max
    self.ip_filter = nil if self.ip_filter && self.ip_filter.strip.empty?
    if !self.available? && self.quiz_type != 'survey' && self.quiz_type != 'graded_survey'
      self.points_possible = self.current_points_possible
    end
    self.title = "Unnamed Quiz" if self.title.blank?
    self.quiz_type ||= "assignment"
    self.last_assignment_id = self.assignment_id_was if self.assignment_id_was
    if (!graded? && self.assignment_id) || (self.assignment_id_was && self.assignment_id != self.assignment_id_was)
      @old_assignment_id = self.assignment_id_was
      self.assignment_id = nil
    end
    self.assignment_group_id ||= self.assignment.assignment_group_id if self.assignment
    self.question_count = self.question_count(true)
    @update_existing_submissions = true if self.for_assignment? && self.quiz_type_changed?<commit_msg>don't force a due date for any quiz that has lock or unlock dates<commit_after>#
# 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/>.
#

class Quiz < ActiveRecord::Base
  include Workflow
  include HasContentTags
  include CopyAuthorizedLinks
  include ActionView::Helpers::SanitizeHelper
  extend ActionView::Helpers::SanitizeHelper::ClassMethods
  attr_accessible :title, :description, :points_possible, :assignment_id, :shuffle_answers,
    :show_correct_answers, :time_limit, :allowed_attempts, :scoring_policy, :quiz_type,
    :lock_at, :unlock_at, :due_at, :access_code, :anonymous_submissions, :assignment_group_id,
    :hide_results, :locked, :ip_filter, :require_lockdown_browser,
    :require_lockdown_browser_for_results, :context

  attr_readonly :context_id, :context_type
  
  has_many :quiz_questions, :dependent => :destroy, :order => 'position'
  has_many :quiz_submissions, :dependent => :destroy
  has_many :quiz_groups, :dependent => :destroy, :order => 'position'
  has_one :context_module_tag, :as => :content, :class_name => 'ContentTag', :conditions => ['content_tags.tag_type = ? AND workflow_state != ?', 'context_module', 'deleted'], :include => {:context_module => [:context_module_progressions, :content_tags]}
  belongs_to :context, :polymorphic => true
  belongs_to :assignment
  belongs_to :cloned_item
  adheres_to_policy
  validates_length_of :description, :maximum => maximum_long_text_length, :allow_nil => true, :allow_blank => true
  validates_length_of :title, :maximum => maximum_string_length, :allow_nil => true
  validates_presence_of :context_id
  validates_presence_of :context_type
  
  sanitize_field :description, Instructure::SanitizeField::SANITIZE
  copy_authorized_links(:description) { [self.context, nil] }
  before_save :set_defaults
  before_save :build_assignment
  after_save :update_assignment
  after_save :touch_context
  
  serialize :quiz_data
  
  simply_versioned

  def infer_times
    # set the time to 11:59 pm in the creator's time zone, if none given
    self.due_at += ((60 * 60 * 24) - 60) if self.due_at && self.due_at.hour == 0 && self.due_at.min == 0
    self.lock_at += ((60 * 60 * 24) - 60) if self.lock_at && self.lock_at.hour == 0 && self.lock_at.min == 0
  end

  def set_defaults
    self.shuffle_answers = false if self.shuffle_answers == nil
    self.show_correct_answers = true if self.show_correct_answers == nil
    self.allowed_attempts = 1 if self.allowed_attempts == nil
    self.scoring_policy = "keep_highest" if self.scoring_policy == nil
    self.due_at ||= self.lock_at if self.lock_at.present?
    self.ip_filter = nil if self.ip_filter && self.ip_filter.strip.empty?
    if !self.available? && self.quiz_type != 'survey' && self.quiz_type != 'graded_survey'
      self.points_possible = self.current_points_possible
    end
    self.title = "Unnamed Quiz" if self.title.blank?
    self.quiz_type ||= "assignment"
    self.last_assignment_id = self.assignment_id_was if self.assignment_id_was
    if (!graded? && self.assignment_id) || (self.assignment_id_was && self.assignment_id != self.assignment_id_was)
      @old_assignment_id = self.assignment_id_was
      self.assignment_id = nil
    end
    self.assignment_group_id ||= self.assignment.assignment_group_id if self.assignment
    self.question_count = self.question_count(true)
    @update_existing_submissions = true if self.for_assignment? && self.quiz_type_changed?
{'fraction_non_alphanumeric': 0.10057114477278371, 'fraction_numerical': 0.007449714427613608, 'mean_word_length': 4.896778916544656, 'pattern_counts': {'":': 0, '<': 7, '<?xml version=': 0, '>': 37, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2050734', 'n_tokens_mistral': 2675, 'n_tokens_neox': 2578, 'n_words': 674}