Update DueDateCacher to use EffectiveDueDates
fixes CNVS-33651 Test plan: * Create a course * Enroll 3 students * Create 2 assignments with different due dates * In rails console: * Submission.pluck(:assignment_id, :cached_due_date) should return an array of 6 tuples of (assignment id, its due date) * Create an override for one student on one assignment * In rails console: * Submission.where( assignment_id: <assignment picked above>, user_id: <user picked above> ).cached_due_date should equal the override date * Smoke test grading and viewing students in different places to make sure the new dummy submissions aren't breaking anything Change-Id: Idc2721fd3f05214555db780b452ddf53e67ff404 Reviewed-on: https://gerrit.instructure.com/109027 Tested-by: Jenkins Reviewed-by: Keith T. Garner <kgarner@instructure.com> QA-Review: Anju Reddy <areddy@instructure.com> Product-Review: Keith T. Garner <kgarner@instructure.com>
This commit is contained in:
parent
5ff873c6da
commit
1e052eae19
|
@ -201,7 +201,7 @@ class SubmissionsApiController < ApplicationController
|
|||
@current_user, section_ids)
|
||||
.pluck(:user_id)
|
||||
end
|
||||
submissions = @assignment.submissions.where(user_id: student_ids).preload(:originality_reports)
|
||||
submissions = @assignment.submissions.not_placeholder.where(user_id: student_ids).preload(:originality_reports)
|
||||
|
||||
if includes.include?("visibility")
|
||||
json = bulk_process_submissions_for_visibility(submissions, includes)
|
||||
|
@ -368,7 +368,7 @@ class SubmissionsApiController < ApplicationController
|
|||
"assignments.workflow_state != 'deleted'"
|
||||
)
|
||||
end
|
||||
submissions = submissions_scope.preload(:originality_reports).to_a
|
||||
submissions = submissions_scope.not_placeholder.preload(:originality_reports).to_a
|
||||
bulk_load_attachments_and_previews(submissions)
|
||||
submissions_for_user = submissions.group_by(&:user_id)
|
||||
|
||||
|
@ -417,7 +417,7 @@ class SubmissionsApiController < ApplicationController
|
|||
order_by = params[:order] == "graded_at" ? "graded_at" : :id
|
||||
order_direction = params[:order_direction] == "descending" ? "desc nulls last" : "asc"
|
||||
order = "#{order_by} #{order_direction}"
|
||||
submissions = @context.submissions.except(:order).where(:user_id => student_ids).order(order)
|
||||
submissions = @context.submissions.not_placeholder.except(:order).where(user_id: student_ids).order(order)
|
||||
submissions = submissions.where(:assignment_id => assignments) unless assignments.empty?
|
||||
submissions = submissions.preload(:user, :originality_reports)
|
||||
|
||||
|
@ -610,8 +610,7 @@ class SubmissionsApiController < ApplicationController
|
|||
@user = get_user_considering_section(params[:user_id])
|
||||
|
||||
authorized = false
|
||||
@submission = @assignment.submissions.where(user_id: @user).first ||
|
||||
@assignment.submissions.build(user: @user)
|
||||
@submission = @assignment.submissions.find_or_create_by!(user: @user)
|
||||
|
||||
if params[:submission] || params[:rubric_assessment]
|
||||
authorized = authorized_action(@submission, @current_user, :grade)
|
||||
|
@ -732,7 +731,7 @@ class SubmissionsApiController < ApplicationController
|
|||
students = Api.paginate(student_scope, self, api_v1_course_assignment_gradeable_students_url(@context, @assignment))
|
||||
if (include_pg = includes.include?('provisional_grades'))
|
||||
return unless authorized_action(@context, @current_user, :moderate_grades)
|
||||
submissions = @assignment.submissions.where(user_id: students).preload(:provisional_grades).index_by(&:user_id)
|
||||
submissions = @assignment.submissions.not_placeholder.where(user_id: students).preload(:provisional_grades).index_by(&:user_id)
|
||||
selections = @assignment.moderated_grading_selections.where(student_id: students).index_by(&:student_id)
|
||||
end
|
||||
render :json => students.map { |student|
|
||||
|
@ -908,7 +907,7 @@ class SubmissionsApiController < ApplicationController
|
|||
def change_topic_read_state(new_state)
|
||||
@assignment = @context.assignments.active.find(params[:assignment_id])
|
||||
@user = get_user_considering_section(params[:user_id])
|
||||
@submission = @assignment.submissions.where(user_id: @user).first || @assignment.submissions.build(user: @user)
|
||||
@submission = @assignment.submissions.find_or_create_by!(user: @user)
|
||||
|
||||
render_state_change_result @submission.change_read_state(new_state, @current_user)
|
||||
end
|
||||
|
|
|
@ -392,9 +392,18 @@ class Assignment < ActiveRecord::Base
|
|||
grading_period = GradingPeriod.for_date_in_course(date: due_at, course: context)
|
||||
return true if grading_period_was&.id == grading_period&.id
|
||||
|
||||
[grading_period_was, grading_period].compact.each do |gp|
|
||||
context.recompute_student_scores(grading_period_id: gp)
|
||||
if grading_period_was
|
||||
# recalculate just the old grading period's score
|
||||
context.recompute_student_scores(grading_period_id: grading_period_was, update_course_score: false)
|
||||
end
|
||||
# recalculate the new grading period's score. If the grading period group is
|
||||
# weighted, then we need to recalculate the overall course score too. (If
|
||||
# grading period is nil, make sure we pass true for `update_course_score`
|
||||
# so we can use a singleton job.)
|
||||
context.recompute_student_scores(
|
||||
grading_period_id: grading_period,
|
||||
update_course_score: !grading_period || grading_period.grading_period_group&.weighted?
|
||||
)
|
||||
true
|
||||
end
|
||||
private :update_grading_period_grades
|
||||
|
|
|
@ -102,9 +102,19 @@ class AssignmentOverride < ActiveRecord::Base
|
|||
students = applies_to_students.map(&:id)
|
||||
return true if students.blank?
|
||||
|
||||
[grading_period_was, grading_period].compact.each do |gp|
|
||||
course.recompute_student_scores(students, grading_period_id: gp)
|
||||
if grading_period_was
|
||||
# recalculate just the old grading period's score
|
||||
course.recompute_student_scores(students, grading_period_id: grading_period_was, update_course_score: false)
|
||||
end
|
||||
# recalculate the new grading period's score. If the grading period group is
|
||||
# weighted, then we need to recalculate the overall course score too. (If
|
||||
# grading period is nil, make sure we pass true for `update_course_score`
|
||||
# so we can use a singleton job.)
|
||||
course.recompute_student_scores(
|
||||
students,
|
||||
grading_period_id: grading_period,
|
||||
update_course_score: !grading_period || grading_period.grading_period_group&.weighted?
|
||||
)
|
||||
true
|
||||
end
|
||||
private :update_grading_period_grades
|
||||
|
|
|
@ -1046,9 +1046,11 @@ class Course < ActiveRecord::Base
|
|||
end
|
||||
end
|
||||
|
||||
def recompute_student_scores(student_ids = nil, grading_period_id: nil, update_all_grading_period_scores: true)
|
||||
def recompute_student_scores(student_ids = nil, grading_period_id: nil,
|
||||
update_all_grading_period_scores: true,
|
||||
update_course_score: true)
|
||||
inst_job_opts = {}
|
||||
if student_ids.blank? && grading_period_id.nil? && update_all_grading_period_scores
|
||||
if student_ids.blank? && grading_period_id.nil? && update_all_grading_period_scores && update_course_score
|
||||
# if we have all default args, let's queue this job in a singleton to avoid duplicates
|
||||
inst_job_opts[:singleton] = "recompute_student_scores:#{global_id}"
|
||||
end
|
||||
|
|
|
@ -68,6 +68,7 @@ class EnrollmentTerm < ActiveRecord::Base
|
|||
def recompute_course_scores(update_all_grading_period_scores: true)
|
||||
courses.active.each do |course|
|
||||
course.recompute_student_scores(update_all_grading_period_scores: update_all_grading_period_scores)
|
||||
DueDateCacher.recompute_course(course)
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
@ -242,6 +242,7 @@ class GradingPeriod < ActiveRecord::Base
|
|||
gp_id = time_boundaries_changed? ? id : nil
|
||||
if course_group?
|
||||
recompute_score_for(grading_period_group.course, gp_id)
|
||||
DueDateCacher.recompute_course(grading_period_group.course) if gp_id
|
||||
else
|
||||
self.send_later_if_production(:recompute_scores_for_term_courses, gp_id) # there could be a lot of courses here
|
||||
end
|
||||
|
|
|
@ -27,6 +27,7 @@ class GradingPeriodGroup < ActiveRecord::Base
|
|||
validate :associated_with_course_or_root_account, if: :active?
|
||||
|
||||
after_save :recompute_course_scores, if: :weighted_changed?
|
||||
after_save :recache_grading_period, if: :course_id_changed?
|
||||
after_destroy :dissociate_enrollment_terms
|
||||
|
||||
set_policy do
|
||||
|
@ -75,6 +76,11 @@ class GradingPeriodGroup < ActiveRecord::Base
|
|||
enrollment_terms.each { |term| term.recompute_course_scores(update_all_grading_period_scores: false) }
|
||||
end
|
||||
|
||||
def recache_grading_period
|
||||
DueDateCacher.recompute_course(course) if course
|
||||
DueDateCacher.recompute_course(course_id_was) if course_id_was
|
||||
end
|
||||
|
||||
def associated_with_course_or_root_account
|
||||
if course_id.blank? && account_id.blank?
|
||||
errors.add(:course_id, t("cannot be nil when account_id is nil"))
|
||||
|
|
|
@ -58,6 +58,7 @@ class Submission < ActiveRecord::Base
|
|||
belongs_to :assignment
|
||||
belongs_to :user
|
||||
belongs_to :grader, :class_name => 'User'
|
||||
belongs_to :grading_period
|
||||
belongs_to :group
|
||||
belongs_to :media_object
|
||||
belongs_to :student, :class_name => 'User', :foreign_key => :user_id
|
||||
|
@ -400,20 +401,14 @@ class Submission < ActiveRecord::Base
|
|||
else
|
||||
Rails.logger.info "GRADES: submission #{global_id} score changed. recomputing grade for course #{context.global_id} user #{user_id}."
|
||||
self.class.connection.after_transaction_commit do
|
||||
effective_due_dates = EffectiveDueDates.new(self.context, self.assignment_id)
|
||||
grading_period_id = effective_due_dates.grading_period_id_for(
|
||||
student_id: self.user_id,
|
||||
assignment_id: self.assignment_id
|
||||
)
|
||||
Enrollment.recompute_final_score_in_singleton(
|
||||
self.user_id,
|
||||
self.context.id,
|
||||
grading_period_id: grading_period_id,
|
||||
update_all_grading_period_scores: false
|
||||
grading_period_id: grading_period_id
|
||||
)
|
||||
end
|
||||
end
|
||||
self.assignment.send_later_if_production(:multiple_module_actions, [self.user_id], :scored, self.score) if self.assignment
|
||||
self.assignment&.send_later_if_production(:multiple_module_actions, [self.user_id], :scored, self.score)
|
||||
end
|
||||
true
|
||||
end
|
||||
|
@ -1089,8 +1084,9 @@ class Submission < ActiveRecord::Base
|
|||
end
|
||||
|
||||
self.accepted_at = nil unless late_policy_status == 'late'
|
||||
self.submitted_at ||= Time.now if self.has_submission? || (self.submission_type && !self.submission_type.empty?)
|
||||
self.submitted_at ||= Time.now if self.has_submission?
|
||||
self.quiz_submission.reload if self.quiz_submission_id
|
||||
self.workflow_state = 'submitted' if self.unsubmitted? && self.submitted_at
|
||||
self.workflow_state = 'unsubmitted' if self.submitted? && !self.has_submission?
|
||||
self.workflow_state = 'graded' if self.grade && self.score && self.grade_matches_current_submission
|
||||
self.workflow_state = 'pending_review' if self.submission_type == 'online_quiz' && self.quiz_submission.try(:latest_submitted_attempt).try(:pending_review?)
|
||||
|
@ -1229,6 +1225,8 @@ class Submission < ActiveRecord::Base
|
|||
|
||||
student_id = user_id || self.user.try(:id)
|
||||
|
||||
# TODO: replace this check with `grading_period&.closed?` once
|
||||
# the populate_grading_period_for_submissions data fixup finishes
|
||||
if assignment.in_closed_grading_period_for_student?(student_id)
|
||||
:assignment_in_closed_grading_period
|
||||
else
|
||||
|
@ -1257,6 +1255,8 @@ class Submission < ActiveRecord::Base
|
|||
|
||||
student_id = self.user_id || self.user.try(:id)
|
||||
|
||||
# TODO: replace this check with `grading_period&.closed?` once
|
||||
# the populate_grading_period_for_submissions data fixup finishes
|
||||
if assignment.in_closed_grading_period_for_student?(student_id)
|
||||
:assignment_in_closed_grading_period
|
||||
else
|
||||
|
@ -1483,7 +1483,7 @@ class Submission < ActiveRecord::Base
|
|||
unless submission_type
|
||||
self.submission_type ||= "online_url" if self.url
|
||||
self.submission_type ||= "online_text_entry" if self.body
|
||||
self.submission_type ||= "online_upload" if !self.attachments.empty?
|
||||
self.submission_type ||= "online_upload" unless self.attachment_ids.blank?
|
||||
end
|
||||
true
|
||||
end
|
||||
|
@ -1506,6 +1506,9 @@ class Submission < ActiveRecord::Base
|
|||
|
||||
scope :having_submission, -> { where("submissions.submission_type IS NOT NULL") }
|
||||
scope :without_submission, -> { where(submission_type: nil, workflow_state: "unsubmitted") }
|
||||
scope :not_placeholder, -> {
|
||||
where("submissions.submission_type IS NOT NULL or submissions.excused or submissions.score IS NOT NULL")
|
||||
}
|
||||
|
||||
scope :include_user, -> { preload(:user) }
|
||||
|
||||
|
|
|
@ -19,7 +19,10 @@ class InitializeSubmissionCachedDueDate < ActiveRecord::Migration[4.2]
|
|||
tag :postdeploy
|
||||
|
||||
def self.up
|
||||
DataFixup::InitializeSubmissionCachedDueDate.send_later_if_production(:run)
|
||||
DataFixup::InitializeSubmissionCachedDueDate.send_later_if_production_enqueue_args(
|
||||
:run,
|
||||
singleton: "DataFixup:InitializeSubmissionCachedDueDate:#{Shard.current.id}"
|
||||
)
|
||||
end
|
||||
|
||||
def self.down
|
||||
|
|
|
@ -19,6 +19,9 @@ class PopulateOverriddenDueAtForDueDateCacher < ActiveRecord::Migration[4.2]
|
|||
tag :postdeploy
|
||||
|
||||
def self.up
|
||||
DataFixup::PopulateOverriddenDueAtForDueDateCacher.send_later_if_production(:run)
|
||||
DataFixup::InitializeSubmissionCachedDueDate.send_later_if_production_enqueue_args(
|
||||
:run,
|
||||
singleton: "DataFixup:InitializeSubmissionCachedDueDate:#{Shard.current.id}"
|
||||
)
|
||||
end
|
||||
end
|
||||
|
|
|
@ -0,0 +1,8 @@
|
|||
class AddGradingPeriodToSubmissions < ActiveRecord::Migration[4.2]
|
||||
tag :predeploy
|
||||
|
||||
def change
|
||||
add_column :submissions, :grading_period_id, :integer, limit: 8
|
||||
add_foreign_key :submissions, :grading_periods
|
||||
end
|
||||
end
|
|
@ -0,0 +1,10 @@
|
|||
class PopulateGradingPeriodForSubmissions < ActiveRecord::Migration[4.2]
|
||||
tag :postdeploy
|
||||
|
||||
def self.up
|
||||
DataFixup::InitializeSubmissionCachedDueDate.send_later_if_production_enqueue_args(
|
||||
:run,
|
||||
singleton: "DataFixup:InitializeSubmissionCachedDueDate:#{Shard.current.id}"
|
||||
)
|
||||
end
|
||||
end
|
|
@ -17,8 +17,10 @@
|
|||
|
||||
module DataFixup::InitializeSubmissionCachedDueDate
|
||||
def self.run
|
||||
Assignment.find_ids_in_ranges do |min, max|
|
||||
DueDateCacher.recompute_batch(min.to_i..max.to_i)
|
||||
Course.find_in_batches do |courses|
|
||||
courses.each do |course|
|
||||
DueDateCacher.recompute_course(course, nil, priority: Delayed::LOWER_PRIORITY)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1,35 +0,0 @@
|
|||
#
|
||||
# Copyright (C) 2011 - present 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/>.
|
||||
#
|
||||
|
||||
module DataFixup::PopulateOverriddenDueAtForDueDateCacher
|
||||
def self.run
|
||||
Shackles.activate(:slave) do
|
||||
overrides = AssignmentOverride.active
|
||||
.overriding_due_at
|
||||
.select("DISTINCT assignment_id")
|
||||
.order(:assignment_id)
|
||||
|
||||
overrides.find_in_batches do |batch|
|
||||
assignment_ids = batch.map(&:assignment_id)
|
||||
Shackles.activate(:master) do
|
||||
DueDateCacher.recompute_batch(assignment_ids)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -17,144 +17,74 @@
|
|||
|
||||
class DueDateCacher
|
||||
def self.recompute(assignment)
|
||||
new([assignment]).send_later_if_production_enqueue_args(
|
||||
:recompute,
|
||||
singleton: "cached_due_date:calculator:Assignment:#{assignment.global_id}"
|
||||
)
|
||||
recompute_course(assignment.context, [assignment.id],
|
||||
singleton: "cached_due_date:calculator:Assignment:#{assignment.global_id}")
|
||||
end
|
||||
|
||||
def self.recompute_course(course, assignments = nil)
|
||||
assignments ||= Assignment.where(context_id: course, context_type: 'Course').pluck(:id)
|
||||
def self.recompute_course(course, assignments = nil, inst_jobs_opts = {})
|
||||
course = Course.find(course) unless course.is_a?(Course)
|
||||
inst_jobs_opts[:singleton] ||= "cached_due_date:calculator:Course:#{course.global_id}" if assignments.nil?
|
||||
assignments ||= Assignment.where(context: course).pluck(:id)
|
||||
return if assignments.empty?
|
||||
new(assignments).send_later_if_production_enqueue_args(:recompute,
|
||||
:strand => "cached_due_date:calculator:Course:#{Shard.global_id_for(course)}")
|
||||
new(course, assignments).send_later_if_production_enqueue_args(:recompute, inst_jobs_opts)
|
||||
end
|
||||
|
||||
def self.recompute_batch(assignments)
|
||||
new(assignments).send_later_if_production_enqueue_args(:recompute,
|
||||
:strand => "cached_due_date:calculator:batch:#{Shard.current.id}",
|
||||
:priority => Delayed::LOWER_PRIORITY)
|
||||
end
|
||||
|
||||
# expects all assignments to be on the same shard
|
||||
def initialize(assignments)
|
||||
def initialize(course, assignments)
|
||||
@course = course
|
||||
@assignments = assignments
|
||||
@shard = Shard.shard_for(assignments.first)
|
||||
end
|
||||
|
||||
def shard
|
||||
@shard
|
||||
def recompute
|
||||
# in a transaction on the correct shard:
|
||||
@course.shard.activate do
|
||||
Assignment.transaction do
|
||||
# Create dummy submissions for caching due date
|
||||
create_missing_submissions
|
||||
|
||||
# Update each submission with user's calculated due date and grading period
|
||||
queries = effective_due_dates.map do |assignment_id, students|
|
||||
students.map do |student_id, submission_info|
|
||||
due_date = submission_info[:due_at] ? "'#{submission_info[:due_at].iso8601}'::timestamptz" : 'NULL'
|
||||
"UPDATE #{Submission.quoted_table_name} SET
|
||||
cached_due_date = #{due_date},
|
||||
grading_period_id = #{submission_info[:grading_period_id] || 'NULL'}
|
||||
WHERE user_id = #{student_id} AND assignment_id = #{assignment_id};"
|
||||
end
|
||||
end.flatten
|
||||
|
||||
Assignment.connection.execute(queries.join("\n")) unless queries.empty?
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def submissions
|
||||
Submission.where(:assignment_id => @assignments)
|
||||
private
|
||||
|
||||
def effective_due_dates
|
||||
@effective_due_dates ||= EffectiveDueDates.for_course(@course, @assignments).to_hash
|
||||
end
|
||||
|
||||
def create_overridden_submissions
|
||||
# Get the students that have an overridden due date
|
||||
overridden_students = Assignment.participants_with_overridden_due_at(@assignments)
|
||||
return if overridden_students.length < 1
|
||||
def student_ids
|
||||
@students ||= effective_due_dates.map { |_, assignment| assignment.keys }.flatten.uniq
|
||||
end
|
||||
|
||||
# Get default submission values.
|
||||
default_submission = Submission.new
|
||||
default_submission.infer_values
|
||||
def create_missing_submissions
|
||||
return if student_ids.empty?
|
||||
|
||||
# Create insert scope
|
||||
insert_scope = Course
|
||||
.select("DISTINCT assignments.id, enrollments.user_id, '#{default_submission.workflow_state}',
|
||||
now() AT TIME ZONE 'UTC', assignments.context_code, 0")
|
||||
.select("DISTINCT assignments.id, enrollments.user_id, 'unsubmitted',
|
||||
now() AT TIME ZONE 'UTC', now() AT TIME ZONE 'UTC', assignments.context_code, 0")
|
||||
.joins("INNER JOIN #{Assignment.quoted_table_name} ON assignments.context_id = courses.id
|
||||
AND assignments.context_type = 'Course'
|
||||
LEFT OUTER JOIN #{Submission.quoted_table_name} ON submissions.user_id = enrollments.user_id
|
||||
AND submissions.assignment_id = assignments.id")
|
||||
.joins(:current_enrollments)
|
||||
.where("enrollments.user_id IN (?) AND assignments.id IN (?) AND submissions.id IS NULL", overridden_students, @assignments)
|
||||
.where("courses.id = ? AND enrollments.user_id IN (?) AND assignments.id IN (?) AND submissions.id IS NULL",
|
||||
@course.id, student_ids, @assignments)
|
||||
|
||||
# Create submissions that do not exist yet to calculate due dates for non submitted assignments.
|
||||
Assignment.connection.update("INSERT INTO #{Submission.quoted_table_name} (assignment_id,
|
||||
user_id, workflow_state, created_at, context_code,
|
||||
user_id, workflow_state, created_at, updated_at, context_code,
|
||||
process_attempts) #{insert_scope.to_sql}")
|
||||
end
|
||||
|
||||
def recompute
|
||||
# in a transaction on the correct shard:
|
||||
shard.activate do
|
||||
Assignment.transaction do
|
||||
# Create overridden due date submissions
|
||||
create_overridden_submissions
|
||||
overrides = AssignmentOverride.active.overriding_due_at.where(:assignment_id => @assignments)
|
||||
if overrides.exists?
|
||||
# create temporary table
|
||||
Assignment.connection.execute("CREATE TEMPORARY TABLE calculated_due_ats AS (#{submissions.select([
|
||||
"submissions.id AS submission_id",
|
||||
"submissions.user_id",
|
||||
"submissions.assignment_id",
|
||||
"assignments.due_at",
|
||||
"CAST(#{Submission.sanitize(false)} AS BOOL) AS overridden"
|
||||
]).joins(:assignment).where(assignments: { id: @assignments }).to_sql})")
|
||||
|
||||
# for each override, narrow to the affected subset of the table, and
|
||||
# apply
|
||||
overrides.each do |override|
|
||||
override_scope(Submission.from("calculated_due_ats"), override).update_all(
|
||||
:due_at => override.due_at,
|
||||
:overridden => true)
|
||||
end
|
||||
|
||||
# copy the results back to the submission table
|
||||
submissions.
|
||||
joins("INNER JOIN calculated_due_ats ON calculated_due_ats.submission_id=submissions.id").
|
||||
where("cached_due_date<>calculated_due_ats.due_at OR (cached_due_date IS NULL)<>(calculated_due_ats.due_at IS NULL)").
|
||||
update_all("cached_due_date=calculated_due_ats.due_at")
|
||||
|
||||
# clean up
|
||||
Assignment.connection.execute("DROP TABLE calculated_due_ats")
|
||||
else
|
||||
# just copy the assignment due dates to the submissions
|
||||
submissions.
|
||||
joins(:assignment).
|
||||
where("cached_due_date<>assignments.due_at OR (cached_due_date IS NULL)<>(assignments.due_at IS NULL)").
|
||||
update_all("cached_due_date=assignments.due_at")
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def override_scope(scope, override)
|
||||
scope = scope.where(calculated_due_ats: { assignment_id: override.assignment_id })
|
||||
|
||||
# and the override's due_at is more lenient than any existing overridden
|
||||
# due_at
|
||||
if override.due_at
|
||||
scope = scope.where(
|
||||
"NOT overridden OR (due_at IS NOT NULL AND due_at<?)",
|
||||
override.due_at)
|
||||
end
|
||||
|
||||
case override.set_type
|
||||
when 'ADHOC'
|
||||
# any student explicitly tagged by an adhoc override,
|
||||
scope.joins("INNER JOIN #{AssignmentOverrideStudent.quoted_table_name} ON assignment_override_students.user_id=calculated_due_ats.user_id").
|
||||
where(:assignment_override_students => {
|
||||
:assignment_override_id => override
|
||||
})
|
||||
when 'CourseSection'
|
||||
# any student in a section override's tagged section, or
|
||||
scope.joins("INNER JOIN #{Enrollment.quoted_table_name} ON enrollments.user_id=calculated_due_ats.user_id").
|
||||
where(:enrollments => {
|
||||
:workflow_state => 'active',
|
||||
:type => ['StudentEnrollment', 'StudentViewEnrollment'],
|
||||
:course_section_id => override.set_id
|
||||
})
|
||||
when 'Group'
|
||||
# any student in a group override's tagged group
|
||||
scope.joins("INNER JOIN #{GroupMembership.quoted_table_name} ON group_memberships.user_id=calculated_due_ats.user_id").
|
||||
where(:group_memberships => {
|
||||
:workflow_state => 'accepted',
|
||||
:group_id => override.set_id
|
||||
})
|
||||
when 'Noop'
|
||||
scope.none
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -43,7 +43,7 @@ class EffectiveDueDates
|
|||
hsh[assignment_id] ||= {}
|
||||
attributes = {}
|
||||
if include?(included, :due_at)
|
||||
attributes[:due_at] = row["due_at"] && Time.zone.parse(row["due_at"])
|
||||
attributes[:due_at] = row["due_at"] && Time.parse(row["due_at"])
|
||||
end
|
||||
if include?(included, :grading_period_id)
|
||||
attributes[:grading_period_id] = row["grading_period_id"] && row["grading_period_id"].to_i
|
||||
|
|
|
@ -1345,7 +1345,7 @@ describe DiscussionTopicsController, type: :request do
|
|||
@topic.save
|
||||
|
||||
student_in_course(:active_all => true)
|
||||
expect(@user.submissions).to be_empty
|
||||
expect(@user.submissions.not_placeholder).to be_empty
|
||||
|
||||
json = api_call(
|
||||
:post, "/api/v1/courses/#{@course.id}/discussion_topics/#{@topic.id}/entries.json",
|
||||
|
@ -1354,8 +1354,8 @@ describe DiscussionTopicsController, type: :request do
|
|||
{:message => @message})
|
||||
|
||||
@user.reload
|
||||
expect(@user.submissions.size).to eq 1
|
||||
expect(@user.submissions.first.submission_type).to eq 'discussion_topic'
|
||||
expect(@user.submissions.not_placeholder.size).to eq 1
|
||||
expect(@user.submissions.not_placeholder.first.submission_type).to eq 'discussion_topic'
|
||||
end
|
||||
|
||||
it "should create a submission from a reply on a graded topic" do
|
||||
|
@ -1365,7 +1365,7 @@ describe DiscussionTopicsController, type: :request do
|
|||
@topic.save
|
||||
|
||||
student_in_course(:active_all => true)
|
||||
expect(@user.submissions).to be_empty
|
||||
expect(@user.submissions.not_placeholder).to be_empty
|
||||
|
||||
json = api_call(
|
||||
:post, "/api/v1/courses/#{@course.id}/discussion_topics/#{@topic.id}/entries/#{top_entry.id}/replies.json",
|
||||
|
@ -1374,8 +1374,8 @@ describe DiscussionTopicsController, type: :request do
|
|||
{:message => @message})
|
||||
|
||||
@user.reload
|
||||
expect(@user.submissions.size).to eq 1
|
||||
expect(@user.submissions.first.submission_type).to eq 'discussion_topic'
|
||||
expect(@user.submissions.not_placeholder.size).to eq 1
|
||||
expect(@user.submissions.not_placeholder.first.submission_type).to eq 'discussion_topic'
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
@ -55,8 +55,8 @@ describe 'Submissions API', type: :request do
|
|||
:format => 'json', :course_id => @course.id.to_s,
|
||||
:assignment_id => @assignment.id.to_s, :user_id => student.id.to_s },
|
||||
{ :include => %w(submission_history submission_comments rubric_assessment) })
|
||||
expect(json.delete('id')).to eq nil
|
||||
expect(json).to eq({
|
||||
"id" => @assignment.submissions.find_by!(user: student).id,
|
||||
"assignment_id" => @assignment.id,
|
||||
"preview_url" => "http://www.example.com/courses/#{@course.id}/assignments/#{@assignment.id}/submissions/#{student.id}?preview=1&version=0",
|
||||
"user_id"=>student.id,
|
||||
|
@ -72,7 +72,7 @@ describe 'Submissions API', type: :request do
|
|||
"submission_comments"=>[],
|
||||
"grade_matches_current_submission"=>nil,
|
||||
"score"=>nil,
|
||||
"workflow_state"=>nil,
|
||||
"workflow_state"=>"unsubmitted",
|
||||
"late"=>false,
|
||||
"graded_at"=>nil,
|
||||
})
|
||||
|
@ -698,7 +698,7 @@ describe 'Submissions API', type: :request do
|
|||
"body"=>"test!",
|
||||
"assignment_id" => a1.id,
|
||||
"submitted_at"=>"1970-01-01T01:00:00Z",
|
||||
"preview_url" => "http://www.example.com/courses/#{@course.id}/assignments/#{a1.id}/submissions/#{student1.id}?preview=1&version=2",
|
||||
"preview_url" => "http://www.example.com/courses/#{@course.id}/assignments/#{a1.id}/submissions/#{student1.id}?preview=1&version=1",
|
||||
"grade_matches_current_submission"=>true,
|
||||
"attempt"=>1,
|
||||
"url"=>nil,
|
||||
|
@ -799,7 +799,7 @@ describe 'Submissions API', type: :request do
|
|||
mock_kaltura.expects(:media_sources).returns([{:height => "240", :bitrate => "382", :isOriginal => "0", :width => "336", :content_type => "video/mp4",
|
||||
:containerFormat => "isom", :url => "https://kaltura.example.com/some/url", :size =>"204", :fileExt=>"mp4"}])
|
||||
|
||||
submit_homework(a1, student1, :media_comment_id => "54321", :media_comment_type => "video")
|
||||
submit_homework(a1, student1, submission_type: 'online_text_entry', media_comment_id: 54321, media_comment_type: "video")
|
||||
stub_kaltura
|
||||
json = api_call(:get,
|
||||
"/api/v1/courses/#{@course.id}/assignments/#{a1.id}/submissions.json",
|
||||
|
@ -866,7 +866,7 @@ describe 'Submissions API', type: :request do
|
|||
"body"=>"test!",
|
||||
"assignment_id" => a1.id,
|
||||
"submitted_at"=>"1970-01-01T03:00:00Z",
|
||||
"preview_url" => "http://www.example.com/courses/#{@course.id}/assignments/#{a1.id}/submissions/#{student1.id}?preview=1&version=4",
|
||||
"preview_url" => "http://www.example.com/courses/#{@course.id}/assignments/#{a1.id}/submissions/#{student1.id}?preview=1&version=3",
|
||||
"grade_matches_current_submission"=>true,
|
||||
"attachments" =>
|
||||
[
|
||||
|
@ -904,7 +904,7 @@ describe 'Submissions API', type: :request do
|
|||
"url"=>nil,
|
||||
"submission_type"=>"online_text_entry",
|
||||
"user_id"=>student1.id,
|
||||
"preview_url" => "http://www.example.com/courses/#{@course.id}/assignments/#{a1.id}/submissions/#{student1.id}?preview=1&version=2",
|
||||
"preview_url" => "http://www.example.com/courses/#{@course.id}/assignments/#{a1.id}/submissions/#{student1.id}?preview=1&version=1",
|
||||
"grade_matches_current_submission"=>nil,
|
||||
"score"=>nil,
|
||||
"workflow_state" => "submitted",
|
||||
|
@ -927,7 +927,7 @@ describe 'Submissions API', type: :request do
|
|||
"url"=>nil,
|
||||
"submission_type"=>"online_text_entry",
|
||||
"user_id"=>student1.id,
|
||||
"preview_url" => "http://www.example.com/courses/#{@course.id}/assignments/#{a1.id}/submissions/#{student1.id}?preview=1&version=3",
|
||||
"preview_url" => "http://www.example.com/courses/#{@course.id}/assignments/#{a1.id}/submissions/#{student1.id}?preview=1&version=2",
|
||||
"grade_matches_current_submission"=>nil,
|
||||
"score"=>nil,
|
||||
"workflow_state" => "submitted",
|
||||
|
@ -972,7 +972,7 @@ describe 'Submissions API', type: :request do
|
|||
"url"=>nil,
|
||||
"submission_type"=>"online_text_entry",
|
||||
"user_id"=>student1.id,
|
||||
"preview_url" => "http://www.example.com/courses/#{@course.id}/assignments/#{a1.id}/submissions/#{student1.id}?preview=1&version=4",
|
||||
"preview_url" => "http://www.example.com/courses/#{@course.id}/assignments/#{a1.id}/submissions/#{student1.id}?preview=1&version=3",
|
||||
"grade_matches_current_submission"=>true,
|
||||
"score"=>13.5,
|
||||
"workflow_state" => "graded",
|
||||
|
@ -1016,7 +1016,7 @@ describe 'Submissions API', type: :request do
|
|||
"graded_at"=>sub2.graded_at.as_json,
|
||||
"assignment_id" => a1.id,
|
||||
"body"=>nil,
|
||||
"preview_url" => "http://www.example.com/courses/#{@course.id}/assignments/#{a1.id}/submissions/#{student2.id}?preview=1&version=2",
|
||||
"preview_url" => "http://www.example.com/courses/#{@course.id}/assignments/#{a1.id}/submissions/#{student2.id}?preview=1&version=1",
|
||||
"grade_matches_current_submission"=>true,
|
||||
"submitted_at"=>"1970-01-01T04:00:00Z",
|
||||
"submission_history"=>
|
||||
|
@ -1032,7 +1032,7 @@ describe 'Submissions API', type: :request do
|
|||
"url"=>"http://www.instructure.com",
|
||||
"submission_type"=>"online_url",
|
||||
"user_id"=>student2.id,
|
||||
"preview_url" => "http://www.example.com/courses/#{@course.id}/assignments/#{a1.id}/submissions/#{student2.id}?preview=1&version=2",
|
||||
"preview_url" => "http://www.example.com/courses/#{@course.id}/assignments/#{a1.id}/submissions/#{student2.id}?preview=1&version=1",
|
||||
"grade_matches_current_submission"=>true,
|
||||
"attachments" =>
|
||||
[
|
||||
|
@ -2815,6 +2815,7 @@ describe 'Submissions API', type: :request do
|
|||
@enrollment.update_attribute(:limit_privileges_to_course_section, true)
|
||||
@teacher = @user
|
||||
s1 = submission_model(:course => @course)
|
||||
s1.update!(submission_type: 'online_text_entry')
|
||||
section2 = @course.course_sections.create(:name => "another section")
|
||||
s2 = submission_model(:course => @course, :username => 'otherstudent@example.com', :section => section2, :assignment => @assignment)
|
||||
@user = @teacher
|
||||
|
@ -3324,7 +3325,7 @@ describe 'Submissions API', type: :request do
|
|||
progress = Progress.find(json["id"])
|
||||
expect(progress.completed?).to be_truthy
|
||||
|
||||
expect(Submission.count).to eq 1
|
||||
expect(Submission.not_placeholder.count).to eq 1
|
||||
s1 = student3.submissions.first
|
||||
expect(s1.grade).to eq "75%"
|
||||
end
|
||||
|
@ -3395,7 +3396,7 @@ describe 'Submissions API', type: :request do
|
|||
progress = Progress.find(json["id"])
|
||||
expect(progress.completed?).to be_truthy
|
||||
|
||||
expect(Submission.count).to eq 1
|
||||
expect(Submission.not_placeholder.count).to eq 1
|
||||
s1 = @student1.submissions.first
|
||||
expect(s1.grade).to eq "75%"
|
||||
end
|
||||
|
@ -3709,7 +3710,7 @@ describe 'Submissions API', type: :request do
|
|||
group.add_user(student1)
|
||||
group.add_user(student2)
|
||||
end
|
||||
let!(:submit_homework) { assignment.submit_homework(student1) }
|
||||
let!(:submit_homework) { assignment.submit_homework(student1, submission_type: 'online_text_entry') }
|
||||
|
||||
let(:path) { "/api/v1/courses/#{test_course.id}/assignments/#{assignment.id}/submissions" }
|
||||
let(:params) do
|
||||
|
|
|
@ -99,14 +99,14 @@ describe DiscussionEntriesController do
|
|||
assignment_model(:course => @course)
|
||||
@topic.assignment = @assignment
|
||||
@topic.save
|
||||
expect(@student.submissions).to be_empty
|
||||
expect(@student.submissions.not_placeholder).to be_empty
|
||||
|
||||
post 'create', :course_id => @course.id, :discussion_entry => {:discussion_topic_id => @topic.id, :message => "yo"}
|
||||
expect(response).to be_redirect
|
||||
|
||||
@student.reload
|
||||
expect(@student.submissions.size).to eq 1
|
||||
expect(@student.submissions.first.submission_type).to eq 'discussion_topic'
|
||||
expect(@student.submissions.not_placeholder.size).to eq 1
|
||||
expect(@student.submissions.not_placeholder.first.submission_type).to eq 'discussion_topic'
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
@ -262,7 +262,7 @@ XML
|
|||
expect(response.content_type).to eq 'application/xml'
|
||||
xml = Nokogiri::XML.parse(response.body)
|
||||
expect(xml.at_css('imsx_POXEnvelopeResponse > imsx_POXHeader > imsx_POXResponseHeaderInfo > imsx_statusInfo > imsx_codeMajor').content).to eq failure_type
|
||||
expect(@assignment.submissions.where(user_id: @student)).not_to be_exists
|
||||
expect(@assignment.submissions.not_placeholder.where(user_id: @student)).not_to be_exists
|
||||
desc = xml.at_css('imsx_description').content.match(/(?<description>.+)\n\[EID_(?<error_report>[^\]]+)\]/)
|
||||
expect(desc[:description]).to eq error_message if error_message
|
||||
expect(desc[:error_report]).to_not be_empty
|
||||
|
@ -287,7 +287,7 @@ XML
|
|||
end
|
||||
|
||||
it "should allow updating the submission score" do
|
||||
expect(@assignment.submissions.where(user_id: @student)).not_to be_exists
|
||||
expect(@assignment.submissions.not_placeholder.where(user_id: @student)).not_to be_exists
|
||||
make_call('body' => replace_result(score: '0.6'))
|
||||
check_success
|
||||
|
||||
|
@ -350,7 +350,7 @@ XML
|
|||
expect(xml.at_css('imsx_codeMajor').content).to eq 'failure'
|
||||
expect(xml.at_css('imsx_description').content).to match /^No score given/
|
||||
|
||||
expect(@assignment.submissions.where(user_id: @student)).not_to be_exists
|
||||
expect(@assignment.submissions.not_placeholder.where(user_id: @student)).not_to be_exists
|
||||
end
|
||||
|
||||
it "should fail if bad score given" do
|
||||
|
@ -360,7 +360,7 @@ XML
|
|||
expect(xml.at_css('imsx_codeMajor').content).to eq 'failure'
|
||||
expect(xml.at_css('imsx_description').content).to match /^Score is not between 0 and 1/
|
||||
|
||||
expect(@assignment.submissions.where(user_id: @student)).not_to be_exists
|
||||
expect(@assignment.submissions.not_placeholder.where(user_id: @student)).not_to be_exists
|
||||
end
|
||||
|
||||
it "should fail if assignment has no points possible" do
|
||||
|
@ -401,7 +401,7 @@ to because the assignment has no points possible.
|
|||
end
|
||||
|
||||
it "should reject out of bound scores" do
|
||||
expect(@assignment.submissions.where(user_id: @student)).not_to be_exists
|
||||
expect(@assignment.submissions.not_placeholder.where(user_id: @student)).not_to be_exists
|
||||
make_call('body' => replace_result(score: '-1'))
|
||||
check_failure('failure')
|
||||
make_call('body' => replace_result(score: '1.1'))
|
||||
|
@ -421,7 +421,7 @@ to because the assignment has no points possible.
|
|||
end
|
||||
|
||||
it "should reject non-numeric scores" do
|
||||
expect(@assignment.submissions.where(user_id: @student)).not_to be_exists
|
||||
expect(@assignment.submissions.not_placeholder.where(user_id: @student)).not_to be_exists
|
||||
make_call('body' => replace_result(score: "OHAI SCORES"))
|
||||
check_failure('failure')
|
||||
end
|
||||
|
@ -494,7 +494,7 @@ to because the assignment has no points possible.
|
|||
end
|
||||
|
||||
it "should reject non-numeric scores" do
|
||||
expect(@assignment.submissions.where(user_id: @student)).not_to be_exists
|
||||
expect(@assignment.submissions.not_placeholder.where(user_id: @student)).not_to be_exists
|
||||
make_call('body' => replace_result(raw_score: "OHAI SCORES"))
|
||||
check_failure('failure')
|
||||
end
|
||||
|
@ -690,13 +690,13 @@ to because the assignment has no points possible.
|
|||
expect(response.content_type).to eq 'application/xml'
|
||||
xml = Nokogiri::XML.parse(response.body)
|
||||
expect(xml.at_css('message_response > statusinfo > codemajor').content).to eq failure_type
|
||||
expect(@assignment.submissions.where(user_id: @student)).not_to be_exists
|
||||
expect(@assignment.submissions.not_placeholder.where(user_id: @student)).not_to be_exists
|
||||
xml
|
||||
end
|
||||
|
||||
describe "basic-lis-updateresult" do
|
||||
it "should allow updating the submission score" do
|
||||
expect(@assignment.submissions.where(user_id: @student)).not_to be_exists
|
||||
expect(@assignment.submissions.not_placeholder.where(user_id: @student)).not_to be_exists
|
||||
make_call('body' => update_result('0.6'))
|
||||
xml = check_success
|
||||
|
||||
|
@ -710,7 +710,7 @@ to because the assignment has no points possible.
|
|||
end
|
||||
|
||||
it "should reject out of bound scores" do
|
||||
expect(@assignment.submissions.where(user_id: @student)).not_to be_exists
|
||||
expect(@assignment.submissions.not_placeholder.where(user_id: @student)).not_to be_exists
|
||||
make_call('body' => update_result('-1'))
|
||||
check_failure('Failure')
|
||||
make_call('body' => update_result('1.1'))
|
||||
|
@ -730,7 +730,7 @@ to because the assignment has no points possible.
|
|||
end
|
||||
|
||||
it "should reject non-numeric scores" do
|
||||
expect(@assignment.submissions.where(user_id: @student)).not_to be_exists
|
||||
expect(@assignment.submissions.not_placeholder.where(user_id: @student)).not_to be_exists
|
||||
make_call('body' => update_result("OHAI SCORES"))
|
||||
check_failure('Failure')
|
||||
end
|
||||
|
|
|
@ -43,6 +43,7 @@ describe Submissions::SubmissionForShow do
|
|||
|
||||
describe '#submission' do
|
||||
it 'instantiates a new submission when one is not present' do
|
||||
Submission.delete_all
|
||||
expect(subject.submission).to be_new_record
|
||||
end
|
||||
|
||||
|
|
|
@ -122,7 +122,7 @@ module Factories
|
|||
submission_count = opts[:submissions] || 1
|
||||
submission_count.times do |s|
|
||||
assignment = @course.assignments.create!(:title => "test #{s} assignment")
|
||||
submission = assignment.submissions.create!(:assignment_id => assignment.id, :user_id => @student.id)
|
||||
submission = assignment.submissions.find_by!(user: @student)
|
||||
submission.update_attributes!(score: '5') if opts[:submission_points]
|
||||
end
|
||||
end
|
||||
|
|
|
@ -30,9 +30,10 @@ module Factories
|
|||
|
||||
# just create the object, we don't care about callbacks or usual side effects
|
||||
def bare_submission_model(assignment, user, opts = {})
|
||||
opts = (opts.presence || {submission_type: "online_text_entry", body: "o hai"}).merge(user: user, workflow_state: "submitted")
|
||||
opts = (opts.presence || {submission_type: "online_text_entry", body: "o hai"}).merge(workflow_state: "submitted")
|
||||
submitted_at = opts.delete(:submitted_at)
|
||||
submission = assignment.submissions.build(opts)
|
||||
submission = assignment.submissions.find_by!(user: user)
|
||||
submission.attributes = opts
|
||||
submission.submitted_at = submitted_at if submitted_at
|
||||
submission.save_without_callbacks
|
||||
submission
|
||||
|
|
|
@ -34,7 +34,7 @@ describe AssignmentsHelper do
|
|||
end
|
||||
|
||||
it "is false if the assignment already has submissions" do
|
||||
@assignment.submissions.create!(user_id: @student, submission_type: 'online_url')
|
||||
@assignment.submissions.find_by!(user_id: @student).update!(submission_type: 'online_url')
|
||||
expect(assignment_publishing_enabled?(@assignment, @teacher)).to be_falsey
|
||||
end
|
||||
|
||||
|
|
|
@ -20,6 +20,7 @@ require_relative '../../config/initializers/consul'
|
|||
|
||||
describe ConsulInitializer do
|
||||
after(:each) do
|
||||
Canvas::DynamicSettings.config = nil
|
||||
Canvas::DynamicSettings.reset_cache!
|
||||
Canvas::DynamicSettings.fallback_data = nil
|
||||
end
|
||||
|
|
|
@ -139,7 +139,6 @@ describe "download submissions link" do
|
|||
end
|
||||
|
||||
it "should not show download submissions button with no submissions" do
|
||||
|
||||
get "/courses/#{@course.id}/assignments/#{@assignment.id}"
|
||||
expect(response).to be_success
|
||||
doc = Nokogiri::XML(response.body)
|
||||
|
@ -147,10 +146,10 @@ describe "download submissions link" do
|
|||
end
|
||||
|
||||
it "should show download submissions button with submission not graded" do
|
||||
|
||||
@submission = Submission.new(:assignment => @assignment, :user => @student, :submission_type => 'online_url')
|
||||
@submission = @assignment.submissions.find_by!(user: @student)
|
||||
@submission.update(submission_type: 'online_url')
|
||||
expect(@submission.state).to eql(:submitted)
|
||||
@submission.save!
|
||||
|
||||
get "/courses/#{@course.id}/assignments/#{@assignment.id}"
|
||||
expect(response).to be_success
|
||||
doc = Nokogiri::XML(response.body)
|
||||
|
@ -158,14 +157,15 @@ describe "download submissions link" do
|
|||
end
|
||||
|
||||
it "should show download submissions button with a submission graded" do
|
||||
|
||||
@submission = Submission.new(:assignment => @assignment, :user => @student, :submission_type => 'online_url')
|
||||
@submission = @assignment.submissions.find_by!(user: @student)
|
||||
@submission.update!(submission_type: 'online_url')
|
||||
@submission.grade_it
|
||||
@submission.score = 5
|
||||
@submission.save!
|
||||
expect(@submission.state).to eql(:graded)
|
||||
@submission2 = Submission.new(:assignment => @assignment, :user => @student2, :submission_type => 'online_url')
|
||||
@submission2.save!
|
||||
@submission2 = @assignment.submissions.find_by!(user: @student2)
|
||||
@submission2.update!(submission_type: 'online_url')
|
||||
|
||||
get "/courses/#{@course.id}/assignments/#{@assignment.id}"
|
||||
expect(response).to be_success
|
||||
doc = Nokogiri::XML(response.body)
|
||||
|
@ -173,17 +173,19 @@ describe "download submissions link" do
|
|||
end
|
||||
|
||||
it "should show download submissions button with all submissions graded" do
|
||||
|
||||
@submission = Submission.new(:assignment => @assignment, :user => @student, :submission_type => 'online_url')
|
||||
@submission = @assignment.submissions.find_by!(user: @student)
|
||||
@submission.update!(submission_type: 'online_url')
|
||||
@submission.grade_it
|
||||
@submission.score = 5
|
||||
@submission.save!
|
||||
expect(@submission.state).to eql(:graded)
|
||||
@submission2 = Submission.new(:assignment => @assignment, :user => @student2, :submission_type => 'online_url')
|
||||
@submission2 = @assignment.submissions.find_by!(user: @student2)
|
||||
@submission2.update!(submission_type: 'online_url')
|
||||
@submission2.grade_it
|
||||
@submission2.score = 5
|
||||
@submission2.save!
|
||||
expect(@submission2.state).to eql(:graded)
|
||||
|
||||
get "/courses/#{@course.id}/assignments/#{@assignment.id}"
|
||||
expect(response).to be_success
|
||||
doc = Nokogiri::XML(response.body)
|
||||
|
@ -191,10 +193,9 @@ describe "download submissions link" do
|
|||
end
|
||||
|
||||
it "should not show download submissions button to students" do
|
||||
|
||||
@submission = Submission.new(:assignment => @assignment, :user => @student, :submission_type => 'online_url')
|
||||
@submission = @assignment.submissions.find_by!(user: @student)
|
||||
@submission.update!(submission_type: 'online_url')
|
||||
expect(@submission.state).to eql(:submitted)
|
||||
@submission.save!
|
||||
user_session(@student)
|
||||
get "/courses/#{@course.id}/assignments/#{@assignment.id}"
|
||||
expect(response).to be_success
|
||||
|
@ -232,13 +233,13 @@ describe "ratio of submissions graded" do
|
|||
end
|
||||
|
||||
it "should show ratio of submissions graded with submission not graded" do
|
||||
|
||||
@submission = Submission.new(:assignment => @assignment, :user => @student, :submission_type => 'online_url')
|
||||
@submission.save!
|
||||
@submission = @assignment.submissions.find_by!(user: @student)
|
||||
@submission.update!(submission_type: 'online_url')
|
||||
expect(@submission.state).to eql(:submitted)
|
||||
@submission2 = Submission.new(:assignment => @assignment, :user => @student2, :submission_type => 'online_url')
|
||||
@submission2 = @assignment.submissions.find_by!(user: @student2)
|
||||
@submission2.update!(submission_type: 'online_url')
|
||||
expect(@submission2.state).to eql(:submitted)
|
||||
@submission2.save!
|
||||
|
||||
get "/courses/#{@course.id}/assignments/#{@assignment.id}"
|
||||
expect(response).to be_success
|
||||
doc = Nokogiri::XML(response.body)
|
||||
|
@ -246,15 +247,15 @@ describe "ratio of submissions graded" do
|
|||
end
|
||||
|
||||
it "should show ratio of submissions graded with a submission graded" do
|
||||
|
||||
@submission = Submission.new(:assignment => @assignment, :user => @student, :submission_type => 'online_url')
|
||||
@submission = @assignment.submissions.find_by!(user: @student)
|
||||
@submission.update!(submission_type: 'online_url')
|
||||
@submission.grade_it
|
||||
@submission.score = 5
|
||||
@submission.save!
|
||||
expect(@submission.state).to eql(:graded)
|
||||
@submission2 = Submission.new(:assignment => @assignment, :user => @student2, :submission_type => 'online_url')
|
||||
expect(@submission2.state).to eql(:submitted)
|
||||
@submission2.save!
|
||||
@submission2 = @assignment.submissions.find_by!(user: @student2)
|
||||
@submission2.update!(submission_type: 'online_url')
|
||||
|
||||
get "/courses/#{@course.id}/assignments/#{@assignment.id}"
|
||||
expect(response).to be_success
|
||||
doc = Nokogiri::XML(response.body)
|
||||
|
@ -262,18 +263,19 @@ describe "ratio of submissions graded" do
|
|||
end
|
||||
|
||||
it "should show ratio of submissions graded with all submissions graded" do
|
||||
|
||||
@submission = Submission.new(:assignment => @assignment, :user => @student, :submission_type => 'online_url')
|
||||
@submission.grade_it
|
||||
@submission = @assignment.submissions.find_by!(user: @student)
|
||||
@submission.update!(submission_type: 'online_url')
|
||||
@submission.grade_it
|
||||
@submission.score = 5
|
||||
@submission.save!
|
||||
expect(@submission.state).to eql(:graded)
|
||||
@submission2 = Submission.new(:assignment => @assignment, :user => @student2, :submission_type => 'online_url')
|
||||
@submission2 = @assignment.submissions.find_by!(user: @student2)
|
||||
@submission2.update!(submission_type: 'online_url')
|
||||
@submission2.grade_it
|
||||
@submission2.score = 5
|
||||
@submission2.save!
|
||||
expect(@submission2.state).to eql(:graded)
|
||||
|
||||
get "/courses/#{@course.id}/assignments/#{@assignment.id}"
|
||||
expect(response).to be_success
|
||||
doc = Nokogiri::XML(response.body)
|
||||
|
@ -281,10 +283,10 @@ describe "ratio of submissions graded" do
|
|||
end
|
||||
|
||||
it "should not show ratio of submissions graded to students" do
|
||||
|
||||
@submission = Submission.new(:assignment => @assignment, :user => @student, :submission_type => 'online_url')
|
||||
@submission = @assignment.submissions.find_by!(user: @student)
|
||||
@submission.update!(submission_type: 'online_url')
|
||||
expect(@submission.state).to eql(:submitted)
|
||||
@submission.save!
|
||||
|
||||
user_session(@student)
|
||||
get "/courses/#{@course.id}/assignments/#{@assignment.id}"
|
||||
expect(response).to be_success
|
||||
|
|
|
@ -276,7 +276,7 @@ describe BasicLTI::BasicOutcomes do
|
|||
it "creates a new submissions if there isn't one" do
|
||||
xml.css('resultData').remove
|
||||
expect{BasicLTI::BasicOutcomes.process_request(tool, xml)}.
|
||||
to change{assignment.submissions.where(user_id: @user.id).count}.from(0).to(1)
|
||||
to change{assignment.submissions.not_placeholder.where(user_id: @user.id).count}.from(0).to(1)
|
||||
end
|
||||
|
||||
it 'creates a new submission of type "external_tool" when a grade is passed back without a submission' do
|
||||
|
|
|
@ -215,7 +215,7 @@ describe Canvas::LiveEvents do
|
|||
submission.grader = @teacher
|
||||
submission.grade = '10'
|
||||
submission.score = 10
|
||||
Canvas::LiveEvents.grade_changed(submission, submission.versions.current.model)
|
||||
Canvas::LiveEvents.grade_changed(submission)
|
||||
end
|
||||
|
||||
it "should include the user_id and assignment_id" do
|
||||
|
|
|
@ -31,7 +31,7 @@ describe DueDateCacher do
|
|||
end
|
||||
|
||||
it "should wrap assignment in an array" do
|
||||
@new_expectation.with([@assignment])
|
||||
@new_expectation.with(@course, [@assignment.id])
|
||||
DueDateCacher.recompute(@assignment)
|
||||
end
|
||||
|
||||
|
@ -56,12 +56,12 @@ describe DueDateCacher do
|
|||
end
|
||||
|
||||
it "should pass along the whole array" do
|
||||
@new_expectation.with(@assignments)
|
||||
@new_expectation.with(@course, @assignments)
|
||||
DueDateCacher.recompute_course(@course, @assignments)
|
||||
end
|
||||
|
||||
it "should default to all assignments in the context" do
|
||||
@new_expectation.with { |assignment_ids| assignment_ids.sort == @assignments.map(&:id).sort }
|
||||
@new_expectation.with { |course, assignment_ids| course.id == @course.id && assignment_ids.sort == @assignments.map(&:id).sort }
|
||||
DueDateCacher.recompute_course(@course)
|
||||
end
|
||||
|
||||
|
@ -70,80 +70,75 @@ describe DueDateCacher do
|
|||
DueDateCacher.recompute_course(@course, @assignments)
|
||||
end
|
||||
|
||||
it "should queue a delayed job on a context-specific strand in production" do
|
||||
it "should queue a delayed job in a singleton in production if assignments.nil" do
|
||||
@instance.expects(:send_later_if_production_enqueue_args).
|
||||
with(:recompute, :strand => "cached_due_date:calculator:Course:#{@course.global_id}")
|
||||
with(:recompute, singleton: "cached_due_date:calculator:Course:#{@course.global_id}")
|
||||
DueDateCacher.recompute_course(@course)
|
||||
end
|
||||
|
||||
it "should queue a delayed job without a singleton if assignments is passed" do
|
||||
@instance.expects(:send_later_if_production_enqueue_args).with(:recompute, {})
|
||||
DueDateCacher.recompute_course(@course, @assignments)
|
||||
end
|
||||
|
||||
it "should operate on a course id" do
|
||||
@instance.expects(:send_later_if_production_enqueue_args).
|
||||
with(:recompute, :strand => "cached_due_date:calculator:Course:#{@course.global_id}")
|
||||
@new_expectation.with { |assignment_ids| assignment_ids.sort == @assignments.map(&:id).sort }
|
||||
with(:recompute, singleton: "cached_due_date:calculator:Course:#{@course.global_id}")
|
||||
@new_expectation.with { |course, assignment_ids| course.id == @course.id && assignment_ids.sort == @assignments.map(&:id).sort }
|
||||
DueDateCacher.recompute_course(@course.id)
|
||||
end
|
||||
end
|
||||
|
||||
describe ".recompute_batch" do
|
||||
before do
|
||||
@assignments = [@assignment]
|
||||
@assignments << assignment_model(:course => @course)
|
||||
@instance = stub('instance', :recompute => nil)
|
||||
@new_expectation = DueDateCacher.expects(:new).returns(@instance)
|
||||
end
|
||||
|
||||
it "should pass along the whole array" do
|
||||
@new_expectation.with(@assignments)
|
||||
DueDateCacher.recompute_batch(@assignments)
|
||||
end
|
||||
|
||||
it "should delegate to an instance" do
|
||||
@instance.expects(:recompute)
|
||||
DueDateCacher.recompute_batch(@assignments)
|
||||
end
|
||||
|
||||
it "should queue a delayed job on a batch-specific singleton strand in production" do
|
||||
@instance.expects(:send_later_if_production_enqueue_args).
|
||||
with(:recompute, :strand => "cached_due_date:calculator:batch:#{Shard.current.id}",
|
||||
:priority => Delayed::LOWER_PRIORITY)
|
||||
DueDateCacher.recompute_batch(@assignments)
|
||||
end
|
||||
end
|
||||
|
||||
describe "#submissions" do
|
||||
it "should not create submissions for enrollments that are not overridden" do
|
||||
cacher = DueDateCacher.new([@assignment])
|
||||
expect(cacher.submissions.size).to eql(0)
|
||||
end
|
||||
|
||||
it "should create submissions for enrollments that are overridden" do
|
||||
assignment_override_model(
|
||||
:assignment => @assignment,
|
||||
:set => @course.default_section)
|
||||
@override.override_due_at(@assignment.due_at + 1.day)
|
||||
@override.save!
|
||||
|
||||
cacher = DueDateCacher.new([@assignment])
|
||||
expect(cacher.submissions.size).to eql(1)
|
||||
expect(cacher.submissions.first.assignment).to eq @assignment
|
||||
expect(cacher.submissions.first.user).to eq @student
|
||||
end
|
||||
end
|
||||
|
||||
describe "#recompute" do
|
||||
before do
|
||||
@cacher = DueDateCacher.new([@assignment])
|
||||
@cacher = DueDateCacher.new(@course, [@assignment])
|
||||
submission_model(:assignment => @assignment, :user => @student)
|
||||
Submission.update_all(:cached_due_date => nil)
|
||||
end
|
||||
|
||||
context 'without existing submissions' do
|
||||
it "should create submissions for enrollments that are not overridden" do
|
||||
Submission.destroy_all
|
||||
expect { @cacher.recompute }.to change {
|
||||
Submission.where(assignment_id: @assignment.id).count
|
||||
}.from(0).to(1)
|
||||
end
|
||||
|
||||
it "should create submissions for enrollments that are overridden" do
|
||||
assignment_override_model(assignment: @assignment, set: @course.default_section)
|
||||
@override.override_due_at(@assignment.due_at + 1.day)
|
||||
@override.save!
|
||||
Submission.destroy_all
|
||||
|
||||
expect { @cacher.recompute }.to change {
|
||||
Submission.where(assignment_id: @assignment.id).count
|
||||
}.from(0).to(1)
|
||||
end
|
||||
end
|
||||
|
||||
it "should not create another submission for enrollments that have a submission" do
|
||||
expect { @cacher.recompute }.not_to change {
|
||||
Submission.where(assignment_id: @assignment.id).count
|
||||
}
|
||||
end
|
||||
|
||||
it "should not create another submission for enrollments that have a submission, even with an overridden" do
|
||||
assignment_override_model(assignment: @assignment, set: @course.default_section)
|
||||
@override.override_due_at(@assignment.due_at + 1.day)
|
||||
@override.save!
|
||||
|
||||
expect { @cacher.recompute }.not_to change {
|
||||
Submission.where(assignment_id: @assignment.id).count
|
||||
}
|
||||
end
|
||||
|
||||
context "no overrides" do
|
||||
it "should set the cached_due_date to the assignment due_at" do
|
||||
@assignment.due_at += 1.day
|
||||
@assignment.save!
|
||||
|
||||
@cacher.recompute
|
||||
expect(@submission.reload.cached_due_date).to eq @assignment.due_at
|
||||
expect(@submission.reload.cached_due_date).to eq @assignment.due_at.change(sec: 0)
|
||||
end
|
||||
|
||||
it "should set the cached_due_date to nil if the assignment has no due_at" do
|
||||
|
@ -167,7 +162,7 @@ describe DueDateCacher do
|
|||
@override.save!
|
||||
|
||||
@cacher.recompute
|
||||
expect(@submission.reload.cached_due_date).to eq @override.due_at
|
||||
expect(@submission.reload.cached_due_date).to eq @override.due_at.change(sec: 0)
|
||||
end
|
||||
|
||||
it "should prefer override's due_at over assignment's nil" do
|
||||
|
@ -178,7 +173,7 @@ describe DueDateCacher do
|
|||
@assignment.save!
|
||||
|
||||
@cacher.recompute
|
||||
expect(@submission.reload.cached_due_date).to eq @override.due_at
|
||||
expect(@submission.reload.cached_due_date).to eq @override.due_at.change(sec: 0)
|
||||
end
|
||||
|
||||
it "should prefer override's nil over assignment's due_at" do
|
||||
|
@ -194,7 +189,7 @@ describe DueDateCacher do
|
|||
@override.save!
|
||||
|
||||
@cacher.recompute
|
||||
expect(@submission.reload.cached_due_date).to eq @assignment.due_at
|
||||
expect(@submission.reload.cached_due_date).to eq @assignment.due_at.change(sec: 0)
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -217,11 +212,11 @@ describe DueDateCacher do
|
|||
end
|
||||
|
||||
it "should apply to students in the adhoc set" do
|
||||
expect(@submission2.reload.cached_due_date).to eq @override.due_at
|
||||
expect(@submission2.reload.cached_due_date).to eq @override.due_at.change(sec: 0)
|
||||
end
|
||||
|
||||
it "should not apply to students not in the adhoc set" do
|
||||
expect(@submission1.reload.cached_due_date).to eq @assignment.due_at
|
||||
expect(@submission1.reload.cached_due_date).to eq @assignment.due_at.change(sec: 0)
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -246,11 +241,11 @@ describe DueDateCacher do
|
|||
end
|
||||
|
||||
it "should apply to students in that section" do
|
||||
expect(@submission2.reload.cached_due_date).to eq @override.due_at
|
||||
expect(@submission2.reload.cached_due_date).to eq @override.due_at.change(sec: 0)
|
||||
end
|
||||
|
||||
it "should not apply to students in other sections" do
|
||||
expect(@submission1.reload.cached_due_date).to eq @assignment.due_at
|
||||
expect(@submission1.reload.cached_due_date).to eq @assignment.due_at.change(sec: 0)
|
||||
end
|
||||
|
||||
it "should not apply to non-active enrollments in that section" do
|
||||
|
@ -258,7 +253,7 @@ describe DueDateCacher do
|
|||
:enrollment_state => 'deleted',
|
||||
:section => @course_section,
|
||||
:allow_multiple_enrollments => true)
|
||||
expect(@submission1.reload.cached_due_date).to eq @assignment.due_at
|
||||
expect(@submission1.reload.cached_due_date).to eq @assignment.due_at.change(sec: 0)
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -290,23 +285,16 @@ describe DueDateCacher do
|
|||
end
|
||||
|
||||
it "should apply to students in that group" do
|
||||
expect(@submission2.reload.cached_due_date).to eq @override.due_at
|
||||
expect(@submission2.reload.cached_due_date).to eq @override.due_at.change(sec: 0)
|
||||
end
|
||||
|
||||
it "should not apply to students not in the group" do
|
||||
expect(@submission1.reload.cached_due_date).to eq @assignment.due_at
|
||||
expect(@submission1.reload.cached_due_date).to eq @assignment.due_at.change(sec: 0)
|
||||
end
|
||||
|
||||
it "should not apply to non-active memberships in that group" do
|
||||
@group.add_user(@student1, 'deleted')
|
||||
expect(@submission1.reload.cached_due_date).to eq @assignment.due_at
|
||||
end
|
||||
end
|
||||
|
||||
context "noop override" do
|
||||
it "should apply to absolutely no one" do
|
||||
assignment_override_model(assignment: assignment_model, set_type: 'Noop', set_id: 1, title: 'Tag 1')
|
||||
expect(@cacher.override_scope(Submission.all, @override)).to be_a ActiveRecord::NullRelation
|
||||
expect(@submission1.reload.cached_due_date).to eq @assignment.due_at.change(sec: 0)
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -331,7 +319,7 @@ describe DueDateCacher do
|
|||
@override1.save!
|
||||
|
||||
@cacher.recompute
|
||||
expect(@submission.reload.cached_due_date).to eq @override1.due_at
|
||||
expect(@submission.reload.cached_due_date).to eq @override1.due_at.change(sec: 0)
|
||||
end
|
||||
|
||||
it "should prefer second override's due_at if latest" do
|
||||
|
@ -339,7 +327,7 @@ describe DueDateCacher do
|
|||
@override2.save!
|
||||
|
||||
@cacher.recompute
|
||||
expect(@submission.reload.cached_due_date).to eq @override2.due_at
|
||||
expect(@submission.reload.cached_due_date).to eq @override2.due_at.change(sec: 0)
|
||||
end
|
||||
|
||||
it "should be nil if first override's nil" do
|
||||
|
@ -391,7 +379,7 @@ describe DueDateCacher do
|
|||
@override1.save!
|
||||
|
||||
@cacher.recompute
|
||||
expect(@submission1.reload.cached_due_date).to eq @override1.due_at
|
||||
expect(@submission1.reload.cached_due_date).to eq @override1.due_at.change(sec: 0)
|
||||
end
|
||||
|
||||
it "should use second override where the first doesn't apply" do
|
||||
|
@ -399,7 +387,7 @@ describe DueDateCacher do
|
|||
@override2.save!
|
||||
|
||||
@cacher.recompute
|
||||
expect(@submission2.reload.cached_due_date).to eq @override2.due_at
|
||||
expect(@submission2.reload.cached_due_date).to eq @override2.due_at.change(sec: 0)
|
||||
end
|
||||
|
||||
it "should use the best override where both apply" do
|
||||
|
@ -407,7 +395,7 @@ describe DueDateCacher do
|
|||
@override1.save!
|
||||
|
||||
@cacher.recompute
|
||||
expect(@submission2.reload.cached_due_date).to eq @override2.due_at
|
||||
expect(@submission2.reload.cached_due_date).to eq @override2.due_at.change(sec: 0)
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -425,15 +413,15 @@ describe DueDateCacher do
|
|||
@submission2 = submission_model(:assignment => @assignment2, :user => @student)
|
||||
Submission.update_all(:cached_due_date => nil)
|
||||
|
||||
DueDateCacher.new([@assignment1, @assignment2]).recompute
|
||||
DueDateCacher.new(@course, [@assignment1, @assignment2]).recompute
|
||||
end
|
||||
|
||||
it "should apply to submission on the overridden assignment" do
|
||||
expect(@submission1.reload.cached_due_date).to eq @override.due_at
|
||||
expect(@submission1.reload.cached_due_date).to eq @override.due_at.change(sec: 0)
|
||||
end
|
||||
|
||||
it "should not apply to apply to submission on the other assignment" do
|
||||
expect(@submission2.reload.cached_due_date).to eq @assignment.due_at
|
||||
expect(@submission2.reload.cached_due_date).to eq @assignment.due_at.change(sec: 0)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -54,6 +54,16 @@ describe Course do
|
|||
@assignment_in_other_course = @other_course.assignments.create!
|
||||
end
|
||||
|
||||
it 'properly converts timezones' do
|
||||
Time.zone = 'Alaska'
|
||||
default_due = DateTime.parse("01 Jan 2011 14:00 AKST")
|
||||
@assignment4 = @test_course.assignments.create!(title: "some assignment", due_at: default_due, submission_types: ['online_text_entry'])
|
||||
|
||||
edd = EffectiveDueDates.for_course(@test_course, @assignment4)
|
||||
result = edd.to_hash
|
||||
expect(result[@assignment4.id][@student1.id][:due_at]).to eq default_due
|
||||
end
|
||||
|
||||
it 'returns the effective due dates per assignment per student' do
|
||||
edd = EffectiveDueDates.for_course(@test_course)
|
||||
result = edd.to_hash
|
||||
|
@ -551,7 +561,10 @@ describe Course do
|
|||
end
|
||||
|
||||
it 'includes not-assigned students with existing graded submissions' do
|
||||
@assignment1.submissions.create!(user: @student1, submission_type: 'online_text_entry', workflow_state: 'graded')
|
||||
@assignment1.submissions.find_by!(user: @student1).update!(
|
||||
submission_type: 'online_text_entry',
|
||||
workflow_state: 'graded'
|
||||
)
|
||||
|
||||
edd = EffectiveDueDates.for_course(@test_course, @assignment1)
|
||||
result = edd.to_hash
|
||||
|
@ -572,7 +585,7 @@ describe Course do
|
|||
it 'uses assigned date instead of submission date even if submission was late' do
|
||||
override = @assignment1.assignment_overrides.create!(due_at: 3.days.from_now(@now), due_at_overridden: true)
|
||||
override.assignment_override_students.create!(user: @student1)
|
||||
@assignment1.submissions.find_by(user: @student1).update!(
|
||||
@assignment1.submissions.find_by!(user: @student1).update!(
|
||||
submitted_at: 1.week.from_now(@now),
|
||||
submission_type: 'online_text_entry',
|
||||
workflow_state: 'graded'
|
||||
|
@ -634,7 +647,7 @@ describe Course do
|
|||
it 'prioritizes the override due date even if it is earlier than the Everyone Else date and the student has a graded submission that does not qualify' do
|
||||
override = @assignment2.assignment_overrides.create!(due_at: 3.days.ago(@now), due_at_overridden: true)
|
||||
override.assignment_override_students.create!(user: @student1)
|
||||
@assignment2.submissions.find_by(user: @student1).update!(
|
||||
@assignment2.submissions.find_by!(user: @student1).update!(
|
||||
submitted_at: 1.week.from_now(@now),
|
||||
submission_type: 'online_text_entry',
|
||||
workflow_state: 'graded'
|
||||
|
@ -675,8 +688,7 @@ describe Course do
|
|||
it 'prioritizes the Everyone Else due date if it exists over the submission NULL date' do
|
||||
@assignment2.due_at = 4.days.from_now(@now)
|
||||
@assignment2.save!
|
||||
@assignment2.submissions.create!(
|
||||
user: @student1,
|
||||
@assignment2.submissions.find_by!(user: @student1).update!(
|
||||
submitted_at: 1.week.from_now(@now),
|
||||
submission_type: 'online_text_entry',
|
||||
workflow_state: 'graded'
|
||||
|
@ -713,7 +725,10 @@ describe Course do
|
|||
end
|
||||
|
||||
it 'ignores not-assigned students with ungraded submissions' do
|
||||
@assignment1.submissions.create!(user: @student1, submission_type: 'online_text_entry', workflow_state: 'submitted')
|
||||
@assignment1.submissions.find_by!(user: @student1).update!(
|
||||
submission_type: 'online_text_entry',
|
||||
workflow_state: 'submitted'
|
||||
)
|
||||
|
||||
edd = EffectiveDueDates.for_course(@test_course, @assignment1)
|
||||
expect(edd.to_hash).to eq({})
|
||||
|
@ -1344,8 +1359,7 @@ describe Course do
|
|||
end_date: 15.days.ago(@now),
|
||||
close_date: 10.days.ago(@now)
|
||||
})
|
||||
@assignment1.submissions.create!(
|
||||
user: @student1,
|
||||
@assignment1.submissions.find_by!(user: @student1).update!(
|
||||
submitted_at: 1.week.from_now(@now),
|
||||
submission_type: 'online_text_entry',
|
||||
workflow_state: 'graded'
|
||||
|
|
|
@ -108,7 +108,7 @@ describe GradeCalculator do
|
|||
@group = @course.assignment_groups.create!(name: "some group", group_weight: 100)
|
||||
@assignment = @course.assignments.create!(title: "Some Assignment", points_possible: 10, assignment_group: @group)
|
||||
@assignment2 = @course.assignments.create!(title: "Some Assignment2", points_possible: 10, assignment_group: @group)
|
||||
@submission = @assignment2.submissions.create!(user: @user)
|
||||
@submission = @assignment2.submissions.find_by!(user: @user)
|
||||
end
|
||||
|
||||
@submission.update_column(:score, 5)
|
||||
|
@ -137,8 +137,8 @@ describe GradeCalculator do
|
|||
@course.assignments.create!(title: "Some Assignment2", due_at: now, points_possible: 10, assignment_group: @group)
|
||||
@assignment_in_period = @course.assignments.create!(title: 'In a Grading Period', due_at: 2.months.from_now(now), points_possible: 10)
|
||||
@course.assignments.create!(title: 'In a Grading Period', due_at: 2.months.from_now(now), points_possible: 10)
|
||||
@submission = @assignment.submissions.create!(user: @user)
|
||||
@submission_in_period = @assignment_in_period.submissions.create!(user: @user)
|
||||
@submission = @assignment.submissions.find_by!(user: @user)
|
||||
@submission_in_period = @assignment_in_period.submissions.find_by!(user: @user)
|
||||
end
|
||||
|
||||
@submission.update_column(:score, 5)
|
||||
|
|
|
@ -23,7 +23,8 @@ describe 'rubric_assessment_submission_reminder' do
|
|||
before :once do
|
||||
user_model
|
||||
rubric_assessment_model(user: @user)
|
||||
@submission = @course.assignments.first.submissions.create!(user: @user)
|
||||
@course.enroll_student(@user)
|
||||
@submission = @course.assignments.first.submissions.find_by!(user: @user)
|
||||
@object = @rubric_association.assessment_requests.create!(user: @user,
|
||||
asset: @submission,
|
||||
assessor: @user,
|
||||
|
|
|
@ -1,61 +0,0 @@
|
|||
#
|
||||
# Copyright (C) 2013 - present 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/>.
|
||||
#
|
||||
|
||||
require File.expand_path(File.dirname(__FILE__) + '/../spec_helper.rb')
|
||||
require 'lib/data_fixup/populate_overridden_due_at_for_due_date_cacher.rb'
|
||||
|
||||
describe DataFixup::PopulateOverriddenDueAtForDueDateCacher do
|
||||
before do
|
||||
course_with_student(:active_all => true)
|
||||
@assignment1 = assignment_model(:course => @course)
|
||||
assignment_model(:course => @course)
|
||||
@section = @course.course_sections.create!
|
||||
student_in_section(@section, :course => @course)
|
||||
|
||||
# Create an override
|
||||
@due_at = @assignment.due_at - 1.day
|
||||
assignment_override_model(:assignment => @assignment, :set => @section)
|
||||
@override.override_due_at(@due_at)
|
||||
@override.save!
|
||||
|
||||
# Delete Submissions simulating current data state.
|
||||
@assignment.submissions.destroy_all
|
||||
@assignment1.submissions.destroy_all
|
||||
end
|
||||
|
||||
it "should recompute cached date dues for overridden assignments" do
|
||||
DueDateCacher.expects(:recompute_batch).once.with([@assignment.id])
|
||||
|
||||
DataFixup::PopulateOverriddenDueAtForDueDateCacher.run
|
||||
end
|
||||
|
||||
it "should create submission for overridden assignments" do
|
||||
DataFixup::PopulateOverriddenDueAtForDueDateCacher.run
|
||||
|
||||
@assignment1.reload
|
||||
expect(@assignment1.submissions.size).to eql(0)
|
||||
|
||||
@assignment.reload
|
||||
expect(@assignment.submissions.size).to eql(1)
|
||||
@submission = @assignment.submissions.first
|
||||
|
||||
expect(@submission.user).to eq @user
|
||||
expect(@submission.assignment).to eq @assignment
|
||||
expect(@submission.cached_due_date).to eq @due_at
|
||||
end
|
||||
end
|
|
@ -30,7 +30,7 @@ describe DataFixup::PopulateSubmissionVersions do
|
|||
|
||||
it "should not migrate a submission version already having a submission_version" do
|
||||
course_with_student
|
||||
submission = @user.submissions.create(:assignment => @course.assignments.create!)
|
||||
@course.assignments.create!
|
||||
expect{
|
||||
DataFixup::PopulateSubmissionVersions.run
|
||||
}.not_to change(SubmissionVersion, :count)
|
||||
|
@ -39,9 +39,7 @@ describe DataFixup::PopulateSubmissionVersions do
|
|||
it "should migrate all submission version rows without submission_versions" do
|
||||
n = 5
|
||||
course_with_student
|
||||
submission = @user.submissions.build(:assignment => @course.assignments.create!)
|
||||
submission.without_versioning{ submission.save! }
|
||||
expect(submission.versions.exists?).to be_falsey
|
||||
submission = @user.submissions.find_by(assignment: @course.assignments.create!)
|
||||
n.times { |x| Version.create(:versionable => submission, :yaml => submission.attributes.to_yaml) }
|
||||
expect{
|
||||
DataFixup::PopulateSubmissionVersions.run
|
||||
|
@ -50,12 +48,8 @@ describe DataFixup::PopulateSubmissionVersions do
|
|||
|
||||
it "should skip submission version rows without a corresponding submission object" do
|
||||
course_with_student
|
||||
submission = @user.submissions.build(:assignment => @course.assignments.create!)
|
||||
submission.without_versioning{ submission.save! }
|
||||
submission = @user.submissions.find_by(assignment: @course.assignments.create!)
|
||||
Version.create(:versionable => submission, :yaml => submission.attributes.to_yaml)
|
||||
|
||||
submission.reload
|
||||
expect(submission.versions.exists?).to be_truthy
|
||||
submission.delete
|
||||
|
||||
expect{
|
||||
|
|
|
@ -221,7 +221,9 @@ describe Assignment::SpeedGrader do
|
|||
json = Assignment::SpeedGrader.new(assignment, @teacher).json
|
||||
json[:submissions].each do |submission|
|
||||
user = [student_1, student_2].detect { |s| s.id.to_s == submission[:user_id] }
|
||||
expect(submission[:late]).to eq user.submissions.first.late?
|
||||
if(submission[:workflow_state] == "submitted")
|
||||
expect(submission[:late]).to eq user.submissions.first.late?
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
@ -2577,7 +2577,7 @@ describe Assignment do
|
|||
|
||||
it "should include re-submitted submissions in the list of submissions needing grading" do
|
||||
expect(@assignment).to be_published
|
||||
expect(@assignment.submissions.size).to eq 1
|
||||
expect(@assignment.submissions.not_placeholder.size).to eq 1
|
||||
expect(Assignment.need_grading_info.where(id: @assignment).first).to be_nil
|
||||
@assignment.submit_homework(@stu1, :body => "Changed my mind!")
|
||||
@sub1.reload
|
||||
|
@ -2822,7 +2822,7 @@ describe Assignment do
|
|||
sub = @a.submit_homework(@u1, :submission_type => "online_text_entry", :body => "Some text for you")
|
||||
expect(sub.user_id).to eql(@u1.id)
|
||||
@a.reload
|
||||
subs = @a.submissions
|
||||
subs = @a.submissions.not_placeholder
|
||||
expect(subs.length).to eql(2)
|
||||
expect(subs.map(&:group_id).uniq).to eql([@group.id])
|
||||
expect(subs.map(&:submission_type).uniq).to eql(['online_text_entry'])
|
||||
|
@ -2833,7 +2833,7 @@ describe Assignment do
|
|||
@a.update_attribute(:grade_group_students_individually, true)
|
||||
res = @a.submit_homework(@u1, :submission_type => "online_text_entry", :body => "Test submission")
|
||||
@a.reload
|
||||
submissions = @a.submissions
|
||||
submissions = @a.submissions.not_placeholder
|
||||
expect(submissions.length).to eql 2
|
||||
expect(submissions.map(&:group_id).uniq).to eql [@group.id]
|
||||
expect(submissions.map(&:submission_type).uniq).to eql ["online_text_entry"]
|
||||
|
@ -2882,7 +2882,7 @@ describe Assignment do
|
|||
expect(sub.user_id).to eql(@u1.id)
|
||||
expect(sub.submission_comments.size).to eql 1
|
||||
@a.reload
|
||||
other_sub = (@a.submissions - [sub])[0]
|
||||
other_sub = (@a.submissions.not_placeholder - [sub])[0]
|
||||
expect(other_sub.submission_comments.size).to eql 1
|
||||
end
|
||||
|
||||
|
@ -2919,7 +2919,7 @@ describe Assignment do
|
|||
context: @u1,
|
||||
filename: 'blah.txt'
|
||||
@a.submit_homework(@u1, attachments: [f])
|
||||
@a.submissions.reload.each { |s|
|
||||
@a.submissions.reload.not_placeholder.each { |s|
|
||||
expect(s.attachments).to eq [f]
|
||||
}
|
||||
end
|
||||
|
@ -4090,7 +4090,7 @@ describe Assignment do
|
|||
|
||||
context "when the student is not in a group" do
|
||||
let!(:associate_student_and_submission) {
|
||||
assignment.submissions.create user: @student
|
||||
assignment.submissions.find_by user: @student
|
||||
}
|
||||
let(:update_submission_response) { assignment.update_submission(@student) }
|
||||
|
||||
|
|
|
@ -362,7 +362,7 @@ describe Course do
|
|||
end
|
||||
|
||||
it 'should be able to i18n without keys' do
|
||||
Importers::CourseContentImporter.translate('stuff')
|
||||
expect { Importers::CourseContentImporter.translate('stuff') }.not_to raise_error
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
@ -23,7 +23,7 @@ describe ModeratedGrading::ProvisionalGrade do
|
|||
grade.scorer = scorer
|
||||
end
|
||||
end
|
||||
let(:submission) { assignment.submissions.create!(user: student) }
|
||||
let(:submission) { assignment.submissions.find_by!(user: student) }
|
||||
let(:assignment) { course.assignments.create! submission_types: 'online_text_entry' }
|
||||
let(:account) { a = account_model; a}
|
||||
let(:course) { c = account.courses.create!; c }
|
||||
|
|
|
@ -22,21 +22,21 @@ describe Pseudonym do
|
|||
|
||||
it "should create a new instance given valid attributes" do
|
||||
user_model
|
||||
factory_with_protected_attributes(Pseudonym, valid_pseudonym_attributes)
|
||||
expect{factory_with_protected_attributes(Pseudonym, valid_pseudonym_attributes)}.to change(Pseudonym, :count).by(1)
|
||||
end
|
||||
|
||||
it "should allow single character usernames" do
|
||||
user_model
|
||||
pseudonym_model
|
||||
@pseudonym.unique_id = 'c'
|
||||
@pseudonym.save!
|
||||
expect(@pseudonym.save).to be true
|
||||
end
|
||||
|
||||
it "should allow a username that starts with a special character" do
|
||||
user_model
|
||||
pseudonym_model
|
||||
@pseudonym.unique_id = '+c'
|
||||
@pseudonym.save!
|
||||
expect(@pseudonym.save).to be true
|
||||
end
|
||||
|
||||
it "should allow apostrophes in usernames" do
|
||||
|
|
|
@ -1554,7 +1554,8 @@ describe Quizzes::QuizSubmission do
|
|||
finished_at: Time.zone.now, user: @user, quiz: quiz, workflow_state: :complete
|
||||
)
|
||||
|
||||
expect(qs.submission.minutes_late).to eq(4)
|
||||
expected_minutes_late = (Time.zone.now - 60.seconds - 5.minutes.ago.change(sec: 0)) / 60
|
||||
expect(qs.submission.minutes_late).to eq(expected_minutes_late)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -265,13 +265,12 @@ describe SplitUsers do
|
|||
assignment.workflow_state = "published"
|
||||
assignment.save
|
||||
valid_attributes = {
|
||||
assignment_id: assignment.id,
|
||||
user_id: user1.id,
|
||||
grade: "1.5",
|
||||
grader: @teacher,
|
||||
url: "www.instructure.com"
|
||||
}
|
||||
submission = Submission.create!(valid_attributes)
|
||||
submission = assignment.submissions.find_by!(user: user1)
|
||||
submission.update!(valid_attributes)
|
||||
|
||||
UserMerge.from(user1).into(user2)
|
||||
expect(submission.reload.user).to eq user2
|
||||
|
@ -286,15 +285,14 @@ describe SplitUsers do
|
|||
assignment.workflow_state = "published"
|
||||
assignment.save
|
||||
valid_attributes = {
|
||||
assignment_id: assignment.id,
|
||||
user_id: user1.id,
|
||||
grade: "1.5",
|
||||
grader: @teacher,
|
||||
url: "www.instructure.com"
|
||||
}
|
||||
submission1 = Submission.create!(valid_attributes)
|
||||
valid_attributes[:user_id] = user2.id
|
||||
submission2 = Submission.create!(valid_attributes)
|
||||
submission1 = assignment.submissions.find_by!(user: user1)
|
||||
submission1.update!(valid_attributes)
|
||||
submission2 = assignment.submissions.find_by!(user: user2)
|
||||
submission2.update!(valid_attributes)
|
||||
|
||||
UserMerge.from(user1).into(user2)
|
||||
expect(submission1.reload.user).to eq user1
|
||||
|
|
|
@ -282,8 +282,8 @@ This text has a http://www.google.com link in it...
|
|||
context 'given a submission with several group comments' do
|
||||
let!(:assignment) { @course.assignments.create! }
|
||||
let!(:unrelated_assignment) { @course.assignments.create! }
|
||||
let!(:submission) { assignment.submissions.create!(user: @user) }
|
||||
let!(:unrelated_submission) { unrelated_assignment.submissions.create!(user: @user) }
|
||||
let!(:submission) { assignment.submissions.find_by!(user: @user) }
|
||||
let!(:unrelated_submission) { unrelated_assignment.submissions.find_by!(user: @user) }
|
||||
let!(:first_comment) do
|
||||
submission.submission_comments.create!(
|
||||
group_comment_id: 'uuid',
|
||||
|
@ -327,8 +327,8 @@ This text has a http://www.google.com link in it...
|
|||
context 'given a submission with several group comments' do
|
||||
let!(:assignment) { @course.assignments.create! }
|
||||
let!(:unrelated_assignment) { @course.assignments.create! }
|
||||
let!(:submission) { assignment.submissions.create!(user: @user) }
|
||||
let!(:unrelated_submission) { unrelated_assignment.submissions.create!(user: @user) }
|
||||
let!(:submission) { assignment.submissions.find_by!(user: @user) }
|
||||
let!(:unrelated_submission) { unrelated_assignment.submissions.find_by!(user: @user) }
|
||||
let!(:first_comment) do
|
||||
submission.submission_comments.create!(
|
||||
group_comment_id: 'uuid',
|
||||
|
|
|
@ -29,11 +29,12 @@ describe Submission do
|
|||
@assignment.workflow_state = "published"
|
||||
@assignment.save
|
||||
@valid_attributes = {
|
||||
assignment_id: @assignment.id,
|
||||
user_id: @user.id,
|
||||
assignment: @assignment,
|
||||
user: @user,
|
||||
grade: "1.5",
|
||||
grader: @teacher,
|
||||
url: "www.instructure.com"
|
||||
url: "www.instructure.com",
|
||||
workflow_state: "submitted"
|
||||
}
|
||||
end
|
||||
|
||||
|
@ -76,7 +77,7 @@ describe Submission do
|
|||
before(:once) do
|
||||
@assignment.due_at = in_open_grading_period
|
||||
@assignment.save!
|
||||
@submission = Submission.create!(@valid_attributes)
|
||||
submission_spec_model
|
||||
end
|
||||
|
||||
it "has grade permissions if the user is a root account admin" do
|
||||
|
@ -98,7 +99,7 @@ describe Submission do
|
|||
before(:once) do
|
||||
@assignment.due_at = outside_of_any_grading_period
|
||||
@assignment.save!
|
||||
@submission = Submission.create!(@valid_attributes)
|
||||
submission_spec_model
|
||||
end
|
||||
|
||||
it "has grade permissions if the user is a root account admin" do
|
||||
|
@ -124,7 +125,7 @@ describe Submission do
|
|||
@now = Time.zone.local(2013, 10, 18)
|
||||
end
|
||||
|
||||
let(:submission) { @assignment.submissions.find_by(user_id: @student) }
|
||||
let(:submission) { @assignment.submissions.find_by!(user_id: @student) }
|
||||
|
||||
it "gets initialized during submission creation" do
|
||||
# create an invited user, so that the submission is not automatically
|
||||
|
@ -138,8 +139,8 @@ describe Submission do
|
|||
override.override_due_at(Time.zone.now + 1.day)
|
||||
override.save!
|
||||
|
||||
submission = @assignment.submissions.create(:user => @user)
|
||||
expect(submission.cached_due_date).to eq override.reload.due_at
|
||||
submission = @assignment.submissions.find_by!(user: @user)
|
||||
expect(submission.cached_due_date).to eq override.reload.due_at.change(sec: 0)
|
||||
end
|
||||
|
||||
context 'due date changes after student submits' do
|
||||
|
@ -352,7 +353,7 @@ describe Submission do
|
|||
)
|
||||
override_student = student_override.assignment_override_students.create!(user: @student)
|
||||
|
||||
submission = assignment.submissions.find_by(user: @student)
|
||||
submission = assignment.submissions.find_by!(user: @student)
|
||||
expect { @student.enrollments.find_by(course_section: section).destroy }.to change {
|
||||
submission.reload.cached_due_date
|
||||
}.from(6.minutes.ago(@now)).to(14.minutes.ago(@now))
|
||||
|
@ -416,7 +417,7 @@ describe Submission do
|
|||
@assignment.update!(due_at: 1.hour.ago(@date), submission_types: "online_text_entry")
|
||||
end
|
||||
|
||||
let(:submission) { @assignment.submissions.find_by(user_id: @student) }
|
||||
let(:submission) { @assignment.submissions.find_by!(user_id: @student) }
|
||||
|
||||
it "returns time between submitted_at and cached_due_date" do
|
||||
Timecop.freeze(@date) do
|
||||
|
@ -526,11 +527,11 @@ describe Submission do
|
|||
|
||||
include_examples "url validation tests"
|
||||
it "should check url validity" do
|
||||
test_url_validation(Submission.create!(@valid_attributes))
|
||||
test_url_validation(submission_spec_model)
|
||||
end
|
||||
|
||||
it "should add http:// to the body for long urls, too" do
|
||||
s = Submission.create!(@valid_attributes)
|
||||
s = submission_spec_model
|
||||
expect(s.url).to eq 'http://www.instructure.com'
|
||||
|
||||
long_url = ("a"*300 + ".com")
|
||||
|
@ -1049,7 +1050,7 @@ describe Submission do
|
|||
describe 'computation of scores' do
|
||||
before(:once) do
|
||||
@assignment.update!(points_possible: 10)
|
||||
@submission = Submission.create!(@valid_attributes)
|
||||
submission_spec_model
|
||||
end
|
||||
|
||||
let(:scores) do
|
||||
|
@ -1720,19 +1721,13 @@ describe Submission do
|
|||
end
|
||||
|
||||
it "should return the correct quiz_submission_version" do
|
||||
# see redmine #6048
|
||||
|
||||
# set up the data to have a submission with a quiz submission with multiple versions
|
||||
course_factory
|
||||
quiz = @course.quizzes.create!
|
||||
quiz_submission = quiz.generate_submission @user, false
|
||||
quiz_submission.save
|
||||
|
||||
submission = Submission.create!({
|
||||
:assignment_id => @assignment.id,
|
||||
:user_id => @user.id,
|
||||
:quiz_submission_id => quiz_submission.id
|
||||
})
|
||||
@assignment.submissions.find_by!(user: @user).update!(quiz_submission_id: quiz_submission.id)
|
||||
|
||||
submission = @assignment.submit_homework @user, :submission_type => 'online_quiz'
|
||||
submission.quiz_submission_id = quiz_submission.id
|
||||
|
@ -2355,7 +2350,7 @@ describe Submission do
|
|||
|
||||
describe "#get_web_snapshot" do
|
||||
it "should not blow up if web snapshotting fails" do
|
||||
sub = Submission.new(@valid_attributes)
|
||||
sub = submission_spec_model
|
||||
CutyCapt.expects(:enabled?).returns(true)
|
||||
CutyCapt.expects(:snapshot_attachment_for_url).with(sub.url).returns(nil)
|
||||
sub.get_web_snapshot
|
||||
|
@ -2807,7 +2802,7 @@ describe Submission do
|
|||
|
||||
describe '#add_comment' do
|
||||
before(:once) do
|
||||
@submission = Submission.create!(@valid_attributes)
|
||||
submission_spec_model
|
||||
end
|
||||
|
||||
it 'creates a draft comment when passed true in the draft_comment option' do
|
||||
|
@ -3068,8 +3063,12 @@ describe Submission do
|
|||
|
||||
|
||||
def submission_spec_model(opts={})
|
||||
@submission = Submission.new(@valid_attributes.merge(opts))
|
||||
@submission.save!
|
||||
opts = @valid_attributes.merge(opts)
|
||||
assignment = opts.delete(:assignment) || Assignment.find(opts.delete(:assignment_id))
|
||||
user = opts.delete(:user) || User.find(opts.delete(:user_id))
|
||||
@submission = assignment.submissions.find_by!(user: user)
|
||||
@submission.update!(opts)
|
||||
@submission
|
||||
end
|
||||
|
||||
def setup_account_for_turnitin(account)
|
||||
|
|
|
@ -22,9 +22,7 @@ describe SubmissionVersion do
|
|||
def unversioned_submission
|
||||
# bypass the built-in submission versioning
|
||||
course_with_student
|
||||
submission = @user.submissions.build(:assignment => @course.assignments.create!)
|
||||
submission.without_versioning{ submission.save! }
|
||||
submission
|
||||
@user.submissions.find_by(assignment: @course.assignments.create!)
|
||||
end
|
||||
|
||||
before do
|
||||
|
|
|
@ -170,12 +170,15 @@ describe "assignments" do
|
|||
assignment_form = f('#submit_online_text_entry_form')
|
||||
wait_for_tiny(assignment_form)
|
||||
wait_for_ajaximations
|
||||
expect {
|
||||
type_in_tiny('#submission_body', 'something to submit')
|
||||
body_text = 'something to submit'
|
||||
expect do
|
||||
type_in_tiny('#submission_body', body_text)
|
||||
wait_for_ajaximations
|
||||
submit_form(assignment_form)
|
||||
wait_for_ajaximations
|
||||
}.to change(Submission, :count).by(1)
|
||||
end.to change {
|
||||
@assignment.submissions.find_by!(user: @student).body
|
||||
}.from(nil).to("<p>#{body_text}</p>")
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
@ -231,31 +231,32 @@ describe "submissions" do
|
|||
f('.submit_assignment_link').click
|
||||
assignment_form = f('#submit_online_text_entry_form')
|
||||
wait_for_tiny(assignment_form)
|
||||
|
||||
submit_form(assignment_form)
|
||||
submission = @assignment.submissions.find_by!(user_id: @student)
|
||||
|
||||
# it should not actually submit and pop up an error message
|
||||
expect { submit_form(assignment_form) }.not_to change { submission.reload.updated_at }
|
||||
expect(submission.reload.body).to be nil
|
||||
expect(ff('.error_box')[1]).to include_text('Required')
|
||||
|
||||
expect(Submission.count).to eq 0
|
||||
|
||||
# now make sure it works
|
||||
type_in_tiny('#submission_body', 'now it is not blank')
|
||||
submit_form(assignment_form)
|
||||
expect { Submission.count }.to become 1
|
||||
body_text = 'now it is not blank'
|
||||
type_in_tiny('#submission_body', body_text)
|
||||
expect { submit_form(assignment_form) }.to change { submission.reload.updated_at }
|
||||
expect(submission.reload.body).to eq "<p>#{body_text}</p>"
|
||||
end
|
||||
|
||||
it "should not allow a submission with only comments", priority: "1", test_id: 237027 do
|
||||
@assignment.update_attributes(:submission_types => "online_text_entry")
|
||||
get "/courses/#{@course.id}/assignments/#{@assignment.id}"
|
||||
f('.submit_assignment_link').click
|
||||
|
||||
expect(f('#submission_body_ifr')).to be_displayed
|
||||
replace_content(f('#submit_online_text_entry_form').find_element(:id, 'submission_comment'), 'this should not be able to be submitted for grading')
|
||||
submit_form("#submit_online_text_entry_form")
|
||||
submission = @assignment.submissions.find_by!(user_id: @student)
|
||||
|
||||
# it should not actually submit and pop up an error message
|
||||
expect { submit_form("#submit_online_text_entry_form") }.not_to change { submission.reload.updated_at }
|
||||
expect(ff('.error_box')[1]).to include_text('Required')
|
||||
expect(Submission.count).to eq 0
|
||||
|
||||
# navigate off the page and dismiss the alert box to avoid problems
|
||||
# with other selenium tests
|
||||
|
|
|
@ -36,7 +36,6 @@ describe "submissions" do
|
|||
|
||||
student_in_course
|
||||
assignment = create_assignment
|
||||
assignment.submissions.create(:user => @student)
|
||||
get "/courses/#{@course.id}/assignments/#{assignment.id}/submissions/#{@student.id}"
|
||||
|
||||
# make sure the JS didn't burn any bridges, and submit two
|
||||
|
@ -51,7 +50,6 @@ describe "submissions" do
|
|||
it "should display the grade in grade field", priority: "1", test_id: 237033 do
|
||||
student_in_course
|
||||
assignment = create_assignment
|
||||
assignment.submissions.create(:user => @student)
|
||||
assignment.grade_student @student, grade: 2, grader: @teacher
|
||||
get "/courses/#{@course.id}/assignments/#{assignment.id}/submissions/#{@student.id}"
|
||||
expect(f('.grading_value')[:value]).to eq '2'
|
||||
|
|
|
@ -131,8 +131,9 @@ describe "editing grades" do
|
|||
|
||||
edit_grade('#gradebook_grid .container_1 .slick-row:nth-child(1) .l5', 'A-')
|
||||
expect(f('#gradebook_grid .container_1 .slick-row:nth-child(1) .l5')).to include_text('A-')
|
||||
expect(@assignment.reload.submissions.size).to eq 1
|
||||
sub = @assignment.submissions.first
|
||||
submissions = @assignment.submissions.where('grade is not null')
|
||||
expect(submissions.count).to eq 1
|
||||
sub = submissions.first
|
||||
expect(sub.grade).to eq 'A-'
|
||||
expect(sub.score).to eq 0.0
|
||||
end
|
||||
|
|
|
@ -192,9 +192,7 @@ describe "gradebook" do
|
|||
})
|
||||
project_group = group_assignment.group_category.groups.create!(:name => 'g1', :context => @course)
|
||||
project_group.users << @student_1
|
||||
graded_assignment.submissions.create(:user => @student)
|
||||
graded_assignment.grade_student @student_1, grade: 10, grader: @teacher # 10 points possible
|
||||
group_assignment.submissions.create(:user => @student)
|
||||
group_assignment.grade_student @student_1, grade: 2, grader: @teacher # 0 points possible
|
||||
|
||||
@gradebook_page.visit_gradebook(@course)
|
||||
|
|
|
@ -167,7 +167,7 @@ describe "gradebook uploads" do
|
|||
expect(@course.assignments.count).to eql (assignment_count + 1)
|
||||
assignment = @course.assignments.order(:created_at).last
|
||||
expect(assignment.name).to eq "Assignment 2"
|
||||
expect(assignment.submissions.count).to eql 0
|
||||
expect(assignment.submissions.having_submission.count).to eql 0
|
||||
expect(f('#gradebook_wrapper')).to be_displayed
|
||||
end
|
||||
|
||||
|
|
|
@ -136,8 +136,8 @@ describe "Gradezilla editing grades" do
|
|||
|
||||
edit_grade('#gradebook_grid .container_1 .slick-row:nth-child(1) .l4', 'A-')
|
||||
expect(f('#gradebook_grid .container_1 .slick-row:nth-child(1) .l4')).to include_text('A-')
|
||||
expect(@assignment.reload.submissions.size).to eq 1
|
||||
sub = @assignment.submissions.first
|
||||
expect(@assignment.submissions.where('grade is not null').count).to eq 1
|
||||
sub = @assignment.submissions.where('grade is not null').first
|
||||
expect(sub.grade).to eq 'A-'
|
||||
expect(sub.score).to eq 0.0
|
||||
end
|
||||
|
|
|
@ -210,9 +210,7 @@ describe "Gradezilla" do
|
|||
})
|
||||
project_group = group_assignment.group_category.groups.create!(:name => 'g1', :context => @course)
|
||||
project_group.users << @student_1
|
||||
graded_assignment.submissions.create(:user => @student)
|
||||
graded_assignment.grade_student @student_1, grade: 10, grader: @teacher # 10 points possible
|
||||
group_assignment.submissions.create(:user => @student)
|
||||
group_assignment.grade_student @student_1, grade: 2, grader: @teacher # 0 points possible
|
||||
|
||||
gradezilla_page.visit(@course)
|
||||
|
|
|
@ -167,7 +167,7 @@ describe "Gradezilla - uploads" do
|
|||
expect(@course.assignments.count).to eql (assignment_count + 1)
|
||||
assignment = @course.assignments.order(:created_at).last
|
||||
expect(assignment.name).to eq "Assignment 2"
|
||||
expect(assignment.submissions.count).to eql 0
|
||||
expect(assignment.submissions.having_submission.count).to eql 0
|
||||
expect(f('#gradebook_wrapper')).to be_displayed
|
||||
end
|
||||
|
||||
|
|
|
@ -51,7 +51,7 @@ describe "speedgrader with grading periods" do
|
|||
Speedgrader.enter_grade(8)
|
||||
|
||||
expect(Speedgrader.current_grade).to eq ""
|
||||
expect(Submission.where(assignment_id: assignment.id, user_id: @student.id).first).to eq nil
|
||||
expect(Submission.where(assignment_id: assignment.id, user_id: @student.id).first).not_to be_graded
|
||||
expect(Speedgrader.top_bar).to contain_css(Speedgrader.closed_gp_notice_selector)
|
||||
end
|
||||
end
|
||||
|
|
|
@ -231,9 +231,8 @@ describe 'Speedgrader' do
|
|||
purpose: 'grading',
|
||||
use_for_grading: true
|
||||
)
|
||||
@submission = Submission.create!(
|
||||
user: @student,
|
||||
assignment: @assignment,
|
||||
@submission = @assignment.submissions.find_by!(user: @student)
|
||||
@submission.update!(
|
||||
submission_type: "online_text_entry",
|
||||
has_rubric_assessment: true
|
||||
)
|
||||
|
|
|
@ -202,7 +202,7 @@ describe 'Screenreader Gradebook grading' do
|
|||
SRGB.select_assignment(assignment)
|
||||
|
||||
expect(SRGB.grading_enabled?).to be false
|
||||
expect(Submission.where(assignment_id: assignment.id, user_id: @student.id).first).to eq nil
|
||||
expect(Submission.not_placeholder.where(assignment_id: assignment.id, user_id: @student.id).first).to eq nil
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -305,7 +305,7 @@ describe "grades" do
|
|||
|
||||
it "should show rubric even if there are no comments", priority: "1", test_id: 229669 do
|
||||
@third_association = @rubric.associate_with(@third_assignment, @course, :purpose => 'grading')
|
||||
@third_submission = @third_assignment.submissions.create!(:user => @student_1) # unsubmitted submission :/
|
||||
@third_submission = @third_assignment.submissions.find_by!(user: @student_1) # unsubmitted submission :/
|
||||
|
||||
@third_association.assess({
|
||||
:user => @student_1,
|
||||
|
|
|
@ -28,8 +28,8 @@ describe "student interactions report" do
|
|||
@student2 = student_in_course(:active_all => true, :name => "zzz student").user
|
||||
|
||||
@assignment = @course.assignments.create(:name => "first assignment", :points_possible => 10)
|
||||
@sub1 = @assignment.submissions.create(:user => @student1)
|
||||
@sub2 = @assignment.submissions.create(:user => @student2)
|
||||
@sub1 = @assignment.submissions.find_by!(user: @student1)
|
||||
@sub2 = @assignment.submissions.find_by!(user: @student2)
|
||||
|
||||
@sub1.update_attribute(:score, 10)
|
||||
@sub2.update_attribute(:score, 5)
|
||||
|
|
Loading…
Reference in New Issue