ensure assignments API uses correct date time format part2
fixes CNVS-10087 test plan - assignments PUT and CREATE request will only accept is08601 formatted dates - will return 400 bad_request - still allow clearing the dates Change-Id: Ie5e25eb1a5e85e0aec0b934f7a256b7a8b0dc473 Reviewed-on: https://gerrit.instructure.com/32634 Reviewed-by: Cody Cutrer <cody@instructure.com> Tested-by: Jenkins <jenkins@instructure.com> QA-Review: August Thornton <august@instructure.com> Product-Review: Rob Orton <rob@instructure.com>
This commit is contained in:
parent
f9fcd1d900
commit
4e90438d25
|
@ -262,6 +262,7 @@ module Api::V1::Assignment
|
|||
return if overrides && !overrides.is_a?(Array)
|
||||
|
||||
return false unless valid_assignment_group_id?(assignment, assignment_params)
|
||||
return false unless valid_assignment_dates?(assignment, assignment_params)
|
||||
|
||||
assignment = update_from_params(assignment, assignment_params)
|
||||
|
||||
|
@ -280,6 +281,20 @@ module Api::V1::Assignment
|
|||
return false
|
||||
end
|
||||
|
||||
# validate that date and times are iso8601
|
||||
def valid_assignment_dates?(assignment, assignment_params)
|
||||
errors = ['due_at', 'lock_at', 'unlock_at', 'peer_reviews_assign_at'].map do |v|
|
||||
if assignment_params[v].present? && assignment_params[v] !~ Api::ISO8601_REGEX
|
||||
assignment.errors.add("assignment[#{v}]",
|
||||
I18n.t("assignments_api.invalid_date_time",
|
||||
'Invalid datetime for %{attribute}',
|
||||
attribute: v))
|
||||
end
|
||||
end
|
||||
|
||||
errors.compact.empty?
|
||||
end
|
||||
|
||||
def valid_assignment_group_id?(assignment, assignment_params)
|
||||
ag_id = assignment_params["assignment_group_id"].presence
|
||||
# if ag_id is a non-numeric string, ag_id.to_i will == 0
|
||||
|
@ -334,42 +349,11 @@ module Api::V1::Assignment
|
|||
assignment.muted = value_to_boolean(assignment_params.delete("muted"))
|
||||
end
|
||||
|
||||
exception_message = ["invalid due_at",
|
||||
"assignment_params: #{assignment_params}",
|
||||
"user: #{@current_user.attributes}",
|
||||
"account: #{assignment.context.root_account.attributes}",
|
||||
"course: #{assignment.context.attributes}",
|
||||
"assignment: #{assignment.attributes}"].join(",\n")
|
||||
|
||||
# do some fiddling with due_at for fancy midnight and add to update_params
|
||||
# validate that date and times are iso8601 otherwise ignore them, but still
|
||||
# allow clearing them when set to nil
|
||||
if update_params['due_at'].present? && update_params['due_at'] !~ Api::ISO8601_REGEX
|
||||
Api.invalid_time_stamp_error('due_at', exception_message)
|
||||
# todo stop logging and delete invalid dates
|
||||
# update_params.delete(:due_at)
|
||||
elsif update_params.has_key?('due_at')
|
||||
if update_params['due_at'].present? && update_params['due_at'] =~ Api::ISO8601_REGEX
|
||||
update_params['time_zone_edited'] = Time.zone.name
|
||||
end
|
||||
|
||||
if update_params['lock_at'].present? && update_params['lock_at'] !~ Api::ISO8601_REGEX
|
||||
Api.invalid_time_stamp_error('lock_at', exception_message)
|
||||
# todo stop logging and delete invalid dates
|
||||
# update_params.delete(:lock_at)
|
||||
end
|
||||
|
||||
if update_params['unlock_at'].present? && update_params['unlock_at'] !~ Api::ISO8601_REGEX
|
||||
Api.invalid_time_stamp_error('unlock_at', exception_message)
|
||||
# todo stop logging and delete invalid dates
|
||||
# update_params.delete(:unlock_at)
|
||||
end
|
||||
|
||||
if update_params['peer_reviews_due_at'].present? && update_params['peer_reviews_due_at'] !~ Api::ISO8601_REGEX
|
||||
Api.invalid_time_stamp_error('peer_reviews_due_at', exception_message)
|
||||
# todo stop logging and delete invalid dates
|
||||
# update_params.delete(:peer_reviews_due_at)
|
||||
end
|
||||
|
||||
if !assignment.context.try(:turnitin_enabled?)
|
||||
update_params.delete("turnitin_enabled")
|
||||
update_params.delete("turnitin_settings")
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
#
|
||||
# Copyright (C) 2011 Instructure, Inc.
|
||||
# Copyright (C) 2011 - 2014 Instructure, Inc.
|
||||
#
|
||||
# This file is part of Canvas.
|
||||
#
|
||||
|
@ -401,8 +401,12 @@ describe AssignmentsApiController, type: :request do
|
|||
|
||||
|
||||
describe "POST /courses/:course_id/assignments (#create)" do
|
||||
it "allows authenticated users to create assignments" do
|
||||
|
||||
before do
|
||||
course_with_teacher(:active_all => true)
|
||||
end
|
||||
|
||||
it "allows authenticated users to create assignments" do
|
||||
@course.assignment_groups.create!({:name => "first group"})
|
||||
@group = @course.assignment_groups.create!({:name => "some group"})
|
||||
@course.assignment_groups.create!({:name => "last group",
|
||||
|
@ -414,9 +418,9 @@ describe AssignmentsApiController, type: :request do
|
|||
{ 'name' => 'some assignment',
|
||||
'position' => '1',
|
||||
'points_possible' => '12',
|
||||
'due_at' => '2011-01-01',
|
||||
'lock_at' => '2011-01-03',
|
||||
'unlock_at' => '2011-12-31',
|
||||
'due_at' => '2011-01-01T00:00:00Z',
|
||||
'lock_at' => '2011-01-03T00:00:00Z',
|
||||
'unlock_at' => '2011-12-31T00:00:00Z',
|
||||
'description' => 'assignment description',
|
||||
'assignment_group_id' => @group.id,
|
||||
'submission_types' => [
|
||||
|
@ -429,7 +433,7 @@ describe AssignmentsApiController, type: :request do
|
|||
'grade_group_students_individually' => true,
|
||||
'automatic_peer_reviews' => true,
|
||||
'peer_reviews' => true,
|
||||
'peer_reviews_assign_at' => '2011-01-01',
|
||||
'peer_reviews_assign_at' => '2011-01-02T00:00:00Z',
|
||||
'peer_review_count' => 2,
|
||||
'group_category_id' => @group_category.id,
|
||||
'turnitin_enabled' => true,
|
||||
|
@ -489,7 +493,6 @@ describe AssignmentsApiController, type: :request do
|
|||
|
||||
it "should not allow assignment titles longer than 255 characters" do
|
||||
name_too_long = greater_than_255
|
||||
course_with_teacher(:active_all => true)
|
||||
#not create an assignment with a name too long
|
||||
lambda{
|
||||
raw_api_call(:post,
|
||||
|
@ -508,7 +511,6 @@ describe AssignmentsApiController, type: :request do
|
|||
|
||||
it "should not allow updating an assignment title to longer than 255 characters" do
|
||||
name_too_long = greater_than_255
|
||||
course_with_teacher(:active_all => true)
|
||||
#create an assignment
|
||||
@json = api_create_assignment_in_course(@course, {'name' => 'some name'})
|
||||
@assignment = Assignment.find @json['id']
|
||||
|
@ -533,7 +535,6 @@ describe AssignmentsApiController, type: :request do
|
|||
end
|
||||
|
||||
it "does not allow modifying turnitin_enabled when not enabled on the context" do
|
||||
course_with_teacher(:active_all => true)
|
||||
Course.any_instance.expects(:turnitin_enabled?).at_least_once.returns false
|
||||
response = api_create_assignment_in_course(@course,
|
||||
{ 'name' => 'some assignment',
|
||||
|
@ -546,8 +547,6 @@ describe AssignmentsApiController, type: :request do
|
|||
end
|
||||
|
||||
it "should process html content in description on create" do
|
||||
course_with_teacher(:active_all => true)
|
||||
|
||||
should_process_incoming_user_content(@course) do |content|
|
||||
api_create_assignment_in_course(@course, { 'description' => content })
|
||||
|
||||
|
@ -558,7 +557,6 @@ describe AssignmentsApiController, type: :request do
|
|||
end
|
||||
|
||||
it "allows creating an assignment with overrides via the API" do
|
||||
course_with_teacher(:active_all => true)
|
||||
student_in_course(:course => @course, :active_enrollment => true)
|
||||
|
||||
@adhoc_due_at = 5.days.from_now
|
||||
|
@ -602,7 +600,6 @@ describe AssignmentsApiController, type: :request do
|
|||
|
||||
it "takes overrides into account in the assignment-created notification " +
|
||||
"for assignments created with overrides" do
|
||||
course_with_teacher(:active_all => true)
|
||||
student_in_course(:course => @course, :active_enrollment => true)
|
||||
course_with_ta(:course => @course, :active_enrollment => true)
|
||||
@course.course_sections.create!
|
||||
|
@ -648,7 +645,6 @@ describe AssignmentsApiController, type: :request do
|
|||
end
|
||||
|
||||
it "should not allow an assignment_group_id that is not a number" do
|
||||
course_with_teacher(:active_all => true)
|
||||
student_in_course(:course => @course, :active_enrollment => true)
|
||||
@user = @teacher
|
||||
|
||||
|
@ -671,7 +667,6 @@ describe AssignmentsApiController, type: :request do
|
|||
|
||||
end
|
||||
|
||||
|
||||
describe "PUT /courses/:course_id/assignments/:id (#update)" do
|
||||
|
||||
it "should update published/unpublished" do
|
||||
|
@ -716,6 +711,55 @@ describe AssignmentsApiController, type: :request do
|
|||
should == "Can't unpublish if there are student submissions"
|
||||
end
|
||||
|
||||
it "should 400 with invalid date times" do
|
||||
course_with_teacher(:active_all => true)
|
||||
the_date = 1.day.ago
|
||||
@assignment = @course.assignments.create({
|
||||
:name => "some assignment",
|
||||
:points_possible => 15
|
||||
})
|
||||
@assignment.due_at = the_date
|
||||
@assignment.lock_at = the_date
|
||||
@assignment.unlock_at = the_date
|
||||
@assignment.peer_reviews_assign_at = the_date
|
||||
@assignment.save!
|
||||
|
||||
raw_api_update_assignment(@course, @assignment,
|
||||
{'peer_reviews_assign_at' => '1/1/2013' })
|
||||
response.should_not be_success
|
||||
response.code.should eql '400'
|
||||
json = JSON.parse response.body
|
||||
json['errors']['assignment[peer_reviews_assign_at]'].first['message'].
|
||||
should == 'Invalid datetime for peer_reviews_assign_at'
|
||||
end
|
||||
|
||||
it "should allow clearing dates" do
|
||||
course_with_teacher(:active_all => true)
|
||||
the_date = 1.day.ago
|
||||
@assignment = @course.assignments.create({
|
||||
:name => "some assignment",
|
||||
:points_possible => 15
|
||||
})
|
||||
@assignment.due_at = the_date
|
||||
@assignment.lock_at = the_date
|
||||
@assignment.unlock_at = the_date
|
||||
@assignment.peer_reviews_assign_at = the_date
|
||||
@assignment.save!
|
||||
|
||||
api_update_assignment_call(@course, @assignment,
|
||||
{'due_at' => nil,
|
||||
'lock_at' => '',
|
||||
'unlock_at' => nil,
|
||||
'peer_reviews_assign_at' => nil })
|
||||
response.should be_success
|
||||
@assignment.reload
|
||||
|
||||
@assignment.due_at.should be_nil
|
||||
@assignment.lock_at.should be_nil
|
||||
@assignment.unlock_at.should be_nil
|
||||
@assignment.peer_reviews_assign_at.should be_nil
|
||||
end
|
||||
|
||||
context "without overrides or frozen attributes" do
|
||||
before do
|
||||
course_with_teacher(:active_all => true)
|
||||
|
@ -746,7 +790,7 @@ describe AssignmentsApiController, type: :request do
|
|||
'group_category_id' => nil,
|
||||
'description' => 'assignment description',
|
||||
'grading_type' => 'letter_grade',
|
||||
'due_at' => '2011-01-01',
|
||||
'due_at' => '2011-01-01T00:00:00Z',
|
||||
'position' => 1,
|
||||
'muted' => true
|
||||
})
|
||||
|
|
Loading…
Reference in New Issue