Apply manual rubocop fixes

This commit is contained in:
Sebastian Serth
2021-05-14 11:07:11 +02:00
parent 6cbecb5b39
commit da0a682ffb
109 changed files with 431 additions and 416 deletions

View File

@ -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

View File

@ -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

View File

@ -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}

View File

@ -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

View File

@ -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)

View File

@ -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

View File

@ -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

View File

@ -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)

View File

@ -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

View File

@ -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)

View File

@ -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

View File

@ -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

View File

@ -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)

View File

@ -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

View File

@ -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

View File

@ -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) }

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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)

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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',

View File

@ -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) { [] }

View File

@ -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

View File

@ -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')) }