Files
codeocean/spec/models/submission_spec.rb
Sebastian Serth be4f2b790d Add user to testrun
* We want to identify a user that has triggered a testrun. Previously (in regular operation), only submission author who were regular users were able to start a testrun. Now, we want to prepare a future where submission authors are programming groups. Still, a testrun is triggered by an individual user and not a group.
* Further, this commit fixes some missing foreign key constrains.
2023-08-24 19:32:06 +02:00

159 lines
4.8 KiB
Ruby

# frozen_string_literal: true
require 'rails_helper'
describe Submission do
let(:submission) { create(:submission, exercise: create(:dummy)) }
it 'validates the presence of a cause' do
expect(described_class.create.errors[:cause]).to be_present
end
it 'validates the presence of an exercise' do
expect(described_class.create.errors[:exercise]).to be_present
end
it 'validates the presence of a contributor' do
expect(described_class.create.errors[:contributor]).to be_present
end
describe '#main_file' do
let(:submission) { create(:submission) }
it "returns the submission's main file" do
expect(submission.main_file).to be_a(CodeOcean::File)
expect(submission.main_file.main_file?).to be true
end
end
describe '#normalized_score' do
context 'with a score' do
let(:submission) { create(:submission) }
before { submission.score = submission.exercise.maximum_score / 2 }
it 'returns the score as a value between 0 and 1' do
expect(submission.normalized_score).to be_between(0, 1)
end
end
context 'without a score' do
before { submission.score = nil }
it 'returns 0' do
expect(submission.normalized_score).to be 0
end
end
end
describe '#percentage' do
context 'with a score' do
let(:submission) { create(:submission) }
before { submission.score = submission.exercise.maximum_score / 2 }
it 'returns the score expressed as a percentage' do
expect(submission.percentage).to be_between(0, 100)
end
end
context 'without a score' do
before { submission.score = nil }
it 'returns 0' do
expect(submission.percentage).to be 0
end
end
end
describe '#siblings' do
let(:siblings) { described_class.find_by(contributor:).siblings }
let(:contributor) { create(:external_user) }
before do
10.times.each_with_index do |_, index|
create(:submission, exercise: submission.exercise, contributor: (index.even? ? contributor : create(:external_user)))
end
end
it "returns all the creator's submissions for the same exercise" do
expect(siblings).to be_an(ActiveRecord::Relation)
expect(siblings.map(&:exercise).uniq).to eq([submission.exercise])
expect(siblings.map(&:contributor).uniq).to eq([contributor])
end
end
describe '#to_s' do
it "equals the class' model name" do
expect(submission.to_s).to eq(described_class.model_name.human)
end
end
describe '#redirect_to_feedback?' do
context 'with no exercise feedback' do
let(:exercise) { create(:dummy) }
let(:contributor) { build(:external_user, id: (11 - (exercise.created_at.to_i % 10)) % 10) }
let(:submission) { build(:submission, exercise:, contributor:) }
it 'sends 10% of users to feedback page' do
expect(submission.send(:redirect_to_feedback?)).to be_truthy
end
it 'does not redirect other users' do
9.times do |i|
submission = build(:submission, exercise:, contributor: build(:external_user, id: (11 - (exercise.created_at.to_i % 10)) - i - 1))
expect(submission.send(:redirect_to_feedback?)).to be_falsey
end
end
end
context 'with little exercise feedback' do
let(:exercise) { create(:dummy_with_user_feedbacks) }
let(:contributor) { build(:external_user, id: (11 - (exercise.created_at.to_i % 10)) % 10) }
let(:submission) { build(:submission, exercise:, contributor:) }
it 'sends 10% of users to feedback page' do
expect(submission.send(:redirect_to_feedback?)).to be_truthy
end
it 'does not redirect other users' do
9.times do |i|
submission = build(:submission, exercise:, contributor: build(:external_user, id: (11 - (exercise.created_at.to_i % 10)) - i - 1))
expect(submission.send(:redirect_to_feedback?)).to be_falsey
end
end
end
end
describe '#calculate_score' do
let(:runner) { create(:runner) }
before do
allow(Runner).to receive(:for).and_return(runner)
allow(runner).to receive(:copy_files)
allow(runner).to receive(:attach_to_execution).and_return(1.0)
end
after { submission.calculate_score(submission.contributor) }
it 'executes every teacher-defined test file' do
allow(submission).to receive(:combine_file_scores)
submission.collect_files.select(&:teacher_defined_assessment?).each do |file|
expect(submission).to receive(:score_file).with(any_args, file, submission.contributor)
end
end
it 'scores the submission' do
expect(submission).to receive(:combine_file_scores)
end
end
describe '#combine_file_scores' do
after { submission.send(:combine_file_scores, []) }
it 'assigns a score to the submissions' do
expect(submission).to receive(:update).with(score: anything)
end
end
end