Skip to content

Conversation

@bestinlalu
Copy link

@bestinlalu bestinlalu commented Oct 29, 2025

This PR focuses on improving the Response system within Expertiza, which handles how peer reviews, teammate evaluations, and other questionnaire-based responses are stored and managed. Previously, response handling was scattered across different map controllers (e.g., ReviewResponseMap, TeammateReviewResponseMap), so the goal of this project is to centralize and standardize response management through enhancements to the Response model and the creation of a new ResponsesController on the back end.

Wiki Link: https://github.com/bestinlalu/reimplementation-back-end/wiki/Background

Yu Wang and others added 25 commits October 26, 2025 12:43
… all APIs and testing done using rspec
[#4, #5, #6, #7, #8, #9, #20] Implement ResponseController class with all APIs and testing done using rspec
…-back-end into ScoreLogic

Adding controller updates to the ScoreLogic
Implemented name link from Edit to Update
Removed save_draft endpoint, Removed using Reviewer role, Updated rspec
Removing mock data from rails_helper
Code clean up, removing output statements
Increase puma version to 6.4.2
@github-actions
Copy link

3 Warnings
⚠️ Pull request is too big (more than 500 LoC).
⚠️ Pull request has duplicated commit messages.
⚠️ RSpec tests seem shallow (single it blocks or no context). Consider improving test structure.

Generated by 🚫 Danger

@github-actions
Copy link

github-actions bot commented Nov 4, 2025

🚨 RSpec Tests Report

Failing Model Test Cases:
rspec ./spec/models/response_spec.rb:47 # Response#calculate_total_score computes the total score of a review
rspec ./spec/models/response_spec.rb:124 # Response#calculate_total_score (weighted) adds weight * answer for scorable items
rspec ./spec/models/response_spec.rb:145 # Response#calculate_total_score (skips non-scorable and nil) ignores items that are not scorable and answers that are nil

2 similar comments
@github-actions
Copy link

github-actions bot commented Nov 4, 2025

🚨 RSpec Tests Report

Failing Model Test Cases:
rspec ./spec/models/response_spec.rb:47 # Response#calculate_total_score computes the total score of a review
rspec ./spec/models/response_spec.rb:124 # Response#calculate_total_score (weighted) adds weight * answer for scorable items
rspec ./spec/models/response_spec.rb:145 # Response#calculate_total_score (skips non-scorable and nil) ignores items that are not scorable and answers that are nil

@github-actions
Copy link

github-actions bot commented Nov 4, 2025

🚨 RSpec Tests Report

Failing Model Test Cases:
rspec ./spec/models/response_spec.rb:47 # Response#calculate_total_score computes the total score of a review
rspec ./spec/models/response_spec.rb:124 # Response#calculate_total_score (weighted) adds weight * answer for scorable items
rspec ./spec/models/response_spec.rb:145 # Response#calculate_total_score (skips non-scorable and nil) ignores items that are not scorable and answers that are nil

@github-actions
Copy link

github-actions bot commented Nov 5, 2025

🚨 RSpec Tests Report

Failing Model Test Cases:
rspec ./spec/models/response_spec.rb:47 # Response#calculate_total_score computes the total score of a review
rspec ./spec/models/response_spec.rb:124 # Response#calculate_total_score (weighted) adds weight * answer for scorable items
rspec ./spec/models/response_spec.rb:145 # Response#calculate_total_score (skips non-scorable and nil) ignores items that are not scorable and answers that are nil

@github-actions
Copy link

github-actions bot commented Nov 5, 2025

🚨 RSpec Tests Report

All tests passed.

1 similar comment
@github-actions
Copy link

github-actions bot commented Nov 5, 2025

🚨 RSpec Tests Report

All tests passed.

@vihar2712 vihar2712 self-requested a review November 10, 2025 18:49
Copy link
Member

@efg efg left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Lots of low-level issues to handle and fix.

true
when 'update', 'submit'
@response = Response.find(params[:id])
unless owns_response_or_map? || has_role?('Instructor') || has_role?('Admin')
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The disjunction should be replaced by ~ has_privileges_of

render json: { error: 'forbidden' }, status: :forbidden
end
when 'unsubmit', 'destroy'
unless has_role?('Instructor') || has_role?('Admin')
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Shouldn't it also check to make sure this is the instructor's (or the admin's) assignment? Shouldn't be able to delete reviews for other people's assignments.

return render json: { error: 'Response already submitted' }, status: :unprocessable_entity if @response.is_submitted?

# Check deadline
return render json: { error: 'Deadline has passed' }, status: :forbidden unless deadline_open?(@response)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

deadline_open? is a bad name. What does that mean?

return render json: { error: 'Deadline has passed' }, status: :forbidden unless deadline_open?(@response)

# Validate rubric completion
unanswered = @response.scores.select { |a| a.answer.nil? }
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It is just WRONG to build into the mechanism that ALL rubric items must have text (or numbers) entered for ALL rubrics of ANY KIND anywhere in the system. This should be dependent on policy. Remove this check.


if @response.is_submitted?
@response.update(is_submitted: false)
render json: { message: 'Response reopened for revision', response: @response }, status: :ok
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The word "Response" here could be confusing. That's what it is in the system, but the UI should use better names. Don't we have print names for each different kind of Questionnaire? Also, "reopened for revision" is much too cryptic. Say it in plain English!

return nil unless reviewee

candidates = []
candidates << reviewee.updated_at if reviewee.respond_to?(:updated_at) && reviewee.updated_at.present?
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

respond_to? is confusing; that method should be renamed to something that is more suggestive of what it does.

Copy link
Member

@efg efg left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for fixing!

true
when 'update', 'submit'
@response = Response.find(params[:id])
unless response_belongs_to? || current_user_has_admin_privileges? ||
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's not whether current_user_has_admin_privileges?; it's whether this user created (is the parent of) the instructor whose course this is. One of the current projects is writing/has written code for this. Not sure which, but it should be fairly easy to guess.

# Checks whether the current_user is the instructor for the assignment
# associated with the response identified by params[:id].
# Uses the shared authorization method from Authorization concern.
def current_user_instructs_response_assignment?
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not only the instructor, but also TAs for the course and the admin who created the instructor, need to be able to perform this method.

return true if assignment.nil?
return true if assignment.due_dates.nil?

# Check if due_date has a future? method, otherwise compare timestamps
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think there is an "upcoming" method that does what you think future? does.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think "upcoming" is a better name.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's E2566, finish DueDates, who is using the upcoming method.

# (each response can omit questions, so maximum_score may differ and we normalize before averaging)
existing_responses.each do |response|
unless id == response.id # the current_response is also in existing_responses array
count += 1
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should this be in the ReviewAggregator mixin?

unless id == response.id # the current_response is also in existing_responses array
count += 1
total += response.aggregate_questionnaire_score.to_f / response.maximum_score
total += response.aggregate_questionnaire_score.to_f / response.maximum_score
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please remove the code smell.

…s; prefer upcoming for deadlines; reduce rounding in report diffs
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants