Apply manual rubocop fixes
This commit is contained in:
@ -33,11 +33,11 @@ describe Lti do
|
||||
let(:last_name) { 'Doe' }
|
||||
let(:full_name) { 'John Doe' }
|
||||
let(:provider) { double }
|
||||
let(:provider_full) { double(lis_person_name_full: full_name) }
|
||||
let(:provider_full) { instance_double('IMS::LTI::ToolProvider', 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)
|
||||
allow(provider_full).to receive(:lis_person_name_full).and_return(full_name)
|
||||
expect(controller.send(:external_user_name, provider_full)).to eq(full_name)
|
||||
end
|
||||
end
|
||||
@ -45,7 +45,7 @@ describe Lti do
|
||||
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)
|
||||
allow(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
|
||||
@ -64,7 +64,7 @@ describe Lti do
|
||||
context 'with a return URL' do
|
||||
let(:consumer_return_url) { 'http://example.org' }
|
||||
|
||||
before { expect(controller).to receive(:params).and_return(launch_presentation_return_url: consumer_return_url) }
|
||||
before { allow(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)
|
||||
@ -80,8 +80,8 @@ describe Lti do
|
||||
|
||||
context 'without a return URL' do
|
||||
before do
|
||||
expect(controller).to receive(:params).and_return({})
|
||||
expect(controller).to receive(:redirect_to).with(:root)
|
||||
allow(controller).to receive(:params).and_return({})
|
||||
allow(controller).to receive(:redirect_to).with(:root)
|
||||
end
|
||||
|
||||
it 'redirects to the root URL' do
|
||||
@ -104,7 +104,10 @@ describe Lti do
|
||||
let(:consumer) { FactoryBot.create(:consumer) }
|
||||
let(:score) { 0.5 }
|
||||
let(:submission) { FactoryBot.create(:submission) }
|
||||
let!(:lti_parameter) { FactoryBot.create(:lti_parameter, consumers_id: consumer.id, external_users_id: submission.user_id, exercises_id: submission.exercise_id) }
|
||||
|
||||
before do
|
||||
FactoryBot.create(:lti_parameter, consumers_id: consumer.id, external_users_id: submission.user_id, exercises_id: submission.exercise_id)
|
||||
end
|
||||
|
||||
context 'with an invalid score' do
|
||||
it 'raises an exception' do
|
||||
@ -117,7 +120,7 @@ describe Lti do
|
||||
context 'with a tool consumer' do
|
||||
context 'when grading is not supported' do
|
||||
it 'returns a corresponding status' do
|
||||
expect_any_instance_of(IMS::LTI::ToolProvider).to receive(:outcome_service?).and_return(false)
|
||||
allow_any_instance_of(IMS::LTI::ToolProvider).to receive(:outcome_service?).and_return(false)
|
||||
allow(submission).to receive(:normalized_score).and_return score
|
||||
expect(controller.send(:send_score, submission)[:status]).to eq('unsupported')
|
||||
end
|
||||
@ -127,12 +130,12 @@ describe Lti do
|
||||
let(:response) { double }
|
||||
|
||||
before 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')
|
||||
allow_any_instance_of(IMS::LTI::ToolProvider).to receive(:outcome_service?).and_return(true)
|
||||
allow_any_instance_of(IMS::LTI::ToolProvider).to receive(:post_replace_result!).with(score).and_return(response)
|
||||
allow(response).to receive(:response_code).at_least(:once).and_return(200)
|
||||
allow(response).to receive(:post_response).and_return(response)
|
||||
allow(response).to receive(:body).at_least(:once).and_return('')
|
||||
allow(response).to receive(:code_major).at_least(:once).and_return('success')
|
||||
end
|
||||
|
||||
it 'sends the score' do
|
||||
|
@ -8,30 +8,29 @@ end
|
||||
|
||||
describe SubmissionScoring do
|
||||
let(:controller) { Controller.new }
|
||||
|
||||
before(:all) { @submission = FactoryBot.create(:submission, cause: 'submit') }
|
||||
let(:submission) { FactoryBot.create(:submission, cause: 'submit') }
|
||||
|
||||
before { controller.instance_variable_set(:@current_user, FactoryBot.create(:external_user)) }
|
||||
|
||||
describe '#collect_test_results' do
|
||||
after { controller.send(:collect_test_results, @submission) }
|
||||
after { controller.send(:collect_test_results, submission) }
|
||||
|
||||
it 'executes every teacher-defined test file' do
|
||||
@submission.collect_files.select(&:teacher_defined_assessment?).each do |file|
|
||||
expect(controller).to receive(:execute_test_file).with(file, @submission).and_return({})
|
||||
submission.collect_files.select(&:teacher_defined_assessment?).each do |file|
|
||||
allow(controller).to receive(:execute_test_file).with(file, submission).and_return({})
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe '#score_submission' do
|
||||
after { controller.score_submission(@submission) }
|
||||
after { controller.score_submission(submission) }
|
||||
|
||||
it 'collects the test results' do
|
||||
expect(controller).to receive(:collect_test_results).and_return([])
|
||||
allow(controller).to receive(:collect_test_results).and_return([])
|
||||
end
|
||||
|
||||
it 'assigns a score to the submissions' do
|
||||
expect(@submission).to receive(:update).with(score: anything)
|
||||
expect(submission).to receive(:update).with(score: anything)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
@ -27,7 +27,7 @@ describe ApplicationController do
|
||||
|
||||
describe '#render_not_authorized' do
|
||||
before do
|
||||
expect(controller).to receive(:welcome) { controller.send(:render_not_authorized) }
|
||||
allow(controller).to receive(:welcome) { controller.send(:render_not_authorized) }
|
||||
get :welcome
|
||||
end
|
||||
|
||||
@ -41,14 +41,14 @@ describe ApplicationController do
|
||||
context 'when specifying a locale' do
|
||||
before { allow(session).to receive(:[]=).at_least(:once) }
|
||||
|
||||
context "using the 'custom_locale' parameter" do
|
||||
context "when using the 'custom_locale' parameter" do
|
||||
it 'overwrites the session' do
|
||||
expect(session).to receive(:[]=).with(:locale, locale.to_s)
|
||||
get :welcome, params: {custom_locale: locale}
|
||||
end
|
||||
end
|
||||
|
||||
context "using the 'locale' parameter" do
|
||||
context "when using the 'locale' parameter" do
|
||||
it 'overwrites the session' do
|
||||
expect(session).to receive(:[]=).with(:locale, locale.to_s)
|
||||
get :welcome, params: {locale: locale}
|
||||
|
@ -14,7 +14,7 @@ describe CodeharborLinksController do
|
||||
allow(controller).to receive(:current_user).and_return(user)
|
||||
end
|
||||
|
||||
context 'GET #new' do
|
||||
describe 'GET #new' do
|
||||
before do
|
||||
get :new
|
||||
end
|
||||
|
@ -54,9 +54,10 @@ describe ConsumersController do
|
||||
end
|
||||
|
||||
describe 'GET #index' do
|
||||
let!(:consumers) { FactoryBot.create_pair(:consumer) }
|
||||
|
||||
before { get :index }
|
||||
before do
|
||||
FactoryBot.create_pair(:consumer)
|
||||
get :index
|
||||
end
|
||||
|
||||
expect_assigns(consumers: Consumer.all)
|
||||
expect_status(200)
|
||||
|
@ -9,7 +9,7 @@ describe ExecutionEnvironmentsController do
|
||||
before { allow(controller).to receive(:current_user).and_return(user) }
|
||||
|
||||
describe 'POST #create' do
|
||||
before { expect(DockerClient).to receive(:image_tags).at_least(:once).and_return([]) }
|
||||
before { allow(DockerClient).to receive(:image_tags).at_least(:once).and_return([]) }
|
||||
|
||||
context 'with a valid execution environment' do
|
||||
let(:perform_request) { proc { post :create, params: {execution_environment: FactoryBot.build(:ruby).attributes} } }
|
||||
@ -50,7 +50,7 @@ describe ExecutionEnvironmentsController do
|
||||
|
||||
describe 'GET #edit' do
|
||||
before do
|
||||
expect(DockerClient).to receive(:image_tags).at_least(:once).and_return([])
|
||||
allow(DockerClient).to receive(:image_tags).at_least(:once).and_return([])
|
||||
get :edit, params: {id: execution_environment.id}
|
||||
end
|
||||
|
||||
@ -64,8 +64,8 @@ describe ExecutionEnvironmentsController do
|
||||
let(:command) { 'which ruby' }
|
||||
|
||||
before do
|
||||
expect(DockerClient).to receive(:new).with(execution_environment: execution_environment).and_call_original
|
||||
expect_any_instance_of(DockerClient).to receive(:execute_arbitrary_command).with(command)
|
||||
allow(DockerClient).to receive(:new).with(execution_environment: execution_environment).and_call_original
|
||||
allow_any_instance_of(DockerClient).to receive(:execute_arbitrary_command).with(command)
|
||||
post :execute_command, params: {command: command, id: execution_environment.id}
|
||||
end
|
||||
|
||||
@ -76,9 +76,10 @@ describe ExecutionEnvironmentsController do
|
||||
end
|
||||
|
||||
describe 'GET #index' do
|
||||
before(:all) { FactoryBot.create_pair(:ruby) }
|
||||
|
||||
before { get :index }
|
||||
before do
|
||||
FactoryBot.create_pair(:ruby)
|
||||
get :index
|
||||
end
|
||||
|
||||
expect_assigns(execution_environments: ExecutionEnvironment.all)
|
||||
expect_status(200)
|
||||
@ -87,7 +88,7 @@ describe ExecutionEnvironmentsController do
|
||||
|
||||
describe 'GET #new' do
|
||||
before do
|
||||
expect(DockerClient).to receive(:image_tags).at_least(:once).and_return([])
|
||||
allow(DockerClient).to receive(:image_tags).at_least(:once).and_return([])
|
||||
get :new
|
||||
end
|
||||
|
||||
@ -102,8 +103,8 @@ describe ExecutionEnvironmentsController do
|
||||
let(:docker_images) { [1, 2, 3] }
|
||||
|
||||
before do
|
||||
expect(DockerClient).to receive(:check_availability!).at_least(:once)
|
||||
expect(DockerClient).to receive(:image_tags).and_return(docker_images)
|
||||
allow(DockerClient).to receive(:check_availability!).at_least(:once)
|
||||
allow(DockerClient).to receive(:image_tags).and_return(docker_images)
|
||||
controller.send(:set_docker_images)
|
||||
end
|
||||
|
||||
@ -114,7 +115,7 @@ describe ExecutionEnvironmentsController do
|
||||
let(:error_message) { 'Docker is unavailable' }
|
||||
|
||||
before do
|
||||
expect(DockerClient).to receive(:check_availability!).at_least(:once).and_raise(DockerClient::Error.new(error_message))
|
||||
allow(DockerClient).to receive(:check_availability!).at_least(:once).and_raise(DockerClient::Error.new(error_message))
|
||||
controller.send(:set_docker_images)
|
||||
end
|
||||
|
||||
@ -154,7 +155,7 @@ describe ExecutionEnvironmentsController do
|
||||
describe 'PUT #update' do
|
||||
context 'with a valid execution environment' do
|
||||
before do
|
||||
expect(DockerClient).to receive(:image_tags).at_least(:once).and_return([])
|
||||
allow(DockerClient).to receive(:image_tags).at_least(:once).and_return([])
|
||||
put :update, params: {execution_environment: FactoryBot.attributes_for(:ruby), id: execution_environment.id}
|
||||
end
|
||||
|
||||
|
@ -45,7 +45,7 @@ describe ExercisesController do
|
||||
|
||||
context 'when saving fails' do
|
||||
before do
|
||||
expect_any_instance_of(Exercise).to receive(:save).and_return(false)
|
||||
allow_any_instance_of(Exercise).to receive(:save).and_return(false)
|
||||
perform_request.call
|
||||
end
|
||||
|
||||
@ -87,7 +87,7 @@ describe ExercisesController do
|
||||
let(:files_attributes) { {'0' => FactoryBot.build(:file, file_type: file_type).attributes.merge(content: uploaded_file)} }
|
||||
|
||||
context 'when uploading a binary file' do
|
||||
let(:file_path) { Rails.root.join('db', 'seeds', 'audio_video', 'devstories.mp4') }
|
||||
let(:file_path) { Rails.root.join('db/seeds/audio_video/devstories.mp4') }
|
||||
let(:file_type) { FactoryBot.create(:dot_mp4) }
|
||||
let(:uploaded_file) { Rack::Test::UploadedFile.new(file_path, 'video/mp4', true) }
|
||||
|
||||
@ -102,7 +102,7 @@ describe ExercisesController do
|
||||
end
|
||||
|
||||
context 'when uploading a non-binary file' do
|
||||
let(:file_path) { Rails.root.join('db', 'seeds', 'fibonacci', 'exercise.rb') }
|
||||
let(:file_path) { Rails.root.join('db/seeds/fibonacci/exercise.rb') }
|
||||
let(:file_type) { FactoryBot.create(:dot_rb) }
|
||||
let(:uploaded_file) { Rack::Test::UploadedFile.new(file_path, 'text/x-ruby', false) }
|
||||
|
||||
@ -189,9 +189,10 @@ describe ExercisesController do
|
||||
describe 'GET #index' do
|
||||
let(:scope) { Pundit.policy_scope!(user, Exercise) }
|
||||
|
||||
before(:all) { FactoryBot.create_pair(:dummy) }
|
||||
|
||||
before { get :index }
|
||||
before do
|
||||
FactoryBot.create_pair(:dummy)
|
||||
get :index
|
||||
end
|
||||
|
||||
expect_assigns(exercises: :scope)
|
||||
expect_status(200)
|
||||
@ -208,7 +209,7 @@ describe ExercisesController do
|
||||
end
|
||||
|
||||
describe 'GET #show' do
|
||||
context 'as admin' do
|
||||
context 'when being admin' do
|
||||
before { get :show, params: {id: exercise.id} }
|
||||
|
||||
expect_assigns(exercise: :exercise)
|
||||
@ -218,7 +219,7 @@ describe ExercisesController do
|
||||
end
|
||||
|
||||
describe 'GET #reload' do
|
||||
context 'as anyone' do
|
||||
context 'when being anyone' do
|
||||
before { get :reload, format: :json, params: {id: exercise.id} }
|
||||
|
||||
expect_assigns(exercise: :exercise)
|
||||
@ -239,22 +240,22 @@ describe ExercisesController do
|
||||
let(:output) { {} }
|
||||
let(:perform_request) { post :submit, format: :json, params: {id: exercise.id, submission: {cause: 'submit', exercise_id: exercise.id}} }
|
||||
let(:user) { FactoryBot.create(:external_user) }
|
||||
let!(:lti_parameter) { FactoryBot.create(:lti_parameter, external_user: user, exercise: exercise) }
|
||||
|
||||
before do
|
||||
FactoryBot.create(:lti_parameter, external_user: user, exercise: exercise)
|
||||
allow_any_instance_of(Submission).to receive(:normalized_score).and_return(1)
|
||||
expect(controller).to receive(:collect_test_results).and_return([{score: 1, weight: 1}])
|
||||
expect(controller).to receive(:score_submission).and_call_original
|
||||
allow(controller).to receive(:collect_test_results).and_return([{score: 1, weight: 1}])
|
||||
allow(controller).to receive(:score_submission).and_call_original
|
||||
end
|
||||
|
||||
context 'when LTI outcomes are supported' do
|
||||
before do
|
||||
expect(controller).to receive(:lti_outcome_service?).and_return(true)
|
||||
allow(controller).to receive(:lti_outcome_service?).and_return(true)
|
||||
end
|
||||
|
||||
context 'when the score transmission succeeds' do
|
||||
before do
|
||||
expect(controller).to receive(:send_score).and_return(status: 'success')
|
||||
allow(controller).to receive(:send_score).and_return(status: 'success')
|
||||
perform_request
|
||||
end
|
||||
|
||||
@ -270,7 +271,7 @@ describe ExercisesController do
|
||||
|
||||
context 'when the score transmission fails' do
|
||||
before do
|
||||
expect(controller).to receive(:send_score).and_return(status: 'unsupported')
|
||||
allow(controller).to receive(:send_score).and_return(status: 'unsupported')
|
||||
perform_request
|
||||
end
|
||||
|
||||
@ -287,8 +288,7 @@ describe ExercisesController do
|
||||
|
||||
context 'when LTI outcomes are not supported' do
|
||||
before do
|
||||
expect(controller).to receive(:lti_outcome_service?).and_return(false)
|
||||
expect(controller).not_to receive(:send_score)
|
||||
allow(controller).to receive(:lti_outcome_service?).and_return(false)
|
||||
perform_request
|
||||
end
|
||||
|
||||
@ -298,6 +298,10 @@ describe ExercisesController do
|
||||
expect(assigns(:submission)).to be_a(Submission)
|
||||
end
|
||||
|
||||
it 'does not send scores' do
|
||||
expect(controller).not_to receive(:send_score)
|
||||
end
|
||||
|
||||
expect_json
|
||||
expect_status(200)
|
||||
end
|
||||
@ -333,7 +337,7 @@ describe ExercisesController do
|
||||
let(:external_check_hash) { {message: message, exercise_found: true, update_right: update_right, error: error} }
|
||||
let(:message) { 'message' }
|
||||
let(:update_right) { true }
|
||||
let(:error) {}
|
||||
let(:error) { nil }
|
||||
|
||||
before { allow(ExerciseService::CheckExternal).to receive(:call).with(uuid: exercise.uuid, codeharbor_link: codeharbor_link).and_return(external_check_hash) }
|
||||
|
||||
@ -384,7 +388,7 @@ describe ExercisesController do
|
||||
|
||||
let!(:codeharbor_link) { FactoryBot.create(:codeharbor_link, user: user) }
|
||||
let(:post_request) { post :export_external_confirm, params: {id: exercise.id, codeharbor_link: codeharbor_link.id} }
|
||||
let(:error) {}
|
||||
let(:error) { nil }
|
||||
let(:zip) { 'zip' }
|
||||
|
||||
before do
|
||||
|
@ -57,9 +57,10 @@ describe FileTypesController do
|
||||
end
|
||||
|
||||
describe 'GET #index' do
|
||||
before(:all) { FactoryBot.create_pair(:dot_rb) }
|
||||
|
||||
before { get :index }
|
||||
before do
|
||||
FactoryBot.create_pair(:dot_rb)
|
||||
get :index
|
||||
end
|
||||
|
||||
expect_assigns(file_types: FileType.all)
|
||||
expect_status(200)
|
||||
|
@ -45,6 +45,9 @@ describe InternalUsersController do
|
||||
before do
|
||||
user.send(:setup_activation)
|
||||
user.save(validate: false)
|
||||
end
|
||||
|
||||
it 'adds an activation token' do
|
||||
expect(user.activation_token).to be_present
|
||||
end
|
||||
|
||||
@ -171,7 +174,7 @@ describe InternalUsersController do
|
||||
before do
|
||||
allow(controller).to receive(:set_sentry_context).and_return(nil)
|
||||
|
||||
expect(controller).to receive(:current_user).and_return(nil)
|
||||
allow(controller).to receive(:current_user).and_return(nil)
|
||||
get :forgot_password
|
||||
end
|
||||
|
||||
@ -183,7 +186,7 @@ describe InternalUsersController do
|
||||
before do
|
||||
allow(controller).to receive(:set_sentry_context).and_return(nil)
|
||||
|
||||
expect(controller).to receive(:current_user).and_return(user)
|
||||
allow(controller).to receive(:current_user).and_return(user)
|
||||
get :forgot_password
|
||||
end
|
||||
|
||||
@ -199,7 +202,7 @@ describe InternalUsersController do
|
||||
before { perform_request.call }
|
||||
|
||||
it 'delivers instructions to reset the password' do
|
||||
expect(InternalUser).to receive(:where).and_return([user])
|
||||
allow(InternalUser).to receive(:where).and_return([user])
|
||||
expect(user).to receive(:deliver_reset_password_instructions!)
|
||||
perform_request.call
|
||||
end
|
||||
|
@ -32,24 +32,24 @@ describe RequestForCommentsController do
|
||||
end
|
||||
end
|
||||
|
||||
describe 'GET #get_my_comment_requests' do
|
||||
before { get :get_my_comment_requests }
|
||||
describe 'GET #my_comment_requests' do
|
||||
before { get :my_comment_requests }
|
||||
|
||||
expect_status(200)
|
||||
expect_template(:index)
|
||||
end
|
||||
|
||||
describe 'GET #get_rfcs_with_my_comments' do
|
||||
before { get :get_rfcs_with_my_comments }
|
||||
describe 'GET #rfcs_with_my_comments' do
|
||||
before { get :rfcs_with_my_comments }
|
||||
|
||||
expect_status(200)
|
||||
expect_template(:index)
|
||||
end
|
||||
|
||||
describe 'GET #get_rfcs_for_exercise' do
|
||||
describe 'GET #rfcs_for_exercise' do
|
||||
before do
|
||||
exercise = FactoryBot.create(:even_odd)
|
||||
get :get_rfcs_for_exercise, params: {exercise_id: exercise.id}
|
||||
get :rfcs_for_exercise, params: {exercise_id: exercise.id}
|
||||
end
|
||||
|
||||
expect_status(200)
|
||||
|
@ -58,8 +58,8 @@ describe SessionsController do
|
||||
|
||||
context 'without a unique OAuth nonce' do
|
||||
it 'refuses the LTI launch' do
|
||||
expect_any_instance_of(IMS::LTI::ToolProvider).to receive(:valid_request?).and_return(true)
|
||||
expect(NonceStore).to receive(:has?).with(nonce).and_return(true)
|
||||
allow_any_instance_of(IMS::LTI::ToolProvider).to receive(:valid_request?).and_return(true)
|
||||
allow(NonceStore).to receive(:has?).with(nonce).and_return(true)
|
||||
expect(controller).to receive(:refuse_lti_launch).with(message: I18n.t('sessions.oauth.used_nonce')).and_call_original
|
||||
post :create_through_lti, params: {oauth_consumer_key: consumer.oauth_key, oauth_nonce: nonce, oauth_signature: SecureRandom.hex}
|
||||
end
|
||||
@ -67,7 +67,7 @@ describe SessionsController do
|
||||
|
||||
context 'without a valid exercise token' do
|
||||
it 'refuses the LTI launch' do
|
||||
expect_any_instance_of(IMS::LTI::ToolProvider).to receive(:valid_request?).and_return(true)
|
||||
allow_any_instance_of(IMS::LTI::ToolProvider).to receive(:valid_request?).and_return(true)
|
||||
expect(controller).to receive(:refuse_lti_launch).with(message: I18n.t('sessions.oauth.invalid_exercise_token')).and_call_original
|
||||
post :create_through_lti, params: {custom_token: '', oauth_consumer_key: consumer.oauth_key, oauth_nonce: nonce, oauth_signature: SecureRandom.hex, user_id: '123'}
|
||||
end
|
||||
@ -78,7 +78,7 @@ describe SessionsController do
|
||||
let(:perform_request) { post :create_through_lti, params: {custom_locale: locale, custom_token: exercise.token, oauth_consumer_key: consumer.oauth_key, oauth_nonce: nonce, oauth_signature: SecureRandom.hex, user_id: user.external_id} }
|
||||
let(:user) { FactoryBot.create(:external_user, consumer_id: consumer.id) }
|
||||
|
||||
before { expect_any_instance_of(IMS::LTI::ToolProvider).to receive(:valid_request?).and_return(true) }
|
||||
before { allow_any_instance_of(IMS::LTI::ToolProvider).to receive(:valid_request?).and_return(true) }
|
||||
|
||||
it 'assigns the current user' do
|
||||
perform_request
|
||||
@ -112,7 +112,7 @@ describe SessionsController do
|
||||
let(:message) { I18n.t('sessions.create_through_lti.session_with_outcome', consumer: consumer) }
|
||||
|
||||
before do
|
||||
expect(controller).to receive(:lti_outcome_service?).and_return(true)
|
||||
allow(controller).to receive(:lti_outcome_service?).and_return(true)
|
||||
perform_request
|
||||
end
|
||||
|
||||
@ -123,7 +123,7 @@ describe SessionsController do
|
||||
let(:message) { I18n.t('sessions.create_through_lti.session_without_outcome', consumer: consumer) }
|
||||
|
||||
before do
|
||||
expect(controller).to receive(:lti_outcome_service?).and_return(false)
|
||||
allow(controller).to receive(:lti_outcome_service?).and_return(false)
|
||||
perform_request
|
||||
end
|
||||
|
||||
@ -159,7 +159,7 @@ describe SessionsController do
|
||||
|
||||
before do
|
||||
allow(controller).to receive(:set_sentry_context).and_return(nil)
|
||||
expect(controller).to receive(:current_user).at_least(:once).and_return(user)
|
||||
allow(controller).to receive(:current_user).at_least(:once).and_return(user)
|
||||
end
|
||||
|
||||
context 'with an internal user' do
|
||||
@ -199,7 +199,14 @@ describe SessionsController do
|
||||
|
||||
describe 'GET #destroy_through_lti' do
|
||||
let(:perform_request) { proc { get :destroy_through_lti, params: {consumer_id: consumer.id, submission_id: submission.id} } }
|
||||
let(:submission) { FactoryBot.create(:submission, exercise: FactoryBot.create(:dummy)) } before { perform_request.call }
|
||||
let(:submission) { FactoryBot.create(:submission, exercise: FactoryBot.create(:dummy)) }
|
||||
|
||||
before do
|
||||
# Todo replace session with lti_parameter
|
||||
# Todo create LtiParameter Object
|
||||
# session[:lti_parameters] = {}
|
||||
perform_request.call
|
||||
end
|
||||
|
||||
it 'clears the session' do
|
||||
# Todo replace session with lti_parameter /should be done already
|
||||
@ -216,7 +223,7 @@ describe SessionsController do
|
||||
before do
|
||||
allow(controller).to receive(:set_sentry_context).and_return(nil)
|
||||
|
||||
expect(controller).to receive(:current_user).and_return(nil)
|
||||
allow(controller).to receive(:current_user).and_return(nil)
|
||||
get :new
|
||||
end
|
||||
|
||||
@ -228,7 +235,7 @@ describe SessionsController do
|
||||
before do
|
||||
allow(controller).to receive(:set_sentry_context).and_return(nil)
|
||||
|
||||
expect(controller).to receive(:current_user).and_return(FactoryBot.build(:teacher))
|
||||
allow(controller).to receive(:current_user).and_return(FactoryBot.build(:teacher))
|
||||
get :new
|
||||
end
|
||||
|
||||
|
@ -50,7 +50,7 @@ describe SubmissionsController do
|
||||
|
||||
before { get :download_file, params: {filename: file.name_with_extension, id: submission.id} }
|
||||
|
||||
context 'for a binary file' do
|
||||
context 'with a binary file' do
|
||||
let(:file) { submission.collect_files.detect {|file| file.name == 'exercise' && file.file_type.file_extension == '.sql' } }
|
||||
|
||||
expect_assigns(file: :file)
|
||||
@ -69,7 +69,7 @@ describe SubmissionsController do
|
||||
|
||||
before { get :download_file, params: {filename: file.name_with_extension, id: submission.id} }
|
||||
|
||||
context 'for a binary file' do
|
||||
context 'with a binary file' do
|
||||
let(:file) { submission.collect_files.detect {|file| file.file_type.file_extension == '.mp4' } }
|
||||
|
||||
expect_assigns(file: :file)
|
||||
@ -82,7 +82,7 @@ describe SubmissionsController do
|
||||
end
|
||||
end
|
||||
|
||||
context 'for a non-binary file' do
|
||||
context 'with a non-binary file' do
|
||||
let(:file) { submission.collect_files.detect {|file| file.file_type.file_extension == '.js' } }
|
||||
|
||||
expect_assigns(file: :file)
|
||||
@ -98,9 +98,10 @@ describe SubmissionsController do
|
||||
end
|
||||
|
||||
describe 'GET #index' do
|
||||
before(:all) { FactoryBot.create_pair(:submission) }
|
||||
|
||||
before { get :index }
|
||||
before do
|
||||
FactoryBot.create_pair(:submission)
|
||||
get :index
|
||||
end
|
||||
|
||||
expect_assigns(submissions: Submission.all)
|
||||
expect_status(200)
|
||||
@ -121,7 +122,7 @@ describe SubmissionsController do
|
||||
|
||||
before { get :render_file, params: {filename: file.name_with_extension, id: submission.id} }
|
||||
|
||||
context 'for a binary file' do
|
||||
context 'with a binary file' do
|
||||
let(:file) { submission.collect_files.detect {|file| file.file_type.file_extension == '.mp4' } }
|
||||
|
||||
expect_assigns(file: :file)
|
||||
@ -134,7 +135,7 @@ describe SubmissionsController do
|
||||
end
|
||||
end
|
||||
|
||||
context 'for a non-binary file' do
|
||||
context 'with a non-binary file' do
|
||||
let(:file) { submission.collect_files.detect {|file| file.file_type.file_extension == '.js' } }
|
||||
|
||||
expect_assigns(file: :file)
|
||||
@ -154,12 +155,12 @@ describe SubmissionsController do
|
||||
let(:perform_request) { get :run, params: {filename: filename, id: submission.id} }
|
||||
|
||||
before do
|
||||
expect_any_instance_of(ActionController::Live::SSE).to receive(:write).at_least(3).times
|
||||
allow_any_instance_of(ActionController::Live::SSE).to receive(:write).at_least(3).times
|
||||
end
|
||||
|
||||
context 'when no errors occur during execution' do
|
||||
before do
|
||||
expect_any_instance_of(DockerClient).to receive(:execute_run_command).with(submission, filename).and_return({})
|
||||
allow_any_instance_of(DockerClient).to receive(:execute_run_command).with(submission, filename).and_return({})
|
||||
perform_request
|
||||
end
|
||||
|
||||
@ -222,7 +223,7 @@ describe SubmissionsController do
|
||||
let(:output) { {} }
|
||||
|
||||
before do
|
||||
expect_any_instance_of(DockerClient).to receive(:execute_test_command).with(submission, filename)
|
||||
allow_any_instance_of(DockerClient).to receive(:execute_test_command).with(submission, filename)
|
||||
get :test, params: {filename: filename, id: submission.id}
|
||||
end
|
||||
|
||||
|
@ -9,7 +9,9 @@ describe 'seeds' do
|
||||
CodeOcean::Application.load_tasks
|
||||
|
||||
# We want to execute the seeds for the dev environment against the test database
|
||||
# rubocop:disable Rails/Inquiry
|
||||
allow(Rails).to receive(:env) { 'development'.inquiry }
|
||||
# rubocop:enable Rails/Inquiry
|
||||
allow(ActiveRecord::Base).to receive(:establish_connection).and_call_original
|
||||
allow(ActiveRecord::Base).to receive(:establish_connection).with(:development) {
|
||||
ActiveRecord::Base.establish_connection(:test)
|
||||
|
@ -16,7 +16,7 @@ module CodeOcean
|
||||
trait(:image) do
|
||||
association :file_type, factory: :dot_png
|
||||
name { 'poster' }
|
||||
native_file { Rack::Test::UploadedFile.new(Rails.root.join('db', 'seeds', 'audio_video', 'poster.png'), 'image/png') }
|
||||
native_file { Rack::Test::UploadedFile.new(Rails.root.join('db/seeds/audio_video/poster.png'), 'image/png') }
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -1,7 +1,7 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
FactoryBot.define do
|
||||
LTI_PARAMETERS = {
|
||||
lti_params = {
|
||||
lis_result_sourcedid: 'c2db0c7c-4411-4b27-a52b-ddfc3dc32065',
|
||||
lis_outcome_service_url: 'http://172.16.54.235:3000/courses/0132156a-9afb-434d-83cc-704780104105/sections/21c6c6f4-1fb6-43b4-af3c-04fdc098879e/items/999b1fe6-d4b6-47b7-a577-ea2b4b1041ec/tool_grading',
|
||||
launch_presentation_return_url: 'http://172.16.54.235:3000/courses/0132156a-9afb-434d-83cc-704780104105/sections/21c6c6f4-1fb6-43b4-af3c-04fdc098879e/items/999b1fe6-d4b6-47b7-a577-ea2b4b1041ec/tool_return',
|
||||
@ -12,10 +12,10 @@ FactoryBot.define do
|
||||
association :exercise, factory: :math
|
||||
association :external_user
|
||||
|
||||
lti_parameters { LTI_PARAMETERS }
|
||||
lti_parameters { lti_params }
|
||||
|
||||
trait :without_outcome_service_url do
|
||||
lti_parameters { LTI_PARAMETERS.except(:lis_outcome_service_url) }
|
||||
lti_parameters { lti_params.except(:lis_outcome_service_url) }
|
||||
end
|
||||
end
|
||||
end
|
||||
|
@ -3,7 +3,7 @@
|
||||
require 'rails_helper'
|
||||
|
||||
describe 'Authorization' do
|
||||
context 'as an admin' do
|
||||
context 'when being an admin' do
|
||||
let(:user) { FactoryBot.create(:admin) }
|
||||
|
||||
before { allow_any_instance_of(ApplicationController).to receive(:current_user).and_return(user) }
|
||||
@ -13,7 +13,7 @@ describe 'Authorization' do
|
||||
end
|
||||
end
|
||||
|
||||
context 'as an external user' do
|
||||
context 'with being an external user' do
|
||||
let(:user) { FactoryBot.create(:external_user) }
|
||||
|
||||
before { allow_any_instance_of(ApplicationController).to receive(:current_user).and_return(user) }
|
||||
@ -23,7 +23,7 @@ describe 'Authorization' do
|
||||
end
|
||||
end
|
||||
|
||||
context 'as a teacher' do
|
||||
context 'with being a teacher' do
|
||||
let(:user) { FactoryBot.create(:teacher) }
|
||||
|
||||
before { allow_any_instance_of(ApplicationController).to receive(:current_user).and_return(user) }
|
||||
|
@ -29,7 +29,7 @@ describe 'Editor', js: true do
|
||||
fill_in('email', with: user.email)
|
||||
fill_in('password', with: FactoryBot.attributes_for(:teacher)[:password])
|
||||
click_button(I18n.t('sessions.new.link'))
|
||||
expect_any_instance_of(LtiHelper).to receive(:lti_outcome_service?).and_return(true)
|
||||
allow_any_instance_of(LtiHelper).to receive(:lti_outcome_service?).and_return(true)
|
||||
visit(implement_exercise_path(exercise))
|
||||
end
|
||||
|
||||
|
@ -7,8 +7,9 @@ describe Prometheus::Controller do
|
||||
let(:prometheus_config) { {prometheus_exporter: {enabled: true}} }
|
||||
|
||||
def stub_metrics
|
||||
metrics = %i[@instance_count @rfc_count @rfc_commented_count]
|
||||
%i[increment decrement observe].each do |method|
|
||||
%i[@instance_count @rfc_count @rfc_commented_count].each do |metric|
|
||||
metrics.each do |metric|
|
||||
allow(described_class.instance_variable_get(metric)).to receive(method)
|
||||
end
|
||||
end
|
||||
|
@ -11,7 +11,7 @@ describe Assessor do
|
||||
|
||||
context 'when an error occurs' do
|
||||
before do
|
||||
expect_any_instance_of(TestingFrameworkAdapter).to receive(:test_outcome).and_raise
|
||||
allow_any_instance_of(TestingFrameworkAdapter).to receive(:test_outcome).and_raise
|
||||
end
|
||||
|
||||
it 'catches the error' do
|
||||
|
@ -4,7 +4,7 @@ require 'rails_helper'
|
||||
|
||||
describe CodeOcean::Config do
|
||||
describe '#read' do
|
||||
let(:content) { {foo: 'bar'} }
|
||||
let(:content) { {'foo' => 'bar'} }
|
||||
let(:filename) { :foo }
|
||||
|
||||
context 'with a .yml file' do
|
||||
|
@ -3,8 +3,6 @@
|
||||
require 'rails_helper'
|
||||
require 'seeds_helper'
|
||||
|
||||
# rubocop:disable RSpec/MultipleMemoizedHelpers
|
||||
|
||||
WORKSPACE_PATH = Rails.root.join('tmp', 'files', Rails.env, 'code_ocean_test')
|
||||
|
||||
describe DockerClient, docker: true do
|
||||
@ -26,14 +24,14 @@ describe DockerClient, docker: true do
|
||||
describe '.check_availability!' do
|
||||
context 'when a socket error occurs' do
|
||||
it 'raises an error' do
|
||||
expect(Docker).to receive(:version).and_raise(Excon::Errors::SocketError.new(StandardError.new))
|
||||
allow(Docker).to receive(:version).and_raise(Excon::Errors::SocketError.new(StandardError.new))
|
||||
expect { described_class.check_availability! }.to raise_error(DockerClient::Error)
|
||||
end
|
||||
end
|
||||
|
||||
context 'when a timeout occurs' do
|
||||
it 'raises an error' do
|
||||
expect(Docker).to receive(:version).and_raise(Timeout::Error)
|
||||
allow(Docker).to receive(:version).and_raise(Timeout::Error)
|
||||
expect { described_class.check_availability! }.to raise_error(DockerClient::Error)
|
||||
end
|
||||
end
|
||||
@ -115,7 +113,7 @@ describe DockerClient, docker: true do
|
||||
|
||||
context 'when retries are left' do
|
||||
before do
|
||||
expect(described_class).to receive(:mapped_directories).and_raise(error).and_call_original
|
||||
allow(described_class).to receive(:mapped_directories).and_raise(error).and_call_original
|
||||
end
|
||||
|
||||
it 'retries to create a container' do
|
||||
@ -125,7 +123,7 @@ describe DockerClient, docker: true do
|
||||
|
||||
context 'when no retries are left' do
|
||||
before do
|
||||
expect(described_class).to receive(:mapped_directories).exactly(DockerClient::RETRY_COUNT + 1).times.and_raise(error)
|
||||
allow(described_class).to receive(:mapped_directories).exactly(DockerClient::RETRY_COUNT + 1).times.and_raise(error)
|
||||
end
|
||||
|
||||
it 'raises the error' do
|
||||
@ -140,7 +138,7 @@ describe DockerClient, docker: true do
|
||||
let(:container) { double }
|
||||
|
||||
before do
|
||||
expect(container).to receive(:binds).at_least(:once).and_return(["#{workspace_path}:#{DockerClient::CONTAINER_WORKSPACE_PATH}"])
|
||||
allow(container).to receive(:binds).at_least(:once).and_return(["#{workspace_path}:#{DockerClient::CONTAINER_WORKSPACE_PATH}"])
|
||||
end
|
||||
|
||||
after { docker_client.send(:create_workspace_files, container, submission) }
|
||||
@ -183,11 +181,11 @@ describe DockerClient, docker: true do
|
||||
after { described_class.destroy_container(container) }
|
||||
|
||||
it 'kills running processes' do
|
||||
expect(container).to receive(:kill).and_return(container)
|
||||
allow(container).to receive(:kill).and_return(container)
|
||||
end
|
||||
|
||||
it 'releases allocated ports' do
|
||||
expect(container).to receive(:port_bindings).at_least(:once).and_return(foo: [{'HostPort' => '42'}])
|
||||
allow(container).to receive(:port_bindings).at_least(:once).and_return(foo: [{'HostPort' => '42'}])
|
||||
expect(PortPool).to receive(:release)
|
||||
end
|
||||
|
||||
@ -211,7 +209,7 @@ describe DockerClient, docker: true do
|
||||
end
|
||||
|
||||
it 'sends the command' do
|
||||
expect(docker_client).to receive(:send_command).with(command, kind_of(Docker::Container)).and_return({})
|
||||
allow(docker_client).to receive(:send_command).with(command, kind_of(Docker::Container)).and_return({})
|
||||
execute_arbitrary_command
|
||||
end
|
||||
|
||||
@ -222,7 +220,7 @@ describe DockerClient, docker: true do
|
||||
let(:result) { {status: 'ok', stdout: 42} }
|
||||
|
||||
before do
|
||||
expect(docker_client).to receive(:send_command).and_raise(error).and_return(result)
|
||||
allow(docker_client).to receive(:send_command).and_raise(error).and_return(result)
|
||||
end
|
||||
|
||||
it 'retries to execute the command' do
|
||||
@ -232,13 +230,13 @@ describe DockerClient, docker: true do
|
||||
|
||||
context 'when no retries are left' do
|
||||
before do
|
||||
expect(docker_client).to receive(:send_command).exactly(DockerClient::RETRY_COUNT + 1).times.and_raise(error)
|
||||
allow(docker_client).to receive(:send_command).exactly(DockerClient::RETRY_COUNT + 1).times.and_raise(error)
|
||||
end
|
||||
|
||||
it 'raises the error' do
|
||||
pending('retries are disabled')
|
||||
# !TODO Retries is disabled
|
||||
# expect { execute_arbitrary_command }.to raise_error(error)
|
||||
# TODO: Retries is disabled
|
||||
expect { execute_arbitrary_command }.to raise_error(error)
|
||||
end
|
||||
end
|
||||
end
|
||||
@ -250,12 +248,10 @@ describe DockerClient, docker: true do
|
||||
after { docker_client.send(:execute_run_command, submission, filename) }
|
||||
|
||||
it 'takes a container from the pool' do
|
||||
pending('todo in the future')
|
||||
expect(DockerContainerPool).to receive(:get_container).with(submission.execution_environment).and_call_original
|
||||
end
|
||||
|
||||
it 'creates the workspace files' do
|
||||
pending('todo in the future')
|
||||
expect(docker_client).to receive(:create_workspace_files)
|
||||
end
|
||||
|
||||
@ -281,7 +277,7 @@ describe DockerClient, docker: true do
|
||||
|
||||
it 'executes the test command' do
|
||||
expect(submission.execution_environment).to receive(:test_command).and_call_original
|
||||
expect(docker_client).to receive(:send_command).with(kind_of(String), kind_of(Docker::Container)).and_return({})
|
||||
allow(docker_client).to receive(:send_command).with(kind_of(String), kind_of(Docker::Container)).and_return({})
|
||||
end
|
||||
end
|
||||
|
||||
@ -305,7 +301,7 @@ describe DockerClient, docker: true do
|
||||
end
|
||||
|
||||
context 'with incomplete configuration' do
|
||||
before { expect(described_class).to receive(:config).at_least(:once).and_return({}) }
|
||||
before { allow(described_class).to receive(:config).at_least(:once).and_return({}) }
|
||||
|
||||
it 'raises an error' do
|
||||
expect { described_class.initialize_environment }.to raise_error(DockerClient::Error)
|
||||
@ -357,7 +353,7 @@ describe DockerClient, docker: true do
|
||||
end
|
||||
|
||||
describe '#send_command' do
|
||||
let(:block) { proc {} }
|
||||
let(:block) { proc { nil } }
|
||||
let(:container) { described_class.create_container(execution_environment) }
|
||||
let(:send_command) { docker_client.send(:send_command, command, container, &block) }
|
||||
|
||||
@ -379,8 +375,13 @@ describe DockerClient, docker: true do
|
||||
|
||||
context 'when a timeout occurs' do
|
||||
before do
|
||||
expect(container).to receive(:exec).once.and_raise(Timeout::Error)
|
||||
expect(container).to receive(:exec).twice.and_return([[], []])
|
||||
exec_called = 0
|
||||
allow(container).to receive(:exec) do
|
||||
exec_called += 1
|
||||
raise Timeout::Error if exec_called == 1
|
||||
|
||||
[[], []]
|
||||
end
|
||||
end
|
||||
|
||||
it 'destroys the container asynchronously' do
|
||||
@ -410,5 +411,3 @@ describe DockerClient, docker: true do
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
# rubocop:enable RSpec/MultipleMemoizedHelpers
|
||||
|
@ -11,7 +11,7 @@ describe DockerContainerMixin do
|
||||
end
|
||||
|
||||
it 'returns the correct information' do
|
||||
expect(CONTAINER).to receive(:json).and_return('HostConfig' => {'Binds' => binds})
|
||||
allow(CONTAINER).to receive(:json).and_return('HostConfig' => {'Binds' => binds})
|
||||
expect(CONTAINER.binds).to eq(binds)
|
||||
end
|
||||
end
|
||||
@ -25,7 +25,7 @@ describe DockerContainerMixin do
|
||||
end
|
||||
|
||||
it 'returns the correct information' do
|
||||
expect(CONTAINER).to receive(:json).and_return('HostConfig' => {'PortBindings' => port_bindings})
|
||||
allow(CONTAINER).to receive(:json).and_return('HostConfig' => {'PortBindings' => port_bindings})
|
||||
expect(CONTAINER.port_bindings).to eq(port => port)
|
||||
end
|
||||
end
|
||||
|
@ -8,8 +8,8 @@ describe FileTree do
|
||||
describe '#file_icon' do
|
||||
let(:file_icon) { file_tree.send(:file_icon, file) }
|
||||
|
||||
context 'for a media file' do
|
||||
context 'for an audio file' do
|
||||
context 'with a media file' do
|
||||
context 'with an audio file' do
|
||||
let(:file) { FactoryBot.build(:file, file_type: FactoryBot.build(:dot_mp3)) }
|
||||
|
||||
it 'is an audio file icon' do
|
||||
@ -17,7 +17,7 @@ describe FileTree do
|
||||
end
|
||||
end
|
||||
|
||||
context 'for an image file' do
|
||||
context 'with an image file' do
|
||||
let(:file) { FactoryBot.build(:file, file_type: FactoryBot.build(:dot_jpg)) }
|
||||
|
||||
it 'is an image file icon' do
|
||||
@ -25,7 +25,7 @@ describe FileTree do
|
||||
end
|
||||
end
|
||||
|
||||
context 'for a video file' do
|
||||
context 'with a video file' do
|
||||
let(:file) { FactoryBot.build(:file, file_type: FactoryBot.build(:dot_mp4)) }
|
||||
|
||||
it 'is a video file icon' do
|
||||
@ -34,8 +34,8 @@ describe FileTree do
|
||||
end
|
||||
end
|
||||
|
||||
context 'for other files' do
|
||||
context 'for a read-only file' do
|
||||
context 'with other files' do
|
||||
context 'with a read-only file' do
|
||||
let(:file) { FactoryBot.build(:file, read_only: true) }
|
||||
|
||||
it 'is a lock icon' do
|
||||
@ -43,7 +43,7 @@ describe FileTree do
|
||||
end
|
||||
end
|
||||
|
||||
context 'for an executable file' do
|
||||
context 'with an executable file' do
|
||||
let(:file) { FactoryBot.build(:file, file_type: FactoryBot.build(:dot_py)) }
|
||||
|
||||
it 'is a code file icon' do
|
||||
@ -51,7 +51,7 @@ describe FileTree do
|
||||
end
|
||||
end
|
||||
|
||||
context 'for a renderable file' do
|
||||
context 'with a renderable file' do
|
||||
let(:file) { FactoryBot.build(:file, file_type: FactoryBot.build(:dot_svg)) }
|
||||
|
||||
it 'is a text file icon' do
|
||||
@ -59,7 +59,7 @@ describe FileTree do
|
||||
end
|
||||
end
|
||||
|
||||
context 'for all other files' do
|
||||
context 'with all other files' do
|
||||
let(:file) { FactoryBot.build(:file, file_type: FactoryBot.build(:dot_md)) }
|
||||
|
||||
it 'is a generic file icon' do
|
||||
@ -100,7 +100,7 @@ describe FileTree do
|
||||
let!(:leaf) { root.add(Tree::TreeNode.new('', file)) }
|
||||
let(:root) { Tree::TreeNode.new('', file) }
|
||||
|
||||
context 'for a leaf node' do
|
||||
context 'with a leaf node' do
|
||||
let(:node) { leaf }
|
||||
|
||||
it 'produces the required attributes' do
|
||||
@ -116,7 +116,7 @@ describe FileTree do
|
||||
end
|
||||
end
|
||||
|
||||
context 'for a non-leaf node' do
|
||||
context 'with a non-leaf node' do
|
||||
let(:node) { root }
|
||||
|
||||
it "traverses the node's children" do
|
||||
@ -144,7 +144,7 @@ describe FileTree do
|
||||
let(:node_icon) { file_tree.send(:node_icon, node) }
|
||||
let(:root) { Tree::TreeNode.new('') }
|
||||
|
||||
context 'for the root node' do
|
||||
context 'with the root node' do
|
||||
let(:node) { root }
|
||||
|
||||
it 'is a folder icon' do
|
||||
@ -152,7 +152,7 @@ describe FileTree do
|
||||
end
|
||||
end
|
||||
|
||||
context 'for leaf nodes' do
|
||||
context 'with leaf nodes' do
|
||||
let(:node) { root.add(Tree::TreeNode.new('')) }
|
||||
|
||||
it 'is a file icon' do
|
||||
@ -161,7 +161,7 @@ describe FileTree do
|
||||
end
|
||||
end
|
||||
|
||||
context 'for intermediary nodes' do
|
||||
context 'with intermediary nodes' do
|
||||
let(:node) do
|
||||
root.add(Tree::TreeNode.new('').tap {|node| node.add(Tree::TreeNode.new('')) })
|
||||
end
|
||||
|
@ -27,7 +27,7 @@ describe TestingFrameworkAdapterGenerator do
|
||||
|
||||
it 'builds a correct class skeleton' do
|
||||
file_content = File.new(path, 'r').read
|
||||
expect(file_content).to start_with("class #{name}Adapter < TestingFrameworkAdapter")
|
||||
expect(file_content&.strip).to start_with("class #{name}Adapter < TestingFrameworkAdapter")
|
||||
end
|
||||
|
||||
it 'generates a corresponding test' do
|
||||
|
@ -5,6 +5,10 @@ require 'rails_helper'
|
||||
describe NonceStore do
|
||||
let(:nonce) { SecureRandom.hex }
|
||||
|
||||
before do
|
||||
stub_const('Lti::MAXIMUM_SESSION_AGE', 1)
|
||||
end
|
||||
|
||||
describe '.add' do
|
||||
it 'stores a nonce in the cache' do
|
||||
expect(Rails.cache).to receive(:write)
|
||||
@ -28,8 +32,6 @@ describe NonceStore do
|
||||
end
|
||||
|
||||
it 'returns false for expired nonces' do
|
||||
Lti.send(:remove_const, 'MAXIMUM_SESSION_AGE')
|
||||
Lti::MAXIMUM_SESSION_AGE = 1
|
||||
described_class.add(nonce)
|
||||
expect(described_class.has?(nonce)).to be true
|
||||
sleep(Lti::MAXIMUM_SESSION_AGE)
|
||||
|
@ -42,7 +42,7 @@ describe TestingFrameworkAdapter do
|
||||
|
||||
describe '#test_outcome' do
|
||||
it 'calls the framework-specific implementation' do
|
||||
expect(adapter).to receive(:parse_output).and_return(count: count, failed: failed, passed: passed)
|
||||
allow(adapter).to receive(:parse_output).and_return(count: count, failed: failed, passed: passed)
|
||||
adapter.test_outcome('')
|
||||
end
|
||||
end
|
||||
|
@ -25,7 +25,7 @@ describe CodeOcean::File do
|
||||
expect(file.errors[:read_only]).to be_blank
|
||||
end
|
||||
|
||||
context 'as a teacher-defined test' do
|
||||
context 'with a teacher-defined test' do
|
||||
before { file.update(role: 'teacher_defined_test') }
|
||||
|
||||
it 'validates the presence of a feedback message' do
|
||||
|
@ -6,7 +6,7 @@ describe ExecutionEnvironment do
|
||||
let(:execution_environment) { described_class.create.tap {|execution_environment| execution_environment.update(network_enabled: nil) } }
|
||||
|
||||
it 'validates that the Docker image works', docker: true do
|
||||
expect(execution_environment).to receive(:validate_docker_image?).and_return(true)
|
||||
allow(execution_environment).to receive(:validate_docker_image?).and_return(true)
|
||||
expect(execution_environment).to receive(:working_docker_image?)
|
||||
execution_environment.update(docker_image: FactoryBot.attributes_for(:ruby)[:docker_image])
|
||||
end
|
||||
@ -124,22 +124,22 @@ describe ExecutionEnvironment do
|
||||
describe '#working_docker_image?', docker: true do
|
||||
let(:working_docker_image?) { execution_environment.send(:working_docker_image?) }
|
||||
|
||||
before { expect(DockerClient).to receive(:find_image_by_tag).and_return(Object.new) }
|
||||
before { allow(DockerClient).to receive(:find_image_by_tag).and_return(Object.new) }
|
||||
|
||||
it 'instantiates a Docker client' do
|
||||
expect(DockerClient).to receive(:new).with(execution_environment: execution_environment).and_call_original
|
||||
expect_any_instance_of(DockerClient).to receive(:execute_arbitrary_command).and_return({})
|
||||
allow_any_instance_of(DockerClient).to receive(:execute_arbitrary_command).and_return({})
|
||||
working_docker_image?
|
||||
end
|
||||
|
||||
it 'executes the validation command' do
|
||||
expect_any_instance_of(DockerClient).to receive(:execute_arbitrary_command).with(ExecutionEnvironment::VALIDATION_COMMAND).and_return({})
|
||||
allow_any_instance_of(DockerClient).to receive(:execute_arbitrary_command).with(ExecutionEnvironment::VALIDATION_COMMAND).and_return({})
|
||||
working_docker_image?
|
||||
end
|
||||
|
||||
context 'when the command produces an error' do
|
||||
it 'adds an error' do
|
||||
expect_any_instance_of(DockerClient).to receive(:execute_arbitrary_command).and_return(stderr: 'command not found')
|
||||
allow_any_instance_of(DockerClient).to receive(:execute_arbitrary_command).and_return(stderr: 'command not found')
|
||||
working_docker_image?
|
||||
expect(execution_environment.errors[:docker_image]).to be_present
|
||||
end
|
||||
@ -147,7 +147,7 @@ describe ExecutionEnvironment do
|
||||
|
||||
context 'when the Docker client produces an error' do
|
||||
it 'adds an error' do
|
||||
expect_any_instance_of(DockerClient).to receive(:execute_arbitrary_command).and_raise(DockerClient::Error)
|
||||
allow_any_instance_of(DockerClient).to receive(:execute_arbitrary_command).and_raise(DockerClient::Error)
|
||||
working_docker_image?
|
||||
expect(execution_environment.errors[:docker_image]).to be_present
|
||||
end
|
||||
|
@ -118,9 +118,7 @@ describe Exercise do
|
||||
end
|
||||
|
||||
it 'duplicates all associated files' do
|
||||
exercise.files.each do |file|
|
||||
expect(file).to receive(:dup).and_call_original
|
||||
end
|
||||
expect(exercise.files).to all(receive(:dup).and_call_original)
|
||||
end
|
||||
|
||||
it 'returns the duplicated exercise' do
|
||||
|
@ -34,7 +34,7 @@ describe Submission do
|
||||
before { submission.score = submission.exercise.maximum_score / 2 }
|
||||
|
||||
it 'returns the score as a value between 0 and 1' do
|
||||
expect(0..1).to include(submission.normalized_score)
|
||||
expect(submission.normalized_score).to be_between(0, 1)
|
||||
end
|
||||
end
|
||||
|
||||
@ -54,7 +54,7 @@ describe Submission do
|
||||
before { submission.score = submission.exercise.maximum_score / 2 }
|
||||
|
||||
it 'returns the score expressed as a percentage' do
|
||||
expect(0..100).to include(submission.percentage)
|
||||
expect(submission.percentage).to be_between(0, 100)
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -3,19 +3,19 @@
|
||||
require 'rails_helper'
|
||||
|
||||
describe Admin::DashboardPolicy do
|
||||
subject { described_class }
|
||||
subject(:policy) { described_class }
|
||||
|
||||
permissions :show? do
|
||||
it 'grants access to admins' do
|
||||
expect(subject).to permit(FactoryBot.build(:admin), :dashboard)
|
||||
expect(policy).to permit(FactoryBot.build(:admin), :dashboard)
|
||||
end
|
||||
|
||||
it 'does not grant access to teachers' do
|
||||
expect(subject).not_to permit(FactoryBot.build(:teacher), :dashboard)
|
||||
expect(policy).not_to permit(FactoryBot.build(:teacher), :dashboard)
|
||||
end
|
||||
|
||||
it 'does not grant access to external users' do
|
||||
expect(subject).not_to permit(FactoryBot.build(:external_user), :dashboard)
|
||||
expect(policy).not_to permit(FactoryBot.build(:external_user), :dashboard)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
@ -3,86 +3,86 @@
|
||||
require 'rails_helper'
|
||||
|
||||
describe CodeOcean::FilePolicy do
|
||||
subject { described_class }
|
||||
subject(:policy) { described_class }
|
||||
|
||||
let(:exercise) { FactoryBot.create(:fibonacci) }
|
||||
let(:submission) { FactoryBot.create(:submission) }
|
||||
|
||||
permissions :create? do
|
||||
context 'as part of an exercise' do
|
||||
context 'when being part of an exercise' do
|
||||
let(:file) { exercise.files.first }
|
||||
|
||||
it 'grants access to admins' do
|
||||
expect(subject).to permit(FactoryBot.build(:admin), file)
|
||||
expect(policy).to permit(FactoryBot.build(:admin), file)
|
||||
end
|
||||
|
||||
it 'grants access to authors' do
|
||||
expect(subject).to permit(exercise.author, file)
|
||||
expect(policy).to permit(exercise.author, file)
|
||||
end
|
||||
|
||||
it 'does not grant access to all other users' do
|
||||
%i[external_user teacher].each do |factory_name|
|
||||
expect(subject).not_to permit(FactoryBot.build(factory_name), file)
|
||||
expect(policy).not_to permit(FactoryBot.build(factory_name), file)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
context 'as part of a submission' do
|
||||
context 'when being part of a submission' do
|
||||
let(:file) { submission.files.first }
|
||||
|
||||
context 'where file creation is allowed' do
|
||||
context 'when file creation is allowed' do
|
||||
before do
|
||||
submission.exercise.update(allow_file_creation: true)
|
||||
end
|
||||
|
||||
it 'grants access to authors' do
|
||||
expect(subject).to permit(submission.author, file)
|
||||
expect(policy).to permit(submission.author, file)
|
||||
end
|
||||
end
|
||||
|
||||
context 'where file creation is not allowed' do
|
||||
context 'when file creation is not allowed' do
|
||||
before do
|
||||
submission.exercise.update(allow_file_creation: false)
|
||||
end
|
||||
|
||||
it 'grants access to authors' do
|
||||
expect(subject).not_to permit(submission.author, file)
|
||||
expect(policy).not_to permit(submission.author, file)
|
||||
end
|
||||
end
|
||||
|
||||
it 'does not grant access to all other users' do
|
||||
%i[admin external_user teacher].each do |factory_name|
|
||||
expect(subject).not_to permit(FactoryBot.build(factory_name), file)
|
||||
expect(policy).not_to permit(FactoryBot.build(factory_name), file)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
permissions :destroy? do
|
||||
context 'as part of an exercise' do
|
||||
context 'when being part of an exercise' do
|
||||
let(:file) { exercise.files.first }
|
||||
|
||||
it 'grants access to admins' do
|
||||
expect(subject).to permit(FactoryBot.build(:admin), file)
|
||||
expect(policy).to permit(FactoryBot.build(:admin), file)
|
||||
end
|
||||
|
||||
it 'grants access to authors' do
|
||||
expect(subject).to permit(exercise.author, file)
|
||||
expect(policy).to permit(exercise.author, file)
|
||||
end
|
||||
|
||||
it 'does not grant access to all other users' do
|
||||
%i[external_user teacher].each do |factory_name|
|
||||
expect(subject).not_to permit(FactoryBot.build(factory_name), file)
|
||||
expect(policy).not_to permit(FactoryBot.build(factory_name), file)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
context 'as part of a submission' do
|
||||
context 'when being part of a submission' do
|
||||
let(:file) { submission.files.first }
|
||||
|
||||
it 'does not grant access to anyone' do
|
||||
%i[admin external_user teacher].each do |factory_name|
|
||||
expect(subject).not_to permit(FactoryBot.build(factory_name), file)
|
||||
expect(policy).not_to permit(FactoryBot.build(factory_name), file)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
@ -3,14 +3,14 @@
|
||||
require 'rails_helper'
|
||||
|
||||
describe ConsumerPolicy do
|
||||
subject { described_class }
|
||||
subject(:policy) { described_class }
|
||||
|
||||
%i[create? destroy? edit? index? new? show? update?].each do |action|
|
||||
permissions(action) do
|
||||
it 'grants access to admins only' do
|
||||
expect(subject).to permit(FactoryBot.build(:admin), Consumer.new)
|
||||
expect(policy).to permit(FactoryBot.build(:admin), Consumer.new)
|
||||
%i[external_user teacher].each do |factory_name|
|
||||
expect(subject).not_to permit(FactoryBot.build(factory_name), Consumer.new)
|
||||
expect(policy).not_to permit(FactoryBot.build(factory_name), Consumer.new)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
@ -3,22 +3,22 @@
|
||||
require 'rails_helper'
|
||||
|
||||
describe ExecutionEnvironmentPolicy do
|
||||
subject { described_class }
|
||||
subject(:policy) { described_class }
|
||||
|
||||
let(:execution_environment) { FactoryBot.build(:ruby) }
|
||||
|
||||
[:index?].each do |action|
|
||||
permissions(action) do
|
||||
it 'grants access to admins' do
|
||||
expect(subject).to permit(FactoryBot.build(:admin), execution_environment)
|
||||
expect(policy).to permit(FactoryBot.build(:admin), execution_environment)
|
||||
end
|
||||
|
||||
it 'grants access to teachers' do
|
||||
expect(subject).to permit(FactoryBot.build(:teacher), execution_environment)
|
||||
expect(policy).to permit(FactoryBot.build(:teacher), execution_environment)
|
||||
end
|
||||
|
||||
it 'does not grant access to external users' do
|
||||
expect(subject).not_to permit(FactoryBot.build(:external_user), execution_environment)
|
||||
expect(policy).not_to permit(FactoryBot.build(:external_user), execution_environment)
|
||||
end
|
||||
end
|
||||
end
|
||||
@ -26,16 +26,16 @@ describe ExecutionEnvironmentPolicy do
|
||||
%i[execute_command? shell? statistics? show?].each do |action|
|
||||
permissions(action) do
|
||||
it 'grants access to admins' do
|
||||
expect(subject).to permit(FactoryBot.build(:admin), execution_environment)
|
||||
expect(policy).to permit(FactoryBot.build(:admin), execution_environment)
|
||||
end
|
||||
|
||||
it 'grants access to authors' do
|
||||
expect(subject).to permit(execution_environment.author, execution_environment)
|
||||
expect(policy).to permit(execution_environment.author, execution_environment)
|
||||
end
|
||||
|
||||
it 'does not grant access to all other users' do
|
||||
%i[external_user teacher].each do |factory_name|
|
||||
expect(subject).not_to permit(FactoryBot.build(factory_name), execution_environment)
|
||||
expect(policy).not_to permit(FactoryBot.build(factory_name), execution_environment)
|
||||
end
|
||||
end
|
||||
end
|
||||
@ -44,16 +44,16 @@ describe ExecutionEnvironmentPolicy do
|
||||
%i[destroy? edit? update? new? create?].each do |action|
|
||||
permissions(action) do
|
||||
it 'grants access to admins' do
|
||||
expect(subject).to permit(FactoryBot.build(:admin), execution_environment)
|
||||
expect(policy).to permit(FactoryBot.build(:admin), execution_environment)
|
||||
end
|
||||
|
||||
it 'does not grant access to authors' do
|
||||
expect(subject).not_to permit(execution_environment.author, execution_environment)
|
||||
expect(policy).not_to permit(execution_environment.author, execution_environment)
|
||||
end
|
||||
|
||||
it 'does not grant access to all other users' do
|
||||
%i[external_user teacher].each do |factory_name|
|
||||
expect(subject).not_to permit(FactoryBot.build(factory_name), execution_environment)
|
||||
expect(policy).not_to permit(FactoryBot.build(factory_name), execution_environment)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
@ -3,31 +3,31 @@
|
||||
require 'rails_helper'
|
||||
|
||||
describe ExercisePolicy do
|
||||
subject { described_class }
|
||||
subject(:policy) { described_class }
|
||||
|
||||
let(:exercise) { FactoryBot.build(:dummy, public: true) }
|
||||
|
||||
permissions :batch_update? do
|
||||
it 'grants access to admins only' do
|
||||
expect(subject).to permit(FactoryBot.build(:admin), exercise)
|
||||
expect(policy).to permit(FactoryBot.build(:admin), exercise)
|
||||
%i[external_user teacher].each do |factory_name|
|
||||
expect(subject).not_to permit(FactoryBot.build(factory_name), exercise)
|
||||
expect(policy).not_to permit(FactoryBot.build(factory_name), exercise)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
%i[create? index? new? statistics? feedback? get_rfcs_for_exercise?].each do |action|
|
||||
%i[create? index? new? statistics? feedback? rfcs_for_exercise?].each do |action|
|
||||
permissions(action) do
|
||||
it 'grants access to admins' do
|
||||
expect(subject).to permit(FactoryBot.build(:admin), exercise)
|
||||
expect(policy).to permit(FactoryBot.build(:admin), exercise)
|
||||
end
|
||||
|
||||
it 'grants access to teachers' do
|
||||
expect(subject).to permit(FactoryBot.build(:teacher), exercise)
|
||||
expect(policy).to permit(FactoryBot.build(:teacher), exercise)
|
||||
end
|
||||
|
||||
it 'does not grant access to external users' do
|
||||
expect(subject).not_to permit(FactoryBot.build(:external_user), exercise)
|
||||
expect(policy).not_to permit(FactoryBot.build(:external_user), exercise)
|
||||
end
|
||||
end
|
||||
end
|
||||
@ -35,16 +35,16 @@ describe ExercisePolicy do
|
||||
%i[clone? destroy? edit? update?].each do |action|
|
||||
permissions(action) do
|
||||
it 'grants access to admins' do
|
||||
expect(subject).to permit(FactoryBot.build(:admin), exercise)
|
||||
expect(policy).to permit(FactoryBot.build(:admin), exercise)
|
||||
end
|
||||
|
||||
it 'grants access to authors' do
|
||||
expect(subject).to permit(exercise.author, exercise)
|
||||
expect(policy).to permit(exercise.author, exercise)
|
||||
end
|
||||
|
||||
it 'does not grant access to all other users' do
|
||||
%i[external_user teacher].each do |factory_name|
|
||||
expect(subject).not_to permit(FactoryBot.build(factory_name), exercise)
|
||||
expect(policy).not_to permit(FactoryBot.build(factory_name), exercise)
|
||||
end
|
||||
end
|
||||
end
|
||||
@ -56,14 +56,14 @@ describe ExercisePolicy do
|
||||
let(:user) { exercise.author }
|
||||
|
||||
it 'does not grant access' do
|
||||
expect(subject).not_to permit(user, exercise)
|
||||
expect(policy).not_to permit(user, exercise)
|
||||
end
|
||||
|
||||
context 'when user has codeharbor_link' do
|
||||
before { user.codeharbor_link = FactoryBot.build(:codeharbor_link) }
|
||||
|
||||
it 'grants access' do
|
||||
expect(subject).to permit(user, exercise)
|
||||
expect(policy).to permit(user, exercise)
|
||||
end
|
||||
end
|
||||
end
|
||||
@ -72,14 +72,14 @@ describe ExercisePolicy do
|
||||
let(:user) { FactoryBot.build(:admin) }
|
||||
|
||||
it 'does not grant access' do
|
||||
expect(subject).not_to permit(user, exercise)
|
||||
expect(policy).not_to permit(user, exercise)
|
||||
end
|
||||
|
||||
context 'when user has codeharbor_link' do
|
||||
before { user.codeharbor_link = FactoryBot.build(:codeharbor_link) }
|
||||
|
||||
it 'grants access' do
|
||||
expect(subject).to permit(user, exercise)
|
||||
expect(policy).to permit(user, exercise)
|
||||
end
|
||||
end
|
||||
end
|
||||
@ -89,14 +89,14 @@ describe ExercisePolicy do
|
||||
let(:user) { FactoryBot.build(factory_name) }
|
||||
|
||||
it 'does not grant access' do
|
||||
expect(subject).not_to permit(user, exercise)
|
||||
expect(policy).not_to permit(user, exercise)
|
||||
end
|
||||
|
||||
context 'when user has codeharbor_link' do
|
||||
before { user.codeharbor_link = FactoryBot.build(:codeharbor_link) }
|
||||
|
||||
it 'does not grant access' do
|
||||
expect(subject).not_to permit(user, exercise)
|
||||
expect(policy).not_to permit(user, exercise)
|
||||
end
|
||||
end
|
||||
end
|
||||
@ -107,7 +107,7 @@ describe ExercisePolicy do
|
||||
[:show?].each do |action|
|
||||
permissions(action) do
|
||||
it 'not grants access to external users' do
|
||||
expect(subject).not_to permit(FactoryBot.build(:external_user), exercise)
|
||||
expect(policy).not_to permit(FactoryBot.build(:external_user), exercise)
|
||||
end
|
||||
end
|
||||
end
|
||||
@ -116,7 +116,7 @@ describe ExercisePolicy do
|
||||
permissions(action) do
|
||||
it 'grants access to anyone' do
|
||||
%i[admin external_user teacher].each do |factory_name|
|
||||
expect(subject).to permit(FactoryBot.build(factory_name), Exercise.new)
|
||||
expect(policy).to permit(FactoryBot.build(factory_name), Exercise.new)
|
||||
end
|
||||
end
|
||||
end
|
||||
@ -124,47 +124,47 @@ describe ExercisePolicy do
|
||||
|
||||
describe ExercisePolicy::Scope do
|
||||
describe '#resolve' do
|
||||
before(:all) do
|
||||
@admin = FactoryBot.create(:admin)
|
||||
@external_user = FactoryBot.create(:external_user)
|
||||
@teacher = FactoryBot.create(:teacher)
|
||||
let(:admin) { FactoryBot.create(:admin) }
|
||||
let(:external_user) { FactoryBot.create(:external_user) }
|
||||
let(:teacher) { FactoryBot.create(:teacher) }
|
||||
|
||||
[@admin, @teacher].each do |user|
|
||||
before do
|
||||
[admin, teacher].each do |user|
|
||||
[true, false].each do |public|
|
||||
FactoryBot.create(:dummy, public: public, user_id: user.id, user_type: InternalUser.name)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
context 'for admins' do
|
||||
let(:scope) { Pundit.policy_scope!(@admin, Exercise) }
|
||||
context 'when being an admin' do
|
||||
let(:scope) { Pundit.policy_scope!(admin, Exercise) }
|
||||
|
||||
it 'returns all exercises' do
|
||||
expect(scope.map(&:id)).to include(*Exercise.all.map(&:id))
|
||||
end
|
||||
end
|
||||
|
||||
context 'for external users' do
|
||||
let(:scope) { Pundit.policy_scope!(@external_user, Exercise) }
|
||||
context 'when being an external users' do
|
||||
let(:scope) { Pundit.policy_scope!(external_user, Exercise) }
|
||||
|
||||
it 'returns nothing' do
|
||||
expect(scope.count).to be 0
|
||||
end
|
||||
end
|
||||
|
||||
context 'for teachers' do
|
||||
let(:scope) { Pundit.policy_scope!(@teacher, Exercise) }
|
||||
context 'when being a teacher' do
|
||||
let(:scope) { Pundit.policy_scope!(teacher, Exercise) }
|
||||
|
||||
it 'includes all public exercises' do
|
||||
expect(scope.map(&:id)).to include(*Exercise.where(public: true).map(&:id))
|
||||
end
|
||||
|
||||
it 'includes all authored non-public exercises' do
|
||||
expect(scope.map(&:id)).to include(*Exercise.where(public: false, user_id: @teacher.id).map(&:id))
|
||||
expect(scope.map(&:id)).to include(*Exercise.where(public: false, user_id: teacher.id).map(&:id))
|
||||
end
|
||||
|
||||
it "does not include other authors' non-public exercises" do
|
||||
expect(scope.map(&:id)).not_to include(*Exercise.where(public: false).where("user_id <> #{@teacher.id}").map(&:id))
|
||||
expect(scope.map(&:id)).not_to include(*Exercise.where(public: false).where("user_id <> #{teacher.id}").map(&:id))
|
||||
end
|
||||
end
|
||||
end
|
||||
|
@ -3,14 +3,14 @@
|
||||
require 'rails_helper'
|
||||
|
||||
describe ExternalUserPolicy do
|
||||
subject { described_class }
|
||||
subject(:policy) { described_class }
|
||||
|
||||
%i[create? destroy? edit? new? show? update?].each do |action|
|
||||
permissions(action) do
|
||||
it 'grants access to admins only' do
|
||||
expect(subject).to permit(FactoryBot.build(:admin), ExternalUser.new)
|
||||
expect(policy).to permit(FactoryBot.build(:admin), ExternalUser.new)
|
||||
%i[external_user teacher].each do |factory_name|
|
||||
expect(subject).not_to permit(FactoryBot.build(factory_name), ExternalUser.new)
|
||||
expect(policy).not_to permit(FactoryBot.build(factory_name), ExternalUser.new)
|
||||
end
|
||||
end
|
||||
end
|
||||
@ -19,10 +19,10 @@ describe ExternalUserPolicy do
|
||||
[:index?].each do |action|
|
||||
permissions(action) do
|
||||
it 'grants access to admins and teachers only' do
|
||||
expect(subject).to permit(FactoryBot.build(:admin), ExternalUser.new)
|
||||
expect(subject).to permit(FactoryBot.build(:teacher), ExternalUser.new)
|
||||
expect(policy).to permit(FactoryBot.build(:admin), ExternalUser.new)
|
||||
expect(policy).to permit(FactoryBot.build(:teacher), ExternalUser.new)
|
||||
[:external_user].each do |factory_name|
|
||||
expect(subject).not_to permit(FactoryBot.build(factory_name), ExternalUser.new)
|
||||
expect(policy).not_to permit(FactoryBot.build(factory_name), ExternalUser.new)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
@ -3,23 +3,23 @@
|
||||
require 'rails_helper'
|
||||
|
||||
describe FileTypePolicy do
|
||||
subject { described_class }
|
||||
subject(:policy) { described_class }
|
||||
|
||||
let(:file_type) { FactoryBot.build(:dot_rb) }
|
||||
|
||||
%i[destroy? edit? update? new? create? index? show?].each do |action|
|
||||
permissions(action) do
|
||||
it 'grants access to admins' do
|
||||
expect(subject).to permit(FactoryBot.build(:admin), file_type)
|
||||
expect(policy).to permit(FactoryBot.build(:admin), file_type)
|
||||
end
|
||||
|
||||
it 'grants access to authors' do
|
||||
expect(subject).to permit(file_type.author, file_type)
|
||||
expect(policy).to permit(file_type.author, file_type)
|
||||
end
|
||||
|
||||
it 'does not grant access to all other users' do
|
||||
%i[external_user teacher].each do |factory_name|
|
||||
expect(subject).not_to permit(FactoryBot.build(factory_name), file_type)
|
||||
expect(policy).not_to permit(FactoryBot.build(factory_name), file_type)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
@ -3,14 +3,14 @@
|
||||
require 'rails_helper'
|
||||
|
||||
describe InternalUserPolicy do
|
||||
subject { described_class }
|
||||
subject(:policy) { described_class }
|
||||
|
||||
%i[create? edit? index? new? show? update?].each do |action|
|
||||
permissions(action) do
|
||||
it 'grants access to admins only' do
|
||||
expect(subject).to permit(FactoryBot.build(:admin), InternalUser.new)
|
||||
expect(policy).to permit(FactoryBot.build(:admin), InternalUser.new)
|
||||
%i[external_user teacher].each do |factory_name|
|
||||
expect(subject).not_to permit(FactoryBot.build(factory_name), InternalUser.new)
|
||||
expect(policy).not_to permit(FactoryBot.build(factory_name), InternalUser.new)
|
||||
end
|
||||
end
|
||||
end
|
||||
@ -20,16 +20,16 @@ describe InternalUserPolicy do
|
||||
context 'with an admin user' do
|
||||
it 'grants access to no one' do
|
||||
%i[admin external_user teacher].each do |factory_name|
|
||||
expect(subject).not_to permit(FactoryBot.build(factory_name), FactoryBot.build(:admin))
|
||||
expect(policy).not_to permit(FactoryBot.build(factory_name), FactoryBot.build(:admin))
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
context 'with a non-admin user' do
|
||||
it 'grants access to admins only' do
|
||||
expect(subject).to permit(FactoryBot.build(:admin), InternalUser.new)
|
||||
expect(policy).to permit(FactoryBot.build(:admin), InternalUser.new)
|
||||
%i[external_user teacher].each do |factory_name|
|
||||
expect(subject).not_to permit(FactoryBot.build(factory_name), FactoryBot.build(:teacher))
|
||||
expect(policy).not_to permit(FactoryBot.build(factory_name), FactoryBot.build(:teacher))
|
||||
end
|
||||
end
|
||||
end
|
||||
|
@ -3,12 +3,12 @@
|
||||
require 'rails_helper'
|
||||
|
||||
describe SubmissionPolicy do
|
||||
subject { described_class }
|
||||
subject(:policy) { described_class }
|
||||
|
||||
permissions :create? do
|
||||
it 'grants access to anyone' do
|
||||
%i[admin external_user teacher].each do |factory_name|
|
||||
expect(subject).to permit(FactoryBot.build(factory_name), Submission.new)
|
||||
expect(policy).to permit(FactoryBot.build(factory_name), Submission.new)
|
||||
end
|
||||
end
|
||||
end
|
||||
@ -16,21 +16,21 @@ describe SubmissionPolicy do
|
||||
%i[download_file? render_file? run? score? show? statistics? stop? test?].each do |action|
|
||||
permissions(action) do
|
||||
it 'grants access to admins' do
|
||||
expect(subject).to permit(FactoryBot.build(:admin), Submission.new)
|
||||
expect(policy).to permit(FactoryBot.build(:admin), Submission.new)
|
||||
end
|
||||
|
||||
it 'grants access to authors' do
|
||||
user = FactoryBot.create(:external_user)
|
||||
expect(subject).to permit(user, FactoryBot.build(:submission, exercise: Exercise.new, user_id: user.id, user_type: user.class.name))
|
||||
expect(policy).to permit(user, FactoryBot.build(:submission, exercise: Exercise.new, user_id: user.id, user_type: user.class.name))
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
permissions :index? do
|
||||
it 'grants access to admins only' do
|
||||
expect(subject).to permit(FactoryBot.build(:admin), Submission.new)
|
||||
expect(policy).to permit(FactoryBot.build(:admin), Submission.new)
|
||||
%i[external_user teacher].each do |factory_name|
|
||||
expect(subject).not_to permit(FactoryBot.build(factory_name), Submission.new)
|
||||
expect(policy).not_to permit(FactoryBot.build(factory_name), Submission.new)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
@ -48,7 +48,7 @@ describe ProformaService::ConvertTaskToExercise do
|
||||
let(:files) { [] }
|
||||
let(:tests) { [] }
|
||||
let(:model_solutions) { [] }
|
||||
let(:exercise) {}
|
||||
let(:exercise) { nil }
|
||||
|
||||
it 'creates an exercise with the correct attributes' do
|
||||
expect(convert_to_exercise_service).to have_attributes(
|
||||
@ -83,7 +83,7 @@ describe ProformaService::ConvertTaskToExercise do
|
||||
let(:mimetype) { 'mimetype' }
|
||||
let(:binary) { false }
|
||||
let(:content) { 'content' }
|
||||
let(:path) {}
|
||||
let(:path) { nil }
|
||||
|
||||
it 'creates an exercise with a file that has the correct attributes' do
|
||||
expect(convert_to_exercise_service.files.first).to have_attributes(
|
||||
@ -196,11 +196,11 @@ describe ProformaService::ConvertTaskToExercise do
|
||||
let(:model_solution2) do
|
||||
Proforma::ModelSolution.new(
|
||||
id: 'ms-id-2',
|
||||
files: ms_files_2
|
||||
files: ms_files2
|
||||
)
|
||||
end
|
||||
let(:ms_files_2) { [ms_file_2] }
|
||||
let(:ms_file_2) do
|
||||
let(:ms_files2) { [ms_file2] }
|
||||
let(:ms_file2) do
|
||||
Proforma::TaskFile.new(
|
||||
id: 'ms-file-2',
|
||||
content: 'content',
|
||||
|
@ -33,7 +33,7 @@ describe ProformaService::Import do
|
||||
user: user)
|
||||
end
|
||||
|
||||
let(:uuid) {}
|
||||
let(:uuid) { nil }
|
||||
let(:execution_environment) { FactoryBot.build(:java) }
|
||||
let(:files) { [] }
|
||||
let(:tests) { [] }
|
||||
|
@ -21,7 +21,7 @@ RSpec.configure do |config|
|
||||
has_docker_tests = examples.any? {|example| example.metadata[:docker] }
|
||||
next unless has_docker_tests
|
||||
|
||||
FileUtils.rm_rf(Rails.root.join('tmp', 'files', 'test'))
|
||||
FileUtils.rm_rf(Rails.root.join('tmp/files/test'))
|
||||
`which docker && test -n "$(docker ps --all --quiet)" && docker rm --force $(docker ps --all --quiet)`
|
||||
end
|
||||
end
|
||||
|
@ -3,7 +3,7 @@
|
||||
require 'rails_helper'
|
||||
|
||||
describe FileUploader do
|
||||
let(:file_path) { Rails.root.join('db', 'seeds', 'fibonacci', 'exercise.rb') }
|
||||
let(:file_path) { Rails.root.join('db/seeds/fibonacci/exercise.rb') }
|
||||
let(:uploader) { described_class.new(FactoryBot.create(:file)) }
|
||||
|
||||
before { uploader.store!(File.open(file_path, 'r')) }
|
||||
|
Reference in New Issue
Block a user