Files
codeocean/spec/models/submission_spec.rb
Sebastian Serth 99bd46af1a Align project files with CodeHarbor
Since both projects are developed together and by the same team, we also want to have the same code structure and utility methods available in both projects. Therefore, this commit changes many files, but without a functional change.
2023-10-11 00:18:33 +02:00

159 lines
4.9 KiB
Ruby

# frozen_string_literal: true
require 'rails_helper'
RSpec.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