<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
	<id>https://wiki.expertiza.ncsu.edu/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Vdeshmu</id>
	<title>Expertiza_Wiki - User contributions [en]</title>
	<link rel="self" type="application/atom+xml" href="https://wiki.expertiza.ncsu.edu/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Vdeshmu"/>
	<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=Special:Contributions/Vdeshmu"/>
	<updated>2026-05-18T09:43:06Z</updated>
	<subtitle>User contributions</subtitle>
	<generator>MediaWiki 1.41.0</generator>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2021_-_E2165._Fix_teammate-review_view&amp;diff=141770</id>
		<title>CSC/ECE 517 Fall 2021 - E2165. Fix teammate-review view</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2021_-_E2165._Fix_teammate-review_view&amp;diff=141770"/>
		<updated>2021-11-28T19:45:29Z</updated>

		<summary type="html">&lt;p&gt;Vdeshmu: /* Explanation of fixes */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Team Introduction ==&lt;br /&gt;
&lt;br /&gt;
Dr. Edward Gehringer (instructor), Parimal Mehta (mentor)&lt;br /&gt;
&lt;br /&gt;
1. Anjali Garg (unity ID : agarg25)&lt;br /&gt;
&lt;br /&gt;
2. Arvasu Chikara (unity ID: achikar2)&lt;br /&gt;
&lt;br /&gt;
3. Lalit Bangad (unity ID: llbangad)&lt;br /&gt;
&lt;br /&gt;
4. Vinay Deshmukh (unity ID: vdeshmu)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Problems to be addressed ==&lt;br /&gt;
&lt;br /&gt;
After a project is submitted and reviewed, both the team members (students) and instructors should be able to view the teammate reviews. Students should be able to view the reviews by going to a particular assignment's -&amp;gt; your scores, at the bottom of the page. An instructor can view the teammate reviews by going to assignments -&amp;gt; assignment -&amp;gt; particular team's submission -&amp;gt; view submission -&amp;gt; assign grades -&amp;gt; view scores. &lt;br /&gt;
&lt;br /&gt;
In the case of the instructor, a single heat grid is shown whereas in the case of a team member, we cant view the scores. In the heat grid, it is not clear if the scores visible are for the reviews that the student has *written* for their teammates or the scores that the student has *received* from their teammates. Additionally, for instructors can choose from a list of the students on the team, but they have no way to tell whether the heat grid shows the reviews done *by* that student or done *for* that student.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Methodology Overview ==&lt;br /&gt;
&lt;br /&gt;
We have divided our work in the following tasks to address the above problems:&lt;br /&gt;
&lt;br /&gt;
1. Distinguish reviews done for a student by rendering separates heatgrids for each student&lt;br /&gt;
&lt;br /&gt;
2. For instructors, the table will have sections based on the students&lt;br /&gt;
&lt;br /&gt;
3. Include a checkbox on the edit assignment page that enables/disables visibility of heat grid to students&lt;br /&gt;
&lt;br /&gt;
4. Fix the average column for a table (which breaks for some reviews)&lt;br /&gt;
&lt;br /&gt;
5. Show a composite score derived from all reviews.  Make this code generalized, so other kinds of heat grid views could use it.&lt;br /&gt;
&lt;br /&gt;
6. Changes should work even in an anonymized view&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Motivations ==&lt;br /&gt;
&lt;br /&gt;
1. Enable users to clearly tell which reviews are done by them, and which reviews are done for them.&lt;br /&gt;
&lt;br /&gt;
2. Code should be generic so it can be used for different types of heat grids as well.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Control Flow to access the concerned screens ==&lt;br /&gt;
'''1. For instructor (Log in as an instructor):-'''&lt;br /&gt;
&lt;br /&gt;
Screen after logging in by the instructor&lt;br /&gt;
[[File:ss1.png |border|1000px|center]]&lt;br /&gt;
Got to assignments on the Manage menu &lt;br /&gt;
[[File:ss2.png |border|1000px|center]]&lt;br /&gt;
Go to assignments&lt;br /&gt;
[[File:ss3.png |border|1000px|center]]&lt;br /&gt;
Go to submissions for any assignment&lt;br /&gt;
[[File:ss4a.png |border|1000px|center]]&lt;br /&gt;
Go to Assign Grade&lt;br /&gt;
[[File:ss5a.png |border|1000px|center]]&lt;br /&gt;
You will land on the page where the changes are made and can be reviewed&lt;br /&gt;
[[File:ss7a.png |border|1000px|center]]&lt;br /&gt;
&lt;br /&gt;
'''2. Student:- (Instructor impersonating a student)'''&lt;br /&gt;
&lt;br /&gt;
After landing on the assignments page, select any student from an assignment as shown below&lt;br /&gt;
[[File:ss6a.png |border|1000px|center]]&lt;br /&gt;
Go to/Select any assignment&lt;br /&gt;
[[File:ss9a.png |border|1000px|center]]&lt;br /&gt;
Go to your scores&lt;br /&gt;
[[File:ss10a.png |border|1000px|center]]&lt;br /&gt;
You will land on the page where the changes are made and can be reviewed&lt;br /&gt;
[[File:ss11a.png |border|1000px|center]]&lt;br /&gt;
&lt;br /&gt;
== Old Status of the application ==&lt;br /&gt;
&lt;br /&gt;
'''1. Instructor's view of teammate review''': This is the current screen given to the instructor. Here we see that the instructor can not determine who has given which review to which student in a team.&lt;br /&gt;
&lt;br /&gt;
[[File:Instructor-view-1.png|border| 700px |center|alt=The proposed expanded student display.|The proposed expanded student display.]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''2. Student's view of teammate review''': Currently, a student is not able to see what grades were given by their teammates. We need to implement that functionality so that the student is able to view those grades.&lt;br /&gt;
&lt;br /&gt;
[[File:Student-view-2.png|border| 700px |center|alt=The current instructor view.|The current review display for instructors.]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''3. Error in existing UI for student''': In the existing UI for a student, the highlighted block should not be rendered. This part of the screen is meant for the instructors/TAs. &lt;br /&gt;
&lt;br /&gt;
[[File:Wrong render for student.png|border|700px|center|alt=Existing UI for student|Existing UI for student.]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Proposed changes ==&lt;br /&gt;
&lt;br /&gt;
''' 1) Proposed UI for instructor ''': The instructor is able to see the score for all teammates. In the existing code, only one teammate's scores are being shown. But, we are planning to change the way the (VmQuestionResponse array is populated)[https://github.com/expertiza/expertiza/blob/master/app/controllers/grades_controller.rb#L114], so that the scores for all teammates are appended to it so it correctly shows what should have already been shown in this screen for the instructor.&lt;br /&gt;
&lt;br /&gt;
[[File:Proposed_screen.png|border|700px|center|alt=Proposed UI for instructor|Proposed UI for instructor.]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Note: When a student visits this screen, they will only be shown the reviews received by them, assuming the instructor has allowed visibility of teammate reviews to students.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
''' 2) Show detailed review for a particular question''': The instructor can see detailed review given to a student by their teammates by clicking on a particular question number in the table.&lt;br /&gt;
&lt;br /&gt;
[[File:ss12a.png|border|700px|center|alt=New UI for students|New UI for students ]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
''' 3) Show teammate review to student UI ''': The existing code doesn't render a student's teammate review scores at all. We are planning to render the scores to a student (as shown below) when they visit this screen. However, the visibility of this screen is contingent on whether the instructor has allowed visibility of the teammate review screen to students. If the instructor has disabled this feature, then the heatgrid will not be displayed at all.&lt;br /&gt;
&lt;br /&gt;
[[File:UI_for_student.png|border|700px|center|alt=New UI for students|New UI for students ]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== User Stories ==&lt;br /&gt;
&lt;br /&gt;
1. As an instructor, I can view what reviews one teammate has given to other teammates.&lt;br /&gt;
&lt;br /&gt;
2. As a student, I can view what reviews my teammates have given to me.&lt;br /&gt;
&lt;br /&gt;
3. As an instructor, I can choose if I want to see all student's teammates reviews together or one by one.&lt;br /&gt;
&lt;br /&gt;
4. As a student, if I am also a TA for another subject, I should not be able to see an instructor's view to the view_team page.&lt;br /&gt;
&lt;br /&gt;
5. As an instructor, I should be able to see the name of the reviewers for the reviews to a particular student.&lt;br /&gt;
&lt;br /&gt;
== UML diagram for the system ==  &lt;br /&gt;
&lt;br /&gt;
[[File:vie_team_use_case.png|border|center]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Changes to the models ==&lt;br /&gt;
&lt;br /&gt;
1. Added new instance variable and method to the class VmQuestionResponseScoreCell.&lt;br /&gt;
[[File:cd1.png |border|400px|center]]&lt;br /&gt;
&lt;br /&gt;
2. Added two new methods to VmQuestionResponse class.&lt;br /&gt;
[[File:cd2.png |border|400px|center]]&lt;br /&gt;
&lt;br /&gt;
== Explanation of fixes ==&lt;br /&gt;
&lt;br /&gt;
The below diagram illustrates the proposed code change for showing all team members with the teammate review data to an instructor. The existing code only iterated on the `Participant` whose ID is present in the URL of the page. To fix this, we will iterate over all teammates of the given participant so that all teammate reviews for all team members are shown to the instructor.&lt;br /&gt;
&lt;br /&gt;
[[File:Logic e2165.png|border|center|alt=Flow diagram of proposed changes for showing team review data to instructor]]&lt;br /&gt;
&lt;br /&gt;
===Changes made to the code are shown below. Every change is shown and explained separately===&lt;br /&gt;
&lt;br /&gt;
====A. Added the following to app/assets/stylesheets/grades.scss:====&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    .teammate_table.hidden {&lt;br /&gt;
      display: none;&lt;br /&gt;
      }&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
====B. In app/controllers/grades_controller.rb: ====&lt;br /&gt;
&lt;br /&gt;
'''B.1:'''&lt;br /&gt;
&lt;br /&gt;
Old code: The existing code does not differentiate when adding a view model for the TeammateReview questionnaire&lt;br /&gt;
  questionnaires.each do |questionnaire|&lt;br /&gt;
     ...&lt;br /&gt;
     @vmlist &amp;lt;&amp;lt; populate_view_model(questionnaire)&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
New code: Since the current page URL contains an ID for the participant, from which we get an assignment, which gives us a list of questionnaires, we need to iterate all participants for a `TeammateReveiwQuestionnaire` questionnaire, so that we get the heatgrid view models for all members of a team.&lt;br /&gt;
  questionnaires.each do |questionnaire|&lt;br /&gt;
     ...&lt;br /&gt;
     if questionnaire.type == &amp;quot;TeammateReviewQuestionnaire&amp;quot;&lt;br /&gt;
        # as teammate review will be different for each participant&lt;br /&gt;
        # we need to create a separate table for each teammate&lt;br /&gt;
        @participant.team.participants.each do |team_participant|&lt;br /&gt;
          @vmlist &amp;lt;&amp;lt; populate_view_model(team_participant, questionnaire, @team)&lt;br /&gt;
        end&lt;br /&gt;
      else&lt;br /&gt;
        # only one participant needs iterating, as apart from teammatereview&lt;br /&gt;
        # all other reviews are at &amp;quot;team&amp;quot; level&lt;br /&gt;
        @vmlist &amp;lt;&amp;lt; populate_view_model(@participant, questionnaire, @team)&lt;br /&gt;
      end&lt;br /&gt;
   end&lt;br /&gt;
&lt;br /&gt;
'''B.2: '''&lt;br /&gt;
&lt;br /&gt;
Old code: This code uses @participant as an instance variable, but this structure will not work as we need to call this ViewModel with multiple participants when iterating for a teammate review questionnaire.&lt;br /&gt;
    def populate_view_model(questionnaire)&lt;br /&gt;
      vm = VmQuestionResponse.new(questionnaire, @assignment, @round)&lt;br /&gt;
      vmquestions = questionnaire.questions&lt;br /&gt;
      vm.add_questions(vmquestions)&lt;br /&gt;
      vm.add_team_members(@team)&lt;br /&gt;
      vm.add_reviews(@participant, @team, @assignment.vary_by_round)&lt;br /&gt;
      vm.number_of_comments_greater_than_10_words&lt;br /&gt;
      vm &lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
New code: We need to call this function with a separate participant in each invocation due to our change for TeammateReviewQuestionnaire, hence it makes sense to make `participant` as an argument to this function. Similarly, as `team` is a closely related model to `participant`, we are passing it as an argument, to keep this function as &amp;quot;pure&amp;quot; as possible.&lt;br /&gt;
    def populate_view_model(participant, questionnaire, team)&lt;br /&gt;
      ...&lt;br /&gt;
      vm.add_team_members(team)&lt;br /&gt;
      vm.add_reviews(participant, team, @assignment.vary_by_round)&lt;br /&gt;
      ...&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
====C. In app/models/vm_question_response.rb:====&lt;br /&gt;
&lt;br /&gt;
'''C.1: '''Added the reviewee_id method: Created a helper method within the VmQuestionReponse model to retrieve the `reviewee_id` for a heatgrid&lt;br /&gt;
&lt;br /&gt;
    def reviewee_id&lt;br /&gt;
      @participant_who_is_reviewee.user_id&lt;br /&gt;
    end &lt;br /&gt;
&lt;br /&gt;
'''C.2: '''Added the reviewee_name method: Created a helper method within the VmQuestionReponse model to retrieve the name of the student who is being reviewed for a heatgrid. This method uses the functionality to anonymize the name when we are in anonymized view.&lt;br /&gt;
&lt;br /&gt;
    def reviewee_name(ip_address = nil)&lt;br /&gt;
      part = @participant_who_is_reviewee&lt;br /&gt;
      User.find_by(id: reviewee_id).fullname(ip_address)&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
'''C.3: '''&lt;br /&gt;
&lt;br /&gt;
Old code: Does not keep track of the student being reviewed&lt;br /&gt;
    elsif @questionnaire_type == &amp;quot;TeammateReviewQuestionnaire&amp;quot;&lt;br /&gt;
      reviews = participant.teammate_reviews&lt;br /&gt;
      reviews.each do |review|&lt;br /&gt;
        review_mapping = TeammateReviewResponseMap.find_by(id: review.map_id)&lt;br /&gt;
        participant = Participant.find(review_mapping.reviewer_id)&lt;br /&gt;
&lt;br /&gt;
New code: Add an instance variable to keep track of the student who is being reviewed in this VmQuestionReponse&lt;br /&gt;
    elsif @questionnaire_type == &amp;quot;TeammateReviewQuestionnaire&amp;quot;&lt;br /&gt;
      reviews = participant.teammate_reviews&lt;br /&gt;
      @participant_who_is_reviewee = participant&lt;br /&gt;
      reviews.each do |review|&lt;br /&gt;
        review_mapping = TeammateReviewResponseMap.find_by(id: review.map_id)&lt;br /&gt;
        participant = Participant.find(review_mapping.reviewer_id)&lt;br /&gt;
&lt;br /&gt;
'''C.4: '''&lt;br /&gt;
&lt;br /&gt;
Old code: Existing VmQuestionReponseScoreCell keeps no information about the reviewer, as it only stores the answer score&lt;br /&gt;
    row.score_row.push(VmQuestionResponseScoreCell.new(answer.answer, color_code, answer.comments, vm_tag_prompts))&lt;br /&gt;
&lt;br /&gt;
New code: Keep track of the response ID, so that we can retrieve the user ID for the reviewer in the model to use in the view file.&lt;br /&gt;
    &lt;br /&gt;
    row.score_row.push(VmQuestionResponseScoreCell.new(answer.answer, color_code, answer.comments, vm_tag_prompts, answer.response_id))&lt;br /&gt;
&lt;br /&gt;
====D. In app/models/vm_question_response_score_cell.rb:====&lt;br /&gt;
&lt;br /&gt;
'''D.1: '''In the method initialize of class VmQuestionResponseScoreCell&lt;br /&gt;
&lt;br /&gt;
Old code: Existing code doesn't keep track of the response id&lt;br /&gt;
    def initialize(score_value, color_code, comments, vmprompts = nil)&lt;br /&gt;
      @score_value = score_value&lt;br /&gt;
      @color_code = color_code&lt;br /&gt;
      @comment = comments&lt;br /&gt;
      @vm_prompts = vmprompts&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
New code: We added an instance variable to keep track of response_id&lt;br /&gt;
&lt;br /&gt;
    def initialize(score_value, color_code, comments, vmprompts = nil, response_id)&lt;br /&gt;
      ...&lt;br /&gt;
      @response_id = response_id&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
'''D.2: '''Added a method reviewer_id to the class VmQuestionResponseScoreCell: This helper method retrieves the ID for the reviewer who created this response.&lt;br /&gt;
&lt;br /&gt;
    def reviewer_id&lt;br /&gt;
      resp = Response.find(@response_id)&lt;br /&gt;
      map = ResponseMap.find(resp.map_id)&lt;br /&gt;
      map.reviewer_id&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
====E. In app/views/grades/_add_icon_to_name.html.erb:====&lt;br /&gt;
&lt;br /&gt;
'''E.1 '''Added the following code to the file: Write the code to generate the review text only once to reduce WET code&lt;br /&gt;
&lt;br /&gt;
    &amp;lt;%# Determine the content of the reviewed by text %&amp;gt;&lt;br /&gt;
    &amp;lt;% review_text = &amp;quot;&amp;quot; %&amp;gt;&lt;br /&gt;
    &amp;lt;% if @current_role_name.eql?'Student' or questionnaire_type != &amp;quot;TeammateReviewQuestionnaire&amp;quot; %&amp;gt;&lt;br /&gt;
      &amp;lt;%# Use Review {{index}} format for student view, and when questionnaire_type is not teammatereview %&amp;gt;&lt;br /&gt;
      &amp;lt;% review_text = &amp;quot;Review #{i + 1}&amp;quot; %&amp;gt;&lt;br /&gt;
    &amp;lt;% else %&amp;gt;&lt;br /&gt;
      &amp;lt;% resp = Response.find(review.id) %&amp;gt;&lt;br /&gt;
      &amp;lt;% map = ResponseMap.find(resp.map_id) %&amp;gt;&lt;br /&gt;
      &amp;lt;% reviewer_id = map.reviewer_id %&amp;gt;&lt;br /&gt;
      &amp;lt;% fullname = Participant.find_by(id: reviewer_id).fullname(session[:ip]) %&amp;gt;&lt;br /&gt;
      &amp;lt;% review_text = &amp;quot;Review by #{fullname}&amp;quot; %&amp;gt;&lt;br /&gt;
    &amp;lt;% end%&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''E.2: '''&lt;br /&gt;
&lt;br /&gt;
Old code: Existing code is very unreadable as it's not indented, and written in a single line with 359 characters, which breaks the ruby style guide rules&lt;br /&gt;
&lt;br /&gt;
    &amp;lt;% if review.done_by_staff_participant? %&amp;gt;&lt;br /&gt;
      &amp;lt;th class=&amp;quot;sorter-false&amp;quot;&amp;gt; &amp;lt;img data-toggle=&amp;quot;tooltip&amp;quot; data-placement=&amp;quot;right&amp;quot; title=&amp;quot;Icon indicates this review was done by course staff&amp;quot; class=&amp;quot;img_icon&amp;quot; src=&amp;quot;/assets/staff.png&amp;quot;&amp;gt; &amp;lt;a target=&amp;quot;_blank&amp;quot; href=&amp;quot;../response/view?id=&amp;lt;%= review.id.to_s %&amp;gt;&amp;quot;  data-toggle=&amp;quot;tooltip&amp;quot; data-placement=&amp;quot;right&amp;quot; title=&amp;quot;Click to see details&amp;quot;&amp;gt;&amp;lt;%= &amp;quot;Review &amp;quot; + i.to_s  %&amp;gt;&amp;lt;/a&amp;gt; &amp;lt;/th&amp;gt;&lt;br /&gt;
    &amp;lt;% else %&amp;gt;&lt;br /&gt;
      &amp;lt;th class=&amp;quot;sorter-false&amp;quot;&amp;gt; &amp;lt;a target=&amp;quot;_blank&amp;quot; href=&amp;quot;../response/view?id=&amp;lt;%= review.id.to_s %&amp;gt;&amp;quot;  data-toggle=&amp;quot;tooltip&amp;quot; data-placement=&amp;quot;right&amp;quot; title=&amp;quot;Click to see details&amp;quot;&amp;gt;&amp;lt;%= &amp;quot;Review &amp;quot; + i.to_s %&amp;gt;&amp;lt;/a&amp;gt;  &amp;lt;/th&amp;gt;&lt;br /&gt;
    &amp;lt;% end %&amp;gt;&lt;br /&gt;
&lt;br /&gt;
New code: Correctly indented and removes WET repetition of code blocks and makes the resulting code DRYer&lt;br /&gt;
&lt;br /&gt;
    &amp;lt;th class=&amp;quot;sorter-false&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;lt;% if review.done_by_staff_participant? %&amp;gt;&lt;br /&gt;
      &amp;lt;img&lt;br /&gt;
      data-toggle=&amp;quot;tooltip&amp;quot;&lt;br /&gt;
      data-placement=&amp;quot;right&amp;quot;&lt;br /&gt;
      title=&amp;quot;Icon indicates this review was done by course staff&amp;quot; class=&amp;quot;img_icon&amp;quot;&lt;br /&gt;
      src=&amp;quot;/assets/staff.png&amp;quot;&lt;br /&gt;
      &amp;gt;&lt;br /&gt;
    &amp;lt;% end %&amp;gt;&lt;br /&gt;
    &amp;lt;a&lt;br /&gt;
      target=&amp;quot;_blank&amp;quot;&lt;br /&gt;
      href=&amp;quot;../response/view?id=&amp;lt;%= review.id.to_s %&amp;gt;&amp;quot;&lt;br /&gt;
      data-toggle=&amp;quot;tooltip&amp;quot;&lt;br /&gt;
      data-placement=&amp;quot;right&amp;quot;&lt;br /&gt;
      title=&amp;quot;Click to see details&amp;quot;&amp;gt;&lt;br /&gt;
      &amp;lt;%= review_text %&amp;gt;&lt;br /&gt;
    &amp;lt;/a&amp;gt;&lt;br /&gt;
    &amp;lt;/th&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====F.In app/views/grades/view_team.html.erb:====&lt;br /&gt;
&lt;br /&gt;
'''F.1: '''Added function teammateSelectOnChange: This function toggles the visibility for the teammate heatgrids when the instructor changes the dropdown&lt;br /&gt;
    &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  function teammateSelectOnChange(selectNode) {&lt;br /&gt;
      const revieweeIdToShow= selectNode.value;&lt;br /&gt;
      const tableSelector = &amp;quot;.teammate_table&amp;quot;;&lt;br /&gt;
      if(revieweeIdToShow == &amp;quot;all&amp;quot;) {&lt;br /&gt;
        document.querySelectorAll(tableSelector).forEach((tableNode) =&amp;gt; {&lt;br /&gt;
          tableNode.classList.remove(&amp;quot;hidden&amp;quot;);&lt;br /&gt;
        });&lt;br /&gt;
        return;&lt;br /&gt;
      }&lt;br /&gt;
&lt;br /&gt;
    document.querySelectorAll(tableSelector).forEach((tableNode) =&amp;gt; {&lt;br /&gt;
      const tableRevieweeId = tableNode.getAttribute('data-reviewee_id');&lt;br /&gt;
      if(tableRevieweeId == revieweeIdToShow) {&lt;br /&gt;
        tableNode.classList.remove(&amp;quot;hidden&amp;quot;);&lt;br /&gt;
      } else {&lt;br /&gt;
        tableNode.classList.add(&amp;quot;hidden&amp;quot;);&lt;br /&gt;
      }&lt;br /&gt;
      });&lt;br /&gt;
    }&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''F.2: '''&lt;br /&gt;
&lt;br /&gt;
Old code: Existing code doesn't render TeammateReviewQuestionnaire&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    &amp;lt;% @vmlist.each do |vm| %&amp;gt;&lt;br /&gt;
        &amp;lt;% if (vm.questionnaire_display_type == &amp;quot;Metareview&amp;quot; or vm.questionnaire_display_type == &amp;quot;Author Feedback&amp;quot; or vm.questionnaire_display_type == &amp;quot;Teammate Review&amp;quot;) and @current_role_name.eql?'Student' %&amp;gt;&lt;br /&gt;
        &amp;lt;% else %&amp;gt;&lt;br /&gt;
        &amp;lt;% if vm.list_of_reviewers.length &amp;gt; 0 %&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
New code: Use a boolean to render a dropdown (that contains the students' IDs and names) just before the first TeammateReviewQuestionnaire, and unset that boolean so we only render 1 table. &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;%# This boolean is used to render a dropdown just before the first teammate review heat grid %&amp;gt;&lt;br /&gt;
&amp;lt;% first_teammate_review_appeared = false %&amp;gt;&lt;br /&gt;
&amp;lt;% @vmlist.each do |vm| %&amp;gt;&lt;br /&gt;
     &amp;lt;% if (not @current_role_name.eql?'Student' and&lt;br /&gt;
        not first_teammate_review_appeared and&lt;br /&gt;
        vm.questionnaire_type == &amp;quot;TeammateReviewQuestionnaire&amp;quot; &lt;br /&gt;
      ) %&amp;gt;&lt;br /&gt;
      &amp;lt;div&amp;gt;&lt;br /&gt;
        &amp;lt;select onchange=&amp;quot;teammateSelectOnChange(this)&amp;quot;&amp;gt;&lt;br /&gt;
          &amp;lt;option value=&amp;quot;all&amp;quot;&amp;gt;All&amp;lt;/option&amp;gt;&lt;br /&gt;
          &amp;lt;% @vmlist.select { |tm_vm| tm_vm.questionnaire_type == &amp;quot;TeammateReviewQuestionnaire&amp;quot; }.each do |tm_vm| %&amp;gt;&lt;br /&gt;
            &amp;lt;option value=&amp;quot;&amp;lt;%= tm_vm.reviewee_id %&amp;gt;&amp;quot;&amp;gt;&lt;br /&gt;
              &amp;lt;%= tm_vm.reviewee_name(session[:ip]) %&amp;gt;&lt;br /&gt;
            &amp;lt;/option&amp;gt;&lt;br /&gt;
          &amp;lt;% end %&amp;gt;&lt;br /&gt;
        &amp;lt;/select&amp;gt;&lt;br /&gt;
      &amp;lt;/div&amp;gt;&lt;br /&gt;
      &amp;lt;% first_teammate_review_appeared = true %&amp;gt;&lt;br /&gt;
    &amp;lt;% end %&amp;gt;&lt;br /&gt;
&lt;br /&gt;
New code: Add conditions which check for the truthiness of ```@assignment.show_teammate_reviews``` and if the current user is a student to decide whether to render the table or not.  Since the existing code checks truthiness for the cases for which NOT to render a table, we have followed the existing style of the code.&lt;br /&gt;
&lt;br /&gt;
1) If type of view model is teammate review questionnaire, and current role is student, and if @assignment.show_teammate_reviews is false, then we don't render anything&lt;br /&gt;
2) If type of view model is teammate review questionnaire, and current role is student, but @assignment.show_teammate_reviews is true, then we don't render anything if the current reviewer_id is different to the currently logged in user.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    &amp;lt;% if (vm.questionnaire_display_type == &amp;quot;Metareview&amp;quot; or vm.questionnaire_display_type == &amp;quot;Author Feedback&amp;quot;) and @current_role_name.eql?'Student' %&amp;gt;&lt;br /&gt;
    &amp;lt;% elsif (&lt;br /&gt;
      vm.questionnaire_type == &amp;quot;TeammateReviewQuestionnaire&amp;quot; and&lt;br /&gt;
      @current_role_name.eql?'Student' and&lt;br /&gt;
      !@assignment.show_teammate_reviews&lt;br /&gt;
      ) %&amp;gt;&lt;br /&gt;
    &amp;lt;% elsif (&lt;br /&gt;
      vm.questionnaire_type == &amp;quot;TeammateReviewQuestionnaire&amp;quot; and &lt;br /&gt;
      @current_role_name.eql?'Student' and&lt;br /&gt;
      @assignment.show_teammate_reviews and current_user.id != vm.reviewee_id&lt;br /&gt;
      )%&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
New code: Finally, add a CSS class and a `data-reviewee_id` to keep track of the heatgrids when toggling visibility.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    &amp;lt;% else %&amp;gt;&lt;br /&gt;
        &amp;lt;% if vm.questionnaire_type == &amp;quot;TeammateReviewQuestionnaire&amp;quot; %&amp;gt;&lt;br /&gt;
          &amp;lt;div class=&amp;quot;teammate_table&amp;quot; data-reviewee_id=&amp;quot;&amp;lt;%= vm.reviewee_id %&amp;gt;&amp;quot;&amp;gt;&lt;br /&gt;
        &amp;lt;% else %&amp;gt;&lt;br /&gt;
          &amp;lt;div&amp;gt;&lt;br /&gt;
        &amp;lt;% end %&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''F.3  '''&lt;br /&gt;
&lt;br /&gt;
Old code: Existing code doesn't print the teammate who is being reviewed.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;!-- display the list of questions for this questionnaire --&amp;gt;&lt;br /&gt;
          &amp;lt;h4 style=&amp;quot;display:inline-block;&amp;quot;&amp;gt;&amp;lt;%= vm.questionnaire_display_type %&amp;gt;&lt;br /&gt;
            &amp;lt;% if vm.questionnaire_type == &amp;quot;ReviewQuestionnaire&amp;quot; %&amp;gt;&lt;br /&gt;
                (Round: &amp;lt;%= vm.round.to_s  %&amp;gt; of &amp;lt;%= vm.rounds.to_s  %&amp;gt;)&lt;br /&gt;
            &amp;lt;%end %&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
New code: If TeammteReviewQuestionnaire is used, then use the `:reviewee_name` method for VmQuestionResponse model to print the name of the student who is being reviewed.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;!-- display the list of questions for this questionnaire --&amp;gt;&lt;br /&gt;
          &amp;lt;h4 style=&amp;quot;display:inline-block;&amp;quot;&amp;gt;&amp;lt;%= vm.questionnaire_display_type %&amp;gt;&lt;br /&gt;
            &amp;lt;% if vm.questionnaire_type == &amp;quot;ReviewQuestionnaire&amp;quot; %&amp;gt;&lt;br /&gt;
                (Round: &amp;lt;%= vm.round.to_s  %&amp;gt; of &amp;lt;%= vm.rounds.to_s  %&amp;gt;)&lt;br /&gt;
            &amp;lt;% elsif vm.questionnaire_type == &amp;quot;TeammateReviewQuestionnaire&amp;quot; %&amp;gt;&lt;br /&gt;
                (For: &amp;lt;%= vm.reviewee_name(session[:ip]) %&amp;gt;)&lt;br /&gt;
            &amp;lt;%end %&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''F.4 '''&lt;br /&gt;
&lt;br /&gt;
Old code: Existing code doesn't inform the partial about the type of review being done&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;% vm.list_of_reviews.each do |review| %&amp;gt;&lt;br /&gt;
              &amp;lt;!-- instructors (or higher level users) see reviewer name, students see anonymized string --&amp;gt;&lt;br /&gt;
              &amp;lt;% if (['Student'].include? @current_role_name) &amp;amp;&amp;amp; @assignment.is_anonymous%&amp;gt;&lt;br /&gt;
                &amp;lt;%= render :partial =&amp;gt; 'add_icon_to_name', :locals =&amp;gt; {review: review, i: i} %&amp;gt;&lt;br /&gt;
              &amp;lt;% else %&amp;gt;&lt;br /&gt;
                  &amp;lt;% user_name = User.find(Participant.find(ResponseMap.find(Response.find(review.id).map_id).reviewer_id).user_id).fullname(session[:ip]).to_s %&amp;gt;&lt;br /&gt;
                &amp;lt;%= render :partial =&amp;gt; 'add_icon_to_name', :locals =&amp;gt; {review: review, i: i} %&amp;gt;&lt;br /&gt;
              &amp;lt;% end %&amp;gt;&lt;br /&gt;
              &amp;lt;% i += 1 %&amp;gt;&lt;br /&gt;
          &amp;lt;% end %&amp;gt;&lt;br /&gt;
New code: Passes the type of review being done to the partial, so it can decide on how to render the review title. Note: This code seems to use repetition, but since the conditional used here are accessing `Anonymous` assignments and checking for user roles, we have not modified this code, as it is not directly related to our scope.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;% vm.list_of_reviews.each do |review| %&amp;gt;&lt;br /&gt;
              &amp;lt;!-- instructors (or higher level users) see reviewer name, students see anonymized string --&amp;gt;&lt;br /&gt;
              &amp;lt;% if (['Student'].include? @current_role_name) &amp;amp;&amp;amp; @assignment.is_anonymous%&amp;gt;&lt;br /&gt;
                &amp;lt;%= render :partial =&amp;gt; 'add_icon_to_name', :locals =&amp;gt; {review: review, i: i, questionnaire_type: vm.questionnaire_type } %&amp;gt;&lt;br /&gt;
              &amp;lt;% else %&amp;gt;&lt;br /&gt;
                &amp;lt;% user_name = User.find(Participant.find(ResponseMap.find(Response.find(review.id).map_id).reviewer_id).user_id).fullname(session[:ip]).to_s %&amp;gt;&lt;br /&gt;
                &amp;lt;%= render :partial =&amp;gt; 'add_icon_to_name', :locals =&amp;gt; {review: review, i: i, questionnaire_type: vm.questionnaire_type } %&amp;gt;&lt;br /&gt;
              &amp;lt;% end %&amp;gt;&lt;br /&gt;
              &amp;lt;% i += 1 %&amp;gt;&lt;br /&gt;
          &amp;lt;% end %&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Old code: Contains a `metrics-1` column&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
          &amp;lt;th class=&amp;quot;sorter-true&amp;quot; align=&amp;quot;right&amp;quot; &amp;gt;&lt;br /&gt;
            Avg&amp;lt;span&amp;gt;&amp;lt;/span&amp;gt;&lt;br /&gt;
          &amp;lt;/th&amp;gt;&lt;br /&gt;
          &amp;lt;th class=&amp;quot;sorter-false&amp;quot;&amp;gt;&lt;br /&gt;
            &amp;lt;span  data-toggle=&amp;quot;tooltip&amp;quot; data-placement=&amp;quot;right&amp;quot; title=&amp;quot;A count of comments, for the respective question, which have word count &amp;gt; 10. The purpose of this metric is to represent how many comments for the question are of a substantial length to provide quality feedback.&amp;quot;&amp;gt;metric-1&amp;lt;/span&amp;gt;&lt;br /&gt;
          &amp;lt;/th&amp;gt;&lt;br /&gt;
        &amp;lt;/tr&amp;gt;&lt;br /&gt;
        &amp;lt;/thead&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
New code: As per discussion with mentor, this column has been removed in our PR.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
          &amp;lt;th class=&amp;quot;sorter-true&amp;quot; align=&amp;quot;right&amp;quot; &amp;gt;&lt;br /&gt;
            Avg&amp;lt;span&amp;gt;&amp;lt;/span&amp;gt;&lt;br /&gt;
          &amp;lt;/th&amp;gt;&lt;br /&gt;
        &amp;lt;/tr&amp;gt;&lt;br /&gt;
        &amp;lt;/thead&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''F.5 '''&lt;br /&gt;
&lt;br /&gt;
Old code: It creates the ID inline in multiple places, so if we decide to change the ID generation logic, we need to modify it in multiple places. (which happened when we started rendering multiple tables for each teammate).&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;% vm.list_of_rows.each do |row| %&amp;gt;&lt;br /&gt;
            &amp;lt;!-- notice the data-target. because we're toggling via looped code, we need to dynamically generate the identifier. --&amp;gt;&lt;br /&gt;
            &amp;lt;tr data-toggle=&amp;quot;collapse&amp;quot; class=&amp;quot;accordion-toggle&amp;quot; data-target=&amp;quot;#hid&amp;lt;%= row.question_id.to_s + vm.round.to_s %&amp;gt;&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
New code: Generate the unique HTML ID once, in a readable manner once. And conditionally make it more unique, if it is a TeammateReviewQuestionnaire, since jQuery code requires these IDs to be unique amongst different tables. If we don't make it more unique, then clicking on one teammate review table will toggle the table visibility for the first table. To prevent this &amp;quot;clashing&amp;quot;, we need to make these IDs more unique for a TeammateReviewQuestionnaire.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;% vm.list_of_rows.each do |row| %&amp;gt;&lt;br /&gt;
            &amp;lt;% target_id = &amp;quot;hid__#{row.question_id}__#{vm.round}&amp;quot; %&amp;gt;&lt;br /&gt;
            &amp;lt;% if vm.questionnaire_type == &amp;quot;TeammateReviewQuestionnaire&amp;quot; %&amp;gt;&lt;br /&gt;
              &amp;lt;%# Since we render different heatgrids with the same questions for each&lt;br /&gt;
              teammember, we need to distinguish the ID, based on the user for whom,&lt;br /&gt;
              the reviews have been created. %&amp;gt;&lt;br /&gt;
              &amp;lt;% target_id += &amp;quot;__#{vm.reviewee_id}&amp;quot; %&amp;gt;&lt;br /&gt;
            &amp;lt;% end%&amp;gt;&lt;br /&gt;
&lt;br /&gt;
            &amp;lt;!-- notice the data-target. because we're toggling via looped code, we need to dynamically generate the identifier. --&amp;gt;&lt;br /&gt;
            &amp;lt;tr data-toggle=&amp;quot;collapse&amp;quot; class=&amp;quot;accordion-toggle&amp;quot; data-target=&amp;quot;&amp;lt;%= &amp;quot;#&amp;quot; + target_id %&amp;gt;&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Old code: Written on a single line crossing 80 characters on a single line&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
              &amp;lt;% row.score_row.each do |score| %&amp;gt;&lt;br /&gt;
                  &amp;lt;% score_comment = score.comment.nil? ? '' : score.comment %&amp;gt; &amp;lt;!-- changing nil to null string to avoid Null Pointer Exception --&amp;gt;&lt;br /&gt;
                  &amp;lt;td class=&amp;quot;&amp;lt;%= score.color_code %&amp;gt;&amp;quot; align=&amp;quot;center&amp;quot; data-toggle=&amp;quot;tooltip&amp;quot; title=&amp;quot;&amp;lt;%= strip_tags(score.comment).html_safe%&amp;gt;&amp;quot;&amp;gt;&lt;br /&gt;
                    &amp;lt;span class=&amp;quot;&amp;lt;%=  underlined?(score) %&amp;gt;&amp;quot;&amp;gt;&amp;lt;%= score.score_value.to_s %&amp;gt;&amp;lt;/span&amp;gt;&lt;br /&gt;
                  &amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;% end %&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
New code: Make code more readable by indenting it and splitting it over multiple lines&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
              &amp;lt;!-- actual cells with scores and colored background. --&amp;gt;&lt;br /&gt;
              &amp;lt;% row.score_row.each do |score| %&amp;gt;&lt;br /&gt;
                  &amp;lt;% score_comment = score.comment.nil? ? '' : score.comment %&amp;gt;&lt;br /&gt;
                  &amp;lt;!-- changing nil to null string to avoid Null Pointer Exception --&amp;gt;&lt;br /&gt;
                  &amp;lt;td class=&amp;quot;&amp;lt;%= score.color_code %&amp;gt;&amp;quot; align=&amp;quot;center&amp;quot; data-toggle=&amp;quot;tooltip&amp;quot; title=&amp;quot;&amp;lt;%= strip_tags(score.comment).html_safe%&amp;gt;&amp;quot;&amp;gt;&lt;br /&gt;
                    &amp;lt;span class=&amp;quot;&amp;lt;%=  underlined?(score) %&amp;gt;&amp;quot;&amp;gt;&lt;br /&gt;
                      &amp;lt;%= score.score_value.to_s %&amp;gt;&lt;br /&gt;
                    &amp;lt;/span&amp;gt;&lt;br /&gt;
                  &amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;% end %&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''F.6 '''Removed the following code as it corresponds to the deleted column&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 &amp;lt;td  class = 'cf' align=&amp;quot;center&amp;quot;&amp;gt;&lt;br /&gt;
                &amp;lt;%= row.countofcomments.to_s %&amp;gt;&lt;br /&gt;
              &amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''F.7 '''&lt;br /&gt;
&lt;br /&gt;
Old code: Existing code just unconditionally prints the text &amp;quot;Review&amp;quot; followed by an index.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
                    &amp;lt;% for index in 0 .. row.score_row.length - 1 %&amp;gt;&lt;br /&gt;
                        &amp;lt;tr&amp;gt;&lt;br /&gt;
                          &amp;lt;td&amp;gt;Review &amp;lt;%=index + 1%&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
New code: Conditionally change the review text that is displayed based on the type of review and the access level of the user&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
                    &amp;lt;% for index in 0 .. row.score_row.length - 1 %&amp;gt;&lt;br /&gt;
                        &amp;lt;tr&amp;gt;&lt;br /&gt;
                          &amp;lt;% if @current_role_name.eql?'Student' or vm.questionnaire_type != &amp;quot;TeammateReviewQuestionnaire&amp;quot; %&amp;gt;&lt;br /&gt;
                            &amp;lt;%# Use Review {{index}} format for student view, and&lt;br /&gt;
                            when questionnaire_type is not teammatereview %&amp;gt;&lt;br /&gt;
                            &amp;lt;td&amp;gt;Review &amp;lt;%=index + 1%&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
                          &amp;lt;% else %&amp;gt;&lt;br /&gt;
                            &amp;lt;td&amp;gt;&lt;br /&gt;
                              &amp;lt;% reviewer_id = row.score_row[index].reviewer_id %&amp;gt;&lt;br /&gt;
                              &amp;lt;% fullname = Participant.find_by(id: reviewer_id).fullname(session[:ip]) %&amp;gt;&lt;br /&gt;
                              Review by &amp;lt;%= fullname %&amp;gt;&lt;br /&gt;
                            &amp;lt;/td&amp;gt;&lt;br /&gt;
                          &amp;lt;% end%&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====G. In spec/controllers/grades_controller_spec.rb:====&lt;br /&gt;
&lt;br /&gt;
'''G.1 '''&lt;br /&gt;
&lt;br /&gt;
Old code&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
before(:each) do&lt;br /&gt;
  allow(AssignmentParticipant).to receive(:find).with('1').and_return(participant)&lt;br /&gt;
  allow(participant).to receive(:team).and_return(team)&lt;br /&gt;
  stub_current_user(instructor, instructor.role.name, instructor.role)&lt;br /&gt;
  allow(Assignment).to receive(:find).with('1').and_return(assignment)&lt;br /&gt;
@@ -91,29 +90,106 @@&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
New code&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
before(:each) do&lt;br /&gt;
  allow(participant).to receive(:team).and_return(team)&lt;br /&gt;
  stub_current_user(instructor, instructor.role.name, instructor.role)&lt;br /&gt;
  allow(Assignment).to receive(:find).with('1').and_return(assignment)&lt;br /&gt;
@@ -91,29 +90,106 @@&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''G.2 '''Remove xdescribe '#view_team' and change describe '#view_team' as follows.&lt;br /&gt;
&lt;br /&gt;
Old code&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
describe '#view_team' do&lt;br /&gt;
render_views&lt;br /&gt;
context 'when view_team page is viewed by a student who is also a TA for another course' do&lt;br /&gt;
  it 'renders grades#view_team page' do&lt;br /&gt;
    allow(participant).to receive(:team).and_return(team)&lt;br /&gt;
    allow(AssignmentQuestionnaire).to receive(:find_by).with(assignment_id: 1, questionnaire_id: 1).and_return(assignment_questionnaire)&lt;br /&gt;
    allow(AssignmentQuestionnaire).to receive(:where).with(any_args).and_return([assignment_questionnaire])&lt;br /&gt;
    allow(assignment).to receive(:late_policy_id).and_return(false)&lt;br /&gt;
    allow(assignment).to receive(:calculate_penalty).and_return(false)&lt;br /&gt;
    allow(assignment).to receive(:compute_total_score).with(any_args).and_return(100)&lt;br /&gt;
    allow(review_questionnaire).to receive(:get_assessments_round_for).with(participant, 1).and_return([review_response])&lt;br /&gt;
    allow(Answer).to receive(:compute_scores).with([review_response], [question]).and_return(max: 95, min: 88, avg: 90)&lt;br /&gt;
    params = {id: 1}&lt;br /&gt;
    allow(TaMapping).to receive(:exists?).with(ta_id: 1, course_id: 1).and_return(true)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
New code&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
describe '#view_team' do&lt;br /&gt;
render_views&lt;br /&gt;
&lt;br /&gt;
# All stubs and factories are instantiated within this scope so as to not &lt;br /&gt;
# clash with other broken test.&lt;br /&gt;
# The names of the factories created for testing view_team&lt;br /&gt;
# have `_vt` suffix ```where necessary``` to differentiate them from &lt;br /&gt;
# the above declared factories&lt;br /&gt;
&lt;br /&gt;
let(:student1_vt) { create(:student, name: &amp;quot;barry&amp;quot;, id: 12) }&lt;br /&gt;
let(:student2_vt) { create(:student, name: &amp;quot;iris&amp;quot;, id: 13) }&lt;br /&gt;
&lt;br /&gt;
let(:tm_questionnaire) {&lt;br /&gt;
  build(&lt;br /&gt;
    :teammate_review_questionnaire,&lt;br /&gt;
    id: 12,&lt;br /&gt;
    questions: [question],&lt;br /&gt;
    max_question_score: 5&lt;br /&gt;
  )&lt;br /&gt;
}&lt;br /&gt;
let(:assignment_vt) {&lt;br /&gt;
  create(:assignment, id: 6, max_team_size: 2,&lt;br /&gt;
  questionnaires: [tm_questionnaire])&lt;br /&gt;
}&lt;br /&gt;
let(:assignment_questionnaire_vt) {&lt;br /&gt;
  create(:tm_assignment_questionnaire, id: 12, used_in_round: nil,&lt;br /&gt;
  assignment: assignment_vt, questionnaire: tm_questionnaire) }&lt;br /&gt;
let(:team_vt) { create(:assignment_team, id: 12,&lt;br /&gt;
assignment: assignment_vt) }&lt;br /&gt;
let(:participant_vt) { create(:participant, id: 12,&lt;br /&gt;
  assignment: assignment_vt, user_id: student1_vt.id) }&lt;br /&gt;
let(:participant2_vt) { create(:participant, id: 13,&lt;br /&gt;
  assignment: assignment_vt, user_id: student2_vt.id) }&lt;br /&gt;
&lt;br /&gt;
before(:each) do&lt;br /&gt;
  # Need to stub this method so the factory instance with&lt;br /&gt;
  # the stubbed :team method is returned by :find&lt;br /&gt;
  # instead of a separate instance with the same data&lt;br /&gt;
  allow(AssignmentParticipant)&lt;br /&gt;
    .to receive(:find)&lt;br /&gt;
    .with(participant_vt.id.to_s)&lt;br /&gt;
    .and_return(participant_vt)&lt;br /&gt;
  allow(participant_vt).to receive(:team).and_return(team_vt)&lt;br /&gt;
  allow(team_vt).to receive(:participants).and_return([participant_vt, participant2_vt])&lt;br /&gt;
  allow(AssignmentQuestionnaire)&lt;br /&gt;
    .to receive(:find_by)&lt;br /&gt;
    .with(assignment_id: assignment_vt.id, questionnaire_id: tm_questionnaire.id)&lt;br /&gt;
    .and_return(assignment_questionnaire_vt)&lt;br /&gt;
  allow(AssignmentQuestionnaire)&lt;br /&gt;
    .to receive(:find_by)&lt;br /&gt;
    .with(assignment_id: assignment.id, questionnaire_id: review_questionnaire.id)&lt;br /&gt;
    .and_return(assignment_questionnaire_vt)&lt;br /&gt;
  allow(AssignmentQuestionnaire)&lt;br /&gt;
    .to receive(:where)&lt;br /&gt;
    .with(any_args)&lt;br /&gt;
    .and_return([assignment_questionnaire_vt])&lt;br /&gt;
  allow(assignment_vt)&lt;br /&gt;
    .to receive(:late_policy_id)&lt;br /&gt;
    .and_return(false)&lt;br /&gt;
  allow(assignment_vt)&lt;br /&gt;
    .to receive(:calculate_penalty)&lt;br /&gt;
    .and_return(false)&lt;br /&gt;
  allow(assignment_vt)&lt;br /&gt;
    .to receive(:compute_total_score)&lt;br /&gt;
    .with(any_args)&lt;br /&gt;
    .and_return(100)&lt;br /&gt;
  allow(review_questionnaire).to receive(:get_assessments_round_for).with(participant, 1).and_return([review_response])&lt;br /&gt;
  allow(Answer).to receive(:compute_scores).with([review_response], [question]).and_return(max: 95, min: 88, avg: 90)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
 it 'renders grades#view_team page' do&lt;br /&gt;
  params = {id: participant_vt.id}&lt;br /&gt;
  get :view_team, params&lt;br /&gt;
  expect(response).to render_template(:view_team)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
context 'when view_team page is opened by student' do&lt;br /&gt;
  it 'dropdown is not rendered' do&lt;br /&gt;
    session = { user: student1_vt }&lt;br /&gt;
    params = {id: participant_vt.id}&lt;br /&gt;
    stub_current_user(student1_vt, student1_vt.role.name, student1_vt.role)&lt;br /&gt;
    get :view_team, params&lt;br /&gt;
    expect(response.body).to_not have_selector('select')&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
context 'when view_team page is opened by instructor' do&lt;br /&gt;
  it 'dropdown is rendered' do&lt;br /&gt;
    session = { user: instructor }&lt;br /&gt;
    params = {id: participant_vt.id}&lt;br /&gt;
    get :view_team, params&lt;br /&gt;
    expect(response.body).to have_selector('select')&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
context 'when view_team page is viewed by a student who is also a TA for another course' do&lt;br /&gt;
  it 'renders grades#view_team page' do&lt;br /&gt;
    params = { id: participant_vt.id }&lt;br /&gt;
    allow(TaMapping).to receive(:exists?).with(ta_id: participant_vt.user_id, course_id: 1).and_return(true)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
====H. In spec/factories/factories.rb:====&lt;br /&gt;
&lt;br /&gt;
'''H.1 '''Add the following factory:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
factory :teammate_review_questionnaire, class: TeammateReviewQuestionnaire do&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''H.2 '''Add another factory&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
factory :tm_assignment_questionnaire, class: AssignmentQuestionnaire do&lt;br /&gt;
  user_id 1&lt;br /&gt;
  questionnaire { association(:teammate_review_questionnaire) }&lt;br /&gt;
  questionnaire_weight 100&lt;br /&gt;
  used_in_round nil&lt;br /&gt;
  topic_id nil&lt;br /&gt;
  dropdown 1&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Testing ==&lt;br /&gt;
The tests written as a part of this project can be run by running the following command on terminal:&lt;br /&gt;
&lt;br /&gt;
1. rspec ./spec/controllers/grades_controller_spec.rb  -e &amp;quot;#view_team&amp;quot;&lt;br /&gt;
&lt;br /&gt;
2. rspec .vm_question_response_score_cell_spec.rb  -e &amp;quot;#reviewer_id&amp;quot;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''OLD STATUS'''&lt;br /&gt;
&lt;br /&gt;
1. Earlier, the tests contained an xdescribe test to check if the view_team page is rendered correctly. However, this test was being skipped as this was an xdescribe segment. There was another test for when the view_team page is accessed by a student who is also a TA for another course. This can be checked [https://github.com/expertiza/expertiza/blob/beta/spec/controllers/grades_controller_spec.rb here].&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 xdescribe '#view_team' do&lt;br /&gt;
    it 'renders grades#view_team page' do&lt;br /&gt;
      allow(participant).to receive(:team).and_return(team)&lt;br /&gt;
      params = {id: 1}&lt;br /&gt;
      get :view_team, params&lt;br /&gt;
      expect(response).to render_template(:view_team)&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  describe '#view_team' do&lt;br /&gt;
    render_views&lt;br /&gt;
    context 'when view_team page is viewed by a student who is also a TA for another course' do&lt;br /&gt;
      it 'renders grades#view_team page' do&lt;br /&gt;
        allow(participant).to receive(:team).and_return(team)&lt;br /&gt;
        allow(AssignmentQuestionnaire).to receive(:find_by).with(assignment_id: 1, questionnaire_id: 1).and_return(assignment_questionnaire)&lt;br /&gt;
        allow(AssignmentQuestionnaire).to receive(:where).with(any_args).and_return([assignment_questionnaire])&lt;br /&gt;
        allow(assignment).to receive(:late_policy_id).and_return(false)&lt;br /&gt;
        allow(assignment).to receive(:calculate_penalty).and_return(false)&lt;br /&gt;
        allow(assignment).to receive(:compute_total_score).with(any_args).and_return(100)&lt;br /&gt;
        allow(review_questionnaire).to receive(:get_assessments_round_for).with(participant, 1).and_return([review_response])&lt;br /&gt;
        allow(Answer).to receive(:compute_scores).with([review_response], [question]).and_return(max: 95, min: 88, avg: 90)&lt;br /&gt;
        params = {id: 1}&lt;br /&gt;
        allow(TaMapping).to receive(:exists?).with(ta_id: 1, course_id: 1).and_return(true)&lt;br /&gt;
        stub_current_user(ta, ta.role.name, ta.role)&lt;br /&gt;
        get :view_team, params&lt;br /&gt;
        expect(response.body).not_to have_content &amp;quot;TA&amp;quot;&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''NEW STATUS'''&lt;br /&gt;
&lt;br /&gt;
1. The view_team page is rendered correctly for a given student or an instructor. This can be checked in [https://github.com/expertiza/expertiza/blob/66239d9a8a53697ea170a92208593b36d06dfd24/spec/controllers/grades_controller_spec.rb this] file.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    it 'renders grades#view_team page' do&lt;br /&gt;
      params = {id: participant_vt.id}&lt;br /&gt;
      get :view_team, params&lt;br /&gt;
      expect(response).to render_template(:view_team)&lt;br /&gt;
    end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
2. When students access then the view_team page, the dropdown to select a student's teammate reviews is not rendered on the page. The dropdown is rendered if the page is accessed by an instructor. This can be checked in [https://github.com/expertiza/expertiza/blob/66239d9a8a53697ea170a92208593b36d06dfd24/spec/controllers/grades_controller_spec.rb this] file.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
   context 'dropdown for selecting a teammate review' do&lt;br /&gt;
    render_views&lt;br /&gt;
      it 'is not rendered is not rendered when page is opened by student' do&lt;br /&gt;
        session = { user: student1_vt }&lt;br /&gt;
        params = {id: participant_vt.id}&lt;br /&gt;
        stub_current_user(student1_vt, student1_vt.role.name, student1_vt.role)&lt;br /&gt;
        get :view_team, params&lt;br /&gt;
        expect(response.body).to_not have_selector('select')&lt;br /&gt;
      end&lt;br /&gt;
&lt;br /&gt;
      it 'is rendered when page is opened by instructor' do&lt;br /&gt;
        session = { user: instructor }&lt;br /&gt;
        params = {id: participant_vt.id}&lt;br /&gt;
        get :view_team, params&lt;br /&gt;
        expect(response.body).to have_selector('select')&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
3. When a student who is also a TA for another course access the view_team page, that student should be able to a student's view to the page. This can be checked in [https://github.com/expertiza/expertiza/blob/66239d9a8a53697ea170a92208593b36d06dfd24/spec/controllers/grades_controller_spec.rb this] file.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    context 'when view_team page is viewed by a student who is also a TA for another course' do&lt;br /&gt;
      it 'renders grades#view_team page' do&lt;br /&gt;
        params = { id: participant_vt.id }&lt;br /&gt;
        allow(TaMapping).to receive(:exists?).with(ta_id: participant_vt.user_id, course_id: 1).and_return(true)&lt;br /&gt;
        stub_current_user(ta, ta.role.name, ta.role)&lt;br /&gt;
        get :view_team, params&lt;br /&gt;
        expect(response.body).not_to have_content &amp;quot;TA&amp;quot;&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
4. If show_teammate_reviews boolean is set to False, then the student should not be able to see the teammate reviews given to him/her. An instructor can still see the teammate reviews. This can be checked in [https://github.com/expertiza/expertiza/blob/66239d9a8a53697ea170a92208593b36d06dfd24/spec/controllers/grades_controller_spec.rb this] file.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    context 'when assignment(show reviews) value is unchecked' do&lt;br /&gt;
      before(:each) do&lt;br /&gt;
        allow(assignment_vt).to receive(:show_teammate_reviews).and_return(false) &lt;br /&gt;
      end&lt;br /&gt;
      it 'Student cannot view his score' do&lt;br /&gt;
        session = { user: student1_vt }&lt;br /&gt;
        params = {id: participant_vt.id}&lt;br /&gt;
        stub_current_user(student1_vt, student1_vt.role.name, student1_vt.role)&lt;br /&gt;
        get :view_team, params&lt;br /&gt;
        expect(response.body).to_not have_selector(&amp;quot;.teammate_table[data-reviewee_id=\&amp;quot;#{participant_vt.id}\&amp;quot;]&amp;quot;)&lt;br /&gt;
        expect(response.body).to_not have_selector(&amp;quot;.teammate_table[data-reviewee_id=\&amp;quot;#{participant2_vt.id}\&amp;quot;]&amp;quot;)&lt;br /&gt;
      end&lt;br /&gt;
&lt;br /&gt;
      it 'Instructor can view the student score' do        &lt;br /&gt;
        params = {id: participant_vt.id}        &lt;br /&gt;
        get :view_team, params&lt;br /&gt;
        expect(response.body).to have_selector(&amp;quot;.teammate_table[data-reviewee_id=\&amp;quot;#{participant_vt.id}\&amp;quot;]&amp;quot;)&lt;br /&gt;
        expect(response.body).to have_selector(&amp;quot;.teammate_table[data-reviewee_id=\&amp;quot;#{participant2_vt.id}\&amp;quot;]&amp;quot;)&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
5. If show_teammate_reviews boolean is set to True, then both the student should and instructor should be able to see the teammate reviews. The student should see only the reviews received by him/her. The instructor should be able to see all student's teammate reviews. This can be checked in [https://github.com/expertiza/expertiza/blob/66239d9a8a53697ea170a92208593b36d06dfd24/spec/controllers/grades_controller_spec.rb this] file.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
    context 'when assignment(show reviews) value is checked' do&lt;br /&gt;
      it 'Student can view his score' do&lt;br /&gt;
        session = { user: student1_vt }&lt;br /&gt;
        params = {id: participant_vt.id}&lt;br /&gt;
        stub_current_user(student1_vt, student1_vt.role.name, student1_vt.role)&lt;br /&gt;
        get :view_team, params&lt;br /&gt;
        expect(response.body).to have_selector(&amp;quot;.teammate_table[data-reviewee_id=\&amp;quot;#{participant_vt.id}\&amp;quot;]&amp;quot;)&lt;br /&gt;
        expect(response.body).to_not have_selector(&amp;quot;.teammate_table[data-reviewee_id=\&amp;quot;#{participant2_vt.id}\&amp;quot;]&amp;quot;)&lt;br /&gt;
      end&lt;br /&gt;
&lt;br /&gt;
      it 'Instructor can view the student score' do        &lt;br /&gt;
        params = {id: participant_vt.id}        &lt;br /&gt;
        get :view_team, params&lt;br /&gt;
        expect(response.body).to have_selector(&amp;quot;.teammate_table[data-reviewee_id=\&amp;quot;#{participant_vt.id}\&amp;quot;]&amp;quot;)&lt;br /&gt;
        expect(response.body).to have_selector(&amp;quot;.teammate_table[data-reviewee_id=\&amp;quot;#{participant2_vt.id}\&amp;quot;]&amp;quot;)&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
6. The reviewer id is tracked correctly to show the correct reviewer name in the teammate reviews table. This can be checked in [https://github.com/expertiza/expertiza/blob/66239d9a8a53697ea170a92208593b36d06dfd24/spec/models/vm_question_response_score_cell_spec.rb this] file &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  	describe '#reviewer_id' do&lt;br /&gt;
  		it 'returns reviewer id' do&lt;br /&gt;
			allow(ResponseMap).to receive(:find).with(1).and_return(review_response_map)&lt;br /&gt;
			allow(response).to receive(:populate_new_response).with(:review_response_map, &amp;quot;0&amp;quot;).and_return(response)&lt;br /&gt;
        	expect(response.id).to eq(1)	&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Summary of file changes ==&lt;br /&gt;
&lt;br /&gt;
The following files are modified:&lt;br /&gt;
&lt;br /&gt;
1. app/controllers/grades_controller.rb - Controller file which changed how the view model is populated&lt;br /&gt;
&lt;br /&gt;
2. app/views/grades/view_team.html.erb - View file, which  conditionally rendered the teammate name, for a teammate review heatgrid&lt;br /&gt;
&lt;br /&gt;
3. spec/controllers/grades_controller_spec.rb - For tests verifying the proposed changes&lt;br /&gt;
&lt;br /&gt;
4. app/models/vm_question_response.rb - To modify the view-model so it can tell us the name of the person being reviewed for the current heatgrid&lt;br /&gt;
&lt;br /&gt;
5. app/models/vm_question_response_score_cell.rb - &lt;br /&gt;
&lt;br /&gt;
6. app/assets/stylesheets/grades.scss - &lt;br /&gt;
&lt;br /&gt;
7. app/views/grades/_add_icon_to_name.html.erb - &lt;br /&gt;
&lt;br /&gt;
8. spec/factories/factories.rb -&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Design Patterns ==&lt;br /&gt;
&lt;br /&gt;
Existing code does not use any design patterns, apart from if-else. It uses if-else conditional statements to check what type of questionnaire is present in the viewmodel `VmQuestionResponse`, and based on that, it renders the appropriate content.&lt;br /&gt;
&lt;br /&gt;
We decided to continue with this approach since to change the present coding style, there were required many changes (refactoring) to many files which were out of the scope of the present project. To complete the project in the assigned time, we followed the if-else approach.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==References==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;https://expertiza.ncsu.edu/&amp;lt;/p&amp;gt;&lt;/div&gt;</summary>
		<author><name>Vdeshmu</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2021_-_E2165._Fix_teammate-review_view&amp;diff=141756</id>
		<title>CSC/ECE 517 Fall 2021 - E2165. Fix teammate-review view</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2021_-_E2165._Fix_teammate-review_view&amp;diff=141756"/>
		<updated>2021-11-28T19:20:17Z</updated>

		<summary type="html">&lt;p&gt;Vdeshmu: /* Changes made to the code are shown below. Every change is shown and explained separately */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Team Introduction ==&lt;br /&gt;
&lt;br /&gt;
Dr. Edward Gehringer (instructor), Parimal Mehta (mentor)&lt;br /&gt;
&lt;br /&gt;
1. Anjali Garg (unity ID : agarg25)&lt;br /&gt;
&lt;br /&gt;
2. Arvasu Chikara (unity ID: achikar2)&lt;br /&gt;
&lt;br /&gt;
3. Lalit Bangad (unity ID: llbangad)&lt;br /&gt;
&lt;br /&gt;
4. Vinay Deshmukh (unity ID: vdeshmu)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Problems to be addressed ==&lt;br /&gt;
&lt;br /&gt;
After a project is submitted and reviewed, both the team members (students) and instructors should be able to view the teammate reviews. Students should be able to view the reviews by going to a particular assignment's -&amp;gt; your scores, at the bottom of the page. An instructor can view the teammate reviews by going to assignments -&amp;gt; assignment -&amp;gt; particular team's submission -&amp;gt; view submission -&amp;gt; assign grades -&amp;gt; view scores. &lt;br /&gt;
&lt;br /&gt;
In the case of the instructor, a single heat grid is shown whereas in the case of a team member, we cant view the scores. In the heat grid, it is not clear if the scores visible are for the reviews that the student has *written* for their teammates or the scores that the student has *received* from their teammates. Additionally, for instructors can choose from a list of the students on the team, but they have no way to tell whether the heat grid shows the reviews done *by* that student or done *for* that student.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Methodology Overview ==&lt;br /&gt;
&lt;br /&gt;
We have divided our work in the following tasks to address the above problems:&lt;br /&gt;
&lt;br /&gt;
1. Distinguish reviews done for a student by rendering separates heatgrids for each student&lt;br /&gt;
&lt;br /&gt;
2. For instructors, the table will have sections based on the students&lt;br /&gt;
&lt;br /&gt;
3. Include a checkbox on the edit assignment page that enables/disables visibility of heat grid to students&lt;br /&gt;
&lt;br /&gt;
4. Fix the average column for a table (which breaks for some reviews)&lt;br /&gt;
&lt;br /&gt;
5. Show a composite score derived from all reviews.  Make this code generalized, so other kinds of heat grid views could use it.&lt;br /&gt;
&lt;br /&gt;
6. Changes should work even in an anonymized view&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Motivations ==&lt;br /&gt;
&lt;br /&gt;
1. Enable users to clearly tell which reviews are done by them, and which reviews are done for them.&lt;br /&gt;
&lt;br /&gt;
2. Code should be generic so it can be used for different types of heat grids as well.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Control Flow to access the concerned screens ==&lt;br /&gt;
'''1. For instructor (Log in as an instructor):-'''&lt;br /&gt;
&lt;br /&gt;
Screen after logging in by the instructor&lt;br /&gt;
[[File:ss1.png |border|1000px|center]]&lt;br /&gt;
Got to assignments on the Manage menu &lt;br /&gt;
[[File:ss2.png |border|1000px|center]]&lt;br /&gt;
Go to assignments&lt;br /&gt;
[[File:ss3.png |border|1000px|center]]&lt;br /&gt;
Go to submissions for any assignment&lt;br /&gt;
[[File:ss4a.png |border|1000px|center]]&lt;br /&gt;
Go to Assign Grade&lt;br /&gt;
[[File:ss5a.png |border|1000px|center]]&lt;br /&gt;
You will land on the page where the changes are made and can be reviewed&lt;br /&gt;
[[File:ss7a.png |border|1000px|center]]&lt;br /&gt;
&lt;br /&gt;
'''2. Student:- (Instructor impersonating a student)'''&lt;br /&gt;
&lt;br /&gt;
After landing on the assignments page, select any student from an assignment as shown below&lt;br /&gt;
[[File:ss6a.png |border|1000px|center]]&lt;br /&gt;
Go to/Select any assignment&lt;br /&gt;
[[File:ss9a.png |border|1000px|center]]&lt;br /&gt;
Go to your scores&lt;br /&gt;
[[File:ss10a.png |border|1000px|center]]&lt;br /&gt;
You will land on the page where the changes are made and can be reviewed&lt;br /&gt;
[[File:ss11a.png |border|1000px|center]]&lt;br /&gt;
&lt;br /&gt;
== Old Status of the application ==&lt;br /&gt;
&lt;br /&gt;
'''1. Instructor's view of teammate review''': This is the current screen given to the instructor. Here we see that the instructor can not determine who has given which review to which student in a team.&lt;br /&gt;
&lt;br /&gt;
[[File:Instructor-view-1.png|border| 700px |center|alt=The proposed expanded student display.|The proposed expanded student display.]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''2. Student's view of teammate review''': Currently, a student is not able to see what grades were given by their teammates. We need to implement that functionality so that the student is able to view those grades.&lt;br /&gt;
&lt;br /&gt;
[[File:Student-view-2.png|border| 700px |center|alt=The current instructor view.|The current review display for instructors.]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''3. Error in existing UI for student''': In the existing UI for a student, the highlighted block should not be rendered. This part of the screen is meant for the instructors/TAs. &lt;br /&gt;
&lt;br /&gt;
[[File:Wrong render for student.png|border|700px|center|alt=Existing UI for student|Existing UI for student.]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Proposed changes ==&lt;br /&gt;
&lt;br /&gt;
''' 1) Proposed UI for instructor ''': The instructor is able to see the score for all teammates. In the existing code, only one teammate's scores are being shown. But, we are planning to change the way the (VmQuestionResponse array is populated)[https://github.com/expertiza/expertiza/blob/master/app/controllers/grades_controller.rb#L114], so that the scores for all teammates are appended to it so it correctly shows what should have already been shown in this screen for the instructor.&lt;br /&gt;
&lt;br /&gt;
[[File:Proposed_screen.png|border|700px|center|alt=Proposed UI for instructor|Proposed UI for instructor.]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Note: When a student visits this screen, they will only be shown the reviews received by them, assuming the instructor has allowed visibility of teammate reviews to students.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
''' 2) Show detailed review for a particular question''': The instructor can see detailed review given to a student by their teammates by clicking on a particular question number in the table.&lt;br /&gt;
&lt;br /&gt;
[[File:ss12a.png|border|700px|center|alt=New UI for students|New UI for students ]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
''' 3) Show teammate review to student UI ''': The existing code doesn't render a student's teammate review scores at all. We are planning to render the scores to a student (as shown below) when they visit this screen. However, the visibility of this screen is contingent on whether the instructor has allowed visibility of the teammate review screen to students. If the instructor has disabled this feature, then the heatgrid will not be displayed at all.&lt;br /&gt;
&lt;br /&gt;
[[File:UI_for_student.png|border|700px|center|alt=New UI for students|New UI for students ]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== User Stories ==&lt;br /&gt;
&lt;br /&gt;
1. As an instructor, I can view what reviews one teammate has given to other teammates.&lt;br /&gt;
&lt;br /&gt;
2. As a student, I can view what reviews my teammates have given to me.&lt;br /&gt;
&lt;br /&gt;
3. As an instructor, I can choose if I want to see all student's teammates reviews together or one by one.&lt;br /&gt;
&lt;br /&gt;
4. As a student, if I am also a TA for another subject, I should not be able to see an instructor's view to the view_team page.&lt;br /&gt;
&lt;br /&gt;
5. As an instructor, I should be able to see the name of the reviewers for the reviews to a particular student.&lt;br /&gt;
&lt;br /&gt;
== Use case diagram for the system ==  &lt;br /&gt;
&lt;br /&gt;
[[File:vie_team_use_case.png|border|center]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Models used / Explanation of fixes ==&lt;br /&gt;
&lt;br /&gt;
The below diagram illustrates the proposed code change for showing all team members with the teammate review data to an instructor. The existing code only iterated on the `Participant` whose ID is present in the URL of the page. To fix this, we will iterate over all teammates of the given participant so that all teammate reviews for all team members are shown to the instructor.&lt;br /&gt;
&lt;br /&gt;
[[File:Logic e2165.png|border|center|alt=Flow diagram of proposed changes for showing team review data to instructor]]&lt;br /&gt;
&lt;br /&gt;
===Changes made to the code are shown below. Every change is shown and explained separately===&lt;br /&gt;
&lt;br /&gt;
====A. Added the following to app/assets/stylesheets/grades.scss:====&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    .teammate_table.hidden {&lt;br /&gt;
      display: none;&lt;br /&gt;
      }&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
====B. In app/controllers/grades_controller.rb: ====&lt;br /&gt;
&lt;br /&gt;
'''B.1:'''&lt;br /&gt;
&lt;br /&gt;
Old code: The existing code does not differentiate when adding a view model for the TeammateReview questionnaire&lt;br /&gt;
  questionnaires.each do |questionnaire|&lt;br /&gt;
     ...&lt;br /&gt;
     @vmlist &amp;lt;&amp;lt; populate_view_model(questionnaire)&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
New code: Since the current page URL contains an ID for the participant, from which we get an assignment, which gives us a list of questionnaires, we need to iterate all participants for a `TeammateReveiwQuestionnaire` questionnaire, so that we get the heatgrid view models for all members of a team.&lt;br /&gt;
  questionnaires.each do |questionnaire|&lt;br /&gt;
     ...&lt;br /&gt;
     if questionnaire.type == &amp;quot;TeammateReviewQuestionnaire&amp;quot;&lt;br /&gt;
        # as teammate review will be different for each participant&lt;br /&gt;
        # we need to create a separate table for each teammate&lt;br /&gt;
        @participant.team.participants.each do |team_participant|&lt;br /&gt;
          @vmlist &amp;lt;&amp;lt; populate_view_model(team_participant, questionnaire, @team)&lt;br /&gt;
        end&lt;br /&gt;
      else&lt;br /&gt;
        # only one participant needs iterating, as apart from teammatereview&lt;br /&gt;
        # all other reviews are at &amp;quot;team&amp;quot; level&lt;br /&gt;
        @vmlist &amp;lt;&amp;lt; populate_view_model(@participant, questionnaire, @team)&lt;br /&gt;
      end&lt;br /&gt;
   end&lt;br /&gt;
&lt;br /&gt;
'''B.2: '''&lt;br /&gt;
&lt;br /&gt;
Old code: This code uses @participant as an instance variable, but this structure will not work as we need to call this ViewModel with multiple participants when iterating for a teammate review questionnaire.&lt;br /&gt;
    def populate_view_model(questionnaire)&lt;br /&gt;
      vm = VmQuestionResponse.new(questionnaire, @assignment, @round)&lt;br /&gt;
      vmquestions = questionnaire.questions&lt;br /&gt;
      vm.add_questions(vmquestions)&lt;br /&gt;
      vm.add_team_members(@team)&lt;br /&gt;
      vm.add_reviews(@participant, @team, @assignment.vary_by_round)&lt;br /&gt;
      vm.number_of_comments_greater_than_10_words&lt;br /&gt;
      vm &lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
New code: We need to call this function with a separate participant in each invocation due to our change for TeammateReviewQuestionnaire, hence it makes sense to make `participant` as an argument to this function. Similarly, as `team` is a closely related model to `participant`, we are passing it as an argument, to keep this function as &amp;quot;pure&amp;quot; as possible.&lt;br /&gt;
    def populate_view_model(participant, questionnaire, team)&lt;br /&gt;
      ...&lt;br /&gt;
      vm.add_team_members(team)&lt;br /&gt;
      vm.add_reviews(participant, team, @assignment.vary_by_round)&lt;br /&gt;
      ...&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
====C. In app/models/vm_question_response.rb:====&lt;br /&gt;
&lt;br /&gt;
'''C.1: '''Added the reviewee_id method: Created a helper method within the VmQuestionReponse model to retrieve the `reviewee_id` for a heatgrid&lt;br /&gt;
&lt;br /&gt;
    def reviewee_id&lt;br /&gt;
      @participant_who_is_reviewee.user_id&lt;br /&gt;
    end &lt;br /&gt;
&lt;br /&gt;
'''C.2: '''Added the reviewee_name method: Created a helper method within the VmQuestionReponse model to retrieve the name of the student who is being reviewed for a heatgrid. This method uses the functionality to anonymize the name when we are in anonymized view.&lt;br /&gt;
&lt;br /&gt;
    def reviewee_name(ip_address = nil)&lt;br /&gt;
      part = @participant_who_is_reviewee&lt;br /&gt;
      User.find_by(id: part.user_id).fullname(ip_address)&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
'''C.3: '''&lt;br /&gt;
&lt;br /&gt;
Old code: Does not keep track of the student being reviewed&lt;br /&gt;
    elsif @questionnaire_type == &amp;quot;TeammateReviewQuestionnaire&amp;quot;&lt;br /&gt;
      reviews = participant.teammate_reviews&lt;br /&gt;
      reviews.each do |review|&lt;br /&gt;
        review_mapping = TeammateReviewResponseMap.find_by(id: review.map_id)&lt;br /&gt;
        participant = Participant.find(review_mapping.reviewer_id)&lt;br /&gt;
&lt;br /&gt;
New code: Add an instance variable to keep track of the student who is being reviewed in this VmQuestionReponse&lt;br /&gt;
    elsif @questionnaire_type == &amp;quot;TeammateReviewQuestionnaire&amp;quot;&lt;br /&gt;
      reviews = participant.teammate_reviews&lt;br /&gt;
      @participant_who_is_reviewee = participant&lt;br /&gt;
      reviews.each do |review|&lt;br /&gt;
        review_mapping = TeammateReviewResponseMap.find_by(id: review.map_id)&lt;br /&gt;
        participant = Participant.find(review_mapping.reviewer_id)&lt;br /&gt;
&lt;br /&gt;
'''C.4: '''&lt;br /&gt;
&lt;br /&gt;
Old code: Existing VmQuestionReponseScoreCell keeps no information about the reviewer, as it only stores the answer score&lt;br /&gt;
    row.score_row.push(VmQuestionResponseScoreCell.new(answer.answer, color_code, answer.comments, vm_tag_prompts))&lt;br /&gt;
&lt;br /&gt;
New code: Keep track of the response ID, so that we can retrieve the user ID for the reviewer in the model to use in the view file.&lt;br /&gt;
    &lt;br /&gt;
    row.score_row.push(VmQuestionResponseScoreCell.new(answer.answer, color_code, answer.comments, vm_tag_prompts, answer.response_id))&lt;br /&gt;
&lt;br /&gt;
====D. In app/models/vm_question_response_score_cell.rb:====&lt;br /&gt;
&lt;br /&gt;
'''D.1: '''In the method initialize of class VmQuestionResponseScoreCell&lt;br /&gt;
&lt;br /&gt;
Old code: Existing code doesn't keep track of the response id&lt;br /&gt;
    def initialize(score_value, color_code, comments, vmprompts = nil)&lt;br /&gt;
      @score_value = score_value&lt;br /&gt;
      @color_code = color_code&lt;br /&gt;
      @comment = comments&lt;br /&gt;
      @vm_prompts = vmprompts&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
New code: We added an instance variable to keep track of response_id&lt;br /&gt;
&lt;br /&gt;
    def initialize(score_value, color_code, comments, vmprompts = nil, response_id)&lt;br /&gt;
      ...&lt;br /&gt;
      @response_id = response_id&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
'''D.2: '''Added a method reviewer_id to the class VmQuestionResponseScoreCell: This helper method retrieves the ID for the reviewer who created this response.&lt;br /&gt;
&lt;br /&gt;
    def reviewer_id&lt;br /&gt;
      resp = Response.find(@response_id)&lt;br /&gt;
      map = ResponseMap.find(resp.map_id)&lt;br /&gt;
      map.reviewer_id&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
====E. In app/views/grades/_add_icon_to_name.html.erb:====&lt;br /&gt;
&lt;br /&gt;
'''E.1 '''Added the following code to the file: Write the code to generate the review text only once to reduce WET code&lt;br /&gt;
&lt;br /&gt;
    &amp;lt;%# Determine the content of the reviewed by text %&amp;gt;&lt;br /&gt;
    &amp;lt;% review_text = &amp;quot;&amp;quot; %&amp;gt;&lt;br /&gt;
    &amp;lt;% if @current_role_name.eql?'Student' or questionnaire_type != &amp;quot;TeammateReviewQuestionnaire&amp;quot; %&amp;gt;&lt;br /&gt;
      &amp;lt;%# Use Review {{index}} format for student view, and when questionnaire_type is not teammatereview %&amp;gt;&lt;br /&gt;
      &amp;lt;% review_text = &amp;quot;Review #{i + 1}&amp;quot; %&amp;gt;&lt;br /&gt;
    &amp;lt;% else %&amp;gt;&lt;br /&gt;
      &amp;lt;% resp = Response.find(review.id) %&amp;gt;&lt;br /&gt;
      &amp;lt;% map = ResponseMap.find(resp.map_id) %&amp;gt;&lt;br /&gt;
      &amp;lt;% reviewer_id = map.reviewer_id %&amp;gt;&lt;br /&gt;
      &amp;lt;% fullname = Participant.find_by(id: reviewer_id).fullname(session[:ip]) %&amp;gt;&lt;br /&gt;
      &amp;lt;% review_text = &amp;quot;Review by #{fullname}&amp;quot; %&amp;gt;&lt;br /&gt;
    &amp;lt;% end%&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''E.2: '''&lt;br /&gt;
&lt;br /&gt;
Old code: Existing code is very unreadable as it's not indented, and written in a single line with 359 characters, which breaks the ruby style guide rules&lt;br /&gt;
&lt;br /&gt;
    &amp;lt;% if review.done_by_staff_participant? %&amp;gt;&lt;br /&gt;
      &amp;lt;th class=&amp;quot;sorter-false&amp;quot;&amp;gt; &amp;lt;img data-toggle=&amp;quot;tooltip&amp;quot; data-placement=&amp;quot;right&amp;quot; title=&amp;quot;Icon indicates this review was done by course staff&amp;quot; class=&amp;quot;img_icon&amp;quot; src=&amp;quot;/assets/staff.png&amp;quot;&amp;gt; &amp;lt;a target=&amp;quot;_blank&amp;quot; href=&amp;quot;../response/view?id=&amp;lt;%= review.id.to_s %&amp;gt;&amp;quot;  data-toggle=&amp;quot;tooltip&amp;quot; data-placement=&amp;quot;right&amp;quot; title=&amp;quot;Click to see details&amp;quot;&amp;gt;&amp;lt;%= &amp;quot;Review &amp;quot; + i.to_s  %&amp;gt;&amp;lt;/a&amp;gt; &amp;lt;/th&amp;gt;&lt;br /&gt;
    &amp;lt;% else %&amp;gt;&lt;br /&gt;
      &amp;lt;th class=&amp;quot;sorter-false&amp;quot;&amp;gt; &amp;lt;a target=&amp;quot;_blank&amp;quot; href=&amp;quot;../response/view?id=&amp;lt;%= review.id.to_s %&amp;gt;&amp;quot;  data-toggle=&amp;quot;tooltip&amp;quot; data-placement=&amp;quot;right&amp;quot; title=&amp;quot;Click to see details&amp;quot;&amp;gt;&amp;lt;%= &amp;quot;Review &amp;quot; + i.to_s %&amp;gt;&amp;lt;/a&amp;gt;  &amp;lt;/th&amp;gt;&lt;br /&gt;
    &amp;lt;% end %&amp;gt;&lt;br /&gt;
&lt;br /&gt;
New code: Correctly indented and removes WET repetition of code blocks and makes the resulting code DRYer&lt;br /&gt;
&lt;br /&gt;
    &amp;lt;th class=&amp;quot;sorter-false&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;lt;% if review.done_by_staff_participant? %&amp;gt;&lt;br /&gt;
      &amp;lt;img&lt;br /&gt;
      data-toggle=&amp;quot;tooltip&amp;quot;&lt;br /&gt;
      data-placement=&amp;quot;right&amp;quot;&lt;br /&gt;
      title=&amp;quot;Icon indicates this review was done by course staff&amp;quot; class=&amp;quot;img_icon&amp;quot;&lt;br /&gt;
      src=&amp;quot;/assets/staff.png&amp;quot;&lt;br /&gt;
      &amp;gt;&lt;br /&gt;
    &amp;lt;% end %&amp;gt;&lt;br /&gt;
    &amp;lt;a&lt;br /&gt;
      target=&amp;quot;_blank&amp;quot;&lt;br /&gt;
      href=&amp;quot;../response/view?id=&amp;lt;%= review.id.to_s %&amp;gt;&amp;quot;&lt;br /&gt;
      data-toggle=&amp;quot;tooltip&amp;quot;&lt;br /&gt;
      data-placement=&amp;quot;right&amp;quot;&lt;br /&gt;
      title=&amp;quot;Click to see details&amp;quot;&amp;gt;&lt;br /&gt;
      &amp;lt;%= review_text %&amp;gt;&lt;br /&gt;
    &amp;lt;/a&amp;gt;&lt;br /&gt;
    &amp;lt;/th&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====F.In app/views/grades/view_team.html.erb:====&lt;br /&gt;
&lt;br /&gt;
'''F.1: '''Added function teammateSelectOnChange: This function toggles the visibility for the teammate heatgrids when the instructor changes the dropdown&lt;br /&gt;
    &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  function teammateSelectOnChange(selectNode) {&lt;br /&gt;
      const revieweeIdToShow= selectNode.value;&lt;br /&gt;
      const tableSelector = &amp;quot;.teammate_table&amp;quot;;&lt;br /&gt;
      if(revieweeIdToShow == &amp;quot;all&amp;quot;) {&lt;br /&gt;
        document.querySelectorAll(tableSelector).forEach((tableNode) =&amp;gt; {&lt;br /&gt;
          tableNode.classList.remove(&amp;quot;hidden&amp;quot;);&lt;br /&gt;
        });&lt;br /&gt;
        return;&lt;br /&gt;
      }&lt;br /&gt;
&lt;br /&gt;
    document.querySelectorAll(tableSelector).forEach((tableNode) =&amp;gt; {&lt;br /&gt;
      const tableRevieweeId = tableNode.getAttribute('data-reviewee_id');&lt;br /&gt;
      if(tableRevieweeId == revieweeIdToShow) {&lt;br /&gt;
        tableNode.classList.remove(&amp;quot;hidden&amp;quot;);&lt;br /&gt;
      } else {&lt;br /&gt;
        tableNode.classList.add(&amp;quot;hidden&amp;quot;);&lt;br /&gt;
      }&lt;br /&gt;
      });&lt;br /&gt;
    }&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''F.2: '''&lt;br /&gt;
&lt;br /&gt;
Old code: Existing code doesn't render TeammateReviewQuestionnaire&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    &amp;lt;% @vmlist.each do |vm| %&amp;gt;&lt;br /&gt;
        &amp;lt;% if (vm.questionnaire_display_type == &amp;quot;Metareview&amp;quot; or vm.questionnaire_display_type == &amp;quot;Author Feedback&amp;quot; or vm.questionnaire_display_type == &amp;quot;Teammate Review&amp;quot;) and @current_role_name.eql?'Student' %&amp;gt;&lt;br /&gt;
        &amp;lt;% else %&amp;gt;&lt;br /&gt;
        &amp;lt;% if vm.list_of_reviewers.length &amp;gt; 0 %&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
New code: Use a boolean to render a dropdown (that contains the students' IDs and names) just before the first TeammateReviewQuestionnaire, and unset that boolean so we only render 1 table. &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;%# This boolean is used to render a dropdown just before the first teammate review heat grid %&amp;gt;&lt;br /&gt;
&amp;lt;% first_teammate_review_appeared = false %&amp;gt;&lt;br /&gt;
&amp;lt;% @vmlist.each do |vm| %&amp;gt;&lt;br /&gt;
     &amp;lt;% if (not @current_role_name.eql?'Student' and&lt;br /&gt;
        not first_teammate_review_appeared and&lt;br /&gt;
        vm.questionnaire_type == &amp;quot;TeammateReviewQuestionnaire&amp;quot; &lt;br /&gt;
      ) %&amp;gt;&lt;br /&gt;
      &amp;lt;div&amp;gt;&lt;br /&gt;
        &amp;lt;select onchange=&amp;quot;teammateSelectOnChange(this)&amp;quot;&amp;gt;&lt;br /&gt;
          &amp;lt;option value=&amp;quot;all&amp;quot;&amp;gt;All&amp;lt;/option&amp;gt;&lt;br /&gt;
          &amp;lt;% @vmlist.select { |tm_vm| tm_vm.questionnaire_type == &amp;quot;TeammateReviewQuestionnaire&amp;quot; }.each do |tm_vm| %&amp;gt;&lt;br /&gt;
            &amp;lt;option value=&amp;quot;&amp;lt;%= tm_vm.reviewee_id %&amp;gt;&amp;quot;&amp;gt;&lt;br /&gt;
              &amp;lt;%= tm_vm.reviewee_name(session[:ip]) %&amp;gt;&lt;br /&gt;
            &amp;lt;/option&amp;gt;&lt;br /&gt;
          &amp;lt;% end %&amp;gt;&lt;br /&gt;
        &amp;lt;/select&amp;gt;&lt;br /&gt;
      &amp;lt;/div&amp;gt;&lt;br /&gt;
      &amp;lt;% first_teammate_review_appeared = true %&amp;gt;&lt;br /&gt;
    &amp;lt;% end %&amp;gt;&lt;br /&gt;
&lt;br /&gt;
New code: Add conditions which check for the truthiness of ```@assignment.show_teammate_reviews``` and if the current user is a student to decide whether to render the table or not.  Since the existing code checks truthiness for the cases for which NOT to render a table, we have followed the existing style of the code.&lt;br /&gt;
&lt;br /&gt;
1) If type of view model is teammate review questionnaire, and current role is student, and if @assignment.show_teammate_reviews is false, then we don't render anything&lt;br /&gt;
2) If type of view model is teammate review questionnaire, and current role is student, but @assignment.show_teammate_reviews is true, then we don't render anything if the current reviewer_id is different to the currently logged in user.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    &amp;lt;% if (vm.questionnaire_display_type == &amp;quot;Metareview&amp;quot; or vm.questionnaire_display_type == &amp;quot;Author Feedback&amp;quot;) and @current_role_name.eql?'Student' %&amp;gt;&lt;br /&gt;
    &amp;lt;% elsif (&lt;br /&gt;
      vm.questionnaire_type == &amp;quot;TeammateReviewQuestionnaire&amp;quot; and&lt;br /&gt;
      @current_role_name.eql?'Student' and&lt;br /&gt;
      !@assignment.show_teammate_reviews&lt;br /&gt;
      ) %&amp;gt;&lt;br /&gt;
    &amp;lt;% elsif (&lt;br /&gt;
      vm.questionnaire_type == &amp;quot;TeammateReviewQuestionnaire&amp;quot; and &lt;br /&gt;
      @current_role_name.eql?'Student' and&lt;br /&gt;
      @assignment.show_teammate_reviews and current_user.id != vm.reviewee_id&lt;br /&gt;
      )%&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
New code: Finally, add a CSS class and a `data-reviewee_id` to keep track of the heatgrids when toggling visibility.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    &amp;lt;% else %&amp;gt;&lt;br /&gt;
        &amp;lt;% if vm.questionnaire_type == &amp;quot;TeammateReviewQuestionnaire&amp;quot; %&amp;gt;&lt;br /&gt;
          &amp;lt;div class=&amp;quot;teammate_table&amp;quot; data-reviewee_id=&amp;quot;&amp;lt;%= vm.reviewee_id %&amp;gt;&amp;quot;&amp;gt;&lt;br /&gt;
        &amp;lt;% else %&amp;gt;&lt;br /&gt;
          &amp;lt;div&amp;gt;&lt;br /&gt;
        &amp;lt;% end %&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''F.3  '''&lt;br /&gt;
&lt;br /&gt;
Old code: Existing code doesn't print the teammate who is being reviewed.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;!-- display the list of questions for this questionnaire --&amp;gt;&lt;br /&gt;
          &amp;lt;h4 style=&amp;quot;display:inline-block;&amp;quot;&amp;gt;&amp;lt;%= vm.questionnaire_display_type %&amp;gt;&lt;br /&gt;
            &amp;lt;% if vm.questionnaire_type == &amp;quot;ReviewQuestionnaire&amp;quot; %&amp;gt;&lt;br /&gt;
                (Round: &amp;lt;%= vm.round.to_s  %&amp;gt; of &amp;lt;%= vm.rounds.to_s  %&amp;gt;)&lt;br /&gt;
            &amp;lt;%end %&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
New code: If TeammteReviewQuestionnaire is used, then use the `:reviewee_name` method for VmQuestionResponse model to print the name of the student who is being reviewed.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;!-- display the list of questions for this questionnaire --&amp;gt;&lt;br /&gt;
          &amp;lt;h4 style=&amp;quot;display:inline-block;&amp;quot;&amp;gt;&amp;lt;%= vm.questionnaire_display_type %&amp;gt;&lt;br /&gt;
            &amp;lt;% if vm.questionnaire_type == &amp;quot;ReviewQuestionnaire&amp;quot; %&amp;gt;&lt;br /&gt;
                (Round: &amp;lt;%= vm.round.to_s  %&amp;gt; of &amp;lt;%= vm.rounds.to_s  %&amp;gt;)&lt;br /&gt;
            &amp;lt;% elsif vm.questionnaire_type == &amp;quot;TeammateReviewQuestionnaire&amp;quot; %&amp;gt;&lt;br /&gt;
                (For: &amp;lt;%= vm.reviewee_name(session[:ip]) %&amp;gt;)&lt;br /&gt;
            &amp;lt;%end %&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''F.4 '''&lt;br /&gt;
&lt;br /&gt;
Old code: Existing code doesn't inform the partial about the type of review being done&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;% vm.list_of_reviews.each do |review| %&amp;gt;&lt;br /&gt;
              &amp;lt;!-- instructors (or higher level users) see reviewer name, students see anonymized string --&amp;gt;&lt;br /&gt;
              &amp;lt;% if (['Student'].include? @current_role_name) &amp;amp;&amp;amp; @assignment.is_anonymous%&amp;gt;&lt;br /&gt;
                &amp;lt;%= render :partial =&amp;gt; 'add_icon_to_name', :locals =&amp;gt; {review: review, i: i} %&amp;gt;&lt;br /&gt;
              &amp;lt;% else %&amp;gt;&lt;br /&gt;
                  &amp;lt;% user_name = User.find(Participant.find(ResponseMap.find(Response.find(review.id).map_id).reviewer_id).user_id).fullname(session[:ip]).to_s %&amp;gt;&lt;br /&gt;
                &amp;lt;%= render :partial =&amp;gt; 'add_icon_to_name', :locals =&amp;gt; {review: review, i: i} %&amp;gt;&lt;br /&gt;
              &amp;lt;% end %&amp;gt;&lt;br /&gt;
              &amp;lt;% i += 1 %&amp;gt;&lt;br /&gt;
          &amp;lt;% end %&amp;gt;&lt;br /&gt;
New code: Passes the type of review being done to the partial, so it can decide on how to render the review title. Note: This code seems to use repetition, but since the conditional used here are accessing `Anonymous` assignments and checking for user roles, we have not modified this code, as it is not directly related to our scope.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;% vm.list_of_reviews.each do |review| %&amp;gt;&lt;br /&gt;
              &amp;lt;!-- instructors (or higher level users) see reviewer name, students see anonymized string --&amp;gt;&lt;br /&gt;
              &amp;lt;% if (['Student'].include? @current_role_name) &amp;amp;&amp;amp; @assignment.is_anonymous%&amp;gt;&lt;br /&gt;
                &amp;lt;%= render :partial =&amp;gt; 'add_icon_to_name', :locals =&amp;gt; {review: review, i: i, questionnaire_type: vm.questionnaire_type } %&amp;gt;&lt;br /&gt;
              &amp;lt;% else %&amp;gt;&lt;br /&gt;
                &amp;lt;% user_name = User.find(Participant.find(ResponseMap.find(Response.find(review.id).map_id).reviewer_id).user_id).fullname(session[:ip]).to_s %&amp;gt;&lt;br /&gt;
                &amp;lt;%= render :partial =&amp;gt; 'add_icon_to_name', :locals =&amp;gt; {review: review, i: i, questionnaire_type: vm.questionnaire_type } %&amp;gt;&lt;br /&gt;
              &amp;lt;% end %&amp;gt;&lt;br /&gt;
              &amp;lt;% i += 1 %&amp;gt;&lt;br /&gt;
          &amp;lt;% end %&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Old code: Contains a `metrics-1` column&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
          &amp;lt;th class=&amp;quot;sorter-true&amp;quot; align=&amp;quot;right&amp;quot; &amp;gt;&lt;br /&gt;
            Avg&amp;lt;span&amp;gt;&amp;lt;/span&amp;gt;&lt;br /&gt;
          &amp;lt;/th&amp;gt;&lt;br /&gt;
          &amp;lt;th class=&amp;quot;sorter-false&amp;quot;&amp;gt;&lt;br /&gt;
            &amp;lt;span  data-toggle=&amp;quot;tooltip&amp;quot; data-placement=&amp;quot;right&amp;quot; title=&amp;quot;A count of comments, for the respective question, which have word count &amp;gt; 10. The purpose of this metric is to represent how many comments for the question are of a substantial length to provide quality feedback.&amp;quot;&amp;gt;metric-1&amp;lt;/span&amp;gt;&lt;br /&gt;
          &amp;lt;/th&amp;gt;&lt;br /&gt;
        &amp;lt;/tr&amp;gt;&lt;br /&gt;
        &amp;lt;/thead&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
New code: As per discussion with mentor, this column has been removed in our PR.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
          &amp;lt;th class=&amp;quot;sorter-true&amp;quot; align=&amp;quot;right&amp;quot; &amp;gt;&lt;br /&gt;
            Avg&amp;lt;span&amp;gt;&amp;lt;/span&amp;gt;&lt;br /&gt;
          &amp;lt;/th&amp;gt;&lt;br /&gt;
        &amp;lt;/tr&amp;gt;&lt;br /&gt;
        &amp;lt;/thead&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''F.5 '''&lt;br /&gt;
&lt;br /&gt;
Old code: It creates the ID inline in multiple places, so if we decide to change the ID generation logic, we need to modify it in multiple places. (which happened when we started rendering multiple tables for each teammate).&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;% vm.list_of_rows.each do |row| %&amp;gt;&lt;br /&gt;
            &amp;lt;!-- notice the data-target. because we're toggling via looped code, we need to dynamically generate the identifier. --&amp;gt;&lt;br /&gt;
            &amp;lt;tr data-toggle=&amp;quot;collapse&amp;quot; class=&amp;quot;accordion-toggle&amp;quot; data-target=&amp;quot;#hid&amp;lt;%= row.question_id.to_s + vm.round.to_s %&amp;gt;&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
New code: Generate the unique HTML ID once, in a readable manner once. And conditionally make it more unique, if it is a TeammateReviewQuestionnaire, since jQuery code requires these IDs to be unique amongst different tables. If we don't make it more unique, then clicking on one teammate review table will toggle the table visibility for the first table. To prevent this &amp;quot;clashing&amp;quot;, we need to make these IDs more unique for a TeammateReviewQuestionnaire.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;% vm.list_of_rows.each do |row| %&amp;gt;&lt;br /&gt;
            &amp;lt;% target_id = &amp;quot;hid__#{row.question_id}__#{vm.round}&amp;quot; %&amp;gt;&lt;br /&gt;
            &amp;lt;% if vm.questionnaire_type == &amp;quot;TeammateReviewQuestionnaire&amp;quot; %&amp;gt;&lt;br /&gt;
              &amp;lt;%# Since we render different heatgrids with the same questions for each&lt;br /&gt;
              teammember, we need to distinguish the ID, based on the user for whom,&lt;br /&gt;
              the reviews have been created. %&amp;gt;&lt;br /&gt;
              &amp;lt;% target_id += &amp;quot;__#{vm.reviewee_id}&amp;quot; %&amp;gt;&lt;br /&gt;
            &amp;lt;% end%&amp;gt;&lt;br /&gt;
&lt;br /&gt;
            &amp;lt;!-- notice the data-target. because we're toggling via looped code, we need to dynamically generate the identifier. --&amp;gt;&lt;br /&gt;
            &amp;lt;tr data-toggle=&amp;quot;collapse&amp;quot; class=&amp;quot;accordion-toggle&amp;quot; data-target=&amp;quot;&amp;lt;%= &amp;quot;#&amp;quot; + target_id %&amp;gt;&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Old code: Written on a single line crossing 80 characters on a single line&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
              &amp;lt;% row.score_row.each do |score| %&amp;gt;&lt;br /&gt;
                  &amp;lt;% score_comment = score.comment.nil? ? '' : score.comment %&amp;gt; &amp;lt;!-- changing nil to null string to avoid Null Pointer Exception --&amp;gt;&lt;br /&gt;
                  &amp;lt;td class=&amp;quot;&amp;lt;%= score.color_code %&amp;gt;&amp;quot; align=&amp;quot;center&amp;quot; data-toggle=&amp;quot;tooltip&amp;quot; title=&amp;quot;&amp;lt;%= strip_tags(score.comment).html_safe%&amp;gt;&amp;quot;&amp;gt;&lt;br /&gt;
                    &amp;lt;span class=&amp;quot;&amp;lt;%=  underlined?(score) %&amp;gt;&amp;quot;&amp;gt;&amp;lt;%= score.score_value.to_s %&amp;gt;&amp;lt;/span&amp;gt;&lt;br /&gt;
                  &amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;% end %&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
New code: Make code more readable by indenting it and splitting it over multiple lines&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
              &amp;lt;!-- actual cells with scores and colored background. --&amp;gt;&lt;br /&gt;
              &amp;lt;% row.score_row.each do |score| %&amp;gt;&lt;br /&gt;
                  &amp;lt;% score_comment = score.comment.nil? ? '' : score.comment %&amp;gt;&lt;br /&gt;
                  &amp;lt;!-- changing nil to null string to avoid Null Pointer Exception --&amp;gt;&lt;br /&gt;
                  &amp;lt;td class=&amp;quot;&amp;lt;%= score.color_code %&amp;gt;&amp;quot; align=&amp;quot;center&amp;quot; data-toggle=&amp;quot;tooltip&amp;quot; title=&amp;quot;&amp;lt;%= strip_tags(score.comment).html_safe%&amp;gt;&amp;quot;&amp;gt;&lt;br /&gt;
                    &amp;lt;span class=&amp;quot;&amp;lt;%=  underlined?(score) %&amp;gt;&amp;quot;&amp;gt;&lt;br /&gt;
                      &amp;lt;%= score.score_value.to_s %&amp;gt;&lt;br /&gt;
                    &amp;lt;/span&amp;gt;&lt;br /&gt;
                  &amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;% end %&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''F.6 '''Removed the following code as it corresponds to the deleted column&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 &amp;lt;td  class = 'cf' align=&amp;quot;center&amp;quot;&amp;gt;&lt;br /&gt;
                &amp;lt;%= row.countofcomments.to_s %&amp;gt;&lt;br /&gt;
              &amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''F.7 '''&lt;br /&gt;
&lt;br /&gt;
Old code: Existing code just unconditionally prints the text &amp;quot;Review&amp;quot; followed by an index.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
                    &amp;lt;% for index in 0 .. row.score_row.length - 1 %&amp;gt;&lt;br /&gt;
                        &amp;lt;tr&amp;gt;&lt;br /&gt;
                          &amp;lt;td&amp;gt;Review &amp;lt;%=index + 1%&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
New code: Conditionally change the review text that is displayed based on the type of review and the access level of the user&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
                    &amp;lt;% for index in 0 .. row.score_row.length - 1 %&amp;gt;&lt;br /&gt;
                        &amp;lt;tr&amp;gt;&lt;br /&gt;
                          &amp;lt;% if @current_role_name.eql?'Student' or vm.questionnaire_type != &amp;quot;TeammateReviewQuestionnaire&amp;quot; %&amp;gt;&lt;br /&gt;
                            &amp;lt;%# Use Review {{index}} format for student view, and&lt;br /&gt;
                            when questionnaire_type is not teammatereview %&amp;gt;&lt;br /&gt;
                            &amp;lt;td&amp;gt;Review &amp;lt;%=index + 1%&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
                          &amp;lt;% else %&amp;gt;&lt;br /&gt;
                            &amp;lt;td&amp;gt;&lt;br /&gt;
                              &amp;lt;% reviewer_id = row.score_row[index].reviewer_id %&amp;gt;&lt;br /&gt;
                              &amp;lt;% fullname = Participant.find_by(id: reviewer_id).fullname(session[:ip]) %&amp;gt;&lt;br /&gt;
                              Review by &amp;lt;%= fullname %&amp;gt;&lt;br /&gt;
                            &amp;lt;/td&amp;gt;&lt;br /&gt;
                          &amp;lt;% end%&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====G. In spec/controllers/grades_controller_spec.rb:====&lt;br /&gt;
&lt;br /&gt;
'''G.1 '''&lt;br /&gt;
&lt;br /&gt;
Old code&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
before(:each) do&lt;br /&gt;
  allow(AssignmentParticipant).to receive(:find).with('1').and_return(participant)&lt;br /&gt;
  allow(participant).to receive(:team).and_return(team)&lt;br /&gt;
  stub_current_user(instructor, instructor.role.name, instructor.role)&lt;br /&gt;
  allow(Assignment).to receive(:find).with('1').and_return(assignment)&lt;br /&gt;
@@ -91,29 +90,106 @@&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
New code&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
before(:each) do&lt;br /&gt;
  allow(participant).to receive(:team).and_return(team)&lt;br /&gt;
  stub_current_user(instructor, instructor.role.name, instructor.role)&lt;br /&gt;
  allow(Assignment).to receive(:find).with('1').and_return(assignment)&lt;br /&gt;
@@ -91,29 +90,106 @@&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''G.2 '''Remove xdescribe '#view_team' and change describe '#view_team' as follows.&lt;br /&gt;
&lt;br /&gt;
Old code&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
describe '#view_team' do&lt;br /&gt;
render_views&lt;br /&gt;
context 'when view_team page is viewed by a student who is also a TA for another course' do&lt;br /&gt;
  it 'renders grades#view_team page' do&lt;br /&gt;
    allow(participant).to receive(:team).and_return(team)&lt;br /&gt;
    allow(AssignmentQuestionnaire).to receive(:find_by).with(assignment_id: 1, questionnaire_id: 1).and_return(assignment_questionnaire)&lt;br /&gt;
    allow(AssignmentQuestionnaire).to receive(:where).with(any_args).and_return([assignment_questionnaire])&lt;br /&gt;
    allow(assignment).to receive(:late_policy_id).and_return(false)&lt;br /&gt;
    allow(assignment).to receive(:calculate_penalty).and_return(false)&lt;br /&gt;
    allow(assignment).to receive(:compute_total_score).with(any_args).and_return(100)&lt;br /&gt;
    allow(review_questionnaire).to receive(:get_assessments_round_for).with(participant, 1).and_return([review_response])&lt;br /&gt;
    allow(Answer).to receive(:compute_scores).with([review_response], [question]).and_return(max: 95, min: 88, avg: 90)&lt;br /&gt;
    params = {id: 1}&lt;br /&gt;
    allow(TaMapping).to receive(:exists?).with(ta_id: 1, course_id: 1).and_return(true)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
New code&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
describe '#view_team' do&lt;br /&gt;
render_views&lt;br /&gt;
&lt;br /&gt;
# All stubs and factories are instantiated within this scope so as to not &lt;br /&gt;
# clash with other broken test.&lt;br /&gt;
# The names of the factories created for testing view_team&lt;br /&gt;
# have `_vt` suffix ```where necessary``` to differentiate them from &lt;br /&gt;
# the above declared factories&lt;br /&gt;
&lt;br /&gt;
let(:student1_vt) { create(:student, name: &amp;quot;barry&amp;quot;, id: 12) }&lt;br /&gt;
let(:student2_vt) { create(:student, name: &amp;quot;iris&amp;quot;, id: 13) }&lt;br /&gt;
&lt;br /&gt;
let(:tm_questionnaire) {&lt;br /&gt;
  build(&lt;br /&gt;
    :teammate_review_questionnaire,&lt;br /&gt;
    id: 12,&lt;br /&gt;
    questions: [question],&lt;br /&gt;
    max_question_score: 5&lt;br /&gt;
  )&lt;br /&gt;
}&lt;br /&gt;
let(:assignment_vt) {&lt;br /&gt;
  create(:assignment, id: 6, max_team_size: 2,&lt;br /&gt;
  questionnaires: [tm_questionnaire])&lt;br /&gt;
}&lt;br /&gt;
let(:assignment_questionnaire_vt) {&lt;br /&gt;
  create(:tm_assignment_questionnaire, id: 12, used_in_round: nil,&lt;br /&gt;
  assignment: assignment_vt, questionnaire: tm_questionnaire) }&lt;br /&gt;
let(:team_vt) { create(:assignment_team, id: 12,&lt;br /&gt;
assignment: assignment_vt) }&lt;br /&gt;
let(:participant_vt) { create(:participant, id: 12,&lt;br /&gt;
  assignment: assignment_vt, user_id: student1_vt.id) }&lt;br /&gt;
let(:participant2_vt) { create(:participant, id: 13,&lt;br /&gt;
  assignment: assignment_vt, user_id: student2_vt.id) }&lt;br /&gt;
&lt;br /&gt;
before(:each) do&lt;br /&gt;
  # Need to stub this method so the factory instance with&lt;br /&gt;
  # the stubbed :team method is returned by :find&lt;br /&gt;
  # instead of a separate instance with the same data&lt;br /&gt;
  allow(AssignmentParticipant)&lt;br /&gt;
    .to receive(:find)&lt;br /&gt;
    .with(participant_vt.id.to_s)&lt;br /&gt;
    .and_return(participant_vt)&lt;br /&gt;
  allow(participant_vt).to receive(:team).and_return(team_vt)&lt;br /&gt;
  allow(team_vt).to receive(:participants).and_return([participant_vt, participant2_vt])&lt;br /&gt;
  allow(AssignmentQuestionnaire)&lt;br /&gt;
    .to receive(:find_by)&lt;br /&gt;
    .with(assignment_id: assignment_vt.id, questionnaire_id: tm_questionnaire.id)&lt;br /&gt;
    .and_return(assignment_questionnaire_vt)&lt;br /&gt;
  allow(AssignmentQuestionnaire)&lt;br /&gt;
    .to receive(:find_by)&lt;br /&gt;
    .with(assignment_id: assignment.id, questionnaire_id: review_questionnaire.id)&lt;br /&gt;
    .and_return(assignment_questionnaire_vt)&lt;br /&gt;
  allow(AssignmentQuestionnaire)&lt;br /&gt;
    .to receive(:where)&lt;br /&gt;
    .with(any_args)&lt;br /&gt;
    .and_return([assignment_questionnaire_vt])&lt;br /&gt;
  allow(assignment_vt)&lt;br /&gt;
    .to receive(:late_policy_id)&lt;br /&gt;
    .and_return(false)&lt;br /&gt;
  allow(assignment_vt)&lt;br /&gt;
    .to receive(:calculate_penalty)&lt;br /&gt;
    .and_return(false)&lt;br /&gt;
  allow(assignment_vt)&lt;br /&gt;
    .to receive(:compute_total_score)&lt;br /&gt;
    .with(any_args)&lt;br /&gt;
    .and_return(100)&lt;br /&gt;
  allow(review_questionnaire).to receive(:get_assessments_round_for).with(participant, 1).and_return([review_response])&lt;br /&gt;
  allow(Answer).to receive(:compute_scores).with([review_response], [question]).and_return(max: 95, min: 88, avg: 90)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
 it 'renders grades#view_team page' do&lt;br /&gt;
  params = {id: participant_vt.id}&lt;br /&gt;
  get :view_team, params&lt;br /&gt;
  expect(response).to render_template(:view_team)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
context 'when view_team page is opened by student' do&lt;br /&gt;
  it 'dropdown is not rendered' do&lt;br /&gt;
    session = { user: student1_vt }&lt;br /&gt;
    params = {id: participant_vt.id}&lt;br /&gt;
    stub_current_user(student1_vt, student1_vt.role.name, student1_vt.role)&lt;br /&gt;
    get :view_team, params&lt;br /&gt;
    expect(response.body).to_not have_selector('select')&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
context 'when view_team page is opened by instructor' do&lt;br /&gt;
  it 'dropdown is rendered' do&lt;br /&gt;
    session = { user: instructor }&lt;br /&gt;
    params = {id: participant_vt.id}&lt;br /&gt;
    get :view_team, params&lt;br /&gt;
    expect(response.body).to have_selector('select')&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
context 'when view_team page is viewed by a student who is also a TA for another course' do&lt;br /&gt;
  it 'renders grades#view_team page' do&lt;br /&gt;
    params = { id: participant_vt.id }&lt;br /&gt;
    allow(TaMapping).to receive(:exists?).with(ta_id: participant_vt.user_id, course_id: 1).and_return(true)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
====H. In spec/factories/factories.rb:====&lt;br /&gt;
&lt;br /&gt;
'''H.1 '''Add the following factory:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
factory :teammate_review_questionnaire, class: TeammateReviewQuestionnaire do&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''H.2 '''Add another factory&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
factory :tm_assignment_questionnaire, class: AssignmentQuestionnaire do&lt;br /&gt;
  user_id 1&lt;br /&gt;
  questionnaire { association(:teammate_review_questionnaire) }&lt;br /&gt;
  questionnaire_weight 100&lt;br /&gt;
  used_in_round nil&lt;br /&gt;
  topic_id nil&lt;br /&gt;
  dropdown 1&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Testing ==&lt;br /&gt;
'''OLD STATUS'''&lt;br /&gt;
&lt;br /&gt;
1. Earlier, the tests contained an xdescribe test to check if the view_team page is rendered correctly. However, this test was being skipped as this was an xdescribe segment. There was another test for when the view_team page is accessed by a student who is also a TA for another course. This can be checked [https://github.com/expertiza/expertiza/blob/beta/spec/controllers/grades_controller_spec.rb here].&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 xdescribe '#view_team' do&lt;br /&gt;
    it 'renders grades#view_team page' do&lt;br /&gt;
      allow(participant).to receive(:team).and_return(team)&lt;br /&gt;
      params = {id: 1}&lt;br /&gt;
      get :view_team, params&lt;br /&gt;
      expect(response).to render_template(:view_team)&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  describe '#view_team' do&lt;br /&gt;
    render_views&lt;br /&gt;
    context 'when view_team page is viewed by a student who is also a TA for another course' do&lt;br /&gt;
      it 'renders grades#view_team page' do&lt;br /&gt;
        allow(participant).to receive(:team).and_return(team)&lt;br /&gt;
        allow(AssignmentQuestionnaire).to receive(:find_by).with(assignment_id: 1, questionnaire_id: 1).and_return(assignment_questionnaire)&lt;br /&gt;
        allow(AssignmentQuestionnaire).to receive(:where).with(any_args).and_return([assignment_questionnaire])&lt;br /&gt;
        allow(assignment).to receive(:late_policy_id).and_return(false)&lt;br /&gt;
        allow(assignment).to receive(:calculate_penalty).and_return(false)&lt;br /&gt;
        allow(assignment).to receive(:compute_total_score).with(any_args).and_return(100)&lt;br /&gt;
        allow(review_questionnaire).to receive(:get_assessments_round_for).with(participant, 1).and_return([review_response])&lt;br /&gt;
        allow(Answer).to receive(:compute_scores).with([review_response], [question]).and_return(max: 95, min: 88, avg: 90)&lt;br /&gt;
        params = {id: 1}&lt;br /&gt;
        allow(TaMapping).to receive(:exists?).with(ta_id: 1, course_id: 1).and_return(true)&lt;br /&gt;
        stub_current_user(ta, ta.role.name, ta.role)&lt;br /&gt;
        get :view_team, params&lt;br /&gt;
        expect(response.body).not_to have_content &amp;quot;TA&amp;quot;&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''NEW STATUS'''&lt;br /&gt;
&lt;br /&gt;
1. The view_team page is rendered correctly for a given student or an instructor. This can be checked in [https://github.com/expertiza/expertiza/blob/66239d9a8a53697ea170a92208593b36d06dfd24/spec/controllers/grades_controller_spec.rb this] file.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    it 'renders grades#view_team page' do&lt;br /&gt;
      params = {id: participant_vt.id}&lt;br /&gt;
      get :view_team, params&lt;br /&gt;
      expect(response).to render_template(:view_team)&lt;br /&gt;
    end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
2. When students access then the view_team page, the dropdown to select a student's teammate reviews is not rendered on the page. This can be checked in [https://github.com/expertiza/expertiza/blob/66239d9a8a53697ea170a92208593b36d06dfd24/spec/controllers/grades_controller_spec.rb this] file.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    context 'when view_team page is opened by student' do&lt;br /&gt;
      it 'dropdown is not rendered' do&lt;br /&gt;
        session = { user: student1_vt }&lt;br /&gt;
        params = {id: participant_vt.id}&lt;br /&gt;
        stub_current_user(student1_vt, student1_vt.role.name, student1_vt.role)&lt;br /&gt;
        get :view_team, params&lt;br /&gt;
        expect(response.body).to_not have_selector('select')&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
3. When an instructor access then the view_team page, the dropdown to select a student's teammate reviews is rendered on the page. This can be checked in [https://github.com/expertiza/expertiza/blob/66239d9a8a53697ea170a92208593b36d06dfd24/spec/controllers/grades_controller_spec.rb this] file.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    context 'when view_team page is opened by instructor' do&lt;br /&gt;
      it 'dropdown is rendered' do&lt;br /&gt;
        session = { user: instructor }&lt;br /&gt;
        params = {id: participant_vt.id}&lt;br /&gt;
        get :view_team, params&lt;br /&gt;
        expect(response.body).to have_selector('select')&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
4. When a student who is also a TA for another course access the view_team page, that student should be able to a student's view to the page. This can be checked in [https://github.com/expertiza/expertiza/blob/66239d9a8a53697ea170a92208593b36d06dfd24/spec/controllers/grades_controller_spec.rb this] file.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    context 'when view_team page is viewed by a student who is also a TA for another course' do&lt;br /&gt;
      it 'renders grades#view_team page' do&lt;br /&gt;
        params = { id: participant_vt.id }&lt;br /&gt;
        allow(TaMapping).to receive(:exists?).with(ta_id: participant_vt.user_id, course_id: 1).and_return(true)&lt;br /&gt;
        stub_current_user(ta, ta.role.name, ta.role)&lt;br /&gt;
        get :view_team, params&lt;br /&gt;
        expect(response.body).not_to have_content &amp;quot;TA&amp;quot;&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
5. If show_teammate_reviews boolean is set to False, then the student should not be able to see the teammate reviews given to him/her. An instructor can still see the teammate reviews. This can be checked in [https://github.com/expertiza/expertiza/blob/66239d9a8a53697ea170a92208593b36d06dfd24/spec/controllers/grades_controller_spec.rb this] file.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    context 'when assignment(show reviews) value is unchecked' do&lt;br /&gt;
      before(:each) do&lt;br /&gt;
        allow(assignment_vt).to receive(:show_teammate_reviews).and_return(false) &lt;br /&gt;
      end&lt;br /&gt;
      it 'Student cannot view his score' do&lt;br /&gt;
        session = { user: student1_vt }&lt;br /&gt;
        params = {id: participant_vt.id}&lt;br /&gt;
        stub_current_user(student1_vt, student1_vt.role.name, student1_vt.role)&lt;br /&gt;
        get :view_team, params&lt;br /&gt;
        expect(response.body).to_not have_selector(&amp;quot;.teammate_table[data-reviewee_id=\&amp;quot;#{participant_vt.id}\&amp;quot;]&amp;quot;)&lt;br /&gt;
        expect(response.body).to_not have_selector(&amp;quot;.teammate_table[data-reviewee_id=\&amp;quot;#{participant2_vt.id}\&amp;quot;]&amp;quot;)&lt;br /&gt;
      end&lt;br /&gt;
&lt;br /&gt;
      it 'Instructor can view the student score' do        &lt;br /&gt;
        params = {id: participant_vt.id}        &lt;br /&gt;
        get :view_team, params&lt;br /&gt;
        expect(response.body).to have_selector(&amp;quot;.teammate_table[data-reviewee_id=\&amp;quot;#{participant_vt.id}\&amp;quot;]&amp;quot;)&lt;br /&gt;
        expect(response.body).to have_selector(&amp;quot;.teammate_table[data-reviewee_id=\&amp;quot;#{participant2_vt.id}\&amp;quot;]&amp;quot;)&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
6. If show_teammate_reviews boolean is set to True, then both the student should and instructor should be able to see the teammate reviews. The student should see only the reviews received by him/her. The instructor should be able to see all student's teammate reviews. This can be checked in [https://github.com/expertiza/expertiza/blob/66239d9a8a53697ea170a92208593b36d06dfd24/spec/controllers/grades_controller_spec.rb this] file.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
    context 'when assignment(show reviews) value is checked' do&lt;br /&gt;
      it 'Student can view his score' do&lt;br /&gt;
        session = { user: student1_vt }&lt;br /&gt;
        params = {id: participant_vt.id}&lt;br /&gt;
        stub_current_user(student1_vt, student1_vt.role.name, student1_vt.role)&lt;br /&gt;
        get :view_team, params&lt;br /&gt;
        expect(response.body).to have_selector(&amp;quot;.teammate_table[data-reviewee_id=\&amp;quot;#{participant_vt.id}\&amp;quot;]&amp;quot;)&lt;br /&gt;
        expect(response.body).to_not have_selector(&amp;quot;.teammate_table[data-reviewee_id=\&amp;quot;#{participant2_vt.id}\&amp;quot;]&amp;quot;)&lt;br /&gt;
      end&lt;br /&gt;
&lt;br /&gt;
      it 'Instructor can view the student score' do        &lt;br /&gt;
        params = {id: participant_vt.id}        &lt;br /&gt;
        get :view_team, params&lt;br /&gt;
        expect(response.body).to have_selector(&amp;quot;.teammate_table[data-reviewee_id=\&amp;quot;#{participant_vt.id}\&amp;quot;]&amp;quot;)&lt;br /&gt;
        expect(response.body).to have_selector(&amp;quot;.teammate_table[data-reviewee_id=\&amp;quot;#{participant2_vt.id}\&amp;quot;]&amp;quot;)&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
7. The reviewer id is tracked correctly to show the correct reviewer name in the teammate reviews table. This can be checked in [https://github.com/expertiza/expertiza/blob/66239d9a8a53697ea170a92208593b36d06dfd24/spec/models/vm_question_response_score_cell_spec.rb this] file &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  	describe '#reviewer_id' do&lt;br /&gt;
  		it 'returns reviewer id' do&lt;br /&gt;
			allow(ResponseMap).to receive(:find).with(1).and_return(review_response_map)&lt;br /&gt;
			allow(response).to receive(:populate_new_response).with(:review_response_map, &amp;quot;0&amp;quot;).and_return(response)&lt;br /&gt;
        	expect(response.id).to eq(1)	&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Summary of file changes ==&lt;br /&gt;
&lt;br /&gt;
The following files are modified:&lt;br /&gt;
&lt;br /&gt;
1. app/controllers/grades_controller.rb - Controller file which changed how the view model is populated&lt;br /&gt;
&lt;br /&gt;
2. app/views/grades/view_team.html.erb - View file, which  conditionally rendered the teammate name, for a teammate review heatgrid&lt;br /&gt;
&lt;br /&gt;
3. spec/controllers/grades_controller_spec.rb - For tests verifying the proposed changes&lt;br /&gt;
&lt;br /&gt;
4. app/models/vm_question_response.rb - To modify the view-model so it can tell us the name of the person being reviewed for the current heatgrid&lt;br /&gt;
&lt;br /&gt;
5. app/models/vm_question_response_score_cell.rb - &lt;br /&gt;
&lt;br /&gt;
6. app/assets/stylesheets/grades.scss - &lt;br /&gt;
&lt;br /&gt;
7. app/views/grades/_add_icon_to_name.html.erb - &lt;br /&gt;
&lt;br /&gt;
8. spec/factories/factories.rb -&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Design Patterns ==&lt;br /&gt;
&lt;br /&gt;
Existing code does not use any design patterns, apart from if-else. It uses if-else conditional statements to check what type of questionnaire is present in the viewmodel `VmQuestionResponse`, and based on that, it renders the appropriate content.&lt;br /&gt;
&lt;br /&gt;
We decided to continue with this approach since to change the present coding style, there were required many changes (refactoring) to many files which were out of the scope of the present project. To complete the project in the assigned time, we followed the if-else approach.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==References==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;https://expertiza.ncsu.edu/&amp;lt;/p&amp;gt;&lt;/div&gt;</summary>
		<author><name>Vdeshmu</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2021_-_E2165._Fix_teammate-review_view&amp;diff=141750</id>
		<title>CSC/ECE 517 Fall 2021 - E2165. Fix teammate-review view</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2021_-_E2165._Fix_teammate-review_view&amp;diff=141750"/>
		<updated>2021-11-28T19:02:57Z</updated>

		<summary type="html">&lt;p&gt;Vdeshmu: /* F.In app/views/grades/view_team.html.erb: */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Team Introduction ==&lt;br /&gt;
&lt;br /&gt;
Dr. Edward Gehringer (instructor), Parimal Mehta (mentor)&lt;br /&gt;
&lt;br /&gt;
1. Anjali Garg (unity ID : agarg25)&lt;br /&gt;
&lt;br /&gt;
2. Arvasu Chikara (unity ID: achikar2)&lt;br /&gt;
&lt;br /&gt;
3. Lalit Bangad (unity ID: llbangad)&lt;br /&gt;
&lt;br /&gt;
4. Vinay Deshmukh (unity ID: vdeshmu)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Problems to be addressed ==&lt;br /&gt;
&lt;br /&gt;
After a project is submitted and reviewed, both the team members (students) and instructors should be able to view the teammate reviews. Students should be able to view the reviews by going to a particular assignment's -&amp;gt; your scores, at the bottom of the page. An instructor can view the teammate reviews by going to assignments -&amp;gt; assignment -&amp;gt; particular team's submission -&amp;gt; view submission -&amp;gt; assign grades -&amp;gt; view scores. &lt;br /&gt;
&lt;br /&gt;
In the case of the instructor, a single heat grid is shown whereas in the case of a team member, we cant view the scores. In the heat grid, it is not clear if the scores visible are for the reviews that the student has *written* for their teammates or the scores that the student has *received* from their teammates. Additionally, for instructors can choose from a list of the students on the team, but they have no way to tell whether the heat grid shows the reviews done *by* that student or done *for* that student.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Methodology Overview ==&lt;br /&gt;
&lt;br /&gt;
We have divided our work in the following tasks to address the above problems:&lt;br /&gt;
&lt;br /&gt;
1. Distinguish reviews done for a student by rendering separates heatgrids for each student&lt;br /&gt;
&lt;br /&gt;
2. For instructors, the table will have sections based on the students&lt;br /&gt;
&lt;br /&gt;
3. Include a checkbox on the edit assignment page that enables/disables visibility of heat grid to students&lt;br /&gt;
&lt;br /&gt;
4. Fix the average column for a table (which breaks for some reviews)&lt;br /&gt;
&lt;br /&gt;
5. Show a composite score derived from all reviews.  Make this code generalized, so other kinds of heat grid views could use it.&lt;br /&gt;
&lt;br /&gt;
6. Changes should work even in an anonymized view&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Motivations ==&lt;br /&gt;
&lt;br /&gt;
1. Enable users to clearly tell which reviews are done by them, and which reviews are done for them.&lt;br /&gt;
&lt;br /&gt;
2. Code should be generic so it can be used for different types of heat grids as well.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Control Flow to access the concerned screens ==&lt;br /&gt;
'''1. For instructor (Log in as an instructor):-'''&lt;br /&gt;
&lt;br /&gt;
Screen after logging in by the instructor&lt;br /&gt;
[[File:ss1.png |border|1000px|center]]&lt;br /&gt;
Got to assignments on the Manage menu &lt;br /&gt;
[[File:ss2.png |border|1000px|center]]&lt;br /&gt;
Go to assignments&lt;br /&gt;
[[File:ss3.png |border|1000px|center]]&lt;br /&gt;
Go to submissions for any assignment&lt;br /&gt;
[[File:ss4a.png |border|1000px|center]]&lt;br /&gt;
Go to Assign Grade&lt;br /&gt;
[[File:ss5a.png |border|1000px|center]]&lt;br /&gt;
You will land on the page where the changes are made and can be reviewed&lt;br /&gt;
[[File:ss7a.png |border|1000px|center]]&lt;br /&gt;
&lt;br /&gt;
'''2. Student:- (Instructor impersonating a student)'''&lt;br /&gt;
&lt;br /&gt;
After landing on the assignments page, select any student from an assignment as shown below&lt;br /&gt;
[[File:ss6a.png |border|1000px|center]]&lt;br /&gt;
Go to/Select any assignment&lt;br /&gt;
[[File:ss9a.png |border|1000px|center]]&lt;br /&gt;
Go to your scores&lt;br /&gt;
[[File:ss10a.png |border|1000px|center]]&lt;br /&gt;
You will land on the page where the changes are made and can be reviewed&lt;br /&gt;
[[File:ss11a.png |border|1000px|center]]&lt;br /&gt;
&lt;br /&gt;
== Old Status of the application ==&lt;br /&gt;
&lt;br /&gt;
'''1. Instructor's view of teammate review''': This is the current screen given to the instructor. Here we see that the instructor can not determine who has given which review to which student in a team.&lt;br /&gt;
&lt;br /&gt;
[[File:Instructor-view-1.png|border| 700px |center|alt=The proposed expanded student display.|The proposed expanded student display.]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''2. Student's view of teammate review''': Currently, a student is not able to see what grades were given by their teammates. We need to implement that functionality so that the student is able to view those grades.&lt;br /&gt;
&lt;br /&gt;
[[File:Student-view-2.png|border| 700px |center|alt=The current instructor view.|The current review display for instructors.]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''3. Error in existing UI for student''': In the existing UI for a student, the highlighted block should not be rendered. This part of the screen is meant for the instructors/TAs. &lt;br /&gt;
&lt;br /&gt;
[[File:Wrong render for student.png|border|700px|center|alt=Existing UI for student|Existing UI for student.]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Proposed changes ==&lt;br /&gt;
&lt;br /&gt;
''' 1) Proposed UI for instructor ''': The instructor is able to see the score for all teammates. In the existing code, only one teammate's scores are being shown. But, we are planning to change the way the (VmQuestionResponse array is populated)[https://github.com/expertiza/expertiza/blob/master/app/controllers/grades_controller.rb#L114], so that the scores for all teammates are appended to it so it correctly shows what should have already been shown in this screen for the instructor.&lt;br /&gt;
&lt;br /&gt;
[[File:Proposed_screen.png|border|700px|center|alt=Proposed UI for instructor|Proposed UI for instructor.]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Note: When a student visits this screen, they will only be shown the reviews received by them, assuming the instructor has allowed visibility of teammate reviews to students.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
''' 2) Show detailed review for a particular question''': The instructor can see detailed review given to a student by their teammates by clicking on a particular question number in the table.&lt;br /&gt;
&lt;br /&gt;
[[File:ss12a.png|border|700px|center|alt=New UI for students|New UI for students ]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
''' 3) Show teammate review to student UI ''': The existing code doesn't render a student's teammate review scores at all. We are planning to render the scores to a student (as shown below) when they visit this screen. However, the visibility of this screen is contingent on whether the instructor has allowed visibility of the teammate review screen to students. If the instructor has disabled this feature, then the heatgrid will not be displayed at all.&lt;br /&gt;
&lt;br /&gt;
[[File:UI_for_student.png|border|700px|center|alt=New UI for students|New UI for students ]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== User Stories ==&lt;br /&gt;
&lt;br /&gt;
1. As an instructor, I can view what reviews one teammate has given to other teammates.&lt;br /&gt;
&lt;br /&gt;
2. As a student, I can view what reviews my teammates have given to me.&lt;br /&gt;
&lt;br /&gt;
3. As an instructor, I can choose if I want to see all student's teammates reviews together or one by one.&lt;br /&gt;
&lt;br /&gt;
4. As a student, if I am also a TA for another subject, I should not be able to see an instructor's view to the view_team page.&lt;br /&gt;
&lt;br /&gt;
5. As an instructor, I should be able to see the name of the reviewers for the reviews to a particular student.&lt;br /&gt;
&lt;br /&gt;
== Use case diagram for the system ==  &lt;br /&gt;
&lt;br /&gt;
[[File:vie_team_use_case.png|border|center]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Models used / Explanation of fixes ==&lt;br /&gt;
&lt;br /&gt;
The below diagram illustrates the proposed code change for showing all team members with the teammate review data to an instructor. The existing code only iterated on the `Participant` whose ID is present in the URL of the page. To fix this, we will iterate over all teammates of the given participant so that all teammate reviews for all team members are shown to the instructor.&lt;br /&gt;
&lt;br /&gt;
[[File:Logic e2165.png|border|center|alt=Flow diagram of proposed changes for showing team review data to instructor]]&lt;br /&gt;
&lt;br /&gt;
===Changes made to the code are shown below. Every change is shown and explained separately===&lt;br /&gt;
&lt;br /&gt;
====A. Added the following to app/assets/stylesheets/grades.scss:====&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    .teammate_table.hidden {&lt;br /&gt;
      display: none;&lt;br /&gt;
      }&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
====B. In app/controllers/grades_controller.rb: ====&lt;br /&gt;
&lt;br /&gt;
'''B.1:'''&lt;br /&gt;
&lt;br /&gt;
Old code: The existing code does not differentiate when adding a view model for the TeammateReview questionnaire&lt;br /&gt;
  questionnaires.each do |questionnaire|&lt;br /&gt;
     ...&lt;br /&gt;
     @vmlist &amp;lt;&amp;lt; populate_view_model(questionnaire)&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
New code: Since the current page URL contains an ID for the participant, from which we get an assignment, which gives us a list of questionnaires, we need to iterate all participants for a `TeammateReveiwQuestionnaire` questionnaire, so that we get the heatgrid view models for all members of a team.&lt;br /&gt;
  questionnaires.each do |questionnaire|&lt;br /&gt;
     ...&lt;br /&gt;
     if questionnaire.type == &amp;quot;TeammateReviewQuestionnaire&amp;quot;&lt;br /&gt;
        # as teammate review will be different for each participant&lt;br /&gt;
        # we need to create a separate table for each teammate&lt;br /&gt;
        @participant.team.participants.each do |team_participant|&lt;br /&gt;
          @vmlist &amp;lt;&amp;lt; populate_view_model(team_participant, questionnaire, @team)&lt;br /&gt;
        end&lt;br /&gt;
      else&lt;br /&gt;
        # only one participant needs iterating, as apart from teammatereview&lt;br /&gt;
        # all other reviews are at &amp;quot;team&amp;quot; level&lt;br /&gt;
        @vmlist &amp;lt;&amp;lt; populate_view_model(@participant, questionnaire, @team)&lt;br /&gt;
      end&lt;br /&gt;
   end&lt;br /&gt;
&lt;br /&gt;
'''B.2: '''&lt;br /&gt;
&lt;br /&gt;
Old code: This code uses @participant as an instance variable, but this structure will not work as we need to call this ViewModel with multiple participants when iterating for a teammate review questionnaire.&lt;br /&gt;
    def populate_view_model(questionnaire)&lt;br /&gt;
      vm = VmQuestionResponse.new(questionnaire, @assignment, @round)&lt;br /&gt;
      vmquestions = questionnaire.questions&lt;br /&gt;
      vm.add_questions(vmquestions)&lt;br /&gt;
      vm.add_team_members(@team)&lt;br /&gt;
      vm.add_reviews(@participant, @team, @assignment.vary_by_round)&lt;br /&gt;
      vm.number_of_comments_greater_than_10_words&lt;br /&gt;
      vm &lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
New code: We need to call this function with a separate participant in each invocation due to our change for TeammateReviewQuestionnaire, hence it makes sense to make `participant` as an argument to this function. Similarly, as `team` is a closely related model to `participant`, we are passing it as an argument, to keep this function as &amp;quot;pure&amp;quot; as possible.&lt;br /&gt;
    def populate_view_model(participant, questionnaire, team)&lt;br /&gt;
      ...&lt;br /&gt;
      vm.add_team_members(team)&lt;br /&gt;
      vm.add_reviews(participant, team, @assignment.vary_by_round)&lt;br /&gt;
      ...&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
====C. In app/models/vm_question_response.rb:====&lt;br /&gt;
&lt;br /&gt;
'''C.1: '''Added the reviewee_id method: Created a helper method within the VmQuestionReponse model to retrieve the `reviewee_id` for a heatgrid&lt;br /&gt;
&lt;br /&gt;
    def reviewee_id&lt;br /&gt;
      @participant_who_is_reviewee.user_id&lt;br /&gt;
    end &lt;br /&gt;
&lt;br /&gt;
'''C.2: '''Added the reviewee_name method: Created a helper method within the VmQuestionReponse model to retrieve the name of the student who is being reviewed for a heatgrid. This method uses the functionality to anonymize the name when we are in anonymized view.&lt;br /&gt;
&lt;br /&gt;
    def reviewee_name(ip_address = nil)&lt;br /&gt;
      part = @participant_who_is_reviewee&lt;br /&gt;
      User.find_by(id: part.user_id).fullname(ip_address)&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
'''C.3: '''&lt;br /&gt;
&lt;br /&gt;
Old code: Does not keep track of the student being reviewed&lt;br /&gt;
    elsif @questionnaire_type == &amp;quot;TeammateReviewQuestionnaire&amp;quot;&lt;br /&gt;
      reviews = participant.teammate_reviews&lt;br /&gt;
      reviews.each do |review|&lt;br /&gt;
        review_mapping = TeammateReviewResponseMap.find_by(id: review.map_id)&lt;br /&gt;
        participant = Participant.find(review_mapping.reviewer_id)&lt;br /&gt;
&lt;br /&gt;
New code: Add an instance variable to keep track of the student who is being reviewed in this VmQuestionReponse&lt;br /&gt;
    elsif @questionnaire_type == &amp;quot;TeammateReviewQuestionnaire&amp;quot;&lt;br /&gt;
      reviews = participant.teammate_reviews&lt;br /&gt;
      @participant_who_is_reviewee = participant&lt;br /&gt;
      reviews.each do |review|&lt;br /&gt;
        review_mapping = TeammateReviewResponseMap.find_by(id: review.map_id)&lt;br /&gt;
        participant = Participant.find(review_mapping.reviewer_id)&lt;br /&gt;
&lt;br /&gt;
'''C.4: '''&lt;br /&gt;
&lt;br /&gt;
Old code: Existing VmQuestionReponseScoreCell keeps no information about the reviewer, as it only stores the answer score&lt;br /&gt;
    row.score_row.push(VmQuestionResponseScoreCell.new(answer.answer, color_code, answer.comments, vm_tag_prompts))&lt;br /&gt;
&lt;br /&gt;
New code: Keep track of the response ID, so that we can retrieve the user ID for the reviewer in the model to use in the view file.&lt;br /&gt;
    &lt;br /&gt;
    row.score_row.push(VmQuestionResponseScoreCell.new(answer.answer, color_code, answer.comments, vm_tag_prompts, answer.response_id))&lt;br /&gt;
&lt;br /&gt;
====D. In app/models/vm_question_response_score_cell.rb:====&lt;br /&gt;
&lt;br /&gt;
'''D.1: '''In the method initialize of class VmQuestionResponseScoreCell&lt;br /&gt;
&lt;br /&gt;
Old code: Existing code doesn't keep track of the response id&lt;br /&gt;
    def initialize(score_value, color_code, comments, vmprompts = nil)&lt;br /&gt;
      @score_value = score_value&lt;br /&gt;
      @color_code = color_code&lt;br /&gt;
      @comment = comments&lt;br /&gt;
      @vm_prompts = vmprompts&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
New code: We added an instance variable to keep track of response_id&lt;br /&gt;
&lt;br /&gt;
    def initialize(score_value, color_code, comments, vmprompts = nil, response_id)&lt;br /&gt;
      ...&lt;br /&gt;
      @response_id = response_id&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
'''D.2: '''Added a method reviewer_id to the class VmQuestionResponseScoreCell: This helper method retrieves the ID for the reviewer who created this response.&lt;br /&gt;
&lt;br /&gt;
    def reviewer_id&lt;br /&gt;
      resp = Response.find(@response_id)&lt;br /&gt;
      map = ResponseMap.find(resp.map_id)&lt;br /&gt;
      map.reviewer_id&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
====E. In app/views/grades/_add_icon_to_name.html.erb:====&lt;br /&gt;
&lt;br /&gt;
'''E.1 '''Added the following code to the file: Write the code to generate the review text only once to reduce WET code&lt;br /&gt;
&lt;br /&gt;
    &amp;lt;%# Determine the content of the reviewed by text %&amp;gt;&lt;br /&gt;
    &amp;lt;% review_text = &amp;quot;&amp;quot; %&amp;gt;&lt;br /&gt;
    &amp;lt;% if @current_role_name.eql?'Student' or questionnaire_type != &amp;quot;TeammateReviewQuestionnaire&amp;quot; %&amp;gt;&lt;br /&gt;
      &amp;lt;%# Use Review {{index}} format for student view, and when questionnaire_type is not teammatereview %&amp;gt;&lt;br /&gt;
      &amp;lt;% review_text = &amp;quot;Review #{i + 1}&amp;quot; %&amp;gt;&lt;br /&gt;
    &amp;lt;% else %&amp;gt;&lt;br /&gt;
      &amp;lt;% resp = Response.find(review.id) %&amp;gt;&lt;br /&gt;
      &amp;lt;% map = ResponseMap.find(resp.map_id) %&amp;gt;&lt;br /&gt;
      &amp;lt;% reviewer_id = map.reviewer_id %&amp;gt;&lt;br /&gt;
      &amp;lt;% fullname = Participant.find_by(id: reviewer_id).fullname(session[:ip]) %&amp;gt;&lt;br /&gt;
      &amp;lt;% review_text = &amp;quot;Review by #{fullname}&amp;quot; %&amp;gt;&lt;br /&gt;
    &amp;lt;% end%&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''E.2: '''&lt;br /&gt;
&lt;br /&gt;
Old code: Existing code is very unreadable as it's not indented, and written in a single line with 359 characters, which breaks the ruby style guide rules&lt;br /&gt;
&lt;br /&gt;
    &amp;lt;% if review.done_by_staff_participant? %&amp;gt;&lt;br /&gt;
      &amp;lt;th class=&amp;quot;sorter-false&amp;quot;&amp;gt; &amp;lt;img data-toggle=&amp;quot;tooltip&amp;quot; data-placement=&amp;quot;right&amp;quot; title=&amp;quot;Icon indicates this review was done by course staff&amp;quot; class=&amp;quot;img_icon&amp;quot; src=&amp;quot;/assets/staff.png&amp;quot;&amp;gt; &amp;lt;a target=&amp;quot;_blank&amp;quot; href=&amp;quot;../response/view?id=&amp;lt;%= review.id.to_s %&amp;gt;&amp;quot;  data-toggle=&amp;quot;tooltip&amp;quot; data-placement=&amp;quot;right&amp;quot; title=&amp;quot;Click to see details&amp;quot;&amp;gt;&amp;lt;%= &amp;quot;Review &amp;quot; + i.to_s  %&amp;gt;&amp;lt;/a&amp;gt; &amp;lt;/th&amp;gt;&lt;br /&gt;
    &amp;lt;% else %&amp;gt;&lt;br /&gt;
      &amp;lt;th class=&amp;quot;sorter-false&amp;quot;&amp;gt; &amp;lt;a target=&amp;quot;_blank&amp;quot; href=&amp;quot;../response/view?id=&amp;lt;%= review.id.to_s %&amp;gt;&amp;quot;  data-toggle=&amp;quot;tooltip&amp;quot; data-placement=&amp;quot;right&amp;quot; title=&amp;quot;Click to see details&amp;quot;&amp;gt;&amp;lt;%= &amp;quot;Review &amp;quot; + i.to_s %&amp;gt;&amp;lt;/a&amp;gt;  &amp;lt;/th&amp;gt;&lt;br /&gt;
    &amp;lt;% end %&amp;gt;&lt;br /&gt;
&lt;br /&gt;
New code: Correctly indented and removes WET repetition of code blocks and makes the resulting code DRYer&lt;br /&gt;
&lt;br /&gt;
    &amp;lt;th class=&amp;quot;sorter-false&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;lt;% if review.done_by_staff_participant? %&amp;gt;&lt;br /&gt;
      &amp;lt;img&lt;br /&gt;
      data-toggle=&amp;quot;tooltip&amp;quot;&lt;br /&gt;
      data-placement=&amp;quot;right&amp;quot;&lt;br /&gt;
      title=&amp;quot;Icon indicates this review was done by course staff&amp;quot; class=&amp;quot;img_icon&amp;quot;&lt;br /&gt;
      src=&amp;quot;/assets/staff.png&amp;quot;&lt;br /&gt;
      &amp;gt;&lt;br /&gt;
    &amp;lt;% end %&amp;gt;&lt;br /&gt;
    &amp;lt;a&lt;br /&gt;
      target=&amp;quot;_blank&amp;quot;&lt;br /&gt;
      href=&amp;quot;../response/view?id=&amp;lt;%= review.id.to_s %&amp;gt;&amp;quot;&lt;br /&gt;
      data-toggle=&amp;quot;tooltip&amp;quot;&lt;br /&gt;
      data-placement=&amp;quot;right&amp;quot;&lt;br /&gt;
      title=&amp;quot;Click to see details&amp;quot;&amp;gt;&lt;br /&gt;
      &amp;lt;%= review_text %&amp;gt;&lt;br /&gt;
    &amp;lt;/a&amp;gt;&lt;br /&gt;
    &amp;lt;/th&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====F.In app/views/grades/view_team.html.erb:====&lt;br /&gt;
&lt;br /&gt;
'''F.1: '''Added function teammateSelectOnChange: This function toggles the visibility for the teammate heatgrids when the instructor changes the dropdown&lt;br /&gt;
    &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  function teammateSelectOnChange(selectNode) {&lt;br /&gt;
      const revieweeIdToShow= selectNode.value;&lt;br /&gt;
      const tableSelector = &amp;quot;.teammate_table&amp;quot;;&lt;br /&gt;
      if(revieweeIdToShow == &amp;quot;all&amp;quot;) {&lt;br /&gt;
        document.querySelectorAll(tableSelector).forEach((tableNode) =&amp;gt; {&lt;br /&gt;
          tableNode.classList.remove(&amp;quot;hidden&amp;quot;);&lt;br /&gt;
        });&lt;br /&gt;
        return;&lt;br /&gt;
      }&lt;br /&gt;
&lt;br /&gt;
    document.querySelectorAll(tableSelector).forEach((tableNode) =&amp;gt; {&lt;br /&gt;
      const tableRevieweeId = tableNode.getAttribute('data-reviewee_id');&lt;br /&gt;
      if(tableRevieweeId == revieweeIdToShow) {&lt;br /&gt;
        tableNode.classList.remove(&amp;quot;hidden&amp;quot;);&lt;br /&gt;
      } else {&lt;br /&gt;
        tableNode.classList.add(&amp;quot;hidden&amp;quot;);&lt;br /&gt;
      }&lt;br /&gt;
      });&lt;br /&gt;
    }&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''F.2: '''&lt;br /&gt;
&lt;br /&gt;
Old code: Existing code doesn't render TeammateReviewQuestionnaire&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    &amp;lt;% @vmlist.each do |vm| %&amp;gt;&lt;br /&gt;
        &amp;lt;% if (vm.questionnaire_display_type == &amp;quot;Metareview&amp;quot; or vm.questionnaire_display_type == &amp;quot;Author Feedback&amp;quot; or vm.questionnaire_display_type == &amp;quot;Teammate Review&amp;quot;) and @current_role_name.eql?'Student' %&amp;gt;&lt;br /&gt;
        &amp;lt;% else %&amp;gt;&lt;br /&gt;
        &amp;lt;% if vm.list_of_reviewers.length &amp;gt; 0 %&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
New code: Use a boolean to render a dropdown (that contains the students' IDs and names) just before the first TeammateReviewQuestionnaire, and unset that boolean so we only render 1 table. Add conditions which check for the truthiness of ```@assignment.show_teammate_reviews``` and if the current user is a student to decide whether to render the table or not. Finally, add a CSS class and a `data-reviewee_id` to keep track of the heatgrids when toggling visibility&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;%# This boolean is used to render a dropdown just before the first teammate review heat grid %&amp;gt;&lt;br /&gt;
&amp;lt;% first_teammate_review_appeared = false %&amp;gt;&lt;br /&gt;
&amp;lt;% @vmlist.each do |vm| %&amp;gt;&lt;br /&gt;
    &amp;lt;% if not @current_role_name.eql?'Student' and not first_teammate_review_appeared and vm.questionnaire_type == &amp;quot;TeammateReviewQuestionnaire&amp;quot; %&amp;gt;&lt;br /&gt;
      &amp;lt;div&amp;gt;&lt;br /&gt;
        &amp;lt;select onchange=&amp;quot;teammateSelectOnChange(this)&amp;quot;&amp;gt;&lt;br /&gt;
          &amp;lt;option value=&amp;quot;all&amp;quot;&amp;gt;All&amp;lt;/option&amp;gt;&lt;br /&gt;
          &amp;lt;% @vmlist.select { |tm_vm| tm_vm.questionnaire_type == &amp;quot;TeammateReviewQuestionnaire&amp;quot; }.each do |tm_vm| %&amp;gt;&lt;br /&gt;
            &amp;lt;option value=&amp;quot;&amp;lt;%= tm_vm.reviewee_id %&amp;gt;&amp;quot;&amp;gt;&lt;br /&gt;
              &amp;lt;%= tm_vm.reviewee_name(session[:ip]) %&amp;gt;&lt;br /&gt;
            &amp;lt;/option&amp;gt;&lt;br /&gt;
          &amp;lt;% end %&amp;gt;&lt;br /&gt;
        &amp;lt;/select&amp;gt;&lt;br /&gt;
      &amp;lt;/div&amp;gt;&lt;br /&gt;
      &amp;lt;% first_teammate_review_appeared = true %&amp;gt;&lt;br /&gt;
    &amp;lt;% end %&amp;gt;&lt;br /&gt;
    &amp;lt;% if (vm.questionnaire_display_type == &amp;quot;Metareview&amp;quot; or vm.questionnaire_display_type == &amp;quot;Author Feedback&amp;quot;) and @current_role_name.eql?'Student' %&amp;gt;&lt;br /&gt;
    &amp;lt;% elsif (vm.questionnaire_type == &amp;quot;TeammateReviewQuestionnaire&amp;quot; and @current_role_name.eql?'Student' and !@assignment.show_teammate_reviews)%&amp;gt;&lt;br /&gt;
    &amp;lt;% elsif (vm.questionnaire_type == &amp;quot;TeammateReviewQuestionnaire&amp;quot; and @current_role_name.eql?'Student' and @assignment.show_teammate_reviews and current_user.id != vm.reviewee_id )%&amp;gt;&lt;br /&gt;
    &amp;lt;% else %&amp;gt;&lt;br /&gt;
        &amp;lt;% if vm.questionnaire_type == &amp;quot;TeammateReviewQuestionnaire&amp;quot; %&amp;gt;&lt;br /&gt;
          &amp;lt;div class=&amp;quot;teammate_table&amp;quot; data-reviewee_id=&amp;quot;&amp;lt;%= vm.reviewee_id %&amp;gt;&amp;quot;&amp;gt;&lt;br /&gt;
        &amp;lt;% else %&amp;gt;&lt;br /&gt;
          &amp;lt;div&amp;gt;&lt;br /&gt;
        &amp;lt;% end %&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''F.3  '''&lt;br /&gt;
&lt;br /&gt;
Old code: Existing code doesn't print the teammate who is being reviewed.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;!-- display the list of questions for this questionnaire --&amp;gt;&lt;br /&gt;
          &amp;lt;h4 style=&amp;quot;display:inline-block;&amp;quot;&amp;gt;&amp;lt;%= vm.questionnaire_display_type %&amp;gt;&lt;br /&gt;
            &amp;lt;% if vm.questionnaire_type == &amp;quot;ReviewQuestionnaire&amp;quot; %&amp;gt;&lt;br /&gt;
                (Round: &amp;lt;%= vm.round.to_s  %&amp;gt; of &amp;lt;%= vm.rounds.to_s  %&amp;gt;)&lt;br /&gt;
            &amp;lt;%end %&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
New code: If TeammteReviewQuestionnaire is used, then use the `:reviewee_name` method for VmQuestionResponse model to print the name of the student who is being reviewed.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;!-- display the list of questions for this questionnaire --&amp;gt;&lt;br /&gt;
          &amp;lt;h4 style=&amp;quot;display:inline-block;&amp;quot;&amp;gt;&amp;lt;%= vm.questionnaire_display_type %&amp;gt;&lt;br /&gt;
            &amp;lt;% if vm.questionnaire_type == &amp;quot;ReviewQuestionnaire&amp;quot; %&amp;gt;&lt;br /&gt;
                (Round: &amp;lt;%= vm.round.to_s  %&amp;gt; of &amp;lt;%= vm.rounds.to_s  %&amp;gt;)&lt;br /&gt;
            &amp;lt;% elsif vm.questionnaire_type == &amp;quot;TeammateReviewQuestionnaire&amp;quot; %&amp;gt;&lt;br /&gt;
                (For: &amp;lt;%= vm.reviewee_name(session[:ip]) %&amp;gt;)&lt;br /&gt;
            &amp;lt;%end %&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''F.4 '''&lt;br /&gt;
&lt;br /&gt;
Old code: Existing code doesn't inform the partial about the type of review being done&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;% vm.list_of_reviews.each do |review| %&amp;gt;&lt;br /&gt;
              &amp;lt;!-- instructors (or higher level users) see reviewer name, students see anonymized string --&amp;gt;&lt;br /&gt;
              &amp;lt;% if (['Student'].include? @current_role_name) &amp;amp;&amp;amp; @assignment.is_anonymous%&amp;gt;&lt;br /&gt;
                &amp;lt;%= render :partial =&amp;gt; 'add_icon_to_name', :locals =&amp;gt; {review: review, i: i} %&amp;gt;&lt;br /&gt;
              &amp;lt;% else %&amp;gt;&lt;br /&gt;
                  &amp;lt;% user_name = User.find(Participant.find(ResponseMap.find(Response.find(review.id).map_id).reviewer_id).user_id).fullname(session[:ip]).to_s %&amp;gt;&lt;br /&gt;
                &amp;lt;%= render :partial =&amp;gt; 'add_icon_to_name', :locals =&amp;gt; {review: review, i: i} %&amp;gt;&lt;br /&gt;
              &amp;lt;% end %&amp;gt;&lt;br /&gt;
              &amp;lt;% i += 1 %&amp;gt;&lt;br /&gt;
          &amp;lt;% end %&amp;gt;&lt;br /&gt;
New code: Passes the type of review being done to the partial, so it can decide on how to render the review title. Note: This code seems to use repetition, but since the conditional used here are accessing `Anonymous` assignments and checking for user roles, we have not modified this code, as it is not directly related to our scope.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;% vm.list_of_reviews.each do |review| %&amp;gt;&lt;br /&gt;
              &amp;lt;!-- instructors (or higher level users) see reviewer name, students see anonymized string --&amp;gt;&lt;br /&gt;
              &amp;lt;% if (['Student'].include? @current_role_name) &amp;amp;&amp;amp; @assignment.is_anonymous%&amp;gt;&lt;br /&gt;
                &amp;lt;%= render :partial =&amp;gt; 'add_icon_to_name', :locals =&amp;gt; {review: review, i: i, questionnaire_type: vm.questionnaire_type } %&amp;gt;&lt;br /&gt;
              &amp;lt;% else %&amp;gt;&lt;br /&gt;
                &amp;lt;% user_name = User.find(Participant.find(ResponseMap.find(Response.find(review.id).map_id).reviewer_id).user_id).fullname(session[:ip]).to_s %&amp;gt;&lt;br /&gt;
                &amp;lt;%= render :partial =&amp;gt; 'add_icon_to_name', :locals =&amp;gt; {review: review, i: i, questionnaire_type: vm.questionnaire_type } %&amp;gt;&lt;br /&gt;
              &amp;lt;% end %&amp;gt;&lt;br /&gt;
              &amp;lt;% i += 1 %&amp;gt;&lt;br /&gt;
          &amp;lt;% end %&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Old code: Contains a `metrics-1` column&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
          &amp;lt;th class=&amp;quot;sorter-true&amp;quot; align=&amp;quot;right&amp;quot; &amp;gt;&lt;br /&gt;
            Avg&amp;lt;span&amp;gt;&amp;lt;/span&amp;gt;&lt;br /&gt;
          &amp;lt;/th&amp;gt;&lt;br /&gt;
          &amp;lt;th class=&amp;quot;sorter-false&amp;quot;&amp;gt;&lt;br /&gt;
            &amp;lt;span  data-toggle=&amp;quot;tooltip&amp;quot; data-placement=&amp;quot;right&amp;quot; title=&amp;quot;A count of comments, for the respective question, which have word count &amp;gt; 10. The purpose of this metric is to represent how many comments for the question are of a substantial length to provide quality feedback.&amp;quot;&amp;gt;metric-1&amp;lt;/span&amp;gt;&lt;br /&gt;
          &amp;lt;/th&amp;gt;&lt;br /&gt;
        &amp;lt;/tr&amp;gt;&lt;br /&gt;
        &amp;lt;/thead&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
New code: As per discussion with mentor, this column has been removed in our PR.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
          &amp;lt;th class=&amp;quot;sorter-true&amp;quot; align=&amp;quot;right&amp;quot; &amp;gt;&lt;br /&gt;
            Avg&amp;lt;span&amp;gt;&amp;lt;/span&amp;gt;&lt;br /&gt;
          &amp;lt;/th&amp;gt;&lt;br /&gt;
        &amp;lt;/tr&amp;gt;&lt;br /&gt;
        &amp;lt;/thead&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''F.5 '''&lt;br /&gt;
&lt;br /&gt;
Old code: It creates the ID inline in multiple places, so if we decide to change the ID generation logic, we need to modify it in multiple places. (which happened when we started rendering multiple tables for each teammate).&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;% vm.list_of_rows.each do |row| %&amp;gt;&lt;br /&gt;
            &amp;lt;!-- notice the data-target. because we're toggling via looped code, we need to dynamically generate the identifier. --&amp;gt;&lt;br /&gt;
            &amp;lt;tr data-toggle=&amp;quot;collapse&amp;quot; class=&amp;quot;accordion-toggle&amp;quot; data-target=&amp;quot;#hid&amp;lt;%= row.question_id.to_s + vm.round.to_s %&amp;gt;&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
New code: Generate the unique HTML ID once, in a readable manner once. And conditionally make it more unique, if it is a TeammateReviewQuestionnaire, since jQuery code requires these IDs to be unique amongst different tables. If we don't make it more unique, then clicking on one teammate review table will toggle the table visibility for the first table. To prevent this &amp;quot;clashing&amp;quot;, we need to make these IDs more unique for a TeammateReviewQuestionnaire.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;% vm.list_of_rows.each do |row| %&amp;gt;&lt;br /&gt;
            &amp;lt;% target_id = &amp;quot;hid__#{row.question_id}__#{vm.round}&amp;quot; %&amp;gt;&lt;br /&gt;
            &amp;lt;% if vm.questionnaire_type == &amp;quot;TeammateReviewQuestionnaire&amp;quot; %&amp;gt;&lt;br /&gt;
              &amp;lt;%# Since we render different heatgrids with the same questions for each&lt;br /&gt;
              teammember, we need to distinguish the ID, based on the user for whom,&lt;br /&gt;
              the reviews have been created. %&amp;gt;&lt;br /&gt;
              &amp;lt;% target_id += &amp;quot;__#{vm.reviewee_id}&amp;quot; %&amp;gt;&lt;br /&gt;
            &amp;lt;% end%&amp;gt;&lt;br /&gt;
&lt;br /&gt;
            &amp;lt;!-- notice the data-target. because we're toggling via looped code, we need to dynamically generate the identifier. --&amp;gt;&lt;br /&gt;
            &amp;lt;tr data-toggle=&amp;quot;collapse&amp;quot; class=&amp;quot;accordion-toggle&amp;quot; data-target=&amp;quot;&amp;lt;%= &amp;quot;#&amp;quot; + target_id %&amp;gt;&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Old code: Written on a single line crossing 80 characters on a single line&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
              &amp;lt;% row.score_row.each do |score| %&amp;gt;&lt;br /&gt;
                  &amp;lt;% score_comment = score.comment.nil? ? '' : score.comment %&amp;gt; &amp;lt;!-- changing nil to null string to avoid Null Pointer Exception --&amp;gt;&lt;br /&gt;
                  &amp;lt;td class=&amp;quot;&amp;lt;%= score.color_code %&amp;gt;&amp;quot; align=&amp;quot;center&amp;quot; data-toggle=&amp;quot;tooltip&amp;quot; title=&amp;quot;&amp;lt;%= strip_tags(score.comment).html_safe%&amp;gt;&amp;quot;&amp;gt;&lt;br /&gt;
                    &amp;lt;span class=&amp;quot;&amp;lt;%=  underlined?(score) %&amp;gt;&amp;quot;&amp;gt;&amp;lt;%= score.score_value.to_s %&amp;gt;&amp;lt;/span&amp;gt;&lt;br /&gt;
                  &amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;% end %&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
New code: Make code more readable by indenting it and splitting it over multiple lines&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
              &amp;lt;!-- actual cells with scores and colored background. --&amp;gt;&lt;br /&gt;
              &amp;lt;% row.score_row.each do |score| %&amp;gt;&lt;br /&gt;
                  &amp;lt;% score_comment = score.comment.nil? ? '' : score.comment %&amp;gt;&lt;br /&gt;
                  &amp;lt;!-- changing nil to null string to avoid Null Pointer Exception --&amp;gt;&lt;br /&gt;
                  &amp;lt;td class=&amp;quot;&amp;lt;%= score.color_code %&amp;gt;&amp;quot; align=&amp;quot;center&amp;quot; data-toggle=&amp;quot;tooltip&amp;quot; title=&amp;quot;&amp;lt;%= strip_tags(score.comment).html_safe%&amp;gt;&amp;quot;&amp;gt;&lt;br /&gt;
                    &amp;lt;span class=&amp;quot;&amp;lt;%=  underlined?(score) %&amp;gt;&amp;quot;&amp;gt;&lt;br /&gt;
                      &amp;lt;%= score.score_value.to_s %&amp;gt;&lt;br /&gt;
                    &amp;lt;/span&amp;gt;&lt;br /&gt;
                  &amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;% end %&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''F.6 '''Removed the following code as it corresponds to the deleted column&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 &amp;lt;td  class = 'cf' align=&amp;quot;center&amp;quot;&amp;gt;&lt;br /&gt;
                &amp;lt;%= row.countofcomments.to_s %&amp;gt;&lt;br /&gt;
              &amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''F.7 '''&lt;br /&gt;
&lt;br /&gt;
Old code: Existing code just unconditionally prints the text &amp;quot;Review&amp;quot; followed by an index.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
                    &amp;lt;% for index in 0 .. row.score_row.length - 1 %&amp;gt;&lt;br /&gt;
                        &amp;lt;tr&amp;gt;&lt;br /&gt;
                          &amp;lt;td&amp;gt;Review &amp;lt;%=index + 1%&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
New code: Conditionally change the review text that is displayed based on the type of review and the access level of the user&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
                    &amp;lt;% for index in 0 .. row.score_row.length - 1 %&amp;gt;&lt;br /&gt;
                        &amp;lt;tr&amp;gt;&lt;br /&gt;
                          &amp;lt;% if @current_role_name.eql?'Student' or vm.questionnaire_type != &amp;quot;TeammateReviewQuestionnaire&amp;quot; %&amp;gt;&lt;br /&gt;
                            &amp;lt;%# Use Review {{index}} format for student view, and&lt;br /&gt;
                            when questionnaire_type is not teammatereview %&amp;gt;&lt;br /&gt;
                            &amp;lt;td&amp;gt;Review &amp;lt;%=index + 1%&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
                          &amp;lt;% else %&amp;gt;&lt;br /&gt;
                            &amp;lt;td&amp;gt;&lt;br /&gt;
                              &amp;lt;% reviewer_id = row.score_row[index].reviewer_id %&amp;gt;&lt;br /&gt;
                              &amp;lt;% fullname = Participant.find_by(id: reviewer_id).fullname(session[:ip]) %&amp;gt;&lt;br /&gt;
                              Review by &amp;lt;%= fullname %&amp;gt;&lt;br /&gt;
                            &amp;lt;/td&amp;gt;&lt;br /&gt;
                          &amp;lt;% end%&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====G. In spec/controllers/grades_controller_spec.rb:====&lt;br /&gt;
&lt;br /&gt;
'''G.1 '''&lt;br /&gt;
&lt;br /&gt;
Old code&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
before(:each) do&lt;br /&gt;
  allow(AssignmentParticipant).to receive(:find).with('1').and_return(participant)&lt;br /&gt;
  allow(participant).to receive(:team).and_return(team)&lt;br /&gt;
  stub_current_user(instructor, instructor.role.name, instructor.role)&lt;br /&gt;
  allow(Assignment).to receive(:find).with('1').and_return(assignment)&lt;br /&gt;
@@ -91,29 +90,106 @@&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
New code&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
before(:each) do&lt;br /&gt;
  allow(participant).to receive(:team).and_return(team)&lt;br /&gt;
  stub_current_user(instructor, instructor.role.name, instructor.role)&lt;br /&gt;
  allow(Assignment).to receive(:find).with('1').and_return(assignment)&lt;br /&gt;
@@ -91,29 +90,106 @@&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''G.2 '''Remove xdescribe '#view_team' and change describe '#view_team' as follows.&lt;br /&gt;
&lt;br /&gt;
Old code&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
describe '#view_team' do&lt;br /&gt;
render_views&lt;br /&gt;
context 'when view_team page is viewed by a student who is also a TA for another course' do&lt;br /&gt;
  it 'renders grades#view_team page' do&lt;br /&gt;
    allow(participant).to receive(:team).and_return(team)&lt;br /&gt;
    allow(AssignmentQuestionnaire).to receive(:find_by).with(assignment_id: 1, questionnaire_id: 1).and_return(assignment_questionnaire)&lt;br /&gt;
    allow(AssignmentQuestionnaire).to receive(:where).with(any_args).and_return([assignment_questionnaire])&lt;br /&gt;
    allow(assignment).to receive(:late_policy_id).and_return(false)&lt;br /&gt;
    allow(assignment).to receive(:calculate_penalty).and_return(false)&lt;br /&gt;
    allow(assignment).to receive(:compute_total_score).with(any_args).and_return(100)&lt;br /&gt;
    allow(review_questionnaire).to receive(:get_assessments_round_for).with(participant, 1).and_return([review_response])&lt;br /&gt;
    allow(Answer).to receive(:compute_scores).with([review_response], [question]).and_return(max: 95, min: 88, avg: 90)&lt;br /&gt;
    params = {id: 1}&lt;br /&gt;
    allow(TaMapping).to receive(:exists?).with(ta_id: 1, course_id: 1).and_return(true)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
New code&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
describe '#view_team' do&lt;br /&gt;
render_views&lt;br /&gt;
&lt;br /&gt;
# All stubs and factories are instantiated within this scope so as to not &lt;br /&gt;
# clash with other broken test.&lt;br /&gt;
# The names of the factories created for testing view_team&lt;br /&gt;
# have `_vt` suffix ```where necessary``` to differentiate them from &lt;br /&gt;
# the above declared factories&lt;br /&gt;
&lt;br /&gt;
let(:student1_vt) { create(:student, name: &amp;quot;barry&amp;quot;, id: 12) }&lt;br /&gt;
let(:student2_vt) { create(:student, name: &amp;quot;iris&amp;quot;, id: 13) }&lt;br /&gt;
&lt;br /&gt;
let(:tm_questionnaire) {&lt;br /&gt;
  build(&lt;br /&gt;
    :teammate_review_questionnaire,&lt;br /&gt;
    id: 12,&lt;br /&gt;
    questions: [question],&lt;br /&gt;
    max_question_score: 5&lt;br /&gt;
  )&lt;br /&gt;
}&lt;br /&gt;
let(:assignment_vt) {&lt;br /&gt;
  create(:assignment, id: 6, max_team_size: 2,&lt;br /&gt;
  questionnaires: [tm_questionnaire])&lt;br /&gt;
}&lt;br /&gt;
let(:assignment_questionnaire_vt) {&lt;br /&gt;
  create(:tm_assignment_questionnaire, id: 12, used_in_round: nil,&lt;br /&gt;
  assignment: assignment_vt, questionnaire: tm_questionnaire) }&lt;br /&gt;
let(:team_vt) { create(:assignment_team, id: 12,&lt;br /&gt;
assignment: assignment_vt) }&lt;br /&gt;
let(:participant_vt) { create(:participant, id: 12,&lt;br /&gt;
  assignment: assignment_vt, user_id: student1_vt.id) }&lt;br /&gt;
let(:participant2_vt) { create(:participant, id: 13,&lt;br /&gt;
  assignment: assignment_vt, user_id: student2_vt.id) }&lt;br /&gt;
&lt;br /&gt;
before(:each) do&lt;br /&gt;
  # Need to stub this method so the factory instance with&lt;br /&gt;
  # the stubbed :team method is returned by :find&lt;br /&gt;
  # instead of a separate instance with the same data&lt;br /&gt;
  allow(AssignmentParticipant)&lt;br /&gt;
    .to receive(:find)&lt;br /&gt;
    .with(participant_vt.id.to_s)&lt;br /&gt;
    .and_return(participant_vt)&lt;br /&gt;
  allow(participant_vt).to receive(:team).and_return(team_vt)&lt;br /&gt;
  allow(team_vt).to receive(:participants).and_return([participant_vt, participant2_vt])&lt;br /&gt;
  allow(AssignmentQuestionnaire)&lt;br /&gt;
    .to receive(:find_by)&lt;br /&gt;
    .with(assignment_id: assignment_vt.id, questionnaire_id: tm_questionnaire.id)&lt;br /&gt;
    .and_return(assignment_questionnaire_vt)&lt;br /&gt;
  allow(AssignmentQuestionnaire)&lt;br /&gt;
    .to receive(:find_by)&lt;br /&gt;
    .with(assignment_id: assignment.id, questionnaire_id: review_questionnaire.id)&lt;br /&gt;
    .and_return(assignment_questionnaire_vt)&lt;br /&gt;
  allow(AssignmentQuestionnaire)&lt;br /&gt;
    .to receive(:where)&lt;br /&gt;
    .with(any_args)&lt;br /&gt;
    .and_return([assignment_questionnaire_vt])&lt;br /&gt;
  allow(assignment_vt)&lt;br /&gt;
    .to receive(:late_policy_id)&lt;br /&gt;
    .and_return(false)&lt;br /&gt;
  allow(assignment_vt)&lt;br /&gt;
    .to receive(:calculate_penalty)&lt;br /&gt;
    .and_return(false)&lt;br /&gt;
  allow(assignment_vt)&lt;br /&gt;
    .to receive(:compute_total_score)&lt;br /&gt;
    .with(any_args)&lt;br /&gt;
    .and_return(100)&lt;br /&gt;
  allow(review_questionnaire).to receive(:get_assessments_round_for).with(participant, 1).and_return([review_response])&lt;br /&gt;
  allow(Answer).to receive(:compute_scores).with([review_response], [question]).and_return(max: 95, min: 88, avg: 90)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
 it 'renders grades#view_team page' do&lt;br /&gt;
  params = {id: participant_vt.id}&lt;br /&gt;
  get :view_team, params&lt;br /&gt;
  expect(response).to render_template(:view_team)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
context 'when view_team page is opened by student' do&lt;br /&gt;
  it 'dropdown is not rendered' do&lt;br /&gt;
    session = { user: student1_vt }&lt;br /&gt;
    params = {id: participant_vt.id}&lt;br /&gt;
    stub_current_user(student1_vt, student1_vt.role.name, student1_vt.role)&lt;br /&gt;
    get :view_team, params&lt;br /&gt;
    expect(response.body).to_not have_selector('select')&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
context 'when view_team page is opened by instructor' do&lt;br /&gt;
  it 'dropdown is rendered' do&lt;br /&gt;
    session = { user: instructor }&lt;br /&gt;
    params = {id: participant_vt.id}&lt;br /&gt;
    get :view_team, params&lt;br /&gt;
    expect(response.body).to have_selector('select')&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
context 'when view_team page is viewed by a student who is also a TA for another course' do&lt;br /&gt;
  it 'renders grades#view_team page' do&lt;br /&gt;
    params = { id: participant_vt.id }&lt;br /&gt;
    allow(TaMapping).to receive(:exists?).with(ta_id: participant_vt.user_id, course_id: 1).and_return(true)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
====H. In spec/factories/factories.rb:====&lt;br /&gt;
&lt;br /&gt;
'''H.1 '''Add the following factory:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
factory :teammate_review_questionnaire, class: TeammateReviewQuestionnaire do&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''H.2 '''Add another factory&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
factory :tm_assignment_questionnaire, class: AssignmentQuestionnaire do&lt;br /&gt;
  user_id 1&lt;br /&gt;
  questionnaire { association(:teammate_review_questionnaire) }&lt;br /&gt;
  questionnaire_weight 100&lt;br /&gt;
  used_in_round nil&lt;br /&gt;
  topic_id nil&lt;br /&gt;
  dropdown 1&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Testing ==&lt;br /&gt;
'''OLD STATUS'''&lt;br /&gt;
&lt;br /&gt;
1. Earlier, the tests only covered if the view_team is page is rendered when it is asked for. This can be seen on the line 94 and 103 in [https://github.com/expertiza/expertiza/blob/beta/spec/controllers/grades_controller_spec.rb this] file.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''NEW STATUS'''&lt;br /&gt;
&lt;br /&gt;
1. The view_team page is rendered correctly for a given student or an instructor.&lt;br /&gt;
&lt;br /&gt;
2. When students access then the view_team page, the dropdown to select a student's teammate reviews is not rendered on the page.&lt;br /&gt;
&lt;br /&gt;
3. When instructor access then the view_team page, the dropdown to select a student's teammate reviews is rendered on the page.&lt;br /&gt;
&lt;br /&gt;
4. When a student who is also a TA for another course access the view_team page, that student should be able to a student's view to the page.&lt;br /&gt;
&lt;br /&gt;
5. If show_teammate_reviews boolean is set to False, then the student should not be able to see the teammate reviews given to him/her. If it is set to True, then the student should be able to see the reviews.&lt;br /&gt;
&lt;br /&gt;
6. An instructor should be able to see the teammate reviews for all students regardless of whether the show_teammate_reviews boolean is set to True or False.&lt;br /&gt;
&lt;br /&gt;
7. The reviewer id is tracked correctly to show the correct reviewer name in the teammate reviews table. This can be seen on line 27 in [https://github.com/expertiza/expertiza/blob/66239d9a8a53697ea170a92208593b36d06dfd24/spec/models/vm_question_response_score_cell_spec.rb this] file &lt;br /&gt;
&lt;br /&gt;
8. An instructor can select which student's scores he/she wants to see. If no student's name is selected then the professor can see the scores of all the students.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Summary of file changes ==&lt;br /&gt;
&lt;br /&gt;
The following files are modified:&lt;br /&gt;
&lt;br /&gt;
1. app/controllers/grades_controller.rb - Controller file which changed how the view model is populated&lt;br /&gt;
&lt;br /&gt;
2. app/views/grades/view_team.html.erb - View file, which  conditionally rendered the teammate name, for a teammate review heatgrid&lt;br /&gt;
&lt;br /&gt;
3. spec/controllers/grades_controller_spec.rb - For tests verifying the proposed changes&lt;br /&gt;
&lt;br /&gt;
4. app/models/vm_question_response.rb - To modify the view-model so it can tell us the name of the person being reviewed for the current heatgrid&lt;br /&gt;
&lt;br /&gt;
5. app/models/vm_question_response_score_cell.rb - &lt;br /&gt;
&lt;br /&gt;
6. app/assets/stylesheets/grades.scss - &lt;br /&gt;
&lt;br /&gt;
7. app/views/grades/_add_icon_to_name.html.erb - &lt;br /&gt;
&lt;br /&gt;
8. spec/factories/factories.rb -&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Design Patterns ==&lt;br /&gt;
&lt;br /&gt;
Existing code does not use any design patterns, apart from if-else. It uses if-else conditional statements to check what type of questionnaire is present in the viewmodel `VmQuestionResponse`, and based on that, it renders the appropriate content.&lt;br /&gt;
&lt;br /&gt;
We decided to continue with this approach since to change the present coding style, there were required many changes (refactoring) to many files which were out of the scope of the present project. To complete the project in the assigned time, we followed the if-else approach.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==References==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;https://expertiza.ncsu.edu/&amp;lt;/p&amp;gt;&lt;/div&gt;</summary>
		<author><name>Vdeshmu</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2021_-_E2165._Fix_teammate-review_view&amp;diff=141745</id>
		<title>CSC/ECE 517 Fall 2021 - E2165. Fix teammate-review view</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2021_-_E2165._Fix_teammate-review_view&amp;diff=141745"/>
		<updated>2021-11-28T18:46:57Z</updated>

		<summary type="html">&lt;p&gt;Vdeshmu: /* F.In app/views/grades/view_team.html.erb: */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Team Introduction ==&lt;br /&gt;
&lt;br /&gt;
Dr. Edward Gehringer (instructor), Parimal Mehta (mentor)&lt;br /&gt;
&lt;br /&gt;
1. Anjali Garg (unity ID : agarg25)&lt;br /&gt;
&lt;br /&gt;
2. Arvasu Chikara (unity ID: achikar2)&lt;br /&gt;
&lt;br /&gt;
3. Lalit Bangad (unity ID: llbangad)&lt;br /&gt;
&lt;br /&gt;
4. Vinay Deshmukh (unity ID: vdeshmu)&lt;br /&gt;
&lt;br /&gt;
== Problems to be addressed ==&lt;br /&gt;
&lt;br /&gt;
After a project is submitted and reviewed, both the team members (students) and instructors should be able to view the teammate reviews. Students should be able to view the reviews by going to a particular assignment's -&amp;gt; your scores, at the bottom of the page. An instructor can view the teammate reviews by going to assignments -&amp;gt; assignment -&amp;gt; particular team's submission -&amp;gt; view submission -&amp;gt; assign grades -&amp;gt; view scores. &lt;br /&gt;
&lt;br /&gt;
In the case of the instructor, a single heat grid is shown whereas in the case of a team member, we cant view the scores. In the heat grid, it is not clear if the scores visible are for the reviews that the student has *written* for their teammates or the scores that the student has *received* from their teammates. Additionally, for instructors can choose from a list of the students on the team, but they have no way to tell whether the heat grid shows the reviews done *by* that student or done *for* that student.&lt;br /&gt;
&lt;br /&gt;
== Methodology Overview ==&lt;br /&gt;
&lt;br /&gt;
We have divided our work in the following tasks to address the above problems:&lt;br /&gt;
&lt;br /&gt;
1. Distinguish reviews done for a student by rendering separates heatgrids for each student&lt;br /&gt;
&lt;br /&gt;
2. For instructors, the table will have sections based on the students&lt;br /&gt;
&lt;br /&gt;
3. Include a checkbox on the edit assignment page that enables/disables visibility of heat grid to students&lt;br /&gt;
&lt;br /&gt;
4. Fix the average column for a table (which breaks for some reviews)&lt;br /&gt;
&lt;br /&gt;
5. Show a composite score derived from all reviews.  Make this code generalized, so other kinds of heat grid views could use it.&lt;br /&gt;
&lt;br /&gt;
6. Changes should work even in an anonymized view&lt;br /&gt;
&lt;br /&gt;
== Motivations ==&lt;br /&gt;
&lt;br /&gt;
1. Enable users to clearly tell which reviews are done by them, and which reviews are done for them.&lt;br /&gt;
&lt;br /&gt;
2. Code should be generic so it can be used for different types of heat grids as well.&lt;br /&gt;
&lt;br /&gt;
== Control Flow to access the concerned screens ==&lt;br /&gt;
'''1. For instructor (Log in as an instructor):-'''&lt;br /&gt;
&lt;br /&gt;
Screen after logging in by the instructor&lt;br /&gt;
[[File:ss1.png |border|1000px|center]]&lt;br /&gt;
Got to assignments on the Manage menu &lt;br /&gt;
[[File:ss2.png |border|1000px|center]]&lt;br /&gt;
Go to assignments&lt;br /&gt;
[[File:ss3.png |border|1000px|center]]&lt;br /&gt;
Go to submissions for any assignment&lt;br /&gt;
[[File:ss4a.png |border|1000px|center]]&lt;br /&gt;
Go to Assign Grade&lt;br /&gt;
[[File:ss5a.png |border|1000px|center]]&lt;br /&gt;
You will land on the page where the changes are made and can be reviewed&lt;br /&gt;
[[File:ss7a.png |border|1000px|center]]&lt;br /&gt;
&lt;br /&gt;
'''2. Student:- (Logged in as an instructor)'''&lt;br /&gt;
&lt;br /&gt;
After landing on the assignments page, select any student from an assignment as shown below&lt;br /&gt;
[[File:ss6a.png |border|1000px|center]]&lt;br /&gt;
Go to/Select any assignment&lt;br /&gt;
[[File:ss9a.png |border|1000px|center]]&lt;br /&gt;
Go to your scores&lt;br /&gt;
[[File:ss10a.png |border|1000px|center]]&lt;br /&gt;
You will land on the page where the changes are made and can be reviewed&lt;br /&gt;
[[File:ss11a.png |border|1000px|center]]&lt;br /&gt;
&lt;br /&gt;
== Old Status of the application ==&lt;br /&gt;
&lt;br /&gt;
'''1. Instructor's view of teammate review''': This is the current screen given to the instructor. Here we see that the instructor can not determine who has given which review to which student in a team.&lt;br /&gt;
&lt;br /&gt;
[[File:Instructor-view-1.png|border| 700px |center|alt=The proposed expanded student display.|The proposed expanded student display.]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''2. Student's view of teammate review''': Currently, a student is not able to see what grades were given by their teammates. We need to implement that functionality so that the student is able to view those grades.&lt;br /&gt;
&lt;br /&gt;
[[File:Student-view-2.png|border| 700px |center|alt=The current instructor view.|The current review display for instructors.]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''3. Error in existing UI for student''': In the existing UI for a student, the highlighted block should not be rendered. This part of the screen is meant for the instructors/TAs. &lt;br /&gt;
&lt;br /&gt;
[[File:Wrong render for student.png|border|700px|center|alt=Existing UI for student|Existing UI for student.]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Proposed changes ==&lt;br /&gt;
&lt;br /&gt;
''' 1) Proposed UI for instructor ''': The instructor is able to see the score for all teammates. In the existing code, only one teammate's scores are being shown. But, we are planning to change the way the (VmQuestionResponse array is populated)[https://github.com/expertiza/expertiza/blob/master/app/controllers/grades_controller.rb#L114], so that the scores for all teammates are appended to it so it correctly shows what should have already been shown in this screen for the instructor.&lt;br /&gt;
&lt;br /&gt;
[[File:Proposed_screen.png|border|700px|center|alt=Proposed UI for instructor|Proposed UI for instructor.]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Note: When a student visits this screen, they will only be shown the reviews received by them, assuming the instructor has allowed visibility of teammate reviews to students.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
''' 2) Show detailed review for a particular question''': The instructor can see detailed review given to a student by their teammates by clicking on a particular question number in the table.&lt;br /&gt;
&lt;br /&gt;
[[File:ss12a.png|border|700px|center|alt=New UI for students|New UI for students ]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
''' 3) Show teammate review to student UI ''': The existing code doesn't render a student's teammate review scores at all. We are planning to render the scores to a student (as shown below) when they visit this screen. However, the visibility of this screen is contingent on whether the instructor has allowed visibility of the teammate review screen to students. If the instructor has disabled this feature, then the heatgrid will not be displayed at all.&lt;br /&gt;
&lt;br /&gt;
[[File:UI_for_student.png|border|700px|center|alt=New UI for students|New UI for students ]]&lt;br /&gt;
&lt;br /&gt;
== User Stories ==&lt;br /&gt;
&lt;br /&gt;
1. As an instructor, I can view what reviews one teammate has given to other teammates.&lt;br /&gt;
&lt;br /&gt;
2. As a student, I can view what reviews my teammates have given to me.&lt;br /&gt;
&lt;br /&gt;
3. As an instructor, I can choose if I want to see all student's teammates reviews together or one by one.&lt;br /&gt;
&lt;br /&gt;
4. As a student, if I am also a TA for another subject, I should not be able to see an instructor's view to the view_team page.&lt;br /&gt;
&lt;br /&gt;
5. As an instructor, I should be able to see the name of the reviewers for the reviews to a particular student.&lt;br /&gt;
&lt;br /&gt;
== Use case diagram for the system ==  &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Models used / Explanation of fixes ==&lt;br /&gt;
&lt;br /&gt;
The below diagram illustrates the proposed code change for showing all team members with the teammate review data to an instructor. The existing code only iterated on the `Participant` whose ID is present in the URL of the page. To fix this, we will iterate over all teammates of the given participant so that all teammate reviews for all team members are shown to the instructor.&lt;br /&gt;
&lt;br /&gt;
[[File:Logic e2165.png|border|center|alt=Flow diagram of proposed changes for showing team review data to instructor]]&lt;br /&gt;
&lt;br /&gt;
===Changes made to the code are shown below. Every change is shown and explained separately===&lt;br /&gt;
&lt;br /&gt;
====A. Added the following to app/assets/stylesheets/grades.scss:====&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    .teammate_table.hidden {&lt;br /&gt;
      display: none;&lt;br /&gt;
      }&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
====B. In app/controllers/grades_controller.rb: ====&lt;br /&gt;
&lt;br /&gt;
'''B.1:'''&lt;br /&gt;
&lt;br /&gt;
Old code: The existing code does not differentiate when adding a view model for the TeammateReview questionnaire&lt;br /&gt;
  questionnaires.each do |questionnaire|&lt;br /&gt;
     ...&lt;br /&gt;
     @vmlist &amp;lt;&amp;lt; populate_view_model(questionnaire)&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
New code: Since the current page URL contains an ID for the participant, from which we get an assignment, which gives us a list of questionnaires, we need to iterate all participants for a `TeammateReveiwQuestionnaire` questionnaire, so that we get the heatgrid view models for all members of a team.&lt;br /&gt;
  questionnaires.each do |questionnaire|&lt;br /&gt;
     ...&lt;br /&gt;
     if questionnaire.type == &amp;quot;TeammateReviewQuestionnaire&amp;quot;&lt;br /&gt;
        # as teammate review will be different for each participant&lt;br /&gt;
        # we need to create a separate table for each teammate&lt;br /&gt;
        @participant.team.participants.each do |team_participant|&lt;br /&gt;
          @vmlist &amp;lt;&amp;lt; populate_view_model(team_participant, questionnaire, @team)&lt;br /&gt;
        end&lt;br /&gt;
      else&lt;br /&gt;
        # only one participant needs iterating, as apart from teammatereview&lt;br /&gt;
        # all other reviews are at &amp;quot;team&amp;quot; level&lt;br /&gt;
        @vmlist &amp;lt;&amp;lt; populate_view_model(@participant, questionnaire, @team)&lt;br /&gt;
      end&lt;br /&gt;
   end&lt;br /&gt;
&lt;br /&gt;
'''B.2: '''&lt;br /&gt;
&lt;br /&gt;
Old code: This code uses @participant as an instance variable, but this structure will not work as we need to call this ViewModel with multiple participants when iterating for a teammate review questionnaire.&lt;br /&gt;
    def populate_view_model(questionnaire)&lt;br /&gt;
      vm = VmQuestionResponse.new(questionnaire, @assignment, @round)&lt;br /&gt;
      vmquestions = questionnaire.questions&lt;br /&gt;
      vm.add_questions(vmquestions)&lt;br /&gt;
      vm.add_team_members(@team)&lt;br /&gt;
      vm.add_reviews(@participant, @team, @assignment.vary_by_round)&lt;br /&gt;
      vm.number_of_comments_greater_than_10_words&lt;br /&gt;
      vm &lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
New code: We need to call this function with a separate participant in each invocation due to our change for TeammateReviewQuestionnaire, hence it makes sense to make `participant` as an argument to this function. Similarly, as `team` is a closely related model to `participant`, we are passing it as an argument, to keep this function as &amp;quot;pure&amp;quot; as possible.&lt;br /&gt;
    def populate_view_model(participant, questionnaire, team)&lt;br /&gt;
      ...&lt;br /&gt;
      vm.add_team_members(team)&lt;br /&gt;
      vm.add_reviews(participant, team, @assignment.vary_by_round)&lt;br /&gt;
      ...&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
====C. In app/models/vm_question_response.rb:====&lt;br /&gt;
&lt;br /&gt;
'''C.1: '''Added the reviewee_id method: Created a helper method within the VmQuestionReponse model to retrieve the `reviewee_id` for a heatgrid&lt;br /&gt;
&lt;br /&gt;
    def reviewee_id&lt;br /&gt;
      @participant_who_is_reviewee.user_id&lt;br /&gt;
    end &lt;br /&gt;
&lt;br /&gt;
'''C.2: '''Added the reviewee_name method: Created a helper method within the VmQuestionReponse model to retrieve the name of the student who is being reviewed for a heatgrid. This method uses the functionality to anonymize the name when we are in anonymized view.&lt;br /&gt;
&lt;br /&gt;
    def reviewee_name(ip_address = nil)&lt;br /&gt;
      part = @participant_who_is_reviewee&lt;br /&gt;
      User.find_by(id: part.user_id).fullname(ip_address)&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
'''C.3: '''&lt;br /&gt;
&lt;br /&gt;
Old code: Does not keep track of the student being reviewed&lt;br /&gt;
    elsif @questionnaire_type == &amp;quot;TeammateReviewQuestionnaire&amp;quot;&lt;br /&gt;
      reviews = participant.teammate_reviews&lt;br /&gt;
      reviews.each do |review|&lt;br /&gt;
        review_mapping = TeammateReviewResponseMap.find_by(id: review.map_id)&lt;br /&gt;
        participant = Participant.find(review_mapping.reviewer_id)&lt;br /&gt;
&lt;br /&gt;
New code: Add an instance variable to keep track of the student who is being reviewed in this VmQuestionReponse&lt;br /&gt;
    elsif @questionnaire_type == &amp;quot;TeammateReviewQuestionnaire&amp;quot;&lt;br /&gt;
      reviews = participant.teammate_reviews&lt;br /&gt;
      @participant_who_is_reviewee = participant&lt;br /&gt;
      reviews.each do |review|&lt;br /&gt;
        review_mapping = TeammateReviewResponseMap.find_by(id: review.map_id)&lt;br /&gt;
        participant = Participant.find(review_mapping.reviewer_id)&lt;br /&gt;
&lt;br /&gt;
'''C.4: '''&lt;br /&gt;
&lt;br /&gt;
Old code: Existing VmQuestionReponseScoreCell keeps no information about the reviewer, as it only stores the answer score&lt;br /&gt;
    row.score_row.push(VmQuestionResponseScoreCell.new(answer.answer, color_code, answer.comments, vm_tag_prompts))&lt;br /&gt;
&lt;br /&gt;
New code: Keep track of the response ID, so that we can retrieve the user ID for the reviewer in the model to use in the view file.&lt;br /&gt;
    &lt;br /&gt;
    row.score_row.push(VmQuestionResponseScoreCell.new(answer.answer, color_code, answer.comments, vm_tag_prompts, answer.response_id))&lt;br /&gt;
&lt;br /&gt;
====D. In app/models/vm_question_response_score_cell.rb:====&lt;br /&gt;
&lt;br /&gt;
'''D.1: '''In the method initialize of class VmQuestionResponseScoreCell&lt;br /&gt;
&lt;br /&gt;
Old code: Existing code doesn't keep track of the response id&lt;br /&gt;
    def initialize(score_value, color_code, comments, vmprompts = nil)&lt;br /&gt;
      @score_value = score_value&lt;br /&gt;
      @color_code = color_code&lt;br /&gt;
      @comment = comments&lt;br /&gt;
      @vm_prompts = vmprompts&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
New code: We added an instance variable to keep track of response_id&lt;br /&gt;
&lt;br /&gt;
    def initialize(score_value, color_code, comments, vmprompts = nil, response_id)&lt;br /&gt;
      ...&lt;br /&gt;
      @response_id = response_id&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
'''D.2: '''Added a method reviewer_id to the class VmQuestionResponseScoreCell: This helper method retrieves the ID for the reviewer who created this response.&lt;br /&gt;
&lt;br /&gt;
    def reviewer_id&lt;br /&gt;
      resp = Response.find(@response_id)&lt;br /&gt;
      map = ResponseMap.find(resp.map_id)&lt;br /&gt;
      map.reviewer_id&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
====E. In app/views/grades/_add_icon_to_name.html.erb:====&lt;br /&gt;
&lt;br /&gt;
'''E.1 '''Added the following code to the file: Write the code to generate the review text only once to reduce WET code&lt;br /&gt;
&lt;br /&gt;
    &amp;lt;%# Determine the content of the reviewed by text %&amp;gt;&lt;br /&gt;
    &amp;lt;% review_text = &amp;quot;&amp;quot; %&amp;gt;&lt;br /&gt;
    &amp;lt;% if @current_role_name.eql?'Student' or questionnaire_type != &amp;quot;TeammateReviewQuestionnaire&amp;quot; %&amp;gt;&lt;br /&gt;
      &amp;lt;%# Use Review {{index}} format for student view, and when questionnaire_type is not teammatereview %&amp;gt;&lt;br /&gt;
      &amp;lt;% review_text = &amp;quot;Review #{i + 1}&amp;quot; %&amp;gt;&lt;br /&gt;
    &amp;lt;% else %&amp;gt;&lt;br /&gt;
      &amp;lt;% resp = Response.find(review.id) %&amp;gt;&lt;br /&gt;
      &amp;lt;% map = ResponseMap.find(resp.map_id) %&amp;gt;&lt;br /&gt;
      &amp;lt;% reviewer_id = map.reviewer_id %&amp;gt;&lt;br /&gt;
      &amp;lt;% fullname = Participant.find_by(id: reviewer_id).fullname(session[:ip]) %&amp;gt;&lt;br /&gt;
      &amp;lt;% review_text = &amp;quot;Review by #{fullname}&amp;quot; %&amp;gt;&lt;br /&gt;
    &amp;lt;% end%&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''E.2: '''&lt;br /&gt;
&lt;br /&gt;
Old code: Existing code is very unreadable as it's not indented, and written in a single line with 359 characters, which breaks the ruby style guide rules&lt;br /&gt;
&lt;br /&gt;
    &amp;lt;% if review.done_by_staff_participant? %&amp;gt;&lt;br /&gt;
      &amp;lt;th class=&amp;quot;sorter-false&amp;quot;&amp;gt; &amp;lt;img data-toggle=&amp;quot;tooltip&amp;quot; data-placement=&amp;quot;right&amp;quot; title=&amp;quot;Icon indicates this review was done by course staff&amp;quot; class=&amp;quot;img_icon&amp;quot; src=&amp;quot;/assets/staff.png&amp;quot;&amp;gt; &amp;lt;a target=&amp;quot;_blank&amp;quot; href=&amp;quot;../response/view?id=&amp;lt;%= review.id.to_s %&amp;gt;&amp;quot;  data-toggle=&amp;quot;tooltip&amp;quot; data-placement=&amp;quot;right&amp;quot; title=&amp;quot;Click to see details&amp;quot;&amp;gt;&amp;lt;%= &amp;quot;Review &amp;quot; + i.to_s  %&amp;gt;&amp;lt;/a&amp;gt; &amp;lt;/th&amp;gt;&lt;br /&gt;
    &amp;lt;% else %&amp;gt;&lt;br /&gt;
      &amp;lt;th class=&amp;quot;sorter-false&amp;quot;&amp;gt; &amp;lt;a target=&amp;quot;_blank&amp;quot; href=&amp;quot;../response/view?id=&amp;lt;%= review.id.to_s %&amp;gt;&amp;quot;  data-toggle=&amp;quot;tooltip&amp;quot; data-placement=&amp;quot;right&amp;quot; title=&amp;quot;Click to see details&amp;quot;&amp;gt;&amp;lt;%= &amp;quot;Review &amp;quot; + i.to_s %&amp;gt;&amp;lt;/a&amp;gt;  &amp;lt;/th&amp;gt;&lt;br /&gt;
    &amp;lt;% end %&amp;gt;&lt;br /&gt;
&lt;br /&gt;
New code: Correctly indented and removes WET repetition of code blocks and makes the resulting code DRYer&lt;br /&gt;
&lt;br /&gt;
    &amp;lt;th class=&amp;quot;sorter-false&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;lt;% if review.done_by_staff_participant? %&amp;gt;&lt;br /&gt;
      &amp;lt;img&lt;br /&gt;
      data-toggle=&amp;quot;tooltip&amp;quot;&lt;br /&gt;
      data-placement=&amp;quot;right&amp;quot;&lt;br /&gt;
      title=&amp;quot;Icon indicates this review was done by course staff&amp;quot; class=&amp;quot;img_icon&amp;quot;&lt;br /&gt;
      src=&amp;quot;/assets/staff.png&amp;quot;&lt;br /&gt;
      &amp;gt;&lt;br /&gt;
    &amp;lt;% end %&amp;gt;&lt;br /&gt;
    &amp;lt;a&lt;br /&gt;
      target=&amp;quot;_blank&amp;quot;&lt;br /&gt;
      href=&amp;quot;../response/view?id=&amp;lt;%= review.id.to_s %&amp;gt;&amp;quot;&lt;br /&gt;
      data-toggle=&amp;quot;tooltip&amp;quot;&lt;br /&gt;
      data-placement=&amp;quot;right&amp;quot;&lt;br /&gt;
      title=&amp;quot;Click to see details&amp;quot;&amp;gt;&lt;br /&gt;
      &amp;lt;%= review_text %&amp;gt;&lt;br /&gt;
    &amp;lt;/a&amp;gt;&lt;br /&gt;
    &amp;lt;/th&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====F.In app/views/grades/view_team.html.erb:====&lt;br /&gt;
&lt;br /&gt;
'''F.1: '''Added function teammateSelectOnChange: This function toggles the visibility for the teammate heatgrids when the instructor changes the dropdown&lt;br /&gt;
    &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  function teammateSelectOnChange(selectNode) {&lt;br /&gt;
      const revieweeIdToShow= selectNode.value;&lt;br /&gt;
      const tableSelector = &amp;quot;.teammate_table&amp;quot;;&lt;br /&gt;
      if(revieweeIdToShow == &amp;quot;all&amp;quot;) {&lt;br /&gt;
        document.querySelectorAll(tableSelector).forEach((tableNode) =&amp;gt; {&lt;br /&gt;
          tableNode.classList.remove(&amp;quot;hidden&amp;quot;);&lt;br /&gt;
        });&lt;br /&gt;
        return;&lt;br /&gt;
      }&lt;br /&gt;
&lt;br /&gt;
    document.querySelectorAll(tableSelector).forEach((tableNode) =&amp;gt; {&lt;br /&gt;
      const tableRevieweeId = tableNode.getAttribute('data-reviewee_id');&lt;br /&gt;
      if(tableRevieweeId == revieweeIdToShow) {&lt;br /&gt;
        tableNode.classList.remove(&amp;quot;hidden&amp;quot;);&lt;br /&gt;
      } else {&lt;br /&gt;
        tableNode.classList.add(&amp;quot;hidden&amp;quot;);&lt;br /&gt;
      }&lt;br /&gt;
      });&lt;br /&gt;
    }&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''F.2: '''&lt;br /&gt;
&lt;br /&gt;
Old code: Existing code doesn't render TeammateReviewQuestionnaire&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    &amp;lt;% @vmlist.each do |vm| %&amp;gt;&lt;br /&gt;
        &amp;lt;% if (vm.questionnaire_display_type == &amp;quot;Metareview&amp;quot; or vm.questionnaire_display_type == &amp;quot;Author Feedback&amp;quot; or vm.questionnaire_display_type == &amp;quot;Teammate Review&amp;quot;) and @current_role_name.eql?'Student' %&amp;gt;&lt;br /&gt;
        &amp;lt;% else %&amp;gt;&lt;br /&gt;
        &amp;lt;% if vm.list_of_reviewers.length &amp;gt; 0 %&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
New code: Use a boolean to render a dropdown just before the first TeammateReviewQuestionnaire, and unset that boolean so we only render 1 table. Add conditions which check for the truthiness of ```@assignment.show_teammate_reviews``` and if the current user is a student to decide whether to render the table or not. Finally, add a CSS class and a `data-reviewee_id` to keep track of the heatgrids when toggling visibility&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;%# This boolean is used to render a dropdown just before the first teammate review heat grid %&amp;gt;&lt;br /&gt;
&amp;lt;% first_teammate_review_appeared = false %&amp;gt;&lt;br /&gt;
&amp;lt;% @vmlist.each do |vm| %&amp;gt;&lt;br /&gt;
    &amp;lt;% if not @current_role_name.eql?'Student' and not first_teammate_review_appeared and vm.questionnaire_type == &amp;quot;TeammateReviewQuestionnaire&amp;quot; %&amp;gt;&lt;br /&gt;
      &amp;lt;div&amp;gt;&lt;br /&gt;
        &amp;lt;select onchange=&amp;quot;teammateSelectOnChange(this)&amp;quot;&amp;gt;&lt;br /&gt;
          &amp;lt;option value=&amp;quot;all&amp;quot;&amp;gt;All&amp;lt;/option&amp;gt;&lt;br /&gt;
          &amp;lt;% @vmlist.select { |tm_vm| tm_vm.questionnaire_type == &amp;quot;TeammateReviewQuestionnaire&amp;quot; }.each do |tm_vm| %&amp;gt;&lt;br /&gt;
            &amp;lt;option value=&amp;quot;&amp;lt;%= tm_vm.reviewee_id %&amp;gt;&amp;quot;&amp;gt;&lt;br /&gt;
              &amp;lt;%= tm_vm.reviewee_name(session[:ip]) %&amp;gt;&lt;br /&gt;
            &amp;lt;/option&amp;gt;&lt;br /&gt;
          &amp;lt;% end %&amp;gt;&lt;br /&gt;
        &amp;lt;/select&amp;gt;&lt;br /&gt;
      &amp;lt;/div&amp;gt;&lt;br /&gt;
      &amp;lt;% first_teammate_review_appeared = true %&amp;gt;&lt;br /&gt;
    &amp;lt;% end %&amp;gt;&lt;br /&gt;
    &amp;lt;% if (vm.questionnaire_display_type == &amp;quot;Metareview&amp;quot; or vm.questionnaire_display_type == &amp;quot;Author Feedback&amp;quot;) and @current_role_name.eql?'Student' %&amp;gt;&lt;br /&gt;
    &amp;lt;% elsif (vm.questionnaire_type == &amp;quot;TeammateReviewQuestionnaire&amp;quot; and @current_role_name.eql?'Student' and !@assignment.show_teammate_reviews)%&amp;gt;&lt;br /&gt;
    &amp;lt;% elsif (vm.questionnaire_type == &amp;quot;TeammateReviewQuestionnaire&amp;quot; and @current_role_name.eql?'Student' and @assignment.show_teammate_reviews and current_user.id != vm.reviewee_id )%&amp;gt;&lt;br /&gt;
    &amp;lt;% else %&amp;gt;&lt;br /&gt;
        &amp;lt;% if vm.questionnaire_type == &amp;quot;TeammateReviewQuestionnaire&amp;quot; %&amp;gt;&lt;br /&gt;
          &amp;lt;div class=&amp;quot;teammate_table&amp;quot; data-reviewee_id=&amp;quot;&amp;lt;%= vm.reviewee_id %&amp;gt;&amp;quot;&amp;gt;&lt;br /&gt;
        &amp;lt;% else %&amp;gt;&lt;br /&gt;
          &amp;lt;div&amp;gt;&lt;br /&gt;
        &amp;lt;% end %&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''F.3  '''&lt;br /&gt;
&lt;br /&gt;
Old code: Existing code doesn't print the teammate who is being reviewed.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;!-- display the list of questions for this questionnaire --&amp;gt;&lt;br /&gt;
          &amp;lt;h4 style=&amp;quot;display:inline-block;&amp;quot;&amp;gt;&amp;lt;%= vm.questionnaire_display_type %&amp;gt;&lt;br /&gt;
            &amp;lt;% if vm.questionnaire_type == &amp;quot;ReviewQuestionnaire&amp;quot; %&amp;gt;&lt;br /&gt;
                (Round: &amp;lt;%= vm.round.to_s  %&amp;gt; of &amp;lt;%= vm.rounds.to_s  %&amp;gt;)&lt;br /&gt;
            &amp;lt;%end %&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
New code: If TeammteReviewQuestionnaire is used, then use the `:reviewee_name` method for VmQuestionResponse model to print the name of the student who is being reviewed.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;!-- display the list of questions for this questionnaire --&amp;gt;&lt;br /&gt;
          &amp;lt;h4 style=&amp;quot;display:inline-block;&amp;quot;&amp;gt;&amp;lt;%= vm.questionnaire_display_type %&amp;gt;&lt;br /&gt;
            &amp;lt;% if vm.questionnaire_type == &amp;quot;ReviewQuestionnaire&amp;quot; %&amp;gt;&lt;br /&gt;
                (Round: &amp;lt;%= vm.round.to_s  %&amp;gt; of &amp;lt;%= vm.rounds.to_s  %&amp;gt;)&lt;br /&gt;
            &amp;lt;% elsif vm.questionnaire_type == &amp;quot;TeammateReviewQuestionnaire&amp;quot; %&amp;gt;&lt;br /&gt;
                (For: &amp;lt;%= vm.reviewee_name(session[:ip]) %&amp;gt;)&lt;br /&gt;
            &amp;lt;%end %&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''F.4 '''&lt;br /&gt;
&lt;br /&gt;
Old code: Existing code doesn't inform the partial about the type of review being done&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;% vm.list_of_reviews.each do |review| %&amp;gt;&lt;br /&gt;
              &amp;lt;!-- instructors (or higher level users) see reviewer name, students see anonymized string --&amp;gt;&lt;br /&gt;
              &amp;lt;% if (['Student'].include? @current_role_name) &amp;amp;&amp;amp; @assignment.is_anonymous%&amp;gt;&lt;br /&gt;
                &amp;lt;%= render :partial =&amp;gt; 'add_icon_to_name', :locals =&amp;gt; {review: review, i: i} %&amp;gt;&lt;br /&gt;
              &amp;lt;% else %&amp;gt;&lt;br /&gt;
                  &amp;lt;% user_name = User.find(Participant.find(ResponseMap.find(Response.find(review.id).map_id).reviewer_id).user_id).fullname(session[:ip]).to_s %&amp;gt;&lt;br /&gt;
                &amp;lt;%= render :partial =&amp;gt; 'add_icon_to_name', :locals =&amp;gt; {review: review, i: i} %&amp;gt;&lt;br /&gt;
              &amp;lt;% end %&amp;gt;&lt;br /&gt;
              &amp;lt;% i += 1 %&amp;gt;&lt;br /&gt;
          &amp;lt;% end %&amp;gt;&lt;br /&gt;
New code: Passes the type of review being done to the partial, so it can decide on how to render the review title. Note: This code seems to use repetition, but since the conditional used here are accessing `Anonymous` assignments and checking for user roles, we have not modified this code, as it is not directly related to our scope.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;% vm.list_of_reviews.each do |review| %&amp;gt;&lt;br /&gt;
              &amp;lt;!-- instructors (or higher level users) see reviewer name, students see anonymized string --&amp;gt;&lt;br /&gt;
              &amp;lt;% if (['Student'].include? @current_role_name) &amp;amp;&amp;amp; @assignment.is_anonymous%&amp;gt;&lt;br /&gt;
                &amp;lt;%= render :partial =&amp;gt; 'add_icon_to_name', :locals =&amp;gt; {review: review, i: i, questionnaire_type: vm.questionnaire_type } %&amp;gt;&lt;br /&gt;
              &amp;lt;% else %&amp;gt;&lt;br /&gt;
                &amp;lt;% user_name = User.find(Participant.find(ResponseMap.find(Response.find(review.id).map_id).reviewer_id).user_id).fullname(session[:ip]).to_s %&amp;gt;&lt;br /&gt;
                &amp;lt;%= render :partial =&amp;gt; 'add_icon_to_name', :locals =&amp;gt; {review: review, i: i, questionnaire_type: vm.questionnaire_type } %&amp;gt;&lt;br /&gt;
              &amp;lt;% end %&amp;gt;&lt;br /&gt;
              &amp;lt;% i += 1 %&amp;gt;&lt;br /&gt;
          &amp;lt;% end %&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Old code: Contains a `metrics-` column&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
          &amp;lt;th class=&amp;quot;sorter-true&amp;quot; align=&amp;quot;right&amp;quot; &amp;gt;&lt;br /&gt;
            Avg&amp;lt;span&amp;gt;&amp;lt;/span&amp;gt;&lt;br /&gt;
          &amp;lt;/th&amp;gt;&lt;br /&gt;
          &amp;lt;th class=&amp;quot;sorter-false&amp;quot;&amp;gt;&lt;br /&gt;
            &amp;lt;span  data-toggle=&amp;quot;tooltip&amp;quot; data-placement=&amp;quot;right&amp;quot; title=&amp;quot;A count of comments, for the respective question, which have word count &amp;gt; 10. The purpose of this metric is to represent how many comments for the question are of a substantial length to provide quality feedback.&amp;quot;&amp;gt;metric-1&amp;lt;/span&amp;gt;&lt;br /&gt;
          &amp;lt;/th&amp;gt;&lt;br /&gt;
        &amp;lt;/tr&amp;gt;&lt;br /&gt;
        &amp;lt;/thead&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
New code: As per discussion with mentor, this column has been removed in our PR.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
          &amp;lt;th class=&amp;quot;sorter-true&amp;quot; align=&amp;quot;right&amp;quot; &amp;gt;&lt;br /&gt;
            Avg&amp;lt;span&amp;gt;&amp;lt;/span&amp;gt;&lt;br /&gt;
          &amp;lt;/th&amp;gt;&lt;br /&gt;
        &amp;lt;/tr&amp;gt;&lt;br /&gt;
        &amp;lt;/thead&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''F.5 '''&lt;br /&gt;
&lt;br /&gt;
Old code: It creates the ID inline in multiple places, so if we decide to change the ID generation logic, we need to modify it in multiple places. (which happened when we started rendering multiple tables for each teammate).&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;% vm.list_of_rows.each do |row| %&amp;gt;&lt;br /&gt;
            &amp;lt;!-- notice the data-target. because we're toggling via looped code, we need to dynamically generate the identifier. --&amp;gt;&lt;br /&gt;
            &amp;lt;tr data-toggle=&amp;quot;collapse&amp;quot; class=&amp;quot;accordion-toggle&amp;quot; data-target=&amp;quot;#hid&amp;lt;%= row.question_id.to_s + vm.round.to_s %&amp;gt;&amp;quot;&amp;gt;&lt;br /&gt;
              &amp;lt;td class = 'cf' data-toggle=&amp;quot;tooltip&amp;quot; title=&amp;quot;&amp;lt;%= row.question_text %&amp;gt;&amp;quot;&amp;gt; &amp;lt;div style='float: left'&amp;gt;&amp;lt;%= j.to_s %&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;div style='float: right'&amp;gt; &amp;amp;#&amp;lt;%= type_and_max(row) %&amp;gt;;&amp;lt;/div&amp;gt;  &amp;lt;/td&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
New code: Generate the unique HTML ID once, in a readable manner once. And conditionally make it more unique, if it is a TeammateReviewQuestionnaire, since jQuery code requires these IDs to be unique amongst different tables. If we don't make it more unique, then clicking on one teammate review table will toggle the table visibility for the first table. To prevent this &amp;quot;clashing&amp;quot;, we need to make these IDs more unique for a TeammateReviewQuestionnaire.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;% vm.list_of_rows.each do |row| %&amp;gt;&lt;br /&gt;
            &amp;lt;% target_id = &amp;quot;hid__#{row.question_id}__#{vm.round}&amp;quot; %&amp;gt;&lt;br /&gt;
            &amp;lt;% if vm.questionnaire_type == &amp;quot;TeammateReviewQuestionnaire&amp;quot; %&amp;gt;&lt;br /&gt;
              &amp;lt;%# Since we render different heatgrids with the same questions for each&lt;br /&gt;
              teammember, we need to distinguish the ID, based on the user for whom,&lt;br /&gt;
              the reviews have been created. %&amp;gt;&lt;br /&gt;
              &amp;lt;% target_id += &amp;quot;__#{vm.reviewee_id}&amp;quot; %&amp;gt;&lt;br /&gt;
            &amp;lt;% end%&amp;gt;&lt;br /&gt;
&lt;br /&gt;
            &amp;lt;!-- notice the data-target. because we're toggling via looped code, we need to dynamically generate the identifier. --&amp;gt;&lt;br /&gt;
            &amp;lt;tr data-toggle=&amp;quot;collapse&amp;quot; class=&amp;quot;accordion-toggle&amp;quot; data-target=&amp;quot;&amp;lt;%= &amp;quot;#&amp;quot; + target_id %&amp;gt;&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Old code: Written on a single line crossing 80 characters on a single line&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
              &amp;lt;% row.score_row.each do |score| %&amp;gt;&lt;br /&gt;
                  &amp;lt;% score_comment = score.comment.nil? ? '' : score.comment %&amp;gt; &amp;lt;!-- changing nil to null string to avoid Null Pointer Exception --&amp;gt;&lt;br /&gt;
                  &amp;lt;td class=&amp;quot;&amp;lt;%= score.color_code %&amp;gt;&amp;quot; align=&amp;quot;center&amp;quot; data-toggle=&amp;quot;tooltip&amp;quot; title=&amp;quot;&amp;lt;%= strip_tags(score.comment).html_safe%&amp;gt;&amp;quot;&amp;gt;&lt;br /&gt;
                    &amp;lt;span class=&amp;quot;&amp;lt;%=  underlined?(score) %&amp;gt;&amp;quot;&amp;gt;&amp;lt;%= score.score_value.to_s %&amp;gt;&amp;lt;/span&amp;gt;&lt;br /&gt;
                  &amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;% end %&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
New code: Make code more readable by indenting it and splitting it over multiple lines&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
              &amp;lt;!-- actual cells with scores and colored background. --&amp;gt;&lt;br /&gt;
              &amp;lt;% row.score_row.each do |score| %&amp;gt;&lt;br /&gt;
                  &amp;lt;% score_comment = score.comment.nil? ? '' : score.comment %&amp;gt;&lt;br /&gt;
                  &amp;lt;!-- changing nil to null string to avoid Null Pointer Exception --&amp;gt;&lt;br /&gt;
                  &amp;lt;td class=&amp;quot;&amp;lt;%= score.color_code %&amp;gt;&amp;quot; align=&amp;quot;center&amp;quot; data-toggle=&amp;quot;tooltip&amp;quot; title=&amp;quot;&amp;lt;%= strip_tags(score.comment).html_safe%&amp;gt;&amp;quot;&amp;gt;&lt;br /&gt;
                    &amp;lt;span class=&amp;quot;&amp;lt;%=  underlined?(score) %&amp;gt;&amp;quot;&amp;gt;&lt;br /&gt;
                      &amp;lt;%= score.score_value.to_s %&amp;gt;&lt;br /&gt;
                    &amp;lt;/span&amp;gt;&lt;br /&gt;
                  &amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;% end %&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''F.6 '''Removed the following code as it corresponds to the deleted column&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 &amp;lt;td  class = 'cf' align=&amp;quot;center&amp;quot;&amp;gt;&lt;br /&gt;
                &amp;lt;%= row.countofcomments.to_s %&amp;gt;&lt;br /&gt;
              &amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''F.7 '''&lt;br /&gt;
&lt;br /&gt;
Old code&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;!--loop that creates the collapsed-by-default row, which lists all comments. --&amp;gt;&lt;br /&gt;
            &amp;lt;tr class=&amp;quot;tablesorter-childRow&amp;quot;&amp;gt;&lt;br /&gt;
              &amp;lt;td colspan=&amp;quot;&amp;lt;%= (i+1).to_s %&amp;gt;&amp;quot; class=&amp;quot;hiddenRow&amp;quot; &amp;gt;&amp;lt;div id=&amp;quot;hid&amp;lt;%= row.question_id.to_s + vm.round.to_s %&amp;gt;&amp;quot; class=&amp;quot;accordion-body collapse&amp;quot; style=&amp;quot;margin-left:10px;&amp;quot;&amp;gt;&lt;br /&gt;
                &amp;lt;div style=&amp;quot;padding-top: 10px; padding-bottom: 10px;&amp;quot;&amp;gt;&amp;lt;%=  sanitize row.question_text %&amp;gt;&amp;lt;/div&amp;gt;&lt;br /&gt;
                &amp;lt;div&amp;gt;&lt;br /&gt;
                  &amp;lt;table class=&amp;quot;table tbl_questlist&amp;quot;&amp;gt;&lt;br /&gt;
@@ -181,7 +233,17 @@&lt;br /&gt;
                    &amp;lt;/thead&amp;gt;&lt;br /&gt;
                    &amp;lt;% for index in 0 .. row.score_row.length - 1 %&amp;gt;&lt;br /&gt;
                        &amp;lt;tr&amp;gt;&lt;br /&gt;
                          &amp;lt;td&amp;gt;Review &amp;lt;%=index + 1%&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
New code&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;!--loop that creates the collapsed-by-default row, which lists all comments. --&amp;gt;&lt;br /&gt;
            &amp;lt;tr class=&amp;quot;tablesorter-childRow&amp;quot;&amp;gt;&lt;br /&gt;
              &amp;lt;td colspan=&amp;quot;&amp;lt;%= (i+1).to_s %&amp;gt;&amp;quot; class=&amp;quot;hiddenRow&amp;quot; &amp;gt;&amp;lt;div id=&amp;quot;&amp;lt;%= target_id %&amp;gt;&amp;quot; class=&amp;quot;accordion-body collapse&amp;quot; style=&amp;quot;margin-left:10px;&amp;quot;&amp;gt;&lt;br /&gt;
                &amp;lt;div style=&amp;quot;padding-top: 10px; padding-bottom: 10px;&amp;quot;&amp;gt;&amp;lt;%=  sanitize row.question_text %&amp;gt;&amp;lt;/div&amp;gt;&lt;br /&gt;
                &amp;lt;div&amp;gt;&lt;br /&gt;
                  &amp;lt;table class=&amp;quot;table tbl_questlist&amp;quot;&amp;gt;&lt;br /&gt;
@@ -181,7 +233,17 @@&lt;br /&gt;
                    &amp;lt;/thead&amp;gt;&lt;br /&gt;
                    &amp;lt;% for index in 0 .. row.score_row.length - 1 %&amp;gt;&lt;br /&gt;
                        &amp;lt;tr&amp;gt;&lt;br /&gt;
                          &amp;lt;% if @current_role_name.eql?'Student' or vm.questionnaire_type != &amp;quot;TeammateReviewQuestionnaire&amp;quot; %&amp;gt;&lt;br /&gt;
                            &amp;lt;%# Use Review {{index}} format for student view, and&lt;br /&gt;
                            when questionnaire_type is not teammatereview %&amp;gt;&lt;br /&gt;
                            &amp;lt;td&amp;gt;Review &amp;lt;%=index + 1%&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
                          &amp;lt;% else %&amp;gt;&lt;br /&gt;
                            &amp;lt;td&amp;gt;&lt;br /&gt;
                              &amp;lt;% reviewer_id = row.score_row[index].reviewer_id %&amp;gt;&lt;br /&gt;
                              &amp;lt;% fullname = Participant.find_by(id: reviewer_id).fullname(session[:ip]) %&amp;gt;&lt;br /&gt;
                              Review by &amp;lt;%= fullname %&amp;gt;&lt;br /&gt;
                            &amp;lt;/td&amp;gt;&lt;br /&gt;
                          &amp;lt;% end%&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====G. In spec/controllers/grades_controller_spec.rb:====&lt;br /&gt;
&lt;br /&gt;
'''G.1 '''&lt;br /&gt;
&lt;br /&gt;
Old code&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
before(:each) do&lt;br /&gt;
  allow(AssignmentParticipant).to receive(:find).with('1').and_return(participant)&lt;br /&gt;
  allow(participant).to receive(:team).and_return(team)&lt;br /&gt;
  stub_current_user(instructor, instructor.role.name, instructor.role)&lt;br /&gt;
  allow(Assignment).to receive(:find).with('1').and_return(assignment)&lt;br /&gt;
@@ -91,29 +90,106 @@&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
New code&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
before(:each) do&lt;br /&gt;
  allow(participant).to receive(:team).and_return(team)&lt;br /&gt;
  stub_current_user(instructor, instructor.role.name, instructor.role)&lt;br /&gt;
  allow(Assignment).to receive(:find).with('1').and_return(assignment)&lt;br /&gt;
@@ -91,29 +90,106 @@&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''G.2 '''Remove xdescribe '#view_team' and change describe '#view_team' as follows.&lt;br /&gt;
&lt;br /&gt;
Old code&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
describe '#view_team' do&lt;br /&gt;
render_views&lt;br /&gt;
context 'when view_team page is viewed by a student who is also a TA for another course' do&lt;br /&gt;
  it 'renders grades#view_team page' do&lt;br /&gt;
    allow(participant).to receive(:team).and_return(team)&lt;br /&gt;
    allow(AssignmentQuestionnaire).to receive(:find_by).with(assignment_id: 1, questionnaire_id: 1).and_return(assignment_questionnaire)&lt;br /&gt;
    allow(AssignmentQuestionnaire).to receive(:where).with(any_args).and_return([assignment_questionnaire])&lt;br /&gt;
    allow(assignment).to receive(:late_policy_id).and_return(false)&lt;br /&gt;
    allow(assignment).to receive(:calculate_penalty).and_return(false)&lt;br /&gt;
    allow(assignment).to receive(:compute_total_score).with(any_args).and_return(100)&lt;br /&gt;
    allow(review_questionnaire).to receive(:get_assessments_round_for).with(participant, 1).and_return([review_response])&lt;br /&gt;
    allow(Answer).to receive(:compute_scores).with([review_response], [question]).and_return(max: 95, min: 88, avg: 90)&lt;br /&gt;
    params = {id: 1}&lt;br /&gt;
    allow(TaMapping).to receive(:exists?).with(ta_id: 1, course_id: 1).and_return(true)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
New code&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
describe '#view_team' do&lt;br /&gt;
render_views&lt;br /&gt;
&lt;br /&gt;
# All stubs and factories are instantiated within this scope so as to not &lt;br /&gt;
# clash with other broken test.&lt;br /&gt;
# The names of the factories created for testing view_team&lt;br /&gt;
# have `_vt` suffix ```where necessary``` to differentiate them from &lt;br /&gt;
# the above declared factories&lt;br /&gt;
&lt;br /&gt;
let(:student1_vt) { create(:student, name: &amp;quot;barry&amp;quot;, id: 12) }&lt;br /&gt;
let(:student2_vt) { create(:student, name: &amp;quot;iris&amp;quot;, id: 13) }&lt;br /&gt;
&lt;br /&gt;
let(:tm_questionnaire) {&lt;br /&gt;
  build(&lt;br /&gt;
    :teammate_review_questionnaire,&lt;br /&gt;
    id: 12,&lt;br /&gt;
    questions: [question],&lt;br /&gt;
    max_question_score: 5&lt;br /&gt;
  )&lt;br /&gt;
}&lt;br /&gt;
let(:assignment_vt) {&lt;br /&gt;
  create(:assignment, id: 6, max_team_size: 2,&lt;br /&gt;
  questionnaires: [tm_questionnaire])&lt;br /&gt;
}&lt;br /&gt;
let(:assignment_questionnaire_vt) {&lt;br /&gt;
  create(:tm_assignment_questionnaire, id: 12, used_in_round: nil,&lt;br /&gt;
  assignment: assignment_vt, questionnaire: tm_questionnaire) }&lt;br /&gt;
let(:team_vt) { create(:assignment_team, id: 12,&lt;br /&gt;
assignment: assignment_vt) }&lt;br /&gt;
let(:participant_vt) { create(:participant, id: 12,&lt;br /&gt;
  assignment: assignment_vt, user_id: student1_vt.id) }&lt;br /&gt;
let(:participant2_vt) { create(:participant, id: 13,&lt;br /&gt;
  assignment: assignment_vt, user_id: student2_vt.id) }&lt;br /&gt;
&lt;br /&gt;
before(:each) do&lt;br /&gt;
  # Need to stub this method so the factory instance with&lt;br /&gt;
  # the stubbed :team method is returned by :find&lt;br /&gt;
  # instead of a separate instance with the same data&lt;br /&gt;
  allow(AssignmentParticipant)&lt;br /&gt;
    .to receive(:find)&lt;br /&gt;
    .with(participant_vt.id.to_s)&lt;br /&gt;
    .and_return(participant_vt)&lt;br /&gt;
  allow(participant_vt).to receive(:team).and_return(team_vt)&lt;br /&gt;
  allow(team_vt).to receive(:participants).and_return([participant_vt, participant2_vt])&lt;br /&gt;
  allow(AssignmentQuestionnaire)&lt;br /&gt;
    .to receive(:find_by)&lt;br /&gt;
    .with(assignment_id: assignment_vt.id, questionnaire_id: tm_questionnaire.id)&lt;br /&gt;
    .and_return(assignment_questionnaire_vt)&lt;br /&gt;
  allow(AssignmentQuestionnaire)&lt;br /&gt;
    .to receive(:find_by)&lt;br /&gt;
    .with(assignment_id: assignment.id, questionnaire_id: review_questionnaire.id)&lt;br /&gt;
    .and_return(assignment_questionnaire_vt)&lt;br /&gt;
  allow(AssignmentQuestionnaire)&lt;br /&gt;
    .to receive(:where)&lt;br /&gt;
    .with(any_args)&lt;br /&gt;
    .and_return([assignment_questionnaire_vt])&lt;br /&gt;
  allow(assignment_vt)&lt;br /&gt;
    .to receive(:late_policy_id)&lt;br /&gt;
    .and_return(false)&lt;br /&gt;
  allow(assignment_vt)&lt;br /&gt;
    .to receive(:calculate_penalty)&lt;br /&gt;
    .and_return(false)&lt;br /&gt;
  allow(assignment_vt)&lt;br /&gt;
    .to receive(:compute_total_score)&lt;br /&gt;
    .with(any_args)&lt;br /&gt;
    .and_return(100)&lt;br /&gt;
  allow(review_questionnaire).to receive(:get_assessments_round_for).with(participant, 1).and_return([review_response])&lt;br /&gt;
  allow(Answer).to receive(:compute_scores).with([review_response], [question]).and_return(max: 95, min: 88, avg: 90)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
 it 'renders grades#view_team page' do&lt;br /&gt;
  params = {id: participant_vt.id}&lt;br /&gt;
  get :view_team, params&lt;br /&gt;
  expect(response).to render_template(:view_team)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
context 'when view_team page is opened by student' do&lt;br /&gt;
  it 'dropdown is not rendered' do&lt;br /&gt;
    session = { user: student1_vt }&lt;br /&gt;
    params = {id: participant_vt.id}&lt;br /&gt;
    stub_current_user(student1_vt, student1_vt.role.name, student1_vt.role)&lt;br /&gt;
    get :view_team, params&lt;br /&gt;
    expect(response.body).to_not have_selector('select')&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
context 'when view_team page is opened by instructor' do&lt;br /&gt;
  it 'dropdown is rendered' do&lt;br /&gt;
    session = { user: instructor }&lt;br /&gt;
    params = {id: participant_vt.id}&lt;br /&gt;
    get :view_team, params&lt;br /&gt;
    expect(response.body).to have_selector('select')&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
context 'when view_team page is viewed by a student who is also a TA for another course' do&lt;br /&gt;
  it 'renders grades#view_team page' do&lt;br /&gt;
    params = { id: participant_vt.id }&lt;br /&gt;
    allow(TaMapping).to receive(:exists?).with(ta_id: participant_vt.user_id, course_id: 1).and_return(true)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
====H. In spec/factories/factories.rb:====&lt;br /&gt;
&lt;br /&gt;
'''H.1 '''Add the following factory:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
factory :teammate_review_questionnaire, class: TeammateReviewQuestionnaire do&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''H.2 '''Add another factory&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
factory :tm_assignment_questionnaire, class: AssignmentQuestionnaire do&lt;br /&gt;
  user_id 1&lt;br /&gt;
  questionnaire { association(:teammate_review_questionnaire) }&lt;br /&gt;
  questionnaire_weight 100&lt;br /&gt;
  used_in_round nil&lt;br /&gt;
  topic_id nil&lt;br /&gt;
  dropdown 1&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Summary of file changes ===&lt;br /&gt;
&lt;br /&gt;
The following files are modified:&lt;br /&gt;
&lt;br /&gt;
1. app/controllers/grades_controller.rb - Controller file which changed how the view model is populated&lt;br /&gt;
&lt;br /&gt;
2. app/views/grades/view_team.html.erb - View file, which  conditionally rendered the teammate name, for a teammate review heatgrid&lt;br /&gt;
&lt;br /&gt;
3. spec/controllers/grades_controller_spec.rb - For tests verifying the proposed changes&lt;br /&gt;
&lt;br /&gt;
4. app/models/vm_question_response.rb - To modify the view-model so it can tell us the name of the person being reviewed for the current heatgrid&lt;br /&gt;
&lt;br /&gt;
5. app/models/vm_question_response_score_cell.rb - &lt;br /&gt;
&lt;br /&gt;
6. app/assets/stylesheets/grades.scss - &lt;br /&gt;
&lt;br /&gt;
7. app/views/grades/_add_icon_to_name.html.erb - &lt;br /&gt;
&lt;br /&gt;
8. spec/factories/factories.rb -&lt;br /&gt;
&lt;br /&gt;
== Design Patterns ==&lt;br /&gt;
&lt;br /&gt;
Existing code does not use any design patterns, apart from if-else. It uses if-else conditional statements to check what type of questionnaire is present in the viewmodel `VmQuestionResponse`, and based on that, it renders the appropriate content.&lt;br /&gt;
&lt;br /&gt;
We decided to continue with this approach since to change the present coding style, there were required many changes (refactoring) to many files which were out of the scope of the present project. To complete the project in the assigned time, we followed the if-else approach.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Testing ==&lt;br /&gt;
'''OLD STATUS'''&lt;br /&gt;
&lt;br /&gt;
1. Earlier, the tests only covered if the view_team is page is rendered when it is asked for. This can be seen on the line 94 and 103 in [https://github.com/expertiza/expertiza/blob/beta/spec/controllers/grades_controller_spec.rb this] file.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''NEW STATUS'''&lt;br /&gt;
&lt;br /&gt;
1. The view_team page is rendered correctly for a given student or an instructor.&lt;br /&gt;
&lt;br /&gt;
2. When students access then the view_team page, the dropdown to select a student's teammate reviews is not rendered on the page.&lt;br /&gt;
&lt;br /&gt;
3. When instructor access then the view_team page, the dropdown to select a student's teammate reviews is rendered on the page.&lt;br /&gt;
&lt;br /&gt;
4. When a student who is also a TA for another course access the view_team page, that student should be able to a student's view to the page.&lt;br /&gt;
&lt;br /&gt;
5. If show_teammate_reviews boolean is set to False, then the student should not be able to see the teammate reviews given to him/her. If it is set to True, then the student should be able to see the reviews.&lt;br /&gt;
&lt;br /&gt;
6. An instructor should be able to see the teammate reviews for all students regardless of whether the show_teammate_reviews boolean is set to True or False.&lt;br /&gt;
&lt;br /&gt;
7. The reviewer id is tracked correctly to show the correct reviewer name in the teammate reviews table. This can be seen on line 27 in [https://github.com/expertiza/expertiza/blob/66239d9a8a53697ea170a92208593b36d06dfd24/spec/models/vm_question_response_score_cell_spec.rb this] file &lt;br /&gt;
&lt;br /&gt;
8. An instructor can select which student's scores he/she wants to see. If no student's name is selected then the professor can see the scores of all the students.&lt;br /&gt;
&lt;br /&gt;
==References==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;https://expertiza.ncsu.edu/&amp;lt;/p&amp;gt;&lt;/div&gt;</summary>
		<author><name>Vdeshmu</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2021_-_E2165._Fix_teammate-review_view&amp;diff=141742</id>
		<title>CSC/ECE 517 Fall 2021 - E2165. Fix teammate-review view</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2021_-_E2165._Fix_teammate-review_view&amp;diff=141742"/>
		<updated>2021-11-28T18:21:20Z</updated>

		<summary type="html">&lt;p&gt;Vdeshmu: /* E. In app/views/grades/_add_icon_to_name.html.erb: */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Team Introduction ==&lt;br /&gt;
&lt;br /&gt;
Dr. Edward Gehringer (instructor), Parimal Mehta (mentor)&lt;br /&gt;
&lt;br /&gt;
1. Anjali Garg (unity ID : agarg25)&lt;br /&gt;
&lt;br /&gt;
2. Arvasu Chikara (unity ID: achikar2)&lt;br /&gt;
&lt;br /&gt;
3. Lalit Bangad (unity ID: llbangad)&lt;br /&gt;
&lt;br /&gt;
4. Vinay Deshmukh (unity ID: vdeshmu)&lt;br /&gt;
&lt;br /&gt;
== Problems to be addressed ==&lt;br /&gt;
&lt;br /&gt;
After a project is submitted and reviewed, both the team members (students) and instructors should be able to view the teammate reviews. Students should be able to view the reviews by going to a particular assignment's -&amp;gt; your scores, at the bottom of the page. An instructor can view the teammate reviews by going to assignments -&amp;gt; assignment -&amp;gt; particular team's submission -&amp;gt; view submission -&amp;gt; assign grades -&amp;gt; view scores. &lt;br /&gt;
&lt;br /&gt;
In the case of the instructor, a single heat grid is shown whereas in the case of a team member, we cant view the scores. In the heat grid, it is not clear if the scores visible are for the reviews that the student has *written* for their teammates or the scores that the student has *received* from their teammates. Additionally, for instructors can choose from a list of the students on the team, but they have no way to tell whether the heat grid shows the reviews done *by* that student or done *for* that student.&lt;br /&gt;
&lt;br /&gt;
== Methodology Overview ==&lt;br /&gt;
&lt;br /&gt;
We have divided our work in the following tasks to address the above problems:&lt;br /&gt;
&lt;br /&gt;
1. Distinguish reviews done for a student by rendering separates heatgrids for each student&lt;br /&gt;
&lt;br /&gt;
2. For instructors, the table will have sections based on the students&lt;br /&gt;
&lt;br /&gt;
3. Include a checkbox on the edit assignment page that enables/disables visibility of heat grid to students&lt;br /&gt;
&lt;br /&gt;
4. Fix the average column for a table (which breaks for some reviews)&lt;br /&gt;
&lt;br /&gt;
5. Show a composite score derived from all reviews.  Make this code generalized, so other kinds of heat grid views could use it.&lt;br /&gt;
&lt;br /&gt;
6. Changes should work even in an anonymized view&lt;br /&gt;
&lt;br /&gt;
== Motivations ==&lt;br /&gt;
&lt;br /&gt;
1. Enable users to clearly tell which reviews are done by them, and which reviews are done for them.&lt;br /&gt;
&lt;br /&gt;
2. Code should be generic so it can be used for different types of heat grids as well.&lt;br /&gt;
&lt;br /&gt;
== Control Flow to access the concerned screens ==&lt;br /&gt;
'''1. For instructor (Log in as an instructor):-'''&lt;br /&gt;
&lt;br /&gt;
Screen after logging in by the instructor&lt;br /&gt;
[[File:ss1.png |border|1000px|center]]&lt;br /&gt;
Got to assignments on the Manage menu &lt;br /&gt;
[[File:ss2.png |border|1000px|center]]&lt;br /&gt;
Go to assignments&lt;br /&gt;
[[File:ss3.png |border|1000px|center]]&lt;br /&gt;
Go to submissions for any assignment&lt;br /&gt;
[[File:ss4a.png |border|1000px|center]]&lt;br /&gt;
Go to Assign Grade&lt;br /&gt;
[[File:ss5a.png |border|1000px|center]]&lt;br /&gt;
You will land on the page where the changes are made and can be reviewed&lt;br /&gt;
[[File:ss7a.png |border|1000px|center]]&lt;br /&gt;
&lt;br /&gt;
'''2. Student:- (Logged in as an instructor)'''&lt;br /&gt;
&lt;br /&gt;
After landing on the assignments page, select any student from an assignment as shown below&lt;br /&gt;
[[File:ss6a.png |border|1000px|center]]&lt;br /&gt;
Go to/Select any assignment&lt;br /&gt;
[[File:ss9a.png |border|1000px|center]]&lt;br /&gt;
Go to your scores&lt;br /&gt;
[[File:ss10a.png |border|1000px|center]]&lt;br /&gt;
You will land on the page where the changes are made and can be reviewed&lt;br /&gt;
[[File:ss11a.png |border|1000px|center]]&lt;br /&gt;
&lt;br /&gt;
== Old Status of the application ==&lt;br /&gt;
&lt;br /&gt;
'''1. Instructor's view of teammate review''': This is the current screen given to the instructor. Here we see that the instructor can not determine who has given which review to which student in a team.&lt;br /&gt;
&lt;br /&gt;
[[File:Instructor-view-1.png|border| 700px |center|alt=The proposed expanded student display.|The proposed expanded student display.]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''2. Student's view of teammate review''': Currently, a student is not able to see what grades were given by their teammates. We need to implement that functionality so that the student is able to view those grades.&lt;br /&gt;
&lt;br /&gt;
[[File:Student-view-2.png|border| 700px |center|alt=The current instructor view.|The current review display for instructors.]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''3. Error in existing UI for student''': In the existing UI for a student, the highlighted block should not be rendered. This part of the screen is meant for the instructors/TAs. &lt;br /&gt;
&lt;br /&gt;
[[File:Wrong render for student.png|border|700px|center|alt=Existing UI for student|Existing UI for student.]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Proposed changes ==&lt;br /&gt;
&lt;br /&gt;
''' 1) Proposed UI for instructor ''': The instructor is able to see the score for all teammates. In the existing code, only one teammate's scores are being shown. But, we are planning to change the way the (VmQuestionResponse array is populated)[https://github.com/expertiza/expertiza/blob/master/app/controllers/grades_controller.rb#L114], so that the scores for all teammates are appended to it so it correctly shows what should have already been shown in this screen for the instructor.&lt;br /&gt;
&lt;br /&gt;
[[File:Proposed_screen.png|border|700px|center|alt=Proposed UI for instructor|Proposed UI for instructor.]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Note: When a student visits this screen, they will only be shown the reviews received by them, assuming the instructor has allowed visibility of teammate reviews to students.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
''' 2) Show detailed review for a particular question''': The instructor can see detailed review given to a student by their teammates by clicking on a particular question number in the table.&lt;br /&gt;
&lt;br /&gt;
[[File:ss12a.png|border|700px|center|alt=New UI for students|New UI for students ]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
''' 3) Show teammate review to student UI ''': The existing code doesn't render a student's teammate review scores at all. We are planning to render the scores to a student (as shown below) when they visit this screen. However, the visibility of this screen is contingent on whether the instructor has allowed visibility of the teammate review screen to students. If the instructor has disabled this feature, then the heatgrid will not be displayed at all.&lt;br /&gt;
&lt;br /&gt;
[[File:UI_for_student.png|border|700px|center|alt=New UI for students|New UI for students ]]&lt;br /&gt;
&lt;br /&gt;
== Models used / Explanation of fixes ==&lt;br /&gt;
&lt;br /&gt;
The below diagram illustrates the proposed code change for showing all team members with the teammate review data to an instructor. The existing code only iterated on the `Participant` whose ID is present in the URL of the page. To fix this, we will iterate over all teammates of the given participant so that all teammate reviews for all team members are shown to the instructor.&lt;br /&gt;
&lt;br /&gt;
[[File:Logic e2165.png|border|center|alt=Flow diagram of proposed changes for showing team review data to instructor]]&lt;br /&gt;
&lt;br /&gt;
===Changes made to the code are shown below. Every change is shown and explained separately===&lt;br /&gt;
&lt;br /&gt;
====A. Added the following to app/assets/stylesheets/grades.scss:====&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    .teammate_table.hidden {&lt;br /&gt;
      display: none;&lt;br /&gt;
      }&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
====B. In app/controllers/grades_controller.rb: ====&lt;br /&gt;
&lt;br /&gt;
'''B.1:'''&lt;br /&gt;
&lt;br /&gt;
Old code: The existing code does not differentiate when adding a view model for the TeammateReview questionnaire&lt;br /&gt;
  questionnaires.each do |questionnaire|&lt;br /&gt;
     ...&lt;br /&gt;
     @vmlist &amp;lt;&amp;lt; populate_view_model(questionnaire)&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
New code: Since the current page URL contains an ID for the participant, from which we get an assignment, which gives us a list of questionnaires, we need to iterate all participants for a `TeammateReveiwQuestionnaire` questionnaire, so that we get the heatgrid view models for all members of a team.&lt;br /&gt;
  questionnaires.each do |questionnaire|&lt;br /&gt;
     ...&lt;br /&gt;
     if questionnaire.type == &amp;quot;TeammateReviewQuestionnaire&amp;quot;&lt;br /&gt;
        # as teammate review will be different for each participant&lt;br /&gt;
        # we need to create a separate table for each teammate&lt;br /&gt;
        @participant.team.participants.each do |team_participant|&lt;br /&gt;
          @vmlist &amp;lt;&amp;lt; populate_view_model(team_participant, questionnaire, @team)&lt;br /&gt;
        end&lt;br /&gt;
      else&lt;br /&gt;
        # only one participant needs iterating, as apart from teammatereview&lt;br /&gt;
        # all other reviews are at &amp;quot;team&amp;quot; level&lt;br /&gt;
        @vmlist &amp;lt;&amp;lt; populate_view_model(@participant, questionnaire, @team)&lt;br /&gt;
      end&lt;br /&gt;
   end&lt;br /&gt;
&lt;br /&gt;
'''B.2: '''&lt;br /&gt;
&lt;br /&gt;
Old code: This code uses @participant as an instance variable, but this structure will not work as we need to call this ViewModel with multiple participants when iterating for a teammate review questionnaire.&lt;br /&gt;
    def populate_view_model(questionnaire)&lt;br /&gt;
      vm = VmQuestionResponse.new(questionnaire, @assignment, @round)&lt;br /&gt;
      vmquestions = questionnaire.questions&lt;br /&gt;
      vm.add_questions(vmquestions)&lt;br /&gt;
      vm.add_team_members(@team)&lt;br /&gt;
      vm.add_reviews(@participant, @team, @assignment.vary_by_round)&lt;br /&gt;
      vm.number_of_comments_greater_than_10_words&lt;br /&gt;
      vm &lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
New code: We need to call this function with a separate participant in each invocation due to our change for TeammateReviewQuestionnaire, hence it makes sense to make `participant` as an argument to this function. Similarly, as `team` is a closely related model to `participant`, we are passing it as an argument, to keep this function as &amp;quot;pure&amp;quot; as possible.&lt;br /&gt;
    def populate_view_model(participant, questionnaire, team)&lt;br /&gt;
      ...&lt;br /&gt;
      vm.add_team_members(team)&lt;br /&gt;
      vm.add_reviews(participant, team, @assignment.vary_by_round)&lt;br /&gt;
      ...&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
====C. In app/models/vm_question_response.rb:====&lt;br /&gt;
&lt;br /&gt;
'''C.1: '''Added the reviewee_id method: Created a helper method within the VmQuestionReponse model to retrieve the `reviewee_id` for a heatgrid&lt;br /&gt;
&lt;br /&gt;
    def reviewee_id&lt;br /&gt;
      @participant_who_is_reviewee.user_id&lt;br /&gt;
    end &lt;br /&gt;
&lt;br /&gt;
'''C.2: '''Added the reviewee_name method: Created a helper method within the VmQuestionReponse model to retrieve the name of the student who is being reviewed for a heatgrid. This method uses the functionality to anonymize the name when we are in anonymized view.&lt;br /&gt;
&lt;br /&gt;
    def reviewee_name(ip_address = nil)&lt;br /&gt;
      part = @participant_who_is_reviewee&lt;br /&gt;
      User.find_by(id: part.user_id).fullname(ip_address)&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
'''C.3: '''&lt;br /&gt;
&lt;br /&gt;
Old code: Does not keep track of the student being reviewed&lt;br /&gt;
    elsif @questionnaire_type == &amp;quot;TeammateReviewQuestionnaire&amp;quot;&lt;br /&gt;
      reviews = participant.teammate_reviews&lt;br /&gt;
      reviews.each do |review|&lt;br /&gt;
        review_mapping = TeammateReviewResponseMap.find_by(id: review.map_id)&lt;br /&gt;
        participant = Participant.find(review_mapping.reviewer_id)&lt;br /&gt;
&lt;br /&gt;
New code: Add an instance variable to keep track of the student who is being reviewed in this VmQuestionReponse&lt;br /&gt;
    elsif @questionnaire_type == &amp;quot;TeammateReviewQuestionnaire&amp;quot;&lt;br /&gt;
      reviews = participant.teammate_reviews&lt;br /&gt;
      @participant_who_is_reviewee = participant&lt;br /&gt;
      reviews.each do |review|&lt;br /&gt;
        review_mapping = TeammateReviewResponseMap.find_by(id: review.map_id)&lt;br /&gt;
        participant = Participant.find(review_mapping.reviewer_id)&lt;br /&gt;
&lt;br /&gt;
'''C.4: '''&lt;br /&gt;
&lt;br /&gt;
Old code: Existing VmQuestionReponseScoreCell keeps no information about the reviewer, as it only stores the answer score&lt;br /&gt;
    row.score_row.push(VmQuestionResponseScoreCell.new(answer.answer, color_code, answer.comments, vm_tag_prompts))&lt;br /&gt;
&lt;br /&gt;
New code: Keep track of the response ID, so that we can retrieve the user ID for the reviewer in the model to use in the view file.&lt;br /&gt;
    &lt;br /&gt;
    row.score_row.push(VmQuestionResponseScoreCell.new(answer.answer, color_code, answer.comments, vm_tag_prompts, answer.response_id))&lt;br /&gt;
&lt;br /&gt;
====D. In app/models/vm_question_response_score_cell.rb:====&lt;br /&gt;
&lt;br /&gt;
'''D.1: '''In the method initialize of class VmQuestionResponseScoreCell&lt;br /&gt;
&lt;br /&gt;
Old code: Existing code doesn't keep track of the response id&lt;br /&gt;
    def initialize(score_value, color_code, comments, vmprompts = nil)&lt;br /&gt;
      @score_value = score_value&lt;br /&gt;
      @color_code = color_code&lt;br /&gt;
      @comment = comments&lt;br /&gt;
      @vm_prompts = vmprompts&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
New code: We added an instance variable to keep track of response_id&lt;br /&gt;
&lt;br /&gt;
    def initialize(score_value, color_code, comments, vmprompts = nil, response_id)&lt;br /&gt;
      ...&lt;br /&gt;
      @response_id = response_id&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
'''D.2: '''Added a method reviewer_id to the class VmQuestionResponseScoreCell: This helper method retrieves the ID for the reviewer who created this response.&lt;br /&gt;
&lt;br /&gt;
    def reviewer_id&lt;br /&gt;
      resp = Response.find(@response_id)&lt;br /&gt;
      map = ResponseMap.find(resp.map_id)&lt;br /&gt;
      map.reviewer_id&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
====E. In app/views/grades/_add_icon_to_name.html.erb:====&lt;br /&gt;
&lt;br /&gt;
'''E.1 '''Added the following code to the file: Write the code to generate the review text only once to reduce WET code&lt;br /&gt;
&lt;br /&gt;
    &amp;lt;%# Determine the content of the reviewed by text %&amp;gt;&lt;br /&gt;
    &amp;lt;% review_text = &amp;quot;&amp;quot; %&amp;gt;&lt;br /&gt;
    &amp;lt;% if @current_role_name.eql?'Student' or questionnaire_type != &amp;quot;TeammateReviewQuestionnaire&amp;quot; %&amp;gt;&lt;br /&gt;
      &amp;lt;%# Use Review {{index}} format for student view, and when questionnaire_type is not teammatereview %&amp;gt;&lt;br /&gt;
      &amp;lt;% review_text = &amp;quot;Review #{i + 1}&amp;quot; %&amp;gt;&lt;br /&gt;
    &amp;lt;% else %&amp;gt;&lt;br /&gt;
      &amp;lt;% resp = Response.find(review.id) %&amp;gt;&lt;br /&gt;
      &amp;lt;% map = ResponseMap.find(resp.map_id) %&amp;gt;&lt;br /&gt;
      &amp;lt;% reviewer_id = map.reviewer_id %&amp;gt;&lt;br /&gt;
      &amp;lt;% fullname = Participant.find_by(id: reviewer_id).fullname(session[:ip]) %&amp;gt;&lt;br /&gt;
      &amp;lt;% review_text = &amp;quot;Review by #{fullname}&amp;quot; %&amp;gt;&lt;br /&gt;
    &amp;lt;% end%&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''E.2: '''&lt;br /&gt;
&lt;br /&gt;
Old code: Existing code is very unreadable as it's not indented, and written in a single line with 359 characters, which breaks the ruby style guide rules&lt;br /&gt;
&lt;br /&gt;
    &amp;lt;% if review.done_by_staff_participant? %&amp;gt;&lt;br /&gt;
      &amp;lt;th class=&amp;quot;sorter-false&amp;quot;&amp;gt; &amp;lt;img data-toggle=&amp;quot;tooltip&amp;quot; data-placement=&amp;quot;right&amp;quot; title=&amp;quot;Icon indicates this review was done by course staff&amp;quot; class=&amp;quot;img_icon&amp;quot; src=&amp;quot;/assets/staff.png&amp;quot;&amp;gt; &amp;lt;a target=&amp;quot;_blank&amp;quot; href=&amp;quot;../response/view?id=&amp;lt;%= review.id.to_s %&amp;gt;&amp;quot;  data-toggle=&amp;quot;tooltip&amp;quot; data-placement=&amp;quot;right&amp;quot; title=&amp;quot;Click to see details&amp;quot;&amp;gt;&amp;lt;%= &amp;quot;Review &amp;quot; + i.to_s  %&amp;gt;&amp;lt;/a&amp;gt; &amp;lt;/th&amp;gt;&lt;br /&gt;
    &amp;lt;% else %&amp;gt;&lt;br /&gt;
      &amp;lt;th class=&amp;quot;sorter-false&amp;quot;&amp;gt; &amp;lt;a target=&amp;quot;_blank&amp;quot; href=&amp;quot;../response/view?id=&amp;lt;%= review.id.to_s %&amp;gt;&amp;quot;  data-toggle=&amp;quot;tooltip&amp;quot; data-placement=&amp;quot;right&amp;quot; title=&amp;quot;Click to see details&amp;quot;&amp;gt;&amp;lt;%= &amp;quot;Review &amp;quot; + i.to_s %&amp;gt;&amp;lt;/a&amp;gt;  &amp;lt;/th&amp;gt;&lt;br /&gt;
    &amp;lt;% end %&amp;gt;&lt;br /&gt;
&lt;br /&gt;
New code: Correctly indented and removes WET repetition of code blocks and makes the resulting code DRYer&lt;br /&gt;
&lt;br /&gt;
    &amp;lt;th class=&amp;quot;sorter-false&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;lt;% if review.done_by_staff_participant? %&amp;gt;&lt;br /&gt;
      &amp;lt;img&lt;br /&gt;
      data-toggle=&amp;quot;tooltip&amp;quot;&lt;br /&gt;
      data-placement=&amp;quot;right&amp;quot;&lt;br /&gt;
      title=&amp;quot;Icon indicates this review was done by course staff&amp;quot; class=&amp;quot;img_icon&amp;quot;&lt;br /&gt;
      src=&amp;quot;/assets/staff.png&amp;quot;&lt;br /&gt;
      &amp;gt;&lt;br /&gt;
    &amp;lt;% end %&amp;gt;&lt;br /&gt;
    &amp;lt;a&lt;br /&gt;
      target=&amp;quot;_blank&amp;quot;&lt;br /&gt;
      href=&amp;quot;../response/view?id=&amp;lt;%= review.id.to_s %&amp;gt;&amp;quot;&lt;br /&gt;
      data-toggle=&amp;quot;tooltip&amp;quot;&lt;br /&gt;
      data-placement=&amp;quot;right&amp;quot;&lt;br /&gt;
      title=&amp;quot;Click to see details&amp;quot;&amp;gt;&lt;br /&gt;
      &amp;lt;%= review_text %&amp;gt;&lt;br /&gt;
    &amp;lt;/a&amp;gt;&lt;br /&gt;
    &amp;lt;/th&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====F.In app/views/grades/view_team.html.erb:====&lt;br /&gt;
&lt;br /&gt;
'''F.1: '''Added function teammateSelectOnChange:&lt;br /&gt;
    &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  function teammateSelectOnChange(selectNode) {&lt;br /&gt;
      const revieweeIdToShow= selectNode.value;&lt;br /&gt;
      const tableSelector = &amp;quot;.teammate_table&amp;quot;;&lt;br /&gt;
      if(revieweeIdToShow == &amp;quot;all&amp;quot;) {&lt;br /&gt;
        document.querySelectorAll(tableSelector).forEach((tableNode) =&amp;gt; {&lt;br /&gt;
          tableNode.classList.remove(&amp;quot;hidden&amp;quot;);&lt;br /&gt;
        });&lt;br /&gt;
        return;&lt;br /&gt;
      }&lt;br /&gt;
&lt;br /&gt;
  document.querySelectorAll(tableSelector).forEach((tableNode) =&amp;gt; {&lt;br /&gt;
    const tableRevieweeId = tableNode.getAttribute('data-reviewee_id');&lt;br /&gt;
    if(tableRevieweeId == revieweeIdToShow) {&lt;br /&gt;
      tableNode.classList.remove(&amp;quot;hidden&amp;quot;);&lt;br /&gt;
    } else {&lt;br /&gt;
      tableNode.classList.add(&amp;quot;hidden&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
    });&lt;br /&gt;
  }&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''F.2: '''&lt;br /&gt;
&lt;br /&gt;
Old code&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    &amp;lt;% @vmlist.each do |vm| %&amp;gt;&lt;br /&gt;
        &amp;lt;% if (vm.questionnaire_display_type == &amp;quot;Metareview&amp;quot; or vm.questionnaire_display_type == &amp;quot;Author Feedback&amp;quot; or vm.questionnaire_display_type == &amp;quot;Teammate Review&amp;quot;) and @current_role_name.eql?'Student' %&amp;gt;&lt;br /&gt;
        &amp;lt;% else %&amp;gt;&lt;br /&gt;
        &amp;lt;% if vm.list_of_reviewers.length &amp;gt; 0 %&amp;gt;&lt;br /&gt;
&lt;br /&gt;
​      &amp;lt;!-- display the list of questions for this questionnaire --&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  @@ -87,6 +131,8 @@&lt;br /&gt;
              &amp;lt;h4 style=&amp;quot;display:inline-block;&amp;quot;&amp;gt;&amp;lt;%= vm.questionnaire_display_type %&amp;gt;&lt;br /&gt;
                &amp;lt;% if vm.questionnaire_type == &amp;quot;ReviewQuestionnaire&amp;quot; %&amp;gt;&lt;br /&gt;
                    (Round: &amp;lt;%= vm.round.to_s  %&amp;gt; of &amp;lt;%= vm.rounds.to_s  %&amp;gt;)&lt;br /&gt;
        &amp;lt;%end %&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
New code&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;%# This boolean is used to render a dropdown just before the first teammate review heat grid %&amp;gt;&lt;br /&gt;
&amp;lt;% first_teammate_review_appeared = false %&amp;gt;&lt;br /&gt;
&amp;lt;% @vmlist.each do |vm| %&amp;gt;&lt;br /&gt;
    &amp;lt;% if not @current_role_name.eql?'Student' and not first_teammate_review_appeared and vm.questionnaire_type == &amp;quot;TeammateReviewQuestionnaire&amp;quot; %&amp;gt;&lt;br /&gt;
      &amp;lt;div&amp;gt;&lt;br /&gt;
        &amp;lt;select onchange=&amp;quot;teammateSelectOnChange(this)&amp;quot;&amp;gt;&lt;br /&gt;
          &amp;lt;option value=&amp;quot;all&amp;quot;&amp;gt;All&amp;lt;/option&amp;gt;&lt;br /&gt;
          &amp;lt;% @vmlist.select { |tm_vm| tm_vm.questionnaire_type == &amp;quot;TeammateReviewQuestionnaire&amp;quot; }.each do |tm_vm| %&amp;gt;&lt;br /&gt;
            &amp;lt;option value=&amp;quot;&amp;lt;%= tm_vm.reviewee_id %&amp;gt;&amp;quot;&amp;gt;&lt;br /&gt;
              &amp;lt;%= tm_vm.reviewee_name(session[:ip]) %&amp;gt;&lt;br /&gt;
            &amp;lt;/option&amp;gt;&lt;br /&gt;
          &amp;lt;% end %&amp;gt;&lt;br /&gt;
        &amp;lt;/select&amp;gt;&lt;br /&gt;
      &amp;lt;/div&amp;gt;&lt;br /&gt;
      &amp;lt;% first_teammate_review_appeared = true %&amp;gt;&lt;br /&gt;
    &amp;lt;% end %&amp;gt;&lt;br /&gt;
    &amp;lt;% if (vm.questionnaire_display_type == &amp;quot;Metareview&amp;quot; or vm.questionnaire_display_type == &amp;quot;Author Feedback&amp;quot;) and @current_role_name.eql?'Student' %&amp;gt;&lt;br /&gt;
    &amp;lt;% elsif (vm.questionnaire_type == &amp;quot;TeammateReviewQuestionnaire&amp;quot; and @current_role_name.eql?'Student' and !@assignment.show_teammate_reviews)%&amp;gt;&lt;br /&gt;
    &amp;lt;% elsif (vm.questionnaire_type == &amp;quot;TeammateReviewQuestionnaire&amp;quot; and @current_role_name.eql?'Student' and @assignment.show_teammate_reviews and current_user.id != vm.reviewee_id )%&amp;gt;&lt;br /&gt;
    &amp;lt;% else %&amp;gt;&lt;br /&gt;
        &amp;lt;% if vm.questionnaire_type == &amp;quot;TeammateReviewQuestionnaire&amp;quot; %&amp;gt;&lt;br /&gt;
          &amp;lt;div class=&amp;quot;teammate_table&amp;quot; data-reviewee_id=&amp;quot;&amp;lt;%= vm.reviewee_id %&amp;gt;&amp;quot;&amp;gt;&lt;br /&gt;
        &amp;lt;% else %&amp;gt;&lt;br /&gt;
          &amp;lt;div&amp;gt;&lt;br /&gt;
        &amp;lt;% end %&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''F.3  '''&lt;br /&gt;
&lt;br /&gt;
Old code&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;!-- display the list of questions for this questionnaire --&amp;gt;&lt;br /&gt;
@@ -87,6 +131,8 @@&lt;br /&gt;
          &amp;lt;h4 style=&amp;quot;display:inline-block;&amp;quot;&amp;gt;&amp;lt;%= vm.questionnaire_display_type %&amp;gt;&lt;br /&gt;
            &amp;lt;% if vm.questionnaire_type == &amp;quot;ReviewQuestionnaire&amp;quot; %&amp;gt;&lt;br /&gt;
                (Round: &amp;lt;%= vm.round.to_s  %&amp;gt; of &amp;lt;%= vm.rounds.to_s  %&amp;gt;)&lt;br /&gt;
            &amp;lt;%end %&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
New code&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;!-- display the list of questions for this questionnaire --&amp;gt;&lt;br /&gt;
@@ -87,6 +131,8 @@&lt;br /&gt;
          &amp;lt;h4 style=&amp;quot;display:inline-block;&amp;quot;&amp;gt;&amp;lt;%= vm.questionnaire_display_type %&amp;gt;&lt;br /&gt;
            &amp;lt;% if vm.questionnaire_type == &amp;quot;ReviewQuestionnaire&amp;quot; %&amp;gt;&lt;br /&gt;
                (Round: &amp;lt;%= vm.round.to_s  %&amp;gt; of &amp;lt;%= vm.rounds.to_s  %&amp;gt;)&lt;br /&gt;
            &amp;lt;% elsif vm.questionnaire_type == &amp;quot;TeammateReviewQuestionnaire&amp;quot; %&amp;gt;&lt;br /&gt;
                (For: &amp;lt;%= vm.reviewee_name(session[:ip]) %&amp;gt;)&lt;br /&gt;
            &amp;lt;%end %&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''F.4 '''&lt;br /&gt;
&lt;br /&gt;
Old code&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;% vm.list_of_reviews.each do |review| %&amp;gt;&lt;br /&gt;
              &amp;lt;!-- instructors (or higher level users) see reviewer name, students see anonymized string --&amp;gt;&lt;br /&gt;
              &amp;lt;% if (['Student'].include? @current_role_name) &amp;amp;&amp;amp; @assignment.is_anonymous%&amp;gt;&lt;br /&gt;
                &amp;lt;%= render :partial =&amp;gt; 'add_icon_to_name', :locals =&amp;gt; {review: review, i: i} %&amp;gt;&lt;br /&gt;
              &amp;lt;% else %&amp;gt;&lt;br /&gt;
                  &amp;lt;% user_name = User.find(Participant.find(ResponseMap.find(Response.find(review.id).map_id).reviewer_id).user_id).fullname(session[:ip]).to_s %&amp;gt;&lt;br /&gt;
                &amp;lt;%= render :partial =&amp;gt; 'add_icon_to_name', :locals =&amp;gt; {review: review, i: i} %&amp;gt;&lt;br /&gt;
              &amp;lt;% end %&amp;gt;&lt;br /&gt;
              &amp;lt;% i += 1 %&amp;gt;&lt;br /&gt;
          &amp;lt;% end %&amp;gt;&lt;br /&gt;
&lt;br /&gt;
          &amp;lt;th class=&amp;quot;sorter-true&amp;quot; align=&amp;quot;right&amp;quot; &amp;gt;&lt;br /&gt;
            Avg&amp;lt;span&amp;gt;&amp;lt;/span&amp;gt;&lt;br /&gt;
          &amp;lt;/th&amp;gt;&lt;br /&gt;
          &amp;lt;th class=&amp;quot;sorter-false&amp;quot;&amp;gt;&lt;br /&gt;
            &amp;lt;span  data-toggle=&amp;quot;tooltip&amp;quot; data-placement=&amp;quot;right&amp;quot; title=&amp;quot;A count of comments, for the respective question, which have word count &amp;gt; 10. The purpose of this metric is to represent how many comments for the question are of a substantial length to provide quality feedback.&amp;quot;&amp;gt;metric-1&amp;lt;/span&amp;gt;&lt;br /&gt;
          &amp;lt;/th&amp;gt;&lt;br /&gt;
        &amp;lt;/tr&amp;gt;&lt;br /&gt;
        &amp;lt;/thead&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
New code&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;% vm.list_of_reviews.each do |review| %&amp;gt;&lt;br /&gt;
              &amp;lt;!-- instructors (or higher level users) see reviewer name, students see anonymized string --&amp;gt;&lt;br /&gt;
              &amp;lt;% if (['Student'].include? @current_role_name) &amp;amp;&amp;amp; @assignment.is_anonymous%&amp;gt;&lt;br /&gt;
                &amp;lt;%= render :partial =&amp;gt; 'add_icon_to_name', :locals =&amp;gt; {review: review, i: i, questionnaire_type: vm.questionnaire_type } %&amp;gt;&lt;br /&gt;
              &amp;lt;% else %&amp;gt;&lt;br /&gt;
                &amp;lt;% user_name = User.find(Participant.find(ResponseMap.find(Response.find(review.id).map_id).reviewer_id).user_id).fullname(session[:ip]).to_s %&amp;gt;&lt;br /&gt;
                &amp;lt;%= render :partial =&amp;gt; 'add_icon_to_name', :locals =&amp;gt; {review: review, i: i, questionnaire_type: vm.questionnaire_type } %&amp;gt;&lt;br /&gt;
              &amp;lt;% end %&amp;gt;&lt;br /&gt;
              &amp;lt;% i += 1 %&amp;gt;&lt;br /&gt;
          &amp;lt;% end %&amp;gt;&lt;br /&gt;
&lt;br /&gt;
          &amp;lt;th class=&amp;quot;sorter-true&amp;quot; align=&amp;quot;right&amp;quot; &amp;gt;&lt;br /&gt;
            Avg&amp;lt;span&amp;gt;&amp;lt;/span&amp;gt;&lt;br /&gt;
          &amp;lt;/th&amp;gt;&lt;br /&gt;
        &amp;lt;/tr&amp;gt;&lt;br /&gt;
        &amp;lt;/thead&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''F.5 '''&lt;br /&gt;
&lt;br /&gt;
Old code&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;% vm.list_of_rows.each do |row| %&amp;gt;&lt;br /&gt;
            &amp;lt;!-- notice the data-target. because we're toggling via looped code, we need to dynamically generate the identifier. --&amp;gt;&lt;br /&gt;
            &amp;lt;tr data-toggle=&amp;quot;collapse&amp;quot; class=&amp;quot;accordion-toggle&amp;quot; data-target=&amp;quot;#hid&amp;lt;%= row.question_id.to_s + vm.round.to_s %&amp;gt;&amp;quot;&amp;gt;&lt;br /&gt;
              &amp;lt;td class = 'cf' data-toggle=&amp;quot;tooltip&amp;quot; title=&amp;quot;&amp;lt;%= row.question_text %&amp;gt;&amp;quot;&amp;gt; &amp;lt;div style='float: left'&amp;gt;&amp;lt;%= j.to_s %&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;div style='float: right'&amp;gt; &amp;amp;#&amp;lt;%= type_and_max(row) %&amp;gt;;&amp;lt;/div&amp;gt;  &amp;lt;/td&amp;gt;&lt;br /&gt;
&lt;br /&gt;
              &amp;lt;!-- actual cells with scores and colored background. --&amp;gt;&lt;br /&gt;
              &amp;lt;% row.score_row.each do |score| %&amp;gt;&lt;br /&gt;
                  &amp;lt;% score_comment = score.comment.nil? ? '' : score.comment %&amp;gt; &amp;lt;!-- changing nil to null string to avoid Null Pointer Exception --&amp;gt;&lt;br /&gt;
                  &amp;lt;td class=&amp;quot;&amp;lt;%= score.color_code %&amp;gt;&amp;quot; align=&amp;quot;center&amp;quot; data-toggle=&amp;quot;tooltip&amp;quot; title=&amp;quot;&amp;lt;%= strip_tags(score.comment).html_safe%&amp;gt;&amp;quot;&amp;gt;&lt;br /&gt;
                    &amp;lt;span class=&amp;quot;&amp;lt;%=  underlined?(score) %&amp;gt;&amp;quot;&amp;gt;&amp;lt;%= score.score_value.to_s %&amp;gt;&amp;lt;/span&amp;gt;&lt;br /&gt;
                  &amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;% end %&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
New code&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;% vm.list_of_rows.each do |row| %&amp;gt;&lt;br /&gt;
            &amp;lt;% target_id = &amp;quot;hid__#{row.question_id}__#{vm.round}&amp;quot; %&amp;gt;&lt;br /&gt;
            &amp;lt;% if vm.questionnaire_type == &amp;quot;TeammateReviewQuestionnaire&amp;quot; %&amp;gt;&lt;br /&gt;
              &amp;lt;%# Since we render different heatgrids with the same questions for each&lt;br /&gt;
              teammember, we need to distinguish the ID, based on the user for whom,&lt;br /&gt;
              the reviews have been created. %&amp;gt;&lt;br /&gt;
              &amp;lt;% target_id += &amp;quot;__#{vm.reviewee_id}&amp;quot; %&amp;gt;&lt;br /&gt;
            &amp;lt;% end%&amp;gt;&lt;br /&gt;
&lt;br /&gt;
            &amp;lt;!-- notice the data-target. because we're toggling via looped code, we need to dynamically generate the identifier. --&amp;gt;&lt;br /&gt;
            &amp;lt;tr data-toggle=&amp;quot;collapse&amp;quot; class=&amp;quot;accordion-toggle&amp;quot; data-target=&amp;quot;&amp;lt;%= &amp;quot;#&amp;quot; + target_id %&amp;gt;&amp;quot;&amp;gt;&lt;br /&gt;
              &amp;lt;td class = 'cf' data-toggle=&amp;quot;tooltip&amp;quot; title=&amp;quot;&amp;lt;%= row.question_text %&amp;gt;&amp;quot;&amp;gt; &amp;lt;div style='float: left'&amp;gt;&amp;lt;%= j.to_s %&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;div style='float: right'&amp;gt; &amp;amp;#&amp;lt;%= type_and_max(row) %&amp;gt;;&amp;lt;/div&amp;gt;  &amp;lt;/td&amp;gt;&lt;br /&gt;
&lt;br /&gt;
              &amp;lt;!-- actual cells with scores and colored background. --&amp;gt;&lt;br /&gt;
              &amp;lt;% row.score_row.each do |score| %&amp;gt;&lt;br /&gt;
                  &amp;lt;% score_comment = score.comment.nil? ? '' : score.comment %&amp;gt;&lt;br /&gt;
                  &amp;lt;!-- changing nil to null string to avoid Null Pointer Exception --&amp;gt;&lt;br /&gt;
                  &amp;lt;td class=&amp;quot;&amp;lt;%= score.color_code %&amp;gt;&amp;quot; align=&amp;quot;center&amp;quot; data-toggle=&amp;quot;tooltip&amp;quot; title=&amp;quot;&amp;lt;%= strip_tags(score.comment).html_safe%&amp;gt;&amp;quot;&amp;gt;&lt;br /&gt;
                    &amp;lt;span class=&amp;quot;&amp;lt;%=  underlined?(score) %&amp;gt;&amp;quot;&amp;gt;&lt;br /&gt;
                      &amp;lt;%= score.score_value.to_s %&amp;gt;&lt;br /&gt;
                    &amp;lt;/span&amp;gt;&lt;br /&gt;
                  &amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;% end %&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''F.6 '''Removed the following code.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 &amp;lt;td  class = 'cf' align=&amp;quot;center&amp;quot;&amp;gt;&lt;br /&gt;
                &amp;lt;%= row.countofcomments.to_s %&amp;gt;&lt;br /&gt;
              &amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''F.7 '''&lt;br /&gt;
&lt;br /&gt;
Old code&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;!--loop that creates the collapsed-by-default row, which lists all comments. --&amp;gt;&lt;br /&gt;
            &amp;lt;tr class=&amp;quot;tablesorter-childRow&amp;quot;&amp;gt;&lt;br /&gt;
              &amp;lt;td colspan=&amp;quot;&amp;lt;%= (i+1).to_s %&amp;gt;&amp;quot; class=&amp;quot;hiddenRow&amp;quot; &amp;gt;&amp;lt;div id=&amp;quot;hid&amp;lt;%= row.question_id.to_s + vm.round.to_s %&amp;gt;&amp;quot; class=&amp;quot;accordion-body collapse&amp;quot; style=&amp;quot;margin-left:10px;&amp;quot;&amp;gt;&lt;br /&gt;
                &amp;lt;div style=&amp;quot;padding-top: 10px; padding-bottom: 10px;&amp;quot;&amp;gt;&amp;lt;%=  sanitize row.question_text %&amp;gt;&amp;lt;/div&amp;gt;&lt;br /&gt;
                &amp;lt;div&amp;gt;&lt;br /&gt;
                  &amp;lt;table class=&amp;quot;table tbl_questlist&amp;quot;&amp;gt;&lt;br /&gt;
@@ -181,7 +233,17 @@&lt;br /&gt;
                    &amp;lt;/thead&amp;gt;&lt;br /&gt;
                    &amp;lt;% for index in 0 .. row.score_row.length - 1 %&amp;gt;&lt;br /&gt;
                        &amp;lt;tr&amp;gt;&lt;br /&gt;
                          &amp;lt;td&amp;gt;Review &amp;lt;%=index + 1%&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
New code&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;!--loop that creates the collapsed-by-default row, which lists all comments. --&amp;gt;&lt;br /&gt;
            &amp;lt;tr class=&amp;quot;tablesorter-childRow&amp;quot;&amp;gt;&lt;br /&gt;
              &amp;lt;td colspan=&amp;quot;&amp;lt;%= (i+1).to_s %&amp;gt;&amp;quot; class=&amp;quot;hiddenRow&amp;quot; &amp;gt;&amp;lt;div id=&amp;quot;&amp;lt;%= target_id %&amp;gt;&amp;quot; class=&amp;quot;accordion-body collapse&amp;quot; style=&amp;quot;margin-left:10px;&amp;quot;&amp;gt;&lt;br /&gt;
                &amp;lt;div style=&amp;quot;padding-top: 10px; padding-bottom: 10px;&amp;quot;&amp;gt;&amp;lt;%=  sanitize row.question_text %&amp;gt;&amp;lt;/div&amp;gt;&lt;br /&gt;
                &amp;lt;div&amp;gt;&lt;br /&gt;
                  &amp;lt;table class=&amp;quot;table tbl_questlist&amp;quot;&amp;gt;&lt;br /&gt;
@@ -181,7 +233,17 @@&lt;br /&gt;
                    &amp;lt;/thead&amp;gt;&lt;br /&gt;
                    &amp;lt;% for index in 0 .. row.score_row.length - 1 %&amp;gt;&lt;br /&gt;
                        &amp;lt;tr&amp;gt;&lt;br /&gt;
                          &amp;lt;% if @current_role_name.eql?'Student' or vm.questionnaire_type != &amp;quot;TeammateReviewQuestionnaire&amp;quot; %&amp;gt;&lt;br /&gt;
                            &amp;lt;%# Use Review {{index}} format for student view, and&lt;br /&gt;
                            when questionnaire_type is not teammatereview %&amp;gt;&lt;br /&gt;
                            &amp;lt;td&amp;gt;Review &amp;lt;%=index + 1%&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
                          &amp;lt;% else %&amp;gt;&lt;br /&gt;
                            &amp;lt;td&amp;gt;&lt;br /&gt;
                              &amp;lt;% reviewer_id = row.score_row[index].reviewer_id %&amp;gt;&lt;br /&gt;
                              &amp;lt;% fullname = Participant.find_by(id: reviewer_id).fullname(session[:ip]) %&amp;gt;&lt;br /&gt;
                              Review by &amp;lt;%= fullname %&amp;gt;&lt;br /&gt;
                            &amp;lt;/td&amp;gt;&lt;br /&gt;
                          &amp;lt;% end%&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
====G. In spec/controllers/grades_controller_spec.rb:====&lt;br /&gt;
&lt;br /&gt;
'''G.1 '''&lt;br /&gt;
&lt;br /&gt;
Old code&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
before(:each) do&lt;br /&gt;
  allow(AssignmentParticipant).to receive(:find).with('1').and_return(participant)&lt;br /&gt;
  allow(participant).to receive(:team).and_return(team)&lt;br /&gt;
  stub_current_user(instructor, instructor.role.name, instructor.role)&lt;br /&gt;
  allow(Assignment).to receive(:find).with('1').and_return(assignment)&lt;br /&gt;
@@ -91,29 +90,106 @@&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
New code&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
before(:each) do&lt;br /&gt;
  allow(participant).to receive(:team).and_return(team)&lt;br /&gt;
  stub_current_user(instructor, instructor.role.name, instructor.role)&lt;br /&gt;
  allow(Assignment).to receive(:find).with('1').and_return(assignment)&lt;br /&gt;
@@ -91,29 +90,106 @@&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''G.2 '''Remove xdescribe '#view_team' and change describe '#view_team' as follows.&lt;br /&gt;
&lt;br /&gt;
Old code&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
describe '#view_team' do&lt;br /&gt;
render_views&lt;br /&gt;
context 'when view_team page is viewed by a student who is also a TA for another course' do&lt;br /&gt;
  it 'renders grades#view_team page' do&lt;br /&gt;
    allow(participant).to receive(:team).and_return(team)&lt;br /&gt;
    allow(AssignmentQuestionnaire).to receive(:find_by).with(assignment_id: 1, questionnaire_id: 1).and_return(assignment_questionnaire)&lt;br /&gt;
    allow(AssignmentQuestionnaire).to receive(:where).with(any_args).and_return([assignment_questionnaire])&lt;br /&gt;
    allow(assignment).to receive(:late_policy_id).and_return(false)&lt;br /&gt;
    allow(assignment).to receive(:calculate_penalty).and_return(false)&lt;br /&gt;
    allow(assignment).to receive(:compute_total_score).with(any_args).and_return(100)&lt;br /&gt;
    allow(review_questionnaire).to receive(:get_assessments_round_for).with(participant, 1).and_return([review_response])&lt;br /&gt;
    allow(Answer).to receive(:compute_scores).with([review_response], [question]).and_return(max: 95, min: 88, avg: 90)&lt;br /&gt;
    params = {id: 1}&lt;br /&gt;
    allow(TaMapping).to receive(:exists?).with(ta_id: 1, course_id: 1).and_return(true)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
New code&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
describe '#view_team' do&lt;br /&gt;
render_views&lt;br /&gt;
&lt;br /&gt;
# All stubs and factories are instantiated within this scope so as to not &lt;br /&gt;
# clash with other broken test.&lt;br /&gt;
# The names of the factories created for testing view_team&lt;br /&gt;
# have `_vt` suffix ```where necessary``` to differentiate them from &lt;br /&gt;
# the above declared factories&lt;br /&gt;
&lt;br /&gt;
let(:student1_vt) { create(:student, name: &amp;quot;barry&amp;quot;, id: 12) }&lt;br /&gt;
let(:student2_vt) { create(:student, name: &amp;quot;iris&amp;quot;, id: 13) }&lt;br /&gt;
&lt;br /&gt;
let(:tm_questionnaire) {&lt;br /&gt;
  build(&lt;br /&gt;
    :teammate_review_questionnaire,&lt;br /&gt;
    id: 12,&lt;br /&gt;
    questions: [question],&lt;br /&gt;
    max_question_score: 5&lt;br /&gt;
  )&lt;br /&gt;
}&lt;br /&gt;
let(:assignment_vt) {&lt;br /&gt;
  create(:assignment, id: 6, max_team_size: 2,&lt;br /&gt;
  questionnaires: [tm_questionnaire])&lt;br /&gt;
}&lt;br /&gt;
let(:assignment_questionnaire_vt) {&lt;br /&gt;
  create(:tm_assignment_questionnaire, id: 12, used_in_round: nil,&lt;br /&gt;
  assignment: assignment_vt, questionnaire: tm_questionnaire) }&lt;br /&gt;
let(:team_vt) { create(:assignment_team, id: 12,&lt;br /&gt;
assignment: assignment_vt) }&lt;br /&gt;
let(:participant_vt) { create(:participant, id: 12,&lt;br /&gt;
  assignment: assignment_vt, user_id: student1_vt.id) }&lt;br /&gt;
let(:participant2_vt) { create(:participant, id: 13,&lt;br /&gt;
  assignment: assignment_vt, user_id: student2_vt.id) }&lt;br /&gt;
&lt;br /&gt;
before(:each) do&lt;br /&gt;
  # Need to stub this method so the factory instance with&lt;br /&gt;
  # the stubbed :team method is returned by :find&lt;br /&gt;
  # instead of a separate instance with the same data&lt;br /&gt;
  allow(AssignmentParticipant)&lt;br /&gt;
    .to receive(:find)&lt;br /&gt;
    .with(participant_vt.id.to_s)&lt;br /&gt;
    .and_return(participant_vt)&lt;br /&gt;
  allow(participant_vt).to receive(:team).and_return(team_vt)&lt;br /&gt;
  allow(team_vt).to receive(:participants).and_return([participant_vt, participant2_vt])&lt;br /&gt;
  allow(AssignmentQuestionnaire)&lt;br /&gt;
    .to receive(:find_by)&lt;br /&gt;
    .with(assignment_id: assignment_vt.id, questionnaire_id: tm_questionnaire.id)&lt;br /&gt;
    .and_return(assignment_questionnaire_vt)&lt;br /&gt;
  allow(AssignmentQuestionnaire)&lt;br /&gt;
    .to receive(:find_by)&lt;br /&gt;
    .with(assignment_id: assignment.id, questionnaire_id: review_questionnaire.id)&lt;br /&gt;
    .and_return(assignment_questionnaire_vt)&lt;br /&gt;
  allow(AssignmentQuestionnaire)&lt;br /&gt;
    .to receive(:where)&lt;br /&gt;
    .with(any_args)&lt;br /&gt;
    .and_return([assignment_questionnaire_vt])&lt;br /&gt;
  allow(assignment_vt)&lt;br /&gt;
    .to receive(:late_policy_id)&lt;br /&gt;
    .and_return(false)&lt;br /&gt;
  allow(assignment_vt)&lt;br /&gt;
    .to receive(:calculate_penalty)&lt;br /&gt;
    .and_return(false)&lt;br /&gt;
  allow(assignment_vt)&lt;br /&gt;
    .to receive(:compute_total_score)&lt;br /&gt;
    .with(any_args)&lt;br /&gt;
    .and_return(100)&lt;br /&gt;
  allow(review_questionnaire).to receive(:get_assessments_round_for).with(participant, 1).and_return([review_response])&lt;br /&gt;
  allow(Answer).to receive(:compute_scores).with([review_response], [question]).and_return(max: 95, min: 88, avg: 90)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
 it 'renders grades#view_team page' do&lt;br /&gt;
  params = {id: participant_vt.id}&lt;br /&gt;
  get :view_team, params&lt;br /&gt;
  expect(response).to render_template(:view_team)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
context 'when view_team page is opened by student' do&lt;br /&gt;
  it 'dropdown is not rendered' do&lt;br /&gt;
    session = { user: student1_vt }&lt;br /&gt;
    params = {id: participant_vt.id}&lt;br /&gt;
    stub_current_user(student1_vt, student1_vt.role.name, student1_vt.role)&lt;br /&gt;
    get :view_team, params&lt;br /&gt;
    expect(response.body).to_not have_selector('select')&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
context 'when view_team page is opened by instructor' do&lt;br /&gt;
  it 'dropdown is rendered' do&lt;br /&gt;
    session = { user: instructor }&lt;br /&gt;
    params = {id: participant_vt.id}&lt;br /&gt;
    get :view_team, params&lt;br /&gt;
    expect(response.body).to have_selector('select')&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
context 'when view_team page is viewed by a student who is also a TA for another course' do&lt;br /&gt;
  it 'renders grades#view_team page' do&lt;br /&gt;
    params = { id: participant_vt.id }&lt;br /&gt;
    allow(TaMapping).to receive(:exists?).with(ta_id: participant_vt.user_id, course_id: 1).and_return(true)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
====H. In spec/factories/factories.rb:====&lt;br /&gt;
&lt;br /&gt;
'''H.1 '''Add the following factory:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
factory :teammate_review_questionnaire, class: TeammateReviewQuestionnaire do&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''H.2 '''Add another factory&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
factory :tm_assignment_questionnaire, class: AssignmentQuestionnaire do&lt;br /&gt;
  user_id 1&lt;br /&gt;
  questionnaire { association(:teammate_review_questionnaire) }&lt;br /&gt;
  questionnaire_weight 100&lt;br /&gt;
  used_in_round nil&lt;br /&gt;
  topic_id nil&lt;br /&gt;
  dropdown 1&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Summary of file changes ===&lt;br /&gt;
&lt;br /&gt;
The following files are modified:&lt;br /&gt;
&lt;br /&gt;
1. app/controllers/grades_controller.rb - Controller file which changed how the view model is populated&lt;br /&gt;
&lt;br /&gt;
2. app/views/grades/view_team.html.erb - View file, which  conditionally rendered the teammate name, for a teammate review heatgrid&lt;br /&gt;
&lt;br /&gt;
3. spec/controllers/grades_controller_spec.rb - For tests verifying the proposed changes&lt;br /&gt;
&lt;br /&gt;
4. app/models/vm_question_response.rb - To modify the view-model so it can tell us the name of the person being reviewed for the current heatgrid&lt;br /&gt;
&lt;br /&gt;
5. app/models/vm_question_response_score_cell.rb - &lt;br /&gt;
&lt;br /&gt;
6. app/assets/stylesheets/grades.scss - &lt;br /&gt;
&lt;br /&gt;
7. app/views/grades/_add_icon_to_name.html.erb - &lt;br /&gt;
&lt;br /&gt;
8. spec/factories/factories.rb -&lt;br /&gt;
&lt;br /&gt;
== Design Patterns ==&lt;br /&gt;
&lt;br /&gt;
Existing code does not use any design patterns, apart from if-else. It uses if-else conditional statements to check what type of questionnaire is present in the viewmodel `VmQuestionResponse`, and based on that, it renders the appropriate content.&lt;br /&gt;
&lt;br /&gt;
We decided to continue with this approach since to change the present coding style, there were required many changes (refactoring) to many files which were out of the scope of the present project. To complete the project in the assigned time, we followed the if-else approach.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== User Stories ==&lt;br /&gt;
&lt;br /&gt;
1. As an instructor, I can view what reviews one teammate has given to other teammates.&lt;br /&gt;
&lt;br /&gt;
2. As a student, I can view what reviews my teammates have given to me.&lt;br /&gt;
&lt;br /&gt;
3. As an instructor, I can choose if I want to see all student's teammates reviews together or one by one.&lt;br /&gt;
&lt;br /&gt;
4. As a student, if I am also a TA for another subject, I should not be able to see an instructor's view to the view_team page.&lt;br /&gt;
&lt;br /&gt;
5. As an instructor, I should be able to see the name of the reviewers for the reviews to a particular student.&lt;br /&gt;
&lt;br /&gt;
== Testing ==&lt;br /&gt;
'''OLD STATUS'''&lt;br /&gt;
&lt;br /&gt;
1. Earlier, the tests only covered if the view_team is page is rendered when it is asked for. This can be seen on the line 94 and 103 in [https://github.com/expertiza/expertiza/blob/beta/spec/controllers/grades_controller_spec.rb this] file.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''NEW STATUS'''&lt;br /&gt;
&lt;br /&gt;
1. The view_team page is rendered correctly for a given student or an instructor.&lt;br /&gt;
&lt;br /&gt;
2. When students access then the view_team page, the dropdown to select a student's teammate reviews is not rendered on the page.&lt;br /&gt;
&lt;br /&gt;
3. When instructor access then the view_team page, the dropdown to select a student's teammate reviews is rendered on the page.&lt;br /&gt;
&lt;br /&gt;
4. When a student who is also a TA for another course access the view_team page, that student should be able to a student's view to the page.&lt;br /&gt;
&lt;br /&gt;
5. If show_teammate_reviews boolean is set to False, then the student should not be able to see the teammate reviews given to him/her. If it is set to True, then the student should be able to see the reviews.&lt;br /&gt;
&lt;br /&gt;
6. An instructor should be able to see the teammate reviews for all students regardless of whether the show_teammate_reviews boolean is set to True or False.&lt;br /&gt;
&lt;br /&gt;
7. The reviewer id is tracked correctly to show the correct reviewer name in the teammate reviews table. This can be seen on line 27 in [https://github.com/expertiza/expertiza/blob/66239d9a8a53697ea170a92208593b36d06dfd24/spec/models/vm_question_response_score_cell_spec.rb this] file &lt;br /&gt;
&lt;br /&gt;
8. An instructor can select which student's scores he/she wants to see. If no student's name is selected then the professor can see the scores of all the students.&lt;br /&gt;
&lt;br /&gt;
==References==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;https://expertiza.ncsu.edu/&amp;lt;/p&amp;gt;&lt;/div&gt;</summary>
		<author><name>Vdeshmu</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2021_-_E2165._Fix_teammate-review_view&amp;diff=141739</id>
		<title>CSC/ECE 517 Fall 2021 - E2165. Fix teammate-review view</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2021_-_E2165._Fix_teammate-review_view&amp;diff=141739"/>
		<updated>2021-11-28T18:04:17Z</updated>

		<summary type="html">&lt;p&gt;Vdeshmu: /* D. In app/models/vm_question_response_score_cell.rb: */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Team Introduction ==&lt;br /&gt;
&lt;br /&gt;
Dr. Edward Gehringer (instructor), Parimal Mehta (mentor)&lt;br /&gt;
&lt;br /&gt;
1. Anjali Garg (unity ID : agarg25)&lt;br /&gt;
&lt;br /&gt;
2. Arvasu Chikara (unity ID: achikar2)&lt;br /&gt;
&lt;br /&gt;
3. Lalit Bangad (unity ID: llbangad)&lt;br /&gt;
&lt;br /&gt;
4. Vinay Deshmukh (unity ID: vdeshmu)&lt;br /&gt;
&lt;br /&gt;
== Problems to be addressed ==&lt;br /&gt;
&lt;br /&gt;
After a project is submitted and reviewed, both the team members (students) and instructors should be able to view the teammate reviews. Students should be able to view the reviews by going to a particular assignment's -&amp;gt; your scores, at the bottom of the page. An instructor can view the teammate reviews by going to assignments -&amp;gt; assignment -&amp;gt; particular team's submission -&amp;gt; view submission -&amp;gt; assign grades -&amp;gt; view scores. &lt;br /&gt;
&lt;br /&gt;
In the case of the instructor, a single heat grid is shown whereas in the case of a team member, we cant view the scores. In the heat grid, it is not clear if the scores visible are for the reviews that the student has *written* for their teammates or the scores that the student has *received* from their teammates. Additionally, for instructors can choose from a list of the students on the team, but they have no way to tell whether the heat grid shows the reviews done *by* that student or done *for* that student.&lt;br /&gt;
&lt;br /&gt;
== Methodology Overview ==&lt;br /&gt;
&lt;br /&gt;
We have divided our work in the following tasks to address the above problems:&lt;br /&gt;
&lt;br /&gt;
1. Distinguish reviews done for a student by rendering separates heatgrids for each student&lt;br /&gt;
&lt;br /&gt;
2. For instructors, the table will have sections based on the students&lt;br /&gt;
&lt;br /&gt;
3. Include a checkbox on the edit assignment page that enables/disables visibility of heat grid to students&lt;br /&gt;
&lt;br /&gt;
4. Fix the average column for a table (which breaks for some reviews)&lt;br /&gt;
&lt;br /&gt;
5. Show a composite score derived from all reviews.  Make this code generalized, so other kinds of heat grid views could use it.&lt;br /&gt;
&lt;br /&gt;
6. Changes should work even in an anonymized view&lt;br /&gt;
&lt;br /&gt;
== Motivations ==&lt;br /&gt;
&lt;br /&gt;
1. Enable users to clearly tell which reviews are done by them, and which reviews are done for them.&lt;br /&gt;
&lt;br /&gt;
2. Code should be generic so it can be used for different types of heat grids as well.&lt;br /&gt;
&lt;br /&gt;
== Control Flow to access the concerned screens ==&lt;br /&gt;
'''1. For instructor (Log in as an instructor):-'''&lt;br /&gt;
&lt;br /&gt;
Screen after logging in by the instructor&lt;br /&gt;
[[File:ss1.png |border|1000px|center]]&lt;br /&gt;
Got to assignments on the Manage menu &lt;br /&gt;
[[File:ss2.png |border|1000px|center]]&lt;br /&gt;
Go to assignments&lt;br /&gt;
[[File:ss3.png |border|1000px|center]]&lt;br /&gt;
Go to submissions for any assignment&lt;br /&gt;
[[File:ss4a.png |border|1000px|center]]&lt;br /&gt;
Go to Assign Grade&lt;br /&gt;
[[File:ss5a.png |border|1000px|center]]&lt;br /&gt;
You will land on the page where the changes are made and can be reviewed&lt;br /&gt;
[[File:ss7a.png |border|1000px|center]]&lt;br /&gt;
&lt;br /&gt;
'''2. Student:- (Logged in as an instructor)'''&lt;br /&gt;
&lt;br /&gt;
After landing on the assignments page, select any student from an assignment as shown below&lt;br /&gt;
[[File:ss6a.png |border|1000px|center]]&lt;br /&gt;
Go to/Select any assignment&lt;br /&gt;
[[File:ss9a.png |border|1000px|center]]&lt;br /&gt;
Go to your scores&lt;br /&gt;
[[File:ss10a.png |border|1000px|center]]&lt;br /&gt;
You will land on the page where the changes are made and can be reviewed&lt;br /&gt;
[[File:ss11a.png |border|1000px|center]]&lt;br /&gt;
&lt;br /&gt;
== Old Status of the application ==&lt;br /&gt;
&lt;br /&gt;
'''1. Instructor's view of teammate review''': This is the current screen given to the instructor. Here we see that the instructor can not determine who has given which review to which student in a team.&lt;br /&gt;
&lt;br /&gt;
[[File:Instructor-view-1.png|border| 700px |center|alt=The proposed expanded student display.|The proposed expanded student display.]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''2. Student's view of teammate review''': Currently, a student is not able to see what grades were given by their teammates. We need to implement that functionality so that the student is able to view those grades.&lt;br /&gt;
&lt;br /&gt;
[[File:Student-view-2.png|border| 700px |center|alt=The current instructor view.|The current review display for instructors.]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''3. Error in existing UI for student''': In the existing UI for a student, the highlighted block should not be rendered. This part of the screen is meant for the instructors/TAs. &lt;br /&gt;
&lt;br /&gt;
[[File:Wrong render for student.png|border|700px|center|alt=Existing UI for student|Existing UI for student.]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Proposed changes ==&lt;br /&gt;
&lt;br /&gt;
''' 1) Proposed UI for instructor ''': The instructor is able to see the score for all teammates. In the existing code, only one teammate's scores are being shown. But, we are planning to change the way the (VmQuestionResponse array is populated)[https://github.com/expertiza/expertiza/blob/master/app/controllers/grades_controller.rb#L114], so that the scores for all teammates are appended to it so it correctly shows what should have already been shown in this screen for the instructor.&lt;br /&gt;
&lt;br /&gt;
[[File:Proposed_screen.png|border|700px|center|alt=Proposed UI for instructor|Proposed UI for instructor.]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Note: When a student visits this screen, they will only be shown the reviews received by them, assuming the instructor has allowed visibility of teammate reviews to students.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
''' 2) Show detailed review for a particular question''': The instructor can see detailed review given to a student by their teammates by clicking on a particular question number in the table.&lt;br /&gt;
&lt;br /&gt;
[[File:ss12a.png|border|700px|center|alt=New UI for students|New UI for students ]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
''' 3) Show teammate review to student UI ''': The existing code doesn't render a student's teammate review scores at all. We are planning to render the scores to a student (as shown below) when they visit this screen. However, the visibility of this screen is contingent on whether the instructor has allowed visibility of the teammate review screen to students. If the instructor has disabled this feature, then the heatgrid will not be displayed at all.&lt;br /&gt;
&lt;br /&gt;
[[File:UI_for_student.png|border|700px|center|alt=New UI for students|New UI for students ]]&lt;br /&gt;
&lt;br /&gt;
== Models used / Explanation of fixes ==&lt;br /&gt;
&lt;br /&gt;
The below diagram illustrates the proposed code change for showing all team members with the teammate review data to an instructor. The existing code only iterated on the `Participant` whose ID is present in the URL of the page. To fix this, we will iterate over all teammates of the given participant so that all teammate reviews for all team members are shown to the instructor.&lt;br /&gt;
&lt;br /&gt;
[[File:Logic e2165.png|border|center|alt=Flow diagram of proposed changes for showing team review data to instructor]]&lt;br /&gt;
&lt;br /&gt;
===Changes made to the code are shown below. Every change is shown and explained separately===&lt;br /&gt;
&lt;br /&gt;
====A. Added the following to app/assets/stylesheets/grades.scss:====&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    .teammate_table.hidden {&lt;br /&gt;
      display: none;&lt;br /&gt;
      }&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
====B. In app/controllers/grades_controller.rb: ====&lt;br /&gt;
&lt;br /&gt;
'''B.1:'''&lt;br /&gt;
&lt;br /&gt;
Old code: The existing code does not differentiate when adding a view model for the TeammateReview questionnaire&lt;br /&gt;
  questionnaires.each do |questionnaire|&lt;br /&gt;
     ...&lt;br /&gt;
     @vmlist &amp;lt;&amp;lt; populate_view_model(questionnaire)&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
New code: Since the current page URL contains an ID for the participant, from which we get an assignment, which gives us a list of questionnaires, we need to iterate all participants for a `TeammateReveiwQuestionnaire` questionnaire, so that we get the heatgrid view models for all members of a team.&lt;br /&gt;
  questionnaires.each do |questionnaire|&lt;br /&gt;
     ...&lt;br /&gt;
     if questionnaire.type == &amp;quot;TeammateReviewQuestionnaire&amp;quot;&lt;br /&gt;
        # as teammate review will be different for each participant&lt;br /&gt;
        # we need to create a separate table for each teammate&lt;br /&gt;
        @participant.team.participants.each do |team_participant|&lt;br /&gt;
          @vmlist &amp;lt;&amp;lt; populate_view_model(team_participant, questionnaire, @team)&lt;br /&gt;
        end&lt;br /&gt;
      else&lt;br /&gt;
        # only one participant needs iterating, as apart from teammatereview&lt;br /&gt;
        # all other reviews are at &amp;quot;team&amp;quot; level&lt;br /&gt;
        @vmlist &amp;lt;&amp;lt; populate_view_model(@participant, questionnaire, @team)&lt;br /&gt;
      end&lt;br /&gt;
   end&lt;br /&gt;
&lt;br /&gt;
'''B.2: '''&lt;br /&gt;
&lt;br /&gt;
Old code: This code uses @participant as an instance variable, but this structure will not work as we need to call this ViewModel with multiple participants when iterating for a teammate review questionnaire.&lt;br /&gt;
    def populate_view_model(questionnaire)&lt;br /&gt;
      vm = VmQuestionResponse.new(questionnaire, @assignment, @round)&lt;br /&gt;
      vmquestions = questionnaire.questions&lt;br /&gt;
      vm.add_questions(vmquestions)&lt;br /&gt;
      vm.add_team_members(@team)&lt;br /&gt;
      vm.add_reviews(@participant, @team, @assignment.vary_by_round)&lt;br /&gt;
      vm.number_of_comments_greater_than_10_words&lt;br /&gt;
      vm &lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
New code: We need to call this function with a separate participant in each invocation due to our change for TeammateReviewQuestionnaire, hence it makes sense to make `participant` as an argument to this function. Similarly, as `team` is a closely related model to `participant`, we are passing it as an argument, to keep this function as &amp;quot;pure&amp;quot; as possible.&lt;br /&gt;
    def populate_view_model(participant, questionnaire, team)&lt;br /&gt;
      ...&lt;br /&gt;
      vm.add_team_members(team)&lt;br /&gt;
      vm.add_reviews(participant, team, @assignment.vary_by_round)&lt;br /&gt;
      ...&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
====C. In app/models/vm_question_response.rb:====&lt;br /&gt;
&lt;br /&gt;
'''C.1: '''Added the reviewee_id method: Created a helper method within the VmQuestionReponse model to retrieve the `reviewee_id` for a heatgrid&lt;br /&gt;
&lt;br /&gt;
    def reviewee_id&lt;br /&gt;
      @participant_who_is_reviewee.user_id&lt;br /&gt;
    end &lt;br /&gt;
&lt;br /&gt;
'''C.2: '''Added the reviewee_name method: Created a helper method within the VmQuestionReponse model to retrieve the name of the student who is being reviewed for a heatgrid. This method uses the functionality to anonymize the name when we are in anonymized view.&lt;br /&gt;
&lt;br /&gt;
    def reviewee_name(ip_address = nil)&lt;br /&gt;
      part = @participant_who_is_reviewee&lt;br /&gt;
      User.find_by(id: part.user_id).fullname(ip_address)&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
'''C.3: '''&lt;br /&gt;
&lt;br /&gt;
Old code: Does not keep track of the student being reviewed&lt;br /&gt;
    elsif @questionnaire_type == &amp;quot;TeammateReviewQuestionnaire&amp;quot;&lt;br /&gt;
      reviews = participant.teammate_reviews&lt;br /&gt;
      reviews.each do |review|&lt;br /&gt;
        review_mapping = TeammateReviewResponseMap.find_by(id: review.map_id)&lt;br /&gt;
        participant = Participant.find(review_mapping.reviewer_id)&lt;br /&gt;
&lt;br /&gt;
New code: Add an instance variable to keep track of the student who is being reviewed in this VmQuestionReponse&lt;br /&gt;
    elsif @questionnaire_type == &amp;quot;TeammateReviewQuestionnaire&amp;quot;&lt;br /&gt;
      reviews = participant.teammate_reviews&lt;br /&gt;
      @participant_who_is_reviewee = participant&lt;br /&gt;
      reviews.each do |review|&lt;br /&gt;
        review_mapping = TeammateReviewResponseMap.find_by(id: review.map_id)&lt;br /&gt;
        participant = Participant.find(review_mapping.reviewer_id)&lt;br /&gt;
&lt;br /&gt;
'''C.4: '''&lt;br /&gt;
&lt;br /&gt;
Old code: Existing VmQuestionReponseScoreCell keeps no information about the reviewer, as it only stores the answer score&lt;br /&gt;
    row.score_row.push(VmQuestionResponseScoreCell.new(answer.answer, color_code, answer.comments, vm_tag_prompts))&lt;br /&gt;
&lt;br /&gt;
New code: Keep track of the response ID, so that we can retrieve the user ID for the reviewer in the model to use in the view file.&lt;br /&gt;
    &lt;br /&gt;
    row.score_row.push(VmQuestionResponseScoreCell.new(answer.answer, color_code, answer.comments, vm_tag_prompts, answer.response_id))&lt;br /&gt;
&lt;br /&gt;
====D. In app/models/vm_question_response_score_cell.rb:====&lt;br /&gt;
&lt;br /&gt;
'''D.1: '''In the method initialize of class VmQuestionResponseScoreCell&lt;br /&gt;
&lt;br /&gt;
Old code: Existing code doesn't keep track of the response id&lt;br /&gt;
    def initialize(score_value, color_code, comments, vmprompts = nil)&lt;br /&gt;
      @score_value = score_value&lt;br /&gt;
      @color_code = color_code&lt;br /&gt;
      @comment = comments&lt;br /&gt;
      @vm_prompts = vmprompts&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
New code: We added an instance variable to keep track of response_id&lt;br /&gt;
&lt;br /&gt;
    def initialize(score_value, color_code, comments, vmprompts = nil, response_id)&lt;br /&gt;
      ...&lt;br /&gt;
      @response_id = response_id&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
'''D.2: '''Added a method reviewer_id to the class VmQuestionResponseScoreCell: This helper method retrieves the ID for the reviewer who created this response.&lt;br /&gt;
&lt;br /&gt;
    def reviewer_id&lt;br /&gt;
      resp = Response.find(@response_id)&lt;br /&gt;
      map = ResponseMap.find(resp.map_id)&lt;br /&gt;
      map.reviewer_id&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
====E. In app/views/grades/_add_icon_to_name.html.erb:====&lt;br /&gt;
&lt;br /&gt;
'''E.1 '''Added the following code to the file:&lt;br /&gt;
&lt;br /&gt;
    &amp;lt;%# Determine the content of the reviewed by text %&amp;gt;&lt;br /&gt;
    &amp;lt;% review_text = &amp;quot;&amp;quot; %&amp;gt;&lt;br /&gt;
    &amp;lt;% if @current_role_name.eql?'Student' or questionnaire_type != &amp;quot;TeammateReviewQuestionnaire&amp;quot; %&amp;gt;&lt;br /&gt;
      &amp;lt;%# Use Review {{index}} format for student view, and when questionnaire_type is not teammatereview %&amp;gt;&lt;br /&gt;
      &amp;lt;% review_text = &amp;quot;Review #{i + 1}&amp;quot; %&amp;gt;&lt;br /&gt;
    &amp;lt;% else %&amp;gt;&lt;br /&gt;
      &amp;lt;% resp = Response.find(review.id) %&amp;gt;&lt;br /&gt;
      &amp;lt;% map = ResponseMap.find(resp.map_id) %&amp;gt;&lt;br /&gt;
      &amp;lt;% reviewer_id = map.reviewer_id %&amp;gt;&lt;br /&gt;
      &amp;lt;% fullname = Participant.find_by(id: reviewer_id).fullname(session[:ip]) %&amp;gt;&lt;br /&gt;
      &amp;lt;% review_text = &amp;quot;Review by #{fullname}&amp;quot; %&amp;gt;&lt;br /&gt;
    &amp;lt;% end%&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''E.2: '''&lt;br /&gt;
&lt;br /&gt;
Old code&lt;br /&gt;
&lt;br /&gt;
    &amp;lt;% if review.done_by_staff_participant? %&amp;gt;&lt;br /&gt;
      &amp;lt;th class=&amp;quot;sorter-false&amp;quot;&amp;gt; &amp;lt;img data-toggle=&amp;quot;tooltip&amp;quot; data-placement=&amp;quot;right&amp;quot; title=&amp;quot;Icon indicates this review was done by course staff&amp;quot; class=&amp;quot;img_icon&amp;quot; src=&amp;quot;/assets/staff.png&amp;quot;&amp;gt; &amp;lt;a target=&amp;quot;_blank&amp;quot; href=&amp;quot;../response/view?id=&amp;lt;%= review.id.to_s %&amp;gt;&amp;quot;  data-toggle=&amp;quot;tooltip&amp;quot; data-placement=&amp;quot;right&amp;quot; title=&amp;quot;Click to see details&amp;quot;&amp;gt;&amp;lt;%= &amp;quot;Review &amp;quot; + i.to_s  %&amp;gt;&amp;lt;/a&amp;gt; &amp;lt;/th&amp;gt;&lt;br /&gt;
    &amp;lt;% else %&amp;gt;&lt;br /&gt;
      &amp;lt;th class=&amp;quot;sorter-false&amp;quot;&amp;gt; &amp;lt;a target=&amp;quot;_blank&amp;quot; href=&amp;quot;../response/view?id=&amp;lt;%= review.id.to_s %&amp;gt;&amp;quot;  data-toggle=&amp;quot;tooltip&amp;quot; data-placement=&amp;quot;right&amp;quot; title=&amp;quot;Click to see details&amp;quot;&amp;gt;&amp;lt;%= &amp;quot;Review &amp;quot; + i.to_s %&amp;gt;&amp;lt;/a&amp;gt;  &amp;lt;/th&amp;gt;&lt;br /&gt;
    &amp;lt;% end %&amp;gt;&lt;br /&gt;
&lt;br /&gt;
New code&lt;br /&gt;
&lt;br /&gt;
    &amp;lt;% if review.done_by_staff_participant? %&amp;gt;&lt;br /&gt;
    &amp;lt;th class=&amp;quot;sorter-false&amp;quot;&amp;gt;&lt;br /&gt;
      &amp;lt;img&lt;br /&gt;
      data-toggle=&amp;quot;tooltip&amp;quot;&lt;br /&gt;
      data-placement=&amp;quot;right&amp;quot;&lt;br /&gt;
      title=&amp;quot;Icon indicates this review was done by course staff&amp;quot; class=&amp;quot;img_icon&amp;quot;&lt;br /&gt;
      src=&amp;quot;/assets/staff.png&amp;quot;&lt;br /&gt;
      &amp;gt;&lt;br /&gt;
    &amp;lt;a&lt;br /&gt;
      target=&amp;quot;_blank&amp;quot;&lt;br /&gt;
      href=&amp;quot;../response/view?id=&amp;lt;%= review.id.to_s %&amp;gt;&amp;quot;&lt;br /&gt;
      data-toggle=&amp;quot;tooltip&amp;quot;&lt;br /&gt;
      data-placement=&amp;quot;right&amp;quot;&lt;br /&gt;
      title=&amp;quot;Click to see details&amp;quot;&amp;gt;&lt;br /&gt;
      &amp;lt;%= review_text %&amp;gt;&lt;br /&gt;
    &amp;lt;/a&amp;gt;&lt;br /&gt;
    &amp;lt;/th&amp;gt;&lt;br /&gt;
    &amp;lt;% else %&amp;gt;&lt;br /&gt;
    &amp;lt;th class=&amp;quot;sorter-false&amp;quot;&amp;gt;&lt;br /&gt;
        &amp;lt;a&lt;br /&gt;
            target=&amp;quot;_blank&amp;quot; &lt;br /&gt;
            href=&amp;quot;../response/view?id=&amp;lt;%= review.id.to_s %&amp;gt;&amp;quot;  &lt;br /&gt;
            data-toggle=&amp;quot;tooltip&amp;quot;&lt;br /&gt;
            data-placement=&amp;quot;right&amp;quot;&lt;br /&gt;
            title=&amp;quot;Click to see details&amp;quot;&lt;br /&gt;
        &amp;gt;&lt;br /&gt;
        &amp;lt;%= review_text %&amp;gt;&lt;br /&gt;
        &amp;lt;/a&amp;gt;&lt;br /&gt;
    &amp;lt;/th&amp;gt;&lt;br /&gt;
    &amp;lt;% end %&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
====F.In app/views/grades/view_team.html.erb:====&lt;br /&gt;
&lt;br /&gt;
'''F.1: '''Added function teammateSelectOnChange:&lt;br /&gt;
    &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  function teammateSelectOnChange(selectNode) {&lt;br /&gt;
      const revieweeIdToShow= selectNode.value;&lt;br /&gt;
      const tableSelector = &amp;quot;.teammate_table&amp;quot;;&lt;br /&gt;
      if(revieweeIdToShow == &amp;quot;all&amp;quot;) {&lt;br /&gt;
        document.querySelectorAll(tableSelector).forEach((tableNode) =&amp;gt; {&lt;br /&gt;
          tableNode.classList.remove(&amp;quot;hidden&amp;quot;);&lt;br /&gt;
        });&lt;br /&gt;
        return;&lt;br /&gt;
      }&lt;br /&gt;
&lt;br /&gt;
  document.querySelectorAll(tableSelector).forEach((tableNode) =&amp;gt; {&lt;br /&gt;
    const tableRevieweeId = tableNode.getAttribute('data-reviewee_id');&lt;br /&gt;
    if(tableRevieweeId == revieweeIdToShow) {&lt;br /&gt;
      tableNode.classList.remove(&amp;quot;hidden&amp;quot;);&lt;br /&gt;
    } else {&lt;br /&gt;
      tableNode.classList.add(&amp;quot;hidden&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
    });&lt;br /&gt;
  }&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''F.2: '''&lt;br /&gt;
&lt;br /&gt;
Old code&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    &amp;lt;% @vmlist.each do |vm| %&amp;gt;&lt;br /&gt;
        &amp;lt;% if (vm.questionnaire_display_type == &amp;quot;Metareview&amp;quot; or vm.questionnaire_display_type == &amp;quot;Author Feedback&amp;quot; or vm.questionnaire_display_type == &amp;quot;Teammate Review&amp;quot;) and @current_role_name.eql?'Student' %&amp;gt;&lt;br /&gt;
        &amp;lt;% else %&amp;gt;&lt;br /&gt;
        &amp;lt;% if vm.list_of_reviewers.length &amp;gt; 0 %&amp;gt;&lt;br /&gt;
&lt;br /&gt;
​      &amp;lt;!-- display the list of questions for this questionnaire --&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  @@ -87,6 +131,8 @@&lt;br /&gt;
              &amp;lt;h4 style=&amp;quot;display:inline-block;&amp;quot;&amp;gt;&amp;lt;%= vm.questionnaire_display_type %&amp;gt;&lt;br /&gt;
                &amp;lt;% if vm.questionnaire_type == &amp;quot;ReviewQuestionnaire&amp;quot; %&amp;gt;&lt;br /&gt;
                    (Round: &amp;lt;%= vm.round.to_s  %&amp;gt; of &amp;lt;%= vm.rounds.to_s  %&amp;gt;)&lt;br /&gt;
        &amp;lt;%end %&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
New code&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;%# This boolean is used to render a dropdown just before the first teammate review heat grid %&amp;gt;&lt;br /&gt;
&amp;lt;% first_teammate_review_appeared = false %&amp;gt;&lt;br /&gt;
&amp;lt;% @vmlist.each do |vm| %&amp;gt;&lt;br /&gt;
    &amp;lt;% if not @current_role_name.eql?'Student' and not first_teammate_review_appeared and vm.questionnaire_type == &amp;quot;TeammateReviewQuestionnaire&amp;quot; %&amp;gt;&lt;br /&gt;
      &amp;lt;div&amp;gt;&lt;br /&gt;
        &amp;lt;select onchange=&amp;quot;teammateSelectOnChange(this)&amp;quot;&amp;gt;&lt;br /&gt;
          &amp;lt;option value=&amp;quot;all&amp;quot;&amp;gt;All&amp;lt;/option&amp;gt;&lt;br /&gt;
          &amp;lt;% @vmlist.select { |tm_vm| tm_vm.questionnaire_type == &amp;quot;TeammateReviewQuestionnaire&amp;quot; }.each do |tm_vm| %&amp;gt;&lt;br /&gt;
            &amp;lt;option value=&amp;quot;&amp;lt;%= tm_vm.reviewee_id %&amp;gt;&amp;quot;&amp;gt;&lt;br /&gt;
              &amp;lt;%= tm_vm.reviewee_name(session[:ip]) %&amp;gt;&lt;br /&gt;
            &amp;lt;/option&amp;gt;&lt;br /&gt;
          &amp;lt;% end %&amp;gt;&lt;br /&gt;
        &amp;lt;/select&amp;gt;&lt;br /&gt;
      &amp;lt;/div&amp;gt;&lt;br /&gt;
      &amp;lt;% first_teammate_review_appeared = true %&amp;gt;&lt;br /&gt;
    &amp;lt;% end %&amp;gt;&lt;br /&gt;
    &amp;lt;% if (vm.questionnaire_display_type == &amp;quot;Metareview&amp;quot; or vm.questionnaire_display_type == &amp;quot;Author Feedback&amp;quot;) and @current_role_name.eql?'Student' %&amp;gt;&lt;br /&gt;
    &amp;lt;% elsif (vm.questionnaire_type == &amp;quot;TeammateReviewQuestionnaire&amp;quot; and @current_role_name.eql?'Student' and !@assignment.show_teammate_reviews)%&amp;gt;&lt;br /&gt;
    &amp;lt;% elsif (vm.questionnaire_type == &amp;quot;TeammateReviewQuestionnaire&amp;quot; and @current_role_name.eql?'Student' and @assignment.show_teammate_reviews and current_user.id != vm.reviewee_id )%&amp;gt;&lt;br /&gt;
    &amp;lt;% else %&amp;gt;&lt;br /&gt;
        &amp;lt;% if vm.questionnaire_type == &amp;quot;TeammateReviewQuestionnaire&amp;quot; %&amp;gt;&lt;br /&gt;
          &amp;lt;div class=&amp;quot;teammate_table&amp;quot; data-reviewee_id=&amp;quot;&amp;lt;%= vm.reviewee_id %&amp;gt;&amp;quot;&amp;gt;&lt;br /&gt;
        &amp;lt;% else %&amp;gt;&lt;br /&gt;
          &amp;lt;div&amp;gt;&lt;br /&gt;
        &amp;lt;% end %&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''F.3  '''&lt;br /&gt;
&lt;br /&gt;
Old code&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;!-- display the list of questions for this questionnaire --&amp;gt;&lt;br /&gt;
@@ -87,6 +131,8 @@&lt;br /&gt;
          &amp;lt;h4 style=&amp;quot;display:inline-block;&amp;quot;&amp;gt;&amp;lt;%= vm.questionnaire_display_type %&amp;gt;&lt;br /&gt;
            &amp;lt;% if vm.questionnaire_type == &amp;quot;ReviewQuestionnaire&amp;quot; %&amp;gt;&lt;br /&gt;
                (Round: &amp;lt;%= vm.round.to_s  %&amp;gt; of &amp;lt;%= vm.rounds.to_s  %&amp;gt;)&lt;br /&gt;
            &amp;lt;%end %&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
New code&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;!-- display the list of questions for this questionnaire --&amp;gt;&lt;br /&gt;
@@ -87,6 +131,8 @@&lt;br /&gt;
          &amp;lt;h4 style=&amp;quot;display:inline-block;&amp;quot;&amp;gt;&amp;lt;%= vm.questionnaire_display_type %&amp;gt;&lt;br /&gt;
            &amp;lt;% if vm.questionnaire_type == &amp;quot;ReviewQuestionnaire&amp;quot; %&amp;gt;&lt;br /&gt;
                (Round: &amp;lt;%= vm.round.to_s  %&amp;gt; of &amp;lt;%= vm.rounds.to_s  %&amp;gt;)&lt;br /&gt;
            &amp;lt;% elsif vm.questionnaire_type == &amp;quot;TeammateReviewQuestionnaire&amp;quot; %&amp;gt;&lt;br /&gt;
                (For: &amp;lt;%= vm.reviewee_name(session[:ip]) %&amp;gt;)&lt;br /&gt;
            &amp;lt;%end %&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''F.4 '''&lt;br /&gt;
&lt;br /&gt;
Old code&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;% vm.list_of_reviews.each do |review| %&amp;gt;&lt;br /&gt;
              &amp;lt;!-- instructors (or higher level users) see reviewer name, students see anonymized string --&amp;gt;&lt;br /&gt;
              &amp;lt;% if (['Student'].include? @current_role_name) &amp;amp;&amp;amp; @assignment.is_anonymous%&amp;gt;&lt;br /&gt;
                &amp;lt;%= render :partial =&amp;gt; 'add_icon_to_name', :locals =&amp;gt; {review: review, i: i} %&amp;gt;&lt;br /&gt;
              &amp;lt;% else %&amp;gt;&lt;br /&gt;
                  &amp;lt;% user_name = User.find(Participant.find(ResponseMap.find(Response.find(review.id).map_id).reviewer_id).user_id).fullname(session[:ip]).to_s %&amp;gt;&lt;br /&gt;
                &amp;lt;%= render :partial =&amp;gt; 'add_icon_to_name', :locals =&amp;gt; {review: review, i: i} %&amp;gt;&lt;br /&gt;
              &amp;lt;% end %&amp;gt;&lt;br /&gt;
              &amp;lt;% i += 1 %&amp;gt;&lt;br /&gt;
          &amp;lt;% end %&amp;gt;&lt;br /&gt;
&lt;br /&gt;
          &amp;lt;th class=&amp;quot;sorter-true&amp;quot; align=&amp;quot;right&amp;quot; &amp;gt;&lt;br /&gt;
            Avg&amp;lt;span&amp;gt;&amp;lt;/span&amp;gt;&lt;br /&gt;
          &amp;lt;/th&amp;gt;&lt;br /&gt;
          &amp;lt;th class=&amp;quot;sorter-false&amp;quot;&amp;gt;&lt;br /&gt;
            &amp;lt;span  data-toggle=&amp;quot;tooltip&amp;quot; data-placement=&amp;quot;right&amp;quot; title=&amp;quot;A count of comments, for the respective question, which have word count &amp;gt; 10. The purpose of this metric is to represent how many comments for the question are of a substantial length to provide quality feedback.&amp;quot;&amp;gt;metric-1&amp;lt;/span&amp;gt;&lt;br /&gt;
          &amp;lt;/th&amp;gt;&lt;br /&gt;
        &amp;lt;/tr&amp;gt;&lt;br /&gt;
        &amp;lt;/thead&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
New code&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;% vm.list_of_reviews.each do |review| %&amp;gt;&lt;br /&gt;
              &amp;lt;!-- instructors (or higher level users) see reviewer name, students see anonymized string --&amp;gt;&lt;br /&gt;
              &amp;lt;% if (['Student'].include? @current_role_name) &amp;amp;&amp;amp; @assignment.is_anonymous%&amp;gt;&lt;br /&gt;
                &amp;lt;%= render :partial =&amp;gt; 'add_icon_to_name', :locals =&amp;gt; {review: review, i: i, questionnaire_type: vm.questionnaire_type } %&amp;gt;&lt;br /&gt;
              &amp;lt;% else %&amp;gt;&lt;br /&gt;
                &amp;lt;% user_name = User.find(Participant.find(ResponseMap.find(Response.find(review.id).map_id).reviewer_id).user_id).fullname(session[:ip]).to_s %&amp;gt;&lt;br /&gt;
                &amp;lt;%= render :partial =&amp;gt; 'add_icon_to_name', :locals =&amp;gt; {review: review, i: i, questionnaire_type: vm.questionnaire_type } %&amp;gt;&lt;br /&gt;
              &amp;lt;% end %&amp;gt;&lt;br /&gt;
              &amp;lt;% i += 1 %&amp;gt;&lt;br /&gt;
          &amp;lt;% end %&amp;gt;&lt;br /&gt;
&lt;br /&gt;
          &amp;lt;th class=&amp;quot;sorter-true&amp;quot; align=&amp;quot;right&amp;quot; &amp;gt;&lt;br /&gt;
            Avg&amp;lt;span&amp;gt;&amp;lt;/span&amp;gt;&lt;br /&gt;
          &amp;lt;/th&amp;gt;&lt;br /&gt;
        &amp;lt;/tr&amp;gt;&lt;br /&gt;
        &amp;lt;/thead&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''F.5 '''&lt;br /&gt;
&lt;br /&gt;
Old code&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;% vm.list_of_rows.each do |row| %&amp;gt;&lt;br /&gt;
            &amp;lt;!-- notice the data-target. because we're toggling via looped code, we need to dynamically generate the identifier. --&amp;gt;&lt;br /&gt;
            &amp;lt;tr data-toggle=&amp;quot;collapse&amp;quot; class=&amp;quot;accordion-toggle&amp;quot; data-target=&amp;quot;#hid&amp;lt;%= row.question_id.to_s + vm.round.to_s %&amp;gt;&amp;quot;&amp;gt;&lt;br /&gt;
              &amp;lt;td class = 'cf' data-toggle=&amp;quot;tooltip&amp;quot; title=&amp;quot;&amp;lt;%= row.question_text %&amp;gt;&amp;quot;&amp;gt; &amp;lt;div style='float: left'&amp;gt;&amp;lt;%= j.to_s %&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;div style='float: right'&amp;gt; &amp;amp;#&amp;lt;%= type_and_max(row) %&amp;gt;;&amp;lt;/div&amp;gt;  &amp;lt;/td&amp;gt;&lt;br /&gt;
&lt;br /&gt;
              &amp;lt;!-- actual cells with scores and colored background. --&amp;gt;&lt;br /&gt;
              &amp;lt;% row.score_row.each do |score| %&amp;gt;&lt;br /&gt;
                  &amp;lt;% score_comment = score.comment.nil? ? '' : score.comment %&amp;gt; &amp;lt;!-- changing nil to null string to avoid Null Pointer Exception --&amp;gt;&lt;br /&gt;
                  &amp;lt;td class=&amp;quot;&amp;lt;%= score.color_code %&amp;gt;&amp;quot; align=&amp;quot;center&amp;quot; data-toggle=&amp;quot;tooltip&amp;quot; title=&amp;quot;&amp;lt;%= strip_tags(score.comment).html_safe%&amp;gt;&amp;quot;&amp;gt;&lt;br /&gt;
                    &amp;lt;span class=&amp;quot;&amp;lt;%=  underlined?(score) %&amp;gt;&amp;quot;&amp;gt;&amp;lt;%= score.score_value.to_s %&amp;gt;&amp;lt;/span&amp;gt;&lt;br /&gt;
                  &amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;% end %&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
New code&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;% vm.list_of_rows.each do |row| %&amp;gt;&lt;br /&gt;
            &amp;lt;% target_id = &amp;quot;hid__#{row.question_id}__#{vm.round}&amp;quot; %&amp;gt;&lt;br /&gt;
            &amp;lt;% if vm.questionnaire_type == &amp;quot;TeammateReviewQuestionnaire&amp;quot; %&amp;gt;&lt;br /&gt;
              &amp;lt;%# Since we render different heatgrids with the same questions for each&lt;br /&gt;
              teammember, we need to distinguish the ID, based on the user for whom,&lt;br /&gt;
              the reviews have been created. %&amp;gt;&lt;br /&gt;
              &amp;lt;% target_id += &amp;quot;__#{vm.reviewee_id}&amp;quot; %&amp;gt;&lt;br /&gt;
            &amp;lt;% end%&amp;gt;&lt;br /&gt;
&lt;br /&gt;
            &amp;lt;!-- notice the data-target. because we're toggling via looped code, we need to dynamically generate the identifier. --&amp;gt;&lt;br /&gt;
            &amp;lt;tr data-toggle=&amp;quot;collapse&amp;quot; class=&amp;quot;accordion-toggle&amp;quot; data-target=&amp;quot;&amp;lt;%= &amp;quot;#&amp;quot; + target_id %&amp;gt;&amp;quot;&amp;gt;&lt;br /&gt;
              &amp;lt;td class = 'cf' data-toggle=&amp;quot;tooltip&amp;quot; title=&amp;quot;&amp;lt;%= row.question_text %&amp;gt;&amp;quot;&amp;gt; &amp;lt;div style='float: left'&amp;gt;&amp;lt;%= j.to_s %&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;div style='float: right'&amp;gt; &amp;amp;#&amp;lt;%= type_and_max(row) %&amp;gt;;&amp;lt;/div&amp;gt;  &amp;lt;/td&amp;gt;&lt;br /&gt;
&lt;br /&gt;
              &amp;lt;!-- actual cells with scores and colored background. --&amp;gt;&lt;br /&gt;
              &amp;lt;% row.score_row.each do |score| %&amp;gt;&lt;br /&gt;
                  &amp;lt;% score_comment = score.comment.nil? ? '' : score.comment %&amp;gt;&lt;br /&gt;
                  &amp;lt;!-- changing nil to null string to avoid Null Pointer Exception --&amp;gt;&lt;br /&gt;
                  &amp;lt;td class=&amp;quot;&amp;lt;%= score.color_code %&amp;gt;&amp;quot; align=&amp;quot;center&amp;quot; data-toggle=&amp;quot;tooltip&amp;quot; title=&amp;quot;&amp;lt;%= strip_tags(score.comment).html_safe%&amp;gt;&amp;quot;&amp;gt;&lt;br /&gt;
                    &amp;lt;span class=&amp;quot;&amp;lt;%=  underlined?(score) %&amp;gt;&amp;quot;&amp;gt;&lt;br /&gt;
                      &amp;lt;%= score.score_value.to_s %&amp;gt;&lt;br /&gt;
                    &amp;lt;/span&amp;gt;&lt;br /&gt;
                  &amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;% end %&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''F.6 '''Removed the following code.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 &amp;lt;td  class = 'cf' align=&amp;quot;center&amp;quot;&amp;gt;&lt;br /&gt;
                &amp;lt;%= row.countofcomments.to_s %&amp;gt;&lt;br /&gt;
              &amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''F.7 '''&lt;br /&gt;
&lt;br /&gt;
Old code&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;!--loop that creates the collapsed-by-default row, which lists all comments. --&amp;gt;&lt;br /&gt;
            &amp;lt;tr class=&amp;quot;tablesorter-childRow&amp;quot;&amp;gt;&lt;br /&gt;
              &amp;lt;td colspan=&amp;quot;&amp;lt;%= (i+1).to_s %&amp;gt;&amp;quot; class=&amp;quot;hiddenRow&amp;quot; &amp;gt;&amp;lt;div id=&amp;quot;hid&amp;lt;%= row.question_id.to_s + vm.round.to_s %&amp;gt;&amp;quot; class=&amp;quot;accordion-body collapse&amp;quot; style=&amp;quot;margin-left:10px;&amp;quot;&amp;gt;&lt;br /&gt;
                &amp;lt;div style=&amp;quot;padding-top: 10px; padding-bottom: 10px;&amp;quot;&amp;gt;&amp;lt;%=  sanitize row.question_text %&amp;gt;&amp;lt;/div&amp;gt;&lt;br /&gt;
                &amp;lt;div&amp;gt;&lt;br /&gt;
                  &amp;lt;table class=&amp;quot;table tbl_questlist&amp;quot;&amp;gt;&lt;br /&gt;
@@ -181,7 +233,17 @@&lt;br /&gt;
                    &amp;lt;/thead&amp;gt;&lt;br /&gt;
                    &amp;lt;% for index in 0 .. row.score_row.length - 1 %&amp;gt;&lt;br /&gt;
                        &amp;lt;tr&amp;gt;&lt;br /&gt;
                          &amp;lt;td&amp;gt;Review &amp;lt;%=index + 1%&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
New code&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;!--loop that creates the collapsed-by-default row, which lists all comments. --&amp;gt;&lt;br /&gt;
            &amp;lt;tr class=&amp;quot;tablesorter-childRow&amp;quot;&amp;gt;&lt;br /&gt;
              &amp;lt;td colspan=&amp;quot;&amp;lt;%= (i+1).to_s %&amp;gt;&amp;quot; class=&amp;quot;hiddenRow&amp;quot; &amp;gt;&amp;lt;div id=&amp;quot;&amp;lt;%= target_id %&amp;gt;&amp;quot; class=&amp;quot;accordion-body collapse&amp;quot; style=&amp;quot;margin-left:10px;&amp;quot;&amp;gt;&lt;br /&gt;
                &amp;lt;div style=&amp;quot;padding-top: 10px; padding-bottom: 10px;&amp;quot;&amp;gt;&amp;lt;%=  sanitize row.question_text %&amp;gt;&amp;lt;/div&amp;gt;&lt;br /&gt;
                &amp;lt;div&amp;gt;&lt;br /&gt;
                  &amp;lt;table class=&amp;quot;table tbl_questlist&amp;quot;&amp;gt;&lt;br /&gt;
@@ -181,7 +233,17 @@&lt;br /&gt;
                    &amp;lt;/thead&amp;gt;&lt;br /&gt;
                    &amp;lt;% for index in 0 .. row.score_row.length - 1 %&amp;gt;&lt;br /&gt;
                        &amp;lt;tr&amp;gt;&lt;br /&gt;
                          &amp;lt;% if @current_role_name.eql?'Student' or vm.questionnaire_type != &amp;quot;TeammateReviewQuestionnaire&amp;quot; %&amp;gt;&lt;br /&gt;
                            &amp;lt;%# Use Review {{index}} format for student view, and&lt;br /&gt;
                            when questionnaire_type is not teammatereview %&amp;gt;&lt;br /&gt;
                            &amp;lt;td&amp;gt;Review &amp;lt;%=index + 1%&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
                          &amp;lt;% else %&amp;gt;&lt;br /&gt;
                            &amp;lt;td&amp;gt;&lt;br /&gt;
                              &amp;lt;% reviewer_id = row.score_row[index].reviewer_id %&amp;gt;&lt;br /&gt;
                              &amp;lt;% fullname = Participant.find_by(id: reviewer_id).fullname(session[:ip]) %&amp;gt;&lt;br /&gt;
                              Review by &amp;lt;%= fullname %&amp;gt;&lt;br /&gt;
                            &amp;lt;/td&amp;gt;&lt;br /&gt;
                          &amp;lt;% end%&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
====G. In spec/controllers/grades_controller_spec.rb:====&lt;br /&gt;
&lt;br /&gt;
'''G.1 '''&lt;br /&gt;
&lt;br /&gt;
Old code&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
before(:each) do&lt;br /&gt;
  allow(AssignmentParticipant).to receive(:find).with('1').and_return(participant)&lt;br /&gt;
  allow(participant).to receive(:team).and_return(team)&lt;br /&gt;
  stub_current_user(instructor, instructor.role.name, instructor.role)&lt;br /&gt;
  allow(Assignment).to receive(:find).with('1').and_return(assignment)&lt;br /&gt;
@@ -91,29 +90,106 @@&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
New code&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
before(:each) do&lt;br /&gt;
  allow(participant).to receive(:team).and_return(team)&lt;br /&gt;
  stub_current_user(instructor, instructor.role.name, instructor.role)&lt;br /&gt;
  allow(Assignment).to receive(:find).with('1').and_return(assignment)&lt;br /&gt;
@@ -91,29 +90,106 @@&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''G.2 '''Remove xdescribe '#view_team' and change describe '#view_team' as follows.&lt;br /&gt;
&lt;br /&gt;
Old code&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
describe '#view_team' do&lt;br /&gt;
render_views&lt;br /&gt;
context 'when view_team page is viewed by a student who is also a TA for another course' do&lt;br /&gt;
  it 'renders grades#view_team page' do&lt;br /&gt;
    allow(participant).to receive(:team).and_return(team)&lt;br /&gt;
    allow(AssignmentQuestionnaire).to receive(:find_by).with(assignment_id: 1, questionnaire_id: 1).and_return(assignment_questionnaire)&lt;br /&gt;
    allow(AssignmentQuestionnaire).to receive(:where).with(any_args).and_return([assignment_questionnaire])&lt;br /&gt;
    allow(assignment).to receive(:late_policy_id).and_return(false)&lt;br /&gt;
    allow(assignment).to receive(:calculate_penalty).and_return(false)&lt;br /&gt;
    allow(assignment).to receive(:compute_total_score).with(any_args).and_return(100)&lt;br /&gt;
    allow(review_questionnaire).to receive(:get_assessments_round_for).with(participant, 1).and_return([review_response])&lt;br /&gt;
    allow(Answer).to receive(:compute_scores).with([review_response], [question]).and_return(max: 95, min: 88, avg: 90)&lt;br /&gt;
    params = {id: 1}&lt;br /&gt;
    allow(TaMapping).to receive(:exists?).with(ta_id: 1, course_id: 1).and_return(true)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
New code&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
describe '#view_team' do&lt;br /&gt;
render_views&lt;br /&gt;
&lt;br /&gt;
# All stubs and factories are instantiated within this scope so as to not &lt;br /&gt;
# clash with other broken test.&lt;br /&gt;
# The names of the factories created for testing view_team&lt;br /&gt;
# have `_vt` suffix ```where necessary``` to differentiate them from &lt;br /&gt;
# the above declared factories&lt;br /&gt;
&lt;br /&gt;
let(:student1_vt) { create(:student, name: &amp;quot;barry&amp;quot;, id: 12) }&lt;br /&gt;
let(:student2_vt) { create(:student, name: &amp;quot;iris&amp;quot;, id: 13) }&lt;br /&gt;
&lt;br /&gt;
let(:tm_questionnaire) {&lt;br /&gt;
  build(&lt;br /&gt;
    :teammate_review_questionnaire,&lt;br /&gt;
    id: 12,&lt;br /&gt;
    questions: [question],&lt;br /&gt;
    max_question_score: 5&lt;br /&gt;
  )&lt;br /&gt;
}&lt;br /&gt;
let(:assignment_vt) {&lt;br /&gt;
  create(:assignment, id: 6, max_team_size: 2,&lt;br /&gt;
  questionnaires: [tm_questionnaire])&lt;br /&gt;
}&lt;br /&gt;
let(:assignment_questionnaire_vt) {&lt;br /&gt;
  create(:tm_assignment_questionnaire, id: 12, used_in_round: nil,&lt;br /&gt;
  assignment: assignment_vt, questionnaire: tm_questionnaire) }&lt;br /&gt;
let(:team_vt) { create(:assignment_team, id: 12,&lt;br /&gt;
assignment: assignment_vt) }&lt;br /&gt;
let(:participant_vt) { create(:participant, id: 12,&lt;br /&gt;
  assignment: assignment_vt, user_id: student1_vt.id) }&lt;br /&gt;
let(:participant2_vt) { create(:participant, id: 13,&lt;br /&gt;
  assignment: assignment_vt, user_id: student2_vt.id) }&lt;br /&gt;
&lt;br /&gt;
before(:each) do&lt;br /&gt;
  # Need to stub this method so the factory instance with&lt;br /&gt;
  # the stubbed :team method is returned by :find&lt;br /&gt;
  # instead of a separate instance with the same data&lt;br /&gt;
  allow(AssignmentParticipant)&lt;br /&gt;
    .to receive(:find)&lt;br /&gt;
    .with(participant_vt.id.to_s)&lt;br /&gt;
    .and_return(participant_vt)&lt;br /&gt;
  allow(participant_vt).to receive(:team).and_return(team_vt)&lt;br /&gt;
  allow(team_vt).to receive(:participants).and_return([participant_vt, participant2_vt])&lt;br /&gt;
  allow(AssignmentQuestionnaire)&lt;br /&gt;
    .to receive(:find_by)&lt;br /&gt;
    .with(assignment_id: assignment_vt.id, questionnaire_id: tm_questionnaire.id)&lt;br /&gt;
    .and_return(assignment_questionnaire_vt)&lt;br /&gt;
  allow(AssignmentQuestionnaire)&lt;br /&gt;
    .to receive(:find_by)&lt;br /&gt;
    .with(assignment_id: assignment.id, questionnaire_id: review_questionnaire.id)&lt;br /&gt;
    .and_return(assignment_questionnaire_vt)&lt;br /&gt;
  allow(AssignmentQuestionnaire)&lt;br /&gt;
    .to receive(:where)&lt;br /&gt;
    .with(any_args)&lt;br /&gt;
    .and_return([assignment_questionnaire_vt])&lt;br /&gt;
  allow(assignment_vt)&lt;br /&gt;
    .to receive(:late_policy_id)&lt;br /&gt;
    .and_return(false)&lt;br /&gt;
  allow(assignment_vt)&lt;br /&gt;
    .to receive(:calculate_penalty)&lt;br /&gt;
    .and_return(false)&lt;br /&gt;
  allow(assignment_vt)&lt;br /&gt;
    .to receive(:compute_total_score)&lt;br /&gt;
    .with(any_args)&lt;br /&gt;
    .and_return(100)&lt;br /&gt;
  allow(review_questionnaire).to receive(:get_assessments_round_for).with(participant, 1).and_return([review_response])&lt;br /&gt;
  allow(Answer).to receive(:compute_scores).with([review_response], [question]).and_return(max: 95, min: 88, avg: 90)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
 it 'renders grades#view_team page' do&lt;br /&gt;
  params = {id: participant_vt.id}&lt;br /&gt;
  get :view_team, params&lt;br /&gt;
  expect(response).to render_template(:view_team)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
context 'when view_team page is opened by student' do&lt;br /&gt;
  it 'dropdown is not rendered' do&lt;br /&gt;
    session = { user: student1_vt }&lt;br /&gt;
    params = {id: participant_vt.id}&lt;br /&gt;
    stub_current_user(student1_vt, student1_vt.role.name, student1_vt.role)&lt;br /&gt;
    get :view_team, params&lt;br /&gt;
    expect(response.body).to_not have_selector('select')&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
context 'when view_team page is opened by instructor' do&lt;br /&gt;
  it 'dropdown is rendered' do&lt;br /&gt;
    session = { user: instructor }&lt;br /&gt;
    params = {id: participant_vt.id}&lt;br /&gt;
    get :view_team, params&lt;br /&gt;
    expect(response.body).to have_selector('select')&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
context 'when view_team page is viewed by a student who is also a TA for another course' do&lt;br /&gt;
  it 'renders grades#view_team page' do&lt;br /&gt;
    params = { id: participant_vt.id }&lt;br /&gt;
    allow(TaMapping).to receive(:exists?).with(ta_id: participant_vt.user_id, course_id: 1).and_return(true)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
====H. In spec/factories/factories.rb:====&lt;br /&gt;
&lt;br /&gt;
'''H.1 '''Add the following factory:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
factory :teammate_review_questionnaire, class: TeammateReviewQuestionnaire do&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''H.2 '''Add another factory&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
factory :tm_assignment_questionnaire, class: AssignmentQuestionnaire do&lt;br /&gt;
  user_id 1&lt;br /&gt;
  questionnaire { association(:teammate_review_questionnaire) }&lt;br /&gt;
  questionnaire_weight 100&lt;br /&gt;
  used_in_round nil&lt;br /&gt;
  topic_id nil&lt;br /&gt;
  dropdown 1&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Summary of file changes ===&lt;br /&gt;
&lt;br /&gt;
The following files are modified:&lt;br /&gt;
&lt;br /&gt;
1. app/controllers/grades_controller.rb - Controller file which changed how the view model is populated&lt;br /&gt;
&lt;br /&gt;
2. app/views/grades/view_team.html.erb - View file, which  conditionally rendered the teammate name, for a teammate review heatgrid&lt;br /&gt;
&lt;br /&gt;
3. spec/controllers/grades_controller_spec.rb - For tests verifying the proposed changes&lt;br /&gt;
&lt;br /&gt;
4. app/models/vm_question_response.rb - To modify the view-model so it can tell us the name of the person being reviewed for the current heatgrid&lt;br /&gt;
&lt;br /&gt;
5. app/models/vm_question_response_score_cell.rb - &lt;br /&gt;
&lt;br /&gt;
6. app/assets/stylesheets/grades.scss - &lt;br /&gt;
&lt;br /&gt;
7. app/views/grades/_add_icon_to_name.html.erb - &lt;br /&gt;
&lt;br /&gt;
8. spec/factories/factories.rb -&lt;br /&gt;
&lt;br /&gt;
== Design Patterns ==&lt;br /&gt;
&lt;br /&gt;
Existing code does not use any design patterns, apart from if-else. It uses if-else conditional statements to check what type of questionnaire is present in the viewmodel `VmQuestionResponse`, and based on that, it renders the appropriate content.&lt;br /&gt;
&lt;br /&gt;
We decided to continue with this approach since to change the present coding style, there were required many changes (refactoring) to many files which were out of the scope of the present project. To complete the project in the assigned time, we followed the if-else approach.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== User Stories ==&lt;br /&gt;
&lt;br /&gt;
1. As an instructor, I can view what reviews one teammate has given to other teammates.&lt;br /&gt;
&lt;br /&gt;
2. As a student, I can view what reviews my teammates have given to me.&lt;br /&gt;
&lt;br /&gt;
3. As an instructor, I can select if a student's reviews are anonymously shown to their teammates.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Testing ==&lt;br /&gt;
'''CURRENT STATUS'''&lt;br /&gt;
&lt;br /&gt;
1. Presently, the tests only cover if the view_team is page is rendered when it is asked for. This can be seen in the following link: &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''OUR PROPOSAL'''&lt;br /&gt;
&lt;br /&gt;
- When show_team is set as false by the professor, the student should not be able to see his scores.&lt;br /&gt;
&lt;br /&gt;
- When show_team is set as true by the professor, the student should be able to see his.&lt;br /&gt;
&lt;br /&gt;
- An instructor can select which student's scores he/she wants to see. If no student's name is selected then the professor can see the scores of all the students.&lt;br /&gt;
- The instructor can decide whether to show the names of the reviewer to the reviewer in teammate reviews, by selecting a checkbox for the same.&lt;br /&gt;
[[File:Untitled Diagram.drawio.png|border|center|alt=New UI for students|New UI for students ]]&lt;br /&gt;
&lt;br /&gt;
==References==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;https://expertiza.ncsu.edu/&amp;lt;/p&amp;gt;&lt;/div&gt;</summary>
		<author><name>Vdeshmu</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2021_-_E2165._Fix_teammate-review_view&amp;diff=141738</id>
		<title>CSC/ECE 517 Fall 2021 - E2165. Fix teammate-review view</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2021_-_E2165._Fix_teammate-review_view&amp;diff=141738"/>
		<updated>2021-11-28T17:57:27Z</updated>

		<summary type="html">&lt;p&gt;Vdeshmu: /* C. In app/models/vm_question_response.rb: */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Team Introduction ==&lt;br /&gt;
&lt;br /&gt;
Dr. Edward Gehringer (instructor), Parimal Mehta (mentor)&lt;br /&gt;
&lt;br /&gt;
1. Anjali Garg (unity ID : agarg25)&lt;br /&gt;
&lt;br /&gt;
2. Arvasu Chikara (unity ID: achikar2)&lt;br /&gt;
&lt;br /&gt;
3. Lalit Bangad (unity ID: llbangad)&lt;br /&gt;
&lt;br /&gt;
4. Vinay Deshmukh (unity ID: vdeshmu)&lt;br /&gt;
&lt;br /&gt;
== Problems to be addressed ==&lt;br /&gt;
&lt;br /&gt;
After a project is submitted and reviewed, both the team members (students) and instructors should be able to view the teammate reviews. Students should be able to view the reviews by going to a particular assignment's -&amp;gt; your scores, at the bottom of the page. An instructor can view the teammate reviews by going to assignments -&amp;gt; assignment -&amp;gt; particular team's submission -&amp;gt; view submission -&amp;gt; assign grades -&amp;gt; view scores. &lt;br /&gt;
&lt;br /&gt;
In the case of the instructor, a single heat grid is shown whereas in the case of a team member, we cant view the scores. In the heat grid, it is not clear if the scores visible are for the reviews that the student has *written* for their teammates or the scores that the student has *received* from their teammates. Additionally, for instructors can choose from a list of the students on the team, but they have no way to tell whether the heat grid shows the reviews done *by* that student or done *for* that student.&lt;br /&gt;
&lt;br /&gt;
== Methodology Overview ==&lt;br /&gt;
&lt;br /&gt;
We have divided our work in the following tasks to address the above problems:&lt;br /&gt;
&lt;br /&gt;
1. Distinguish reviews done for a student by rendering separates heatgrids for each student&lt;br /&gt;
&lt;br /&gt;
2. For instructors, the table will have sections based on the students&lt;br /&gt;
&lt;br /&gt;
3. Include a checkbox on the edit assignment page that enables/disables visibility of heat grid to students&lt;br /&gt;
&lt;br /&gt;
4. Fix the average column for a table (which breaks for some reviews)&lt;br /&gt;
&lt;br /&gt;
5. Show a composite score derived from all reviews.  Make this code generalized, so other kinds of heat grid views could use it.&lt;br /&gt;
&lt;br /&gt;
6. Changes should work even in an anonymized view&lt;br /&gt;
&lt;br /&gt;
== Motivations ==&lt;br /&gt;
&lt;br /&gt;
1. Enable users to clearly tell which reviews are done by them, and which reviews are done for them.&lt;br /&gt;
&lt;br /&gt;
2. Code should be generic so it can be used for different types of heat grids as well.&lt;br /&gt;
&lt;br /&gt;
== Control Flow to access the concerned screens ==&lt;br /&gt;
'''1. For instructor (Log in as an instructor):-'''&lt;br /&gt;
&lt;br /&gt;
Screen after logging in by the instructor&lt;br /&gt;
[[File:ss1.png |border|1000px|center]]&lt;br /&gt;
Got to assignments on the Manage menu &lt;br /&gt;
[[File:ss2.png |border|1000px|center]]&lt;br /&gt;
Go to assignments&lt;br /&gt;
[[File:ss3.png |border|1000px|center]]&lt;br /&gt;
Go to submissions for any assignment&lt;br /&gt;
[[File:ss4a.png |border|1000px|center]]&lt;br /&gt;
Go to Assign Grade&lt;br /&gt;
[[File:ss5a.png |border|1000px|center]]&lt;br /&gt;
You will land on the page where the changes are made and can be reviewed&lt;br /&gt;
[[File:ss7a.png |border|1000px|center]]&lt;br /&gt;
&lt;br /&gt;
'''2. Student:- (Logged in as an instructor)'''&lt;br /&gt;
&lt;br /&gt;
After landing on the assignments page, select any student from an assignment as shown below&lt;br /&gt;
[[File:ss6a.png |border|1000px|center]]&lt;br /&gt;
Go to/Select any assignment&lt;br /&gt;
[[File:ss9a.png |border|1000px|center]]&lt;br /&gt;
Go to your scores&lt;br /&gt;
[[File:ss10a.png |border|1000px|center]]&lt;br /&gt;
You will land on the page where the changes are made and can be reviewed&lt;br /&gt;
[[File:ss11a.png |border|1000px|center]]&lt;br /&gt;
&lt;br /&gt;
== Old Status of the application ==&lt;br /&gt;
&lt;br /&gt;
'''1. Instructor's view of teammate review''': This is the current screen given to the instructor. Here we see that the instructor can not determine who has given which review to which student in a team.&lt;br /&gt;
&lt;br /&gt;
[[File:Instructor-view-1.png|border| 700px |center|alt=The proposed expanded student display.|The proposed expanded student display.]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''2. Student's view of teammate review''': Currently, a student is not able to see what grades were given by their teammates. We need to implement that functionality so that the student is able to view those grades.&lt;br /&gt;
&lt;br /&gt;
[[File:Student-view-2.png|border| 700px |center|alt=The current instructor view.|The current review display for instructors.]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''3. Error in existing UI for student''': In the existing UI for a student, the highlighted block should not be rendered. This part of the screen is meant for the instructors/TAs. &lt;br /&gt;
&lt;br /&gt;
[[File:Wrong render for student.png|border|700px|center|alt=Existing UI for student|Existing UI for student.]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Proposed changes ==&lt;br /&gt;
&lt;br /&gt;
''' 1) Proposed UI for instructor ''': The instructor is able to see the score for all teammates. In the existing code, only one teammate's scores are being shown. But, we are planning to change the way the (VmQuestionResponse array is populated)[https://github.com/expertiza/expertiza/blob/master/app/controllers/grades_controller.rb#L114], so that the scores for all teammates are appended to it so it correctly shows what should have already been shown in this screen for the instructor.&lt;br /&gt;
&lt;br /&gt;
[[File:Proposed_screen.png|border|700px|center|alt=Proposed UI for instructor|Proposed UI for instructor.]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Note: When a student visits this screen, they will only be shown the reviews received by them, assuming the instructor has allowed visibility of teammate reviews to students.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
''' 2) Show detailed review for a particular question''': The instructor can see detailed review given to a student by their teammates by clicking on a particular question number in the table.&lt;br /&gt;
&lt;br /&gt;
[[File:ss12a.png|border|700px|center|alt=New UI for students|New UI for students ]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
''' 3) Show teammate review to student UI ''': The existing code doesn't render a student's teammate review scores at all. We are planning to render the scores to a student (as shown below) when they visit this screen. However, the visibility of this screen is contingent on whether the instructor has allowed visibility of the teammate review screen to students. If the instructor has disabled this feature, then the heatgrid will not be displayed at all.&lt;br /&gt;
&lt;br /&gt;
[[File:UI_for_student.png|border|700px|center|alt=New UI for students|New UI for students ]]&lt;br /&gt;
&lt;br /&gt;
== Models used / Explanation of fixes ==&lt;br /&gt;
&lt;br /&gt;
The below diagram illustrates the proposed code change for showing all team members with the teammate review data to an instructor. The existing code only iterated on the `Participant` whose ID is present in the URL of the page. To fix this, we will iterate over all teammates of the given participant so that all teammate reviews for all team members are shown to the instructor.&lt;br /&gt;
&lt;br /&gt;
[[File:Logic e2165.png|border|center|alt=Flow diagram of proposed changes for showing team review data to instructor]]&lt;br /&gt;
&lt;br /&gt;
===Changes made to the code are shown below. Every change is shown and explained separately===&lt;br /&gt;
&lt;br /&gt;
====A. Added the following to app/assets/stylesheets/grades.scss:====&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    .teammate_table.hidden {&lt;br /&gt;
      display: none;&lt;br /&gt;
      }&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
====B. In app/controllers/grades_controller.rb: ====&lt;br /&gt;
&lt;br /&gt;
'''B.1:'''&lt;br /&gt;
&lt;br /&gt;
Old code: The existing code does not differentiate when adding a view model for the TeammateReview questionnaire&lt;br /&gt;
  questionnaires.each do |questionnaire|&lt;br /&gt;
     ...&lt;br /&gt;
     @vmlist &amp;lt;&amp;lt; populate_view_model(questionnaire)&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
New code: Since the current page URL contains an ID for the participant, from which we get an assignment, which gives us a list of questionnaires, we need to iterate all participants for a `TeammateReveiwQuestionnaire` questionnaire, so that we get the heatgrid view models for all members of a team.&lt;br /&gt;
  questionnaires.each do |questionnaire|&lt;br /&gt;
     ...&lt;br /&gt;
     if questionnaire.type == &amp;quot;TeammateReviewQuestionnaire&amp;quot;&lt;br /&gt;
        # as teammate review will be different for each participant&lt;br /&gt;
        # we need to create a separate table for each teammate&lt;br /&gt;
        @participant.team.participants.each do |team_participant|&lt;br /&gt;
          @vmlist &amp;lt;&amp;lt; populate_view_model(team_participant, questionnaire, @team)&lt;br /&gt;
        end&lt;br /&gt;
      else&lt;br /&gt;
        # only one participant needs iterating, as apart from teammatereview&lt;br /&gt;
        # all other reviews are at &amp;quot;team&amp;quot; level&lt;br /&gt;
        @vmlist &amp;lt;&amp;lt; populate_view_model(@participant, questionnaire, @team)&lt;br /&gt;
      end&lt;br /&gt;
   end&lt;br /&gt;
&lt;br /&gt;
'''B.2: '''&lt;br /&gt;
&lt;br /&gt;
Old code: This code uses @participant as an instance variable, but this structure will not work as we need to call this ViewModel with multiple participants when iterating for a teammate review questionnaire.&lt;br /&gt;
    def populate_view_model(questionnaire)&lt;br /&gt;
      vm = VmQuestionResponse.new(questionnaire, @assignment, @round)&lt;br /&gt;
      vmquestions = questionnaire.questions&lt;br /&gt;
      vm.add_questions(vmquestions)&lt;br /&gt;
      vm.add_team_members(@team)&lt;br /&gt;
      vm.add_reviews(@participant, @team, @assignment.vary_by_round)&lt;br /&gt;
      vm.number_of_comments_greater_than_10_words&lt;br /&gt;
      vm &lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
New code: We need to call this function with a separate participant in each invocation due to our change for TeammateReviewQuestionnaire, hence it makes sense to make `participant` as an argument to this function. Similarly, as `team` is a closely related model to `participant`, we are passing it as an argument, to keep this function as &amp;quot;pure&amp;quot; as possible.&lt;br /&gt;
    def populate_view_model(participant, questionnaire, team)&lt;br /&gt;
      ...&lt;br /&gt;
      vm.add_team_members(team)&lt;br /&gt;
      vm.add_reviews(participant, team, @assignment.vary_by_round)&lt;br /&gt;
      ...&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
====C. In app/models/vm_question_response.rb:====&lt;br /&gt;
&lt;br /&gt;
'''C.1: '''Added the reviewee_id method: Created a helper method within the VmQuestionReponse model to retrieve the `reviewee_id` for a heatgrid&lt;br /&gt;
&lt;br /&gt;
    def reviewee_id&lt;br /&gt;
      @participant_who_is_reviewee.user_id&lt;br /&gt;
    end &lt;br /&gt;
&lt;br /&gt;
'''C.2: '''Added the reviewee_name method: Created a helper method within the VmQuestionReponse model to retrieve the name of the student who is being reviewed for a heatgrid. This method uses the functionality to anonymize the name when we are in anonymized view.&lt;br /&gt;
&lt;br /&gt;
    def reviewee_name(ip_address = nil)&lt;br /&gt;
      part = @participant_who_is_reviewee&lt;br /&gt;
      User.find_by(id: part.user_id).fullname(ip_address)&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
'''C.3: '''&lt;br /&gt;
&lt;br /&gt;
Old code: Does not keep track of the student being reviewed&lt;br /&gt;
    elsif @questionnaire_type == &amp;quot;TeammateReviewQuestionnaire&amp;quot;&lt;br /&gt;
      reviews = participant.teammate_reviews&lt;br /&gt;
      reviews.each do |review|&lt;br /&gt;
        review_mapping = TeammateReviewResponseMap.find_by(id: review.map_id)&lt;br /&gt;
        participant = Participant.find(review_mapping.reviewer_id)&lt;br /&gt;
&lt;br /&gt;
New code: Add an instance variable to keep track of the student who is being reviewed in this VmQuestionReponse&lt;br /&gt;
    elsif @questionnaire_type == &amp;quot;TeammateReviewQuestionnaire&amp;quot;&lt;br /&gt;
      reviews = participant.teammate_reviews&lt;br /&gt;
      @participant_who_is_reviewee = participant&lt;br /&gt;
      reviews.each do |review|&lt;br /&gt;
        review_mapping = TeammateReviewResponseMap.find_by(id: review.map_id)&lt;br /&gt;
        participant = Participant.find(review_mapping.reviewer_id)&lt;br /&gt;
&lt;br /&gt;
'''C.4: '''&lt;br /&gt;
&lt;br /&gt;
Old code: Existing VmQuestionReponseScoreCell keeps no information about the reviewer, as it only stores the answer score&lt;br /&gt;
    row.score_row.push(VmQuestionResponseScoreCell.new(answer.answer, color_code, answer.comments, vm_tag_prompts))&lt;br /&gt;
&lt;br /&gt;
New code: Keep track of the response ID, so that we can retrieve the user ID for the reviewer in the model to use in the view file.&lt;br /&gt;
    &lt;br /&gt;
    row.score_row.push(VmQuestionResponseScoreCell.new(answer.answer, color_code, answer.comments, vm_tag_prompts, answer.response_id))&lt;br /&gt;
&lt;br /&gt;
====D. In app/models/vm_question_response_score_cell.rb:====&lt;br /&gt;
&lt;br /&gt;
'''D.1: '''In the method initialize of class VmQuestionResponseScoreCell&lt;br /&gt;
&lt;br /&gt;
Old code&lt;br /&gt;
    def initialize(score_value, color_code, comments, vmprompts = nil)&lt;br /&gt;
      @score_value = score_value&lt;br /&gt;
      @color_code = color_code&lt;br /&gt;
      @comment = comments&lt;br /&gt;
      @vm_prompts = vmprompts&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
New code&lt;br /&gt;
&lt;br /&gt;
    def initialize(score_value, color_code, comments, vmprompts = nil, response_id)&lt;br /&gt;
      @score_value = score_value&lt;br /&gt;
      @color_code = color_code&lt;br /&gt;
      @comment = comments&lt;br /&gt;
      @vm_prompts = vmprompts&lt;br /&gt;
      @response_id = response_id&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
'''D.2: '''Added a method reviewer_id to the class VmQuestionResponseScoreCell&lt;br /&gt;
&lt;br /&gt;
    def reviewer_id&lt;br /&gt;
      resp = Response.find(@response_id)&lt;br /&gt;
      map = ResponseMap.find(resp.map_id)&lt;br /&gt;
      map.reviewer_id&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
====E. In app/views/grades/_add_icon_to_name.html.erb:====&lt;br /&gt;
&lt;br /&gt;
'''E.1 '''Added the following code to the file:&lt;br /&gt;
&lt;br /&gt;
    &amp;lt;%# Determine the content of the reviewed by text %&amp;gt;&lt;br /&gt;
    &amp;lt;% review_text = &amp;quot;&amp;quot; %&amp;gt;&lt;br /&gt;
    &amp;lt;% if @current_role_name.eql?'Student' or questionnaire_type != &amp;quot;TeammateReviewQuestionnaire&amp;quot; %&amp;gt;&lt;br /&gt;
      &amp;lt;%# Use Review {{index}} format for student view, and when questionnaire_type is not teammatereview %&amp;gt;&lt;br /&gt;
      &amp;lt;% review_text = &amp;quot;Review #{i + 1}&amp;quot; %&amp;gt;&lt;br /&gt;
    &amp;lt;% else %&amp;gt;&lt;br /&gt;
      &amp;lt;% resp = Response.find(review.id) %&amp;gt;&lt;br /&gt;
      &amp;lt;% map = ResponseMap.find(resp.map_id) %&amp;gt;&lt;br /&gt;
      &amp;lt;% reviewer_id = map.reviewer_id %&amp;gt;&lt;br /&gt;
      &amp;lt;% fullname = Participant.find_by(id: reviewer_id).fullname(session[:ip]) %&amp;gt;&lt;br /&gt;
      &amp;lt;% review_text = &amp;quot;Review by #{fullname}&amp;quot; %&amp;gt;&lt;br /&gt;
    &amp;lt;% end%&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''E.2: '''&lt;br /&gt;
&lt;br /&gt;
Old code&lt;br /&gt;
&lt;br /&gt;
    &amp;lt;% if review.done_by_staff_participant? %&amp;gt;&lt;br /&gt;
      &amp;lt;th class=&amp;quot;sorter-false&amp;quot;&amp;gt; &amp;lt;img data-toggle=&amp;quot;tooltip&amp;quot; data-placement=&amp;quot;right&amp;quot; title=&amp;quot;Icon indicates this review was done by course staff&amp;quot; class=&amp;quot;img_icon&amp;quot; src=&amp;quot;/assets/staff.png&amp;quot;&amp;gt; &amp;lt;a target=&amp;quot;_blank&amp;quot; href=&amp;quot;../response/view?id=&amp;lt;%= review.id.to_s %&amp;gt;&amp;quot;  data-toggle=&amp;quot;tooltip&amp;quot; data-placement=&amp;quot;right&amp;quot; title=&amp;quot;Click to see details&amp;quot;&amp;gt;&amp;lt;%= &amp;quot;Review &amp;quot; + i.to_s  %&amp;gt;&amp;lt;/a&amp;gt; &amp;lt;/th&amp;gt;&lt;br /&gt;
    &amp;lt;% else %&amp;gt;&lt;br /&gt;
      &amp;lt;th class=&amp;quot;sorter-false&amp;quot;&amp;gt; &amp;lt;a target=&amp;quot;_blank&amp;quot; href=&amp;quot;../response/view?id=&amp;lt;%= review.id.to_s %&amp;gt;&amp;quot;  data-toggle=&amp;quot;tooltip&amp;quot; data-placement=&amp;quot;right&amp;quot; title=&amp;quot;Click to see details&amp;quot;&amp;gt;&amp;lt;%= &amp;quot;Review &amp;quot; + i.to_s %&amp;gt;&amp;lt;/a&amp;gt;  &amp;lt;/th&amp;gt;&lt;br /&gt;
    &amp;lt;% end %&amp;gt;&lt;br /&gt;
&lt;br /&gt;
New code&lt;br /&gt;
&lt;br /&gt;
    &amp;lt;% if review.done_by_staff_participant? %&amp;gt;&lt;br /&gt;
    &amp;lt;th class=&amp;quot;sorter-false&amp;quot;&amp;gt;&lt;br /&gt;
      &amp;lt;img&lt;br /&gt;
      data-toggle=&amp;quot;tooltip&amp;quot;&lt;br /&gt;
      data-placement=&amp;quot;right&amp;quot;&lt;br /&gt;
      title=&amp;quot;Icon indicates this review was done by course staff&amp;quot; class=&amp;quot;img_icon&amp;quot;&lt;br /&gt;
      src=&amp;quot;/assets/staff.png&amp;quot;&lt;br /&gt;
      &amp;gt;&lt;br /&gt;
    &amp;lt;a&lt;br /&gt;
      target=&amp;quot;_blank&amp;quot;&lt;br /&gt;
      href=&amp;quot;../response/view?id=&amp;lt;%= review.id.to_s %&amp;gt;&amp;quot;&lt;br /&gt;
      data-toggle=&amp;quot;tooltip&amp;quot;&lt;br /&gt;
      data-placement=&amp;quot;right&amp;quot;&lt;br /&gt;
      title=&amp;quot;Click to see details&amp;quot;&amp;gt;&lt;br /&gt;
      &amp;lt;%= review_text %&amp;gt;&lt;br /&gt;
    &amp;lt;/a&amp;gt;&lt;br /&gt;
    &amp;lt;/th&amp;gt;&lt;br /&gt;
    &amp;lt;% else %&amp;gt;&lt;br /&gt;
    &amp;lt;th class=&amp;quot;sorter-false&amp;quot;&amp;gt;&lt;br /&gt;
        &amp;lt;a&lt;br /&gt;
            target=&amp;quot;_blank&amp;quot; &lt;br /&gt;
            href=&amp;quot;../response/view?id=&amp;lt;%= review.id.to_s %&amp;gt;&amp;quot;  &lt;br /&gt;
            data-toggle=&amp;quot;tooltip&amp;quot;&lt;br /&gt;
            data-placement=&amp;quot;right&amp;quot;&lt;br /&gt;
            title=&amp;quot;Click to see details&amp;quot;&lt;br /&gt;
        &amp;gt;&lt;br /&gt;
        &amp;lt;%= review_text %&amp;gt;&lt;br /&gt;
        &amp;lt;/a&amp;gt;&lt;br /&gt;
    &amp;lt;/th&amp;gt;&lt;br /&gt;
    &amp;lt;% end %&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
====F.In app/views/grades/view_team.html.erb:====&lt;br /&gt;
&lt;br /&gt;
'''F.1: '''Added function teammateSelectOnChange:&lt;br /&gt;
    &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  function teammateSelectOnChange(selectNode) {&lt;br /&gt;
      const revieweeIdToShow= selectNode.value;&lt;br /&gt;
      const tableSelector = &amp;quot;.teammate_table&amp;quot;;&lt;br /&gt;
      if(revieweeIdToShow == &amp;quot;all&amp;quot;) {&lt;br /&gt;
        document.querySelectorAll(tableSelector).forEach((tableNode) =&amp;gt; {&lt;br /&gt;
          tableNode.classList.remove(&amp;quot;hidden&amp;quot;);&lt;br /&gt;
        });&lt;br /&gt;
        return;&lt;br /&gt;
      }&lt;br /&gt;
&lt;br /&gt;
  document.querySelectorAll(tableSelector).forEach((tableNode) =&amp;gt; {&lt;br /&gt;
    const tableRevieweeId = tableNode.getAttribute('data-reviewee_id');&lt;br /&gt;
    if(tableRevieweeId == revieweeIdToShow) {&lt;br /&gt;
      tableNode.classList.remove(&amp;quot;hidden&amp;quot;);&lt;br /&gt;
    } else {&lt;br /&gt;
      tableNode.classList.add(&amp;quot;hidden&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
    });&lt;br /&gt;
  }&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''F.2: '''&lt;br /&gt;
&lt;br /&gt;
Old code&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    &amp;lt;% @vmlist.each do |vm| %&amp;gt;&lt;br /&gt;
        &amp;lt;% if (vm.questionnaire_display_type == &amp;quot;Metareview&amp;quot; or vm.questionnaire_display_type == &amp;quot;Author Feedback&amp;quot; or vm.questionnaire_display_type == &amp;quot;Teammate Review&amp;quot;) and @current_role_name.eql?'Student' %&amp;gt;&lt;br /&gt;
        &amp;lt;% else %&amp;gt;&lt;br /&gt;
        &amp;lt;% if vm.list_of_reviewers.length &amp;gt; 0 %&amp;gt;&lt;br /&gt;
&lt;br /&gt;
​      &amp;lt;!-- display the list of questions for this questionnaire --&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  @@ -87,6 +131,8 @@&lt;br /&gt;
              &amp;lt;h4 style=&amp;quot;display:inline-block;&amp;quot;&amp;gt;&amp;lt;%= vm.questionnaire_display_type %&amp;gt;&lt;br /&gt;
                &amp;lt;% if vm.questionnaire_type == &amp;quot;ReviewQuestionnaire&amp;quot; %&amp;gt;&lt;br /&gt;
                    (Round: &amp;lt;%= vm.round.to_s  %&amp;gt; of &amp;lt;%= vm.rounds.to_s  %&amp;gt;)&lt;br /&gt;
        &amp;lt;%end %&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
New code&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;%# This boolean is used to render a dropdown just before the first teammate review heat grid %&amp;gt;&lt;br /&gt;
&amp;lt;% first_teammate_review_appeared = false %&amp;gt;&lt;br /&gt;
&amp;lt;% @vmlist.each do |vm| %&amp;gt;&lt;br /&gt;
    &amp;lt;% if not @current_role_name.eql?'Student' and not first_teammate_review_appeared and vm.questionnaire_type == &amp;quot;TeammateReviewQuestionnaire&amp;quot; %&amp;gt;&lt;br /&gt;
      &amp;lt;div&amp;gt;&lt;br /&gt;
        &amp;lt;select onchange=&amp;quot;teammateSelectOnChange(this)&amp;quot;&amp;gt;&lt;br /&gt;
          &amp;lt;option value=&amp;quot;all&amp;quot;&amp;gt;All&amp;lt;/option&amp;gt;&lt;br /&gt;
          &amp;lt;% @vmlist.select { |tm_vm| tm_vm.questionnaire_type == &amp;quot;TeammateReviewQuestionnaire&amp;quot; }.each do |tm_vm| %&amp;gt;&lt;br /&gt;
            &amp;lt;option value=&amp;quot;&amp;lt;%= tm_vm.reviewee_id %&amp;gt;&amp;quot;&amp;gt;&lt;br /&gt;
              &amp;lt;%= tm_vm.reviewee_name(session[:ip]) %&amp;gt;&lt;br /&gt;
            &amp;lt;/option&amp;gt;&lt;br /&gt;
          &amp;lt;% end %&amp;gt;&lt;br /&gt;
        &amp;lt;/select&amp;gt;&lt;br /&gt;
      &amp;lt;/div&amp;gt;&lt;br /&gt;
      &amp;lt;% first_teammate_review_appeared = true %&amp;gt;&lt;br /&gt;
    &amp;lt;% end %&amp;gt;&lt;br /&gt;
    &amp;lt;% if (vm.questionnaire_display_type == &amp;quot;Metareview&amp;quot; or vm.questionnaire_display_type == &amp;quot;Author Feedback&amp;quot;) and @current_role_name.eql?'Student' %&amp;gt;&lt;br /&gt;
    &amp;lt;% elsif (vm.questionnaire_type == &amp;quot;TeammateReviewQuestionnaire&amp;quot; and @current_role_name.eql?'Student' and !@assignment.show_teammate_reviews)%&amp;gt;&lt;br /&gt;
    &amp;lt;% elsif (vm.questionnaire_type == &amp;quot;TeammateReviewQuestionnaire&amp;quot; and @current_role_name.eql?'Student' and @assignment.show_teammate_reviews and current_user.id != vm.reviewee_id )%&amp;gt;&lt;br /&gt;
    &amp;lt;% else %&amp;gt;&lt;br /&gt;
        &amp;lt;% if vm.questionnaire_type == &amp;quot;TeammateReviewQuestionnaire&amp;quot; %&amp;gt;&lt;br /&gt;
          &amp;lt;div class=&amp;quot;teammate_table&amp;quot; data-reviewee_id=&amp;quot;&amp;lt;%= vm.reviewee_id %&amp;gt;&amp;quot;&amp;gt;&lt;br /&gt;
        &amp;lt;% else %&amp;gt;&lt;br /&gt;
          &amp;lt;div&amp;gt;&lt;br /&gt;
        &amp;lt;% end %&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''F.3  '''&lt;br /&gt;
&lt;br /&gt;
Old code&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;!-- display the list of questions for this questionnaire --&amp;gt;&lt;br /&gt;
@@ -87,6 +131,8 @@&lt;br /&gt;
          &amp;lt;h4 style=&amp;quot;display:inline-block;&amp;quot;&amp;gt;&amp;lt;%= vm.questionnaire_display_type %&amp;gt;&lt;br /&gt;
            &amp;lt;% if vm.questionnaire_type == &amp;quot;ReviewQuestionnaire&amp;quot; %&amp;gt;&lt;br /&gt;
                (Round: &amp;lt;%= vm.round.to_s  %&amp;gt; of &amp;lt;%= vm.rounds.to_s  %&amp;gt;)&lt;br /&gt;
            &amp;lt;%end %&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
New code&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;!-- display the list of questions for this questionnaire --&amp;gt;&lt;br /&gt;
@@ -87,6 +131,8 @@&lt;br /&gt;
          &amp;lt;h4 style=&amp;quot;display:inline-block;&amp;quot;&amp;gt;&amp;lt;%= vm.questionnaire_display_type %&amp;gt;&lt;br /&gt;
            &amp;lt;% if vm.questionnaire_type == &amp;quot;ReviewQuestionnaire&amp;quot; %&amp;gt;&lt;br /&gt;
                (Round: &amp;lt;%= vm.round.to_s  %&amp;gt; of &amp;lt;%= vm.rounds.to_s  %&amp;gt;)&lt;br /&gt;
            &amp;lt;% elsif vm.questionnaire_type == &amp;quot;TeammateReviewQuestionnaire&amp;quot; %&amp;gt;&lt;br /&gt;
                (For: &amp;lt;%= vm.reviewee_name(session[:ip]) %&amp;gt;)&lt;br /&gt;
            &amp;lt;%end %&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''F.4 '''&lt;br /&gt;
&lt;br /&gt;
Old code&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;% vm.list_of_reviews.each do |review| %&amp;gt;&lt;br /&gt;
              &amp;lt;!-- instructors (or higher level users) see reviewer name, students see anonymized string --&amp;gt;&lt;br /&gt;
              &amp;lt;% if (['Student'].include? @current_role_name) &amp;amp;&amp;amp; @assignment.is_anonymous%&amp;gt;&lt;br /&gt;
                &amp;lt;%= render :partial =&amp;gt; 'add_icon_to_name', :locals =&amp;gt; {review: review, i: i} %&amp;gt;&lt;br /&gt;
              &amp;lt;% else %&amp;gt;&lt;br /&gt;
                  &amp;lt;% user_name = User.find(Participant.find(ResponseMap.find(Response.find(review.id).map_id).reviewer_id).user_id).fullname(session[:ip]).to_s %&amp;gt;&lt;br /&gt;
                &amp;lt;%= render :partial =&amp;gt; 'add_icon_to_name', :locals =&amp;gt; {review: review, i: i} %&amp;gt;&lt;br /&gt;
              &amp;lt;% end %&amp;gt;&lt;br /&gt;
              &amp;lt;% i += 1 %&amp;gt;&lt;br /&gt;
          &amp;lt;% end %&amp;gt;&lt;br /&gt;
&lt;br /&gt;
          &amp;lt;th class=&amp;quot;sorter-true&amp;quot; align=&amp;quot;right&amp;quot; &amp;gt;&lt;br /&gt;
            Avg&amp;lt;span&amp;gt;&amp;lt;/span&amp;gt;&lt;br /&gt;
          &amp;lt;/th&amp;gt;&lt;br /&gt;
          &amp;lt;th class=&amp;quot;sorter-false&amp;quot;&amp;gt;&lt;br /&gt;
            &amp;lt;span  data-toggle=&amp;quot;tooltip&amp;quot; data-placement=&amp;quot;right&amp;quot; title=&amp;quot;A count of comments, for the respective question, which have word count &amp;gt; 10. The purpose of this metric is to represent how many comments for the question are of a substantial length to provide quality feedback.&amp;quot;&amp;gt;metric-1&amp;lt;/span&amp;gt;&lt;br /&gt;
          &amp;lt;/th&amp;gt;&lt;br /&gt;
        &amp;lt;/tr&amp;gt;&lt;br /&gt;
        &amp;lt;/thead&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
New code&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;% vm.list_of_reviews.each do |review| %&amp;gt;&lt;br /&gt;
              &amp;lt;!-- instructors (or higher level users) see reviewer name, students see anonymized string --&amp;gt;&lt;br /&gt;
              &amp;lt;% if (['Student'].include? @current_role_name) &amp;amp;&amp;amp; @assignment.is_anonymous%&amp;gt;&lt;br /&gt;
                &amp;lt;%= render :partial =&amp;gt; 'add_icon_to_name', :locals =&amp;gt; {review: review, i: i, questionnaire_type: vm.questionnaire_type } %&amp;gt;&lt;br /&gt;
              &amp;lt;% else %&amp;gt;&lt;br /&gt;
                &amp;lt;% user_name = User.find(Participant.find(ResponseMap.find(Response.find(review.id).map_id).reviewer_id).user_id).fullname(session[:ip]).to_s %&amp;gt;&lt;br /&gt;
                &amp;lt;%= render :partial =&amp;gt; 'add_icon_to_name', :locals =&amp;gt; {review: review, i: i, questionnaire_type: vm.questionnaire_type } %&amp;gt;&lt;br /&gt;
              &amp;lt;% end %&amp;gt;&lt;br /&gt;
              &amp;lt;% i += 1 %&amp;gt;&lt;br /&gt;
          &amp;lt;% end %&amp;gt;&lt;br /&gt;
&lt;br /&gt;
          &amp;lt;th class=&amp;quot;sorter-true&amp;quot; align=&amp;quot;right&amp;quot; &amp;gt;&lt;br /&gt;
            Avg&amp;lt;span&amp;gt;&amp;lt;/span&amp;gt;&lt;br /&gt;
          &amp;lt;/th&amp;gt;&lt;br /&gt;
        &amp;lt;/tr&amp;gt;&lt;br /&gt;
        &amp;lt;/thead&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''F.5 '''&lt;br /&gt;
&lt;br /&gt;
Old code&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;% vm.list_of_rows.each do |row| %&amp;gt;&lt;br /&gt;
            &amp;lt;!-- notice the data-target. because we're toggling via looped code, we need to dynamically generate the identifier. --&amp;gt;&lt;br /&gt;
            &amp;lt;tr data-toggle=&amp;quot;collapse&amp;quot; class=&amp;quot;accordion-toggle&amp;quot; data-target=&amp;quot;#hid&amp;lt;%= row.question_id.to_s + vm.round.to_s %&amp;gt;&amp;quot;&amp;gt;&lt;br /&gt;
              &amp;lt;td class = 'cf' data-toggle=&amp;quot;tooltip&amp;quot; title=&amp;quot;&amp;lt;%= row.question_text %&amp;gt;&amp;quot;&amp;gt; &amp;lt;div style='float: left'&amp;gt;&amp;lt;%= j.to_s %&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;div style='float: right'&amp;gt; &amp;amp;#&amp;lt;%= type_and_max(row) %&amp;gt;;&amp;lt;/div&amp;gt;  &amp;lt;/td&amp;gt;&lt;br /&gt;
&lt;br /&gt;
              &amp;lt;!-- actual cells with scores and colored background. --&amp;gt;&lt;br /&gt;
              &amp;lt;% row.score_row.each do |score| %&amp;gt;&lt;br /&gt;
                  &amp;lt;% score_comment = score.comment.nil? ? '' : score.comment %&amp;gt; &amp;lt;!-- changing nil to null string to avoid Null Pointer Exception --&amp;gt;&lt;br /&gt;
                  &amp;lt;td class=&amp;quot;&amp;lt;%= score.color_code %&amp;gt;&amp;quot; align=&amp;quot;center&amp;quot; data-toggle=&amp;quot;tooltip&amp;quot; title=&amp;quot;&amp;lt;%= strip_tags(score.comment).html_safe%&amp;gt;&amp;quot;&amp;gt;&lt;br /&gt;
                    &amp;lt;span class=&amp;quot;&amp;lt;%=  underlined?(score) %&amp;gt;&amp;quot;&amp;gt;&amp;lt;%= score.score_value.to_s %&amp;gt;&amp;lt;/span&amp;gt;&lt;br /&gt;
                  &amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;% end %&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
New code&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;% vm.list_of_rows.each do |row| %&amp;gt;&lt;br /&gt;
            &amp;lt;% target_id = &amp;quot;hid__#{row.question_id}__#{vm.round}&amp;quot; %&amp;gt;&lt;br /&gt;
            &amp;lt;% if vm.questionnaire_type == &amp;quot;TeammateReviewQuestionnaire&amp;quot; %&amp;gt;&lt;br /&gt;
              &amp;lt;%# Since we render different heatgrids with the same questions for each&lt;br /&gt;
              teammember, we need to distinguish the ID, based on the user for whom,&lt;br /&gt;
              the reviews have been created. %&amp;gt;&lt;br /&gt;
              &amp;lt;% target_id += &amp;quot;__#{vm.reviewee_id}&amp;quot; %&amp;gt;&lt;br /&gt;
            &amp;lt;% end%&amp;gt;&lt;br /&gt;
&lt;br /&gt;
            &amp;lt;!-- notice the data-target. because we're toggling via looped code, we need to dynamically generate the identifier. --&amp;gt;&lt;br /&gt;
            &amp;lt;tr data-toggle=&amp;quot;collapse&amp;quot; class=&amp;quot;accordion-toggle&amp;quot; data-target=&amp;quot;&amp;lt;%= &amp;quot;#&amp;quot; + target_id %&amp;gt;&amp;quot;&amp;gt;&lt;br /&gt;
              &amp;lt;td class = 'cf' data-toggle=&amp;quot;tooltip&amp;quot; title=&amp;quot;&amp;lt;%= row.question_text %&amp;gt;&amp;quot;&amp;gt; &amp;lt;div style='float: left'&amp;gt;&amp;lt;%= j.to_s %&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;div style='float: right'&amp;gt; &amp;amp;#&amp;lt;%= type_and_max(row) %&amp;gt;;&amp;lt;/div&amp;gt;  &amp;lt;/td&amp;gt;&lt;br /&gt;
&lt;br /&gt;
              &amp;lt;!-- actual cells with scores and colored background. --&amp;gt;&lt;br /&gt;
              &amp;lt;% row.score_row.each do |score| %&amp;gt;&lt;br /&gt;
                  &amp;lt;% score_comment = score.comment.nil? ? '' : score.comment %&amp;gt;&lt;br /&gt;
                  &amp;lt;!-- changing nil to null string to avoid Null Pointer Exception --&amp;gt;&lt;br /&gt;
                  &amp;lt;td class=&amp;quot;&amp;lt;%= score.color_code %&amp;gt;&amp;quot; align=&amp;quot;center&amp;quot; data-toggle=&amp;quot;tooltip&amp;quot; title=&amp;quot;&amp;lt;%= strip_tags(score.comment).html_safe%&amp;gt;&amp;quot;&amp;gt;&lt;br /&gt;
                    &amp;lt;span class=&amp;quot;&amp;lt;%=  underlined?(score) %&amp;gt;&amp;quot;&amp;gt;&lt;br /&gt;
                      &amp;lt;%= score.score_value.to_s %&amp;gt;&lt;br /&gt;
                    &amp;lt;/span&amp;gt;&lt;br /&gt;
                  &amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;% end %&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''F.6 '''Removed the following code.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 &amp;lt;td  class = 'cf' align=&amp;quot;center&amp;quot;&amp;gt;&lt;br /&gt;
                &amp;lt;%= row.countofcomments.to_s %&amp;gt;&lt;br /&gt;
              &amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''F.7 '''&lt;br /&gt;
&lt;br /&gt;
Old code&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;!--loop that creates the collapsed-by-default row, which lists all comments. --&amp;gt;&lt;br /&gt;
            &amp;lt;tr class=&amp;quot;tablesorter-childRow&amp;quot;&amp;gt;&lt;br /&gt;
              &amp;lt;td colspan=&amp;quot;&amp;lt;%= (i+1).to_s %&amp;gt;&amp;quot; class=&amp;quot;hiddenRow&amp;quot; &amp;gt;&amp;lt;div id=&amp;quot;hid&amp;lt;%= row.question_id.to_s + vm.round.to_s %&amp;gt;&amp;quot; class=&amp;quot;accordion-body collapse&amp;quot; style=&amp;quot;margin-left:10px;&amp;quot;&amp;gt;&lt;br /&gt;
                &amp;lt;div style=&amp;quot;padding-top: 10px; padding-bottom: 10px;&amp;quot;&amp;gt;&amp;lt;%=  sanitize row.question_text %&amp;gt;&amp;lt;/div&amp;gt;&lt;br /&gt;
                &amp;lt;div&amp;gt;&lt;br /&gt;
                  &amp;lt;table class=&amp;quot;table tbl_questlist&amp;quot;&amp;gt;&lt;br /&gt;
@@ -181,7 +233,17 @@&lt;br /&gt;
                    &amp;lt;/thead&amp;gt;&lt;br /&gt;
                    &amp;lt;% for index in 0 .. row.score_row.length - 1 %&amp;gt;&lt;br /&gt;
                        &amp;lt;tr&amp;gt;&lt;br /&gt;
                          &amp;lt;td&amp;gt;Review &amp;lt;%=index + 1%&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
New code&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;!--loop that creates the collapsed-by-default row, which lists all comments. --&amp;gt;&lt;br /&gt;
            &amp;lt;tr class=&amp;quot;tablesorter-childRow&amp;quot;&amp;gt;&lt;br /&gt;
              &amp;lt;td colspan=&amp;quot;&amp;lt;%= (i+1).to_s %&amp;gt;&amp;quot; class=&amp;quot;hiddenRow&amp;quot; &amp;gt;&amp;lt;div id=&amp;quot;&amp;lt;%= target_id %&amp;gt;&amp;quot; class=&amp;quot;accordion-body collapse&amp;quot; style=&amp;quot;margin-left:10px;&amp;quot;&amp;gt;&lt;br /&gt;
                &amp;lt;div style=&amp;quot;padding-top: 10px; padding-bottom: 10px;&amp;quot;&amp;gt;&amp;lt;%=  sanitize row.question_text %&amp;gt;&amp;lt;/div&amp;gt;&lt;br /&gt;
                &amp;lt;div&amp;gt;&lt;br /&gt;
                  &amp;lt;table class=&amp;quot;table tbl_questlist&amp;quot;&amp;gt;&lt;br /&gt;
@@ -181,7 +233,17 @@&lt;br /&gt;
                    &amp;lt;/thead&amp;gt;&lt;br /&gt;
                    &amp;lt;% for index in 0 .. row.score_row.length - 1 %&amp;gt;&lt;br /&gt;
                        &amp;lt;tr&amp;gt;&lt;br /&gt;
                          &amp;lt;% if @current_role_name.eql?'Student' or vm.questionnaire_type != &amp;quot;TeammateReviewQuestionnaire&amp;quot; %&amp;gt;&lt;br /&gt;
                            &amp;lt;%# Use Review {{index}} format for student view, and&lt;br /&gt;
                            when questionnaire_type is not teammatereview %&amp;gt;&lt;br /&gt;
                            &amp;lt;td&amp;gt;Review &amp;lt;%=index + 1%&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
                          &amp;lt;% else %&amp;gt;&lt;br /&gt;
                            &amp;lt;td&amp;gt;&lt;br /&gt;
                              &amp;lt;% reviewer_id = row.score_row[index].reviewer_id %&amp;gt;&lt;br /&gt;
                              &amp;lt;% fullname = Participant.find_by(id: reviewer_id).fullname(session[:ip]) %&amp;gt;&lt;br /&gt;
                              Review by &amp;lt;%= fullname %&amp;gt;&lt;br /&gt;
                            &amp;lt;/td&amp;gt;&lt;br /&gt;
                          &amp;lt;% end%&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
====G. In spec/controllers/grades_controller_spec.rb:====&lt;br /&gt;
&lt;br /&gt;
'''G.1 '''&lt;br /&gt;
&lt;br /&gt;
Old code&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
before(:each) do&lt;br /&gt;
  allow(AssignmentParticipant).to receive(:find).with('1').and_return(participant)&lt;br /&gt;
  allow(participant).to receive(:team).and_return(team)&lt;br /&gt;
  stub_current_user(instructor, instructor.role.name, instructor.role)&lt;br /&gt;
  allow(Assignment).to receive(:find).with('1').and_return(assignment)&lt;br /&gt;
@@ -91,29 +90,106 @@&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
New code&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
before(:each) do&lt;br /&gt;
  allow(participant).to receive(:team).and_return(team)&lt;br /&gt;
  stub_current_user(instructor, instructor.role.name, instructor.role)&lt;br /&gt;
  allow(Assignment).to receive(:find).with('1').and_return(assignment)&lt;br /&gt;
@@ -91,29 +90,106 @@&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''G.2 '''Remove xdescribe '#view_team' and change describe '#view_team' as follows.&lt;br /&gt;
&lt;br /&gt;
Old code&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
describe '#view_team' do&lt;br /&gt;
render_views&lt;br /&gt;
context 'when view_team page is viewed by a student who is also a TA for another course' do&lt;br /&gt;
  it 'renders grades#view_team page' do&lt;br /&gt;
    allow(participant).to receive(:team).and_return(team)&lt;br /&gt;
    allow(AssignmentQuestionnaire).to receive(:find_by).with(assignment_id: 1, questionnaire_id: 1).and_return(assignment_questionnaire)&lt;br /&gt;
    allow(AssignmentQuestionnaire).to receive(:where).with(any_args).and_return([assignment_questionnaire])&lt;br /&gt;
    allow(assignment).to receive(:late_policy_id).and_return(false)&lt;br /&gt;
    allow(assignment).to receive(:calculate_penalty).and_return(false)&lt;br /&gt;
    allow(assignment).to receive(:compute_total_score).with(any_args).and_return(100)&lt;br /&gt;
    allow(review_questionnaire).to receive(:get_assessments_round_for).with(participant, 1).and_return([review_response])&lt;br /&gt;
    allow(Answer).to receive(:compute_scores).with([review_response], [question]).and_return(max: 95, min: 88, avg: 90)&lt;br /&gt;
    params = {id: 1}&lt;br /&gt;
    allow(TaMapping).to receive(:exists?).with(ta_id: 1, course_id: 1).and_return(true)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
New code&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
describe '#view_team' do&lt;br /&gt;
render_views&lt;br /&gt;
&lt;br /&gt;
# All stubs and factories are instantiated within this scope so as to not &lt;br /&gt;
# clash with other broken test.&lt;br /&gt;
# The names of the factories created for testing view_team&lt;br /&gt;
# have `_vt` suffix ```where necessary``` to differentiate them from &lt;br /&gt;
# the above declared factories&lt;br /&gt;
&lt;br /&gt;
let(:student1_vt) { create(:student, name: &amp;quot;barry&amp;quot;, id: 12) }&lt;br /&gt;
let(:student2_vt) { create(:student, name: &amp;quot;iris&amp;quot;, id: 13) }&lt;br /&gt;
&lt;br /&gt;
let(:tm_questionnaire) {&lt;br /&gt;
  build(&lt;br /&gt;
    :teammate_review_questionnaire,&lt;br /&gt;
    id: 12,&lt;br /&gt;
    questions: [question],&lt;br /&gt;
    max_question_score: 5&lt;br /&gt;
  )&lt;br /&gt;
}&lt;br /&gt;
let(:assignment_vt) {&lt;br /&gt;
  create(:assignment, id: 6, max_team_size: 2,&lt;br /&gt;
  questionnaires: [tm_questionnaire])&lt;br /&gt;
}&lt;br /&gt;
let(:assignment_questionnaire_vt) {&lt;br /&gt;
  create(:tm_assignment_questionnaire, id: 12, used_in_round: nil,&lt;br /&gt;
  assignment: assignment_vt, questionnaire: tm_questionnaire) }&lt;br /&gt;
let(:team_vt) { create(:assignment_team, id: 12,&lt;br /&gt;
assignment: assignment_vt) }&lt;br /&gt;
let(:participant_vt) { create(:participant, id: 12,&lt;br /&gt;
  assignment: assignment_vt, user_id: student1_vt.id) }&lt;br /&gt;
let(:participant2_vt) { create(:participant, id: 13,&lt;br /&gt;
  assignment: assignment_vt, user_id: student2_vt.id) }&lt;br /&gt;
&lt;br /&gt;
before(:each) do&lt;br /&gt;
  # Need to stub this method so the factory instance with&lt;br /&gt;
  # the stubbed :team method is returned by :find&lt;br /&gt;
  # instead of a separate instance with the same data&lt;br /&gt;
  allow(AssignmentParticipant)&lt;br /&gt;
    .to receive(:find)&lt;br /&gt;
    .with(participant_vt.id.to_s)&lt;br /&gt;
    .and_return(participant_vt)&lt;br /&gt;
  allow(participant_vt).to receive(:team).and_return(team_vt)&lt;br /&gt;
  allow(team_vt).to receive(:participants).and_return([participant_vt, participant2_vt])&lt;br /&gt;
  allow(AssignmentQuestionnaire)&lt;br /&gt;
    .to receive(:find_by)&lt;br /&gt;
    .with(assignment_id: assignment_vt.id, questionnaire_id: tm_questionnaire.id)&lt;br /&gt;
    .and_return(assignment_questionnaire_vt)&lt;br /&gt;
  allow(AssignmentQuestionnaire)&lt;br /&gt;
    .to receive(:find_by)&lt;br /&gt;
    .with(assignment_id: assignment.id, questionnaire_id: review_questionnaire.id)&lt;br /&gt;
    .and_return(assignment_questionnaire_vt)&lt;br /&gt;
  allow(AssignmentQuestionnaire)&lt;br /&gt;
    .to receive(:where)&lt;br /&gt;
    .with(any_args)&lt;br /&gt;
    .and_return([assignment_questionnaire_vt])&lt;br /&gt;
  allow(assignment_vt)&lt;br /&gt;
    .to receive(:late_policy_id)&lt;br /&gt;
    .and_return(false)&lt;br /&gt;
  allow(assignment_vt)&lt;br /&gt;
    .to receive(:calculate_penalty)&lt;br /&gt;
    .and_return(false)&lt;br /&gt;
  allow(assignment_vt)&lt;br /&gt;
    .to receive(:compute_total_score)&lt;br /&gt;
    .with(any_args)&lt;br /&gt;
    .and_return(100)&lt;br /&gt;
  allow(review_questionnaire).to receive(:get_assessments_round_for).with(participant, 1).and_return([review_response])&lt;br /&gt;
  allow(Answer).to receive(:compute_scores).with([review_response], [question]).and_return(max: 95, min: 88, avg: 90)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
 it 'renders grades#view_team page' do&lt;br /&gt;
  params = {id: participant_vt.id}&lt;br /&gt;
  get :view_team, params&lt;br /&gt;
  expect(response).to render_template(:view_team)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
context 'when view_team page is opened by student' do&lt;br /&gt;
  it 'dropdown is not rendered' do&lt;br /&gt;
    session = { user: student1_vt }&lt;br /&gt;
    params = {id: participant_vt.id}&lt;br /&gt;
    stub_current_user(student1_vt, student1_vt.role.name, student1_vt.role)&lt;br /&gt;
    get :view_team, params&lt;br /&gt;
    expect(response.body).to_not have_selector('select')&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
context 'when view_team page is opened by instructor' do&lt;br /&gt;
  it 'dropdown is rendered' do&lt;br /&gt;
    session = { user: instructor }&lt;br /&gt;
    params = {id: participant_vt.id}&lt;br /&gt;
    get :view_team, params&lt;br /&gt;
    expect(response.body).to have_selector('select')&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
context 'when view_team page is viewed by a student who is also a TA for another course' do&lt;br /&gt;
  it 'renders grades#view_team page' do&lt;br /&gt;
    params = { id: participant_vt.id }&lt;br /&gt;
    allow(TaMapping).to receive(:exists?).with(ta_id: participant_vt.user_id, course_id: 1).and_return(true)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
====H. In spec/factories/factories.rb:====&lt;br /&gt;
&lt;br /&gt;
'''H.1 '''Add the following factory:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
factory :teammate_review_questionnaire, class: TeammateReviewQuestionnaire do&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''H.2 '''Add another factory&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
factory :tm_assignment_questionnaire, class: AssignmentQuestionnaire do&lt;br /&gt;
  user_id 1&lt;br /&gt;
  questionnaire { association(:teammate_review_questionnaire) }&lt;br /&gt;
  questionnaire_weight 100&lt;br /&gt;
  used_in_round nil&lt;br /&gt;
  topic_id nil&lt;br /&gt;
  dropdown 1&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Summary of file changes ===&lt;br /&gt;
&lt;br /&gt;
The following files are modified:&lt;br /&gt;
&lt;br /&gt;
1. app/controllers/grades_controller.rb - Controller file which changed how the view model is populated&lt;br /&gt;
&lt;br /&gt;
2. app/views/grades/view_team.html.erb - View file, which  conditionally rendered the teammate name, for a teammate review heatgrid&lt;br /&gt;
&lt;br /&gt;
3. spec/controllers/grades_controller_spec.rb - For tests verifying the proposed changes&lt;br /&gt;
&lt;br /&gt;
4. app/models/vm_question_response.rb - To modify the view-model so it can tell us the name of the person being reviewed for the current heatgrid&lt;br /&gt;
&lt;br /&gt;
5. app/models/vm_question_response_score_cell.rb - &lt;br /&gt;
&lt;br /&gt;
6. app/assets/stylesheets/grades.scss - &lt;br /&gt;
&lt;br /&gt;
7. app/views/grades/_add_icon_to_name.html.erb - &lt;br /&gt;
&lt;br /&gt;
8. spec/factories/factories.rb -&lt;br /&gt;
&lt;br /&gt;
== Design Patterns ==&lt;br /&gt;
&lt;br /&gt;
Existing code does not use any design patterns, apart from if-else. It uses if-else conditional statements to check what type of questionnaire is present in the viewmodel `VmQuestionResponse`, and based on that, it renders the appropriate content.&lt;br /&gt;
&lt;br /&gt;
We decided to continue with this approach since to change the present coding style, there were required many changes (refactoring) to many files which were out of the scope of the present project. To complete the project in the assigned time, we followed the if-else approach.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== User Stories ==&lt;br /&gt;
&lt;br /&gt;
1. As an instructor, I can view what reviews one teammate has given to other teammates.&lt;br /&gt;
&lt;br /&gt;
2. As a student, I can view what reviews my teammates have given to me.&lt;br /&gt;
&lt;br /&gt;
3. As an instructor, I can select if a student's reviews are anonymously shown to their teammates.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Testing ==&lt;br /&gt;
'''CURRENT STATUS'''&lt;br /&gt;
&lt;br /&gt;
1. Presently, the tests only cover if the view_team is page is rendered when it is asked for. This can be seen in the following link: &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''OUR PROPOSAL'''&lt;br /&gt;
&lt;br /&gt;
- When show_team is set as false by the professor, the student should not be able to see his scores.&lt;br /&gt;
&lt;br /&gt;
- When show_team is set as true by the professor, the student should be able to see his.&lt;br /&gt;
&lt;br /&gt;
- An instructor can select which student's scores he/she wants to see. If no student's name is selected then the professor can see the scores of all the students.&lt;br /&gt;
- The instructor can decide whether to show the names of the reviewer to the reviewer in teammate reviews, by selecting a checkbox for the same.&lt;br /&gt;
[[File:Untitled Diagram.drawio.png|border|center|alt=New UI for students|New UI for students ]]&lt;br /&gt;
&lt;br /&gt;
==References==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;https://expertiza.ncsu.edu/&amp;lt;/p&amp;gt;&lt;/div&gt;</summary>
		<author><name>Vdeshmu</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2021_-_E2165._Fix_teammate-review_view&amp;diff=141737</id>
		<title>CSC/ECE 517 Fall 2021 - E2165. Fix teammate-review view</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2021_-_E2165._Fix_teammate-review_view&amp;diff=141737"/>
		<updated>2021-11-28T17:45:24Z</updated>

		<summary type="html">&lt;p&gt;Vdeshmu: /* B. In app/controllers/grades_controller.rb: */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Team Introduction ==&lt;br /&gt;
&lt;br /&gt;
Dr. Edward Gehringer (instructor), Parimal Mehta (mentor)&lt;br /&gt;
&lt;br /&gt;
1. Anjali Garg (unity ID : agarg25)&lt;br /&gt;
&lt;br /&gt;
2. Arvasu Chikara (unity ID: achikar2)&lt;br /&gt;
&lt;br /&gt;
3. Lalit Bangad (unity ID: llbangad)&lt;br /&gt;
&lt;br /&gt;
4. Vinay Deshmukh (unity ID: vdeshmu)&lt;br /&gt;
&lt;br /&gt;
== Problems to be addressed ==&lt;br /&gt;
&lt;br /&gt;
After a project is submitted and reviewed, both the team members (students) and instructors should be able to view the teammate reviews. Students should be able to view the reviews by going to a particular assignment's -&amp;gt; your scores, at the bottom of the page. An instructor can view the teammate reviews by going to assignments -&amp;gt; assignment -&amp;gt; particular team's submission -&amp;gt; view submission -&amp;gt; assign grades -&amp;gt; view scores. &lt;br /&gt;
&lt;br /&gt;
In the case of the instructor, a single heat grid is shown whereas in the case of a team member, we cant view the scores. In the heat grid, it is not clear if the scores visible are for the reviews that the student has *written* for their teammates or the scores that the student has *received* from their teammates. Additionally, for instructors can choose from a list of the students on the team, but they have no way to tell whether the heat grid shows the reviews done *by* that student or done *for* that student.&lt;br /&gt;
&lt;br /&gt;
== Methodology Overview ==&lt;br /&gt;
&lt;br /&gt;
We have divided our work in the following tasks to address the above problems:&lt;br /&gt;
&lt;br /&gt;
1. Distinguish reviews done for a student by rendering separates heatgrids for each student&lt;br /&gt;
&lt;br /&gt;
2. For instructors, the table will have sections based on the students&lt;br /&gt;
&lt;br /&gt;
3. Include a checkbox on the edit assignment page that enables/disables visibility of heat grid to students&lt;br /&gt;
&lt;br /&gt;
4. Fix the average column for a table (which breaks for some reviews)&lt;br /&gt;
&lt;br /&gt;
5. Show a composite score derived from all reviews.  Make this code generalized, so other kinds of heat grid views could use it.&lt;br /&gt;
&lt;br /&gt;
6. Changes should work even in an anonymized view&lt;br /&gt;
&lt;br /&gt;
== Motivations ==&lt;br /&gt;
&lt;br /&gt;
1. Enable users to clearly tell which reviews are done by them, and which reviews are done for them.&lt;br /&gt;
&lt;br /&gt;
2. Code should be generic so it can be used for different types of heat grids as well.&lt;br /&gt;
&lt;br /&gt;
== Control Flow to access the concerned screens ==&lt;br /&gt;
'''1. For instructor (Log in as an instructor):-'''&lt;br /&gt;
&lt;br /&gt;
Screen after logging in by the instructor&lt;br /&gt;
[[File:ss1.png |border|1000px|center]]&lt;br /&gt;
Got to assignments on the Manage menu &lt;br /&gt;
[[File:ss2.png |border|1000px|center]]&lt;br /&gt;
Go to assignments&lt;br /&gt;
[[File:ss3.png |border|1000px|center]]&lt;br /&gt;
Go to submissions for any assignment&lt;br /&gt;
[[File:ss4a.png |border|1000px|center]]&lt;br /&gt;
Go to Assign Grade&lt;br /&gt;
[[File:ss5a.png |border|1000px|center]]&lt;br /&gt;
You will land on the page where the changes are made and can be reviewed&lt;br /&gt;
[[File:ss7a.png |border|1000px|center]]&lt;br /&gt;
&lt;br /&gt;
'''2. Student:- (Logged in as an instructor)'''&lt;br /&gt;
&lt;br /&gt;
After landing on the assignments page, select any student from an assignment as shown below&lt;br /&gt;
[[File:ss6a.png |border|1000px|center]]&lt;br /&gt;
Go to/Select any assignment&lt;br /&gt;
[[File:ss9a.png |border|1000px|center]]&lt;br /&gt;
Go to your scores&lt;br /&gt;
[[File:ss10a.png |border|1000px|center]]&lt;br /&gt;
You will land on the page where the changes are made and can be reviewed&lt;br /&gt;
[[File:ss11a.png |border|1000px|center]]&lt;br /&gt;
&lt;br /&gt;
== Old Status of the application ==&lt;br /&gt;
&lt;br /&gt;
'''1. Instructor's view of teammate review''': This is the current screen given to the instructor. Here we see that the instructor can not determine who has given which review to which student in a team.&lt;br /&gt;
&lt;br /&gt;
[[File:Instructor-view-1.png|border| 700px |center|alt=The proposed expanded student display.|The proposed expanded student display.]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''2. Student's view of teammate review''': Currently, a student is not able to see what grades were given by their teammates. We need to implement that functionality so that the student is able to view those grades.&lt;br /&gt;
&lt;br /&gt;
[[File:Student-view-2.png|border| 700px |center|alt=The current instructor view.|The current review display for instructors.]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''3. Error in existing UI for student''': In the existing UI for a student, the highlighted block should not be rendered. This part of the screen is meant for the instructors/TAs. &lt;br /&gt;
&lt;br /&gt;
[[File:Wrong render for student.png|border|700px|center|alt=Existing UI for student|Existing UI for student.]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Proposed changes ==&lt;br /&gt;
&lt;br /&gt;
''' 1) Proposed UI for instructor ''': The instructor is able to see the score for all teammates. In the existing code, only one teammate's scores are being shown. But, we are planning to change the way the (VmQuestionResponse array is populated)[https://github.com/expertiza/expertiza/blob/master/app/controllers/grades_controller.rb#L114], so that the scores for all teammates are appended to it so it correctly shows what should have already been shown in this screen for the instructor.&lt;br /&gt;
&lt;br /&gt;
[[File:Proposed_screen.png|border|700px|center|alt=Proposed UI for instructor|Proposed UI for instructor.]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Note: When a student visits this screen, they will only be shown the reviews received by them, assuming the instructor has allowed visibility of teammate reviews to students.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
''' 2) Show detailed review for a particular question''': The instructor can see detailed review given to a student by their teammates by clicking on a particular question number in the table.&lt;br /&gt;
&lt;br /&gt;
[[File:ss12a.png|border|700px|center|alt=New UI for students|New UI for students ]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
''' 3) Show teammate review to student UI ''': The existing code doesn't render a student's teammate review scores at all. We are planning to render the scores to a student (as shown below) when they visit this screen. However, the visibility of this screen is contingent on whether the instructor has allowed visibility of the teammate review screen to students. If the instructor has disabled this feature, then the heatgrid will not be displayed at all.&lt;br /&gt;
&lt;br /&gt;
[[File:UI_for_student.png|border|700px|center|alt=New UI for students|New UI for students ]]&lt;br /&gt;
&lt;br /&gt;
== Models used / Explanation of fixes ==&lt;br /&gt;
&lt;br /&gt;
The below diagram illustrates the proposed code change for showing all team members with the teammate review data to an instructor. The existing code only iterated on the `Participant` whose ID is present in the URL of the page. To fix this, we will iterate over all teammates of the given participant so that all teammate reviews for all team members are shown to the instructor.&lt;br /&gt;
&lt;br /&gt;
[[File:Logic e2165.png|border|center|alt=Flow diagram of proposed changes for showing team review data to instructor]]&lt;br /&gt;
&lt;br /&gt;
===Changes made to the code are shown below. Every change is shown and explained separately===&lt;br /&gt;
&lt;br /&gt;
====A. Added the following to app/assets/stylesheets/grades.scss:====&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    .teammate_table.hidden {&lt;br /&gt;
      display: none;&lt;br /&gt;
      }&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
====B. In app/controllers/grades_controller.rb: ====&lt;br /&gt;
&lt;br /&gt;
'''B.1:'''&lt;br /&gt;
&lt;br /&gt;
Old code: The existing code does not differentiate when adding a view model for the TeammateReview questionnaire&lt;br /&gt;
  questionnaires.each do |questionnaire|&lt;br /&gt;
     ...&lt;br /&gt;
     @vmlist &amp;lt;&amp;lt; populate_view_model(questionnaire)&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
New code: Since the current page URL contains an ID for the participant, from which we get an assignment, which gives us a list of questionnaires, we need to iterate all participants for a `TeammateReveiwQuestionnaire` questionnaire, so that we get the heatgrid view models for all members of a team.&lt;br /&gt;
  questionnaires.each do |questionnaire|&lt;br /&gt;
     ...&lt;br /&gt;
     if questionnaire.type == &amp;quot;TeammateReviewQuestionnaire&amp;quot;&lt;br /&gt;
        # as teammate review will be different for each participant&lt;br /&gt;
        # we need to create a separate table for each teammate&lt;br /&gt;
        @participant.team.participants.each do |team_participant|&lt;br /&gt;
          @vmlist &amp;lt;&amp;lt; populate_view_model(team_participant, questionnaire, @team)&lt;br /&gt;
        end&lt;br /&gt;
      else&lt;br /&gt;
        # only one participant needs iterating, as apart from teammatereview&lt;br /&gt;
        # all other reviews are at &amp;quot;team&amp;quot; level&lt;br /&gt;
        @vmlist &amp;lt;&amp;lt; populate_view_model(@participant, questionnaire, @team)&lt;br /&gt;
      end&lt;br /&gt;
   end&lt;br /&gt;
&lt;br /&gt;
'''B.2: '''&lt;br /&gt;
&lt;br /&gt;
Old code: This code uses @participant as an instance variable, but this structure will not work as we need to call this ViewModel with multiple participants when iterating for a teammate review questionnaire.&lt;br /&gt;
    def populate_view_model(questionnaire)&lt;br /&gt;
      vm = VmQuestionResponse.new(questionnaire, @assignment, @round)&lt;br /&gt;
      vmquestions = questionnaire.questions&lt;br /&gt;
      vm.add_questions(vmquestions)&lt;br /&gt;
      vm.add_team_members(@team)&lt;br /&gt;
      vm.add_reviews(@participant, @team, @assignment.vary_by_round)&lt;br /&gt;
      vm.number_of_comments_greater_than_10_words&lt;br /&gt;
      vm &lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
New code: We need to call this function with a separate participant in each invocation due to our change for TeammateReviewQuestionnaire, hence it makes sense to make `participant` as an argument to this function. Similarly, as `team` is a closely related model to `participant`, we are passing it as an argument, to keep this function as &amp;quot;pure&amp;quot; as possible.&lt;br /&gt;
    def populate_view_model(participant, questionnaire, team)&lt;br /&gt;
      ...&lt;br /&gt;
      vm.add_team_members(team)&lt;br /&gt;
      vm.add_reviews(participant, team, @assignment.vary_by_round)&lt;br /&gt;
      ...&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
====C. In app/models/vm_question_response.rb:====&lt;br /&gt;
&lt;br /&gt;
'''C.1: '''Added the reviewee_id method&lt;br /&gt;
&lt;br /&gt;
    def reviewee_id&lt;br /&gt;
      @participant_who_is_reviewee.user_id&lt;br /&gt;
    end &lt;br /&gt;
&lt;br /&gt;
'''C.2: '''Added the reviewee_name method&lt;br /&gt;
&lt;br /&gt;
    def reviewee_name(ip_address = nil)&lt;br /&gt;
      part = @participant_who_is_reviewee&lt;br /&gt;
      User.find_by(id: part.user_id).fullname(ip_address)&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
'''C.3: '''&lt;br /&gt;
&lt;br /&gt;
Old code&lt;br /&gt;
    elsif @questionnaire_type == &amp;quot;TeammateReviewQuestionnaire&amp;quot;&lt;br /&gt;
      reviews = participant.teammate_reviews&lt;br /&gt;
      reviews.each do |review|&lt;br /&gt;
        review_mapping = TeammateReviewResponseMap.find_by(id: review.map_id)&lt;br /&gt;
        participant = Participant.find(review_mapping.reviewer_id)&lt;br /&gt;
&lt;br /&gt;
New code&lt;br /&gt;
    elsif @questionnaire_type == &amp;quot;TeammateReviewQuestionnaire&amp;quot;&lt;br /&gt;
      reviews = participant.teammate_reviews&lt;br /&gt;
      @participant_who_is_reviewee = participant&lt;br /&gt;
      reviews.each do |review|&lt;br /&gt;
        review_mapping = TeammateReviewResponseMap.find_by(id: review.map_id)&lt;br /&gt;
        participant = Participant.find(review_mapping.reviewer_id)&lt;br /&gt;
&lt;br /&gt;
'''C.4: '''&lt;br /&gt;
&lt;br /&gt;
Old code&lt;br /&gt;
    row.score_row.push(VmQuestionResponseScoreCell.new(answer.answer, color_code, answer.comments, vm_tag_prompts))&lt;br /&gt;
&lt;br /&gt;
New code&lt;br /&gt;
    &lt;br /&gt;
    row.score_row.push(VmQuestionResponseScoreCell.new(answer.answer, color_code, answer.comments, vm_tag_prompts, answer.response_id))&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
====D. In app/models/vm_question_response_score_cell.rb:====&lt;br /&gt;
&lt;br /&gt;
'''D.1: '''In the method initialize of class VmQuestionResponseScoreCell&lt;br /&gt;
&lt;br /&gt;
Old code&lt;br /&gt;
    def initialize(score_value, color_code, comments, vmprompts = nil)&lt;br /&gt;
      @score_value = score_value&lt;br /&gt;
      @color_code = color_code&lt;br /&gt;
      @comment = comments&lt;br /&gt;
      @vm_prompts = vmprompts&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
New code&lt;br /&gt;
&lt;br /&gt;
    def initialize(score_value, color_code, comments, vmprompts = nil, response_id)&lt;br /&gt;
      @score_value = score_value&lt;br /&gt;
      @color_code = color_code&lt;br /&gt;
      @comment = comments&lt;br /&gt;
      @vm_prompts = vmprompts&lt;br /&gt;
      @response_id = response_id&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
'''D.2: '''Added a method reviewer_id to the class VmQuestionResponseScoreCell&lt;br /&gt;
&lt;br /&gt;
    def reviewer_id&lt;br /&gt;
      resp = Response.find(@response_id)&lt;br /&gt;
      map = ResponseMap.find(resp.map_id)&lt;br /&gt;
      map.reviewer_id&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
====E. In app/views/grades/_add_icon_to_name.html.erb:====&lt;br /&gt;
&lt;br /&gt;
'''E.1 '''Added the following code to the file:&lt;br /&gt;
&lt;br /&gt;
    &amp;lt;%# Determine the content of the reviewed by text %&amp;gt;&lt;br /&gt;
    &amp;lt;% review_text = &amp;quot;&amp;quot; %&amp;gt;&lt;br /&gt;
    &amp;lt;% if @current_role_name.eql?'Student' or questionnaire_type != &amp;quot;TeammateReviewQuestionnaire&amp;quot; %&amp;gt;&lt;br /&gt;
      &amp;lt;%# Use Review {{index}} format for student view, and when questionnaire_type is not teammatereview %&amp;gt;&lt;br /&gt;
      &amp;lt;% review_text = &amp;quot;Review #{i + 1}&amp;quot; %&amp;gt;&lt;br /&gt;
    &amp;lt;% else %&amp;gt;&lt;br /&gt;
      &amp;lt;% resp = Response.find(review.id) %&amp;gt;&lt;br /&gt;
      &amp;lt;% map = ResponseMap.find(resp.map_id) %&amp;gt;&lt;br /&gt;
      &amp;lt;% reviewer_id = map.reviewer_id %&amp;gt;&lt;br /&gt;
      &amp;lt;% fullname = Participant.find_by(id: reviewer_id).fullname(session[:ip]) %&amp;gt;&lt;br /&gt;
      &amp;lt;% review_text = &amp;quot;Review by #{fullname}&amp;quot; %&amp;gt;&lt;br /&gt;
    &amp;lt;% end%&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''E.2: '''&lt;br /&gt;
&lt;br /&gt;
Old code&lt;br /&gt;
&lt;br /&gt;
    &amp;lt;% if review.done_by_staff_participant? %&amp;gt;&lt;br /&gt;
      &amp;lt;th class=&amp;quot;sorter-false&amp;quot;&amp;gt; &amp;lt;img data-toggle=&amp;quot;tooltip&amp;quot; data-placement=&amp;quot;right&amp;quot; title=&amp;quot;Icon indicates this review was done by course staff&amp;quot; class=&amp;quot;img_icon&amp;quot; src=&amp;quot;/assets/staff.png&amp;quot;&amp;gt; &amp;lt;a target=&amp;quot;_blank&amp;quot; href=&amp;quot;../response/view?id=&amp;lt;%= review.id.to_s %&amp;gt;&amp;quot;  data-toggle=&amp;quot;tooltip&amp;quot; data-placement=&amp;quot;right&amp;quot; title=&amp;quot;Click to see details&amp;quot;&amp;gt;&amp;lt;%= &amp;quot;Review &amp;quot; + i.to_s  %&amp;gt;&amp;lt;/a&amp;gt; &amp;lt;/th&amp;gt;&lt;br /&gt;
    &amp;lt;% else %&amp;gt;&lt;br /&gt;
      &amp;lt;th class=&amp;quot;sorter-false&amp;quot;&amp;gt; &amp;lt;a target=&amp;quot;_blank&amp;quot; href=&amp;quot;../response/view?id=&amp;lt;%= review.id.to_s %&amp;gt;&amp;quot;  data-toggle=&amp;quot;tooltip&amp;quot; data-placement=&amp;quot;right&amp;quot; title=&amp;quot;Click to see details&amp;quot;&amp;gt;&amp;lt;%= &amp;quot;Review &amp;quot; + i.to_s %&amp;gt;&amp;lt;/a&amp;gt;  &amp;lt;/th&amp;gt;&lt;br /&gt;
    &amp;lt;% end %&amp;gt;&lt;br /&gt;
&lt;br /&gt;
New code&lt;br /&gt;
&lt;br /&gt;
    &amp;lt;% if review.done_by_staff_participant? %&amp;gt;&lt;br /&gt;
    &amp;lt;th class=&amp;quot;sorter-false&amp;quot;&amp;gt;&lt;br /&gt;
      &amp;lt;img&lt;br /&gt;
      data-toggle=&amp;quot;tooltip&amp;quot;&lt;br /&gt;
      data-placement=&amp;quot;right&amp;quot;&lt;br /&gt;
      title=&amp;quot;Icon indicates this review was done by course staff&amp;quot; class=&amp;quot;img_icon&amp;quot;&lt;br /&gt;
      src=&amp;quot;/assets/staff.png&amp;quot;&lt;br /&gt;
      &amp;gt;&lt;br /&gt;
    &amp;lt;a&lt;br /&gt;
      target=&amp;quot;_blank&amp;quot;&lt;br /&gt;
      href=&amp;quot;../response/view?id=&amp;lt;%= review.id.to_s %&amp;gt;&amp;quot;&lt;br /&gt;
      data-toggle=&amp;quot;tooltip&amp;quot;&lt;br /&gt;
      data-placement=&amp;quot;right&amp;quot;&lt;br /&gt;
      title=&amp;quot;Click to see details&amp;quot;&amp;gt;&lt;br /&gt;
      &amp;lt;%= review_text %&amp;gt;&lt;br /&gt;
    &amp;lt;/a&amp;gt;&lt;br /&gt;
    &amp;lt;/th&amp;gt;&lt;br /&gt;
    &amp;lt;% else %&amp;gt;&lt;br /&gt;
    &amp;lt;th class=&amp;quot;sorter-false&amp;quot;&amp;gt;&lt;br /&gt;
        &amp;lt;a&lt;br /&gt;
            target=&amp;quot;_blank&amp;quot; &lt;br /&gt;
            href=&amp;quot;../response/view?id=&amp;lt;%= review.id.to_s %&amp;gt;&amp;quot;  &lt;br /&gt;
            data-toggle=&amp;quot;tooltip&amp;quot;&lt;br /&gt;
            data-placement=&amp;quot;right&amp;quot;&lt;br /&gt;
            title=&amp;quot;Click to see details&amp;quot;&lt;br /&gt;
        &amp;gt;&lt;br /&gt;
        &amp;lt;%= review_text %&amp;gt;&lt;br /&gt;
        &amp;lt;/a&amp;gt;&lt;br /&gt;
    &amp;lt;/th&amp;gt;&lt;br /&gt;
    &amp;lt;% end %&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
====F.In app/views/grades/view_team.html.erb:====&lt;br /&gt;
&lt;br /&gt;
'''F.1: '''Added function teammateSelectOnChange:&lt;br /&gt;
    &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  function teammateSelectOnChange(selectNode) {&lt;br /&gt;
      const revieweeIdToShow= selectNode.value;&lt;br /&gt;
      const tableSelector = &amp;quot;.teammate_table&amp;quot;;&lt;br /&gt;
      if(revieweeIdToShow == &amp;quot;all&amp;quot;) {&lt;br /&gt;
        document.querySelectorAll(tableSelector).forEach((tableNode) =&amp;gt; {&lt;br /&gt;
          tableNode.classList.remove(&amp;quot;hidden&amp;quot;);&lt;br /&gt;
        });&lt;br /&gt;
        return;&lt;br /&gt;
      }&lt;br /&gt;
&lt;br /&gt;
  document.querySelectorAll(tableSelector).forEach((tableNode) =&amp;gt; {&lt;br /&gt;
    const tableRevieweeId = tableNode.getAttribute('data-reviewee_id');&lt;br /&gt;
    if(tableRevieweeId == revieweeIdToShow) {&lt;br /&gt;
      tableNode.classList.remove(&amp;quot;hidden&amp;quot;);&lt;br /&gt;
    } else {&lt;br /&gt;
      tableNode.classList.add(&amp;quot;hidden&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
    });&lt;br /&gt;
  }&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''F.2: '''&lt;br /&gt;
&lt;br /&gt;
Old code&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    &amp;lt;% @vmlist.each do |vm| %&amp;gt;&lt;br /&gt;
        &amp;lt;% if (vm.questionnaire_display_type == &amp;quot;Metareview&amp;quot; or vm.questionnaire_display_type == &amp;quot;Author Feedback&amp;quot; or vm.questionnaire_display_type == &amp;quot;Teammate Review&amp;quot;) and @current_role_name.eql?'Student' %&amp;gt;&lt;br /&gt;
        &amp;lt;% else %&amp;gt;&lt;br /&gt;
        &amp;lt;% if vm.list_of_reviewers.length &amp;gt; 0 %&amp;gt;&lt;br /&gt;
&lt;br /&gt;
​      &amp;lt;!-- display the list of questions for this questionnaire --&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  @@ -87,6 +131,8 @@&lt;br /&gt;
              &amp;lt;h4 style=&amp;quot;display:inline-block;&amp;quot;&amp;gt;&amp;lt;%= vm.questionnaire_display_type %&amp;gt;&lt;br /&gt;
                &amp;lt;% if vm.questionnaire_type == &amp;quot;ReviewQuestionnaire&amp;quot; %&amp;gt;&lt;br /&gt;
                    (Round: &amp;lt;%= vm.round.to_s  %&amp;gt; of &amp;lt;%= vm.rounds.to_s  %&amp;gt;)&lt;br /&gt;
        &amp;lt;%end %&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
New code&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;%# This boolean is used to render a dropdown just before the first teammate review heat grid %&amp;gt;&lt;br /&gt;
&amp;lt;% first_teammate_review_appeared = false %&amp;gt;&lt;br /&gt;
&amp;lt;% @vmlist.each do |vm| %&amp;gt;&lt;br /&gt;
    &amp;lt;% if not @current_role_name.eql?'Student' and not first_teammate_review_appeared and vm.questionnaire_type == &amp;quot;TeammateReviewQuestionnaire&amp;quot; %&amp;gt;&lt;br /&gt;
      &amp;lt;div&amp;gt;&lt;br /&gt;
        &amp;lt;select onchange=&amp;quot;teammateSelectOnChange(this)&amp;quot;&amp;gt;&lt;br /&gt;
          &amp;lt;option value=&amp;quot;all&amp;quot;&amp;gt;All&amp;lt;/option&amp;gt;&lt;br /&gt;
          &amp;lt;% @vmlist.select { |tm_vm| tm_vm.questionnaire_type == &amp;quot;TeammateReviewQuestionnaire&amp;quot; }.each do |tm_vm| %&amp;gt;&lt;br /&gt;
            &amp;lt;option value=&amp;quot;&amp;lt;%= tm_vm.reviewee_id %&amp;gt;&amp;quot;&amp;gt;&lt;br /&gt;
              &amp;lt;%= tm_vm.reviewee_name(session[:ip]) %&amp;gt;&lt;br /&gt;
            &amp;lt;/option&amp;gt;&lt;br /&gt;
          &amp;lt;% end %&amp;gt;&lt;br /&gt;
        &amp;lt;/select&amp;gt;&lt;br /&gt;
      &amp;lt;/div&amp;gt;&lt;br /&gt;
      &amp;lt;% first_teammate_review_appeared = true %&amp;gt;&lt;br /&gt;
    &amp;lt;% end %&amp;gt;&lt;br /&gt;
    &amp;lt;% if (vm.questionnaire_display_type == &amp;quot;Metareview&amp;quot; or vm.questionnaire_display_type == &amp;quot;Author Feedback&amp;quot;) and @current_role_name.eql?'Student' %&amp;gt;&lt;br /&gt;
    &amp;lt;% elsif (vm.questionnaire_type == &amp;quot;TeammateReviewQuestionnaire&amp;quot; and @current_role_name.eql?'Student' and !@assignment.show_teammate_reviews)%&amp;gt;&lt;br /&gt;
    &amp;lt;% elsif (vm.questionnaire_type == &amp;quot;TeammateReviewQuestionnaire&amp;quot; and @current_role_name.eql?'Student' and @assignment.show_teammate_reviews and current_user.id != vm.reviewee_id )%&amp;gt;&lt;br /&gt;
    &amp;lt;% else %&amp;gt;&lt;br /&gt;
        &amp;lt;% if vm.questionnaire_type == &amp;quot;TeammateReviewQuestionnaire&amp;quot; %&amp;gt;&lt;br /&gt;
          &amp;lt;div class=&amp;quot;teammate_table&amp;quot; data-reviewee_id=&amp;quot;&amp;lt;%= vm.reviewee_id %&amp;gt;&amp;quot;&amp;gt;&lt;br /&gt;
        &amp;lt;% else %&amp;gt;&lt;br /&gt;
          &amp;lt;div&amp;gt;&lt;br /&gt;
        &amp;lt;% end %&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''F.3  '''&lt;br /&gt;
&lt;br /&gt;
Old code&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;!-- display the list of questions for this questionnaire --&amp;gt;&lt;br /&gt;
@@ -87,6 +131,8 @@&lt;br /&gt;
          &amp;lt;h4 style=&amp;quot;display:inline-block;&amp;quot;&amp;gt;&amp;lt;%= vm.questionnaire_display_type %&amp;gt;&lt;br /&gt;
            &amp;lt;% if vm.questionnaire_type == &amp;quot;ReviewQuestionnaire&amp;quot; %&amp;gt;&lt;br /&gt;
                (Round: &amp;lt;%= vm.round.to_s  %&amp;gt; of &amp;lt;%= vm.rounds.to_s  %&amp;gt;)&lt;br /&gt;
            &amp;lt;%end %&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
New code&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;!-- display the list of questions for this questionnaire --&amp;gt;&lt;br /&gt;
@@ -87,6 +131,8 @@&lt;br /&gt;
          &amp;lt;h4 style=&amp;quot;display:inline-block;&amp;quot;&amp;gt;&amp;lt;%= vm.questionnaire_display_type %&amp;gt;&lt;br /&gt;
            &amp;lt;% if vm.questionnaire_type == &amp;quot;ReviewQuestionnaire&amp;quot; %&amp;gt;&lt;br /&gt;
                (Round: &amp;lt;%= vm.round.to_s  %&amp;gt; of &amp;lt;%= vm.rounds.to_s  %&amp;gt;)&lt;br /&gt;
            &amp;lt;% elsif vm.questionnaire_type == &amp;quot;TeammateReviewQuestionnaire&amp;quot; %&amp;gt;&lt;br /&gt;
                (For: &amp;lt;%= vm.reviewee_name(session[:ip]) %&amp;gt;)&lt;br /&gt;
            &amp;lt;%end %&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''F.4 '''&lt;br /&gt;
&lt;br /&gt;
Old code&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;% vm.list_of_reviews.each do |review| %&amp;gt;&lt;br /&gt;
              &amp;lt;!-- instructors (or higher level users) see reviewer name, students see anonymized string --&amp;gt;&lt;br /&gt;
              &amp;lt;% if (['Student'].include? @current_role_name) &amp;amp;&amp;amp; @assignment.is_anonymous%&amp;gt;&lt;br /&gt;
                &amp;lt;%= render :partial =&amp;gt; 'add_icon_to_name', :locals =&amp;gt; {review: review, i: i} %&amp;gt;&lt;br /&gt;
              &amp;lt;% else %&amp;gt;&lt;br /&gt;
                  &amp;lt;% user_name = User.find(Participant.find(ResponseMap.find(Response.find(review.id).map_id).reviewer_id).user_id).fullname(session[:ip]).to_s %&amp;gt;&lt;br /&gt;
                &amp;lt;%= render :partial =&amp;gt; 'add_icon_to_name', :locals =&amp;gt; {review: review, i: i} %&amp;gt;&lt;br /&gt;
              &amp;lt;% end %&amp;gt;&lt;br /&gt;
              &amp;lt;% i += 1 %&amp;gt;&lt;br /&gt;
          &amp;lt;% end %&amp;gt;&lt;br /&gt;
&lt;br /&gt;
          &amp;lt;th class=&amp;quot;sorter-true&amp;quot; align=&amp;quot;right&amp;quot; &amp;gt;&lt;br /&gt;
            Avg&amp;lt;span&amp;gt;&amp;lt;/span&amp;gt;&lt;br /&gt;
          &amp;lt;/th&amp;gt;&lt;br /&gt;
          &amp;lt;th class=&amp;quot;sorter-false&amp;quot;&amp;gt;&lt;br /&gt;
            &amp;lt;span  data-toggle=&amp;quot;tooltip&amp;quot; data-placement=&amp;quot;right&amp;quot; title=&amp;quot;A count of comments, for the respective question, which have word count &amp;gt; 10. The purpose of this metric is to represent how many comments for the question are of a substantial length to provide quality feedback.&amp;quot;&amp;gt;metric-1&amp;lt;/span&amp;gt;&lt;br /&gt;
          &amp;lt;/th&amp;gt;&lt;br /&gt;
        &amp;lt;/tr&amp;gt;&lt;br /&gt;
        &amp;lt;/thead&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
New code&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;% vm.list_of_reviews.each do |review| %&amp;gt;&lt;br /&gt;
              &amp;lt;!-- instructors (or higher level users) see reviewer name, students see anonymized string --&amp;gt;&lt;br /&gt;
              &amp;lt;% if (['Student'].include? @current_role_name) &amp;amp;&amp;amp; @assignment.is_anonymous%&amp;gt;&lt;br /&gt;
                &amp;lt;%= render :partial =&amp;gt; 'add_icon_to_name', :locals =&amp;gt; {review: review, i: i, questionnaire_type: vm.questionnaire_type } %&amp;gt;&lt;br /&gt;
              &amp;lt;% else %&amp;gt;&lt;br /&gt;
                &amp;lt;% user_name = User.find(Participant.find(ResponseMap.find(Response.find(review.id).map_id).reviewer_id).user_id).fullname(session[:ip]).to_s %&amp;gt;&lt;br /&gt;
                &amp;lt;%= render :partial =&amp;gt; 'add_icon_to_name', :locals =&amp;gt; {review: review, i: i, questionnaire_type: vm.questionnaire_type } %&amp;gt;&lt;br /&gt;
              &amp;lt;% end %&amp;gt;&lt;br /&gt;
              &amp;lt;% i += 1 %&amp;gt;&lt;br /&gt;
          &amp;lt;% end %&amp;gt;&lt;br /&gt;
&lt;br /&gt;
          &amp;lt;th class=&amp;quot;sorter-true&amp;quot; align=&amp;quot;right&amp;quot; &amp;gt;&lt;br /&gt;
            Avg&amp;lt;span&amp;gt;&amp;lt;/span&amp;gt;&lt;br /&gt;
          &amp;lt;/th&amp;gt;&lt;br /&gt;
        &amp;lt;/tr&amp;gt;&lt;br /&gt;
        &amp;lt;/thead&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''F.5 '''&lt;br /&gt;
&lt;br /&gt;
Old code&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;% vm.list_of_rows.each do |row| %&amp;gt;&lt;br /&gt;
            &amp;lt;!-- notice the data-target. because we're toggling via looped code, we need to dynamically generate the identifier. --&amp;gt;&lt;br /&gt;
            &amp;lt;tr data-toggle=&amp;quot;collapse&amp;quot; class=&amp;quot;accordion-toggle&amp;quot; data-target=&amp;quot;#hid&amp;lt;%= row.question_id.to_s + vm.round.to_s %&amp;gt;&amp;quot;&amp;gt;&lt;br /&gt;
              &amp;lt;td class = 'cf' data-toggle=&amp;quot;tooltip&amp;quot; title=&amp;quot;&amp;lt;%= row.question_text %&amp;gt;&amp;quot;&amp;gt; &amp;lt;div style='float: left'&amp;gt;&amp;lt;%= j.to_s %&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;div style='float: right'&amp;gt; &amp;amp;#&amp;lt;%= type_and_max(row) %&amp;gt;;&amp;lt;/div&amp;gt;  &amp;lt;/td&amp;gt;&lt;br /&gt;
&lt;br /&gt;
              &amp;lt;!-- actual cells with scores and colored background. --&amp;gt;&lt;br /&gt;
              &amp;lt;% row.score_row.each do |score| %&amp;gt;&lt;br /&gt;
                  &amp;lt;% score_comment = score.comment.nil? ? '' : score.comment %&amp;gt; &amp;lt;!-- changing nil to null string to avoid Null Pointer Exception --&amp;gt;&lt;br /&gt;
                  &amp;lt;td class=&amp;quot;&amp;lt;%= score.color_code %&amp;gt;&amp;quot; align=&amp;quot;center&amp;quot; data-toggle=&amp;quot;tooltip&amp;quot; title=&amp;quot;&amp;lt;%= strip_tags(score.comment).html_safe%&amp;gt;&amp;quot;&amp;gt;&lt;br /&gt;
                    &amp;lt;span class=&amp;quot;&amp;lt;%=  underlined?(score) %&amp;gt;&amp;quot;&amp;gt;&amp;lt;%= score.score_value.to_s %&amp;gt;&amp;lt;/span&amp;gt;&lt;br /&gt;
                  &amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;% end %&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
New code&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;% vm.list_of_rows.each do |row| %&amp;gt;&lt;br /&gt;
            &amp;lt;% target_id = &amp;quot;hid__#{row.question_id}__#{vm.round}&amp;quot; %&amp;gt;&lt;br /&gt;
            &amp;lt;% if vm.questionnaire_type == &amp;quot;TeammateReviewQuestionnaire&amp;quot; %&amp;gt;&lt;br /&gt;
              &amp;lt;%# Since we render different heatgrids with the same questions for each&lt;br /&gt;
              teammember, we need to distinguish the ID, based on the user for whom,&lt;br /&gt;
              the reviews have been created. %&amp;gt;&lt;br /&gt;
              &amp;lt;% target_id += &amp;quot;__#{vm.reviewee_id}&amp;quot; %&amp;gt;&lt;br /&gt;
            &amp;lt;% end%&amp;gt;&lt;br /&gt;
&lt;br /&gt;
            &amp;lt;!-- notice the data-target. because we're toggling via looped code, we need to dynamically generate the identifier. --&amp;gt;&lt;br /&gt;
            &amp;lt;tr data-toggle=&amp;quot;collapse&amp;quot; class=&amp;quot;accordion-toggle&amp;quot; data-target=&amp;quot;&amp;lt;%= &amp;quot;#&amp;quot; + target_id %&amp;gt;&amp;quot;&amp;gt;&lt;br /&gt;
              &amp;lt;td class = 'cf' data-toggle=&amp;quot;tooltip&amp;quot; title=&amp;quot;&amp;lt;%= row.question_text %&amp;gt;&amp;quot;&amp;gt; &amp;lt;div style='float: left'&amp;gt;&amp;lt;%= j.to_s %&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;div style='float: right'&amp;gt; &amp;amp;#&amp;lt;%= type_and_max(row) %&amp;gt;;&amp;lt;/div&amp;gt;  &amp;lt;/td&amp;gt;&lt;br /&gt;
&lt;br /&gt;
              &amp;lt;!-- actual cells with scores and colored background. --&amp;gt;&lt;br /&gt;
              &amp;lt;% row.score_row.each do |score| %&amp;gt;&lt;br /&gt;
                  &amp;lt;% score_comment = score.comment.nil? ? '' : score.comment %&amp;gt;&lt;br /&gt;
                  &amp;lt;!-- changing nil to null string to avoid Null Pointer Exception --&amp;gt;&lt;br /&gt;
                  &amp;lt;td class=&amp;quot;&amp;lt;%= score.color_code %&amp;gt;&amp;quot; align=&amp;quot;center&amp;quot; data-toggle=&amp;quot;tooltip&amp;quot; title=&amp;quot;&amp;lt;%= strip_tags(score.comment).html_safe%&amp;gt;&amp;quot;&amp;gt;&lt;br /&gt;
                    &amp;lt;span class=&amp;quot;&amp;lt;%=  underlined?(score) %&amp;gt;&amp;quot;&amp;gt;&lt;br /&gt;
                      &amp;lt;%= score.score_value.to_s %&amp;gt;&lt;br /&gt;
                    &amp;lt;/span&amp;gt;&lt;br /&gt;
                  &amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;% end %&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''F.6 '''Removed the following code.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 &amp;lt;td  class = 'cf' align=&amp;quot;center&amp;quot;&amp;gt;&lt;br /&gt;
                &amp;lt;%= row.countofcomments.to_s %&amp;gt;&lt;br /&gt;
              &amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''F.7 '''&lt;br /&gt;
&lt;br /&gt;
Old code&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;!--loop that creates the collapsed-by-default row, which lists all comments. --&amp;gt;&lt;br /&gt;
            &amp;lt;tr class=&amp;quot;tablesorter-childRow&amp;quot;&amp;gt;&lt;br /&gt;
              &amp;lt;td colspan=&amp;quot;&amp;lt;%= (i+1).to_s %&amp;gt;&amp;quot; class=&amp;quot;hiddenRow&amp;quot; &amp;gt;&amp;lt;div id=&amp;quot;hid&amp;lt;%= row.question_id.to_s + vm.round.to_s %&amp;gt;&amp;quot; class=&amp;quot;accordion-body collapse&amp;quot; style=&amp;quot;margin-left:10px;&amp;quot;&amp;gt;&lt;br /&gt;
                &amp;lt;div style=&amp;quot;padding-top: 10px; padding-bottom: 10px;&amp;quot;&amp;gt;&amp;lt;%=  sanitize row.question_text %&amp;gt;&amp;lt;/div&amp;gt;&lt;br /&gt;
                &amp;lt;div&amp;gt;&lt;br /&gt;
                  &amp;lt;table class=&amp;quot;table tbl_questlist&amp;quot;&amp;gt;&lt;br /&gt;
@@ -181,7 +233,17 @@&lt;br /&gt;
                    &amp;lt;/thead&amp;gt;&lt;br /&gt;
                    &amp;lt;% for index in 0 .. row.score_row.length - 1 %&amp;gt;&lt;br /&gt;
                        &amp;lt;tr&amp;gt;&lt;br /&gt;
                          &amp;lt;td&amp;gt;Review &amp;lt;%=index + 1%&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
New code&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;!--loop that creates the collapsed-by-default row, which lists all comments. --&amp;gt;&lt;br /&gt;
            &amp;lt;tr class=&amp;quot;tablesorter-childRow&amp;quot;&amp;gt;&lt;br /&gt;
              &amp;lt;td colspan=&amp;quot;&amp;lt;%= (i+1).to_s %&amp;gt;&amp;quot; class=&amp;quot;hiddenRow&amp;quot; &amp;gt;&amp;lt;div id=&amp;quot;&amp;lt;%= target_id %&amp;gt;&amp;quot; class=&amp;quot;accordion-body collapse&amp;quot; style=&amp;quot;margin-left:10px;&amp;quot;&amp;gt;&lt;br /&gt;
                &amp;lt;div style=&amp;quot;padding-top: 10px; padding-bottom: 10px;&amp;quot;&amp;gt;&amp;lt;%=  sanitize row.question_text %&amp;gt;&amp;lt;/div&amp;gt;&lt;br /&gt;
                &amp;lt;div&amp;gt;&lt;br /&gt;
                  &amp;lt;table class=&amp;quot;table tbl_questlist&amp;quot;&amp;gt;&lt;br /&gt;
@@ -181,7 +233,17 @@&lt;br /&gt;
                    &amp;lt;/thead&amp;gt;&lt;br /&gt;
                    &amp;lt;% for index in 0 .. row.score_row.length - 1 %&amp;gt;&lt;br /&gt;
                        &amp;lt;tr&amp;gt;&lt;br /&gt;
                          &amp;lt;% if @current_role_name.eql?'Student' or vm.questionnaire_type != &amp;quot;TeammateReviewQuestionnaire&amp;quot; %&amp;gt;&lt;br /&gt;
                            &amp;lt;%# Use Review {{index}} format for student view, and&lt;br /&gt;
                            when questionnaire_type is not teammatereview %&amp;gt;&lt;br /&gt;
                            &amp;lt;td&amp;gt;Review &amp;lt;%=index + 1%&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
                          &amp;lt;% else %&amp;gt;&lt;br /&gt;
                            &amp;lt;td&amp;gt;&lt;br /&gt;
                              &amp;lt;% reviewer_id = row.score_row[index].reviewer_id %&amp;gt;&lt;br /&gt;
                              &amp;lt;% fullname = Participant.find_by(id: reviewer_id).fullname(session[:ip]) %&amp;gt;&lt;br /&gt;
                              Review by &amp;lt;%= fullname %&amp;gt;&lt;br /&gt;
                            &amp;lt;/td&amp;gt;&lt;br /&gt;
                          &amp;lt;% end%&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
====G. In spec/controllers/grades_controller_spec.rb:====&lt;br /&gt;
&lt;br /&gt;
'''G.1 '''&lt;br /&gt;
&lt;br /&gt;
Old code&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
before(:each) do&lt;br /&gt;
  allow(AssignmentParticipant).to receive(:find).with('1').and_return(participant)&lt;br /&gt;
  allow(participant).to receive(:team).and_return(team)&lt;br /&gt;
  stub_current_user(instructor, instructor.role.name, instructor.role)&lt;br /&gt;
  allow(Assignment).to receive(:find).with('1').and_return(assignment)&lt;br /&gt;
@@ -91,29 +90,106 @@&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
New code&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
before(:each) do&lt;br /&gt;
  allow(participant).to receive(:team).and_return(team)&lt;br /&gt;
  stub_current_user(instructor, instructor.role.name, instructor.role)&lt;br /&gt;
  allow(Assignment).to receive(:find).with('1').and_return(assignment)&lt;br /&gt;
@@ -91,29 +90,106 @@&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''G.2 '''Remove xdescribe '#view_team' and change describe '#view_team' as follows.&lt;br /&gt;
&lt;br /&gt;
Old code&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
describe '#view_team' do&lt;br /&gt;
render_views&lt;br /&gt;
context 'when view_team page is viewed by a student who is also a TA for another course' do&lt;br /&gt;
  it 'renders grades#view_team page' do&lt;br /&gt;
    allow(participant).to receive(:team).and_return(team)&lt;br /&gt;
    allow(AssignmentQuestionnaire).to receive(:find_by).with(assignment_id: 1, questionnaire_id: 1).and_return(assignment_questionnaire)&lt;br /&gt;
    allow(AssignmentQuestionnaire).to receive(:where).with(any_args).and_return([assignment_questionnaire])&lt;br /&gt;
    allow(assignment).to receive(:late_policy_id).and_return(false)&lt;br /&gt;
    allow(assignment).to receive(:calculate_penalty).and_return(false)&lt;br /&gt;
    allow(assignment).to receive(:compute_total_score).with(any_args).and_return(100)&lt;br /&gt;
    allow(review_questionnaire).to receive(:get_assessments_round_for).with(participant, 1).and_return([review_response])&lt;br /&gt;
    allow(Answer).to receive(:compute_scores).with([review_response], [question]).and_return(max: 95, min: 88, avg: 90)&lt;br /&gt;
    params = {id: 1}&lt;br /&gt;
    allow(TaMapping).to receive(:exists?).with(ta_id: 1, course_id: 1).and_return(true)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
New code&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
describe '#view_team' do&lt;br /&gt;
render_views&lt;br /&gt;
&lt;br /&gt;
# All stubs and factories are instantiated within this scope so as to not &lt;br /&gt;
# clash with other broken test.&lt;br /&gt;
# The names of the factories created for testing view_team&lt;br /&gt;
# have `_vt` suffix ```where necessary``` to differentiate them from &lt;br /&gt;
# the above declared factories&lt;br /&gt;
&lt;br /&gt;
let(:student1_vt) { create(:student, name: &amp;quot;barry&amp;quot;, id: 12) }&lt;br /&gt;
let(:student2_vt) { create(:student, name: &amp;quot;iris&amp;quot;, id: 13) }&lt;br /&gt;
&lt;br /&gt;
let(:tm_questionnaire) {&lt;br /&gt;
  build(&lt;br /&gt;
    :teammate_review_questionnaire,&lt;br /&gt;
    id: 12,&lt;br /&gt;
    questions: [question],&lt;br /&gt;
    max_question_score: 5&lt;br /&gt;
  )&lt;br /&gt;
}&lt;br /&gt;
let(:assignment_vt) {&lt;br /&gt;
  create(:assignment, id: 6, max_team_size: 2,&lt;br /&gt;
  questionnaires: [tm_questionnaire])&lt;br /&gt;
}&lt;br /&gt;
let(:assignment_questionnaire_vt) {&lt;br /&gt;
  create(:tm_assignment_questionnaire, id: 12, used_in_round: nil,&lt;br /&gt;
  assignment: assignment_vt, questionnaire: tm_questionnaire) }&lt;br /&gt;
let(:team_vt) { create(:assignment_team, id: 12,&lt;br /&gt;
assignment: assignment_vt) }&lt;br /&gt;
let(:participant_vt) { create(:participant, id: 12,&lt;br /&gt;
  assignment: assignment_vt, user_id: student1_vt.id) }&lt;br /&gt;
let(:participant2_vt) { create(:participant, id: 13,&lt;br /&gt;
  assignment: assignment_vt, user_id: student2_vt.id) }&lt;br /&gt;
&lt;br /&gt;
before(:each) do&lt;br /&gt;
  # Need to stub this method so the factory instance with&lt;br /&gt;
  # the stubbed :team method is returned by :find&lt;br /&gt;
  # instead of a separate instance with the same data&lt;br /&gt;
  allow(AssignmentParticipant)&lt;br /&gt;
    .to receive(:find)&lt;br /&gt;
    .with(participant_vt.id.to_s)&lt;br /&gt;
    .and_return(participant_vt)&lt;br /&gt;
  allow(participant_vt).to receive(:team).and_return(team_vt)&lt;br /&gt;
  allow(team_vt).to receive(:participants).and_return([participant_vt, participant2_vt])&lt;br /&gt;
  allow(AssignmentQuestionnaire)&lt;br /&gt;
    .to receive(:find_by)&lt;br /&gt;
    .with(assignment_id: assignment_vt.id, questionnaire_id: tm_questionnaire.id)&lt;br /&gt;
    .and_return(assignment_questionnaire_vt)&lt;br /&gt;
  allow(AssignmentQuestionnaire)&lt;br /&gt;
    .to receive(:find_by)&lt;br /&gt;
    .with(assignment_id: assignment.id, questionnaire_id: review_questionnaire.id)&lt;br /&gt;
    .and_return(assignment_questionnaire_vt)&lt;br /&gt;
  allow(AssignmentQuestionnaire)&lt;br /&gt;
    .to receive(:where)&lt;br /&gt;
    .with(any_args)&lt;br /&gt;
    .and_return([assignment_questionnaire_vt])&lt;br /&gt;
  allow(assignment_vt)&lt;br /&gt;
    .to receive(:late_policy_id)&lt;br /&gt;
    .and_return(false)&lt;br /&gt;
  allow(assignment_vt)&lt;br /&gt;
    .to receive(:calculate_penalty)&lt;br /&gt;
    .and_return(false)&lt;br /&gt;
  allow(assignment_vt)&lt;br /&gt;
    .to receive(:compute_total_score)&lt;br /&gt;
    .with(any_args)&lt;br /&gt;
    .and_return(100)&lt;br /&gt;
  allow(review_questionnaire).to receive(:get_assessments_round_for).with(participant, 1).and_return([review_response])&lt;br /&gt;
  allow(Answer).to receive(:compute_scores).with([review_response], [question]).and_return(max: 95, min: 88, avg: 90)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
 it 'renders grades#view_team page' do&lt;br /&gt;
  params = {id: participant_vt.id}&lt;br /&gt;
  get :view_team, params&lt;br /&gt;
  expect(response).to render_template(:view_team)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
context 'when view_team page is opened by student' do&lt;br /&gt;
  it 'dropdown is not rendered' do&lt;br /&gt;
    session = { user: student1_vt }&lt;br /&gt;
    params = {id: participant_vt.id}&lt;br /&gt;
    stub_current_user(student1_vt, student1_vt.role.name, student1_vt.role)&lt;br /&gt;
    get :view_team, params&lt;br /&gt;
    expect(response.body).to_not have_selector('select')&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
context 'when view_team page is opened by instructor' do&lt;br /&gt;
  it 'dropdown is rendered' do&lt;br /&gt;
    session = { user: instructor }&lt;br /&gt;
    params = {id: participant_vt.id}&lt;br /&gt;
    get :view_team, params&lt;br /&gt;
    expect(response.body).to have_selector('select')&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
context 'when view_team page is viewed by a student who is also a TA for another course' do&lt;br /&gt;
  it 'renders grades#view_team page' do&lt;br /&gt;
    params = { id: participant_vt.id }&lt;br /&gt;
    allow(TaMapping).to receive(:exists?).with(ta_id: participant_vt.user_id, course_id: 1).and_return(true)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
====H. In spec/factories/factories.rb:====&lt;br /&gt;
&lt;br /&gt;
'''H.1 '''Add the following factory:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
factory :teammate_review_questionnaire, class: TeammateReviewQuestionnaire do&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''H.2 '''Add another factory&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
factory :tm_assignment_questionnaire, class: AssignmentQuestionnaire do&lt;br /&gt;
  user_id 1&lt;br /&gt;
  questionnaire { association(:teammate_review_questionnaire) }&lt;br /&gt;
  questionnaire_weight 100&lt;br /&gt;
  used_in_round nil&lt;br /&gt;
  topic_id nil&lt;br /&gt;
  dropdown 1&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Summary of file changes ===&lt;br /&gt;
&lt;br /&gt;
The following files are modified:&lt;br /&gt;
&lt;br /&gt;
1. app/controllers/grades_controller.rb - Controller file which changed how the view model is populated&lt;br /&gt;
&lt;br /&gt;
2. app/views/grades/view_team.html.erb - View file, which  conditionally rendered the teammate name, for a teammate review heatgrid&lt;br /&gt;
&lt;br /&gt;
3. spec/controllers/grades_controller_spec.rb - For tests verifying the proposed changes&lt;br /&gt;
&lt;br /&gt;
4. app/models/vm_question_response.rb - To modify the view-model so it can tell us the name of the person being reviewed for the current heatgrid&lt;br /&gt;
&lt;br /&gt;
5. app/models/vm_question_response_score_cell.rb - &lt;br /&gt;
&lt;br /&gt;
6. app/assets/stylesheets/grades.scss - &lt;br /&gt;
&lt;br /&gt;
7. app/views/grades/_add_icon_to_name.html.erb - &lt;br /&gt;
&lt;br /&gt;
8. spec/factories/factories.rb -&lt;br /&gt;
&lt;br /&gt;
== Design Patterns ==&lt;br /&gt;
&lt;br /&gt;
Existing code does not use any design patterns, apart from if-else. It uses if-else conditional statements to check what type of questionnaire is present in the viewmodel `VmQuestionResponse`, and based on that, it renders the appropriate content.&lt;br /&gt;
&lt;br /&gt;
We decided to continue with this approach since to change the present coding style, there were required many changes (refactoring) to many files which were out of the scope of the present project. To complete the project in the assigned time, we followed the if-else approach.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== User Stories ==&lt;br /&gt;
&lt;br /&gt;
1. As an instructor, I can view what reviews one teammate has given to other teammates.&lt;br /&gt;
&lt;br /&gt;
2. As a student, I can view what reviews my teammates have given to me.&lt;br /&gt;
&lt;br /&gt;
3. As an instructor, I can select if a student's reviews are anonymously shown to their teammates.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Testing ==&lt;br /&gt;
'''CURRENT STATUS'''&lt;br /&gt;
&lt;br /&gt;
1. Presently, the tests only cover if the view_team is page is rendered when it is asked for. This can be seen in the following link: &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''OUR PROPOSAL'''&lt;br /&gt;
&lt;br /&gt;
- When show_team is set as false by the professor, the student should not be able to see his scores.&lt;br /&gt;
&lt;br /&gt;
- When show_team is set as true by the professor, the student should be able to see his.&lt;br /&gt;
&lt;br /&gt;
- An instructor can select which student's scores he/she wants to see. If no student's name is selected then the professor can see the scores of all the students.&lt;br /&gt;
- The instructor can decide whether to show the names of the reviewer to the reviewer in teammate reviews, by selecting a checkbox for the same.&lt;br /&gt;
[[File:Untitled Diagram.drawio.png|border|center|alt=New UI for students|New UI for students ]]&lt;br /&gt;
&lt;br /&gt;
==References==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;https://expertiza.ncsu.edu/&amp;lt;/p&amp;gt;&lt;/div&gt;</summary>
		<author><name>Vdeshmu</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2021_-_E2165._Fix_teammate-review_view&amp;diff=141391</id>
		<title>CSC/ECE 517 Fall 2021 - E2165. Fix teammate-review view</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2021_-_E2165._Fix_teammate-review_view&amp;diff=141391"/>
		<updated>2021-11-09T02:40:05Z</updated>

		<summary type="html">&lt;p&gt;Vdeshmu: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Team Introduction ==&lt;br /&gt;
&lt;br /&gt;
Dr. Edward Gehringer (instructor), Parimal Mehta (mentor)&lt;br /&gt;
&lt;br /&gt;
1. Lalit Bangad (unity ID: llbangad)&lt;br /&gt;
&lt;br /&gt;
2. Vinay Deshmukh (unity ID: vdeshmu)&lt;br /&gt;
&lt;br /&gt;
3. Arvasu Chikara (unity ID: achikar2)&lt;br /&gt;
&lt;br /&gt;
4. Anjali Garg (unity ID : agarg25)   &lt;br /&gt;
&lt;br /&gt;
  &lt;br /&gt;
&lt;br /&gt;
== Problems to be addressed ==&lt;br /&gt;
&lt;br /&gt;
After a project is submitted and reviewed, both the team members (students) and instructors should be able to view the teammate reviews. Students should be able to view the reviews by going to a particular assignment's -&amp;gt; your scores, at the bottom of the page. An instructor can view the teammate reviews by going to assignments -&amp;gt; assignment -&amp;gt; particular team's submission -&amp;gt; view submission -&amp;gt; assign grades -&amp;gt; view scores. &lt;br /&gt;
&lt;br /&gt;
In the case of the instructor, a single heat grid is shown whereas in the case of a team member, we cant view the scores. In the heat grid, it is not clear if the scores visible are for the reviews that the student has *written* for their teammates or the scores that the student has *received* from their teammates. Additionally, for instructors can choose from a list of the students on the team, but they have no way to tell whether the heat grid shows the reviews done *by* that student or done *for* that student.&lt;br /&gt;
&lt;br /&gt;
== Methodology Overview ==&lt;br /&gt;
&lt;br /&gt;
We have divided our work in the following tasks to address the above problems:&lt;br /&gt;
&lt;br /&gt;
1. Distinguish reviews done for a student by rendering separates heatgrids for each student&lt;br /&gt;
&lt;br /&gt;
2. For instructors, the table will have sections based on the students&lt;br /&gt;
&lt;br /&gt;
3. Include a checkbox on the edit assignment page that enables/disables visibility of heat grid to students&lt;br /&gt;
&lt;br /&gt;
4. Fix the average column for a table (which breaks for some reviews)&lt;br /&gt;
&lt;br /&gt;
5. Show a composite score derived from all reviews.  Make this code generalized, so other kinds of heat grid views could use it.&lt;br /&gt;
&lt;br /&gt;
6. Changes should work even in an anonymized view&lt;br /&gt;
&lt;br /&gt;
== Motivations ==&lt;br /&gt;
&lt;br /&gt;
1. Enable users to clearly tell which reviews are done by them, and which reviews are done for them.&lt;br /&gt;
&lt;br /&gt;
2. Code should be generic so it can be used for different types of heat grids as well.&lt;br /&gt;
&lt;br /&gt;
== Control Flow to access the concerned screens ==&lt;br /&gt;
&lt;br /&gt;
== Models used / Explanation of fixes ==&lt;br /&gt;
&lt;br /&gt;
The below diagram illustrates the proposed code change for showing all team members with the teammate review data to an instructor. The existing code only iterated on the `Participant` whose ID is present in the URL of the page. To fix this, we will iterate over all teammates of the given participant so that all teammate reviews for all team members are shown to the instructor.&lt;br /&gt;
&lt;br /&gt;
[[File:Logic e2165.png|border|center|alt=Flow diagram of proposed changes for showing team review data to instructor]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Existing code:&lt;br /&gt;
&lt;br /&gt;
    questionnaires.each do |questionnaire|&lt;br /&gt;
      @round = nil&lt;br /&gt;
      if @assignment.vary_by_round &amp;amp;&amp;amp; questionnaire.type == &amp;quot;ReviewQuestionnaire&amp;quot;&lt;br /&gt;
        questionnaires = AssignmentQuestionnaire.where(assignment_id: @assignment.id, questionnaire_id: questionnaire.id)&lt;br /&gt;
        if questionnaires.count &amp;gt; 1&lt;br /&gt;
          @round = questionnaires[counter_for_same_rubric].used_in_round&lt;br /&gt;
          counter_for_same_rubric += 1&lt;br /&gt;
        else&lt;br /&gt;
          @round = questionnaires[0].used_in_round&lt;br /&gt;
          counter_for_same_rubric = 0&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
      &lt;br /&gt;
      # line which is causing the issue&lt;br /&gt;
      @vmlist &amp;lt;&amp;lt; populate_view_model(@participant, questionnaire, @team)&lt;br /&gt;
    end&lt;br /&gt;
        &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Modified code (replace the line which is causing issues):&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
      if questionnaire.display_type == &amp;quot;Teammate Review&amp;quot;&lt;br /&gt;
        # as teammate review will be different for each participant&lt;br /&gt;
        # we need to create a separate table for each teammate&lt;br /&gt;
        @participant.team.participants.each do |participant|&lt;br /&gt;
          @vmlist &amp;lt;&amp;lt; populate_view_model(participant, questionnaire, @team)&lt;br /&gt;
        end&lt;br /&gt;
      else&lt;br /&gt;
        # only one participant needs iterating, as apart from teammatereview&lt;br /&gt;
        # all other reviews are at &amp;quot;team&amp;quot; level&lt;br /&gt;
        @vmlist &amp;lt;&amp;lt; populate_view_model(@participant, questionnaire, @team)&lt;br /&gt;
      end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Image 1. Instructor's view of teammate review'''&lt;br /&gt;
[[File:Instructor-view-1.png|border|center|alt=The proposed expanded student display.|The proposed expanded student display.]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The `populate_view_model` returns an instance of `VmQuestionResponse`. This model represents the data required to render the table along with it's metadata, like `list_of_reviews` which is used to render the rows.&lt;br /&gt;
&lt;br /&gt;
== Present Status of the application ==&lt;br /&gt;
&lt;br /&gt;
'''Image 1. Instructor's view of teammate review''': This is the current screen given to the instructor. Here we see that the instructor can not determine who has given which review to which student.&lt;br /&gt;
&lt;br /&gt;
[[File:Instructor-view-1.png|border|center|alt=The proposed expanded student display.|The proposed expanded student display.]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Image 2. Student's view of teammate review''': Currently, a student is not able to see what grades were given by their teammates. We need to implement that functionality so that the student is able to view the grades.&lt;br /&gt;
&lt;br /&gt;
[[File:Student-view-2.png|border|center|alt=The current instructor view.|The current review display for instructors.]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Image 3. UML Diagram''': We are planning to add two variables namely showTeammateReview and hideReviewerName. showTeammateReview will decide whether the students would be able to view their team members reviews. hideReviewerName will decide whether the student is able to view peer's names or not.&lt;br /&gt;
[[File:Uml-assignment.png|border|center|alt=The proposed condensed student display.|The proposed condensed student display.]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Proposed changes ==&lt;br /&gt;
&lt;br /&gt;
1)''' Proposed UI for instructor ''': The instructor is able to see the score for all teammates. In the existing code, only one teammate's scores are being shown. But, we are planning to change the way the (VmQuestionResponse array is populated)[https://github.com/expertiza/expertiza/blob/master/app/controllers/grades_controller.rb#L114], so that the scores for all teammates are appended to it so it correctly shows what should have already been shown in this screen for the instructor.&lt;br /&gt;
&lt;br /&gt;
[[File:Proposed_screen.png|border|center|alt=Proposed UI for instructor|Proposed UI for instructor.]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Note: When a student visits this screen, they will only be shown the reviews received by them, assuming the instructor has allowed visibility of teammate reviews to students.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
2)''' Error in existing UI for student ''': In the existing UI for a student, the highlighted block should not be rendered. This part of the screen is meant for the instructors/TAs. This portion of the screen being rendered to a student is a mistake, and we will remove this part of the screen from the student's screen as part of our proposed changes.&lt;br /&gt;
&lt;br /&gt;
[[File:Wrong render for student.png|border|center|alt=Existing UI for student|Existing UI for student.]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
3)''' Show teammate review to student UI ''': The existing code doesn't render a student's teammate review scores at all. We are planning to render the scores to a student when they visit this screen. However, the visibility of this screen is contingent on whether the instructor has allowed visibility of the teammate review screen to students. If the instructor has disabled this feature, then the heatgrid will not be displayed at all.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[File:UI_for_student.png|border|center|alt=New UI for students|New UI for students ]]&lt;br /&gt;
&lt;br /&gt;
=== Files to be modified ===&lt;br /&gt;
&lt;br /&gt;
In the current design plan, the following files are planned to be edited:&lt;br /&gt;
&lt;br /&gt;
1. app/controllers/grades_controller.rb - Controller file which will change how the view model is populated&lt;br /&gt;
2. app/views/grades/view_team.html.erb - View file, which will conditionally render the teammate name, for a teammate review heatgrid&lt;br /&gt;
3. spec/controllers/grades_controller_spec.rb - For tests verifying the proposed changes&lt;br /&gt;
4. app/models/vm_question_response.rb - We need to modify the view-model so it can tell us the name of the person being reviewed for the current heatgrid&lt;br /&gt;
&lt;br /&gt;
Apart from these, there will be a schema change for the `Assignment` model, as we need to add the appropriate boolean flags&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Design Patterns ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Existing code does not use any design patterns, apart from if-else. It uses if-else conditional statements to check what type of questionnaire is present in the viewmodel `VmQuestionResponse`, and based on that, it renders the appropriate content.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
We can use decorator pattern, for handling the visibility of the heatgrid when rendering heatgrids for a student login.&lt;br /&gt;
&lt;br /&gt;
== User Stories ==&lt;br /&gt;
&lt;br /&gt;
1. As an instructor, I can view what reviews one teammate has given to other teammates.&lt;br /&gt;
&lt;br /&gt;
2. As a student, I can view what reviews my teammates have given to me.&lt;br /&gt;
&lt;br /&gt;
3. As an instructor, I can select if a student's reviews are anonymously shown to their teammates.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Testing ==&lt;br /&gt;
'''CURRENT STATUS'''&lt;br /&gt;
&lt;br /&gt;
1. Presently, the tests only cover if the view_team is page is rendered when it is asked for.&lt;br /&gt;
&lt;br /&gt;
[[File:current_testing_status.png|border|center|alt=New UI for students|New UI for students ]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''OUR PROPOSAL'''&lt;br /&gt;
&lt;br /&gt;
1. For a student:&lt;br /&gt;
&lt;br /&gt;
- When show_team is set as false, the student should not be able to see his scores.&lt;br /&gt;
&lt;br /&gt;
- When show_team is set as true, the student should be able to see his scores.&lt;br /&gt;
&lt;br /&gt;
2. For instructor:&lt;br /&gt;
&lt;br /&gt;
- Should be able to see all the scores by default.&lt;br /&gt;
&lt;br /&gt;
- The instructor can decide whether to show the names of the reviewer to the reviewer in teammate reviews, by selecting a checkbox for the same.&lt;br /&gt;
[[File:Untitled Diagram.drawio.png|border|center|alt=New UI for students|New UI for students ]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==References==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;https://expertiza.ncsu.edu/&amp;lt;/p&amp;gt;&lt;/div&gt;</summary>
		<author><name>Vdeshmu</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2021_-_E2165._Fix_teammate-review_view&amp;diff=141385</id>
		<title>CSC/ECE 517 Fall 2021 - E2165. Fix teammate-review view</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2021_-_E2165._Fix_teammate-review_view&amp;diff=141385"/>
		<updated>2021-11-09T02:29:42Z</updated>

		<summary type="html">&lt;p&gt;Vdeshmu: /* Proposed changes */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Team Introduction ==&lt;br /&gt;
&lt;br /&gt;
Dr. Edward Gehringer (instructor), Parimal Mehta (mentor)&lt;br /&gt;
&lt;br /&gt;
1. Lalit Bangad (unity ID: llbangad)&lt;br /&gt;
&lt;br /&gt;
2. Vinay Deshmukh (unity ID: vdeshmu)&lt;br /&gt;
&lt;br /&gt;
3. Arvasu Chikara (unity ID: achikar2)&lt;br /&gt;
&lt;br /&gt;
4. Anjali Garg (unity ID : agarg25)   &lt;br /&gt;
&lt;br /&gt;
  &lt;br /&gt;
&lt;br /&gt;
== Problems to be addressed ==&lt;br /&gt;
&lt;br /&gt;
After a project is submitted and reviewed, both the team members (students) and instructors should be able to view the teammate reviews. Students should be able to view the reviews by going to a particular assignment's -&amp;gt; your scores, at the bottom of the page. An instructor can view the teammate reviews by going to assignments -&amp;gt; assignment -&amp;gt; particular team's submission -&amp;gt; view submission -&amp;gt; assign grades -&amp;gt; view scores. &lt;br /&gt;
&lt;br /&gt;
In the case of the instructor, a single heat grid is shown whereas in the case of a team member, we cant view the scores. In the heat grid, it is not clear if the scores visible are for the reviews that the student has *written* for their teammates or the scores that the student has *received* from their teammates. Additionally, for instructors can choose from a list of the students on the team, but they have no way to tell whether the heat grid shows the reviews done *by* that student or done *for* that student.&lt;br /&gt;
&lt;br /&gt;
== Methodology Overview ==&lt;br /&gt;
&lt;br /&gt;
We have divided our work in the following tasks to address the above problems:&lt;br /&gt;
&lt;br /&gt;
1. Distinguish reviews done for a student by rendering separates heatgrids for each student&lt;br /&gt;
&lt;br /&gt;
2. For instructors, the table will have sections based on the students&lt;br /&gt;
&lt;br /&gt;
3. Include a checkbox on the edit assignment page that enables/disables visibility of heat grid to students&lt;br /&gt;
&lt;br /&gt;
4. Fix the average column for a table (which breaks for some reviews)&lt;br /&gt;
&lt;br /&gt;
5. Show a composite score derived from all reviews.  Make this code generalized, so other kinds of heat grid views could use it.&lt;br /&gt;
&lt;br /&gt;
6. Changes should work even in an anonymized view&lt;br /&gt;
&lt;br /&gt;
== Motivations ==&lt;br /&gt;
&lt;br /&gt;
1. Enable users to clearly tell which reviews are done by them, and which reviews are done for them.&lt;br /&gt;
&lt;br /&gt;
2. Code should be generic so it can be used for different types of heat grids as well.&lt;br /&gt;
&lt;br /&gt;
== Control Flow to access the concerned screens ==&lt;br /&gt;
&lt;br /&gt;
== Models used / Explanation of fixes ==&lt;br /&gt;
&lt;br /&gt;
The below diagram illustrates the proposed code change for showing all team members with the teammate review data to an instructor. The existing code only iterated on the `Participant` whose ID is present in the URL of the page. To fix this, we will iterate over all teammates of the given participant so that all teammate reviews for all team members are shown to the instructor.&lt;br /&gt;
&lt;br /&gt;
[[File:Logic e2165.png|border|center|alt=Flow diagram of proposed changes for showing team review data to instructor]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Existing code:&lt;br /&gt;
&lt;br /&gt;
    questionnaires.each do |questionnaire|&lt;br /&gt;
      @round = nil&lt;br /&gt;
      if @assignment.vary_by_round &amp;amp;&amp;amp; questionnaire.type == &amp;quot;ReviewQuestionnaire&amp;quot;&lt;br /&gt;
        questionnaires = AssignmentQuestionnaire.where(assignment_id: @assignment.id, questionnaire_id: questionnaire.id)&lt;br /&gt;
        if questionnaires.count &amp;gt; 1&lt;br /&gt;
          @round = questionnaires[counter_for_same_rubric].used_in_round&lt;br /&gt;
          counter_for_same_rubric += 1&lt;br /&gt;
        else&lt;br /&gt;
          @round = questionnaires[0].used_in_round&lt;br /&gt;
          counter_for_same_rubric = 0&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
      &lt;br /&gt;
      # line which is causing the issue&lt;br /&gt;
      @vmlist &amp;lt;&amp;lt; populate_view_model(@participant, questionnaire, @team)&lt;br /&gt;
    end&lt;br /&gt;
        &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Modified code (replace the line which is causing issues):&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
      if questionnaire.display_type == &amp;quot;Teammate Review&amp;quot;&lt;br /&gt;
        # as teammate review will be different for each participant&lt;br /&gt;
        # we need to create a separate table for each teammate&lt;br /&gt;
        @participant.team.participants.each do |participant|&lt;br /&gt;
          @vmlist &amp;lt;&amp;lt; populate_view_model(participant, questionnaire, @team)&lt;br /&gt;
        end&lt;br /&gt;
      else&lt;br /&gt;
        # only one participant needs iterating, as apart from teammatereview&lt;br /&gt;
        # all other reviews are at &amp;quot;team&amp;quot; level&lt;br /&gt;
        @vmlist &amp;lt;&amp;lt; populate_view_model(@participant, questionnaire, @team)&lt;br /&gt;
      end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Image 1. Instructor's view of teammate review'''&lt;br /&gt;
[[File:Instructor-view-1.png|border|center|alt=The proposed expanded student display.|The proposed expanded student display.]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The `populate_view_model` returns an instance of `VmQuestionResponse`. This model represents the data required to render the table along with it's metadata, like `list_of_reviews` which is used to render the rows.&lt;br /&gt;
&lt;br /&gt;
== Present Status of the application ==&lt;br /&gt;
&lt;br /&gt;
'''Image 1. Instructor's view of teammate review''': This is the current screen given to the instructor. Here we see that the instructor can not determine who has given which review to which student.&lt;br /&gt;
&lt;br /&gt;
[[File:Instructor-view-1.png|border|center|alt=The proposed expanded student display.|The proposed expanded student display.]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Image 2. Student's view of teammate review''': Currently, a student is not able to see what grades were given by their teammates. We need to implement that functionality so that the student is able to view the grades.&lt;br /&gt;
&lt;br /&gt;
[[File:Student-view-2.png|border|center|alt=The current instructor view.|The current review display for instructors.]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Image 3. UML Diagram''': We are planning to add two variables namely showTeammateReview and hideReviewerName. showTeammateReview will decide whether the students would be able to view their team members reviews. hideReviewerName will decide whether the student is able to view peer's names or not.&lt;br /&gt;
[[File:Uml-assignment.png|border|center|alt=The proposed condensed student display.|The proposed condensed student display.]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Proposed changes ==&lt;br /&gt;
&lt;br /&gt;
1)''' Proposed UI for instructor ''': The instructor is able to see the score for all teammates. In the existing code, only one teammate's scores are being shown. But, we are planning to change the way the (VmQuestionResponse array is populated)[https://github.com/expertiza/expertiza/blob/master/app/controllers/grades_controller.rb#L114], so that the scores for all teammates are appended to it so it correctly shows what should have already been shown in this screen for the instructor.&lt;br /&gt;
&lt;br /&gt;
[[File:Proposed_screen.png|border|center|alt=Proposed UI for instructor|Proposed UI for instructor.]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Note: When a student visits this screen, they will only be shown the reviews received by them, assuming the instructor has allowed visibility of teammate reviews to students.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
2)''' Error in existing UI for student ''': In the existing UI for a student, the highlighted block should not be rendered. This part of the screen is meant for the instructors/TAs. This portion of the screen being rendered to a student is a mistake, and we will remove this part of the screen from the student's screen as part of our proposed changes.&lt;br /&gt;
&lt;br /&gt;
[[File:Wrong render for student.png|border|center|alt=Existing UI for student|Existing UI for student.]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
3)''' Show teammate review to student UI ''': The existing code doesn't render a student's teammate review scores at all. We are planning to render the scores to a student when they visit this screen. However, the visibility of this screen is contingent on whether the instructor has allowed visibility of the teammate review screen to students. If the instructor has disabled this feature, then the heatgrid will not be displayed at all.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[File:UI_for_student.png|border|center|alt=New UI for students|New UI for students ]]&lt;br /&gt;
&lt;br /&gt;
== Design Patterns ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Existing code does not use any design patterns, apart from if-else. It uses if-else conditional statements to check what type of questionnaire is present in the viewmodel `VmQuestionResponse`, and based on that, it renders the appropriate content.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
We can use decorator pattern, for handling the visibility of the heatgrid when rendering heatgrids for a student login.&lt;br /&gt;
&lt;br /&gt;
== User Stories ==&lt;br /&gt;
&lt;br /&gt;
1. As an instructor, I can view what reviews one teammate has given to other teammates.&lt;br /&gt;
&lt;br /&gt;
2. As a student, I can view what reviews my teammates have given to me.&lt;br /&gt;
&lt;br /&gt;
3. As an instructor, I can select if a student's reviews are anonymously shown to their teammates.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Testing ==&lt;br /&gt;
'''CURRENT STATUS'''&lt;br /&gt;
&lt;br /&gt;
1. Presently, the tests only cover if the view_team is page is rendered when it is asked for.&lt;br /&gt;
&lt;br /&gt;
'''OUR PROPOSAL'''&lt;br /&gt;
&lt;br /&gt;
1. For a student:&lt;br /&gt;
&lt;br /&gt;
- When show_team is set as false, the student should not be able to see his scores.&lt;br /&gt;
&lt;br /&gt;
- When show_team is set as true, the student should be able to see his scores.&lt;br /&gt;
&lt;br /&gt;
2. For instructor:&lt;br /&gt;
&lt;br /&gt;
- Should be able to see all the scores by default.&lt;br /&gt;
&lt;br /&gt;
- The instructor can decide whether to show the names of the reviewer to the reviewer in teammate reviews, by selecting a checkbox for the same.&lt;br /&gt;
[[File:Untitled Diagram.drawio.png|border|center|alt=New UI for students|New UI for students ]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==References==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;https://expertiza.ncsu.edu/&amp;lt;/p&amp;gt;&lt;/div&gt;</summary>
		<author><name>Vdeshmu</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2021_-_E2165._Fix_teammate-review_view&amp;diff=141369</id>
		<title>CSC/ECE 517 Fall 2021 - E2165. Fix teammate-review view</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2021_-_E2165._Fix_teammate-review_view&amp;diff=141369"/>
		<updated>2021-11-09T01:51:40Z</updated>

		<summary type="html">&lt;p&gt;Vdeshmu: /* Design Patterns */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Team Introduction ==&lt;br /&gt;
&lt;br /&gt;
Dr. Edward Gehringer (instructor), Parimal Mehta (mentor)&lt;br /&gt;
&lt;br /&gt;
1. Lalit Bangad (unity ID: llbangad)&lt;br /&gt;
&lt;br /&gt;
2. Vinay Deshmukh (unity ID: vdeshmu)&lt;br /&gt;
&lt;br /&gt;
3. Arvasu Chikara (unity ID: achikar2)&lt;br /&gt;
&lt;br /&gt;
4. Anjali Garg (unity ID : agarg25)   &lt;br /&gt;
&lt;br /&gt;
  &lt;br /&gt;
&lt;br /&gt;
== Problems to be addressed ==&lt;br /&gt;
&lt;br /&gt;
After a project is submitted and reviewed, both the team members (students) and instructors should be able to view the teammate reviews. Students should be able to view the reviews by going to a particular assignment's -&amp;gt; your scores, at the bottom of the page. An instructor can view the teammate reviews by going to assignments -&amp;gt; assignment -&amp;gt; particular team's submission -&amp;gt; view submission -&amp;gt; assign grades -&amp;gt; view scores. &lt;br /&gt;
&lt;br /&gt;
In the case of the instructor, a single heat grid is shown whereas in the case of a team member, we cant view the scores. In the heat grid, it is not clear if the scores visible are for the reviews that the student has *written* for their teammates or the scores that the student has *received* from their teammates. Additionally, for instructors can choose from a list of the students on the team, but they have no way to tell whether the heat grid shows the reviews done *by* that student or done *for* that student.&lt;br /&gt;
&lt;br /&gt;
== Methodology Overview ==&lt;br /&gt;
&lt;br /&gt;
We have divided our work in the following tasks to address the above problems:&lt;br /&gt;
&lt;br /&gt;
1. Distinguish reviews done for a student by rendering separates heatgrids for each student&lt;br /&gt;
&lt;br /&gt;
2. For instructors, the table will have sections based on the students&lt;br /&gt;
&lt;br /&gt;
3. Include a checkbox on the edit assignment page that enables/disables visibility of heat grid to students&lt;br /&gt;
&lt;br /&gt;
4. Fix the average column for a table (which breaks for some reviews)&lt;br /&gt;
&lt;br /&gt;
5. Show a composite score derived from all reviews.  Make this code generalized, so other kinds of heat grid views could use it.&lt;br /&gt;
&lt;br /&gt;
6. Changes should work even in an anonymized view&lt;br /&gt;
&lt;br /&gt;
== Motivations ==&lt;br /&gt;
&lt;br /&gt;
1. Enable users to clearly tell which reviews are done by them, and which reviews are done for them.&lt;br /&gt;
&lt;br /&gt;
2. Code should be generic so it can be used for different types of heat grids as well.&lt;br /&gt;
&lt;br /&gt;
== Control Flow to access the concerned screens ==&lt;br /&gt;
&lt;br /&gt;
== Models used / Explanation of fixes ==&lt;br /&gt;
&lt;br /&gt;
The below diagram illustrates the proposed code change for showing all team members with the teammate review data to an instructor. The existing code only iterated on the `Participant` whose ID is present in the URL of the page. To fix this, we will iterate over all teammates of the given participant so that all teammate reviews for all team members are shown to the instructor.&lt;br /&gt;
&lt;br /&gt;
[[File:Logic e2165.png|border|center|alt=Flow diagram of proposed changes for showing team review data to instructor]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Existing code:&lt;br /&gt;
&lt;br /&gt;
    questionnaires.each do |questionnaire|&lt;br /&gt;
      @round = nil&lt;br /&gt;
      if @assignment.vary_by_round &amp;amp;&amp;amp; questionnaire.type == &amp;quot;ReviewQuestionnaire&amp;quot;&lt;br /&gt;
        questionnaires = AssignmentQuestionnaire.where(assignment_id: @assignment.id, questionnaire_id: questionnaire.id)&lt;br /&gt;
        if questionnaires.count &amp;gt; 1&lt;br /&gt;
          @round = questionnaires[counter_for_same_rubric].used_in_round&lt;br /&gt;
          counter_for_same_rubric += 1&lt;br /&gt;
        else&lt;br /&gt;
          @round = questionnaires[0].used_in_round&lt;br /&gt;
          counter_for_same_rubric = 0&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
      &lt;br /&gt;
      # line which is causing the issue&lt;br /&gt;
      @vmlist &amp;lt;&amp;lt; populate_view_model(@participant, questionnaire, @team)&lt;br /&gt;
    end&lt;br /&gt;
        &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Modified code (replace the line which is causing issues):&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
      if questionnaire.display_type == &amp;quot;Teammate Review&amp;quot;&lt;br /&gt;
        # as teammate review will be different for each participant&lt;br /&gt;
        # we need to create a separate table for each teammate&lt;br /&gt;
        @participant.team.participants.each do |participant|&lt;br /&gt;
          @vmlist &amp;lt;&amp;lt; populate_view_model(participant, questionnaire, @team)&lt;br /&gt;
        end&lt;br /&gt;
      else&lt;br /&gt;
        # only one participant needs iterating, as apart from teammatereview&lt;br /&gt;
        # all other reviews are at &amp;quot;team&amp;quot; level&lt;br /&gt;
        @vmlist &amp;lt;&amp;lt; populate_view_model(@participant, questionnaire, @team)&lt;br /&gt;
      end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Image 1. Instructor's view of teammate review'''&lt;br /&gt;
[[File:Instructor-view-1.png|border|center|alt=The proposed expanded student display.|The proposed expanded student display.]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The `populate_view_model` returns an instance of `VmQuestionResponse`. This model represents the data required to render the table along with it's metadata, like `list_of_reviews` which is used to render the rows.&lt;br /&gt;
&lt;br /&gt;
== Present Status of the application ==&lt;br /&gt;
&lt;br /&gt;
'''Image 1. Instructor's view of teammate review''': This is the current screen given to the instructor. Here we see that the instructor can not determine who has given which review to which student.&lt;br /&gt;
&lt;br /&gt;
[[File:Instructor-view-1.png|border|center|alt=The proposed expanded student display.|The proposed expanded student display.]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Image 2. Student's view of teammate review''': Currently, a student is not able to see what grades were given by their teammates. We need to implement that functionality so that the student is able to view the grades.&lt;br /&gt;
&lt;br /&gt;
[[File:Student-view-2.png|border|center|alt=The current instructor view.|The current review display for instructors.]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Image 3. UML Diagram''': We are planning to add two variables namely showTeammateReview and hideReviewerName. showTeammateReview will decide whether the students would be able to view their team members reviews. hideReviewerName will decide whether the student is able to view peer's names or not.&lt;br /&gt;
[[File:Uml-assignment.png|border|center|alt=The proposed condensed student display.|The proposed condensed student display.]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Proposed changes ==&lt;br /&gt;
&lt;br /&gt;
1)''' Proposed UI for instructor ''': The instructor is able to see the score for all teammates. In the existing code, only one teammate's scores are being shown. But, we are planning to change the way the VmQuestionResponse array is created, so that the scores for all teammates are appended to it so it correctly shows what should have already been shown in this screen for the instructor.&lt;br /&gt;
&lt;br /&gt;
[[File:Proposed_screen.png|border|center|alt=Proposed UI for instructor|Proposed UI for instructor.]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Note: When a student visits this screen, they will only be shown the reviews received by them, assuming the instructor has allowed visibility of teammate reviews to students.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
2)''' Error in existing UI for student ''': In the existing UI for a student, the highlighted block should not be rendered. This part of the screen is meant for the instructors/TAs. This portion of the screen being rendered to a student is a mistake, and we will remove this part of the screen from the student's screen as part of our proposed changes.&lt;br /&gt;
&lt;br /&gt;
[[File:Wrong render for student.png|border|center|alt=Existing UI for student|Existing UI for student.]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
3)''' Show teammate review to student UI ''': The existing code doesn't render a student's teammate review scores at all. We are planning to render the scores to a student when they visit this screen. However, the visibility of this screen is contingent on whether the instructor has allowed visibility of the teammate review screen to students. If the instructor has disabled this feature, then the heatgrid will not be displayed at all.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[File:UI_for_student.png|border|center|alt=New UI for students|New UI for students ]]&lt;br /&gt;
&lt;br /&gt;
== Design Patterns ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Existing code does not use any design patterns, apart from if-else. It uses if-else conditional statements to check what type of questionnaire is present in the viewmodel `VmQuestionResponse`, and based on that, it renders the appropriate content.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
We can use decorator pattern, for handling the visibility of the heatgrid when rendering heatgrids for a student login.&lt;br /&gt;
&lt;br /&gt;
== User Stories ==&lt;br /&gt;
&lt;br /&gt;
1. As an instructor, I can view what reviews one teammate has given to other teammates.&lt;br /&gt;
&lt;br /&gt;
2. As a student, I can view what reviews my teammates have given to me.&lt;br /&gt;
&lt;br /&gt;
3. As an instructor, I can select if a student's reviews are anonymously shown to their teammates.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Testing ==&lt;br /&gt;
&lt;br /&gt;
We will be using RSpec and Capybara for unit and functional testing. UI testing will be done manually.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==References==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;https://expertiza.ncsu.edu/&amp;lt;/p&amp;gt;&lt;/div&gt;</summary>
		<author><name>Vdeshmu</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2021_-_E2165._Fix_teammate-review_view&amp;diff=141362</id>
		<title>CSC/ECE 517 Fall 2021 - E2165. Fix teammate-review view</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2021_-_E2165._Fix_teammate-review_view&amp;diff=141362"/>
		<updated>2021-11-09T01:33:09Z</updated>

		<summary type="html">&lt;p&gt;Vdeshmu: /* Models used / Explanation of fixes */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Team Introduction ==&lt;br /&gt;
&lt;br /&gt;
Dr. Edward Gehringer (instructor), Parimal Mehta (mentor)&lt;br /&gt;
&lt;br /&gt;
1. Lalit Bangad (unity ID: llbangad)&lt;br /&gt;
&lt;br /&gt;
2. Vinay Deshmukh (unity ID: vdeshmu)&lt;br /&gt;
&lt;br /&gt;
3. Arvasu Chikara (unity ID: achikar2)&lt;br /&gt;
&lt;br /&gt;
4. Anjali Garg (unity ID : agarg25)   &lt;br /&gt;
&lt;br /&gt;
  &lt;br /&gt;
&lt;br /&gt;
== Problems to be addressed ==&lt;br /&gt;
&lt;br /&gt;
After a project is submitted and reviewed, both the team members (students) and instructors should be able to view the teammate reviews. Students should be able to view the reviews by going to a particular assignment's -&amp;gt; your scores, at the bottom of the page. An instructor can view the teammate reviews by going to assignments -&amp;gt; assignment -&amp;gt; particular team's submission -&amp;gt; view submission -&amp;gt; assign grades -&amp;gt; view scores. &lt;br /&gt;
&lt;br /&gt;
In the case of the instructor, a single heat grid is shown whereas in the case of a team member, we cant view the scores. In the heat grid, it is not clear if the scores visible are for the reviews that the student has *written* for their teammates or the scores that the student has *received* from their teammates. Additionally, for instructors can choose from a list of the students on the team, but they have no way to tell whether the heat grid shows the reviews done *by* that student or done *for* that student.&lt;br /&gt;
&lt;br /&gt;
== Methodology Overview ==&lt;br /&gt;
&lt;br /&gt;
We have divided our work in the following tasks to address the above problems:&lt;br /&gt;
&lt;br /&gt;
1. Distinguish reviews done for a student by rendering separates heatgrids for each student&lt;br /&gt;
&lt;br /&gt;
2. For instructors, the table will have sections based on the students&lt;br /&gt;
&lt;br /&gt;
3. Include a checkbox on the edit assignment page that enables/disables visibility of heat grid to students&lt;br /&gt;
&lt;br /&gt;
4. Fix the average column for a table (which breaks for some reviews)&lt;br /&gt;
&lt;br /&gt;
5. Show a composite score derived from all reviews.  Make this code generalized, so other kinds of heat grid views could use it.&lt;br /&gt;
&lt;br /&gt;
6. Changes should work even in an anonymized view&lt;br /&gt;
&lt;br /&gt;
== Motivations ==&lt;br /&gt;
&lt;br /&gt;
1. Enable users to clearly tell which reviews are done by them, and which reviews are done for them.&lt;br /&gt;
&lt;br /&gt;
2. Code should be generic so it can be used for different types of heat grids as well.&lt;br /&gt;
&lt;br /&gt;
== Control Flow to access the concerned screens ==&lt;br /&gt;
&lt;br /&gt;
== Models used / Explanation of fixes ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[File:Logic e2165.png|border|center|alt=Flow diagram of proposed changes for showing team review data to instructor]]&lt;br /&gt;
&lt;br /&gt;
The above diagram illustrates the proposed code change for showing all team members with the teammate review data to an instructor.&lt;br /&gt;
&lt;br /&gt;
The existing code only iterated on the `Participant` whose ID is present in the URL of the page. To fix this, we will iterate over all teammates of the given participant so that all teammate reviews for all team members are shown to the instructor.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Existing code:&lt;br /&gt;
&lt;br /&gt;
    questionnaires.each do |questionnaire|&lt;br /&gt;
      @round = nil&lt;br /&gt;
      if @assignment.vary_by_round &amp;amp;&amp;amp; questionnaire.type == &amp;quot;ReviewQuestionnaire&amp;quot;&lt;br /&gt;
        questionnaires = AssignmentQuestionnaire.where(assignment_id: @assignment.id, questionnaire_id: questionnaire.id)&lt;br /&gt;
        if questionnaires.count &amp;gt; 1&lt;br /&gt;
          @round = questionnaires[counter_for_same_rubric].used_in_round&lt;br /&gt;
          counter_for_same_rubric += 1&lt;br /&gt;
        else&lt;br /&gt;
          @round = questionnaires[0].used_in_round&lt;br /&gt;
          counter_for_same_rubric = 0&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
      &lt;br /&gt;
      # line which is causing the issue&lt;br /&gt;
      @vmlist &amp;lt;&amp;lt; populate_view_model(@participant, questionnaire, @team)&lt;br /&gt;
    end&lt;br /&gt;
        &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Modified code (replace the line which is causing issues):&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
      if questionnaire.display_type == &amp;quot;Teammate Review&amp;quot;&lt;br /&gt;
        # as teammate review will be different for each participant&lt;br /&gt;
        # we need to create a separate table for each teammate&lt;br /&gt;
        @participant.team.participants.each do |participant|&lt;br /&gt;
          @vmlist &amp;lt;&amp;lt; populate_view_model(participant, questionnaire, @team)&lt;br /&gt;
        end&lt;br /&gt;
      else&lt;br /&gt;
        # only one participant needs iterating, as apart from teammatereview&lt;br /&gt;
        # all other reviews are at &amp;quot;team&amp;quot; level&lt;br /&gt;
        @vmlist &amp;lt;&amp;lt; populate_view_model(@participant, questionnaire, @team)&lt;br /&gt;
      end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Image 1. Instructor's view of teammate review'''&lt;br /&gt;
[[File:Instructor-view-1.png|border|center|alt=The proposed expanded student display.|The proposed expanded student display.]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The `populate_view_model` returns an instance of `VmQuestionResponse`. This model represents the data required to render the table along with it's metadata, like `list_of_reviews` which is used to render the rows.&lt;br /&gt;
&lt;br /&gt;
== Present Status of the application ==&lt;br /&gt;
&lt;br /&gt;
'''Image 1. Instructor's view of teammate review''': This is the current screen given to the instructor. Here we see that the instructor can not determine who has given which review to which student.&lt;br /&gt;
&lt;br /&gt;
[[File:Instructor-view-1.png|border|center|alt=The proposed expanded student display.|The proposed expanded student display.]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Image 2. Student's view of teammate review''': Currently, a student is not able to see what grades were given by their teammates. We need to implement that functionality so that the student is able to view the grades.&lt;br /&gt;
&lt;br /&gt;
[[File:Student-view-2.png|border|center|alt=The current instructor view.|The current review display for instructors.]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Image 3. UML Diagram''': We are planning to add two variables namely showTeammateReview and hideReviewerName. showTeammateReview will decide whether the students would be able to view their team members reviews. hideReviewerName will decide whether the student is able to view peer's names or not.&lt;br /&gt;
[[File:Uml-assignment.png|border|center|alt=The proposed condensed student display.|The proposed condensed student display.]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Proposed changes ==&lt;br /&gt;
&lt;br /&gt;
1)''' Proposed UI for instructor ''': The instructor is able to see the score for all teammates. In the existing code, only one teammate's scores are being shown. But, we are planning to change the way the VmQuestionResponse array is created, so that the scores for all teammates are appended to it so it correctly shows what should have already been shown in this screen for the instructor.&lt;br /&gt;
&lt;br /&gt;
[[File:Proposed_screen.png|border|center|alt=Proposed UI for instructor|Proposed UI for instructor.]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Note: When a student visits this screen, they will only be shown the reviews received by them, assuming the instructor has allowed visibility of teammate reviews to students.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
2)''' Error in existing UI for student ''': In the existing UI for a student, the highlighted block should not be rendered. This part of the screen is meant for the instructors/TAs. This portion of the screen being rendered to a student is a mistake, and we will remove this part of the screen from the student's screen as part of our proposed changes.&lt;br /&gt;
&lt;br /&gt;
[[File:Wrong render for student.png|border|center|alt=Existing UI for student|Existing UI for student.]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
3)''' Show teammate review to student UI ''': The existing code doesn't render a student's teammate review scores at all. We are planning to render the scores to a student when they visit this screen. However, the visibility of this screen is contingent on whether the instructor has allowed visibility of the teammate review screen to students. If the instructor has disabled this feature, then the heatgrid will not be displayed at all.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[File:UI_for_student.png|border|center|alt=New UI for students|New UI for students ]]&lt;br /&gt;
&lt;br /&gt;
== Design Patterns ==&lt;br /&gt;
We think that we will be using Abstract Factory for our implementation but this may change as we further our development.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== User Stories ==&lt;br /&gt;
&lt;br /&gt;
1. As an instructor, I can view what reviews one teammate has given to other teammates.&lt;br /&gt;
&lt;br /&gt;
2. As a student, I can view what reviews my teammates have given to me.&lt;br /&gt;
&lt;br /&gt;
3. As an instructor, I can select if a student's reviews are anonymously shown to their teammates.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Testing ==&lt;br /&gt;
&lt;br /&gt;
We will be using RSpec and Capybara for unit and functional testing. UI testing will be done manually.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==References==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;https://expertiza.ncsu.edu/&amp;lt;/p&amp;gt;&lt;/div&gt;</summary>
		<author><name>Vdeshmu</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2021_-_E2165._Fix_teammate-review_view&amp;diff=141360</id>
		<title>CSC/ECE 517 Fall 2021 - E2165. Fix teammate-review view</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2021_-_E2165._Fix_teammate-review_view&amp;diff=141360"/>
		<updated>2021-11-09T01:32:14Z</updated>

		<summary type="html">&lt;p&gt;Vdeshmu: /* Models used / Explanation of issues */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Team Introduction ==&lt;br /&gt;
&lt;br /&gt;
Dr. Edward Gehringer (instructor), Parimal Mehta (mentor)&lt;br /&gt;
&lt;br /&gt;
1. Lalit Bangad (unity ID: llbangad)&lt;br /&gt;
&lt;br /&gt;
2. Vinay Deshmukh (unity ID: vdeshmu)&lt;br /&gt;
&lt;br /&gt;
3. Arvasu Chikara (unity ID: achikar2)&lt;br /&gt;
&lt;br /&gt;
4. Anjali Garg (unity ID : agarg25)   &lt;br /&gt;
&lt;br /&gt;
  &lt;br /&gt;
&lt;br /&gt;
== Problems to be addressed ==&lt;br /&gt;
&lt;br /&gt;
After a project is submitted and reviewed, both the team members (students) and instructors should be able to view the teammate reviews. Students should be able to view the reviews by going to a particular assignment's -&amp;gt; your scores, at the bottom of the page. An instructor can view the teammate reviews by going to assignments -&amp;gt; assignment -&amp;gt; particular team's submission -&amp;gt; view submission -&amp;gt; assign grades -&amp;gt; view scores. &lt;br /&gt;
&lt;br /&gt;
In the case of the instructor, a single heat grid is shown whereas in the case of a team member, we cant view the scores. In the heat grid, it is not clear if the scores visible are for the reviews that the student has *written* for their teammates or the scores that the student has *received* from their teammates. Additionally, for instructors can choose from a list of the students on the team, but they have no way to tell whether the heat grid shows the reviews done *by* that student or done *for* that student.&lt;br /&gt;
&lt;br /&gt;
== Methodology Overview ==&lt;br /&gt;
&lt;br /&gt;
We have divided our work in the following tasks to address the above problems:&lt;br /&gt;
&lt;br /&gt;
1. Distinguish reviews done for a student by rendering separates heatgrids for each student&lt;br /&gt;
&lt;br /&gt;
2. For instructors, the table will have sections based on the students&lt;br /&gt;
&lt;br /&gt;
3. Include a checkbox on the edit assignment page that enables/disables visibility of heat grid to students&lt;br /&gt;
&lt;br /&gt;
4. Fix the average column for a table (which breaks for some reviews)&lt;br /&gt;
&lt;br /&gt;
5. Show a composite score derived from all reviews.  Make this code generalized, so other kinds of heat grid views could use it.&lt;br /&gt;
&lt;br /&gt;
6. Changes should work even in an anonymized view&lt;br /&gt;
&lt;br /&gt;
== Motivations ==&lt;br /&gt;
&lt;br /&gt;
1. Enable users to clearly tell which reviews are done by them, and which reviews are done for them.&lt;br /&gt;
&lt;br /&gt;
2. Code should be generic so it can be used for different types of heat grids as well.&lt;br /&gt;
&lt;br /&gt;
== Control Flow to access the concerned screens ==&lt;br /&gt;
&lt;br /&gt;
== Models used / Explanation of fixes ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[File:Logic e2165.png|border|center|alt=Flow diagram of proposed changes for showing team review data to instructor]]&lt;br /&gt;
&lt;br /&gt;
The above diagram illustrates the proposed code change for showing all team members with the teammate review data to an instructor.&lt;br /&gt;
&lt;br /&gt;
The existing code only iterated on the `Participant` whose ID is present in the URL of the page. To fix this, we will iterate over all teammates of the given participant so that all teammate reviews for all team members are shown to the instructor.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Existing code:&lt;br /&gt;
```&lt;br /&gt;
    questionnaires.each do |questionnaire|&lt;br /&gt;
      @round = nil&lt;br /&gt;
      if @assignment.vary_by_round &amp;amp;&amp;amp; questionnaire.type == &amp;quot;ReviewQuestionnaire&amp;quot;&lt;br /&gt;
        questionnaires = AssignmentQuestionnaire.where(assignment_id: @assignment.id, questionnaire_id: questionnaire.id)&lt;br /&gt;
        if questionnaires.count &amp;gt; 1&lt;br /&gt;
          @round = questionnaires[counter_for_same_rubric].used_in_round&lt;br /&gt;
          counter_for_same_rubric += 1&lt;br /&gt;
        else&lt;br /&gt;
          @round = questionnaires[0].used_in_round&lt;br /&gt;
          counter_for_same_rubric = 0&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
      &lt;br /&gt;
      # line which is causing the issue&lt;br /&gt;
      @vmlist &amp;lt;&amp;lt; populate_view_model(@participant, questionnaire, @team)&lt;br /&gt;
    end&lt;br /&gt;
        &lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Modified code (replace above line):&lt;br /&gt;
&lt;br /&gt;
```&lt;br /&gt;
      if questionnaire.display_type == &amp;quot;Teammate Review&amp;quot;&lt;br /&gt;
        # as teammate review will be different for each participant&lt;br /&gt;
        # we need to create a separate table for each teammate&lt;br /&gt;
        @participant.team.participants.each do |participant|&lt;br /&gt;
          @vmlist &amp;lt;&amp;lt; populate_view_model(participant, questionnaire, @team)&lt;br /&gt;
        end&lt;br /&gt;
      else&lt;br /&gt;
        # only one participant needs iterating, as apart from teammatereview&lt;br /&gt;
        # all other reviews are at &amp;quot;team&amp;quot; level&lt;br /&gt;
        @vmlist &amp;lt;&amp;lt; populate_view_model(@participant, questionnaire, @team)&lt;br /&gt;
      end&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Image 1. Instructor's view of teammate review'''&lt;br /&gt;
[[File:Instructor-view-1.png|border|center|alt=The proposed expanded student display.|The proposed expanded student display.]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The `populate_view_model` returns an instance of `VmQuestionResponse`. This model represents the data required to render the table along with it's metadata, like `list_of_reviews` which is used to render the rows.&lt;br /&gt;
&lt;br /&gt;
== Present Status of the application ==&lt;br /&gt;
&lt;br /&gt;
'''Image 1. Instructor's view of teammate review'''&lt;br /&gt;
[[File:Instructor-view-1.png|border|center|alt=The proposed expanded student display.|The proposed expanded student display.]]&lt;br /&gt;
&lt;br /&gt;
This is the current screen given to the instructor. Instructor can not determine who has given which review to which student.&lt;br /&gt;
&lt;br /&gt;
'''Image 2. Student's view of teammate review'''&lt;br /&gt;
[[File:Student-view-2.png|border|center|alt=The current instructor view.|The current review display for instructors.]]&lt;br /&gt;
&lt;br /&gt;
Currently, student is not able to see what grades were given by their teammates. We need to implement that functionality so that the student is able to view the grades.&lt;br /&gt;
&lt;br /&gt;
'''Image 3. UML Diagram'''&lt;br /&gt;
[[File:Uml-assignment.png|border|center|alt=The proposed condensed student display.|The proposed condensed student display.]]&lt;br /&gt;
&lt;br /&gt;
We are planning to add two variables namely showTeammateReview and hideReviewerName. showTeammateReview will decide whether the students would be able to view their team members reviews. hideReviewerName will decide whether the student is able to view peer's names or not.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Proposed changes ==&lt;br /&gt;
&lt;br /&gt;
1)&lt;br /&gt;
&lt;br /&gt;
''' Proposed UI for instructor '''&lt;br /&gt;
&lt;br /&gt;
[[File:Proposed_screen.png|border|center|alt=Proposed UI for instructor|Proposed UI for instructor.]]&lt;br /&gt;
&lt;br /&gt;
The instructor is able to see the score for all teammates. In the existing code, only one teammate's scores are being shown. But, we are planning to change the way the VmQuestionResponse array is created, so that the scores for all teammates are appended to it so it correctly shows what should have already been shown in this screen for the instructor.&lt;br /&gt;
&lt;br /&gt;
Note: When a student visits this screen, they will only be shown the reviews received by them, assuming the instructor has allowed visibility of teammate reviews to students.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
2)&lt;br /&gt;
&lt;br /&gt;
''' Error in existing UI for student '''&lt;br /&gt;
&lt;br /&gt;
[[File:Wrong render for student.png|border|center|alt=Existing UI for student|Existing UI for student.]]&lt;br /&gt;
&lt;br /&gt;
In the existing UI for student, the highlighted block should not be rendered. This part of the screen is meant for the instructors/TAs. This portion of the screen being rendered to a student is a mistake, and we will remove this part of the screen from the student's screen as part of our proposed changes.&lt;br /&gt;
&lt;br /&gt;
3)&lt;br /&gt;
&lt;br /&gt;
''' Show teammate review to student UI '''&lt;br /&gt;
&lt;br /&gt;
[[File:UI_for_student.png|border|center|alt=New UI for students|New UI for students ]]&lt;br /&gt;
&lt;br /&gt;
The existing code doesn't render a student's teammate review scores at all. We are planning to render the scores to a student when they visit this screen. However, the visibility of this screen is contingent on whether the instructor has allowed visibility of the teammate review screen to students. If the instructor has disabled this feature, then the heatgrid will not be displayed at all.&lt;br /&gt;
&lt;br /&gt;
== Design Patterns ==&lt;br /&gt;
We think that we will be using Abstract Factory for our implementation but this may change as we further our development.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== User Stories ==&lt;br /&gt;
&lt;br /&gt;
1. As an instructor, I can view what reviews one teammate has given to other teammates.&lt;br /&gt;
&lt;br /&gt;
2. As a student, I can view what reviews my teammates have given to me.&lt;br /&gt;
&lt;br /&gt;
3. As an instructor, I can select if a student's reviews are anonymously shown to their teammates.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Testing ==&lt;br /&gt;
&lt;br /&gt;
We will be using RSpec and Capybara for unit and functional testing. UI testing will be done manually.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==References==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;https://expertiza.ncsu.edu/&amp;lt;/p&amp;gt;&lt;/div&gt;</summary>
		<author><name>Vdeshmu</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=File:Logic_e2165.png&amp;diff=141356</id>
		<title>File:Logic e2165.png</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=File:Logic_e2165.png&amp;diff=141356"/>
		<updated>2021-11-09T01:14:58Z</updated>

		<summary type="html">&lt;p&gt;Vdeshmu: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Vdeshmu</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2021_-_E2165._Fix_teammate-review_view&amp;diff=141355</id>
		<title>CSC/ECE 517 Fall 2021 - E2165. Fix teammate-review view</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2021_-_E2165._Fix_teammate-review_view&amp;diff=141355"/>
		<updated>2021-11-09T01:14:25Z</updated>

		<summary type="html">&lt;p&gt;Vdeshmu: /* Proposed changes */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Team Introduction ==&lt;br /&gt;
&lt;br /&gt;
Dr. Edward Gehringer (instructor), Parimal Mehta (mentor)&lt;br /&gt;
&lt;br /&gt;
1. Lalit Bangad (unity ID: llbangad)&lt;br /&gt;
&lt;br /&gt;
2. Vinay Deshmukh (unity ID: vdeshmu)&lt;br /&gt;
&lt;br /&gt;
3. Arvasu Chikara (unity ID: achikar2)&lt;br /&gt;
&lt;br /&gt;
4. Anjali Garg (unity ID : agarg25)   &lt;br /&gt;
&lt;br /&gt;
  &lt;br /&gt;
&lt;br /&gt;
== Problems to be addressed ==&lt;br /&gt;
&lt;br /&gt;
After a project is submitted and reviewed, both the team members (students) and instructors should be able to view the teammate reviews. Students should be able to view the reviews by going to a particular assignment's -&amp;gt; your scores, at the bottom of the page. An instructor can view the teammate reviews by going to assignments -&amp;gt; assignment -&amp;gt; particular team's submission -&amp;gt; view submission -&amp;gt; assign grades -&amp;gt; view scores. &lt;br /&gt;
&lt;br /&gt;
In the case of the instructor, a single heat grid is shown whereas in the case of a team member, we cant view the scores. In the heat grid, it is not clear if the scores visible are for the reviews that the student has *written* for their teammates or the scores that the student has *received* from their teammates. Additionally, for instructors can choose from a list of the students on the team, but they have no way to tell whether the heat grid shows the reviews done *by* that student or done *for* that student.&lt;br /&gt;
&lt;br /&gt;
== Methodology Overview ==&lt;br /&gt;
&lt;br /&gt;
We have divided our work in the following tasks to address the above problems:&lt;br /&gt;
&lt;br /&gt;
1. Distinguish reviews done for a student by rendering separates heatgrids for each student&lt;br /&gt;
&lt;br /&gt;
2. For instructors, the table will have sections based on the students&lt;br /&gt;
&lt;br /&gt;
3. Include a checkbox on the edit assignment page that enables/disables visibility of heat grid to students&lt;br /&gt;
&lt;br /&gt;
4. Fix the average column for a table (which breaks for some reviews)&lt;br /&gt;
&lt;br /&gt;
5. Show a composite score derived from all reviews.  Make this code generalized, so other kinds of heat grid views could use it.&lt;br /&gt;
&lt;br /&gt;
6. Changes should work even in an anonymized view&lt;br /&gt;
&lt;br /&gt;
== Motivations ==&lt;br /&gt;
&lt;br /&gt;
1. Enable users to clearly tell which reviews are done by them, and which reviews are done for them.&lt;br /&gt;
&lt;br /&gt;
2. Code should be generic so it can be used for different types of heat grids as well.&lt;br /&gt;
&lt;br /&gt;
== Control Flow to access the concerned screens ==&lt;br /&gt;
&lt;br /&gt;
== Models used / Explanation of issues ==&lt;br /&gt;
&lt;br /&gt;
// Insert draw.io diagram&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  &lt;br /&gt;
&lt;br /&gt;
== Present Status of the application ==&lt;br /&gt;
&lt;br /&gt;
'''Image 1. Instructor's view of teammate review'''&lt;br /&gt;
[[File:Instructor-view-1.png|border|center|alt=The proposed expanded student display.|The proposed expanded student display.]]&lt;br /&gt;
&lt;br /&gt;
This is the current screen given to the instructor. Instructor can not determine who has given which review to which student.&lt;br /&gt;
&lt;br /&gt;
'''Image 2. Student's view of teammate review'''&lt;br /&gt;
[[File:Student-view-2.png|border|center|alt=The current instructor view.|The current review display for instructors.]]&lt;br /&gt;
&lt;br /&gt;
Currently, student is not able to see what grades were given by their teammates. We need to implement that functionality so that the student is able to view the grades.&lt;br /&gt;
&lt;br /&gt;
'''Image 3. UML Diagram'''&lt;br /&gt;
[[File:Uml-assignment.png|border|center|alt=The proposed condensed student display.|The proposed condensed student display.]]&lt;br /&gt;
&lt;br /&gt;
We are planning to add two variables namely showTeammateReview and hideReviewerName. showTeammateReview will decide whether the students would be able to view their team members reviews. hideReviewerName will decide whether the student is able to view peer's names or not.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Proposed changes ==&lt;br /&gt;
&lt;br /&gt;
1)&lt;br /&gt;
&lt;br /&gt;
''' Proposed UI for instructor '''&lt;br /&gt;
&lt;br /&gt;
[[File:Proposed_screen.png|border|center|alt=Proposed UI for instructor|Proposed UI for instructor.]]&lt;br /&gt;
&lt;br /&gt;
The instructor is able to see the score for all teammates. In the existing code, only one teammate's scores are being shown. But, we are planning to change the way the VmQuestionResponse array is created, so that the scores for all teammates are appended to it so it correctly shows what should have already been shown in this screen for the instructor.&lt;br /&gt;
&lt;br /&gt;
Note: When a student visits this screen, they will only be shown the reviews received by them, assuming the instructor has allowed visibility of teammate reviews to students.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
2)&lt;br /&gt;
&lt;br /&gt;
''' Error in existing UI for student '''&lt;br /&gt;
&lt;br /&gt;
[[File:Wrong render for student.png|border|center|alt=Existing UI for student|Existing UI for student.]]&lt;br /&gt;
&lt;br /&gt;
In the existing UI for student, the highlighted block should not be rendered. This part of the screen is meant for the instructors/TAs. This portion of the screen being rendered to a student is a mistake, and we will remove this part of the screen from the student's screen as part of our proposed changes.&lt;br /&gt;
&lt;br /&gt;
3)&lt;br /&gt;
&lt;br /&gt;
''' Show teammate review to student UI '''&lt;br /&gt;
&lt;br /&gt;
[[File:UI_for_student.png|border|center|alt=New UI for students|New UI for students ]]&lt;br /&gt;
&lt;br /&gt;
The existing code doesn't render a student's teammate review scores at all. We are planning to render the scores to a student when they visit this screen. However, the visibility of this screen is contingent on whether the instructor has allowed visibility of the teammate review screen to students. If the instructor has disabled this feature, then the heatgrid will not be displayed at all.&lt;br /&gt;
&lt;br /&gt;
== Design Patterns ==&lt;br /&gt;
We think that we will be using Abstract Factory for our implementation but this may change as we further our development.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== User Stories ==&lt;br /&gt;
&lt;br /&gt;
1. As an instructor, I can view what reviews one teammate has given to other teammates.&lt;br /&gt;
&lt;br /&gt;
2. As a student, I can view what reviews my teammates have given to me.&lt;br /&gt;
&lt;br /&gt;
3. As an instructor, I can select if a student's reviews are anonymously shown to their teammates.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Testing ==&lt;br /&gt;
&lt;br /&gt;
We will be using RSpec and Capybara for unit and functional testing. UI testing will be done manually.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==References==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;https://expertiza.ncsu.edu/&amp;lt;/p&amp;gt;&lt;/div&gt;</summary>
		<author><name>Vdeshmu</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=File:Student-view-2.png&amp;diff=141354</id>
		<title>File:Student-view-2.png</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=File:Student-view-2.png&amp;diff=141354"/>
		<updated>2021-11-09T01:10:55Z</updated>

		<summary type="html">&lt;p&gt;Vdeshmu: Vdeshmu uploaded a new version of File:Student-view-2.png&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Vdeshmu</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2021_-_E2165._Fix_teammate-review_view&amp;diff=141353</id>
		<title>CSC/ECE 517 Fall 2021 - E2165. Fix teammate-review view</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2021_-_E2165._Fix_teammate-review_view&amp;diff=141353"/>
		<updated>2021-11-09T01:07:45Z</updated>

		<summary type="html">&lt;p&gt;Vdeshmu: /* Methodology Overview */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Team Introduction ==&lt;br /&gt;
&lt;br /&gt;
Dr. Edward Gehringer (instructor), Parimal Mehta (mentor)&lt;br /&gt;
&lt;br /&gt;
1. Lalit Bangad (unity ID: llbangad)&lt;br /&gt;
&lt;br /&gt;
2. Vinay Deshmukh (unity ID: vdeshmu)&lt;br /&gt;
&lt;br /&gt;
3. Arvasu Chikara (unity ID: achikar2)&lt;br /&gt;
&lt;br /&gt;
4. Anjali Garg (unity ID : agarg25)   &lt;br /&gt;
&lt;br /&gt;
  &lt;br /&gt;
&lt;br /&gt;
== Problems to be addressed ==&lt;br /&gt;
&lt;br /&gt;
After a project is submitted and reviewed, both the team members (students) and instructors should be able to view the teammate reviews. Students should be able to view the reviews by going to a particular assignment's -&amp;gt; your scores, at the bottom of the page. An instructor can view the teammate reviews by going to assignments -&amp;gt; assignment -&amp;gt; particular team's submission -&amp;gt; view submission -&amp;gt; assign grades -&amp;gt; view scores. &lt;br /&gt;
&lt;br /&gt;
In the case of the instructor, a single heat grid is shown whereas in the case of a team member, we cant view the scores. In the heat grid, it is not clear if the scores visible are for the reviews that the student has *written* for their teammates or the scores that the student has *received* from their teammates. Additionally, for instructors can choose from a list of the students on the team, but they have no way to tell whether the heat grid shows the reviews done *by* that student or done *for* that student.&lt;br /&gt;
&lt;br /&gt;
== Methodology Overview ==&lt;br /&gt;
&lt;br /&gt;
We have divided our work in the following tasks to address the above problems:&lt;br /&gt;
&lt;br /&gt;
1. Distinguish reviews done for a student by rendering separates heatgrids for each student&lt;br /&gt;
&lt;br /&gt;
2. For instructors, the table will have sections based on the students&lt;br /&gt;
&lt;br /&gt;
3. Include a checkbox on the edit assignment page that enables/disables visibility of heat grid to students&lt;br /&gt;
&lt;br /&gt;
4. Fix the average column for a table (which breaks for some reviews)&lt;br /&gt;
&lt;br /&gt;
5. Show a composite score derived from all reviews.  Make this code generalized, so other kinds of heat grid views could use it.&lt;br /&gt;
&lt;br /&gt;
6. Changes should work even in an anonymized view&lt;br /&gt;
&lt;br /&gt;
== Motivations ==&lt;br /&gt;
&lt;br /&gt;
1. Enable users to clearly tell which reviews are done by them, and which reviews are done for them.&lt;br /&gt;
&lt;br /&gt;
2. Code should be generic so it can be used for different types of heat grids as well.&lt;br /&gt;
&lt;br /&gt;
== Control Flow to access the concerned screens ==&lt;br /&gt;
&lt;br /&gt;
== Models used / Explanation of issues ==&lt;br /&gt;
&lt;br /&gt;
// Insert draw.io diagram&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  &lt;br /&gt;
&lt;br /&gt;
== Present Status of the application ==&lt;br /&gt;
&lt;br /&gt;
'''Image 1. Instructor's view of teammate review'''&lt;br /&gt;
[[File:Instructor-view-1.png|border|center|alt=The proposed expanded student display.|The proposed expanded student display.]]&lt;br /&gt;
&lt;br /&gt;
This is the current screen given to the instructor. Instructor can not determine who has given which review to which student.&lt;br /&gt;
&lt;br /&gt;
'''Image 2. Student's view of teammate review'''&lt;br /&gt;
[[File:Student-view-2.png|border|center|alt=The current instructor view.|The current review display for instructors.]]&lt;br /&gt;
&lt;br /&gt;
Currently, student is not able to see what grades were given by their teammates. We need to implement that functionality so that the student is able to view the grades.&lt;br /&gt;
&lt;br /&gt;
'''Image 3. UML Diagram'''&lt;br /&gt;
[[File:Uml-assignment.png|border|center|alt=The proposed condensed student display.|The proposed condensed student display.]]&lt;br /&gt;
&lt;br /&gt;
We are planning to add two variables namely showTeammateReview and hideReviewerName. showTeammateReview will decide whether the students would be able to view their team members reviews. hideReviewerName will decide whether the student is able to view peer's names or not.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Proposed changes ==&lt;br /&gt;
&lt;br /&gt;
1)&lt;br /&gt;
&lt;br /&gt;
''' Proposed UI for instructor '''&lt;br /&gt;
&lt;br /&gt;
[[File:Proposed_screen.png|border|center|alt=Proposed UI for instructor|Proposed UI for instructor.]]&lt;br /&gt;
&lt;br /&gt;
The instructor is able to see the score for all teammates. In the existing code, only one teammate's scores are being shown. But, we are planning to change the way the VmQuestionResponse array is created, so that the scores for all teammates are appended to it so it correctly shows what should have already been shown in this screen for the instructor.&lt;br /&gt;
&lt;br /&gt;
Note: When a student visits this screen, they will only be shown the reviews received by them, assuming the instructor has allowed visibility of teammate reviews to students.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
2)&lt;br /&gt;
&lt;br /&gt;
''' Error in existing UI for student '''&lt;br /&gt;
&lt;br /&gt;
[[File:Wrong render for student.png|border|center|alt=Existing UI for student|Existing UI for student.]]&lt;br /&gt;
&lt;br /&gt;
In the existing UI for student, the highlighted block should not be rendered. This part of the screen is meant for the instructors/TAs. This portion of the screen being rendered to a student is a mistake, and we will remove this part of the screen from the student's screen as part of our proposed changes.&lt;br /&gt;
&lt;br /&gt;
3)&lt;br /&gt;
&lt;br /&gt;
''' Show teammate review to student UI '''&lt;br /&gt;
&lt;br /&gt;
// TODO:&lt;br /&gt;
&lt;br /&gt;
[[File:UI_for_student.png|border|center|alt=New UI for students|New UI for students ]]&lt;br /&gt;
&lt;br /&gt;
The existing code doesn't render a student's teammate review scores at all. We are planning to render the scores to a student when they visit this screen. However, the visibility of this screen is contingent on whether the instructor has allowed visibility of the teammate review screen to students. If the instructor has disabled this feature, then the heatgrid will not be displayed at all.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Design Patterns ==&lt;br /&gt;
We think that we will be using Abstract Factory for our implementation but this may change as we further our development.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== User Stories ==&lt;br /&gt;
&lt;br /&gt;
1. As an instructor, I can view what reviews one teammate has given to other teammates.&lt;br /&gt;
&lt;br /&gt;
2. As a student, I can view what reviews my teammates have given to me.&lt;br /&gt;
&lt;br /&gt;
3. As an instructor, I can select if a student's reviews are anonymously shown to their teammates.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Testing ==&lt;br /&gt;
&lt;br /&gt;
We will be using RSpec and Capybara for unit and functional testing. UI testing will be done manually.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==References==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;https://expertiza.ncsu.edu/&amp;lt;/p&amp;gt;&lt;/div&gt;</summary>
		<author><name>Vdeshmu</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=File:Student-view-2.png&amp;diff=141341</id>
		<title>File:Student-view-2.png</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=File:Student-view-2.png&amp;diff=141341"/>
		<updated>2021-11-09T00:47:02Z</updated>

		<summary type="html">&lt;p&gt;Vdeshmu: Vdeshmu uploaded a new version of File:Student-view-2.png&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Vdeshmu</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=File:Student-view-2.png&amp;diff=141338</id>
		<title>File:Student-view-2.png</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=File:Student-view-2.png&amp;diff=141338"/>
		<updated>2021-11-09T00:45:16Z</updated>

		<summary type="html">&lt;p&gt;Vdeshmu: Vdeshmu uploaded a new version of File:Student-view-2.png&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Vdeshmu</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=File:Student-view-2.png&amp;diff=141336</id>
		<title>File:Student-view-2.png</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=File:Student-view-2.png&amp;diff=141336"/>
		<updated>2021-11-09T00:45:00Z</updated>

		<summary type="html">&lt;p&gt;Vdeshmu: Vdeshmu uploaded a new version of File:Student-view-2.png&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Vdeshmu</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=File:Student-view-2.png&amp;diff=141334</id>
		<title>File:Student-view-2.png</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=File:Student-view-2.png&amp;diff=141334"/>
		<updated>2021-11-09T00:43:50Z</updated>

		<summary type="html">&lt;p&gt;Vdeshmu: Vdeshmu uploaded a new version of File:Student-view-2.png&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Vdeshmu</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=File:Student-view-2.png&amp;diff=141331</id>
		<title>File:Student-view-2.png</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=File:Student-view-2.png&amp;diff=141331"/>
		<updated>2021-11-09T00:43:03Z</updated>

		<summary type="html">&lt;p&gt;Vdeshmu: Vdeshmu uploaded a new version of File:Student-view-2.png&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Vdeshmu</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=File:Student-view-2.png&amp;diff=141329</id>
		<title>File:Student-view-2.png</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=File:Student-view-2.png&amp;diff=141329"/>
		<updated>2021-11-09T00:41:52Z</updated>

		<summary type="html">&lt;p&gt;Vdeshmu: Vdeshmu uploaded a new version of File:Student-view-2.png&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Vdeshmu</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2021_-_E2165._Fix_teammate-review_view&amp;diff=141327</id>
		<title>CSC/ECE 517 Fall 2021 - E2165. Fix teammate-review view</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2021_-_E2165._Fix_teammate-review_view&amp;diff=141327"/>
		<updated>2021-11-09T00:36:38Z</updated>

		<summary type="html">&lt;p&gt;Vdeshmu: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Team Introduction ==&lt;br /&gt;
&lt;br /&gt;
Dr. Edward Gehringer (instructor), Parimal Mehta (mentor)&lt;br /&gt;
&lt;br /&gt;
1. Lalit Bangad (unity ID: llbangad)&lt;br /&gt;
&lt;br /&gt;
2. Vinay Deshmukh (unity ID: vdeshmu)&lt;br /&gt;
&lt;br /&gt;
3. Arvasu Chikara (unity ID: achikar2)&lt;br /&gt;
&lt;br /&gt;
4. Anjali Garg (unity ID : agarg25)   &lt;br /&gt;
&lt;br /&gt;
  &lt;br /&gt;
&lt;br /&gt;
== Problems to be addressed ==&lt;br /&gt;
&lt;br /&gt;
After a project is submitted and reviewed, both the team members (students) and instructors should be able to view the teammate reviews. Students should be able to view the reviews by going to a particular assignment's -&amp;gt; your scores, at the bottom of the page. An instructor can view the teammate reviews by going to assignments -&amp;gt; assignment -&amp;gt; particular team's submission -&amp;gt; view submission -&amp;gt; assign grades -&amp;gt; view scores. &lt;br /&gt;
&lt;br /&gt;
In the case of the instructor, a single heat grid is shown whereas in the case of a team member, we cant view the scores. In the heat grid, it is not clear if the scores visible are for the reviews that the student has *written* for their teammates or the scores that the student has *received* from their teammates. Additionally, for instructors can choose from a list of the students on the team, but they have no way to tell whether the heat grid shows the reviews done *by* that student or done *for* that student.&lt;br /&gt;
&lt;br /&gt;
== Methodology Overview ==&lt;br /&gt;
&lt;br /&gt;
We have divided our work in the following tasks to address the above problems:&lt;br /&gt;
&lt;br /&gt;
1. Distinguish reviews done by a student and for a student, by creating sections in the table&lt;br /&gt;
&lt;br /&gt;
2. For instructors, the table will have sections based on the students&lt;br /&gt;
&lt;br /&gt;
3. Include a checkbox on the edit assignment page that enables/disables visibility of heat grid to students&lt;br /&gt;
&lt;br /&gt;
4. Fix the average column for a table (which breaks for some reviews)&lt;br /&gt;
&lt;br /&gt;
5. Show a composite score derived from all reviews.  Make this code generalized, so other kinds of heat grid views could use it.&lt;br /&gt;
&lt;br /&gt;
6. Changes should work even in an anonymized view&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Motivations ==&lt;br /&gt;
&lt;br /&gt;
1. Enable users to clearly tell which reviews are done by them, and which reviews are done for them.&lt;br /&gt;
&lt;br /&gt;
2. Code should be generic so it can be used for different types of heat grids as well.&lt;br /&gt;
&lt;br /&gt;
== Control Flow to access the concerned screens ==&lt;br /&gt;
&lt;br /&gt;
== Models used / Explanation of issues ==&lt;br /&gt;
&lt;br /&gt;
// Insert draw.io diagram&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  &lt;br /&gt;
&lt;br /&gt;
== Present Status of the application ==&lt;br /&gt;
&lt;br /&gt;
'''Image 1. Instructor's view of teammate review'''&lt;br /&gt;
[[File:Instructor-view-1.png|border|center|alt=The proposed expanded student display.|The proposed expanded student display.]]&lt;br /&gt;
&lt;br /&gt;
This is the current screen given to the instructor. Instructor can not determine who has given which review to which student.&lt;br /&gt;
&lt;br /&gt;
'''Image 2. Student's view of teammate review'''&lt;br /&gt;
[[File:Student-view-2.png|border|center|alt=The current instructor view.|The current review display for instructors.]]&lt;br /&gt;
&lt;br /&gt;
Currently, student is not able to see what grades were given by their teammates. We need to implement that functionality so that the student is able to view the grades.&lt;br /&gt;
&lt;br /&gt;
'''Image 3. UML Diagram'''&lt;br /&gt;
[[File:Uml-assignment.png|border|center|alt=The proposed condensed student display.|The proposed condensed student display.]]&lt;br /&gt;
&lt;br /&gt;
We are planning to add two variables namely showTeammateReview and hideReviewerName. showTeammateReview will decide whether the students would be able to view their team members reviews. hideReviewerName will decide whether the student is able to view peer's names or not.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Proposed changes ==&lt;br /&gt;
&lt;br /&gt;
1)&lt;br /&gt;
&lt;br /&gt;
''' Proposed UI for instructor '''&lt;br /&gt;
&lt;br /&gt;
[[File:Proposed_screen.png|border|center|alt=Proposed UI for instructor|Proposed UI for instructor.]]&lt;br /&gt;
&lt;br /&gt;
The instructor is able to see the score for all teammates. In the existing code, only one teammate's scores are being shown. But, we are planning to change the way the VmQuestionResponse array is created, so that the scores for all teammates are appended to it so it correctly shows what should have already been shown in this screen for the instructor.&lt;br /&gt;
&lt;br /&gt;
Note: When a student visits this screen, they will only be shown the reviews received by them, assuming the instructor has allowed visibility of teammate reviews to students.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
2)&lt;br /&gt;
&lt;br /&gt;
''' Error in existing UI for student '''&lt;br /&gt;
&lt;br /&gt;
[[File:Wrong render for student.png|border|center|alt=Existing UI for student|Existing UI for student.]]&lt;br /&gt;
&lt;br /&gt;
In the existing UI for student, the highlighted block should not be rendered. This part of the screen is meant for the instructors/TAs. This portion of the screen being rendered to a student is a mistake, and we will remove this part of the screen from the student's screen as part of our proposed changes.&lt;br /&gt;
&lt;br /&gt;
3)&lt;br /&gt;
&lt;br /&gt;
''' Show teammate review to student UI '''&lt;br /&gt;
&lt;br /&gt;
// TODO:&lt;br /&gt;
&lt;br /&gt;
[[File:UI_for_student.png|border|center|alt=New UI for students|New UI for students ]]&lt;br /&gt;
&lt;br /&gt;
The existing code doesn't render a student's teammate review scores at all. We are planning to render the scores to a student when they visit this screen. However, the visibility of this screen is contingent on whether the instructor has allowed visibility of the teammate review screen to students. If the instructor has disabled this feature, then the heatgrid will not be displayed at all.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Design Patterns ==&lt;br /&gt;
We think that we will be using Abstract Factory for our implementation but this may change as we further our development.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== User Stories ==&lt;br /&gt;
&lt;br /&gt;
1. As an instructor, I can view what reviews one teammate has given to other teammates.&lt;br /&gt;
&lt;br /&gt;
2. As a student, I can view what reviews my teammates have given to me.&lt;br /&gt;
&lt;br /&gt;
3. As an instructor, I can select if a student's reviews are anonymously shown to their teammates.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Testing ==&lt;br /&gt;
&lt;br /&gt;
We will be using RSpec and Capybara for unit and functional testing. UI testing will be done manually.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==References==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;https://expertiza.ncsu.edu/&amp;lt;/p&amp;gt;&lt;/div&gt;</summary>
		<author><name>Vdeshmu</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=File:UI_for_student.png&amp;diff=141325</id>
		<title>File:UI for student.png</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=File:UI_for_student.png&amp;diff=141325"/>
		<updated>2021-11-09T00:34:37Z</updated>

		<summary type="html">&lt;p&gt;Vdeshmu: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Vdeshmu</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2021_-_E2165._Fix_teammate-review_view&amp;diff=141324</id>
		<title>CSC/ECE 517 Fall 2021 - E2165. Fix teammate-review view</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2021_-_E2165._Fix_teammate-review_view&amp;diff=141324"/>
		<updated>2021-11-09T00:31:08Z</updated>

		<summary type="html">&lt;p&gt;Vdeshmu: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Team Introduction ==&lt;br /&gt;
&lt;br /&gt;
Dr. Edward Gehringer (instructor), Parimal Mehta (mentor)&lt;br /&gt;
&lt;br /&gt;
1. Lalit Bangad (unity ID: llbangad)&lt;br /&gt;
&lt;br /&gt;
2. Vinay Deshmukh (unity ID: vdeshmu)&lt;br /&gt;
&lt;br /&gt;
3. Arvasu Chikara (unity ID: achikar2)&lt;br /&gt;
&lt;br /&gt;
4. Anjali Garg (unity ID : agarg25)   &lt;br /&gt;
&lt;br /&gt;
  &lt;br /&gt;
&lt;br /&gt;
== Problems to be addressed ==&lt;br /&gt;
&lt;br /&gt;
After a project is submitted and reviewed, both the team members (students) and instructors should be able to view the teammate reviews. Students should be able to view the reviews by going to a particular assignment's -&amp;gt; your scores, at the bottom of the page. An instructor can view the teammate reviews by going to assignments -&amp;gt; assignment -&amp;gt; particular team's submission -&amp;gt; view submission -&amp;gt; assign grades -&amp;gt; view scores. &lt;br /&gt;
&lt;br /&gt;
In the case of the instructor, a single heat grid is shown whereas in the case of a team member, we cant view the scores. In the heat grid, it is not clear if the scores visible are for the reviews that the student has *written* for their teammates or the scores that the student has *received* from their teammates. Additionally, for instructors can choose from a list of the students on the team, but they have no way to tell whether the heat grid shows the reviews done *by* that student or done *for* that student.&lt;br /&gt;
&lt;br /&gt;
== Methodology Overview ==&lt;br /&gt;
&lt;br /&gt;
We have divided our work in the following tasks to address the above problems:&lt;br /&gt;
&lt;br /&gt;
1. Distinguish reviews done by a student and for a student, by creating sections in the table&lt;br /&gt;
&lt;br /&gt;
2. For instructors, the table will have sections based on the students&lt;br /&gt;
&lt;br /&gt;
3. Include a checkbox on the edit assignment page that enables/disables visibility of heat grid to students&lt;br /&gt;
&lt;br /&gt;
4. Fix the average column for a table (which breaks for some reviews)&lt;br /&gt;
&lt;br /&gt;
5. Show a composite score derived from all reviews.  Make this code generalized, so other kinds of heat grid views could use it.&lt;br /&gt;
&lt;br /&gt;
6. Changes should work even in an anonymized view&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Motivations ==&lt;br /&gt;
&lt;br /&gt;
1. Enable users to clearly tell which reviews are done by them, and which reviews are done for them.&lt;br /&gt;
&lt;br /&gt;
2. Code should be generic so it can be used for different types of heat grids as well.&lt;br /&gt;
&lt;br /&gt;
  &lt;br /&gt;
&lt;br /&gt;
== Present Status of the application ==&lt;br /&gt;
&lt;br /&gt;
'''Image 1. Instructor's view of teammate review'''&lt;br /&gt;
[[File:Instructor-view-1.png|border|center|alt=The proposed expanded student display.|The proposed expanded student display.]]&lt;br /&gt;
&lt;br /&gt;
This is the current screen given to the instructor. Instructor can not determine who has given which review to which student.&lt;br /&gt;
&lt;br /&gt;
'''Image 2. Student's view of teammate review'''&lt;br /&gt;
[[File:Student-view-2.png|border|center|alt=The current instructor view.|The current review display for instructors.]]&lt;br /&gt;
&lt;br /&gt;
Currently, student is not able to see what grades were given by their teammates. We need to implement that functionality so that the student is able to view the grades.&lt;br /&gt;
&lt;br /&gt;
'''Image 3. UML Diagram'''&lt;br /&gt;
[[File:Uml-assignment.png|border|center|alt=The proposed condensed student display.|The proposed condensed student display.]]&lt;br /&gt;
&lt;br /&gt;
We are planning to add two variables namely showTeammateReview and hideReviewerName. showTeammateReview will decide whether the students would be able to view their team members reviews. hideReviewerName will decide whether the student is able to view peer's names or not.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Proposed changes ==&lt;br /&gt;
&lt;br /&gt;
1)&lt;br /&gt;
&lt;br /&gt;
''' Proposed UI for instructor '''&lt;br /&gt;
&lt;br /&gt;
[[File:Proposed_screen.png|border|center|alt=Proposed UI for instructor|Proposed UI for instructor.]]&lt;br /&gt;
&lt;br /&gt;
The instructor is able to see the score for all teammates. In the existing code, only one teammate's scores are being shown. But, we are planning to change the way the VmQuestionResponse array is created, so that the scores for all teammates are appended to it so it correctly shows what should have already been shown in this screen for the instructor.&lt;br /&gt;
&lt;br /&gt;
Note: When a student visits this screen, they will only be shown the reviews received by them, assuming the instructor has allowed visibility of teammate reviews to students.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
2)&lt;br /&gt;
&lt;br /&gt;
''' Error in existing UI for student '''&lt;br /&gt;
&lt;br /&gt;
[[File:Wrong render for student.png|border|center|alt=Existing UI for student|Existing UI for student.]]&lt;br /&gt;
&lt;br /&gt;
In the existing UI for student, the highlighted block should not be rendered. This part of the screen is meant for the instructors/TAs. This portion of the screen being rendered to a student is a mistake, and we will remove this part of the screen from the student's screen as part of our proposed changes.&lt;br /&gt;
&lt;br /&gt;
3)&lt;br /&gt;
&lt;br /&gt;
''' Show teammate review to student UI '''&lt;br /&gt;
&lt;br /&gt;
// TODO:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Design Patterns ==&lt;br /&gt;
We think that we will be using Abstract Factory for our implementation but this may change as we further our development.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== User Stories ==&lt;br /&gt;
&lt;br /&gt;
1. As an instructor, I can view what reviews one teammate has given to other teammates.&lt;br /&gt;
&lt;br /&gt;
2. As a student, I can view what reviews my teammates have given to me.&lt;br /&gt;
&lt;br /&gt;
3. As an instructor, I can select if a student's reviews are anonymously shown to their teammates.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Testing ==&lt;br /&gt;
&lt;br /&gt;
We will be using RSpec and Capybara for unit and functional testing. UI testing will be done manually.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==References==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;https://expertiza.ncsu.edu/&amp;lt;/p&amp;gt;&lt;/div&gt;</summary>
		<author><name>Vdeshmu</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=File:Wrong_render_for_student.png&amp;diff=141323</id>
		<title>File:Wrong render for student.png</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=File:Wrong_render_for_student.png&amp;diff=141323"/>
		<updated>2021-11-09T00:28:01Z</updated>

		<summary type="html">&lt;p&gt;Vdeshmu: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Vdeshmu</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2021_-_E2165._Fix_teammate-review_view&amp;diff=141322</id>
		<title>CSC/ECE 517 Fall 2021 - E2165. Fix teammate-review view</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2021_-_E2165._Fix_teammate-review_view&amp;diff=141322"/>
		<updated>2021-11-09T00:24:23Z</updated>

		<summary type="html">&lt;p&gt;Vdeshmu: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Team Introduction ==&lt;br /&gt;
&lt;br /&gt;
Dr. Edward Gehringer (instructor), Parimal Mehta (mentor)&lt;br /&gt;
&lt;br /&gt;
1. Lalit Bangad (unity ID: llbangad)&lt;br /&gt;
&lt;br /&gt;
2. Vinay Deshmukh (unity ID: vdeshmu)&lt;br /&gt;
&lt;br /&gt;
3. Arvasu Chikara (unity ID: achikar2)&lt;br /&gt;
&lt;br /&gt;
4. Anjali Garg (unity ID : agarg25)   &lt;br /&gt;
&lt;br /&gt;
  &lt;br /&gt;
&lt;br /&gt;
== Problems to be addressed ==&lt;br /&gt;
&lt;br /&gt;
After a project is submitted and reviewed, both the team members (students) and instructors should be able to view the teammate reviews. Students should be able to view the reviews by going to a particular assignment's -&amp;gt; your scores, at the bottom of the page. An instructor can view the teammate reviews by going to assignments -&amp;gt; assignment -&amp;gt; particular team's submission -&amp;gt; view submission -&amp;gt; assign grades -&amp;gt; view scores. &lt;br /&gt;
&lt;br /&gt;
In the case of the instructor, a single heat grid is shown whereas in the case of a team member, we cant view the scores. In the heat grid, it is not clear if the scores visible are for the reviews that the student has *written* for their teammates or the scores that the student has *received* from their teammates. Additionally, for instructors can choose from a list of the students on the team, but they have no way to tell whether the heat grid shows the reviews done *by* that student or done *for* that student.&lt;br /&gt;
&lt;br /&gt;
== Methodology Overview ==&lt;br /&gt;
&lt;br /&gt;
We have divided our work in the following tasks to address the above problems:&lt;br /&gt;
&lt;br /&gt;
1. Distinguish reviews done by a student and for a student, by creating sections in the table&lt;br /&gt;
&lt;br /&gt;
2. For instructors, the table will have sections based on the students&lt;br /&gt;
&lt;br /&gt;
3. Include a checkbox on the edit assignment page that enables/disables visibility of heat grid to students&lt;br /&gt;
&lt;br /&gt;
4. Fix the average column for a table (which breaks for some reviews)&lt;br /&gt;
&lt;br /&gt;
5. Show a composite score derived from all reviews.  Make this code generalized, so other kinds of heat grid views could use it.&lt;br /&gt;
&lt;br /&gt;
6. Changes should work even in an anonymized view&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Motivations ==&lt;br /&gt;
&lt;br /&gt;
1. Enable users to clearly tell which reviews are done by them, and which reviews are done for them.&lt;br /&gt;
&lt;br /&gt;
2. Code should be generic so it can be used for different types of heat grids as well.&lt;br /&gt;
&lt;br /&gt;
  &lt;br /&gt;
&lt;br /&gt;
== Present Status of the application ==&lt;br /&gt;
&lt;br /&gt;
'''Image 1. Instructor's view of teammate review'''&lt;br /&gt;
[[File:Instructor-view-1.png|border|center|alt=The proposed expanded student display.|The proposed expanded student display.]]&lt;br /&gt;
&lt;br /&gt;
This is the current screen given to the instructor. Instructor can not determine who has given which review to which student.&lt;br /&gt;
&lt;br /&gt;
'''Image 2. Student's view of teammate review'''&lt;br /&gt;
[[File:Student-view-2.png|border|center|alt=The current instructor view.|The current review display for instructors.]]&lt;br /&gt;
&lt;br /&gt;
Currently, student is not able to see what grades were given by their teammates. We need to implement that functionality so that the student is able to view the grades.&lt;br /&gt;
&lt;br /&gt;
'''Image 3. UML Diagram'''&lt;br /&gt;
[[File:Uml-assignment.png|border|center|alt=The proposed condensed student display.|The proposed condensed student display.]]&lt;br /&gt;
&lt;br /&gt;
We are planning to add two variables namely showTeammateReview and hideReviewerName. showTeammateReview will decide whether the students would be able to view their team members reviews. hideReviewerName will decide whether the student is able to view peer's names or not.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Proposed changes ==&lt;br /&gt;
&lt;br /&gt;
''' Proposed UI for instructor '''&lt;br /&gt;
&lt;br /&gt;
[[File:Proposed_screen.png|border|center|alt=Proposed UI for instructor|Proposed UI for instructor.]]&lt;br /&gt;
&lt;br /&gt;
The instructor is able to see the score for all teammates. In the existing code, only one teammate's scores are being shown. But, we are planning to change the way the VmQuestionResponse array is created, so that the scores for all teammates are appended to it so it correctly shows what should have already been shown in this screen for the instructor.&lt;br /&gt;
&lt;br /&gt;
Note: When a student visits this screen, they will only be shown the reviews received by them, assuming the instructor has allowed visibility of teammate reviews to students.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Design Patterns ==&lt;br /&gt;
We think that we will be using Abstract Factory for our implementation but this may change as we further our development.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== User Stories ==&lt;br /&gt;
&lt;br /&gt;
1. As an instructor, I can view what reviews one teammate has given to other teammates.&lt;br /&gt;
&lt;br /&gt;
2. As a student, I can view what reviews my teammates have given to me.&lt;br /&gt;
&lt;br /&gt;
3. As an instructor, I can select if a student's reviews are anonymously shown to their teammates.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Testing ==&lt;br /&gt;
&lt;br /&gt;
We will be using RSpec and Capybara for unit and functional testing. UI testing will be done manually.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==References==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;https://expertiza.ncsu.edu/&amp;lt;/p&amp;gt;&lt;/div&gt;</summary>
		<author><name>Vdeshmu</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=File:Proposed_screen.png&amp;diff=141321</id>
		<title>File:Proposed screen.png</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=File:Proposed_screen.png&amp;diff=141321"/>
		<updated>2021-11-09T00:19:08Z</updated>

		<summary type="html">&lt;p&gt;Vdeshmu: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Vdeshmu</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2021_-_E2165._Fix_teammate-review_view&amp;diff=140435</id>
		<title>CSC/ECE 517 Fall 2021 - E2165. Fix teammate-review view</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2021_-_E2165._Fix_teammate-review_view&amp;diff=140435"/>
		<updated>2021-11-02T18:41:29Z</updated>

		<summary type="html">&lt;p&gt;Vdeshmu: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Introduction ==&lt;br /&gt;
[https://expertiza.ncsu.edu/ Expertiza] is an open-source education and classroom web-tool founded by the [http://www.nsf.gov/ National Science Foundation]. Built with Ruby on Rails, it is designed to manage complete courses and students’ work within those courses. Each course can have a collection of instructors and students, though the interaction between instructors and students is minimal. The real emphasis of Expertiza is placed on peer-to-peer interactions, fostering a student-driven learning environment. Courses are comprised of assignments which users complete individually or with a team. Assignments usually encourage or require a team to enforce practicing peer-to-peer interaction.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Assignment ==&lt;br /&gt;
&lt;br /&gt;
=== Description ===&lt;br /&gt;
&lt;br /&gt;
The tasks of the assignment are as follows:&lt;br /&gt;
&lt;br /&gt;
# Distinguish reviews done by a student and for a student, by creating sections in the table&lt;br /&gt;
# For instructors, the table will have sections based on the students&lt;br /&gt;
# Include a checkbox on edit assignment page that enables/disables visibiity of heatgrid to students&lt;br /&gt;
# Fix average column for table (which breaks for some reviews)&lt;br /&gt;
# Show a composite score derived from all reviews.  Make this code generalized, so other kinds of heatgrid views could use it.&lt;br /&gt;
# Changes should work even in anonymized view&lt;br /&gt;
&lt;br /&gt;
=== Purpose ===&lt;br /&gt;
==== Motivations ====&lt;br /&gt;
* Enable users to clearly tell which reviews are done by them, and which reviews are done for them.&lt;br /&gt;
* Code should be generic so it can be used for different heatgrids as well&lt;br /&gt;
&lt;br /&gt;
==== Discussion ====&lt;br /&gt;
&lt;br /&gt;
// TODO:&lt;br /&gt;
There is no denying that the usability of viewing peer reviews leaves much to be desired. It lacks uniformity across the student and instructor roles, and the view itself has no semblance of order or organization. Viewing a single student’s review is a chore for both instructors and students, as there is no clear separation between reviews. In addition, all reviews are displayed at once, meaning viewing a single review requires scrolling through the page until the desired review is found. Our goal is to take the same data in the current display and present it in a more focused manner that allows a user, in either the instructor or student role, to absorb and process the content in the peer review more efficiently. Accessing, viewing, and understanding a review should be a far more simple task than what it currently is. In addition to the overhaul of the presentation layer, we also strive to drastically increase code reuse in the controller and model layers of the review module, which will in turn create a more uniform experience for both the instructor and student roles.&lt;br /&gt;
&lt;br /&gt;
=== Scope ===&lt;br /&gt;
&lt;br /&gt;
// TODO:&lt;br /&gt;
The scope of this task is limited to enhancing the usability of viewing peer reviews for both students and instructors. It is within our scope to modify the corresponding views for this functionality, as well as the underlying controllers and models as needed. The modifications to the Ruby classes will either be to accommodate changes to the view or to provide a uniform experience for both the instructor and student. As this is more of a user experience task, e.g, changing the way data is displayed to the user, there will be limited modifications to the base functionality of this module. It is not within our scope to change any element of the actual peer review process, such as selecting a topic to review or completing a review of a topic. As a result, we will not be modifying the results of peer reviews; the same peer review data will be present both before and after our task is completed.&lt;br /&gt;
&lt;br /&gt;
== Design ==&lt;br /&gt;
&lt;br /&gt;
=== Discussion of Resolution ===&lt;br /&gt;
The goal of this project is to optimize code and UI of review module, to make it more readable and user-friendly. To be more specific, our work focuses on the following specific areas:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* Add the checkbox to enable/disable visibility of heatgrid for students&lt;br /&gt;
* Modifying UI to clearly denote the reviews given by and for a student for both instructors and students&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Mock-Ups ===&lt;br /&gt;
&lt;br /&gt;
// TODO:&lt;br /&gt;
&lt;br /&gt;
[[File:Heatgrid_studen_condensed.png|border|center|alt=The proposed condensed student display.|The proposed condensed student display.]]&lt;br /&gt;
'''Image 2. The proposed student review report, in default collapsed view.'''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Text&lt;br /&gt;
&lt;br /&gt;
[[File:Heatgrid_student_expanded.png|border|center|alt=The proposed expanded student display.|The proposed expanded student display.]]&lt;br /&gt;
'''Image 3. The proposed student review report, in expanded view.'''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Text&lt;br /&gt;
&lt;br /&gt;
[[File:Current Instructor.PNG|border|center|alt=The current instructor view.|The current review display for instructors.]]&lt;br /&gt;
'''Image 4. Current design of the Instructor's Review Report.'''&lt;br /&gt;
&lt;br /&gt;
Text&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Design Patterns ===&lt;br /&gt;
The implementation team used following design patterns in the solution:&lt;br /&gt;
&lt;br /&gt;
* Pattern 1&lt;br /&gt;
* Pattern 2&lt;br /&gt;
&lt;br /&gt;
=== User Stories ===&lt;br /&gt;
&lt;br /&gt;
* Use 1&lt;br /&gt;
* Use 2&lt;br /&gt;
* Use 3&lt;br /&gt;
&lt;br /&gt;
=== Testing ===&lt;br /&gt;
Much of the testing was done informally during the development phase in the development database. Because the database was converted from the production environment, the development environment provide many opportunities for parallel testing between the view_my_scores (existing) and view_team (new) views. &lt;br /&gt;
&lt;br /&gt;
Some functional tests were completed with RSpec, but not many and probably not enough. This was because the scope of the project was large and the implementation team ran out of time before the deadline.  &lt;br /&gt;
&lt;br /&gt;
One situation where the parallel testing of the development environment provided limited value was with multi-round assignments and multi-round rubrics because the database came from production prior to the functionality being available in production. thus, in order to have sufficient tests, we created assignments new assignments, and new reviews in the development environment. The tests were not exhaustive, and probably not along the lines of TDD. &lt;br /&gt;
&lt;br /&gt;
=== Functional Tests ===&lt;br /&gt;
&lt;br /&gt;
* ColorMapping module: &lt;br /&gt;
&lt;br /&gt;
* Role Security Testing: &lt;br /&gt;
&lt;br /&gt;
* Char Comment Count Module: &lt;br /&gt;
&lt;br /&gt;
* Calculate Total Review Score: &lt;br /&gt;
&lt;br /&gt;
* Calculate Question Average Score: &lt;br /&gt;
&lt;br /&gt;
=== UI Tests ===&lt;br /&gt;
&lt;br /&gt;
UI will be tested manually, but also automatedly with [https://en.wikipedia.org/wiki/Selenium_(software) Selenium].&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Implementation ==&lt;br /&gt;
=== New Files ===&lt;br /&gt;
&lt;br /&gt;
=== Modified Files === &lt;br /&gt;
  &lt;br /&gt;
=== View Models: What, Why How. ===&lt;br /&gt;
Advantages:&lt;br /&gt;
* fast: The view_team view generates quickly compared to the view_my_scores. the main reason for this is that the view models only contain and retrieve what is necessary to populate the view. &lt;br /&gt;
&lt;br /&gt;
=== Javascript, JQuery, CSS tactics in the view_team view ===&lt;br /&gt;
There are 3 main mechanisms that need to be understood in order to modify the view_team view in future development tasks:&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;code&amp;gt;stylesheet grades.scss&amp;lt;/code&amp;gt; is used to create the heat grid effect, allowing users to quickly hone in on bad scores:&lt;br /&gt;
&lt;br /&gt;
[[File:Detailedreview2.png|border|center|alt=uml.|UML]]&lt;br /&gt;
&lt;br /&gt;
Text&lt;br /&gt;
&lt;br /&gt;
[[File:Rsz_screenshot_2015-12-04_235548.png|border|center|alt=uml.|UML]]&lt;br /&gt;
&lt;br /&gt;
Text&lt;br /&gt;
&lt;br /&gt;
[[File:detailedreview.png|border|center|alt=uml.|UML]]&lt;br /&gt;
&lt;br /&gt;
=== Users' Access of Report ===&lt;br /&gt;
'''see associated video for a visual walk-through here'''&lt;br /&gt;
* Instructors: Instructors will access the heat-grid view_team view via the grades/view . A 'heat grid' link appears for each participant.&lt;br /&gt;
* Students: Students will access the heat-grid via the student_task/view view, which already lists links available for a participant. &lt;br /&gt;
&lt;br /&gt;
=== UML &amp;amp; ER diagrams ===&lt;br /&gt;
&lt;br /&gt;
Below is a UML diagram of the main model classes used in our solution. &lt;br /&gt;
[[File:FinalProjUml2.png|border|center|alt=uml.|UML]]&lt;br /&gt;
&lt;br /&gt;
Below is a ER diagram of the added model classes used in our solution. &lt;br /&gt;
[[File:Er_vm2.png|border|center|alt=er.|ER]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Special Testing ===&lt;br /&gt;
Screenshot of a single round assignment review&lt;br /&gt;
[[File:Singleround.PNG|border|center|alt=singleround.|singleround]]&lt;br /&gt;
Screenshot of a multiround assignment review&lt;br /&gt;
[[File:Multi_no_vary.PNG|border|center|alt=Multi_no_vary.PNG.|Multi_no_vary.PNG]]&lt;br /&gt;
Screenshot of a vary-by-rubric review, with reviews for rounds 1 and 3, and blank 2.&lt;br /&gt;
[[File:Vary13.PNG|border|center|alt=Vary13.PNG.|Vary13.PNG]]&lt;br /&gt;
Screenshot of a vary-by-rubric review, with reviews for rounds 1 and 2, and blank 3.&lt;br /&gt;
[[File:Vary12.PNG|border|center|alt=Vary12.PNG.|Vary12.PNG]]&lt;br /&gt;
Screenshot of a vary-by-rubric review, with reviews for rounds 2 and 3, and blank 1.&lt;br /&gt;
[[Image:Vary23.PNG|border|center|alt=Vary23.PNG.|Vary23.PNG]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Future Enhancements==&lt;br /&gt;
* The project team may attempt to implement sorting of the lists and tables in in both the instructor and student review pages.&lt;br /&gt;
* The project team suggests that an instructor view of the heat grid be created, with lists all peer reviews for all teams stacked vertically on one page.&lt;br /&gt;
* The mock-ups above include suggested functionality for expanding all heatgrid rows. This was not implemented due to time limitations. &lt;br /&gt;
* Teammate review display have been suppressed such that they will not be displayed. At the end of the project, we realized that teammate reviews are hidden for the current semester, and we don't know how to implement that logic, so we suppressed teammate reviews to be safe. &lt;br /&gt;
==References==&lt;br /&gt;
&amp;lt;references/&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;https://expertiza.ncsu.edu/&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
// Add more&lt;/div&gt;</summary>
		<author><name>Vdeshmu</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2021&amp;diff=140434</id>
		<title>CSC/ECE 517 Fall 2021</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2021&amp;diff=140434"/>
		<updated>2021-11-02T18:04:32Z</updated>

		<summary type="html">&lt;p&gt;Vdeshmu: /* Final Projects */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== OSS Projects ==&lt;br /&gt;
&lt;br /&gt;
* [[CSC/ECE 517 Fall 2021 - E2117. Refactor questionaires_controller.rb]]&lt;br /&gt;
* [[CSC/ECE 517 Fall 2021 - E2128. Refactor student_quizzes_controller.rb &amp;amp; late_policies_controller.rb]]&lt;br /&gt;
* [[CSC/ECE 517 Fall 2021 - E2129. Refactor auth_controller.rb &amp;amp; password_retrieval_controller.rb]]&lt;br /&gt;
* [[CSC/ECE 517 Fall 2021 - E2132. Add tests cases for review mapping helper.rb]]&lt;br /&gt;
* [[CSC/ECE 517 Fall 2021 - E2134. Write unit tests for admin_controller.rb and institution_controller.rb]]&lt;br /&gt;
* [[CSC/ECE 517 Fall 2021 - E2138. Auto-generate submission directory names based on assignment]]&lt;br /&gt;
* [[CSC/ECE 517 Fall 2021 - E2142. Improve e-mail notifications]]&lt;br /&gt;
* [[CSC/ECE 517 Fall 2021 - E2133. Write tests for popup_controller.rb]]&lt;br /&gt;
* [[CSC/ECE 517 Fall 2021 - E2120. Refactor reputation_web_service_controller.rb]]&lt;br /&gt;
* [[CSC/ECE 517 Fall 2021 - E2139. Remove multiple topics at a time]]&lt;br /&gt;
* [[CSC/ECE 517 Fall 2021 - E2131. Improve assessment360_controller.rb]]&lt;br /&gt;
* [[CSC/ECE 517 Fall 2021 - E2121. Refactor suggestion_controller.rb]]&lt;br /&gt;
* [[CSC/ECE 517 Fall 2021 - E2122. Refactor impersonate_controller.rb]]&lt;br /&gt;
* [[CSC/ECE 517 Fall 2021 - E2123. Refactor sign_up_sheet_controller.rb]]&lt;br /&gt;
* [[CSC/ECE 517 Fall 2021 - E2126. Refactor account_request_controller.rb]]&lt;br /&gt;
* [[CSC/ECE 517 Fall 2021 - E2124. Refactor review_mapping_controller.rb]]&lt;br /&gt;
* [[CSC/ECE 517 Fall 2021 - E2125. Refactor review_mapping_helper.rb]]&lt;br /&gt;
* [[CSC/ECE 517 Fall 2021 - E2127. Refactor teams_controller]]&lt;br /&gt;
* [[CSC/ECE 517 Fall 2021 - E2130. Refactor submitted_content_controller.rb]]&lt;br /&gt;
* [[CSC/ECE 517 Fall 2021 - E2140. Create new late policy successfully and fix Bank link]]&lt;br /&gt;
* [[CSC/ECE 517 Fall 2021 - E2141. OSS project Finklestein: Instructors &amp;amp; Institutions]]&lt;br /&gt;
* [[CSC/ECE 517 Fall 2021 - E2144. Refactor delayed mailer and scheduled task]]&lt;br /&gt;
* [[CSC/ECE 517 Fall 2021 - E2147. Role-based reviewing]]&lt;br /&gt;
* [[CSC/ECE 517 Fall 2021 - E2145. OSS Project Beige]]&lt;br /&gt;
* [[CSC/ECE 517 Fall 2021 - E2146. Introduce a Student View for instructors]]&lt;br /&gt;
* [[CSC/ECE 517 Fall 2021 - Refactor Evaluation of SQL Queries]]&lt;br /&gt;
* [[CSC/ECE 517 Fall 2021 - E2135. Email notification to reviewers and instructors]]&lt;br /&gt;
* [[CSC/ECE 517 Fall 2021 - E2168. Testing - Reputations]]&lt;br /&gt;
* [[CSC/ECE 517 Fall 2021 - E2166. Testing - Scoring &amp;amp; Grades]]&lt;br /&gt;
* [[CSC/ECE 517 Fall 2021 - E2149. Finish Github metrics integration - Reputations]]&lt;br /&gt;
&lt;br /&gt;
== Final Projects ==&lt;br /&gt;
* [https://expertiza.csc.ncsu.edu/index.php/CSC/ECE_517_Fall_2021_-_E2152._Revision_planning_tool#Description_about_project CSC/ECE 517 Fall 2021 - E2152. Revision_planning_tool]&lt;br /&gt;
* [https://expertiza.csc.ncsu.edu/index.php/CSC/ECE_517_Fall_2021_-_E2170._Testing_-_Response_Maps#Description_about_project CSC/ECE 517 Fall 2021 - E2170. Testing - Response Maps]&lt;br /&gt;
* [https://expertiza.csc.ncsu.edu/index.php/CSC/ECE_517_Fall_2021_-_E2153._Improving_search_facility_in_Expertiza#Description_about_project CSC/ECE 517 Fall 2021 - E2153. Improving search facility in Expertiza]&lt;br /&gt;
* [https://expertiza.csc.ncsu.edu/index.php/CSC/ECE_517_Fall_2021_-_E2162._Further_refactoring_and_improvement_of_review_mapping_helper CSC/ECE 517 Fall 2021 - E2162. Further refactoring and improvement of review mapping helper]&lt;br /&gt;
* [https://expertiza.csc.ncsu.edu/index.php/CSC/ECE_517_Fall_2021_-_E2165._Fix_teammate-review_view CSC/ECE 517 Fall 2021 - E2165. Fix teammate review view ]&lt;/div&gt;</summary>
		<author><name>Vdeshmu</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2021&amp;diff=140433</id>
		<title>CSC/ECE 517 Fall 2021</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2021&amp;diff=140433"/>
		<updated>2021-11-02T18:02:07Z</updated>

		<summary type="html">&lt;p&gt;Vdeshmu: /* Final Projects */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== OSS Projects ==&lt;br /&gt;
&lt;br /&gt;
* [[CSC/ECE 517 Fall 2021 - E2117. Refactor questionaires_controller.rb]]&lt;br /&gt;
* [[CSC/ECE 517 Fall 2021 - E2128. Refactor student_quizzes_controller.rb &amp;amp; late_policies_controller.rb]]&lt;br /&gt;
* [[CSC/ECE 517 Fall 2021 - E2129. Refactor auth_controller.rb &amp;amp; password_retrieval_controller.rb]]&lt;br /&gt;
* [[CSC/ECE 517 Fall 2021 - E2132. Add tests cases for review mapping helper.rb]]&lt;br /&gt;
* [[CSC/ECE 517 Fall 2021 - E2134. Write unit tests for admin_controller.rb and institution_controller.rb]]&lt;br /&gt;
* [[CSC/ECE 517 Fall 2021 - E2138. Auto-generate submission directory names based on assignment]]&lt;br /&gt;
* [[CSC/ECE 517 Fall 2021 - E2142. Improve e-mail notifications]]&lt;br /&gt;
* [[CSC/ECE 517 Fall 2021 - E2133. Write tests for popup_controller.rb]]&lt;br /&gt;
* [[CSC/ECE 517 Fall 2021 - E2120. Refactor reputation_web_service_controller.rb]]&lt;br /&gt;
* [[CSC/ECE 517 Fall 2021 - E2139. Remove multiple topics at a time]]&lt;br /&gt;
* [[CSC/ECE 517 Fall 2021 - E2131. Improve assessment360_controller.rb]]&lt;br /&gt;
* [[CSC/ECE 517 Fall 2021 - E2121. Refactor suggestion_controller.rb]]&lt;br /&gt;
* [[CSC/ECE 517 Fall 2021 - E2122. Refactor impersonate_controller.rb]]&lt;br /&gt;
* [[CSC/ECE 517 Fall 2021 - E2123. Refactor sign_up_sheet_controller.rb]]&lt;br /&gt;
* [[CSC/ECE 517 Fall 2021 - E2126. Refactor account_request_controller.rb]]&lt;br /&gt;
* [[CSC/ECE 517 Fall 2021 - E2124. Refactor review_mapping_controller.rb]]&lt;br /&gt;
* [[CSC/ECE 517 Fall 2021 - E2125. Refactor review_mapping_helper.rb]]&lt;br /&gt;
* [[CSC/ECE 517 Fall 2021 - E2127. Refactor teams_controller]]&lt;br /&gt;
* [[CSC/ECE 517 Fall 2021 - E2130. Refactor submitted_content_controller.rb]]&lt;br /&gt;
* [[CSC/ECE 517 Fall 2021 - E2140. Create new late policy successfully and fix Bank link]]&lt;br /&gt;
* [[CSC/ECE 517 Fall 2021 - E2141. OSS project Finklestein: Instructors &amp;amp; Institutions]]&lt;br /&gt;
* [[CSC/ECE 517 Fall 2021 - E2144. Refactor delayed mailer and scheduled task]]&lt;br /&gt;
* [[CSC/ECE 517 Fall 2021 - E2147. Role-based reviewing]]&lt;br /&gt;
* [[CSC/ECE 517 Fall 2021 - E2145. OSS Project Beige]]&lt;br /&gt;
* [[CSC/ECE 517 Fall 2021 - E2146. Introduce a Student View for instructors]]&lt;br /&gt;
* [[CSC/ECE 517 Fall 2021 - Refactor Evaluation of SQL Queries]]&lt;br /&gt;
* [[CSC/ECE 517 Fall 2021 - E2135. Email notification to reviewers and instructors]]&lt;br /&gt;
* [[CSC/ECE 517 Fall 2021 - E2168. Testing - Reputations]]&lt;br /&gt;
* [[CSC/ECE 517 Fall 2021 - E2166. Testing - Scoring &amp;amp; Grades]]&lt;br /&gt;
* [[CSC/ECE 517 Fall 2021 - E2149. Finish Github metrics integration - Reputations]]&lt;br /&gt;
&lt;br /&gt;
== Final Projects ==&lt;br /&gt;
* [https://expertiza.csc.ncsu.edu/index.php/CSC/ECE_517_Fall_2021_-_E2152._Revision_planning_tool#Description_about_project CSC/ECE 517 Fall 2021 - E2152. Revision_planning_tool]&lt;br /&gt;
* [https://expertiza.csc.ncsu.edu/index.php/CSC/ECE_517_Fall_2021_-_E2170._Testing_-_Response_Maps#Description_about_project CSC/ECE 517 Fall 2021 - E2170. Testing - Response Maps]&lt;br /&gt;
* [https://expertiza.csc.ncsu.edu/index.php/CSC/ECE_517_Fall_2021_-_E2153._Improving_search_facility_in_Expertiza#Description_about_project CSC/ECE 517 Fall 2021 - E2153. Improving search facility in Expertiza]&lt;br /&gt;
* [https://expertiza.csc.ncsu.edu/index.php/CSC/ECE_517_Fall_2021_-_E2162._Further_refactoring_and_improvement_of_review_mapping_helper CSC/ECE 517 Fall 2021 - E2162. Further refactoring and improvement of review mapping helper]&lt;br /&gt;
* [[https://expertiza.csc.ncsu.edu/index.php/CSC/ECE_517_Fall_2021_-_E2165. Fix teammate-review view]]&lt;/div&gt;</summary>
		<author><name>Vdeshmu</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2021_-_E2165._Fix_teammate-review_view&amp;diff=140432</id>
		<title>CSC/ECE 517 Fall 2021 - E2165. Fix teammate-review view</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2021_-_E2165._Fix_teammate-review_view&amp;diff=140432"/>
		<updated>2021-11-02T18:01:45Z</updated>

		<summary type="html">&lt;p&gt;Vdeshmu: Created page with &amp;quot;E2165&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;E2165&lt;/div&gt;</summary>
		<author><name>Vdeshmu</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2021&amp;diff=140261</id>
		<title>CSC/ECE 517 Fall 2021</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2021&amp;diff=140261"/>
		<updated>2021-10-31T17:55:10Z</updated>

		<summary type="html">&lt;p&gt;Vdeshmu: /* OSS Projects */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== OSS Projects ==&lt;br /&gt;
&lt;br /&gt;
* [[CSC/ECE 517 Fall 2021 - E2117. Refactor questionaires_controller.rb]]&lt;br /&gt;
* [[CSC/ECE 517 Fall 2021 - E2128. Refactor student_quizzes_controller.rb &amp;amp; late_policies_controller.rb]]&lt;br /&gt;
* [[CSC/ECE 517 Fall 2021 - E2129. Refactor auth_controller.rb &amp;amp; password_retrieval_controller.rb]]&lt;br /&gt;
* [[CSC/ECE 517 Fall 2021 - E2132. Add tests cases for review mapping helper.rb]]&lt;br /&gt;
* [[CSC/ECE 517 Fall 2021 - E2134. Write unit tests for admin_controller.rb and institution_controller.rb]]&lt;br /&gt;
* [[CSC/ECE 517 Fall 2021 - E2138. Auto-generate submission directory names based on assignment]]&lt;br /&gt;
* [[CSC/ECE 517 Fall 2021 - E2142. Improve e-mail notifications]]&lt;br /&gt;
* [[CSC/ECE 517 Fall 2021 - E2133. Write tests for popup_controller.rb]]&lt;br /&gt;
* [[CSC/ECE 517 Fall 2021 - E2120. Refactor reputation_web_service_controller.rb]]&lt;br /&gt;
* [[CSC/ECE 517 Fall 2021 - E2139. Remove multiple topics at a time]]&lt;br /&gt;
* [[CSC/ECE 517 Fall 2021 - E2131. Improve assessment360_controller.rb]]&lt;br /&gt;
* [[CSC/ECE 517 Fall 2021 - E2121. Refactor suggestion_controller.rb]]&lt;br /&gt;
* [[CSC/ECE 517 Fall 2021 - E2122. Refactor impersonate_controller.rb]]&lt;br /&gt;
* [[CSC/ECE 517 Fall 2021 - E2123. Refactor sign_up_sheet_controller.rb]]&lt;br /&gt;
* [[CSC/ECE 517 Fall 2021 - E2126. Refactor account_request_controller.rb]]&lt;br /&gt;
* [[CSC/ECE 517 Fall 2021 - E2124. Refactor review_mapping_controller.rb]]&lt;br /&gt;
* [[CSC/ECE 517 Fall 2021 - E2125. Refactor review_mapping_helper.rb]]&lt;br /&gt;
* [[CSC/ECE 517 Fall 2021 - E2127. Refactor teams_controller]]&lt;br /&gt;
* [[CSC/ECE 517 Fall 2021 - E2130. Refactor submitted_content_controller.rb]]&lt;br /&gt;
* [[CSC/ECE 517 Fall 2021 - E2140. Create new late policy successfully and fix Bank link]]&lt;br /&gt;
* [[CSC/ECE 517 Fall 2021 - E2141. OSS project Finklestein: Instructors &amp;amp; Institutions]]&lt;br /&gt;
* [[CSC/ECE 517 Fall 2021 - E2147. Role-based reviewing]]&lt;br /&gt;
* [[CSC/ECE 517 Fall 2021 - E2145. OSS Project Beige]]&lt;br /&gt;
* [[CSC/ECE 517 Fall 2021 - E2146. Introduce a Student View for instructors]]&lt;br /&gt;
* [[CSC/ECE 517 Fall 2021 - Refactor Evaluation of SQL Queries]]&lt;br /&gt;
* [[CSC/ECE 517 Fall 2021 - E2135. Email notification to reviewers and instructors]]&lt;br /&gt;
* [[CSC/ECE 517 Fall 2021 - E2168. Testing - Reputations]]&lt;br /&gt;
* [[CSC/ECE 517 Fall 2021 - E2149. Finish Github metrics integration - Reputations]]&lt;br /&gt;
* [[CSC/ECE 517 Fall 2021 - E2161. Merge code for role-based reviewing with code for topic-specific rubrics]]&lt;/div&gt;</summary>
		<author><name>Vdeshmu</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2021_-_E2140._Create_new_late_policy_successfully_and_fix_Bank_link&amp;diff=139904</id>
		<title>CSC/ECE 517 Fall 2021 - E2140. Create new late policy successfully and fix Bank link</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2021_-_E2140._Create_new_late_policy_successfully_and_fix_Bank_link&amp;diff=139904"/>
		<updated>2021-10-21T21:12:03Z</updated>

		<summary type="html">&lt;p&gt;Vdeshmu: /* Problem Statement */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
==E2140. Create new late policy successfully and fix &amp;quot;Back&amp;quot; link==&lt;br /&gt;
&lt;br /&gt;
This page provides a description of the Expertiza based OSS project, E1240.&lt;br /&gt;
&lt;br /&gt;
===About Expertiza===&lt;br /&gt;
&lt;br /&gt;
[http://expertiza.ncsu.edu/ Expertiza] is an open source project based on [http://rubyonrails.org/ Ruby on Rails] framework. Expertiza allows the instructor to create new assignments and customize new or existing assignments. It also allows the instructor to create a list of topics the students can sign up for. Students can form teams in Expertiza to work on various projects and assignments. Students can also peer review other students' submissions. Expertiza supports submission across various document types, including the URLs and wiki pages.&lt;br /&gt;
&lt;br /&gt;
===Problem Statement===&lt;br /&gt;
Create new late policy successfull and fix &amp;quot;Back&amp;quot; link.&lt;br /&gt;
&lt;br /&gt;
'''Please note: As the initial bug fix was only a few lines of code/it was halfway fixed, after discussing with mentor, the project was converted into a &amp;quot;testing project&amp;quot;, where we focused on writing tests for the implemented bugfixes. Hence, it hasn't been deployed and videos of the &amp;quot;tests&amp;quot;/&amp;quot;flow&amp;quot; have been recorded and uploaded to the attached link in the submission folder.'''&lt;br /&gt;
&lt;br /&gt;
==Fixes performed==&lt;br /&gt;
&lt;br /&gt;
* Fix back link on &amp;quot;New late policy&amp;quot; page.&lt;br /&gt;
* Fix incorrect flash message on the screen when new late policy is created&lt;br /&gt;
* Add controller unit tests for create and edit actions for late_policies_controller&lt;br /&gt;
* Add functional test for late policy creation&lt;br /&gt;
* Add functional test for back button on new late policy page&lt;br /&gt;
* Improve flow of late_policies_controller#edit action for better tests&lt;br /&gt;
* Fix late_policies_controller#edit action when it displayed two contradictory flashes&lt;br /&gt;
* SQL stack trace showed up when long string is entered in policy name, this has been fixed to show a different error to user&lt;br /&gt;
* View was checked after a controller test to ensure that the correct message is shown to the user.&lt;br /&gt;
* Database was checked after controller test to verify whether correct changes happened or didn't.&lt;br /&gt;
* model was also checked to ensure the database is in a correct state&lt;br /&gt;
&lt;br /&gt;
===About Late Policies Controller===&lt;br /&gt;
&lt;br /&gt;
This controller can be accessed by editing an assignment, going on &amp;quot;Due Dates&amp;quot; page and  clicking on &amp;quot;New late policy&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
== Files modified in current project ==&lt;br /&gt;
&lt;br /&gt;
1. app/controllers/late_policies_controller.rb &amp;lt;br/&amp;gt;&lt;br /&gt;
2. app/views/late_policies/new.html.erb &amp;lt;br/&amp;gt;&lt;br /&gt;
3. spec/factories/factories.rb&amp;lt;br/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Files added for tests==&lt;br /&gt;
&lt;br /&gt;
1. spec/controllers/late_policies_controller_spec.rb &amp;lt;br/&amp;gt;&lt;br /&gt;
2. spec/features/late_policy_creation_spec.rb &amp;lt;br/&amp;gt;&lt;br /&gt;
3. spec/features/late_policy_back_button_spec.rb &amp;lt;br/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Files modified for tests==&lt;br /&gt;
&lt;br /&gt;
1. spec/factories/factories.rb&amp;lt;br /&amp;gt;&lt;br /&gt;
2. app/controllers/late_policies_controller.rb&lt;br /&gt;
&lt;br /&gt;
===Current Implementation===&lt;br /&gt;
&lt;br /&gt;
* There were no tests present in beta branch, so tests for the CRUD operations were added.&lt;br /&gt;
* Edit action for late_policies_controller is complex to reason about, with booleans deciding whether there are errors.&lt;br /&gt;
* Back button does not lead to the assignment from which the new late policy page was created.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=====Drawbacks and Solutions=====&lt;br /&gt;
* '''Problem 1''': Back button was taking user to index of late_policies, and not assignment due dates page&lt;br /&gt;
::The back button was performing it's default action of going back to index page of late_policies, but it needs to send user to the assginment page.&lt;br /&gt;
&lt;br /&gt;
Before: &amp;lt;br /&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;%= link_to 'Back', :action =&amp;gt; 'index' %&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
After: &amp;lt;br /&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;%= link_to 'Back', edit_assignment_path(session[:edit_assignment]) %&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
* '''Solution''': The link_to function is called with the link to the assignment which was last edited, so it will go to assginment page.&lt;br /&gt;
&lt;br /&gt;
* Use edit_assignment_path(session[:edit_assignment]) to go back to the previous page&lt;br /&gt;
&lt;br /&gt;
* '''Problem 2''': Creating new policy with blank fields does not give a proper error&lt;br /&gt;
::The existing code just shows a blank error, without specifying what has gone wrong. Hence, user will not know what is wrong when they created a new policy.&lt;br /&gt;
&lt;br /&gt;
* '''Solution''':  The existing error handling code was changed to show the ActiveRecord::Invalid errors to user. And in case, a different exception occurs, a &amp;quot;Something went wrong&amp;quot; message is shown, as this exception shouldn't be visible to users.&lt;br /&gt;
        &lt;br /&gt;
Before:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
      rescue StandardError&lt;br /&gt;
        flash[:error] = &amp;quot;The following error occurred while saving the penalty policy: &amp;quot;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
After:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
      rescue ActiveRecord::RecordInvalid =&amp;gt; exception&lt;br /&gt;
        flash[:error] = exception.record.errors.full_messages.join(&amp;quot;&amp;lt;br /&amp;gt;&amp;quot;).html_safe&lt;br /&gt;
        redirect_to action: 'new'&lt;br /&gt;
      rescue StandardError =&amp;gt; exception&lt;br /&gt;
        # In case it's some error, this error should not be shown to users&lt;br /&gt;
        flash[:error] = &amp;quot;Something went wrong&amp;quot;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* '''Problem 3''':  Update `update` method of late_policies_controller &lt;br /&gt;
:: Existing update method was too convoluted to read and due to it's convolution, it was showing wrong errors on screen.&lt;br /&gt;
* '''Solution''': &lt;br /&gt;
The control flow of the `update` method was improved to use early exits when errors occur, instead of using booleans to manage execution.&lt;br /&gt;
&lt;br /&gt;
===Code improvements===&lt;br /&gt;
late_policies_controller#update&lt;br /&gt;
Before&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    @penalty_policy = LatePolicy.find(params[:id])&lt;br /&gt;
    flash[:error] = &amp;quot;The maximum penalty cannot be less than penalty per unit.&amp;quot; if invalid_penalty_per_unit&lt;br /&gt;
    same_policy_name = false&lt;br /&gt;
    # if name has changed then only check for this&lt;br /&gt;
    if same_policy_name == LatePolicy.check_policy_with_same_name(params[:late_policy][:policy_name], instructor_id)&lt;br /&gt;
      flash[:error] = &amp;quot;The policy could not be updated because a policy with the same name already exists.&amp;quot;&lt;br /&gt;
    if !same_policy_name &amp;amp;&amp;amp; !invalid_penalty_per_unit&lt;br /&gt;
      begin&lt;br /&gt;
        @penalty_policy.update_attributes(late_policy_params)&lt;br /&gt;
        @penalty_policy.save!&lt;br /&gt;
        LatePolicy.update_calculated_penalty_objects(@penalty_policy)&lt;br /&gt;
        flash[:notice] = &amp;quot;The late policy was successfully updated.&amp;quot;&lt;br /&gt;
        redirect_to action: 'index'&lt;br /&gt;
      rescue StandardError&lt;br /&gt;
        flash[:error] = &amp;quot;The following error occurred while updating the penalty policy: &amp;quot;&lt;br /&gt;
        redirect_to action: 'edit', id: params[:id]&lt;br /&gt;
      end&lt;br /&gt;
    elsif invalid_penalty_per_unit&lt;br /&gt;
      flash[:error] = &amp;quot;Cannot edit the policy. The maximum penalty cannot be less than penalty per unit.&amp;quot;&lt;br /&gt;
      redirect_to action: 'edit', id: params[:id]&lt;br /&gt;
    elsif same_policy_name&lt;br /&gt;
      flash[:error] = &amp;quot;Cannot edit the policy. A policy with the same name &amp;quot; + params[:late_policy][:policy_name] + &amp;quot; already exists.&amp;quot;&lt;br /&gt;
      redirect_to action: 'edit', id: params[:id]&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
After:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    invalid_penalty_per_unit = params[:late_policy][:max_penalty].to_i &amp;lt; params[:late_policy][:penalty_per_unit].to_i&lt;br /&gt;
    # If penalty per unit is invalid, exit early&lt;br /&gt;
    if invalid_penalty_per_unit&lt;br /&gt;
      flash[:error] = &amp;quot;Cannot edit the policy. The maximum penalty cannot be less than penalty per unit.&amp;quot;&lt;br /&gt;
      redirect_to action: 'edit', id: params[:id] and return&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    # Only do DB search if we pass the invalid penalty check&lt;br /&gt;
    @penalty_policy = LatePolicy.find(params[:id])&lt;br /&gt;
    # if name has changed, then only check for this&lt;br /&gt;
    if params[:late_policy][:policy_name] != @penalty_policy.policy_name&lt;br /&gt;
      if LatePolicy.check_policy_with_same_name(params[:late_policy][:policy_name], instructor_id)&lt;br /&gt;
        flash[:error] = &amp;quot;Cannot edit the policy. A policy with the same name &amp;quot; + params[:late_policy][:policy_name] + &amp;quot; already exists.&amp;quot;&lt;br /&gt;
        redirect_to action: 'edit', id: params[:id] and return&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    begin&lt;br /&gt;
      @penalty_policy.update_attributes(late_policy_params)&lt;br /&gt;
      @penalty_policy.save!&lt;br /&gt;
      LatePolicy.update_calculated_penalty_objects(@penalty_policy)&lt;br /&gt;
      flash[:notice] = &amp;quot;The late policy was successfully updated.&amp;quot;&lt;br /&gt;
      redirect_to action: 'index' and return&lt;br /&gt;
    rescue StandardError&lt;br /&gt;
      flash[:error] = &amp;quot;The following error occurred while updating the penalty policy: &amp;quot;&lt;br /&gt;
      redirect_to action: 'edit', id: params[:id] and return&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Test Plan===&lt;br /&gt;
&lt;br /&gt;
Late Policies Controller's CRUD methods were tested via unit tests to test the REST API, and they were also tested via capybara to emulate a user using the website.&lt;br /&gt;
&lt;br /&gt;
Test cases considered:&lt;br /&gt;
&lt;br /&gt;
1. Submitting an empty form when creating a new late policy &amp;lt;br /&amp;gt;&lt;br /&gt;
2. Using an maximum penalty that was less than the actual penalty &amp;lt;br /&amp;gt;&lt;br /&gt;
3. Penalty unit entered as negative number &amp;lt;br /&amp;gt;&lt;br /&gt;
4. Policy name is greater than 255 characters &amp;lt;br /&amp;gt;&lt;br /&gt;
5. Prevent creation of policy name if a policy with the same name already exists &amp;lt;br /&amp;gt;&lt;br /&gt;
6. Render the :new template successfully &amp;lt;br /&amp;gt;&lt;br /&gt;
7. Render the :edit template successfully &amp;lt;br /&amp;gt;&lt;br /&gt;
8. Prevents edit if policy name is being changed to an already existing policy's name &amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
For testing whether back button takes user back to the assginment edit page, we have used Capybara to emulate a user browsing the page. &amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
For capybara testing, we have considered the following tests: &amp;lt;br /&amp;gt;&lt;br /&gt;
1. Filling the form with blank values and then expecting failures as well as database not being updated. &amp;lt;br /&amp;gt;&lt;br /&gt;
2. Using a policy name that is longer than 255 characters (which is the database column length) &amp;lt;br /&amp;gt;&lt;br /&gt;
3. If user enters a negative penalty per point, the policy should not be created &amp;lt;br /&amp;gt;&lt;br /&gt;
4. Entering valid values in each field, should successfully create the late policy &amp;lt;br /&amp;gt;&lt;br /&gt;
5. If penalty per unit is greater than max penalty , then creation of late policy should fail. &amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Automated Testing using RSPEC===&lt;br /&gt;
The current version of expertiza did not have any test for LatePoliciesController, and for back button.&lt;br /&gt;
Using the test driven development(TDD) approach, we have added an exhaustive set of RSPEC tests for LatePoliciesController, to test creation and expected failure to create scenarios.&lt;br /&gt;
We have also added tests for back button on new late policy page.&lt;br /&gt;
Similarly, we have added feature tests for late policy creation.&lt;br /&gt;
&lt;br /&gt;
Late policy creation tests with Capybara&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
$ rspec ./spec/features/late_policy_creation_spec.rb &lt;br /&gt;
Randomized with seed 65056&lt;br /&gt;
.....&lt;br /&gt;
&lt;br /&gt;
Finished in 22.28 seconds (files took 9.71 seconds to load)&lt;br /&gt;
5 examples, 0 failures&lt;br /&gt;
&lt;br /&gt;
Randomized with seed 65056&lt;br /&gt;
&lt;br /&gt;
Coverage report generated for RSpec to /.../expertiza/coverage. 2074 / 15378 LOC (13.49%) covered.&lt;br /&gt;
[Coveralls] Outside the Travis environment, not sending data.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
REST API tests for LatePoliciesController:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
$ rspec ./spec/controllers/late_policies_controller_spec.rb &lt;br /&gt;
&lt;br /&gt;
Randomized with seed 29277&lt;br /&gt;
........&lt;br /&gt;
&lt;br /&gt;
Finished in 17.56 seconds (files took 8.64 seconds to load)&lt;br /&gt;
8 examples, 0 failures&lt;br /&gt;
&lt;br /&gt;
Randomized with seed 29277&lt;br /&gt;
&lt;br /&gt;
Coverage report generated for RSpec to /.../expertiza/coverage. 1587 / 15800 LOC (10.04%) covered.&lt;br /&gt;
[Coveralls] Outside the Travis environment, not sending data.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Back button tests&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
$ rspec ./spec/features/late_policy_back_button_spec.rb &lt;br /&gt;
Randomized with seed 15242&lt;br /&gt;
.&lt;br /&gt;
&lt;br /&gt;
Finished in 9.74 seconds (files took 8.95 seconds to load)&lt;br /&gt;
1 example, 0 failures&lt;br /&gt;
&lt;br /&gt;
Randomized with seed 15242&lt;br /&gt;
&lt;br /&gt;
Coverage report generated for RSpec to /.../expertiza/coverage. 2041 / 15378 LOC (13.27%) covered.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===References===&lt;br /&gt;
&lt;br /&gt;
#[https://github.com/expertiza/expertiza Expertiza on GitHub]&lt;br /&gt;
#[https://github.com/vinay-deshmukh/expertiza GitHub Project Repository Fork]&lt;br /&gt;
#[https://github.com/expertiza/expertiza/pull/2087/ Pull request to Expertiza repo]&lt;br /&gt;
#[https://github.com/vinay-deshmukh/expertiza/projects/1 GitHub Fork: Project board]&lt;br /&gt;
#[https://github.com/vinay-deshmukh/expertiza/issues Issues made while development]&lt;br /&gt;
#[https://github.com/vinay-deshmukh/expertiza/pulls  Pull requests made to the fork to document work]&lt;br /&gt;
#[https://github.com/vinay-deshmukh/expertiza/pulls?q=is%3Apr+is%3Aclosed Closed Pull Requests on Fork]&lt;/div&gt;</summary>
		<author><name>Vdeshmu</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2021_-_E2140._Create_new_late_policy_successfully_and_fix_Bank_link&amp;diff=139903</id>
		<title>CSC/ECE 517 Fall 2021 - E2140. Create new late policy successfully and fix Bank link</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2021_-_E2140._Create_new_late_policy_successfully_and_fix_Bank_link&amp;diff=139903"/>
		<updated>2021-10-21T21:06:22Z</updated>

		<summary type="html">&lt;p&gt;Vdeshmu: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
==E2140. Create new late policy successfully and fix &amp;quot;Back&amp;quot; link==&lt;br /&gt;
&lt;br /&gt;
This page provides a description of the Expertiza based OSS project, E1240.&lt;br /&gt;
&lt;br /&gt;
===About Expertiza===&lt;br /&gt;
&lt;br /&gt;
[http://expertiza.ncsu.edu/ Expertiza] is an open source project based on [http://rubyonrails.org/ Ruby on Rails] framework. Expertiza allows the instructor to create new assignments and customize new or existing assignments. It also allows the instructor to create a list of topics the students can sign up for. Students can form teams in Expertiza to work on various projects and assignments. Students can also peer review other students' submissions. Expertiza supports submission across various document types, including the URLs and wiki pages.&lt;br /&gt;
&lt;br /&gt;
===Problem Statement===&lt;br /&gt;
Create new late policy successfull and fix &amp;quot;Back&amp;quot; link.&lt;br /&gt;
&lt;br /&gt;
'''Please note: As the initial bug fix was only a few lines of code/it was halfway fixed, after discussing with mentor, the project was converted into a &amp;quot;testing project&amp;quot;, where we focused on writing tests for the implemented features. Hence, it hasn't been deployed and videos of the &amp;quot;tests&amp;quot;/&amp;quot;flow&amp;quot; have been recorded and uploaded to the attached link in the submission folder.'''&lt;br /&gt;
&lt;br /&gt;
==Fixes performed==&lt;br /&gt;
&lt;br /&gt;
* Fix back link on &amp;quot;New late policy&amp;quot; page.&lt;br /&gt;
* Fix incorrect flash message on the screen when new late policy is created&lt;br /&gt;
* Add controller unit tests for create and edit actions for late_policies_controller&lt;br /&gt;
* Add functional test for late policy creation&lt;br /&gt;
* Add functional test for back button on new late policy page&lt;br /&gt;
* Improve flow of late_policies_controller#edit action for better tests&lt;br /&gt;
* Fix late_policies_controller#edit action when it displayed two contradictory flashes&lt;br /&gt;
* SQL stack trace showed up when long string is entered in policy name, this has been fixed to show a different error to user&lt;br /&gt;
* View was checked after a controller test to ensure that the correct message is shown to the user.&lt;br /&gt;
* Database was checked after controller test to verify whether correct changes happened or didn't.&lt;br /&gt;
* model was also checked to ensure the database is in a correct state&lt;br /&gt;
&lt;br /&gt;
===About Late Policies Controller===&lt;br /&gt;
&lt;br /&gt;
This controller can be accessed by editing an assignment, going on &amp;quot;Due Dates&amp;quot; page and  clicking on &amp;quot;New late policy&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
== Files modified in current project ==&lt;br /&gt;
&lt;br /&gt;
1. app/controllers/late_policies_controller.rb &amp;lt;br/&amp;gt;&lt;br /&gt;
2. app/views/late_policies/new.html.erb &amp;lt;br/&amp;gt;&lt;br /&gt;
3. spec/factories/factories.rb&amp;lt;br/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Files added for tests==&lt;br /&gt;
&lt;br /&gt;
1. spec/controllers/late_policies_controller_spec.rb &amp;lt;br/&amp;gt;&lt;br /&gt;
2. spec/features/late_policy_creation_spec.rb &amp;lt;br/&amp;gt;&lt;br /&gt;
3. spec/features/late_policy_back_button_spec.rb &amp;lt;br/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Files modified for tests==&lt;br /&gt;
&lt;br /&gt;
1. spec/factories/factories.rb&amp;lt;br /&amp;gt;&lt;br /&gt;
2. app/controllers/late_policies_controller.rb&lt;br /&gt;
&lt;br /&gt;
===Current Implementation===&lt;br /&gt;
&lt;br /&gt;
* There were no tests present in beta branch, so tests for the CRUD operations were added.&lt;br /&gt;
* Edit action for late_policies_controller is complex to reason about, with booleans deciding whether there are errors.&lt;br /&gt;
* Back button does not lead to the assignment from which the new late policy page was created.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=====Drawbacks and Solutions=====&lt;br /&gt;
* '''Problem 1''': Back button was taking user to index of late_policies, and not assignment due dates page&lt;br /&gt;
::The back button was performing it's default action of going back to index page of late_policies, but it needs to send user to the assginment page.&lt;br /&gt;
&lt;br /&gt;
Before: &amp;lt;br /&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;%= link_to 'Back', :action =&amp;gt; 'index' %&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
After: &amp;lt;br /&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;%= link_to 'Back', edit_assignment_path(session[:edit_assignment]) %&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
* '''Solution''': The link_to function is called with the link to the assignment which was last edited, so it will go to assginment page.&lt;br /&gt;
&lt;br /&gt;
* Use edit_assignment_path(session[:edit_assignment]) to go back to the previous page&lt;br /&gt;
&lt;br /&gt;
* '''Problem 2''': Creating new policy with blank fields does not give a proper error&lt;br /&gt;
::The existing code just shows a blank error, without specifying what has gone wrong. Hence, user will not know what is wrong when they created a new policy.&lt;br /&gt;
&lt;br /&gt;
* '''Solution''':  The existing error handling code was changed to show the ActiveRecord::Invalid errors to user. And in case, a different exception occurs, a &amp;quot;Something went wrong&amp;quot; message is shown, as this exception shouldn't be visible to users.&lt;br /&gt;
        &lt;br /&gt;
Before:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
      rescue StandardError&lt;br /&gt;
        flash[:error] = &amp;quot;The following error occurred while saving the penalty policy: &amp;quot;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
After:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
      rescue ActiveRecord::RecordInvalid =&amp;gt; exception&lt;br /&gt;
        flash[:error] = exception.record.errors.full_messages.join(&amp;quot;&amp;lt;br /&amp;gt;&amp;quot;).html_safe&lt;br /&gt;
        redirect_to action: 'new'&lt;br /&gt;
      rescue StandardError =&amp;gt; exception&lt;br /&gt;
        # In case it's some error, this error should not be shown to users&lt;br /&gt;
        flash[:error] = &amp;quot;Something went wrong&amp;quot;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* '''Problem 3''':  Update `update` method of late_policies_controller &lt;br /&gt;
:: Existing update method was too convoluted to read and due to it's convolution, it was showing wrong errors on screen.&lt;br /&gt;
* '''Solution''': &lt;br /&gt;
The control flow of the `update` method was improved to use early exits when errors occur, instead of using booleans to manage execution.&lt;br /&gt;
&lt;br /&gt;
===Code improvements===&lt;br /&gt;
late_policies_controller#update&lt;br /&gt;
Before&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    @penalty_policy = LatePolicy.find(params[:id])&lt;br /&gt;
    flash[:error] = &amp;quot;The maximum penalty cannot be less than penalty per unit.&amp;quot; if invalid_penalty_per_unit&lt;br /&gt;
    same_policy_name = false&lt;br /&gt;
    # if name has changed then only check for this&lt;br /&gt;
    if same_policy_name == LatePolicy.check_policy_with_same_name(params[:late_policy][:policy_name], instructor_id)&lt;br /&gt;
      flash[:error] = &amp;quot;The policy could not be updated because a policy with the same name already exists.&amp;quot;&lt;br /&gt;
    if !same_policy_name &amp;amp;&amp;amp; !invalid_penalty_per_unit&lt;br /&gt;
      begin&lt;br /&gt;
        @penalty_policy.update_attributes(late_policy_params)&lt;br /&gt;
        @penalty_policy.save!&lt;br /&gt;
        LatePolicy.update_calculated_penalty_objects(@penalty_policy)&lt;br /&gt;
        flash[:notice] = &amp;quot;The late policy was successfully updated.&amp;quot;&lt;br /&gt;
        redirect_to action: 'index'&lt;br /&gt;
      rescue StandardError&lt;br /&gt;
        flash[:error] = &amp;quot;The following error occurred while updating the penalty policy: &amp;quot;&lt;br /&gt;
        redirect_to action: 'edit', id: params[:id]&lt;br /&gt;
      end&lt;br /&gt;
    elsif invalid_penalty_per_unit&lt;br /&gt;
      flash[:error] = &amp;quot;Cannot edit the policy. The maximum penalty cannot be less than penalty per unit.&amp;quot;&lt;br /&gt;
      redirect_to action: 'edit', id: params[:id]&lt;br /&gt;
    elsif same_policy_name&lt;br /&gt;
      flash[:error] = &amp;quot;Cannot edit the policy. A policy with the same name &amp;quot; + params[:late_policy][:policy_name] + &amp;quot; already exists.&amp;quot;&lt;br /&gt;
      redirect_to action: 'edit', id: params[:id]&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
After:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    invalid_penalty_per_unit = params[:late_policy][:max_penalty].to_i &amp;lt; params[:late_policy][:penalty_per_unit].to_i&lt;br /&gt;
    # If penalty per unit is invalid, exit early&lt;br /&gt;
    if invalid_penalty_per_unit&lt;br /&gt;
      flash[:error] = &amp;quot;Cannot edit the policy. The maximum penalty cannot be less than penalty per unit.&amp;quot;&lt;br /&gt;
      redirect_to action: 'edit', id: params[:id] and return&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    # Only do DB search if we pass the invalid penalty check&lt;br /&gt;
    @penalty_policy = LatePolicy.find(params[:id])&lt;br /&gt;
    # if name has changed, then only check for this&lt;br /&gt;
    if params[:late_policy][:policy_name] != @penalty_policy.policy_name&lt;br /&gt;
      if LatePolicy.check_policy_with_same_name(params[:late_policy][:policy_name], instructor_id)&lt;br /&gt;
        flash[:error] = &amp;quot;Cannot edit the policy. A policy with the same name &amp;quot; + params[:late_policy][:policy_name] + &amp;quot; already exists.&amp;quot;&lt;br /&gt;
        redirect_to action: 'edit', id: params[:id] and return&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    begin&lt;br /&gt;
      @penalty_policy.update_attributes(late_policy_params)&lt;br /&gt;
      @penalty_policy.save!&lt;br /&gt;
      LatePolicy.update_calculated_penalty_objects(@penalty_policy)&lt;br /&gt;
      flash[:notice] = &amp;quot;The late policy was successfully updated.&amp;quot;&lt;br /&gt;
      redirect_to action: 'index' and return&lt;br /&gt;
    rescue StandardError&lt;br /&gt;
      flash[:error] = &amp;quot;The following error occurred while updating the penalty policy: &amp;quot;&lt;br /&gt;
      redirect_to action: 'edit', id: params[:id] and return&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Test Plan===&lt;br /&gt;
&lt;br /&gt;
Late Policies Controller's CRUD methods were tested via unit tests to test the REST API, and they were also tested via capybara to emulate a user using the website.&lt;br /&gt;
&lt;br /&gt;
Test cases considered:&lt;br /&gt;
&lt;br /&gt;
1. Submitting an empty form when creating a new late policy &amp;lt;br /&amp;gt;&lt;br /&gt;
2. Using an maximum penalty that was less than the actual penalty &amp;lt;br /&amp;gt;&lt;br /&gt;
3. Penalty unit entered as negative number &amp;lt;br /&amp;gt;&lt;br /&gt;
4. Policy name is greater than 255 characters &amp;lt;br /&amp;gt;&lt;br /&gt;
5. Prevent creation of policy name if a policy with the same name already exists &amp;lt;br /&amp;gt;&lt;br /&gt;
6. Render the :new template successfully &amp;lt;br /&amp;gt;&lt;br /&gt;
7. Render the :edit template successfully &amp;lt;br /&amp;gt;&lt;br /&gt;
8. Prevents edit if policy name is being changed to an already existing policy's name &amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
For testing whether back button takes user back to the assginment edit page, we have used Capybara to emulate a user browsing the page. &amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
For capybara testing, we have considered the following tests: &amp;lt;br /&amp;gt;&lt;br /&gt;
1. Filling the form with blank values and then expecting failures as well as database not being updated. &amp;lt;br /&amp;gt;&lt;br /&gt;
2. Using a policy name that is longer than 255 characters (which is the database column length) &amp;lt;br /&amp;gt;&lt;br /&gt;
3. If user enters a negative penalty per point, the policy should not be created &amp;lt;br /&amp;gt;&lt;br /&gt;
4. Entering valid values in each field, should successfully create the late policy &amp;lt;br /&amp;gt;&lt;br /&gt;
5. If penalty per unit is greater than max penalty , then creation of late policy should fail. &amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Automated Testing using RSPEC===&lt;br /&gt;
The current version of expertiza did not have any test for LatePoliciesController, and for back button.&lt;br /&gt;
Using the test driven development(TDD) approach, we have added an exhaustive set of RSPEC tests for LatePoliciesController, to test creation and expected failure to create scenarios.&lt;br /&gt;
We have also added tests for back button on new late policy page.&lt;br /&gt;
Similarly, we have added feature tests for late policy creation.&lt;br /&gt;
&lt;br /&gt;
Late policy creation tests with Capybara&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
$ rspec ./spec/features/late_policy_creation_spec.rb &lt;br /&gt;
Randomized with seed 65056&lt;br /&gt;
.....&lt;br /&gt;
&lt;br /&gt;
Finished in 22.28 seconds (files took 9.71 seconds to load)&lt;br /&gt;
5 examples, 0 failures&lt;br /&gt;
&lt;br /&gt;
Randomized with seed 65056&lt;br /&gt;
&lt;br /&gt;
Coverage report generated for RSpec to /.../expertiza/coverage. 2074 / 15378 LOC (13.49%) covered.&lt;br /&gt;
[Coveralls] Outside the Travis environment, not sending data.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
REST API tests for LatePoliciesController:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
$ rspec ./spec/controllers/late_policies_controller_spec.rb &lt;br /&gt;
&lt;br /&gt;
Randomized with seed 29277&lt;br /&gt;
........&lt;br /&gt;
&lt;br /&gt;
Finished in 17.56 seconds (files took 8.64 seconds to load)&lt;br /&gt;
8 examples, 0 failures&lt;br /&gt;
&lt;br /&gt;
Randomized with seed 29277&lt;br /&gt;
&lt;br /&gt;
Coverage report generated for RSpec to /.../expertiza/coverage. 1587 / 15800 LOC (10.04%) covered.&lt;br /&gt;
[Coveralls] Outside the Travis environment, not sending data.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Back button tests&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
$ rspec ./spec/features/late_policy_back_button_spec.rb &lt;br /&gt;
Randomized with seed 15242&lt;br /&gt;
.&lt;br /&gt;
&lt;br /&gt;
Finished in 9.74 seconds (files took 8.95 seconds to load)&lt;br /&gt;
1 example, 0 failures&lt;br /&gt;
&lt;br /&gt;
Randomized with seed 15242&lt;br /&gt;
&lt;br /&gt;
Coverage report generated for RSpec to /.../expertiza/coverage. 2041 / 15378 LOC (13.27%) covered.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===References===&lt;br /&gt;
&lt;br /&gt;
#[https://github.com/expertiza/expertiza Expertiza on GitHub]&lt;br /&gt;
#[https://github.com/vinay-deshmukh/expertiza GitHub Project Repository Fork]&lt;br /&gt;
#[https://github.com/expertiza/expertiza/pull/2087/ Pull request to Expertiza repo]&lt;br /&gt;
#[https://github.com/vinay-deshmukh/expertiza/projects/1 GitHub Fork: Project board]&lt;br /&gt;
#[https://github.com/vinay-deshmukh/expertiza/issues Issues made while development]&lt;br /&gt;
#[https://github.com/vinay-deshmukh/expertiza/pulls  Pull requests made to the fork to document work]&lt;br /&gt;
#[https://github.com/vinay-deshmukh/expertiza/pulls?q=is%3Apr+is%3Aclosed Closed Pull Requests on Fork]&lt;/div&gt;</summary>
		<author><name>Vdeshmu</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2021_-_E2140._Create_new_late_policy_successfully_and_fix_Bank_link&amp;diff=139902</id>
		<title>CSC/ECE 517 Fall 2021 - E2140. Create new late policy successfully and fix Bank link</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2021_-_E2140._Create_new_late_policy_successfully_and_fix_Bank_link&amp;diff=139902"/>
		<updated>2021-10-21T21:05:24Z</updated>

		<summary type="html">&lt;p&gt;Vdeshmu: /* Problem Statement */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
==E2140. Create new late policy successfully and fix &amp;quot;Back&amp;quot; link==&lt;br /&gt;
&lt;br /&gt;
This page provides a description of the Expertiza based OSS project, E1240.&lt;br /&gt;
&lt;br /&gt;
===About Expertiza===&lt;br /&gt;
&lt;br /&gt;
[http://expertiza.ncsu.edu/ Expertiza] is an open source project based on [http://rubyonrails.org/ Ruby on Rails] framework. Expertiza allows the instructor to create new assignments and customize new or existing assignments. It also allows the instructor to create a list of topics the students can sign up for. Students can form teams in Expertiza to work on various projects and assignments. Students can also peer review other students' submissions. Expertiza supports submission across various document types, including the URLs and wiki pages.&lt;br /&gt;
&lt;br /&gt;
===Problem Statement===&lt;br /&gt;
Create new late policy successfull and fix &amp;quot;Back&amp;quot; link.&lt;br /&gt;
&lt;br /&gt;
'''Please note: As the initial bug fix was only a few lines of code/it was halfway fixed, after discussing with mentor, the project was converted into a &amp;quot;testing project&amp;quot;, where we focused on writing tests for the implemented features.'''&lt;br /&gt;
&lt;br /&gt;
==Fixes performed==&lt;br /&gt;
&lt;br /&gt;
* Fix back link on &amp;quot;New late policy&amp;quot; page.&lt;br /&gt;
* Fix incorrect flash message on the screen when new late policy is created&lt;br /&gt;
* Add controller unit tests for create and edit actions for late_policies_controller&lt;br /&gt;
* Add functional test for late policy creation&lt;br /&gt;
* Add functional test for back button on new late policy page&lt;br /&gt;
* Improve flow of late_policies_controller#edit action for better tests&lt;br /&gt;
* Fix late_policies_controller#edit action when it displayed two contradictory flashes&lt;br /&gt;
* SQL stack trace showed up when long string is entered in policy name, this has been fixed to show a different error to user&lt;br /&gt;
* View was checked after a controller test to ensure that the correct message is shown to the user.&lt;br /&gt;
* Database was checked after controller test to verify whether correct changes happened or didn't.&lt;br /&gt;
* model was also checked to ensure the database is in a correct state&lt;br /&gt;
&lt;br /&gt;
===About Late Policies Controller===&lt;br /&gt;
&lt;br /&gt;
This controller can be accessed by editing an assignment, going on &amp;quot;Due Dates&amp;quot; page and  clicking on &amp;quot;New late policy&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
== Files modified in current project ==&lt;br /&gt;
&lt;br /&gt;
1. app/controllers/late_policies_controller.rb &amp;lt;br/&amp;gt;&lt;br /&gt;
2. app/views/late_policies/new.html.erb &amp;lt;br/&amp;gt;&lt;br /&gt;
3. spec/factories/factories.rb&amp;lt;br/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Files added for tests==&lt;br /&gt;
&lt;br /&gt;
1. spec/controllers/late_policies_controller_spec.rb &amp;lt;br/&amp;gt;&lt;br /&gt;
2. spec/features/late_policy_creation_spec.rb &amp;lt;br/&amp;gt;&lt;br /&gt;
3. spec/features/late_policy_back_button_spec.rb &amp;lt;br/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Files modified for tests==&lt;br /&gt;
&lt;br /&gt;
1. spec/factories/factories.rb&amp;lt;br /&amp;gt;&lt;br /&gt;
2. app/controllers/late_policies_controller.rb&lt;br /&gt;
&lt;br /&gt;
===Current Implementation===&lt;br /&gt;
&lt;br /&gt;
* There were no tests present in beta branch, so tests for the CRUD operations were added.&lt;br /&gt;
* Edit action for late_policies_controller is complex to reason about, with booleans deciding whether there are errors.&lt;br /&gt;
* Back button does not lead to the assignment from which the new late policy page was created.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=====Drawbacks and Solutions=====&lt;br /&gt;
* '''Problem 1''': Back button was taking user to index of late_policies, and not assignment due dates page&lt;br /&gt;
::The back button was performing it's default action of going back to index page of late_policies, but it needs to send user to the assginment page.&lt;br /&gt;
&lt;br /&gt;
Before: &amp;lt;br /&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;%= link_to 'Back', :action =&amp;gt; 'index' %&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
After: &amp;lt;br /&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;%= link_to 'Back', edit_assignment_path(session[:edit_assignment]) %&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
* '''Solution''': The link_to function is called with the link to the assignment which was last edited, so it will go to assginment page.&lt;br /&gt;
&lt;br /&gt;
* Use edit_assignment_path(session[:edit_assignment]) to go back to the previous page&lt;br /&gt;
&lt;br /&gt;
* '''Problem 2''': Creating new policy with blank fields does not give a proper error&lt;br /&gt;
::The existing code just shows a blank error, without specifying what has gone wrong. Hence, user will not know what is wrong when they created a new policy.&lt;br /&gt;
&lt;br /&gt;
* '''Solution''':  The existing error handling code was changed to show the ActiveRecord::Invalid errors to user. And in case, a different exception occurs, a &amp;quot;Something went wrong&amp;quot; message is shown, as this exception shouldn't be visible to users.&lt;br /&gt;
        &lt;br /&gt;
Before:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
      rescue StandardError&lt;br /&gt;
        flash[:error] = &amp;quot;The following error occurred while saving the penalty policy: &amp;quot;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
After:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
      rescue ActiveRecord::RecordInvalid =&amp;gt; exception&lt;br /&gt;
        flash[:error] = exception.record.errors.full_messages.join(&amp;quot;&amp;lt;br /&amp;gt;&amp;quot;).html_safe&lt;br /&gt;
        redirect_to action: 'new'&lt;br /&gt;
      rescue StandardError =&amp;gt; exception&lt;br /&gt;
        # In case it's some error, this error should not be shown to users&lt;br /&gt;
        flash[:error] = &amp;quot;Something went wrong&amp;quot;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* '''Problem 3''':  Update `update` method of late_policies_controller &lt;br /&gt;
:: Existing update method was too convoluted to read and due to it's convolution, it was showing wrong errors on screen.&lt;br /&gt;
* '''Solution''': &lt;br /&gt;
The control flow of the `update` method was improved to use early exits when errors occur, instead of using booleans to manage execution.&lt;br /&gt;
&lt;br /&gt;
===Code improvements===&lt;br /&gt;
late_policies_controller#update&lt;br /&gt;
Before&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    @penalty_policy = LatePolicy.find(params[:id])&lt;br /&gt;
    flash[:error] = &amp;quot;The maximum penalty cannot be less than penalty per unit.&amp;quot; if invalid_penalty_per_unit&lt;br /&gt;
    same_policy_name = false&lt;br /&gt;
    # if name has changed then only check for this&lt;br /&gt;
    if same_policy_name == LatePolicy.check_policy_with_same_name(params[:late_policy][:policy_name], instructor_id)&lt;br /&gt;
      flash[:error] = &amp;quot;The policy could not be updated because a policy with the same name already exists.&amp;quot;&lt;br /&gt;
    if !same_policy_name &amp;amp;&amp;amp; !invalid_penalty_per_unit&lt;br /&gt;
      begin&lt;br /&gt;
        @penalty_policy.update_attributes(late_policy_params)&lt;br /&gt;
        @penalty_policy.save!&lt;br /&gt;
        LatePolicy.update_calculated_penalty_objects(@penalty_policy)&lt;br /&gt;
        flash[:notice] = &amp;quot;The late policy was successfully updated.&amp;quot;&lt;br /&gt;
        redirect_to action: 'index'&lt;br /&gt;
      rescue StandardError&lt;br /&gt;
        flash[:error] = &amp;quot;The following error occurred while updating the penalty policy: &amp;quot;&lt;br /&gt;
        redirect_to action: 'edit', id: params[:id]&lt;br /&gt;
      end&lt;br /&gt;
    elsif invalid_penalty_per_unit&lt;br /&gt;
      flash[:error] = &amp;quot;Cannot edit the policy. The maximum penalty cannot be less than penalty per unit.&amp;quot;&lt;br /&gt;
      redirect_to action: 'edit', id: params[:id]&lt;br /&gt;
    elsif same_policy_name&lt;br /&gt;
      flash[:error] = &amp;quot;Cannot edit the policy. A policy with the same name &amp;quot; + params[:late_policy][:policy_name] + &amp;quot; already exists.&amp;quot;&lt;br /&gt;
      redirect_to action: 'edit', id: params[:id]&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
After:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    invalid_penalty_per_unit = params[:late_policy][:max_penalty].to_i &amp;lt; params[:late_policy][:penalty_per_unit].to_i&lt;br /&gt;
    # If penalty per unit is invalid, exit early&lt;br /&gt;
    if invalid_penalty_per_unit&lt;br /&gt;
      flash[:error] = &amp;quot;Cannot edit the policy. The maximum penalty cannot be less than penalty per unit.&amp;quot;&lt;br /&gt;
      redirect_to action: 'edit', id: params[:id] and return&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    # Only do DB search if we pass the invalid penalty check&lt;br /&gt;
    @penalty_policy = LatePolicy.find(params[:id])&lt;br /&gt;
    # if name has changed, then only check for this&lt;br /&gt;
    if params[:late_policy][:policy_name] != @penalty_policy.policy_name&lt;br /&gt;
      if LatePolicy.check_policy_with_same_name(params[:late_policy][:policy_name], instructor_id)&lt;br /&gt;
        flash[:error] = &amp;quot;Cannot edit the policy. A policy with the same name &amp;quot; + params[:late_policy][:policy_name] + &amp;quot; already exists.&amp;quot;&lt;br /&gt;
        redirect_to action: 'edit', id: params[:id] and return&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    begin&lt;br /&gt;
      @penalty_policy.update_attributes(late_policy_params)&lt;br /&gt;
      @penalty_policy.save!&lt;br /&gt;
      LatePolicy.update_calculated_penalty_objects(@penalty_policy)&lt;br /&gt;
      flash[:notice] = &amp;quot;The late policy was successfully updated.&amp;quot;&lt;br /&gt;
      redirect_to action: 'index' and return&lt;br /&gt;
    rescue StandardError&lt;br /&gt;
      flash[:error] = &amp;quot;The following error occurred while updating the penalty policy: &amp;quot;&lt;br /&gt;
      redirect_to action: 'edit', id: params[:id] and return&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Test Plan===&lt;br /&gt;
&lt;br /&gt;
Late Policies Controller's CRUD methods were tested via unit tests to test the REST API, and they were also tested via capybara to emulate a user using the website.&lt;br /&gt;
&lt;br /&gt;
Test cases considered:&lt;br /&gt;
&lt;br /&gt;
1. Submitting an empty form when creating a new late policy &amp;lt;br /&amp;gt;&lt;br /&gt;
2. Using an maximum penalty that was less than the actual penalty &amp;lt;br /&amp;gt;&lt;br /&gt;
3. Penalty unit entered as negative number &amp;lt;br /&amp;gt;&lt;br /&gt;
4. Policy name is greater than 255 characters &amp;lt;br /&amp;gt;&lt;br /&gt;
5. Prevent creation of policy name if a policy with the same name already exists &amp;lt;br /&amp;gt;&lt;br /&gt;
6. Render the :new template successfully &amp;lt;br /&amp;gt;&lt;br /&gt;
7. Render the :edit template successfully &amp;lt;br /&amp;gt;&lt;br /&gt;
8. Prevents edit if policy name is being changed to an already existing policy's name &amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
For testing whether back button takes user back to the assginment edit page, we have used Capybara to emulate a user browsing the page. &amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
For capybara testing, we have considered the following tests: &amp;lt;br /&amp;gt;&lt;br /&gt;
1. Filling the form with blank values and then expecting failures as well as database not being updated. &amp;lt;br /&amp;gt;&lt;br /&gt;
2. Using a policy name that is longer than 255 characters (which is the database column length) &amp;lt;br /&amp;gt;&lt;br /&gt;
3. If user enters a negative penalty per point, the policy should not be created &amp;lt;br /&amp;gt;&lt;br /&gt;
4. Entering valid values in each field, should successfully create the late policy &amp;lt;br /&amp;gt;&lt;br /&gt;
5. If penalty per unit is greater than max penalty , then creation of late policy should fail. &amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Automated Testing using RSPEC===&lt;br /&gt;
The current version of expertiza did not have any test for LatePoliciesController, and for back button.&lt;br /&gt;
Using the test driven development(TDD) approach, we have added an exhaustive set of RSPEC tests for LatePoliciesController, to test creation and expected failure to create scenarios.&lt;br /&gt;
We have also added tests for back button on new late policy page.&lt;br /&gt;
Similarly, we have added feature tests for late policy creation.&lt;br /&gt;
&lt;br /&gt;
Late policy creation tests with Capybara&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
$ rspec ./spec/features/late_policy_creation_spec.rb &lt;br /&gt;
Randomized with seed 65056&lt;br /&gt;
.....&lt;br /&gt;
&lt;br /&gt;
Finished in 22.28 seconds (files took 9.71 seconds to load)&lt;br /&gt;
5 examples, 0 failures&lt;br /&gt;
&lt;br /&gt;
Randomized with seed 65056&lt;br /&gt;
&lt;br /&gt;
Coverage report generated for RSpec to /.../expertiza/coverage. 2074 / 15378 LOC (13.49%) covered.&lt;br /&gt;
[Coveralls] Outside the Travis environment, not sending data.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
REST API tests for LatePoliciesController:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
$ rspec ./spec/controllers/late_policies_controller_spec.rb &lt;br /&gt;
&lt;br /&gt;
Randomized with seed 29277&lt;br /&gt;
........&lt;br /&gt;
&lt;br /&gt;
Finished in 17.56 seconds (files took 8.64 seconds to load)&lt;br /&gt;
8 examples, 0 failures&lt;br /&gt;
&lt;br /&gt;
Randomized with seed 29277&lt;br /&gt;
&lt;br /&gt;
Coverage report generated for RSpec to /.../expertiza/coverage. 1587 / 15800 LOC (10.04%) covered.&lt;br /&gt;
[Coveralls] Outside the Travis environment, not sending data.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Back button tests&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
$ rspec ./spec/features/late_policy_back_button_spec.rb &lt;br /&gt;
Randomized with seed 15242&lt;br /&gt;
.&lt;br /&gt;
&lt;br /&gt;
Finished in 9.74 seconds (files took 8.95 seconds to load)&lt;br /&gt;
1 example, 0 failures&lt;br /&gt;
&lt;br /&gt;
Randomized with seed 15242&lt;br /&gt;
&lt;br /&gt;
Coverage report generated for RSpec to /.../expertiza/coverage. 2041 / 15378 LOC (13.27%) covered.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===References===&lt;br /&gt;
&lt;br /&gt;
#[https://github.com/expertiza/expertiza Expertiza on GitHub]&lt;br /&gt;
#[https://github.com/vinay-deshmukh/expertiza GitHub Project Repository Fork]&lt;br /&gt;
#[https://github.com/expertiza/expertiza/pull/2087/ Pull request to Expertiza repo]&lt;br /&gt;
#[https://github.com/vinay-deshmukh/expertiza/projects/1 GitHub Fork: Project board]&lt;br /&gt;
#[https://github.com/vinay-deshmukh/expertiza/issues Issues made while development]&lt;br /&gt;
#[https://github.com/vinay-deshmukh/expertiza/pulls  Pull requests made to the fork to document work]&lt;br /&gt;
#[https://github.com/vinay-deshmukh/expertiza/pulls?q=is%3Apr+is%3Aclosed Closed Pull Requests on Fork]&lt;/div&gt;</summary>
		<author><name>Vdeshmu</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2021_-_E2140._Create_new_late_policy_successfully_and_fix_Bank_link&amp;diff=139901</id>
		<title>CSC/ECE 517 Fall 2021 - E2140. Create new late policy successfully and fix Bank link</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2021_-_E2140._Create_new_late_policy_successfully_and_fix_Bank_link&amp;diff=139901"/>
		<updated>2021-10-21T21:01:14Z</updated>

		<summary type="html">&lt;p&gt;Vdeshmu: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
==E2140. Create new late policy successfully and fix &amp;quot;Back&amp;quot; link==&lt;br /&gt;
&lt;br /&gt;
This page provides a description of the Expertiza based OSS project, E1240.&lt;br /&gt;
&lt;br /&gt;
===About Expertiza===&lt;br /&gt;
&lt;br /&gt;
[http://expertiza.ncsu.edu/ Expertiza] is an open source project based on [http://rubyonrails.org/ Ruby on Rails] framework. Expertiza allows the instructor to create new assignments and customize new or existing assignments. It also allows the instructor to create a list of topics the students can sign up for. Students can form teams in Expertiza to work on various projects and assignments. Students can also peer review other students' submissions. Expertiza supports submission across various document types, including the URLs and wiki pages.&lt;br /&gt;
&lt;br /&gt;
===Problem Statement===&lt;br /&gt;
Create new late policy successfull and fix &amp;quot;Back&amp;quot; link.&lt;br /&gt;
&lt;br /&gt;
Please note: As the initial bug fix was only a few lines of code/it was halfway fixed, after discussing with mentor, the project was converted into a &amp;quot;testing project&amp;quot;, where we focused on writing tests for the implemented features.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Fixes performed==&lt;br /&gt;
&lt;br /&gt;
* Fix back link on &amp;quot;New late policy&amp;quot; page.&lt;br /&gt;
* Fix incorrect flash message on the screen when new late policy is created&lt;br /&gt;
* Add controller unit tests for create and edit actions for late_policies_controller&lt;br /&gt;
* Add functional test for late policy creation&lt;br /&gt;
* Add functional test for back button on new late policy page&lt;br /&gt;
* Improve flow of late_policies_controller#edit action for better tests&lt;br /&gt;
* Fix late_policies_controller#edit action when it displayed two contradictory flashes&lt;br /&gt;
* SQL stack trace showed up when long string is entered in policy name, this has been fixed to show a different error to user&lt;br /&gt;
* View was checked after a controller test to ensure that the correct message is shown to the user.&lt;br /&gt;
* Database was checked after controller test to verify whether correct changes happened or didn't.&lt;br /&gt;
* model was also checked to ensure the database is in a correct state&lt;br /&gt;
&lt;br /&gt;
===About Late Policies Controller===&lt;br /&gt;
&lt;br /&gt;
This controller can be accessed by editing an assignment, going on &amp;quot;Due Dates&amp;quot; page and  clicking on &amp;quot;New late policy&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
== Files modified in current project ==&lt;br /&gt;
&lt;br /&gt;
1. app/controllers/late_policies_controller.rb &amp;lt;br/&amp;gt;&lt;br /&gt;
2. app/views/late_policies/new.html.erb &amp;lt;br/&amp;gt;&lt;br /&gt;
3. spec/factories/factories.rb&amp;lt;br/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Files added for tests==&lt;br /&gt;
&lt;br /&gt;
1. spec/controllers/late_policies_controller_spec.rb &amp;lt;br/&amp;gt;&lt;br /&gt;
2. spec/features/late_policy_creation_spec.rb &amp;lt;br/&amp;gt;&lt;br /&gt;
3. spec/features/late_policy_back_button_spec.rb &amp;lt;br/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Files modified for tests==&lt;br /&gt;
&lt;br /&gt;
1. spec/factories/factories.rb&amp;lt;br /&amp;gt;&lt;br /&gt;
2. app/controllers/late_policies_controller.rb&lt;br /&gt;
&lt;br /&gt;
===Current Implementation===&lt;br /&gt;
&lt;br /&gt;
* There were no tests present in beta branch, so tests for the CRUD operations were added.&lt;br /&gt;
* Edit action for late_policies_controller is complex to reason about, with booleans deciding whether there are errors.&lt;br /&gt;
* Back button does not lead to the assignment from which the new late policy page was created.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=====Drawbacks and Solutions=====&lt;br /&gt;
* '''Problem 1''': Back button was taking user to index of late_policies, and not assignment due dates page&lt;br /&gt;
::The back button was performing it's default action of going back to index page of late_policies, but it needs to send user to the assginment page.&lt;br /&gt;
&lt;br /&gt;
Before: &amp;lt;br /&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;%= link_to 'Back', :action =&amp;gt; 'index' %&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
After: &amp;lt;br /&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;%= link_to 'Back', edit_assignment_path(session[:edit_assignment]) %&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
* '''Solution''': The link_to function is called with the link to the assignment which was last edited, so it will go to assginment page.&lt;br /&gt;
&lt;br /&gt;
* Use edit_assignment_path(session[:edit_assignment]) to go back to the previous page&lt;br /&gt;
&lt;br /&gt;
* '''Problem 2''': Creating new policy with blank fields does not give a proper error&lt;br /&gt;
::The existing code just shows a blank error, without specifying what has gone wrong. Hence, user will not know what is wrong when they created a new policy.&lt;br /&gt;
&lt;br /&gt;
* '''Solution''':  The existing error handling code was changed to show the ActiveRecord::Invalid errors to user. And in case, a different exception occurs, a &amp;quot;Something went wrong&amp;quot; message is shown, as this exception shouldn't be visible to users.&lt;br /&gt;
        &lt;br /&gt;
Before:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
      rescue StandardError&lt;br /&gt;
        flash[:error] = &amp;quot;The following error occurred while saving the penalty policy: &amp;quot;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
After:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
      rescue ActiveRecord::RecordInvalid =&amp;gt; exception&lt;br /&gt;
        flash[:error] = exception.record.errors.full_messages.join(&amp;quot;&amp;lt;br /&amp;gt;&amp;quot;).html_safe&lt;br /&gt;
        redirect_to action: 'new'&lt;br /&gt;
      rescue StandardError =&amp;gt; exception&lt;br /&gt;
        # In case it's some error, this error should not be shown to users&lt;br /&gt;
        flash[:error] = &amp;quot;Something went wrong&amp;quot;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* '''Problem 3''':  Update `update` method of late_policies_controller &lt;br /&gt;
:: Existing update method was too convoluted to read and due to it's convolution, it was showing wrong errors on screen.&lt;br /&gt;
* '''Solution''': &lt;br /&gt;
The control flow of the `update` method was improved to use early exits when errors occur, instead of using booleans to manage execution.&lt;br /&gt;
&lt;br /&gt;
===Code improvements===&lt;br /&gt;
late_policies_controller#update&lt;br /&gt;
Before&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    @penalty_policy = LatePolicy.find(params[:id])&lt;br /&gt;
    flash[:error] = &amp;quot;The maximum penalty cannot be less than penalty per unit.&amp;quot; if invalid_penalty_per_unit&lt;br /&gt;
    same_policy_name = false&lt;br /&gt;
    # if name has changed then only check for this&lt;br /&gt;
    if same_policy_name == LatePolicy.check_policy_with_same_name(params[:late_policy][:policy_name], instructor_id)&lt;br /&gt;
      flash[:error] = &amp;quot;The policy could not be updated because a policy with the same name already exists.&amp;quot;&lt;br /&gt;
    if !same_policy_name &amp;amp;&amp;amp; !invalid_penalty_per_unit&lt;br /&gt;
      begin&lt;br /&gt;
        @penalty_policy.update_attributes(late_policy_params)&lt;br /&gt;
        @penalty_policy.save!&lt;br /&gt;
        LatePolicy.update_calculated_penalty_objects(@penalty_policy)&lt;br /&gt;
        flash[:notice] = &amp;quot;The late policy was successfully updated.&amp;quot;&lt;br /&gt;
        redirect_to action: 'index'&lt;br /&gt;
      rescue StandardError&lt;br /&gt;
        flash[:error] = &amp;quot;The following error occurred while updating the penalty policy: &amp;quot;&lt;br /&gt;
        redirect_to action: 'edit', id: params[:id]&lt;br /&gt;
      end&lt;br /&gt;
    elsif invalid_penalty_per_unit&lt;br /&gt;
      flash[:error] = &amp;quot;Cannot edit the policy. The maximum penalty cannot be less than penalty per unit.&amp;quot;&lt;br /&gt;
      redirect_to action: 'edit', id: params[:id]&lt;br /&gt;
    elsif same_policy_name&lt;br /&gt;
      flash[:error] = &amp;quot;Cannot edit the policy. A policy with the same name &amp;quot; + params[:late_policy][:policy_name] + &amp;quot; already exists.&amp;quot;&lt;br /&gt;
      redirect_to action: 'edit', id: params[:id]&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
After:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    invalid_penalty_per_unit = params[:late_policy][:max_penalty].to_i &amp;lt; params[:late_policy][:penalty_per_unit].to_i&lt;br /&gt;
    # If penalty per unit is invalid, exit early&lt;br /&gt;
    if invalid_penalty_per_unit&lt;br /&gt;
      flash[:error] = &amp;quot;Cannot edit the policy. The maximum penalty cannot be less than penalty per unit.&amp;quot;&lt;br /&gt;
      redirect_to action: 'edit', id: params[:id] and return&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    # Only do DB search if we pass the invalid penalty check&lt;br /&gt;
    @penalty_policy = LatePolicy.find(params[:id])&lt;br /&gt;
    # if name has changed, then only check for this&lt;br /&gt;
    if params[:late_policy][:policy_name] != @penalty_policy.policy_name&lt;br /&gt;
      if LatePolicy.check_policy_with_same_name(params[:late_policy][:policy_name], instructor_id)&lt;br /&gt;
        flash[:error] = &amp;quot;Cannot edit the policy. A policy with the same name &amp;quot; + params[:late_policy][:policy_name] + &amp;quot; already exists.&amp;quot;&lt;br /&gt;
        redirect_to action: 'edit', id: params[:id] and return&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    begin&lt;br /&gt;
      @penalty_policy.update_attributes(late_policy_params)&lt;br /&gt;
      @penalty_policy.save!&lt;br /&gt;
      LatePolicy.update_calculated_penalty_objects(@penalty_policy)&lt;br /&gt;
      flash[:notice] = &amp;quot;The late policy was successfully updated.&amp;quot;&lt;br /&gt;
      redirect_to action: 'index' and return&lt;br /&gt;
    rescue StandardError&lt;br /&gt;
      flash[:error] = &amp;quot;The following error occurred while updating the penalty policy: &amp;quot;&lt;br /&gt;
      redirect_to action: 'edit', id: params[:id] and return&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Test Plan===&lt;br /&gt;
&lt;br /&gt;
Late Policies Controller's CRUD methods were tested via unit tests to test the REST API, and they were also tested via capybara to emulate a user using the website.&lt;br /&gt;
&lt;br /&gt;
Test cases considered:&lt;br /&gt;
&lt;br /&gt;
1. Submitting an empty form when creating a new late policy &amp;lt;br /&amp;gt;&lt;br /&gt;
2. Using an maximum penalty that was less than the actual penalty &amp;lt;br /&amp;gt;&lt;br /&gt;
3. Penalty unit entered as negative number &amp;lt;br /&amp;gt;&lt;br /&gt;
4. Policy name is greater than 255 characters &amp;lt;br /&amp;gt;&lt;br /&gt;
5. Prevent creation of policy name if a policy with the same name already exists &amp;lt;br /&amp;gt;&lt;br /&gt;
6. Render the :new template successfully &amp;lt;br /&amp;gt;&lt;br /&gt;
7. Render the :edit template successfully &amp;lt;br /&amp;gt;&lt;br /&gt;
8. Prevents edit if policy name is being changed to an already existing policy's name &amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
For testing whether back button takes user back to the assginment edit page, we have used Capybara to emulate a user browsing the page. &amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
For capybara testing, we have considered the following tests: &amp;lt;br /&amp;gt;&lt;br /&gt;
1. Filling the form with blank values and then expecting failures as well as database not being updated. &amp;lt;br /&amp;gt;&lt;br /&gt;
2. Using a policy name that is longer than 255 characters (which is the database column length) &amp;lt;br /&amp;gt;&lt;br /&gt;
3. If user enters a negative penalty per point, the policy should not be created &amp;lt;br /&amp;gt;&lt;br /&gt;
4. Entering valid values in each field, should successfully create the late policy &amp;lt;br /&amp;gt;&lt;br /&gt;
5. If penalty per unit is greater than max penalty , then creation of late policy should fail. &amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Automated Testing using RSPEC===&lt;br /&gt;
The current version of expertiza did not have any test for LatePoliciesController, and for back button.&lt;br /&gt;
Using the test driven development(TDD) approach, we have added an exhaustive set of RSPEC tests for LatePoliciesController, to test creation and expected failure to create scenarios.&lt;br /&gt;
We have also added tests for back button on new late policy page.&lt;br /&gt;
Similarly, we have added feature tests for late policy creation.&lt;br /&gt;
&lt;br /&gt;
Late policy creation tests with Capybara&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
$ rspec ./spec/features/late_policy_creation_spec.rb &lt;br /&gt;
Randomized with seed 65056&lt;br /&gt;
.....&lt;br /&gt;
&lt;br /&gt;
Finished in 22.28 seconds (files took 9.71 seconds to load)&lt;br /&gt;
5 examples, 0 failures&lt;br /&gt;
&lt;br /&gt;
Randomized with seed 65056&lt;br /&gt;
&lt;br /&gt;
Coverage report generated for RSpec to /.../expertiza/coverage. 2074 / 15378 LOC (13.49%) covered.&lt;br /&gt;
[Coveralls] Outside the Travis environment, not sending data.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
REST API tests for LatePoliciesController:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
$ rspec ./spec/controllers/late_policies_controller_spec.rb &lt;br /&gt;
&lt;br /&gt;
Randomized with seed 29277&lt;br /&gt;
........&lt;br /&gt;
&lt;br /&gt;
Finished in 17.56 seconds (files took 8.64 seconds to load)&lt;br /&gt;
8 examples, 0 failures&lt;br /&gt;
&lt;br /&gt;
Randomized with seed 29277&lt;br /&gt;
&lt;br /&gt;
Coverage report generated for RSpec to /.../expertiza/coverage. 1587 / 15800 LOC (10.04%) covered.&lt;br /&gt;
[Coveralls] Outside the Travis environment, not sending data.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Back button tests&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
$ rspec ./spec/features/late_policy_back_button_spec.rb &lt;br /&gt;
Randomized with seed 15242&lt;br /&gt;
.&lt;br /&gt;
&lt;br /&gt;
Finished in 9.74 seconds (files took 8.95 seconds to load)&lt;br /&gt;
1 example, 0 failures&lt;br /&gt;
&lt;br /&gt;
Randomized with seed 15242&lt;br /&gt;
&lt;br /&gt;
Coverage report generated for RSpec to /.../expertiza/coverage. 2041 / 15378 LOC (13.27%) covered.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===References===&lt;br /&gt;
&lt;br /&gt;
#[https://github.com/expertiza/expertiza Expertiza on GitHub]&lt;br /&gt;
#[https://github.com/vinay-deshmukh/expertiza GitHub Project Repository Fork]&lt;br /&gt;
#[https://github.com/expertiza/expertiza/pull/2087/ Pull request to Expertiza repo]&lt;br /&gt;
#[https://github.com/vinay-deshmukh/expertiza/projects/1 GitHub Fork: Project board]&lt;br /&gt;
#[https://github.com/vinay-deshmukh/expertiza/issues Issues made while development]&lt;br /&gt;
#[https://github.com/vinay-deshmukh/expertiza/pulls  Pull requests made to the fork to document work]&lt;br /&gt;
#[https://github.com/vinay-deshmukh/expertiza/pulls?q=is%3Apr+is%3Aclosed Closed Pull Requests on Fork]&lt;/div&gt;</summary>
		<author><name>Vdeshmu</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2021_-_E2140._Create_new_late_policy_successfully_and_fix_Bank_link&amp;diff=139896</id>
		<title>CSC/ECE 517 Fall 2021 - E2140. Create new late policy successfully and fix Bank link</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2021_-_E2140._Create_new_late_policy_successfully_and_fix_Bank_link&amp;diff=139896"/>
		<updated>2021-10-21T16:40:07Z</updated>

		<summary type="html">&lt;p&gt;Vdeshmu: /* Fixes performed */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
==E2140. Create new late policy successfully and fix &amp;quot;Back&amp;quot; link==&lt;br /&gt;
&lt;br /&gt;
This page provides a description of the Expertiza based OSS project, E1240.&lt;br /&gt;
&lt;br /&gt;
===About Expertiza===&lt;br /&gt;
&lt;br /&gt;
[http://expertiza.ncsu.edu/ Expertiza] is an open source project based on [http://rubyonrails.org/ Ruby on Rails] framework. Expertiza allows the instructor to create new assignments and customize new or existing assignments. It also allows the instructor to create a list of topics the students can sign up for. Students can form teams in Expertiza to work on various projects and assignments. Students can also peer review other students' submissions. Expertiza supports submission across various document types, including the URLs and wiki pages.&lt;br /&gt;
&lt;br /&gt;
===Problem Statement===&lt;br /&gt;
Create new late policy successfull and fix &amp;quot;Back&amp;quot; link.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Fixes performed==&lt;br /&gt;
&lt;br /&gt;
* Fix back link on &amp;quot;New late policy&amp;quot; page.&lt;br /&gt;
* Fix incorrect flash message on the screen when new late policy is created&lt;br /&gt;
* Add controller unit tests for create and edit actions for late_policies_controller&lt;br /&gt;
* Add functional test for late policy creation&lt;br /&gt;
* Add functional test for back button on new late policy page&lt;br /&gt;
* Improve flow of late_policies_controller#edit action for better tests&lt;br /&gt;
* Fix late_policies_controller#edit action when it displayed two contradictory flashes&lt;br /&gt;
* SQL stack trace showed up when long string is entered in policy name, this has been fixed to show a different error to user&lt;br /&gt;
* View was checked after a controller test to ensure that the correct message is shown to the user.&lt;br /&gt;
* Database was checked after controller test to verify whether correct changes happened or didn't.&lt;br /&gt;
* model was also checked to ensure the database is in a correct state&lt;br /&gt;
&lt;br /&gt;
===About Late Policies Controller===&lt;br /&gt;
&lt;br /&gt;
This controller can be accessed by editing an assignment, going on &amp;quot;Due Dates&amp;quot; page and  clicking on &amp;quot;New late policy&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
== Files modified in current project ==&lt;br /&gt;
&lt;br /&gt;
1. app/controllers/late_policies_controller.rb &amp;lt;br/&amp;gt;&lt;br /&gt;
2. app/views/late_policies/new.html.erb &amp;lt;br/&amp;gt;&lt;br /&gt;
3. spec/factories/factories.rb&amp;lt;br/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Files added for tests==&lt;br /&gt;
&lt;br /&gt;
1. spec/controllers/late_policies_controller_spec.rb &amp;lt;br/&amp;gt;&lt;br /&gt;
2. spec/features/late_policy_creation_spec.rb &amp;lt;br/&amp;gt;&lt;br /&gt;
3. spec/features/late_policy_back_button_spec.rb &amp;lt;br/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Files modified for tests==&lt;br /&gt;
&lt;br /&gt;
1. spec/factories/factories.rb&amp;lt;br /&amp;gt;&lt;br /&gt;
2. app/controllers/late_policies_controller.rb&lt;br /&gt;
&lt;br /&gt;
===Current Implementation===&lt;br /&gt;
&lt;br /&gt;
* There were no tests present in beta branch, so tests for the CRUD operations were added.&lt;br /&gt;
* Edit action for late_policies_controller is complex to reason about, with booleans deciding whether there are errors.&lt;br /&gt;
* Back button does not lead to the assignment from which the new late policy page was created.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=====Drawbacks and Solutions=====&lt;br /&gt;
* '''Problem 1''': Back button was taking user to index of late_policies, and not assignment due dates page&lt;br /&gt;
::The back button was performing it's default action of going back to index page of late_policies, but it needs to send user to the assginment page.&lt;br /&gt;
&lt;br /&gt;
Before: &amp;lt;br /&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;%= link_to 'Back', :action =&amp;gt; 'index' %&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
After: &amp;lt;br /&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;%= link_to 'Back', edit_assignment_path(session[:edit_assignment]) %&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
* '''Solution''': The link_to function is called with the link to the assignment which was last edited, so it will go to assginment page.&lt;br /&gt;
&lt;br /&gt;
* Use edit_assignment_path(session[:edit_assignment]) to go back to the previous page&lt;br /&gt;
&lt;br /&gt;
* '''Problem 2''': Creating new policy with blank fields does not give a proper error&lt;br /&gt;
::The existing code just shows a blank error, without specifying what has gone wrong. Hence, user will not know what is wrong when they created a new policy.&lt;br /&gt;
&lt;br /&gt;
* '''Solution''':  The existing error handling code was changed to show the ActiveRecord::Invalid errors to user. And in case, a different exception occurs, a &amp;quot;Something went wrong&amp;quot; message is shown, as this exception shouldn't be visible to users.&lt;br /&gt;
        &lt;br /&gt;
Before:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
      rescue StandardError&lt;br /&gt;
        flash[:error] = &amp;quot;The following error occurred while saving the penalty policy: &amp;quot;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
After:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
      rescue ActiveRecord::RecordInvalid =&amp;gt; exception&lt;br /&gt;
        flash[:error] = exception.record.errors.full_messages.join(&amp;quot;&amp;lt;br /&amp;gt;&amp;quot;).html_safe&lt;br /&gt;
        redirect_to action: 'new'&lt;br /&gt;
      rescue StandardError =&amp;gt; exception&lt;br /&gt;
        # In case it's some error, this error should not be shown to users&lt;br /&gt;
        flash[:error] = &amp;quot;Something went wrong&amp;quot;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* '''Problem 3''':  Update `update` method of late_policies_controller &lt;br /&gt;
:: Existing update method was too convoluted to read and due to it's convolution, it was showing wrong errors on screen.&lt;br /&gt;
* '''Solution''': &lt;br /&gt;
The control flow of the `update` method was improved to use early exits when errors occur, instead of using booleans to manage execution.&lt;br /&gt;
&lt;br /&gt;
===Code improvements===&lt;br /&gt;
late_policies_controller#update&lt;br /&gt;
Before&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    @penalty_policy = LatePolicy.find(params[:id])&lt;br /&gt;
    flash[:error] = &amp;quot;The maximum penalty cannot be less than penalty per unit.&amp;quot; if invalid_penalty_per_unit&lt;br /&gt;
    same_policy_name = false&lt;br /&gt;
    # if name has changed then only check for this&lt;br /&gt;
    if same_policy_name == LatePolicy.check_policy_with_same_name(params[:late_policy][:policy_name], instructor_id)&lt;br /&gt;
      flash[:error] = &amp;quot;The policy could not be updated because a policy with the same name already exists.&amp;quot;&lt;br /&gt;
    if !same_policy_name &amp;amp;&amp;amp; !invalid_penalty_per_unit&lt;br /&gt;
      begin&lt;br /&gt;
        @penalty_policy.update_attributes(late_policy_params)&lt;br /&gt;
        @penalty_policy.save!&lt;br /&gt;
        LatePolicy.update_calculated_penalty_objects(@penalty_policy)&lt;br /&gt;
        flash[:notice] = &amp;quot;The late policy was successfully updated.&amp;quot;&lt;br /&gt;
        redirect_to action: 'index'&lt;br /&gt;
      rescue StandardError&lt;br /&gt;
        flash[:error] = &amp;quot;The following error occurred while updating the penalty policy: &amp;quot;&lt;br /&gt;
        redirect_to action: 'edit', id: params[:id]&lt;br /&gt;
      end&lt;br /&gt;
    elsif invalid_penalty_per_unit&lt;br /&gt;
      flash[:error] = &amp;quot;Cannot edit the policy. The maximum penalty cannot be less than penalty per unit.&amp;quot;&lt;br /&gt;
      redirect_to action: 'edit', id: params[:id]&lt;br /&gt;
    elsif same_policy_name&lt;br /&gt;
      flash[:error] = &amp;quot;Cannot edit the policy. A policy with the same name &amp;quot; + params[:late_policy][:policy_name] + &amp;quot; already exists.&amp;quot;&lt;br /&gt;
      redirect_to action: 'edit', id: params[:id]&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
After:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    invalid_penalty_per_unit = params[:late_policy][:max_penalty].to_i &amp;lt; params[:late_policy][:penalty_per_unit].to_i&lt;br /&gt;
    # If penalty per unit is invalid, exit early&lt;br /&gt;
    if invalid_penalty_per_unit&lt;br /&gt;
      flash[:error] = &amp;quot;Cannot edit the policy. The maximum penalty cannot be less than penalty per unit.&amp;quot;&lt;br /&gt;
      redirect_to action: 'edit', id: params[:id] and return&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    # Only do DB search if we pass the invalid penalty check&lt;br /&gt;
    @penalty_policy = LatePolicy.find(params[:id])&lt;br /&gt;
    # if name has changed, then only check for this&lt;br /&gt;
    if params[:late_policy][:policy_name] != @penalty_policy.policy_name&lt;br /&gt;
      if LatePolicy.check_policy_with_same_name(params[:late_policy][:policy_name], instructor_id)&lt;br /&gt;
        flash[:error] = &amp;quot;Cannot edit the policy. A policy with the same name &amp;quot; + params[:late_policy][:policy_name] + &amp;quot; already exists.&amp;quot;&lt;br /&gt;
        redirect_to action: 'edit', id: params[:id] and return&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    begin&lt;br /&gt;
      @penalty_policy.update_attributes(late_policy_params)&lt;br /&gt;
      @penalty_policy.save!&lt;br /&gt;
      LatePolicy.update_calculated_penalty_objects(@penalty_policy)&lt;br /&gt;
      flash[:notice] = &amp;quot;The late policy was successfully updated.&amp;quot;&lt;br /&gt;
      redirect_to action: 'index' and return&lt;br /&gt;
    rescue StandardError&lt;br /&gt;
      flash[:error] = &amp;quot;The following error occurred while updating the penalty policy: &amp;quot;&lt;br /&gt;
      redirect_to action: 'edit', id: params[:id] and return&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Test Plan===&lt;br /&gt;
&lt;br /&gt;
Late Policies Controller's CRUD methods were tested via unit tests to test the REST API, and they were also tested via capybara to emulate a user using the website.&lt;br /&gt;
&lt;br /&gt;
Test cases considered:&lt;br /&gt;
&lt;br /&gt;
1. Submitting an empty form when creating a new late policy &amp;lt;br /&amp;gt;&lt;br /&gt;
2. Using an maximum penalty that was less than the actual penalty &amp;lt;br /&amp;gt;&lt;br /&gt;
3. Penalty unit entered as negative number &amp;lt;br /&amp;gt;&lt;br /&gt;
4. Policy name is greater than 255 characters &amp;lt;br /&amp;gt;&lt;br /&gt;
5. Prevent creation of policy name if a policy with the same name already exists &amp;lt;br /&amp;gt;&lt;br /&gt;
6. Render the :new template successfully &amp;lt;br /&amp;gt;&lt;br /&gt;
7. Render the :edit template successfully &amp;lt;br /&amp;gt;&lt;br /&gt;
8. Prevents edit if policy name is being changed to an already existing policy's name &amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
For testing whether back button takes user back to the assginment edit page, we have used Capybara to emulate a user browsing the page. &amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
For capybara testing, we have considered the following tests: &amp;lt;br /&amp;gt;&lt;br /&gt;
1. Filling the form with blank values and then expecting failures as well as database not being updated. &amp;lt;br /&amp;gt;&lt;br /&gt;
2. Using a policy name that is longer than 255 characters (which is the database column length) &amp;lt;br /&amp;gt;&lt;br /&gt;
3. If user enters a negative penalty per point, the policy should not be created &amp;lt;br /&amp;gt;&lt;br /&gt;
4. Entering valid values in each field, should successfully create the late policy &amp;lt;br /&amp;gt;&lt;br /&gt;
5. If penalty per unit is greater than max penalty , then creation of late policy should fail. &amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Automated Testing using RSPEC===&lt;br /&gt;
The current version of expertiza did not have any test for LatePoliciesController, and for back button.&lt;br /&gt;
Using the test driven development(TDD) approach, we have added an exhaustive set of RSPEC tests for LatePoliciesController, to test creation and expected failure to create scenarios.&lt;br /&gt;
We have also added tests for back button on new late policy page.&lt;br /&gt;
Similarly, we have added feature tests for late policy creation.&lt;br /&gt;
&lt;br /&gt;
Late policy creation tests with Capybara&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
$ rspec ./spec/features/late_policy_creation_spec.rb &lt;br /&gt;
Randomized with seed 65056&lt;br /&gt;
.....&lt;br /&gt;
&lt;br /&gt;
Finished in 22.28 seconds (files took 9.71 seconds to load)&lt;br /&gt;
5 examples, 0 failures&lt;br /&gt;
&lt;br /&gt;
Randomized with seed 65056&lt;br /&gt;
&lt;br /&gt;
Coverage report generated for RSpec to /.../expertiza/coverage. 2074 / 15378 LOC (13.49%) covered.&lt;br /&gt;
[Coveralls] Outside the Travis environment, not sending data.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
REST API tests for LatePoliciesController:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
$ rspec ./spec/controllers/late_policies_controller_spec.rb &lt;br /&gt;
&lt;br /&gt;
Randomized with seed 29277&lt;br /&gt;
........&lt;br /&gt;
&lt;br /&gt;
Finished in 17.56 seconds (files took 8.64 seconds to load)&lt;br /&gt;
8 examples, 0 failures&lt;br /&gt;
&lt;br /&gt;
Randomized with seed 29277&lt;br /&gt;
&lt;br /&gt;
Coverage report generated for RSpec to /.../expertiza/coverage. 1587 / 15800 LOC (10.04%) covered.&lt;br /&gt;
[Coveralls] Outside the Travis environment, not sending data.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Back button tests&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
$ rspec ./spec/features/late_policy_back_button_spec.rb &lt;br /&gt;
Randomized with seed 15242&lt;br /&gt;
.&lt;br /&gt;
&lt;br /&gt;
Finished in 9.74 seconds (files took 8.95 seconds to load)&lt;br /&gt;
1 example, 0 failures&lt;br /&gt;
&lt;br /&gt;
Randomized with seed 15242&lt;br /&gt;
&lt;br /&gt;
Coverage report generated for RSpec to /.../expertiza/coverage. 2041 / 15378 LOC (13.27%) covered.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===References===&lt;br /&gt;
&lt;br /&gt;
#[https://github.com/expertiza/expertiza Expertiza on GitHub]&lt;br /&gt;
#[https://github.com/vinay-deshmukh/expertiza GitHub Project Repository Fork]&lt;br /&gt;
#[https://github.com/expertiza/expertiza/pull/2087/ Pull request to Expertiza repo]&lt;br /&gt;
#[https://github.com/vinay-deshmukh/expertiza/projects/1 GitHub Fork: Project board]&lt;br /&gt;
#[https://github.com/vinay-deshmukh/expertiza/issues Issues made while development]&lt;br /&gt;
#[https://github.com/vinay-deshmukh/expertiza/pulls  Pull requests made to the fork to document work]&lt;br /&gt;
#[https://github.com/vinay-deshmukh/expertiza/pulls?q=is%3Apr+is%3Aclosed Closed Pull Requests on Fork]&lt;/div&gt;</summary>
		<author><name>Vdeshmu</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2021_-_E2140._Create_new_late_policy_successfully_and_fix_Bank_link&amp;diff=139895</id>
		<title>CSC/ECE 517 Fall 2021 - E2140. Create new late policy successfully and fix Bank link</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2021_-_E2140._Create_new_late_policy_successfully_and_fix_Bank_link&amp;diff=139895"/>
		<updated>2021-10-21T15:09:29Z</updated>

		<summary type="html">&lt;p&gt;Vdeshmu: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
==E2140. Create new late policy successfully and fix &amp;quot;Back&amp;quot; link==&lt;br /&gt;
&lt;br /&gt;
This page provides a description of the Expertiza based OSS project, E1240.&lt;br /&gt;
&lt;br /&gt;
===About Expertiza===&lt;br /&gt;
&lt;br /&gt;
[http://expertiza.ncsu.edu/ Expertiza] is an open source project based on [http://rubyonrails.org/ Ruby on Rails] framework. Expertiza allows the instructor to create new assignments and customize new or existing assignments. It also allows the instructor to create a list of topics the students can sign up for. Students can form teams in Expertiza to work on various projects and assignments. Students can also peer review other students' submissions. Expertiza supports submission across various document types, including the URLs and wiki pages.&lt;br /&gt;
&lt;br /&gt;
===Problem Statement===&lt;br /&gt;
Create new late policy successfull and fix &amp;quot;Back&amp;quot; link.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Fixes performed==&lt;br /&gt;
&lt;br /&gt;
* Fix back link on &amp;quot;New late policy&amp;quot; page.&lt;br /&gt;
* Fix incorrect flash message on the screen when new late policy is created&lt;br /&gt;
* Add controller unit tests for create and edit actions for late_policies_controller&lt;br /&gt;
* Add functional test for late policy creation&lt;br /&gt;
* Add functional test for back button on new late policy page&lt;br /&gt;
* Improve flow of late_policies_controller#edit action for better tests&lt;br /&gt;
* Fix late_policies_controller#edit action when it displayed two contradictory flashes&lt;br /&gt;
* TODO: SQL stack trace shows up when long string is entered in policy name&lt;br /&gt;
* View was checked after a controller test to ensure that the correct message is shown to the user.&lt;br /&gt;
* Database was checked after controller test to verify whether correct changes happened or didn't.&lt;br /&gt;
* model was also checked to ensure the database is in a correct state&lt;br /&gt;
&lt;br /&gt;
===About Late Policies Controller===&lt;br /&gt;
&lt;br /&gt;
This controller can be accessed by editing an assignment, going on &amp;quot;Due Dates&amp;quot; page and  clicking on &amp;quot;New late policy&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
== Files modified in current project ==&lt;br /&gt;
&lt;br /&gt;
1. app/controllers/late_policies_controller.rb &amp;lt;br/&amp;gt;&lt;br /&gt;
2. app/views/late_policies/new.html.erb &amp;lt;br/&amp;gt;&lt;br /&gt;
3. spec/factories/factories.rb&amp;lt;br/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Files added for tests==&lt;br /&gt;
&lt;br /&gt;
1. spec/controllers/late_policies_controller_spec.rb &amp;lt;br/&amp;gt;&lt;br /&gt;
2. spec/features/late_policy_creation_spec.rb &amp;lt;br/&amp;gt;&lt;br /&gt;
3. spec/features/late_policy_back_button_spec.rb &amp;lt;br/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Files modified for tests==&lt;br /&gt;
&lt;br /&gt;
1. spec/factories/factories.rb&amp;lt;br /&amp;gt;&lt;br /&gt;
2. app/controllers/late_policies_controller.rb&lt;br /&gt;
&lt;br /&gt;
===Current Implementation===&lt;br /&gt;
&lt;br /&gt;
* There were no tests present in beta branch, so tests for the CRUD operations were added.&lt;br /&gt;
* Edit action for late_policies_controller is complex to reason about, with booleans deciding whether there are errors.&lt;br /&gt;
* Back button does not lead to the assignment from which the new late policy page was created.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=====Drawbacks and Solutions=====&lt;br /&gt;
* '''Problem 1''': Back button was taking user to index of late_policies, and not assignment due dates page&lt;br /&gt;
::The back button was performing it's default action of going back to index page of late_policies, but it needs to send user to the assginment page.&lt;br /&gt;
&lt;br /&gt;
Before: &amp;lt;br /&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;%= link_to 'Back', :action =&amp;gt; 'index' %&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
After: &amp;lt;br /&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;%= link_to 'Back', edit_assignment_path(session[:edit_assignment]) %&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
* '''Solution''': The link_to function is called with the link to the assignment which was last edited, so it will go to assginment page.&lt;br /&gt;
&lt;br /&gt;
* Use edit_assignment_path(session[:edit_assignment]) to go back to the previous page&lt;br /&gt;
&lt;br /&gt;
* '''Problem 2''': Creating new policy with blank fields does not give a proper error&lt;br /&gt;
::The existing code just shows a blank error, without specifying what has gone wrong. Hence, user will not know what is wrong when they created a new policy.&lt;br /&gt;
&lt;br /&gt;
* '''Solution''':  The existing error handling code was changed to show the ActiveRecord::Invalid errors to user. And in case, a different exception occurs, a &amp;quot;Something went wrong&amp;quot; message is shown, as this exception shouldn't be visible to users.&lt;br /&gt;
        &lt;br /&gt;
Before:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
      rescue StandardError&lt;br /&gt;
        flash[:error] = &amp;quot;The following error occurred while saving the penalty policy: &amp;quot;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
After:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
      rescue ActiveRecord::RecordInvalid =&amp;gt; exception&lt;br /&gt;
        flash[:error] = exception.record.errors.full_messages.join(&amp;quot;&amp;lt;br /&amp;gt;&amp;quot;).html_safe&lt;br /&gt;
        redirect_to action: 'new'&lt;br /&gt;
      rescue StandardError =&amp;gt; exception&lt;br /&gt;
        # In case it's some error, this error should not be shown to users&lt;br /&gt;
        flash[:error] = &amp;quot;Something went wrong&amp;quot;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* '''Problem 3''':  Update `update` method of late_policies_controller &lt;br /&gt;
:: Existing update method was too convoluted to read and due to it's convolution, it was showing wrong errors on screen.&lt;br /&gt;
* '''Solution''': &lt;br /&gt;
The control flow of the `update` method was improved to use early exits when errors occur, instead of using booleans to manage execution.&lt;br /&gt;
&lt;br /&gt;
===Code improvements===&lt;br /&gt;
late_policies_controller#update&lt;br /&gt;
Before&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    @penalty_policy = LatePolicy.find(params[:id])&lt;br /&gt;
    flash[:error] = &amp;quot;The maximum penalty cannot be less than penalty per unit.&amp;quot; if invalid_penalty_per_unit&lt;br /&gt;
    same_policy_name = false&lt;br /&gt;
    # if name has changed then only check for this&lt;br /&gt;
    if same_policy_name == LatePolicy.check_policy_with_same_name(params[:late_policy][:policy_name], instructor_id)&lt;br /&gt;
      flash[:error] = &amp;quot;The policy could not be updated because a policy with the same name already exists.&amp;quot;&lt;br /&gt;
    if !same_policy_name &amp;amp;&amp;amp; !invalid_penalty_per_unit&lt;br /&gt;
      begin&lt;br /&gt;
        @penalty_policy.update_attributes(late_policy_params)&lt;br /&gt;
        @penalty_policy.save!&lt;br /&gt;
        LatePolicy.update_calculated_penalty_objects(@penalty_policy)&lt;br /&gt;
        flash[:notice] = &amp;quot;The late policy was successfully updated.&amp;quot;&lt;br /&gt;
        redirect_to action: 'index'&lt;br /&gt;
      rescue StandardError&lt;br /&gt;
        flash[:error] = &amp;quot;The following error occurred while updating the penalty policy: &amp;quot;&lt;br /&gt;
        redirect_to action: 'edit', id: params[:id]&lt;br /&gt;
      end&lt;br /&gt;
    elsif invalid_penalty_per_unit&lt;br /&gt;
      flash[:error] = &amp;quot;Cannot edit the policy. The maximum penalty cannot be less than penalty per unit.&amp;quot;&lt;br /&gt;
      redirect_to action: 'edit', id: params[:id]&lt;br /&gt;
    elsif same_policy_name&lt;br /&gt;
      flash[:error] = &amp;quot;Cannot edit the policy. A policy with the same name &amp;quot; + params[:late_policy][:policy_name] + &amp;quot; already exists.&amp;quot;&lt;br /&gt;
      redirect_to action: 'edit', id: params[:id]&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
After:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    invalid_penalty_per_unit = params[:late_policy][:max_penalty].to_i &amp;lt; params[:late_policy][:penalty_per_unit].to_i&lt;br /&gt;
    # If penalty per unit is invalid, exit early&lt;br /&gt;
    if invalid_penalty_per_unit&lt;br /&gt;
      flash[:error] = &amp;quot;Cannot edit the policy. The maximum penalty cannot be less than penalty per unit.&amp;quot;&lt;br /&gt;
      redirect_to action: 'edit', id: params[:id] and return&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    # Only do DB search if we pass the invalid penalty check&lt;br /&gt;
    @penalty_policy = LatePolicy.find(params[:id])&lt;br /&gt;
    # if name has changed, then only check for this&lt;br /&gt;
    if params[:late_policy][:policy_name] != @penalty_policy.policy_name&lt;br /&gt;
      if LatePolicy.check_policy_with_same_name(params[:late_policy][:policy_name], instructor_id)&lt;br /&gt;
        flash[:error] = &amp;quot;Cannot edit the policy. A policy with the same name &amp;quot; + params[:late_policy][:policy_name] + &amp;quot; already exists.&amp;quot;&lt;br /&gt;
        redirect_to action: 'edit', id: params[:id] and return&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    begin&lt;br /&gt;
      @penalty_policy.update_attributes(late_policy_params)&lt;br /&gt;
      @penalty_policy.save!&lt;br /&gt;
      LatePolicy.update_calculated_penalty_objects(@penalty_policy)&lt;br /&gt;
      flash[:notice] = &amp;quot;The late policy was successfully updated.&amp;quot;&lt;br /&gt;
      redirect_to action: 'index' and return&lt;br /&gt;
    rescue StandardError&lt;br /&gt;
      flash[:error] = &amp;quot;The following error occurred while updating the penalty policy: &amp;quot;&lt;br /&gt;
      redirect_to action: 'edit', id: params[:id] and return&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Test Plan===&lt;br /&gt;
&lt;br /&gt;
Late Policies Controller's CRUD methods were tested via unit tests to test the REST API, and they were also tested via capybara to emulate a user using the website.&lt;br /&gt;
&lt;br /&gt;
Test cases considered:&lt;br /&gt;
&lt;br /&gt;
1. Submitting an empty form when creating a new late policy &amp;lt;br /&amp;gt;&lt;br /&gt;
2. Using an maximum penalty that was less than the actual penalty &amp;lt;br /&amp;gt;&lt;br /&gt;
3. Penalty unit entered as negative number &amp;lt;br /&amp;gt;&lt;br /&gt;
4. Policy name is greater than 255 characters &amp;lt;br /&amp;gt;&lt;br /&gt;
5. Prevent creation of policy name if a policy with the same name already exists &amp;lt;br /&amp;gt;&lt;br /&gt;
6. Render the :new template successfully &amp;lt;br /&amp;gt;&lt;br /&gt;
7. Render the :edit template successfully &amp;lt;br /&amp;gt;&lt;br /&gt;
8. Prevents edit if policy name is being changed to an already existing policy's name &amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
For testing whether back button takes user back to the assginment edit page, we have used Capybara to emulate a user browsing the page. &amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
For capybara testing, we have considered the following tests: &amp;lt;br /&amp;gt;&lt;br /&gt;
1. Filling the form with blank values and then expecting failures as well as database not being updated. &amp;lt;br /&amp;gt;&lt;br /&gt;
2. Using a policy name that is longer than 255 characters (which is the database column length) &amp;lt;br /&amp;gt;&lt;br /&gt;
3. If user enters a negative penalty per point, the policy should not be created &amp;lt;br /&amp;gt;&lt;br /&gt;
4. Entering valid values in each field, should successfully create the late policy &amp;lt;br /&amp;gt;&lt;br /&gt;
5. If penalty per unit is greater than max penalty , then creation of late policy should fail. &amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Automated Testing using RSPEC===&lt;br /&gt;
The current version of expertiza did not have any test for LatePoliciesController, and for back button.&lt;br /&gt;
Using the test driven development(TDD) approach, we have added an exhaustive set of RSPEC tests for LatePoliciesController, to test creation and expected failure to create scenarios.&lt;br /&gt;
We have also added tests for back button on new late policy page.&lt;br /&gt;
Similarly, we have added feature tests for late policy creation.&lt;br /&gt;
&lt;br /&gt;
Late policy creation tests with Capybara&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
$ rspec ./spec/features/late_policy_creation_spec.rb &lt;br /&gt;
Randomized with seed 65056&lt;br /&gt;
.....&lt;br /&gt;
&lt;br /&gt;
Finished in 22.28 seconds (files took 9.71 seconds to load)&lt;br /&gt;
5 examples, 0 failures&lt;br /&gt;
&lt;br /&gt;
Randomized with seed 65056&lt;br /&gt;
&lt;br /&gt;
Coverage report generated for RSpec to /.../expertiza/coverage. 2074 / 15378 LOC (13.49%) covered.&lt;br /&gt;
[Coveralls] Outside the Travis environment, not sending data.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
REST API tests for LatePoliciesController:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
$ rspec ./spec/controllers/late_policies_controller_spec.rb &lt;br /&gt;
&lt;br /&gt;
Randomized with seed 29277&lt;br /&gt;
........&lt;br /&gt;
&lt;br /&gt;
Finished in 17.56 seconds (files took 8.64 seconds to load)&lt;br /&gt;
8 examples, 0 failures&lt;br /&gt;
&lt;br /&gt;
Randomized with seed 29277&lt;br /&gt;
&lt;br /&gt;
Coverage report generated for RSpec to /.../expertiza/coverage. 1587 / 15800 LOC (10.04%) covered.&lt;br /&gt;
[Coveralls] Outside the Travis environment, not sending data.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Back button tests&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
$ rspec ./spec/features/late_policy_back_button_spec.rb &lt;br /&gt;
Randomized with seed 15242&lt;br /&gt;
.&lt;br /&gt;
&lt;br /&gt;
Finished in 9.74 seconds (files took 8.95 seconds to load)&lt;br /&gt;
1 example, 0 failures&lt;br /&gt;
&lt;br /&gt;
Randomized with seed 15242&lt;br /&gt;
&lt;br /&gt;
Coverage report generated for RSpec to /.../expertiza/coverage. 2041 / 15378 LOC (13.27%) covered.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===References===&lt;br /&gt;
&lt;br /&gt;
#[https://github.com/expertiza/expertiza Expertiza on GitHub]&lt;br /&gt;
#[https://github.com/vinay-deshmukh/expertiza GitHub Project Repository Fork]&lt;br /&gt;
#[https://github.com/expertiza/expertiza/pull/2087/ Pull request to Expertiza repo]&lt;br /&gt;
#[https://github.com/vinay-deshmukh/expertiza/projects/1 GitHub Fork: Project board]&lt;br /&gt;
#[https://github.com/vinay-deshmukh/expertiza/issues Issues made while development]&lt;br /&gt;
#[https://github.com/vinay-deshmukh/expertiza/pulls  Pull requests made to the fork to document work]&lt;br /&gt;
#[https://github.com/vinay-deshmukh/expertiza/pulls?q=is%3Apr+is%3Aclosed Closed Pull Requests on Fork]&lt;/div&gt;</summary>
		<author><name>Vdeshmu</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2021_-_E2140._Create_new_late_policy_successfully_and_fix_Bank_link&amp;diff=139894</id>
		<title>CSC/ECE 517 Fall 2021 - E2140. Create new late policy successfully and fix Bank link</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2021_-_E2140._Create_new_late_policy_successfully_and_fix_Bank_link&amp;diff=139894"/>
		<updated>2021-10-21T15:07:53Z</updated>

		<summary type="html">&lt;p&gt;Vdeshmu: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
==E2140. Create new late policy successfully and fix &amp;quot;Back&amp;quot; link==&lt;br /&gt;
&lt;br /&gt;
This page provides a description of the Expertiza based OSS project, E1240.&lt;br /&gt;
&lt;br /&gt;
===About Expertiza===&lt;br /&gt;
&lt;br /&gt;
[http://expertiza.ncsu.edu/ Expertiza] is an open source project based on [http://rubyonrails.org/ Ruby on Rails] framework. Expertiza allows the instructor to create new assignments and customize new or existing assignments. It also allows the instructor to create a list of topics the students can sign up for. Students can form teams in Expertiza to work on various projects and assignments. Students can also peer review other students' submissions. Expertiza supports submission across various document types, including the URLs and wiki pages.&lt;br /&gt;
&lt;br /&gt;
===Problem Statement===&lt;br /&gt;
Create new late policy successfull and fix &amp;quot;Back&amp;quot; link.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Fixes performed==&lt;br /&gt;
&lt;br /&gt;
* Fix back link on &amp;quot;New late policy&amp;quot; page.&lt;br /&gt;
* Fix incorrect flash message on the screen when new late policy is created&lt;br /&gt;
* Add controller unit tests for create and edit actions for late_policies_controller&lt;br /&gt;
* Add functional test for late policy creation&lt;br /&gt;
* Add functional test for back button on new late policy page&lt;br /&gt;
* Improve flow of late_policies_controller#edit action for better tests&lt;br /&gt;
* Fix late_policies_controller#edit action when it displayed two contradictory flashes&lt;br /&gt;
* TODO: SQL stack trace shows up when long string is entered in policy name&lt;br /&gt;
* View was checked after a controller test to ensure that the correct message is shown to the user.&lt;br /&gt;
* Database was checked after controller test to verify whether correct changes happened or didn't.&lt;br /&gt;
* model was also checked to ensure the database is in a correct state&lt;br /&gt;
&lt;br /&gt;
===About Late Policies Controller===&lt;br /&gt;
&lt;br /&gt;
This controller can be accessed by editing an assignment, going on &amp;quot;Due Dates&amp;quot; page and  clicking on &amp;quot;New late policy&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
== Files modified in current project ==&lt;br /&gt;
&lt;br /&gt;
1. app/controllers/late_policies_controller.rb &amp;lt;br/&amp;gt;&lt;br /&gt;
2. app/views/late_policies/new.html.erb &amp;lt;br/&amp;gt;&lt;br /&gt;
3. spec/factories/factories.rb&amp;lt;br/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Files added for tests==&lt;br /&gt;
&lt;br /&gt;
1. spec/controllers/late_policies_controller_spec.rb &amp;lt;br/&amp;gt;&lt;br /&gt;
2. spec/features/late_policy_creation_spec.rb &amp;lt;br/&amp;gt;&lt;br /&gt;
3. spec/features/late_policy_back_button_spec.rb &amp;lt;br/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Files modified for tests==&lt;br /&gt;
&lt;br /&gt;
1. spec/factories/factories.rb&amp;lt;br /&amp;gt;&lt;br /&gt;
2. app/controllers/late_policies_controller.rb&lt;br /&gt;
&lt;br /&gt;
===Current Implementation===&lt;br /&gt;
&lt;br /&gt;
* There were no tests present in beta branch, so tests for the CRUD operations were added.&lt;br /&gt;
* Edit action for late_policies_controller is complex to reason about, with booleans deciding whether there are errors.&lt;br /&gt;
* Back button does not lead to the assignment from which the new late policy page was created.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=====Drawbacks and Solutions=====&lt;br /&gt;
* '''Problem 1''': Back button was taking user to index of late_policies, and not assignment due dates page&lt;br /&gt;
::The back button was performing it's default action of going back to index page of late_policies, but it needs to send user to the assginment page.&lt;br /&gt;
&lt;br /&gt;
Before: &amp;lt;br /&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;%= link_to 'Back', :action =&amp;gt; 'index' %&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
After: &amp;lt;br /&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;%= link_to 'Back', edit_assignment_path(session[:edit_assignment]) %&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
* '''Solution''': The link_to function is called with the link to the assignment which was last edited, so it will go to assginment page.&lt;br /&gt;
&lt;br /&gt;
* Use edit_assignment_path(session[:edit_assignment]) to go back to the previous page&lt;br /&gt;
&lt;br /&gt;
* '''Problem 2''': Creating new policy with blank fields does not give a proper error&lt;br /&gt;
::The existing code just shows a blank error, without specifying what has gone wrong. Hence, user will not know what is wrong when they created a new policy.&lt;br /&gt;
&lt;br /&gt;
* '''Solution''':  The existing error handling code was changed to show the ActiveRecord::Invalid errors to user. And in case, a different exception occurs, a &amp;quot;Something went wrong&amp;quot; message is shown, as this exception shouldn't be visible to users.&lt;br /&gt;
        &lt;br /&gt;
Before:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
      rescue StandardError&lt;br /&gt;
        flash[:error] = &amp;quot;The following error occurred while saving the penalty policy: &amp;quot;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
After:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
      rescue ActiveRecord::RecordInvalid =&amp;gt; exception&lt;br /&gt;
        flash[:error] = exception.record.errors.full_messages.join(&amp;quot;&amp;lt;br /&amp;gt;&amp;quot;).html_safe&lt;br /&gt;
        redirect_to action: 'new'&lt;br /&gt;
      rescue StandardError =&amp;gt; exception&lt;br /&gt;
        # In case it's some error, this error should not be shown to users&lt;br /&gt;
        flash[:error] = &amp;quot;Something went wrong&amp;quot;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* '''Problem 3''':  Update `update` method of late_policies_controller &lt;br /&gt;
:: Existing update method was too convoluted to read and due to it's convolution, it was showing wrong errors on screen.&lt;br /&gt;
* '''Solution''': &lt;br /&gt;
The control flow of the `update` method was improved to use early exits when errors occur, instead of using booleans to manage execution.&lt;br /&gt;
&lt;br /&gt;
===Code improvements===&lt;br /&gt;
late_policies_controller#update&lt;br /&gt;
Before&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    @penalty_policy = LatePolicy.find(params[:id])&lt;br /&gt;
    flash[:error] = &amp;quot;The maximum penalty cannot be less than penalty per unit.&amp;quot; if invalid_penalty_per_unit&lt;br /&gt;
    same_policy_name = false&lt;br /&gt;
    # if name has changed then only check for this&lt;br /&gt;
    if same_policy_name == LatePolicy.check_policy_with_same_name(params[:late_policy][:policy_name], instructor_id)&lt;br /&gt;
      flash[:error] = &amp;quot;The policy could not be updated because a policy with the same name already exists.&amp;quot;&lt;br /&gt;
    if !same_policy_name &amp;amp;&amp;amp; !invalid_penalty_per_unit&lt;br /&gt;
      begin&lt;br /&gt;
        @penalty_policy.update_attributes(late_policy_params)&lt;br /&gt;
        @penalty_policy.save!&lt;br /&gt;
        LatePolicy.update_calculated_penalty_objects(@penalty_policy)&lt;br /&gt;
        flash[:notice] = &amp;quot;The late policy was successfully updated.&amp;quot;&lt;br /&gt;
        redirect_to action: 'index'&lt;br /&gt;
      rescue StandardError&lt;br /&gt;
        flash[:error] = &amp;quot;The following error occurred while updating the penalty policy: &amp;quot;&lt;br /&gt;
        redirect_to action: 'edit', id: params[:id]&lt;br /&gt;
      end&lt;br /&gt;
    elsif invalid_penalty_per_unit&lt;br /&gt;
      flash[:error] = &amp;quot;Cannot edit the policy. The maximum penalty cannot be less than penalty per unit.&amp;quot;&lt;br /&gt;
      redirect_to action: 'edit', id: params[:id]&lt;br /&gt;
    elsif same_policy_name&lt;br /&gt;
      flash[:error] = &amp;quot;Cannot edit the policy. A policy with the same name &amp;quot; + params[:late_policy][:policy_name] + &amp;quot; already exists.&amp;quot;&lt;br /&gt;
      redirect_to action: 'edit', id: params[:id]&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
After:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    invalid_penalty_per_unit = params[:late_policy][:max_penalty].to_i &amp;lt; params[:late_policy][:penalty_per_unit].to_i&lt;br /&gt;
    # If penalty per unit is invalid, exit early&lt;br /&gt;
    if invalid_penalty_per_unit&lt;br /&gt;
      flash[:error] = &amp;quot;Cannot edit the policy. The maximum penalty cannot be less than penalty per unit.&amp;quot;&lt;br /&gt;
      redirect_to action: 'edit', id: params[:id] and return&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    # Only do DB search if we pass the invalid penalty check&lt;br /&gt;
    @penalty_policy = LatePolicy.find(params[:id])&lt;br /&gt;
    # if name has changed, then only check for this&lt;br /&gt;
    if params[:late_policy][:policy_name] != @penalty_policy.policy_name&lt;br /&gt;
      if LatePolicy.check_policy_with_same_name(params[:late_policy][:policy_name], instructor_id)&lt;br /&gt;
        flash[:error] = &amp;quot;Cannot edit the policy. A policy with the same name &amp;quot; + params[:late_policy][:policy_name] + &amp;quot; already exists.&amp;quot;&lt;br /&gt;
        redirect_to action: 'edit', id: params[:id] and return&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    begin&lt;br /&gt;
      @penalty_policy.update_attributes(late_policy_params)&lt;br /&gt;
      @penalty_policy.save!&lt;br /&gt;
      LatePolicy.update_calculated_penalty_objects(@penalty_policy)&lt;br /&gt;
      flash[:notice] = &amp;quot;The late policy was successfully updated.&amp;quot;&lt;br /&gt;
      redirect_to action: 'index' and return&lt;br /&gt;
    rescue StandardError&lt;br /&gt;
      flash[:error] = &amp;quot;The following error occurred while updating the penalty policy: &amp;quot;&lt;br /&gt;
      redirect_to action: 'edit', id: params[:id] and return&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Test Plan===&lt;br /&gt;
&lt;br /&gt;
Late Policies Controller's CRUD methods were tested via unit tests to test the REST API, and they were also tested via capybara to emulate a user using the website.&lt;br /&gt;
&lt;br /&gt;
Test cases considered:&lt;br /&gt;
&lt;br /&gt;
1. Submitting an empty form when creating a new late policy&lt;br /&gt;
2. Using an maximum penalty that was less than the actual penalty&lt;br /&gt;
3. Penalty unit entered as negative number&lt;br /&gt;
4. Policy name is greater than 255 characters&lt;br /&gt;
5. Prevent creation of policy name if a policy with the same name already exists&lt;br /&gt;
6. Render the :new template successfully&lt;br /&gt;
7. Render the :edit template successfully&lt;br /&gt;
8. Prevents edit if policy name is being changed to an already existing policy's name&lt;br /&gt;
&lt;br /&gt;
For testing whether back button takes user back to the assginment edit page, we have used Capybara to emulate a user browsing the page.&lt;br /&gt;
&lt;br /&gt;
For capybara testing, we have considered the following tests:&lt;br /&gt;
1. Filling the form with blank values and then expecting failures as well as database not being updated.&lt;br /&gt;
2. Using a policy name that is longer than 255 characters (which is the database column length)&lt;br /&gt;
3. If user enters a negative penalty per point, the policy should not be created&lt;br /&gt;
4. Entering valid values in each field, should successfully create the late policy&lt;br /&gt;
5. If penalty per unit is greater than max penalty , then creation of late policy should fail.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===Automated Testing using RSPEC===&lt;br /&gt;
The current version of expertiza did not have any test for LatePoliciesController, and for back button.&lt;br /&gt;
Using the test driven development(TDD) approach, we have added an exhaustive set of RSPEC tests for LatePoliciesController, to test creation and expected failure to create scenarios.&lt;br /&gt;
We have also added tests for back button on new late policy page.&lt;br /&gt;
Similarly, we have added feature tests for late policy creation.&lt;br /&gt;
&lt;br /&gt;
Late policy creation tests with Capybara&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
$ rspec ./spec/features/late_policy_creation_spec.rb &lt;br /&gt;
Randomized with seed 65056&lt;br /&gt;
.....&lt;br /&gt;
&lt;br /&gt;
Finished in 22.28 seconds (files took 9.71 seconds to load)&lt;br /&gt;
5 examples, 0 failures&lt;br /&gt;
&lt;br /&gt;
Randomized with seed 65056&lt;br /&gt;
&lt;br /&gt;
Coverage report generated for RSpec to /.../expertiza/coverage. 2074 / 15378 LOC (13.49%) covered.&lt;br /&gt;
[Coveralls] Outside the Travis environment, not sending data.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
REST API tests for LatePoliciesController:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
$ rspec ./spec/controllers/late_policies_controller_spec.rb &lt;br /&gt;
&lt;br /&gt;
Randomized with seed 29277&lt;br /&gt;
........&lt;br /&gt;
&lt;br /&gt;
Finished in 17.56 seconds (files took 8.64 seconds to load)&lt;br /&gt;
8 examples, 0 failures&lt;br /&gt;
&lt;br /&gt;
Randomized with seed 29277&lt;br /&gt;
&lt;br /&gt;
Coverage report generated for RSpec to /.../expertiza/coverage. 1587 / 15800 LOC (10.04%) covered.&lt;br /&gt;
[Coveralls] Outside the Travis environment, not sending data.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Back button tests&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
$ rspec ./spec/features/late_policy_back_button_spec.rb &lt;br /&gt;
Randomized with seed 15242&lt;br /&gt;
.&lt;br /&gt;
&lt;br /&gt;
Finished in 9.74 seconds (files took 8.95 seconds to load)&lt;br /&gt;
1 example, 0 failures&lt;br /&gt;
&lt;br /&gt;
Randomized with seed 15242&lt;br /&gt;
&lt;br /&gt;
Coverage report generated for RSpec to /.../expertiza/coverage. 2041 / 15378 LOC (13.27%) covered.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===References===&lt;br /&gt;
&lt;br /&gt;
#[https://github.com/expertiza/expertiza Expertiza on GitHub]&lt;br /&gt;
#[https://github.com/vinay-deshmukh/expertiza GitHub Project Repository Fork]&lt;br /&gt;
#[https://github.com/expertiza/expertiza/pull/2087/ Pull request to Expertiza repo]&lt;br /&gt;
#[https://github.com/vinay-deshmukh/expertiza/projects/1 GitHub Fork: Project board]&lt;br /&gt;
#[https://github.com/vinay-deshmukh/expertiza/issues Issues made while development]&lt;br /&gt;
#[https://github.com/vinay-deshmukh/expertiza/pulls  Pull requests made to the fork to document work]&lt;br /&gt;
#[https://github.com/vinay-deshmukh/expertiza/pulls?q=is%3Apr+is%3Aclosed Closed Pull Requests on Fork]&lt;/div&gt;</summary>
		<author><name>Vdeshmu</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2021_-_E2140._Create_new_late_policy_successfully_and_fix_Bank_link&amp;diff=139893</id>
		<title>CSC/ECE 517 Fall 2021 - E2140. Create new late policy successfully and fix Bank link</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2021_-_E2140._Create_new_late_policy_successfully_and_fix_Bank_link&amp;diff=139893"/>
		<updated>2021-10-21T14:31:11Z</updated>

		<summary type="html">&lt;p&gt;Vdeshmu: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
==E2140. Create new late policy successfully and fix &amp;quot;Back&amp;quot; link==&lt;br /&gt;
&lt;br /&gt;
This page provides a description of the Expertiza based OSS project, E1240.&lt;br /&gt;
&lt;br /&gt;
===About Expertiza===&lt;br /&gt;
&lt;br /&gt;
[http://expertiza.ncsu.edu/ Expertiza] is an open source project based on [http://rubyonrails.org/ Ruby on Rails] framework. Expertiza allows the instructor to create new assignments and customize new or existing assignments. It also allows the instructor to create a list of topics the students can sign up for. Students can form teams in Expertiza to work on various projects and assignments. Students can also peer review other students' submissions. Expertiza supports submission across various document types, including the URLs and wiki pages.&lt;br /&gt;
&lt;br /&gt;
===Problem Statement===&lt;br /&gt;
Create new late policy successfull and fix &amp;quot;Back&amp;quot; link.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Fixes performed==&lt;br /&gt;
&lt;br /&gt;
* Fix back link on &amp;quot;New late policy&amp;quot; page.&lt;br /&gt;
* Fix incorrect flash message on the screen when new late policy is created&lt;br /&gt;
* Add controller unit tests for create and edit actions for late_policies_controller&lt;br /&gt;
* Add functional test for late policy creation&lt;br /&gt;
* Add functional test for back button on new late policy page&lt;br /&gt;
* Improve flow of late_policies_controller#edit action for better tests&lt;br /&gt;
* Fix late_policies_controller#edit action when it displayed two contradictory flashes&lt;br /&gt;
* TODO: SQL stack trace shows up when long string is entered in policy name&lt;br /&gt;
* View was checked after a controller test to ensure that the correct message is shown to the user.&lt;br /&gt;
* Database was checked after controller test to verify whether correct changes happened or didn't.&lt;br /&gt;
* model was also checked to ensure the database is in a correct state&lt;br /&gt;
&lt;br /&gt;
===About Late Policies Controller===&lt;br /&gt;
&lt;br /&gt;
This controller can be accessed by editing an assignment, going on &amp;quot;Due Dates&amp;quot; page and  clicking on &amp;quot;New late policy&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
== Files modified in current project ==&lt;br /&gt;
&lt;br /&gt;
1. app/controllers/late_policies_controller.rb &amp;lt;br/&amp;gt;&lt;br /&gt;
2. app/views/late_policies/new.html.erb &amp;lt;br/&amp;gt;&lt;br /&gt;
3. spec/factories/factories.rb&amp;lt;br/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Files added for tests==&lt;br /&gt;
&lt;br /&gt;
1. spec/controllers/late_policies_controller_spec.rb &amp;lt;br/&amp;gt;&lt;br /&gt;
2. spec/features/late_policy_creation_spec.rb &amp;lt;br/&amp;gt;&lt;br /&gt;
3. spec/features/late_policy_back_button_spec.rb &amp;lt;br/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Files modified for tests==&lt;br /&gt;
&lt;br /&gt;
1. spec/factories/factories.rb&amp;lt;br /&amp;gt;&lt;br /&gt;
2. app/controllers/late_policies_controller.rb&lt;br /&gt;
&lt;br /&gt;
===Current Implementation===&lt;br /&gt;
&lt;br /&gt;
* There were no tests present in beta branch, so tests for the CRUD operations were added.&lt;br /&gt;
* Edit action for late_policies_controller is complex to reason about, with booleans deciding whether there are errors.&lt;br /&gt;
* Back button does not lead to the assignment from which the new late policy page was created.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=====Drawbacks and Solutions=====&lt;br /&gt;
* '''Problem 1''': Back button was taking user to index of late_policies, and not assignment due dates page&lt;br /&gt;
::The back button was performing it's default action of going back to index page of late_policies, but it needs to send user to the assginment page.&lt;br /&gt;
&lt;br /&gt;
Before: &amp;lt;br /&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;%= link_to 'Back', :action =&amp;gt; 'index' %&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
After: &amp;lt;br /&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;%= link_to 'Back', edit_assignment_path(session[:edit_assignment]) %&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
* '''Solution''': The link_to function is called with the link to the assignment which was last edited, so it will go to assginment page.&lt;br /&gt;
&lt;br /&gt;
* Use edit_assignment_path(session[:edit_assignment]) to go back to the previous page&lt;br /&gt;
&lt;br /&gt;
* '''Problem 2''': Creating new policy with blank fields does not give a proper error&lt;br /&gt;
::The existing code just shows a blank error, without specifying what has gone wrong. Hence, user will not know what is wrong when they created a new policy.&lt;br /&gt;
&lt;br /&gt;
* '''Solution''':  The existing error handling code was changed to show the ActiveRecord::Invalid errors to user. And in case, a different exception occurs, a &amp;quot;Something went wrong&amp;quot; message is shown, as this exception shouldn't be visible to users.&lt;br /&gt;
        &lt;br /&gt;
Before:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
      rescue StandardError&lt;br /&gt;
        flash[:error] = &amp;quot;The following error occurred while saving the penalty policy: &amp;quot;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
After:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
      rescue ActiveRecord::RecordInvalid =&amp;gt; exception&lt;br /&gt;
        flash[:error] = exception.record.errors.full_messages.join(&amp;quot;&amp;lt;br /&amp;gt;&amp;quot;).html_safe&lt;br /&gt;
        redirect_to action: 'new'&lt;br /&gt;
      rescue StandardError =&amp;gt; exception&lt;br /&gt;
        # In case it's some error, this error should not be shown to users&lt;br /&gt;
        flash[:error] = &amp;quot;Something went wrong&amp;quot;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* '''Problem 3''':  Update `update` method of late_policies_controller &lt;br /&gt;
:: Existing update method was too convoluted to read and due to it's convolution, it was showing wrong errors on screen.&lt;br /&gt;
* '''Solution''': &lt;br /&gt;
The control flow of the `update` method was improved to use early exits when errors occur, instead of using booleans to manage execution.&lt;br /&gt;
&lt;br /&gt;
===Code improvements===&lt;br /&gt;
late_policies_controller#update&lt;br /&gt;
Before&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    @penalty_policy = LatePolicy.find(params[:id])&lt;br /&gt;
    flash[:error] = &amp;quot;The maximum penalty cannot be less than penalty per unit.&amp;quot; if invalid_penalty_per_unit&lt;br /&gt;
    same_policy_name = false&lt;br /&gt;
    # if name has changed then only check for this&lt;br /&gt;
    if same_policy_name == LatePolicy.check_policy_with_same_name(params[:late_policy][:policy_name], instructor_id)&lt;br /&gt;
      flash[:error] = &amp;quot;The policy could not be updated because a policy with the same name already exists.&amp;quot;&lt;br /&gt;
    if !same_policy_name &amp;amp;&amp;amp; !invalid_penalty_per_unit&lt;br /&gt;
      begin&lt;br /&gt;
        @penalty_policy.update_attributes(late_policy_params)&lt;br /&gt;
        @penalty_policy.save!&lt;br /&gt;
        LatePolicy.update_calculated_penalty_objects(@penalty_policy)&lt;br /&gt;
        flash[:notice] = &amp;quot;The late policy was successfully updated.&amp;quot;&lt;br /&gt;
        redirect_to action: 'index'&lt;br /&gt;
      rescue StandardError&lt;br /&gt;
        flash[:error] = &amp;quot;The following error occurred while updating the penalty policy: &amp;quot;&lt;br /&gt;
        redirect_to action: 'edit', id: params[:id]&lt;br /&gt;
      end&lt;br /&gt;
    elsif invalid_penalty_per_unit&lt;br /&gt;
      flash[:error] = &amp;quot;Cannot edit the policy. The maximum penalty cannot be less than penalty per unit.&amp;quot;&lt;br /&gt;
      redirect_to action: 'edit', id: params[:id]&lt;br /&gt;
    elsif same_policy_name&lt;br /&gt;
      flash[:error] = &amp;quot;Cannot edit the policy. A policy with the same name &amp;quot; + params[:late_policy][:policy_name] + &amp;quot; already exists.&amp;quot;&lt;br /&gt;
      redirect_to action: 'edit', id: params[:id]&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
After:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    invalid_penalty_per_unit = params[:late_policy][:max_penalty].to_i &amp;lt; params[:late_policy][:penalty_per_unit].to_i&lt;br /&gt;
    # If penalty per unit is invalid, exit early&lt;br /&gt;
    if invalid_penalty_per_unit&lt;br /&gt;
      flash[:error] = &amp;quot;Cannot edit the policy. The maximum penalty cannot be less than penalty per unit.&amp;quot;&lt;br /&gt;
      redirect_to action: 'edit', id: params[:id] and return&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    # Only do DB search if we pass the invalid penalty check&lt;br /&gt;
    @penalty_policy = LatePolicy.find(params[:id])&lt;br /&gt;
    # if name has changed, then only check for this&lt;br /&gt;
    if params[:late_policy][:policy_name] != @penalty_policy.policy_name&lt;br /&gt;
      if LatePolicy.check_policy_with_same_name(params[:late_policy][:policy_name], instructor_id)&lt;br /&gt;
        flash[:error] = &amp;quot;Cannot edit the policy. A policy with the same name &amp;quot; + params[:late_policy][:policy_name] + &amp;quot; already exists.&amp;quot;&lt;br /&gt;
        redirect_to action: 'edit', id: params[:id] and return&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    begin&lt;br /&gt;
      @penalty_policy.update_attributes(late_policy_params)&lt;br /&gt;
      @penalty_policy.save!&lt;br /&gt;
      LatePolicy.update_calculated_penalty_objects(@penalty_policy)&lt;br /&gt;
      flash[:notice] = &amp;quot;The late policy was successfully updated.&amp;quot;&lt;br /&gt;
      redirect_to action: 'index' and return&lt;br /&gt;
    rescue StandardError&lt;br /&gt;
      flash[:error] = &amp;quot;The following error occurred while updating the penalty policy: &amp;quot;&lt;br /&gt;
      redirect_to action: 'edit', id: params[:id] and return&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===Automated Testing using RSPEC===&lt;br /&gt;
The current version of expertiza did not have any test for LatePoliciesController, and for back button.&lt;br /&gt;
Using the test driven development(TDD) approach, we have added an exhaustive set of RSPEC tests for LatePoliciesController, to test creation and expected failure to create scenarios.&lt;br /&gt;
We have also added tests for back button on new late policy page.&lt;br /&gt;
Similarly, we have added feature tests for late policy creation.&lt;br /&gt;
&lt;br /&gt;
Late policy creation tests with Capybara&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
$ rspec ./spec/features/late_policy_creation_spec.rb &lt;br /&gt;
Randomized with seed 65056&lt;br /&gt;
.....&lt;br /&gt;
&lt;br /&gt;
Finished in 22.28 seconds (files took 9.71 seconds to load)&lt;br /&gt;
5 examples, 0 failures&lt;br /&gt;
&lt;br /&gt;
Randomized with seed 65056&lt;br /&gt;
&lt;br /&gt;
Coverage report generated for RSpec to /.../expertiza/coverage. 2074 / 15378 LOC (13.49%) covered.&lt;br /&gt;
[Coveralls] Outside the Travis environment, not sending data.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
REST API tests for LatePoliciesController:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
$ rspec ./spec/controllers/late_policies_controller_spec.rb &lt;br /&gt;
&lt;br /&gt;
Randomized with seed 29277&lt;br /&gt;
........&lt;br /&gt;
&lt;br /&gt;
Finished in 17.56 seconds (files took 8.64 seconds to load)&lt;br /&gt;
8 examples, 0 failures&lt;br /&gt;
&lt;br /&gt;
Randomized with seed 29277&lt;br /&gt;
&lt;br /&gt;
Coverage report generated for RSpec to /.../expertiza/coverage. 1587 / 15800 LOC (10.04%) covered.&lt;br /&gt;
[Coveralls] Outside the Travis environment, not sending data.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Back button tests&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
$ rspec ./spec/features/late_policy_back_button_spec.rb &lt;br /&gt;
Randomized with seed 15242&lt;br /&gt;
.&lt;br /&gt;
&lt;br /&gt;
Finished in 9.74 seconds (files took 8.95 seconds to load)&lt;br /&gt;
1 example, 0 failures&lt;br /&gt;
&lt;br /&gt;
Randomized with seed 15242&lt;br /&gt;
&lt;br /&gt;
Coverage report generated for RSpec to /.../expertiza/coverage. 2041 / 15378 LOC (13.27%) covered.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===References===&lt;br /&gt;
&lt;br /&gt;
#[https://github.com/expertiza/expertiza Expertiza on GitHub]&lt;br /&gt;
#[https://github.com/vinay-deshmukh/expertiza GitHub Project Repository Fork]&lt;br /&gt;
#[https://github.com/expertiza/expertiza/pull/2087/ Pull request to Expertiza repo]&lt;br /&gt;
#[https://github.com/vinay-deshmukh/expertiza/projects/1 GitHub Fork: Project board]&lt;br /&gt;
#[https://github.com/vinay-deshmukh/expertiza/issues Issues made while development]&lt;br /&gt;
#[https://github.com/vinay-deshmukh/expertiza/pulls  Pull requests made to the fork to document work]&lt;br /&gt;
#[https://github.com/vinay-deshmukh/expertiza/pulls?q=is%3Apr+is%3Aclosed Closed Pull Requests on Fork]&lt;/div&gt;</summary>
		<author><name>Vdeshmu</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2021_-_E2140._Create_new_late_policy_successfully_and_fix_Bank_link&amp;diff=139892</id>
		<title>CSC/ECE 517 Fall 2021 - E2140. Create new late policy successfully and fix Bank link</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2021_-_E2140._Create_new_late_policy_successfully_and_fix_Bank_link&amp;diff=139892"/>
		<updated>2021-10-21T14:30:14Z</updated>

		<summary type="html">&lt;p&gt;Vdeshmu: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
==E2140. Create new late policy successfully and fix &amp;quot;Back&amp;quot; link==&lt;br /&gt;
&lt;br /&gt;
This page provides a description of the Expertiza based OSS project, E1240.&lt;br /&gt;
&lt;br /&gt;
===About Expertiza===&lt;br /&gt;
&lt;br /&gt;
[http://expertiza.ncsu.edu/ Expertiza] is an open source project based on [http://rubyonrails.org/ Ruby on Rails] framework. Expertiza allows the instructor to create new assignments and customize new or existing assignments. It also allows the instructor to create a list of topics the students can sign up for. Students can form teams in Expertiza to work on various projects and assignments. Students can also peer review other students' submissions. Expertiza supports submission across various document types, including the URLs and wiki pages.&lt;br /&gt;
&lt;br /&gt;
===Problem Statement===&lt;br /&gt;
Create new late policy successfull and fix &amp;quot;Back&amp;quot; link.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Fixes performed==&lt;br /&gt;
&lt;br /&gt;
* Fix back link on &amp;quot;New late policy&amp;quot; page.&lt;br /&gt;
* Fix incorrect flash message on the screen when new late policy is created&lt;br /&gt;
* Add controller unit tests for create and edit actions for late_policies_controller&lt;br /&gt;
* Add functional test for late policy creation&lt;br /&gt;
* Add functional test for back button on new late policy page&lt;br /&gt;
* Improve flow of late_policies_controller#edit action for better tests&lt;br /&gt;
* Fix late_policies_controller#edit action when it displayed two contradictory flashes&lt;br /&gt;
* TODO: SQL stack trace shows up when long string is entered in policy name&lt;br /&gt;
* View was checked after a controller test to ensure that the correct message is shown to the user.&lt;br /&gt;
* Database was checked after controller test to verify whether correct changes happened or didn't.&lt;br /&gt;
* model was also checked to ensure the database is in a correct state&lt;br /&gt;
&lt;br /&gt;
===About Late Policies Controller===&lt;br /&gt;
&lt;br /&gt;
This controller can be accessed by editing an assignment, going on &amp;quot;Due Dates&amp;quot; page and  clicking on &amp;quot;New late policy&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
== Files modified in current project ==&lt;br /&gt;
&lt;br /&gt;
1. app/controllers/late_policies_controller.rb &amp;lt;br/&amp;gt;&lt;br /&gt;
2. app/views/late_policies/new.html.erb &amp;lt;br/&amp;gt;&lt;br /&gt;
3. spec/factories/factories.rb&amp;lt;br/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Files added for tests==&lt;br /&gt;
&lt;br /&gt;
1. spec/controllers/late_policies_controller_spec.rb &amp;lt;br/&amp;gt;&lt;br /&gt;
2. spec/features/late_policy_creation_spec.rb &amp;lt;br/&amp;gt;&lt;br /&gt;
3. spec/features/late_policy_back_button_spec.rb &amp;lt;br/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Files modified for tests==&lt;br /&gt;
&lt;br /&gt;
1. spec/factories/factories.rb&amp;lt;br /&amp;gt;&lt;br /&gt;
2. app/controllers/late_policies_controller.rb&lt;br /&gt;
&lt;br /&gt;
===Current Implementation===&lt;br /&gt;
&lt;br /&gt;
* There were no tests present in beta branch, so tests for the CRUD operations were added.&lt;br /&gt;
* Edit action for late_policies_controller is complex to reason about, with booleans deciding whether there are errors.&lt;br /&gt;
* Back button does not lead to the assignment from which the new late policy page was created.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=====Drawbacks and Solutions=====&lt;br /&gt;
* '''Problem 1''': Back button was taking user to index of late_policies, and not assignment due dates page&lt;br /&gt;
::The back button was performing it's default action of going back to index page of late_policies, but it needs to send user to the assginment page.&lt;br /&gt;
&lt;br /&gt;
Before: &amp;lt;br /&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;%= link_to 'Back', :action =&amp;gt; 'index' %&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
After: &amp;lt;br /&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;%= link_to 'Back', edit_assignment_path(session[:edit_assignment]) %&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
* '''Solution''': The link_to function is called with the link to the assignment which was last edited, so it will go to assginment page.&lt;br /&gt;
&lt;br /&gt;
* Use edit_assignment_path(session[:edit_assignment]) to go back to the previous page&lt;br /&gt;
&lt;br /&gt;
* '''Problem 2''': Creating new policy with blank fields does not give a proper error&lt;br /&gt;
::The existing code just shows a blank error, without specifying what has gone wrong. Hence, user will not know what is wrong when they created a new policy.&lt;br /&gt;
&lt;br /&gt;
* '''Solution''':  The existing error handling code was changed to show the ActiveRecord::Invalid errors to user. And in case, a different exception occurs, a &amp;quot;Something went wrong&amp;quot; message is shown, as this exception shouldn't be visible to users.&lt;br /&gt;
        &lt;br /&gt;
Before:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
      rescue StandardError&lt;br /&gt;
        flash[:error] = &amp;quot;The following error occurred while saving the penalty policy: &amp;quot;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
After:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
      rescue ActiveRecord::RecordInvalid =&amp;gt; exception&lt;br /&gt;
        flash[:error] = exception.record.errors.full_messages.join(&amp;quot;&amp;lt;br /&amp;gt;&amp;quot;).html_safe&lt;br /&gt;
        redirect_to action: 'new'&lt;br /&gt;
      rescue StandardError =&amp;gt; exception&lt;br /&gt;
        # In case it's some error, this error should not be shown to users&lt;br /&gt;
        flash[:error] = &amp;quot;Something went wrong&amp;quot;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* '''Problem 3''':  Update `update` method of late_policies_controller &lt;br /&gt;
:: Existing update method was too convoluted to read and due to it's convolution, it was showing wrong errors on screen.&lt;br /&gt;
* '''Solution''': &lt;br /&gt;
The control flow of the `update` method was improved to use early exits when errors occur, instead of using booleans to manage execution.&lt;br /&gt;
&lt;br /&gt;
===Code improvements===&lt;br /&gt;
late_policies_controller#update&lt;br /&gt;
Before&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    @penalty_policy = LatePolicy.find(params[:id])&lt;br /&gt;
    flash[:error] = &amp;quot;The maximum penalty cannot be less than penalty per unit.&amp;quot; if invalid_penalty_per_unit&lt;br /&gt;
    same_policy_name = false&lt;br /&gt;
    # if name has changed then only check for this&lt;br /&gt;
    if same_policy_name == LatePolicy.check_policy_with_same_name(params[:late_policy][:policy_name], instructor_id)&lt;br /&gt;
      flash[:error] = &amp;quot;The policy could not be updated because a policy with the same name already exists.&amp;quot;&lt;br /&gt;
    if !same_policy_name &amp;amp;&amp;amp; !invalid_penalty_per_unit&lt;br /&gt;
      begin&lt;br /&gt;
        @penalty_policy.update_attributes(late_policy_params)&lt;br /&gt;
        @penalty_policy.save!&lt;br /&gt;
        LatePolicy.update_calculated_penalty_objects(@penalty_policy)&lt;br /&gt;
        flash[:notice] = &amp;quot;The late policy was successfully updated.&amp;quot;&lt;br /&gt;
        redirect_to action: 'index'&lt;br /&gt;
      rescue StandardError&lt;br /&gt;
        flash[:error] = &amp;quot;The following error occurred while updating the penalty policy: &amp;quot;&lt;br /&gt;
        redirect_to action: 'edit', id: params[:id]&lt;br /&gt;
      end&lt;br /&gt;
    elsif invalid_penalty_per_unit&lt;br /&gt;
      flash[:error] = &amp;quot;Cannot edit the policy. The maximum penalty cannot be less than penalty per unit.&amp;quot;&lt;br /&gt;
      redirect_to action: 'edit', id: params[:id]&lt;br /&gt;
    elsif same_policy_name&lt;br /&gt;
      flash[:error] = &amp;quot;Cannot edit the policy. A policy with the same name &amp;quot; + params[:late_policy][:policy_name] + &amp;quot; already exists.&amp;quot;&lt;br /&gt;
      redirect_to action: 'edit', id: params[:id]&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
After:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    invalid_penalty_per_unit = params[:late_policy][:max_penalty].to_i &amp;lt; params[:late_policy][:penalty_per_unit].to_i&lt;br /&gt;
    # If penalty per unit is invalid, exit early&lt;br /&gt;
    if invalid_penalty_per_unit&lt;br /&gt;
      flash[:error] = &amp;quot;Cannot edit the policy. The maximum penalty cannot be less than penalty per unit.&amp;quot;&lt;br /&gt;
      redirect_to action: 'edit', id: params[:id] and return&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    # Only do DB search if we pass the invalid penalty check&lt;br /&gt;
    @penalty_policy = LatePolicy.find(params[:id])&lt;br /&gt;
    # if name has changed, then only check for this&lt;br /&gt;
    if params[:late_policy][:policy_name] != @penalty_policy.policy_name&lt;br /&gt;
      if LatePolicy.check_policy_with_same_name(params[:late_policy][:policy_name], instructor_id)&lt;br /&gt;
        flash[:error] = &amp;quot;Cannot edit the policy. A policy with the same name &amp;quot; + params[:late_policy][:policy_name] + &amp;quot; already exists.&amp;quot;&lt;br /&gt;
        redirect_to action: 'edit', id: params[:id] and return&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    begin&lt;br /&gt;
      @penalty_policy.update_attributes(late_policy_params)&lt;br /&gt;
      @penalty_policy.save!&lt;br /&gt;
      LatePolicy.update_calculated_penalty_objects(@penalty_policy)&lt;br /&gt;
      flash[:notice] = &amp;quot;The late policy was successfully updated.&amp;quot;&lt;br /&gt;
      redirect_to action: 'index' and return&lt;br /&gt;
    rescue StandardError&lt;br /&gt;
      flash[:error] = &amp;quot;The following error occurred while updating the penalty policy: &amp;quot;&lt;br /&gt;
      redirect_to action: 'edit', id: params[:id] and return&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===Automated Testing using RSPEC===&lt;br /&gt;
The current version of expertiza did not have any test for LatePoliciesController, and for back button.&lt;br /&gt;
Using the test driven development(TDD) approach, we have added an exhaustive set of RSPEC tests for LatePoliciesController, to test creation and expected failure to create scenarios.&lt;br /&gt;
We have also added tests for back button on new late policy page.&lt;br /&gt;
Similarly, we have added feature tests for late policy creation.&lt;br /&gt;
&lt;br /&gt;
Late policy creation tests&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
$ rspec ./spec/features/late_policy_creation_spec.rb &lt;br /&gt;
Randomized with seed 65056&lt;br /&gt;
.....&lt;br /&gt;
&lt;br /&gt;
Finished in 22.28 seconds (files took 9.71 seconds to load)&lt;br /&gt;
5 examples, 0 failures&lt;br /&gt;
&lt;br /&gt;
Randomized with seed 65056&lt;br /&gt;
&lt;br /&gt;
Coverage report generated for RSpec to /.../expertiza/coverage. 2074 / 15378 LOC (13.49%) covered.&lt;br /&gt;
[Coveralls] Outside the Travis environment, not sending data.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Back button tests&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
$ rspec ./spec/features/late_policy_back_button_spec.rb &lt;br /&gt;
Randomized with seed 15242&lt;br /&gt;
.&lt;br /&gt;
&lt;br /&gt;
Finished in 9.74 seconds (files took 8.95 seconds to load)&lt;br /&gt;
1 example, 0 failures&lt;br /&gt;
&lt;br /&gt;
Randomized with seed 15242&lt;br /&gt;
&lt;br /&gt;
Coverage report generated for RSpec to /.../expertiza/coverage. 2041 / 15378 LOC (13.27%) covered.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
$ rspec ./spec/controllers/late_policies_controller_spec.rb &lt;br /&gt;
&lt;br /&gt;
Randomized with seed 29277&lt;br /&gt;
........&lt;br /&gt;
&lt;br /&gt;
Finished in 17.56 seconds (files took 8.64 seconds to load)&lt;br /&gt;
8 examples, 0 failures&lt;br /&gt;
&lt;br /&gt;
Randomized with seed 29277&lt;br /&gt;
&lt;br /&gt;
Coverage report generated for RSpec to /.../expertiza/coverage. 1587 / 15800 LOC (10.04%) covered.&lt;br /&gt;
[Coveralls] Outside the Travis environment, not sending data.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===References===&lt;br /&gt;
&lt;br /&gt;
#[https://github.com/expertiza/expertiza Expertiza on GitHub]&lt;br /&gt;
#[https://github.com/vinay-deshmukh/expertiza GitHub Project Repository Fork]&lt;br /&gt;
#[https://github.com/expertiza/expertiza/pull/2087/ Pull request to Expertiza repo]&lt;br /&gt;
#[https://github.com/vinay-deshmukh/expertiza/projects/1 GitHub Fork: Project board]&lt;br /&gt;
#[https://github.com/vinay-deshmukh/expertiza/issues Issues made while development]&lt;br /&gt;
#[https://github.com/vinay-deshmukh/expertiza/pulls  Pull requests made to the fork to document work]&lt;br /&gt;
#[https://github.com/vinay-deshmukh/expertiza/pulls?q=is%3Apr+is%3Aclosed Closed Pull Requests on Fork]&lt;/div&gt;</summary>
		<author><name>Vdeshmu</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2021_-_E2140._Create_new_late_policy_successfully_and_fix_Bank_link&amp;diff=139891</id>
		<title>CSC/ECE 517 Fall 2021 - E2140. Create new late policy successfully and fix Bank link</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2021_-_E2140._Create_new_late_policy_successfully_and_fix_Bank_link&amp;diff=139891"/>
		<updated>2021-10-21T14:29:18Z</updated>

		<summary type="html">&lt;p&gt;Vdeshmu: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
==E2140. Create new late policy successfully and fix &amp;quot;Back&amp;quot; link==&lt;br /&gt;
&lt;br /&gt;
This page provides a description of the Expertiza based OSS project, E1240.&lt;br /&gt;
&lt;br /&gt;
===About Expertiza===&lt;br /&gt;
&lt;br /&gt;
[http://expertiza.ncsu.edu/ Expertiza] is an open source project based on [http://rubyonrails.org/ Ruby on Rails] framework. Expertiza allows the instructor to create new assignments and customize new or existing assignments. It also allows the instructor to create a list of topics the students can sign up for. Students can form teams in Expertiza to work on various projects and assignments. Students can also peer review other students' submissions. Expertiza supports submission across various document types, including the URLs and wiki pages.&lt;br /&gt;
&lt;br /&gt;
===Problem Statement===&lt;br /&gt;
Create new late policy successfull and fix &amp;quot;Back&amp;quot; link.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Fixes performed==&lt;br /&gt;
&lt;br /&gt;
* Fix back link on &amp;quot;New late policy&amp;quot; page.&lt;br /&gt;
* Fix incorrect flash message on the screen when new late policy is created&lt;br /&gt;
* Add controller unit tests for create and edit actions for late_policies_controller&lt;br /&gt;
* Add functional test for late policy creation&lt;br /&gt;
* Add functional test for back button on new late policy page&lt;br /&gt;
* Improve flow of late_policies_controller#edit action for better tests&lt;br /&gt;
* Fix late_policies_controller#edit action when it displayed two contradictory flashes&lt;br /&gt;
* TODO: SQL stack trace shows up when long string is entered in policy name&lt;br /&gt;
* View was checked after a controller test to ensure that the correct message is shown to the user.&lt;br /&gt;
* Database was checked after controller test to verify whether correct changes happened or didn't.&lt;br /&gt;
* model was also checked to ensure the database is in a correct state&lt;br /&gt;
&lt;br /&gt;
===About Late Policies Controller===&lt;br /&gt;
&lt;br /&gt;
This controller can be accessed by editing an assignment, going on &amp;quot;Due Dates&amp;quot; page and  clicking on &amp;quot;New late policy&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
== Files modified in current project ==&lt;br /&gt;
&lt;br /&gt;
1. app/controllers/late_policies_controller.rb &amp;lt;br/&amp;gt;&lt;br /&gt;
2. app/views/late_policies/new.html.erb &amp;lt;br/&amp;gt;&lt;br /&gt;
3. spec/factories/factories.rb&amp;lt;br/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Files added for tests==&lt;br /&gt;
&lt;br /&gt;
1. spec/controllers/late_policies_controller_spec.rb &amp;lt;br/&amp;gt;&lt;br /&gt;
2. spec/features/late_policy_creation_spec.rb &amp;lt;br/&amp;gt;&lt;br /&gt;
3. spec/features/late_policy_back_button_spec.rb &amp;lt;br/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Files modified for tests==&lt;br /&gt;
&lt;br /&gt;
1. spec/factories/factories.rb&amp;lt;br /&amp;gt;&lt;br /&gt;
2. app/controllers/late_policies_controller.rb&lt;br /&gt;
&lt;br /&gt;
===Current Implementation===&lt;br /&gt;
&lt;br /&gt;
* There were no tests present in beta branch, so tests for the CRUD operations were added.&lt;br /&gt;
* Edit action for late_policies_controller is complex to reason about, with booleans deciding whether there are errors.&lt;br /&gt;
* Back button does not lead to the assignment from which the new late policy page was created.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=====Drawbacks and Solutions=====&lt;br /&gt;
* '''Problem 1''': Back button was taking user to index of late_policies, and not assignment due dates page&lt;br /&gt;
::The back button was performing it's default action of going back to index page of late_policies, but it needs to send user to the assginment page.&lt;br /&gt;
&lt;br /&gt;
Before: &amp;lt;br /&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;%= link_to 'Back', :action =&amp;gt; 'index' %&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
After: &amp;lt;br /&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;%= link_to 'Back', edit_assignment_path(session[:edit_assignment]) %&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
* '''Solution''': The link_to function is called with the link to the assignment which was last edited, so it will go to assginment page.&lt;br /&gt;
&lt;br /&gt;
* Use edit_assignment_path(session[:edit_assignment]) to go back to the previous page&lt;br /&gt;
&lt;br /&gt;
* '''Problem 2''': Creating new policy with blank fields does not give a proper error&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
::The existing code just shows a blank error, without specifying what has gone wrong. Hence, user will not know what is wrong when they created a new policy.&lt;br /&gt;
&lt;br /&gt;
* '''Solution''':  The existing error handling code was changed to show the ActiveRecord::Invalid errors to user. And in case, a different exception occurs, a &amp;quot;Something went wrong&amp;quot; message is shown, as this exception shouldn't be visible to users.&lt;br /&gt;
        &lt;br /&gt;
Before:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
      rescue StandardError&lt;br /&gt;
        flash[:error] = &amp;quot;The following error occurred while saving the penalty policy: &amp;quot;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
After:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
      rescue ActiveRecord::RecordInvalid =&amp;gt; exception&lt;br /&gt;
        flash[:error] = exception.record.errors.full_messages.join(&amp;quot;&amp;lt;br /&amp;gt;&amp;quot;).html_safe&lt;br /&gt;
        redirect_to action: 'new'&lt;br /&gt;
      rescue StandardError =&amp;gt; exception&lt;br /&gt;
        # In case it's some error, this error should not be shown to users&lt;br /&gt;
        flash[:error] = &amp;quot;Something went wrong&amp;quot;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* '''Problem 3''':  Update `update` method of late_policies_controller &lt;br /&gt;
:: Existing update method was too convoluted to read and due to it's convolution, it was showing wrong errors on screen.&lt;br /&gt;
* '''Solution''': &lt;br /&gt;
The control flow of the `update` method was improved to use early exits when errors occur, instead of using booleans to manage execution.&lt;br /&gt;
&lt;br /&gt;
===Code improvements===&lt;br /&gt;
late_policies_controller#update&lt;br /&gt;
Before&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    @penalty_policy = LatePolicy.find(params[:id])&lt;br /&gt;
    flash[:error] = &amp;quot;The maximum penalty cannot be less than penalty per unit.&amp;quot; if invalid_penalty_per_unit&lt;br /&gt;
    same_policy_name = false&lt;br /&gt;
    # if name has changed then only check for this&lt;br /&gt;
    if same_policy_name == LatePolicy.check_policy_with_same_name(params[:late_policy][:policy_name], instructor_id)&lt;br /&gt;
      flash[:error] = &amp;quot;The policy could not be updated because a policy with the same name already exists.&amp;quot;&lt;br /&gt;
    if !same_policy_name &amp;amp;&amp;amp; !invalid_penalty_per_unit&lt;br /&gt;
      begin&lt;br /&gt;
        @penalty_policy.update_attributes(late_policy_params)&lt;br /&gt;
        @penalty_policy.save!&lt;br /&gt;
        LatePolicy.update_calculated_penalty_objects(@penalty_policy)&lt;br /&gt;
        flash[:notice] = &amp;quot;The late policy was successfully updated.&amp;quot;&lt;br /&gt;
        redirect_to action: 'index'&lt;br /&gt;
      rescue StandardError&lt;br /&gt;
        flash[:error] = &amp;quot;The following error occurred while updating the penalty policy: &amp;quot;&lt;br /&gt;
        redirect_to action: 'edit', id: params[:id]&lt;br /&gt;
      end&lt;br /&gt;
    elsif invalid_penalty_per_unit&lt;br /&gt;
      flash[:error] = &amp;quot;Cannot edit the policy. The maximum penalty cannot be less than penalty per unit.&amp;quot;&lt;br /&gt;
      redirect_to action: 'edit', id: params[:id]&lt;br /&gt;
    elsif same_policy_name&lt;br /&gt;
      flash[:error] = &amp;quot;Cannot edit the policy. A policy with the same name &amp;quot; + params[:late_policy][:policy_name] + &amp;quot; already exists.&amp;quot;&lt;br /&gt;
      redirect_to action: 'edit', id: params[:id]&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
After:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    invalid_penalty_per_unit = params[:late_policy][:max_penalty].to_i &amp;lt; params[:late_policy][:penalty_per_unit].to_i&lt;br /&gt;
    # If penalty per unit is invalid, exit early&lt;br /&gt;
    if invalid_penalty_per_unit&lt;br /&gt;
      flash[:error] = &amp;quot;Cannot edit the policy. The maximum penalty cannot be less than penalty per unit.&amp;quot;&lt;br /&gt;
      redirect_to action: 'edit', id: params[:id] and return&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    # Only do DB search if we pass the invalid penalty check&lt;br /&gt;
    @penalty_policy = LatePolicy.find(params[:id])&lt;br /&gt;
    # if name has changed, then only check for this&lt;br /&gt;
    if params[:late_policy][:policy_name] != @penalty_policy.policy_name&lt;br /&gt;
      if LatePolicy.check_policy_with_same_name(params[:late_policy][:policy_name], instructor_id)&lt;br /&gt;
        flash[:error] = &amp;quot;Cannot edit the policy. A policy with the same name &amp;quot; + params[:late_policy][:policy_name] + &amp;quot; already exists.&amp;quot;&lt;br /&gt;
        redirect_to action: 'edit', id: params[:id] and return&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    begin&lt;br /&gt;
      @penalty_policy.update_attributes(late_policy_params)&lt;br /&gt;
      @penalty_policy.save!&lt;br /&gt;
      LatePolicy.update_calculated_penalty_objects(@penalty_policy)&lt;br /&gt;
      flash[:notice] = &amp;quot;The late policy was successfully updated.&amp;quot;&lt;br /&gt;
      redirect_to action: 'index' and return&lt;br /&gt;
    rescue StandardError&lt;br /&gt;
      flash[:error] = &amp;quot;The following error occurred while updating the penalty policy: &amp;quot;&lt;br /&gt;
      redirect_to action: 'edit', id: params[:id] and return&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===Automated Testing using RSPEC===&lt;br /&gt;
The current version of expertiza did not have any test for LatePoliciesController, and for back button.&lt;br /&gt;
Using the test driven development(TDD) approach, we have added an exhaustive set of RSPEC tests for LatePoliciesController, to test creation and expected failure to create scenarios.&lt;br /&gt;
We have also added tests for back button on new late policy page.&lt;br /&gt;
Similarly, we have added feature tests for late policy creation.&lt;br /&gt;
&lt;br /&gt;
Late policy creation tests&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
$ rspec ./spec/features/late_policy_creation_spec.rb &lt;br /&gt;
Randomized with seed 65056&lt;br /&gt;
.....&lt;br /&gt;
&lt;br /&gt;
Finished in 22.28 seconds (files took 9.71 seconds to load)&lt;br /&gt;
5 examples, 0 failures&lt;br /&gt;
&lt;br /&gt;
Randomized with seed 65056&lt;br /&gt;
&lt;br /&gt;
Coverage report generated for RSpec to /.../expertiza/coverage. 2074 / 15378 LOC (13.49%) covered.&lt;br /&gt;
[Coveralls] Outside the Travis environment, not sending data.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Back button tests&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
$ rspec ./spec/features/late_policy_back_button_spec.rb &lt;br /&gt;
Randomized with seed 15242&lt;br /&gt;
.&lt;br /&gt;
&lt;br /&gt;
Finished in 9.74 seconds (files took 8.95 seconds to load)&lt;br /&gt;
1 example, 0 failures&lt;br /&gt;
&lt;br /&gt;
Randomized with seed 15242&lt;br /&gt;
&lt;br /&gt;
Coverage report generated for RSpec to /.../expertiza/coverage. 2041 / 15378 LOC (13.27%) covered.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
$ rspec ./spec/controllers/late_policies_controller_spec.rb &lt;br /&gt;
&lt;br /&gt;
Randomized with seed 29277&lt;br /&gt;
........&lt;br /&gt;
&lt;br /&gt;
Finished in 17.56 seconds (files took 8.64 seconds to load)&lt;br /&gt;
8 examples, 0 failures&lt;br /&gt;
&lt;br /&gt;
Randomized with seed 29277&lt;br /&gt;
&lt;br /&gt;
Coverage report generated for RSpec to /.../expertiza/coverage. 1587 / 15800 LOC (10.04%) covered.&lt;br /&gt;
[Coveralls] Outside the Travis environment, not sending data.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===References===&lt;br /&gt;
&lt;br /&gt;
#[https://github.com/expertiza/expertiza Expertiza on GitHub]&lt;br /&gt;
#[https://github.com/vinay-deshmukh/expertiza GitHub Project Repository Fork]&lt;br /&gt;
#[https://github.com/expertiza/expertiza/pull/2087/ Pull request to Expertiza repo]&lt;br /&gt;
#[https://github.com/vinay-deshmukh/expertiza/projects/1 GitHub Fork: Project board]&lt;br /&gt;
#[https://github.com/vinay-deshmukh/expertiza/issues Issues made while development]&lt;br /&gt;
#[https://github.com/vinay-deshmukh/expertiza/pulls  Pull requests made to the fork to document work]&lt;br /&gt;
#[https://github.com/vinay-deshmukh/expertiza/pulls?q=is%3Apr+is%3Aclosed Closed Pull Requests on Fork]&lt;/div&gt;</summary>
		<author><name>Vdeshmu</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2021_-_E2140._Create_new_late_policy_successfully_and_fix_Bank_link&amp;diff=139890</id>
		<title>CSC/ECE 517 Fall 2021 - E2140. Create new late policy successfully and fix Bank link</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2021_-_E2140._Create_new_late_policy_successfully_and_fix_Bank_link&amp;diff=139890"/>
		<updated>2021-10-21T14:29:02Z</updated>

		<summary type="html">&lt;p&gt;Vdeshmu: Fix typo&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
==E2140. Create new late policy successfully and fix &amp;quot;Back&amp;quot; link==&lt;br /&gt;
&lt;br /&gt;
This page provides a description of the Expertiza based OSS project, E1240.&lt;br /&gt;
&lt;br /&gt;
===About Expertiza===&lt;br /&gt;
&lt;br /&gt;
[http://expertiza.ncsu.edu/ Expertiza] is an open source project based on [http://rubyonrails.org/ Ruby on Rails] framework. Expertiza allows the instructor to create new assignments and customize new or existing assignments. It also allows the instructor to create a list of topics the students can sign up for. Students can form teams in Expertiza to work on various projects and assignments. Students can also peer review other students' submissions. Expertiza supports submission across various document types, including the URLs and wiki pages.&lt;br /&gt;
&lt;br /&gt;
===Problem Statement===&lt;br /&gt;
Create new late policy successfull and fix &amp;quot;Back&amp;quot; link.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Fixes performed==&lt;br /&gt;
&lt;br /&gt;
* Fix back link on &amp;quot;New late policy&amp;quot; page.&lt;br /&gt;
* Fix incorrect flash message on the screen when new late policy is created&lt;br /&gt;
* Add controller unit tests for create and edit actions for late_policies_controller&lt;br /&gt;
* Add functional test for late policy creation&lt;br /&gt;
* Add functional test for back button on new late policy page&lt;br /&gt;
* Improve flow of late_policies_controller#edit action for better tests&lt;br /&gt;
* Fix late_policies_controller#edit action when it displayed two contradictory flashes&lt;br /&gt;
* TODO: SQL stack trace shows up when long string is entered in policy name&lt;br /&gt;
* View was checked after a controller test to ensure that the correct message is shown to the user.&lt;br /&gt;
* Database was checked after controller test to verify whether correct changes happened or didn't.&lt;br /&gt;
* model was also checked to ensure the database is in a correct state&lt;br /&gt;
&lt;br /&gt;
===About Late Policies Controller===&lt;br /&gt;
&lt;br /&gt;
This controller can be accessed by editing an assignment, going on &amp;quot;Due Dates&amp;quot; page and  clicking on &amp;quot;New late policy&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
== Files modified in current project ==&lt;br /&gt;
&lt;br /&gt;
1. app/controllers/late_policies_controller.rb &amp;lt;br/&amp;gt;&lt;br /&gt;
2. app/views/late_policies/new.html.erb &amp;lt;br/&amp;gt;&lt;br /&gt;
3. spec/factories/factories.rb&amp;lt;br/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Files added for tests==&lt;br /&gt;
&lt;br /&gt;
1. spec/controllers/late_policies_controller_spec.rb &amp;lt;br/&amp;gt;&lt;br /&gt;
2. spec/features/late_policy_creation_spec.rb &amp;lt;br/&amp;gt;&lt;br /&gt;
3. spec/features/late_policy_back_button_spec.rb &amp;lt;br/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Files modified for tests==&lt;br /&gt;
&lt;br /&gt;
1. spec/factories/factories.rb&amp;lt;br /&amp;gt;&lt;br /&gt;
2. app/controllers/late_policies_controller.rb&lt;br /&gt;
&lt;br /&gt;
===Current Implementation===&lt;br /&gt;
&lt;br /&gt;
* There were no tests present in beta branch, so tests for the CRUD operations were added.&lt;br /&gt;
* Edit action for late_policies_controller is complex to reason about, with booleans deciding whether there are errors.&lt;br /&gt;
* Back button does not lead to the assignment from which the new late policy page was created.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=====Functionality=====&lt;br /&gt;
&lt;br /&gt;
1. &lt;br /&gt;
&lt;br /&gt;
=====Drawbacks and Solutions=====&lt;br /&gt;
* '''Problem 1''': Back button was taking user to index of late_policies, and not assignment due dates page&lt;br /&gt;
::The back button was performing it's default action of going back to index page of late_policies, but it needs to send user to the assginment page.&lt;br /&gt;
&lt;br /&gt;
Before: &amp;lt;br /&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;%= link_to 'Back', :action =&amp;gt; 'index' %&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
After: &amp;lt;br /&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;%= link_to 'Back', edit_assignment_path(session[:edit_assignment]) %&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
* '''Solution''': The link_to function is called with the link to the assignment which was last edited, so it will go to assginment page.&lt;br /&gt;
&lt;br /&gt;
* Use edit_assignment_path(session[:edit_assignment]) to go back to the previous page&lt;br /&gt;
&lt;br /&gt;
* '''Problem 2''': Creating new policy with blank fields does not give a proper error&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
::The existing code just shows a blank error, without specifying what has gone wrong. Hence, user will not know what is wrong when they created a new policy.&lt;br /&gt;
&lt;br /&gt;
* '''Solution''':  The existing error handling code was changed to show the ActiveRecord::Invalid errors to user. And in case, a different exception occurs, a &amp;quot;Something went wrong&amp;quot; message is shown, as this exception shouldn't be visible to users.&lt;br /&gt;
        &lt;br /&gt;
Before:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
      rescue StandardError&lt;br /&gt;
        flash[:error] = &amp;quot;The following error occurred while saving the penalty policy: &amp;quot;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
After:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
      rescue ActiveRecord::RecordInvalid =&amp;gt; exception&lt;br /&gt;
        flash[:error] = exception.record.errors.full_messages.join(&amp;quot;&amp;lt;br /&amp;gt;&amp;quot;).html_safe&lt;br /&gt;
        redirect_to action: 'new'&lt;br /&gt;
      rescue StandardError =&amp;gt; exception&lt;br /&gt;
        # In case it's some error, this error should not be shown to users&lt;br /&gt;
        flash[:error] = &amp;quot;Something went wrong&amp;quot;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* '''Problem 3''':  Update `update` method of late_policies_controller &lt;br /&gt;
:: Existing update method was too convoluted to read and due to it's convolution, it was showing wrong errors on screen.&lt;br /&gt;
* '''Solution''': &lt;br /&gt;
The control flow of the `update` method was improved to use early exits when errors occur, instead of using booleans to manage execution.&lt;br /&gt;
&lt;br /&gt;
===Code improvements===&lt;br /&gt;
late_policies_controller#update&lt;br /&gt;
Before&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    @penalty_policy = LatePolicy.find(params[:id])&lt;br /&gt;
    flash[:error] = &amp;quot;The maximum penalty cannot be less than penalty per unit.&amp;quot; if invalid_penalty_per_unit&lt;br /&gt;
    same_policy_name = false&lt;br /&gt;
    # if name has changed then only check for this&lt;br /&gt;
    if same_policy_name == LatePolicy.check_policy_with_same_name(params[:late_policy][:policy_name], instructor_id)&lt;br /&gt;
      flash[:error] = &amp;quot;The policy could not be updated because a policy with the same name already exists.&amp;quot;&lt;br /&gt;
    if !same_policy_name &amp;amp;&amp;amp; !invalid_penalty_per_unit&lt;br /&gt;
      begin&lt;br /&gt;
        @penalty_policy.update_attributes(late_policy_params)&lt;br /&gt;
        @penalty_policy.save!&lt;br /&gt;
        LatePolicy.update_calculated_penalty_objects(@penalty_policy)&lt;br /&gt;
        flash[:notice] = &amp;quot;The late policy was successfully updated.&amp;quot;&lt;br /&gt;
        redirect_to action: 'index'&lt;br /&gt;
      rescue StandardError&lt;br /&gt;
        flash[:error] = &amp;quot;The following error occurred while updating the penalty policy: &amp;quot;&lt;br /&gt;
        redirect_to action: 'edit', id: params[:id]&lt;br /&gt;
      end&lt;br /&gt;
    elsif invalid_penalty_per_unit&lt;br /&gt;
      flash[:error] = &amp;quot;Cannot edit the policy. The maximum penalty cannot be less than penalty per unit.&amp;quot;&lt;br /&gt;
      redirect_to action: 'edit', id: params[:id]&lt;br /&gt;
    elsif same_policy_name&lt;br /&gt;
      flash[:error] = &amp;quot;Cannot edit the policy. A policy with the same name &amp;quot; + params[:late_policy][:policy_name] + &amp;quot; already exists.&amp;quot;&lt;br /&gt;
      redirect_to action: 'edit', id: params[:id]&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
After:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    invalid_penalty_per_unit = params[:late_policy][:max_penalty].to_i &amp;lt; params[:late_policy][:penalty_per_unit].to_i&lt;br /&gt;
    # If penalty per unit is invalid, exit early&lt;br /&gt;
    if invalid_penalty_per_unit&lt;br /&gt;
      flash[:error] = &amp;quot;Cannot edit the policy. The maximum penalty cannot be less than penalty per unit.&amp;quot;&lt;br /&gt;
      redirect_to action: 'edit', id: params[:id] and return&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    # Only do DB search if we pass the invalid penalty check&lt;br /&gt;
    @penalty_policy = LatePolicy.find(params[:id])&lt;br /&gt;
    # if name has changed, then only check for this&lt;br /&gt;
    if params[:late_policy][:policy_name] != @penalty_policy.policy_name&lt;br /&gt;
      if LatePolicy.check_policy_with_same_name(params[:late_policy][:policy_name], instructor_id)&lt;br /&gt;
        flash[:error] = &amp;quot;Cannot edit the policy. A policy with the same name &amp;quot; + params[:late_policy][:policy_name] + &amp;quot; already exists.&amp;quot;&lt;br /&gt;
        redirect_to action: 'edit', id: params[:id] and return&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    begin&lt;br /&gt;
      @penalty_policy.update_attributes(late_policy_params)&lt;br /&gt;
      @penalty_policy.save!&lt;br /&gt;
      LatePolicy.update_calculated_penalty_objects(@penalty_policy)&lt;br /&gt;
      flash[:notice] = &amp;quot;The late policy was successfully updated.&amp;quot;&lt;br /&gt;
      redirect_to action: 'index' and return&lt;br /&gt;
    rescue StandardError&lt;br /&gt;
      flash[:error] = &amp;quot;The following error occurred while updating the penalty policy: &amp;quot;&lt;br /&gt;
      redirect_to action: 'edit', id: params[:id] and return&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===Automated Testing using RSPEC===&lt;br /&gt;
The current version of expertiza did not have any test for LatePoliciesController, and for back button.&lt;br /&gt;
Using the test driven development(TDD) approach, we have added an exhaustive set of RSPEC tests for LatePoliciesController, to test creation and expected failure to create scenarios.&lt;br /&gt;
We have also added tests for back button on new late policy page.&lt;br /&gt;
Similarly, we have added feature tests for late policy creation.&lt;br /&gt;
&lt;br /&gt;
Late policy creation tests&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
$ rspec ./spec/features/late_policy_creation_spec.rb &lt;br /&gt;
Randomized with seed 65056&lt;br /&gt;
.....&lt;br /&gt;
&lt;br /&gt;
Finished in 22.28 seconds (files took 9.71 seconds to load)&lt;br /&gt;
5 examples, 0 failures&lt;br /&gt;
&lt;br /&gt;
Randomized with seed 65056&lt;br /&gt;
&lt;br /&gt;
Coverage report generated for RSpec to /.../expertiza/coverage. 2074 / 15378 LOC (13.49%) covered.&lt;br /&gt;
[Coveralls] Outside the Travis environment, not sending data.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Back button tests&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
$ rspec ./spec/features/late_policy_back_button_spec.rb &lt;br /&gt;
Randomized with seed 15242&lt;br /&gt;
.&lt;br /&gt;
&lt;br /&gt;
Finished in 9.74 seconds (files took 8.95 seconds to load)&lt;br /&gt;
1 example, 0 failures&lt;br /&gt;
&lt;br /&gt;
Randomized with seed 15242&lt;br /&gt;
&lt;br /&gt;
Coverage report generated for RSpec to /.../expertiza/coverage. 2041 / 15378 LOC (13.27%) covered.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
$ rspec ./spec/controllers/late_policies_controller_spec.rb &lt;br /&gt;
&lt;br /&gt;
Randomized with seed 29277&lt;br /&gt;
........&lt;br /&gt;
&lt;br /&gt;
Finished in 17.56 seconds (files took 8.64 seconds to load)&lt;br /&gt;
8 examples, 0 failures&lt;br /&gt;
&lt;br /&gt;
Randomized with seed 29277&lt;br /&gt;
&lt;br /&gt;
Coverage report generated for RSpec to /.../expertiza/coverage. 1587 / 15800 LOC (10.04%) covered.&lt;br /&gt;
[Coveralls] Outside the Travis environment, not sending data.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===References===&lt;br /&gt;
&lt;br /&gt;
#[https://github.com/expertiza/expertiza Expertiza on GitHub]&lt;br /&gt;
#[https://github.com/vinay-deshmukh/expertiza GitHub Project Repository Fork]&lt;br /&gt;
#[https://github.com/expertiza/expertiza/pull/2087/ Pull request to Expertiza repo]&lt;br /&gt;
#[https://github.com/vinay-deshmukh/expertiza/projects/1 GitHub Fork: Project board]&lt;br /&gt;
#[https://github.com/vinay-deshmukh/expertiza/issues Issues made while development]&lt;br /&gt;
#[https://github.com/vinay-deshmukh/expertiza/pulls  Pull requests made to the fork to document work]&lt;br /&gt;
#[https://github.com/vinay-deshmukh/expertiza/pulls?q=is%3Apr+is%3Aclosed Closed Pull Requests on Fork]&lt;/div&gt;</summary>
		<author><name>Vdeshmu</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2021_-_E2140._Create_new_late_policy_successfully_and_fix_Bank_link&amp;diff=139753</id>
		<title>CSC/ECE 517 Fall 2021 - E2140. Create new late policy successfully and fix Bank link</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2021_-_E2140._Create_new_late_policy_successfully_and_fix_Bank_link&amp;diff=139753"/>
		<updated>2021-10-21T02:39:37Z</updated>

		<summary type="html">&lt;p&gt;Vdeshmu: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
==E2140. Create new late policy successfully and fix &amp;quot;Back&amp;quot; link==&lt;br /&gt;
&lt;br /&gt;
This page provides a description of the Expertiza based OSS project, E1240.&lt;br /&gt;
&lt;br /&gt;
===About Expertiza===&lt;br /&gt;
&lt;br /&gt;
[http://expertiza.ncsu.edu/ Expertiza] is an open source project based on [http://rubyonrails.org/ Ruby on Rails] framework. Expertiza allows the instructor to create new assignments and customize new or existing assignments. It also allows the instructor to create a list of topics the students can sign up for. Students can form teams in Expertiza to work on various projects and assignments. Students can also peer review other students' submissions. Expertiza supports submission across various document types, including the URLs and wiki pages.&lt;br /&gt;
&lt;br /&gt;
===Problem Statement===&lt;br /&gt;
Create new late policy successfull and fix &amp;quot;Back&amp;quot; link.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Fixes performed==&lt;br /&gt;
&lt;br /&gt;
* Fix back link on &amp;quot;New late policy&amp;quot; page.&lt;br /&gt;
* Fix incorrect flash message on the screen when new late policy is created&lt;br /&gt;
* Add controller unit tests for create and edit actions for late_policies_controller&lt;br /&gt;
* Add functional test for late policy creation&lt;br /&gt;
* Add functional test for back button on new late policy page&lt;br /&gt;
* Improve flow of late_policies_controller#edit action for better tests&lt;br /&gt;
* Fix late_policies_controller#edit action when it displayed two contradictory flashes&lt;br /&gt;
* TODO: SQL stack trace shows up when long string is entered in policy name&lt;br /&gt;
* View was checked after a controller test to ensure that the correct message is shown to the user.&lt;br /&gt;
* Database was checked after controller test to verify whether correct changes happened or didn't.&lt;br /&gt;
* model was also checked to ensure the database is in a correct state&lt;br /&gt;
&lt;br /&gt;
===About Late Policies Controller===&lt;br /&gt;
&lt;br /&gt;
This controller can be accessed by editing an assignment, going on &amp;quot;Due Dates&amp;quot; page and  clicking on &amp;quot;New late policy&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
== Files modified in current project ==&lt;br /&gt;
&lt;br /&gt;
1. app/controllers/late_policies_controller.rb &amp;lt;br/&amp;gt;&lt;br /&gt;
2. app/views/late_policies/new.html.erb &amp;lt;br/&amp;gt;&lt;br /&gt;
3. spec/factories/factories.rb&amp;lt;br/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Files added for tests==&lt;br /&gt;
&lt;br /&gt;
1. spec/controllers/late_policies_controller_spec.rb &amp;lt;br/&amp;gt;&lt;br /&gt;
2. spec/features/late_policy_creation_spec.rb &amp;lt;br/&amp;gt;&lt;br /&gt;
3. spec/features/late_policy_back_button_spec.rb &amp;lt;br/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Files modified for tests==&lt;br /&gt;
&lt;br /&gt;
1. spec/factories/factories.rb&amp;lt;br /&amp;gt;&lt;br /&gt;
2. app/controllers/late_policies_controller.rb&lt;br /&gt;
&lt;br /&gt;
===Current Implementation===&lt;br /&gt;
&lt;br /&gt;
* There were no tests present in beta branch, so tests for the CRUD operations were added.&lt;br /&gt;
* Edit action for late_policies_controller is complex to reason about, with booleans deciding whether there are errors.&lt;br /&gt;
* Back button does not lead to the assignment from which the new late policy page was created.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=====Functionality=====&lt;br /&gt;
&lt;br /&gt;
1. &lt;br /&gt;
&lt;br /&gt;
=====Drawbacks and Solutions=====&lt;br /&gt;
* '''Problem 1''': Back button was taking user to index of late_policies, and not assignment due dates page&lt;br /&gt;
::The back button was performing it's default action of going back to index page of late_policies, but it needs to send user to the assginment page.&lt;br /&gt;
&lt;br /&gt;
Before: &amp;lt;br /&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;%= link_to 'Back', :action =&amp;gt; 'index' %&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
After: &amp;lt;br /&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;%= link_to 'Back', edit_assignment_path(session[:edit_assignment]) %&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
* '''Solution''': The link_to function is called with the link to the assignment which was last edited, so it will go to assginment page.&lt;br /&gt;
&lt;br /&gt;
* Use edit_assignment_path(session[:edit_assignment]) to go back to the previous page&lt;br /&gt;
&lt;br /&gt;
* '''Problem 2''': Creating new policy with blank fields does not give a proper error&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
::The existing code just shows a blank error, without specifying what has gone wrong. Hence, user will not know what is wrong when they created a new policy.&lt;br /&gt;
&lt;br /&gt;
* '''Solution''':  The existing error handling code was changed to show the ActiveRecord::Invalid errors to user. And in case, a different exception occurs, a &amp;quot;Something went wrong&amp;quot; message is shown, as this exception shouldn't be visible to users.&lt;br /&gt;
        &lt;br /&gt;
Before:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
      rescue StandardError&lt;br /&gt;
        flash[:error] = &amp;quot;The following error occurred while saving the penalty policy: &amp;quot;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
After:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
      rescue ActiveRecord::RecordInvalid =&amp;gt; exception&lt;br /&gt;
        flash[:error] = exception.record.errors.full_messages.join(&amp;quot;&amp;lt;br /&amp;gt;&amp;quot;).html_safe&lt;br /&gt;
        redirect_to action: 'new'&lt;br /&gt;
      rescue StandardError =&amp;gt; exception&lt;br /&gt;
        # In case it's some error, this error should not be shown to users&lt;br /&gt;
        flash[:error] = &amp;quot;Something went wrong&amp;quot;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* '''Problem 3''':  Update `update` method of late_policies_controller &lt;br /&gt;
:: Existing update method was too convoluted to read and due to it's convolution, it was showing wrong errors on screen.&lt;br /&gt;
* '''Solution''': &lt;br /&gt;
The control flow of the `update` method was improved to use early exits when errors occur, instead of using booleans to manage execution.&lt;br /&gt;
&lt;br /&gt;
===Code improvements===&lt;br /&gt;
late_policies_controller#update&lt;br /&gt;
Before&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    @penalty_policy = LatePolicy.find(params[:id])&lt;br /&gt;
    flash[:error] = &amp;quot;The maximum penalty cannot be less than penalty per unit.&amp;quot; if invalid_penalty_per_unit&lt;br /&gt;
    same_policy_name = false&lt;br /&gt;
    # if name has changed then only check for this&lt;br /&gt;
    if same_policy_name == LatePolicy.check_policy_with_same_name(params[:late_policy][:policy_name], instructor_id)&lt;br /&gt;
      flash[:error] = &amp;quot;The policy could not be updated because a policy with the same name already exists.&amp;quot;&lt;br /&gt;
    if !same_policy_name &amp;amp;&amp;amp; !invalid_penalty_per_unit&lt;br /&gt;
      begin&lt;br /&gt;
        @penalty_policy.update_attributes(late_policy_params)&lt;br /&gt;
        @penalty_policy.save!&lt;br /&gt;
        LatePolicy.update_calculated_penalty_objects(@penalty_policy)&lt;br /&gt;
        flash[:notice] = &amp;quot;The late policy was successfully updated.&amp;quot;&lt;br /&gt;
        redirect_to action: 'index'&lt;br /&gt;
      rescue StandardError&lt;br /&gt;
        flash[:error] = &amp;quot;The following error occurred while updating the penalty policy: &amp;quot;&lt;br /&gt;
        redirect_to action: 'edit', id: params[:id]&lt;br /&gt;
      end&lt;br /&gt;
    elsif invalid_penalty_per_unit&lt;br /&gt;
      flash[:error] = &amp;quot;Cannot edit the policy. The maximum penalty cannot be less than penalty per unit.&amp;quot;&lt;br /&gt;
      redirect_to action: 'edit', id: params[:id]&lt;br /&gt;
    elsif same_policy_name&lt;br /&gt;
      flash[:error] = &amp;quot;Cannot edit the policy. A policy with the same name &amp;quot; + params[:late_policy][:policy_name] + &amp;quot; already exists.&amp;quot;&lt;br /&gt;
      redirect_to action: 'edit', id: params[:id]&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
After:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    invalid_penalty_per_unit = params[:late_policy][:max_penalty].to_i &amp;lt; params[:late_policy][:penalty_per_unit].to_i&lt;br /&gt;
    # If penalty per unit is invalid, exit early&lt;br /&gt;
    if invalid_penalty_per_unit&lt;br /&gt;
      flash[:error] = &amp;quot;Cannot edit the policy. The maximum penalty cannot be less than penalty per unit.&amp;quot;&lt;br /&gt;
      redirect_to action: 'edit', id: params[:id] and return&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    # Only do DB search if we pass the invalid penalty check&lt;br /&gt;
    @penalty_policy = LatePolicy.find(params[:id])&lt;br /&gt;
    # if name has changed, then only check for this&lt;br /&gt;
    if params[:late_policy][:policy_name] != @penalty_policy.policy_name&lt;br /&gt;
      if LatePolicy.check_policy_with_same_name(params[:late_policy][:policy_name], instructor_id)&lt;br /&gt;
        flash[:error] = &amp;quot;Cannot edit the policy. A policy with the same name &amp;quot; + params[:late_policy][:policy_name] + &amp;quot; already exists.&amp;quot;&lt;br /&gt;
        redirect_to action: 'edit', id: params[:id] and return&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    begin&lt;br /&gt;
      @penalty_policy.update_attributes(late_policy_params)&lt;br /&gt;
      @penalty_policy.save!&lt;br /&gt;
      LatePolicy.update_calculated_penalty_objects(@penalty_policy)&lt;br /&gt;
      flash[:notice] = &amp;quot;The late policy was successfully updated.&amp;quot;&lt;br /&gt;
      redirect_to action: 'index' and return&lt;br /&gt;
    rescue StandardError&lt;br /&gt;
      flash[:error] = &amp;quot;The following error occurred while updating the penalty policy: &amp;quot;&lt;br /&gt;
      redirect_to action: 'edit', id: params[:id] and return&lt;br /&gt;
    end&lt;br /&gt;
* text&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
:text&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Automated Testing using RSPEC===&lt;br /&gt;
The current version of expertiza did not have any test for LatePoliciesController, and for back button.&lt;br /&gt;
Using the test driven development(TDD) approach, we have added an exhaustive set of RSPEC tests for LatePoliciesController, to test creation and expected failure to create scenarios.&lt;br /&gt;
We have also added tests for back button on new late policy page.&lt;br /&gt;
Similarly, we have added feature tests for late policy creation.&lt;br /&gt;
&lt;br /&gt;
Late policy creation tests&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
$ rspec ./spec/features/late_policy_creation_spec.rb &lt;br /&gt;
Randomized with seed 65056&lt;br /&gt;
.....&lt;br /&gt;
&lt;br /&gt;
Finished in 22.28 seconds (files took 9.71 seconds to load)&lt;br /&gt;
5 examples, 0 failures&lt;br /&gt;
&lt;br /&gt;
Randomized with seed 65056&lt;br /&gt;
&lt;br /&gt;
Coverage report generated for RSpec to /.../expertiza/coverage. 2074 / 15378 LOC (13.49%) covered.&lt;br /&gt;
[Coveralls] Outside the Travis environment, not sending data.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Back button tests&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
$ rspec ./spec/features/late_policy_back_button_spec.rb &lt;br /&gt;
Randomized with seed 15242&lt;br /&gt;
.&lt;br /&gt;
&lt;br /&gt;
Finished in 9.74 seconds (files took 8.95 seconds to load)&lt;br /&gt;
1 example, 0 failures&lt;br /&gt;
&lt;br /&gt;
Randomized with seed 15242&lt;br /&gt;
&lt;br /&gt;
Coverage report generated for RSpec to /.../expertiza/coverage. 2041 / 15378 LOC (13.27%) covered.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
$ rspec ./spec/controllers/late_policies_controller_spec.rb &lt;br /&gt;
&lt;br /&gt;
Randomized with seed 29277&lt;br /&gt;
........&lt;br /&gt;
&lt;br /&gt;
Finished in 17.56 seconds (files took 8.64 seconds to load)&lt;br /&gt;
8 examples, 0 failures&lt;br /&gt;
&lt;br /&gt;
Randomized with seed 29277&lt;br /&gt;
&lt;br /&gt;
Coverage report generated for RSpec to /.../expertiza/coverage. 1587 / 15800 LOC (10.04%) covered.&lt;br /&gt;
[Coveralls] Outside the Travis environment, not sending data.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===References===&lt;br /&gt;
&lt;br /&gt;
#[https://github.com/expertiza/expertiza Expertiza on GitHub]&lt;br /&gt;
#[https://github.com/vinay-deshmukh/expertiza GitHub Project Repository Fork]&lt;br /&gt;
#[https://github.com/expertiza/expertiza/pull/2087/ Pull request to Expertiza repo]&lt;br /&gt;
#[https://github.com/vinay-deshmukh/expertiza/projects/1 GitHub Fork: Project board]&lt;br /&gt;
#[https://github.com/vinay-deshmukh/expertiza/issues Issues made while development]&lt;br /&gt;
#[https://github.com/vinay-deshmukh/expertiza/pulls  Pull requests made to the fork to document work]&lt;br /&gt;
#[https://github.com/vinay-deshmukh/expertiza/pulls?q=is%3Apr+is%3Aclosed Closed Pull Requests on Fork]&lt;/div&gt;</summary>
		<author><name>Vdeshmu</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2021_-_E2140._Create_new_late_policy_successfully_and_fix_Bank_link&amp;diff=139752</id>
		<title>CSC/ECE 517 Fall 2021 - E2140. Create new late policy successfully and fix Bank link</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2021_-_E2140._Create_new_late_policy_successfully_and_fix_Bank_link&amp;diff=139752"/>
		<updated>2021-10-21T02:38:49Z</updated>

		<summary type="html">&lt;p&gt;Vdeshmu: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
==E2140. Create new late policy successfully and fix &amp;quot;Back&amp;quot; link==&lt;br /&gt;
&lt;br /&gt;
This page provides a description of the Expertiza based OSS project, E1240.&lt;br /&gt;
&lt;br /&gt;
===About Expertiza===&lt;br /&gt;
&lt;br /&gt;
[http://expertiza.ncsu.edu/ Expertiza] is an open source project based on [http://rubyonrails.org/ Ruby on Rails] framework. Expertiza allows the instructor to create new assignments and customize new or existing assignments. It also allows the instructor to create a list of topics the students can sign up for. Students can form teams in Expertiza to work on various projects and assignments. Students can also peer review other students' submissions. Expertiza supports submission across various document types, including the URLs and wiki pages.&lt;br /&gt;
&lt;br /&gt;
===Problem Statement===&lt;br /&gt;
Create new late policy successfull and fix &amp;quot;Back&amp;quot; link.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Fixes performed==&lt;br /&gt;
&lt;br /&gt;
* Fix back link on &amp;quot;New late policy&amp;quot; page.&lt;br /&gt;
* Fix incorrect flash message on the screen when new late policy is created&lt;br /&gt;
* Add controller unit tests for create and edit actions for late_policies_controller&lt;br /&gt;
* Add functional test for late policy creation&lt;br /&gt;
* Add functional test for back button on new late policy page&lt;br /&gt;
* Improve flow of late_policies_controller#edit action for better tests&lt;br /&gt;
* Fix late_policies_controller#edit action when it displayed two contradictory flashes&lt;br /&gt;
* TODO: SQL stack trace shows up when long string is entered in policy name&lt;br /&gt;
* View was checked after a controller test to ensure that the correct message is shown to the user.&lt;br /&gt;
* Database was checked after controller test to verify whether correct changes happened or didn't.&lt;br /&gt;
* model was also checked to ensure the database is in a correct state&lt;br /&gt;
&lt;br /&gt;
===About Late Policies Controller===&lt;br /&gt;
&lt;br /&gt;
This controller can be accessed by editing an assignment, going on &amp;quot;Due Dates&amp;quot; page and  clicking on &amp;quot;New late policy&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
== Files modified in current project ==&lt;br /&gt;
&lt;br /&gt;
1. app/controllers/late_policies_controller.rb &amp;lt;br/&amp;gt;&lt;br /&gt;
2. app/views/late_policies/new.html.erb &amp;lt;br/&amp;gt;&lt;br /&gt;
3. spec/factories/factories.rb&amp;lt;br/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Files added for tests===&lt;br /&gt;
&lt;br /&gt;
1. spec/controllers/late_policies_controller_spec.rb &amp;lt;br/&amp;gt;&lt;br /&gt;
2. spec/features/late_policy_creation_spec.rb &amp;lt;br/&amp;gt;&lt;br /&gt;
3. spec/features/late_policy_back_button_spec.rb &amp;lt;br/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Files modified for tests===&lt;br /&gt;
&lt;br /&gt;
1. spec/factories/factories.rb&amp;lt;br /&amp;gt;&lt;br /&gt;
2. app/controllers/late_policies_controller.rb&lt;br /&gt;
&lt;br /&gt;
===Current Implementation===&lt;br /&gt;
&lt;br /&gt;
* There were no tests present in beta branch, so tests for the CRUD operations were added.&lt;br /&gt;
* Edit action for late_policies_controller is complex to reason about, with booleans deciding whether there are errors.&lt;br /&gt;
* Back button does not lead to the assignment from which the new late policy page was created.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=====Functionality=====&lt;br /&gt;
&lt;br /&gt;
1. &lt;br /&gt;
&lt;br /&gt;
=====Drawbacks and Solutions=====&lt;br /&gt;
* '''Problem 1''': Back button was taking user to index of late_policies, and not assignment due dates page&lt;br /&gt;
::The back button was performing it's default action of going back to index page of late_policies, but it needs to send user to the assginment page.&lt;br /&gt;
&lt;br /&gt;
Before: &amp;lt;br /&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;%= link_to 'Back', :action =&amp;gt; 'index' %&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
After: &amp;lt;br /&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;%= link_to 'Back', edit_assignment_path(session[:edit_assignment]) %&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
* '''Solution''': The link_to function is called with the link to the assignment which was last edited, so it will go to assginment page.&lt;br /&gt;
&lt;br /&gt;
* Use edit_assignment_path(session[:edit_assignment]) to go back to the previous page&lt;br /&gt;
&lt;br /&gt;
* '''Problem 2''': Creating new policy with blank fields does not give a proper error&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
::The existing code just shows a blank error, without specifying what has gone wrong. Hence, user will not know what is wrong when they created a new policy.&lt;br /&gt;
&lt;br /&gt;
* '''Solution''':  The existing error handling code was changed to show the ActiveRecord::Invalid errors to user. And in case, a different exception occurs, a &amp;quot;Something went wrong&amp;quot; message is shown, as this exception shouldn't be visible to users.&lt;br /&gt;
        &lt;br /&gt;
Before:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
      rescue StandardError&lt;br /&gt;
        flash[:error] = &amp;quot;The following error occurred while saving the penalty policy: &amp;quot;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
After:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
      rescue ActiveRecord::RecordInvalid =&amp;gt; exception&lt;br /&gt;
        flash[:error] = exception.record.errors.full_messages.join(&amp;quot;&amp;lt;br /&amp;gt;&amp;quot;).html_safe&lt;br /&gt;
        redirect_to action: 'new'&lt;br /&gt;
      rescue StandardError =&amp;gt; exception&lt;br /&gt;
        # In case it's some error, this error should not be shown to users&lt;br /&gt;
        flash[:error] = &amp;quot;Something went wrong&amp;quot;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* '''Problem 3''':  Update `update` method of late_policies_controller &lt;br /&gt;
:: Existing update method was too convoluted to read and due to it's convolution, it was showing wrong errors on screen.&lt;br /&gt;
* '''Solution''': &lt;br /&gt;
The control flow of the `update` method was improved to use early exits when errors occur, instead of using booleans to manage execution.&lt;br /&gt;
&lt;br /&gt;
===Code improvements===&lt;br /&gt;
late_policies_controller#update&lt;br /&gt;
Before&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    @penalty_policy = LatePolicy.find(params[:id])&lt;br /&gt;
    flash[:error] = &amp;quot;The maximum penalty cannot be less than penalty per unit.&amp;quot; if invalid_penalty_per_unit&lt;br /&gt;
    same_policy_name = false&lt;br /&gt;
    # if name has changed then only check for this&lt;br /&gt;
    if same_policy_name == LatePolicy.check_policy_with_same_name(params[:late_policy][:policy_name], instructor_id)&lt;br /&gt;
      flash[:error] = &amp;quot;The policy could not be updated because a policy with the same name already exists.&amp;quot;&lt;br /&gt;
    if !same_policy_name &amp;amp;&amp;amp; !invalid_penalty_per_unit&lt;br /&gt;
      begin&lt;br /&gt;
        @penalty_policy.update_attributes(late_policy_params)&lt;br /&gt;
        @penalty_policy.save!&lt;br /&gt;
        LatePolicy.update_calculated_penalty_objects(@penalty_policy)&lt;br /&gt;
        flash[:notice] = &amp;quot;The late policy was successfully updated.&amp;quot;&lt;br /&gt;
        redirect_to action: 'index'&lt;br /&gt;
      rescue StandardError&lt;br /&gt;
        flash[:error] = &amp;quot;The following error occurred while updating the penalty policy: &amp;quot;&lt;br /&gt;
        redirect_to action: 'edit', id: params[:id]&lt;br /&gt;
      end&lt;br /&gt;
    elsif invalid_penalty_per_unit&lt;br /&gt;
      flash[:error] = &amp;quot;Cannot edit the policy. The maximum penalty cannot be less than penalty per unit.&amp;quot;&lt;br /&gt;
      redirect_to action: 'edit', id: params[:id]&lt;br /&gt;
    elsif same_policy_name&lt;br /&gt;
      flash[:error] = &amp;quot;Cannot edit the policy. A policy with the same name &amp;quot; + params[:late_policy][:policy_name] + &amp;quot; already exists.&amp;quot;&lt;br /&gt;
      redirect_to action: 'edit', id: params[:id]&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
After:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    invalid_penalty_per_unit = params[:late_policy][:max_penalty].to_i &amp;lt; params[:late_policy][:penalty_per_unit].to_i&lt;br /&gt;
    # If penalty per unit is invalid, exit early&lt;br /&gt;
    if invalid_penalty_per_unit&lt;br /&gt;
      flash[:error] = &amp;quot;Cannot edit the policy. The maximum penalty cannot be less than penalty per unit.&amp;quot;&lt;br /&gt;
      redirect_to action: 'edit', id: params[:id] and return&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    # Only do DB search if we pass the invalid penalty check&lt;br /&gt;
    @penalty_policy = LatePolicy.find(params[:id])&lt;br /&gt;
    # if name has changed, then only check for this&lt;br /&gt;
    if params[:late_policy][:policy_name] != @penalty_policy.policy_name&lt;br /&gt;
      if LatePolicy.check_policy_with_same_name(params[:late_policy][:policy_name], instructor_id)&lt;br /&gt;
        flash[:error] = &amp;quot;Cannot edit the policy. A policy with the same name &amp;quot; + params[:late_policy][:policy_name] + &amp;quot; already exists.&amp;quot;&lt;br /&gt;
        redirect_to action: 'edit', id: params[:id] and return&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    begin&lt;br /&gt;
      @penalty_policy.update_attributes(late_policy_params)&lt;br /&gt;
      @penalty_policy.save!&lt;br /&gt;
      LatePolicy.update_calculated_penalty_objects(@penalty_policy)&lt;br /&gt;
      flash[:notice] = &amp;quot;The late policy was successfully updated.&amp;quot;&lt;br /&gt;
      redirect_to action: 'index' and return&lt;br /&gt;
    rescue StandardError&lt;br /&gt;
      flash[:error] = &amp;quot;The following error occurred while updating the penalty policy: &amp;quot;&lt;br /&gt;
      redirect_to action: 'edit', id: params[:id] and return&lt;br /&gt;
    end&lt;br /&gt;
* text&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
:text&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Automated Testing using RSPEC===&lt;br /&gt;
The current version of expertiza did not have any test for LatePoliciesController, and for back button.&lt;br /&gt;
Using the test driven development(TDD) approach, we have added an exhaustive set of RSPEC tests for LatePoliciesController, to test creation and expected failure to create scenarios.&lt;br /&gt;
We have also added tests for back button on new late policy page.&lt;br /&gt;
Similarly, we have added feature tests for late policy creation.&lt;br /&gt;
&lt;br /&gt;
Late policy creation tests&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
$ rspec ./spec/features/late_policy_creation_spec.rb &lt;br /&gt;
Randomized with seed 65056&lt;br /&gt;
.....&lt;br /&gt;
&lt;br /&gt;
Finished in 22.28 seconds (files took 9.71 seconds to load)&lt;br /&gt;
5 examples, 0 failures&lt;br /&gt;
&lt;br /&gt;
Randomized with seed 65056&lt;br /&gt;
&lt;br /&gt;
Coverage report generated for RSpec to /.../expertiza/coverage. 2074 / 15378 LOC (13.49%) covered.&lt;br /&gt;
[Coveralls] Outside the Travis environment, not sending data.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Back button tests&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
$ rspec ./spec/features/late_policy_back_button_spec.rb &lt;br /&gt;
Randomized with seed 15242&lt;br /&gt;
.&lt;br /&gt;
&lt;br /&gt;
Finished in 9.74 seconds (files took 8.95 seconds to load)&lt;br /&gt;
1 example, 0 failures&lt;br /&gt;
&lt;br /&gt;
Randomized with seed 15242&lt;br /&gt;
&lt;br /&gt;
Coverage report generated for RSpec to /.../expertiza/coverage. 2041 / 15378 LOC (13.27%) covered.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
$ rspec ./spec/controllers/late_policies_controller_spec.rb &lt;br /&gt;
&lt;br /&gt;
Randomized with seed 29277&lt;br /&gt;
........&lt;br /&gt;
&lt;br /&gt;
Finished in 17.56 seconds (files took 8.64 seconds to load)&lt;br /&gt;
8 examples, 0 failures&lt;br /&gt;
&lt;br /&gt;
Randomized with seed 29277&lt;br /&gt;
&lt;br /&gt;
Coverage report generated for RSpec to /.../expertiza/coverage. 1587 / 15800 LOC (10.04%) covered.&lt;br /&gt;
[Coveralls] Outside the Travis environment, not sending data.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===References===&lt;br /&gt;
&lt;br /&gt;
#[https://github.com/expertiza/expertiza Expertiza on GitHub]&lt;br /&gt;
#[https://github.com/vinay-deshmukh/expertiza GitHub Project Repository Fork]&lt;br /&gt;
#[https://github.com/expertiza/expertiza/pull/2087/ Pull request to Expertiza repo]&lt;br /&gt;
#[https://github.com/vinay-deshmukh/expertiza/projects/1 GitHub Fork: Project board]&lt;br /&gt;
#[https://github.com/vinay-deshmukh/expertiza/issues Issues made while development]&lt;br /&gt;
#[https://github.com/vinay-deshmukh/expertiza/pulls  Pull requests made to the fork to document work]&lt;br /&gt;
#[https://github.com/vinay-deshmukh/expertiza/pulls?q=is%3Apr+is%3Aclosed Closed Pull Requests on Fork]&lt;/div&gt;</summary>
		<author><name>Vdeshmu</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2021_-_E2140._Create_new_late_policy_successfully_and_fix_Bank_link&amp;diff=139749</id>
		<title>CSC/ECE 517 Fall 2021 - E2140. Create new late policy successfully and fix Bank link</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2021_-_E2140._Create_new_late_policy_successfully_and_fix_Bank_link&amp;diff=139749"/>
		<updated>2021-10-21T02:37:47Z</updated>

		<summary type="html">&lt;p&gt;Vdeshmu: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
==E2140. Create new late policy successfully and fix &amp;quot;Back&amp;quot; link==&lt;br /&gt;
&lt;br /&gt;
This page provides a description of the Expertiza based OSS project, E1240.&lt;br /&gt;
&lt;br /&gt;
===About Expertiza===&lt;br /&gt;
&lt;br /&gt;
[http://expertiza.ncsu.edu/ Expertiza] is an open source project based on [http://rubyonrails.org/ Ruby on Rails] framework. Expertiza allows the instructor to create new assignments and customize new or existing assignments. It also allows the instructor to create a list of topics the students can sign up for. Students can form teams in Expertiza to work on various projects and assignments. Students can also peer review other students' submissions. Expertiza supports submission across various document types, including the URLs and wiki pages.&lt;br /&gt;
&lt;br /&gt;
===Problem Statement===&lt;br /&gt;
Create new late policy successfull and fix &amp;quot;Back&amp;quot; link.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Fixes performed==&lt;br /&gt;
&lt;br /&gt;
* Fix back link on &amp;quot;New late policy&amp;quot; page.&lt;br /&gt;
* Fix incorrect flash message on the screen when new late policy is created&lt;br /&gt;
* Add controller unit tests for create and edit actions for late_policies_controller&lt;br /&gt;
* Add functional test for late policy creation&lt;br /&gt;
* Add functional test for back button on new late policy page&lt;br /&gt;
* Improve flow of late_policies_controller#edit action for better tests&lt;br /&gt;
* Fix late_policies_controller#edit action when it displayed two contradictory flashes&lt;br /&gt;
* TODO: SQL stack trace shows up when long string is entered in policy name&lt;br /&gt;
* View was checked after a controller test to ensure that the correct message is shown to the user.&lt;br /&gt;
* Database was checked after controller test to verify whether correct changes happened or didn't.&lt;br /&gt;
* TODO: model was also checked to ensure the database is in a correct state&lt;br /&gt;
&lt;br /&gt;
===About Late Policies Controller===&lt;br /&gt;
&lt;br /&gt;
This controller can be accessed by editing an assignment, going on &amp;quot;Due Dates&amp;quot; page and  clicking on &amp;quot;New late policy&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
== Files modified in current project ==&lt;br /&gt;
&lt;br /&gt;
1. app/controllers/late_policies_controller.rb &amp;lt;br/&amp;gt;&lt;br /&gt;
2. app/views/late_policies/new.html.erb &amp;lt;br/&amp;gt;&lt;br /&gt;
3. spec/factories/factories.rb&amp;lt;br/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Files added for tests===&lt;br /&gt;
&lt;br /&gt;
1. spec/controllers/late_policies_controller_spec.rb &amp;lt;br/&amp;gt;&lt;br /&gt;
2. spec/features/late_policy_creation_spec.rb &amp;lt;br/&amp;gt;&lt;br /&gt;
3. spec/features/late_policy_back_button_spec.rb &amp;lt;br/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Files modified for tests===&lt;br /&gt;
&lt;br /&gt;
1. spec/factories/factories.rb&amp;lt;br /&amp;gt;&lt;br /&gt;
2. app/controllers/late_policies_controller.rb&lt;br /&gt;
&lt;br /&gt;
===Current Implementation===&lt;br /&gt;
&lt;br /&gt;
* There were no tests present in beta branch, so tests for the CRUD operations were added.&lt;br /&gt;
* Edit action for late_policies_controller is complex to reason about, with booleans deciding whether there are errors.&lt;br /&gt;
* Back button does not lead to the assignment from which the new late policy page was created.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=====Functionality=====&lt;br /&gt;
&lt;br /&gt;
1. &lt;br /&gt;
&lt;br /&gt;
=====Drawbacks and Solutions=====&lt;br /&gt;
* '''Problem 1''': Back button was taking user to index of late_policies, and not assignment due dates page&lt;br /&gt;
::The back button was performing it's default action of going back to index page of late_policies, but it needs to send user to the assginment page.&lt;br /&gt;
&lt;br /&gt;
Before: &amp;lt;br /&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;%= link_to 'Back', :action =&amp;gt; 'index' %&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
After: &amp;lt;br /&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;%= link_to 'Back', edit_assignment_path(session[:edit_assignment]) %&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
* '''Solution''': The link_to function is called with the link to the assignment which was last edited, so it will go to assginment page.&lt;br /&gt;
&lt;br /&gt;
* Use edit_assignment_path(session[:edit_assignment]) to go back to the previous page&lt;br /&gt;
&lt;br /&gt;
* '''Problem 2''': Creating new policy with blank fields does not give a proper error&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
::The existing code just shows a blank error, without specifying what has gone wrong. Hence, user will not know what is wrong when they created a new policy.&lt;br /&gt;
&lt;br /&gt;
* '''Solution''':  The existing error handling code was changed to show the ActiveRecord::Invalid errors to user. And in case, a different exception occurs, a &amp;quot;Something went wrong&amp;quot; message is shown, as this exception shouldn't be visible to users.&lt;br /&gt;
        &lt;br /&gt;
Before:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
      rescue StandardError&lt;br /&gt;
        flash[:error] = &amp;quot;The following error occurred while saving the penalty policy: &amp;quot;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
After:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
      rescue ActiveRecord::RecordInvalid =&amp;gt; exception&lt;br /&gt;
        flash[:error] = exception.record.errors.full_messages.join(&amp;quot;&amp;lt;br /&amp;gt;&amp;quot;).html_safe&lt;br /&gt;
        redirect_to action: 'new'&lt;br /&gt;
      rescue StandardError =&amp;gt; exception&lt;br /&gt;
        # In case it's some error, this error should not be shown to users&lt;br /&gt;
        flash[:error] = &amp;quot;Something went wrong&amp;quot;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* '''Problem 3''':  Update `update` method of late_policies_controller &lt;br /&gt;
:: Existing update method was too convoluted to read and due to it's convolution, it was showing wrong errors on screen.&lt;br /&gt;
* '''Solution''': &lt;br /&gt;
The control flow of the `update` method was improved to use early exits when errors occur, instead of using booleans to manage execution.&lt;br /&gt;
&lt;br /&gt;
===Code improvements===&lt;br /&gt;
late_policies_controller#update&lt;br /&gt;
Before&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    @penalty_policy = LatePolicy.find(params[:id])&lt;br /&gt;
    flash[:error] = &amp;quot;The maximum penalty cannot be less than penalty per unit.&amp;quot; if invalid_penalty_per_unit&lt;br /&gt;
    same_policy_name = false&lt;br /&gt;
    # if name has changed then only check for this&lt;br /&gt;
    if same_policy_name == LatePolicy.check_policy_with_same_name(params[:late_policy][:policy_name], instructor_id)&lt;br /&gt;
      flash[:error] = &amp;quot;The policy could not be updated because a policy with the same name already exists.&amp;quot;&lt;br /&gt;
    if !same_policy_name &amp;amp;&amp;amp; !invalid_penalty_per_unit&lt;br /&gt;
      begin&lt;br /&gt;
        @penalty_policy.update_attributes(late_policy_params)&lt;br /&gt;
        @penalty_policy.save!&lt;br /&gt;
        LatePolicy.update_calculated_penalty_objects(@penalty_policy)&lt;br /&gt;
        flash[:notice] = &amp;quot;The late policy was successfully updated.&amp;quot;&lt;br /&gt;
        redirect_to action: 'index'&lt;br /&gt;
      rescue StandardError&lt;br /&gt;
        flash[:error] = &amp;quot;The following error occurred while updating the penalty policy: &amp;quot;&lt;br /&gt;
        redirect_to action: 'edit', id: params[:id]&lt;br /&gt;
      end&lt;br /&gt;
    elsif invalid_penalty_per_unit&lt;br /&gt;
      flash[:error] = &amp;quot;Cannot edit the policy. The maximum penalty cannot be less than penalty per unit.&amp;quot;&lt;br /&gt;
      redirect_to action: 'edit', id: params[:id]&lt;br /&gt;
    elsif same_policy_name&lt;br /&gt;
      flash[:error] = &amp;quot;Cannot edit the policy. A policy with the same name &amp;quot; + params[:late_policy][:policy_name] + &amp;quot; already exists.&amp;quot;&lt;br /&gt;
      redirect_to action: 'edit', id: params[:id]&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
After:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    invalid_penalty_per_unit = params[:late_policy][:max_penalty].to_i &amp;lt; params[:late_policy][:penalty_per_unit].to_i&lt;br /&gt;
    # If penalty per unit is invalid, exit early&lt;br /&gt;
    if invalid_penalty_per_unit&lt;br /&gt;
      flash[:error] = &amp;quot;Cannot edit the policy. The maximum penalty cannot be less than penalty per unit.&amp;quot;&lt;br /&gt;
      redirect_to action: 'edit', id: params[:id] and return&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    # Only do DB search if we pass the invalid penalty check&lt;br /&gt;
    @penalty_policy = LatePolicy.find(params[:id])&lt;br /&gt;
    # if name has changed, then only check for this&lt;br /&gt;
    if params[:late_policy][:policy_name] != @penalty_policy.policy_name&lt;br /&gt;
      if LatePolicy.check_policy_with_same_name(params[:late_policy][:policy_name], instructor_id)&lt;br /&gt;
        flash[:error] = &amp;quot;Cannot edit the policy. A policy with the same name &amp;quot; + params[:late_policy][:policy_name] + &amp;quot; already exists.&amp;quot;&lt;br /&gt;
        redirect_to action: 'edit', id: params[:id] and return&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    begin&lt;br /&gt;
      @penalty_policy.update_attributes(late_policy_params)&lt;br /&gt;
      @penalty_policy.save!&lt;br /&gt;
      LatePolicy.update_calculated_penalty_objects(@penalty_policy)&lt;br /&gt;
      flash[:notice] = &amp;quot;The late policy was successfully updated.&amp;quot;&lt;br /&gt;
      redirect_to action: 'index' and return&lt;br /&gt;
    rescue StandardError&lt;br /&gt;
      flash[:error] = &amp;quot;The following error occurred while updating the penalty policy: &amp;quot;&lt;br /&gt;
      redirect_to action: 'edit', id: params[:id] and return&lt;br /&gt;
    end&lt;br /&gt;
* text&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
:text&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Automated Testing using RSPEC===&lt;br /&gt;
TODO: add this section&lt;br /&gt;
The current version of expertiza did not have any test for LatePoliciesController, and for back button.&lt;br /&gt;
Using the test driven development(TDD) approach, we have added an exhaustive set of RSPEC tests for LatePoliciesController, to test creation and expected failure to create scenarios.&lt;br /&gt;
We have also added tests for back button on new late policy page.&lt;br /&gt;
Similarly, we have added feature tests for late policy creation.&lt;br /&gt;
&lt;br /&gt;
Late policy creation tests&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
$ rspec ./spec/features/late_policy_creation_spec.rb &lt;br /&gt;
Randomized with seed 65056&lt;br /&gt;
.....&lt;br /&gt;
&lt;br /&gt;
Finished in 22.28 seconds (files took 9.71 seconds to load)&lt;br /&gt;
5 examples, 0 failures&lt;br /&gt;
&lt;br /&gt;
Randomized with seed 65056&lt;br /&gt;
&lt;br /&gt;
Coverage report generated for RSpec to /.../expertiza/coverage. 2074 / 15378 LOC (13.49%) covered.&lt;br /&gt;
[Coveralls] Outside the Travis environment, not sending data.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Back button tests&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
$ rspec ./spec/features/late_policy_back_button_spec.rb &lt;br /&gt;
Randomized with seed 15242&lt;br /&gt;
.&lt;br /&gt;
&lt;br /&gt;
Finished in 9.74 seconds (files took 8.95 seconds to load)&lt;br /&gt;
1 example, 0 failures&lt;br /&gt;
&lt;br /&gt;
Randomized with seed 15242&lt;br /&gt;
&lt;br /&gt;
Coverage report generated for RSpec to /.../expertiza/coverage. 2041 / 15378 LOC (13.27%) covered.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
$ rspec ./spec/controllers/late_policies_controller_spec.rb &lt;br /&gt;
&lt;br /&gt;
Randomized with seed 29277&lt;br /&gt;
........&lt;br /&gt;
&lt;br /&gt;
Finished in 17.56 seconds (files took 8.64 seconds to load)&lt;br /&gt;
8 examples, 0 failures&lt;br /&gt;
&lt;br /&gt;
Randomized with seed 29277&lt;br /&gt;
&lt;br /&gt;
Coverage report generated for RSpec to /.../expertiza/coverage. 1587 / 15800 LOC (10.04%) covered.&lt;br /&gt;
[Coveralls] Outside the Travis environment, not sending data.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===References===&lt;br /&gt;
&lt;br /&gt;
#[https://github.com/expertiza/expertiza Expertiza on GitHub]&lt;br /&gt;
#[https://github.com/vinay-deshmukh/expertiza GitHub Project Repository Fork]&lt;br /&gt;
#[https://github.com/expertiza/expertiza/pull/2087/ Pull request to Expertiza repo]&lt;br /&gt;
#[https://github.com/vinay-deshmukh/expertiza/projects/1 GitHub Fork: Project board]&lt;br /&gt;
#[https://github.com/vinay-deshmukh/expertiza/issues Issues made while development]&lt;br /&gt;
#[https://github.com/vinay-deshmukh/expertiza/pulls  Pull requests made to the fork to document work]&lt;br /&gt;
#[https://github.com/vinay-deshmukh/expertiza/pulls?q=is%3Apr+is%3Aclosed Closed Pull Requests on Fork]&lt;/div&gt;</summary>
		<author><name>Vdeshmu</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2021_-_E2140._Create_new_late_policy_successfully_and_fix_Bank_link&amp;diff=139259</id>
		<title>CSC/ECE 517 Fall 2021 - E2140. Create new late policy successfully and fix Bank link</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2021_-_E2140._Create_new_late_policy_successfully_and_fix_Bank_link&amp;diff=139259"/>
		<updated>2021-10-20T01:42:25Z</updated>

		<summary type="html">&lt;p&gt;Vdeshmu: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
==E2140. Create new late policy successfully and fix &amp;quot;Back&amp;quot; link==&lt;br /&gt;
&lt;br /&gt;
This page provides a description of the Expertiza based OSS project, E1240.&lt;br /&gt;
&lt;br /&gt;
===About Expertiza===&lt;br /&gt;
&lt;br /&gt;
[http://expertiza.ncsu.edu/ Expertiza] is an open source project based on [http://rubyonrails.org/ Ruby on Rails] framework. Expertiza allows the instructor to create new assignments and customize new or existing assignments. It also allows the instructor to create a list of topics the students can sign up for. Students can form teams in Expertiza to work on various projects and assignments. Students can also peer review other students' submissions. Expertiza supports submission across various document types, including the URLs and wiki pages.&lt;br /&gt;
&lt;br /&gt;
===Problem Statement===&lt;br /&gt;
Create new late policy successfull and fix &amp;quot;Back&amp;quot; link.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Fixes performed==&lt;br /&gt;
&lt;br /&gt;
* Fix back link on &amp;quot;New late policy&amp;quot; page.&lt;br /&gt;
* Fix incorrect flash message on the screen when new late policy is created&lt;br /&gt;
* Add controller unit tests for create actions for late_policies_controller&lt;br /&gt;
* Add functional test for late policy creation&lt;br /&gt;
* Add functional test for back button on new late policy page&lt;br /&gt;
* Improve flow of late_policies_controller#edit action for better tests&lt;br /&gt;
* Fix late_policies_controller#edit action when it displayed two contradictory flashes&lt;br /&gt;
* TODO: SQL stack trace shows up when long string is entered in policy name&lt;br /&gt;
* View was checked after a controller test to ensure that the correct message is shown to the user.&lt;br /&gt;
* TODO: model was also checked to ensure the database is in a correct state&lt;br /&gt;
&lt;br /&gt;
===About Late Policies Controller===&lt;br /&gt;
&lt;br /&gt;
This controller can be accessed by editing an assignment, going on &amp;quot;Due Dates&amp;quot; page and  clicking on &amp;quot;New late policy&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
== Files modified in current project ==&lt;br /&gt;
&lt;br /&gt;
1. app/controllers/late_policies_controller.rb &amp;lt;br/&amp;gt;&lt;br /&gt;
2. app/views/late_policies/new.html.erb &amp;lt;br/&amp;gt;&lt;br /&gt;
3. spec/factories/factories.rb&amp;lt;br/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Files added for tests===&lt;br /&gt;
&lt;br /&gt;
1. spec/controllers/late_policies_controller_spec.rb &amp;lt;br/&amp;gt;&lt;br /&gt;
2. spec/features/late_policy_creation_spec.rb &amp;lt;br/&amp;gt;&lt;br /&gt;
3. spec/features/late_policy_back_button_spec.rb &amp;lt;br/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Current Implementation===&lt;br /&gt;
&lt;br /&gt;
* There were no tests present in beta branch, so tests for the CRUD operations were added.&lt;br /&gt;
* Edit action for late_policies_controller is complex to reason about, with booleans deciding whether there are errors.&lt;br /&gt;
* Back button does not lead to the assignment from which the new late policy page was created.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=====Functionality=====&lt;br /&gt;
&lt;br /&gt;
1. &lt;br /&gt;
&lt;br /&gt;
=====Drawbacks and Solutions=====&lt;br /&gt;
* '''Problem 1''': Back button was taking user to index of late_policies, and not assignment due dates page&lt;br /&gt;
::The back button was performing it's default action of going back to index page of late_policies, but it needs to send user to the assginment page.&lt;br /&gt;
&lt;br /&gt;
Before: &amp;lt;br /&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;%= link_to 'Back', :action =&amp;gt; 'index' %&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
After: &amp;lt;br /&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;%= link_to 'Back', edit_assignment_path(session[:edit_assignment]) %&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
* '''Solution''': The link_to function is called with the page previous to current page, so it will go to assginment page.&lt;br /&gt;
&lt;br /&gt;
* Use edit_assignment_path(session[:edit_assignment]) to go back to the previous page&lt;br /&gt;
&lt;br /&gt;
* '''Problem 2''': Creating new policy with blank fields does not give a proper error&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
::The existing code just shows a blank error, without specifying what has gone wrong. Hence, user will not know what is wrong when they created a new policy.&lt;br /&gt;
&lt;br /&gt;
* '''Solution''':  The existing error handling code was changed to show the ActiveRecord::Invalid errors to user. And in case, a different exception occurs, a &amp;quot;something went wrong&amp;quot; message is shown, as this exception shouldn't be visible to users.&lt;br /&gt;
        &lt;br /&gt;
Before:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
      rescue StandardError&lt;br /&gt;
      flash[:error] = &amp;quot;The following error occurred while saving the penalty policy: &amp;quot;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
After:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
      rescue ActiveRecord::RecordInvalid =&amp;gt; exception&lt;br /&gt;
        flash[:error] = exception.record.errors.full_messages.join(&amp;quot;&amp;lt;br /&amp;gt;&amp;quot;).html_safe&lt;br /&gt;
        redirect_to action: 'new'&lt;br /&gt;
      rescue StandardError =&amp;gt; exception&lt;br /&gt;
        # In case it's some error, this error should not be shown to users&lt;br /&gt;
        flash[:error] = &amp;quot;Something went wrong&amp;quot;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* '''Problem 3''': The paginate method can be moved to a helper class.&lt;br /&gt;
::VersionsController is not the only component which require to paginate items. There are other components too. For instance, the UsersController has to paginate the list of users. Hence the Paginate method can be moved to a helper class which can be accessed by other components as well.&lt;br /&gt;
* '''Solution''': The filtering options has also been enhanced. The current user can now choose as part of the version search filter any user from a list of users if the current user is authorized to see the versions created by that user.&lt;br /&gt;
&lt;br /&gt;
===New Implementation===&lt;br /&gt;
text&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
* text&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* text&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Code improvements===&lt;br /&gt;
* text&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
:text&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Automated Testing using RSPEC===&lt;br /&gt;
TODO: add this section&lt;br /&gt;
The current version of expertiza did not have any test for LatePoliciesController.&lt;br /&gt;
Using the test driven development(TDD) approach, we have added an exhaustive set of RSPEC tests for LatePoliciesController, to test all the modifications we have done to the code of the controller class. The tests use double and stub features of rspec-rails gem, to fake the log in by different users - Administrator, Instructor, Student etc. The tests can be executed &amp;quot;rpec spec&amp;quot; command as shown below.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
TODO:: Add execution trace for tests, with time taken, etc&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Testing from UI===&lt;br /&gt;
===References===&lt;br /&gt;
&lt;br /&gt;
#[https://github.com/expertiza/expertiza Expertiza on GitHub]&lt;br /&gt;
#[https://github.com/vinay-deshmukh/expertiza GitHub Project Repository Fork]&lt;br /&gt;
#[https://github.com/expertiza/expertiza/pull/2087/ Pull request to Expertiza repo]&lt;br /&gt;
#[https://github.com/vinay-deshmukh/expertiza/projects/1 GitHub Fork: Project board]&lt;br /&gt;
#[https://github.com/vinay-deshmukh/expertiza/issues Issues made while development]&lt;br /&gt;
#[https://github.com/vinay-deshmukh/expertiza/pulls  Pull requests made to the fork to document work]&lt;/div&gt;</summary>
		<author><name>Vdeshmu</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2021_-_E2140._Create_new_late_policy_successfully_and_fix_Bank_link&amp;diff=139148</id>
		<title>CSC/ECE 517 Fall 2021 - E2140. Create new late policy successfully and fix Bank link</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2021_-_E2140._Create_new_late_policy_successfully_and_fix_Bank_link&amp;diff=139148"/>
		<updated>2021-10-19T02:08:03Z</updated>

		<summary type="html">&lt;p&gt;Vdeshmu: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
==E2140. Create new late policy successfully and fix &amp;quot;Back&amp;quot; link==&lt;br /&gt;
&lt;br /&gt;
This page provides a description of the Expertiza based OSS project, E1240.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===About Expertiza===&lt;br /&gt;
&lt;br /&gt;
[http://expertiza.ncsu.edu/ Expertiza] is an open source project based on [http://rubyonrails.org/ Ruby on Rails] framework. Expertiza allows the instructor to create new assignments and customize new or existing assignments. It also allows the instructor to create a list of topics the students can sign up for. Students can form teams in Expertiza to work on various projects and assignments. Students can also peer review other students' submissions. Expertiza supports submission across various document types, including the URLs and wiki pages.&lt;br /&gt;
&lt;br /&gt;
===Problem Statement===&lt;br /&gt;
Create new late policy successfull and fix &amp;quot;Back&amp;quot; link.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Fixes performed===&lt;br /&gt;
&lt;br /&gt;
* Fix back link on &amp;quot;New late policy&amp;quot; page.&lt;br /&gt;
* Fix incorrect flash message on the screen when new late policy is created&lt;br /&gt;
* Add controller unit tests for create actions for late_policies_controller&lt;br /&gt;
* Add functional test for late policy creation&lt;br /&gt;
* Add functional test for back button on new late policy page&lt;br /&gt;
* Improve flow of late_policies_controller#edit action for better tests&lt;br /&gt;
* Fix late_policies_controller#edit action when it displayed two contradictory flashes&lt;br /&gt;
* TODO: SQL stack trace shows up when long string is entered in policy name&lt;br /&gt;
* View was checked after a controller test to ensure that the correct message is shown to the user.&lt;br /&gt;
* TODO: model was also checked to ensure the database is in a correct state&lt;br /&gt;
&lt;br /&gt;
===About Late Policies Controller===&lt;br /&gt;
&lt;br /&gt;
This controller can be accessed by editing an assignment, going on &amp;quot;Due Dates&amp;quot; page and  clicking on &amp;quot;New late policy&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
== Files modified in current project ==&lt;br /&gt;
&lt;br /&gt;
1. app/controllers/late_policies_controller.rb &amp;lt;br/&amp;gt;&lt;br /&gt;
2. app/views/late_policies/new.html.erb &amp;lt;br/&amp;gt;&lt;br /&gt;
3. spec/factories/factories.rb&amp;lt;br/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Files added for tests===&lt;br /&gt;
&lt;br /&gt;
1. spec/controllers/late_policies_controller_spec.rb &amp;lt;br/&amp;gt;&lt;br /&gt;
2. spec/features/late_policy_creation_spec.rb &amp;lt;br/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===About Versions Controller===&lt;br /&gt;
This class manages different versions of reviews. If a reviewer reviews a submission, and after that, the author revises the submission, the next time the reviewer does a review (s)he will create a new version. Sometimes it’s necessary to find the current version of a review; sometimes it’s necessary to find all versions. Similarly, a user may want to delete the current version of a review, or all versions of a review. Pagination of versions helps the user to view a subset of versions at a time. Considering the huge number of versions in the system, it is very useful to have a pagination mechanism and a filtering mechanism which can be applied on the whole set of versions. The idea is to display the versions in an ordered, comprehensible and logical manner. In Expertiza the gem ‘will_paginate’ is used to achieve pagination.&lt;br /&gt;
&lt;br /&gt;
===Current Implementation===&lt;br /&gt;
&lt;br /&gt;
* There were no tests present in beta branch, so tests for the CRUD operations were added.&lt;br /&gt;
* Edit action for late_policies_controller is complex to reason about, with booleans deciding whether there are errors.&lt;br /&gt;
* Back button does not lead to the assignment from which the new late policy page was created.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=====Functionality=====&lt;br /&gt;
&lt;br /&gt;
1. &lt;br /&gt;
&lt;br /&gt;
=====Drawbacks and Solutions=====&lt;br /&gt;
* '''Problem 1''': Back button was taking user to index of late_policies, and not assignment due dates page&lt;br /&gt;
::The back button was performing it's default action of going back to index page of late_policies, but it needs to send user to the assginment page.&lt;br /&gt;
&lt;br /&gt;
Before: &amp;lt;br /&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;%= link_to 'Back', :action =&amp;gt; 'index' %&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
After: &amp;lt;br /&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;%= link_to 'Back', 'javascript:history.back()' %&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
* '''Solution''': The link_to function is called with the page previous to current page, so it will go to assginment page.&lt;br /&gt;
&lt;br /&gt;
* Use javascript:history.back() to go back to the previous page&lt;br /&gt;
&lt;br /&gt;
* '''Problem 2''': Creating new policy with blank fields does not give a proper error&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
::The existing code just shows a blank error, without specifying what has gone wrong. Hence, user will not know what is wrong when they created a new policy.&lt;br /&gt;
&lt;br /&gt;
* '''Solution''':  The existing error handling code was changed to show the ActiveRecord::Invalid errors to user. And in case, a different exception occurs, a &amp;quot;something went wrong&amp;quot; message is shown, as this exception shouldn't be visible to users.&lt;br /&gt;
        &lt;br /&gt;
Before:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
      rescue StandardError&lt;br /&gt;
      flash[:error] = &amp;quot;The following error occurred while saving the penalty policy: &amp;quot;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
After:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
      rescue ActiveRecord::RecordInvalid =&amp;gt; exception&lt;br /&gt;
        flash[:error] = exception.record.errors.full_messages.join(&amp;quot;&amp;lt;br /&amp;gt;&amp;quot;).html_safe&lt;br /&gt;
        redirect_to action: 'new'&lt;br /&gt;
      rescue StandardError =&amp;gt; exception&lt;br /&gt;
        # In case it's some error, this error should not be shown to users&lt;br /&gt;
        flash[:error] = &amp;quot;Something went wrong&amp;quot;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* '''Problem 3''': The paginate method can be moved to a helper class.&lt;br /&gt;
::VersionsController is not the only component which require to paginate items. There are other components too. For instance, the UsersController has to paginate the list of users. Hence the Paginate method can be moved to a helper class which can be accessed by other components as well.&lt;br /&gt;
* '''Solution''': The filtering options has also been enhanced. The current user can now choose as part of the version search filter any user from a list of users if the current user is authorized to see the versions created by that user.&lt;br /&gt;
&lt;br /&gt;
===New Implementation===&lt;br /&gt;
text&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
* text&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* text&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Code improvements===&lt;br /&gt;
* text&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
:text&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Automated Testing using RSPEC===&lt;br /&gt;
TODO: add this section&lt;br /&gt;
The current version of expertiza did not have any test for LatePoliciesController.&lt;br /&gt;
Using the test driven development(TDD) approach, we have added an exhaustive set of RSPEC tests for LatePoliciesController, to test all the modifications we have done to the code of the controller class. The tests use double and stub features of rspec-rails gem, to fake the log in by different users - Administrator, Instructor, Student etc. The tests can be executed &amp;quot;rpec spec&amp;quot; command as shown below.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
TODO:: Add execution trace for tests, with time taken, etc&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Testing from UI===&lt;br /&gt;
===References===&lt;br /&gt;
&lt;br /&gt;
#[https://github.com/expertiza/expertiza Expertiza on GitHub]&lt;br /&gt;
#[https://github.com/vinay-deshmukh/expertiza GitHub Project Repository Fork]&lt;br /&gt;
#[https://github.com/expertiza/expertiza/pull/2087/ Pull request to Expertiza repo]&lt;br /&gt;
#[https://github.com/vinay-deshmukh/expertiza/projects/1 GitHub Fork: Project board]&lt;br /&gt;
#[https://github.com/vinay-deshmukh/expertiza/issues Issues made while development]&lt;br /&gt;
#[https://github.com/vinay-deshmukh/expertiza/pulls  Pull requests made to the fork to document work]&lt;/div&gt;</summary>
		<author><name>Vdeshmu</name></author>
	</entry>
</feed>