-
Notifications
You must be signed in to change notification settings - Fork 2.5k
/
results_controller.rb
127 lines (114 loc) · 4.56 KB
/
results_controller.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
# frozen_string_literal: true
#
# Copyright (C) 2018 - 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 Lti::IMS
# @API Result
#
# Result API for IMS Assignment and Grade Services
#
# @model Result
# {
# "id": "Result",
# "description": "",
# "properties": {
# "id": {
# "description": "The fully qualified URL for showing the Result",
# "example": "http://institution.canvas.com/api/lti/courses/5/line_items/2/results/1",
# "type": "string"
# },
# "userId": {
# "description": "The lti_user_id or the Canvas user_id",
# "example": "50 | 'abcasdf'",
# "type": "string"
# },
# "resultScore": {
# "description": "The score of the result as defined by Canvas, scaled to the resultMaximum",
# "example": "50",
# "type": "number"
# },
# "resultMaximum": {
# "description": "Maximum possible score for this result; 1 is the default value and will be assumed if not specified otherwise. Minimum value of 0 required.",
# "example": "50",
# "type": "number"
# },
# "comment": {
# "description": "Comment visible to the student about the result.",
# "type": "string"
# },
# "scoreOf": {
# "description": "URL of the line item this belongs to",
# "example": "http://institution.canvas.com/api/lti/courses/5/line_items/2",
# "type": "string"
# }
# }
# }
class ResultsController < ApplicationController
include Concerns::GradebookServices
before_action :verify_line_item_in_context
before_action :verify_result_in_line_item, only: %i[show]
MIME_TYPE = "application/vnd.ims.lis.v2.resultcontainer+json"
# @API Show a collection of Results
#
# Show existing Results of a line item. Can be used to retrieve a specific student's
# result by adding the user_id (defined as the lti_user_id or the Canvas user_id) as
# a query parameter (i.e. user_id=1000). If user_id is included, it will return only
# one Result in the collection if the result exists, otherwise it will be empty. May
# also limit number of results by adding the limit query param (i.e. limit=100)
#
# @returns Result
def index
render(json: [], content_type: MIME_TYPE) and return if user.present? && !context.user_is_student?(user)
results = Lti::Result.active.where(line_item:).preload(:assignment, :submission)
results = results.where(user:).preload(:user) if params.key?(:user_id)
results = Api.paginate(results, self, "#{line_item_url}/results", pagination_args)
render json: results_collection(results), content_type: MIME_TYPE
end
# @API Show a Result
#
# Show existing Result of a line item.
#
# @returns Result
def show
render json: Lti::IMS::ResultsSerializer.new(result, line_item_url).as_json, content_type: MIME_TYPE
end
private
def scopes_matcher
# Spec seems to strongly imply this scope is sufficient. I.e. even tho a Result belongs to a LineItem,
# doesn't look like we're compelled to require at least one of LTI_AGS_LINE_ITEM_SCOPE and
# LTI_AGS_LINE_ITEM_READ_ONLY_SCOPE
self.class.all_of(TokenScopes::LTI_AGS_RESULT_READ_ONLY_SCOPE)
end
def verify_result_in_line_item
raise ActiveRecord::RecordNotFound unless result.line_item == line_item
end
def line_item_url
lti_line_item_show_url(
host: line_item.root_account.environment_specific_domain,
course_id: params[:course_id],
id: params[:line_item_id]
)
end
def result
@_result = Lti::Result.active.find(params[:id])
end
def results_collection(results)
results.map do |result|
Lti::IMS::ResultsSerializer.new(result, line_item_url).as_json
end
end
end
end