<?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=Jdeng8</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=Jdeng8"/>
	<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=Special:Contributions/Jdeng8"/>
	<updated>2026-06-05T14:04:36Z</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_2016/E1701._Accelerate_RSpec_testing&amp;diff=106876</id>
		<title>CSC/ECE 517 Fall 2016/E1701. Accelerate RSpec testing</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2016/E1701._Accelerate_RSpec_testing&amp;diff=106876"/>
		<updated>2016-12-15T01:31:05Z</updated>

		<summary type="html">&lt;p&gt;Jdeng8: /* Performance improvement */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== '''Expertiza''' ==&lt;br /&gt;
Expertiza is a web application where students can submit and peer-review learning objects (articles, code, web sites, etc). It is used in select courses at NC State and by professors at several other colleges and universities.&lt;br /&gt;
&lt;br /&gt;
== '''Rspec''' ==&lt;br /&gt;
Rspec is a meta-gem, which depends on the rspec-core, rspec-expectations and rspec-mocks gems. Each of these can be installed separately and loaded in isolation using require. Among other benefits, this allows you to use rspec-expectations, for example, in Test::Unit::TestCase if you happen to prefer that style.&lt;br /&gt;
Conversely, if you like RSpec's approach to declaring example groups and examples (describe and it) but prefer Test::Unit assertions and mocha, rr or flexmock for mocking, you'll be able to do that without having to install or load the components of RSpec that you're not using.&lt;br /&gt;
== '''Problem Statement''' ==&lt;br /&gt;
Unfortunately, Expertiza tests are really slow. If you check the TravisCI, it needs nearly 9 min to run all tests.&lt;br /&gt;
 [[File:Expertiza test time.png]]&lt;br /&gt;
One reason is that we use fixture to create records in test DB each time running tests.&lt;br /&gt;
 &lt;br /&gt;
For example, the codes in quiz_spec.rb contain too much create so that prolong testing time.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
   # Create an assignment due date&lt;br /&gt;
    create(:deadline_type, name: &amp;quot;submission&amp;quot;)&lt;br /&gt;
    create(:deadline_type, name: &amp;quot;review&amp;quot;)&lt;br /&gt;
    create(:deadline_type, name: &amp;quot;metareview&amp;quot;)&lt;br /&gt;
    create(:deadline_type, name: &amp;quot;drop_topic&amp;quot;)&lt;br /&gt;
    create(:deadline_type, name: &amp;quot;signup&amp;quot;)&lt;br /&gt;
    create(:deadline_type, name: &amp;quot;team_formation&amp;quot;)&lt;br /&gt;
    create(:deadline_right)&lt;br /&gt;
    create(:deadline_right, name: 'Late')&lt;br /&gt;
    create(:deadline_right, name: 'OK')&lt;br /&gt;
    create :assignment_due_date, due_at: (DateTime.now + 1)&lt;br /&gt;
&amp;lt;/pre&amp;gt; &lt;br /&gt;
&lt;br /&gt;
One solution is building an complete database to support all RSpec test without creating new records.&lt;br /&gt;
&lt;br /&gt;
== '''Task''' ==&lt;br /&gt;
Formally, we need to:&lt;br /&gt;
* Create the records in test DB according to the content in fixtures.&lt;br /&gt;
* Check each test file and delete certain DB records creation code that insert default records (eg. create(:deadline_type)).&lt;br /&gt;
* And keep all the test cases passing when using test DB and make sure the time running test cases is shorter than before.&lt;br /&gt;
* You should submit the sql file of test DB to Expertiza.&lt;br /&gt;
To finish these tasks, we need to modify all RSpec test files in Expertiza and using a new Database:Expertiza_test.&lt;br /&gt;
&lt;br /&gt;
== Refactor files==&lt;br /&gt;
test database&lt;br /&gt;
&lt;br /&gt;
Rspec tests&lt;br /&gt;
&lt;br /&gt;
== '''Design''' ==&lt;br /&gt;
=== Design idea explanation ===&lt;br /&gt;
[[File: Design explanation.png]]&lt;br /&gt;
&lt;br /&gt;
In this design, we create a new database for testing, and we save some related information in this database. Every test just need to fetch data from this test database, and after the testing, we need to add some operation to rollback the data. For example,  if the test is about creating a new quiz, in this situation, we need to delete this quiz after this test. Because of it, the state of database can be saved, and also it will not influence other test or test this test case again.&lt;br /&gt;
&lt;br /&gt;
=== Database design ===&lt;br /&gt;
We design a expertiza_test database to save the test date used for Rspec. The test database owns the same structure as the real expertiza database, including the relations between tables and some restriction of attribute like it cannot be null or some other requirements for different attributes. Besides, the data in test database is the same as the data in factories part in spec, which includes FeedbackResponseMap.rb, Respone.rb, factories.rb, quiz_factory.rb. In this situation we do not need to create some data before testing, and we can use the data in test DB directly. Because of it, the overhead of testing cases will experience obvious decreasing.&lt;br /&gt;
like the Rspec statements in creating some User objects.:&lt;br /&gt;
  factory :admin, class: User do&lt;br /&gt;
    sequence(:name) {|n| &amp;quot;admin#{n}&amp;quot; }&lt;br /&gt;
    role { Role.where(name: 'Administrator').first || association(:role_of_administrator) }&lt;br /&gt;
    password &amp;quot;password&amp;quot;&lt;br /&gt;
    password_confirmation &amp;quot;password&amp;quot;&lt;br /&gt;
    sequence(:fullname) {|n| &amp;quot;#{n}, administrator&amp;quot; }&lt;br /&gt;
    email &amp;quot;expertiza@mailinator.com&amp;quot;&lt;br /&gt;
    parent_id 1&lt;br /&gt;
    private_by_default  false&lt;br /&gt;
    mru_directory_path  nil&lt;br /&gt;
    email_on_review true&lt;br /&gt;
    email_on_submission true&lt;br /&gt;
    email_on_review_of_review true&lt;br /&gt;
    is_new_user false&lt;br /&gt;
    master_permission_granted 0&lt;br /&gt;
    handle &amp;quot;handle&amp;quot;&lt;br /&gt;
    leaderboard_privacy false&lt;br /&gt;
    digital_certificate nil&lt;br /&gt;
    timezonepref nil&lt;br /&gt;
    public_key nil&lt;br /&gt;
    copy_of_emails  false&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
then transfer this into SQL query and then add the information the same as designed for Rspec test into expertiza_test database.&lt;br /&gt;
&lt;br /&gt;
We will try two method to achieve the goal:&lt;br /&gt;
# Write a script to create all test data automatically then don't clean the database.&lt;br /&gt;
# We transfer the data in girls_factory into the data base, and there are some steps:&lt;br /&gt;
1. we delete some related information in Rails_hepler.rb &lt;br /&gt;
&lt;br /&gt;
 config.before(:suite) do&lt;br /&gt;
    DatabaseCleaner.clean_with(:truncation)&lt;br /&gt;
  end&lt;br /&gt;
  config.before(:each) do |_example|&lt;br /&gt;
    DatabaseCleaner.strategy = :truncation&lt;br /&gt;
    DatabaseCleaner.start&lt;br /&gt;
  end&lt;br /&gt;
 &lt;br /&gt;
  config.after(:each) do&lt;br /&gt;
    DatabaseCleaner.clean&lt;br /&gt;
  end&lt;br /&gt;
Those statements is used for adding the technology to clean the database before everytime using Rspec test, and then also clean the database(using turncate to increase the time of cleaning database).&lt;br /&gt;
2. We generate a new create rb file, and in this file we just put the create statements in Rspec style function, like  create(:deadline_type, name: &amp;quot;submission&amp;quot;) to transfer the data into database when running rspec create.rb&lt;br /&gt;
&lt;br /&gt;
=== Feature test design ===&lt;br /&gt;
To accelerate the feature test, we have to eliminate pseudo data creation. Now all the feature tests must create their own data before each test. For an example, now a test first create a user before it can do the login operation. The creation latency is considerable. After building a test database, all the pseudo data creation statement can be removed from the test files. Instead, the tests reference data stored in the test database. This change will not only accelerate the testing time, but also dry out the code.&lt;br /&gt;
&lt;br /&gt;
The way tests reference data from database is the same as it does in the development mode.  To login, or do other operations, the test can invoke existing user data in test database. Using &amp;quot;User.find()&amp;quot; or &amp;quot;User.where()&amp;quot;, test data can easily be invoked by tests.&lt;br /&gt;
&lt;br /&gt;
For existing tests, they can directly use the test database. For new tests added later, they can use the records in test database or create specialized data use FactoryGirl. So to keep the test database up to date ,it needs to be maintained regularly.&lt;br /&gt;
&lt;br /&gt;
== ''' Modify feature test''' ==&lt;br /&gt;
&lt;br /&gt;
With test data in the database, we modified the RSpec feature test files:&lt;br /&gt;
1. Disable the data clean statement in rails_helper.rb.&lt;br /&gt;
  config.before(:suite) do&lt;br /&gt;
     DatabaseCleaner.clean_with(:truncation)&lt;br /&gt;
   end&lt;br /&gt;
   config.before(:each) do |_example|&lt;br /&gt;
     DatabaseCleaner.strategy = :truncation&lt;br /&gt;
     DatabaseCleaner.start&lt;br /&gt;
   end&lt;br /&gt;
  &lt;br /&gt;
   config.after(:each) do&lt;br /&gt;
     DatabaseCleaner.clean&lt;br /&gt;
   end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
2. Eliminate data creation statement in each test case.&lt;br /&gt;
Delete” create(:assignment)” like code&lt;br /&gt;
&lt;br /&gt;
3. Modify url visit statement.&lt;br /&gt;
Modify “visit '/student_teams/view?student_id=1'” &lt;br /&gt;
to &lt;br /&gt;
@student=User.find_by(name:”student2064”)&lt;br /&gt;
“visit '/student_teams/view?student_id=@student.id’”&lt;br /&gt;
&lt;br /&gt;
4. Recover test database before or after each change data operation&lt;br /&gt;
For tests involved with create or delete actions, the data modified should be rollback.&lt;br /&gt;
&lt;br /&gt;
== ''' The file we need to edit''' ==&lt;br /&gt;
&lt;br /&gt;
airbrake_expection_errors_feature_tests_spec.rb&lt;br /&gt;
&lt;br /&gt;
assignment_creation_spec.rb&lt;br /&gt;
&lt;br /&gt;
calibration_spec.rb&lt;br /&gt;
&lt;br /&gt;
inherit_teams_display_spec.rb&lt;br /&gt;
&lt;br /&gt;
instructor_interface_spec.rb&lt;br /&gt;
&lt;br /&gt;
list_teams_spec.rb&lt;br /&gt;
&lt;br /&gt;
questionnaire_spec.rb&lt;br /&gt;
&lt;br /&gt;
review_mapping_spec.rb&lt;br /&gt;
&lt;br /&gt;
staggered_deadline_spec.rb&lt;br /&gt;
&lt;br /&gt;
topic_suggestion_spec.rb&lt;br /&gt;
&lt;br /&gt;
==Performance improvement==&lt;br /&gt;
We run a single rspec test &amp;quot;airbrake_expection_errors_feature_tests_spec.rb&amp;quot; to test the performance improvement when using test database.&lt;br /&gt;
&lt;br /&gt;
Without a test database, the feature test costs 1:37 minutes:&lt;br /&gt;
 [[File:After refactor.png]]&lt;br /&gt;
Using the test database, the same test costs 1:10 minutes:&lt;br /&gt;
 [[File:Before refactor.png]]&lt;br /&gt;
The time is decreased by about 20%. Consider the browser's response time in both trial, the improvement proportion should be higher.&lt;br /&gt;
&lt;br /&gt;
Here is a video to show the improvement:&lt;br /&gt;
https://www.youtube.com/watch?v=9y0i-zSRHe8&amp;amp;feature=youtu.be&lt;/div&gt;</summary>
		<author><name>Jdeng8</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2016/E1701._Accelerate_RSpec_testing&amp;diff=106875</id>
		<title>CSC/ECE 517 Fall 2016/E1701. Accelerate RSpec testing</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2016/E1701._Accelerate_RSpec_testing&amp;diff=106875"/>
		<updated>2016-12-15T01:29:55Z</updated>

		<summary type="html">&lt;p&gt;Jdeng8: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== '''Expertiza''' ==&lt;br /&gt;
Expertiza is a web application where students can submit and peer-review learning objects (articles, code, web sites, etc). It is used in select courses at NC State and by professors at several other colleges and universities.&lt;br /&gt;
&lt;br /&gt;
== '''Rspec''' ==&lt;br /&gt;
Rspec is a meta-gem, which depends on the rspec-core, rspec-expectations and rspec-mocks gems. Each of these can be installed separately and loaded in isolation using require. Among other benefits, this allows you to use rspec-expectations, for example, in Test::Unit::TestCase if you happen to prefer that style.&lt;br /&gt;
Conversely, if you like RSpec's approach to declaring example groups and examples (describe and it) but prefer Test::Unit assertions and mocha, rr or flexmock for mocking, you'll be able to do that without having to install or load the components of RSpec that you're not using.&lt;br /&gt;
== '''Problem Statement''' ==&lt;br /&gt;
Unfortunately, Expertiza tests are really slow. If you check the TravisCI, it needs nearly 9 min to run all tests.&lt;br /&gt;
 [[File:Expertiza test time.png]]&lt;br /&gt;
One reason is that we use fixture to create records in test DB each time running tests.&lt;br /&gt;
 &lt;br /&gt;
For example, the codes in quiz_spec.rb contain too much create so that prolong testing time.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
   # Create an assignment due date&lt;br /&gt;
    create(:deadline_type, name: &amp;quot;submission&amp;quot;)&lt;br /&gt;
    create(:deadline_type, name: &amp;quot;review&amp;quot;)&lt;br /&gt;
    create(:deadline_type, name: &amp;quot;metareview&amp;quot;)&lt;br /&gt;
    create(:deadline_type, name: &amp;quot;drop_topic&amp;quot;)&lt;br /&gt;
    create(:deadline_type, name: &amp;quot;signup&amp;quot;)&lt;br /&gt;
    create(:deadline_type, name: &amp;quot;team_formation&amp;quot;)&lt;br /&gt;
    create(:deadline_right)&lt;br /&gt;
    create(:deadline_right, name: 'Late')&lt;br /&gt;
    create(:deadline_right, name: 'OK')&lt;br /&gt;
    create :assignment_due_date, due_at: (DateTime.now + 1)&lt;br /&gt;
&amp;lt;/pre&amp;gt; &lt;br /&gt;
&lt;br /&gt;
One solution is building an complete database to support all RSpec test without creating new records.&lt;br /&gt;
&lt;br /&gt;
== '''Task''' ==&lt;br /&gt;
Formally, we need to:&lt;br /&gt;
* Create the records in test DB according to the content in fixtures.&lt;br /&gt;
* Check each test file and delete certain DB records creation code that insert default records (eg. create(:deadline_type)).&lt;br /&gt;
* And keep all the test cases passing when using test DB and make sure the time running test cases is shorter than before.&lt;br /&gt;
* You should submit the sql file of test DB to Expertiza.&lt;br /&gt;
To finish these tasks, we need to modify all RSpec test files in Expertiza and using a new Database:Expertiza_test.&lt;br /&gt;
&lt;br /&gt;
== Refactor files==&lt;br /&gt;
test database&lt;br /&gt;
&lt;br /&gt;
Rspec tests&lt;br /&gt;
&lt;br /&gt;
== '''Design''' ==&lt;br /&gt;
=== Design idea explanation ===&lt;br /&gt;
[[File: Design explanation.png]]&lt;br /&gt;
&lt;br /&gt;
In this design, we create a new database for testing, and we save some related information in this database. Every test just need to fetch data from this test database, and after the testing, we need to add some operation to rollback the data. For example,  if the test is about creating a new quiz, in this situation, we need to delete this quiz after this test. Because of it, the state of database can be saved, and also it will not influence other test or test this test case again.&lt;br /&gt;
&lt;br /&gt;
=== Database design ===&lt;br /&gt;
We design a expertiza_test database to save the test date used for Rspec. The test database owns the same structure as the real expertiza database, including the relations between tables and some restriction of attribute like it cannot be null or some other requirements for different attributes. Besides, the data in test database is the same as the data in factories part in spec, which includes FeedbackResponseMap.rb, Respone.rb, factories.rb, quiz_factory.rb. In this situation we do not need to create some data before testing, and we can use the data in test DB directly. Because of it, the overhead of testing cases will experience obvious decreasing.&lt;br /&gt;
like the Rspec statements in creating some User objects.:&lt;br /&gt;
  factory :admin, class: User do&lt;br /&gt;
    sequence(:name) {|n| &amp;quot;admin#{n}&amp;quot; }&lt;br /&gt;
    role { Role.where(name: 'Administrator').first || association(:role_of_administrator) }&lt;br /&gt;
    password &amp;quot;password&amp;quot;&lt;br /&gt;
    password_confirmation &amp;quot;password&amp;quot;&lt;br /&gt;
    sequence(:fullname) {|n| &amp;quot;#{n}, administrator&amp;quot; }&lt;br /&gt;
    email &amp;quot;expertiza@mailinator.com&amp;quot;&lt;br /&gt;
    parent_id 1&lt;br /&gt;
    private_by_default  false&lt;br /&gt;
    mru_directory_path  nil&lt;br /&gt;
    email_on_review true&lt;br /&gt;
    email_on_submission true&lt;br /&gt;
    email_on_review_of_review true&lt;br /&gt;
    is_new_user false&lt;br /&gt;
    master_permission_granted 0&lt;br /&gt;
    handle &amp;quot;handle&amp;quot;&lt;br /&gt;
    leaderboard_privacy false&lt;br /&gt;
    digital_certificate nil&lt;br /&gt;
    timezonepref nil&lt;br /&gt;
    public_key nil&lt;br /&gt;
    copy_of_emails  false&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
then transfer this into SQL query and then add the information the same as designed for Rspec test into expertiza_test database.&lt;br /&gt;
&lt;br /&gt;
We will try two method to achieve the goal:&lt;br /&gt;
# Write a script to create all test data automatically then don't clean the database.&lt;br /&gt;
# We transfer the data in girls_factory into the data base, and there are some steps:&lt;br /&gt;
1. we delete some related information in Rails_hepler.rb &lt;br /&gt;
&lt;br /&gt;
 config.before(:suite) do&lt;br /&gt;
    DatabaseCleaner.clean_with(:truncation)&lt;br /&gt;
  end&lt;br /&gt;
  config.before(:each) do |_example|&lt;br /&gt;
    DatabaseCleaner.strategy = :truncation&lt;br /&gt;
    DatabaseCleaner.start&lt;br /&gt;
  end&lt;br /&gt;
 &lt;br /&gt;
  config.after(:each) do&lt;br /&gt;
    DatabaseCleaner.clean&lt;br /&gt;
  end&lt;br /&gt;
Those statements is used for adding the technology to clean the database before everytime using Rspec test, and then also clean the database(using turncate to increase the time of cleaning database).&lt;br /&gt;
2. We generate a new create rb file, and in this file we just put the create statements in Rspec style function, like  create(:deadline_type, name: &amp;quot;submission&amp;quot;) to transfer the data into database when running rspec create.rb&lt;br /&gt;
&lt;br /&gt;
=== Feature test design ===&lt;br /&gt;
To accelerate the feature test, we have to eliminate pseudo data creation. Now all the feature tests must create their own data before each test. For an example, now a test first create a user before it can do the login operation. The creation latency is considerable. After building a test database, all the pseudo data creation statement can be removed from the test files. Instead, the tests reference data stored in the test database. This change will not only accelerate the testing time, but also dry out the code.&lt;br /&gt;
&lt;br /&gt;
The way tests reference data from database is the same as it does in the development mode.  To login, or do other operations, the test can invoke existing user data in test database. Using &amp;quot;User.find()&amp;quot; or &amp;quot;User.where()&amp;quot;, test data can easily be invoked by tests.&lt;br /&gt;
&lt;br /&gt;
For existing tests, they can directly use the test database. For new tests added later, they can use the records in test database or create specialized data use FactoryGirl. So to keep the test database up to date ,it needs to be maintained regularly.&lt;br /&gt;
&lt;br /&gt;
== ''' Modify feature test''' ==&lt;br /&gt;
&lt;br /&gt;
With test data in the database, we modified the RSpec feature test files:&lt;br /&gt;
1. Disable the data clean statement in rails_helper.rb.&lt;br /&gt;
  config.before(:suite) do&lt;br /&gt;
     DatabaseCleaner.clean_with(:truncation)&lt;br /&gt;
   end&lt;br /&gt;
   config.before(:each) do |_example|&lt;br /&gt;
     DatabaseCleaner.strategy = :truncation&lt;br /&gt;
     DatabaseCleaner.start&lt;br /&gt;
   end&lt;br /&gt;
  &lt;br /&gt;
   config.after(:each) do&lt;br /&gt;
     DatabaseCleaner.clean&lt;br /&gt;
   end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
2. Eliminate data creation statement in each test case.&lt;br /&gt;
Delete” create(:assignment)” like code&lt;br /&gt;
&lt;br /&gt;
3. Modify url visit statement.&lt;br /&gt;
Modify “visit '/student_teams/view?student_id=1'” &lt;br /&gt;
to &lt;br /&gt;
@student=User.find_by(name:”student2064”)&lt;br /&gt;
“visit '/student_teams/view?student_id=@student.id’”&lt;br /&gt;
&lt;br /&gt;
4. Recover test database before or after each change data operation&lt;br /&gt;
For tests involved with create or delete actions, the data modified should be rollback.&lt;br /&gt;
&lt;br /&gt;
== ''' The file we need to edit''' ==&lt;br /&gt;
&lt;br /&gt;
airbrake_expection_errors_feature_tests_spec.rb&lt;br /&gt;
&lt;br /&gt;
assignment_creation_spec.rb&lt;br /&gt;
&lt;br /&gt;
calibration_spec.rb&lt;br /&gt;
&lt;br /&gt;
inherit_teams_display_spec.rb&lt;br /&gt;
&lt;br /&gt;
instructor_interface_spec.rb&lt;br /&gt;
&lt;br /&gt;
list_teams_spec.rb&lt;br /&gt;
&lt;br /&gt;
questionnaire_spec.rb&lt;br /&gt;
&lt;br /&gt;
review_mapping_spec.rb&lt;br /&gt;
&lt;br /&gt;
staggered_deadline_spec.rb&lt;br /&gt;
&lt;br /&gt;
topic_suggestion_spec.rb&lt;br /&gt;
&lt;br /&gt;
==Performance improvement==&lt;br /&gt;
We run a single rspec test &amp;quot;airbrake_expection_errors_feature_tests_spec.rb&amp;quot; to test the performance improvement when using test database.&lt;br /&gt;
&lt;br /&gt;
Without a test database, the feature test costs 1:37 minutes:&lt;br /&gt;
 [[File:After refactor.png]]&lt;br /&gt;
Using the test database, the same test costs 1:10 minutes:&lt;br /&gt;
 [[File:Before refactor.png]]&lt;br /&gt;
The time is decreased by about 20%. Consider the browser's response time in both trial, the improvement &lt;br /&gt;
&lt;br /&gt;
Here is a video to show the improvement:&lt;br /&gt;
https://www.youtube.com/watch?v=9y0i-zSRHe8&amp;amp;feature=youtu.be&lt;/div&gt;</summary>
		<author><name>Jdeng8</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=File:After_refactor.png&amp;diff=106874</id>
		<title>File:After refactor.png</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=File:After_refactor.png&amp;diff=106874"/>
		<updated>2016-12-15T01:20:44Z</updated>

		<summary type="html">&lt;p&gt;Jdeng8: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Jdeng8</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=File:Before_refactor.png&amp;diff=106873</id>
		<title>File:Before refactor.png</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=File:Before_refactor.png&amp;diff=106873"/>
		<updated>2016-12-15T01:20:24Z</updated>

		<summary type="html">&lt;p&gt;Jdeng8: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Jdeng8</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2016/E1701._Accelerate_RSpec_testing&amp;diff=105602</id>
		<title>CSC/ECE 517 Fall 2016/E1701. Accelerate RSpec testing</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2016/E1701._Accelerate_RSpec_testing&amp;diff=105602"/>
		<updated>2016-11-14T18:56:44Z</updated>

		<summary type="html">&lt;p&gt;Jdeng8: /* Problem Statement */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== '''Expertiza''' ==&lt;br /&gt;
Expertiza is a web application where students can submit and peer-review learning objects (articles, code, web sites, etc). It is used in select courses at NC State and by professors at several other colleges and universities.&lt;br /&gt;
&lt;br /&gt;
== '''Rspec''' ==&lt;br /&gt;
Rspec is a meta-gem, which depends on the rspec-core, rspec-expectations and rspec-mocks gems. Each of these can be installed separately and loaded in isolation using require. Among other benefits, this allows you to use rspec-expectations, for example, in Test::Unit::TestCase if you happen to prefer that style.&lt;br /&gt;
Conversely, if you like RSpec's approach to declaring example groups and examples (describe and it) but prefer Test::Unit assertions and mocha, rr or flexmock for mocking, you'll be able to do that without having to install or load the components of RSpec that you're not using.&lt;br /&gt;
== '''Problem Statement''' ==&lt;br /&gt;
Unfortunately, Expertiza tests are really slow. If you check the TravisCI, it needs nearly 9 min to run all tests.&lt;br /&gt;
 [[File:Expertiza test time.png]]&lt;br /&gt;
One reason is that we use fixture to create records in test DB each time running tests.&lt;br /&gt;
 &lt;br /&gt;
For example, the codes in quiz_spec.rb contain too much create so that prolong testing time.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
   # Create an assignment due date&lt;br /&gt;
    create(:deadline_type, name: &amp;quot;submission&amp;quot;)&lt;br /&gt;
    create(:deadline_type, name: &amp;quot;review&amp;quot;)&lt;br /&gt;
    create(:deadline_type, name: &amp;quot;metareview&amp;quot;)&lt;br /&gt;
    create(:deadline_type, name: &amp;quot;drop_topic&amp;quot;)&lt;br /&gt;
    create(:deadline_type, name: &amp;quot;signup&amp;quot;)&lt;br /&gt;
    create(:deadline_type, name: &amp;quot;team_formation&amp;quot;)&lt;br /&gt;
    create(:deadline_right)&lt;br /&gt;
    create(:deadline_right, name: 'Late')&lt;br /&gt;
    create(:deadline_right, name: 'OK')&lt;br /&gt;
    create :assignment_due_date, due_at: (DateTime.now + 1)&lt;br /&gt;
&amp;lt;/pre&amp;gt; &lt;br /&gt;
&lt;br /&gt;
One solution is building an complete database to support all RSpec test without creating new records.&lt;br /&gt;
&lt;br /&gt;
== '''Task''' ==&lt;br /&gt;
Formally, we need to:&lt;br /&gt;
* Create the records in test DB according to the content in fixtures.&lt;br /&gt;
* Check each test file and delete certain DB records creation code that insert default records (eg. create(:deadline_type)).&lt;br /&gt;
* And keep all the test cases passing when using test DB and make sure the time running test cases is shorter than before.&lt;br /&gt;
* You should submit the sql file of test DB to Expertiza.&lt;br /&gt;
To finish these tasks, we need to modify all RSpec test files in Expertiza and using a new Database:Expertiza_test.&lt;br /&gt;
&lt;br /&gt;
== Refactor files==&lt;br /&gt;
test database&lt;br /&gt;
&lt;br /&gt;
Rspec tests&lt;br /&gt;
&lt;br /&gt;
== '''Design''' ==&lt;br /&gt;
=== Database design ===&lt;br /&gt;
We design a expertiza_test database to save the test date used for Rspec. The test database owns the same structure as the real expertiza database, including the relations between tables and some restriction of attribute like it cannot be null or some other requirements for different attributes. Besides, the data in test database is the same as the data in factories part in spec, which includes FeedbackResponseMap.rb, Respone.rb, factories.rb, quiz_factory.rb. In this situation we do not need to create some data before testing, and we can use the data in test DB directly. Because of it, the overhead of testing cases will experience obvious decreasing.&lt;br /&gt;
like the Rspec statements in creating some User objects.:&lt;br /&gt;
  factory :admin, class: User do&lt;br /&gt;
    sequence(:name) {|n| &amp;quot;admin#{n}&amp;quot; }&lt;br /&gt;
    role { Role.where(name: 'Administrator').first || association(:role_of_administrator) }&lt;br /&gt;
    password &amp;quot;password&amp;quot;&lt;br /&gt;
    password_confirmation &amp;quot;password&amp;quot;&lt;br /&gt;
    sequence(:fullname) {|n| &amp;quot;#{n}, administrator&amp;quot; }&lt;br /&gt;
    email &amp;quot;expertiza@mailinator.com&amp;quot;&lt;br /&gt;
    parent_id 1&lt;br /&gt;
    private_by_default  false&lt;br /&gt;
    mru_directory_path  nil&lt;br /&gt;
    email_on_review true&lt;br /&gt;
    email_on_submission true&lt;br /&gt;
    email_on_review_of_review true&lt;br /&gt;
    is_new_user false&lt;br /&gt;
    master_permission_granted 0&lt;br /&gt;
    handle &amp;quot;handle&amp;quot;&lt;br /&gt;
    leaderboard_privacy false&lt;br /&gt;
    digital_certificate nil&lt;br /&gt;
    timezonepref nil&lt;br /&gt;
    public_key nil&lt;br /&gt;
    copy_of_emails  false&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
then transfer this into SQL query and then add the information the same as designed for Rspec test into expertiza_test database.&lt;br /&gt;
&lt;br /&gt;
We will try two method to achieve the goal:&lt;br /&gt;
# Write a script to create all test data automatically then don't clean the database.&lt;br /&gt;
# Build the database manually using SQL:&lt;br /&gt;
  INSERT INTO User VALUES (xxxxx, xxxxxx, xxxxx, xxxxxxxx, xxxxxxx, xxxxxxx, xxxx );&lt;br /&gt;
&lt;br /&gt;
=== Feature test design ===&lt;br /&gt;
To accelerate the feature test, we have to eliminate pseudo data creation. Now all the feature tests must create their own data before each test. For an example, now a test first create a user before it can do the login operation. The creation latency is considerable. After building a test database, all the pseudo data creation statement can be removed from the test files. Instead, the tests reference data stored in the test database. This change will not only accelerate the testing time, but also dry out the code.&lt;br /&gt;
&lt;br /&gt;
The way tests reference data from database is the same as it does in the development mode.  To login, or do other operations, the test can invoke existing user data in test database. Using &amp;quot;User.find()&amp;quot; or &amp;quot;User.where()&amp;quot;, test data can easily be invoked by tests.&lt;br /&gt;
&lt;br /&gt;
For existing tests, they can directly use the test database. For new tests added later, they can use the records in test database or create specialized data use FactoryGirl. So to keep the test database up to date ,it needs to be maintained regularly.&lt;/div&gt;</summary>
		<author><name>Jdeng8</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2016/E1701._Accelerate_RSpec_testing&amp;diff=105601</id>
		<title>CSC/ECE 517 Fall 2016/E1701. Accelerate RSpec testing</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2016/E1701._Accelerate_RSpec_testing&amp;diff=105601"/>
		<updated>2016-11-14T18:54:38Z</updated>

		<summary type="html">&lt;p&gt;Jdeng8: /* Database design */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== '''Expertiza''' ==&lt;br /&gt;
Expertiza is a web application where students can submit and peer-review learning objects (articles, code, web sites, etc). It is used in select courses at NC State and by professors at several other colleges and universities.&lt;br /&gt;
&lt;br /&gt;
== '''Rspec''' ==&lt;br /&gt;
Rspec is a meta-gem, which depends on the rspec-core, rspec-expectations and rspec-mocks gems. Each of these can be installed separately and loaded in isolation using require. Among other benefits, this allows you to use rspec-expectations, for example, in Test::Unit::TestCase if you happen to prefer that style.&lt;br /&gt;
Conversely, if you like RSpec's approach to declaring example groups and examples (describe and it) but prefer Test::Unit assertions and mocha, rr or flexmock for mocking, you'll be able to do that without having to install or load the components of RSpec that you're not using.&lt;br /&gt;
== '''Problem Statement''' ==&lt;br /&gt;
Unfortunately, Expertiza tests are really slow. If you check the TravisCI, it needs more than 9 min to run all tests.&lt;br /&gt;
 [[File:Expertiza test time.png]]&lt;br /&gt;
One reason is that we use fixture to create records in test DB each time running tests.&lt;br /&gt;
 &lt;br /&gt;
For example, the codes in quiz_spec.rb contain too much create so that prolong testing time.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
   # Create an assignment due date&lt;br /&gt;
    create(:deadline_type, name: &amp;quot;submission&amp;quot;)&lt;br /&gt;
    create(:deadline_type, name: &amp;quot;review&amp;quot;)&lt;br /&gt;
    create(:deadline_type, name: &amp;quot;metareview&amp;quot;)&lt;br /&gt;
    create(:deadline_type, name: &amp;quot;drop_topic&amp;quot;)&lt;br /&gt;
    create(:deadline_type, name: &amp;quot;signup&amp;quot;)&lt;br /&gt;
    create(:deadline_type, name: &amp;quot;team_formation&amp;quot;)&lt;br /&gt;
    create(:deadline_right)&lt;br /&gt;
    create(:deadline_right, name: 'Late')&lt;br /&gt;
    create(:deadline_right, name: 'OK')&lt;br /&gt;
    create :assignment_due_date, due_at: (DateTime.now + 1)&lt;br /&gt;
&amp;lt;/pre&amp;gt; &lt;br /&gt;
&lt;br /&gt;
One solution is building an complete database to support all RSpec test without creating new records.&lt;br /&gt;
&lt;br /&gt;
== '''Task''' ==&lt;br /&gt;
Formally, we need to:&lt;br /&gt;
* Create the records in test DB according to the content in fixtures.&lt;br /&gt;
* Check each test file and delete certain DB records creation code that insert default records (eg. create(:deadline_type)).&lt;br /&gt;
* And keep all the test cases passing when using test DB and make sure the time running test cases is shorter than before.&lt;br /&gt;
* You should submit the sql file of test DB to Expertiza.&lt;br /&gt;
To finish these tasks, we need to modify all RSpec test files in Expertiza and using a new Database:Expertiza_test.&lt;br /&gt;
&lt;br /&gt;
== Refactor files==&lt;br /&gt;
test database&lt;br /&gt;
&lt;br /&gt;
Rspec tests&lt;br /&gt;
&lt;br /&gt;
== '''Design''' ==&lt;br /&gt;
=== Database design ===&lt;br /&gt;
We design a expertiza_test database to save the test date used for Rspec. The test database owns the same structure as the real expertiza database, including the relations between tables and some restriction of attribute like it cannot be null or some other requirements for different attributes. Besides, the data in test database is the same as the data in factories part in spec, which includes FeedbackResponseMap.rb, Respone.rb, factories.rb, quiz_factory.rb. In this situation we do not need to create some data before testing, and we can use the data in test DB directly. Because of it, the overhead of testing cases will experience obvious decreasing.&lt;br /&gt;
like the Rspec statements in creating some User objects.:&lt;br /&gt;
  factory :admin, class: User do&lt;br /&gt;
    sequence(:name) {|n| &amp;quot;admin#{n}&amp;quot; }&lt;br /&gt;
    role { Role.where(name: 'Administrator').first || association(:role_of_administrator) }&lt;br /&gt;
    password &amp;quot;password&amp;quot;&lt;br /&gt;
    password_confirmation &amp;quot;password&amp;quot;&lt;br /&gt;
    sequence(:fullname) {|n| &amp;quot;#{n}, administrator&amp;quot; }&lt;br /&gt;
    email &amp;quot;expertiza@mailinator.com&amp;quot;&lt;br /&gt;
    parent_id 1&lt;br /&gt;
    private_by_default  false&lt;br /&gt;
    mru_directory_path  nil&lt;br /&gt;
    email_on_review true&lt;br /&gt;
    email_on_submission true&lt;br /&gt;
    email_on_review_of_review true&lt;br /&gt;
    is_new_user false&lt;br /&gt;
    master_permission_granted 0&lt;br /&gt;
    handle &amp;quot;handle&amp;quot;&lt;br /&gt;
    leaderboard_privacy false&lt;br /&gt;
    digital_certificate nil&lt;br /&gt;
    timezonepref nil&lt;br /&gt;
    public_key nil&lt;br /&gt;
    copy_of_emails  false&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
then transfer this into SQL query and then add the information the same as designed for Rspec test into expertiza_test database.&lt;br /&gt;
&lt;br /&gt;
We will try two method to achieve the goal:&lt;br /&gt;
# Write a script to create all test data automatically then don't clean the database.&lt;br /&gt;
# Build the database manually using SQL:&lt;br /&gt;
  INSERT INTO User VALUES (xxxxx, xxxxxx, xxxxx, xxxxxxxx, xxxxxxx, xxxxxxx, xxxx );&lt;br /&gt;
&lt;br /&gt;
=== Feature test design ===&lt;br /&gt;
To accelerate the feature test, we have to eliminate pseudo data creation. Now all the feature tests must create their own data before each test. For an example, now a test first create a user before it can do the login operation. The creation latency is considerable. After building a test database, all the pseudo data creation statement can be removed from the test files. Instead, the tests reference data stored in the test database. This change will not only accelerate the testing time, but also dry out the code.&lt;br /&gt;
&lt;br /&gt;
The way tests reference data from database is the same as it does in the development mode.  To login, or do other operations, the test can invoke existing user data in test database. Using &amp;quot;User.find()&amp;quot; or &amp;quot;User.where()&amp;quot;, test data can easily be invoked by tests.&lt;br /&gt;
&lt;br /&gt;
For existing tests, they can directly use the test database. For new tests added later, they can use the records in test database or create specialized data use FactoryGirl. So to keep the test database up to date ,it needs to be maintained regularly.&lt;/div&gt;</summary>
		<author><name>Jdeng8</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2016/E1701._Accelerate_RSpec_testing&amp;diff=105600</id>
		<title>CSC/ECE 517 Fall 2016/E1701. Accelerate RSpec testing</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2016/E1701._Accelerate_RSpec_testing&amp;diff=105600"/>
		<updated>2016-11-14T18:54:19Z</updated>

		<summary type="html">&lt;p&gt;Jdeng8: /* Database design */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== '''Expertiza''' ==&lt;br /&gt;
Expertiza is a web application where students can submit and peer-review learning objects (articles, code, web sites, etc). It is used in select courses at NC State and by professors at several other colleges and universities.&lt;br /&gt;
&lt;br /&gt;
== '''Rspec''' ==&lt;br /&gt;
Rspec is a meta-gem, which depends on the rspec-core, rspec-expectations and rspec-mocks gems. Each of these can be installed separately and loaded in isolation using require. Among other benefits, this allows you to use rspec-expectations, for example, in Test::Unit::TestCase if you happen to prefer that style.&lt;br /&gt;
Conversely, if you like RSpec's approach to declaring example groups and examples (describe and it) but prefer Test::Unit assertions and mocha, rr or flexmock for mocking, you'll be able to do that without having to install or load the components of RSpec that you're not using.&lt;br /&gt;
== '''Problem Statement''' ==&lt;br /&gt;
Unfortunately, Expertiza tests are really slow. If you check the TravisCI, it needs more than 9 min to run all tests.&lt;br /&gt;
 [[File:Expertiza test time.png]]&lt;br /&gt;
One reason is that we use fixture to create records in test DB each time running tests.&lt;br /&gt;
 &lt;br /&gt;
For example, the codes in quiz_spec.rb contain too much create so that prolong testing time.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
   # Create an assignment due date&lt;br /&gt;
    create(:deadline_type, name: &amp;quot;submission&amp;quot;)&lt;br /&gt;
    create(:deadline_type, name: &amp;quot;review&amp;quot;)&lt;br /&gt;
    create(:deadline_type, name: &amp;quot;metareview&amp;quot;)&lt;br /&gt;
    create(:deadline_type, name: &amp;quot;drop_topic&amp;quot;)&lt;br /&gt;
    create(:deadline_type, name: &amp;quot;signup&amp;quot;)&lt;br /&gt;
    create(:deadline_type, name: &amp;quot;team_formation&amp;quot;)&lt;br /&gt;
    create(:deadline_right)&lt;br /&gt;
    create(:deadline_right, name: 'Late')&lt;br /&gt;
    create(:deadline_right, name: 'OK')&lt;br /&gt;
    create :assignment_due_date, due_at: (DateTime.now + 1)&lt;br /&gt;
&amp;lt;/pre&amp;gt; &lt;br /&gt;
&lt;br /&gt;
One solution is building an complete database to support all RSpec test without creating new records.&lt;br /&gt;
&lt;br /&gt;
== '''Task''' ==&lt;br /&gt;
Formally, we need to:&lt;br /&gt;
* Create the records in test DB according to the content in fixtures.&lt;br /&gt;
* Check each test file and delete certain DB records creation code that insert default records (eg. create(:deadline_type)).&lt;br /&gt;
* And keep all the test cases passing when using test DB and make sure the time running test cases is shorter than before.&lt;br /&gt;
* You should submit the sql file of test DB to Expertiza.&lt;br /&gt;
To finish these tasks, we need to modify all RSpec test files in Expertiza and using a new Database:Expertiza_test.&lt;br /&gt;
&lt;br /&gt;
== Refactor files==&lt;br /&gt;
test database&lt;br /&gt;
&lt;br /&gt;
Rspec tests&lt;br /&gt;
&lt;br /&gt;
== '''Design''' ==&lt;br /&gt;
=== Database design ===&lt;br /&gt;
We design a expertiza_test database to save the test date used for Rspec. The test database owns the same structure as the real expertiza database, including the relations between tables and some restriction of attribute like it cannot be null or some other requirements for different attributes. Besides, the data in test database is the same as the data in factories part in spec, which includes FeedbackResponseMap.rb, Respone.rb, factories.rb, quiz_factory.rb. In this situation we do not need to create some data before testing, and we can use the data in test DB directly. Because of it, the overhead of testing cases will experience obvious decreasing.&lt;br /&gt;
like the Rspec statements in creating some User objects.:&lt;br /&gt;
  factory :admin, class: User do&lt;br /&gt;
    sequence(:name) {|n| &amp;quot;admin#{n}&amp;quot; }&lt;br /&gt;
    role { Role.where(name: 'Administrator').first || association(:role_of_administrator) }&lt;br /&gt;
    password &amp;quot;password&amp;quot;&lt;br /&gt;
    password_confirmation &amp;quot;password&amp;quot;&lt;br /&gt;
    sequence(:fullname) {|n| &amp;quot;#{n}, administrator&amp;quot; }&lt;br /&gt;
    email &amp;quot;expertiza@mailinator.com&amp;quot;&lt;br /&gt;
    parent_id 1&lt;br /&gt;
    private_by_default  false&lt;br /&gt;
    mru_directory_path  nil&lt;br /&gt;
    email_on_review true&lt;br /&gt;
    email_on_submission true&lt;br /&gt;
    email_on_review_of_review true&lt;br /&gt;
    is_new_user false&lt;br /&gt;
    master_permission_granted 0&lt;br /&gt;
    handle &amp;quot;handle&amp;quot;&lt;br /&gt;
    leaderboard_privacy false&lt;br /&gt;
    digital_certificate nil&lt;br /&gt;
    timezonepref nil&lt;br /&gt;
    public_key nil&lt;br /&gt;
    copy_of_emails  false&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
then transfer this into SQL query and then add the information the same as designed for Rspec test into expertiza_test database.&lt;br /&gt;
&lt;br /&gt;
We will try two method to achieve the goal:&lt;br /&gt;
# Write a script to create all test data automatically then don't clean the database.&lt;br /&gt;
# Build the database manually using SQL:&lt;br /&gt;
INSERT INTO User VALUES (xxxxx, xxxxxx, xxxxx, xxxxxxxx, xxxxxxx, xxxxxxx, xxxx );&lt;br /&gt;
&lt;br /&gt;
=== Feature test design ===&lt;br /&gt;
To accelerate the feature test, we have to eliminate pseudo data creation. Now all the feature tests must create their own data before each test. For an example, now a test first create a user before it can do the login operation. The creation latency is considerable. After building a test database, all the pseudo data creation statement can be removed from the test files. Instead, the tests reference data stored in the test database. This change will not only accelerate the testing time, but also dry out the code.&lt;br /&gt;
&lt;br /&gt;
The way tests reference data from database is the same as it does in the development mode.  To login, or do other operations, the test can invoke existing user data in test database. Using &amp;quot;User.find()&amp;quot; or &amp;quot;User.where()&amp;quot;, test data can easily be invoked by tests.&lt;br /&gt;
&lt;br /&gt;
For existing tests, they can directly use the test database. For new tests added later, they can use the records in test database or create specialized data use FactoryGirl. So to keep the test database up to date ,it needs to be maintained regularly.&lt;/div&gt;</summary>
		<author><name>Jdeng8</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=File:Expertiza_test_time.png&amp;diff=105599</id>
		<title>File:Expertiza test time.png</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=File:Expertiza_test_time.png&amp;diff=105599"/>
		<updated>2016-11-14T18:46:27Z</updated>

		<summary type="html">&lt;p&gt;Jdeng8: uploaded a new version of &amp;amp;quot;File:Expertiza test time.png&amp;amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Jdeng8</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2016/E1701._Accelerate_RSpec_testing&amp;diff=105598</id>
		<title>CSC/ECE 517 Fall 2016/E1701. Accelerate RSpec testing</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2016/E1701._Accelerate_RSpec_testing&amp;diff=105598"/>
		<updated>2016-11-14T18:44:04Z</updated>

		<summary type="html">&lt;p&gt;Jdeng8: /* Problem Statement */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== '''Expertiza''' ==&lt;br /&gt;
Expertiza is a web application where students can submit and peer-review learning objects (articles, code, web sites, etc). It is used in select courses at NC State and by professors at several other colleges and universities.&lt;br /&gt;
&lt;br /&gt;
== '''Rspec''' ==&lt;br /&gt;
Rspec is a meta-gem, which depends on the rspec-core, rspec-expectations and rspec-mocks gems. Each of these can be installed separately and loaded in isolation using require. Among other benefits, this allows you to use rspec-expectations, for example, in Test::Unit::TestCase if you happen to prefer that style.&lt;br /&gt;
Conversely, if you like RSpec's approach to declaring example groups and examples (describe and it) but prefer Test::Unit assertions and mocha, rr or flexmock for mocking, you'll be able to do that without having to install or load the components of RSpec that you're not using.&lt;br /&gt;
== '''Problem Statement''' ==&lt;br /&gt;
Unfortunately, Expertiza tests are really slow. If you check the TravisCI, it needs more than 9 min to run all tests.&lt;br /&gt;
 [[File:Expertiza test time.png]]&lt;br /&gt;
One reason is that we use fixture to create records in test DB each time running tests.&lt;br /&gt;
 &lt;br /&gt;
For example, the codes in quiz_spec.rb contain too much create so that prolong testing time.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
   # Create an assignment due date&lt;br /&gt;
    create(:deadline_type, name: &amp;quot;submission&amp;quot;)&lt;br /&gt;
    create(:deadline_type, name: &amp;quot;review&amp;quot;)&lt;br /&gt;
    create(:deadline_type, name: &amp;quot;metareview&amp;quot;)&lt;br /&gt;
    create(:deadline_type, name: &amp;quot;drop_topic&amp;quot;)&lt;br /&gt;
    create(:deadline_type, name: &amp;quot;signup&amp;quot;)&lt;br /&gt;
    create(:deadline_type, name: &amp;quot;team_formation&amp;quot;)&lt;br /&gt;
    create(:deadline_right)&lt;br /&gt;
    create(:deadline_right, name: 'Late')&lt;br /&gt;
    create(:deadline_right, name: 'OK')&lt;br /&gt;
    create :assignment_due_date, due_at: (DateTime.now + 1)&lt;br /&gt;
&amp;lt;/pre&amp;gt; &lt;br /&gt;
&lt;br /&gt;
One solution is building an complete database to support all RSpec test without creating new records.&lt;br /&gt;
&lt;br /&gt;
== '''Task''' ==&lt;br /&gt;
Formally, we need to:&lt;br /&gt;
* Create the records in test DB according to the content in fixtures.&lt;br /&gt;
* Check each test file and delete certain DB records creation code that insert default records (eg. create(:deadline_type)).&lt;br /&gt;
* And keep all the test cases passing when using test DB and make sure the time running test cases is shorter than before.&lt;br /&gt;
* You should submit the sql file of test DB to Expertiza.&lt;br /&gt;
To finish these tasks, we need to modify all RSpec test files in Expertiza and using a new Database:Expertiza_test.&lt;br /&gt;
&lt;br /&gt;
== Refactor files==&lt;br /&gt;
test database&lt;br /&gt;
&lt;br /&gt;
Rspec tests&lt;br /&gt;
&lt;br /&gt;
== '''Design''' ==&lt;br /&gt;
=== Database design ===&lt;br /&gt;
We design a expertiza_test database to save the test date used for Rspec. The test database owns the same structure as the real expertiza database, including the relations between tables and some restriction of attribute like it cannot be null or some other requirements for different attributes. Besides, the data in test database is the same as the data in factories part in spec, which includes FeedbackResponseMap.rb, Respone.rb, factories.rb, quiz_factory.rb. In this situation we do not need to create some data before testing, and we can use the data in test DB directly. Because of it, the overhead of testing cases will experience obvious decreasing.&lt;br /&gt;
like the Rspec statements in creating some User objects.:&lt;br /&gt;
  factory :admin, class: User do&lt;br /&gt;
    sequence(:name) {|n| &amp;quot;admin#{n}&amp;quot; }&lt;br /&gt;
    role { Role.where(name: 'Administrator').first || association(:role_of_administrator) }&lt;br /&gt;
    password &amp;quot;password&amp;quot;&lt;br /&gt;
    password_confirmation &amp;quot;password&amp;quot;&lt;br /&gt;
    sequence(:fullname) {|n| &amp;quot;#{n}, administrator&amp;quot; }&lt;br /&gt;
    email &amp;quot;expertiza@mailinator.com&amp;quot;&lt;br /&gt;
    parent_id 1&lt;br /&gt;
    private_by_default  false&lt;br /&gt;
    mru_directory_path  nil&lt;br /&gt;
    email_on_review true&lt;br /&gt;
    email_on_submission true&lt;br /&gt;
    email_on_review_of_review true&lt;br /&gt;
    is_new_user false&lt;br /&gt;
    master_permission_granted 0&lt;br /&gt;
    handle &amp;quot;handle&amp;quot;&lt;br /&gt;
    leaderboard_privacy false&lt;br /&gt;
    digital_certificate nil&lt;br /&gt;
    timezonepref nil&lt;br /&gt;
    public_key nil&lt;br /&gt;
    copy_of_emails  false&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
then transfer this into SQL query and then add the information the same as designed for Rspec test into expertiza_test database.&lt;br /&gt;
INSERT INTO User VALUES (xxxxx, xxxxxx, xxxxx, xxxxxxxx, xxxxxxx, xxxxxxx, xxxx );&lt;br /&gt;
&lt;br /&gt;
=== Feature test design ===&lt;br /&gt;
To accelerate the feature test, we have to eliminate pseudo data creation. Now all the feature tests must create their own data before each test. For an example, now a test first create a user before it can do the login operation. The creation latency is considerable. After building a test database, all the pseudo data creation statement can be removed from the test files. Instead, the tests reference data stored in the test database. This change will not only accelerate the testing time, but also dry out the code.&lt;br /&gt;
&lt;br /&gt;
The way tests reference data from database is the same as it does in the development mode.  To login, or do other operations, the test can invoke existing user data in test database. Using &amp;quot;User.find()&amp;quot; or &amp;quot;User.where()&amp;quot;, test data can easily be invoked by tests.&lt;br /&gt;
&lt;br /&gt;
For existing tests, they can directly use the test database. For new tests added later, they can use the records in test database or create specialized data use FactoryGirl. So to keep the test database up to date ,it needs to be maintained regularly.&lt;/div&gt;</summary>
		<author><name>Jdeng8</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=File:Expertiza_test_time.png&amp;diff=105597</id>
		<title>File:Expertiza test time.png</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=File:Expertiza_test_time.png&amp;diff=105597"/>
		<updated>2016-11-14T18:43:19Z</updated>

		<summary type="html">&lt;p&gt;Jdeng8: uploaded a new version of &amp;amp;quot;File:Expertiza test time.png&amp;amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Jdeng8</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2016/E1701._Accelerate_RSpec_testing&amp;diff=105596</id>
		<title>CSC/ECE 517 Fall 2016/E1701. Accelerate RSpec testing</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2016/E1701._Accelerate_RSpec_testing&amp;diff=105596"/>
		<updated>2016-11-14T18:39:31Z</updated>

		<summary type="html">&lt;p&gt;Jdeng8: /* Problem Statement */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== '''Expertiza''' ==&lt;br /&gt;
Expertiza is a web application where students can submit and peer-review learning objects (articles, code, web sites, etc). It is used in select courses at NC State and by professors at several other colleges and universities.&lt;br /&gt;
&lt;br /&gt;
== '''Rspec''' ==&lt;br /&gt;
Rspec is a meta-gem, which depends on the rspec-core, rspec-expectations and rspec-mocks gems. Each of these can be installed separately and loaded in isolation using require. Among other benefits, this allows you to use rspec-expectations, for example, in Test::Unit::TestCase if you happen to prefer that style.&lt;br /&gt;
Conversely, if you like RSpec's approach to declaring example groups and examples (describe and it) but prefer Test::Unit assertions and mocha, rr or flexmock for mocking, you'll be able to do that without having to install or load the components of RSpec that you're not using.&lt;br /&gt;
== '''Problem Statement''' ==&lt;br /&gt;
Unfortunately, Expertiza tests are really slow. If you check the TravisCI, it needs more than 9 min to run all tests.&lt;br /&gt;
 [[File:Example.jpg]]&lt;br /&gt;
One reason is that we use fixture to create records in test DB each time running tests.&lt;br /&gt;
 &lt;br /&gt;
For example, the codes in quiz_spec.rb contain too much create so that prolong testing time.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
   # Create an assignment due date&lt;br /&gt;
    create(:deadline_type, name: &amp;quot;submission&amp;quot;)&lt;br /&gt;
    create(:deadline_type, name: &amp;quot;review&amp;quot;)&lt;br /&gt;
    create(:deadline_type, name: &amp;quot;metareview&amp;quot;)&lt;br /&gt;
    create(:deadline_type, name: &amp;quot;drop_topic&amp;quot;)&lt;br /&gt;
    create(:deadline_type, name: &amp;quot;signup&amp;quot;)&lt;br /&gt;
    create(:deadline_type, name: &amp;quot;team_formation&amp;quot;)&lt;br /&gt;
    create(:deadline_right)&lt;br /&gt;
    create(:deadline_right, name: 'Late')&lt;br /&gt;
    create(:deadline_right, name: 'OK')&lt;br /&gt;
    create :assignment_due_date, due_at: (DateTime.now + 1)&lt;br /&gt;
&amp;lt;/pre&amp;gt; &lt;br /&gt;
&lt;br /&gt;
One solution is building an complete database to support all RSpec test without creating new records.&lt;br /&gt;
&lt;br /&gt;
== '''Task''' ==&lt;br /&gt;
Formally, we need to:&lt;br /&gt;
* Create the records in test DB according to the content in fixtures.&lt;br /&gt;
* Check each test file and delete certain DB records creation code that insert default records (eg. create(:deadline_type)).&lt;br /&gt;
* And keep all the test cases passing when using test DB and make sure the time running test cases is shorter than before.&lt;br /&gt;
* You should submit the sql file of test DB to Expertiza.&lt;br /&gt;
To finish these tasks, we need to modify all RSpec test files in Expertiza and using a new Database:Expertiza_test.&lt;br /&gt;
&lt;br /&gt;
== Refactor files==&lt;br /&gt;
test database&lt;br /&gt;
&lt;br /&gt;
Rspec tests&lt;br /&gt;
&lt;br /&gt;
== '''Design''' ==&lt;br /&gt;
=== Database design ===&lt;br /&gt;
We design a expertiza_test database to save the test date used for Rspec. The test database owns the same structure as the real expertiza database, including the relations between tables and some restriction of attribute like it cannot be null or some other requirements for different attributes. Besides, the data in test database is the same as the data in factories part in spec, which includes FeedbackResponseMap.rb, Respone.rb, factories.rb, quiz_factory.rb. In this situation we do not need to create some data before testing, and we can use the data in test DB directly. Because of it, the overhead of testing cases will experience obvious decreasing.&lt;br /&gt;
like the Rspec statements in creating some User objects.:&lt;br /&gt;
  factory :admin, class: User do&lt;br /&gt;
    sequence(:name) {|n| &amp;quot;admin#{n}&amp;quot; }&lt;br /&gt;
    role { Role.where(name: 'Administrator').first || association(:role_of_administrator) }&lt;br /&gt;
    password &amp;quot;password&amp;quot;&lt;br /&gt;
    password_confirmation &amp;quot;password&amp;quot;&lt;br /&gt;
    sequence(:fullname) {|n| &amp;quot;#{n}, administrator&amp;quot; }&lt;br /&gt;
    email &amp;quot;expertiza@mailinator.com&amp;quot;&lt;br /&gt;
    parent_id 1&lt;br /&gt;
    private_by_default  false&lt;br /&gt;
    mru_directory_path  nil&lt;br /&gt;
    email_on_review true&lt;br /&gt;
    email_on_submission true&lt;br /&gt;
    email_on_review_of_review true&lt;br /&gt;
    is_new_user false&lt;br /&gt;
    master_permission_granted 0&lt;br /&gt;
    handle &amp;quot;handle&amp;quot;&lt;br /&gt;
    leaderboard_privacy false&lt;br /&gt;
    digital_certificate nil&lt;br /&gt;
    timezonepref nil&lt;br /&gt;
    public_key nil&lt;br /&gt;
    copy_of_emails  false&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
then transfer this into SQL query and then add the information the same as designed for Rspec test into expertiza_test database.&lt;br /&gt;
INSERT INTO User VALUES (xxxxx, xxxxxx, xxxxx, xxxxxxxx, xxxxxxx, xxxxxxx, xxxx );&lt;br /&gt;
&lt;br /&gt;
=== Feature test design ===&lt;br /&gt;
To accelerate the feature test, we have to eliminate pseudo data creation. Now all the feature tests must create their own data before each test. For an example, now a test first create a user before it can do the login operation. The creation latency is considerable. After building a test database, all the pseudo data creation statement can be removed from the test files. Instead, the tests reference data stored in the test database. This change will not only accelerate the testing time, but also dry out the code.&lt;br /&gt;
&lt;br /&gt;
The way tests reference data from database is the same as it does in the development mode.  To login, or do other operations, the test can invoke existing user data in test database. Using &amp;quot;User.find()&amp;quot; or &amp;quot;User.where()&amp;quot;, test data can easily be invoked by tests.&lt;br /&gt;
&lt;br /&gt;
For existing tests, they can directly use the test database. For new tests added later, they can use the records in test database or create specialized data use FactoryGirl. So to keep the test database up to date ,it needs to be maintained regularly.&lt;/div&gt;</summary>
		<author><name>Jdeng8</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2016/E1701._Accelerate_RSpec_testing&amp;diff=105595</id>
		<title>CSC/ECE 517 Fall 2016/E1701. Accelerate RSpec testing</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2016/E1701._Accelerate_RSpec_testing&amp;diff=105595"/>
		<updated>2016-11-14T18:36:12Z</updated>

		<summary type="html">&lt;p&gt;Jdeng8: /* Feature test design */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== '''Expertiza''' ==&lt;br /&gt;
Expertiza is a web application where students can submit and peer-review learning objects (articles, code, web sites, etc). It is used in select courses at NC State and by professors at several other colleges and universities.&lt;br /&gt;
&lt;br /&gt;
== '''Rspec''' ==&lt;br /&gt;
Rspec is a meta-gem, which depends on the rspec-core, rspec-expectations and rspec-mocks gems. Each of these can be installed separately and loaded in isolation using require. Among other benefits, this allows you to use rspec-expectations, for example, in Test::Unit::TestCase if you happen to prefer that style.&lt;br /&gt;
Conversely, if you like RSpec's approach to declaring example groups and examples (describe and it) but prefer Test::Unit assertions and mocha, rr or flexmock for mocking, you'll be able to do that without having to install or load the components of RSpec that you're not using.&lt;br /&gt;
== '''Problem Statement''' ==&lt;br /&gt;
Unfortunately, Expertiza tests are really slow. If you check the TravisCI, it needs more than 9 min to run all tests.&lt;br /&gt;
 &lt;br /&gt;
One reason is that we use fixture to create records in test DB each time running tests.&lt;br /&gt;
 &lt;br /&gt;
For example, the codes in quiz_spec.rb contain too much create so that prolong testing time.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
   # Create an assignment due date&lt;br /&gt;
    create(:deadline_type, name: &amp;quot;submission&amp;quot;)&lt;br /&gt;
    create(:deadline_type, name: &amp;quot;review&amp;quot;)&lt;br /&gt;
    create(:deadline_type, name: &amp;quot;metareview&amp;quot;)&lt;br /&gt;
    create(:deadline_type, name: &amp;quot;drop_topic&amp;quot;)&lt;br /&gt;
    create(:deadline_type, name: &amp;quot;signup&amp;quot;)&lt;br /&gt;
    create(:deadline_type, name: &amp;quot;team_formation&amp;quot;)&lt;br /&gt;
    create(:deadline_right)&lt;br /&gt;
    create(:deadline_right, name: 'Late')&lt;br /&gt;
    create(:deadline_right, name: 'OK')&lt;br /&gt;
    create :assignment_due_date, due_at: (DateTime.now + 1)&lt;br /&gt;
&amp;lt;/pre&amp;gt; &lt;br /&gt;
&lt;br /&gt;
One solution is building an complete database to support all RSpec test without creating new records.&lt;br /&gt;
&lt;br /&gt;
== '''Task''' ==&lt;br /&gt;
Formally, we need to:&lt;br /&gt;
* Create the records in test DB according to the content in fixtures.&lt;br /&gt;
* Check each test file and delete certain DB records creation code that insert default records (eg. create(:deadline_type)).&lt;br /&gt;
* And keep all the test cases passing when using test DB and make sure the time running test cases is shorter than before.&lt;br /&gt;
* You should submit the sql file of test DB to Expertiza.&lt;br /&gt;
To finish these tasks, we need to modify all RSpec test files in Expertiza and using a new Database:Expertiza_test.&lt;br /&gt;
&lt;br /&gt;
== Refactor files==&lt;br /&gt;
test database&lt;br /&gt;
&lt;br /&gt;
Rspec tests&lt;br /&gt;
&lt;br /&gt;
== '''Design''' ==&lt;br /&gt;
=== Database design ===&lt;br /&gt;
We design a expertiza_test database to save the test date used for Rspec. The test database owns the same structure as the real expertiza database, including the relations between tables and some restriction of attribute like it cannot be null or some other requirements for different attributes. Besides, the data in test database is the same as the data in factories part in spec, which includes FeedbackResponseMap.rb, Respone.rb, factories.rb, quiz_factory.rb. In this situation we do not need to create some data before testing, and we can use the data in test DB directly. Because of it, the overhead of testing cases will experience obvious decreasing.&lt;br /&gt;
like the Rspec statements in creating some User objects.:&lt;br /&gt;
  factory :admin, class: User do&lt;br /&gt;
    sequence(:name) {|n| &amp;quot;admin#{n}&amp;quot; }&lt;br /&gt;
    role { Role.where(name: 'Administrator').first || association(:role_of_administrator) }&lt;br /&gt;
    password &amp;quot;password&amp;quot;&lt;br /&gt;
    password_confirmation &amp;quot;password&amp;quot;&lt;br /&gt;
    sequence(:fullname) {|n| &amp;quot;#{n}, administrator&amp;quot; }&lt;br /&gt;
    email &amp;quot;expertiza@mailinator.com&amp;quot;&lt;br /&gt;
    parent_id 1&lt;br /&gt;
    private_by_default  false&lt;br /&gt;
    mru_directory_path  nil&lt;br /&gt;
    email_on_review true&lt;br /&gt;
    email_on_submission true&lt;br /&gt;
    email_on_review_of_review true&lt;br /&gt;
    is_new_user false&lt;br /&gt;
    master_permission_granted 0&lt;br /&gt;
    handle &amp;quot;handle&amp;quot;&lt;br /&gt;
    leaderboard_privacy false&lt;br /&gt;
    digital_certificate nil&lt;br /&gt;
    timezonepref nil&lt;br /&gt;
    public_key nil&lt;br /&gt;
    copy_of_emails  false&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
then transfer this into SQL query and then add the information the same as designed for Rspec test into expertiza_test database.&lt;br /&gt;
INSERT INTO User VALUES (xxxxx, xxxxxx, xxxxx, xxxxxxxx, xxxxxxx, xxxxxxx, xxxx );&lt;br /&gt;
&lt;br /&gt;
=== Feature test design ===&lt;br /&gt;
To accelerate the feature test, we have to eliminate pseudo data creation. Now all the feature tests must create their own data before each test. For an example, now a test first create a user before it can do the login operation. The creation latency is considerable. After building a test database, all the pseudo data creation statement can be removed from the test files. Instead, the tests reference data stored in the test database. This change will not only accelerate the testing time, but also dry out the code.&lt;br /&gt;
&lt;br /&gt;
The way tests reference data from database is the same as it does in the development mode.  To login, or do other operations, the test can invoke existing user data in test database. Using &amp;quot;User.find()&amp;quot; or &amp;quot;User.where()&amp;quot;, test data can easily be invoked by tests.&lt;br /&gt;
&lt;br /&gt;
For existing tests, they can directly use the test database. For new tests added later, they can use the records in test database or create specialized data use FactoryGirl. So to keep the test database up to date ,it needs to be maintained regularly.&lt;/div&gt;</summary>
		<author><name>Jdeng8</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2016/E1701._Accelerate_RSpec_testing&amp;diff=105594</id>
		<title>CSC/ECE 517 Fall 2016/E1701. Accelerate RSpec testing</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2016/E1701._Accelerate_RSpec_testing&amp;diff=105594"/>
		<updated>2016-11-14T18:35:13Z</updated>

		<summary type="html">&lt;p&gt;Jdeng8: /* Feature test design */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== '''Expertiza''' ==&lt;br /&gt;
Expertiza is a web application where students can submit and peer-review learning objects (articles, code, web sites, etc). It is used in select courses at NC State and by professors at several other colleges and universities.&lt;br /&gt;
&lt;br /&gt;
== '''Rspec''' ==&lt;br /&gt;
Rspec is a meta-gem, which depends on the rspec-core, rspec-expectations and rspec-mocks gems. Each of these can be installed separately and loaded in isolation using require. Among other benefits, this allows you to use rspec-expectations, for example, in Test::Unit::TestCase if you happen to prefer that style.&lt;br /&gt;
Conversely, if you like RSpec's approach to declaring example groups and examples (describe and it) but prefer Test::Unit assertions and mocha, rr or flexmock for mocking, you'll be able to do that without having to install or load the components of RSpec that you're not using.&lt;br /&gt;
== '''Problem Statement''' ==&lt;br /&gt;
Unfortunately, Expertiza tests are really slow. If you check the TravisCI, it needs more than 9 min to run all tests.&lt;br /&gt;
 &lt;br /&gt;
One reason is that we use fixture to create records in test DB each time running tests.&lt;br /&gt;
 &lt;br /&gt;
For example, the codes in quiz_spec.rb contain too much create so that prolong testing time.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
   # Create an assignment due date&lt;br /&gt;
    create(:deadline_type, name: &amp;quot;submission&amp;quot;)&lt;br /&gt;
    create(:deadline_type, name: &amp;quot;review&amp;quot;)&lt;br /&gt;
    create(:deadline_type, name: &amp;quot;metareview&amp;quot;)&lt;br /&gt;
    create(:deadline_type, name: &amp;quot;drop_topic&amp;quot;)&lt;br /&gt;
    create(:deadline_type, name: &amp;quot;signup&amp;quot;)&lt;br /&gt;
    create(:deadline_type, name: &amp;quot;team_formation&amp;quot;)&lt;br /&gt;
    create(:deadline_right)&lt;br /&gt;
    create(:deadline_right, name: 'Late')&lt;br /&gt;
    create(:deadline_right, name: 'OK')&lt;br /&gt;
    create :assignment_due_date, due_at: (DateTime.now + 1)&lt;br /&gt;
&amp;lt;/pre&amp;gt; &lt;br /&gt;
&lt;br /&gt;
One solution is building an complete database to support all RSpec test without creating new records.&lt;br /&gt;
&lt;br /&gt;
== '''Task''' ==&lt;br /&gt;
Formally, we need to:&lt;br /&gt;
* Create the records in test DB according to the content in fixtures.&lt;br /&gt;
* Check each test file and delete certain DB records creation code that insert default records (eg. create(:deadline_type)).&lt;br /&gt;
* And keep all the test cases passing when using test DB and make sure the time running test cases is shorter than before.&lt;br /&gt;
* You should submit the sql file of test DB to Expertiza.&lt;br /&gt;
To finish these tasks, we need to modify all RSpec test files in Expertiza and using a new Database:Expertiza_test.&lt;br /&gt;
&lt;br /&gt;
== Refactor files==&lt;br /&gt;
test database&lt;br /&gt;
&lt;br /&gt;
Rspec tests&lt;br /&gt;
&lt;br /&gt;
== '''Design''' ==&lt;br /&gt;
=== Database design ===&lt;br /&gt;
We design a expertiza_test database to save the test date used for Rspec. The test database owns the same structure as the real expertiza database, including the relations between tables and some restriction of attribute like it cannot be null or some other requirements for different attributes. Besides, the data in test database is the same as the data in factories part in spec, which includes FeedbackResponseMap.rb, Respone.rb, factories.rb, quiz_factory.rb. In this situation we do not need to create some data before testing, and we can use the data in test DB directly. Because of it, the overhead of testing cases will experience obvious decreasing.&lt;br /&gt;
like the Rspec statements in creating some User objects.:&lt;br /&gt;
  factory :admin, class: User do&lt;br /&gt;
    sequence(:name) {|n| &amp;quot;admin#{n}&amp;quot; }&lt;br /&gt;
    role { Role.where(name: 'Administrator').first || association(:role_of_administrator) }&lt;br /&gt;
    password &amp;quot;password&amp;quot;&lt;br /&gt;
    password_confirmation &amp;quot;password&amp;quot;&lt;br /&gt;
    sequence(:fullname) {|n| &amp;quot;#{n}, administrator&amp;quot; }&lt;br /&gt;
    email &amp;quot;expertiza@mailinator.com&amp;quot;&lt;br /&gt;
    parent_id 1&lt;br /&gt;
    private_by_default  false&lt;br /&gt;
    mru_directory_path  nil&lt;br /&gt;
    email_on_review true&lt;br /&gt;
    email_on_submission true&lt;br /&gt;
    email_on_review_of_review true&lt;br /&gt;
    is_new_user false&lt;br /&gt;
    master_permission_granted 0&lt;br /&gt;
    handle &amp;quot;handle&amp;quot;&lt;br /&gt;
    leaderboard_privacy false&lt;br /&gt;
    digital_certificate nil&lt;br /&gt;
    timezonepref nil&lt;br /&gt;
    public_key nil&lt;br /&gt;
    copy_of_emails  false&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
then transfer this into SQL query and then add the information the same as designed for Rspec test into expertiza_test database.&lt;br /&gt;
INSERT INTO User VALUES (xxxxx, xxxxxx, xxxxx, xxxxxxxx, xxxxxxx, xxxxxxx, xxxx );&lt;br /&gt;
&lt;br /&gt;
=== Feature test design ===&lt;br /&gt;
To accelerate the feature test, we have to eliminate pseudo data creation. Now all the feature tests must create their own data before each test. For an example, now a test first create a user before it can do the login operation. The creation latency is considerable. After building a test database, all the pseudo data creation statement can be removed from the test files. Instead, the tests reference data stored in the test database. This change will not only accelerate the testing time, but also dry out the code.&lt;br /&gt;
&lt;br /&gt;
The way tests reference data from database is the same as it does in the development mode.  To login, or do other operations, the test can invoke existing user data in test database. Using &amp;quot;User.find()&amp;quot; or &amp;quot;User.where()&amp;quot;, test data can easily be invoked by tests.&lt;br /&gt;
&lt;br /&gt;
For existing tests, they can directly use the test database. For new tests added later, they can use the records in test database or create specialized data. So to keep the test database up to date ,it needs to be maintained regularly.&lt;/div&gt;</summary>
		<author><name>Jdeng8</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2016/E1701._Accelerate_RSpec_testing&amp;diff=105593</id>
		<title>CSC/ECE 517 Fall 2016/E1701. Accelerate RSpec testing</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2016/E1701._Accelerate_RSpec_testing&amp;diff=105593"/>
		<updated>2016-11-14T18:32:43Z</updated>

		<summary type="html">&lt;p&gt;Jdeng8: /* &amp;quot;&amp;quot;Refactor files&amp;quot;&amp;quot; */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== '''Expertiza''' ==&lt;br /&gt;
Expertiza is a web application where students can submit and peer-review learning objects (articles, code, web sites, etc). It is used in select courses at NC State and by professors at several other colleges and universities.&lt;br /&gt;
&lt;br /&gt;
== '''Rspec''' ==&lt;br /&gt;
Rspec is a meta-gem, which depends on the rspec-core, rspec-expectations and rspec-mocks gems. Each of these can be installed separately and loaded in isolation using require. Among other benefits, this allows you to use rspec-expectations, for example, in Test::Unit::TestCase if you happen to prefer that style.&lt;br /&gt;
Conversely, if you like RSpec's approach to declaring example groups and examples (describe and it) but prefer Test::Unit assertions and mocha, rr or flexmock for mocking, you'll be able to do that without having to install or load the components of RSpec that you're not using.&lt;br /&gt;
== '''Problem Statement''' ==&lt;br /&gt;
Unfortunately, Expertiza tests are really slow. If you check the TravisCI, it needs more than 9 min to run all tests.&lt;br /&gt;
 &lt;br /&gt;
One reason is that we use fixture to create records in test DB each time running tests.&lt;br /&gt;
 &lt;br /&gt;
For example, the codes in quiz_spec.rb contain too much create so that prolong testing time.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
   # Create an assignment due date&lt;br /&gt;
    create(:deadline_type, name: &amp;quot;submission&amp;quot;)&lt;br /&gt;
    create(:deadline_type, name: &amp;quot;review&amp;quot;)&lt;br /&gt;
    create(:deadline_type, name: &amp;quot;metareview&amp;quot;)&lt;br /&gt;
    create(:deadline_type, name: &amp;quot;drop_topic&amp;quot;)&lt;br /&gt;
    create(:deadline_type, name: &amp;quot;signup&amp;quot;)&lt;br /&gt;
    create(:deadline_type, name: &amp;quot;team_formation&amp;quot;)&lt;br /&gt;
    create(:deadline_right)&lt;br /&gt;
    create(:deadline_right, name: 'Late')&lt;br /&gt;
    create(:deadline_right, name: 'OK')&lt;br /&gt;
    create :assignment_due_date, due_at: (DateTime.now + 1)&lt;br /&gt;
&amp;lt;/pre&amp;gt; &lt;br /&gt;
&lt;br /&gt;
One solution is building an complete database to support all RSpec test without creating new records.&lt;br /&gt;
&lt;br /&gt;
== '''Task''' ==&lt;br /&gt;
Formally, we need to:&lt;br /&gt;
* Create the records in test DB according to the content in fixtures.&lt;br /&gt;
* Check each test file and delete certain DB records creation code that insert default records (eg. create(:deadline_type)).&lt;br /&gt;
* And keep all the test cases passing when using test DB and make sure the time running test cases is shorter than before.&lt;br /&gt;
* You should submit the sql file of test DB to Expertiza.&lt;br /&gt;
To finish these tasks, we need to modify all RSpec test files in Expertiza and using a new Database:Expertiza_test.&lt;br /&gt;
&lt;br /&gt;
== Refactor files==&lt;br /&gt;
test database&lt;br /&gt;
&lt;br /&gt;
Rspec tests&lt;br /&gt;
&lt;br /&gt;
== '''Design''' ==&lt;br /&gt;
=== Database design ===&lt;br /&gt;
We design a expertiza_test database to save the test date used for Rspec. The test database owns the same structure as the real expertiza database, including the relations between tables and some restriction of attribute like it cannot be null or some other requirements for different attributes. Besides, the data in test database is the same as the data in factories part in spec, which includes FeedbackResponseMap.rb, Respone.rb, factories.rb, quiz_factory.rb. In this situation we do not need to create some data before testing, and we can use the data in test DB directly. Because of it, the overhead of testing cases will experience obvious decreasing.&lt;br /&gt;
like the Rspec statements in creating some User objects.:&lt;br /&gt;
  factory :admin, class: User do&lt;br /&gt;
    sequence(:name) {|n| &amp;quot;admin#{n}&amp;quot; }&lt;br /&gt;
    role { Role.where(name: 'Administrator').first || association(:role_of_administrator) }&lt;br /&gt;
    password &amp;quot;password&amp;quot;&lt;br /&gt;
    password_confirmation &amp;quot;password&amp;quot;&lt;br /&gt;
    sequence(:fullname) {|n| &amp;quot;#{n}, administrator&amp;quot; }&lt;br /&gt;
    email &amp;quot;expertiza@mailinator.com&amp;quot;&lt;br /&gt;
    parent_id 1&lt;br /&gt;
    private_by_default  false&lt;br /&gt;
    mru_directory_path  nil&lt;br /&gt;
    email_on_review true&lt;br /&gt;
    email_on_submission true&lt;br /&gt;
    email_on_review_of_review true&lt;br /&gt;
    is_new_user false&lt;br /&gt;
    master_permission_granted 0&lt;br /&gt;
    handle &amp;quot;handle&amp;quot;&lt;br /&gt;
    leaderboard_privacy false&lt;br /&gt;
    digital_certificate nil&lt;br /&gt;
    timezonepref nil&lt;br /&gt;
    public_key nil&lt;br /&gt;
    copy_of_emails  false&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
then transfer this into SQL query and then add the information the same as designed for Rspec test into expertiza_test database.&lt;br /&gt;
INSERT INTO User VALUES (xxxxx, xxxxxx, xxxxx, xxxxxxxx, xxxxxxx, xxxxxxx, xxxx );&lt;br /&gt;
&lt;br /&gt;
=== Feature test design ===&lt;br /&gt;
To accelerate the feature test, we have to eliminate pseudo data creation. Now all the feature tests must create their own data before each test. For an example, now a test first create a user before it can do the login operation. The creation latency is considerable. After building a test database, all the pseudo data creation statement can be removed from the test files. Instead, the tests reference data stored in the test database. This change will not only accelerate the testing time, but also dry out the code.&lt;br /&gt;
&lt;br /&gt;
The way tests reference data from database is the same as it does in the development mode.  To login, or do other operations, the test can invoke existing user data in test database. Using &amp;quot;User.find()&amp;quot; or &amp;quot;User.where()&amp;quot;, test data can easily be invoked by tests.&lt;br /&gt;
&lt;br /&gt;
For existing tests, they can directly use the test database. For tests&lt;/div&gt;</summary>
		<author><name>Jdeng8</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2016/E1701._Accelerate_RSpec_testing&amp;diff=105592</id>
		<title>CSC/ECE 517 Fall 2016/E1701. Accelerate RSpec testing</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2016/E1701._Accelerate_RSpec_testing&amp;diff=105592"/>
		<updated>2016-11-14T18:32:26Z</updated>

		<summary type="html">&lt;p&gt;Jdeng8: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== '''Expertiza''' ==&lt;br /&gt;
Expertiza is a web application where students can submit and peer-review learning objects (articles, code, web sites, etc). It is used in select courses at NC State and by professors at several other colleges and universities.&lt;br /&gt;
&lt;br /&gt;
== '''Rspec''' ==&lt;br /&gt;
Rspec is a meta-gem, which depends on the rspec-core, rspec-expectations and rspec-mocks gems. Each of these can be installed separately and loaded in isolation using require. Among other benefits, this allows you to use rspec-expectations, for example, in Test::Unit::TestCase if you happen to prefer that style.&lt;br /&gt;
Conversely, if you like RSpec's approach to declaring example groups and examples (describe and it) but prefer Test::Unit assertions and mocha, rr or flexmock for mocking, you'll be able to do that without having to install or load the components of RSpec that you're not using.&lt;br /&gt;
== '''Problem Statement''' ==&lt;br /&gt;
Unfortunately, Expertiza tests are really slow. If you check the TravisCI, it needs more than 9 min to run all tests.&lt;br /&gt;
 &lt;br /&gt;
One reason is that we use fixture to create records in test DB each time running tests.&lt;br /&gt;
 &lt;br /&gt;
For example, the codes in quiz_spec.rb contain too much create so that prolong testing time.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
   # Create an assignment due date&lt;br /&gt;
    create(:deadline_type, name: &amp;quot;submission&amp;quot;)&lt;br /&gt;
    create(:deadline_type, name: &amp;quot;review&amp;quot;)&lt;br /&gt;
    create(:deadline_type, name: &amp;quot;metareview&amp;quot;)&lt;br /&gt;
    create(:deadline_type, name: &amp;quot;drop_topic&amp;quot;)&lt;br /&gt;
    create(:deadline_type, name: &amp;quot;signup&amp;quot;)&lt;br /&gt;
    create(:deadline_type, name: &amp;quot;team_formation&amp;quot;)&lt;br /&gt;
    create(:deadline_right)&lt;br /&gt;
    create(:deadline_right, name: 'Late')&lt;br /&gt;
    create(:deadline_right, name: 'OK')&lt;br /&gt;
    create :assignment_due_date, due_at: (DateTime.now + 1)&lt;br /&gt;
&amp;lt;/pre&amp;gt; &lt;br /&gt;
&lt;br /&gt;
One solution is building an complete database to support all RSpec test without creating new records.&lt;br /&gt;
&lt;br /&gt;
== '''Task''' ==&lt;br /&gt;
Formally, we need to:&lt;br /&gt;
* Create the records in test DB according to the content in fixtures.&lt;br /&gt;
* Check each test file and delete certain DB records creation code that insert default records (eg. create(:deadline_type)).&lt;br /&gt;
* And keep all the test cases passing when using test DB and make sure the time running test cases is shorter than before.&lt;br /&gt;
* You should submit the sql file of test DB to Expertiza.&lt;br /&gt;
To finish these tasks, we need to modify all RSpec test files in Expertiza and using a new Database:Expertiza_test.&lt;br /&gt;
&lt;br /&gt;
== &amp;quot;&amp;quot;Refactor files&amp;quot;&amp;quot;==&lt;br /&gt;
test database&lt;br /&gt;
Rspec tests&lt;br /&gt;
&lt;br /&gt;
== '''Design''' ==&lt;br /&gt;
=== Database design ===&lt;br /&gt;
We design a expertiza_test database to save the test date used for Rspec. The test database owns the same structure as the real expertiza database, including the relations between tables and some restriction of attribute like it cannot be null or some other requirements for different attributes. Besides, the data in test database is the same as the data in factories part in spec, which includes FeedbackResponseMap.rb, Respone.rb, factories.rb, quiz_factory.rb. In this situation we do not need to create some data before testing, and we can use the data in test DB directly. Because of it, the overhead of testing cases will experience obvious decreasing.&lt;br /&gt;
like the Rspec statements in creating some User objects.:&lt;br /&gt;
  factory :admin, class: User do&lt;br /&gt;
    sequence(:name) {|n| &amp;quot;admin#{n}&amp;quot; }&lt;br /&gt;
    role { Role.where(name: 'Administrator').first || association(:role_of_administrator) }&lt;br /&gt;
    password &amp;quot;password&amp;quot;&lt;br /&gt;
    password_confirmation &amp;quot;password&amp;quot;&lt;br /&gt;
    sequence(:fullname) {|n| &amp;quot;#{n}, administrator&amp;quot; }&lt;br /&gt;
    email &amp;quot;expertiza@mailinator.com&amp;quot;&lt;br /&gt;
    parent_id 1&lt;br /&gt;
    private_by_default  false&lt;br /&gt;
    mru_directory_path  nil&lt;br /&gt;
    email_on_review true&lt;br /&gt;
    email_on_submission true&lt;br /&gt;
    email_on_review_of_review true&lt;br /&gt;
    is_new_user false&lt;br /&gt;
    master_permission_granted 0&lt;br /&gt;
    handle &amp;quot;handle&amp;quot;&lt;br /&gt;
    leaderboard_privacy false&lt;br /&gt;
    digital_certificate nil&lt;br /&gt;
    timezonepref nil&lt;br /&gt;
    public_key nil&lt;br /&gt;
    copy_of_emails  false&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
then transfer this into SQL query and then add the information the same as designed for Rspec test into expertiza_test database.&lt;br /&gt;
INSERT INTO User VALUES (xxxxx, xxxxxx, xxxxx, xxxxxxxx, xxxxxxx, xxxxxxx, xxxx );&lt;br /&gt;
&lt;br /&gt;
=== Feature test design ===&lt;br /&gt;
To accelerate the feature test, we have to eliminate pseudo data creation. Now all the feature tests must create their own data before each test. For an example, now a test first create a user before it can do the login operation. The creation latency is considerable. After building a test database, all the pseudo data creation statement can be removed from the test files. Instead, the tests reference data stored in the test database. This change will not only accelerate the testing time, but also dry out the code.&lt;br /&gt;
&lt;br /&gt;
The way tests reference data from database is the same as it does in the development mode.  To login, or do other operations, the test can invoke existing user data in test database. Using &amp;quot;User.find()&amp;quot; or &amp;quot;User.where()&amp;quot;, test data can easily be invoked by tests.&lt;br /&gt;
&lt;br /&gt;
For existing tests, they can directly use the test database. For tests&lt;/div&gt;</summary>
		<author><name>Jdeng8</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2016/E1701._Accelerate_RSpec_testing&amp;diff=105591</id>
		<title>CSC/ECE 517 Fall 2016/E1701. Accelerate RSpec testing</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2016/E1701._Accelerate_RSpec_testing&amp;diff=105591"/>
		<updated>2016-11-14T18:28:10Z</updated>

		<summary type="html">&lt;p&gt;Jdeng8: /* Problem Statement */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== '''Expertiza''' ==&lt;br /&gt;
Expertiza is a web application where students can submit and peer-review learning objects (articles, code, web sites, etc). It is used in select courses at NC State and by professors at several other colleges and universities.&lt;br /&gt;
&lt;br /&gt;
== '''Rspec''' ==&lt;br /&gt;
Rspec is a meta-gem, which depends on the rspec-core, rspec-expectations and rspec-mocks gems. Each of these can be installed separately and loaded in isolation using require. Among other benefits, this allows you to use rspec-expectations, for example, in Test::Unit::TestCase if you happen to prefer that style.&lt;br /&gt;
Conversely, if you like RSpec's approach to declaring example groups and examples (describe and it) but prefer Test::Unit assertions and mocha, rr or flexmock for mocking, you'll be able to do that without having to install or load the components of RSpec that you're not using.&lt;br /&gt;
== '''Problem Statement''' ==&lt;br /&gt;
Unfortunately, Expertiza tests are really slow. If you check the TravisCI, it needs more than 9 min to run all tests.&lt;br /&gt;
 &lt;br /&gt;
One reason is that we use fixture to create records in test DB each time running tests.&lt;br /&gt;
 &lt;br /&gt;
For example, the codes in quiz_spec.rb contain too much create so that prolong testing time.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
   # Create an assignment due date&lt;br /&gt;
    create(:deadline_type, name: &amp;quot;submission&amp;quot;)&lt;br /&gt;
    create(:deadline_type, name: &amp;quot;review&amp;quot;)&lt;br /&gt;
    create(:deadline_type, name: &amp;quot;metareview&amp;quot;)&lt;br /&gt;
    create(:deadline_type, name: &amp;quot;drop_topic&amp;quot;)&lt;br /&gt;
    create(:deadline_type, name: &amp;quot;signup&amp;quot;)&lt;br /&gt;
    create(:deadline_type, name: &amp;quot;team_formation&amp;quot;)&lt;br /&gt;
    create(:deadline_right)&lt;br /&gt;
    create(:deadline_right, name: 'Late')&lt;br /&gt;
    create(:deadline_right, name: 'OK')&lt;br /&gt;
    create :assignment_due_date, due_at: (DateTime.now + 1)&lt;br /&gt;
&amp;lt;/pre&amp;gt; &lt;br /&gt;
&lt;br /&gt;
One solution is building an complete database to support all RSpec test without creating new records.&lt;br /&gt;
&lt;br /&gt;
== '''Task''' ==&lt;br /&gt;
Formally, we need to:&lt;br /&gt;
* Create the records in test DB according to the content in fixtures.&lt;br /&gt;
* Check each test file and delete certain DB records creation code that insert default records (eg. create(:deadline_type)).&lt;br /&gt;
* And keep all the test cases passing when using test DB and make sure the time running test cases is shorter than before.&lt;br /&gt;
* You should submit the sql file of test DB to Expertiza.&lt;br /&gt;
To finish these tasks, we need to modify all RSpec test files in Expertiza and using a new Database:Expertiza_test.&lt;br /&gt;
&lt;br /&gt;
== '''Design''' ==&lt;br /&gt;
=== Database design ===&lt;br /&gt;
We design a expertiza_test database to save the test date used for Rspec. The test database owns the same structure as the real expertiza database, including the relations between tables and some restriction of attribute like it cannot be null or some other requirements for different attributes. Besides, the data in test database is the same as the data in factories part in spec, which includes FeedbackResponseMap.rb, Respone.rb, factories.rb, quiz_factory.rb. In this situation we do not need to create some data before testing, and we can use the data in test DB directly. Because of it, the overhead of testing cases will experience obvious decreasing.&lt;br /&gt;
like the Rspec statements in creating some User objects.:&lt;br /&gt;
  factory :admin, class: User do&lt;br /&gt;
    sequence(:name) {|n| &amp;quot;admin#{n}&amp;quot; }&lt;br /&gt;
    role { Role.where(name: 'Administrator').first || association(:role_of_administrator) }&lt;br /&gt;
    password &amp;quot;password&amp;quot;&lt;br /&gt;
    password_confirmation &amp;quot;password&amp;quot;&lt;br /&gt;
    sequence(:fullname) {|n| &amp;quot;#{n}, administrator&amp;quot; }&lt;br /&gt;
    email &amp;quot;expertiza@mailinator.com&amp;quot;&lt;br /&gt;
    parent_id 1&lt;br /&gt;
    private_by_default  false&lt;br /&gt;
    mru_directory_path  nil&lt;br /&gt;
    email_on_review true&lt;br /&gt;
    email_on_submission true&lt;br /&gt;
    email_on_review_of_review true&lt;br /&gt;
    is_new_user false&lt;br /&gt;
    master_permission_granted 0&lt;br /&gt;
    handle &amp;quot;handle&amp;quot;&lt;br /&gt;
    leaderboard_privacy false&lt;br /&gt;
    digital_certificate nil&lt;br /&gt;
    timezonepref nil&lt;br /&gt;
    public_key nil&lt;br /&gt;
    copy_of_emails  false&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
then transfer this into SQL query and then add the information the same as designed for Rspec test into expertiza_test database.&lt;br /&gt;
INSERT INTO User VALUES (xxxxx, xxxxxx, xxxxx, xxxxxxxx, xxxxxxx, xxxxxxx, xxxx );&lt;br /&gt;
&lt;br /&gt;
=== Feature test design ===&lt;br /&gt;
To accelerate the feature test, we have to eliminate pseudo data creation. Now all the feature tests must create their own data before each test. For an example, now a test first create a user before it can do the login operation. The creation latency is considerable. After building a test database, all the pseudo data creation statement can be removed from the test files. Instead, the tests reference data stored in the test database. This change will not only accelerate the testing time, but also dry out the code.&lt;br /&gt;
&lt;br /&gt;
The way tests reference data from database is the same as it does in the development mode.  To login, or do other operations, the test can invoke existing user data in test database. Using &amp;quot;User.find()&amp;quot; or &amp;quot;User.where()&amp;quot;, test data can easily be invoked by tests.&lt;/div&gt;</summary>
		<author><name>Jdeng8</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=File:Expertiza_test_time.png&amp;diff=105411</id>
		<title>File:Expertiza test time.png</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=File:Expertiza_test_time.png&amp;diff=105411"/>
		<updated>2016-11-11T18:52:43Z</updated>

		<summary type="html">&lt;p&gt;Jdeng8: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Jdeng8</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2016/E1701._Accelerate_RSpec_testing&amp;diff=104808</id>
		<title>CSC/ECE 517 Fall 2016/E1701. Accelerate RSpec testing</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2016/E1701._Accelerate_RSpec_testing&amp;diff=104808"/>
		<updated>2016-11-09T01:12:27Z</updated>

		<summary type="html">&lt;p&gt;Jdeng8: /* Feature test design */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== '''Eexpertiza''' ==&lt;br /&gt;
Expertiza is a web application where students can submit and peer-review learning objects (articles, code, web sites, etc). It is used in select courses at NC State and by professors at several other colleges and universities.&lt;br /&gt;
== '''Rspec''' ==&lt;br /&gt;
Rspec is a meta-gem, which depends on the rspec-core, rspec-expectations and rspec-mocks gems. Each of these can be installed separately and loaded in isolation using require. Among other benefits, this allows you to use rspec-expectations, for example, in Test::Unit::TestCase if you happen to prefer that style.&lt;br /&gt;
Conversely, if you like RSpec's approach to declaring example groups and examples (describe and it) but prefer Test::Unit assertions and mocha, rr or flexmock for mocking, you'll be able to do that without having to install or load the components of RSpec that you're not using.&lt;br /&gt;
== '''Problem Statement''' ==&lt;br /&gt;
Unfortunately, Expertiza tests are really slow. If you check the TravisCI, it needs more than 9 min to run all tests.&lt;br /&gt;
 &lt;br /&gt;
One reason is that we use fixture to create records in test DB each time running tests.&lt;br /&gt;
 &lt;br /&gt;
For example, the codes in quiz_spec.rb contain too much create so that prolong testing time.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
   # Create an assignment due date&lt;br /&gt;
    create(:deadline_type, name: &amp;quot;submission&amp;quot;)&lt;br /&gt;
    create(:deadline_type, name: &amp;quot;review&amp;quot;)&lt;br /&gt;
    create(:deadline_type, name: &amp;quot;metareview&amp;quot;)&lt;br /&gt;
    create(:deadline_type, name: &amp;quot;drop_topic&amp;quot;)&lt;br /&gt;
    create(:deadline_type, name: &amp;quot;signup&amp;quot;)&lt;br /&gt;
    create(:deadline_type, name: &amp;quot;team_formation&amp;quot;)&lt;br /&gt;
    create(:deadline_right)&lt;br /&gt;
    create(:deadline_right, name: 'Late')&lt;br /&gt;
    create(:deadline_right, name: 'OK')&lt;br /&gt;
    create :assignment_due_date, due_at: (DateTime.now + 1)&lt;br /&gt;
&amp;lt;/pre&amp;gt; &lt;br /&gt;
&lt;br /&gt;
One solution is building an complete database to one time to support all RSpec test without create new records.&lt;br /&gt;
&lt;br /&gt;
== '''Task''' ==&lt;br /&gt;
Formally, we need to:&lt;br /&gt;
* Create the records in test DB according to the content in fixtures.&lt;br /&gt;
* Check each test file and delete certain DB records creation code that insert default records (eg. create(:deadline_type)).&lt;br /&gt;
* And keep all the test cases passing when using test DB and make sure the time running test cases is shorter than before.&lt;br /&gt;
* You should submit the sql file of test DB to Expertiza.&lt;br /&gt;
To finish these tasks, we need to modify all RSpec test files in Expertiza and using a new Database:Expertiza_test.&lt;br /&gt;
&lt;br /&gt;
== '''Design''' ==&lt;br /&gt;
=== Database design ===&lt;br /&gt;
We design a expertiza_test database to save the test date used for Rspec. The test database owns the same structure as the real expertiza database, including the relations between tables and some restriction of attribute like it cannot be null or some other requirements for different attributes. Besides, the data in test database is the same as the data in factories part in spec, which includes FeedbackResponseMap.rb, Respone.rb, factories.rb, quiz_factory.rb. In this situation we do not need to create some data before testing, and we can use the data in test DB directly. Because of it, the overhead of testing cases will experience obvious decreasing.&lt;br /&gt;
like the Rspec statements in creating some User objects.:&lt;br /&gt;
  factory :admin, class: User do&lt;br /&gt;
    sequence(:name) {|n| &amp;quot;admin#{n}&amp;quot; }&lt;br /&gt;
    role { Role.where(name: 'Administrator').first || association(:role_of_administrator) }&lt;br /&gt;
    password &amp;quot;password&amp;quot;&lt;br /&gt;
    password_confirmation &amp;quot;password&amp;quot;&lt;br /&gt;
    sequence(:fullname) {|n| &amp;quot;#{n}, administrator&amp;quot; }&lt;br /&gt;
    email &amp;quot;expertiza@mailinator.com&amp;quot;&lt;br /&gt;
    parent_id 1&lt;br /&gt;
    private_by_default  false&lt;br /&gt;
    mru_directory_path  nil&lt;br /&gt;
    email_on_review true&lt;br /&gt;
    email_on_submission true&lt;br /&gt;
    email_on_review_of_review true&lt;br /&gt;
    is_new_user false&lt;br /&gt;
    master_permission_granted 0&lt;br /&gt;
    handle &amp;quot;handle&amp;quot;&lt;br /&gt;
    leaderboard_privacy false&lt;br /&gt;
    digital_certificate nil&lt;br /&gt;
    timezonepref nil&lt;br /&gt;
    public_key nil&lt;br /&gt;
    copy_of_emails  false&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
then transfer this into SQL query and then add the information the same as designed for Rspec test into expertiza_test database.&lt;br /&gt;
INSERT INTO User VALUES (xxxxx, xxxxxx, xxxxx, xxxxxxxx, xxxxxxx, xxxxxxx, xxxx );&lt;br /&gt;
&lt;br /&gt;
=== Feature test design ===&lt;br /&gt;
To accelerate the feature test, we have to eliminate pseudo data creation. Now all the feature tests must create their own data before each test. For an example, now a test first create a user before it can do the login operation. The creation latency is considerable. After building a test database, all the pseudo data creation statement can be removed from the test files. Instead, the tests reference data stored in the test database. This change will not only accelerate the testing time, but also dry out the code.&lt;br /&gt;
&lt;br /&gt;
The way tests reference data from database is the same as it does in the development mode.  To login, or do other operations, the test can invoke existing user data in test database. Using &amp;quot;User.find()&amp;quot; or &amp;quot;User.where()&amp;quot;, test data can easily be invoked by tests.&lt;/div&gt;</summary>
		<author><name>Jdeng8</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2016/E1701._Accelerate_RSpec_testing&amp;diff=104807</id>
		<title>CSC/ECE 517 Fall 2016/E1701. Accelerate RSpec testing</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2016/E1701._Accelerate_RSpec_testing&amp;diff=104807"/>
		<updated>2016-11-09T01:10:42Z</updated>

		<summary type="html">&lt;p&gt;Jdeng8: /* Feature test design */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== '''Eexpertiza''' ==&lt;br /&gt;
Expertiza is a web application where students can submit and peer-review learning objects (articles, code, web sites, etc). It is used in select courses at NC State and by professors at several other colleges and universities.&lt;br /&gt;
== '''Rspec''' ==&lt;br /&gt;
Rspec is a meta-gem, which depends on the rspec-core, rspec-expectations and rspec-mocks gems. Each of these can be installed separately and loaded in isolation using require. Among other benefits, this allows you to use rspec-expectations, for example, in Test::Unit::TestCase if you happen to prefer that style.&lt;br /&gt;
Conversely, if you like RSpec's approach to declaring example groups and examples (describe and it) but prefer Test::Unit assertions and mocha, rr or flexmock for mocking, you'll be able to do that without having to install or load the components of RSpec that you're not using.&lt;br /&gt;
== '''Problem Statement''' ==&lt;br /&gt;
Unfortunately, Expertiza tests are really slow. If you check the TravisCI, it needs more than 9 min to run all tests.&lt;br /&gt;
 &lt;br /&gt;
One reason is that we use fixture to create records in test DB each time running tests.&lt;br /&gt;
 &lt;br /&gt;
For example, the codes in quiz_spec.rb contain too much create so that prolong testing time.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
   # Create an assignment due date&lt;br /&gt;
    create(:deadline_type, name: &amp;quot;submission&amp;quot;)&lt;br /&gt;
    create(:deadline_type, name: &amp;quot;review&amp;quot;)&lt;br /&gt;
    create(:deadline_type, name: &amp;quot;metareview&amp;quot;)&lt;br /&gt;
    create(:deadline_type, name: &amp;quot;drop_topic&amp;quot;)&lt;br /&gt;
    create(:deadline_type, name: &amp;quot;signup&amp;quot;)&lt;br /&gt;
    create(:deadline_type, name: &amp;quot;team_formation&amp;quot;)&lt;br /&gt;
    create(:deadline_right)&lt;br /&gt;
    create(:deadline_right, name: 'Late')&lt;br /&gt;
    create(:deadline_right, name: 'OK')&lt;br /&gt;
    create :assignment_due_date, due_at: (DateTime.now + 1)&lt;br /&gt;
&amp;lt;/pre&amp;gt; &lt;br /&gt;
&lt;br /&gt;
One solution is building an complete database to one time to support all RSpec test without create new records.&lt;br /&gt;
&lt;br /&gt;
== '''Task''' ==&lt;br /&gt;
Formally, we need to:&lt;br /&gt;
* Create the records in test DB according to the content in fixtures.&lt;br /&gt;
* Check each test file and delete certain DB records creation code that insert default records (eg. create(:deadline_type)).&lt;br /&gt;
* And keep all the test cases passing when using test DB and make sure the time running test cases is shorter than before.&lt;br /&gt;
* You should submit the sql file of test DB to Expertiza.&lt;br /&gt;
To finish these tasks, we need to modify all RSpec test files in Expertiza and using a new Database:Expertiza_test.&lt;br /&gt;
&lt;br /&gt;
== '''Design''' ==&lt;br /&gt;
=== Database design ===&lt;br /&gt;
We design a expertiza_test database to save the test date used for Rspec. The test database owns the same structure as the real expertiza database, including the relations between tables and some restriction of attribute like it cannot be null or some other requirements for different attributes. Besides, the data in test database is the same as the data in factories part in spec, which includes FeedbackResponseMap.rb, Respone.rb, factories.rb, quiz_factory.rb. In this situation we do not need to create some data before testing, and we can use the data in test DB directly. Because of it, the overhead of testing cases will experience obvious decreasing.&lt;br /&gt;
like the Rspec statements in creating some User objects.:&lt;br /&gt;
  factory :admin, class: User do&lt;br /&gt;
    sequence(:name) {|n| &amp;quot;admin#{n}&amp;quot; }&lt;br /&gt;
    role { Role.where(name: 'Administrator').first || association(:role_of_administrator) }&lt;br /&gt;
    password &amp;quot;password&amp;quot;&lt;br /&gt;
    password_confirmation &amp;quot;password&amp;quot;&lt;br /&gt;
    sequence(:fullname) {|n| &amp;quot;#{n}, administrator&amp;quot; }&lt;br /&gt;
    email &amp;quot;expertiza@mailinator.com&amp;quot;&lt;br /&gt;
    parent_id 1&lt;br /&gt;
    private_by_default  false&lt;br /&gt;
    mru_directory_path  nil&lt;br /&gt;
    email_on_review true&lt;br /&gt;
    email_on_submission true&lt;br /&gt;
    email_on_review_of_review true&lt;br /&gt;
    is_new_user false&lt;br /&gt;
    master_permission_granted 0&lt;br /&gt;
    handle &amp;quot;handle&amp;quot;&lt;br /&gt;
    leaderboard_privacy false&lt;br /&gt;
    digital_certificate nil&lt;br /&gt;
    timezonepref nil&lt;br /&gt;
    public_key nil&lt;br /&gt;
    copy_of_emails  false&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
then transfer this into SQL query and then add the information the same as designed for Rspec test into expertiza_test database.&lt;br /&gt;
INSERT INTO User VALUES (xxxxx, xxxxxx, xxxxx, xxxxxxxx, xxxxxxx, xxxxxxx, xxxx );&lt;br /&gt;
&lt;br /&gt;
=== Feature test design ===&lt;br /&gt;
To accelerate the feature test, we have to eliminate pseudo data creation. Now all the feature tests must create their own data before each test. For an example, now a test first create a user before it can do the login operation. The creation latency is considerable. After building a test database, all the pseudo data creation statement can be removed from the test files. Instead, the tests reference data stored in the test database. &lt;br /&gt;
&lt;br /&gt;
The way tests reference data from database is the same as it does in the development mode.  To login, or do other operations, the test can invoke existing user data in test database. Using &amp;quot;User.find()&amp;quot; or &amp;quot;User.where()&amp;quot;, test data can easily be invoked by tests.&lt;/div&gt;</summary>
		<author><name>Jdeng8</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2016/E1701._Accelerate_RSpec_testing&amp;diff=104806</id>
		<title>CSC/ECE 517 Fall 2016/E1701. Accelerate RSpec testing</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2016/E1701._Accelerate_RSpec_testing&amp;diff=104806"/>
		<updated>2016-11-09T01:09:58Z</updated>

		<summary type="html">&lt;p&gt;Jdeng8: /* feature test design */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== '''Eexpertiza''' ==&lt;br /&gt;
Expertiza is a web application where students can submit and peer-review learning objects (articles, code, web sites, etc). It is used in select courses at NC State and by professors at several other colleges and universities.&lt;br /&gt;
== '''Rspec''' ==&lt;br /&gt;
Rspec is a meta-gem, which depends on the rspec-core, rspec-expectations and rspec-mocks gems. Each of these can be installed separately and loaded in isolation using require. Among other benefits, this allows you to use rspec-expectations, for example, in Test::Unit::TestCase if you happen to prefer that style.&lt;br /&gt;
Conversely, if you like RSpec's approach to declaring example groups and examples (describe and it) but prefer Test::Unit assertions and mocha, rr or flexmock for mocking, you'll be able to do that without having to install or load the components of RSpec that you're not using.&lt;br /&gt;
== '''Problem Statement''' ==&lt;br /&gt;
Unfortunately, Expertiza tests are really slow. If you check the TravisCI, it needs more than 9 min to run all tests.&lt;br /&gt;
 &lt;br /&gt;
One reason is that we use fixture to create records in test DB each time running tests.&lt;br /&gt;
 &lt;br /&gt;
For example, the codes in quiz_spec.rb contain too much create so that prolong testing time.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
   # Create an assignment due date&lt;br /&gt;
    create(:deadline_type, name: &amp;quot;submission&amp;quot;)&lt;br /&gt;
    create(:deadline_type, name: &amp;quot;review&amp;quot;)&lt;br /&gt;
    create(:deadline_type, name: &amp;quot;metareview&amp;quot;)&lt;br /&gt;
    create(:deadline_type, name: &amp;quot;drop_topic&amp;quot;)&lt;br /&gt;
    create(:deadline_type, name: &amp;quot;signup&amp;quot;)&lt;br /&gt;
    create(:deadline_type, name: &amp;quot;team_formation&amp;quot;)&lt;br /&gt;
    create(:deadline_right)&lt;br /&gt;
    create(:deadline_right, name: 'Late')&lt;br /&gt;
    create(:deadline_right, name: 'OK')&lt;br /&gt;
    create :assignment_due_date, due_at: (DateTime.now + 1)&lt;br /&gt;
&amp;lt;/pre&amp;gt; &lt;br /&gt;
&lt;br /&gt;
One solution is building an complete database to one time to support all RSpec test without create new records.&lt;br /&gt;
&lt;br /&gt;
== '''Task''' ==&lt;br /&gt;
Formally, we need to:&lt;br /&gt;
* Create the records in test DB according to the content in fixtures.&lt;br /&gt;
* Check each test file and delete certain DB records creation code that insert default records (eg. create(:deadline_type)).&lt;br /&gt;
* And keep all the test cases passing when using test DB and make sure the time running test cases is shorter than before.&lt;br /&gt;
* You should submit the sql file of test DB to Expertiza.&lt;br /&gt;
To finish these tasks, we need to modify all RSpec test files in Expertiza and using a new Database:Expertiza_test.&lt;br /&gt;
&lt;br /&gt;
== '''Design''' ==&lt;br /&gt;
=== Database design ===&lt;br /&gt;
We design a expertiza_test database to save the test date used for Rspec. The test database owns the same structure as the real expertiza database, including the relations between tables and some restriction of attribute like it cannot be null or some other requirements for different attributes. Besides, the data in test database is the same as the data in factories part in spec, which includes FeedbackResponseMap.rb, Respone.rb, factories.rb, quiz_factory.rb. In this situation we do not need to create some data before testing, and we can use the data in test DB directly. Because of it, the overhead of testing cases will experience obvious decreasing.&lt;br /&gt;
like the Rspec statements in creating some User objects.:&lt;br /&gt;
  factory :admin, class: User do&lt;br /&gt;
    sequence(:name) {|n| &amp;quot;admin#{n}&amp;quot; }&lt;br /&gt;
    role { Role.where(name: 'Administrator').first || association(:role_of_administrator) }&lt;br /&gt;
    password &amp;quot;password&amp;quot;&lt;br /&gt;
    password_confirmation &amp;quot;password&amp;quot;&lt;br /&gt;
    sequence(:fullname) {|n| &amp;quot;#{n}, administrator&amp;quot; }&lt;br /&gt;
    email &amp;quot;expertiza@mailinator.com&amp;quot;&lt;br /&gt;
    parent_id 1&lt;br /&gt;
    private_by_default  false&lt;br /&gt;
    mru_directory_path  nil&lt;br /&gt;
    email_on_review true&lt;br /&gt;
    email_on_submission true&lt;br /&gt;
    email_on_review_of_review true&lt;br /&gt;
    is_new_user false&lt;br /&gt;
    master_permission_granted 0&lt;br /&gt;
    handle &amp;quot;handle&amp;quot;&lt;br /&gt;
    leaderboard_privacy false&lt;br /&gt;
    digital_certificate nil&lt;br /&gt;
    timezonepref nil&lt;br /&gt;
    public_key nil&lt;br /&gt;
    copy_of_emails  false&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
then transfer this into SQL query and then add the information the same as designed for Rspec test into expertiza_test database.&lt;br /&gt;
INSERT INTO User VALUES (xxxxx, xxxxxx, xxxxx, xxxxxxxx, xxxxxxx, xxxxxxx, xxxx );&lt;br /&gt;
&lt;br /&gt;
=== Feature test design ===&lt;br /&gt;
To accelerate the feature test, we have to eliminate pseudo data creation. Now all the feature tests must create their own data before each test. For an example, now a test first create a user before it can do the login operation. The creation latency is considerable. After building a test database, all the pseudo data creation statement can be removed from the test files. Instead, the tests reference data stored in the test database. &lt;br /&gt;
&lt;br /&gt;
The way tests reference data from database is the same as it does in the development mode.  To login, or do other operations, the test can just invoke existing user data in test database. Using &amp;quot;User.find()&amp;quot; or &amp;quot;User.where()&amp;quot;, test data can easily be invoked by tests.&lt;/div&gt;</summary>
		<author><name>Jdeng8</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2016/E1701._Accelerate_RSpec_testing&amp;diff=104799</id>
		<title>CSC/ECE 517 Fall 2016/E1701. Accelerate RSpec testing</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2016/E1701._Accelerate_RSpec_testing&amp;diff=104799"/>
		<updated>2016-11-08T23:38:22Z</updated>

		<summary type="html">&lt;p&gt;Jdeng8: /* feature test design */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== '''Eexpertiza''' ==&lt;br /&gt;
Expertiza is a web application where students can submit and peer-review learning objects (articles, code, web sites, etc). It is used in select courses at NC State and by professors at several other colleges and universities.&lt;br /&gt;
== '''Rspec''' ==&lt;br /&gt;
Rspec is a meta-gem, which depends on the rspec-core, rspec-expectations and rspec-mocks gems. Each of these can be installed separately and loaded in isolation using require. Among other benefits, this allows you to use rspec-expectations, for example, in Test::Unit::TestCase if you happen to prefer that style.&lt;br /&gt;
Conversely, if you like RSpec's approach to declaring example groups and examples (describe and it) but prefer Test::Unit assertions and mocha, rr or flexmock for mocking, you'll be able to do that without having to install or load the components of RSpec that you're not using.&lt;br /&gt;
== '''Problem Statement''' ==&lt;br /&gt;
Unfortunately, Expertiza tests are really slow. If you check the TravisCI, it needs more than 9 min to run all tests.&lt;br /&gt;
 &lt;br /&gt;
One reason is that we use fixture to create records in test DB each time running tests.&lt;br /&gt;
 &lt;br /&gt;
For example, the codes in quiz_spec.rb contain too much create so that prolong testing time.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
   # Create an assignment due date&lt;br /&gt;
    create(:deadline_type, name: &amp;quot;submission&amp;quot;)&lt;br /&gt;
    create(:deadline_type, name: &amp;quot;review&amp;quot;)&lt;br /&gt;
    create(:deadline_type, name: &amp;quot;metareview&amp;quot;)&lt;br /&gt;
    create(:deadline_type, name: &amp;quot;drop_topic&amp;quot;)&lt;br /&gt;
    create(:deadline_type, name: &amp;quot;signup&amp;quot;)&lt;br /&gt;
    create(:deadline_type, name: &amp;quot;team_formation&amp;quot;)&lt;br /&gt;
    create(:deadline_right)&lt;br /&gt;
    create(:deadline_right, name: 'Late')&lt;br /&gt;
    create(:deadline_right, name: 'OK')&lt;br /&gt;
    create :assignment_due_date, due_at: (DateTime.now + 1)&lt;br /&gt;
&amp;lt;/pre&amp;gt; &lt;br /&gt;
&lt;br /&gt;
One solution is building an complete database to one time to support all RSpec test without create new records.&lt;br /&gt;
&lt;br /&gt;
== '''Task''' ==&lt;br /&gt;
Formally, we need to:&lt;br /&gt;
* Create the records in test DB according to the content in fixtures.&lt;br /&gt;
* Check each test file and delete certain DB records creation code that insert default records (eg. create(:deadline_type)).&lt;br /&gt;
* And keep all the test cases passing when using test DB and make sure the time running test cases is shorter than before.&lt;br /&gt;
* You should submit the sql file of test DB to Expertiza.&lt;br /&gt;
To finish these tasks, we need to modify all RSpec test files in Expertiza and using a new Database:Expertiza_test.&lt;br /&gt;
&lt;br /&gt;
== '''Design''' ==&lt;br /&gt;
=== Database design ===&lt;br /&gt;
We design a expertiza_test database to save the test date used for Rspec. The test database owns the same structure as the real expertiza database, including the relations between tables and some restriction of attribute like it cannot be null or some other requirements for different attributes. Besides, the data in test database is the same as the data in factories part in spec, which includes FeedbackResponseMap.rb, Respone.rb, factories.rb, quiz_factory.rb. In this situation we do not need to create some data before testing, and we can use the data in test DB directly. Because of it, the overhead of testing cases will experience obvious decreasing.&lt;br /&gt;
like the Rspec statements in creating some User objects.:&lt;br /&gt;
  factory :admin, class: User do&lt;br /&gt;
    sequence(:name) {|n| &amp;quot;admin#{n}&amp;quot; }&lt;br /&gt;
    role { Role.where(name: 'Administrator').first || association(:role_of_administrator) }&lt;br /&gt;
    password &amp;quot;password&amp;quot;&lt;br /&gt;
    password_confirmation &amp;quot;password&amp;quot;&lt;br /&gt;
    sequence(:fullname) {|n| &amp;quot;#{n}, administrator&amp;quot; }&lt;br /&gt;
    email &amp;quot;expertiza@mailinator.com&amp;quot;&lt;br /&gt;
    parent_id 1&lt;br /&gt;
    private_by_default  false&lt;br /&gt;
    mru_directory_path  nil&lt;br /&gt;
    email_on_review true&lt;br /&gt;
    email_on_submission true&lt;br /&gt;
    email_on_review_of_review true&lt;br /&gt;
    is_new_user false&lt;br /&gt;
    master_permission_granted 0&lt;br /&gt;
    handle &amp;quot;handle&amp;quot;&lt;br /&gt;
    leaderboard_privacy false&lt;br /&gt;
    digital_certificate nil&lt;br /&gt;
    timezonepref nil&lt;br /&gt;
    public_key nil&lt;br /&gt;
    copy_of_emails  false&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
then transfer this into SQL query and then add the information the same as designed for Rspec test into expertiza_test database.&lt;br /&gt;
INSERT INTO User VALUES (xxxxx, xxxxxx, xxxxx, xxxxxxxx, xxxxxxx, xxxxxxx, xxxx );&lt;br /&gt;
&lt;br /&gt;
=== feature test design ===&lt;br /&gt;
To accelerate the feature test, we have to eliminate pseudo data creation. Now all the feature tests have to create their own data before each test. After building a test database, all the pseudo data creation statement can be removed from the test files. Instead, the tests reference data stored in the test database. &lt;br /&gt;
&lt;br /&gt;
The way tests reference data from database is the same as it does in project.  For an example, if a test want to use &amp;quot;instructor6&amp;quot; to login, now the test first create a user named &amp;quot;instruc&amp;quot;&lt;/div&gt;</summary>
		<author><name>Jdeng8</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2016/E1701._Accelerate_RSpec_testing&amp;diff=104775</id>
		<title>CSC/ECE 517 Fall 2016/E1701. Accelerate RSpec testing</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2016/E1701._Accelerate_RSpec_testing&amp;diff=104775"/>
		<updated>2016-11-08T22:08:23Z</updated>

		<summary type="html">&lt;p&gt;Jdeng8: /* Task */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== '''Eexpertiza''' ==&lt;br /&gt;
== '''Rspec''' ==&lt;br /&gt;
== '''Problem Statement''' ==&lt;br /&gt;
Expertiza is a web application where students can submit and peer-review learning objects (articles, code, web sites, etc). It is used in select courses at NC State and by professors at several other colleges and universities.&lt;br /&gt;
Unfortunately, Expertiza tests are really slow. If you check the TravisCI, it needs more than 9 min to run all tests. &lt;br /&gt;
One reason is that we use fixture to create records in test DB each time running tests.&lt;br /&gt;
&lt;br /&gt;
For example, the codes in quiz_spec.rb contain too much create so that prolong testing time.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
   # Create an assignment due date&lt;br /&gt;
    create(:deadline_type, name: &amp;quot;submission&amp;quot;)&lt;br /&gt;
    create(:deadline_type, name: &amp;quot;review&amp;quot;)&lt;br /&gt;
    create(:deadline_type, name: &amp;quot;metareview&amp;quot;)&lt;br /&gt;
    create(:deadline_type, name: &amp;quot;drop_topic&amp;quot;)&lt;br /&gt;
    create(:deadline_type, name: &amp;quot;signup&amp;quot;)&lt;br /&gt;
    create(:deadline_type, name: &amp;quot;team_formation&amp;quot;)&lt;br /&gt;
    create(:deadline_right)&lt;br /&gt;
    create(:deadline_right, name: 'Late')&lt;br /&gt;
    create(:deadline_right, name: 'OK')&lt;br /&gt;
    create :assignment_due_date, due_at: (DateTime.now + 1)&lt;br /&gt;
&amp;lt;/pre&amp;gt; &lt;br /&gt;
&lt;br /&gt;
One solution is building an complete database to one time to support all RSpec test without create new records.&lt;br /&gt;
== '''Related Work''' ==&lt;br /&gt;
* Classes involved:  All RSpec test files in Expertiza.&lt;br /&gt;
* Database involved: Expertiza_test &lt;br /&gt;
&lt;br /&gt;
== '''Task''' ==&lt;br /&gt;
Formally, you need to:&lt;br /&gt;
* Create the records in test DB according to the content in fixtures.&lt;br /&gt;
* Check each test file and delete certain DB records creation code that insert default records (eg. create(:deadline_type)).&lt;br /&gt;
* And keep all the test cases passing when using test DB and make sure the time running test cases is shorter than before.&lt;br /&gt;
* You should submit the sql file of test DB to Expertiza.&lt;br /&gt;
&lt;br /&gt;
== '''Design''' ==&lt;br /&gt;
=== Database design ===&lt;br /&gt;
We design a expertiza_test database to save the test date used for Rspec. The test database owns the same structure as the real expertiza database, including the relations between tables and some restriction of attribute like it cannot be null or some other requirements for different attributes. Besides, the data in test database is the same as the data in factories part in spec, which includes FeedbackResponseMap.rb, Respone.rb, factories.rb, quiz_factory.rb. In this situation we do not need to create some data before testing, and we can use the data in test DB directly. Because of it, the overhead of testing cases will experience obvious decreasing.&lt;br /&gt;
=== feature test design ===&lt;br /&gt;
To accelerate the feature test, we have to eliminate pseudo data creation. Now all the feature tests have to create their own data before each test. After building a test database, all the pseudo data creation statement can be removed from the test files. Instead, the tests reference data stored in the test database.&lt;/div&gt;</summary>
		<author><name>Jdeng8</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2016/E1701._Accelerate_RSpec_testing&amp;diff=104773</id>
		<title>CSC/ECE 517 Fall 2016/E1701. Accelerate RSpec testing</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2016/E1701._Accelerate_RSpec_testing&amp;diff=104773"/>
		<updated>2016-11-08T22:06:27Z</updated>

		<summary type="html">&lt;p&gt;Jdeng8: /* factories design */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== '''Eexpertiza''' ==&lt;br /&gt;
== '''Rspec''' ==&lt;br /&gt;
== '''Problem Statement''' ==&lt;br /&gt;
Expertiza is a web application where students can submit and peer-review learning objects (articles, code, web sites, etc). It is used in select courses at NC State and by professors at several other colleges and universities.&lt;br /&gt;
Unfortunately, Expertiza tests are really slow. If you check the TravisCI, it needs more than 9 min to run all tests. &lt;br /&gt;
One reason is that we use fixture to create records in test DB each time running tests.&lt;br /&gt;
&lt;br /&gt;
For example, the codes in quiz_spec.rb contain too much create so that prolong testing time.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
   # Create an assignment due date&lt;br /&gt;
    create(:deadline_type, name: &amp;quot;submission&amp;quot;)&lt;br /&gt;
    create(:deadline_type, name: &amp;quot;review&amp;quot;)&lt;br /&gt;
    create(:deadline_type, name: &amp;quot;metareview&amp;quot;)&lt;br /&gt;
    create(:deadline_type, name: &amp;quot;drop_topic&amp;quot;)&lt;br /&gt;
    create(:deadline_type, name: &amp;quot;signup&amp;quot;)&lt;br /&gt;
    create(:deadline_type, name: &amp;quot;team_formation&amp;quot;)&lt;br /&gt;
    create(:deadline_right)&lt;br /&gt;
    create(:deadline_right, name: 'Late')&lt;br /&gt;
    create(:deadline_right, name: 'OK')&lt;br /&gt;
    create :assignment_due_date, due_at: (DateTime.now + 1)&lt;br /&gt;
&amp;lt;/pre&amp;gt; &lt;br /&gt;
&lt;br /&gt;
One solution is building an complete database to one time to support all RSpec test without create new records.&lt;br /&gt;
== '''Related Work''' ==&lt;br /&gt;
* Classes involved:  All RSpec test files in Expertiza.&lt;br /&gt;
* Database involved: Expertiza_test &lt;br /&gt;
&lt;br /&gt;
== '''Task''' ==&lt;br /&gt;
Formally, you need to:&lt;br /&gt;
* Create the records in test DB according to the content in fixtures.&lt;br /&gt;
* Check each test file and delete certain DB records creation code that insert default records (eg. create(:deadline_type)) &lt;br /&gt;
* And keep all the test cases passing when using test DB and make sure the time running test cases is shorter than before.&lt;br /&gt;
* You should submit the sql file of test DB to expertiza.&lt;br /&gt;
&lt;br /&gt;
== '''Design''' ==&lt;br /&gt;
=== Database design ===&lt;br /&gt;
=== feature test design ===&lt;br /&gt;
To accelerate the feature test, we have to eliminate pseudo data creation. Now all the feature tests have to create their own data before each test. After building a test database, all the pseudo data creation statement can be removed from the test files. Instead, the tests reference data stored in the test database.&lt;/div&gt;</summary>
		<author><name>Jdeng8</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2016/E1701._Accelerate_RSpec_testing&amp;diff=104761</id>
		<title>CSC/ECE 517 Fall 2016/E1701. Accelerate RSpec testing</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2016/E1701._Accelerate_RSpec_testing&amp;diff=104761"/>
		<updated>2016-11-08T21:44:12Z</updated>

		<summary type="html">&lt;p&gt;Jdeng8: /* E1701. Accelerate RSpec testing */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Problem Statement =&lt;br /&gt;
Expertiza tests are really slow. If you check the TravisCI, it needs more than 9 min to run all tests. &lt;br /&gt;
One reason is that we use fixture to create records in test DB each time running tests.&lt;br /&gt;
&lt;br /&gt;
= Related Work =&lt;br /&gt;
* Classes involved:  All RSpec test files in Expertiza.&lt;br /&gt;
* Database involved: Expertiza_test &lt;br /&gt;
&lt;br /&gt;
= Task =&lt;br /&gt;
Formally, you need to:&lt;br /&gt;
* Create the records in test DB according to the content in fixtures.&lt;br /&gt;
* Check each test file and delete certain DB records creation code that insert default records (eg. create(:deadline_type)) &lt;br /&gt;
* And keep all the test cases passing when using test DB and make sure the time running test cases is shorter than before.&lt;br /&gt;
* You should submit the sql file of test DB to expertiza.&lt;/div&gt;</summary>
		<author><name>Jdeng8</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2016/E1641._Refactor_review_mapping_controller.rb&amp;diff=104379</id>
		<title>CSC/ECE 517 Fall 2016/E1641. Refactor review mapping controller.rb</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2016/E1641._Refactor_review_mapping_controller.rb&amp;diff=104379"/>
		<updated>2016-11-04T18:20:59Z</updated>

		<summary type="html">&lt;p&gt;Jdeng8: /* Test */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=Background=&lt;br /&gt;
&lt;br /&gt;
This controller sets up mappings between reviewer and reviewee. It handles all different types of response maps (review response map, author feedback response map, teammate review response map, meta review response map and quiz response map). The class has functionality for five different kinds of Responses: reviews, metareviews, teammate reviews, author feedback (“rejoinders”), and quizzes. &lt;br /&gt;
&lt;br /&gt;
=Current Implementation and Problems=&lt;br /&gt;
The controller has many methods and involve with many other controllers and views, the code is long and complicated. Some of the methods in this controller have unreasonable name associated with their functions, some methods are too long, some methods haven't been used by any other methods or views. Our work is to refactor these problems and make the code more beautiful.&lt;br /&gt;
&lt;br /&gt;
The problems are:&lt;br /&gt;
&lt;br /&gt;
# Method ''response_report'' has some SQL - like code.  Rewrite with Active Record.&lt;br /&gt;
# Test whether method ''add_user_to_assignment'' is used. There is no way that this method should be in ReviewMappingController. Please remove this method and caller.&lt;br /&gt;
# There was a ''self-review'' feature, the method ''add_self_reviewer'', ''get_team_from_submission'' are related to this. Two views calls ''add_self_reviewer'' are &amp;quot;show_available_submissions_for_quizzes.html.erb&amp;quot; and &amp;quot;show_available_submissions.html.erb&amp;quot;. The names of views are not related to ''self_review'' feature. Plus those two views are not called anywhere. Please verify this and if so, you should delete those two views, two method and also related records (e.g. in routes.rb).&lt;br /&gt;
# Method ''delete_all_reviewers'' actually only deletes the outstanding review response maps (the ones which has been initiated, but there is no response yet). So it should better be named ''delete_outstanding_reviewers''. You can try to test this method by clicking “Assign reviewers” icon on an assignment.&lt;br /&gt;
# Method ''release_reservation'' should be renamed as'' release_mapping''. In addition, delete it if you find this method is not called anywhere.&lt;br /&gt;
# Method ''delete_mappings'' is problematic. It does not looks like a controller method. Please refactor it or delete it if you can validate that this method is not called anywhere.&lt;br /&gt;
# Method'' automatic_review_mapping_strategy'' is too long. Please refactor and test it.&lt;br /&gt;
&lt;br /&gt;
=Changes Implemented=&lt;br /&gt;
&lt;br /&gt;
# change the rails query from sql like code, like ReviewResponseMap.where(['reviewee_id = ? and reviewer_id = ? ', params[:contributor_id], reviewer.id]) to more rails quey like ReviewResponseMap.where(reviewee_id: params[:contributor_id],reviewer_id: reviewer.id)&lt;br /&gt;
# We search the function name(''add_user_to_assignment'') in the whole files, and find that this method is invoked in &amp;quot;participants_helper.rb&amp;quot;, and also being invoked in the function of ''add_reviewer'' and ''add_metareviewer'' in the controller of ''review_mapping_controller'' &lt;br /&gt;
# By searching the whole project and routes, we verify that methods ''add_self_reviewer'' and ''get_team_from_submission'' in this controller are not called by any other methods except for views &amp;quot;show_available_submissions_for_quizzes.html.erb&amp;quot; and &amp;quot;show_available_submissions.html.erb&amp;quot;. And those two views are not linked to any other views. So they are deleted from the project.&lt;br /&gt;
# We already renamed method ''delete_all_reviewers'' to ''delete_outstanding_reviewers'' and changed the corresponding button name at the corresponding view (_list_review_mappings.html.erb).&lt;br /&gt;
# By searching the whole project and routes, we verify that methods'' release_reservation'' in this controller are not used in anywhere.&lt;br /&gt;
# By searching the whole project and routes, we verify that methods ''delete_mappings'' in this controller are not used in anywhere.&lt;br /&gt;
# Method ''automatic_review_mapping_strategy'' have many long lines. We already shorten each long line to multiple lines. And also, we split this long function into three different functions.&lt;br /&gt;
&lt;br /&gt;
=Code=&lt;br /&gt;
&lt;br /&gt;
==Refactor SQL query code==&lt;br /&gt;
&lt;br /&gt;
The rails query we change in this controller:&lt;br /&gt;
&lt;br /&gt;
1. From &lt;br /&gt;
&lt;br /&gt;
  ReviewResponseMap.where(['reviewee_id = ? and reviewer_id = ? ', params[:contributor_id], reviewer.id]) &lt;br /&gt;
&lt;br /&gt;
To&lt;br /&gt;
&lt;br /&gt;
  ReviewResponseMap.where(reviewee_id: params[:contributor_id],reviewer_id: reviewer.id)&lt;br /&gt;
&lt;br /&gt;
2. From&lt;br /&gt;
&lt;br /&gt;
  MetareviewResponseMap.where(['reviewed_object_id = ? and reviewer_id = ?', mapping.map_id, reviewer.id])&lt;br /&gt;
&lt;br /&gt;
To&lt;br /&gt;
&lt;br /&gt;
  MetareviewResponseMap.where(reviewed_object_id: mapping.map_id, reviewer_id: reviewer.id)&lt;br /&gt;
&lt;br /&gt;
3. From&lt;br /&gt;
&lt;br /&gt;
                   @assignments = Assignment&lt;br /&gt;
                   .where([&amp;quot;instructor_id = ? and substring(name,1,1) = ?&amp;quot;, session[:user].id, letter])&lt;br /&gt;
                   .order('name')&lt;br /&gt;
                   .page(params[:page])&lt;br /&gt;
                   .per_page(10)&lt;br /&gt;
&lt;br /&gt;
To &lt;br /&gt;
&lt;br /&gt;
                   @assignments = Assignment&lt;br /&gt;
                   .where(instructor_id:session[:user].id)&lt;br /&gt;
                   .where(&amp;quot;substring(name,1,1) = :letter&amp;quot;,{letter:letter})&lt;br /&gt;
                   .order('name')&lt;br /&gt;
                   .page(params[:page])&lt;br /&gt;
                   .per_page(10)&lt;br /&gt;
&lt;br /&gt;
4.  From&lt;br /&gt;
&lt;br /&gt;
  ReviewResponseMap.where([&amp;quot;reviewed_object_id = ? and calibrate_to = ?&amp;quot;, assignment_id, 1])&lt;br /&gt;
&lt;br /&gt;
To &lt;br /&gt;
&lt;br /&gt;
  ReviewResponseMap.where(reviewed_object_id:assignment_id, calibrate_to: 1)&lt;br /&gt;
&lt;br /&gt;
5. From&lt;br /&gt;
&lt;br /&gt;
  ReviewResponseMap.where([&amp;quot;reviewed_object_id = ? and created_at &amp;gt; ? and calibrate_to = ?&amp;quot;, assignment_id, @@time_create_last_review_mapping_record, 0])&lt;br /&gt;
&lt;br /&gt;
To &lt;br /&gt;
&lt;br /&gt;
  ReviewResponseMap.where(reviewed_object_id:assignment_id,calibrate_to:0).where(&amp;quot;created_at &amp;gt; :time&amp;quot;,{time:@@time_create_last_review_mapping_record})&lt;br /&gt;
&lt;br /&gt;
6. From&lt;br /&gt;
&lt;br /&gt;
  AssignmentQuestionnaire.where([&amp;quot;assignment_id = ? and questionnaire_id IN (?)&amp;quot;, params[:id], @review_questionnaire_ids])&lt;br /&gt;
&lt;br /&gt;
To&lt;br /&gt;
 &lt;br /&gt;
  AssignmentQuestionnaire.where(assignment_id: params[:id],:questionnaire_id =&amp;gt; @review_questionnaire_ids)&lt;br /&gt;
&lt;br /&gt;
7. From&lt;br /&gt;
&lt;br /&gt;
  SelfReviewResponseMap.where(['reviewee_id = ? and reviewer_id = ?', team_id[0].t_id, params[:reviewer_id]])&lt;br /&gt;
&lt;br /&gt;
To &lt;br /&gt;
&lt;br /&gt;
  SelfReviewResponseMap.where(reviewee_id:team_id[0].t_id,reviewer_id:params[:reviewer_id])&lt;br /&gt;
&lt;br /&gt;
==Refactor long line method==&lt;br /&gt;
&lt;br /&gt;
  def automatic_review_mapping_strategy(assignment_id,&lt;br /&gt;
                                        participants, teams, student_review_num = 0,&lt;br /&gt;
                                        submission_review_num = 0)&lt;br /&gt;
    participants_hash = {}&lt;br /&gt;
    participants.each {|participant| participants_hash[participant.id] = 0 }&lt;br /&gt;
    # calculate reviewers for each team&lt;br /&gt;
    num_participants = participants.size&lt;br /&gt;
    if student_review_num != 0 and submission_review_num == 0&lt;br /&gt;
      num_reviews_per_team = (participants.size * student_review_num * 1.0 / teams.size).round&lt;br /&gt;
      student_review_num = student_review_num&lt;br /&gt;
      exact_num_of_review_needed = participants.size * student_review_num&lt;br /&gt;
    elsif student_review_num == 0 and submission_review_num != 0&lt;br /&gt;
      num_reviews_per_team = submission_review_num&lt;br /&gt;
      student_review_num = (teams.size * submission_review_num * 1.0 / participants.size).round&lt;br /&gt;
      exact_num_of_review_needed = teams.size * submission_review_num&lt;br /&gt;
    end&lt;br /&gt;
    execute_peer_review_strategy(assignment_id, teams, num_participants,&lt;br /&gt;
                                     student_review_num, num_reviews_per_team,&lt;br /&gt;
                                     participants, participants_hash)&lt;br /&gt;
    # after assigning peer reviews for each team,&lt;br /&gt;
    # if there are still some peer reviewers not obtain enough peer review,&lt;br /&gt;
    # just assign them to valid teams&lt;br /&gt;
    assign_reviewers_for_team(assignment_id,student_review_num,participants_hash,&lt;br /&gt;
                              exact_num_of_review_needed)&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  def assign_reviewers_for_team(assignment_id,student_review_num,participants_hash,&lt;br /&gt;
                                exact_num_of_review_needed)&lt;br /&gt;
     if ReviewResponseMap.where(reviewed_object_id:assignment_id,calibrate_to:0)&lt;br /&gt;
             .where(&amp;quot;created_at &amp;gt; :time&amp;quot;,&lt;br /&gt;
          {time:@@time_create_last_review_mapping_record}).size &amp;lt; exact_num_of_review_needed&lt;br /&gt;
      participants_with_insufficient_review_num = []&lt;br /&gt;
      participants_hash.each do |participant_id, review_num|&lt;br /&gt;
        participants_with_insufficient_review_num &amp;lt;&amp;lt; participant_id if review_num &amp;lt; student_review_num&lt;br /&gt;
      end&lt;br /&gt;
      unsorted_teams_hash = {}&lt;br /&gt;
     ReviewResponseMap.where(reviewed_object_id:assignment_id,&lt;br /&gt;
                  calibrate_to:0).each do |response_map|&lt;br /&gt;
        if unsorted_teams_hash.key? response_map.reviewee_id&lt;br /&gt;
          unsorted_teams_hash[response_map.reviewee_id] += 1&lt;br /&gt;
        else&lt;br /&gt;
          unsorted_teams_hash[response_map.reviewee_id] = 1&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
      teams_hash = unsorted_teams_hash.sort_by {|_, v| v }.to_h&lt;br /&gt;
      participants_with_insufficient_review_num.each do |participant_id|&lt;br /&gt;
        teams_hash.each do |team_id, _num_review_received|&lt;br /&gt;
          next if TeamsUser.exists?(team_id: team_id, &lt;br /&gt;
                                    user_id: Participant.find(participant_id).user_id)&lt;br /&gt;
          ReviewResponseMap.where(reviewee_id: team_id, reviewer_id: participant_id, &lt;br /&gt;
                                  reviewed_object_id: assignment_id).first_or_create&lt;br /&gt;
          teams_hash[team_id] += 1&lt;br /&gt;
          teams_hash = teams_hash.sort_by {|_, v| v }.to_h&lt;br /&gt;
          break&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
    @@time_create_last_review_mapping_record = ReviewResponseMap.&lt;br /&gt;
                                               where(reviewed_object_id: assignment_id).&lt;br /&gt;
                                               last.created_at&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def execute_peer_review_strategy(assignment_id, teams, num_participants, &lt;br /&gt;
                                   student_review_num, num_reviews_per_team, &lt;br /&gt;
                                   participants, participants_hash)&lt;br /&gt;
    # Exception detection: If instructor want to assign too many reviews done&lt;br /&gt;
    # by each student, there will be an error msg.&lt;br /&gt;
    if student_review_num &amp;gt;= teams.size&lt;br /&gt;
      flash[:error] = 'You cannot set the number of reviews done &lt;br /&gt;
      by each student to be greater than or equal to total number of teams &lt;br /&gt;
      [or &amp;quot;participants&amp;quot; if it is an individual assignment].'&lt;br /&gt;
    end&lt;br /&gt;
    peer_review_strategy(assignment_id, teams, num_participants, &lt;br /&gt;
                         student_review_num, num_reviews_per_team, &lt;br /&gt;
                         participants, participants_hash)&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
=Test=&lt;br /&gt;
# We test delete_outstanding_reviewers refactor from the UI. Here is a video for this test. https://youtu.be/MZxOaSsm58E&lt;br /&gt;
# We use some data to test the result of old query and new query in rails console&lt;br /&gt;
 &lt;br /&gt;
  ReviewResponseMap.where(['reviewee_id = ? and reviewer_id = ? ‘,6050, 9])&lt;br /&gt;
  ReviewResponseMap.where(reviewee_id: 6050,reviewer_id: 9)&lt;br /&gt;
&lt;br /&gt;
  Assignment.where([&amp;quot;instructor_id = ? and substring(name,1,1) = ?&amp;quot;, 2, ‘TestAssign2’]).order('name')&lt;br /&gt;
  Assignment .where(instructor_id:2).where(&amp;quot;substring(name,1,1) = :letter&amp;quot;,{letter:’TestAssign2’}).order('name')&lt;br /&gt;
&lt;br /&gt;
  ReviewResponseMap.where([&amp;quot;reviewed_object_id = ? and created_at &amp;gt; ? and calibrate_to = ?&amp;quot;, 13, nil, 0])&lt;br /&gt;
  ReviewResponseMap.where(reviewed_object_id:13,calibrate_to:0).where(&amp;quot;created_at &amp;gt; :time&amp;quot;,{time:nil})&lt;br /&gt;
&lt;br /&gt;
# We write RSpec feature tests to prove that all changes are correct and the project performs well as before. All tests have passed.&lt;br /&gt;
Automatic_review_mapping method&lt;br /&gt;
&lt;br /&gt;
The function of  method automatic_review_mapping is to automatically assign reviews on students in teams when instructor set either student review number or submissions review number. There is constraint that only one of the two numbers must be set value other than 0 (that is, one is 0 and other is not 0). To test the correctness  of our refactoring, we design a scenario and 4 cases of assigning reviews to students:&lt;br /&gt;
&lt;br /&gt;
Case 1. Instructor has not set both students review number and submissions review number (They are both 0). The page will show a notice.&lt;br /&gt;
&lt;br /&gt;
Case 2. Instructor set both numbers (They are both not 0). The page will show a notice.&lt;br /&gt;
&lt;br /&gt;
Case 3. Instructors set students review number. The controller will change database: create new relationship in ReviewResponseMap. For example, if assign student review number to 2, and there will be 20 peer reviews in total and need to allocate to 3 teams. So each team get 7 reviews on average and 1 team’s artifact will be reviewed 6 times.&lt;br /&gt;
&lt;br /&gt;
Case 4. Instructors set submissions review number. The controller will change database: create new relationship in ReviewResponseMap. For example, if assign submission review number to 3, and there will be 21 peer reviews in total to allocate to 10 participants. So every participants get 2 reviews. 9 among 10 participants will review 2 teams’ artifacts and 1 participant will review 3 teams’ artifacts.&lt;br /&gt;
&lt;br /&gt;
require 'rails_helper'&lt;br /&gt;
  describe &amp;quot;review mapping&amp;quot;, js: true do&lt;br /&gt;
    before(:each) do&lt;br /&gt;
      .#create test data&lt;br /&gt;
    end&lt;br /&gt;
 &lt;br /&gt;
    it &amp;quot;show error when assign both 0&amp;quot; do&lt;br /&gt;
      login_as(&amp;quot;instructor6&amp;quot;)&lt;br /&gt;
      visit '/assignments/1/edit'&lt;br /&gt;
      find_link('ReviewStrategy').click&lt;br /&gt;
      select &amp;quot;Instructor-Selected&amp;quot;, from: 'assignment_form_assignment_review_assignment_strategy'&lt;br /&gt;
      fill_in 'num_reviews_per_student', with: 0&lt;br /&gt;
      choose 'num_reviews_submission'&lt;br /&gt;
      fill_in 'num_reviews_per_submission', with: 0&lt;br /&gt;
      click_button 'second_submit_tag'&lt;br /&gt;
      #click_button 'Save'&lt;br /&gt;
      expect(page).to have_content('Please choose either the number of reviews per student or the number of reviewers per team (student)')&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    it &amp;quot;show error when assign both numbers&amp;quot; do&lt;br /&gt;
      login_as(&amp;quot;instructor6&amp;quot;)&lt;br /&gt;
      visit '/assignments/1/edit'&lt;br /&gt;
      find_link('ReviewStrategy').click&lt;br /&gt;
      select &amp;quot;Instructor-Selected&amp;quot;, from: 'assignment_form_assignment_review_assignment_strategy'&lt;br /&gt;
      fill_in 'num_reviews_per_student', with: 1&lt;br /&gt;
      choose 'num_reviews_submission'&lt;br /&gt;
      fill_in 'num_reviews_per_submission', with: 1&lt;br /&gt;
      click_button 'second_submit_tag'&lt;br /&gt;
      #click_button 'Save'&lt;br /&gt;
      expect(page).to have_content('Please choose either the number of reviews per student or the number of reviewers per team (student), not both')&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    it &amp;quot;calculate reviewmapping from given review number per student&amp;quot; do&lt;br /&gt;
      login_as(&amp;quot;instructor6&amp;quot;)&lt;br /&gt;
      visit '/assignments/1/edit'&lt;br /&gt;
      find_link('ReviewStrategy').click&lt;br /&gt;
      select &amp;quot;Instructor-Selected&amp;quot;, from: 'assignment_form_assignment_review_assignment_strategy'&lt;br /&gt;
      fill_in 'num_reviews_per_student', with: 2&lt;br /&gt;
      click_button 'first_submit_tag'&lt;br /&gt;
      num = ReviewResponseMap.where(reviewee_id: @team1.id, reviewed_object_id: @assignment.id).count&lt;br /&gt;
      expect(num).to eq(7)&lt;br /&gt;
      num2 = ReviewResponseMap.where(reviewee_id: @team3.id, reviewed_object_id: @assignment.id).count&lt;br /&gt;
      expect(num2).to eq(6)&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    it &amp;quot;calculate reviewmapping from given review number per submission&amp;quot; do&lt;br /&gt;
      login_as(&amp;quot;instructor6&amp;quot;)&lt;br /&gt;
      visit '/assignments/1/edit'&lt;br /&gt;
      find_link('ReviewStrategy').click&lt;br /&gt;
      select &amp;quot;Instructor-Selected&amp;quot;, from: 'assignment_form_assignment_review_assignment_strategy'&lt;br /&gt;
      choose 'num_reviews_submission'&lt;br /&gt;
      fill_in 'num_reviews_per_submission', with: 7&lt;br /&gt;
      click_button 'second_submit_tag'&lt;br /&gt;
      #click_button 'Save'&lt;br /&gt;
      num = ReviewResponseMap.where(reviewer_id: @teamuser1.id, reviewed_object_id: @assignment.id).count&lt;br /&gt;
      expect(num).to eq(2)&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
Refactoring add_reviewer, add_metareviewer, delete_reviewer, delete_metareviewer, delete_outstanding_reviewers and delete_all_metareviewers&lt;br /&gt;
Since we merge methods have similar functions, we need to test their functionality. Here is a feature test work flow include those refactored functions.&lt;br /&gt;
    it &amp;quot;can add reviewer then delete it&amp;quot; do&lt;br /&gt;
 &lt;br /&gt;
       @student_reviewer = create :student,name:'student_reviewer'&lt;br /&gt;
       @participant_reviewer = create :participant, assignment: @assignment, user: @student_reviewer&lt;br /&gt;
       @student_reviewer2 = create :student,name:'student_reviewer2'&lt;br /&gt;
       @participant_reviewer2 = create :participant, assignment: @assignment, user: @student_reviewer2&lt;br /&gt;
       login_and_assign_reviewer(&amp;quot;instructor6&amp;quot;,@assignment.id,0,0)&lt;br /&gt;
 &lt;br /&gt;
       first(:link,'add reviewer').click&lt;br /&gt;
       add_reviewer(@student_reviewer.name)&lt;br /&gt;
       expect(page).to have_content @student_reviewer.name&lt;br /&gt;
       click_link('delete')&lt;br /&gt;
       expect(page).to have_content (&amp;quot;The review mapping for \&amp;quot;#{@team1.name}\&amp;quot; and \&amp;quot;#{@student_reviewer.name}\&amp;quot; has been deleted&amp;quot;)&lt;br /&gt;
 &lt;br /&gt;
       first(:link,'add reviewer').click&lt;br /&gt;
       add_reviewer(@student_reviewer.name)&lt;br /&gt;
       click_link('add metareviewer')&lt;br /&gt;
       add_matareviewer(@student_reviewer2.name)&lt;br /&gt;
       expect(page).to have_content @student_reviewer2.name&lt;br /&gt;
       find(:xpath, &amp;quot;//a[@href='/review_mapping/delete_metareviewer?id=3']&amp;quot;).click&lt;br /&gt;
       expect(page).to have_content (&amp;quot;The metareview mapping for #{@student_reviewer.name} and #{@student_reviewer2.name} has been deleted&amp;quot;)&lt;br /&gt;
 &lt;br /&gt;
       click_link('add metareviewer')&lt;br /&gt;
       add_matareviewer(@student_reviewer2.name)&lt;br /&gt;
       click_link('delete all metareviewers')&lt;br /&gt;
       expect(page).to have_content (&amp;quot;All metareview mappings for contributor \&amp;quot;#{@team1.name}\&amp;quot; and reviewer \&amp;quot;#{@student_reviewer.name}\&amp;quot; have been deleted&amp;quot;)&lt;br /&gt;
 &lt;br /&gt;
       first(:link,'delete outstanding reviewers').click&lt;br /&gt;
       expect(page).to have_content (&amp;quot;All review mappings for \&amp;quot;#{@team1.name}\&amp;quot; have been deleted&amp;quot;)&lt;br /&gt;
 &lt;br /&gt;
     end&lt;/div&gt;</summary>
		<author><name>Jdeng8</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2016/E1641._Refactor_review_mapping_controller.rb&amp;diff=104378</id>
		<title>CSC/ECE 517 Fall 2016/E1641. Refactor review mapping controller.rb</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2016/E1641._Refactor_review_mapping_controller.rb&amp;diff=104378"/>
		<updated>2016-11-04T18:19:41Z</updated>

		<summary type="html">&lt;p&gt;Jdeng8: /* Test */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=Background=&lt;br /&gt;
&lt;br /&gt;
This controller sets up mappings between reviewer and reviewee. It handles all different types of response maps (review response map, author feedback response map, teammate review response map, meta review response map and quiz response map). The class has functionality for five different kinds of Responses: reviews, metareviews, teammate reviews, author feedback (“rejoinders”), and quizzes. &lt;br /&gt;
&lt;br /&gt;
=Current Implementation and Problems=&lt;br /&gt;
The controller has many methods and involve with many other controllers and views, the code is long and complicated. Some of the methods in this controller have unreasonable name associated with their functions, some methods are too long, some methods haven't been used by any other methods or views. Our work is to refactor these problems and make the code more beautiful.&lt;br /&gt;
&lt;br /&gt;
The problems are:&lt;br /&gt;
&lt;br /&gt;
# Method ''response_report'' has some SQL - like code.  Rewrite with Active Record.&lt;br /&gt;
# Test whether method ''add_user_to_assignment'' is used. There is no way that this method should be in ReviewMappingController. Please remove this method and caller.&lt;br /&gt;
# There was a ''self-review'' feature, the method ''add_self_reviewer'', ''get_team_from_submission'' are related to this. Two views calls ''add_self_reviewer'' are &amp;quot;show_available_submissions_for_quizzes.html.erb&amp;quot; and &amp;quot;show_available_submissions.html.erb&amp;quot;. The names of views are not related to ''self_review'' feature. Plus those two views are not called anywhere. Please verify this and if so, you should delete those two views, two method and also related records (e.g. in routes.rb).&lt;br /&gt;
# Method ''delete_all_reviewers'' actually only deletes the outstanding review response maps (the ones which has been initiated, but there is no response yet). So it should better be named ''delete_outstanding_reviewers''. You can try to test this method by clicking “Assign reviewers” icon on an assignment.&lt;br /&gt;
# Method ''release_reservation'' should be renamed as'' release_mapping''. In addition, delete it if you find this method is not called anywhere.&lt;br /&gt;
# Method ''delete_mappings'' is problematic. It does not looks like a controller method. Please refactor it or delete it if you can validate that this method is not called anywhere.&lt;br /&gt;
# Method'' automatic_review_mapping_strategy'' is too long. Please refactor and test it.&lt;br /&gt;
&lt;br /&gt;
=Changes Implemented=&lt;br /&gt;
&lt;br /&gt;
# change the rails query from sql like code, like ReviewResponseMap.where(['reviewee_id = ? and reviewer_id = ? ', params[:contributor_id], reviewer.id]) to more rails quey like ReviewResponseMap.where(reviewee_id: params[:contributor_id],reviewer_id: reviewer.id)&lt;br /&gt;
# We search the function name(''add_user_to_assignment'') in the whole files, and find that this method is invoked in &amp;quot;participants_helper.rb&amp;quot;, and also being invoked in the function of ''add_reviewer'' and ''add_metareviewer'' in the controller of ''review_mapping_controller'' &lt;br /&gt;
# By searching the whole project and routes, we verify that methods ''add_self_reviewer'' and ''get_team_from_submission'' in this controller are not called by any other methods except for views &amp;quot;show_available_submissions_for_quizzes.html.erb&amp;quot; and &amp;quot;show_available_submissions.html.erb&amp;quot;. And those two views are not linked to any other views. So they are deleted from the project.&lt;br /&gt;
# We already renamed method ''delete_all_reviewers'' to ''delete_outstanding_reviewers'' and changed the corresponding button name at the corresponding view (_list_review_mappings.html.erb).&lt;br /&gt;
# By searching the whole project and routes, we verify that methods'' release_reservation'' in this controller are not used in anywhere.&lt;br /&gt;
# By searching the whole project and routes, we verify that methods ''delete_mappings'' in this controller are not used in anywhere.&lt;br /&gt;
# Method ''automatic_review_mapping_strategy'' have many long lines. We already shorten each long line to multiple lines. And also, we split this long function into three different functions.&lt;br /&gt;
&lt;br /&gt;
=Code=&lt;br /&gt;
&lt;br /&gt;
==Refactor SQL query code==&lt;br /&gt;
&lt;br /&gt;
The rails query we change in this controller:&lt;br /&gt;
&lt;br /&gt;
1. From &lt;br /&gt;
&lt;br /&gt;
  ReviewResponseMap.where(['reviewee_id = ? and reviewer_id = ? ', params[:contributor_id], reviewer.id]) &lt;br /&gt;
&lt;br /&gt;
To&lt;br /&gt;
&lt;br /&gt;
  ReviewResponseMap.where(reviewee_id: params[:contributor_id],reviewer_id: reviewer.id)&lt;br /&gt;
&lt;br /&gt;
2. From&lt;br /&gt;
&lt;br /&gt;
  MetareviewResponseMap.where(['reviewed_object_id = ? and reviewer_id = ?', mapping.map_id, reviewer.id])&lt;br /&gt;
&lt;br /&gt;
To&lt;br /&gt;
&lt;br /&gt;
  MetareviewResponseMap.where(reviewed_object_id: mapping.map_id, reviewer_id: reviewer.id)&lt;br /&gt;
&lt;br /&gt;
3. From&lt;br /&gt;
&lt;br /&gt;
                   @assignments = Assignment&lt;br /&gt;
                   .where([&amp;quot;instructor_id = ? and substring(name,1,1) = ?&amp;quot;, session[:user].id, letter])&lt;br /&gt;
                   .order('name')&lt;br /&gt;
                   .page(params[:page])&lt;br /&gt;
                   .per_page(10)&lt;br /&gt;
&lt;br /&gt;
To &lt;br /&gt;
&lt;br /&gt;
                   @assignments = Assignment&lt;br /&gt;
                   .where(instructor_id:session[:user].id)&lt;br /&gt;
                   .where(&amp;quot;substring(name,1,1) = :letter&amp;quot;,{letter:letter})&lt;br /&gt;
                   .order('name')&lt;br /&gt;
                   .page(params[:page])&lt;br /&gt;
                   .per_page(10)&lt;br /&gt;
&lt;br /&gt;
4.  From&lt;br /&gt;
&lt;br /&gt;
  ReviewResponseMap.where([&amp;quot;reviewed_object_id = ? and calibrate_to = ?&amp;quot;, assignment_id, 1])&lt;br /&gt;
&lt;br /&gt;
To &lt;br /&gt;
&lt;br /&gt;
  ReviewResponseMap.where(reviewed_object_id:assignment_id, calibrate_to: 1)&lt;br /&gt;
&lt;br /&gt;
5. From&lt;br /&gt;
&lt;br /&gt;
  ReviewResponseMap.where([&amp;quot;reviewed_object_id = ? and created_at &amp;gt; ? and calibrate_to = ?&amp;quot;, assignment_id, @@time_create_last_review_mapping_record, 0])&lt;br /&gt;
&lt;br /&gt;
To &lt;br /&gt;
&lt;br /&gt;
  ReviewResponseMap.where(reviewed_object_id:assignment_id,calibrate_to:0).where(&amp;quot;created_at &amp;gt; :time&amp;quot;,{time:@@time_create_last_review_mapping_record})&lt;br /&gt;
&lt;br /&gt;
6. From&lt;br /&gt;
&lt;br /&gt;
  AssignmentQuestionnaire.where([&amp;quot;assignment_id = ? and questionnaire_id IN (?)&amp;quot;, params[:id], @review_questionnaire_ids])&lt;br /&gt;
&lt;br /&gt;
To&lt;br /&gt;
 &lt;br /&gt;
  AssignmentQuestionnaire.where(assignment_id: params[:id],:questionnaire_id =&amp;gt; @review_questionnaire_ids)&lt;br /&gt;
&lt;br /&gt;
7. From&lt;br /&gt;
&lt;br /&gt;
  SelfReviewResponseMap.where(['reviewee_id = ? and reviewer_id = ?', team_id[0].t_id, params[:reviewer_id]])&lt;br /&gt;
&lt;br /&gt;
To &lt;br /&gt;
&lt;br /&gt;
  SelfReviewResponseMap.where(reviewee_id:team_id[0].t_id,reviewer_id:params[:reviewer_id])&lt;br /&gt;
&lt;br /&gt;
==Refactor long line method==&lt;br /&gt;
&lt;br /&gt;
  def automatic_review_mapping_strategy(assignment_id,&lt;br /&gt;
                                        participants, teams, student_review_num = 0,&lt;br /&gt;
                                        submission_review_num = 0)&lt;br /&gt;
    participants_hash = {}&lt;br /&gt;
    participants.each {|participant| participants_hash[participant.id] = 0 }&lt;br /&gt;
    # calculate reviewers for each team&lt;br /&gt;
    num_participants = participants.size&lt;br /&gt;
    if student_review_num != 0 and submission_review_num == 0&lt;br /&gt;
      num_reviews_per_team = (participants.size * student_review_num * 1.0 / teams.size).round&lt;br /&gt;
      student_review_num = student_review_num&lt;br /&gt;
      exact_num_of_review_needed = participants.size * student_review_num&lt;br /&gt;
    elsif student_review_num == 0 and submission_review_num != 0&lt;br /&gt;
      num_reviews_per_team = submission_review_num&lt;br /&gt;
      student_review_num = (teams.size * submission_review_num * 1.0 / participants.size).round&lt;br /&gt;
      exact_num_of_review_needed = teams.size * submission_review_num&lt;br /&gt;
    end&lt;br /&gt;
    execute_peer_review_strategy(assignment_id, teams, num_participants,&lt;br /&gt;
                                     student_review_num, num_reviews_per_team,&lt;br /&gt;
                                     participants, participants_hash)&lt;br /&gt;
    # after assigning peer reviews for each team,&lt;br /&gt;
    # if there are still some peer reviewers not obtain enough peer review,&lt;br /&gt;
    # just assign them to valid teams&lt;br /&gt;
    assign_reviewers_for_team(assignment_id,student_review_num,participants_hash,&lt;br /&gt;
                              exact_num_of_review_needed)&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  def assign_reviewers_for_team(assignment_id,student_review_num,participants_hash,&lt;br /&gt;
                                exact_num_of_review_needed)&lt;br /&gt;
     if ReviewResponseMap.where(reviewed_object_id:assignment_id,calibrate_to:0)&lt;br /&gt;
             .where(&amp;quot;created_at &amp;gt; :time&amp;quot;,&lt;br /&gt;
          {time:@@time_create_last_review_mapping_record}).size &amp;lt; exact_num_of_review_needed&lt;br /&gt;
      participants_with_insufficient_review_num = []&lt;br /&gt;
      participants_hash.each do |participant_id, review_num|&lt;br /&gt;
        participants_with_insufficient_review_num &amp;lt;&amp;lt; participant_id if review_num &amp;lt; student_review_num&lt;br /&gt;
      end&lt;br /&gt;
      unsorted_teams_hash = {}&lt;br /&gt;
     ReviewResponseMap.where(reviewed_object_id:assignment_id,&lt;br /&gt;
                  calibrate_to:0).each do |response_map|&lt;br /&gt;
        if unsorted_teams_hash.key? response_map.reviewee_id&lt;br /&gt;
          unsorted_teams_hash[response_map.reviewee_id] += 1&lt;br /&gt;
        else&lt;br /&gt;
          unsorted_teams_hash[response_map.reviewee_id] = 1&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
      teams_hash = unsorted_teams_hash.sort_by {|_, v| v }.to_h&lt;br /&gt;
      participants_with_insufficient_review_num.each do |participant_id|&lt;br /&gt;
        teams_hash.each do |team_id, _num_review_received|&lt;br /&gt;
          next if TeamsUser.exists?(team_id: team_id, &lt;br /&gt;
                                    user_id: Participant.find(participant_id).user_id)&lt;br /&gt;
          ReviewResponseMap.where(reviewee_id: team_id, reviewer_id: participant_id, &lt;br /&gt;
                                  reviewed_object_id: assignment_id).first_or_create&lt;br /&gt;
          teams_hash[team_id] += 1&lt;br /&gt;
          teams_hash = teams_hash.sort_by {|_, v| v }.to_h&lt;br /&gt;
          break&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
    @@time_create_last_review_mapping_record = ReviewResponseMap.&lt;br /&gt;
                                               where(reviewed_object_id: assignment_id).&lt;br /&gt;
                                               last.created_at&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def execute_peer_review_strategy(assignment_id, teams, num_participants, &lt;br /&gt;
                                   student_review_num, num_reviews_per_team, &lt;br /&gt;
                                   participants, participants_hash)&lt;br /&gt;
    # Exception detection: If instructor want to assign too many reviews done&lt;br /&gt;
    # by each student, there will be an error msg.&lt;br /&gt;
    if student_review_num &amp;gt;= teams.size&lt;br /&gt;
      flash[:error] = 'You cannot set the number of reviews done &lt;br /&gt;
      by each student to be greater than or equal to total number of teams &lt;br /&gt;
      [or &amp;quot;participants&amp;quot; if it is an individual assignment].'&lt;br /&gt;
    end&lt;br /&gt;
    peer_review_strategy(assignment_id, teams, num_participants, &lt;br /&gt;
                         student_review_num, num_reviews_per_team, &lt;br /&gt;
                         participants, participants_hash)&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
=Test=&lt;br /&gt;
== We test delete_outstanding_reviewers refactor from the UI. Here is a video for this test. https://youtu.be/MZxOaSsm58E&lt;br /&gt;
== We use some data to test the result of old query and new query in rails console&lt;br /&gt;
 &lt;br /&gt;
  ReviewResponseMap.where(['reviewee_id = ? and reviewer_id = ? ‘,6050, 9])&lt;br /&gt;
  ReviewResponseMap.where(reviewee_id: 6050,reviewer_id: 9)&lt;br /&gt;
&lt;br /&gt;
  Assignment.where([&amp;quot;instructor_id = ? and substring(name,1,1) = ?&amp;quot;, 2, ‘TestAssign2’]).order('name')&lt;br /&gt;
  Assignment .where(instructor_id:2).where(&amp;quot;substring(name,1,1) = :letter&amp;quot;,{letter:’TestAssign2’}).order('name')&lt;br /&gt;
&lt;br /&gt;
  ReviewResponseMap.where([&amp;quot;reviewed_object_id = ? and created_at &amp;gt; ? and calibrate_to = ?&amp;quot;, 13, nil, 0])&lt;br /&gt;
  ReviewResponseMap.where(reviewed_object_id:13,calibrate_to:0).where(&amp;quot;created_at &amp;gt; :time&amp;quot;,{time:nil})&lt;br /&gt;
&lt;br /&gt;
== We write RSpec feature tests to prove that all changes are correct and the project performs well as before. All tests have passed.&lt;br /&gt;
=== Automatic_review_mapping method&lt;br /&gt;
&lt;br /&gt;
The function of  method automatic_review_mapping is to automatically assign reviews on students in teams when instructor set either student review number or submissions review number. There is constraint that only one of the two numbers must be set value other than 0 (that is, one is 0 and other is not 0). To test the correctness  of our refactoring, we design a scenario and 4 cases of assigning reviews to students:&lt;br /&gt;
&lt;br /&gt;
Case 1. Instructor has not set both students review number and submissions review number (They are both 0). The page will show a notice.&lt;br /&gt;
&lt;br /&gt;
Case 2. Instructor set both numbers (They are both not 0). The page will show a notice.&lt;br /&gt;
&lt;br /&gt;
Case 3. Instructors set students review number. The controller will change database: create new relationship in ReviewResponseMap. For example, if assign student review number to 2, and there will be 20 peer reviews in total and need to allocate to 3 teams. So each team get 7 reviews on average and 1 team’s artifact will be reviewed 6 times.&lt;br /&gt;
&lt;br /&gt;
Case 4. Instructors set submissions review number. The controller will change database: create new relationship in ReviewResponseMap. For example, if assign submission review number to 3, and there will be 21 peer reviews in total to allocate to 10 participants. So every participants get 2 reviews. 9 among 10 participants will review 2 teams’ artifacts and 1 participant will review 3 teams’ artifacts.&lt;br /&gt;
&lt;br /&gt;
require 'rails_helper'&lt;br /&gt;
  describe &amp;quot;review mapping&amp;quot;, js: true do&lt;br /&gt;
    before(:each) do&lt;br /&gt;
      #create test data&lt;br /&gt;
    end&lt;br /&gt;
 &lt;br /&gt;
    it &amp;quot;show error when assign both 0&amp;quot; do&lt;br /&gt;
      login_as(&amp;quot;instructor6&amp;quot;)&lt;br /&gt;
      visit '/assignments/1/edit'&lt;br /&gt;
      find_link('ReviewStrategy').click&lt;br /&gt;
      select &amp;quot;Instructor-Selected&amp;quot;, from: 'assignment_form_assignment_review_assignment_strategy'&lt;br /&gt;
      fill_in 'num_reviews_per_student', with: 0&lt;br /&gt;
      choose 'num_reviews_submission'&lt;br /&gt;
      fill_in 'num_reviews_per_submission', with: 0&lt;br /&gt;
      click_button 'second_submit_tag'&lt;br /&gt;
      #click_button 'Save'&lt;br /&gt;
      expect(page).to have_content('Please choose either the number of reviews per student or the number of reviewers per team (student)')&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    it &amp;quot;show error when assign both numbers&amp;quot; do&lt;br /&gt;
      login_as(&amp;quot;instructor6&amp;quot;)&lt;br /&gt;
      visit '/assignments/1/edit'&lt;br /&gt;
      find_link('ReviewStrategy').click&lt;br /&gt;
      select &amp;quot;Instructor-Selected&amp;quot;, from: 'assignment_form_assignment_review_assignment_strategy'&lt;br /&gt;
      fill_in 'num_reviews_per_student', with: 1&lt;br /&gt;
      choose 'num_reviews_submission'&lt;br /&gt;
      fill_in 'num_reviews_per_submission', with: 1&lt;br /&gt;
      click_button 'second_submit_tag'&lt;br /&gt;
      #click_button 'Save'&lt;br /&gt;
      expect(page).to have_content('Please choose either the number of reviews per student or the number of reviewers per team (student), not both')&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    it &amp;quot;calculate reviewmapping from given review number per student&amp;quot; do&lt;br /&gt;
      login_as(&amp;quot;instructor6&amp;quot;)&lt;br /&gt;
      visit '/assignments/1/edit'&lt;br /&gt;
      find_link('ReviewStrategy').click&lt;br /&gt;
      select &amp;quot;Instructor-Selected&amp;quot;, from: 'assignment_form_assignment_review_assignment_strategy'&lt;br /&gt;
      fill_in 'num_reviews_per_student', with: 2&lt;br /&gt;
      click_button 'first_submit_tag'&lt;br /&gt;
      num = ReviewResponseMap.where(reviewee_id: @team1.id, reviewed_object_id: @assignment.id).count&lt;br /&gt;
      expect(num).to eq(7)&lt;br /&gt;
      num2 = ReviewResponseMap.where(reviewee_id: @team3.id, reviewed_object_id: @assignment.id).count&lt;br /&gt;
      expect(num2).to eq(6)&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    it &amp;quot;calculate reviewmapping from given review number per submission&amp;quot; do&lt;br /&gt;
      login_as(&amp;quot;instructor6&amp;quot;)&lt;br /&gt;
      visit '/assignments/1/edit'&lt;br /&gt;
      find_link('ReviewStrategy').click&lt;br /&gt;
      select &amp;quot;Instructor-Selected&amp;quot;, from: 'assignment_form_assignment_review_assignment_strategy'&lt;br /&gt;
      choose 'num_reviews_submission'&lt;br /&gt;
      fill_in 'num_reviews_per_submission', with: 7&lt;br /&gt;
      click_button 'second_submit_tag'&lt;br /&gt;
      #click_button 'Save'&lt;br /&gt;
      num = ReviewResponseMap.where(reviewer_id: @teamuser1.id, reviewed_object_id: @assignment.id).count&lt;br /&gt;
      expect(num).to eq(2)&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
=== Refactoring add_reviewer, add_metareviewer, delete_reviewer, delete_metareviewer, delete_outstanding_reviewers and delete_all_metareviewers&lt;br /&gt;
Since we merge methods have similar functions, we need to test their functionality. Here is a feature test work flow include those refactored functions.&lt;br /&gt;
    it &amp;quot;can add reviewer then delete it&amp;quot; do&lt;br /&gt;
 &lt;br /&gt;
       @student_reviewer = create :student,name:'student_reviewer'&lt;br /&gt;
       @participant_reviewer = create :participant, assignment: @assignment, user: @student_reviewer&lt;br /&gt;
       @student_reviewer2 = create :student,name:'student_reviewer2'&lt;br /&gt;
       @participant_reviewer2 = create :participant, assignment: @assignment, user: @student_reviewer2&lt;br /&gt;
       login_and_assign_reviewer(&amp;quot;instructor6&amp;quot;,@assignment.id,0,0)&lt;br /&gt;
 &lt;br /&gt;
       first(:link,'add reviewer').click&lt;br /&gt;
       add_reviewer(@student_reviewer.name)&lt;br /&gt;
       expect(page).to have_content @student_reviewer.name&lt;br /&gt;
       click_link('delete')&lt;br /&gt;
       expect(page).to have_content (&amp;quot;The review mapping for \&amp;quot;#{@team1.name}\&amp;quot; and \&amp;quot;#{@student_reviewer.name}\&amp;quot; has been deleted&amp;quot;)&lt;br /&gt;
 &lt;br /&gt;
       first(:link,'add reviewer').click&lt;br /&gt;
       add_reviewer(@student_reviewer.name)&lt;br /&gt;
       click_link('add metareviewer')&lt;br /&gt;
       add_matareviewer(@student_reviewer2.name)&lt;br /&gt;
       expect(page).to have_content @student_reviewer2.name&lt;br /&gt;
       find(:xpath, &amp;quot;//a[@href='/review_mapping/delete_metareviewer?id=3']&amp;quot;).click&lt;br /&gt;
       expect(page).to have_content (&amp;quot;The metareview mapping for #{@student_reviewer.name} and #{@student_reviewer2.name} has been deleted&amp;quot;)&lt;br /&gt;
 &lt;br /&gt;
       click_link('add metareviewer')&lt;br /&gt;
       add_matareviewer(@student_reviewer2.name)&lt;br /&gt;
       click_link('delete all metareviewers')&lt;br /&gt;
       expect(page).to have_content (&amp;quot;All metareview mappings for contributor \&amp;quot;#{@team1.name}\&amp;quot; and reviewer \&amp;quot;#{@student_reviewer.name}\&amp;quot; have been deleted&amp;quot;)&lt;br /&gt;
 &lt;br /&gt;
       first(:link,'delete outstanding reviewers').click&lt;br /&gt;
       expect(page).to have_content (&amp;quot;All review mappings for \&amp;quot;#{@team1.name}\&amp;quot; have been deleted&amp;quot;)&lt;br /&gt;
 &lt;br /&gt;
     end&lt;/div&gt;</summary>
		<author><name>Jdeng8</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2016/E1641._Refactor_review_mapping_controller.rb&amp;diff=104377</id>
		<title>CSC/ECE 517 Fall 2016/E1641. Refactor review mapping controller.rb</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2016/E1641._Refactor_review_mapping_controller.rb&amp;diff=104377"/>
		<updated>2016-11-04T18:19:04Z</updated>

		<summary type="html">&lt;p&gt;Jdeng8: /* Test */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=Background=&lt;br /&gt;
&lt;br /&gt;
This controller sets up mappings between reviewer and reviewee. It handles all different types of response maps (review response map, author feedback response map, teammate review response map, meta review response map and quiz response map). The class has functionality for five different kinds of Responses: reviews, metareviews, teammate reviews, author feedback (“rejoinders”), and quizzes. &lt;br /&gt;
&lt;br /&gt;
=Current Implementation and Problems=&lt;br /&gt;
The controller has many methods and involve with many other controllers and views, the code is long and complicated. Some of the methods in this controller have unreasonable name associated with their functions, some methods are too long, some methods haven't been used by any other methods or views. Our work is to refactor these problems and make the code more beautiful.&lt;br /&gt;
&lt;br /&gt;
The problems are:&lt;br /&gt;
&lt;br /&gt;
# Method ''response_report'' has some SQL - like code.  Rewrite with Active Record.&lt;br /&gt;
# Test whether method ''add_user_to_assignment'' is used. There is no way that this method should be in ReviewMappingController. Please remove this method and caller.&lt;br /&gt;
# There was a ''self-review'' feature, the method ''add_self_reviewer'', ''get_team_from_submission'' are related to this. Two views calls ''add_self_reviewer'' are &amp;quot;show_available_submissions_for_quizzes.html.erb&amp;quot; and &amp;quot;show_available_submissions.html.erb&amp;quot;. The names of views are not related to ''self_review'' feature. Plus those two views are not called anywhere. Please verify this and if so, you should delete those two views, two method and also related records (e.g. in routes.rb).&lt;br /&gt;
# Method ''delete_all_reviewers'' actually only deletes the outstanding review response maps (the ones which has been initiated, but there is no response yet). So it should better be named ''delete_outstanding_reviewers''. You can try to test this method by clicking “Assign reviewers” icon on an assignment.&lt;br /&gt;
# Method ''release_reservation'' should be renamed as'' release_mapping''. In addition, delete it if you find this method is not called anywhere.&lt;br /&gt;
# Method ''delete_mappings'' is problematic. It does not looks like a controller method. Please refactor it or delete it if you can validate that this method is not called anywhere.&lt;br /&gt;
# Method'' automatic_review_mapping_strategy'' is too long. Please refactor and test it.&lt;br /&gt;
&lt;br /&gt;
=Changes Implemented=&lt;br /&gt;
&lt;br /&gt;
# change the rails query from sql like code, like ReviewResponseMap.where(['reviewee_id = ? and reviewer_id = ? ', params[:contributor_id], reviewer.id]) to more rails quey like ReviewResponseMap.where(reviewee_id: params[:contributor_id],reviewer_id: reviewer.id)&lt;br /&gt;
# We search the function name(''add_user_to_assignment'') in the whole files, and find that this method is invoked in &amp;quot;participants_helper.rb&amp;quot;, and also being invoked in the function of ''add_reviewer'' and ''add_metareviewer'' in the controller of ''review_mapping_controller'' &lt;br /&gt;
# By searching the whole project and routes, we verify that methods ''add_self_reviewer'' and ''get_team_from_submission'' in this controller are not called by any other methods except for views &amp;quot;show_available_submissions_for_quizzes.html.erb&amp;quot; and &amp;quot;show_available_submissions.html.erb&amp;quot;. And those two views are not linked to any other views. So they are deleted from the project.&lt;br /&gt;
# We already renamed method ''delete_all_reviewers'' to ''delete_outstanding_reviewers'' and changed the corresponding button name at the corresponding view (_list_review_mappings.html.erb).&lt;br /&gt;
# By searching the whole project and routes, we verify that methods'' release_reservation'' in this controller are not used in anywhere.&lt;br /&gt;
# By searching the whole project and routes, we verify that methods ''delete_mappings'' in this controller are not used in anywhere.&lt;br /&gt;
# Method ''automatic_review_mapping_strategy'' have many long lines. We already shorten each long line to multiple lines. And also, we split this long function into three different functions.&lt;br /&gt;
&lt;br /&gt;
=Code=&lt;br /&gt;
&lt;br /&gt;
==Refactor SQL query code==&lt;br /&gt;
&lt;br /&gt;
The rails query we change in this controller:&lt;br /&gt;
&lt;br /&gt;
1. From &lt;br /&gt;
&lt;br /&gt;
  ReviewResponseMap.where(['reviewee_id = ? and reviewer_id = ? ', params[:contributor_id], reviewer.id]) &lt;br /&gt;
&lt;br /&gt;
To&lt;br /&gt;
&lt;br /&gt;
  ReviewResponseMap.where(reviewee_id: params[:contributor_id],reviewer_id: reviewer.id)&lt;br /&gt;
&lt;br /&gt;
2. From&lt;br /&gt;
&lt;br /&gt;
  MetareviewResponseMap.where(['reviewed_object_id = ? and reviewer_id = ?', mapping.map_id, reviewer.id])&lt;br /&gt;
&lt;br /&gt;
To&lt;br /&gt;
&lt;br /&gt;
  MetareviewResponseMap.where(reviewed_object_id: mapping.map_id, reviewer_id: reviewer.id)&lt;br /&gt;
&lt;br /&gt;
3. From&lt;br /&gt;
&lt;br /&gt;
                   @assignments = Assignment&lt;br /&gt;
                   .where([&amp;quot;instructor_id = ? and substring(name,1,1) = ?&amp;quot;, session[:user].id, letter])&lt;br /&gt;
                   .order('name')&lt;br /&gt;
                   .page(params[:page])&lt;br /&gt;
                   .per_page(10)&lt;br /&gt;
&lt;br /&gt;
To &lt;br /&gt;
&lt;br /&gt;
                   @assignments = Assignment&lt;br /&gt;
                   .where(instructor_id:session[:user].id)&lt;br /&gt;
                   .where(&amp;quot;substring(name,1,1) = :letter&amp;quot;,{letter:letter})&lt;br /&gt;
                   .order('name')&lt;br /&gt;
                   .page(params[:page])&lt;br /&gt;
                   .per_page(10)&lt;br /&gt;
&lt;br /&gt;
4.  From&lt;br /&gt;
&lt;br /&gt;
  ReviewResponseMap.where([&amp;quot;reviewed_object_id = ? and calibrate_to = ?&amp;quot;, assignment_id, 1])&lt;br /&gt;
&lt;br /&gt;
To &lt;br /&gt;
&lt;br /&gt;
  ReviewResponseMap.where(reviewed_object_id:assignment_id, calibrate_to: 1)&lt;br /&gt;
&lt;br /&gt;
5. From&lt;br /&gt;
&lt;br /&gt;
  ReviewResponseMap.where([&amp;quot;reviewed_object_id = ? and created_at &amp;gt; ? and calibrate_to = ?&amp;quot;, assignment_id, @@time_create_last_review_mapping_record, 0])&lt;br /&gt;
&lt;br /&gt;
To &lt;br /&gt;
&lt;br /&gt;
  ReviewResponseMap.where(reviewed_object_id:assignment_id,calibrate_to:0).where(&amp;quot;created_at &amp;gt; :time&amp;quot;,{time:@@time_create_last_review_mapping_record})&lt;br /&gt;
&lt;br /&gt;
6. From&lt;br /&gt;
&lt;br /&gt;
  AssignmentQuestionnaire.where([&amp;quot;assignment_id = ? and questionnaire_id IN (?)&amp;quot;, params[:id], @review_questionnaire_ids])&lt;br /&gt;
&lt;br /&gt;
To&lt;br /&gt;
 &lt;br /&gt;
  AssignmentQuestionnaire.where(assignment_id: params[:id],:questionnaire_id =&amp;gt; @review_questionnaire_ids)&lt;br /&gt;
&lt;br /&gt;
7. From&lt;br /&gt;
&lt;br /&gt;
  SelfReviewResponseMap.where(['reviewee_id = ? and reviewer_id = ?', team_id[0].t_id, params[:reviewer_id]])&lt;br /&gt;
&lt;br /&gt;
To &lt;br /&gt;
&lt;br /&gt;
  SelfReviewResponseMap.where(reviewee_id:team_id[0].t_id,reviewer_id:params[:reviewer_id])&lt;br /&gt;
&lt;br /&gt;
==Refactor long line method==&lt;br /&gt;
&lt;br /&gt;
  def automatic_review_mapping_strategy(assignment_id,&lt;br /&gt;
                                        participants, teams, student_review_num = 0,&lt;br /&gt;
                                        submission_review_num = 0)&lt;br /&gt;
    participants_hash = {}&lt;br /&gt;
    participants.each {|participant| participants_hash[participant.id] = 0 }&lt;br /&gt;
    # calculate reviewers for each team&lt;br /&gt;
    num_participants = participants.size&lt;br /&gt;
    if student_review_num != 0 and submission_review_num == 0&lt;br /&gt;
      num_reviews_per_team = (participants.size * student_review_num * 1.0 / teams.size).round&lt;br /&gt;
      student_review_num = student_review_num&lt;br /&gt;
      exact_num_of_review_needed = participants.size * student_review_num&lt;br /&gt;
    elsif student_review_num == 0 and submission_review_num != 0&lt;br /&gt;
      num_reviews_per_team = submission_review_num&lt;br /&gt;
      student_review_num = (teams.size * submission_review_num * 1.0 / participants.size).round&lt;br /&gt;
      exact_num_of_review_needed = teams.size * submission_review_num&lt;br /&gt;
    end&lt;br /&gt;
    execute_peer_review_strategy(assignment_id, teams, num_participants,&lt;br /&gt;
                                     student_review_num, num_reviews_per_team,&lt;br /&gt;
                                     participants, participants_hash)&lt;br /&gt;
    # after assigning peer reviews for each team,&lt;br /&gt;
    # if there are still some peer reviewers not obtain enough peer review,&lt;br /&gt;
    # just assign them to valid teams&lt;br /&gt;
    assign_reviewers_for_team(assignment_id,student_review_num,participants_hash,&lt;br /&gt;
                              exact_num_of_review_needed)&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  def assign_reviewers_for_team(assignment_id,student_review_num,participants_hash,&lt;br /&gt;
                                exact_num_of_review_needed)&lt;br /&gt;
     if ReviewResponseMap.where(reviewed_object_id:assignment_id,calibrate_to:0)&lt;br /&gt;
             .where(&amp;quot;created_at &amp;gt; :time&amp;quot;,&lt;br /&gt;
          {time:@@time_create_last_review_mapping_record}).size &amp;lt; exact_num_of_review_needed&lt;br /&gt;
      participants_with_insufficient_review_num = []&lt;br /&gt;
      participants_hash.each do |participant_id, review_num|&lt;br /&gt;
        participants_with_insufficient_review_num &amp;lt;&amp;lt; participant_id if review_num &amp;lt; student_review_num&lt;br /&gt;
      end&lt;br /&gt;
      unsorted_teams_hash = {}&lt;br /&gt;
     ReviewResponseMap.where(reviewed_object_id:assignment_id,&lt;br /&gt;
                  calibrate_to:0).each do |response_map|&lt;br /&gt;
        if unsorted_teams_hash.key? response_map.reviewee_id&lt;br /&gt;
          unsorted_teams_hash[response_map.reviewee_id] += 1&lt;br /&gt;
        else&lt;br /&gt;
          unsorted_teams_hash[response_map.reviewee_id] = 1&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
      teams_hash = unsorted_teams_hash.sort_by {|_, v| v }.to_h&lt;br /&gt;
      participants_with_insufficient_review_num.each do |participant_id|&lt;br /&gt;
        teams_hash.each do |team_id, _num_review_received|&lt;br /&gt;
          next if TeamsUser.exists?(team_id: team_id, &lt;br /&gt;
                                    user_id: Participant.find(participant_id).user_id)&lt;br /&gt;
          ReviewResponseMap.where(reviewee_id: team_id, reviewer_id: participant_id, &lt;br /&gt;
                                  reviewed_object_id: assignment_id).first_or_create&lt;br /&gt;
          teams_hash[team_id] += 1&lt;br /&gt;
          teams_hash = teams_hash.sort_by {|_, v| v }.to_h&lt;br /&gt;
          break&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
    @@time_create_last_review_mapping_record = ReviewResponseMap.&lt;br /&gt;
                                               where(reviewed_object_id: assignment_id).&lt;br /&gt;
                                               last.created_at&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def execute_peer_review_strategy(assignment_id, teams, num_participants, &lt;br /&gt;
                                   student_review_num, num_reviews_per_team, &lt;br /&gt;
                                   participants, participants_hash)&lt;br /&gt;
    # Exception detection: If instructor want to assign too many reviews done&lt;br /&gt;
    # by each student, there will be an error msg.&lt;br /&gt;
    if student_review_num &amp;gt;= teams.size&lt;br /&gt;
      flash[:error] = 'You cannot set the number of reviews done &lt;br /&gt;
      by each student to be greater than or equal to total number of teams &lt;br /&gt;
      [or &amp;quot;participants&amp;quot; if it is an individual assignment].'&lt;br /&gt;
    end&lt;br /&gt;
    peer_review_strategy(assignment_id, teams, num_participants, &lt;br /&gt;
                         student_review_num, num_reviews_per_team, &lt;br /&gt;
                         participants, participants_hash)&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
=Test=&lt;br /&gt;
# We test delete_outstanding_reviewers refactor from the UI. Here is a video for this test. https://youtu.be/MZxOaSsm58E&lt;br /&gt;
# We use some data to test the result of old query and new query in rails console&lt;br /&gt;
 &lt;br /&gt;
  ReviewResponseMap.where(['reviewee_id = ? and reviewer_id = ? ‘,6050, 9])&lt;br /&gt;
  ReviewResponseMap.where(reviewee_id: 6050,reviewer_id: 9)&lt;br /&gt;
&lt;br /&gt;
  Assignment.where([&amp;quot;instructor_id = ? and substring(name,1,1) = ?&amp;quot;, 2, ‘TestAssign2’]).order('name')&lt;br /&gt;
  Assignment .where(instructor_id:2).where(&amp;quot;substring(name,1,1) = :letter&amp;quot;,{letter:’TestAssign2’}).order('name')&lt;br /&gt;
&lt;br /&gt;
  ReviewResponseMap.where([&amp;quot;reviewed_object_id = ? and created_at &amp;gt; ? and calibrate_to = ?&amp;quot;, 13, nil, 0])&lt;br /&gt;
  ReviewResponseMap.where(reviewed_object_id:13,calibrate_to:0).where(&amp;quot;created_at &amp;gt; :time&amp;quot;,{time:nil})&lt;br /&gt;
&lt;br /&gt;
# We write RSpec feature tests to prove that all changes are correct and the project performs well as before. All tests have passed.&lt;br /&gt;
## Automatic_review_mapping method&lt;br /&gt;
&lt;br /&gt;
The function of  method automatic_review_mapping is to automatically assign reviews on students in teams when instructor set either student review number or submissions review number. There is constraint that only one of the two numbers must be set value other than 0 (that is, one is 0 and other is not 0). To test the correctness  of our refactoring, we design a scenario and 4 cases of assigning reviews to students:&lt;br /&gt;
&lt;br /&gt;
Case 1. Instructor has not set both students review number and submissions review number (They are both 0). The page will show a notice.&lt;br /&gt;
&lt;br /&gt;
Case 2. Instructor set both numbers (They are both not 0). The page will show a notice.&lt;br /&gt;
&lt;br /&gt;
Case 3. Instructors set students review number. The controller will change database: create new relationship in ReviewResponseMap. For example, if assign student review number to 2, and there will be 20 peer reviews in total and need to allocate to 3 teams. So each team get 7 reviews on average and 1 team’s artifact will be reviewed 6 times.&lt;br /&gt;
&lt;br /&gt;
Case 4. Instructors set submissions review number. The controller will change database: create new relationship in ReviewResponseMap. For example, if assign submission review number to 3, and there will be 21 peer reviews in total to allocate to 10 participants. So every participants get 2 reviews. 9 among 10 participants will review 2 teams’ artifacts and 1 participant will review 3 teams’ artifacts.&lt;br /&gt;
&lt;br /&gt;
require 'rails_helper'&lt;br /&gt;
  describe &amp;quot;review mapping&amp;quot;, js: true do&lt;br /&gt;
    before(:each) do&lt;br /&gt;
      #create test data&lt;br /&gt;
    end&lt;br /&gt;
 &lt;br /&gt;
    it &amp;quot;show error when assign both 0&amp;quot; do&lt;br /&gt;
      login_as(&amp;quot;instructor6&amp;quot;)&lt;br /&gt;
      visit '/assignments/1/edit'&lt;br /&gt;
      find_link('ReviewStrategy').click&lt;br /&gt;
      select &amp;quot;Instructor-Selected&amp;quot;, from: 'assignment_form_assignment_review_assignment_strategy'&lt;br /&gt;
      fill_in 'num_reviews_per_student', with: 0&lt;br /&gt;
      choose 'num_reviews_submission'&lt;br /&gt;
      fill_in 'num_reviews_per_submission', with: 0&lt;br /&gt;
      click_button 'second_submit_tag'&lt;br /&gt;
      #click_button 'Save'&lt;br /&gt;
      expect(page).to have_content('Please choose either the number of reviews per student or the number of reviewers per team (student)')&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    it &amp;quot;show error when assign both numbers&amp;quot; do&lt;br /&gt;
      login_as(&amp;quot;instructor6&amp;quot;)&lt;br /&gt;
      visit '/assignments/1/edit'&lt;br /&gt;
      find_link('ReviewStrategy').click&lt;br /&gt;
      select &amp;quot;Instructor-Selected&amp;quot;, from: 'assignment_form_assignment_review_assignment_strategy'&lt;br /&gt;
      fill_in 'num_reviews_per_student', with: 1&lt;br /&gt;
      choose 'num_reviews_submission'&lt;br /&gt;
      fill_in 'num_reviews_per_submission', with: 1&lt;br /&gt;
      click_button 'second_submit_tag'&lt;br /&gt;
      #click_button 'Save'&lt;br /&gt;
      expect(page).to have_content('Please choose either the number of reviews per student or the number of reviewers per team (student), not both')&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    it &amp;quot;calculate reviewmapping from given review number per student&amp;quot; do&lt;br /&gt;
      login_as(&amp;quot;instructor6&amp;quot;)&lt;br /&gt;
      visit '/assignments/1/edit'&lt;br /&gt;
      find_link('ReviewStrategy').click&lt;br /&gt;
      select &amp;quot;Instructor-Selected&amp;quot;, from: 'assignment_form_assignment_review_assignment_strategy'&lt;br /&gt;
      fill_in 'num_reviews_per_student', with: 2&lt;br /&gt;
      click_button 'first_submit_tag'&lt;br /&gt;
      num = ReviewResponseMap.where(reviewee_id: @team1.id, reviewed_object_id: @assignment.id).count&lt;br /&gt;
      expect(num).to eq(7)&lt;br /&gt;
      num2 = ReviewResponseMap.where(reviewee_id: @team3.id, reviewed_object_id: @assignment.id).count&lt;br /&gt;
      expect(num2).to eq(6)&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    it &amp;quot;calculate reviewmapping from given review number per submission&amp;quot; do&lt;br /&gt;
      login_as(&amp;quot;instructor6&amp;quot;)&lt;br /&gt;
      visit '/assignments/1/edit'&lt;br /&gt;
      find_link('ReviewStrategy').click&lt;br /&gt;
      select &amp;quot;Instructor-Selected&amp;quot;, from: 'assignment_form_assignment_review_assignment_strategy'&lt;br /&gt;
      choose 'num_reviews_submission'&lt;br /&gt;
      fill_in 'num_reviews_per_submission', with: 7&lt;br /&gt;
      click_button 'second_submit_tag'&lt;br /&gt;
      #click_button 'Save'&lt;br /&gt;
      num = ReviewResponseMap.where(reviewer_id: @teamuser1.id, reviewed_object_id: @assignment.id).count&lt;br /&gt;
      expect(num).to eq(2)&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
## Refactoring add_reviewer, add_metareviewer, delete_reviewer, delete_metareviewer, delete_outstanding_reviewers and delete_all_metareviewers&lt;br /&gt;
Since we merge methods have similar functions, we need to test their functionality. Here is a feature test work flow include those refactored functions.&lt;br /&gt;
    it &amp;quot;can add reviewer then delete it&amp;quot; do&lt;br /&gt;
 &lt;br /&gt;
       @student_reviewer = create :student,name:'student_reviewer'&lt;br /&gt;
       @participant_reviewer = create :participant, assignment: @assignment, user: @student_reviewer&lt;br /&gt;
       @student_reviewer2 = create :student,name:'student_reviewer2'&lt;br /&gt;
       @participant_reviewer2 = create :participant, assignment: @assignment, user: @student_reviewer2&lt;br /&gt;
       login_and_assign_reviewer(&amp;quot;instructor6&amp;quot;,@assignment.id,0,0)&lt;br /&gt;
 &lt;br /&gt;
       first(:link,'add reviewer').click&lt;br /&gt;
       add_reviewer(@student_reviewer.name)&lt;br /&gt;
       expect(page).to have_content @student_reviewer.name&lt;br /&gt;
       click_link('delete')&lt;br /&gt;
       expect(page).to have_content (&amp;quot;The review mapping for \&amp;quot;#{@team1.name}\&amp;quot; and \&amp;quot;#{@student_reviewer.name}\&amp;quot; has been deleted&amp;quot;)&lt;br /&gt;
 &lt;br /&gt;
       first(:link,'add reviewer').click&lt;br /&gt;
       add_reviewer(@student_reviewer.name)&lt;br /&gt;
       click_link('add metareviewer')&lt;br /&gt;
       add_matareviewer(@student_reviewer2.name)&lt;br /&gt;
       expect(page).to have_content @student_reviewer2.name&lt;br /&gt;
       find(:xpath, &amp;quot;//a[@href='/review_mapping/delete_metareviewer?id=3']&amp;quot;).click&lt;br /&gt;
       expect(page).to have_content (&amp;quot;The metareview mapping for #{@student_reviewer.name} and #{@student_reviewer2.name} has been deleted&amp;quot;)&lt;br /&gt;
 &lt;br /&gt;
       click_link('add metareviewer')&lt;br /&gt;
       add_matareviewer(@student_reviewer2.name)&lt;br /&gt;
       click_link('delete all metareviewers')&lt;br /&gt;
       expect(page).to have_content (&amp;quot;All metareview mappings for contributor \&amp;quot;#{@team1.name}\&amp;quot; and reviewer \&amp;quot;#{@student_reviewer.name}\&amp;quot; have been deleted&amp;quot;)&lt;br /&gt;
 &lt;br /&gt;
       first(:link,'delete outstanding reviewers').click&lt;br /&gt;
       expect(page).to have_content (&amp;quot;All review mappings for \&amp;quot;#{@team1.name}\&amp;quot; have been deleted&amp;quot;)&lt;br /&gt;
 &lt;br /&gt;
     end&lt;/div&gt;</summary>
		<author><name>Jdeng8</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2016/E1641._Refactor_review_mapping_controller.rb&amp;diff=104376</id>
		<title>CSC/ECE 517 Fall 2016/E1641. Refactor review mapping controller.rb</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2016/E1641._Refactor_review_mapping_controller.rb&amp;diff=104376"/>
		<updated>2016-11-04T18:17:58Z</updated>

		<summary type="html">&lt;p&gt;Jdeng8: /* Test */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=Background=&lt;br /&gt;
&lt;br /&gt;
This controller sets up mappings between reviewer and reviewee. It handles all different types of response maps (review response map, author feedback response map, teammate review response map, meta review response map and quiz response map). The class has functionality for five different kinds of Responses: reviews, metareviews, teammate reviews, author feedback (“rejoinders”), and quizzes. &lt;br /&gt;
&lt;br /&gt;
=Current Implementation and Problems=&lt;br /&gt;
The controller has many methods and involve with many other controllers and views, the code is long and complicated. Some of the methods in this controller have unreasonable name associated with their functions, some methods are too long, some methods haven't been used by any other methods or views. Our work is to refactor these problems and make the code more beautiful.&lt;br /&gt;
&lt;br /&gt;
The problems are:&lt;br /&gt;
&lt;br /&gt;
# Method ''response_report'' has some SQL - like code.  Rewrite with Active Record.&lt;br /&gt;
# Test whether method ''add_user_to_assignment'' is used. There is no way that this method should be in ReviewMappingController. Please remove this method and caller.&lt;br /&gt;
# There was a ''self-review'' feature, the method ''add_self_reviewer'', ''get_team_from_submission'' are related to this. Two views calls ''add_self_reviewer'' are &amp;quot;show_available_submissions_for_quizzes.html.erb&amp;quot; and &amp;quot;show_available_submissions.html.erb&amp;quot;. The names of views are not related to ''self_review'' feature. Plus those two views are not called anywhere. Please verify this and if so, you should delete those two views, two method and also related records (e.g. in routes.rb).&lt;br /&gt;
# Method ''delete_all_reviewers'' actually only deletes the outstanding review response maps (the ones which has been initiated, but there is no response yet). So it should better be named ''delete_outstanding_reviewers''. You can try to test this method by clicking “Assign reviewers” icon on an assignment.&lt;br /&gt;
# Method ''release_reservation'' should be renamed as'' release_mapping''. In addition, delete it if you find this method is not called anywhere.&lt;br /&gt;
# Method ''delete_mappings'' is problematic. It does not looks like a controller method. Please refactor it or delete it if you can validate that this method is not called anywhere.&lt;br /&gt;
# Method'' automatic_review_mapping_strategy'' is too long. Please refactor and test it.&lt;br /&gt;
&lt;br /&gt;
=Changes Implemented=&lt;br /&gt;
&lt;br /&gt;
# change the rails query from sql like code, like ReviewResponseMap.where(['reviewee_id = ? and reviewer_id = ? ', params[:contributor_id], reviewer.id]) to more rails quey like ReviewResponseMap.where(reviewee_id: params[:contributor_id],reviewer_id: reviewer.id)&lt;br /&gt;
# We search the function name(''add_user_to_assignment'') in the whole files, and find that this method is invoked in &amp;quot;participants_helper.rb&amp;quot;, and also being invoked in the function of ''add_reviewer'' and ''add_metareviewer'' in the controller of ''review_mapping_controller'' &lt;br /&gt;
# By searching the whole project and routes, we verify that methods ''add_self_reviewer'' and ''get_team_from_submission'' in this controller are not called by any other methods except for views &amp;quot;show_available_submissions_for_quizzes.html.erb&amp;quot; and &amp;quot;show_available_submissions.html.erb&amp;quot;. And those two views are not linked to any other views. So they are deleted from the project.&lt;br /&gt;
# We already renamed method ''delete_all_reviewers'' to ''delete_outstanding_reviewers'' and changed the corresponding button name at the corresponding view (_list_review_mappings.html.erb).&lt;br /&gt;
# By searching the whole project and routes, we verify that methods'' release_reservation'' in this controller are not used in anywhere.&lt;br /&gt;
# By searching the whole project and routes, we verify that methods ''delete_mappings'' in this controller are not used in anywhere.&lt;br /&gt;
# Method ''automatic_review_mapping_strategy'' have many long lines. We already shorten each long line to multiple lines. And also, we split this long function into three different functions.&lt;br /&gt;
&lt;br /&gt;
=Code=&lt;br /&gt;
&lt;br /&gt;
==Refactor SQL query code==&lt;br /&gt;
&lt;br /&gt;
The rails query we change in this controller:&lt;br /&gt;
&lt;br /&gt;
1. From &lt;br /&gt;
&lt;br /&gt;
  ReviewResponseMap.where(['reviewee_id = ? and reviewer_id = ? ', params[:contributor_id], reviewer.id]) &lt;br /&gt;
&lt;br /&gt;
To&lt;br /&gt;
&lt;br /&gt;
  ReviewResponseMap.where(reviewee_id: params[:contributor_id],reviewer_id: reviewer.id)&lt;br /&gt;
&lt;br /&gt;
2. From&lt;br /&gt;
&lt;br /&gt;
  MetareviewResponseMap.where(['reviewed_object_id = ? and reviewer_id = ?', mapping.map_id, reviewer.id])&lt;br /&gt;
&lt;br /&gt;
To&lt;br /&gt;
&lt;br /&gt;
  MetareviewResponseMap.where(reviewed_object_id: mapping.map_id, reviewer_id: reviewer.id)&lt;br /&gt;
&lt;br /&gt;
3. From&lt;br /&gt;
&lt;br /&gt;
                   @assignments = Assignment&lt;br /&gt;
                   .where([&amp;quot;instructor_id = ? and substring(name,1,1) = ?&amp;quot;, session[:user].id, letter])&lt;br /&gt;
                   .order('name')&lt;br /&gt;
                   .page(params[:page])&lt;br /&gt;
                   .per_page(10)&lt;br /&gt;
&lt;br /&gt;
To &lt;br /&gt;
&lt;br /&gt;
                   @assignments = Assignment&lt;br /&gt;
                   .where(instructor_id:session[:user].id)&lt;br /&gt;
                   .where(&amp;quot;substring(name,1,1) = :letter&amp;quot;,{letter:letter})&lt;br /&gt;
                   .order('name')&lt;br /&gt;
                   .page(params[:page])&lt;br /&gt;
                   .per_page(10)&lt;br /&gt;
&lt;br /&gt;
4.  From&lt;br /&gt;
&lt;br /&gt;
  ReviewResponseMap.where([&amp;quot;reviewed_object_id = ? and calibrate_to = ?&amp;quot;, assignment_id, 1])&lt;br /&gt;
&lt;br /&gt;
To &lt;br /&gt;
&lt;br /&gt;
  ReviewResponseMap.where(reviewed_object_id:assignment_id, calibrate_to: 1)&lt;br /&gt;
&lt;br /&gt;
5. From&lt;br /&gt;
&lt;br /&gt;
  ReviewResponseMap.where([&amp;quot;reviewed_object_id = ? and created_at &amp;gt; ? and calibrate_to = ?&amp;quot;, assignment_id, @@time_create_last_review_mapping_record, 0])&lt;br /&gt;
&lt;br /&gt;
To &lt;br /&gt;
&lt;br /&gt;
  ReviewResponseMap.where(reviewed_object_id:assignment_id,calibrate_to:0).where(&amp;quot;created_at &amp;gt; :time&amp;quot;,{time:@@time_create_last_review_mapping_record})&lt;br /&gt;
&lt;br /&gt;
6. From&lt;br /&gt;
&lt;br /&gt;
  AssignmentQuestionnaire.where([&amp;quot;assignment_id = ? and questionnaire_id IN (?)&amp;quot;, params[:id], @review_questionnaire_ids])&lt;br /&gt;
&lt;br /&gt;
To&lt;br /&gt;
 &lt;br /&gt;
  AssignmentQuestionnaire.where(assignment_id: params[:id],:questionnaire_id =&amp;gt; @review_questionnaire_ids)&lt;br /&gt;
&lt;br /&gt;
7. From&lt;br /&gt;
&lt;br /&gt;
  SelfReviewResponseMap.where(['reviewee_id = ? and reviewer_id = ?', team_id[0].t_id, params[:reviewer_id]])&lt;br /&gt;
&lt;br /&gt;
To &lt;br /&gt;
&lt;br /&gt;
  SelfReviewResponseMap.where(reviewee_id:team_id[0].t_id,reviewer_id:params[:reviewer_id])&lt;br /&gt;
&lt;br /&gt;
==Refactor long line method==&lt;br /&gt;
&lt;br /&gt;
  def automatic_review_mapping_strategy(assignment_id,&lt;br /&gt;
                                        participants, teams, student_review_num = 0,&lt;br /&gt;
                                        submission_review_num = 0)&lt;br /&gt;
    participants_hash = {}&lt;br /&gt;
    participants.each {|participant| participants_hash[participant.id] = 0 }&lt;br /&gt;
    # calculate reviewers for each team&lt;br /&gt;
    num_participants = participants.size&lt;br /&gt;
    if student_review_num != 0 and submission_review_num == 0&lt;br /&gt;
      num_reviews_per_team = (participants.size * student_review_num * 1.0 / teams.size).round&lt;br /&gt;
      student_review_num = student_review_num&lt;br /&gt;
      exact_num_of_review_needed = participants.size * student_review_num&lt;br /&gt;
    elsif student_review_num == 0 and submission_review_num != 0&lt;br /&gt;
      num_reviews_per_team = submission_review_num&lt;br /&gt;
      student_review_num = (teams.size * submission_review_num * 1.0 / participants.size).round&lt;br /&gt;
      exact_num_of_review_needed = teams.size * submission_review_num&lt;br /&gt;
    end&lt;br /&gt;
    execute_peer_review_strategy(assignment_id, teams, num_participants,&lt;br /&gt;
                                     student_review_num, num_reviews_per_team,&lt;br /&gt;
                                     participants, participants_hash)&lt;br /&gt;
    # after assigning peer reviews for each team,&lt;br /&gt;
    # if there are still some peer reviewers not obtain enough peer review,&lt;br /&gt;
    # just assign them to valid teams&lt;br /&gt;
    assign_reviewers_for_team(assignment_id,student_review_num,participants_hash,&lt;br /&gt;
                              exact_num_of_review_needed)&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  def assign_reviewers_for_team(assignment_id,student_review_num,participants_hash,&lt;br /&gt;
                                exact_num_of_review_needed)&lt;br /&gt;
     if ReviewResponseMap.where(reviewed_object_id:assignment_id,calibrate_to:0)&lt;br /&gt;
             .where(&amp;quot;created_at &amp;gt; :time&amp;quot;,&lt;br /&gt;
          {time:@@time_create_last_review_mapping_record}).size &amp;lt; exact_num_of_review_needed&lt;br /&gt;
      participants_with_insufficient_review_num = []&lt;br /&gt;
      participants_hash.each do |participant_id, review_num|&lt;br /&gt;
        participants_with_insufficient_review_num &amp;lt;&amp;lt; participant_id if review_num &amp;lt; student_review_num&lt;br /&gt;
      end&lt;br /&gt;
      unsorted_teams_hash = {}&lt;br /&gt;
     ReviewResponseMap.where(reviewed_object_id:assignment_id,&lt;br /&gt;
                  calibrate_to:0).each do |response_map|&lt;br /&gt;
        if unsorted_teams_hash.key? response_map.reviewee_id&lt;br /&gt;
          unsorted_teams_hash[response_map.reviewee_id] += 1&lt;br /&gt;
        else&lt;br /&gt;
          unsorted_teams_hash[response_map.reviewee_id] = 1&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
      teams_hash = unsorted_teams_hash.sort_by {|_, v| v }.to_h&lt;br /&gt;
      participants_with_insufficient_review_num.each do |participant_id|&lt;br /&gt;
        teams_hash.each do |team_id, _num_review_received|&lt;br /&gt;
          next if TeamsUser.exists?(team_id: team_id, &lt;br /&gt;
                                    user_id: Participant.find(participant_id).user_id)&lt;br /&gt;
          ReviewResponseMap.where(reviewee_id: team_id, reviewer_id: participant_id, &lt;br /&gt;
                                  reviewed_object_id: assignment_id).first_or_create&lt;br /&gt;
          teams_hash[team_id] += 1&lt;br /&gt;
          teams_hash = teams_hash.sort_by {|_, v| v }.to_h&lt;br /&gt;
          break&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
    @@time_create_last_review_mapping_record = ReviewResponseMap.&lt;br /&gt;
                                               where(reviewed_object_id: assignment_id).&lt;br /&gt;
                                               last.created_at&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def execute_peer_review_strategy(assignment_id, teams, num_participants, &lt;br /&gt;
                                   student_review_num, num_reviews_per_team, &lt;br /&gt;
                                   participants, participants_hash)&lt;br /&gt;
    # Exception detection: If instructor want to assign too many reviews done&lt;br /&gt;
    # by each student, there will be an error msg.&lt;br /&gt;
    if student_review_num &amp;gt;= teams.size&lt;br /&gt;
      flash[:error] = 'You cannot set the number of reviews done &lt;br /&gt;
      by each student to be greater than or equal to total number of teams &lt;br /&gt;
      [or &amp;quot;participants&amp;quot; if it is an individual assignment].'&lt;br /&gt;
    end&lt;br /&gt;
    peer_review_strategy(assignment_id, teams, num_participants, &lt;br /&gt;
                         student_review_num, num_reviews_per_team, &lt;br /&gt;
                         participants, participants_hash)&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
=Test=&lt;br /&gt;
# We test delete_outstanding_reviewers refactor from the UI. Here is a video for this test. https://youtu.be/MZxOaSsm58E&lt;br /&gt;
# We use some data to test the result of old query and new query in rails console&lt;br /&gt;
 &lt;br /&gt;
  ReviewResponseMap.where(['reviewee_id = ? and reviewer_id = ? ‘,6050, 9])&lt;br /&gt;
  ReviewResponseMap.where(reviewee_id: 6050,reviewer_id: 9)&lt;br /&gt;
&lt;br /&gt;
  Assignment.where([&amp;quot;instructor_id = ? and substring(name,1,1) = ?&amp;quot;, 2, ‘TestAssign2’]).order('name')&lt;br /&gt;
  Assignment .where(instructor_id:2).where(&amp;quot;substring(name,1,1) = :letter&amp;quot;,{letter:’TestAssign2’}).order('name')&lt;br /&gt;
&lt;br /&gt;
  ReviewResponseMap.where([&amp;quot;reviewed_object_id = ? and created_at &amp;gt; ? and calibrate_to = ?&amp;quot;, 13, nil, 0])&lt;br /&gt;
  ReviewResponseMap.where(reviewed_object_id:13,calibrate_to:0).where(&amp;quot;created_at &amp;gt; :time&amp;quot;,{time:nil})&lt;br /&gt;
&lt;br /&gt;
# We write RSpec feature tests to prove that all changes are correct and the project performs well as before. All tests have passed.&lt;br /&gt;
## Automatic_review_mapping method&lt;br /&gt;
The function of  method automatic_review_mapping is to automatically assign reviews on students in teams when instructor set either student review number or submissions review number. There is constraint that only one of the two numbers must be set value other than 0 (that is, one is 0 and other is not 0). To test the correctness  of our refactoring, we design a scenario and 4 cases of assigning reviews to students:&lt;br /&gt;
&lt;br /&gt;
Case 1. Instructor has not set both students review number and submissions review number (They are both 0). The page will show a notice.&lt;br /&gt;
&lt;br /&gt;
Case 2. Instructor set both numbers (They are both not 0). The page will show a notice.&lt;br /&gt;
&lt;br /&gt;
Case 3. Instructors set students review number. The controller will change database: create new relationship in ReviewResponseMap. For example, if assign student review number to 2, and there will be 20 peer reviews in total and need to allocate to 3 teams. So each team get 7 reviews on average and 1 team’s artifact will be reviewed 6 times.&lt;br /&gt;
&lt;br /&gt;
Case 4. Instructors set submissions review number. The controller will change database: create new relationship in ReviewResponseMap. For example, if assign submission review number to 3, and there will be 21 peer reviews in total to allocate to 10 participants. So every participants get 2 reviews. 9 among 10 participants will review 2 teams’ artifacts and 1 participant will review 3 teams’ artifacts.&lt;br /&gt;
&lt;br /&gt;
require 'rails_helper'&lt;br /&gt;
  describe &amp;quot;review mapping&amp;quot;, js: true do&lt;br /&gt;
    before(:each) do&lt;br /&gt;
      #create test data&lt;br /&gt;
    end&lt;br /&gt;
 &lt;br /&gt;
    it &amp;quot;show error when assign both 0&amp;quot; do&lt;br /&gt;
      login_as(&amp;quot;instructor6&amp;quot;)&lt;br /&gt;
      visit '/assignments/1/edit'&lt;br /&gt;
      find_link('ReviewStrategy').click&lt;br /&gt;
      select &amp;quot;Instructor-Selected&amp;quot;, from: 'assignment_form_assignment_review_assignment_strategy'&lt;br /&gt;
      fill_in 'num_reviews_per_student', with: 0&lt;br /&gt;
      choose 'num_reviews_submission'&lt;br /&gt;
      fill_in 'num_reviews_per_submission', with: 0&lt;br /&gt;
      click_button 'second_submit_tag'&lt;br /&gt;
      #click_button 'Save'&lt;br /&gt;
      expect(page).to have_content('Please choose either the number of reviews per student or the number of reviewers per team (student)')&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    it &amp;quot;show error when assign both numbers&amp;quot; do&lt;br /&gt;
      login_as(&amp;quot;instructor6&amp;quot;)&lt;br /&gt;
      visit '/assignments/1/edit'&lt;br /&gt;
      find_link('ReviewStrategy').click&lt;br /&gt;
      select &amp;quot;Instructor-Selected&amp;quot;, from: 'assignment_form_assignment_review_assignment_strategy'&lt;br /&gt;
      fill_in 'num_reviews_per_student', with: 1&lt;br /&gt;
      choose 'num_reviews_submission'&lt;br /&gt;
      fill_in 'num_reviews_per_submission', with: 1&lt;br /&gt;
      click_button 'second_submit_tag'&lt;br /&gt;
      #click_button 'Save'&lt;br /&gt;
      expect(page).to have_content('Please choose either the number of reviews per student or the number of reviewers per team (student), not both')&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    it &amp;quot;calculate reviewmapping from given review number per student&amp;quot; do&lt;br /&gt;
      login_as(&amp;quot;instructor6&amp;quot;)&lt;br /&gt;
      visit '/assignments/1/edit'&lt;br /&gt;
      find_link('ReviewStrategy').click&lt;br /&gt;
      select &amp;quot;Instructor-Selected&amp;quot;, from: 'assignment_form_assignment_review_assignment_strategy'&lt;br /&gt;
      fill_in 'num_reviews_per_student', with: 2&lt;br /&gt;
      click_button 'first_submit_tag'&lt;br /&gt;
      num = ReviewResponseMap.where(reviewee_id: @team1.id, reviewed_object_id: @assignment.id).count&lt;br /&gt;
      expect(num).to eq(7)&lt;br /&gt;
      num2 = ReviewResponseMap.where(reviewee_id: @team3.id, reviewed_object_id: @assignment.id).count&lt;br /&gt;
      expect(num2).to eq(6)&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    it &amp;quot;calculate reviewmapping from given review number per submission&amp;quot; do&lt;br /&gt;
      login_as(&amp;quot;instructor6&amp;quot;)&lt;br /&gt;
      visit '/assignments/1/edit'&lt;br /&gt;
      find_link('ReviewStrategy').click&lt;br /&gt;
      select &amp;quot;Instructor-Selected&amp;quot;, from: 'assignment_form_assignment_review_assignment_strategy'&lt;br /&gt;
      choose 'num_reviews_submission'&lt;br /&gt;
      fill_in 'num_reviews_per_submission', with: 7&lt;br /&gt;
      click_button 'second_submit_tag'&lt;br /&gt;
      #click_button 'Save'&lt;br /&gt;
      num = ReviewResponseMap.where(reviewer_id: @teamuser1.id, reviewed_object_id: @assignment.id).count&lt;br /&gt;
      expect(num).to eq(2)&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
## Refactoring add_reviewer, add_metareviewer, delete_reviewer, delete_metareviewer, delete_outstanding_reviewers and delete_all_metareviewers&lt;br /&gt;
Since we merge methods have similar functions, we need to test their functionality. Here is a feature test work flow include those refactored functions.&lt;br /&gt;
    it &amp;quot;can add reviewer then delete it&amp;quot; do&lt;br /&gt;
 &lt;br /&gt;
       @student_reviewer = create :student,name:'student_reviewer'&lt;br /&gt;
       @participant_reviewer = create :participant, assignment: @assignment, user: @student_reviewer&lt;br /&gt;
       @student_reviewer2 = create :student,name:'student_reviewer2'&lt;br /&gt;
       @participant_reviewer2 = create :participant, assignment: @assignment, user: @student_reviewer2&lt;br /&gt;
       login_and_assign_reviewer(&amp;quot;instructor6&amp;quot;,@assignment.id,0,0)&lt;br /&gt;
 &lt;br /&gt;
       #add_reviewer&lt;br /&gt;
       first(:link,'add reviewer').click&lt;br /&gt;
       add_reviewer(@student_reviewer.name)&lt;br /&gt;
       expect(page).to have_content @student_reviewer.name&lt;br /&gt;
       #delete_reviewer&lt;br /&gt;
       click_link('delete')&lt;br /&gt;
       expect(page).to have_content (&amp;quot;The review mapping for \&amp;quot;#{@team1.name}\&amp;quot; and \&amp;quot;#{@student_reviewer.name}\&amp;quot; has been deleted&amp;quot;)&lt;br /&gt;
 &lt;br /&gt;
       #add_meta_reviewer&lt;br /&gt;
       first(:link,'add reviewer').click&lt;br /&gt;
       add_reviewer(@student_reviewer.name)&lt;br /&gt;
       click_link('add metareviewer')&lt;br /&gt;
       add_matareviewer(@student_reviewer2.name)&lt;br /&gt;
       expect(page).to have_content @student_reviewer2.name&lt;br /&gt;
       #delete_meta_reviewer&lt;br /&gt;
       find(:xpath, &amp;quot;//a[@href='/review_mapping/delete_metareviewer?id=3']&amp;quot;).click&lt;br /&gt;
       expect(page).to have_content (&amp;quot;The metareview mapping for #{@student_reviewer.name} and #{@student_reviewer2.name} has been deleted&amp;quot;)&lt;br /&gt;
 &lt;br /&gt;
       click_link('add metareviewer')&lt;br /&gt;
       add_matareviewer(@student_reviewer2.name)&lt;br /&gt;
       #delete_all_meta_reviewer&lt;br /&gt;
       click_link('delete all metareviewers')&lt;br /&gt;
       expect(page).to have_content (&amp;quot;All metareview mappings for contributor \&amp;quot;#{@team1.name}\&amp;quot; and reviewer \&amp;quot;#{@student_reviewer.name}\&amp;quot; have been deleted&amp;quot;)&lt;br /&gt;
 &lt;br /&gt;
       first(:link,'delete outstanding reviewers').click&lt;br /&gt;
       expect(page).to have_content (&amp;quot;All review mappings for \&amp;quot;#{@team1.name}\&amp;quot; have been deleted&amp;quot;)&lt;br /&gt;
 &lt;br /&gt;
     end&lt;/div&gt;</summary>
		<author><name>Jdeng8</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=File:WechatIMG57.jpeg&amp;diff=104113</id>
		<title>File:WechatIMG57.jpeg</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=File:WechatIMG57.jpeg&amp;diff=104113"/>
		<updated>2016-10-31T00:32:38Z</updated>

		<summary type="html">&lt;p&gt;Jdeng8: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Jdeng8</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=File:Testpass.png&amp;diff=104112</id>
		<title>File:Testpass.png</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=File:Testpass.png&amp;diff=104112"/>
		<updated>2016-10-31T00:26:40Z</updated>

		<summary type="html">&lt;p&gt;Jdeng8: uploaded a new version of &amp;amp;quot;File:Testpass.png&amp;amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Jdeng8</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=File:Testpass.png&amp;diff=104111</id>
		<title>File:Testpass.png</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=File:Testpass.png&amp;diff=104111"/>
		<updated>2016-10-31T00:25:59Z</updated>

		<summary type="html">&lt;p&gt;Jdeng8: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Jdeng8</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2016/E1641._Refactor_review_mapping_controller.rb&amp;diff=104110</id>
		<title>CSC/ECE 517 Fall 2016/E1641. Refactor review mapping controller.rb</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2016/E1641._Refactor_review_mapping_controller.rb&amp;diff=104110"/>
		<updated>2016-10-31T00:25:17Z</updated>

		<summary type="html">&lt;p&gt;Jdeng8: /* Test */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=Background=&lt;br /&gt;
&lt;br /&gt;
This controller sets up mappings between reviewer and reviewee. It handles all different types of response maps (review response map, author feedback response map, teammate review response map, meta review response map and quiz response map). The class has functionality for five different kinds of Responses: reviews, metareviews, teammate reviews, author feedback (“rejoinders”), and quizzes. &lt;br /&gt;
&lt;br /&gt;
=Current Implementation and Problems=&lt;br /&gt;
The controller has many methods and involve with many other controllers and views, the code is long and complicated. Some of the methods in this controller have unreasonable name associated with their functions, some methods are too long, some methods haven't been used by any other methods or views. Our work is to refactor these problems and make the code more beautiful.&lt;br /&gt;
&lt;br /&gt;
The problems are:&lt;br /&gt;
&lt;br /&gt;
# Method ''response_report'' has some SQL - like code.  Rewrite with Active Record.&lt;br /&gt;
# Test whether method ''add_user_to_assignment'' is used. There is no way that this method should be in ReviewMappingController. Please remove this method and caller.&lt;br /&gt;
# There was a ''self-review'' feature, the method ''add_self_reviewer'', ''get_team_from_submission'' are related to this. Two views calls ''add_self_reviewer'' are &amp;quot;show_available_submissions_for_quizzes.html.erb&amp;quot; and &amp;quot;show_available_submissions.html.erb&amp;quot;. The names of views are not related to ''self_review'' feature. Plus those two views are not called anywhere. Please verify this and if so, you should delete those two views, two method and also related records (e.g. in routes.rb).&lt;br /&gt;
# Method ''delete_all_reviewers'' actually only deletes the outstanding review response maps (the ones which has been initiated, but there is no response yet). So it should better be named ''delete_outstanding_reviewers''. You can try to test this method by clicking “Assign reviewers” icon on an assignment.&lt;br /&gt;
# Method ''release_reservation'' should be renamed as'' release_mapping''. In addition, delete it if you find this method is not called anywhere.&lt;br /&gt;
# Method ''delete_mappings'' is problematic. It does not looks like a controller method. Please refactor it or delete it if you can validate that this method is not called anywhere.&lt;br /&gt;
# Method'' automatic_review_mapping_strategy'' is too long. Please refactor and test it.&lt;br /&gt;
&lt;br /&gt;
=Changes Implemented=&lt;br /&gt;
&lt;br /&gt;
# change the rails query from sql like code, like ReviewResponseMap.where(['reviewee_id = ? and reviewer_id = ? ', params[:contributor_id], reviewer.id]) to more rails quey like ReviewResponseMap.where(reviewee_id: params[:contributor_id],reviewer_id: reviewer.id)&lt;br /&gt;
# We search the function name(''add_user_to_assignment'') in the whole files, and find that this method is invoked in &amp;quot;participants_helper.rb&amp;quot;, and also being invoked in the function of ''add_reviewer'' and ''add_metareviewer'' in the controller of ''review_mapping_controller'' &lt;br /&gt;
# By searching the whole project and routes, we verify that methods ''add_self_reviewer'' and ''get_team_from_submission'' in this controller are not called by any other methods except for views &amp;quot;show_available_submissions_for_quizzes.html.erb&amp;quot; and &amp;quot;show_available_submissions.html.erb&amp;quot;. And those two views are not linked to any other views. So they are deleted from the project.&lt;br /&gt;
# We already renamed method ''delete_all_reviewers'' to ''delete_outstanding_reviewers'' and changed the corresponding button name at the corresponding view (_list_review_mappings.html.erb).&lt;br /&gt;
# By searching the whole project and routes, we verify that methods'' release_reservation'' in this controller are not used in anywhere.&lt;br /&gt;
# By searching the whole project and routes, we verify that methods ''delete_mappings'' in this controller are not used in anywhere.&lt;br /&gt;
# Method ''automatic_review_mapping_strategy'' have many long lines. We already shorten each long line to multiple lines. And also, we split this long function into three different functions.&lt;br /&gt;
&lt;br /&gt;
=Code=&lt;br /&gt;
&lt;br /&gt;
==Refactor SQL query code==&lt;br /&gt;
&lt;br /&gt;
The rails query we change in this controller:&lt;br /&gt;
&lt;br /&gt;
1. From &lt;br /&gt;
&lt;br /&gt;
  ReviewResponseMap.where(['reviewee_id = ? and reviewer_id = ? ', params[:contributor_id], reviewer.id]) &lt;br /&gt;
&lt;br /&gt;
To&lt;br /&gt;
&lt;br /&gt;
  ReviewResponseMap.where(reviewee_id: params[:contributor_id],reviewer_id: reviewer.id)&lt;br /&gt;
&lt;br /&gt;
2. From&lt;br /&gt;
&lt;br /&gt;
  MetareviewResponseMap.where(['reviewed_object_id = ? and reviewer_id = ?', mapping.map_id, reviewer.id])&lt;br /&gt;
&lt;br /&gt;
To&lt;br /&gt;
&lt;br /&gt;
  MetareviewResponseMap.where(reviewed_object_id: mapping.map_id, reviewer_id: reviewer.id)&lt;br /&gt;
&lt;br /&gt;
3. From&lt;br /&gt;
&lt;br /&gt;
                   @assignments = Assignment&lt;br /&gt;
                   .where([&amp;quot;instructor_id = ? and substring(name,1,1) = ?&amp;quot;, session[:user].id, letter])&lt;br /&gt;
                   .order('name')&lt;br /&gt;
                   .page(params[:page])&lt;br /&gt;
                   .per_page(10)&lt;br /&gt;
&lt;br /&gt;
To &lt;br /&gt;
&lt;br /&gt;
                   @assignments = Assignment&lt;br /&gt;
                   .where(instructor_id:session[:user].id)&lt;br /&gt;
                   .where(&amp;quot;substring(name,1,1) = :letter&amp;quot;,{letter:letter})&lt;br /&gt;
                   .order('name')&lt;br /&gt;
                   .page(params[:page])&lt;br /&gt;
                   .per_page(10)&lt;br /&gt;
&lt;br /&gt;
4.  From&lt;br /&gt;
&lt;br /&gt;
  ReviewResponseMap.where([&amp;quot;reviewed_object_id = ? and calibrate_to = ?&amp;quot;, assignment_id, 1])&lt;br /&gt;
&lt;br /&gt;
To &lt;br /&gt;
&lt;br /&gt;
  ReviewResponseMap.where(reviewed_object_id:assignment_id, calibrate_to: 1)&lt;br /&gt;
&lt;br /&gt;
5. From&lt;br /&gt;
&lt;br /&gt;
  ReviewResponseMap.where([&amp;quot;reviewed_object_id = ? and created_at &amp;gt; ? and calibrate_to = ?&amp;quot;, assignment_id, @@time_create_last_review_mapping_record, 0])&lt;br /&gt;
&lt;br /&gt;
To &lt;br /&gt;
&lt;br /&gt;
  ReviewResponseMap.where(reviewed_object_id:assignment_id,calibrate_to:0).where(&amp;quot;created_at &amp;gt; :time&amp;quot;,{time:@@time_create_last_review_mapping_record})&lt;br /&gt;
&lt;br /&gt;
6. From&lt;br /&gt;
&lt;br /&gt;
  AssignmentQuestionnaire.where([&amp;quot;assignment_id = ? and questionnaire_id IN (?)&amp;quot;, params[:id], @review_questionnaire_ids])&lt;br /&gt;
&lt;br /&gt;
To&lt;br /&gt;
 &lt;br /&gt;
  AssignmentQuestionnaire.where(assignment_id: params[:id],:questionnaire_id =&amp;gt; @review_questionnaire_ids)&lt;br /&gt;
&lt;br /&gt;
7. From&lt;br /&gt;
&lt;br /&gt;
  SelfReviewResponseMap.where(['reviewee_id = ? and reviewer_id = ?', team_id[0].t_id, params[:reviewer_id]])&lt;br /&gt;
&lt;br /&gt;
To &lt;br /&gt;
&lt;br /&gt;
  SelfReviewResponseMap.where(reviewee_id:team_id[0].t_id,reviewer_id:params[:reviewer_id])&lt;br /&gt;
&lt;br /&gt;
==Refactor long line method==&lt;br /&gt;
&lt;br /&gt;
  def automatic_review_mapping_strategy(assignment_id,&lt;br /&gt;
                                        participants, teams, student_review_num = 0,&lt;br /&gt;
                                        submission_review_num = 0)&lt;br /&gt;
    participants_hash = {}&lt;br /&gt;
    participants.each {|participant| participants_hash[participant.id] = 0 }&lt;br /&gt;
    # calculate reviewers for each team&lt;br /&gt;
    num_participants = participants.size&lt;br /&gt;
    if student_review_num != 0 and submission_review_num == 0&lt;br /&gt;
      num_reviews_per_team = (participants.size * student_review_num * 1.0 / teams.size).round&lt;br /&gt;
      student_review_num = student_review_num&lt;br /&gt;
      exact_num_of_review_needed = participants.size * student_review_num&lt;br /&gt;
    elsif student_review_num == 0 and submission_review_num != 0&lt;br /&gt;
      num_reviews_per_team = submission_review_num&lt;br /&gt;
      student_review_num = (teams.size * submission_review_num * 1.0 / participants.size).round&lt;br /&gt;
      exact_num_of_review_needed = teams.size * submission_review_num&lt;br /&gt;
    end&lt;br /&gt;
    execute_peer_review_strategy(assignment_id, teams, num_participants,&lt;br /&gt;
                                     student_review_num, num_reviews_per_team,&lt;br /&gt;
                                     participants, participants_hash)&lt;br /&gt;
    # after assigning peer reviews for each team,&lt;br /&gt;
    # if there are still some peer reviewers not obtain enough peer review,&lt;br /&gt;
    # just assign them to valid teams&lt;br /&gt;
    assign_reviewers_for_team(assignment_id,student_review_num,participants_hash,&lt;br /&gt;
                              exact_num_of_review_needed)&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  def assign_reviewers_for_team(assignment_id,student_review_num,participants_hash,&lt;br /&gt;
                                exact_num_of_review_needed)&lt;br /&gt;
     if ReviewResponseMap.where(reviewed_object_id:assignment_id,calibrate_to:0)&lt;br /&gt;
             .where(&amp;quot;created_at &amp;gt; :time&amp;quot;,&lt;br /&gt;
          {time:@@time_create_last_review_mapping_record}).size &amp;lt; exact_num_of_review_needed&lt;br /&gt;
      participants_with_insufficient_review_num = []&lt;br /&gt;
      participants_hash.each do |participant_id, review_num|&lt;br /&gt;
        participants_with_insufficient_review_num &amp;lt;&amp;lt; participant_id if review_num &amp;lt; student_review_num&lt;br /&gt;
      end&lt;br /&gt;
      unsorted_teams_hash = {}&lt;br /&gt;
     ReviewResponseMap.where(reviewed_object_id:assignment_id,&lt;br /&gt;
                  calibrate_to:0).each do |response_map|&lt;br /&gt;
        if unsorted_teams_hash.key? response_map.reviewee_id&lt;br /&gt;
          unsorted_teams_hash[response_map.reviewee_id] += 1&lt;br /&gt;
        else&lt;br /&gt;
          unsorted_teams_hash[response_map.reviewee_id] = 1&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
      teams_hash = unsorted_teams_hash.sort_by {|_, v| v }.to_h&lt;br /&gt;
      participants_with_insufficient_review_num.each do |participant_id|&lt;br /&gt;
        teams_hash.each do |team_id, _num_review_received|&lt;br /&gt;
          next if TeamsUser.exists?(team_id: team_id, &lt;br /&gt;
                                    user_id: Participant.find(participant_id).user_id)&lt;br /&gt;
          ReviewResponseMap.where(reviewee_id: team_id, reviewer_id: participant_id, &lt;br /&gt;
                                  reviewed_object_id: assignment_id).first_or_create&lt;br /&gt;
          teams_hash[team_id] += 1&lt;br /&gt;
          teams_hash = teams_hash.sort_by {|_, v| v }.to_h&lt;br /&gt;
          break&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
    @@time_create_last_review_mapping_record = ReviewResponseMap.&lt;br /&gt;
                                               where(reviewed_object_id: assignment_id).&lt;br /&gt;
                                               last.created_at&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def execute_peer_review_strategy(assignment_id, teams, num_participants, &lt;br /&gt;
                                   student_review_num, num_reviews_per_team, &lt;br /&gt;
                                   participants, participants_hash)&lt;br /&gt;
    # Exception detection: If instructor want to assign too many reviews done&lt;br /&gt;
    # by each student, there will be an error msg.&lt;br /&gt;
    if student_review_num &amp;gt;= teams.size&lt;br /&gt;
      flash[:error] = 'You cannot set the number of reviews done &lt;br /&gt;
      by each student to be greater than or equal to total number of teams &lt;br /&gt;
      [or &amp;quot;participants&amp;quot; if it is an individual assignment].'&lt;br /&gt;
    end&lt;br /&gt;
    peer_review_strategy(assignment_id, teams, num_participants, &lt;br /&gt;
                         student_review_num, num_reviews_per_team, &lt;br /&gt;
                         participants, participants_hash)&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
=Test=&lt;br /&gt;
# We test delete_outstanding_reviewers refactor from the UI. Here is a video for this test. https://youtu.be/MZxOaSsm58E&lt;br /&gt;
# We use some data to test the result of old query and new query in rails console&lt;br /&gt;
 &lt;br /&gt;
  ReviewResponseMap.where(['reviewee_id = ? and reviewer_id = ? ‘,6050, 9])&lt;br /&gt;
  ReviewResponseMap.where(reviewee_id: 6050,reviewer_id: 9)&lt;br /&gt;
&lt;br /&gt;
  Assignment.where([&amp;quot;instructor_id = ? and substring(name,1,1) = ?&amp;quot;, 2, ‘TestAssign2’]).order('name')&lt;br /&gt;
  Assignment .where(instructor_id:2).where(&amp;quot;substring(name,1,1) = :letter&amp;quot;,{letter:’TestAssign2’}).order('name')&lt;br /&gt;
&lt;br /&gt;
  ReviewResponseMap.where([&amp;quot;reviewed_object_id = ? and created_at &amp;gt; ? and calibrate_to = ?&amp;quot;, 13, nil, 0])&lt;br /&gt;
  ReviewResponseMap.where(reviewed_object_id:13,calibrate_to:0).where(&amp;quot;created_at &amp;gt; :time&amp;quot;,{time:nil})&lt;br /&gt;
&lt;br /&gt;
# We write RSpec feature tests to prove that all changes are correct and the project performs well as before. All tests have passed.&lt;br /&gt;
&lt;br /&gt;
The function of  method automatic_review_mapping is to automatically assign reviews on students in teams when instructor set either student review number or submissions review number. There is constraint that only one of the two numbers must be set value other than 0 (that is, one is 0 and other is not 0). To test the correctness  of our refactoring, we design a scenario and 4 cases of assigning reviews to students:&lt;br /&gt;
&lt;br /&gt;
Case 1. Instructor has not set both students review number and submissions review number (They are both 0). The page will show a notice.&lt;br /&gt;
&lt;br /&gt;
Case 2. Instructor set both numbers (They are both not 0). The page will show a notice.&lt;br /&gt;
&lt;br /&gt;
Case 3. Instructors set students review number. The controller will change database: create new relationship in ReviewResponseMap. For example, if assign student review number to 2, and there will be 20 peer reviews in total and need to allocate to 3 teams. So each team get 7 reviews on average and 1 team’s artifact will be reviewed 6 times.&lt;br /&gt;
&lt;br /&gt;
Case 4. Instructors set submissions review number. The controller will change database: create new relationship in ReviewResponseMap. For example, if assign submission review number to 3, and there will be 21 peer reviews in total to allocate to 10 participants. So every participants get 2 reviews. 9 among 10 participants will review 2 teams’ artifacts and 1 participant will review 3 teams’ artifacts.&lt;br /&gt;
&lt;br /&gt;
require 'rails_helper'&lt;br /&gt;
  describe &amp;quot;review mapping&amp;quot;, js: true do&lt;br /&gt;
    before(:each) do&lt;br /&gt;
      #create test data&lt;br /&gt;
    end&lt;br /&gt;
 &lt;br /&gt;
    it &amp;quot;show error when assign both 0&amp;quot; do&lt;br /&gt;
      login_as(&amp;quot;instructor6&amp;quot;)&lt;br /&gt;
      visit '/assignments/1/edit'&lt;br /&gt;
      find_link('ReviewStrategy').click&lt;br /&gt;
      select &amp;quot;Instructor-Selected&amp;quot;, from: 'assignment_form_assignment_review_assignment_strategy'&lt;br /&gt;
      fill_in 'num_reviews_per_student', with: 0&lt;br /&gt;
      choose 'num_reviews_submission'&lt;br /&gt;
      fill_in 'num_reviews_per_submission', with: 0&lt;br /&gt;
      click_button 'second_submit_tag'&lt;br /&gt;
      #click_button 'Save'&lt;br /&gt;
      expect(page).to have_content('Please choose either the number of reviews per student or the number of reviewers per team (student)')&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    it &amp;quot;show error when assign both numbers&amp;quot; do&lt;br /&gt;
      login_as(&amp;quot;instructor6&amp;quot;)&lt;br /&gt;
      visit '/assignments/1/edit'&lt;br /&gt;
      find_link('ReviewStrategy').click&lt;br /&gt;
      select &amp;quot;Instructor-Selected&amp;quot;, from: 'assignment_form_assignment_review_assignment_strategy'&lt;br /&gt;
      fill_in 'num_reviews_per_student', with: 1&lt;br /&gt;
      choose 'num_reviews_submission'&lt;br /&gt;
      fill_in 'num_reviews_per_submission', with: 1&lt;br /&gt;
      click_button 'second_submit_tag'&lt;br /&gt;
      #click_button 'Save'&lt;br /&gt;
      expect(page).to have_content('Please choose either the number of reviews per student or the number of reviewers per team (student), not both')&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    it &amp;quot;calculate reviewmapping from given review number per student&amp;quot; do&lt;br /&gt;
      login_as(&amp;quot;instructor6&amp;quot;)&lt;br /&gt;
      visit '/assignments/1/edit'&lt;br /&gt;
      find_link('ReviewStrategy').click&lt;br /&gt;
      select &amp;quot;Instructor-Selected&amp;quot;, from: 'assignment_form_assignment_review_assignment_strategy'&lt;br /&gt;
      fill_in 'num_reviews_per_student', with: 2&lt;br /&gt;
      click_button 'first_submit_tag'&lt;br /&gt;
      num = ReviewResponseMap.where(reviewee_id: @team1.id, reviewed_object_id: @assignment.id).count&lt;br /&gt;
      expect(num).to eq(7)&lt;br /&gt;
      num2 = ReviewResponseMap.where(reviewee_id: @team3.id, reviewed_object_id: @assignment.id).count&lt;br /&gt;
      expect(num2).to eq(6)&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    it &amp;quot;calculate reviewmapping from given review number per submission&amp;quot; do&lt;br /&gt;
      login_as(&amp;quot;instructor6&amp;quot;)&lt;br /&gt;
      visit '/assignments/1/edit'&lt;br /&gt;
      find_link('ReviewStrategy').click&lt;br /&gt;
      select &amp;quot;Instructor-Selected&amp;quot;, from: 'assignment_form_assignment_review_assignment_strategy'&lt;br /&gt;
      choose 'num_reviews_submission'&lt;br /&gt;
      fill_in 'num_reviews_per_submission', with: 7&lt;br /&gt;
      click_button 'second_submit_tag'&lt;br /&gt;
      #click_button 'Save'&lt;br /&gt;
      num = ReviewResponseMap.where(reviewer_id: @teamuser1.id, reviewed_object_id: @assignment.id).count&lt;br /&gt;
      expect(num).to eq(2)&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;/div&gt;</summary>
		<author><name>Jdeng8</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2016/E1641._Refactor_review_mapping_controller.rb&amp;diff=104105</id>
		<title>CSC/ECE 517 Fall 2016/E1641. Refactor review mapping controller.rb</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2016/E1641._Refactor_review_mapping_controller.rb&amp;diff=104105"/>
		<updated>2016-10-30T23:50:44Z</updated>

		<summary type="html">&lt;p&gt;Jdeng8: /* Test */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=Background=&lt;br /&gt;
&lt;br /&gt;
This controller sets up mappings between reviewer and reviewee. It handles all different types of response maps (review response map, author feedback response map, teammate review response map, meta review response map and quiz response map). The class has functionality for five different kinds of Responses: reviews, metareviews, teammate reviews, author feedback (“rejoinders”), and quizzes. &lt;br /&gt;
&lt;br /&gt;
=Current Implementation and Problems=&lt;br /&gt;
The controller has many methods and involve with many other controllers and views, the code is long and complicated. Some of the methods in this controller have unreasonable name associated with their functions, some methods are too long, some methods haven't been used by any other methods or views. Our work is to refactor these problems and make the code more beautiful.&lt;br /&gt;
&lt;br /&gt;
The problems are:&lt;br /&gt;
&lt;br /&gt;
# Method ''response_report'' has some SQL - like code.  Rewrite with Active Record.&lt;br /&gt;
# Test whether method ''add_user_to_assignment'' is used. There is no way that this method should be in ReviewMappingController. Please remove this method and caller.&lt;br /&gt;
# There was a ''self-review'' feature, the method ''add_self_reviewer'', ''get_team_from_submission'' are related to this. Two views calls ''add_self_reviewer'' are &amp;quot;show_available_submissions_for_quizzes.html.erb&amp;quot; and &amp;quot;show_available_submissions.html.erb&amp;quot;. The names of views are not related to ''self_review'' feature. Plus those two views are not called anywhere. Please verify this and if so, you should delete those two views, two method and also related records (e.g. in routes.rb).&lt;br /&gt;
# Method ''delete_all_reviewers'' actually only deletes the outstanding review response maps (the ones which has been initiated, but there is no response yet). So it should better be named ''delete_outstanding_reviewers''. You can try to test this method by clicking “Assign reviewers” icon on an assignment.&lt;br /&gt;
# Method ''release_reservation'' should be renamed as'' release_mapping''. In addition, delete it if you find this method is not called anywhere.&lt;br /&gt;
# Method ''delete_mappings'' is problematic. It does not looks like a controller method. Please refactor it or delete it if you can validate that this method is not called anywhere.&lt;br /&gt;
# Method'' automatic_review_mapping_strategy'' is too long. Please refactor and test it.&lt;br /&gt;
&lt;br /&gt;
=Changes Implemented=&lt;br /&gt;
&lt;br /&gt;
# change the rails query from sql like code, like ReviewResponseMap.where(['reviewee_id = ? and reviewer_id = ? ', params[:contributor_id], reviewer.id]) to more rails quey like ReviewResponseMap.where(reviewee_id: params[:contributor_id],reviewer_id: reviewer.id)&lt;br /&gt;
# We search the function name(''add_user_to_assignment'') in the whole files, and find that this method is invoked in &amp;quot;participants_helper.rb&amp;quot;, and also being invoked in the function of ''add_reviewer'' and ''add_metareviewer'' in the controller of ''review_mapping_controller'' &lt;br /&gt;
# By searching the whole project and routes, we verify that methods ''add_self_reviewer'' and ''get_team_from_submission'' in this controller are not called by any other methods except for views &amp;quot;show_available_submissions_for_quizzes.html.erb&amp;quot; and &amp;quot;show_available_submissions.html.erb&amp;quot;. And those two views are not linked to any other views. So they are deleted from the project.&lt;br /&gt;
# We already renamed method ''delete_all_reviewers'' to ''delete_outstanding_reviewers'' and changed the corresponding button name at the corresponding view (_list_review_mappings.html.erb).&lt;br /&gt;
# By searching the whole project and routes, we verify that methods'' release_reservation'' in this controller are not used in anywhere.&lt;br /&gt;
# By searching the whole project and routes, we verify that methods ''delete_mappings'' in this controller are not used in anywhere.&lt;br /&gt;
# Method ''automatic_review_mapping_strategy'' have many long lines. We already shorten each long line to multiple lines. And also, we split this long function into three different functions.&lt;br /&gt;
&lt;br /&gt;
=Code=&lt;br /&gt;
&lt;br /&gt;
==Refactor SQL query code==&lt;br /&gt;
&lt;br /&gt;
The rails query we change in this controller:&lt;br /&gt;
&lt;br /&gt;
1. From &lt;br /&gt;
&lt;br /&gt;
  ReviewResponseMap.where(['reviewee_id = ? and reviewer_id = ? ', params[:contributor_id], reviewer.id]) &lt;br /&gt;
&lt;br /&gt;
To&lt;br /&gt;
&lt;br /&gt;
  ReviewResponseMap.where(reviewee_id: params[:contributor_id],reviewer_id: reviewer.id)&lt;br /&gt;
&lt;br /&gt;
2. From&lt;br /&gt;
&lt;br /&gt;
  MetareviewResponseMap.where(['reviewed_object_id = ? and reviewer_id = ?', mapping.map_id, reviewer.id])&lt;br /&gt;
&lt;br /&gt;
To&lt;br /&gt;
&lt;br /&gt;
  MetareviewResponseMap.where(reviewed_object_id: mapping.map_id, reviewer_id: reviewer.id)&lt;br /&gt;
&lt;br /&gt;
3. From&lt;br /&gt;
&lt;br /&gt;
                   @assignments = Assignment&lt;br /&gt;
                   .where([&amp;quot;instructor_id = ? and substring(name,1,1) = ?&amp;quot;, session[:user].id, letter])&lt;br /&gt;
                   .order('name')&lt;br /&gt;
                   .page(params[:page])&lt;br /&gt;
                   .per_page(10)&lt;br /&gt;
&lt;br /&gt;
To &lt;br /&gt;
&lt;br /&gt;
                   @assignments = Assignment&lt;br /&gt;
                   .where(instructor_id:session[:user].id)&lt;br /&gt;
                   .where(&amp;quot;substring(name,1,1) = :letter&amp;quot;,{letter:letter})&lt;br /&gt;
                   .order('name')&lt;br /&gt;
                   .page(params[:page])&lt;br /&gt;
                   .per_page(10)&lt;br /&gt;
&lt;br /&gt;
4.  From&lt;br /&gt;
&lt;br /&gt;
  ReviewResponseMap.where([&amp;quot;reviewed_object_id = ? and calibrate_to = ?&amp;quot;, assignment_id, 1])&lt;br /&gt;
&lt;br /&gt;
To &lt;br /&gt;
&lt;br /&gt;
  ReviewResponseMap.where(reviewed_object_id:assignment_id, calibrate_to: 1)&lt;br /&gt;
&lt;br /&gt;
5. From&lt;br /&gt;
&lt;br /&gt;
  ReviewResponseMap.where([&amp;quot;reviewed_object_id = ? and created_at &amp;gt; ? and calibrate_to = ?&amp;quot;, assignment_id, @@time_create_last_review_mapping_record, 0])&lt;br /&gt;
&lt;br /&gt;
To &lt;br /&gt;
&lt;br /&gt;
  ReviewResponseMap.where(reviewed_object_id:assignment_id,calibrate_to:0).where(&amp;quot;created_at &amp;gt; :time&amp;quot;,{time:@@time_create_last_review_mapping_record})&lt;br /&gt;
&lt;br /&gt;
6. From&lt;br /&gt;
&lt;br /&gt;
  AssignmentQuestionnaire.where([&amp;quot;assignment_id = ? and questionnaire_id IN (?)&amp;quot;, params[:id], @review_questionnaire_ids])&lt;br /&gt;
&lt;br /&gt;
To&lt;br /&gt;
 &lt;br /&gt;
  AssignmentQuestionnaire.where(assignment_id: params[:id],:questionnaire_id =&amp;gt; @review_questionnaire_ids)&lt;br /&gt;
&lt;br /&gt;
7. From&lt;br /&gt;
&lt;br /&gt;
  SelfReviewResponseMap.where(['reviewee_id = ? and reviewer_id = ?', team_id[0].t_id, params[:reviewer_id]])&lt;br /&gt;
&lt;br /&gt;
To &lt;br /&gt;
&lt;br /&gt;
  SelfReviewResponseMap.where(reviewee_id:team_id[0].t_id,reviewer_id:params[:reviewer_id])&lt;br /&gt;
&lt;br /&gt;
==Refactor long line method==&lt;br /&gt;
&lt;br /&gt;
  def automatic_review_mapping_strategy(assignment_id,&lt;br /&gt;
                                        participants, teams, student_review_num = 0,&lt;br /&gt;
                                        submission_review_num = 0)&lt;br /&gt;
    participants_hash = {}&lt;br /&gt;
    participants.each {|participant| participants_hash[participant.id] = 0 }&lt;br /&gt;
    # calculate reviewers for each team&lt;br /&gt;
    num_participants = participants.size&lt;br /&gt;
    if student_review_num != 0 and submission_review_num == 0&lt;br /&gt;
      num_reviews_per_team = (participants.size * student_review_num * 1.0 / teams.size).round&lt;br /&gt;
      student_review_num = student_review_num&lt;br /&gt;
      exact_num_of_review_needed = participants.size * student_review_num&lt;br /&gt;
    elsif student_review_num == 0 and submission_review_num != 0&lt;br /&gt;
      num_reviews_per_team = submission_review_num&lt;br /&gt;
      student_review_num = (teams.size * submission_review_num * 1.0 / participants.size).round&lt;br /&gt;
      exact_num_of_review_needed = teams.size * submission_review_num&lt;br /&gt;
    end&lt;br /&gt;
    execute_peer_review_strategy(assignment_id, teams, num_participants,&lt;br /&gt;
                                     student_review_num, num_reviews_per_team,&lt;br /&gt;
                                     participants, participants_hash)&lt;br /&gt;
    # after assigning peer reviews for each team,&lt;br /&gt;
    # if there are still some peer reviewers not obtain enough peer review,&lt;br /&gt;
    # just assign them to valid teams&lt;br /&gt;
    assign_reviewers_for_team(assignment_id,student_review_num,participants_hash,&lt;br /&gt;
                              exact_num_of_review_needed)&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  def assign_reviewers_for_team(assignment_id,student_review_num,participants_hash,&lt;br /&gt;
                                exact_num_of_review_needed)&lt;br /&gt;
     if ReviewResponseMap.where(reviewed_object_id:assignment_id,calibrate_to:0)&lt;br /&gt;
             .where(&amp;quot;created_at &amp;gt; :time&amp;quot;,&lt;br /&gt;
          {time:@@time_create_last_review_mapping_record}).size &amp;lt; exact_num_of_review_needed&lt;br /&gt;
      participants_with_insufficient_review_num = []&lt;br /&gt;
      participants_hash.each do |participant_id, review_num|&lt;br /&gt;
        participants_with_insufficient_review_num &amp;lt;&amp;lt; participant_id if review_num &amp;lt; student_review_num&lt;br /&gt;
      end&lt;br /&gt;
      unsorted_teams_hash = {}&lt;br /&gt;
     ReviewResponseMap.where(reviewed_object_id:assignment_id,&lt;br /&gt;
                  calibrate_to:0).each do |response_map|&lt;br /&gt;
        if unsorted_teams_hash.key? response_map.reviewee_id&lt;br /&gt;
          unsorted_teams_hash[response_map.reviewee_id] += 1&lt;br /&gt;
        else&lt;br /&gt;
          unsorted_teams_hash[response_map.reviewee_id] = 1&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
      teams_hash = unsorted_teams_hash.sort_by {|_, v| v }.to_h&lt;br /&gt;
      participants_with_insufficient_review_num.each do |participant_id|&lt;br /&gt;
        teams_hash.each do |team_id, _num_review_received|&lt;br /&gt;
          next if TeamsUser.exists?(team_id: team_id, &lt;br /&gt;
                                    user_id: Participant.find(participant_id).user_id)&lt;br /&gt;
          ReviewResponseMap.where(reviewee_id: team_id, reviewer_id: participant_id, &lt;br /&gt;
                                  reviewed_object_id: assignment_id).first_or_create&lt;br /&gt;
          teams_hash[team_id] += 1&lt;br /&gt;
          teams_hash = teams_hash.sort_by {|_, v| v }.to_h&lt;br /&gt;
          break&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
    @@time_create_last_review_mapping_record = ReviewResponseMap.&lt;br /&gt;
                                               where(reviewed_object_id: assignment_id).&lt;br /&gt;
                                               last.created_at&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def execute_peer_review_strategy(assignment_id, teams, num_participants, &lt;br /&gt;
                                   student_review_num, num_reviews_per_team, &lt;br /&gt;
                                   participants, participants_hash)&lt;br /&gt;
    # Exception detection: If instructor want to assign too many reviews done&lt;br /&gt;
    # by each student, there will be an error msg.&lt;br /&gt;
    if student_review_num &amp;gt;= teams.size&lt;br /&gt;
      flash[:error] = 'You cannot set the number of reviews done &lt;br /&gt;
      by each student to be greater than or equal to total number of teams &lt;br /&gt;
      [or &amp;quot;participants&amp;quot; if it is an individual assignment].'&lt;br /&gt;
    end&lt;br /&gt;
    peer_review_strategy(assignment_id, teams, num_participants, &lt;br /&gt;
                         student_review_num, num_reviews_per_team, &lt;br /&gt;
                         participants, participants_hash)&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
=Test=&lt;br /&gt;
# We test delete_outstanding_reviewers refactor from the UI. Here is a video for this test. https://youtu.be/MZxOaSsm58E&lt;br /&gt;
# We use some data to test the result of old query and new query in rails console&lt;br /&gt;
 &lt;br /&gt;
  ReviewResponseMap.where(['reviewee_id = ? and reviewer_id = ? ‘,6050, 9])&lt;br /&gt;
  ReviewResponseMap.where(reviewee_id: 6050,reviewer_id: 9)&lt;br /&gt;
&lt;br /&gt;
  Assignment.where([&amp;quot;instructor_id = ? and substring(name,1,1) = ?&amp;quot;, 2, ‘TestAssign2’]).order('name')&lt;br /&gt;
  Assignment .where(instructor_id:2).where(&amp;quot;substring(name,1,1) = :letter&amp;quot;,{letter:’TestAssign2’}).order('name')&lt;br /&gt;
&lt;br /&gt;
  ReviewResponseMap.where([&amp;quot;reviewed_object_id = ? and created_at &amp;gt; ? and calibrate_to = ?&amp;quot;, 13, nil, 0])&lt;br /&gt;
  ReviewResponseMap.where(reviewed_object_id:13,calibrate_to:0).where(&amp;quot;created_at &amp;gt; :time&amp;quot;,{time:nil})&lt;br /&gt;
&lt;br /&gt;
# We write RSpec feature tests to prove that all changes are correct and the project performs well as before.&lt;br /&gt;
&lt;br /&gt;
The function of  method automatic_review_mapping is to automatically assign reviews on students in teams when instructor set either student review number or submissions review number. There is constraint that only one of the two numbers must be set value other than 0 (that is, one is 0 and other is not 0). To test the correctness  of our refactoring, we design a scenario and 4 cases of assigning reviews to students:&lt;br /&gt;
&lt;br /&gt;
Case 1. Instructor has not set both students review number and submissions review number (They are both 0). The page will show a notice.&lt;br /&gt;
&lt;br /&gt;
Case 2. Instructor set both numbers (They are both not 0). The page will show a notice.&lt;br /&gt;
&lt;br /&gt;
Case 3. Instructors set students review number. The controller will change database: create new relationship in ReviewResponseMap. For example, if assign student review number to 2, and there will be 20 peer reviews in total and need to allocate to 3 teams. So each team get 7 reviews on average and 1 team’s artifact will be reviewed 6 times.&lt;br /&gt;
&lt;br /&gt;
Case 4. Instructors set submissions review number. The controller will change database: create new relationship in ReviewResponseMap. For example, if assign submission review number to 3, and there will be 21 peer reviews in total to allocate to 10 participants. So every participants get 2 reviews. 9 among 10 participants will review 2 teams’ artifacts and 1 participant will review 3 teams’ artifacts.&lt;br /&gt;
&lt;br /&gt;
require 'rails_helper'&lt;br /&gt;
  describe &amp;quot;review mapping&amp;quot;, js: true do&lt;br /&gt;
    before(:each) do&lt;br /&gt;
      #create test data&lt;br /&gt;
    end&lt;br /&gt;
 &lt;br /&gt;
    it &amp;quot;show error when assign both 0&amp;quot; do&lt;br /&gt;
      login_as(&amp;quot;instructor6&amp;quot;)&lt;br /&gt;
      visit '/assignments/1/edit'&lt;br /&gt;
      find_link('ReviewStrategy').click&lt;br /&gt;
      select &amp;quot;Instructor-Selected&amp;quot;, from: 'assignment_form_assignment_review_assignment_strategy'&lt;br /&gt;
      fill_in 'num_reviews_per_student', with: 0&lt;br /&gt;
      choose 'num_reviews_submission'&lt;br /&gt;
      fill_in 'num_reviews_per_submission', with: 0&lt;br /&gt;
      click_button 'second_submit_tag'&lt;br /&gt;
      #click_button 'Save'&lt;br /&gt;
      expect(page).to have_content('Please choose either the number of reviews per student or the number of reviewers per team (student)')&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    it &amp;quot;show error when assign both numbers&amp;quot; do&lt;br /&gt;
      login_as(&amp;quot;instructor6&amp;quot;)&lt;br /&gt;
      visit '/assignments/1/edit'&lt;br /&gt;
      find_link('ReviewStrategy').click&lt;br /&gt;
      select &amp;quot;Instructor-Selected&amp;quot;, from: 'assignment_form_assignment_review_assignment_strategy'&lt;br /&gt;
      fill_in 'num_reviews_per_student', with: 1&lt;br /&gt;
      choose 'num_reviews_submission'&lt;br /&gt;
      fill_in 'num_reviews_per_submission', with: 1&lt;br /&gt;
      click_button 'second_submit_tag'&lt;br /&gt;
      #click_button 'Save'&lt;br /&gt;
      expect(page).to have_content('Please choose either the number of reviews per student or the number of reviewers per team (student), not both')&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    it &amp;quot;calculate reviewmapping from given review number per student&amp;quot; do&lt;br /&gt;
      login_as(&amp;quot;instructor6&amp;quot;)&lt;br /&gt;
      visit '/assignments/1/edit'&lt;br /&gt;
      find_link('ReviewStrategy').click&lt;br /&gt;
      select &amp;quot;Instructor-Selected&amp;quot;, from: 'assignment_form_assignment_review_assignment_strategy'&lt;br /&gt;
      fill_in 'num_reviews_per_student', with: 2&lt;br /&gt;
      click_button 'first_submit_tag'&lt;br /&gt;
      num = ReviewResponseMap.where(reviewee_id: @team1.id, reviewed_object_id: @assignment.id).count&lt;br /&gt;
      expect(num).to eq(7)&lt;br /&gt;
      num2 = ReviewResponseMap.where(reviewee_id: @team3.id, reviewed_object_id: @assignment.id).count&lt;br /&gt;
      expect(num2).to eq(6)&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    it &amp;quot;calculate reviewmapping from given review number per submission&amp;quot; do&lt;br /&gt;
      login_as(&amp;quot;instructor6&amp;quot;)&lt;br /&gt;
      visit '/assignments/1/edit'&lt;br /&gt;
      find_link('ReviewStrategy').click&lt;br /&gt;
      select &amp;quot;Instructor-Selected&amp;quot;, from: 'assignment_form_assignment_review_assignment_strategy'&lt;br /&gt;
      choose 'num_reviews_submission'&lt;br /&gt;
      fill_in 'num_reviews_per_submission', with: 7&lt;br /&gt;
      click_button 'second_submit_tag'&lt;br /&gt;
      #click_button 'Save'&lt;br /&gt;
      num = ReviewResponseMap.where(reviewer_id: @teamuser1.id, reviewed_object_id: @assignment.id).count&lt;br /&gt;
      expect(num).to eq(2)&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;/div&gt;</summary>
		<author><name>Jdeng8</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2016/E1641._Refactor_review_mapping_controller.rb&amp;diff=104104</id>
		<title>CSC/ECE 517 Fall 2016/E1641. Refactor review mapping controller.rb</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2016/E1641._Refactor_review_mapping_controller.rb&amp;diff=104104"/>
		<updated>2016-10-30T23:50:23Z</updated>

		<summary type="html">&lt;p&gt;Jdeng8: /* Test */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=Background=&lt;br /&gt;
&lt;br /&gt;
This controller sets up mappings between reviewer and reviewee. It handles all different types of response maps (review response map, author feedback response map, teammate review response map, meta review response map and quiz response map). The class has functionality for five different kinds of Responses: reviews, metareviews, teammate reviews, author feedback (“rejoinders”), and quizzes. &lt;br /&gt;
&lt;br /&gt;
=Current Implementation and Problems=&lt;br /&gt;
The controller has many methods and involve with many other controllers and views, the code is long and complicated. Some of the methods in this controller have unreasonable name associated with their functions, some methods are too long, some methods haven't been used by any other methods or views. Our work is to refactor these problems and make the code more beautiful.&lt;br /&gt;
&lt;br /&gt;
The problems are:&lt;br /&gt;
&lt;br /&gt;
# Method ''response_report'' has some SQL - like code.  Rewrite with Active Record.&lt;br /&gt;
# Test whether method ''add_user_to_assignment'' is used. There is no way that this method should be in ReviewMappingController. Please remove this method and caller.&lt;br /&gt;
# There was a ''self-review'' feature, the method ''add_self_reviewer'', ''get_team_from_submission'' are related to this. Two views calls ''add_self_reviewer'' are &amp;quot;show_available_submissions_for_quizzes.html.erb&amp;quot; and &amp;quot;show_available_submissions.html.erb&amp;quot;. The names of views are not related to ''self_review'' feature. Plus those two views are not called anywhere. Please verify this and if so, you should delete those two views, two method and also related records (e.g. in routes.rb).&lt;br /&gt;
# Method ''delete_all_reviewers'' actually only deletes the outstanding review response maps (the ones which has been initiated, but there is no response yet). So it should better be named ''delete_outstanding_reviewers''. You can try to test this method by clicking “Assign reviewers” icon on an assignment.&lt;br /&gt;
# Method ''release_reservation'' should be renamed as'' release_mapping''. In addition, delete it if you find this method is not called anywhere.&lt;br /&gt;
# Method ''delete_mappings'' is problematic. It does not looks like a controller method. Please refactor it or delete it if you can validate that this method is not called anywhere.&lt;br /&gt;
# Method'' automatic_review_mapping_strategy'' is too long. Please refactor and test it.&lt;br /&gt;
&lt;br /&gt;
=Changes Implemented=&lt;br /&gt;
&lt;br /&gt;
# change the rails query from sql like code, like ReviewResponseMap.where(['reviewee_id = ? and reviewer_id = ? ', params[:contributor_id], reviewer.id]) to more rails quey like ReviewResponseMap.where(reviewee_id: params[:contributor_id],reviewer_id: reviewer.id)&lt;br /&gt;
# We search the function name(''add_user_to_assignment'') in the whole files, and find that this method is invoked in &amp;quot;participants_helper.rb&amp;quot;, and also being invoked in the function of ''add_reviewer'' and ''add_metareviewer'' in the controller of ''review_mapping_controller'' &lt;br /&gt;
# By searching the whole project and routes, we verify that methods ''add_self_reviewer'' and ''get_team_from_submission'' in this controller are not called by any other methods except for views &amp;quot;show_available_submissions_for_quizzes.html.erb&amp;quot; and &amp;quot;show_available_submissions.html.erb&amp;quot;. And those two views are not linked to any other views. So they are deleted from the project.&lt;br /&gt;
# We already renamed method ''delete_all_reviewers'' to ''delete_outstanding_reviewers'' and changed the corresponding button name at the corresponding view (_list_review_mappings.html.erb).&lt;br /&gt;
# By searching the whole project and routes, we verify that methods'' release_reservation'' in this controller are not used in anywhere.&lt;br /&gt;
# By searching the whole project and routes, we verify that methods ''delete_mappings'' in this controller are not used in anywhere.&lt;br /&gt;
# Method ''automatic_review_mapping_strategy'' have many long lines. We already shorten each long line to multiple lines. And also, we split this long function into three different functions.&lt;br /&gt;
&lt;br /&gt;
=Code=&lt;br /&gt;
&lt;br /&gt;
==Refactor SQL query code==&lt;br /&gt;
&lt;br /&gt;
The rails query we change in this controller:&lt;br /&gt;
&lt;br /&gt;
1. From &lt;br /&gt;
&lt;br /&gt;
  ReviewResponseMap.where(['reviewee_id = ? and reviewer_id = ? ', params[:contributor_id], reviewer.id]) &lt;br /&gt;
&lt;br /&gt;
To&lt;br /&gt;
&lt;br /&gt;
  ReviewResponseMap.where(reviewee_id: params[:contributor_id],reviewer_id: reviewer.id)&lt;br /&gt;
&lt;br /&gt;
2. From&lt;br /&gt;
&lt;br /&gt;
  MetareviewResponseMap.where(['reviewed_object_id = ? and reviewer_id = ?', mapping.map_id, reviewer.id])&lt;br /&gt;
&lt;br /&gt;
To&lt;br /&gt;
&lt;br /&gt;
  MetareviewResponseMap.where(reviewed_object_id: mapping.map_id, reviewer_id: reviewer.id)&lt;br /&gt;
&lt;br /&gt;
3. From&lt;br /&gt;
&lt;br /&gt;
                   @assignments = Assignment&lt;br /&gt;
                   .where([&amp;quot;instructor_id = ? and substring(name,1,1) = ?&amp;quot;, session[:user].id, letter])&lt;br /&gt;
                   .order('name')&lt;br /&gt;
                   .page(params[:page])&lt;br /&gt;
                   .per_page(10)&lt;br /&gt;
&lt;br /&gt;
To &lt;br /&gt;
&lt;br /&gt;
                   @assignments = Assignment&lt;br /&gt;
                   .where(instructor_id:session[:user].id)&lt;br /&gt;
                   .where(&amp;quot;substring(name,1,1) = :letter&amp;quot;,{letter:letter})&lt;br /&gt;
                   .order('name')&lt;br /&gt;
                   .page(params[:page])&lt;br /&gt;
                   .per_page(10)&lt;br /&gt;
&lt;br /&gt;
4.  From&lt;br /&gt;
&lt;br /&gt;
  ReviewResponseMap.where([&amp;quot;reviewed_object_id = ? and calibrate_to = ?&amp;quot;, assignment_id, 1])&lt;br /&gt;
&lt;br /&gt;
To &lt;br /&gt;
&lt;br /&gt;
  ReviewResponseMap.where(reviewed_object_id:assignment_id, calibrate_to: 1)&lt;br /&gt;
&lt;br /&gt;
5. From&lt;br /&gt;
&lt;br /&gt;
  ReviewResponseMap.where([&amp;quot;reviewed_object_id = ? and created_at &amp;gt; ? and calibrate_to = ?&amp;quot;, assignment_id, @@time_create_last_review_mapping_record, 0])&lt;br /&gt;
&lt;br /&gt;
To &lt;br /&gt;
&lt;br /&gt;
  ReviewResponseMap.where(reviewed_object_id:assignment_id,calibrate_to:0).where(&amp;quot;created_at &amp;gt; :time&amp;quot;,{time:@@time_create_last_review_mapping_record})&lt;br /&gt;
&lt;br /&gt;
6. From&lt;br /&gt;
&lt;br /&gt;
  AssignmentQuestionnaire.where([&amp;quot;assignment_id = ? and questionnaire_id IN (?)&amp;quot;, params[:id], @review_questionnaire_ids])&lt;br /&gt;
&lt;br /&gt;
To&lt;br /&gt;
 &lt;br /&gt;
  AssignmentQuestionnaire.where(assignment_id: params[:id],:questionnaire_id =&amp;gt; @review_questionnaire_ids)&lt;br /&gt;
&lt;br /&gt;
7. From&lt;br /&gt;
&lt;br /&gt;
  SelfReviewResponseMap.where(['reviewee_id = ? and reviewer_id = ?', team_id[0].t_id, params[:reviewer_id]])&lt;br /&gt;
&lt;br /&gt;
To &lt;br /&gt;
&lt;br /&gt;
  SelfReviewResponseMap.where(reviewee_id:team_id[0].t_id,reviewer_id:params[:reviewer_id])&lt;br /&gt;
&lt;br /&gt;
==Refactor long line method==&lt;br /&gt;
&lt;br /&gt;
  def automatic_review_mapping_strategy(assignment_id,&lt;br /&gt;
                                        participants, teams, student_review_num = 0,&lt;br /&gt;
                                        submission_review_num = 0)&lt;br /&gt;
    participants_hash = {}&lt;br /&gt;
    participants.each {|participant| participants_hash[participant.id] = 0 }&lt;br /&gt;
    # calculate reviewers for each team&lt;br /&gt;
    num_participants = participants.size&lt;br /&gt;
    if student_review_num != 0 and submission_review_num == 0&lt;br /&gt;
      num_reviews_per_team = (participants.size * student_review_num * 1.0 / teams.size).round&lt;br /&gt;
      student_review_num = student_review_num&lt;br /&gt;
      exact_num_of_review_needed = participants.size * student_review_num&lt;br /&gt;
    elsif student_review_num == 0 and submission_review_num != 0&lt;br /&gt;
      num_reviews_per_team = submission_review_num&lt;br /&gt;
      student_review_num = (teams.size * submission_review_num * 1.0 / participants.size).round&lt;br /&gt;
      exact_num_of_review_needed = teams.size * submission_review_num&lt;br /&gt;
    end&lt;br /&gt;
    execute_peer_review_strategy(assignment_id, teams, num_participants,&lt;br /&gt;
                                     student_review_num, num_reviews_per_team,&lt;br /&gt;
                                     participants, participants_hash)&lt;br /&gt;
    # after assigning peer reviews for each team,&lt;br /&gt;
    # if there are still some peer reviewers not obtain enough peer review,&lt;br /&gt;
    # just assign them to valid teams&lt;br /&gt;
    assign_reviewers_for_team(assignment_id,student_review_num,participants_hash,&lt;br /&gt;
                              exact_num_of_review_needed)&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  def assign_reviewers_for_team(assignment_id,student_review_num,participants_hash,&lt;br /&gt;
                                exact_num_of_review_needed)&lt;br /&gt;
     if ReviewResponseMap.where(reviewed_object_id:assignment_id,calibrate_to:0)&lt;br /&gt;
             .where(&amp;quot;created_at &amp;gt; :time&amp;quot;,&lt;br /&gt;
          {time:@@time_create_last_review_mapping_record}).size &amp;lt; exact_num_of_review_needed&lt;br /&gt;
      participants_with_insufficient_review_num = []&lt;br /&gt;
      participants_hash.each do |participant_id, review_num|&lt;br /&gt;
        participants_with_insufficient_review_num &amp;lt;&amp;lt; participant_id if review_num &amp;lt; student_review_num&lt;br /&gt;
      end&lt;br /&gt;
      unsorted_teams_hash = {}&lt;br /&gt;
     ReviewResponseMap.where(reviewed_object_id:assignment_id,&lt;br /&gt;
                  calibrate_to:0).each do |response_map|&lt;br /&gt;
        if unsorted_teams_hash.key? response_map.reviewee_id&lt;br /&gt;
          unsorted_teams_hash[response_map.reviewee_id] += 1&lt;br /&gt;
        else&lt;br /&gt;
          unsorted_teams_hash[response_map.reviewee_id] = 1&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
      teams_hash = unsorted_teams_hash.sort_by {|_, v| v }.to_h&lt;br /&gt;
      participants_with_insufficient_review_num.each do |participant_id|&lt;br /&gt;
        teams_hash.each do |team_id, _num_review_received|&lt;br /&gt;
          next if TeamsUser.exists?(team_id: team_id, &lt;br /&gt;
                                    user_id: Participant.find(participant_id).user_id)&lt;br /&gt;
          ReviewResponseMap.where(reviewee_id: team_id, reviewer_id: participant_id, &lt;br /&gt;
                                  reviewed_object_id: assignment_id).first_or_create&lt;br /&gt;
          teams_hash[team_id] += 1&lt;br /&gt;
          teams_hash = teams_hash.sort_by {|_, v| v }.to_h&lt;br /&gt;
          break&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
    @@time_create_last_review_mapping_record = ReviewResponseMap.&lt;br /&gt;
                                               where(reviewed_object_id: assignment_id).&lt;br /&gt;
                                               last.created_at&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def execute_peer_review_strategy(assignment_id, teams, num_participants, &lt;br /&gt;
                                   student_review_num, num_reviews_per_team, &lt;br /&gt;
                                   participants, participants_hash)&lt;br /&gt;
    # Exception detection: If instructor want to assign too many reviews done&lt;br /&gt;
    # by each student, there will be an error msg.&lt;br /&gt;
    if student_review_num &amp;gt;= teams.size&lt;br /&gt;
      flash[:error] = 'You cannot set the number of reviews done &lt;br /&gt;
      by each student to be greater than or equal to total number of teams &lt;br /&gt;
      [or &amp;quot;participants&amp;quot; if it is an individual assignment].'&lt;br /&gt;
    end&lt;br /&gt;
    peer_review_strategy(assignment_id, teams, num_participants, &lt;br /&gt;
                         student_review_num, num_reviews_per_team, &lt;br /&gt;
                         participants, participants_hash)&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
=Test=&lt;br /&gt;
# We test delete_outstanding_reviewers refactor from the UI. Here is a video for this test. https://youtu.be/MZxOaSsm58E&lt;br /&gt;
# We use some data to test the result of old query and new query in rails console&lt;br /&gt;
 &lt;br /&gt;
  ReviewResponseMap.where(['reviewee_id = ? and reviewer_id = ? ‘,6050, 9])&lt;br /&gt;
  ReviewResponseMap.where(reviewee_id: 6050,reviewer_id: 9)&lt;br /&gt;
&lt;br /&gt;
  Assignment.where([&amp;quot;instructor_id = ? and substring(name,1,1) = ?&amp;quot;, 2, ‘TestAssign2’]).order('name')&lt;br /&gt;
  Assignment .where(instructor_id:2).where(&amp;quot;substring(name,1,1) = :letter&amp;quot;,{letter:’TestAssign2’}).order('name')&lt;br /&gt;
&lt;br /&gt;
  ReviewResponseMap.where([&amp;quot;reviewed_object_id = ? and created_at &amp;gt; ? and calibrate_to = ?&amp;quot;, 13, nil, 0])&lt;br /&gt;
  ReviewResponseMap.where(reviewed_object_id:13,calibrate_to:0).where(&amp;quot;created_at &amp;gt; :time&amp;quot;,{time:nil})&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
#We write RSpec feature tests to prove that all changes are correct and the project performs well as before.&lt;br /&gt;
&lt;br /&gt;
The function of  method automatic_review_mapping is to automatically assign reviews on students in teams when instructor set either student review number or submissions review number. There is constraint that only one of the two numbers must be set value other than 0 (that is, one is 0 and other is not 0). To test the correctness  of our refactoring, we design a scenario and 4 cases of assigning reviews to students:&lt;br /&gt;
&lt;br /&gt;
Case 1. Instructor has not set both students review number and submissions review number (They are both 0). The page will show a notice.&lt;br /&gt;
&lt;br /&gt;
Case 2. Instructor set both numbers (They are both not 0). The page will show a notice.&lt;br /&gt;
&lt;br /&gt;
Case 3. Instructors set students review number. The controller will change database: create new relationship in ReviewResponseMap. For example, if assign student review number to 2, and there will be 20 peer reviews in total and need to allocate to 3 teams. So each team get 7 reviews on average and 1 team’s artifact will be reviewed 6 times.&lt;br /&gt;
&lt;br /&gt;
Case 4. Instructors set submissions review number. The controller will change database: create new relationship in ReviewResponseMap. For example, if assign submission review number to 3, and there will be 21 peer reviews in total to allocate to 10 participants. So every participants get 2 reviews. 9 among 10 participants will review 2 teams’ artifacts and 1 participant will review 3 teams’ artifacts.&lt;br /&gt;
&lt;br /&gt;
require 'rails_helper'&lt;br /&gt;
  describe &amp;quot;review mapping&amp;quot;, js: true do&lt;br /&gt;
    before(:each) do&lt;br /&gt;
      #create test data&lt;br /&gt;
    end&lt;br /&gt;
 &lt;br /&gt;
    it &amp;quot;show error when assign both 0&amp;quot; do&lt;br /&gt;
      login_as(&amp;quot;instructor6&amp;quot;)&lt;br /&gt;
      visit '/assignments/1/edit'&lt;br /&gt;
      find_link('ReviewStrategy').click&lt;br /&gt;
      select &amp;quot;Instructor-Selected&amp;quot;, from: 'assignment_form_assignment_review_assignment_strategy'&lt;br /&gt;
      fill_in 'num_reviews_per_student', with: 0&lt;br /&gt;
      choose 'num_reviews_submission'&lt;br /&gt;
      fill_in 'num_reviews_per_submission', with: 0&lt;br /&gt;
      click_button 'second_submit_tag'&lt;br /&gt;
      #click_button 'Save'&lt;br /&gt;
      expect(page).to have_content('Please choose either the number of reviews per student or the number of reviewers per team (student)')&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    it &amp;quot;show error when assign both numbers&amp;quot; do&lt;br /&gt;
      login_as(&amp;quot;instructor6&amp;quot;)&lt;br /&gt;
      visit '/assignments/1/edit'&lt;br /&gt;
      find_link('ReviewStrategy').click&lt;br /&gt;
      select &amp;quot;Instructor-Selected&amp;quot;, from: 'assignment_form_assignment_review_assignment_strategy'&lt;br /&gt;
      fill_in 'num_reviews_per_student', with: 1&lt;br /&gt;
      choose 'num_reviews_submission'&lt;br /&gt;
      fill_in 'num_reviews_per_submission', with: 1&lt;br /&gt;
      click_button 'second_submit_tag'&lt;br /&gt;
      #click_button 'Save'&lt;br /&gt;
      expect(page).to have_content('Please choose either the number of reviews per student or the number of reviewers per team (student), not both')&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    it &amp;quot;calculate reviewmapping from given review number per student&amp;quot; do&lt;br /&gt;
      login_as(&amp;quot;instructor6&amp;quot;)&lt;br /&gt;
      visit '/assignments/1/edit'&lt;br /&gt;
      find_link('ReviewStrategy').click&lt;br /&gt;
      select &amp;quot;Instructor-Selected&amp;quot;, from: 'assignment_form_assignment_review_assignment_strategy'&lt;br /&gt;
      fill_in 'num_reviews_per_student', with: 2&lt;br /&gt;
      click_button 'first_submit_tag'&lt;br /&gt;
      num = ReviewResponseMap.where(reviewee_id: @team1.id, reviewed_object_id: @assignment.id).count&lt;br /&gt;
      expect(num).to eq(7)&lt;br /&gt;
      num2 = ReviewResponseMap.where(reviewee_id: @team3.id, reviewed_object_id: @assignment.id).count&lt;br /&gt;
      expect(num2).to eq(6)&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    it &amp;quot;calculate reviewmapping from given review number per submission&amp;quot; do&lt;br /&gt;
      login_as(&amp;quot;instructor6&amp;quot;)&lt;br /&gt;
      visit '/assignments/1/edit'&lt;br /&gt;
      find_link('ReviewStrategy').click&lt;br /&gt;
      select &amp;quot;Instructor-Selected&amp;quot;, from: 'assignment_form_assignment_review_assignment_strategy'&lt;br /&gt;
      choose 'num_reviews_submission'&lt;br /&gt;
      fill_in 'num_reviews_per_submission', with: 7&lt;br /&gt;
      click_button 'second_submit_tag'&lt;br /&gt;
      #click_button 'Save'&lt;br /&gt;
      num = ReviewResponseMap.where(reviewer_id: @teamuser1.id, reviewed_object_id: @assignment.id).count&lt;br /&gt;
      expect(num).to eq(2)&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;/div&gt;</summary>
		<author><name>Jdeng8</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2016/E1641._Refactor_review_mapping_controller.rb&amp;diff=104103</id>
		<title>CSC/ECE 517 Fall 2016/E1641. Refactor review mapping controller.rb</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2016/E1641._Refactor_review_mapping_controller.rb&amp;diff=104103"/>
		<updated>2016-10-30T23:49:53Z</updated>

		<summary type="html">&lt;p&gt;Jdeng8: /* Current Implementation and Problems */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=Background=&lt;br /&gt;
&lt;br /&gt;
This controller sets up mappings between reviewer and reviewee. It handles all different types of response maps (review response map, author feedback response map, teammate review response map, meta review response map and quiz response map). The class has functionality for five different kinds of Responses: reviews, metareviews, teammate reviews, author feedback (“rejoinders”), and quizzes. &lt;br /&gt;
&lt;br /&gt;
=Current Implementation and Problems=&lt;br /&gt;
The controller has many methods and involve with many other controllers and views, the code is long and complicated. Some of the methods in this controller have unreasonable name associated with their functions, some methods are too long, some methods haven't been used by any other methods or views. Our work is to refactor these problems and make the code more beautiful.&lt;br /&gt;
&lt;br /&gt;
The problems are:&lt;br /&gt;
&lt;br /&gt;
# Method ''response_report'' has some SQL - like code.  Rewrite with Active Record.&lt;br /&gt;
# Test whether method ''add_user_to_assignment'' is used. There is no way that this method should be in ReviewMappingController. Please remove this method and caller.&lt;br /&gt;
# There was a ''self-review'' feature, the method ''add_self_reviewer'', ''get_team_from_submission'' are related to this. Two views calls ''add_self_reviewer'' are &amp;quot;show_available_submissions_for_quizzes.html.erb&amp;quot; and &amp;quot;show_available_submissions.html.erb&amp;quot;. The names of views are not related to ''self_review'' feature. Plus those two views are not called anywhere. Please verify this and if so, you should delete those two views, two method and also related records (e.g. in routes.rb).&lt;br /&gt;
# Method ''delete_all_reviewers'' actually only deletes the outstanding review response maps (the ones which has been initiated, but there is no response yet). So it should better be named ''delete_outstanding_reviewers''. You can try to test this method by clicking “Assign reviewers” icon on an assignment.&lt;br /&gt;
# Method ''release_reservation'' should be renamed as'' release_mapping''. In addition, delete it if you find this method is not called anywhere.&lt;br /&gt;
# Method ''delete_mappings'' is problematic. It does not looks like a controller method. Please refactor it or delete it if you can validate that this method is not called anywhere.&lt;br /&gt;
# Method'' automatic_review_mapping_strategy'' is too long. Please refactor and test it.&lt;br /&gt;
&lt;br /&gt;
=Changes Implemented=&lt;br /&gt;
&lt;br /&gt;
# change the rails query from sql like code, like ReviewResponseMap.where(['reviewee_id = ? and reviewer_id = ? ', params[:contributor_id], reviewer.id]) to more rails quey like ReviewResponseMap.where(reviewee_id: params[:contributor_id],reviewer_id: reviewer.id)&lt;br /&gt;
# We search the function name(''add_user_to_assignment'') in the whole files, and find that this method is invoked in &amp;quot;participants_helper.rb&amp;quot;, and also being invoked in the function of ''add_reviewer'' and ''add_metareviewer'' in the controller of ''review_mapping_controller'' &lt;br /&gt;
# By searching the whole project and routes, we verify that methods ''add_self_reviewer'' and ''get_team_from_submission'' in this controller are not called by any other methods except for views &amp;quot;show_available_submissions_for_quizzes.html.erb&amp;quot; and &amp;quot;show_available_submissions.html.erb&amp;quot;. And those two views are not linked to any other views. So they are deleted from the project.&lt;br /&gt;
# We already renamed method ''delete_all_reviewers'' to ''delete_outstanding_reviewers'' and changed the corresponding button name at the corresponding view (_list_review_mappings.html.erb).&lt;br /&gt;
# By searching the whole project and routes, we verify that methods'' release_reservation'' in this controller are not used in anywhere.&lt;br /&gt;
# By searching the whole project and routes, we verify that methods ''delete_mappings'' in this controller are not used in anywhere.&lt;br /&gt;
# Method ''automatic_review_mapping_strategy'' have many long lines. We already shorten each long line to multiple lines. And also, we split this long function into three different functions.&lt;br /&gt;
&lt;br /&gt;
=Code=&lt;br /&gt;
&lt;br /&gt;
==Refactor SQL query code==&lt;br /&gt;
&lt;br /&gt;
The rails query we change in this controller:&lt;br /&gt;
&lt;br /&gt;
1. From &lt;br /&gt;
&lt;br /&gt;
  ReviewResponseMap.where(['reviewee_id = ? and reviewer_id = ? ', params[:contributor_id], reviewer.id]) &lt;br /&gt;
&lt;br /&gt;
To&lt;br /&gt;
&lt;br /&gt;
  ReviewResponseMap.where(reviewee_id: params[:contributor_id],reviewer_id: reviewer.id)&lt;br /&gt;
&lt;br /&gt;
2. From&lt;br /&gt;
&lt;br /&gt;
  MetareviewResponseMap.where(['reviewed_object_id = ? and reviewer_id = ?', mapping.map_id, reviewer.id])&lt;br /&gt;
&lt;br /&gt;
To&lt;br /&gt;
&lt;br /&gt;
  MetareviewResponseMap.where(reviewed_object_id: mapping.map_id, reviewer_id: reviewer.id)&lt;br /&gt;
&lt;br /&gt;
3. From&lt;br /&gt;
&lt;br /&gt;
                   @assignments = Assignment&lt;br /&gt;
                   .where([&amp;quot;instructor_id = ? and substring(name,1,1) = ?&amp;quot;, session[:user].id, letter])&lt;br /&gt;
                   .order('name')&lt;br /&gt;
                   .page(params[:page])&lt;br /&gt;
                   .per_page(10)&lt;br /&gt;
&lt;br /&gt;
To &lt;br /&gt;
&lt;br /&gt;
                   @assignments = Assignment&lt;br /&gt;
                   .where(instructor_id:session[:user].id)&lt;br /&gt;
                   .where(&amp;quot;substring(name,1,1) = :letter&amp;quot;,{letter:letter})&lt;br /&gt;
                   .order('name')&lt;br /&gt;
                   .page(params[:page])&lt;br /&gt;
                   .per_page(10)&lt;br /&gt;
&lt;br /&gt;
4.  From&lt;br /&gt;
&lt;br /&gt;
  ReviewResponseMap.where([&amp;quot;reviewed_object_id = ? and calibrate_to = ?&amp;quot;, assignment_id, 1])&lt;br /&gt;
&lt;br /&gt;
To &lt;br /&gt;
&lt;br /&gt;
  ReviewResponseMap.where(reviewed_object_id:assignment_id, calibrate_to: 1)&lt;br /&gt;
&lt;br /&gt;
5. From&lt;br /&gt;
&lt;br /&gt;
  ReviewResponseMap.where([&amp;quot;reviewed_object_id = ? and created_at &amp;gt; ? and calibrate_to = ?&amp;quot;, assignment_id, @@time_create_last_review_mapping_record, 0])&lt;br /&gt;
&lt;br /&gt;
To &lt;br /&gt;
&lt;br /&gt;
  ReviewResponseMap.where(reviewed_object_id:assignment_id,calibrate_to:0).where(&amp;quot;created_at &amp;gt; :time&amp;quot;,{time:@@time_create_last_review_mapping_record})&lt;br /&gt;
&lt;br /&gt;
6. From&lt;br /&gt;
&lt;br /&gt;
  AssignmentQuestionnaire.where([&amp;quot;assignment_id = ? and questionnaire_id IN (?)&amp;quot;, params[:id], @review_questionnaire_ids])&lt;br /&gt;
&lt;br /&gt;
To&lt;br /&gt;
 &lt;br /&gt;
  AssignmentQuestionnaire.where(assignment_id: params[:id],:questionnaire_id =&amp;gt; @review_questionnaire_ids)&lt;br /&gt;
&lt;br /&gt;
7. From&lt;br /&gt;
&lt;br /&gt;
  SelfReviewResponseMap.where(['reviewee_id = ? and reviewer_id = ?', team_id[0].t_id, params[:reviewer_id]])&lt;br /&gt;
&lt;br /&gt;
To &lt;br /&gt;
&lt;br /&gt;
  SelfReviewResponseMap.where(reviewee_id:team_id[0].t_id,reviewer_id:params[:reviewer_id])&lt;br /&gt;
&lt;br /&gt;
==Refactor long line method==&lt;br /&gt;
&lt;br /&gt;
  def automatic_review_mapping_strategy(assignment_id,&lt;br /&gt;
                                        participants, teams, student_review_num = 0,&lt;br /&gt;
                                        submission_review_num = 0)&lt;br /&gt;
    participants_hash = {}&lt;br /&gt;
    participants.each {|participant| participants_hash[participant.id] = 0 }&lt;br /&gt;
    # calculate reviewers for each team&lt;br /&gt;
    num_participants = participants.size&lt;br /&gt;
    if student_review_num != 0 and submission_review_num == 0&lt;br /&gt;
      num_reviews_per_team = (participants.size * student_review_num * 1.0 / teams.size).round&lt;br /&gt;
      student_review_num = student_review_num&lt;br /&gt;
      exact_num_of_review_needed = participants.size * student_review_num&lt;br /&gt;
    elsif student_review_num == 0 and submission_review_num != 0&lt;br /&gt;
      num_reviews_per_team = submission_review_num&lt;br /&gt;
      student_review_num = (teams.size * submission_review_num * 1.0 / participants.size).round&lt;br /&gt;
      exact_num_of_review_needed = teams.size * submission_review_num&lt;br /&gt;
    end&lt;br /&gt;
    execute_peer_review_strategy(assignment_id, teams, num_participants,&lt;br /&gt;
                                     student_review_num, num_reviews_per_team,&lt;br /&gt;
                                     participants, participants_hash)&lt;br /&gt;
    # after assigning peer reviews for each team,&lt;br /&gt;
    # if there are still some peer reviewers not obtain enough peer review,&lt;br /&gt;
    # just assign them to valid teams&lt;br /&gt;
    assign_reviewers_for_team(assignment_id,student_review_num,participants_hash,&lt;br /&gt;
                              exact_num_of_review_needed)&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  def assign_reviewers_for_team(assignment_id,student_review_num,participants_hash,&lt;br /&gt;
                                exact_num_of_review_needed)&lt;br /&gt;
     if ReviewResponseMap.where(reviewed_object_id:assignment_id,calibrate_to:0)&lt;br /&gt;
             .where(&amp;quot;created_at &amp;gt; :time&amp;quot;,&lt;br /&gt;
          {time:@@time_create_last_review_mapping_record}).size &amp;lt; exact_num_of_review_needed&lt;br /&gt;
      participants_with_insufficient_review_num = []&lt;br /&gt;
      participants_hash.each do |participant_id, review_num|&lt;br /&gt;
        participants_with_insufficient_review_num &amp;lt;&amp;lt; participant_id if review_num &amp;lt; student_review_num&lt;br /&gt;
      end&lt;br /&gt;
      unsorted_teams_hash = {}&lt;br /&gt;
     ReviewResponseMap.where(reviewed_object_id:assignment_id,&lt;br /&gt;
                  calibrate_to:0).each do |response_map|&lt;br /&gt;
        if unsorted_teams_hash.key? response_map.reviewee_id&lt;br /&gt;
          unsorted_teams_hash[response_map.reviewee_id] += 1&lt;br /&gt;
        else&lt;br /&gt;
          unsorted_teams_hash[response_map.reviewee_id] = 1&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
      teams_hash = unsorted_teams_hash.sort_by {|_, v| v }.to_h&lt;br /&gt;
      participants_with_insufficient_review_num.each do |participant_id|&lt;br /&gt;
        teams_hash.each do |team_id, _num_review_received|&lt;br /&gt;
          next if TeamsUser.exists?(team_id: team_id, &lt;br /&gt;
                                    user_id: Participant.find(participant_id).user_id)&lt;br /&gt;
          ReviewResponseMap.where(reviewee_id: team_id, reviewer_id: participant_id, &lt;br /&gt;
                                  reviewed_object_id: assignment_id).first_or_create&lt;br /&gt;
          teams_hash[team_id] += 1&lt;br /&gt;
          teams_hash = teams_hash.sort_by {|_, v| v }.to_h&lt;br /&gt;
          break&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
    @@time_create_last_review_mapping_record = ReviewResponseMap.&lt;br /&gt;
                                               where(reviewed_object_id: assignment_id).&lt;br /&gt;
                                               last.created_at&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def execute_peer_review_strategy(assignment_id, teams, num_participants, &lt;br /&gt;
                                   student_review_num, num_reviews_per_team, &lt;br /&gt;
                                   participants, participants_hash)&lt;br /&gt;
    # Exception detection: If instructor want to assign too many reviews done&lt;br /&gt;
    # by each student, there will be an error msg.&lt;br /&gt;
    if student_review_num &amp;gt;= teams.size&lt;br /&gt;
      flash[:error] = 'You cannot set the number of reviews done &lt;br /&gt;
      by each student to be greater than or equal to total number of teams &lt;br /&gt;
      [or &amp;quot;participants&amp;quot; if it is an individual assignment].'&lt;br /&gt;
    end&lt;br /&gt;
    peer_review_strategy(assignment_id, teams, num_participants, &lt;br /&gt;
                         student_review_num, num_reviews_per_team, &lt;br /&gt;
                         participants, participants_hash)&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
=Test=&lt;br /&gt;
# We test delete_outstanding_reviewers refactor from the UI. Here is a video for this test. https://youtu.be/MZxOaSsm58E&lt;br /&gt;
# We use some data to test the result of old query and new query in rails console&lt;br /&gt;
 &lt;br /&gt;
  ReviewResponseMap.where(['reviewee_id = ? and reviewer_id = ? ‘,6050, 9])&lt;br /&gt;
  ReviewResponseMap.where(reviewee_id: 6050,reviewer_id: 9)&lt;br /&gt;
&lt;br /&gt;
  Assignment.where([&amp;quot;instructor_id = ? and substring(name,1,1) = ?&amp;quot;, 2, ‘TestAssign2’]).order('name')&lt;br /&gt;
  Assignment .where(instructor_id:2).where(&amp;quot;substring(name,1,1) = :letter&amp;quot;,{letter:’TestAssign2’}).order('name')&lt;br /&gt;
&lt;br /&gt;
  ReviewResponseMap.where([&amp;quot;reviewed_object_id = ? and created_at &amp;gt; ? and calibrate_to = ?&amp;quot;, 13, nil, 0])&lt;br /&gt;
  ReviewResponseMap.where(reviewed_object_id:13,calibrate_to:0).where(&amp;quot;created_at &amp;gt; :time&amp;quot;,{time:nil})&lt;br /&gt;
&lt;br /&gt;
#We write RSpec feature tests to prove that all changes are correct and the project performs well as before.&lt;br /&gt;
&lt;br /&gt;
The function of  method automatic_review_mapping is to automatically assign reviews on students in teams when instructor set either student review number or submissions review number. There is constraint that only one of the two numbers must be set value other than 0 (that is, one is 0 and other is not 0). To test the correctness  of our refactoring, we design a scenario and 4 cases of assigning reviews to students:&lt;br /&gt;
&lt;br /&gt;
Case 1. Instructor has not set both students review number and submissions review number (They are both 0). The page will show a notice.&lt;br /&gt;
&lt;br /&gt;
Case 2. Instructor set both numbers (They are both not 0). The page will show a notice.&lt;br /&gt;
&lt;br /&gt;
Case 3. Instructors set students review number. The controller will change database: create new relationship in ReviewResponseMap. For example, if assign student review number to 2, and there will be 20 peer reviews in total and need to allocate to 3 teams. So each team get 7 reviews on average and 1 team’s artifact will be reviewed 6 times.&lt;br /&gt;
&lt;br /&gt;
Case 4. Instructors set submissions review number. The controller will change database: create new relationship in ReviewResponseMap. For example, if assign submission review number to 3, and there will be 21 peer reviews in total to allocate to 10 participants. So every participants get 2 reviews. 9 among 10 participants will review 2 teams’ artifacts and 1 participant will review 3 teams’ artifacts.&lt;br /&gt;
&lt;br /&gt;
require 'rails_helper'&lt;br /&gt;
  describe &amp;quot;review mapping&amp;quot;, js: true do&lt;br /&gt;
    before(:each) do&lt;br /&gt;
      #create test data&lt;br /&gt;
    end&lt;br /&gt;
 &lt;br /&gt;
    it &amp;quot;show error when assign both 0&amp;quot; do&lt;br /&gt;
      login_as(&amp;quot;instructor6&amp;quot;)&lt;br /&gt;
      visit '/assignments/1/edit'&lt;br /&gt;
      find_link('ReviewStrategy').click&lt;br /&gt;
      select &amp;quot;Instructor-Selected&amp;quot;, from: 'assignment_form_assignment_review_assignment_strategy'&lt;br /&gt;
      fill_in 'num_reviews_per_student', with: 0&lt;br /&gt;
      choose 'num_reviews_submission'&lt;br /&gt;
      fill_in 'num_reviews_per_submission', with: 0&lt;br /&gt;
      click_button 'second_submit_tag'&lt;br /&gt;
      #click_button 'Save'&lt;br /&gt;
      expect(page).to have_content('Please choose either the number of reviews per student or the number of reviewers per team (student)')&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    it &amp;quot;show error when assign both numbers&amp;quot; do&lt;br /&gt;
      login_as(&amp;quot;instructor6&amp;quot;)&lt;br /&gt;
      visit '/assignments/1/edit'&lt;br /&gt;
      find_link('ReviewStrategy').click&lt;br /&gt;
      select &amp;quot;Instructor-Selected&amp;quot;, from: 'assignment_form_assignment_review_assignment_strategy'&lt;br /&gt;
      fill_in 'num_reviews_per_student', with: 1&lt;br /&gt;
      choose 'num_reviews_submission'&lt;br /&gt;
      fill_in 'num_reviews_per_submission', with: 1&lt;br /&gt;
      click_button 'second_submit_tag'&lt;br /&gt;
      #click_button 'Save'&lt;br /&gt;
      expect(page).to have_content('Please choose either the number of reviews per student or the number of reviewers per team (student), not both')&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    it &amp;quot;calculate reviewmapping from given review number per student&amp;quot; do&lt;br /&gt;
      login_as(&amp;quot;instructor6&amp;quot;)&lt;br /&gt;
      visit '/assignments/1/edit'&lt;br /&gt;
      find_link('ReviewStrategy').click&lt;br /&gt;
      select &amp;quot;Instructor-Selected&amp;quot;, from: 'assignment_form_assignment_review_assignment_strategy'&lt;br /&gt;
      fill_in 'num_reviews_per_student', with: 2&lt;br /&gt;
      click_button 'first_submit_tag'&lt;br /&gt;
      num = ReviewResponseMap.where(reviewee_id: @team1.id, reviewed_object_id: @assignment.id).count&lt;br /&gt;
      expect(num).to eq(7)&lt;br /&gt;
      num2 = ReviewResponseMap.where(reviewee_id: @team3.id, reviewed_object_id: @assignment.id).count&lt;br /&gt;
      expect(num2).to eq(6)&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    it &amp;quot;calculate reviewmapping from given review number per submission&amp;quot; do&lt;br /&gt;
      login_as(&amp;quot;instructor6&amp;quot;)&lt;br /&gt;
      visit '/assignments/1/edit'&lt;br /&gt;
      find_link('ReviewStrategy').click&lt;br /&gt;
      select &amp;quot;Instructor-Selected&amp;quot;, from: 'assignment_form_assignment_review_assignment_strategy'&lt;br /&gt;
      choose 'num_reviews_submission'&lt;br /&gt;
      fill_in 'num_reviews_per_submission', with: 7&lt;br /&gt;
      click_button 'second_submit_tag'&lt;br /&gt;
      #click_button 'Save'&lt;br /&gt;
      num = ReviewResponseMap.where(reviewer_id: @teamuser1.id, reviewed_object_id: @assignment.id).count&lt;br /&gt;
      expect(num).to eq(2)&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;/div&gt;</summary>
		<author><name>Jdeng8</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2016/E1641._Refactor_review_mapping_controller.rb&amp;diff=104102</id>
		<title>CSC/ECE 517 Fall 2016/E1641. Refactor review mapping controller.rb</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2016/E1641._Refactor_review_mapping_controller.rb&amp;diff=104102"/>
		<updated>2016-10-30T23:49:21Z</updated>

		<summary type="html">&lt;p&gt;Jdeng8: /* Current Implementation and Problems */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=Background=&lt;br /&gt;
&lt;br /&gt;
This controller sets up mappings between reviewer and reviewee. It handles all different types of response maps (review response map, author feedback response map, teammate review response map, meta review response map and quiz response map). The class has functionality for five different kinds of Responses: reviews, metareviews, teammate reviews, author feedback (“rejoinders”), and quizzes. &lt;br /&gt;
&lt;br /&gt;
=Current Implementation and Problems=&lt;br /&gt;
The controller has many methods and involve with other controller and views, so the code is long and complicated. Some of the methods in this controller have unreasonable name associated with their functions, some methods are too long, some methods haven't been used by any other methods or views. Our work is to refactor these problems and make the code more beautiful.&lt;br /&gt;
&lt;br /&gt;
The problems are:&lt;br /&gt;
&lt;br /&gt;
# Method ''response_report'' has some SQL - like code.  Rewrite with Active Record.&lt;br /&gt;
# Test whether method ''add_user_to_assignment'' is used. There is no way that this method should be in ReviewMappingController. Please remove this method and caller.&lt;br /&gt;
# There was a ''self-review'' feature, the method ''add_self_reviewer'', ''get_team_from_submission'' are related to this. Two views calls ''add_self_reviewer'' are &amp;quot;show_available_submissions_for_quizzes.html.erb&amp;quot; and &amp;quot;show_available_submissions.html.erb&amp;quot;. The names of views are not related to ''self_review'' feature. Plus those two views are not called anywhere. Please verify this and if so, you should delete those two views, two method and also related records (e.g. in routes.rb).&lt;br /&gt;
# Method ''delete_all_reviewers'' actually only deletes the outstanding review response maps (the ones which has been initiated, but there is no response yet). So it should better be named ''delete_outstanding_reviewers''. You can try to test this method by clicking “Assign reviewers” icon on an assignment.&lt;br /&gt;
# Method ''release_reservation'' should be renamed as'' release_mapping''. In addition, delete it if you find this method is not called anywhere.&lt;br /&gt;
# Method ''delete_mappings'' is problematic. It does not looks like a controller method. Please refactor it or delete it if you can validate that this method is not called anywhere.&lt;br /&gt;
# Method'' automatic_review_mapping_strategy'' is too long. Please refactor and test it.&lt;br /&gt;
&lt;br /&gt;
=Changes Implemented=&lt;br /&gt;
&lt;br /&gt;
# change the rails query from sql like code, like ReviewResponseMap.where(['reviewee_id = ? and reviewer_id = ? ', params[:contributor_id], reviewer.id]) to more rails quey like ReviewResponseMap.where(reviewee_id: params[:contributor_id],reviewer_id: reviewer.id)&lt;br /&gt;
# We search the function name(''add_user_to_assignment'') in the whole files, and find that this method is invoked in &amp;quot;participants_helper.rb&amp;quot;, and also being invoked in the function of ''add_reviewer'' and ''add_metareviewer'' in the controller of ''review_mapping_controller'' &lt;br /&gt;
# By searching the whole project and routes, we verify that methods ''add_self_reviewer'' and ''get_team_from_submission'' in this controller are not called by any other methods except for views &amp;quot;show_available_submissions_for_quizzes.html.erb&amp;quot; and &amp;quot;show_available_submissions.html.erb&amp;quot;. And those two views are not linked to any other views. So they are deleted from the project.&lt;br /&gt;
# We already renamed method ''delete_all_reviewers'' to ''delete_outstanding_reviewers'' and changed the corresponding button name at the corresponding view (_list_review_mappings.html.erb).&lt;br /&gt;
# By searching the whole project and routes, we verify that methods'' release_reservation'' in this controller are not used in anywhere.&lt;br /&gt;
# By searching the whole project and routes, we verify that methods ''delete_mappings'' in this controller are not used in anywhere.&lt;br /&gt;
# Method ''automatic_review_mapping_strategy'' have many long lines. We already shorten each long line to multiple lines. And also, we split this long function into three different functions.&lt;br /&gt;
&lt;br /&gt;
=Code=&lt;br /&gt;
&lt;br /&gt;
==Refactor SQL query code==&lt;br /&gt;
&lt;br /&gt;
The rails query we change in this controller:&lt;br /&gt;
&lt;br /&gt;
1. From &lt;br /&gt;
&lt;br /&gt;
  ReviewResponseMap.where(['reviewee_id = ? and reviewer_id = ? ', params[:contributor_id], reviewer.id]) &lt;br /&gt;
&lt;br /&gt;
To&lt;br /&gt;
&lt;br /&gt;
  ReviewResponseMap.where(reviewee_id: params[:contributor_id],reviewer_id: reviewer.id)&lt;br /&gt;
&lt;br /&gt;
2. From&lt;br /&gt;
&lt;br /&gt;
  MetareviewResponseMap.where(['reviewed_object_id = ? and reviewer_id = ?', mapping.map_id, reviewer.id])&lt;br /&gt;
&lt;br /&gt;
To&lt;br /&gt;
&lt;br /&gt;
  MetareviewResponseMap.where(reviewed_object_id: mapping.map_id, reviewer_id: reviewer.id)&lt;br /&gt;
&lt;br /&gt;
3. From&lt;br /&gt;
&lt;br /&gt;
                   @assignments = Assignment&lt;br /&gt;
                   .where([&amp;quot;instructor_id = ? and substring(name,1,1) = ?&amp;quot;, session[:user].id, letter])&lt;br /&gt;
                   .order('name')&lt;br /&gt;
                   .page(params[:page])&lt;br /&gt;
                   .per_page(10)&lt;br /&gt;
&lt;br /&gt;
To &lt;br /&gt;
&lt;br /&gt;
                   @assignments = Assignment&lt;br /&gt;
                   .where(instructor_id:session[:user].id)&lt;br /&gt;
                   .where(&amp;quot;substring(name,1,1) = :letter&amp;quot;,{letter:letter})&lt;br /&gt;
                   .order('name')&lt;br /&gt;
                   .page(params[:page])&lt;br /&gt;
                   .per_page(10)&lt;br /&gt;
&lt;br /&gt;
4.  From&lt;br /&gt;
&lt;br /&gt;
  ReviewResponseMap.where([&amp;quot;reviewed_object_id = ? and calibrate_to = ?&amp;quot;, assignment_id, 1])&lt;br /&gt;
&lt;br /&gt;
To &lt;br /&gt;
&lt;br /&gt;
  ReviewResponseMap.where(reviewed_object_id:assignment_id, calibrate_to: 1)&lt;br /&gt;
&lt;br /&gt;
5. From&lt;br /&gt;
&lt;br /&gt;
  ReviewResponseMap.where([&amp;quot;reviewed_object_id = ? and created_at &amp;gt; ? and calibrate_to = ?&amp;quot;, assignment_id, @@time_create_last_review_mapping_record, 0])&lt;br /&gt;
&lt;br /&gt;
To &lt;br /&gt;
&lt;br /&gt;
  ReviewResponseMap.where(reviewed_object_id:assignment_id,calibrate_to:0).where(&amp;quot;created_at &amp;gt; :time&amp;quot;,{time:@@time_create_last_review_mapping_record})&lt;br /&gt;
&lt;br /&gt;
6. From&lt;br /&gt;
&lt;br /&gt;
  AssignmentQuestionnaire.where([&amp;quot;assignment_id = ? and questionnaire_id IN (?)&amp;quot;, params[:id], @review_questionnaire_ids])&lt;br /&gt;
&lt;br /&gt;
To&lt;br /&gt;
 &lt;br /&gt;
  AssignmentQuestionnaire.where(assignment_id: params[:id],:questionnaire_id =&amp;gt; @review_questionnaire_ids)&lt;br /&gt;
&lt;br /&gt;
7. From&lt;br /&gt;
&lt;br /&gt;
  SelfReviewResponseMap.where(['reviewee_id = ? and reviewer_id = ?', team_id[0].t_id, params[:reviewer_id]])&lt;br /&gt;
&lt;br /&gt;
To &lt;br /&gt;
&lt;br /&gt;
  SelfReviewResponseMap.where(reviewee_id:team_id[0].t_id,reviewer_id:params[:reviewer_id])&lt;br /&gt;
&lt;br /&gt;
==Refactor long line method==&lt;br /&gt;
&lt;br /&gt;
  def automatic_review_mapping_strategy(assignment_id,&lt;br /&gt;
                                        participants, teams, student_review_num = 0,&lt;br /&gt;
                                        submission_review_num = 0)&lt;br /&gt;
    participants_hash = {}&lt;br /&gt;
    participants.each {|participant| participants_hash[participant.id] = 0 }&lt;br /&gt;
    # calculate reviewers for each team&lt;br /&gt;
    num_participants = participants.size&lt;br /&gt;
    if student_review_num != 0 and submission_review_num == 0&lt;br /&gt;
      num_reviews_per_team = (participants.size * student_review_num * 1.0 / teams.size).round&lt;br /&gt;
      student_review_num = student_review_num&lt;br /&gt;
      exact_num_of_review_needed = participants.size * student_review_num&lt;br /&gt;
    elsif student_review_num == 0 and submission_review_num != 0&lt;br /&gt;
      num_reviews_per_team = submission_review_num&lt;br /&gt;
      student_review_num = (teams.size * submission_review_num * 1.0 / participants.size).round&lt;br /&gt;
      exact_num_of_review_needed = teams.size * submission_review_num&lt;br /&gt;
    end&lt;br /&gt;
    execute_peer_review_strategy(assignment_id, teams, num_participants,&lt;br /&gt;
                                     student_review_num, num_reviews_per_team,&lt;br /&gt;
                                     participants, participants_hash)&lt;br /&gt;
    # after assigning peer reviews for each team,&lt;br /&gt;
    # if there are still some peer reviewers not obtain enough peer review,&lt;br /&gt;
    # just assign them to valid teams&lt;br /&gt;
    assign_reviewers_for_team(assignment_id,student_review_num,participants_hash,&lt;br /&gt;
                              exact_num_of_review_needed)&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  def assign_reviewers_for_team(assignment_id,student_review_num,participants_hash,&lt;br /&gt;
                                exact_num_of_review_needed)&lt;br /&gt;
     if ReviewResponseMap.where(reviewed_object_id:assignment_id,calibrate_to:0)&lt;br /&gt;
             .where(&amp;quot;created_at &amp;gt; :time&amp;quot;,&lt;br /&gt;
          {time:@@time_create_last_review_mapping_record}).size &amp;lt; exact_num_of_review_needed&lt;br /&gt;
      participants_with_insufficient_review_num = []&lt;br /&gt;
      participants_hash.each do |participant_id, review_num|&lt;br /&gt;
        participants_with_insufficient_review_num &amp;lt;&amp;lt; participant_id if review_num &amp;lt; student_review_num&lt;br /&gt;
      end&lt;br /&gt;
      unsorted_teams_hash = {}&lt;br /&gt;
     ReviewResponseMap.where(reviewed_object_id:assignment_id,&lt;br /&gt;
                  calibrate_to:0).each do |response_map|&lt;br /&gt;
        if unsorted_teams_hash.key? response_map.reviewee_id&lt;br /&gt;
          unsorted_teams_hash[response_map.reviewee_id] += 1&lt;br /&gt;
        else&lt;br /&gt;
          unsorted_teams_hash[response_map.reviewee_id] = 1&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
      teams_hash = unsorted_teams_hash.sort_by {|_, v| v }.to_h&lt;br /&gt;
      participants_with_insufficient_review_num.each do |participant_id|&lt;br /&gt;
        teams_hash.each do |team_id, _num_review_received|&lt;br /&gt;
          next if TeamsUser.exists?(team_id: team_id, &lt;br /&gt;
                                    user_id: Participant.find(participant_id).user_id)&lt;br /&gt;
          ReviewResponseMap.where(reviewee_id: team_id, reviewer_id: participant_id, &lt;br /&gt;
                                  reviewed_object_id: assignment_id).first_or_create&lt;br /&gt;
          teams_hash[team_id] += 1&lt;br /&gt;
          teams_hash = teams_hash.sort_by {|_, v| v }.to_h&lt;br /&gt;
          break&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
    @@time_create_last_review_mapping_record = ReviewResponseMap.&lt;br /&gt;
                                               where(reviewed_object_id: assignment_id).&lt;br /&gt;
                                               last.created_at&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def execute_peer_review_strategy(assignment_id, teams, num_participants, &lt;br /&gt;
                                   student_review_num, num_reviews_per_team, &lt;br /&gt;
                                   participants, participants_hash)&lt;br /&gt;
    # Exception detection: If instructor want to assign too many reviews done&lt;br /&gt;
    # by each student, there will be an error msg.&lt;br /&gt;
    if student_review_num &amp;gt;= teams.size&lt;br /&gt;
      flash[:error] = 'You cannot set the number of reviews done &lt;br /&gt;
      by each student to be greater than or equal to total number of teams &lt;br /&gt;
      [or &amp;quot;participants&amp;quot; if it is an individual assignment].'&lt;br /&gt;
    end&lt;br /&gt;
    peer_review_strategy(assignment_id, teams, num_participants, &lt;br /&gt;
                         student_review_num, num_reviews_per_team, &lt;br /&gt;
                         participants, participants_hash)&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
=Test=&lt;br /&gt;
# We test delete_outstanding_reviewers refactor from the UI. Here is a video for this test. https://youtu.be/MZxOaSsm58E&lt;br /&gt;
# We use some data to test the result of old query and new query in rails console&lt;br /&gt;
 &lt;br /&gt;
  ReviewResponseMap.where(['reviewee_id = ? and reviewer_id = ? ‘,6050, 9])&lt;br /&gt;
  ReviewResponseMap.where(reviewee_id: 6050,reviewer_id: 9)&lt;br /&gt;
&lt;br /&gt;
  Assignment.where([&amp;quot;instructor_id = ? and substring(name,1,1) = ?&amp;quot;, 2, ‘TestAssign2’]).order('name')&lt;br /&gt;
  Assignment .where(instructor_id:2).where(&amp;quot;substring(name,1,1) = :letter&amp;quot;,{letter:’TestAssign2’}).order('name')&lt;br /&gt;
&lt;br /&gt;
  ReviewResponseMap.where([&amp;quot;reviewed_object_id = ? and created_at &amp;gt; ? and calibrate_to = ?&amp;quot;, 13, nil, 0])&lt;br /&gt;
  ReviewResponseMap.where(reviewed_object_id:13,calibrate_to:0).where(&amp;quot;created_at &amp;gt; :time&amp;quot;,{time:nil})&lt;br /&gt;
&lt;br /&gt;
#We write RSpec feature tests to prove that all changes are correct and the project performs well as before.&lt;br /&gt;
&lt;br /&gt;
The function of  method automatic_review_mapping is to automatically assign reviews on students in teams when instructor set either student review number or submissions review number. There is constraint that only one of the two numbers must be set value other than 0 (that is, one is 0 and other is not 0). To test the correctness  of our refactoring, we design a scenario and 4 cases of assigning reviews to students:&lt;br /&gt;
&lt;br /&gt;
Case 1. Instructor has not set both students review number and submissions review number (They are both 0). The page will show a notice.&lt;br /&gt;
&lt;br /&gt;
Case 2. Instructor set both numbers (They are both not 0). The page will show a notice.&lt;br /&gt;
&lt;br /&gt;
Case 3. Instructors set students review number. The controller will change database: create new relationship in ReviewResponseMap. For example, if assign student review number to 2, and there will be 20 peer reviews in total and need to allocate to 3 teams. So each team get 7 reviews on average and 1 team’s artifact will be reviewed 6 times.&lt;br /&gt;
&lt;br /&gt;
Case 4. Instructors set submissions review number. The controller will change database: create new relationship in ReviewResponseMap. For example, if assign submission review number to 3, and there will be 21 peer reviews in total to allocate to 10 participants. So every participants get 2 reviews. 9 among 10 participants will review 2 teams’ artifacts and 1 participant will review 3 teams’ artifacts.&lt;br /&gt;
&lt;br /&gt;
require 'rails_helper'&lt;br /&gt;
  describe &amp;quot;review mapping&amp;quot;, js: true do&lt;br /&gt;
    before(:each) do&lt;br /&gt;
      #create test data&lt;br /&gt;
    end&lt;br /&gt;
 &lt;br /&gt;
    it &amp;quot;show error when assign both 0&amp;quot; do&lt;br /&gt;
      login_as(&amp;quot;instructor6&amp;quot;)&lt;br /&gt;
      visit '/assignments/1/edit'&lt;br /&gt;
      find_link('ReviewStrategy').click&lt;br /&gt;
      select &amp;quot;Instructor-Selected&amp;quot;, from: 'assignment_form_assignment_review_assignment_strategy'&lt;br /&gt;
      fill_in 'num_reviews_per_student', with: 0&lt;br /&gt;
      choose 'num_reviews_submission'&lt;br /&gt;
      fill_in 'num_reviews_per_submission', with: 0&lt;br /&gt;
      click_button 'second_submit_tag'&lt;br /&gt;
      #click_button 'Save'&lt;br /&gt;
      expect(page).to have_content('Please choose either the number of reviews per student or the number of reviewers per team (student)')&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    it &amp;quot;show error when assign both numbers&amp;quot; do&lt;br /&gt;
      login_as(&amp;quot;instructor6&amp;quot;)&lt;br /&gt;
      visit '/assignments/1/edit'&lt;br /&gt;
      find_link('ReviewStrategy').click&lt;br /&gt;
      select &amp;quot;Instructor-Selected&amp;quot;, from: 'assignment_form_assignment_review_assignment_strategy'&lt;br /&gt;
      fill_in 'num_reviews_per_student', with: 1&lt;br /&gt;
      choose 'num_reviews_submission'&lt;br /&gt;
      fill_in 'num_reviews_per_submission', with: 1&lt;br /&gt;
      click_button 'second_submit_tag'&lt;br /&gt;
      #click_button 'Save'&lt;br /&gt;
      expect(page).to have_content('Please choose either the number of reviews per student or the number of reviewers per team (student), not both')&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    it &amp;quot;calculate reviewmapping from given review number per student&amp;quot; do&lt;br /&gt;
      login_as(&amp;quot;instructor6&amp;quot;)&lt;br /&gt;
      visit '/assignments/1/edit'&lt;br /&gt;
      find_link('ReviewStrategy').click&lt;br /&gt;
      select &amp;quot;Instructor-Selected&amp;quot;, from: 'assignment_form_assignment_review_assignment_strategy'&lt;br /&gt;
      fill_in 'num_reviews_per_student', with: 2&lt;br /&gt;
      click_button 'first_submit_tag'&lt;br /&gt;
      num = ReviewResponseMap.where(reviewee_id: @team1.id, reviewed_object_id: @assignment.id).count&lt;br /&gt;
      expect(num).to eq(7)&lt;br /&gt;
      num2 = ReviewResponseMap.where(reviewee_id: @team3.id, reviewed_object_id: @assignment.id).count&lt;br /&gt;
      expect(num2).to eq(6)&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    it &amp;quot;calculate reviewmapping from given review number per submission&amp;quot; do&lt;br /&gt;
      login_as(&amp;quot;instructor6&amp;quot;)&lt;br /&gt;
      visit '/assignments/1/edit'&lt;br /&gt;
      find_link('ReviewStrategy').click&lt;br /&gt;
      select &amp;quot;Instructor-Selected&amp;quot;, from: 'assignment_form_assignment_review_assignment_strategy'&lt;br /&gt;
      choose 'num_reviews_submission'&lt;br /&gt;
      fill_in 'num_reviews_per_submission', with: 7&lt;br /&gt;
      click_button 'second_submit_tag'&lt;br /&gt;
      #click_button 'Save'&lt;br /&gt;
      num = ReviewResponseMap.where(reviewer_id: @teamuser1.id, reviewed_object_id: @assignment.id).count&lt;br /&gt;
      expect(num).to eq(2)&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;/div&gt;</summary>
		<author><name>Jdeng8</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2016/E1641._Refactor_review_mapping_controller.rb&amp;diff=104100</id>
		<title>CSC/ECE 517 Fall 2016/E1641. Refactor review mapping controller.rb</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2016/E1641._Refactor_review_mapping_controller.rb&amp;diff=104100"/>
		<updated>2016-10-30T23:38:55Z</updated>

		<summary type="html">&lt;p&gt;Jdeng8: /* Test */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=Background=&lt;br /&gt;
&lt;br /&gt;
This controller sets up mappings between reviewer and reviewee. It handles all different types of response maps (review response map, author feedback response map, teammate review response map, meta review response map and quiz response map). The class has functionality for five different kinds of Responses: reviews, metareviews, teammate reviews, author feedback (“rejoinders”), and quizzes. &lt;br /&gt;
&lt;br /&gt;
=Current Implementation and Problems=&lt;br /&gt;
&lt;br /&gt;
# Method ''response_report'' has some SQL - like code.  Rewrite with Active Record.&lt;br /&gt;
# Test whether method ''add_user_to_assignment'' is used. There is no way that this method should be in ReviewMappingController. Please remove this method and caller.&lt;br /&gt;
# There was a ''self-review'' feature, the method ''add_self_reviewer'', ''get_team_from_submission'' are related to this. Two views calls ''add_self_reviewer'' are &amp;quot;show_available_submissions_for_quizzes.html.erb&amp;quot; and &amp;quot;show_available_submissions.html.erb&amp;quot;. The names of views are not related to ''self_review'' feature. Plus those two views are not called anywhere. Please verify this and if so, you should delete those two views, two method and also related records (e.g. in routes.rb).&lt;br /&gt;
# Method ''delete_all_reviewers'' actually only deletes the outstanding review response maps (the ones which has been initiated, but there is no response yet). So it should better be named ''delete_outstanding_reviewers''. You can try to test this method by clicking “Assign reviewers” icon on an assignment.&lt;br /&gt;
# Method ''release_reservation'' should be renamed as'' release_mapping''. In addition, delete it if you find this method is not called anywhere.&lt;br /&gt;
# Method ''delete_mappings'' is problematic. It does not looks like a controller method. Please refactor it or delete it if you can validate that this method is not called anywhere.&lt;br /&gt;
# Method'' automatic_review_mapping_strategy'' is too long. Please refactor and test it.&lt;br /&gt;
&lt;br /&gt;
=Changes Implemented=&lt;br /&gt;
&lt;br /&gt;
# change the rails query from sql like code, like ReviewResponseMap.where(['reviewee_id = ? and reviewer_id = ? ', params[:contributor_id], reviewer.id]) to more rails quey like ReviewResponseMap.where(reviewee_id: params[:contributor_id],reviewer_id: reviewer.id)&lt;br /&gt;
# We search the function name(''add_user_to_assignment'') in the whole files, and find that this method is invoked in &amp;quot;participants_helper.rb&amp;quot;, and also being invoked in the function of ''add_reviewer'' and ''add_metareviewer'' in the controller of ''review_mapping_controller'' &lt;br /&gt;
# By searching the whole project and routes, we verify that methods ''add_self_reviewer'' and ''get_team_from_submission'' in this controller are not called by any other methods except for views &amp;quot;show_available_submissions_for_quizzes.html.erb&amp;quot; and &amp;quot;show_available_submissions.html.erb&amp;quot;. And those two views are not linked to any other views. So they are deleted from the project.&lt;br /&gt;
# We already renamed method ''delete_all_reviewers'' to ''delete_outstanding_reviewers'' and changed the corresponding button name at the corresponding view (_list_review_mappings.html.erb).&lt;br /&gt;
# By searching the whole project and routes, we verify that methods'' release_reservation'' in this controller are not used in anywhere.&lt;br /&gt;
# By searching the whole project and routes, we verify that methods ''delete_mappings'' in this controller are not used in anywhere.&lt;br /&gt;
# Method ''automatic_review_mapping_strategy'' have many long lines. We already shorten each long line to multiple lines. And also, we split this long function into three different functions.&lt;br /&gt;
&lt;br /&gt;
=Code=&lt;br /&gt;
&lt;br /&gt;
==Refactor SQL query code==&lt;br /&gt;
&lt;br /&gt;
The rails query we change in this controller:&lt;br /&gt;
&lt;br /&gt;
1. From &lt;br /&gt;
&lt;br /&gt;
  ReviewResponseMap.where(['reviewee_id = ? and reviewer_id = ? ', params[:contributor_id], reviewer.id]) &lt;br /&gt;
&lt;br /&gt;
To&lt;br /&gt;
&lt;br /&gt;
  ReviewResponseMap.where(reviewee_id: params[:contributor_id],reviewer_id: reviewer.id)&lt;br /&gt;
&lt;br /&gt;
2. From&lt;br /&gt;
&lt;br /&gt;
  MetareviewResponseMap.where(['reviewed_object_id = ? and reviewer_id = ?', mapping.map_id, reviewer.id])&lt;br /&gt;
&lt;br /&gt;
To&lt;br /&gt;
&lt;br /&gt;
  MetareviewResponseMap.where(reviewed_object_id: mapping.map_id, reviewer_id: reviewer.id)&lt;br /&gt;
&lt;br /&gt;
3. From&lt;br /&gt;
&lt;br /&gt;
                   @assignments = Assignment&lt;br /&gt;
                   .where([&amp;quot;instructor_id = ? and substring(name,1,1) = ?&amp;quot;, session[:user].id, letter])&lt;br /&gt;
                   .order('name')&lt;br /&gt;
                   .page(params[:page])&lt;br /&gt;
                   .per_page(10)&lt;br /&gt;
&lt;br /&gt;
To &lt;br /&gt;
&lt;br /&gt;
                   @assignments = Assignment&lt;br /&gt;
                   .where(instructor_id:session[:user].id)&lt;br /&gt;
                   .where(&amp;quot;substring(name,1,1) = :letter&amp;quot;,{letter:letter})&lt;br /&gt;
                   .order('name')&lt;br /&gt;
                   .page(params[:page])&lt;br /&gt;
                   .per_page(10)&lt;br /&gt;
&lt;br /&gt;
4.  From&lt;br /&gt;
&lt;br /&gt;
  ReviewResponseMap.where([&amp;quot;reviewed_object_id = ? and calibrate_to = ?&amp;quot;, assignment_id, 1])&lt;br /&gt;
&lt;br /&gt;
To &lt;br /&gt;
&lt;br /&gt;
  ReviewResponseMap.where(reviewed_object_id:assignment_id, calibrate_to: 1)&lt;br /&gt;
&lt;br /&gt;
5. From&lt;br /&gt;
&lt;br /&gt;
  ReviewResponseMap.where([&amp;quot;reviewed_object_id = ? and created_at &amp;gt; ? and calibrate_to = ?&amp;quot;, assignment_id, @@time_create_last_review_mapping_record, 0])&lt;br /&gt;
&lt;br /&gt;
To &lt;br /&gt;
&lt;br /&gt;
  ReviewResponseMap.where(reviewed_object_id:assignment_id,calibrate_to:0).where(&amp;quot;created_at &amp;gt; :time&amp;quot;,{time:@@time_create_last_review_mapping_record})&lt;br /&gt;
&lt;br /&gt;
6. From&lt;br /&gt;
&lt;br /&gt;
  AssignmentQuestionnaire.where([&amp;quot;assignment_id = ? and questionnaire_id IN (?)&amp;quot;, params[:id], @review_questionnaire_ids])&lt;br /&gt;
&lt;br /&gt;
To&lt;br /&gt;
 &lt;br /&gt;
  AssignmentQuestionnaire.where(assignment_id: params[:id],:questionnaire_id =&amp;gt; @review_questionnaire_ids)&lt;br /&gt;
&lt;br /&gt;
7. From&lt;br /&gt;
&lt;br /&gt;
  SelfReviewResponseMap.where(['reviewee_id = ? and reviewer_id = ?', team_id[0].t_id, params[:reviewer_id]])&lt;br /&gt;
&lt;br /&gt;
To &lt;br /&gt;
&lt;br /&gt;
  SelfReviewResponseMap.where(reviewee_id:team_id[0].t_id,reviewer_id:params[:reviewer_id])&lt;br /&gt;
&lt;br /&gt;
==Refactor long line method==&lt;br /&gt;
&lt;br /&gt;
  def automatic_review_mapping_strategy(assignment_id,&lt;br /&gt;
                                        participants, teams, student_review_num = 0,&lt;br /&gt;
                                        submission_review_num = 0)&lt;br /&gt;
    participants_hash = {}&lt;br /&gt;
    participants.each {|participant| participants_hash[participant.id] = 0 }&lt;br /&gt;
    # calculate reviewers for each team&lt;br /&gt;
    num_participants = participants.size&lt;br /&gt;
    if student_review_num != 0 and submission_review_num == 0&lt;br /&gt;
      num_reviews_per_team = (participants.size * student_review_num * 1.0 / teams.size).round&lt;br /&gt;
      student_review_num = student_review_num&lt;br /&gt;
      exact_num_of_review_needed = participants.size * student_review_num&lt;br /&gt;
    elsif student_review_num == 0 and submission_review_num != 0&lt;br /&gt;
      num_reviews_per_team = submission_review_num&lt;br /&gt;
      student_review_num = (teams.size * submission_review_num * 1.0 / participants.size).round&lt;br /&gt;
      exact_num_of_review_needed = teams.size * submission_review_num&lt;br /&gt;
    end&lt;br /&gt;
    execute_peer_review_strategy(assignment_id, teams, num_participants,&lt;br /&gt;
                                     student_review_num, num_reviews_per_team,&lt;br /&gt;
                                     participants, participants_hash)&lt;br /&gt;
    # after assigning peer reviews for each team,&lt;br /&gt;
    # if there are still some peer reviewers not obtain enough peer review,&lt;br /&gt;
    # just assign them to valid teams&lt;br /&gt;
    assign_reviewers_for_team(assignment_id,student_review_num,participants_hash,&lt;br /&gt;
                              exact_num_of_review_needed)&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  def assign_reviewers_for_team(assignment_id,student_review_num,participants_hash,&lt;br /&gt;
                                exact_num_of_review_needed)&lt;br /&gt;
     if ReviewResponseMap.where(reviewed_object_id:assignment_id,calibrate_to:0)&lt;br /&gt;
             .where(&amp;quot;created_at &amp;gt; :time&amp;quot;,&lt;br /&gt;
          {time:@@time_create_last_review_mapping_record}).size &amp;lt; exact_num_of_review_needed&lt;br /&gt;
      participants_with_insufficient_review_num = []&lt;br /&gt;
      participants_hash.each do |participant_id, review_num|&lt;br /&gt;
        participants_with_insufficient_review_num &amp;lt;&amp;lt; participant_id if review_num &amp;lt; student_review_num&lt;br /&gt;
      end&lt;br /&gt;
      unsorted_teams_hash = {}&lt;br /&gt;
     ReviewResponseMap.where(reviewed_object_id:assignment_id,&lt;br /&gt;
                  calibrate_to:0).each do |response_map|&lt;br /&gt;
        if unsorted_teams_hash.key? response_map.reviewee_id&lt;br /&gt;
          unsorted_teams_hash[response_map.reviewee_id] += 1&lt;br /&gt;
        else&lt;br /&gt;
          unsorted_teams_hash[response_map.reviewee_id] = 1&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
      teams_hash = unsorted_teams_hash.sort_by {|_, v| v }.to_h&lt;br /&gt;
      participants_with_insufficient_review_num.each do |participant_id|&lt;br /&gt;
        teams_hash.each do |team_id, _num_review_received|&lt;br /&gt;
          next if TeamsUser.exists?(team_id: team_id, &lt;br /&gt;
                                    user_id: Participant.find(participant_id).user_id)&lt;br /&gt;
          ReviewResponseMap.where(reviewee_id: team_id, reviewer_id: participant_id, &lt;br /&gt;
                                  reviewed_object_id: assignment_id).first_or_create&lt;br /&gt;
          teams_hash[team_id] += 1&lt;br /&gt;
          teams_hash = teams_hash.sort_by {|_, v| v }.to_h&lt;br /&gt;
          break&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
    @@time_create_last_review_mapping_record = ReviewResponseMap.&lt;br /&gt;
                                               where(reviewed_object_id: assignment_id).&lt;br /&gt;
                                               last.created_at&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def execute_peer_review_strategy(assignment_id, teams, num_participants, &lt;br /&gt;
                                   student_review_num, num_reviews_per_team, &lt;br /&gt;
                                   participants, participants_hash)&lt;br /&gt;
    # Exception detection: If instructor want to assign too many reviews done&lt;br /&gt;
    # by each student, there will be an error msg.&lt;br /&gt;
    if student_review_num &amp;gt;= teams.size&lt;br /&gt;
      flash[:error] = 'You cannot set the number of reviews done &lt;br /&gt;
      by each student to be greater than or equal to total number of teams &lt;br /&gt;
      [or &amp;quot;participants&amp;quot; if it is an individual assignment].'&lt;br /&gt;
    end&lt;br /&gt;
    peer_review_strategy(assignment_id, teams, num_participants, &lt;br /&gt;
                         student_review_num, num_reviews_per_team, &lt;br /&gt;
                         participants, participants_hash)&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
=Test=&lt;br /&gt;
# We test delete_outstanding_reviewers refactor from the UI. Here is a video for this test. https://youtu.be/MZxOaSsm58E&lt;br /&gt;
# We use some data to test the result of old query and new query in rails console&lt;br /&gt;
 &lt;br /&gt;
  ReviewResponseMap.where(['reviewee_id = ? and reviewer_id = ? ‘,6050, 9])&lt;br /&gt;
  ReviewResponseMap.where(reviewee_id: 6050,reviewer_id: 9)&lt;br /&gt;
&lt;br /&gt;
  Assignment.where([&amp;quot;instructor_id = ? and substring(name,1,1) = ?&amp;quot;, 2, ‘TestAssign2’]).order('name')&lt;br /&gt;
  Assignment .where(instructor_id:2).where(&amp;quot;substring(name,1,1) = :letter&amp;quot;,{letter:’TestAssign2’}).order('name')&lt;br /&gt;
&lt;br /&gt;
  ReviewResponseMap.where([&amp;quot;reviewed_object_id = ? and created_at &amp;gt; ? and calibrate_to = ?&amp;quot;, 13, nil, 0])&lt;br /&gt;
  ReviewResponseMap.where(reviewed_object_id:13,calibrate_to:0).where(&amp;quot;created_at &amp;gt; :time&amp;quot;,{time:nil})&lt;br /&gt;
&lt;br /&gt;
#We write RSpec feature tests to prove that all changes are correct and the project performs well as before.&lt;br /&gt;
&lt;br /&gt;
The function of  method automatic_review_mapping is to automatically assign reviews on students in teams when instructor set either student review number or submissions review number. There is constraint that only one of the two numbers must be set value other than 0 (that is, one is 0 and other is not 0). To test the correctness  of our refactoring, we design a scenario and 4 cases of assigning reviews to students:&lt;br /&gt;
&lt;br /&gt;
Case 1. Instructor has not set both students review number and submissions review number (They are both 0). The page will show a notice.&lt;br /&gt;
&lt;br /&gt;
Case 2. Instructor set both numbers (They are both not 0). The page will show a notice.&lt;br /&gt;
&lt;br /&gt;
Case 3. Instructors set students review number. The controller will change database: create new relationship in ReviewResponseMap. For example, if assign student review number to 2, and there will be 20 peer reviews in total and need to allocate to 3 teams. So each team get 7 reviews on average and 1 team’s artifact will be reviewed 6 times.&lt;br /&gt;
&lt;br /&gt;
Case 4. Instructors set submissions review number. The controller will change database: create new relationship in ReviewResponseMap. For example, if assign submission review number to 3, and there will be 21 peer reviews in total to allocate to 10 participants. So every participants get 2 reviews. 9 among 10 participants will review 2 teams’ artifacts and 1 participant will review 3 teams’ artifacts.&lt;br /&gt;
&lt;br /&gt;
require 'rails_helper'&lt;br /&gt;
  describe &amp;quot;review mapping&amp;quot;, js: true do&lt;br /&gt;
    before(:each) do&lt;br /&gt;
      #create test data&lt;br /&gt;
    end&lt;br /&gt;
 &lt;br /&gt;
    it &amp;quot;show error when assign both 0&amp;quot; do&lt;br /&gt;
      login_as(&amp;quot;instructor6&amp;quot;)&lt;br /&gt;
      visit '/assignments/1/edit'&lt;br /&gt;
      find_link('ReviewStrategy').click&lt;br /&gt;
      select &amp;quot;Instructor-Selected&amp;quot;, from: 'assignment_form_assignment_review_assignment_strategy'&lt;br /&gt;
      fill_in 'num_reviews_per_student', with: 0&lt;br /&gt;
      choose 'num_reviews_submission'&lt;br /&gt;
      fill_in 'num_reviews_per_submission', with: 0&lt;br /&gt;
      click_button 'second_submit_tag'&lt;br /&gt;
      #click_button 'Save'&lt;br /&gt;
      expect(page).to have_content('Please choose either the number of reviews per student or the number of reviewers per team (student)')&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    it &amp;quot;show error when assign both numbers&amp;quot; do&lt;br /&gt;
      login_as(&amp;quot;instructor6&amp;quot;)&lt;br /&gt;
      visit '/assignments/1/edit'&lt;br /&gt;
      find_link('ReviewStrategy').click&lt;br /&gt;
      select &amp;quot;Instructor-Selected&amp;quot;, from: 'assignment_form_assignment_review_assignment_strategy'&lt;br /&gt;
      fill_in 'num_reviews_per_student', with: 1&lt;br /&gt;
      choose 'num_reviews_submission'&lt;br /&gt;
      fill_in 'num_reviews_per_submission', with: 1&lt;br /&gt;
      click_button 'second_submit_tag'&lt;br /&gt;
      #click_button 'Save'&lt;br /&gt;
      expect(page).to have_content('Please choose either the number of reviews per student or the number of reviewers per team (student), not both')&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    it &amp;quot;calculate reviewmapping from given review number per student&amp;quot; do&lt;br /&gt;
      login_as(&amp;quot;instructor6&amp;quot;)&lt;br /&gt;
      visit '/assignments/1/edit'&lt;br /&gt;
      find_link('ReviewStrategy').click&lt;br /&gt;
      select &amp;quot;Instructor-Selected&amp;quot;, from: 'assignment_form_assignment_review_assignment_strategy'&lt;br /&gt;
      fill_in 'num_reviews_per_student', with: 2&lt;br /&gt;
      click_button 'first_submit_tag'&lt;br /&gt;
      num = ReviewResponseMap.where(reviewee_id: @team1.id, reviewed_object_id: @assignment.id).count&lt;br /&gt;
      expect(num).to eq(7)&lt;br /&gt;
      num2 = ReviewResponseMap.where(reviewee_id: @team3.id, reviewed_object_id: @assignment.id).count&lt;br /&gt;
      expect(num2).to eq(6)&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    it &amp;quot;calculate reviewmapping from given review number per submission&amp;quot; do&lt;br /&gt;
      login_as(&amp;quot;instructor6&amp;quot;)&lt;br /&gt;
      visit '/assignments/1/edit'&lt;br /&gt;
      find_link('ReviewStrategy').click&lt;br /&gt;
      select &amp;quot;Instructor-Selected&amp;quot;, from: 'assignment_form_assignment_review_assignment_strategy'&lt;br /&gt;
      choose 'num_reviews_submission'&lt;br /&gt;
      fill_in 'num_reviews_per_submission', with: 7&lt;br /&gt;
      click_button 'second_submit_tag'&lt;br /&gt;
      #click_button 'Save'&lt;br /&gt;
      num = ReviewResponseMap.where(reviewer_id: @teamuser1.id, reviewed_object_id: @assignment.id).count&lt;br /&gt;
      expect(num).to eq(2)&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;/div&gt;</summary>
		<author><name>Jdeng8</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2016/E1641._Refactor_review_mapping_controller.rb&amp;diff=103948</id>
		<title>CSC/ECE 517 Fall 2016/E1641. Refactor review mapping controller.rb</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2016/E1641._Refactor_review_mapping_controller.rb&amp;diff=103948"/>
		<updated>2016-10-29T05:46:04Z</updated>

		<summary type="html">&lt;p&gt;Jdeng8: /* Current Implementation and Problems */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=Background=&lt;br /&gt;
&lt;br /&gt;
This controller sets up mappings between reviewer and reviewee. It handles all different types of response maps (review response map, author feedback response map, teammate review response map, meta review response map and quiz response map). The class has functionality for five different kinds of Responses: reviews, metareviews, teammate reviews, author feedback (“rejoinders”), and quizzes. &lt;br /&gt;
&lt;br /&gt;
=Current Implementation and Problems=&lt;br /&gt;
&lt;br /&gt;
# Method ''response_report'' has some SQL - like code.  Rewrite with Active Record.&lt;br /&gt;
# Test whether method ''add_user_to_assignment'' is used. There is no way that this method should be in ReviewMappingController. Please remove this method and caller.&lt;br /&gt;
# There was a ''self-review'' feature, the method ''add_self_reviewer'', ''get_team_from_submission'' are related to this. Two views calls ''add_self_reviewer'' are &amp;quot;show_available_submissions_for_quizzes.html.erb&amp;quot; and &amp;quot;show_available_submissions.html.erb&amp;quot;. The names of views are not related to ''self_review'' feature. Plus those two views are not called anywhere. Please verify this and if so, you should delete those two views, two method and also related records (e.g. in routes.rb).&lt;br /&gt;
# Method ''delete_all_reviewers'' actually only deletes the outstanding review response maps (the ones which has been initiated, but there is no response yet). So it should better be named ''delete_outstanding_reviewers''. You can try to test this method by clicking “Assign reviewers” icon on an assignment.&lt;br /&gt;
# Method ''release_reservation'' should be renamed as'' release_mapping''. In addition, delete it if you find this method is not called anywhere.&lt;br /&gt;
# Method ''delete_mappings'' is problematic. It does not looks like a controller method. Please refactor it or delete it if you can validate that this method is not called anywhere.&lt;br /&gt;
# Method'' automatic_review_mapping_strategy'' is too long. Please refactor and test it.&lt;br /&gt;
&lt;br /&gt;
=Changes Implemented=&lt;br /&gt;
&lt;br /&gt;
# change the rails query from sql like code, like ReviewResponseMap.where(['reviewee_id = ? and reviewer_id = ? ', params[:contributor_id], reviewer.id]) to more rails quey like ReviewResponseMap.where(reviewee_id: params[:contributor_id],reviewer_id: reviewer.id)&lt;br /&gt;
# We search the function name(''add_user_to_assignment'') in the whole files, and find that this method is invoked in &amp;quot;participants_helper.rb&amp;quot;, and also being invoked in the function of ''add_reviewer'' and ''add_metareviewer'' in the controller of ''review_mapping_controller'' &lt;br /&gt;
# By searching the whole project and routes, we verify that methods ''add_self_reviewer'' and ''get_team_from_submission'' in this controller are not called by any other methods except for views &amp;quot;show_available_submissions_for_quizzes.html.erb&amp;quot; and &amp;quot;show_available_submissions.html.erb&amp;quot;. And those two views are not linked to any other views. So they are deleted from the project.&lt;br /&gt;
# We already renamed method ''delete_all_reviewers'' to ''delete_outstanding_reviewers'' and changed the corresponding button name at the corresponding view (_list_review_mappings.html.erb).&lt;br /&gt;
# By searching the whole project and routes, we verify that methods'' release_reservation'' in this controller are not used in anywhere.&lt;br /&gt;
# By searching the whole project and routes, we verify that methods ''delete_mappings'' in this controller are not used in anywhere.&lt;br /&gt;
# Method ''automatic_review_mapping_strategy'' have many long lines. We already shorten each long line to multiple lines. And also, we split this long function into three different functions.&lt;br /&gt;
&lt;br /&gt;
=Code=&lt;br /&gt;
&lt;br /&gt;
==Refactor SQL query code==&lt;br /&gt;
&lt;br /&gt;
The rails query we change in this controller:&lt;br /&gt;
&lt;br /&gt;
1. From &lt;br /&gt;
&lt;br /&gt;
  ReviewResponseMap.where(['reviewee_id = ? and reviewer_id = ? ', params[:contributor_id], reviewer.id]) &lt;br /&gt;
&lt;br /&gt;
To&lt;br /&gt;
&lt;br /&gt;
  ReviewResponseMap.where(reviewee_id: params[:contributor_id],reviewer_id: reviewer.id)&lt;br /&gt;
&lt;br /&gt;
2. From&lt;br /&gt;
&lt;br /&gt;
  MetareviewResponseMap.where(['reviewed_object_id = ? and reviewer_id = ?', mapping.map_id, reviewer.id])&lt;br /&gt;
&lt;br /&gt;
To&lt;br /&gt;
&lt;br /&gt;
  MetareviewResponseMap.where(reviewed_object_id: mapping.map_id, reviewer_id: reviewer.id)&lt;br /&gt;
&lt;br /&gt;
3. From&lt;br /&gt;
&lt;br /&gt;
                   @assignments = Assignment&lt;br /&gt;
                   .where([&amp;quot;instructor_id = ? and substring(name,1,1) = ?&amp;quot;, session[:user].id, letter])&lt;br /&gt;
                   .order('name')&lt;br /&gt;
                   .page(params[:page])&lt;br /&gt;
                   .per_page(10)&lt;br /&gt;
&lt;br /&gt;
To &lt;br /&gt;
&lt;br /&gt;
                   @assignments = Assignment&lt;br /&gt;
                   .where(instructor_id:session[:user].id)&lt;br /&gt;
                   .where(&amp;quot;substring(name,1,1) = :letter&amp;quot;,{letter:letter})&lt;br /&gt;
                   .order('name')&lt;br /&gt;
                   .page(params[:page])&lt;br /&gt;
                   .per_page(10)&lt;br /&gt;
&lt;br /&gt;
4.  From&lt;br /&gt;
&lt;br /&gt;
  ReviewResponseMap.where([&amp;quot;reviewed_object_id = ? and calibrate_to = ?&amp;quot;, assignment_id, 1])&lt;br /&gt;
&lt;br /&gt;
To &lt;br /&gt;
&lt;br /&gt;
  ReviewResponseMap.where(reviewed_object_id:assignment_id, calibrate_to: 1)&lt;br /&gt;
&lt;br /&gt;
5. From&lt;br /&gt;
&lt;br /&gt;
  ReviewResponseMap.where([&amp;quot;reviewed_object_id = ? and created_at &amp;gt; ? and calibrate_to = ?&amp;quot;, assignment_id, @@time_create_last_review_mapping_record, 0])&lt;br /&gt;
&lt;br /&gt;
To &lt;br /&gt;
&lt;br /&gt;
  ReviewResponseMap.where(reviewed_object_id:assignment_id,calibrate_to:0).where(&amp;quot;created_at &amp;gt; :time&amp;quot;,{time:@@time_create_last_review_mapping_record})&lt;br /&gt;
&lt;br /&gt;
6. From&lt;br /&gt;
&lt;br /&gt;
  AssignmentQuestionnaire.where([&amp;quot;assignment_id = ? and questionnaire_id IN (?)&amp;quot;, params[:id], @review_questionnaire_ids])&lt;br /&gt;
&lt;br /&gt;
To&lt;br /&gt;
 &lt;br /&gt;
  AssignmentQuestionnaire.where(assignment_id: params[:id],:questionnaire_id =&amp;gt; @review_questionnaire_ids)&lt;br /&gt;
&lt;br /&gt;
7. From&lt;br /&gt;
&lt;br /&gt;
  SelfReviewResponseMap.where(['reviewee_id = ? and reviewer_id = ?', team_id[0].t_id, params[:reviewer_id]])&lt;br /&gt;
&lt;br /&gt;
To &lt;br /&gt;
&lt;br /&gt;
  SelfReviewResponseMap.where(reviewee_id:team_id[0].t_id,reviewer_id:params[:reviewer_id])&lt;br /&gt;
&lt;br /&gt;
==Refactor long line method==&lt;br /&gt;
&lt;br /&gt;
  def automatic_review_mapping_strategy(assignment_id,&lt;br /&gt;
                                        participants, teams, student_review_num = 0,&lt;br /&gt;
                                        submission_review_num = 0)&lt;br /&gt;
    participants_hash = {}&lt;br /&gt;
    participants.each {|participant| participants_hash[participant.id] = 0 }&lt;br /&gt;
    # calculate reviewers for each team&lt;br /&gt;
    num_participants = participants.size&lt;br /&gt;
    if student_review_num != 0 and submission_review_num == 0&lt;br /&gt;
      num_reviews_per_team = (participants.size * student_review_num * 1.0 / teams.size).round&lt;br /&gt;
      student_review_num = student_review_num&lt;br /&gt;
      exact_num_of_review_needed = participants.size * student_review_num&lt;br /&gt;
    elsif student_review_num == 0 and submission_review_num != 0&lt;br /&gt;
      num_reviews_per_team = submission_review_num&lt;br /&gt;
      student_review_num = (teams.size * submission_review_num * 1.0 / participants.size).round&lt;br /&gt;
      exact_num_of_review_needed = teams.size * submission_review_num&lt;br /&gt;
    end&lt;br /&gt;
    execute_peer_review_strategy(assignment_id, teams, num_participants,&lt;br /&gt;
                                     student_review_num, num_reviews_per_team,&lt;br /&gt;
                                     participants, participants_hash)&lt;br /&gt;
    # after assigning peer reviews for each team,&lt;br /&gt;
    # if there are still some peer reviewers not obtain enough peer review,&lt;br /&gt;
    # just assign them to valid teams&lt;br /&gt;
    assign_reviewers_for_team(assignment_id,student_review_num,participants_hash,&lt;br /&gt;
                              exact_num_of_review_needed)&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  def assign_reviewers_for_team(assignment_id,student_review_num,participants_hash,&lt;br /&gt;
                                exact_num_of_review_needed)&lt;br /&gt;
    if ReviewResponseMap.where([&amp;quot;reviewed_object_id = ? and created_at &amp;gt; ? and calibrate_to = ?&amp;quot;, &lt;br /&gt;
                                assignment_id, &lt;br /&gt;
                                @@time_create_last_review_mapping_record, 0]).size &amp;lt; exact_num_of_review_needed&lt;br /&gt;
      participants_with_insufficient_review_num = []&lt;br /&gt;
      participants_hash.each do |participant_id, review_num|&lt;br /&gt;
        participants_with_insufficient_review_num &amp;lt;&amp;lt; participant_id if review_num &amp;lt; student_review_num&lt;br /&gt;
      end&lt;br /&gt;
      unsorted_teams_hash = {}&lt;br /&gt;
      ReviewResponseMap.where([&amp;quot;reviewed_object_id = ? and calibrate_to = ?&amp;quot;, &lt;br /&gt;
                               assignment_id, 0]).each do |response_map|&lt;br /&gt;
        if unsorted_teams_hash.key? response_map.reviewee_id&lt;br /&gt;
          unsorted_teams_hash[response_map.reviewee_id] += 1&lt;br /&gt;
        else&lt;br /&gt;
          unsorted_teams_hash[response_map.reviewee_id] = 1&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
      teams_hash = unsorted_teams_hash.sort_by {|_, v| v }.to_h&lt;br /&gt;
      participants_with_insufficient_review_num.each do |participant_id|&lt;br /&gt;
        teams_hash.each do |team_id, _num_review_received|&lt;br /&gt;
          next if TeamsUser.exists?(team_id: team_id, &lt;br /&gt;
                                    user_id: Participant.find(participant_id).user_id)&lt;br /&gt;
          ReviewResponseMap.where(reviewee_id: team_id, reviewer_id: participant_id, &lt;br /&gt;
                                  reviewed_object_id: assignment_id).first_or_create&lt;br /&gt;
          teams_hash[team_id] += 1&lt;br /&gt;
          teams_hash = teams_hash.sort_by {|_, v| v }.to_h&lt;br /&gt;
          break&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
    @@time_create_last_review_mapping_record = ReviewResponseMap.&lt;br /&gt;
                                               where(reviewed_object_id: assignment_id).&lt;br /&gt;
                                               last.created_at&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def execute_peer_review_strategy(assignment_id, teams, num_participants, &lt;br /&gt;
                                   student_review_num, num_reviews_per_team, &lt;br /&gt;
                                   participants, participants_hash)&lt;br /&gt;
    # Exception detection: If instructor want to assign too many reviews done&lt;br /&gt;
    # by each student, there will be an error msg.&lt;br /&gt;
    if student_review_num &amp;gt;= teams.size&lt;br /&gt;
      flash[:error] = 'You cannot set the number of reviews done &lt;br /&gt;
      by each student to be greater than or equal to total number of teams &lt;br /&gt;
      [or &amp;quot;participants&amp;quot; if it is an individual assignment].'&lt;br /&gt;
    end&lt;br /&gt;
    peer_review_strategy(assignment_id, teams, num_participants, &lt;br /&gt;
                         student_review_num, num_reviews_per_team, &lt;br /&gt;
                         participants, participants_hash)&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
=Test=&lt;br /&gt;
We write RSpec feature tests to prove that all changes are correct and the project performs well as before.&lt;br /&gt;
&lt;br /&gt;
The function of  method automatic_review_mapping is to automatically assign reviews on students in teams when instructor set either student review number or submissions review number. There is constraint that only one of the two numbers must be set value other than 0 (that is, one is 0 and other is not 0). To test the correctness  of our refactoring, we design a scenario and 4 cases of assigning reviews to students:&lt;br /&gt;
&lt;br /&gt;
Case 1. Instructor has not set both students review number and submissions review number (They are both 0). The page will show a notice.&lt;br /&gt;
&lt;br /&gt;
Case 2. Instructor set both numbers (They are both not 0). The page will show a notice.&lt;br /&gt;
&lt;br /&gt;
Case 3. Instructors set students review number. The controller will change database: create new relationship in ReviewResponseMap. For example, if assign student review number to 2, and there will be 20 peer reviews in total and need to allocate to 3 teams. So each team get 7 reviews on average and 1 team’s artifact will be reviewed 6 times.&lt;br /&gt;
&lt;br /&gt;
Case 4. Instructors set submissions review number. The controller will change database: create new relationship in ReviewResponseMap. For example, if assign submission review number to 3, and there will be 21 peer reviews in total to allocate to 10 participants. So every participants get 2 reviews. 9 among 10 participants will review 2 teams’ artifacts and 1 participant will review 3 teams’ artifacts.&lt;br /&gt;
&lt;br /&gt;
require 'rails_helper'&lt;br /&gt;
  describe &amp;quot;review mapping&amp;quot;, js: true do&lt;br /&gt;
    before(:each) do&lt;br /&gt;
      #create test data&lt;br /&gt;
    end&lt;br /&gt;
 &lt;br /&gt;
    it &amp;quot;show error when assign both 0&amp;quot; do&lt;br /&gt;
      login_as(&amp;quot;instructor6&amp;quot;)&lt;br /&gt;
      visit '/assignments/1/edit'&lt;br /&gt;
      find_link('ReviewStrategy').click&lt;br /&gt;
      select &amp;quot;Instructor-Selected&amp;quot;, from: 'assignment_form_assignment_review_assignment_strategy'&lt;br /&gt;
      fill_in 'num_reviews_per_student', with: 0&lt;br /&gt;
      choose 'num_reviews_submission'&lt;br /&gt;
      fill_in 'num_reviews_per_submission', with: 0&lt;br /&gt;
      click_button 'second_submit_tag'&lt;br /&gt;
      #click_button 'Save'&lt;br /&gt;
      expect(page).to have_content('Please choose either the number of reviews per student or the number of reviewers per team (student)')&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    it &amp;quot;show error when assign both numbers&amp;quot; do&lt;br /&gt;
      login_as(&amp;quot;instructor6&amp;quot;)&lt;br /&gt;
      visit '/assignments/1/edit'&lt;br /&gt;
      find_link('ReviewStrategy').click&lt;br /&gt;
      select &amp;quot;Instructor-Selected&amp;quot;, from: 'assignment_form_assignment_review_assignment_strategy'&lt;br /&gt;
      fill_in 'num_reviews_per_student', with: 1&lt;br /&gt;
      choose 'num_reviews_submission'&lt;br /&gt;
      fill_in 'num_reviews_per_submission', with: 1&lt;br /&gt;
      click_button 'second_submit_tag'&lt;br /&gt;
      #click_button 'Save'&lt;br /&gt;
      expect(page).to have_content('Please choose either the number of reviews per student or the number of reviewers per team (student), not both')&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    it &amp;quot;calculate reviewmapping from given review number per student&amp;quot; do&lt;br /&gt;
      login_as(&amp;quot;instructor6&amp;quot;)&lt;br /&gt;
      visit '/assignments/1/edit'&lt;br /&gt;
      find_link('ReviewStrategy').click&lt;br /&gt;
      select &amp;quot;Instructor-Selected&amp;quot;, from: 'assignment_form_assignment_review_assignment_strategy'&lt;br /&gt;
      fill_in 'num_reviews_per_student', with: 2&lt;br /&gt;
      click_button 'first_submit_tag'&lt;br /&gt;
      num = ReviewResponseMap.where(reviewee_id: @team1.id, reviewed_object_id: @assignment.id).count&lt;br /&gt;
      expect(num).to eq(7)&lt;br /&gt;
      num2 = ReviewResponseMap.where(reviewee_id: @team3.id, reviewed_object_id: @assignment.id).count&lt;br /&gt;
      expect(num2).to eq(6)&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    it &amp;quot;calculate reviewmapping from given review number per submission&amp;quot; do&lt;br /&gt;
      login_as(&amp;quot;instructor6&amp;quot;)&lt;br /&gt;
      visit '/assignments/1/edit'&lt;br /&gt;
      find_link('ReviewStrategy').click&lt;br /&gt;
      select &amp;quot;Instructor-Selected&amp;quot;, from: 'assignment_form_assignment_review_assignment_strategy'&lt;br /&gt;
      choose 'num_reviews_submission'&lt;br /&gt;
      fill_in 'num_reviews_per_submission', with: 7&lt;br /&gt;
      click_button 'second_submit_tag'&lt;br /&gt;
      #click_button 'Save'&lt;br /&gt;
      num = ReviewResponseMap.where(reviewer_id: @teamuser1.id, reviewed_object_id: @assignment.id).count&lt;br /&gt;
      expect(num).to eq(2)&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;/div&gt;</summary>
		<author><name>Jdeng8</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2016/E1641._Refactor_review_mapping_controller.rb&amp;diff=103946</id>
		<title>CSC/ECE 517 Fall 2016/E1641. Refactor review mapping controller.rb</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2016/E1641._Refactor_review_mapping_controller.rb&amp;diff=103946"/>
		<updated>2016-10-29T05:44:14Z</updated>

		<summary type="html">&lt;p&gt;Jdeng8: /* Current Implementation and Problems */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=Background=&lt;br /&gt;
&lt;br /&gt;
This controller sets up mappings between reviewer and reviewee. It handles all different types of response maps (review response map, author feedback response map, teammate review response map, meta review response map and quiz response map). The class has functionality for five different kinds of Responses: reviews, metareviews, teammate reviews, author feedback (“rejoinders”), and quizzes. &lt;br /&gt;
&lt;br /&gt;
=Current Implementation and Problems=&lt;br /&gt;
&lt;br /&gt;
# Method ''response_report'' has some [[SQL]] - like code.  Rewrite with Active Record.&lt;br /&gt;
# Test whether method ''add_user_to_assignment'' is used. There is no way that this method should be in ReviewMappingController. Please remove this method and caller.&lt;br /&gt;
# There was a ''self-review'' feature, the method ''add_self_reviewer'', ''get_team_from_submission'' are related to this. Two views calls ''add_self_reviewer'' are &amp;quot;show_available_submissions_for_quizzes.html.erb&amp;quot; and &amp;quot;show_available_submissions.html.erb&amp;quot;. The names of views are not related to ''self_review'' feature. Plus those two views are not called anywhere. Please verify this and if so, you should delete those two views, two method and also related records (e.g. in routes.rb).&lt;br /&gt;
# Method ''delete_all_reviewers'' actually only deletes the outstanding review response maps (the ones which has been initiated, but there is no response yet). So it should better be named ''delete_outstanding_reviewers''. You can try to test this method by clicking “Assign reviewers” icon on an assignment.&lt;br /&gt;
# Method ''release_reservation'' should be renamed as'' release_mapping''. In addition, delete it if you find this method is not called anywhere.&lt;br /&gt;
# Method ''delete_mappings'' is problematic. It does not looks like a controller method. Please refactor it or delete it if you can validate that this method is not called anywhere.&lt;br /&gt;
# Method'' automatic_review_mapping_strategy'' is too long. Please refactor and test it.&lt;br /&gt;
&lt;br /&gt;
=Changes Implemented=&lt;br /&gt;
&lt;br /&gt;
# change the rails query from sql like code, like ReviewResponseMap.where(['reviewee_id = ? and reviewer_id = ? ', params[:contributor_id], reviewer.id]) to more rails quey like ReviewResponseMap.where(reviewee_id: params[:contributor_id],reviewer_id: reviewer.id)&lt;br /&gt;
# We search the function name(''add_user_to_assignment'') in the whole files, and find that this method is invoked in &amp;quot;participants_helper.rb&amp;quot;, and also being invoked in the function of ''add_reviewer'' and ''add_metareviewer'' in the controller of ''review_mapping_controller'' &lt;br /&gt;
# By searching the whole project and routes, we verify that methods ''add_self_reviewer'' and ''get_team_from_submission'' in this controller are not called by any other methods except for views &amp;quot;show_available_submissions_for_quizzes.html.erb&amp;quot; and &amp;quot;show_available_submissions.html.erb&amp;quot;. And those two views are not linked to any other views. So they are deleted from the project.&lt;br /&gt;
# We already renamed method ''delete_all_reviewers'' to ''delete_outstanding_reviewers'' and changed the corresponding button name at the corresponding view (_list_review_mappings.html.erb).&lt;br /&gt;
# By searching the whole project and routes, we verify that methods'' release_reservation'' in this controller are not used in anywhere.&lt;br /&gt;
# By searching the whole project and routes, we verify that methods ''delete_mappings'' in this controller are not used in anywhere.&lt;br /&gt;
# Method ''automatic_review_mapping_strategy'' have many long lines. We already shorten each long line to multiple lines. And also, we split this long function into three different functions.&lt;br /&gt;
&lt;br /&gt;
=Code=&lt;br /&gt;
&lt;br /&gt;
==Refactor SQL query code==&lt;br /&gt;
&lt;br /&gt;
The rails query we change in this controller:&lt;br /&gt;
&lt;br /&gt;
1. From &lt;br /&gt;
&lt;br /&gt;
  ReviewResponseMap.where(['reviewee_id = ? and reviewer_id = ? ', params[:contributor_id], reviewer.id]) &lt;br /&gt;
&lt;br /&gt;
To&lt;br /&gt;
&lt;br /&gt;
  ReviewResponseMap.where(reviewee_id: params[:contributor_id],reviewer_id: reviewer.id)&lt;br /&gt;
&lt;br /&gt;
2. From&lt;br /&gt;
&lt;br /&gt;
  MetareviewResponseMap.where(['reviewed_object_id = ? and reviewer_id = ?', mapping.map_id, reviewer.id])&lt;br /&gt;
&lt;br /&gt;
To&lt;br /&gt;
&lt;br /&gt;
  MetareviewResponseMap.where(reviewed_object_id: mapping.map_id, reviewer_id: reviewer.id)&lt;br /&gt;
&lt;br /&gt;
3. From&lt;br /&gt;
&lt;br /&gt;
                   @assignments = Assignment&lt;br /&gt;
                   .where([&amp;quot;instructor_id = ? and substring(name,1,1) = ?&amp;quot;, session[:user].id, letter])&lt;br /&gt;
                   .order('name')&lt;br /&gt;
                   .page(params[:page])&lt;br /&gt;
                   .per_page(10)&lt;br /&gt;
&lt;br /&gt;
To &lt;br /&gt;
&lt;br /&gt;
                   @assignments = Assignment&lt;br /&gt;
                   .where(instructor_id:session[:user].id)&lt;br /&gt;
                   .where(&amp;quot;substring(name,1,1) = :letter&amp;quot;,{letter:letter})&lt;br /&gt;
                   .order('name')&lt;br /&gt;
                   .page(params[:page])&lt;br /&gt;
                   .per_page(10)&lt;br /&gt;
&lt;br /&gt;
4.  From&lt;br /&gt;
&lt;br /&gt;
  ReviewResponseMap.where([&amp;quot;reviewed_object_id = ? and calibrate_to = ?&amp;quot;, assignment_id, 1])&lt;br /&gt;
&lt;br /&gt;
To &lt;br /&gt;
&lt;br /&gt;
  ReviewResponseMap.where(reviewed_object_id:assignment_id, calibrate_to: 1)&lt;br /&gt;
&lt;br /&gt;
5. From&lt;br /&gt;
&lt;br /&gt;
  ReviewResponseMap.where([&amp;quot;reviewed_object_id = ? and created_at &amp;gt; ? and calibrate_to = ?&amp;quot;, assignment_id, @@time_create_last_review_mapping_record, 0])&lt;br /&gt;
&lt;br /&gt;
To &lt;br /&gt;
&lt;br /&gt;
  ReviewResponseMap.where(reviewed_object_id:assignment_id,calibrate_to:0).where(&amp;quot;created_at &amp;gt; :time&amp;quot;,{time:@@time_create_last_review_mapping_record})&lt;br /&gt;
&lt;br /&gt;
6. From&lt;br /&gt;
&lt;br /&gt;
  AssignmentQuestionnaire.where([&amp;quot;assignment_id = ? and questionnaire_id IN (?)&amp;quot;, params[:id], @review_questionnaire_ids])&lt;br /&gt;
&lt;br /&gt;
To&lt;br /&gt;
 &lt;br /&gt;
  AssignmentQuestionnaire.where(assignment_id: params[:id],:questionnaire_id =&amp;gt; @review_questionnaire_ids)&lt;br /&gt;
&lt;br /&gt;
7. From&lt;br /&gt;
&lt;br /&gt;
  SelfReviewResponseMap.where(['reviewee_id = ? and reviewer_id = ?', team_id[0].t_id, params[:reviewer_id]])&lt;br /&gt;
&lt;br /&gt;
To &lt;br /&gt;
&lt;br /&gt;
  SelfReviewResponseMap.where(reviewee_id:team_id[0].t_id,reviewer_id:params[:reviewer_id])&lt;br /&gt;
&lt;br /&gt;
==Refactor long line method==&lt;br /&gt;
&lt;br /&gt;
  def automatic_review_mapping_strategy(assignment_id,&lt;br /&gt;
                                        participants, teams, student_review_num = 0,&lt;br /&gt;
                                        submission_review_num = 0)&lt;br /&gt;
    participants_hash = {}&lt;br /&gt;
    participants.each {|participant| participants_hash[participant.id] = 0 }&lt;br /&gt;
    # calculate reviewers for each team&lt;br /&gt;
    num_participants = participants.size&lt;br /&gt;
    if student_review_num != 0 and submission_review_num == 0&lt;br /&gt;
      num_reviews_per_team = (participants.size * student_review_num * 1.0 / teams.size).round&lt;br /&gt;
      student_review_num = student_review_num&lt;br /&gt;
      exact_num_of_review_needed = participants.size * student_review_num&lt;br /&gt;
    elsif student_review_num == 0 and submission_review_num != 0&lt;br /&gt;
      num_reviews_per_team = submission_review_num&lt;br /&gt;
      student_review_num = (teams.size * submission_review_num * 1.0 / participants.size).round&lt;br /&gt;
      exact_num_of_review_needed = teams.size * submission_review_num&lt;br /&gt;
    end&lt;br /&gt;
    execute_peer_review_strategy(assignment_id, teams, num_participants,&lt;br /&gt;
                                     student_review_num, num_reviews_per_team,&lt;br /&gt;
                                     participants, participants_hash)&lt;br /&gt;
    # after assigning peer reviews for each team,&lt;br /&gt;
    # if there are still some peer reviewers not obtain enough peer review,&lt;br /&gt;
    # just assign them to valid teams&lt;br /&gt;
    assign_reviewers_for_team(assignment_id,student_review_num,participants_hash,&lt;br /&gt;
                              exact_num_of_review_needed)&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  def assign_reviewers_for_team(assignment_id,student_review_num,participants_hash,&lt;br /&gt;
                                exact_num_of_review_needed)&lt;br /&gt;
    if ReviewResponseMap.where([&amp;quot;reviewed_object_id = ? and created_at &amp;gt; ? and calibrate_to = ?&amp;quot;, &lt;br /&gt;
                                assignment_id, &lt;br /&gt;
                                @@time_create_last_review_mapping_record, 0]).size &amp;lt; exact_num_of_review_needed&lt;br /&gt;
      participants_with_insufficient_review_num = []&lt;br /&gt;
      participants_hash.each do |participant_id, review_num|&lt;br /&gt;
        participants_with_insufficient_review_num &amp;lt;&amp;lt; participant_id if review_num &amp;lt; student_review_num&lt;br /&gt;
      end&lt;br /&gt;
      unsorted_teams_hash = {}&lt;br /&gt;
      ReviewResponseMap.where([&amp;quot;reviewed_object_id = ? and calibrate_to = ?&amp;quot;, &lt;br /&gt;
                               assignment_id, 0]).each do |response_map|&lt;br /&gt;
        if unsorted_teams_hash.key? response_map.reviewee_id&lt;br /&gt;
          unsorted_teams_hash[response_map.reviewee_id] += 1&lt;br /&gt;
        else&lt;br /&gt;
          unsorted_teams_hash[response_map.reviewee_id] = 1&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
      teams_hash = unsorted_teams_hash.sort_by {|_, v| v }.to_h&lt;br /&gt;
      participants_with_insufficient_review_num.each do |participant_id|&lt;br /&gt;
        teams_hash.each do |team_id, _num_review_received|&lt;br /&gt;
          next if TeamsUser.exists?(team_id: team_id, &lt;br /&gt;
                                    user_id: Participant.find(participant_id).user_id)&lt;br /&gt;
          ReviewResponseMap.where(reviewee_id: team_id, reviewer_id: participant_id, &lt;br /&gt;
                                  reviewed_object_id: assignment_id).first_or_create&lt;br /&gt;
          teams_hash[team_id] += 1&lt;br /&gt;
          teams_hash = teams_hash.sort_by {|_, v| v }.to_h&lt;br /&gt;
          break&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
    @@time_create_last_review_mapping_record = ReviewResponseMap.&lt;br /&gt;
                                               where(reviewed_object_id: assignment_id).&lt;br /&gt;
                                               last.created_at&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def execute_peer_review_strategy(assignment_id, teams, num_participants, &lt;br /&gt;
                                   student_review_num, num_reviews_per_team, &lt;br /&gt;
                                   participants, participants_hash)&lt;br /&gt;
    # Exception detection: If instructor want to assign too many reviews done&lt;br /&gt;
    # by each student, there will be an error msg.&lt;br /&gt;
    if student_review_num &amp;gt;= teams.size&lt;br /&gt;
      flash[:error] = 'You cannot set the number of reviews done &lt;br /&gt;
      by each student to be greater than or equal to total number of teams &lt;br /&gt;
      [or &amp;quot;participants&amp;quot; if it is an individual assignment].'&lt;br /&gt;
    end&lt;br /&gt;
    peer_review_strategy(assignment_id, teams, num_participants, &lt;br /&gt;
                         student_review_num, num_reviews_per_team, &lt;br /&gt;
                         participants, participants_hash)&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
=Test=&lt;br /&gt;
We write RSpec feature tests to prove that all changes are correct and the project performs well as before.&lt;br /&gt;
&lt;br /&gt;
The function of  method automatic_review_mapping is to automatically assign reviews on students in teams when instructor set either student review number or submissions review number. There is constraint that only one of the two numbers must be set value other than 0 (that is, one is 0 and other is not 0). To test the correctness  of our refactoring, we design a scenario and 4 cases of assigning reviews to students:&lt;br /&gt;
&lt;br /&gt;
Case 1. Instructor has not set both students review number and submissions review number (They are both 0). The page will show a notice.&lt;br /&gt;
&lt;br /&gt;
Case 2. Instructor set both numbers (They are both not 0). The page will show a notice.&lt;br /&gt;
&lt;br /&gt;
Case 3. Instructors set students review number. The controller will change database: create new relationship in ReviewResponseMap. For example, if assign student review number to 2, and there will be 20 peer reviews in total and need to allocate to 3 teams. So each team get 7 reviews on average and 1 team’s artifact will be reviewed 6 times.&lt;br /&gt;
&lt;br /&gt;
Case 4. Instructors set submissions review number. The controller will change database: create new relationship in ReviewResponseMap. For example, if assign submission review number to 3, and there will be 21 peer reviews in total to allocate to 10 participants. So every participants get 2 reviews. 9 among 10 participants will review 2 teams’ artifacts and 1 participant will review 3 teams’ artifacts.&lt;br /&gt;
&lt;br /&gt;
require 'rails_helper'&lt;br /&gt;
  describe &amp;quot;review mapping&amp;quot;, js: true do&lt;br /&gt;
    before(:each) do&lt;br /&gt;
      #create test data&lt;br /&gt;
    end&lt;br /&gt;
 &lt;br /&gt;
    it &amp;quot;show error when assign both 0&amp;quot; do&lt;br /&gt;
      login_as(&amp;quot;instructor6&amp;quot;)&lt;br /&gt;
      visit '/assignments/1/edit'&lt;br /&gt;
      find_link('ReviewStrategy').click&lt;br /&gt;
      select &amp;quot;Instructor-Selected&amp;quot;, from: 'assignment_form_assignment_review_assignment_strategy'&lt;br /&gt;
      fill_in 'num_reviews_per_student', with: 0&lt;br /&gt;
      choose 'num_reviews_submission'&lt;br /&gt;
      fill_in 'num_reviews_per_submission', with: 0&lt;br /&gt;
      click_button 'second_submit_tag'&lt;br /&gt;
      #click_button 'Save'&lt;br /&gt;
      expect(page).to have_content('Please choose either the number of reviews per student or the number of reviewers per team (student)')&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    it &amp;quot;show error when assign both numbers&amp;quot; do&lt;br /&gt;
      login_as(&amp;quot;instructor6&amp;quot;)&lt;br /&gt;
      visit '/assignments/1/edit'&lt;br /&gt;
      find_link('ReviewStrategy').click&lt;br /&gt;
      select &amp;quot;Instructor-Selected&amp;quot;, from: 'assignment_form_assignment_review_assignment_strategy'&lt;br /&gt;
      fill_in 'num_reviews_per_student', with: 1&lt;br /&gt;
      choose 'num_reviews_submission'&lt;br /&gt;
      fill_in 'num_reviews_per_submission', with: 1&lt;br /&gt;
      click_button 'second_submit_tag'&lt;br /&gt;
      #click_button 'Save'&lt;br /&gt;
      expect(page).to have_content('Please choose either the number of reviews per student or the number of reviewers per team (student), not both')&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    it &amp;quot;calculate reviewmapping from given review number per student&amp;quot; do&lt;br /&gt;
      login_as(&amp;quot;instructor6&amp;quot;)&lt;br /&gt;
      visit '/assignments/1/edit'&lt;br /&gt;
      find_link('ReviewStrategy').click&lt;br /&gt;
      select &amp;quot;Instructor-Selected&amp;quot;, from: 'assignment_form_assignment_review_assignment_strategy'&lt;br /&gt;
      fill_in 'num_reviews_per_student', with: 2&lt;br /&gt;
      click_button 'first_submit_tag'&lt;br /&gt;
      num = ReviewResponseMap.where(reviewee_id: @team1.id, reviewed_object_id: @assignment.id).count&lt;br /&gt;
      expect(num).to eq(7)&lt;br /&gt;
      num2 = ReviewResponseMap.where(reviewee_id: @team3.id, reviewed_object_id: @assignment.id).count&lt;br /&gt;
      expect(num2).to eq(6)&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    it &amp;quot;calculate reviewmapping from given review number per submission&amp;quot; do&lt;br /&gt;
      login_as(&amp;quot;instructor6&amp;quot;)&lt;br /&gt;
      visit '/assignments/1/edit'&lt;br /&gt;
      find_link('ReviewStrategy').click&lt;br /&gt;
      select &amp;quot;Instructor-Selected&amp;quot;, from: 'assignment_form_assignment_review_assignment_strategy'&lt;br /&gt;
      choose 'num_reviews_submission'&lt;br /&gt;
      fill_in 'num_reviews_per_submission', with: 7&lt;br /&gt;
      click_button 'second_submit_tag'&lt;br /&gt;
      #click_button 'Save'&lt;br /&gt;
      num = ReviewResponseMap.where(reviewer_id: @teamuser1.id, reviewed_object_id: @assignment.id).count&lt;br /&gt;
      expect(num).to eq(2)&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;/div&gt;</summary>
		<author><name>Jdeng8</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2016/E1641._Refactor_review_mapping_controller.rb&amp;diff=103942</id>
		<title>CSC/ECE 517 Fall 2016/E1641. Refactor review mapping controller.rb</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2016/E1641._Refactor_review_mapping_controller.rb&amp;diff=103942"/>
		<updated>2016-10-29T05:41:14Z</updated>

		<summary type="html">&lt;p&gt;Jdeng8: /* Current Implementation and Problems */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=Background=&lt;br /&gt;
&lt;br /&gt;
This controller sets up mappings between reviewer and reviewee. It handles all different types of response maps (review response map, author feedback response map, teammate review response map, meta review response map and quiz response map). The class has functionality for five different kinds of Responses: reviews, metareviews, teammate reviews, author feedback (“rejoinders”), and quizzes. &lt;br /&gt;
&lt;br /&gt;
=Current Implementation and Problems=&lt;br /&gt;
&lt;br /&gt;
# Method ''response_report'' has some [[#wikipedia:SQL|SQL]] - like code.  Rewrite with Active Record.&lt;br /&gt;
# Test whether method ''add_user_to_assignment'' is used. There is no way that this method should be in ReviewMappingController. Please remove this method and caller.&lt;br /&gt;
# There was a ''self-review'' feature, the method ''add_self_reviewer'', ''get_team_from_submission'' are related to this. Two views calls ''add_self_reviewer'' are &amp;quot;show_available_submissions_for_quizzes.html.erb&amp;quot; and &amp;quot;show_available_submissions.html.erb&amp;quot;. The names of views are not related to ''self_review'' feature. Plus those two views are not called anywhere. Please verify this and if so, you should delete those two views, two method and also related records (e.g. in routes.rb).&lt;br /&gt;
# Method ''delete_all_reviewers'' actually only deletes the outstanding review response maps (the ones which has been initiated, but there is no response yet). So it should better be named ''delete_outstanding_reviewers''. You can try to test this method by clicking “Assign reviewers” icon on an assignment.&lt;br /&gt;
# Method ''release_reservation'' should be renamed as'' release_mapping''. In addition, delete it if you find this method is not called anywhere.&lt;br /&gt;
# Method ''delete_mappings'' is problematic. It does not looks like a controller method. Please refactor it or delete it if you can validate that this method is not called anywhere.&lt;br /&gt;
# Method'' automatic_review_mapping_strategy'' is too long. Please refactor and test it.&lt;br /&gt;
&lt;br /&gt;
=Changes Implemented=&lt;br /&gt;
&lt;br /&gt;
# change the rails query from sql like code, like ReviewResponseMap.where(['reviewee_id = ? and reviewer_id = ? ', params[:contributor_id], reviewer.id]) to more rails quey like ReviewResponseMap.where(reviewee_id: params[:contributor_id],reviewer_id: reviewer.id)&lt;br /&gt;
# We search the function name(''add_user_to_assignment'') in the whole files, and find that this method is invoked in &amp;quot;participants_helper.rb&amp;quot;, and also being invoked in the function of ''add_reviewer'' and ''add_metareviewer'' in the controller of ''review_mapping_controller'' &lt;br /&gt;
# By searching the whole project and routes, we verify that methods ''add_self_reviewer'' and ''get_team_from_submission'' in this controller are not called by any other methods except for views &amp;quot;show_available_submissions_for_quizzes.html.erb&amp;quot; and &amp;quot;show_available_submissions.html.erb&amp;quot;. And those two views are not linked to any other views. So they are deleted from the project.&lt;br /&gt;
# We already renamed method ''delete_all_reviewers'' to ''delete_outstanding_reviewers'' and changed the corresponding button name at the corresponding view (_list_review_mappings.html.erb).&lt;br /&gt;
# By searching the whole project and routes, we verify that methods'' release_reservation'' in this controller are not used in anywhere.&lt;br /&gt;
# By searching the whole project and routes, we verify that methods ''delete_mappings'' in this controller are not used in anywhere.&lt;br /&gt;
# Method ''automatic_review_mapping_strategy'' have many long lines. We already shorten each long line to multiple lines. And also, we split this long function into three different functions.&lt;br /&gt;
&lt;br /&gt;
=Code=&lt;br /&gt;
&lt;br /&gt;
==Refactor SQL query code==&lt;br /&gt;
&lt;br /&gt;
The rails query we change in this controller:&lt;br /&gt;
&lt;br /&gt;
1. From &lt;br /&gt;
&lt;br /&gt;
  ReviewResponseMap.where(['reviewee_id = ? and reviewer_id = ? ', params[:contributor_id], reviewer.id]) &lt;br /&gt;
&lt;br /&gt;
To&lt;br /&gt;
&lt;br /&gt;
  ReviewResponseMap.where(reviewee_id: params[:contributor_id],reviewer_id: reviewer.id)&lt;br /&gt;
&lt;br /&gt;
2. From&lt;br /&gt;
&lt;br /&gt;
  MetareviewResponseMap.where(['reviewed_object_id = ? and reviewer_id = ?', mapping.map_id, reviewer.id])&lt;br /&gt;
&lt;br /&gt;
To&lt;br /&gt;
&lt;br /&gt;
  MetareviewResponseMap.where(reviewed_object_id: mapping.map_id, reviewer_id: reviewer.id)&lt;br /&gt;
&lt;br /&gt;
3. From&lt;br /&gt;
&lt;br /&gt;
                   @assignments = Assignment&lt;br /&gt;
                   .where([&amp;quot;instructor_id = ? and substring(name,1,1) = ?&amp;quot;, session[:user].id, letter])&lt;br /&gt;
                   .order('name')&lt;br /&gt;
                   .page(params[:page])&lt;br /&gt;
                   .per_page(10)&lt;br /&gt;
&lt;br /&gt;
To &lt;br /&gt;
&lt;br /&gt;
                   @assignments = Assignment&lt;br /&gt;
                   .where(instructor_id:session[:user].id)&lt;br /&gt;
                   .where(&amp;quot;substring(name,1,1) = :letter&amp;quot;,{letter:letter})&lt;br /&gt;
                   .order('name')&lt;br /&gt;
                   .page(params[:page])&lt;br /&gt;
                   .per_page(10)&lt;br /&gt;
&lt;br /&gt;
4.  From&lt;br /&gt;
&lt;br /&gt;
  ReviewResponseMap.where([&amp;quot;reviewed_object_id = ? and calibrate_to = ?&amp;quot;, assignment_id, 1])&lt;br /&gt;
&lt;br /&gt;
To &lt;br /&gt;
&lt;br /&gt;
  ReviewResponseMap.where(reviewed_object_id:assignment_id, calibrate_to: 1)&lt;br /&gt;
&lt;br /&gt;
5. From&lt;br /&gt;
&lt;br /&gt;
  ReviewResponseMap.where([&amp;quot;reviewed_object_id = ? and created_at &amp;gt; ? and calibrate_to = ?&amp;quot;, assignment_id, @@time_create_last_review_mapping_record, 0])&lt;br /&gt;
&lt;br /&gt;
To &lt;br /&gt;
&lt;br /&gt;
  ReviewResponseMap.where(reviewed_object_id:assignment_id,calibrate_to:0).where(&amp;quot;created_at &amp;gt; :time&amp;quot;,{time:@@time_create_last_review_mapping_record})&lt;br /&gt;
&lt;br /&gt;
6. From&lt;br /&gt;
&lt;br /&gt;
  AssignmentQuestionnaire.where([&amp;quot;assignment_id = ? and questionnaire_id IN (?)&amp;quot;, params[:id], @review_questionnaire_ids])&lt;br /&gt;
&lt;br /&gt;
To&lt;br /&gt;
 &lt;br /&gt;
  AssignmentQuestionnaire.where(assignment_id: params[:id],:questionnaire_id =&amp;gt; @review_questionnaire_ids)&lt;br /&gt;
&lt;br /&gt;
7. From&lt;br /&gt;
&lt;br /&gt;
  SelfReviewResponseMap.where(['reviewee_id = ? and reviewer_id = ?', team_id[0].t_id, params[:reviewer_id]])&lt;br /&gt;
&lt;br /&gt;
To &lt;br /&gt;
&lt;br /&gt;
  SelfReviewResponseMap.where(reviewee_id:team_id[0].t_id,reviewer_id:params[:reviewer_id])&lt;br /&gt;
&lt;br /&gt;
==Refactor long line method==&lt;br /&gt;
&lt;br /&gt;
  def automatic_review_mapping_strategy(assignment_id,&lt;br /&gt;
                                        participants, teams, student_review_num = 0,&lt;br /&gt;
                                        submission_review_num = 0)&lt;br /&gt;
    participants_hash = {}&lt;br /&gt;
    participants.each {|participant| participants_hash[participant.id] = 0 }&lt;br /&gt;
    # calculate reviewers for each team&lt;br /&gt;
    num_participants = participants.size&lt;br /&gt;
    if student_review_num != 0 and submission_review_num == 0&lt;br /&gt;
      num_reviews_per_team = (participants.size * student_review_num * 1.0 / teams.size).round&lt;br /&gt;
      student_review_num = student_review_num&lt;br /&gt;
      exact_num_of_review_needed = participants.size * student_review_num&lt;br /&gt;
    elsif student_review_num == 0 and submission_review_num != 0&lt;br /&gt;
      num_reviews_per_team = submission_review_num&lt;br /&gt;
      student_review_num = (teams.size * submission_review_num * 1.0 / participants.size).round&lt;br /&gt;
      exact_num_of_review_needed = teams.size * submission_review_num&lt;br /&gt;
    end&lt;br /&gt;
    execute_peer_review_strategy(assignment_id, teams, num_participants,&lt;br /&gt;
                                     student_review_num, num_reviews_per_team,&lt;br /&gt;
                                     participants, participants_hash)&lt;br /&gt;
    # after assigning peer reviews for each team,&lt;br /&gt;
    # if there are still some peer reviewers not obtain enough peer review,&lt;br /&gt;
    # just assign them to valid teams&lt;br /&gt;
    assign_reviewers_for_team(assignment_id,student_review_num,participants_hash,&lt;br /&gt;
                              exact_num_of_review_needed)&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  def assign_reviewers_for_team(assignment_id,student_review_num,participants_hash,&lt;br /&gt;
                                exact_num_of_review_needed)&lt;br /&gt;
    if ReviewResponseMap.where([&amp;quot;reviewed_object_id = ? and created_at &amp;gt; ? and calibrate_to = ?&amp;quot;, &lt;br /&gt;
                                assignment_id, &lt;br /&gt;
                                @@time_create_last_review_mapping_record, 0]).size &amp;lt; exact_num_of_review_needed&lt;br /&gt;
      participants_with_insufficient_review_num = []&lt;br /&gt;
      participants_hash.each do |participant_id, review_num|&lt;br /&gt;
        participants_with_insufficient_review_num &amp;lt;&amp;lt; participant_id if review_num &amp;lt; student_review_num&lt;br /&gt;
      end&lt;br /&gt;
      unsorted_teams_hash = {}&lt;br /&gt;
      ReviewResponseMap.where([&amp;quot;reviewed_object_id = ? and calibrate_to = ?&amp;quot;, &lt;br /&gt;
                               assignment_id, 0]).each do |response_map|&lt;br /&gt;
        if unsorted_teams_hash.key? response_map.reviewee_id&lt;br /&gt;
          unsorted_teams_hash[response_map.reviewee_id] += 1&lt;br /&gt;
        else&lt;br /&gt;
          unsorted_teams_hash[response_map.reviewee_id] = 1&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
      teams_hash = unsorted_teams_hash.sort_by {|_, v| v }.to_h&lt;br /&gt;
      participants_with_insufficient_review_num.each do |participant_id|&lt;br /&gt;
        teams_hash.each do |team_id, _num_review_received|&lt;br /&gt;
          next if TeamsUser.exists?(team_id: team_id, &lt;br /&gt;
                                    user_id: Participant.find(participant_id).user_id)&lt;br /&gt;
          ReviewResponseMap.where(reviewee_id: team_id, reviewer_id: participant_id, &lt;br /&gt;
                                  reviewed_object_id: assignment_id).first_or_create&lt;br /&gt;
          teams_hash[team_id] += 1&lt;br /&gt;
          teams_hash = teams_hash.sort_by {|_, v| v }.to_h&lt;br /&gt;
          break&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
    @@time_create_last_review_mapping_record = ReviewResponseMap.&lt;br /&gt;
                                               where(reviewed_object_id: assignment_id).&lt;br /&gt;
                                               last.created_at&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def execute_peer_review_strategy(assignment_id, teams, num_participants, &lt;br /&gt;
                                   student_review_num, num_reviews_per_team, &lt;br /&gt;
                                   participants, participants_hash)&lt;br /&gt;
    # Exception detection: If instructor want to assign too many reviews done&lt;br /&gt;
    # by each student, there will be an error msg.&lt;br /&gt;
    if student_review_num &amp;gt;= teams.size&lt;br /&gt;
      flash[:error] = 'You cannot set the number of reviews done &lt;br /&gt;
      by each student to be greater than or equal to total number of teams &lt;br /&gt;
      [or &amp;quot;participants&amp;quot; if it is an individual assignment].'&lt;br /&gt;
    end&lt;br /&gt;
    peer_review_strategy(assignment_id, teams, num_participants, &lt;br /&gt;
                         student_review_num, num_reviews_per_team, &lt;br /&gt;
                         participants, participants_hash)&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
=Test=&lt;br /&gt;
We write RSpec feature tests to prove that all changes are correct and the project performs well as before.&lt;br /&gt;
&lt;br /&gt;
The function of  method automatic_review_mapping is to automatically assign reviews on students in teams when instructor set either student review number or submissions review number. There is constraint that only one of the two numbers must be set value other than 0 (that is, one is 0 and other is not 0). To test the correctness  of our refactoring, we design a scenario and 4 cases of assigning reviews to students:&lt;br /&gt;
&lt;br /&gt;
Case 1. Instructor has not set both students review number and submissions review number (They are both 0). The page will show a notice.&lt;br /&gt;
&lt;br /&gt;
Case 2. Instructor set both numbers (They are both not 0). The page will show a notice.&lt;br /&gt;
&lt;br /&gt;
Case 3. Instructors set students review number. The controller will change database: create new relationship in ReviewResponseMap. For example, if assign student review number to 2, and there will be 20 peer reviews in total and need to allocate to 3 teams. So each team get 7 reviews on average and 1 team’s artifact will be reviewed 6 times.&lt;br /&gt;
&lt;br /&gt;
Case 4. Instructors set submissions review number. The controller will change database: create new relationship in ReviewResponseMap. For example, if assign submission review number to 3, and there will be 21 peer reviews in total to allocate to 10 participants. So every participants get 2 reviews. 9 among 10 participants will review 2 teams’ artifacts and 1 participant will review 3 teams’ artifacts.&lt;br /&gt;
&lt;br /&gt;
require 'rails_helper'&lt;br /&gt;
  describe &amp;quot;review mapping&amp;quot;, js: true do&lt;br /&gt;
    before(:each) do&lt;br /&gt;
      #create test data&lt;br /&gt;
    end&lt;br /&gt;
 &lt;br /&gt;
    it &amp;quot;show error when assign both 0&amp;quot; do&lt;br /&gt;
      login_as(&amp;quot;instructor6&amp;quot;)&lt;br /&gt;
      visit '/assignments/1/edit'&lt;br /&gt;
      find_link('ReviewStrategy').click&lt;br /&gt;
      select &amp;quot;Instructor-Selected&amp;quot;, from: 'assignment_form_assignment_review_assignment_strategy'&lt;br /&gt;
      fill_in 'num_reviews_per_student', with: 0&lt;br /&gt;
      choose 'num_reviews_submission'&lt;br /&gt;
      fill_in 'num_reviews_per_submission', with: 0&lt;br /&gt;
      click_button 'second_submit_tag'&lt;br /&gt;
      #click_button 'Save'&lt;br /&gt;
      expect(page).to have_content('Please choose either the number of reviews per student or the number of reviewers per team (student)')&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    it &amp;quot;show error when assign both numbers&amp;quot; do&lt;br /&gt;
      login_as(&amp;quot;instructor6&amp;quot;)&lt;br /&gt;
      visit '/assignments/1/edit'&lt;br /&gt;
      find_link('ReviewStrategy').click&lt;br /&gt;
      select &amp;quot;Instructor-Selected&amp;quot;, from: 'assignment_form_assignment_review_assignment_strategy'&lt;br /&gt;
      fill_in 'num_reviews_per_student', with: 1&lt;br /&gt;
      choose 'num_reviews_submission'&lt;br /&gt;
      fill_in 'num_reviews_per_submission', with: 1&lt;br /&gt;
      click_button 'second_submit_tag'&lt;br /&gt;
      #click_button 'Save'&lt;br /&gt;
      expect(page).to have_content('Please choose either the number of reviews per student or the number of reviewers per team (student), not both')&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    it &amp;quot;calculate reviewmapping from given review number per student&amp;quot; do&lt;br /&gt;
      login_as(&amp;quot;instructor6&amp;quot;)&lt;br /&gt;
      visit '/assignments/1/edit'&lt;br /&gt;
      find_link('ReviewStrategy').click&lt;br /&gt;
      select &amp;quot;Instructor-Selected&amp;quot;, from: 'assignment_form_assignment_review_assignment_strategy'&lt;br /&gt;
      fill_in 'num_reviews_per_student', with: 2&lt;br /&gt;
      click_button 'first_submit_tag'&lt;br /&gt;
      num = ReviewResponseMap.where(reviewee_id: @team1.id, reviewed_object_id: @assignment.id).count&lt;br /&gt;
      expect(num).to eq(7)&lt;br /&gt;
      num2 = ReviewResponseMap.where(reviewee_id: @team3.id, reviewed_object_id: @assignment.id).count&lt;br /&gt;
      expect(num2).to eq(6)&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    it &amp;quot;calculate reviewmapping from given review number per submission&amp;quot; do&lt;br /&gt;
      login_as(&amp;quot;instructor6&amp;quot;)&lt;br /&gt;
      visit '/assignments/1/edit'&lt;br /&gt;
      find_link('ReviewStrategy').click&lt;br /&gt;
      select &amp;quot;Instructor-Selected&amp;quot;, from: 'assignment_form_assignment_review_assignment_strategy'&lt;br /&gt;
      choose 'num_reviews_submission'&lt;br /&gt;
      fill_in 'num_reviews_per_submission', with: 7&lt;br /&gt;
      click_button 'second_submit_tag'&lt;br /&gt;
      #click_button 'Save'&lt;br /&gt;
      num = ReviewResponseMap.where(reviewer_id: @teamuser1.id, reviewed_object_id: @assignment.id).count&lt;br /&gt;
      expect(num).to eq(2)&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;/div&gt;</summary>
		<author><name>Jdeng8</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2016/E1641._Refactor_review_mapping_controller.rb&amp;diff=103941</id>
		<title>CSC/ECE 517 Fall 2016/E1641. Refactor review mapping controller.rb</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2016/E1641._Refactor_review_mapping_controller.rb&amp;diff=103941"/>
		<updated>2016-10-29T05:41:02Z</updated>

		<summary type="html">&lt;p&gt;Jdeng8: /* Current Implementation and Problems */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=Background=&lt;br /&gt;
&lt;br /&gt;
This controller sets up mappings between reviewer and reviewee. It handles all different types of response maps (review response map, author feedback response map, teammate review response map, meta review response map and quiz response map). The class has functionality for five different kinds of Responses: reviews, metareviews, teammate reviews, author feedback (“rejoinders”), and quizzes. &lt;br /&gt;
&lt;br /&gt;
=Current Implementation and Problems=&lt;br /&gt;
&lt;br /&gt;
# Method ''response_report'' has some [[#w:SQL|SQL]] - like code.  Rewrite with Active Record.&lt;br /&gt;
# Test whether method ''add_user_to_assignment'' is used. There is no way that this method should be in ReviewMappingController. Please remove this method and caller.&lt;br /&gt;
# There was a ''self-review'' feature, the method ''add_self_reviewer'', ''get_team_from_submission'' are related to this. Two views calls ''add_self_reviewer'' are &amp;quot;show_available_submissions_for_quizzes.html.erb&amp;quot; and &amp;quot;show_available_submissions.html.erb&amp;quot;. The names of views are not related to ''self_review'' feature. Plus those two views are not called anywhere. Please verify this and if so, you should delete those two views, two method and also related records (e.g. in routes.rb).&lt;br /&gt;
# Method ''delete_all_reviewers'' actually only deletes the outstanding review response maps (the ones which has been initiated, but there is no response yet). So it should better be named ''delete_outstanding_reviewers''. You can try to test this method by clicking “Assign reviewers” icon on an assignment.&lt;br /&gt;
# Method ''release_reservation'' should be renamed as'' release_mapping''. In addition, delete it if you find this method is not called anywhere.&lt;br /&gt;
# Method ''delete_mappings'' is problematic. It does not looks like a controller method. Please refactor it or delete it if you can validate that this method is not called anywhere.&lt;br /&gt;
# Method'' automatic_review_mapping_strategy'' is too long. Please refactor and test it.&lt;br /&gt;
&lt;br /&gt;
=Changes Implemented=&lt;br /&gt;
&lt;br /&gt;
# change the rails query from sql like code, like ReviewResponseMap.where(['reviewee_id = ? and reviewer_id = ? ', params[:contributor_id], reviewer.id]) to more rails quey like ReviewResponseMap.where(reviewee_id: params[:contributor_id],reviewer_id: reviewer.id)&lt;br /&gt;
# We search the function name(''add_user_to_assignment'') in the whole files, and find that this method is invoked in &amp;quot;participants_helper.rb&amp;quot;, and also being invoked in the function of ''add_reviewer'' and ''add_metareviewer'' in the controller of ''review_mapping_controller'' &lt;br /&gt;
# By searching the whole project and routes, we verify that methods ''add_self_reviewer'' and ''get_team_from_submission'' in this controller are not called by any other methods except for views &amp;quot;show_available_submissions_for_quizzes.html.erb&amp;quot; and &amp;quot;show_available_submissions.html.erb&amp;quot;. And those two views are not linked to any other views. So they are deleted from the project.&lt;br /&gt;
# We already renamed method ''delete_all_reviewers'' to ''delete_outstanding_reviewers'' and changed the corresponding button name at the corresponding view (_list_review_mappings.html.erb).&lt;br /&gt;
# By searching the whole project and routes, we verify that methods'' release_reservation'' in this controller are not used in anywhere.&lt;br /&gt;
# By searching the whole project and routes, we verify that methods ''delete_mappings'' in this controller are not used in anywhere.&lt;br /&gt;
# Method ''automatic_review_mapping_strategy'' have many long lines. We already shorten each long line to multiple lines. And also, we split this long function into three different functions.&lt;br /&gt;
&lt;br /&gt;
=Code=&lt;br /&gt;
&lt;br /&gt;
==Refactor SQL query code==&lt;br /&gt;
&lt;br /&gt;
The rails query we change in this controller:&lt;br /&gt;
&lt;br /&gt;
1. From &lt;br /&gt;
&lt;br /&gt;
  ReviewResponseMap.where(['reviewee_id = ? and reviewer_id = ? ', params[:contributor_id], reviewer.id]) &lt;br /&gt;
&lt;br /&gt;
To&lt;br /&gt;
&lt;br /&gt;
  ReviewResponseMap.where(reviewee_id: params[:contributor_id],reviewer_id: reviewer.id)&lt;br /&gt;
&lt;br /&gt;
2. From&lt;br /&gt;
&lt;br /&gt;
  MetareviewResponseMap.where(['reviewed_object_id = ? and reviewer_id = ?', mapping.map_id, reviewer.id])&lt;br /&gt;
&lt;br /&gt;
To&lt;br /&gt;
&lt;br /&gt;
  MetareviewResponseMap.where(reviewed_object_id: mapping.map_id, reviewer_id: reviewer.id)&lt;br /&gt;
&lt;br /&gt;
3. From&lt;br /&gt;
&lt;br /&gt;
                   @assignments = Assignment&lt;br /&gt;
                   .where([&amp;quot;instructor_id = ? and substring(name,1,1) = ?&amp;quot;, session[:user].id, letter])&lt;br /&gt;
                   .order('name')&lt;br /&gt;
                   .page(params[:page])&lt;br /&gt;
                   .per_page(10)&lt;br /&gt;
&lt;br /&gt;
To &lt;br /&gt;
&lt;br /&gt;
                   @assignments = Assignment&lt;br /&gt;
                   .where(instructor_id:session[:user].id)&lt;br /&gt;
                   .where(&amp;quot;substring(name,1,1) = :letter&amp;quot;,{letter:letter})&lt;br /&gt;
                   .order('name')&lt;br /&gt;
                   .page(params[:page])&lt;br /&gt;
                   .per_page(10)&lt;br /&gt;
&lt;br /&gt;
4.  From&lt;br /&gt;
&lt;br /&gt;
  ReviewResponseMap.where([&amp;quot;reviewed_object_id = ? and calibrate_to = ?&amp;quot;, assignment_id, 1])&lt;br /&gt;
&lt;br /&gt;
To &lt;br /&gt;
&lt;br /&gt;
  ReviewResponseMap.where(reviewed_object_id:assignment_id, calibrate_to: 1)&lt;br /&gt;
&lt;br /&gt;
5. From&lt;br /&gt;
&lt;br /&gt;
  ReviewResponseMap.where([&amp;quot;reviewed_object_id = ? and created_at &amp;gt; ? and calibrate_to = ?&amp;quot;, assignment_id, @@time_create_last_review_mapping_record, 0])&lt;br /&gt;
&lt;br /&gt;
To &lt;br /&gt;
&lt;br /&gt;
  ReviewResponseMap.where(reviewed_object_id:assignment_id,calibrate_to:0).where(&amp;quot;created_at &amp;gt; :time&amp;quot;,{time:@@time_create_last_review_mapping_record})&lt;br /&gt;
&lt;br /&gt;
6. From&lt;br /&gt;
&lt;br /&gt;
  AssignmentQuestionnaire.where([&amp;quot;assignment_id = ? and questionnaire_id IN (?)&amp;quot;, params[:id], @review_questionnaire_ids])&lt;br /&gt;
&lt;br /&gt;
To&lt;br /&gt;
 &lt;br /&gt;
  AssignmentQuestionnaire.where(assignment_id: params[:id],:questionnaire_id =&amp;gt; @review_questionnaire_ids)&lt;br /&gt;
&lt;br /&gt;
7. From&lt;br /&gt;
&lt;br /&gt;
  SelfReviewResponseMap.where(['reviewee_id = ? and reviewer_id = ?', team_id[0].t_id, params[:reviewer_id]])&lt;br /&gt;
&lt;br /&gt;
To &lt;br /&gt;
&lt;br /&gt;
  SelfReviewResponseMap.where(reviewee_id:team_id[0].t_id,reviewer_id:params[:reviewer_id])&lt;br /&gt;
&lt;br /&gt;
==Refactor long line method==&lt;br /&gt;
&lt;br /&gt;
  def automatic_review_mapping_strategy(assignment_id,&lt;br /&gt;
                                        participants, teams, student_review_num = 0,&lt;br /&gt;
                                        submission_review_num = 0)&lt;br /&gt;
    participants_hash = {}&lt;br /&gt;
    participants.each {|participant| participants_hash[participant.id] = 0 }&lt;br /&gt;
    # calculate reviewers for each team&lt;br /&gt;
    num_participants = participants.size&lt;br /&gt;
    if student_review_num != 0 and submission_review_num == 0&lt;br /&gt;
      num_reviews_per_team = (participants.size * student_review_num * 1.0 / teams.size).round&lt;br /&gt;
      student_review_num = student_review_num&lt;br /&gt;
      exact_num_of_review_needed = participants.size * student_review_num&lt;br /&gt;
    elsif student_review_num == 0 and submission_review_num != 0&lt;br /&gt;
      num_reviews_per_team = submission_review_num&lt;br /&gt;
      student_review_num = (teams.size * submission_review_num * 1.0 / participants.size).round&lt;br /&gt;
      exact_num_of_review_needed = teams.size * submission_review_num&lt;br /&gt;
    end&lt;br /&gt;
    execute_peer_review_strategy(assignment_id, teams, num_participants,&lt;br /&gt;
                                     student_review_num, num_reviews_per_team,&lt;br /&gt;
                                     participants, participants_hash)&lt;br /&gt;
    # after assigning peer reviews for each team,&lt;br /&gt;
    # if there are still some peer reviewers not obtain enough peer review,&lt;br /&gt;
    # just assign them to valid teams&lt;br /&gt;
    assign_reviewers_for_team(assignment_id,student_review_num,participants_hash,&lt;br /&gt;
                              exact_num_of_review_needed)&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  def assign_reviewers_for_team(assignment_id,student_review_num,participants_hash,&lt;br /&gt;
                                exact_num_of_review_needed)&lt;br /&gt;
    if ReviewResponseMap.where([&amp;quot;reviewed_object_id = ? and created_at &amp;gt; ? and calibrate_to = ?&amp;quot;, &lt;br /&gt;
                                assignment_id, &lt;br /&gt;
                                @@time_create_last_review_mapping_record, 0]).size &amp;lt; exact_num_of_review_needed&lt;br /&gt;
      participants_with_insufficient_review_num = []&lt;br /&gt;
      participants_hash.each do |participant_id, review_num|&lt;br /&gt;
        participants_with_insufficient_review_num &amp;lt;&amp;lt; participant_id if review_num &amp;lt; student_review_num&lt;br /&gt;
      end&lt;br /&gt;
      unsorted_teams_hash = {}&lt;br /&gt;
      ReviewResponseMap.where([&amp;quot;reviewed_object_id = ? and calibrate_to = ?&amp;quot;, &lt;br /&gt;
                               assignment_id, 0]).each do |response_map|&lt;br /&gt;
        if unsorted_teams_hash.key? response_map.reviewee_id&lt;br /&gt;
          unsorted_teams_hash[response_map.reviewee_id] += 1&lt;br /&gt;
        else&lt;br /&gt;
          unsorted_teams_hash[response_map.reviewee_id] = 1&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
      teams_hash = unsorted_teams_hash.sort_by {|_, v| v }.to_h&lt;br /&gt;
      participants_with_insufficient_review_num.each do |participant_id|&lt;br /&gt;
        teams_hash.each do |team_id, _num_review_received|&lt;br /&gt;
          next if TeamsUser.exists?(team_id: team_id, &lt;br /&gt;
                                    user_id: Participant.find(participant_id).user_id)&lt;br /&gt;
          ReviewResponseMap.where(reviewee_id: team_id, reviewer_id: participant_id, &lt;br /&gt;
                                  reviewed_object_id: assignment_id).first_or_create&lt;br /&gt;
          teams_hash[team_id] += 1&lt;br /&gt;
          teams_hash = teams_hash.sort_by {|_, v| v }.to_h&lt;br /&gt;
          break&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
    @@time_create_last_review_mapping_record = ReviewResponseMap.&lt;br /&gt;
                                               where(reviewed_object_id: assignment_id).&lt;br /&gt;
                                               last.created_at&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def execute_peer_review_strategy(assignment_id, teams, num_participants, &lt;br /&gt;
                                   student_review_num, num_reviews_per_team, &lt;br /&gt;
                                   participants, participants_hash)&lt;br /&gt;
    # Exception detection: If instructor want to assign too many reviews done&lt;br /&gt;
    # by each student, there will be an error msg.&lt;br /&gt;
    if student_review_num &amp;gt;= teams.size&lt;br /&gt;
      flash[:error] = 'You cannot set the number of reviews done &lt;br /&gt;
      by each student to be greater than or equal to total number of teams &lt;br /&gt;
      [or &amp;quot;participants&amp;quot; if it is an individual assignment].'&lt;br /&gt;
    end&lt;br /&gt;
    peer_review_strategy(assignment_id, teams, num_participants, &lt;br /&gt;
                         student_review_num, num_reviews_per_team, &lt;br /&gt;
                         participants, participants_hash)&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
=Test=&lt;br /&gt;
We write RSpec feature tests to prove that all changes are correct and the project performs well as before.&lt;br /&gt;
&lt;br /&gt;
The function of  method automatic_review_mapping is to automatically assign reviews on students in teams when instructor set either student review number or submissions review number. There is constraint that only one of the two numbers must be set value other than 0 (that is, one is 0 and other is not 0). To test the correctness  of our refactoring, we design a scenario and 4 cases of assigning reviews to students:&lt;br /&gt;
&lt;br /&gt;
Case 1. Instructor has not set both students review number and submissions review number (They are both 0). The page will show a notice.&lt;br /&gt;
&lt;br /&gt;
Case 2. Instructor set both numbers (They are both not 0). The page will show a notice.&lt;br /&gt;
&lt;br /&gt;
Case 3. Instructors set students review number. The controller will change database: create new relationship in ReviewResponseMap. For example, if assign student review number to 2, and there will be 20 peer reviews in total and need to allocate to 3 teams. So each team get 7 reviews on average and 1 team’s artifact will be reviewed 6 times.&lt;br /&gt;
&lt;br /&gt;
Case 4. Instructors set submissions review number. The controller will change database: create new relationship in ReviewResponseMap. For example, if assign submission review number to 3, and there will be 21 peer reviews in total to allocate to 10 participants. So every participants get 2 reviews. 9 among 10 participants will review 2 teams’ artifacts and 1 participant will review 3 teams’ artifacts.&lt;br /&gt;
&lt;br /&gt;
require 'rails_helper'&lt;br /&gt;
  describe &amp;quot;review mapping&amp;quot;, js: true do&lt;br /&gt;
    before(:each) do&lt;br /&gt;
      #create test data&lt;br /&gt;
    end&lt;br /&gt;
 &lt;br /&gt;
    it &amp;quot;show error when assign both 0&amp;quot; do&lt;br /&gt;
      login_as(&amp;quot;instructor6&amp;quot;)&lt;br /&gt;
      visit '/assignments/1/edit'&lt;br /&gt;
      find_link('ReviewStrategy').click&lt;br /&gt;
      select &amp;quot;Instructor-Selected&amp;quot;, from: 'assignment_form_assignment_review_assignment_strategy'&lt;br /&gt;
      fill_in 'num_reviews_per_student', with: 0&lt;br /&gt;
      choose 'num_reviews_submission'&lt;br /&gt;
      fill_in 'num_reviews_per_submission', with: 0&lt;br /&gt;
      click_button 'second_submit_tag'&lt;br /&gt;
      #click_button 'Save'&lt;br /&gt;
      expect(page).to have_content('Please choose either the number of reviews per student or the number of reviewers per team (student)')&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    it &amp;quot;show error when assign both numbers&amp;quot; do&lt;br /&gt;
      login_as(&amp;quot;instructor6&amp;quot;)&lt;br /&gt;
      visit '/assignments/1/edit'&lt;br /&gt;
      find_link('ReviewStrategy').click&lt;br /&gt;
      select &amp;quot;Instructor-Selected&amp;quot;, from: 'assignment_form_assignment_review_assignment_strategy'&lt;br /&gt;
      fill_in 'num_reviews_per_student', with: 1&lt;br /&gt;
      choose 'num_reviews_submission'&lt;br /&gt;
      fill_in 'num_reviews_per_submission', with: 1&lt;br /&gt;
      click_button 'second_submit_tag'&lt;br /&gt;
      #click_button 'Save'&lt;br /&gt;
      expect(page).to have_content('Please choose either the number of reviews per student or the number of reviewers per team (student), not both')&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    it &amp;quot;calculate reviewmapping from given review number per student&amp;quot; do&lt;br /&gt;
      login_as(&amp;quot;instructor6&amp;quot;)&lt;br /&gt;
      visit '/assignments/1/edit'&lt;br /&gt;
      find_link('ReviewStrategy').click&lt;br /&gt;
      select &amp;quot;Instructor-Selected&amp;quot;, from: 'assignment_form_assignment_review_assignment_strategy'&lt;br /&gt;
      fill_in 'num_reviews_per_student', with: 2&lt;br /&gt;
      click_button 'first_submit_tag'&lt;br /&gt;
      num = ReviewResponseMap.where(reviewee_id: @team1.id, reviewed_object_id: @assignment.id).count&lt;br /&gt;
      expect(num).to eq(7)&lt;br /&gt;
      num2 = ReviewResponseMap.where(reviewee_id: @team3.id, reviewed_object_id: @assignment.id).count&lt;br /&gt;
      expect(num2).to eq(6)&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    it &amp;quot;calculate reviewmapping from given review number per submission&amp;quot; do&lt;br /&gt;
      login_as(&amp;quot;instructor6&amp;quot;)&lt;br /&gt;
      visit '/assignments/1/edit'&lt;br /&gt;
      find_link('ReviewStrategy').click&lt;br /&gt;
      select &amp;quot;Instructor-Selected&amp;quot;, from: 'assignment_form_assignment_review_assignment_strategy'&lt;br /&gt;
      choose 'num_reviews_submission'&lt;br /&gt;
      fill_in 'num_reviews_per_submission', with: 7&lt;br /&gt;
      click_button 'second_submit_tag'&lt;br /&gt;
      #click_button 'Save'&lt;br /&gt;
      num = ReviewResponseMap.where(reviewer_id: @teamuser1.id, reviewed_object_id: @assignment.id).count&lt;br /&gt;
      expect(num).to eq(2)&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;/div&gt;</summary>
		<author><name>Jdeng8</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2016/E1641._Refactor_review_mapping_controller.rb&amp;diff=103940</id>
		<title>CSC/ECE 517 Fall 2016/E1641. Refactor review mapping controller.rb</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2016/E1641._Refactor_review_mapping_controller.rb&amp;diff=103940"/>
		<updated>2016-10-29T05:40:40Z</updated>

		<summary type="html">&lt;p&gt;Jdeng8: /* Current Implementation and Problems */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=Background=&lt;br /&gt;
&lt;br /&gt;
This controller sets up mappings between reviewer and reviewee. It handles all different types of response maps (review response map, author feedback response map, teammate review response map, meta review response map and quiz response map). The class has functionality for five different kinds of Responses: reviews, metareviews, teammate reviews, author feedback (“rejoinders”), and quizzes. &lt;br /&gt;
&lt;br /&gt;
=Current Implementation and Problems=&lt;br /&gt;
&lt;br /&gt;
# Method ''response_report'' has some [[#SQL|SQL]] - like code.  Rewrite with Active Record.&lt;br /&gt;
# Test whether method ''add_user_to_assignment'' is used. There is no way that this method should be in ReviewMappingController. Please remove this method and caller.&lt;br /&gt;
# There was a ''self-review'' feature, the method ''add_self_reviewer'', ''get_team_from_submission'' are related to this. Two views calls ''add_self_reviewer'' are &amp;quot;show_available_submissions_for_quizzes.html.erb&amp;quot; and &amp;quot;show_available_submissions.html.erb&amp;quot;. The names of views are not related to ''self_review'' feature. Plus those two views are not called anywhere. Please verify this and if so, you should delete those two views, two method and also related records (e.g. in routes.rb).&lt;br /&gt;
# Method ''delete_all_reviewers'' actually only deletes the outstanding review response maps (the ones which has been initiated, but there is no response yet). So it should better be named ''delete_outstanding_reviewers''. You can try to test this method by clicking “Assign reviewers” icon on an assignment.&lt;br /&gt;
# Method ''release_reservation'' should be renamed as'' release_mapping''. In addition, delete it if you find this method is not called anywhere.&lt;br /&gt;
# Method ''delete_mappings'' is problematic. It does not looks like a controller method. Please refactor it or delete it if you can validate that this method is not called anywhere.&lt;br /&gt;
# Method'' automatic_review_mapping_strategy'' is too long. Please refactor and test it.&lt;br /&gt;
&lt;br /&gt;
=Changes Implemented=&lt;br /&gt;
&lt;br /&gt;
# change the rails query from sql like code, like ReviewResponseMap.where(['reviewee_id = ? and reviewer_id = ? ', params[:contributor_id], reviewer.id]) to more rails quey like ReviewResponseMap.where(reviewee_id: params[:contributor_id],reviewer_id: reviewer.id)&lt;br /&gt;
# We search the function name(''add_user_to_assignment'') in the whole files, and find that this method is invoked in &amp;quot;participants_helper.rb&amp;quot;, and also being invoked in the function of ''add_reviewer'' and ''add_metareviewer'' in the controller of ''review_mapping_controller'' &lt;br /&gt;
# By searching the whole project and routes, we verify that methods ''add_self_reviewer'' and ''get_team_from_submission'' in this controller are not called by any other methods except for views &amp;quot;show_available_submissions_for_quizzes.html.erb&amp;quot; and &amp;quot;show_available_submissions.html.erb&amp;quot;. And those two views are not linked to any other views. So they are deleted from the project.&lt;br /&gt;
# We already renamed method ''delete_all_reviewers'' to ''delete_outstanding_reviewers'' and changed the corresponding button name at the corresponding view (_list_review_mappings.html.erb).&lt;br /&gt;
# By searching the whole project and routes, we verify that methods'' release_reservation'' in this controller are not used in anywhere.&lt;br /&gt;
# By searching the whole project and routes, we verify that methods ''delete_mappings'' in this controller are not used in anywhere.&lt;br /&gt;
# Method ''automatic_review_mapping_strategy'' have many long lines. We already shorten each long line to multiple lines. And also, we split this long function into three different functions.&lt;br /&gt;
&lt;br /&gt;
=Code=&lt;br /&gt;
&lt;br /&gt;
==Refactor SQL query code==&lt;br /&gt;
&lt;br /&gt;
The rails query we change in this controller:&lt;br /&gt;
&lt;br /&gt;
1. From &lt;br /&gt;
&lt;br /&gt;
  ReviewResponseMap.where(['reviewee_id = ? and reviewer_id = ? ', params[:contributor_id], reviewer.id]) &lt;br /&gt;
&lt;br /&gt;
To&lt;br /&gt;
&lt;br /&gt;
  ReviewResponseMap.where(reviewee_id: params[:contributor_id],reviewer_id: reviewer.id)&lt;br /&gt;
&lt;br /&gt;
2. From&lt;br /&gt;
&lt;br /&gt;
  MetareviewResponseMap.where(['reviewed_object_id = ? and reviewer_id = ?', mapping.map_id, reviewer.id])&lt;br /&gt;
&lt;br /&gt;
To&lt;br /&gt;
&lt;br /&gt;
  MetareviewResponseMap.where(reviewed_object_id: mapping.map_id, reviewer_id: reviewer.id)&lt;br /&gt;
&lt;br /&gt;
3. From&lt;br /&gt;
&lt;br /&gt;
                   @assignments = Assignment&lt;br /&gt;
                   .where([&amp;quot;instructor_id = ? and substring(name,1,1) = ?&amp;quot;, session[:user].id, letter])&lt;br /&gt;
                   .order('name')&lt;br /&gt;
                   .page(params[:page])&lt;br /&gt;
                   .per_page(10)&lt;br /&gt;
&lt;br /&gt;
To &lt;br /&gt;
&lt;br /&gt;
                   @assignments = Assignment&lt;br /&gt;
                   .where(instructor_id:session[:user].id)&lt;br /&gt;
                   .where(&amp;quot;substring(name,1,1) = :letter&amp;quot;,{letter:letter})&lt;br /&gt;
                   .order('name')&lt;br /&gt;
                   .page(params[:page])&lt;br /&gt;
                   .per_page(10)&lt;br /&gt;
&lt;br /&gt;
4.  From&lt;br /&gt;
&lt;br /&gt;
  ReviewResponseMap.where([&amp;quot;reviewed_object_id = ? and calibrate_to = ?&amp;quot;, assignment_id, 1])&lt;br /&gt;
&lt;br /&gt;
To &lt;br /&gt;
&lt;br /&gt;
  ReviewResponseMap.where(reviewed_object_id:assignment_id, calibrate_to: 1)&lt;br /&gt;
&lt;br /&gt;
5. From&lt;br /&gt;
&lt;br /&gt;
  ReviewResponseMap.where([&amp;quot;reviewed_object_id = ? and created_at &amp;gt; ? and calibrate_to = ?&amp;quot;, assignment_id, @@time_create_last_review_mapping_record, 0])&lt;br /&gt;
&lt;br /&gt;
To &lt;br /&gt;
&lt;br /&gt;
  ReviewResponseMap.where(reviewed_object_id:assignment_id,calibrate_to:0).where(&amp;quot;created_at &amp;gt; :time&amp;quot;,{time:@@time_create_last_review_mapping_record})&lt;br /&gt;
&lt;br /&gt;
6. From&lt;br /&gt;
&lt;br /&gt;
  AssignmentQuestionnaire.where([&amp;quot;assignment_id = ? and questionnaire_id IN (?)&amp;quot;, params[:id], @review_questionnaire_ids])&lt;br /&gt;
&lt;br /&gt;
To&lt;br /&gt;
 &lt;br /&gt;
  AssignmentQuestionnaire.where(assignment_id: params[:id],:questionnaire_id =&amp;gt; @review_questionnaire_ids)&lt;br /&gt;
&lt;br /&gt;
7. From&lt;br /&gt;
&lt;br /&gt;
  SelfReviewResponseMap.where(['reviewee_id = ? and reviewer_id = ?', team_id[0].t_id, params[:reviewer_id]])&lt;br /&gt;
&lt;br /&gt;
To &lt;br /&gt;
&lt;br /&gt;
  SelfReviewResponseMap.where(reviewee_id:team_id[0].t_id,reviewer_id:params[:reviewer_id])&lt;br /&gt;
&lt;br /&gt;
==Refactor long line method==&lt;br /&gt;
&lt;br /&gt;
  def automatic_review_mapping_strategy(assignment_id,&lt;br /&gt;
                                        participants, teams, student_review_num = 0,&lt;br /&gt;
                                        submission_review_num = 0)&lt;br /&gt;
    participants_hash = {}&lt;br /&gt;
    participants.each {|participant| participants_hash[participant.id] = 0 }&lt;br /&gt;
    # calculate reviewers for each team&lt;br /&gt;
    num_participants = participants.size&lt;br /&gt;
    if student_review_num != 0 and submission_review_num == 0&lt;br /&gt;
      num_reviews_per_team = (participants.size * student_review_num * 1.0 / teams.size).round&lt;br /&gt;
      student_review_num = student_review_num&lt;br /&gt;
      exact_num_of_review_needed = participants.size * student_review_num&lt;br /&gt;
    elsif student_review_num == 0 and submission_review_num != 0&lt;br /&gt;
      num_reviews_per_team = submission_review_num&lt;br /&gt;
      student_review_num = (teams.size * submission_review_num * 1.0 / participants.size).round&lt;br /&gt;
      exact_num_of_review_needed = teams.size * submission_review_num&lt;br /&gt;
    end&lt;br /&gt;
    execute_peer_review_strategy(assignment_id, teams, num_participants,&lt;br /&gt;
                                     student_review_num, num_reviews_per_team,&lt;br /&gt;
                                     participants, participants_hash)&lt;br /&gt;
    # after assigning peer reviews for each team,&lt;br /&gt;
    # if there are still some peer reviewers not obtain enough peer review,&lt;br /&gt;
    # just assign them to valid teams&lt;br /&gt;
    assign_reviewers_for_team(assignment_id,student_review_num,participants_hash,&lt;br /&gt;
                              exact_num_of_review_needed)&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  def assign_reviewers_for_team(assignment_id,student_review_num,participants_hash,&lt;br /&gt;
                                exact_num_of_review_needed)&lt;br /&gt;
    if ReviewResponseMap.where([&amp;quot;reviewed_object_id = ? and created_at &amp;gt; ? and calibrate_to = ?&amp;quot;, &lt;br /&gt;
                                assignment_id, &lt;br /&gt;
                                @@time_create_last_review_mapping_record, 0]).size &amp;lt; exact_num_of_review_needed&lt;br /&gt;
      participants_with_insufficient_review_num = []&lt;br /&gt;
      participants_hash.each do |participant_id, review_num|&lt;br /&gt;
        participants_with_insufficient_review_num &amp;lt;&amp;lt; participant_id if review_num &amp;lt; student_review_num&lt;br /&gt;
      end&lt;br /&gt;
      unsorted_teams_hash = {}&lt;br /&gt;
      ReviewResponseMap.where([&amp;quot;reviewed_object_id = ? and calibrate_to = ?&amp;quot;, &lt;br /&gt;
                               assignment_id, 0]).each do |response_map|&lt;br /&gt;
        if unsorted_teams_hash.key? response_map.reviewee_id&lt;br /&gt;
          unsorted_teams_hash[response_map.reviewee_id] += 1&lt;br /&gt;
        else&lt;br /&gt;
          unsorted_teams_hash[response_map.reviewee_id] = 1&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
      teams_hash = unsorted_teams_hash.sort_by {|_, v| v }.to_h&lt;br /&gt;
      participants_with_insufficient_review_num.each do |participant_id|&lt;br /&gt;
        teams_hash.each do |team_id, _num_review_received|&lt;br /&gt;
          next if TeamsUser.exists?(team_id: team_id, &lt;br /&gt;
                                    user_id: Participant.find(participant_id).user_id)&lt;br /&gt;
          ReviewResponseMap.where(reviewee_id: team_id, reviewer_id: participant_id, &lt;br /&gt;
                                  reviewed_object_id: assignment_id).first_or_create&lt;br /&gt;
          teams_hash[team_id] += 1&lt;br /&gt;
          teams_hash = teams_hash.sort_by {|_, v| v }.to_h&lt;br /&gt;
          break&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
    @@time_create_last_review_mapping_record = ReviewResponseMap.&lt;br /&gt;
                                               where(reviewed_object_id: assignment_id).&lt;br /&gt;
                                               last.created_at&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def execute_peer_review_strategy(assignment_id, teams, num_participants, &lt;br /&gt;
                                   student_review_num, num_reviews_per_team, &lt;br /&gt;
                                   participants, participants_hash)&lt;br /&gt;
    # Exception detection: If instructor want to assign too many reviews done&lt;br /&gt;
    # by each student, there will be an error msg.&lt;br /&gt;
    if student_review_num &amp;gt;= teams.size&lt;br /&gt;
      flash[:error] = 'You cannot set the number of reviews done &lt;br /&gt;
      by each student to be greater than or equal to total number of teams &lt;br /&gt;
      [or &amp;quot;participants&amp;quot; if it is an individual assignment].'&lt;br /&gt;
    end&lt;br /&gt;
    peer_review_strategy(assignment_id, teams, num_participants, &lt;br /&gt;
                         student_review_num, num_reviews_per_team, &lt;br /&gt;
                         participants, participants_hash)&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
=Test=&lt;br /&gt;
We write RSpec feature tests to prove that all changes are correct and the project performs well as before.&lt;br /&gt;
&lt;br /&gt;
The function of  method automatic_review_mapping is to automatically assign reviews on students in teams when instructor set either student review number or submissions review number. There is constraint that only one of the two numbers must be set value other than 0 (that is, one is 0 and other is not 0). To test the correctness  of our refactoring, we design a scenario and 4 cases of assigning reviews to students:&lt;br /&gt;
&lt;br /&gt;
Case 1. Instructor has not set both students review number and submissions review number (They are both 0). The page will show a notice.&lt;br /&gt;
&lt;br /&gt;
Case 2. Instructor set both numbers (They are both not 0). The page will show a notice.&lt;br /&gt;
&lt;br /&gt;
Case 3. Instructors set students review number. The controller will change database: create new relationship in ReviewResponseMap. For example, if assign student review number to 2, and there will be 20 peer reviews in total and need to allocate to 3 teams. So each team get 7 reviews on average and 1 team’s artifact will be reviewed 6 times.&lt;br /&gt;
&lt;br /&gt;
Case 4. Instructors set submissions review number. The controller will change database: create new relationship in ReviewResponseMap. For example, if assign submission review number to 3, and there will be 21 peer reviews in total to allocate to 10 participants. So every participants get 2 reviews. 9 among 10 participants will review 2 teams’ artifacts and 1 participant will review 3 teams’ artifacts.&lt;br /&gt;
&lt;br /&gt;
require 'rails_helper'&lt;br /&gt;
  describe &amp;quot;review mapping&amp;quot;, js: true do&lt;br /&gt;
    before(:each) do&lt;br /&gt;
      #create test data&lt;br /&gt;
    end&lt;br /&gt;
 &lt;br /&gt;
    it &amp;quot;show error when assign both 0&amp;quot; do&lt;br /&gt;
      login_as(&amp;quot;instructor6&amp;quot;)&lt;br /&gt;
      visit '/assignments/1/edit'&lt;br /&gt;
      find_link('ReviewStrategy').click&lt;br /&gt;
      select &amp;quot;Instructor-Selected&amp;quot;, from: 'assignment_form_assignment_review_assignment_strategy'&lt;br /&gt;
      fill_in 'num_reviews_per_student', with: 0&lt;br /&gt;
      choose 'num_reviews_submission'&lt;br /&gt;
      fill_in 'num_reviews_per_submission', with: 0&lt;br /&gt;
      click_button 'second_submit_tag'&lt;br /&gt;
      #click_button 'Save'&lt;br /&gt;
      expect(page).to have_content('Please choose either the number of reviews per student or the number of reviewers per team (student)')&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    it &amp;quot;show error when assign both numbers&amp;quot; do&lt;br /&gt;
      login_as(&amp;quot;instructor6&amp;quot;)&lt;br /&gt;
      visit '/assignments/1/edit'&lt;br /&gt;
      find_link('ReviewStrategy').click&lt;br /&gt;
      select &amp;quot;Instructor-Selected&amp;quot;, from: 'assignment_form_assignment_review_assignment_strategy'&lt;br /&gt;
      fill_in 'num_reviews_per_student', with: 1&lt;br /&gt;
      choose 'num_reviews_submission'&lt;br /&gt;
      fill_in 'num_reviews_per_submission', with: 1&lt;br /&gt;
      click_button 'second_submit_tag'&lt;br /&gt;
      #click_button 'Save'&lt;br /&gt;
      expect(page).to have_content('Please choose either the number of reviews per student or the number of reviewers per team (student), not both')&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    it &amp;quot;calculate reviewmapping from given review number per student&amp;quot; do&lt;br /&gt;
      login_as(&amp;quot;instructor6&amp;quot;)&lt;br /&gt;
      visit '/assignments/1/edit'&lt;br /&gt;
      find_link('ReviewStrategy').click&lt;br /&gt;
      select &amp;quot;Instructor-Selected&amp;quot;, from: 'assignment_form_assignment_review_assignment_strategy'&lt;br /&gt;
      fill_in 'num_reviews_per_student', with: 2&lt;br /&gt;
      click_button 'first_submit_tag'&lt;br /&gt;
      num = ReviewResponseMap.where(reviewee_id: @team1.id, reviewed_object_id: @assignment.id).count&lt;br /&gt;
      expect(num).to eq(7)&lt;br /&gt;
      num2 = ReviewResponseMap.where(reviewee_id: @team3.id, reviewed_object_id: @assignment.id).count&lt;br /&gt;
      expect(num2).to eq(6)&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    it &amp;quot;calculate reviewmapping from given review number per submission&amp;quot; do&lt;br /&gt;
      login_as(&amp;quot;instructor6&amp;quot;)&lt;br /&gt;
      visit '/assignments/1/edit'&lt;br /&gt;
      find_link('ReviewStrategy').click&lt;br /&gt;
      select &amp;quot;Instructor-Selected&amp;quot;, from: 'assignment_form_assignment_review_assignment_strategy'&lt;br /&gt;
      choose 'num_reviews_submission'&lt;br /&gt;
      fill_in 'num_reviews_per_submission', with: 7&lt;br /&gt;
      click_button 'second_submit_tag'&lt;br /&gt;
      #click_button 'Save'&lt;br /&gt;
      num = ReviewResponseMap.where(reviewer_id: @teamuser1.id, reviewed_object_id: @assignment.id).count&lt;br /&gt;
      expect(num).to eq(2)&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;/div&gt;</summary>
		<author><name>Jdeng8</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2016/E1641._Refactor_review_mapping_controller.rb&amp;diff=103938</id>
		<title>CSC/ECE 517 Fall 2016/E1641. Refactor review mapping controller.rb</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2016/E1641._Refactor_review_mapping_controller.rb&amp;diff=103938"/>
		<updated>2016-10-29T05:39:47Z</updated>

		<summary type="html">&lt;p&gt;Jdeng8: /* Current Implementation and Problems */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=Background=&lt;br /&gt;
&lt;br /&gt;
This controller sets up mappings between reviewer and reviewee. It handles all different types of response maps (review response map, author feedback response map, teammate review response map, meta review response map and quiz response map). The class has functionality for five different kinds of Responses: reviews, metareviews, teammate reviews, author feedback (“rejoinders”), and quizzes. &lt;br /&gt;
&lt;br /&gt;
=Current Implementation and Problems=&lt;br /&gt;
&lt;br /&gt;
# Method ''response_report'' has some SQL[SQL] - like code.  Rewrite with Active Record.&lt;br /&gt;
# Test whether method ''add_user_to_assignment'' is used. There is no way that this method should be in ReviewMappingController. Please remove this method and caller.&lt;br /&gt;
# There was a ''self-review'' feature, the method ''add_self_reviewer'', ''get_team_from_submission'' are related to this. Two views calls ''add_self_reviewer'' are &amp;quot;show_available_submissions_for_quizzes.html.erb&amp;quot; and &amp;quot;show_available_submissions.html.erb&amp;quot;. The names of views are not related to ''self_review'' feature. Plus those two views are not called anywhere. Please verify this and if so, you should delete those two views, two method and also related records (e.g. in routes.rb).&lt;br /&gt;
# Method ''delete_all_reviewers'' actually only deletes the outstanding review response maps (the ones which has been initiated, but there is no response yet). So it should better be named ''delete_outstanding_reviewers''. You can try to test this method by clicking “Assign reviewers” icon on an assignment.&lt;br /&gt;
# Method ''release_reservation'' should be renamed as'' release_mapping''. In addition, delete it if you find this method is not called anywhere.&lt;br /&gt;
# Method ''delete_mappings'' is problematic. It does not looks like a controller method. Please refactor it or delete it if you can validate that this method is not called anywhere.&lt;br /&gt;
# Method'' automatic_review_mapping_strategy'' is too long. Please refactor and test it.&lt;br /&gt;
&lt;br /&gt;
=Changes Implemented=&lt;br /&gt;
&lt;br /&gt;
# change the rails query from sql like code, like ReviewResponseMap.where(['reviewee_id = ? and reviewer_id = ? ', params[:contributor_id], reviewer.id]) to more rails quey like ReviewResponseMap.where(reviewee_id: params[:contributor_id],reviewer_id: reviewer.id)&lt;br /&gt;
# We search the function name(''add_user_to_assignment'') in the whole files, and find that this method is invoked in &amp;quot;participants_helper.rb&amp;quot;, and also being invoked in the function of ''add_reviewer'' and ''add_metareviewer'' in the controller of ''review_mapping_controller'' &lt;br /&gt;
# By searching the whole project and routes, we verify that methods ''add_self_reviewer'' and ''get_team_from_submission'' in this controller are not called by any other methods except for views &amp;quot;show_available_submissions_for_quizzes.html.erb&amp;quot; and &amp;quot;show_available_submissions.html.erb&amp;quot;. And those two views are not linked to any other views. So they are deleted from the project.&lt;br /&gt;
# We already renamed method ''delete_all_reviewers'' to ''delete_outstanding_reviewers'' and changed the corresponding button name at the corresponding view (_list_review_mappings.html.erb).&lt;br /&gt;
# By searching the whole project and routes, we verify that methods'' release_reservation'' in this controller are not used in anywhere.&lt;br /&gt;
# By searching the whole project and routes, we verify that methods ''delete_mappings'' in this controller are not used in anywhere.&lt;br /&gt;
# Method ''automatic_review_mapping_strategy'' have many long lines. We already shorten each long line to multiple lines. And also, we split this long function into three different functions.&lt;br /&gt;
&lt;br /&gt;
=Code=&lt;br /&gt;
&lt;br /&gt;
==Refactor SQL query code==&lt;br /&gt;
&lt;br /&gt;
The rails query we change in this controller:&lt;br /&gt;
&lt;br /&gt;
1. From &lt;br /&gt;
&lt;br /&gt;
  ReviewResponseMap.where(['reviewee_id = ? and reviewer_id = ? ', params[:contributor_id], reviewer.id]) &lt;br /&gt;
&lt;br /&gt;
To&lt;br /&gt;
&lt;br /&gt;
  ReviewResponseMap.where(reviewee_id: params[:contributor_id],reviewer_id: reviewer.id)&lt;br /&gt;
&lt;br /&gt;
2. From&lt;br /&gt;
&lt;br /&gt;
  MetareviewResponseMap.where(['reviewed_object_id = ? and reviewer_id = ?', mapping.map_id, reviewer.id])&lt;br /&gt;
&lt;br /&gt;
To&lt;br /&gt;
&lt;br /&gt;
  MetareviewResponseMap.where(reviewed_object_id: mapping.map_id, reviewer_id: reviewer.id)&lt;br /&gt;
&lt;br /&gt;
3. From&lt;br /&gt;
&lt;br /&gt;
                   @assignments = Assignment&lt;br /&gt;
                   .where([&amp;quot;instructor_id = ? and substring(name,1,1) = ?&amp;quot;, session[:user].id, letter])&lt;br /&gt;
                   .order('name')&lt;br /&gt;
                   .page(params[:page])&lt;br /&gt;
                   .per_page(10)&lt;br /&gt;
&lt;br /&gt;
To &lt;br /&gt;
&lt;br /&gt;
                   @assignments = Assignment&lt;br /&gt;
                   .where(instructor_id:session[:user].id)&lt;br /&gt;
                   .where(&amp;quot;substring(name,1,1) = :letter&amp;quot;,{letter:letter})&lt;br /&gt;
                   .order('name')&lt;br /&gt;
                   .page(params[:page])&lt;br /&gt;
                   .per_page(10)&lt;br /&gt;
&lt;br /&gt;
4.  From&lt;br /&gt;
&lt;br /&gt;
  ReviewResponseMap.where([&amp;quot;reviewed_object_id = ? and calibrate_to = ?&amp;quot;, assignment_id, 1])&lt;br /&gt;
&lt;br /&gt;
To &lt;br /&gt;
&lt;br /&gt;
  ReviewResponseMap.where(reviewed_object_id:assignment_id, calibrate_to: 1)&lt;br /&gt;
&lt;br /&gt;
5. From&lt;br /&gt;
&lt;br /&gt;
  ReviewResponseMap.where([&amp;quot;reviewed_object_id = ? and created_at &amp;gt; ? and calibrate_to = ?&amp;quot;, assignment_id, @@time_create_last_review_mapping_record, 0])&lt;br /&gt;
&lt;br /&gt;
To &lt;br /&gt;
&lt;br /&gt;
  ReviewResponseMap.where(reviewed_object_id:assignment_id,calibrate_to:0).where(&amp;quot;created_at &amp;gt; :time&amp;quot;,{time:@@time_create_last_review_mapping_record})&lt;br /&gt;
&lt;br /&gt;
6. From&lt;br /&gt;
&lt;br /&gt;
  AssignmentQuestionnaire.where([&amp;quot;assignment_id = ? and questionnaire_id IN (?)&amp;quot;, params[:id], @review_questionnaire_ids])&lt;br /&gt;
&lt;br /&gt;
To&lt;br /&gt;
 &lt;br /&gt;
  AssignmentQuestionnaire.where(assignment_id: params[:id],:questionnaire_id =&amp;gt; @review_questionnaire_ids)&lt;br /&gt;
&lt;br /&gt;
7. From&lt;br /&gt;
&lt;br /&gt;
  SelfReviewResponseMap.where(['reviewee_id = ? and reviewer_id = ?', team_id[0].t_id, params[:reviewer_id]])&lt;br /&gt;
&lt;br /&gt;
To &lt;br /&gt;
&lt;br /&gt;
  SelfReviewResponseMap.where(reviewee_id:team_id[0].t_id,reviewer_id:params[:reviewer_id])&lt;br /&gt;
&lt;br /&gt;
==Refactor long line method==&lt;br /&gt;
&lt;br /&gt;
  def automatic_review_mapping_strategy(assignment_id,&lt;br /&gt;
                                        participants, teams, student_review_num = 0,&lt;br /&gt;
                                        submission_review_num = 0)&lt;br /&gt;
    participants_hash = {}&lt;br /&gt;
    participants.each {|participant| participants_hash[participant.id] = 0 }&lt;br /&gt;
    # calculate reviewers for each team&lt;br /&gt;
    num_participants = participants.size&lt;br /&gt;
    if student_review_num != 0 and submission_review_num == 0&lt;br /&gt;
      num_reviews_per_team = (participants.size * student_review_num * 1.0 / teams.size).round&lt;br /&gt;
      student_review_num = student_review_num&lt;br /&gt;
      exact_num_of_review_needed = participants.size * student_review_num&lt;br /&gt;
    elsif student_review_num == 0 and submission_review_num != 0&lt;br /&gt;
      num_reviews_per_team = submission_review_num&lt;br /&gt;
      student_review_num = (teams.size * submission_review_num * 1.0 / participants.size).round&lt;br /&gt;
      exact_num_of_review_needed = teams.size * submission_review_num&lt;br /&gt;
    end&lt;br /&gt;
    execute_peer_review_strategy(assignment_id, teams, num_participants,&lt;br /&gt;
                                     student_review_num, num_reviews_per_team,&lt;br /&gt;
                                     participants, participants_hash)&lt;br /&gt;
    # after assigning peer reviews for each team,&lt;br /&gt;
    # if there are still some peer reviewers not obtain enough peer review,&lt;br /&gt;
    # just assign them to valid teams&lt;br /&gt;
    assign_reviewers_for_team(assignment_id,student_review_num,participants_hash,&lt;br /&gt;
                              exact_num_of_review_needed)&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  def assign_reviewers_for_team(assignment_id,student_review_num,participants_hash,&lt;br /&gt;
                                exact_num_of_review_needed)&lt;br /&gt;
    if ReviewResponseMap.where([&amp;quot;reviewed_object_id = ? and created_at &amp;gt; ? and calibrate_to = ?&amp;quot;, &lt;br /&gt;
                                assignment_id, &lt;br /&gt;
                                @@time_create_last_review_mapping_record, 0]).size &amp;lt; exact_num_of_review_needed&lt;br /&gt;
      participants_with_insufficient_review_num = []&lt;br /&gt;
      participants_hash.each do |participant_id, review_num|&lt;br /&gt;
        participants_with_insufficient_review_num &amp;lt;&amp;lt; participant_id if review_num &amp;lt; student_review_num&lt;br /&gt;
      end&lt;br /&gt;
      unsorted_teams_hash = {}&lt;br /&gt;
      ReviewResponseMap.where([&amp;quot;reviewed_object_id = ? and calibrate_to = ?&amp;quot;, &lt;br /&gt;
                               assignment_id, 0]).each do |response_map|&lt;br /&gt;
        if unsorted_teams_hash.key? response_map.reviewee_id&lt;br /&gt;
          unsorted_teams_hash[response_map.reviewee_id] += 1&lt;br /&gt;
        else&lt;br /&gt;
          unsorted_teams_hash[response_map.reviewee_id] = 1&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
      teams_hash = unsorted_teams_hash.sort_by {|_, v| v }.to_h&lt;br /&gt;
      participants_with_insufficient_review_num.each do |participant_id|&lt;br /&gt;
        teams_hash.each do |team_id, _num_review_received|&lt;br /&gt;
          next if TeamsUser.exists?(team_id: team_id, &lt;br /&gt;
                                    user_id: Participant.find(participant_id).user_id)&lt;br /&gt;
          ReviewResponseMap.where(reviewee_id: team_id, reviewer_id: participant_id, &lt;br /&gt;
                                  reviewed_object_id: assignment_id).first_or_create&lt;br /&gt;
          teams_hash[team_id] += 1&lt;br /&gt;
          teams_hash = teams_hash.sort_by {|_, v| v }.to_h&lt;br /&gt;
          break&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
    @@time_create_last_review_mapping_record = ReviewResponseMap.&lt;br /&gt;
                                               where(reviewed_object_id: assignment_id).&lt;br /&gt;
                                               last.created_at&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def execute_peer_review_strategy(assignment_id, teams, num_participants, &lt;br /&gt;
                                   student_review_num, num_reviews_per_team, &lt;br /&gt;
                                   participants, participants_hash)&lt;br /&gt;
    # Exception detection: If instructor want to assign too many reviews done&lt;br /&gt;
    # by each student, there will be an error msg.&lt;br /&gt;
    if student_review_num &amp;gt;= teams.size&lt;br /&gt;
      flash[:error] = 'You cannot set the number of reviews done &lt;br /&gt;
      by each student to be greater than or equal to total number of teams &lt;br /&gt;
      [or &amp;quot;participants&amp;quot; if it is an individual assignment].'&lt;br /&gt;
    end&lt;br /&gt;
    peer_review_strategy(assignment_id, teams, num_participants, &lt;br /&gt;
                         student_review_num, num_reviews_per_team, &lt;br /&gt;
                         participants, participants_hash)&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
=Test=&lt;br /&gt;
We write RSpec feature tests to prove that all changes are correct and the project performs well as before.&lt;br /&gt;
&lt;br /&gt;
The function of  method automatic_review_mapping is to automatically assign reviews on students in teams when instructor set either student review number or submissions review number. There is constraint that only one of the two numbers must be set value other than 0 (that is, one is 0 and other is not 0). To test the correctness  of our refactoring, we design a scenario and 4 cases of assigning reviews to students:&lt;br /&gt;
&lt;br /&gt;
Case 1. Instructor has not set both students review number and submissions review number (They are both 0). The page will show a notice.&lt;br /&gt;
&lt;br /&gt;
Case 2. Instructor set both numbers (They are both not 0). The page will show a notice.&lt;br /&gt;
&lt;br /&gt;
Case 3. Instructors set students review number. The controller will change database: create new relationship in ReviewResponseMap. For example, if assign student review number to 2, and there will be 20 peer reviews in total and need to allocate to 3 teams. So each team get 7 reviews on average and 1 team’s artifact will be reviewed 6 times.&lt;br /&gt;
&lt;br /&gt;
Case 4. Instructors set submissions review number. The controller will change database: create new relationship in ReviewResponseMap. For example, if assign submission review number to 3, and there will be 21 peer reviews in total to allocate to 10 participants. So every participants get 2 reviews. 9 among 10 participants will review 2 teams’ artifacts and 1 participant will review 3 teams’ artifacts.&lt;br /&gt;
&lt;br /&gt;
require 'rails_helper'&lt;br /&gt;
  describe &amp;quot;review mapping&amp;quot;, js: true do&lt;br /&gt;
    before(:each) do&lt;br /&gt;
      #create test data&lt;br /&gt;
    end&lt;br /&gt;
 &lt;br /&gt;
    it &amp;quot;show error when assign both 0&amp;quot; do&lt;br /&gt;
      login_as(&amp;quot;instructor6&amp;quot;)&lt;br /&gt;
      visit '/assignments/1/edit'&lt;br /&gt;
      find_link('ReviewStrategy').click&lt;br /&gt;
      select &amp;quot;Instructor-Selected&amp;quot;, from: 'assignment_form_assignment_review_assignment_strategy'&lt;br /&gt;
      fill_in 'num_reviews_per_student', with: 0&lt;br /&gt;
      choose 'num_reviews_submission'&lt;br /&gt;
      fill_in 'num_reviews_per_submission', with: 0&lt;br /&gt;
      click_button 'second_submit_tag'&lt;br /&gt;
      #click_button 'Save'&lt;br /&gt;
      expect(page).to have_content('Please choose either the number of reviews per student or the number of reviewers per team (student)')&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    it &amp;quot;show error when assign both numbers&amp;quot; do&lt;br /&gt;
      login_as(&amp;quot;instructor6&amp;quot;)&lt;br /&gt;
      visit '/assignments/1/edit'&lt;br /&gt;
      find_link('ReviewStrategy').click&lt;br /&gt;
      select &amp;quot;Instructor-Selected&amp;quot;, from: 'assignment_form_assignment_review_assignment_strategy'&lt;br /&gt;
      fill_in 'num_reviews_per_student', with: 1&lt;br /&gt;
      choose 'num_reviews_submission'&lt;br /&gt;
      fill_in 'num_reviews_per_submission', with: 1&lt;br /&gt;
      click_button 'second_submit_tag'&lt;br /&gt;
      #click_button 'Save'&lt;br /&gt;
      expect(page).to have_content('Please choose either the number of reviews per student or the number of reviewers per team (student), not both')&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    it &amp;quot;calculate reviewmapping from given review number per student&amp;quot; do&lt;br /&gt;
      login_as(&amp;quot;instructor6&amp;quot;)&lt;br /&gt;
      visit '/assignments/1/edit'&lt;br /&gt;
      find_link('ReviewStrategy').click&lt;br /&gt;
      select &amp;quot;Instructor-Selected&amp;quot;, from: 'assignment_form_assignment_review_assignment_strategy'&lt;br /&gt;
      fill_in 'num_reviews_per_student', with: 2&lt;br /&gt;
      click_button 'first_submit_tag'&lt;br /&gt;
      num = ReviewResponseMap.where(reviewee_id: @team1.id, reviewed_object_id: @assignment.id).count&lt;br /&gt;
      expect(num).to eq(7)&lt;br /&gt;
      num2 = ReviewResponseMap.where(reviewee_id: @team3.id, reviewed_object_id: @assignment.id).count&lt;br /&gt;
      expect(num2).to eq(6)&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    it &amp;quot;calculate reviewmapping from given review number per submission&amp;quot; do&lt;br /&gt;
      login_as(&amp;quot;instructor6&amp;quot;)&lt;br /&gt;
      visit '/assignments/1/edit'&lt;br /&gt;
      find_link('ReviewStrategy').click&lt;br /&gt;
      select &amp;quot;Instructor-Selected&amp;quot;, from: 'assignment_form_assignment_review_assignment_strategy'&lt;br /&gt;
      choose 'num_reviews_submission'&lt;br /&gt;
      fill_in 'num_reviews_per_submission', with: 7&lt;br /&gt;
      click_button 'second_submit_tag'&lt;br /&gt;
      #click_button 'Save'&lt;br /&gt;
      num = ReviewResponseMap.where(reviewer_id: @teamuser1.id, reviewed_object_id: @assignment.id).count&lt;br /&gt;
      expect(num).to eq(2)&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;/div&gt;</summary>
		<author><name>Jdeng8</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2016/E1641._Refactor_review_mapping_controller.rb&amp;diff=103936</id>
		<title>CSC/ECE 517 Fall 2016/E1641. Refactor review mapping controller.rb</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2016/E1641._Refactor_review_mapping_controller.rb&amp;diff=103936"/>
		<updated>2016-10-29T05:38:51Z</updated>

		<summary type="html">&lt;p&gt;Jdeng8: /* Current Implementation and Problems */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=Background=&lt;br /&gt;
&lt;br /&gt;
This controller sets up mappings between reviewer and reviewee. It handles all different types of response maps (review response map, author feedback response map, teammate review response map, meta review response map and quiz response map). The class has functionality for five different kinds of Responses: reviews, metareviews, teammate reviews, author feedback (“rejoinders”), and quizzes. &lt;br /&gt;
&lt;br /&gt;
=Current Implementation and Problems=&lt;br /&gt;
&lt;br /&gt;
# Method ''response_report'' has some [w:SQL|SQL] - like code.  Rewrite with Active Record.&lt;br /&gt;
# Test whether method ''add_user_to_assignment'' is used. There is no way that this method should be in ReviewMappingController. Please remove this method and caller.&lt;br /&gt;
# There was a ''self-review'' feature, the method ''add_self_reviewer'', ''get_team_from_submission'' are related to this. Two views calls ''add_self_reviewer'' are &amp;quot;show_available_submissions_for_quizzes.html.erb&amp;quot; and &amp;quot;show_available_submissions.html.erb&amp;quot;. The names of views are not related to ''self_review'' feature. Plus those two views are not called anywhere. Please verify this and if so, you should delete those two views, two method and also related records (e.g. in routes.rb).&lt;br /&gt;
# Method ''delete_all_reviewers'' actually only deletes the outstanding review response maps (the ones which has been initiated, but there is no response yet). So it should better be named ''delete_outstanding_reviewers''. You can try to test this method by clicking “Assign reviewers” icon on an assignment.&lt;br /&gt;
# Method ''release_reservation'' should be renamed as'' release_mapping''. In addition, delete it if you find this method is not called anywhere.&lt;br /&gt;
# Method ''delete_mappings'' is problematic. It does not looks like a controller method. Please refactor it or delete it if you can validate that this method is not called anywhere.&lt;br /&gt;
# Method'' automatic_review_mapping_strategy'' is too long. Please refactor and test it.&lt;br /&gt;
&lt;br /&gt;
=Changes Implemented=&lt;br /&gt;
&lt;br /&gt;
# change the rails query from sql like code, like ReviewResponseMap.where(['reviewee_id = ? and reviewer_id = ? ', params[:contributor_id], reviewer.id]) to more rails quey like ReviewResponseMap.where(reviewee_id: params[:contributor_id],reviewer_id: reviewer.id)&lt;br /&gt;
# We search the function name(''add_user_to_assignment'') in the whole files, and find that this method is invoked in &amp;quot;participants_helper.rb&amp;quot;, and also being invoked in the function of ''add_reviewer'' and ''add_metareviewer'' in the controller of ''review_mapping_controller'' &lt;br /&gt;
# By searching the whole project and routes, we verify that methods ''add_self_reviewer'' and ''get_team_from_submission'' in this controller are not called by any other methods except for views &amp;quot;show_available_submissions_for_quizzes.html.erb&amp;quot; and &amp;quot;show_available_submissions.html.erb&amp;quot;. And those two views are not linked to any other views. So they are deleted from the project.&lt;br /&gt;
# We already renamed method ''delete_all_reviewers'' to ''delete_outstanding_reviewers'' and changed the corresponding button name at the corresponding view (_list_review_mappings.html.erb).&lt;br /&gt;
# By searching the whole project and routes, we verify that methods'' release_reservation'' in this controller are not used in anywhere.&lt;br /&gt;
# By searching the whole project and routes, we verify that methods ''delete_mappings'' in this controller are not used in anywhere.&lt;br /&gt;
# Method ''automatic_review_mapping_strategy'' have many long lines. We already shorten each long line to multiple lines. And also, we split this long function into three different functions.&lt;br /&gt;
&lt;br /&gt;
=Code=&lt;br /&gt;
&lt;br /&gt;
==Refactor SQL query code==&lt;br /&gt;
&lt;br /&gt;
The rails query we change in this controller:&lt;br /&gt;
&lt;br /&gt;
1. From &lt;br /&gt;
&lt;br /&gt;
  ReviewResponseMap.where(['reviewee_id = ? and reviewer_id = ? ', params[:contributor_id], reviewer.id]) &lt;br /&gt;
&lt;br /&gt;
To&lt;br /&gt;
&lt;br /&gt;
  ReviewResponseMap.where(reviewee_id: params[:contributor_id],reviewer_id: reviewer.id)&lt;br /&gt;
&lt;br /&gt;
2. From&lt;br /&gt;
&lt;br /&gt;
  MetareviewResponseMap.where(['reviewed_object_id = ? and reviewer_id = ?', mapping.map_id, reviewer.id])&lt;br /&gt;
&lt;br /&gt;
To&lt;br /&gt;
&lt;br /&gt;
  MetareviewResponseMap.where(reviewed_object_id: mapping.map_id, reviewer_id: reviewer.id)&lt;br /&gt;
&lt;br /&gt;
3. From&lt;br /&gt;
&lt;br /&gt;
                   @assignments = Assignment&lt;br /&gt;
                   .where([&amp;quot;instructor_id = ? and substring(name,1,1) = ?&amp;quot;, session[:user].id, letter])&lt;br /&gt;
                   .order('name')&lt;br /&gt;
                   .page(params[:page])&lt;br /&gt;
                   .per_page(10)&lt;br /&gt;
&lt;br /&gt;
To &lt;br /&gt;
&lt;br /&gt;
                   @assignments = Assignment&lt;br /&gt;
                   .where(instructor_id:session[:user].id)&lt;br /&gt;
                   .where(&amp;quot;substring(name,1,1) = :letter&amp;quot;,{letter:letter})&lt;br /&gt;
                   .order('name')&lt;br /&gt;
                   .page(params[:page])&lt;br /&gt;
                   .per_page(10)&lt;br /&gt;
&lt;br /&gt;
4.  From&lt;br /&gt;
&lt;br /&gt;
  ReviewResponseMap.where([&amp;quot;reviewed_object_id = ? and calibrate_to = ?&amp;quot;, assignment_id, 1])&lt;br /&gt;
&lt;br /&gt;
To &lt;br /&gt;
&lt;br /&gt;
  ReviewResponseMap.where(reviewed_object_id:assignment_id, calibrate_to: 1)&lt;br /&gt;
&lt;br /&gt;
5. From&lt;br /&gt;
&lt;br /&gt;
  ReviewResponseMap.where([&amp;quot;reviewed_object_id = ? and created_at &amp;gt; ? and calibrate_to = ?&amp;quot;, assignment_id, @@time_create_last_review_mapping_record, 0])&lt;br /&gt;
&lt;br /&gt;
To &lt;br /&gt;
&lt;br /&gt;
  ReviewResponseMap.where(reviewed_object_id:assignment_id,calibrate_to:0).where(&amp;quot;created_at &amp;gt; :time&amp;quot;,{time:@@time_create_last_review_mapping_record})&lt;br /&gt;
&lt;br /&gt;
6. From&lt;br /&gt;
&lt;br /&gt;
  AssignmentQuestionnaire.where([&amp;quot;assignment_id = ? and questionnaire_id IN (?)&amp;quot;, params[:id], @review_questionnaire_ids])&lt;br /&gt;
&lt;br /&gt;
To&lt;br /&gt;
 &lt;br /&gt;
  AssignmentQuestionnaire.where(assignment_id: params[:id],:questionnaire_id =&amp;gt; @review_questionnaire_ids)&lt;br /&gt;
&lt;br /&gt;
7. From&lt;br /&gt;
&lt;br /&gt;
  SelfReviewResponseMap.where(['reviewee_id = ? and reviewer_id = ?', team_id[0].t_id, params[:reviewer_id]])&lt;br /&gt;
&lt;br /&gt;
To &lt;br /&gt;
&lt;br /&gt;
  SelfReviewResponseMap.where(reviewee_id:team_id[0].t_id,reviewer_id:params[:reviewer_id])&lt;br /&gt;
&lt;br /&gt;
==Refactor long line method==&lt;br /&gt;
&lt;br /&gt;
  def automatic_review_mapping_strategy(assignment_id,&lt;br /&gt;
                                        participants, teams, student_review_num = 0,&lt;br /&gt;
                                        submission_review_num = 0)&lt;br /&gt;
    participants_hash = {}&lt;br /&gt;
    participants.each {|participant| participants_hash[participant.id] = 0 }&lt;br /&gt;
    # calculate reviewers for each team&lt;br /&gt;
    num_participants = participants.size&lt;br /&gt;
    if student_review_num != 0 and submission_review_num == 0&lt;br /&gt;
      num_reviews_per_team = (participants.size * student_review_num * 1.0 / teams.size).round&lt;br /&gt;
      student_review_num = student_review_num&lt;br /&gt;
      exact_num_of_review_needed = participants.size * student_review_num&lt;br /&gt;
    elsif student_review_num == 0 and submission_review_num != 0&lt;br /&gt;
      num_reviews_per_team = submission_review_num&lt;br /&gt;
      student_review_num = (teams.size * submission_review_num * 1.0 / participants.size).round&lt;br /&gt;
      exact_num_of_review_needed = teams.size * submission_review_num&lt;br /&gt;
    end&lt;br /&gt;
    execute_peer_review_strategy(assignment_id, teams, num_participants,&lt;br /&gt;
                                     student_review_num, num_reviews_per_team,&lt;br /&gt;
                                     participants, participants_hash)&lt;br /&gt;
    # after assigning peer reviews for each team,&lt;br /&gt;
    # if there are still some peer reviewers not obtain enough peer review,&lt;br /&gt;
    # just assign them to valid teams&lt;br /&gt;
    assign_reviewers_for_team(assignment_id,student_review_num,participants_hash,&lt;br /&gt;
                              exact_num_of_review_needed)&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  def assign_reviewers_for_team(assignment_id,student_review_num,participants_hash,&lt;br /&gt;
                                exact_num_of_review_needed)&lt;br /&gt;
    if ReviewResponseMap.where([&amp;quot;reviewed_object_id = ? and created_at &amp;gt; ? and calibrate_to = ?&amp;quot;, &lt;br /&gt;
                                assignment_id, &lt;br /&gt;
                                @@time_create_last_review_mapping_record, 0]).size &amp;lt; exact_num_of_review_needed&lt;br /&gt;
      participants_with_insufficient_review_num = []&lt;br /&gt;
      participants_hash.each do |participant_id, review_num|&lt;br /&gt;
        participants_with_insufficient_review_num &amp;lt;&amp;lt; participant_id if review_num &amp;lt; student_review_num&lt;br /&gt;
      end&lt;br /&gt;
      unsorted_teams_hash = {}&lt;br /&gt;
      ReviewResponseMap.where([&amp;quot;reviewed_object_id = ? and calibrate_to = ?&amp;quot;, &lt;br /&gt;
                               assignment_id, 0]).each do |response_map|&lt;br /&gt;
        if unsorted_teams_hash.key? response_map.reviewee_id&lt;br /&gt;
          unsorted_teams_hash[response_map.reviewee_id] += 1&lt;br /&gt;
        else&lt;br /&gt;
          unsorted_teams_hash[response_map.reviewee_id] = 1&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
      teams_hash = unsorted_teams_hash.sort_by {|_, v| v }.to_h&lt;br /&gt;
      participants_with_insufficient_review_num.each do |participant_id|&lt;br /&gt;
        teams_hash.each do |team_id, _num_review_received|&lt;br /&gt;
          next if TeamsUser.exists?(team_id: team_id, &lt;br /&gt;
                                    user_id: Participant.find(participant_id).user_id)&lt;br /&gt;
          ReviewResponseMap.where(reviewee_id: team_id, reviewer_id: participant_id, &lt;br /&gt;
                                  reviewed_object_id: assignment_id).first_or_create&lt;br /&gt;
          teams_hash[team_id] += 1&lt;br /&gt;
          teams_hash = teams_hash.sort_by {|_, v| v }.to_h&lt;br /&gt;
          break&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
    @@time_create_last_review_mapping_record = ReviewResponseMap.&lt;br /&gt;
                                               where(reviewed_object_id: assignment_id).&lt;br /&gt;
                                               last.created_at&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def execute_peer_review_strategy(assignment_id, teams, num_participants, &lt;br /&gt;
                                   student_review_num, num_reviews_per_team, &lt;br /&gt;
                                   participants, participants_hash)&lt;br /&gt;
    # Exception detection: If instructor want to assign too many reviews done&lt;br /&gt;
    # by each student, there will be an error msg.&lt;br /&gt;
    if student_review_num &amp;gt;= teams.size&lt;br /&gt;
      flash[:error] = 'You cannot set the number of reviews done &lt;br /&gt;
      by each student to be greater than or equal to total number of teams &lt;br /&gt;
      [or &amp;quot;participants&amp;quot; if it is an individual assignment].'&lt;br /&gt;
    end&lt;br /&gt;
    peer_review_strategy(assignment_id, teams, num_participants, &lt;br /&gt;
                         student_review_num, num_reviews_per_team, &lt;br /&gt;
                         participants, participants_hash)&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
=Test=&lt;br /&gt;
We write RSpec feature tests to prove that all changes are correct and the project performs well as before.&lt;br /&gt;
&lt;br /&gt;
The function of  method automatic_review_mapping is to automatically assign reviews on students in teams when instructor set either student review number or submissions review number. There is constraint that only one of the two numbers must be set value other than 0 (that is, one is 0 and other is not 0). To test the correctness  of our refactoring, we design a scenario and 4 cases of assigning reviews to students:&lt;br /&gt;
&lt;br /&gt;
Case 1. Instructor has not set both students review number and submissions review number (They are both 0). The page will show a notice.&lt;br /&gt;
&lt;br /&gt;
Case 2. Instructor set both numbers (They are both not 0). The page will show a notice.&lt;br /&gt;
&lt;br /&gt;
Case 3. Instructors set students review number. The controller will change database: create new relationship in ReviewResponseMap. For example, if assign student review number to 2, and there will be 20 peer reviews in total and need to allocate to 3 teams. So each team get 7 reviews on average and 1 team’s artifact will be reviewed 6 times.&lt;br /&gt;
&lt;br /&gt;
Case 4. Instructors set submissions review number. The controller will change database: create new relationship in ReviewResponseMap. For example, if assign submission review number to 3, and there will be 21 peer reviews in total to allocate to 10 participants. So every participants get 2 reviews. 9 among 10 participants will review 2 teams’ artifacts and 1 participant will review 3 teams’ artifacts.&lt;br /&gt;
&lt;br /&gt;
require 'rails_helper'&lt;br /&gt;
  describe &amp;quot;review mapping&amp;quot;, js: true do&lt;br /&gt;
    before(:each) do&lt;br /&gt;
      #create test data&lt;br /&gt;
    end&lt;br /&gt;
 &lt;br /&gt;
    it &amp;quot;show error when assign both 0&amp;quot; do&lt;br /&gt;
      login_as(&amp;quot;instructor6&amp;quot;)&lt;br /&gt;
      visit '/assignments/1/edit'&lt;br /&gt;
      find_link('ReviewStrategy').click&lt;br /&gt;
      select &amp;quot;Instructor-Selected&amp;quot;, from: 'assignment_form_assignment_review_assignment_strategy'&lt;br /&gt;
      fill_in 'num_reviews_per_student', with: 0&lt;br /&gt;
      choose 'num_reviews_submission'&lt;br /&gt;
      fill_in 'num_reviews_per_submission', with: 0&lt;br /&gt;
      click_button 'second_submit_tag'&lt;br /&gt;
      #click_button 'Save'&lt;br /&gt;
      expect(page).to have_content('Please choose either the number of reviews per student or the number of reviewers per team (student)')&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    it &amp;quot;show error when assign both numbers&amp;quot; do&lt;br /&gt;
      login_as(&amp;quot;instructor6&amp;quot;)&lt;br /&gt;
      visit '/assignments/1/edit'&lt;br /&gt;
      find_link('ReviewStrategy').click&lt;br /&gt;
      select &amp;quot;Instructor-Selected&amp;quot;, from: 'assignment_form_assignment_review_assignment_strategy'&lt;br /&gt;
      fill_in 'num_reviews_per_student', with: 1&lt;br /&gt;
      choose 'num_reviews_submission'&lt;br /&gt;
      fill_in 'num_reviews_per_submission', with: 1&lt;br /&gt;
      click_button 'second_submit_tag'&lt;br /&gt;
      #click_button 'Save'&lt;br /&gt;
      expect(page).to have_content('Please choose either the number of reviews per student or the number of reviewers per team (student), not both')&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    it &amp;quot;calculate reviewmapping from given review number per student&amp;quot; do&lt;br /&gt;
      login_as(&amp;quot;instructor6&amp;quot;)&lt;br /&gt;
      visit '/assignments/1/edit'&lt;br /&gt;
      find_link('ReviewStrategy').click&lt;br /&gt;
      select &amp;quot;Instructor-Selected&amp;quot;, from: 'assignment_form_assignment_review_assignment_strategy'&lt;br /&gt;
      fill_in 'num_reviews_per_student', with: 2&lt;br /&gt;
      click_button 'first_submit_tag'&lt;br /&gt;
      num = ReviewResponseMap.where(reviewee_id: @team1.id, reviewed_object_id: @assignment.id).count&lt;br /&gt;
      expect(num).to eq(7)&lt;br /&gt;
      num2 = ReviewResponseMap.where(reviewee_id: @team3.id, reviewed_object_id: @assignment.id).count&lt;br /&gt;
      expect(num2).to eq(6)&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    it &amp;quot;calculate reviewmapping from given review number per submission&amp;quot; do&lt;br /&gt;
      login_as(&amp;quot;instructor6&amp;quot;)&lt;br /&gt;
      visit '/assignments/1/edit'&lt;br /&gt;
      find_link('ReviewStrategy').click&lt;br /&gt;
      select &amp;quot;Instructor-Selected&amp;quot;, from: 'assignment_form_assignment_review_assignment_strategy'&lt;br /&gt;
      choose 'num_reviews_submission'&lt;br /&gt;
      fill_in 'num_reviews_per_submission', with: 7&lt;br /&gt;
      click_button 'second_submit_tag'&lt;br /&gt;
      #click_button 'Save'&lt;br /&gt;
      num = ReviewResponseMap.where(reviewer_id: @teamuser1.id, reviewed_object_id: @assignment.id).count&lt;br /&gt;
      expect(num).to eq(2)&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;/div&gt;</summary>
		<author><name>Jdeng8</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2016/E1641._Refactor_review_mapping_controller.rb&amp;diff=103935</id>
		<title>CSC/ECE 517 Fall 2016/E1641. Refactor review mapping controller.rb</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2016/E1641._Refactor_review_mapping_controller.rb&amp;diff=103935"/>
		<updated>2016-10-29T05:38:33Z</updated>

		<summary type="html">&lt;p&gt;Jdeng8: /* Current Implementation and Problems */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=Background=&lt;br /&gt;
&lt;br /&gt;
This controller sets up mappings between reviewer and reviewee. It handles all different types of response maps (review response map, author feedback response map, teammate review response map, meta review response map and quiz response map). The class has functionality for five different kinds of Responses: reviews, metareviews, teammate reviews, author feedback (“rejoinders”), and quizzes. &lt;br /&gt;
&lt;br /&gt;
=Current Implementation and Problems=&lt;br /&gt;
&lt;br /&gt;
# Method ''response_report'' has some [SQL] - like code.  Rewrite with Active Record.&lt;br /&gt;
# Test whether method ''add_user_to_assignment'' is used. There is no way that this method should be in ReviewMappingController. Please remove this method and caller.&lt;br /&gt;
# There was a ''self-review'' feature, the method ''add_self_reviewer'', ''get_team_from_submission'' are related to this. Two views calls ''add_self_reviewer'' are &amp;quot;show_available_submissions_for_quizzes.html.erb&amp;quot; and &amp;quot;show_available_submissions.html.erb&amp;quot;. The names of views are not related to ''self_review'' feature. Plus those two views are not called anywhere. Please verify this and if so, you should delete those two views, two method and also related records (e.g. in routes.rb).&lt;br /&gt;
# Method ''delete_all_reviewers'' actually only deletes the outstanding review response maps (the ones which has been initiated, but there is no response yet). So it should better be named ''delete_outstanding_reviewers''. You can try to test this method by clicking “Assign reviewers” icon on an assignment.&lt;br /&gt;
# Method ''release_reservation'' should be renamed as'' release_mapping''. In addition, delete it if you find this method is not called anywhere.&lt;br /&gt;
# Method ''delete_mappings'' is problematic. It does not looks like a controller method. Please refactor it or delete it if you can validate that this method is not called anywhere.&lt;br /&gt;
# Method'' automatic_review_mapping_strategy'' is too long. Please refactor and test it.&lt;br /&gt;
&lt;br /&gt;
=Changes Implemented=&lt;br /&gt;
&lt;br /&gt;
# change the rails query from sql like code, like ReviewResponseMap.where(['reviewee_id = ? and reviewer_id = ? ', params[:contributor_id], reviewer.id]) to more rails quey like ReviewResponseMap.where(reviewee_id: params[:contributor_id],reviewer_id: reviewer.id)&lt;br /&gt;
# We search the function name(''add_user_to_assignment'') in the whole files, and find that this method is invoked in &amp;quot;participants_helper.rb&amp;quot;, and also being invoked in the function of ''add_reviewer'' and ''add_metareviewer'' in the controller of ''review_mapping_controller'' &lt;br /&gt;
# By searching the whole project and routes, we verify that methods ''add_self_reviewer'' and ''get_team_from_submission'' in this controller are not called by any other methods except for views &amp;quot;show_available_submissions_for_quizzes.html.erb&amp;quot; and &amp;quot;show_available_submissions.html.erb&amp;quot;. And those two views are not linked to any other views. So they are deleted from the project.&lt;br /&gt;
# We already renamed method ''delete_all_reviewers'' to ''delete_outstanding_reviewers'' and changed the corresponding button name at the corresponding view (_list_review_mappings.html.erb).&lt;br /&gt;
# By searching the whole project and routes, we verify that methods'' release_reservation'' in this controller are not used in anywhere.&lt;br /&gt;
# By searching the whole project and routes, we verify that methods ''delete_mappings'' in this controller are not used in anywhere.&lt;br /&gt;
# Method ''automatic_review_mapping_strategy'' have many long lines. We already shorten each long line to multiple lines. And also, we split this long function into three different functions.&lt;br /&gt;
&lt;br /&gt;
=Code=&lt;br /&gt;
&lt;br /&gt;
==Refactor SQL query code==&lt;br /&gt;
&lt;br /&gt;
The rails query we change in this controller:&lt;br /&gt;
&lt;br /&gt;
1. From &lt;br /&gt;
&lt;br /&gt;
  ReviewResponseMap.where(['reviewee_id = ? and reviewer_id = ? ', params[:contributor_id], reviewer.id]) &lt;br /&gt;
&lt;br /&gt;
To&lt;br /&gt;
&lt;br /&gt;
  ReviewResponseMap.where(reviewee_id: params[:contributor_id],reviewer_id: reviewer.id)&lt;br /&gt;
&lt;br /&gt;
2. From&lt;br /&gt;
&lt;br /&gt;
  MetareviewResponseMap.where(['reviewed_object_id = ? and reviewer_id = ?', mapping.map_id, reviewer.id])&lt;br /&gt;
&lt;br /&gt;
To&lt;br /&gt;
&lt;br /&gt;
  MetareviewResponseMap.where(reviewed_object_id: mapping.map_id, reviewer_id: reviewer.id)&lt;br /&gt;
&lt;br /&gt;
3. From&lt;br /&gt;
&lt;br /&gt;
                   @assignments = Assignment&lt;br /&gt;
                   .where([&amp;quot;instructor_id = ? and substring(name,1,1) = ?&amp;quot;, session[:user].id, letter])&lt;br /&gt;
                   .order('name')&lt;br /&gt;
                   .page(params[:page])&lt;br /&gt;
                   .per_page(10)&lt;br /&gt;
&lt;br /&gt;
To &lt;br /&gt;
&lt;br /&gt;
                   @assignments = Assignment&lt;br /&gt;
                   .where(instructor_id:session[:user].id)&lt;br /&gt;
                   .where(&amp;quot;substring(name,1,1) = :letter&amp;quot;,{letter:letter})&lt;br /&gt;
                   .order('name')&lt;br /&gt;
                   .page(params[:page])&lt;br /&gt;
                   .per_page(10)&lt;br /&gt;
&lt;br /&gt;
4.  From&lt;br /&gt;
&lt;br /&gt;
  ReviewResponseMap.where([&amp;quot;reviewed_object_id = ? and calibrate_to = ?&amp;quot;, assignment_id, 1])&lt;br /&gt;
&lt;br /&gt;
To &lt;br /&gt;
&lt;br /&gt;
  ReviewResponseMap.where(reviewed_object_id:assignment_id, calibrate_to: 1)&lt;br /&gt;
&lt;br /&gt;
5. From&lt;br /&gt;
&lt;br /&gt;
  ReviewResponseMap.where([&amp;quot;reviewed_object_id = ? and created_at &amp;gt; ? and calibrate_to = ?&amp;quot;, assignment_id, @@time_create_last_review_mapping_record, 0])&lt;br /&gt;
&lt;br /&gt;
To &lt;br /&gt;
&lt;br /&gt;
  ReviewResponseMap.where(reviewed_object_id:assignment_id,calibrate_to:0).where(&amp;quot;created_at &amp;gt; :time&amp;quot;,{time:@@time_create_last_review_mapping_record})&lt;br /&gt;
&lt;br /&gt;
6. From&lt;br /&gt;
&lt;br /&gt;
  AssignmentQuestionnaire.where([&amp;quot;assignment_id = ? and questionnaire_id IN (?)&amp;quot;, params[:id], @review_questionnaire_ids])&lt;br /&gt;
&lt;br /&gt;
To&lt;br /&gt;
 &lt;br /&gt;
  AssignmentQuestionnaire.where(assignment_id: params[:id],:questionnaire_id =&amp;gt; @review_questionnaire_ids)&lt;br /&gt;
&lt;br /&gt;
7. From&lt;br /&gt;
&lt;br /&gt;
  SelfReviewResponseMap.where(['reviewee_id = ? and reviewer_id = ?', team_id[0].t_id, params[:reviewer_id]])&lt;br /&gt;
&lt;br /&gt;
To &lt;br /&gt;
&lt;br /&gt;
  SelfReviewResponseMap.where(reviewee_id:team_id[0].t_id,reviewer_id:params[:reviewer_id])&lt;br /&gt;
&lt;br /&gt;
==Refactor long line method==&lt;br /&gt;
&lt;br /&gt;
  def automatic_review_mapping_strategy(assignment_id,&lt;br /&gt;
                                        participants, teams, student_review_num = 0,&lt;br /&gt;
                                        submission_review_num = 0)&lt;br /&gt;
    participants_hash = {}&lt;br /&gt;
    participants.each {|participant| participants_hash[participant.id] = 0 }&lt;br /&gt;
    # calculate reviewers for each team&lt;br /&gt;
    num_participants = participants.size&lt;br /&gt;
    if student_review_num != 0 and submission_review_num == 0&lt;br /&gt;
      num_reviews_per_team = (participants.size * student_review_num * 1.0 / teams.size).round&lt;br /&gt;
      student_review_num = student_review_num&lt;br /&gt;
      exact_num_of_review_needed = participants.size * student_review_num&lt;br /&gt;
    elsif student_review_num == 0 and submission_review_num != 0&lt;br /&gt;
      num_reviews_per_team = submission_review_num&lt;br /&gt;
      student_review_num = (teams.size * submission_review_num * 1.0 / participants.size).round&lt;br /&gt;
      exact_num_of_review_needed = teams.size * submission_review_num&lt;br /&gt;
    end&lt;br /&gt;
    execute_peer_review_strategy(assignment_id, teams, num_participants,&lt;br /&gt;
                                     student_review_num, num_reviews_per_team,&lt;br /&gt;
                                     participants, participants_hash)&lt;br /&gt;
    # after assigning peer reviews for each team,&lt;br /&gt;
    # if there are still some peer reviewers not obtain enough peer review,&lt;br /&gt;
    # just assign them to valid teams&lt;br /&gt;
    assign_reviewers_for_team(assignment_id,student_review_num,participants_hash,&lt;br /&gt;
                              exact_num_of_review_needed)&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  def assign_reviewers_for_team(assignment_id,student_review_num,participants_hash,&lt;br /&gt;
                                exact_num_of_review_needed)&lt;br /&gt;
    if ReviewResponseMap.where([&amp;quot;reviewed_object_id = ? and created_at &amp;gt; ? and calibrate_to = ?&amp;quot;, &lt;br /&gt;
                                assignment_id, &lt;br /&gt;
                                @@time_create_last_review_mapping_record, 0]).size &amp;lt; exact_num_of_review_needed&lt;br /&gt;
      participants_with_insufficient_review_num = []&lt;br /&gt;
      participants_hash.each do |participant_id, review_num|&lt;br /&gt;
        participants_with_insufficient_review_num &amp;lt;&amp;lt; participant_id if review_num &amp;lt; student_review_num&lt;br /&gt;
      end&lt;br /&gt;
      unsorted_teams_hash = {}&lt;br /&gt;
      ReviewResponseMap.where([&amp;quot;reviewed_object_id = ? and calibrate_to = ?&amp;quot;, &lt;br /&gt;
                               assignment_id, 0]).each do |response_map|&lt;br /&gt;
        if unsorted_teams_hash.key? response_map.reviewee_id&lt;br /&gt;
          unsorted_teams_hash[response_map.reviewee_id] += 1&lt;br /&gt;
        else&lt;br /&gt;
          unsorted_teams_hash[response_map.reviewee_id] = 1&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
      teams_hash = unsorted_teams_hash.sort_by {|_, v| v }.to_h&lt;br /&gt;
      participants_with_insufficient_review_num.each do |participant_id|&lt;br /&gt;
        teams_hash.each do |team_id, _num_review_received|&lt;br /&gt;
          next if TeamsUser.exists?(team_id: team_id, &lt;br /&gt;
                                    user_id: Participant.find(participant_id).user_id)&lt;br /&gt;
          ReviewResponseMap.where(reviewee_id: team_id, reviewer_id: participant_id, &lt;br /&gt;
                                  reviewed_object_id: assignment_id).first_or_create&lt;br /&gt;
          teams_hash[team_id] += 1&lt;br /&gt;
          teams_hash = teams_hash.sort_by {|_, v| v }.to_h&lt;br /&gt;
          break&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
    @@time_create_last_review_mapping_record = ReviewResponseMap.&lt;br /&gt;
                                               where(reviewed_object_id: assignment_id).&lt;br /&gt;
                                               last.created_at&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def execute_peer_review_strategy(assignment_id, teams, num_participants, &lt;br /&gt;
                                   student_review_num, num_reviews_per_team, &lt;br /&gt;
                                   participants, participants_hash)&lt;br /&gt;
    # Exception detection: If instructor want to assign too many reviews done&lt;br /&gt;
    # by each student, there will be an error msg.&lt;br /&gt;
    if student_review_num &amp;gt;= teams.size&lt;br /&gt;
      flash[:error] = 'You cannot set the number of reviews done &lt;br /&gt;
      by each student to be greater than or equal to total number of teams &lt;br /&gt;
      [or &amp;quot;participants&amp;quot; if it is an individual assignment].'&lt;br /&gt;
    end&lt;br /&gt;
    peer_review_strategy(assignment_id, teams, num_participants, &lt;br /&gt;
                         student_review_num, num_reviews_per_team, &lt;br /&gt;
                         participants, participants_hash)&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
=Test=&lt;br /&gt;
We write RSpec feature tests to prove that all changes are correct and the project performs well as before.&lt;br /&gt;
&lt;br /&gt;
The function of  method automatic_review_mapping is to automatically assign reviews on students in teams when instructor set either student review number or submissions review number. There is constraint that only one of the two numbers must be set value other than 0 (that is, one is 0 and other is not 0). To test the correctness  of our refactoring, we design a scenario and 4 cases of assigning reviews to students:&lt;br /&gt;
&lt;br /&gt;
Case 1. Instructor has not set both students review number and submissions review number (They are both 0). The page will show a notice.&lt;br /&gt;
&lt;br /&gt;
Case 2. Instructor set both numbers (They are both not 0). The page will show a notice.&lt;br /&gt;
&lt;br /&gt;
Case 3. Instructors set students review number. The controller will change database: create new relationship in ReviewResponseMap. For example, if assign student review number to 2, and there will be 20 peer reviews in total and need to allocate to 3 teams. So each team get 7 reviews on average and 1 team’s artifact will be reviewed 6 times.&lt;br /&gt;
&lt;br /&gt;
Case 4. Instructors set submissions review number. The controller will change database: create new relationship in ReviewResponseMap. For example, if assign submission review number to 3, and there will be 21 peer reviews in total to allocate to 10 participants. So every participants get 2 reviews. 9 among 10 participants will review 2 teams’ artifacts and 1 participant will review 3 teams’ artifacts.&lt;br /&gt;
&lt;br /&gt;
require 'rails_helper'&lt;br /&gt;
  describe &amp;quot;review mapping&amp;quot;, js: true do&lt;br /&gt;
    before(:each) do&lt;br /&gt;
      #create test data&lt;br /&gt;
    end&lt;br /&gt;
 &lt;br /&gt;
    it &amp;quot;show error when assign both 0&amp;quot; do&lt;br /&gt;
      login_as(&amp;quot;instructor6&amp;quot;)&lt;br /&gt;
      visit '/assignments/1/edit'&lt;br /&gt;
      find_link('ReviewStrategy').click&lt;br /&gt;
      select &amp;quot;Instructor-Selected&amp;quot;, from: 'assignment_form_assignment_review_assignment_strategy'&lt;br /&gt;
      fill_in 'num_reviews_per_student', with: 0&lt;br /&gt;
      choose 'num_reviews_submission'&lt;br /&gt;
      fill_in 'num_reviews_per_submission', with: 0&lt;br /&gt;
      click_button 'second_submit_tag'&lt;br /&gt;
      #click_button 'Save'&lt;br /&gt;
      expect(page).to have_content('Please choose either the number of reviews per student or the number of reviewers per team (student)')&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    it &amp;quot;show error when assign both numbers&amp;quot; do&lt;br /&gt;
      login_as(&amp;quot;instructor6&amp;quot;)&lt;br /&gt;
      visit '/assignments/1/edit'&lt;br /&gt;
      find_link('ReviewStrategy').click&lt;br /&gt;
      select &amp;quot;Instructor-Selected&amp;quot;, from: 'assignment_form_assignment_review_assignment_strategy'&lt;br /&gt;
      fill_in 'num_reviews_per_student', with: 1&lt;br /&gt;
      choose 'num_reviews_submission'&lt;br /&gt;
      fill_in 'num_reviews_per_submission', with: 1&lt;br /&gt;
      click_button 'second_submit_tag'&lt;br /&gt;
      #click_button 'Save'&lt;br /&gt;
      expect(page).to have_content('Please choose either the number of reviews per student or the number of reviewers per team (student), not both')&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    it &amp;quot;calculate reviewmapping from given review number per student&amp;quot; do&lt;br /&gt;
      login_as(&amp;quot;instructor6&amp;quot;)&lt;br /&gt;
      visit '/assignments/1/edit'&lt;br /&gt;
      find_link('ReviewStrategy').click&lt;br /&gt;
      select &amp;quot;Instructor-Selected&amp;quot;, from: 'assignment_form_assignment_review_assignment_strategy'&lt;br /&gt;
      fill_in 'num_reviews_per_student', with: 2&lt;br /&gt;
      click_button 'first_submit_tag'&lt;br /&gt;
      num = ReviewResponseMap.where(reviewee_id: @team1.id, reviewed_object_id: @assignment.id).count&lt;br /&gt;
      expect(num).to eq(7)&lt;br /&gt;
      num2 = ReviewResponseMap.where(reviewee_id: @team3.id, reviewed_object_id: @assignment.id).count&lt;br /&gt;
      expect(num2).to eq(6)&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    it &amp;quot;calculate reviewmapping from given review number per submission&amp;quot; do&lt;br /&gt;
      login_as(&amp;quot;instructor6&amp;quot;)&lt;br /&gt;
      visit '/assignments/1/edit'&lt;br /&gt;
      find_link('ReviewStrategy').click&lt;br /&gt;
      select &amp;quot;Instructor-Selected&amp;quot;, from: 'assignment_form_assignment_review_assignment_strategy'&lt;br /&gt;
      choose 'num_reviews_submission'&lt;br /&gt;
      fill_in 'num_reviews_per_submission', with: 7&lt;br /&gt;
      click_button 'second_submit_tag'&lt;br /&gt;
      #click_button 'Save'&lt;br /&gt;
      num = ReviewResponseMap.where(reviewer_id: @teamuser1.id, reviewed_object_id: @assignment.id).count&lt;br /&gt;
      expect(num).to eq(2)&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;/div&gt;</summary>
		<author><name>Jdeng8</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2016/E1641._Refactor_review_mapping_controller.rb&amp;diff=103934</id>
		<title>CSC/ECE 517 Fall 2016/E1641. Refactor review mapping controller.rb</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2016/E1641._Refactor_review_mapping_controller.rb&amp;diff=103934"/>
		<updated>2016-10-29T05:37:33Z</updated>

		<summary type="html">&lt;p&gt;Jdeng8: /* Current Implementation and Problems */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=Background=&lt;br /&gt;
&lt;br /&gt;
This controller sets up mappings between reviewer and reviewee. It handles all different types of response maps (review response map, author feedback response map, teammate review response map, meta review response map and quiz response map). The class has functionality for five different kinds of Responses: reviews, metareviews, teammate reviews, author feedback (“rejoinders”), and quizzes. &lt;br /&gt;
&lt;br /&gt;
=Current Implementation and Problems=&lt;br /&gt;
&lt;br /&gt;
# Method ''response_report'' has some [[w:SQL|SQL]] - like code.  Rewrite with Active Record.&lt;br /&gt;
# Test whether method ''add_user_to_assignment'' is used. There is no way that this method should be in ReviewMappingController. Please remove this method and caller.&lt;br /&gt;
# There was a ''self-review'' feature, the method ''add_self_reviewer'', ''get_team_from_submission'' are related to this. Two views calls ''add_self_reviewer'' are &amp;quot;show_available_submissions_for_quizzes.html.erb&amp;quot; and &amp;quot;show_available_submissions.html.erb&amp;quot;. The names of views are not related to ''self_review'' feature. Plus those two views are not called anywhere. Please verify this and if so, you should delete those two views, two method and also related records (e.g. in routes.rb).&lt;br /&gt;
# Method ''delete_all_reviewers'' actually only deletes the outstanding review response maps (the ones which has been initiated, but there is no response yet). So it should better be named ''delete_outstanding_reviewers''. You can try to test this method by clicking “Assign reviewers” icon on an assignment.&lt;br /&gt;
# Method ''release_reservation'' should be renamed as'' release_mapping''. In addition, delete it if you find this method is not called anywhere.&lt;br /&gt;
# Method ''delete_mappings'' is problematic. It does not looks like a controller method. Please refactor it or delete it if you can validate that this method is not called anywhere.&lt;br /&gt;
# Method'' automatic_review_mapping_strategy'' is too long. Please refactor and test it.&lt;br /&gt;
&lt;br /&gt;
=Changes Implemented=&lt;br /&gt;
&lt;br /&gt;
# change the rails query from sql like code, like ReviewResponseMap.where(['reviewee_id = ? and reviewer_id = ? ', params[:contributor_id], reviewer.id]) to more rails quey like ReviewResponseMap.where(reviewee_id: params[:contributor_id],reviewer_id: reviewer.id)&lt;br /&gt;
# We search the function name(''add_user_to_assignment'') in the whole files, and find that this method is invoked in &amp;quot;participants_helper.rb&amp;quot;, and also being invoked in the function of ''add_reviewer'' and ''add_metareviewer'' in the controller of ''review_mapping_controller'' &lt;br /&gt;
# By searching the whole project and routes, we verify that methods ''add_self_reviewer'' and ''get_team_from_submission'' in this controller are not called by any other methods except for views &amp;quot;show_available_submissions_for_quizzes.html.erb&amp;quot; and &amp;quot;show_available_submissions.html.erb&amp;quot;. And those two views are not linked to any other views. So they are deleted from the project.&lt;br /&gt;
# We already renamed method ''delete_all_reviewers'' to ''delete_outstanding_reviewers'' and changed the corresponding button name at the corresponding view (_list_review_mappings.html.erb).&lt;br /&gt;
# By searching the whole project and routes, we verify that methods'' release_reservation'' in this controller are not used in anywhere.&lt;br /&gt;
# By searching the whole project and routes, we verify that methods ''delete_mappings'' in this controller are not used in anywhere.&lt;br /&gt;
# Method ''automatic_review_mapping_strategy'' have many long lines. We already shorten each long line to multiple lines. And also, we split this long function into three different functions.&lt;br /&gt;
&lt;br /&gt;
=Code=&lt;br /&gt;
&lt;br /&gt;
==Refactor SQL query code==&lt;br /&gt;
&lt;br /&gt;
The rails query we change in this controller:&lt;br /&gt;
&lt;br /&gt;
1. From &lt;br /&gt;
&lt;br /&gt;
  ReviewResponseMap.where(['reviewee_id = ? and reviewer_id = ? ', params[:contributor_id], reviewer.id]) &lt;br /&gt;
&lt;br /&gt;
To&lt;br /&gt;
&lt;br /&gt;
  ReviewResponseMap.where(reviewee_id: params[:contributor_id],reviewer_id: reviewer.id)&lt;br /&gt;
&lt;br /&gt;
2. From&lt;br /&gt;
&lt;br /&gt;
  MetareviewResponseMap.where(['reviewed_object_id = ? and reviewer_id = ?', mapping.map_id, reviewer.id])&lt;br /&gt;
&lt;br /&gt;
To&lt;br /&gt;
&lt;br /&gt;
  MetareviewResponseMap.where(reviewed_object_id: mapping.map_id, reviewer_id: reviewer.id)&lt;br /&gt;
&lt;br /&gt;
3. From&lt;br /&gt;
&lt;br /&gt;
                   @assignments = Assignment&lt;br /&gt;
                   .where([&amp;quot;instructor_id = ? and substring(name,1,1) = ?&amp;quot;, session[:user].id, letter])&lt;br /&gt;
                   .order('name')&lt;br /&gt;
                   .page(params[:page])&lt;br /&gt;
                   .per_page(10)&lt;br /&gt;
&lt;br /&gt;
To &lt;br /&gt;
&lt;br /&gt;
                   @assignments = Assignment&lt;br /&gt;
                   .where(instructor_id:session[:user].id)&lt;br /&gt;
                   .where(&amp;quot;substring(name,1,1) = :letter&amp;quot;,{letter:letter})&lt;br /&gt;
                   .order('name')&lt;br /&gt;
                   .page(params[:page])&lt;br /&gt;
                   .per_page(10)&lt;br /&gt;
&lt;br /&gt;
4.  From&lt;br /&gt;
&lt;br /&gt;
  ReviewResponseMap.where([&amp;quot;reviewed_object_id = ? and calibrate_to = ?&amp;quot;, assignment_id, 1])&lt;br /&gt;
&lt;br /&gt;
To &lt;br /&gt;
&lt;br /&gt;
  ReviewResponseMap.where(reviewed_object_id:assignment_id, calibrate_to: 1)&lt;br /&gt;
&lt;br /&gt;
5. From&lt;br /&gt;
&lt;br /&gt;
  ReviewResponseMap.where([&amp;quot;reviewed_object_id = ? and created_at &amp;gt; ? and calibrate_to = ?&amp;quot;, assignment_id, @@time_create_last_review_mapping_record, 0])&lt;br /&gt;
&lt;br /&gt;
To &lt;br /&gt;
&lt;br /&gt;
  ReviewResponseMap.where(reviewed_object_id:assignment_id,calibrate_to:0).where(&amp;quot;created_at &amp;gt; :time&amp;quot;,{time:@@time_create_last_review_mapping_record})&lt;br /&gt;
&lt;br /&gt;
6. From&lt;br /&gt;
&lt;br /&gt;
  AssignmentQuestionnaire.where([&amp;quot;assignment_id = ? and questionnaire_id IN (?)&amp;quot;, params[:id], @review_questionnaire_ids])&lt;br /&gt;
&lt;br /&gt;
To&lt;br /&gt;
 &lt;br /&gt;
  AssignmentQuestionnaire.where(assignment_id: params[:id],:questionnaire_id =&amp;gt; @review_questionnaire_ids)&lt;br /&gt;
&lt;br /&gt;
7. From&lt;br /&gt;
&lt;br /&gt;
  SelfReviewResponseMap.where(['reviewee_id = ? and reviewer_id = ?', team_id[0].t_id, params[:reviewer_id]])&lt;br /&gt;
&lt;br /&gt;
To &lt;br /&gt;
&lt;br /&gt;
  SelfReviewResponseMap.where(reviewee_id:team_id[0].t_id,reviewer_id:params[:reviewer_id])&lt;br /&gt;
&lt;br /&gt;
==Refactor long line method==&lt;br /&gt;
&lt;br /&gt;
  def automatic_review_mapping_strategy(assignment_id,&lt;br /&gt;
                                        participants, teams, student_review_num = 0,&lt;br /&gt;
                                        submission_review_num = 0)&lt;br /&gt;
    participants_hash = {}&lt;br /&gt;
    participants.each {|participant| participants_hash[participant.id] = 0 }&lt;br /&gt;
    # calculate reviewers for each team&lt;br /&gt;
    num_participants = participants.size&lt;br /&gt;
    if student_review_num != 0 and submission_review_num == 0&lt;br /&gt;
      num_reviews_per_team = (participants.size * student_review_num * 1.0 / teams.size).round&lt;br /&gt;
      student_review_num = student_review_num&lt;br /&gt;
      exact_num_of_review_needed = participants.size * student_review_num&lt;br /&gt;
    elsif student_review_num == 0 and submission_review_num != 0&lt;br /&gt;
      num_reviews_per_team = submission_review_num&lt;br /&gt;
      student_review_num = (teams.size * submission_review_num * 1.0 / participants.size).round&lt;br /&gt;
      exact_num_of_review_needed = teams.size * submission_review_num&lt;br /&gt;
    end&lt;br /&gt;
    execute_peer_review_strategy(assignment_id, teams, num_participants,&lt;br /&gt;
                                     student_review_num, num_reviews_per_team,&lt;br /&gt;
                                     participants, participants_hash)&lt;br /&gt;
    # after assigning peer reviews for each team,&lt;br /&gt;
    # if there are still some peer reviewers not obtain enough peer review,&lt;br /&gt;
    # just assign them to valid teams&lt;br /&gt;
    assign_reviewers_for_team(assignment_id,student_review_num,participants_hash,&lt;br /&gt;
                              exact_num_of_review_needed)&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  def assign_reviewers_for_team(assignment_id,student_review_num,participants_hash,&lt;br /&gt;
                                exact_num_of_review_needed)&lt;br /&gt;
    if ReviewResponseMap.where([&amp;quot;reviewed_object_id = ? and created_at &amp;gt; ? and calibrate_to = ?&amp;quot;, &lt;br /&gt;
                                assignment_id, &lt;br /&gt;
                                @@time_create_last_review_mapping_record, 0]).size &amp;lt; exact_num_of_review_needed&lt;br /&gt;
      participants_with_insufficient_review_num = []&lt;br /&gt;
      participants_hash.each do |participant_id, review_num|&lt;br /&gt;
        participants_with_insufficient_review_num &amp;lt;&amp;lt; participant_id if review_num &amp;lt; student_review_num&lt;br /&gt;
      end&lt;br /&gt;
      unsorted_teams_hash = {}&lt;br /&gt;
      ReviewResponseMap.where([&amp;quot;reviewed_object_id = ? and calibrate_to = ?&amp;quot;, &lt;br /&gt;
                               assignment_id, 0]).each do |response_map|&lt;br /&gt;
        if unsorted_teams_hash.key? response_map.reviewee_id&lt;br /&gt;
          unsorted_teams_hash[response_map.reviewee_id] += 1&lt;br /&gt;
        else&lt;br /&gt;
          unsorted_teams_hash[response_map.reviewee_id] = 1&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
      teams_hash = unsorted_teams_hash.sort_by {|_, v| v }.to_h&lt;br /&gt;
      participants_with_insufficient_review_num.each do |participant_id|&lt;br /&gt;
        teams_hash.each do |team_id, _num_review_received|&lt;br /&gt;
          next if TeamsUser.exists?(team_id: team_id, &lt;br /&gt;
                                    user_id: Participant.find(participant_id).user_id)&lt;br /&gt;
          ReviewResponseMap.where(reviewee_id: team_id, reviewer_id: participant_id, &lt;br /&gt;
                                  reviewed_object_id: assignment_id).first_or_create&lt;br /&gt;
          teams_hash[team_id] += 1&lt;br /&gt;
          teams_hash = teams_hash.sort_by {|_, v| v }.to_h&lt;br /&gt;
          break&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
    @@time_create_last_review_mapping_record = ReviewResponseMap.&lt;br /&gt;
                                               where(reviewed_object_id: assignment_id).&lt;br /&gt;
                                               last.created_at&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def execute_peer_review_strategy(assignment_id, teams, num_participants, &lt;br /&gt;
                                   student_review_num, num_reviews_per_team, &lt;br /&gt;
                                   participants, participants_hash)&lt;br /&gt;
    # Exception detection: If instructor want to assign too many reviews done&lt;br /&gt;
    # by each student, there will be an error msg.&lt;br /&gt;
    if student_review_num &amp;gt;= teams.size&lt;br /&gt;
      flash[:error] = 'You cannot set the number of reviews done &lt;br /&gt;
      by each student to be greater than or equal to total number of teams &lt;br /&gt;
      [or &amp;quot;participants&amp;quot; if it is an individual assignment].'&lt;br /&gt;
    end&lt;br /&gt;
    peer_review_strategy(assignment_id, teams, num_participants, &lt;br /&gt;
                         student_review_num, num_reviews_per_team, &lt;br /&gt;
                         participants, participants_hash)&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
=Test=&lt;br /&gt;
We write RSpec feature tests to prove that all changes are correct and the project performs well as before.&lt;br /&gt;
&lt;br /&gt;
The function of  method automatic_review_mapping is to automatically assign reviews on students in teams when instructor set either student review number or submissions review number. There is constraint that only one of the two numbers must be set value other than 0 (that is, one is 0 and other is not 0). To test the correctness  of our refactoring, we design a scenario and 4 cases of assigning reviews to students:&lt;br /&gt;
&lt;br /&gt;
Case 1. Instructor has not set both students review number and submissions review number (They are both 0). The page will show a notice.&lt;br /&gt;
&lt;br /&gt;
Case 2. Instructor set both numbers (They are both not 0). The page will show a notice.&lt;br /&gt;
&lt;br /&gt;
Case 3. Instructors set students review number. The controller will change database: create new relationship in ReviewResponseMap. For example, if assign student review number to 2, and there will be 20 peer reviews in total and need to allocate to 3 teams. So each team get 7 reviews on average and 1 team’s artifact will be reviewed 6 times.&lt;br /&gt;
&lt;br /&gt;
Case 4. Instructors set submissions review number. The controller will change database: create new relationship in ReviewResponseMap. For example, if assign submission review number to 3, and there will be 21 peer reviews in total to allocate to 10 participants. So every participants get 2 reviews. 9 among 10 participants will review 2 teams’ artifacts and 1 participant will review 3 teams’ artifacts.&lt;br /&gt;
&lt;br /&gt;
require 'rails_helper'&lt;br /&gt;
  describe &amp;quot;review mapping&amp;quot;, js: true do&lt;br /&gt;
    before(:each) do&lt;br /&gt;
      #create test data&lt;br /&gt;
    end&lt;br /&gt;
 &lt;br /&gt;
    it &amp;quot;show error when assign both 0&amp;quot; do&lt;br /&gt;
      login_as(&amp;quot;instructor6&amp;quot;)&lt;br /&gt;
      visit '/assignments/1/edit'&lt;br /&gt;
      find_link('ReviewStrategy').click&lt;br /&gt;
      select &amp;quot;Instructor-Selected&amp;quot;, from: 'assignment_form_assignment_review_assignment_strategy'&lt;br /&gt;
      fill_in 'num_reviews_per_student', with: 0&lt;br /&gt;
      choose 'num_reviews_submission'&lt;br /&gt;
      fill_in 'num_reviews_per_submission', with: 0&lt;br /&gt;
      click_button 'second_submit_tag'&lt;br /&gt;
      #click_button 'Save'&lt;br /&gt;
      expect(page).to have_content('Please choose either the number of reviews per student or the number of reviewers per team (student)')&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    it &amp;quot;show error when assign both numbers&amp;quot; do&lt;br /&gt;
      login_as(&amp;quot;instructor6&amp;quot;)&lt;br /&gt;
      visit '/assignments/1/edit'&lt;br /&gt;
      find_link('ReviewStrategy').click&lt;br /&gt;
      select &amp;quot;Instructor-Selected&amp;quot;, from: 'assignment_form_assignment_review_assignment_strategy'&lt;br /&gt;
      fill_in 'num_reviews_per_student', with: 1&lt;br /&gt;
      choose 'num_reviews_submission'&lt;br /&gt;
      fill_in 'num_reviews_per_submission', with: 1&lt;br /&gt;
      click_button 'second_submit_tag'&lt;br /&gt;
      #click_button 'Save'&lt;br /&gt;
      expect(page).to have_content('Please choose either the number of reviews per student or the number of reviewers per team (student), not both')&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    it &amp;quot;calculate reviewmapping from given review number per student&amp;quot; do&lt;br /&gt;
      login_as(&amp;quot;instructor6&amp;quot;)&lt;br /&gt;
      visit '/assignments/1/edit'&lt;br /&gt;
      find_link('ReviewStrategy').click&lt;br /&gt;
      select &amp;quot;Instructor-Selected&amp;quot;, from: 'assignment_form_assignment_review_assignment_strategy'&lt;br /&gt;
      fill_in 'num_reviews_per_student', with: 2&lt;br /&gt;
      click_button 'first_submit_tag'&lt;br /&gt;
      num = ReviewResponseMap.where(reviewee_id: @team1.id, reviewed_object_id: @assignment.id).count&lt;br /&gt;
      expect(num).to eq(7)&lt;br /&gt;
      num2 = ReviewResponseMap.where(reviewee_id: @team3.id, reviewed_object_id: @assignment.id).count&lt;br /&gt;
      expect(num2).to eq(6)&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    it &amp;quot;calculate reviewmapping from given review number per submission&amp;quot; do&lt;br /&gt;
      login_as(&amp;quot;instructor6&amp;quot;)&lt;br /&gt;
      visit '/assignments/1/edit'&lt;br /&gt;
      find_link('ReviewStrategy').click&lt;br /&gt;
      select &amp;quot;Instructor-Selected&amp;quot;, from: 'assignment_form_assignment_review_assignment_strategy'&lt;br /&gt;
      choose 'num_reviews_submission'&lt;br /&gt;
      fill_in 'num_reviews_per_submission', with: 7&lt;br /&gt;
      click_button 'second_submit_tag'&lt;br /&gt;
      #click_button 'Save'&lt;br /&gt;
      num = ReviewResponseMap.where(reviewer_id: @teamuser1.id, reviewed_object_id: @assignment.id).count&lt;br /&gt;
      expect(num).to eq(2)&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;/div&gt;</summary>
		<author><name>Jdeng8</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2016/E1641._Refactor_review_mapping_controller.rb&amp;diff=103933</id>
		<title>CSC/ECE 517 Fall 2016/E1641. Refactor review mapping controller.rb</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2016/E1641._Refactor_review_mapping_controller.rb&amp;diff=103933"/>
		<updated>2016-10-29T05:37:21Z</updated>

		<summary type="html">&lt;p&gt;Jdeng8: /* Current Implementation and Problems */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=Background=&lt;br /&gt;
&lt;br /&gt;
This controller sets up mappings between reviewer and reviewee. It handles all different types of response maps (review response map, author feedback response map, teammate review response map, meta review response map and quiz response map). The class has functionality for five different kinds of Responses: reviews, metareviews, teammate reviews, author feedback (“rejoinders”), and quizzes. &lt;br /&gt;
&lt;br /&gt;
=Current Implementation and Problems=&lt;br /&gt;
&lt;br /&gt;
# Method ''response_report'' has some [[w:SQL/SQL]] - like code.  Rewrite with Active Record.&lt;br /&gt;
# Test whether method ''add_user_to_assignment'' is used. There is no way that this method should be in ReviewMappingController. Please remove this method and caller.&lt;br /&gt;
# There was a ''self-review'' feature, the method ''add_self_reviewer'', ''get_team_from_submission'' are related to this. Two views calls ''add_self_reviewer'' are &amp;quot;show_available_submissions_for_quizzes.html.erb&amp;quot; and &amp;quot;show_available_submissions.html.erb&amp;quot;. The names of views are not related to ''self_review'' feature. Plus those two views are not called anywhere. Please verify this and if so, you should delete those two views, two method and also related records (e.g. in routes.rb).&lt;br /&gt;
# Method ''delete_all_reviewers'' actually only deletes the outstanding review response maps (the ones which has been initiated, but there is no response yet). So it should better be named ''delete_outstanding_reviewers''. You can try to test this method by clicking “Assign reviewers” icon on an assignment.&lt;br /&gt;
# Method ''release_reservation'' should be renamed as'' release_mapping''. In addition, delete it if you find this method is not called anywhere.&lt;br /&gt;
# Method ''delete_mappings'' is problematic. It does not looks like a controller method. Please refactor it or delete it if you can validate that this method is not called anywhere.&lt;br /&gt;
# Method'' automatic_review_mapping_strategy'' is too long. Please refactor and test it.&lt;br /&gt;
&lt;br /&gt;
=Changes Implemented=&lt;br /&gt;
&lt;br /&gt;
# change the rails query from sql like code, like ReviewResponseMap.where(['reviewee_id = ? and reviewer_id = ? ', params[:contributor_id], reviewer.id]) to more rails quey like ReviewResponseMap.where(reviewee_id: params[:contributor_id],reviewer_id: reviewer.id)&lt;br /&gt;
# We search the function name(''add_user_to_assignment'') in the whole files, and find that this method is invoked in &amp;quot;participants_helper.rb&amp;quot;, and also being invoked in the function of ''add_reviewer'' and ''add_metareviewer'' in the controller of ''review_mapping_controller'' &lt;br /&gt;
# By searching the whole project and routes, we verify that methods ''add_self_reviewer'' and ''get_team_from_submission'' in this controller are not called by any other methods except for views &amp;quot;show_available_submissions_for_quizzes.html.erb&amp;quot; and &amp;quot;show_available_submissions.html.erb&amp;quot;. And those two views are not linked to any other views. So they are deleted from the project.&lt;br /&gt;
# We already renamed method ''delete_all_reviewers'' to ''delete_outstanding_reviewers'' and changed the corresponding button name at the corresponding view (_list_review_mappings.html.erb).&lt;br /&gt;
# By searching the whole project and routes, we verify that methods'' release_reservation'' in this controller are not used in anywhere.&lt;br /&gt;
# By searching the whole project and routes, we verify that methods ''delete_mappings'' in this controller are not used in anywhere.&lt;br /&gt;
# Method ''automatic_review_mapping_strategy'' have many long lines. We already shorten each long line to multiple lines. And also, we split this long function into three different functions.&lt;br /&gt;
&lt;br /&gt;
=Code=&lt;br /&gt;
&lt;br /&gt;
==Refactor SQL query code==&lt;br /&gt;
&lt;br /&gt;
The rails query we change in this controller:&lt;br /&gt;
&lt;br /&gt;
1. From &lt;br /&gt;
&lt;br /&gt;
  ReviewResponseMap.where(['reviewee_id = ? and reviewer_id = ? ', params[:contributor_id], reviewer.id]) &lt;br /&gt;
&lt;br /&gt;
To&lt;br /&gt;
&lt;br /&gt;
  ReviewResponseMap.where(reviewee_id: params[:contributor_id],reviewer_id: reviewer.id)&lt;br /&gt;
&lt;br /&gt;
2. From&lt;br /&gt;
&lt;br /&gt;
  MetareviewResponseMap.where(['reviewed_object_id = ? and reviewer_id = ?', mapping.map_id, reviewer.id])&lt;br /&gt;
&lt;br /&gt;
To&lt;br /&gt;
&lt;br /&gt;
  MetareviewResponseMap.where(reviewed_object_id: mapping.map_id, reviewer_id: reviewer.id)&lt;br /&gt;
&lt;br /&gt;
3. From&lt;br /&gt;
&lt;br /&gt;
                   @assignments = Assignment&lt;br /&gt;
                   .where([&amp;quot;instructor_id = ? and substring(name,1,1) = ?&amp;quot;, session[:user].id, letter])&lt;br /&gt;
                   .order('name')&lt;br /&gt;
                   .page(params[:page])&lt;br /&gt;
                   .per_page(10)&lt;br /&gt;
&lt;br /&gt;
To &lt;br /&gt;
&lt;br /&gt;
                   @assignments = Assignment&lt;br /&gt;
                   .where(instructor_id:session[:user].id)&lt;br /&gt;
                   .where(&amp;quot;substring(name,1,1) = :letter&amp;quot;,{letter:letter})&lt;br /&gt;
                   .order('name')&lt;br /&gt;
                   .page(params[:page])&lt;br /&gt;
                   .per_page(10)&lt;br /&gt;
&lt;br /&gt;
4.  From&lt;br /&gt;
&lt;br /&gt;
  ReviewResponseMap.where([&amp;quot;reviewed_object_id = ? and calibrate_to = ?&amp;quot;, assignment_id, 1])&lt;br /&gt;
&lt;br /&gt;
To &lt;br /&gt;
&lt;br /&gt;
  ReviewResponseMap.where(reviewed_object_id:assignment_id, calibrate_to: 1)&lt;br /&gt;
&lt;br /&gt;
5. From&lt;br /&gt;
&lt;br /&gt;
  ReviewResponseMap.where([&amp;quot;reviewed_object_id = ? and created_at &amp;gt; ? and calibrate_to = ?&amp;quot;, assignment_id, @@time_create_last_review_mapping_record, 0])&lt;br /&gt;
&lt;br /&gt;
To &lt;br /&gt;
&lt;br /&gt;
  ReviewResponseMap.where(reviewed_object_id:assignment_id,calibrate_to:0).where(&amp;quot;created_at &amp;gt; :time&amp;quot;,{time:@@time_create_last_review_mapping_record})&lt;br /&gt;
&lt;br /&gt;
6. From&lt;br /&gt;
&lt;br /&gt;
  AssignmentQuestionnaire.where([&amp;quot;assignment_id = ? and questionnaire_id IN (?)&amp;quot;, params[:id], @review_questionnaire_ids])&lt;br /&gt;
&lt;br /&gt;
To&lt;br /&gt;
 &lt;br /&gt;
  AssignmentQuestionnaire.where(assignment_id: params[:id],:questionnaire_id =&amp;gt; @review_questionnaire_ids)&lt;br /&gt;
&lt;br /&gt;
7. From&lt;br /&gt;
&lt;br /&gt;
  SelfReviewResponseMap.where(['reviewee_id = ? and reviewer_id = ?', team_id[0].t_id, params[:reviewer_id]])&lt;br /&gt;
&lt;br /&gt;
To &lt;br /&gt;
&lt;br /&gt;
  SelfReviewResponseMap.where(reviewee_id:team_id[0].t_id,reviewer_id:params[:reviewer_id])&lt;br /&gt;
&lt;br /&gt;
==Refactor long line method==&lt;br /&gt;
&lt;br /&gt;
  def automatic_review_mapping_strategy(assignment_id,&lt;br /&gt;
                                        participants, teams, student_review_num = 0,&lt;br /&gt;
                                        submission_review_num = 0)&lt;br /&gt;
    participants_hash = {}&lt;br /&gt;
    participants.each {|participant| participants_hash[participant.id] = 0 }&lt;br /&gt;
    # calculate reviewers for each team&lt;br /&gt;
    num_participants = participants.size&lt;br /&gt;
    if student_review_num != 0 and submission_review_num == 0&lt;br /&gt;
      num_reviews_per_team = (participants.size * student_review_num * 1.0 / teams.size).round&lt;br /&gt;
      student_review_num = student_review_num&lt;br /&gt;
      exact_num_of_review_needed = participants.size * student_review_num&lt;br /&gt;
    elsif student_review_num == 0 and submission_review_num != 0&lt;br /&gt;
      num_reviews_per_team = submission_review_num&lt;br /&gt;
      student_review_num = (teams.size * submission_review_num * 1.0 / participants.size).round&lt;br /&gt;
      exact_num_of_review_needed = teams.size * submission_review_num&lt;br /&gt;
    end&lt;br /&gt;
    execute_peer_review_strategy(assignment_id, teams, num_participants,&lt;br /&gt;
                                     student_review_num, num_reviews_per_team,&lt;br /&gt;
                                     participants, participants_hash)&lt;br /&gt;
    # after assigning peer reviews for each team,&lt;br /&gt;
    # if there are still some peer reviewers not obtain enough peer review,&lt;br /&gt;
    # just assign them to valid teams&lt;br /&gt;
    assign_reviewers_for_team(assignment_id,student_review_num,participants_hash,&lt;br /&gt;
                              exact_num_of_review_needed)&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  def assign_reviewers_for_team(assignment_id,student_review_num,participants_hash,&lt;br /&gt;
                                exact_num_of_review_needed)&lt;br /&gt;
    if ReviewResponseMap.where([&amp;quot;reviewed_object_id = ? and created_at &amp;gt; ? and calibrate_to = ?&amp;quot;, &lt;br /&gt;
                                assignment_id, &lt;br /&gt;
                                @@time_create_last_review_mapping_record, 0]).size &amp;lt; exact_num_of_review_needed&lt;br /&gt;
      participants_with_insufficient_review_num = []&lt;br /&gt;
      participants_hash.each do |participant_id, review_num|&lt;br /&gt;
        participants_with_insufficient_review_num &amp;lt;&amp;lt; participant_id if review_num &amp;lt; student_review_num&lt;br /&gt;
      end&lt;br /&gt;
      unsorted_teams_hash = {}&lt;br /&gt;
      ReviewResponseMap.where([&amp;quot;reviewed_object_id = ? and calibrate_to = ?&amp;quot;, &lt;br /&gt;
                               assignment_id, 0]).each do |response_map|&lt;br /&gt;
        if unsorted_teams_hash.key? response_map.reviewee_id&lt;br /&gt;
          unsorted_teams_hash[response_map.reviewee_id] += 1&lt;br /&gt;
        else&lt;br /&gt;
          unsorted_teams_hash[response_map.reviewee_id] = 1&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
      teams_hash = unsorted_teams_hash.sort_by {|_, v| v }.to_h&lt;br /&gt;
      participants_with_insufficient_review_num.each do |participant_id|&lt;br /&gt;
        teams_hash.each do |team_id, _num_review_received|&lt;br /&gt;
          next if TeamsUser.exists?(team_id: team_id, &lt;br /&gt;
                                    user_id: Participant.find(participant_id).user_id)&lt;br /&gt;
          ReviewResponseMap.where(reviewee_id: team_id, reviewer_id: participant_id, &lt;br /&gt;
                                  reviewed_object_id: assignment_id).first_or_create&lt;br /&gt;
          teams_hash[team_id] += 1&lt;br /&gt;
          teams_hash = teams_hash.sort_by {|_, v| v }.to_h&lt;br /&gt;
          break&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
    @@time_create_last_review_mapping_record = ReviewResponseMap.&lt;br /&gt;
                                               where(reviewed_object_id: assignment_id).&lt;br /&gt;
                                               last.created_at&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def execute_peer_review_strategy(assignment_id, teams, num_participants, &lt;br /&gt;
                                   student_review_num, num_reviews_per_team, &lt;br /&gt;
                                   participants, participants_hash)&lt;br /&gt;
    # Exception detection: If instructor want to assign too many reviews done&lt;br /&gt;
    # by each student, there will be an error msg.&lt;br /&gt;
    if student_review_num &amp;gt;= teams.size&lt;br /&gt;
      flash[:error] = 'You cannot set the number of reviews done &lt;br /&gt;
      by each student to be greater than or equal to total number of teams &lt;br /&gt;
      [or &amp;quot;participants&amp;quot; if it is an individual assignment].'&lt;br /&gt;
    end&lt;br /&gt;
    peer_review_strategy(assignment_id, teams, num_participants, &lt;br /&gt;
                         student_review_num, num_reviews_per_team, &lt;br /&gt;
                         participants, participants_hash)&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
=Test=&lt;br /&gt;
We write RSpec feature tests to prove that all changes are correct and the project performs well as before.&lt;br /&gt;
&lt;br /&gt;
The function of  method automatic_review_mapping is to automatically assign reviews on students in teams when instructor set either student review number or submissions review number. There is constraint that only one of the two numbers must be set value other than 0 (that is, one is 0 and other is not 0). To test the correctness  of our refactoring, we design a scenario and 4 cases of assigning reviews to students:&lt;br /&gt;
&lt;br /&gt;
Case 1. Instructor has not set both students review number and submissions review number (They are both 0). The page will show a notice.&lt;br /&gt;
&lt;br /&gt;
Case 2. Instructor set both numbers (They are both not 0). The page will show a notice.&lt;br /&gt;
&lt;br /&gt;
Case 3. Instructors set students review number. The controller will change database: create new relationship in ReviewResponseMap. For example, if assign student review number to 2, and there will be 20 peer reviews in total and need to allocate to 3 teams. So each team get 7 reviews on average and 1 team’s artifact will be reviewed 6 times.&lt;br /&gt;
&lt;br /&gt;
Case 4. Instructors set submissions review number. The controller will change database: create new relationship in ReviewResponseMap. For example, if assign submission review number to 3, and there will be 21 peer reviews in total to allocate to 10 participants. So every participants get 2 reviews. 9 among 10 participants will review 2 teams’ artifacts and 1 participant will review 3 teams’ artifacts.&lt;br /&gt;
&lt;br /&gt;
require 'rails_helper'&lt;br /&gt;
  describe &amp;quot;review mapping&amp;quot;, js: true do&lt;br /&gt;
    before(:each) do&lt;br /&gt;
      #create test data&lt;br /&gt;
    end&lt;br /&gt;
 &lt;br /&gt;
    it &amp;quot;show error when assign both 0&amp;quot; do&lt;br /&gt;
      login_as(&amp;quot;instructor6&amp;quot;)&lt;br /&gt;
      visit '/assignments/1/edit'&lt;br /&gt;
      find_link('ReviewStrategy').click&lt;br /&gt;
      select &amp;quot;Instructor-Selected&amp;quot;, from: 'assignment_form_assignment_review_assignment_strategy'&lt;br /&gt;
      fill_in 'num_reviews_per_student', with: 0&lt;br /&gt;
      choose 'num_reviews_submission'&lt;br /&gt;
      fill_in 'num_reviews_per_submission', with: 0&lt;br /&gt;
      click_button 'second_submit_tag'&lt;br /&gt;
      #click_button 'Save'&lt;br /&gt;
      expect(page).to have_content('Please choose either the number of reviews per student or the number of reviewers per team (student)')&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    it &amp;quot;show error when assign both numbers&amp;quot; do&lt;br /&gt;
      login_as(&amp;quot;instructor6&amp;quot;)&lt;br /&gt;
      visit '/assignments/1/edit'&lt;br /&gt;
      find_link('ReviewStrategy').click&lt;br /&gt;
      select &amp;quot;Instructor-Selected&amp;quot;, from: 'assignment_form_assignment_review_assignment_strategy'&lt;br /&gt;
      fill_in 'num_reviews_per_student', with: 1&lt;br /&gt;
      choose 'num_reviews_submission'&lt;br /&gt;
      fill_in 'num_reviews_per_submission', with: 1&lt;br /&gt;
      click_button 'second_submit_tag'&lt;br /&gt;
      #click_button 'Save'&lt;br /&gt;
      expect(page).to have_content('Please choose either the number of reviews per student or the number of reviewers per team (student), not both')&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    it &amp;quot;calculate reviewmapping from given review number per student&amp;quot; do&lt;br /&gt;
      login_as(&amp;quot;instructor6&amp;quot;)&lt;br /&gt;
      visit '/assignments/1/edit'&lt;br /&gt;
      find_link('ReviewStrategy').click&lt;br /&gt;
      select &amp;quot;Instructor-Selected&amp;quot;, from: 'assignment_form_assignment_review_assignment_strategy'&lt;br /&gt;
      fill_in 'num_reviews_per_student', with: 2&lt;br /&gt;
      click_button 'first_submit_tag'&lt;br /&gt;
      num = ReviewResponseMap.where(reviewee_id: @team1.id, reviewed_object_id: @assignment.id).count&lt;br /&gt;
      expect(num).to eq(7)&lt;br /&gt;
      num2 = ReviewResponseMap.where(reviewee_id: @team3.id, reviewed_object_id: @assignment.id).count&lt;br /&gt;
      expect(num2).to eq(6)&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    it &amp;quot;calculate reviewmapping from given review number per submission&amp;quot; do&lt;br /&gt;
      login_as(&amp;quot;instructor6&amp;quot;)&lt;br /&gt;
      visit '/assignments/1/edit'&lt;br /&gt;
      find_link('ReviewStrategy').click&lt;br /&gt;
      select &amp;quot;Instructor-Selected&amp;quot;, from: 'assignment_form_assignment_review_assignment_strategy'&lt;br /&gt;
      choose 'num_reviews_submission'&lt;br /&gt;
      fill_in 'num_reviews_per_submission', with: 7&lt;br /&gt;
      click_button 'second_submit_tag'&lt;br /&gt;
      #click_button 'Save'&lt;br /&gt;
      num = ReviewResponseMap.where(reviewer_id: @teamuser1.id, reviewed_object_id: @assignment.id).count&lt;br /&gt;
      expect(num).to eq(2)&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;/div&gt;</summary>
		<author><name>Jdeng8</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2016/E1641._Refactor_review_mapping_controller.rb&amp;diff=103931</id>
		<title>CSC/ECE 517 Fall 2016/E1641. Refactor review mapping controller.rb</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2016/E1641._Refactor_review_mapping_controller.rb&amp;diff=103931"/>
		<updated>2016-10-29T05:34:42Z</updated>

		<summary type="html">&lt;p&gt;Jdeng8: /* Current Implementation and Problems */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=Background=&lt;br /&gt;
&lt;br /&gt;
This controller sets up mappings between reviewer and reviewee. It handles all different types of response maps (review response map, author feedback response map, teammate review response map, meta review response map and quiz response map). The class has functionality for five different kinds of Responses: reviews, metareviews, teammate reviews, author feedback (“rejoinders”), and quizzes. &lt;br /&gt;
&lt;br /&gt;
=Current Implementation and Problems=&lt;br /&gt;
&lt;br /&gt;
# Method ''response_report'' has some SQL - like code.  Rewrite with Active Record.&lt;br /&gt;
# Test whether method ''add_user_to_assignment'' is used. There is no way that this method should be in ReviewMappingController. Please remove this method and caller.&lt;br /&gt;
# There was a ''self-review'' feature, the method ''add_self_reviewer'', ''get_team_from_submission'' are related to this. Two views calls ''add_self_reviewer'' are &amp;quot;show_available_submissions_for_quizzes.html.erb&amp;quot; and &amp;quot;show_available_submissions.html.erb&amp;quot;. The names of views are not related to ''self_review'' feature. Plus those two views are not called anywhere. Please verify this and if so, you should delete those two views, two method and also related records (e.g. in routes.rb).&lt;br /&gt;
# Method ''delete_all_reviewers'' actually only deletes the outstanding review response maps (the ones which has been initiated, but there is no response yet). So it should better be named ''delete_outstanding_reviewers''. You can try to test this method by clicking “Assign reviewers” icon on an assignment.&lt;br /&gt;
# Method ''release_reservation'' should be renamed as'' release_mapping''. In addition, delete it if you find this method is not called anywhere.&lt;br /&gt;
# Method ''delete_mappings'' is problematic. It does not looks like a controller method. Please refactor it or delete it if you can validate that this method is not called anywhere.&lt;br /&gt;
# Method'' automatic_review_mapping_strategy'' is too long. Please refactor and test it.&lt;br /&gt;
&lt;br /&gt;
=Changes Implemented=&lt;br /&gt;
&lt;br /&gt;
# change the rails query from sql like code, like ReviewResponseMap.where(['reviewee_id = ? and reviewer_id = ? ', params[:contributor_id], reviewer.id]) to more rails quey like ReviewResponseMap.where(reviewee_id: params[:contributor_id],reviewer_id: reviewer.id)&lt;br /&gt;
# We search the function name(''add_user_to_assignment'') in the whole files, and find that this method is invoked in &amp;quot;participants_helper.rb&amp;quot;, and also being invoked in the function of ''add_reviewer'' and ''add_metareviewer'' in the controller of ''review_mapping_controller'' &lt;br /&gt;
# By searching the whole project and routes, we verify that methods ''add_self_reviewer'' and ''get_team_from_submission'' in this controller are not called by any other methods except for views &amp;quot;show_available_submissions_for_quizzes.html.erb&amp;quot; and &amp;quot;show_available_submissions.html.erb&amp;quot;. And those two views are not linked to any other views. So they are deleted from the project.&lt;br /&gt;
# We already renamed method ''delete_all_reviewers'' to ''delete_outstanding_reviewers'' and changed the corresponding button name at the corresponding view (_list_review_mappings.html.erb).&lt;br /&gt;
# By searching the whole project and routes, we verify that methods'' release_reservation'' in this controller are not used in anywhere.&lt;br /&gt;
# By searching the whole project and routes, we verify that methods ''delete_mappings'' in this controller are not used in anywhere.&lt;br /&gt;
# Method ''automatic_review_mapping_strategy'' have many long lines. We already shorten each long line to multiple lines. And also, we split this long function into three different functions.&lt;br /&gt;
&lt;br /&gt;
=Code=&lt;br /&gt;
&lt;br /&gt;
==Refactor SQL query code==&lt;br /&gt;
&lt;br /&gt;
The rails query we change in this controller:&lt;br /&gt;
&lt;br /&gt;
1. From &lt;br /&gt;
&lt;br /&gt;
  ReviewResponseMap.where(['reviewee_id = ? and reviewer_id = ? ', params[:contributor_id], reviewer.id]) &lt;br /&gt;
&lt;br /&gt;
To&lt;br /&gt;
&lt;br /&gt;
  ReviewResponseMap.where(reviewee_id: params[:contributor_id],reviewer_id: reviewer.id)&lt;br /&gt;
&lt;br /&gt;
2. From&lt;br /&gt;
&lt;br /&gt;
  MetareviewResponseMap.where(['reviewed_object_id = ? and reviewer_id = ?', mapping.map_id, reviewer.id])&lt;br /&gt;
&lt;br /&gt;
To&lt;br /&gt;
&lt;br /&gt;
  MetareviewResponseMap.where(reviewed_object_id: mapping.map_id, reviewer_id: reviewer.id)&lt;br /&gt;
&lt;br /&gt;
3. From&lt;br /&gt;
&lt;br /&gt;
                   @assignments = Assignment&lt;br /&gt;
                   .where([&amp;quot;instructor_id = ? and substring(name,1,1) = ?&amp;quot;, session[:user].id, letter])&lt;br /&gt;
                   .order('name')&lt;br /&gt;
                   .page(params[:page])&lt;br /&gt;
                   .per_page(10)&lt;br /&gt;
&lt;br /&gt;
To &lt;br /&gt;
&lt;br /&gt;
                   @assignments = Assignment&lt;br /&gt;
                   .where(instructor_id:session[:user].id)&lt;br /&gt;
                   .where(&amp;quot;substring(name,1,1) = :letter&amp;quot;,{letter:letter})&lt;br /&gt;
                   .order('name')&lt;br /&gt;
                   .page(params[:page])&lt;br /&gt;
                   .per_page(10)&lt;br /&gt;
&lt;br /&gt;
4.  From&lt;br /&gt;
&lt;br /&gt;
  ReviewResponseMap.where([&amp;quot;reviewed_object_id = ? and calibrate_to = ?&amp;quot;, assignment_id, 1])&lt;br /&gt;
&lt;br /&gt;
To &lt;br /&gt;
&lt;br /&gt;
  ReviewResponseMap.where(reviewed_object_id:assignment_id, calibrate_to: 1)&lt;br /&gt;
&lt;br /&gt;
5. From&lt;br /&gt;
&lt;br /&gt;
  ReviewResponseMap.where([&amp;quot;reviewed_object_id = ? and created_at &amp;gt; ? and calibrate_to = ?&amp;quot;, assignment_id, @@time_create_last_review_mapping_record, 0])&lt;br /&gt;
&lt;br /&gt;
To &lt;br /&gt;
&lt;br /&gt;
  ReviewResponseMap.where(reviewed_object_id:assignment_id,calibrate_to:0).where(&amp;quot;created_at &amp;gt; :time&amp;quot;,{time:@@time_create_last_review_mapping_record})&lt;br /&gt;
&lt;br /&gt;
6. From&lt;br /&gt;
&lt;br /&gt;
  AssignmentQuestionnaire.where([&amp;quot;assignment_id = ? and questionnaire_id IN (?)&amp;quot;, params[:id], @review_questionnaire_ids])&lt;br /&gt;
&lt;br /&gt;
To&lt;br /&gt;
 &lt;br /&gt;
  AssignmentQuestionnaire.where(assignment_id: params[:id],:questionnaire_id =&amp;gt; @review_questionnaire_ids)&lt;br /&gt;
&lt;br /&gt;
7. From&lt;br /&gt;
&lt;br /&gt;
  SelfReviewResponseMap.where(['reviewee_id = ? and reviewer_id = ?', team_id[0].t_id, params[:reviewer_id]])&lt;br /&gt;
&lt;br /&gt;
To &lt;br /&gt;
&lt;br /&gt;
  SelfReviewResponseMap.where(reviewee_id:team_id[0].t_id,reviewer_id:params[:reviewer_id])&lt;br /&gt;
&lt;br /&gt;
==Refactor long line method==&lt;br /&gt;
&lt;br /&gt;
  def automatic_review_mapping_strategy(assignment_id,&lt;br /&gt;
                                        participants, teams, student_review_num = 0,&lt;br /&gt;
                                        submission_review_num = 0)&lt;br /&gt;
    participants_hash = {}&lt;br /&gt;
    participants.each {|participant| participants_hash[participant.id] = 0 }&lt;br /&gt;
    # calculate reviewers for each team&lt;br /&gt;
    num_participants = participants.size&lt;br /&gt;
    if student_review_num != 0 and submission_review_num == 0&lt;br /&gt;
      num_reviews_per_team = (participants.size * student_review_num * 1.0 / teams.size).round&lt;br /&gt;
      student_review_num = student_review_num&lt;br /&gt;
      exact_num_of_review_needed = participants.size * student_review_num&lt;br /&gt;
    elsif student_review_num == 0 and submission_review_num != 0&lt;br /&gt;
      num_reviews_per_team = submission_review_num&lt;br /&gt;
      student_review_num = (teams.size * submission_review_num * 1.0 / participants.size).round&lt;br /&gt;
      exact_num_of_review_needed = teams.size * submission_review_num&lt;br /&gt;
    end&lt;br /&gt;
    execute_peer_review_strategy(assignment_id, teams, num_participants,&lt;br /&gt;
                                     student_review_num, num_reviews_per_team,&lt;br /&gt;
                                     participants, participants_hash)&lt;br /&gt;
    # after assigning peer reviews for each team,&lt;br /&gt;
    # if there are still some peer reviewers not obtain enough peer review,&lt;br /&gt;
    # just assign them to valid teams&lt;br /&gt;
    assign_reviewers_for_team(assignment_id,student_review_num,participants_hash,&lt;br /&gt;
                              exact_num_of_review_needed)&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  def assign_reviewers_for_team(assignment_id,student_review_num,participants_hash,&lt;br /&gt;
                                exact_num_of_review_needed)&lt;br /&gt;
    if ReviewResponseMap.where([&amp;quot;reviewed_object_id = ? and created_at &amp;gt; ? and calibrate_to = ?&amp;quot;, &lt;br /&gt;
                                assignment_id, &lt;br /&gt;
                                @@time_create_last_review_mapping_record, 0]).size &amp;lt; exact_num_of_review_needed&lt;br /&gt;
      participants_with_insufficient_review_num = []&lt;br /&gt;
      participants_hash.each do |participant_id, review_num|&lt;br /&gt;
        participants_with_insufficient_review_num &amp;lt;&amp;lt; participant_id if review_num &amp;lt; student_review_num&lt;br /&gt;
      end&lt;br /&gt;
      unsorted_teams_hash = {}&lt;br /&gt;
      ReviewResponseMap.where([&amp;quot;reviewed_object_id = ? and calibrate_to = ?&amp;quot;, &lt;br /&gt;
                               assignment_id, 0]).each do |response_map|&lt;br /&gt;
        if unsorted_teams_hash.key? response_map.reviewee_id&lt;br /&gt;
          unsorted_teams_hash[response_map.reviewee_id] += 1&lt;br /&gt;
        else&lt;br /&gt;
          unsorted_teams_hash[response_map.reviewee_id] = 1&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
      teams_hash = unsorted_teams_hash.sort_by {|_, v| v }.to_h&lt;br /&gt;
      participants_with_insufficient_review_num.each do |participant_id|&lt;br /&gt;
        teams_hash.each do |team_id, _num_review_received|&lt;br /&gt;
          next if TeamsUser.exists?(team_id: team_id, &lt;br /&gt;
                                    user_id: Participant.find(participant_id).user_id)&lt;br /&gt;
          ReviewResponseMap.where(reviewee_id: team_id, reviewer_id: participant_id, &lt;br /&gt;
                                  reviewed_object_id: assignment_id).first_or_create&lt;br /&gt;
          teams_hash[team_id] += 1&lt;br /&gt;
          teams_hash = teams_hash.sort_by {|_, v| v }.to_h&lt;br /&gt;
          break&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
    @@time_create_last_review_mapping_record = ReviewResponseMap.&lt;br /&gt;
                                               where(reviewed_object_id: assignment_id).&lt;br /&gt;
                                               last.created_at&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def execute_peer_review_strategy(assignment_id, teams, num_participants, &lt;br /&gt;
                                   student_review_num, num_reviews_per_team, &lt;br /&gt;
                                   participants, participants_hash)&lt;br /&gt;
    # Exception detection: If instructor want to assign too many reviews done&lt;br /&gt;
    # by each student, there will be an error msg.&lt;br /&gt;
    if student_review_num &amp;gt;= teams.size&lt;br /&gt;
      flash[:error] = 'You cannot set the number of reviews done &lt;br /&gt;
      by each student to be greater than or equal to total number of teams &lt;br /&gt;
      [or &amp;quot;participants&amp;quot; if it is an individual assignment].'&lt;br /&gt;
    end&lt;br /&gt;
    peer_review_strategy(assignment_id, teams, num_participants, &lt;br /&gt;
                         student_review_num, num_reviews_per_team, &lt;br /&gt;
                         participants, participants_hash)&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
=Test=&lt;br /&gt;
We write RSpec feature tests to prove that all changes are correct and the project performs well as before.&lt;br /&gt;
&lt;br /&gt;
The function of  method automatic_review_mapping is to automatically assign reviews on students in teams when instructor set either student review number or submissions review number. There is constraint that only one of the two numbers must be set value other than 0 (that is, one is 0 and other is not 0). To test the correctness  of our refactoring, we design a scenario and 4 cases of assigning reviews to students:&lt;br /&gt;
&lt;br /&gt;
Case 1. Instructor has not set both students review number and submissions review number (They are both 0). The page will show a notice.&lt;br /&gt;
&lt;br /&gt;
Case 2. Instructor set both numbers (They are both not 0). The page will show a notice.&lt;br /&gt;
&lt;br /&gt;
Case 3. Instructors set students review number. The controller will change database: create new relationship in ReviewResponseMap. For example, if assign student review number to 2, and there will be 20 peer reviews in total and need to allocate to 3 teams. So each team get 7 reviews on average and 1 team’s artifact will be reviewed 6 times.&lt;br /&gt;
&lt;br /&gt;
Case 4. Instructors set submissions review number. The controller will change database: create new relationship in ReviewResponseMap. For example, if assign submission review number to 3, and there will be 21 peer reviews in total to allocate to 10 participants. So every participants get 2 reviews. 9 among 10 participants will review 2 teams’ artifacts and 1 participant will review 3 teams’ artifacts.&lt;br /&gt;
&lt;br /&gt;
require 'rails_helper'&lt;br /&gt;
  describe &amp;quot;review mapping&amp;quot;, js: true do&lt;br /&gt;
    before(:each) do&lt;br /&gt;
      #create test data&lt;br /&gt;
    end&lt;br /&gt;
 &lt;br /&gt;
    it &amp;quot;show error when assign both 0&amp;quot; do&lt;br /&gt;
      login_as(&amp;quot;instructor6&amp;quot;)&lt;br /&gt;
      visit '/assignments/1/edit'&lt;br /&gt;
      find_link('ReviewStrategy').click&lt;br /&gt;
      select &amp;quot;Instructor-Selected&amp;quot;, from: 'assignment_form_assignment_review_assignment_strategy'&lt;br /&gt;
      fill_in 'num_reviews_per_student', with: 0&lt;br /&gt;
      choose 'num_reviews_submission'&lt;br /&gt;
      fill_in 'num_reviews_per_submission', with: 0&lt;br /&gt;
      click_button 'second_submit_tag'&lt;br /&gt;
      #click_button 'Save'&lt;br /&gt;
      expect(page).to have_content('Please choose either the number of reviews per student or the number of reviewers per team (student)')&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    it &amp;quot;show error when assign both numbers&amp;quot; do&lt;br /&gt;
      login_as(&amp;quot;instructor6&amp;quot;)&lt;br /&gt;
      visit '/assignments/1/edit'&lt;br /&gt;
      find_link('ReviewStrategy').click&lt;br /&gt;
      select &amp;quot;Instructor-Selected&amp;quot;, from: 'assignment_form_assignment_review_assignment_strategy'&lt;br /&gt;
      fill_in 'num_reviews_per_student', with: 1&lt;br /&gt;
      choose 'num_reviews_submission'&lt;br /&gt;
      fill_in 'num_reviews_per_submission', with: 1&lt;br /&gt;
      click_button 'second_submit_tag'&lt;br /&gt;
      #click_button 'Save'&lt;br /&gt;
      expect(page).to have_content('Please choose either the number of reviews per student or the number of reviewers per team (student), not both')&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    it &amp;quot;calculate reviewmapping from given review number per student&amp;quot; do&lt;br /&gt;
      login_as(&amp;quot;instructor6&amp;quot;)&lt;br /&gt;
      visit '/assignments/1/edit'&lt;br /&gt;
      find_link('ReviewStrategy').click&lt;br /&gt;
      select &amp;quot;Instructor-Selected&amp;quot;, from: 'assignment_form_assignment_review_assignment_strategy'&lt;br /&gt;
      fill_in 'num_reviews_per_student', with: 2&lt;br /&gt;
      click_button 'first_submit_tag'&lt;br /&gt;
      num = ReviewResponseMap.where(reviewee_id: @team1.id, reviewed_object_id: @assignment.id).count&lt;br /&gt;
      expect(num).to eq(7)&lt;br /&gt;
      num2 = ReviewResponseMap.where(reviewee_id: @team3.id, reviewed_object_id: @assignment.id).count&lt;br /&gt;
      expect(num2).to eq(6)&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    it &amp;quot;calculate reviewmapping from given review number per submission&amp;quot; do&lt;br /&gt;
      login_as(&amp;quot;instructor6&amp;quot;)&lt;br /&gt;
      visit '/assignments/1/edit'&lt;br /&gt;
      find_link('ReviewStrategy').click&lt;br /&gt;
      select &amp;quot;Instructor-Selected&amp;quot;, from: 'assignment_form_assignment_review_assignment_strategy'&lt;br /&gt;
      choose 'num_reviews_submission'&lt;br /&gt;
      fill_in 'num_reviews_per_submission', with: 7&lt;br /&gt;
      click_button 'second_submit_tag'&lt;br /&gt;
      #click_button 'Save'&lt;br /&gt;
      num = ReviewResponseMap.where(reviewer_id: @teamuser1.id, reviewed_object_id: @assignment.id).count&lt;br /&gt;
      expect(num).to eq(2)&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;/div&gt;</summary>
		<author><name>Jdeng8</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2016/E1641._Refactor_review_mapping_controller.rb&amp;diff=103926</id>
		<title>CSC/ECE 517 Fall 2016/E1641. Refactor review mapping controller.rb</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2016/E1641._Refactor_review_mapping_controller.rb&amp;diff=103926"/>
		<updated>2016-10-29T05:32:14Z</updated>

		<summary type="html">&lt;p&gt;Jdeng8: /* Current Implementation and Problems */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=Background=&lt;br /&gt;
&lt;br /&gt;
This controller sets up mappings between reviewer and reviewee. It handles all different types of response maps (review response map, author feedback response map, teammate review response map, meta review response map and quiz response map). The class has functionality for five different kinds of Responses: reviews, metareviews, teammate reviews, author feedback (“rejoinders”), and quizzes. &lt;br /&gt;
&lt;br /&gt;
=Current Implementation and Problems=&lt;br /&gt;
&lt;br /&gt;
# Method ''response_report'' has some [[w:SQL|SQL]] - like code.  Rewrite with [Active Record].&lt;br /&gt;
# Test whether method ''add_user_to_assignment'' is used. There is no way that this method should be in ReviewMappingController. Please remove this method and caller.&lt;br /&gt;
# There was a ''self-review'' feature, the method ''add_self_reviewer'', ''get_team_from_submission'' are related to this. Two views calls ''add_self_reviewer'' are &amp;quot;show_available_submissions_for_quizzes.html.erb&amp;quot; and &amp;quot;show_available_submissions.html.erb&amp;quot;. The names of views are not related to ''self_review'' feature. Plus those two views are not called anywhere. Please verify this and if so, you should delete those two views, two method and also related records (e.g. in routes.rb).&lt;br /&gt;
# Method ''delete_all_reviewers'' actually only deletes the outstanding review response maps (the ones which has been initiated, but there is no response yet). So it should better be named ''delete_outstanding_reviewers''. You can try to test this method by clicking “Assign reviewers” icon on an assignment.&lt;br /&gt;
# Method ''release_reservation'' should be renamed as'' release_mapping''. In addition, delete it if you find this method is not called anywhere.&lt;br /&gt;
# Method ''delete_mappings'' is problematic. It does not looks like a controller method. Please refactor it or delete it if you can validate that this method is not called anywhere.&lt;br /&gt;
# Method'' automatic_review_mapping_strategy'' is too long. Please refactor and test it.&lt;br /&gt;
&lt;br /&gt;
=Changes Implemented=&lt;br /&gt;
&lt;br /&gt;
# change the rails query from sql like code, like ReviewResponseMap.where(['reviewee_id = ? and reviewer_id = ? ', params[:contributor_id], reviewer.id]) to more rails quey like ReviewResponseMap.where(reviewee_id: params[:contributor_id],reviewer_id: reviewer.id)&lt;br /&gt;
# We search the function name(''add_user_to_assignment'') in the whole files, and find that this method is invoked in &amp;quot;participants_helper.rb&amp;quot;, and also being invoked in the function of ''add_reviewer'' and ''add_metareviewer'' in the controller of ''review_mapping_controller'' &lt;br /&gt;
# By searching the whole project and routes, we verify that methods ''add_self_reviewer'' and ''get_team_from_submission'' in this controller are not called by any other methods except for views &amp;quot;show_available_submissions_for_quizzes.html.erb&amp;quot; and &amp;quot;show_available_submissions.html.erb&amp;quot;. And those two views are not linked to any other views. So they are deleted from the project.&lt;br /&gt;
# We already renamed method ''delete_all_reviewers'' to ''delete_outstanding_reviewers'' and changed the corresponding button name at the corresponding view (_list_review_mappings.html.erb).&lt;br /&gt;
# By searching the whole project and routes, we verify that methods'' release_reservation'' in this controller are not used in anywhere.&lt;br /&gt;
# By searching the whole project and routes, we verify that methods ''delete_mappings'' in this controller are not used in anywhere.&lt;br /&gt;
# Method ''automatic_review_mapping_strategy'' have many long lines. We already shorten each long line to multiple lines. And also, we split this long function into three different functions.&lt;br /&gt;
&lt;br /&gt;
=Code=&lt;br /&gt;
&lt;br /&gt;
==Refactor SQL query code==&lt;br /&gt;
&lt;br /&gt;
The rails query we change in this controller:&lt;br /&gt;
&lt;br /&gt;
1. From &lt;br /&gt;
&lt;br /&gt;
  ReviewResponseMap.where(['reviewee_id = ? and reviewer_id = ? ', params[:contributor_id], reviewer.id]) &lt;br /&gt;
&lt;br /&gt;
To&lt;br /&gt;
&lt;br /&gt;
  ReviewResponseMap.where(reviewee_id: params[:contributor_id],reviewer_id: reviewer.id)&lt;br /&gt;
&lt;br /&gt;
2. From&lt;br /&gt;
&lt;br /&gt;
  MetareviewResponseMap.where(['reviewed_object_id = ? and reviewer_id = ?', mapping.map_id, reviewer.id])&lt;br /&gt;
&lt;br /&gt;
To&lt;br /&gt;
&lt;br /&gt;
  MetareviewResponseMap.where(reviewed_object_id: mapping.map_id, reviewer_id: reviewer.id)&lt;br /&gt;
&lt;br /&gt;
3. From&lt;br /&gt;
&lt;br /&gt;
                   @assignments = Assignment&lt;br /&gt;
                   .where([&amp;quot;instructor_id = ? and substring(name,1,1) = ?&amp;quot;, session[:user].id, letter])&lt;br /&gt;
                   .order('name')&lt;br /&gt;
                   .page(params[:page])&lt;br /&gt;
                   .per_page(10)&lt;br /&gt;
&lt;br /&gt;
To &lt;br /&gt;
&lt;br /&gt;
                   @assignments = Assignment&lt;br /&gt;
                   .where(instructor_id:session[:user].id)&lt;br /&gt;
                   .where(&amp;quot;substring(name,1,1) = :letter&amp;quot;,{letter:letter})&lt;br /&gt;
                   .order('name')&lt;br /&gt;
                   .page(params[:page])&lt;br /&gt;
                   .per_page(10)&lt;br /&gt;
&lt;br /&gt;
4.  From&lt;br /&gt;
&lt;br /&gt;
  ReviewResponseMap.where([&amp;quot;reviewed_object_id = ? and calibrate_to = ?&amp;quot;, assignment_id, 1])&lt;br /&gt;
&lt;br /&gt;
To &lt;br /&gt;
&lt;br /&gt;
  ReviewResponseMap.where(reviewed_object_id:assignment_id, calibrate_to: 1)&lt;br /&gt;
&lt;br /&gt;
5. From&lt;br /&gt;
&lt;br /&gt;
  ReviewResponseMap.where([&amp;quot;reviewed_object_id = ? and created_at &amp;gt; ? and calibrate_to = ?&amp;quot;, assignment_id, @@time_create_last_review_mapping_record, 0])&lt;br /&gt;
&lt;br /&gt;
To &lt;br /&gt;
&lt;br /&gt;
  ReviewResponseMap.where(reviewed_object_id:assignment_id,calibrate_to:0).where(&amp;quot;created_at &amp;gt; :time&amp;quot;,{time:@@time_create_last_review_mapping_record})&lt;br /&gt;
&lt;br /&gt;
6. From&lt;br /&gt;
&lt;br /&gt;
  AssignmentQuestionnaire.where([&amp;quot;assignment_id = ? and questionnaire_id IN (?)&amp;quot;, params[:id], @review_questionnaire_ids])&lt;br /&gt;
&lt;br /&gt;
To&lt;br /&gt;
 &lt;br /&gt;
  AssignmentQuestionnaire.where(assignment_id: params[:id],:questionnaire_id =&amp;gt; @review_questionnaire_ids)&lt;br /&gt;
&lt;br /&gt;
7. From&lt;br /&gt;
&lt;br /&gt;
  SelfReviewResponseMap.where(['reviewee_id = ? and reviewer_id = ?', team_id[0].t_id, params[:reviewer_id]])&lt;br /&gt;
&lt;br /&gt;
To &lt;br /&gt;
&lt;br /&gt;
  SelfReviewResponseMap.where(reviewee_id:team_id[0].t_id,reviewer_id:params[:reviewer_id])&lt;br /&gt;
&lt;br /&gt;
==Refactor long line method==&lt;br /&gt;
&lt;br /&gt;
  def automatic_review_mapping_strategy(assignment_id,&lt;br /&gt;
                                        participants, teams, student_review_num = 0,&lt;br /&gt;
                                        submission_review_num = 0)&lt;br /&gt;
    participants_hash = {}&lt;br /&gt;
    participants.each {|participant| participants_hash[participant.id] = 0 }&lt;br /&gt;
    # calculate reviewers for each team&lt;br /&gt;
    num_participants = participants.size&lt;br /&gt;
    if student_review_num != 0 and submission_review_num == 0&lt;br /&gt;
      num_reviews_per_team = (participants.size * student_review_num * 1.0 / teams.size).round&lt;br /&gt;
      student_review_num = student_review_num&lt;br /&gt;
      exact_num_of_review_needed = participants.size * student_review_num&lt;br /&gt;
    elsif student_review_num == 0 and submission_review_num != 0&lt;br /&gt;
      num_reviews_per_team = submission_review_num&lt;br /&gt;
      student_review_num = (teams.size * submission_review_num * 1.0 / participants.size).round&lt;br /&gt;
      exact_num_of_review_needed = teams.size * submission_review_num&lt;br /&gt;
    end&lt;br /&gt;
    execute_peer_review_strategy(assignment_id, teams, num_participants,&lt;br /&gt;
                                     student_review_num, num_reviews_per_team,&lt;br /&gt;
                                     participants, participants_hash)&lt;br /&gt;
    # after assigning peer reviews for each team,&lt;br /&gt;
    # if there are still some peer reviewers not obtain enough peer review,&lt;br /&gt;
    # just assign them to valid teams&lt;br /&gt;
    assign_reviewers_for_team(assignment_id,student_review_num,participants_hash,&lt;br /&gt;
                              exact_num_of_review_needed)&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  def assign_reviewers_for_team(assignment_id,student_review_num,participants_hash,&lt;br /&gt;
                                exact_num_of_review_needed)&lt;br /&gt;
    if ReviewResponseMap.where([&amp;quot;reviewed_object_id = ? and created_at &amp;gt; ? and calibrate_to = ?&amp;quot;, &lt;br /&gt;
                                assignment_id, &lt;br /&gt;
                                @@time_create_last_review_mapping_record, 0]).size &amp;lt; exact_num_of_review_needed&lt;br /&gt;
      participants_with_insufficient_review_num = []&lt;br /&gt;
      participants_hash.each do |participant_id, review_num|&lt;br /&gt;
        participants_with_insufficient_review_num &amp;lt;&amp;lt; participant_id if review_num &amp;lt; student_review_num&lt;br /&gt;
      end&lt;br /&gt;
      unsorted_teams_hash = {}&lt;br /&gt;
      ReviewResponseMap.where([&amp;quot;reviewed_object_id = ? and calibrate_to = ?&amp;quot;, &lt;br /&gt;
                               assignment_id, 0]).each do |response_map|&lt;br /&gt;
        if unsorted_teams_hash.key? response_map.reviewee_id&lt;br /&gt;
          unsorted_teams_hash[response_map.reviewee_id] += 1&lt;br /&gt;
        else&lt;br /&gt;
          unsorted_teams_hash[response_map.reviewee_id] = 1&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
      teams_hash = unsorted_teams_hash.sort_by {|_, v| v }.to_h&lt;br /&gt;
      participants_with_insufficient_review_num.each do |participant_id|&lt;br /&gt;
        teams_hash.each do |team_id, _num_review_received|&lt;br /&gt;
          next if TeamsUser.exists?(team_id: team_id, &lt;br /&gt;
                                    user_id: Participant.find(participant_id).user_id)&lt;br /&gt;
          ReviewResponseMap.where(reviewee_id: team_id, reviewer_id: participant_id, &lt;br /&gt;
                                  reviewed_object_id: assignment_id).first_or_create&lt;br /&gt;
          teams_hash[team_id] += 1&lt;br /&gt;
          teams_hash = teams_hash.sort_by {|_, v| v }.to_h&lt;br /&gt;
          break&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
    @@time_create_last_review_mapping_record = ReviewResponseMap.&lt;br /&gt;
                                               where(reviewed_object_id: assignment_id).&lt;br /&gt;
                                               last.created_at&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def execute_peer_review_strategy(assignment_id, teams, num_participants, &lt;br /&gt;
                                   student_review_num, num_reviews_per_team, &lt;br /&gt;
                                   participants, participants_hash)&lt;br /&gt;
    # Exception detection: If instructor want to assign too many reviews done&lt;br /&gt;
    # by each student, there will be an error msg.&lt;br /&gt;
    if student_review_num &amp;gt;= teams.size&lt;br /&gt;
      flash[:error] = 'You cannot set the number of reviews done &lt;br /&gt;
      by each student to be greater than or equal to total number of teams &lt;br /&gt;
      [or &amp;quot;participants&amp;quot; if it is an individual assignment].'&lt;br /&gt;
    end&lt;br /&gt;
    peer_review_strategy(assignment_id, teams, num_participants, &lt;br /&gt;
                         student_review_num, num_reviews_per_team, &lt;br /&gt;
                         participants, participants_hash)&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
=Test=&lt;br /&gt;
We write RSpec feature tests to prove that all changes are correct and the project performs well as before.&lt;br /&gt;
&lt;br /&gt;
The function of  method automatic_review_mapping is to automatically assign reviews on students in teams when instructor set either student review number or submissions review number. There is constraint that only one of the two numbers must be set value other than 0 (that is, one is 0 and other is not 0). To test the correctness  of our refactoring, we design a scenario and 4 cases of assigning reviews to students:&lt;br /&gt;
&lt;br /&gt;
Case 1. Instructor has not set both students review number and submissions review number (They are both 0). The page will show a notice.&lt;br /&gt;
&lt;br /&gt;
Case 2. Instructor set both numbers (They are both not 0). The page will show a notice.&lt;br /&gt;
&lt;br /&gt;
Case 3. Instructors set students review number. The controller will change database: create new relationship in ReviewResponseMap. For example, if assign student review number to 2, and there will be 20 peer reviews in total and need to allocate to 3 teams. So each team get 7 reviews on average and 1 team’s artifact will be reviewed 6 times.&lt;br /&gt;
&lt;br /&gt;
Case 4. Instructors set submissions review number. The controller will change database: create new relationship in ReviewResponseMap. For example, if assign submission review number to 3, and there will be 21 peer reviews in total to allocate to 10 participants. So every participants get 2 reviews. 9 among 10 participants will review 2 teams’ artifacts and 1 participant will review 3 teams’ artifacts.&lt;br /&gt;
&lt;br /&gt;
require 'rails_helper'&lt;br /&gt;
  describe &amp;quot;review mapping&amp;quot;, js: true do&lt;br /&gt;
    before(:each) do&lt;br /&gt;
      #create test data&lt;br /&gt;
    end&lt;br /&gt;
 &lt;br /&gt;
    it &amp;quot;show error when assign both 0&amp;quot; do&lt;br /&gt;
      login_as(&amp;quot;instructor6&amp;quot;)&lt;br /&gt;
      visit '/assignments/1/edit'&lt;br /&gt;
      find_link('ReviewStrategy').click&lt;br /&gt;
      select &amp;quot;Instructor-Selected&amp;quot;, from: 'assignment_form_assignment_review_assignment_strategy'&lt;br /&gt;
      fill_in 'num_reviews_per_student', with: 0&lt;br /&gt;
      choose 'num_reviews_submission'&lt;br /&gt;
      fill_in 'num_reviews_per_submission', with: 0&lt;br /&gt;
      click_button 'second_submit_tag'&lt;br /&gt;
      #click_button 'Save'&lt;br /&gt;
      expect(page).to have_content('Please choose either the number of reviews per student or the number of reviewers per team (student)')&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    it &amp;quot;show error when assign both numbers&amp;quot; do&lt;br /&gt;
      login_as(&amp;quot;instructor6&amp;quot;)&lt;br /&gt;
      visit '/assignments/1/edit'&lt;br /&gt;
      find_link('ReviewStrategy').click&lt;br /&gt;
      select &amp;quot;Instructor-Selected&amp;quot;, from: 'assignment_form_assignment_review_assignment_strategy'&lt;br /&gt;
      fill_in 'num_reviews_per_student', with: 1&lt;br /&gt;
      choose 'num_reviews_submission'&lt;br /&gt;
      fill_in 'num_reviews_per_submission', with: 1&lt;br /&gt;
      click_button 'second_submit_tag'&lt;br /&gt;
      #click_button 'Save'&lt;br /&gt;
      expect(page).to have_content('Please choose either the number of reviews per student or the number of reviewers per team (student), not both')&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    it &amp;quot;calculate reviewmapping from given review number per student&amp;quot; do&lt;br /&gt;
      login_as(&amp;quot;instructor6&amp;quot;)&lt;br /&gt;
      visit '/assignments/1/edit'&lt;br /&gt;
      find_link('ReviewStrategy').click&lt;br /&gt;
      select &amp;quot;Instructor-Selected&amp;quot;, from: 'assignment_form_assignment_review_assignment_strategy'&lt;br /&gt;
      fill_in 'num_reviews_per_student', with: 2&lt;br /&gt;
      click_button 'first_submit_tag'&lt;br /&gt;
      num = ReviewResponseMap.where(reviewee_id: @team1.id, reviewed_object_id: @assignment.id).count&lt;br /&gt;
      expect(num).to eq(7)&lt;br /&gt;
      num2 = ReviewResponseMap.where(reviewee_id: @team3.id, reviewed_object_id: @assignment.id).count&lt;br /&gt;
      expect(num2).to eq(6)&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    it &amp;quot;calculate reviewmapping from given review number per submission&amp;quot; do&lt;br /&gt;
      login_as(&amp;quot;instructor6&amp;quot;)&lt;br /&gt;
      visit '/assignments/1/edit'&lt;br /&gt;
      find_link('ReviewStrategy').click&lt;br /&gt;
      select &amp;quot;Instructor-Selected&amp;quot;, from: 'assignment_form_assignment_review_assignment_strategy'&lt;br /&gt;
      choose 'num_reviews_submission'&lt;br /&gt;
      fill_in 'num_reviews_per_submission', with: 7&lt;br /&gt;
      click_button 'second_submit_tag'&lt;br /&gt;
      #click_button 'Save'&lt;br /&gt;
      num = ReviewResponseMap.where(reviewer_id: @teamuser1.id, reviewed_object_id: @assignment.id).count&lt;br /&gt;
      expect(num).to eq(2)&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;/div&gt;</summary>
		<author><name>Jdeng8</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2016/E1641._Refactor_review_mapping_controller.rb&amp;diff=103924</id>
		<title>CSC/ECE 517 Fall 2016/E1641. Refactor review mapping controller.rb</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2016/E1641._Refactor_review_mapping_controller.rb&amp;diff=103924"/>
		<updated>2016-10-29T05:30:53Z</updated>

		<summary type="html">&lt;p&gt;Jdeng8: /* Current Implementation and Problems */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=Background=&lt;br /&gt;
&lt;br /&gt;
This controller sets up mappings between reviewer and reviewee. It handles all different types of response maps (review response map, author feedback response map, teammate review response map, meta review response map and quiz response map). The class has functionality for five different kinds of Responses: reviews, metareviews, teammate reviews, author feedback (“rejoinders”), and quizzes. &lt;br /&gt;
&lt;br /&gt;
=Current Implementation and Problems=&lt;br /&gt;
&lt;br /&gt;
# Method ''response_report'' has some [[wikipedia:SQL|SQL]] - like code.  Rewrite with [Active Record].&lt;br /&gt;
# Test whether method ''add_user_to_assignment'' is used. There is no way that this method should be in ReviewMappingController. Please remove this method and caller.&lt;br /&gt;
# There was a ''self-review'' feature, the method ''add_self_reviewer'', ''get_team_from_submission'' are related to this. Two views calls ''add_self_reviewer'' are &amp;quot;show_available_submissions_for_quizzes.html.erb&amp;quot; and &amp;quot;show_available_submissions.html.erb&amp;quot;. The names of views are not related to ''self_review'' feature. Plus those two views are not called anywhere. Please verify this and if so, you should delete those two views, two method and also related records (e.g. in routes.rb).&lt;br /&gt;
# Method ''delete_all_reviewers'' actually only deletes the outstanding review response maps (the ones which has been initiated, but there is no response yet). So it should better be named ''delete_outstanding_reviewers''. You can try to test this method by clicking “Assign reviewers” icon on an assignment.&lt;br /&gt;
# Method ''release_reservation'' should be renamed as'' release_mapping''. In addition, delete it if you find this method is not called anywhere.&lt;br /&gt;
# Method ''delete_mappings'' is problematic. It does not looks like a controller method. Please refactor it or delete it if you can validate that this method is not called anywhere.&lt;br /&gt;
# Method'' automatic_review_mapping_strategy'' is too long. Please refactor and test it.&lt;br /&gt;
&lt;br /&gt;
=Changes Implemented=&lt;br /&gt;
&lt;br /&gt;
# change the rails query from sql like code, like ReviewResponseMap.where(['reviewee_id = ? and reviewer_id = ? ', params[:contributor_id], reviewer.id]) to more rails quey like ReviewResponseMap.where(reviewee_id: params[:contributor_id],reviewer_id: reviewer.id)&lt;br /&gt;
# We search the function name(''add_user_to_assignment'') in the whole files, and find that this method is invoked in &amp;quot;participants_helper.rb&amp;quot;, and also being invoked in the function of ''add_reviewer'' and ''add_metareviewer'' in the controller of ''review_mapping_controller'' &lt;br /&gt;
# By searching the whole project and routes, we verify that methods ''add_self_reviewer'' and ''get_team_from_submission'' in this controller are not called by any other methods except for views &amp;quot;show_available_submissions_for_quizzes.html.erb&amp;quot; and &amp;quot;show_available_submissions.html.erb&amp;quot;. And those two views are not linked to any other views. So they are deleted from the project.&lt;br /&gt;
# We already renamed method ''delete_all_reviewers'' to ''delete_outstanding_reviewers'' and changed the corresponding button name at the corresponding view (_list_review_mappings.html.erb).&lt;br /&gt;
# By searching the whole project and routes, we verify that methods'' release_reservation'' in this controller are not used in anywhere.&lt;br /&gt;
# By searching the whole project and routes, we verify that methods ''delete_mappings'' in this controller are not used in anywhere.&lt;br /&gt;
# Method ''automatic_review_mapping_strategy'' have many long lines. We already shorten each long line to multiple lines. And also, we split this long function into three different functions.&lt;br /&gt;
&lt;br /&gt;
=Code=&lt;br /&gt;
&lt;br /&gt;
==Refactor SQL query code==&lt;br /&gt;
&lt;br /&gt;
The rails query we change in this controller:&lt;br /&gt;
&lt;br /&gt;
1. From &lt;br /&gt;
&lt;br /&gt;
  ReviewResponseMap.where(['reviewee_id = ? and reviewer_id = ? ', params[:contributor_id], reviewer.id]) &lt;br /&gt;
&lt;br /&gt;
To&lt;br /&gt;
&lt;br /&gt;
  ReviewResponseMap.where(reviewee_id: params[:contributor_id],reviewer_id: reviewer.id)&lt;br /&gt;
&lt;br /&gt;
2. From&lt;br /&gt;
&lt;br /&gt;
  MetareviewResponseMap.where(['reviewed_object_id = ? and reviewer_id = ?', mapping.map_id, reviewer.id])&lt;br /&gt;
&lt;br /&gt;
To&lt;br /&gt;
&lt;br /&gt;
  MetareviewResponseMap.where(reviewed_object_id: mapping.map_id, reviewer_id: reviewer.id)&lt;br /&gt;
&lt;br /&gt;
3. From&lt;br /&gt;
&lt;br /&gt;
                   @assignments = Assignment&lt;br /&gt;
                   .where([&amp;quot;instructor_id = ? and substring(name,1,1) = ?&amp;quot;, session[:user].id, letter])&lt;br /&gt;
                   .order('name')&lt;br /&gt;
                   .page(params[:page])&lt;br /&gt;
                   .per_page(10)&lt;br /&gt;
&lt;br /&gt;
To &lt;br /&gt;
&lt;br /&gt;
                   @assignments = Assignment&lt;br /&gt;
                   .where(instructor_id:session[:user].id)&lt;br /&gt;
                   .where(&amp;quot;substring(name,1,1) = :letter&amp;quot;,{letter:letter})&lt;br /&gt;
                   .order('name')&lt;br /&gt;
                   .page(params[:page])&lt;br /&gt;
                   .per_page(10)&lt;br /&gt;
&lt;br /&gt;
4.  From&lt;br /&gt;
&lt;br /&gt;
  ReviewResponseMap.where([&amp;quot;reviewed_object_id = ? and calibrate_to = ?&amp;quot;, assignment_id, 1])&lt;br /&gt;
&lt;br /&gt;
To &lt;br /&gt;
&lt;br /&gt;
  ReviewResponseMap.where(reviewed_object_id:assignment_id, calibrate_to: 1)&lt;br /&gt;
&lt;br /&gt;
5. From&lt;br /&gt;
&lt;br /&gt;
  ReviewResponseMap.where([&amp;quot;reviewed_object_id = ? and created_at &amp;gt; ? and calibrate_to = ?&amp;quot;, assignment_id, @@time_create_last_review_mapping_record, 0])&lt;br /&gt;
&lt;br /&gt;
To &lt;br /&gt;
&lt;br /&gt;
  ReviewResponseMap.where(reviewed_object_id:assignment_id,calibrate_to:0).where(&amp;quot;created_at &amp;gt; :time&amp;quot;,{time:@@time_create_last_review_mapping_record})&lt;br /&gt;
&lt;br /&gt;
6. From&lt;br /&gt;
&lt;br /&gt;
  AssignmentQuestionnaire.where([&amp;quot;assignment_id = ? and questionnaire_id IN (?)&amp;quot;, params[:id], @review_questionnaire_ids])&lt;br /&gt;
&lt;br /&gt;
To&lt;br /&gt;
 &lt;br /&gt;
  AssignmentQuestionnaire.where(assignment_id: params[:id],:questionnaire_id =&amp;gt; @review_questionnaire_ids)&lt;br /&gt;
&lt;br /&gt;
7. From&lt;br /&gt;
&lt;br /&gt;
  SelfReviewResponseMap.where(['reviewee_id = ? and reviewer_id = ?', team_id[0].t_id, params[:reviewer_id]])&lt;br /&gt;
&lt;br /&gt;
To &lt;br /&gt;
&lt;br /&gt;
  SelfReviewResponseMap.where(reviewee_id:team_id[0].t_id,reviewer_id:params[:reviewer_id])&lt;br /&gt;
&lt;br /&gt;
==Refactor long line method==&lt;br /&gt;
&lt;br /&gt;
  def automatic_review_mapping_strategy(assignment_id,&lt;br /&gt;
                                        participants, teams, student_review_num = 0,&lt;br /&gt;
                                        submission_review_num = 0)&lt;br /&gt;
    participants_hash = {}&lt;br /&gt;
    participants.each {|participant| participants_hash[participant.id] = 0 }&lt;br /&gt;
    # calculate reviewers for each team&lt;br /&gt;
    num_participants = participants.size&lt;br /&gt;
    if student_review_num != 0 and submission_review_num == 0&lt;br /&gt;
      num_reviews_per_team = (participants.size * student_review_num * 1.0 / teams.size).round&lt;br /&gt;
      student_review_num = student_review_num&lt;br /&gt;
      exact_num_of_review_needed = participants.size * student_review_num&lt;br /&gt;
    elsif student_review_num == 0 and submission_review_num != 0&lt;br /&gt;
      num_reviews_per_team = submission_review_num&lt;br /&gt;
      student_review_num = (teams.size * submission_review_num * 1.0 / participants.size).round&lt;br /&gt;
      exact_num_of_review_needed = teams.size * submission_review_num&lt;br /&gt;
    end&lt;br /&gt;
    execute_peer_review_strategy(assignment_id, teams, num_participants,&lt;br /&gt;
                                     student_review_num, num_reviews_per_team,&lt;br /&gt;
                                     participants, participants_hash)&lt;br /&gt;
    # after assigning peer reviews for each team,&lt;br /&gt;
    # if there are still some peer reviewers not obtain enough peer review,&lt;br /&gt;
    # just assign them to valid teams&lt;br /&gt;
    assign_reviewers_for_team(assignment_id,student_review_num,participants_hash,&lt;br /&gt;
                              exact_num_of_review_needed)&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  def assign_reviewers_for_team(assignment_id,student_review_num,participants_hash,&lt;br /&gt;
                                exact_num_of_review_needed)&lt;br /&gt;
    if ReviewResponseMap.where([&amp;quot;reviewed_object_id = ? and created_at &amp;gt; ? and calibrate_to = ?&amp;quot;, &lt;br /&gt;
                                assignment_id, &lt;br /&gt;
                                @@time_create_last_review_mapping_record, 0]).size &amp;lt; exact_num_of_review_needed&lt;br /&gt;
      participants_with_insufficient_review_num = []&lt;br /&gt;
      participants_hash.each do |participant_id, review_num|&lt;br /&gt;
        participants_with_insufficient_review_num &amp;lt;&amp;lt; participant_id if review_num &amp;lt; student_review_num&lt;br /&gt;
      end&lt;br /&gt;
      unsorted_teams_hash = {}&lt;br /&gt;
      ReviewResponseMap.where([&amp;quot;reviewed_object_id = ? and calibrate_to = ?&amp;quot;, &lt;br /&gt;
                               assignment_id, 0]).each do |response_map|&lt;br /&gt;
        if unsorted_teams_hash.key? response_map.reviewee_id&lt;br /&gt;
          unsorted_teams_hash[response_map.reviewee_id] += 1&lt;br /&gt;
        else&lt;br /&gt;
          unsorted_teams_hash[response_map.reviewee_id] = 1&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
      teams_hash = unsorted_teams_hash.sort_by {|_, v| v }.to_h&lt;br /&gt;
      participants_with_insufficient_review_num.each do |participant_id|&lt;br /&gt;
        teams_hash.each do |team_id, _num_review_received|&lt;br /&gt;
          next if TeamsUser.exists?(team_id: team_id, &lt;br /&gt;
                                    user_id: Participant.find(participant_id).user_id)&lt;br /&gt;
          ReviewResponseMap.where(reviewee_id: team_id, reviewer_id: participant_id, &lt;br /&gt;
                                  reviewed_object_id: assignment_id).first_or_create&lt;br /&gt;
          teams_hash[team_id] += 1&lt;br /&gt;
          teams_hash = teams_hash.sort_by {|_, v| v }.to_h&lt;br /&gt;
          break&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
    @@time_create_last_review_mapping_record = ReviewResponseMap.&lt;br /&gt;
                                               where(reviewed_object_id: assignment_id).&lt;br /&gt;
                                               last.created_at&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def execute_peer_review_strategy(assignment_id, teams, num_participants, &lt;br /&gt;
                                   student_review_num, num_reviews_per_team, &lt;br /&gt;
                                   participants, participants_hash)&lt;br /&gt;
    # Exception detection: If instructor want to assign too many reviews done&lt;br /&gt;
    # by each student, there will be an error msg.&lt;br /&gt;
    if student_review_num &amp;gt;= teams.size&lt;br /&gt;
      flash[:error] = 'You cannot set the number of reviews done &lt;br /&gt;
      by each student to be greater than or equal to total number of teams &lt;br /&gt;
      [or &amp;quot;participants&amp;quot; if it is an individual assignment].'&lt;br /&gt;
    end&lt;br /&gt;
    peer_review_strategy(assignment_id, teams, num_participants, &lt;br /&gt;
                         student_review_num, num_reviews_per_team, &lt;br /&gt;
                         participants, participants_hash)&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
=Test=&lt;br /&gt;
We write RSpec feature tests to prove that all changes are correct and the project performs well as before.&lt;br /&gt;
&lt;br /&gt;
The function of  method automatic_review_mapping is to automatically assign reviews on students in teams when instructor set either student review number or submissions review number. There is constraint that only one of the two numbers must be set value other than 0 (that is, one is 0 and other is not 0). To test the correctness  of our refactoring, we design a scenario and 4 cases of assigning reviews to students:&lt;br /&gt;
&lt;br /&gt;
Case 1. Instructor has not set both students review number and submissions review number (They are both 0). The page will show a notice.&lt;br /&gt;
&lt;br /&gt;
Case 2. Instructor set both numbers (They are both not 0). The page will show a notice.&lt;br /&gt;
&lt;br /&gt;
Case 3. Instructors set students review number. The controller will change database: create new relationship in ReviewResponseMap. For example, if assign student review number to 2, and there will be 20 peer reviews in total and need to allocate to 3 teams. So each team get 7 reviews on average and 1 team’s artifact will be reviewed 6 times.&lt;br /&gt;
&lt;br /&gt;
Case 4. Instructors set submissions review number. The controller will change database: create new relationship in ReviewResponseMap. For example, if assign submission review number to 3, and there will be 21 peer reviews in total to allocate to 10 participants. So every participants get 2 reviews. 9 among 10 participants will review 2 teams’ artifacts and 1 participant will review 3 teams’ artifacts.&lt;br /&gt;
&lt;br /&gt;
require 'rails_helper'&lt;br /&gt;
  describe &amp;quot;review mapping&amp;quot;, js: true do&lt;br /&gt;
    before(:each) do&lt;br /&gt;
      #create test data&lt;br /&gt;
    end&lt;br /&gt;
 &lt;br /&gt;
    it &amp;quot;show error when assign both 0&amp;quot; do&lt;br /&gt;
      login_as(&amp;quot;instructor6&amp;quot;)&lt;br /&gt;
      visit '/assignments/1/edit'&lt;br /&gt;
      find_link('ReviewStrategy').click&lt;br /&gt;
      select &amp;quot;Instructor-Selected&amp;quot;, from: 'assignment_form_assignment_review_assignment_strategy'&lt;br /&gt;
      fill_in 'num_reviews_per_student', with: 0&lt;br /&gt;
      choose 'num_reviews_submission'&lt;br /&gt;
      fill_in 'num_reviews_per_submission', with: 0&lt;br /&gt;
      click_button 'second_submit_tag'&lt;br /&gt;
      #click_button 'Save'&lt;br /&gt;
      expect(page).to have_content('Please choose either the number of reviews per student or the number of reviewers per team (student)')&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    it &amp;quot;show error when assign both numbers&amp;quot; do&lt;br /&gt;
      login_as(&amp;quot;instructor6&amp;quot;)&lt;br /&gt;
      visit '/assignments/1/edit'&lt;br /&gt;
      find_link('ReviewStrategy').click&lt;br /&gt;
      select &amp;quot;Instructor-Selected&amp;quot;, from: 'assignment_form_assignment_review_assignment_strategy'&lt;br /&gt;
      fill_in 'num_reviews_per_student', with: 1&lt;br /&gt;
      choose 'num_reviews_submission'&lt;br /&gt;
      fill_in 'num_reviews_per_submission', with: 1&lt;br /&gt;
      click_button 'second_submit_tag'&lt;br /&gt;
      #click_button 'Save'&lt;br /&gt;
      expect(page).to have_content('Please choose either the number of reviews per student or the number of reviewers per team (student), not both')&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    it &amp;quot;calculate reviewmapping from given review number per student&amp;quot; do&lt;br /&gt;
      login_as(&amp;quot;instructor6&amp;quot;)&lt;br /&gt;
      visit '/assignments/1/edit'&lt;br /&gt;
      find_link('ReviewStrategy').click&lt;br /&gt;
      select &amp;quot;Instructor-Selected&amp;quot;, from: 'assignment_form_assignment_review_assignment_strategy'&lt;br /&gt;
      fill_in 'num_reviews_per_student', with: 2&lt;br /&gt;
      click_button 'first_submit_tag'&lt;br /&gt;
      num = ReviewResponseMap.where(reviewee_id: @team1.id, reviewed_object_id: @assignment.id).count&lt;br /&gt;
      expect(num).to eq(7)&lt;br /&gt;
      num2 = ReviewResponseMap.where(reviewee_id: @team3.id, reviewed_object_id: @assignment.id).count&lt;br /&gt;
      expect(num2).to eq(6)&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    it &amp;quot;calculate reviewmapping from given review number per submission&amp;quot; do&lt;br /&gt;
      login_as(&amp;quot;instructor6&amp;quot;)&lt;br /&gt;
      visit '/assignments/1/edit'&lt;br /&gt;
      find_link('ReviewStrategy').click&lt;br /&gt;
      select &amp;quot;Instructor-Selected&amp;quot;, from: 'assignment_form_assignment_review_assignment_strategy'&lt;br /&gt;
      choose 'num_reviews_submission'&lt;br /&gt;
      fill_in 'num_reviews_per_submission', with: 7&lt;br /&gt;
      click_button 'second_submit_tag'&lt;br /&gt;
      #click_button 'Save'&lt;br /&gt;
      num = ReviewResponseMap.where(reviewer_id: @teamuser1.id, reviewed_object_id: @assignment.id).count&lt;br /&gt;
      expect(num).to eq(2)&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;/div&gt;</summary>
		<author><name>Jdeng8</name></author>
	</entry>
</feed>