<?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=Cnbrown4</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=Cnbrown4"/>
	<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=Special:Contributions/Cnbrown4"/>
	<updated>2026-05-22T22:40:59Z</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_2015_E1581_Integration_testing_for_student_interface&amp;diff=100579</id>
		<title>CSC/ECE 517 Fall 2015 E1581 Integration testing for student interface</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2015_E1581_Integration_testing_for_student_interface&amp;diff=100579"/>
		<updated>2015-12-16T15:25:41Z</updated>

		<summary type="html">&lt;p&gt;Cnbrown4: /* Setup */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Create integration tests for the student interface using capybara and rspec. Integration testing is the phase in software testing in which individual software modules are combined and tested as a group. It occurs after unit testing and before validation testing. Integration testing takes as its input modules that have been unit tested, groups them in larger aggregates, applies tests defined in an integration test plan to those aggregates, and delivers as its output the integrated system ready for system testing.&lt;br /&gt;
&lt;br /&gt;
== Design ==&lt;br /&gt;
To properly execute the integration tests we will write the test cases to mimic a user operating the system. We will create strong integration test cases to help ensure the outcome of application's student interface remains the same regardless of changes to its inner functionality. In an attempt to keep our tests DRY we will put common code in a support directory.&lt;br /&gt;
&lt;br /&gt;
== Testing tools ==&lt;br /&gt;
'''RSpec''' is a behavior-driven development (BDD) framework for the Ruby (programming language)|Ruby programming language, inspired by JBehave. It contains its own mocking framework that is fully integrated into the framework based upon JMock.&lt;br /&gt;
&lt;br /&gt;
'''Capybara''' is a web-based automation framework used for creating functional tests which can simulate how users would interact with your application.&lt;br /&gt;
==Setup==&lt;br /&gt;
In order to run these test successfully the test data must be inserted into the expertiza_test database.  To add the test data to the database run this command: &amp;quot;mysql -u root -p -h localhost expertiza_test &amp;lt; spec/features/db/TestData.sql&amp;quot;.  You should now be able to run the integration tests.&lt;br /&gt;
&lt;br /&gt;
== Test Plan ==&lt;br /&gt;
There are 8 features to be tested:&lt;br /&gt;
# Log in&lt;br /&gt;
# Add someone to a team &lt;br /&gt;
# Select a topic(if the assignment has topics)&lt;br /&gt;
# Select a submission to review For assignments with or without topics&lt;br /&gt;
# Bring up a review form&lt;br /&gt;
# Fill out &amp;amp; submit a review form&lt;br /&gt;
# View your scores&lt;br /&gt;
# Respond to a review (“author feedback”)&lt;br /&gt;
&lt;br /&gt;
=== Log in ===&lt;br /&gt;
we create a file called ‘student_signin_spec.rb’.  We define a method named login; and because we need this method in every later  feature test we will put this in the support directory.&lt;br /&gt;
* Scenario 1: Log in with ‘invalid combination of username and password’&lt;br /&gt;
When we sign in with correct name and password; we expect that there should be content ‘Invalid username/password’ appear in the new page.&lt;br /&gt;
* Scenario 2: Log in with ‘valid combination of username and password’&lt;br /&gt;
When we sign in with correct name and password; we expect that there should be content ‘User: (username)’ appear in the new page.&lt;br /&gt;
&lt;br /&gt;
Run test using the command &amp;quot;rspec spec/features/student_sign_in_spec.rb&amp;quot;&lt;br /&gt;
&lt;br /&gt;
=== Add someone to a team ===&lt;br /&gt;
* Scenario 1: Team member exceed max amount&lt;br /&gt;
# Sign in &lt;br /&gt;
# Click link certain assignment(in this test: Ethical analysis 2)&lt;br /&gt;
# Click link  “Your team” &lt;br /&gt;
# Fill in the text area with invitation receiver name&lt;br /&gt;
# Click send invitation button&lt;br /&gt;
# Sign out.&lt;br /&gt;
# Sign in as receiver&lt;br /&gt;
# Click link assignment&lt;br /&gt;
# Click link  “Your team”&lt;br /&gt;
# Click  button ‘accept’&lt;br /&gt;
&lt;br /&gt;
On this page, we expect the sender's name will appear.&lt;br /&gt;
&lt;br /&gt;
Run test using the command &amp;quot;rspec spec/features/add_member_spec.rb &amp;quot;&lt;br /&gt;
&lt;br /&gt;
=== Select a topic ===&lt;br /&gt;
Note: assignment has topics&lt;br /&gt;
&lt;br /&gt;
We need the following steps:&lt;br /&gt;
# sign in. &lt;br /&gt;
# click the link for assignment &lt;br /&gt;
# click link  “signup sheet”&lt;br /&gt;
# click the sign up for the remaining topic we want, as this user has already signed up for this topic, we should get the following message: Your topic(s): Self-plagiarism. &lt;br /&gt;
# sign out &lt;br /&gt;
Run test using the command &amp;quot;rspec spec/features/select_a_topic_spec.rb &amp;quot;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Select a submission to review ===&lt;br /&gt;
# sign in.  &lt;br /&gt;
# click the link for the assignment we want to review.&lt;br /&gt;
# click the link for “other’s work”&lt;br /&gt;
# click the link for the submission we want to review&lt;br /&gt;
# sign out &lt;br /&gt;
Run test using the command &amp;quot;rspec spec/features/select_a_submission_to_review_spec.rb &amp;quot;&lt;br /&gt;
&lt;br /&gt;
=== Bring up a review form ===&lt;br /&gt;
* Scenario 1: Choose a topic to review&lt;br /&gt;
# sign in.  &lt;br /&gt;
# click the link for the assignment we want to review.&lt;br /&gt;
# click the link for “other’s work”&lt;br /&gt;
# choose a topic&lt;br /&gt;
# click 'Begin'&lt;br /&gt;
# check that a review form has successfully been created&lt;br /&gt;
* Scenario 2: Choose a random topic&lt;br /&gt;
# sign in.  &lt;br /&gt;
# click the link for the assignment we want to review.&lt;br /&gt;
# click the link for “other’s work”&lt;br /&gt;
# check 'I do not care'&lt;br /&gt;
# click 'Request new submission' button&lt;br /&gt;
# click 'Begin' to open review form&lt;br /&gt;
# check that a review form has successfully been created&lt;br /&gt;
* Scenario 3: Review an assignment without a topic&lt;br /&gt;
# sign in.  &lt;br /&gt;
# click the link for the assignment we want to review.&lt;br /&gt;
# click the link for “other’s work”&lt;br /&gt;
# click 'Request new submission' button&lt;br /&gt;
# click 'Begin' to open review form&lt;br /&gt;
# check that a review form has successfully been created&lt;br /&gt;
Run test using the command &amp;quot;rspec spec/features/bring_up_review_form_spec.rb &amp;quot;&lt;br /&gt;
&lt;br /&gt;
=== Fill out and submit a review form ===&lt;br /&gt;
* Scenario 1: Fill out form and save&lt;br /&gt;
# sign in.  &lt;br /&gt;
# click the link for the assignment we want to review.&lt;br /&gt;
# click the link for “other’s work”&lt;br /&gt;
# click 'Begin'&lt;br /&gt;
# fill out all text fields&lt;br /&gt;
# save form&lt;br /&gt;
# check for successful save&lt;br /&gt;
* Scenario 2: Fill out form, save, edit, and resave&lt;br /&gt;
# sign in.  &lt;br /&gt;
# click the link for the assignment we want to review.&lt;br /&gt;
# click the link for “other’s work”&lt;br /&gt;
# click 'Begin'&lt;br /&gt;
# fill out one text field&lt;br /&gt;
# save form&lt;br /&gt;
# click edit&lt;br /&gt;
# fill out other text fields&lt;br /&gt;
# click save&lt;br /&gt;
# check for successful save&lt;br /&gt;
Run test using the command &amp;quot;rspec spec/features/fill_out_review_form_spec.rb &amp;quot;&lt;br /&gt;
&lt;br /&gt;
=== View your scores ===&lt;br /&gt;
* Scenario 1: No Scores available yet&lt;br /&gt;
# Sign in&lt;br /&gt;
# Click link for Assignment&lt;br /&gt;
# Click ‘Your scores’&lt;br /&gt;
# Check that nothing exists yet&lt;br /&gt;
# Check for dashes.&lt;br /&gt;
* Scenario 2: Scores available.&lt;br /&gt;
# Sign in&lt;br /&gt;
# Click link for Assignment&lt;br /&gt;
# Click ‘Your scores’&lt;br /&gt;
# Check that displayed scores match scores independently calculated from all reviews.&lt;br /&gt;
To run this test run: $ rspec spec/features/student_view_score.rb&lt;br /&gt;
&lt;br /&gt;
=== Respond to a review (“author feedback”) ===&lt;br /&gt;
# Sign in as author&lt;br /&gt;
# Click link for Assignment&lt;br /&gt;
# Click ‘Your scores’&lt;br /&gt;
# Click ‘show reviews’&lt;br /&gt;
# Click ‘Give feedback’&lt;br /&gt;
# Fill out Feedback form&lt;br /&gt;
# Click Save Feedback&lt;br /&gt;
# Check for confirmation that the feedback was saved&lt;br /&gt;
To run this test run:$ rspec spec/features/review_feedback.rb&lt;br /&gt;
&lt;br /&gt;
==Links==&lt;br /&gt;
*Github repository:  https://github.com/xhy279/expertiza/tree/fall2015/spec/features&lt;br /&gt;
*Pull requests link: https://github.com/expertiza/expertiza/pull/640 &lt;br /&gt;
*Demo videos(4 in total): &amp;lt;br&amp;gt;&lt;br /&gt;
1. https://drive.google.com/open?id=0B3EOsci5DEveMGZOdVNIazJlNVE &amp;lt;br&amp;gt;&lt;br /&gt;
2. https://drive.google.com/a/ncsu.edu/file/d/0B-l-xu44qiJUZDRFMU02U09kZWs/view?usp=sharing &amp;lt;br&amp;gt;&lt;br /&gt;
3. https://drive.google.com/a/ncsu.edu/file/d/0B80MLsKsoSOmaVV5Tm1mQWIwb0U/view?usp=sharing &amp;lt;br&amp;gt; &lt;br /&gt;
4. https://drive.google.com/a/ncsu.edu/file/d/0B7dSj1bvwNp9X29TTHJMVFhPWkE/view?usp=sharing &amp;lt;br&amp;gt;&lt;br /&gt;
Note: There is a problem at the end of the third video and the save can not complete because of a time out issue. This does not effect the test, just the ability to demonstrate the test.&lt;/div&gt;</summary>
		<author><name>Cnbrown4</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2015_E1581_Integration_testing_for_student_interface&amp;diff=100428</id>
		<title>CSC/ECE 517 Fall 2015 E1581 Integration testing for student interface</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2015_E1581_Integration_testing_for_student_interface&amp;diff=100428"/>
		<updated>2015-12-13T18:52:11Z</updated>

		<summary type="html">&lt;p&gt;Cnbrown4: /* Bring up a review form */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Create integration tests for the student interface using capybara and rspec. Integration testing is the phase in software testing in which individual software modules are combined and tested as a group. It occurs after unit testing and before validation testing. Integration testing takes as its input modules that have been unit tested, groups them in larger aggregates, applies tests defined in an integration test plan to those aggregates, and delivers as its output the integrated system ready for system testing.&lt;br /&gt;
&lt;br /&gt;
== Design ==&lt;br /&gt;
To properly execute the integration tests we will write the test cases to mimic a user operating the system. We will create strong integration test cases to help ensure the outcome of application's student interface remains the same regardless of changes to its inner functionality. In an attempt to keep our tests DRY we will put common code in a support directory.&lt;br /&gt;
&lt;br /&gt;
== Testing tools ==&lt;br /&gt;
'''RSpec''' is a behavior-driven development (BDD) framework for the Ruby (programming language)|Ruby programming language, inspired by JBehave. It contains its own mocking framework that is fully integrated into the framework based upon JMock.&lt;br /&gt;
&lt;br /&gt;
'''Capybara''' is a web-based automation framework used for creating functional tests which can simulate how users would interact with your application.&lt;br /&gt;
==Setup==&lt;br /&gt;
In order to run these test successfully the test data must be inserted into the expertiza_test database.  To add the test data to the database run this command: &amp;quot;mysql -u root -p -h localhost expertiza_test &amp;lt; spec/features/db/TestData.sql&amp;quot;.  After this command runs you should update the review date to be a future date.  To do this log into mysql by using the command &amp;quot;mysql -u -root -p&amp;quot;, then type &amp;quot;use expertiza_test;&amp;quot; and hit enter, the execute this query &amp;quot;update due_dates set due_at = 'FUTURE DATE HERE' where deadline_type_id = 2;&amp;quot; (The format of the future date should look like this - &amp;gt; 2016-01-01 00:00:00).  You should now be able to run the integration tests.  In order to run the tests for a second time you should follow this setup from the beginning.&lt;br /&gt;
&lt;br /&gt;
== Test Plan ==&lt;br /&gt;
There are 8 features to be tested:&lt;br /&gt;
# Log in&lt;br /&gt;
# Add someone to a team &lt;br /&gt;
# Select a topic(if the assignment has topics)&lt;br /&gt;
# Select a submission to review For assignments with or without topics&lt;br /&gt;
# Bring up a review form&lt;br /&gt;
# Fill out &amp;amp; submit a review form&lt;br /&gt;
# View your scores&lt;br /&gt;
# Respond to a review (“author feedback”)&lt;br /&gt;
&lt;br /&gt;
=== Log in ===&lt;br /&gt;
we create a file called ‘student_signin_spec.rb’.  We define a method named login; and because we need this method in every later  feature test we will put this in the support directory.&lt;br /&gt;
* Scenario 1: Log in with ‘invalid combination of username and password’&lt;br /&gt;
When we sign in with correct name and password; we expect that there should be content ‘Invalid username/password’ appear in the new page.&lt;br /&gt;
* Scenario 2: Log in with ‘valid combination of username and password’&lt;br /&gt;
When we sign in with correct name and password; we expect that there should be content ‘User: (username)’ appear in the new page.&lt;br /&gt;
&lt;br /&gt;
Run test using the command &amp;quot;rspec spec/features/student_sign_in_spec.rb&amp;quot;&lt;br /&gt;
&lt;br /&gt;
=== Add someone to a team ===&lt;br /&gt;
* Scenario 1: Team member exceed max amount&lt;br /&gt;
# Sign in &lt;br /&gt;
# Click link certain assignment(in this test: Ethical analysis 2)&lt;br /&gt;
# Click link  “Your team” &lt;br /&gt;
# Fill in the text area with invitation receiver name&lt;br /&gt;
# Click send invitation button&lt;br /&gt;
# Sign out.&lt;br /&gt;
# Sign in as receiver&lt;br /&gt;
# Click link assignment&lt;br /&gt;
# Click link  “Your team”&lt;br /&gt;
# Click  button ‘accept’&lt;br /&gt;
&lt;br /&gt;
On this page, we expect the sender's name will appear.&lt;br /&gt;
&lt;br /&gt;
Run test using the command &amp;quot;rspec spec/features/add_member_spec.rb &amp;quot;&lt;br /&gt;
&lt;br /&gt;
=== Select a topic ===&lt;br /&gt;
Note: assignment has topics&lt;br /&gt;
&lt;br /&gt;
We need the following steps:&lt;br /&gt;
# sign in. &lt;br /&gt;
# click the link for assignment &lt;br /&gt;
# click link  “signup sheet”&lt;br /&gt;
# click the sign up for the remaining topic we want, as this user has already signed up for this topic, we should get the following message: Your topic(s): Self-plagiarism. &lt;br /&gt;
# sign out &lt;br /&gt;
Run test using the command &amp;quot;rspec spec/features/select_a_topic_spec.rb &amp;quot;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Select a submission to review ===&lt;br /&gt;
# sign in.  &lt;br /&gt;
# click the link for the assignment we want to review.&lt;br /&gt;
# click the link for “other’s work”&lt;br /&gt;
# click the link for the submission we want to review&lt;br /&gt;
# sign out &lt;br /&gt;
Run test using the command &amp;quot;rspec spec/features/select_a_submission_to_review_spec.rb &amp;quot;&lt;br /&gt;
&lt;br /&gt;
=== Bring up a review form ===&lt;br /&gt;
* Scenario 1: Choose a topic to review&lt;br /&gt;
# sign in.  &lt;br /&gt;
# click the link for the assignment we want to review.&lt;br /&gt;
# click the link for “other’s work”&lt;br /&gt;
# choose a topic&lt;br /&gt;
# click 'Begin'&lt;br /&gt;
# check that a review form has successfully been created&lt;br /&gt;
* Scenario 2: Choose a random topic&lt;br /&gt;
# sign in.  &lt;br /&gt;
# click the link for the assignment we want to review.&lt;br /&gt;
# click the link for “other’s work”&lt;br /&gt;
# check 'I do not care'&lt;br /&gt;
# click 'Request new submission' button&lt;br /&gt;
# click 'Begin' to open review form&lt;br /&gt;
# check that a review form has successfully been created&lt;br /&gt;
* Scenario 3: Review an assignment without a topic&lt;br /&gt;
# sign in.  &lt;br /&gt;
# click the link for the assignment we want to review.&lt;br /&gt;
# click the link for “other’s work”&lt;br /&gt;
# click 'Request new submission' button&lt;br /&gt;
# click 'Begin' to open review form&lt;br /&gt;
# check that a review form has successfully been created&lt;br /&gt;
Run test using the command &amp;quot;rspec spec/features/bring_up_review_form_spec.rb &amp;quot;&lt;br /&gt;
&lt;br /&gt;
=== Fill out and submit a review form ===&lt;br /&gt;
* Scenario 1: Fill out form and save&lt;br /&gt;
# sign in.  &lt;br /&gt;
# click the link for the assignment we want to review.&lt;br /&gt;
# click the link for “other’s work”&lt;br /&gt;
# click 'Begin'&lt;br /&gt;
# fill out all text fields&lt;br /&gt;
# save form&lt;br /&gt;
# check for successful save&lt;br /&gt;
* Scenario 2: Fill out form, save, edit, and resave&lt;br /&gt;
# sign in.  &lt;br /&gt;
# click the link for the assignment we want to review.&lt;br /&gt;
# click the link for “other’s work”&lt;br /&gt;
# click 'Begin'&lt;br /&gt;
# fill out one text field&lt;br /&gt;
# save form&lt;br /&gt;
# click edit&lt;br /&gt;
# fill out other text fields&lt;br /&gt;
# click save&lt;br /&gt;
# check for successful save&lt;br /&gt;
Run test using the command &amp;quot;rspec spec/features/fill_out_review_form_spec.rb &amp;quot;&lt;br /&gt;
&lt;br /&gt;
=== View your scores ===&lt;br /&gt;
* Scenario 1: No Scores available yet&lt;br /&gt;
# Sign in&lt;br /&gt;
# Click link for Assignment&lt;br /&gt;
# Click ‘Your scores’&lt;br /&gt;
# Check that nothing exists yet&lt;br /&gt;
# Check for dashes.&lt;br /&gt;
* Scenario 2: Scores available.&lt;br /&gt;
# Sign in&lt;br /&gt;
# Click link for Assignment&lt;br /&gt;
# Click ‘Your scores’&lt;br /&gt;
# Check that displayed scores match scores independently calculated from all reviews.&lt;br /&gt;
To run this test run: $ rspec spec/features/student_view_score.rb&lt;br /&gt;
&lt;br /&gt;
=== Respond to a review (“author feedback”) ===&lt;br /&gt;
# Sign in as author&lt;br /&gt;
# Click link for Assignment&lt;br /&gt;
# Click ‘Your scores’&lt;br /&gt;
# Click ‘show reviews’&lt;br /&gt;
# Click ‘Give feedback’&lt;br /&gt;
# Fill out Feedback form&lt;br /&gt;
# Click Save Feedback&lt;br /&gt;
# Check for confirmation that the feedback was saved&lt;br /&gt;
To run this test run:$ rspec spec/features/review_feedback.rb&lt;br /&gt;
&lt;br /&gt;
==Links==&lt;br /&gt;
*Github repository:  https://github.com/xhy279/expertiza/tree/fall2015/spec/features&lt;br /&gt;
*Pull requests link: https://github.com/expertiza/expertiza/pull/640 &lt;br /&gt;
*Demo videos(4 in total): &amp;lt;br&amp;gt;&lt;br /&gt;
1. https://drive.google.com/open?id=0B3EOsci5DEveMGZOdVNIazJlNVE &amp;lt;br&amp;gt;&lt;br /&gt;
2. https://drive.google.com/a/ncsu.edu/file/d/0B-l-xu44qiJUZDRFMU02U09kZWs/view?usp=sharing &amp;lt;br&amp;gt;&lt;br /&gt;
3. https://drive.google.com/a/ncsu.edu/file/d/0B80MLsKsoSOmaVV5Tm1mQWIwb0U/view?usp=sharing &amp;lt;br&amp;gt; &lt;br /&gt;
4. https://drive.google.com/a/ncsu.edu/file/d/0B7dSj1bvwNp9X29TTHJMVFhPWkE/view?usp=sharing &amp;lt;br&amp;gt;&lt;br /&gt;
Note: There is a problem at the end of the third video and the save can not complete because of a time out issue. This does not effect the test, just the ability to demonstrate the test.&lt;/div&gt;</summary>
		<author><name>Cnbrown4</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2015_E1581_Integration_testing_for_student_interface&amp;diff=100427</id>
		<title>CSC/ECE 517 Fall 2015 E1581 Integration testing for student interface</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2015_E1581_Integration_testing_for_student_interface&amp;diff=100427"/>
		<updated>2015-12-13T18:50:45Z</updated>

		<summary type="html">&lt;p&gt;Cnbrown4: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Create integration tests for the student interface using capybara and rspec. Integration testing is the phase in software testing in which individual software modules are combined and tested as a group. It occurs after unit testing and before validation testing. Integration testing takes as its input modules that have been unit tested, groups them in larger aggregates, applies tests defined in an integration test plan to those aggregates, and delivers as its output the integrated system ready for system testing.&lt;br /&gt;
&lt;br /&gt;
== Design ==&lt;br /&gt;
To properly execute the integration tests we will write the test cases to mimic a user operating the system. We will create strong integration test cases to help ensure the outcome of application's student interface remains the same regardless of changes to its inner functionality. In an attempt to keep our tests DRY we will put common code in a support directory.&lt;br /&gt;
&lt;br /&gt;
== Testing tools ==&lt;br /&gt;
'''RSpec''' is a behavior-driven development (BDD) framework for the Ruby (programming language)|Ruby programming language, inspired by JBehave. It contains its own mocking framework that is fully integrated into the framework based upon JMock.&lt;br /&gt;
&lt;br /&gt;
'''Capybara''' is a web-based automation framework used for creating functional tests which can simulate how users would interact with your application.&lt;br /&gt;
==Setup==&lt;br /&gt;
In order to run these test successfully the test data must be inserted into the expertiza_test database.  To add the test data to the database run this command: &amp;quot;mysql -u root -p -h localhost expertiza_test &amp;lt; spec/features/db/TestData.sql&amp;quot;.  After this command runs you should update the review date to be a future date.  To do this log into mysql by using the command &amp;quot;mysql -u -root -p&amp;quot;, then type &amp;quot;use expertiza_test;&amp;quot; and hit enter, the execute this query &amp;quot;update due_dates set due_at = 'FUTURE DATE HERE' where deadline_type_id = 2;&amp;quot; (The format of the future date should look like this - &amp;gt; 2016-01-01 00:00:00).  You should now be able to run the integration tests.  In order to run the tests for a second time you should follow this setup from the beginning.&lt;br /&gt;
&lt;br /&gt;
== Test Plan ==&lt;br /&gt;
There are 8 features to be tested:&lt;br /&gt;
# Log in&lt;br /&gt;
# Add someone to a team &lt;br /&gt;
# Select a topic(if the assignment has topics)&lt;br /&gt;
# Select a submission to review For assignments with or without topics&lt;br /&gt;
# Bring up a review form&lt;br /&gt;
# Fill out &amp;amp; submit a review form&lt;br /&gt;
# View your scores&lt;br /&gt;
# Respond to a review (“author feedback”)&lt;br /&gt;
&lt;br /&gt;
=== Log in ===&lt;br /&gt;
we create a file called ‘student_signin_spec.rb’.  We define a method named login; and because we need this method in every later  feature test we will put this in the support directory.&lt;br /&gt;
* Scenario 1: Log in with ‘invalid combination of username and password’&lt;br /&gt;
When we sign in with correct name and password; we expect that there should be content ‘Invalid username/password’ appear in the new page.&lt;br /&gt;
* Scenario 2: Log in with ‘valid combination of username and password’&lt;br /&gt;
When we sign in with correct name and password; we expect that there should be content ‘User: (username)’ appear in the new page.&lt;br /&gt;
&lt;br /&gt;
Run test using the command &amp;quot;rspec spec/features/student_sign_in_spec.rb&amp;quot;&lt;br /&gt;
&lt;br /&gt;
=== Add someone to a team ===&lt;br /&gt;
* Scenario 1: Team member exceed max amount&lt;br /&gt;
# Sign in &lt;br /&gt;
# Click link certain assignment(in this test: Ethical analysis 2)&lt;br /&gt;
# Click link  “Your team” &lt;br /&gt;
# Fill in the text area with invitation receiver name&lt;br /&gt;
# Click send invitation button&lt;br /&gt;
# Sign out.&lt;br /&gt;
# Sign in as receiver&lt;br /&gt;
# Click link assignment&lt;br /&gt;
# Click link  “Your team”&lt;br /&gt;
# Click  button ‘accept’&lt;br /&gt;
&lt;br /&gt;
On this page, we expect the sender's name will appear.&lt;br /&gt;
&lt;br /&gt;
Run test using the command &amp;quot;rspec spec/features/add_member_spec.rb &amp;quot;&lt;br /&gt;
&lt;br /&gt;
=== Select a topic ===&lt;br /&gt;
Note: assignment has topics&lt;br /&gt;
&lt;br /&gt;
We need the following steps:&lt;br /&gt;
# sign in. &lt;br /&gt;
# click the link for assignment &lt;br /&gt;
# click link  “signup sheet”&lt;br /&gt;
# click the sign up for the remaining topic we want, as this user has already signed up for this topic, we should get the following message: Your topic(s): Self-plagiarism. &lt;br /&gt;
# sign out &lt;br /&gt;
Run test using the command &amp;quot;rspec spec/features/select_a_topic_spec.rb &amp;quot;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Select a submission to review ===&lt;br /&gt;
# sign in.  &lt;br /&gt;
# click the link for the assignment we want to review.&lt;br /&gt;
# click the link for “other’s work”&lt;br /&gt;
# click the link for the submission we want to review&lt;br /&gt;
# sign out &lt;br /&gt;
Run test using the command &amp;quot;rspec spec/features/select_a_submission_to_review_spec.rb &amp;quot;&lt;br /&gt;
&lt;br /&gt;
=== Bring up a review form ===&lt;br /&gt;
* Scenario 1: Choose a topic to review&lt;br /&gt;
# sign in.  &lt;br /&gt;
# click the link for the assignment we want to review.&lt;br /&gt;
# click the link for “other’s work”&lt;br /&gt;
# choose a topic&lt;br /&gt;
# click 'Begin'&lt;br /&gt;
# check that a review form has successfully been created&lt;br /&gt;
* Scenario 2: Choose a random topic&lt;br /&gt;
# sign in.  &lt;br /&gt;
# click the link for the assignment we want to review.&lt;br /&gt;
# click the link for “other’s work”&lt;br /&gt;
# check 'I do not care'&lt;br /&gt;
# click 'Request new submission' button&lt;br /&gt;
# click 'Begin' to open review form&lt;br /&gt;
# check that a review form has successfully been created&lt;br /&gt;
Run test using the command &amp;quot;rspec spec/features/bring_up_review_form_spec.rb &amp;quot;&lt;br /&gt;
&lt;br /&gt;
=== Fill out and submit a review form ===&lt;br /&gt;
* Scenario 1: Fill out form and save&lt;br /&gt;
# sign in.  &lt;br /&gt;
# click the link for the assignment we want to review.&lt;br /&gt;
# click the link for “other’s work”&lt;br /&gt;
# click 'Begin'&lt;br /&gt;
# fill out all text fields&lt;br /&gt;
# save form&lt;br /&gt;
# check for successful save&lt;br /&gt;
* Scenario 2: Fill out form, save, edit, and resave&lt;br /&gt;
# sign in.  &lt;br /&gt;
# click the link for the assignment we want to review.&lt;br /&gt;
# click the link for “other’s work”&lt;br /&gt;
# click 'Begin'&lt;br /&gt;
# fill out one text field&lt;br /&gt;
# save form&lt;br /&gt;
# click edit&lt;br /&gt;
# fill out other text fields&lt;br /&gt;
# click save&lt;br /&gt;
# check for successful save&lt;br /&gt;
Run test using the command &amp;quot;rspec spec/features/fill_out_review_form_spec.rb &amp;quot;&lt;br /&gt;
&lt;br /&gt;
=== View your scores ===&lt;br /&gt;
* Scenario 1: No Scores available yet&lt;br /&gt;
# Sign in&lt;br /&gt;
# Click link for Assignment&lt;br /&gt;
# Click ‘Your scores’&lt;br /&gt;
# Check that nothing exists yet&lt;br /&gt;
# Check for dashes.&lt;br /&gt;
* Scenario 2: Scores available.&lt;br /&gt;
# Sign in&lt;br /&gt;
# Click link for Assignment&lt;br /&gt;
# Click ‘Your scores’&lt;br /&gt;
# Check that displayed scores match scores independently calculated from all reviews.&lt;br /&gt;
To run this test run: $ rspec spec/features/student_view_score.rb&lt;br /&gt;
&lt;br /&gt;
=== Respond to a review (“author feedback”) ===&lt;br /&gt;
# Sign in as author&lt;br /&gt;
# Click link for Assignment&lt;br /&gt;
# Click ‘Your scores’&lt;br /&gt;
# Click ‘show reviews’&lt;br /&gt;
# Click ‘Give feedback’&lt;br /&gt;
# Fill out Feedback form&lt;br /&gt;
# Click Save Feedback&lt;br /&gt;
# Check for confirmation that the feedback was saved&lt;br /&gt;
To run this test run:$ rspec spec/features/review_feedback.rb&lt;br /&gt;
&lt;br /&gt;
==Links==&lt;br /&gt;
*Github repository:  https://github.com/xhy279/expertiza/tree/fall2015/spec/features&lt;br /&gt;
*Pull requests link: https://github.com/expertiza/expertiza/pull/640 &lt;br /&gt;
*Demo videos(4 in total): &amp;lt;br&amp;gt;&lt;br /&gt;
1. https://drive.google.com/open?id=0B3EOsci5DEveMGZOdVNIazJlNVE &amp;lt;br&amp;gt;&lt;br /&gt;
2. https://drive.google.com/a/ncsu.edu/file/d/0B-l-xu44qiJUZDRFMU02U09kZWs/view?usp=sharing &amp;lt;br&amp;gt;&lt;br /&gt;
3. https://drive.google.com/a/ncsu.edu/file/d/0B80MLsKsoSOmaVV5Tm1mQWIwb0U/view?usp=sharing &amp;lt;br&amp;gt; &lt;br /&gt;
4. https://drive.google.com/a/ncsu.edu/file/d/0B7dSj1bvwNp9X29TTHJMVFhPWkE/view?usp=sharing &amp;lt;br&amp;gt;&lt;br /&gt;
Note: There is a problem at the end of the third video and the save can not complete because of a time out issue. This does not effect the test, just the ability to demonstrate the test.&lt;/div&gt;</summary>
		<author><name>Cnbrown4</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2015_E1581_Integration_testing_for_student_interface&amp;diff=100425</id>
		<title>CSC/ECE 517 Fall 2015 E1581 Integration testing for student interface</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2015_E1581_Integration_testing_for_student_interface&amp;diff=100425"/>
		<updated>2015-12-13T18:15:47Z</updated>

		<summary type="html">&lt;p&gt;Cnbrown4: /* Fill out and submit a review form */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Create integration tests for the student interface using capybara and rspec. Integration testing is the phase in software testing in which individual software modules are combined and tested as a group. It occurs after unit testing and before validation testing. Integration testing takes as its input modules that have been unit tested, groups them in larger aggregates, applies tests defined in an integration test plan to those aggregates, and delivers as its output the integrated system ready for system testing.&lt;br /&gt;
&lt;br /&gt;
== Design ==&lt;br /&gt;
To properly execute the integration tests we will write the test cases to mimic a user operating the system. We will create strong integration test cases to help ensure the outcome of application's student interface remains the same regardless of changes to its inner functionality. In an attempt to keep our tests DRY we will put common code in a support directory.&lt;br /&gt;
&lt;br /&gt;
== Testing tools ==&lt;br /&gt;
'''RSpec''' is a behavior-driven development (BDD) framework for the Ruby (programming language)|Ruby programming language, inspired by JBehave. It contains its own mocking framework that is fully integrated into the framework based upon JMock.&lt;br /&gt;
&lt;br /&gt;
'''Capybara''' is a web-based automation framework used for creating functional tests which can simulate how users would interact with your application.&lt;br /&gt;
&lt;br /&gt;
== Test Plan ==&lt;br /&gt;
There are 8 features to be tested:&lt;br /&gt;
# Log in&lt;br /&gt;
# Add someone to a team &lt;br /&gt;
# Select a topic(if the assignment has topics)&lt;br /&gt;
# Select a submission to review For assignments with or without topics&lt;br /&gt;
# Bring up a review form&lt;br /&gt;
# Fill out &amp;amp; submit a review form&lt;br /&gt;
# View your scores&lt;br /&gt;
# Respond to a review (“author feedback”)&lt;br /&gt;
&lt;br /&gt;
=== Log in ===&lt;br /&gt;
we create a file called ‘student_signin_spec.rb’.  We define a method named login; and because we need this method in every later  feature test we will put this in the support directory.&lt;br /&gt;
* Scenario 1: Log in with ‘invalid combination of username and password’&lt;br /&gt;
When we sign in with correct name and password; we expect that there should be content ‘Invalid username/password’ appear in the new page.&lt;br /&gt;
* Scenario 2: Log in with ‘valid combination of username and password’&lt;br /&gt;
When we sign in with correct name and password; we expect that there should be content ‘User: (username)’ appear in the new page.&lt;br /&gt;
&lt;br /&gt;
Run test using the command &amp;quot;rspec spec/features/student_sign_in_spec.rb&amp;quot;&lt;br /&gt;
&lt;br /&gt;
=== Add someone to a team ===&lt;br /&gt;
* Scenario 1: Team member exceed max amount&lt;br /&gt;
# Sign in &lt;br /&gt;
# Click link certain assignment(in this test: Ethical analysis 2)&lt;br /&gt;
# Click link  “Your team” &lt;br /&gt;
# Fill in the text area with invitation receiver name&lt;br /&gt;
# Click send invitation button&lt;br /&gt;
# Sign out.&lt;br /&gt;
# Sign in as receiver&lt;br /&gt;
# Click link assignment&lt;br /&gt;
# Click link  “Your team”&lt;br /&gt;
# Click  button ‘accept’&lt;br /&gt;
&lt;br /&gt;
On this page, we expect the sender's name will appear.&lt;br /&gt;
&lt;br /&gt;
Run test using the command &amp;quot;rspec spec/features/add_member_spec.rb &amp;quot;&lt;br /&gt;
&lt;br /&gt;
=== Select a topic ===&lt;br /&gt;
Note: assignment has topics&lt;br /&gt;
&lt;br /&gt;
We need the following steps:&lt;br /&gt;
# sign in. &lt;br /&gt;
# click the link for assignment &lt;br /&gt;
# click link  “signup sheet”&lt;br /&gt;
# click the sign up for the remaining topic we want, as this user has already signed up for this topic, we should get the following message: Your topic(s): Self-plagiarism. &lt;br /&gt;
# sign out &lt;br /&gt;
Run test using the command &amp;quot;rspec spec/features/select_a_topic_spec.rb &amp;quot;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Select a submission to review ===&lt;br /&gt;
# sign in.  &lt;br /&gt;
# click the link for the assignment we want to review.&lt;br /&gt;
# click the link for “other’s work”&lt;br /&gt;
# click the link for the submission we want to review&lt;br /&gt;
# sign out &lt;br /&gt;
Run test using the command &amp;quot;rspec spec/features/select_a_submission_to_review_spec.rb &amp;quot;&lt;br /&gt;
&lt;br /&gt;
=== Bring up a review form ===&lt;br /&gt;
* Scenario 1: Choose a topic to review&lt;br /&gt;
# sign in.  &lt;br /&gt;
# click the link for the assignment we want to review.&lt;br /&gt;
# click the link for “other’s work”&lt;br /&gt;
# choose a topic&lt;br /&gt;
# click 'Begin'&lt;br /&gt;
# check that a review form has successfully been created&lt;br /&gt;
* Scenario 2: Choose a random topic&lt;br /&gt;
# sign in.  &lt;br /&gt;
# click the link for the assignment we want to review.&lt;br /&gt;
# click the link for “other’s work”&lt;br /&gt;
# check 'I do not care'&lt;br /&gt;
# click 'Request new submission' button&lt;br /&gt;
# click 'Begin' to open review form&lt;br /&gt;
# check that a review form has successfully been created&lt;br /&gt;
Run test using the command &amp;quot;rspec spec/features/bring_up_review_form_spec.rb &amp;quot;&lt;br /&gt;
&lt;br /&gt;
=== Fill out and submit a review form ===&lt;br /&gt;
* Scenario 1: Fill out form and save&lt;br /&gt;
# sign in.  &lt;br /&gt;
# click the link for the assignment we want to review.&lt;br /&gt;
# click the link for “other’s work”&lt;br /&gt;
# click 'Begin'&lt;br /&gt;
# fill out all text fields&lt;br /&gt;
# save form&lt;br /&gt;
# check for successful save&lt;br /&gt;
* Scenario 2: Fill out form, save, edit, and resave&lt;br /&gt;
# sign in.  &lt;br /&gt;
# click the link for the assignment we want to review.&lt;br /&gt;
# click the link for “other’s work”&lt;br /&gt;
# click 'Begin'&lt;br /&gt;
# fill out one text field&lt;br /&gt;
# save form&lt;br /&gt;
# click edit&lt;br /&gt;
# fill out other text fields&lt;br /&gt;
# click save&lt;br /&gt;
# check for successful save&lt;br /&gt;
Run test using the command &amp;quot;rspec spec/features/fill_out_review_form_spec.rb &amp;quot;&lt;br /&gt;
&lt;br /&gt;
=== View your scores ===&lt;br /&gt;
* Scenario 1: No Scores available yet&lt;br /&gt;
# Sign in&lt;br /&gt;
# Click link for Assignment&lt;br /&gt;
# Click ‘Your scores’&lt;br /&gt;
# Check that nothing exists yet&lt;br /&gt;
# Check for dashes.&lt;br /&gt;
* Scenario 2: Scores available.&lt;br /&gt;
# Sign in&lt;br /&gt;
# Click link for Assignment&lt;br /&gt;
# Click ‘Your scores’&lt;br /&gt;
# Check that displayed scores match scores independently calculated from all reviews.&lt;br /&gt;
To run this test run: $ rspec spec/features/student_view_score.rb&lt;br /&gt;
&lt;br /&gt;
=== Respond to a review (“author feedback”) ===&lt;br /&gt;
# Sign in as author&lt;br /&gt;
# Click link for Assignment&lt;br /&gt;
# Click ‘Your scores’&lt;br /&gt;
# Click ‘show reviews’&lt;br /&gt;
# Click ‘Give feedback’&lt;br /&gt;
# Fill out Feedback form&lt;br /&gt;
# Click Save Feedback&lt;br /&gt;
# Check for confirmation that the feedback was saved&lt;br /&gt;
To run this test run:$ rspec spec/features/review_feedback.rb&lt;br /&gt;
&lt;br /&gt;
==Links==&lt;br /&gt;
*Github repository:  https://github.com/xhy279/expertiza/tree/fall2015/spec/features&lt;br /&gt;
*Pull requests link: https://github.com/expertiza/expertiza/pull/640 &lt;br /&gt;
*Demo videos(4 in total): &amp;lt;br&amp;gt;&lt;br /&gt;
1. https://drive.google.com/open?id=0B3EOsci5DEveMGZOdVNIazJlNVE &amp;lt;br&amp;gt;&lt;br /&gt;
2. https://drive.google.com/a/ncsu.edu/file/d/0B-l-xu44qiJUZDRFMU02U09kZWs/view?usp=sharing &amp;lt;br&amp;gt;&lt;br /&gt;
3. https://drive.google.com/a/ncsu.edu/file/d/0B80MLsKsoSOmaVV5Tm1mQWIwb0U/view?usp=sharing &amp;lt;br&amp;gt; &lt;br /&gt;
4. https://drive.google.com/a/ncsu.edu/file/d/0B7dSj1bvwNp9X29TTHJMVFhPWkE/view?usp=sharing &amp;lt;br&amp;gt;&lt;br /&gt;
Note: There is a problem at the end of the third video and the save can not complete because of a time out issue. This does not effect the test, just the ability to demonstrate the test.&lt;/div&gt;</summary>
		<author><name>Cnbrown4</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2015_E1581_Integration_testing_for_student_interface&amp;diff=100424</id>
		<title>CSC/ECE 517 Fall 2015 E1581 Integration testing for student interface</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2015_E1581_Integration_testing_for_student_interface&amp;diff=100424"/>
		<updated>2015-12-13T18:12:45Z</updated>

		<summary type="html">&lt;p&gt;Cnbrown4: /* Bring up a review form */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Create integration tests for the student interface using capybara and rspec. Integration testing is the phase in software testing in which individual software modules are combined and tested as a group. It occurs after unit testing and before validation testing. Integration testing takes as its input modules that have been unit tested, groups them in larger aggregates, applies tests defined in an integration test plan to those aggregates, and delivers as its output the integrated system ready for system testing.&lt;br /&gt;
&lt;br /&gt;
== Design ==&lt;br /&gt;
To properly execute the integration tests we will write the test cases to mimic a user operating the system. We will create strong integration test cases to help ensure the outcome of application's student interface remains the same regardless of changes to its inner functionality. In an attempt to keep our tests DRY we will put common code in a support directory.&lt;br /&gt;
&lt;br /&gt;
== Testing tools ==&lt;br /&gt;
'''RSpec''' is a behavior-driven development (BDD) framework for the Ruby (programming language)|Ruby programming language, inspired by JBehave. It contains its own mocking framework that is fully integrated into the framework based upon JMock.&lt;br /&gt;
&lt;br /&gt;
'''Capybara''' is a web-based automation framework used for creating functional tests which can simulate how users would interact with your application.&lt;br /&gt;
&lt;br /&gt;
== Test Plan ==&lt;br /&gt;
There are 8 features to be tested:&lt;br /&gt;
# Log in&lt;br /&gt;
# Add someone to a team &lt;br /&gt;
# Select a topic(if the assignment has topics)&lt;br /&gt;
# Select a submission to review For assignments with or without topics&lt;br /&gt;
# Bring up a review form&lt;br /&gt;
# Fill out &amp;amp; submit a review form&lt;br /&gt;
# View your scores&lt;br /&gt;
# Respond to a review (“author feedback”)&lt;br /&gt;
&lt;br /&gt;
=== Log in ===&lt;br /&gt;
we create a file called ‘student_signin_spec.rb’.  We define a method named login; and because we need this method in every later  feature test we will put this in the support directory.&lt;br /&gt;
* Scenario 1: Log in with ‘invalid combination of username and password’&lt;br /&gt;
When we sign in with correct name and password; we expect that there should be content ‘Invalid username/password’ appear in the new page.&lt;br /&gt;
* Scenario 2: Log in with ‘valid combination of username and password’&lt;br /&gt;
When we sign in with correct name and password; we expect that there should be content ‘User: (username)’ appear in the new page.&lt;br /&gt;
&lt;br /&gt;
Run test using the command &amp;quot;rspec spec/features/student_sign_in_spec.rb&amp;quot;&lt;br /&gt;
&lt;br /&gt;
=== Add someone to a team ===&lt;br /&gt;
* Scenario 1: Team member exceed max amount&lt;br /&gt;
# Sign in &lt;br /&gt;
# Click link certain assignment(in this test: Ethical analysis 2)&lt;br /&gt;
# Click link  “Your team” &lt;br /&gt;
# Fill in the text area with invitation receiver name&lt;br /&gt;
# Click send invitation button&lt;br /&gt;
# Sign out.&lt;br /&gt;
# Sign in as receiver&lt;br /&gt;
# Click link assignment&lt;br /&gt;
# Click link  “Your team”&lt;br /&gt;
# Click  button ‘accept’&lt;br /&gt;
&lt;br /&gt;
On this page, we expect the sender's name will appear.&lt;br /&gt;
&lt;br /&gt;
Run test using the command &amp;quot;rspec spec/features/add_member_spec.rb &amp;quot;&lt;br /&gt;
&lt;br /&gt;
=== Select a topic ===&lt;br /&gt;
Note: assignment has topics&lt;br /&gt;
&lt;br /&gt;
We need the following steps:&lt;br /&gt;
# sign in. &lt;br /&gt;
# click the link for assignment &lt;br /&gt;
# click link  “signup sheet”&lt;br /&gt;
# click the sign up for the remaining topic we want, as this user has already signed up for this topic, we should get the following message: Your topic(s): Self-plagiarism. &lt;br /&gt;
# sign out &lt;br /&gt;
Run test using the command &amp;quot;rspec spec/features/select_a_topic_spec.rb &amp;quot;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Select a submission to review ===&lt;br /&gt;
# sign in.  &lt;br /&gt;
# click the link for the assignment we want to review.&lt;br /&gt;
# click the link for “other’s work”&lt;br /&gt;
# click the link for the submission we want to review&lt;br /&gt;
# sign out &lt;br /&gt;
Run test using the command &amp;quot;rspec spec/features/select_a_submission_to_review_spec.rb &amp;quot;&lt;br /&gt;
&lt;br /&gt;
=== Bring up a review form ===&lt;br /&gt;
* Scenario 1: Choose a topic to review&lt;br /&gt;
# sign in.  &lt;br /&gt;
# click the link for the assignment we want to review.&lt;br /&gt;
# click the link for “other’s work”&lt;br /&gt;
# choose a topic&lt;br /&gt;
# click 'Begin'&lt;br /&gt;
# check that a review form has successfully been created&lt;br /&gt;
* Scenario 2: Choose a random topic&lt;br /&gt;
# sign in.  &lt;br /&gt;
# click the link for the assignment we want to review.&lt;br /&gt;
# click the link for “other’s work”&lt;br /&gt;
# check 'I do not care'&lt;br /&gt;
# click 'Request new submission' button&lt;br /&gt;
# click 'Begin' to open review form&lt;br /&gt;
# check that a review form has successfully been created&lt;br /&gt;
Run test using the command &amp;quot;rspec spec/features/bring_up_review_form_spec.rb &amp;quot;&lt;br /&gt;
&lt;br /&gt;
=== Fill out and submit a review form ===&lt;br /&gt;
# sign in.  &lt;br /&gt;
# click the link for the assignment we want to review.&lt;br /&gt;
# click the link for “other’s work”&lt;br /&gt;
# click 'Begin'&lt;br /&gt;
# fill out all text fields&lt;br /&gt;
# select all scores from dropdowns&lt;br /&gt;
# save form&lt;br /&gt;
# check for successful save&lt;br /&gt;
Run test using the command &amp;quot;rspec spec/features/fill_out_review_form_spec.rb &amp;quot;&lt;br /&gt;
&lt;br /&gt;
=== View your scores ===&lt;br /&gt;
* Scenario 1: No Scores available yet&lt;br /&gt;
# Sign in&lt;br /&gt;
# Click link for Assignment&lt;br /&gt;
# Click ‘Your scores’&lt;br /&gt;
# Check that nothing exists yet&lt;br /&gt;
# Check for dashes.&lt;br /&gt;
* Scenario 2: Scores available.&lt;br /&gt;
# Sign in&lt;br /&gt;
# Click link for Assignment&lt;br /&gt;
# Click ‘Your scores’&lt;br /&gt;
# Check that displayed scores match scores independently calculated from all reviews.&lt;br /&gt;
To run this test run: $ rspec spec/features/student_view_score.rb&lt;br /&gt;
&lt;br /&gt;
=== Respond to a review (“author feedback”) ===&lt;br /&gt;
# Sign in as author&lt;br /&gt;
# Click link for Assignment&lt;br /&gt;
# Click ‘Your scores’&lt;br /&gt;
# Click ‘show reviews’&lt;br /&gt;
# Click ‘Give feedback’&lt;br /&gt;
# Fill out Feedback form&lt;br /&gt;
# Click Save Feedback&lt;br /&gt;
# Check for confirmation that the feedback was saved&lt;br /&gt;
To run this test run:$ rspec spec/features/review_feedback.rb&lt;br /&gt;
&lt;br /&gt;
==Links==&lt;br /&gt;
*Github repository:  https://github.com/xhy279/expertiza/tree/fall2015/spec/features&lt;br /&gt;
*Pull requests link: https://github.com/expertiza/expertiza/pull/640 &lt;br /&gt;
*Demo videos(4 in total): &amp;lt;br&amp;gt;&lt;br /&gt;
1. https://drive.google.com/open?id=0B3EOsci5DEveMGZOdVNIazJlNVE &amp;lt;br&amp;gt;&lt;br /&gt;
2. https://drive.google.com/a/ncsu.edu/file/d/0B-l-xu44qiJUZDRFMU02U09kZWs/view?usp=sharing &amp;lt;br&amp;gt;&lt;br /&gt;
3. https://drive.google.com/a/ncsu.edu/file/d/0B80MLsKsoSOmaVV5Tm1mQWIwb0U/view?usp=sharing &amp;lt;br&amp;gt; &lt;br /&gt;
4. https://drive.google.com/a/ncsu.edu/file/d/0B7dSj1bvwNp9X29TTHJMVFhPWkE/view?usp=sharing &amp;lt;br&amp;gt;&lt;br /&gt;
Note: There is a problem at the end of the third video and the save can not complete because of a time out issue. This does not effect the test, just the ability to demonstrate the test.&lt;/div&gt;</summary>
		<author><name>Cnbrown4</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2015_E1581_Integration_testing_for_student_interface&amp;diff=100411</id>
		<title>CSC/ECE 517 Fall 2015 E1581 Integration testing for student interface</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2015_E1581_Integration_testing_for_student_interface&amp;diff=100411"/>
		<updated>2015-12-11T12:52:22Z</updated>

		<summary type="html">&lt;p&gt;Cnbrown4: /* Links */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Create integration tests for the student interface using capybara and rspec. Integration testing is the phase in software testing in which individual software modules are combined and tested as a group. It occurs after unit testing and before validation testing. Integration testing takes as its input modules that have been unit tested, groups them in larger aggregates, applies tests defined in an integration test plan to those aggregates, and delivers as its output the integrated system ready for system testing.&lt;br /&gt;
&lt;br /&gt;
== Design ==&lt;br /&gt;
To properly execute the integration tests we will write the test cases to mimic a user operating the system. We will create strong integration test cases to help ensure the outcome of application's student interface remains the same regardless of changes to its inner functionality. In an attempt to keep our tests DRY we will put common code in a support directory.&lt;br /&gt;
&lt;br /&gt;
== Testing tools ==&lt;br /&gt;
'''RSpec''' is a behavior-driven development (BDD) framework for the Ruby (programming language)|Ruby programming language, inspired by JBehave. It contains its own mocking framework that is fully integrated into the framework based upon JMock.&lt;br /&gt;
&lt;br /&gt;
'''Capybara''' is a web-based automation framework used for creating functional tests which can simulate how users would interact with your application.&lt;br /&gt;
&lt;br /&gt;
== Test Plan ==&lt;br /&gt;
There are 8 features to be tested:&lt;br /&gt;
# Log in&lt;br /&gt;
# Add someone to a team &lt;br /&gt;
# Select a topic(if the assignment has topics)&lt;br /&gt;
# Select a submission to review For assignments with or without topics&lt;br /&gt;
# Bring up a review form&lt;br /&gt;
# Fill out &amp;amp; submit a review form&lt;br /&gt;
# View your scores&lt;br /&gt;
# Respond to a review (“author feedback”)&lt;br /&gt;
&lt;br /&gt;
=== Log in ===&lt;br /&gt;
we create a file called ‘student_signin_spec.rb’.  We define a method named login; and because we need this method in every later  feature test we will put this in the support directory.&lt;br /&gt;
* Scenario 1: Log in with ‘invalid combination of username and password’&lt;br /&gt;
When we sign in with correct name and password; we expect that there should be content ‘Invalid username/password’ appear in the new page.&lt;br /&gt;
* Scenario 2: Log in with ‘valid combination of username and password’&lt;br /&gt;
When we sign in with correct name and password; we expect that there should be content ‘User: (username)’ appear in the new page.&lt;br /&gt;
&lt;br /&gt;
Run test using the command &amp;quot;rspec spec/features/student_sign_in_spec.rb&amp;quot;&lt;br /&gt;
&lt;br /&gt;
=== Add someone to a team ===&lt;br /&gt;
* Scenario 1: Team member exceed max amount&lt;br /&gt;
# Sign in &lt;br /&gt;
# Click link certain assignment(in this test: Ethical analysis 2)&lt;br /&gt;
# Click link  “Your team” &lt;br /&gt;
# Fill in the text area with invitation receiver name&lt;br /&gt;
# Click send invitation button&lt;br /&gt;
# Sign out.&lt;br /&gt;
# Sign in as receiver&lt;br /&gt;
# Click link assignment&lt;br /&gt;
# Click link  “Your team”&lt;br /&gt;
# Click  button ‘accept’&lt;br /&gt;
&lt;br /&gt;
On this page, we expect the sender's name will appear.&lt;br /&gt;
&lt;br /&gt;
Run test using the command &amp;quot;rspec spec/features/add_member_spec.rb &amp;quot;&lt;br /&gt;
&lt;br /&gt;
=== Select a topic ===&lt;br /&gt;
Note: assignment has topics&lt;br /&gt;
&lt;br /&gt;
We need the following steps:&lt;br /&gt;
# sign in. &lt;br /&gt;
# click the link for assignment &lt;br /&gt;
# click link  “signup sheet”&lt;br /&gt;
# click the sign up for the remaining topic we want, as this user has already signed up for this topic, we should get the following message: Your topic(s): Self-plagiarism. &lt;br /&gt;
# sign out &lt;br /&gt;
Run test using the command &amp;quot;rspec spec/features/select_a_topic_spec.rb &amp;quot;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Select a submission to review ===&lt;br /&gt;
# sign in.  &lt;br /&gt;
# click the link for the assignment we want to review.&lt;br /&gt;
# click the link for “other’s work”&lt;br /&gt;
# click the link for the submission we want to review&lt;br /&gt;
# sign out &lt;br /&gt;
Run test using the command &amp;quot;rspec spec/features/select_a_submission_to_review_spec.rb &amp;quot;&lt;br /&gt;
&lt;br /&gt;
=== Bring up a review form ===&lt;br /&gt;
# sign in.  &lt;br /&gt;
# click the link for the assignment we want to review.&lt;br /&gt;
# click the link for “other’s work”&lt;br /&gt;
# click 'Begin'&lt;br /&gt;
# check that a review form has successfully been created&lt;br /&gt;
Run test using the command &amp;quot;rspec spec/features/bring_up_review_form_spec.rb &amp;quot;&lt;br /&gt;
&lt;br /&gt;
=== Fill out and submit a review form ===&lt;br /&gt;
# sign in.  &lt;br /&gt;
# click the link for the assignment we want to review.&lt;br /&gt;
# click the link for “other’s work”&lt;br /&gt;
# click 'Begin'&lt;br /&gt;
# fill out all text fields&lt;br /&gt;
# select all scores from dropdowns&lt;br /&gt;
# save form&lt;br /&gt;
# check for successful save&lt;br /&gt;
Run test using the command &amp;quot;rspec spec/features/fill_out_review_form_spec.rb &amp;quot;&lt;br /&gt;
&lt;br /&gt;
=== View your scores ===&lt;br /&gt;
* Scenario 1: No Scores available yet&lt;br /&gt;
# Sign in&lt;br /&gt;
# Click link for Assignment&lt;br /&gt;
# Click ‘Your scores’&lt;br /&gt;
# Check that nothing exists yet&lt;br /&gt;
# Check for dashes.&lt;br /&gt;
* Scenario 2: Scores available.&lt;br /&gt;
# Sign in&lt;br /&gt;
# Click link for Assignment&lt;br /&gt;
# Click ‘Your scores’&lt;br /&gt;
# Check that displayed scores match scores independently calculated from all reviews.&lt;br /&gt;
To run this test run: $ rspec spec/features/student_view_score.rb&lt;br /&gt;
&lt;br /&gt;
=== Respond to a review (“author feedback”) ===&lt;br /&gt;
# Sign in as author&lt;br /&gt;
# Click link for Assignment&lt;br /&gt;
# Click ‘Your scores’&lt;br /&gt;
# Click ‘show reviews’&lt;br /&gt;
# Click ‘Give feedback’&lt;br /&gt;
# Fill out Feedback form&lt;br /&gt;
# Click Save Feedback&lt;br /&gt;
# Check for confirmation that the feedback was saved&lt;br /&gt;
To run this test run:$ rspec spec/features/review_feedback.rb&lt;br /&gt;
&lt;br /&gt;
==Links==&lt;br /&gt;
*Github repository:  https://github.com/xhy279/expertiza/tree/fall2015/spec/features&lt;br /&gt;
*Pull requests link: https://github.com/expertiza/expertiza/pull/640 &lt;br /&gt;
*Demo videos(4 in total): &amp;lt;br&amp;gt;&lt;br /&gt;
1. https://drive.google.com/open?id=0B3EOsci5DEveMGZOdVNIazJlNVE &amp;lt;br&amp;gt;&lt;br /&gt;
2. https://drive.google.com/a/ncsu.edu/file/d/0B-l-xu44qiJUZDRFMU02U09kZWs/view?usp=sharing &amp;lt;br&amp;gt;&lt;br /&gt;
3. https://drive.google.com/a/ncsu.edu/file/d/0B80MLsKsoSOmaVV5Tm1mQWIwb0U/view?usp=sharing &amp;lt;br&amp;gt; &lt;br /&gt;
4. https://drive.google.com/a/ncsu.edu/file/d/0B7dSj1bvwNp9X29TTHJMVFhPWkE/view?usp=sharing &amp;lt;br&amp;gt;&lt;br /&gt;
Note: There is a problem at the end of the third video and the save can not complete because of a time out issue. This does not effect the test, just the ability to demonstrate the test.&lt;/div&gt;</summary>
		<author><name>Cnbrown4</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2015_E1581_Integration_testing_for_student_interface&amp;diff=100298</id>
		<title>CSC/ECE 517 Fall 2015 E1581 Integration testing for student interface</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2015_E1581_Integration_testing_for_student_interface&amp;diff=100298"/>
		<updated>2015-12-05T04:27:22Z</updated>

		<summary type="html">&lt;p&gt;Cnbrown4: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Create integration tests for the student interface using capybara and rspec. Integration testing is the phase in software testing in which individual software modules are combined and tested as a group. It occurs after unit testing and before validation testing. Integration testing takes as its input modules that have been unit tested, groups them in larger aggregates, applies tests defined in an integration test plan to those aggregates, and delivers as its output the integrated system ready for system testing.&lt;br /&gt;
&lt;br /&gt;
== Design ==&lt;br /&gt;
To properly execute the integration tests we will write the test cases to mimic a user operating the system. We will create strong integration test cases to help ensure the outcome of application's student interface remains the same regardless of changes to its inner functionality. In an attempt to keep our tests DRY we will put common code in a support directory.&lt;br /&gt;
&lt;br /&gt;
== Testing tools ==&lt;br /&gt;
'''RSpec''' is a behavior-driven development (BDD) framework for the Ruby (programming language)|Ruby programming language, inspired by JBehave. It contains its own mocking framework that is fully integrated into the framework based upon JMock.&lt;br /&gt;
&lt;br /&gt;
'''Capybara''' is a web-based automation framework used for creating functional tests which can simulate how users would interact with your application.&lt;br /&gt;
&lt;br /&gt;
== Test Plan ==&lt;br /&gt;
There are 8 features to be tested:&lt;br /&gt;
# Log in&lt;br /&gt;
# Add someone to a team &lt;br /&gt;
# Select a topic(if the assignment has topics)&lt;br /&gt;
# Select a submission to review For assignments with or without topics&lt;br /&gt;
# Bring up a review form&lt;br /&gt;
# Fill out &amp;amp; submit a review form&lt;br /&gt;
# View your scores&lt;br /&gt;
# Respond to a review (“author feedback”)&lt;br /&gt;
&lt;br /&gt;
=== Log in ===&lt;br /&gt;
we create a file called ‘student_signin_spec.rb’.  We define a method named login; and because we need this method in every later  feature test we will put this in the support directory.&lt;br /&gt;
* Scenario 1: Log in with ‘invalid combination of username and password’&lt;br /&gt;
When we sign in with correct name and password; we expect that there should be content ‘Invalid username/password’ appear in the new page.&lt;br /&gt;
* Scenario 2: Log in with ‘valid combination of username and password’&lt;br /&gt;
When we sign in with correct name and password; we expect that there should be content ‘User: (username)’ appear in the new page.&lt;br /&gt;
&lt;br /&gt;
==== We have test file &amp;quot;student_sign_in.rb&amp;quot; do this task. Run test using command &amp;quot; rspec spec/features/student_sign_in_spec.rb&amp;quot;====&lt;br /&gt;
&lt;br /&gt;
=== Add someone to a team ===&lt;br /&gt;
* Scenario 1: Team member exceed max amount&lt;br /&gt;
# Sign in &lt;br /&gt;
# Click link certain assignment(in this test: Ethical analysis 2)&lt;br /&gt;
# Click link  “Your team” &lt;br /&gt;
# Fill in the text area with invitation receiver name&lt;br /&gt;
# Click send invitation button&lt;br /&gt;
# Sign out.&lt;br /&gt;
# Sign in as receiver&lt;br /&gt;
# Click link assignment&lt;br /&gt;
# Click link  “Your team”&lt;br /&gt;
# Click  button ‘accept’&lt;br /&gt;
&lt;br /&gt;
On this page, we expect the sender's name will appear.&lt;br /&gt;
&lt;br /&gt;
====We have &amp;quot;add_member_spec.rb&amp;quot; to do this task. Run test using the command &amp;quot;rspec spec/features/add_member_spec.rb &amp;quot;====&lt;br /&gt;
&lt;br /&gt;
=== Select a topic ===&lt;br /&gt;
Note: assignment has topics&lt;br /&gt;
&lt;br /&gt;
We need the following steps:&lt;br /&gt;
# sign in. &lt;br /&gt;
# click the link for assignment &lt;br /&gt;
# click link  “signup sheet”&lt;br /&gt;
# click the sign up for the remaining topic we want, as this user has already signed up for this topic, we should get the following message: Your topic(s): Self-plagiarism. &lt;br /&gt;
# sign out &lt;br /&gt;
Run test using the command &amp;quot;rspec spec/features/select_a_topic_spec.rb &amp;quot;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Select a submission to review ===&lt;br /&gt;
# sign in.  &lt;br /&gt;
# click the link for the assignment we want to review.&lt;br /&gt;
# click the link for “other’s work”&lt;br /&gt;
# click the link for the submission we want to review&lt;br /&gt;
# sign out &lt;br /&gt;
Run test using the command &amp;quot;rspec spec/features/select_a_submission_to_review_spec.rb &amp;quot;&lt;br /&gt;
&lt;br /&gt;
=== Bring up a review form ===&lt;br /&gt;
# sign in.  &lt;br /&gt;
# click the link for the assignment we want to review.&lt;br /&gt;
# click the link for “other’s work”&lt;br /&gt;
# click 'Begin'&lt;br /&gt;
# check that a review form has successfully been created&lt;br /&gt;
Run test using the command &amp;quot;rspec spec/features/bring_up_review_form_spec.rb &amp;quot;&lt;br /&gt;
&lt;br /&gt;
=== Fill out and submit a review form ===&lt;br /&gt;
# sign in.  &lt;br /&gt;
# click the link for the assignment we want to review.&lt;br /&gt;
# click the link for “other’s work”&lt;br /&gt;
# click 'Begin'&lt;br /&gt;
# fill out all text fields&lt;br /&gt;
# select all scores from dropdowns&lt;br /&gt;
# save form&lt;br /&gt;
# check for successful save&lt;br /&gt;
Run test using the command &amp;quot;rspec spec/features/fill_out_review_form_spec.rb &amp;quot;&lt;br /&gt;
&lt;br /&gt;
=== View your scores ===&lt;br /&gt;
* Scenario 1: No Scores available yet&lt;br /&gt;
# Sign in&lt;br /&gt;
# Click link for Assignment&lt;br /&gt;
# Click ‘Your scores’&lt;br /&gt;
# Check that nothing exists yet&lt;br /&gt;
# Check for dashes.&lt;br /&gt;
* Scenario 2: Scores available.&lt;br /&gt;
# Sign in&lt;br /&gt;
# Click link for Assignment&lt;br /&gt;
# Click ‘Your scores’&lt;br /&gt;
# Check that displayed scores match scores independently calculated from all reviews.&lt;br /&gt;
To run this test run: $ rspec spec/features/student_view_score.rb&lt;br /&gt;
&lt;br /&gt;
=== Respond to a review (“author feedback”) ===&lt;br /&gt;
# Sign in as author&lt;br /&gt;
# Click link for Assignment&lt;br /&gt;
# Click ‘Your scores’&lt;br /&gt;
# Click ‘show reviews’&lt;br /&gt;
# Click ‘Give feedback’&lt;br /&gt;
# Fill out Feedback form&lt;br /&gt;
# Click Save Feedback&lt;br /&gt;
# Check for confirmation that the feedback was saved&lt;br /&gt;
To run this test run:$ rspec spec/features/review_feedback.rb&lt;br /&gt;
&lt;br /&gt;
==Links==&lt;br /&gt;
*Github repository:  https://github.com/xhy279/expertiza/tree/fall2015/spec/features&lt;br /&gt;
*Demo videos(4 in total): &amp;lt;br&amp;gt;&lt;br /&gt;
1. https://drive.google.com/open?id=0B3EOsci5DEveMGZOdVNIazJlNVE &amp;lt;br&amp;gt;&lt;br /&gt;
2. https://drive.google.com/a/ncsu.edu/file/d/0B-l-xu44qiJUZDRFMU02U09kZWs/view?usp=sharing &amp;lt;br&amp;gt;&lt;br /&gt;
3. https://drive.google.com/a/ncsu.edu/file/d/0B80MLsKsoSOmWFdvYThJZzdCVVE/view?usp=sharing &amp;lt;br&amp;gt; &lt;br /&gt;
4. https://drive.google.com/a/ncsu.edu/file/d/0B7dSj1bvwNp9X29TTHJMVFhPWkE/view?usp=sharing &amp;lt;br&amp;gt;&lt;br /&gt;
Note: There is a problem at the end of the third video and the save can not complete because of a time out issue. This does not effect the test, just the ability to demonstrate the test.&lt;/div&gt;</summary>
		<author><name>Cnbrown4</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2015_E1581_Integration_testing_for_student_interface&amp;diff=100293</id>
		<title>CSC/ECE 517 Fall 2015 E1581 Integration testing for student interface</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2015_E1581_Integration_testing_for_student_interface&amp;diff=100293"/>
		<updated>2015-12-05T04:21:40Z</updated>

		<summary type="html">&lt;p&gt;Cnbrown4: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Create integration tests for the student interface using capybara and rspec. Integration testing is the phase in software testing in which individual software modules are combined and tested as a group. It occurs after unit testing and before validation testing. Integration testing takes as its input modules that have been unit tested, groups them in larger aggregates, applies tests defined in an integration test plan to those aggregates, and delivers as its output the integrated system ready for system testing.&lt;br /&gt;
&lt;br /&gt;
== Design ==&lt;br /&gt;
To properly execute the integration tests we will write the test cases to mimic a user operating the system. We will create strong integration test cases to help ensure the outcome of application's student interface remains the same regardless of changes to its inner functionality. In an attempt to keep our tests DRY we will put common code in a support directory.&lt;br /&gt;
&lt;br /&gt;
== Testing tools ==&lt;br /&gt;
'''RSpec''' is a behavior-driven development (BDD) framework for the Ruby (programming language)|Ruby programming language, inspired by JBehave. It contains its own mocking framework that is fully integrated into the framework based upon JMock.&lt;br /&gt;
&lt;br /&gt;
'''Capybara''' is a web-based automation framework used for creating functional tests which can simulate how users would interact with your application.&lt;br /&gt;
&lt;br /&gt;
== Test Plan ==&lt;br /&gt;
There are 8 features to be tested:&lt;br /&gt;
# Log in&lt;br /&gt;
# Add someone to a team &lt;br /&gt;
# Select a topic(if the assignment has topics)&lt;br /&gt;
# Select a submission to review For assignments with or without topics&lt;br /&gt;
# Bring up a review form&lt;br /&gt;
# Fill out &amp;amp; submit a review form&lt;br /&gt;
# View your scores&lt;br /&gt;
# Respond to a review (“author feedback”)&lt;br /&gt;
&lt;br /&gt;
=== Log in ===&lt;br /&gt;
we create a file called ‘student_signin_spec.rb’.  We define a method named login; and because we need this method in every later  feature test we will put this in the support directory.&lt;br /&gt;
* Scenario 1: Log in with ‘invalid combination of username and password’&lt;br /&gt;
When we sign in with correct name and password; we expect that there should be content ‘Invalid username/password’ appear in the new page.&lt;br /&gt;
* Scenario 2: Log in with ‘valid combination of username and password’&lt;br /&gt;
When we sign in with correct name and password; we expect that there should be content ‘User: (username)’ appear in the new page.&lt;br /&gt;
&lt;br /&gt;
==== We have test file &amp;quot;student_sign_in.rb&amp;quot; do this task. Run test using command &amp;quot; rspec spec/features/student_sign_in_spec.rb&amp;quot;====&lt;br /&gt;
&lt;br /&gt;
=== Add someone to a team ===&lt;br /&gt;
* Scenario 1: Team member exceed max amount&lt;br /&gt;
# Sign in &lt;br /&gt;
# Click link certain assignment(in this test: Ethical analysis 2)&lt;br /&gt;
# Click link  “Your team” &lt;br /&gt;
# Fill in the text area with invitation receiver name&lt;br /&gt;
# Click send invitation button&lt;br /&gt;
# Sign out.&lt;br /&gt;
# Sign in as receiver&lt;br /&gt;
# Click link assignment&lt;br /&gt;
# Click link  “Your team”&lt;br /&gt;
# Click  button ‘accept’&lt;br /&gt;
&lt;br /&gt;
On this page, we expect the sender's name will appear.&lt;br /&gt;
&lt;br /&gt;
====We have &amp;quot;add_member_spec.rb&amp;quot; to do this task. Run test using the command &amp;quot;rspec spec/features/add_member_spec.rb &amp;quot;====&lt;br /&gt;
&lt;br /&gt;
=== Select a topic ===&lt;br /&gt;
Note: assignment has topics&lt;br /&gt;
&lt;br /&gt;
We need the following steps:&lt;br /&gt;
# sign in. &lt;br /&gt;
# click the link for assignment &lt;br /&gt;
# click link  “signup sheet”&lt;br /&gt;
# click the sign up for the remaining topic we want, as this user has already signed up for this topic, we should get the following message: Your topic(s): Self-plagiarism. &lt;br /&gt;
# sign out &lt;br /&gt;
Run test using the command &amp;quot;rspec spec/features/select_a_topic_spec.rb &amp;quot;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Select a submission to review ===&lt;br /&gt;
# sign in.  &lt;br /&gt;
# click the link for the assignment we want to review.&lt;br /&gt;
# click the link for “other’s work”&lt;br /&gt;
# click the link for the submission we want to review&lt;br /&gt;
# sign out &lt;br /&gt;
Run test using the command &amp;quot;rspec spec/features/select_a_submission_to_review_spec.rb &amp;quot;&lt;br /&gt;
&lt;br /&gt;
=== Bring up a review form ===&lt;br /&gt;
# sign in.  &lt;br /&gt;
# click the link for the assignment we want to review.&lt;br /&gt;
# click the link for “other’s work”&lt;br /&gt;
# click 'Begin'&lt;br /&gt;
# check that a review form has successfully been created&lt;br /&gt;
Run test using the command &amp;quot;rspec spec/features/bring_up_review_form_spec.rb &amp;quot;&lt;br /&gt;
&lt;br /&gt;
=== Fill out and submit a review form ===&lt;br /&gt;
# sign in.  &lt;br /&gt;
# click the link for the assignment we want to review.&lt;br /&gt;
# click the link for “other’s work”&lt;br /&gt;
# open a review form&lt;br /&gt;
# fill out all text fields&lt;br /&gt;
# select all scores from dropdowns&lt;br /&gt;
# submit form&lt;br /&gt;
# check for successful save&lt;br /&gt;
Run test using the command &amp;quot;rspec spec/features/fill_out_review_form_spec.rb &amp;quot;&lt;br /&gt;
&lt;br /&gt;
=== View your scores ===&lt;br /&gt;
* Scenario 1: No Scores available yet&lt;br /&gt;
# Sign in&lt;br /&gt;
# Click link for Assignment&lt;br /&gt;
# Click ‘Your scores’&lt;br /&gt;
# Check that nothing exists yet&lt;br /&gt;
# Check for dashes.&lt;br /&gt;
* Scenario 2: Scores available.&lt;br /&gt;
# Sign in&lt;br /&gt;
# Click link for Assignment&lt;br /&gt;
# Click ‘Your scores’&lt;br /&gt;
# Check that displayed scores match scores independently calculated from all reviews.&lt;br /&gt;
To run this test run: $ rspec spec/features/student_view_score.rb&lt;br /&gt;
&lt;br /&gt;
=== Respond to a review (“author feedback”) ===&lt;br /&gt;
# Sign in as author&lt;br /&gt;
# Click link for Assignment&lt;br /&gt;
# Click ‘Your scores’&lt;br /&gt;
# Click ‘show reviews’&lt;br /&gt;
# Click ‘Give feedback’&lt;br /&gt;
# Fill out Feedback form&lt;br /&gt;
# Click Save Feedback&lt;br /&gt;
# Check for confirmation that the feedback was saved&lt;br /&gt;
To run this test run:$ rspec spec/features/review_feedback.rb&lt;br /&gt;
&lt;br /&gt;
==Links==&lt;br /&gt;
*Github repository:  https://github.com/xhy279/expertiza/tree/fall2015/spec/features&lt;br /&gt;
*Demo videos(4 in total): &amp;lt;br&amp;gt;&lt;br /&gt;
1. https://drive.google.com/open?id=0B3EOsci5DEveMGZOdVNIazJlNVE &amp;lt;br&amp;gt;&lt;br /&gt;
2. https://drive.google.com/a/ncsu.edu/file/d/0B-l-xu44qiJUZDRFMU02U09kZWs/view?usp=sharing &amp;lt;br&amp;gt;&lt;br /&gt;
3. https://drive.google.com/a/ncsu.edu/file/d/0B80MLsKsoSOmWFdvYThJZzdCVVE/view?usp=sharing &amp;lt;br&amp;gt; &lt;br /&gt;
4. https://drive.google.com/a/ncsu.edu/file/d/0B7dSj1bvwNp9X29TTHJMVFhPWkE/view?usp=sharing &amp;lt;br&amp;gt;&lt;br /&gt;
Note: There is a problem at the end of the third video and the save can not complete because of a time out issue. This does not effect the test, just the ability to demonstrate the test.&lt;/div&gt;</summary>
		<author><name>Cnbrown4</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2015_E1581_Integration_testing_for_student_interface&amp;diff=100292</id>
		<title>CSC/ECE 517 Fall 2015 E1581 Integration testing for student interface</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2015_E1581_Integration_testing_for_student_interface&amp;diff=100292"/>
		<updated>2015-12-05T04:20:26Z</updated>

		<summary type="html">&lt;p&gt;Cnbrown4: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Create integration tests for the student interface using capybara and rspec. Integration testing is the phase in software testing in which individual software modules are combined and tested as a group. It occurs after unit testing and before validation testing. Integration testing takes as its input modules that have been unit tested, groups them in larger aggregates, applies tests defined in an integration test plan to those aggregates, and delivers as its output the integrated system ready for system testing.&lt;br /&gt;
&lt;br /&gt;
== Design ==&lt;br /&gt;
To properly execute the integration tests we will write the test cases to mimic a user operating the system. We will create strong integration test cases to help ensure the outcome of application's student interface remains the same regardless of changes to its inner functionality. In an attempt to keep our tests DRY we will put common code in a support directory.&lt;br /&gt;
&lt;br /&gt;
== Testing tools ==&lt;br /&gt;
'''RSpec''' is a behavior-driven development (BDD) framework for the Ruby (programming language)|Ruby programming language, inspired by JBehave. It contains its own mocking framework that is fully integrated into the framework based upon JMock.&lt;br /&gt;
&lt;br /&gt;
'''Capybara''' is a web-based automation framework used for creating functional tests which can simulate how users would interact with your application.&lt;br /&gt;
&lt;br /&gt;
== Test Plan ==&lt;br /&gt;
There are 8 features to be tested:&lt;br /&gt;
# Log in&lt;br /&gt;
# Add someone to a team &lt;br /&gt;
# Select a topic(if the assignment has topics)&lt;br /&gt;
# Select a submission to review For assignments with or without topics&lt;br /&gt;
# Bring up a review form&lt;br /&gt;
# Fill out &amp;amp; submit a review form&lt;br /&gt;
# View your scores&lt;br /&gt;
# Respond to a review (“author feedback”)&lt;br /&gt;
&lt;br /&gt;
=== Log in ===&lt;br /&gt;
we create a file called ‘student_signin_spec.rb’.  We define a method named login; and because we need this method in every later  feature test we will put this in the support directory.&lt;br /&gt;
* Scenario 1: Log in with ‘invalid combination of username and password’&lt;br /&gt;
When we sign in with correct name and password; we expect that there should be content ‘Invalid username/password’ appear in the new page.&lt;br /&gt;
* Scenario 2: Log in with ‘valid combination of username and password’&lt;br /&gt;
When we sign in with correct name and password; we expect that there should be content ‘User: (username)’ appear in the new page.&lt;br /&gt;
&lt;br /&gt;
==== We have test file &amp;quot;student_sign_in.rb&amp;quot; do this task. Run test using command &amp;quot; rspec spec/features/student_sign_in_spec.rb&amp;quot;====&lt;br /&gt;
&lt;br /&gt;
=== Add someone to a team ===&lt;br /&gt;
* Scenario 1: Team member exceed max amount&lt;br /&gt;
# Sign in &lt;br /&gt;
# Click link certain assignment(in this test: Ethical analysis 2)&lt;br /&gt;
# Click link  “Your team” &lt;br /&gt;
# Fill in the text area with invitation receiver name&lt;br /&gt;
# Click send invitation button&lt;br /&gt;
# Sign out.&lt;br /&gt;
# Sign in as receiver&lt;br /&gt;
# Click link assignment&lt;br /&gt;
# Click link  “Your team”&lt;br /&gt;
# Click  button ‘accept’&lt;br /&gt;
&lt;br /&gt;
On this page, we expect the sender's name will appear.&lt;br /&gt;
&lt;br /&gt;
====We have &amp;quot;add_member_spec.rb&amp;quot; to do this task. Run test using the command &amp;quot;rspec spec/features/add_member_spec.rb &amp;quot;====&lt;br /&gt;
&lt;br /&gt;
=== Select a topic ===&lt;br /&gt;
Note: assignment has topics&lt;br /&gt;
&lt;br /&gt;
We need the following steps:&lt;br /&gt;
# sign in. &lt;br /&gt;
# click the link for assignment &lt;br /&gt;
# click link  “signup sheet”&lt;br /&gt;
# click the sign up for the remaining topic we want, as this user has already signed up for this topic, we should get the following message: Your topic(s): Self-plagiarism. &lt;br /&gt;
# sign out &lt;br /&gt;
Run test using the command &amp;quot;rspec spec/features/select_a_topic_spec.rb &amp;quot;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Select a submission to review ===&lt;br /&gt;
# sign in.  &lt;br /&gt;
# click the link for the assignment we want to review.&lt;br /&gt;
# click the link for “other’s work”&lt;br /&gt;
# click the link for the submission we want to review&lt;br /&gt;
# sign out &lt;br /&gt;
Run test using the command &amp;quot;rspec spec/features/select_a_submission_to_review_spec.rb &amp;quot;&lt;br /&gt;
&lt;br /&gt;
=== Bring up a review form ===&lt;br /&gt;
# sign in.  &lt;br /&gt;
# click the link for the assignment we want to review.&lt;br /&gt;
# click the link for “other’s work”&lt;br /&gt;
# click 'Begin'&lt;br /&gt;
# check that a review form has successfully been created&lt;br /&gt;
Run test using the command &amp;quot;rspec spec/features/bring_up_review_form_spec.rb &amp;quot;&lt;br /&gt;
&lt;br /&gt;
=== Fill out and submit a review form ===&lt;br /&gt;
# sign in.  &lt;br /&gt;
# click the link for the assignment we want to review.&lt;br /&gt;
# click the link for “other’s work”&lt;br /&gt;
# open a review form&lt;br /&gt;
# fill out all text fields&lt;br /&gt;
# select all scores from dropdowns&lt;br /&gt;
# submit form&lt;br /&gt;
# check for successful save&lt;br /&gt;
Run test using the command &amp;quot;rspec spec/features/fill_out_review_form_spec.rb &amp;quot;&lt;br /&gt;
&lt;br /&gt;
=== View your scores ===&lt;br /&gt;
* Scenario 1: No Scores available yet&lt;br /&gt;
# Sign in&lt;br /&gt;
# Click link for Assignment&lt;br /&gt;
# Click ‘Your scores’&lt;br /&gt;
# Check that nothing exists yet&lt;br /&gt;
# Check for dashes.&lt;br /&gt;
* Scenario 2: Scores available.&lt;br /&gt;
# Sign in&lt;br /&gt;
# Click link for Assignment&lt;br /&gt;
# Click ‘Your scores’&lt;br /&gt;
# Check that displayed scores match scores independently calculated from all reviews.&lt;br /&gt;
To run this test run: $ rspec spec/features/student_view_score.rb&lt;br /&gt;
&lt;br /&gt;
=== Respond to a review (“author feedback”) ===&lt;br /&gt;
# Sign in as author&lt;br /&gt;
# Click link for Assignment&lt;br /&gt;
# Click ‘Your scores’&lt;br /&gt;
# Click ‘show reviews’&lt;br /&gt;
# Click ‘Give feedback’&lt;br /&gt;
# Fill out Feedback form&lt;br /&gt;
# Click Save Feedback&lt;br /&gt;
# Check for confirmation that the feedback was saved&lt;br /&gt;
To run this test run:$ rspec spec/features/review_feedback.rb&lt;br /&gt;
&lt;br /&gt;
==Links==&lt;br /&gt;
*Github repository:  https://github.com/xhy279/expertiza/tree/fall2015/spec/features&lt;br /&gt;
*Demo videos(4 in total): &amp;lt;br&amp;gt;&lt;br /&gt;
1. https://drive.google.com/open?id=0B3EOsci5DEveMGZOdVNIazJlNVE &amp;lt;br&amp;gt;&lt;br /&gt;
2. https://drive.google.com/a/ncsu.edu/file/d/0B-l-xu44qiJUZDRFMU02U09kZWs/view?usp=sharing &amp;lt;br&amp;gt;&lt;br /&gt;
3. https://drive.google.com/a/ncsu.edu/file/d/0B80MLsKsoSOmWFdvYThJZzdCVVE/view?usp=sharing &amp;lt;br&amp;gt;&lt;br /&gt;
   Note: There is a problem at the end of the video and the save can not complete because of a time out issue.  &lt;br /&gt;
4. https://drive.google.com/a/ncsu.edu/file/d/0B7dSj1bvwNp9X29TTHJMVFhPWkE/view?usp=sharing &amp;lt;br&amp;gt;&lt;/div&gt;</summary>
		<author><name>Cnbrown4</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2015_E1581_Integration_testing_for_student_interface&amp;diff=100289</id>
		<title>CSC/ECE 517 Fall 2015 E1581 Integration testing for student interface</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2015_E1581_Integration_testing_for_student_interface&amp;diff=100289"/>
		<updated>2015-12-05T04:18:42Z</updated>

		<summary type="html">&lt;p&gt;Cnbrown4: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Create integration tests for the student interface using capybara and rspec. Integration testing is the phase in software testing in which individual software modules are combined and tested as a group. It occurs after unit testing and before validation testing. Integration testing takes as its input modules that have been unit tested, groups them in larger aggregates, applies tests defined in an integration test plan to those aggregates, and delivers as its output the integrated system ready for system testing.&lt;br /&gt;
&lt;br /&gt;
== Design ==&lt;br /&gt;
To properly execute the integration tests we will write the test cases to mimic a user operating the system. We will create strong integration test cases to help ensure the outcome of application's student interface remains the same regardless of changes to its inner functionality. In an attempt to keep our tests DRY we will put common code in a support directory.&lt;br /&gt;
&lt;br /&gt;
== Testing tools ==&lt;br /&gt;
'''RSpec''' is a behavior-driven development (BDD) framework for the Ruby (programming language)|Ruby programming language, inspired by JBehave. It contains its own mocking framework that is fully integrated into the framework based upon JMock.&lt;br /&gt;
&lt;br /&gt;
'''Capybara''' is a web-based automation framework used for creating functional tests which can simulate how users would interact with your application.&lt;br /&gt;
&lt;br /&gt;
== Test Plan ==&lt;br /&gt;
There are 8 features to be tested:&lt;br /&gt;
# Log in&lt;br /&gt;
# Add someone to a team &lt;br /&gt;
# Select a topic(if the assignment has topics)&lt;br /&gt;
# Select a submission to review For assignments with or without topics&lt;br /&gt;
# Bring up a review form&lt;br /&gt;
# Fill out &amp;amp; submit a review form&lt;br /&gt;
# View your scores&lt;br /&gt;
# Respond to a review (“author feedback”)&lt;br /&gt;
&lt;br /&gt;
=== Log in ===&lt;br /&gt;
we create a file called ‘student_signin_spec.rb’.  We define a method named login; and because we need this method in every later  feature test we will put this in the support directory.&lt;br /&gt;
* Scenario 1: Log in with ‘invalid combination of username and password’&lt;br /&gt;
When we sign in with correct name and password; we expect that there should be content ‘Invalid username/password’ appear in the new page.&lt;br /&gt;
* Scenario 2: Log in with ‘valid combination of username and password’&lt;br /&gt;
When we sign in with correct name and password; we expect that there should be content ‘User: (username)’ appear in the new page.&lt;br /&gt;
&lt;br /&gt;
==== We have test file &amp;quot;student_sign_in.rb&amp;quot; do this task. Run test using command &amp;quot; rspec spec/features/student_sign_in_spec.rb&amp;quot;====&lt;br /&gt;
&lt;br /&gt;
=== Add someone to a team ===&lt;br /&gt;
* Scenario 1: Team member exceed max amount&lt;br /&gt;
# Sign in &lt;br /&gt;
# Click link certain assignment(in this test: Ethical analysis 2)&lt;br /&gt;
# Click link  “Your team” &lt;br /&gt;
# Fill in the text area with invitation receiver name&lt;br /&gt;
# Click send invitation button&lt;br /&gt;
# Sign out.&lt;br /&gt;
# Sign in as receiver&lt;br /&gt;
# Click link assignment&lt;br /&gt;
# Click link  “Your team”&lt;br /&gt;
# Click  button ‘accept’&lt;br /&gt;
&lt;br /&gt;
On this page, we expect the sender's name will appear.&lt;br /&gt;
&lt;br /&gt;
====We have &amp;quot;add_member_spec.rb&amp;quot; to do this task. Run test using the command &amp;quot;rspec spec/features/add_member_spec.rb &amp;quot;====&lt;br /&gt;
&lt;br /&gt;
=== Select a topic ===&lt;br /&gt;
Note: assignment has topics&lt;br /&gt;
&lt;br /&gt;
We need the following steps:&lt;br /&gt;
# sign in. &lt;br /&gt;
# click the link for assignment &lt;br /&gt;
# click link  “signup sheet”&lt;br /&gt;
# click the sign up for the remaining topic we want, as this user has already signed up for this topic, we should get the following message: Your topic(s): Self-plagiarism. &lt;br /&gt;
# sign out &lt;br /&gt;
Run test using the command &amp;quot;rspec spec/features/select_a_topic_spec.rb &amp;quot;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Select a submission to review ===&lt;br /&gt;
# sign in.  &lt;br /&gt;
# click the link for the assignment we want to review.&lt;br /&gt;
# click the link for “other’s work”&lt;br /&gt;
# click the link for the submission we want to review&lt;br /&gt;
# sign out &lt;br /&gt;
Run test using the command &amp;quot;rspec spec/features/select_a_submission_to_review_spec.rb &amp;quot;&lt;br /&gt;
&lt;br /&gt;
=== Bring up a review form ===&lt;br /&gt;
# sign in.  &lt;br /&gt;
# click the link for the assignment we want to review.&lt;br /&gt;
# click the link for “other’s work”&lt;br /&gt;
# click 'Begin'&lt;br /&gt;
# check that a review form has successfully been created&lt;br /&gt;
Run test using the command &amp;quot;rspec spec/features/bring_up_review_form_spec.rb &amp;quot;&lt;br /&gt;
&lt;br /&gt;
=== Fill out and submit a review form ===&lt;br /&gt;
# sign in.  &lt;br /&gt;
# click the link for the assignment we want to review.&lt;br /&gt;
# click the link for “other’s work”&lt;br /&gt;
# open a review form&lt;br /&gt;
# fill out all text fields&lt;br /&gt;
# select all scores from dropdowns&lt;br /&gt;
# submit form&lt;br /&gt;
# check for successful save&lt;br /&gt;
Run test using the command &amp;quot;rspec spec/features/fill_out_review_form_spec.rb &amp;quot;&lt;br /&gt;
&lt;br /&gt;
=== View your scores ===&lt;br /&gt;
* Scenario 1: No Scores available yet&lt;br /&gt;
# Sign in&lt;br /&gt;
# Click link for Assignment&lt;br /&gt;
# Click ‘Your scores’&lt;br /&gt;
# Check that nothing exists yet&lt;br /&gt;
# Check for dashes.&lt;br /&gt;
* Scenario 2: Scores available.&lt;br /&gt;
# Sign in&lt;br /&gt;
# Click link for Assignment&lt;br /&gt;
# Click ‘Your scores’&lt;br /&gt;
# Check that displayed scores match scores independently calculated from all reviews.&lt;br /&gt;
To run this test run: $ rspec spec/features/student_view_score.rb&lt;br /&gt;
&lt;br /&gt;
=== Respond to a review (“author feedback”) ===&lt;br /&gt;
# Sign in as author&lt;br /&gt;
# Click link for Assignment&lt;br /&gt;
# Click ‘Your scores’&lt;br /&gt;
# Click ‘show reviews’&lt;br /&gt;
# Click ‘Give feedback’&lt;br /&gt;
# Fill out Feedback form&lt;br /&gt;
# Click Save Feedback&lt;br /&gt;
# Check for confirmation that the feedback was saved&lt;br /&gt;
To run this test run:$ rspec spec/features/review_feedback.rb&lt;br /&gt;
&lt;br /&gt;
==Links==&lt;br /&gt;
*Github repository:  https://github.com/xhy279/expertiza/tree/fall2015/spec/features&lt;br /&gt;
*Demo videos(4 in total): &amp;lt;br&amp;gt;&lt;br /&gt;
1. https://drive.google.com/open?id=0B3EOsci5DEveMGZOdVNIazJlNVE &amp;lt;br&amp;gt;&lt;br /&gt;
2. https://drive.google.com/a/ncsu.edu/file/d/0B-l-xu44qiJUZDRFMU02U09kZWs/view?usp=sharing &amp;lt;br&amp;gt;&lt;br /&gt;
3. https://drive.google.com/a/ncsu.edu/file/d/0B80MLsKsoSOmWFdvYThJZzdCVVE/view?usp=sharing &amp;lt;br&amp;gt;&lt;br /&gt;
4. https://drive.google.com/a/ncsu.edu/file/d/0B7dSj1bvwNp9X29TTHJMVFhPWkE/view?usp=sharing &amp;lt;br&amp;gt;&lt;/div&gt;</summary>
		<author><name>Cnbrown4</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2015_E1581_Integration_testing_for_student_interface&amp;diff=100268</id>
		<title>CSC/ECE 517 Fall 2015 E1581 Integration testing for student interface</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2015_E1581_Integration_testing_for_student_interface&amp;diff=100268"/>
		<updated>2015-12-05T03:29:28Z</updated>

		<summary type="html">&lt;p&gt;Cnbrown4: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Create integration tests for the student interface using capybara and rspec. Integration testing is the phase in software testing in which individual software modules are combined and tested as a group. It occurs after unit testing and before validation testing. Integration testing takes as its input modules that have been unit tested, groups them in larger aggregates, applies tests defined in an integration test plan to those aggregates, and delivers as its output the integrated system ready for system testing.&lt;br /&gt;
&lt;br /&gt;
== Design ==&lt;br /&gt;
To properly execute the integration tests we will write the test cases to mimic a user operating the system. We will create strong integration test cases to help ensure the outcome of application's student interface remains the same regardless of changes to its inner functionality. In an attempt to keep our tests DRY we will put common code in a support directory.&lt;br /&gt;
&lt;br /&gt;
== Testing tools ==&lt;br /&gt;
'''RSpec''' is a behavior-driven development (BDD) framework for the Ruby (programming language)|Ruby programming language, inspired by JBehave. It contains its own mocking framework that is fully integrated into the framework based upon JMock.&lt;br /&gt;
&lt;br /&gt;
'''Capybara''' is a web-based automation framework used for creating functional tests which can simulate how users would interact with your application.&lt;br /&gt;
&lt;br /&gt;
== Test Plan ==&lt;br /&gt;
There are 8 features to be tested:&lt;br /&gt;
# Log in&lt;br /&gt;
# Add someone to a team &lt;br /&gt;
# Select a topic(if the assignment has topics)&lt;br /&gt;
# Select a submission to review For assignments with or without topics&lt;br /&gt;
# Bring up a review form&lt;br /&gt;
# Fill out &amp;amp; submit a review form&lt;br /&gt;
# View your scores&lt;br /&gt;
# Respond to a review (“author feedback”)&lt;br /&gt;
&lt;br /&gt;
=== Log in ===&lt;br /&gt;
we create a file called ‘student_signin_spec.rb’.  We define a method named login; and because we need this method in every later  feature test we will put this in the support directory.&lt;br /&gt;
* Scenario 1: Log in with ‘invalid combination of username and password’&lt;br /&gt;
When we sign in with correct name and password; we expect that there should be content ‘Invalid username/password’ appear in the new page.&lt;br /&gt;
* Scenario 2: Log in with ‘valid combination of username and password’&lt;br /&gt;
When we sign in with correct name and password; we expect that there should be content ‘User: (username)’ appear in the new page.&lt;br /&gt;
&lt;br /&gt;
==== We have test file &amp;quot;student_sign_in.rb&amp;quot; do this task. Run test using command &amp;quot; rspec spec/features/student_sign_in_spec.rb&amp;quot;====&lt;br /&gt;
&lt;br /&gt;
=== Add someone to a team ===&lt;br /&gt;
* Scenario 1: Team member exceed max amount&lt;br /&gt;
# Sign in &lt;br /&gt;
# Click link certain assignment(in this test: Ethical analysis 2)&lt;br /&gt;
# Click link  “Your team” &lt;br /&gt;
# Fill in the text area with invitation receiver name&lt;br /&gt;
# Click send invitation button&lt;br /&gt;
# Sign out.&lt;br /&gt;
# Sign in as receiver&lt;br /&gt;
# Click link assignment&lt;br /&gt;
# Click link  “Your team”&lt;br /&gt;
# Click  button ‘accept’&lt;br /&gt;
&lt;br /&gt;
On this page, we expect the sender's name will appear.&lt;br /&gt;
&lt;br /&gt;
====We have &amp;quot;add_member_spec.rb&amp;quot; to do this task. Run test using the command &amp;quot;rspec spec/features/add_member_spec.rb &amp;quot;====&lt;br /&gt;
&lt;br /&gt;
=== Select a topic ===&lt;br /&gt;
Note: assignment has topics&lt;br /&gt;
&lt;br /&gt;
We need the following steps:&lt;br /&gt;
# sign in. &lt;br /&gt;
# click the link for assignment &lt;br /&gt;
# click link  “signup sheet”&lt;br /&gt;
# click the sign up for the remaining topic we want, as this user has already signed up for this topic, we should get the following message: Your topic(s): Self-plagiarism. &lt;br /&gt;
# sign out &lt;br /&gt;
Run test using the command &amp;quot;rspec spec/features/select_a_topic_spec.rb &amp;quot;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Select a submission to review ===&lt;br /&gt;
# sign in.  &lt;br /&gt;
# click the link for the assignment we want to review.&lt;br /&gt;
# click the link for “other’s work”&lt;br /&gt;
# click the link for the submission we want to review&lt;br /&gt;
# sign out &lt;br /&gt;
Run test using the command &amp;quot;rspec spec/features/select_a_submission_to_review_spec.rb &amp;quot;&lt;br /&gt;
&lt;br /&gt;
=== Bring up a review form ===&lt;br /&gt;
# sign in.  &lt;br /&gt;
# click the link for the assignment we want to review.&lt;br /&gt;
# click the link for “other’s work”&lt;br /&gt;
# click 'Begin'&lt;br /&gt;
# check that a review form has successfully been created&lt;br /&gt;
Run test using the command &amp;quot;rspec spec/features/bring_up_review_form_spec.rb &amp;quot;&lt;br /&gt;
&lt;br /&gt;
=== Fill out and submit a review form ===&lt;br /&gt;
# sign in.  &lt;br /&gt;
# click the link for the assignment we want to review.&lt;br /&gt;
# click the link for “other’s work”&lt;br /&gt;
# open a review form&lt;br /&gt;
# fill out all text fields&lt;br /&gt;
# select all scores from dropdowns&lt;br /&gt;
# submit form&lt;br /&gt;
# check for successful save&lt;br /&gt;
Run test using the command &amp;quot;rspec spec/features/fill_out_review_form_spec.rb &amp;quot;&lt;br /&gt;
&lt;br /&gt;
=== View your scores ===&lt;br /&gt;
* Scenario 1: No Scores available yet&lt;br /&gt;
# Sign in&lt;br /&gt;
# Click link for Assignment&lt;br /&gt;
# Click ‘Your scores’&lt;br /&gt;
# Check that nothing exists yet&lt;br /&gt;
# Check for dashes.&lt;br /&gt;
* Scenario 2: Scores available.&lt;br /&gt;
# Sign in&lt;br /&gt;
# Click link for Assignment&lt;br /&gt;
# Click ‘Your scores’&lt;br /&gt;
# Check that displayed scores match scores independently calculated from all reviews.&lt;br /&gt;
To run this test run: $ rspec spec/features/student_view_score.rb&lt;br /&gt;
&lt;br /&gt;
=== Respond to a review (“author feedback”) ===&lt;br /&gt;
# Sign in as author&lt;br /&gt;
# Click link for Assignment&lt;br /&gt;
# Click ‘Your scores’&lt;br /&gt;
# Click ‘show reviews’&lt;br /&gt;
# Click ‘Give feedback’&lt;br /&gt;
# Fill out Feedback form&lt;br /&gt;
# Click Save Feedback&lt;br /&gt;
# Check for confirmation that the feedback was saved&lt;br /&gt;
To run this test run:$ rspec spec/features/review_feedback.rb&lt;br /&gt;
&lt;br /&gt;
==Links==&lt;br /&gt;
*Github repository:  https://github.com/xhy279/expertiza/tree/fall2015/spec/features&lt;br /&gt;
*Demo videos(4 in total): &lt;br /&gt;
1. https://drive.google.com/open?id=0B3EOsci5DEveMGZOdVNIazJlNVE&lt;br /&gt;
2. https://drive.google.com/a/ncsu.edu/file/d/0B-l-xu44qiJUZDRFMU02U09kZWs/view?usp=sharing&lt;br /&gt;
3.&lt;br /&gt;
4. https://drive.google.com/a/ncsu.edu/file/d/0B7dSj1bvwNp9X29TTHJMVFhPWkE/view?usp=sharing&lt;/div&gt;</summary>
		<author><name>Cnbrown4</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2015_E1581_Integration_testing_for_student_interface&amp;diff=100242</id>
		<title>CSC/ECE 517 Fall 2015 E1581 Integration testing for student interface</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2015_E1581_Integration_testing_for_student_interface&amp;diff=100242"/>
		<updated>2015-12-05T02:28:52Z</updated>

		<summary type="html">&lt;p&gt;Cnbrown4: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Create integration tests for the student interface using capybara and rspec. Integration testing is the phase in software testing in which individual software modules are combined and tested as a group. It occurs after unit testing and before validation testing. Integration testing takes as its input modules that have been unit tested, groups them in larger aggregates, applies tests defined in an integration test plan to those aggregates, and delivers as its output the integrated system ready for system testing.&lt;br /&gt;
&lt;br /&gt;
== Design ==&lt;br /&gt;
To properly execute the integration tests we will write the test cases to mimic a user operating the system. We will create strong integration test cases to help ensure the outcome of application's student interface remains the same regardless of changes to its inner functionality. In an attempt to keep our tests DRY we will put common code in a support directory.&lt;br /&gt;
&lt;br /&gt;
== Testing tools ==&lt;br /&gt;
'''RSpec''' is a behavior-driven development (BDD) framework for the Ruby (programming language)|Ruby programming language, inspired by JBehave. It contains its own mocking framework that is fully integrated into the framework based upon JMock.&lt;br /&gt;
&lt;br /&gt;
'''Capybara''' is a web-based automation framework used for creating functional tests which can simulate how users would interact with your application.&lt;br /&gt;
&lt;br /&gt;
== Test Plan ==&lt;br /&gt;
There are 8 features to be tested:&lt;br /&gt;
# Log in&lt;br /&gt;
# Add someone to a team &lt;br /&gt;
# Select a topic(if the assignment has topics)&lt;br /&gt;
# Select a submission to review For assignments with or without topics&lt;br /&gt;
# Bring up a review form&lt;br /&gt;
# Fill out &amp;amp; submit a review form&lt;br /&gt;
# View your scores&lt;br /&gt;
# Respond to a review (“author feedback”)&lt;br /&gt;
&lt;br /&gt;
=== Log in ===&lt;br /&gt;
we create a file called ‘student_signin_spec.rb’.  We define a method named login; and because we need this method in every later  feature test we will put this in the support directory.&lt;br /&gt;
* Scenario 1: Log in with ‘invalid combination of username and password’&lt;br /&gt;
When we sign in with correct name and password; we expect that there should be content ‘Invalid username/password’ appear in the new page.&lt;br /&gt;
* Scenario 2: Log in with ‘valid combination of username and password’&lt;br /&gt;
When we sign in with correct name and password; we expect that there should be content ‘User: (username)’ appear in the new page.&lt;br /&gt;
&lt;br /&gt;
==== We have test file &amp;quot;student_sign_in.rb&amp;quot; do this task. Run test using command &amp;quot; rspec spec/features/student_sign_in_spec.rb&amp;quot;====&lt;br /&gt;
&lt;br /&gt;
=== Add someone to a team ===&lt;br /&gt;
* Scenario 1: Team member exceed max amount&lt;br /&gt;
# Sign in &lt;br /&gt;
# Click link certain assignment(in this test: Ethical analysis 2)&lt;br /&gt;
# Click link  “Your team” &lt;br /&gt;
# Fill in the text area with invitation receiver name&lt;br /&gt;
# Click send invitation button&lt;br /&gt;
# Sign out.&lt;br /&gt;
# Sign in as receiver&lt;br /&gt;
# Click link assignment&lt;br /&gt;
# Click link  “Your team”&lt;br /&gt;
# Click  button ‘accept’&lt;br /&gt;
&lt;br /&gt;
On this page, we expect the sender's name will appear.&lt;br /&gt;
&lt;br /&gt;
====We have &amp;quot;add_member_spec.rb&amp;quot; to do this task. Run test using the command &amp;quot;rspec spec/features/add_member_spec.rb &amp;quot;====&lt;br /&gt;
&lt;br /&gt;
=== Select a topic ===&lt;br /&gt;
Note: assignment has topics&lt;br /&gt;
&lt;br /&gt;
We need the following steps:&lt;br /&gt;
# sign in. &lt;br /&gt;
# click the link for assignment &lt;br /&gt;
# click link  “signup sheet”&lt;br /&gt;
# click the sign up for the remaining topic we want, as this user has already signed up for this topic, we should get the following message: Your topic(s): Self-plagiarism. &lt;br /&gt;
# sign out &lt;br /&gt;
Run test using the command &amp;quot;rspec spec/features/select_a_topic_spec.rb &amp;quot;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Select a submission to review ===&lt;br /&gt;
# sign in.  &lt;br /&gt;
# click the link for the assignment we want to review.&lt;br /&gt;
# click the link for “other’s work”&lt;br /&gt;
# click the link for the submission we want to review&lt;br /&gt;
# sign out &lt;br /&gt;
Run test using the command &amp;quot;rspec spec/features/select_a_submission_to_review_spec.rb &amp;quot;&lt;br /&gt;
&lt;br /&gt;
=== Bring up a review form ===&lt;br /&gt;
# sign in.  &lt;br /&gt;
# click the link for the assignment we want to review.&lt;br /&gt;
# click the link for “other’s work”&lt;br /&gt;
# click 'Begin'&lt;br /&gt;
# check that a review form has successfully been created&lt;br /&gt;
Run test using the command &amp;quot;rspec spec/features/fill_out_review_form_spec.rb &amp;quot;&lt;br /&gt;
&lt;br /&gt;
=== Fill out and submit a review form ===&lt;br /&gt;
# sign in.  &lt;br /&gt;
# click the link for the assignment we want to review.&lt;br /&gt;
# click the link for “other’s work”&lt;br /&gt;
# open a review form&lt;br /&gt;
# fill out all text fields&lt;br /&gt;
# select all scores from dropdowns&lt;br /&gt;
# submit form&lt;br /&gt;
# check for successful save&lt;br /&gt;
Run test using the command &amp;quot;rspec spec/features/fill_out_review_form_spec.rb &amp;quot;&lt;br /&gt;
&lt;br /&gt;
=== View your scores ===&lt;br /&gt;
* Scenario 1: No Scores available yet&lt;br /&gt;
# Sign in&lt;br /&gt;
# Click link for Assignment&lt;br /&gt;
# Click ‘Your scores’&lt;br /&gt;
# Check that nothing exists yet&lt;br /&gt;
# Check for dashes.&lt;br /&gt;
* Scenario 2: Scores available.&lt;br /&gt;
# Sign in&lt;br /&gt;
# Click link for Assignment&lt;br /&gt;
# Click ‘Your scores’&lt;br /&gt;
# Check that displayed scores match scores independently calculated from all reviews.&lt;br /&gt;
To run this test run: $ rspec spec/features/student_view_score.rb&lt;br /&gt;
&lt;br /&gt;
=== Respond to a review (“author feedback”) ===&lt;br /&gt;
# Sign in as author&lt;br /&gt;
# Click link for Assignment&lt;br /&gt;
# Click ‘Your scores’&lt;br /&gt;
# Click ‘show reviews’&lt;br /&gt;
# Click ‘Give feedback’&lt;br /&gt;
# Fill out Feedback form&lt;br /&gt;
# Click Save Feedback&lt;br /&gt;
# Check for confirmation that the feedback was saved&lt;br /&gt;
To run this test run:$ rspec spec/features/review_feedback.rb&lt;br /&gt;
&lt;br /&gt;
==Links==&lt;br /&gt;
*Github repository:  https://github.com/xhy279/expertiza/tree/fall2015/spec/features&lt;br /&gt;
*Demo videos(4 in total): &lt;br /&gt;
1. https://drive.google.com/open?id=0B3EOsci5DEveMGZOdVNIazJlNVE&lt;br /&gt;
2. https://drive.google.com/a/ncsu.edu/file/d/0B-l-xu44qiJUZDRFMU02U09kZWs/view?usp=sharing&lt;br /&gt;
3.&lt;br /&gt;
4. https://drive.google.com/a/ncsu.edu/file/d/0B7dSj1bvwNp9X29TTHJMVFhPWkE/view?usp=sharing&lt;/div&gt;</summary>
		<author><name>Cnbrown4</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2015_E1581_Integration_testing_for_student_interface&amp;diff=100240</id>
		<title>CSC/ECE 517 Fall 2015 E1581 Integration testing for student interface</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2015_E1581_Integration_testing_for_student_interface&amp;diff=100240"/>
		<updated>2015-12-05T02:24:27Z</updated>

		<summary type="html">&lt;p&gt;Cnbrown4: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Create integration tests for the student interface using capybara and rspec. Integration testing is the phase in software testing in which individual software modules are combined and tested as a group. It occurs after unit testing and before validation testing. Integration testing takes as its input modules that have been unit tested, groups them in larger aggregates, applies tests defined in an integration test plan to those aggregates, and delivers as its output the integrated system ready for system testing.&lt;br /&gt;
&lt;br /&gt;
== Design ==&lt;br /&gt;
To properly execute the integration tests we will write the test cases to mimic a user operating the system. We will create strong integration test cases to help ensure the outcome of application's student interface remains the same regardless of changes to its inner functionality. In an attempt to keep our tests DRY we will put common code in a support directory.&lt;br /&gt;
&lt;br /&gt;
== Testing tools ==&lt;br /&gt;
'''RSpec''' is a behavior-driven development (BDD) framework for the Ruby (programming language)|Ruby programming language, inspired by JBehave. It contains its own mocking framework that is fully integrated into the framework based upon JMock.&lt;br /&gt;
&lt;br /&gt;
'''Capybara''' is a web-based automation framework used for creating functional tests which can simulate how users would interact with your application.&lt;br /&gt;
&lt;br /&gt;
== Test Plan ==&lt;br /&gt;
There are 8 features to be tested:&lt;br /&gt;
# Log in&lt;br /&gt;
# Add someone to a team &lt;br /&gt;
# Select a topic(if the assignment has topics)&lt;br /&gt;
# Select a submission to review For assignments with or without topics&lt;br /&gt;
# Bring up a review form&lt;br /&gt;
# Fill out &amp;amp; submit a review form&lt;br /&gt;
# View your scores&lt;br /&gt;
# Respond to a review (“author feedback”)&lt;br /&gt;
&lt;br /&gt;
=== Log in ===&lt;br /&gt;
we create a file called ‘student_signin_spec.rb’.  We define a method named login; and because we need this method in every later  feature test we will put this in the support directory.&lt;br /&gt;
* Scenario 1: Log in with ‘invalid combination of username and password’&lt;br /&gt;
When we sign in with correct name and password; we expect that there should be content ‘Invalid username/password’ appear in the new page.&lt;br /&gt;
* Scenario 2: Log in with ‘valid combination of username and password’&lt;br /&gt;
When we sign in with correct name and password; we expect that there should be content ‘User: (username)’ appear in the new page.&lt;br /&gt;
&lt;br /&gt;
==== We have test file &amp;quot;student_sign_in.rb&amp;quot; do this task. Run test using command &amp;quot; rspec spec/features/student_sign_in_spec.rb&amp;quot;====&lt;br /&gt;
&lt;br /&gt;
=== Add someone to a team ===&lt;br /&gt;
* Scenario 1: Team member exceed max amount&lt;br /&gt;
# Sign in &lt;br /&gt;
# Click link certain assignment(in this test: Ethical analysis 2)&lt;br /&gt;
# Click link  “Your team” &lt;br /&gt;
# Fill in the text area with invitation receiver name&lt;br /&gt;
# Click send invitation button&lt;br /&gt;
# Sign out.&lt;br /&gt;
# Sign in as receiver&lt;br /&gt;
# Click link assignment&lt;br /&gt;
# Click link  “Your team”&lt;br /&gt;
# Click  button ‘accept’&lt;br /&gt;
&lt;br /&gt;
On this page, we expect the sender's name will appear.&lt;br /&gt;
&lt;br /&gt;
====We have &amp;quot;add_member_spec.rb&amp;quot; to do this task. Run test using the command &amp;quot;rspec spec/features/add_member_spec.rb &amp;quot;====&lt;br /&gt;
&lt;br /&gt;
=== Select a topic ===&lt;br /&gt;
Note: assignment has topics&lt;br /&gt;
&lt;br /&gt;
We need the following steps:&lt;br /&gt;
# sign in. &lt;br /&gt;
# click the link for assignment &lt;br /&gt;
# click link  “signup sheet”&lt;br /&gt;
# click the sign up for the remaining topic we want, as this user has already signed up for this topic, we should get the following message: Your topic(s): Self-plagiarism. &lt;br /&gt;
# sign out &lt;br /&gt;
Run test using the command &amp;quot;rspec spec/features/select_a_topic_spec.rb &amp;quot;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Select a submission to review ===&lt;br /&gt;
# sign in.  &lt;br /&gt;
# click the link for the assignment we want to review.&lt;br /&gt;
# click the link for “other’s work”&lt;br /&gt;
# click the link for the submission we want to review&lt;br /&gt;
# sign out &lt;br /&gt;
Run test using the command &amp;quot;rspec spec/features/select_a_submission_to_review_spec.rb &amp;quot;&lt;br /&gt;
&lt;br /&gt;
=== Bring up a review form ===&lt;br /&gt;
Repeated for an assignment without a topic and an assignment with a topic&lt;br /&gt;
# sign in.  &lt;br /&gt;
# click the link for the assignment we want to review.&lt;br /&gt;
# click the link for “other’s work”&lt;br /&gt;
# click 'Begin'&lt;br /&gt;
# check that a review form has successfully been created&lt;br /&gt;
Run test using the command &amp;quot;rspec spec/features/fill_out_review_form_spec.rb &amp;quot;&lt;br /&gt;
&lt;br /&gt;
=== Fill out and submit a review form ===&lt;br /&gt;
* Scenario 1:&lt;br /&gt;
Note: Do this for an assignment without a topic and an assignment with a topic.&lt;br /&gt;
# sign in.  &lt;br /&gt;
# click the link for the assignment we want to review.&lt;br /&gt;
# click the link for “other’s work”&lt;br /&gt;
# open a review form&lt;br /&gt;
# fill out all text fields&lt;br /&gt;
# select all scores from dropdowns&lt;br /&gt;
# submit form&lt;br /&gt;
# check for successful save&lt;br /&gt;
Run test using the command &amp;quot;rspec spec/features/fill_out_review_form_spec.rb &amp;quot;&lt;br /&gt;
&lt;br /&gt;
=== View your scores ===&lt;br /&gt;
* Scenario 1: No Scores available yet&lt;br /&gt;
# Sign in&lt;br /&gt;
# Click link for Assignment&lt;br /&gt;
# Click ‘Your scores’&lt;br /&gt;
# Check that nothing exists yet&lt;br /&gt;
# Check for dashes.&lt;br /&gt;
* Scenario 2: Scores available.&lt;br /&gt;
# Sign in&lt;br /&gt;
# Click link for Assignment&lt;br /&gt;
# Click ‘Your scores’&lt;br /&gt;
# Check that displayed scores match scores independently calculated from all reviews.&lt;br /&gt;
To run this test run: $ rspec spec/features/student_view_score.rb&lt;br /&gt;
&lt;br /&gt;
=== Respond to a review (“author feedback”) ===&lt;br /&gt;
# Sign in as author&lt;br /&gt;
# Click link for Assignment&lt;br /&gt;
# Click ‘Your scores’&lt;br /&gt;
# Click ‘show reviews’&lt;br /&gt;
# Click ‘Give feedback’&lt;br /&gt;
# Fill out Feedback form&lt;br /&gt;
# Click Save Feedback&lt;br /&gt;
# Check for confirmation that the feedback was saved&lt;br /&gt;
To run this test run:$ rspec spec/features/review_feedback.rb&lt;br /&gt;
&lt;br /&gt;
==Links==&lt;br /&gt;
*Github repository:  https://github.com/xhy279/expertiza/tree/fall2015/spec/features&lt;br /&gt;
*Demo videos(4 in total): &lt;br /&gt;
1. https://drive.google.com/open?id=0B3EOsci5DEveMGZOdVNIazJlNVE&lt;br /&gt;
2. https://drive.google.com/a/ncsu.edu/file/d/0B-l-xu44qiJUZDRFMU02U09kZWs/view?usp=sharing&lt;br /&gt;
3.&lt;br /&gt;
4. https://drive.google.com/a/ncsu.edu/file/d/0B7dSj1bvwNp9X29TTHJMVFhPWkE/view?usp=sharing&lt;/div&gt;</summary>
		<author><name>Cnbrown4</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2015_E1581_Integration_testing_for_student_interface&amp;diff=100092</id>
		<title>CSC/ECE 517 Fall 2015 E1581 Integration testing for student interface</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2015_E1581_Integration_testing_for_student_interface&amp;diff=100092"/>
		<updated>2015-12-04T21:12:02Z</updated>

		<summary type="html">&lt;p&gt;Cnbrown4: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Create integration tests for the student interface using capybara and rspec. Integration testing is the phase in software testing in which individual software modules are combined and tested as a group. It occurs after unit testing and before validation testing. Integration testing takes as its input modules that have been unit tested, groups them in larger aggregates, applies tests defined in an integration test plan to those aggregates, and delivers as its output the integrated system ready for system testing.&lt;br /&gt;
&lt;br /&gt;
== Design ==&lt;br /&gt;
To properly execute the integration tests we will write the test cases to mimic a user operating the system. We will create strong integration test cases to help ensure the outcome of application's student interface remains the same regardless of changes to its inner functionality. In an attempt to keep our tests DRY we will put common code in a support directory.&lt;br /&gt;
&lt;br /&gt;
== Testing tools ==&lt;br /&gt;
'''RSpec''' is a behavior-driven development (BDD) framework for the Ruby (programming language)|Ruby programming language, inspired by JBehave. It contains its own mocking framework that is fully integrated into the framework based upon JMock.&lt;br /&gt;
&lt;br /&gt;
'''Capybara''' is a web-based automation framework used for creating functional tests which can simulate how users would interact with your application.&lt;br /&gt;
&lt;br /&gt;
== Test Plan ==&lt;br /&gt;
There are 8 features to be tested:&lt;br /&gt;
# Log in&lt;br /&gt;
# Add someone to a team Should not be possible if you exceed the max # of team members)&lt;br /&gt;
# Select a topic(if the assignment has topics)&lt;br /&gt;
# Select a submission to review For assignments with or without topics&lt;br /&gt;
# Bring up a review form&lt;br /&gt;
# Fill out &amp;amp; submit a review form&lt;br /&gt;
# View your scores&lt;br /&gt;
# Respond to a review (“author feedback”)&lt;br /&gt;
&lt;br /&gt;
=== Log in ===&lt;br /&gt;
we create a file called ‘student_signin_spec.rb’.  We define a method named login; and because we need this method in every later  feature test we will put this in the support directory.&lt;br /&gt;
* Scenario 1: Log in with ‘invalid combination of username and password’&lt;br /&gt;
When we sign in with correct name and password; we expect that there should be content ‘Invalid username/password’ appear in the new page.&lt;br /&gt;
* Scenario 2: Log in with ‘valid combination of username and password’&lt;br /&gt;
When we sign in with correct name and password; we expect that there should be content ‘User: (username)’ appear in the new page.&lt;br /&gt;
&lt;br /&gt;
==== We have test file &amp;quot;student_sign_in.rb&amp;quot; do this task. Run test using command &amp;quot; rspec spec/features/student_sign_in_spec.rb&amp;quot;====&lt;br /&gt;
&lt;br /&gt;
=== Add someone to a team ===&lt;br /&gt;
* Scenario 1: Team member exceed max amount&lt;br /&gt;
# Sign in &lt;br /&gt;
# Click link certain assignment(in this test: Ethical analysis 2)&lt;br /&gt;
# Click link  “Your team” &lt;br /&gt;
# Fill in the text area with invitation receiver name&lt;br /&gt;
# Click send invitation button&lt;br /&gt;
# Sign out.&lt;br /&gt;
# Sign in as receiver&lt;br /&gt;
# Click link assignment&lt;br /&gt;
# Click link  “Your team”&lt;br /&gt;
# Click  button ‘accept’&lt;br /&gt;
&lt;br /&gt;
On this page, we expect the sender's name will appear.&lt;br /&gt;
&lt;br /&gt;
====We have &amp;quot;add_member_spec.rb&amp;quot; to do this task. Run test using the command &amp;quot;rspec spec/features/add_member_spec.rb &amp;quot;====&lt;br /&gt;
&lt;br /&gt;
=== Select a topic ===&lt;br /&gt;
Note: assignment has topics&lt;br /&gt;
&lt;br /&gt;
We need the following steps:&lt;br /&gt;
# sign in. &lt;br /&gt;
# click the link for assignment &lt;br /&gt;
# click link  “signup sheet”&lt;br /&gt;
# click the sign up for the remaining topic we want, or join the waiting list if the topic is not available. &lt;br /&gt;
# sign out &lt;br /&gt;
&lt;br /&gt;
=== Select a submission to review ===&lt;br /&gt;
# sign in.  &lt;br /&gt;
# click the link for the assignment we want to review.&lt;br /&gt;
# click the link for “other’s work”&lt;br /&gt;
# click the link for the submission we want to review&lt;br /&gt;
# sign out &lt;br /&gt;
&lt;br /&gt;
=== Bring up a review form ===&lt;br /&gt;
Repeated for an assignment without a topic and an assignment with a topic&lt;br /&gt;
# sign in.  &lt;br /&gt;
# click the link for the assignment we want to review.&lt;br /&gt;
# click the link for “other’s work”&lt;br /&gt;
# click 'Begin'&lt;br /&gt;
# check that a review form has successfully been created&lt;br /&gt;
&lt;br /&gt;
=== Fill out and submit a review form ===&lt;br /&gt;
* Scenario 1:&lt;br /&gt;
Note: Do this for an assignment without a topic and an assignment with a topic.&lt;br /&gt;
# sign in.  &lt;br /&gt;
# click the link for the assignment we want to review.&lt;br /&gt;
# click the link for “other’s work”&lt;br /&gt;
# open a review form&lt;br /&gt;
# fill out all text fields&lt;br /&gt;
# select all scores from dropdowns&lt;br /&gt;
# submit form&lt;br /&gt;
# check for successful save&lt;br /&gt;
&lt;br /&gt;
* Scenario 2:&lt;br /&gt;
# open a review form&lt;br /&gt;
# sign in.  &lt;br /&gt;
# click the link for the assignment we want to review.&lt;br /&gt;
# click the link for “other’s work”&lt;br /&gt;
# fill out some text fields&lt;br /&gt;
# select some scores&lt;br /&gt;
# save form&lt;br /&gt;
# reopen form&lt;br /&gt;
# fill out remaining fields and scores&lt;br /&gt;
# save form&lt;br /&gt;
# check for successful save&lt;br /&gt;
&lt;br /&gt;
=== View your scores ===&lt;br /&gt;
* Scenario 1: No Scores available yet&lt;br /&gt;
# Sign in&lt;br /&gt;
# Click link for Assignment&lt;br /&gt;
# Click ‘Your scores’&lt;br /&gt;
# Check that nothing exists yet&lt;br /&gt;
# Check for dashes.&lt;br /&gt;
* Scenario 2: Scores available.&lt;br /&gt;
# Sign in&lt;br /&gt;
# Click link for Assignment&lt;br /&gt;
# Click ‘Your scores’&lt;br /&gt;
# Check that displayed scores match scores independently calculated from all reviews.&lt;br /&gt;
&lt;br /&gt;
=== Respond to a review (“author feedback”) ===&lt;br /&gt;
# Sign in as author&lt;br /&gt;
# Click link for Assignment&lt;br /&gt;
# Click ‘Your scores’&lt;br /&gt;
# Click ‘show reviews’&lt;br /&gt;
# Click ‘Give feedback’&lt;br /&gt;
# Fill out Feedback form&lt;br /&gt;
# Click Save Feedback&lt;br /&gt;
# Sign out&lt;br /&gt;
# Sign in as reviewer&lt;br /&gt;
# Click link for Assignment&lt;br /&gt;
# Click ‘Other’s work’&lt;br /&gt;
# Check that a feedback exists.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Links==&lt;br /&gt;
*Github repository:  https://github.com/xhy279/expertiza/tree/fall2015/spec/features&lt;br /&gt;
*Demo videos(4 in total): 1. https://drive.google.com/open?id=0B3EOsci5DEveMGZOdVNIazJlNVE&lt;/div&gt;</summary>
		<author><name>Cnbrown4</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2015/ossE1558BGJ&amp;diff=98482</id>
		<title>CSC/ECE 517 Fall 2015/ossE1558BGJ</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2015/ossE1558BGJ&amp;diff=98482"/>
		<updated>2015-11-06T21:52:26Z</updated>

		<summary type="html">&lt;p&gt;Cnbrown4: /* Refactoring of other methods */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Introduction =&lt;br /&gt;
&lt;br /&gt;
This page provides a description of the modifications and improvements made to the Expertiza project’s source code as part of an Expertiza based Open Source Software project.  Expertiza is a web based application which allows students to submit and peer-review classmates’ work, including written articles and development projects. The specific changes made during the course of this project were to the ReviewResponseMap.rb file, with additional changes made to other related files in support of refactoring ReviewResponseMap.rb.  &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
= Problem Statement =&lt;br /&gt;
&lt;br /&gt;
ReviewResponseMap is the model class used to manage the relationship between contributors, reviewers, and assignments.  The intent of the changes were to refactor the code for better readability and adherence to Ruby coding standards and best practices.  Primarily these changes involved the refactoring of overly complex methods, renaming methods for better readability, and the addition of missing unit tests.&lt;br /&gt;
&lt;br /&gt;
Project Requirements:&lt;br /&gt;
&lt;br /&gt;
# Code Climate&amp;lt;ref name=&amp;quot;Code Climate&amp;quot;&amp;gt;https://codeclimate.com&amp;lt;/ref&amp;gt; shows import method is complex, because of lots of checks. This method can be fixed by adding private methods for raising import error.&lt;br /&gt;
# Get_assessments_round_for method can be renamed to get_team_responses_for_round. Team_id private variable is not needed.&lt;br /&gt;
# metareview_response_maps rename, refactoring can be done. No need to do second iteration.&lt;br /&gt;
# write missing unit tests for existing methods.&lt;br /&gt;
&lt;br /&gt;
= Design Patterns =&lt;br /&gt;
&lt;br /&gt;
As part of our project, we refactored the model to follow the Single Responsibility and Don't Repeat Yourself (DRY) Principles.  Both of the principles focus on reducing code repetition and increasing the cohesion of the individual methods in the class.  The Single Responsibility Principle states that each class and method should have sole responsibility over one single part of the functionality of the system&amp;lt;ref&amp;gt;https://en.wikipedia.org/wiki/Single_responsibility_principle&amp;lt;/ref&amp;gt;.  The DRY principle states that whenever the same types of logic and functionality are being performed in a class the duplicated logic should be extracted into a new method that can be called in place of the repeated lines of code &amp;lt;ref&amp;gt;https://en.wikipedia.org/wiki/Don%27t_repeat_yourself&amp;lt;/ref&amp;gt;.  A prime example of a method that initially violated these principles was the import method, which in addition to performing the core import processes also performed a number of checks that would be more properly extracted into private methods.&lt;br /&gt;
&lt;br /&gt;
=Code Changes =&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Refactoring of import method ===&lt;br /&gt;
&lt;br /&gt;
CodeClimate reports showed the import method to be overly complex, with a number of checks being included within the import method itself.  The resolution for this problem was to refactor the import method, creating private methods to perform the null checks and throw import errors.  Prior to refactoring, all null checks were performed within the import method.   After refactoring, the import method adheres to the single responsibility principle, performing only key import tasks while making calls to private methods for any necessary validation. The size of the import method was reduced by doing this and counts for better readability of the code. Also, this method is a very important one and care was taken so that any existing functionality did not break. &lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
Before refactoring:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;big&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 def self.import(row, session, id)&lt;br /&gt;
    if row.length &amp;lt; 2&lt;br /&gt;
      raise ArgumentError, &amp;quot;Not enough items&amp;quot;&lt;br /&gt;
    end&lt;br /&gt;
    assignment = Assignment.find(id)&lt;br /&gt;
    if assignment.nil?&lt;br /&gt;
      raise ImportError, &amp;quot;The assignment with id \&amp;quot;#{id}\&amp;quot; was not found. &amp;lt;a href='/assignment/new'&amp;gt;Create&amp;lt;/a&amp;gt; this assignment?&amp;quot;&lt;br /&gt;
    end&lt;br /&gt;
    index = 1&lt;br /&gt;
    while index &amp;lt; row.length&lt;br /&gt;
      user = User.find_by_name(row[index].to_s.strip)&lt;br /&gt;
      if user.nil?&lt;br /&gt;
        raise ImportError, &amp;quot;The user account for the reviewer \&amp;quot;#{row[index]}\&amp;quot; was not found. &amp;lt;a href='/users/new'&amp;gt;Create&amp;lt;/a&amp;gt; this user?&amp;quot;&lt;br /&gt;
      end&lt;br /&gt;
      reviewer = AssignmentParticipant.where(user_id: user.id, parent_id:  assignment.id).first&lt;br /&gt;
      if reviewer == nil&lt;br /&gt;
        raise ImportError, &amp;quot;The reviewer \&amp;quot;#{row[index]}\&amp;quot; is not a participant in this assignment. &amp;lt;a href='/users/new'&amp;gt;Register&amp;lt;/a&amp;gt; this user as a participant?&amp;quot;&lt;br /&gt;
      end&lt;br /&gt;
      if assignment.team_assignment&lt;br /&gt;
        reviewee = AssignmentTeam.where(name: row[0].to_s.strip, parent_id:  assignment.id).first&lt;br /&gt;
        if reviewee == nil&lt;br /&gt;
          raise ImportError, &amp;quot;The author \&amp;quot;#{row[0].to_s.strip}\&amp;quot; was not found. &amp;lt;a href='/users/new'&amp;gt;Create&amp;lt;/a&amp;gt; this user?&amp;quot;&lt;br /&gt;
        end&lt;br /&gt;
        existing = ReviewResponseMap.where(reviewee_id: reviewee.id, reviewer_id:  reviewer.id).first&lt;br /&gt;
        if existing.nil?&lt;br /&gt;
          ReviewResponseMap.create(:reviewer_id =&amp;gt; reviewer.id, :reviewee_id =&amp;gt; reviewee.id, :reviewed_object_id =&amp;gt; assignment.id)&lt;br /&gt;
        end&lt;br /&gt;
      else&lt;br /&gt;
        puser = User.find_by_name(row[0].to_s.strip)&lt;br /&gt;
        if user == nil&lt;br /&gt;
          raise ImportError, &amp;quot;The user account for the reviewee \&amp;quot;#{row[0]}\&amp;quot; was not found. &amp;lt;a href='/users/new'&amp;gt;Create&amp;lt;/a&amp;gt; this user?&amp;quot;&lt;br /&gt;
        end&lt;br /&gt;
        reviewee = AssignmentParticipant.where(user_id: puser.id, parent_id:  assignment.id).first&lt;br /&gt;
        if reviewee == nil&lt;br /&gt;
          raise ImportError, &amp;quot;The author \&amp;quot;#{row[0].to_s.strip}\&amp;quot; was not found. &amp;lt;a href='/users/new'&amp;gt;Create&amp;lt;/a&amp;gt; this user?&amp;quot;&lt;br /&gt;
        end&lt;br /&gt;
        team_id = TeamsUser.team_id(reviewee.parent_id, reviewee.user_id)&lt;br /&gt;
        existing = ReviewResponseMap.where(reviewee_id: team_id, reviewer_id:  reviewer.id).first&lt;br /&gt;
        if existing.nil?&lt;br /&gt;
          ReviewResponseMap.create(:reviewee_id =&amp;gt; team_id, :reviewer_id =&amp;gt; reviewer.id, :reviewed_object_id =&amp;gt; assignment.id)&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
      index += 1&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
&lt;br /&gt;
After refactoring:&lt;br /&gt;
 &lt;br /&gt;
  &amp;lt;big&amp;gt;&amp;lt;nowiki&amp;gt;#Imports new reponse maps if they do not already exist&lt;br /&gt;
  def self.import(row, _session, id)&lt;br /&gt;
      if row.length &amp;lt; 2&lt;br /&gt;
          raise ArgumentError, 'Not enough items'&lt;br /&gt;
      end&lt;br /&gt;
      assignment = find_assignment(id)&lt;br /&gt;
      index = 1&lt;br /&gt;
      reviewee_name = row[0]&lt;br /&gt;
      while index &amp;lt; row.length&lt;br /&gt;
          reviewee_id = nil&lt;br /&gt;
          reviewer_name = row[index]&lt;br /&gt;
          reviewer = get_assignment_participant(reviewer_name,  assignment.id, &amp;quot;reviewer&amp;quot;)&lt;br /&gt;
          participant_nil?(reviewer, reviewer_name , &amp;quot;reviewer&amp;quot;)&lt;br /&gt;
         &lt;br /&gt;
         #Find reviewee if assignment is a team assignment&lt;br /&gt;
         if assignment.team_assignment&lt;br /&gt;
             reviewee = AssignmentTeam.where(name: reviewee_name .to_s.strip, parent_id: assignment.id).first&lt;br /&gt;
             participant_nil?(reviewee, reviewee_name, &amp;quot;author&amp;quot;)&lt;br /&gt;
             reviewee_id = reviewee.id&lt;br /&gt;
         #Find reviewee if assignment is not a team assignment&lt;br /&gt;
         else&lt;br /&gt;
	     reviewee = get_assignment_participant(reviewee_name, assignment.id, &amp;quot;reviewee&amp;quot;)&lt;br /&gt;
             participant_nil?(reviewee, reviewee_name, &amp;quot;author&amp;quot;)&lt;br /&gt;
             reviewee_id  = TeamsUser.team_id(reviewee.parent_id, reviewee.user_id)&lt;br /&gt;
         end&lt;br /&gt;
         create_response_map(reviewer, reviewee_id,  assignment)&lt;br /&gt;
         index += 1&lt;br /&gt;
      end&lt;br /&gt;
  end&amp;lt;/nowiki&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Private methods added:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;big&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  # Check for if assignment value is null&lt;br /&gt;
  def self.find_assignment(id)&lt;br /&gt;
      begin&lt;br /&gt;
          assignment = Assignment.find(id)&lt;br /&gt;
      rescue ActiveRecord::RecordNotFound&lt;br /&gt;
          raise ImportError, &amp;quot;The assignment with id \&amp;quot;#{id}\&amp;quot; was not found.&amp;lt;a href='/assignment/new'&amp;gt;Create&amp;lt;/a&amp;gt; this assignment?&amp;quot;&lt;br /&gt;
      end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  # Check for if participant is null&lt;br /&gt;
  def self.participant_nil?(participant, user_name, participant_type) &lt;br /&gt;
      error_message = nil&lt;br /&gt;
      if participant_type == &amp;quot;author&amp;quot;&lt;br /&gt;
          error_message = &amp;quot;The author \&amp;quot;#{user_name.to_s.strip}\&amp;quot; was not found.&amp;lt;a href='/users/new'&amp;gt;Create&amp;lt;/a&amp;gt; this user?&amp;quot;&lt;br /&gt;
      else&lt;br /&gt;
          error_message =  &amp;quot;The reviewer \&amp;quot;#{user_name}\&amp;quot; is not a participant in this assignment.&amp;lt;a href='/users/new'&amp;gt;Register&amp;lt;/a&amp;gt; this user as a participant?&amp;quot;&lt;br /&gt;
      end&lt;br /&gt;
      check_nil?(participant, error_message)&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  # Check for if user is null&lt;br /&gt;
  def self.user_nil?(user, user_name, user_type)&lt;br /&gt;
      check_nil?( user, &amp;quot;The user account for the \&amp;quot;#{user_type}\&amp;quot; \&amp;quot;#{user_name}\&amp;quot; was not found.&amp;lt;a href='/users/new'&amp;gt;Create&amp;lt;/a&amp;gt; this user?&amp;quot;)&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
 #Throws import error for nil objects&lt;br /&gt;
  def self.check_nil?(object, error_message)&lt;br /&gt;
      if object.nil?&lt;br /&gt;
          raise ImportError, error_message&lt;br /&gt;
      end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Refactoring of get_assessments_round_for method ===&lt;br /&gt;
&lt;br /&gt;
The get_assessments_round_for method’s name failed to provide a clear idea of the method’s purpose and functionality.  This is why it was renamed to get_team_responses_for_round, the new name of the method provides a clearer idea of its purpose. Additionally, there was a private variable, team_id, introduced in the method that was unnecessary and could be replaced by using the id property of the team parameter directly.  We also removed the return statement at the end of the method.  &lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
Before refactoring:&lt;br /&gt;
&amp;lt;big&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  def self.get_assessments_round_for(team,round)&lt;br /&gt;
    team_id =team.id&lt;br /&gt;
    responses = Array.new&lt;br /&gt;
    if team_id&lt;br /&gt;
      maps = ResponseMap.where(:reviewee_id =&amp;gt; team_id, :type =&amp;gt; &amp;quot;ReviewResponseMap&amp;quot;)&lt;br /&gt;
      maps.each{ |map|&lt;br /&gt;
        if !map.response.empty? &amp;amp;&amp;amp; !map.response.reject{|r| r.round!=round}.empty?&lt;br /&gt;
          responses &amp;lt;&amp;lt; map.response.reject{|r| r.round!=round}.last&lt;br /&gt;
        end&lt;br /&gt;
      }&lt;br /&gt;
      responses.sort! {|a,b| a.map.reviewer.fullname &amp;lt;=&amp;gt; b.map.reviewer.fullname }&lt;br /&gt;
    end&lt;br /&gt;
    return responses&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
&lt;br /&gt;
After refactoring: &lt;br /&gt;
&lt;br /&gt;
&amp;lt;big&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  # return the responses for specified round,&lt;br /&gt;
  # for varying rubric feature -Yang&lt;br /&gt;
  def self.get_team_responses_for_round(team, round)&lt;br /&gt;
    responses = []&lt;br /&gt;
    if team.id&lt;br /&gt;
      maps = ResponseMap.where(reviewee_id: team.id, type: 'ReviewResponseMap')&lt;br /&gt;
      maps.each do |map|&lt;br /&gt;
        unless map.response.empty? &amp;amp;&amp;amp; map.response.reject { |r| r.round != round }.empty?&lt;br /&gt;
          responses &amp;lt;&amp;lt; map.response.reject { |r| r.round != round }.last&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
      responses.sort! { |a, b| a.map.reviewer.fullname &amp;lt;=&amp;gt; b.map.reviewer.fullname }&lt;br /&gt;
    end&lt;br /&gt;
    responses&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
The change in method name also required changes to the following files that referenced it:&lt;br /&gt;
&lt;br /&gt;
/app/models/assignment.rb:436:    &lt;br /&gt;
 &lt;br /&gt;
&amp;lt;big&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  assessments = ReviewResponseMap.get_assessments_round_for(team,i)&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt; &lt;br /&gt;
&lt;br /&gt;
./app/models/assignment_participant.rb:268:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;big&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 scores[questionnaire_symbol][:assessments] = questionnaire.get_assessments_round_for(self,round)&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Refactoring of metareview_response_maps method ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The metareview_response_maps method was unnecessarily complex.  It contained an unneeded private variable and an unnecessary nested loop.  Originally, it added each metareview map individually in the nested loop.  We decided to remove the nested loop and use the concat method for readability and maintainability.  These changes allowed us to remove the private variable &amp;quot;metareview_list&amp;quot; and only maintain the &amp;quot;metareview_response_maps&amp;quot; variable.  We also renamed the metareview_response_maps method to get_metareview_response_maps method to be more descriptive about the intent of the method. &lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
Before refactoring:&lt;br /&gt;
&amp;lt;big&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 def metareview_response_maps&lt;br /&gt;
    responses = Response.where(map_id:self.id)&lt;br /&gt;
    metareview_list=[]&lt;br /&gt;
    responses.each do |response|&lt;br /&gt;
      metareview_response_maps = MetareviewResponseMap.where(reviewed_object_id:response.id)&lt;br /&gt;
      metareview_response_maps.each do |metareview_response_map|&lt;br /&gt;
        metareview_list&amp;lt;&amp;lt;metareview_response_map&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
    metareview_list&lt;br /&gt;
 end&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
After refactoring:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;big&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  # Returns the response maps for all the metareviews&lt;br /&gt;
  def get_metareview_response_maps&lt;br /&gt;
    responses = Response.where(map_id: id)&lt;br /&gt;
    metareview_response_maps = []&lt;br /&gt;
    responses.each do |response|&lt;br /&gt;
      metareview_response_maps.concat MetareviewResponseMap.where(reviewed_object_id: response.id)&lt;br /&gt;
    end&lt;br /&gt;
    metareview_response_maps&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Refactoring of export method ===&lt;br /&gt;
The export method contained mappings.sort! { |a, b| a.reviewee.name &amp;lt;=&amp;gt; b.reviewee.name }.  We could not get past this when running tests, we kept getting a message saying, &amp;quot;sort! was not a method for an ActiveRecord_Relation&amp;quot;.  But, ActiveRecord_Relation does allow the use of sort.  So we changed that line of code to  mappings = mappings.sort { |a, b| a.reviewee.name &amp;lt;=&amp;gt; b.reviewee.name }&lt;br /&gt;
&lt;br /&gt;
Before refactoring:&lt;br /&gt;
&amp;lt;big&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  def self.export(csv, parent_id, options)&lt;br /&gt;
    mappings = where(reviewed_object_id: parent_id)&lt;br /&gt;
    mappings.sort! { |a, b| a.reviewee.name &amp;lt;=&amp;gt; b.reviewee.name }&lt;br /&gt;
    mappings.each {&lt;br /&gt;
      |map|&lt;br /&gt;
      csv &amp;lt;&amp;lt; [&lt;br /&gt;
        map.reviewee.name,&lt;br /&gt;
        map.reviewer.name&lt;br /&gt;
      ]&lt;br /&gt;
    }&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
&lt;br /&gt;
After refactoring:&lt;br /&gt;
&amp;lt;big&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  # options parameter used as a signature in other models&lt;br /&gt;
  def self.export(csv, parent_id, options)&lt;br /&gt;
    mappings = where(reviewed_object_id: parent_id)&lt;br /&gt;
    mappings = mappings.sort { |a, b| a.reviewee.name &amp;lt;=&amp;gt; b.reviewee.name }&lt;br /&gt;
    mappings.each do&lt;br /&gt;
    |map|&lt;br /&gt;
      csv &amp;lt;&amp;lt; [map.reviewee.name, map.reviewer.name]&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Refactoring of final_versions_from_reviewer method ===&lt;br /&gt;
The final_versions_from_reviewer method was too long and repetitive.  We removed common functionality from within the if and else statement and put it in a private method final_versions_from_reviewer.  Then we created the get_responses method to find the responses based on the arguments values.  These private methods make the class more readable for other programmers.&lt;br /&gt;
 &lt;br /&gt;
Before refactoring:&lt;br /&gt;
&amp;lt;big&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  def self.final_versions_from_reviewer(reviewer_id)&lt;br /&gt;
    maps = ReviewResponseMap.where(reviewer_id: reviewer_id)&lt;br /&gt;
    assignment = Assignment.find(Participant.find(reviewer_id).parent_id)&lt;br /&gt;
    review_final_versions = Hash.new&lt;br /&gt;
    if !assignment.varying_rubrics_by_round?&lt;br /&gt;
      #same review rubric used in multiple rounds&lt;br /&gt;
      review_final_versions[:review] = Hash.new&lt;br /&gt;
      review_final_versions[:review][:questionnaire_id] = assignment.get_review_questionnaire_id&lt;br /&gt;
      response_ids = Array.new&lt;br /&gt;
      maps.each do |map|&lt;br /&gt;
        responses = Response.where(map_id:map.id)&lt;br /&gt;
        if !responses.empty?&lt;br /&gt;
          response_ids &amp;lt;&amp;lt; responses.last.id&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
      review_final_versions[:review][:response_ids] = response_ids&lt;br /&gt;
    else&lt;br /&gt;
      #vary rubric by round&lt;br /&gt;
      rounds_num = assignment.rounds_of_reviews&lt;br /&gt;
      for round in 1..rounds_num&lt;br /&gt;
        symbol = (&amp;quot;review round&amp;quot;+round.to_s).to_sym&lt;br /&gt;
        review_final_versions[symbol] = Hash.new&lt;br /&gt;
        review_final_versions[symbol][:questionnaire_id] = assignment.get_review_questionnaire_id(round)&lt;br /&gt;
        response_ids = Array.new&lt;br /&gt;
        maps.each do |map|&lt;br /&gt;
          responses = Response.where(map_id:map.id, round:round)&lt;br /&gt;
          if !responses.empty?&lt;br /&gt;
            response_ids &amp;lt;&amp;lt; responses.last.id&lt;br /&gt;
          end&lt;br /&gt;
        end&lt;br /&gt;
        review_final_versions[symbol][:response_ids] = response_ids&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
    review_final_versions&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
&lt;br /&gt;
After refactoring:&lt;br /&gt;
&amp;lt;big&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  # wrap The latest version of responses in each response map,&lt;br /&gt;
  # together with the questionnaire_id will be used to&lt;br /&gt;
  # display the reviewer summary&lt;br /&gt;
  def self.final_versions_from_reviewer(reviewer_id)&lt;br /&gt;
    maps = ReviewResponseMap.where(reviewer_id: reviewer_id)&lt;br /&gt;
    assignment = find_assignment(Participant.find(reviewer_id).parent_id)&lt;br /&gt;
    review_final_versions = {}&lt;br /&gt;
    unless assignment.varying_rubrics_by_round?&lt;br /&gt;
      #same review rubric used in multiple rounds&lt;br /&gt;
      review_final_versions = review_final_version_responses(:review, :questionnaire_id, assignment, maps)&lt;br /&gt;
    else&lt;br /&gt;
      # vary rubric by round&lt;br /&gt;
      rounds_num = assignment.rounds_of_reviews&lt;br /&gt;
      (1..rounds_num).each do |round|&lt;br /&gt;
        symbol = ('review round' + round.to_s).to_sym&lt;br /&gt;
        review_final_versions = review_final_version_responses(symbol, :questionnaire_id, assignment, maps, round)&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
    review_final_versions&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Private methods added:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;big&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  # Compute list of responses and return it&lt;br /&gt;
  def self.review_final_version_responses(symbol, questionnaire_id, assignment, maps, round = nil)&lt;br /&gt;
    review_final_versions = {}&lt;br /&gt;
    review_final_versions[symbol] = {}&lt;br /&gt;
    review_final_versions[symbol][questionnaire_id] = assignment.get_review_questionnaire_id(round)&lt;br /&gt;
    response_ids = []&lt;br /&gt;
    maps.each do |map|&lt;br /&gt;
      responses =  get_responses(map.id, round)&lt;br /&gt;
      unless responses.empty?&lt;br /&gt;
        response_ids &amp;lt;&amp;lt; responses.last.id&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
    review_final_versions[symbol][:response_ids] = response_ids&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;big&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  #Get responses by map_id and round (if exists)&lt;br /&gt;
  def self.get_responses(id, round)&lt;br /&gt;
     if round.nil?&lt;br /&gt;
       responses = Response.where(map_id: id)&lt;br /&gt;
     else&lt;br /&gt;
       responses = Response.where(map_id: id, round: round)&lt;br /&gt;
     end	&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Refactoring of other methods ===&lt;br /&gt;
We removed the return statement from the get_title, export_fields, and show_feedback methods because return statements are unnecessary in Ruby.&lt;br /&gt;
&lt;br /&gt;
=== Addition of code comments ===&lt;br /&gt;
&lt;br /&gt;
We added comments to all of the methods in the ReviewResponseMap.rb file and corrected instances where CodeClimate Identified opportunities for code improvement.  One issue flagged by CodeClimate that we did not change was to use the find_by method instead of where().first method.  The where().first method occurs in the import, get_assignment_participant, and create_response_map methods. It is not always appropriate to use the find_by method, as documented in this github post: https://github.com/bbatsov/rubocop/issues/1938 .  In instances where ordering by id is the desired behavior, where().first will order by default, but in Rails 4+ find_by does not honor that default behavior.  For this reason we left the instances of where().first unchanged.&lt;br /&gt;
&lt;br /&gt;
=== Code Improvements ===&lt;br /&gt;
&lt;br /&gt;
This refactoring was to improve readability and follow as many good ''Rubyist'' coding practices as possible without breaking the functionality of existing code. We used CodeClimate of the master branch code as a reference. We took the suggestions we got from CodeClimate and improved our code based on that.&lt;br /&gt;
We also made some of the methods shorter by removing redundant functionality and adding private methods to methods with a lot internal functionality. We also added private methods in places where we saw repeated patterns to make the code ''DRYer''.&lt;br /&gt;
At the end of our refactoring, we managed to improve the rating on CodeClimate from a '''C''' to a '''B''' . Further improvements meant reducing the size of the entire class which required a much more significant refactoring in multiple files and folders. We focused on refactoring the existing model, '''ReviewResponseMap'''.&lt;br /&gt;
&lt;br /&gt;
= Unit Tests =&lt;br /&gt;
The previous unit tests had syntactical and run time errors.  We were not able to get the previous unit tests to run without errors.  Because of this we rewrote all of the unit tests for the &amp;lt;b&amp;gt;ReviewResponseModel&amp;lt;/b&amp;gt;.  It is important to have working unit tests so that when internal changes are made to functions the external output remains the same.&lt;br /&gt;
&lt;br /&gt;
=== Refactoring of Unit Tests===&lt;br /&gt;
&lt;br /&gt;
We added a test_helper file to the main test folder that requires a needed configuration file and needed gems.  We also added 8 fixtures that were needed for data to run the unit tests.  The following fixture files were added:&lt;br /&gt;
&lt;br /&gt;
* assignment_questionnaires.yml&lt;br /&gt;
* assignments.yml&lt;br /&gt;
* participants.yml&lt;br /&gt;
* questionnaires.yml&lt;br /&gt;
* response_maps.yml&lt;br /&gt;
* responses.yml&lt;br /&gt;
* teams.yml&lt;br /&gt;
* users.yml&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
There is at least one unit test for every public method within the &amp;lt;b&amp;gt;ReviewResponseModel&amp;lt;/b&amp;gt;.  The test naming convention used is &amp;quot;method_&amp;lt;name of method that is being tested&amp;gt;&amp;quot;.  For example, the unit test for the export method is &amp;quot;method_export&amp;quot;.  If there are multiple test for one method the name of the test will include the test case after the normal naming convention.  For example, one of the unit tests for the import method checks for an invalid assignment.  The name of this method is &amp;quot;method_import_invalid_assignment&amp;quot;.  The following are the unit tests we created:&lt;br /&gt;
&lt;br /&gt;
* method_export&lt;br /&gt;
* method_get_metareview_response_maps&lt;br /&gt;
* method_get_team_response_for_round&lt;br /&gt;
* method_final_versions_from_reviewer&lt;br /&gt;
* method_import&lt;br /&gt;
* method_import_invalid_reviewee&lt;br /&gt;
* method_import_invalid_reviewer&lt;br /&gt;
* method_import_invalid_assignment&lt;br /&gt;
* method_delete&lt;br /&gt;
* method_delete_no _force&lt;br /&gt;
* method_show_feedback&lt;br /&gt;
* method_get_title&lt;br /&gt;
* method_export_fields&lt;br /&gt;
* method_questionnaire&lt;br /&gt;
* method_add_reviewer&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== How to Run Unit Tests ===&lt;br /&gt;
To run the unit tests, follow these steps:&lt;br /&gt;
&lt;br /&gt;
# Download the master branch of the repo.&lt;br /&gt;
# Setup the Databases for the test environment (we have used Zhewei's scrubbed expertiza DB )&lt;br /&gt;
#* Run the &amp;quot; rake db:create RAILS_ENV=test &amp;quot; command&lt;br /&gt;
#* Run the &amp;quot; rake db:reset RAILS_ENV=test &amp;quot; command&lt;br /&gt;
#* Scrub the DB using &amp;quot; mysql -u root expertiza_development &amp;lt; expertiza-scrubbed.sql&amp;quot;&lt;br /&gt;
#* Run the &amp;quot; rake db:migrate &amp;quot;&lt;br /&gt;
# Run &amp;quot; rake test test/unit/review_response_map_test.rb &amp;quot; in the &amp;quot;expertiza/&amp;quot; directory.&lt;br /&gt;
#* If you run into a mysql log in error go into config/database.yml and edit the mysql credentials for the test section so that it matches the local environment's mysql configuration&lt;br /&gt;
# Check if tests passed or failed.&lt;br /&gt;
&lt;br /&gt;
= Manual Test Case =&lt;br /&gt;
&lt;br /&gt;
In order to test the changes made to the ReviewResponseMap, bring up [[ http://152.46.16.195:5902/ | Expertiza]] and log in as an administrator.  Once logged in, proceed with the following steps:&lt;br /&gt;
&lt;br /&gt;
# Go to '''impersonate user''' when logged in as ''instructor6'' and type in ''student559'' (or) just log in as ''student559''. All passwords are ''password'' .&lt;br /&gt;
# Pick any assignment to view.&lt;br /&gt;
# Navigate to '''Other's work'''.&lt;br /&gt;
# Check the different reviews and metareviews. Whether they are being displayed correctly or not.&lt;br /&gt;
# Go to Edit or Give feedback and submit a feedback.&lt;br /&gt;
# Go back and check if the feedback given is displayed correctly or not.&lt;br /&gt;
# Check if author's feedback is correct or not.&lt;br /&gt;
# Go to the '''Temp''' assignment and see if the page is being displayed correctly or not (since there is no assignment submission content or reviews for that).&lt;br /&gt;
&lt;br /&gt;
''NOTE: Since this was a refactoring of the code and methods, the existing functionality was supposed to remain the same and not break for the changes we've made.''&lt;br /&gt;
&lt;br /&gt;
= References =&lt;br /&gt;
&lt;br /&gt;
&amp;lt;references/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
= External Links =&lt;br /&gt;
&lt;br /&gt;
# [https://github.com/expertiza/expertiza Expertiza Main Repo] &amp;lt;br&amp;gt;&lt;br /&gt;
# [https://github.com/adeeshag/expertiza/blob/develop/app/models/review_response_map.rb Refactored ReviewResponseMap.rb]&amp;lt;br&amp;gt;&lt;br /&gt;
# [https://github.com/adeeshag/expertiza/tree/develop/test/fixtures Test Fixtures]&amp;lt;br&amp;gt;&lt;br /&gt;
# [https://github.com/adeeshag/expertiza/blob/develop/test/unit/review_response_map_test.rb Unit Tests]&amp;lt;br&amp;gt;&lt;br /&gt;
# [http://152.46.16.195:5902/ Expertiza Deployed Site]&amp;lt;br&amp;gt;&lt;/div&gt;</summary>
		<author><name>Cnbrown4</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2015/ossE1558BGJ&amp;diff=98478</id>
		<title>CSC/ECE 517 Fall 2015/ossE1558BGJ</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2015/ossE1558BGJ&amp;diff=98478"/>
		<updated>2015-11-06T21:47:24Z</updated>

		<summary type="html">&lt;p&gt;Cnbrown4: /* External Links */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Introduction =&lt;br /&gt;
&lt;br /&gt;
This page provides a description of the modifications and improvements made to the Expertiza project’s source code as part of an Expertiza based Open Source Software project.  Expertiza is a web based application which allows students to submit and peer-review classmates’ work, including written articles and development projects. The specific changes made during the course of this project were to the ReviewResponseMap.rb file, with additional changes made to other related files in support of refactoring ReviewResponseMap.rb.  &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
= Problem Statement =&lt;br /&gt;
&lt;br /&gt;
ReviewResponseMap is the model class used to manage the relationship between contributors, reviewers, and assignments.  The intent of the changes were to refactor the code for better readability and adherence to Ruby coding standards and best practices.  Primarily these changes involved the refactoring of overly complex methods, renaming methods for better readability, and the addition of missing unit tests.&lt;br /&gt;
&lt;br /&gt;
Project Requirements:&lt;br /&gt;
&lt;br /&gt;
# Code Climate&amp;lt;ref name=&amp;quot;Code Climate&amp;quot;&amp;gt;https://codeclimate.com&amp;lt;/ref&amp;gt; shows import method is complex, because of lots of checks. This method can be fixed by adding private methods for raising import error.&lt;br /&gt;
# Get_assessments_round_for method can be renamed to get_team_responses_for_round. Team_id private variable is not needed.&lt;br /&gt;
# metareview_response_maps rename, refactoring can be done. No need to do second iteration.&lt;br /&gt;
# write missing unit tests for existing methods.&lt;br /&gt;
&lt;br /&gt;
= Design Patterns =&lt;br /&gt;
&lt;br /&gt;
As part of our project, we refactored the model to follow the Single Responsibility and Don't Repeat Yourself (DRY) Principles.  Both of the principles focus on reducing code repetition and increasing the cohesion of the individual methods in the class.  The Single Responsibility Principle states that each class and method should have sole responsibility over one single part of the functionality of the system&amp;lt;ref&amp;gt;https://en.wikipedia.org/wiki/Single_responsibility_principle&amp;lt;/ref&amp;gt;.  The DRY principle states that whenever the same types of logic and functionality are being performed in a class the duplicated logic should be extracted into a new method that can be called in place of the repeated lines of code &amp;lt;ref&amp;gt;https://en.wikipedia.org/wiki/Don%27t_repeat_yourself&amp;lt;/ref&amp;gt;.  A prime example of a method that initially violated these principles was the import method, which in addition to performing the core import processes also performed a number of checks that would be more properly extracted into private methods.&lt;br /&gt;
&lt;br /&gt;
=Code Changes =&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Refactoring of import method ===&lt;br /&gt;
&lt;br /&gt;
CodeClimate reports showed the import method to be overly complex, with a number of checks being included within the import method itself.  The resolution for this problem was to refactor the import method, creating private methods to perform the null checks and throw import errors.  Prior to refactoring, all null checks were performed within the import method.   After refactoring, the import method adheres to the single responsibility principle, performing only key import tasks while making calls to private methods for any necessary validation. The size of the import method was reduced by doing this and counts for better readability of the code. Also, this method is a very important one and care was taken so that any existing functionality did not break. &lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
Before refactoring:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;big&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 def self.import(row, session, id)&lt;br /&gt;
    if row.length &amp;lt; 2&lt;br /&gt;
      raise ArgumentError, &amp;quot;Not enough items&amp;quot;&lt;br /&gt;
    end&lt;br /&gt;
    assignment = Assignment.find(id)&lt;br /&gt;
    if assignment.nil?&lt;br /&gt;
      raise ImportError, &amp;quot;The assignment with id \&amp;quot;#{id}\&amp;quot; was not found. &amp;lt;a href='/assignment/new'&amp;gt;Create&amp;lt;/a&amp;gt; this assignment?&amp;quot;&lt;br /&gt;
    end&lt;br /&gt;
    index = 1&lt;br /&gt;
    while index &amp;lt; row.length&lt;br /&gt;
      user = User.find_by_name(row[index].to_s.strip)&lt;br /&gt;
      if user.nil?&lt;br /&gt;
        raise ImportError, &amp;quot;The user account for the reviewer \&amp;quot;#{row[index]}\&amp;quot; was not found. &amp;lt;a href='/users/new'&amp;gt;Create&amp;lt;/a&amp;gt; this user?&amp;quot;&lt;br /&gt;
      end&lt;br /&gt;
      reviewer = AssignmentParticipant.where(user_id: user.id, parent_id:  assignment.id).first&lt;br /&gt;
      if reviewer == nil&lt;br /&gt;
        raise ImportError, &amp;quot;The reviewer \&amp;quot;#{row[index]}\&amp;quot; is not a participant in this assignment. &amp;lt;a href='/users/new'&amp;gt;Register&amp;lt;/a&amp;gt; this user as a participant?&amp;quot;&lt;br /&gt;
      end&lt;br /&gt;
      if assignment.team_assignment&lt;br /&gt;
        reviewee = AssignmentTeam.where(name: row[0].to_s.strip, parent_id:  assignment.id).first&lt;br /&gt;
        if reviewee == nil&lt;br /&gt;
          raise ImportError, &amp;quot;The author \&amp;quot;#{row[0].to_s.strip}\&amp;quot; was not found. &amp;lt;a href='/users/new'&amp;gt;Create&amp;lt;/a&amp;gt; this user?&amp;quot;&lt;br /&gt;
        end&lt;br /&gt;
        existing = ReviewResponseMap.where(reviewee_id: reviewee.id, reviewer_id:  reviewer.id).first&lt;br /&gt;
        if existing.nil?&lt;br /&gt;
          ReviewResponseMap.create(:reviewer_id =&amp;gt; reviewer.id, :reviewee_id =&amp;gt; reviewee.id, :reviewed_object_id =&amp;gt; assignment.id)&lt;br /&gt;
        end&lt;br /&gt;
      else&lt;br /&gt;
        puser = User.find_by_name(row[0].to_s.strip)&lt;br /&gt;
        if user == nil&lt;br /&gt;
          raise ImportError, &amp;quot;The user account for the reviewee \&amp;quot;#{row[0]}\&amp;quot; was not found. &amp;lt;a href='/users/new'&amp;gt;Create&amp;lt;/a&amp;gt; this user?&amp;quot;&lt;br /&gt;
        end&lt;br /&gt;
        reviewee = AssignmentParticipant.where(user_id: puser.id, parent_id:  assignment.id).first&lt;br /&gt;
        if reviewee == nil&lt;br /&gt;
          raise ImportError, &amp;quot;The author \&amp;quot;#{row[0].to_s.strip}\&amp;quot; was not found. &amp;lt;a href='/users/new'&amp;gt;Create&amp;lt;/a&amp;gt; this user?&amp;quot;&lt;br /&gt;
        end&lt;br /&gt;
        team_id = TeamsUser.team_id(reviewee.parent_id, reviewee.user_id)&lt;br /&gt;
        existing = ReviewResponseMap.where(reviewee_id: team_id, reviewer_id:  reviewer.id).first&lt;br /&gt;
        if existing.nil?&lt;br /&gt;
          ReviewResponseMap.create(:reviewee_id =&amp;gt; team_id, :reviewer_id =&amp;gt; reviewer.id, :reviewed_object_id =&amp;gt; assignment.id)&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
      index += 1&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
&lt;br /&gt;
After refactoring:&lt;br /&gt;
 &lt;br /&gt;
  &amp;lt;big&amp;gt;&amp;lt;nowiki&amp;gt;#Imports new reponse maps if they do not already exist&lt;br /&gt;
  def self.import(row, _session, id)&lt;br /&gt;
      if row.length &amp;lt; 2&lt;br /&gt;
          raise ArgumentError, 'Not enough items'&lt;br /&gt;
      end&lt;br /&gt;
      assignment = find_assignment(id)&lt;br /&gt;
      index = 1&lt;br /&gt;
      reviewee_name = row[0]&lt;br /&gt;
      while index &amp;lt; row.length&lt;br /&gt;
          reviewee_id = nil&lt;br /&gt;
          reviewer_name = row[index]&lt;br /&gt;
          reviewer = get_assignment_participant(reviewer_name,  assignment.id, &amp;quot;reviewer&amp;quot;)&lt;br /&gt;
          participant_nil?(reviewer, reviewer_name , &amp;quot;reviewer&amp;quot;)&lt;br /&gt;
         &lt;br /&gt;
         #Find reviewee if assignment is a team assignment&lt;br /&gt;
         if assignment.team_assignment&lt;br /&gt;
             reviewee = AssignmentTeam.where(name: reviewee_name .to_s.strip, parent_id: assignment.id).first&lt;br /&gt;
             participant_nil?(reviewee, reviewee_name, &amp;quot;author&amp;quot;)&lt;br /&gt;
             reviewee_id = reviewee.id&lt;br /&gt;
         #Find reviewee if assignment is not a team assignment&lt;br /&gt;
         else&lt;br /&gt;
	     reviewee = get_assignment_participant(reviewee_name, assignment.id, &amp;quot;reviewee&amp;quot;)&lt;br /&gt;
             participant_nil?(reviewee, reviewee_name, &amp;quot;author&amp;quot;)&lt;br /&gt;
             reviewee_id  = TeamsUser.team_id(reviewee.parent_id, reviewee.user_id)&lt;br /&gt;
         end&lt;br /&gt;
         create_response_map(reviewer, reviewee_id,  assignment)&lt;br /&gt;
         index += 1&lt;br /&gt;
      end&lt;br /&gt;
  end&amp;lt;/nowiki&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Private methods added:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;big&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  # Check for if assignment value is null&lt;br /&gt;
  def self.find_assignment(id)&lt;br /&gt;
      begin&lt;br /&gt;
          assignment = Assignment.find(id)&lt;br /&gt;
      rescue ActiveRecord::RecordNotFound&lt;br /&gt;
          raise ImportError, &amp;quot;The assignment with id \&amp;quot;#{id}\&amp;quot; was not found.&amp;lt;a href='/assignment/new'&amp;gt;Create&amp;lt;/a&amp;gt; this assignment?&amp;quot;&lt;br /&gt;
      end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  # Check for if participant is null&lt;br /&gt;
  def self.participant_nil?(participant, user_name, participant_type) &lt;br /&gt;
      error_message = nil&lt;br /&gt;
      if participant_type == &amp;quot;author&amp;quot;&lt;br /&gt;
          error_message = &amp;quot;The author \&amp;quot;#{user_name.to_s.strip}\&amp;quot; was not found.&amp;lt;a href='/users/new'&amp;gt;Create&amp;lt;/a&amp;gt; this user?&amp;quot;&lt;br /&gt;
      else&lt;br /&gt;
          error_message =  &amp;quot;The reviewer \&amp;quot;#{user_name}\&amp;quot; is not a participant in this assignment.&amp;lt;a href='/users/new'&amp;gt;Register&amp;lt;/a&amp;gt; this user as a participant?&amp;quot;&lt;br /&gt;
      end&lt;br /&gt;
      check_nil?(participant, error_message)&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  # Check for if user is null&lt;br /&gt;
  def self.user_nil?(user, user_name, user_type)&lt;br /&gt;
      check_nil?( user, &amp;quot;The user account for the \&amp;quot;#{user_type}\&amp;quot; \&amp;quot;#{user_name}\&amp;quot; was not found.&amp;lt;a href='/users/new'&amp;gt;Create&amp;lt;/a&amp;gt; this user?&amp;quot;)&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
 #Throws import error for nil objects&lt;br /&gt;
  def self.check_nil?(object, error_message)&lt;br /&gt;
      if object.nil?&lt;br /&gt;
          raise ImportError, error_message&lt;br /&gt;
      end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Refactoring of get_assessments_round_for method ===&lt;br /&gt;
&lt;br /&gt;
The get_assessments_round_for method’s name failed to provide a clear idea of the method’s purpose and functionality.  This is why it was renamed to get_team_responses_for_round, the new name of the method provides a clearer idea of its purpose. Additionally, there was a private variable, team_id, introduced in the method that was unnecessary and could be replaced by using the id property of the team parameter directly.  We also removed the return statement at the end of the method.  &lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
Before refactoring:&lt;br /&gt;
&amp;lt;big&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  def self.get_assessments_round_for(team,round)&lt;br /&gt;
    team_id =team.id&lt;br /&gt;
    responses = Array.new&lt;br /&gt;
    if team_id&lt;br /&gt;
      maps = ResponseMap.where(:reviewee_id =&amp;gt; team_id, :type =&amp;gt; &amp;quot;ReviewResponseMap&amp;quot;)&lt;br /&gt;
      maps.each{ |map|&lt;br /&gt;
        if !map.response.empty? &amp;amp;&amp;amp; !map.response.reject{|r| r.round!=round}.empty?&lt;br /&gt;
          responses &amp;lt;&amp;lt; map.response.reject{|r| r.round!=round}.last&lt;br /&gt;
        end&lt;br /&gt;
      }&lt;br /&gt;
      responses.sort! {|a,b| a.map.reviewer.fullname &amp;lt;=&amp;gt; b.map.reviewer.fullname }&lt;br /&gt;
    end&lt;br /&gt;
    return responses&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
&lt;br /&gt;
After refactoring: &lt;br /&gt;
&lt;br /&gt;
&amp;lt;big&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  # return the responses for specified round,&lt;br /&gt;
  # for varying rubric feature -Yang&lt;br /&gt;
  def self.get_team_responses_for_round(team, round)&lt;br /&gt;
    responses = []&lt;br /&gt;
    if team.id&lt;br /&gt;
      maps = ResponseMap.where(reviewee_id: team.id, type: 'ReviewResponseMap')&lt;br /&gt;
      maps.each do |map|&lt;br /&gt;
        unless map.response.empty? &amp;amp;&amp;amp; map.response.reject { |r| r.round != round }.empty?&lt;br /&gt;
          responses &amp;lt;&amp;lt; map.response.reject { |r| r.round != round }.last&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
      responses.sort! { |a, b| a.map.reviewer.fullname &amp;lt;=&amp;gt; b.map.reviewer.fullname }&lt;br /&gt;
    end&lt;br /&gt;
    responses&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
The change in method name also required changes to the following files that referenced it:&lt;br /&gt;
&lt;br /&gt;
/app/models/assignment.rb:436:    &lt;br /&gt;
 &lt;br /&gt;
&amp;lt;big&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  assessments = ReviewResponseMap.get_assessments_round_for(team,i)&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt; &lt;br /&gt;
&lt;br /&gt;
./app/models/assignment_participant.rb:268:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;big&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 scores[questionnaire_symbol][:assessments] = questionnaire.get_assessments_round_for(self,round)&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Refactoring of metareview_response_maps method ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The metareview_response_maps method was unnecessarily complex.  It contained an unneeded private variable and an unnecessary nested loop.  Originally, it added each metareview map individually in the nested loop.  We decided to remove the nested loop and use the concat method for readability and maintainability.  These changes allowed us to remove the private variable &amp;quot;metareview_list&amp;quot; and only maintain the &amp;quot;metareview_response_maps&amp;quot; variable.  We also renamed the metareview_response_maps method to get_metareview_response_maps method to be more descriptive about the intent of the method. &lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
Before refactoring:&lt;br /&gt;
&amp;lt;big&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 def metareview_response_maps&lt;br /&gt;
    responses = Response.where(map_id:self.id)&lt;br /&gt;
    metareview_list=[]&lt;br /&gt;
    responses.each do |response|&lt;br /&gt;
      metareview_response_maps = MetareviewResponseMap.where(reviewed_object_id:response.id)&lt;br /&gt;
      metareview_response_maps.each do |metareview_response_map|&lt;br /&gt;
        metareview_list&amp;lt;&amp;lt;metareview_response_map&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
    metareview_list&lt;br /&gt;
 end&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
After refactoring:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;big&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  # Returns the response maps for all the metareviews&lt;br /&gt;
  def get_metareview_response_maps&lt;br /&gt;
    responses = Response.where(map_id: id)&lt;br /&gt;
    metareview_response_maps = []&lt;br /&gt;
    responses.each do |response|&lt;br /&gt;
      metareview_response_maps.concat MetareviewResponseMap.where(reviewed_object_id: response.id)&lt;br /&gt;
    end&lt;br /&gt;
    metareview_response_maps&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Refactoring of export method ===&lt;br /&gt;
The export method contained mappings.sort! { |a, b| a.reviewee.name &amp;lt;=&amp;gt; b.reviewee.name }.  We could not get past this when running tests, we kept getting a message saying, &amp;quot;sort! was not a method for an ActiveRecord_Relation&amp;quot;.  But, ActiveRecord_Relation does allow the use of sort.  So we changed that line of code to  mappings = mappings.sort { |a, b| a.reviewee.name &amp;lt;=&amp;gt; b.reviewee.name }&lt;br /&gt;
&lt;br /&gt;
Before refactoring:&lt;br /&gt;
&amp;lt;big&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  def self.export(csv, parent_id, options)&lt;br /&gt;
    mappings = where(reviewed_object_id: parent_id)&lt;br /&gt;
    mappings.sort! { |a, b| a.reviewee.name &amp;lt;=&amp;gt; b.reviewee.name }&lt;br /&gt;
    mappings.each {&lt;br /&gt;
      |map|&lt;br /&gt;
      csv &amp;lt;&amp;lt; [&lt;br /&gt;
        map.reviewee.name,&lt;br /&gt;
        map.reviewer.name&lt;br /&gt;
      ]&lt;br /&gt;
    }&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
&lt;br /&gt;
After refactoring:&lt;br /&gt;
&amp;lt;big&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  # options parameter used as a signature in other models&lt;br /&gt;
  def self.export(csv, parent_id, options)&lt;br /&gt;
    mappings = where(reviewed_object_id: parent_id)&lt;br /&gt;
    mappings = mappings.sort { |a, b| a.reviewee.name &amp;lt;=&amp;gt; b.reviewee.name }&lt;br /&gt;
    mappings.each do&lt;br /&gt;
    |map|&lt;br /&gt;
      csv &amp;lt;&amp;lt; [map.reviewee.name, map.reviewer.name]&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Refactoring of final_versions_from_reviewer method ===&lt;br /&gt;
The final_versions_from_reviewer method was too long and repetitive.  We removed common functionality from within the if and else statement and put it in a private method final_versions_from_reviewer.  Then we created the get_responses method to find the responses based on the arguments values.  These private methods make the class more readable for other programmers.&lt;br /&gt;
 &lt;br /&gt;
Before refactoring:&lt;br /&gt;
&amp;lt;big&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  def self.final_versions_from_reviewer(reviewer_id)&lt;br /&gt;
    maps = ReviewResponseMap.where(reviewer_id: reviewer_id)&lt;br /&gt;
    assignment = Assignment.find(Participant.find(reviewer_id).parent_id)&lt;br /&gt;
    review_final_versions = Hash.new&lt;br /&gt;
    if !assignment.varying_rubrics_by_round?&lt;br /&gt;
      #same review rubric used in multiple rounds&lt;br /&gt;
      review_final_versions[:review] = Hash.new&lt;br /&gt;
      review_final_versions[:review][:questionnaire_id] = assignment.get_review_questionnaire_id&lt;br /&gt;
      response_ids = Array.new&lt;br /&gt;
      maps.each do |map|&lt;br /&gt;
        responses = Response.where(map_id:map.id)&lt;br /&gt;
        if !responses.empty?&lt;br /&gt;
          response_ids &amp;lt;&amp;lt; responses.last.id&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
      review_final_versions[:review][:response_ids] = response_ids&lt;br /&gt;
    else&lt;br /&gt;
      #vary rubric by round&lt;br /&gt;
      rounds_num = assignment.rounds_of_reviews&lt;br /&gt;
      for round in 1..rounds_num&lt;br /&gt;
        symbol = (&amp;quot;review round&amp;quot;+round.to_s).to_sym&lt;br /&gt;
        review_final_versions[symbol] = Hash.new&lt;br /&gt;
        review_final_versions[symbol][:questionnaire_id] = assignment.get_review_questionnaire_id(round)&lt;br /&gt;
        response_ids = Array.new&lt;br /&gt;
        maps.each do |map|&lt;br /&gt;
          responses = Response.where(map_id:map.id, round:round)&lt;br /&gt;
          if !responses.empty?&lt;br /&gt;
            response_ids &amp;lt;&amp;lt; responses.last.id&lt;br /&gt;
          end&lt;br /&gt;
        end&lt;br /&gt;
        review_final_versions[symbol][:response_ids] = response_ids&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
    review_final_versions&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
&lt;br /&gt;
After refactoring:&lt;br /&gt;
&amp;lt;big&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  # wrap The latest version of responses in each response map,&lt;br /&gt;
  # together with the questionnaire_id will be used to&lt;br /&gt;
  # display the reviewer summary&lt;br /&gt;
  def self.final_versions_from_reviewer(reviewer_id)&lt;br /&gt;
    maps = ReviewResponseMap.where(reviewer_id: reviewer_id)&lt;br /&gt;
    assignment = find_assignment(Participant.find(reviewer_id).parent_id)&lt;br /&gt;
    review_final_versions = {}&lt;br /&gt;
    unless assignment.varying_rubrics_by_round?&lt;br /&gt;
      #same review rubric used in multiple rounds&lt;br /&gt;
      review_final_versions = review_final_version_responses(:review, :questionnaire_id, assignment, maps)&lt;br /&gt;
    else&lt;br /&gt;
      # vary rubric by round&lt;br /&gt;
      rounds_num = assignment.rounds_of_reviews&lt;br /&gt;
      (1..rounds_num).each do |round|&lt;br /&gt;
        symbol = ('review round' + round.to_s).to_sym&lt;br /&gt;
        review_final_versions = review_final_version_responses(symbol, :questionnaire_id, assignment, maps, round)&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
    review_final_versions&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Private methods added:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;big&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  # Compute list of responses and return it&lt;br /&gt;
  def self.review_final_version_responses(symbol, questionnaire_id, assignment, maps, round = nil)&lt;br /&gt;
    review_final_versions = {}&lt;br /&gt;
    review_final_versions[symbol] = {}&lt;br /&gt;
    review_final_versions[symbol][questionnaire_id] = assignment.get_review_questionnaire_id(round)&lt;br /&gt;
    response_ids = []&lt;br /&gt;
    maps.each do |map|&lt;br /&gt;
      responses =  get_responses(map.id, round)&lt;br /&gt;
      unless responses.empty?&lt;br /&gt;
        response_ids &amp;lt;&amp;lt; responses.last.id&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
    review_final_versions[symbol][:response_ids] = response_ids&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;big&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  #Get responses by map_id and round (if exists)&lt;br /&gt;
  def self.get_responses(id, round)&lt;br /&gt;
     if round.nil?&lt;br /&gt;
       responses = Response.where(map_id: id)&lt;br /&gt;
     else&lt;br /&gt;
       responses = Response.where(map_id: id, round: round)&lt;br /&gt;
     end	&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Refactoring of other methods ===&lt;br /&gt;
Although trivial, we removed the return statement from the get_title, export_fields, and show_feedback methods because return statements are unnecessary in Ruby.&lt;br /&gt;
&lt;br /&gt;
=== Addition of code comments ===&lt;br /&gt;
&lt;br /&gt;
We added comments to all of the methods in the ReviewResponseMap.rb file and corrected instances where CodeClimate Identified opportunities for code improvement.  One issue flagged by CodeClimate that we did not change was to use the find_by method instead of where().first method.  The where().first method occurs in the import, get_assignment_participant, and create_response_map methods. It is not always appropriate to use the find_by method, as documented in this github post: https://github.com/bbatsov/rubocop/issues/1938 .  In instances where ordering by id is the desired behavior, where().first will order by default, but in Rails 4+ find_by does not honor that default behavior.  For this reason we left the instances of where().first unchanged.&lt;br /&gt;
&lt;br /&gt;
=== Code Improvements ===&lt;br /&gt;
&lt;br /&gt;
This refactoring was to improve readability and follow as many good ''Rubyist'' coding practices as possible without breaking the functionality of existing code. We used CodeClimate of the master branch code as a reference. We took the suggestions we got from CodeClimate and improved our code based on that.&lt;br /&gt;
We also made some of the methods shorter by removing redundant functionality and adding private methods to methods with a lot internal functionality. We also added private methods in places where we saw repeated patterns to make the code ''DRYer''.&lt;br /&gt;
At the end of our refactoring, we managed to improve the rating on CodeClimate from a '''C''' to a '''B''' . Further improvements meant reducing the size of the entire class which required a much more significant refactoring in multiple files and folders. We focused on refactoring the existing model, '''ReviewResponseMap'''.&lt;br /&gt;
&lt;br /&gt;
= Unit Tests =&lt;br /&gt;
The previous unit tests had syntactical and run time errors.  We were not able to get the previous unit tests to run without errors.  Because of this we rewrote all of the unit tests for the &amp;lt;b&amp;gt;ReviewResponseModel&amp;lt;/b&amp;gt;.  It is important to have working unit tests so that when internal changes are made to functions the external output remains the same.&lt;br /&gt;
&lt;br /&gt;
=== Refactoring of Unit Tests===&lt;br /&gt;
&lt;br /&gt;
We added a test_helper file to the main test folder that requires a needed configuration file and needed gems.  We also added 8 fixtures that were needed for data to run the unit tests.  The following fixture files were added:&lt;br /&gt;
&lt;br /&gt;
* assignment_questionnaires.yml&lt;br /&gt;
* assignments.yml&lt;br /&gt;
* participants.yml&lt;br /&gt;
* questionnaires.yml&lt;br /&gt;
* response_maps.yml&lt;br /&gt;
* responses.yml&lt;br /&gt;
* teams.yml&lt;br /&gt;
* users.yml&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
There is at least one unit test for every public method within the &amp;lt;b&amp;gt;ReviewResponseModel&amp;lt;/b&amp;gt;.  The test naming convention used is &amp;quot;method_&amp;lt;name of method that is being tested&amp;gt;&amp;quot;.  For example, the unit test for the export method is &amp;quot;method_export&amp;quot;.  If there are multiple test for one method the name of the test will include the test case after the normal naming convention.  For example, one of the unit tests for the import method checks for an invalid assignment.  The name of this method is &amp;quot;method_import_invalid_assignment&amp;quot;.  The following are the unit tests we created:&lt;br /&gt;
&lt;br /&gt;
* method_export&lt;br /&gt;
* method_get_metareview_response_maps&lt;br /&gt;
* method_get_team_response_for_round&lt;br /&gt;
* method_final_versions_from_reviewer&lt;br /&gt;
* method_import&lt;br /&gt;
* method_import_invalid_reviewee&lt;br /&gt;
* method_import_invalid_reviewer&lt;br /&gt;
* method_import_invalid_assignment&lt;br /&gt;
* method_delete&lt;br /&gt;
* method_delete_no _force&lt;br /&gt;
* method_show_feedback&lt;br /&gt;
* method_get_title&lt;br /&gt;
* method_export_fields&lt;br /&gt;
* method_questionnaire&lt;br /&gt;
* method_add_reviewer&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== How to Run Unit Tests ===&lt;br /&gt;
To run the unit tests, follow these steps:&lt;br /&gt;
&lt;br /&gt;
# Download the master branch of the repo.&lt;br /&gt;
# Setup the Databases for the test environment (we have used Zhewei's scrubbed expertiza DB )&lt;br /&gt;
#* Run the &amp;quot; rake db:create RAILS_ENV=test &amp;quot; command&lt;br /&gt;
#* Run the &amp;quot; rake db:reset RAILS_ENV=test &amp;quot; command&lt;br /&gt;
#* Scrub the DB using &amp;quot; mysql -u root expertiza_development &amp;lt; expertiza-scrubbed.sql&amp;quot;&lt;br /&gt;
#* Run the &amp;quot; rake db:migrate &amp;quot;&lt;br /&gt;
# Run &amp;quot; rake test test/unit/review_response_map_test.rb &amp;quot; in the &amp;quot;expertiza/&amp;quot; directory.&lt;br /&gt;
#* If you run into a mysql log in error go into config/database.yml and edit the mysql credentials for the test section so that it matches the local environment's mysql configuration&lt;br /&gt;
# Check if tests passed or failed.&lt;br /&gt;
&lt;br /&gt;
= Manual Test Case =&lt;br /&gt;
&lt;br /&gt;
In order to test the changes made to the ReviewResponseMap, bring up [[ http://152.46.16.195:5902/ | Expertiza]] and log in as an administrator.  Once logged in, proceed with the following steps:&lt;br /&gt;
&lt;br /&gt;
# Go to '''impersonate user''' when logged in as ''instructor6'' and type in ''student559'' (or) just log in as ''student559''. All passwords are ''password'' .&lt;br /&gt;
# Pick any assignment to view.&lt;br /&gt;
# Navigate to '''Other's work'''.&lt;br /&gt;
# Check the different reviews and metareviews. Whether they are being displayed correctly or not.&lt;br /&gt;
# Go to Edit or Give feedback and submit a feedback.&lt;br /&gt;
# Go back and check if the feedback given is displayed correctly or not.&lt;br /&gt;
# Check if author's feedback is correct or not.&lt;br /&gt;
# Go to the '''Temp''' assignment and see if the page is being displayed correctly or not (since there is no assignment submission content or reviews for that).&lt;br /&gt;
&lt;br /&gt;
''NOTE: Since this was a refactoring of the code and methods, the existing functionality was supposed to remain the same and not break for the changes we've made.''&lt;br /&gt;
&lt;br /&gt;
= References =&lt;br /&gt;
&lt;br /&gt;
&amp;lt;references/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
= External Links =&lt;br /&gt;
&lt;br /&gt;
# [https://github.com/expertiza/expertiza Expertiza Main Repo] &amp;lt;br&amp;gt;&lt;br /&gt;
# [https://github.com/adeeshag/expertiza/blob/develop/app/models/review_response_map.rb Refactored ReviewResponseMap.rb]&amp;lt;br&amp;gt;&lt;br /&gt;
# [https://github.com/adeeshag/expertiza/tree/develop/test/fixtures Test Fixtures]&amp;lt;br&amp;gt;&lt;br /&gt;
# [https://github.com/adeeshag/expertiza/blob/develop/test/unit/review_response_map_test.rb Unit Tests]&amp;lt;br&amp;gt;&lt;br /&gt;
# [http://152.46.16.195:5902/ Expertiza Deployed Site]&amp;lt;br&amp;gt;&lt;/div&gt;</summary>
		<author><name>Cnbrown4</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2015/ossE1558BGJ&amp;diff=98477</id>
		<title>CSC/ECE 517 Fall 2015/ossE1558BGJ</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2015/ossE1558BGJ&amp;diff=98477"/>
		<updated>2015-11-06T21:46:53Z</updated>

		<summary type="html">&lt;p&gt;Cnbrown4: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Introduction =&lt;br /&gt;
&lt;br /&gt;
This page provides a description of the modifications and improvements made to the Expertiza project’s source code as part of an Expertiza based Open Source Software project.  Expertiza is a web based application which allows students to submit and peer-review classmates’ work, including written articles and development projects. The specific changes made during the course of this project were to the ReviewResponseMap.rb file, with additional changes made to other related files in support of refactoring ReviewResponseMap.rb.  &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
= Problem Statement =&lt;br /&gt;
&lt;br /&gt;
ReviewResponseMap is the model class used to manage the relationship between contributors, reviewers, and assignments.  The intent of the changes were to refactor the code for better readability and adherence to Ruby coding standards and best practices.  Primarily these changes involved the refactoring of overly complex methods, renaming methods for better readability, and the addition of missing unit tests.&lt;br /&gt;
&lt;br /&gt;
Project Requirements:&lt;br /&gt;
&lt;br /&gt;
# Code Climate&amp;lt;ref name=&amp;quot;Code Climate&amp;quot;&amp;gt;https://codeclimate.com&amp;lt;/ref&amp;gt; shows import method is complex, because of lots of checks. This method can be fixed by adding private methods for raising import error.&lt;br /&gt;
# Get_assessments_round_for method can be renamed to get_team_responses_for_round. Team_id private variable is not needed.&lt;br /&gt;
# metareview_response_maps rename, refactoring can be done. No need to do second iteration.&lt;br /&gt;
# write missing unit tests for existing methods.&lt;br /&gt;
&lt;br /&gt;
= Design Patterns =&lt;br /&gt;
&lt;br /&gt;
As part of our project, we refactored the model to follow the Single Responsibility and Don't Repeat Yourself (DRY) Principles.  Both of the principles focus on reducing code repetition and increasing the cohesion of the individual methods in the class.  The Single Responsibility Principle states that each class and method should have sole responsibility over one single part of the functionality of the system&amp;lt;ref&amp;gt;https://en.wikipedia.org/wiki/Single_responsibility_principle&amp;lt;/ref&amp;gt;.  The DRY principle states that whenever the same types of logic and functionality are being performed in a class the duplicated logic should be extracted into a new method that can be called in place of the repeated lines of code &amp;lt;ref&amp;gt;https://en.wikipedia.org/wiki/Don%27t_repeat_yourself&amp;lt;/ref&amp;gt;.  A prime example of a method that initially violated these principles was the import method, which in addition to performing the core import processes also performed a number of checks that would be more properly extracted into private methods.&lt;br /&gt;
&lt;br /&gt;
=Code Changes =&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Refactoring of import method ===&lt;br /&gt;
&lt;br /&gt;
CodeClimate reports showed the import method to be overly complex, with a number of checks being included within the import method itself.  The resolution for this problem was to refactor the import method, creating private methods to perform the null checks and throw import errors.  Prior to refactoring, all null checks were performed within the import method.   After refactoring, the import method adheres to the single responsibility principle, performing only key import tasks while making calls to private methods for any necessary validation. The size of the import method was reduced by doing this and counts for better readability of the code. Also, this method is a very important one and care was taken so that any existing functionality did not break. &lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
Before refactoring:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;big&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 def self.import(row, session, id)&lt;br /&gt;
    if row.length &amp;lt; 2&lt;br /&gt;
      raise ArgumentError, &amp;quot;Not enough items&amp;quot;&lt;br /&gt;
    end&lt;br /&gt;
    assignment = Assignment.find(id)&lt;br /&gt;
    if assignment.nil?&lt;br /&gt;
      raise ImportError, &amp;quot;The assignment with id \&amp;quot;#{id}\&amp;quot; was not found. &amp;lt;a href='/assignment/new'&amp;gt;Create&amp;lt;/a&amp;gt; this assignment?&amp;quot;&lt;br /&gt;
    end&lt;br /&gt;
    index = 1&lt;br /&gt;
    while index &amp;lt; row.length&lt;br /&gt;
      user = User.find_by_name(row[index].to_s.strip)&lt;br /&gt;
      if user.nil?&lt;br /&gt;
        raise ImportError, &amp;quot;The user account for the reviewer \&amp;quot;#{row[index]}\&amp;quot; was not found. &amp;lt;a href='/users/new'&amp;gt;Create&amp;lt;/a&amp;gt; this user?&amp;quot;&lt;br /&gt;
      end&lt;br /&gt;
      reviewer = AssignmentParticipant.where(user_id: user.id, parent_id:  assignment.id).first&lt;br /&gt;
      if reviewer == nil&lt;br /&gt;
        raise ImportError, &amp;quot;The reviewer \&amp;quot;#{row[index]}\&amp;quot; is not a participant in this assignment. &amp;lt;a href='/users/new'&amp;gt;Register&amp;lt;/a&amp;gt; this user as a participant?&amp;quot;&lt;br /&gt;
      end&lt;br /&gt;
      if assignment.team_assignment&lt;br /&gt;
        reviewee = AssignmentTeam.where(name: row[0].to_s.strip, parent_id:  assignment.id).first&lt;br /&gt;
        if reviewee == nil&lt;br /&gt;
          raise ImportError, &amp;quot;The author \&amp;quot;#{row[0].to_s.strip}\&amp;quot; was not found. &amp;lt;a href='/users/new'&amp;gt;Create&amp;lt;/a&amp;gt; this user?&amp;quot;&lt;br /&gt;
        end&lt;br /&gt;
        existing = ReviewResponseMap.where(reviewee_id: reviewee.id, reviewer_id:  reviewer.id).first&lt;br /&gt;
        if existing.nil?&lt;br /&gt;
          ReviewResponseMap.create(:reviewer_id =&amp;gt; reviewer.id, :reviewee_id =&amp;gt; reviewee.id, :reviewed_object_id =&amp;gt; assignment.id)&lt;br /&gt;
        end&lt;br /&gt;
      else&lt;br /&gt;
        puser = User.find_by_name(row[0].to_s.strip)&lt;br /&gt;
        if user == nil&lt;br /&gt;
          raise ImportError, &amp;quot;The user account for the reviewee \&amp;quot;#{row[0]}\&amp;quot; was not found. &amp;lt;a href='/users/new'&amp;gt;Create&amp;lt;/a&amp;gt; this user?&amp;quot;&lt;br /&gt;
        end&lt;br /&gt;
        reviewee = AssignmentParticipant.where(user_id: puser.id, parent_id:  assignment.id).first&lt;br /&gt;
        if reviewee == nil&lt;br /&gt;
          raise ImportError, &amp;quot;The author \&amp;quot;#{row[0].to_s.strip}\&amp;quot; was not found. &amp;lt;a href='/users/new'&amp;gt;Create&amp;lt;/a&amp;gt; this user?&amp;quot;&lt;br /&gt;
        end&lt;br /&gt;
        team_id = TeamsUser.team_id(reviewee.parent_id, reviewee.user_id)&lt;br /&gt;
        existing = ReviewResponseMap.where(reviewee_id: team_id, reviewer_id:  reviewer.id).first&lt;br /&gt;
        if existing.nil?&lt;br /&gt;
          ReviewResponseMap.create(:reviewee_id =&amp;gt; team_id, :reviewer_id =&amp;gt; reviewer.id, :reviewed_object_id =&amp;gt; assignment.id)&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
      index += 1&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
&lt;br /&gt;
After refactoring:&lt;br /&gt;
 &lt;br /&gt;
  &amp;lt;big&amp;gt;&amp;lt;nowiki&amp;gt;#Imports new reponse maps if they do not already exist&lt;br /&gt;
  def self.import(row, _session, id)&lt;br /&gt;
      if row.length &amp;lt; 2&lt;br /&gt;
          raise ArgumentError, 'Not enough items'&lt;br /&gt;
      end&lt;br /&gt;
      assignment = find_assignment(id)&lt;br /&gt;
      index = 1&lt;br /&gt;
      reviewee_name = row[0]&lt;br /&gt;
      while index &amp;lt; row.length&lt;br /&gt;
          reviewee_id = nil&lt;br /&gt;
          reviewer_name = row[index]&lt;br /&gt;
          reviewer = get_assignment_participant(reviewer_name,  assignment.id, &amp;quot;reviewer&amp;quot;)&lt;br /&gt;
          participant_nil?(reviewer, reviewer_name , &amp;quot;reviewer&amp;quot;)&lt;br /&gt;
         &lt;br /&gt;
         #Find reviewee if assignment is a team assignment&lt;br /&gt;
         if assignment.team_assignment&lt;br /&gt;
             reviewee = AssignmentTeam.where(name: reviewee_name .to_s.strip, parent_id: assignment.id).first&lt;br /&gt;
             participant_nil?(reviewee, reviewee_name, &amp;quot;author&amp;quot;)&lt;br /&gt;
             reviewee_id = reviewee.id&lt;br /&gt;
         #Find reviewee if assignment is not a team assignment&lt;br /&gt;
         else&lt;br /&gt;
	     reviewee = get_assignment_participant(reviewee_name, assignment.id, &amp;quot;reviewee&amp;quot;)&lt;br /&gt;
             participant_nil?(reviewee, reviewee_name, &amp;quot;author&amp;quot;)&lt;br /&gt;
             reviewee_id  = TeamsUser.team_id(reviewee.parent_id, reviewee.user_id)&lt;br /&gt;
         end&lt;br /&gt;
         create_response_map(reviewer, reviewee_id,  assignment)&lt;br /&gt;
         index += 1&lt;br /&gt;
      end&lt;br /&gt;
  end&amp;lt;/nowiki&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Private methods added:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;big&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  # Check for if assignment value is null&lt;br /&gt;
  def self.find_assignment(id)&lt;br /&gt;
      begin&lt;br /&gt;
          assignment = Assignment.find(id)&lt;br /&gt;
      rescue ActiveRecord::RecordNotFound&lt;br /&gt;
          raise ImportError, &amp;quot;The assignment with id \&amp;quot;#{id}\&amp;quot; was not found.&amp;lt;a href='/assignment/new'&amp;gt;Create&amp;lt;/a&amp;gt; this assignment?&amp;quot;&lt;br /&gt;
      end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  # Check for if participant is null&lt;br /&gt;
  def self.participant_nil?(participant, user_name, participant_type) &lt;br /&gt;
      error_message = nil&lt;br /&gt;
      if participant_type == &amp;quot;author&amp;quot;&lt;br /&gt;
          error_message = &amp;quot;The author \&amp;quot;#{user_name.to_s.strip}\&amp;quot; was not found.&amp;lt;a href='/users/new'&amp;gt;Create&amp;lt;/a&amp;gt; this user?&amp;quot;&lt;br /&gt;
      else&lt;br /&gt;
          error_message =  &amp;quot;The reviewer \&amp;quot;#{user_name}\&amp;quot; is not a participant in this assignment.&amp;lt;a href='/users/new'&amp;gt;Register&amp;lt;/a&amp;gt; this user as a participant?&amp;quot;&lt;br /&gt;
      end&lt;br /&gt;
      check_nil?(participant, error_message)&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  # Check for if user is null&lt;br /&gt;
  def self.user_nil?(user, user_name, user_type)&lt;br /&gt;
      check_nil?( user, &amp;quot;The user account for the \&amp;quot;#{user_type}\&amp;quot; \&amp;quot;#{user_name}\&amp;quot; was not found.&amp;lt;a href='/users/new'&amp;gt;Create&amp;lt;/a&amp;gt; this user?&amp;quot;)&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
 #Throws import error for nil objects&lt;br /&gt;
  def self.check_nil?(object, error_message)&lt;br /&gt;
      if object.nil?&lt;br /&gt;
          raise ImportError, error_message&lt;br /&gt;
      end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Refactoring of get_assessments_round_for method ===&lt;br /&gt;
&lt;br /&gt;
The get_assessments_round_for method’s name failed to provide a clear idea of the method’s purpose and functionality.  This is why it was renamed to get_team_responses_for_round, the new name of the method provides a clearer idea of its purpose. Additionally, there was a private variable, team_id, introduced in the method that was unnecessary and could be replaced by using the id property of the team parameter directly.  We also removed the return statement at the end of the method.  &lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
Before refactoring:&lt;br /&gt;
&amp;lt;big&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  def self.get_assessments_round_for(team,round)&lt;br /&gt;
    team_id =team.id&lt;br /&gt;
    responses = Array.new&lt;br /&gt;
    if team_id&lt;br /&gt;
      maps = ResponseMap.where(:reviewee_id =&amp;gt; team_id, :type =&amp;gt; &amp;quot;ReviewResponseMap&amp;quot;)&lt;br /&gt;
      maps.each{ |map|&lt;br /&gt;
        if !map.response.empty? &amp;amp;&amp;amp; !map.response.reject{|r| r.round!=round}.empty?&lt;br /&gt;
          responses &amp;lt;&amp;lt; map.response.reject{|r| r.round!=round}.last&lt;br /&gt;
        end&lt;br /&gt;
      }&lt;br /&gt;
      responses.sort! {|a,b| a.map.reviewer.fullname &amp;lt;=&amp;gt; b.map.reviewer.fullname }&lt;br /&gt;
    end&lt;br /&gt;
    return responses&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
&lt;br /&gt;
After refactoring: &lt;br /&gt;
&lt;br /&gt;
&amp;lt;big&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  # return the responses for specified round,&lt;br /&gt;
  # for varying rubric feature -Yang&lt;br /&gt;
  def self.get_team_responses_for_round(team, round)&lt;br /&gt;
    responses = []&lt;br /&gt;
    if team.id&lt;br /&gt;
      maps = ResponseMap.where(reviewee_id: team.id, type: 'ReviewResponseMap')&lt;br /&gt;
      maps.each do |map|&lt;br /&gt;
        unless map.response.empty? &amp;amp;&amp;amp; map.response.reject { |r| r.round != round }.empty?&lt;br /&gt;
          responses &amp;lt;&amp;lt; map.response.reject { |r| r.round != round }.last&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
      responses.sort! { |a, b| a.map.reviewer.fullname &amp;lt;=&amp;gt; b.map.reviewer.fullname }&lt;br /&gt;
    end&lt;br /&gt;
    responses&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
The change in method name also required changes to the following files that referenced it:&lt;br /&gt;
&lt;br /&gt;
/app/models/assignment.rb:436:    &lt;br /&gt;
 &lt;br /&gt;
&amp;lt;big&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  assessments = ReviewResponseMap.get_assessments_round_for(team,i)&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt; &lt;br /&gt;
&lt;br /&gt;
./app/models/assignment_participant.rb:268:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;big&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 scores[questionnaire_symbol][:assessments] = questionnaire.get_assessments_round_for(self,round)&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Refactoring of metareview_response_maps method ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The metareview_response_maps method was unnecessarily complex.  It contained an unneeded private variable and an unnecessary nested loop.  Originally, it added each metareview map individually in the nested loop.  We decided to remove the nested loop and use the concat method for readability and maintainability.  These changes allowed us to remove the private variable &amp;quot;metareview_list&amp;quot; and only maintain the &amp;quot;metareview_response_maps&amp;quot; variable.  We also renamed the metareview_response_maps method to get_metareview_response_maps method to be more descriptive about the intent of the method. &lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
Before refactoring:&lt;br /&gt;
&amp;lt;big&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 def metareview_response_maps&lt;br /&gt;
    responses = Response.where(map_id:self.id)&lt;br /&gt;
    metareview_list=[]&lt;br /&gt;
    responses.each do |response|&lt;br /&gt;
      metareview_response_maps = MetareviewResponseMap.where(reviewed_object_id:response.id)&lt;br /&gt;
      metareview_response_maps.each do |metareview_response_map|&lt;br /&gt;
        metareview_list&amp;lt;&amp;lt;metareview_response_map&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
    metareview_list&lt;br /&gt;
 end&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
After refactoring:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;big&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  # Returns the response maps for all the metareviews&lt;br /&gt;
  def get_metareview_response_maps&lt;br /&gt;
    responses = Response.where(map_id: id)&lt;br /&gt;
    metareview_response_maps = []&lt;br /&gt;
    responses.each do |response|&lt;br /&gt;
      metareview_response_maps.concat MetareviewResponseMap.where(reviewed_object_id: response.id)&lt;br /&gt;
    end&lt;br /&gt;
    metareview_response_maps&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Refactoring of export method ===&lt;br /&gt;
The export method contained mappings.sort! { |a, b| a.reviewee.name &amp;lt;=&amp;gt; b.reviewee.name }.  We could not get past this when running tests, we kept getting a message saying, &amp;quot;sort! was not a method for an ActiveRecord_Relation&amp;quot;.  But, ActiveRecord_Relation does allow the use of sort.  So we changed that line of code to  mappings = mappings.sort { |a, b| a.reviewee.name &amp;lt;=&amp;gt; b.reviewee.name }&lt;br /&gt;
&lt;br /&gt;
Before refactoring:&lt;br /&gt;
&amp;lt;big&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  def self.export(csv, parent_id, options)&lt;br /&gt;
    mappings = where(reviewed_object_id: parent_id)&lt;br /&gt;
    mappings.sort! { |a, b| a.reviewee.name &amp;lt;=&amp;gt; b.reviewee.name }&lt;br /&gt;
    mappings.each {&lt;br /&gt;
      |map|&lt;br /&gt;
      csv &amp;lt;&amp;lt; [&lt;br /&gt;
        map.reviewee.name,&lt;br /&gt;
        map.reviewer.name&lt;br /&gt;
      ]&lt;br /&gt;
    }&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
&lt;br /&gt;
After refactoring:&lt;br /&gt;
&amp;lt;big&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  # options parameter used as a signature in other models&lt;br /&gt;
  def self.export(csv, parent_id, options)&lt;br /&gt;
    mappings = where(reviewed_object_id: parent_id)&lt;br /&gt;
    mappings = mappings.sort { |a, b| a.reviewee.name &amp;lt;=&amp;gt; b.reviewee.name }&lt;br /&gt;
    mappings.each do&lt;br /&gt;
    |map|&lt;br /&gt;
      csv &amp;lt;&amp;lt; [map.reviewee.name, map.reviewer.name]&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Refactoring of final_versions_from_reviewer method ===&lt;br /&gt;
The final_versions_from_reviewer method was too long and repetitive.  We removed common functionality from within the if and else statement and put it in a private method final_versions_from_reviewer.  Then we created the get_responses method to find the responses based on the arguments values.  These private methods make the class more readable for other programmers.&lt;br /&gt;
 &lt;br /&gt;
Before refactoring:&lt;br /&gt;
&amp;lt;big&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  def self.final_versions_from_reviewer(reviewer_id)&lt;br /&gt;
    maps = ReviewResponseMap.where(reviewer_id: reviewer_id)&lt;br /&gt;
    assignment = Assignment.find(Participant.find(reviewer_id).parent_id)&lt;br /&gt;
    review_final_versions = Hash.new&lt;br /&gt;
    if !assignment.varying_rubrics_by_round?&lt;br /&gt;
      #same review rubric used in multiple rounds&lt;br /&gt;
      review_final_versions[:review] = Hash.new&lt;br /&gt;
      review_final_versions[:review][:questionnaire_id] = assignment.get_review_questionnaire_id&lt;br /&gt;
      response_ids = Array.new&lt;br /&gt;
      maps.each do |map|&lt;br /&gt;
        responses = Response.where(map_id:map.id)&lt;br /&gt;
        if !responses.empty?&lt;br /&gt;
          response_ids &amp;lt;&amp;lt; responses.last.id&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
      review_final_versions[:review][:response_ids] = response_ids&lt;br /&gt;
    else&lt;br /&gt;
      #vary rubric by round&lt;br /&gt;
      rounds_num = assignment.rounds_of_reviews&lt;br /&gt;
      for round in 1..rounds_num&lt;br /&gt;
        symbol = (&amp;quot;review round&amp;quot;+round.to_s).to_sym&lt;br /&gt;
        review_final_versions[symbol] = Hash.new&lt;br /&gt;
        review_final_versions[symbol][:questionnaire_id] = assignment.get_review_questionnaire_id(round)&lt;br /&gt;
        response_ids = Array.new&lt;br /&gt;
        maps.each do |map|&lt;br /&gt;
          responses = Response.where(map_id:map.id, round:round)&lt;br /&gt;
          if !responses.empty?&lt;br /&gt;
            response_ids &amp;lt;&amp;lt; responses.last.id&lt;br /&gt;
          end&lt;br /&gt;
        end&lt;br /&gt;
        review_final_versions[symbol][:response_ids] = response_ids&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
    review_final_versions&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
&lt;br /&gt;
After refactoring:&lt;br /&gt;
&amp;lt;big&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  # wrap The latest version of responses in each response map,&lt;br /&gt;
  # together with the questionnaire_id will be used to&lt;br /&gt;
  # display the reviewer summary&lt;br /&gt;
  def self.final_versions_from_reviewer(reviewer_id)&lt;br /&gt;
    maps = ReviewResponseMap.where(reviewer_id: reviewer_id)&lt;br /&gt;
    assignment = find_assignment(Participant.find(reviewer_id).parent_id)&lt;br /&gt;
    review_final_versions = {}&lt;br /&gt;
    unless assignment.varying_rubrics_by_round?&lt;br /&gt;
      #same review rubric used in multiple rounds&lt;br /&gt;
      review_final_versions = review_final_version_responses(:review, :questionnaire_id, assignment, maps)&lt;br /&gt;
    else&lt;br /&gt;
      # vary rubric by round&lt;br /&gt;
      rounds_num = assignment.rounds_of_reviews&lt;br /&gt;
      (1..rounds_num).each do |round|&lt;br /&gt;
        symbol = ('review round' + round.to_s).to_sym&lt;br /&gt;
        review_final_versions = review_final_version_responses(symbol, :questionnaire_id, assignment, maps, round)&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
    review_final_versions&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Private methods added:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;big&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  # Compute list of responses and return it&lt;br /&gt;
  def self.review_final_version_responses(symbol, questionnaire_id, assignment, maps, round = nil)&lt;br /&gt;
    review_final_versions = {}&lt;br /&gt;
    review_final_versions[symbol] = {}&lt;br /&gt;
    review_final_versions[symbol][questionnaire_id] = assignment.get_review_questionnaire_id(round)&lt;br /&gt;
    response_ids = []&lt;br /&gt;
    maps.each do |map|&lt;br /&gt;
      responses =  get_responses(map.id, round)&lt;br /&gt;
      unless responses.empty?&lt;br /&gt;
        response_ids &amp;lt;&amp;lt; responses.last.id&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
    review_final_versions[symbol][:response_ids] = response_ids&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;big&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  #Get responses by map_id and round (if exists)&lt;br /&gt;
  def self.get_responses(id, round)&lt;br /&gt;
     if round.nil?&lt;br /&gt;
       responses = Response.where(map_id: id)&lt;br /&gt;
     else&lt;br /&gt;
       responses = Response.where(map_id: id, round: round)&lt;br /&gt;
     end	&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Refactoring of other methods ===&lt;br /&gt;
Although trivial, we removed the return statement from the get_title, export_fields, and show_feedback methods because return statements are unnecessary in Ruby.&lt;br /&gt;
&lt;br /&gt;
=== Addition of code comments ===&lt;br /&gt;
&lt;br /&gt;
We added comments to all of the methods in the ReviewResponseMap.rb file and corrected instances where CodeClimate Identified opportunities for code improvement.  One issue flagged by CodeClimate that we did not change was to use the find_by method instead of where().first method.  The where().first method occurs in the import, get_assignment_participant, and create_response_map methods. It is not always appropriate to use the find_by method, as documented in this github post: https://github.com/bbatsov/rubocop/issues/1938 .  In instances where ordering by id is the desired behavior, where().first will order by default, but in Rails 4+ find_by does not honor that default behavior.  For this reason we left the instances of where().first unchanged.&lt;br /&gt;
&lt;br /&gt;
=== Code Improvements ===&lt;br /&gt;
&lt;br /&gt;
This refactoring was to improve readability and follow as many good ''Rubyist'' coding practices as possible without breaking the functionality of existing code. We used CodeClimate of the master branch code as a reference. We took the suggestions we got from CodeClimate and improved our code based on that.&lt;br /&gt;
We also made some of the methods shorter by removing redundant functionality and adding private methods to methods with a lot internal functionality. We also added private methods in places where we saw repeated patterns to make the code ''DRYer''.&lt;br /&gt;
At the end of our refactoring, we managed to improve the rating on CodeClimate from a '''C''' to a '''B''' . Further improvements meant reducing the size of the entire class which required a much more significant refactoring in multiple files and folders. We focused on refactoring the existing model, '''ReviewResponseMap'''.&lt;br /&gt;
&lt;br /&gt;
= Unit Tests =&lt;br /&gt;
The previous unit tests had syntactical and run time errors.  We were not able to get the previous unit tests to run without errors.  Because of this we rewrote all of the unit tests for the &amp;lt;b&amp;gt;ReviewResponseModel&amp;lt;/b&amp;gt;.  It is important to have working unit tests so that when internal changes are made to functions the external output remains the same.&lt;br /&gt;
&lt;br /&gt;
=== Refactoring of Unit Tests===&lt;br /&gt;
&lt;br /&gt;
We added a test_helper file to the main test folder that requires a needed configuration file and needed gems.  We also added 8 fixtures that were needed for data to run the unit tests.  The following fixture files were added:&lt;br /&gt;
&lt;br /&gt;
* assignment_questionnaires.yml&lt;br /&gt;
* assignments.yml&lt;br /&gt;
* participants.yml&lt;br /&gt;
* questionnaires.yml&lt;br /&gt;
* response_maps.yml&lt;br /&gt;
* responses.yml&lt;br /&gt;
* teams.yml&lt;br /&gt;
* users.yml&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
There is at least one unit test for every public method within the &amp;lt;b&amp;gt;ReviewResponseModel&amp;lt;/b&amp;gt;.  The test naming convention used is &amp;quot;method_&amp;lt;name of method that is being tested&amp;gt;&amp;quot;.  For example, the unit test for the export method is &amp;quot;method_export&amp;quot;.  If there are multiple test for one method the name of the test will include the test case after the normal naming convention.  For example, one of the unit tests for the import method checks for an invalid assignment.  The name of this method is &amp;quot;method_import_invalid_assignment&amp;quot;.  The following are the unit tests we created:&lt;br /&gt;
&lt;br /&gt;
* method_export&lt;br /&gt;
* method_get_metareview_response_maps&lt;br /&gt;
* method_get_team_response_for_round&lt;br /&gt;
* method_final_versions_from_reviewer&lt;br /&gt;
* method_import&lt;br /&gt;
* method_import_invalid_reviewee&lt;br /&gt;
* method_import_invalid_reviewer&lt;br /&gt;
* method_import_invalid_assignment&lt;br /&gt;
* method_delete&lt;br /&gt;
* method_delete_no _force&lt;br /&gt;
* method_show_feedback&lt;br /&gt;
* method_get_title&lt;br /&gt;
* method_export_fields&lt;br /&gt;
* method_questionnaire&lt;br /&gt;
* method_add_reviewer&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== How to Run Unit Tests ===&lt;br /&gt;
To run the unit tests, follow these steps:&lt;br /&gt;
&lt;br /&gt;
# Download the master branch of the repo.&lt;br /&gt;
# Setup the Databases for the test environment (we have used Zhewei's scrubbed expertiza DB )&lt;br /&gt;
#* Run the &amp;quot; rake db:create RAILS_ENV=test &amp;quot; command&lt;br /&gt;
#* Run the &amp;quot; rake db:reset RAILS_ENV=test &amp;quot; command&lt;br /&gt;
#* Scrub the DB using &amp;quot; mysql -u root expertiza_development &amp;lt; expertiza-scrubbed.sql&amp;quot;&lt;br /&gt;
#* Run the &amp;quot; rake db:migrate &amp;quot;&lt;br /&gt;
# Run &amp;quot; rake test test/unit/review_response_map_test.rb &amp;quot; in the &amp;quot;expertiza/&amp;quot; directory.&lt;br /&gt;
#* If you run into a mysql log in error go into config/database.yml and edit the mysql credentials for the test section so that it matches the local environment's mysql configuration&lt;br /&gt;
# Check if tests passed or failed.&lt;br /&gt;
&lt;br /&gt;
= Manual Test Case =&lt;br /&gt;
&lt;br /&gt;
In order to test the changes made to the ReviewResponseMap, bring up [[ http://152.46.16.195:5902/ | Expertiza]] and log in as an administrator.  Once logged in, proceed with the following steps:&lt;br /&gt;
&lt;br /&gt;
# Go to '''impersonate user''' when logged in as ''instructor6'' and type in ''student559'' (or) just log in as ''student559''. All passwords are ''password'' .&lt;br /&gt;
# Pick any assignment to view.&lt;br /&gt;
# Navigate to '''Other's work'''.&lt;br /&gt;
# Check the different reviews and metareviews. Whether they are being displayed correctly or not.&lt;br /&gt;
# Go to Edit or Give feedback and submit a feedback.&lt;br /&gt;
# Go back and check if the feedback given is displayed correctly or not.&lt;br /&gt;
# Check if author's feedback is correct or not.&lt;br /&gt;
# Go to the '''Temp''' assignment and see if the page is being displayed correctly or not (since there is no assignment submission content or reviews for that).&lt;br /&gt;
&lt;br /&gt;
''NOTE: Since this was a refactoring of the code and methods, the existing functionality was supposed to remain the same and not break for the changes we've made.''&lt;br /&gt;
&lt;br /&gt;
= References =&lt;br /&gt;
&lt;br /&gt;
&amp;lt;references/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
= External Links =&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;4.&amp;amp;nbsp; [https://github.com/expertiza/expertiza Expertiza Main Repo] &amp;lt;br&amp;gt;&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;5.&amp;amp;nbsp; [https://github.com/adeeshag/expertiza/blob/develop/app/models/review_response_map.rb Refactored ReviewResponseMap.rb]&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;6.&amp;amp;nbsp; [https://github.com/adeeshag/expertiza/tree/develop/test/fixtures Test Fixtures]&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;7.&amp;amp;nbsp; [https://github.com/adeeshag/expertiza/blob/develop/test/unit/review_response_map_test.rb Unit Tests]&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;8.&amp;amp;nbsp; [http://152.46.16.195:5902/ Expertiza Deployed Site]&amp;lt;br&amp;gt;&lt;/div&gt;</summary>
		<author><name>Cnbrown4</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2015/ossE1558BGJ&amp;diff=98476</id>
		<title>CSC/ECE 517 Fall 2015/ossE1558BGJ</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2015/ossE1558BGJ&amp;diff=98476"/>
		<updated>2015-11-06T21:46:22Z</updated>

		<summary type="html">&lt;p&gt;Cnbrown4: /* References */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Introduction =&lt;br /&gt;
&lt;br /&gt;
This page provides a description of the modifications and improvements made to the Expertiza project’s source code as part of an Expertiza based Open Source Software project.  Expertiza is a web based application which allows students to submit and peer-review classmates’ work, including written articles and development projects. The specific changes made during the course of this project were to the ReviewResponseMap.rb file, with additional changes made to other related files in support of refactoring ReviewResponseMap.rb.  &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
= Problem Statement =&lt;br /&gt;
&lt;br /&gt;
ReviewResponseMap is the model class used to manage the relationship between contributors, reviewers, and assignments.  The intent of the changes were to refactor the code for better readability and adherence to Ruby coding standards and best practices.  Primarily these changes involved the refactoring of overly complex methods, renaming methods for better readability, and the addition of missing unit tests.&lt;br /&gt;
&lt;br /&gt;
Project Requirements:&lt;br /&gt;
&lt;br /&gt;
# Code Climate&amp;lt;ref name=&amp;quot;Code Climate&amp;quot;&amp;gt;https://codeclimate.com&amp;lt;/ref&amp;gt; shows import method is complex, because of lots of checks. This method can be fixed by adding private methods for raising import error.&lt;br /&gt;
# Get_assessments_round_for method can be renamed to get_team_responses_for_round. Team_id private variable is not needed.&lt;br /&gt;
# metareview_response_maps rename, refactoring can be done. No need to do second iteration.&lt;br /&gt;
# write missing unit tests for existing methods.&lt;br /&gt;
&lt;br /&gt;
= Design Patterns =&lt;br /&gt;
&lt;br /&gt;
As part of our project, we refactored the model to follow the Single Responsibility and Don't Repeat Yourself (DRY) Principles.  Both of the principles focus on reducing code repetition and increasing the cohesion of the individual methods in the class.  The Single Responsibility Principle states that each class and method should have sole responsibility over one single part of the functionality of the system&amp;lt;ref&amp;gt;https://en.wikipedia.org/wiki/Single_responsibility_principle&amp;lt;/ref&amp;gt;.  The DRY principle states that whenever the same types of logic and functionality are being performed in a class the duplicated logic should be extracted into a new method that can be called in place of the repeated lines of code &amp;lt;ref&amp;gt;https://en.wikipedia.org/wiki/Don%27t_repeat_yourself&amp;lt;/ref&amp;gt;.  A prime example of a method that initially violated these principles was the import method, which in addition to performing the core import processes also performed a number of checks that would be more properly extracted into private methods.&lt;br /&gt;
&lt;br /&gt;
=Code Changes =&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Refactoring of import method ===&lt;br /&gt;
&lt;br /&gt;
CodeClimate reports showed the import method to be overly complex, with a number of checks being included within the import method itself.  The resolution for this problem was to refactor the import method, creating private methods to perform the null checks and throw import errors.  Prior to refactoring, all null checks were performed within the import method.   After refactoring, the import method adheres to the single responsibility principle, performing only key import tasks while making calls to private methods for any necessary validation. The size of the import method was reduced by doing this and counts for better readability of the code. Also, this method is a very important one and care was taken so that any existing functionality did not break. &lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
Before refactoring:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;big&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 def self.import(row, session, id)&lt;br /&gt;
    if row.length &amp;lt; 2&lt;br /&gt;
      raise ArgumentError, &amp;quot;Not enough items&amp;quot;&lt;br /&gt;
    end&lt;br /&gt;
    assignment = Assignment.find(id)&lt;br /&gt;
    if assignment.nil?&lt;br /&gt;
      raise ImportError, &amp;quot;The assignment with id \&amp;quot;#{id}\&amp;quot; was not found. &amp;lt;a href='/assignment/new'&amp;gt;Create&amp;lt;/a&amp;gt; this assignment?&amp;quot;&lt;br /&gt;
    end&lt;br /&gt;
    index = 1&lt;br /&gt;
    while index &amp;lt; row.length&lt;br /&gt;
      user = User.find_by_name(row[index].to_s.strip)&lt;br /&gt;
      if user.nil?&lt;br /&gt;
        raise ImportError, &amp;quot;The user account for the reviewer \&amp;quot;#{row[index]}\&amp;quot; was not found. &amp;lt;a href='/users/new'&amp;gt;Create&amp;lt;/a&amp;gt; this user?&amp;quot;&lt;br /&gt;
      end&lt;br /&gt;
      reviewer = AssignmentParticipant.where(user_id: user.id, parent_id:  assignment.id).first&lt;br /&gt;
      if reviewer == nil&lt;br /&gt;
        raise ImportError, &amp;quot;The reviewer \&amp;quot;#{row[index]}\&amp;quot; is not a participant in this assignment. &amp;lt;a href='/users/new'&amp;gt;Register&amp;lt;/a&amp;gt; this user as a participant?&amp;quot;&lt;br /&gt;
      end&lt;br /&gt;
      if assignment.team_assignment&lt;br /&gt;
        reviewee = AssignmentTeam.where(name: row[0].to_s.strip, parent_id:  assignment.id).first&lt;br /&gt;
        if reviewee == nil&lt;br /&gt;
          raise ImportError, &amp;quot;The author \&amp;quot;#{row[0].to_s.strip}\&amp;quot; was not found. &amp;lt;a href='/users/new'&amp;gt;Create&amp;lt;/a&amp;gt; this user?&amp;quot;&lt;br /&gt;
        end&lt;br /&gt;
        existing = ReviewResponseMap.where(reviewee_id: reviewee.id, reviewer_id:  reviewer.id).first&lt;br /&gt;
        if existing.nil?&lt;br /&gt;
          ReviewResponseMap.create(:reviewer_id =&amp;gt; reviewer.id, :reviewee_id =&amp;gt; reviewee.id, :reviewed_object_id =&amp;gt; assignment.id)&lt;br /&gt;
        end&lt;br /&gt;
      else&lt;br /&gt;
        puser = User.find_by_name(row[0].to_s.strip)&lt;br /&gt;
        if user == nil&lt;br /&gt;
          raise ImportError, &amp;quot;The user account for the reviewee \&amp;quot;#{row[0]}\&amp;quot; was not found. &amp;lt;a href='/users/new'&amp;gt;Create&amp;lt;/a&amp;gt; this user?&amp;quot;&lt;br /&gt;
        end&lt;br /&gt;
        reviewee = AssignmentParticipant.where(user_id: puser.id, parent_id:  assignment.id).first&lt;br /&gt;
        if reviewee == nil&lt;br /&gt;
          raise ImportError, &amp;quot;The author \&amp;quot;#{row[0].to_s.strip}\&amp;quot; was not found. &amp;lt;a href='/users/new'&amp;gt;Create&amp;lt;/a&amp;gt; this user?&amp;quot;&lt;br /&gt;
        end&lt;br /&gt;
        team_id = TeamsUser.team_id(reviewee.parent_id, reviewee.user_id)&lt;br /&gt;
        existing = ReviewResponseMap.where(reviewee_id: team_id, reviewer_id:  reviewer.id).first&lt;br /&gt;
        if existing.nil?&lt;br /&gt;
          ReviewResponseMap.create(:reviewee_id =&amp;gt; team_id, :reviewer_id =&amp;gt; reviewer.id, :reviewed_object_id =&amp;gt; assignment.id)&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
      index += 1&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
&lt;br /&gt;
After refactoring:&lt;br /&gt;
 &lt;br /&gt;
  &amp;lt;big&amp;gt;&amp;lt;nowiki&amp;gt;#Imports new reponse maps if they do not already exist&lt;br /&gt;
  def self.import(row, _session, id)&lt;br /&gt;
      if row.length &amp;lt; 2&lt;br /&gt;
          raise ArgumentError, 'Not enough items'&lt;br /&gt;
      end&lt;br /&gt;
      assignment = find_assignment(id)&lt;br /&gt;
      index = 1&lt;br /&gt;
      reviewee_name = row[0]&lt;br /&gt;
      while index &amp;lt; row.length&lt;br /&gt;
          reviewee_id = nil&lt;br /&gt;
          reviewer_name = row[index]&lt;br /&gt;
          reviewer = get_assignment_participant(reviewer_name,  assignment.id, &amp;quot;reviewer&amp;quot;)&lt;br /&gt;
          participant_nil?(reviewer, reviewer_name , &amp;quot;reviewer&amp;quot;)&lt;br /&gt;
         &lt;br /&gt;
         #Find reviewee if assignment is a team assignment&lt;br /&gt;
         if assignment.team_assignment&lt;br /&gt;
             reviewee = AssignmentTeam.where(name: reviewee_name .to_s.strip, parent_id: assignment.id).first&lt;br /&gt;
             participant_nil?(reviewee, reviewee_name, &amp;quot;author&amp;quot;)&lt;br /&gt;
             reviewee_id = reviewee.id&lt;br /&gt;
         #Find reviewee if assignment is not a team assignment&lt;br /&gt;
         else&lt;br /&gt;
	     reviewee = get_assignment_participant(reviewee_name, assignment.id, &amp;quot;reviewee&amp;quot;)&lt;br /&gt;
             participant_nil?(reviewee, reviewee_name, &amp;quot;author&amp;quot;)&lt;br /&gt;
             reviewee_id  = TeamsUser.team_id(reviewee.parent_id, reviewee.user_id)&lt;br /&gt;
         end&lt;br /&gt;
         create_response_map(reviewer, reviewee_id,  assignment)&lt;br /&gt;
         index += 1&lt;br /&gt;
      end&lt;br /&gt;
  end&amp;lt;/nowiki&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Private methods added:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;big&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  # Check for if assignment value is null&lt;br /&gt;
  def self.find_assignment(id)&lt;br /&gt;
      begin&lt;br /&gt;
          assignment = Assignment.find(id)&lt;br /&gt;
      rescue ActiveRecord::RecordNotFound&lt;br /&gt;
          raise ImportError, &amp;quot;The assignment with id \&amp;quot;#{id}\&amp;quot; was not found.&amp;lt;a href='/assignment/new'&amp;gt;Create&amp;lt;/a&amp;gt; this assignment?&amp;quot;&lt;br /&gt;
      end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  # Check for if participant is null&lt;br /&gt;
  def self.participant_nil?(participant, user_name, participant_type) &lt;br /&gt;
      error_message = nil&lt;br /&gt;
      if participant_type == &amp;quot;author&amp;quot;&lt;br /&gt;
          error_message = &amp;quot;The author \&amp;quot;#{user_name.to_s.strip}\&amp;quot; was not found.&amp;lt;a href='/users/new'&amp;gt;Create&amp;lt;/a&amp;gt; this user?&amp;quot;&lt;br /&gt;
      else&lt;br /&gt;
          error_message =  &amp;quot;The reviewer \&amp;quot;#{user_name}\&amp;quot; is not a participant in this assignment.&amp;lt;a href='/users/new'&amp;gt;Register&amp;lt;/a&amp;gt; this user as a participant?&amp;quot;&lt;br /&gt;
      end&lt;br /&gt;
      check_nil?(participant, error_message)&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  # Check for if user is null&lt;br /&gt;
  def self.user_nil?(user, user_name, user_type)&lt;br /&gt;
      check_nil?( user, &amp;quot;The user account for the \&amp;quot;#{user_type}\&amp;quot; \&amp;quot;#{user_name}\&amp;quot; was not found.&amp;lt;a href='/users/new'&amp;gt;Create&amp;lt;/a&amp;gt; this user?&amp;quot;)&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
 #Throws import error for nil objects&lt;br /&gt;
  def self.check_nil?(object, error_message)&lt;br /&gt;
      if object.nil?&lt;br /&gt;
          raise ImportError, error_message&lt;br /&gt;
      end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Refactoring of get_assessments_round_for method ===&lt;br /&gt;
&lt;br /&gt;
The get_assessments_round_for method’s name failed to provide a clear idea of the method’s purpose and functionality.  This is why it was renamed to get_team_responses_for_round, the new name of the method provides a clearer idea of its purpose. Additionally, there was a private variable, team_id, introduced in the method that was unnecessary and could be replaced by using the id property of the team parameter directly.  We also removed the return statement at the end of the method.  &lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
Before refactoring:&lt;br /&gt;
&amp;lt;big&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  def self.get_assessments_round_for(team,round)&lt;br /&gt;
    team_id =team.id&lt;br /&gt;
    responses = Array.new&lt;br /&gt;
    if team_id&lt;br /&gt;
      maps = ResponseMap.where(:reviewee_id =&amp;gt; team_id, :type =&amp;gt; &amp;quot;ReviewResponseMap&amp;quot;)&lt;br /&gt;
      maps.each{ |map|&lt;br /&gt;
        if !map.response.empty? &amp;amp;&amp;amp; !map.response.reject{|r| r.round!=round}.empty?&lt;br /&gt;
          responses &amp;lt;&amp;lt; map.response.reject{|r| r.round!=round}.last&lt;br /&gt;
        end&lt;br /&gt;
      }&lt;br /&gt;
      responses.sort! {|a,b| a.map.reviewer.fullname &amp;lt;=&amp;gt; b.map.reviewer.fullname }&lt;br /&gt;
    end&lt;br /&gt;
    return responses&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
&lt;br /&gt;
After refactoring: &lt;br /&gt;
&lt;br /&gt;
&amp;lt;big&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  # return the responses for specified round,&lt;br /&gt;
  # for varying rubric feature -Yang&lt;br /&gt;
  def self.get_team_responses_for_round(team, round)&lt;br /&gt;
    responses = []&lt;br /&gt;
    if team.id&lt;br /&gt;
      maps = ResponseMap.where(reviewee_id: team.id, type: 'ReviewResponseMap')&lt;br /&gt;
      maps.each do |map|&lt;br /&gt;
        unless map.response.empty? &amp;amp;&amp;amp; map.response.reject { |r| r.round != round }.empty?&lt;br /&gt;
          responses &amp;lt;&amp;lt; map.response.reject { |r| r.round != round }.last&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
      responses.sort! { |a, b| a.map.reviewer.fullname &amp;lt;=&amp;gt; b.map.reviewer.fullname }&lt;br /&gt;
    end&lt;br /&gt;
    responses&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
The change in method name also required changes to the following files that referenced it:&lt;br /&gt;
&lt;br /&gt;
/app/models/assignment.rb:436:    &lt;br /&gt;
 &lt;br /&gt;
&amp;lt;big&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  assessments = ReviewResponseMap.get_assessments_round_for(team,i)&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt; &lt;br /&gt;
&lt;br /&gt;
./app/models/assignment_participant.rb:268:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;big&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 scores[questionnaire_symbol][:assessments] = questionnaire.get_assessments_round_for(self,round)&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Refactoring of metareview_response_maps method ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The metareview_response_maps method was unnecessarily complex.  It contained an unneeded private variable and an unnecessary nested loop.  Originally, it added each metareview map individually in the nested loop.  We decided to remove the nested loop and use the concat method for readability and maintainability.  These changes allowed us to remove the private variable &amp;quot;metareview_list&amp;quot; and only maintain the &amp;quot;metareview_response_maps&amp;quot; variable.  We also renamed the metareview_response_maps method to get_metareview_response_maps method to be more descriptive about the intent of the method. &lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
Before refactoring:&lt;br /&gt;
&amp;lt;big&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 def metareview_response_maps&lt;br /&gt;
    responses = Response.where(map_id:self.id)&lt;br /&gt;
    metareview_list=[]&lt;br /&gt;
    responses.each do |response|&lt;br /&gt;
      metareview_response_maps = MetareviewResponseMap.where(reviewed_object_id:response.id)&lt;br /&gt;
      metareview_response_maps.each do |metareview_response_map|&lt;br /&gt;
        metareview_list&amp;lt;&amp;lt;metareview_response_map&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
    metareview_list&lt;br /&gt;
 end&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
After refactoring:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;big&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  # Returns the response maps for all the metareviews&lt;br /&gt;
  def get_metareview_response_maps&lt;br /&gt;
    responses = Response.where(map_id: id)&lt;br /&gt;
    metareview_response_maps = []&lt;br /&gt;
    responses.each do |response|&lt;br /&gt;
      metareview_response_maps.concat MetareviewResponseMap.where(reviewed_object_id: response.id)&lt;br /&gt;
    end&lt;br /&gt;
    metareview_response_maps&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Refactoring of export method ===&lt;br /&gt;
The export method contained mappings.sort! { |a, b| a.reviewee.name &amp;lt;=&amp;gt; b.reviewee.name }.  We could not get past this when running tests, we kept getting a message saying, &amp;quot;sort! was not a method for an ActiveRecord_Relation&amp;quot;.  But, ActiveRecord_Relation does allow the use of sort.  So we changed that line of code to  mappings = mappings.sort { |a, b| a.reviewee.name &amp;lt;=&amp;gt; b.reviewee.name }&lt;br /&gt;
&lt;br /&gt;
Before refactoring:&lt;br /&gt;
&amp;lt;big&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  def self.export(csv, parent_id, options)&lt;br /&gt;
    mappings = where(reviewed_object_id: parent_id)&lt;br /&gt;
    mappings.sort! { |a, b| a.reviewee.name &amp;lt;=&amp;gt; b.reviewee.name }&lt;br /&gt;
    mappings.each {&lt;br /&gt;
      |map|&lt;br /&gt;
      csv &amp;lt;&amp;lt; [&lt;br /&gt;
        map.reviewee.name,&lt;br /&gt;
        map.reviewer.name&lt;br /&gt;
      ]&lt;br /&gt;
    }&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
&lt;br /&gt;
After refactoring:&lt;br /&gt;
&amp;lt;big&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  # options parameter used as a signature in other models&lt;br /&gt;
  def self.export(csv, parent_id, options)&lt;br /&gt;
    mappings = where(reviewed_object_id: parent_id)&lt;br /&gt;
    mappings = mappings.sort { |a, b| a.reviewee.name &amp;lt;=&amp;gt; b.reviewee.name }&lt;br /&gt;
    mappings.each do&lt;br /&gt;
    |map|&lt;br /&gt;
      csv &amp;lt;&amp;lt; [map.reviewee.name, map.reviewer.name]&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Refactoring of final_versions_from_reviewer method ===&lt;br /&gt;
The final_versions_from_reviewer method was too long and repetitive.  We removed common functionality from within the if and else statement and put it in a private method final_versions_from_reviewer.  Then we created the get_responses method to find the responses based on the arguments values.  These private methods make the class more readable for other programmers.&lt;br /&gt;
 &lt;br /&gt;
Before refactoring:&lt;br /&gt;
&amp;lt;big&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  def self.final_versions_from_reviewer(reviewer_id)&lt;br /&gt;
    maps = ReviewResponseMap.where(reviewer_id: reviewer_id)&lt;br /&gt;
    assignment = Assignment.find(Participant.find(reviewer_id).parent_id)&lt;br /&gt;
    review_final_versions = Hash.new&lt;br /&gt;
    if !assignment.varying_rubrics_by_round?&lt;br /&gt;
      #same review rubric used in multiple rounds&lt;br /&gt;
      review_final_versions[:review] = Hash.new&lt;br /&gt;
      review_final_versions[:review][:questionnaire_id] = assignment.get_review_questionnaire_id&lt;br /&gt;
      response_ids = Array.new&lt;br /&gt;
      maps.each do |map|&lt;br /&gt;
        responses = Response.where(map_id:map.id)&lt;br /&gt;
        if !responses.empty?&lt;br /&gt;
          response_ids &amp;lt;&amp;lt; responses.last.id&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
      review_final_versions[:review][:response_ids] = response_ids&lt;br /&gt;
    else&lt;br /&gt;
      #vary rubric by round&lt;br /&gt;
      rounds_num = assignment.rounds_of_reviews&lt;br /&gt;
      for round in 1..rounds_num&lt;br /&gt;
        symbol = (&amp;quot;review round&amp;quot;+round.to_s).to_sym&lt;br /&gt;
        review_final_versions[symbol] = Hash.new&lt;br /&gt;
        review_final_versions[symbol][:questionnaire_id] = assignment.get_review_questionnaire_id(round)&lt;br /&gt;
        response_ids = Array.new&lt;br /&gt;
        maps.each do |map|&lt;br /&gt;
          responses = Response.where(map_id:map.id, round:round)&lt;br /&gt;
          if !responses.empty?&lt;br /&gt;
            response_ids &amp;lt;&amp;lt; responses.last.id&lt;br /&gt;
          end&lt;br /&gt;
        end&lt;br /&gt;
        review_final_versions[symbol][:response_ids] = response_ids&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
    review_final_versions&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
&lt;br /&gt;
After refactoring:&lt;br /&gt;
&amp;lt;big&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  # wrap The latest version of responses in each response map,&lt;br /&gt;
  # together with the questionnaire_id will be used to&lt;br /&gt;
  # display the reviewer summary&lt;br /&gt;
  def self.final_versions_from_reviewer(reviewer_id)&lt;br /&gt;
    maps = ReviewResponseMap.where(reviewer_id: reviewer_id)&lt;br /&gt;
    assignment = find_assignment(Participant.find(reviewer_id).parent_id)&lt;br /&gt;
    review_final_versions = {}&lt;br /&gt;
    unless assignment.varying_rubrics_by_round?&lt;br /&gt;
      #same review rubric used in multiple rounds&lt;br /&gt;
      review_final_versions = review_final_version_responses(:review, :questionnaire_id, assignment, maps)&lt;br /&gt;
    else&lt;br /&gt;
      # vary rubric by round&lt;br /&gt;
      rounds_num = assignment.rounds_of_reviews&lt;br /&gt;
      (1..rounds_num).each do |round|&lt;br /&gt;
        symbol = ('review round' + round.to_s).to_sym&lt;br /&gt;
        review_final_versions = review_final_version_responses(symbol, :questionnaire_id, assignment, maps, round)&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
    review_final_versions&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Private methods added:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;big&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  # Compute list of responses and return it&lt;br /&gt;
  def self.review_final_version_responses(symbol, questionnaire_id, assignment, maps, round = nil)&lt;br /&gt;
    review_final_versions = {}&lt;br /&gt;
    review_final_versions[symbol] = {}&lt;br /&gt;
    review_final_versions[symbol][questionnaire_id] = assignment.get_review_questionnaire_id(round)&lt;br /&gt;
    response_ids = []&lt;br /&gt;
    maps.each do |map|&lt;br /&gt;
      responses =  get_responses(map.id, round)&lt;br /&gt;
      unless responses.empty?&lt;br /&gt;
        response_ids &amp;lt;&amp;lt; responses.last.id&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
    review_final_versions[symbol][:response_ids] = response_ids&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;big&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  #Get responses by map_id and round (if exists)&lt;br /&gt;
  def self.get_responses(id, round)&lt;br /&gt;
     if round.nil?&lt;br /&gt;
       responses = Response.where(map_id: id)&lt;br /&gt;
     else&lt;br /&gt;
       responses = Response.where(map_id: id, round: round)&lt;br /&gt;
     end	&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Refactoring of other methods ===&lt;br /&gt;
Although trivial, we removed the return statement from the get_title, export_fields, and show_feedback methods because return statements are unnecessary in Ruby.&lt;br /&gt;
&lt;br /&gt;
=== Addition of code comments ===&lt;br /&gt;
&lt;br /&gt;
We added comments to all of the methods in the ReviewResponseMap.rb file and corrected instances where CodeClimate Identified opportunities for code improvement.  One issue flagged by CodeClimate that we did not change was to use the find_by method instead of where().first method.  The where().first method occurs in the import, get_assignment_participant, and create_response_map methods. It is not always appropriate to use the find_by method, as documented in this github post: https://github.com/bbatsov/rubocop/issues/1938 .  In instances where ordering by id is the desired behavior, where().first will order by default, but in Rails 4+ find_by does not honor that default behavior.  For this reason we left the instances of where().first unchanged.&lt;br /&gt;
&lt;br /&gt;
=== Code Improvements ===&lt;br /&gt;
&lt;br /&gt;
This refactoring was to improve readability and follow as many good ''Rubyist'' coding practices as possible without breaking the functionality of existing code. We used CodeClimate of the master branch code as a reference. We took the suggestions we got from CodeClimate and improved our code based on that.&lt;br /&gt;
We also made some of the methods shorter by removing redundant functionality and adding private methods to methods with a lot internal functionality. We also added private methods in places where we saw repeated patterns to make the code ''DRYer''.&lt;br /&gt;
At the end of our refactoring, we managed to improve the rating on CodeClimate from a '''C''' to a '''B''' . Further improvements meant reducing the size of the entire class which required a much more significant refactoring in multiple files and folders. We focused on refactoring the existing model, '''ReviewResponseMap'''.&lt;br /&gt;
&lt;br /&gt;
= Unit Tests =&lt;br /&gt;
The previous unit tests had syntactical and run time errors.  We were not able to get the previous unit tests to run without errors.  Because of this we rewrote all of the unit tests for the &amp;lt;b&amp;gt;ReviewResponseModel&amp;lt;/b&amp;gt;.  It is important to have working unit tests so that when internal changes are made to functions the external output remains the same.&lt;br /&gt;
&lt;br /&gt;
=== Refactoring of Unit Tests===&lt;br /&gt;
&lt;br /&gt;
We added a test_helper file to the main test folder that requires a needed configuration file and needed gems.  We also added 8 fixtures that were needed for data to run the unit tests.  The following fixture files were added:&lt;br /&gt;
&lt;br /&gt;
* assignment_questionnaires.yml&lt;br /&gt;
* assignments.yml&lt;br /&gt;
* participants.yml&lt;br /&gt;
* questionnaires.yml&lt;br /&gt;
* response_maps.yml&lt;br /&gt;
* responses.yml&lt;br /&gt;
* teams.yml&lt;br /&gt;
* users.yml&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
There is at least one unit test for every public method within the &amp;lt;b&amp;gt;ReviewResponseModel&amp;lt;/b&amp;gt;.  The test naming convention used is &amp;quot;method_&amp;lt;name of method that is being tested&amp;gt;&amp;quot;.  For example, the unit test for the export method is &amp;quot;method_export&amp;quot;.  If there are multiple test for one method the name of the test will include the test case after the normal naming convention.  For example, one of the unit tests for the import method checks for an invalid assignment.  The name of this method is &amp;quot;method_import_invalid_assignment&amp;quot;.  The following are the unit tests we created:&lt;br /&gt;
&lt;br /&gt;
* method_export&lt;br /&gt;
* method_get_metareview_response_maps&lt;br /&gt;
* method_get_team_response_for_round&lt;br /&gt;
* method_final_versions_from_reviewer&lt;br /&gt;
* method_import&lt;br /&gt;
* method_import_invalid_reviewee&lt;br /&gt;
* method_import_invalid_reviewer&lt;br /&gt;
* method_import_invalid_assignment&lt;br /&gt;
* method_delete&lt;br /&gt;
* method_delete_no _force&lt;br /&gt;
* method_show_feedback&lt;br /&gt;
* method_get_title&lt;br /&gt;
* method_export_fields&lt;br /&gt;
* method_questionnaire&lt;br /&gt;
* method_add_reviewer&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== How to Run Unit Tests ===&lt;br /&gt;
To run the unit tests, follow these steps:&lt;br /&gt;
&lt;br /&gt;
# Download the master branch of the repo.&lt;br /&gt;
# Setup the Databases for the test environment (we have used Zhewei's scrubbed expertiza DB )&lt;br /&gt;
#* Run the &amp;quot; rake db:create RAILS_ENV=test &amp;quot; command&lt;br /&gt;
#* Run the &amp;quot; rake db:reset RAILS_ENV=test &amp;quot; command&lt;br /&gt;
#* Scrub the DB using &amp;quot; mysql -u root expertiza_development &amp;lt; expertiza-scrubbed.sql&amp;quot;&lt;br /&gt;
#* Run the &amp;quot; rake db:migrate &amp;quot;&lt;br /&gt;
# Run &amp;quot; rake test test/unit/review_response_map_test.rb &amp;quot; in the &amp;quot;expertiza/&amp;quot; directory.&lt;br /&gt;
#* If you run into a mysql log in error go into config/database.yml and edit the mysql credentials for the test section so that it matches the local environment's mysql configuration&lt;br /&gt;
# Check if tests passed or failed.&lt;br /&gt;
&lt;br /&gt;
= Manual Test Case =&lt;br /&gt;
&lt;br /&gt;
In order to test the changes made to the ReviewResponseMap, bring up [[ http://152.46.16.195:5902/ | Expertiza]] and log in as an administrator.  Once logged in, proceed with the following steps:&lt;br /&gt;
&lt;br /&gt;
# Go to '''impersonate user''' when logged in as ''instructor6'' and type in ''student559'' (or) just log in as ''student559''. All passwords are ''password'' .&lt;br /&gt;
# Pick any assignment to view.&lt;br /&gt;
# Navigate to '''Other's work'''.&lt;br /&gt;
# Check the different reviews and metareviews. Whether they are being displayed correctly or not.&lt;br /&gt;
# Go to Edit or Give feedback and submit a feedback.&lt;br /&gt;
# Go back and check if the feedback given is displayed correctly or not.&lt;br /&gt;
# Check if author's feedback is correct or not.&lt;br /&gt;
# Go to the '''Temp''' assignment and see if the page is being displayed correctly or not (since there is no assignment submission content or reviews for that).&lt;br /&gt;
&lt;br /&gt;
''NOTE: Since this was a refactoring of the code and methods, the existing functionality was supposed to remain the same and not break for the changes we've made.''&lt;br /&gt;
&lt;br /&gt;
= References =&lt;br /&gt;
&lt;br /&gt;
&amp;lt;references/&amp;gt;&lt;/div&gt;</summary>
		<author><name>Cnbrown4</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2015/ossE1558BGJ&amp;diff=98475</id>
		<title>CSC/ECE 517 Fall 2015/ossE1558BGJ</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2015/ossE1558BGJ&amp;diff=98475"/>
		<updated>2015-11-06T21:45:50Z</updated>

		<summary type="html">&lt;p&gt;Cnbrown4: /* Code Changes */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Introduction =&lt;br /&gt;
&lt;br /&gt;
This page provides a description of the modifications and improvements made to the Expertiza project’s source code as part of an Expertiza based Open Source Software project.  Expertiza is a web based application which allows students to submit and peer-review classmates’ work, including written articles and development projects. The specific changes made during the course of this project were to the ReviewResponseMap.rb file, with additional changes made to other related files in support of refactoring ReviewResponseMap.rb.  &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
= Problem Statement =&lt;br /&gt;
&lt;br /&gt;
ReviewResponseMap is the model class used to manage the relationship between contributors, reviewers, and assignments.  The intent of the changes were to refactor the code for better readability and adherence to Ruby coding standards and best practices.  Primarily these changes involved the refactoring of overly complex methods, renaming methods for better readability, and the addition of missing unit tests.&lt;br /&gt;
&lt;br /&gt;
Project Requirements:&lt;br /&gt;
&lt;br /&gt;
# Code Climate&amp;lt;ref name=&amp;quot;Code Climate&amp;quot;&amp;gt;https://codeclimate.com&amp;lt;/ref&amp;gt; shows import method is complex, because of lots of checks. This method can be fixed by adding private methods for raising import error.&lt;br /&gt;
# Get_assessments_round_for method can be renamed to get_team_responses_for_round. Team_id private variable is not needed.&lt;br /&gt;
# metareview_response_maps rename, refactoring can be done. No need to do second iteration.&lt;br /&gt;
# write missing unit tests for existing methods.&lt;br /&gt;
&lt;br /&gt;
= Design Patterns =&lt;br /&gt;
&lt;br /&gt;
As part of our project, we refactored the model to follow the Single Responsibility and Don't Repeat Yourself (DRY) Principles.  Both of the principles focus on reducing code repetition and increasing the cohesion of the individual methods in the class.  The Single Responsibility Principle states that each class and method should have sole responsibility over one single part of the functionality of the system&amp;lt;ref&amp;gt;https://en.wikipedia.org/wiki/Single_responsibility_principle&amp;lt;/ref&amp;gt;.  The DRY principle states that whenever the same types of logic and functionality are being performed in a class the duplicated logic should be extracted into a new method that can be called in place of the repeated lines of code &amp;lt;ref&amp;gt;https://en.wikipedia.org/wiki/Don%27t_repeat_yourself&amp;lt;/ref&amp;gt;.  A prime example of a method that initially violated these principles was the import method, which in addition to performing the core import processes also performed a number of checks that would be more properly extracted into private methods.&lt;br /&gt;
&lt;br /&gt;
=Code Changes =&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Refactoring of import method ===&lt;br /&gt;
&lt;br /&gt;
CodeClimate reports showed the import method to be overly complex, with a number of checks being included within the import method itself.  The resolution for this problem was to refactor the import method, creating private methods to perform the null checks and throw import errors.  Prior to refactoring, all null checks were performed within the import method.   After refactoring, the import method adheres to the single responsibility principle, performing only key import tasks while making calls to private methods for any necessary validation. The size of the import method was reduced by doing this and counts for better readability of the code. Also, this method is a very important one and care was taken so that any existing functionality did not break. &lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
Before refactoring:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;big&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 def self.import(row, session, id)&lt;br /&gt;
    if row.length &amp;lt; 2&lt;br /&gt;
      raise ArgumentError, &amp;quot;Not enough items&amp;quot;&lt;br /&gt;
    end&lt;br /&gt;
    assignment = Assignment.find(id)&lt;br /&gt;
    if assignment.nil?&lt;br /&gt;
      raise ImportError, &amp;quot;The assignment with id \&amp;quot;#{id}\&amp;quot; was not found. &amp;lt;a href='/assignment/new'&amp;gt;Create&amp;lt;/a&amp;gt; this assignment?&amp;quot;&lt;br /&gt;
    end&lt;br /&gt;
    index = 1&lt;br /&gt;
    while index &amp;lt; row.length&lt;br /&gt;
      user = User.find_by_name(row[index].to_s.strip)&lt;br /&gt;
      if user.nil?&lt;br /&gt;
        raise ImportError, &amp;quot;The user account for the reviewer \&amp;quot;#{row[index]}\&amp;quot; was not found. &amp;lt;a href='/users/new'&amp;gt;Create&amp;lt;/a&amp;gt; this user?&amp;quot;&lt;br /&gt;
      end&lt;br /&gt;
      reviewer = AssignmentParticipant.where(user_id: user.id, parent_id:  assignment.id).first&lt;br /&gt;
      if reviewer == nil&lt;br /&gt;
        raise ImportError, &amp;quot;The reviewer \&amp;quot;#{row[index]}\&amp;quot; is not a participant in this assignment. &amp;lt;a href='/users/new'&amp;gt;Register&amp;lt;/a&amp;gt; this user as a participant?&amp;quot;&lt;br /&gt;
      end&lt;br /&gt;
      if assignment.team_assignment&lt;br /&gt;
        reviewee = AssignmentTeam.where(name: row[0].to_s.strip, parent_id:  assignment.id).first&lt;br /&gt;
        if reviewee == nil&lt;br /&gt;
          raise ImportError, &amp;quot;The author \&amp;quot;#{row[0].to_s.strip}\&amp;quot; was not found. &amp;lt;a href='/users/new'&amp;gt;Create&amp;lt;/a&amp;gt; this user?&amp;quot;&lt;br /&gt;
        end&lt;br /&gt;
        existing = ReviewResponseMap.where(reviewee_id: reviewee.id, reviewer_id:  reviewer.id).first&lt;br /&gt;
        if existing.nil?&lt;br /&gt;
          ReviewResponseMap.create(:reviewer_id =&amp;gt; reviewer.id, :reviewee_id =&amp;gt; reviewee.id, :reviewed_object_id =&amp;gt; assignment.id)&lt;br /&gt;
        end&lt;br /&gt;
      else&lt;br /&gt;
        puser = User.find_by_name(row[0].to_s.strip)&lt;br /&gt;
        if user == nil&lt;br /&gt;
          raise ImportError, &amp;quot;The user account for the reviewee \&amp;quot;#{row[0]}\&amp;quot; was not found. &amp;lt;a href='/users/new'&amp;gt;Create&amp;lt;/a&amp;gt; this user?&amp;quot;&lt;br /&gt;
        end&lt;br /&gt;
        reviewee = AssignmentParticipant.where(user_id: puser.id, parent_id:  assignment.id).first&lt;br /&gt;
        if reviewee == nil&lt;br /&gt;
          raise ImportError, &amp;quot;The author \&amp;quot;#{row[0].to_s.strip}\&amp;quot; was not found. &amp;lt;a href='/users/new'&amp;gt;Create&amp;lt;/a&amp;gt; this user?&amp;quot;&lt;br /&gt;
        end&lt;br /&gt;
        team_id = TeamsUser.team_id(reviewee.parent_id, reviewee.user_id)&lt;br /&gt;
        existing = ReviewResponseMap.where(reviewee_id: team_id, reviewer_id:  reviewer.id).first&lt;br /&gt;
        if existing.nil?&lt;br /&gt;
          ReviewResponseMap.create(:reviewee_id =&amp;gt; team_id, :reviewer_id =&amp;gt; reviewer.id, :reviewed_object_id =&amp;gt; assignment.id)&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
      index += 1&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
&lt;br /&gt;
After refactoring:&lt;br /&gt;
 &lt;br /&gt;
  &amp;lt;big&amp;gt;&amp;lt;nowiki&amp;gt;#Imports new reponse maps if they do not already exist&lt;br /&gt;
  def self.import(row, _session, id)&lt;br /&gt;
      if row.length &amp;lt; 2&lt;br /&gt;
          raise ArgumentError, 'Not enough items'&lt;br /&gt;
      end&lt;br /&gt;
      assignment = find_assignment(id)&lt;br /&gt;
      index = 1&lt;br /&gt;
      reviewee_name = row[0]&lt;br /&gt;
      while index &amp;lt; row.length&lt;br /&gt;
          reviewee_id = nil&lt;br /&gt;
          reviewer_name = row[index]&lt;br /&gt;
          reviewer = get_assignment_participant(reviewer_name,  assignment.id, &amp;quot;reviewer&amp;quot;)&lt;br /&gt;
          participant_nil?(reviewer, reviewer_name , &amp;quot;reviewer&amp;quot;)&lt;br /&gt;
         &lt;br /&gt;
         #Find reviewee if assignment is a team assignment&lt;br /&gt;
         if assignment.team_assignment&lt;br /&gt;
             reviewee = AssignmentTeam.where(name: reviewee_name .to_s.strip, parent_id: assignment.id).first&lt;br /&gt;
             participant_nil?(reviewee, reviewee_name, &amp;quot;author&amp;quot;)&lt;br /&gt;
             reviewee_id = reviewee.id&lt;br /&gt;
         #Find reviewee if assignment is not a team assignment&lt;br /&gt;
         else&lt;br /&gt;
	     reviewee = get_assignment_participant(reviewee_name, assignment.id, &amp;quot;reviewee&amp;quot;)&lt;br /&gt;
             participant_nil?(reviewee, reviewee_name, &amp;quot;author&amp;quot;)&lt;br /&gt;
             reviewee_id  = TeamsUser.team_id(reviewee.parent_id, reviewee.user_id)&lt;br /&gt;
         end&lt;br /&gt;
         create_response_map(reviewer, reviewee_id,  assignment)&lt;br /&gt;
         index += 1&lt;br /&gt;
      end&lt;br /&gt;
  end&amp;lt;/nowiki&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Private methods added:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;big&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  # Check for if assignment value is null&lt;br /&gt;
  def self.find_assignment(id)&lt;br /&gt;
      begin&lt;br /&gt;
          assignment = Assignment.find(id)&lt;br /&gt;
      rescue ActiveRecord::RecordNotFound&lt;br /&gt;
          raise ImportError, &amp;quot;The assignment with id \&amp;quot;#{id}\&amp;quot; was not found.&amp;lt;a href='/assignment/new'&amp;gt;Create&amp;lt;/a&amp;gt; this assignment?&amp;quot;&lt;br /&gt;
      end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  # Check for if participant is null&lt;br /&gt;
  def self.participant_nil?(participant, user_name, participant_type) &lt;br /&gt;
      error_message = nil&lt;br /&gt;
      if participant_type == &amp;quot;author&amp;quot;&lt;br /&gt;
          error_message = &amp;quot;The author \&amp;quot;#{user_name.to_s.strip}\&amp;quot; was not found.&amp;lt;a href='/users/new'&amp;gt;Create&amp;lt;/a&amp;gt; this user?&amp;quot;&lt;br /&gt;
      else&lt;br /&gt;
          error_message =  &amp;quot;The reviewer \&amp;quot;#{user_name}\&amp;quot; is not a participant in this assignment.&amp;lt;a href='/users/new'&amp;gt;Register&amp;lt;/a&amp;gt; this user as a participant?&amp;quot;&lt;br /&gt;
      end&lt;br /&gt;
      check_nil?(participant, error_message)&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  # Check for if user is null&lt;br /&gt;
  def self.user_nil?(user, user_name, user_type)&lt;br /&gt;
      check_nil?( user, &amp;quot;The user account for the \&amp;quot;#{user_type}\&amp;quot; \&amp;quot;#{user_name}\&amp;quot; was not found.&amp;lt;a href='/users/new'&amp;gt;Create&amp;lt;/a&amp;gt; this user?&amp;quot;)&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
 #Throws import error for nil objects&lt;br /&gt;
  def self.check_nil?(object, error_message)&lt;br /&gt;
      if object.nil?&lt;br /&gt;
          raise ImportError, error_message&lt;br /&gt;
      end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Refactoring of get_assessments_round_for method ===&lt;br /&gt;
&lt;br /&gt;
The get_assessments_round_for method’s name failed to provide a clear idea of the method’s purpose and functionality.  This is why it was renamed to get_team_responses_for_round, the new name of the method provides a clearer idea of its purpose. Additionally, there was a private variable, team_id, introduced in the method that was unnecessary and could be replaced by using the id property of the team parameter directly.  We also removed the return statement at the end of the method.  &lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
Before refactoring:&lt;br /&gt;
&amp;lt;big&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  def self.get_assessments_round_for(team,round)&lt;br /&gt;
    team_id =team.id&lt;br /&gt;
    responses = Array.new&lt;br /&gt;
    if team_id&lt;br /&gt;
      maps = ResponseMap.where(:reviewee_id =&amp;gt; team_id, :type =&amp;gt; &amp;quot;ReviewResponseMap&amp;quot;)&lt;br /&gt;
      maps.each{ |map|&lt;br /&gt;
        if !map.response.empty? &amp;amp;&amp;amp; !map.response.reject{|r| r.round!=round}.empty?&lt;br /&gt;
          responses &amp;lt;&amp;lt; map.response.reject{|r| r.round!=round}.last&lt;br /&gt;
        end&lt;br /&gt;
      }&lt;br /&gt;
      responses.sort! {|a,b| a.map.reviewer.fullname &amp;lt;=&amp;gt; b.map.reviewer.fullname }&lt;br /&gt;
    end&lt;br /&gt;
    return responses&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
&lt;br /&gt;
After refactoring: &lt;br /&gt;
&lt;br /&gt;
&amp;lt;big&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  # return the responses for specified round,&lt;br /&gt;
  # for varying rubric feature -Yang&lt;br /&gt;
  def self.get_team_responses_for_round(team, round)&lt;br /&gt;
    responses = []&lt;br /&gt;
    if team.id&lt;br /&gt;
      maps = ResponseMap.where(reviewee_id: team.id, type: 'ReviewResponseMap')&lt;br /&gt;
      maps.each do |map|&lt;br /&gt;
        unless map.response.empty? &amp;amp;&amp;amp; map.response.reject { |r| r.round != round }.empty?&lt;br /&gt;
          responses &amp;lt;&amp;lt; map.response.reject { |r| r.round != round }.last&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
      responses.sort! { |a, b| a.map.reviewer.fullname &amp;lt;=&amp;gt; b.map.reviewer.fullname }&lt;br /&gt;
    end&lt;br /&gt;
    responses&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
The change in method name also required changes to the following files that referenced it:&lt;br /&gt;
&lt;br /&gt;
/app/models/assignment.rb:436:    &lt;br /&gt;
 &lt;br /&gt;
&amp;lt;big&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  assessments = ReviewResponseMap.get_assessments_round_for(team,i)&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt; &lt;br /&gt;
&lt;br /&gt;
./app/models/assignment_participant.rb:268:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;big&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 scores[questionnaire_symbol][:assessments] = questionnaire.get_assessments_round_for(self,round)&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Refactoring of metareview_response_maps method ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The metareview_response_maps method was unnecessarily complex.  It contained an unneeded private variable and an unnecessary nested loop.  Originally, it added each metareview map individually in the nested loop.  We decided to remove the nested loop and use the concat method for readability and maintainability.  These changes allowed us to remove the private variable &amp;quot;metareview_list&amp;quot; and only maintain the &amp;quot;metareview_response_maps&amp;quot; variable.  We also renamed the metareview_response_maps method to get_metareview_response_maps method to be more descriptive about the intent of the method. &lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
Before refactoring:&lt;br /&gt;
&amp;lt;big&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 def metareview_response_maps&lt;br /&gt;
    responses = Response.where(map_id:self.id)&lt;br /&gt;
    metareview_list=[]&lt;br /&gt;
    responses.each do |response|&lt;br /&gt;
      metareview_response_maps = MetareviewResponseMap.where(reviewed_object_id:response.id)&lt;br /&gt;
      metareview_response_maps.each do |metareview_response_map|&lt;br /&gt;
        metareview_list&amp;lt;&amp;lt;metareview_response_map&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
    metareview_list&lt;br /&gt;
 end&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
After refactoring:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;big&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  # Returns the response maps for all the metareviews&lt;br /&gt;
  def get_metareview_response_maps&lt;br /&gt;
    responses = Response.where(map_id: id)&lt;br /&gt;
    metareview_response_maps = []&lt;br /&gt;
    responses.each do |response|&lt;br /&gt;
      metareview_response_maps.concat MetareviewResponseMap.where(reviewed_object_id: response.id)&lt;br /&gt;
    end&lt;br /&gt;
    metareview_response_maps&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Refactoring of export method ===&lt;br /&gt;
The export method contained mappings.sort! { |a, b| a.reviewee.name &amp;lt;=&amp;gt; b.reviewee.name }.  We could not get past this when running tests, we kept getting a message saying, &amp;quot;sort! was not a method for an ActiveRecord_Relation&amp;quot;.  But, ActiveRecord_Relation does allow the use of sort.  So we changed that line of code to  mappings = mappings.sort { |a, b| a.reviewee.name &amp;lt;=&amp;gt; b.reviewee.name }&lt;br /&gt;
&lt;br /&gt;
Before refactoring:&lt;br /&gt;
&amp;lt;big&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  def self.export(csv, parent_id, options)&lt;br /&gt;
    mappings = where(reviewed_object_id: parent_id)&lt;br /&gt;
    mappings.sort! { |a, b| a.reviewee.name &amp;lt;=&amp;gt; b.reviewee.name }&lt;br /&gt;
    mappings.each {&lt;br /&gt;
      |map|&lt;br /&gt;
      csv &amp;lt;&amp;lt; [&lt;br /&gt;
        map.reviewee.name,&lt;br /&gt;
        map.reviewer.name&lt;br /&gt;
      ]&lt;br /&gt;
    }&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
&lt;br /&gt;
After refactoring:&lt;br /&gt;
&amp;lt;big&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  # options parameter used as a signature in other models&lt;br /&gt;
  def self.export(csv, parent_id, options)&lt;br /&gt;
    mappings = where(reviewed_object_id: parent_id)&lt;br /&gt;
    mappings = mappings.sort { |a, b| a.reviewee.name &amp;lt;=&amp;gt; b.reviewee.name }&lt;br /&gt;
    mappings.each do&lt;br /&gt;
    |map|&lt;br /&gt;
      csv &amp;lt;&amp;lt; [map.reviewee.name, map.reviewer.name]&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Refactoring of final_versions_from_reviewer method ===&lt;br /&gt;
The final_versions_from_reviewer method was too long and repetitive.  We removed common functionality from within the if and else statement and put it in a private method final_versions_from_reviewer.  Then we created the get_responses method to find the responses based on the arguments values.  These private methods make the class more readable for other programmers.&lt;br /&gt;
 &lt;br /&gt;
Before refactoring:&lt;br /&gt;
&amp;lt;big&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  def self.final_versions_from_reviewer(reviewer_id)&lt;br /&gt;
    maps = ReviewResponseMap.where(reviewer_id: reviewer_id)&lt;br /&gt;
    assignment = Assignment.find(Participant.find(reviewer_id).parent_id)&lt;br /&gt;
    review_final_versions = Hash.new&lt;br /&gt;
    if !assignment.varying_rubrics_by_round?&lt;br /&gt;
      #same review rubric used in multiple rounds&lt;br /&gt;
      review_final_versions[:review] = Hash.new&lt;br /&gt;
      review_final_versions[:review][:questionnaire_id] = assignment.get_review_questionnaire_id&lt;br /&gt;
      response_ids = Array.new&lt;br /&gt;
      maps.each do |map|&lt;br /&gt;
        responses = Response.where(map_id:map.id)&lt;br /&gt;
        if !responses.empty?&lt;br /&gt;
          response_ids &amp;lt;&amp;lt; responses.last.id&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
      review_final_versions[:review][:response_ids] = response_ids&lt;br /&gt;
    else&lt;br /&gt;
      #vary rubric by round&lt;br /&gt;
      rounds_num = assignment.rounds_of_reviews&lt;br /&gt;
      for round in 1..rounds_num&lt;br /&gt;
        symbol = (&amp;quot;review round&amp;quot;+round.to_s).to_sym&lt;br /&gt;
        review_final_versions[symbol] = Hash.new&lt;br /&gt;
        review_final_versions[symbol][:questionnaire_id] = assignment.get_review_questionnaire_id(round)&lt;br /&gt;
        response_ids = Array.new&lt;br /&gt;
        maps.each do |map|&lt;br /&gt;
          responses = Response.where(map_id:map.id, round:round)&lt;br /&gt;
          if !responses.empty?&lt;br /&gt;
            response_ids &amp;lt;&amp;lt; responses.last.id&lt;br /&gt;
          end&lt;br /&gt;
        end&lt;br /&gt;
        review_final_versions[symbol][:response_ids] = response_ids&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
    review_final_versions&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
&lt;br /&gt;
After refactoring:&lt;br /&gt;
&amp;lt;big&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  # wrap The latest version of responses in each response map,&lt;br /&gt;
  # together with the questionnaire_id will be used to&lt;br /&gt;
  # display the reviewer summary&lt;br /&gt;
  def self.final_versions_from_reviewer(reviewer_id)&lt;br /&gt;
    maps = ReviewResponseMap.where(reviewer_id: reviewer_id)&lt;br /&gt;
    assignment = find_assignment(Participant.find(reviewer_id).parent_id)&lt;br /&gt;
    review_final_versions = {}&lt;br /&gt;
    unless assignment.varying_rubrics_by_round?&lt;br /&gt;
      #same review rubric used in multiple rounds&lt;br /&gt;
      review_final_versions = review_final_version_responses(:review, :questionnaire_id, assignment, maps)&lt;br /&gt;
    else&lt;br /&gt;
      # vary rubric by round&lt;br /&gt;
      rounds_num = assignment.rounds_of_reviews&lt;br /&gt;
      (1..rounds_num).each do |round|&lt;br /&gt;
        symbol = ('review round' + round.to_s).to_sym&lt;br /&gt;
        review_final_versions = review_final_version_responses(symbol, :questionnaire_id, assignment, maps, round)&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
    review_final_versions&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Private methods added:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;big&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  # Compute list of responses and return it&lt;br /&gt;
  def self.review_final_version_responses(symbol, questionnaire_id, assignment, maps, round = nil)&lt;br /&gt;
    review_final_versions = {}&lt;br /&gt;
    review_final_versions[symbol] = {}&lt;br /&gt;
    review_final_versions[symbol][questionnaire_id] = assignment.get_review_questionnaire_id(round)&lt;br /&gt;
    response_ids = []&lt;br /&gt;
    maps.each do |map|&lt;br /&gt;
      responses =  get_responses(map.id, round)&lt;br /&gt;
      unless responses.empty?&lt;br /&gt;
        response_ids &amp;lt;&amp;lt; responses.last.id&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
    review_final_versions[symbol][:response_ids] = response_ids&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;big&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  #Get responses by map_id and round (if exists)&lt;br /&gt;
  def self.get_responses(id, round)&lt;br /&gt;
     if round.nil?&lt;br /&gt;
       responses = Response.where(map_id: id)&lt;br /&gt;
     else&lt;br /&gt;
       responses = Response.where(map_id: id, round: round)&lt;br /&gt;
     end	&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Refactoring of other methods ===&lt;br /&gt;
Although trivial, we removed the return statement from the get_title, export_fields, and show_feedback methods because return statements are unnecessary in Ruby.&lt;br /&gt;
&lt;br /&gt;
=== Addition of code comments ===&lt;br /&gt;
&lt;br /&gt;
We added comments to all of the methods in the ReviewResponseMap.rb file and corrected instances where CodeClimate Identified opportunities for code improvement.  One issue flagged by CodeClimate that we did not change was to use the find_by method instead of where().first method.  The where().first method occurs in the import, get_assignment_participant, and create_response_map methods. It is not always appropriate to use the find_by method, as documented in this github post: https://github.com/bbatsov/rubocop/issues/1938 .  In instances where ordering by id is the desired behavior, where().first will order by default, but in Rails 4+ find_by does not honor that default behavior.  For this reason we left the instances of where().first unchanged.&lt;br /&gt;
&lt;br /&gt;
=== Code Improvements ===&lt;br /&gt;
&lt;br /&gt;
This refactoring was to improve readability and follow as many good ''Rubyist'' coding practices as possible without breaking the functionality of existing code. We used CodeClimate of the master branch code as a reference. We took the suggestions we got from CodeClimate and improved our code based on that.&lt;br /&gt;
We also made some of the methods shorter by removing redundant functionality and adding private methods to methods with a lot internal functionality. We also added private methods in places where we saw repeated patterns to make the code ''DRYer''.&lt;br /&gt;
At the end of our refactoring, we managed to improve the rating on CodeClimate from a '''C''' to a '''B''' . Further improvements meant reducing the size of the entire class which required a much more significant refactoring in multiple files and folders. We focused on refactoring the existing model, '''ReviewResponseMap'''.&lt;br /&gt;
&lt;br /&gt;
= Unit Tests =&lt;br /&gt;
The previous unit tests had syntactical and run time errors.  We were not able to get the previous unit tests to run without errors.  Because of this we rewrote all of the unit tests for the &amp;lt;b&amp;gt;ReviewResponseModel&amp;lt;/b&amp;gt;.  It is important to have working unit tests so that when internal changes are made to functions the external output remains the same.&lt;br /&gt;
&lt;br /&gt;
=== Refactoring of Unit Tests===&lt;br /&gt;
&lt;br /&gt;
We added a test_helper file to the main test folder that requires a needed configuration file and needed gems.  We also added 8 fixtures that were needed for data to run the unit tests.  The following fixture files were added:&lt;br /&gt;
&lt;br /&gt;
* assignment_questionnaires.yml&lt;br /&gt;
* assignments.yml&lt;br /&gt;
* participants.yml&lt;br /&gt;
* questionnaires.yml&lt;br /&gt;
* response_maps.yml&lt;br /&gt;
* responses.yml&lt;br /&gt;
* teams.yml&lt;br /&gt;
* users.yml&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
There is at least one unit test for every public method within the &amp;lt;b&amp;gt;ReviewResponseModel&amp;lt;/b&amp;gt;.  The test naming convention used is &amp;quot;method_&amp;lt;name of method that is being tested&amp;gt;&amp;quot;.  For example, the unit test for the export method is &amp;quot;method_export&amp;quot;.  If there are multiple test for one method the name of the test will include the test case after the normal naming convention.  For example, one of the unit tests for the import method checks for an invalid assignment.  The name of this method is &amp;quot;method_import_invalid_assignment&amp;quot;.  The following are the unit tests we created:&lt;br /&gt;
&lt;br /&gt;
* method_export&lt;br /&gt;
* method_get_metareview_response_maps&lt;br /&gt;
* method_get_team_response_for_round&lt;br /&gt;
* method_final_versions_from_reviewer&lt;br /&gt;
* method_import&lt;br /&gt;
* method_import_invalid_reviewee&lt;br /&gt;
* method_import_invalid_reviewer&lt;br /&gt;
* method_import_invalid_assignment&lt;br /&gt;
* method_delete&lt;br /&gt;
* method_delete_no _force&lt;br /&gt;
* method_show_feedback&lt;br /&gt;
* method_get_title&lt;br /&gt;
* method_export_fields&lt;br /&gt;
* method_questionnaire&lt;br /&gt;
* method_add_reviewer&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== How to Run Unit Tests ===&lt;br /&gt;
To run the unit tests, follow these steps:&lt;br /&gt;
&lt;br /&gt;
# Download the master branch of the repo.&lt;br /&gt;
# Setup the Databases for the test environment (we have used Zhewei's scrubbed expertiza DB )&lt;br /&gt;
#* Run the &amp;quot; rake db:create RAILS_ENV=test &amp;quot; command&lt;br /&gt;
#* Run the &amp;quot; rake db:reset RAILS_ENV=test &amp;quot; command&lt;br /&gt;
#* Scrub the DB using &amp;quot; mysql -u root expertiza_development &amp;lt; expertiza-scrubbed.sql&amp;quot;&lt;br /&gt;
#* Run the &amp;quot; rake db:migrate &amp;quot;&lt;br /&gt;
# Run &amp;quot; rake test test/unit/review_response_map_test.rb &amp;quot; in the &amp;quot;expertiza/&amp;quot; directory.&lt;br /&gt;
#* If you run into a mysql log in error go into config/database.yml and edit the mysql credentials for the test section so that it matches the local environment's mysql configuration&lt;br /&gt;
# Check if tests passed or failed.&lt;br /&gt;
&lt;br /&gt;
= Manual Test Case =&lt;br /&gt;
&lt;br /&gt;
In order to test the changes made to the ReviewResponseMap, bring up [[ http://152.46.16.195:5902/ | Expertiza]] and log in as an administrator.  Once logged in, proceed with the following steps:&lt;br /&gt;
&lt;br /&gt;
# Go to '''impersonate user''' when logged in as ''instructor6'' and type in ''student559'' (or) just log in as ''student559''. All passwords are ''password'' .&lt;br /&gt;
# Pick any assignment to view.&lt;br /&gt;
# Navigate to '''Other's work'''.&lt;br /&gt;
# Check the different reviews and metareviews. Whether they are being displayed correctly or not.&lt;br /&gt;
# Go to Edit or Give feedback and submit a feedback.&lt;br /&gt;
# Go back and check if the feedback given is displayed correctly or not.&lt;br /&gt;
# Check if author's feedback is correct or not.&lt;br /&gt;
# Go to the '''Temp''' assignment and see if the page is being displayed correctly or not (since there is no assignment submission content or reviews for that).&lt;br /&gt;
&lt;br /&gt;
''NOTE: Since this was a refactoring of the code and methods, the existing functionality was supposed to remain the same and not break for the changes we've made.''&lt;br /&gt;
&lt;br /&gt;
= References =&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;references/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;4.&amp;amp;nbsp; [https://github.com/expertiza/expertiza Expertiza Main Repo] &amp;lt;br&amp;gt;&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;5.&amp;amp;nbsp; [https://github.com/adeeshag/expertiza/blob/develop/app/models/review_response_map.rb Refactored ReviewResponseMap.rb]&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;6.&amp;amp;nbsp; [https://github.com/adeeshag/expertiza/tree/develop/test/fixtures Test Fixtures]&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;7.&amp;amp;nbsp; [https://github.com/adeeshag/expertiza/blob/develop/test/unit/review_response_map_test.rb Unit Tests]&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;8.&amp;amp;nbsp; [http://152.46.16.195:5902/ Expertiza Deployed Site]&amp;lt;br&amp;gt;&lt;/div&gt;</summary>
		<author><name>Cnbrown4</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2015/ossE1558BGJ&amp;diff=98474</id>
		<title>CSC/ECE 517 Fall 2015/ossE1558BGJ</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2015/ossE1558BGJ&amp;diff=98474"/>
		<updated>2015-11-06T21:45:17Z</updated>

		<summary type="html">&lt;p&gt;Cnbrown4: /* Refactoring of final_versions_from_reviewer method */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Introduction =&lt;br /&gt;
&lt;br /&gt;
This page provides a description of the modifications and improvements made to the Expertiza project’s source code as part of an Expertiza based Open Source Software project.  Expertiza is a web based application which allows students to submit and peer-review classmates’ work, including written articles and development projects. The specific changes made during the course of this project were to the ReviewResponseMap.rb file, with additional changes made to other related files in support of refactoring ReviewResponseMap.rb.  &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
= Problem Statement =&lt;br /&gt;
&lt;br /&gt;
ReviewResponseMap is the model class used to manage the relationship between contributors, reviewers, and assignments.  The intent of the changes were to refactor the code for better readability and adherence to Ruby coding standards and best practices.  Primarily these changes involved the refactoring of overly complex methods, renaming methods for better readability, and the addition of missing unit tests.&lt;br /&gt;
&lt;br /&gt;
Project Requirements:&lt;br /&gt;
&lt;br /&gt;
# Code Climate&amp;lt;ref name=&amp;quot;Code Climate&amp;quot;&amp;gt;https://codeclimate.com&amp;lt;/ref&amp;gt; shows import method is complex, because of lots of checks. This method can be fixed by adding private methods for raising import error.&lt;br /&gt;
# Get_assessments_round_for method can be renamed to get_team_responses_for_round. Team_id private variable is not needed.&lt;br /&gt;
# metareview_response_maps rename, refactoring can be done. No need to do second iteration.&lt;br /&gt;
# write missing unit tests for existing methods.&lt;br /&gt;
&lt;br /&gt;
= Design Patterns =&lt;br /&gt;
&lt;br /&gt;
As part of our project, we refactored the model to follow the Single Responsibility and Don't Repeat Yourself (DRY) Principles.  Both of the principles focus on reducing code repetition and increasing the cohesion of the individual methods in the class.  The Single Responsibility Principle states that each class and method should have sole responsibility over one single part of the functionality of the system&amp;lt;ref&amp;gt;https://en.wikipedia.org/wiki/Single_responsibility_principle&amp;lt;/ref&amp;gt;.  The DRY principle states that whenever the same types of logic and functionality are being performed in a class the duplicated logic should be extracted into a new method that can be called in place of the repeated lines of code &amp;lt;ref&amp;gt;https://en.wikipedia.org/wiki/Don%27t_repeat_yourself&amp;lt;/ref&amp;gt;.  A prime example of a method that initially violated these principles was the import method, which in addition to performing the core import processes also performed a number of checks that would be more properly extracted into private methods.&lt;br /&gt;
&lt;br /&gt;
=Code Changes =&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Refactoring of import method ===&lt;br /&gt;
&lt;br /&gt;
CodeClimate reports showed the import method to be overly complex, with a number of checks being included within the import method itself.  The resolution for this problem was to refactor the import method, creating private methods to perform the null checks and throw import errors.  Prior to refactoring, all null checks were performed within the import method.   After refactoring, the import method adheres to the single responsibility principle, performing only key import tasks while making calls to private methods for any necessary validation. The size of the import method was reduced by doing this and counts for better readability of the code. Also, this method is a very important one and care was taken so that any existing functionality did not break. &lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
Before refactoring:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;big&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 def self.import(row, session, id)&lt;br /&gt;
    if row.length &amp;lt; 2&lt;br /&gt;
      raise ArgumentError, &amp;quot;Not enough items&amp;quot;&lt;br /&gt;
    end&lt;br /&gt;
    assignment = Assignment.find(id)&lt;br /&gt;
    if assignment.nil?&lt;br /&gt;
      raise ImportError, &amp;quot;The assignment with id \&amp;quot;#{id}\&amp;quot; was not found. &amp;lt;a href='/assignment/new'&amp;gt;Create&amp;lt;/a&amp;gt; this assignment?&amp;quot;&lt;br /&gt;
    end&lt;br /&gt;
    index = 1&lt;br /&gt;
    while index &amp;lt; row.length&lt;br /&gt;
      user = User.find_by_name(row[index].to_s.strip)&lt;br /&gt;
      if user.nil?&lt;br /&gt;
        raise ImportError, &amp;quot;The user account for the reviewer \&amp;quot;#{row[index]}\&amp;quot; was not found. &amp;lt;a href='/users/new'&amp;gt;Create&amp;lt;/a&amp;gt; this user?&amp;quot;&lt;br /&gt;
      end&lt;br /&gt;
      reviewer = AssignmentParticipant.where(user_id: user.id, parent_id:  assignment.id).first&lt;br /&gt;
      if reviewer == nil&lt;br /&gt;
        raise ImportError, &amp;quot;The reviewer \&amp;quot;#{row[index]}\&amp;quot; is not a participant in this assignment. &amp;lt;a href='/users/new'&amp;gt;Register&amp;lt;/a&amp;gt; this user as a participant?&amp;quot;&lt;br /&gt;
      end&lt;br /&gt;
      if assignment.team_assignment&lt;br /&gt;
        reviewee = AssignmentTeam.where(name: row[0].to_s.strip, parent_id:  assignment.id).first&lt;br /&gt;
        if reviewee == nil&lt;br /&gt;
          raise ImportError, &amp;quot;The author \&amp;quot;#{row[0].to_s.strip}\&amp;quot; was not found. &amp;lt;a href='/users/new'&amp;gt;Create&amp;lt;/a&amp;gt; this user?&amp;quot;&lt;br /&gt;
        end&lt;br /&gt;
        existing = ReviewResponseMap.where(reviewee_id: reviewee.id, reviewer_id:  reviewer.id).first&lt;br /&gt;
        if existing.nil?&lt;br /&gt;
          ReviewResponseMap.create(:reviewer_id =&amp;gt; reviewer.id, :reviewee_id =&amp;gt; reviewee.id, :reviewed_object_id =&amp;gt; assignment.id)&lt;br /&gt;
        end&lt;br /&gt;
      else&lt;br /&gt;
        puser = User.find_by_name(row[0].to_s.strip)&lt;br /&gt;
        if user == nil&lt;br /&gt;
          raise ImportError, &amp;quot;The user account for the reviewee \&amp;quot;#{row[0]}\&amp;quot; was not found. &amp;lt;a href='/users/new'&amp;gt;Create&amp;lt;/a&amp;gt; this user?&amp;quot;&lt;br /&gt;
        end&lt;br /&gt;
        reviewee = AssignmentParticipant.where(user_id: puser.id, parent_id:  assignment.id).first&lt;br /&gt;
        if reviewee == nil&lt;br /&gt;
          raise ImportError, &amp;quot;The author \&amp;quot;#{row[0].to_s.strip}\&amp;quot; was not found. &amp;lt;a href='/users/new'&amp;gt;Create&amp;lt;/a&amp;gt; this user?&amp;quot;&lt;br /&gt;
        end&lt;br /&gt;
        team_id = TeamsUser.team_id(reviewee.parent_id, reviewee.user_id)&lt;br /&gt;
        existing = ReviewResponseMap.where(reviewee_id: team_id, reviewer_id:  reviewer.id).first&lt;br /&gt;
        if existing.nil?&lt;br /&gt;
          ReviewResponseMap.create(:reviewee_id =&amp;gt; team_id, :reviewer_id =&amp;gt; reviewer.id, :reviewed_object_id =&amp;gt; assignment.id)&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
      index += 1&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
&lt;br /&gt;
After refactoring:&lt;br /&gt;
 &lt;br /&gt;
  &amp;lt;big&amp;gt;&amp;lt;nowiki&amp;gt;#Imports new reponse maps if they do not already exist&lt;br /&gt;
  def self.import(row, _session, id)&lt;br /&gt;
      if row.length &amp;lt; 2&lt;br /&gt;
          raise ArgumentError, 'Not enough items'&lt;br /&gt;
      end&lt;br /&gt;
      assignment = find_assignment(id)&lt;br /&gt;
      index = 1&lt;br /&gt;
      reviewee_name = row[0]&lt;br /&gt;
      while index &amp;lt; row.length&lt;br /&gt;
          reviewee_id = nil&lt;br /&gt;
          reviewer_name = row[index]&lt;br /&gt;
          reviewer = get_assignment_participant(reviewer_name,  assignment.id, &amp;quot;reviewer&amp;quot;)&lt;br /&gt;
          participant_nil?(reviewer, reviewer_name , &amp;quot;reviewer&amp;quot;)&lt;br /&gt;
         &lt;br /&gt;
         #Find reviewee if assignment is a team assignment&lt;br /&gt;
         if assignment.team_assignment&lt;br /&gt;
             reviewee = AssignmentTeam.where(name: reviewee_name .to_s.strip, parent_id: assignment.id).first&lt;br /&gt;
             participant_nil?(reviewee, reviewee_name, &amp;quot;author&amp;quot;)&lt;br /&gt;
             reviewee_id = reviewee.id&lt;br /&gt;
         #Find reviewee if assignment is not a team assignment&lt;br /&gt;
         else&lt;br /&gt;
	     reviewee = get_assignment_participant(reviewee_name, assignment.id, &amp;quot;reviewee&amp;quot;)&lt;br /&gt;
             participant_nil?(reviewee, reviewee_name, &amp;quot;author&amp;quot;)&lt;br /&gt;
             reviewee_id  = TeamsUser.team_id(reviewee.parent_id, reviewee.user_id)&lt;br /&gt;
         end&lt;br /&gt;
         create_response_map(reviewer, reviewee_id,  assignment)&lt;br /&gt;
         index += 1&lt;br /&gt;
      end&lt;br /&gt;
  end&amp;lt;/nowiki&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Private methods added:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;big&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  # Check for if assignment value is null&lt;br /&gt;
  def self.find_assignment(id)&lt;br /&gt;
      begin&lt;br /&gt;
          assignment = Assignment.find(id)&lt;br /&gt;
      rescue ActiveRecord::RecordNotFound&lt;br /&gt;
          raise ImportError, &amp;quot;The assignment with id \&amp;quot;#{id}\&amp;quot; was not found.&amp;lt;a href='/assignment/new'&amp;gt;Create&amp;lt;/a&amp;gt; this assignment?&amp;quot;&lt;br /&gt;
      end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  # Check for if participant is null&lt;br /&gt;
  def self.participant_nil?(participant, user_name, participant_type) &lt;br /&gt;
      error_message = nil&lt;br /&gt;
      if participant_type == &amp;quot;author&amp;quot;&lt;br /&gt;
          error_message = &amp;quot;The author \&amp;quot;#{user_name.to_s.strip}\&amp;quot; was not found.&amp;lt;a href='/users/new'&amp;gt;Create&amp;lt;/a&amp;gt; this user?&amp;quot;&lt;br /&gt;
      else&lt;br /&gt;
          error_message =  &amp;quot;The reviewer \&amp;quot;#{user_name}\&amp;quot; is not a participant in this assignment.&amp;lt;a href='/users/new'&amp;gt;Register&amp;lt;/a&amp;gt; this user as a participant?&amp;quot;&lt;br /&gt;
      end&lt;br /&gt;
      check_nil?(participant, error_message)&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  # Check for if user is null&lt;br /&gt;
  def self.user_nil?(user, user_name, user_type)&lt;br /&gt;
      check_nil?( user, &amp;quot;The user account for the \&amp;quot;#{user_type}\&amp;quot; \&amp;quot;#{user_name}\&amp;quot; was not found.&amp;lt;a href='/users/new'&amp;gt;Create&amp;lt;/a&amp;gt; this user?&amp;quot;)&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
 #Throws import error for nil objects&lt;br /&gt;
  def self.check_nil?(object, error_message)&lt;br /&gt;
      if object.nil?&lt;br /&gt;
          raise ImportError, error_message&lt;br /&gt;
      end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Refactoring of get_assessments_round_for method ===&lt;br /&gt;
&lt;br /&gt;
The get_assessments_round_for method’s name failed to provide a clear idea of the method’s purpose and functionality.  This is why it was renamed to get_team_responses_for_round, the new name of the method provides a clearer idea of its purpose. Additionally, there was a private variable, team_id, introduced in the method that was unnecessary and could be replaced by using the id property of the team parameter directly.  We also removed the return statement at the end of the method.  &lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
Before refactoring:&lt;br /&gt;
&amp;lt;big&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  def self.get_assessments_round_for(team,round)&lt;br /&gt;
    team_id =team.id&lt;br /&gt;
    responses = Array.new&lt;br /&gt;
    if team_id&lt;br /&gt;
      maps = ResponseMap.where(:reviewee_id =&amp;gt; team_id, :type =&amp;gt; &amp;quot;ReviewResponseMap&amp;quot;)&lt;br /&gt;
      maps.each{ |map|&lt;br /&gt;
        if !map.response.empty? &amp;amp;&amp;amp; !map.response.reject{|r| r.round!=round}.empty?&lt;br /&gt;
          responses &amp;lt;&amp;lt; map.response.reject{|r| r.round!=round}.last&lt;br /&gt;
        end&lt;br /&gt;
      }&lt;br /&gt;
      responses.sort! {|a,b| a.map.reviewer.fullname &amp;lt;=&amp;gt; b.map.reviewer.fullname }&lt;br /&gt;
    end&lt;br /&gt;
    return responses&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
&lt;br /&gt;
After refactoring: &lt;br /&gt;
&lt;br /&gt;
&amp;lt;big&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  # return the responses for specified round,&lt;br /&gt;
  # for varying rubric feature -Yang&lt;br /&gt;
  def self.get_team_responses_for_round(team, round)&lt;br /&gt;
    responses = []&lt;br /&gt;
    if team.id&lt;br /&gt;
      maps = ResponseMap.where(reviewee_id: team.id, type: 'ReviewResponseMap')&lt;br /&gt;
      maps.each do |map|&lt;br /&gt;
        unless map.response.empty? &amp;amp;&amp;amp; map.response.reject { |r| r.round != round }.empty?&lt;br /&gt;
          responses &amp;lt;&amp;lt; map.response.reject { |r| r.round != round }.last&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
      responses.sort! { |a, b| a.map.reviewer.fullname &amp;lt;=&amp;gt; b.map.reviewer.fullname }&lt;br /&gt;
    end&lt;br /&gt;
    responses&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
The change in method name also required changes to the following files that referenced it:&lt;br /&gt;
&lt;br /&gt;
/app/models/assignment.rb:436:    &lt;br /&gt;
 &lt;br /&gt;
&amp;lt;big&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  assessments = ReviewResponseMap.get_assessments_round_for(team,i)&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt; &lt;br /&gt;
&lt;br /&gt;
./app/models/assignment_participant.rb:268:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;big&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 scores[questionnaire_symbol][:assessments] = questionnaire.get_assessments_round_for(self,round)&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Refactoring of metareview_response_maps method ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The metareview_response_maps method was unnecessarily complex.  It contained an unneeded private variable and an unnecessary nested loop.  Originally, it added each metareview map individually in the nested loop.  We decided to remove the nested loop and use the concat method for readability and maintainability.  These changes allowed us to remove the private variable &amp;quot;metareview_list&amp;quot; and only maintain the &amp;quot;metareview_response_maps&amp;quot; variable.  We also renamed the metareview_response_maps method to get_metareview_response_maps method to be more descriptive about the intent of the method. &lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
Before refactoring:&lt;br /&gt;
&amp;lt;big&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 def metareview_response_maps&lt;br /&gt;
    responses = Response.where(map_id:self.id)&lt;br /&gt;
    metareview_list=[]&lt;br /&gt;
    responses.each do |response|&lt;br /&gt;
      metareview_response_maps = MetareviewResponseMap.where(reviewed_object_id:response.id)&lt;br /&gt;
      metareview_response_maps.each do |metareview_response_map|&lt;br /&gt;
        metareview_list&amp;lt;&amp;lt;metareview_response_map&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
    metareview_list&lt;br /&gt;
 end&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
After refactoring:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;big&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  # Returns the response maps for all the metareviews&lt;br /&gt;
  def get_metareview_response_maps&lt;br /&gt;
    responses = Response.where(map_id: id)&lt;br /&gt;
    metareview_response_maps = []&lt;br /&gt;
    responses.each do |response|&lt;br /&gt;
      metareview_response_maps.concat MetareviewResponseMap.where(reviewed_object_id: response.id)&lt;br /&gt;
    end&lt;br /&gt;
    metareview_response_maps&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Refactoring of export method ===&lt;br /&gt;
The export method contained mappings.sort! { |a, b| a.reviewee.name &amp;lt;=&amp;gt; b.reviewee.name }.  We could not get past this when running tests, we kept getting a message saying, &amp;quot;sort! was not a method for an ActiveRecord_Relation&amp;quot;.  But, ActiveRecord_Relation does allow the use of sort.  So we changed that line of code to  mappings = mappings.sort { |a, b| a.reviewee.name &amp;lt;=&amp;gt; b.reviewee.name }&lt;br /&gt;
&lt;br /&gt;
Before refactoring:&lt;br /&gt;
&amp;lt;big&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  def self.export(csv, parent_id, options)&lt;br /&gt;
    mappings = where(reviewed_object_id: parent_id)&lt;br /&gt;
    mappings.sort! { |a, b| a.reviewee.name &amp;lt;=&amp;gt; b.reviewee.name }&lt;br /&gt;
    mappings.each {&lt;br /&gt;
      |map|&lt;br /&gt;
      csv &amp;lt;&amp;lt; [&lt;br /&gt;
        map.reviewee.name,&lt;br /&gt;
        map.reviewer.name&lt;br /&gt;
      ]&lt;br /&gt;
    }&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
&lt;br /&gt;
After refactoring:&lt;br /&gt;
&amp;lt;big&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  # options parameter used as a signature in other models&lt;br /&gt;
  def self.export(csv, parent_id, options)&lt;br /&gt;
    mappings = where(reviewed_object_id: parent_id)&lt;br /&gt;
    mappings = mappings.sort { |a, b| a.reviewee.name &amp;lt;=&amp;gt; b.reviewee.name }&lt;br /&gt;
    mappings.each do&lt;br /&gt;
    |map|&lt;br /&gt;
      csv &amp;lt;&amp;lt; [map.reviewee.name, map.reviewer.name]&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Refactoring of final_versions_from_reviewer method ===&lt;br /&gt;
The final_versions_from_reviewer method was too long and repetitive.  We removed common functionality from within the if and else statement and put it in a private method final_versions_from_reviewer.  Then we created the get_responses method to find the responses based on the arguments values.  These private methods make the class more readable for other programmers.&lt;br /&gt;
 &lt;br /&gt;
Before refactoring:&lt;br /&gt;
&amp;lt;big&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  def self.final_versions_from_reviewer(reviewer_id)&lt;br /&gt;
    maps = ReviewResponseMap.where(reviewer_id: reviewer_id)&lt;br /&gt;
    assignment = Assignment.find(Participant.find(reviewer_id).parent_id)&lt;br /&gt;
    review_final_versions = Hash.new&lt;br /&gt;
    if !assignment.varying_rubrics_by_round?&lt;br /&gt;
      #same review rubric used in multiple rounds&lt;br /&gt;
      review_final_versions[:review] = Hash.new&lt;br /&gt;
      review_final_versions[:review][:questionnaire_id] = assignment.get_review_questionnaire_id&lt;br /&gt;
      response_ids = Array.new&lt;br /&gt;
      maps.each do |map|&lt;br /&gt;
        responses = Response.where(map_id:map.id)&lt;br /&gt;
        if !responses.empty?&lt;br /&gt;
          response_ids &amp;lt;&amp;lt; responses.last.id&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
      review_final_versions[:review][:response_ids] = response_ids&lt;br /&gt;
    else&lt;br /&gt;
      #vary rubric by round&lt;br /&gt;
      rounds_num = assignment.rounds_of_reviews&lt;br /&gt;
      for round in 1..rounds_num&lt;br /&gt;
        symbol = (&amp;quot;review round&amp;quot;+round.to_s).to_sym&lt;br /&gt;
        review_final_versions[symbol] = Hash.new&lt;br /&gt;
        review_final_versions[symbol][:questionnaire_id] = assignment.get_review_questionnaire_id(round)&lt;br /&gt;
        response_ids = Array.new&lt;br /&gt;
        maps.each do |map|&lt;br /&gt;
          responses = Response.where(map_id:map.id, round:round)&lt;br /&gt;
          if !responses.empty?&lt;br /&gt;
            response_ids &amp;lt;&amp;lt; responses.last.id&lt;br /&gt;
          end&lt;br /&gt;
        end&lt;br /&gt;
        review_final_versions[symbol][:response_ids] = response_ids&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
    review_final_versions&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
&lt;br /&gt;
After refactoring:&lt;br /&gt;
&amp;lt;big&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  # wrap The latest version of responses in each response map,&lt;br /&gt;
  # together with the questionnaire_id will be used to&lt;br /&gt;
  # display the reviewer summary&lt;br /&gt;
  def self.final_versions_from_reviewer(reviewer_id)&lt;br /&gt;
    maps = ReviewResponseMap.where(reviewer_id: reviewer_id)&lt;br /&gt;
    assignment = find_assignment(Participant.find(reviewer_id).parent_id)&lt;br /&gt;
    review_final_versions = {}&lt;br /&gt;
    unless assignment.varying_rubrics_by_round?&lt;br /&gt;
      #same review rubric used in multiple rounds&lt;br /&gt;
      review_final_versions = review_final_version_responses(:review, :questionnaire_id, assignment, maps)&lt;br /&gt;
    else&lt;br /&gt;
      # vary rubric by round&lt;br /&gt;
      rounds_num = assignment.rounds_of_reviews&lt;br /&gt;
      (1..rounds_num).each do |round|&lt;br /&gt;
        symbol = ('review round' + round.to_s).to_sym&lt;br /&gt;
        review_final_versions = review_final_version_responses(symbol, :questionnaire_id, assignment, maps, round)&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
    review_final_versions&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Private methods added:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;big&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  # Compute list of responses and return it&lt;br /&gt;
  def self.review_final_version_responses(symbol, questionnaire_id, assignment, maps, round = nil)&lt;br /&gt;
    review_final_versions = {}&lt;br /&gt;
    review_final_versions[symbol] = {}&lt;br /&gt;
    review_final_versions[symbol][questionnaire_id] = assignment.get_review_questionnaire_id(round)&lt;br /&gt;
    response_ids = []&lt;br /&gt;
    maps.each do |map|&lt;br /&gt;
      responses =  get_responses(map.id, round)&lt;br /&gt;
      unless responses.empty?&lt;br /&gt;
        response_ids &amp;lt;&amp;lt; responses.last.id&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
    review_final_versions[symbol][:response_ids] = response_ids&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;big&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  #Get responses by map_id and round (if exists)&lt;br /&gt;
  def self.get_responses(id, round)&lt;br /&gt;
     if round.nil?&lt;br /&gt;
       responses = Response.where(map_id: id)&lt;br /&gt;
     else&lt;br /&gt;
       responses = Response.where(map_id: id, round: round)&lt;br /&gt;
     end	&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Refactoring of other methods ===&lt;br /&gt;
Although trivial, we removed the return statement from the get_title, export_fields, and show_feedback methods because return statements are unnecessary in Ruby.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Addition of code comments ===&lt;br /&gt;
&lt;br /&gt;
We added comments to all of the methods in the ReviewResponseMap.rb file and corrected instances where CodeClimate Identified opportunities for code improvement.  One issue flagged by CodeClimate that we did not change was to use the find_by method instead of where().first method.  The where().first method occurs in the import, get_assignment_participant, and create_response_map methods. It is not always appropriate to use the find_by method, as documented in this github post: https://github.com/bbatsov/rubocop/issues/1938 .  In instances where ordering by id is the desired behavior, where().first will order by default, but in Rails 4+ find_by does not honor that default behavior.  For this reason we left the instances of where().first unchanged.&lt;br /&gt;
&lt;br /&gt;
=== Code Improvements ===&lt;br /&gt;
&lt;br /&gt;
This refactoring was to improve readability and follow as many good ''Rubyist'' coding practices as possible without breaking the functionality of existing code. We used CodeClimate of the master branch code as a reference. We took the suggestions we got from CodeClimate and improved our code based on that.&lt;br /&gt;
We also made some of the methods shorter by removing redundant functionality and adding private methods to methods with a lot internal functionality. We also added private methods in places where we saw repeated patterns to make the code ''DRYer''.&lt;br /&gt;
At the end of our refactoring, we managed to improve the rating on CodeClimate from a '''C''' to a '''B''' . Further improvements meant reducing the size of the entire class which required a much more significant refactoring in multiple files and folders. We focused on refactoring the existing model, '''ReviewResponseMap'''.&lt;br /&gt;
&lt;br /&gt;
= Unit Tests =&lt;br /&gt;
The previous unit tests had syntactical and run time errors.  We were not able to get the previous unit tests to run without errors.  Because of this we rewrote all of the unit tests for the &amp;lt;b&amp;gt;ReviewResponseModel&amp;lt;/b&amp;gt;.  It is important to have working unit tests so that when internal changes are made to functions the external output remains the same.&lt;br /&gt;
&lt;br /&gt;
=== Refactoring of Unit Tests===&lt;br /&gt;
&lt;br /&gt;
We added a test_helper file to the main test folder that requires a needed configuration file and needed gems.  We also added 8 fixtures that were needed for data to run the unit tests.  The following fixture files were added:&lt;br /&gt;
&lt;br /&gt;
* assignment_questionnaires.yml&lt;br /&gt;
* assignments.yml&lt;br /&gt;
* participants.yml&lt;br /&gt;
* questionnaires.yml&lt;br /&gt;
* response_maps.yml&lt;br /&gt;
* responses.yml&lt;br /&gt;
* teams.yml&lt;br /&gt;
* users.yml&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
There is at least one unit test for every public method within the &amp;lt;b&amp;gt;ReviewResponseModel&amp;lt;/b&amp;gt;.  The test naming convention used is &amp;quot;method_&amp;lt;name of method that is being tested&amp;gt;&amp;quot;.  For example, the unit test for the export method is &amp;quot;method_export&amp;quot;.  If there are multiple test for one method the name of the test will include the test case after the normal naming convention.  For example, one of the unit tests for the import method checks for an invalid assignment.  The name of this method is &amp;quot;method_import_invalid_assignment&amp;quot;.  The following are the unit tests we created:&lt;br /&gt;
&lt;br /&gt;
* method_export&lt;br /&gt;
* method_get_metareview_response_maps&lt;br /&gt;
* method_get_team_response_for_round&lt;br /&gt;
* method_final_versions_from_reviewer&lt;br /&gt;
* method_import&lt;br /&gt;
* method_import_invalid_reviewee&lt;br /&gt;
* method_import_invalid_reviewer&lt;br /&gt;
* method_import_invalid_assignment&lt;br /&gt;
* method_delete&lt;br /&gt;
* method_delete_no _force&lt;br /&gt;
* method_show_feedback&lt;br /&gt;
* method_get_title&lt;br /&gt;
* method_export_fields&lt;br /&gt;
* method_questionnaire&lt;br /&gt;
* method_add_reviewer&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== How to Run Unit Tests ===&lt;br /&gt;
To run the unit tests, follow these steps:&lt;br /&gt;
&lt;br /&gt;
# Download the master branch of the repo.&lt;br /&gt;
# Setup the Databases for the test environment (we have used Zhewei's scrubbed expertiza DB )&lt;br /&gt;
#* Run the &amp;quot; rake db:create RAILS_ENV=test &amp;quot; command&lt;br /&gt;
#* Run the &amp;quot; rake db:reset RAILS_ENV=test &amp;quot; command&lt;br /&gt;
#* Scrub the DB using &amp;quot; mysql -u root expertiza_development &amp;lt; expertiza-scrubbed.sql&amp;quot;&lt;br /&gt;
#* Run the &amp;quot; rake db:migrate &amp;quot;&lt;br /&gt;
# Run &amp;quot; rake test test/unit/review_response_map_test.rb &amp;quot; in the &amp;quot;expertiza/&amp;quot; directory.&lt;br /&gt;
#* If you run into a mysql log in error go into config/database.yml and edit the mysql credentials for the test section so that it matches the local environment's mysql configuration&lt;br /&gt;
# Check if tests passed or failed.&lt;br /&gt;
&lt;br /&gt;
= Manual Test Case =&lt;br /&gt;
&lt;br /&gt;
In order to test the changes made to the ReviewResponseMap, bring up [[ http://152.46.16.195:5902/ | Expertiza]] and log in as an administrator.  Once logged in, proceed with the following steps:&lt;br /&gt;
&lt;br /&gt;
# Go to '''impersonate user''' when logged in as ''instructor6'' and type in ''student559'' (or) just log in as ''student559''. All passwords are ''password'' .&lt;br /&gt;
# Pick any assignment to view.&lt;br /&gt;
# Navigate to '''Other's work'''.&lt;br /&gt;
# Check the different reviews and metareviews. Whether they are being displayed correctly or not.&lt;br /&gt;
# Go to Edit or Give feedback and submit a feedback.&lt;br /&gt;
# Go back and check if the feedback given is displayed correctly or not.&lt;br /&gt;
# Check if author's feedback is correct or not.&lt;br /&gt;
# Go to the '''Temp''' assignment and see if the page is being displayed correctly or not (since there is no assignment submission content or reviews for that).&lt;br /&gt;
&lt;br /&gt;
''NOTE: Since this was a refactoring of the code and methods, the existing functionality was supposed to remain the same and not break for the changes we've made.''&lt;br /&gt;
&lt;br /&gt;
= References =&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;references/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;4.&amp;amp;nbsp; [https://github.com/expertiza/expertiza Expertiza Main Repo] &amp;lt;br&amp;gt;&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;5.&amp;amp;nbsp; [https://github.com/adeeshag/expertiza/blob/develop/app/models/review_response_map.rb Refactored ReviewResponseMap.rb]&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;6.&amp;amp;nbsp; [https://github.com/adeeshag/expertiza/tree/develop/test/fixtures Test Fixtures]&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;7.&amp;amp;nbsp; [https://github.com/adeeshag/expertiza/blob/develop/test/unit/review_response_map_test.rb Unit Tests]&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;8.&amp;amp;nbsp; [http://152.46.16.195:5902/ Expertiza Deployed Site]&amp;lt;br&amp;gt;&lt;/div&gt;</summary>
		<author><name>Cnbrown4</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2015/ossE1558BGJ&amp;diff=98472</id>
		<title>CSC/ECE 517 Fall 2015/ossE1558BGJ</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2015/ossE1558BGJ&amp;diff=98472"/>
		<updated>2015-11-06T21:44:49Z</updated>

		<summary type="html">&lt;p&gt;Cnbrown4: /* Refactoring of export method */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Introduction =&lt;br /&gt;
&lt;br /&gt;
This page provides a description of the modifications and improvements made to the Expertiza project’s source code as part of an Expertiza based Open Source Software project.  Expertiza is a web based application which allows students to submit and peer-review classmates’ work, including written articles and development projects. The specific changes made during the course of this project were to the ReviewResponseMap.rb file, with additional changes made to other related files in support of refactoring ReviewResponseMap.rb.  &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
= Problem Statement =&lt;br /&gt;
&lt;br /&gt;
ReviewResponseMap is the model class used to manage the relationship between contributors, reviewers, and assignments.  The intent of the changes were to refactor the code for better readability and adherence to Ruby coding standards and best practices.  Primarily these changes involved the refactoring of overly complex methods, renaming methods for better readability, and the addition of missing unit tests.&lt;br /&gt;
&lt;br /&gt;
Project Requirements:&lt;br /&gt;
&lt;br /&gt;
# Code Climate&amp;lt;ref name=&amp;quot;Code Climate&amp;quot;&amp;gt;https://codeclimate.com&amp;lt;/ref&amp;gt; shows import method is complex, because of lots of checks. This method can be fixed by adding private methods for raising import error.&lt;br /&gt;
# Get_assessments_round_for method can be renamed to get_team_responses_for_round. Team_id private variable is not needed.&lt;br /&gt;
# metareview_response_maps rename, refactoring can be done. No need to do second iteration.&lt;br /&gt;
# write missing unit tests for existing methods.&lt;br /&gt;
&lt;br /&gt;
= Design Patterns =&lt;br /&gt;
&lt;br /&gt;
As part of our project, we refactored the model to follow the Single Responsibility and Don't Repeat Yourself (DRY) Principles.  Both of the principles focus on reducing code repetition and increasing the cohesion of the individual methods in the class.  The Single Responsibility Principle states that each class and method should have sole responsibility over one single part of the functionality of the system&amp;lt;ref&amp;gt;https://en.wikipedia.org/wiki/Single_responsibility_principle&amp;lt;/ref&amp;gt;.  The DRY principle states that whenever the same types of logic and functionality are being performed in a class the duplicated logic should be extracted into a new method that can be called in place of the repeated lines of code &amp;lt;ref&amp;gt;https://en.wikipedia.org/wiki/Don%27t_repeat_yourself&amp;lt;/ref&amp;gt;.  A prime example of a method that initially violated these principles was the import method, which in addition to performing the core import processes also performed a number of checks that would be more properly extracted into private methods.&lt;br /&gt;
&lt;br /&gt;
=Code Changes =&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Refactoring of import method ===&lt;br /&gt;
&lt;br /&gt;
CodeClimate reports showed the import method to be overly complex, with a number of checks being included within the import method itself.  The resolution for this problem was to refactor the import method, creating private methods to perform the null checks and throw import errors.  Prior to refactoring, all null checks were performed within the import method.   After refactoring, the import method adheres to the single responsibility principle, performing only key import tasks while making calls to private methods for any necessary validation. The size of the import method was reduced by doing this and counts for better readability of the code. Also, this method is a very important one and care was taken so that any existing functionality did not break. &lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
Before refactoring:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;big&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 def self.import(row, session, id)&lt;br /&gt;
    if row.length &amp;lt; 2&lt;br /&gt;
      raise ArgumentError, &amp;quot;Not enough items&amp;quot;&lt;br /&gt;
    end&lt;br /&gt;
    assignment = Assignment.find(id)&lt;br /&gt;
    if assignment.nil?&lt;br /&gt;
      raise ImportError, &amp;quot;The assignment with id \&amp;quot;#{id}\&amp;quot; was not found. &amp;lt;a href='/assignment/new'&amp;gt;Create&amp;lt;/a&amp;gt; this assignment?&amp;quot;&lt;br /&gt;
    end&lt;br /&gt;
    index = 1&lt;br /&gt;
    while index &amp;lt; row.length&lt;br /&gt;
      user = User.find_by_name(row[index].to_s.strip)&lt;br /&gt;
      if user.nil?&lt;br /&gt;
        raise ImportError, &amp;quot;The user account for the reviewer \&amp;quot;#{row[index]}\&amp;quot; was not found. &amp;lt;a href='/users/new'&amp;gt;Create&amp;lt;/a&amp;gt; this user?&amp;quot;&lt;br /&gt;
      end&lt;br /&gt;
      reviewer = AssignmentParticipant.where(user_id: user.id, parent_id:  assignment.id).first&lt;br /&gt;
      if reviewer == nil&lt;br /&gt;
        raise ImportError, &amp;quot;The reviewer \&amp;quot;#{row[index]}\&amp;quot; is not a participant in this assignment. &amp;lt;a href='/users/new'&amp;gt;Register&amp;lt;/a&amp;gt; this user as a participant?&amp;quot;&lt;br /&gt;
      end&lt;br /&gt;
      if assignment.team_assignment&lt;br /&gt;
        reviewee = AssignmentTeam.where(name: row[0].to_s.strip, parent_id:  assignment.id).first&lt;br /&gt;
        if reviewee == nil&lt;br /&gt;
          raise ImportError, &amp;quot;The author \&amp;quot;#{row[0].to_s.strip}\&amp;quot; was not found. &amp;lt;a href='/users/new'&amp;gt;Create&amp;lt;/a&amp;gt; this user?&amp;quot;&lt;br /&gt;
        end&lt;br /&gt;
        existing = ReviewResponseMap.where(reviewee_id: reviewee.id, reviewer_id:  reviewer.id).first&lt;br /&gt;
        if existing.nil?&lt;br /&gt;
          ReviewResponseMap.create(:reviewer_id =&amp;gt; reviewer.id, :reviewee_id =&amp;gt; reviewee.id, :reviewed_object_id =&amp;gt; assignment.id)&lt;br /&gt;
        end&lt;br /&gt;
      else&lt;br /&gt;
        puser = User.find_by_name(row[0].to_s.strip)&lt;br /&gt;
        if user == nil&lt;br /&gt;
          raise ImportError, &amp;quot;The user account for the reviewee \&amp;quot;#{row[0]}\&amp;quot; was not found. &amp;lt;a href='/users/new'&amp;gt;Create&amp;lt;/a&amp;gt; this user?&amp;quot;&lt;br /&gt;
        end&lt;br /&gt;
        reviewee = AssignmentParticipant.where(user_id: puser.id, parent_id:  assignment.id).first&lt;br /&gt;
        if reviewee == nil&lt;br /&gt;
          raise ImportError, &amp;quot;The author \&amp;quot;#{row[0].to_s.strip}\&amp;quot; was not found. &amp;lt;a href='/users/new'&amp;gt;Create&amp;lt;/a&amp;gt; this user?&amp;quot;&lt;br /&gt;
        end&lt;br /&gt;
        team_id = TeamsUser.team_id(reviewee.parent_id, reviewee.user_id)&lt;br /&gt;
        existing = ReviewResponseMap.where(reviewee_id: team_id, reviewer_id:  reviewer.id).first&lt;br /&gt;
        if existing.nil?&lt;br /&gt;
          ReviewResponseMap.create(:reviewee_id =&amp;gt; team_id, :reviewer_id =&amp;gt; reviewer.id, :reviewed_object_id =&amp;gt; assignment.id)&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
      index += 1&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
&lt;br /&gt;
After refactoring:&lt;br /&gt;
 &lt;br /&gt;
  &amp;lt;big&amp;gt;&amp;lt;nowiki&amp;gt;#Imports new reponse maps if they do not already exist&lt;br /&gt;
  def self.import(row, _session, id)&lt;br /&gt;
      if row.length &amp;lt; 2&lt;br /&gt;
          raise ArgumentError, 'Not enough items'&lt;br /&gt;
      end&lt;br /&gt;
      assignment = find_assignment(id)&lt;br /&gt;
      index = 1&lt;br /&gt;
      reviewee_name = row[0]&lt;br /&gt;
      while index &amp;lt; row.length&lt;br /&gt;
          reviewee_id = nil&lt;br /&gt;
          reviewer_name = row[index]&lt;br /&gt;
          reviewer = get_assignment_participant(reviewer_name,  assignment.id, &amp;quot;reviewer&amp;quot;)&lt;br /&gt;
          participant_nil?(reviewer, reviewer_name , &amp;quot;reviewer&amp;quot;)&lt;br /&gt;
         &lt;br /&gt;
         #Find reviewee if assignment is a team assignment&lt;br /&gt;
         if assignment.team_assignment&lt;br /&gt;
             reviewee = AssignmentTeam.where(name: reviewee_name .to_s.strip, parent_id: assignment.id).first&lt;br /&gt;
             participant_nil?(reviewee, reviewee_name, &amp;quot;author&amp;quot;)&lt;br /&gt;
             reviewee_id = reviewee.id&lt;br /&gt;
         #Find reviewee if assignment is not a team assignment&lt;br /&gt;
         else&lt;br /&gt;
	     reviewee = get_assignment_participant(reviewee_name, assignment.id, &amp;quot;reviewee&amp;quot;)&lt;br /&gt;
             participant_nil?(reviewee, reviewee_name, &amp;quot;author&amp;quot;)&lt;br /&gt;
             reviewee_id  = TeamsUser.team_id(reviewee.parent_id, reviewee.user_id)&lt;br /&gt;
         end&lt;br /&gt;
         create_response_map(reviewer, reviewee_id,  assignment)&lt;br /&gt;
         index += 1&lt;br /&gt;
      end&lt;br /&gt;
  end&amp;lt;/nowiki&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Private methods added:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;big&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  # Check for if assignment value is null&lt;br /&gt;
  def self.find_assignment(id)&lt;br /&gt;
      begin&lt;br /&gt;
          assignment = Assignment.find(id)&lt;br /&gt;
      rescue ActiveRecord::RecordNotFound&lt;br /&gt;
          raise ImportError, &amp;quot;The assignment with id \&amp;quot;#{id}\&amp;quot; was not found.&amp;lt;a href='/assignment/new'&amp;gt;Create&amp;lt;/a&amp;gt; this assignment?&amp;quot;&lt;br /&gt;
      end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  # Check for if participant is null&lt;br /&gt;
  def self.participant_nil?(participant, user_name, participant_type) &lt;br /&gt;
      error_message = nil&lt;br /&gt;
      if participant_type == &amp;quot;author&amp;quot;&lt;br /&gt;
          error_message = &amp;quot;The author \&amp;quot;#{user_name.to_s.strip}\&amp;quot; was not found.&amp;lt;a href='/users/new'&amp;gt;Create&amp;lt;/a&amp;gt; this user?&amp;quot;&lt;br /&gt;
      else&lt;br /&gt;
          error_message =  &amp;quot;The reviewer \&amp;quot;#{user_name}\&amp;quot; is not a participant in this assignment.&amp;lt;a href='/users/new'&amp;gt;Register&amp;lt;/a&amp;gt; this user as a participant?&amp;quot;&lt;br /&gt;
      end&lt;br /&gt;
      check_nil?(participant, error_message)&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  # Check for if user is null&lt;br /&gt;
  def self.user_nil?(user, user_name, user_type)&lt;br /&gt;
      check_nil?( user, &amp;quot;The user account for the \&amp;quot;#{user_type}\&amp;quot; \&amp;quot;#{user_name}\&amp;quot; was not found.&amp;lt;a href='/users/new'&amp;gt;Create&amp;lt;/a&amp;gt; this user?&amp;quot;)&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
 #Throws import error for nil objects&lt;br /&gt;
  def self.check_nil?(object, error_message)&lt;br /&gt;
      if object.nil?&lt;br /&gt;
          raise ImportError, error_message&lt;br /&gt;
      end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Refactoring of get_assessments_round_for method ===&lt;br /&gt;
&lt;br /&gt;
The get_assessments_round_for method’s name failed to provide a clear idea of the method’s purpose and functionality.  This is why it was renamed to get_team_responses_for_round, the new name of the method provides a clearer idea of its purpose. Additionally, there was a private variable, team_id, introduced in the method that was unnecessary and could be replaced by using the id property of the team parameter directly.  We also removed the return statement at the end of the method.  &lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
Before refactoring:&lt;br /&gt;
&amp;lt;big&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  def self.get_assessments_round_for(team,round)&lt;br /&gt;
    team_id =team.id&lt;br /&gt;
    responses = Array.new&lt;br /&gt;
    if team_id&lt;br /&gt;
      maps = ResponseMap.where(:reviewee_id =&amp;gt; team_id, :type =&amp;gt; &amp;quot;ReviewResponseMap&amp;quot;)&lt;br /&gt;
      maps.each{ |map|&lt;br /&gt;
        if !map.response.empty? &amp;amp;&amp;amp; !map.response.reject{|r| r.round!=round}.empty?&lt;br /&gt;
          responses &amp;lt;&amp;lt; map.response.reject{|r| r.round!=round}.last&lt;br /&gt;
        end&lt;br /&gt;
      }&lt;br /&gt;
      responses.sort! {|a,b| a.map.reviewer.fullname &amp;lt;=&amp;gt; b.map.reviewer.fullname }&lt;br /&gt;
    end&lt;br /&gt;
    return responses&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
&lt;br /&gt;
After refactoring: &lt;br /&gt;
&lt;br /&gt;
&amp;lt;big&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  # return the responses for specified round,&lt;br /&gt;
  # for varying rubric feature -Yang&lt;br /&gt;
  def self.get_team_responses_for_round(team, round)&lt;br /&gt;
    responses = []&lt;br /&gt;
    if team.id&lt;br /&gt;
      maps = ResponseMap.where(reviewee_id: team.id, type: 'ReviewResponseMap')&lt;br /&gt;
      maps.each do |map|&lt;br /&gt;
        unless map.response.empty? &amp;amp;&amp;amp; map.response.reject { |r| r.round != round }.empty?&lt;br /&gt;
          responses &amp;lt;&amp;lt; map.response.reject { |r| r.round != round }.last&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
      responses.sort! { |a, b| a.map.reviewer.fullname &amp;lt;=&amp;gt; b.map.reviewer.fullname }&lt;br /&gt;
    end&lt;br /&gt;
    responses&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
The change in method name also required changes to the following files that referenced it:&lt;br /&gt;
&lt;br /&gt;
/app/models/assignment.rb:436:    &lt;br /&gt;
 &lt;br /&gt;
&amp;lt;big&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  assessments = ReviewResponseMap.get_assessments_round_for(team,i)&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt; &lt;br /&gt;
&lt;br /&gt;
./app/models/assignment_participant.rb:268:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;big&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 scores[questionnaire_symbol][:assessments] = questionnaire.get_assessments_round_for(self,round)&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Refactoring of metareview_response_maps method ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The metareview_response_maps method was unnecessarily complex.  It contained an unneeded private variable and an unnecessary nested loop.  Originally, it added each metareview map individually in the nested loop.  We decided to remove the nested loop and use the concat method for readability and maintainability.  These changes allowed us to remove the private variable &amp;quot;metareview_list&amp;quot; and only maintain the &amp;quot;metareview_response_maps&amp;quot; variable.  We also renamed the metareview_response_maps method to get_metareview_response_maps method to be more descriptive about the intent of the method. &lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
Before refactoring:&lt;br /&gt;
&amp;lt;big&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 def metareview_response_maps&lt;br /&gt;
    responses = Response.where(map_id:self.id)&lt;br /&gt;
    metareview_list=[]&lt;br /&gt;
    responses.each do |response|&lt;br /&gt;
      metareview_response_maps = MetareviewResponseMap.where(reviewed_object_id:response.id)&lt;br /&gt;
      metareview_response_maps.each do |metareview_response_map|&lt;br /&gt;
        metareview_list&amp;lt;&amp;lt;metareview_response_map&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
    metareview_list&lt;br /&gt;
 end&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
After refactoring:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;big&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  # Returns the response maps for all the metareviews&lt;br /&gt;
  def get_metareview_response_maps&lt;br /&gt;
    responses = Response.where(map_id: id)&lt;br /&gt;
    metareview_response_maps = []&lt;br /&gt;
    responses.each do |response|&lt;br /&gt;
      metareview_response_maps.concat MetareviewResponseMap.where(reviewed_object_id: response.id)&lt;br /&gt;
    end&lt;br /&gt;
    metareview_response_maps&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Refactoring of export method ===&lt;br /&gt;
The export method contained mappings.sort! { |a, b| a.reviewee.name &amp;lt;=&amp;gt; b.reviewee.name }.  We could not get past this when running tests, we kept getting a message saying, &amp;quot;sort! was not a method for an ActiveRecord_Relation&amp;quot;.  But, ActiveRecord_Relation does allow the use of sort.  So we changed that line of code to  mappings = mappings.sort { |a, b| a.reviewee.name &amp;lt;=&amp;gt; b.reviewee.name }&lt;br /&gt;
&lt;br /&gt;
Before refactoring:&lt;br /&gt;
&amp;lt;big&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  def self.export(csv, parent_id, options)&lt;br /&gt;
    mappings = where(reviewed_object_id: parent_id)&lt;br /&gt;
    mappings.sort! { |a, b| a.reviewee.name &amp;lt;=&amp;gt; b.reviewee.name }&lt;br /&gt;
    mappings.each {&lt;br /&gt;
      |map|&lt;br /&gt;
      csv &amp;lt;&amp;lt; [&lt;br /&gt;
        map.reviewee.name,&lt;br /&gt;
        map.reviewer.name&lt;br /&gt;
      ]&lt;br /&gt;
    }&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
&lt;br /&gt;
After refactoring:&lt;br /&gt;
&amp;lt;big&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  # options parameter used as a signature in other models&lt;br /&gt;
  def self.export(csv, parent_id, options)&lt;br /&gt;
    mappings = where(reviewed_object_id: parent_id)&lt;br /&gt;
    mappings = mappings.sort { |a, b| a.reviewee.name &amp;lt;=&amp;gt; b.reviewee.name }&lt;br /&gt;
    mappings.each do&lt;br /&gt;
    |map|&lt;br /&gt;
      csv &amp;lt;&amp;lt; [map.reviewee.name, map.reviewer.name]&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Refactoring of final_versions_from_reviewer method ===&lt;br /&gt;
The final_versions_from_reviewer method was too long and repetitive.  We removed common functionality from within the if and else statement and put it in a private method final_versions_from_reviewer.  Then we created the get_responses method to find the responses based on the arguments values.  These private methods make the class more readable for other programmers.&lt;br /&gt;
 &lt;br /&gt;
Before refactoring:&lt;br /&gt;
&amp;lt;big&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  def self.final_versions_from_reviewer(reviewer_id)&lt;br /&gt;
    maps = ReviewResponseMap.where(reviewer_id: reviewer_id)&lt;br /&gt;
    assignment = Assignment.find(Participant.find(reviewer_id).parent_id)&lt;br /&gt;
    review_final_versions = Hash.new&lt;br /&gt;
    if !assignment.varying_rubrics_by_round?&lt;br /&gt;
      #same review rubric used in multiple rounds&lt;br /&gt;
      review_final_versions[:review] = Hash.new&lt;br /&gt;
      review_final_versions[:review][:questionnaire_id] = assignment.get_review_questionnaire_id&lt;br /&gt;
      response_ids = Array.new&lt;br /&gt;
      maps.each do |map|&lt;br /&gt;
        responses = Response.where(map_id:map.id)&lt;br /&gt;
        if !responses.empty?&lt;br /&gt;
          response_ids &amp;lt;&amp;lt; responses.last.id&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
      review_final_versions[:review][:response_ids] = response_ids&lt;br /&gt;
    else&lt;br /&gt;
      #vary rubric by round&lt;br /&gt;
      rounds_num = assignment.rounds_of_reviews&lt;br /&gt;
      for round in 1..rounds_num&lt;br /&gt;
        symbol = (&amp;quot;review round&amp;quot;+round.to_s).to_sym&lt;br /&gt;
        review_final_versions[symbol] = Hash.new&lt;br /&gt;
        review_final_versions[symbol][:questionnaire_id] = assignment.get_review_questionnaire_id(round)&lt;br /&gt;
        response_ids = Array.new&lt;br /&gt;
        maps.each do |map|&lt;br /&gt;
          responses = Response.where(map_id:map.id, round:round)&lt;br /&gt;
          if !responses.empty?&lt;br /&gt;
            response_ids &amp;lt;&amp;lt; responses.last.id&lt;br /&gt;
          end&lt;br /&gt;
        end&lt;br /&gt;
        review_final_versions[symbol][:response_ids] = response_ids&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
    review_final_versions&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
&lt;br /&gt;
After refactoring:&lt;br /&gt;
&amp;lt;big&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  def self.final_versions_from_reviewer(reviewer_id)&lt;br /&gt;
    maps = ReviewResponseMap.where(reviewer_id: reviewer_id)&lt;br /&gt;
    assignment = find_assignment(Participant.find(reviewer_id).parent_id)&lt;br /&gt;
    review_final_versions = {}&lt;br /&gt;
    unless assignment.varying_rubrics_by_round?&lt;br /&gt;
      #same review rubric used in multiple rounds&lt;br /&gt;
      review_final_versions = review_final_version_responses(:review, :questionnaire_id, assignment, maps)&lt;br /&gt;
    else&lt;br /&gt;
      # vary rubric by round&lt;br /&gt;
      rounds_num = assignment.rounds_of_reviews&lt;br /&gt;
      (1..rounds_num).each do |round|&lt;br /&gt;
        symbol = ('review round' + round.to_s).to_sym&lt;br /&gt;
        review_final_versions = review_final_version_responses(symbol, :questionnaire_id, assignment, maps, round)&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
    review_final_versions&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Private methods added:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;big&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  # Compute list of responses and return it&lt;br /&gt;
  def self.review_final_version_responses(symbol, questionnaire_id, assignment, maps, round = nil)&lt;br /&gt;
    review_final_versions = {}&lt;br /&gt;
    review_final_versions[symbol] = {}&lt;br /&gt;
    review_final_versions[symbol][questionnaire_id] = assignment.get_review_questionnaire_id(round)&lt;br /&gt;
    response_ids = []&lt;br /&gt;
    maps.each do |map|&lt;br /&gt;
      responses =  get_responses(map.id, round)&lt;br /&gt;
      unless responses.empty?&lt;br /&gt;
        response_ids &amp;lt;&amp;lt; responses.last.id&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
    review_final_versions[symbol][:response_ids] = response_ids&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;big&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  #Get responses by map_id and round (if exists)&lt;br /&gt;
  def self.get_responses(id, round)&lt;br /&gt;
     if round.nil?&lt;br /&gt;
       responses = Response.where(map_id: id)&lt;br /&gt;
     else&lt;br /&gt;
       responses = Response.where(map_id: id, round: round)&lt;br /&gt;
     end	&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Refactoring of other methods ===&lt;br /&gt;
Although trivial, we removed the return statement from the get_title, export_fields, and show_feedback methods because return statements are unnecessary in Ruby.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Addition of code comments ===&lt;br /&gt;
&lt;br /&gt;
We added comments to all of the methods in the ReviewResponseMap.rb file and corrected instances where CodeClimate Identified opportunities for code improvement.  One issue flagged by CodeClimate that we did not change was to use the find_by method instead of where().first method.  The where().first method occurs in the import, get_assignment_participant, and create_response_map methods. It is not always appropriate to use the find_by method, as documented in this github post: https://github.com/bbatsov/rubocop/issues/1938 .  In instances where ordering by id is the desired behavior, where().first will order by default, but in Rails 4+ find_by does not honor that default behavior.  For this reason we left the instances of where().first unchanged.&lt;br /&gt;
&lt;br /&gt;
=== Code Improvements ===&lt;br /&gt;
&lt;br /&gt;
This refactoring was to improve readability and follow as many good ''Rubyist'' coding practices as possible without breaking the functionality of existing code. We used CodeClimate of the master branch code as a reference. We took the suggestions we got from CodeClimate and improved our code based on that.&lt;br /&gt;
We also made some of the methods shorter by removing redundant functionality and adding private methods to methods with a lot internal functionality. We also added private methods in places where we saw repeated patterns to make the code ''DRYer''.&lt;br /&gt;
At the end of our refactoring, we managed to improve the rating on CodeClimate from a '''C''' to a '''B''' . Further improvements meant reducing the size of the entire class which required a much more significant refactoring in multiple files and folders. We focused on refactoring the existing model, '''ReviewResponseMap'''.&lt;br /&gt;
&lt;br /&gt;
= Unit Tests =&lt;br /&gt;
The previous unit tests had syntactical and run time errors.  We were not able to get the previous unit tests to run without errors.  Because of this we rewrote all of the unit tests for the &amp;lt;b&amp;gt;ReviewResponseModel&amp;lt;/b&amp;gt;.  It is important to have working unit tests so that when internal changes are made to functions the external output remains the same.&lt;br /&gt;
&lt;br /&gt;
=== Refactoring of Unit Tests===&lt;br /&gt;
&lt;br /&gt;
We added a test_helper file to the main test folder that requires a needed configuration file and needed gems.  We also added 8 fixtures that were needed for data to run the unit tests.  The following fixture files were added:&lt;br /&gt;
&lt;br /&gt;
* assignment_questionnaires.yml&lt;br /&gt;
* assignments.yml&lt;br /&gt;
* participants.yml&lt;br /&gt;
* questionnaires.yml&lt;br /&gt;
* response_maps.yml&lt;br /&gt;
* responses.yml&lt;br /&gt;
* teams.yml&lt;br /&gt;
* users.yml&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
There is at least one unit test for every public method within the &amp;lt;b&amp;gt;ReviewResponseModel&amp;lt;/b&amp;gt;.  The test naming convention used is &amp;quot;method_&amp;lt;name of method that is being tested&amp;gt;&amp;quot;.  For example, the unit test for the export method is &amp;quot;method_export&amp;quot;.  If there are multiple test for one method the name of the test will include the test case after the normal naming convention.  For example, one of the unit tests for the import method checks for an invalid assignment.  The name of this method is &amp;quot;method_import_invalid_assignment&amp;quot;.  The following are the unit tests we created:&lt;br /&gt;
&lt;br /&gt;
* method_export&lt;br /&gt;
* method_get_metareview_response_maps&lt;br /&gt;
* method_get_team_response_for_round&lt;br /&gt;
* method_final_versions_from_reviewer&lt;br /&gt;
* method_import&lt;br /&gt;
* method_import_invalid_reviewee&lt;br /&gt;
* method_import_invalid_reviewer&lt;br /&gt;
* method_import_invalid_assignment&lt;br /&gt;
* method_delete&lt;br /&gt;
* method_delete_no _force&lt;br /&gt;
* method_show_feedback&lt;br /&gt;
* method_get_title&lt;br /&gt;
* method_export_fields&lt;br /&gt;
* method_questionnaire&lt;br /&gt;
* method_add_reviewer&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== How to Run Unit Tests ===&lt;br /&gt;
To run the unit tests, follow these steps:&lt;br /&gt;
&lt;br /&gt;
# Download the master branch of the repo.&lt;br /&gt;
# Setup the Databases for the test environment (we have used Zhewei's scrubbed expertiza DB )&lt;br /&gt;
#* Run the &amp;quot; rake db:create RAILS_ENV=test &amp;quot; command&lt;br /&gt;
#* Run the &amp;quot; rake db:reset RAILS_ENV=test &amp;quot; command&lt;br /&gt;
#* Scrub the DB using &amp;quot; mysql -u root expertiza_development &amp;lt; expertiza-scrubbed.sql&amp;quot;&lt;br /&gt;
#* Run the &amp;quot; rake db:migrate &amp;quot;&lt;br /&gt;
# Run &amp;quot; rake test test/unit/review_response_map_test.rb &amp;quot; in the &amp;quot;expertiza/&amp;quot; directory.&lt;br /&gt;
#* If you run into a mysql log in error go into config/database.yml and edit the mysql credentials for the test section so that it matches the local environment's mysql configuration&lt;br /&gt;
# Check if tests passed or failed.&lt;br /&gt;
&lt;br /&gt;
= Manual Test Case =&lt;br /&gt;
&lt;br /&gt;
In order to test the changes made to the ReviewResponseMap, bring up [[ http://152.46.16.195:5902/ | Expertiza]] and log in as an administrator.  Once logged in, proceed with the following steps:&lt;br /&gt;
&lt;br /&gt;
# Go to '''impersonate user''' when logged in as ''instructor6'' and type in ''student559'' (or) just log in as ''student559''. All passwords are ''password'' .&lt;br /&gt;
# Pick any assignment to view.&lt;br /&gt;
# Navigate to '''Other's work'''.&lt;br /&gt;
# Check the different reviews and metareviews. Whether they are being displayed correctly or not.&lt;br /&gt;
# Go to Edit or Give feedback and submit a feedback.&lt;br /&gt;
# Go back and check if the feedback given is displayed correctly or not.&lt;br /&gt;
# Check if author's feedback is correct or not.&lt;br /&gt;
# Go to the '''Temp''' assignment and see if the page is being displayed correctly or not (since there is no assignment submission content or reviews for that).&lt;br /&gt;
&lt;br /&gt;
''NOTE: Since this was a refactoring of the code and methods, the existing functionality was supposed to remain the same and not break for the changes we've made.''&lt;br /&gt;
&lt;br /&gt;
= References =&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;references/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;4.&amp;amp;nbsp; [https://github.com/expertiza/expertiza Expertiza Main Repo] &amp;lt;br&amp;gt;&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;5.&amp;amp;nbsp; [https://github.com/adeeshag/expertiza/blob/develop/app/models/review_response_map.rb Refactored ReviewResponseMap.rb]&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;6.&amp;amp;nbsp; [https://github.com/adeeshag/expertiza/tree/develop/test/fixtures Test Fixtures]&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;7.&amp;amp;nbsp; [https://github.com/adeeshag/expertiza/blob/develop/test/unit/review_response_map_test.rb Unit Tests]&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;8.&amp;amp;nbsp; [http://152.46.16.195:5902/ Expertiza Deployed Site]&amp;lt;br&amp;gt;&lt;/div&gt;</summary>
		<author><name>Cnbrown4</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2015/ossE1558BGJ&amp;diff=98468</id>
		<title>CSC/ECE 517 Fall 2015/ossE1558BGJ</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2015/ossE1558BGJ&amp;diff=98468"/>
		<updated>2015-11-06T21:43:00Z</updated>

		<summary type="html">&lt;p&gt;Cnbrown4: /* Refactoring of metareview_response_maps method */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Introduction =&lt;br /&gt;
&lt;br /&gt;
This page provides a description of the modifications and improvements made to the Expertiza project’s source code as part of an Expertiza based Open Source Software project.  Expertiza is a web based application which allows students to submit and peer-review classmates’ work, including written articles and development projects. The specific changes made during the course of this project were to the ReviewResponseMap.rb file, with additional changes made to other related files in support of refactoring ReviewResponseMap.rb.  &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
= Problem Statement =&lt;br /&gt;
&lt;br /&gt;
ReviewResponseMap is the model class used to manage the relationship between contributors, reviewers, and assignments.  The intent of the changes were to refactor the code for better readability and adherence to Ruby coding standards and best practices.  Primarily these changes involved the refactoring of overly complex methods, renaming methods for better readability, and the addition of missing unit tests.&lt;br /&gt;
&lt;br /&gt;
Project Requirements:&lt;br /&gt;
&lt;br /&gt;
# Code Climate&amp;lt;ref name=&amp;quot;Code Climate&amp;quot;&amp;gt;https://codeclimate.com&amp;lt;/ref&amp;gt; shows import method is complex, because of lots of checks. This method can be fixed by adding private methods for raising import error.&lt;br /&gt;
# Get_assessments_round_for method can be renamed to get_team_responses_for_round. Team_id private variable is not needed.&lt;br /&gt;
# metareview_response_maps rename, refactoring can be done. No need to do second iteration.&lt;br /&gt;
# write missing unit tests for existing methods.&lt;br /&gt;
&lt;br /&gt;
= Design Patterns =&lt;br /&gt;
&lt;br /&gt;
As part of our project, we refactored the model to follow the Single Responsibility and Don't Repeat Yourself (DRY) Principles.  Both of the principles focus on reducing code repetition and increasing the cohesion of the individual methods in the class.  The Single Responsibility Principle states that each class and method should have sole responsibility over one single part of the functionality of the system&amp;lt;ref&amp;gt;https://en.wikipedia.org/wiki/Single_responsibility_principle&amp;lt;/ref&amp;gt;.  The DRY principle states that whenever the same types of logic and functionality are being performed in a class the duplicated logic should be extracted into a new method that can be called in place of the repeated lines of code &amp;lt;ref&amp;gt;https://en.wikipedia.org/wiki/Don%27t_repeat_yourself&amp;lt;/ref&amp;gt;.  A prime example of a method that initially violated these principles was the import method, which in addition to performing the core import processes also performed a number of checks that would be more properly extracted into private methods.&lt;br /&gt;
&lt;br /&gt;
=Code Changes =&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Refactoring of import method ===&lt;br /&gt;
&lt;br /&gt;
CodeClimate reports showed the import method to be overly complex, with a number of checks being included within the import method itself.  The resolution for this problem was to refactor the import method, creating private methods to perform the null checks and throw import errors.  Prior to refactoring, all null checks were performed within the import method.   After refactoring, the import method adheres to the single responsibility principle, performing only key import tasks while making calls to private methods for any necessary validation. The size of the import method was reduced by doing this and counts for better readability of the code. Also, this method is a very important one and care was taken so that any existing functionality did not break. &lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
Before refactoring:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;big&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 def self.import(row, session, id)&lt;br /&gt;
    if row.length &amp;lt; 2&lt;br /&gt;
      raise ArgumentError, &amp;quot;Not enough items&amp;quot;&lt;br /&gt;
    end&lt;br /&gt;
    assignment = Assignment.find(id)&lt;br /&gt;
    if assignment.nil?&lt;br /&gt;
      raise ImportError, &amp;quot;The assignment with id \&amp;quot;#{id}\&amp;quot; was not found. &amp;lt;a href='/assignment/new'&amp;gt;Create&amp;lt;/a&amp;gt; this assignment?&amp;quot;&lt;br /&gt;
    end&lt;br /&gt;
    index = 1&lt;br /&gt;
    while index &amp;lt; row.length&lt;br /&gt;
      user = User.find_by_name(row[index].to_s.strip)&lt;br /&gt;
      if user.nil?&lt;br /&gt;
        raise ImportError, &amp;quot;The user account for the reviewer \&amp;quot;#{row[index]}\&amp;quot; was not found. &amp;lt;a href='/users/new'&amp;gt;Create&amp;lt;/a&amp;gt; this user?&amp;quot;&lt;br /&gt;
      end&lt;br /&gt;
      reviewer = AssignmentParticipant.where(user_id: user.id, parent_id:  assignment.id).first&lt;br /&gt;
      if reviewer == nil&lt;br /&gt;
        raise ImportError, &amp;quot;The reviewer \&amp;quot;#{row[index]}\&amp;quot; is not a participant in this assignment. &amp;lt;a href='/users/new'&amp;gt;Register&amp;lt;/a&amp;gt; this user as a participant?&amp;quot;&lt;br /&gt;
      end&lt;br /&gt;
      if assignment.team_assignment&lt;br /&gt;
        reviewee = AssignmentTeam.where(name: row[0].to_s.strip, parent_id:  assignment.id).first&lt;br /&gt;
        if reviewee == nil&lt;br /&gt;
          raise ImportError, &amp;quot;The author \&amp;quot;#{row[0].to_s.strip}\&amp;quot; was not found. &amp;lt;a href='/users/new'&amp;gt;Create&amp;lt;/a&amp;gt; this user?&amp;quot;&lt;br /&gt;
        end&lt;br /&gt;
        existing = ReviewResponseMap.where(reviewee_id: reviewee.id, reviewer_id:  reviewer.id).first&lt;br /&gt;
        if existing.nil?&lt;br /&gt;
          ReviewResponseMap.create(:reviewer_id =&amp;gt; reviewer.id, :reviewee_id =&amp;gt; reviewee.id, :reviewed_object_id =&amp;gt; assignment.id)&lt;br /&gt;
        end&lt;br /&gt;
      else&lt;br /&gt;
        puser = User.find_by_name(row[0].to_s.strip)&lt;br /&gt;
        if user == nil&lt;br /&gt;
          raise ImportError, &amp;quot;The user account for the reviewee \&amp;quot;#{row[0]}\&amp;quot; was not found. &amp;lt;a href='/users/new'&amp;gt;Create&amp;lt;/a&amp;gt; this user?&amp;quot;&lt;br /&gt;
        end&lt;br /&gt;
        reviewee = AssignmentParticipant.where(user_id: puser.id, parent_id:  assignment.id).first&lt;br /&gt;
        if reviewee == nil&lt;br /&gt;
          raise ImportError, &amp;quot;The author \&amp;quot;#{row[0].to_s.strip}\&amp;quot; was not found. &amp;lt;a href='/users/new'&amp;gt;Create&amp;lt;/a&amp;gt; this user?&amp;quot;&lt;br /&gt;
        end&lt;br /&gt;
        team_id = TeamsUser.team_id(reviewee.parent_id, reviewee.user_id)&lt;br /&gt;
        existing = ReviewResponseMap.where(reviewee_id: team_id, reviewer_id:  reviewer.id).first&lt;br /&gt;
        if existing.nil?&lt;br /&gt;
          ReviewResponseMap.create(:reviewee_id =&amp;gt; team_id, :reviewer_id =&amp;gt; reviewer.id, :reviewed_object_id =&amp;gt; assignment.id)&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
      index += 1&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
&lt;br /&gt;
After refactoring:&lt;br /&gt;
 &lt;br /&gt;
  &amp;lt;big&amp;gt;&amp;lt;nowiki&amp;gt;#Imports new reponse maps if they do not already exist&lt;br /&gt;
  def self.import(row, _session, id)&lt;br /&gt;
      if row.length &amp;lt; 2&lt;br /&gt;
          raise ArgumentError, 'Not enough items'&lt;br /&gt;
      end&lt;br /&gt;
      assignment = find_assignment(id)&lt;br /&gt;
      index = 1&lt;br /&gt;
      reviewee_name = row[0]&lt;br /&gt;
      while index &amp;lt; row.length&lt;br /&gt;
          reviewee_id = nil&lt;br /&gt;
          reviewer_name = row[index]&lt;br /&gt;
          reviewer = get_assignment_participant(reviewer_name,  assignment.id, &amp;quot;reviewer&amp;quot;)&lt;br /&gt;
          participant_nil?(reviewer, reviewer_name , &amp;quot;reviewer&amp;quot;)&lt;br /&gt;
         &lt;br /&gt;
         #Find reviewee if assignment is a team assignment&lt;br /&gt;
         if assignment.team_assignment&lt;br /&gt;
             reviewee = AssignmentTeam.where(name: reviewee_name .to_s.strip, parent_id: assignment.id).first&lt;br /&gt;
             participant_nil?(reviewee, reviewee_name, &amp;quot;author&amp;quot;)&lt;br /&gt;
             reviewee_id = reviewee.id&lt;br /&gt;
         #Find reviewee if assignment is not a team assignment&lt;br /&gt;
         else&lt;br /&gt;
	     reviewee = get_assignment_participant(reviewee_name, assignment.id, &amp;quot;reviewee&amp;quot;)&lt;br /&gt;
             participant_nil?(reviewee, reviewee_name, &amp;quot;author&amp;quot;)&lt;br /&gt;
             reviewee_id  = TeamsUser.team_id(reviewee.parent_id, reviewee.user_id)&lt;br /&gt;
         end&lt;br /&gt;
         create_response_map(reviewer, reviewee_id,  assignment)&lt;br /&gt;
         index += 1&lt;br /&gt;
      end&lt;br /&gt;
  end&amp;lt;/nowiki&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Private methods added:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;big&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  # Check for if assignment value is null&lt;br /&gt;
  def self.find_assignment(id)&lt;br /&gt;
      begin&lt;br /&gt;
          assignment = Assignment.find(id)&lt;br /&gt;
      rescue ActiveRecord::RecordNotFound&lt;br /&gt;
          raise ImportError, &amp;quot;The assignment with id \&amp;quot;#{id}\&amp;quot; was not found.&amp;lt;a href='/assignment/new'&amp;gt;Create&amp;lt;/a&amp;gt; this assignment?&amp;quot;&lt;br /&gt;
      end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  # Check for if participant is null&lt;br /&gt;
  def self.participant_nil?(participant, user_name, participant_type) &lt;br /&gt;
      error_message = nil&lt;br /&gt;
      if participant_type == &amp;quot;author&amp;quot;&lt;br /&gt;
          error_message = &amp;quot;The author \&amp;quot;#{user_name.to_s.strip}\&amp;quot; was not found.&amp;lt;a href='/users/new'&amp;gt;Create&amp;lt;/a&amp;gt; this user?&amp;quot;&lt;br /&gt;
      else&lt;br /&gt;
          error_message =  &amp;quot;The reviewer \&amp;quot;#{user_name}\&amp;quot; is not a participant in this assignment.&amp;lt;a href='/users/new'&amp;gt;Register&amp;lt;/a&amp;gt; this user as a participant?&amp;quot;&lt;br /&gt;
      end&lt;br /&gt;
      check_nil?(participant, error_message)&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  # Check for if user is null&lt;br /&gt;
  def self.user_nil?(user, user_name, user_type)&lt;br /&gt;
      check_nil?( user, &amp;quot;The user account for the \&amp;quot;#{user_type}\&amp;quot; \&amp;quot;#{user_name}\&amp;quot; was not found.&amp;lt;a href='/users/new'&amp;gt;Create&amp;lt;/a&amp;gt; this user?&amp;quot;)&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
 #Throws import error for nil objects&lt;br /&gt;
  def self.check_nil?(object, error_message)&lt;br /&gt;
      if object.nil?&lt;br /&gt;
          raise ImportError, error_message&lt;br /&gt;
      end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Refactoring of get_assessments_round_for method ===&lt;br /&gt;
&lt;br /&gt;
The get_assessments_round_for method’s name failed to provide a clear idea of the method’s purpose and functionality.  This is why it was renamed to get_team_responses_for_round, the new name of the method provides a clearer idea of its purpose. Additionally, there was a private variable, team_id, introduced in the method that was unnecessary and could be replaced by using the id property of the team parameter directly.  We also removed the return statement at the end of the method.  &lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
Before refactoring:&lt;br /&gt;
&amp;lt;big&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  def self.get_assessments_round_for(team,round)&lt;br /&gt;
    team_id =team.id&lt;br /&gt;
    responses = Array.new&lt;br /&gt;
    if team_id&lt;br /&gt;
      maps = ResponseMap.where(:reviewee_id =&amp;gt; team_id, :type =&amp;gt; &amp;quot;ReviewResponseMap&amp;quot;)&lt;br /&gt;
      maps.each{ |map|&lt;br /&gt;
        if !map.response.empty? &amp;amp;&amp;amp; !map.response.reject{|r| r.round!=round}.empty?&lt;br /&gt;
          responses &amp;lt;&amp;lt; map.response.reject{|r| r.round!=round}.last&lt;br /&gt;
        end&lt;br /&gt;
      }&lt;br /&gt;
      responses.sort! {|a,b| a.map.reviewer.fullname &amp;lt;=&amp;gt; b.map.reviewer.fullname }&lt;br /&gt;
    end&lt;br /&gt;
    return responses&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
&lt;br /&gt;
After refactoring: &lt;br /&gt;
&lt;br /&gt;
&amp;lt;big&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  # return the responses for specified round,&lt;br /&gt;
  # for varying rubric feature -Yang&lt;br /&gt;
  def self.get_team_responses_for_round(team, round)&lt;br /&gt;
    responses = []&lt;br /&gt;
    if team.id&lt;br /&gt;
      maps = ResponseMap.where(reviewee_id: team.id, type: 'ReviewResponseMap')&lt;br /&gt;
      maps.each do |map|&lt;br /&gt;
        unless map.response.empty? &amp;amp;&amp;amp; map.response.reject { |r| r.round != round }.empty?&lt;br /&gt;
          responses &amp;lt;&amp;lt; map.response.reject { |r| r.round != round }.last&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
      responses.sort! { |a, b| a.map.reviewer.fullname &amp;lt;=&amp;gt; b.map.reviewer.fullname }&lt;br /&gt;
    end&lt;br /&gt;
    responses&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
The change in method name also required changes to the following files that referenced it:&lt;br /&gt;
&lt;br /&gt;
/app/models/assignment.rb:436:    &lt;br /&gt;
 &lt;br /&gt;
&amp;lt;big&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  assessments = ReviewResponseMap.get_assessments_round_for(team,i)&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt; &lt;br /&gt;
&lt;br /&gt;
./app/models/assignment_participant.rb:268:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;big&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 scores[questionnaire_symbol][:assessments] = questionnaire.get_assessments_round_for(self,round)&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Refactoring of metareview_response_maps method ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The metareview_response_maps method was unnecessarily complex.  It contained an unneeded private variable and an unnecessary nested loop.  Originally, it added each metareview map individually in the nested loop.  We decided to remove the nested loop and use the concat method for readability and maintainability.  These changes allowed us to remove the private variable &amp;quot;metareview_list&amp;quot; and only maintain the &amp;quot;metareview_response_maps&amp;quot; variable.  We also renamed the metareview_response_maps method to get_metareview_response_maps method to be more descriptive about the intent of the method. &lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
Before refactoring:&lt;br /&gt;
&amp;lt;big&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 def metareview_response_maps&lt;br /&gt;
    responses = Response.where(map_id:self.id)&lt;br /&gt;
    metareview_list=[]&lt;br /&gt;
    responses.each do |response|&lt;br /&gt;
      metareview_response_maps = MetareviewResponseMap.where(reviewed_object_id:response.id)&lt;br /&gt;
      metareview_response_maps.each do |metareview_response_map|&lt;br /&gt;
        metareview_list&amp;lt;&amp;lt;metareview_response_map&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
    metareview_list&lt;br /&gt;
 end&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
After refactoring:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;big&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  # Returns the response maps for all the metareviews&lt;br /&gt;
  def get_metareview_response_maps&lt;br /&gt;
    responses = Response.where(map_id: id)&lt;br /&gt;
    metareview_response_maps = []&lt;br /&gt;
    responses.each do |response|&lt;br /&gt;
      metareview_response_maps.concat MetareviewResponseMap.where(reviewed_object_id: response.id)&lt;br /&gt;
    end&lt;br /&gt;
    metareview_response_maps&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Refactoring of export method ===&lt;br /&gt;
The export method contained mappings.sort! { |a, b| a.reviewee.name &amp;lt;=&amp;gt; b.reviewee.name }.  We could not get past this when running tests, we kept getting a message saying, &amp;quot;sort! was not a method for an ActiveRecord_Relation&amp;quot;.  But, ActiveRecord_Relation does allow the use of sort.  So we changed that line of code to  mappings = mappings.sort { |a, b| a.reviewee.name &amp;lt;=&amp;gt; b.reviewee.name }&lt;br /&gt;
&lt;br /&gt;
Before refactoring:&lt;br /&gt;
&amp;lt;big&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  def self.export(csv, parent_id, options)&lt;br /&gt;
    mappings = where(reviewed_object_id: parent_id)&lt;br /&gt;
    mappings.sort! { |a, b| a.reviewee.name &amp;lt;=&amp;gt; b.reviewee.name }&lt;br /&gt;
    mappings.each {&lt;br /&gt;
      |map|&lt;br /&gt;
      csv &amp;lt;&amp;lt; [&lt;br /&gt;
        map.reviewee.name,&lt;br /&gt;
        map.reviewer.name&lt;br /&gt;
      ]&lt;br /&gt;
    }&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
&lt;br /&gt;
After refactoring:&lt;br /&gt;
&amp;lt;big&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  def self.export(csv, parent_id, options)&lt;br /&gt;
    mappings = where(reviewed_object_id: parent_id)&lt;br /&gt;
    mappings = mappings.sort { |a, b| a.reviewee.name &amp;lt;=&amp;gt; b.reviewee.name }&lt;br /&gt;
    mappings.each do&lt;br /&gt;
    |map|&lt;br /&gt;
      csv &amp;lt;&amp;lt; [map.reviewee.name, map.reviewer.name]&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Refactoring of final_versions_from_reviewer method ===&lt;br /&gt;
The final_versions_from_reviewer method was too long and repetitive.  We removed common functionality from within the if and else statement and put it in a private method final_versions_from_reviewer.  Then we created the get_responses method to find the responses based on the arguments values.  These private methods make the class more readable for other programmers.&lt;br /&gt;
 &lt;br /&gt;
Before refactoring:&lt;br /&gt;
&amp;lt;big&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  def self.final_versions_from_reviewer(reviewer_id)&lt;br /&gt;
    maps = ReviewResponseMap.where(reviewer_id: reviewer_id)&lt;br /&gt;
    assignment = Assignment.find(Participant.find(reviewer_id).parent_id)&lt;br /&gt;
    review_final_versions = Hash.new&lt;br /&gt;
    if !assignment.varying_rubrics_by_round?&lt;br /&gt;
      #same review rubric used in multiple rounds&lt;br /&gt;
      review_final_versions[:review] = Hash.new&lt;br /&gt;
      review_final_versions[:review][:questionnaire_id] = assignment.get_review_questionnaire_id&lt;br /&gt;
      response_ids = Array.new&lt;br /&gt;
      maps.each do |map|&lt;br /&gt;
        responses = Response.where(map_id:map.id)&lt;br /&gt;
        if !responses.empty?&lt;br /&gt;
          response_ids &amp;lt;&amp;lt; responses.last.id&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
      review_final_versions[:review][:response_ids] = response_ids&lt;br /&gt;
    else&lt;br /&gt;
      #vary rubric by round&lt;br /&gt;
      rounds_num = assignment.rounds_of_reviews&lt;br /&gt;
      for round in 1..rounds_num&lt;br /&gt;
        symbol = (&amp;quot;review round&amp;quot;+round.to_s).to_sym&lt;br /&gt;
        review_final_versions[symbol] = Hash.new&lt;br /&gt;
        review_final_versions[symbol][:questionnaire_id] = assignment.get_review_questionnaire_id(round)&lt;br /&gt;
        response_ids = Array.new&lt;br /&gt;
        maps.each do |map|&lt;br /&gt;
          responses = Response.where(map_id:map.id, round:round)&lt;br /&gt;
          if !responses.empty?&lt;br /&gt;
            response_ids &amp;lt;&amp;lt; responses.last.id&lt;br /&gt;
          end&lt;br /&gt;
        end&lt;br /&gt;
        review_final_versions[symbol][:response_ids] = response_ids&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
    review_final_versions&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
&lt;br /&gt;
After refactoring:&lt;br /&gt;
&amp;lt;big&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  def self.final_versions_from_reviewer(reviewer_id)&lt;br /&gt;
    maps = ReviewResponseMap.where(reviewer_id: reviewer_id)&lt;br /&gt;
    assignment = find_assignment(Participant.find(reviewer_id).parent_id)&lt;br /&gt;
    review_final_versions = {}&lt;br /&gt;
    unless assignment.varying_rubrics_by_round?&lt;br /&gt;
      #same review rubric used in multiple rounds&lt;br /&gt;
      review_final_versions = review_final_version_responses(:review, :questionnaire_id, assignment, maps)&lt;br /&gt;
    else&lt;br /&gt;
      # vary rubric by round&lt;br /&gt;
      rounds_num = assignment.rounds_of_reviews&lt;br /&gt;
      (1..rounds_num).each do |round|&lt;br /&gt;
        symbol = ('review round' + round.to_s).to_sym&lt;br /&gt;
        review_final_versions = review_final_version_responses(symbol, :questionnaire_id, assignment, maps, round)&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
    review_final_versions&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Private methods added:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;big&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  # Compute list of responses and return it&lt;br /&gt;
  def self.review_final_version_responses(symbol, questionnaire_id, assignment, maps, round = nil)&lt;br /&gt;
    review_final_versions = {}&lt;br /&gt;
    review_final_versions[symbol] = {}&lt;br /&gt;
    review_final_versions[symbol][questionnaire_id] = assignment.get_review_questionnaire_id(round)&lt;br /&gt;
    response_ids = []&lt;br /&gt;
    maps.each do |map|&lt;br /&gt;
      responses =  get_responses(map.id, round)&lt;br /&gt;
      unless responses.empty?&lt;br /&gt;
        response_ids &amp;lt;&amp;lt; responses.last.id&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
    review_final_versions[symbol][:response_ids] = response_ids&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;big&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  #Get responses by map_id and round (if exists)&lt;br /&gt;
  def self.get_responses(id, round)&lt;br /&gt;
     if round.nil?&lt;br /&gt;
       responses = Response.where(map_id: id)&lt;br /&gt;
     else&lt;br /&gt;
       responses = Response.where(map_id: id, round: round)&lt;br /&gt;
     end	&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Refactoring of other methods ===&lt;br /&gt;
Although trivial, we removed the return statement from the get_title, export_fields, and show_feedback methods because return statements are unnecessary in Ruby.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Addition of code comments ===&lt;br /&gt;
&lt;br /&gt;
We added comments to all of the methods in the ReviewResponseMap.rb file and corrected instances where CodeClimate Identified opportunities for code improvement.  One issue flagged by CodeClimate that we did not change was to use the find_by method instead of where().first method.  The where().first method occurs in the import, get_assignment_participant, and create_response_map methods. It is not always appropriate to use the find_by method, as documented in this github post: https://github.com/bbatsov/rubocop/issues/1938 .  In instances where ordering by id is the desired behavior, where().first will order by default, but in Rails 4+ find_by does not honor that default behavior.  For this reason we left the instances of where().first unchanged.&lt;br /&gt;
&lt;br /&gt;
=== Code Improvements ===&lt;br /&gt;
&lt;br /&gt;
This refactoring was to improve readability and follow as many good ''Rubyist'' coding practices as possible without breaking the functionality of existing code. We used CodeClimate of the master branch code as a reference. We took the suggestions we got from CodeClimate and improved our code based on that.&lt;br /&gt;
We also made some of the methods shorter by removing redundant functionality and adding private methods to methods with a lot internal functionality. We also added private methods in places where we saw repeated patterns to make the code ''DRYer''.&lt;br /&gt;
At the end of our refactoring, we managed to improve the rating on CodeClimate from a '''C''' to a '''B''' . Further improvements meant reducing the size of the entire class which required a much more significant refactoring in multiple files and folders. We focused on refactoring the existing model, '''ReviewResponseMap'''.&lt;br /&gt;
&lt;br /&gt;
= Unit Tests =&lt;br /&gt;
The previous unit tests had syntactical and run time errors.  We were not able to get the previous unit tests to run without errors.  Because of this we rewrote all of the unit tests for the &amp;lt;b&amp;gt;ReviewResponseModel&amp;lt;/b&amp;gt;.  It is important to have working unit tests so that when internal changes are made to functions the external output remains the same.&lt;br /&gt;
&lt;br /&gt;
=== Refactoring of Unit Tests===&lt;br /&gt;
&lt;br /&gt;
We added a test_helper file to the main test folder that requires a needed configuration file and needed gems.  We also added 8 fixtures that were needed for data to run the unit tests.  The following fixture files were added:&lt;br /&gt;
&lt;br /&gt;
* assignment_questionnaires.yml&lt;br /&gt;
* assignments.yml&lt;br /&gt;
* participants.yml&lt;br /&gt;
* questionnaires.yml&lt;br /&gt;
* response_maps.yml&lt;br /&gt;
* responses.yml&lt;br /&gt;
* teams.yml&lt;br /&gt;
* users.yml&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
There is at least one unit test for every public method within the &amp;lt;b&amp;gt;ReviewResponseModel&amp;lt;/b&amp;gt;.  The test naming convention used is &amp;quot;method_&amp;lt;name of method that is being tested&amp;gt;&amp;quot;.  For example, the unit test for the export method is &amp;quot;method_export&amp;quot;.  If there are multiple test for one method the name of the test will include the test case after the normal naming convention.  For example, one of the unit tests for the import method checks for an invalid assignment.  The name of this method is &amp;quot;method_import_invalid_assignment&amp;quot;.  The following are the unit tests we created:&lt;br /&gt;
&lt;br /&gt;
* method_export&lt;br /&gt;
* method_get_metareview_response_maps&lt;br /&gt;
* method_get_team_response_for_round&lt;br /&gt;
* method_final_versions_from_reviewer&lt;br /&gt;
* method_import&lt;br /&gt;
* method_import_invalid_reviewee&lt;br /&gt;
* method_import_invalid_reviewer&lt;br /&gt;
* method_import_invalid_assignment&lt;br /&gt;
* method_delete&lt;br /&gt;
* method_delete_no _force&lt;br /&gt;
* method_show_feedback&lt;br /&gt;
* method_get_title&lt;br /&gt;
* method_export_fields&lt;br /&gt;
* method_questionnaire&lt;br /&gt;
* method_add_reviewer&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== How to Run Unit Tests ===&lt;br /&gt;
To run the unit tests, follow these steps:&lt;br /&gt;
&lt;br /&gt;
# Download the master branch of the repo.&lt;br /&gt;
# Setup the Databases for the test environment (we have used Zhewei's scrubbed expertiza DB )&lt;br /&gt;
#* Run the &amp;quot; rake db:create RAILS_ENV=test &amp;quot; command&lt;br /&gt;
#* Run the &amp;quot; rake db:reset RAILS_ENV=test &amp;quot; command&lt;br /&gt;
#* Scrub the DB using &amp;quot; mysql -u root expertiza_development &amp;lt; expertiza-scrubbed.sql&amp;quot;&lt;br /&gt;
#* Run the &amp;quot; rake db:migrate &amp;quot;&lt;br /&gt;
# Run &amp;quot; rake test test/unit/review_response_map_test.rb &amp;quot; in the &amp;quot;expertiza/&amp;quot; directory.&lt;br /&gt;
#* If you run into a mysql log in error go into config/database.yml and edit the mysql credentials for the test section so that it matches the local environment's mysql configuration&lt;br /&gt;
# Check if tests passed or failed.&lt;br /&gt;
&lt;br /&gt;
= Manual Test Case =&lt;br /&gt;
&lt;br /&gt;
In order to test the changes made to the ReviewResponseMap, bring up [[ http://152.46.16.195:5902/ | Expertiza]] and log in as an administrator.  Once logged in, proceed with the following steps:&lt;br /&gt;
&lt;br /&gt;
# Go to '''impersonate user''' when logged in as ''instructor6'' and type in ''student559'' (or) just log in as ''student559''. All passwords are ''password'' .&lt;br /&gt;
# Pick any assignment to view.&lt;br /&gt;
# Navigate to '''Other's work'''.&lt;br /&gt;
# Check the different reviews and metareviews. Whether they are being displayed correctly or not.&lt;br /&gt;
# Go to Edit or Give feedback and submit a feedback.&lt;br /&gt;
# Go back and check if the feedback given is displayed correctly or not.&lt;br /&gt;
# Check if author's feedback is correct or not.&lt;br /&gt;
# Go to the '''Temp''' assignment and see if the page is being displayed correctly or not (since there is no assignment submission content or reviews for that).&lt;br /&gt;
&lt;br /&gt;
''NOTE: Since this was a refactoring of the code and methods, the existing functionality was supposed to remain the same and not break for the changes we've made.''&lt;br /&gt;
&lt;br /&gt;
= References =&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;references/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;4.&amp;amp;nbsp; [https://github.com/expertiza/expertiza Expertiza Main Repo] &amp;lt;br&amp;gt;&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;5.&amp;amp;nbsp; [https://github.com/adeeshag/expertiza/blob/develop/app/models/review_response_map.rb Refactored ReviewResponseMap.rb]&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;6.&amp;amp;nbsp; [https://github.com/adeeshag/expertiza/tree/develop/test/fixtures Test Fixtures]&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;7.&amp;amp;nbsp; [https://github.com/adeeshag/expertiza/blob/develop/test/unit/review_response_map_test.rb Unit Tests]&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;8.&amp;amp;nbsp; [http://152.46.16.195:5902/ Expertiza Deployed Site]&amp;lt;br&amp;gt;&lt;/div&gt;</summary>
		<author><name>Cnbrown4</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2015/ossE1558BGJ&amp;diff=98466</id>
		<title>CSC/ECE 517 Fall 2015/ossE1558BGJ</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2015/ossE1558BGJ&amp;diff=98466"/>
		<updated>2015-11-06T21:42:05Z</updated>

		<summary type="html">&lt;p&gt;Cnbrown4: /* Refactoring of get_assessments_round_for method */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Introduction =&lt;br /&gt;
&lt;br /&gt;
This page provides a description of the modifications and improvements made to the Expertiza project’s source code as part of an Expertiza based Open Source Software project.  Expertiza is a web based application which allows students to submit and peer-review classmates’ work, including written articles and development projects. The specific changes made during the course of this project were to the ReviewResponseMap.rb file, with additional changes made to other related files in support of refactoring ReviewResponseMap.rb.  &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
= Problem Statement =&lt;br /&gt;
&lt;br /&gt;
ReviewResponseMap is the model class used to manage the relationship between contributors, reviewers, and assignments.  The intent of the changes were to refactor the code for better readability and adherence to Ruby coding standards and best practices.  Primarily these changes involved the refactoring of overly complex methods, renaming methods for better readability, and the addition of missing unit tests.&lt;br /&gt;
&lt;br /&gt;
Project Requirements:&lt;br /&gt;
&lt;br /&gt;
# Code Climate&amp;lt;ref name=&amp;quot;Code Climate&amp;quot;&amp;gt;https://codeclimate.com&amp;lt;/ref&amp;gt; shows import method is complex, because of lots of checks. This method can be fixed by adding private methods for raising import error.&lt;br /&gt;
# Get_assessments_round_for method can be renamed to get_team_responses_for_round. Team_id private variable is not needed.&lt;br /&gt;
# metareview_response_maps rename, refactoring can be done. No need to do second iteration.&lt;br /&gt;
# write missing unit tests for existing methods.&lt;br /&gt;
&lt;br /&gt;
= Design Patterns =&lt;br /&gt;
&lt;br /&gt;
As part of our project, we refactored the model to follow the Single Responsibility and Don't Repeat Yourself (DRY) Principles.  Both of the principles focus on reducing code repetition and increasing the cohesion of the individual methods in the class.  The Single Responsibility Principle states that each class and method should have sole responsibility over one single part of the functionality of the system&amp;lt;ref&amp;gt;https://en.wikipedia.org/wiki/Single_responsibility_principle&amp;lt;/ref&amp;gt;.  The DRY principle states that whenever the same types of logic and functionality are being performed in a class the duplicated logic should be extracted into a new method that can be called in place of the repeated lines of code &amp;lt;ref&amp;gt;https://en.wikipedia.org/wiki/Don%27t_repeat_yourself&amp;lt;/ref&amp;gt;.  A prime example of a method that initially violated these principles was the import method, which in addition to performing the core import processes also performed a number of checks that would be more properly extracted into private methods.&lt;br /&gt;
&lt;br /&gt;
=Code Changes =&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Refactoring of import method ===&lt;br /&gt;
&lt;br /&gt;
CodeClimate reports showed the import method to be overly complex, with a number of checks being included within the import method itself.  The resolution for this problem was to refactor the import method, creating private methods to perform the null checks and throw import errors.  Prior to refactoring, all null checks were performed within the import method.   After refactoring, the import method adheres to the single responsibility principle, performing only key import tasks while making calls to private methods for any necessary validation. The size of the import method was reduced by doing this and counts for better readability of the code. Also, this method is a very important one and care was taken so that any existing functionality did not break. &lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
Before refactoring:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;big&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 def self.import(row, session, id)&lt;br /&gt;
    if row.length &amp;lt; 2&lt;br /&gt;
      raise ArgumentError, &amp;quot;Not enough items&amp;quot;&lt;br /&gt;
    end&lt;br /&gt;
    assignment = Assignment.find(id)&lt;br /&gt;
    if assignment.nil?&lt;br /&gt;
      raise ImportError, &amp;quot;The assignment with id \&amp;quot;#{id}\&amp;quot; was not found. &amp;lt;a href='/assignment/new'&amp;gt;Create&amp;lt;/a&amp;gt; this assignment?&amp;quot;&lt;br /&gt;
    end&lt;br /&gt;
    index = 1&lt;br /&gt;
    while index &amp;lt; row.length&lt;br /&gt;
      user = User.find_by_name(row[index].to_s.strip)&lt;br /&gt;
      if user.nil?&lt;br /&gt;
        raise ImportError, &amp;quot;The user account for the reviewer \&amp;quot;#{row[index]}\&amp;quot; was not found. &amp;lt;a href='/users/new'&amp;gt;Create&amp;lt;/a&amp;gt; this user?&amp;quot;&lt;br /&gt;
      end&lt;br /&gt;
      reviewer = AssignmentParticipant.where(user_id: user.id, parent_id:  assignment.id).first&lt;br /&gt;
      if reviewer == nil&lt;br /&gt;
        raise ImportError, &amp;quot;The reviewer \&amp;quot;#{row[index]}\&amp;quot; is not a participant in this assignment. &amp;lt;a href='/users/new'&amp;gt;Register&amp;lt;/a&amp;gt; this user as a participant?&amp;quot;&lt;br /&gt;
      end&lt;br /&gt;
      if assignment.team_assignment&lt;br /&gt;
        reviewee = AssignmentTeam.where(name: row[0].to_s.strip, parent_id:  assignment.id).first&lt;br /&gt;
        if reviewee == nil&lt;br /&gt;
          raise ImportError, &amp;quot;The author \&amp;quot;#{row[0].to_s.strip}\&amp;quot; was not found. &amp;lt;a href='/users/new'&amp;gt;Create&amp;lt;/a&amp;gt; this user?&amp;quot;&lt;br /&gt;
        end&lt;br /&gt;
        existing = ReviewResponseMap.where(reviewee_id: reviewee.id, reviewer_id:  reviewer.id).first&lt;br /&gt;
        if existing.nil?&lt;br /&gt;
          ReviewResponseMap.create(:reviewer_id =&amp;gt; reviewer.id, :reviewee_id =&amp;gt; reviewee.id, :reviewed_object_id =&amp;gt; assignment.id)&lt;br /&gt;
        end&lt;br /&gt;
      else&lt;br /&gt;
        puser = User.find_by_name(row[0].to_s.strip)&lt;br /&gt;
        if user == nil&lt;br /&gt;
          raise ImportError, &amp;quot;The user account for the reviewee \&amp;quot;#{row[0]}\&amp;quot; was not found. &amp;lt;a href='/users/new'&amp;gt;Create&amp;lt;/a&amp;gt; this user?&amp;quot;&lt;br /&gt;
        end&lt;br /&gt;
        reviewee = AssignmentParticipant.where(user_id: puser.id, parent_id:  assignment.id).first&lt;br /&gt;
        if reviewee == nil&lt;br /&gt;
          raise ImportError, &amp;quot;The author \&amp;quot;#{row[0].to_s.strip}\&amp;quot; was not found. &amp;lt;a href='/users/new'&amp;gt;Create&amp;lt;/a&amp;gt; this user?&amp;quot;&lt;br /&gt;
        end&lt;br /&gt;
        team_id = TeamsUser.team_id(reviewee.parent_id, reviewee.user_id)&lt;br /&gt;
        existing = ReviewResponseMap.where(reviewee_id: team_id, reviewer_id:  reviewer.id).first&lt;br /&gt;
        if existing.nil?&lt;br /&gt;
          ReviewResponseMap.create(:reviewee_id =&amp;gt; team_id, :reviewer_id =&amp;gt; reviewer.id, :reviewed_object_id =&amp;gt; assignment.id)&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
      index += 1&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
&lt;br /&gt;
After refactoring:&lt;br /&gt;
 &lt;br /&gt;
  &amp;lt;big&amp;gt;&amp;lt;nowiki&amp;gt;#Imports new reponse maps if they do not already exist&lt;br /&gt;
  def self.import(row, _session, id)&lt;br /&gt;
      if row.length &amp;lt; 2&lt;br /&gt;
          raise ArgumentError, 'Not enough items'&lt;br /&gt;
      end&lt;br /&gt;
      assignment = find_assignment(id)&lt;br /&gt;
      index = 1&lt;br /&gt;
      reviewee_name = row[0]&lt;br /&gt;
      while index &amp;lt; row.length&lt;br /&gt;
          reviewee_id = nil&lt;br /&gt;
          reviewer_name = row[index]&lt;br /&gt;
          reviewer = get_assignment_participant(reviewer_name,  assignment.id, &amp;quot;reviewer&amp;quot;)&lt;br /&gt;
          participant_nil?(reviewer, reviewer_name , &amp;quot;reviewer&amp;quot;)&lt;br /&gt;
         &lt;br /&gt;
         #Find reviewee if assignment is a team assignment&lt;br /&gt;
         if assignment.team_assignment&lt;br /&gt;
             reviewee = AssignmentTeam.where(name: reviewee_name .to_s.strip, parent_id: assignment.id).first&lt;br /&gt;
             participant_nil?(reviewee, reviewee_name, &amp;quot;author&amp;quot;)&lt;br /&gt;
             reviewee_id = reviewee.id&lt;br /&gt;
         #Find reviewee if assignment is not a team assignment&lt;br /&gt;
         else&lt;br /&gt;
	     reviewee = get_assignment_participant(reviewee_name, assignment.id, &amp;quot;reviewee&amp;quot;)&lt;br /&gt;
             participant_nil?(reviewee, reviewee_name, &amp;quot;author&amp;quot;)&lt;br /&gt;
             reviewee_id  = TeamsUser.team_id(reviewee.parent_id, reviewee.user_id)&lt;br /&gt;
         end&lt;br /&gt;
         create_response_map(reviewer, reviewee_id,  assignment)&lt;br /&gt;
         index += 1&lt;br /&gt;
      end&lt;br /&gt;
  end&amp;lt;/nowiki&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Private methods added:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;big&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  # Check for if assignment value is null&lt;br /&gt;
  def self.find_assignment(id)&lt;br /&gt;
      begin&lt;br /&gt;
          assignment = Assignment.find(id)&lt;br /&gt;
      rescue ActiveRecord::RecordNotFound&lt;br /&gt;
          raise ImportError, &amp;quot;The assignment with id \&amp;quot;#{id}\&amp;quot; was not found.&amp;lt;a href='/assignment/new'&amp;gt;Create&amp;lt;/a&amp;gt; this assignment?&amp;quot;&lt;br /&gt;
      end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  # Check for if participant is null&lt;br /&gt;
  def self.participant_nil?(participant, user_name, participant_type) &lt;br /&gt;
      error_message = nil&lt;br /&gt;
      if participant_type == &amp;quot;author&amp;quot;&lt;br /&gt;
          error_message = &amp;quot;The author \&amp;quot;#{user_name.to_s.strip}\&amp;quot; was not found.&amp;lt;a href='/users/new'&amp;gt;Create&amp;lt;/a&amp;gt; this user?&amp;quot;&lt;br /&gt;
      else&lt;br /&gt;
          error_message =  &amp;quot;The reviewer \&amp;quot;#{user_name}\&amp;quot; is not a participant in this assignment.&amp;lt;a href='/users/new'&amp;gt;Register&amp;lt;/a&amp;gt; this user as a participant?&amp;quot;&lt;br /&gt;
      end&lt;br /&gt;
      check_nil?(participant, error_message)&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  # Check for if user is null&lt;br /&gt;
  def self.user_nil?(user, user_name, user_type)&lt;br /&gt;
      check_nil?( user, &amp;quot;The user account for the \&amp;quot;#{user_type}\&amp;quot; \&amp;quot;#{user_name}\&amp;quot; was not found.&amp;lt;a href='/users/new'&amp;gt;Create&amp;lt;/a&amp;gt; this user?&amp;quot;)&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
 #Throws import error for nil objects&lt;br /&gt;
  def self.check_nil?(object, error_message)&lt;br /&gt;
      if object.nil?&lt;br /&gt;
          raise ImportError, error_message&lt;br /&gt;
      end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Refactoring of get_assessments_round_for method ===&lt;br /&gt;
&lt;br /&gt;
The get_assessments_round_for method’s name failed to provide a clear idea of the method’s purpose and functionality.  This is why it was renamed to get_team_responses_for_round, the new name of the method provides a clearer idea of its purpose. Additionally, there was a private variable, team_id, introduced in the method that was unnecessary and could be replaced by using the id property of the team parameter directly.  We also removed the return statement at the end of the method.  &lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
Before refactoring:&lt;br /&gt;
&amp;lt;big&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  def self.get_assessments_round_for(team,round)&lt;br /&gt;
    team_id =team.id&lt;br /&gt;
    responses = Array.new&lt;br /&gt;
    if team_id&lt;br /&gt;
      maps = ResponseMap.where(:reviewee_id =&amp;gt; team_id, :type =&amp;gt; &amp;quot;ReviewResponseMap&amp;quot;)&lt;br /&gt;
      maps.each{ |map|&lt;br /&gt;
        if !map.response.empty? &amp;amp;&amp;amp; !map.response.reject{|r| r.round!=round}.empty?&lt;br /&gt;
          responses &amp;lt;&amp;lt; map.response.reject{|r| r.round!=round}.last&lt;br /&gt;
        end&lt;br /&gt;
      }&lt;br /&gt;
      responses.sort! {|a,b| a.map.reviewer.fullname &amp;lt;=&amp;gt; b.map.reviewer.fullname }&lt;br /&gt;
    end&lt;br /&gt;
    return responses&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
&lt;br /&gt;
After refactoring: &lt;br /&gt;
&lt;br /&gt;
&amp;lt;big&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  # return the responses for specified round,&lt;br /&gt;
  # for varying rubric feature -Yang&lt;br /&gt;
  def self.get_team_responses_for_round(team, round)&lt;br /&gt;
    responses = []&lt;br /&gt;
    if team.id&lt;br /&gt;
      maps = ResponseMap.where(reviewee_id: team.id, type: 'ReviewResponseMap')&lt;br /&gt;
      maps.each do |map|&lt;br /&gt;
        unless map.response.empty? &amp;amp;&amp;amp; map.response.reject { |r| r.round != round }.empty?&lt;br /&gt;
          responses &amp;lt;&amp;lt; map.response.reject { |r| r.round != round }.last&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
      responses.sort! { |a, b| a.map.reviewer.fullname &amp;lt;=&amp;gt; b.map.reviewer.fullname }&lt;br /&gt;
    end&lt;br /&gt;
    responses&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
The change in method name also required changes to the following files that referenced it:&lt;br /&gt;
&lt;br /&gt;
/app/models/assignment.rb:436:    &lt;br /&gt;
 &lt;br /&gt;
&amp;lt;big&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  assessments = ReviewResponseMap.get_assessments_round_for(team,i)&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt; &lt;br /&gt;
&lt;br /&gt;
./app/models/assignment_participant.rb:268:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;big&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 scores[questionnaire_symbol][:assessments] = questionnaire.get_assessments_round_for(self,round)&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Refactoring of metareview_response_maps method ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The metareview_response_maps method was unnecessarily complex.  It contained an unneeded private variable and an unnecessary nested loop.  Originally, it added each metareview map individually in the nested loop.  We decided to remove the nested loop and use the concat method for readability and maintainability.  These changes allowed us to remove the private variable &amp;quot;metareview_list&amp;quot; and only maintain the &amp;quot;metareview_response_maps&amp;quot; variable.  We also renamed the metareview_response_maps method to get_metareview_response_maps method to be more descriptive about the intent of the method. &lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
Before refactoring:&lt;br /&gt;
&amp;lt;big&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 def metareview_response_maps&lt;br /&gt;
    responses = Response.where(map_id:self.id)&lt;br /&gt;
    metareview_list=[]&lt;br /&gt;
    responses.each do |response|&lt;br /&gt;
      metareview_response_maps = MetareviewResponseMap.where(reviewed_object_id:response.id)&lt;br /&gt;
      metareview_response_maps.each do |metareview_response_map|&lt;br /&gt;
        metareview_list&amp;lt;&amp;lt;metareview_response_map&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
    metareview_list&lt;br /&gt;
 end&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
After refactoring:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;big&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  def get_metareview_response_maps&lt;br /&gt;
    responses = Response.where(map_id: id)&lt;br /&gt;
    metareview_response_maps = []&lt;br /&gt;
    responses.each do |response|&lt;br /&gt;
      metareview_response_maps.concat MetareviewResponseMap.where(reviewed_object_id: response.id)&lt;br /&gt;
    end&lt;br /&gt;
    metareview_response_maps&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Refactoring of export method ===&lt;br /&gt;
The export method contained mappings.sort! { |a, b| a.reviewee.name &amp;lt;=&amp;gt; b.reviewee.name }.  We could not get past this when running tests, we kept getting a message saying, &amp;quot;sort! was not a method for an ActiveRecord_Relation&amp;quot;.  But, ActiveRecord_Relation does allow the use of sort.  So we changed that line of code to  mappings = mappings.sort { |a, b| a.reviewee.name &amp;lt;=&amp;gt; b.reviewee.name }&lt;br /&gt;
&lt;br /&gt;
Before refactoring:&lt;br /&gt;
&amp;lt;big&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  def self.export(csv, parent_id, options)&lt;br /&gt;
    mappings = where(reviewed_object_id: parent_id)&lt;br /&gt;
    mappings.sort! { |a, b| a.reviewee.name &amp;lt;=&amp;gt; b.reviewee.name }&lt;br /&gt;
    mappings.each {&lt;br /&gt;
      |map|&lt;br /&gt;
      csv &amp;lt;&amp;lt; [&lt;br /&gt;
        map.reviewee.name,&lt;br /&gt;
        map.reviewer.name&lt;br /&gt;
      ]&lt;br /&gt;
    }&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
&lt;br /&gt;
After refactoring:&lt;br /&gt;
&amp;lt;big&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  def self.export(csv, parent_id, options)&lt;br /&gt;
    mappings = where(reviewed_object_id: parent_id)&lt;br /&gt;
    mappings = mappings.sort { |a, b| a.reviewee.name &amp;lt;=&amp;gt; b.reviewee.name }&lt;br /&gt;
    mappings.each do&lt;br /&gt;
    |map|&lt;br /&gt;
      csv &amp;lt;&amp;lt; [map.reviewee.name, map.reviewer.name]&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Refactoring of final_versions_from_reviewer method ===&lt;br /&gt;
The final_versions_from_reviewer method was too long and repetitive.  We removed common functionality from within the if and else statement and put it in a private method final_versions_from_reviewer.  Then we created the get_responses method to find the responses based on the arguments values.  These private methods make the class more readable for other programmers.&lt;br /&gt;
 &lt;br /&gt;
Before refactoring:&lt;br /&gt;
&amp;lt;big&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  def self.final_versions_from_reviewer(reviewer_id)&lt;br /&gt;
    maps = ReviewResponseMap.where(reviewer_id: reviewer_id)&lt;br /&gt;
    assignment = Assignment.find(Participant.find(reviewer_id).parent_id)&lt;br /&gt;
    review_final_versions = Hash.new&lt;br /&gt;
    if !assignment.varying_rubrics_by_round?&lt;br /&gt;
      #same review rubric used in multiple rounds&lt;br /&gt;
      review_final_versions[:review] = Hash.new&lt;br /&gt;
      review_final_versions[:review][:questionnaire_id] = assignment.get_review_questionnaire_id&lt;br /&gt;
      response_ids = Array.new&lt;br /&gt;
      maps.each do |map|&lt;br /&gt;
        responses = Response.where(map_id:map.id)&lt;br /&gt;
        if !responses.empty?&lt;br /&gt;
          response_ids &amp;lt;&amp;lt; responses.last.id&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
      review_final_versions[:review][:response_ids] = response_ids&lt;br /&gt;
    else&lt;br /&gt;
      #vary rubric by round&lt;br /&gt;
      rounds_num = assignment.rounds_of_reviews&lt;br /&gt;
      for round in 1..rounds_num&lt;br /&gt;
        symbol = (&amp;quot;review round&amp;quot;+round.to_s).to_sym&lt;br /&gt;
        review_final_versions[symbol] = Hash.new&lt;br /&gt;
        review_final_versions[symbol][:questionnaire_id] = assignment.get_review_questionnaire_id(round)&lt;br /&gt;
        response_ids = Array.new&lt;br /&gt;
        maps.each do |map|&lt;br /&gt;
          responses = Response.where(map_id:map.id, round:round)&lt;br /&gt;
          if !responses.empty?&lt;br /&gt;
            response_ids &amp;lt;&amp;lt; responses.last.id&lt;br /&gt;
          end&lt;br /&gt;
        end&lt;br /&gt;
        review_final_versions[symbol][:response_ids] = response_ids&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
    review_final_versions&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
&lt;br /&gt;
After refactoring:&lt;br /&gt;
&amp;lt;big&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  def self.final_versions_from_reviewer(reviewer_id)&lt;br /&gt;
    maps = ReviewResponseMap.where(reviewer_id: reviewer_id)&lt;br /&gt;
    assignment = find_assignment(Participant.find(reviewer_id).parent_id)&lt;br /&gt;
    review_final_versions = {}&lt;br /&gt;
    unless assignment.varying_rubrics_by_round?&lt;br /&gt;
      #same review rubric used in multiple rounds&lt;br /&gt;
      review_final_versions = review_final_version_responses(:review, :questionnaire_id, assignment, maps)&lt;br /&gt;
    else&lt;br /&gt;
      # vary rubric by round&lt;br /&gt;
      rounds_num = assignment.rounds_of_reviews&lt;br /&gt;
      (1..rounds_num).each do |round|&lt;br /&gt;
        symbol = ('review round' + round.to_s).to_sym&lt;br /&gt;
        review_final_versions = review_final_version_responses(symbol, :questionnaire_id, assignment, maps, round)&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
    review_final_versions&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Private methods added:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;big&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  # Compute list of responses and return it&lt;br /&gt;
  def self.review_final_version_responses(symbol, questionnaire_id, assignment, maps, round = nil)&lt;br /&gt;
    review_final_versions = {}&lt;br /&gt;
    review_final_versions[symbol] = {}&lt;br /&gt;
    review_final_versions[symbol][questionnaire_id] = assignment.get_review_questionnaire_id(round)&lt;br /&gt;
    response_ids = []&lt;br /&gt;
    maps.each do |map|&lt;br /&gt;
      responses =  get_responses(map.id, round)&lt;br /&gt;
      unless responses.empty?&lt;br /&gt;
        response_ids &amp;lt;&amp;lt; responses.last.id&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
    review_final_versions[symbol][:response_ids] = response_ids&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;big&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  #Get responses by map_id and round (if exists)&lt;br /&gt;
  def self.get_responses(id, round)&lt;br /&gt;
     if round.nil?&lt;br /&gt;
       responses = Response.where(map_id: id)&lt;br /&gt;
     else&lt;br /&gt;
       responses = Response.where(map_id: id, round: round)&lt;br /&gt;
     end	&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Refactoring of other methods ===&lt;br /&gt;
Although trivial, we removed the return statement from the get_title, export_fields, and show_feedback methods because return statements are unnecessary in Ruby.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Addition of code comments ===&lt;br /&gt;
&lt;br /&gt;
We added comments to all of the methods in the ReviewResponseMap.rb file and corrected instances where CodeClimate Identified opportunities for code improvement.  One issue flagged by CodeClimate that we did not change was to use the find_by method instead of where().first method.  The where().first method occurs in the import, get_assignment_participant, and create_response_map methods. It is not always appropriate to use the find_by method, as documented in this github post: https://github.com/bbatsov/rubocop/issues/1938 .  In instances where ordering by id is the desired behavior, where().first will order by default, but in Rails 4+ find_by does not honor that default behavior.  For this reason we left the instances of where().first unchanged.&lt;br /&gt;
&lt;br /&gt;
=== Code Improvements ===&lt;br /&gt;
&lt;br /&gt;
This refactoring was to improve readability and follow as many good ''Rubyist'' coding practices as possible without breaking the functionality of existing code. We used CodeClimate of the master branch code as a reference. We took the suggestions we got from CodeClimate and improved our code based on that.&lt;br /&gt;
We also made some of the methods shorter by removing redundant functionality and adding private methods to methods with a lot internal functionality. We also added private methods in places where we saw repeated patterns to make the code ''DRYer''.&lt;br /&gt;
At the end of our refactoring, we managed to improve the rating on CodeClimate from a '''C''' to a '''B''' . Further improvements meant reducing the size of the entire class which required a much more significant refactoring in multiple files and folders. We focused on refactoring the existing model, '''ReviewResponseMap'''.&lt;br /&gt;
&lt;br /&gt;
= Unit Tests =&lt;br /&gt;
The previous unit tests had syntactical and run time errors.  We were not able to get the previous unit tests to run without errors.  Because of this we rewrote all of the unit tests for the &amp;lt;b&amp;gt;ReviewResponseModel&amp;lt;/b&amp;gt;.  It is important to have working unit tests so that when internal changes are made to functions the external output remains the same.&lt;br /&gt;
&lt;br /&gt;
=== Refactoring of Unit Tests===&lt;br /&gt;
&lt;br /&gt;
We added a test_helper file to the main test folder that requires a needed configuration file and needed gems.  We also added 8 fixtures that were needed for data to run the unit tests.  The following fixture files were added:&lt;br /&gt;
&lt;br /&gt;
* assignment_questionnaires.yml&lt;br /&gt;
* assignments.yml&lt;br /&gt;
* participants.yml&lt;br /&gt;
* questionnaires.yml&lt;br /&gt;
* response_maps.yml&lt;br /&gt;
* responses.yml&lt;br /&gt;
* teams.yml&lt;br /&gt;
* users.yml&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
There is at least one unit test for every public method within the &amp;lt;b&amp;gt;ReviewResponseModel&amp;lt;/b&amp;gt;.  The test naming convention used is &amp;quot;method_&amp;lt;name of method that is being tested&amp;gt;&amp;quot;.  For example, the unit test for the export method is &amp;quot;method_export&amp;quot;.  If there are multiple test for one method the name of the test will include the test case after the normal naming convention.  For example, one of the unit tests for the import method checks for an invalid assignment.  The name of this method is &amp;quot;method_import_invalid_assignment&amp;quot;.  The following are the unit tests we created:&lt;br /&gt;
&lt;br /&gt;
* method_export&lt;br /&gt;
* method_get_metareview_response_maps&lt;br /&gt;
* method_get_team_response_for_round&lt;br /&gt;
* method_final_versions_from_reviewer&lt;br /&gt;
* method_import&lt;br /&gt;
* method_import_invalid_reviewee&lt;br /&gt;
* method_import_invalid_reviewer&lt;br /&gt;
* method_import_invalid_assignment&lt;br /&gt;
* method_delete&lt;br /&gt;
* method_delete_no _force&lt;br /&gt;
* method_show_feedback&lt;br /&gt;
* method_get_title&lt;br /&gt;
* method_export_fields&lt;br /&gt;
* method_questionnaire&lt;br /&gt;
* method_add_reviewer&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== How to Run Unit Tests ===&lt;br /&gt;
To run the unit tests, follow these steps:&lt;br /&gt;
&lt;br /&gt;
# Download the master branch of the repo.&lt;br /&gt;
# Setup the Databases for the test environment (we have used Zhewei's scrubbed expertiza DB )&lt;br /&gt;
#* Run the &amp;quot; rake db:create RAILS_ENV=test &amp;quot; command&lt;br /&gt;
#* Run the &amp;quot; rake db:reset RAILS_ENV=test &amp;quot; command&lt;br /&gt;
#* Scrub the DB using &amp;quot; mysql -u root expertiza_development &amp;lt; expertiza-scrubbed.sql&amp;quot;&lt;br /&gt;
#* Run the &amp;quot; rake db:migrate &amp;quot;&lt;br /&gt;
# Run &amp;quot; rake test test/unit/review_response_map_test.rb &amp;quot; in the &amp;quot;expertiza/&amp;quot; directory.&lt;br /&gt;
#* If you run into a mysql log in error go into config/database.yml and edit the mysql credentials for the test section so that it matches the local environment's mysql configuration&lt;br /&gt;
# Check if tests passed or failed.&lt;br /&gt;
&lt;br /&gt;
= Manual Test Case =&lt;br /&gt;
&lt;br /&gt;
In order to test the changes made to the ReviewResponseMap, bring up [[ http://152.46.16.195:5902/ | Expertiza]] and log in as an administrator.  Once logged in, proceed with the following steps:&lt;br /&gt;
&lt;br /&gt;
# Go to '''impersonate user''' when logged in as ''instructor6'' and type in ''student559'' (or) just log in as ''student559''. All passwords are ''password'' .&lt;br /&gt;
# Pick any assignment to view.&lt;br /&gt;
# Navigate to '''Other's work'''.&lt;br /&gt;
# Check the different reviews and metareviews. Whether they are being displayed correctly or not.&lt;br /&gt;
# Go to Edit or Give feedback and submit a feedback.&lt;br /&gt;
# Go back and check if the feedback given is displayed correctly or not.&lt;br /&gt;
# Check if author's feedback is correct or not.&lt;br /&gt;
# Go to the '''Temp''' assignment and see if the page is being displayed correctly or not (since there is no assignment submission content or reviews for that).&lt;br /&gt;
&lt;br /&gt;
''NOTE: Since this was a refactoring of the code and methods, the existing functionality was supposed to remain the same and not break for the changes we've made.''&lt;br /&gt;
&lt;br /&gt;
= References =&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;references/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;4.&amp;amp;nbsp; [https://github.com/expertiza/expertiza Expertiza Main Repo] &amp;lt;br&amp;gt;&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;5.&amp;amp;nbsp; [https://github.com/adeeshag/expertiza/blob/develop/app/models/review_response_map.rb Refactored ReviewResponseMap.rb]&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;6.&amp;amp;nbsp; [https://github.com/adeeshag/expertiza/tree/develop/test/fixtures Test Fixtures]&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;7.&amp;amp;nbsp; [https://github.com/adeeshag/expertiza/blob/develop/test/unit/review_response_map_test.rb Unit Tests]&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;8.&amp;amp;nbsp; [http://152.46.16.195:5902/ Expertiza Deployed Site]&amp;lt;br&amp;gt;&lt;/div&gt;</summary>
		<author><name>Cnbrown4</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2015/ossE1558BGJ&amp;diff=98464</id>
		<title>CSC/ECE 517 Fall 2015/ossE1558BGJ</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2015/ossE1558BGJ&amp;diff=98464"/>
		<updated>2015-11-06T21:40:21Z</updated>

		<summary type="html">&lt;p&gt;Cnbrown4: /* Refactoring of export method */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Introduction =&lt;br /&gt;
&lt;br /&gt;
This page provides a description of the modifications and improvements made to the Expertiza project’s source code as part of an Expertiza based Open Source Software project.  Expertiza is a web based application which allows students to submit and peer-review classmates’ work, including written articles and development projects. The specific changes made during the course of this project were to the ReviewResponseMap.rb file, with additional changes made to other related files in support of refactoring ReviewResponseMap.rb.  &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
= Problem Statement =&lt;br /&gt;
&lt;br /&gt;
ReviewResponseMap is the model class used to manage the relationship between contributors, reviewers, and assignments.  The intent of the changes were to refactor the code for better readability and adherence to Ruby coding standards and best practices.  Primarily these changes involved the refactoring of overly complex methods, renaming methods for better readability, and the addition of missing unit tests.&lt;br /&gt;
&lt;br /&gt;
Project Requirements:&lt;br /&gt;
&lt;br /&gt;
# Code Climate&amp;lt;ref name=&amp;quot;Code Climate&amp;quot;&amp;gt;https://codeclimate.com&amp;lt;/ref&amp;gt; shows import method is complex, because of lots of checks. This method can be fixed by adding private methods for raising import error.&lt;br /&gt;
# Get_assessments_round_for method can be renamed to get_team_responses_for_round. Team_id private variable is not needed.&lt;br /&gt;
# metareview_response_maps rename, refactoring can be done. No need to do second iteration.&lt;br /&gt;
# write missing unit tests for existing methods.&lt;br /&gt;
&lt;br /&gt;
= Design Patterns =&lt;br /&gt;
&lt;br /&gt;
As part of our project, we refactored the model to follow the Single Responsibility and Don't Repeat Yourself (DRY) Principles.  Both of the principles focus on reducing code repetition and increasing the cohesion of the individual methods in the class.  The Single Responsibility Principle states that each class and method should have sole responsibility over one single part of the functionality of the system&amp;lt;ref&amp;gt;https://en.wikipedia.org/wiki/Single_responsibility_principle&amp;lt;/ref&amp;gt;.  The DRY principle states that whenever the same types of logic and functionality are being performed in a class the duplicated logic should be extracted into a new method that can be called in place of the repeated lines of code &amp;lt;ref&amp;gt;https://en.wikipedia.org/wiki/Don%27t_repeat_yourself&amp;lt;/ref&amp;gt;.  A prime example of a method that initially violated these principles was the import method, which in addition to performing the core import processes also performed a number of checks that would be more properly extracted into private methods.&lt;br /&gt;
&lt;br /&gt;
=Code Changes =&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Refactoring of import method ===&lt;br /&gt;
&lt;br /&gt;
CodeClimate reports showed the import method to be overly complex, with a number of checks being included within the import method itself.  The resolution for this problem was to refactor the import method, creating private methods to perform the null checks and throw import errors.  Prior to refactoring, all null checks were performed within the import method.   After refactoring, the import method adheres to the single responsibility principle, performing only key import tasks while making calls to private methods for any necessary validation. The size of the import method was reduced by doing this and counts for better readability of the code. Also, this method is a very important one and care was taken so that any existing functionality did not break. &lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
Before refactoring:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;big&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 def self.import(row, session, id)&lt;br /&gt;
    if row.length &amp;lt; 2&lt;br /&gt;
      raise ArgumentError, &amp;quot;Not enough items&amp;quot;&lt;br /&gt;
    end&lt;br /&gt;
    assignment = Assignment.find(id)&lt;br /&gt;
    if assignment.nil?&lt;br /&gt;
      raise ImportError, &amp;quot;The assignment with id \&amp;quot;#{id}\&amp;quot; was not found. &amp;lt;a href='/assignment/new'&amp;gt;Create&amp;lt;/a&amp;gt; this assignment?&amp;quot;&lt;br /&gt;
    end&lt;br /&gt;
    index = 1&lt;br /&gt;
    while index &amp;lt; row.length&lt;br /&gt;
      user = User.find_by_name(row[index].to_s.strip)&lt;br /&gt;
      if user.nil?&lt;br /&gt;
        raise ImportError, &amp;quot;The user account for the reviewer \&amp;quot;#{row[index]}\&amp;quot; was not found. &amp;lt;a href='/users/new'&amp;gt;Create&amp;lt;/a&amp;gt; this user?&amp;quot;&lt;br /&gt;
      end&lt;br /&gt;
      reviewer = AssignmentParticipant.where(user_id: user.id, parent_id:  assignment.id).first&lt;br /&gt;
      if reviewer == nil&lt;br /&gt;
        raise ImportError, &amp;quot;The reviewer \&amp;quot;#{row[index]}\&amp;quot; is not a participant in this assignment. &amp;lt;a href='/users/new'&amp;gt;Register&amp;lt;/a&amp;gt; this user as a participant?&amp;quot;&lt;br /&gt;
      end&lt;br /&gt;
      if assignment.team_assignment&lt;br /&gt;
        reviewee = AssignmentTeam.where(name: row[0].to_s.strip, parent_id:  assignment.id).first&lt;br /&gt;
        if reviewee == nil&lt;br /&gt;
          raise ImportError, &amp;quot;The author \&amp;quot;#{row[0].to_s.strip}\&amp;quot; was not found. &amp;lt;a href='/users/new'&amp;gt;Create&amp;lt;/a&amp;gt; this user?&amp;quot;&lt;br /&gt;
        end&lt;br /&gt;
        existing = ReviewResponseMap.where(reviewee_id: reviewee.id, reviewer_id:  reviewer.id).first&lt;br /&gt;
        if existing.nil?&lt;br /&gt;
          ReviewResponseMap.create(:reviewer_id =&amp;gt; reviewer.id, :reviewee_id =&amp;gt; reviewee.id, :reviewed_object_id =&amp;gt; assignment.id)&lt;br /&gt;
        end&lt;br /&gt;
      else&lt;br /&gt;
        puser = User.find_by_name(row[0].to_s.strip)&lt;br /&gt;
        if user == nil&lt;br /&gt;
          raise ImportError, &amp;quot;The user account for the reviewee \&amp;quot;#{row[0]}\&amp;quot; was not found. &amp;lt;a href='/users/new'&amp;gt;Create&amp;lt;/a&amp;gt; this user?&amp;quot;&lt;br /&gt;
        end&lt;br /&gt;
        reviewee = AssignmentParticipant.where(user_id: puser.id, parent_id:  assignment.id).first&lt;br /&gt;
        if reviewee == nil&lt;br /&gt;
          raise ImportError, &amp;quot;The author \&amp;quot;#{row[0].to_s.strip}\&amp;quot; was not found. &amp;lt;a href='/users/new'&amp;gt;Create&amp;lt;/a&amp;gt; this user?&amp;quot;&lt;br /&gt;
        end&lt;br /&gt;
        team_id = TeamsUser.team_id(reviewee.parent_id, reviewee.user_id)&lt;br /&gt;
        existing = ReviewResponseMap.where(reviewee_id: team_id, reviewer_id:  reviewer.id).first&lt;br /&gt;
        if existing.nil?&lt;br /&gt;
          ReviewResponseMap.create(:reviewee_id =&amp;gt; team_id, :reviewer_id =&amp;gt; reviewer.id, :reviewed_object_id =&amp;gt; assignment.id)&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
      index += 1&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
&lt;br /&gt;
After refactoring:&lt;br /&gt;
 &lt;br /&gt;
  &amp;lt;big&amp;gt;&amp;lt;nowiki&amp;gt;#Imports new reponse maps if they do not already exist&lt;br /&gt;
  def self.import(row, _session, id)&lt;br /&gt;
      if row.length &amp;lt; 2&lt;br /&gt;
          raise ArgumentError, 'Not enough items'&lt;br /&gt;
      end&lt;br /&gt;
      assignment = find_assignment(id)&lt;br /&gt;
      index = 1&lt;br /&gt;
      reviewee_name = row[0]&lt;br /&gt;
      while index &amp;lt; row.length&lt;br /&gt;
          reviewee_id = nil&lt;br /&gt;
          reviewer_name = row[index]&lt;br /&gt;
          reviewer = get_assignment_participant(reviewer_name,  assignment.id, &amp;quot;reviewer&amp;quot;)&lt;br /&gt;
          participant_nil?(reviewer, reviewer_name , &amp;quot;reviewer&amp;quot;)&lt;br /&gt;
         &lt;br /&gt;
         #Find reviewee if assignment is a team assignment&lt;br /&gt;
         if assignment.team_assignment&lt;br /&gt;
             reviewee = AssignmentTeam.where(name: reviewee_name .to_s.strip, parent_id: assignment.id).first&lt;br /&gt;
             participant_nil?(reviewee, reviewee_name, &amp;quot;author&amp;quot;)&lt;br /&gt;
             reviewee_id = reviewee.id&lt;br /&gt;
         #Find reviewee if assignment is not a team assignment&lt;br /&gt;
         else&lt;br /&gt;
	     reviewee = get_assignment_participant(reviewee_name, assignment.id, &amp;quot;reviewee&amp;quot;)&lt;br /&gt;
             participant_nil?(reviewee, reviewee_name, &amp;quot;author&amp;quot;)&lt;br /&gt;
             reviewee_id  = TeamsUser.team_id(reviewee.parent_id, reviewee.user_id)&lt;br /&gt;
         end&lt;br /&gt;
         create_response_map(reviewer, reviewee_id,  assignment)&lt;br /&gt;
         index += 1&lt;br /&gt;
      end&lt;br /&gt;
  end&amp;lt;/nowiki&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Private methods added:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;big&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  # Check for if assignment value is null&lt;br /&gt;
  def self.find_assignment(id)&lt;br /&gt;
      begin&lt;br /&gt;
          assignment = Assignment.find(id)&lt;br /&gt;
      rescue ActiveRecord::RecordNotFound&lt;br /&gt;
          raise ImportError, &amp;quot;The assignment with id \&amp;quot;#{id}\&amp;quot; was not found.&amp;lt;a href='/assignment/new'&amp;gt;Create&amp;lt;/a&amp;gt; this assignment?&amp;quot;&lt;br /&gt;
      end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  # Check for if participant is null&lt;br /&gt;
  def self.participant_nil?(participant, user_name, participant_type) &lt;br /&gt;
      error_message = nil&lt;br /&gt;
      if participant_type == &amp;quot;author&amp;quot;&lt;br /&gt;
          error_message = &amp;quot;The author \&amp;quot;#{user_name.to_s.strip}\&amp;quot; was not found.&amp;lt;a href='/users/new'&amp;gt;Create&amp;lt;/a&amp;gt; this user?&amp;quot;&lt;br /&gt;
      else&lt;br /&gt;
          error_message =  &amp;quot;The reviewer \&amp;quot;#{user_name}\&amp;quot; is not a participant in this assignment.&amp;lt;a href='/users/new'&amp;gt;Register&amp;lt;/a&amp;gt; this user as a participant?&amp;quot;&lt;br /&gt;
      end&lt;br /&gt;
      check_nil?(participant, error_message)&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  # Check for if user is null&lt;br /&gt;
  def self.user_nil?(user, user_name, user_type)&lt;br /&gt;
      check_nil?( user, &amp;quot;The user account for the \&amp;quot;#{user_type}\&amp;quot; \&amp;quot;#{user_name}\&amp;quot; was not found.&amp;lt;a href='/users/new'&amp;gt;Create&amp;lt;/a&amp;gt; this user?&amp;quot;)&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
 #Throws import error for nil objects&lt;br /&gt;
  def self.check_nil?(object, error_message)&lt;br /&gt;
      if object.nil?&lt;br /&gt;
          raise ImportError, error_message&lt;br /&gt;
      end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Refactoring of get_assessments_round_for method ===&lt;br /&gt;
&lt;br /&gt;
The get_assessments_round_for method’s name failed to provide a clear idea of the method’s purpose and functionality.  This is why it was renamed to get_team_responses_for_round, the new name of the method provides a clearer idea of its purpose. Additionally, there was a private variable, team_id, introduced in the method that was unnecessary and could be replaced by using the id property of the team parameter directly.  We also removed the return statement at the end of the method.  &lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
Before refactoring:&lt;br /&gt;
&amp;lt;big&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  def self.get_assessments_round_for(team,round)&lt;br /&gt;
    team_id =team.id&lt;br /&gt;
    responses = Array.new&lt;br /&gt;
    if team_id&lt;br /&gt;
      maps = ResponseMap.where(:reviewee_id =&amp;gt; team_id, :type =&amp;gt; &amp;quot;ReviewResponseMap&amp;quot;)&lt;br /&gt;
      maps.each{ |map|&lt;br /&gt;
        if !map.response.empty? &amp;amp;&amp;amp; !map.response.reject{|r| r.round!=round}.empty?&lt;br /&gt;
          responses &amp;lt;&amp;lt; map.response.reject{|r| r.round!=round}.last&lt;br /&gt;
        end&lt;br /&gt;
      }&lt;br /&gt;
      responses.sort! {|a,b| a.map.reviewer.fullname &amp;lt;=&amp;gt; b.map.reviewer.fullname }&lt;br /&gt;
    end&lt;br /&gt;
    return responses&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
&lt;br /&gt;
After refactoring: &lt;br /&gt;
&lt;br /&gt;
&amp;lt;big&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  def self.get_team_responses_for_round(team, round)&lt;br /&gt;
    responses = []&lt;br /&gt;
    if team.id&lt;br /&gt;
      maps = ResponseMap.where(reviewee_id: team.id, type: 'ReviewResponseMap')&lt;br /&gt;
      maps.each do |map|&lt;br /&gt;
        unless map.response.empty? &amp;amp;&amp;amp; map.response.reject { |r| r.round != round }.empty?&lt;br /&gt;
          responses &amp;lt;&amp;lt; map.response.reject { |r| r.round != round }.last&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
      responses.sort! { |a, b| a.map.reviewer.fullname &amp;lt;=&amp;gt; b.map.reviewer.fullname }&lt;br /&gt;
    end&lt;br /&gt;
    responses&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
The change in method name also required changes to the following files that referenced it:&lt;br /&gt;
&lt;br /&gt;
/app/models/assignment.rb:436:    &lt;br /&gt;
 &lt;br /&gt;
&amp;lt;big&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  assessments = ReviewResponseMap.get_assessments_round_for(team,i)&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt; &lt;br /&gt;
&lt;br /&gt;
./app/models/assignment_participant.rb:268:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;big&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 scores[questionnaire_symbol][:assessments] = questionnaire.get_assessments_round_for(self,round)&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Refactoring of metareview_response_maps method ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The metareview_response_maps method was unnecessarily complex.  It contained an unneeded private variable and an unnecessary nested loop.  Originally, it added each metareview map individually in the nested loop.  We decided to remove the nested loop and use the concat method for readability and maintainability.  These changes allowed us to remove the private variable &amp;quot;metareview_list&amp;quot; and only maintain the &amp;quot;metareview_response_maps&amp;quot; variable.  We also renamed the metareview_response_maps method to get_metareview_response_maps method to be more descriptive about the intent of the method. &lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
Before refactoring:&lt;br /&gt;
&amp;lt;big&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 def metareview_response_maps&lt;br /&gt;
    responses = Response.where(map_id:self.id)&lt;br /&gt;
    metareview_list=[]&lt;br /&gt;
    responses.each do |response|&lt;br /&gt;
      metareview_response_maps = MetareviewResponseMap.where(reviewed_object_id:response.id)&lt;br /&gt;
      metareview_response_maps.each do |metareview_response_map|&lt;br /&gt;
        metareview_list&amp;lt;&amp;lt;metareview_response_map&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
    metareview_list&lt;br /&gt;
 end&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
After refactoring:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;big&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  def get_metareview_response_maps&lt;br /&gt;
    responses = Response.where(map_id: id)&lt;br /&gt;
    metareview_response_maps = []&lt;br /&gt;
    responses.each do |response|&lt;br /&gt;
      metareview_response_maps.concat MetareviewResponseMap.where(reviewed_object_id: response.id)&lt;br /&gt;
    end&lt;br /&gt;
    metareview_response_maps&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Refactoring of export method ===&lt;br /&gt;
The export method contained mappings.sort! { |a, b| a.reviewee.name &amp;lt;=&amp;gt; b.reviewee.name }.  We could not get past this when running tests, we kept getting a message saying, &amp;quot;sort! was not a method for an ActiveRecord_Relation&amp;quot;.  But, ActiveRecord_Relation does allow the use of sort.  So we changed that line of code to  mappings = mappings.sort { |a, b| a.reviewee.name &amp;lt;=&amp;gt; b.reviewee.name }&lt;br /&gt;
&lt;br /&gt;
Before refactoring:&lt;br /&gt;
&amp;lt;big&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  def self.export(csv, parent_id, options)&lt;br /&gt;
    mappings = where(reviewed_object_id: parent_id)&lt;br /&gt;
    mappings.sort! { |a, b| a.reviewee.name &amp;lt;=&amp;gt; b.reviewee.name }&lt;br /&gt;
    mappings.each {&lt;br /&gt;
      |map|&lt;br /&gt;
      csv &amp;lt;&amp;lt; [&lt;br /&gt;
        map.reviewee.name,&lt;br /&gt;
        map.reviewer.name&lt;br /&gt;
      ]&lt;br /&gt;
    }&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
&lt;br /&gt;
After refactoring:&lt;br /&gt;
&amp;lt;big&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  def self.export(csv, parent_id, options)&lt;br /&gt;
    mappings = where(reviewed_object_id: parent_id)&lt;br /&gt;
    mappings = mappings.sort { |a, b| a.reviewee.name &amp;lt;=&amp;gt; b.reviewee.name }&lt;br /&gt;
    mappings.each do&lt;br /&gt;
    |map|&lt;br /&gt;
      csv &amp;lt;&amp;lt; [map.reviewee.name, map.reviewer.name]&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Refactoring of final_versions_from_reviewer method ===&lt;br /&gt;
The final_versions_from_reviewer method was too long and repetitive.  We removed common functionality from within the if and else statement and put it in a private method final_versions_from_reviewer.  Then we created the get_responses method to find the responses based on the arguments values.  These private methods make the class more readable for other programmers.&lt;br /&gt;
 &lt;br /&gt;
Before refactoring:&lt;br /&gt;
&amp;lt;big&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  def self.final_versions_from_reviewer(reviewer_id)&lt;br /&gt;
    maps = ReviewResponseMap.where(reviewer_id: reviewer_id)&lt;br /&gt;
    assignment = Assignment.find(Participant.find(reviewer_id).parent_id)&lt;br /&gt;
    review_final_versions = Hash.new&lt;br /&gt;
    if !assignment.varying_rubrics_by_round?&lt;br /&gt;
      #same review rubric used in multiple rounds&lt;br /&gt;
      review_final_versions[:review] = Hash.new&lt;br /&gt;
      review_final_versions[:review][:questionnaire_id] = assignment.get_review_questionnaire_id&lt;br /&gt;
      response_ids = Array.new&lt;br /&gt;
      maps.each do |map|&lt;br /&gt;
        responses = Response.where(map_id:map.id)&lt;br /&gt;
        if !responses.empty?&lt;br /&gt;
          response_ids &amp;lt;&amp;lt; responses.last.id&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
      review_final_versions[:review][:response_ids] = response_ids&lt;br /&gt;
    else&lt;br /&gt;
      #vary rubric by round&lt;br /&gt;
      rounds_num = assignment.rounds_of_reviews&lt;br /&gt;
      for round in 1..rounds_num&lt;br /&gt;
        symbol = (&amp;quot;review round&amp;quot;+round.to_s).to_sym&lt;br /&gt;
        review_final_versions[symbol] = Hash.new&lt;br /&gt;
        review_final_versions[symbol][:questionnaire_id] = assignment.get_review_questionnaire_id(round)&lt;br /&gt;
        response_ids = Array.new&lt;br /&gt;
        maps.each do |map|&lt;br /&gt;
          responses = Response.where(map_id:map.id, round:round)&lt;br /&gt;
          if !responses.empty?&lt;br /&gt;
            response_ids &amp;lt;&amp;lt; responses.last.id&lt;br /&gt;
          end&lt;br /&gt;
        end&lt;br /&gt;
        review_final_versions[symbol][:response_ids] = response_ids&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
    review_final_versions&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
&lt;br /&gt;
After refactoring:&lt;br /&gt;
&amp;lt;big&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  def self.final_versions_from_reviewer(reviewer_id)&lt;br /&gt;
    maps = ReviewResponseMap.where(reviewer_id: reviewer_id)&lt;br /&gt;
    assignment = find_assignment(Participant.find(reviewer_id).parent_id)&lt;br /&gt;
    review_final_versions = {}&lt;br /&gt;
    unless assignment.varying_rubrics_by_round?&lt;br /&gt;
      #same review rubric used in multiple rounds&lt;br /&gt;
      review_final_versions = review_final_version_responses(:review, :questionnaire_id, assignment, maps)&lt;br /&gt;
    else&lt;br /&gt;
      # vary rubric by round&lt;br /&gt;
      rounds_num = assignment.rounds_of_reviews&lt;br /&gt;
      (1..rounds_num).each do |round|&lt;br /&gt;
        symbol = ('review round' + round.to_s).to_sym&lt;br /&gt;
        review_final_versions = review_final_version_responses(symbol, :questionnaire_id, assignment, maps, round)&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
    review_final_versions&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Private methods added:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;big&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  # Compute list of responses and return it&lt;br /&gt;
  def self.review_final_version_responses(symbol, questionnaire_id, assignment, maps, round = nil)&lt;br /&gt;
    review_final_versions = {}&lt;br /&gt;
    review_final_versions[symbol] = {}&lt;br /&gt;
    review_final_versions[symbol][questionnaire_id] = assignment.get_review_questionnaire_id(round)&lt;br /&gt;
    response_ids = []&lt;br /&gt;
    maps.each do |map|&lt;br /&gt;
      responses =  get_responses(map.id, round)&lt;br /&gt;
      unless responses.empty?&lt;br /&gt;
        response_ids &amp;lt;&amp;lt; responses.last.id&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
    review_final_versions[symbol][:response_ids] = response_ids&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;big&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  #Get responses by map_id and round (if exists)&lt;br /&gt;
  def self.get_responses(id, round)&lt;br /&gt;
     if round.nil?&lt;br /&gt;
       responses = Response.where(map_id: id)&lt;br /&gt;
     else&lt;br /&gt;
       responses = Response.where(map_id: id, round: round)&lt;br /&gt;
     end	&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Refactoring of other methods ===&lt;br /&gt;
Although trivial, we removed the return statement from the get_title, export_fields, and show_feedback methods because return statements are unnecessary in Ruby.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Addition of code comments ===&lt;br /&gt;
&lt;br /&gt;
We added comments to all of the methods in the ReviewResponseMap.rb file and corrected instances where CodeClimate Identified opportunities for code improvement.  One issue flagged by CodeClimate that we did not change was to use the find_by method instead of where().first method.  The where().first method occurs in the import, get_assignment_participant, and create_response_map methods. It is not always appropriate to use the find_by method, as documented in this github post: https://github.com/bbatsov/rubocop/issues/1938 .  In instances where ordering by id is the desired behavior, where().first will order by default, but in Rails 4+ find_by does not honor that default behavior.  For this reason we left the instances of where().first unchanged.&lt;br /&gt;
&lt;br /&gt;
=== Code Improvements ===&lt;br /&gt;
&lt;br /&gt;
This refactoring was to improve readability and follow as many good ''Rubyist'' coding practices as possible without breaking the functionality of existing code. We used CodeClimate of the master branch code as a reference. We took the suggestions we got from CodeClimate and improved our code based on that.&lt;br /&gt;
We also made some of the methods shorter by removing redundant functionality and adding private methods to methods with a lot internal functionality. We also added private methods in places where we saw repeated patterns to make the code ''DRYer''.&lt;br /&gt;
At the end of our refactoring, we managed to improve the rating on CodeClimate from a '''C''' to a '''B''' . Further improvements meant reducing the size of the entire class which required a much more significant refactoring in multiple files and folders. We focused on refactoring the existing model, '''ReviewResponseMap'''.&lt;br /&gt;
&lt;br /&gt;
= Unit Tests =&lt;br /&gt;
The previous unit tests had syntactical and run time errors.  We were not able to get the previous unit tests to run without errors.  Because of this we rewrote all of the unit tests for the &amp;lt;b&amp;gt;ReviewResponseModel&amp;lt;/b&amp;gt;.  It is important to have working unit tests so that when internal changes are made to functions the external output remains the same.&lt;br /&gt;
&lt;br /&gt;
=== Refactoring of Unit Tests===&lt;br /&gt;
&lt;br /&gt;
We added a test_helper file to the main test folder that requires a needed configuration file and needed gems.  We also added 8 fixtures that were needed for data to run the unit tests.  The following fixture files were added:&lt;br /&gt;
&lt;br /&gt;
* assignment_questionnaires.yml&lt;br /&gt;
* assignments.yml&lt;br /&gt;
* participants.yml&lt;br /&gt;
* questionnaires.yml&lt;br /&gt;
* response_maps.yml&lt;br /&gt;
* responses.yml&lt;br /&gt;
* teams.yml&lt;br /&gt;
* users.yml&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
There is at least one unit test for every public method within the &amp;lt;b&amp;gt;ReviewResponseModel&amp;lt;/b&amp;gt;.  The test naming convention used is &amp;quot;method_&amp;lt;name of method that is being tested&amp;gt;&amp;quot;.  For example, the unit test for the export method is &amp;quot;method_export&amp;quot;.  If there are multiple test for one method the name of the test will include the test case after the normal naming convention.  For example, one of the unit tests for the import method checks for an invalid assignment.  The name of this method is &amp;quot;method_import_invalid_assignment&amp;quot;.  The following are the unit tests we created:&lt;br /&gt;
&lt;br /&gt;
* method_export&lt;br /&gt;
* method_get_metareview_response_maps&lt;br /&gt;
* method_get_team_response_for_round&lt;br /&gt;
* method_final_versions_from_reviewer&lt;br /&gt;
* method_import&lt;br /&gt;
* method_import_invalid_reviewee&lt;br /&gt;
* method_import_invalid_reviewer&lt;br /&gt;
* method_import_invalid_assignment&lt;br /&gt;
* method_delete&lt;br /&gt;
* method_delete_no _force&lt;br /&gt;
* method_show_feedback&lt;br /&gt;
* method_get_title&lt;br /&gt;
* method_export_fields&lt;br /&gt;
* method_questionnaire&lt;br /&gt;
* method_add_reviewer&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== How to Run Unit Tests ===&lt;br /&gt;
To run the unit tests, follow these steps:&lt;br /&gt;
&lt;br /&gt;
# Download the master branch of the repo.&lt;br /&gt;
# Setup the Databases for the test environment (we have used Zhewei's scrubbed expertiza DB )&lt;br /&gt;
#* Run the &amp;quot; rake db:create RAILS_ENV=test &amp;quot; command&lt;br /&gt;
#* Run the &amp;quot; rake db:reset RAILS_ENV=test &amp;quot; command&lt;br /&gt;
#* Scrub the DB using &amp;quot; mysql -u root expertiza_development &amp;lt; expertiza-scrubbed.sql&amp;quot;&lt;br /&gt;
#* Run the &amp;quot; rake db:migrate &amp;quot;&lt;br /&gt;
# Run &amp;quot; rake test test/unit/review_response_map_test.rb &amp;quot; in the &amp;quot;expertiza/&amp;quot; directory.&lt;br /&gt;
#* If you run into a mysql log in error go into config/database.yml and edit the mysql credentials for the test section so that it matches the local environment's mysql configuration&lt;br /&gt;
# Check if tests passed or failed.&lt;br /&gt;
&lt;br /&gt;
= Manual Test Case =&lt;br /&gt;
&lt;br /&gt;
In order to test the changes made to the ReviewResponseMap, bring up [[ http://152.46.16.195:5902/ | Expertiza]] and log in as an administrator.  Once logged in, proceed with the following steps:&lt;br /&gt;
&lt;br /&gt;
# Go to '''impersonate user''' when logged in as ''instructor6'' and type in ''student559'' (or) just log in as ''student559''. All passwords are ''password'' .&lt;br /&gt;
# Pick any assignment to view.&lt;br /&gt;
# Navigate to '''Other's work'''.&lt;br /&gt;
# Check the different reviews and metareviews. Whether they are being displayed correctly or not.&lt;br /&gt;
# Go to Edit or Give feedback and submit a feedback.&lt;br /&gt;
# Go back and check if the feedback given is displayed correctly or not.&lt;br /&gt;
# Check if author's feedback is correct or not.&lt;br /&gt;
# Go to the '''Temp''' assignment and see if the page is being displayed correctly or not (since there is no assignment submission content or reviews for that).&lt;br /&gt;
&lt;br /&gt;
''NOTE: Since this was a refactoring of the code and methods, the existing functionality was supposed to remain the same and not break for the changes we've made.''&lt;br /&gt;
&lt;br /&gt;
= References =&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;references/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;4.&amp;amp;nbsp; [https://github.com/expertiza/expertiza Expertiza Main Repo] &amp;lt;br&amp;gt;&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;5.&amp;amp;nbsp; [https://github.com/adeeshag/expertiza/blob/develop/app/models/review_response_map.rb Refactored ReviewResponseMap.rb]&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;6.&amp;amp;nbsp; [https://github.com/adeeshag/expertiza/tree/develop/test/fixtures Test Fixtures]&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;7.&amp;amp;nbsp; [https://github.com/adeeshag/expertiza/blob/develop/test/unit/review_response_map_test.rb Unit Tests]&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;8.&amp;amp;nbsp; [http://152.46.16.195:5902/ Expertiza Deployed Site]&amp;lt;br&amp;gt;&lt;/div&gt;</summary>
		<author><name>Cnbrown4</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2015/ossE1558BGJ&amp;diff=98463</id>
		<title>CSC/ECE 517 Fall 2015/ossE1558BGJ</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2015/ossE1558BGJ&amp;diff=98463"/>
		<updated>2015-11-06T21:38:33Z</updated>

		<summary type="html">&lt;p&gt;Cnbrown4: /* Refactoring of final_versions_from_reviewer method */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Introduction =&lt;br /&gt;
&lt;br /&gt;
This page provides a description of the modifications and improvements made to the Expertiza project’s source code as part of an Expertiza based Open Source Software project.  Expertiza is a web based application which allows students to submit and peer-review classmates’ work, including written articles and development projects. The specific changes made during the course of this project were to the ReviewResponseMap.rb file, with additional changes made to other related files in support of refactoring ReviewResponseMap.rb.  &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
= Problem Statement =&lt;br /&gt;
&lt;br /&gt;
ReviewResponseMap is the model class used to manage the relationship between contributors, reviewers, and assignments.  The intent of the changes were to refactor the code for better readability and adherence to Ruby coding standards and best practices.  Primarily these changes involved the refactoring of overly complex methods, renaming methods for better readability, and the addition of missing unit tests.&lt;br /&gt;
&lt;br /&gt;
Project Requirements:&lt;br /&gt;
&lt;br /&gt;
# Code Climate&amp;lt;ref name=&amp;quot;Code Climate&amp;quot;&amp;gt;https://codeclimate.com&amp;lt;/ref&amp;gt; shows import method is complex, because of lots of checks. This method can be fixed by adding private methods for raising import error.&lt;br /&gt;
# Get_assessments_round_for method can be renamed to get_team_responses_for_round. Team_id private variable is not needed.&lt;br /&gt;
# metareview_response_maps rename, refactoring can be done. No need to do second iteration.&lt;br /&gt;
# write missing unit tests for existing methods.&lt;br /&gt;
&lt;br /&gt;
= Design Patterns =&lt;br /&gt;
&lt;br /&gt;
As part of our project, we refactored the model to follow the Single Responsibility and Don't Repeat Yourself (DRY) Principles.  Both of the principles focus on reducing code repetition and increasing the cohesion of the individual methods in the class.  The Single Responsibility Principle states that each class and method should have sole responsibility over one single part of the functionality of the system&amp;lt;ref&amp;gt;https://en.wikipedia.org/wiki/Single_responsibility_principle&amp;lt;/ref&amp;gt;.  The DRY principle states that whenever the same types of logic and functionality are being performed in a class the duplicated logic should be extracted into a new method that can be called in place of the repeated lines of code &amp;lt;ref&amp;gt;https://en.wikipedia.org/wiki/Don%27t_repeat_yourself&amp;lt;/ref&amp;gt;.  A prime example of a method that initially violated these principles was the import method, which in addition to performing the core import processes also performed a number of checks that would be more properly extracted into private methods.&lt;br /&gt;
&lt;br /&gt;
=Code Changes =&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Refactoring of import method ===&lt;br /&gt;
&lt;br /&gt;
CodeClimate reports showed the import method to be overly complex, with a number of checks being included within the import method itself.  The resolution for this problem was to refactor the import method, creating private methods to perform the null checks and throw import errors.  Prior to refactoring, all null checks were performed within the import method.   After refactoring, the import method adheres to the single responsibility principle, performing only key import tasks while making calls to private methods for any necessary validation. The size of the import method was reduced by doing this and counts for better readability of the code. Also, this method is a very important one and care was taken so that any existing functionality did not break. &lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
Before refactoring:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;big&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 def self.import(row, session, id)&lt;br /&gt;
    if row.length &amp;lt; 2&lt;br /&gt;
      raise ArgumentError, &amp;quot;Not enough items&amp;quot;&lt;br /&gt;
    end&lt;br /&gt;
    assignment = Assignment.find(id)&lt;br /&gt;
    if assignment.nil?&lt;br /&gt;
      raise ImportError, &amp;quot;The assignment with id \&amp;quot;#{id}\&amp;quot; was not found. &amp;lt;a href='/assignment/new'&amp;gt;Create&amp;lt;/a&amp;gt; this assignment?&amp;quot;&lt;br /&gt;
    end&lt;br /&gt;
    index = 1&lt;br /&gt;
    while index &amp;lt; row.length&lt;br /&gt;
      user = User.find_by_name(row[index].to_s.strip)&lt;br /&gt;
      if user.nil?&lt;br /&gt;
        raise ImportError, &amp;quot;The user account for the reviewer \&amp;quot;#{row[index]}\&amp;quot; was not found. &amp;lt;a href='/users/new'&amp;gt;Create&amp;lt;/a&amp;gt; this user?&amp;quot;&lt;br /&gt;
      end&lt;br /&gt;
      reviewer = AssignmentParticipant.where(user_id: user.id, parent_id:  assignment.id).first&lt;br /&gt;
      if reviewer == nil&lt;br /&gt;
        raise ImportError, &amp;quot;The reviewer \&amp;quot;#{row[index]}\&amp;quot; is not a participant in this assignment. &amp;lt;a href='/users/new'&amp;gt;Register&amp;lt;/a&amp;gt; this user as a participant?&amp;quot;&lt;br /&gt;
      end&lt;br /&gt;
      if assignment.team_assignment&lt;br /&gt;
        reviewee = AssignmentTeam.where(name: row[0].to_s.strip, parent_id:  assignment.id).first&lt;br /&gt;
        if reviewee == nil&lt;br /&gt;
          raise ImportError, &amp;quot;The author \&amp;quot;#{row[0].to_s.strip}\&amp;quot; was not found. &amp;lt;a href='/users/new'&amp;gt;Create&amp;lt;/a&amp;gt; this user?&amp;quot;&lt;br /&gt;
        end&lt;br /&gt;
        existing = ReviewResponseMap.where(reviewee_id: reviewee.id, reviewer_id:  reviewer.id).first&lt;br /&gt;
        if existing.nil?&lt;br /&gt;
          ReviewResponseMap.create(:reviewer_id =&amp;gt; reviewer.id, :reviewee_id =&amp;gt; reviewee.id, :reviewed_object_id =&amp;gt; assignment.id)&lt;br /&gt;
        end&lt;br /&gt;
      else&lt;br /&gt;
        puser = User.find_by_name(row[0].to_s.strip)&lt;br /&gt;
        if user == nil&lt;br /&gt;
          raise ImportError, &amp;quot;The user account for the reviewee \&amp;quot;#{row[0]}\&amp;quot; was not found. &amp;lt;a href='/users/new'&amp;gt;Create&amp;lt;/a&amp;gt; this user?&amp;quot;&lt;br /&gt;
        end&lt;br /&gt;
        reviewee = AssignmentParticipant.where(user_id: puser.id, parent_id:  assignment.id).first&lt;br /&gt;
        if reviewee == nil&lt;br /&gt;
          raise ImportError, &amp;quot;The author \&amp;quot;#{row[0].to_s.strip}\&amp;quot; was not found. &amp;lt;a href='/users/new'&amp;gt;Create&amp;lt;/a&amp;gt; this user?&amp;quot;&lt;br /&gt;
        end&lt;br /&gt;
        team_id = TeamsUser.team_id(reviewee.parent_id, reviewee.user_id)&lt;br /&gt;
        existing = ReviewResponseMap.where(reviewee_id: team_id, reviewer_id:  reviewer.id).first&lt;br /&gt;
        if existing.nil?&lt;br /&gt;
          ReviewResponseMap.create(:reviewee_id =&amp;gt; team_id, :reviewer_id =&amp;gt; reviewer.id, :reviewed_object_id =&amp;gt; assignment.id)&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
      index += 1&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
&lt;br /&gt;
After refactoring:&lt;br /&gt;
 &lt;br /&gt;
  &amp;lt;big&amp;gt;&amp;lt;nowiki&amp;gt;#Imports new reponse maps if they do not already exist&lt;br /&gt;
  def self.import(row, _session, id)&lt;br /&gt;
      if row.length &amp;lt; 2&lt;br /&gt;
          raise ArgumentError, 'Not enough items'&lt;br /&gt;
      end&lt;br /&gt;
      assignment = find_assignment(id)&lt;br /&gt;
      index = 1&lt;br /&gt;
      reviewee_name = row[0]&lt;br /&gt;
      while index &amp;lt; row.length&lt;br /&gt;
          reviewee_id = nil&lt;br /&gt;
          reviewer_name = row[index]&lt;br /&gt;
          reviewer = get_assignment_participant(reviewer_name,  assignment.id, &amp;quot;reviewer&amp;quot;)&lt;br /&gt;
          participant_nil?(reviewer, reviewer_name , &amp;quot;reviewer&amp;quot;)&lt;br /&gt;
         &lt;br /&gt;
         #Find reviewee if assignment is a team assignment&lt;br /&gt;
         if assignment.team_assignment&lt;br /&gt;
             reviewee = AssignmentTeam.where(name: reviewee_name .to_s.strip, parent_id: assignment.id).first&lt;br /&gt;
             participant_nil?(reviewee, reviewee_name, &amp;quot;author&amp;quot;)&lt;br /&gt;
             reviewee_id = reviewee.id&lt;br /&gt;
         #Find reviewee if assignment is not a team assignment&lt;br /&gt;
         else&lt;br /&gt;
	     reviewee = get_assignment_participant(reviewee_name, assignment.id, &amp;quot;reviewee&amp;quot;)&lt;br /&gt;
             participant_nil?(reviewee, reviewee_name, &amp;quot;author&amp;quot;)&lt;br /&gt;
             reviewee_id  = TeamsUser.team_id(reviewee.parent_id, reviewee.user_id)&lt;br /&gt;
         end&lt;br /&gt;
         create_response_map(reviewer, reviewee_id,  assignment)&lt;br /&gt;
         index += 1&lt;br /&gt;
      end&lt;br /&gt;
  end&amp;lt;/nowiki&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Private methods added:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;big&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  # Check for if assignment value is null&lt;br /&gt;
  def self.find_assignment(id)&lt;br /&gt;
      begin&lt;br /&gt;
          assignment = Assignment.find(id)&lt;br /&gt;
      rescue ActiveRecord::RecordNotFound&lt;br /&gt;
          raise ImportError, &amp;quot;The assignment with id \&amp;quot;#{id}\&amp;quot; was not found.&amp;lt;a href='/assignment/new'&amp;gt;Create&amp;lt;/a&amp;gt; this assignment?&amp;quot;&lt;br /&gt;
      end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  # Check for if participant is null&lt;br /&gt;
  def self.participant_nil?(participant, user_name, participant_type) &lt;br /&gt;
      error_message = nil&lt;br /&gt;
      if participant_type == &amp;quot;author&amp;quot;&lt;br /&gt;
          error_message = &amp;quot;The author \&amp;quot;#{user_name.to_s.strip}\&amp;quot; was not found.&amp;lt;a href='/users/new'&amp;gt;Create&amp;lt;/a&amp;gt; this user?&amp;quot;&lt;br /&gt;
      else&lt;br /&gt;
          error_message =  &amp;quot;The reviewer \&amp;quot;#{user_name}\&amp;quot; is not a participant in this assignment.&amp;lt;a href='/users/new'&amp;gt;Register&amp;lt;/a&amp;gt; this user as a participant?&amp;quot;&lt;br /&gt;
      end&lt;br /&gt;
      check_nil?(participant, error_message)&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  # Check for if user is null&lt;br /&gt;
  def self.user_nil?(user, user_name, user_type)&lt;br /&gt;
      check_nil?( user, &amp;quot;The user account for the \&amp;quot;#{user_type}\&amp;quot; \&amp;quot;#{user_name}\&amp;quot; was not found.&amp;lt;a href='/users/new'&amp;gt;Create&amp;lt;/a&amp;gt; this user?&amp;quot;)&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
 #Throws import error for nil objects&lt;br /&gt;
  def self.check_nil?(object, error_message)&lt;br /&gt;
      if object.nil?&lt;br /&gt;
          raise ImportError, error_message&lt;br /&gt;
      end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Refactoring of get_assessments_round_for method ===&lt;br /&gt;
&lt;br /&gt;
The get_assessments_round_for method’s name failed to provide a clear idea of the method’s purpose and functionality.  This is why it was renamed to get_team_responses_for_round, the new name of the method provides a clearer idea of its purpose. Additionally, there was a private variable, team_id, introduced in the method that was unnecessary and could be replaced by using the id property of the team parameter directly.  We also removed the return statement at the end of the method.  &lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
Before refactoring:&lt;br /&gt;
&amp;lt;big&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  def self.get_assessments_round_for(team,round)&lt;br /&gt;
    team_id =team.id&lt;br /&gt;
    responses = Array.new&lt;br /&gt;
    if team_id&lt;br /&gt;
      maps = ResponseMap.where(:reviewee_id =&amp;gt; team_id, :type =&amp;gt; &amp;quot;ReviewResponseMap&amp;quot;)&lt;br /&gt;
      maps.each{ |map|&lt;br /&gt;
        if !map.response.empty? &amp;amp;&amp;amp; !map.response.reject{|r| r.round!=round}.empty?&lt;br /&gt;
          responses &amp;lt;&amp;lt; map.response.reject{|r| r.round!=round}.last&lt;br /&gt;
        end&lt;br /&gt;
      }&lt;br /&gt;
      responses.sort! {|a,b| a.map.reviewer.fullname &amp;lt;=&amp;gt; b.map.reviewer.fullname }&lt;br /&gt;
    end&lt;br /&gt;
    return responses&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
&lt;br /&gt;
After refactoring: &lt;br /&gt;
&lt;br /&gt;
&amp;lt;big&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  def self.get_team_responses_for_round(team, round)&lt;br /&gt;
    responses = []&lt;br /&gt;
    if team.id&lt;br /&gt;
      maps = ResponseMap.where(reviewee_id: team.id, type: 'ReviewResponseMap')&lt;br /&gt;
      maps.each do |map|&lt;br /&gt;
        unless map.response.empty? &amp;amp;&amp;amp; map.response.reject { |r| r.round != round }.empty?&lt;br /&gt;
          responses &amp;lt;&amp;lt; map.response.reject { |r| r.round != round }.last&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
      responses.sort! { |a, b| a.map.reviewer.fullname &amp;lt;=&amp;gt; b.map.reviewer.fullname }&lt;br /&gt;
    end&lt;br /&gt;
    responses&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
The change in method name also required changes to the following files that referenced it:&lt;br /&gt;
&lt;br /&gt;
/app/models/assignment.rb:436:    &lt;br /&gt;
 &lt;br /&gt;
&amp;lt;big&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  assessments = ReviewResponseMap.get_assessments_round_for(team,i)&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt; &lt;br /&gt;
&lt;br /&gt;
./app/models/assignment_participant.rb:268:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;big&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 scores[questionnaire_symbol][:assessments] = questionnaire.get_assessments_round_for(self,round)&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Refactoring of metareview_response_maps method ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The metareview_response_maps method was unnecessarily complex.  It contained an unneeded private variable and an unnecessary nested loop.  Originally, it added each metareview map individually in the nested loop.  We decided to remove the nested loop and use the concat method for readability and maintainability.  These changes allowed us to remove the private variable &amp;quot;metareview_list&amp;quot; and only maintain the &amp;quot;metareview_response_maps&amp;quot; variable.  We also renamed the metareview_response_maps method to get_metareview_response_maps method to be more descriptive about the intent of the method. &lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
Before refactoring:&lt;br /&gt;
&amp;lt;big&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 def metareview_response_maps&lt;br /&gt;
    responses = Response.where(map_id:self.id)&lt;br /&gt;
    metareview_list=[]&lt;br /&gt;
    responses.each do |response|&lt;br /&gt;
      metareview_response_maps = MetareviewResponseMap.where(reviewed_object_id:response.id)&lt;br /&gt;
      metareview_response_maps.each do |metareview_response_map|&lt;br /&gt;
        metareview_list&amp;lt;&amp;lt;metareview_response_map&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
    metareview_list&lt;br /&gt;
 end&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
After refactoring:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;big&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  def get_metareview_response_maps&lt;br /&gt;
    responses = Response.where(map_id: id)&lt;br /&gt;
    metareview_response_maps = []&lt;br /&gt;
    responses.each do |response|&lt;br /&gt;
      metareview_response_maps.concat MetareviewResponseMap.where(reviewed_object_id: response.id)&lt;br /&gt;
    end&lt;br /&gt;
    metareview_response_maps&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Refactoring of export method ===&lt;br /&gt;
The export method contained mappings.sort! { |a, b| a.reviewee.name &amp;lt;=&amp;gt; b.reviewee.name }.  We could not get past this when running tests, we kept getting a message saying that sort! was not a method for an ActiveRecord_Relation.  So we &lt;br /&gt;
&lt;br /&gt;
Before refactoring:&lt;br /&gt;
&amp;lt;big&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  def self.export(csv, parent_id, options)&lt;br /&gt;
    mappings = where(reviewed_object_id: parent_id)&lt;br /&gt;
    mappings.sort! { |a, b| a.reviewee.name &amp;lt;=&amp;gt; b.reviewee.name }&lt;br /&gt;
    mappings.each {&lt;br /&gt;
      |map|&lt;br /&gt;
      csv &amp;lt;&amp;lt; [&lt;br /&gt;
        map.reviewee.name,&lt;br /&gt;
        map.reviewer.name&lt;br /&gt;
      ]&lt;br /&gt;
    }&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
&lt;br /&gt;
After refactoring:&lt;br /&gt;
&amp;lt;big&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  def self.export(csv, parent_id, options)&lt;br /&gt;
    mappings = where(reviewed_object_id: parent_id)&lt;br /&gt;
    mappings = mappings.sort { |a, b| a.reviewee.name &amp;lt;=&amp;gt; b.reviewee.name }&lt;br /&gt;
    mappings.each do&lt;br /&gt;
    |map|&lt;br /&gt;
      csv &amp;lt;&amp;lt; [map.reviewee.name, map.reviewer.name]&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
=== Refactoring of final_versions_from_reviewer method ===&lt;br /&gt;
The final_versions_from_reviewer method was too long and repetitive.  We removed common functionality from within the if and else statement and put it in a private method final_versions_from_reviewer.  Then we created the get_responses method to find the responses based on the arguments values.  These private methods make the class more readable for other programmers.&lt;br /&gt;
 &lt;br /&gt;
Before refactoring:&lt;br /&gt;
&amp;lt;big&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  def self.final_versions_from_reviewer(reviewer_id)&lt;br /&gt;
    maps = ReviewResponseMap.where(reviewer_id: reviewer_id)&lt;br /&gt;
    assignment = Assignment.find(Participant.find(reviewer_id).parent_id)&lt;br /&gt;
    review_final_versions = Hash.new&lt;br /&gt;
    if !assignment.varying_rubrics_by_round?&lt;br /&gt;
      #same review rubric used in multiple rounds&lt;br /&gt;
      review_final_versions[:review] = Hash.new&lt;br /&gt;
      review_final_versions[:review][:questionnaire_id] = assignment.get_review_questionnaire_id&lt;br /&gt;
      response_ids = Array.new&lt;br /&gt;
      maps.each do |map|&lt;br /&gt;
        responses = Response.where(map_id:map.id)&lt;br /&gt;
        if !responses.empty?&lt;br /&gt;
          response_ids &amp;lt;&amp;lt; responses.last.id&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
      review_final_versions[:review][:response_ids] = response_ids&lt;br /&gt;
    else&lt;br /&gt;
      #vary rubric by round&lt;br /&gt;
      rounds_num = assignment.rounds_of_reviews&lt;br /&gt;
      for round in 1..rounds_num&lt;br /&gt;
        symbol = (&amp;quot;review round&amp;quot;+round.to_s).to_sym&lt;br /&gt;
        review_final_versions[symbol] = Hash.new&lt;br /&gt;
        review_final_versions[symbol][:questionnaire_id] = assignment.get_review_questionnaire_id(round)&lt;br /&gt;
        response_ids = Array.new&lt;br /&gt;
        maps.each do |map|&lt;br /&gt;
          responses = Response.where(map_id:map.id, round:round)&lt;br /&gt;
          if !responses.empty?&lt;br /&gt;
            response_ids &amp;lt;&amp;lt; responses.last.id&lt;br /&gt;
          end&lt;br /&gt;
        end&lt;br /&gt;
        review_final_versions[symbol][:response_ids] = response_ids&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
    review_final_versions&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
&lt;br /&gt;
After refactoring:&lt;br /&gt;
&amp;lt;big&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  def self.final_versions_from_reviewer(reviewer_id)&lt;br /&gt;
    maps = ReviewResponseMap.where(reviewer_id: reviewer_id)&lt;br /&gt;
    assignment = find_assignment(Participant.find(reviewer_id).parent_id)&lt;br /&gt;
    review_final_versions = {}&lt;br /&gt;
    unless assignment.varying_rubrics_by_round?&lt;br /&gt;
      #same review rubric used in multiple rounds&lt;br /&gt;
      review_final_versions = review_final_version_responses(:review, :questionnaire_id, assignment, maps)&lt;br /&gt;
    else&lt;br /&gt;
      # vary rubric by round&lt;br /&gt;
      rounds_num = assignment.rounds_of_reviews&lt;br /&gt;
      (1..rounds_num).each do |round|&lt;br /&gt;
        symbol = ('review round' + round.to_s).to_sym&lt;br /&gt;
        review_final_versions = review_final_version_responses(symbol, :questionnaire_id, assignment, maps, round)&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
    review_final_versions&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Private methods added:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;big&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  # Compute list of responses and return it&lt;br /&gt;
  def self.review_final_version_responses(symbol, questionnaire_id, assignment, maps, round = nil)&lt;br /&gt;
    review_final_versions = {}&lt;br /&gt;
    review_final_versions[symbol] = {}&lt;br /&gt;
    review_final_versions[symbol][questionnaire_id] = assignment.get_review_questionnaire_id(round)&lt;br /&gt;
    response_ids = []&lt;br /&gt;
    maps.each do |map|&lt;br /&gt;
      responses =  get_responses(map.id, round)&lt;br /&gt;
      unless responses.empty?&lt;br /&gt;
        response_ids &amp;lt;&amp;lt; responses.last.id&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
    review_final_versions[symbol][:response_ids] = response_ids&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;big&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  #Get responses by map_id and round (if exists)&lt;br /&gt;
  def self.get_responses(id, round)&lt;br /&gt;
     if round.nil?&lt;br /&gt;
       responses = Response.where(map_id: id)&lt;br /&gt;
     else&lt;br /&gt;
       responses = Response.where(map_id: id, round: round)&lt;br /&gt;
     end	&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Refactoring of other methods ===&lt;br /&gt;
Although trivial, we removed the return statement from the get_title, export_fields, and show_feedback methods because return statements are unnecessary in Ruby.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Addition of code comments ===&lt;br /&gt;
&lt;br /&gt;
We added comments to all of the methods in the ReviewResponseMap.rb file and corrected instances where CodeClimate Identified opportunities for code improvement.  One issue flagged by CodeClimate that we did not change was to use the find_by method instead of where().first method.  The where().first method occurs in the import, get_assignment_participant, and create_response_map methods. It is not always appropriate to use the find_by method, as documented in this github post: https://github.com/bbatsov/rubocop/issues/1938 .  In instances where ordering by id is the desired behavior, where().first will order by default, but in Rails 4+ find_by does not honor that default behavior.  For this reason we left the instances of where().first unchanged.&lt;br /&gt;
&lt;br /&gt;
=== Code Improvements ===&lt;br /&gt;
&lt;br /&gt;
This refactoring was to improve readability and follow as many good ''Rubyist'' coding practices as possible without breaking the functionality of existing code. We used CodeClimate of the master branch code as a reference. We took the suggestions we got from CodeClimate and improved our code based on that.&lt;br /&gt;
We also made some of the methods shorter by removing redundant functionality and adding private methods to methods with a lot internal functionality. We also added private methods in places where we saw repeated patterns to make the code ''DRYer''.&lt;br /&gt;
At the end of our refactoring, we managed to improve the rating on CodeClimate from a '''C''' to a '''B''' . Further improvements meant reducing the size of the entire class which required a much more significant refactoring in multiple files and folders. We focused on refactoring the existing model, '''ReviewResponseMap'''.&lt;br /&gt;
&lt;br /&gt;
= Unit Tests =&lt;br /&gt;
The previous unit tests had syntactical and run time errors.  We were not able to get the previous unit tests to run without errors.  Because of this we rewrote all of the unit tests for the &amp;lt;b&amp;gt;ReviewResponseModel&amp;lt;/b&amp;gt;.  It is important to have working unit tests so that when internal changes are made to functions the external output remains the same.&lt;br /&gt;
&lt;br /&gt;
=== Refactoring of Unit Tests===&lt;br /&gt;
&lt;br /&gt;
We added a test_helper file to the main test folder that requires a needed configuration file and needed gems.  We also added 8 fixtures that were needed for data to run the unit tests.  The following fixture files were added:&lt;br /&gt;
&lt;br /&gt;
* assignment_questionnaires.yml&lt;br /&gt;
* assignments.yml&lt;br /&gt;
* participants.yml&lt;br /&gt;
* questionnaires.yml&lt;br /&gt;
* response_maps.yml&lt;br /&gt;
* responses.yml&lt;br /&gt;
* teams.yml&lt;br /&gt;
* users.yml&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
There is at least one unit test for every public method within the &amp;lt;b&amp;gt;ReviewResponseModel&amp;lt;/b&amp;gt;.  The test naming convention used is &amp;quot;method_&amp;lt;name of method that is being tested&amp;gt;&amp;quot;.  For example, the unit test for the export method is &amp;quot;method_export&amp;quot;.  If there are multiple test for one method the name of the test will include the test case after the normal naming convention.  For example, one of the unit tests for the import method checks for an invalid assignment.  The name of this method is &amp;quot;method_import_invalid_assignment&amp;quot;.  The following are the unit tests we created:&lt;br /&gt;
&lt;br /&gt;
* method_export&lt;br /&gt;
* method_get_metareview_response_maps&lt;br /&gt;
* method_get_team_response_for_round&lt;br /&gt;
* method_final_versions_from_reviewer&lt;br /&gt;
* method_import&lt;br /&gt;
* method_import_invalid_reviewee&lt;br /&gt;
* method_import_invalid_reviewer&lt;br /&gt;
* method_import_invalid_assignment&lt;br /&gt;
* method_delete&lt;br /&gt;
* method_delete_no _force&lt;br /&gt;
* method_show_feedback&lt;br /&gt;
* method_get_title&lt;br /&gt;
* method_export_fields&lt;br /&gt;
* method_questionnaire&lt;br /&gt;
* method_add_reviewer&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== How to Run Unit Tests ===&lt;br /&gt;
To run the unit tests, follow these steps:&lt;br /&gt;
&lt;br /&gt;
# Download the master branch of the repo.&lt;br /&gt;
# Setup the Databases for the test environment (we have used Zhewei's scrubbed expertiza DB )&lt;br /&gt;
#* Run the &amp;quot; rake db:create RAILS_ENV=test &amp;quot; command&lt;br /&gt;
#* Run the &amp;quot; rake db:reset RAILS_ENV=test &amp;quot; command&lt;br /&gt;
#* Scrub the DB using &amp;quot; mysql -u root expertiza_development &amp;lt; expertiza-scrubbed.sql&amp;quot;&lt;br /&gt;
#* Run the &amp;quot; rake db:migrate &amp;quot;&lt;br /&gt;
# Run &amp;quot; rake test test/unit/review_response_map_test.rb &amp;quot; in the &amp;quot;expertiza/&amp;quot; directory.&lt;br /&gt;
#* If you run into a mysql log in error go into config/database.yml and edit the mysql credentials for the test section so that it matches the local environment's mysql configuration&lt;br /&gt;
# Check if tests passed or failed.&lt;br /&gt;
&lt;br /&gt;
= Manual Test Case =&lt;br /&gt;
&lt;br /&gt;
In order to test the changes made to the ReviewResponseMap, bring up [[ http://152.46.16.195:5902/ | Expertiza]] and log in as an administrator.  Once logged in, proceed with the following steps:&lt;br /&gt;
&lt;br /&gt;
# Go to '''impersonate user''' when logged in as ''instructor6'' and type in ''student559'' (or) just log in as ''student559''. All passwords are ''password'' .&lt;br /&gt;
# Pick any assignment to view.&lt;br /&gt;
# Navigate to '''Other's work'''.&lt;br /&gt;
# Check the different reviews and metareviews. Whether they are being displayed correctly or not.&lt;br /&gt;
# Go to Edit or Give feedback and submit a feedback.&lt;br /&gt;
# Go back and check if the feedback given is displayed correctly or not.&lt;br /&gt;
# Check if author's feedback is correct or not.&lt;br /&gt;
# Go to the '''Temp''' assignment and see if the page is being displayed correctly or not (since there is no assignment submission content or reviews for that).&lt;br /&gt;
&lt;br /&gt;
''NOTE: Since this was a refactoring of the code and methods, the existing functionality was supposed to remain the same and not break for the changes we've made.''&lt;br /&gt;
&lt;br /&gt;
= References =&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;references/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;4.&amp;amp;nbsp; [https://github.com/expertiza/expertiza Expertiza Main Repo] &amp;lt;br&amp;gt;&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;5.&amp;amp;nbsp; [https://github.com/adeeshag/expertiza/blob/develop/app/models/review_response_map.rb Refactored ReviewResponseMap.rb]&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;6.&amp;amp;nbsp; [https://github.com/adeeshag/expertiza/tree/develop/test/fixtures Test Fixtures]&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;7.&amp;amp;nbsp; [https://github.com/adeeshag/expertiza/blob/develop/test/unit/review_response_map_test.rb Unit Tests]&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;8.&amp;amp;nbsp; [http://152.46.16.195:5902/ Expertiza Deployed Site]&amp;lt;br&amp;gt;&lt;/div&gt;</summary>
		<author><name>Cnbrown4</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2015/ossE1558BGJ&amp;diff=98462</id>
		<title>CSC/ECE 517 Fall 2015/ossE1558BGJ</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2015/ossE1558BGJ&amp;diff=98462"/>
		<updated>2015-11-06T21:34:31Z</updated>

		<summary type="html">&lt;p&gt;Cnbrown4: /* Refactoring of final_versions_from_reviewer method */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Introduction =&lt;br /&gt;
&lt;br /&gt;
This page provides a description of the modifications and improvements made to the Expertiza project’s source code as part of an Expertiza based Open Source Software project.  Expertiza is a web based application which allows students to submit and peer-review classmates’ work, including written articles and development projects. The specific changes made during the course of this project were to the ReviewResponseMap.rb file, with additional changes made to other related files in support of refactoring ReviewResponseMap.rb.  &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
= Problem Statement =&lt;br /&gt;
&lt;br /&gt;
ReviewResponseMap is the model class used to manage the relationship between contributors, reviewers, and assignments.  The intent of the changes were to refactor the code for better readability and adherence to Ruby coding standards and best practices.  Primarily these changes involved the refactoring of overly complex methods, renaming methods for better readability, and the addition of missing unit tests.&lt;br /&gt;
&lt;br /&gt;
Project Requirements:&lt;br /&gt;
&lt;br /&gt;
# Code Climate&amp;lt;ref name=&amp;quot;Code Climate&amp;quot;&amp;gt;https://codeclimate.com&amp;lt;/ref&amp;gt; shows import method is complex, because of lots of checks. This method can be fixed by adding private methods for raising import error.&lt;br /&gt;
# Get_assessments_round_for method can be renamed to get_team_responses_for_round. Team_id private variable is not needed.&lt;br /&gt;
# metareview_response_maps rename, refactoring can be done. No need to do second iteration.&lt;br /&gt;
# write missing unit tests for existing methods.&lt;br /&gt;
&lt;br /&gt;
= Design Patterns =&lt;br /&gt;
&lt;br /&gt;
As part of our project, we refactored the model to follow the Single Responsibility and Don't Repeat Yourself (DRY) Principles.  Both of the principles focus on reducing code repetition and increasing the cohesion of the individual methods in the class.  The Single Responsibility Principle states that each class and method should have sole responsibility over one single part of the functionality of the system&amp;lt;ref&amp;gt;https://en.wikipedia.org/wiki/Single_responsibility_principle&amp;lt;/ref&amp;gt;.  The DRY principle states that whenever the same types of logic and functionality are being performed in a class the duplicated logic should be extracted into a new method that can be called in place of the repeated lines of code &amp;lt;ref&amp;gt;https://en.wikipedia.org/wiki/Don%27t_repeat_yourself&amp;lt;/ref&amp;gt;.  A prime example of a method that initially violated these principles was the import method, which in addition to performing the core import processes also performed a number of checks that would be more properly extracted into private methods.&lt;br /&gt;
&lt;br /&gt;
=Code Changes =&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Refactoring of import method ===&lt;br /&gt;
&lt;br /&gt;
CodeClimate reports showed the import method to be overly complex, with a number of checks being included within the import method itself.  The resolution for this problem was to refactor the import method, creating private methods to perform the null checks and throw import errors.  Prior to refactoring, all null checks were performed within the import method.   After refactoring, the import method adheres to the single responsibility principle, performing only key import tasks while making calls to private methods for any necessary validation. The size of the import method was reduced by doing this and counts for better readability of the code. Also, this method is a very important one and care was taken so that any existing functionality did not break. &lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
Before refactoring:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;big&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 def self.import(row, session, id)&lt;br /&gt;
    if row.length &amp;lt; 2&lt;br /&gt;
      raise ArgumentError, &amp;quot;Not enough items&amp;quot;&lt;br /&gt;
    end&lt;br /&gt;
    assignment = Assignment.find(id)&lt;br /&gt;
    if assignment.nil?&lt;br /&gt;
      raise ImportError, &amp;quot;The assignment with id \&amp;quot;#{id}\&amp;quot; was not found. &amp;lt;a href='/assignment/new'&amp;gt;Create&amp;lt;/a&amp;gt; this assignment?&amp;quot;&lt;br /&gt;
    end&lt;br /&gt;
    index = 1&lt;br /&gt;
    while index &amp;lt; row.length&lt;br /&gt;
      user = User.find_by_name(row[index].to_s.strip)&lt;br /&gt;
      if user.nil?&lt;br /&gt;
        raise ImportError, &amp;quot;The user account for the reviewer \&amp;quot;#{row[index]}\&amp;quot; was not found. &amp;lt;a href='/users/new'&amp;gt;Create&amp;lt;/a&amp;gt; this user?&amp;quot;&lt;br /&gt;
      end&lt;br /&gt;
      reviewer = AssignmentParticipant.where(user_id: user.id, parent_id:  assignment.id).first&lt;br /&gt;
      if reviewer == nil&lt;br /&gt;
        raise ImportError, &amp;quot;The reviewer \&amp;quot;#{row[index]}\&amp;quot; is not a participant in this assignment. &amp;lt;a href='/users/new'&amp;gt;Register&amp;lt;/a&amp;gt; this user as a participant?&amp;quot;&lt;br /&gt;
      end&lt;br /&gt;
      if assignment.team_assignment&lt;br /&gt;
        reviewee = AssignmentTeam.where(name: row[0].to_s.strip, parent_id:  assignment.id).first&lt;br /&gt;
        if reviewee == nil&lt;br /&gt;
          raise ImportError, &amp;quot;The author \&amp;quot;#{row[0].to_s.strip}\&amp;quot; was not found. &amp;lt;a href='/users/new'&amp;gt;Create&amp;lt;/a&amp;gt; this user?&amp;quot;&lt;br /&gt;
        end&lt;br /&gt;
        existing = ReviewResponseMap.where(reviewee_id: reviewee.id, reviewer_id:  reviewer.id).first&lt;br /&gt;
        if existing.nil?&lt;br /&gt;
          ReviewResponseMap.create(:reviewer_id =&amp;gt; reviewer.id, :reviewee_id =&amp;gt; reviewee.id, :reviewed_object_id =&amp;gt; assignment.id)&lt;br /&gt;
        end&lt;br /&gt;
      else&lt;br /&gt;
        puser = User.find_by_name(row[0].to_s.strip)&lt;br /&gt;
        if user == nil&lt;br /&gt;
          raise ImportError, &amp;quot;The user account for the reviewee \&amp;quot;#{row[0]}\&amp;quot; was not found. &amp;lt;a href='/users/new'&amp;gt;Create&amp;lt;/a&amp;gt; this user?&amp;quot;&lt;br /&gt;
        end&lt;br /&gt;
        reviewee = AssignmentParticipant.where(user_id: puser.id, parent_id:  assignment.id).first&lt;br /&gt;
        if reviewee == nil&lt;br /&gt;
          raise ImportError, &amp;quot;The author \&amp;quot;#{row[0].to_s.strip}\&amp;quot; was not found. &amp;lt;a href='/users/new'&amp;gt;Create&amp;lt;/a&amp;gt; this user?&amp;quot;&lt;br /&gt;
        end&lt;br /&gt;
        team_id = TeamsUser.team_id(reviewee.parent_id, reviewee.user_id)&lt;br /&gt;
        existing = ReviewResponseMap.where(reviewee_id: team_id, reviewer_id:  reviewer.id).first&lt;br /&gt;
        if existing.nil?&lt;br /&gt;
          ReviewResponseMap.create(:reviewee_id =&amp;gt; team_id, :reviewer_id =&amp;gt; reviewer.id, :reviewed_object_id =&amp;gt; assignment.id)&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
      index += 1&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
&lt;br /&gt;
After refactoring:&lt;br /&gt;
 &lt;br /&gt;
  &amp;lt;big&amp;gt;&amp;lt;nowiki&amp;gt;#Imports new reponse maps if they do not already exist&lt;br /&gt;
  def self.import(row, _session, id)&lt;br /&gt;
      if row.length &amp;lt; 2&lt;br /&gt;
          raise ArgumentError, 'Not enough items'&lt;br /&gt;
      end&lt;br /&gt;
      assignment = find_assignment(id)&lt;br /&gt;
      index = 1&lt;br /&gt;
      reviewee_name = row[0]&lt;br /&gt;
      while index &amp;lt; row.length&lt;br /&gt;
          reviewee_id = nil&lt;br /&gt;
          reviewer_name = row[index]&lt;br /&gt;
          reviewer = get_assignment_participant(reviewer_name,  assignment.id, &amp;quot;reviewer&amp;quot;)&lt;br /&gt;
          participant_nil?(reviewer, reviewer_name , &amp;quot;reviewer&amp;quot;)&lt;br /&gt;
         &lt;br /&gt;
         #Find reviewee if assignment is a team assignment&lt;br /&gt;
         if assignment.team_assignment&lt;br /&gt;
             reviewee = AssignmentTeam.where(name: reviewee_name .to_s.strip, parent_id: assignment.id).first&lt;br /&gt;
             participant_nil?(reviewee, reviewee_name, &amp;quot;author&amp;quot;)&lt;br /&gt;
             reviewee_id = reviewee.id&lt;br /&gt;
         #Find reviewee if assignment is not a team assignment&lt;br /&gt;
         else&lt;br /&gt;
	     reviewee = get_assignment_participant(reviewee_name, assignment.id, &amp;quot;reviewee&amp;quot;)&lt;br /&gt;
             participant_nil?(reviewee, reviewee_name, &amp;quot;author&amp;quot;)&lt;br /&gt;
             reviewee_id  = TeamsUser.team_id(reviewee.parent_id, reviewee.user_id)&lt;br /&gt;
         end&lt;br /&gt;
         create_response_map(reviewer, reviewee_id,  assignment)&lt;br /&gt;
         index += 1&lt;br /&gt;
      end&lt;br /&gt;
  end&amp;lt;/nowiki&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Private methods added:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;big&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  # Check for if assignment value is null&lt;br /&gt;
  def self.find_assignment(id)&lt;br /&gt;
      begin&lt;br /&gt;
          assignment = Assignment.find(id)&lt;br /&gt;
      rescue ActiveRecord::RecordNotFound&lt;br /&gt;
          raise ImportError, &amp;quot;The assignment with id \&amp;quot;#{id}\&amp;quot; was not found.&amp;lt;a href='/assignment/new'&amp;gt;Create&amp;lt;/a&amp;gt; this assignment?&amp;quot;&lt;br /&gt;
      end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  # Check for if participant is null&lt;br /&gt;
  def self.participant_nil?(participant, user_name, participant_type) &lt;br /&gt;
      error_message = nil&lt;br /&gt;
      if participant_type == &amp;quot;author&amp;quot;&lt;br /&gt;
          error_message = &amp;quot;The author \&amp;quot;#{user_name.to_s.strip}\&amp;quot; was not found.&amp;lt;a href='/users/new'&amp;gt;Create&amp;lt;/a&amp;gt; this user?&amp;quot;&lt;br /&gt;
      else&lt;br /&gt;
          error_message =  &amp;quot;The reviewer \&amp;quot;#{user_name}\&amp;quot; is not a participant in this assignment.&amp;lt;a href='/users/new'&amp;gt;Register&amp;lt;/a&amp;gt; this user as a participant?&amp;quot;&lt;br /&gt;
      end&lt;br /&gt;
      check_nil?(participant, error_message)&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  # Check for if user is null&lt;br /&gt;
  def self.user_nil?(user, user_name, user_type)&lt;br /&gt;
      check_nil?( user, &amp;quot;The user account for the \&amp;quot;#{user_type}\&amp;quot; \&amp;quot;#{user_name}\&amp;quot; was not found.&amp;lt;a href='/users/new'&amp;gt;Create&amp;lt;/a&amp;gt; this user?&amp;quot;)&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
 #Throws import error for nil objects&lt;br /&gt;
  def self.check_nil?(object, error_message)&lt;br /&gt;
      if object.nil?&lt;br /&gt;
          raise ImportError, error_message&lt;br /&gt;
      end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Refactoring of get_assessments_round_for method ===&lt;br /&gt;
&lt;br /&gt;
The get_assessments_round_for method’s name failed to provide a clear idea of the method’s purpose and functionality.  This is why it was renamed to get_team_responses_for_round, the new name of the method provides a clearer idea of its purpose. Additionally, there was a private variable, team_id, introduced in the method that was unnecessary and could be replaced by using the id property of the team parameter directly.  We also removed the return statement at the end of the method.  &lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
Before refactoring:&lt;br /&gt;
&amp;lt;big&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  def self.get_assessments_round_for(team,round)&lt;br /&gt;
    team_id =team.id&lt;br /&gt;
    responses = Array.new&lt;br /&gt;
    if team_id&lt;br /&gt;
      maps = ResponseMap.where(:reviewee_id =&amp;gt; team_id, :type =&amp;gt; &amp;quot;ReviewResponseMap&amp;quot;)&lt;br /&gt;
      maps.each{ |map|&lt;br /&gt;
        if !map.response.empty? &amp;amp;&amp;amp; !map.response.reject{|r| r.round!=round}.empty?&lt;br /&gt;
          responses &amp;lt;&amp;lt; map.response.reject{|r| r.round!=round}.last&lt;br /&gt;
        end&lt;br /&gt;
      }&lt;br /&gt;
      responses.sort! {|a,b| a.map.reviewer.fullname &amp;lt;=&amp;gt; b.map.reviewer.fullname }&lt;br /&gt;
    end&lt;br /&gt;
    return responses&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
&lt;br /&gt;
After refactoring: &lt;br /&gt;
&lt;br /&gt;
&amp;lt;big&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  def self.get_team_responses_for_round(team, round)&lt;br /&gt;
    responses = []&lt;br /&gt;
    if team.id&lt;br /&gt;
      maps = ResponseMap.where(reviewee_id: team.id, type: 'ReviewResponseMap')&lt;br /&gt;
      maps.each do |map|&lt;br /&gt;
        unless map.response.empty? &amp;amp;&amp;amp; map.response.reject { |r| r.round != round }.empty?&lt;br /&gt;
          responses &amp;lt;&amp;lt; map.response.reject { |r| r.round != round }.last&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
      responses.sort! { |a, b| a.map.reviewer.fullname &amp;lt;=&amp;gt; b.map.reviewer.fullname }&lt;br /&gt;
    end&lt;br /&gt;
    responses&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
The change in method name also required changes to the following files that referenced it:&lt;br /&gt;
&lt;br /&gt;
/app/models/assignment.rb:436:    &lt;br /&gt;
 &lt;br /&gt;
&amp;lt;big&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  assessments = ReviewResponseMap.get_assessments_round_for(team,i)&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt; &lt;br /&gt;
&lt;br /&gt;
./app/models/assignment_participant.rb:268:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;big&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 scores[questionnaire_symbol][:assessments] = questionnaire.get_assessments_round_for(self,round)&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Refactoring of metareview_response_maps method ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The metareview_response_maps method was unnecessarily complex.  It contained an unneeded private variable and an unnecessary nested loop.  Originally, it added each metareview map individually in the nested loop.  We decided to remove the nested loop and use the concat method for readability and maintainability.  These changes allowed us to remove the private variable &amp;quot;metareview_list&amp;quot; and only maintain the &amp;quot;metareview_response_maps&amp;quot; variable.  We also renamed the metareview_response_maps method to get_metareview_response_maps method to be more descriptive about the intent of the method. &lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
Before refactoring:&lt;br /&gt;
&amp;lt;big&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 def metareview_response_maps&lt;br /&gt;
    responses = Response.where(map_id:self.id)&lt;br /&gt;
    metareview_list=[]&lt;br /&gt;
    responses.each do |response|&lt;br /&gt;
      metareview_response_maps = MetareviewResponseMap.where(reviewed_object_id:response.id)&lt;br /&gt;
      metareview_response_maps.each do |metareview_response_map|&lt;br /&gt;
        metareview_list&amp;lt;&amp;lt;metareview_response_map&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
    metareview_list&lt;br /&gt;
 end&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
After refactoring:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;big&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  def get_metareview_response_maps&lt;br /&gt;
    responses = Response.where(map_id: id)&lt;br /&gt;
    metareview_response_maps = []&lt;br /&gt;
    responses.each do |response|&lt;br /&gt;
      metareview_response_maps.concat MetareviewResponseMap.where(reviewed_object_id: response.id)&lt;br /&gt;
    end&lt;br /&gt;
    metareview_response_maps&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Refactoring of export method ===&lt;br /&gt;
The export method contained mappings.sort! { |a, b| a.reviewee.name &amp;lt;=&amp;gt; b.reviewee.name }.  We could not get past this when running tests, we kept getting a message saying that sort! was not a method for an ActiveRecord_Relation.  So we &lt;br /&gt;
&lt;br /&gt;
Before refactoring:&lt;br /&gt;
&amp;lt;big&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  def self.export(csv, parent_id, options)&lt;br /&gt;
    mappings = where(reviewed_object_id: parent_id)&lt;br /&gt;
    mappings.sort! { |a, b| a.reviewee.name &amp;lt;=&amp;gt; b.reviewee.name }&lt;br /&gt;
    mappings.each {&lt;br /&gt;
      |map|&lt;br /&gt;
      csv &amp;lt;&amp;lt; [&lt;br /&gt;
        map.reviewee.name,&lt;br /&gt;
        map.reviewer.name&lt;br /&gt;
      ]&lt;br /&gt;
    }&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
&lt;br /&gt;
After refactoring:&lt;br /&gt;
&amp;lt;big&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  def self.export(csv, parent_id, options)&lt;br /&gt;
    mappings = where(reviewed_object_id: parent_id)&lt;br /&gt;
    mappings = mappings.sort { |a, b| a.reviewee.name &amp;lt;=&amp;gt; b.reviewee.name }&lt;br /&gt;
    mappings.each do&lt;br /&gt;
    |map|&lt;br /&gt;
      csv &amp;lt;&amp;lt; [map.reviewee.name, map.reviewer.name]&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
=== Refactoring of final_versions_from_reviewer method ===&lt;br /&gt;
&lt;br /&gt;
Before refactoring:&lt;br /&gt;
&amp;lt;big&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  def self.final_versions_from_reviewer(reviewer_id)&lt;br /&gt;
    maps = ReviewResponseMap.where(reviewer_id: reviewer_id)&lt;br /&gt;
    assignment = Assignment.find(Participant.find(reviewer_id).parent_id)&lt;br /&gt;
    review_final_versions = Hash.new&lt;br /&gt;
    if !assignment.varying_rubrics_by_round?&lt;br /&gt;
      #same review rubric used in multiple rounds&lt;br /&gt;
      review_final_versions[:review] = Hash.new&lt;br /&gt;
      review_final_versions[:review][:questionnaire_id] = assignment.get_review_questionnaire_id&lt;br /&gt;
      response_ids = Array.new&lt;br /&gt;
      maps.each do |map|&lt;br /&gt;
        responses = Response.where(map_id:map.id)&lt;br /&gt;
        if !responses.empty?&lt;br /&gt;
          response_ids &amp;lt;&amp;lt; responses.last.id&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
      review_final_versions[:review][:response_ids] = response_ids&lt;br /&gt;
    else&lt;br /&gt;
      #vary rubric by round&lt;br /&gt;
      rounds_num = assignment.rounds_of_reviews&lt;br /&gt;
      for round in 1..rounds_num&lt;br /&gt;
        symbol = (&amp;quot;review round&amp;quot;+round.to_s).to_sym&lt;br /&gt;
        review_final_versions[symbol] = Hash.new&lt;br /&gt;
        review_final_versions[symbol][:questionnaire_id] = assignment.get_review_questionnaire_id(round)&lt;br /&gt;
        response_ids = Array.new&lt;br /&gt;
        maps.each do |map|&lt;br /&gt;
          responses = Response.where(map_id:map.id, round:round)&lt;br /&gt;
          if !responses.empty?&lt;br /&gt;
            response_ids &amp;lt;&amp;lt; responses.last.id&lt;br /&gt;
          end&lt;br /&gt;
        end&lt;br /&gt;
        review_final_versions[symbol][:response_ids] = response_ids&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
    review_final_versions&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
&lt;br /&gt;
After refactoring:&lt;br /&gt;
&amp;lt;big&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  def self.final_versions_from_reviewer(reviewer_id)&lt;br /&gt;
    maps = ReviewResponseMap.where(reviewer_id: reviewer_id)&lt;br /&gt;
    assignment = find_assignment(Participant.find(reviewer_id).parent_id)&lt;br /&gt;
    review_final_versions = {}&lt;br /&gt;
    unless assignment.varying_rubrics_by_round?&lt;br /&gt;
      #same review rubric used in multiple rounds&lt;br /&gt;
      review_final_versions = review_final_version_responses(:review, :questionnaire_id, assignment, maps)&lt;br /&gt;
    else&lt;br /&gt;
      # vary rubric by round&lt;br /&gt;
      rounds_num = assignment.rounds_of_reviews&lt;br /&gt;
      (1..rounds_num).each do |round|&lt;br /&gt;
        symbol = ('review round' + round.to_s).to_sym&lt;br /&gt;
        review_final_versions = review_final_version_responses(symbol, :questionnaire_id, assignment, maps, round)&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
    review_final_versions&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Private methods added:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;big&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  # Compute list of responses and return it&lt;br /&gt;
  def self.review_final_version_responses(symbol, questionnaire_id, assignment, maps, round = nil)&lt;br /&gt;
    review_final_versions = {}&lt;br /&gt;
    review_final_versions[symbol] = {}&lt;br /&gt;
    review_final_versions[symbol][questionnaire_id] = assignment.get_review_questionnaire_id(round)&lt;br /&gt;
    response_ids = []&lt;br /&gt;
    maps.each do |map|&lt;br /&gt;
      responses =  get_responses(map.id, round)&lt;br /&gt;
      unless responses.empty?&lt;br /&gt;
        response_ids &amp;lt;&amp;lt; responses.last.id&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
    review_final_versions[symbol][:response_ids] = response_ids&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;big&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  #Get responses by map_id and round (if exists)&lt;br /&gt;
  def self.get_responses(id, round)&lt;br /&gt;
     if round.nil?&lt;br /&gt;
       responses = Response.where(map_id: id)&lt;br /&gt;
     else&lt;br /&gt;
       responses = Response.where(map_id: id, round: round)&lt;br /&gt;
     end	&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Refactoring of other methods ===&lt;br /&gt;
Although trivial, we removed the return statement from the get_title, export_fields, and show_feedback methods because return statements are unnecessary in Ruby.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Addition of code comments ===&lt;br /&gt;
&lt;br /&gt;
We added comments to all of the methods in the ReviewResponseMap.rb file and corrected instances where CodeClimate Identified opportunities for code improvement.  One issue flagged by CodeClimate that we did not change was to use the find_by method instead of where().first method.  The where().first method occurs in the import, get_assignment_participant, and create_response_map methods. It is not always appropriate to use the find_by method, as documented in this github post: https://github.com/bbatsov/rubocop/issues/1938 .  In instances where ordering by id is the desired behavior, where().first will order by default, but in Rails 4+ find_by does not honor that default behavior.  For this reason we left the instances of where().first unchanged.&lt;br /&gt;
&lt;br /&gt;
=== Code Improvements ===&lt;br /&gt;
&lt;br /&gt;
This refactoring was to improve readability and follow as many good ''Rubyist'' coding practices as possible without breaking the functionality of existing code. We used CodeClimate of the master branch code as a reference. We took the suggestions we got from CodeClimate and improved our code based on that.&lt;br /&gt;
We also made some of the methods shorter by removing redundant functionality and adding private methods to methods with a lot internal functionality. We also added private methods in places where we saw repeated patterns to make the code ''DRYer''.&lt;br /&gt;
At the end of our refactoring, we managed to improve the rating on CodeClimate from a '''C''' to a '''B''' . Further improvements meant reducing the size of the entire class which required a much more significant refactoring in multiple files and folders. We focused on refactoring the existing model, '''ReviewResponseMap'''.&lt;br /&gt;
&lt;br /&gt;
= Unit Tests =&lt;br /&gt;
The previous unit tests had syntactical and run time errors.  We were not able to get the previous unit tests to run without errors.  Because of this we rewrote all of the unit tests for the &amp;lt;b&amp;gt;ReviewResponseModel&amp;lt;/b&amp;gt;.  It is important to have working unit tests so that when internal changes are made to functions the external output remains the same.&lt;br /&gt;
&lt;br /&gt;
=== Refactoring of Unit Tests===&lt;br /&gt;
&lt;br /&gt;
We added a test_helper file to the main test folder that requires a needed configuration file and needed gems.  We also added 8 fixtures that were needed for data to run the unit tests.  The following fixture files were added:&lt;br /&gt;
&lt;br /&gt;
* assignment_questionnaires.yml&lt;br /&gt;
* assignments.yml&lt;br /&gt;
* participants.yml&lt;br /&gt;
* questionnaires.yml&lt;br /&gt;
* response_maps.yml&lt;br /&gt;
* responses.yml&lt;br /&gt;
* teams.yml&lt;br /&gt;
* users.yml&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
There is at least one unit test for every public method within the &amp;lt;b&amp;gt;ReviewResponseModel&amp;lt;/b&amp;gt;.  The test naming convention used is &amp;quot;method_&amp;lt;name of method that is being tested&amp;gt;&amp;quot;.  For example, the unit test for the export method is &amp;quot;method_export&amp;quot;.  If there are multiple test for one method the name of the test will include the test case after the normal naming convention.  For example, one of the unit tests for the import method checks for an invalid assignment.  The name of this method is &amp;quot;method_import_invalid_assignment&amp;quot;.  The following are the unit tests we created:&lt;br /&gt;
&lt;br /&gt;
* method_export&lt;br /&gt;
* method_get_metareview_response_maps&lt;br /&gt;
* method_get_team_response_for_round&lt;br /&gt;
* method_final_versions_from_reviewer&lt;br /&gt;
* method_import&lt;br /&gt;
* method_import_invalid_reviewee&lt;br /&gt;
* method_import_invalid_reviewer&lt;br /&gt;
* method_import_invalid_assignment&lt;br /&gt;
* method_delete&lt;br /&gt;
* method_delete_no _force&lt;br /&gt;
* method_show_feedback&lt;br /&gt;
* method_get_title&lt;br /&gt;
* method_export_fields&lt;br /&gt;
* method_questionnaire&lt;br /&gt;
* method_add_reviewer&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== How to Run Unit Tests ===&lt;br /&gt;
To run the unit tests, follow these steps:&lt;br /&gt;
&lt;br /&gt;
# Download the master branch of the repo.&lt;br /&gt;
# Setup the Databases for the test environment (we have used Zhewei's scrubbed expertiza DB )&lt;br /&gt;
#* Run the &amp;quot; rake db:create RAILS_ENV=test &amp;quot; command&lt;br /&gt;
#* Run the &amp;quot; rake db:reset RAILS_ENV=test &amp;quot; command&lt;br /&gt;
#* Scrub the DB using &amp;quot; mysql -u root expertiza_development &amp;lt; expertiza-scrubbed.sql&amp;quot;&lt;br /&gt;
#* Run the &amp;quot; rake db:migrate &amp;quot;&lt;br /&gt;
# Run &amp;quot; rake test test/unit/review_response_map_test.rb &amp;quot; in the &amp;quot;expertiza/&amp;quot; directory.&lt;br /&gt;
#* If you run into a mysql log in error go into config/database.yml and edit the mysql credentials for the test section so that it matches the local environment's mysql configuration&lt;br /&gt;
# Check if tests passed or failed.&lt;br /&gt;
&lt;br /&gt;
= Manual Test Case =&lt;br /&gt;
&lt;br /&gt;
In order to test the changes made to the ReviewResponseMap, bring up [[ http://152.46.16.195:5902/ | Expertiza]] and log in as an administrator.  Once logged in, proceed with the following steps:&lt;br /&gt;
&lt;br /&gt;
# Go to '''impersonate user''' when logged in as ''instructor6'' and type in ''student559'' (or) just log in as ''student559''. All passwords are ''password'' .&lt;br /&gt;
# Pick any assignment to view.&lt;br /&gt;
# Navigate to '''Other's work'''.&lt;br /&gt;
# Check the different reviews and metareviews. Whether they are being displayed correctly or not.&lt;br /&gt;
# Go to Edit or Give feedback and submit a feedback.&lt;br /&gt;
# Go back and check if the feedback given is displayed correctly or not.&lt;br /&gt;
# Check if author's feedback is correct or not.&lt;br /&gt;
# Go to the '''Temp''' assignment and see if the page is being displayed correctly or not (since there is no assignment submission content or reviews for that).&lt;br /&gt;
&lt;br /&gt;
''NOTE: Since this was a refactoring of the code and methods, the existing functionality was supposed to remain the same and not break for the changes we've made.''&lt;br /&gt;
&lt;br /&gt;
= References =&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;references/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;4.&amp;amp;nbsp; [https://github.com/expertiza/expertiza Expertiza Main Repo] &amp;lt;br&amp;gt;&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;5.&amp;amp;nbsp; [https://github.com/adeeshag/expertiza/blob/develop/app/models/review_response_map.rb Refactored ReviewResponseMap.rb]&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;6.&amp;amp;nbsp; [https://github.com/adeeshag/expertiza/tree/develop/test/fixtures Test Fixtures]&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;7.&amp;amp;nbsp; [https://github.com/adeeshag/expertiza/blob/develop/test/unit/review_response_map_test.rb Unit Tests]&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;8.&amp;amp;nbsp; [http://152.46.16.195:5902/ Expertiza Deployed Site]&amp;lt;br&amp;gt;&lt;/div&gt;</summary>
		<author><name>Cnbrown4</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2015/ossE1558BGJ&amp;diff=98461</id>
		<title>CSC/ECE 517 Fall 2015/ossE1558BGJ</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2015/ossE1558BGJ&amp;diff=98461"/>
		<updated>2015-11-06T21:33:51Z</updated>

		<summary type="html">&lt;p&gt;Cnbrown4: /* Code Changes */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Introduction =&lt;br /&gt;
&lt;br /&gt;
This page provides a description of the modifications and improvements made to the Expertiza project’s source code as part of an Expertiza based Open Source Software project.  Expertiza is a web based application which allows students to submit and peer-review classmates’ work, including written articles and development projects. The specific changes made during the course of this project were to the ReviewResponseMap.rb file, with additional changes made to other related files in support of refactoring ReviewResponseMap.rb.  &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
= Problem Statement =&lt;br /&gt;
&lt;br /&gt;
ReviewResponseMap is the model class used to manage the relationship between contributors, reviewers, and assignments.  The intent of the changes were to refactor the code for better readability and adherence to Ruby coding standards and best practices.  Primarily these changes involved the refactoring of overly complex methods, renaming methods for better readability, and the addition of missing unit tests.&lt;br /&gt;
&lt;br /&gt;
Project Requirements:&lt;br /&gt;
&lt;br /&gt;
# Code Climate&amp;lt;ref name=&amp;quot;Code Climate&amp;quot;&amp;gt;https://codeclimate.com&amp;lt;/ref&amp;gt; shows import method is complex, because of lots of checks. This method can be fixed by adding private methods for raising import error.&lt;br /&gt;
# Get_assessments_round_for method can be renamed to get_team_responses_for_round. Team_id private variable is not needed.&lt;br /&gt;
# metareview_response_maps rename, refactoring can be done. No need to do second iteration.&lt;br /&gt;
# write missing unit tests for existing methods.&lt;br /&gt;
&lt;br /&gt;
= Design Patterns =&lt;br /&gt;
&lt;br /&gt;
As part of our project, we refactored the model to follow the Single Responsibility and Don't Repeat Yourself (DRY) Principles.  Both of the principles focus on reducing code repetition and increasing the cohesion of the individual methods in the class.  The Single Responsibility Principle states that each class and method should have sole responsibility over one single part of the functionality of the system&amp;lt;ref&amp;gt;https://en.wikipedia.org/wiki/Single_responsibility_principle&amp;lt;/ref&amp;gt;.  The DRY principle states that whenever the same types of logic and functionality are being performed in a class the duplicated logic should be extracted into a new method that can be called in place of the repeated lines of code &amp;lt;ref&amp;gt;https://en.wikipedia.org/wiki/Don%27t_repeat_yourself&amp;lt;/ref&amp;gt;.  A prime example of a method that initially violated these principles was the import method, which in addition to performing the core import processes also performed a number of checks that would be more properly extracted into private methods.&lt;br /&gt;
&lt;br /&gt;
=Code Changes =&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Refactoring of import method ===&lt;br /&gt;
&lt;br /&gt;
CodeClimate reports showed the import method to be overly complex, with a number of checks being included within the import method itself.  The resolution for this problem was to refactor the import method, creating private methods to perform the null checks and throw import errors.  Prior to refactoring, all null checks were performed within the import method.   After refactoring, the import method adheres to the single responsibility principle, performing only key import tasks while making calls to private methods for any necessary validation. The size of the import method was reduced by doing this and counts for better readability of the code. Also, this method is a very important one and care was taken so that any existing functionality did not break. &lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
Before refactoring:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;big&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 def self.import(row, session, id)&lt;br /&gt;
    if row.length &amp;lt; 2&lt;br /&gt;
      raise ArgumentError, &amp;quot;Not enough items&amp;quot;&lt;br /&gt;
    end&lt;br /&gt;
    assignment = Assignment.find(id)&lt;br /&gt;
    if assignment.nil?&lt;br /&gt;
      raise ImportError, &amp;quot;The assignment with id \&amp;quot;#{id}\&amp;quot; was not found. &amp;lt;a href='/assignment/new'&amp;gt;Create&amp;lt;/a&amp;gt; this assignment?&amp;quot;&lt;br /&gt;
    end&lt;br /&gt;
    index = 1&lt;br /&gt;
    while index &amp;lt; row.length&lt;br /&gt;
      user = User.find_by_name(row[index].to_s.strip)&lt;br /&gt;
      if user.nil?&lt;br /&gt;
        raise ImportError, &amp;quot;The user account for the reviewer \&amp;quot;#{row[index]}\&amp;quot; was not found. &amp;lt;a href='/users/new'&amp;gt;Create&amp;lt;/a&amp;gt; this user?&amp;quot;&lt;br /&gt;
      end&lt;br /&gt;
      reviewer = AssignmentParticipant.where(user_id: user.id, parent_id:  assignment.id).first&lt;br /&gt;
      if reviewer == nil&lt;br /&gt;
        raise ImportError, &amp;quot;The reviewer \&amp;quot;#{row[index]}\&amp;quot; is not a participant in this assignment. &amp;lt;a href='/users/new'&amp;gt;Register&amp;lt;/a&amp;gt; this user as a participant?&amp;quot;&lt;br /&gt;
      end&lt;br /&gt;
      if assignment.team_assignment&lt;br /&gt;
        reviewee = AssignmentTeam.where(name: row[0].to_s.strip, parent_id:  assignment.id).first&lt;br /&gt;
        if reviewee == nil&lt;br /&gt;
          raise ImportError, &amp;quot;The author \&amp;quot;#{row[0].to_s.strip}\&amp;quot; was not found. &amp;lt;a href='/users/new'&amp;gt;Create&amp;lt;/a&amp;gt; this user?&amp;quot;&lt;br /&gt;
        end&lt;br /&gt;
        existing = ReviewResponseMap.where(reviewee_id: reviewee.id, reviewer_id:  reviewer.id).first&lt;br /&gt;
        if existing.nil?&lt;br /&gt;
          ReviewResponseMap.create(:reviewer_id =&amp;gt; reviewer.id, :reviewee_id =&amp;gt; reviewee.id, :reviewed_object_id =&amp;gt; assignment.id)&lt;br /&gt;
        end&lt;br /&gt;
      else&lt;br /&gt;
        puser = User.find_by_name(row[0].to_s.strip)&lt;br /&gt;
        if user == nil&lt;br /&gt;
          raise ImportError, &amp;quot;The user account for the reviewee \&amp;quot;#{row[0]}\&amp;quot; was not found. &amp;lt;a href='/users/new'&amp;gt;Create&amp;lt;/a&amp;gt; this user?&amp;quot;&lt;br /&gt;
        end&lt;br /&gt;
        reviewee = AssignmentParticipant.where(user_id: puser.id, parent_id:  assignment.id).first&lt;br /&gt;
        if reviewee == nil&lt;br /&gt;
          raise ImportError, &amp;quot;The author \&amp;quot;#{row[0].to_s.strip}\&amp;quot; was not found. &amp;lt;a href='/users/new'&amp;gt;Create&amp;lt;/a&amp;gt; this user?&amp;quot;&lt;br /&gt;
        end&lt;br /&gt;
        team_id = TeamsUser.team_id(reviewee.parent_id, reviewee.user_id)&lt;br /&gt;
        existing = ReviewResponseMap.where(reviewee_id: team_id, reviewer_id:  reviewer.id).first&lt;br /&gt;
        if existing.nil?&lt;br /&gt;
          ReviewResponseMap.create(:reviewee_id =&amp;gt; team_id, :reviewer_id =&amp;gt; reviewer.id, :reviewed_object_id =&amp;gt; assignment.id)&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
      index += 1&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
&lt;br /&gt;
After refactoring:&lt;br /&gt;
 &lt;br /&gt;
  &amp;lt;big&amp;gt;&amp;lt;nowiki&amp;gt;#Imports new reponse maps if they do not already exist&lt;br /&gt;
  def self.import(row, _session, id)&lt;br /&gt;
      if row.length &amp;lt; 2&lt;br /&gt;
          raise ArgumentError, 'Not enough items'&lt;br /&gt;
      end&lt;br /&gt;
      assignment = find_assignment(id)&lt;br /&gt;
      index = 1&lt;br /&gt;
      reviewee_name = row[0]&lt;br /&gt;
      while index &amp;lt; row.length&lt;br /&gt;
          reviewee_id = nil&lt;br /&gt;
          reviewer_name = row[index]&lt;br /&gt;
          reviewer = get_assignment_participant(reviewer_name,  assignment.id, &amp;quot;reviewer&amp;quot;)&lt;br /&gt;
          participant_nil?(reviewer, reviewer_name , &amp;quot;reviewer&amp;quot;)&lt;br /&gt;
         &lt;br /&gt;
         #Find reviewee if assignment is a team assignment&lt;br /&gt;
         if assignment.team_assignment&lt;br /&gt;
             reviewee = AssignmentTeam.where(name: reviewee_name .to_s.strip, parent_id: assignment.id).first&lt;br /&gt;
             participant_nil?(reviewee, reviewee_name, &amp;quot;author&amp;quot;)&lt;br /&gt;
             reviewee_id = reviewee.id&lt;br /&gt;
         #Find reviewee if assignment is not a team assignment&lt;br /&gt;
         else&lt;br /&gt;
	     reviewee = get_assignment_participant(reviewee_name, assignment.id, &amp;quot;reviewee&amp;quot;)&lt;br /&gt;
             participant_nil?(reviewee, reviewee_name, &amp;quot;author&amp;quot;)&lt;br /&gt;
             reviewee_id  = TeamsUser.team_id(reviewee.parent_id, reviewee.user_id)&lt;br /&gt;
         end&lt;br /&gt;
         create_response_map(reviewer, reviewee_id,  assignment)&lt;br /&gt;
         index += 1&lt;br /&gt;
      end&lt;br /&gt;
  end&amp;lt;/nowiki&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Private methods added:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;big&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  # Check for if assignment value is null&lt;br /&gt;
  def self.find_assignment(id)&lt;br /&gt;
      begin&lt;br /&gt;
          assignment = Assignment.find(id)&lt;br /&gt;
      rescue ActiveRecord::RecordNotFound&lt;br /&gt;
          raise ImportError, &amp;quot;The assignment with id \&amp;quot;#{id}\&amp;quot; was not found.&amp;lt;a href='/assignment/new'&amp;gt;Create&amp;lt;/a&amp;gt; this assignment?&amp;quot;&lt;br /&gt;
      end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  # Check for if participant is null&lt;br /&gt;
  def self.participant_nil?(participant, user_name, participant_type) &lt;br /&gt;
      error_message = nil&lt;br /&gt;
      if participant_type == &amp;quot;author&amp;quot;&lt;br /&gt;
          error_message = &amp;quot;The author \&amp;quot;#{user_name.to_s.strip}\&amp;quot; was not found.&amp;lt;a href='/users/new'&amp;gt;Create&amp;lt;/a&amp;gt; this user?&amp;quot;&lt;br /&gt;
      else&lt;br /&gt;
          error_message =  &amp;quot;The reviewer \&amp;quot;#{user_name}\&amp;quot; is not a participant in this assignment.&amp;lt;a href='/users/new'&amp;gt;Register&amp;lt;/a&amp;gt; this user as a participant?&amp;quot;&lt;br /&gt;
      end&lt;br /&gt;
      check_nil?(participant, error_message)&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  # Check for if user is null&lt;br /&gt;
  def self.user_nil?(user, user_name, user_type)&lt;br /&gt;
      check_nil?( user, &amp;quot;The user account for the \&amp;quot;#{user_type}\&amp;quot; \&amp;quot;#{user_name}\&amp;quot; was not found.&amp;lt;a href='/users/new'&amp;gt;Create&amp;lt;/a&amp;gt; this user?&amp;quot;)&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
 #Throws import error for nil objects&lt;br /&gt;
  def self.check_nil?(object, error_message)&lt;br /&gt;
      if object.nil?&lt;br /&gt;
          raise ImportError, error_message&lt;br /&gt;
      end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Refactoring of get_assessments_round_for method ===&lt;br /&gt;
&lt;br /&gt;
The get_assessments_round_for method’s name failed to provide a clear idea of the method’s purpose and functionality.  This is why it was renamed to get_team_responses_for_round, the new name of the method provides a clearer idea of its purpose. Additionally, there was a private variable, team_id, introduced in the method that was unnecessary and could be replaced by using the id property of the team parameter directly.  We also removed the return statement at the end of the method.  &lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
Before refactoring:&lt;br /&gt;
&amp;lt;big&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  def self.get_assessments_round_for(team,round)&lt;br /&gt;
    team_id =team.id&lt;br /&gt;
    responses = Array.new&lt;br /&gt;
    if team_id&lt;br /&gt;
      maps = ResponseMap.where(:reviewee_id =&amp;gt; team_id, :type =&amp;gt; &amp;quot;ReviewResponseMap&amp;quot;)&lt;br /&gt;
      maps.each{ |map|&lt;br /&gt;
        if !map.response.empty? &amp;amp;&amp;amp; !map.response.reject{|r| r.round!=round}.empty?&lt;br /&gt;
          responses &amp;lt;&amp;lt; map.response.reject{|r| r.round!=round}.last&lt;br /&gt;
        end&lt;br /&gt;
      }&lt;br /&gt;
      responses.sort! {|a,b| a.map.reviewer.fullname &amp;lt;=&amp;gt; b.map.reviewer.fullname }&lt;br /&gt;
    end&lt;br /&gt;
    return responses&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
&lt;br /&gt;
After refactoring: &lt;br /&gt;
&lt;br /&gt;
&amp;lt;big&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  def self.get_team_responses_for_round(team, round)&lt;br /&gt;
    responses = []&lt;br /&gt;
    if team.id&lt;br /&gt;
      maps = ResponseMap.where(reviewee_id: team.id, type: 'ReviewResponseMap')&lt;br /&gt;
      maps.each do |map|&lt;br /&gt;
        unless map.response.empty? &amp;amp;&amp;amp; map.response.reject { |r| r.round != round }.empty?&lt;br /&gt;
          responses &amp;lt;&amp;lt; map.response.reject { |r| r.round != round }.last&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
      responses.sort! { |a, b| a.map.reviewer.fullname &amp;lt;=&amp;gt; b.map.reviewer.fullname }&lt;br /&gt;
    end&lt;br /&gt;
    responses&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
The change in method name also required changes to the following files that referenced it:&lt;br /&gt;
&lt;br /&gt;
/app/models/assignment.rb:436:    &lt;br /&gt;
 &lt;br /&gt;
&amp;lt;big&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  assessments = ReviewResponseMap.get_assessments_round_for(team,i)&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt; &lt;br /&gt;
&lt;br /&gt;
./app/models/assignment_participant.rb:268:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;big&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 scores[questionnaire_symbol][:assessments] = questionnaire.get_assessments_round_for(self,round)&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Refactoring of metareview_response_maps method ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The metareview_response_maps method was unnecessarily complex.  It contained an unneeded private variable and an unnecessary nested loop.  Originally, it added each metareview map individually in the nested loop.  We decided to remove the nested loop and use the concat method for readability and maintainability.  These changes allowed us to remove the private variable &amp;quot;metareview_list&amp;quot; and only maintain the &amp;quot;metareview_response_maps&amp;quot; variable.  We also renamed the metareview_response_maps method to get_metareview_response_maps method to be more descriptive about the intent of the method. &lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
Before refactoring:&lt;br /&gt;
&amp;lt;big&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 def metareview_response_maps&lt;br /&gt;
    responses = Response.where(map_id:self.id)&lt;br /&gt;
    metareview_list=[]&lt;br /&gt;
    responses.each do |response|&lt;br /&gt;
      metareview_response_maps = MetareviewResponseMap.where(reviewed_object_id:response.id)&lt;br /&gt;
      metareview_response_maps.each do |metareview_response_map|&lt;br /&gt;
        metareview_list&amp;lt;&amp;lt;metareview_response_map&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
    metareview_list&lt;br /&gt;
 end&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
After refactoring:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;big&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  def get_metareview_response_maps&lt;br /&gt;
    responses = Response.where(map_id: id)&lt;br /&gt;
    metareview_response_maps = []&lt;br /&gt;
    responses.each do |response|&lt;br /&gt;
      metareview_response_maps.concat MetareviewResponseMap.where(reviewed_object_id: response.id)&lt;br /&gt;
    end&lt;br /&gt;
    metareview_response_maps&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Refactoring of export method ===&lt;br /&gt;
The export method contained mappings.sort! { |a, b| a.reviewee.name &amp;lt;=&amp;gt; b.reviewee.name }.  We could not get past this when running tests, we kept getting a message saying that sort! was not a method for an ActiveRecord_Relation.  So we &lt;br /&gt;
&lt;br /&gt;
Before refactoring:&lt;br /&gt;
&amp;lt;big&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  def self.export(csv, parent_id, options)&lt;br /&gt;
    mappings = where(reviewed_object_id: parent_id)&lt;br /&gt;
    mappings.sort! { |a, b| a.reviewee.name &amp;lt;=&amp;gt; b.reviewee.name }&lt;br /&gt;
    mappings.each {&lt;br /&gt;
      |map|&lt;br /&gt;
      csv &amp;lt;&amp;lt; [&lt;br /&gt;
        map.reviewee.name,&lt;br /&gt;
        map.reviewer.name&lt;br /&gt;
      ]&lt;br /&gt;
    }&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
&lt;br /&gt;
After refactoring:&lt;br /&gt;
&amp;lt;big&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  def self.export(csv, parent_id, options)&lt;br /&gt;
    mappings = where(reviewed_object_id: parent_id)&lt;br /&gt;
    mappings = mappings.sort { |a, b| a.reviewee.name &amp;lt;=&amp;gt; b.reviewee.name }&lt;br /&gt;
    mappings.each do&lt;br /&gt;
    |map|&lt;br /&gt;
      csv &amp;lt;&amp;lt; [map.reviewee.name, map.reviewer.name]&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
=== Refactoring of final_versions_from_reviewer method ===&lt;br /&gt;
&lt;br /&gt;
Before refactoring:&lt;br /&gt;
&amp;lt;big&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  def self.final_versions_from_reviewer(reviewer_id)&lt;br /&gt;
    maps = ReviewResponseMap.where(reviewer_id: reviewer_id)&lt;br /&gt;
    assignment = Assignment.find(Participant.find(reviewer_id).parent_id)&lt;br /&gt;
    review_final_versions = Hash.new&lt;br /&gt;
&lt;br /&gt;
    if !assignment.varying_rubrics_by_round?&lt;br /&gt;
      #same review rubric used in multiple rounds&lt;br /&gt;
      review_final_versions[:review] = Hash.new&lt;br /&gt;
      review_final_versions[:review][:questionnaire_id] = assignment.get_review_questionnaire_id&lt;br /&gt;
      response_ids = Array.new&lt;br /&gt;
&lt;br /&gt;
      maps.each do |map|&lt;br /&gt;
        responses = Response.where(map_id:map.id)&lt;br /&gt;
        if !responses.empty?&lt;br /&gt;
          response_ids &amp;lt;&amp;lt; responses.last.id&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
      review_final_versions[:review][:response_ids] = response_ids&lt;br /&gt;
&lt;br /&gt;
    else&lt;br /&gt;
      #vary rubric by round&lt;br /&gt;
      rounds_num = assignment.rounds_of_reviews&lt;br /&gt;
&lt;br /&gt;
      for round in 1..rounds_num&lt;br /&gt;
        symbol = (&amp;quot;review round&amp;quot;+round.to_s).to_sym&lt;br /&gt;
        review_final_versions[symbol] = Hash.new&lt;br /&gt;
        review_final_versions[symbol][:questionnaire_id] = assignment.get_review_questionnaire_id(round)&lt;br /&gt;
        response_ids = Array.new&lt;br /&gt;
&lt;br /&gt;
        maps.each do |map|&lt;br /&gt;
          responses = Response.where(map_id:map.id, round:round)&lt;br /&gt;
          if !responses.empty?&lt;br /&gt;
            response_ids &amp;lt;&amp;lt; responses.last.id&lt;br /&gt;
          end&lt;br /&gt;
        end&lt;br /&gt;
        review_final_versions[symbol][:response_ids] = response_ids&lt;br /&gt;
      end&lt;br /&gt;
&lt;br /&gt;
    end&lt;br /&gt;
    review_final_versions&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
&lt;br /&gt;
After refactoring:&lt;br /&gt;
&amp;lt;big&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  def self.final_versions_from_reviewer(reviewer_id)&lt;br /&gt;
    maps = ReviewResponseMap.where(reviewer_id: reviewer_id)&lt;br /&gt;
    assignment = find_assignment(Participant.find(reviewer_id).parent_id)&lt;br /&gt;
    review_final_versions = {}&lt;br /&gt;
    unless assignment.varying_rubrics_by_round?&lt;br /&gt;
      #same review rubric used in multiple rounds&lt;br /&gt;
      review_final_versions = review_final_version_responses(:review, :questionnaire_id, assignment, maps)&lt;br /&gt;
    else&lt;br /&gt;
      # vary rubric by round&lt;br /&gt;
      rounds_num = assignment.rounds_of_reviews&lt;br /&gt;
      (1..rounds_num).each do |round|&lt;br /&gt;
        symbol = ('review round' + round.to_s).to_sym&lt;br /&gt;
        review_final_versions = review_final_version_responses(symbol, :questionnaire_id, assignment, maps, round)&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
    review_final_versions&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Private methods added:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;big&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  # Compute list of responses and return it&lt;br /&gt;
  def self.review_final_version_responses(symbol, questionnaire_id, assignment, maps, round = nil)&lt;br /&gt;
    review_final_versions = {}&lt;br /&gt;
    review_final_versions[symbol] = {}&lt;br /&gt;
    review_final_versions[symbol][questionnaire_id] = assignment.get_review_questionnaire_id(round)&lt;br /&gt;
    response_ids = []&lt;br /&gt;
    maps.each do |map|&lt;br /&gt;
      responses =  get_responses(map.id, round)&lt;br /&gt;
      unless responses.empty?&lt;br /&gt;
        response_ids &amp;lt;&amp;lt; responses.last.id&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
    review_final_versions[symbol][:response_ids] = response_ids&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;big&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  #Get responses by map_id and round (if exists)&lt;br /&gt;
  def self.get_responses(id, round)&lt;br /&gt;
     if round.nil?&lt;br /&gt;
       responses = Response.where(map_id: id)&lt;br /&gt;
     else&lt;br /&gt;
       responses = Response.where(map_id: id, round: round)&lt;br /&gt;
     end	&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Refactoring of other methods ===&lt;br /&gt;
Although trivial, we removed the return statement from the get_title, export_fields, and show_feedback methods because return statements are unnecessary in Ruby.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Addition of code comments ===&lt;br /&gt;
&lt;br /&gt;
We added comments to all of the methods in the ReviewResponseMap.rb file and corrected instances where CodeClimate Identified opportunities for code improvement.  One issue flagged by CodeClimate that we did not change was to use the find_by method instead of where().first method.  The where().first method occurs in the import, get_assignment_participant, and create_response_map methods. It is not always appropriate to use the find_by method, as documented in this github post: https://github.com/bbatsov/rubocop/issues/1938 .  In instances where ordering by id is the desired behavior, where().first will order by default, but in Rails 4+ find_by does not honor that default behavior.  For this reason we left the instances of where().first unchanged.&lt;br /&gt;
&lt;br /&gt;
=== Code Improvements ===&lt;br /&gt;
&lt;br /&gt;
This refactoring was to improve readability and follow as many good ''Rubyist'' coding practices as possible without breaking the functionality of existing code. We used CodeClimate of the master branch code as a reference. We took the suggestions we got from CodeClimate and improved our code based on that.&lt;br /&gt;
We also made some of the methods shorter by removing redundant functionality and adding private methods to methods with a lot internal functionality. We also added private methods in places where we saw repeated patterns to make the code ''DRYer''.&lt;br /&gt;
At the end of our refactoring, we managed to improve the rating on CodeClimate from a '''C''' to a '''B''' . Further improvements meant reducing the size of the entire class which required a much more significant refactoring in multiple files and folders. We focused on refactoring the existing model, '''ReviewResponseMap'''.&lt;br /&gt;
&lt;br /&gt;
= Unit Tests =&lt;br /&gt;
The previous unit tests had syntactical and run time errors.  We were not able to get the previous unit tests to run without errors.  Because of this we rewrote all of the unit tests for the &amp;lt;b&amp;gt;ReviewResponseModel&amp;lt;/b&amp;gt;.  It is important to have working unit tests so that when internal changes are made to functions the external output remains the same.&lt;br /&gt;
&lt;br /&gt;
=== Refactoring of Unit Tests===&lt;br /&gt;
&lt;br /&gt;
We added a test_helper file to the main test folder that requires a needed configuration file and needed gems.  We also added 8 fixtures that were needed for data to run the unit tests.  The following fixture files were added:&lt;br /&gt;
&lt;br /&gt;
* assignment_questionnaires.yml&lt;br /&gt;
* assignments.yml&lt;br /&gt;
* participants.yml&lt;br /&gt;
* questionnaires.yml&lt;br /&gt;
* response_maps.yml&lt;br /&gt;
* responses.yml&lt;br /&gt;
* teams.yml&lt;br /&gt;
* users.yml&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
There is at least one unit test for every public method within the &amp;lt;b&amp;gt;ReviewResponseModel&amp;lt;/b&amp;gt;.  The test naming convention used is &amp;quot;method_&amp;lt;name of method that is being tested&amp;gt;&amp;quot;.  For example, the unit test for the export method is &amp;quot;method_export&amp;quot;.  If there are multiple test for one method the name of the test will include the test case after the normal naming convention.  For example, one of the unit tests for the import method checks for an invalid assignment.  The name of this method is &amp;quot;method_import_invalid_assignment&amp;quot;.  The following are the unit tests we created:&lt;br /&gt;
&lt;br /&gt;
* method_export&lt;br /&gt;
* method_get_metareview_response_maps&lt;br /&gt;
* method_get_team_response_for_round&lt;br /&gt;
* method_final_versions_from_reviewer&lt;br /&gt;
* method_import&lt;br /&gt;
* method_import_invalid_reviewee&lt;br /&gt;
* method_import_invalid_reviewer&lt;br /&gt;
* method_import_invalid_assignment&lt;br /&gt;
* method_delete&lt;br /&gt;
* method_delete_no _force&lt;br /&gt;
* method_show_feedback&lt;br /&gt;
* method_get_title&lt;br /&gt;
* method_export_fields&lt;br /&gt;
* method_questionnaire&lt;br /&gt;
* method_add_reviewer&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== How to Run Unit Tests ===&lt;br /&gt;
To run the unit tests, follow these steps:&lt;br /&gt;
&lt;br /&gt;
# Download the master branch of the repo.&lt;br /&gt;
# Setup the Databases for the test environment (we have used Zhewei's scrubbed expertiza DB )&lt;br /&gt;
#* Run the &amp;quot; rake db:create RAILS_ENV=test &amp;quot; command&lt;br /&gt;
#* Run the &amp;quot; rake db:reset RAILS_ENV=test &amp;quot; command&lt;br /&gt;
#* Scrub the DB using &amp;quot; mysql -u root expertiza_development &amp;lt; expertiza-scrubbed.sql&amp;quot;&lt;br /&gt;
#* Run the &amp;quot; rake db:migrate &amp;quot;&lt;br /&gt;
# Run &amp;quot; rake test test/unit/review_response_map_test.rb &amp;quot; in the &amp;quot;expertiza/&amp;quot; directory.&lt;br /&gt;
#* If you run into a mysql log in error go into config/database.yml and edit the mysql credentials for the test section so that it matches the local environment's mysql configuration&lt;br /&gt;
# Check if tests passed or failed.&lt;br /&gt;
&lt;br /&gt;
= Manual Test Case =&lt;br /&gt;
&lt;br /&gt;
In order to test the changes made to the ReviewResponseMap, bring up [[ http://152.46.16.195:5902/ | Expertiza]] and log in as an administrator.  Once logged in, proceed with the following steps:&lt;br /&gt;
&lt;br /&gt;
# Go to '''impersonate user''' when logged in as ''instructor6'' and type in ''student559'' (or) just log in as ''student559''. All passwords are ''password'' .&lt;br /&gt;
# Pick any assignment to view.&lt;br /&gt;
# Navigate to '''Other's work'''.&lt;br /&gt;
# Check the different reviews and metareviews. Whether they are being displayed correctly or not.&lt;br /&gt;
# Go to Edit or Give feedback and submit a feedback.&lt;br /&gt;
# Go back and check if the feedback given is displayed correctly or not.&lt;br /&gt;
# Check if author's feedback is correct or not.&lt;br /&gt;
# Go to the '''Temp''' assignment and see if the page is being displayed correctly or not (since there is no assignment submission content or reviews for that).&lt;br /&gt;
&lt;br /&gt;
''NOTE: Since this was a refactoring of the code and methods, the existing functionality was supposed to remain the same and not break for the changes we've made.''&lt;br /&gt;
&lt;br /&gt;
= References =&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;references/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;4.&amp;amp;nbsp; [https://github.com/expertiza/expertiza Expertiza Main Repo] &amp;lt;br&amp;gt;&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;5.&amp;amp;nbsp; [https://github.com/adeeshag/expertiza/blob/develop/app/models/review_response_map.rb Refactored ReviewResponseMap.rb]&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;6.&amp;amp;nbsp; [https://github.com/adeeshag/expertiza/tree/develop/test/fixtures Test Fixtures]&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;7.&amp;amp;nbsp; [https://github.com/adeeshag/expertiza/blob/develop/test/unit/review_response_map_test.rb Unit Tests]&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;8.&amp;amp;nbsp; [http://152.46.16.195:5902/ Expertiza Deployed Site]&amp;lt;br&amp;gt;&lt;/div&gt;</summary>
		<author><name>Cnbrown4</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2015/ossE1558BGJ&amp;diff=98442</id>
		<title>CSC/ECE 517 Fall 2015/ossE1558BGJ</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2015/ossE1558BGJ&amp;diff=98442"/>
		<updated>2015-11-06T20:29:50Z</updated>

		<summary type="html">&lt;p&gt;Cnbrown4: /* Code Changes */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Introduction =&lt;br /&gt;
&lt;br /&gt;
This page provides a description of the modifications and improvements made to the Expertiza project’s source code as part of an Expertiza based Open Source Software project.  Expertiza is a web based application which allows students to submit and peer-review classmates’ work, including written articles and development projects. The specific changes made during the course of this project were to the ReviewResponseMap.rb file, with additional changes made to other related files in support of refactoring ReviewResponseMap.rb.  &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
= Problem Statement =&lt;br /&gt;
&lt;br /&gt;
ReviewResponseMap is the model class used to manage the relationship between contributors, reviewers, and assignments.  The intent of the changes were to refactor the code for better readability and adherence to Ruby coding standards and best practices.  Primarily these changes involved the refactoring of overly complex methods, renaming methods for better readability, and the addition of missing unit tests.&lt;br /&gt;
&lt;br /&gt;
Project Requirements:&lt;br /&gt;
&lt;br /&gt;
# Code Climate&amp;lt;ref name=&amp;quot;Code Climate&amp;quot;&amp;gt;https://codeclimate.com&amp;lt;/ref&amp;gt; shows import method is complex, because of lots of checks. This method can be fixed by adding private methods for raising import error.&lt;br /&gt;
# Get_assessments_round_for method can be renamed to get_team_responses_for_round. Team_id private variable is not needed.&lt;br /&gt;
# metareview_response_maps rename, refactoring can be done. No need to do second iteration.&lt;br /&gt;
# write missing unit tests for existing methods.&lt;br /&gt;
&lt;br /&gt;
= Design Patterns =&lt;br /&gt;
&lt;br /&gt;
As part of our project, we refactored the model to follow the Single Responsibility and Don't Repeat Yourself (DRY) Principles.  Both of the principles focus on reducing code repetition and increasing the cohesion of the individual methods in the class.  The Single Responsibility Principle states that each class and method should have sole responsibility over one single part of the functionality of the system&amp;lt;ref&amp;gt;https://en.wikipedia.org/wiki/Single_responsibility_principle&amp;lt;/ref&amp;gt;.  The DRY principle states that whenever the same types of logic and functionality are being performed in a class the duplicated logic should be extracted into a new method that can be called in place of the repeated lines of code &amp;lt;ref&amp;gt;https://en.wikipedia.org/wiki/Don%27t_repeat_yourself&amp;lt;/ref&amp;gt;.  A prime example of a method that initially violated these principles was the import method, which in addition to performing the core import processes also performed a number of checks that would be more properly extracted into private methods.&lt;br /&gt;
&lt;br /&gt;
=Code Changes =&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Refactoring of import method ===&lt;br /&gt;
&lt;br /&gt;
CodeClimate reports showed the import method to be overly complex, with a number of checks being included within the import method itself.  The resolution for this problem was to refactor the import method, creating private methods to perform the null checks and throw import errors.  Prior to refactoring, all null checks were performed within the import method.   After refactoring, the import method adheres to the single responsibility principle, performing only key import tasks while making calls to private methods for any necessary validation. The size of the import method was reduced by doing this and counts for better readability of the code. Also, this method is a very important one and care was taken so that any existing functionality did not break. &lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
Before refactoring:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;big&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 def self.import(row, session, id)&lt;br /&gt;
    if row.length &amp;lt; 2&lt;br /&gt;
      raise ArgumentError, &amp;quot;Not enough items&amp;quot;&lt;br /&gt;
    end&lt;br /&gt;
    assignment = Assignment.find(id)&lt;br /&gt;
    if assignment.nil?&lt;br /&gt;
      raise ImportError, &amp;quot;The assignment with id \&amp;quot;#{id}\&amp;quot; was not found. &amp;lt;a href='/assignment/new'&amp;gt;Create&amp;lt;/a&amp;gt; this assignment?&amp;quot;&lt;br /&gt;
    end&lt;br /&gt;
    index = 1&lt;br /&gt;
    while index &amp;lt; row.length&lt;br /&gt;
      user = User.find_by_name(row[index].to_s.strip)&lt;br /&gt;
      if user.nil?&lt;br /&gt;
        raise ImportError, &amp;quot;The user account for the reviewer \&amp;quot;#{row[index]}\&amp;quot; was not found. &amp;lt;a href='/users/new'&amp;gt;Create&amp;lt;/a&amp;gt; this user?&amp;quot;&lt;br /&gt;
      end&lt;br /&gt;
      reviewer = AssignmentParticipant.where(user_id: user.id, parent_id:  assignment.id).first&lt;br /&gt;
      if reviewer == nil&lt;br /&gt;
        raise ImportError, &amp;quot;The reviewer \&amp;quot;#{row[index]}\&amp;quot; is not a participant in this assignment. &amp;lt;a href='/users/new'&amp;gt;Register&amp;lt;/a&amp;gt; this user as a participant?&amp;quot;&lt;br /&gt;
      end&lt;br /&gt;
      if assignment.team_assignment&lt;br /&gt;
        reviewee = AssignmentTeam.where(name: row[0].to_s.strip, parent_id:  assignment.id).first&lt;br /&gt;
        if reviewee == nil&lt;br /&gt;
          raise ImportError, &amp;quot;The author \&amp;quot;#{row[0].to_s.strip}\&amp;quot; was not found. &amp;lt;a href='/users/new'&amp;gt;Create&amp;lt;/a&amp;gt; this user?&amp;quot;&lt;br /&gt;
        end&lt;br /&gt;
        existing = ReviewResponseMap.where(reviewee_id: reviewee.id, reviewer_id:  reviewer.id).first&lt;br /&gt;
        if existing.nil?&lt;br /&gt;
          ReviewResponseMap.create(:reviewer_id =&amp;gt; reviewer.id, :reviewee_id =&amp;gt; reviewee.id, :reviewed_object_id =&amp;gt; assignment.id)&lt;br /&gt;
        end&lt;br /&gt;
      else&lt;br /&gt;
        puser = User.find_by_name(row[0].to_s.strip)&lt;br /&gt;
        if user == nil&lt;br /&gt;
          raise ImportError, &amp;quot;The user account for the reviewee \&amp;quot;#{row[0]}\&amp;quot; was not found. &amp;lt;a href='/users/new'&amp;gt;Create&amp;lt;/a&amp;gt; this user?&amp;quot;&lt;br /&gt;
        end&lt;br /&gt;
        reviewee = AssignmentParticipant.where(user_id: puser.id, parent_id:  assignment.id).first&lt;br /&gt;
        if reviewee == nil&lt;br /&gt;
          raise ImportError, &amp;quot;The author \&amp;quot;#{row[0].to_s.strip}\&amp;quot; was not found. &amp;lt;a href='/users/new'&amp;gt;Create&amp;lt;/a&amp;gt; this user?&amp;quot;&lt;br /&gt;
        end&lt;br /&gt;
        team_id = TeamsUser.team_id(reviewee.parent_id, reviewee.user_id)&lt;br /&gt;
        existing = ReviewResponseMap.where(reviewee_id: team_id, reviewer_id:  reviewer.id).first&lt;br /&gt;
        if existing.nil?&lt;br /&gt;
          ReviewResponseMap.create(:reviewee_id =&amp;gt; team_id, :reviewer_id =&amp;gt; reviewer.id, :reviewed_object_id =&amp;gt; assignment.id)&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
      index += 1&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
&lt;br /&gt;
After refactoring:&lt;br /&gt;
 &lt;br /&gt;
  &amp;lt;big&amp;gt;&amp;lt;nowiki&amp;gt;#Imports new reponse maps if they do not already exist&lt;br /&gt;
  def self.import(row, _session, id)&lt;br /&gt;
      if row.length &amp;lt; 2&lt;br /&gt;
          raise ArgumentError, 'Not enough items'&lt;br /&gt;
      end&lt;br /&gt;
      assignment = find_assignment(id)&lt;br /&gt;
      index = 1&lt;br /&gt;
      reviewee_name = row[0]&lt;br /&gt;
      while index &amp;lt; row.length&lt;br /&gt;
          reviewee_id = nil&lt;br /&gt;
          reviewer_name = row[index]&lt;br /&gt;
          reviewer = get_assignment_participant(reviewer_name,  assignment.id, &amp;quot;reviewer&amp;quot;)&lt;br /&gt;
          participant_nil?(reviewer, reviewer_name , &amp;quot;reviewer&amp;quot;)&lt;br /&gt;
         &lt;br /&gt;
         #Find reviewee if assignment is a team assignment&lt;br /&gt;
         if assignment.team_assignment&lt;br /&gt;
             reviewee = AssignmentTeam.where(name: reviewee_name .to_s.strip, parent_id: assignment.id).first&lt;br /&gt;
             participant_nil?(reviewee, reviewee_name, &amp;quot;author&amp;quot;)&lt;br /&gt;
             reviewee_id = reviewee.id&lt;br /&gt;
         #Find reviewee if assignment is not a team assignment&lt;br /&gt;
         else&lt;br /&gt;
	     reviewee = get_assignment_participant(reviewee_name, assignment.id, &amp;quot;reviewee&amp;quot;)&lt;br /&gt;
             participant_nil?(reviewee, reviewee_name, &amp;quot;author&amp;quot;)&lt;br /&gt;
             reviewee_id  = TeamsUser.team_id(reviewee.parent_id, reviewee.user_id)&lt;br /&gt;
         end&lt;br /&gt;
         create_response_map(reviewer, reviewee_id,  assignment)&lt;br /&gt;
         index += 1&lt;br /&gt;
      end&lt;br /&gt;
  end&amp;lt;/nowiki&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Private methods added:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;big&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  # Check for if assignment value is null&lt;br /&gt;
  def self.find_assignment(id)&lt;br /&gt;
      begin&lt;br /&gt;
          assignment = Assignment.find(id)&lt;br /&gt;
      rescue ActiveRecord::RecordNotFound&lt;br /&gt;
          raise ImportError, &amp;quot;The assignment with id \&amp;quot;#{id}\&amp;quot; was not found.&amp;lt;a href='/assignment/new'&amp;gt;Create&amp;lt;/a&amp;gt; this assignment?&amp;quot;&lt;br /&gt;
      end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  # Check for if participant is null&lt;br /&gt;
  def self.participant_nil?(participant, user_name, participant_type) &lt;br /&gt;
      error_message = nil&lt;br /&gt;
      if participant_type == &amp;quot;author&amp;quot;&lt;br /&gt;
          error_message = &amp;quot;The author \&amp;quot;#{user_name.to_s.strip}\&amp;quot; was not found.&amp;lt;a href='/users/new'&amp;gt;Create&amp;lt;/a&amp;gt; this user?&amp;quot;&lt;br /&gt;
      else&lt;br /&gt;
          error_message =  &amp;quot;The reviewer \&amp;quot;#{user_name}\&amp;quot; is not a participant in this assignment.&amp;lt;a href='/users/new'&amp;gt;Register&amp;lt;/a&amp;gt; this user as a participant?&amp;quot;&lt;br /&gt;
      end&lt;br /&gt;
      check_nil?(participant, error_message)&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  # Check for if user is null&lt;br /&gt;
  def self.user_nil?(user, user_name, user_type)&lt;br /&gt;
      check_nil?( user, &amp;quot;The user account for the \&amp;quot;#{user_type}\&amp;quot; \&amp;quot;#{user_name}\&amp;quot; was not found.&amp;lt;a href='/users/new'&amp;gt;Create&amp;lt;/a&amp;gt; this user?&amp;quot;)&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
 #Throws import error for nil objects&lt;br /&gt;
  def self.check_nil?(object, error_message)&lt;br /&gt;
      if object.nil?&lt;br /&gt;
          raise ImportError, error_message&lt;br /&gt;
      end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Refactoring of get_assessments_round_for method ===&lt;br /&gt;
&lt;br /&gt;
The get_assessments_round_for method’s name failed to provide a clear idea of the method’s purpose and functionality.  This is why it was renamed to get_team_responses_for_round, the new name of the method provides a clearer idea of its purpose. Additionally, there was a private variable, team_id, introduced in the method that was unnecessary and could be replaced by using the id property of the team parameter directly.  We also removed the return statement at the end of the method.  &lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
Before refactoring:&lt;br /&gt;
&amp;lt;big&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  def self.get_assessments_round_for(team,round)&lt;br /&gt;
    team_id =team.id&lt;br /&gt;
    responses = Array.new&lt;br /&gt;
    if team_id&lt;br /&gt;
      maps = ResponseMap.where(:reviewee_id =&amp;gt; team_id, :type =&amp;gt; &amp;quot;ReviewResponseMap&amp;quot;)&lt;br /&gt;
      maps.each{ |map|&lt;br /&gt;
        if !map.response.empty? &amp;amp;&amp;amp; !map.response.reject{|r| r.round!=round}.empty?&lt;br /&gt;
          responses &amp;lt;&amp;lt; map.response.reject{|r| r.round!=round}.last&lt;br /&gt;
        end&lt;br /&gt;
      }&lt;br /&gt;
      responses.sort! {|a,b| a.map.reviewer.fullname &amp;lt;=&amp;gt; b.map.reviewer.fullname }&lt;br /&gt;
    end&lt;br /&gt;
    return responses&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
&lt;br /&gt;
After refactoring: &lt;br /&gt;
&lt;br /&gt;
&amp;lt;big&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  def self.get_team_responses_for_round(team, round)&lt;br /&gt;
    responses = []&lt;br /&gt;
    if team.id&lt;br /&gt;
      maps = ResponseMap.where(reviewee_id: team.id, type: 'ReviewResponseMap')&lt;br /&gt;
      maps.each do |map|&lt;br /&gt;
        unless map.response.empty? &amp;amp;&amp;amp; map.response.reject { |r| r.round != round }.empty?&lt;br /&gt;
          responses &amp;lt;&amp;lt; map.response.reject { |r| r.round != round }.last&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
      responses.sort! { |a, b| a.map.reviewer.fullname &amp;lt;=&amp;gt; b.map.reviewer.fullname }&lt;br /&gt;
    end&lt;br /&gt;
    responses&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
The change in method name also required changes to the following files that referenced it:&lt;br /&gt;
&lt;br /&gt;
/app/models/assignment.rb:436:    &lt;br /&gt;
 &lt;br /&gt;
&amp;lt;big&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  assessments = ReviewResponseMap.get_assessments_round_for(team,i)&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt; &lt;br /&gt;
&lt;br /&gt;
./app/models/assignment_participant.rb:268:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;big&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 scores[questionnaire_symbol][:assessments] = questionnaire.get_assessments_round_for(self,round)&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Refactoring of metareview_response_maps method ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The metareview_response_maps method was unnecessarily complex.  It contained an unneeded private variable and an unnecessary nested loop.  Originally, it added each metareview map individually in the nested loop.  We decided to remove the nested loop and use the concat method for readability and maintainability.  These changes allowed us to remove the private variable &amp;quot;metareview_list&amp;quot; and only maintain the &amp;quot;metareview_response_maps&amp;quot; variable.  We also renamed the metareview_response_maps method to get_metareview_response_maps method to be more descriptive about the intent of the method. &lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
Before refactoring:&lt;br /&gt;
&amp;lt;big&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 def metareview_response_maps&lt;br /&gt;
    responses = Response.where(map_id:self.id)&lt;br /&gt;
    metareview_list=[]&lt;br /&gt;
    responses.each do |response|&lt;br /&gt;
      metareview_response_maps = MetareviewResponseMap.where(reviewed_object_id:response.id)&lt;br /&gt;
      metareview_response_maps.each do |metareview_response_map|&lt;br /&gt;
        metareview_list&amp;lt;&amp;lt;metareview_response_map&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
    metareview_list&lt;br /&gt;
 end&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
After refactoring:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;big&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  def get_metareview_response_maps&lt;br /&gt;
    responses = Response.where(map_id: id)&lt;br /&gt;
    metareview_response_maps = []&lt;br /&gt;
    responses.each do |response|&lt;br /&gt;
      metareview_response_maps.concat MetareviewResponseMap.where(reviewed_object_id: response.id)&lt;br /&gt;
    end&lt;br /&gt;
    metareview_response_maps&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Refactoring of other methods ===&lt;br /&gt;
Although trivial, we removed the return statement from the get_title, export_fields, and show_feedback methods because return statements are unnecessary in Ruby.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Addition of code comments ===&lt;br /&gt;
&lt;br /&gt;
We added comments to all of the methods in the ReviewResponseMap.rb file and corrected instances where CodeClimate Identified opportunities for code improvement.  One issue flagged by CodeClimate that we did not change was to use the find_by method instead of where().first method.  The where().first method occurs in the import, get_assignment_participant, and create_response_map methods. It is not always appropriate to use the find_by method, as documented in this github post: https://github.com/bbatsov/rubocop/issues/1938 .  In instances where ordering by id is the desired behavior, where().first will order by default, but in Rails 4+ find_by does not honor that default behavior.  For this reason we left the instances of where().first unchanged.&lt;br /&gt;
&lt;br /&gt;
=== Code Improvements ===&lt;br /&gt;
&lt;br /&gt;
This refactoring was to improve readability and follow as many good ''Rubyist'' coding practices as possible without breaking the functionality of existing code. We used CodeClimate of the master branch code as a reference. We took the suggestions we got from CodeClimate and improved our code based on that.&lt;br /&gt;
We also made some of the methods shorter by removing redundant functionality and adding private methods to methods with a lot internal functionality. We also added private methods in places where we saw repeated patterns to make the code ''DRYer''.&lt;br /&gt;
At the end of our refactoring, we managed to improve the rating on CodeClimate from a '''C''' to a '''B''' . Further improvements meant reducing the size of the entire class which required a much more significant refactoring in multiple files and folders. We focused on refactoring the existing model, '''ReviewResponseMap'''.&lt;br /&gt;
&lt;br /&gt;
= Unit Tests =&lt;br /&gt;
The previous unit tests had syntactical and run time errors.  We were not able to get the previous unit tests to run without errors.  Because of this we rewrote all of the unit tests for the &amp;lt;b&amp;gt;ReviewResponseModel&amp;lt;/b&amp;gt;.  It is important to have working unit tests so that when internal changes are made to functions the external output remains the same.&lt;br /&gt;
&lt;br /&gt;
=== Refactoring of Unit Tests===&lt;br /&gt;
&lt;br /&gt;
We added a test_helper file to the main test folder that requires a needed configuration file and needed gems.  We also added 8 fixtures that were needed for data to run the unit tests.  The following fixture files were added:&lt;br /&gt;
&lt;br /&gt;
* assignment_questionnaires.yml&lt;br /&gt;
* assignments.yml&lt;br /&gt;
* participants.yml&lt;br /&gt;
* questionnaires.yml&lt;br /&gt;
* response_maps.yml&lt;br /&gt;
* responses.yml&lt;br /&gt;
* teams.yml&lt;br /&gt;
* users.yml&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
There is at least one unit test for every public method within the &amp;lt;b&amp;gt;ReviewResponseModel&amp;lt;/b&amp;gt;.  The test naming convention used is &amp;quot;method_&amp;lt;name of method that is being tested&amp;gt;&amp;quot;.  For example, the unit test for the export method is &amp;quot;method_export&amp;quot;.  If there are multiple test for one method the name of the test will include the test case after the normal naming convention.  For example, one of the unit tests for the import method checks for an invalid assignment.  The name of this method is &amp;quot;method_import_invalid_assignment&amp;quot;.  The following are the unit tests we created:&lt;br /&gt;
&lt;br /&gt;
* method_export&lt;br /&gt;
* method_get_metareview_response_maps&lt;br /&gt;
* method_get_team_response_for_round&lt;br /&gt;
* method_final_versions_from_reviewer&lt;br /&gt;
* method_import&lt;br /&gt;
* method_import_invalid_reviewee&lt;br /&gt;
* method_import_invalid_reviewer&lt;br /&gt;
* method_import_invalid_assignment&lt;br /&gt;
* method_delete&lt;br /&gt;
* method_delete_no _force&lt;br /&gt;
* method_show_feedback&lt;br /&gt;
* method_get_title&lt;br /&gt;
* method_export_fields&lt;br /&gt;
* method_questionnaire&lt;br /&gt;
* method_add_reviewer&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== How to Run Unit Tests ===&lt;br /&gt;
To run the unit tests, follow these steps:&lt;br /&gt;
&lt;br /&gt;
# Download the master branch of the repo.&lt;br /&gt;
# Setup the Databases for the test environment (we have used Zhewei's scrubbed expertiza DB )&lt;br /&gt;
#* Run the &amp;quot; rake db:create RAILS_ENV=test &amp;quot; command&lt;br /&gt;
#* Run the &amp;quot; rake db:reset RAILS_ENV=test &amp;quot; command&lt;br /&gt;
#* Scrub the DB using &amp;quot; mysql -u root expertiza_development &amp;lt; expertiza-scrubbed.sql&amp;quot;&lt;br /&gt;
#* Run the &amp;quot; rake db:migrate &amp;quot;&lt;br /&gt;
# Run &amp;quot; rake test test/unit/review_response_map_test.rb &amp;quot; in the &amp;quot;expertiza/&amp;quot; directory.&lt;br /&gt;
#* If you run into a mysql log in error go into config/database.yml and edit the mysql credentials for the test section so that it matches the local environment's mysql configuration&lt;br /&gt;
# Check if tests passed or failed.&lt;br /&gt;
&lt;br /&gt;
= Manual Test Case =&lt;br /&gt;
&lt;br /&gt;
In order to test the changes made to the ReviewResponseMap, bring up [[ http://152.46.16.195:5902/ | Expertiza]] and log in as an administrator.  Once logged in, proceed with the following steps:&lt;br /&gt;
&lt;br /&gt;
# Go to '''impersonate user''' when logged in as ''instructor6'' and type in ''student559'' (or) just log in as ''student559''. All passwords are ''password'' .&lt;br /&gt;
# Pick any assignment to view.&lt;br /&gt;
# Navigate to '''Other's work'''.&lt;br /&gt;
# Check the different reviews and metareviews. Whether they are being displayed correctly or not.&lt;br /&gt;
# Go to Edit or Give feedback and submit a feedback.&lt;br /&gt;
# Go back and check if the feedback given is displayed correctly or not.&lt;br /&gt;
# Check if author's feedback is correct or not.&lt;br /&gt;
# Go to the '''Temp''' assignment and see if the page is being displayed correctly or not (since there is no assignment submission content or reviews for that).&lt;br /&gt;
&lt;br /&gt;
''NOTE: Since this was a refactoring of the code and methods, the existing functionality was supposed to remain the same and not break for the changes we've made.''&lt;br /&gt;
&lt;br /&gt;
= References =&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;references/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;4.&amp;amp;nbsp; [https://github.com/expertiza/expertiza Expertiza Main Repo] &amp;lt;br&amp;gt;&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;5.&amp;amp;nbsp; [https://github.com/adeeshag/expertiza/blob/develop/app/models/review_response_map.rb Refactored ReviewResponseMap.rb]&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;6.&amp;amp;nbsp; [https://github.com/adeeshag/expertiza/tree/develop/test/fixtures Test Fixtures]&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;7.&amp;amp;nbsp; [https://github.com/adeeshag/expertiza/blob/develop/test/unit/review_response_map_test.rb Unit Tests]&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;8.&amp;amp;nbsp; [http://152.46.16.195:5902/ Expertiza Deployed Site]&amp;lt;br&amp;gt;&lt;/div&gt;</summary>
		<author><name>Cnbrown4</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2015/ossE1558BGJ&amp;diff=98438</id>
		<title>CSC/ECE 517 Fall 2015/ossE1558BGJ</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2015/ossE1558BGJ&amp;diff=98438"/>
		<updated>2015-11-06T20:06:27Z</updated>

		<summary type="html">&lt;p&gt;Cnbrown4: /* Manual Test Case */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Introduction =&lt;br /&gt;
&lt;br /&gt;
This page provides a description of the modifications and improvements made to the Expertiza project’s source code as part of an Expertiza based Open Source Software project.  Expertiza is a web based application which allows students to submit and peer-review classmates’ work, including written articles and development projects. The specific changes made during the course of this project were to the ReviewResponseMap.rb file, with additional changes made to other related files in support of refactoring ReviewResponseMap.rb.  &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
= Problem Statement =&lt;br /&gt;
&lt;br /&gt;
ReviewResponseMap is the model class used to manage the relationship between contributors, reviewers, and assignments.  The intent of the changes were to refactor the code for better readability and adherence to Ruby coding standards and best practices.  Primarily these changes involved the refactoring of overly complex methods, renaming methods for better readability, and the addition of missing unit tests.&lt;br /&gt;
&lt;br /&gt;
Project Requirements:&lt;br /&gt;
&lt;br /&gt;
# Code Climate&amp;lt;ref name=&amp;quot;Code Climate&amp;quot;&amp;gt;https://codeclimate.com&amp;lt;/ref&amp;gt; shows import method is complex, because of lots of checks. This method can be fixed by adding private methods for raising import error.&lt;br /&gt;
# Get_assessments_round_for method can be renamed to get_team_responses_for_round. Team_id private variable is not needed.&lt;br /&gt;
# metareview_response_maps rename, refactoring can be done. No need to do second iteration.&lt;br /&gt;
# write missing unit tests for existing methods.&lt;br /&gt;
&lt;br /&gt;
= Design Patterns =&lt;br /&gt;
&lt;br /&gt;
As part of our project, we refactored the model to follow the Single Responsibility and Don't Repeat Yourself (DRY) Principles.  Both of the principles focus on reducing code repetition and increasing the cohesion of the individual methods in the class.  The Single Responsibility Principle states that each class and method should have sole responsibility over one single part of the functionality of the system&amp;lt;ref&amp;gt;https://en.wikipedia.org/wiki/Single_responsibility_principle&amp;lt;/ref&amp;gt;.  The DRY principle states that whenever the same types of logic and functionality are being performed in a class the duplicated logic should be extracted into a new method that can be called in place of the repeated lines of code &amp;lt;ref&amp;gt;https://en.wikipedia.org/wiki/Don%27t_repeat_yourself&amp;lt;/ref&amp;gt;.  A prime example of a method that initially violated these principles was the import method, which in addition to performing the core import processes also performed a number of checks that would be more properly extracted into private methods.&lt;br /&gt;
&lt;br /&gt;
=Code Changes =&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Refactoring of import method ===&lt;br /&gt;
&lt;br /&gt;
CodeClimate reports showed the import method to be overly complex, with a number of checks being included within the import method itself.  The resolution for this problem was to refactor the import method, creating private methods to perform the null checks and throw import errors.  Prior to refactoring, all null checks were performed within the import method.   After refactoring, the import method adheres to the single responsibility principle, performing only key import tasks while making calls to private methods for any necessary validation. The size of the import method was reduced by doing this and counts for better readability of the code. Also, this method is a very important one and care was taken so that any existing functionality did not break. &lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
Before refactoring:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;big&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 def self.import(row, session, id)&lt;br /&gt;
    if row.length &amp;lt; 2&lt;br /&gt;
      raise ArgumentError, &amp;quot;Not enough items&amp;quot;&lt;br /&gt;
    end&lt;br /&gt;
    assignment = Assignment.find(id)&lt;br /&gt;
    if assignment.nil?&lt;br /&gt;
      raise ImportError, &amp;quot;The assignment with id \&amp;quot;#{id}\&amp;quot; was not found. &amp;lt;a href='/assignment/new'&amp;gt;Create&amp;lt;/a&amp;gt; this assignment?&amp;quot;&lt;br /&gt;
    end&lt;br /&gt;
    index = 1&lt;br /&gt;
    while index &amp;lt; row.length&lt;br /&gt;
      user = User.find_by_name(row[index].to_s.strip)&lt;br /&gt;
      if user.nil?&lt;br /&gt;
        raise ImportError, &amp;quot;The user account for the reviewer \&amp;quot;#{row[index]}\&amp;quot; was not found. &amp;lt;a href='/users/new'&amp;gt;Create&amp;lt;/a&amp;gt; this user?&amp;quot;&lt;br /&gt;
      end&lt;br /&gt;
      reviewer = AssignmentParticipant.where(user_id: user.id, parent_id:  assignment.id).first&lt;br /&gt;
      if reviewer == nil&lt;br /&gt;
        raise ImportError, &amp;quot;The reviewer \&amp;quot;#{row[index]}\&amp;quot; is not a participant in this assignment. &amp;lt;a href='/users/new'&amp;gt;Register&amp;lt;/a&amp;gt; this user as a participant?&amp;quot;&lt;br /&gt;
      end&lt;br /&gt;
      if assignment.team_assignment&lt;br /&gt;
        reviewee = AssignmentTeam.where(name: row[0].to_s.strip, parent_id:  assignment.id).first&lt;br /&gt;
        if reviewee == nil&lt;br /&gt;
          raise ImportError, &amp;quot;The author \&amp;quot;#{row[0].to_s.strip}\&amp;quot; was not found. &amp;lt;a href='/users/new'&amp;gt;Create&amp;lt;/a&amp;gt; this user?&amp;quot;&lt;br /&gt;
        end&lt;br /&gt;
        existing = ReviewResponseMap.where(reviewee_id: reviewee.id, reviewer_id:  reviewer.id).first&lt;br /&gt;
        if existing.nil?&lt;br /&gt;
          ReviewResponseMap.create(:reviewer_id =&amp;gt; reviewer.id, :reviewee_id =&amp;gt; reviewee.id, :reviewed_object_id =&amp;gt; assignment.id)&lt;br /&gt;
        end&lt;br /&gt;
      else&lt;br /&gt;
        puser = User.find_by_name(row[0].to_s.strip)&lt;br /&gt;
        if user == nil&lt;br /&gt;
          raise ImportError, &amp;quot;The user account for the reviewee \&amp;quot;#{row[0]}\&amp;quot; was not found. &amp;lt;a href='/users/new'&amp;gt;Create&amp;lt;/a&amp;gt; this user?&amp;quot;&lt;br /&gt;
        end&lt;br /&gt;
        reviewee = AssignmentParticipant.where(user_id: puser.id, parent_id:  assignment.id).first&lt;br /&gt;
        if reviewee == nil&lt;br /&gt;
          raise ImportError, &amp;quot;The author \&amp;quot;#{row[0].to_s.strip}\&amp;quot; was not found. &amp;lt;a href='/users/new'&amp;gt;Create&amp;lt;/a&amp;gt; this user?&amp;quot;&lt;br /&gt;
        end&lt;br /&gt;
        team_id = TeamsUser.team_id(reviewee.parent_id, reviewee.user_id)&lt;br /&gt;
        existing = ReviewResponseMap.where(reviewee_id: team_id, reviewer_id:  reviewer.id).first&lt;br /&gt;
        if existing.nil?&lt;br /&gt;
          ReviewResponseMap.create(:reviewee_id =&amp;gt; team_id, :reviewer_id =&amp;gt; reviewer.id, :reviewed_object_id =&amp;gt; assignment.id)&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
      index += 1&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
&lt;br /&gt;
After refactoring:&lt;br /&gt;
 &lt;br /&gt;
  &amp;lt;big&amp;gt;&amp;lt;nowiki&amp;gt;#Imports new reponse maps if they do not already exist&lt;br /&gt;
  def self.import(row, _session, id)&lt;br /&gt;
      if row.length &amp;lt; 2&lt;br /&gt;
          raise ArgumentError, 'Not enough items'&lt;br /&gt;
      end&lt;br /&gt;
      assignment = find_assignment(id)&lt;br /&gt;
      index = 1&lt;br /&gt;
      reviewee_name = row[0]&lt;br /&gt;
      while index &amp;lt; row.length&lt;br /&gt;
          reviewee_id = nil&lt;br /&gt;
          reviewer_name = row[index]&lt;br /&gt;
          reviewer = get_assignment_participant(reviewer_name,  assignment.id, &amp;quot;reviewer&amp;quot;)&lt;br /&gt;
          participant_nil?(reviewer, reviewer_name , &amp;quot;reviewer&amp;quot;)&lt;br /&gt;
         &lt;br /&gt;
         #Find reviewee if assignment is a team assignment&lt;br /&gt;
         if assignment.team_assignment&lt;br /&gt;
             reviewee = AssignmentTeam.where(name: reviewee_name .to_s.strip, parent_id: assignment.id).first&lt;br /&gt;
             participant_nil?(reviewee, reviewee_name, &amp;quot;author&amp;quot;)&lt;br /&gt;
             reviewee_id = reviewee.id&lt;br /&gt;
         #Find reviewee if assignment is not a team assignment&lt;br /&gt;
         else&lt;br /&gt;
	     reviewee = get_assignment_participant(reviewee_name, assignment.id, &amp;quot;reviewee&amp;quot;)&lt;br /&gt;
             participant_nil?(reviewee, reviewee_name, &amp;quot;author&amp;quot;)&lt;br /&gt;
             reviewee_id  = TeamsUser.team_id(reviewee.parent_id, reviewee.user_id)&lt;br /&gt;
         end&lt;br /&gt;
         create_response_map(reviewer, reviewee_id,  assignment)&lt;br /&gt;
         index += 1&lt;br /&gt;
      end&lt;br /&gt;
  end&amp;lt;/nowiki&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Private methods added:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;big&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  # Check for if assignment value is null&lt;br /&gt;
  def self.find_assignment(id)&lt;br /&gt;
      begin&lt;br /&gt;
          assignment = Assignment.find(id)&lt;br /&gt;
      rescue ActiveRecord::RecordNotFound&lt;br /&gt;
          raise ImportError, &amp;quot;The assignment with id \&amp;quot;#{id}\&amp;quot; was not found.&amp;lt;a href='/assignment/new'&amp;gt;Create&amp;lt;/a&amp;gt; this assignment?&amp;quot;&lt;br /&gt;
      end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  # Check for if participant is null&lt;br /&gt;
  def self.participant_nil?(participant, user_name, participant_type) &lt;br /&gt;
      error_message = nil&lt;br /&gt;
      if participant_type == &amp;quot;author&amp;quot;&lt;br /&gt;
          error_message = &amp;quot;The author \&amp;quot;#{user_name.to_s.strip}\&amp;quot; was not found.&amp;lt;a href='/users/new'&amp;gt;Create&amp;lt;/a&amp;gt; this user?&amp;quot;&lt;br /&gt;
      else&lt;br /&gt;
          error_message =  &amp;quot;The reviewer \&amp;quot;#{user_name}\&amp;quot; is not a participant in this assignment.&amp;lt;a href='/users/new'&amp;gt;Register&amp;lt;/a&amp;gt; this user as a participant?&amp;quot;&lt;br /&gt;
      end&lt;br /&gt;
      check_nil?(participant, error_message)&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  # Check for if user is null&lt;br /&gt;
  def self.user_nil?(user, user_name, user_type)&lt;br /&gt;
      check_nil?( user, &amp;quot;The user account for the \&amp;quot;#{user_type}\&amp;quot; \&amp;quot;#{user_name}\&amp;quot; was not found.&amp;lt;a href='/users/new'&amp;gt;Create&amp;lt;/a&amp;gt; this user?&amp;quot;)&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
 #Throws import error for nil objects&lt;br /&gt;
  def self.check_nil?(object, error_message)&lt;br /&gt;
      if object.nil?&lt;br /&gt;
          raise ImportError, error_message&lt;br /&gt;
      end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Refactoring of get_assessments_round_for method ===&lt;br /&gt;
&lt;br /&gt;
The get_assessments_round_for method’s name failed to provide a clear idea of the method’s purpose and functionality.  This is why it was renamed to get_team_responses_for_round, the new name of the method provides a clearer idea of its purpose. Additionally, there was a private variable, team_id, introduced in the method that was unnecessary and could be replaced by using the id property of the team parameter directly.  &lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
Before refactoring:&lt;br /&gt;
&amp;lt;big&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  def self.get_assessments_round_for(team,round)&lt;br /&gt;
    team_id =team.id&lt;br /&gt;
    responses = Array.new&lt;br /&gt;
    if team_id&lt;br /&gt;
      maps = ResponseMap.where(:reviewee_id =&amp;gt; team_id, :type =&amp;gt; &amp;quot;ReviewResponseMap&amp;quot;)&lt;br /&gt;
      maps.each{ |map|&lt;br /&gt;
        if !map.response.empty? &amp;amp;&amp;amp; !map.response.reject{|r| r.round!=round}.empty?&lt;br /&gt;
          responses &amp;lt;&amp;lt; map.response.reject{|r| r.round!=round}.last&lt;br /&gt;
        end&lt;br /&gt;
      }&lt;br /&gt;
      responses.sort! {|a,b| a.map.reviewer.fullname &amp;lt;=&amp;gt; b.map.reviewer.fullname }&lt;br /&gt;
    end&lt;br /&gt;
    return responses&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
&lt;br /&gt;
After refactoring: &lt;br /&gt;
&lt;br /&gt;
&amp;lt;big&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  def self.get_team_responses_for_round(team, round)&lt;br /&gt;
    responses = []&lt;br /&gt;
    if team.id&lt;br /&gt;
      maps = ResponseMap.where(reviewee_id: team.id, type: 'ReviewResponseMap')&lt;br /&gt;
      maps.each do |map|&lt;br /&gt;
        unless map.response.empty? &amp;amp;&amp;amp; map.response.reject { |r| r.round != round }.empty?&lt;br /&gt;
          responses &amp;lt;&amp;lt; map.response.reject { |r| r.round != round }.last&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
      responses.sort! { |a, b| a.map.reviewer.fullname &amp;lt;=&amp;gt; b.map.reviewer.fullname }&lt;br /&gt;
    end&lt;br /&gt;
    responses&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
The change in method name also required changes to the following files that referenced it:&lt;br /&gt;
&lt;br /&gt;
/app/models/assignment.rb:436:    &lt;br /&gt;
 &lt;br /&gt;
&amp;lt;big&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  assessments = ReviewResponseMap.get_assessments_round_for(team,i)&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt; &lt;br /&gt;
&lt;br /&gt;
./app/models/assignment_participant.rb:268:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;big&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 scores[questionnaire_symbol][:assessments] = questionnaire.get_assessments_round_for(self,round)&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Refactoring of metareview_response_maps method ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The metareview_response_maps method was unnecessarily complex.  It contained an unneeded private variable and an unnecessary nested loop.  Originally, it added each metareview map individually in the nested loop.  We decided to remove the nested loop and use the concat method for readability and maintainability.  These changes allowed us to remove the private variable &amp;quot;metareview_list&amp;quot; and only maintain the &amp;quot;metareview_response_maps&amp;quot; variable.  We also renamed the metareview_response_maps method to get_metareview_response_maps method to be more descriptive about the intent of the method. &lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
Before refactoring:&lt;br /&gt;
&amp;lt;big&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 def metareview_response_maps&lt;br /&gt;
    responses = Response.where(map_id:self.id)&lt;br /&gt;
    metareview_list=[]&lt;br /&gt;
    responses.each do |response|&lt;br /&gt;
      metareview_response_maps = MetareviewResponseMap.where(reviewed_object_id:response.id)&lt;br /&gt;
      metareview_response_maps.each do |metareview_response_map|&lt;br /&gt;
        metareview_list&amp;lt;&amp;lt;metareview_response_map&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
    metareview_list&lt;br /&gt;
 end&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
After refactoring:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;big&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  def get_metareview_response_maps&lt;br /&gt;
    responses = Response.where(map_id: id)&lt;br /&gt;
    metareview_response_maps = []&lt;br /&gt;
    responses.each do |response|&lt;br /&gt;
      metareview_response_maps.concat MetareviewResponseMap.where(reviewed_object_id: response.id)&lt;br /&gt;
    end&lt;br /&gt;
    metareview_response_maps&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Addition of code comments ===&lt;br /&gt;
&lt;br /&gt;
We added comments to all of the methods in the ReviewResponseMap.rb file and corrected instances where CodeClimate Identified opportunities for code improvement.  One issue flagged by CodeClimate that we did not change was to use the find_by method instead of where().first method.  The where().first method occurs in the import, get_assignment_participant, and create_response_map methods. It is not always appropriate to use the find_by method, as documented in this github post: https://github.com/bbatsov/rubocop/issues/1938 .  In instances where ordering by id is the desired behavior, where().first will order by default, but in Rails 4+ find_by does not honor that default behavior.  For this reason we left the instances of where().first unchanged.&lt;br /&gt;
&lt;br /&gt;
=== Code Improvements ===&lt;br /&gt;
&lt;br /&gt;
This refactoring was to improve readability and follow as many good ''Rubyist'' coding practices as possible without breaking the functionality of existing code. We used CodeClimate of the master branch code as a reference. We took the suggestions we got from CodeClimate and improved our code based on that.&lt;br /&gt;
We also made some of the methods shorter by removing redundant functionality and adding private methods to methods with a lot internal functionality. We also added private methods in places where we saw repeated patterns to make the code ''DRYer''.&lt;br /&gt;
At the end of our refactoring, we managed to improve the rating on CodeClimate from a '''C''' to a '''B''' . Further improvements meant reducing the size of the entire class which required a much more significant refactoring in multiple files and folders. We focused on refactoring the existing model, '''ReviewResponseMap'''.&lt;br /&gt;
&lt;br /&gt;
= Unit Tests =&lt;br /&gt;
The previous unit tests had syntactical and run time errors.  We were not able to get the previous unit tests to run without errors.  Because of this we rewrote all of the unit tests for the &amp;lt;b&amp;gt;ReviewResponseModel&amp;lt;/b&amp;gt;.  It is important to have working unit tests so that when internal changes are made to functions the external output remains the same.&lt;br /&gt;
&lt;br /&gt;
=== Refactoring of Unit Tests===&lt;br /&gt;
&lt;br /&gt;
We added a test_helper file to the main test folder that requires a needed configuration file and needed gems.  We also added 8 fixtures that were needed for data to run the unit tests.  The following fixture files were added:&lt;br /&gt;
&lt;br /&gt;
* assignment_questionnaires.yml&lt;br /&gt;
* assignments.yml&lt;br /&gt;
* participants.yml&lt;br /&gt;
* questionnaires.yml&lt;br /&gt;
* response_maps.yml&lt;br /&gt;
* responses.yml&lt;br /&gt;
* teams.yml&lt;br /&gt;
* users.yml&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
There is at least one unit test for every public method within the &amp;lt;b&amp;gt;ReviewResponseModel&amp;lt;/b&amp;gt;.  The test naming convention used is &amp;quot;method_&amp;lt;name of method that is being tested&amp;gt;&amp;quot;.  For example, the unit test for the export method is &amp;quot;method_export&amp;quot;.  If there are multiple test for one method the name of the test will include the test case after the normal naming convention.  For example, one of the unit tests for the import method checks for an invalid assignment.  The name of this method is &amp;quot;method_import_invalid_assignment&amp;quot;.  The following are the unit tests we created:&lt;br /&gt;
&lt;br /&gt;
* method_export&lt;br /&gt;
* method_get_metareview_response_maps&lt;br /&gt;
* method_get_team_response_for_round&lt;br /&gt;
* method_final_versions_from_reviewer&lt;br /&gt;
* method_import&lt;br /&gt;
* method_import_invalid_reviewee&lt;br /&gt;
* method_import_invalid_reviewer&lt;br /&gt;
* method_import_invalid_assignment&lt;br /&gt;
* method_delete&lt;br /&gt;
* method_delete_no _force&lt;br /&gt;
* method_show_feedback&lt;br /&gt;
* method_get_title&lt;br /&gt;
* method_export_fields&lt;br /&gt;
* method_questionnaire&lt;br /&gt;
* method_add_reviewer&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== How to Run Unit Tests ===&lt;br /&gt;
To run the unit tests, follow these steps:&lt;br /&gt;
&lt;br /&gt;
# Download the master branch of the repo.&lt;br /&gt;
# Setup the Databases for the test environment (we have used Zhewei's scrubbed expertiza DB )&lt;br /&gt;
#* Run the &amp;quot; rake db:create RAILS_ENV=test &amp;quot; command&lt;br /&gt;
#* Run the &amp;quot; rake db:reset RAILS_ENV=test &amp;quot; command&lt;br /&gt;
#* Scrub the DB using &amp;quot; mysql -u root expertiza_development &amp;lt; expertiza-scrubbed.sql&amp;quot;&lt;br /&gt;
#* Run the &amp;quot; rake db:migrate &amp;quot;&lt;br /&gt;
# Run &amp;quot; rake test test/unit/review_response_map_test.rb &amp;quot; in the &amp;quot;expertiza/&amp;quot; directory.&lt;br /&gt;
#* If you run into a mysql log in error go into config/database.yml and edit the mysql credentials for the test section so that it matches the local environment's mysql configuration&lt;br /&gt;
# Check if tests passed or failed.&lt;br /&gt;
&lt;br /&gt;
= Manual Test Case =&lt;br /&gt;
&lt;br /&gt;
In order to test the changes made to the ReviewResponseMap, bring up [[ http://152.46.16.195:5902/ | Expertiza]] and log in as an administrator.  Once logged in, proceed with the following steps:&lt;br /&gt;
&lt;br /&gt;
# Go to '''impersonate user''' when logged in as ''instructor6'' and type in ''student559'' (or) just log in as ''student559''. All passwords are ''password'' .&lt;br /&gt;
# Pick any assignment to view.&lt;br /&gt;
# Navigate to '''Other's work'''.&lt;br /&gt;
# Check the different reviews and metareviews. Whether they are being displayed correctly or not.&lt;br /&gt;
# Go to Edit or Give feedback and submit a feedback.&lt;br /&gt;
# Go back and check if the feedback given is displayed correctly or not.&lt;br /&gt;
# Check if author's feedback is correct or not.&lt;br /&gt;
# Go to the '''Temp''' assignment and see if the page is being displayed correctly or not (since there is no assignment submission content or reviews for that).&lt;br /&gt;
&lt;br /&gt;
''NOTE: Since this was a refactoring of the code and methods, the existing functionality was supposed to remain the same and not break for the changes we've made.''&lt;br /&gt;
&lt;br /&gt;
= References =&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;references/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;4.&amp;amp;nbsp; [https://github.com/expertiza/expertiza Expertiza Main Repo] &amp;lt;br&amp;gt;&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;5.&amp;amp;nbsp; [https://github.com/adeeshag/expertiza/blob/develop/app/models/review_response_map.rb Refactored ReviewResponseMap.rb]&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;6.&amp;amp;nbsp; [https://github.com/adeeshag/expertiza/tree/develop/test/fixtures Test Fixtures]&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;7.&amp;amp;nbsp; [https://github.com/adeeshag/expertiza/blob/develop/test/unit/review_response_map_test.rb Unit Tests]&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;8.&amp;amp;nbsp; [http://152.46.16.195:5902/ Expertiza Deployed Site]&amp;lt;br&amp;gt;&lt;/div&gt;</summary>
		<author><name>Cnbrown4</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2015/ossE1558BGJ&amp;diff=98434</id>
		<title>CSC/ECE 517 Fall 2015/ossE1558BGJ</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2015/ossE1558BGJ&amp;diff=98434"/>
		<updated>2015-11-06T20:05:27Z</updated>

		<summary type="html">&lt;p&gt;Cnbrown4: /* Unit Tests */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Introduction =&lt;br /&gt;
&lt;br /&gt;
This page provides a description of the modifications and improvements made to the Expertiza project’s source code as part of an Expertiza based Open Source Software project.  Expertiza is a web based application which allows students to submit and peer-review classmates’ work, including written articles and development projects. The specific changes made during the course of this project were to the ReviewResponseMap.rb file, with additional changes made to other related files in support of refactoring ReviewResponseMap.rb.  &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
= Problem Statement =&lt;br /&gt;
&lt;br /&gt;
ReviewResponseMap is the model class used to manage the relationship between contributors, reviewers, and assignments.  The intent of the changes were to refactor the code for better readability and adherence to Ruby coding standards and best practices.  Primarily these changes involved the refactoring of overly complex methods, renaming methods for better readability, and the addition of missing unit tests.&lt;br /&gt;
&lt;br /&gt;
Project Requirements:&lt;br /&gt;
&lt;br /&gt;
# Code Climate&amp;lt;ref name=&amp;quot;Code Climate&amp;quot;&amp;gt;https://codeclimate.com&amp;lt;/ref&amp;gt; shows import method is complex, because of lots of checks. This method can be fixed by adding private methods for raising import error.&lt;br /&gt;
# Get_assessments_round_for method can be renamed to get_team_responses_for_round. Team_id private variable is not needed.&lt;br /&gt;
# metareview_response_maps rename, refactoring can be done. No need to do second iteration.&lt;br /&gt;
# write missing unit tests for existing methods.&lt;br /&gt;
&lt;br /&gt;
= Design Patterns =&lt;br /&gt;
&lt;br /&gt;
As part of our project, we refactored the model to follow the Single Responsibility and Don't Repeat Yourself (DRY) Principles.  Both of the principles focus on reducing code repetition and increasing the cohesion of the individual methods in the class.  The Single Responsibility Principle states that each class and method should have sole responsibility over one single part of the functionality of the system&amp;lt;ref&amp;gt;https://en.wikipedia.org/wiki/Single_responsibility_principle&amp;lt;/ref&amp;gt;.  The DRY principle states that whenever the same types of logic and functionality are being performed in a class the duplicated logic should be extracted into a new method that can be called in place of the repeated lines of code &amp;lt;ref&amp;gt;https://en.wikipedia.org/wiki/Don%27t_repeat_yourself&amp;lt;/ref&amp;gt;.  A prime example of a method that initially violated these principles was the import method, which in addition to performing the core import processes also performed a number of checks that would be more properly extracted into private methods.&lt;br /&gt;
&lt;br /&gt;
=Code Changes =&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Refactoring of import method ===&lt;br /&gt;
&lt;br /&gt;
CodeClimate reports showed the import method to be overly complex, with a number of checks being included within the import method itself.  The resolution for this problem was to refactor the import method, creating private methods to perform the null checks and throw import errors.  Prior to refactoring, all null checks were performed within the import method.   After refactoring, the import method adheres to the single responsibility principle, performing only key import tasks while making calls to private methods for any necessary validation. The size of the import method was reduced by doing this and counts for better readability of the code. Also, this method is a very important one and care was taken so that any existing functionality did not break. &lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
Before refactoring:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;big&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 def self.import(row, session, id)&lt;br /&gt;
    if row.length &amp;lt; 2&lt;br /&gt;
      raise ArgumentError, &amp;quot;Not enough items&amp;quot;&lt;br /&gt;
    end&lt;br /&gt;
    assignment = Assignment.find(id)&lt;br /&gt;
    if assignment.nil?&lt;br /&gt;
      raise ImportError, &amp;quot;The assignment with id \&amp;quot;#{id}\&amp;quot; was not found. &amp;lt;a href='/assignment/new'&amp;gt;Create&amp;lt;/a&amp;gt; this assignment?&amp;quot;&lt;br /&gt;
    end&lt;br /&gt;
    index = 1&lt;br /&gt;
    while index &amp;lt; row.length&lt;br /&gt;
      user = User.find_by_name(row[index].to_s.strip)&lt;br /&gt;
      if user.nil?&lt;br /&gt;
        raise ImportError, &amp;quot;The user account for the reviewer \&amp;quot;#{row[index]}\&amp;quot; was not found. &amp;lt;a href='/users/new'&amp;gt;Create&amp;lt;/a&amp;gt; this user?&amp;quot;&lt;br /&gt;
      end&lt;br /&gt;
      reviewer = AssignmentParticipant.where(user_id: user.id, parent_id:  assignment.id).first&lt;br /&gt;
      if reviewer == nil&lt;br /&gt;
        raise ImportError, &amp;quot;The reviewer \&amp;quot;#{row[index]}\&amp;quot; is not a participant in this assignment. &amp;lt;a href='/users/new'&amp;gt;Register&amp;lt;/a&amp;gt; this user as a participant?&amp;quot;&lt;br /&gt;
      end&lt;br /&gt;
      if assignment.team_assignment&lt;br /&gt;
        reviewee = AssignmentTeam.where(name: row[0].to_s.strip, parent_id:  assignment.id).first&lt;br /&gt;
        if reviewee == nil&lt;br /&gt;
          raise ImportError, &amp;quot;The author \&amp;quot;#{row[0].to_s.strip}\&amp;quot; was not found. &amp;lt;a href='/users/new'&amp;gt;Create&amp;lt;/a&amp;gt; this user?&amp;quot;&lt;br /&gt;
        end&lt;br /&gt;
        existing = ReviewResponseMap.where(reviewee_id: reviewee.id, reviewer_id:  reviewer.id).first&lt;br /&gt;
        if existing.nil?&lt;br /&gt;
          ReviewResponseMap.create(:reviewer_id =&amp;gt; reviewer.id, :reviewee_id =&amp;gt; reviewee.id, :reviewed_object_id =&amp;gt; assignment.id)&lt;br /&gt;
        end&lt;br /&gt;
      else&lt;br /&gt;
        puser = User.find_by_name(row[0].to_s.strip)&lt;br /&gt;
        if user == nil&lt;br /&gt;
          raise ImportError, &amp;quot;The user account for the reviewee \&amp;quot;#{row[0]}\&amp;quot; was not found. &amp;lt;a href='/users/new'&amp;gt;Create&amp;lt;/a&amp;gt; this user?&amp;quot;&lt;br /&gt;
        end&lt;br /&gt;
        reviewee = AssignmentParticipant.where(user_id: puser.id, parent_id:  assignment.id).first&lt;br /&gt;
        if reviewee == nil&lt;br /&gt;
          raise ImportError, &amp;quot;The author \&amp;quot;#{row[0].to_s.strip}\&amp;quot; was not found. &amp;lt;a href='/users/new'&amp;gt;Create&amp;lt;/a&amp;gt; this user?&amp;quot;&lt;br /&gt;
        end&lt;br /&gt;
        team_id = TeamsUser.team_id(reviewee.parent_id, reviewee.user_id)&lt;br /&gt;
        existing = ReviewResponseMap.where(reviewee_id: team_id, reviewer_id:  reviewer.id).first&lt;br /&gt;
        if existing.nil?&lt;br /&gt;
          ReviewResponseMap.create(:reviewee_id =&amp;gt; team_id, :reviewer_id =&amp;gt; reviewer.id, :reviewed_object_id =&amp;gt; assignment.id)&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
      index += 1&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
&lt;br /&gt;
After refactoring:&lt;br /&gt;
 &lt;br /&gt;
  &amp;lt;big&amp;gt;&amp;lt;nowiki&amp;gt;#Imports new reponse maps if they do not already exist&lt;br /&gt;
  def self.import(row, _session, id)&lt;br /&gt;
      if row.length &amp;lt; 2&lt;br /&gt;
          raise ArgumentError, 'Not enough items'&lt;br /&gt;
      end&lt;br /&gt;
      assignment = find_assignment(id)&lt;br /&gt;
      index = 1&lt;br /&gt;
      reviewee_name = row[0]&lt;br /&gt;
      while index &amp;lt; row.length&lt;br /&gt;
          reviewee_id = nil&lt;br /&gt;
          reviewer_name = row[index]&lt;br /&gt;
          reviewer = get_assignment_participant(reviewer_name,  assignment.id, &amp;quot;reviewer&amp;quot;)&lt;br /&gt;
          participant_nil?(reviewer, reviewer_name , &amp;quot;reviewer&amp;quot;)&lt;br /&gt;
         &lt;br /&gt;
         #Find reviewee if assignment is a team assignment&lt;br /&gt;
         if assignment.team_assignment&lt;br /&gt;
             reviewee = AssignmentTeam.where(name: reviewee_name .to_s.strip, parent_id: assignment.id).first&lt;br /&gt;
             participant_nil?(reviewee, reviewee_name, &amp;quot;author&amp;quot;)&lt;br /&gt;
             reviewee_id = reviewee.id&lt;br /&gt;
         #Find reviewee if assignment is not a team assignment&lt;br /&gt;
         else&lt;br /&gt;
	     reviewee = get_assignment_participant(reviewee_name, assignment.id, &amp;quot;reviewee&amp;quot;)&lt;br /&gt;
             participant_nil?(reviewee, reviewee_name, &amp;quot;author&amp;quot;)&lt;br /&gt;
             reviewee_id  = TeamsUser.team_id(reviewee.parent_id, reviewee.user_id)&lt;br /&gt;
         end&lt;br /&gt;
         create_response_map(reviewer, reviewee_id,  assignment)&lt;br /&gt;
         index += 1&lt;br /&gt;
      end&lt;br /&gt;
  end&amp;lt;/nowiki&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Private methods added:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;big&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  # Check for if assignment value is null&lt;br /&gt;
  def self.find_assignment(id)&lt;br /&gt;
      begin&lt;br /&gt;
          assignment = Assignment.find(id)&lt;br /&gt;
      rescue ActiveRecord::RecordNotFound&lt;br /&gt;
          raise ImportError, &amp;quot;The assignment with id \&amp;quot;#{id}\&amp;quot; was not found.&amp;lt;a href='/assignment/new'&amp;gt;Create&amp;lt;/a&amp;gt; this assignment?&amp;quot;&lt;br /&gt;
      end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  # Check for if participant is null&lt;br /&gt;
  def self.participant_nil?(participant, user_name, participant_type) &lt;br /&gt;
      error_message = nil&lt;br /&gt;
      if participant_type == &amp;quot;author&amp;quot;&lt;br /&gt;
          error_message = &amp;quot;The author \&amp;quot;#{user_name.to_s.strip}\&amp;quot; was not found.&amp;lt;a href='/users/new'&amp;gt;Create&amp;lt;/a&amp;gt; this user?&amp;quot;&lt;br /&gt;
      else&lt;br /&gt;
          error_message =  &amp;quot;The reviewer \&amp;quot;#{user_name}\&amp;quot; is not a participant in this assignment.&amp;lt;a href='/users/new'&amp;gt;Register&amp;lt;/a&amp;gt; this user as a participant?&amp;quot;&lt;br /&gt;
      end&lt;br /&gt;
      check_nil?(participant, error_message)&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  # Check for if user is null&lt;br /&gt;
  def self.user_nil?(user, user_name, user_type)&lt;br /&gt;
      check_nil?( user, &amp;quot;The user account for the \&amp;quot;#{user_type}\&amp;quot; \&amp;quot;#{user_name}\&amp;quot; was not found.&amp;lt;a href='/users/new'&amp;gt;Create&amp;lt;/a&amp;gt; this user?&amp;quot;)&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
 #Throws import error for nil objects&lt;br /&gt;
  def self.check_nil?(object, error_message)&lt;br /&gt;
      if object.nil?&lt;br /&gt;
          raise ImportError, error_message&lt;br /&gt;
      end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Refactoring of get_assessments_round_for method ===&lt;br /&gt;
&lt;br /&gt;
The get_assessments_round_for method’s name failed to provide a clear idea of the method’s purpose and functionality.  This is why it was renamed to get_team_responses_for_round, the new name of the method provides a clearer idea of its purpose. Additionally, there was a private variable, team_id, introduced in the method that was unnecessary and could be replaced by using the id property of the team parameter directly.  &lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
Before refactoring:&lt;br /&gt;
&amp;lt;big&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  def self.get_assessments_round_for(team,round)&lt;br /&gt;
    team_id =team.id&lt;br /&gt;
    responses = Array.new&lt;br /&gt;
    if team_id&lt;br /&gt;
      maps = ResponseMap.where(:reviewee_id =&amp;gt; team_id, :type =&amp;gt; &amp;quot;ReviewResponseMap&amp;quot;)&lt;br /&gt;
      maps.each{ |map|&lt;br /&gt;
        if !map.response.empty? &amp;amp;&amp;amp; !map.response.reject{|r| r.round!=round}.empty?&lt;br /&gt;
          responses &amp;lt;&amp;lt; map.response.reject{|r| r.round!=round}.last&lt;br /&gt;
        end&lt;br /&gt;
      }&lt;br /&gt;
      responses.sort! {|a,b| a.map.reviewer.fullname &amp;lt;=&amp;gt; b.map.reviewer.fullname }&lt;br /&gt;
    end&lt;br /&gt;
    return responses&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
&lt;br /&gt;
After refactoring: &lt;br /&gt;
&lt;br /&gt;
&amp;lt;big&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  def self.get_team_responses_for_round(team, round)&lt;br /&gt;
    responses = []&lt;br /&gt;
    if team.id&lt;br /&gt;
      maps = ResponseMap.where(reviewee_id: team.id, type: 'ReviewResponseMap')&lt;br /&gt;
      maps.each do |map|&lt;br /&gt;
        unless map.response.empty? &amp;amp;&amp;amp; map.response.reject { |r| r.round != round }.empty?&lt;br /&gt;
          responses &amp;lt;&amp;lt; map.response.reject { |r| r.round != round }.last&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
      responses.sort! { |a, b| a.map.reviewer.fullname &amp;lt;=&amp;gt; b.map.reviewer.fullname }&lt;br /&gt;
    end&lt;br /&gt;
    responses&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
The change in method name also required changes to the following files that referenced it:&lt;br /&gt;
&lt;br /&gt;
/app/models/assignment.rb:436:    &lt;br /&gt;
 &lt;br /&gt;
&amp;lt;big&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  assessments = ReviewResponseMap.get_assessments_round_for(team,i)&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt; &lt;br /&gt;
&lt;br /&gt;
./app/models/assignment_participant.rb:268:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;big&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 scores[questionnaire_symbol][:assessments] = questionnaire.get_assessments_round_for(self,round)&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Refactoring of metareview_response_maps method ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The metareview_response_maps method was unnecessarily complex.  It contained an unneeded private variable and an unnecessary nested loop.  Originally, it added each metareview map individually in the nested loop.  We decided to remove the nested loop and use the concat method for readability and maintainability.  These changes allowed us to remove the private variable &amp;quot;metareview_list&amp;quot; and only maintain the &amp;quot;metareview_response_maps&amp;quot; variable.  We also renamed the metareview_response_maps method to get_metareview_response_maps method to be more descriptive about the intent of the method. &lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
Before refactoring:&lt;br /&gt;
&amp;lt;big&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 def metareview_response_maps&lt;br /&gt;
    responses = Response.where(map_id:self.id)&lt;br /&gt;
    metareview_list=[]&lt;br /&gt;
    responses.each do |response|&lt;br /&gt;
      metareview_response_maps = MetareviewResponseMap.where(reviewed_object_id:response.id)&lt;br /&gt;
      metareview_response_maps.each do |metareview_response_map|&lt;br /&gt;
        metareview_list&amp;lt;&amp;lt;metareview_response_map&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
    metareview_list&lt;br /&gt;
 end&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
After refactoring:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;big&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  def get_metareview_response_maps&lt;br /&gt;
    responses = Response.where(map_id: id)&lt;br /&gt;
    metareview_response_maps = []&lt;br /&gt;
    responses.each do |response|&lt;br /&gt;
      metareview_response_maps.concat MetareviewResponseMap.where(reviewed_object_id: response.id)&lt;br /&gt;
    end&lt;br /&gt;
    metareview_response_maps&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Addition of code comments ===&lt;br /&gt;
&lt;br /&gt;
We added comments to all of the methods in the ReviewResponseMap.rb file and corrected instances where CodeClimate Identified opportunities for code improvement.  One issue flagged by CodeClimate that we did not change was to use the find_by method instead of where().first method.  The where().first method occurs in the import, get_assignment_participant, and create_response_map methods. It is not always appropriate to use the find_by method, as documented in this github post: https://github.com/bbatsov/rubocop/issues/1938 .  In instances where ordering by id is the desired behavior, where().first will order by default, but in Rails 4+ find_by does not honor that default behavior.  For this reason we left the instances of where().first unchanged.&lt;br /&gt;
&lt;br /&gt;
=== Code Improvements ===&lt;br /&gt;
&lt;br /&gt;
This refactoring was to improve readability and follow as many good ''Rubyist'' coding practices as possible without breaking the functionality of existing code. We used CodeClimate of the master branch code as a reference. We took the suggestions we got from CodeClimate and improved our code based on that.&lt;br /&gt;
We also made some of the methods shorter by removing redundant functionality and adding private methods to methods with a lot internal functionality. We also added private methods in places where we saw repeated patterns to make the code ''DRYer''.&lt;br /&gt;
At the end of our refactoring, we managed to improve the rating on CodeClimate from a '''C''' to a '''B''' . Further improvements meant reducing the size of the entire class which required a much more significant refactoring in multiple files and folders. We focused on refactoring the existing model, '''ReviewResponseMap'''.&lt;br /&gt;
&lt;br /&gt;
= Unit Tests =&lt;br /&gt;
The previous unit tests had syntactical and run time errors.  We were not able to get the previous unit tests to run without errors.  Because of this we rewrote all of the unit tests for the &amp;lt;b&amp;gt;ReviewResponseModel&amp;lt;/b&amp;gt;.  It is important to have working unit tests so that when internal changes are made to functions the external output remains the same.&lt;br /&gt;
&lt;br /&gt;
=== Refactoring of Unit Tests===&lt;br /&gt;
&lt;br /&gt;
We added a test_helper file to the main test folder that requires a needed configuration file and needed gems.  We also added 8 fixtures that were needed for data to run the unit tests.  The following fixture files were added:&lt;br /&gt;
&lt;br /&gt;
* assignment_questionnaires.yml&lt;br /&gt;
* assignments.yml&lt;br /&gt;
* participants.yml&lt;br /&gt;
* questionnaires.yml&lt;br /&gt;
* response_maps.yml&lt;br /&gt;
* responses.yml&lt;br /&gt;
* teams.yml&lt;br /&gt;
* users.yml&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
There is at least one unit test for every public method within the &amp;lt;b&amp;gt;ReviewResponseModel&amp;lt;/b&amp;gt;.  The test naming convention used is &amp;quot;method_&amp;lt;name of method that is being tested&amp;gt;&amp;quot;.  For example, the unit test for the export method is &amp;quot;method_export&amp;quot;.  If there are multiple test for one method the name of the test will include the test case after the normal naming convention.  For example, one of the unit tests for the import method checks for an invalid assignment.  The name of this method is &amp;quot;method_import_invalid_assignment&amp;quot;.  The following are the unit tests we created:&lt;br /&gt;
&lt;br /&gt;
* method_export&lt;br /&gt;
* method_get_metareview_response_maps&lt;br /&gt;
* method_get_team_response_for_round&lt;br /&gt;
* method_final_versions_from_reviewer&lt;br /&gt;
* method_import&lt;br /&gt;
* method_import_invalid_reviewee&lt;br /&gt;
* method_import_invalid_reviewer&lt;br /&gt;
* method_import_invalid_assignment&lt;br /&gt;
* method_delete&lt;br /&gt;
* method_delete_no _force&lt;br /&gt;
* method_show_feedback&lt;br /&gt;
* method_get_title&lt;br /&gt;
* method_export_fields&lt;br /&gt;
* method_questionnaire&lt;br /&gt;
* method_add_reviewer&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== How to Run Unit Tests ===&lt;br /&gt;
To run the unit tests, follow these steps:&lt;br /&gt;
&lt;br /&gt;
# Download the master branch of the repo.&lt;br /&gt;
# Setup the Databases for the test environment (we have used Zhewei's scrubbed expertiza DB )&lt;br /&gt;
#* Run the &amp;quot; rake db:create RAILS_ENV=test &amp;quot; command&lt;br /&gt;
#* Run the &amp;quot; rake db:reset RAILS_ENV=test &amp;quot; command&lt;br /&gt;
#* Scrub the DB using &amp;quot; mysql -u root expertiza_development &amp;lt; expertiza-scrubbed.sql&amp;quot;&lt;br /&gt;
#* Run the &amp;quot; rake db:migrate &amp;quot;&lt;br /&gt;
# Run &amp;quot; rake test test/unit/review_response_map_test.rb &amp;quot; in the &amp;quot;expertiza/&amp;quot; directory.&lt;br /&gt;
#* If you run into a mysql log in error go into config/database.yml and edit the mysql credentials for the test section so that it matches the local environment's mysql configuration&lt;br /&gt;
# Check if tests passed or failed.&lt;br /&gt;
&lt;br /&gt;
= Manual Test Case =&lt;br /&gt;
&lt;br /&gt;
In order to test the changes made to the ReviewResponseMap, bring up Expertiza and log in as an administrator.  Once logged in, proceed with the following steps:&lt;br /&gt;
&lt;br /&gt;
# Go to '''impersonate user''' when logged in as ''instructor6'' and type in ''student559'' (or) just log in as ''student559''. All passwords are ''password'' .&lt;br /&gt;
# Pick any assignment to view.&lt;br /&gt;
# Navigate to '''Other's work'''.&lt;br /&gt;
# Check the different reviews and metareviews. Whether they are being displayed correctly or not.&lt;br /&gt;
# Go to Edit or Give feedback and submit a feedback.&lt;br /&gt;
# Go back and check if the feedback given is displayed correctly or not.&lt;br /&gt;
# Check if author's feedback is correct or not.&lt;br /&gt;
# Go to the '''Temp''' assignment and see if the page is being displayed correctly or not (since there is no assignment submission content or reviews for that).&lt;br /&gt;
&lt;br /&gt;
''NOTE: Since this was a refactoring of the code and methods, the existing functionality was supposed to remain the same and not break for the changes we've made.''&lt;br /&gt;
&lt;br /&gt;
= References =&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;references/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;4.&amp;amp;nbsp; [https://github.com/expertiza/expertiza Expertiza Main Repo] &amp;lt;br&amp;gt;&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;5.&amp;amp;nbsp; [https://github.com/adeeshag/expertiza/blob/develop/app/models/review_response_map.rb Refactored ReviewResponseMap.rb]&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;6.&amp;amp;nbsp; [https://github.com/adeeshag/expertiza/tree/develop/test/fixtures Test Fixtures]&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;7.&amp;amp;nbsp; [https://github.com/adeeshag/expertiza/blob/develop/test/unit/review_response_map_test.rb Unit Tests]&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;8.&amp;amp;nbsp; [http://152.46.16.195:5902/ Expertiza Deployed Site]&amp;lt;br&amp;gt;&lt;/div&gt;</summary>
		<author><name>Cnbrown4</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2015/ossE1558BGJ&amp;diff=98433</id>
		<title>CSC/ECE 517 Fall 2015/ossE1558BGJ</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2015/ossE1558BGJ&amp;diff=98433"/>
		<updated>2015-11-06T20:03:21Z</updated>

		<summary type="html">&lt;p&gt;Cnbrown4: /* Refactoring of Unit Tests */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Introduction =&lt;br /&gt;
&lt;br /&gt;
This page provides a description of the modifications and improvements made to the Expertiza project’s source code as part of an Expertiza based Open Source Software project.  Expertiza is a web based application which allows students to submit and peer-review classmates’ work, including written articles and development projects. The specific changes made during the course of this project were to the ReviewResponseMap.rb file, with additional changes made to other related files in support of refactoring ReviewResponseMap.rb.  &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
= Problem Statement =&lt;br /&gt;
&lt;br /&gt;
ReviewResponseMap is the model class used to manage the relationship between contributors, reviewers, and assignments.  The intent of the changes were to refactor the code for better readability and adherence to Ruby coding standards and best practices.  Primarily these changes involved the refactoring of overly complex methods, renaming methods for better readability, and the addition of missing unit tests.&lt;br /&gt;
&lt;br /&gt;
Project Requirements:&lt;br /&gt;
&lt;br /&gt;
# Code Climate&amp;lt;ref name=&amp;quot;Code Climate&amp;quot;&amp;gt;https://codeclimate.com&amp;lt;/ref&amp;gt; shows import method is complex, because of lots of checks. This method can be fixed by adding private methods for raising import error.&lt;br /&gt;
# Get_assessments_round_for method can be renamed to get_team_responses_for_round. Team_id private variable is not needed.&lt;br /&gt;
# metareview_response_maps rename, refactoring can be done. No need to do second iteration.&lt;br /&gt;
# write missing unit tests for existing methods.&lt;br /&gt;
&lt;br /&gt;
= Design Patterns =&lt;br /&gt;
&lt;br /&gt;
As part of our project, we refactored the model to follow the Single Responsibility and Don't Repeat Yourself (DRY) Principles.  Both of the principles focus on reducing code repetition and increasing the cohesion of the individual methods in the class.  The Single Responsibility Principle states that each class and method should have sole responsibility over one single part of the functionality of the system&amp;lt;ref&amp;gt;https://en.wikipedia.org/wiki/Single_responsibility_principle&amp;lt;/ref&amp;gt;.  The DRY principle states that whenever the same types of logic and functionality are being performed in a class the duplicated logic should be extracted into a new method that can be called in place of the repeated lines of code &amp;lt;ref&amp;gt;https://en.wikipedia.org/wiki/Don%27t_repeat_yourself&amp;lt;/ref&amp;gt;.  A prime example of a method that initially violated these principles was the import method, which in addition to performing the core import processes also performed a number of checks that would be more properly extracted into private methods.&lt;br /&gt;
&lt;br /&gt;
=Code Changes =&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Refactoring of import method ===&lt;br /&gt;
&lt;br /&gt;
CodeClimate reports showed the import method to be overly complex, with a number of checks being included within the import method itself.  The resolution for this problem was to refactor the import method, creating private methods to perform the null checks and throw import errors.  Prior to refactoring, all null checks were performed within the import method.   After refactoring, the import method adheres to the single responsibility principle, performing only key import tasks while making calls to private methods for any necessary validation. The size of the import method was reduced by doing this and counts for better readability of the code. Also, this method is a very important one and care was taken so that any existing functionality did not break. &lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
Before refactoring:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;big&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 def self.import(row, session, id)&lt;br /&gt;
    if row.length &amp;lt; 2&lt;br /&gt;
      raise ArgumentError, &amp;quot;Not enough items&amp;quot;&lt;br /&gt;
    end&lt;br /&gt;
    assignment = Assignment.find(id)&lt;br /&gt;
    if assignment.nil?&lt;br /&gt;
      raise ImportError, &amp;quot;The assignment with id \&amp;quot;#{id}\&amp;quot; was not found. &amp;lt;a href='/assignment/new'&amp;gt;Create&amp;lt;/a&amp;gt; this assignment?&amp;quot;&lt;br /&gt;
    end&lt;br /&gt;
    index = 1&lt;br /&gt;
    while index &amp;lt; row.length&lt;br /&gt;
      user = User.find_by_name(row[index].to_s.strip)&lt;br /&gt;
      if user.nil?&lt;br /&gt;
        raise ImportError, &amp;quot;The user account for the reviewer \&amp;quot;#{row[index]}\&amp;quot; was not found. &amp;lt;a href='/users/new'&amp;gt;Create&amp;lt;/a&amp;gt; this user?&amp;quot;&lt;br /&gt;
      end&lt;br /&gt;
      reviewer = AssignmentParticipant.where(user_id: user.id, parent_id:  assignment.id).first&lt;br /&gt;
      if reviewer == nil&lt;br /&gt;
        raise ImportError, &amp;quot;The reviewer \&amp;quot;#{row[index]}\&amp;quot; is not a participant in this assignment. &amp;lt;a href='/users/new'&amp;gt;Register&amp;lt;/a&amp;gt; this user as a participant?&amp;quot;&lt;br /&gt;
      end&lt;br /&gt;
      if assignment.team_assignment&lt;br /&gt;
        reviewee = AssignmentTeam.where(name: row[0].to_s.strip, parent_id:  assignment.id).first&lt;br /&gt;
        if reviewee == nil&lt;br /&gt;
          raise ImportError, &amp;quot;The author \&amp;quot;#{row[0].to_s.strip}\&amp;quot; was not found. &amp;lt;a href='/users/new'&amp;gt;Create&amp;lt;/a&amp;gt; this user?&amp;quot;&lt;br /&gt;
        end&lt;br /&gt;
        existing = ReviewResponseMap.where(reviewee_id: reviewee.id, reviewer_id:  reviewer.id).first&lt;br /&gt;
        if existing.nil?&lt;br /&gt;
          ReviewResponseMap.create(:reviewer_id =&amp;gt; reviewer.id, :reviewee_id =&amp;gt; reviewee.id, :reviewed_object_id =&amp;gt; assignment.id)&lt;br /&gt;
        end&lt;br /&gt;
      else&lt;br /&gt;
        puser = User.find_by_name(row[0].to_s.strip)&lt;br /&gt;
        if user == nil&lt;br /&gt;
          raise ImportError, &amp;quot;The user account for the reviewee \&amp;quot;#{row[0]}\&amp;quot; was not found. &amp;lt;a href='/users/new'&amp;gt;Create&amp;lt;/a&amp;gt; this user?&amp;quot;&lt;br /&gt;
        end&lt;br /&gt;
        reviewee = AssignmentParticipant.where(user_id: puser.id, parent_id:  assignment.id).first&lt;br /&gt;
        if reviewee == nil&lt;br /&gt;
          raise ImportError, &amp;quot;The author \&amp;quot;#{row[0].to_s.strip}\&amp;quot; was not found. &amp;lt;a href='/users/new'&amp;gt;Create&amp;lt;/a&amp;gt; this user?&amp;quot;&lt;br /&gt;
        end&lt;br /&gt;
        team_id = TeamsUser.team_id(reviewee.parent_id, reviewee.user_id)&lt;br /&gt;
        existing = ReviewResponseMap.where(reviewee_id: team_id, reviewer_id:  reviewer.id).first&lt;br /&gt;
        if existing.nil?&lt;br /&gt;
          ReviewResponseMap.create(:reviewee_id =&amp;gt; team_id, :reviewer_id =&amp;gt; reviewer.id, :reviewed_object_id =&amp;gt; assignment.id)&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
      index += 1&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
&lt;br /&gt;
After refactoring:&lt;br /&gt;
 &lt;br /&gt;
  &amp;lt;big&amp;gt;&amp;lt;nowiki&amp;gt;#Imports new reponse maps if they do not already exist&lt;br /&gt;
  def self.import(row, _session, id)&lt;br /&gt;
      if row.length &amp;lt; 2&lt;br /&gt;
          raise ArgumentError, 'Not enough items'&lt;br /&gt;
      end&lt;br /&gt;
      assignment = find_assignment(id)&lt;br /&gt;
      index = 1&lt;br /&gt;
      reviewee_name = row[0]&lt;br /&gt;
      while index &amp;lt; row.length&lt;br /&gt;
          reviewee_id = nil&lt;br /&gt;
          reviewer_name = row[index]&lt;br /&gt;
          reviewer = get_assignment_participant(reviewer_name,  assignment.id, &amp;quot;reviewer&amp;quot;)&lt;br /&gt;
          participant_nil?(reviewer, reviewer_name , &amp;quot;reviewer&amp;quot;)&lt;br /&gt;
         &lt;br /&gt;
         #Find reviewee if assignment is a team assignment&lt;br /&gt;
         if assignment.team_assignment&lt;br /&gt;
             reviewee = AssignmentTeam.where(name: reviewee_name .to_s.strip, parent_id: assignment.id).first&lt;br /&gt;
             participant_nil?(reviewee, reviewee_name, &amp;quot;author&amp;quot;)&lt;br /&gt;
             reviewee_id = reviewee.id&lt;br /&gt;
         #Find reviewee if assignment is not a team assignment&lt;br /&gt;
         else&lt;br /&gt;
	     reviewee = get_assignment_participant(reviewee_name, assignment.id, &amp;quot;reviewee&amp;quot;)&lt;br /&gt;
             participant_nil?(reviewee, reviewee_name, &amp;quot;author&amp;quot;)&lt;br /&gt;
             reviewee_id  = TeamsUser.team_id(reviewee.parent_id, reviewee.user_id)&lt;br /&gt;
         end&lt;br /&gt;
         create_response_map(reviewer, reviewee_id,  assignment)&lt;br /&gt;
         index += 1&lt;br /&gt;
      end&lt;br /&gt;
  end&amp;lt;/nowiki&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Private methods added:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;big&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  # Check for if assignment value is null&lt;br /&gt;
  def self.find_assignment(id)&lt;br /&gt;
      begin&lt;br /&gt;
          assignment = Assignment.find(id)&lt;br /&gt;
      rescue ActiveRecord::RecordNotFound&lt;br /&gt;
          raise ImportError, &amp;quot;The assignment with id \&amp;quot;#{id}\&amp;quot; was not found.&amp;lt;a href='/assignment/new'&amp;gt;Create&amp;lt;/a&amp;gt; this assignment?&amp;quot;&lt;br /&gt;
      end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  # Check for if participant is null&lt;br /&gt;
  def self.participant_nil?(participant, user_name, participant_type) &lt;br /&gt;
      error_message = nil&lt;br /&gt;
      if participant_type == &amp;quot;author&amp;quot;&lt;br /&gt;
          error_message = &amp;quot;The author \&amp;quot;#{user_name.to_s.strip}\&amp;quot; was not found.&amp;lt;a href='/users/new'&amp;gt;Create&amp;lt;/a&amp;gt; this user?&amp;quot;&lt;br /&gt;
      else&lt;br /&gt;
          error_message =  &amp;quot;The reviewer \&amp;quot;#{user_name}\&amp;quot; is not a participant in this assignment.&amp;lt;a href='/users/new'&amp;gt;Register&amp;lt;/a&amp;gt; this user as a participant?&amp;quot;&lt;br /&gt;
      end&lt;br /&gt;
      check_nil?(participant, error_message)&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  # Check for if user is null&lt;br /&gt;
  def self.user_nil?(user, user_name, user_type)&lt;br /&gt;
      check_nil?( user, &amp;quot;The user account for the \&amp;quot;#{user_type}\&amp;quot; \&amp;quot;#{user_name}\&amp;quot; was not found.&amp;lt;a href='/users/new'&amp;gt;Create&amp;lt;/a&amp;gt; this user?&amp;quot;)&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
 #Throws import error for nil objects&lt;br /&gt;
  def self.check_nil?(object, error_message)&lt;br /&gt;
      if object.nil?&lt;br /&gt;
          raise ImportError, error_message&lt;br /&gt;
      end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Refactoring of get_assessments_round_for method ===&lt;br /&gt;
&lt;br /&gt;
The get_assessments_round_for method’s name failed to provide a clear idea of the method’s purpose and functionality.  This is why it was renamed to get_team_responses_for_round, the new name of the method provides a clearer idea of its purpose. Additionally, there was a private variable, team_id, introduced in the method that was unnecessary and could be replaced by using the id property of the team parameter directly.  &lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
Before refactoring:&lt;br /&gt;
&amp;lt;big&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  def self.get_assessments_round_for(team,round)&lt;br /&gt;
    team_id =team.id&lt;br /&gt;
    responses = Array.new&lt;br /&gt;
    if team_id&lt;br /&gt;
      maps = ResponseMap.where(:reviewee_id =&amp;gt; team_id, :type =&amp;gt; &amp;quot;ReviewResponseMap&amp;quot;)&lt;br /&gt;
      maps.each{ |map|&lt;br /&gt;
        if !map.response.empty? &amp;amp;&amp;amp; !map.response.reject{|r| r.round!=round}.empty?&lt;br /&gt;
          responses &amp;lt;&amp;lt; map.response.reject{|r| r.round!=round}.last&lt;br /&gt;
        end&lt;br /&gt;
      }&lt;br /&gt;
      responses.sort! {|a,b| a.map.reviewer.fullname &amp;lt;=&amp;gt; b.map.reviewer.fullname }&lt;br /&gt;
    end&lt;br /&gt;
    return responses&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
&lt;br /&gt;
After refactoring: &lt;br /&gt;
&lt;br /&gt;
&amp;lt;big&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  def self.get_team_responses_for_round(team, round)&lt;br /&gt;
    responses = []&lt;br /&gt;
    if team.id&lt;br /&gt;
      maps = ResponseMap.where(reviewee_id: team.id, type: 'ReviewResponseMap')&lt;br /&gt;
      maps.each do |map|&lt;br /&gt;
        unless map.response.empty? &amp;amp;&amp;amp; map.response.reject { |r| r.round != round }.empty?&lt;br /&gt;
          responses &amp;lt;&amp;lt; map.response.reject { |r| r.round != round }.last&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
      responses.sort! { |a, b| a.map.reviewer.fullname &amp;lt;=&amp;gt; b.map.reviewer.fullname }&lt;br /&gt;
    end&lt;br /&gt;
    responses&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
The change in method name also required changes to the following files that referenced it:&lt;br /&gt;
&lt;br /&gt;
/app/models/assignment.rb:436:    &lt;br /&gt;
 &lt;br /&gt;
&amp;lt;big&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  assessments = ReviewResponseMap.get_assessments_round_for(team,i)&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt; &lt;br /&gt;
&lt;br /&gt;
./app/models/assignment_participant.rb:268:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;big&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 scores[questionnaire_symbol][:assessments] = questionnaire.get_assessments_round_for(self,round)&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Refactoring of metareview_response_maps method ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The metareview_response_maps method was unnecessarily complex.  It contained an unneeded private variable and an unnecessary nested loop.  Originally, it added each metareview map individually in the nested loop.  We decided to remove the nested loop and use the concat method for readability and maintainability.  These changes allowed us to remove the private variable &amp;quot;metareview_list&amp;quot; and only maintain the &amp;quot;metareview_response_maps&amp;quot; variable.  We also renamed the metareview_response_maps method to get_metareview_response_maps method to be more descriptive about the intent of the method. &lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
Before refactoring:&lt;br /&gt;
&amp;lt;big&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 def metareview_response_maps&lt;br /&gt;
    responses = Response.where(map_id:self.id)&lt;br /&gt;
    metareview_list=[]&lt;br /&gt;
    responses.each do |response|&lt;br /&gt;
      metareview_response_maps = MetareviewResponseMap.where(reviewed_object_id:response.id)&lt;br /&gt;
      metareview_response_maps.each do |metareview_response_map|&lt;br /&gt;
        metareview_list&amp;lt;&amp;lt;metareview_response_map&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
    metareview_list&lt;br /&gt;
 end&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
After refactoring:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;big&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  def get_metareview_response_maps&lt;br /&gt;
    responses = Response.where(map_id: id)&lt;br /&gt;
    metareview_response_maps = []&lt;br /&gt;
    responses.each do |response|&lt;br /&gt;
      metareview_response_maps.concat MetareviewResponseMap.where(reviewed_object_id: response.id)&lt;br /&gt;
    end&lt;br /&gt;
    metareview_response_maps&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Addition of code comments ===&lt;br /&gt;
&lt;br /&gt;
We added comments to all of the methods in the ReviewResponseMap.rb file and corrected instances where CodeClimate Identified opportunities for code improvement.  One issue flagged by CodeClimate that we did not change was to use the find_by method instead of where().first method.  The where().first method occurs in the import, get_assignment_participant, and create_response_map methods. It is not always appropriate to use the find_by method, as documented in this github post: https://github.com/bbatsov/rubocop/issues/1938 .  In instances where ordering by id is the desired behavior, where().first will order by default, but in Rails 4+ find_by does not honor that default behavior.  For this reason we left the instances of where().first unchanged.&lt;br /&gt;
&lt;br /&gt;
=== Code Improvements ===&lt;br /&gt;
&lt;br /&gt;
This refactoring was to improve readability and follow as many good ''Rubyist'' coding practices as possible without breaking the functionality of existing code. We used CodeClimate of the master branch code as a reference. We took the suggestions we got from CodeClimate and improved our code based on that.&lt;br /&gt;
We also made some of the methods shorter by removing redundant functionality and adding private methods to methods with a lot internal functionality. We also added private methods in places where we saw repeated patterns to make the code ''DRYer''.&lt;br /&gt;
At the end of our refactoring, we managed to improve the rating on CodeClimate from a '''C''' to a '''B''' . Further improvements meant reducing the size of the entire class which required a much more significant refactoring in multiple files and folders. We focused on refactoring the existing model, '''ReviewResponseMap'''.&lt;br /&gt;
&lt;br /&gt;
= Unit Tests =&lt;br /&gt;
&lt;br /&gt;
=== Refactoring of Unit Tests===&lt;br /&gt;
&lt;br /&gt;
The previous unit tests had syntactical and run time errors.  We were not able to get the previous unit tests to run without errors.  Because of this we rewrote the unit tests for the &amp;lt;b&amp;gt;ReviewResponseModel&amp;lt;/b&amp;gt;.  It is important to have working unit tests so that when internal changes are made to functions the external output remains the same.&lt;br /&gt;
&lt;br /&gt;
We added a test_helper file to the main test folder that requires a needed configuration file and needed gems.  We also added 8 fixtures that were needed for data to run the unit tests.  The following fixture files were added:&lt;br /&gt;
&lt;br /&gt;
* assignment_questionnaires.yml&lt;br /&gt;
* assignments.yml&lt;br /&gt;
* participants.yml&lt;br /&gt;
* questionnaires.yml&lt;br /&gt;
* response_maps.yml&lt;br /&gt;
* responses.yml&lt;br /&gt;
* teams.yml&lt;br /&gt;
* users.yml&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
There is at least one unit test for every public method within the &amp;lt;b&amp;gt;ReviewResponseModel&amp;lt;/b&amp;gt;.  The test naming convention used is &amp;quot;method_&amp;lt;name of method that is being tested&amp;gt;&amp;quot;.  For example, the unit test for the export method is &amp;quot;method_export&amp;quot;.  If there are multiple test for one method the name of the test will include the test case after the normal naming convention.  For example, one of the unit tests for the import method checks for an invalid assignment.  The name of this method is &amp;quot;method_import_invalid_assignment&amp;quot;.  The following are the unit tests we created:&lt;br /&gt;
&lt;br /&gt;
* method_export&lt;br /&gt;
* method_get_metareview_response_maps&lt;br /&gt;
* method_get_team_response_for_round&lt;br /&gt;
* method_final_versions_from_reviewer&lt;br /&gt;
* method_import&lt;br /&gt;
* method_import_invalid_reviewee&lt;br /&gt;
* method_import_invalid_reviewer&lt;br /&gt;
* method_import_invalid_assignment&lt;br /&gt;
* method_delete&lt;br /&gt;
* method_delete_no _force&lt;br /&gt;
* method_show_feedback&lt;br /&gt;
* method_get_title&lt;br /&gt;
* method_export_fields&lt;br /&gt;
* method_questionnaire&lt;br /&gt;
* method_add_reviewer&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== How to Run Unit Tests ===&lt;br /&gt;
To run the unit tests, follow these steps:&lt;br /&gt;
&lt;br /&gt;
# Download the master branch of the repo.&lt;br /&gt;
# Setup the Databases for the test environment (we have used Zhewei's scrubbed expertiza DB )&lt;br /&gt;
#* Run the &amp;quot; rake db:create RAILS_ENV=test &amp;quot; command&lt;br /&gt;
#* Run the &amp;quot; rake db:reset RAILS_ENV=test &amp;quot; command&lt;br /&gt;
#* Scrub the DB using &amp;quot; mysql -u root expertiza_development &amp;lt; expertiza-scrubbed.sql&amp;quot;&lt;br /&gt;
#* Run the &amp;quot; rake db:migrate &amp;quot;&lt;br /&gt;
# Run &amp;quot; rake test test/unit/review_response_map_test.rb &amp;quot; in the &amp;quot;expertiza/&amp;quot; directory.&lt;br /&gt;
#* If you run into a mysql log in error go into config/database.yml and edit the mysql credentials for the test section so that it matches the local environment's mysql configuration&lt;br /&gt;
# Check if tests passed or failed.&lt;br /&gt;
&lt;br /&gt;
= Manual Test Case =&lt;br /&gt;
&lt;br /&gt;
In order to test the changes made to the ReviewResponseMap, bring up Expertiza and log in as an administrator.  Once logged in, proceed with the following steps:&lt;br /&gt;
&lt;br /&gt;
# Go to '''impersonate user''' when logged in as ''instructor6'' and type in ''student559'' (or) just log in as ''student559''. All passwords are ''password'' .&lt;br /&gt;
# Pick any assignment to view.&lt;br /&gt;
# Navigate to '''Other's work'''.&lt;br /&gt;
# Check the different reviews and metareviews. Whether they are being displayed correctly or not.&lt;br /&gt;
# Go to Edit or Give feedback and submit a feedback.&lt;br /&gt;
# Go back and check if the feedback given is displayed correctly or not.&lt;br /&gt;
# Check if author's feedback is correct or not.&lt;br /&gt;
# Go to the '''Temp''' assignment and see if the page is being displayed correctly or not (since there is no assignment submission content or reviews for that).&lt;br /&gt;
&lt;br /&gt;
''NOTE: Since this was a refactoring of the code and methods, the existing functionality was supposed to remain the same and not break for the changes we've made.''&lt;br /&gt;
&lt;br /&gt;
= References =&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;references/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;4.&amp;amp;nbsp; [https://github.com/expertiza/expertiza Expertiza Main Repo] &amp;lt;br&amp;gt;&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;5.&amp;amp;nbsp; [https://github.com/adeeshag/expertiza/blob/develop/app/models/review_response_map.rb Refactored ReviewResponseMap.rb]&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;6.&amp;amp;nbsp; [https://github.com/adeeshag/expertiza/tree/develop/test/fixtures Test Fixtures]&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;7.&amp;amp;nbsp; [https://github.com/adeeshag/expertiza/blob/develop/test/unit/review_response_map_test.rb Unit Tests]&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;8.&amp;amp;nbsp; [http://152.46.16.195:5902/ Expertiza Deployed Site]&amp;lt;br&amp;gt;&lt;/div&gt;</summary>
		<author><name>Cnbrown4</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2015/ossE1558BGJ&amp;diff=98432</id>
		<title>CSC/ECE 517 Fall 2015/ossE1558BGJ</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2015/ossE1558BGJ&amp;diff=98432"/>
		<updated>2015-11-06T19:59:02Z</updated>

		<summary type="html">&lt;p&gt;Cnbrown4: /* References */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Introduction =&lt;br /&gt;
&lt;br /&gt;
This page provides a description of the modifications and improvements made to the Expertiza project’s source code as part of an Expertiza based Open Source Software project.  Expertiza is a web based application which allows students to submit and peer-review classmates’ work, including written articles and development projects. The specific changes made during the course of this project were to the ReviewResponseMap.rb file, with additional changes made to other related files in support of refactoring ReviewResponseMap.rb.  &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
= Problem Statement =&lt;br /&gt;
&lt;br /&gt;
ReviewResponseMap is the model class used to manage the relationship between contributors, reviewers, and assignments.  The intent of the changes were to refactor the code for better readability and adherence to Ruby coding standards and best practices.  Primarily these changes involved the refactoring of overly complex methods, renaming methods for better readability, and the addition of missing unit tests.&lt;br /&gt;
&lt;br /&gt;
Project Requirements:&lt;br /&gt;
&lt;br /&gt;
# Code Climate&amp;lt;ref name=&amp;quot;Code Climate&amp;quot;&amp;gt;https://codeclimate.com&amp;lt;/ref&amp;gt; shows import method is complex, because of lots of checks. This method can be fixed by adding private methods for raising import error.&lt;br /&gt;
# Get_assessments_round_for method can be renamed to get_team_responses_for_round. Team_id private variable is not needed.&lt;br /&gt;
# metareview_response_maps rename, refactoring can be done. No need to do second iteration.&lt;br /&gt;
# write missing unit tests for existing methods.&lt;br /&gt;
&lt;br /&gt;
= Design Patterns =&lt;br /&gt;
&lt;br /&gt;
As part of our project, we refactored the model to follow the Single Responsibility and Don't Repeat Yourself (DRY) Principles.  Both of the principles focus on reducing code repetition and increasing the cohesion of the individual methods in the class.  The Single Responsibility Principle states that each class and method should have sole responsibility over one single part of the functionality of the system&amp;lt;ref&amp;gt;https://en.wikipedia.org/wiki/Single_responsibility_principle&amp;lt;/ref&amp;gt;.  The DRY principle states that whenever the same types of logic and functionality are being performed in a class the duplicated logic should be extracted into a new method that can be called in place of the repeated lines of code &amp;lt;ref&amp;gt;https://en.wikipedia.org/wiki/Don%27t_repeat_yourself&amp;lt;/ref&amp;gt;.  A prime example of a method that initially violated these principles was the import method, which in addition to performing the core import processes also performed a number of checks that would be more properly extracted into private methods.&lt;br /&gt;
&lt;br /&gt;
=Code Changes =&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Refactoring of import method ===&lt;br /&gt;
&lt;br /&gt;
CodeClimate reports showed the import method to be overly complex, with a number of checks being included within the import method itself.  The resolution for this problem was to refactor the import method, creating private methods to perform the null checks and throw import errors.  Prior to refactoring, all null checks were performed within the import method.   After refactoring, the import method adheres to the single responsibility principle, performing only key import tasks while making calls to private methods for any necessary validation. The size of the import method was reduced by doing this and counts for better readability of the code. Also, this method is a very important one and care was taken so that any existing functionality did not break. &lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
Before refactoring:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;big&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 def self.import(row, session, id)&lt;br /&gt;
    if row.length &amp;lt; 2&lt;br /&gt;
      raise ArgumentError, &amp;quot;Not enough items&amp;quot;&lt;br /&gt;
    end&lt;br /&gt;
    assignment = Assignment.find(id)&lt;br /&gt;
    if assignment.nil?&lt;br /&gt;
      raise ImportError, &amp;quot;The assignment with id \&amp;quot;#{id}\&amp;quot; was not found. &amp;lt;a href='/assignment/new'&amp;gt;Create&amp;lt;/a&amp;gt; this assignment?&amp;quot;&lt;br /&gt;
    end&lt;br /&gt;
    index = 1&lt;br /&gt;
    while index &amp;lt; row.length&lt;br /&gt;
      user = User.find_by_name(row[index].to_s.strip)&lt;br /&gt;
      if user.nil?&lt;br /&gt;
        raise ImportError, &amp;quot;The user account for the reviewer \&amp;quot;#{row[index]}\&amp;quot; was not found. &amp;lt;a href='/users/new'&amp;gt;Create&amp;lt;/a&amp;gt; this user?&amp;quot;&lt;br /&gt;
      end&lt;br /&gt;
      reviewer = AssignmentParticipant.where(user_id: user.id, parent_id:  assignment.id).first&lt;br /&gt;
      if reviewer == nil&lt;br /&gt;
        raise ImportError, &amp;quot;The reviewer \&amp;quot;#{row[index]}\&amp;quot; is not a participant in this assignment. &amp;lt;a href='/users/new'&amp;gt;Register&amp;lt;/a&amp;gt; this user as a participant?&amp;quot;&lt;br /&gt;
      end&lt;br /&gt;
      if assignment.team_assignment&lt;br /&gt;
        reviewee = AssignmentTeam.where(name: row[0].to_s.strip, parent_id:  assignment.id).first&lt;br /&gt;
        if reviewee == nil&lt;br /&gt;
          raise ImportError, &amp;quot;The author \&amp;quot;#{row[0].to_s.strip}\&amp;quot; was not found. &amp;lt;a href='/users/new'&amp;gt;Create&amp;lt;/a&amp;gt; this user?&amp;quot;&lt;br /&gt;
        end&lt;br /&gt;
        existing = ReviewResponseMap.where(reviewee_id: reviewee.id, reviewer_id:  reviewer.id).first&lt;br /&gt;
        if existing.nil?&lt;br /&gt;
          ReviewResponseMap.create(:reviewer_id =&amp;gt; reviewer.id, :reviewee_id =&amp;gt; reviewee.id, :reviewed_object_id =&amp;gt; assignment.id)&lt;br /&gt;
        end&lt;br /&gt;
      else&lt;br /&gt;
        puser = User.find_by_name(row[0].to_s.strip)&lt;br /&gt;
        if user == nil&lt;br /&gt;
          raise ImportError, &amp;quot;The user account for the reviewee \&amp;quot;#{row[0]}\&amp;quot; was not found. &amp;lt;a href='/users/new'&amp;gt;Create&amp;lt;/a&amp;gt; this user?&amp;quot;&lt;br /&gt;
        end&lt;br /&gt;
        reviewee = AssignmentParticipant.where(user_id: puser.id, parent_id:  assignment.id).first&lt;br /&gt;
        if reviewee == nil&lt;br /&gt;
          raise ImportError, &amp;quot;The author \&amp;quot;#{row[0].to_s.strip}\&amp;quot; was not found. &amp;lt;a href='/users/new'&amp;gt;Create&amp;lt;/a&amp;gt; this user?&amp;quot;&lt;br /&gt;
        end&lt;br /&gt;
        team_id = TeamsUser.team_id(reviewee.parent_id, reviewee.user_id)&lt;br /&gt;
        existing = ReviewResponseMap.where(reviewee_id: team_id, reviewer_id:  reviewer.id).first&lt;br /&gt;
        if existing.nil?&lt;br /&gt;
          ReviewResponseMap.create(:reviewee_id =&amp;gt; team_id, :reviewer_id =&amp;gt; reviewer.id, :reviewed_object_id =&amp;gt; assignment.id)&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
      index += 1&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
&lt;br /&gt;
After refactoring:&lt;br /&gt;
 &lt;br /&gt;
  &amp;lt;big&amp;gt;&amp;lt;nowiki&amp;gt;#Imports new reponse maps if they do not already exist&lt;br /&gt;
  def self.import(row, _session, id)&lt;br /&gt;
      if row.length &amp;lt; 2&lt;br /&gt;
          raise ArgumentError, 'Not enough items'&lt;br /&gt;
      end&lt;br /&gt;
      assignment = find_assignment(id)&lt;br /&gt;
      index = 1&lt;br /&gt;
      reviewee_name = row[0]&lt;br /&gt;
      while index &amp;lt; row.length&lt;br /&gt;
          reviewee_id = nil&lt;br /&gt;
          reviewer_name = row[index]&lt;br /&gt;
          reviewer = get_assignment_participant(reviewer_name,  assignment.id, &amp;quot;reviewer&amp;quot;)&lt;br /&gt;
          participant_nil?(reviewer, reviewer_name , &amp;quot;reviewer&amp;quot;)&lt;br /&gt;
         &lt;br /&gt;
         #Find reviewee if assignment is a team assignment&lt;br /&gt;
         if assignment.team_assignment&lt;br /&gt;
             reviewee = AssignmentTeam.where(name: reviewee_name .to_s.strip, parent_id: assignment.id).first&lt;br /&gt;
             participant_nil?(reviewee, reviewee_name, &amp;quot;author&amp;quot;)&lt;br /&gt;
             reviewee_id = reviewee.id&lt;br /&gt;
         #Find reviewee if assignment is not a team assignment&lt;br /&gt;
         else&lt;br /&gt;
	     reviewee = get_assignment_participant(reviewee_name, assignment.id, &amp;quot;reviewee&amp;quot;)&lt;br /&gt;
             participant_nil?(reviewee, reviewee_name, &amp;quot;author&amp;quot;)&lt;br /&gt;
             reviewee_id  = TeamsUser.team_id(reviewee.parent_id, reviewee.user_id)&lt;br /&gt;
         end&lt;br /&gt;
         create_response_map(reviewer, reviewee_id,  assignment)&lt;br /&gt;
         index += 1&lt;br /&gt;
      end&lt;br /&gt;
  end&amp;lt;/nowiki&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Private methods added:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;big&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  # Check for if assignment value is null&lt;br /&gt;
  def self.find_assignment(id)&lt;br /&gt;
      begin&lt;br /&gt;
          assignment = Assignment.find(id)&lt;br /&gt;
      rescue ActiveRecord::RecordNotFound&lt;br /&gt;
          raise ImportError, &amp;quot;The assignment with id \&amp;quot;#{id}\&amp;quot; was not found.&amp;lt;a href='/assignment/new'&amp;gt;Create&amp;lt;/a&amp;gt; this assignment?&amp;quot;&lt;br /&gt;
      end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  # Check for if participant is null&lt;br /&gt;
  def self.participant_nil?(participant, user_name, participant_type) &lt;br /&gt;
      error_message = nil&lt;br /&gt;
      if participant_type == &amp;quot;author&amp;quot;&lt;br /&gt;
          error_message = &amp;quot;The author \&amp;quot;#{user_name.to_s.strip}\&amp;quot; was not found.&amp;lt;a href='/users/new'&amp;gt;Create&amp;lt;/a&amp;gt; this user?&amp;quot;&lt;br /&gt;
      else&lt;br /&gt;
          error_message =  &amp;quot;The reviewer \&amp;quot;#{user_name}\&amp;quot; is not a participant in this assignment.&amp;lt;a href='/users/new'&amp;gt;Register&amp;lt;/a&amp;gt; this user as a participant?&amp;quot;&lt;br /&gt;
      end&lt;br /&gt;
      check_nil?(participant, error_message)&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  # Check for if user is null&lt;br /&gt;
  def self.user_nil?(user, user_name, user_type)&lt;br /&gt;
      check_nil?( user, &amp;quot;The user account for the \&amp;quot;#{user_type}\&amp;quot; \&amp;quot;#{user_name}\&amp;quot; was not found.&amp;lt;a href='/users/new'&amp;gt;Create&amp;lt;/a&amp;gt; this user?&amp;quot;)&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
 #Throws import error for nil objects&lt;br /&gt;
  def self.check_nil?(object, error_message)&lt;br /&gt;
      if object.nil?&lt;br /&gt;
          raise ImportError, error_message&lt;br /&gt;
      end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Refactoring of get_assessments_round_for method ===&lt;br /&gt;
&lt;br /&gt;
The get_assessments_round_for method’s name failed to provide a clear idea of the method’s purpose and functionality.  This is why it was renamed to get_team_responses_for_round, the new name of the method provides a clearer idea of its purpose. Additionally, there was a private variable, team_id, introduced in the method that was unnecessary and could be replaced by using the id property of the team parameter directly.  &lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
Before refactoring:&lt;br /&gt;
&amp;lt;big&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  def self.get_assessments_round_for(team,round)&lt;br /&gt;
    team_id =team.id&lt;br /&gt;
    responses = Array.new&lt;br /&gt;
    if team_id&lt;br /&gt;
      maps = ResponseMap.where(:reviewee_id =&amp;gt; team_id, :type =&amp;gt; &amp;quot;ReviewResponseMap&amp;quot;)&lt;br /&gt;
      maps.each{ |map|&lt;br /&gt;
        if !map.response.empty? &amp;amp;&amp;amp; !map.response.reject{|r| r.round!=round}.empty?&lt;br /&gt;
          responses &amp;lt;&amp;lt; map.response.reject{|r| r.round!=round}.last&lt;br /&gt;
        end&lt;br /&gt;
      }&lt;br /&gt;
      responses.sort! {|a,b| a.map.reviewer.fullname &amp;lt;=&amp;gt; b.map.reviewer.fullname }&lt;br /&gt;
    end&lt;br /&gt;
    return responses&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
&lt;br /&gt;
After refactoring: &lt;br /&gt;
&lt;br /&gt;
&amp;lt;big&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  def self.get_team_responses_for_round(team, round)&lt;br /&gt;
    responses = []&lt;br /&gt;
    if team.id&lt;br /&gt;
      maps = ResponseMap.where(reviewee_id: team.id, type: 'ReviewResponseMap')&lt;br /&gt;
      maps.each do |map|&lt;br /&gt;
        unless map.response.empty? &amp;amp;&amp;amp; map.response.reject { |r| r.round != round }.empty?&lt;br /&gt;
          responses &amp;lt;&amp;lt; map.response.reject { |r| r.round != round }.last&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
      responses.sort! { |a, b| a.map.reviewer.fullname &amp;lt;=&amp;gt; b.map.reviewer.fullname }&lt;br /&gt;
    end&lt;br /&gt;
    responses&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
The change in method name also required changes to the following files that referenced it:&lt;br /&gt;
&lt;br /&gt;
/app/models/assignment.rb:436:    &lt;br /&gt;
 &lt;br /&gt;
&amp;lt;big&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  assessments = ReviewResponseMap.get_assessments_round_for(team,i)&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt; &lt;br /&gt;
&lt;br /&gt;
./app/models/assignment_participant.rb:268:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;big&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 scores[questionnaire_symbol][:assessments] = questionnaire.get_assessments_round_for(self,round)&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Refactoring of metareview_response_maps method ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The metareview_response_maps method was unnecessarily complex.  It contained an unneeded private variable and an unnecessary nested loop.  Originally, it added each metareview map individually in the nested loop.  We decided to remove the nested loop and use the concat method for readability and maintainability.  These changes allowed us to remove the private variable &amp;quot;metareview_list&amp;quot; and only maintain the &amp;quot;metareview_response_maps&amp;quot; variable.  We also renamed the metareview_response_maps method to get_metareview_response_maps method to be more descriptive about the intent of the method. &lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
Before refactoring:&lt;br /&gt;
&amp;lt;big&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 def metareview_response_maps&lt;br /&gt;
    responses = Response.where(map_id:self.id)&lt;br /&gt;
    metareview_list=[]&lt;br /&gt;
    responses.each do |response|&lt;br /&gt;
      metareview_response_maps = MetareviewResponseMap.where(reviewed_object_id:response.id)&lt;br /&gt;
      metareview_response_maps.each do |metareview_response_map|&lt;br /&gt;
        metareview_list&amp;lt;&amp;lt;metareview_response_map&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
    metareview_list&lt;br /&gt;
 end&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
After refactoring:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;big&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  def get_metareview_response_maps&lt;br /&gt;
    responses = Response.where(map_id: id)&lt;br /&gt;
    metareview_response_maps = []&lt;br /&gt;
    responses.each do |response|&lt;br /&gt;
      metareview_response_maps.concat MetareviewResponseMap.where(reviewed_object_id: response.id)&lt;br /&gt;
    end&lt;br /&gt;
    metareview_response_maps&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Addition of code comments ===&lt;br /&gt;
&lt;br /&gt;
We added comments to all of the methods in the ReviewResponseMap.rb file and corrected instances where CodeClimate Identified opportunities for code improvement.  One issue flagged by CodeClimate that we did not change was to use the find_by method instead of where().first method.  The where().first method occurs in the import, get_assignment_participant, and create_response_map methods. It is not always appropriate to use the find_by method, as documented in this github post: https://github.com/bbatsov/rubocop/issues/1938 .  In instances where ordering by id is the desired behavior, where().first will order by default, but in Rails 4+ find_by does not honor that default behavior.  For this reason we left the instances of where().first unchanged.&lt;br /&gt;
&lt;br /&gt;
=== Code Improvements ===&lt;br /&gt;
&lt;br /&gt;
This refactoring was to improve readability and follow as many good ''Rubyist'' coding practices as possible without breaking the functionality of existing code. We used CodeClimate of the master branch code as a reference. We took the suggestions we got from CodeClimate and improved our code based on that.&lt;br /&gt;
We also made some of the methods shorter by removing redundant functionality and adding private methods to methods with a lot internal functionality. We also added private methods in places where we saw repeated patterns to make the code ''DRYer''.&lt;br /&gt;
At the end of our refactoring, we managed to improve the rating on CodeClimate from a '''C''' to a '''B''' . Further improvements meant reducing the size of the entire class which required a much more significant refactoring in multiple files and folders. We focused on refactoring the existing model, '''ReviewResponseMap'''.&lt;br /&gt;
&lt;br /&gt;
= Unit Tests =&lt;br /&gt;
&lt;br /&gt;
=== Refactoring of Unit Tests===&lt;br /&gt;
&lt;br /&gt;
The previous unit tests had syntactical and run time errors.  We were not able to get the previous unit tests to run without errors.  Because of this we rewrote the unit tests for the &amp;lt;b&amp;gt;ReviewResponseModel&amp;lt;/b&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
We added a test_helper file to the main test folder that requires a needed configuration file and needed gems.  We also added 8 fixtures that were needed for data to run the unit tests.  The following fixture files were added:&lt;br /&gt;
&lt;br /&gt;
* assignment_questionnaires.yml&lt;br /&gt;
* assignments.yml&lt;br /&gt;
* participants.yml&lt;br /&gt;
* questionnaires.yml&lt;br /&gt;
* response_maps.yml&lt;br /&gt;
* responses.yml&lt;br /&gt;
* teams.yml&lt;br /&gt;
* users.yml&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
There is at least one unit test for every public method within the &amp;lt;b&amp;gt;ReviewResponseModel&amp;lt;/b&amp;gt;.  The test naming convention used is &amp;quot;method_&amp;lt;name of method that is being tested&amp;gt;&amp;quot;.  For example, the unit test for the export method is &amp;quot;method_export&amp;quot;.  If there are multiple test for one method the name of the test will include the test case after the normal naming convention.  For example, one of the unit tests for the import method checks for an invalid assignment.  The name of this method is &amp;quot;method_import_invalid_assignment&amp;quot;.  The following are the unit tests we created:&lt;br /&gt;
&lt;br /&gt;
* method_export&lt;br /&gt;
* method_get_metareview_response_maps&lt;br /&gt;
* method_get_team_response_for_round&lt;br /&gt;
* method_final_versions_from_reviewer&lt;br /&gt;
* method_import&lt;br /&gt;
* method_import_invalid_reviewee&lt;br /&gt;
* method_import_invalid_reviewer&lt;br /&gt;
* method_import_invalid_assignment&lt;br /&gt;
* method_delete&lt;br /&gt;
* method_delete_no _force&lt;br /&gt;
* method_show_feedback&lt;br /&gt;
* method_get_title&lt;br /&gt;
* method_export_fields&lt;br /&gt;
* method_questionnaire&lt;br /&gt;
* method_add_reviewer&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
=== How to Run Unit Tests ===&lt;br /&gt;
To run the unit tests, follow these steps:&lt;br /&gt;
&lt;br /&gt;
# Download the master branch of the repo.&lt;br /&gt;
# Setup the Databases for the test environment (we have used Zhewei's scrubbed expertiza DB )&lt;br /&gt;
#* Run the &amp;quot; rake db:create RAILS_ENV=test &amp;quot; command&lt;br /&gt;
#* Run the &amp;quot; rake db:reset RAILS_ENV=test &amp;quot; command&lt;br /&gt;
#* Scrub the DB using &amp;quot; mysql -u root expertiza_development &amp;lt; expertiza-scrubbed.sql&amp;quot;&lt;br /&gt;
#* Run the &amp;quot; rake db:migrate &amp;quot;&lt;br /&gt;
# Run &amp;quot; rake test test/unit/review_response_map_test.rb &amp;quot; in the &amp;quot;expertiza/&amp;quot; directory.&lt;br /&gt;
#* If you run into a mysql log in error go into config/database.yml and edit the mysql credentials for the test section so that it matches the local environment's mysql configuration&lt;br /&gt;
# Check if tests passed or failed.&lt;br /&gt;
&lt;br /&gt;
= Manual Test Case =&lt;br /&gt;
&lt;br /&gt;
In order to test the changes made to the ReviewResponseMap, bring up Expertiza and log in as an administrator.  Once logged in, proceed with the following steps:&lt;br /&gt;
&lt;br /&gt;
# Go to '''impersonate user''' when logged in as ''instructor6'' and type in ''student559'' (or) just log in as ''student559''. All passwords are ''password'' .&lt;br /&gt;
# Pick any assignment to view.&lt;br /&gt;
# Navigate to '''Other's work'''.&lt;br /&gt;
# Check the different reviews and metareviews. Whether they are being displayed correctly or not.&lt;br /&gt;
# Go to Edit or Give feedback and submit a feedback.&lt;br /&gt;
# Go back and check if the feedback given is displayed correctly or not.&lt;br /&gt;
# Check if author's feedback is correct or not.&lt;br /&gt;
# Go to the '''Temp''' assignment and see if the page is being displayed correctly or not (since there is no assignment submission content or reviews for that).&lt;br /&gt;
&lt;br /&gt;
''NOTE: Since this was a refactoring of the code and methods, the existing functionality was supposed to remain the same and not break for the changes we've made.''&lt;br /&gt;
&lt;br /&gt;
= References =&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;references/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;4.&amp;amp;nbsp; [https://github.com/expertiza/expertiza Expertiza Main Repo] &amp;lt;br&amp;gt;&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;5.&amp;amp;nbsp; [https://github.com/adeeshag/expertiza/blob/develop/app/models/review_response_map.rb Refactored ReviewResponseMap.rb]&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;6.&amp;amp;nbsp; [https://github.com/adeeshag/expertiza/tree/develop/test/fixtures Test Fixtures]&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;7.&amp;amp;nbsp; [https://github.com/adeeshag/expertiza/blob/develop/test/unit/review_response_map_test.rb Unit Tests]&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;8.&amp;amp;nbsp; [http://152.46.16.195:5902/ Expertiza Deployed Site]&amp;lt;br&amp;gt;&lt;/div&gt;</summary>
		<author><name>Cnbrown4</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2015/ossE1558BGJ&amp;diff=98431</id>
		<title>CSC/ECE 517 Fall 2015/ossE1558BGJ</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2015/ossE1558BGJ&amp;diff=98431"/>
		<updated>2015-11-06T19:58:00Z</updated>

		<summary type="html">&lt;p&gt;Cnbrown4: /* Code Improvements */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Introduction =&lt;br /&gt;
&lt;br /&gt;
This page provides a description of the modifications and improvements made to the Expertiza project’s source code as part of an Expertiza based Open Source Software project.  Expertiza is a web based application which allows students to submit and peer-review classmates’ work, including written articles and development projects. The specific changes made during the course of this project were to the ReviewResponseMap.rb file, with additional changes made to other related files in support of refactoring ReviewResponseMap.rb.  &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
= Problem Statement =&lt;br /&gt;
&lt;br /&gt;
ReviewResponseMap is the model class used to manage the relationship between contributors, reviewers, and assignments.  The intent of the changes were to refactor the code for better readability and adherence to Ruby coding standards and best practices.  Primarily these changes involved the refactoring of overly complex methods, renaming methods for better readability, and the addition of missing unit tests.&lt;br /&gt;
&lt;br /&gt;
Project Requirements:&lt;br /&gt;
&lt;br /&gt;
# Code Climate&amp;lt;ref name=&amp;quot;Code Climate&amp;quot;&amp;gt;https://codeclimate.com&amp;lt;/ref&amp;gt; shows import method is complex, because of lots of checks. This method can be fixed by adding private methods for raising import error.&lt;br /&gt;
# Get_assessments_round_for method can be renamed to get_team_responses_for_round. Team_id private variable is not needed.&lt;br /&gt;
# metareview_response_maps rename, refactoring can be done. No need to do second iteration.&lt;br /&gt;
# write missing unit tests for existing methods.&lt;br /&gt;
&lt;br /&gt;
= Design Patterns =&lt;br /&gt;
&lt;br /&gt;
As part of our project, we refactored the model to follow the Single Responsibility and Don't Repeat Yourself (DRY) Principles.  Both of the principles focus on reducing code repetition and increasing the cohesion of the individual methods in the class.  The Single Responsibility Principle states that each class and method should have sole responsibility over one single part of the functionality of the system&amp;lt;ref&amp;gt;https://en.wikipedia.org/wiki/Single_responsibility_principle&amp;lt;/ref&amp;gt;.  The DRY principle states that whenever the same types of logic and functionality are being performed in a class the duplicated logic should be extracted into a new method that can be called in place of the repeated lines of code &amp;lt;ref&amp;gt;https://en.wikipedia.org/wiki/Don%27t_repeat_yourself&amp;lt;/ref&amp;gt;.  A prime example of a method that initially violated these principles was the import method, which in addition to performing the core import processes also performed a number of checks that would be more properly extracted into private methods.&lt;br /&gt;
&lt;br /&gt;
=Code Changes =&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Refactoring of import method ===&lt;br /&gt;
&lt;br /&gt;
CodeClimate reports showed the import method to be overly complex, with a number of checks being included within the import method itself.  The resolution for this problem was to refactor the import method, creating private methods to perform the null checks and throw import errors.  Prior to refactoring, all null checks were performed within the import method.   After refactoring, the import method adheres to the single responsibility principle, performing only key import tasks while making calls to private methods for any necessary validation. The size of the import method was reduced by doing this and counts for better readability of the code. Also, this method is a very important one and care was taken so that any existing functionality did not break. &lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
Before refactoring:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;big&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 def self.import(row, session, id)&lt;br /&gt;
    if row.length &amp;lt; 2&lt;br /&gt;
      raise ArgumentError, &amp;quot;Not enough items&amp;quot;&lt;br /&gt;
    end&lt;br /&gt;
    assignment = Assignment.find(id)&lt;br /&gt;
    if assignment.nil?&lt;br /&gt;
      raise ImportError, &amp;quot;The assignment with id \&amp;quot;#{id}\&amp;quot; was not found. &amp;lt;a href='/assignment/new'&amp;gt;Create&amp;lt;/a&amp;gt; this assignment?&amp;quot;&lt;br /&gt;
    end&lt;br /&gt;
    index = 1&lt;br /&gt;
    while index &amp;lt; row.length&lt;br /&gt;
      user = User.find_by_name(row[index].to_s.strip)&lt;br /&gt;
      if user.nil?&lt;br /&gt;
        raise ImportError, &amp;quot;The user account for the reviewer \&amp;quot;#{row[index]}\&amp;quot; was not found. &amp;lt;a href='/users/new'&amp;gt;Create&amp;lt;/a&amp;gt; this user?&amp;quot;&lt;br /&gt;
      end&lt;br /&gt;
      reviewer = AssignmentParticipant.where(user_id: user.id, parent_id:  assignment.id).first&lt;br /&gt;
      if reviewer == nil&lt;br /&gt;
        raise ImportError, &amp;quot;The reviewer \&amp;quot;#{row[index]}\&amp;quot; is not a participant in this assignment. &amp;lt;a href='/users/new'&amp;gt;Register&amp;lt;/a&amp;gt; this user as a participant?&amp;quot;&lt;br /&gt;
      end&lt;br /&gt;
      if assignment.team_assignment&lt;br /&gt;
        reviewee = AssignmentTeam.where(name: row[0].to_s.strip, parent_id:  assignment.id).first&lt;br /&gt;
        if reviewee == nil&lt;br /&gt;
          raise ImportError, &amp;quot;The author \&amp;quot;#{row[0].to_s.strip}\&amp;quot; was not found. &amp;lt;a href='/users/new'&amp;gt;Create&amp;lt;/a&amp;gt; this user?&amp;quot;&lt;br /&gt;
        end&lt;br /&gt;
        existing = ReviewResponseMap.where(reviewee_id: reviewee.id, reviewer_id:  reviewer.id).first&lt;br /&gt;
        if existing.nil?&lt;br /&gt;
          ReviewResponseMap.create(:reviewer_id =&amp;gt; reviewer.id, :reviewee_id =&amp;gt; reviewee.id, :reviewed_object_id =&amp;gt; assignment.id)&lt;br /&gt;
        end&lt;br /&gt;
      else&lt;br /&gt;
        puser = User.find_by_name(row[0].to_s.strip)&lt;br /&gt;
        if user == nil&lt;br /&gt;
          raise ImportError, &amp;quot;The user account for the reviewee \&amp;quot;#{row[0]}\&amp;quot; was not found. &amp;lt;a href='/users/new'&amp;gt;Create&amp;lt;/a&amp;gt; this user?&amp;quot;&lt;br /&gt;
        end&lt;br /&gt;
        reviewee = AssignmentParticipant.where(user_id: puser.id, parent_id:  assignment.id).first&lt;br /&gt;
        if reviewee == nil&lt;br /&gt;
          raise ImportError, &amp;quot;The author \&amp;quot;#{row[0].to_s.strip}\&amp;quot; was not found. &amp;lt;a href='/users/new'&amp;gt;Create&amp;lt;/a&amp;gt; this user?&amp;quot;&lt;br /&gt;
        end&lt;br /&gt;
        team_id = TeamsUser.team_id(reviewee.parent_id, reviewee.user_id)&lt;br /&gt;
        existing = ReviewResponseMap.where(reviewee_id: team_id, reviewer_id:  reviewer.id).first&lt;br /&gt;
        if existing.nil?&lt;br /&gt;
          ReviewResponseMap.create(:reviewee_id =&amp;gt; team_id, :reviewer_id =&amp;gt; reviewer.id, :reviewed_object_id =&amp;gt; assignment.id)&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
      index += 1&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
&lt;br /&gt;
After refactoring:&lt;br /&gt;
 &lt;br /&gt;
  &amp;lt;big&amp;gt;&amp;lt;nowiki&amp;gt;#Imports new reponse maps if they do not already exist&lt;br /&gt;
  def self.import(row, _session, id)&lt;br /&gt;
      if row.length &amp;lt; 2&lt;br /&gt;
          raise ArgumentError, 'Not enough items'&lt;br /&gt;
      end&lt;br /&gt;
      assignment = find_assignment(id)&lt;br /&gt;
      index = 1&lt;br /&gt;
      reviewee_name = row[0]&lt;br /&gt;
      while index &amp;lt; row.length&lt;br /&gt;
          reviewee_id = nil&lt;br /&gt;
          reviewer_name = row[index]&lt;br /&gt;
          reviewer = get_assignment_participant(reviewer_name,  assignment.id, &amp;quot;reviewer&amp;quot;)&lt;br /&gt;
          participant_nil?(reviewer, reviewer_name , &amp;quot;reviewer&amp;quot;)&lt;br /&gt;
         &lt;br /&gt;
         #Find reviewee if assignment is a team assignment&lt;br /&gt;
         if assignment.team_assignment&lt;br /&gt;
             reviewee = AssignmentTeam.where(name: reviewee_name .to_s.strip, parent_id: assignment.id).first&lt;br /&gt;
             participant_nil?(reviewee, reviewee_name, &amp;quot;author&amp;quot;)&lt;br /&gt;
             reviewee_id = reviewee.id&lt;br /&gt;
         #Find reviewee if assignment is not a team assignment&lt;br /&gt;
         else&lt;br /&gt;
	     reviewee = get_assignment_participant(reviewee_name, assignment.id, &amp;quot;reviewee&amp;quot;)&lt;br /&gt;
             participant_nil?(reviewee, reviewee_name, &amp;quot;author&amp;quot;)&lt;br /&gt;
             reviewee_id  = TeamsUser.team_id(reviewee.parent_id, reviewee.user_id)&lt;br /&gt;
         end&lt;br /&gt;
         create_response_map(reviewer, reviewee_id,  assignment)&lt;br /&gt;
         index += 1&lt;br /&gt;
      end&lt;br /&gt;
  end&amp;lt;/nowiki&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Private methods added:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;big&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  # Check for if assignment value is null&lt;br /&gt;
  def self.find_assignment(id)&lt;br /&gt;
      begin&lt;br /&gt;
          assignment = Assignment.find(id)&lt;br /&gt;
      rescue ActiveRecord::RecordNotFound&lt;br /&gt;
          raise ImportError, &amp;quot;The assignment with id \&amp;quot;#{id}\&amp;quot; was not found.&amp;lt;a href='/assignment/new'&amp;gt;Create&amp;lt;/a&amp;gt; this assignment?&amp;quot;&lt;br /&gt;
      end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  # Check for if participant is null&lt;br /&gt;
  def self.participant_nil?(participant, user_name, participant_type) &lt;br /&gt;
      error_message = nil&lt;br /&gt;
      if participant_type == &amp;quot;author&amp;quot;&lt;br /&gt;
          error_message = &amp;quot;The author \&amp;quot;#{user_name.to_s.strip}\&amp;quot; was not found.&amp;lt;a href='/users/new'&amp;gt;Create&amp;lt;/a&amp;gt; this user?&amp;quot;&lt;br /&gt;
      else&lt;br /&gt;
          error_message =  &amp;quot;The reviewer \&amp;quot;#{user_name}\&amp;quot; is not a participant in this assignment.&amp;lt;a href='/users/new'&amp;gt;Register&amp;lt;/a&amp;gt; this user as a participant?&amp;quot;&lt;br /&gt;
      end&lt;br /&gt;
      check_nil?(participant, error_message)&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  # Check for if user is null&lt;br /&gt;
  def self.user_nil?(user, user_name, user_type)&lt;br /&gt;
      check_nil?( user, &amp;quot;The user account for the \&amp;quot;#{user_type}\&amp;quot; \&amp;quot;#{user_name}\&amp;quot; was not found.&amp;lt;a href='/users/new'&amp;gt;Create&amp;lt;/a&amp;gt; this user?&amp;quot;)&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
 #Throws import error for nil objects&lt;br /&gt;
  def self.check_nil?(object, error_message)&lt;br /&gt;
      if object.nil?&lt;br /&gt;
          raise ImportError, error_message&lt;br /&gt;
      end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Refactoring of get_assessments_round_for method ===&lt;br /&gt;
&lt;br /&gt;
The get_assessments_round_for method’s name failed to provide a clear idea of the method’s purpose and functionality.  This is why it was renamed to get_team_responses_for_round, the new name of the method provides a clearer idea of its purpose. Additionally, there was a private variable, team_id, introduced in the method that was unnecessary and could be replaced by using the id property of the team parameter directly.  &lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
Before refactoring:&lt;br /&gt;
&amp;lt;big&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  def self.get_assessments_round_for(team,round)&lt;br /&gt;
    team_id =team.id&lt;br /&gt;
    responses = Array.new&lt;br /&gt;
    if team_id&lt;br /&gt;
      maps = ResponseMap.where(:reviewee_id =&amp;gt; team_id, :type =&amp;gt; &amp;quot;ReviewResponseMap&amp;quot;)&lt;br /&gt;
      maps.each{ |map|&lt;br /&gt;
        if !map.response.empty? &amp;amp;&amp;amp; !map.response.reject{|r| r.round!=round}.empty?&lt;br /&gt;
          responses &amp;lt;&amp;lt; map.response.reject{|r| r.round!=round}.last&lt;br /&gt;
        end&lt;br /&gt;
      }&lt;br /&gt;
      responses.sort! {|a,b| a.map.reviewer.fullname &amp;lt;=&amp;gt; b.map.reviewer.fullname }&lt;br /&gt;
    end&lt;br /&gt;
    return responses&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
&lt;br /&gt;
After refactoring: &lt;br /&gt;
&lt;br /&gt;
&amp;lt;big&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  def self.get_team_responses_for_round(team, round)&lt;br /&gt;
    responses = []&lt;br /&gt;
    if team.id&lt;br /&gt;
      maps = ResponseMap.where(reviewee_id: team.id, type: 'ReviewResponseMap')&lt;br /&gt;
      maps.each do |map|&lt;br /&gt;
        unless map.response.empty? &amp;amp;&amp;amp; map.response.reject { |r| r.round != round }.empty?&lt;br /&gt;
          responses &amp;lt;&amp;lt; map.response.reject { |r| r.round != round }.last&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
      responses.sort! { |a, b| a.map.reviewer.fullname &amp;lt;=&amp;gt; b.map.reviewer.fullname }&lt;br /&gt;
    end&lt;br /&gt;
    responses&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
The change in method name also required changes to the following files that referenced it:&lt;br /&gt;
&lt;br /&gt;
/app/models/assignment.rb:436:    &lt;br /&gt;
 &lt;br /&gt;
&amp;lt;big&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  assessments = ReviewResponseMap.get_assessments_round_for(team,i)&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt; &lt;br /&gt;
&lt;br /&gt;
./app/models/assignment_participant.rb:268:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;big&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 scores[questionnaire_symbol][:assessments] = questionnaire.get_assessments_round_for(self,round)&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Refactoring of metareview_response_maps method ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The metareview_response_maps method was unnecessarily complex.  It contained an unneeded private variable and an unnecessary nested loop.  Originally, it added each metareview map individually in the nested loop.  We decided to remove the nested loop and use the concat method for readability and maintainability.  These changes allowed us to remove the private variable &amp;quot;metareview_list&amp;quot; and only maintain the &amp;quot;metareview_response_maps&amp;quot; variable.  We also renamed the metareview_response_maps method to get_metareview_response_maps method to be more descriptive about the intent of the method. &lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
Before refactoring:&lt;br /&gt;
&amp;lt;big&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 def metareview_response_maps&lt;br /&gt;
    responses = Response.where(map_id:self.id)&lt;br /&gt;
    metareview_list=[]&lt;br /&gt;
    responses.each do |response|&lt;br /&gt;
      metareview_response_maps = MetareviewResponseMap.where(reviewed_object_id:response.id)&lt;br /&gt;
      metareview_response_maps.each do |metareview_response_map|&lt;br /&gt;
        metareview_list&amp;lt;&amp;lt;metareview_response_map&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
    metareview_list&lt;br /&gt;
 end&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
After refactoring:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;big&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  def get_metareview_response_maps&lt;br /&gt;
    responses = Response.where(map_id: id)&lt;br /&gt;
    metareview_response_maps = []&lt;br /&gt;
    responses.each do |response|&lt;br /&gt;
      metareview_response_maps.concat MetareviewResponseMap.where(reviewed_object_id: response.id)&lt;br /&gt;
    end&lt;br /&gt;
    metareview_response_maps&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Addition of code comments ===&lt;br /&gt;
&lt;br /&gt;
We added comments to all of the methods in the ReviewResponseMap.rb file and corrected instances where CodeClimate Identified opportunities for code improvement.  One issue flagged by CodeClimate that we did not change was to use the find_by method instead of where().first method.  The where().first method occurs in the import, get_assignment_participant, and create_response_map methods. It is not always appropriate to use the find_by method, as documented in this github post: https://github.com/bbatsov/rubocop/issues/1938 .  In instances where ordering by id is the desired behavior, where().first will order by default, but in Rails 4+ find_by does not honor that default behavior.  For this reason we left the instances of where().first unchanged.&lt;br /&gt;
&lt;br /&gt;
=== Code Improvements ===&lt;br /&gt;
&lt;br /&gt;
This refactoring was to improve readability and follow as many good ''Rubyist'' coding practices as possible without breaking the functionality of existing code. We used CodeClimate of the master branch code as a reference. We took the suggestions we got from CodeClimate and improved our code based on that.&lt;br /&gt;
We also made some of the methods shorter by removing redundant functionality and adding private methods to methods with a lot internal functionality. We also added private methods in places where we saw repeated patterns to make the code ''DRYer''.&lt;br /&gt;
At the end of our refactoring, we managed to improve the rating on CodeClimate from a '''C''' to a '''B''' . Further improvements meant reducing the size of the entire class which required a much more significant refactoring in multiple files and folders. We focused on refactoring the existing model, '''ReviewResponseMap'''.&lt;br /&gt;
&lt;br /&gt;
= Unit Tests =&lt;br /&gt;
&lt;br /&gt;
=== Refactoring of Unit Tests===&lt;br /&gt;
&lt;br /&gt;
The previous unit tests had syntactical and run time errors.  We were not able to get the previous unit tests to run without errors.  Because of this we rewrote the unit tests for the &amp;lt;b&amp;gt;ReviewResponseModel&amp;lt;/b&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
We added a test_helper file to the main test folder that requires a needed configuration file and needed gems.  We also added 8 fixtures that were needed for data to run the unit tests.  The following fixture files were added:&lt;br /&gt;
&lt;br /&gt;
* assignment_questionnaires.yml&lt;br /&gt;
* assignments.yml&lt;br /&gt;
* participants.yml&lt;br /&gt;
* questionnaires.yml&lt;br /&gt;
* response_maps.yml&lt;br /&gt;
* responses.yml&lt;br /&gt;
* teams.yml&lt;br /&gt;
* users.yml&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
There is at least one unit test for every public method within the &amp;lt;b&amp;gt;ReviewResponseModel&amp;lt;/b&amp;gt;.  The test naming convention used is &amp;quot;method_&amp;lt;name of method that is being tested&amp;gt;&amp;quot;.  For example, the unit test for the export method is &amp;quot;method_export&amp;quot;.  If there are multiple test for one method the name of the test will include the test case after the normal naming convention.  For example, one of the unit tests for the import method checks for an invalid assignment.  The name of this method is &amp;quot;method_import_invalid_assignment&amp;quot;.  The following are the unit tests we created:&lt;br /&gt;
&lt;br /&gt;
* method_export&lt;br /&gt;
* method_get_metareview_response_maps&lt;br /&gt;
* method_get_team_response_for_round&lt;br /&gt;
* method_final_versions_from_reviewer&lt;br /&gt;
* method_import&lt;br /&gt;
* method_import_invalid_reviewee&lt;br /&gt;
* method_import_invalid_reviewer&lt;br /&gt;
* method_import_invalid_assignment&lt;br /&gt;
* method_delete&lt;br /&gt;
* method_delete_no _force&lt;br /&gt;
* method_show_feedback&lt;br /&gt;
* method_get_title&lt;br /&gt;
* method_export_fields&lt;br /&gt;
* method_questionnaire&lt;br /&gt;
* method_add_reviewer&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
=== How to Run Unit Tests ===&lt;br /&gt;
To run the unit tests, follow these steps:&lt;br /&gt;
&lt;br /&gt;
# Download the master branch of the repo.&lt;br /&gt;
# Setup the Databases for the test environment (we have used Zhewei's scrubbed expertiza DB )&lt;br /&gt;
#* Run the &amp;quot; rake db:create RAILS_ENV=test &amp;quot; command&lt;br /&gt;
#* Run the &amp;quot; rake db:reset RAILS_ENV=test &amp;quot; command&lt;br /&gt;
#* Scrub the DB using &amp;quot; mysql -u root expertiza_development &amp;lt; expertiza-scrubbed.sql&amp;quot;&lt;br /&gt;
#* Run the &amp;quot; rake db:migrate &amp;quot;&lt;br /&gt;
# Run &amp;quot; rake test test/unit/review_response_map_test.rb &amp;quot; in the &amp;quot;expertiza/&amp;quot; directory.&lt;br /&gt;
#* If you run into a mysql log in error go into config/database.yml and edit the mysql credentials for the test section so that it matches the local environment's mysql configuration&lt;br /&gt;
# Check if tests passed or failed.&lt;br /&gt;
&lt;br /&gt;
= Manual Test Case =&lt;br /&gt;
&lt;br /&gt;
In order to test the changes made to the ReviewResponseMap, bring up Expertiza and log in as an administrator.  Once logged in, proceed with the following steps:&lt;br /&gt;
&lt;br /&gt;
# Go to '''impersonate user''' when logged in as ''instructor6'' and type in ''student559'' (or) just log in as ''student559''. All passwords are ''password'' .&lt;br /&gt;
# Pick any assignment to view.&lt;br /&gt;
# Navigate to '''Other's work'''.&lt;br /&gt;
# Check the different reviews and metareviews. Whether they are being displayed correctly or not.&lt;br /&gt;
# Go to Edit or Give feedback and submit a feedback.&lt;br /&gt;
# Go back and check if the feedback given is displayed correctly or not.&lt;br /&gt;
# Check if author's feedback is correct or not.&lt;br /&gt;
# Go to the '''Temp''' assignment and see if the page is being displayed correctly or not (since there is no assignment submission content or reviews for that).&lt;br /&gt;
&lt;br /&gt;
''NOTE: Since this was a refactoring of the code and methods, the existing functionality was supposed to remain the same and not break for the changes we've made.''&lt;br /&gt;
&lt;br /&gt;
= References =&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;references/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;3. [https://github.com/expertiza/expertiza Expertiza Main Repo] &amp;lt;br&amp;gt;&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;4. [https://github.com/adeeshag/expertiza/blob/develop/app/models/review_response_map.rb Refactored ReviewResponseMap.rb]&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;5. [https://github.com/adeeshag/expertiza/tree/develop/test/fixtures Test Fixtures]&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;6. [https://github.com/adeeshag/expertiza/blob/develop/test/unit/review_response_map_test.rb Unit Tests]&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;6. [http://152.46.16.195:5902/ Expertiza Deployed Site]&amp;lt;br&amp;gt;&lt;/div&gt;</summary>
		<author><name>Cnbrown4</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2015/ossE1558BGJ&amp;diff=98429</id>
		<title>CSC/ECE 517 Fall 2015/ossE1558BGJ</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2015/ossE1558BGJ&amp;diff=98429"/>
		<updated>2015-11-06T19:55:30Z</updated>

		<summary type="html">&lt;p&gt;Cnbrown4: /* Refactoring of import method */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Introduction =&lt;br /&gt;
&lt;br /&gt;
This page provides a description of the modifications and improvements made to the Expertiza project’s source code as part of an Expertiza based Open Source Software project.  Expertiza is a web based application which allows students to submit and peer-review classmates’ work, including written articles and development projects. The specific changes made during the course of this project were to the ReviewResponseMap.rb file, with additional changes made to other related files in support of refactoring ReviewResponseMap.rb.  &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
= Problem Statement =&lt;br /&gt;
&lt;br /&gt;
ReviewResponseMap is the model class used to manage the relationship between contributors, reviewers, and assignments.  The intent of the changes were to refactor the code for better readability and adherence to Ruby coding standards and best practices.  Primarily these changes involved the refactoring of overly complex methods, renaming methods for better readability, and the addition of missing unit tests.&lt;br /&gt;
&lt;br /&gt;
Project Requirements:&lt;br /&gt;
&lt;br /&gt;
# Code Climate&amp;lt;ref name=&amp;quot;Code Climate&amp;quot;&amp;gt;https://codeclimate.com&amp;lt;/ref&amp;gt; shows import method is complex, because of lots of checks. This method can be fixed by adding private methods for raising import error.&lt;br /&gt;
# Get_assessments_round_for method can be renamed to get_team_responses_for_round. Team_id private variable is not needed.&lt;br /&gt;
# metareview_response_maps rename, refactoring can be done. No need to do second iteration.&lt;br /&gt;
# write missing unit tests for existing methods.&lt;br /&gt;
&lt;br /&gt;
= Design Patterns =&lt;br /&gt;
&lt;br /&gt;
As part of our project, we refactored the model to follow the Single Responsibility and Don't Repeat Yourself (DRY) Principles.  Both of the principles focus on reducing code repetition and increasing the cohesion of the individual methods in the class.  The Single Responsibility Principle states that each class and method should have sole responsibility over one single part of the functionality of the system&amp;lt;ref&amp;gt;https://en.wikipedia.org/wiki/Single_responsibility_principle&amp;lt;/ref&amp;gt;.  The DRY principle states that whenever the same types of logic and functionality are being performed in a class the duplicated logic should be extracted into a new method that can be called in place of the repeated lines of code &amp;lt;ref&amp;gt;https://en.wikipedia.org/wiki/Don%27t_repeat_yourself&amp;lt;/ref&amp;gt;.  A prime example of a method that initially violated these principles was the import method, which in addition to performing the core import processes also performed a number of checks that would be more properly extracted into private methods.&lt;br /&gt;
&lt;br /&gt;
=Code Changes =&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Refactoring of import method ===&lt;br /&gt;
&lt;br /&gt;
CodeClimate reports showed the import method to be overly complex, with a number of checks being included within the import method itself.  The resolution for this problem was to refactor the import method, creating private methods to perform the null checks and throw import errors.  Prior to refactoring, all null checks were performed within the import method.   After refactoring, the import method adheres to the single responsibility principle, performing only key import tasks while making calls to private methods for any necessary validation. The size of the import method was reduced by doing this and counts for better readability of the code. Also, this method is a very important one and care was taken so that any existing functionality did not break. &lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
Before refactoring:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;big&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 def self.import(row, session, id)&lt;br /&gt;
    if row.length &amp;lt; 2&lt;br /&gt;
      raise ArgumentError, &amp;quot;Not enough items&amp;quot;&lt;br /&gt;
    end&lt;br /&gt;
    assignment = Assignment.find(id)&lt;br /&gt;
    if assignment.nil?&lt;br /&gt;
      raise ImportError, &amp;quot;The assignment with id \&amp;quot;#{id}\&amp;quot; was not found. &amp;lt;a href='/assignment/new'&amp;gt;Create&amp;lt;/a&amp;gt; this assignment?&amp;quot;&lt;br /&gt;
    end&lt;br /&gt;
    index = 1&lt;br /&gt;
    while index &amp;lt; row.length&lt;br /&gt;
      user = User.find_by_name(row[index].to_s.strip)&lt;br /&gt;
      if user.nil?&lt;br /&gt;
        raise ImportError, &amp;quot;The user account for the reviewer \&amp;quot;#{row[index]}\&amp;quot; was not found. &amp;lt;a href='/users/new'&amp;gt;Create&amp;lt;/a&amp;gt; this user?&amp;quot;&lt;br /&gt;
      end&lt;br /&gt;
      reviewer = AssignmentParticipant.where(user_id: user.id, parent_id:  assignment.id).first&lt;br /&gt;
      if reviewer == nil&lt;br /&gt;
        raise ImportError, &amp;quot;The reviewer \&amp;quot;#{row[index]}\&amp;quot; is not a participant in this assignment. &amp;lt;a href='/users/new'&amp;gt;Register&amp;lt;/a&amp;gt; this user as a participant?&amp;quot;&lt;br /&gt;
      end&lt;br /&gt;
      if assignment.team_assignment&lt;br /&gt;
        reviewee = AssignmentTeam.where(name: row[0].to_s.strip, parent_id:  assignment.id).first&lt;br /&gt;
        if reviewee == nil&lt;br /&gt;
          raise ImportError, &amp;quot;The author \&amp;quot;#{row[0].to_s.strip}\&amp;quot; was not found. &amp;lt;a href='/users/new'&amp;gt;Create&amp;lt;/a&amp;gt; this user?&amp;quot;&lt;br /&gt;
        end&lt;br /&gt;
        existing = ReviewResponseMap.where(reviewee_id: reviewee.id, reviewer_id:  reviewer.id).first&lt;br /&gt;
        if existing.nil?&lt;br /&gt;
          ReviewResponseMap.create(:reviewer_id =&amp;gt; reviewer.id, :reviewee_id =&amp;gt; reviewee.id, :reviewed_object_id =&amp;gt; assignment.id)&lt;br /&gt;
        end&lt;br /&gt;
      else&lt;br /&gt;
        puser = User.find_by_name(row[0].to_s.strip)&lt;br /&gt;
        if user == nil&lt;br /&gt;
          raise ImportError, &amp;quot;The user account for the reviewee \&amp;quot;#{row[0]}\&amp;quot; was not found. &amp;lt;a href='/users/new'&amp;gt;Create&amp;lt;/a&amp;gt; this user?&amp;quot;&lt;br /&gt;
        end&lt;br /&gt;
        reviewee = AssignmentParticipant.where(user_id: puser.id, parent_id:  assignment.id).first&lt;br /&gt;
        if reviewee == nil&lt;br /&gt;
          raise ImportError, &amp;quot;The author \&amp;quot;#{row[0].to_s.strip}\&amp;quot; was not found. &amp;lt;a href='/users/new'&amp;gt;Create&amp;lt;/a&amp;gt; this user?&amp;quot;&lt;br /&gt;
        end&lt;br /&gt;
        team_id = TeamsUser.team_id(reviewee.parent_id, reviewee.user_id)&lt;br /&gt;
        existing = ReviewResponseMap.where(reviewee_id: team_id, reviewer_id:  reviewer.id).first&lt;br /&gt;
        if existing.nil?&lt;br /&gt;
          ReviewResponseMap.create(:reviewee_id =&amp;gt; team_id, :reviewer_id =&amp;gt; reviewer.id, :reviewed_object_id =&amp;gt; assignment.id)&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
      index += 1&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
&lt;br /&gt;
After refactoring:&lt;br /&gt;
 &lt;br /&gt;
  &amp;lt;big&amp;gt;&amp;lt;nowiki&amp;gt;#Imports new reponse maps if they do not already exist&lt;br /&gt;
  def self.import(row, _session, id)&lt;br /&gt;
      if row.length &amp;lt; 2&lt;br /&gt;
          raise ArgumentError, 'Not enough items'&lt;br /&gt;
      end&lt;br /&gt;
      assignment = find_assignment(id)&lt;br /&gt;
      index = 1&lt;br /&gt;
      reviewee_name = row[0]&lt;br /&gt;
      while index &amp;lt; row.length&lt;br /&gt;
          reviewee_id = nil&lt;br /&gt;
          reviewer_name = row[index]&lt;br /&gt;
          reviewer = get_assignment_participant(reviewer_name,  assignment.id, &amp;quot;reviewer&amp;quot;)&lt;br /&gt;
          participant_nil?(reviewer, reviewer_name , &amp;quot;reviewer&amp;quot;)&lt;br /&gt;
         &lt;br /&gt;
         #Find reviewee if assignment is a team assignment&lt;br /&gt;
         if assignment.team_assignment&lt;br /&gt;
             reviewee = AssignmentTeam.where(name: reviewee_name .to_s.strip, parent_id: assignment.id).first&lt;br /&gt;
             participant_nil?(reviewee, reviewee_name, &amp;quot;author&amp;quot;)&lt;br /&gt;
             reviewee_id = reviewee.id&lt;br /&gt;
         #Find reviewee if assignment is not a team assignment&lt;br /&gt;
         else&lt;br /&gt;
	     reviewee = get_assignment_participant(reviewee_name, assignment.id, &amp;quot;reviewee&amp;quot;)&lt;br /&gt;
             participant_nil?(reviewee, reviewee_name, &amp;quot;author&amp;quot;)&lt;br /&gt;
             reviewee_id  = TeamsUser.team_id(reviewee.parent_id, reviewee.user_id)&lt;br /&gt;
         end&lt;br /&gt;
         create_response_map(reviewer, reviewee_id,  assignment)&lt;br /&gt;
         index += 1&lt;br /&gt;
      end&lt;br /&gt;
  end&amp;lt;/nowiki&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Private methods added:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;big&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  # Check for if assignment value is null&lt;br /&gt;
  def self.find_assignment(id)&lt;br /&gt;
      begin&lt;br /&gt;
          assignment = Assignment.find(id)&lt;br /&gt;
      rescue ActiveRecord::RecordNotFound&lt;br /&gt;
          raise ImportError, &amp;quot;The assignment with id \&amp;quot;#{id}\&amp;quot; was not found.&amp;lt;a href='/assignment/new'&amp;gt;Create&amp;lt;/a&amp;gt; this assignment?&amp;quot;&lt;br /&gt;
      end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  # Check for if participant is null&lt;br /&gt;
  def self.participant_nil?(participant, user_name, participant_type) &lt;br /&gt;
      error_message = nil&lt;br /&gt;
      if participant_type == &amp;quot;author&amp;quot;&lt;br /&gt;
          error_message = &amp;quot;The author \&amp;quot;#{user_name.to_s.strip}\&amp;quot; was not found.&amp;lt;a href='/users/new'&amp;gt;Create&amp;lt;/a&amp;gt; this user?&amp;quot;&lt;br /&gt;
      else&lt;br /&gt;
          error_message =  &amp;quot;The reviewer \&amp;quot;#{user_name}\&amp;quot; is not a participant in this assignment.&amp;lt;a href='/users/new'&amp;gt;Register&amp;lt;/a&amp;gt; this user as a participant?&amp;quot;&lt;br /&gt;
      end&lt;br /&gt;
      check_nil?(participant, error_message)&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  # Check for if user is null&lt;br /&gt;
  def self.user_nil?(user, user_name, user_type)&lt;br /&gt;
      check_nil?( user, &amp;quot;The user account for the \&amp;quot;#{user_type}\&amp;quot; \&amp;quot;#{user_name}\&amp;quot; was not found.&amp;lt;a href='/users/new'&amp;gt;Create&amp;lt;/a&amp;gt; this user?&amp;quot;)&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
 #Throws import error for nil objects&lt;br /&gt;
  def self.check_nil?(object, error_message)&lt;br /&gt;
      if object.nil?&lt;br /&gt;
          raise ImportError, error_message&lt;br /&gt;
      end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Refactoring of get_assessments_round_for method ===&lt;br /&gt;
&lt;br /&gt;
The get_assessments_round_for method’s name failed to provide a clear idea of the method’s purpose and functionality.  This is why it was renamed to get_team_responses_for_round, the new name of the method provides a clearer idea of its purpose. Additionally, there was a private variable, team_id, introduced in the method that was unnecessary and could be replaced by using the id property of the team parameter directly.  &lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
Before refactoring:&lt;br /&gt;
&amp;lt;big&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  def self.get_assessments_round_for(team,round)&lt;br /&gt;
    team_id =team.id&lt;br /&gt;
    responses = Array.new&lt;br /&gt;
    if team_id&lt;br /&gt;
      maps = ResponseMap.where(:reviewee_id =&amp;gt; team_id, :type =&amp;gt; &amp;quot;ReviewResponseMap&amp;quot;)&lt;br /&gt;
      maps.each{ |map|&lt;br /&gt;
        if !map.response.empty? &amp;amp;&amp;amp; !map.response.reject{|r| r.round!=round}.empty?&lt;br /&gt;
          responses &amp;lt;&amp;lt; map.response.reject{|r| r.round!=round}.last&lt;br /&gt;
        end&lt;br /&gt;
      }&lt;br /&gt;
      responses.sort! {|a,b| a.map.reviewer.fullname &amp;lt;=&amp;gt; b.map.reviewer.fullname }&lt;br /&gt;
    end&lt;br /&gt;
    return responses&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
&lt;br /&gt;
After refactoring: &lt;br /&gt;
&lt;br /&gt;
&amp;lt;big&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  def self.get_team_responses_for_round(team, round)&lt;br /&gt;
    responses = []&lt;br /&gt;
    if team.id&lt;br /&gt;
      maps = ResponseMap.where(reviewee_id: team.id, type: 'ReviewResponseMap')&lt;br /&gt;
      maps.each do |map|&lt;br /&gt;
        unless map.response.empty? &amp;amp;&amp;amp; map.response.reject { |r| r.round != round }.empty?&lt;br /&gt;
          responses &amp;lt;&amp;lt; map.response.reject { |r| r.round != round }.last&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
      responses.sort! { |a, b| a.map.reviewer.fullname &amp;lt;=&amp;gt; b.map.reviewer.fullname }&lt;br /&gt;
    end&lt;br /&gt;
    responses&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
The change in method name also required changes to the following files that referenced it:&lt;br /&gt;
&lt;br /&gt;
/app/models/assignment.rb:436:    &lt;br /&gt;
 &lt;br /&gt;
&amp;lt;big&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  assessments = ReviewResponseMap.get_assessments_round_for(team,i)&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt; &lt;br /&gt;
&lt;br /&gt;
./app/models/assignment_participant.rb:268:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;big&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 scores[questionnaire_symbol][:assessments] = questionnaire.get_assessments_round_for(self,round)&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Refactoring of metareview_response_maps method ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The metareview_response_maps method was unnecessarily complex.  It contained an unneeded private variable and an unnecessary nested loop.  Originally, it added each metareview map individually in the nested loop.  We decided to remove the nested loop and use the concat method for readability and maintainability.  These changes allowed us to remove the private variable &amp;quot;metareview_list&amp;quot; and only maintain the &amp;quot;metareview_response_maps&amp;quot; variable.  We also renamed the metareview_response_maps method to get_metareview_response_maps method to be more descriptive about the intent of the method. &lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
Before refactoring:&lt;br /&gt;
&amp;lt;big&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 def metareview_response_maps&lt;br /&gt;
    responses = Response.where(map_id:self.id)&lt;br /&gt;
    metareview_list=[]&lt;br /&gt;
    responses.each do |response|&lt;br /&gt;
      metareview_response_maps = MetareviewResponseMap.where(reviewed_object_id:response.id)&lt;br /&gt;
      metareview_response_maps.each do |metareview_response_map|&lt;br /&gt;
        metareview_list&amp;lt;&amp;lt;metareview_response_map&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
    metareview_list&lt;br /&gt;
 end&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
After refactoring:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;big&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  def get_metareview_response_maps&lt;br /&gt;
    responses = Response.where(map_id: id)&lt;br /&gt;
    metareview_response_maps = []&lt;br /&gt;
    responses.each do |response|&lt;br /&gt;
      metareview_response_maps.concat MetareviewResponseMap.where(reviewed_object_id: response.id)&lt;br /&gt;
    end&lt;br /&gt;
    metareview_response_maps&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Addition of code comments ===&lt;br /&gt;
&lt;br /&gt;
We added comments to all of the methods in the ReviewResponseMap.rb file and corrected instances where CodeClimate Identified opportunities for code improvement.  One issue flagged by CodeClimate that we did not change was to use the find_by method instead of where().first method.  The where().first method occurs in the import, get_assignment_participant, and create_response_map methods. It is not always appropriate to use the find_by method, as documented in this github post: https://github.com/bbatsov/rubocop/issues/1938 .  In instances where ordering by id is the desired behavior, where().first will order by default, but in Rails 4+ find_by does not honor that default behavior.  For this reason we left the instances of where().first unchanged.&lt;br /&gt;
&lt;br /&gt;
=== Code Improvements ===&lt;br /&gt;
&lt;br /&gt;
This refactoring was to improve readability and follow as many good ''Rubyist'' coding practices as possible without breaking the functionality of existing code. We used CodeClimate of the master branch code as a reference. We took the suggestions we got from CodeClimate and improved our code based on that.&lt;br /&gt;
We also made some of the methods shorter by removing redundant functionality and adding private methods to methods with a lot of functions. We also added private methods in places where we saw repeated patterns to make the code ''DRYer''.&lt;br /&gt;
At the end of our refactoring, we managed to improve the rating on CodeClimate from a '''C''' to a '''B''' . Further improvements meant reducing the size of the entire class which required a much more significant refactoring in multiple files and folders. We focussed on refactoring the existing mode, '''ReviewResponseMap'''.&lt;br /&gt;
&lt;br /&gt;
= Unit Tests =&lt;br /&gt;
&lt;br /&gt;
=== Refactoring of Unit Tests===&lt;br /&gt;
&lt;br /&gt;
The previous unit tests had syntactical and run time errors.  We were not able to get the previous unit tests to run without errors.  Because of this we rewrote the unit tests for the &amp;lt;b&amp;gt;ReviewResponseModel&amp;lt;/b&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
We added a test_helper file to the main test folder that requires a needed configuration file and needed gems.  We also added 8 fixtures that were needed for data to run the unit tests.  The following fixture files were added:&lt;br /&gt;
&lt;br /&gt;
* assignment_questionnaires.yml&lt;br /&gt;
* assignments.yml&lt;br /&gt;
* participants.yml&lt;br /&gt;
* questionnaires.yml&lt;br /&gt;
* response_maps.yml&lt;br /&gt;
* responses.yml&lt;br /&gt;
* teams.yml&lt;br /&gt;
* users.yml&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
There is at least one unit test for every public method within the &amp;lt;b&amp;gt;ReviewResponseModel&amp;lt;/b&amp;gt;.  The test naming convention used is &amp;quot;method_&amp;lt;name of method that is being tested&amp;gt;&amp;quot;.  For example, the unit test for the export method is &amp;quot;method_export&amp;quot;.  If there are multiple test for one method the name of the test will include the test case after the normal naming convention.  For example, one of the unit tests for the import method checks for an invalid assignment.  The name of this method is &amp;quot;method_import_invalid_assignment&amp;quot;.  The following are the unit tests we created:&lt;br /&gt;
&lt;br /&gt;
* method_export&lt;br /&gt;
* method_get_metareview_response_maps&lt;br /&gt;
* method_get_team_response_for_round&lt;br /&gt;
* method_final_versions_from_reviewer&lt;br /&gt;
* method_import&lt;br /&gt;
* method_import_invalid_reviewee&lt;br /&gt;
* method_import_invalid_reviewer&lt;br /&gt;
* method_import_invalid_assignment&lt;br /&gt;
* method_delete&lt;br /&gt;
* method_delete_no _force&lt;br /&gt;
* method_show_feedback&lt;br /&gt;
* method_get_title&lt;br /&gt;
* method_export_fields&lt;br /&gt;
* method_questionnaire&lt;br /&gt;
* method_add_reviewer&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
=== How to Run Unit Tests ===&lt;br /&gt;
To run the unit tests, follow these steps:&lt;br /&gt;
&lt;br /&gt;
# Download the master branch of the repo.&lt;br /&gt;
# Setup the Databases for the test environment (we have used Zhewei's scrubbed expertiza DB )&lt;br /&gt;
#* Run the &amp;quot; rake db:create RAILS_ENV=test &amp;quot; command&lt;br /&gt;
#* Run the &amp;quot; rake db:reset RAILS_ENV=test &amp;quot; command&lt;br /&gt;
#* Scrub the DB using &amp;quot; mysql -u root expertiza_development &amp;lt; expertiza-scrubbed.sql&amp;quot;&lt;br /&gt;
#* Run the &amp;quot; rake db:migrate &amp;quot;&lt;br /&gt;
# Run &amp;quot; rake test test/unit/review_response_map_test.rb &amp;quot; in the &amp;quot;expertiza/&amp;quot; directory.&lt;br /&gt;
#* If you run into a mysql log in error go into config/database.yml and edit the mysql credentials for the test section so that it matches the local environment's mysql configuration&lt;br /&gt;
# Check if tests passed or failed.&lt;br /&gt;
&lt;br /&gt;
= Manual Test Case =&lt;br /&gt;
&lt;br /&gt;
In order to test the changes made to the ReviewResponseMap, bring up Expertiza and log in as an administrator.  Once logged in, proceed with the following steps:&lt;br /&gt;
&lt;br /&gt;
# Go to '''impersonate user''' when logged in as ''instructor6'' and type in ''student559'' (or) just log in as ''student559''. All passwords are ''password'' .&lt;br /&gt;
# Pick any assignment to view.&lt;br /&gt;
# Navigate to '''Other's work'''.&lt;br /&gt;
# Check the different reviews and metareviews. Whether they are being displayed correctly or not.&lt;br /&gt;
# Go to Edit or Give feedback and submit a feedback.&lt;br /&gt;
# Go back and check if the feedback given is displayed correctly or not.&lt;br /&gt;
# Check if author's feedback is correct or not.&lt;br /&gt;
# Go to the '''Temp''' assignment and see if the page is being displayed correctly or not (since there is no assignment submission content or reviews for that).&lt;br /&gt;
&lt;br /&gt;
''NOTE: Since this was a refactoring of the code and methods, the existing functionality was supposed to remain the same and not break for the changes we've made.''&lt;br /&gt;
&lt;br /&gt;
= References =&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;references/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;3. [https://github.com/expertiza/expertiza Expertiza Main Repo] &amp;lt;br&amp;gt;&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;4. [https://github.com/adeeshag/expertiza/blob/develop/app/models/review_response_map.rb Refactored ReviewResponseMap.rb]&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;5. [https://github.com/adeeshag/expertiza/tree/develop/test/fixtures Test Fixtures]&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;6. [https://github.com/adeeshag/expertiza/blob/develop/test/unit/review_response_map_test.rb Unit Tests]&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;6. [http://152.46.16.195:5902/ Expertiza Deployed Site]&amp;lt;br&amp;gt;&lt;/div&gt;</summary>
		<author><name>Cnbrown4</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2015/ossE1558BGJ&amp;diff=98428</id>
		<title>CSC/ECE 517 Fall 2015/ossE1558BGJ</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2015/ossE1558BGJ&amp;diff=98428"/>
		<updated>2015-11-06T19:55:20Z</updated>

		<summary type="html">&lt;p&gt;Cnbrown4: /* Refactoring of import method */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Introduction =&lt;br /&gt;
&lt;br /&gt;
This page provides a description of the modifications and improvements made to the Expertiza project’s source code as part of an Expertiza based Open Source Software project.  Expertiza is a web based application which allows students to submit and peer-review classmates’ work, including written articles and development projects. The specific changes made during the course of this project were to the ReviewResponseMap.rb file, with additional changes made to other related files in support of refactoring ReviewResponseMap.rb.  &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
= Problem Statement =&lt;br /&gt;
&lt;br /&gt;
ReviewResponseMap is the model class used to manage the relationship between contributors, reviewers, and assignments.  The intent of the changes were to refactor the code for better readability and adherence to Ruby coding standards and best practices.  Primarily these changes involved the refactoring of overly complex methods, renaming methods for better readability, and the addition of missing unit tests.&lt;br /&gt;
&lt;br /&gt;
Project Requirements:&lt;br /&gt;
&lt;br /&gt;
# Code Climate&amp;lt;ref name=&amp;quot;Code Climate&amp;quot;&amp;gt;https://codeclimate.com&amp;lt;/ref&amp;gt; shows import method is complex, because of lots of checks. This method can be fixed by adding private methods for raising import error.&lt;br /&gt;
# Get_assessments_round_for method can be renamed to get_team_responses_for_round. Team_id private variable is not needed.&lt;br /&gt;
# metareview_response_maps rename, refactoring can be done. No need to do second iteration.&lt;br /&gt;
# write missing unit tests for existing methods.&lt;br /&gt;
&lt;br /&gt;
= Design Patterns =&lt;br /&gt;
&lt;br /&gt;
As part of our project, we refactored the model to follow the Single Responsibility and Don't Repeat Yourself (DRY) Principles.  Both of the principles focus on reducing code repetition and increasing the cohesion of the individual methods in the class.  The Single Responsibility Principle states that each class and method should have sole responsibility over one single part of the functionality of the system&amp;lt;ref&amp;gt;https://en.wikipedia.org/wiki/Single_responsibility_principle&amp;lt;/ref&amp;gt;.  The DRY principle states that whenever the same types of logic and functionality are being performed in a class the duplicated logic should be extracted into a new method that can be called in place of the repeated lines of code &amp;lt;ref&amp;gt;https://en.wikipedia.org/wiki/Don%27t_repeat_yourself&amp;lt;/ref&amp;gt;.  A prime example of a method that initially violated these principles was the import method, which in addition to performing the core import processes also performed a number of checks that would be more properly extracted into private methods.&lt;br /&gt;
&lt;br /&gt;
=Code Changes =&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Refactoring of import method ===&lt;br /&gt;
&lt;br /&gt;
CodeClimate reports showed the import method to be overly complex, with a number of checks being included within the import method itself.  The resolution for this problem was to refactor the import method, creating private methods to perform the null checks and throw import errors.  Prior to refactoring, all null checks were performed within the import method.   After refactoring, the import method adheres to the single responsibility principle, performing only key import tasks while making calls to private methods for any necessary validation. The size of the import method was reduced by doing this and counts for better readability of the code. Also, this method is a very important one and care was taken so that any existing functionality did not break. &lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
Brfore refactoring:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;big&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 def self.import(row, session, id)&lt;br /&gt;
    if row.length &amp;lt; 2&lt;br /&gt;
      raise ArgumentError, &amp;quot;Not enough items&amp;quot;&lt;br /&gt;
    end&lt;br /&gt;
    assignment = Assignment.find(id)&lt;br /&gt;
    if assignment.nil?&lt;br /&gt;
      raise ImportError, &amp;quot;The assignment with id \&amp;quot;#{id}\&amp;quot; was not found. &amp;lt;a href='/assignment/new'&amp;gt;Create&amp;lt;/a&amp;gt; this assignment?&amp;quot;&lt;br /&gt;
    end&lt;br /&gt;
    index = 1&lt;br /&gt;
    while index &amp;lt; row.length&lt;br /&gt;
      user = User.find_by_name(row[index].to_s.strip)&lt;br /&gt;
      if user.nil?&lt;br /&gt;
        raise ImportError, &amp;quot;The user account for the reviewer \&amp;quot;#{row[index]}\&amp;quot; was not found. &amp;lt;a href='/users/new'&amp;gt;Create&amp;lt;/a&amp;gt; this user?&amp;quot;&lt;br /&gt;
      end&lt;br /&gt;
      reviewer = AssignmentParticipant.where(user_id: user.id, parent_id:  assignment.id).first&lt;br /&gt;
      if reviewer == nil&lt;br /&gt;
        raise ImportError, &amp;quot;The reviewer \&amp;quot;#{row[index]}\&amp;quot; is not a participant in this assignment. &amp;lt;a href='/users/new'&amp;gt;Register&amp;lt;/a&amp;gt; this user as a participant?&amp;quot;&lt;br /&gt;
      end&lt;br /&gt;
      if assignment.team_assignment&lt;br /&gt;
        reviewee = AssignmentTeam.where(name: row[0].to_s.strip, parent_id:  assignment.id).first&lt;br /&gt;
        if reviewee == nil&lt;br /&gt;
          raise ImportError, &amp;quot;The author \&amp;quot;#{row[0].to_s.strip}\&amp;quot; was not found. &amp;lt;a href='/users/new'&amp;gt;Create&amp;lt;/a&amp;gt; this user?&amp;quot;&lt;br /&gt;
        end&lt;br /&gt;
        existing = ReviewResponseMap.where(reviewee_id: reviewee.id, reviewer_id:  reviewer.id).first&lt;br /&gt;
        if existing.nil?&lt;br /&gt;
          ReviewResponseMap.create(:reviewer_id =&amp;gt; reviewer.id, :reviewee_id =&amp;gt; reviewee.id, :reviewed_object_id =&amp;gt; assignment.id)&lt;br /&gt;
        end&lt;br /&gt;
      else&lt;br /&gt;
        puser = User.find_by_name(row[0].to_s.strip)&lt;br /&gt;
        if user == nil&lt;br /&gt;
          raise ImportError, &amp;quot;The user account for the reviewee \&amp;quot;#{row[0]}\&amp;quot; was not found. &amp;lt;a href='/users/new'&amp;gt;Create&amp;lt;/a&amp;gt; this user?&amp;quot;&lt;br /&gt;
        end&lt;br /&gt;
        reviewee = AssignmentParticipant.where(user_id: puser.id, parent_id:  assignment.id).first&lt;br /&gt;
        if reviewee == nil&lt;br /&gt;
          raise ImportError, &amp;quot;The author \&amp;quot;#{row[0].to_s.strip}\&amp;quot; was not found. &amp;lt;a href='/users/new'&amp;gt;Create&amp;lt;/a&amp;gt; this user?&amp;quot;&lt;br /&gt;
        end&lt;br /&gt;
        team_id = TeamsUser.team_id(reviewee.parent_id, reviewee.user_id)&lt;br /&gt;
        existing = ReviewResponseMap.where(reviewee_id: team_id, reviewer_id:  reviewer.id).first&lt;br /&gt;
        if existing.nil?&lt;br /&gt;
          ReviewResponseMap.create(:reviewee_id =&amp;gt; team_id, :reviewer_id =&amp;gt; reviewer.id, :reviewed_object_id =&amp;gt; assignment.id)&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
      index += 1&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
&lt;br /&gt;
After refactoring:&lt;br /&gt;
 &lt;br /&gt;
  &amp;lt;big&amp;gt;&amp;lt;nowiki&amp;gt;#Imports new reponse maps if they do not already exist&lt;br /&gt;
  def self.import(row, _session, id)&lt;br /&gt;
      if row.length &amp;lt; 2&lt;br /&gt;
          raise ArgumentError, 'Not enough items'&lt;br /&gt;
      end&lt;br /&gt;
      assignment = find_assignment(id)&lt;br /&gt;
      index = 1&lt;br /&gt;
      reviewee_name = row[0]&lt;br /&gt;
      while index &amp;lt; row.length&lt;br /&gt;
          reviewee_id = nil&lt;br /&gt;
          reviewer_name = row[index]&lt;br /&gt;
          reviewer = get_assignment_participant(reviewer_name,  assignment.id, &amp;quot;reviewer&amp;quot;)&lt;br /&gt;
          participant_nil?(reviewer, reviewer_name , &amp;quot;reviewer&amp;quot;)&lt;br /&gt;
         &lt;br /&gt;
         #Find reviewee if assignment is a team assignment&lt;br /&gt;
         if assignment.team_assignment&lt;br /&gt;
             reviewee = AssignmentTeam.where(name: reviewee_name .to_s.strip, parent_id: assignment.id).first&lt;br /&gt;
             participant_nil?(reviewee, reviewee_name, &amp;quot;author&amp;quot;)&lt;br /&gt;
             reviewee_id = reviewee.id&lt;br /&gt;
         #Find reviewee if assignment is not a team assignment&lt;br /&gt;
         else&lt;br /&gt;
	     reviewee = get_assignment_participant(reviewee_name, assignment.id, &amp;quot;reviewee&amp;quot;)&lt;br /&gt;
             participant_nil?(reviewee, reviewee_name, &amp;quot;author&amp;quot;)&lt;br /&gt;
             reviewee_id  = TeamsUser.team_id(reviewee.parent_id, reviewee.user_id)&lt;br /&gt;
         end&lt;br /&gt;
         create_response_map(reviewer, reviewee_id,  assignment)&lt;br /&gt;
         index += 1&lt;br /&gt;
      end&lt;br /&gt;
  end&amp;lt;/nowiki&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Private methods added:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;big&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  # Check for if assignment value is null&lt;br /&gt;
  def self.find_assignment(id)&lt;br /&gt;
      begin&lt;br /&gt;
          assignment = Assignment.find(id)&lt;br /&gt;
      rescue ActiveRecord::RecordNotFound&lt;br /&gt;
          raise ImportError, &amp;quot;The assignment with id \&amp;quot;#{id}\&amp;quot; was not found.&amp;lt;a href='/assignment/new'&amp;gt;Create&amp;lt;/a&amp;gt; this assignment?&amp;quot;&lt;br /&gt;
      end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  # Check for if participant is null&lt;br /&gt;
  def self.participant_nil?(participant, user_name, participant_type) &lt;br /&gt;
      error_message = nil&lt;br /&gt;
      if participant_type == &amp;quot;author&amp;quot;&lt;br /&gt;
          error_message = &amp;quot;The author \&amp;quot;#{user_name.to_s.strip}\&amp;quot; was not found.&amp;lt;a href='/users/new'&amp;gt;Create&amp;lt;/a&amp;gt; this user?&amp;quot;&lt;br /&gt;
      else&lt;br /&gt;
          error_message =  &amp;quot;The reviewer \&amp;quot;#{user_name}\&amp;quot; is not a participant in this assignment.&amp;lt;a href='/users/new'&amp;gt;Register&amp;lt;/a&amp;gt; this user as a participant?&amp;quot;&lt;br /&gt;
      end&lt;br /&gt;
      check_nil?(participant, error_message)&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  # Check for if user is null&lt;br /&gt;
  def self.user_nil?(user, user_name, user_type)&lt;br /&gt;
      check_nil?( user, &amp;quot;The user account for the \&amp;quot;#{user_type}\&amp;quot; \&amp;quot;#{user_name}\&amp;quot; was not found.&amp;lt;a href='/users/new'&amp;gt;Create&amp;lt;/a&amp;gt; this user?&amp;quot;)&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
 #Throws import error for nil objects&lt;br /&gt;
  def self.check_nil?(object, error_message)&lt;br /&gt;
      if object.nil?&lt;br /&gt;
          raise ImportError, error_message&lt;br /&gt;
      end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Refactoring of get_assessments_round_for method ===&lt;br /&gt;
&lt;br /&gt;
The get_assessments_round_for method’s name failed to provide a clear idea of the method’s purpose and functionality.  This is why it was renamed to get_team_responses_for_round, the new name of the method provides a clearer idea of its purpose. Additionally, there was a private variable, team_id, introduced in the method that was unnecessary and could be replaced by using the id property of the team parameter directly.  &lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
Before refactoring:&lt;br /&gt;
&amp;lt;big&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  def self.get_assessments_round_for(team,round)&lt;br /&gt;
    team_id =team.id&lt;br /&gt;
    responses = Array.new&lt;br /&gt;
    if team_id&lt;br /&gt;
      maps = ResponseMap.where(:reviewee_id =&amp;gt; team_id, :type =&amp;gt; &amp;quot;ReviewResponseMap&amp;quot;)&lt;br /&gt;
      maps.each{ |map|&lt;br /&gt;
        if !map.response.empty? &amp;amp;&amp;amp; !map.response.reject{|r| r.round!=round}.empty?&lt;br /&gt;
          responses &amp;lt;&amp;lt; map.response.reject{|r| r.round!=round}.last&lt;br /&gt;
        end&lt;br /&gt;
      }&lt;br /&gt;
      responses.sort! {|a,b| a.map.reviewer.fullname &amp;lt;=&amp;gt; b.map.reviewer.fullname }&lt;br /&gt;
    end&lt;br /&gt;
    return responses&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
&lt;br /&gt;
After refactoring: &lt;br /&gt;
&lt;br /&gt;
&amp;lt;big&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  def self.get_team_responses_for_round(team, round)&lt;br /&gt;
    responses = []&lt;br /&gt;
    if team.id&lt;br /&gt;
      maps = ResponseMap.where(reviewee_id: team.id, type: 'ReviewResponseMap')&lt;br /&gt;
      maps.each do |map|&lt;br /&gt;
        unless map.response.empty? &amp;amp;&amp;amp; map.response.reject { |r| r.round != round }.empty?&lt;br /&gt;
          responses &amp;lt;&amp;lt; map.response.reject { |r| r.round != round }.last&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
      responses.sort! { |a, b| a.map.reviewer.fullname &amp;lt;=&amp;gt; b.map.reviewer.fullname }&lt;br /&gt;
    end&lt;br /&gt;
    responses&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
The change in method name also required changes to the following files that referenced it:&lt;br /&gt;
&lt;br /&gt;
/app/models/assignment.rb:436:    &lt;br /&gt;
 &lt;br /&gt;
&amp;lt;big&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  assessments = ReviewResponseMap.get_assessments_round_for(team,i)&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt; &lt;br /&gt;
&lt;br /&gt;
./app/models/assignment_participant.rb:268:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;big&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 scores[questionnaire_symbol][:assessments] = questionnaire.get_assessments_round_for(self,round)&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Refactoring of metareview_response_maps method ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The metareview_response_maps method was unnecessarily complex.  It contained an unneeded private variable and an unnecessary nested loop.  Originally, it added each metareview map individually in the nested loop.  We decided to remove the nested loop and use the concat method for readability and maintainability.  These changes allowed us to remove the private variable &amp;quot;metareview_list&amp;quot; and only maintain the &amp;quot;metareview_response_maps&amp;quot; variable.  We also renamed the metareview_response_maps method to get_metareview_response_maps method to be more descriptive about the intent of the method. &lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
Before refactoring:&lt;br /&gt;
&amp;lt;big&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 def metareview_response_maps&lt;br /&gt;
    responses = Response.where(map_id:self.id)&lt;br /&gt;
    metareview_list=[]&lt;br /&gt;
    responses.each do |response|&lt;br /&gt;
      metareview_response_maps = MetareviewResponseMap.where(reviewed_object_id:response.id)&lt;br /&gt;
      metareview_response_maps.each do |metareview_response_map|&lt;br /&gt;
        metareview_list&amp;lt;&amp;lt;metareview_response_map&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
    metareview_list&lt;br /&gt;
 end&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
After refactoring:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;big&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  def get_metareview_response_maps&lt;br /&gt;
    responses = Response.where(map_id: id)&lt;br /&gt;
    metareview_response_maps = []&lt;br /&gt;
    responses.each do |response|&lt;br /&gt;
      metareview_response_maps.concat MetareviewResponseMap.where(reviewed_object_id: response.id)&lt;br /&gt;
    end&lt;br /&gt;
    metareview_response_maps&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Addition of code comments ===&lt;br /&gt;
&lt;br /&gt;
We added comments to all of the methods in the ReviewResponseMap.rb file and corrected instances where CodeClimate Identified opportunities for code improvement.  One issue flagged by CodeClimate that we did not change was to use the find_by method instead of where().first method.  The where().first method occurs in the import, get_assignment_participant, and create_response_map methods. It is not always appropriate to use the find_by method, as documented in this github post: https://github.com/bbatsov/rubocop/issues/1938 .  In instances where ordering by id is the desired behavior, where().first will order by default, but in Rails 4+ find_by does not honor that default behavior.  For this reason we left the instances of where().first unchanged.&lt;br /&gt;
&lt;br /&gt;
=== Code Improvements ===&lt;br /&gt;
&lt;br /&gt;
This refactoring was to improve readability and follow as many good ''Rubyist'' coding practices as possible without breaking the functionality of existing code. We used CodeClimate of the master branch code as a reference. We took the suggestions we got from CodeClimate and improved our code based on that.&lt;br /&gt;
We also made some of the methods shorter by removing redundant functionality and adding private methods to methods with a lot of functions. We also added private methods in places where we saw repeated patterns to make the code ''DRYer''.&lt;br /&gt;
At the end of our refactoring, we managed to improve the rating on CodeClimate from a '''C''' to a '''B''' . Further improvements meant reducing the size of the entire class which required a much more significant refactoring in multiple files and folders. We focussed on refactoring the existing mode, '''ReviewResponseMap'''.&lt;br /&gt;
&lt;br /&gt;
= Unit Tests =&lt;br /&gt;
&lt;br /&gt;
=== Refactoring of Unit Tests===&lt;br /&gt;
&lt;br /&gt;
The previous unit tests had syntactical and run time errors.  We were not able to get the previous unit tests to run without errors.  Because of this we rewrote the unit tests for the &amp;lt;b&amp;gt;ReviewResponseModel&amp;lt;/b&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
We added a test_helper file to the main test folder that requires a needed configuration file and needed gems.  We also added 8 fixtures that were needed for data to run the unit tests.  The following fixture files were added:&lt;br /&gt;
&lt;br /&gt;
* assignment_questionnaires.yml&lt;br /&gt;
* assignments.yml&lt;br /&gt;
* participants.yml&lt;br /&gt;
* questionnaires.yml&lt;br /&gt;
* response_maps.yml&lt;br /&gt;
* responses.yml&lt;br /&gt;
* teams.yml&lt;br /&gt;
* users.yml&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
There is at least one unit test for every public method within the &amp;lt;b&amp;gt;ReviewResponseModel&amp;lt;/b&amp;gt;.  The test naming convention used is &amp;quot;method_&amp;lt;name of method that is being tested&amp;gt;&amp;quot;.  For example, the unit test for the export method is &amp;quot;method_export&amp;quot;.  If there are multiple test for one method the name of the test will include the test case after the normal naming convention.  For example, one of the unit tests for the import method checks for an invalid assignment.  The name of this method is &amp;quot;method_import_invalid_assignment&amp;quot;.  The following are the unit tests we created:&lt;br /&gt;
&lt;br /&gt;
* method_export&lt;br /&gt;
* method_get_metareview_response_maps&lt;br /&gt;
* method_get_team_response_for_round&lt;br /&gt;
* method_final_versions_from_reviewer&lt;br /&gt;
* method_import&lt;br /&gt;
* method_import_invalid_reviewee&lt;br /&gt;
* method_import_invalid_reviewer&lt;br /&gt;
* method_import_invalid_assignment&lt;br /&gt;
* method_delete&lt;br /&gt;
* method_delete_no _force&lt;br /&gt;
* method_show_feedback&lt;br /&gt;
* method_get_title&lt;br /&gt;
* method_export_fields&lt;br /&gt;
* method_questionnaire&lt;br /&gt;
* method_add_reviewer&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
=== How to Run Unit Tests ===&lt;br /&gt;
To run the unit tests, follow these steps:&lt;br /&gt;
&lt;br /&gt;
# Download the master branch of the repo.&lt;br /&gt;
# Setup the Databases for the test environment (we have used Zhewei's scrubbed expertiza DB )&lt;br /&gt;
#* Run the &amp;quot; rake db:create RAILS_ENV=test &amp;quot; command&lt;br /&gt;
#* Run the &amp;quot; rake db:reset RAILS_ENV=test &amp;quot; command&lt;br /&gt;
#* Scrub the DB using &amp;quot; mysql -u root expertiza_development &amp;lt; expertiza-scrubbed.sql&amp;quot;&lt;br /&gt;
#* Run the &amp;quot; rake db:migrate &amp;quot;&lt;br /&gt;
# Run &amp;quot; rake test test/unit/review_response_map_test.rb &amp;quot; in the &amp;quot;expertiza/&amp;quot; directory.&lt;br /&gt;
#* If you run into a mysql log in error go into config/database.yml and edit the mysql credentials for the test section so that it matches the local environment's mysql configuration&lt;br /&gt;
# Check if tests passed or failed.&lt;br /&gt;
&lt;br /&gt;
= Manual Test Case =&lt;br /&gt;
&lt;br /&gt;
In order to test the changes made to the ReviewResponseMap, bring up Expertiza and log in as an administrator.  Once logged in, proceed with the following steps:&lt;br /&gt;
&lt;br /&gt;
# Go to '''impersonate user''' when logged in as ''instructor6'' and type in ''student559'' (or) just log in as ''student559''. All passwords are ''password'' .&lt;br /&gt;
# Pick any assignment to view.&lt;br /&gt;
# Navigate to '''Other's work'''.&lt;br /&gt;
# Check the different reviews and metareviews. Whether they are being displayed correctly or not.&lt;br /&gt;
# Go to Edit or Give feedback and submit a feedback.&lt;br /&gt;
# Go back and check if the feedback given is displayed correctly or not.&lt;br /&gt;
# Check if author's feedback is correct or not.&lt;br /&gt;
# Go to the '''Temp''' assignment and see if the page is being displayed correctly or not (since there is no assignment submission content or reviews for that).&lt;br /&gt;
&lt;br /&gt;
''NOTE: Since this was a refactoring of the code and methods, the existing functionality was supposed to remain the same and not break for the changes we've made.''&lt;br /&gt;
&lt;br /&gt;
= References =&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;references/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;3. [https://github.com/expertiza/expertiza Expertiza Main Repo] &amp;lt;br&amp;gt;&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;4. [https://github.com/adeeshag/expertiza/blob/develop/app/models/review_response_map.rb Refactored ReviewResponseMap.rb]&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;5. [https://github.com/adeeshag/expertiza/tree/develop/test/fixtures Test Fixtures]&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;6. [https://github.com/adeeshag/expertiza/blob/develop/test/unit/review_response_map_test.rb Unit Tests]&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;6. [http://152.46.16.195:5902/ Expertiza Deployed Site]&amp;lt;br&amp;gt;&lt;/div&gt;</summary>
		<author><name>Cnbrown4</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2015/ossE1558BGJ&amp;diff=98427</id>
		<title>CSC/ECE 517 Fall 2015/ossE1558BGJ</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2015/ossE1558BGJ&amp;diff=98427"/>
		<updated>2015-11-06T19:52:13Z</updated>

		<summary type="html">&lt;p&gt;Cnbrown4: /* Refactoring of get_assessments_round_for method */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Introduction =&lt;br /&gt;
&lt;br /&gt;
This page provides a description of the modifications and improvements made to the Expertiza project’s source code as part of an Expertiza based Open Source Software project.  Expertiza is a web based application which allows students to submit and peer-review classmates’ work, including written articles and development projects. The specific changes made during the course of this project were to the ReviewResponseMap.rb file, with additional changes made to other related files in support of refactoring ReviewResponseMap.rb.  &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
= Problem Statement =&lt;br /&gt;
&lt;br /&gt;
ReviewResponseMap is the model class used to manage the relationship between contributors, reviewers, and assignments.  The intent of the changes were to refactor the code for better readability and adherence to Ruby coding standards and best practices.  Primarily these changes involved the refactoring of overly complex methods, renaming methods for better readability, and the addition of missing unit tests.&lt;br /&gt;
&lt;br /&gt;
Project Requirements:&lt;br /&gt;
&lt;br /&gt;
# Code Climate&amp;lt;ref name=&amp;quot;Code Climate&amp;quot;&amp;gt;https://codeclimate.com&amp;lt;/ref&amp;gt; shows import method is complex, because of lots of checks. This method can be fixed by adding private methods for raising import error.&lt;br /&gt;
# Get_assessments_round_for method can be renamed to get_team_responses_for_round. Team_id private variable is not needed.&lt;br /&gt;
# metareview_response_maps rename, refactoring can be done. No need to do second iteration.&lt;br /&gt;
# write missing unit tests for existing methods.&lt;br /&gt;
&lt;br /&gt;
= Design Patterns =&lt;br /&gt;
&lt;br /&gt;
As part of our project, we refactored the model to follow the Single Responsibility and Don't Repeat Yourself (DRY) Principles.  Both of the principles focus on reducing code repetition and increasing the cohesion of the individual methods in the class.  The Single Responsibility Principle states that each class and method should have sole responsibility over one single part of the functionality of the system&amp;lt;ref&amp;gt;https://en.wikipedia.org/wiki/Single_responsibility_principle&amp;lt;/ref&amp;gt;.  The DRY principle states that whenever the same types of logic and functionality are being performed in a class the duplicated logic should be extracted into a new method that can be called in place of the repeated lines of code &amp;lt;ref&amp;gt;https://en.wikipedia.org/wiki/Don%27t_repeat_yourself&amp;lt;/ref&amp;gt;.  A prime example of a method that initially violated these principles was the import method, which in addition to performing the core import processes also performed a number of checks that would be more properly extracted into private methods.&lt;br /&gt;
&lt;br /&gt;
=Code Changes =&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Refactoring of import method ===&lt;br /&gt;
&lt;br /&gt;
	CodeClimate reports showed the import method to be overly complex, with a number of checks being included within the import method itself.  The resolution for this problem was to refactor the import method, creating private methods to perform the null checks and throw import errors.&lt;br /&gt;
&lt;br /&gt;
Prior to refactoring, all null checks were performed in line:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;big&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 def self.import(row, session, id)&lt;br /&gt;
    if row.length &amp;lt; 2&lt;br /&gt;
      raise ArgumentError, &amp;quot;Not enough items&amp;quot;&lt;br /&gt;
    end&lt;br /&gt;
    assignment = Assignment.find(id)&lt;br /&gt;
    if assignment.nil?&lt;br /&gt;
      raise ImportError, &amp;quot;The assignment with id \&amp;quot;#{id}\&amp;quot; was not found. &amp;lt;a href='/assignment/new'&amp;gt;Create&amp;lt;/a&amp;gt; this assignment?&amp;quot;&lt;br /&gt;
    end&lt;br /&gt;
    index = 1&lt;br /&gt;
    while index &amp;lt; row.length&lt;br /&gt;
      user = User.find_by_name(row[index].to_s.strip)&lt;br /&gt;
      if user.nil?&lt;br /&gt;
        raise ImportError, &amp;quot;The user account for the reviewer \&amp;quot;#{row[index]}\&amp;quot; was not found. &amp;lt;a href='/users/new'&amp;gt;Create&amp;lt;/a&amp;gt; this user?&amp;quot;&lt;br /&gt;
      end&lt;br /&gt;
      reviewer = AssignmentParticipant.where(user_id: user.id, parent_id:  assignment.id).first&lt;br /&gt;
      if reviewer == nil&lt;br /&gt;
        raise ImportError, &amp;quot;The reviewer \&amp;quot;#{row[index]}\&amp;quot; is not a participant in this assignment. &amp;lt;a href='/users/new'&amp;gt;Register&amp;lt;/a&amp;gt; this user as a participant?&amp;quot;&lt;br /&gt;
      end&lt;br /&gt;
      if assignment.team_assignment&lt;br /&gt;
        reviewee = AssignmentTeam.where(name: row[0].to_s.strip, parent_id:  assignment.id).first&lt;br /&gt;
        if reviewee == nil&lt;br /&gt;
          raise ImportError, &amp;quot;The author \&amp;quot;#{row[0].to_s.strip}\&amp;quot; was not found. &amp;lt;a href='/users/new'&amp;gt;Create&amp;lt;/a&amp;gt; this user?&amp;quot;&lt;br /&gt;
        end&lt;br /&gt;
        existing = ReviewResponseMap.where(reviewee_id: reviewee.id, reviewer_id:  reviewer.id).first&lt;br /&gt;
        if existing.nil?&lt;br /&gt;
          ReviewResponseMap.create(:reviewer_id =&amp;gt; reviewer.id, :reviewee_id =&amp;gt; reviewee.id, :reviewed_object_id =&amp;gt; assignment.id)&lt;br /&gt;
        end&lt;br /&gt;
      else&lt;br /&gt;
        puser = User.find_by_name(row[0].to_s.strip)&lt;br /&gt;
        if user == nil&lt;br /&gt;
          raise ImportError, &amp;quot;The user account for the reviewee \&amp;quot;#{row[0]}\&amp;quot; was not found. &amp;lt;a href='/users/new'&amp;gt;Create&amp;lt;/a&amp;gt; this user?&amp;quot;&lt;br /&gt;
        end&lt;br /&gt;
        reviewee = AssignmentParticipant.where(user_id: puser.id, parent_id:  assignment.id).first&lt;br /&gt;
        if reviewee == nil&lt;br /&gt;
          raise ImportError, &amp;quot;The author \&amp;quot;#{row[0].to_s.strip}\&amp;quot; was not found. &amp;lt;a href='/users/new'&amp;gt;Create&amp;lt;/a&amp;gt; this user?&amp;quot;&lt;br /&gt;
        end&lt;br /&gt;
        team_id = TeamsUser.team_id(reviewee.parent_id, reviewee.user_id)&lt;br /&gt;
        existing = ReviewResponseMap.where(reviewee_id: team_id, reviewer_id:  reviewer.id).first&lt;br /&gt;
        if existing.nil?&lt;br /&gt;
          ReviewResponseMap.create(:reviewee_id =&amp;gt; team_id, :reviewer_id =&amp;gt; reviewer.id, :reviewed_object_id =&amp;gt; assignment.id)&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
      index += 1&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
&lt;br /&gt;
After refactoring the import method adheres to the single responsibility principle, performing only key import tasks while making calls to private methods for any necessary validation. The size of the import method was reduced by doing this and counts for better readability of the code. Also, this method is a very important one and care was taken so that it wouldn't break any existing functionality. Changes were reflected in CodeClimate (link expired as it was a trial version).&lt;br /&gt;
 &lt;br /&gt;
  &amp;lt;big&amp;gt;&amp;lt;nowiki&amp;gt;#Imports new reponse maps if they do not already exist&lt;br /&gt;
  def self.import(row, _session, id)&lt;br /&gt;
      if row.length &amp;lt; 2&lt;br /&gt;
          raise ArgumentError, 'Not enough items'&lt;br /&gt;
      end&lt;br /&gt;
      assignment = find_assignment(id)&lt;br /&gt;
      index = 1&lt;br /&gt;
      reviewee_name = row[0]&lt;br /&gt;
      while index &amp;lt; row.length&lt;br /&gt;
          reviewee_id = nil&lt;br /&gt;
          reviewer_name = row[index]&lt;br /&gt;
          reviewer = get_assignment_participant(reviewer_name,  assignment.id, &amp;quot;reviewer&amp;quot;)&lt;br /&gt;
          participant_nil?(reviewer, reviewer_name , &amp;quot;reviewer&amp;quot;)&lt;br /&gt;
         &lt;br /&gt;
         #Find reviewee if assignment is a team assignment&lt;br /&gt;
         if assignment.team_assignment&lt;br /&gt;
             reviewee = AssignmentTeam.where(name: reviewee_name .to_s.strip, parent_id: assignment.id).first&lt;br /&gt;
             participant_nil?(reviewee, reviewee_name, &amp;quot;author&amp;quot;)&lt;br /&gt;
             reviewee_id = reviewee.id&lt;br /&gt;
         #Find reviewee if assignment is not a team assignment&lt;br /&gt;
         else&lt;br /&gt;
	     reviewee = get_assignment_participant(reviewee_name, assignment.id, &amp;quot;reviewee&amp;quot;)&lt;br /&gt;
             participant_nil?(reviewee, reviewee_name, &amp;quot;author&amp;quot;)&lt;br /&gt;
             reviewee_id  = TeamsUser.team_id(reviewee.parent_id, reviewee.user_id)&lt;br /&gt;
         end&lt;br /&gt;
         create_response_map(reviewer, reviewee_id,  assignment)&lt;br /&gt;
         index += 1&lt;br /&gt;
      end&lt;br /&gt;
  end&amp;lt;/nowiki&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Private methods added:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;big&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  # Check for if assignment value is null&lt;br /&gt;
  def self.find_assignment(id)&lt;br /&gt;
      begin&lt;br /&gt;
          assignment = Assignment.find(id)&lt;br /&gt;
      rescue ActiveRecord::RecordNotFound&lt;br /&gt;
          raise ImportError, &amp;quot;The assignment with id \&amp;quot;#{id}\&amp;quot; was not found.&amp;lt;a href='/assignment/new'&amp;gt;Create&amp;lt;/a&amp;gt; this assignment?&amp;quot;&lt;br /&gt;
      end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  # Check for if participant is null&lt;br /&gt;
  def self.participant_nil?(participant, user_name, participant_type) &lt;br /&gt;
      error_message = nil&lt;br /&gt;
      if participant_type == &amp;quot;author&amp;quot;&lt;br /&gt;
          error_message = &amp;quot;The author \&amp;quot;#{user_name.to_s.strip}\&amp;quot; was not found.&amp;lt;a href='/users/new'&amp;gt;Create&amp;lt;/a&amp;gt; this user?&amp;quot;&lt;br /&gt;
      else&lt;br /&gt;
          error_message =  &amp;quot;The reviewer \&amp;quot;#{user_name}\&amp;quot; is not a participant in this assignment.&amp;lt;a href='/users/new'&amp;gt;Register&amp;lt;/a&amp;gt; this user as a participant?&amp;quot;&lt;br /&gt;
      end&lt;br /&gt;
      check_nil?(participant, error_message)&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  # Check for if user is null&lt;br /&gt;
  def self.user_nil?(user, user_name, user_type)&lt;br /&gt;
      check_nil?( user, &amp;quot;The user account for the \&amp;quot;#{user_type}\&amp;quot; \&amp;quot;#{user_name}\&amp;quot; was not found.&amp;lt;a href='/users/new'&amp;gt;Create&amp;lt;/a&amp;gt; this user?&amp;quot;)&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
 #Throws import error for nil objects&lt;br /&gt;
  def self.check_nil?(object, error_message)&lt;br /&gt;
      if object.nil?&lt;br /&gt;
          raise ImportError, error_message&lt;br /&gt;
      end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Refactoring of get_assessments_round_for method ===&lt;br /&gt;
&lt;br /&gt;
The get_assessments_round_for method’s name failed to provide a clear idea of the method’s purpose and functionality.  This is why it was renamed to get_team_responses_for_round, the new name of the method provides a clearer idea of its purpose. Additionally, there was a private variable, team_id, introduced in the method that was unnecessary and could be replaced by using the id property of the team parameter directly.  &lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
Before refactoring:&lt;br /&gt;
&amp;lt;big&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  def self.get_assessments_round_for(team,round)&lt;br /&gt;
    team_id =team.id&lt;br /&gt;
    responses = Array.new&lt;br /&gt;
    if team_id&lt;br /&gt;
      maps = ResponseMap.where(:reviewee_id =&amp;gt; team_id, :type =&amp;gt; &amp;quot;ReviewResponseMap&amp;quot;)&lt;br /&gt;
      maps.each{ |map|&lt;br /&gt;
        if !map.response.empty? &amp;amp;&amp;amp; !map.response.reject{|r| r.round!=round}.empty?&lt;br /&gt;
          responses &amp;lt;&amp;lt; map.response.reject{|r| r.round!=round}.last&lt;br /&gt;
        end&lt;br /&gt;
      }&lt;br /&gt;
      responses.sort! {|a,b| a.map.reviewer.fullname &amp;lt;=&amp;gt; b.map.reviewer.fullname }&lt;br /&gt;
    end&lt;br /&gt;
    return responses&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
&lt;br /&gt;
After refactoring: &lt;br /&gt;
&lt;br /&gt;
&amp;lt;big&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  def self.get_team_responses_for_round(team, round)&lt;br /&gt;
    responses = []&lt;br /&gt;
    if team.id&lt;br /&gt;
      maps = ResponseMap.where(reviewee_id: team.id, type: 'ReviewResponseMap')&lt;br /&gt;
      maps.each do |map|&lt;br /&gt;
        unless map.response.empty? &amp;amp;&amp;amp; map.response.reject { |r| r.round != round }.empty?&lt;br /&gt;
          responses &amp;lt;&amp;lt; map.response.reject { |r| r.round != round }.last&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
      responses.sort! { |a, b| a.map.reviewer.fullname &amp;lt;=&amp;gt; b.map.reviewer.fullname }&lt;br /&gt;
    end&lt;br /&gt;
    responses&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
The change in method name also required changes to the following files that referenced it:&lt;br /&gt;
&lt;br /&gt;
/app/models/assignment.rb:436:    &lt;br /&gt;
 &lt;br /&gt;
&amp;lt;big&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  assessments = ReviewResponseMap.get_assessments_round_for(team,i)&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt; &lt;br /&gt;
&lt;br /&gt;
./app/models/assignment_participant.rb:268:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;big&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 scores[questionnaire_symbol][:assessments] = questionnaire.get_assessments_round_for(self,round)&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Refactoring of metareview_response_maps method ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The metareview_response_maps method was unnecessarily complex.  It contained an unneeded private variable and an unnecessary nested loop.  Originally, it added each metareview map individually in the nested loop.  We decided to remove the nested loop and use the concat method for readability and maintainability.  These changes allowed us to remove the private variable &amp;quot;metareview_list&amp;quot; and only maintain the &amp;quot;metareview_response_maps&amp;quot; variable.  We also renamed the metareview_response_maps method to get_metareview_response_maps method to be more descriptive about the intent of the method. &lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
Before refactoring:&lt;br /&gt;
&amp;lt;big&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 def metareview_response_maps&lt;br /&gt;
    responses = Response.where(map_id:self.id)&lt;br /&gt;
    metareview_list=[]&lt;br /&gt;
    responses.each do |response|&lt;br /&gt;
      metareview_response_maps = MetareviewResponseMap.where(reviewed_object_id:response.id)&lt;br /&gt;
      metareview_response_maps.each do |metareview_response_map|&lt;br /&gt;
        metareview_list&amp;lt;&amp;lt;metareview_response_map&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
    metareview_list&lt;br /&gt;
 end&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
After refactoring:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;big&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  def get_metareview_response_maps&lt;br /&gt;
    responses = Response.where(map_id: id)&lt;br /&gt;
    metareview_response_maps = []&lt;br /&gt;
    responses.each do |response|&lt;br /&gt;
      metareview_response_maps.concat MetareviewResponseMap.where(reviewed_object_id: response.id)&lt;br /&gt;
    end&lt;br /&gt;
    metareview_response_maps&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Addition of code comments ===&lt;br /&gt;
&lt;br /&gt;
We added comments to all of the methods in the ReviewResponseMap.rb file and corrected instances where CodeClimate Identified opportunities for code improvement.  One issue flagged by CodeClimate that we did not change was to use the find_by method instead of where().first method.  The where().first method occurs in the import, get_assignment_participant, and create_response_map methods. It is not always appropriate to use the find_by method, as documented in this github post: https://github.com/bbatsov/rubocop/issues/1938 .  In instances where ordering by id is the desired behavior, where().first will order by default, but in Rails 4+ find_by does not honor that default behavior.  For this reason we left the instances of where().first unchanged.&lt;br /&gt;
&lt;br /&gt;
=== Code Improvements ===&lt;br /&gt;
&lt;br /&gt;
This refactoring was to improve readability and follow as many good ''Rubyist'' coding practices as possible without breaking the functionality of existing code. We used CodeClimate of the master branch code as a reference. We took the suggestions we got from CodeClimate and improved our code based on that.&lt;br /&gt;
We also made some of the methods shorter by removing redundant functionality and adding private methods to methods with a lot of functions. We also added private methods in places where we saw repeated patterns to make the code ''DRYer''.&lt;br /&gt;
At the end of our refactoring, we managed to improve the rating on CodeClimate from a '''C''' to a '''B''' . Further improvements meant reducing the size of the entire class which required a much more significant refactoring in multiple files and folders. We focussed on refactoring the existing mode, '''ReviewResponseMap'''.&lt;br /&gt;
&lt;br /&gt;
= Unit Tests =&lt;br /&gt;
&lt;br /&gt;
=== Refactoring of Unit Tests===&lt;br /&gt;
&lt;br /&gt;
The previous unit tests had syntactical and run time errors.  We were not able to get the previous unit tests to run without errors.  Because of this we rewrote the unit tests for the &amp;lt;b&amp;gt;ReviewResponseModel&amp;lt;/b&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
We added a test_helper file to the main test folder that requires a needed configuration file and needed gems.  We also added 8 fixtures that were needed for data to run the unit tests.  The following fixture files were added:&lt;br /&gt;
&lt;br /&gt;
* assignment_questionnaires.yml&lt;br /&gt;
* assignments.yml&lt;br /&gt;
* participants.yml&lt;br /&gt;
* questionnaires.yml&lt;br /&gt;
* response_maps.yml&lt;br /&gt;
* responses.yml&lt;br /&gt;
* teams.yml&lt;br /&gt;
* users.yml&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
There is at least one unit test for every public method within the &amp;lt;b&amp;gt;ReviewResponseModel&amp;lt;/b&amp;gt;.  The test naming convention used is &amp;quot;method_&amp;lt;name of method that is being tested&amp;gt;&amp;quot;.  For example, the unit test for the export method is &amp;quot;method_export&amp;quot;.  If there are multiple test for one method the name of the test will include the test case after the normal naming convention.  For example, one of the unit tests for the import method checks for an invalid assignment.  The name of this method is &amp;quot;method_import_invalid_assignment&amp;quot;.  The following are the unit tests we created:&lt;br /&gt;
&lt;br /&gt;
* method_export&lt;br /&gt;
* method_get_metareview_response_maps&lt;br /&gt;
* method_get_team_response_for_round&lt;br /&gt;
* method_final_versions_from_reviewer&lt;br /&gt;
* method_import&lt;br /&gt;
* method_import_invalid_reviewee&lt;br /&gt;
* method_import_invalid_reviewer&lt;br /&gt;
* method_import_invalid_assignment&lt;br /&gt;
* method_delete&lt;br /&gt;
* method_delete_no _force&lt;br /&gt;
* method_show_feedback&lt;br /&gt;
* method_get_title&lt;br /&gt;
* method_export_fields&lt;br /&gt;
* method_questionnaire&lt;br /&gt;
* method_add_reviewer&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
=== How to Run Unit Tests ===&lt;br /&gt;
To run the unit tests, follow these steps:&lt;br /&gt;
&lt;br /&gt;
# Download the master branch of the repo.&lt;br /&gt;
# Setup the Databases for the test environment (we have used Zhewei's scrubbed expertiza DB )&lt;br /&gt;
#* Run the &amp;quot; rake db:create RAILS_ENV=test &amp;quot; command&lt;br /&gt;
#* Run the &amp;quot; rake db:reset RAILS_ENV=test &amp;quot; command&lt;br /&gt;
#* Scrub the DB using &amp;quot; mysql -u root expertiza_development &amp;lt; expertiza-scrubbed.sql&amp;quot;&lt;br /&gt;
#* Run the &amp;quot; rake db:migrate &amp;quot;&lt;br /&gt;
# Run &amp;quot; rake test test/unit/review_response_map_test.rb &amp;quot; in the &amp;quot;expertiza/&amp;quot; directory.&lt;br /&gt;
#* If you run into a mysql log in error go into config/database.yml and edit the mysql credentials for the test section so that it matches the local environment's mysql configuration&lt;br /&gt;
# Check if tests passed or failed.&lt;br /&gt;
&lt;br /&gt;
= Manual Test Case =&lt;br /&gt;
&lt;br /&gt;
In order to test the changes made to the ReviewResponseMap, bring up Expertiza and log in as an administrator.  Once logged in, proceed with the following steps:&lt;br /&gt;
&lt;br /&gt;
# Go to '''impersonate user''' when logged in as ''instructor6'' and type in ''student559'' (or) just log in as ''student559''. All passwords are ''password'' .&lt;br /&gt;
# Pick any assignment to view.&lt;br /&gt;
# Navigate to '''Other's work'''.&lt;br /&gt;
# Check the different reviews and metareviews. Whether they are being displayed correctly or not.&lt;br /&gt;
# Go to Edit or Give feedback and submit a feedback.&lt;br /&gt;
# Go back and check if the feedback given is displayed correctly or not.&lt;br /&gt;
# Check if author's feedback is correct or not.&lt;br /&gt;
# Go to the '''Temp''' assignment and see if the page is being displayed correctly or not (since there is no assignment submission content or reviews for that).&lt;br /&gt;
&lt;br /&gt;
''NOTE: Since this was a refactoring of the code and methods, the existing functionality was supposed to remain the same and not break for the changes we've made.''&lt;br /&gt;
&lt;br /&gt;
= References =&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;references/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;3. [https://github.com/expertiza/expertiza Expertiza Main Repo] &amp;lt;br&amp;gt;&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;4. [https://github.com/adeeshag/expertiza/blob/develop/app/models/review_response_map.rb Refactored ReviewResponseMap.rb]&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;5. [https://github.com/adeeshag/expertiza/tree/develop/test/fixtures Test Fixtures]&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;6. [https://github.com/adeeshag/expertiza/blob/develop/test/unit/review_response_map_test.rb Unit Tests]&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;6. [http://152.46.16.195:5902/ Expertiza Deployed Site]&amp;lt;br&amp;gt;&lt;/div&gt;</summary>
		<author><name>Cnbrown4</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2015/ossE1558BGJ&amp;diff=98426</id>
		<title>CSC/ECE 517 Fall 2015/ossE1558BGJ</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2015/ossE1558BGJ&amp;diff=98426"/>
		<updated>2015-11-06T19:50:22Z</updated>

		<summary type="html">&lt;p&gt;Cnbrown4: /* Refactoring of metareview_response_maps method */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Introduction =&lt;br /&gt;
&lt;br /&gt;
This page provides a description of the modifications and improvements made to the Expertiza project’s source code as part of an Expertiza based Open Source Software project.  Expertiza is a web based application which allows students to submit and peer-review classmates’ work, including written articles and development projects. The specific changes made during the course of this project were to the ReviewResponseMap.rb file, with additional changes made to other related files in support of refactoring ReviewResponseMap.rb.  &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
= Problem Statement =&lt;br /&gt;
&lt;br /&gt;
ReviewResponseMap is the model class used to manage the relationship between contributors, reviewers, and assignments.  The intent of the changes were to refactor the code for better readability and adherence to Ruby coding standards and best practices.  Primarily these changes involved the refactoring of overly complex methods, renaming methods for better readability, and the addition of missing unit tests.&lt;br /&gt;
&lt;br /&gt;
Project Requirements:&lt;br /&gt;
&lt;br /&gt;
# Code Climate&amp;lt;ref name=&amp;quot;Code Climate&amp;quot;&amp;gt;https://codeclimate.com&amp;lt;/ref&amp;gt; shows import method is complex, because of lots of checks. This method can be fixed by adding private methods for raising import error.&lt;br /&gt;
# Get_assessments_round_for method can be renamed to get_team_responses_for_round. Team_id private variable is not needed.&lt;br /&gt;
# metareview_response_maps rename, refactoring can be done. No need to do second iteration.&lt;br /&gt;
# write missing unit tests for existing methods.&lt;br /&gt;
&lt;br /&gt;
= Design Patterns =&lt;br /&gt;
&lt;br /&gt;
As part of our project, we refactored the model to follow the Single Responsibility and Don't Repeat Yourself (DRY) Principles.  Both of the principles focus on reducing code repetition and increasing the cohesion of the individual methods in the class.  The Single Responsibility Principle states that each class and method should have sole responsibility over one single part of the functionality of the system&amp;lt;ref&amp;gt;https://en.wikipedia.org/wiki/Single_responsibility_principle&amp;lt;/ref&amp;gt;.  The DRY principle states that whenever the same types of logic and functionality are being performed in a class the duplicated logic should be extracted into a new method that can be called in place of the repeated lines of code &amp;lt;ref&amp;gt;https://en.wikipedia.org/wiki/Don%27t_repeat_yourself&amp;lt;/ref&amp;gt;.  A prime example of a method that initially violated these principles was the import method, which in addition to performing the core import processes also performed a number of checks that would be more properly extracted into private methods.&lt;br /&gt;
&lt;br /&gt;
=Code Changes =&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Refactoring of import method ===&lt;br /&gt;
&lt;br /&gt;
	CodeClimate reports showed the import method to be overly complex, with a number of checks being included within the import method itself.  The resolution for this problem was to refactor the import method, creating private methods to perform the null checks and throw import errors.&lt;br /&gt;
&lt;br /&gt;
Prior to refactoring, all null checks were performed in line:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;big&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 def self.import(row, session, id)&lt;br /&gt;
    if row.length &amp;lt; 2&lt;br /&gt;
      raise ArgumentError, &amp;quot;Not enough items&amp;quot;&lt;br /&gt;
    end&lt;br /&gt;
    assignment = Assignment.find(id)&lt;br /&gt;
    if assignment.nil?&lt;br /&gt;
      raise ImportError, &amp;quot;The assignment with id \&amp;quot;#{id}\&amp;quot; was not found. &amp;lt;a href='/assignment/new'&amp;gt;Create&amp;lt;/a&amp;gt; this assignment?&amp;quot;&lt;br /&gt;
    end&lt;br /&gt;
    index = 1&lt;br /&gt;
    while index &amp;lt; row.length&lt;br /&gt;
      user = User.find_by_name(row[index].to_s.strip)&lt;br /&gt;
      if user.nil?&lt;br /&gt;
        raise ImportError, &amp;quot;The user account for the reviewer \&amp;quot;#{row[index]}\&amp;quot; was not found. &amp;lt;a href='/users/new'&amp;gt;Create&amp;lt;/a&amp;gt; this user?&amp;quot;&lt;br /&gt;
      end&lt;br /&gt;
      reviewer = AssignmentParticipant.where(user_id: user.id, parent_id:  assignment.id).first&lt;br /&gt;
      if reviewer == nil&lt;br /&gt;
        raise ImportError, &amp;quot;The reviewer \&amp;quot;#{row[index]}\&amp;quot; is not a participant in this assignment. &amp;lt;a href='/users/new'&amp;gt;Register&amp;lt;/a&amp;gt; this user as a participant?&amp;quot;&lt;br /&gt;
      end&lt;br /&gt;
      if assignment.team_assignment&lt;br /&gt;
        reviewee = AssignmentTeam.where(name: row[0].to_s.strip, parent_id:  assignment.id).first&lt;br /&gt;
        if reviewee == nil&lt;br /&gt;
          raise ImportError, &amp;quot;The author \&amp;quot;#{row[0].to_s.strip}\&amp;quot; was not found. &amp;lt;a href='/users/new'&amp;gt;Create&amp;lt;/a&amp;gt; this user?&amp;quot;&lt;br /&gt;
        end&lt;br /&gt;
        existing = ReviewResponseMap.where(reviewee_id: reviewee.id, reviewer_id:  reviewer.id).first&lt;br /&gt;
        if existing.nil?&lt;br /&gt;
          ReviewResponseMap.create(:reviewer_id =&amp;gt; reviewer.id, :reviewee_id =&amp;gt; reviewee.id, :reviewed_object_id =&amp;gt; assignment.id)&lt;br /&gt;
        end&lt;br /&gt;
      else&lt;br /&gt;
        puser = User.find_by_name(row[0].to_s.strip)&lt;br /&gt;
        if user == nil&lt;br /&gt;
          raise ImportError, &amp;quot;The user account for the reviewee \&amp;quot;#{row[0]}\&amp;quot; was not found. &amp;lt;a href='/users/new'&amp;gt;Create&amp;lt;/a&amp;gt; this user?&amp;quot;&lt;br /&gt;
        end&lt;br /&gt;
        reviewee = AssignmentParticipant.where(user_id: puser.id, parent_id:  assignment.id).first&lt;br /&gt;
        if reviewee == nil&lt;br /&gt;
          raise ImportError, &amp;quot;The author \&amp;quot;#{row[0].to_s.strip}\&amp;quot; was not found. &amp;lt;a href='/users/new'&amp;gt;Create&amp;lt;/a&amp;gt; this user?&amp;quot;&lt;br /&gt;
        end&lt;br /&gt;
        team_id = TeamsUser.team_id(reviewee.parent_id, reviewee.user_id)&lt;br /&gt;
        existing = ReviewResponseMap.where(reviewee_id: team_id, reviewer_id:  reviewer.id).first&lt;br /&gt;
        if existing.nil?&lt;br /&gt;
          ReviewResponseMap.create(:reviewee_id =&amp;gt; team_id, :reviewer_id =&amp;gt; reviewer.id, :reviewed_object_id =&amp;gt; assignment.id)&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
      index += 1&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
&lt;br /&gt;
After refactoring the import method adheres to the single responsibility principle, performing only key import tasks while making calls to private methods for any necessary validation. The size of the import method was reduced by doing this and counts for better readability of the code. Also, this method is a very important one and care was taken so that it wouldn't break any existing functionality. Changes were reflected in CodeClimate (link expired as it was a trial version).&lt;br /&gt;
 &lt;br /&gt;
  &amp;lt;big&amp;gt;&amp;lt;nowiki&amp;gt;#Imports new reponse maps if they do not already exist&lt;br /&gt;
  def self.import(row, _session, id)&lt;br /&gt;
      if row.length &amp;lt; 2&lt;br /&gt;
          raise ArgumentError, 'Not enough items'&lt;br /&gt;
      end&lt;br /&gt;
      assignment = find_assignment(id)&lt;br /&gt;
      index = 1&lt;br /&gt;
      reviewee_name = row[0]&lt;br /&gt;
      while index &amp;lt; row.length&lt;br /&gt;
          reviewee_id = nil&lt;br /&gt;
          reviewer_name = row[index]&lt;br /&gt;
          reviewer = get_assignment_participant(reviewer_name,  assignment.id, &amp;quot;reviewer&amp;quot;)&lt;br /&gt;
          participant_nil?(reviewer, reviewer_name , &amp;quot;reviewer&amp;quot;)&lt;br /&gt;
         &lt;br /&gt;
         #Find reviewee if assignment is a team assignment&lt;br /&gt;
         if assignment.team_assignment&lt;br /&gt;
             reviewee = AssignmentTeam.where(name: reviewee_name .to_s.strip, parent_id: assignment.id).first&lt;br /&gt;
             participant_nil?(reviewee, reviewee_name, &amp;quot;author&amp;quot;)&lt;br /&gt;
             reviewee_id = reviewee.id&lt;br /&gt;
         #Find reviewee if assignment is not a team assignment&lt;br /&gt;
         else&lt;br /&gt;
	     reviewee = get_assignment_participant(reviewee_name, assignment.id, &amp;quot;reviewee&amp;quot;)&lt;br /&gt;
             participant_nil?(reviewee, reviewee_name, &amp;quot;author&amp;quot;)&lt;br /&gt;
             reviewee_id  = TeamsUser.team_id(reviewee.parent_id, reviewee.user_id)&lt;br /&gt;
         end&lt;br /&gt;
         create_response_map(reviewer, reviewee_id,  assignment)&lt;br /&gt;
         index += 1&lt;br /&gt;
      end&lt;br /&gt;
  end&amp;lt;/nowiki&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Private methods added:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;big&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  # Check for if assignment value is null&lt;br /&gt;
  def self.find_assignment(id)&lt;br /&gt;
      begin&lt;br /&gt;
          assignment = Assignment.find(id)&lt;br /&gt;
      rescue ActiveRecord::RecordNotFound&lt;br /&gt;
          raise ImportError, &amp;quot;The assignment with id \&amp;quot;#{id}\&amp;quot; was not found.&amp;lt;a href='/assignment/new'&amp;gt;Create&amp;lt;/a&amp;gt; this assignment?&amp;quot;&lt;br /&gt;
      end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  # Check for if participant is null&lt;br /&gt;
  def self.participant_nil?(participant, user_name, participant_type) &lt;br /&gt;
      error_message = nil&lt;br /&gt;
      if participant_type == &amp;quot;author&amp;quot;&lt;br /&gt;
          error_message = &amp;quot;The author \&amp;quot;#{user_name.to_s.strip}\&amp;quot; was not found.&amp;lt;a href='/users/new'&amp;gt;Create&amp;lt;/a&amp;gt; this user?&amp;quot;&lt;br /&gt;
      else&lt;br /&gt;
          error_message =  &amp;quot;The reviewer \&amp;quot;#{user_name}\&amp;quot; is not a participant in this assignment.&amp;lt;a href='/users/new'&amp;gt;Register&amp;lt;/a&amp;gt; this user as a participant?&amp;quot;&lt;br /&gt;
      end&lt;br /&gt;
      check_nil?(participant, error_message)&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  # Check for if user is null&lt;br /&gt;
  def self.user_nil?(user, user_name, user_type)&lt;br /&gt;
      check_nil?( user, &amp;quot;The user account for the \&amp;quot;#{user_type}\&amp;quot; \&amp;quot;#{user_name}\&amp;quot; was not found.&amp;lt;a href='/users/new'&amp;gt;Create&amp;lt;/a&amp;gt; this user?&amp;quot;)&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
 #Throws import error for nil objects&lt;br /&gt;
  def self.check_nil?(object, error_message)&lt;br /&gt;
      if object.nil?&lt;br /&gt;
          raise ImportError, error_message&lt;br /&gt;
      end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Refactoring of get_assessments_round_for method ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The get_assessments_round_for method’s name failed to provide a clear idea of the method’s purpose and functionality. Additionally, there was a private variable, team_id, introduced in the method that was unnecessary and could be replaced by using the id property of the team parameter directly.  &lt;br /&gt;
&amp;lt;big&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  def self.get_assessments_round_for(team,round)&lt;br /&gt;
    team_id =team.id&lt;br /&gt;
    responses = Array.new&lt;br /&gt;
    if team_id&lt;br /&gt;
      maps = ResponseMap.where(:reviewee_id =&amp;gt; team_id, :type =&amp;gt; &amp;quot;ReviewResponseMap&amp;quot;)&lt;br /&gt;
      maps.each{ |map|&lt;br /&gt;
        if !map.response.empty? &amp;amp;&amp;amp; !map.response.reject{|r| r.round!=round}.empty?&lt;br /&gt;
          responses &amp;lt;&amp;lt; map.response.reject{|r| r.round!=round}.last&lt;br /&gt;
        end&lt;br /&gt;
      }&lt;br /&gt;
      responses.sort! {|a,b| a.map.reviewer.fullname &amp;lt;=&amp;gt; b.map.reviewer.fullname }&lt;br /&gt;
    end&lt;br /&gt;
    return responses&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Following the refactoring, the name of the method provides a clearer idea of its purpose:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;big&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  def self.get_team_responses_for_round(team, round)&lt;br /&gt;
    responses = []&lt;br /&gt;
    if team.id&lt;br /&gt;
      maps = ResponseMap.where(reviewee_id: team.id, type: 'ReviewResponseMap')&lt;br /&gt;
      maps.each do |map|&lt;br /&gt;
        unless map.response.empty? &amp;amp;&amp;amp; map.response.reject { |r| r.round != round }.empty?&lt;br /&gt;
          responses &amp;lt;&amp;lt; map.response.reject { |r| r.round != round }.last&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
      responses.sort! { |a, b| a.map.reviewer.fullname &amp;lt;=&amp;gt; b.map.reviewer.fullname }&lt;br /&gt;
    end&lt;br /&gt;
    responses&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
The change in method name also required changes to the following files that referenced it:&lt;br /&gt;
&lt;br /&gt;
/app/models/assignment.rb:436:    &lt;br /&gt;
 &lt;br /&gt;
&amp;lt;big&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  assessments = ReviewResponseMap.get_assessments_round_for(team,i)&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt; &lt;br /&gt;
&lt;br /&gt;
./app/models/assignment_participant.rb:268:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;big&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 scores[questionnaire_symbol][:assessments] = questionnaire.get_assessments_round_for(self,round)&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Refactoring of metareview_response_maps method ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The metareview_response_maps method was unnecessarily complex.  It contained an unneeded private variable and an unnecessary nested loop.  Originally, it added each metareview map individually in the nested loop.  We decided to remove the nested loop and use the concat method for readability and maintainability.  These changes allowed us to remove the private variable &amp;quot;metareview_list&amp;quot; and only maintain the &amp;quot;metareview_response_maps&amp;quot; variable.  We also renamed the metareview_response_maps method to get_metareview_response_maps method to be more descriptive about the intent of the method. &lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
Before refactoring:&lt;br /&gt;
&amp;lt;big&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 def metareview_response_maps&lt;br /&gt;
    responses = Response.where(map_id:self.id)&lt;br /&gt;
    metareview_list=[]&lt;br /&gt;
    responses.each do |response|&lt;br /&gt;
      metareview_response_maps = MetareviewResponseMap.where(reviewed_object_id:response.id)&lt;br /&gt;
      metareview_response_maps.each do |metareview_response_map|&lt;br /&gt;
        metareview_list&amp;lt;&amp;lt;metareview_response_map&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
    metareview_list&lt;br /&gt;
 end&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
After refactoring:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;big&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  def get_metareview_response_maps&lt;br /&gt;
    responses = Response.where(map_id: id)&lt;br /&gt;
    metareview_response_maps = []&lt;br /&gt;
    responses.each do |response|&lt;br /&gt;
      metareview_response_maps.concat MetareviewResponseMap.where(reviewed_object_id: response.id)&lt;br /&gt;
    end&lt;br /&gt;
    metareview_response_maps&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Addition of code comments ===&lt;br /&gt;
&lt;br /&gt;
We added comments to all of the methods in the ReviewResponseMap.rb file and corrected instances where CodeClimate Identified opportunities for code improvement.  One issue flagged by CodeClimate that we did not change was to use the find_by method instead of where().first method.  The where().first method occurs in the import, get_assignment_participant, and create_response_map methods. It is not always appropriate to use the find_by method, as documented in this github post: https://github.com/bbatsov/rubocop/issues/1938 .  In instances where ordering by id is the desired behavior, where().first will order by default, but in Rails 4+ find_by does not honor that default behavior.  For this reason we left the instances of where().first unchanged.&lt;br /&gt;
&lt;br /&gt;
=== Code Improvements ===&lt;br /&gt;
&lt;br /&gt;
This refactoring was to improve readability and follow as many good ''Rubyist'' coding practices as possible without breaking the functionality of existing code. We used CodeClimate of the master branch code as a reference. We took the suggestions we got from CodeClimate and improved our code based on that.&lt;br /&gt;
We also made some of the methods shorter by removing redundant functionality and adding private methods to methods with a lot of functions. We also added private methods in places where we saw repeated patterns to make the code ''DRYer''.&lt;br /&gt;
At the end of our refactoring, we managed to improve the rating on CodeClimate from a '''C''' to a '''B''' . Further improvements meant reducing the size of the entire class which required a much more significant refactoring in multiple files and folders. We focussed on refactoring the existing mode, '''ReviewResponseMap'''.&lt;br /&gt;
&lt;br /&gt;
= Unit Tests =&lt;br /&gt;
&lt;br /&gt;
=== Refactoring of Unit Tests===&lt;br /&gt;
&lt;br /&gt;
The previous unit tests had syntactical and run time errors.  We were not able to get the previous unit tests to run without errors.  Because of this we rewrote the unit tests for the &amp;lt;b&amp;gt;ReviewResponseModel&amp;lt;/b&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
We added a test_helper file to the main test folder that requires a needed configuration file and needed gems.  We also added 8 fixtures that were needed for data to run the unit tests.  The following fixture files were added:&lt;br /&gt;
&lt;br /&gt;
* assignment_questionnaires.yml&lt;br /&gt;
* assignments.yml&lt;br /&gt;
* participants.yml&lt;br /&gt;
* questionnaires.yml&lt;br /&gt;
* response_maps.yml&lt;br /&gt;
* responses.yml&lt;br /&gt;
* teams.yml&lt;br /&gt;
* users.yml&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
There is at least one unit test for every public method within the &amp;lt;b&amp;gt;ReviewResponseModel&amp;lt;/b&amp;gt;.  The test naming convention used is &amp;quot;method_&amp;lt;name of method that is being tested&amp;gt;&amp;quot;.  For example, the unit test for the export method is &amp;quot;method_export&amp;quot;.  If there are multiple test for one method the name of the test will include the test case after the normal naming convention.  For example, one of the unit tests for the import method checks for an invalid assignment.  The name of this method is &amp;quot;method_import_invalid_assignment&amp;quot;.  The following are the unit tests we created:&lt;br /&gt;
&lt;br /&gt;
* method_export&lt;br /&gt;
* method_get_metareview_response_maps&lt;br /&gt;
* method_get_team_response_for_round&lt;br /&gt;
* method_final_versions_from_reviewer&lt;br /&gt;
* method_import&lt;br /&gt;
* method_import_invalid_reviewee&lt;br /&gt;
* method_import_invalid_reviewer&lt;br /&gt;
* method_import_invalid_assignment&lt;br /&gt;
* method_delete&lt;br /&gt;
* method_delete_no _force&lt;br /&gt;
* method_show_feedback&lt;br /&gt;
* method_get_title&lt;br /&gt;
* method_export_fields&lt;br /&gt;
* method_questionnaire&lt;br /&gt;
* method_add_reviewer&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
=== How to Run Unit Tests ===&lt;br /&gt;
To run the unit tests, follow these steps:&lt;br /&gt;
&lt;br /&gt;
# Download the master branch of the repo.&lt;br /&gt;
# Setup the Databases for the test environment (we have used Zhewei's scrubbed expertiza DB )&lt;br /&gt;
#* Run the &amp;quot; rake db:create RAILS_ENV=test &amp;quot; command&lt;br /&gt;
#* Run the &amp;quot; rake db:reset RAILS_ENV=test &amp;quot; command&lt;br /&gt;
#* Scrub the DB using &amp;quot; mysql -u root expertiza_development &amp;lt; expertiza-scrubbed.sql&amp;quot;&lt;br /&gt;
#* Run the &amp;quot; rake db:migrate &amp;quot;&lt;br /&gt;
# Run &amp;quot; rake test test/unit/review_response_map_test.rb &amp;quot; in the &amp;quot;expertiza/&amp;quot; directory.&lt;br /&gt;
#* If you run into a mysql log in error go into config/database.yml and edit the mysql credentials for the test section so that it matches the local environment's mysql configuration&lt;br /&gt;
# Check if tests passed or failed.&lt;br /&gt;
&lt;br /&gt;
= Manual Test Case =&lt;br /&gt;
&lt;br /&gt;
In order to test the changes made to the ReviewResponseMap, bring up Expertiza and log in as an administrator.  Once logged in, proceed with the following steps:&lt;br /&gt;
&lt;br /&gt;
# Go to '''impersonate user''' when logged in as ''instructor6'' and type in ''student559'' (or) just log in as ''student559''. All passwords are ''password'' .&lt;br /&gt;
# Pick any assignment to view.&lt;br /&gt;
# Navigate to '''Other's work'''.&lt;br /&gt;
# Check the different reviews and metareviews. Whether they are being displayed correctly or not.&lt;br /&gt;
# Go to Edit or Give feedback and submit a feedback.&lt;br /&gt;
# Go back and check if the feedback given is displayed correctly or not.&lt;br /&gt;
# Check if author's feedback is correct or not.&lt;br /&gt;
# Go to the '''Temp''' assignment and see if the page is being displayed correctly or not (since there is no assignment submission content or reviews for that).&lt;br /&gt;
&lt;br /&gt;
''NOTE: Since this was a refactoring of the code and methods, the existing functionality was supposed to remain the same and not break for the changes we've made.''&lt;br /&gt;
&lt;br /&gt;
= References =&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;references/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;3. [https://github.com/expertiza/expertiza Expertiza Main Repo] &amp;lt;br&amp;gt;&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;4. [https://github.com/adeeshag/expertiza/blob/develop/app/models/review_response_map.rb Refactored ReviewResponseMap.rb]&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;5. [https://github.com/adeeshag/expertiza/tree/develop/test/fixtures Test Fixtures]&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;6. [https://github.com/adeeshag/expertiza/blob/develop/test/unit/review_response_map_test.rb Unit Tests]&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;6. [http://152.46.16.195:5902/ Expertiza Deployed Site]&amp;lt;br&amp;gt;&lt;/div&gt;</summary>
		<author><name>Cnbrown4</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2015/ossE1558BGJ&amp;diff=98425</id>
		<title>CSC/ECE 517 Fall 2015/ossE1558BGJ</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2015/ossE1558BGJ&amp;diff=98425"/>
		<updated>2015-11-06T19:50:14Z</updated>

		<summary type="html">&lt;p&gt;Cnbrown4: /* Refactoring of metareview_response_maps method */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Introduction =&lt;br /&gt;
&lt;br /&gt;
This page provides a description of the modifications and improvements made to the Expertiza project’s source code as part of an Expertiza based Open Source Software project.  Expertiza is a web based application which allows students to submit and peer-review classmates’ work, including written articles and development projects. The specific changes made during the course of this project were to the ReviewResponseMap.rb file, with additional changes made to other related files in support of refactoring ReviewResponseMap.rb.  &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
= Problem Statement =&lt;br /&gt;
&lt;br /&gt;
ReviewResponseMap is the model class used to manage the relationship between contributors, reviewers, and assignments.  The intent of the changes were to refactor the code for better readability and adherence to Ruby coding standards and best practices.  Primarily these changes involved the refactoring of overly complex methods, renaming methods for better readability, and the addition of missing unit tests.&lt;br /&gt;
&lt;br /&gt;
Project Requirements:&lt;br /&gt;
&lt;br /&gt;
# Code Climate&amp;lt;ref name=&amp;quot;Code Climate&amp;quot;&amp;gt;https://codeclimate.com&amp;lt;/ref&amp;gt; shows import method is complex, because of lots of checks. This method can be fixed by adding private methods for raising import error.&lt;br /&gt;
# Get_assessments_round_for method can be renamed to get_team_responses_for_round. Team_id private variable is not needed.&lt;br /&gt;
# metareview_response_maps rename, refactoring can be done. No need to do second iteration.&lt;br /&gt;
# write missing unit tests for existing methods.&lt;br /&gt;
&lt;br /&gt;
= Design Patterns =&lt;br /&gt;
&lt;br /&gt;
As part of our project, we refactored the model to follow the Single Responsibility and Don't Repeat Yourself (DRY) Principles.  Both of the principles focus on reducing code repetition and increasing the cohesion of the individual methods in the class.  The Single Responsibility Principle states that each class and method should have sole responsibility over one single part of the functionality of the system&amp;lt;ref&amp;gt;https://en.wikipedia.org/wiki/Single_responsibility_principle&amp;lt;/ref&amp;gt;.  The DRY principle states that whenever the same types of logic and functionality are being performed in a class the duplicated logic should be extracted into a new method that can be called in place of the repeated lines of code &amp;lt;ref&amp;gt;https://en.wikipedia.org/wiki/Don%27t_repeat_yourself&amp;lt;/ref&amp;gt;.  A prime example of a method that initially violated these principles was the import method, which in addition to performing the core import processes also performed a number of checks that would be more properly extracted into private methods.&lt;br /&gt;
&lt;br /&gt;
=Code Changes =&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Refactoring of import method ===&lt;br /&gt;
&lt;br /&gt;
	CodeClimate reports showed the import method to be overly complex, with a number of checks being included within the import method itself.  The resolution for this problem was to refactor the import method, creating private methods to perform the null checks and throw import errors.&lt;br /&gt;
&lt;br /&gt;
Prior to refactoring, all null checks were performed in line:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;big&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 def self.import(row, session, id)&lt;br /&gt;
    if row.length &amp;lt; 2&lt;br /&gt;
      raise ArgumentError, &amp;quot;Not enough items&amp;quot;&lt;br /&gt;
    end&lt;br /&gt;
    assignment = Assignment.find(id)&lt;br /&gt;
    if assignment.nil?&lt;br /&gt;
      raise ImportError, &amp;quot;The assignment with id \&amp;quot;#{id}\&amp;quot; was not found. &amp;lt;a href='/assignment/new'&amp;gt;Create&amp;lt;/a&amp;gt; this assignment?&amp;quot;&lt;br /&gt;
    end&lt;br /&gt;
    index = 1&lt;br /&gt;
    while index &amp;lt; row.length&lt;br /&gt;
      user = User.find_by_name(row[index].to_s.strip)&lt;br /&gt;
      if user.nil?&lt;br /&gt;
        raise ImportError, &amp;quot;The user account for the reviewer \&amp;quot;#{row[index]}\&amp;quot; was not found. &amp;lt;a href='/users/new'&amp;gt;Create&amp;lt;/a&amp;gt; this user?&amp;quot;&lt;br /&gt;
      end&lt;br /&gt;
      reviewer = AssignmentParticipant.where(user_id: user.id, parent_id:  assignment.id).first&lt;br /&gt;
      if reviewer == nil&lt;br /&gt;
        raise ImportError, &amp;quot;The reviewer \&amp;quot;#{row[index]}\&amp;quot; is not a participant in this assignment. &amp;lt;a href='/users/new'&amp;gt;Register&amp;lt;/a&amp;gt; this user as a participant?&amp;quot;&lt;br /&gt;
      end&lt;br /&gt;
      if assignment.team_assignment&lt;br /&gt;
        reviewee = AssignmentTeam.where(name: row[0].to_s.strip, parent_id:  assignment.id).first&lt;br /&gt;
        if reviewee == nil&lt;br /&gt;
          raise ImportError, &amp;quot;The author \&amp;quot;#{row[0].to_s.strip}\&amp;quot; was not found. &amp;lt;a href='/users/new'&amp;gt;Create&amp;lt;/a&amp;gt; this user?&amp;quot;&lt;br /&gt;
        end&lt;br /&gt;
        existing = ReviewResponseMap.where(reviewee_id: reviewee.id, reviewer_id:  reviewer.id).first&lt;br /&gt;
        if existing.nil?&lt;br /&gt;
          ReviewResponseMap.create(:reviewer_id =&amp;gt; reviewer.id, :reviewee_id =&amp;gt; reviewee.id, :reviewed_object_id =&amp;gt; assignment.id)&lt;br /&gt;
        end&lt;br /&gt;
      else&lt;br /&gt;
        puser = User.find_by_name(row[0].to_s.strip)&lt;br /&gt;
        if user == nil&lt;br /&gt;
          raise ImportError, &amp;quot;The user account for the reviewee \&amp;quot;#{row[0]}\&amp;quot; was not found. &amp;lt;a href='/users/new'&amp;gt;Create&amp;lt;/a&amp;gt; this user?&amp;quot;&lt;br /&gt;
        end&lt;br /&gt;
        reviewee = AssignmentParticipant.where(user_id: puser.id, parent_id:  assignment.id).first&lt;br /&gt;
        if reviewee == nil&lt;br /&gt;
          raise ImportError, &amp;quot;The author \&amp;quot;#{row[0].to_s.strip}\&amp;quot; was not found. &amp;lt;a href='/users/new'&amp;gt;Create&amp;lt;/a&amp;gt; this user?&amp;quot;&lt;br /&gt;
        end&lt;br /&gt;
        team_id = TeamsUser.team_id(reviewee.parent_id, reviewee.user_id)&lt;br /&gt;
        existing = ReviewResponseMap.where(reviewee_id: team_id, reviewer_id:  reviewer.id).first&lt;br /&gt;
        if existing.nil?&lt;br /&gt;
          ReviewResponseMap.create(:reviewee_id =&amp;gt; team_id, :reviewer_id =&amp;gt; reviewer.id, :reviewed_object_id =&amp;gt; assignment.id)&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
      index += 1&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
&lt;br /&gt;
After refactoring the import method adheres to the single responsibility principle, performing only key import tasks while making calls to private methods for any necessary validation. The size of the import method was reduced by doing this and counts for better readability of the code. Also, this method is a very important one and care was taken so that it wouldn't break any existing functionality. Changes were reflected in CodeClimate (link expired as it was a trial version).&lt;br /&gt;
 &lt;br /&gt;
  &amp;lt;big&amp;gt;&amp;lt;nowiki&amp;gt;#Imports new reponse maps if they do not already exist&lt;br /&gt;
  def self.import(row, _session, id)&lt;br /&gt;
      if row.length &amp;lt; 2&lt;br /&gt;
          raise ArgumentError, 'Not enough items'&lt;br /&gt;
      end&lt;br /&gt;
      assignment = find_assignment(id)&lt;br /&gt;
      index = 1&lt;br /&gt;
      reviewee_name = row[0]&lt;br /&gt;
      while index &amp;lt; row.length&lt;br /&gt;
          reviewee_id = nil&lt;br /&gt;
          reviewer_name = row[index]&lt;br /&gt;
          reviewer = get_assignment_participant(reviewer_name,  assignment.id, &amp;quot;reviewer&amp;quot;)&lt;br /&gt;
          participant_nil?(reviewer, reviewer_name , &amp;quot;reviewer&amp;quot;)&lt;br /&gt;
         &lt;br /&gt;
         #Find reviewee if assignment is a team assignment&lt;br /&gt;
         if assignment.team_assignment&lt;br /&gt;
             reviewee = AssignmentTeam.where(name: reviewee_name .to_s.strip, parent_id: assignment.id).first&lt;br /&gt;
             participant_nil?(reviewee, reviewee_name, &amp;quot;author&amp;quot;)&lt;br /&gt;
             reviewee_id = reviewee.id&lt;br /&gt;
         #Find reviewee if assignment is not a team assignment&lt;br /&gt;
         else&lt;br /&gt;
	     reviewee = get_assignment_participant(reviewee_name, assignment.id, &amp;quot;reviewee&amp;quot;)&lt;br /&gt;
             participant_nil?(reviewee, reviewee_name, &amp;quot;author&amp;quot;)&lt;br /&gt;
             reviewee_id  = TeamsUser.team_id(reviewee.parent_id, reviewee.user_id)&lt;br /&gt;
         end&lt;br /&gt;
         create_response_map(reviewer, reviewee_id,  assignment)&lt;br /&gt;
         index += 1&lt;br /&gt;
      end&lt;br /&gt;
  end&amp;lt;/nowiki&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Private methods added:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;big&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  # Check for if assignment value is null&lt;br /&gt;
  def self.find_assignment(id)&lt;br /&gt;
      begin&lt;br /&gt;
          assignment = Assignment.find(id)&lt;br /&gt;
      rescue ActiveRecord::RecordNotFound&lt;br /&gt;
          raise ImportError, &amp;quot;The assignment with id \&amp;quot;#{id}\&amp;quot; was not found.&amp;lt;a href='/assignment/new'&amp;gt;Create&amp;lt;/a&amp;gt; this assignment?&amp;quot;&lt;br /&gt;
      end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  # Check for if participant is null&lt;br /&gt;
  def self.participant_nil?(participant, user_name, participant_type) &lt;br /&gt;
      error_message = nil&lt;br /&gt;
      if participant_type == &amp;quot;author&amp;quot;&lt;br /&gt;
          error_message = &amp;quot;The author \&amp;quot;#{user_name.to_s.strip}\&amp;quot; was not found.&amp;lt;a href='/users/new'&amp;gt;Create&amp;lt;/a&amp;gt; this user?&amp;quot;&lt;br /&gt;
      else&lt;br /&gt;
          error_message =  &amp;quot;The reviewer \&amp;quot;#{user_name}\&amp;quot; is not a participant in this assignment.&amp;lt;a href='/users/new'&amp;gt;Register&amp;lt;/a&amp;gt; this user as a participant?&amp;quot;&lt;br /&gt;
      end&lt;br /&gt;
      check_nil?(participant, error_message)&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  # Check for if user is null&lt;br /&gt;
  def self.user_nil?(user, user_name, user_type)&lt;br /&gt;
      check_nil?( user, &amp;quot;The user account for the \&amp;quot;#{user_type}\&amp;quot; \&amp;quot;#{user_name}\&amp;quot; was not found.&amp;lt;a href='/users/new'&amp;gt;Create&amp;lt;/a&amp;gt; this user?&amp;quot;)&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
 #Throws import error for nil objects&lt;br /&gt;
  def self.check_nil?(object, error_message)&lt;br /&gt;
      if object.nil?&lt;br /&gt;
          raise ImportError, error_message&lt;br /&gt;
      end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Refactoring of get_assessments_round_for method ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The get_assessments_round_for method’s name failed to provide a clear idea of the method’s purpose and functionality. Additionally, there was a private variable, team_id, introduced in the method that was unnecessary and could be replaced by using the id property of the team parameter directly.  &lt;br /&gt;
&amp;lt;big&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  def self.get_assessments_round_for(team,round)&lt;br /&gt;
    team_id =team.id&lt;br /&gt;
    responses = Array.new&lt;br /&gt;
    if team_id&lt;br /&gt;
      maps = ResponseMap.where(:reviewee_id =&amp;gt; team_id, :type =&amp;gt; &amp;quot;ReviewResponseMap&amp;quot;)&lt;br /&gt;
      maps.each{ |map|&lt;br /&gt;
        if !map.response.empty? &amp;amp;&amp;amp; !map.response.reject{|r| r.round!=round}.empty?&lt;br /&gt;
          responses &amp;lt;&amp;lt; map.response.reject{|r| r.round!=round}.last&lt;br /&gt;
        end&lt;br /&gt;
      }&lt;br /&gt;
      responses.sort! {|a,b| a.map.reviewer.fullname &amp;lt;=&amp;gt; b.map.reviewer.fullname }&lt;br /&gt;
    end&lt;br /&gt;
    return responses&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Following the refactoring, the name of the method provides a clearer idea of its purpose:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;big&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  def self.get_team_responses_for_round(team, round)&lt;br /&gt;
    responses = []&lt;br /&gt;
    if team.id&lt;br /&gt;
      maps = ResponseMap.where(reviewee_id: team.id, type: 'ReviewResponseMap')&lt;br /&gt;
      maps.each do |map|&lt;br /&gt;
        unless map.response.empty? &amp;amp;&amp;amp; map.response.reject { |r| r.round != round }.empty?&lt;br /&gt;
          responses &amp;lt;&amp;lt; map.response.reject { |r| r.round != round }.last&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
      responses.sort! { |a, b| a.map.reviewer.fullname &amp;lt;=&amp;gt; b.map.reviewer.fullname }&lt;br /&gt;
    end&lt;br /&gt;
    responses&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
The change in method name also required changes to the following files that referenced it:&lt;br /&gt;
&lt;br /&gt;
/app/models/assignment.rb:436:    &lt;br /&gt;
 &lt;br /&gt;
&amp;lt;big&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  assessments = ReviewResponseMap.get_assessments_round_for(team,i)&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt; &lt;br /&gt;
&lt;br /&gt;
./app/models/assignment_participant.rb:268:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;big&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 scores[questionnaire_symbol][:assessments] = questionnaire.get_assessments_round_for(self,round)&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Refactoring of metareview_response_maps method ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The metareview_response_maps method was unnecessarily complex.  It contained an unneeded private variable and an unnecessary nested loop.  Originally, it added each metareview map individually in the nested loop.  We decided to remove the nested loop and use the concat method for readability and maintainability.  These changes allowed us to remove the private variable &amp;quot;metareview_list&amp;quot; and only maintain the &amp;quot;metareview_response_maps&amp;quot; variable.  We also renamed the metareview_response_maps method to get_metareview_response_maps method to be more descriptive about the intent of the method. &lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Before refactoring:&lt;br /&gt;
&amp;lt;big&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 def metareview_response_maps&lt;br /&gt;
    responses = Response.where(map_id:self.id)&lt;br /&gt;
    metareview_list=[]&lt;br /&gt;
    responses.each do |response|&lt;br /&gt;
      metareview_response_maps = MetareviewResponseMap.where(reviewed_object_id:response.id)&lt;br /&gt;
      metareview_response_maps.each do |metareview_response_map|&lt;br /&gt;
        metareview_list&amp;lt;&amp;lt;metareview_response_map&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
    metareview_list&lt;br /&gt;
 end&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
After refactoring:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;big&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  def get_metareview_response_maps&lt;br /&gt;
    responses = Response.where(map_id: id)&lt;br /&gt;
    metareview_response_maps = []&lt;br /&gt;
    responses.each do |response|&lt;br /&gt;
      metareview_response_maps.concat MetareviewResponseMap.where(reviewed_object_id: response.id)&lt;br /&gt;
    end&lt;br /&gt;
    metareview_response_maps&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Addition of code comments ===&lt;br /&gt;
&lt;br /&gt;
We added comments to all of the methods in the ReviewResponseMap.rb file and corrected instances where CodeClimate Identified opportunities for code improvement.  One issue flagged by CodeClimate that we did not change was to use the find_by method instead of where().first method.  The where().first method occurs in the import, get_assignment_participant, and create_response_map methods. It is not always appropriate to use the find_by method, as documented in this github post: https://github.com/bbatsov/rubocop/issues/1938 .  In instances where ordering by id is the desired behavior, where().first will order by default, but in Rails 4+ find_by does not honor that default behavior.  For this reason we left the instances of where().first unchanged.&lt;br /&gt;
&lt;br /&gt;
=== Code Improvements ===&lt;br /&gt;
&lt;br /&gt;
This refactoring was to improve readability and follow as many good ''Rubyist'' coding practices as possible without breaking the functionality of existing code. We used CodeClimate of the master branch code as a reference. We took the suggestions we got from CodeClimate and improved our code based on that.&lt;br /&gt;
We also made some of the methods shorter by removing redundant functionality and adding private methods to methods with a lot of functions. We also added private methods in places where we saw repeated patterns to make the code ''DRYer''.&lt;br /&gt;
At the end of our refactoring, we managed to improve the rating on CodeClimate from a '''C''' to a '''B''' . Further improvements meant reducing the size of the entire class which required a much more significant refactoring in multiple files and folders. We focussed on refactoring the existing mode, '''ReviewResponseMap'''.&lt;br /&gt;
&lt;br /&gt;
= Unit Tests =&lt;br /&gt;
&lt;br /&gt;
=== Refactoring of Unit Tests===&lt;br /&gt;
&lt;br /&gt;
The previous unit tests had syntactical and run time errors.  We were not able to get the previous unit tests to run without errors.  Because of this we rewrote the unit tests for the &amp;lt;b&amp;gt;ReviewResponseModel&amp;lt;/b&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
We added a test_helper file to the main test folder that requires a needed configuration file and needed gems.  We also added 8 fixtures that were needed for data to run the unit tests.  The following fixture files were added:&lt;br /&gt;
&lt;br /&gt;
* assignment_questionnaires.yml&lt;br /&gt;
* assignments.yml&lt;br /&gt;
* participants.yml&lt;br /&gt;
* questionnaires.yml&lt;br /&gt;
* response_maps.yml&lt;br /&gt;
* responses.yml&lt;br /&gt;
* teams.yml&lt;br /&gt;
* users.yml&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
There is at least one unit test for every public method within the &amp;lt;b&amp;gt;ReviewResponseModel&amp;lt;/b&amp;gt;.  The test naming convention used is &amp;quot;method_&amp;lt;name of method that is being tested&amp;gt;&amp;quot;.  For example, the unit test for the export method is &amp;quot;method_export&amp;quot;.  If there are multiple test for one method the name of the test will include the test case after the normal naming convention.  For example, one of the unit tests for the import method checks for an invalid assignment.  The name of this method is &amp;quot;method_import_invalid_assignment&amp;quot;.  The following are the unit tests we created:&lt;br /&gt;
&lt;br /&gt;
* method_export&lt;br /&gt;
* method_get_metareview_response_maps&lt;br /&gt;
* method_get_team_response_for_round&lt;br /&gt;
* method_final_versions_from_reviewer&lt;br /&gt;
* method_import&lt;br /&gt;
* method_import_invalid_reviewee&lt;br /&gt;
* method_import_invalid_reviewer&lt;br /&gt;
* method_import_invalid_assignment&lt;br /&gt;
* method_delete&lt;br /&gt;
* method_delete_no _force&lt;br /&gt;
* method_show_feedback&lt;br /&gt;
* method_get_title&lt;br /&gt;
* method_export_fields&lt;br /&gt;
* method_questionnaire&lt;br /&gt;
* method_add_reviewer&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
=== How to Run Unit Tests ===&lt;br /&gt;
To run the unit tests, follow these steps:&lt;br /&gt;
&lt;br /&gt;
# Download the master branch of the repo.&lt;br /&gt;
# Setup the Databases for the test environment (we have used Zhewei's scrubbed expertiza DB )&lt;br /&gt;
#* Run the &amp;quot; rake db:create RAILS_ENV=test &amp;quot; command&lt;br /&gt;
#* Run the &amp;quot; rake db:reset RAILS_ENV=test &amp;quot; command&lt;br /&gt;
#* Scrub the DB using &amp;quot; mysql -u root expertiza_development &amp;lt; expertiza-scrubbed.sql&amp;quot;&lt;br /&gt;
#* Run the &amp;quot; rake db:migrate &amp;quot;&lt;br /&gt;
# Run &amp;quot; rake test test/unit/review_response_map_test.rb &amp;quot; in the &amp;quot;expertiza/&amp;quot; directory.&lt;br /&gt;
#* If you run into a mysql log in error go into config/database.yml and edit the mysql credentials for the test section so that it matches the local environment's mysql configuration&lt;br /&gt;
# Check if tests passed or failed.&lt;br /&gt;
&lt;br /&gt;
= Manual Test Case =&lt;br /&gt;
&lt;br /&gt;
In order to test the changes made to the ReviewResponseMap, bring up Expertiza and log in as an administrator.  Once logged in, proceed with the following steps:&lt;br /&gt;
&lt;br /&gt;
# Go to '''impersonate user''' when logged in as ''instructor6'' and type in ''student559'' (or) just log in as ''student559''. All passwords are ''password'' .&lt;br /&gt;
# Pick any assignment to view.&lt;br /&gt;
# Navigate to '''Other's work'''.&lt;br /&gt;
# Check the different reviews and metareviews. Whether they are being displayed correctly or not.&lt;br /&gt;
# Go to Edit or Give feedback and submit a feedback.&lt;br /&gt;
# Go back and check if the feedback given is displayed correctly or not.&lt;br /&gt;
# Check if author's feedback is correct or not.&lt;br /&gt;
# Go to the '''Temp''' assignment and see if the page is being displayed correctly or not (since there is no assignment submission content or reviews for that).&lt;br /&gt;
&lt;br /&gt;
''NOTE: Since this was a refactoring of the code and methods, the existing functionality was supposed to remain the same and not break for the changes we've made.''&lt;br /&gt;
&lt;br /&gt;
= References =&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;references/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;3. [https://github.com/expertiza/expertiza Expertiza Main Repo] &amp;lt;br&amp;gt;&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;4. [https://github.com/adeeshag/expertiza/blob/develop/app/models/review_response_map.rb Refactored ReviewResponseMap.rb]&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;5. [https://github.com/adeeshag/expertiza/tree/develop/test/fixtures Test Fixtures]&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;6. [https://github.com/adeeshag/expertiza/blob/develop/test/unit/review_response_map_test.rb Unit Tests]&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;6. [http://152.46.16.195:5902/ Expertiza Deployed Site]&amp;lt;br&amp;gt;&lt;/div&gt;</summary>
		<author><name>Cnbrown4</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2015/ossE1558BGJ&amp;diff=98424</id>
		<title>CSC/ECE 517 Fall 2015/ossE1558BGJ</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2015/ossE1558BGJ&amp;diff=98424"/>
		<updated>2015-11-06T19:46:40Z</updated>

		<summary type="html">&lt;p&gt;Cnbrown4: /* Refactoring of metareview_response_maps method */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Introduction =&lt;br /&gt;
&lt;br /&gt;
This page provides a description of the modifications and improvements made to the Expertiza project’s source code as part of an Expertiza based Open Source Software project.  Expertiza is a web based application which allows students to submit and peer-review classmates’ work, including written articles and development projects. The specific changes made during the course of this project were to the ReviewResponseMap.rb file, with additional changes made to other related files in support of refactoring ReviewResponseMap.rb.  &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
= Problem Statement =&lt;br /&gt;
&lt;br /&gt;
ReviewResponseMap is the model class used to manage the relationship between contributors, reviewers, and assignments.  The intent of the changes were to refactor the code for better readability and adherence to Ruby coding standards and best practices.  Primarily these changes involved the refactoring of overly complex methods, renaming methods for better readability, and the addition of missing unit tests.&lt;br /&gt;
&lt;br /&gt;
Project Requirements:&lt;br /&gt;
&lt;br /&gt;
# Code Climate&amp;lt;ref name=&amp;quot;Code Climate&amp;quot;&amp;gt;https://codeclimate.com&amp;lt;/ref&amp;gt; shows import method is complex, because of lots of checks. This method can be fixed by adding private methods for raising import error.&lt;br /&gt;
# Get_assessments_round_for method can be renamed to get_team_responses_for_round. Team_id private variable is not needed.&lt;br /&gt;
# metareview_response_maps rename, refactoring can be done. No need to do second iteration.&lt;br /&gt;
# write missing unit tests for existing methods.&lt;br /&gt;
&lt;br /&gt;
= Design Patterns =&lt;br /&gt;
&lt;br /&gt;
As part of our project, we refactored the model to follow the Single Responsibility and Don't Repeat Yourself (DRY) Principles.  Both of the principles focus on reducing code repetition and increasing the cohesion of the individual methods in the class.  The Single Responsibility Principle states that each class and method should have sole responsibility over one single part of the functionality of the system&amp;lt;ref&amp;gt;https://en.wikipedia.org/wiki/Single_responsibility_principle&amp;lt;/ref&amp;gt;.  The DRY principle states that whenever the same types of logic and functionality are being performed in a class the duplicated logic should be extracted into a new method that can be called in place of the repeated lines of code &amp;lt;ref&amp;gt;https://en.wikipedia.org/wiki/Don%27t_repeat_yourself&amp;lt;/ref&amp;gt;.  A prime example of a method that initially violated these principles was the import method, which in addition to performing the core import processes also performed a number of checks that would be more properly extracted into private methods.&lt;br /&gt;
&lt;br /&gt;
=Code Changes =&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Refactoring of import method ===&lt;br /&gt;
&lt;br /&gt;
	CodeClimate reports showed the import method to be overly complex, with a number of checks being included within the import method itself.  The resolution for this problem was to refactor the import method, creating private methods to perform the null checks and throw import errors.&lt;br /&gt;
&lt;br /&gt;
Prior to refactoring, all null checks were performed in line:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;big&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 def self.import(row, session, id)&lt;br /&gt;
    if row.length &amp;lt; 2&lt;br /&gt;
      raise ArgumentError, &amp;quot;Not enough items&amp;quot;&lt;br /&gt;
    end&lt;br /&gt;
    assignment = Assignment.find(id)&lt;br /&gt;
    if assignment.nil?&lt;br /&gt;
      raise ImportError, &amp;quot;The assignment with id \&amp;quot;#{id}\&amp;quot; was not found. &amp;lt;a href='/assignment/new'&amp;gt;Create&amp;lt;/a&amp;gt; this assignment?&amp;quot;&lt;br /&gt;
    end&lt;br /&gt;
    index = 1&lt;br /&gt;
    while index &amp;lt; row.length&lt;br /&gt;
      user = User.find_by_name(row[index].to_s.strip)&lt;br /&gt;
      if user.nil?&lt;br /&gt;
        raise ImportError, &amp;quot;The user account for the reviewer \&amp;quot;#{row[index]}\&amp;quot; was not found. &amp;lt;a href='/users/new'&amp;gt;Create&amp;lt;/a&amp;gt; this user?&amp;quot;&lt;br /&gt;
      end&lt;br /&gt;
      reviewer = AssignmentParticipant.where(user_id: user.id, parent_id:  assignment.id).first&lt;br /&gt;
      if reviewer == nil&lt;br /&gt;
        raise ImportError, &amp;quot;The reviewer \&amp;quot;#{row[index]}\&amp;quot; is not a participant in this assignment. &amp;lt;a href='/users/new'&amp;gt;Register&amp;lt;/a&amp;gt; this user as a participant?&amp;quot;&lt;br /&gt;
      end&lt;br /&gt;
      if assignment.team_assignment&lt;br /&gt;
        reviewee = AssignmentTeam.where(name: row[0].to_s.strip, parent_id:  assignment.id).first&lt;br /&gt;
        if reviewee == nil&lt;br /&gt;
          raise ImportError, &amp;quot;The author \&amp;quot;#{row[0].to_s.strip}\&amp;quot; was not found. &amp;lt;a href='/users/new'&amp;gt;Create&amp;lt;/a&amp;gt; this user?&amp;quot;&lt;br /&gt;
        end&lt;br /&gt;
        existing = ReviewResponseMap.where(reviewee_id: reviewee.id, reviewer_id:  reviewer.id).first&lt;br /&gt;
        if existing.nil?&lt;br /&gt;
          ReviewResponseMap.create(:reviewer_id =&amp;gt; reviewer.id, :reviewee_id =&amp;gt; reviewee.id, :reviewed_object_id =&amp;gt; assignment.id)&lt;br /&gt;
        end&lt;br /&gt;
      else&lt;br /&gt;
        puser = User.find_by_name(row[0].to_s.strip)&lt;br /&gt;
        if user == nil&lt;br /&gt;
          raise ImportError, &amp;quot;The user account for the reviewee \&amp;quot;#{row[0]}\&amp;quot; was not found. &amp;lt;a href='/users/new'&amp;gt;Create&amp;lt;/a&amp;gt; this user?&amp;quot;&lt;br /&gt;
        end&lt;br /&gt;
        reviewee = AssignmentParticipant.where(user_id: puser.id, parent_id:  assignment.id).first&lt;br /&gt;
        if reviewee == nil&lt;br /&gt;
          raise ImportError, &amp;quot;The author \&amp;quot;#{row[0].to_s.strip}\&amp;quot; was not found. &amp;lt;a href='/users/new'&amp;gt;Create&amp;lt;/a&amp;gt; this user?&amp;quot;&lt;br /&gt;
        end&lt;br /&gt;
        team_id = TeamsUser.team_id(reviewee.parent_id, reviewee.user_id)&lt;br /&gt;
        existing = ReviewResponseMap.where(reviewee_id: team_id, reviewer_id:  reviewer.id).first&lt;br /&gt;
        if existing.nil?&lt;br /&gt;
          ReviewResponseMap.create(:reviewee_id =&amp;gt; team_id, :reviewer_id =&amp;gt; reviewer.id, :reviewed_object_id =&amp;gt; assignment.id)&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
      index += 1&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
&lt;br /&gt;
After refactoring the import method adheres to the single responsibility principle, performing only key import tasks while making calls to private methods for any necessary validation. The size of the import method was reduced by doing this and counts for better readability of the code. Also, this method is a very important one and care was taken so that it wouldn't break any existing functionality. Changes were reflected in CodeClimate (link expired as it was a trial version).&lt;br /&gt;
 &lt;br /&gt;
  &amp;lt;big&amp;gt;&amp;lt;nowiki&amp;gt;#Imports new reponse maps if they do not already exist&lt;br /&gt;
  def self.import(row, _session, id)&lt;br /&gt;
      if row.length &amp;lt; 2&lt;br /&gt;
          raise ArgumentError, 'Not enough items'&lt;br /&gt;
      end&lt;br /&gt;
      assignment = find_assignment(id)&lt;br /&gt;
      index = 1&lt;br /&gt;
      reviewee_name = row[0]&lt;br /&gt;
      while index &amp;lt; row.length&lt;br /&gt;
          reviewee_id = nil&lt;br /&gt;
          reviewer_name = row[index]&lt;br /&gt;
          reviewer = get_assignment_participant(reviewer_name,  assignment.id, &amp;quot;reviewer&amp;quot;)&lt;br /&gt;
          participant_nil?(reviewer, reviewer_name , &amp;quot;reviewer&amp;quot;)&lt;br /&gt;
         &lt;br /&gt;
         #Find reviewee if assignment is a team assignment&lt;br /&gt;
         if assignment.team_assignment&lt;br /&gt;
             reviewee = AssignmentTeam.where(name: reviewee_name .to_s.strip, parent_id: assignment.id).first&lt;br /&gt;
             participant_nil?(reviewee, reviewee_name, &amp;quot;author&amp;quot;)&lt;br /&gt;
             reviewee_id = reviewee.id&lt;br /&gt;
         #Find reviewee if assignment is not a team assignment&lt;br /&gt;
         else&lt;br /&gt;
	     reviewee = get_assignment_participant(reviewee_name, assignment.id, &amp;quot;reviewee&amp;quot;)&lt;br /&gt;
             participant_nil?(reviewee, reviewee_name, &amp;quot;author&amp;quot;)&lt;br /&gt;
             reviewee_id  = TeamsUser.team_id(reviewee.parent_id, reviewee.user_id)&lt;br /&gt;
         end&lt;br /&gt;
         create_response_map(reviewer, reviewee_id,  assignment)&lt;br /&gt;
         index += 1&lt;br /&gt;
      end&lt;br /&gt;
  end&amp;lt;/nowiki&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Private methods added:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;big&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  # Check for if assignment value is null&lt;br /&gt;
  def self.find_assignment(id)&lt;br /&gt;
      begin&lt;br /&gt;
          assignment = Assignment.find(id)&lt;br /&gt;
      rescue ActiveRecord::RecordNotFound&lt;br /&gt;
          raise ImportError, &amp;quot;The assignment with id \&amp;quot;#{id}\&amp;quot; was not found.&amp;lt;a href='/assignment/new'&amp;gt;Create&amp;lt;/a&amp;gt; this assignment?&amp;quot;&lt;br /&gt;
      end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  # Check for if participant is null&lt;br /&gt;
  def self.participant_nil?(participant, user_name, participant_type) &lt;br /&gt;
      error_message = nil&lt;br /&gt;
      if participant_type == &amp;quot;author&amp;quot;&lt;br /&gt;
          error_message = &amp;quot;The author \&amp;quot;#{user_name.to_s.strip}\&amp;quot; was not found.&amp;lt;a href='/users/new'&amp;gt;Create&amp;lt;/a&amp;gt; this user?&amp;quot;&lt;br /&gt;
      else&lt;br /&gt;
          error_message =  &amp;quot;The reviewer \&amp;quot;#{user_name}\&amp;quot; is not a participant in this assignment.&amp;lt;a href='/users/new'&amp;gt;Register&amp;lt;/a&amp;gt; this user as a participant?&amp;quot;&lt;br /&gt;
      end&lt;br /&gt;
      check_nil?(participant, error_message)&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  # Check for if user is null&lt;br /&gt;
  def self.user_nil?(user, user_name, user_type)&lt;br /&gt;
      check_nil?( user, &amp;quot;The user account for the \&amp;quot;#{user_type}\&amp;quot; \&amp;quot;#{user_name}\&amp;quot; was not found.&amp;lt;a href='/users/new'&amp;gt;Create&amp;lt;/a&amp;gt; this user?&amp;quot;)&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
 #Throws import error for nil objects&lt;br /&gt;
  def self.check_nil?(object, error_message)&lt;br /&gt;
      if object.nil?&lt;br /&gt;
          raise ImportError, error_message&lt;br /&gt;
      end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Refactoring of get_assessments_round_for method ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The get_assessments_round_for method’s name failed to provide a clear idea of the method’s purpose and functionality. Additionally, there was a private variable, team_id, introduced in the method that was unnecessary and could be replaced by using the id property of the team parameter directly.  &lt;br /&gt;
&amp;lt;big&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  def self.get_assessments_round_for(team,round)&lt;br /&gt;
    team_id =team.id&lt;br /&gt;
    responses = Array.new&lt;br /&gt;
    if team_id&lt;br /&gt;
      maps = ResponseMap.where(:reviewee_id =&amp;gt; team_id, :type =&amp;gt; &amp;quot;ReviewResponseMap&amp;quot;)&lt;br /&gt;
      maps.each{ |map|&lt;br /&gt;
        if !map.response.empty? &amp;amp;&amp;amp; !map.response.reject{|r| r.round!=round}.empty?&lt;br /&gt;
          responses &amp;lt;&amp;lt; map.response.reject{|r| r.round!=round}.last&lt;br /&gt;
        end&lt;br /&gt;
      }&lt;br /&gt;
      responses.sort! {|a,b| a.map.reviewer.fullname &amp;lt;=&amp;gt; b.map.reviewer.fullname }&lt;br /&gt;
    end&lt;br /&gt;
    return responses&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Following the refactoring, the name of the method provides a clearer idea of its purpose:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;big&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  def self.get_team_responses_for_round(team, round)&lt;br /&gt;
    responses = []&lt;br /&gt;
    if team.id&lt;br /&gt;
      maps = ResponseMap.where(reviewee_id: team.id, type: 'ReviewResponseMap')&lt;br /&gt;
      maps.each do |map|&lt;br /&gt;
        unless map.response.empty? &amp;amp;&amp;amp; map.response.reject { |r| r.round != round }.empty?&lt;br /&gt;
          responses &amp;lt;&amp;lt; map.response.reject { |r| r.round != round }.last&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
      responses.sort! { |a, b| a.map.reviewer.fullname &amp;lt;=&amp;gt; b.map.reviewer.fullname }&lt;br /&gt;
    end&lt;br /&gt;
    responses&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
The change in method name also required changes to the following files that referenced it:&lt;br /&gt;
&lt;br /&gt;
/app/models/assignment.rb:436:    &lt;br /&gt;
 &lt;br /&gt;
&amp;lt;big&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  assessments = ReviewResponseMap.get_assessments_round_for(team,i)&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt; &lt;br /&gt;
&lt;br /&gt;
./app/models/assignment_participant.rb:268:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;big&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 scores[questionnaire_symbol][:assessments] = questionnaire.get_assessments_round_for(self,round)&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Refactoring of metareview_response_maps method ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The metareview_response_maps method was unnecessarily complex.  It contained an unneeded private variable and an unnecessary nested loop.  Originally, it added each metareview map individually in the nested loop.  We decided to remove the nested loop and use the concat method for readability and maintainability.  These changes allowed us to remove the private variable &amp;quot;metareview_list&amp;quot; and only maintain the &amp;quot;metareview_response_maps&amp;quot; variable.  We also renamed the metareview_response_maps method to get_metareview_response_maps method to be more descriptive about the intent of the method. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;big&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 def metareview_response_maps&lt;br /&gt;
    responses = Response.where(map_id:self.id)&lt;br /&gt;
    metareview_list=[]&lt;br /&gt;
    responses.each do |response|&lt;br /&gt;
      metareview_response_maps = MetareviewResponseMap.where(reviewed_object_id:response.id)&lt;br /&gt;
      metareview_response_maps.each do |metareview_response_map|&lt;br /&gt;
        metareview_list&amp;lt;&amp;lt;metareview_response_map&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
    metareview_list&lt;br /&gt;
 end&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
After refactoring:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;big&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  def get_metareview_response_maps&lt;br /&gt;
    responses = Response.where(map_id: id)&lt;br /&gt;
    metareview_response_maps = []&lt;br /&gt;
    responses.each do |response|&lt;br /&gt;
      metareview_response_maps.concat MetareviewResponseMap.where(reviewed_object_id: response.id)&lt;br /&gt;
    end&lt;br /&gt;
    metareview_response_maps&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Addition of code comments ===&lt;br /&gt;
&lt;br /&gt;
We added comments to all of the methods in the ReviewResponseMap.rb file and corrected instances where CodeClimate Identified opportunities for code improvement.  One issue flagged by CodeClimate that we did not change was to use the find_by method instead of where().first method.  The where().first method occurs in the import, get_assignment_participant, and create_response_map methods. It is not always appropriate to use the find_by method, as documented in this github post: https://github.com/bbatsov/rubocop/issues/1938 .  In instances where ordering by id is the desired behavior, where().first will order by default, but in Rails 4+ find_by does not honor that default behavior.  For this reason we left the instances of where().first unchanged.&lt;br /&gt;
&lt;br /&gt;
=== Code Improvements ===&lt;br /&gt;
&lt;br /&gt;
This refactoring was to improve readability and follow as many good ''Rubyist'' coding practices as possible without breaking the functionality of existing code. We used CodeClimate of the master branch code as a reference. We took the suggestions we got from CodeClimate and improved our code based on that.&lt;br /&gt;
We also made some of the methods shorter by removing redundant functionality and adding private methods to methods with a lot of functions. We also added private methods in places where we saw repeated patterns to make the code ''DRYer''.&lt;br /&gt;
At the end of our refactoring, we managed to improve the rating on CodeClimate from a '''C''' to a '''B''' . Further improvements meant reducing the size of the entire class which required a much more significant refactoring in multiple files and folders. We focussed on refactoring the existing mode, '''ReviewResponseMap'''.&lt;br /&gt;
&lt;br /&gt;
= Unit Tests =&lt;br /&gt;
&lt;br /&gt;
=== Refactoring of Unit Tests===&lt;br /&gt;
&lt;br /&gt;
The previous unit tests had syntactical and run time errors.  We were not able to get the previous unit tests to run without errors.  Because of this we rewrote the unit tests for the &amp;lt;b&amp;gt;ReviewResponseModel&amp;lt;/b&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
We added a test_helper file to the main test folder that requires a needed configuration file and needed gems.  We also added 8 fixtures that were needed for data to run the unit tests.  The following fixture files were added:&lt;br /&gt;
&lt;br /&gt;
* assignment_questionnaires.yml&lt;br /&gt;
* assignments.yml&lt;br /&gt;
* participants.yml&lt;br /&gt;
* questionnaires.yml&lt;br /&gt;
* response_maps.yml&lt;br /&gt;
* responses.yml&lt;br /&gt;
* teams.yml&lt;br /&gt;
* users.yml&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
There is at least one unit test for every public method within the &amp;lt;b&amp;gt;ReviewResponseModel&amp;lt;/b&amp;gt;.  The test naming convention used is &amp;quot;method_&amp;lt;name of method that is being tested&amp;gt;&amp;quot;.  For example, the unit test for the export method is &amp;quot;method_export&amp;quot;.  If there are multiple test for one method the name of the test will include the test case after the normal naming convention.  For example, one of the unit tests for the import method checks for an invalid assignment.  The name of this method is &amp;quot;method_import_invalid_assignment&amp;quot;.  The following are the unit tests we created:&lt;br /&gt;
&lt;br /&gt;
* method_export&lt;br /&gt;
* method_get_metareview_response_maps&lt;br /&gt;
* method_get_team_response_for_round&lt;br /&gt;
* method_final_versions_from_reviewer&lt;br /&gt;
* method_import&lt;br /&gt;
* method_import_invalid_reviewee&lt;br /&gt;
* method_import_invalid_reviewer&lt;br /&gt;
* method_import_invalid_assignment&lt;br /&gt;
* method_delete&lt;br /&gt;
* method_delete_no _force&lt;br /&gt;
* method_show_feedback&lt;br /&gt;
* method_get_title&lt;br /&gt;
* method_export_fields&lt;br /&gt;
* method_questionnaire&lt;br /&gt;
* method_add_reviewer&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
=== How to Run Unit Tests ===&lt;br /&gt;
To run the unit tests, follow these steps:&lt;br /&gt;
&lt;br /&gt;
# Download the master branch of the repo.&lt;br /&gt;
# Setup the Databases for the test environment (we have used Zhewei's scrubbed expertiza DB )&lt;br /&gt;
#* Run the &amp;quot; rake db:create RAILS_ENV=test &amp;quot; command&lt;br /&gt;
#* Run the &amp;quot; rake db:reset RAILS_ENV=test &amp;quot; command&lt;br /&gt;
#* Scrub the DB using &amp;quot; mysql -u root expertiza_development &amp;lt; expertiza-scrubbed.sql&amp;quot;&lt;br /&gt;
#* Run the &amp;quot; rake db:migrate &amp;quot;&lt;br /&gt;
# Run &amp;quot; rake test test/unit/review_response_map_test.rb &amp;quot; in the &amp;quot;expertiza/&amp;quot; directory.&lt;br /&gt;
#* If you run into a mysql log in error go into config/database.yml and edit the mysql credentials for the test section so that it matches the local environment's mysql configuration&lt;br /&gt;
# Check if tests passed or failed.&lt;br /&gt;
&lt;br /&gt;
= Manual Test Case =&lt;br /&gt;
&lt;br /&gt;
In order to test the changes made to the ReviewResponseMap, bring up Expertiza and log in as an administrator.  Once logged in, proceed with the following steps:&lt;br /&gt;
&lt;br /&gt;
# Go to '''impersonate user''' when logged in as ''instructor6'' and type in ''student559'' (or) just log in as ''student559''. All passwords are ''password'' .&lt;br /&gt;
# Pick any assignment to view.&lt;br /&gt;
# Navigate to '''Other's work'''.&lt;br /&gt;
# Check the different reviews and metareviews. Whether they are being displayed correctly or not.&lt;br /&gt;
# Go to Edit or Give feedback and submit a feedback.&lt;br /&gt;
# Go back and check if the feedback given is displayed correctly or not.&lt;br /&gt;
# Check if author's feedback is correct or not.&lt;br /&gt;
# Go to the '''Temp''' assignment and see if the page is being displayed correctly or not (since there is no assignment submission content or reviews for that).&lt;br /&gt;
&lt;br /&gt;
''NOTE: Since this was a refactoring of the code and methods, the existing functionality was supposed to remain the same and not break for the changes we've made.''&lt;br /&gt;
&lt;br /&gt;
= References =&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;references/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;3. [https://github.com/expertiza/expertiza Expertiza Main Repo] &amp;lt;br&amp;gt;&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;4. [https://github.com/adeeshag/expertiza/blob/develop/app/models/review_response_map.rb Refactored ReviewResponseMap.rb]&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;5. [https://github.com/adeeshag/expertiza/tree/develop/test/fixtures Test Fixtures]&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;6. [https://github.com/adeeshag/expertiza/blob/develop/test/unit/review_response_map_test.rb Unit Tests]&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;6. [http://152.46.16.195:5902/ Expertiza Deployed Site]&amp;lt;br&amp;gt;&lt;/div&gt;</summary>
		<author><name>Cnbrown4</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2015/ossE1558BGJ&amp;diff=98423</id>
		<title>CSC/ECE 517 Fall 2015/ossE1558BGJ</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2015/ossE1558BGJ&amp;diff=98423"/>
		<updated>2015-11-06T19:44:58Z</updated>

		<summary type="html">&lt;p&gt;Cnbrown4: /* Refactoring of metareview_response_maps method */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Introduction =&lt;br /&gt;
&lt;br /&gt;
This page provides a description of the modifications and improvements made to the Expertiza project’s source code as part of an Expertiza based Open Source Software project.  Expertiza is a web based application which allows students to submit and peer-review classmates’ work, including written articles and development projects. The specific changes made during the course of this project were to the ReviewResponseMap.rb file, with additional changes made to other related files in support of refactoring ReviewResponseMap.rb.  &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
= Problem Statement =&lt;br /&gt;
&lt;br /&gt;
ReviewResponseMap is the model class used to manage the relationship between contributors, reviewers, and assignments.  The intent of the changes were to refactor the code for better readability and adherence to Ruby coding standards and best practices.  Primarily these changes involved the refactoring of overly complex methods, renaming methods for better readability, and the addition of missing unit tests.&lt;br /&gt;
&lt;br /&gt;
Project Requirements:&lt;br /&gt;
&lt;br /&gt;
# Code Climate&amp;lt;ref name=&amp;quot;Code Climate&amp;quot;&amp;gt;https://codeclimate.com&amp;lt;/ref&amp;gt; shows import method is complex, because of lots of checks. This method can be fixed by adding private methods for raising import error.&lt;br /&gt;
# Get_assessments_round_for method can be renamed to get_team_responses_for_round. Team_id private variable is not needed.&lt;br /&gt;
# metareview_response_maps rename, refactoring can be done. No need to do second iteration.&lt;br /&gt;
# write missing unit tests for existing methods.&lt;br /&gt;
&lt;br /&gt;
= Design Patterns =&lt;br /&gt;
&lt;br /&gt;
As part of our project, we refactored the model to follow the Single Responsibility and Don't Repeat Yourself (DRY) Principles.  Both of the principles focus on reducing code repetition and increasing the cohesion of the individual methods in the class.  The Single Responsibility Principle states that each class and method should have sole responsibility over one single part of the functionality of the system&amp;lt;ref&amp;gt;https://en.wikipedia.org/wiki/Single_responsibility_principle&amp;lt;/ref&amp;gt;.  The DRY principle states that whenever the same types of logic and functionality are being performed in a class the duplicated logic should be extracted into a new method that can be called in place of the repeated lines of code &amp;lt;ref&amp;gt;https://en.wikipedia.org/wiki/Don%27t_repeat_yourself&amp;lt;/ref&amp;gt;.  A prime example of a method that initially violated these principles was the import method, which in addition to performing the core import processes also performed a number of checks that would be more properly extracted into private methods.&lt;br /&gt;
&lt;br /&gt;
=Code Changes =&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Refactoring of import method ===&lt;br /&gt;
&lt;br /&gt;
	CodeClimate reports showed the import method to be overly complex, with a number of checks being included within the import method itself.  The resolution for this problem was to refactor the import method, creating private methods to perform the null checks and throw import errors.&lt;br /&gt;
&lt;br /&gt;
Prior to refactoring, all null checks were performed in line:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;big&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 def self.import(row, session, id)&lt;br /&gt;
    if row.length &amp;lt; 2&lt;br /&gt;
      raise ArgumentError, &amp;quot;Not enough items&amp;quot;&lt;br /&gt;
    end&lt;br /&gt;
    assignment = Assignment.find(id)&lt;br /&gt;
    if assignment.nil?&lt;br /&gt;
      raise ImportError, &amp;quot;The assignment with id \&amp;quot;#{id}\&amp;quot; was not found. &amp;lt;a href='/assignment/new'&amp;gt;Create&amp;lt;/a&amp;gt; this assignment?&amp;quot;&lt;br /&gt;
    end&lt;br /&gt;
    index = 1&lt;br /&gt;
    while index &amp;lt; row.length&lt;br /&gt;
      user = User.find_by_name(row[index].to_s.strip)&lt;br /&gt;
      if user.nil?&lt;br /&gt;
        raise ImportError, &amp;quot;The user account for the reviewer \&amp;quot;#{row[index]}\&amp;quot; was not found. &amp;lt;a href='/users/new'&amp;gt;Create&amp;lt;/a&amp;gt; this user?&amp;quot;&lt;br /&gt;
      end&lt;br /&gt;
      reviewer = AssignmentParticipant.where(user_id: user.id, parent_id:  assignment.id).first&lt;br /&gt;
      if reviewer == nil&lt;br /&gt;
        raise ImportError, &amp;quot;The reviewer \&amp;quot;#{row[index]}\&amp;quot; is not a participant in this assignment. &amp;lt;a href='/users/new'&amp;gt;Register&amp;lt;/a&amp;gt; this user as a participant?&amp;quot;&lt;br /&gt;
      end&lt;br /&gt;
      if assignment.team_assignment&lt;br /&gt;
        reviewee = AssignmentTeam.where(name: row[0].to_s.strip, parent_id:  assignment.id).first&lt;br /&gt;
        if reviewee == nil&lt;br /&gt;
          raise ImportError, &amp;quot;The author \&amp;quot;#{row[0].to_s.strip}\&amp;quot; was not found. &amp;lt;a href='/users/new'&amp;gt;Create&amp;lt;/a&amp;gt; this user?&amp;quot;&lt;br /&gt;
        end&lt;br /&gt;
        existing = ReviewResponseMap.where(reviewee_id: reviewee.id, reviewer_id:  reviewer.id).first&lt;br /&gt;
        if existing.nil?&lt;br /&gt;
          ReviewResponseMap.create(:reviewer_id =&amp;gt; reviewer.id, :reviewee_id =&amp;gt; reviewee.id, :reviewed_object_id =&amp;gt; assignment.id)&lt;br /&gt;
        end&lt;br /&gt;
      else&lt;br /&gt;
        puser = User.find_by_name(row[0].to_s.strip)&lt;br /&gt;
        if user == nil&lt;br /&gt;
          raise ImportError, &amp;quot;The user account for the reviewee \&amp;quot;#{row[0]}\&amp;quot; was not found. &amp;lt;a href='/users/new'&amp;gt;Create&amp;lt;/a&amp;gt; this user?&amp;quot;&lt;br /&gt;
        end&lt;br /&gt;
        reviewee = AssignmentParticipant.where(user_id: puser.id, parent_id:  assignment.id).first&lt;br /&gt;
        if reviewee == nil&lt;br /&gt;
          raise ImportError, &amp;quot;The author \&amp;quot;#{row[0].to_s.strip}\&amp;quot; was not found. &amp;lt;a href='/users/new'&amp;gt;Create&amp;lt;/a&amp;gt; this user?&amp;quot;&lt;br /&gt;
        end&lt;br /&gt;
        team_id = TeamsUser.team_id(reviewee.parent_id, reviewee.user_id)&lt;br /&gt;
        existing = ReviewResponseMap.where(reviewee_id: team_id, reviewer_id:  reviewer.id).first&lt;br /&gt;
        if existing.nil?&lt;br /&gt;
          ReviewResponseMap.create(:reviewee_id =&amp;gt; team_id, :reviewer_id =&amp;gt; reviewer.id, :reviewed_object_id =&amp;gt; assignment.id)&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
      index += 1&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
&lt;br /&gt;
After refactoring the import method adheres to the single responsibility principle, performing only key import tasks while making calls to private methods for any necessary validation. The size of the import method was reduced by doing this and counts for better readability of the code. Also, this method is a very important one and care was taken so that it wouldn't break any existing functionality. Changes were reflected in CodeClimate (link expired as it was a trial version).&lt;br /&gt;
 &lt;br /&gt;
  &amp;lt;big&amp;gt;&amp;lt;nowiki&amp;gt;#Imports new reponse maps if they do not already exist&lt;br /&gt;
  def self.import(row, _session, id)&lt;br /&gt;
      if row.length &amp;lt; 2&lt;br /&gt;
          raise ArgumentError, 'Not enough items'&lt;br /&gt;
      end&lt;br /&gt;
      assignment = find_assignment(id)&lt;br /&gt;
      index = 1&lt;br /&gt;
      reviewee_name = row[0]&lt;br /&gt;
      while index &amp;lt; row.length&lt;br /&gt;
          reviewee_id = nil&lt;br /&gt;
          reviewer_name = row[index]&lt;br /&gt;
          reviewer = get_assignment_participant(reviewer_name,  assignment.id, &amp;quot;reviewer&amp;quot;)&lt;br /&gt;
          participant_nil?(reviewer, reviewer_name , &amp;quot;reviewer&amp;quot;)&lt;br /&gt;
         &lt;br /&gt;
         #Find reviewee if assignment is a team assignment&lt;br /&gt;
         if assignment.team_assignment&lt;br /&gt;
             reviewee = AssignmentTeam.where(name: reviewee_name .to_s.strip, parent_id: assignment.id).first&lt;br /&gt;
             participant_nil?(reviewee, reviewee_name, &amp;quot;author&amp;quot;)&lt;br /&gt;
             reviewee_id = reviewee.id&lt;br /&gt;
         #Find reviewee if assignment is not a team assignment&lt;br /&gt;
         else&lt;br /&gt;
	     reviewee = get_assignment_participant(reviewee_name, assignment.id, &amp;quot;reviewee&amp;quot;)&lt;br /&gt;
             participant_nil?(reviewee, reviewee_name, &amp;quot;author&amp;quot;)&lt;br /&gt;
             reviewee_id  = TeamsUser.team_id(reviewee.parent_id, reviewee.user_id)&lt;br /&gt;
         end&lt;br /&gt;
         create_response_map(reviewer, reviewee_id,  assignment)&lt;br /&gt;
         index += 1&lt;br /&gt;
      end&lt;br /&gt;
  end&amp;lt;/nowiki&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Private methods added:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;big&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  # Check for if assignment value is null&lt;br /&gt;
  def self.find_assignment(id)&lt;br /&gt;
      begin&lt;br /&gt;
          assignment = Assignment.find(id)&lt;br /&gt;
      rescue ActiveRecord::RecordNotFound&lt;br /&gt;
          raise ImportError, &amp;quot;The assignment with id \&amp;quot;#{id}\&amp;quot; was not found.&amp;lt;a href='/assignment/new'&amp;gt;Create&amp;lt;/a&amp;gt; this assignment?&amp;quot;&lt;br /&gt;
      end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  # Check for if participant is null&lt;br /&gt;
  def self.participant_nil?(participant, user_name, participant_type) &lt;br /&gt;
      error_message = nil&lt;br /&gt;
      if participant_type == &amp;quot;author&amp;quot;&lt;br /&gt;
          error_message = &amp;quot;The author \&amp;quot;#{user_name.to_s.strip}\&amp;quot; was not found.&amp;lt;a href='/users/new'&amp;gt;Create&amp;lt;/a&amp;gt; this user?&amp;quot;&lt;br /&gt;
      else&lt;br /&gt;
          error_message =  &amp;quot;The reviewer \&amp;quot;#{user_name}\&amp;quot; is not a participant in this assignment.&amp;lt;a href='/users/new'&amp;gt;Register&amp;lt;/a&amp;gt; this user as a participant?&amp;quot;&lt;br /&gt;
      end&lt;br /&gt;
      check_nil?(participant, error_message)&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  # Check for if user is null&lt;br /&gt;
  def self.user_nil?(user, user_name, user_type)&lt;br /&gt;
      check_nil?( user, &amp;quot;The user account for the \&amp;quot;#{user_type}\&amp;quot; \&amp;quot;#{user_name}\&amp;quot; was not found.&amp;lt;a href='/users/new'&amp;gt;Create&amp;lt;/a&amp;gt; this user?&amp;quot;)&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
 #Throws import error for nil objects&lt;br /&gt;
  def self.check_nil?(object, error_message)&lt;br /&gt;
      if object.nil?&lt;br /&gt;
          raise ImportError, error_message&lt;br /&gt;
      end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Refactoring of get_assessments_round_for method ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The get_assessments_round_for method’s name failed to provide a clear idea of the method’s purpose and functionality. Additionally, there was a private variable, team_id, introduced in the method that was unnecessary and could be replaced by using the id property of the team parameter directly.  &lt;br /&gt;
&amp;lt;big&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  def self.get_assessments_round_for(team,round)&lt;br /&gt;
    team_id =team.id&lt;br /&gt;
    responses = Array.new&lt;br /&gt;
    if team_id&lt;br /&gt;
      maps = ResponseMap.where(:reviewee_id =&amp;gt; team_id, :type =&amp;gt; &amp;quot;ReviewResponseMap&amp;quot;)&lt;br /&gt;
      maps.each{ |map|&lt;br /&gt;
        if !map.response.empty? &amp;amp;&amp;amp; !map.response.reject{|r| r.round!=round}.empty?&lt;br /&gt;
          responses &amp;lt;&amp;lt; map.response.reject{|r| r.round!=round}.last&lt;br /&gt;
        end&lt;br /&gt;
      }&lt;br /&gt;
      responses.sort! {|a,b| a.map.reviewer.fullname &amp;lt;=&amp;gt; b.map.reviewer.fullname }&lt;br /&gt;
    end&lt;br /&gt;
    return responses&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Following the refactoring, the name of the method provides a clearer idea of its purpose:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;big&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  def self.get_team_responses_for_round(team, round)&lt;br /&gt;
    responses = []&lt;br /&gt;
    if team.id&lt;br /&gt;
      maps = ResponseMap.where(reviewee_id: team.id, type: 'ReviewResponseMap')&lt;br /&gt;
      maps.each do |map|&lt;br /&gt;
        unless map.response.empty? &amp;amp;&amp;amp; map.response.reject { |r| r.round != round }.empty?&lt;br /&gt;
          responses &amp;lt;&amp;lt; map.response.reject { |r| r.round != round }.last&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
      responses.sort! { |a, b| a.map.reviewer.fullname &amp;lt;=&amp;gt; b.map.reviewer.fullname }&lt;br /&gt;
    end&lt;br /&gt;
    responses&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
The change in method name also required changes to the following files that referenced it:&lt;br /&gt;
&lt;br /&gt;
/app/models/assignment.rb:436:    &lt;br /&gt;
 &lt;br /&gt;
&amp;lt;big&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  assessments = ReviewResponseMap.get_assessments_round_for(team,i)&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt; &lt;br /&gt;
&lt;br /&gt;
./app/models/assignment_participant.rb:268:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;big&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 scores[questionnaire_symbol][:assessments] = questionnaire.get_assessments_round_for(self,round)&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Refactoring of metareview_response_maps method ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The metareview_response_maps method was unnecessarily complex.  It contained unneeded private variables and an unnecessary nested loop.  Originally, it added each metareview map individually in the nested loop.  We decided to remove the nested loop and use the concat method for readability and maintainability.  These changes allowed us to remove the private variable &amp;quot;metareview_list&amp;quot; and only maintain the &amp;quot;metareview_response_maps&amp;quot; variable.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;big&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 def metareview_response_maps&lt;br /&gt;
    responses = Response.where(map_id:self.id)&lt;br /&gt;
    metareview_list=[]&lt;br /&gt;
    responses.each do |response|&lt;br /&gt;
      metareview_response_maps = MetareviewResponseMap.where(reviewed_object_id:response.id)&lt;br /&gt;
      metareview_response_maps.each do |metareview_response_map|&lt;br /&gt;
        metareview_list&amp;lt;&amp;lt;metareview_response_map&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
    metareview_list&lt;br /&gt;
 end&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
After refactoring:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;big&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  def get_metareview_response_maps&lt;br /&gt;
    responses = Response.where(map_id: id)&lt;br /&gt;
    metareview_response_maps = []&lt;br /&gt;
    responses.each do |response|&lt;br /&gt;
      metareview_response_maps.concat MetareviewResponseMap.where(reviewed_object_id: response.id)&lt;br /&gt;
    end&lt;br /&gt;
    metareview_response_maps&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Addition of code comments ===&lt;br /&gt;
&lt;br /&gt;
We added comments to all of the methods in the ReviewResponseMap.rb file and corrected instances where CodeClimate Identified opportunities for code improvement.  One issue flagged by CodeClimate that we did not change was to use the find_by method instead of where().first method.  The where().first method occurs in the import, get_assignment_participant, and create_response_map methods. It is not always appropriate to use the find_by method, as documented in this github post: https://github.com/bbatsov/rubocop/issues/1938 .  In instances where ordering by id is the desired behavior, where().first will order by default, but in Rails 4+ find_by does not honor that default behavior.  For this reason we left the instances of where().first unchanged.&lt;br /&gt;
&lt;br /&gt;
=== Code Improvements ===&lt;br /&gt;
&lt;br /&gt;
This refactoring was to improve readability and follow as many good ''Rubyist'' coding practices as possible without breaking the functionality of existing code. We used CodeClimate of the master branch code as a reference. We took the suggestions we got from CodeClimate and improved our code based on that.&lt;br /&gt;
We also made some of the methods shorter by removing redundant functionality and adding private methods to methods with a lot of functions. We also added private methods in places where we saw repeated patterns to make the code ''DRYer''.&lt;br /&gt;
At the end of our refactoring, we managed to improve the rating on CodeClimate from a '''C''' to a '''B''' . Further improvements meant reducing the size of the entire class which required a much more significant refactoring in multiple files and folders. We focussed on refactoring the existing mode, '''ReviewResponseMap'''.&lt;br /&gt;
&lt;br /&gt;
= Unit Tests =&lt;br /&gt;
&lt;br /&gt;
=== Refactoring of Unit Tests===&lt;br /&gt;
&lt;br /&gt;
The previous unit tests had syntactical and run time errors.  We were not able to get the previous unit tests to run without errors.  Because of this we rewrote the unit tests for the &amp;lt;b&amp;gt;ReviewResponseModel&amp;lt;/b&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
We added a test_helper file to the main test folder that requires a needed configuration file and needed gems.  We also added 8 fixtures that were needed for data to run the unit tests.  The following fixture files were added:&lt;br /&gt;
&lt;br /&gt;
* assignment_questionnaires.yml&lt;br /&gt;
* assignments.yml&lt;br /&gt;
* participants.yml&lt;br /&gt;
* questionnaires.yml&lt;br /&gt;
* response_maps.yml&lt;br /&gt;
* responses.yml&lt;br /&gt;
* teams.yml&lt;br /&gt;
* users.yml&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
There is at least one unit test for every public method within the &amp;lt;b&amp;gt;ReviewResponseModel&amp;lt;/b&amp;gt;.  The test naming convention used is &amp;quot;method_&amp;lt;name of method that is being tested&amp;gt;&amp;quot;.  For example, the unit test for the export method is &amp;quot;method_export&amp;quot;.  If there are multiple test for one method the name of the test will include the test case after the normal naming convention.  For example, one of the unit tests for the import method checks for an invalid assignment.  The name of this method is &amp;quot;method_import_invalid_assignment&amp;quot;.  The following are the unit tests we created:&lt;br /&gt;
&lt;br /&gt;
* method_export&lt;br /&gt;
* method_get_metareview_response_maps&lt;br /&gt;
* method_get_team_response_for_round&lt;br /&gt;
* method_final_versions_from_reviewer&lt;br /&gt;
* method_import&lt;br /&gt;
* method_import_invalid_reviewee&lt;br /&gt;
* method_import_invalid_reviewer&lt;br /&gt;
* method_import_invalid_assignment&lt;br /&gt;
* method_delete&lt;br /&gt;
* method_delete_no _force&lt;br /&gt;
* method_show_feedback&lt;br /&gt;
* method_get_title&lt;br /&gt;
* method_export_fields&lt;br /&gt;
* method_questionnaire&lt;br /&gt;
* method_add_reviewer&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
=== How to Run Unit Tests ===&lt;br /&gt;
To run the unit tests, follow these steps:&lt;br /&gt;
&lt;br /&gt;
# Download the master branch of the repo.&lt;br /&gt;
# Setup the Databases for the test environment (we have used Zhewei's scrubbed expertiza DB )&lt;br /&gt;
#* Run the &amp;quot; rake db:create RAILS_ENV=test &amp;quot; command&lt;br /&gt;
#* Run the &amp;quot; rake db:reset RAILS_ENV=test &amp;quot; command&lt;br /&gt;
#* Scrub the DB using &amp;quot; mysql -u root expertiza_development &amp;lt; expertiza-scrubbed.sql&amp;quot;&lt;br /&gt;
#* Run the &amp;quot; rake db:migrate &amp;quot;&lt;br /&gt;
# Run &amp;quot; rake test test/unit/review_response_map_test.rb &amp;quot; in the &amp;quot;expertiza/&amp;quot; directory.&lt;br /&gt;
#* If you run into a mysql log in error go into config/database.yml and edit the mysql credentials for the test section so that it matches the local environment's mysql configuration&lt;br /&gt;
# Check if tests passed or failed.&lt;br /&gt;
&lt;br /&gt;
= Manual Test Case =&lt;br /&gt;
&lt;br /&gt;
In order to test the changes made to the ReviewResponseMap, bring up Expertiza and log in as an administrator.  Once logged in, proceed with the following steps:&lt;br /&gt;
&lt;br /&gt;
# Go to '''impersonate user''' when logged in as ''instructor6'' and type in ''student559'' (or) just log in as ''student559''. All passwords are ''password'' .&lt;br /&gt;
# Pick any assignment to view.&lt;br /&gt;
# Navigate to '''Other's work'''.&lt;br /&gt;
# Check the different reviews and metareviews. Whether they are being displayed correctly or not.&lt;br /&gt;
# Go to Edit or Give feedback and submit a feedback.&lt;br /&gt;
# Go back and check if the feedback given is displayed correctly or not.&lt;br /&gt;
# Check if author's feedback is correct or not.&lt;br /&gt;
# Go to the '''Temp''' assignment and see if the page is being displayed correctly or not (since there is no assignment submission content or reviews for that).&lt;br /&gt;
&lt;br /&gt;
''NOTE: Since this was a refactoring of the code and methods, the existing functionality was supposed to remain the same and not break for the changes we've made.''&lt;br /&gt;
&lt;br /&gt;
= References =&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;references/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;3. [https://github.com/expertiza/expertiza Expertiza Main Repo] &amp;lt;br&amp;gt;&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;4. [https://github.com/adeeshag/expertiza/blob/develop/app/models/review_response_map.rb Refactored ReviewResponseMap.rb]&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;5. [https://github.com/adeeshag/expertiza/tree/develop/test/fixtures Test Fixtures]&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;6. [https://github.com/adeeshag/expertiza/blob/develop/test/unit/review_response_map_test.rb Unit Tests]&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;6. [http://152.46.16.195:5902/ Expertiza Deployed Site]&amp;lt;br&amp;gt;&lt;/div&gt;</summary>
		<author><name>Cnbrown4</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2015/ossE1558BGJ&amp;diff=98421</id>
		<title>CSC/ECE 517 Fall 2015/ossE1558BGJ</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2015/ossE1558BGJ&amp;diff=98421"/>
		<updated>2015-11-06T18:38:29Z</updated>

		<summary type="html">&lt;p&gt;Cnbrown4: /* Unit Tests */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Introduction =&lt;br /&gt;
&lt;br /&gt;
This page provides a description of the modifications and improvements made to the Expertiza project’s source code as part of an Expertiza based Open Source Software project.  Expertiza is a web based application which allows students to submit and peer-review classmates’ work, including written articles and development projects. The specific changes made during the course of this project were to the ReviewResponseMap.rb file, with additional changes made to other related files in support of refactoring ReviewResponseMap.rb.  &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
= Problem Statement =&lt;br /&gt;
&lt;br /&gt;
ReviewResponseMap is the model class used to manage the relationship between contributors, reviewers, and assignments.  The intent of the changes were to refactor the code for better readability and adherence to Ruby coding standards and best practices.  Primarily these changes involved the refactoring of overly complex methods, renaming methods for better readability, and the addition of missing unit tests.&lt;br /&gt;
&lt;br /&gt;
Project Requirements:&lt;br /&gt;
&lt;br /&gt;
# Code Climate&amp;lt;ref name=&amp;quot;Code Climate&amp;quot;&amp;gt;https://codeclimate.com&amp;lt;/ref&amp;gt; shows import method is complex, because of lots of checks. This method can be fixed by adding private methods for raising import error.&lt;br /&gt;
# Get_assessments_round_for method can be renamed to get_team_responses_for_round. Team_id private variable is not needed.&lt;br /&gt;
# metareview_response_maps rename, refactoring can be done. No need to do second iteration.&lt;br /&gt;
# write missing unit tests for existing methods.&lt;br /&gt;
&lt;br /&gt;
= Design Patterns =&lt;br /&gt;
&lt;br /&gt;
As part of our project, we refactored the model to follow the Single Responsibility and Don't Repeat Yourself (DRY) Principles.  Both of the principles focus on reducing code repetition and increasing the cohesion of the individual methods in the class.  The Single Responsibility Principle states that each class and method should have sole responsibility over one single part of the functionality of the system&amp;lt;ref&amp;gt;https://en.wikipedia.org/wiki/Single_responsibility_principle&amp;lt;/ref&amp;gt;.  The DRY principle states that whenever the same types of logic and functionality are being performed in a class the duplicated logic should be extracted into a new method that can be called in place of the repeated lines of code &amp;lt;ref&amp;gt;https://en.wikipedia.org/wiki/Don%27t_repeat_yourself&amp;lt;/ref&amp;gt;.  A prime example of a method that initially violated these principles was the import method, which in addition to performing the core import processes also performed a number of checks that would be more properly extracted into private methods.&lt;br /&gt;
&lt;br /&gt;
=Code Changes =&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Refactoring of import method ===&lt;br /&gt;
&lt;br /&gt;
	CodeClimate reports showed the import method to be overly complex, with a number of checks being included within the import method itself.  The resolution for this problem was to refactor the import method, creating private methods to perform the null checks and throw import errors.&lt;br /&gt;
&lt;br /&gt;
Prior to refactoring, all null checks were performed in line:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;big&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 def self.import(row, session, id)&lt;br /&gt;
    if row.length &amp;lt; 2&lt;br /&gt;
      raise ArgumentError, &amp;quot;Not enough items&amp;quot;&lt;br /&gt;
    end&lt;br /&gt;
    assignment = Assignment.find(id)&lt;br /&gt;
    if assignment.nil?&lt;br /&gt;
      raise ImportError, &amp;quot;The assignment with id \&amp;quot;#{id}\&amp;quot; was not found. &amp;lt;a href='/assignment/new'&amp;gt;Create&amp;lt;/a&amp;gt; this assignment?&amp;quot;&lt;br /&gt;
    end&lt;br /&gt;
    index = 1&lt;br /&gt;
    while index &amp;lt; row.length&lt;br /&gt;
      user = User.find_by_name(row[index].to_s.strip)&lt;br /&gt;
      if user.nil?&lt;br /&gt;
        raise ImportError, &amp;quot;The user account for the reviewer \&amp;quot;#{row[index]}\&amp;quot; was not found. &amp;lt;a href='/users/new'&amp;gt;Create&amp;lt;/a&amp;gt; this user?&amp;quot;&lt;br /&gt;
      end&lt;br /&gt;
      reviewer = AssignmentParticipant.where(user_id: user.id, parent_id:  assignment.id).first&lt;br /&gt;
      if reviewer == nil&lt;br /&gt;
        raise ImportError, &amp;quot;The reviewer \&amp;quot;#{row[index]}\&amp;quot; is not a participant in this assignment. &amp;lt;a href='/users/new'&amp;gt;Register&amp;lt;/a&amp;gt; this user as a participant?&amp;quot;&lt;br /&gt;
      end&lt;br /&gt;
      if assignment.team_assignment&lt;br /&gt;
        reviewee = AssignmentTeam.where(name: row[0].to_s.strip, parent_id:  assignment.id).first&lt;br /&gt;
        if reviewee == nil&lt;br /&gt;
          raise ImportError, &amp;quot;The author \&amp;quot;#{row[0].to_s.strip}\&amp;quot; was not found. &amp;lt;a href='/users/new'&amp;gt;Create&amp;lt;/a&amp;gt; this user?&amp;quot;&lt;br /&gt;
        end&lt;br /&gt;
        existing = ReviewResponseMap.where(reviewee_id: reviewee.id, reviewer_id:  reviewer.id).first&lt;br /&gt;
        if existing.nil?&lt;br /&gt;
          ReviewResponseMap.create(:reviewer_id =&amp;gt; reviewer.id, :reviewee_id =&amp;gt; reviewee.id, :reviewed_object_id =&amp;gt; assignment.id)&lt;br /&gt;
        end&lt;br /&gt;
      else&lt;br /&gt;
        puser = User.find_by_name(row[0].to_s.strip)&lt;br /&gt;
        if user == nil&lt;br /&gt;
          raise ImportError, &amp;quot;The user account for the reviewee \&amp;quot;#{row[0]}\&amp;quot; was not found. &amp;lt;a href='/users/new'&amp;gt;Create&amp;lt;/a&amp;gt; this user?&amp;quot;&lt;br /&gt;
        end&lt;br /&gt;
        reviewee = AssignmentParticipant.where(user_id: puser.id, parent_id:  assignment.id).first&lt;br /&gt;
        if reviewee == nil&lt;br /&gt;
          raise ImportError, &amp;quot;The author \&amp;quot;#{row[0].to_s.strip}\&amp;quot; was not found. &amp;lt;a href='/users/new'&amp;gt;Create&amp;lt;/a&amp;gt; this user?&amp;quot;&lt;br /&gt;
        end&lt;br /&gt;
        team_id = TeamsUser.team_id(reviewee.parent_id, reviewee.user_id)&lt;br /&gt;
        existing = ReviewResponseMap.where(reviewee_id: team_id, reviewer_id:  reviewer.id).first&lt;br /&gt;
        if existing.nil?&lt;br /&gt;
          ReviewResponseMap.create(:reviewee_id =&amp;gt; team_id, :reviewer_id =&amp;gt; reviewer.id, :reviewed_object_id =&amp;gt; assignment.id)&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
      index += 1&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
&lt;br /&gt;
After refactoring the import method adheres to the single responsibility principle, performing only key import tasks while making calls to private methods for any necessary validation. The size of the import method was reduced by doing this and counts for better readability of the code. Also, this method is a very important one and care was taken so that it wouldn't break any existing functionality. Changes were reflected in CodeClimate (link expired as it was a trial version).&lt;br /&gt;
 &lt;br /&gt;
  &amp;lt;big&amp;gt;&amp;lt;nowiki&amp;gt;#Imports new reponse maps if they do not already exist&lt;br /&gt;
  def self.import(row, _session, id)&lt;br /&gt;
      if row.length &amp;lt; 2&lt;br /&gt;
          raise ArgumentError, 'Not enough items'&lt;br /&gt;
      end&lt;br /&gt;
      assignment = find_assignment(id)&lt;br /&gt;
      index = 1&lt;br /&gt;
      reviewee_name = row[0]&lt;br /&gt;
      while index &amp;lt; row.length&lt;br /&gt;
          reviewee_id = nil&lt;br /&gt;
          reviewer_name = row[index]&lt;br /&gt;
          reviewer = get_assignment_participant(reviewer_name,  assignment.id, &amp;quot;reviewer&amp;quot;)&lt;br /&gt;
          participant_nil?(reviewer, reviewer_name , &amp;quot;reviewer&amp;quot;)&lt;br /&gt;
         &lt;br /&gt;
         #Find reviewee if assignment is a team assignment&lt;br /&gt;
         if assignment.team_assignment&lt;br /&gt;
             reviewee = AssignmentTeam.where(name: reviewee_name .to_s.strip, parent_id: assignment.id).first&lt;br /&gt;
             participant_nil?(reviewee, reviewee_name, &amp;quot;author&amp;quot;)&lt;br /&gt;
             reviewee_id = reviewee.id&lt;br /&gt;
         #Find reviewee if assignment is not a team assignment&lt;br /&gt;
         else&lt;br /&gt;
	     reviewee = get_assignment_participant(reviewee_name, assignment.id, &amp;quot;reviewee&amp;quot;)&lt;br /&gt;
             participant_nil?(reviewee, reviewee_name, &amp;quot;author&amp;quot;)&lt;br /&gt;
             reviewee_id  = TeamsUser.team_id(reviewee.parent_id, reviewee.user_id)&lt;br /&gt;
         end&lt;br /&gt;
         create_response_map(reviewer, reviewee_id,  assignment)&lt;br /&gt;
         index += 1&lt;br /&gt;
      end&lt;br /&gt;
  end&amp;lt;/nowiki&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Private methods added:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;big&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  # Check for if assignment value is null&lt;br /&gt;
  def self.find_assignment(id)&lt;br /&gt;
      begin&lt;br /&gt;
          assignment = Assignment.find(id)&lt;br /&gt;
      rescue ActiveRecord::RecordNotFound&lt;br /&gt;
          raise ImportError, &amp;quot;The assignment with id \&amp;quot;#{id}\&amp;quot; was not found.&amp;lt;a href='/assignment/new'&amp;gt;Create&amp;lt;/a&amp;gt; this assignment?&amp;quot;&lt;br /&gt;
      end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  # Check for if participant is null&lt;br /&gt;
  def self.participant_nil?(participant, user_name, participant_type) &lt;br /&gt;
      error_message = nil&lt;br /&gt;
      if participant_type == &amp;quot;author&amp;quot;&lt;br /&gt;
          error_message = &amp;quot;The author \&amp;quot;#{user_name.to_s.strip}\&amp;quot; was not found.&amp;lt;a href='/users/new'&amp;gt;Create&amp;lt;/a&amp;gt; this user?&amp;quot;&lt;br /&gt;
      else&lt;br /&gt;
          error_message =  &amp;quot;The reviewer \&amp;quot;#{user_name}\&amp;quot; is not a participant in this assignment.&amp;lt;a href='/users/new'&amp;gt;Register&amp;lt;/a&amp;gt; this user as a participant?&amp;quot;&lt;br /&gt;
      end&lt;br /&gt;
      check_nil?(participant, error_message)&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  # Check for if user is null&lt;br /&gt;
  def self.user_nil?(user, user_name, user_type)&lt;br /&gt;
      check_nil?( user, &amp;quot;The user account for the \&amp;quot;#{user_type}\&amp;quot; \&amp;quot;#{user_name}\&amp;quot; was not found.&amp;lt;a href='/users/new'&amp;gt;Create&amp;lt;/a&amp;gt; this user?&amp;quot;)&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
 #Throws import error for nil objects&lt;br /&gt;
  def self.check_nil?(object, error_message)&lt;br /&gt;
      if object.nil?&lt;br /&gt;
          raise ImportError, error_message&lt;br /&gt;
      end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Refactoring of get_assessments_round_for method ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The get_assessments_round_for method’s name failed to provide a clear idea of the method’s purpose and functionality. Additionally, there was a private variable, team_id, introduced in the method that was unnecessary and could be replaced by using the id property of the team parameter directly.  &lt;br /&gt;
&amp;lt;big&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  def self.get_assessments_round_for(team,round)&lt;br /&gt;
    team_id =team.id&lt;br /&gt;
    responses = Array.new&lt;br /&gt;
    if team_id&lt;br /&gt;
      maps = ResponseMap.where(:reviewee_id =&amp;gt; team_id, :type =&amp;gt; &amp;quot;ReviewResponseMap&amp;quot;)&lt;br /&gt;
      maps.each{ |map|&lt;br /&gt;
        if !map.response.empty? &amp;amp;&amp;amp; !map.response.reject{|r| r.round!=round}.empty?&lt;br /&gt;
          responses &amp;lt;&amp;lt; map.response.reject{|r| r.round!=round}.last&lt;br /&gt;
        end&lt;br /&gt;
      }&lt;br /&gt;
      responses.sort! {|a,b| a.map.reviewer.fullname &amp;lt;=&amp;gt; b.map.reviewer.fullname }&lt;br /&gt;
    end&lt;br /&gt;
    return responses&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Following the refactoring, the name of the method provides a clearer idea of its purpose:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;big&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  def self.get_team_responses_for_round(team, round)&lt;br /&gt;
    responses = []&lt;br /&gt;
    if team.id&lt;br /&gt;
      maps = ResponseMap.where(reviewee_id: team.id, type: 'ReviewResponseMap')&lt;br /&gt;
      maps.each do |map|&lt;br /&gt;
        unless map.response.empty? &amp;amp;&amp;amp; map.response.reject { |r| r.round != round }.empty?&lt;br /&gt;
          responses &amp;lt;&amp;lt; map.response.reject { |r| r.round != round }.last&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
      responses.sort! { |a, b| a.map.reviewer.fullname &amp;lt;=&amp;gt; b.map.reviewer.fullname }&lt;br /&gt;
    end&lt;br /&gt;
    responses&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
The change in method name also required changes to the following files that referenced it:&lt;br /&gt;
&lt;br /&gt;
/app/models/assignment.rb:436:    &lt;br /&gt;
 &lt;br /&gt;
&amp;lt;big&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  assessments = ReviewResponseMap.get_assessments_round_for(team,i)&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt; &lt;br /&gt;
&lt;br /&gt;
./app/models/assignment_participant.rb:268:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;big&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 scores[questionnaire_symbol][:assessments] = questionnaire.get_assessments_round_for(self,round)&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Refactoring of metareview_response_maps method ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The metareview_response_maps method was unnecessarily complex, introducing unneeded private variables and removing additional loop. &lt;br /&gt;
Here, the ''metareview_response_maps'' variable is a collection that doesn't need to be looped (in fact the metareviews are being overwritten each iteration of the loop and not appended to the collection). And we're returning the last value of the collection. The rest of them are just lost. We've removed the redundant iteration so that it just maps to metareviews once and returns the collection at the end of the iteration. The private variable removed is: ''metareview_list'' .&lt;br /&gt;
&lt;br /&gt;
&amp;lt;big&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 def metareview_response_maps&lt;br /&gt;
    responses = Response.where(map_id:self.id)&lt;br /&gt;
    metareview_list=Array.new()&lt;br /&gt;
    responses.each do |response|&lt;br /&gt;
      metareview_response_maps = MetareviewResponseMap.where(reviewed_object_id:response.id)&lt;br /&gt;
      metareview_response_maps.each do |metareview_response_map|&lt;br /&gt;
        metareview_list&amp;lt;&amp;lt;metareview_response_map&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
    metareview_list&lt;br /&gt;
 end&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
After refactoring:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;big&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  def get_metareview_response_maps&lt;br /&gt;
    responses = Response.where(map_id: id)&lt;br /&gt;
    metareview_response_maps = []&lt;br /&gt;
    responses.each do |response|&lt;br /&gt;
      metareview_response_maps &amp;lt;&amp;lt; MetareviewResponseMap.where(reviewed_object_id: response.id)&lt;br /&gt;
    end&lt;br /&gt;
    metareview_response_maps&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Addition of code comments ===&lt;br /&gt;
&lt;br /&gt;
We added comments to all of the methods in the ReviewResponseMap.rb file and corrected instances where CodeClimate Identified opportunities for code improvement.  One issue flagged by CodeClimate that we did not change was to use the find_by method instead of where().first method.  The where().first method occurs in the import, get_assignment_participant, and create_response_map methods. It is not always appropriate to use the find_by method, as documented in this github post: https://github.com/bbatsov/rubocop/issues/1938 .  In instances where ordering by id is the desired behavior, where().first will order by default, but in Rails 4+ find_by does not honor that default behavior.  For this reason we left the instances of where().first unchanged.&lt;br /&gt;
&lt;br /&gt;
=== Code Improvements ===&lt;br /&gt;
&lt;br /&gt;
This refactoring was to improve readability and follow as many good ''Rubyist'' coding practices as possible without breaking the functionality of existing code. We used CodeClimate of the master branch code as a reference. We took the suggestions we got from CodeClimate and improved our code based on that.&lt;br /&gt;
We also made some of the methods shorter by removing redundant functionality and adding private methods to methods with a lot of functions. We also added private methods in places where we saw repeated patterns to make the code ''DRYer''.&lt;br /&gt;
At the end of our refactoring, we managed to improve the rating on CodeClimate from a '''C''' to a '''B''' . Further improvements meant reducing the size of the entire class which required a much more significant refactoring in multiple files and folders. We focussed on refactoring the existing mode, '''ReviewResponseMap'''.&lt;br /&gt;
&lt;br /&gt;
= Unit Tests =&lt;br /&gt;
&lt;br /&gt;
=== Refactoring of Unit Tests===&lt;br /&gt;
&lt;br /&gt;
The previous unit tests had syntactical and run time errors.  We were not able to get the previous unit tests to run without errors.  Because of this we rewrote the unit tests for the &amp;lt;b&amp;gt;ReviewResponseModel&amp;lt;/b&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
We added a test_helper file to the main test folder that requires a needed configuration file and needed gems.  We also added 8 fixtures that were needed for data to run the unit tests.  The following fixture files were added:&lt;br /&gt;
&lt;br /&gt;
* assignment_questionnaires.yml&lt;br /&gt;
* assignments.yml&lt;br /&gt;
* participants.yml&lt;br /&gt;
* questionnaires.yml&lt;br /&gt;
* response_maps.yml&lt;br /&gt;
* responses.yml&lt;br /&gt;
* teams.yml&lt;br /&gt;
* users.yml&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
There is at least one unit test for every public method within the &amp;lt;b&amp;gt;ReviewResponseModel&amp;lt;/b&amp;gt;.  The test naming convention used is &amp;quot;method_&amp;lt;name of method that is being tested&amp;gt;&amp;quot;.  For example, the unit test for the export method is &amp;quot;method_export&amp;quot;.  If there are multiple test for one method the name of the test will include the test case after the normal naming convention.  For example, one of the unit tests for the import method checks for an invalid assignment.  The name of this method is &amp;quot;method_import_invalid_assignment&amp;quot;.  The following are the unit tests we created:&lt;br /&gt;
&lt;br /&gt;
* method_export&lt;br /&gt;
* method_get_metareview_response_maps&lt;br /&gt;
* method_get_team_response_for_round&lt;br /&gt;
* method_final_versions_from_reviewer&lt;br /&gt;
* method_import&lt;br /&gt;
* method_import_invalid_reviewee&lt;br /&gt;
* method_import_invalid_reviewer&lt;br /&gt;
* method_import_invalid_assignment&lt;br /&gt;
* method_delete&lt;br /&gt;
* method_delete_no _force&lt;br /&gt;
* method_show_feedback&lt;br /&gt;
* method_get_title&lt;br /&gt;
* method_export_fields&lt;br /&gt;
* method_questionnaire&lt;br /&gt;
* method_add_reviewer&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
=== How to Run Unit Tests ===&lt;br /&gt;
To run the unit tests, follow these steps:&lt;br /&gt;
&lt;br /&gt;
# Download the master branch of the repo.&lt;br /&gt;
# Setup the Databases for the test environment (we have used Zhewei's scrubbed expertiza DB )&lt;br /&gt;
#* Run the &amp;quot; rake db:create RAILS_ENV=test &amp;quot; command&lt;br /&gt;
#* Run the &amp;quot; rake db:reset RAILS_ENV=test &amp;quot; command&lt;br /&gt;
#* Scrub the DB using &amp;quot; mysql -u root expertiza_development &amp;lt; expertiza-scrubbed.sql&amp;quot;&lt;br /&gt;
#* Run the &amp;quot; rake db:migrate &amp;quot;&lt;br /&gt;
# Run &amp;quot; rake test test/unit/review_response_map_test.rb &amp;quot; in the &amp;quot;expertiza/&amp;quot; directory.&lt;br /&gt;
#* If you run into a mysql log in error go into config/database.yml and edit the mysql credentials for the test section so that it matches the local environment's mysql configuration&lt;br /&gt;
# Check if tests passed or failed.&lt;br /&gt;
&lt;br /&gt;
= Manual Test Case =&lt;br /&gt;
&lt;br /&gt;
In order to test the changes made to the ReviewResponseMap, bring up Expertiza and log in as an administrator.  Once logged in, proceed with the following steps:&lt;br /&gt;
&lt;br /&gt;
# Go to '''impersonate user''' when logged in as ''instructor6'' and type in ''student559'' (or) just log in as ''student559''. All passwords are ''password'' .&lt;br /&gt;
# Pick any assignment to view.&lt;br /&gt;
# Navigate to '''Other's work'''.&lt;br /&gt;
# Check the different reviews and metareviews. Whether they are being displayed correctly or not.&lt;br /&gt;
# Go to Edit or Give feedback and submit a feedback.&lt;br /&gt;
# Go back and check if the feedback given is displayed correctly or not.&lt;br /&gt;
# Check if author's feedback is correct or not.&lt;br /&gt;
# Go to the '''Temp''' assignment and see if the page is being displayed correctly or not (since there is no assignment submission content or reviews for that).&lt;br /&gt;
&lt;br /&gt;
''NOTE: Since this was a refactoring of the code and methods, the existing functionality was supposed to remain the same and not break for the changes we've made.''&lt;br /&gt;
&lt;br /&gt;
= References =&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;references/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;3. [https://github.com/expertiza/expertiza Expertiza Main Repo] &amp;lt;br&amp;gt;&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;4. [https://github.com/adeeshag/expertiza/blob/develop/app/models/review_response_map.rb Refactored ReviewResponseMap.rb]&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;5. [https://github.com/adeeshag/expertiza/tree/develop/test/fixtures Test Fixtures]&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;6. [https://github.com/adeeshag/expertiza/blob/develop/test/unit/review_response_map_test.rb Unit Tests]&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;6. [http://152.46.16.195:5902/ Expertiza Deployed Site]&amp;lt;br&amp;gt;&lt;/div&gt;</summary>
		<author><name>Cnbrown4</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2015/ossE1558BGJ&amp;diff=98420</id>
		<title>CSC/ECE 517 Fall 2015/ossE1558BGJ</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2015/ossE1558BGJ&amp;diff=98420"/>
		<updated>2015-11-06T18:35:11Z</updated>

		<summary type="html">&lt;p&gt;Cnbrown4: /* Refactoring of Unit Tests */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Introduction =&lt;br /&gt;
&lt;br /&gt;
This page provides a description of the modifications and improvements made to the Expertiza project’s source code as part of an Expertiza based Open Source Software project.  Expertiza is a web based application which allows students to submit and peer-review classmates’ work, including written articles and development projects. The specific changes made during the course of this project were to the ReviewResponseMap.rb file, with additional changes made to other related files in support of refactoring ReviewResponseMap.rb.  &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
= Problem Statement =&lt;br /&gt;
&lt;br /&gt;
ReviewResponseMap is the model class used to manage the relationship between contributors, reviewers, and assignments.  The intent of the changes were to refactor the code for better readability and adherence to Ruby coding standards and best practices.  Primarily these changes involved the refactoring of overly complex methods, renaming methods for better readability, and the addition of missing unit tests.&lt;br /&gt;
&lt;br /&gt;
Project Requirements:&lt;br /&gt;
&lt;br /&gt;
# Code Climate&amp;lt;ref name=&amp;quot;Code Climate&amp;quot;&amp;gt;https://codeclimate.com&amp;lt;/ref&amp;gt; shows import method is complex, because of lots of checks. This method can be fixed by adding private methods for raising import error.&lt;br /&gt;
# Get_assessments_round_for method can be renamed to get_team_responses_for_round. Team_id private variable is not needed.&lt;br /&gt;
# metareview_response_maps rename, refactoring can be done. No need to do second iteration.&lt;br /&gt;
# write missing unit tests for existing methods.&lt;br /&gt;
&lt;br /&gt;
= Design Patterns =&lt;br /&gt;
&lt;br /&gt;
As part of our project, we refactored the model to follow the Single Responsibility and Don't Repeat Yourself (DRY) Principles.  Both of the principles focus on reducing code repetition and increasing the cohesion of the individual methods in the class.  The Single Responsibility Principle states that each class and method should have sole responsibility over one single part of the functionality of the system&amp;lt;ref&amp;gt;https://en.wikipedia.org/wiki/Single_responsibility_principle&amp;lt;/ref&amp;gt;.  The DRY principle states that whenever the same types of logic and functionality are being performed in a class the duplicated logic should be extracted into a new method that can be called in place of the repeated lines of code &amp;lt;ref&amp;gt;https://en.wikipedia.org/wiki/Don%27t_repeat_yourself&amp;lt;/ref&amp;gt;.  A prime example of a method that initially violated these principles was the import method, which in addition to performing the core import processes also performed a number of checks that would be more properly extracted into private methods.&lt;br /&gt;
&lt;br /&gt;
=Code Changes =&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Refactoring of import method ===&lt;br /&gt;
&lt;br /&gt;
	CodeClimate reports showed the import method to be overly complex, with a number of checks being included within the import method itself.  The resolution for this problem was to refactor the import method, creating private methods to perform the null checks and throw import errors.&lt;br /&gt;
&lt;br /&gt;
Prior to refactoring, all null checks were performed in line:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;big&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 def self.import(row, session, id)&lt;br /&gt;
    if row.length &amp;lt; 2&lt;br /&gt;
      raise ArgumentError, &amp;quot;Not enough items&amp;quot;&lt;br /&gt;
    end&lt;br /&gt;
    assignment = Assignment.find(id)&lt;br /&gt;
    if assignment.nil?&lt;br /&gt;
      raise ImportError, &amp;quot;The assignment with id \&amp;quot;#{id}\&amp;quot; was not found. &amp;lt;a href='/assignment/new'&amp;gt;Create&amp;lt;/a&amp;gt; this assignment?&amp;quot;&lt;br /&gt;
    end&lt;br /&gt;
    index = 1&lt;br /&gt;
    while index &amp;lt; row.length&lt;br /&gt;
      user = User.find_by_name(row[index].to_s.strip)&lt;br /&gt;
      if user.nil?&lt;br /&gt;
        raise ImportError, &amp;quot;The user account for the reviewer \&amp;quot;#{row[index]}\&amp;quot; was not found. &amp;lt;a href='/users/new'&amp;gt;Create&amp;lt;/a&amp;gt; this user?&amp;quot;&lt;br /&gt;
      end&lt;br /&gt;
      reviewer = AssignmentParticipant.where(user_id: user.id, parent_id:  assignment.id).first&lt;br /&gt;
      if reviewer == nil&lt;br /&gt;
        raise ImportError, &amp;quot;The reviewer \&amp;quot;#{row[index]}\&amp;quot; is not a participant in this assignment. &amp;lt;a href='/users/new'&amp;gt;Register&amp;lt;/a&amp;gt; this user as a participant?&amp;quot;&lt;br /&gt;
      end&lt;br /&gt;
      if assignment.team_assignment&lt;br /&gt;
        reviewee = AssignmentTeam.where(name: row[0].to_s.strip, parent_id:  assignment.id).first&lt;br /&gt;
        if reviewee == nil&lt;br /&gt;
          raise ImportError, &amp;quot;The author \&amp;quot;#{row[0].to_s.strip}\&amp;quot; was not found. &amp;lt;a href='/users/new'&amp;gt;Create&amp;lt;/a&amp;gt; this user?&amp;quot;&lt;br /&gt;
        end&lt;br /&gt;
        existing = ReviewResponseMap.where(reviewee_id: reviewee.id, reviewer_id:  reviewer.id).first&lt;br /&gt;
        if existing.nil?&lt;br /&gt;
          ReviewResponseMap.create(:reviewer_id =&amp;gt; reviewer.id, :reviewee_id =&amp;gt; reviewee.id, :reviewed_object_id =&amp;gt; assignment.id)&lt;br /&gt;
        end&lt;br /&gt;
      else&lt;br /&gt;
        puser = User.find_by_name(row[0].to_s.strip)&lt;br /&gt;
        if user == nil&lt;br /&gt;
          raise ImportError, &amp;quot;The user account for the reviewee \&amp;quot;#{row[0]}\&amp;quot; was not found. &amp;lt;a href='/users/new'&amp;gt;Create&amp;lt;/a&amp;gt; this user?&amp;quot;&lt;br /&gt;
        end&lt;br /&gt;
        reviewee = AssignmentParticipant.where(user_id: puser.id, parent_id:  assignment.id).first&lt;br /&gt;
        if reviewee == nil&lt;br /&gt;
          raise ImportError, &amp;quot;The author \&amp;quot;#{row[0].to_s.strip}\&amp;quot; was not found. &amp;lt;a href='/users/new'&amp;gt;Create&amp;lt;/a&amp;gt; this user?&amp;quot;&lt;br /&gt;
        end&lt;br /&gt;
        team_id = TeamsUser.team_id(reviewee.parent_id, reviewee.user_id)&lt;br /&gt;
        existing = ReviewResponseMap.where(reviewee_id: team_id, reviewer_id:  reviewer.id).first&lt;br /&gt;
        if existing.nil?&lt;br /&gt;
          ReviewResponseMap.create(:reviewee_id =&amp;gt; team_id, :reviewer_id =&amp;gt; reviewer.id, :reviewed_object_id =&amp;gt; assignment.id)&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
      index += 1&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
&lt;br /&gt;
After refactoring the import method adheres to the single responsibility principle, performing only key import tasks while making calls to private methods for any necessary validation. The size of the import method was reduced by doing this and counts for better readability of the code. Also, this method is a very important one and care was taken so that it wouldn't break any existing functionality. Changes were reflected in CodeClimate (link expired as it was a trial version).&lt;br /&gt;
 &lt;br /&gt;
  &amp;lt;big&amp;gt;&amp;lt;nowiki&amp;gt;#Imports new reponse maps if they do not already exist&lt;br /&gt;
  def self.import(row, _session, id)&lt;br /&gt;
      if row.length &amp;lt; 2&lt;br /&gt;
          raise ArgumentError, 'Not enough items'&lt;br /&gt;
      end&lt;br /&gt;
      assignment = find_assignment(id)&lt;br /&gt;
      index = 1&lt;br /&gt;
      reviewee_name = row[0]&lt;br /&gt;
      while index &amp;lt; row.length&lt;br /&gt;
          reviewee_id = nil&lt;br /&gt;
          reviewer_name = row[index]&lt;br /&gt;
          reviewer = get_assignment_participant(reviewer_name,  assignment.id, &amp;quot;reviewer&amp;quot;)&lt;br /&gt;
          participant_nil?(reviewer, reviewer_name , &amp;quot;reviewer&amp;quot;)&lt;br /&gt;
         &lt;br /&gt;
         #Find reviewee if assignment is a team assignment&lt;br /&gt;
         if assignment.team_assignment&lt;br /&gt;
             reviewee = AssignmentTeam.where(name: reviewee_name .to_s.strip, parent_id: assignment.id).first&lt;br /&gt;
             participant_nil?(reviewee, reviewee_name, &amp;quot;author&amp;quot;)&lt;br /&gt;
             reviewee_id = reviewee.id&lt;br /&gt;
         #Find reviewee if assignment is not a team assignment&lt;br /&gt;
         else&lt;br /&gt;
	     reviewee = get_assignment_participant(reviewee_name, assignment.id, &amp;quot;reviewee&amp;quot;)&lt;br /&gt;
             participant_nil?(reviewee, reviewee_name, &amp;quot;author&amp;quot;)&lt;br /&gt;
             reviewee_id  = TeamsUser.team_id(reviewee.parent_id, reviewee.user_id)&lt;br /&gt;
         end&lt;br /&gt;
         create_response_map(reviewer, reviewee_id,  assignment)&lt;br /&gt;
         index += 1&lt;br /&gt;
      end&lt;br /&gt;
  end&amp;lt;/nowiki&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Private methods added:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;big&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  # Check for if assignment value is null&lt;br /&gt;
  def self.find_assignment(id)&lt;br /&gt;
      begin&lt;br /&gt;
          assignment = Assignment.find(id)&lt;br /&gt;
      rescue ActiveRecord::RecordNotFound&lt;br /&gt;
          raise ImportError, &amp;quot;The assignment with id \&amp;quot;#{id}\&amp;quot; was not found.&amp;lt;a href='/assignment/new'&amp;gt;Create&amp;lt;/a&amp;gt; this assignment?&amp;quot;&lt;br /&gt;
      end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  # Check for if participant is null&lt;br /&gt;
  def self.participant_nil?(participant, user_name, participant_type) &lt;br /&gt;
      error_message = nil&lt;br /&gt;
      if participant_type == &amp;quot;author&amp;quot;&lt;br /&gt;
          error_message = &amp;quot;The author \&amp;quot;#{user_name.to_s.strip}\&amp;quot; was not found.&amp;lt;a href='/users/new'&amp;gt;Create&amp;lt;/a&amp;gt; this user?&amp;quot;&lt;br /&gt;
      else&lt;br /&gt;
          error_message =  &amp;quot;The reviewer \&amp;quot;#{user_name}\&amp;quot; is not a participant in this assignment.&amp;lt;a href='/users/new'&amp;gt;Register&amp;lt;/a&amp;gt; this user as a participant?&amp;quot;&lt;br /&gt;
      end&lt;br /&gt;
      check_nil?(participant, error_message)&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  # Check for if user is null&lt;br /&gt;
  def self.user_nil?(user, user_name, user_type)&lt;br /&gt;
      check_nil?( user, &amp;quot;The user account for the \&amp;quot;#{user_type}\&amp;quot; \&amp;quot;#{user_name}\&amp;quot; was not found.&amp;lt;a href='/users/new'&amp;gt;Create&amp;lt;/a&amp;gt; this user?&amp;quot;)&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
 #Throws import error for nil objects&lt;br /&gt;
  def self.check_nil?(object, error_message)&lt;br /&gt;
      if object.nil?&lt;br /&gt;
          raise ImportError, error_message&lt;br /&gt;
      end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Refactoring of get_assessments_round_for method ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The get_assessments_round_for method’s name failed to provide a clear idea of the method’s purpose and functionality. Additionally, there was a private variable, team_id, introduced in the method that was unnecessary and could be replaced by using the id property of the team parameter directly.  &lt;br /&gt;
&amp;lt;big&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  def self.get_assessments_round_for(team,round)&lt;br /&gt;
    team_id =team.id&lt;br /&gt;
    responses = Array.new&lt;br /&gt;
    if team_id&lt;br /&gt;
      maps = ResponseMap.where(:reviewee_id =&amp;gt; team_id, :type =&amp;gt; &amp;quot;ReviewResponseMap&amp;quot;)&lt;br /&gt;
      maps.each{ |map|&lt;br /&gt;
        if !map.response.empty? &amp;amp;&amp;amp; !map.response.reject{|r| r.round!=round}.empty?&lt;br /&gt;
          responses &amp;lt;&amp;lt; map.response.reject{|r| r.round!=round}.last&lt;br /&gt;
        end&lt;br /&gt;
      }&lt;br /&gt;
      responses.sort! {|a,b| a.map.reviewer.fullname &amp;lt;=&amp;gt; b.map.reviewer.fullname }&lt;br /&gt;
    end&lt;br /&gt;
    return responses&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Following the refactoring, the name of the method provides a clearer idea of its purpose:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;big&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  def self.get_team_responses_for_round(team, round)&lt;br /&gt;
    responses = []&lt;br /&gt;
    if team.id&lt;br /&gt;
      maps = ResponseMap.where(reviewee_id: team.id, type: 'ReviewResponseMap')&lt;br /&gt;
      maps.each do |map|&lt;br /&gt;
        unless map.response.empty? &amp;amp;&amp;amp; map.response.reject { |r| r.round != round }.empty?&lt;br /&gt;
          responses &amp;lt;&amp;lt; map.response.reject { |r| r.round != round }.last&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
      responses.sort! { |a, b| a.map.reviewer.fullname &amp;lt;=&amp;gt; b.map.reviewer.fullname }&lt;br /&gt;
    end&lt;br /&gt;
    responses&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
The change in method name also required changes to the following files that referenced it:&lt;br /&gt;
&lt;br /&gt;
/app/models/assignment.rb:436:    &lt;br /&gt;
 &lt;br /&gt;
&amp;lt;big&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  assessments = ReviewResponseMap.get_assessments_round_for(team,i)&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt; &lt;br /&gt;
&lt;br /&gt;
./app/models/assignment_participant.rb:268:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;big&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 scores[questionnaire_symbol][:assessments] = questionnaire.get_assessments_round_for(self,round)&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Refactoring of metareview_response_maps method ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The metareview_response_maps method was unnecessarily complex, introducing unneeded private variables and removing additional loop. &lt;br /&gt;
Here, the ''metareview_response_maps'' variable is a collection that doesn't need to be looped (in fact the metareviews are being overwritten each iteration of the loop and not appended to the collection). And we're returning the last value of the collection. The rest of them are just lost. We've removed the redundant iteration so that it just maps to metareviews once and returns the collection at the end of the iteration. The private variable removed is: ''metareview_list'' .&lt;br /&gt;
&lt;br /&gt;
&amp;lt;big&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 def metareview_response_maps&lt;br /&gt;
    responses = Response.where(map_id:self.id)&lt;br /&gt;
    metareview_list=Array.new()&lt;br /&gt;
    responses.each do |response|&lt;br /&gt;
      metareview_response_maps = MetareviewResponseMap.where(reviewed_object_id:response.id)&lt;br /&gt;
      metareview_response_maps.each do |metareview_response_map|&lt;br /&gt;
        metareview_list&amp;lt;&amp;lt;metareview_response_map&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
    metareview_list&lt;br /&gt;
 end&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
After refactoring:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;big&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  def get_metareview_response_maps&lt;br /&gt;
    responses = Response.where(map_id: id)&lt;br /&gt;
    metareview_response_maps = []&lt;br /&gt;
    responses.each do |response|&lt;br /&gt;
      metareview_response_maps &amp;lt;&amp;lt; MetareviewResponseMap.where(reviewed_object_id: response.id)&lt;br /&gt;
    end&lt;br /&gt;
    metareview_response_maps&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Addition of code comments ===&lt;br /&gt;
&lt;br /&gt;
We added comments to all of the methods in the ReviewResponseMap.rb file and corrected instances where CodeClimate Identified opportunities for code improvement.  One issue flagged by CodeClimate that we did not change was to use the find_by method instead of where().first method.  The where().first method occurs in the import, get_assignment_participant, and create_response_map methods. It is not always appropriate to use the find_by method, as documented in this github post: https://github.com/bbatsov/rubocop/issues/1938 .  In instances where ordering by id is the desired behavior, where().first will order by default, but in Rails 4+ find_by does not honor that default behavior.  For this reason we left the instances of where().first unchanged.&lt;br /&gt;
&lt;br /&gt;
=== Code Improvements ===&lt;br /&gt;
&lt;br /&gt;
This refactoring was to improve readability and follow as many good ''Rubyist'' coding practices as possible without breaking the functionality of existing code. We used CodeClimate of the master branch code as a reference. We took the suggestions we got from CodeClimate and improved our code based on that.&lt;br /&gt;
We also made some of the methods shorter by removing redundant functionality and adding private methods to methods with a lot of functions. We also added private methods in places where we saw repeated patterns to make the code ''DRYer''.&lt;br /&gt;
At the end of our refactoring, we managed to improve the rating on CodeClimate from a '''C''' to a '''B''' . Further improvements meant reducing the size of the entire class which required a much more significant refactoring in multiple files and folders. We focussed on refactoring the existing mode, '''ReviewResponseMap'''.&lt;br /&gt;
&lt;br /&gt;
= Unit Tests =&lt;br /&gt;
&lt;br /&gt;
=== Refactoring of Unit Tests===&lt;br /&gt;
&lt;br /&gt;
The previous unit tests had syntactical and run time errors.  We were not able to get the previous unit tests to run without errors.  Because of this we rewrote the unit tests for the &amp;lt;b&amp;gt;ReviewResponseModel&amp;lt;/b&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
We added a test_helper file to the main test folder that requires a needed configuration file and needed gems.  We also added 8 fixtures that were needed for data to run the unit tests.  The following fixture files were added:&lt;br /&gt;
&lt;br /&gt;
* assignment_questionnaires.yml&lt;br /&gt;
* assignments.yml&lt;br /&gt;
* participants.yml&lt;br /&gt;
* questionnaires.yml&lt;br /&gt;
* response_maps.yml&lt;br /&gt;
* responses.yml&lt;br /&gt;
* teams.yml&lt;br /&gt;
* users.yml&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
There is at least one unit test for every public method within the &amp;lt;b&amp;gt;ReviewResponseModel&amp;lt;/b&amp;gt;.  The test naming convention used is &amp;quot;method_&amp;lt;name of method that is being tested&amp;gt;&amp;quot;.  For example, the unit test for the export method is &amp;quot;method_export&amp;quot;.  If there are multiple test for one method the name of the test will include the test case after the normal naming convention.  For example, one of the unit tests for the import method checks for an invalid assignment.  The name of this method is &amp;quot;method_import_invalid_assignment&amp;quot;.  The following are the unit tests we created:&lt;br /&gt;
&lt;br /&gt;
* method_export&lt;br /&gt;
* method_get_metareview_response_maps&lt;br /&gt;
* method_get_team_response_for_round&lt;br /&gt;
* method_final_versions_from_reviewer&lt;br /&gt;
* method_import&lt;br /&gt;
* method_import_invalid_reviewee&lt;br /&gt;
* method_import_invalid_reviewer&lt;br /&gt;
* method_import_invalid_assignment&lt;br /&gt;
* method_delete&lt;br /&gt;
* method_delete_no _force&lt;br /&gt;
* method_show_feedback&lt;br /&gt;
* method_get_title&lt;br /&gt;
* method_export_fields&lt;br /&gt;
* method_questionnaire&lt;br /&gt;
* method_add_reviewer&lt;br /&gt;
&lt;br /&gt;
=== How to Run Unit Tests ===&lt;br /&gt;
To run the unit tests, follow these steps:&lt;br /&gt;
&lt;br /&gt;
# Download the master branch of the repo.&lt;br /&gt;
# Setup the Databases for the test environment (we have used Zhewei's scrubbed expertiza DB )&lt;br /&gt;
#* Run the &amp;quot; rake db:create RAILS_ENV=test &amp;quot; command&lt;br /&gt;
#* Run the &amp;quot; rake db:reset RAILS_ENV=test &amp;quot; command&lt;br /&gt;
#* Scrub the DB using &amp;quot; mysql -u root expertiza_development &amp;lt; expertiza-scrubbed.sql&amp;quot;&lt;br /&gt;
#* Run the &amp;quot; rake db:migrate &amp;quot;&lt;br /&gt;
# Run &amp;quot; rake test test/unit/review_response_map_test.rb &amp;quot; in the &amp;quot;expertiza/&amp;quot; directory.&lt;br /&gt;
#* If you run into a mysql log in error go into config/database.yml and edit the mysql credentials for the test section so that it matches the local environment's mysql configuration&lt;br /&gt;
# Check if tests passed or failed.&lt;br /&gt;
&lt;br /&gt;
= Manual Test Case =&lt;br /&gt;
&lt;br /&gt;
In order to test the changes made to the ReviewResponseMap, bring up Expertiza and log in as an administrator.  Once logged in, proceed with the following steps:&lt;br /&gt;
&lt;br /&gt;
# Go to '''impersonate user''' when logged in as ''instructor6'' and type in ''student559'' (or) just log in as ''student559''. All passwords are ''password'' .&lt;br /&gt;
# Pick any assignment to view.&lt;br /&gt;
# Navigate to '''Other's work'''.&lt;br /&gt;
# Check the different reviews and metareviews. Whether they are being displayed correctly or not.&lt;br /&gt;
# Go to Edit or Give feedback and submit a feedback.&lt;br /&gt;
# Go back and check if the feedback given is displayed correctly or not.&lt;br /&gt;
# Check if author's feedback is correct or not.&lt;br /&gt;
# Go to the '''Temp''' assignment and see if the page is being displayed correctly or not (since there is no assignment submission content or reviews for that).&lt;br /&gt;
&lt;br /&gt;
''NOTE: Since this was a refactoring of the code and methods, the existing functionality was supposed to remain the same and not break for the changes we've made.''&lt;br /&gt;
&lt;br /&gt;
= References =&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;references/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;3. [https://github.com/expertiza/expertiza Expertiza Main Repo] &amp;lt;br&amp;gt;&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;4. [https://github.com/adeeshag/expertiza/blob/develop/app/models/review_response_map.rb Refactored ReviewResponseMap.rb]&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;5. [https://github.com/adeeshag/expertiza/tree/develop/test/fixtures Test Fixtures]&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;6. [https://github.com/adeeshag/expertiza/blob/develop/test/unit/review_response_map_test.rb Unit Tests]&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;6. [http://152.46.16.195:5902/ Expertiza Deployed Site]&amp;lt;br&amp;gt;&lt;/div&gt;</summary>
		<author><name>Cnbrown4</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2015/ossE1558BGJ&amp;diff=98419</id>
		<title>CSC/ECE 517 Fall 2015/ossE1558BGJ</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2015/ossE1558BGJ&amp;diff=98419"/>
		<updated>2015-11-06T18:30:24Z</updated>

		<summary type="html">&lt;p&gt;Cnbrown4: /* Refactoring of Unit Tests */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Introduction =&lt;br /&gt;
&lt;br /&gt;
This page provides a description of the modifications and improvements made to the Expertiza project’s source code as part of an Expertiza based Open Source Software project.  Expertiza is a web based application which allows students to submit and peer-review classmates’ work, including written articles and development projects. The specific changes made during the course of this project were to the ReviewResponseMap.rb file, with additional changes made to other related files in support of refactoring ReviewResponseMap.rb.  &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
= Problem Statement =&lt;br /&gt;
&lt;br /&gt;
ReviewResponseMap is the model class used to manage the relationship between contributors, reviewers, and assignments.  The intent of the changes were to refactor the code for better readability and adherence to Ruby coding standards and best practices.  Primarily these changes involved the refactoring of overly complex methods, renaming methods for better readability, and the addition of missing unit tests.&lt;br /&gt;
&lt;br /&gt;
Project Requirements:&lt;br /&gt;
&lt;br /&gt;
# Code Climate&amp;lt;ref name=&amp;quot;Code Climate&amp;quot;&amp;gt;https://codeclimate.com&amp;lt;/ref&amp;gt; shows import method is complex, because of lots of checks. This method can be fixed by adding private methods for raising import error.&lt;br /&gt;
# Get_assessments_round_for method can be renamed to get_team_responses_for_round. Team_id private variable is not needed.&lt;br /&gt;
# metareview_response_maps rename, refactoring can be done. No need to do second iteration.&lt;br /&gt;
# write missing unit tests for existing methods.&lt;br /&gt;
&lt;br /&gt;
= Design Patterns =&lt;br /&gt;
&lt;br /&gt;
As part of our project, we refactored the model to follow the Single Responsibility and Don't Repeat Yourself (DRY) Principles.  Both of the principles focus on reducing code repetition and increasing the cohesion of the individual methods in the class.  The Single Responsibility Principle states that each class and method should have sole responsibility over one single part of the functionality of the system&amp;lt;ref&amp;gt;https://en.wikipedia.org/wiki/Single_responsibility_principle&amp;lt;/ref&amp;gt;.  The DRY principle states that whenever the same types of logic and functionality are being performed in a class the duplicated logic should be extracted into a new method that can be called in place of the repeated lines of code &amp;lt;ref&amp;gt;https://en.wikipedia.org/wiki/Don%27t_repeat_yourself&amp;lt;/ref&amp;gt;.  A prime example of a method that initially violated these principles was the import method, which in addition to performing the core import processes also performed a number of checks that would be more properly extracted into private methods.&lt;br /&gt;
&lt;br /&gt;
=Code Changes =&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Refactoring of import method ===&lt;br /&gt;
&lt;br /&gt;
	CodeClimate reports showed the import method to be overly complex, with a number of checks being included within the import method itself.  The resolution for this problem was to refactor the import method, creating private methods to perform the null checks and throw import errors.&lt;br /&gt;
&lt;br /&gt;
Prior to refactoring, all null checks were performed in line:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;big&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 def self.import(row, session, id)&lt;br /&gt;
    if row.length &amp;lt; 2&lt;br /&gt;
      raise ArgumentError, &amp;quot;Not enough items&amp;quot;&lt;br /&gt;
    end&lt;br /&gt;
    assignment = Assignment.find(id)&lt;br /&gt;
    if assignment.nil?&lt;br /&gt;
      raise ImportError, &amp;quot;The assignment with id \&amp;quot;#{id}\&amp;quot; was not found. &amp;lt;a href='/assignment/new'&amp;gt;Create&amp;lt;/a&amp;gt; this assignment?&amp;quot;&lt;br /&gt;
    end&lt;br /&gt;
    index = 1&lt;br /&gt;
    while index &amp;lt; row.length&lt;br /&gt;
      user = User.find_by_name(row[index].to_s.strip)&lt;br /&gt;
      if user.nil?&lt;br /&gt;
        raise ImportError, &amp;quot;The user account for the reviewer \&amp;quot;#{row[index]}\&amp;quot; was not found. &amp;lt;a href='/users/new'&amp;gt;Create&amp;lt;/a&amp;gt; this user?&amp;quot;&lt;br /&gt;
      end&lt;br /&gt;
      reviewer = AssignmentParticipant.where(user_id: user.id, parent_id:  assignment.id).first&lt;br /&gt;
      if reviewer == nil&lt;br /&gt;
        raise ImportError, &amp;quot;The reviewer \&amp;quot;#{row[index]}\&amp;quot; is not a participant in this assignment. &amp;lt;a href='/users/new'&amp;gt;Register&amp;lt;/a&amp;gt; this user as a participant?&amp;quot;&lt;br /&gt;
      end&lt;br /&gt;
      if assignment.team_assignment&lt;br /&gt;
        reviewee = AssignmentTeam.where(name: row[0].to_s.strip, parent_id:  assignment.id).first&lt;br /&gt;
        if reviewee == nil&lt;br /&gt;
          raise ImportError, &amp;quot;The author \&amp;quot;#{row[0].to_s.strip}\&amp;quot; was not found. &amp;lt;a href='/users/new'&amp;gt;Create&amp;lt;/a&amp;gt; this user?&amp;quot;&lt;br /&gt;
        end&lt;br /&gt;
        existing = ReviewResponseMap.where(reviewee_id: reviewee.id, reviewer_id:  reviewer.id).first&lt;br /&gt;
        if existing.nil?&lt;br /&gt;
          ReviewResponseMap.create(:reviewer_id =&amp;gt; reviewer.id, :reviewee_id =&amp;gt; reviewee.id, :reviewed_object_id =&amp;gt; assignment.id)&lt;br /&gt;
        end&lt;br /&gt;
      else&lt;br /&gt;
        puser = User.find_by_name(row[0].to_s.strip)&lt;br /&gt;
        if user == nil&lt;br /&gt;
          raise ImportError, &amp;quot;The user account for the reviewee \&amp;quot;#{row[0]}\&amp;quot; was not found. &amp;lt;a href='/users/new'&amp;gt;Create&amp;lt;/a&amp;gt; this user?&amp;quot;&lt;br /&gt;
        end&lt;br /&gt;
        reviewee = AssignmentParticipant.where(user_id: puser.id, parent_id:  assignment.id).first&lt;br /&gt;
        if reviewee == nil&lt;br /&gt;
          raise ImportError, &amp;quot;The author \&amp;quot;#{row[0].to_s.strip}\&amp;quot; was not found. &amp;lt;a href='/users/new'&amp;gt;Create&amp;lt;/a&amp;gt; this user?&amp;quot;&lt;br /&gt;
        end&lt;br /&gt;
        team_id = TeamsUser.team_id(reviewee.parent_id, reviewee.user_id)&lt;br /&gt;
        existing = ReviewResponseMap.where(reviewee_id: team_id, reviewer_id:  reviewer.id).first&lt;br /&gt;
        if existing.nil?&lt;br /&gt;
          ReviewResponseMap.create(:reviewee_id =&amp;gt; team_id, :reviewer_id =&amp;gt; reviewer.id, :reviewed_object_id =&amp;gt; assignment.id)&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
      index += 1&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
&lt;br /&gt;
After refactoring the import method adheres to the single responsibility principle, performing only key import tasks while making calls to private methods for any necessary validation. The size of the import method was reduced by doing this and counts for better readability of the code. Also, this method is a very important one and care was taken so that it wouldn't break any existing functionality. Changes were reflected in CodeClimate (link expired as it was a trial version).&lt;br /&gt;
 &lt;br /&gt;
  &amp;lt;big&amp;gt;&amp;lt;nowiki&amp;gt;#Imports new reponse maps if they do not already exist&lt;br /&gt;
  def self.import(row, _session, id)&lt;br /&gt;
      if row.length &amp;lt; 2&lt;br /&gt;
          raise ArgumentError, 'Not enough items'&lt;br /&gt;
      end&lt;br /&gt;
      assignment = find_assignment(id)&lt;br /&gt;
      index = 1&lt;br /&gt;
      reviewee_name = row[0]&lt;br /&gt;
      while index &amp;lt; row.length&lt;br /&gt;
          reviewee_id = nil&lt;br /&gt;
          reviewer_name = row[index]&lt;br /&gt;
          reviewer = get_assignment_participant(reviewer_name,  assignment.id, &amp;quot;reviewer&amp;quot;)&lt;br /&gt;
          participant_nil?(reviewer, reviewer_name , &amp;quot;reviewer&amp;quot;)&lt;br /&gt;
         &lt;br /&gt;
         #Find reviewee if assignment is a team assignment&lt;br /&gt;
         if assignment.team_assignment&lt;br /&gt;
             reviewee = AssignmentTeam.where(name: reviewee_name .to_s.strip, parent_id: assignment.id).first&lt;br /&gt;
             participant_nil?(reviewee, reviewee_name, &amp;quot;author&amp;quot;)&lt;br /&gt;
             reviewee_id = reviewee.id&lt;br /&gt;
         #Find reviewee if assignment is not a team assignment&lt;br /&gt;
         else&lt;br /&gt;
	     reviewee = get_assignment_participant(reviewee_name, assignment.id, &amp;quot;reviewee&amp;quot;)&lt;br /&gt;
             participant_nil?(reviewee, reviewee_name, &amp;quot;author&amp;quot;)&lt;br /&gt;
             reviewee_id  = TeamsUser.team_id(reviewee.parent_id, reviewee.user_id)&lt;br /&gt;
         end&lt;br /&gt;
         create_response_map(reviewer, reviewee_id,  assignment)&lt;br /&gt;
         index += 1&lt;br /&gt;
      end&lt;br /&gt;
  end&amp;lt;/nowiki&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Private methods added:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;big&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  # Check for if assignment value is null&lt;br /&gt;
  def self.find_assignment(id)&lt;br /&gt;
      begin&lt;br /&gt;
          assignment = Assignment.find(id)&lt;br /&gt;
      rescue ActiveRecord::RecordNotFound&lt;br /&gt;
          raise ImportError, &amp;quot;The assignment with id \&amp;quot;#{id}\&amp;quot; was not found.&amp;lt;a href='/assignment/new'&amp;gt;Create&amp;lt;/a&amp;gt; this assignment?&amp;quot;&lt;br /&gt;
      end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  # Check for if participant is null&lt;br /&gt;
  def self.participant_nil?(participant, user_name, participant_type) &lt;br /&gt;
      error_message = nil&lt;br /&gt;
      if participant_type == &amp;quot;author&amp;quot;&lt;br /&gt;
          error_message = &amp;quot;The author \&amp;quot;#{user_name.to_s.strip}\&amp;quot; was not found.&amp;lt;a href='/users/new'&amp;gt;Create&amp;lt;/a&amp;gt; this user?&amp;quot;&lt;br /&gt;
      else&lt;br /&gt;
          error_message =  &amp;quot;The reviewer \&amp;quot;#{user_name}\&amp;quot; is not a participant in this assignment.&amp;lt;a href='/users/new'&amp;gt;Register&amp;lt;/a&amp;gt; this user as a participant?&amp;quot;&lt;br /&gt;
      end&lt;br /&gt;
      check_nil?(participant, error_message)&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  # Check for if user is null&lt;br /&gt;
  def self.user_nil?(user, user_name, user_type)&lt;br /&gt;
      check_nil?( user, &amp;quot;The user account for the \&amp;quot;#{user_type}\&amp;quot; \&amp;quot;#{user_name}\&amp;quot; was not found.&amp;lt;a href='/users/new'&amp;gt;Create&amp;lt;/a&amp;gt; this user?&amp;quot;)&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
 #Throws import error for nil objects&lt;br /&gt;
  def self.check_nil?(object, error_message)&lt;br /&gt;
      if object.nil?&lt;br /&gt;
          raise ImportError, error_message&lt;br /&gt;
      end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Refactoring of get_assessments_round_for method ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The get_assessments_round_for method’s name failed to provide a clear idea of the method’s purpose and functionality. Additionally, there was a private variable, team_id, introduced in the method that was unnecessary and could be replaced by using the id property of the team parameter directly.  &lt;br /&gt;
&amp;lt;big&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  def self.get_assessments_round_for(team,round)&lt;br /&gt;
    team_id =team.id&lt;br /&gt;
    responses = Array.new&lt;br /&gt;
    if team_id&lt;br /&gt;
      maps = ResponseMap.where(:reviewee_id =&amp;gt; team_id, :type =&amp;gt; &amp;quot;ReviewResponseMap&amp;quot;)&lt;br /&gt;
      maps.each{ |map|&lt;br /&gt;
        if !map.response.empty? &amp;amp;&amp;amp; !map.response.reject{|r| r.round!=round}.empty?&lt;br /&gt;
          responses &amp;lt;&amp;lt; map.response.reject{|r| r.round!=round}.last&lt;br /&gt;
        end&lt;br /&gt;
      }&lt;br /&gt;
      responses.sort! {|a,b| a.map.reviewer.fullname &amp;lt;=&amp;gt; b.map.reviewer.fullname }&lt;br /&gt;
    end&lt;br /&gt;
    return responses&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Following the refactoring, the name of the method provides a clearer idea of its purpose:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;big&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  def self.get_team_responses_for_round(team, round)&lt;br /&gt;
    responses = []&lt;br /&gt;
    if team.id&lt;br /&gt;
      maps = ResponseMap.where(reviewee_id: team.id, type: 'ReviewResponseMap')&lt;br /&gt;
      maps.each do |map|&lt;br /&gt;
        unless map.response.empty? &amp;amp;&amp;amp; map.response.reject { |r| r.round != round }.empty?&lt;br /&gt;
          responses &amp;lt;&amp;lt; map.response.reject { |r| r.round != round }.last&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
      responses.sort! { |a, b| a.map.reviewer.fullname &amp;lt;=&amp;gt; b.map.reviewer.fullname }&lt;br /&gt;
    end&lt;br /&gt;
    responses&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
The change in method name also required changes to the following files that referenced it:&lt;br /&gt;
&lt;br /&gt;
/app/models/assignment.rb:436:    &lt;br /&gt;
 &lt;br /&gt;
&amp;lt;big&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  assessments = ReviewResponseMap.get_assessments_round_for(team,i)&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt; &lt;br /&gt;
&lt;br /&gt;
./app/models/assignment_participant.rb:268:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;big&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 scores[questionnaire_symbol][:assessments] = questionnaire.get_assessments_round_for(self,round)&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Refactoring of metareview_response_maps method ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The metareview_response_maps method was unnecessarily complex, introducing unneeded private variables and removing additional loop. &lt;br /&gt;
Here, the ''metareview_response_maps'' variable is a collection that doesn't need to be looped (in fact the metareviews are being overwritten each iteration of the loop and not appended to the collection). And we're returning the last value of the collection. The rest of them are just lost. We've removed the redundant iteration so that it just maps to metareviews once and returns the collection at the end of the iteration. The private variable removed is: ''metareview_list'' .&lt;br /&gt;
&lt;br /&gt;
&amp;lt;big&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 def metareview_response_maps&lt;br /&gt;
    responses = Response.where(map_id:self.id)&lt;br /&gt;
    metareview_list=Array.new()&lt;br /&gt;
    responses.each do |response|&lt;br /&gt;
      metareview_response_maps = MetareviewResponseMap.where(reviewed_object_id:response.id)&lt;br /&gt;
      metareview_response_maps.each do |metareview_response_map|&lt;br /&gt;
        metareview_list&amp;lt;&amp;lt;metareview_response_map&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
    metareview_list&lt;br /&gt;
 end&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
After refactoring:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;big&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  def get_metareview_response_maps&lt;br /&gt;
    responses = Response.where(map_id: id)&lt;br /&gt;
    metareview_response_maps = []&lt;br /&gt;
    responses.each do |response|&lt;br /&gt;
      metareview_response_maps &amp;lt;&amp;lt; MetareviewResponseMap.where(reviewed_object_id: response.id)&lt;br /&gt;
    end&lt;br /&gt;
    metareview_response_maps&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Addition of code comments ===&lt;br /&gt;
&lt;br /&gt;
We added comments to all of the methods in the ReviewResponseMap.rb file and corrected instances where CodeClimate Identified opportunities for code improvement.  One issue flagged by CodeClimate that we did not change was to use the find_by method instead of where().first method.  The where().first method occurs in the import, get_assignment_participant, and create_response_map methods. It is not always appropriate to use the find_by method, as documented in this github post: https://github.com/bbatsov/rubocop/issues/1938 .  In instances where ordering by id is the desired behavior, where().first will order by default, but in Rails 4+ find_by does not honor that default behavior.  For this reason we left the instances of where().first unchanged.&lt;br /&gt;
&lt;br /&gt;
=== Code Improvements ===&lt;br /&gt;
&lt;br /&gt;
This refactoring was to improve readability and follow as many good ''Rubyist'' coding practices as possible without breaking the functionality of existing code. We used CodeClimate of the master branch code as a reference. We took the suggestions we got from CodeClimate and improved our code based on that.&lt;br /&gt;
We also made some of the methods shorter by removing redundant functionality and adding private methods to methods with a lot of functions. We also added private methods in places where we saw repeated patterns to make the code ''DRYer''.&lt;br /&gt;
At the end of our refactoring, we managed to improve the rating on CodeClimate from a '''C''' to a '''B''' . Further improvements meant reducing the size of the entire class which required a much more significant refactoring in multiple files and folders. We focussed on refactoring the existing mode, '''ReviewResponseMap'''.&lt;br /&gt;
&lt;br /&gt;
= Unit Tests =&lt;br /&gt;
&lt;br /&gt;
=== Refactoring of Unit Tests===&lt;br /&gt;
&lt;br /&gt;
The previous unit tests had syntactical and run time errors.  We were not able to get the previous unit tests to run without errors.  Because of this we rewrote the unit tests for the &amp;lt;b&amp;gt;ReviewResponseModel&amp;lt;/b&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
We added a test_helper file to the main test folder that requires a needed configuration file and needed gems.  We also added 8 fixtures that were needed for data to run the unit tests.  The following fixture files were added:&lt;br /&gt;
&lt;br /&gt;
* assignment_questionnaires.yml&lt;br /&gt;
* assignments.yml&lt;br /&gt;
* participants.yml&lt;br /&gt;
* questionnaires.yml&lt;br /&gt;
* response_maps.yml&lt;br /&gt;
* responses.yml&lt;br /&gt;
* teams.yml&lt;br /&gt;
* users.yml&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
There is at least one unit test for every public method within the &amp;lt;b&amp;gt;ReviewResponseModel&amp;lt;/b&amp;gt;.  The test naming convention used is &amp;quot;method_&amp;lt;name of method that is being tested&amp;gt;&amp;quot;.  For example, the unit test for the export method is &amp;quot;method_export&amp;quot;.  If there are multiple test for one method the name of the test will include the test case after the normal naming convention.  For example, one of the unit tests for the import method checks for an invalid assignment.  The name of this method is &amp;quot;method_import_invalid_assignment&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
=== How to Run Unit Tests ===&lt;br /&gt;
To run the unit tests, follow these steps:&lt;br /&gt;
&lt;br /&gt;
# Download the master branch of the repo.&lt;br /&gt;
# Setup the Databases for the test environment (we have used Zhewei's scrubbed expertiza DB )&lt;br /&gt;
#* Run the &amp;quot; rake db:create RAILS_ENV=test &amp;quot; command&lt;br /&gt;
#* Run the &amp;quot; rake db:reset RAILS_ENV=test &amp;quot; command&lt;br /&gt;
#* Scrub the DB using &amp;quot; mysql -u root expertiza_development &amp;lt; expertiza-scrubbed.sql&amp;quot;&lt;br /&gt;
#* Run the &amp;quot; rake db:migrate &amp;quot;&lt;br /&gt;
# Run &amp;quot; rake test test/unit/review_response_map_test.rb &amp;quot; in the &amp;quot;expertiza/&amp;quot; directory.&lt;br /&gt;
#* If you run into a mysql log in error go into config/database.yml and edit the mysql credentials for the test section so that it matches the local environment's mysql configuration&lt;br /&gt;
# Check if tests passed or failed.&lt;br /&gt;
&lt;br /&gt;
= Manual Test Case =&lt;br /&gt;
&lt;br /&gt;
In order to test the changes made to the ReviewResponseMap, bring up Expertiza and log in as an administrator.  Once logged in, proceed with the following steps:&lt;br /&gt;
&lt;br /&gt;
# Go to '''impersonate user''' when logged in as ''instructor6'' and type in ''student559'' (or) just log in as ''student559''. All passwords are ''password'' .&lt;br /&gt;
# Pick any assignment to view.&lt;br /&gt;
# Navigate to '''Other's work'''.&lt;br /&gt;
# Check the different reviews and metareviews. Whether they are being displayed correctly or not.&lt;br /&gt;
# Go to Edit or Give feedback and submit a feedback.&lt;br /&gt;
# Go back and check if the feedback given is displayed correctly or not.&lt;br /&gt;
# Check if author's feedback is correct or not.&lt;br /&gt;
# Go to the '''Temp''' assignment and see if the page is being displayed correctly or not (since there is no assignment submission content or reviews for that).&lt;br /&gt;
&lt;br /&gt;
''NOTE: Since this was a refactoring of the code and methods, the existing functionality was supposed to remain the same and not break for the changes we've made.''&lt;br /&gt;
&lt;br /&gt;
= References =&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;references/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;3. [https://github.com/expertiza/expertiza Expertiza Main Repo] &amp;lt;br&amp;gt;&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;4. [https://github.com/adeeshag/expertiza/blob/develop/app/models/review_response_map.rb Refactored ReviewResponseMap.rb]&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;5. [https://github.com/adeeshag/expertiza/tree/develop/test/fixtures Test Fixtures]&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;6. [https://github.com/adeeshag/expertiza/blob/develop/test/unit/review_response_map_test.rb Unit Tests]&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;6. [http://152.46.16.195:5902/ Expertiza Deployed Site]&amp;lt;br&amp;gt;&lt;/div&gt;</summary>
		<author><name>Cnbrown4</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2015/ossE1558BGJ&amp;diff=98418</id>
		<title>CSC/ECE 517 Fall 2015/ossE1558BGJ</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2015/ossE1558BGJ&amp;diff=98418"/>
		<updated>2015-11-06T18:29:30Z</updated>

		<summary type="html">&lt;p&gt;Cnbrown4: /* Refactoring of Unit Tests */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Introduction =&lt;br /&gt;
&lt;br /&gt;
This page provides a description of the modifications and improvements made to the Expertiza project’s source code as part of an Expertiza based Open Source Software project.  Expertiza is a web based application which allows students to submit and peer-review classmates’ work, including written articles and development projects. The specific changes made during the course of this project were to the ReviewResponseMap.rb file, with additional changes made to other related files in support of refactoring ReviewResponseMap.rb.  &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
= Problem Statement =&lt;br /&gt;
&lt;br /&gt;
ReviewResponseMap is the model class used to manage the relationship between contributors, reviewers, and assignments.  The intent of the changes were to refactor the code for better readability and adherence to Ruby coding standards and best practices.  Primarily these changes involved the refactoring of overly complex methods, renaming methods for better readability, and the addition of missing unit tests.&lt;br /&gt;
&lt;br /&gt;
Project Requirements:&lt;br /&gt;
&lt;br /&gt;
# Code Climate&amp;lt;ref name=&amp;quot;Code Climate&amp;quot;&amp;gt;https://codeclimate.com&amp;lt;/ref&amp;gt; shows import method is complex, because of lots of checks. This method can be fixed by adding private methods for raising import error.&lt;br /&gt;
# Get_assessments_round_for method can be renamed to get_team_responses_for_round. Team_id private variable is not needed.&lt;br /&gt;
# metareview_response_maps rename, refactoring can be done. No need to do second iteration.&lt;br /&gt;
# write missing unit tests for existing methods.&lt;br /&gt;
&lt;br /&gt;
= Design Patterns =&lt;br /&gt;
&lt;br /&gt;
As part of our project, we refactored the model to follow the Single Responsibility and Don't Repeat Yourself (DRY) Principles.  Both of the principles focus on reducing code repetition and increasing the cohesion of the individual methods in the class.  The Single Responsibility Principle states that each class and method should have sole responsibility over one single part of the functionality of the system&amp;lt;ref&amp;gt;https://en.wikipedia.org/wiki/Single_responsibility_principle&amp;lt;/ref&amp;gt;.  The DRY principle states that whenever the same types of logic and functionality are being performed in a class the duplicated logic should be extracted into a new method that can be called in place of the repeated lines of code &amp;lt;ref&amp;gt;https://en.wikipedia.org/wiki/Don%27t_repeat_yourself&amp;lt;/ref&amp;gt;.  A prime example of a method that initially violated these principles was the import method, which in addition to performing the core import processes also performed a number of checks that would be more properly extracted into private methods.&lt;br /&gt;
&lt;br /&gt;
=Code Changes =&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Refactoring of import method ===&lt;br /&gt;
&lt;br /&gt;
	CodeClimate reports showed the import method to be overly complex, with a number of checks being included within the import method itself.  The resolution for this problem was to refactor the import method, creating private methods to perform the null checks and throw import errors.&lt;br /&gt;
&lt;br /&gt;
Prior to refactoring, all null checks were performed in line:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;big&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 def self.import(row, session, id)&lt;br /&gt;
    if row.length &amp;lt; 2&lt;br /&gt;
      raise ArgumentError, &amp;quot;Not enough items&amp;quot;&lt;br /&gt;
    end&lt;br /&gt;
    assignment = Assignment.find(id)&lt;br /&gt;
    if assignment.nil?&lt;br /&gt;
      raise ImportError, &amp;quot;The assignment with id \&amp;quot;#{id}\&amp;quot; was not found. &amp;lt;a href='/assignment/new'&amp;gt;Create&amp;lt;/a&amp;gt; this assignment?&amp;quot;&lt;br /&gt;
    end&lt;br /&gt;
    index = 1&lt;br /&gt;
    while index &amp;lt; row.length&lt;br /&gt;
      user = User.find_by_name(row[index].to_s.strip)&lt;br /&gt;
      if user.nil?&lt;br /&gt;
        raise ImportError, &amp;quot;The user account for the reviewer \&amp;quot;#{row[index]}\&amp;quot; was not found. &amp;lt;a href='/users/new'&amp;gt;Create&amp;lt;/a&amp;gt; this user?&amp;quot;&lt;br /&gt;
      end&lt;br /&gt;
      reviewer = AssignmentParticipant.where(user_id: user.id, parent_id:  assignment.id).first&lt;br /&gt;
      if reviewer == nil&lt;br /&gt;
        raise ImportError, &amp;quot;The reviewer \&amp;quot;#{row[index]}\&amp;quot; is not a participant in this assignment. &amp;lt;a href='/users/new'&amp;gt;Register&amp;lt;/a&amp;gt; this user as a participant?&amp;quot;&lt;br /&gt;
      end&lt;br /&gt;
      if assignment.team_assignment&lt;br /&gt;
        reviewee = AssignmentTeam.where(name: row[0].to_s.strip, parent_id:  assignment.id).first&lt;br /&gt;
        if reviewee == nil&lt;br /&gt;
          raise ImportError, &amp;quot;The author \&amp;quot;#{row[0].to_s.strip}\&amp;quot; was not found. &amp;lt;a href='/users/new'&amp;gt;Create&amp;lt;/a&amp;gt; this user?&amp;quot;&lt;br /&gt;
        end&lt;br /&gt;
        existing = ReviewResponseMap.where(reviewee_id: reviewee.id, reviewer_id:  reviewer.id).first&lt;br /&gt;
        if existing.nil?&lt;br /&gt;
          ReviewResponseMap.create(:reviewer_id =&amp;gt; reviewer.id, :reviewee_id =&amp;gt; reviewee.id, :reviewed_object_id =&amp;gt; assignment.id)&lt;br /&gt;
        end&lt;br /&gt;
      else&lt;br /&gt;
        puser = User.find_by_name(row[0].to_s.strip)&lt;br /&gt;
        if user == nil&lt;br /&gt;
          raise ImportError, &amp;quot;The user account for the reviewee \&amp;quot;#{row[0]}\&amp;quot; was not found. &amp;lt;a href='/users/new'&amp;gt;Create&amp;lt;/a&amp;gt; this user?&amp;quot;&lt;br /&gt;
        end&lt;br /&gt;
        reviewee = AssignmentParticipant.where(user_id: puser.id, parent_id:  assignment.id).first&lt;br /&gt;
        if reviewee == nil&lt;br /&gt;
          raise ImportError, &amp;quot;The author \&amp;quot;#{row[0].to_s.strip}\&amp;quot; was not found. &amp;lt;a href='/users/new'&amp;gt;Create&amp;lt;/a&amp;gt; this user?&amp;quot;&lt;br /&gt;
        end&lt;br /&gt;
        team_id = TeamsUser.team_id(reviewee.parent_id, reviewee.user_id)&lt;br /&gt;
        existing = ReviewResponseMap.where(reviewee_id: team_id, reviewer_id:  reviewer.id).first&lt;br /&gt;
        if existing.nil?&lt;br /&gt;
          ReviewResponseMap.create(:reviewee_id =&amp;gt; team_id, :reviewer_id =&amp;gt; reviewer.id, :reviewed_object_id =&amp;gt; assignment.id)&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
      index += 1&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
&lt;br /&gt;
After refactoring the import method adheres to the single responsibility principle, performing only key import tasks while making calls to private methods for any necessary validation. The size of the import method was reduced by doing this and counts for better readability of the code. Also, this method is a very important one and care was taken so that it wouldn't break any existing functionality. Changes were reflected in CodeClimate (link expired as it was a trial version).&lt;br /&gt;
 &lt;br /&gt;
  &amp;lt;big&amp;gt;&amp;lt;nowiki&amp;gt;#Imports new reponse maps if they do not already exist&lt;br /&gt;
  def self.import(row, _session, id)&lt;br /&gt;
      if row.length &amp;lt; 2&lt;br /&gt;
          raise ArgumentError, 'Not enough items'&lt;br /&gt;
      end&lt;br /&gt;
      assignment = find_assignment(id)&lt;br /&gt;
      index = 1&lt;br /&gt;
      reviewee_name = row[0]&lt;br /&gt;
      while index &amp;lt; row.length&lt;br /&gt;
          reviewee_id = nil&lt;br /&gt;
          reviewer_name = row[index]&lt;br /&gt;
          reviewer = get_assignment_participant(reviewer_name,  assignment.id, &amp;quot;reviewer&amp;quot;)&lt;br /&gt;
          participant_nil?(reviewer, reviewer_name , &amp;quot;reviewer&amp;quot;)&lt;br /&gt;
         &lt;br /&gt;
         #Find reviewee if assignment is a team assignment&lt;br /&gt;
         if assignment.team_assignment&lt;br /&gt;
             reviewee = AssignmentTeam.where(name: reviewee_name .to_s.strip, parent_id: assignment.id).first&lt;br /&gt;
             participant_nil?(reviewee, reviewee_name, &amp;quot;author&amp;quot;)&lt;br /&gt;
             reviewee_id = reviewee.id&lt;br /&gt;
         #Find reviewee if assignment is not a team assignment&lt;br /&gt;
         else&lt;br /&gt;
	     reviewee = get_assignment_participant(reviewee_name, assignment.id, &amp;quot;reviewee&amp;quot;)&lt;br /&gt;
             participant_nil?(reviewee, reviewee_name, &amp;quot;author&amp;quot;)&lt;br /&gt;
             reviewee_id  = TeamsUser.team_id(reviewee.parent_id, reviewee.user_id)&lt;br /&gt;
         end&lt;br /&gt;
         create_response_map(reviewer, reviewee_id,  assignment)&lt;br /&gt;
         index += 1&lt;br /&gt;
      end&lt;br /&gt;
  end&amp;lt;/nowiki&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Private methods added:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;big&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  # Check for if assignment value is null&lt;br /&gt;
  def self.find_assignment(id)&lt;br /&gt;
      begin&lt;br /&gt;
          assignment = Assignment.find(id)&lt;br /&gt;
      rescue ActiveRecord::RecordNotFound&lt;br /&gt;
          raise ImportError, &amp;quot;The assignment with id \&amp;quot;#{id}\&amp;quot; was not found.&amp;lt;a href='/assignment/new'&amp;gt;Create&amp;lt;/a&amp;gt; this assignment?&amp;quot;&lt;br /&gt;
      end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  # Check for if participant is null&lt;br /&gt;
  def self.participant_nil?(participant, user_name, participant_type) &lt;br /&gt;
      error_message = nil&lt;br /&gt;
      if participant_type == &amp;quot;author&amp;quot;&lt;br /&gt;
          error_message = &amp;quot;The author \&amp;quot;#{user_name.to_s.strip}\&amp;quot; was not found.&amp;lt;a href='/users/new'&amp;gt;Create&amp;lt;/a&amp;gt; this user?&amp;quot;&lt;br /&gt;
      else&lt;br /&gt;
          error_message =  &amp;quot;The reviewer \&amp;quot;#{user_name}\&amp;quot; is not a participant in this assignment.&amp;lt;a href='/users/new'&amp;gt;Register&amp;lt;/a&amp;gt; this user as a participant?&amp;quot;&lt;br /&gt;
      end&lt;br /&gt;
      check_nil?(participant, error_message)&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  # Check for if user is null&lt;br /&gt;
  def self.user_nil?(user, user_name, user_type)&lt;br /&gt;
      check_nil?( user, &amp;quot;The user account for the \&amp;quot;#{user_type}\&amp;quot; \&amp;quot;#{user_name}\&amp;quot; was not found.&amp;lt;a href='/users/new'&amp;gt;Create&amp;lt;/a&amp;gt; this user?&amp;quot;)&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
 #Throws import error for nil objects&lt;br /&gt;
  def self.check_nil?(object, error_message)&lt;br /&gt;
      if object.nil?&lt;br /&gt;
          raise ImportError, error_message&lt;br /&gt;
      end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Refactoring of get_assessments_round_for method ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The get_assessments_round_for method’s name failed to provide a clear idea of the method’s purpose and functionality. Additionally, there was a private variable, team_id, introduced in the method that was unnecessary and could be replaced by using the id property of the team parameter directly.  &lt;br /&gt;
&amp;lt;big&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  def self.get_assessments_round_for(team,round)&lt;br /&gt;
    team_id =team.id&lt;br /&gt;
    responses = Array.new&lt;br /&gt;
    if team_id&lt;br /&gt;
      maps = ResponseMap.where(:reviewee_id =&amp;gt; team_id, :type =&amp;gt; &amp;quot;ReviewResponseMap&amp;quot;)&lt;br /&gt;
      maps.each{ |map|&lt;br /&gt;
        if !map.response.empty? &amp;amp;&amp;amp; !map.response.reject{|r| r.round!=round}.empty?&lt;br /&gt;
          responses &amp;lt;&amp;lt; map.response.reject{|r| r.round!=round}.last&lt;br /&gt;
        end&lt;br /&gt;
      }&lt;br /&gt;
      responses.sort! {|a,b| a.map.reviewer.fullname &amp;lt;=&amp;gt; b.map.reviewer.fullname }&lt;br /&gt;
    end&lt;br /&gt;
    return responses&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Following the refactoring, the name of the method provides a clearer idea of its purpose:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;big&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  def self.get_team_responses_for_round(team, round)&lt;br /&gt;
    responses = []&lt;br /&gt;
    if team.id&lt;br /&gt;
      maps = ResponseMap.where(reviewee_id: team.id, type: 'ReviewResponseMap')&lt;br /&gt;
      maps.each do |map|&lt;br /&gt;
        unless map.response.empty? &amp;amp;&amp;amp; map.response.reject { |r| r.round != round }.empty?&lt;br /&gt;
          responses &amp;lt;&amp;lt; map.response.reject { |r| r.round != round }.last&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
      responses.sort! { |a, b| a.map.reviewer.fullname &amp;lt;=&amp;gt; b.map.reviewer.fullname }&lt;br /&gt;
    end&lt;br /&gt;
    responses&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
The change in method name also required changes to the following files that referenced it:&lt;br /&gt;
&lt;br /&gt;
/app/models/assignment.rb:436:    &lt;br /&gt;
 &lt;br /&gt;
&amp;lt;big&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  assessments = ReviewResponseMap.get_assessments_round_for(team,i)&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt; &lt;br /&gt;
&lt;br /&gt;
./app/models/assignment_participant.rb:268:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;big&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 scores[questionnaire_symbol][:assessments] = questionnaire.get_assessments_round_for(self,round)&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Refactoring of metareview_response_maps method ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The metareview_response_maps method was unnecessarily complex, introducing unneeded private variables and removing additional loop. &lt;br /&gt;
Here, the ''metareview_response_maps'' variable is a collection that doesn't need to be looped (in fact the metareviews are being overwritten each iteration of the loop and not appended to the collection). And we're returning the last value of the collection. The rest of them are just lost. We've removed the redundant iteration so that it just maps to metareviews once and returns the collection at the end of the iteration. The private variable removed is: ''metareview_list'' .&lt;br /&gt;
&lt;br /&gt;
&amp;lt;big&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 def metareview_response_maps&lt;br /&gt;
    responses = Response.where(map_id:self.id)&lt;br /&gt;
    metareview_list=Array.new()&lt;br /&gt;
    responses.each do |response|&lt;br /&gt;
      metareview_response_maps = MetareviewResponseMap.where(reviewed_object_id:response.id)&lt;br /&gt;
      metareview_response_maps.each do |metareview_response_map|&lt;br /&gt;
        metareview_list&amp;lt;&amp;lt;metareview_response_map&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
    metareview_list&lt;br /&gt;
 end&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
After refactoring:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;big&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  def get_metareview_response_maps&lt;br /&gt;
    responses = Response.where(map_id: id)&lt;br /&gt;
    metareview_response_maps = []&lt;br /&gt;
    responses.each do |response|&lt;br /&gt;
      metareview_response_maps &amp;lt;&amp;lt; MetareviewResponseMap.where(reviewed_object_id: response.id)&lt;br /&gt;
    end&lt;br /&gt;
    metareview_response_maps&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Addition of code comments ===&lt;br /&gt;
&lt;br /&gt;
We added comments to all of the methods in the ReviewResponseMap.rb file and corrected instances where CodeClimate Identified opportunities for code improvement.  One issue flagged by CodeClimate that we did not change was to use the find_by method instead of where().first method.  The where().first method occurs in the import, get_assignment_participant, and create_response_map methods. It is not always appropriate to use the find_by method, as documented in this github post: https://github.com/bbatsov/rubocop/issues/1938 .  In instances where ordering by id is the desired behavior, where().first will order by default, but in Rails 4+ find_by does not honor that default behavior.  For this reason we left the instances of where().first unchanged.&lt;br /&gt;
&lt;br /&gt;
=== Code Improvements ===&lt;br /&gt;
&lt;br /&gt;
This refactoring was to improve readability and follow as many good ''Rubyist'' coding practices as possible without breaking the functionality of existing code. We used CodeClimate of the master branch code as a reference. We took the suggestions we got from CodeClimate and improved our code based on that.&lt;br /&gt;
We also made some of the methods shorter by removing redundant functionality and adding private methods to methods with a lot of functions. We also added private methods in places where we saw repeated patterns to make the code ''DRYer''.&lt;br /&gt;
At the end of our refactoring, we managed to improve the rating on CodeClimate from a '''C''' to a '''B''' . Further improvements meant reducing the size of the entire class which required a much more significant refactoring in multiple files and folders. We focussed on refactoring the existing mode, '''ReviewResponseMap'''.&lt;br /&gt;
&lt;br /&gt;
= Unit Tests =&lt;br /&gt;
&lt;br /&gt;
=== Refactoring of Unit Tests===&lt;br /&gt;
&lt;br /&gt;
The previous unit tests had syntactical and run time errors.  We were not able to get the previous unit tests to run without errors.  Because of this we rewrote the unit tests for the &amp;lt;b&amp;gt;ReviewResponseModel&amp;lt;/b&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
We added a test_helper file to the main test folder that requires a needed configuration file and needed gems.  We also added 8 fixtures that were needed for data to run the unit tests.  The following fixture files were added:&lt;br /&gt;
&lt;br /&gt;
* assignment_questionnaires.yml&lt;br /&gt;
* assignments.yml&lt;br /&gt;
* participants.yml&lt;br /&gt;
* questionnaired.yml&lt;br /&gt;
* response_maps.yml&lt;br /&gt;
* responses.yml&lt;br /&gt;
* teams.yml&lt;br /&gt;
* users.yml&lt;br /&gt;
&lt;br /&gt;
There is at least one unit test for every public method within the &amp;lt;b&amp;gt;ReviewResponseModel&amp;lt;/b&amp;gt;.  The test naming convention used is &amp;quot;method_&amp;lt;name of method that is being tested&amp;gt;&amp;quot;.  For example, the unit test for the export method is &amp;quot;method_export&amp;quot;.  If there are multiple test for one method the name of the test will include the test case after the normal naming convention.  For example, one of the unit tests for the import method checks for an invalid assignment.  The name of this method is &amp;quot;method_import_invalid_assignment&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
=== How to Run Unit Tests ===&lt;br /&gt;
To run the unit tests, follow these steps:&lt;br /&gt;
&lt;br /&gt;
# Download the master branch of the repo.&lt;br /&gt;
# Setup the Databases for the test environment (we have used Zhewei's scrubbed expertiza DB )&lt;br /&gt;
#* Run the &amp;quot; rake db:create RAILS_ENV=test &amp;quot; command&lt;br /&gt;
#* Run the &amp;quot; rake db:reset RAILS_ENV=test &amp;quot; command&lt;br /&gt;
#* Scrub the DB using &amp;quot; mysql -u root expertiza_development &amp;lt; expertiza-scrubbed.sql&amp;quot;&lt;br /&gt;
#* Run the &amp;quot; rake db:migrate &amp;quot;&lt;br /&gt;
# Run &amp;quot; rake test test/unit/review_response_map_test.rb &amp;quot; in the &amp;quot;expertiza/&amp;quot; directory.&lt;br /&gt;
#* If you run into a mysql log in error go into config/database.yml and edit the mysql credentials for the test section so that it matches the local environment's mysql configuration&lt;br /&gt;
# Check if tests passed or failed.&lt;br /&gt;
&lt;br /&gt;
= Manual Test Case =&lt;br /&gt;
&lt;br /&gt;
In order to test the changes made to the ReviewResponseMap, bring up Expertiza and log in as an administrator.  Once logged in, proceed with the following steps:&lt;br /&gt;
&lt;br /&gt;
# Go to '''impersonate user''' when logged in as ''instructor6'' and type in ''student559'' (or) just log in as ''student559''. All passwords are ''password'' .&lt;br /&gt;
# Pick any assignment to view.&lt;br /&gt;
# Navigate to '''Other's work'''.&lt;br /&gt;
# Check the different reviews and metareviews. Whether they are being displayed correctly or not.&lt;br /&gt;
# Go to Edit or Give feedback and submit a feedback.&lt;br /&gt;
# Go back and check if the feedback given is displayed correctly or not.&lt;br /&gt;
# Check if author's feedback is correct or not.&lt;br /&gt;
# Go to the '''Temp''' assignment and see if the page is being displayed correctly or not (since there is no assignment submission content or reviews for that).&lt;br /&gt;
&lt;br /&gt;
''NOTE: Since this was a refactoring of the code and methods, the existing functionality was supposed to remain the same and not break for the changes we've made.''&lt;br /&gt;
&lt;br /&gt;
= References =&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;references/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;3. [https://github.com/expertiza/expertiza Expertiza Main Repo] &amp;lt;br&amp;gt;&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;4. [https://github.com/adeeshag/expertiza/blob/develop/app/models/review_response_map.rb Refactored ReviewResponseMap.rb]&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;5. [https://github.com/adeeshag/expertiza/tree/develop/test/fixtures Test Fixtures]&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;6. [https://github.com/adeeshag/expertiza/blob/develop/test/unit/review_response_map_test.rb Unit Tests]&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;6. [http://152.46.16.195:5902/ Expertiza Deployed Site]&amp;lt;br&amp;gt;&lt;/div&gt;</summary>
		<author><name>Cnbrown4</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2015/ossE1558BGJ&amp;diff=98417</id>
		<title>CSC/ECE 517 Fall 2015/ossE1558BGJ</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2015/ossE1558BGJ&amp;diff=98417"/>
		<updated>2015-11-06T18:22:45Z</updated>

		<summary type="html">&lt;p&gt;Cnbrown4: /* Refactoring of Unit Tests */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Introduction =&lt;br /&gt;
&lt;br /&gt;
This page provides a description of the modifications and improvements made to the Expertiza project’s source code as part of an Expertiza based Open Source Software project.  Expertiza is a web based application which allows students to submit and peer-review classmates’ work, including written articles and development projects. The specific changes made during the course of this project were to the ReviewResponseMap.rb file, with additional changes made to other related files in support of refactoring ReviewResponseMap.rb.  &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
= Problem Statement =&lt;br /&gt;
&lt;br /&gt;
ReviewResponseMap is the model class used to manage the relationship between contributors, reviewers, and assignments.  The intent of the changes were to refactor the code for better readability and adherence to Ruby coding standards and best practices.  Primarily these changes involved the refactoring of overly complex methods, renaming methods for better readability, and the addition of missing unit tests.&lt;br /&gt;
&lt;br /&gt;
Project Requirements:&lt;br /&gt;
&lt;br /&gt;
# Code Climate&amp;lt;ref name=&amp;quot;Code Climate&amp;quot;&amp;gt;https://codeclimate.com&amp;lt;/ref&amp;gt; shows import method is complex, because of lots of checks. This method can be fixed by adding private methods for raising import error.&lt;br /&gt;
# Get_assessments_round_for method can be renamed to get_team_responses_for_round. Team_id private variable is not needed.&lt;br /&gt;
# metareview_response_maps rename, refactoring can be done. No need to do second iteration.&lt;br /&gt;
# write missing unit tests for existing methods.&lt;br /&gt;
&lt;br /&gt;
= Design Patterns =&lt;br /&gt;
&lt;br /&gt;
As part of our project, we refactored the model to follow the Single Responsibility and Don't Repeat Yourself (DRY) Principles.  Both of the principles focus on reducing code repetition and increasing the cohesion of the individual methods in the class.  The Single Responsibility Principle states that each class and method should have sole responsibility over one single part of the functionality of the system&amp;lt;ref&amp;gt;https://en.wikipedia.org/wiki/Single_responsibility_principle&amp;lt;/ref&amp;gt;.  The DRY principle states that whenever the same types of logic and functionality are being performed in a class the duplicated logic should be extracted into a new method that can be called in place of the repeated lines of code &amp;lt;ref&amp;gt;https://en.wikipedia.org/wiki/Don%27t_repeat_yourself&amp;lt;/ref&amp;gt;.  A prime example of a method that initially violated these principles was the import method, which in addition to performing the core import processes also performed a number of checks that would be more properly extracted into private methods.&lt;br /&gt;
&lt;br /&gt;
=Code Changes =&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Refactoring of import method ===&lt;br /&gt;
&lt;br /&gt;
	CodeClimate reports showed the import method to be overly complex, with a number of checks being included within the import method itself.  The resolution for this problem was to refactor the import method, creating private methods to perform the null checks and throw import errors.&lt;br /&gt;
&lt;br /&gt;
Prior to refactoring, all null checks were performed in line:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;big&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 def self.import(row, session, id)&lt;br /&gt;
    if row.length &amp;lt; 2&lt;br /&gt;
      raise ArgumentError, &amp;quot;Not enough items&amp;quot;&lt;br /&gt;
    end&lt;br /&gt;
    assignment = Assignment.find(id)&lt;br /&gt;
    if assignment.nil?&lt;br /&gt;
      raise ImportError, &amp;quot;The assignment with id \&amp;quot;#{id}\&amp;quot; was not found. &amp;lt;a href='/assignment/new'&amp;gt;Create&amp;lt;/a&amp;gt; this assignment?&amp;quot;&lt;br /&gt;
    end&lt;br /&gt;
    index = 1&lt;br /&gt;
    while index &amp;lt; row.length&lt;br /&gt;
      user = User.find_by_name(row[index].to_s.strip)&lt;br /&gt;
      if user.nil?&lt;br /&gt;
        raise ImportError, &amp;quot;The user account for the reviewer \&amp;quot;#{row[index]}\&amp;quot; was not found. &amp;lt;a href='/users/new'&amp;gt;Create&amp;lt;/a&amp;gt; this user?&amp;quot;&lt;br /&gt;
      end&lt;br /&gt;
      reviewer = AssignmentParticipant.where(user_id: user.id, parent_id:  assignment.id).first&lt;br /&gt;
      if reviewer == nil&lt;br /&gt;
        raise ImportError, &amp;quot;The reviewer \&amp;quot;#{row[index]}\&amp;quot; is not a participant in this assignment. &amp;lt;a href='/users/new'&amp;gt;Register&amp;lt;/a&amp;gt; this user as a participant?&amp;quot;&lt;br /&gt;
      end&lt;br /&gt;
      if assignment.team_assignment&lt;br /&gt;
        reviewee = AssignmentTeam.where(name: row[0].to_s.strip, parent_id:  assignment.id).first&lt;br /&gt;
        if reviewee == nil&lt;br /&gt;
          raise ImportError, &amp;quot;The author \&amp;quot;#{row[0].to_s.strip}\&amp;quot; was not found. &amp;lt;a href='/users/new'&amp;gt;Create&amp;lt;/a&amp;gt; this user?&amp;quot;&lt;br /&gt;
        end&lt;br /&gt;
        existing = ReviewResponseMap.where(reviewee_id: reviewee.id, reviewer_id:  reviewer.id).first&lt;br /&gt;
        if existing.nil?&lt;br /&gt;
          ReviewResponseMap.create(:reviewer_id =&amp;gt; reviewer.id, :reviewee_id =&amp;gt; reviewee.id, :reviewed_object_id =&amp;gt; assignment.id)&lt;br /&gt;
        end&lt;br /&gt;
      else&lt;br /&gt;
        puser = User.find_by_name(row[0].to_s.strip)&lt;br /&gt;
        if user == nil&lt;br /&gt;
          raise ImportError, &amp;quot;The user account for the reviewee \&amp;quot;#{row[0]}\&amp;quot; was not found. &amp;lt;a href='/users/new'&amp;gt;Create&amp;lt;/a&amp;gt; this user?&amp;quot;&lt;br /&gt;
        end&lt;br /&gt;
        reviewee = AssignmentParticipant.where(user_id: puser.id, parent_id:  assignment.id).first&lt;br /&gt;
        if reviewee == nil&lt;br /&gt;
          raise ImportError, &amp;quot;The author \&amp;quot;#{row[0].to_s.strip}\&amp;quot; was not found. &amp;lt;a href='/users/new'&amp;gt;Create&amp;lt;/a&amp;gt; this user?&amp;quot;&lt;br /&gt;
        end&lt;br /&gt;
        team_id = TeamsUser.team_id(reviewee.parent_id, reviewee.user_id)&lt;br /&gt;
        existing = ReviewResponseMap.where(reviewee_id: team_id, reviewer_id:  reviewer.id).first&lt;br /&gt;
        if existing.nil?&lt;br /&gt;
          ReviewResponseMap.create(:reviewee_id =&amp;gt; team_id, :reviewer_id =&amp;gt; reviewer.id, :reviewed_object_id =&amp;gt; assignment.id)&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
      index += 1&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
&lt;br /&gt;
After refactoring the import method adheres to the single responsibility principle, performing only key import tasks while making calls to private methods for any necessary validation. The size of the import method was reduced by doing this and counts for better readability of the code. Also, this method is a very important one and care was taken so that it wouldn't break any existing functionality. Changes were reflected in CodeClimate (link expired as it was a trial version).&lt;br /&gt;
 &lt;br /&gt;
  &amp;lt;big&amp;gt;&amp;lt;nowiki&amp;gt;#Imports new reponse maps if they do not already exist&lt;br /&gt;
  def self.import(row, _session, id)&lt;br /&gt;
      if row.length &amp;lt; 2&lt;br /&gt;
          raise ArgumentError, 'Not enough items'&lt;br /&gt;
      end&lt;br /&gt;
      assignment = find_assignment(id)&lt;br /&gt;
      index = 1&lt;br /&gt;
      reviewee_name = row[0]&lt;br /&gt;
      while index &amp;lt; row.length&lt;br /&gt;
          reviewee_id = nil&lt;br /&gt;
          reviewer_name = row[index]&lt;br /&gt;
          reviewer = get_assignment_participant(reviewer_name,  assignment.id, &amp;quot;reviewer&amp;quot;)&lt;br /&gt;
          participant_nil?(reviewer, reviewer_name , &amp;quot;reviewer&amp;quot;)&lt;br /&gt;
         &lt;br /&gt;
         #Find reviewee if assignment is a team assignment&lt;br /&gt;
         if assignment.team_assignment&lt;br /&gt;
             reviewee = AssignmentTeam.where(name: reviewee_name .to_s.strip, parent_id: assignment.id).first&lt;br /&gt;
             participant_nil?(reviewee, reviewee_name, &amp;quot;author&amp;quot;)&lt;br /&gt;
             reviewee_id = reviewee.id&lt;br /&gt;
         #Find reviewee if assignment is not a team assignment&lt;br /&gt;
         else&lt;br /&gt;
	     reviewee = get_assignment_participant(reviewee_name, assignment.id, &amp;quot;reviewee&amp;quot;)&lt;br /&gt;
             participant_nil?(reviewee, reviewee_name, &amp;quot;author&amp;quot;)&lt;br /&gt;
             reviewee_id  = TeamsUser.team_id(reviewee.parent_id, reviewee.user_id)&lt;br /&gt;
         end&lt;br /&gt;
         create_response_map(reviewer, reviewee_id,  assignment)&lt;br /&gt;
         index += 1&lt;br /&gt;
      end&lt;br /&gt;
  end&amp;lt;/nowiki&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Private methods added:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;big&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  # Check for if assignment value is null&lt;br /&gt;
  def self.find_assignment(id)&lt;br /&gt;
      begin&lt;br /&gt;
          assignment = Assignment.find(id)&lt;br /&gt;
      rescue ActiveRecord::RecordNotFound&lt;br /&gt;
          raise ImportError, &amp;quot;The assignment with id \&amp;quot;#{id}\&amp;quot; was not found.&amp;lt;a href='/assignment/new'&amp;gt;Create&amp;lt;/a&amp;gt; this assignment?&amp;quot;&lt;br /&gt;
      end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  # Check for if participant is null&lt;br /&gt;
  def self.participant_nil?(participant, user_name, participant_type) &lt;br /&gt;
      error_message = nil&lt;br /&gt;
      if participant_type == &amp;quot;author&amp;quot;&lt;br /&gt;
          error_message = &amp;quot;The author \&amp;quot;#{user_name.to_s.strip}\&amp;quot; was not found.&amp;lt;a href='/users/new'&amp;gt;Create&amp;lt;/a&amp;gt; this user?&amp;quot;&lt;br /&gt;
      else&lt;br /&gt;
          error_message =  &amp;quot;The reviewer \&amp;quot;#{user_name}\&amp;quot; is not a participant in this assignment.&amp;lt;a href='/users/new'&amp;gt;Register&amp;lt;/a&amp;gt; this user as a participant?&amp;quot;&lt;br /&gt;
      end&lt;br /&gt;
      check_nil?(participant, error_message)&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  # Check for if user is null&lt;br /&gt;
  def self.user_nil?(user, user_name, user_type)&lt;br /&gt;
      check_nil?( user, &amp;quot;The user account for the \&amp;quot;#{user_type}\&amp;quot; \&amp;quot;#{user_name}\&amp;quot; was not found.&amp;lt;a href='/users/new'&amp;gt;Create&amp;lt;/a&amp;gt; this user?&amp;quot;)&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
 #Throws import error for nil objects&lt;br /&gt;
  def self.check_nil?(object, error_message)&lt;br /&gt;
      if object.nil?&lt;br /&gt;
          raise ImportError, error_message&lt;br /&gt;
      end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Refactoring of get_assessments_round_for method ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The get_assessments_round_for method’s name failed to provide a clear idea of the method’s purpose and functionality. Additionally, there was a private variable, team_id, introduced in the method that was unnecessary and could be replaced by using the id property of the team parameter directly.  &lt;br /&gt;
&amp;lt;big&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  def self.get_assessments_round_for(team,round)&lt;br /&gt;
    team_id =team.id&lt;br /&gt;
    responses = Array.new&lt;br /&gt;
    if team_id&lt;br /&gt;
      maps = ResponseMap.where(:reviewee_id =&amp;gt; team_id, :type =&amp;gt; &amp;quot;ReviewResponseMap&amp;quot;)&lt;br /&gt;
      maps.each{ |map|&lt;br /&gt;
        if !map.response.empty? &amp;amp;&amp;amp; !map.response.reject{|r| r.round!=round}.empty?&lt;br /&gt;
          responses &amp;lt;&amp;lt; map.response.reject{|r| r.round!=round}.last&lt;br /&gt;
        end&lt;br /&gt;
      }&lt;br /&gt;
      responses.sort! {|a,b| a.map.reviewer.fullname &amp;lt;=&amp;gt; b.map.reviewer.fullname }&lt;br /&gt;
    end&lt;br /&gt;
    return responses&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Following the refactoring, the name of the method provides a clearer idea of its purpose:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;big&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  def self.get_team_responses_for_round(team, round)&lt;br /&gt;
    responses = []&lt;br /&gt;
    if team.id&lt;br /&gt;
      maps = ResponseMap.where(reviewee_id: team.id, type: 'ReviewResponseMap')&lt;br /&gt;
      maps.each do |map|&lt;br /&gt;
        unless map.response.empty? &amp;amp;&amp;amp; map.response.reject { |r| r.round != round }.empty?&lt;br /&gt;
          responses &amp;lt;&amp;lt; map.response.reject { |r| r.round != round }.last&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
      responses.sort! { |a, b| a.map.reviewer.fullname &amp;lt;=&amp;gt; b.map.reviewer.fullname }&lt;br /&gt;
    end&lt;br /&gt;
    responses&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
The change in method name also required changes to the following files that referenced it:&lt;br /&gt;
&lt;br /&gt;
/app/models/assignment.rb:436:    &lt;br /&gt;
 &lt;br /&gt;
&amp;lt;big&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  assessments = ReviewResponseMap.get_assessments_round_for(team,i)&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt; &lt;br /&gt;
&lt;br /&gt;
./app/models/assignment_participant.rb:268:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;big&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 scores[questionnaire_symbol][:assessments] = questionnaire.get_assessments_round_for(self,round)&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Refactoring of metareview_response_maps method ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The metareview_response_maps method was unnecessarily complex, introducing unneeded private variables and removing additional loop. &lt;br /&gt;
Here, the ''metareview_response_maps'' variable is a collection that doesn't need to be looped (in fact the metareviews are being overwritten each iteration of the loop and not appended to the collection). And we're returning the last value of the collection. The rest of them are just lost. We've removed the redundant iteration so that it just maps to metareviews once and returns the collection at the end of the iteration. The private variable removed is: ''metareview_list'' .&lt;br /&gt;
&lt;br /&gt;
&amp;lt;big&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 def metareview_response_maps&lt;br /&gt;
    responses = Response.where(map_id:self.id)&lt;br /&gt;
    metareview_list=Array.new()&lt;br /&gt;
    responses.each do |response|&lt;br /&gt;
      metareview_response_maps = MetareviewResponseMap.where(reviewed_object_id:response.id)&lt;br /&gt;
      metareview_response_maps.each do |metareview_response_map|&lt;br /&gt;
        metareview_list&amp;lt;&amp;lt;metareview_response_map&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
    metareview_list&lt;br /&gt;
 end&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
After refactoring:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;big&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  def get_metareview_response_maps&lt;br /&gt;
    responses = Response.where(map_id: id)&lt;br /&gt;
    metareview_response_maps = []&lt;br /&gt;
    responses.each do |response|&lt;br /&gt;
      metareview_response_maps &amp;lt;&amp;lt; MetareviewResponseMap.where(reviewed_object_id: response.id)&lt;br /&gt;
    end&lt;br /&gt;
    metareview_response_maps&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Addition of code comments ===&lt;br /&gt;
&lt;br /&gt;
We added comments to all of the methods in the ReviewResponseMap.rb file and corrected instances where CodeClimate Identified opportunities for code improvement.  One issue flagged by CodeClimate that we did not change was to use the find_by method instead of where().first method.  The where().first method occurs in the import, get_assignment_participant, and create_response_map methods. It is not always appropriate to use the find_by method, as documented in this github post: https://github.com/bbatsov/rubocop/issues/1938 .  In instances where ordering by id is the desired behavior, where().first will order by default, but in Rails 4+ find_by does not honor that default behavior.  For this reason we left the instances of where().first unchanged.&lt;br /&gt;
&lt;br /&gt;
=== Code Improvements ===&lt;br /&gt;
&lt;br /&gt;
This refactoring was to improve readability and follow as many good ''Rubyist'' coding practices as possible without breaking the functionality of existing code. We used CodeClimate of the master branch code as a reference. We took the suggestions we got from CodeClimate and improved our code based on that.&lt;br /&gt;
We also made some of the methods shorter by removing redundant functionality and adding private methods to methods with a lot of functions. We also added private methods in places where we saw repeated patterns to make the code ''DRYer''.&lt;br /&gt;
At the end of our refactoring, we managed to improve the rating on CodeClimate from a '''C''' to a '''B''' . Further improvements meant reducing the size of the entire class which required a much more significant refactoring in multiple files and folders. We focussed on refactoring the existing mode, '''ReviewResponseMap'''.&lt;br /&gt;
&lt;br /&gt;
= Unit Tests =&lt;br /&gt;
&lt;br /&gt;
=== Refactoring of Unit Tests===&lt;br /&gt;
&lt;br /&gt;
The previous unit tests had syntactical and run time errors.  We were not able to get the previous unit tests to run without errors.  Because of this we rewrote the unit tests for the &amp;lt;b&amp;gt;ReviewResponseModel&amp;lt;/b&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
We added a test_helper file to the main test folder that requires a needed configuration file and needed gems.  We also added 8 fixtures that were needed for data to run the unit tests.  The following fixture files were added:&lt;br /&gt;
&lt;br /&gt;
* assignment_questionnaires.yml&lt;br /&gt;
* assignments.yml&lt;br /&gt;
* participants.yml&lt;br /&gt;
* questionnaired.yml&lt;br /&gt;
* response_maps.yml&lt;br /&gt;
* responses.yml&lt;br /&gt;
* teams.yml&lt;br /&gt;
* users.yml&lt;br /&gt;
&lt;br /&gt;
=== How to Run Unit Tests ===&lt;br /&gt;
To run the unit tests, follow these steps:&lt;br /&gt;
&lt;br /&gt;
# Download the master branch of the repo.&lt;br /&gt;
# Setup the Databases for the test environment (we have used Zhewei's scrubbed expertiza DB )&lt;br /&gt;
#* Run the &amp;quot; rake db:create RAILS_ENV=test &amp;quot; command&lt;br /&gt;
#* Run the &amp;quot; rake db:reset RAILS_ENV=test &amp;quot; command&lt;br /&gt;
#* Scrub the DB using &amp;quot; mysql -u root expertiza_development &amp;lt; expertiza-scrubbed.sql&amp;quot;&lt;br /&gt;
#* Run the &amp;quot; rake db:migrate &amp;quot;&lt;br /&gt;
# Run &amp;quot; rake test test/unit/review_response_map_test.rb &amp;quot; in the &amp;quot;expertiza/&amp;quot; directory.&lt;br /&gt;
#* If you run into a mysql log in error go into config/database.yml and edit the mysql credentials for the test section so that it matches the local environment's mysql configuration&lt;br /&gt;
# Check if tests passed or failed.&lt;br /&gt;
&lt;br /&gt;
= Manual Test Case =&lt;br /&gt;
&lt;br /&gt;
In order to test the changes made to the ReviewResponseMap, bring up Expertiza and log in as an administrator.  Once logged in, proceed with the following steps:&lt;br /&gt;
&lt;br /&gt;
# Go to '''impersonate user''' when logged in as ''instructor6'' and type in ''student559'' (or) just log in as ''student559''. All passwords are ''password'' .&lt;br /&gt;
# Pick any assignment to view.&lt;br /&gt;
# Navigate to '''Other's work'''.&lt;br /&gt;
# Check the different reviews and metareviews. Whether they are being displayed correctly or not.&lt;br /&gt;
# Go to Edit or Give feedback and submit a feedback.&lt;br /&gt;
# Go back and check if the feedback given is displayed correctly or not.&lt;br /&gt;
# Check if author's feedback is correct or not.&lt;br /&gt;
# Go to the '''Temp''' assignment and see if the page is being displayed correctly or not (since there is no assignment submission content or reviews for that).&lt;br /&gt;
&lt;br /&gt;
''NOTE: Since this was a refactoring of the code and methods, the existing functionality was supposed to remain the same and not break for the changes we've made.''&lt;br /&gt;
&lt;br /&gt;
= References =&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;references/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;3. [https://github.com/expertiza/expertiza Expertiza Main Repo] &amp;lt;br&amp;gt;&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;4. [https://github.com/adeeshag/expertiza/blob/develop/app/models/review_response_map.rb Refactored ReviewResponseMap.rb]&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;5. [https://github.com/adeeshag/expertiza/tree/develop/test/fixtures Test Fixtures]&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;6. [https://github.com/adeeshag/expertiza/blob/develop/test/unit/review_response_map_test.rb Unit Tests]&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;6. [http://152.46.16.195:5902/ Expertiza Deployed Site]&amp;lt;br&amp;gt;&lt;/div&gt;</summary>
		<author><name>Cnbrown4</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2015/ossE1558BGJ&amp;diff=98415</id>
		<title>CSC/ECE 517 Fall 2015/ossE1558BGJ</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2015/ossE1558BGJ&amp;diff=98415"/>
		<updated>2015-11-06T18:18:43Z</updated>

		<summary type="html">&lt;p&gt;Cnbrown4: /* Changes to Unit Tests */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Introduction =&lt;br /&gt;
&lt;br /&gt;
This page provides a description of the modifications and improvements made to the Expertiza project’s source code as part of an Expertiza based Open Source Software project.  Expertiza is a web based application which allows students to submit and peer-review classmates’ work, including written articles and development projects. The specific changes made during the course of this project were to the ReviewResponseMap.rb file, with additional changes made to other related files in support of refactoring ReviewResponseMap.rb.  &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
= Problem Statement =&lt;br /&gt;
&lt;br /&gt;
ReviewResponseMap is the model class used to manage the relationship between contributors, reviewers, and assignments.  The intent of the changes were to refactor the code for better readability and adherence to Ruby coding standards and best practices.  Primarily these changes involved the refactoring of overly complex methods, renaming methods for better readability, and the addition of missing unit tests.&lt;br /&gt;
&lt;br /&gt;
Project Requirements:&lt;br /&gt;
&lt;br /&gt;
# Code Climate&amp;lt;ref name=&amp;quot;Code Climate&amp;quot;&amp;gt;https://codeclimate.com&amp;lt;/ref&amp;gt; shows import method is complex, because of lots of checks. This method can be fixed by adding private methods for raising import error.&lt;br /&gt;
# Get_assessments_round_for method can be renamed to get_team_responses_for_round. Team_id private variable is not needed.&lt;br /&gt;
# metareview_response_maps rename, refactoring can be done. No need to do second iteration.&lt;br /&gt;
# write missing unit tests for existing methods.&lt;br /&gt;
&lt;br /&gt;
= Design Patterns =&lt;br /&gt;
&lt;br /&gt;
As part of our project, we refactored the model to follow the Single Responsibility and Don't Repeat Yourself (DRY) Principles.  Both of the principles focus on reducing code repetition and increasing the cohesion of the individual methods in the class.  The Single Responsibility Principle states that each class and method should have sole responsibility over one single part of the functionality of the system&amp;lt;ref&amp;gt;https://en.wikipedia.org/wiki/Single_responsibility_principle&amp;lt;/ref&amp;gt;.  The DRY principle states that whenever the same types of logic and functionality are being performed in a class the duplicated logic should be extracted into a new method that can be called in place of the repeated lines of code &amp;lt;ref&amp;gt;https://en.wikipedia.org/wiki/Don%27t_repeat_yourself&amp;lt;/ref&amp;gt;.  A prime example of a method that initially violated these principles was the import method, which in addition to performing the core import processes also performed a number of checks that would be more properly extracted into private methods.&lt;br /&gt;
&lt;br /&gt;
=Code Changes =&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Refactoring of import method ===&lt;br /&gt;
&lt;br /&gt;
	CodeClimate reports showed the import method to be overly complex, with a number of checks being included within the import method itself.  The resolution for this problem was to refactor the import method, creating private methods to perform the null checks and throw import errors.&lt;br /&gt;
&lt;br /&gt;
Prior to refactoring, all null checks were performed in line:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;big&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 def self.import(row, session, id)&lt;br /&gt;
    if row.length &amp;lt; 2&lt;br /&gt;
      raise ArgumentError, &amp;quot;Not enough items&amp;quot;&lt;br /&gt;
    end&lt;br /&gt;
    assignment = Assignment.find(id)&lt;br /&gt;
    if assignment.nil?&lt;br /&gt;
      raise ImportError, &amp;quot;The assignment with id \&amp;quot;#{id}\&amp;quot; was not found. &amp;lt;a href='/assignment/new'&amp;gt;Create&amp;lt;/a&amp;gt; this assignment?&amp;quot;&lt;br /&gt;
    end&lt;br /&gt;
    index = 1&lt;br /&gt;
    while index &amp;lt; row.length&lt;br /&gt;
      user = User.find_by_name(row[index].to_s.strip)&lt;br /&gt;
      if user.nil?&lt;br /&gt;
        raise ImportError, &amp;quot;The user account for the reviewer \&amp;quot;#{row[index]}\&amp;quot; was not found. &amp;lt;a href='/users/new'&amp;gt;Create&amp;lt;/a&amp;gt; this user?&amp;quot;&lt;br /&gt;
      end&lt;br /&gt;
      reviewer = AssignmentParticipant.where(user_id: user.id, parent_id:  assignment.id).first&lt;br /&gt;
      if reviewer == nil&lt;br /&gt;
        raise ImportError, &amp;quot;The reviewer \&amp;quot;#{row[index]}\&amp;quot; is not a participant in this assignment. &amp;lt;a href='/users/new'&amp;gt;Register&amp;lt;/a&amp;gt; this user as a participant?&amp;quot;&lt;br /&gt;
      end&lt;br /&gt;
      if assignment.team_assignment&lt;br /&gt;
        reviewee = AssignmentTeam.where(name: row[0].to_s.strip, parent_id:  assignment.id).first&lt;br /&gt;
        if reviewee == nil&lt;br /&gt;
          raise ImportError, &amp;quot;The author \&amp;quot;#{row[0].to_s.strip}\&amp;quot; was not found. &amp;lt;a href='/users/new'&amp;gt;Create&amp;lt;/a&amp;gt; this user?&amp;quot;&lt;br /&gt;
        end&lt;br /&gt;
        existing = ReviewResponseMap.where(reviewee_id: reviewee.id, reviewer_id:  reviewer.id).first&lt;br /&gt;
        if existing.nil?&lt;br /&gt;
          ReviewResponseMap.create(:reviewer_id =&amp;gt; reviewer.id, :reviewee_id =&amp;gt; reviewee.id, :reviewed_object_id =&amp;gt; assignment.id)&lt;br /&gt;
        end&lt;br /&gt;
      else&lt;br /&gt;
        puser = User.find_by_name(row[0].to_s.strip)&lt;br /&gt;
        if user == nil&lt;br /&gt;
          raise ImportError, &amp;quot;The user account for the reviewee \&amp;quot;#{row[0]}\&amp;quot; was not found. &amp;lt;a href='/users/new'&amp;gt;Create&amp;lt;/a&amp;gt; this user?&amp;quot;&lt;br /&gt;
        end&lt;br /&gt;
        reviewee = AssignmentParticipant.where(user_id: puser.id, parent_id:  assignment.id).first&lt;br /&gt;
        if reviewee == nil&lt;br /&gt;
          raise ImportError, &amp;quot;The author \&amp;quot;#{row[0].to_s.strip}\&amp;quot; was not found. &amp;lt;a href='/users/new'&amp;gt;Create&amp;lt;/a&amp;gt; this user?&amp;quot;&lt;br /&gt;
        end&lt;br /&gt;
        team_id = TeamsUser.team_id(reviewee.parent_id, reviewee.user_id)&lt;br /&gt;
        existing = ReviewResponseMap.where(reviewee_id: team_id, reviewer_id:  reviewer.id).first&lt;br /&gt;
        if existing.nil?&lt;br /&gt;
          ReviewResponseMap.create(:reviewee_id =&amp;gt; team_id, :reviewer_id =&amp;gt; reviewer.id, :reviewed_object_id =&amp;gt; assignment.id)&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
      index += 1&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
&lt;br /&gt;
After refactoring the import method adheres to the single responsibility principle, performing only key import tasks while making calls to private methods for any necessary validation. The size of the import method was reduced by doing this and counts for better readability of the code. Also, this method is a very important one and care was taken so that it wouldn't break any existing functionality. Changes were reflected in CodeClimate (link expired as it was a trial version).&lt;br /&gt;
 &lt;br /&gt;
  &amp;lt;big&amp;gt;&amp;lt;nowiki&amp;gt;#Imports new reponse maps if they do not already exist&lt;br /&gt;
  def self.import(row, _session, id)&lt;br /&gt;
      if row.length &amp;lt; 2&lt;br /&gt;
          raise ArgumentError, 'Not enough items'&lt;br /&gt;
      end&lt;br /&gt;
      assignment = find_assignment(id)&lt;br /&gt;
      index = 1&lt;br /&gt;
      reviewee_name = row[0]&lt;br /&gt;
      while index &amp;lt; row.length&lt;br /&gt;
          reviewee_id = nil&lt;br /&gt;
          reviewer_name = row[index]&lt;br /&gt;
          reviewer = get_assignment_participant(reviewer_name,  assignment.id, &amp;quot;reviewer&amp;quot;)&lt;br /&gt;
          participant_nil?(reviewer, reviewer_name , &amp;quot;reviewer&amp;quot;)&lt;br /&gt;
         &lt;br /&gt;
         #Find reviewee if assignment is a team assignment&lt;br /&gt;
         if assignment.team_assignment&lt;br /&gt;
             reviewee = AssignmentTeam.where(name: reviewee_name .to_s.strip, parent_id: assignment.id).first&lt;br /&gt;
             participant_nil?(reviewee, reviewee_name, &amp;quot;author&amp;quot;)&lt;br /&gt;
             reviewee_id = reviewee.id&lt;br /&gt;
         #Find reviewee if assignment is not a team assignment&lt;br /&gt;
         else&lt;br /&gt;
	     reviewee = get_assignment_participant(reviewee_name, assignment.id, &amp;quot;reviewee&amp;quot;)&lt;br /&gt;
             participant_nil?(reviewee, reviewee_name, &amp;quot;author&amp;quot;)&lt;br /&gt;
             reviewee_id  = TeamsUser.team_id(reviewee.parent_id, reviewee.user_id)&lt;br /&gt;
         end&lt;br /&gt;
         create_response_map(reviewer, reviewee_id,  assignment)&lt;br /&gt;
         index += 1&lt;br /&gt;
      end&lt;br /&gt;
  end&amp;lt;/nowiki&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Private methods added:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;big&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  # Check for if assignment value is null&lt;br /&gt;
  def self.find_assignment(id)&lt;br /&gt;
      begin&lt;br /&gt;
          assignment = Assignment.find(id)&lt;br /&gt;
      rescue ActiveRecord::RecordNotFound&lt;br /&gt;
          raise ImportError, &amp;quot;The assignment with id \&amp;quot;#{id}\&amp;quot; was not found.&amp;lt;a href='/assignment/new'&amp;gt;Create&amp;lt;/a&amp;gt; this assignment?&amp;quot;&lt;br /&gt;
      end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  # Check for if participant is null&lt;br /&gt;
  def self.participant_nil?(participant, user_name, participant_type) &lt;br /&gt;
      error_message = nil&lt;br /&gt;
      if participant_type == &amp;quot;author&amp;quot;&lt;br /&gt;
          error_message = &amp;quot;The author \&amp;quot;#{user_name.to_s.strip}\&amp;quot; was not found.&amp;lt;a href='/users/new'&amp;gt;Create&amp;lt;/a&amp;gt; this user?&amp;quot;&lt;br /&gt;
      else&lt;br /&gt;
          error_message =  &amp;quot;The reviewer \&amp;quot;#{user_name}\&amp;quot; is not a participant in this assignment.&amp;lt;a href='/users/new'&amp;gt;Register&amp;lt;/a&amp;gt; this user as a participant?&amp;quot;&lt;br /&gt;
      end&lt;br /&gt;
      check_nil?(participant, error_message)&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  # Check for if user is null&lt;br /&gt;
  def self.user_nil?(user, user_name, user_type)&lt;br /&gt;
      check_nil?( user, &amp;quot;The user account for the \&amp;quot;#{user_type}\&amp;quot; \&amp;quot;#{user_name}\&amp;quot; was not found.&amp;lt;a href='/users/new'&amp;gt;Create&amp;lt;/a&amp;gt; this user?&amp;quot;)&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
 #Throws import error for nil objects&lt;br /&gt;
  def self.check_nil?(object, error_message)&lt;br /&gt;
      if object.nil?&lt;br /&gt;
          raise ImportError, error_message&lt;br /&gt;
      end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Refactoring of get_assessments_round_for method ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The get_assessments_round_for method’s name failed to provide a clear idea of the method’s purpose and functionality. Additionally, there was a private variable, team_id, introduced in the method that was unnecessary and could be replaced by using the id property of the team parameter directly.  &lt;br /&gt;
&amp;lt;big&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  def self.get_assessments_round_for(team,round)&lt;br /&gt;
    team_id =team.id&lt;br /&gt;
    responses = Array.new&lt;br /&gt;
    if team_id&lt;br /&gt;
      maps = ResponseMap.where(:reviewee_id =&amp;gt; team_id, :type =&amp;gt; &amp;quot;ReviewResponseMap&amp;quot;)&lt;br /&gt;
      maps.each{ |map|&lt;br /&gt;
        if !map.response.empty? &amp;amp;&amp;amp; !map.response.reject{|r| r.round!=round}.empty?&lt;br /&gt;
          responses &amp;lt;&amp;lt; map.response.reject{|r| r.round!=round}.last&lt;br /&gt;
        end&lt;br /&gt;
      }&lt;br /&gt;
      responses.sort! {|a,b| a.map.reviewer.fullname &amp;lt;=&amp;gt; b.map.reviewer.fullname }&lt;br /&gt;
    end&lt;br /&gt;
    return responses&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Following the refactoring, the name of the method provides a clearer idea of its purpose:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;big&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  def self.get_team_responses_for_round(team, round)&lt;br /&gt;
    responses = []&lt;br /&gt;
    if team.id&lt;br /&gt;
      maps = ResponseMap.where(reviewee_id: team.id, type: 'ReviewResponseMap')&lt;br /&gt;
      maps.each do |map|&lt;br /&gt;
        unless map.response.empty? &amp;amp;&amp;amp; map.response.reject { |r| r.round != round }.empty?&lt;br /&gt;
          responses &amp;lt;&amp;lt; map.response.reject { |r| r.round != round }.last&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
      responses.sort! { |a, b| a.map.reviewer.fullname &amp;lt;=&amp;gt; b.map.reviewer.fullname }&lt;br /&gt;
    end&lt;br /&gt;
    responses&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
The change in method name also required changes to the following files that referenced it:&lt;br /&gt;
&lt;br /&gt;
/app/models/assignment.rb:436:    &lt;br /&gt;
 &lt;br /&gt;
&amp;lt;big&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  assessments = ReviewResponseMap.get_assessments_round_for(team,i)&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt; &lt;br /&gt;
&lt;br /&gt;
./app/models/assignment_participant.rb:268:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;big&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 scores[questionnaire_symbol][:assessments] = questionnaire.get_assessments_round_for(self,round)&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Refactoring of metareview_response_maps method ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The metareview_response_maps method was unnecessarily complex, introducing unneeded private variables and removing additional loop. &lt;br /&gt;
Here, the ''metareview_response_maps'' variable is a collection that doesn't need to be looped (in fact the metareviews are being overwritten each iteration of the loop and not appended to the collection). And we're returning the last value of the collection. The rest of them are just lost. We've removed the redundant iteration so that it just maps to metareviews once and returns the collection at the end of the iteration. The private variable removed is: ''metareview_list'' .&lt;br /&gt;
&lt;br /&gt;
&amp;lt;big&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 def metareview_response_maps&lt;br /&gt;
    responses = Response.where(map_id:self.id)&lt;br /&gt;
    metareview_list=Array.new()&lt;br /&gt;
    responses.each do |response|&lt;br /&gt;
      metareview_response_maps = MetareviewResponseMap.where(reviewed_object_id:response.id)&lt;br /&gt;
      metareview_response_maps.each do |metareview_response_map|&lt;br /&gt;
        metareview_list&amp;lt;&amp;lt;metareview_response_map&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
    metareview_list&lt;br /&gt;
 end&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
After refactoring:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;big&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  def get_metareview_response_maps&lt;br /&gt;
    responses = Response.where(map_id: id)&lt;br /&gt;
    metareview_response_maps = []&lt;br /&gt;
    responses.each do |response|&lt;br /&gt;
      metareview_response_maps &amp;lt;&amp;lt; MetareviewResponseMap.where(reviewed_object_id: response.id)&lt;br /&gt;
    end&lt;br /&gt;
    metareview_response_maps&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Addition of code comments ===&lt;br /&gt;
&lt;br /&gt;
We added comments to all of the methods in the ReviewResponseMap.rb file and corrected instances where CodeClimate Identified opportunities for code improvement.  One issue flagged by CodeClimate that we did not change was to use the find_by method instead of where().first method.  The where().first method occurs in the import, get_assignment_participant, and create_response_map methods. It is not always appropriate to use the find_by method, as documented in this github post: https://github.com/bbatsov/rubocop/issues/1938 .  In instances where ordering by id is the desired behavior, where().first will order by default, but in Rails 4+ find_by does not honor that default behavior.  For this reason we left the instances of where().first unchanged.&lt;br /&gt;
&lt;br /&gt;
=== Code Improvements ===&lt;br /&gt;
&lt;br /&gt;
This refactoring was to improve readability and follow as many good ''Rubyist'' coding practices as possible without breaking the functionality of existing code. We used CodeClimate of the master branch code as a reference. We took the suggestions we got from CodeClimate and improved our code based on that.&lt;br /&gt;
We also made some of the methods shorter by removing redundant functionality and adding private methods to methods with a lot of functions. We also added private methods in places where we saw repeated patterns to make the code ''DRYer''.&lt;br /&gt;
At the end of our refactoring, we managed to improve the rating on CodeClimate from a '''C''' to a '''B''' . Further improvements meant reducing the size of the entire class which required a much more significant refactoring in multiple files and folders. We focussed on refactoring the existing mode, '''ReviewResponseMap'''.&lt;br /&gt;
&lt;br /&gt;
= Unit Tests =&lt;br /&gt;
&lt;br /&gt;
=== Refactoring of Unit Tests===&lt;br /&gt;
&lt;br /&gt;
The previous unit tests had syntactical and run time errors.  We were not able to get the previous unit tests to run without errors.  Because of this we rewrote the unit tests for the &amp;lt;b&amp;gt;ReviewResponseModel&amp;lt;/b&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== How to Run Unit Tests ===&lt;br /&gt;
To run the unit tests, follow these steps:&lt;br /&gt;
&lt;br /&gt;
# Download the master branch of the repo.&lt;br /&gt;
# Setup the Databases for the test environment (we have used Zhewei's scrubbed expertiza DB )&lt;br /&gt;
#* Run the &amp;quot; rake db:create RAILS_ENV=test &amp;quot; command&lt;br /&gt;
#* Run the &amp;quot; rake db:reset RAILS_ENV=test &amp;quot; command&lt;br /&gt;
#* Scrub the DB using &amp;quot; mysql -u root expertiza_development &amp;lt; expertiza-scrubbed.sql&amp;quot;&lt;br /&gt;
#* Run the &amp;quot; rake db:migrate &amp;quot;&lt;br /&gt;
# Run &amp;quot; rake test test/unit/review_response_map_test.rb &amp;quot; in the &amp;quot;expertiza/&amp;quot; directory.&lt;br /&gt;
#* If you run into a mysql log in error go into config/database.yml and edit the mysql credentials for the test section so that it matches the local environment's mysql configuration&lt;br /&gt;
# Check if tests passed or failed.&lt;br /&gt;
&lt;br /&gt;
= Manual Test Case =&lt;br /&gt;
&lt;br /&gt;
In order to test the changes made to the ReviewResponseMap, bring up Expertiza and log in as an administrator.  Once logged in, proceed with the following steps:&lt;br /&gt;
&lt;br /&gt;
# Go to '''impersonate user''' when logged in as ''instructor6'' and type in ''student559'' (or) just log in as ''student559''. All passwords are ''password'' .&lt;br /&gt;
# Pick any assignment to view.&lt;br /&gt;
# Navigate to '''Other's work'''.&lt;br /&gt;
# Check the different reviews and metareviews. Whether they are being displayed correctly or not.&lt;br /&gt;
# Go to Edit or Give feedback and submit a feedback.&lt;br /&gt;
# Go back and check if the feedback given is displayed correctly or not.&lt;br /&gt;
# Check if author's feedback is correct or not.&lt;br /&gt;
# Go to the '''Temp''' assignment and see if the page is being displayed correctly or not (since there is no assignment submission content or reviews for that).&lt;br /&gt;
&lt;br /&gt;
''NOTE: Since this was a refactoring of the code and methods, the existing functionality was supposed to remain the same and not break for the changes we've made.''&lt;br /&gt;
&lt;br /&gt;
= References =&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;references/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;3. [https://github.com/expertiza/expertiza Expertiza Main Repo] &amp;lt;br&amp;gt;&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;4. [https://github.com/adeeshag/expertiza/blob/develop/app/models/review_response_map.rb Refactored ReviewResponseMap.rb]&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;5. [https://github.com/adeeshag/expertiza/tree/develop/test/fixtures Test Fixtures]&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;6. [https://github.com/adeeshag/expertiza/blob/develop/test/unit/review_response_map_test.rb Unit Tests]&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;6. [http://152.46.16.195:5902/ Expertiza Deployed Site]&amp;lt;br&amp;gt;&lt;/div&gt;</summary>
		<author><name>Cnbrown4</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2015/ossE1558BGJ&amp;diff=98414</id>
		<title>CSC/ECE 517 Fall 2015/ossE1558BGJ</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2015/ossE1558BGJ&amp;diff=98414"/>
		<updated>2015-11-06T18:15:19Z</updated>

		<summary type="html">&lt;p&gt;Cnbrown4: /* Code Changes */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Introduction =&lt;br /&gt;
&lt;br /&gt;
This page provides a description of the modifications and improvements made to the Expertiza project’s source code as part of an Expertiza based Open Source Software project.  Expertiza is a web based application which allows students to submit and peer-review classmates’ work, including written articles and development projects. The specific changes made during the course of this project were to the ReviewResponseMap.rb file, with additional changes made to other related files in support of refactoring ReviewResponseMap.rb.  &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
= Problem Statement =&lt;br /&gt;
&lt;br /&gt;
ReviewResponseMap is the model class used to manage the relationship between contributors, reviewers, and assignments.  The intent of the changes were to refactor the code for better readability and adherence to Ruby coding standards and best practices.  Primarily these changes involved the refactoring of overly complex methods, renaming methods for better readability, and the addition of missing unit tests.&lt;br /&gt;
&lt;br /&gt;
Project Requirements:&lt;br /&gt;
&lt;br /&gt;
# Code Climate&amp;lt;ref name=&amp;quot;Code Climate&amp;quot;&amp;gt;https://codeclimate.com&amp;lt;/ref&amp;gt; shows import method is complex, because of lots of checks. This method can be fixed by adding private methods for raising import error.&lt;br /&gt;
# Get_assessments_round_for method can be renamed to get_team_responses_for_round. Team_id private variable is not needed.&lt;br /&gt;
# metareview_response_maps rename, refactoring can be done. No need to do second iteration.&lt;br /&gt;
# write missing unit tests for existing methods.&lt;br /&gt;
&lt;br /&gt;
= Design Patterns =&lt;br /&gt;
&lt;br /&gt;
As part of our project, we refactored the model to follow the Single Responsibility and Don't Repeat Yourself (DRY) Principles.  Both of the principles focus on reducing code repetition and increasing the cohesion of the individual methods in the class.  The Single Responsibility Principle states that each class and method should have sole responsibility over one single part of the functionality of the system&amp;lt;ref&amp;gt;https://en.wikipedia.org/wiki/Single_responsibility_principle&amp;lt;/ref&amp;gt;.  The DRY principle states that whenever the same types of logic and functionality are being performed in a class the duplicated logic should be extracted into a new method that can be called in place of the repeated lines of code &amp;lt;ref&amp;gt;https://en.wikipedia.org/wiki/Don%27t_repeat_yourself&amp;lt;/ref&amp;gt;.  A prime example of a method that initially violated these principles was the import method, which in addition to performing the core import processes also performed a number of checks that would be more properly extracted into private methods.&lt;br /&gt;
&lt;br /&gt;
=Code Changes =&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Refactoring of import method ===&lt;br /&gt;
&lt;br /&gt;
	CodeClimate reports showed the import method to be overly complex, with a number of checks being included within the import method itself.  The resolution for this problem was to refactor the import method, creating private methods to perform the null checks and throw import errors.&lt;br /&gt;
&lt;br /&gt;
Prior to refactoring, all null checks were performed in line:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;big&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 def self.import(row, session, id)&lt;br /&gt;
    if row.length &amp;lt; 2&lt;br /&gt;
      raise ArgumentError, &amp;quot;Not enough items&amp;quot;&lt;br /&gt;
    end&lt;br /&gt;
    assignment = Assignment.find(id)&lt;br /&gt;
    if assignment.nil?&lt;br /&gt;
      raise ImportError, &amp;quot;The assignment with id \&amp;quot;#{id}\&amp;quot; was not found. &amp;lt;a href='/assignment/new'&amp;gt;Create&amp;lt;/a&amp;gt; this assignment?&amp;quot;&lt;br /&gt;
    end&lt;br /&gt;
    index = 1&lt;br /&gt;
    while index &amp;lt; row.length&lt;br /&gt;
      user = User.find_by_name(row[index].to_s.strip)&lt;br /&gt;
      if user.nil?&lt;br /&gt;
        raise ImportError, &amp;quot;The user account for the reviewer \&amp;quot;#{row[index]}\&amp;quot; was not found. &amp;lt;a href='/users/new'&amp;gt;Create&amp;lt;/a&amp;gt; this user?&amp;quot;&lt;br /&gt;
      end&lt;br /&gt;
      reviewer = AssignmentParticipant.where(user_id: user.id, parent_id:  assignment.id).first&lt;br /&gt;
      if reviewer == nil&lt;br /&gt;
        raise ImportError, &amp;quot;The reviewer \&amp;quot;#{row[index]}\&amp;quot; is not a participant in this assignment. &amp;lt;a href='/users/new'&amp;gt;Register&amp;lt;/a&amp;gt; this user as a participant?&amp;quot;&lt;br /&gt;
      end&lt;br /&gt;
      if assignment.team_assignment&lt;br /&gt;
        reviewee = AssignmentTeam.where(name: row[0].to_s.strip, parent_id:  assignment.id).first&lt;br /&gt;
        if reviewee == nil&lt;br /&gt;
          raise ImportError, &amp;quot;The author \&amp;quot;#{row[0].to_s.strip}\&amp;quot; was not found. &amp;lt;a href='/users/new'&amp;gt;Create&amp;lt;/a&amp;gt; this user?&amp;quot;&lt;br /&gt;
        end&lt;br /&gt;
        existing = ReviewResponseMap.where(reviewee_id: reviewee.id, reviewer_id:  reviewer.id).first&lt;br /&gt;
        if existing.nil?&lt;br /&gt;
          ReviewResponseMap.create(:reviewer_id =&amp;gt; reviewer.id, :reviewee_id =&amp;gt; reviewee.id, :reviewed_object_id =&amp;gt; assignment.id)&lt;br /&gt;
        end&lt;br /&gt;
      else&lt;br /&gt;
        puser = User.find_by_name(row[0].to_s.strip)&lt;br /&gt;
        if user == nil&lt;br /&gt;
          raise ImportError, &amp;quot;The user account for the reviewee \&amp;quot;#{row[0]}\&amp;quot; was not found. &amp;lt;a href='/users/new'&amp;gt;Create&amp;lt;/a&amp;gt; this user?&amp;quot;&lt;br /&gt;
        end&lt;br /&gt;
        reviewee = AssignmentParticipant.where(user_id: puser.id, parent_id:  assignment.id).first&lt;br /&gt;
        if reviewee == nil&lt;br /&gt;
          raise ImportError, &amp;quot;The author \&amp;quot;#{row[0].to_s.strip}\&amp;quot; was not found. &amp;lt;a href='/users/new'&amp;gt;Create&amp;lt;/a&amp;gt; this user?&amp;quot;&lt;br /&gt;
        end&lt;br /&gt;
        team_id = TeamsUser.team_id(reviewee.parent_id, reviewee.user_id)&lt;br /&gt;
        existing = ReviewResponseMap.where(reviewee_id: team_id, reviewer_id:  reviewer.id).first&lt;br /&gt;
        if existing.nil?&lt;br /&gt;
          ReviewResponseMap.create(:reviewee_id =&amp;gt; team_id, :reviewer_id =&amp;gt; reviewer.id, :reviewed_object_id =&amp;gt; assignment.id)&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
      index += 1&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
&lt;br /&gt;
After refactoring the import method adheres to the single responsibility principle, performing only key import tasks while making calls to private methods for any necessary validation. The size of the import method was reduced by doing this and counts for better readability of the code. Also, this method is a very important one and care was taken so that it wouldn't break any existing functionality. Changes were reflected in CodeClimate (link expired as it was a trial version).&lt;br /&gt;
 &lt;br /&gt;
  &amp;lt;big&amp;gt;&amp;lt;nowiki&amp;gt;#Imports new reponse maps if they do not already exist&lt;br /&gt;
  def self.import(row, _session, id)&lt;br /&gt;
      if row.length &amp;lt; 2&lt;br /&gt;
          raise ArgumentError, 'Not enough items'&lt;br /&gt;
      end&lt;br /&gt;
      assignment = find_assignment(id)&lt;br /&gt;
      index = 1&lt;br /&gt;
      reviewee_name = row[0]&lt;br /&gt;
      while index &amp;lt; row.length&lt;br /&gt;
          reviewee_id = nil&lt;br /&gt;
          reviewer_name = row[index]&lt;br /&gt;
          reviewer = get_assignment_participant(reviewer_name,  assignment.id, &amp;quot;reviewer&amp;quot;)&lt;br /&gt;
          participant_nil?(reviewer, reviewer_name , &amp;quot;reviewer&amp;quot;)&lt;br /&gt;
         &lt;br /&gt;
         #Find reviewee if assignment is a team assignment&lt;br /&gt;
         if assignment.team_assignment&lt;br /&gt;
             reviewee = AssignmentTeam.where(name: reviewee_name .to_s.strip, parent_id: assignment.id).first&lt;br /&gt;
             participant_nil?(reviewee, reviewee_name, &amp;quot;author&amp;quot;)&lt;br /&gt;
             reviewee_id = reviewee.id&lt;br /&gt;
         #Find reviewee if assignment is not a team assignment&lt;br /&gt;
         else&lt;br /&gt;
	     reviewee = get_assignment_participant(reviewee_name, assignment.id, &amp;quot;reviewee&amp;quot;)&lt;br /&gt;
             participant_nil?(reviewee, reviewee_name, &amp;quot;author&amp;quot;)&lt;br /&gt;
             reviewee_id  = TeamsUser.team_id(reviewee.parent_id, reviewee.user_id)&lt;br /&gt;
         end&lt;br /&gt;
         create_response_map(reviewer, reviewee_id,  assignment)&lt;br /&gt;
         index += 1&lt;br /&gt;
      end&lt;br /&gt;
  end&amp;lt;/nowiki&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Private methods added:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;big&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  # Check for if assignment value is null&lt;br /&gt;
  def self.find_assignment(id)&lt;br /&gt;
      begin&lt;br /&gt;
          assignment = Assignment.find(id)&lt;br /&gt;
      rescue ActiveRecord::RecordNotFound&lt;br /&gt;
          raise ImportError, &amp;quot;The assignment with id \&amp;quot;#{id}\&amp;quot; was not found.&amp;lt;a href='/assignment/new'&amp;gt;Create&amp;lt;/a&amp;gt; this assignment?&amp;quot;&lt;br /&gt;
      end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  # Check for if participant is null&lt;br /&gt;
  def self.participant_nil?(participant, user_name, participant_type) &lt;br /&gt;
      error_message = nil&lt;br /&gt;
      if participant_type == &amp;quot;author&amp;quot;&lt;br /&gt;
          error_message = &amp;quot;The author \&amp;quot;#{user_name.to_s.strip}\&amp;quot; was not found.&amp;lt;a href='/users/new'&amp;gt;Create&amp;lt;/a&amp;gt; this user?&amp;quot;&lt;br /&gt;
      else&lt;br /&gt;
          error_message =  &amp;quot;The reviewer \&amp;quot;#{user_name}\&amp;quot; is not a participant in this assignment.&amp;lt;a href='/users/new'&amp;gt;Register&amp;lt;/a&amp;gt; this user as a participant?&amp;quot;&lt;br /&gt;
      end&lt;br /&gt;
      check_nil?(participant, error_message)&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  # Check for if user is null&lt;br /&gt;
  def self.user_nil?(user, user_name, user_type)&lt;br /&gt;
      check_nil?( user, &amp;quot;The user account for the \&amp;quot;#{user_type}\&amp;quot; \&amp;quot;#{user_name}\&amp;quot; was not found.&amp;lt;a href='/users/new'&amp;gt;Create&amp;lt;/a&amp;gt; this user?&amp;quot;)&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
 #Throws import error for nil objects&lt;br /&gt;
  def self.check_nil?(object, error_message)&lt;br /&gt;
      if object.nil?&lt;br /&gt;
          raise ImportError, error_message&lt;br /&gt;
      end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Refactoring of get_assessments_round_for method ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The get_assessments_round_for method’s name failed to provide a clear idea of the method’s purpose and functionality. Additionally, there was a private variable, team_id, introduced in the method that was unnecessary and could be replaced by using the id property of the team parameter directly.  &lt;br /&gt;
&amp;lt;big&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  def self.get_assessments_round_for(team,round)&lt;br /&gt;
    team_id =team.id&lt;br /&gt;
    responses = Array.new&lt;br /&gt;
    if team_id&lt;br /&gt;
      maps = ResponseMap.where(:reviewee_id =&amp;gt; team_id, :type =&amp;gt; &amp;quot;ReviewResponseMap&amp;quot;)&lt;br /&gt;
      maps.each{ |map|&lt;br /&gt;
        if !map.response.empty? &amp;amp;&amp;amp; !map.response.reject{|r| r.round!=round}.empty?&lt;br /&gt;
          responses &amp;lt;&amp;lt; map.response.reject{|r| r.round!=round}.last&lt;br /&gt;
        end&lt;br /&gt;
      }&lt;br /&gt;
      responses.sort! {|a,b| a.map.reviewer.fullname &amp;lt;=&amp;gt; b.map.reviewer.fullname }&lt;br /&gt;
    end&lt;br /&gt;
    return responses&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Following the refactoring, the name of the method provides a clearer idea of its purpose:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;big&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  def self.get_team_responses_for_round(team, round)&lt;br /&gt;
    responses = []&lt;br /&gt;
    if team.id&lt;br /&gt;
      maps = ResponseMap.where(reviewee_id: team.id, type: 'ReviewResponseMap')&lt;br /&gt;
      maps.each do |map|&lt;br /&gt;
        unless map.response.empty? &amp;amp;&amp;amp; map.response.reject { |r| r.round != round }.empty?&lt;br /&gt;
          responses &amp;lt;&amp;lt; map.response.reject { |r| r.round != round }.last&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
      responses.sort! { |a, b| a.map.reviewer.fullname &amp;lt;=&amp;gt; b.map.reviewer.fullname }&lt;br /&gt;
    end&lt;br /&gt;
    responses&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
The change in method name also required changes to the following files that referenced it:&lt;br /&gt;
&lt;br /&gt;
/app/models/assignment.rb:436:    &lt;br /&gt;
 &lt;br /&gt;
&amp;lt;big&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  assessments = ReviewResponseMap.get_assessments_round_for(team,i)&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt; &lt;br /&gt;
&lt;br /&gt;
./app/models/assignment_participant.rb:268:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;big&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 scores[questionnaire_symbol][:assessments] = questionnaire.get_assessments_round_for(self,round)&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Refactoring of metareview_response_maps method ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The metareview_response_maps method was unnecessarily complex, introducing unneeded private variables and removing additional loop. &lt;br /&gt;
Here, the ''metareview_response_maps'' variable is a collection that doesn't need to be looped (in fact the metareviews are being overwritten each iteration of the loop and not appended to the collection). And we're returning the last value of the collection. The rest of them are just lost. We've removed the redundant iteration so that it just maps to metareviews once and returns the collection at the end of the iteration. The private variable removed is: ''metareview_list'' .&lt;br /&gt;
&lt;br /&gt;
&amp;lt;big&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 def metareview_response_maps&lt;br /&gt;
    responses = Response.where(map_id:self.id)&lt;br /&gt;
    metareview_list=Array.new()&lt;br /&gt;
    responses.each do |response|&lt;br /&gt;
      metareview_response_maps = MetareviewResponseMap.where(reviewed_object_id:response.id)&lt;br /&gt;
      metareview_response_maps.each do |metareview_response_map|&lt;br /&gt;
        metareview_list&amp;lt;&amp;lt;metareview_response_map&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
    metareview_list&lt;br /&gt;
 end&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
After refactoring:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;big&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  def get_metareview_response_maps&lt;br /&gt;
    responses = Response.where(map_id: id)&lt;br /&gt;
    metareview_response_maps = []&lt;br /&gt;
    responses.each do |response|&lt;br /&gt;
      metareview_response_maps &amp;lt;&amp;lt; MetareviewResponseMap.where(reviewed_object_id: response.id)&lt;br /&gt;
    end&lt;br /&gt;
    metareview_response_maps&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Addition of code comments ===&lt;br /&gt;
&lt;br /&gt;
We added comments to all of the methods in the ReviewResponseMap.rb file and corrected instances where CodeClimate Identified opportunities for code improvement.  One issue flagged by CodeClimate that we did not change was to use the find_by method instead of where().first method.  The where().first method occurs in the import, get_assignment_participant, and create_response_map methods. It is not always appropriate to use the find_by method, as documented in this github post: https://github.com/bbatsov/rubocop/issues/1938 .  In instances where ordering by id is the desired behavior, where().first will order by default, but in Rails 4+ find_by does not honor that default behavior.  For this reason we left the instances of where().first unchanged.&lt;br /&gt;
&lt;br /&gt;
=== Code Improvements ===&lt;br /&gt;
&lt;br /&gt;
This refactoring was to improve readability and follow as many good ''Rubyist'' coding practices as possible without breaking the functionality of existing code. We used CodeClimate of the master branch code as a reference. We took the suggestions we got from CodeClimate and improved our code based on that.&lt;br /&gt;
We also made some of the methods shorter by removing redundant functionality and adding private methods to methods with a lot of functions. We also added private methods in places where we saw repeated patterns to make the code ''DRYer''.&lt;br /&gt;
At the end of our refactoring, we managed to improve the rating on CodeClimate from a '''C''' to a '''B''' . Further improvements meant reducing the size of the entire class which required a much more significant refactoring in multiple files and folders. We focussed on refactoring the existing mode, '''ReviewResponseMap'''.&lt;br /&gt;
&lt;br /&gt;
= Unit Tests =&lt;br /&gt;
&lt;br /&gt;
=== Changes to Unit Tests===&lt;br /&gt;
&lt;br /&gt;
=== How to Run Unit Tests ===&lt;br /&gt;
To run the unit tests, follow these steps:&lt;br /&gt;
&lt;br /&gt;
# Download the master branch of the repo.&lt;br /&gt;
# Setup the Databases for the test environment (we have used Zhewei's scrubbed expertiza DB )&lt;br /&gt;
#* Run the &amp;quot; rake db:create RAILS_ENV=test &amp;quot; command&lt;br /&gt;
#* Run the &amp;quot; rake db:reset RAILS_ENV=test &amp;quot; command&lt;br /&gt;
#* Scrub the DB using &amp;quot; mysql -u root expertiza_development &amp;lt; expertiza-scrubbed.sql&amp;quot;&lt;br /&gt;
#* Run the &amp;quot; rake db:migrate &amp;quot;&lt;br /&gt;
# Run &amp;quot; rake test test/unit/review_response_map_test.rb &amp;quot; in the &amp;quot;expertiza/&amp;quot; directory.&lt;br /&gt;
#* If you run into a mysql log in error go into config/database.yml and edit the mysql credentials for the test section so that it matches the local environment's mysql configuration&lt;br /&gt;
# Check if tests passed or failed.&lt;br /&gt;
&lt;br /&gt;
= Manual Test Case =&lt;br /&gt;
&lt;br /&gt;
In order to test the changes made to the ReviewResponseMap, bring up Expertiza and log in as an administrator.  Once logged in, proceed with the following steps:&lt;br /&gt;
&lt;br /&gt;
# Go to '''impersonate user''' when logged in as ''instructor6'' and type in ''student559'' (or) just log in as ''student559''. All passwords are ''password'' .&lt;br /&gt;
# Pick any assignment to view.&lt;br /&gt;
# Navigate to '''Other's work'''.&lt;br /&gt;
# Check the different reviews and metareviews. Whether they are being displayed correctly or not.&lt;br /&gt;
# Go to Edit or Give feedback and submit a feedback.&lt;br /&gt;
# Go back and check if the feedback given is displayed correctly or not.&lt;br /&gt;
# Check if author's feedback is correct or not.&lt;br /&gt;
# Go to the '''Temp''' assignment and see if the page is being displayed correctly or not (since there is no assignment submission content or reviews for that).&lt;br /&gt;
&lt;br /&gt;
''NOTE: Since this was a refactoring of the code and methods, the existing functionality was supposed to remain the same and not break for the changes we've made.''&lt;br /&gt;
&lt;br /&gt;
= References =&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;references/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;3. [https://github.com/expertiza/expertiza Expertiza Main Repo] &amp;lt;br&amp;gt;&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;4. [https://github.com/adeeshag/expertiza/blob/develop/app/models/review_response_map.rb Refactored ReviewResponseMap.rb]&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;5. [https://github.com/adeeshag/expertiza/tree/develop/test/fixtures Test Fixtures]&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;6. [https://github.com/adeeshag/expertiza/blob/develop/test/unit/review_response_map_test.rb Unit Tests]&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;6. [http://152.46.16.195:5902/ Expertiza Deployed Site]&amp;lt;br&amp;gt;&lt;/div&gt;</summary>
		<author><name>Cnbrown4</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2015/ossE1558BGJ&amp;diff=98412</id>
		<title>CSC/ECE 517 Fall 2015/ossE1558BGJ</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2015/ossE1558BGJ&amp;diff=98412"/>
		<updated>2015-11-06T18:14:37Z</updated>

		<summary type="html">&lt;p&gt;Cnbrown4: /* Unit Tests */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Introduction =&lt;br /&gt;
&lt;br /&gt;
This page provides a description of the modifications and improvements made to the Expertiza project’s source code as part of an Expertiza based Open Source Software project.  Expertiza is a web based application which allows students to submit and peer-review classmates’ work, including written articles and development projects. The specific changes made during the course of this project were to the ReviewResponseMap.rb file, with additional changes made to other related files in support of refactoring ReviewResponseMap.rb.  &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
= Problem Statement =&lt;br /&gt;
&lt;br /&gt;
ReviewResponseMap is the model class used to manage the relationship between contributors, reviewers, and assignments.  The intent of the changes were to refactor the code for better readability and adherence to Ruby coding standards and best practices.  Primarily these changes involved the refactoring of overly complex methods, renaming methods for better readability, and the addition of missing unit tests.&lt;br /&gt;
&lt;br /&gt;
Project Requirements:&lt;br /&gt;
&lt;br /&gt;
# Code Climate&amp;lt;ref name=&amp;quot;Code Climate&amp;quot;&amp;gt;https://codeclimate.com&amp;lt;/ref&amp;gt; shows import method is complex, because of lots of checks. This method can be fixed by adding private methods for raising import error.&lt;br /&gt;
# Get_assessments_round_for method can be renamed to get_team_responses_for_round. Team_id private variable is not needed.&lt;br /&gt;
# metareview_response_maps rename, refactoring can be done. No need to do second iteration.&lt;br /&gt;
# write missing unit tests for existing methods.&lt;br /&gt;
&lt;br /&gt;
= Design Patterns =&lt;br /&gt;
&lt;br /&gt;
As part of our project, we refactored the model to follow the Single Responsibility and Don't Repeat Yourself (DRY) Principles.  Both of the principles focus on reducing code repetition and increasing the cohesion of the individual methods in the class.  The Single Responsibility Principle states that each class and method should have sole responsibility over one single part of the functionality of the system&amp;lt;ref&amp;gt;https://en.wikipedia.org/wiki/Single_responsibility_principle&amp;lt;/ref&amp;gt;.  The DRY principle states that whenever the same types of logic and functionality are being performed in a class the duplicated logic should be extracted into a new method that can be called in place of the repeated lines of code &amp;lt;ref&amp;gt;https://en.wikipedia.org/wiki/Don%27t_repeat_yourself&amp;lt;/ref&amp;gt;.  A prime example of a method that initially violated these principles was the import method, which in addition to performing the core import processes also performed a number of checks that would be more properly extracted into private methods.&lt;br /&gt;
&lt;br /&gt;
=Code Changes =&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Refactoring of import method ===&lt;br /&gt;
&lt;br /&gt;
	CodeClimate reports showed the import method to be overly complex, with a number of checks being included within the import method itself.  The resolution for this problem was to refactor the import method, creating private methods to perform the null checks and throw import errors.&lt;br /&gt;
&lt;br /&gt;
Prior to refactoring, all null checks were performed in line:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;big&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 def self.import(row, session, id)&lt;br /&gt;
    if row.length &amp;lt; 2&lt;br /&gt;
      raise ArgumentError, &amp;quot;Not enough items&amp;quot;&lt;br /&gt;
    end&lt;br /&gt;
    assignment = Assignment.find(id)&lt;br /&gt;
    if assignment.nil?&lt;br /&gt;
      raise ImportError, &amp;quot;The assignment with id \&amp;quot;#{id}\&amp;quot; was not found. &amp;lt;a href='/assignment/new'&amp;gt;Create&amp;lt;/a&amp;gt; this assignment?&amp;quot;&lt;br /&gt;
    end&lt;br /&gt;
    index = 1&lt;br /&gt;
    while index &amp;lt; row.length&lt;br /&gt;
      user = User.find_by_name(row[index].to_s.strip)&lt;br /&gt;
      if user.nil?&lt;br /&gt;
        raise ImportError, &amp;quot;The user account for the reviewer \&amp;quot;#{row[index]}\&amp;quot; was not found. &amp;lt;a href='/users/new'&amp;gt;Create&amp;lt;/a&amp;gt; this user?&amp;quot;&lt;br /&gt;
      end&lt;br /&gt;
      reviewer = AssignmentParticipant.where(user_id: user.id, parent_id:  assignment.id).first&lt;br /&gt;
      if reviewer == nil&lt;br /&gt;
        raise ImportError, &amp;quot;The reviewer \&amp;quot;#{row[index]}\&amp;quot; is not a participant in this assignment. &amp;lt;a href='/users/new'&amp;gt;Register&amp;lt;/a&amp;gt; this user as a participant?&amp;quot;&lt;br /&gt;
      end&lt;br /&gt;
      if assignment.team_assignment&lt;br /&gt;
        reviewee = AssignmentTeam.where(name: row[0].to_s.strip, parent_id:  assignment.id).first&lt;br /&gt;
        if reviewee == nil&lt;br /&gt;
          raise ImportError, &amp;quot;The author \&amp;quot;#{row[0].to_s.strip}\&amp;quot; was not found. &amp;lt;a href='/users/new'&amp;gt;Create&amp;lt;/a&amp;gt; this user?&amp;quot;&lt;br /&gt;
        end&lt;br /&gt;
        existing = ReviewResponseMap.where(reviewee_id: reviewee.id, reviewer_id:  reviewer.id).first&lt;br /&gt;
        if existing.nil?&lt;br /&gt;
          ReviewResponseMap.create(:reviewer_id =&amp;gt; reviewer.id, :reviewee_id =&amp;gt; reviewee.id, :reviewed_object_id =&amp;gt; assignment.id)&lt;br /&gt;
        end&lt;br /&gt;
      else&lt;br /&gt;
        puser = User.find_by_name(row[0].to_s.strip)&lt;br /&gt;
        if user == nil&lt;br /&gt;
          raise ImportError, &amp;quot;The user account for the reviewee \&amp;quot;#{row[0]}\&amp;quot; was not found. &amp;lt;a href='/users/new'&amp;gt;Create&amp;lt;/a&amp;gt; this user?&amp;quot;&lt;br /&gt;
        end&lt;br /&gt;
        reviewee = AssignmentParticipant.where(user_id: puser.id, parent_id:  assignment.id).first&lt;br /&gt;
        if reviewee == nil&lt;br /&gt;
          raise ImportError, &amp;quot;The author \&amp;quot;#{row[0].to_s.strip}\&amp;quot; was not found. &amp;lt;a href='/users/new'&amp;gt;Create&amp;lt;/a&amp;gt; this user?&amp;quot;&lt;br /&gt;
        end&lt;br /&gt;
        team_id = TeamsUser.team_id(reviewee.parent_id, reviewee.user_id)&lt;br /&gt;
        existing = ReviewResponseMap.where(reviewee_id: team_id, reviewer_id:  reviewer.id).first&lt;br /&gt;
        if existing.nil?&lt;br /&gt;
          ReviewResponseMap.create(:reviewee_id =&amp;gt; team_id, :reviewer_id =&amp;gt; reviewer.id, :reviewed_object_id =&amp;gt; assignment.id)&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
      index += 1&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
&lt;br /&gt;
After refactoring the import method adheres to the single responsibility principle, performing only key import tasks while making calls to private methods for any necessary validation. The size of the import method was reduced by doing this and counts for better readability of the code. Also, this method is a very important one and care was taken so that it wouldn't break any existing functionality. Changes were reflected in CodeClimate (link expired as it was a trial version).&lt;br /&gt;
 &lt;br /&gt;
  &amp;lt;big&amp;gt;&amp;lt;nowiki&amp;gt;#Imports new reponse maps if they do not already exist&lt;br /&gt;
  def self.import(row, _session, id)&lt;br /&gt;
      if row.length &amp;lt; 2&lt;br /&gt;
          raise ArgumentError, 'Not enough items'&lt;br /&gt;
      end&lt;br /&gt;
      assignment = find_assignment(id)&lt;br /&gt;
      index = 1&lt;br /&gt;
      reviewee_name = row[0]&lt;br /&gt;
      while index &amp;lt; row.length&lt;br /&gt;
          reviewee_id = nil&lt;br /&gt;
          reviewer_name = row[index]&lt;br /&gt;
          reviewer = get_assignment_participant(reviewer_name,  assignment.id, &amp;quot;reviewer&amp;quot;)&lt;br /&gt;
          participant_nil?(reviewer, reviewer_name , &amp;quot;reviewer&amp;quot;)&lt;br /&gt;
         &lt;br /&gt;
         #Find reviewee if assignment is a team assignment&lt;br /&gt;
         if assignment.team_assignment&lt;br /&gt;
             reviewee = AssignmentTeam.where(name: reviewee_name .to_s.strip, parent_id: assignment.id).first&lt;br /&gt;
             participant_nil?(reviewee, reviewee_name, &amp;quot;author&amp;quot;)&lt;br /&gt;
             reviewee_id = reviewee.id&lt;br /&gt;
         #Find reviewee if assignment is not a team assignment&lt;br /&gt;
         else&lt;br /&gt;
	     reviewee = get_assignment_participant(reviewee_name, assignment.id, &amp;quot;reviewee&amp;quot;)&lt;br /&gt;
             participant_nil?(reviewee, reviewee_name, &amp;quot;author&amp;quot;)&lt;br /&gt;
             reviewee_id  = TeamsUser.team_id(reviewee.parent_id, reviewee.user_id)&lt;br /&gt;
         end&lt;br /&gt;
         create_response_map(reviewer, reviewee_id,  assignment)&lt;br /&gt;
         index += 1&lt;br /&gt;
      end&lt;br /&gt;
  end&amp;lt;/nowiki&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Private methods added:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;big&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  # Check for if assignment value is null&lt;br /&gt;
  def self.find_assignment(id)&lt;br /&gt;
      begin&lt;br /&gt;
          assignment = Assignment.find(id)&lt;br /&gt;
      rescue ActiveRecord::RecordNotFound&lt;br /&gt;
          raise ImportError, &amp;quot;The assignment with id \&amp;quot;#{id}\&amp;quot; was not found.&amp;lt;a href='/assignment/new'&amp;gt;Create&amp;lt;/a&amp;gt; this assignment?&amp;quot;&lt;br /&gt;
      end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  # Check for if participant is null&lt;br /&gt;
  def self.participant_nil?(participant, user_name, participant_type) &lt;br /&gt;
      error_message = nil&lt;br /&gt;
      if participant_type == &amp;quot;author&amp;quot;&lt;br /&gt;
          error_message = &amp;quot;The author \&amp;quot;#{user_name.to_s.strip}\&amp;quot; was not found.&amp;lt;a href='/users/new'&amp;gt;Create&amp;lt;/a&amp;gt; this user?&amp;quot;&lt;br /&gt;
      else&lt;br /&gt;
          error_message =  &amp;quot;The reviewer \&amp;quot;#{user_name}\&amp;quot; is not a participant in this assignment.&amp;lt;a href='/users/new'&amp;gt;Register&amp;lt;/a&amp;gt; this user as a participant?&amp;quot;&lt;br /&gt;
      end&lt;br /&gt;
      check_nil?(participant, error_message)&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  # Check for if user is null&lt;br /&gt;
  def self.user_nil?(user, user_name, user_type)&lt;br /&gt;
      check_nil?( user, &amp;quot;The user account for the \&amp;quot;#{user_type}\&amp;quot; \&amp;quot;#{user_name}\&amp;quot; was not found.&amp;lt;a href='/users/new'&amp;gt;Create&amp;lt;/a&amp;gt; this user?&amp;quot;)&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
 #Throws import error for nil objects&lt;br /&gt;
  def self.check_nil?(object, error_message)&lt;br /&gt;
      if object.nil?&lt;br /&gt;
          raise ImportError, error_message&lt;br /&gt;
      end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Refactoring of get_assessments_round_for method ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The get_assessments_round_for method’s name failed to provide a clear idea of the method’s purpose and functionality. Additionally, there was a private variable, team_id, introduced in the method that was unnecessary and could be replaced by using the id property of the team parameter directly.  &lt;br /&gt;
&amp;lt;big&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  def self.get_assessments_round_for(team,round)&lt;br /&gt;
    team_id =team.id&lt;br /&gt;
    responses = Array.new&lt;br /&gt;
    if team_id&lt;br /&gt;
      maps = ResponseMap.where(:reviewee_id =&amp;gt; team_id, :type =&amp;gt; &amp;quot;ReviewResponseMap&amp;quot;)&lt;br /&gt;
      maps.each{ |map|&lt;br /&gt;
        if !map.response.empty? &amp;amp;&amp;amp; !map.response.reject{|r| r.round!=round}.empty?&lt;br /&gt;
          responses &amp;lt;&amp;lt; map.response.reject{|r| r.round!=round}.last&lt;br /&gt;
        end&lt;br /&gt;
      }&lt;br /&gt;
      responses.sort! {|a,b| a.map.reviewer.fullname &amp;lt;=&amp;gt; b.map.reviewer.fullname }&lt;br /&gt;
    end&lt;br /&gt;
    return responses&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Following the refactoring, the name of the method provides a clearer idea of its purpose:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;big&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  def self.get_team_responses_for_round(team, round)&lt;br /&gt;
    responses = []&lt;br /&gt;
    if team.id&lt;br /&gt;
      maps = ResponseMap.where(reviewee_id: team.id, type: 'ReviewResponseMap')&lt;br /&gt;
      maps.each do |map|&lt;br /&gt;
        unless map.response.empty? &amp;amp;&amp;amp; map.response.reject { |r| r.round != round }.empty?&lt;br /&gt;
          responses &amp;lt;&amp;lt; map.response.reject { |r| r.round != round }.last&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
      responses.sort! { |a, b| a.map.reviewer.fullname &amp;lt;=&amp;gt; b.map.reviewer.fullname }&lt;br /&gt;
    end&lt;br /&gt;
    responses&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
The change in method name also required changes to the following files that referenced it:&lt;br /&gt;
&lt;br /&gt;
/app/models/assignment.rb:436:    &lt;br /&gt;
 &lt;br /&gt;
&amp;lt;big&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  assessments = ReviewResponseMap.get_assessments_round_for(team,i)&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt; &lt;br /&gt;
&lt;br /&gt;
./app/models/assignment_participant.rb:268:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;big&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 scores[questionnaire_symbol][:assessments] = questionnaire.get_assessments_round_for(self,round)&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Refactor metareview_response_maps ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The metareview_response_maps method was unnecessarily complex, introducing unneeded private variables and an additional iteration inside the main loop. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;big&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 def metareview_response_maps&lt;br /&gt;
    responses = Response.where(map_id:self.id)&lt;br /&gt;
    metareview_list=Array.new()&lt;br /&gt;
    responses.each do |response|&lt;br /&gt;
      metareview_response_maps = MetareviewResponseMap.where(reviewed_object_id:response.id)&lt;br /&gt;
      metareview_response_maps.each do |metareview_response_map|&lt;br /&gt;
        metareview_list&amp;lt;&amp;lt;metareview_response_map&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
    metareview_list&lt;br /&gt;
 end&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
After refactoring:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;big&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  def get_metareview_response_maps&lt;br /&gt;
    responses = Response.where(map_id: id)&lt;br /&gt;
    metareview_response_maps = []&lt;br /&gt;
    responses.each do |response|&lt;br /&gt;
      metareview_response_maps &amp;lt;&amp;lt; MetareviewResponseMap.where(reviewed_object_id: response.id)&lt;br /&gt;
    end&lt;br /&gt;
    metareview_response_maps&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Addition of code comments ===&lt;br /&gt;
&lt;br /&gt;
We added comments to all of the methods in the ReviewResponseMap.rb file and corrected instances where CodeClimate Identified opportunities for code improvement.  One issue flagged by CodeClimate that we did not change was to use the find_by method instead of where().first method.  The where().first method occurs in the import, get_assignment_participant, and create_response_map methods. It is not always appropriate to use the find_by method, as documented in this github post: https://github.com/bbatsov/rubocop/issues/1938 .  In instances where ordering by id is the desired behavior, where().first will order by default, but in Rails 4+ find_by does not honor that default behavior.  For this reason we left the instances of where().first unchanged.&lt;br /&gt;
&lt;br /&gt;
=== Code Improvements ===&lt;br /&gt;
&lt;br /&gt;
This refactoring was to improve readability and follow as many good ''Rubyist'' coding practices as possible without breaking the functionality of existing code. We used CodeClimate of the master branch code as a reference. We took the suggestions we got from CodeClimate and improved our code based on that.&lt;br /&gt;
We also made some of the methods shorter by removing redundant functionality and adding private methods to methods with a lot of functions. We also added private methods in places where we saw repeated patterns to make the code ''DRYer''.&lt;br /&gt;
At the end of our refactoring, we managed to improve the rating on CodeClimate from a '''C''' to a '''B''' . Further improvements meant reducing the size of the entire class which required a much more significant refactoring in multiple files and folders. We focussed on refactoring the existing mode, '''ReviewResponseMap'''.&lt;br /&gt;
&lt;br /&gt;
= Unit Tests =&lt;br /&gt;
&lt;br /&gt;
=== Changes to Unit Tests===&lt;br /&gt;
&lt;br /&gt;
=== How to Run Unit Tests ===&lt;br /&gt;
To run the unit tests, follow these steps:&lt;br /&gt;
&lt;br /&gt;
# Download the master branch of the repo.&lt;br /&gt;
# Setup the Databases for the test environment (we have used Zhewei's scrubbed expertiza DB )&lt;br /&gt;
#* Run the &amp;quot; rake db:create RAILS_ENV=test &amp;quot; command&lt;br /&gt;
#* Run the &amp;quot; rake db:reset RAILS_ENV=test &amp;quot; command&lt;br /&gt;
#* Scrub the DB using &amp;quot; mysql -u root expertiza_development &amp;lt; expertiza-scrubbed.sql&amp;quot;&lt;br /&gt;
#* Run the &amp;quot; rake db:migrate &amp;quot;&lt;br /&gt;
# Run &amp;quot; rake test test/unit/review_response_map_test.rb &amp;quot; in the &amp;quot;expertiza/&amp;quot; directory.&lt;br /&gt;
#* If you run into a mysql log in error go into config/database.yml and edit the mysql credentials for the test section so that it matches the local environment's mysql configuration&lt;br /&gt;
# Check if tests passed or failed.&lt;br /&gt;
&lt;br /&gt;
= Manual Test Case =&lt;br /&gt;
&lt;br /&gt;
In order to test the changes made to the ReviewResponseMap, bring up Expertiza and log in as an administrator.  Once logged in, proceed with the following steps:&lt;br /&gt;
&lt;br /&gt;
# Go to '''impersonate user''' when logged in as ''instructor6'' and type in ''student559'' (or) just log in as ''student559''. All passwords are ''password'' .&lt;br /&gt;
# Pick any assignment to view.&lt;br /&gt;
# Navigate to '''Other's work'''.&lt;br /&gt;
# Check the different reviews and metareviews. Whether they are being displayed correctly or not.&lt;br /&gt;
# Go to Edit or Give feedback and submit a feedback.&lt;br /&gt;
# Go back and check if the feedback given is displayed correctly or not.&lt;br /&gt;
# Check if author's feedback is correct or not.&lt;br /&gt;
# Go to the '''Temp''' assignment and see if the page is being displayed correctly or not (since there is no assignment submission content or reviews for that).&lt;br /&gt;
&lt;br /&gt;
''NOTE: Since this was a refactoring of the code and methods, the existing functionality was supposed to remain the same and not break for the changes we've made.''&lt;br /&gt;
&lt;br /&gt;
= References =&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;references/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;3. [https://github.com/expertiza/expertiza Expertiza Main Repo] &amp;lt;br&amp;gt;&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;4. [https://github.com/adeeshag/expertiza/blob/develop/app/models/review_response_map.rb Refactored ReviewResponseMap.rb]&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;5. [https://github.com/adeeshag/expertiza/tree/develop/test/fixtures Test Fixtures]&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;6. [https://github.com/adeeshag/expertiza/blob/develop/test/unit/review_response_map_test.rb Unit Tests]&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;6. [http://152.46.16.195:5902/ Expertiza Deployed Site]&amp;lt;br&amp;gt;&lt;/div&gt;</summary>
		<author><name>Cnbrown4</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2015/ossE1558BGJ&amp;diff=98411</id>
		<title>CSC/ECE 517 Fall 2015/ossE1558BGJ</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2015/ossE1558BGJ&amp;diff=98411"/>
		<updated>2015-11-06T18:13:20Z</updated>

		<summary type="html">&lt;p&gt;Cnbrown4: /* Code Changes */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Introduction =&lt;br /&gt;
&lt;br /&gt;
This page provides a description of the modifications and improvements made to the Expertiza project’s source code as part of an Expertiza based Open Source Software project.  Expertiza is a web based application which allows students to submit and peer-review classmates’ work, including written articles and development projects. The specific changes made during the course of this project were to the ReviewResponseMap.rb file, with additional changes made to other related files in support of refactoring ReviewResponseMap.rb.  &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
= Problem Statement =&lt;br /&gt;
&lt;br /&gt;
ReviewResponseMap is the model class used to manage the relationship between contributors, reviewers, and assignments.  The intent of the changes were to refactor the code for better readability and adherence to Ruby coding standards and best practices.  Primarily these changes involved the refactoring of overly complex methods, renaming methods for better readability, and the addition of missing unit tests.&lt;br /&gt;
&lt;br /&gt;
Project Requirements:&lt;br /&gt;
&lt;br /&gt;
# Code Climate&amp;lt;ref name=&amp;quot;Code Climate&amp;quot;&amp;gt;https://codeclimate.com&amp;lt;/ref&amp;gt; shows import method is complex, because of lots of checks. This method can be fixed by adding private methods for raising import error.&lt;br /&gt;
# Get_assessments_round_for method can be renamed to get_team_responses_for_round. Team_id private variable is not needed.&lt;br /&gt;
# metareview_response_maps rename, refactoring can be done. No need to do second iteration.&lt;br /&gt;
# write missing unit tests for existing methods.&lt;br /&gt;
&lt;br /&gt;
= Design Patterns =&lt;br /&gt;
&lt;br /&gt;
As part of our project, we refactored the model to follow the Single Responsibility and Don't Repeat Yourself (DRY) Principles.  Both of the principles focus on reducing code repetition and increasing the cohesion of the individual methods in the class.  The Single Responsibility Principle states that each class and method should have sole responsibility over one single part of the functionality of the system&amp;lt;ref&amp;gt;https://en.wikipedia.org/wiki/Single_responsibility_principle&amp;lt;/ref&amp;gt;.  The DRY principle states that whenever the same types of logic and functionality are being performed in a class the duplicated logic should be extracted into a new method that can be called in place of the repeated lines of code &amp;lt;ref&amp;gt;https://en.wikipedia.org/wiki/Don%27t_repeat_yourself&amp;lt;/ref&amp;gt;.  A prime example of a method that initially violated these principles was the import method, which in addition to performing the core import processes also performed a number of checks that would be more properly extracted into private methods.&lt;br /&gt;
&lt;br /&gt;
=Code Changes =&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Refactoring of import method ===&lt;br /&gt;
&lt;br /&gt;
	CodeClimate reports showed the import method to be overly complex, with a number of checks being included within the import method itself.  The resolution for this problem was to refactor the import method, creating private methods to perform the null checks and throw import errors.&lt;br /&gt;
&lt;br /&gt;
Prior to refactoring, all null checks were performed in line:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;big&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 def self.import(row, session, id)&lt;br /&gt;
    if row.length &amp;lt; 2&lt;br /&gt;
      raise ArgumentError, &amp;quot;Not enough items&amp;quot;&lt;br /&gt;
    end&lt;br /&gt;
    assignment = Assignment.find(id)&lt;br /&gt;
    if assignment.nil?&lt;br /&gt;
      raise ImportError, &amp;quot;The assignment with id \&amp;quot;#{id}\&amp;quot; was not found. &amp;lt;a href='/assignment/new'&amp;gt;Create&amp;lt;/a&amp;gt; this assignment?&amp;quot;&lt;br /&gt;
    end&lt;br /&gt;
    index = 1&lt;br /&gt;
    while index &amp;lt; row.length&lt;br /&gt;
      user = User.find_by_name(row[index].to_s.strip)&lt;br /&gt;
      if user.nil?&lt;br /&gt;
        raise ImportError, &amp;quot;The user account for the reviewer \&amp;quot;#{row[index]}\&amp;quot; was not found. &amp;lt;a href='/users/new'&amp;gt;Create&amp;lt;/a&amp;gt; this user?&amp;quot;&lt;br /&gt;
      end&lt;br /&gt;
      reviewer = AssignmentParticipant.where(user_id: user.id, parent_id:  assignment.id).first&lt;br /&gt;
      if reviewer == nil&lt;br /&gt;
        raise ImportError, &amp;quot;The reviewer \&amp;quot;#{row[index]}\&amp;quot; is not a participant in this assignment. &amp;lt;a href='/users/new'&amp;gt;Register&amp;lt;/a&amp;gt; this user as a participant?&amp;quot;&lt;br /&gt;
      end&lt;br /&gt;
      if assignment.team_assignment&lt;br /&gt;
        reviewee = AssignmentTeam.where(name: row[0].to_s.strip, parent_id:  assignment.id).first&lt;br /&gt;
        if reviewee == nil&lt;br /&gt;
          raise ImportError, &amp;quot;The author \&amp;quot;#{row[0].to_s.strip}\&amp;quot; was not found. &amp;lt;a href='/users/new'&amp;gt;Create&amp;lt;/a&amp;gt; this user?&amp;quot;&lt;br /&gt;
        end&lt;br /&gt;
        existing = ReviewResponseMap.where(reviewee_id: reviewee.id, reviewer_id:  reviewer.id).first&lt;br /&gt;
        if existing.nil?&lt;br /&gt;
          ReviewResponseMap.create(:reviewer_id =&amp;gt; reviewer.id, :reviewee_id =&amp;gt; reviewee.id, :reviewed_object_id =&amp;gt; assignment.id)&lt;br /&gt;
        end&lt;br /&gt;
      else&lt;br /&gt;
        puser = User.find_by_name(row[0].to_s.strip)&lt;br /&gt;
        if user == nil&lt;br /&gt;
          raise ImportError, &amp;quot;The user account for the reviewee \&amp;quot;#{row[0]}\&amp;quot; was not found. &amp;lt;a href='/users/new'&amp;gt;Create&amp;lt;/a&amp;gt; this user?&amp;quot;&lt;br /&gt;
        end&lt;br /&gt;
        reviewee = AssignmentParticipant.where(user_id: puser.id, parent_id:  assignment.id).first&lt;br /&gt;
        if reviewee == nil&lt;br /&gt;
          raise ImportError, &amp;quot;The author \&amp;quot;#{row[0].to_s.strip}\&amp;quot; was not found. &amp;lt;a href='/users/new'&amp;gt;Create&amp;lt;/a&amp;gt; this user?&amp;quot;&lt;br /&gt;
        end&lt;br /&gt;
        team_id = TeamsUser.team_id(reviewee.parent_id, reviewee.user_id)&lt;br /&gt;
        existing = ReviewResponseMap.where(reviewee_id: team_id, reviewer_id:  reviewer.id).first&lt;br /&gt;
        if existing.nil?&lt;br /&gt;
          ReviewResponseMap.create(:reviewee_id =&amp;gt; team_id, :reviewer_id =&amp;gt; reviewer.id, :reviewed_object_id =&amp;gt; assignment.id)&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
      index += 1&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
&lt;br /&gt;
After refactoring the import method adheres to the single responsibility principle, performing only key import tasks while making calls to private methods for any necessary validation. The size of the import method was reduced by doing this and counts for better readability of the code. Also, this method is a very important one and care was taken so that it wouldn't break any existing functionality. Changes were reflected in CodeClimate (link expired as it was a trial version).&lt;br /&gt;
 &lt;br /&gt;
  &amp;lt;big&amp;gt;&amp;lt;nowiki&amp;gt;#Imports new reponse maps if they do not already exist&lt;br /&gt;
  def self.import(row, _session, id)&lt;br /&gt;
      if row.length &amp;lt; 2&lt;br /&gt;
          raise ArgumentError, 'Not enough items'&lt;br /&gt;
      end&lt;br /&gt;
      assignment = find_assignment(id)&lt;br /&gt;
      index = 1&lt;br /&gt;
      reviewee_name = row[0]&lt;br /&gt;
      while index &amp;lt; row.length&lt;br /&gt;
          reviewee_id = nil&lt;br /&gt;
          reviewer_name = row[index]&lt;br /&gt;
          reviewer = get_assignment_participant(reviewer_name,  assignment.id, &amp;quot;reviewer&amp;quot;)&lt;br /&gt;
          participant_nil?(reviewer, reviewer_name , &amp;quot;reviewer&amp;quot;)&lt;br /&gt;
         &lt;br /&gt;
         #Find reviewee if assignment is a team assignment&lt;br /&gt;
         if assignment.team_assignment&lt;br /&gt;
             reviewee = AssignmentTeam.where(name: reviewee_name .to_s.strip, parent_id: assignment.id).first&lt;br /&gt;
             participant_nil?(reviewee, reviewee_name, &amp;quot;author&amp;quot;)&lt;br /&gt;
             reviewee_id = reviewee.id&lt;br /&gt;
         #Find reviewee if assignment is not a team assignment&lt;br /&gt;
         else&lt;br /&gt;
	     reviewee = get_assignment_participant(reviewee_name, assignment.id, &amp;quot;reviewee&amp;quot;)&lt;br /&gt;
             participant_nil?(reviewee, reviewee_name, &amp;quot;author&amp;quot;)&lt;br /&gt;
             reviewee_id  = TeamsUser.team_id(reviewee.parent_id, reviewee.user_id)&lt;br /&gt;
         end&lt;br /&gt;
         create_response_map(reviewer, reviewee_id,  assignment)&lt;br /&gt;
         index += 1&lt;br /&gt;
      end&lt;br /&gt;
  end&amp;lt;/nowiki&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Private methods added:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;big&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  # Check for if assignment value is null&lt;br /&gt;
  def self.find_assignment(id)&lt;br /&gt;
      begin&lt;br /&gt;
          assignment = Assignment.find(id)&lt;br /&gt;
      rescue ActiveRecord::RecordNotFound&lt;br /&gt;
          raise ImportError, &amp;quot;The assignment with id \&amp;quot;#{id}\&amp;quot; was not found.&amp;lt;a href='/assignment/new'&amp;gt;Create&amp;lt;/a&amp;gt; this assignment?&amp;quot;&lt;br /&gt;
      end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  # Check for if participant is null&lt;br /&gt;
  def self.participant_nil?(participant, user_name, participant_type) &lt;br /&gt;
      error_message = nil&lt;br /&gt;
      if participant_type == &amp;quot;author&amp;quot;&lt;br /&gt;
          error_message = &amp;quot;The author \&amp;quot;#{user_name.to_s.strip}\&amp;quot; was not found.&amp;lt;a href='/users/new'&amp;gt;Create&amp;lt;/a&amp;gt; this user?&amp;quot;&lt;br /&gt;
      else&lt;br /&gt;
          error_message =  &amp;quot;The reviewer \&amp;quot;#{user_name}\&amp;quot; is not a participant in this assignment.&amp;lt;a href='/users/new'&amp;gt;Register&amp;lt;/a&amp;gt; this user as a participant?&amp;quot;&lt;br /&gt;
      end&lt;br /&gt;
      check_nil?(participant, error_message)&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  # Check for if user is null&lt;br /&gt;
  def self.user_nil?(user, user_name, user_type)&lt;br /&gt;
      check_nil?( user, &amp;quot;The user account for the \&amp;quot;#{user_type}\&amp;quot; \&amp;quot;#{user_name}\&amp;quot; was not found.&amp;lt;a href='/users/new'&amp;gt;Create&amp;lt;/a&amp;gt; this user?&amp;quot;)&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
 #Throws import error for nil objects&lt;br /&gt;
  def self.check_nil?(object, error_message)&lt;br /&gt;
      if object.nil?&lt;br /&gt;
          raise ImportError, error_message&lt;br /&gt;
      end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Refactoring of get_assessments_round_for method ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The get_assessments_round_for method’s name failed to provide a clear idea of the method’s purpose and functionality. Additionally, there was a private variable, team_id, introduced in the method that was unnecessary and could be replaced by using the id property of the team parameter directly.  &lt;br /&gt;
&amp;lt;big&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  def self.get_assessments_round_for(team,round)&lt;br /&gt;
    team_id =team.id&lt;br /&gt;
    responses = Array.new&lt;br /&gt;
    if team_id&lt;br /&gt;
      maps = ResponseMap.where(:reviewee_id =&amp;gt; team_id, :type =&amp;gt; &amp;quot;ReviewResponseMap&amp;quot;)&lt;br /&gt;
      maps.each{ |map|&lt;br /&gt;
        if !map.response.empty? &amp;amp;&amp;amp; !map.response.reject{|r| r.round!=round}.empty?&lt;br /&gt;
          responses &amp;lt;&amp;lt; map.response.reject{|r| r.round!=round}.last&lt;br /&gt;
        end&lt;br /&gt;
      }&lt;br /&gt;
      responses.sort! {|a,b| a.map.reviewer.fullname &amp;lt;=&amp;gt; b.map.reviewer.fullname }&lt;br /&gt;
    end&lt;br /&gt;
    return responses&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Following the refactoring, the name of the method provides a clearer idea of its purpose:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;big&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  def self.get_team_responses_for_round(team, round)&lt;br /&gt;
    responses = []&lt;br /&gt;
    if team.id&lt;br /&gt;
      maps = ResponseMap.where(reviewee_id: team.id, type: 'ReviewResponseMap')&lt;br /&gt;
      maps.each do |map|&lt;br /&gt;
        unless map.response.empty? &amp;amp;&amp;amp; map.response.reject { |r| r.round != round }.empty?&lt;br /&gt;
          responses &amp;lt;&amp;lt; map.response.reject { |r| r.round != round }.last&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
      responses.sort! { |a, b| a.map.reviewer.fullname &amp;lt;=&amp;gt; b.map.reviewer.fullname }&lt;br /&gt;
    end&lt;br /&gt;
    responses&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
The change in method name also required changes to the following files that referenced it:&lt;br /&gt;
&lt;br /&gt;
/app/models/assignment.rb:436:    &lt;br /&gt;
 &lt;br /&gt;
&amp;lt;big&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  assessments = ReviewResponseMap.get_assessments_round_for(team,i)&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt; &lt;br /&gt;
&lt;br /&gt;
./app/models/assignment_participant.rb:268:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;big&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 scores[questionnaire_symbol][:assessments] = questionnaire.get_assessments_round_for(self,round)&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Refactor metareview_response_maps ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The metareview_response_maps method was unnecessarily complex, introducing unneeded private variables and an additional iteration inside the main loop. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;big&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 def metareview_response_maps&lt;br /&gt;
    responses = Response.where(map_id:self.id)&lt;br /&gt;
    metareview_list=Array.new()&lt;br /&gt;
    responses.each do |response|&lt;br /&gt;
      metareview_response_maps = MetareviewResponseMap.where(reviewed_object_id:response.id)&lt;br /&gt;
      metareview_response_maps.each do |metareview_response_map|&lt;br /&gt;
        metareview_list&amp;lt;&amp;lt;metareview_response_map&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
    metareview_list&lt;br /&gt;
 end&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
After refactoring:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;big&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  def get_metareview_response_maps&lt;br /&gt;
    responses = Response.where(map_id: id)&lt;br /&gt;
    metareview_response_maps = []&lt;br /&gt;
    responses.each do |response|&lt;br /&gt;
      metareview_response_maps &amp;lt;&amp;lt; MetareviewResponseMap.where(reviewed_object_id: response.id)&lt;br /&gt;
    end&lt;br /&gt;
    metareview_response_maps&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Addition of code comments ===&lt;br /&gt;
&lt;br /&gt;
We added comments to all of the methods in the ReviewResponseMap.rb file and corrected instances where CodeClimate Identified opportunities for code improvement.  One issue flagged by CodeClimate that we did not change was to use the find_by method instead of where().first method.  The where().first method occurs in the import, get_assignment_participant, and create_response_map methods. It is not always appropriate to use the find_by method, as documented in this github post: https://github.com/bbatsov/rubocop/issues/1938 .  In instances where ordering by id is the desired behavior, where().first will order by default, but in Rails 4+ find_by does not honor that default behavior.  For this reason we left the instances of where().first unchanged.&lt;br /&gt;
&lt;br /&gt;
=== Code Improvements ===&lt;br /&gt;
&lt;br /&gt;
This refactoring was to improve readability and follow as many good ''Rubyist'' coding practices as possible without breaking the functionality of existing code. We used CodeClimate of the master branch code as a reference. We took the suggestions we got from CodeClimate and improved our code based on that.&lt;br /&gt;
We also made some of the methods shorter by removing redundant functionality and adding private methods to methods with a lot of functions. We also added private methods in places where we saw repeated patterns to make the code ''DRYer''.&lt;br /&gt;
At the end of our refactoring, we managed to improve the rating on CodeClimate from a '''C''' to a '''B''' . Further improvements meant reducing the size of the entire class which required a much more significant refactoring in multiple files and folders. We focussed on refactoring the existing mode, '''ReviewResponseMap'''.&lt;br /&gt;
&lt;br /&gt;
= Unit Tests =&lt;br /&gt;
To run the unit tests, follow these steps:&lt;br /&gt;
&lt;br /&gt;
# Download the master branch of the repo.&lt;br /&gt;
# Setup the Databases for the test environment (we have used Zhewei's scrubbed expertiza DB )&lt;br /&gt;
#* Run the &amp;quot; rake db:create RAILS_ENV=test &amp;quot; command&lt;br /&gt;
#* Run the &amp;quot; rake db:reset RAILS_ENV=test &amp;quot; command&lt;br /&gt;
#* Scrub the DB using &amp;quot; mysql -u root expertiza_development &amp;lt; expertiza-scrubbed.sql&amp;quot;&lt;br /&gt;
#* Run the &amp;quot; rake db:migrate &amp;quot;&lt;br /&gt;
# Run &amp;quot; rake test test/unit/review_response_map_test.rb &amp;quot; in the &amp;quot;expertiza/&amp;quot; directory.&lt;br /&gt;
#* If you run into a mysql log in error go into config/database.yml and edit the mysql credentials for the test section so that it matches the local environment's mysql configuration&lt;br /&gt;
# Check if tests passed or failed.&lt;br /&gt;
&lt;br /&gt;
= Manual Test Case =&lt;br /&gt;
&lt;br /&gt;
In order to test the changes made to the ReviewResponseMap, bring up Expertiza and log in as an administrator.  Once logged in, proceed with the following steps:&lt;br /&gt;
&lt;br /&gt;
# Go to '''impersonate user''' when logged in as ''instructor6'' and type in ''student559'' (or) just log in as ''student559''. All passwords are ''password'' .&lt;br /&gt;
# Pick any assignment to view.&lt;br /&gt;
# Navigate to '''Other's work'''.&lt;br /&gt;
# Check the different reviews and metareviews. Whether they are being displayed correctly or not.&lt;br /&gt;
# Go to Edit or Give feedback and submit a feedback.&lt;br /&gt;
# Go back and check if the feedback given is displayed correctly or not.&lt;br /&gt;
# Check if author's feedback is correct or not.&lt;br /&gt;
# Go to the '''Temp''' assignment and see if the page is being displayed correctly or not (since there is no assignment submission content or reviews for that).&lt;br /&gt;
&lt;br /&gt;
''NOTE: Since this was a refactoring of the code and methods, the existing functionality was supposed to remain the same and not break for the changes we've made.''&lt;br /&gt;
&lt;br /&gt;
= References =&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;references/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;3. [https://github.com/expertiza/expertiza Expertiza Main Repo] &amp;lt;br&amp;gt;&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;4. [https://github.com/adeeshag/expertiza/blob/develop/app/models/review_response_map.rb Refactored ReviewResponseMap.rb]&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;5. [https://github.com/adeeshag/expertiza/tree/develop/test/fixtures Test Fixtures]&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;6. [https://github.com/adeeshag/expertiza/blob/develop/test/unit/review_response_map_test.rb Unit Tests]&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;6. [http://152.46.16.195:5902/ Expertiza Deployed Site]&amp;lt;br&amp;gt;&lt;/div&gt;</summary>
		<author><name>Cnbrown4</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2015/ossE1558BGJ&amp;diff=98410</id>
		<title>CSC/ECE 517 Fall 2015/ossE1558BGJ</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2015/ossE1558BGJ&amp;diff=98410"/>
		<updated>2015-11-06T18:12:51Z</updated>

		<summary type="html">&lt;p&gt;Cnbrown4: /* Code Changes */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Introduction =&lt;br /&gt;
&lt;br /&gt;
This page provides a description of the modifications and improvements made to the Expertiza project’s source code as part of an Expertiza based Open Source Software project.  Expertiza is a web based application which allows students to submit and peer-review classmates’ work, including written articles and development projects. The specific changes made during the course of this project were to the ReviewResponseMap.rb file, with additional changes made to other related files in support of refactoring ReviewResponseMap.rb.  &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
= Problem Statement =&lt;br /&gt;
&lt;br /&gt;
ReviewResponseMap is the model class used to manage the relationship between contributors, reviewers, and assignments.  The intent of the changes were to refactor the code for better readability and adherence to Ruby coding standards and best practices.  Primarily these changes involved the refactoring of overly complex methods, renaming methods for better readability, and the addition of missing unit tests.&lt;br /&gt;
&lt;br /&gt;
Project Requirements:&lt;br /&gt;
&lt;br /&gt;
# Code Climate&amp;lt;ref name=&amp;quot;Code Climate&amp;quot;&amp;gt;https://codeclimate.com&amp;lt;/ref&amp;gt; shows import method is complex, because of lots of checks. This method can be fixed by adding private methods for raising import error.&lt;br /&gt;
# Get_assessments_round_for method can be renamed to get_team_responses_for_round. Team_id private variable is not needed.&lt;br /&gt;
# metareview_response_maps rename, refactoring can be done. No need to do second iteration.&lt;br /&gt;
# write missing unit tests for existing methods.&lt;br /&gt;
&lt;br /&gt;
= Design Patterns =&lt;br /&gt;
&lt;br /&gt;
As part of our project, we refactored the model to follow the Single Responsibility and Don't Repeat Yourself (DRY) Principles.  Both of the principles focus on reducing code repetition and increasing the cohesion of the individual methods in the class.  The Single Responsibility Principle states that each class and method should have sole responsibility over one single part of the functionality of the system&amp;lt;ref&amp;gt;https://en.wikipedia.org/wiki/Single_responsibility_principle&amp;lt;/ref&amp;gt;.  The DRY principle states that whenever the same types of logic and functionality are being performed in a class the duplicated logic should be extracted into a new method that can be called in place of the repeated lines of code &amp;lt;ref&amp;gt;https://en.wikipedia.org/wiki/Don%27t_repeat_yourself&amp;lt;/ref&amp;gt;.  A prime example of a method that initially violated these principles was the import method, which in addition to performing the core import processes also performed a number of checks that would be more properly extracted into private methods.&lt;br /&gt;
&lt;br /&gt;
=Code Changes =&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Refactoring of import method ===&lt;br /&gt;
&lt;br /&gt;
	CodeClimate reports showed the import method to be overly complex, with a number of checks being included within the import method itself.  The resolution for this problem was to refactor the import method, creating private methods to perform the null checks and throw import errors.&lt;br /&gt;
&lt;br /&gt;
Prior to refactoring, all null checks were performed in line:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;big&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 def self.import(row, session, id)&lt;br /&gt;
    if row.length &amp;lt; 2&lt;br /&gt;
      raise ArgumentError, &amp;quot;Not enough items&amp;quot;&lt;br /&gt;
    end&lt;br /&gt;
    assignment = Assignment.find(id)&lt;br /&gt;
    if assignment.nil?&lt;br /&gt;
      raise ImportError, &amp;quot;The assignment with id \&amp;quot;#{id}\&amp;quot; was not found. &amp;lt;a href='/assignment/new'&amp;gt;Create&amp;lt;/a&amp;gt; this assignment?&amp;quot;&lt;br /&gt;
    end&lt;br /&gt;
    index = 1&lt;br /&gt;
    while index &amp;lt; row.length&lt;br /&gt;
      user = User.find_by_name(row[index].to_s.strip)&lt;br /&gt;
      if user.nil?&lt;br /&gt;
        raise ImportError, &amp;quot;The user account for the reviewer \&amp;quot;#{row[index]}\&amp;quot; was not found. &amp;lt;a href='/users/new'&amp;gt;Create&amp;lt;/a&amp;gt; this user?&amp;quot;&lt;br /&gt;
      end&lt;br /&gt;
      reviewer = AssignmentParticipant.where(user_id: user.id, parent_id:  assignment.id).first&lt;br /&gt;
      if reviewer == nil&lt;br /&gt;
        raise ImportError, &amp;quot;The reviewer \&amp;quot;#{row[index]}\&amp;quot; is not a participant in this assignment. &amp;lt;a href='/users/new'&amp;gt;Register&amp;lt;/a&amp;gt; this user as a participant?&amp;quot;&lt;br /&gt;
      end&lt;br /&gt;
      if assignment.team_assignment&lt;br /&gt;
        reviewee = AssignmentTeam.where(name: row[0].to_s.strip, parent_id:  assignment.id).first&lt;br /&gt;
        if reviewee == nil&lt;br /&gt;
          raise ImportError, &amp;quot;The author \&amp;quot;#{row[0].to_s.strip}\&amp;quot; was not found. &amp;lt;a href='/users/new'&amp;gt;Create&amp;lt;/a&amp;gt; this user?&amp;quot;&lt;br /&gt;
        end&lt;br /&gt;
        existing = ReviewResponseMap.where(reviewee_id: reviewee.id, reviewer_id:  reviewer.id).first&lt;br /&gt;
        if existing.nil?&lt;br /&gt;
          ReviewResponseMap.create(:reviewer_id =&amp;gt; reviewer.id, :reviewee_id =&amp;gt; reviewee.id, :reviewed_object_id =&amp;gt; assignment.id)&lt;br /&gt;
        end&lt;br /&gt;
      else&lt;br /&gt;
        puser = User.find_by_name(row[0].to_s.strip)&lt;br /&gt;
        if user == nil&lt;br /&gt;
          raise ImportError, &amp;quot;The user account for the reviewee \&amp;quot;#{row[0]}\&amp;quot; was not found. &amp;lt;a href='/users/new'&amp;gt;Create&amp;lt;/a&amp;gt; this user?&amp;quot;&lt;br /&gt;
        end&lt;br /&gt;
        reviewee = AssignmentParticipant.where(user_id: puser.id, parent_id:  assignment.id).first&lt;br /&gt;
        if reviewee == nil&lt;br /&gt;
          raise ImportError, &amp;quot;The author \&amp;quot;#{row[0].to_s.strip}\&amp;quot; was not found. &amp;lt;a href='/users/new'&amp;gt;Create&amp;lt;/a&amp;gt; this user?&amp;quot;&lt;br /&gt;
        end&lt;br /&gt;
        team_id = TeamsUser.team_id(reviewee.parent_id, reviewee.user_id)&lt;br /&gt;
        existing = ReviewResponseMap.where(reviewee_id: team_id, reviewer_id:  reviewer.id).first&lt;br /&gt;
        if existing.nil?&lt;br /&gt;
          ReviewResponseMap.create(:reviewee_id =&amp;gt; team_id, :reviewer_id =&amp;gt; reviewer.id, :reviewed_object_id =&amp;gt; assignment.id)&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
      index += 1&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
&lt;br /&gt;
After refactoring the import method adheres to the single responsibility principle, performing only key import tasks while making calls to private methods for any necessary validation. The size of the import method was reduced by doing this and counts for better readability of the code. Also, this method is a very important one and care was taken so that it wouldn't break any existing functionality. Changes were reflected in CodeClimate (link expired as it was a trial version).&lt;br /&gt;
 &lt;br /&gt;
  &amp;lt;big&amp;gt;&amp;lt;nowiki&amp;gt;#Imports new reponse maps if they do not already exist&lt;br /&gt;
  def self.import(row, _session, id)&lt;br /&gt;
      if row.length &amp;lt; 2&lt;br /&gt;
          raise ArgumentError, 'Not enough items'&lt;br /&gt;
      end&lt;br /&gt;
      assignment = find_assignment(id)&lt;br /&gt;
      index = 1&lt;br /&gt;
      reviewee_name = row[0]&lt;br /&gt;
      while index &amp;lt; row.length&lt;br /&gt;
          reviewee_id = nil&lt;br /&gt;
          reviewer_name = row[index]&lt;br /&gt;
          reviewer = get_assignment_participant(reviewer_name,  assignment.id, &amp;quot;reviewer&amp;quot;)&lt;br /&gt;
          participant_nil?(reviewer, reviewer_name , &amp;quot;reviewer&amp;quot;)&lt;br /&gt;
         &lt;br /&gt;
         #Find reviewee if assignment is a team assignment&lt;br /&gt;
         if assignment.team_assignment&lt;br /&gt;
             reviewee = AssignmentTeam.where(name: reviewee_name .to_s.strip, parent_id: assignment.id).first&lt;br /&gt;
             participant_nil?(reviewee, reviewee_name, &amp;quot;author&amp;quot;)&lt;br /&gt;
             reviewee_id = reviewee.id&lt;br /&gt;
         #Find reviewee if assignment is not a team assignment&lt;br /&gt;
         else&lt;br /&gt;
	     reviewee = get_assignment_participant(reviewee_name, assignment.id, &amp;quot;reviewee&amp;quot;)&lt;br /&gt;
             participant_nil?(reviewee, reviewee_name, &amp;quot;author&amp;quot;)&lt;br /&gt;
             reviewee_id  = TeamsUser.team_id(reviewee.parent_id, reviewee.user_id)&lt;br /&gt;
         end&lt;br /&gt;
         create_response_map(reviewer, reviewee_id,  assignment)&lt;br /&gt;
         index += 1&lt;br /&gt;
      end&lt;br /&gt;
  end&amp;lt;/nowiki&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Private methods added:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;big&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  # Check for if assignment value is null&lt;br /&gt;
  def self.find_assignment(id)&lt;br /&gt;
      begin&lt;br /&gt;
          assignment = Assignment.find(id)&lt;br /&gt;
      rescue ActiveRecord::RecordNotFound&lt;br /&gt;
          raise ImportError, &amp;quot;The assignment with id \&amp;quot;#{id}\&amp;quot; was not found.&amp;lt;a href='/assignment/new'&amp;gt;Create&amp;lt;/a&amp;gt; this assignment?&amp;quot;&lt;br /&gt;
      end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  # Check for if participant is null&lt;br /&gt;
  def self.participant_nil?(participant, user_name, participant_type) &lt;br /&gt;
      error_message = nil&lt;br /&gt;
      if participant_type == &amp;quot;author&amp;quot;&lt;br /&gt;
          error_message = &amp;quot;The author \&amp;quot;#{user_name.to_s.strip}\&amp;quot; was not found.&amp;lt;a href='/users/new'&amp;gt;Create&amp;lt;/a&amp;gt; this user?&amp;quot;&lt;br /&gt;
      else&lt;br /&gt;
          error_message =  &amp;quot;The reviewer \&amp;quot;#{user_name}\&amp;quot; is not a participant in this assignment.&amp;lt;a href='/users/new'&amp;gt;Register&amp;lt;/a&amp;gt; this user as a participant?&amp;quot;&lt;br /&gt;
      end&lt;br /&gt;
      check_nil?(participant, error_message)&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  # Check for if user is null&lt;br /&gt;
  def self.user_nil?(user, user_name, user_type)&lt;br /&gt;
      check_nil?( user, &amp;quot;The user account for the \&amp;quot;#{user_type}\&amp;quot; \&amp;quot;#{user_name}\&amp;quot; was not found.&amp;lt;a href='/users/new'&amp;gt;Create&amp;lt;/a&amp;gt; this user?&amp;quot;)&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
 #Throws import error for nil objects&lt;br /&gt;
  def self.check_nil?(object, error_message)&lt;br /&gt;
      if object.nil?&lt;br /&gt;
          raise ImportError, error_message&lt;br /&gt;
      end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Refactoring of get_assessments_round_for method ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The get_assessments_round_for method’s name failed to provide a clear idea of the method’s purpose and functionality. Additionally, there was a private variable, team_id, introduced in the method that was unnecessary and could be replaced by using the id property of the team parameter directly.  &lt;br /&gt;
&amp;lt;big&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  def self.get_assessments_round_for(team,round)&lt;br /&gt;
    team_id =team.id&lt;br /&gt;
    responses = Array.new&lt;br /&gt;
    if team_id&lt;br /&gt;
      maps = ResponseMap.where(:reviewee_id =&amp;gt; team_id, :type =&amp;gt; &amp;quot;ReviewResponseMap&amp;quot;)&lt;br /&gt;
      maps.each{ |map|&lt;br /&gt;
        if !map.response.empty? &amp;amp;&amp;amp; !map.response.reject{|r| r.round!=round}.empty?&lt;br /&gt;
          responses &amp;lt;&amp;lt; map.response.reject{|r| r.round!=round}.last&lt;br /&gt;
        end&lt;br /&gt;
      }&lt;br /&gt;
      responses.sort! {|a,b| a.map.reviewer.fullname &amp;lt;=&amp;gt; b.map.reviewer.fullname }&lt;br /&gt;
    end&lt;br /&gt;
    return responses&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Following the refactoring, the name of the method provides a clearer idea of its purpose:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;big&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  def self.get_team_responses_for_round(team, round)&lt;br /&gt;
    responses = []&lt;br /&gt;
    if team.id&lt;br /&gt;
      maps = ResponseMap.where(reviewee_id: team.id, type: 'ReviewResponseMap')&lt;br /&gt;
      maps.each do |map|&lt;br /&gt;
        unless map.response.empty? &amp;amp;&amp;amp; map.response.reject { |r| r.round != round }.empty?&lt;br /&gt;
          responses &amp;lt;&amp;lt; map.response.reject { |r| r.round != round }.last&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
      responses.sort! { |a, b| a.map.reviewer.fullname &amp;lt;=&amp;gt; b.map.reviewer.fullname }&lt;br /&gt;
    end&lt;br /&gt;
    responses&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
The change in method name also required changes to the following files that referenced it:&lt;br /&gt;
&lt;br /&gt;
/app/models/assignment.rb:436:    &lt;br /&gt;
 &lt;br /&gt;
&amp;lt;big&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  assessments = ReviewResponseMap.get_assessments_round_for(team,i)&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt; &lt;br /&gt;
&lt;br /&gt;
./app/models/assignment_participant.rb:268:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;big&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 scores[questionnaire_symbol][:assessments] = questionnaire.get_assessments_round_for(self,round)&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Refactor metareview_response_maps ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The metareview_response_maps method was unnecessarily complex, introducing unneeded private variables and an additional iteration inside the main loop. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;big&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 def metareview_response_maps&lt;br /&gt;
    responses = Response.where(map_id:self.id)&lt;br /&gt;
    metareview_list=Array.new()&lt;br /&gt;
    responses.each do |response|&lt;br /&gt;
      metareview_response_maps = MetareviewResponseMap.where(reviewed_object_id:response.id)&lt;br /&gt;
      metareview_response_maps.each do |metareview_response_map|&lt;br /&gt;
        metareview_list&amp;lt;&amp;lt;metareview_response_map&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
    metareview_list&lt;br /&gt;
 end&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
After refactoring:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;big&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  def get_metareview_response_maps&lt;br /&gt;
    responses = Response.where(map_id: id)&lt;br /&gt;
    metareview_response_maps = []&lt;br /&gt;
    responses.each do |response|&lt;br /&gt;
      metareview_response_maps &amp;lt;&amp;lt; MetareviewResponseMap.where(reviewed_object_id: response.id)&lt;br /&gt;
    end&lt;br /&gt;
    metareview_response_maps&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Addition of code comments ===&lt;br /&gt;
&lt;br /&gt;
We added comments to all of the methods in the ReviewResponseMap.rb file and corrected instances where CodeClimate Identified opportunities for code improvement.  One issue flagged by CodeClimate that we did not change was to use the find_by method instead of where().first method.  The where().first method occurs in the import, get_assignment_participant, and create_response_map methods. It is not always appropriate to use the find_by method, as documented in this github post: https://github.com/bbatsov/rubocop/issues/1938 .  In instances where ordering by id is the desired behavior, where().first will order by default, but in Rails 4+ find_by does not honor that default behavior.  For this reason we left the instances of where().first unchanged.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Code Improvements ===&lt;br /&gt;
&lt;br /&gt;
This refactoring was to improve readability and follow as many good ''Rubyist'' coding practices as possible without breaking the functionality of existing code. We used CodeClimate of the master branch code as a reference. We took the suggestions we got from CodeClimate and improved our code based on that.&lt;br /&gt;
We also made some of the methods shorter by removing redundant functionality and adding private methods to methods with a lot of functions. We also added private methods in places where we saw repeated patterns to make the code ''DRYer''.&lt;br /&gt;
At the end of our refactoring, we managed to improve the rating on CodeClimate from a '''C''' to a '''B''' . Further improvements meant reducing the size of the entire class which required a much more significant refactoring in multiple files and folders. We focussed on refactoring the existing mode, '''ReviewResponseMap'''.&lt;br /&gt;
&lt;br /&gt;
= Unit Tests =&lt;br /&gt;
To run the unit tests, follow these steps:&lt;br /&gt;
&lt;br /&gt;
# Download the master branch of the repo.&lt;br /&gt;
# Setup the Databases for the test environment (we have used Zhewei's scrubbed expertiza DB )&lt;br /&gt;
#* Run the &amp;quot; rake db:create RAILS_ENV=test &amp;quot; command&lt;br /&gt;
#* Run the &amp;quot; rake db:reset RAILS_ENV=test &amp;quot; command&lt;br /&gt;
#* Scrub the DB using &amp;quot; mysql -u root expertiza_development &amp;lt; expertiza-scrubbed.sql&amp;quot;&lt;br /&gt;
#* Run the &amp;quot; rake db:migrate &amp;quot;&lt;br /&gt;
# Run &amp;quot; rake test test/unit/review_response_map_test.rb &amp;quot; in the &amp;quot;expertiza/&amp;quot; directory.&lt;br /&gt;
#* If you run into a mysql log in error go into config/database.yml and edit the mysql credentials for the test section so that it matches the local environment's mysql configuration&lt;br /&gt;
# Check if tests passed or failed.&lt;br /&gt;
&lt;br /&gt;
= Manual Test Case =&lt;br /&gt;
&lt;br /&gt;
In order to test the changes made to the ReviewResponseMap, bring up Expertiza and log in as an administrator.  Once logged in, proceed with the following steps:&lt;br /&gt;
&lt;br /&gt;
# Go to '''impersonate user''' when logged in as ''instructor6'' and type in ''student559'' (or) just log in as ''student559''. All passwords are ''password'' .&lt;br /&gt;
# Pick any assignment to view.&lt;br /&gt;
# Navigate to '''Other's work'''.&lt;br /&gt;
# Check the different reviews and metareviews. Whether they are being displayed correctly or not.&lt;br /&gt;
# Go to Edit or Give feedback and submit a feedback.&lt;br /&gt;
# Go back and check if the feedback given is displayed correctly or not.&lt;br /&gt;
# Check if author's feedback is correct or not.&lt;br /&gt;
# Go to the '''Temp''' assignment and see if the page is being displayed correctly or not (since there is no assignment submission content or reviews for that).&lt;br /&gt;
&lt;br /&gt;
''NOTE: Since this was a refactoring of the code and methods, the existing functionality was supposed to remain the same and not break for the changes we've made.''&lt;br /&gt;
&lt;br /&gt;
= References =&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;references/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;3. [https://github.com/expertiza/expertiza Expertiza Main Repo] &amp;lt;br&amp;gt;&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;4. [https://github.com/adeeshag/expertiza/blob/develop/app/models/review_response_map.rb Refactored ReviewResponseMap.rb]&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;5. [https://github.com/adeeshag/expertiza/tree/develop/test/fixtures Test Fixtures]&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;6. [https://github.com/adeeshag/expertiza/blob/develop/test/unit/review_response_map_test.rb Unit Tests]&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;6. [http://152.46.16.195:5902/ Expertiza Deployed Site]&amp;lt;br&amp;gt;&lt;/div&gt;</summary>
		<author><name>Cnbrown4</name></author>
	</entry>
</feed>