diff --git a/app/controllers/lti_api_controller.rb b/app/controllers/lti_api_controller.rb index 88b0d4ed7aa..9262e80eaf0 100644 --- a/app/controllers/lti_api_controller.rb +++ b/app/controllers/lti_api_controller.rb @@ -77,8 +77,8 @@ class LtiApiController < ApplicationController # } # } # - # * result.duration must be an ISO 8601 duration # * object.id will be logged as url + # * result.duration must be an ISO 8601 duration if supplied def xapi_service token = Lti::XapiService::Token.parse_and_validate(params[:token]) verify_oauth(token.tool) diff --git a/app/models/lti/xapi_service.rb b/app/models/lti/xapi_service.rb index 8cd15247055..907954abeab 100644 --- a/app/models/lti/xapi_service.rb +++ b/app/models/lti/xapi_service.rb @@ -36,10 +36,13 @@ module Lti course = token.course user = token.user tool = token.tool - duration = params[:result]['duration'] - seconds = Duration.new(duration).to_i + duration = params[:result] ? params[:result]['duration'] : nil + seconds = duration ? Duration.new(duration).to_i : nil - course.enrollments.where(:user_id => user).update_all(['total_activity_time = COALESCE(total_activity_time, 0) + ?', seconds]) + if duration + course.enrollments.where(:user_id => user). + update_all(['total_activity_time = COALESCE(total_activity_time, 0) + ?', seconds]) + end access = AssetUserAccess.where(user_id: user, asset_code: tool.asset_string).first_or_initialize access.log(course, group_code: "external_tools", category: "external_tools") diff --git a/spec/apis/lti/xapi_service_spec.rb b/spec/apis/lti/xapi_service_spec.rb index 0d0a233b698..8349f483e04 100644 --- a/spec/apis/lti/xapi_service_spec.rb +++ b/spec/apis/lti/xapi_service_spec.rb @@ -101,4 +101,11 @@ describe LtiApiController, type: :request do after { Setting.set 'enable_page_views', 'false' } end + + it "should handle requests without durations" do + body = xapi_body + body.delete(:result) + make_call('body' => body) + expect(response).to be_success + end end