220 lines
8.0 KiB
Ruby
220 lines
8.0 KiB
Ruby
# frozen_string_literal: true
|
|
|
|
#
|
|
# Copyright (C) 2017 - 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/>.
|
|
#
|
|
|
|
require File.expand_path(File.dirname(__FILE__) + '/lti2_api_spec_helper')
|
|
require File.expand_path(File.dirname(__FILE__) + '/../api_spec_helper')
|
|
|
|
require_dependency "lti/ims/access_token_helper"
|
|
require_dependency "lti/users_api_controller"
|
|
module Lti
|
|
describe UsersApiController, type: :request do
|
|
include_context 'lti2_api_spec_helper'
|
|
|
|
let(:authorized_services) do
|
|
[
|
|
{ "service" => "vnd.Canvas.User", "action" => ["GET"], "@type" => "RestServiceProfile" },
|
|
{ "service" => "vnd.Canvas.GroupIndex", "action" => ["GET"], "@type" => "RestServiceProfile" }
|
|
]
|
|
end
|
|
|
|
let(:assignment) do
|
|
a = course.assignments.new(:title => "some assignment")
|
|
a.workflow_state = "published"
|
|
a.tool_settings_tool = message_handler
|
|
a.save!
|
|
a
|
|
end
|
|
|
|
before do
|
|
message_handler.update(capabilities: [Lti::ResourcePlacement::SIMILARITY_DETECTION_LTI2])
|
|
tool_proxy.raw_data['security_contract']['tool_service'] = authorized_services
|
|
tool_proxy.save!
|
|
assignment.tool_settings_tool = message_handler
|
|
assignment.save!
|
|
end
|
|
|
|
describe '#show' do
|
|
let(:service_name) { UsersApiController::USER_SERVICE }
|
|
let(:canvas_id_endpoint) { "/api/lti/users/#{student.id}" }
|
|
let(:student) do
|
|
course_with_student(active_all: true, course: course)
|
|
@student.update(lti_context_id: SecureRandom.uuid)
|
|
@student
|
|
end
|
|
let(:expected_student) do
|
|
{
|
|
"id" => student.id,
|
|
"created_at" => @student.created_at.iso8601,
|
|
"name" => student.name,
|
|
"sortable_name" => student.sortable_name,
|
|
"short_name" => student.short_name,
|
|
"lti_id" => student.lti_context_id,
|
|
"email" => student.email
|
|
}
|
|
end
|
|
|
|
it 'verifies the tool has the required services' do
|
|
tool_proxy.raw_data['security_contract']['tool_service'] = []
|
|
tool_proxy.save!
|
|
get canvas_id_endpoint, params: { id: student.id }, headers: request_headers
|
|
expect(response).to be_unauthorized
|
|
end
|
|
|
|
it "verifies the tool is associated with at least one of the user's assignments" do
|
|
second_course = Course.create!(name: 'second course')
|
|
assignment.update!(course: second_course)
|
|
get canvas_id_endpoint, params: { id: student.id }, headers: request_headers
|
|
expect(response).to be_unauthorized
|
|
end
|
|
|
|
it 'does not grant access if the tool and the user have no associated assignments' do
|
|
assignment.destroy!
|
|
get canvas_id_endpoint, params: { id: student.id }, headers: request_headers
|
|
expect(response).to be_unauthorized
|
|
end
|
|
|
|
context 'course' do
|
|
before do
|
|
tool_proxy.update!(context: course)
|
|
end
|
|
|
|
it 'returns a user by lti id' do
|
|
get canvas_id_endpoint, params: { id: student.lti_context_id }, headers: request_headers
|
|
parsed_body = JSON.parse(response.body)
|
|
expect(parsed_body).to eq expected_student
|
|
end
|
|
|
|
it 'returns a user by old lti id' do
|
|
UserPastLtiId.create!(user: student, context: course, user_lti_id: student.lti_id, user_lti_context_id: 'old_lti_id', user_uuid: 'old')
|
|
get canvas_id_endpoint, params: { id: 'old_lti_id' }, headers: request_headers
|
|
parsed_body = JSON.parse(response.body)
|
|
new_expected_student = expected_student
|
|
new_expected_student['lti_id'] = 'old_lti_id'
|
|
expect(parsed_body).to eq expected_student
|
|
end
|
|
|
|
it 'returns a user by Canvas id' do
|
|
get canvas_id_endpoint, params: { id: student.id }, headers: request_headers
|
|
parsed_body = JSON.parse(response.body)
|
|
expect(parsed_body).to eq expected_student
|
|
end
|
|
|
|
it 'does not grant access if the course is inactive and the user has no associated assignments' do
|
|
id = student.id
|
|
course.destroy!
|
|
get canvas_id_endpoint, params: { id: id }, headers: request_headers
|
|
expect(response).to be_unauthorized
|
|
end
|
|
end
|
|
|
|
context 'account' do
|
|
it 'returns a user by lti id' do
|
|
get canvas_id_endpoint, params: { id: student.lti_context_id }, headers: request_headers
|
|
parsed_body = JSON.parse(response.body)
|
|
expect(parsed_body).to eq expected_student
|
|
end
|
|
|
|
it 'returns a user by Canvas id' do
|
|
get canvas_id_endpoint, params: { id: student.id }, headers: request_headers
|
|
parsed_body = JSON.parse(response.body)
|
|
expect(parsed_body).to eq expected_student
|
|
end
|
|
end
|
|
end
|
|
|
|
describe '#group_index' do
|
|
include Api::V1::User
|
|
|
|
let(:service_name) { UsersApiController::USER_SERVICE }
|
|
let(:course) { course_model }
|
|
let(:group) { group_model(context: course) }
|
|
let(:group_index_endpoint) { "/api/lti/groups/#{group.global_id}/users" }
|
|
let(:student_lti_id) { SecureRandom.uuid }
|
|
|
|
let(:student_one) do
|
|
student_in_course(course: group.context)
|
|
@student.update!(lti_context_id: student_lti_id)
|
|
@student
|
|
end
|
|
|
|
let(:student_two) do
|
|
student_in_course(course: group.context)
|
|
@student
|
|
end
|
|
|
|
let(:student_three) do
|
|
student_in_course(course: group.context)
|
|
@student.update!(email: 'student@test.com')
|
|
@student
|
|
end
|
|
|
|
before do
|
|
group.context.update!(account: tool_proxy.account)
|
|
group.add_user(student_one, 'accepted')
|
|
group.add_user(student_two, 'accepted')
|
|
group.add_user(student_three, 'accepted')
|
|
end
|
|
|
|
it 'returns a list of users in the specified group' do
|
|
get group_index_endpoint, headers: request_headers
|
|
parsed_body = JSON.parse(response.body)
|
|
expected_json = group.users.map do |user|
|
|
user_json(user, user, nil, [], group.context, tool_includes: %w(email lti_id))
|
|
end
|
|
expect(parsed_body.sort_by { |u| u[:id] }).to eq(expected_json.sort_by { |u| u[:id] })
|
|
end
|
|
|
|
it 'responds with 401 if group is not in tool context' do
|
|
group.context.update!(account: account_model)
|
|
get group_index_endpoint, headers: request_headers
|
|
expect(response).to be_unauthorized
|
|
end
|
|
|
|
it 'responds with 401 if the group is not active' do
|
|
group.update!(workflow_state: 'deleted')
|
|
get group_index_endpoint, headers: request_headers
|
|
expect(response).to be_unauthorized
|
|
end
|
|
|
|
it 'responds with 404 if group is not found' do
|
|
get "/api/lti/groups/#{group.global_id + 1}/users", headers: request_headers
|
|
expect(response).to be_not_found
|
|
end
|
|
|
|
it 'includes user lti id' do
|
|
get group_index_endpoint, headers: request_headers
|
|
parsed_body = JSON.parse(response.body)
|
|
user_json = parsed_body.find { |u| u['id'] == student_one.id }
|
|
expect(user_json['lti_id']).to eq student_one.lti_context_id
|
|
end
|
|
|
|
it 'does not include students who are not in the group' do
|
|
student_in_course(course: group.context)
|
|
get group_index_endpoint, headers: request_headers
|
|
parsed_body = JSON.parse(response.body)
|
|
expected_json = group.users.map do |user|
|
|
user_json(user, user, nil, [], group.context, tool_includes: %w(email lti_id))
|
|
end
|
|
expect(parsed_body.sort_by { |u| u[:id] }).to eq(expected_json.sort_by { |u| u[:id] })
|
|
end
|
|
end
|
|
end
|
|
end
|