fix and add specs

This commit is contained in:
Karol
2022-08-31 20:51:58 +02:00
parent 76c9dfa4e5
commit 5ace779d0c
8 changed files with 104 additions and 47 deletions

View File

@ -119,7 +119,7 @@ class ExercisesController < ApplicationController
partial: 'export_actions', partial: 'export_actions',
locals: { locals: {
exercise: @exercise, exercise: @exercise,
task_found: codeharbor_check[:uuid_found], uuid_found: codeharbor_check[:uuid_found],
update_right: codeharbor_check[:update_right], update_right: codeharbor_check[:update_right],
error: codeharbor_check[:error], error: codeharbor_check[:error],
exported: false, exported: false,

View File

@ -37,6 +37,7 @@ module ProformaService
allow_auto_completion: @exercise.allow_auto_completion, allow_auto_completion: @exercise.allow_auto_completion,
expected_difficulty: @exercise.expected_difficulty, expected_difficulty: @exercise.expected_difficulty,
execution_environment_id: @exercise.execution_environment_id, execution_environment_id: @exercise.execution_environment_id,
files: task_files_meta_data,
}, },
}, },
}.compact }.compact
@ -92,17 +93,26 @@ module ProformaService
[ [
task_file(file).tap do |t_file| task_file(file).tap do |t_file|
t_file.used_by_grader = true t_file.used_by_grader = true
t_file.internal_description = 'teacher_defined_test'
end, end,
] ]
end end
def task_files def exercise_files
@exercise.files @exercise.files.filter do |file|
.filter do |file|
!file.role.in? %w[reference_implementation teacher_defined_test !file.role.in? %w[reference_implementation teacher_defined_test
teacher_defined_linter] teacher_defined_linter]
end.map do |file| end
end
def task_files_meta_data
exercise_files.to_h do |file|
# added CO- to id, otherwise the key would have CodeOcean as a prefix after export and import (cause unknown)
["CO-#{file.id}", {role: file.role}]
end
end
def task_files
exercise_files.map do |file|
task_file(file) task_file(file)
end end
end end
@ -112,8 +122,7 @@ module ProformaService
id: file.id, id: file.id,
filename: filename(file), filename: filename(file),
usage_by_lms: file.read_only ? 'display' : 'edit', usage_by_lms: file.read_only ? 'display' : 'edit',
visible: file.hidden ? 'no' : 'yes', visible: file.hidden ? 'no' : 'yes'
# internal_description: file.role || 'regular_file'
) )
add_content_to_task_file(file, task_file) add_content_to_task_file(file, task_file)
task_file task_file
@ -121,8 +130,7 @@ module ProformaService
def filename(file) def filename(file)
if file.path.present? && file.path != '.' if file.path.present? && file.path != '.'
::File.join(file.path, ::File.join(file.path, file.name_with_extension)
file.name_with_extension)
else else
file.name_with_extension file.name_with_extension
end end

View File

@ -21,10 +21,10 @@ module ProformaService
user: @user, user: @user,
title: @task.title, title: @task.title,
description: @task.description, description: @task.description,
public: @task.meta_data[:CodeOcean]&.dig(:public) == 'true', public: string_to_bool(@task.meta_data[:CodeOcean]&.dig(:public)),
hide_file_tree: @task.meta_data[:CodeOcean]&.dig(:hide_file_tree) == 'true', hide_file_tree: string_to_bool(@task.meta_data[:CodeOcean]&.dig(:hide_file_tree)),
allow_file_creation: @task.meta_data[:CodeOcean]&.dig(:allow_file_creation) == 'true', allow_file_creation: string_to_bool(@task.meta_data[:CodeOcean]&.dig(:allow_file_creation)),
allow_auto_completion: @task.meta_data[:CodeOcean]&.dig(:allow_auto_completion) == 'true', allow_auto_completion: string_to_bool(@task.meta_data[:CodeOcean]&.dig(:allow_auto_completion)),
expected_difficulty: @task.meta_data[:CodeOcean]&.dig(:expected_difficulty), expected_difficulty: @task.meta_data[:CodeOcean]&.dig(:expected_difficulty),
execution_environment_id: @task.meta_data[:CodeOcean]&.dig(:execution_environment_id), execution_environment_id: @task.meta_data[:CodeOcean]&.dig(:execution_environment_id),
@ -32,6 +32,13 @@ module ProformaService
) )
end end
def string_to_bool(str)
return true if str == 'true'
return false if str == 'false'
nil
end
def files def files
model_solution_files + test_files + task_files.values model_solution_files + test_files + task_files.values
end end
@ -68,7 +75,7 @@ module ProformaService
hidden: file.visible == 'no', hidden: file.visible == 'no',
name: File.basename(file.filename, '.*'), name: File.basename(file.filename, '.*'),
read_only: file.usage_by_lms != 'edit', read_only: file.usage_by_lms != 'edit',
role: 'regular_file', role: @task.meta_data[:CodeOcean]&.dig(:files)&.dig("CO-#{file.id}".to_sym)&.dig(:role) || 'regular_file',
path: File.dirname(file.filename).in?(['.', '']) ? nil : File.dirname(file.filename) path: File.dirname(file.filename).in?(['.', '']) ? nil : File.dirname(file.filename)
) )
if file.binary if file.binary

View File

@ -4,7 +4,7 @@
= t('exercises.export_codeharbor.buttons.retry') = t('exercises.export_codeharbor.buttons.retry')
- else - else
- unless exported - unless exported
- if !task_found || update_right - if !uuid_found || update_right
= button_tag type: 'button', class:'btn btn-primary float-end export-action export-button', data: {exercise_id: exercise.id} do = button_tag type: 'button', class:'btn btn-primary float-end export-action export-button', data: {exercise_id: exercise.id} do
i.fa-solid.fa-check.confirm-icon i.fa-solid.fa-check.confirm-icon
= t('exercises.export_codeharbor.buttons.export') = t('exercises.export_codeharbor.buttons.export')

View File

@ -387,7 +387,7 @@ describe ExercisesController do
let(:post_request) { post :export_external_check, params: {id: exercise.id} } let(:post_request) { post :export_external_check, params: {id: exercise.id} }
let!(:codeharbor_link) { create(:codeharbor_link, user: user) } let!(:codeharbor_link) { create(:codeharbor_link, user: user) }
let(:external_check_hash) { {message: message, task_found: true, update_right: update_right, error: error} } let(:external_check_hash) { {message: message, uuid_found: true, update_right: update_right, error: error} }
let(:message) { 'message' } let(:message) { 'message' }
let(:update_right) { true } let(:update_right) { true }
let(:error) { nil } let(:error) { nil }
@ -436,7 +436,7 @@ describe ExercisesController do
end end
end end
describe '#export_external_confirm' do describe 'POST #export_external_confirm' do
render_views render_views
let!(:codeharbor_link) { create(:codeharbor_link, user: user) } let!(:codeharbor_link) { create(:codeharbor_link, user: user) }
@ -473,7 +473,7 @@ describe ExercisesController do
end end
end end
describe '#import_uuid_check' do describe 'POST #import_uuid_check' do
let(:exercise) { create(:dummy, uuid: SecureRandom.uuid) } let(:exercise) { create(:dummy, uuid: SecureRandom.uuid) }
let!(:codeharbor_link) { create(:codeharbor_link, user: user) } let!(:codeharbor_link) { create(:codeharbor_link, user: user) }
let(:uuid) { exercise.reload.uuid } let(:uuid) { exercise.reload.uuid }
@ -486,7 +486,7 @@ describe ExercisesController do
post_request post_request
expect(response).to have_http_status(:success) expect(response).to have_http_status(:success)
expect(JSON.parse(response.body).symbolize_keys[:exercise_found]).to be true expect(JSON.parse(response.body).symbolize_keys[:uuid_found]).to be true
expect(JSON.parse(response.body).symbolize_keys[:update_right]).to be true expect(JSON.parse(response.body).symbolize_keys[:update_right]).to be true
end end
@ -506,7 +506,7 @@ describe ExercisesController do
post_request post_request
expect(response).to have_http_status(:success) expect(response).to have_http_status(:success)
expect(JSON.parse(response.body).symbolize_keys[:exercise_found]).to be true expect(JSON.parse(response.body).symbolize_keys[:uuid_found]).to be true
expect(JSON.parse(response.body).symbolize_keys[:update_right]).to be false expect(JSON.parse(response.body).symbolize_keys[:update_right]).to be false
end end
end end
@ -518,7 +518,7 @@ describe ExercisesController do
post_request post_request
expect(response).to have_http_status(:success) expect(response).to have_http_status(:success)
expect(JSON.parse(response.body).symbolize_keys[:exercise_found]).to be false expect(JSON.parse(response.body).symbolize_keys[:uuid_found]).to be false
end end
end end
end end

View File

@ -42,25 +42,25 @@ describe ExerciseService::CheckExternal do
end end
context 'when response contains a JSON with expected keys' do context 'when response contains a JSON with expected keys' do
let(:response) { {task_found: true, update_right: true}.to_json } let(:response) { {uuid_found: true, update_right: true}.to_json }
it 'returns the correct hash' do it 'returns the correct hash' do
expect(check_external_service).to eql(error: false, message: I18n.t('exercises.export_codeharbor.check.task_found'), task_found: true, update_right: true) expect(check_external_service).to eql(error: false, message: I18n.t('exercises.export_codeharbor.check.task_found'), uuid_found: true, update_right: true)
end end
context 'with task_found: false and no update_right' do context 'with uuid_found: false and no update_right' do
let(:response) { {task_found: false}.to_json } let(:response) { {uuid_found: false}.to_json }
it 'returns the correct hash' do it 'returns the correct hash' do
expect(check_external_service).to eql(error: false, message: I18n.t('exercises.export_codeharbor.check.no_task'), task_found: false) expect(check_external_service).to eql(error: false, message: I18n.t('exercises.export_codeharbor.check.no_task'), uuid_found: false)
end end
end end
context 'with task_found: true and update_right: false' do context 'with uuid_found: true and update_right: false' do
let(:response) { {task_found: true, update_right: false}.to_json } let(:response) { {uuid_found: true, update_right: false}.to_json }
it 'returns the correct hash' do it 'returns the correct hash' do
expect(check_external_service).to eql(error: false, message: I18n.t('exercises.export_codeharbor.check.task_found_no_right'), task_found: true, update_right: false) expect(check_external_service).to eql(error: false, message: I18n.t('exercises.export_codeharbor.check.task_found_no_right'), uuid_found: true, update_right: false)
end end
end end
end end

View File

@ -39,7 +39,13 @@ RSpec.describe ProformaService::ConvertExerciseToTask do
language: described_class::DEFAULT_LANGUAGE, language: described_class::DEFAULT_LANGUAGE,
meta_data: { meta_data: {
CodeOcean: { CodeOcean: {
instructions: exercise.instructions, allow_auto_completion: exercise.allow_auto_completion,
allow_file_creation: exercise.allow_file_creation,
execution_environment_id: exercise.execution_environment_id,
expected_difficulty: exercise.expected_difficulty,
hide_file_tree: exercise.hide_file_tree,
public: exercise.public,
files: {},
}, },
}, },
# parent_uuid: exercise.clone_relations.first&.origin&.uuid, # parent_uuid: exercise.clone_relations.first&.origin&.uuid,
@ -62,7 +68,15 @@ RSpec.describe ProformaService::ConvertExerciseToTask do
usage_by_lms: 'edit', usage_by_lms: 'edit',
visible: 'yes', visible: 'yes',
binary: false, binary: false,
internal_description: 'main_file' internal_description: nil
)
end
it 'adds the file\'s role to the file hash in task-meta_data' do
expect(task).to have_attributes(
meta_data: {
CodeOcean: a_hash_including(files: {"CO-#{file.id}" => {role: 'main_file'}}),
}
) )
end end
end end
@ -82,7 +96,15 @@ RSpec.describe ProformaService::ConvertExerciseToTask do
usage_by_lms: 'display', usage_by_lms: 'display',
visible: 'no', visible: 'no',
binary: false, binary: false,
internal_description: 'regular_file' internal_description: nil
)
end
it 'adds the file\'s role to the file hash in task-meta_data' do
expect(task).to have_attributes(
meta_data: {
CodeOcean: a_hash_including(files: {"CO-#{file.id}" => {role: 'regular_file'}}),
}
) )
end end
@ -139,7 +161,7 @@ RSpec.describe ProformaService::ConvertExerciseToTask do
usage_by_lms: 'display', usage_by_lms: 'display',
visible: 'yes', visible: 'yes',
binary: false, binary: false,
internal_description: 'reference_implementation' internal_description: nil
) )
end end
end end
@ -168,8 +190,8 @@ RSpec.describe ProformaService::ConvertExerciseToTask do
files: have(1).item, files: have(1).item,
meta_data: { meta_data: {
CodeOcean: { CodeOcean: {
'entry-point': test_file.filepath,
'feedback-message': 'feedback_message', 'feedback-message': 'feedback_message',
weight: test_file.weight,
}, },
} }
) )
@ -183,7 +205,7 @@ RSpec.describe ProformaService::ConvertExerciseToTask do
used_by_grader: true, used_by_grader: true,
visible: 'no', visible: 'no',
binary: false, binary: false,
internal_description: 'teacher_defined_test' internal_description: nil
) )
end end

View File

@ -38,32 +38,54 @@ describe ProformaService::ConvertTaskToExercise do
uuid: 'uuid', uuid: 'uuid',
parent_uuid: 'parent_uuid', parent_uuid: 'parent_uuid',
language: 'language', language: 'language',
meta_data: { meta_data: meta_data,
CodeOcean: {
instructions: 'instructions',
},
},
model_solutions: model_solutions, model_solutions: model_solutions,
files: files, files: files,
tests: tests tests: tests
) )
end end
let(:user) { create(:teacher) } let(:user) { create(:teacher) }
let(:files) { [] } let(:files) { [] }
let(:tests) { [] } let(:tests) { [] }
let(:model_solutions) { [] } let(:model_solutions) { [] }
let(:exercise) { nil } let(:exercise) { nil }
let(:meta_data) do
{
CodeOcean: {
public: public,
hide_file_tree: hide_file_tree,
allow_file_creation: allow_file_creation,
allow_auto_completion: allow_auto_completion,
expected_difficulty: expected_difficulty,
execution_environment_id: execution_environment.id,
files: files_meta_data,
},
}
end
let(:public) { 'true' }
let(:hide_file_tree) { 'true' }
let(:allow_file_creation) { 'true' }
let(:allow_auto_completion) { 'true' }
let(:expected_difficulty) { 7 }
let!(:execution_environment) { create(:java) }
let(:files_meta_data) { {} }
it 'creates an exercise with the correct attributes' do it 'creates an exercise with the correct attributes' do
expect(convert_to_exercise_service).to have_attributes( expect(convert_to_exercise_service).to have_attributes(
title: 'title', title: 'title',
description: 'description', description: 'description',
instructions: 'instructions',
execution_environment: be_blank,
uuid: be_blank, uuid: be_blank,
unpublished: true, unpublished: true,
user: user, user: user,
files: be_empty files: be_empty,
public: true,
hide_file_tree: true,
allow_file_creation: true,
allow_auto_completion: true,
expected_difficulty: 7,
execution_environment_id: execution_environment.id
) )
end end
@ -311,8 +333,7 @@ describe ProformaService::ConvertTaskToExercise do
create( create(
:files, :files,
title: 'exercise-title', title: 'exercise-title',
description: 'exercise-description', description: 'exercise-description'
instructions: 'exercise-instruction'
) )
end end
@ -324,7 +345,6 @@ describe ProformaService::ConvertTaskToExercise do
id: exercise.id, id: exercise.id,
title: task.title, title: task.title,
description: task.description, description: task.description,
instructions: task.meta_data[:CodeOcean][:instructions],
execution_environment: exercise.execution_environment, execution_environment: exercise.execution_environment,
uuid: exercise.uuid, uuid: exercise.uuid,
user: exercise.user, user: exercise.user,