186 lines
7.6 KiB
Ruby
186 lines
7.6 KiB
Ruby
require 'rails_helper'
|
|
|
|
class Controller < AnonymousController
|
|
include Lti
|
|
end
|
|
|
|
describe Lti do
|
|
let(:controller) { Controller.new }
|
|
let(:session) { double }
|
|
|
|
describe '#build_tool_provider' do
|
|
it 'instantiates a tool provider' do
|
|
expect(IMS::LTI::ToolProvider).to receive(:new)
|
|
controller.send(:build_tool_provider, consumer: FactoryGirl.build(:consumer), parameters: {})
|
|
end
|
|
end
|
|
|
|
describe '#clear_lti_session_data' do
|
|
it 'clears the session' do
|
|
expect(controller.session).to receive(:delete).with(:consumer_id)
|
|
expect(controller.session).to receive(:delete).with(:external_user_id)
|
|
controller.send(:clear_lti_session_data)
|
|
end
|
|
end
|
|
|
|
describe '#external_user_name' do
|
|
let(:first_name) { 'Jane' }
|
|
let(:last_name) { 'Doe' }
|
|
let(:full_name) { 'John Doe' }
|
|
let(:provider) { double }
|
|
let(:provider_full) { double(:lis_person_name_full => full_name) }
|
|
|
|
context 'when a full name is provided' do
|
|
it 'returns the full name' do
|
|
expect(provider_full).to receive(:lis_person_name_full).twice.and_return(full_name)
|
|
expect(controller.send(:external_user_name, provider_full)).to eq(full_name)
|
|
end
|
|
end
|
|
|
|
context 'when only partial information is provided' do
|
|
it 'returns the first available name' do
|
|
expect(provider).to receive(:lis_person_name_full)
|
|
expect(provider).to receive(:lis_person_name_given).and_return(first_name)
|
|
expect(provider).not_to receive(:lis_person_name_family)
|
|
expect(controller.send(:external_user_name, provider)).to eq(first_name)
|
|
end
|
|
end
|
|
end
|
|
|
|
describe '#refuse_lti_launch' do
|
|
it 'returns to the tool consumer' do
|
|
message = I18n.t('sessions.oauth.invalid_consumer')
|
|
expect(controller).to receive(:return_to_consumer).with(lti_errorlog: message, lti_errormsg: I18n.t('sessions.oauth.failure'))
|
|
controller.send(:refuse_lti_launch, message: message)
|
|
end
|
|
end
|
|
|
|
describe '#return_to_consumer' do
|
|
context 'with a return URL' do
|
|
let(:consumer_return_url) { 'http://example.org' }
|
|
before(:each) { expect(controller).to receive(:params).and_return(launch_presentation_return_url: consumer_return_url) }
|
|
|
|
it 'redirects to the tool consumer' do
|
|
expect(controller).to receive(:redirect_to).with(consumer_return_url)
|
|
controller.send(:return_to_consumer)
|
|
end
|
|
|
|
it 'passes messages to the consumer' do
|
|
message = I18n.t('sessions.oauth.failure')
|
|
expect(controller).to receive(:redirect_to).with("#{consumer_return_url}?lti_errorlog=#{CGI.escape(message)}")
|
|
controller.send(:return_to_consumer, lti_errorlog: message)
|
|
end
|
|
end
|
|
|
|
context 'without a return URL' do
|
|
before(:each) do
|
|
expect(controller).to receive(:params).and_return({})
|
|
expect(controller).to receive(:redirect_to).with(:root)
|
|
end
|
|
|
|
it 'redirects to the root URL' do
|
|
controller.send(:return_to_consumer)
|
|
end
|
|
|
|
it 'displays alerts' do
|
|
message = I18n.t('sessions.oauth.failure')
|
|
controller.send(:return_to_consumer, lti_errormsg: message)
|
|
end
|
|
|
|
it 'displays notices' do
|
|
message = I18n.t('sessions.oauth.success')
|
|
controller.send(:return_to_consumer, lti_msg: message)
|
|
end
|
|
end
|
|
end
|
|
|
|
describe '#send_score' do
|
|
let(:consumer) { FactoryGirl.create(:consumer) }
|
|
let(:score) { 0.5 }
|
|
let(:submission) { FactoryGirl.create(:submission) }
|
|
let!(:lti_parameter) { FactoryGirl.create(:lti_parameter)}
|
|
|
|
context 'with an invalid score' do
|
|
it 'raises an exception' do
|
|
expect { controller.send(:send_score, submission.exercise_id, Lti::MAXIMUM_SCORE * 2, submission.user_id) }.to raise_error(Lti::Error)
|
|
end
|
|
end
|
|
|
|
context 'with an valid score' do
|
|
context 'with a tool consumer' do
|
|
before(:each) do
|
|
controller.session[:consumer_id] = consumer.id
|
|
end
|
|
|
|
context 'when grading is not supported' do
|
|
it 'returns a corresponding status' do
|
|
skip('ralf: this does not work, since send_score pulls data from the database, which then returns an empty array. On this is called .first, which returns nil and lets the test fail. Before Toms changes, this was taken from the session, which could be mocked')
|
|
expect_any_instance_of(IMS::LTI::ToolProvider).to receive(:outcome_service?).and_return(false)
|
|
expect(controller.send(:send_score, submission.exercise_id, score, submission.user_id)[:status]).to eq('unsupported')
|
|
end
|
|
end
|
|
|
|
context 'when grading is supported' do
|
|
let(:response) { double }
|
|
|
|
before(:each) do
|
|
expect_any_instance_of(IMS::LTI::ToolProvider).to receive(:outcome_service?).and_return(true)
|
|
expect_any_instance_of(IMS::LTI::ToolProvider).to receive(:post_replace_result!).with(score).and_return(response)
|
|
expect(response).to receive(:response_code).at_least(:once).and_return(200)
|
|
expect(response).to receive(:post_response).and_return(response)
|
|
expect(response).to receive(:body).at_least(:once).and_return('')
|
|
expect(response).to receive(:code_major).at_least(:once).and_return('success')
|
|
end
|
|
|
|
it 'sends the score' do
|
|
skip('ralf: this does not work, since send_score pulls data from the database, which then returns an empty array. On this is called .first, which returns nil and lets the test fail. Before Toms changes, this was taken from the session, which could be mocked')
|
|
controller.send(:send_score, submission.exercise_id, score, submission.user_id)
|
|
end
|
|
|
|
it 'returns code, message, and status' do
|
|
skip('ralf: this does not work, since send_score pulls data from the database, which then returns an empty array. On this is called .first, which returns nil and lets the test fail. Before Toms changes, this was taken from the session, which could be mocked')
|
|
result = controller.send(:send_score, submission.exercise_id, score, submission.user_id)
|
|
expect(result[:code]).to eq(response.response_code)
|
|
expect(result[:message]).to eq(response.body)
|
|
expect(result[:status]).to eq(response.code_major)
|
|
end
|
|
end
|
|
end
|
|
|
|
context 'without a tool consumer' do
|
|
it 'returns a corresponding status' do
|
|
expect(controller.send(:send_score, submission.exercise_id, score, submission.user_id)[:status]).to eq('error')
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
describe '#store_lti_session_data' do
|
|
let(:parameters) { {} }
|
|
|
|
it 'stores data in the session' do
|
|
controller.instance_variable_set(:@current_user, FactoryGirl.create(:external_user))
|
|
controller.instance_variable_set(:@exercise, FactoryGirl.create(:fibonacci))
|
|
expect(controller.session).to receive(:[]=).with(:consumer_id, anything)
|
|
expect(controller.session).to receive(:[]=).with(:external_user_id, anything)
|
|
controller.send(:store_lti_session_data, consumer: FactoryGirl.build(:consumer), parameters: parameters)
|
|
end
|
|
|
|
it 'it creates an LtiParameter Object' do
|
|
before_count = LtiParameter.count
|
|
controller.instance_variable_set(:@current_user, FactoryGirl.create(:external_user))
|
|
controller.instance_variable_set(:@exercise, FactoryGirl.create(:fibonacci))
|
|
controller.send(:store_lti_session_data, consumer: FactoryGirl.build(:consumer), parameters: parameters)
|
|
expect(LtiParameter.count).to eq(before_count + 1)
|
|
end
|
|
end
|
|
|
|
describe '#store_nonce' do
|
|
it 'adds a nonce to the nonce store' do
|
|
nonce = SecureRandom.hex
|
|
expect(NonceStore).to receive(:add).with(nonce)
|
|
controller.send(:store_nonce, nonce)
|
|
end
|
|
end
|
|
end
|