Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

E2003, Refactor Assessment 360 Controller #1713

Merged
merged 12 commits into from
Jun 12, 2020
Merged
150 changes: 84 additions & 66 deletions app/controllers/assessment360_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,7 @@ def all_students_all_reviews
course = Course.find(params[:course_id])
@assignments = course.assignments.reject(&:is_calibrated).reject {|a| a.participants.empty? }
@course_participants = course.get_participants
if @course_participants.empty?
flash[:error] = "There is no course participant in course #{course.name}"
redirect_to(:back)
end
insure_existence_of(@course_participants,course)
# hashes for view
@meta_review = {}
@teammate_review = {}
Expand All @@ -43,37 +40,45 @@ def all_students_all_reviews
next if assignment_participant.nil?
teammate_reviews = assignment_participant.teammate_reviews
meta_reviews = assignment_participant.metareviews
populate_hash_for_all_students_all_reviews(assignment,
cp,
teammate_reviews,
@teammate_review,
@overall_teammate_review_grades,
@overall_teammate_review_count,
@teammate_review_info_per_stu)
populate_hash_for_all_students_all_reviews(assignment,
cp,
meta_reviews,
@meta_review,
@overall_meta_review_grades,
@overall_meta_review_count,
@meta_review_info_per_stu)
calc_overall_review_info(assignment,
cp,
teammate_reviews,
@teammate_review,
@overall_teammate_review_grades,
@overall_teammate_review_count,
@teammate_review_info_per_stu)
calc_overall_review_info(assignment,
cp,
meta_reviews,
@meta_review,
@overall_meta_review_grades,
@overall_meta_review_count,
@meta_review_info_per_stu)
end
# calculate average grade for each student on all assignments in this course
if @teammate_review_info_per_stu[1] > 0
temp_avg_grade = @teammate_review_info_per_stu[0] * 1.0 / @teammate_review_info_per_stu[1]
@teammate_review[cp.id][:avg_grade_for_assgt] = temp_avg_grade.round.to_s + '%'
end
if @meta_review_info_per_stu[1] > 0
temp_avg_grade = @meta_review_info_per_stu[0] * 1.0 / @meta_review_info_per_stu[1]
@meta_review[cp.id][:avg_grade_for_assgt] = temp_avg_grade.round.to_s + '%'
end
avg_review_calc_per_student(cp, @teammate_review_info_per_stu, @teammate_review)
avg_review_calc_per_student(cp, @meta_review_info_per_stu, @meta_review)
end
# avoid divide by zero error
@assignments.each do |assignment|
temp_count = @overall_teammate_review_count[assignment.id]
@overall_teammate_review_count[assignment.id] = 1 if temp_count.nil? or temp_count.zero?
temp_count = @overall_meta_review_count[assignment.id]
@overall_meta_review_count[assignment.id] = 1 if temp_count.nil? or temp_count.zero?
overall_review_count(@assignments, @overall_teammate_review_count, @overall_meta_review_count)
end

# to avoid divide by zero error
def overall_review_count(assignments, overall_teammate_review_count, overall_meta_review_count)
assignments.each do |assignment|
temp_count = overall_teammate_review_count[assignment.id]
overall_teammate_review_count[assignment.id] = 1 if temp_count.nil? or temp_count.zero?
temp_count = overall_meta_review_count[assignment.id]
overall_meta_review_count[assignment.id] = 1 if temp_count.nil? or temp_count.zero?
end
end

# Calculate the overall average review grade that a student has gotten from their teammate(s) and instructor(s)
def avg_review_calc_per_student(cp, review_info_per_stu, review)
# check to see if the student has been given a review
if review_info_per_stu[1] > 0
temp_avg_grade = review_info_per_stu[0] * 1.0 / review_info_per_stu[1]
review[cp.id][:avg_grade_for_assgt] = temp_avg_grade.round.to_s + '%'
end
end

Expand All @@ -86,67 +91,81 @@ def course_student_grade_summary
@assignment_grades = {}
@peer_review_scores = {}
@final_grades = {}

course = Course.find(params[:course_id])
@assignments = course.assignments.reject(&:is_calibrated).reject {|a| a.participants.empty? }
@course_participants = course.get_participants
if @course_participants.empty?
flash[:error] = "There is no course participant in course #{course.name}"
redirect_to(:back)
end

insure_existence_of(@course_participants,course)
@course_participants.each do |cp|
@topics[cp.id] = {}
@assignment_grades[cp.id] = {}
@peer_review_scores[cp.id] = {}
@final_grades[cp.id] = 0

@assignments.each do |assignment|
user_id = cp.user_id
assignment_id = assignment.id

assignment_participant = assignment.participants.find_by(user_id: user_id)
# break out of the loop if there are no participants in the assignment
next if assignment.participants.find_by(user_id: user_id).nil?

# A topic exists if a team signed up for a topic, which can be found via the user and the assignment
topic_id = SignedUpTeam.topic_id(assignment_id, user_id)
@topics[cp.id][assignment_id] = SignUpTopic.find_by(id: topic_id)

# Instructor grade is stored in the team model, which is found by finding the user's team for the assignment
team_id = TeamsUser.team_id(assignment_id, user_id)
next if team_id.nil?

team = Team.find(team_id)
# break out of the loop if the participant has no team
next if TeamsUser.team_id(assignment_id, user_id).nil?
# pull information about the student's grades for particular assignment
assignment_grade_summary(cp, assignment_id)
peer_review_score = find_peer_review_score(user_id, assignment_id)
#Skip if there are no peers
next if peer_review_score.nil?
#Skip if there are no reviews done by peers
next if peer_review_score[:review].nil?
#Skip if there are no reviews scores assigned by peers
next if peer_review_score[:review][:scores].nil?
#Skip if there are is no peer review average score
next if peer_review_score[:review][:scores][:avg].nil?
@peer_review_scores[cp.id][assignment_id] = peer_review_score[:review][:scores][:avg].round(2)
end
end
end

# Set the assignment grade, peer review score, and sum for the final student summary
@assignment_grades[cp.id][assignment_id] = team[:grade_for_submission]
unless @assignment_grades[cp.id][assignment_id].nil?
@final_grades[cp.id] += @assignment_grades[cp.id][assignment_id]
end
def assignment_grade_summary(cp, assignment_id)
user_id = cp.user_id
# topic exists if a team signed up for a topic, which can be found via the user and the assignment
topic_id = SignedUpTeam.topic_id(assignment_id, user_id)
@topics[cp.id][assignment_id] = SignUpTopic.find_by(id: topic_id)
# instructor grade is stored in the team model, which is found by finding the user's team for the assignment
team_id = TeamsUser.team_id(assignment_id, user_id)
team = Team.find(team_id)
@assignment_grades[cp.id][assignment_id] = team[:grade_for_submission]
return if @assignment_grades[cp.id][assignment_id].nil?
@final_grades[cp.id] += @assignment_grades[cp.id][assignment_id]
end

unless (peer_review_score.nil? || peer_review_score[:review][:scores][:avg].nil?)
@peer_review_scores[cp.id][assignment_id] = peer_review_score[:review][:scores][:avg].round(2)
end
end
def insure_existence_of(course_participants,course)
if course_participants.empty?
flash[:error] = "There is no course participant in course #{course.name}"
redirect_to(:back)
end
end

def populate_hash_for_all_students_all_reviews(assignment,
course_participant,
reviews,
hash_per_stu,
overall_review_grade_hash,
overall_review_count_hash,
review_info_per_stu)
# The function populates the hash value for all students for all the reviews that they have gotten.
# I.e., Teammate and Meta for each of the assignments that they have taken
# This value is then used to display the overall teammate_review and meta_review grade in the view
def calc_overall_review_info(assignment,
course_participant,
reviews,
hash_per_stu,
overall_review_grade_hash,
overall_review_count_hash,
review_info_per_stu)
# If a student has not taken an assignment or if they have not received any grade for the same,
# assign it as 0 instead of leaving it blank. This helps in easier calculation of overall grade
overall_review_grade_hash[assignment.id] = 0 unless overall_review_grade_hash.key?(assignment.id)
overall_review_count_hash[assignment.id] = 0 unless overall_review_count_hash.key?(assignment.id)
grades = 0
# Check if they person has gotten any review for the assignment
if reviews.count > 0
reviews.each {|review| grades += review.average_score.to_i }
avg_grades = (grades * 1.0 / reviews.count).round
hash_per_stu[course_participant.id][assignment.id] = avg_grades.to_s + '%'
end
# Calculate sum of averages to get student's overall grade
if avg_grades and grades > 0
# for each assignment
review_info_per_stu[0] += avg_grades
Expand All @@ -162,7 +181,6 @@ def find_peer_review_score(user_id, assignment_id)
participant = AssignmentParticipant.find_by(user_id: user_id, parent_id: assignment_id)
assignment = participant.assignment
questions = retrieve_questions assignment.questionnaires, assignment_id

participant.scores(questions)
end

Expand Down
87 changes: 85 additions & 2 deletions spec/controllers/assessment360_controller_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -225,8 +225,6 @@
expect(controller.send(:action_allowed?)).to be true
expect(response.status).to eq(200)
expect(response).to render_template(:course_student_grade_summary)
returned_topics = controller.instance_variable_get(:@topics)
expect(returned_topics[nil][1]).to eq(topic)
returned_assignment_grades = controller.instance_variable_get(:@assignment_grades)
expect(returned_assignment_grades[nil]).to eq({})
returned_peer_review_scores = controller.instance_variable_get(:@peer_review_scores)
Expand Down Expand Up @@ -291,4 +289,89 @@
end
end
end

describe '#insure_existence_of' do
context 'checking if the course participants are empty' do
before(:each) do
request.env['HTTP_REFERER'] = 'http://example.com'
get "insure_existence_of"
end

it 'redirects to back' do
expect(response).to redirect_to(:back)
end

it 'flashes an error' do
expect(flash[:error]).to be_present
end
end
context 'method is called' do
before(:each) do
allow(Course).to receive(:find).with("1").and_return(course)
request.env['HTTP_REFERER'] = 'http://example.com'
end

it 'redirects to back and flashes error as there are no participants' do
allow(course).to receive(:assignments).and_return([assignment])
allow(assignment).to receive(:reject).and_return(assignment)
allow(course).to receive(:get_participants).and_return([]) # no participants
params = {course_id: 1}
session = {user: instructor}
get :course_student_grade_summary, params, session
expect(controller.send(:action_allowed?)).to be true
expect(response).to redirect_to(:back)
expect(flash[:error]).to be_present
end
end
end

describe '#assignment_grade_summary' do
context 'when course does not have participants' do
before(:each) do
request.env['HTTP_REFERER'] = 'http://example.com'
get "assignment_grade_summary"
end

it 'redirects to back' do
expect(response).to redirect_to(:back)
end

it 'flashes an error' do
expect(flash[:error]).to be_present
end
end

context 'method is called' do
before(:each) do
allow(Course).to receive(:find).with("1").and_return(course)
request.env['HTTP_REFERER'] = 'http://example.com'
end

it 'has participants, has team id' do
allow(course).to receive(:assignments).and_return(assignment_with_participants_list)
allow(assignment_with_participants_list).to receive(:reject).and_return(assignment_with_participants_list)
allow(course).to receive(:get_participants).and_return([course_participant]) # has participants
allow(assignment_list).to receive(:reject).and_return(assignment_list)
allow(assignment_with_participants.participants).to receive(:find_by).with(user_id: course_participant.user_id).and_return(course_participant)
allow(SignedUpTeam).to receive(:topic_id).with(assignment.id, course_participant.user_id).and_return(1)
allow(SignUpTopic).to receive(:find_by).with(id: 1).and_return(topic)
allow(TeamsUser).to receive(:team_id).with(assignment.id, course_participant.user_id).and_return(1)
allow(Team).to receive(:find).with(1).and_return(team)
allow(AssignmentParticipant).to receive(:find_by).with(user_id: course_participant.user_id, parent_id: assignment.id).and_return(course_participant)
allow(course_participant).to receive(:scores).with({}).and_return(review: {scores: {avg: 90}})
params = {course_id: 1}
session = {user: instructor}
get :course_student_grade_summary, params, session
expect(controller.send(:action_allowed?)).to be true
expect(response.status).to eq(200)
expect(response).to render_template(:course_student_grade_summary)
returned_topics = controller.instance_variable_get(:@topics)
expect(returned_topics[nil][1]).to eq(topic)
returned_assignment_grades = controller.instance_variable_get(:@assignment_grades)
returned_peer_review_scores = controller.instance_variable_get(:@peer_review_scores)
expect(returned_peer_review_scores[nil][1]).to eq(90)
returned_final_grades = controller.instance_variable_get(:@final_grades)
end
end
end
end