Files
codeocean/spec/concerns/lti_spec.rb
2017-10-25 10:12:29 +02:00

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