ensure calendar events API uses correct date times part 2

fixes CNVS-9618

test plan
 - passing an invalid date or invalid
   date time to the calendar events index
 - it should return a 400 bad_request

Change-Id: Ie559a2902f07c1e13d76bb0d087372c7dfe09cf5
Reviewed-on: https://gerrit.instructure.com/33175
Tested-by: Jenkins <jenkins@instructure.com>
Reviewed-by: Cody Cutrer <cody@instructure.com>
QA-Review: August Thornton <august@instructure.com>
Product-Review: Rob Orton <rob@instructure.com>
This commit is contained in:
Rob Orton 2014-04-17 10:53:41 -06:00
parent df0f72b723
commit f9fcd1d900
2 changed files with 56 additions and 32 deletions

View File

@ -260,10 +260,10 @@ class CalendarEventsApiController < ApplicationController
# @argument type [Optional, String, "event"|"assignment"] Defaults to "event" # @argument type [Optional, String, "event"|"assignment"] Defaults to "event"
# @argument start_date [Optional, Date] # @argument start_date [Optional, Date]
# Only return events since the start_date (inclusive). # Only return events since the start_date (inclusive).
# Defaults to today. The value should be formatted as: yyyy-mm-dd. # Defaults to today. The value should be formatted as: yyyy-mm-dd or ISO 8601 YYYY-MM-DDTHH:MM:SSZ.
# @argument end_date [Optional, Date] # @argument end_date [Optional, Date]
# Only return events before the end_date (inclusive). # Only return events before the end_date (inclusive).
# Defaults to start_date. The value should be formatted as: yyyy-mm-dd. # Defaults to start_date. The value should be formatted as: yyyy-mm-dd or ISO 8601 YYYY-MM-DDTHH:MM:SSZ.
# If end_date is the same as start_date, then only events on that day are # If end_date is the same as start_date, then only events on that day are
# returned. # returned.
# @argument undated [Optional, Boolean] # @argument undated [Optional, Boolean]
@ -281,6 +281,7 @@ class CalendarEventsApiController < ApplicationController
# #
# @returns [CalendarEvent] # @returns [CalendarEvent]
def index def index
@errors = {}
codes = (params[:context_codes] || [@current_user.asset_string])[0, 10] codes = (params[:context_codes] || [@current_user.asset_string])[0, 10]
get_options(codes) get_options(codes)
@ -306,7 +307,11 @@ class CalendarEventsApiController < ApplicationController
CalendarEvent.send(:preload_associations, events, :child_events) if @type == :event CalendarEvent.send(:preload_associations, events, :child_events) if @type == :event
events = apply_assignment_overrides(events) if @type == :assignment events = apply_assignment_overrides(events) if @type == :assignment
render :json => events.map { |event| event_json(event, @current_user, session) } if @errors.empty?
render :json => events.map { |event| event_json(event, @current_user, session) }
else
render json: {errors: @errors.as_json}, status: :bad_request
end
end end
# @API Create a calendar event # @API Create a calendar event
@ -616,27 +621,36 @@ class CalendarEventsApiController < ApplicationController
end end
end end
def validate_dates
@errors ||= {}
if params[:start_date].present?
if params[:start_date] =~ Api::DATE_REGEX
@start_date ||= Time.zone.parse(params[:start_date]).beginning_of_day
elsif params[:start_date] =~ Api::ISO8601_REGEX
@start_date ||= Time.zone.parse(params[:start_date])
else # params[:start_date] is not valid
@errors[:start_date] = t(:invalid_date_or_time, 'Invalid date or invalid datetime for %{attr}', attr: 'start_date')
end
end
if params[:end_date].present?
if params[:end_date] =~ Api::DATE_REGEX
@end_date ||= Time.zone.parse(params[:end_date]).end_of_day
elsif params[:end_date] =~ Api::ISO8601_REGEX
@end_date ||= Time.zone.parse(params[:end_date])
else # params[:end_date] is not valid
@errors[:end_date] = t(:invalid_date_or_time, 'Invalid date or invalid datetime for %{attr}', attr: 'end_date')
end
end
end
def get_options(codes) def get_options(codes)
@all_events = value_to_boolean(params[:all_events]) @all_events = value_to_boolean(params[:all_events])
@undated = value_to_boolean(params[:undated]) @undated = value_to_boolean(params[:undated])
if !@all_events && !@undated if !@all_events && !@undated
if params[:start_date].present? && params[:start_date] !~ Api::DATE_REGEX validate_dates
Api.invalid_time_stamp_error('start_date', @current_user.attributes.to_s + @start_date ||= Time.zone.now.beginning_of_day
ErrorReport.useful_http_env_stuff_from_request(request).to_s) @end_date ||= Time.zone.now.end_of_day
# todo stop logging and delete invalid dates
# params.delete(:start_date)
end
if params[:end_date].present? && params[:end_date] !~ Api::DATE_REGEX
Api.invalid_time_stamp_error('end_date', @current_user.attributes.to_s +
ErrorReport.useful_http_env_stuff_from_request(request).to_s)
# todo stop logging and delete invalid dates
# params.delete(:end_date)
end
today = Time.zone.now
@start_date ||= CanvasTime.try_parse(params[:start_date], today).beginning_of_day
@end_date ||= CanvasTime.try_parse(params[:end_date], today).end_of_day
@end_date = @start_date.end_of_day if @end_date < @start_date @end_date = @start_date.end_of_day if @end_date < @start_date
end end
@ -707,7 +721,7 @@ class CalendarEventsApiController < ApplicationController
def assignment_context_scope def assignment_context_scope
# contexts have to be partitioned into two groups so they can be queried effectively # contexts have to be partitioned into two groups so they can be queried effectively
contexts = @contexts.select{ |c| @context_codes.include?(c.asset_string) } contexts = @contexts.select { |c| @context_codes.include?(c.asset_string) }
view_unpublished, other = contexts.partition { |c| c.grants_right?(@current_user, session, :view_unpublished_items) } view_unpublished, other = contexts.partition { |c| c.grants_right?(@current_user, session, :view_unpublished_items) }
sql = [] sql = []

View File

@ -819,6 +819,16 @@ describe CalendarEventsApiController, type: :request do
json.size.should eql 1 json.size.should eql 1
end end
it 'should 400 for bad dates' do
raw_api_call(:get, "/api/v1/calendar_events?type=assignment&start_date=201-201-208&end_date=201-201-209&context_codes[]=course_#{@course.id}", {
controller: 'calendar_events_api', action: 'index', format: 'json', type: 'assignment',
context_codes: ["course_#{@course.id}"], start_date: '201-201-208', end_date: '201-201-209'})
response.code.should eql '400'
json = JSON.parse response.body
json['errors']['start_date'].should == 'Invalid date or invalid datetime for start_date'
json['errors']['end_date'].should == 'Invalid date or invalid datetime for end_date'
end
it 'should return assignments from up to 10 contexts' do it 'should return assignments from up to 10 contexts' do
contexts = [@course.asset_string] contexts = [@course.asset_string]
contexts.concat 15.times.map { |i| contexts.concat 15.times.map { |i|