diff --git a/common/lib/xmodule/xmodule/js/spec/video/completion_spec.js b/common/lib/xmodule/xmodule/js/spec/video/completion_spec.js index c4994caae4..94f45eb800 100644 --- a/common/lib/xmodule/xmodule/js/spec/video/completion_spec.js +++ b/common/lib/xmodule/xmodule/js/spec/video/completion_spec.js @@ -67,5 +67,20 @@ state.el.trigger('ended'); expect(state.completionHandler.markCompletion).toHaveBeenCalled(); }); + + it('calls the completion api if the video is age restricted', function() { + spyOn(state, 'youtubeId').and.returnValue('fakeYouTubeID'); + spyOn(state.completionHandler, 'markCompletion').and.callThrough(); + state.metadata = {fakeYouTubeID: {contentRating: {}}}; + + // Check metadata once with no content rating and it should not be marked complete + state.el.trigger('metadata_received'); + expect(state.completionHandler.markCompletion).not.toHaveBeenCalled(); + + // But with age restricted rating, it will be completed immediately + state.metadata.fakeYouTubeID.contentRating.ytRating = 'ytAgeRestricted'; + state.el.trigger('metadata_received'); + expect(state.completionHandler.markCompletion).toHaveBeenCalled(); + }); }); }).call(this); diff --git a/common/lib/xmodule/xmodule/js/src/video/09_completion.js b/common/lib/xmodule/xmodule/js/src/video/09_completion.js index 97378e92ef..aa53a97b80 100644 --- a/common/lib/xmodule/xmodule/js/src/video/09_completion.js +++ b/common/lib/xmodule/xmodule/js/src/video/09_completion.js @@ -86,6 +86,13 @@ self.handleTimeUpdate(currentTime); }); + /** Event handler to receive youtube metadata (if we even are a youtube link), + * and mark complete, if youtube will insist on hosting the video itself. + */ + this.state.el.on('metadata_received', function() { + self.checkMetadata(); + }); + /** Event handler to clean up resources when the video player * is destroyed. */ @@ -126,6 +133,21 @@ } }, + /** Handler to call when youtube metadata is received */ + checkMetadata: function() { + var metadata = this.state.metadata[this.state.youtubeId()]; + + // https://developers.google.com/youtube/v3/docs/videos#contentDetails.contentRating.ytRating + if (metadata && metadata.contentRating && metadata.contentRating.ytRating === 'ytAgeRestricted') { + // Age-restricted videos won't play in embedded players. Instead, they ask you to watch it on + // youtube itself. Which means we can't notice if they complete it. Rather than leaving an + // incompletable video in the course, let's just mark it complete right now. + if (!this.isComplete) { + this.markCompletion(); + } + } + }, + /** Submit completion to the LMS */ markCompletion: function(currentTime) { var self = this;