spec/models/assignment_participant_spec.rb
describe AssignmentParticipant do
let(:response) { build(:response) }
let(:team) { build(:assignment_team, id: 1) }
let(:team2) { build(:assignment_team, id: 2) }
let(:response_map) { build(:review_response_map, reviewer_id: 2, response: [response]) }
let(:participant) { build(:participant, id: 1, assignment: assignment) }
let(:participant2) { build(:participant, id: 2, grade: 100) }
let(:assignment) { build(:assignment, id: 1) }
let(:review_questionnaire) { build(:questionnaire, id: 1) }
let(:question) { double('Question') }
before(:each) do
allow(assignment).to receive(:questionnaires).and_return([review_questionnaire])
allow(participant).to receive(:team).and_return(team)
end
describe '#dir_path' do
it 'returns the directory path of current assignment' do
expect(participant.dir_path).to eq('final_test')
end
end
describe '#reviewers' do
it 'returns all the participants in this assignment who have reviewed the team where this participant belongs' do
allow(ReviewResponseMap).to receive(:where).with('reviewee_id = ?', 1).and_return([response_map])
allow(AssignmentParticipant).to receive(:find).with(2).and_return(participant2)
expect(participant.reviewers).to eq([participant2])
end
end
describe '#get_reviewer' do
context 'when the associated assignment is reviewed by his team' do
it 'returns the team' do
allow(assignment).to receive(:team_reviewing_enabled).and_return(true)
allow(participant).to receive(:team).and_return(team)
expect(participant.get_reviewer).to eq(team)
end
end
end
describe '#path' do
it 'returns the path name of the associated assignment submission for the team' do
allow(assignment).to receive(:path).and_return('assignment780')
allow(participant).to receive(:team).and_return(team)
allow(team).to receive(:directory_num).and_return(780)
expect(participant.path).to eq('assignment780/780')
end
end
describe '#copy_to_course' do
it 'copies assignment participants to a certain course' do
expect { participant.copy_to_course(123) }.to change { CourseParticipant.count }.from(0).to(1)
expect(CourseParticipant.first.user_id).to eq(2)
expect(CourseParticipant.first.parent_id).to eq(123)
end
end
describe '#feedback' do
it 'returns corresponding author feedback responses given by current participant' do
allow(FeedbackResponseMap).to receive(:assessments_for).with(participant).and_return([response])
expect(participant.feedback).to eq([response])
end
end
describe '#reviews' do
it 'returns corresponding peer review responses given by current team' do
allow(ReviewResponseMap).to receive(:assessments_for).with(team).and_return([response])
expect(participant.reviews).to eq([response])
end
end
describe '#quizzes_taken' do
it 'returns corresponding quiz responses given by current participant' do
allow(QuizResponseMap).to receive(:assessments_for).with(participant).and_return([response])
expect(participant.quizzes_taken).to eq([response])
end
end
describe '#metareviews' do
it 'returns corresponding metareview responses given by current participant' do
allow(MetareviewResponseMap).to receive(:assessments_for).with(participant).and_return([response])
expect(participant.metareviews).to eq([response])
end
end
describe '#teammate_reviews' do
it 'returns corresponding teammate review responses given by current participant' do
allow(TeammateReviewResponseMap).to receive(:assessments_for).with(participant).and_return([response])
expect(participant.teammate_reviews).to eq([response])
end
end
describe '#bookmark_reviews' do
it 'returns corresponding bookmark review responses given by current participant' do
allow(BookmarkRatingResponseMap).to receive(:assessments_for).with(participant).and_return([response])
expect(participant.bookmark_reviews).to eq([response])
end
end
describe '#assign_copyright' do
it 'grant publishing rights to one or more assignments using the supplied private key' do
# create new RSA key-pair
key = OpenSSL::PKey::RSA.new 2048
participant.user.public_key = key.public_key.to_pem
participant.assign_copyright(key)
expect(participant.permission_granted).to eq(true)
end
end
describe '#files' do
context 'when there is not subdirectory in current directory' do
it 'returns all files in current directory' do
expect(participant.files('./hooks')).to eq(['./hooks/pre-commit'])
end
end
context 'when there is subdirectory in current directory' do
it 'recursively returns all files in current directory' do
allow(Dir).to receive(:[]).with('a/*').and_return(['a/b'])
allow(File).to receive(:directory?).with('a/b').and_return(true)
allow(Dir).to receive(:[]).with('a/b/*').and_return(['a/b/k.rb'])
allow(File).to receive(:directory?).with('a/b/k.rb').and_return(false)
expect(participant.files('a')).to eq(%w[a/b/k.rb a/b])
end
end
end
describe '.import' do
context 'when record is empty' do
it 'raises an ArgumentError' do
expect { AssignmentParticipant.import({}, nil, nil, nil) }.to raise_error(ArgumentError, 'No user id has been specified.')
end
end
context 'when no user is found by offered username' do
context 'when the record has less than 4 items' do
it 'raises an ArgumentError' do
row = { username: 'no one', fullname: 'no one', email: 'no_one@email.com' }
expect(ImportFileHelper).not_to receive(:create_new_user)
expect { AssignmentParticipant.import(row, nil, nil, nil) }.to raise_error('The record containing no one does not have enough items.')
end
end
context 'when new user needs to be created' do
let(:row) do
{ username: 'no one', fullname: 'no one', email: 'name@email.com', role: 'user_role_name', parent: 'user_parent_name' }
end
let(:attributes) do
{ role_id: 1, name: 'no one', fullname: 'no one', email: 'name@email.com', email_on_submission: 'name@email.com',
email_on_review: 'name@email.com', email_on_review_of_review: 'name@email.com' }
end
let(:test_user) do
{ name: 'abc', email: 'abcbbc@gmail.com' }
end
it 'create the user and number of mails sent should be 1' do
ActionMailer::Base.deliveries.clear
allow(ImportFileHelper).to receive(:define_attributes).with(row).and_return(attributes)
allow(ImportFileHelper).to receive(:create_new_user) do
test_user = User.new(name: 'abc', fullname: 'abc bbc', email: 'abcbbc@gmail.com')
test_user.id = 123
test_user.save!
password = test_user.reset_password # the password is reset
prepared_mail = MailerHelper.send_mail_to_user(test_user, 'Your Expertiza account and password have been created.', 'user_welcome', password)
prepared_mail.deliver
test_user
end
# allow(ImportFileHelper).to receive(:create_new_user).with(attributes, {}).and_return()
allow(Assignment).to receive(:find).with(1).and_return(assignment)
allow(User).to receive(:exists?).with(name: 'no one').and_return(false)
allow(participant).to receive(:set_handle).and_return('handle')
allow(AssignmentParticipant).to receive(:exists?).and_return(false)
allow(AssignmentParticipant).to receive(:create).and_return(participant)
allow(AssignmentParticipant).to receive(:set_handle)
expect { AssignmentParticipant.import(row, nil, {}, 1) }.to change { ActionMailer::Base.deliveries.count }.by(1)
end
end
context 'when the record has more than 4 items' do
let(:row) do
{ username: 'no one', fullname: 'no one', email: 'name@email.com', role: 'user_role_name', parent: 'user_parent_name' }
end
let(:attributes) do
{ role_id: 1, name: 'no one', fullname: 'no one', email: 'name@email.com', email_on_submission: 'name@email.com',
email_on_review: 'name@email.com', email_on_review_of_review: 'name@email.com' }
end
before(:each) do
allow(ImportFileHelper).to receive(:define_attributes).with(row).and_return(attributes)
allow(ImportFileHelper).to receive(:create_new_user).with(attributes, {}).and_return(double('User', id: 1))
end
context 'when certain assignment cannot be found' do
it 'creates a new user based on import information and raises an ImportError' do
allow(Assignment).to receive(:find).with(1).and_return(nil)
expect(ImportFileHelper).to receive(:create_new_user)
expect { AssignmentParticipant.import(row, nil, {}, 1) }.to raise_error('The assignment with id "1" was not found.')
end
end
context 'when certain assignment can be found and assignment participant does not exists' do
it 'creates a new user, new participant and raises an ImportError' do
allow(Assignment).to receive(:find).with(1).and_return(assignment)
allow(AssignmentParticipant).to receive(:exists?).with(user_id: 1, parent_id: 1).and_return(false)
allow(AssignmentParticipant).to receive(:create).with(user_id: 1, parent_id: 1).and_return(participant)
allow(participant).to receive(:set_handle).and_return('handle')
expect(ImportFileHelper).to receive(:create_new_user)
expect(AssignmentParticipant.import(row, nil, {}, 1)).to be_truthy
end
end
end
end
end
describe '.export' do
it 'exports all participants in current assignment' do
allow(AssignmentParticipant).to receive_message_chain(:where, :find_each).with(parent_id: 1).with(no_args).and_yield(participant)
allow(participant).to receive(:user).and_return(build(:student, name: 'student2065', fullname: '2065, student'))
options = { 'personal_details' => 'true', 'role' => 'true', 'handle' => 'true', 'parent' => 'true', 'email_options' => 'true' }
expect(AssignmentParticipant.export([], 1, options)).to eq(
[['student2065',
'2065, student',
'expertiza@mailinator.com',
'Student',
'instructor6',
true,
true,
true,
'handle']]
)
end
end
describe '#set_handle' do
let(:student) { build(:student, name: 'no one') }
before(:each) do
allow(participant).to receive(:user).and_return(student)
end
context 'when the user of current participant does not have handle' do
it 'sets the user name as the handle of current participant' do
student.handle = ''
expect { participant.set_handle }.to change { AssignmentParticipant.count }.from(0).to(1)
expect(AssignmentParticipant.first.handle).to eq('no one')
end
end
context 'when current assignment exists participants with same handle as the one of current user' do
it 'sets the user name as the name of current participant' do
allow(AssignmentParticipant).to receive(:exists?).with(parent_id: 1, handle: 'handle').and_return(true)
expect { participant.set_handle }.to change { AssignmentParticipant.count }.from(0).to(1)
expect(AssignmentParticipant.first.handle).to eq('no one')
end
end
context 'when current assignment does not have participants with same handle as the one of current user' do
it 'sets the user name as the handle of current participant' do
allow(AssignmentParticipant).to receive(:exist?).with(parent_id: 1, handle: 'handle').and_return(false)
expect { participant.set_handle }.to change { AssignmentParticipant.count }.from(0).to(1)
expect(AssignmentParticipant.first.handle).to eq('handle')
end
end
end
describe '#review_file_path' do
it 'returns the file path for reviewer to upload files during peer review' do
allow(ResponseMap).to receive(:find).with(1).and_return(build(:review_response_map))
allow(TeamsUser).to receive(:find_by).with(team_id: 1).and_return(build(:team_user))
allow(Participant).to receive(:find_by).with(parent_id: 1, user_id: 4).and_return(participant)
expect(participant.review_file_path(1)).to match('pg_data/instructor6/csc517/test/final_test/0_review/1')
end
end
describe '#current_stage' do
it 'returns stage of current assignment' do
allow(SignedUpTeam).to receive(:topic_id).with(1, 2).and_return(5)
expect(participant.current_stage).to eq('Finished')
end
end
describe '#stage_deadline' do
context 'when stage of current assignment is not Finished' do
it 'returns current stage' do
allow(SignedUpTeam).to receive(:topic_id).with(1, 2).and_return(5)
allow(assignment).to receive(:stage_deadline).with(5).and_return('submission')
expect(participant.stage_deadline).to eq('submission')
end
end
context 'when stage of current assignment not Finished' do
before(:each) do
allow(SignedUpTeam).to receive(:topic_id).with(1, 2).and_return(5)
allow(assignment).to receive(:stage_deadline).with(5).and_return('Finished')
end
context 'current assignment is not a staggered deadline assignment' do
it 'returns the due date of current assignment' do
allow(assignment).to receive(:due_dates).and_return([build(:assignment_due_date, due_at: '2007-05-16')])
expect(participant.stage_deadline).to match('2007-05-16')
end
end
context 'current assignment is a staggered deadline assignment' do
it 'returns the due date of current topic' do
assignment.staggered_deadline = true
allow(TopicDueDate).to receive(:find_by).with(parent_id: 5).and_return([build(:assignment_due_date, due_at: '2008-08-08')])
expect(participant.stage_deadline).to match('2008-08-08')
end
end
end
end
end