<?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=Hguan2</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=Hguan2"/>
	<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=Special:Contributions/Hguan2"/>
	<updated>2026-07-12T15:53:46Z</updated>
	<subtitle>User contributions</subtitle>
	<generator>MediaWiki 1.41.0</generator>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2016_E1624_Compose_functional_tests_for_Suggest_topics_of_student_functionality&amp;diff=102268</id>
		<title>CSC/ECE 517 Spring 2016 E1624 Compose functional tests for Suggest topics of student functionality</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2016_E1624_Compose_functional_tests_for_Suggest_topics_of_student_functionality&amp;diff=102268"/>
		<updated>2016-04-15T00:16:44Z</updated>

		<summary type="html">&lt;p&gt;Hguan2: /* Step 4 Approve/Reject the suggested topic */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This wiki page is for the description of changes made under E1624 Final project design assignment for Spring 2016, CSC/ECE 517. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Problem Statement==&lt;br /&gt;
&lt;br /&gt;
===What it does===&lt;br /&gt;
Suggested topic functionality is designed for students to suggest topics they interested in. An assignment can be set up to allow students to suggest topics at the discretion of the instructor. Then, students can suggest topics, and add related descriptions. The proposer can state that (s)he wants to work on the suggested topic.  When the instructor approves a suggested topic, if the proposer wanted to work on it, it is assigned to the proposer. Otherwise, it is placed on the signup sheet for anyone to reserve. The purpose of suggested topic is to make the writing assignment more personalized.&lt;br /&gt;
===What’s wrong with it===&lt;br /&gt;
Currently, there is no functional test for student's topic suggestion function.&lt;br /&gt;
&lt;br /&gt;
===What needs to be done===&lt;br /&gt;
*Understand the flow of the suggested topic function.&lt;br /&gt;
*Do not use the development DB, otherwise the tests will not pass on TravisCI.&lt;br /&gt;
*Create RSpec file in /spec/features/ folder.&lt;br /&gt;
*Use fixtures to create the assignment record  and any other records such as participant records in test DB.  &lt;br /&gt;
*Use Capybara to write functional tests for these three scenarios.&lt;br /&gt;
**One team is on the waitlist. They sent a suggestion for new topic and they want to choose their suggested topic. After their suggested topic is approved, they should leave the waitlist and hold their suggested topic;&lt;br /&gt;
**One team is holding a topic. They sent a suggestion for new topic and they want to choose their suggested topic. After their suggested topic is approved and they choose to switch to suggested topic, they will hold suggested topic and their old topic will be released. And if another team is in waitlist of that old topic, that team should hold the old topic now;&lt;br /&gt;
**One team is holding a topic. They sent a suggestion for new topic and they do not want to work on their suggested topic. After their suggested topic is approved and they choose to public suggested topic, they will still hold their old topic. Their suggested topic will be added in sign-up sheet.&lt;br /&gt;
*Create multiple tests to check valid and invalid cases.&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Design of solution==&lt;br /&gt;
To test the functionality of student's suggest topic, we plan to use Capybara to write the test code for each step listed below, covering all three scenarios.&lt;br /&gt;
(We wish to add some UI screenshots for each step, for better illustration, but seems the file upload function of this expertiza wiki is available for student user level so far.)&lt;br /&gt;
&lt;br /&gt;
===Prerequisites===&lt;br /&gt;
In the project, we assume that an instructor account ''instructor6'' and a student account ''student11'' is already created.&lt;br /&gt;
===Flow of suggest topic function===&lt;br /&gt;
====Step 1 Use instructor to add a course with topic suggestion enabled====&lt;br /&gt;
First step is to login with the instructor account (''instructor6'' here), and then create a course with the '''new public assignment''' function.&lt;br /&gt;
We will create the assignment and edit the topic feature to '''enable the topic suggestions''' function for student, where in the UI, it means select the &amp;quot;Allow topic suggestions from students?&amp;quot; checkbox.&lt;br /&gt;
Also, to test the second and third scenarios that the student already hold a topic, we will '''add a new topic''' with 1 slot for testing the later two scenarios.&lt;br /&gt;
After all above are done, the course just created can be saved to the test database.&lt;br /&gt;
&lt;br /&gt;
In this step, we need to write two functional tests: one is to check whether the course can be added and does the added one have topic suggestion enabled, the other one is to check whether the topic is added by instructor with 1 slot.&lt;br /&gt;
[[File:Csc517-final-design-yj-2.png]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====Step 2 Add student to the course====&lt;br /&gt;
After the course is added, the student (''student11'' for this test project) will be '''added as participants''' to the course. &lt;br /&gt;
For UI test, it should be entering &amp;quot;student11&amp;quot; as the participant name with the &amp;quot;participant&amp;quot; choice selected then click &amp;quot;add&amp;quot; button.&lt;br /&gt;
&lt;br /&gt;
In this step, we need to test whether the student, named ''student11'', is added to the course correctly.&lt;br /&gt;
&lt;br /&gt;
[[File:Csc517-final-design-yj-3.png]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====Step 3.1 Use student to suggest a new topic without holding any topic====&lt;br /&gt;
For the first scenario, which the student does not holding any topic, we should test after login with ''student11'' account and choose the assignment just created by ''instructor6''. &lt;br /&gt;
Then, we will '''suggest a topic''' with the choice of &amp;quot;Yes&amp;quot; for the question '''Do you wish to work on this topic?''' and '''submit''' the new topic suggestion.&lt;br /&gt;
&lt;br /&gt;
In this step, we need to write the function test to check whether the new topic is added and the student is willing to work on this topic if it is approved.&lt;br /&gt;
&lt;br /&gt;
[[File:Csc517-final-design-yj-41.png]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====Step 3.2 Use student to suggest a new topic holding a topic and wish to switch ====&lt;br /&gt;
For the second scenario, we should first let the student login and '''Signup''' the only topic created by the instructor in the Signup sheet. &lt;br /&gt;
Then do the same thing as depict in Step 3.1. &lt;br /&gt;
&lt;br /&gt;
In this step, we need to write two function tests: one is to check whether the student is already on the student list the topic, and the other one is to check whether the topic's available slots of the topic is 1 and the max number of slots is 2.&lt;br /&gt;
[[File:Csc517-final-design-yj-5.png]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====Step 3.3 Use student to suggest a new topic holding a topic and do '''NOT''' wish to switch ====&lt;br /&gt;
For the third scenario, we should do the same thing as introduced in Step 3.2, but the only difference is to select the choice of &amp;quot;No&amp;quot; for the question '''Do you wish to work on this topic?'''.&lt;br /&gt;
&lt;br /&gt;
In this step, we also need to write two function tests: one is to check whether the student is already on the student list the topic, and the other one is to check whether the topic's available slots of the topic is 0 now and the max number of slots is 2.&lt;br /&gt;
&lt;br /&gt;
[[File:Csc517-final-design-yj-6.png]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====Step 4 Approve/Reject the suggested topic====&lt;br /&gt;
The approve/reject functions should also be tested by using the ''instructor6'' account. After login the instructor account, use the assignment '''view suggestions''' function to '''view''' and then '''approve/reject''' the new suggested topic. &lt;br /&gt;
&lt;br /&gt;
In this step, we need to write two function tests: one is to check whether the '''Signup sheet''' does have/not have the suggested topic if it is approved/rejected, the other one is to check whether in the student '''suggest new topics''', the topic suggested by ''student11'' is indeed approved/rejected accordingly. &lt;br /&gt;
&lt;br /&gt;
Note that, this step is the final test step for the case of suggested topic is rejected. The following 3 possible step 5 is for the case the suggested topic is approved.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[File:Csc517-final-design-yj-9.png]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====Step 5.1 Student did not holding any topic before suggestion====&lt;br /&gt;
In addition to step 4, since the choice is &amp;quot;Yes&amp;quot; for willing to work on this topic when the student suggested, we will also need to test whether the student is already on the list of the new suggested topic and the number of available slot of the new suggested topic is 0.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====Step 5.2 Student held a topic but '''NOT''' wish to switch to new suggested topic====&lt;br /&gt;
For the student was holding a topic and do not want to switch, we need to write two tests: one is to check whether the student is still enrolled on the previous holding topic, and the other one is to confirm that the available slot of the new topic suggested topic is 1.&lt;br /&gt;
&lt;br /&gt;
[[File:Csc517-final-design-yj-7.png]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====Step 5.3 Student held a topic and wish to switch to new suggested topic====&lt;br /&gt;
For the student was holding a topic, coupled with the test written for Step 5.1, there is another test need to be written to check whether the slot of the previous held topic is increased by one.&lt;br /&gt;
&lt;br /&gt;
[[File:Csc517-final-design-yj-8.png]]&lt;/div&gt;</summary>
		<author><name>Hguan2</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2016_E1624_Compose_functional_tests_for_Suggest_topics_of_student_functionality&amp;diff=102267</id>
		<title>CSC/ECE 517 Spring 2016 E1624 Compose functional tests for Suggest topics of student functionality</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2016_E1624_Compose_functional_tests_for_Suggest_topics_of_student_functionality&amp;diff=102267"/>
		<updated>2016-04-15T00:16:27Z</updated>

		<summary type="html">&lt;p&gt;Hguan2: /* Step 3.1 Use student to suggest a new topic without holding any topic */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This wiki page is for the description of changes made under E1624 Final project design assignment for Spring 2016, CSC/ECE 517. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Problem Statement==&lt;br /&gt;
&lt;br /&gt;
===What it does===&lt;br /&gt;
Suggested topic functionality is designed for students to suggest topics they interested in. An assignment can be set up to allow students to suggest topics at the discretion of the instructor. Then, students can suggest topics, and add related descriptions. The proposer can state that (s)he wants to work on the suggested topic.  When the instructor approves a suggested topic, if the proposer wanted to work on it, it is assigned to the proposer. Otherwise, it is placed on the signup sheet for anyone to reserve. The purpose of suggested topic is to make the writing assignment more personalized.&lt;br /&gt;
===What’s wrong with it===&lt;br /&gt;
Currently, there is no functional test for student's topic suggestion function.&lt;br /&gt;
&lt;br /&gt;
===What needs to be done===&lt;br /&gt;
*Understand the flow of the suggested topic function.&lt;br /&gt;
*Do not use the development DB, otherwise the tests will not pass on TravisCI.&lt;br /&gt;
*Create RSpec file in /spec/features/ folder.&lt;br /&gt;
*Use fixtures to create the assignment record  and any other records such as participant records in test DB.  &lt;br /&gt;
*Use Capybara to write functional tests for these three scenarios.&lt;br /&gt;
**One team is on the waitlist. They sent a suggestion for new topic and they want to choose their suggested topic. After their suggested topic is approved, they should leave the waitlist and hold their suggested topic;&lt;br /&gt;
**One team is holding a topic. They sent a suggestion for new topic and they want to choose their suggested topic. After their suggested topic is approved and they choose to switch to suggested topic, they will hold suggested topic and their old topic will be released. And if another team is in waitlist of that old topic, that team should hold the old topic now;&lt;br /&gt;
**One team is holding a topic. They sent a suggestion for new topic and they do not want to work on their suggested topic. After their suggested topic is approved and they choose to public suggested topic, they will still hold their old topic. Their suggested topic will be added in sign-up sheet.&lt;br /&gt;
*Create multiple tests to check valid and invalid cases.&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Design of solution==&lt;br /&gt;
To test the functionality of student's suggest topic, we plan to use Capybara to write the test code for each step listed below, covering all three scenarios.&lt;br /&gt;
(We wish to add some UI screenshots for each step, for better illustration, but seems the file upload function of this expertiza wiki is available for student user level so far.)&lt;br /&gt;
&lt;br /&gt;
===Prerequisites===&lt;br /&gt;
In the project, we assume that an instructor account ''instructor6'' and a student account ''student11'' is already created.&lt;br /&gt;
===Flow of suggest topic function===&lt;br /&gt;
====Step 1 Use instructor to add a course with topic suggestion enabled====&lt;br /&gt;
First step is to login with the instructor account (''instructor6'' here), and then create a course with the '''new public assignment''' function.&lt;br /&gt;
We will create the assignment and edit the topic feature to '''enable the topic suggestions''' function for student, where in the UI, it means select the &amp;quot;Allow topic suggestions from students?&amp;quot; checkbox.&lt;br /&gt;
Also, to test the second and third scenarios that the student already hold a topic, we will '''add a new topic''' with 1 slot for testing the later two scenarios.&lt;br /&gt;
After all above are done, the course just created can be saved to the test database.&lt;br /&gt;
&lt;br /&gt;
In this step, we need to write two functional tests: one is to check whether the course can be added and does the added one have topic suggestion enabled, the other one is to check whether the topic is added by instructor with 1 slot.&lt;br /&gt;
[[File:Csc517-final-design-yj-2.png]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====Step 2 Add student to the course====&lt;br /&gt;
After the course is added, the student (''student11'' for this test project) will be '''added as participants''' to the course. &lt;br /&gt;
For UI test, it should be entering &amp;quot;student11&amp;quot; as the participant name with the &amp;quot;participant&amp;quot; choice selected then click &amp;quot;add&amp;quot; button.&lt;br /&gt;
&lt;br /&gt;
In this step, we need to test whether the student, named ''student11'', is added to the course correctly.&lt;br /&gt;
&lt;br /&gt;
[[File:Csc517-final-design-yj-3.png]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====Step 3.1 Use student to suggest a new topic without holding any topic====&lt;br /&gt;
For the first scenario, which the student does not holding any topic, we should test after login with ''student11'' account and choose the assignment just created by ''instructor6''. &lt;br /&gt;
Then, we will '''suggest a topic''' with the choice of &amp;quot;Yes&amp;quot; for the question '''Do you wish to work on this topic?''' and '''submit''' the new topic suggestion.&lt;br /&gt;
&lt;br /&gt;
In this step, we need to write the function test to check whether the new topic is added and the student is willing to work on this topic if it is approved.&lt;br /&gt;
&lt;br /&gt;
[[File:Csc517-final-design-yj-41.png]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====Step 3.2 Use student to suggest a new topic holding a topic and wish to switch ====&lt;br /&gt;
For the second scenario, we should first let the student login and '''Signup''' the only topic created by the instructor in the Signup sheet. &lt;br /&gt;
Then do the same thing as depict in Step 3.1. &lt;br /&gt;
&lt;br /&gt;
In this step, we need to write two function tests: one is to check whether the student is already on the student list the topic, and the other one is to check whether the topic's available slots of the topic is 1 and the max number of slots is 2.&lt;br /&gt;
[[File:Csc517-final-design-yj-5.png]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====Step 3.3 Use student to suggest a new topic holding a topic and do '''NOT''' wish to switch ====&lt;br /&gt;
For the third scenario, we should do the same thing as introduced in Step 3.2, but the only difference is to select the choice of &amp;quot;No&amp;quot; for the question '''Do you wish to work on this topic?'''.&lt;br /&gt;
&lt;br /&gt;
In this step, we also need to write two function tests: one is to check whether the student is already on the student list the topic, and the other one is to check whether the topic's available slots of the topic is 0 now and the max number of slots is 2.&lt;br /&gt;
&lt;br /&gt;
[[File:Csc517-final-design-yj-6.png]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====Step 4 Approve/Reject the suggested topic====&lt;br /&gt;
The approve/reject functions should also be tested by using the ''instructor6'' account. After login the instructor account, use the assignment '''view suggestions''' function to '''view''' and then '''approve/reject''' the new suggested topic. &lt;br /&gt;
&lt;br /&gt;
In this step, we need to write two function tests: one is to check whether the '''Signup sheet''' does have/not have the suggested topic if it is approved/rejected, the other one is to check whether in the student '''suggest new topics''', the topic suggested by ''student11'' is indeed approved/rejected accordingly. &lt;br /&gt;
&lt;br /&gt;
Note that, this step is the final test step for the case of suggested topic is rejected. The following 3 possible step 5 is for the case the suggested topic is approved.&lt;br /&gt;
[[File:Csc517-final-design-yj-9.png]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====Step 5.1 Student did not holding any topic before suggestion====&lt;br /&gt;
In addition to step 4, since the choice is &amp;quot;Yes&amp;quot; for willing to work on this topic when the student suggested, we will also need to test whether the student is already on the list of the new suggested topic and the number of available slot of the new suggested topic is 0.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====Step 5.2 Student held a topic but '''NOT''' wish to switch to new suggested topic====&lt;br /&gt;
For the student was holding a topic and do not want to switch, we need to write two tests: one is to check whether the student is still enrolled on the previous holding topic, and the other one is to confirm that the available slot of the new topic suggested topic is 1.&lt;br /&gt;
&lt;br /&gt;
[[File:Csc517-final-design-yj-7.png]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====Step 5.3 Student held a topic and wish to switch to new suggested topic====&lt;br /&gt;
For the student was holding a topic, coupled with the test written for Step 5.1, there is another test need to be written to check whether the slot of the previous held topic is increased by one.&lt;br /&gt;
&lt;br /&gt;
[[File:Csc517-final-design-yj-8.png]]&lt;/div&gt;</summary>
		<author><name>Hguan2</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2016_E1624_Compose_functional_tests_for_Suggest_topics_of_student_functionality&amp;diff=102266</id>
		<title>CSC/ECE 517 Spring 2016 E1624 Compose functional tests for Suggest topics of student functionality</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2016_E1624_Compose_functional_tests_for_Suggest_topics_of_student_functionality&amp;diff=102266"/>
		<updated>2016-04-15T00:16:17Z</updated>

		<summary type="html">&lt;p&gt;Hguan2: /* Step 2 Add student to the course */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This wiki page is for the description of changes made under E1624 Final project design assignment for Spring 2016, CSC/ECE 517. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Problem Statement==&lt;br /&gt;
&lt;br /&gt;
===What it does===&lt;br /&gt;
Suggested topic functionality is designed for students to suggest topics they interested in. An assignment can be set up to allow students to suggest topics at the discretion of the instructor. Then, students can suggest topics, and add related descriptions. The proposer can state that (s)he wants to work on the suggested topic.  When the instructor approves a suggested topic, if the proposer wanted to work on it, it is assigned to the proposer. Otherwise, it is placed on the signup sheet for anyone to reserve. The purpose of suggested topic is to make the writing assignment more personalized.&lt;br /&gt;
===What’s wrong with it===&lt;br /&gt;
Currently, there is no functional test for student's topic suggestion function.&lt;br /&gt;
&lt;br /&gt;
===What needs to be done===&lt;br /&gt;
*Understand the flow of the suggested topic function.&lt;br /&gt;
*Do not use the development DB, otherwise the tests will not pass on TravisCI.&lt;br /&gt;
*Create RSpec file in /spec/features/ folder.&lt;br /&gt;
*Use fixtures to create the assignment record  and any other records such as participant records in test DB.  &lt;br /&gt;
*Use Capybara to write functional tests for these three scenarios.&lt;br /&gt;
**One team is on the waitlist. They sent a suggestion for new topic and they want to choose their suggested topic. After their suggested topic is approved, they should leave the waitlist and hold their suggested topic;&lt;br /&gt;
**One team is holding a topic. They sent a suggestion for new topic and they want to choose their suggested topic. After their suggested topic is approved and they choose to switch to suggested topic, they will hold suggested topic and their old topic will be released. And if another team is in waitlist of that old topic, that team should hold the old topic now;&lt;br /&gt;
**One team is holding a topic. They sent a suggestion for new topic and they do not want to work on their suggested topic. After their suggested topic is approved and they choose to public suggested topic, they will still hold their old topic. Their suggested topic will be added in sign-up sheet.&lt;br /&gt;
*Create multiple tests to check valid and invalid cases.&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Design of solution==&lt;br /&gt;
To test the functionality of student's suggest topic, we plan to use Capybara to write the test code for each step listed below, covering all three scenarios.&lt;br /&gt;
(We wish to add some UI screenshots for each step, for better illustration, but seems the file upload function of this expertiza wiki is available for student user level so far.)&lt;br /&gt;
&lt;br /&gt;
===Prerequisites===&lt;br /&gt;
In the project, we assume that an instructor account ''instructor6'' and a student account ''student11'' is already created.&lt;br /&gt;
===Flow of suggest topic function===&lt;br /&gt;
====Step 1 Use instructor to add a course with topic suggestion enabled====&lt;br /&gt;
First step is to login with the instructor account (''instructor6'' here), and then create a course with the '''new public assignment''' function.&lt;br /&gt;
We will create the assignment and edit the topic feature to '''enable the topic suggestions''' function for student, where in the UI, it means select the &amp;quot;Allow topic suggestions from students?&amp;quot; checkbox.&lt;br /&gt;
Also, to test the second and third scenarios that the student already hold a topic, we will '''add a new topic''' with 1 slot for testing the later two scenarios.&lt;br /&gt;
After all above are done, the course just created can be saved to the test database.&lt;br /&gt;
&lt;br /&gt;
In this step, we need to write two functional tests: one is to check whether the course can be added and does the added one have topic suggestion enabled, the other one is to check whether the topic is added by instructor with 1 slot.&lt;br /&gt;
[[File:Csc517-final-design-yj-2.png]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====Step 2 Add student to the course====&lt;br /&gt;
After the course is added, the student (''student11'' for this test project) will be '''added as participants''' to the course. &lt;br /&gt;
For UI test, it should be entering &amp;quot;student11&amp;quot; as the participant name with the &amp;quot;participant&amp;quot; choice selected then click &amp;quot;add&amp;quot; button.&lt;br /&gt;
&lt;br /&gt;
In this step, we need to test whether the student, named ''student11'', is added to the course correctly.&lt;br /&gt;
&lt;br /&gt;
[[File:Csc517-final-design-yj-3.png]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====Step 3.1 Use student to suggest a new topic without holding any topic====&lt;br /&gt;
For the first scenario, which the student does not holding any topic, we should test after login with ''student11'' account and choose the assignment just created by ''instructor6''. &lt;br /&gt;
Then, we will '''suggest a topic''' with the choice of &amp;quot;Yes&amp;quot; for the question '''Do you wish to work on this topic?''' and '''submit''' the new topic suggestion.&lt;br /&gt;
&lt;br /&gt;
In this step, we need to write the function test to check whether the new topic is added and the student is willing to work on this topic if it is approved.&lt;br /&gt;
[[File:Csc517-final-design-yj-41.png]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====Step 3.2 Use student to suggest a new topic holding a topic and wish to switch ====&lt;br /&gt;
For the second scenario, we should first let the student login and '''Signup''' the only topic created by the instructor in the Signup sheet. &lt;br /&gt;
Then do the same thing as depict in Step 3.1. &lt;br /&gt;
&lt;br /&gt;
In this step, we need to write two function tests: one is to check whether the student is already on the student list the topic, and the other one is to check whether the topic's available slots of the topic is 1 and the max number of slots is 2.&lt;br /&gt;
[[File:Csc517-final-design-yj-5.png]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====Step 3.3 Use student to suggest a new topic holding a topic and do '''NOT''' wish to switch ====&lt;br /&gt;
For the third scenario, we should do the same thing as introduced in Step 3.2, but the only difference is to select the choice of &amp;quot;No&amp;quot; for the question '''Do you wish to work on this topic?'''.&lt;br /&gt;
&lt;br /&gt;
In this step, we also need to write two function tests: one is to check whether the student is already on the student list the topic, and the other one is to check whether the topic's available slots of the topic is 0 now and the max number of slots is 2.&lt;br /&gt;
&lt;br /&gt;
[[File:Csc517-final-design-yj-6.png]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====Step 4 Approve/Reject the suggested topic====&lt;br /&gt;
The approve/reject functions should also be tested by using the ''instructor6'' account. After login the instructor account, use the assignment '''view suggestions''' function to '''view''' and then '''approve/reject''' the new suggested topic. &lt;br /&gt;
&lt;br /&gt;
In this step, we need to write two function tests: one is to check whether the '''Signup sheet''' does have/not have the suggested topic if it is approved/rejected, the other one is to check whether in the student '''suggest new topics''', the topic suggested by ''student11'' is indeed approved/rejected accordingly. &lt;br /&gt;
&lt;br /&gt;
Note that, this step is the final test step for the case of suggested topic is rejected. The following 3 possible step 5 is for the case the suggested topic is approved.&lt;br /&gt;
[[File:Csc517-final-design-yj-9.png]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====Step 5.1 Student did not holding any topic before suggestion====&lt;br /&gt;
In addition to step 4, since the choice is &amp;quot;Yes&amp;quot; for willing to work on this topic when the student suggested, we will also need to test whether the student is already on the list of the new suggested topic and the number of available slot of the new suggested topic is 0.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====Step 5.2 Student held a topic but '''NOT''' wish to switch to new suggested topic====&lt;br /&gt;
For the student was holding a topic and do not want to switch, we need to write two tests: one is to check whether the student is still enrolled on the previous holding topic, and the other one is to confirm that the available slot of the new topic suggested topic is 1.&lt;br /&gt;
&lt;br /&gt;
[[File:Csc517-final-design-yj-7.png]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====Step 5.3 Student held a topic and wish to switch to new suggested topic====&lt;br /&gt;
For the student was holding a topic, coupled with the test written for Step 5.1, there is another test need to be written to check whether the slot of the previous held topic is increased by one.&lt;br /&gt;
&lt;br /&gt;
[[File:Csc517-final-design-yj-8.png]]&lt;/div&gt;</summary>
		<author><name>Hguan2</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=File:Screen_Shot_2016-04-03_at_5.06.21_PM.png&amp;diff=101893</id>
		<title>File:Screen Shot 2016-04-03 at 5.06.21 PM.png</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=File:Screen_Shot_2016-04-03_at_5.06.21_PM.png&amp;diff=101893"/>
		<updated>2016-04-05T16:19:26Z</updated>

		<summary type="html">&lt;p&gt;Hguan2: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Hguan2</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=File:Student_login_page.png&amp;diff=101892</id>
		<title>File:Student login page.png</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=File:Student_login_page.png&amp;diff=101892"/>
		<updated>2016-04-05T16:13:46Z</updated>

		<summary type="html">&lt;p&gt;Hguan2: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Hguan2</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2016_E1624_Compose_functional_tests_for_Suggest_topics_of_student_functionality&amp;diff=101891</id>
		<title>CSC/ECE 517 Spring 2016 E1624 Compose functional tests for Suggest topics of student functionality</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2016_E1624_Compose_functional_tests_for_Suggest_topics_of_student_functionality&amp;diff=101891"/>
		<updated>2016-04-05T16:11:35Z</updated>

		<summary type="html">&lt;p&gt;Hguan2: /* Prerequisites */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This wiki page is for the description of changes made under E1624 Final project design assignment for Spring 2016, CSC/ECE 517. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Problem Statement==&lt;br /&gt;
&lt;br /&gt;
===What it does===&lt;br /&gt;
Suggested topic functionality is designed for students to suggest topics they interested in. An assignment can be set up to allow students to suggest topics at the discretion of the instructor. Then, students can suggest topics, and add related descriptions. The proposer can state that (s)he wants to work on the suggested topic.  When the instructor approves a suggested topic, if the proposer wanted to work on it, it is assigned to the proposer. Otherwise, it is placed on the signup sheet for anyone to reserve. The purpose of suggested topic is to make the writing assignment more personalized.&lt;br /&gt;
===What’s wrong with it===&lt;br /&gt;
Currently, there is no functional test for student's topic suggestion function.&lt;br /&gt;
&lt;br /&gt;
===What needs to be done===&lt;br /&gt;
*Understand the flow of the suggested topic function.&lt;br /&gt;
*Do not use the development DB, otherwise the tests will not pass on TravisCI.&lt;br /&gt;
*Create RSpec file in /spec/features/ folder.&lt;br /&gt;
*Use fixtures to create the assignment record  and any other records such as participant records in test DB.  &lt;br /&gt;
*Use Capybara to write functional tests for these three scenarios.&lt;br /&gt;
**One team is on the waitlist. They sent a suggestion for new topic and they want to choose their suggested topic. After their suggested topic is approved, they should leave the waitlist and hold their suggested topic;&lt;br /&gt;
**One team is holding a topic. They sent a suggestion for new topic and they want to choose their suggested topic. After their suggested topic is approved and they choose to switch to suggested topic, they will hold suggested topic and their old topic will be released. And if another team is in waitlist of that old topic, that team should hold the old topic now;&lt;br /&gt;
**One team is holding a topic. They sent a suggestion for new topic and they do not want to work on their suggested topic. After their suggested topic is approved and they choose to public suggested topic, they will still hold their old topic. Their suggested topic will be added in sign-up sheet.&lt;br /&gt;
*Create multiple tests to check valid and invalid cases.&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Design of solution==&lt;br /&gt;
To test the functionality of student's suggest topic, we plan to use Capybara to write the test code for each step listed below, covering all three scenarios.&lt;br /&gt;
(We wish to add some UI screenshots for each step, for better illustration, but seems the file upload function of this expertiza wiki is available for student user level so far.)&lt;br /&gt;
&lt;br /&gt;
===Prerequisites===&lt;br /&gt;
In the project, we assume that an instructor account ''instructor6'' and a student account ''student11'' is already created.&lt;br /&gt;
&lt;br /&gt;
===Flow of suggest topic function===&lt;br /&gt;
====Step 1 Use instructor to add a course with topic suggestion enabled====&lt;br /&gt;
First step is to login with the instructor account (''instructor6'' here), and then create a course with the '''new public assignment''' function.&lt;br /&gt;
We will create the assignment and edit the topic feature to '''enable the topic suggestions''' function for student, where in the UI, it means select the &amp;quot;Allow topic suggestions from students?&amp;quot; checkbox.&lt;br /&gt;
Also, to test the second and third scenarios that the student already hold a topic, we will '''add a new topic''' with 1 slot for testing the later two scenarios.&lt;br /&gt;
After all above are done, the course just created can be saved to the test database.&lt;br /&gt;
&lt;br /&gt;
In this step, we need to write two functional tests: one is to check whether the course can be added and does the added one have topic suggestion enabled, the other one is to check whether the topic is added by instructor with 1 slot.&lt;br /&gt;
&lt;br /&gt;
====Step 2 Add student to the course====&lt;br /&gt;
After the course is added, the student (''student11'' for this test project) will be '''added as participants''' to the course. &lt;br /&gt;
For UI test, it should be entering &amp;quot;student11&amp;quot; as the participant name with the &amp;quot;participant&amp;quot; choice selected then click &amp;quot;add&amp;quot; button.&lt;br /&gt;
&lt;br /&gt;
In this step, we need to test whether the student, named ''student11'', is added to the course correctly.&lt;br /&gt;
&lt;br /&gt;
====Step 3.1 Use student to suggest a new topic without holding any topic====&lt;br /&gt;
For the first scenario, which the student does not holding any topic, we should test after login with ''student11'' account and choose the assignment just created by ''instructor6''. &lt;br /&gt;
Then, we will '''suggest a topic''' with the choice of &amp;quot;Yes&amp;quot; for the question '''Do you wish to work on this topic?''' and '''submit''' the new topic suggestion.&lt;br /&gt;
&lt;br /&gt;
In this step, we need to write the function test to check whether the new topic is added and the student is willing to work on this topic if it is approved.&lt;br /&gt;
&lt;br /&gt;
====Step 3.2 Use student to suggest a new topic holding a topic and wish to switch ====&lt;br /&gt;
For the second scenario, we should first let the student login and '''Signup''' the only topic created by the instructor in the Signup sheet. &lt;br /&gt;
Then do the same thing as depict in Step 3.1. &lt;br /&gt;
&lt;br /&gt;
In this step, we need to write two function tests: one is to check whether the student is already on the student list the topic, and the other one is to check whether the topic's available slots of the topic is 1 and the max number of slots is 2. &lt;br /&gt;
&lt;br /&gt;
====Step 3.3 Use student to suggest a new topic holding a topic and do NOT wish to switch ====&lt;br /&gt;
For the third scenario, we should do the same thing as introduced in Step 3.2, but the only difference is to select the choice of &amp;quot;No&amp;quot; for the question '''Do you wish to work on this topic?'''.&lt;br /&gt;
&lt;br /&gt;
In this step, we also need to write two function tests: one is to check whether the student is already on the student list the topic, and the other one is to check whether the topic's available slots of the topic is 0 now and the max number of slots is 2. &lt;br /&gt;
&lt;br /&gt;
====Step 4 Approve/Reject the suggested topic====&lt;br /&gt;
The approve/reject functions should also be tested by using the ''instructor6'' account. After login the instructor account, use the assignment '''view suggestions''' function to '''view''' and then '''approve/reject''' the new suggested topic. &lt;br /&gt;
&lt;br /&gt;
In this step, we need to write two function tests: one is to check whether the '''Signup sheet''' does have/not have the suggested topic if it is approved/rejected, the other one is to check whether in the student '''suggest new topics''', the topic suggested by ''student11'' is indeed approved/rejected accordingly. &lt;br /&gt;
&lt;br /&gt;
Note that, this step is the final test step for the case of suggested topic is rejected. The following 3 possible step 5 is for the case the suggested topic is approved.&lt;br /&gt;
&lt;br /&gt;
====Step 5.1 Student did not holding any topic before suggestion====&lt;br /&gt;
In addition to step 4, since the choice is &amp;quot;Yes&amp;quot; for willing to work on this topic when the student suggested, we will also need to test whether the student is already on the list of the new suggested topic and the number of available slot of the new suggested topic is 0.&lt;br /&gt;
&lt;br /&gt;
====Step 5.2 Student held a topic and wish to switch to new suggested topic====&lt;br /&gt;
For the student was holding a topic, coupled with the test written for Step 5.1, there is another test need to be written to check whether the slot of the previous held topic is increased by one.&lt;br /&gt;
&lt;br /&gt;
====Step 5.3 Student held a topic but NOT wish to switch to new suggested topic====&lt;br /&gt;
For the student was holding a topic and do not want to switch, we need to write two tests: one is to check whether the student is still enrolled on the previous holding topic, and the other one is to confirm that the available slot of the new topic suggested topic is 1.&lt;/div&gt;</summary>
		<author><name>Hguan2</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2016_E1624_Compose_functional_tests_for_Suggest_topics_of_student_functionality&amp;diff=101890</id>
		<title>CSC/ECE 517 Spring 2016 E1624 Compose functional tests for Suggest topics of student functionality</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2016_E1624_Compose_functional_tests_for_Suggest_topics_of_student_functionality&amp;diff=101890"/>
		<updated>2016-04-05T16:09:44Z</updated>

		<summary type="html">&lt;p&gt;Hguan2: /* Design of solution */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This wiki page is for the description of changes made under E1624 Final project design assignment for Spring 2016, CSC/ECE 517. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Problem Statement==&lt;br /&gt;
&lt;br /&gt;
===What it does===&lt;br /&gt;
Suggested topic functionality is designed for students to suggest topics they interested in. An assignment can be set up to allow students to suggest topics at the discretion of the instructor. Then, students can suggest topics, and add related descriptions. The proposer can state that (s)he wants to work on the suggested topic.  When the instructor approves a suggested topic, if the proposer wanted to work on it, it is assigned to the proposer. Otherwise, it is placed on the signup sheet for anyone to reserve. The purpose of suggested topic is to make the writing assignment more personalized.&lt;br /&gt;
===What’s wrong with it===&lt;br /&gt;
Currently, there is no functional test for student's topic suggestion function.&lt;br /&gt;
&lt;br /&gt;
===What needs to be done===&lt;br /&gt;
*Understand the flow of the suggested topic function.&lt;br /&gt;
*Do not use the development DB, otherwise the tests will not pass on TravisCI.&lt;br /&gt;
*Create RSpec file in /spec/features/ folder.&lt;br /&gt;
*Use fixtures to create the assignment record  and any other records such as participant records in test DB.  &lt;br /&gt;
*Use Capybara to write functional tests for these three scenarios.&lt;br /&gt;
**One team is on the waitlist. They sent a suggestion for new topic and they want to choose their suggested topic. After their suggested topic is approved, they should leave the waitlist and hold their suggested topic;&lt;br /&gt;
**One team is holding a topic. They sent a suggestion for new topic and they want to choose their suggested topic. After their suggested topic is approved and they choose to switch to suggested topic, they will hold suggested topic and their old topic will be released. And if another team is in waitlist of that old topic, that team should hold the old topic now;&lt;br /&gt;
**One team is holding a topic. They sent a suggestion for new topic and they do not want to work on their suggested topic. After their suggested topic is approved and they choose to public suggested topic, they will still hold their old topic. Their suggested topic will be added in sign-up sheet.&lt;br /&gt;
*Create multiple tests to check valid and invalid cases.&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Design of solution==&lt;br /&gt;
To test the functionality of student's suggest topic, we plan to use Capybara to write the test code for each step listed below, covering all three scenarios.&lt;br /&gt;
(We wish to add some UI screenshots for each step, for better illustration, but seems the file upload function of this expertiza wiki is available for student user level so far.)&lt;br /&gt;
&lt;br /&gt;
===Prerequisites===&lt;br /&gt;
In the project, we assume that an instructor account ''instructor6'' and a student account ''student11'' is already created. &lt;br /&gt;
[[File:Example.jpg]]&lt;br /&gt;
&lt;br /&gt;
===Flow of suggest topic function===&lt;br /&gt;
====Step 1 Use instructor to add a course with topic suggestion enabled====&lt;br /&gt;
First step is to login with the instructor account (''instructor6'' here), and then create a course with the '''new public assignment''' function.&lt;br /&gt;
We will create the assignment and edit the topic feature to '''enable the topic suggestions''' function for student, where in the UI, it means select the &amp;quot;Allow topic suggestions from students?&amp;quot; checkbox.&lt;br /&gt;
Also, to test the second and third scenarios that the student already hold a topic, we will '''add a new topic''' with 1 slot for testing the later two scenarios.&lt;br /&gt;
After all above are done, the course just created can be saved to the test database.&lt;br /&gt;
&lt;br /&gt;
In this step, we need to write two functional tests: one is to check whether the course can be added and does the added one have topic suggestion enabled, the other one is to check whether the topic is added by instructor with 1 slot.&lt;br /&gt;
&lt;br /&gt;
====Step 2 Add student to the course====&lt;br /&gt;
After the course is added, the student (''student11'' for this test project) will be '''added as participants''' to the course. &lt;br /&gt;
For UI test, it should be entering &amp;quot;student11&amp;quot; as the participant name with the &amp;quot;participant&amp;quot; choice selected then click &amp;quot;add&amp;quot; button.&lt;br /&gt;
&lt;br /&gt;
In this step, we need to test whether the student, named ''student11'', is added to the course correctly.&lt;br /&gt;
&lt;br /&gt;
====Step 3.1 Use student to suggest a new topic without holding any topic====&lt;br /&gt;
For the first scenario, which the student does not holding any topic, we should test after login with ''student11'' account and choose the assignment just created by ''instructor6''. &lt;br /&gt;
Then, we will '''suggest a topic''' with the choice of &amp;quot;Yes&amp;quot; for the question '''Do you wish to work on this topic?''' and '''submit''' the new topic suggestion.&lt;br /&gt;
&lt;br /&gt;
In this step, we need to write the function test to check whether the new topic is added and the student is willing to work on this topic if it is approved.&lt;br /&gt;
&lt;br /&gt;
====Step 3.2 Use student to suggest a new topic holding a topic and wish to switch ====&lt;br /&gt;
For the second scenario, we should first let the student login and '''Signup''' the only topic created by the instructor in the Signup sheet. &lt;br /&gt;
Then do the same thing as depict in Step 3.1. &lt;br /&gt;
&lt;br /&gt;
In this step, we need to write two function tests: one is to check whether the student is already on the student list the topic, and the other one is to check whether the topic's available slots of the topic is 1 and the max number of slots is 2. &lt;br /&gt;
&lt;br /&gt;
====Step 3.3 Use student to suggest a new topic holding a topic and do NOT wish to switch ====&lt;br /&gt;
For the third scenario, we should do the same thing as introduced in Step 3.2, but the only difference is to select the choice of &amp;quot;No&amp;quot; for the question '''Do you wish to work on this topic?'''.&lt;br /&gt;
&lt;br /&gt;
In this step, we also need to write two function tests: one is to check whether the student is already on the student list the topic, and the other one is to check whether the topic's available slots of the topic is 0 now and the max number of slots is 2. &lt;br /&gt;
&lt;br /&gt;
====Step 4 Approve/Reject the suggested topic====&lt;br /&gt;
The approve/reject functions should also be tested by using the ''instructor6'' account. After login the instructor account, use the assignment '''view suggestions''' function to '''view''' and then '''approve/reject''' the new suggested topic. &lt;br /&gt;
&lt;br /&gt;
In this step, we need to write two function tests: one is to check whether the '''Signup sheet''' does have/not have the suggested topic if it is approved/rejected, the other one is to check whether in the student '''suggest new topics''', the topic suggested by ''student11'' is indeed approved/rejected accordingly. &lt;br /&gt;
&lt;br /&gt;
Note that, this step is the final test step for the case of suggested topic is rejected. The following 3 possible step 5 is for the case the suggested topic is approved.&lt;br /&gt;
&lt;br /&gt;
====Step 5.1 Student did not holding any topic before suggestion====&lt;br /&gt;
In addition to step 4, since the choice is &amp;quot;Yes&amp;quot; for willing to work on this topic when the student suggested, we will also need to test whether the student is already on the list of the new suggested topic and the number of available slot of the new suggested topic is 0.&lt;br /&gt;
&lt;br /&gt;
====Step 5.2 Student held a topic and wish to switch to new suggested topic====&lt;br /&gt;
For the student was holding a topic, coupled with the test written for Step 5.1, there is another test need to be written to check whether the slot of the previous held topic is increased by one.&lt;br /&gt;
&lt;br /&gt;
====Step 5.3 Student held a topic but NOT wish to switch to new suggested topic====&lt;br /&gt;
For the student was holding a topic and do not want to switch, we need to write two tests: one is to check whether the student is still enrolled on the previous holding topic, and the other one is to confirm that the available slot of the new topic suggested topic is 1.&lt;/div&gt;</summary>
		<author><name>Hguan2</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2016_E1624_Compose_functional_tests_for_Suggest_topics_of_student_functionality&amp;diff=101889</id>
		<title>CSC/ECE 517 Spring 2016 E1624 Compose functional tests for Suggest topics of student functionality</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2016_E1624_Compose_functional_tests_for_Suggest_topics_of_student_functionality&amp;diff=101889"/>
		<updated>2016-04-05T15:58:00Z</updated>

		<summary type="html">&lt;p&gt;Hguan2: /* What needs to be done */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This wiki page is for the description of changes made under E1624 Final project design assignment for Spring 2016, CSC/ECE 517. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Problem Statement==&lt;br /&gt;
&lt;br /&gt;
===What it does===&lt;br /&gt;
Suggested topic functionality is designed for students to suggest topics they interested in. An assignment can be set up to allow students to suggest topics at the discretion of the instructor. Then, students can suggest topics, and add related descriptions. The proposer can state that (s)he wants to work on the suggested topic.  When the instructor approves a suggested topic, if the proposer wanted to work on it, it is assigned to the proposer. Otherwise, it is placed on the signup sheet for anyone to reserve. The purpose of suggested topic is to make the writing assignment more personalized.&lt;br /&gt;
===What’s wrong with it===&lt;br /&gt;
Currently, there is no functional test for student's topic suggestion function.&lt;br /&gt;
&lt;br /&gt;
===What needs to be done===&lt;br /&gt;
*Understand the flow of the suggested topic function.&lt;br /&gt;
*Do not use the development DB, otherwise the tests will not pass on TravisCI.&lt;br /&gt;
*Create RSpec file in /spec/features/ folder.&lt;br /&gt;
*Use fixtures to create the assignment record  and any other records such as participant records in test DB.  &lt;br /&gt;
*Use Capybara to write functional tests for these three scenarios.&lt;br /&gt;
**One team is on the waitlist. They sent a suggestion for new topic and they want to choose their suggested topic. After their suggested topic is approved, they should leave the waitlist and hold their suggested topic;&lt;br /&gt;
**One team is holding a topic. They sent a suggestion for new topic and they want to choose their suggested topic. After their suggested topic is approved and they choose to switch to suggested topic, they will hold suggested topic and their old topic will be released. And if another team is in waitlist of that old topic, that team should hold the old topic now;&lt;br /&gt;
**One team is holding a topic. They sent a suggestion for new topic and they do not want to work on their suggested topic. After their suggested topic is approved and they choose to public suggested topic, they will still hold their old topic. Their suggested topic will be added in sign-up sheet.&lt;br /&gt;
*Create multiple tests to check valid and invalid cases.&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Design of solution==&lt;br /&gt;
To test the functionality of student's suggest topic, we plan to use Capybara to write the test code for each step listed below, covering all three scenarios.&lt;br /&gt;
In the project, we assume that an instructor account ''instructor6'' and a student account ''student11'' is already created.&lt;br /&gt;
(We wish to add some UI screenshots for each step, for better illustration, but seems the file upload function of this expertiza wiki is available for student user level so far.)&lt;br /&gt;
&lt;br /&gt;
===Flow of suggest topic function===&lt;br /&gt;
====Step 1 Use instructor to add a course with topic suggestion enabled====&lt;br /&gt;
First step is to login with the instructor account (''instructor6'' here), and then create a course with the '''new public assignment''' function.&lt;br /&gt;
We will create the assignment and edit the topic feature to '''enable the topic suggestions''' function for student, where in the UI, it means select the &amp;quot;Allow topic suggestions from students?&amp;quot; checkbox.&lt;br /&gt;
Also, to test the second and third scenarios that the student already hold a topic, we will '''add a new topic''' with 1 slot for testing the later two scenarios.&lt;br /&gt;
After all above are done, the course just created can be saved to the test database.&lt;br /&gt;
&lt;br /&gt;
In this step, we need to write two functional tests: one is to check whether the course can be added and does the added one have topic suggestion enabled, the other one is to check whether the topic is added by instructor with 1 slot.&lt;br /&gt;
&lt;br /&gt;
====Step 2 Add student to the course====&lt;br /&gt;
After the course is added, the student (''student11'' for this test project) will be '''added as participants''' to the course. &lt;br /&gt;
For UI test, it should be entering &amp;quot;student11&amp;quot; as the participant name with the &amp;quot;participant&amp;quot; choice selected then click &amp;quot;add&amp;quot; button.&lt;br /&gt;
&lt;br /&gt;
In this step, we need to test whether the student, named ''student11'', is added to the course correctly.&lt;br /&gt;
&lt;br /&gt;
====Step 3.1 Use student to suggest a new topic without holding any topic====&lt;br /&gt;
For the first scenario, which the student does not holding any topic, we should test after login with ''student11'' account and choose the assignment just created by ''instructor6''. &lt;br /&gt;
Then, we will '''suggest a topic''' with the choice of &amp;quot;Yes&amp;quot; for the question '''Do you wish to work on this topic?''' and '''submit''' the new topic suggestion.&lt;br /&gt;
&lt;br /&gt;
In this step, we need to write the function test to check whether the new topic is added and the student is willing to work on this topic if it is approved.&lt;br /&gt;
&lt;br /&gt;
====Step 3.2 Use student to suggest a new topic holding a topic and wish to switch ====&lt;br /&gt;
For the second scenario, we should first let the student login and '''Signup''' the only topic created by the instructor in the Signup sheet. &lt;br /&gt;
Then do the same thing as depict in Step 3.1. &lt;br /&gt;
&lt;br /&gt;
In this step, we need to write two function tests: one is to check whether the student is already on the student list the topic, and the other one is to check whether the topic's available slots of the topic is 1 and the max number of slots is 2. &lt;br /&gt;
&lt;br /&gt;
====Step 3.3 Use student to suggest a new topic holding a topic and do NOT wish to switch ====&lt;br /&gt;
For the third scenario, we should do the same thing as introduced in Step 3.2, but the only difference is to select the choice of &amp;quot;No&amp;quot; for the question '''Do you wish to work on this topic?'''.&lt;br /&gt;
&lt;br /&gt;
In this step, we also need to write two function tests: one is to check whether the student is already on the student list the topic, and the other one is to check whether the topic's available slots of the topic is 0 now and the max number of slots is 2. &lt;br /&gt;
&lt;br /&gt;
====Step 4 Approve/Reject the suggested topic====&lt;br /&gt;
The approve/reject functions should also be tested by using the ''instructor6'' account. After login the instructor account, use the assignment '''view suggestions''' function to '''view''' and then '''approve/reject''' the new suggested topic. &lt;br /&gt;
&lt;br /&gt;
In this step, we need to write two function tests: one is to check whether the '''Signup sheet''' does have/not have the suggested topic if it is approved/rejected, the other one is to check whether in the student '''suggest new topics''', the topic suggested by ''student11'' is indeed approved/rejected accordingly. &lt;br /&gt;
&lt;br /&gt;
Note that, this step is the final test step for the case of suggested topic is rejected. The following 3 possible step 5 is for the case the suggested topic is approved.&lt;br /&gt;
&lt;br /&gt;
====Step 5.1 Student did not holding any topic before suggestion====&lt;br /&gt;
In addition to step 4, since the choice is &amp;quot;Yes&amp;quot; for willing to work on this topic when the student suggested, we will also need to test whether the student is already on the list of the new suggested topic and the number of available slot of the new suggested topic is 0.&lt;br /&gt;
&lt;br /&gt;
====Step 5.2 Student held a topic and wish to switch to new suggested topic====&lt;br /&gt;
For the student was holding a topic, coupled with the test written for Step 5.1, there is another test need to be written to check whether the slot of the previous held topic is increased by one.&lt;br /&gt;
&lt;br /&gt;
====Step 5.3 Student held a topic but NOT wish to switch to new suggested topic====&lt;br /&gt;
For the student was holding a topic and do not want to switch, we need to write two tests: one is to check whether the student is still enrolled on the previous holding topic, and the other one is to confirm that the available slot of the new topic suggested topic is 1.&lt;/div&gt;</summary>
		<author><name>Hguan2</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2016/Refactor_and_write_unit_tests_for_question_type.rb&amp;diff=101738</id>
		<title>CSC/ECE 517 Spring 2016/Refactor and write unit tests for question type.rb</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2016/Refactor_and_write_unit_tests_for_question_type.rb&amp;diff=101738"/>
		<updated>2016-04-04T01:35:44Z</updated>

		<summary type="html">&lt;p&gt;Hguan2: /* Unit-tests */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This wiki page is for the description of changes made under E1608 OSS assignment for Spring 2016, CSC/ECE 517. The assignment task is to  refactor &amp;amp; write unit tests for [question_type].rb (eg. criterion.rb).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Problem Statement ==&lt;br /&gt;
===Files related===&lt;br /&gt;
Four models is related: criterion.rb, scale.rb, checkbox.rb, questionnaire_header.rb, upload_file.rb. There are 4 methods “edit”, “view_question_text”, “complete” and “view_completed_question” correspond to different views. &lt;br /&gt;
&lt;br /&gt;
*edit ~&amp;gt;	when instructor add/edit new questions&lt;br /&gt;
*view ~&amp;gt; when instructor view existed questions&lt;br /&gt;
*complete ~&amp;gt; when students do peer reviews&lt;br /&gt;
*view_completed_question ~&amp;gt; when student view existed peer reviews&lt;br /&gt;
&lt;br /&gt;
===Expertiza question types inheritance hierarchy===&lt;br /&gt;
&lt;br /&gt;
*Choice question&lt;br /&gt;
**Scored question&lt;br /&gt;
***Scale&lt;br /&gt;
***Criterion&lt;br /&gt;
**Unscored question&lt;br /&gt;
***Dropdown&lt;br /&gt;
***CheckBox&lt;br /&gt;
*TextResponse&lt;br /&gt;
**TextArea&lt;br /&gt;
**TextField&lt;br /&gt;
*UploadFile&lt;br /&gt;
&lt;br /&gt;
===Files problem===&lt;br /&gt;
&lt;br /&gt;
There are some issues in each file, such as security, complexity, duplication, etc. And currently there is no unit tests for [question_type].rb.&lt;br /&gt;
&lt;br /&gt;
===Our contribution===&lt;br /&gt;
*Refactor these [question_type].rb files and fix issues.&lt;br /&gt;
*Keep the inputs and outputs of these methods (edit, view, complete, view_completed_question) the same as before.&lt;br /&gt;
*Write unit tests for [question_type].rb listed above.&lt;br /&gt;
*Create RSpec files for each question type in /spec/models/ folder&lt;br /&gt;
*Create multiple tests to check valid and invalid cases, such as input including special character double quote (“”).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
==Refactor==&lt;br /&gt;
===Criterion.rb===&lt;br /&gt;
* Method has too many lines: Line 35 - 158 [106/30]&lt;br /&gt;
Wrap the specific code into different instance methods. &lt;br /&gt;
* Cyclomatic complexity for complete is too high: Line 35 - 158 [28/6]&lt;br /&gt;
Wrap the code into different instance methods to reduce cyclomatic complexity&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 def complete(count, answer=nil, questionnaire_min, questionnaire_max, dropdown_or_scale)&lt;br /&gt;
    if self.size.nil?&lt;br /&gt;
      cols = '70'&lt;br /&gt;
      rows = '1'&lt;br /&gt;
    else&lt;br /&gt;
      cols = self.size.split(',')[0]&lt;br /&gt;
      rows = self.size.split(',')[1]&lt;br /&gt;
    end&lt;br /&gt;
    html = '&amp;lt;li&amp;gt;&amp;lt;div&amp;gt;&amp;lt;label for=&amp;quot;responses_' +count.to_s+ '&amp;quot;&amp;gt;' +self.txt+ &amp;quot;&amp;lt;/label&amp;gt;&amp;lt;/div&amp;gt;&amp;quot;&lt;br /&gt;
    #show advice for each criterion question&lt;br /&gt;
    question_advices = QuestionAdvice.where(question_id: self.id).sort_by { |advice| advice.id }&lt;br /&gt;
    advice_total_length = 0&lt;br /&gt;
    question_advices.each do |question_advice|&lt;br /&gt;
      if question_advice.advice &amp;amp;&amp;amp; !question_advice.advice == &amp;quot;&amp;quot;&lt;br /&gt;
        advice_total_length += question_advice.advice.length&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
    if question_advices.length &amp;gt; 0 and advice_total_length &amp;gt; 0&lt;br /&gt;
       html = complete_show_advice(self, html)&lt;br /&gt;
    question_advices.reverse.each_with_index do |question_advice, index|&lt;br /&gt;
        html += '&amp;lt;a id=&amp;quot;changeScore_&amp;gt;' + self.id.to_s + '&amp;quot; onclick=&amp;quot;changeScore(' + count.to_s + ',' + index.to_s + ')&amp;quot;&amp;gt;'&lt;br /&gt;
        html += (question_advices.length - index).to_s + ' - ' + question_advice.advice + '&amp;lt;/a&amp;gt;&amp;lt;br/&amp;gt;'&lt;br /&gt;
        html += '&amp;lt;script&amp;gt;'&lt;br /&gt;
        html += 'function changeScore(i, j) {'&lt;br /&gt;
        html += 'var elem = jQuery(&amp;quot;#responses_&amp;quot; + i.toString() + &amp;quot;_score&amp;quot;);'&lt;br /&gt;
        html += 'var opts = elem.children(&amp;quot;option&amp;quot;).length;'&lt;br /&gt;
        html += 'elem.val((opts - j - 1).toString());}'&lt;br /&gt;
        html += '&amp;lt;/script&amp;gt;'&lt;br /&gt;
      end&lt;br /&gt;
      html += '&amp;lt;/div&amp;gt;'&lt;br /&gt;
    end&lt;br /&gt;
    if dropdown_or_scale == 'dropdown'&lt;br /&gt;
      ## code added  to reduce Cyclomatic Complexity&lt;br /&gt;
      html = complete_drop_down(self, html, count, answer, questionnaire_min, questionnaire_max)&lt;br /&gt;
    elsif dropdown_or_scale == 'scale'&lt;br /&gt;
       html = complete_scale(self, html, count, answer, questionnaire_min, questionnaire_max)&lt;br /&gt;
    end&lt;br /&gt;
    html.html_safe&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
* Identical code found in 1 other location: Line 20 - 32 (mass = 89)&lt;br /&gt;
Also found in   app/models/scale.rb:17…28. The following method is removed from subclass: criterion and added to their superclass: scaled_question&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def view_question_text&lt;br /&gt;
    html = '&amp;lt;TR&amp;gt;&amp;lt;TD align=&amp;quot;left&amp;quot;&amp;gt; '+self.txt+' &amp;lt;/TD&amp;gt;'&lt;br /&gt;
    html += '&amp;lt;TD align=&amp;quot;left&amp;quot;&amp;gt;'+self.type+'&amp;lt;/TD&amp;gt;'&lt;br /&gt;
    html += '&amp;lt;td align=&amp;quot;center&amp;quot;&amp;gt;'+self.weight.to_s+'&amp;lt;/TD&amp;gt;'&lt;br /&gt;
    questionnaire = self.questionnaire&lt;br /&gt;
    if !self.max_label.nil? &amp;amp;&amp;amp; !self.min_label.nil?&lt;br /&gt;
      html += '&amp;lt;TD align=&amp;quot;center&amp;quot;&amp;gt; ('+self.min_label+') '+questionnaire.min_question_score.to_s+' to '+ questionnaire.max_question_score.to_s + ' ('+self.max_label+')&amp;lt;/TD&amp;gt;'&lt;br /&gt;
    else&lt;br /&gt;
      html += '&amp;lt;TD align=&amp;quot;center&amp;quot;&amp;gt;'+questionnaire.min_question_score.to_s+' to '+ questionnaire.max_question_score.to_s + '&amp;lt;/TD&amp;gt;'&lt;br /&gt;
    end&lt;br /&gt;
    html += '&amp;lt;/TR&amp;gt;'&lt;br /&gt;
    Html.html_safe&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
* Identical code found in 1 other location: Line 135 - 139 (mass = 50)&lt;br /&gt;
Also found in  app/models/scale.rb:50…54. Wrap the duplicated code into an instance method and add the instance method into superclass: scaled_question&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# add the following functions to refactor duplicates.&lt;br /&gt;
  def complete_questionnaire_min_to_questionnaire_max(ob, html, answer, questionnaire_min, questionnaire_max)&lt;br /&gt;
    for j in questionnaire_min..questionnaire_max&lt;br /&gt;
      html += '&amp;lt;td width=&amp;quot;10%&amp;quot;&amp;gt;&amp;lt;input type=&amp;quot;radio&amp;quot; id=&amp;quot;' +j.to_s+ '&amp;quot; value=&amp;quot;' +j.to_s+ '&amp;quot; name=&amp;quot;Radio_' +ob.id.to_s+ '&amp;quot;'&lt;br /&gt;
      html += 'checked=&amp;quot;checked&amp;quot;' if (!answer.nil? and answer.answer == j) or (answer.nil? and questionnaire_min == j)&lt;br /&gt;
      html += '&amp;gt;&amp;lt;/td&amp;gt;'&lt;br /&gt;
    end&lt;br /&gt;
    return html&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
* Identical code found in 1 other location Line 13 - 14 (mass = 40)&lt;br /&gt;
Also found in  app/models/scale.rb:10…11. Wrap the duplicated code into an instance method and add the instance method into superclass: scaled_question&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# add the following functions to refactor duplicates.  &lt;br /&gt;
def edit_end(ob, html)&lt;br /&gt;
    html+='&amp;lt;td&amp;gt; max_label &amp;lt;input size=&amp;quot;4&amp;quot; value=&amp;quot;'+ob.max_label.to_s+'&amp;quot; name=&amp;quot;question['+ob.id.to_s+'][max_label]&amp;quot; id=&amp;quot;question_'+ob.id.to_s+'_max_label&amp;quot; type=&amp;quot;text&amp;quot;&amp;gt;  min_label &amp;lt;input size=&amp;quot;4&amp;quot; value=&amp;quot;'+ob.min_label.to_s+'&amp;quot; name=&amp;quot;question['+ob.id.to_s+'][min_label]&amp;quot; id=&amp;quot;question_'+ob.id.to_s+'_min_label&amp;quot; type=&amp;quot;text&amp;quot;&amp;gt;&amp;lt;/td&amp;gt;'&lt;br /&gt;
    html+='&amp;lt;/tr&amp;gt;'&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
* Similar code found in 1 other location Line 103 - 105 (mass = 26)&lt;br /&gt;
Also found in   app/models/criterion.rb:107…110. Wrap the duplicated code into an instance method&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def complete_drop_down_label_config(html, label)&lt;br /&gt;
    html += j.to_s&lt;br /&gt;
    html += &amp;quot;-&amp;quot; + label if label &amp;amp;&amp;amp; label.length&amp;gt;0&lt;br /&gt;
    html += &amp;quot;&amp;lt;/option&amp;gt;&amp;quot;&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
* Similar code found in 2 other locations Line 152 - 153 (mass = 22)&lt;br /&gt;
 Also found in   app/models/criterion.rb:115…116, app/models/text_area.rb:12…13. Wrap the duplicated code into an instance method&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def complete_answer_comment(count, html, answer)&lt;br /&gt;
    html += '&amp;lt;textarea cols=' +cols+ ' rows=' +rows+ ' id=&amp;quot;responses_' +count.to_s+ '_comments&amp;quot; name=&amp;quot;responses[' +count.to_s+ '][comment]&amp;quot; style=&amp;quot;overflow:hidden;&amp;quot;&amp;gt;'&lt;br /&gt;
    html += answer.comments if !answer.nil?&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
* Similar code found in 3 other locations: Line 130 - 134 (mass = 18)&lt;br /&gt;
Also found in app/models/criterion.rb:145…149, app/models/scale.rb:45…49, app/models/scale.rb:60…64.&lt;br /&gt;
Wrap the duplicated code into an instance method and add the instance method into superclass: scaled_question&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# add the following functions to refactor duplicates.  &lt;br /&gt;
  def complete_label(label, html)&lt;br /&gt;
    if !label.nil?&lt;br /&gt;
      html += '&amp;lt;td width=&amp;quot;10%&amp;quot;&amp;gt;' +label+ '&amp;lt;/td&amp;gt;'&lt;br /&gt;
    else&lt;br /&gt;
      html += '&amp;lt;td width=&amp;quot;10%&amp;quot;&amp;gt;&amp;lt;/td&amp;gt;'&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Scale.rb===&lt;br /&gt;
* Cyclomatic complexity for complete is too high. Method has too many lines&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def complete(count, answer=nil, questionnaire_min, questionnaire_max)&lt;br /&gt;
  	html = self.txt + '&amp;lt;br&amp;gt;'&lt;br /&gt;
    html += '&amp;lt;input id=&amp;quot;responses_' +count.to_s+ '_score&amp;quot; name=&amp;quot;responses[' +count.to_s+ '][score]&amp;quot; type=&amp;quot;hidden&amp;quot;'&lt;br /&gt;
    html += 'value=&amp;quot;'+answer.answer.to_s+'&amp;quot;' if !answer.nil?&lt;br /&gt;
    html += '&amp;gt;'&lt;br /&gt;
    html += '&amp;lt;input id=&amp;quot;responses_' +count.to_s+ '_comments&amp;quot; name=&amp;quot;responses[' +count.to_s+ '][comment]&amp;quot; type=&amp;quot;hidden&amp;quot; value=&amp;quot;&amp;quot;&amp;gt;'&lt;br /&gt;
&lt;br /&gt;
    html += '&amp;lt;table&amp;gt;'&lt;br /&gt;
    html += '&amp;lt;tr&amp;gt;&amp;lt;td width=&amp;quot;10%&amp;quot;&amp;gt;&amp;lt;/td&amp;gt;'&lt;br /&gt;
    for j in questionnaire_min..questionnaire_max&lt;br /&gt;
      html += '&amp;lt;td width=&amp;quot;10%&amp;quot;&amp;gt;&amp;lt;label&amp;gt;' +j.to_s+ '&amp;lt;/label&amp;gt;&amp;lt;/td&amp;gt;'&lt;br /&gt;
    end&lt;br /&gt;
    html += '&amp;lt;td width=&amp;quot;10%&amp;quot;&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;tr&amp;gt;'&lt;br /&gt;
&lt;br /&gt;
    html = complete_label(self.min_label, html)&lt;br /&gt;
    html = complete_questionnaire_min_to_questionnaire_max(self, html, answer, questionnaire_min, questionnaire_max)&lt;br /&gt;
&lt;br /&gt;
    html += '&amp;lt;script&amp;gt;jQuery(&amp;quot;input[name=Radio_' +self.id.to_s+ ']:radio&amp;quot;).change(function() {'&lt;br /&gt;
    html += 'var response_score = jQuery(&amp;quot;#responses_' +count.to_s+ '_score&amp;quot;);'&lt;br /&gt;
    html += 'var checked_value = jQuery(&amp;quot;input[name=Radio_' +self.id.to_s+ ']:checked&amp;quot;).val();'&lt;br /&gt;
    html += 'response_score.val(checked_value);});&amp;lt;/script&amp;gt;'&lt;br /&gt;
    html = complete_label(self.max_label, html)&lt;br /&gt;
&lt;br /&gt;
    html += '&amp;lt;td width=&amp;quot;10%&amp;quot;&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;/table&amp;gt;'&lt;br /&gt;
    html.html_safe&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
* Identical code found in 1 other location: line 17-28&lt;br /&gt;
app/models/criterion.rb:20…32, def view_question_text.&lt;br /&gt;
The following method is removed from subclass: scale and added to their superclass: scaled_question.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#This method returns what to display if an instructor (etc.) is viewing a questionnaire&lt;br /&gt;
  def view_question_text&lt;br /&gt;
    html = '&amp;lt;TR&amp;gt;&amp;lt;TD align=&amp;quot;left&amp;quot;&amp;gt; '+self.txt+' &amp;lt;/TD&amp;gt;'&lt;br /&gt;
    html += '&amp;lt;TD align=&amp;quot;left&amp;quot;&amp;gt;'+self.type+'&amp;lt;/TD&amp;gt;'&lt;br /&gt;
    html += '&amp;lt;td align=&amp;quot;center&amp;quot;&amp;gt;'+self.weight.to_s+'&amp;lt;/TD&amp;gt;'&lt;br /&gt;
    questionnaire = self.questionnaire&lt;br /&gt;
    if !self.max_label.nil? &amp;amp;&amp;amp; !self.min_label.nil?&lt;br /&gt;
      html += '&amp;lt;TD align=&amp;quot;center&amp;quot;&amp;gt; ('+self.min_label+') '+questionnaire.min_question_score.to_s+' to '+ questionnaire.max_question_score.to_s + ' ('+self.max_label+')&amp;lt;/TD&amp;gt;'&lt;br /&gt;
    else&lt;br /&gt;
      html += '&amp;lt;TD align=&amp;quot;center&amp;quot;&amp;gt;'+questionnaire.min_question_score.to_s+' to '+ questionnaire.max_question_score.to_s + '&amp;lt;/TD&amp;gt;'&lt;br /&gt;
    end&lt;br /&gt;
    html += '&amp;lt;/TR&amp;gt;'&lt;br /&gt;
    html.html_safe&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
* Identical code  found in 1 other location: line 50-54&lt;br /&gt;
app/models/criterion.rb:135…139. Wrap the duplicated code into an instance method and add the instance method into superclass: scaled_question.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  # add the following functions to refactor duplicates.&lt;br /&gt;
  def complete_questionnaire_min_to_questionnaire_max(ob, html, answer, questionnaire_min, questionnaire_max)&lt;br /&gt;
    for j in questionnaire_min..questionnaire_max&lt;br /&gt;
      html += '&amp;lt;td width=&amp;quot;10%&amp;quot;&amp;gt;&amp;lt;input type=&amp;quot;radio&amp;quot; id=&amp;quot;' +j.to_s+ '&amp;quot; value=&amp;quot;' +j.to_s+ '&amp;quot; name=&amp;quot;Radio_' +ob.id.to_s+ '&amp;quot;'&lt;br /&gt;
      html += 'checked=&amp;quot;checked&amp;quot;' if (!answer.nil? and answer.answer == j) or (answer.nil? and questionnaire_min == j)&lt;br /&gt;
      html += '&amp;gt;&amp;lt;/td&amp;gt;'&lt;br /&gt;
    end&lt;br /&gt;
    return html&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
* Identical code found in 1 other location: line 10-11&lt;br /&gt;
app/models/criterion.rb:13…14. Wrap the duplicated code into an instance method and add the instance method into superclass: scaled_question&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# add the following functions to refactor duplicates.  &lt;br /&gt;
def edit_end(ob, html)&lt;br /&gt;
    html+='&amp;lt;td&amp;gt; max_label &amp;lt;input size=&amp;quot;4&amp;quot; value=&amp;quot;'+ob.max_label.to_s+'&amp;quot; name=&amp;quot;question['+ob.id.to_s+'][max_label]&amp;quot; id=&amp;quot;question_'+ob.id.to_s+'_max_label&amp;quot; type=&amp;quot;text&amp;quot;&amp;gt;  min_label &amp;lt;input size=&amp;quot;4&amp;quot; value=&amp;quot;'+ob.min_label.to_s+'&amp;quot; name=&amp;quot;question['+ob.id.to_s+'][min_label]&amp;quot; id=&amp;quot;question_'+ob.id.to_s+'_min_label&amp;quot; type=&amp;quot;text&amp;quot;&amp;gt;&amp;lt;/td&amp;gt;'&lt;br /&gt;
    html+='&amp;lt;/tr&amp;gt;'&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
* Similar code found in 3 other locations: line 60-64&lt;br /&gt;
app/models/criterion.rb:130…134, app/models/criterion.rb:145…149, app/models/scale.rb:45…49. &lt;br /&gt;
Wrap the duplicated code into an instance method and add the instance method into superclass: scaled_question&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# add the following functions to refactor duplicates.  &lt;br /&gt;
  def complete_label(label, html)&lt;br /&gt;
    if !label.nil?&lt;br /&gt;
      html += '&amp;lt;td width=&amp;quot;10%&amp;quot;&amp;gt;' +label+ '&amp;lt;/td&amp;gt;'&lt;br /&gt;
    else&lt;br /&gt;
      html += '&amp;lt;td width=&amp;quot;10%&amp;quot;&amp;gt;&amp;lt;/td&amp;gt;'&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Checkbox.rb===&lt;br /&gt;
* Method has too many lines.&lt;br /&gt;
By moving codes to private methods outside this method, this problem can be fixed together with the following one. Here is the new complete method together with two additional private methods: hasAnswer(html, answer) and nextQuestionTail(html, next_question). The source codes are listed as below.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def complete(count, answer=nil)&lt;br /&gt;
    curr_question = Question.find(self.id)&lt;br /&gt;
    prev_question = Question.where(&amp;quot;seq &amp;lt; ?&amp;quot;, curr_question.seq).order(:seq).last&lt;br /&gt;
    next_question = Question.where(&amp;quot;seq &amp;gt; ?&amp;quot;, curr_question.seq).order(:seq).first&lt;br /&gt;
    html = ''&lt;br /&gt;
    if prev_question.type == 'ColumnHeader'&lt;br /&gt;
      html = '&amp;lt;td style=&amp;quot;padding: 15px;&amp;quot;&amp;gt;'&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    html += '&amp;lt;input id=&amp;quot;responses_' +count.to_s+ '_comments&amp;quot; name=&amp;quot;responses[' +count.to_s+ '][comment]&amp;quot; type=&amp;quot;hidden&amp;quot; value=&amp;quot;&amp;quot;&amp;gt;'&lt;br /&gt;
    html += '&amp;lt;input id=&amp;quot;responses_' +count.to_s+ '_score&amp;quot; name=&amp;quot;responses[' +count.to_s+ '][score]&amp;quot; type=&amp;quot;hidden&amp;quot;'&lt;br /&gt;
    html += hasAnswer(html , answer)&lt;br /&gt;
    html += '&amp;gt;'&lt;br /&gt;
    html += '&amp;lt;input id=&amp;quot;responses_' +count.to_s+ '_checkbox&amp;quot; type=&amp;quot;checkbox&amp;quot; onchange=&amp;quot;checkbox' +count.to_s+ 'Changed()&amp;quot;'&lt;br /&gt;
    html += 'checked=&amp;quot;checked&amp;quot;' if !answer.nil? and answer.answer == 1&lt;br /&gt;
    html += '&amp;gt;'&lt;br /&gt;
    html += '&amp;lt;label for=&amp;quot;responses_' +count.to_s+ '&amp;quot;&amp;gt;' +self.txt+ '&amp;lt;/label&amp;gt;'&lt;br /&gt;
&lt;br /&gt;
    html += '&amp;lt;script&amp;gt;function checkbox' +count.to_s+ 'Changed() {'&lt;br /&gt;
    html += ' var checkbox = jQuery(&amp;quot;#responses_' +count.to_s+ '_checkbox&amp;quot;);'&lt;br /&gt;
    html += ' var response_score = jQuery(&amp;quot;#responses_' +count.to_s+ '_score&amp;quot;);'&lt;br /&gt;
    html += 'if (checkbox.is(&amp;quot;:checked&amp;quot;)) {'&lt;br /&gt;
    html += 'response_score.val(&amp;quot;1&amp;quot;);'&lt;br /&gt;
    html += '} else {'&lt;br /&gt;
    html += 'response_score.val(&amp;quot;0&amp;quot;);}}&amp;lt;/script&amp;gt;'&lt;br /&gt;
&lt;br /&gt;
    html = nextQuestionTail(html, next_question)&lt;br /&gt;
    html.html_safe&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  #YJ private for complete()&lt;br /&gt;
  def hasAnswer(html, answer)&lt;br /&gt;
    if !answer.nil? and answer.answer == 1&lt;br /&gt;
      html += 'value=&amp;quot;1&amp;quot;'&lt;br /&gt;
    else&lt;br /&gt;
      html += 'value=&amp;quot;0&amp;quot;'&lt;br /&gt;
    end&lt;br /&gt;
    return html&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def nextQuestionTail(html, next_q)&lt;br /&gt;
    if next_question.type == 'ColumnHeader'&lt;br /&gt;
      html += '&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;'&lt;br /&gt;
    elsif next_question.type == 'SectionHeader' or next_question.type == 'TableHeader'&lt;br /&gt;
      html += '&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;/table&amp;gt;&amp;lt;br/&amp;gt;'&lt;br /&gt;
    else&lt;br /&gt;
      html += '&amp;lt;BR/&amp;gt;'&lt;br /&gt;
    end&lt;br /&gt;
    return html&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
* Cyclomatic complexity for complete is too high.&lt;br /&gt;
This problem can be solved by moving branches outside to other private methods. See source code above.&lt;br /&gt;
* Similar codes in edit method are found in 2 other locations.&lt;br /&gt;
(questionnaire_header.rb and upload_file.rb)&lt;br /&gt;
Such code duplication can be eliminated by moving the identical part of the similar edit method to a new function, named edit_prefix(html, count) to their common superclass, which is Question (question.rb).&lt;br /&gt;
Here is the source code of the added edit_prefix method in question.rb:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 def edit_prefix(self, html)&lt;br /&gt;
    html ='&amp;lt;tr&amp;gt;'&lt;br /&gt;
    html+='&amp;lt;td align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;a rel=&amp;quot;nofollow&amp;quot; data-method=&amp;quot;delete&amp;quot; href=&amp;quot;/questions/' +ob.id.to_s+ '&amp;quot;&amp;gt;Remove&amp;lt;/a&amp;gt;&amp;lt;/td&amp;gt;'&lt;br /&gt;
    html+='&amp;lt;td&amp;gt;&amp;lt;input size=&amp;quot;6&amp;quot; value=&amp;quot;'+ob.seq.to_s+'&amp;quot; name=&amp;quot;question['+ob.id.to_s+'][seq]&amp;quot; id=&amp;quot;question_'+ob.id.to_s+'_seq&amp;quot; type=&amp;quot;text&amp;quot;&amp;gt;&amp;lt;/td&amp;gt;'&lt;br /&gt;
    html+='&amp;lt;td&amp;gt;&amp;lt;textarea cols=&amp;quot;50&amp;quot; rows=&amp;quot;1&amp;quot; name=&amp;quot;question['+ob.id.to_s+'][txt]&amp;quot; id=&amp;quot;question_'+ob.id.to_s+'_txt&amp;quot;&amp;gt;'+ob.txt+'&amp;lt;/textarea&amp;gt;&amp;lt;/td&amp;gt;'&lt;br /&gt;
    html+='&amp;lt;td&amp;gt;&amp;lt;input size=&amp;quot;10&amp;quot; disabled=&amp;quot;disabled&amp;quot; value=&amp;quot;'+ob.type+'&amp;quot; name=&amp;quot;question['+ob.id.to_s+'][type]&amp;quot; id=&amp;quot;question_'+ob.id.to_s+'_type&amp;quot; type=&amp;quot;text&amp;quot;&amp;gt;''&amp;lt;/td&amp;gt;'&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
The original code are commented out and insert the function call of the above function, html will be returned in the above function, see codes below:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def edit(count)&lt;br /&gt;
    html = edit_prefix(self, html)&lt;br /&gt;
    html+='&amp;lt;td&amp;gt;&amp;lt;!--placeholder (UnscoredQuestion does not need weight)--&amp;gt;&amp;lt;/td&amp;gt;'&lt;br /&gt;
    html+='&amp;lt;/tr&amp;gt;'&lt;br /&gt;
    html.html_safe&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
* Similar codes in view_question_text method are found in 4 other locations.&lt;br /&gt;
(dropdown.rb, questionnaire_header.rb, text_response.rb, upload_file.rb)&lt;br /&gt;
The solution to this problem is the same as above one, below is the function added in the most common superclass, which is Question, that contains the common parts of the codes found in the view_question_text methods in all five classes.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def view_qt_prefix(ob, html)&lt;br /&gt;
    html = '&amp;lt;TR&amp;gt;&amp;lt;TD align=&amp;quot;left&amp;quot;&amp;gt; '+ob.txt+ ' &amp;lt;/TD&amp;gt;'&lt;br /&gt;
    html += '&amp;lt;TD align=&amp;quot;left&amp;quot;&amp;gt;'+ob.type+'&amp;lt;/TD&amp;gt;'&lt;br /&gt;
    html += '&amp;lt;td align=&amp;quot;center&amp;quot;&amp;gt;'+ob.weight.to_s+'&amp;lt;/TD&amp;gt;'&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
The original code are commented out and insert the function call of the above function, html will be returned in the above function, see codes below:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def view_question_text&lt;br /&gt;
    html = view_qt_prefix(ob, html)&lt;br /&gt;
    html += '&amp;lt;TD align=&amp;quot;center&amp;quot;&amp;gt;Checked/Unchecked&amp;lt;/TD&amp;gt;'&lt;br /&gt;
    html += '&amp;lt;/TR&amp;gt;'&lt;br /&gt;
    html.html_safe&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Questionnaire_header.rb===&lt;br /&gt;
All problems in this file are solved after solving the problems found in checkbox.rb.&lt;br /&gt;
&lt;br /&gt;
===Upload_file.rb===&lt;br /&gt;
All problems in this file are solved after solving the problems found in checkbox.rb.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Unit-tests==&lt;br /&gt;
One contribution is to write unite test for four question types. For each of the four required question types: &lt;br /&gt;
*criterion.rb,&lt;br /&gt;
*scale.rb,&lt;br /&gt;
*checkbox.rb,&lt;br /&gt;
*upload_file.rb,&lt;br /&gt;
there are four unit tests for the following four functions: &lt;br /&gt;
*''edit'', &lt;br /&gt;
*''complete'', &lt;br /&gt;
*''view_question_text'', &lt;br /&gt;
*''view_complete_question_text''. &lt;br /&gt;
&lt;br /&gt;
These four functions are tested since they are the only methods that the question types class can perform. &lt;br /&gt;
&lt;br /&gt;
The output of those four functions is HTML format string. We test if the output string is matched with the expected given certain conditions. Here are the spec files git hub links:&lt;br /&gt;
*[https://github.com/schen35/expertiza/blob/master/spec/models/criterion_spec.rb criterion_spec.rb] &lt;br /&gt;
*[https://github.com/schen35/expertiza/blob/master/spec/models/scale_spec.rb scale_spec.rb] &lt;br /&gt;
*[https://github.com/schen35/expertiza/blob/master/spec/models/checkbox_spec.rb checkbox_spec.rb] &lt;br /&gt;
*[https://github.com/schen35/expertiza/blob/master/spec/models/upload_file_spec.rb upload_file_spec.rb].&lt;/div&gt;</summary>
		<author><name>Hguan2</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2016/Refactor_and_write_unit_tests_for_question_type.rb&amp;diff=101737</id>
		<title>CSC/ECE 517 Spring 2016/Refactor and write unit tests for question type.rb</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2016/Refactor_and_write_unit_tests_for_question_type.rb&amp;diff=101737"/>
		<updated>2016-04-04T01:35:25Z</updated>

		<summary type="html">&lt;p&gt;Hguan2: /* Unit-tests */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This wiki page is for the description of changes made under E1608 OSS assignment for Spring 2016, CSC/ECE 517. The assignment task is to  refactor &amp;amp; write unit tests for [question_type].rb (eg. criterion.rb).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Problem Statement ==&lt;br /&gt;
===Files related===&lt;br /&gt;
Four models is related: criterion.rb, scale.rb, checkbox.rb, questionnaire_header.rb, upload_file.rb. There are 4 methods “edit”, “view_question_text”, “complete” and “view_completed_question” correspond to different views. &lt;br /&gt;
&lt;br /&gt;
*edit ~&amp;gt;	when instructor add/edit new questions&lt;br /&gt;
*view ~&amp;gt; when instructor view existed questions&lt;br /&gt;
*complete ~&amp;gt; when students do peer reviews&lt;br /&gt;
*view_completed_question ~&amp;gt; when student view existed peer reviews&lt;br /&gt;
&lt;br /&gt;
===Expertiza question types inheritance hierarchy===&lt;br /&gt;
&lt;br /&gt;
*Choice question&lt;br /&gt;
**Scored question&lt;br /&gt;
***Scale&lt;br /&gt;
***Criterion&lt;br /&gt;
**Unscored question&lt;br /&gt;
***Dropdown&lt;br /&gt;
***CheckBox&lt;br /&gt;
*TextResponse&lt;br /&gt;
**TextArea&lt;br /&gt;
**TextField&lt;br /&gt;
*UploadFile&lt;br /&gt;
&lt;br /&gt;
===Files problem===&lt;br /&gt;
&lt;br /&gt;
There are some issues in each file, such as security, complexity, duplication, etc. And currently there is no unit tests for [question_type].rb.&lt;br /&gt;
&lt;br /&gt;
===Our contribution===&lt;br /&gt;
*Refactor these [question_type].rb files and fix issues.&lt;br /&gt;
*Keep the inputs and outputs of these methods (edit, view, complete, view_completed_question) the same as before.&lt;br /&gt;
*Write unit tests for [question_type].rb listed above.&lt;br /&gt;
*Create RSpec files for each question type in /spec/models/ folder&lt;br /&gt;
*Create multiple tests to check valid and invalid cases, such as input including special character double quote (“”).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
==Refactor==&lt;br /&gt;
===Criterion.rb===&lt;br /&gt;
* Method has too many lines: Line 35 - 158 [106/30]&lt;br /&gt;
Wrap the specific code into different instance methods. &lt;br /&gt;
* Cyclomatic complexity for complete is too high: Line 35 - 158 [28/6]&lt;br /&gt;
Wrap the code into different instance methods to reduce cyclomatic complexity&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 def complete(count, answer=nil, questionnaire_min, questionnaire_max, dropdown_or_scale)&lt;br /&gt;
    if self.size.nil?&lt;br /&gt;
      cols = '70'&lt;br /&gt;
      rows = '1'&lt;br /&gt;
    else&lt;br /&gt;
      cols = self.size.split(',')[0]&lt;br /&gt;
      rows = self.size.split(',')[1]&lt;br /&gt;
    end&lt;br /&gt;
    html = '&amp;lt;li&amp;gt;&amp;lt;div&amp;gt;&amp;lt;label for=&amp;quot;responses_' +count.to_s+ '&amp;quot;&amp;gt;' +self.txt+ &amp;quot;&amp;lt;/label&amp;gt;&amp;lt;/div&amp;gt;&amp;quot;&lt;br /&gt;
    #show advice for each criterion question&lt;br /&gt;
    question_advices = QuestionAdvice.where(question_id: self.id).sort_by { |advice| advice.id }&lt;br /&gt;
    advice_total_length = 0&lt;br /&gt;
    question_advices.each do |question_advice|&lt;br /&gt;
      if question_advice.advice &amp;amp;&amp;amp; !question_advice.advice == &amp;quot;&amp;quot;&lt;br /&gt;
        advice_total_length += question_advice.advice.length&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
    if question_advices.length &amp;gt; 0 and advice_total_length &amp;gt; 0&lt;br /&gt;
       html = complete_show_advice(self, html)&lt;br /&gt;
    question_advices.reverse.each_with_index do |question_advice, index|&lt;br /&gt;
        html += '&amp;lt;a id=&amp;quot;changeScore_&amp;gt;' + self.id.to_s + '&amp;quot; onclick=&amp;quot;changeScore(' + count.to_s + ',' + index.to_s + ')&amp;quot;&amp;gt;'&lt;br /&gt;
        html += (question_advices.length - index).to_s + ' - ' + question_advice.advice + '&amp;lt;/a&amp;gt;&amp;lt;br/&amp;gt;'&lt;br /&gt;
        html += '&amp;lt;script&amp;gt;'&lt;br /&gt;
        html += 'function changeScore(i, j) {'&lt;br /&gt;
        html += 'var elem = jQuery(&amp;quot;#responses_&amp;quot; + i.toString() + &amp;quot;_score&amp;quot;);'&lt;br /&gt;
        html += 'var opts = elem.children(&amp;quot;option&amp;quot;).length;'&lt;br /&gt;
        html += 'elem.val((opts - j - 1).toString());}'&lt;br /&gt;
        html += '&amp;lt;/script&amp;gt;'&lt;br /&gt;
      end&lt;br /&gt;
      html += '&amp;lt;/div&amp;gt;'&lt;br /&gt;
    end&lt;br /&gt;
    if dropdown_or_scale == 'dropdown'&lt;br /&gt;
      ## code added  to reduce Cyclomatic Complexity&lt;br /&gt;
      html = complete_drop_down(self, html, count, answer, questionnaire_min, questionnaire_max)&lt;br /&gt;
    elsif dropdown_or_scale == 'scale'&lt;br /&gt;
       html = complete_scale(self, html, count, answer, questionnaire_min, questionnaire_max)&lt;br /&gt;
    end&lt;br /&gt;
    html.html_safe&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
* Identical code found in 1 other location: Line 20 - 32 (mass = 89)&lt;br /&gt;
Also found in   app/models/scale.rb:17…28. The following method is removed from subclass: criterion and added to their superclass: scaled_question&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def view_question_text&lt;br /&gt;
    html = '&amp;lt;TR&amp;gt;&amp;lt;TD align=&amp;quot;left&amp;quot;&amp;gt; '+self.txt+' &amp;lt;/TD&amp;gt;'&lt;br /&gt;
    html += '&amp;lt;TD align=&amp;quot;left&amp;quot;&amp;gt;'+self.type+'&amp;lt;/TD&amp;gt;'&lt;br /&gt;
    html += '&amp;lt;td align=&amp;quot;center&amp;quot;&amp;gt;'+self.weight.to_s+'&amp;lt;/TD&amp;gt;'&lt;br /&gt;
    questionnaire = self.questionnaire&lt;br /&gt;
    if !self.max_label.nil? &amp;amp;&amp;amp; !self.min_label.nil?&lt;br /&gt;
      html += '&amp;lt;TD align=&amp;quot;center&amp;quot;&amp;gt; ('+self.min_label+') '+questionnaire.min_question_score.to_s+' to '+ questionnaire.max_question_score.to_s + ' ('+self.max_label+')&amp;lt;/TD&amp;gt;'&lt;br /&gt;
    else&lt;br /&gt;
      html += '&amp;lt;TD align=&amp;quot;center&amp;quot;&amp;gt;'+questionnaire.min_question_score.to_s+' to '+ questionnaire.max_question_score.to_s + '&amp;lt;/TD&amp;gt;'&lt;br /&gt;
    end&lt;br /&gt;
    html += '&amp;lt;/TR&amp;gt;'&lt;br /&gt;
    Html.html_safe&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
* Identical code found in 1 other location: Line 135 - 139 (mass = 50)&lt;br /&gt;
Also found in  app/models/scale.rb:50…54. Wrap the duplicated code into an instance method and add the instance method into superclass: scaled_question&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# add the following functions to refactor duplicates.&lt;br /&gt;
  def complete_questionnaire_min_to_questionnaire_max(ob, html, answer, questionnaire_min, questionnaire_max)&lt;br /&gt;
    for j in questionnaire_min..questionnaire_max&lt;br /&gt;
      html += '&amp;lt;td width=&amp;quot;10%&amp;quot;&amp;gt;&amp;lt;input type=&amp;quot;radio&amp;quot; id=&amp;quot;' +j.to_s+ '&amp;quot; value=&amp;quot;' +j.to_s+ '&amp;quot; name=&amp;quot;Radio_' +ob.id.to_s+ '&amp;quot;'&lt;br /&gt;
      html += 'checked=&amp;quot;checked&amp;quot;' if (!answer.nil? and answer.answer == j) or (answer.nil? and questionnaire_min == j)&lt;br /&gt;
      html += '&amp;gt;&amp;lt;/td&amp;gt;'&lt;br /&gt;
    end&lt;br /&gt;
    return html&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
* Identical code found in 1 other location Line 13 - 14 (mass = 40)&lt;br /&gt;
Also found in  app/models/scale.rb:10…11. Wrap the duplicated code into an instance method and add the instance method into superclass: scaled_question&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# add the following functions to refactor duplicates.  &lt;br /&gt;
def edit_end(ob, html)&lt;br /&gt;
    html+='&amp;lt;td&amp;gt; max_label &amp;lt;input size=&amp;quot;4&amp;quot; value=&amp;quot;'+ob.max_label.to_s+'&amp;quot; name=&amp;quot;question['+ob.id.to_s+'][max_label]&amp;quot; id=&amp;quot;question_'+ob.id.to_s+'_max_label&amp;quot; type=&amp;quot;text&amp;quot;&amp;gt;  min_label &amp;lt;input size=&amp;quot;4&amp;quot; value=&amp;quot;'+ob.min_label.to_s+'&amp;quot; name=&amp;quot;question['+ob.id.to_s+'][min_label]&amp;quot; id=&amp;quot;question_'+ob.id.to_s+'_min_label&amp;quot; type=&amp;quot;text&amp;quot;&amp;gt;&amp;lt;/td&amp;gt;'&lt;br /&gt;
    html+='&amp;lt;/tr&amp;gt;'&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
* Similar code found in 1 other location Line 103 - 105 (mass = 26)&lt;br /&gt;
Also found in   app/models/criterion.rb:107…110. Wrap the duplicated code into an instance method&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def complete_drop_down_label_config(html, label)&lt;br /&gt;
    html += j.to_s&lt;br /&gt;
    html += &amp;quot;-&amp;quot; + label if label &amp;amp;&amp;amp; label.length&amp;gt;0&lt;br /&gt;
    html += &amp;quot;&amp;lt;/option&amp;gt;&amp;quot;&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
* Similar code found in 2 other locations Line 152 - 153 (mass = 22)&lt;br /&gt;
 Also found in   app/models/criterion.rb:115…116, app/models/text_area.rb:12…13. Wrap the duplicated code into an instance method&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def complete_answer_comment(count, html, answer)&lt;br /&gt;
    html += '&amp;lt;textarea cols=' +cols+ ' rows=' +rows+ ' id=&amp;quot;responses_' +count.to_s+ '_comments&amp;quot; name=&amp;quot;responses[' +count.to_s+ '][comment]&amp;quot; style=&amp;quot;overflow:hidden;&amp;quot;&amp;gt;'&lt;br /&gt;
    html += answer.comments if !answer.nil?&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
* Similar code found in 3 other locations: Line 130 - 134 (mass = 18)&lt;br /&gt;
Also found in app/models/criterion.rb:145…149, app/models/scale.rb:45…49, app/models/scale.rb:60…64.&lt;br /&gt;
Wrap the duplicated code into an instance method and add the instance method into superclass: scaled_question&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# add the following functions to refactor duplicates.  &lt;br /&gt;
  def complete_label(label, html)&lt;br /&gt;
    if !label.nil?&lt;br /&gt;
      html += '&amp;lt;td width=&amp;quot;10%&amp;quot;&amp;gt;' +label+ '&amp;lt;/td&amp;gt;'&lt;br /&gt;
    else&lt;br /&gt;
      html += '&amp;lt;td width=&amp;quot;10%&amp;quot;&amp;gt;&amp;lt;/td&amp;gt;'&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Scale.rb===&lt;br /&gt;
* Cyclomatic complexity for complete is too high. Method has too many lines&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def complete(count, answer=nil, questionnaire_min, questionnaire_max)&lt;br /&gt;
  	html = self.txt + '&amp;lt;br&amp;gt;'&lt;br /&gt;
    html += '&amp;lt;input id=&amp;quot;responses_' +count.to_s+ '_score&amp;quot; name=&amp;quot;responses[' +count.to_s+ '][score]&amp;quot; type=&amp;quot;hidden&amp;quot;'&lt;br /&gt;
    html += 'value=&amp;quot;'+answer.answer.to_s+'&amp;quot;' if !answer.nil?&lt;br /&gt;
    html += '&amp;gt;'&lt;br /&gt;
    html += '&amp;lt;input id=&amp;quot;responses_' +count.to_s+ '_comments&amp;quot; name=&amp;quot;responses[' +count.to_s+ '][comment]&amp;quot; type=&amp;quot;hidden&amp;quot; value=&amp;quot;&amp;quot;&amp;gt;'&lt;br /&gt;
&lt;br /&gt;
    html += '&amp;lt;table&amp;gt;'&lt;br /&gt;
    html += '&amp;lt;tr&amp;gt;&amp;lt;td width=&amp;quot;10%&amp;quot;&amp;gt;&amp;lt;/td&amp;gt;'&lt;br /&gt;
    for j in questionnaire_min..questionnaire_max&lt;br /&gt;
      html += '&amp;lt;td width=&amp;quot;10%&amp;quot;&amp;gt;&amp;lt;label&amp;gt;' +j.to_s+ '&amp;lt;/label&amp;gt;&amp;lt;/td&amp;gt;'&lt;br /&gt;
    end&lt;br /&gt;
    html += '&amp;lt;td width=&amp;quot;10%&amp;quot;&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;tr&amp;gt;'&lt;br /&gt;
&lt;br /&gt;
    html = complete_label(self.min_label, html)&lt;br /&gt;
    html = complete_questionnaire_min_to_questionnaire_max(self, html, answer, questionnaire_min, questionnaire_max)&lt;br /&gt;
&lt;br /&gt;
    html += '&amp;lt;script&amp;gt;jQuery(&amp;quot;input[name=Radio_' +self.id.to_s+ ']:radio&amp;quot;).change(function() {'&lt;br /&gt;
    html += 'var response_score = jQuery(&amp;quot;#responses_' +count.to_s+ '_score&amp;quot;);'&lt;br /&gt;
    html += 'var checked_value = jQuery(&amp;quot;input[name=Radio_' +self.id.to_s+ ']:checked&amp;quot;).val();'&lt;br /&gt;
    html += 'response_score.val(checked_value);});&amp;lt;/script&amp;gt;'&lt;br /&gt;
    html = complete_label(self.max_label, html)&lt;br /&gt;
&lt;br /&gt;
    html += '&amp;lt;td width=&amp;quot;10%&amp;quot;&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;/table&amp;gt;'&lt;br /&gt;
    html.html_safe&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
* Identical code found in 1 other location: line 17-28&lt;br /&gt;
app/models/criterion.rb:20…32, def view_question_text.&lt;br /&gt;
The following method is removed from subclass: scale and added to their superclass: scaled_question.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#This method returns what to display if an instructor (etc.) is viewing a questionnaire&lt;br /&gt;
  def view_question_text&lt;br /&gt;
    html = '&amp;lt;TR&amp;gt;&amp;lt;TD align=&amp;quot;left&amp;quot;&amp;gt; '+self.txt+' &amp;lt;/TD&amp;gt;'&lt;br /&gt;
    html += '&amp;lt;TD align=&amp;quot;left&amp;quot;&amp;gt;'+self.type+'&amp;lt;/TD&amp;gt;'&lt;br /&gt;
    html += '&amp;lt;td align=&amp;quot;center&amp;quot;&amp;gt;'+self.weight.to_s+'&amp;lt;/TD&amp;gt;'&lt;br /&gt;
    questionnaire = self.questionnaire&lt;br /&gt;
    if !self.max_label.nil? &amp;amp;&amp;amp; !self.min_label.nil?&lt;br /&gt;
      html += '&amp;lt;TD align=&amp;quot;center&amp;quot;&amp;gt; ('+self.min_label+') '+questionnaire.min_question_score.to_s+' to '+ questionnaire.max_question_score.to_s + ' ('+self.max_label+')&amp;lt;/TD&amp;gt;'&lt;br /&gt;
    else&lt;br /&gt;
      html += '&amp;lt;TD align=&amp;quot;center&amp;quot;&amp;gt;'+questionnaire.min_question_score.to_s+' to '+ questionnaire.max_question_score.to_s + '&amp;lt;/TD&amp;gt;'&lt;br /&gt;
    end&lt;br /&gt;
    html += '&amp;lt;/TR&amp;gt;'&lt;br /&gt;
    html.html_safe&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
* Identical code  found in 1 other location: line 50-54&lt;br /&gt;
app/models/criterion.rb:135…139. Wrap the duplicated code into an instance method and add the instance method into superclass: scaled_question.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  # add the following functions to refactor duplicates.&lt;br /&gt;
  def complete_questionnaire_min_to_questionnaire_max(ob, html, answer, questionnaire_min, questionnaire_max)&lt;br /&gt;
    for j in questionnaire_min..questionnaire_max&lt;br /&gt;
      html += '&amp;lt;td width=&amp;quot;10%&amp;quot;&amp;gt;&amp;lt;input type=&amp;quot;radio&amp;quot; id=&amp;quot;' +j.to_s+ '&amp;quot; value=&amp;quot;' +j.to_s+ '&amp;quot; name=&amp;quot;Radio_' +ob.id.to_s+ '&amp;quot;'&lt;br /&gt;
      html += 'checked=&amp;quot;checked&amp;quot;' if (!answer.nil? and answer.answer == j) or (answer.nil? and questionnaire_min == j)&lt;br /&gt;
      html += '&amp;gt;&amp;lt;/td&amp;gt;'&lt;br /&gt;
    end&lt;br /&gt;
    return html&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
* Identical code found in 1 other location: line 10-11&lt;br /&gt;
app/models/criterion.rb:13…14. Wrap the duplicated code into an instance method and add the instance method into superclass: scaled_question&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# add the following functions to refactor duplicates.  &lt;br /&gt;
def edit_end(ob, html)&lt;br /&gt;
    html+='&amp;lt;td&amp;gt; max_label &amp;lt;input size=&amp;quot;4&amp;quot; value=&amp;quot;'+ob.max_label.to_s+'&amp;quot; name=&amp;quot;question['+ob.id.to_s+'][max_label]&amp;quot; id=&amp;quot;question_'+ob.id.to_s+'_max_label&amp;quot; type=&amp;quot;text&amp;quot;&amp;gt;  min_label &amp;lt;input size=&amp;quot;4&amp;quot; value=&amp;quot;'+ob.min_label.to_s+'&amp;quot; name=&amp;quot;question['+ob.id.to_s+'][min_label]&amp;quot; id=&amp;quot;question_'+ob.id.to_s+'_min_label&amp;quot; type=&amp;quot;text&amp;quot;&amp;gt;&amp;lt;/td&amp;gt;'&lt;br /&gt;
    html+='&amp;lt;/tr&amp;gt;'&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
* Similar code found in 3 other locations: line 60-64&lt;br /&gt;
app/models/criterion.rb:130…134, app/models/criterion.rb:145…149, app/models/scale.rb:45…49. &lt;br /&gt;
Wrap the duplicated code into an instance method and add the instance method into superclass: scaled_question&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# add the following functions to refactor duplicates.  &lt;br /&gt;
  def complete_label(label, html)&lt;br /&gt;
    if !label.nil?&lt;br /&gt;
      html += '&amp;lt;td width=&amp;quot;10%&amp;quot;&amp;gt;' +label+ '&amp;lt;/td&amp;gt;'&lt;br /&gt;
    else&lt;br /&gt;
      html += '&amp;lt;td width=&amp;quot;10%&amp;quot;&amp;gt;&amp;lt;/td&amp;gt;'&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Checkbox.rb===&lt;br /&gt;
* Method has too many lines.&lt;br /&gt;
By moving codes to private methods outside this method, this problem can be fixed together with the following one. Here is the new complete method together with two additional private methods: hasAnswer(html, answer) and nextQuestionTail(html, next_question). The source codes are listed as below.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def complete(count, answer=nil)&lt;br /&gt;
    curr_question = Question.find(self.id)&lt;br /&gt;
    prev_question = Question.where(&amp;quot;seq &amp;lt; ?&amp;quot;, curr_question.seq).order(:seq).last&lt;br /&gt;
    next_question = Question.where(&amp;quot;seq &amp;gt; ?&amp;quot;, curr_question.seq).order(:seq).first&lt;br /&gt;
    html = ''&lt;br /&gt;
    if prev_question.type == 'ColumnHeader'&lt;br /&gt;
      html = '&amp;lt;td style=&amp;quot;padding: 15px;&amp;quot;&amp;gt;'&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    html += '&amp;lt;input id=&amp;quot;responses_' +count.to_s+ '_comments&amp;quot; name=&amp;quot;responses[' +count.to_s+ '][comment]&amp;quot; type=&amp;quot;hidden&amp;quot; value=&amp;quot;&amp;quot;&amp;gt;'&lt;br /&gt;
    html += '&amp;lt;input id=&amp;quot;responses_' +count.to_s+ '_score&amp;quot; name=&amp;quot;responses[' +count.to_s+ '][score]&amp;quot; type=&amp;quot;hidden&amp;quot;'&lt;br /&gt;
    html += hasAnswer(html , answer)&lt;br /&gt;
    html += '&amp;gt;'&lt;br /&gt;
    html += '&amp;lt;input id=&amp;quot;responses_' +count.to_s+ '_checkbox&amp;quot; type=&amp;quot;checkbox&amp;quot; onchange=&amp;quot;checkbox' +count.to_s+ 'Changed()&amp;quot;'&lt;br /&gt;
    html += 'checked=&amp;quot;checked&amp;quot;' if !answer.nil? and answer.answer == 1&lt;br /&gt;
    html += '&amp;gt;'&lt;br /&gt;
    html += '&amp;lt;label for=&amp;quot;responses_' +count.to_s+ '&amp;quot;&amp;gt;' +self.txt+ '&amp;lt;/label&amp;gt;'&lt;br /&gt;
&lt;br /&gt;
    html += '&amp;lt;script&amp;gt;function checkbox' +count.to_s+ 'Changed() {'&lt;br /&gt;
    html += ' var checkbox = jQuery(&amp;quot;#responses_' +count.to_s+ '_checkbox&amp;quot;);'&lt;br /&gt;
    html += ' var response_score = jQuery(&amp;quot;#responses_' +count.to_s+ '_score&amp;quot;);'&lt;br /&gt;
    html += 'if (checkbox.is(&amp;quot;:checked&amp;quot;)) {'&lt;br /&gt;
    html += 'response_score.val(&amp;quot;1&amp;quot;);'&lt;br /&gt;
    html += '} else {'&lt;br /&gt;
    html += 'response_score.val(&amp;quot;0&amp;quot;);}}&amp;lt;/script&amp;gt;'&lt;br /&gt;
&lt;br /&gt;
    html = nextQuestionTail(html, next_question)&lt;br /&gt;
    html.html_safe&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  #YJ private for complete()&lt;br /&gt;
  def hasAnswer(html, answer)&lt;br /&gt;
    if !answer.nil? and answer.answer == 1&lt;br /&gt;
      html += 'value=&amp;quot;1&amp;quot;'&lt;br /&gt;
    else&lt;br /&gt;
      html += 'value=&amp;quot;0&amp;quot;'&lt;br /&gt;
    end&lt;br /&gt;
    return html&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def nextQuestionTail(html, next_q)&lt;br /&gt;
    if next_question.type == 'ColumnHeader'&lt;br /&gt;
      html += '&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;'&lt;br /&gt;
    elsif next_question.type == 'SectionHeader' or next_question.type == 'TableHeader'&lt;br /&gt;
      html += '&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;/table&amp;gt;&amp;lt;br/&amp;gt;'&lt;br /&gt;
    else&lt;br /&gt;
      html += '&amp;lt;BR/&amp;gt;'&lt;br /&gt;
    end&lt;br /&gt;
    return html&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
* Cyclomatic complexity for complete is too high.&lt;br /&gt;
This problem can be solved by moving branches outside to other private methods. See source code above.&lt;br /&gt;
* Similar codes in edit method are found in 2 other locations.&lt;br /&gt;
(questionnaire_header.rb and upload_file.rb)&lt;br /&gt;
Such code duplication can be eliminated by moving the identical part of the similar edit method to a new function, named edit_prefix(html, count) to their common superclass, which is Question (question.rb).&lt;br /&gt;
Here is the source code of the added edit_prefix method in question.rb:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 def edit_prefix(self, html)&lt;br /&gt;
    html ='&amp;lt;tr&amp;gt;'&lt;br /&gt;
    html+='&amp;lt;td align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;a rel=&amp;quot;nofollow&amp;quot; data-method=&amp;quot;delete&amp;quot; href=&amp;quot;/questions/' +ob.id.to_s+ '&amp;quot;&amp;gt;Remove&amp;lt;/a&amp;gt;&amp;lt;/td&amp;gt;'&lt;br /&gt;
    html+='&amp;lt;td&amp;gt;&amp;lt;input size=&amp;quot;6&amp;quot; value=&amp;quot;'+ob.seq.to_s+'&amp;quot; name=&amp;quot;question['+ob.id.to_s+'][seq]&amp;quot; id=&amp;quot;question_'+ob.id.to_s+'_seq&amp;quot; type=&amp;quot;text&amp;quot;&amp;gt;&amp;lt;/td&amp;gt;'&lt;br /&gt;
    html+='&amp;lt;td&amp;gt;&amp;lt;textarea cols=&amp;quot;50&amp;quot; rows=&amp;quot;1&amp;quot; name=&amp;quot;question['+ob.id.to_s+'][txt]&amp;quot; id=&amp;quot;question_'+ob.id.to_s+'_txt&amp;quot;&amp;gt;'+ob.txt+'&amp;lt;/textarea&amp;gt;&amp;lt;/td&amp;gt;'&lt;br /&gt;
    html+='&amp;lt;td&amp;gt;&amp;lt;input size=&amp;quot;10&amp;quot; disabled=&amp;quot;disabled&amp;quot; value=&amp;quot;'+ob.type+'&amp;quot; name=&amp;quot;question['+ob.id.to_s+'][type]&amp;quot; id=&amp;quot;question_'+ob.id.to_s+'_type&amp;quot; type=&amp;quot;text&amp;quot;&amp;gt;''&amp;lt;/td&amp;gt;'&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
The original code are commented out and insert the function call of the above function, html will be returned in the above function, see codes below:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def edit(count)&lt;br /&gt;
    html = edit_prefix(self, html)&lt;br /&gt;
    html+='&amp;lt;td&amp;gt;&amp;lt;!--placeholder (UnscoredQuestion does not need weight)--&amp;gt;&amp;lt;/td&amp;gt;'&lt;br /&gt;
    html+='&amp;lt;/tr&amp;gt;'&lt;br /&gt;
    html.html_safe&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
* Similar codes in view_question_text method are found in 4 other locations.&lt;br /&gt;
(dropdown.rb, questionnaire_header.rb, text_response.rb, upload_file.rb)&lt;br /&gt;
The solution to this problem is the same as above one, below is the function added in the most common superclass, which is Question, that contains the common parts of the codes found in the view_question_text methods in all five classes.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def view_qt_prefix(ob, html)&lt;br /&gt;
    html = '&amp;lt;TR&amp;gt;&amp;lt;TD align=&amp;quot;left&amp;quot;&amp;gt; '+ob.txt+ ' &amp;lt;/TD&amp;gt;'&lt;br /&gt;
    html += '&amp;lt;TD align=&amp;quot;left&amp;quot;&amp;gt;'+ob.type+'&amp;lt;/TD&amp;gt;'&lt;br /&gt;
    html += '&amp;lt;td align=&amp;quot;center&amp;quot;&amp;gt;'+ob.weight.to_s+'&amp;lt;/TD&amp;gt;'&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
The original code are commented out and insert the function call of the above function, html will be returned in the above function, see codes below:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def view_question_text&lt;br /&gt;
    html = view_qt_prefix(ob, html)&lt;br /&gt;
    html += '&amp;lt;TD align=&amp;quot;center&amp;quot;&amp;gt;Checked/Unchecked&amp;lt;/TD&amp;gt;'&lt;br /&gt;
    html += '&amp;lt;/TR&amp;gt;'&lt;br /&gt;
    html.html_safe&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Questionnaire_header.rb===&lt;br /&gt;
All problems in this file are solved after solving the problems found in checkbox.rb.&lt;br /&gt;
&lt;br /&gt;
===Upload_file.rb===&lt;br /&gt;
All problems in this file are solved after solving the problems found in checkbox.rb.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Unit-tests==&lt;br /&gt;
One contribution is to write unite test for four question types. For each of the four required four question types: &lt;br /&gt;
*criterion.rb,&lt;br /&gt;
*scale.rb,&lt;br /&gt;
*checkbox.rb,&lt;br /&gt;
*upload_file.rb,&lt;br /&gt;
there are four unit tests for the following four functions: &lt;br /&gt;
*''edit'', &lt;br /&gt;
*''complete'', &lt;br /&gt;
*''view_question_text'', &lt;br /&gt;
*''view_complete_question_text''. &lt;br /&gt;
&lt;br /&gt;
These four functions are tested since they are the only methods that the question types class can perform. &lt;br /&gt;
&lt;br /&gt;
The output of those four functions is HTML format string. We test if the output string is matched with the expected given certain conditions. Here are the spec files git hub links:&lt;br /&gt;
*[https://github.com/schen35/expertiza/blob/master/spec/models/criterion_spec.rb criterion_spec.rb] &lt;br /&gt;
*[https://github.com/schen35/expertiza/blob/master/spec/models/scale_spec.rb scale_spec.rb] &lt;br /&gt;
*[https://github.com/schen35/expertiza/blob/master/spec/models/checkbox_spec.rb checkbox_spec.rb] &lt;br /&gt;
*[https://github.com/schen35/expertiza/blob/master/spec/models/upload_file_spec.rb upload_file_spec.rb].&lt;/div&gt;</summary>
		<author><name>Hguan2</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2016/Refactor_and_write_unit_tests_for_question_type.rb&amp;diff=101725</id>
		<title>CSC/ECE 517 Spring 2016/Refactor and write unit tests for question type.rb</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2016/Refactor_and_write_unit_tests_for_question_type.rb&amp;diff=101725"/>
		<updated>2016-04-03T20:03:03Z</updated>

		<summary type="html">&lt;p&gt;Hguan2: /* Unit-tests */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This wiki page is for the description of changes made under E1608 OSS assignment for Spring 2016, CSC/ECE 517. The assignment task is to  refactor &amp;amp; write unit tests for [question_type].rb (eg. criterion.rb).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Problem Statement ==&lt;br /&gt;
===Files related===&lt;br /&gt;
Four models is related: criterion.rb, scale.rb, checkbox.rb, questionnaire_header.rb, upload_file.rb. There are 4 methods “edit”, “view_question_text”, “complete” and “view_completed_question” correspond to different views. &lt;br /&gt;
&lt;br /&gt;
*edit ~&amp;gt;	when instructor add/edit new questions&lt;br /&gt;
*view ~&amp;gt; when instructor view existed questions&lt;br /&gt;
*complete ~&amp;gt; when students do peer reviews&lt;br /&gt;
*view_completed_question ~&amp;gt; when student view existed peer reviews&lt;br /&gt;
&lt;br /&gt;
===Expertiza question types inheritance hierarchy===&lt;br /&gt;
&lt;br /&gt;
*Choice question&lt;br /&gt;
**Scored question&lt;br /&gt;
***Scale&lt;br /&gt;
***Criterion&lt;br /&gt;
**Unscored question&lt;br /&gt;
***Dropdown&lt;br /&gt;
***CheckBox&lt;br /&gt;
*TextResponse&lt;br /&gt;
**TextArea&lt;br /&gt;
**TextField&lt;br /&gt;
*UploadFile&lt;br /&gt;
&lt;br /&gt;
===Files problem===&lt;br /&gt;
&lt;br /&gt;
There are some issues in each file, such as security, complexity, duplication, etc. And currently there is no unit tests for [question_type].rb.&lt;br /&gt;
&lt;br /&gt;
===Our contribution===&lt;br /&gt;
*Refactor these [question_type].rb files and fix issues.&lt;br /&gt;
*Keep the inputs and outputs of these methods (edit, view, complete, view_completed_question) the same as before.&lt;br /&gt;
*Write unit tests for [question_type].rb listed above.&lt;br /&gt;
*Create RSpec files for each question type in /spec/models/ folder&lt;br /&gt;
*Create multiple tests to check valid and invalid cases, such as input including special character double quote (“”).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
==Refactor==&lt;br /&gt;
===Criterion.rb===&lt;br /&gt;
* Method has too many lines: Line 35 - 158 [106/30]&lt;br /&gt;
Wrap the specific code into different instance methods. &lt;br /&gt;
* Cyclomatic complexity for complete is too high: Line 35 - 158 [28/6]&lt;br /&gt;
Wrap the code into different instance methods to reduce cyclomatic complexity&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 def complete(count, answer=nil, questionnaire_min, questionnaire_max, dropdown_or_scale)&lt;br /&gt;
    if self.size.nil?&lt;br /&gt;
      cols = '70'&lt;br /&gt;
      rows = '1'&lt;br /&gt;
    else&lt;br /&gt;
      cols = self.size.split(',')[0]&lt;br /&gt;
      rows = self.size.split(',')[1]&lt;br /&gt;
    end&lt;br /&gt;
    html = '&amp;lt;li&amp;gt;&amp;lt;div&amp;gt;&amp;lt;label for=&amp;quot;responses_' +count.to_s+ '&amp;quot;&amp;gt;' +self.txt+ &amp;quot;&amp;lt;/label&amp;gt;&amp;lt;/div&amp;gt;&amp;quot;&lt;br /&gt;
    #show advice for each criterion question&lt;br /&gt;
    question_advices = QuestionAdvice.where(question_id: self.id).sort_by { |advice| advice.id }&lt;br /&gt;
    advice_total_length = 0&lt;br /&gt;
    question_advices.each do |question_advice|&lt;br /&gt;
      if question_advice.advice &amp;amp;&amp;amp; !question_advice.advice == &amp;quot;&amp;quot;&lt;br /&gt;
        advice_total_length += question_advice.advice.length&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
    if question_advices.length &amp;gt; 0 and advice_total_length &amp;gt; 0&lt;br /&gt;
       html = complete_show_advice(self, html)&lt;br /&gt;
    question_advices.reverse.each_with_index do |question_advice, index|&lt;br /&gt;
        html += '&amp;lt;a id=&amp;quot;changeScore_&amp;gt;' + self.id.to_s + '&amp;quot; onclick=&amp;quot;changeScore(' + count.to_s + ',' + index.to_s + ')&amp;quot;&amp;gt;'&lt;br /&gt;
        html += (question_advices.length - index).to_s + ' - ' + question_advice.advice + '&amp;lt;/a&amp;gt;&amp;lt;br/&amp;gt;'&lt;br /&gt;
        html += '&amp;lt;script&amp;gt;'&lt;br /&gt;
        html += 'function changeScore(i, j) {'&lt;br /&gt;
        html += 'var elem = jQuery(&amp;quot;#responses_&amp;quot; + i.toString() + &amp;quot;_score&amp;quot;);'&lt;br /&gt;
        html += 'var opts = elem.children(&amp;quot;option&amp;quot;).length;'&lt;br /&gt;
        html += 'elem.val((opts - j - 1).toString());}'&lt;br /&gt;
        html += '&amp;lt;/script&amp;gt;'&lt;br /&gt;
      end&lt;br /&gt;
      html += '&amp;lt;/div&amp;gt;'&lt;br /&gt;
    end&lt;br /&gt;
    if dropdown_or_scale == 'dropdown'&lt;br /&gt;
      ## code added  to reduce Cyclomatic Complexity&lt;br /&gt;
      html = complete_drop_down(self, html, count, answer, questionnaire_min, questionnaire_max)&lt;br /&gt;
    elsif dropdown_or_scale == 'scale'&lt;br /&gt;
       html = complete_scale(self, html, count, answer, questionnaire_min, questionnaire_max)&lt;br /&gt;
    end&lt;br /&gt;
    html.html_safe&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
* Identical code found in 1 other location: Line 20 - 32 (mass = 89)&lt;br /&gt;
Also found in   app/models/scale.rb:17…28. The following method is removed from subclass: criterion and added to their superclass: scaled_question&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def view_question_text&lt;br /&gt;
    html = '&amp;lt;TR&amp;gt;&amp;lt;TD align=&amp;quot;left&amp;quot;&amp;gt; '+self.txt+' &amp;lt;/TD&amp;gt;'&lt;br /&gt;
    html += '&amp;lt;TD align=&amp;quot;left&amp;quot;&amp;gt;'+self.type+'&amp;lt;/TD&amp;gt;'&lt;br /&gt;
    html += '&amp;lt;td align=&amp;quot;center&amp;quot;&amp;gt;'+self.weight.to_s+'&amp;lt;/TD&amp;gt;'&lt;br /&gt;
    questionnaire = self.questionnaire&lt;br /&gt;
    if !self.max_label.nil? &amp;amp;&amp;amp; !self.min_label.nil?&lt;br /&gt;
      html += '&amp;lt;TD align=&amp;quot;center&amp;quot;&amp;gt; ('+self.min_label+') '+questionnaire.min_question_score.to_s+' to '+ questionnaire.max_question_score.to_s + ' ('+self.max_label+')&amp;lt;/TD&amp;gt;'&lt;br /&gt;
    else&lt;br /&gt;
      html += '&amp;lt;TD align=&amp;quot;center&amp;quot;&amp;gt;'+questionnaire.min_question_score.to_s+' to '+ questionnaire.max_question_score.to_s + '&amp;lt;/TD&amp;gt;'&lt;br /&gt;
    end&lt;br /&gt;
    html += '&amp;lt;/TR&amp;gt;'&lt;br /&gt;
    Html.html_safe&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
* Identical code found in 1 other location: Line 135 - 139 (mass = 50)&lt;br /&gt;
Also found in  app/models/scale.rb:50…54. Wrap the duplicated code into an instance method and add the instance method into superclass: scaled_question&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# add the following functions to refactor duplicates.&lt;br /&gt;
  def complete_questionnaire_min_to_questionnaire_max(ob, html, answer, questionnaire_min, questionnaire_max)&lt;br /&gt;
    for j in questionnaire_min..questionnaire_max&lt;br /&gt;
      html += '&amp;lt;td width=&amp;quot;10%&amp;quot;&amp;gt;&amp;lt;input type=&amp;quot;radio&amp;quot; id=&amp;quot;' +j.to_s+ '&amp;quot; value=&amp;quot;' +j.to_s+ '&amp;quot; name=&amp;quot;Radio_' +ob.id.to_s+ '&amp;quot;'&lt;br /&gt;
      html += 'checked=&amp;quot;checked&amp;quot;' if (!answer.nil? and answer.answer == j) or (answer.nil? and questionnaire_min == j)&lt;br /&gt;
      html += '&amp;gt;&amp;lt;/td&amp;gt;'&lt;br /&gt;
    end&lt;br /&gt;
    return html&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
* Identical code found in 1 other location Line 13 - 14 (mass = 40)&lt;br /&gt;
Also found in  app/models/scale.rb:10…11. Wrap the duplicated code into an instance method and add the instance method into superclass: scaled_question&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# add the following functions to refactor duplicates.  &lt;br /&gt;
def edit_end(ob, html)&lt;br /&gt;
    html+='&amp;lt;td&amp;gt; max_label &amp;lt;input size=&amp;quot;4&amp;quot; value=&amp;quot;'+ob.max_label.to_s+'&amp;quot; name=&amp;quot;question['+ob.id.to_s+'][max_label]&amp;quot; id=&amp;quot;question_'+ob.id.to_s+'_max_label&amp;quot; type=&amp;quot;text&amp;quot;&amp;gt;  min_label &amp;lt;input size=&amp;quot;4&amp;quot; value=&amp;quot;'+ob.min_label.to_s+'&amp;quot; name=&amp;quot;question['+ob.id.to_s+'][min_label]&amp;quot; id=&amp;quot;question_'+ob.id.to_s+'_min_label&amp;quot; type=&amp;quot;text&amp;quot;&amp;gt;&amp;lt;/td&amp;gt;'&lt;br /&gt;
    html+='&amp;lt;/tr&amp;gt;'&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
* Similar code found in 1 other location Line 103 - 105 (mass = 26)&lt;br /&gt;
Also found in   app/models/criterion.rb:107…110. Wrap the duplicated code into an instance method&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def complete_drop_down_label_config(html, label)&lt;br /&gt;
    html += j.to_s&lt;br /&gt;
    html += &amp;quot;-&amp;quot; + label if label &amp;amp;&amp;amp; label.length&amp;gt;0&lt;br /&gt;
    html += &amp;quot;&amp;lt;/option&amp;gt;&amp;quot;&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
* Similar code found in 2 other locations Line 152 - 153 (mass = 22)&lt;br /&gt;
 Also found in   app/models/criterion.rb:115…116, app/models/text_area.rb:12…13. Wrap the duplicated code into an instance method&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def complete_answer_comment(count, html, answer)&lt;br /&gt;
    html += '&amp;lt;textarea cols=' +cols+ ' rows=' +rows+ ' id=&amp;quot;responses_' +count.to_s+ '_comments&amp;quot; name=&amp;quot;responses[' +count.to_s+ '][comment]&amp;quot; style=&amp;quot;overflow:hidden;&amp;quot;&amp;gt;'&lt;br /&gt;
    html += answer.comments if !answer.nil?&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
* Similar code found in 3 other locations: Line 130 - 134 (mass = 18)&lt;br /&gt;
Also found in app/models/criterion.rb:145…149, app/models/scale.rb:45…49, app/models/scale.rb:60…64.&lt;br /&gt;
Wrap the duplicated code into an instance method and add the instance method into superclass: scaled_question&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# add the following functions to refactor duplicates.  &lt;br /&gt;
  def complete_label(label, html)&lt;br /&gt;
    if !label.nil?&lt;br /&gt;
      html += '&amp;lt;td width=&amp;quot;10%&amp;quot;&amp;gt;' +label+ '&amp;lt;/td&amp;gt;'&lt;br /&gt;
    else&lt;br /&gt;
      html += '&amp;lt;td width=&amp;quot;10%&amp;quot;&amp;gt;&amp;lt;/td&amp;gt;'&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Scale.rb===&lt;br /&gt;
* Cyclomatic complexity for complete is too high. Method has too many lines&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def complete(count, answer=nil, questionnaire_min, questionnaire_max)&lt;br /&gt;
  	html = self.txt + '&amp;lt;br&amp;gt;'&lt;br /&gt;
    html += '&amp;lt;input id=&amp;quot;responses_' +count.to_s+ '_score&amp;quot; name=&amp;quot;responses[' +count.to_s+ '][score]&amp;quot; type=&amp;quot;hidden&amp;quot;'&lt;br /&gt;
    html += 'value=&amp;quot;'+answer.answer.to_s+'&amp;quot;' if !answer.nil?&lt;br /&gt;
    html += '&amp;gt;'&lt;br /&gt;
    html += '&amp;lt;input id=&amp;quot;responses_' +count.to_s+ '_comments&amp;quot; name=&amp;quot;responses[' +count.to_s+ '][comment]&amp;quot; type=&amp;quot;hidden&amp;quot; value=&amp;quot;&amp;quot;&amp;gt;'&lt;br /&gt;
&lt;br /&gt;
    html += '&amp;lt;table&amp;gt;'&lt;br /&gt;
    html += '&amp;lt;tr&amp;gt;&amp;lt;td width=&amp;quot;10%&amp;quot;&amp;gt;&amp;lt;/td&amp;gt;'&lt;br /&gt;
    for j in questionnaire_min..questionnaire_max&lt;br /&gt;
      html += '&amp;lt;td width=&amp;quot;10%&amp;quot;&amp;gt;&amp;lt;label&amp;gt;' +j.to_s+ '&amp;lt;/label&amp;gt;&amp;lt;/td&amp;gt;'&lt;br /&gt;
    end&lt;br /&gt;
    html += '&amp;lt;td width=&amp;quot;10%&amp;quot;&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;tr&amp;gt;'&lt;br /&gt;
&lt;br /&gt;
    html = complete_label(self.min_label, html)&lt;br /&gt;
    html = complete_questionnaire_min_to_questionnaire_max(self, html, answer, questionnaire_min, questionnaire_max)&lt;br /&gt;
&lt;br /&gt;
    html += '&amp;lt;script&amp;gt;jQuery(&amp;quot;input[name=Radio_' +self.id.to_s+ ']:radio&amp;quot;).change(function() {'&lt;br /&gt;
    html += 'var response_score = jQuery(&amp;quot;#responses_' +count.to_s+ '_score&amp;quot;);'&lt;br /&gt;
    html += 'var checked_value = jQuery(&amp;quot;input[name=Radio_' +self.id.to_s+ ']:checked&amp;quot;).val();'&lt;br /&gt;
    html += 'response_score.val(checked_value);});&amp;lt;/script&amp;gt;'&lt;br /&gt;
    html = complete_label(self.max_label, html)&lt;br /&gt;
&lt;br /&gt;
    html += '&amp;lt;td width=&amp;quot;10%&amp;quot;&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;/table&amp;gt;'&lt;br /&gt;
    html.html_safe&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
* Identical code found in 1 other location: line 17-28&lt;br /&gt;
app/models/criterion.rb:20…32, def view_question_text.&lt;br /&gt;
The following method is removed from subclass: scale and added to their superclass: scaled_question.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#This method returns what to display if an instructor (etc.) is viewing a questionnaire&lt;br /&gt;
  def view_question_text&lt;br /&gt;
    html = '&amp;lt;TR&amp;gt;&amp;lt;TD align=&amp;quot;left&amp;quot;&amp;gt; '+self.txt+' &amp;lt;/TD&amp;gt;'&lt;br /&gt;
    html += '&amp;lt;TD align=&amp;quot;left&amp;quot;&amp;gt;'+self.type+'&amp;lt;/TD&amp;gt;'&lt;br /&gt;
    html += '&amp;lt;td align=&amp;quot;center&amp;quot;&amp;gt;'+self.weight.to_s+'&amp;lt;/TD&amp;gt;'&lt;br /&gt;
    questionnaire = self.questionnaire&lt;br /&gt;
    if !self.max_label.nil? &amp;amp;&amp;amp; !self.min_label.nil?&lt;br /&gt;
      html += '&amp;lt;TD align=&amp;quot;center&amp;quot;&amp;gt; ('+self.min_label+') '+questionnaire.min_question_score.to_s+' to '+ questionnaire.max_question_score.to_s + ' ('+self.max_label+')&amp;lt;/TD&amp;gt;'&lt;br /&gt;
    else&lt;br /&gt;
      html += '&amp;lt;TD align=&amp;quot;center&amp;quot;&amp;gt;'+questionnaire.min_question_score.to_s+' to '+ questionnaire.max_question_score.to_s + '&amp;lt;/TD&amp;gt;'&lt;br /&gt;
    end&lt;br /&gt;
    html += '&amp;lt;/TR&amp;gt;'&lt;br /&gt;
    html.html_safe&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
* Identical code  found in 1 other location: line 50-54&lt;br /&gt;
app/models/criterion.rb:135…139. Wrap the duplicated code into an instance method and add the instance method into superclass: scaled_question.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  # add the following functions to refactor duplicates.&lt;br /&gt;
  def complete_questionnaire_min_to_questionnaire_max(ob, html, answer, questionnaire_min, questionnaire_max)&lt;br /&gt;
    for j in questionnaire_min..questionnaire_max&lt;br /&gt;
      html += '&amp;lt;td width=&amp;quot;10%&amp;quot;&amp;gt;&amp;lt;input type=&amp;quot;radio&amp;quot; id=&amp;quot;' +j.to_s+ '&amp;quot; value=&amp;quot;' +j.to_s+ '&amp;quot; name=&amp;quot;Radio_' +ob.id.to_s+ '&amp;quot;'&lt;br /&gt;
      html += 'checked=&amp;quot;checked&amp;quot;' if (!answer.nil? and answer.answer == j) or (answer.nil? and questionnaire_min == j)&lt;br /&gt;
      html += '&amp;gt;&amp;lt;/td&amp;gt;'&lt;br /&gt;
    end&lt;br /&gt;
    return html&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
* Identical code found in 1 other location: line 10-11&lt;br /&gt;
app/models/criterion.rb:13…14. Wrap the duplicated code into an instance method and add the instance method into superclass: scaled_question&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# add the following functions to refactor duplicates.  &lt;br /&gt;
def edit_end(ob, html)&lt;br /&gt;
    html+='&amp;lt;td&amp;gt; max_label &amp;lt;input size=&amp;quot;4&amp;quot; value=&amp;quot;'+ob.max_label.to_s+'&amp;quot; name=&amp;quot;question['+ob.id.to_s+'][max_label]&amp;quot; id=&amp;quot;question_'+ob.id.to_s+'_max_label&amp;quot; type=&amp;quot;text&amp;quot;&amp;gt;  min_label &amp;lt;input size=&amp;quot;4&amp;quot; value=&amp;quot;'+ob.min_label.to_s+'&amp;quot; name=&amp;quot;question['+ob.id.to_s+'][min_label]&amp;quot; id=&amp;quot;question_'+ob.id.to_s+'_min_label&amp;quot; type=&amp;quot;text&amp;quot;&amp;gt;&amp;lt;/td&amp;gt;'&lt;br /&gt;
    html+='&amp;lt;/tr&amp;gt;'&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
* Similar code found in 3 other locations: line 60-64&lt;br /&gt;
app/models/criterion.rb:130…134, app/models/criterion.rb:145…149, app/models/scale.rb:45…49. &lt;br /&gt;
Wrap the duplicated code into an instance method and add the instance method into superclass: scaled_question&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# add the following functions to refactor duplicates.  &lt;br /&gt;
  def complete_label(label, html)&lt;br /&gt;
    if !label.nil?&lt;br /&gt;
      html += '&amp;lt;td width=&amp;quot;10%&amp;quot;&amp;gt;' +label+ '&amp;lt;/td&amp;gt;'&lt;br /&gt;
    else&lt;br /&gt;
      html += '&amp;lt;td width=&amp;quot;10%&amp;quot;&amp;gt;&amp;lt;/td&amp;gt;'&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Checkbox.rb===&lt;br /&gt;
* Method has too many lines.&lt;br /&gt;
By moving codes to private methods outside this method, this problem can be fixed together with the following one. Here is the new complete method together with two additional private methods: hasAnswer(html, answer) and nextQuestionTail(html, next_question). The source codes are listed as below.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def complete(count, answer=nil)&lt;br /&gt;
    curr_question = Question.find(self.id)&lt;br /&gt;
    prev_question = Question.where(&amp;quot;seq &amp;lt; ?&amp;quot;, curr_question.seq).order(:seq).last&lt;br /&gt;
    next_question = Question.where(&amp;quot;seq &amp;gt; ?&amp;quot;, curr_question.seq).order(:seq).first&lt;br /&gt;
    html = ''&lt;br /&gt;
    if prev_question.type == 'ColumnHeader'&lt;br /&gt;
      html = '&amp;lt;td style=&amp;quot;padding: 15px;&amp;quot;&amp;gt;'&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    html += '&amp;lt;input id=&amp;quot;responses_' +count.to_s+ '_comments&amp;quot; name=&amp;quot;responses[' +count.to_s+ '][comment]&amp;quot; type=&amp;quot;hidden&amp;quot; value=&amp;quot;&amp;quot;&amp;gt;'&lt;br /&gt;
    html += '&amp;lt;input id=&amp;quot;responses_' +count.to_s+ '_score&amp;quot; name=&amp;quot;responses[' +count.to_s+ '][score]&amp;quot; type=&amp;quot;hidden&amp;quot;'&lt;br /&gt;
    html += hasAnswer(html , answer)&lt;br /&gt;
    html += '&amp;gt;'&lt;br /&gt;
    html += '&amp;lt;input id=&amp;quot;responses_' +count.to_s+ '_checkbox&amp;quot; type=&amp;quot;checkbox&amp;quot; onchange=&amp;quot;checkbox' +count.to_s+ 'Changed()&amp;quot;'&lt;br /&gt;
    html += 'checked=&amp;quot;checked&amp;quot;' if !answer.nil? and answer.answer == 1&lt;br /&gt;
    html += '&amp;gt;'&lt;br /&gt;
    html += '&amp;lt;label for=&amp;quot;responses_' +count.to_s+ '&amp;quot;&amp;gt;' +self.txt+ '&amp;lt;/label&amp;gt;'&lt;br /&gt;
&lt;br /&gt;
    html += '&amp;lt;script&amp;gt;function checkbox' +count.to_s+ 'Changed() {'&lt;br /&gt;
    html += ' var checkbox = jQuery(&amp;quot;#responses_' +count.to_s+ '_checkbox&amp;quot;);'&lt;br /&gt;
    html += ' var response_score = jQuery(&amp;quot;#responses_' +count.to_s+ '_score&amp;quot;);'&lt;br /&gt;
    html += 'if (checkbox.is(&amp;quot;:checked&amp;quot;)) {'&lt;br /&gt;
    html += 'response_score.val(&amp;quot;1&amp;quot;);'&lt;br /&gt;
    html += '} else {'&lt;br /&gt;
    html += 'response_score.val(&amp;quot;0&amp;quot;);}}&amp;lt;/script&amp;gt;'&lt;br /&gt;
&lt;br /&gt;
    html = nextQuestionTail(html, next_question)&lt;br /&gt;
    html.html_safe&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  #YJ private for complete()&lt;br /&gt;
  def hasAnswer(html, answer)&lt;br /&gt;
    if !answer.nil? and answer.answer == 1&lt;br /&gt;
      html += 'value=&amp;quot;1&amp;quot;'&lt;br /&gt;
    else&lt;br /&gt;
      html += 'value=&amp;quot;0&amp;quot;'&lt;br /&gt;
    end&lt;br /&gt;
    return html&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def nextQuestionTail(html, next_q)&lt;br /&gt;
    if next_question.type == 'ColumnHeader'&lt;br /&gt;
      html += '&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;'&lt;br /&gt;
    elsif next_question.type == 'SectionHeader' or next_question.type == 'TableHeader'&lt;br /&gt;
      html += '&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;/table&amp;gt;&amp;lt;br/&amp;gt;'&lt;br /&gt;
    else&lt;br /&gt;
      html += '&amp;lt;BR/&amp;gt;'&lt;br /&gt;
    end&lt;br /&gt;
    return html&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
* Cyclomatic complexity for complete is too high.&lt;br /&gt;
This problem can be solved by moving branches outside to other private methods. See source code above.&lt;br /&gt;
* Similar codes in edit method are found in 2 other locations.&lt;br /&gt;
(questionnaire_header.rb and upload_file.rb)&lt;br /&gt;
Such code duplication can be eliminated by moving the identical part of the similar edit method to a new function, named edit_prefix(html, count) to their common superclass, which is Question (question.rb).&lt;br /&gt;
Here is the source code of the added edit_prefix method in question.rb:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 def edit_prefix(self, html)&lt;br /&gt;
    html ='&amp;lt;tr&amp;gt;'&lt;br /&gt;
    html+='&amp;lt;td align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;a rel=&amp;quot;nofollow&amp;quot; data-method=&amp;quot;delete&amp;quot; href=&amp;quot;/questions/' +ob.id.to_s+ '&amp;quot;&amp;gt;Remove&amp;lt;/a&amp;gt;&amp;lt;/td&amp;gt;'&lt;br /&gt;
    html+='&amp;lt;td&amp;gt;&amp;lt;input size=&amp;quot;6&amp;quot; value=&amp;quot;'+ob.seq.to_s+'&amp;quot; name=&amp;quot;question['+ob.id.to_s+'][seq]&amp;quot; id=&amp;quot;question_'+ob.id.to_s+'_seq&amp;quot; type=&amp;quot;text&amp;quot;&amp;gt;&amp;lt;/td&amp;gt;'&lt;br /&gt;
    html+='&amp;lt;td&amp;gt;&amp;lt;textarea cols=&amp;quot;50&amp;quot; rows=&amp;quot;1&amp;quot; name=&amp;quot;question['+ob.id.to_s+'][txt]&amp;quot; id=&amp;quot;question_'+ob.id.to_s+'_txt&amp;quot;&amp;gt;'+ob.txt+'&amp;lt;/textarea&amp;gt;&amp;lt;/td&amp;gt;'&lt;br /&gt;
    html+='&amp;lt;td&amp;gt;&amp;lt;input size=&amp;quot;10&amp;quot; disabled=&amp;quot;disabled&amp;quot; value=&amp;quot;'+ob.type+'&amp;quot; name=&amp;quot;question['+ob.id.to_s+'][type]&amp;quot; id=&amp;quot;question_'+ob.id.to_s+'_type&amp;quot; type=&amp;quot;text&amp;quot;&amp;gt;''&amp;lt;/td&amp;gt;'&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
The original code are commented out and insert the function call of the above function, html will be returned in the above function, see codes below:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def edit(count)&lt;br /&gt;
    html = edit_prefix(self, html)&lt;br /&gt;
    html+='&amp;lt;td&amp;gt;&amp;lt;!--placeholder (UnscoredQuestion does not need weight)--&amp;gt;&amp;lt;/td&amp;gt;'&lt;br /&gt;
    html+='&amp;lt;/tr&amp;gt;'&lt;br /&gt;
    html.html_safe&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
* Similar codes in view_question_text method are found in 4 other locations.&lt;br /&gt;
(dropdown.rb, questionnaire_header.rb, text_response.rb, upload_file.rb)&lt;br /&gt;
The solution to this problem is the same as above one, below is the function added in the most common superclass, which is Question, that contains the common parts of the codes found in the view_question_text methods in all five classes.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def view_qt_prefix(ob, html)&lt;br /&gt;
    html = '&amp;lt;TR&amp;gt;&amp;lt;TD align=&amp;quot;left&amp;quot;&amp;gt; '+ob.txt+ ' &amp;lt;/TD&amp;gt;'&lt;br /&gt;
    html += '&amp;lt;TD align=&amp;quot;left&amp;quot;&amp;gt;'+ob.type+'&amp;lt;/TD&amp;gt;'&lt;br /&gt;
    html += '&amp;lt;td align=&amp;quot;center&amp;quot;&amp;gt;'+ob.weight.to_s+'&amp;lt;/TD&amp;gt;'&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
The original code are commented out and insert the function call of the above function, html will be returned in the above function, see codes below:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def view_question_text&lt;br /&gt;
    html = view_qt_prefix(ob, html)&lt;br /&gt;
    html += '&amp;lt;TD align=&amp;quot;center&amp;quot;&amp;gt;Checked/Unchecked&amp;lt;/TD&amp;gt;'&lt;br /&gt;
    html += '&amp;lt;/TR&amp;gt;'&lt;br /&gt;
    html.html_safe&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Questionnaire_header.rb===&lt;br /&gt;
All problems in this file are solved after solving the problems found in checkbox.rb.&lt;br /&gt;
&lt;br /&gt;
===Upload_file.rb===&lt;br /&gt;
All problems in this file are solved after solving the problems found in checkbox.rb.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Unit-tests==&lt;br /&gt;
One contribution is to write unite test for four question types. For each of the four required four question types: &lt;br /&gt;
*criterion.rb,&lt;br /&gt;
*scale.rb,&lt;br /&gt;
*checkbox.rb,&lt;br /&gt;
*upload_file.rb,&lt;br /&gt;
there are four unit tests for the following four functions: &lt;br /&gt;
*''edit'', &lt;br /&gt;
*''complete'', &lt;br /&gt;
*''view_question_text'', &lt;br /&gt;
*''view_complete_question_text''. &lt;br /&gt;
&lt;br /&gt;
These four functions are tested since they are these are the only methods that the question types class can perform. &lt;br /&gt;
&lt;br /&gt;
The output of those four functions are HTML format string. We test if the output string is matched with the expected given certain conditions. Here are the spec files git hub links:&lt;br /&gt;
*[https://github.com/schen35/expertiza/blob/master/spec/models/criterion_spec.rb criterion_spec.rb] &lt;br /&gt;
*[https://github.com/schen35/expertiza/blob/master/spec/models/scale_spec.rb scale_spec.rb] &lt;br /&gt;
*[https://github.com/schen35/expertiza/blob/master/spec/models/checkbox_spec.rb checkbox_spec.rb] &lt;br /&gt;
*[https://github.com/schen35/expertiza/blob/master/spec/models/upload_file_spec.rb upload_file_spec.rb].&lt;/div&gt;</summary>
		<author><name>Hguan2</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=User_talk:Yjin6&amp;diff=101585</id>
		<title>User talk:Yjin6</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=User_talk:Yjin6&amp;diff=101585"/>
		<updated>2016-04-01T19:42:38Z</updated>

		<summary type="html">&lt;p&gt;Hguan2: /* Unit-tests */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This wiki page is for the description of changes made under E1624 OSS assignment for Spring 2016, CSC/ECE 517. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Problem Statement ==&lt;br /&gt;
&lt;br /&gt;
===What it does===&lt;br /&gt;
Suggested topic functionality is designed for students to suggest topics they interested in. An assignment can be set up to allow students to suggest topics at the discretion of the instructor. Then, students can suggest topics, and add related descriptions. The proposer can state that (s)he wants to work on the suggested topic.  When the instructor approves a suggested topic, if the proposer wanted to work on it, it is assigned to the proposer. Otherwise, it is placed on the signup sheet for anyone to reserve. The purpose of suggested topic is to make the writing assignment more personalized.&lt;br /&gt;
===What’s wrong with it===&lt;br /&gt;
Currently, there is no functional test for calibration function.&lt;br /&gt;
===What needs to be done===&lt;br /&gt;
*Understand the flow of the suggested topic function.&lt;br /&gt;
*Do not use the development DB, otherwise your tests will not pass on TravisCI.&lt;br /&gt;
*Create RSpec file in /spec/features/ folder.&lt;br /&gt;
*Use fixtures to create the assignment record  and any other records such as participant records in test DB.  &lt;br /&gt;
*Use Capybara to write functional tests for these three scenarios.&lt;br /&gt;
**One team is on the waitlist. They sent a suggestion for new topic and they want to choose their suggested topic. After their suggested topic is approved, they should leave the waitlist and hold their suggested topic;&lt;br /&gt;
**One team is holding a topic. They sent a suggestion for new topic and they want to choose their suggested topic. After their suggested topic is approved and they choose to switch to suggested topic, they will hold suggested topic and their old topic will be released. And if another team is in waitlist of that old topic, that team should hold the old topic now;&lt;br /&gt;
**One team is holding a topic. They sent a suggestion for new topic and they do not want to work on their suggested topic. After their suggested topic is approved and they choose to public suggested topic, they will still hold their old topic. Their suggested topic will be added in sign-up sheet.&lt;br /&gt;
*Create multiple tests to check valid and invalid cases.&lt;/div&gt;</summary>
		<author><name>Hguan2</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=User_talk:Yjin6&amp;diff=101584</id>
		<title>User talk:Yjin6</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=User_talk:Yjin6&amp;diff=101584"/>
		<updated>2016-04-01T19:42:22Z</updated>

		<summary type="html">&lt;p&gt;Hguan2: /* What needs to be done */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This wiki page is for the description of changes made under E1624 OSS assignment for Spring 2016, CSC/ECE 517. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Problem Statement ==&lt;br /&gt;
&lt;br /&gt;
===What it does===&lt;br /&gt;
Suggested topic functionality is designed for students to suggest topics they interested in. An assignment can be set up to allow students to suggest topics at the discretion of the instructor. Then, students can suggest topics, and add related descriptions. The proposer can state that (s)he wants to work on the suggested topic.  When the instructor approves a suggested topic, if the proposer wanted to work on it, it is assigned to the proposer. Otherwise, it is placed on the signup sheet for anyone to reserve. The purpose of suggested topic is to make the writing assignment more personalized.&lt;br /&gt;
===What’s wrong with it===&lt;br /&gt;
Currently, there is no functional test for calibration function.&lt;br /&gt;
===What needs to be done===&lt;br /&gt;
*Understand the flow of the suggested topic function.&lt;br /&gt;
*Do not use the development DB, otherwise your tests will not pass on TravisCI.&lt;br /&gt;
*Create RSpec file in /spec/features/ folder.&lt;br /&gt;
*Use fixtures to create the assignment record  and any other records such as participant records in test DB.  &lt;br /&gt;
*Use Capybara to write functional tests for these three scenarios.&lt;br /&gt;
**One team is on the waitlist. They sent a suggestion for new topic and they want to choose their suggested topic. After their suggested topic is approved, they should leave the waitlist and hold their suggested topic;&lt;br /&gt;
**One team is holding a topic. They sent a suggestion for new topic and they want to choose their suggested topic. After their suggested topic is approved and they choose to switch to suggested topic, they will hold suggested topic and their old topic will be released. And if another team is in waitlist of that old topic, that team should hold the old topic now;&lt;br /&gt;
**One team is holding a topic. They sent a suggestion for new topic and they do not want to work on their suggested topic. After their suggested topic is approved and they choose to public suggested topic, they will still hold their old topic. Their suggested topic will be added in sign-up sheet.&lt;br /&gt;
*Create multiple tests to check valid and invalid cases.&lt;br /&gt;
&lt;br /&gt;
==Unit-tests==&lt;/div&gt;</summary>
		<author><name>Hguan2</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=User_talk:Yjin6&amp;diff=101583</id>
		<title>User talk:Yjin6</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=User_talk:Yjin6&amp;diff=101583"/>
		<updated>2016-04-01T19:40:13Z</updated>

		<summary type="html">&lt;p&gt;Hguan2: /* What needs to be done */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This wiki page is for the description of changes made under E1624 OSS assignment for Spring 2016, CSC/ECE 517. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Problem Statement ==&lt;br /&gt;
&lt;br /&gt;
===What it does===&lt;br /&gt;
Suggested topic functionality is designed for students to suggest topics they interested in. An assignment can be set up to allow students to suggest topics at the discretion of the instructor. Then, students can suggest topics, and add related descriptions. The proposer can state that (s)he wants to work on the suggested topic.  When the instructor approves a suggested topic, if the proposer wanted to work on it, it is assigned to the proposer. Otherwise, it is placed on the signup sheet for anyone to reserve. The purpose of suggested topic is to make the writing assignment more personalized.&lt;br /&gt;
===What’s wrong with it===&lt;br /&gt;
Currently, there is no functional test for calibration function.&lt;br /&gt;
===What needs to be done===&lt;br /&gt;
*Understand the flow of the suggested topic function.&lt;br /&gt;
*Do not use the development DB, otherwise your tests will not pass on TravisCI.&lt;br /&gt;
Create RSpec file in /spec/features/ folder.&lt;br /&gt;
Use fixtures to create the assignment record  and any other records such as participant records in test DB.  &lt;br /&gt;
Use Capybara to write functional tests for these three scenarios.&lt;br /&gt;
One team is on the waitlist. They sent a suggestion for new topic and they want to choose their suggested topic. After their suggested topic is approved, they should leave the waitlist and hold their suggested topic;&lt;br /&gt;
One team is holding a topic. They sent a suggestion for new topic and they want to choose their suggested topic. After their suggested topic is approved and they choose to switch to suggested topic, they will hold suggested topic and their old topic will be released. And if another team is in waitlist of that old topic, that team should hold the old topic now;&lt;br /&gt;
One team is holding a topic. They sent a suggestion for new topic and they do not want to work on their suggested topic. After their suggested topic is approved and they choose to public suggested topic, they will still hold their old topic. Their suggested topic will be added in sign-up sheet.&lt;br /&gt;
Create multiple tests to check valid and invalid cases.&lt;br /&gt;
&lt;br /&gt;
==Unit-tests==&lt;/div&gt;</summary>
		<author><name>Hguan2</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=User_talk:Yjin6&amp;diff=101582</id>
		<title>User talk:Yjin6</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=User_talk:Yjin6&amp;diff=101582"/>
		<updated>2016-04-01T19:38:52Z</updated>

		<summary type="html">&lt;p&gt;Hguan2: /* Problem Statement */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This wiki page is for the description of changes made under E1624 OSS assignment for Spring 2016, CSC/ECE 517. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Problem Statement ==&lt;br /&gt;
&lt;br /&gt;
===What it does===&lt;br /&gt;
Suggested topic functionality is designed for students to suggest topics they interested in. An assignment can be set up to allow students to suggest topics at the discretion of the instructor. Then, students can suggest topics, and add related descriptions. The proposer can state that (s)he wants to work on the suggested topic.  When the instructor approves a suggested topic, if the proposer wanted to work on it, it is assigned to the proposer. Otherwise, it is placed on the signup sheet for anyone to reserve. The purpose of suggested topic is to make the writing assignment more personalized.&lt;br /&gt;
===What’s wrong with it===&lt;br /&gt;
Currently, there is no functional test for calibration function.&lt;br /&gt;
===What needs to be done===&lt;br /&gt;
Understand the flow of the suggested topic function.&lt;br /&gt;
Do not use the development DB, otherwise your tests will not pass on TravisCI.&lt;br /&gt;
Create RSpec file in /spec/features/ folder.&lt;br /&gt;
Use fixtures to create the assignment record  and any other records such as participant records in test DB.  &lt;br /&gt;
Use Capybara to write functional tests for these three scenarios.&lt;br /&gt;
One team is on the waitlist. They sent a suggestion for new topic and they want to choose their suggested topic. After their suggested topic is approved, they should leave the waitlist and hold their suggested topic;&lt;br /&gt;
One team is holding a topic. They sent a suggestion for new topic and they want to choose their suggested topic. After their suggested topic is approved and they choose to switch to suggested topic, they will hold suggested topic and their old topic will be released. And if another team is in waitlist of that old topic, that team should hold the old topic now;&lt;br /&gt;
One team is holding a topic. They sent a suggestion for new topic and they do not want to work on their suggested topic. After their suggested topic is approved and they choose to public suggested topic, they will still hold their old topic. Their suggested topic will be added in sign-up sheet.&lt;br /&gt;
Create multiple tests to check valid and invalid cases.&lt;br /&gt;
&lt;br /&gt;
==Unit-tests==&lt;/div&gt;</summary>
		<author><name>Hguan2</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2016&amp;diff=101470</id>
		<title>CSC/ECE 517 Spring 2016</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2016&amp;diff=101470"/>
		<updated>2016-03-29T02:09:59Z</updated>

		<summary type="html">&lt;p&gt;Hguan2: /* Writing Assignment 2 */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Calibration Assignment Submissions==&lt;br /&gt;
*[[Calibration Assignment Submission (OmniAuth)]]&lt;br /&gt;
*[[Calibration Assignment Submission (Patch_verb)]]&lt;br /&gt;
&lt;br /&gt;
==Writing Assignment 2==&lt;br /&gt;
[[CSC/ECE 517 Spring 2016/Mozilla Implement HTML5 form validation]]&lt;br /&gt;
&lt;br /&gt;
[[CSC/ECE 517 Spring 2016/Functional Tests for Questionnaire Controller]]&lt;br /&gt;
&lt;br /&gt;
[[CSC/ECE 517 Spring 2016 / Expertiza Self-Review Feature]]&lt;br /&gt;
&lt;br /&gt;
[[CSC/ECE 517 Spring 2016/Refactor different question types from quiz feature]]&lt;br /&gt;
&lt;br /&gt;
[[CSC/ECE 517 Spring 2016/Implement private browsing]]&lt;br /&gt;
&lt;br /&gt;
[[CSC/ECE 517 Spring 2016/Write automated tests for WebDriver]]&lt;br /&gt;
&lt;br /&gt;
[[CSC/ECE 517 Spring 2016/Refactor sign_up_sheet_controller.rb and sign_up_topic.rb]]&lt;br /&gt;
&lt;br /&gt;
[[CSC/ECE 517 Spring 2016/Implement Common Parts of the CSSOM API]]&lt;br /&gt;
&lt;br /&gt;
[[CSC/ECE 517 Spring 2016/Functional tests for assignment creation function]]&lt;br /&gt;
&lt;br /&gt;
[[CSC/ECE 517 Spring 2016/E1604. Functional tests for Calibration function]]&lt;br /&gt;
&lt;br /&gt;
[[CSC/ECE 517 Spring 2016/Refactor and write unit tests for question type.rb]]&lt;/div&gt;</summary>
		<author><name>Hguan2</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=E1608:_Refactor_and_write_unit_tests_for_question_type.rb&amp;diff=101469</id>
		<title>E1608: Refactor and write unit tests for question type.rb</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=E1608:_Refactor_and_write_unit_tests_for_question_type.rb&amp;diff=101469"/>
		<updated>2016-03-29T02:09:01Z</updated>

		<summary type="html">&lt;p&gt;Hguan2: moved E1608: Refactor and write unit tests for question type.rb to CSC/ECE 517 Spring 2016/Refactor and write unit tests for question type.rb&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;#REDIRECT [[CSC/ECE 517 Spring 2016/Refactor and write unit tests for question type.rb]]&lt;/div&gt;</summary>
		<author><name>Hguan2</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2016/Refactor_and_write_unit_tests_for_question_type.rb&amp;diff=101468</id>
		<title>CSC/ECE 517 Spring 2016/Refactor and write unit tests for question type.rb</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2016/Refactor_and_write_unit_tests_for_question_type.rb&amp;diff=101468"/>
		<updated>2016-03-29T02:09:01Z</updated>

		<summary type="html">&lt;p&gt;Hguan2: moved E1608: Refactor and write unit tests for question type.rb to CSC/ECE 517 Spring 2016/Refactor and write unit tests for question type.rb&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This wiki page is for the description of changes made under E1608 OSS assignment for Spring 2016, CSC/ECE 517. The assignment task is to  refactor &amp;amp; write unit tests for [question_type].rb (eg. criterion.rb).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Problem Statement ==&lt;br /&gt;
===Files related===&lt;br /&gt;
Four models is related: criterion.rb, scale.rb, checkbox.rb, questionnaire_header.rb, upload_file.rb. There are 4 methods “edit”, “view_question_text”, “complete” and “view_completed_question” correspond to different views. &lt;br /&gt;
&lt;br /&gt;
*edit ~&amp;gt;	when instructor add/edit new questions&lt;br /&gt;
*view ~&amp;gt; when instructor view existed questions&lt;br /&gt;
*complete ~&amp;gt; when students do peer reviews&lt;br /&gt;
*view_completed_question ~&amp;gt; when student view existed peer reviews&lt;br /&gt;
&lt;br /&gt;
===Expertiza question types inheritance hierarchy===&lt;br /&gt;
&lt;br /&gt;
*Choice question&lt;br /&gt;
**Scored question&lt;br /&gt;
***Scale&lt;br /&gt;
***Criterion&lt;br /&gt;
**Unscored question&lt;br /&gt;
***Dropdown&lt;br /&gt;
***CheckBox&lt;br /&gt;
*TextResponse&lt;br /&gt;
**TextArea&lt;br /&gt;
**TextField&lt;br /&gt;
*UploadFile&lt;br /&gt;
&lt;br /&gt;
===Files problem===&lt;br /&gt;
&lt;br /&gt;
There are some issues in each file, such as security, complexity, duplication, etc. And currently there is no unit tests for [question_type].rb.&lt;br /&gt;
&lt;br /&gt;
===Our contribution===&lt;br /&gt;
*Refactor these [question_type].rb files and fix issues.&lt;br /&gt;
*Keep the inputs and outputs of these methods (edit, view, complete, view_completed_question) the same as before.&lt;br /&gt;
*Write unit tests for [question_type].rb listed above.&lt;br /&gt;
*Create RSpec files for each question type in /spec/models/ folder&lt;br /&gt;
*Create multiple tests to check valid and invalid cases, such as input including special character double quote (“”).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
==Refactor==&lt;br /&gt;
===Criterion.rb===&lt;br /&gt;
* Method has too many lines: Line 35 - 158 [106/30]&lt;br /&gt;
Wrap the specific code into different instance methods. &lt;br /&gt;
* Cyclomatic complexity for complete is too high: Line 35 - 158 [28/6]&lt;br /&gt;
Wrap the code into different instance methods to reduce cyclomatic complexity&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 def complete(count, answer=nil, questionnaire_min, questionnaire_max, dropdown_or_scale)&lt;br /&gt;
    if self.size.nil?&lt;br /&gt;
      cols = '70'&lt;br /&gt;
      rows = '1'&lt;br /&gt;
    else&lt;br /&gt;
      cols = self.size.split(',')[0]&lt;br /&gt;
      rows = self.size.split(',')[1]&lt;br /&gt;
    end&lt;br /&gt;
    html = '&amp;lt;li&amp;gt;&amp;lt;div&amp;gt;&amp;lt;label for=&amp;quot;responses_' +count.to_s+ '&amp;quot;&amp;gt;' +self.txt+ &amp;quot;&amp;lt;/label&amp;gt;&amp;lt;/div&amp;gt;&amp;quot;&lt;br /&gt;
    #show advice for each criterion question&lt;br /&gt;
    question_advices = QuestionAdvice.where(question_id: self.id).sort_by { |advice| advice.id }&lt;br /&gt;
    advice_total_length = 0&lt;br /&gt;
    question_advices.each do |question_advice|&lt;br /&gt;
      if question_advice.advice &amp;amp;&amp;amp; !question_advice.advice == &amp;quot;&amp;quot;&lt;br /&gt;
        advice_total_length += question_advice.advice.length&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
    if question_advices.length &amp;gt; 0 and advice_total_length &amp;gt; 0&lt;br /&gt;
       html = complete_show_advice(self, html)&lt;br /&gt;
    question_advices.reverse.each_with_index do |question_advice, index|&lt;br /&gt;
        html += '&amp;lt;a id=&amp;quot;changeScore_&amp;gt;' + self.id.to_s + '&amp;quot; onclick=&amp;quot;changeScore(' + count.to_s + ',' + index.to_s + ')&amp;quot;&amp;gt;'&lt;br /&gt;
        html += (question_advices.length - index).to_s + ' - ' + question_advice.advice + '&amp;lt;/a&amp;gt;&amp;lt;br/&amp;gt;'&lt;br /&gt;
        html += '&amp;lt;script&amp;gt;'&lt;br /&gt;
        html += 'function changeScore(i, j) {'&lt;br /&gt;
        html += 'var elem = jQuery(&amp;quot;#responses_&amp;quot; + i.toString() + &amp;quot;_score&amp;quot;);'&lt;br /&gt;
        html += 'var opts = elem.children(&amp;quot;option&amp;quot;).length;'&lt;br /&gt;
        html += 'elem.val((opts - j - 1).toString());}'&lt;br /&gt;
        html += '&amp;lt;/script&amp;gt;'&lt;br /&gt;
      end&lt;br /&gt;
      html += '&amp;lt;/div&amp;gt;'&lt;br /&gt;
    end&lt;br /&gt;
    if dropdown_or_scale == 'dropdown'&lt;br /&gt;
      ## code added  to reduce Cyclomatic Complexity&lt;br /&gt;
      html = complete_drop_down(self, html, count, answer, questionnaire_min, questionnaire_max)&lt;br /&gt;
    elsif dropdown_or_scale == 'scale'&lt;br /&gt;
       html = complete_scale(self, html, count, answer, questionnaire_min, questionnaire_max)&lt;br /&gt;
    end&lt;br /&gt;
    html.html_safe&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
* Identical code found in 1 other location: Line 20 - 32 (mass = 89)&lt;br /&gt;
Also found in   app/models/scale.rb:17…28. The following method is removed from subclass: criterion and added to their superclass: scaled_question&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def view_question_text&lt;br /&gt;
    html = '&amp;lt;TR&amp;gt;&amp;lt;TD align=&amp;quot;left&amp;quot;&amp;gt; '+self.txt+' &amp;lt;/TD&amp;gt;'&lt;br /&gt;
    html += '&amp;lt;TD align=&amp;quot;left&amp;quot;&amp;gt;'+self.type+'&amp;lt;/TD&amp;gt;'&lt;br /&gt;
    html += '&amp;lt;td align=&amp;quot;center&amp;quot;&amp;gt;'+self.weight.to_s+'&amp;lt;/TD&amp;gt;'&lt;br /&gt;
    questionnaire = self.questionnaire&lt;br /&gt;
    if !self.max_label.nil? &amp;amp;&amp;amp; !self.min_label.nil?&lt;br /&gt;
      html += '&amp;lt;TD align=&amp;quot;center&amp;quot;&amp;gt; ('+self.min_label+') '+questionnaire.min_question_score.to_s+' to '+ questionnaire.max_question_score.to_s + ' ('+self.max_label+')&amp;lt;/TD&amp;gt;'&lt;br /&gt;
    else&lt;br /&gt;
      html += '&amp;lt;TD align=&amp;quot;center&amp;quot;&amp;gt;'+questionnaire.min_question_score.to_s+' to '+ questionnaire.max_question_score.to_s + '&amp;lt;/TD&amp;gt;'&lt;br /&gt;
    end&lt;br /&gt;
    html += '&amp;lt;/TR&amp;gt;'&lt;br /&gt;
    Html.html_safe&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
* Identical code found in 1 other location: Line 135 - 139 (mass = 50)&lt;br /&gt;
Also found in  app/models/scale.rb:50…54. Wrap the duplicated code into an instance method and add the instance method into superclass: scaled_question&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# add the following functions to refactor duplicates.&lt;br /&gt;
  def complete_questionnaire_min_to_questionnaire_max(ob, html, answer, questionnaire_min, questionnaire_max)&lt;br /&gt;
    for j in questionnaire_min..questionnaire_max&lt;br /&gt;
      html += '&amp;lt;td width=&amp;quot;10%&amp;quot;&amp;gt;&amp;lt;input type=&amp;quot;radio&amp;quot; id=&amp;quot;' +j.to_s+ '&amp;quot; value=&amp;quot;' +j.to_s+ '&amp;quot; name=&amp;quot;Radio_' +ob.id.to_s+ '&amp;quot;'&lt;br /&gt;
      html += 'checked=&amp;quot;checked&amp;quot;' if (!answer.nil? and answer.answer == j) or (answer.nil? and questionnaire_min == j)&lt;br /&gt;
      html += '&amp;gt;&amp;lt;/td&amp;gt;'&lt;br /&gt;
    end&lt;br /&gt;
    return html&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
* Identical code found in 1 other location Line 13 - 14 (mass = 40)&lt;br /&gt;
Also found in  app/models/scale.rb:10…11. Wrap the duplicated code into an instance method and add the instance method into superclass: scaled_question&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# add the following functions to refactor duplicates.  &lt;br /&gt;
def edit_end(ob, html)&lt;br /&gt;
    html+='&amp;lt;td&amp;gt; max_label &amp;lt;input size=&amp;quot;4&amp;quot; value=&amp;quot;'+ob.max_label.to_s+'&amp;quot; name=&amp;quot;question['+ob.id.to_s+'][max_label]&amp;quot; id=&amp;quot;question_'+ob.id.to_s+'_max_label&amp;quot; type=&amp;quot;text&amp;quot;&amp;gt;  min_label &amp;lt;input size=&amp;quot;4&amp;quot; value=&amp;quot;'+ob.min_label.to_s+'&amp;quot; name=&amp;quot;question['+ob.id.to_s+'][min_label]&amp;quot; id=&amp;quot;question_'+ob.id.to_s+'_min_label&amp;quot; type=&amp;quot;text&amp;quot;&amp;gt;&amp;lt;/td&amp;gt;'&lt;br /&gt;
    html+='&amp;lt;/tr&amp;gt;'&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
* Similar code found in 1 other location Line 103 - 105 (mass = 26)&lt;br /&gt;
Also found in   app/models/criterion.rb:107…110. Wrap the duplicated code into an instance method&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def complete_drop_down_label_config(html, label)&lt;br /&gt;
    html += j.to_s&lt;br /&gt;
    html += &amp;quot;-&amp;quot; + label if label &amp;amp;&amp;amp; label.length&amp;gt;0&lt;br /&gt;
    html += &amp;quot;&amp;lt;/option&amp;gt;&amp;quot;&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
* Similar code found in 2 other locations Line 152 - 153 (mass = 22)&lt;br /&gt;
 Also found in   app/models/criterion.rb:115…116, app/models/text_area.rb:12…13. Wrap the duplicated code into an instance method&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def complete_answer_comment(count, html, answer)&lt;br /&gt;
    html += '&amp;lt;textarea cols=' +cols+ ' rows=' +rows+ ' id=&amp;quot;responses_' +count.to_s+ '_comments&amp;quot; name=&amp;quot;responses[' +count.to_s+ '][comment]&amp;quot; style=&amp;quot;overflow:hidden;&amp;quot;&amp;gt;'&lt;br /&gt;
    html += answer.comments if !answer.nil?&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
* Similar code found in 3 other locations: Line 130 - 134 (mass = 18)&lt;br /&gt;
Also found in app/models/criterion.rb:145…149, app/models/scale.rb:45…49, app/models/scale.rb:60…64.&lt;br /&gt;
Wrap the duplicated code into an instance method and add the instance method into superclass: scaled_question&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# add the following functions to refactor duplicates.  &lt;br /&gt;
  def complete_label(label, html)&lt;br /&gt;
    if !label.nil?&lt;br /&gt;
      html += '&amp;lt;td width=&amp;quot;10%&amp;quot;&amp;gt;' +label+ '&amp;lt;/td&amp;gt;'&lt;br /&gt;
    else&lt;br /&gt;
      html += '&amp;lt;td width=&amp;quot;10%&amp;quot;&amp;gt;&amp;lt;/td&amp;gt;'&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Scale.rb===&lt;br /&gt;
* Cyclomatic complexity for complete is too high. Method has too many lines&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def complete(count, answer=nil, questionnaire_min, questionnaire_max)&lt;br /&gt;
  	html = self.txt + '&amp;lt;br&amp;gt;'&lt;br /&gt;
    html += '&amp;lt;input id=&amp;quot;responses_' +count.to_s+ '_score&amp;quot; name=&amp;quot;responses[' +count.to_s+ '][score]&amp;quot; type=&amp;quot;hidden&amp;quot;'&lt;br /&gt;
    html += 'value=&amp;quot;'+answer.answer.to_s+'&amp;quot;' if !answer.nil?&lt;br /&gt;
    html += '&amp;gt;'&lt;br /&gt;
    html += '&amp;lt;input id=&amp;quot;responses_' +count.to_s+ '_comments&amp;quot; name=&amp;quot;responses[' +count.to_s+ '][comment]&amp;quot; type=&amp;quot;hidden&amp;quot; value=&amp;quot;&amp;quot;&amp;gt;'&lt;br /&gt;
&lt;br /&gt;
    html += '&amp;lt;table&amp;gt;'&lt;br /&gt;
    html += '&amp;lt;tr&amp;gt;&amp;lt;td width=&amp;quot;10%&amp;quot;&amp;gt;&amp;lt;/td&amp;gt;'&lt;br /&gt;
    for j in questionnaire_min..questionnaire_max&lt;br /&gt;
      html += '&amp;lt;td width=&amp;quot;10%&amp;quot;&amp;gt;&amp;lt;label&amp;gt;' +j.to_s+ '&amp;lt;/label&amp;gt;&amp;lt;/td&amp;gt;'&lt;br /&gt;
    end&lt;br /&gt;
    html += '&amp;lt;td width=&amp;quot;10%&amp;quot;&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;tr&amp;gt;'&lt;br /&gt;
&lt;br /&gt;
    html = complete_label(self.min_label, html)&lt;br /&gt;
    html = complete_questionnaire_min_to_questionnaire_max(self, html, answer, questionnaire_min, questionnaire_max)&lt;br /&gt;
&lt;br /&gt;
    html += '&amp;lt;script&amp;gt;jQuery(&amp;quot;input[name=Radio_' +self.id.to_s+ ']:radio&amp;quot;).change(function() {'&lt;br /&gt;
    html += 'var response_score = jQuery(&amp;quot;#responses_' +count.to_s+ '_score&amp;quot;);'&lt;br /&gt;
    html += 'var checked_value = jQuery(&amp;quot;input[name=Radio_' +self.id.to_s+ ']:checked&amp;quot;).val();'&lt;br /&gt;
    html += 'response_score.val(checked_value);});&amp;lt;/script&amp;gt;'&lt;br /&gt;
    html = complete_label(self.max_label, html)&lt;br /&gt;
&lt;br /&gt;
    html += '&amp;lt;td width=&amp;quot;10%&amp;quot;&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;/table&amp;gt;'&lt;br /&gt;
    html.html_safe&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
* Identical code found in 1 other location: line 17-28&lt;br /&gt;
app/models/criterion.rb:20…32, def view_question_text.&lt;br /&gt;
The following method is removed from subclass: scale and added to their superclass: scaled_question.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#This method returns what to display if an instructor (etc.) is viewing a questionnaire&lt;br /&gt;
  def view_question_text&lt;br /&gt;
    html = '&amp;lt;TR&amp;gt;&amp;lt;TD align=&amp;quot;left&amp;quot;&amp;gt; '+self.txt+' &amp;lt;/TD&amp;gt;'&lt;br /&gt;
    html += '&amp;lt;TD align=&amp;quot;left&amp;quot;&amp;gt;'+self.type+'&amp;lt;/TD&amp;gt;'&lt;br /&gt;
    html += '&amp;lt;td align=&amp;quot;center&amp;quot;&amp;gt;'+self.weight.to_s+'&amp;lt;/TD&amp;gt;'&lt;br /&gt;
    questionnaire = self.questionnaire&lt;br /&gt;
    if !self.max_label.nil? &amp;amp;&amp;amp; !self.min_label.nil?&lt;br /&gt;
      html += '&amp;lt;TD align=&amp;quot;center&amp;quot;&amp;gt; ('+self.min_label+') '+questionnaire.min_question_score.to_s+' to '+ questionnaire.max_question_score.to_s + ' ('+self.max_label+')&amp;lt;/TD&amp;gt;'&lt;br /&gt;
    else&lt;br /&gt;
      html += '&amp;lt;TD align=&amp;quot;center&amp;quot;&amp;gt;'+questionnaire.min_question_score.to_s+' to '+ questionnaire.max_question_score.to_s + '&amp;lt;/TD&amp;gt;'&lt;br /&gt;
    end&lt;br /&gt;
    html += '&amp;lt;/TR&amp;gt;'&lt;br /&gt;
    html.html_safe&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
* Identical code  found in 1 other location: line 50-54&lt;br /&gt;
app/models/criterion.rb:135…139. Wrap the duplicated code into an instance method and add the instance method into superclass: scaled_question.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  # add the following functions to refactor duplicates.&lt;br /&gt;
  def complete_questionnaire_min_to_questionnaire_max(ob, html, answer, questionnaire_min, questionnaire_max)&lt;br /&gt;
    for j in questionnaire_min..questionnaire_max&lt;br /&gt;
      html += '&amp;lt;td width=&amp;quot;10%&amp;quot;&amp;gt;&amp;lt;input type=&amp;quot;radio&amp;quot; id=&amp;quot;' +j.to_s+ '&amp;quot; value=&amp;quot;' +j.to_s+ '&amp;quot; name=&amp;quot;Radio_' +ob.id.to_s+ '&amp;quot;'&lt;br /&gt;
      html += 'checked=&amp;quot;checked&amp;quot;' if (!answer.nil? and answer.answer == j) or (answer.nil? and questionnaire_min == j)&lt;br /&gt;
      html += '&amp;gt;&amp;lt;/td&amp;gt;'&lt;br /&gt;
    end&lt;br /&gt;
    return html&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
* Identical code found in 1 other location: line 10-11&lt;br /&gt;
app/models/criterion.rb:13…14. Wrap the duplicated code into an instance method and add the instance method into superclass: scaled_question&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# add the following functions to refactor duplicates.  &lt;br /&gt;
def edit_end(ob, html)&lt;br /&gt;
    html+='&amp;lt;td&amp;gt; max_label &amp;lt;input size=&amp;quot;4&amp;quot; value=&amp;quot;'+ob.max_label.to_s+'&amp;quot; name=&amp;quot;question['+ob.id.to_s+'][max_label]&amp;quot; id=&amp;quot;question_'+ob.id.to_s+'_max_label&amp;quot; type=&amp;quot;text&amp;quot;&amp;gt;  min_label &amp;lt;input size=&amp;quot;4&amp;quot; value=&amp;quot;'+ob.min_label.to_s+'&amp;quot; name=&amp;quot;question['+ob.id.to_s+'][min_label]&amp;quot; id=&amp;quot;question_'+ob.id.to_s+'_min_label&amp;quot; type=&amp;quot;text&amp;quot;&amp;gt;&amp;lt;/td&amp;gt;'&lt;br /&gt;
    html+='&amp;lt;/tr&amp;gt;'&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
* Similar code found in 3 other locations: line 60-64&lt;br /&gt;
app/models/criterion.rb:130…134, app/models/criterion.rb:145…149, app/models/scale.rb:45…49. &lt;br /&gt;
Wrap the duplicated code into an instance method and add the instance method into superclass: scaled_question&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# add the following functions to refactor duplicates.  &lt;br /&gt;
  def complete_label(label, html)&lt;br /&gt;
    if !label.nil?&lt;br /&gt;
      html += '&amp;lt;td width=&amp;quot;10%&amp;quot;&amp;gt;' +label+ '&amp;lt;/td&amp;gt;'&lt;br /&gt;
    else&lt;br /&gt;
      html += '&amp;lt;td width=&amp;quot;10%&amp;quot;&amp;gt;&amp;lt;/td&amp;gt;'&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Checkbox.rb===&lt;br /&gt;
* Method has too many lines.&lt;br /&gt;
By moving codes to private methods outside this method, this problem can be fixed together with the following one. Here is the new complete method together with two additional private methods: hasAnswer(html, answer) and nextQuestionTail(html, next_question). The source codes are listed as below.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def complete(count, answer=nil)&lt;br /&gt;
    curr_question = Question.find(self.id)&lt;br /&gt;
    prev_question = Question.where(&amp;quot;seq &amp;lt; ?&amp;quot;, curr_question.seq).order(:seq).last&lt;br /&gt;
    next_question = Question.where(&amp;quot;seq &amp;gt; ?&amp;quot;, curr_question.seq).order(:seq).first&lt;br /&gt;
    html = ''&lt;br /&gt;
    if prev_question.type == 'ColumnHeader'&lt;br /&gt;
      html = '&amp;lt;td style=&amp;quot;padding: 15px;&amp;quot;&amp;gt;'&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    html += '&amp;lt;input id=&amp;quot;responses_' +count.to_s+ '_comments&amp;quot; name=&amp;quot;responses[' +count.to_s+ '][comment]&amp;quot; type=&amp;quot;hidden&amp;quot; value=&amp;quot;&amp;quot;&amp;gt;'&lt;br /&gt;
    html += '&amp;lt;input id=&amp;quot;responses_' +count.to_s+ '_score&amp;quot; name=&amp;quot;responses[' +count.to_s+ '][score]&amp;quot; type=&amp;quot;hidden&amp;quot;'&lt;br /&gt;
    html += hasAnswer(html , answer)&lt;br /&gt;
    html += '&amp;gt;'&lt;br /&gt;
    html += '&amp;lt;input id=&amp;quot;responses_' +count.to_s+ '_checkbox&amp;quot; type=&amp;quot;checkbox&amp;quot; onchange=&amp;quot;checkbox' +count.to_s+ 'Changed()&amp;quot;'&lt;br /&gt;
    html += 'checked=&amp;quot;checked&amp;quot;' if !answer.nil? and answer.answer == 1&lt;br /&gt;
    html += '&amp;gt;'&lt;br /&gt;
    html += '&amp;lt;label for=&amp;quot;responses_' +count.to_s+ '&amp;quot;&amp;gt;' +self.txt+ '&amp;lt;/label&amp;gt;'&lt;br /&gt;
&lt;br /&gt;
    html += '&amp;lt;script&amp;gt;function checkbox' +count.to_s+ 'Changed() {'&lt;br /&gt;
    html += ' var checkbox = jQuery(&amp;quot;#responses_' +count.to_s+ '_checkbox&amp;quot;);'&lt;br /&gt;
    html += ' var response_score = jQuery(&amp;quot;#responses_' +count.to_s+ '_score&amp;quot;);'&lt;br /&gt;
    html += 'if (checkbox.is(&amp;quot;:checked&amp;quot;)) {'&lt;br /&gt;
    html += 'response_score.val(&amp;quot;1&amp;quot;);'&lt;br /&gt;
    html += '} else {'&lt;br /&gt;
    html += 'response_score.val(&amp;quot;0&amp;quot;);}}&amp;lt;/script&amp;gt;'&lt;br /&gt;
&lt;br /&gt;
    html = nextQuestionTail(html, next_question)&lt;br /&gt;
    html.html_safe&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  #YJ private for complete()&lt;br /&gt;
  def hasAnswer(html, answer)&lt;br /&gt;
    if !answer.nil? and answer.answer == 1&lt;br /&gt;
      html += 'value=&amp;quot;1&amp;quot;'&lt;br /&gt;
    else&lt;br /&gt;
      html += 'value=&amp;quot;0&amp;quot;'&lt;br /&gt;
    end&lt;br /&gt;
    return html&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def nextQuestionTail(html, next_q)&lt;br /&gt;
    if next_question.type == 'ColumnHeader'&lt;br /&gt;
      html += '&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;'&lt;br /&gt;
    elsif next_question.type == 'SectionHeader' or next_question.type == 'TableHeader'&lt;br /&gt;
      html += '&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;/table&amp;gt;&amp;lt;br/&amp;gt;'&lt;br /&gt;
    else&lt;br /&gt;
      html += '&amp;lt;BR/&amp;gt;'&lt;br /&gt;
    end&lt;br /&gt;
    return html&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
* Cyclomatic complexity for complete is too high.&lt;br /&gt;
This problem can be solved by moving branches outside to other private methods. See source code above.&lt;br /&gt;
* Similar codes in edit method are found in 2 other locations.&lt;br /&gt;
(questionnaire_header.rb and upload_file.rb)&lt;br /&gt;
Such code duplication can be eliminated by moving the identical part of the similar edit method to a new function, named edit_prefix(html, count) to their common superclass, which is Question (question.rb).&lt;br /&gt;
Here is the source code of the added edit_prefix method in question.rb:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 def edit_prefix(self, html)&lt;br /&gt;
    html ='&amp;lt;tr&amp;gt;'&lt;br /&gt;
    html+='&amp;lt;td align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;a rel=&amp;quot;nofollow&amp;quot; data-method=&amp;quot;delete&amp;quot; href=&amp;quot;/questions/' +ob.id.to_s+ '&amp;quot;&amp;gt;Remove&amp;lt;/a&amp;gt;&amp;lt;/td&amp;gt;'&lt;br /&gt;
    html+='&amp;lt;td&amp;gt;&amp;lt;input size=&amp;quot;6&amp;quot; value=&amp;quot;'+ob.seq.to_s+'&amp;quot; name=&amp;quot;question['+ob.id.to_s+'][seq]&amp;quot; id=&amp;quot;question_'+ob.id.to_s+'_seq&amp;quot; type=&amp;quot;text&amp;quot;&amp;gt;&amp;lt;/td&amp;gt;'&lt;br /&gt;
    html+='&amp;lt;td&amp;gt;&amp;lt;textarea cols=&amp;quot;50&amp;quot; rows=&amp;quot;1&amp;quot; name=&amp;quot;question['+ob.id.to_s+'][txt]&amp;quot; id=&amp;quot;question_'+ob.id.to_s+'_txt&amp;quot;&amp;gt;'+ob.txt+'&amp;lt;/textarea&amp;gt;&amp;lt;/td&amp;gt;'&lt;br /&gt;
    html+='&amp;lt;td&amp;gt;&amp;lt;input size=&amp;quot;10&amp;quot; disabled=&amp;quot;disabled&amp;quot; value=&amp;quot;'+ob.type+'&amp;quot; name=&amp;quot;question['+ob.id.to_s+'][type]&amp;quot; id=&amp;quot;question_'+ob.id.to_s+'_type&amp;quot; type=&amp;quot;text&amp;quot;&amp;gt;''&amp;lt;/td&amp;gt;'&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
The original code are commented out and insert the function call of the above function, html will be returned in the above function, see codes below:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def edit(count)&lt;br /&gt;
    html = edit_prefix(self, html)&lt;br /&gt;
    html+='&amp;lt;td&amp;gt;&amp;lt;!--placeholder (UnscoredQuestion does not need weight)--&amp;gt;&amp;lt;/td&amp;gt;'&lt;br /&gt;
    html+='&amp;lt;/tr&amp;gt;'&lt;br /&gt;
    html.html_safe&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
* Similar codes in view_question_text method are found in 4 other locations.&lt;br /&gt;
(dropdown.rb, questionnaire_header.rb, text_response.rb, upload_file.rb)&lt;br /&gt;
The solution to this problem is the same as above one, below is the function added in the most common superclass, which is Question, that contains the common parts of the codes found in the view_question_text methods in all five classes.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def view_qt_prefix(ob, html)&lt;br /&gt;
    html = '&amp;lt;TR&amp;gt;&amp;lt;TD align=&amp;quot;left&amp;quot;&amp;gt; '+ob.txt+ ' &amp;lt;/TD&amp;gt;'&lt;br /&gt;
    html += '&amp;lt;TD align=&amp;quot;left&amp;quot;&amp;gt;'+ob.type+'&amp;lt;/TD&amp;gt;'&lt;br /&gt;
    html += '&amp;lt;td align=&amp;quot;center&amp;quot;&amp;gt;'+ob.weight.to_s+'&amp;lt;/TD&amp;gt;'&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
The original code are commented out and insert the function call of the above function, html will be returned in the above function, see codes below:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def view_question_text&lt;br /&gt;
    html = view_qt_prefix(ob, html)&lt;br /&gt;
    html += '&amp;lt;TD align=&amp;quot;center&amp;quot;&amp;gt;Checked/Unchecked&amp;lt;/TD&amp;gt;'&lt;br /&gt;
    html += '&amp;lt;/TR&amp;gt;'&lt;br /&gt;
    html.html_safe&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Questionnaire_header.rb===&lt;br /&gt;
All problems in this file are solved after solving the problems found in checkbox.rb.&lt;br /&gt;
&lt;br /&gt;
===Upload_file.rb===&lt;br /&gt;
All problems in this file are solved after solving the problems found in checkbox.rb.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Unit-tests==&lt;br /&gt;
For each of the four required four question types (criterion.rb, scale.rb, checkbox.rb, upload_file.rb), there are four unit tests for the following four functions: ''edit'', ''complete'', ''view_question_text'', and ''view_complete_question_text''. Here are the spec files git hub links:&lt;br /&gt;
[https://github.com/schen35/expertiza/blob/master/spec/models/criterion_spec.rb criterion_spec.rb] [https://github.com/schen35/expertiza/blob/master/spec/models/scale_spec.rb scale_spec.rb] &lt;br /&gt;
[https://github.com/schen35/expertiza/blob/master/spec/models/checkbox_spec.rb checkbox_spec.rb] &lt;br /&gt;
[https://github.com/schen35/expertiza/blob/master/spec/models/upload_file_spec.rb upload_file_spec.rb].&lt;/div&gt;</summary>
		<author><name>Hguan2</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=User:Hguan2&amp;diff=101467</id>
		<title>User:Hguan2</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=User:Hguan2&amp;diff=101467"/>
		<updated>2016-03-29T02:05:47Z</updated>

		<summary type="html">&lt;p&gt;Hguan2: moved User:Hguan2 to E1608: Refactor and write unit tests for question type.rb: change the title to the writing assignment title&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;#REDIRECT [[E1608: Refactor and write unit tests for question type.rb]]&lt;/div&gt;</summary>
		<author><name>Hguan2</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2016/Refactor_and_write_unit_tests_for_question_type.rb&amp;diff=101466</id>
		<title>CSC/ECE 517 Spring 2016/Refactor and write unit tests for question type.rb</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2016/Refactor_and_write_unit_tests_for_question_type.rb&amp;diff=101466"/>
		<updated>2016-03-29T02:05:47Z</updated>

		<summary type="html">&lt;p&gt;Hguan2: moved User:Hguan2 to E1608: Refactor and write unit tests for question type.rb: change the title to the writing assignment title&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This wiki page is for the description of changes made under E1608 OSS assignment for Spring 2016, CSC/ECE 517. The assignment task is to  refactor &amp;amp; write unit tests for [question_type].rb (eg. criterion.rb).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Problem Statement ==&lt;br /&gt;
===Files related===&lt;br /&gt;
Four models is related: criterion.rb, scale.rb, checkbox.rb, questionnaire_header.rb, upload_file.rb. There are 4 methods “edit”, “view_question_text”, “complete” and “view_completed_question” correspond to different views. &lt;br /&gt;
&lt;br /&gt;
*edit ~&amp;gt;	when instructor add/edit new questions&lt;br /&gt;
*view ~&amp;gt; when instructor view existed questions&lt;br /&gt;
*complete ~&amp;gt; when students do peer reviews&lt;br /&gt;
*view_completed_question ~&amp;gt; when student view existed peer reviews&lt;br /&gt;
&lt;br /&gt;
===Expertiza question types inheritance hierarchy===&lt;br /&gt;
&lt;br /&gt;
*Choice question&lt;br /&gt;
**Scored question&lt;br /&gt;
***Scale&lt;br /&gt;
***Criterion&lt;br /&gt;
**Unscored question&lt;br /&gt;
***Dropdown&lt;br /&gt;
***CheckBox&lt;br /&gt;
*TextResponse&lt;br /&gt;
**TextArea&lt;br /&gt;
**TextField&lt;br /&gt;
*UploadFile&lt;br /&gt;
&lt;br /&gt;
===Files problem===&lt;br /&gt;
&lt;br /&gt;
There are some issues in each file, such as security, complexity, duplication, etc. And currently there is no unit tests for [question_type].rb.&lt;br /&gt;
&lt;br /&gt;
===Our contribution===&lt;br /&gt;
*Refactor these [question_type].rb files and fix issues.&lt;br /&gt;
*Keep the inputs and outputs of these methods (edit, view, complete, view_completed_question) the same as before.&lt;br /&gt;
*Write unit tests for [question_type].rb listed above.&lt;br /&gt;
*Create RSpec files for each question type in /spec/models/ folder&lt;br /&gt;
*Create multiple tests to check valid and invalid cases, such as input including special character double quote (“”).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
==Refactor==&lt;br /&gt;
===Criterion.rb===&lt;br /&gt;
* Method has too many lines: Line 35 - 158 [106/30]&lt;br /&gt;
Wrap the specific code into different instance methods. &lt;br /&gt;
* Cyclomatic complexity for complete is too high: Line 35 - 158 [28/6]&lt;br /&gt;
Wrap the code into different instance methods to reduce cyclomatic complexity&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 def complete(count, answer=nil, questionnaire_min, questionnaire_max, dropdown_or_scale)&lt;br /&gt;
    if self.size.nil?&lt;br /&gt;
      cols = '70'&lt;br /&gt;
      rows = '1'&lt;br /&gt;
    else&lt;br /&gt;
      cols = self.size.split(',')[0]&lt;br /&gt;
      rows = self.size.split(',')[1]&lt;br /&gt;
    end&lt;br /&gt;
    html = '&amp;lt;li&amp;gt;&amp;lt;div&amp;gt;&amp;lt;label for=&amp;quot;responses_' +count.to_s+ '&amp;quot;&amp;gt;' +self.txt+ &amp;quot;&amp;lt;/label&amp;gt;&amp;lt;/div&amp;gt;&amp;quot;&lt;br /&gt;
    #show advice for each criterion question&lt;br /&gt;
    question_advices = QuestionAdvice.where(question_id: self.id).sort_by { |advice| advice.id }&lt;br /&gt;
    advice_total_length = 0&lt;br /&gt;
    question_advices.each do |question_advice|&lt;br /&gt;
      if question_advice.advice &amp;amp;&amp;amp; !question_advice.advice == &amp;quot;&amp;quot;&lt;br /&gt;
        advice_total_length += question_advice.advice.length&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
    if question_advices.length &amp;gt; 0 and advice_total_length &amp;gt; 0&lt;br /&gt;
       html = complete_show_advice(self, html)&lt;br /&gt;
    question_advices.reverse.each_with_index do |question_advice, index|&lt;br /&gt;
        html += '&amp;lt;a id=&amp;quot;changeScore_&amp;gt;' + self.id.to_s + '&amp;quot; onclick=&amp;quot;changeScore(' + count.to_s + ',' + index.to_s + ')&amp;quot;&amp;gt;'&lt;br /&gt;
        html += (question_advices.length - index).to_s + ' - ' + question_advice.advice + '&amp;lt;/a&amp;gt;&amp;lt;br/&amp;gt;'&lt;br /&gt;
        html += '&amp;lt;script&amp;gt;'&lt;br /&gt;
        html += 'function changeScore(i, j) {'&lt;br /&gt;
        html += 'var elem = jQuery(&amp;quot;#responses_&amp;quot; + i.toString() + &amp;quot;_score&amp;quot;);'&lt;br /&gt;
        html += 'var opts = elem.children(&amp;quot;option&amp;quot;).length;'&lt;br /&gt;
        html += 'elem.val((opts - j - 1).toString());}'&lt;br /&gt;
        html += '&amp;lt;/script&amp;gt;'&lt;br /&gt;
      end&lt;br /&gt;
      html += '&amp;lt;/div&amp;gt;'&lt;br /&gt;
    end&lt;br /&gt;
    if dropdown_or_scale == 'dropdown'&lt;br /&gt;
      ## code added  to reduce Cyclomatic Complexity&lt;br /&gt;
      html = complete_drop_down(self, html, count, answer, questionnaire_min, questionnaire_max)&lt;br /&gt;
    elsif dropdown_or_scale == 'scale'&lt;br /&gt;
       html = complete_scale(self, html, count, answer, questionnaire_min, questionnaire_max)&lt;br /&gt;
    end&lt;br /&gt;
    html.html_safe&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
* Identical code found in 1 other location: Line 20 - 32 (mass = 89)&lt;br /&gt;
Also found in   app/models/scale.rb:17…28. The following method is removed from subclass: criterion and added to their superclass: scaled_question&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def view_question_text&lt;br /&gt;
    html = '&amp;lt;TR&amp;gt;&amp;lt;TD align=&amp;quot;left&amp;quot;&amp;gt; '+self.txt+' &amp;lt;/TD&amp;gt;'&lt;br /&gt;
    html += '&amp;lt;TD align=&amp;quot;left&amp;quot;&amp;gt;'+self.type+'&amp;lt;/TD&amp;gt;'&lt;br /&gt;
    html += '&amp;lt;td align=&amp;quot;center&amp;quot;&amp;gt;'+self.weight.to_s+'&amp;lt;/TD&amp;gt;'&lt;br /&gt;
    questionnaire = self.questionnaire&lt;br /&gt;
    if !self.max_label.nil? &amp;amp;&amp;amp; !self.min_label.nil?&lt;br /&gt;
      html += '&amp;lt;TD align=&amp;quot;center&amp;quot;&amp;gt; ('+self.min_label+') '+questionnaire.min_question_score.to_s+' to '+ questionnaire.max_question_score.to_s + ' ('+self.max_label+')&amp;lt;/TD&amp;gt;'&lt;br /&gt;
    else&lt;br /&gt;
      html += '&amp;lt;TD align=&amp;quot;center&amp;quot;&amp;gt;'+questionnaire.min_question_score.to_s+' to '+ questionnaire.max_question_score.to_s + '&amp;lt;/TD&amp;gt;'&lt;br /&gt;
    end&lt;br /&gt;
    html += '&amp;lt;/TR&amp;gt;'&lt;br /&gt;
    Html.html_safe&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
* Identical code found in 1 other location: Line 135 - 139 (mass = 50)&lt;br /&gt;
Also found in  app/models/scale.rb:50…54. Wrap the duplicated code into an instance method and add the instance method into superclass: scaled_question&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# add the following functions to refactor duplicates.&lt;br /&gt;
  def complete_questionnaire_min_to_questionnaire_max(ob, html, answer, questionnaire_min, questionnaire_max)&lt;br /&gt;
    for j in questionnaire_min..questionnaire_max&lt;br /&gt;
      html += '&amp;lt;td width=&amp;quot;10%&amp;quot;&amp;gt;&amp;lt;input type=&amp;quot;radio&amp;quot; id=&amp;quot;' +j.to_s+ '&amp;quot; value=&amp;quot;' +j.to_s+ '&amp;quot; name=&amp;quot;Radio_' +ob.id.to_s+ '&amp;quot;'&lt;br /&gt;
      html += 'checked=&amp;quot;checked&amp;quot;' if (!answer.nil? and answer.answer == j) or (answer.nil? and questionnaire_min == j)&lt;br /&gt;
      html += '&amp;gt;&amp;lt;/td&amp;gt;'&lt;br /&gt;
    end&lt;br /&gt;
    return html&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
* Identical code found in 1 other location Line 13 - 14 (mass = 40)&lt;br /&gt;
Also found in  app/models/scale.rb:10…11. Wrap the duplicated code into an instance method and add the instance method into superclass: scaled_question&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# add the following functions to refactor duplicates.  &lt;br /&gt;
def edit_end(ob, html)&lt;br /&gt;
    html+='&amp;lt;td&amp;gt; max_label &amp;lt;input size=&amp;quot;4&amp;quot; value=&amp;quot;'+ob.max_label.to_s+'&amp;quot; name=&amp;quot;question['+ob.id.to_s+'][max_label]&amp;quot; id=&amp;quot;question_'+ob.id.to_s+'_max_label&amp;quot; type=&amp;quot;text&amp;quot;&amp;gt;  min_label &amp;lt;input size=&amp;quot;4&amp;quot; value=&amp;quot;'+ob.min_label.to_s+'&amp;quot; name=&amp;quot;question['+ob.id.to_s+'][min_label]&amp;quot; id=&amp;quot;question_'+ob.id.to_s+'_min_label&amp;quot; type=&amp;quot;text&amp;quot;&amp;gt;&amp;lt;/td&amp;gt;'&lt;br /&gt;
    html+='&amp;lt;/tr&amp;gt;'&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
* Similar code found in 1 other location Line 103 - 105 (mass = 26)&lt;br /&gt;
Also found in   app/models/criterion.rb:107…110. Wrap the duplicated code into an instance method&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def complete_drop_down_label_config(html, label)&lt;br /&gt;
    html += j.to_s&lt;br /&gt;
    html += &amp;quot;-&amp;quot; + label if label &amp;amp;&amp;amp; label.length&amp;gt;0&lt;br /&gt;
    html += &amp;quot;&amp;lt;/option&amp;gt;&amp;quot;&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
* Similar code found in 2 other locations Line 152 - 153 (mass = 22)&lt;br /&gt;
 Also found in   app/models/criterion.rb:115…116, app/models/text_area.rb:12…13. Wrap the duplicated code into an instance method&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def complete_answer_comment(count, html, answer)&lt;br /&gt;
    html += '&amp;lt;textarea cols=' +cols+ ' rows=' +rows+ ' id=&amp;quot;responses_' +count.to_s+ '_comments&amp;quot; name=&amp;quot;responses[' +count.to_s+ '][comment]&amp;quot; style=&amp;quot;overflow:hidden;&amp;quot;&amp;gt;'&lt;br /&gt;
    html += answer.comments if !answer.nil?&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
* Similar code found in 3 other locations: Line 130 - 134 (mass = 18)&lt;br /&gt;
Also found in app/models/criterion.rb:145…149, app/models/scale.rb:45…49, app/models/scale.rb:60…64.&lt;br /&gt;
Wrap the duplicated code into an instance method and add the instance method into superclass: scaled_question&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# add the following functions to refactor duplicates.  &lt;br /&gt;
  def complete_label(label, html)&lt;br /&gt;
    if !label.nil?&lt;br /&gt;
      html += '&amp;lt;td width=&amp;quot;10%&amp;quot;&amp;gt;' +label+ '&amp;lt;/td&amp;gt;'&lt;br /&gt;
    else&lt;br /&gt;
      html += '&amp;lt;td width=&amp;quot;10%&amp;quot;&amp;gt;&amp;lt;/td&amp;gt;'&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Scale.rb===&lt;br /&gt;
* Cyclomatic complexity for complete is too high. Method has too many lines&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def complete(count, answer=nil, questionnaire_min, questionnaire_max)&lt;br /&gt;
  	html = self.txt + '&amp;lt;br&amp;gt;'&lt;br /&gt;
    html += '&amp;lt;input id=&amp;quot;responses_' +count.to_s+ '_score&amp;quot; name=&amp;quot;responses[' +count.to_s+ '][score]&amp;quot; type=&amp;quot;hidden&amp;quot;'&lt;br /&gt;
    html += 'value=&amp;quot;'+answer.answer.to_s+'&amp;quot;' if !answer.nil?&lt;br /&gt;
    html += '&amp;gt;'&lt;br /&gt;
    html += '&amp;lt;input id=&amp;quot;responses_' +count.to_s+ '_comments&amp;quot; name=&amp;quot;responses[' +count.to_s+ '][comment]&amp;quot; type=&amp;quot;hidden&amp;quot; value=&amp;quot;&amp;quot;&amp;gt;'&lt;br /&gt;
&lt;br /&gt;
    html += '&amp;lt;table&amp;gt;'&lt;br /&gt;
    html += '&amp;lt;tr&amp;gt;&amp;lt;td width=&amp;quot;10%&amp;quot;&amp;gt;&amp;lt;/td&amp;gt;'&lt;br /&gt;
    for j in questionnaire_min..questionnaire_max&lt;br /&gt;
      html += '&amp;lt;td width=&amp;quot;10%&amp;quot;&amp;gt;&amp;lt;label&amp;gt;' +j.to_s+ '&amp;lt;/label&amp;gt;&amp;lt;/td&amp;gt;'&lt;br /&gt;
    end&lt;br /&gt;
    html += '&amp;lt;td width=&amp;quot;10%&amp;quot;&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;tr&amp;gt;'&lt;br /&gt;
&lt;br /&gt;
    html = complete_label(self.min_label, html)&lt;br /&gt;
    html = complete_questionnaire_min_to_questionnaire_max(self, html, answer, questionnaire_min, questionnaire_max)&lt;br /&gt;
&lt;br /&gt;
    html += '&amp;lt;script&amp;gt;jQuery(&amp;quot;input[name=Radio_' +self.id.to_s+ ']:radio&amp;quot;).change(function() {'&lt;br /&gt;
    html += 'var response_score = jQuery(&amp;quot;#responses_' +count.to_s+ '_score&amp;quot;);'&lt;br /&gt;
    html += 'var checked_value = jQuery(&amp;quot;input[name=Radio_' +self.id.to_s+ ']:checked&amp;quot;).val();'&lt;br /&gt;
    html += 'response_score.val(checked_value);});&amp;lt;/script&amp;gt;'&lt;br /&gt;
    html = complete_label(self.max_label, html)&lt;br /&gt;
&lt;br /&gt;
    html += '&amp;lt;td width=&amp;quot;10%&amp;quot;&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;/table&amp;gt;'&lt;br /&gt;
    html.html_safe&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
* Identical code found in 1 other location: line 17-28&lt;br /&gt;
app/models/criterion.rb:20…32, def view_question_text.&lt;br /&gt;
The following method is removed from subclass: scale and added to their superclass: scaled_question.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#This method returns what to display if an instructor (etc.) is viewing a questionnaire&lt;br /&gt;
  def view_question_text&lt;br /&gt;
    html = '&amp;lt;TR&amp;gt;&amp;lt;TD align=&amp;quot;left&amp;quot;&amp;gt; '+self.txt+' &amp;lt;/TD&amp;gt;'&lt;br /&gt;
    html += '&amp;lt;TD align=&amp;quot;left&amp;quot;&amp;gt;'+self.type+'&amp;lt;/TD&amp;gt;'&lt;br /&gt;
    html += '&amp;lt;td align=&amp;quot;center&amp;quot;&amp;gt;'+self.weight.to_s+'&amp;lt;/TD&amp;gt;'&lt;br /&gt;
    questionnaire = self.questionnaire&lt;br /&gt;
    if !self.max_label.nil? &amp;amp;&amp;amp; !self.min_label.nil?&lt;br /&gt;
      html += '&amp;lt;TD align=&amp;quot;center&amp;quot;&amp;gt; ('+self.min_label+') '+questionnaire.min_question_score.to_s+' to '+ questionnaire.max_question_score.to_s + ' ('+self.max_label+')&amp;lt;/TD&amp;gt;'&lt;br /&gt;
    else&lt;br /&gt;
      html += '&amp;lt;TD align=&amp;quot;center&amp;quot;&amp;gt;'+questionnaire.min_question_score.to_s+' to '+ questionnaire.max_question_score.to_s + '&amp;lt;/TD&amp;gt;'&lt;br /&gt;
    end&lt;br /&gt;
    html += '&amp;lt;/TR&amp;gt;'&lt;br /&gt;
    html.html_safe&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
* Identical code  found in 1 other location: line 50-54&lt;br /&gt;
app/models/criterion.rb:135…139. Wrap the duplicated code into an instance method and add the instance method into superclass: scaled_question.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  # add the following functions to refactor duplicates.&lt;br /&gt;
  def complete_questionnaire_min_to_questionnaire_max(ob, html, answer, questionnaire_min, questionnaire_max)&lt;br /&gt;
    for j in questionnaire_min..questionnaire_max&lt;br /&gt;
      html += '&amp;lt;td width=&amp;quot;10%&amp;quot;&amp;gt;&amp;lt;input type=&amp;quot;radio&amp;quot; id=&amp;quot;' +j.to_s+ '&amp;quot; value=&amp;quot;' +j.to_s+ '&amp;quot; name=&amp;quot;Radio_' +ob.id.to_s+ '&amp;quot;'&lt;br /&gt;
      html += 'checked=&amp;quot;checked&amp;quot;' if (!answer.nil? and answer.answer == j) or (answer.nil? and questionnaire_min == j)&lt;br /&gt;
      html += '&amp;gt;&amp;lt;/td&amp;gt;'&lt;br /&gt;
    end&lt;br /&gt;
    return html&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
* Identical code found in 1 other location: line 10-11&lt;br /&gt;
app/models/criterion.rb:13…14. Wrap the duplicated code into an instance method and add the instance method into superclass: scaled_question&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# add the following functions to refactor duplicates.  &lt;br /&gt;
def edit_end(ob, html)&lt;br /&gt;
    html+='&amp;lt;td&amp;gt; max_label &amp;lt;input size=&amp;quot;4&amp;quot; value=&amp;quot;'+ob.max_label.to_s+'&amp;quot; name=&amp;quot;question['+ob.id.to_s+'][max_label]&amp;quot; id=&amp;quot;question_'+ob.id.to_s+'_max_label&amp;quot; type=&amp;quot;text&amp;quot;&amp;gt;  min_label &amp;lt;input size=&amp;quot;4&amp;quot; value=&amp;quot;'+ob.min_label.to_s+'&amp;quot; name=&amp;quot;question['+ob.id.to_s+'][min_label]&amp;quot; id=&amp;quot;question_'+ob.id.to_s+'_min_label&amp;quot; type=&amp;quot;text&amp;quot;&amp;gt;&amp;lt;/td&amp;gt;'&lt;br /&gt;
    html+='&amp;lt;/tr&amp;gt;'&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
* Similar code found in 3 other locations: line 60-64&lt;br /&gt;
app/models/criterion.rb:130…134, app/models/criterion.rb:145…149, app/models/scale.rb:45…49. &lt;br /&gt;
Wrap the duplicated code into an instance method and add the instance method into superclass: scaled_question&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# add the following functions to refactor duplicates.  &lt;br /&gt;
  def complete_label(label, html)&lt;br /&gt;
    if !label.nil?&lt;br /&gt;
      html += '&amp;lt;td width=&amp;quot;10%&amp;quot;&amp;gt;' +label+ '&amp;lt;/td&amp;gt;'&lt;br /&gt;
    else&lt;br /&gt;
      html += '&amp;lt;td width=&amp;quot;10%&amp;quot;&amp;gt;&amp;lt;/td&amp;gt;'&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Checkbox.rb===&lt;br /&gt;
* Method has too many lines.&lt;br /&gt;
By moving codes to private methods outside this method, this problem can be fixed together with the following one. Here is the new complete method together with two additional private methods: hasAnswer(html, answer) and nextQuestionTail(html, next_question). The source codes are listed as below.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def complete(count, answer=nil)&lt;br /&gt;
    curr_question = Question.find(self.id)&lt;br /&gt;
    prev_question = Question.where(&amp;quot;seq &amp;lt; ?&amp;quot;, curr_question.seq).order(:seq).last&lt;br /&gt;
    next_question = Question.where(&amp;quot;seq &amp;gt; ?&amp;quot;, curr_question.seq).order(:seq).first&lt;br /&gt;
    html = ''&lt;br /&gt;
    if prev_question.type == 'ColumnHeader'&lt;br /&gt;
      html = '&amp;lt;td style=&amp;quot;padding: 15px;&amp;quot;&amp;gt;'&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    html += '&amp;lt;input id=&amp;quot;responses_' +count.to_s+ '_comments&amp;quot; name=&amp;quot;responses[' +count.to_s+ '][comment]&amp;quot; type=&amp;quot;hidden&amp;quot; value=&amp;quot;&amp;quot;&amp;gt;'&lt;br /&gt;
    html += '&amp;lt;input id=&amp;quot;responses_' +count.to_s+ '_score&amp;quot; name=&amp;quot;responses[' +count.to_s+ '][score]&amp;quot; type=&amp;quot;hidden&amp;quot;'&lt;br /&gt;
    html += hasAnswer(html , answer)&lt;br /&gt;
    html += '&amp;gt;'&lt;br /&gt;
    html += '&amp;lt;input id=&amp;quot;responses_' +count.to_s+ '_checkbox&amp;quot; type=&amp;quot;checkbox&amp;quot; onchange=&amp;quot;checkbox' +count.to_s+ 'Changed()&amp;quot;'&lt;br /&gt;
    html += 'checked=&amp;quot;checked&amp;quot;' if !answer.nil? and answer.answer == 1&lt;br /&gt;
    html += '&amp;gt;'&lt;br /&gt;
    html += '&amp;lt;label for=&amp;quot;responses_' +count.to_s+ '&amp;quot;&amp;gt;' +self.txt+ '&amp;lt;/label&amp;gt;'&lt;br /&gt;
&lt;br /&gt;
    html += '&amp;lt;script&amp;gt;function checkbox' +count.to_s+ 'Changed() {'&lt;br /&gt;
    html += ' var checkbox = jQuery(&amp;quot;#responses_' +count.to_s+ '_checkbox&amp;quot;);'&lt;br /&gt;
    html += ' var response_score = jQuery(&amp;quot;#responses_' +count.to_s+ '_score&amp;quot;);'&lt;br /&gt;
    html += 'if (checkbox.is(&amp;quot;:checked&amp;quot;)) {'&lt;br /&gt;
    html += 'response_score.val(&amp;quot;1&amp;quot;);'&lt;br /&gt;
    html += '} else {'&lt;br /&gt;
    html += 'response_score.val(&amp;quot;0&amp;quot;);}}&amp;lt;/script&amp;gt;'&lt;br /&gt;
&lt;br /&gt;
    html = nextQuestionTail(html, next_question)&lt;br /&gt;
    html.html_safe&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  #YJ private for complete()&lt;br /&gt;
  def hasAnswer(html, answer)&lt;br /&gt;
    if !answer.nil? and answer.answer == 1&lt;br /&gt;
      html += 'value=&amp;quot;1&amp;quot;'&lt;br /&gt;
    else&lt;br /&gt;
      html += 'value=&amp;quot;0&amp;quot;'&lt;br /&gt;
    end&lt;br /&gt;
    return html&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def nextQuestionTail(html, next_q)&lt;br /&gt;
    if next_question.type == 'ColumnHeader'&lt;br /&gt;
      html += '&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;'&lt;br /&gt;
    elsif next_question.type == 'SectionHeader' or next_question.type == 'TableHeader'&lt;br /&gt;
      html += '&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;/table&amp;gt;&amp;lt;br/&amp;gt;'&lt;br /&gt;
    else&lt;br /&gt;
      html += '&amp;lt;BR/&amp;gt;'&lt;br /&gt;
    end&lt;br /&gt;
    return html&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
* Cyclomatic complexity for complete is too high.&lt;br /&gt;
This problem can be solved by moving branches outside to other private methods. See source code above.&lt;br /&gt;
* Similar codes in edit method are found in 2 other locations.&lt;br /&gt;
(questionnaire_header.rb and upload_file.rb)&lt;br /&gt;
Such code duplication can be eliminated by moving the identical part of the similar edit method to a new function, named edit_prefix(html, count) to their common superclass, which is Question (question.rb).&lt;br /&gt;
Here is the source code of the added edit_prefix method in question.rb:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 def edit_prefix(self, html)&lt;br /&gt;
    html ='&amp;lt;tr&amp;gt;'&lt;br /&gt;
    html+='&amp;lt;td align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;a rel=&amp;quot;nofollow&amp;quot; data-method=&amp;quot;delete&amp;quot; href=&amp;quot;/questions/' +ob.id.to_s+ '&amp;quot;&amp;gt;Remove&amp;lt;/a&amp;gt;&amp;lt;/td&amp;gt;'&lt;br /&gt;
    html+='&amp;lt;td&amp;gt;&amp;lt;input size=&amp;quot;6&amp;quot; value=&amp;quot;'+ob.seq.to_s+'&amp;quot; name=&amp;quot;question['+ob.id.to_s+'][seq]&amp;quot; id=&amp;quot;question_'+ob.id.to_s+'_seq&amp;quot; type=&amp;quot;text&amp;quot;&amp;gt;&amp;lt;/td&amp;gt;'&lt;br /&gt;
    html+='&amp;lt;td&amp;gt;&amp;lt;textarea cols=&amp;quot;50&amp;quot; rows=&amp;quot;1&amp;quot; name=&amp;quot;question['+ob.id.to_s+'][txt]&amp;quot; id=&amp;quot;question_'+ob.id.to_s+'_txt&amp;quot;&amp;gt;'+ob.txt+'&amp;lt;/textarea&amp;gt;&amp;lt;/td&amp;gt;'&lt;br /&gt;
    html+='&amp;lt;td&amp;gt;&amp;lt;input size=&amp;quot;10&amp;quot; disabled=&amp;quot;disabled&amp;quot; value=&amp;quot;'+ob.type+'&amp;quot; name=&amp;quot;question['+ob.id.to_s+'][type]&amp;quot; id=&amp;quot;question_'+ob.id.to_s+'_type&amp;quot; type=&amp;quot;text&amp;quot;&amp;gt;''&amp;lt;/td&amp;gt;'&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
The original code are commented out and insert the function call of the above function, html will be returned in the above function, see codes below:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def edit(count)&lt;br /&gt;
    html = edit_prefix(self, html)&lt;br /&gt;
    html+='&amp;lt;td&amp;gt;&amp;lt;!--placeholder (UnscoredQuestion does not need weight)--&amp;gt;&amp;lt;/td&amp;gt;'&lt;br /&gt;
    html+='&amp;lt;/tr&amp;gt;'&lt;br /&gt;
    html.html_safe&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
* Similar codes in view_question_text method are found in 4 other locations.&lt;br /&gt;
(dropdown.rb, questionnaire_header.rb, text_response.rb, upload_file.rb)&lt;br /&gt;
The solution to this problem is the same as above one, below is the function added in the most common superclass, which is Question, that contains the common parts of the codes found in the view_question_text methods in all five classes.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def view_qt_prefix(ob, html)&lt;br /&gt;
    html = '&amp;lt;TR&amp;gt;&amp;lt;TD align=&amp;quot;left&amp;quot;&amp;gt; '+ob.txt+ ' &amp;lt;/TD&amp;gt;'&lt;br /&gt;
    html += '&amp;lt;TD align=&amp;quot;left&amp;quot;&amp;gt;'+ob.type+'&amp;lt;/TD&amp;gt;'&lt;br /&gt;
    html += '&amp;lt;td align=&amp;quot;center&amp;quot;&amp;gt;'+ob.weight.to_s+'&amp;lt;/TD&amp;gt;'&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
The original code are commented out and insert the function call of the above function, html will be returned in the above function, see codes below:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def view_question_text&lt;br /&gt;
    html = view_qt_prefix(ob, html)&lt;br /&gt;
    html += '&amp;lt;TD align=&amp;quot;center&amp;quot;&amp;gt;Checked/Unchecked&amp;lt;/TD&amp;gt;'&lt;br /&gt;
    html += '&amp;lt;/TR&amp;gt;'&lt;br /&gt;
    html.html_safe&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Questionnaire_header.rb===&lt;br /&gt;
All problems in this file are solved after solving the problems found in checkbox.rb.&lt;br /&gt;
&lt;br /&gt;
===Upload_file.rb===&lt;br /&gt;
All problems in this file are solved after solving the problems found in checkbox.rb.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Unit-tests==&lt;br /&gt;
For each of the four required four question types (criterion.rb, scale.rb, checkbox.rb, upload_file.rb), there are four unit tests for the following four functions: ''edit'', ''complete'', ''view_question_text'', and ''view_complete_question_text''. Here are the spec files git hub links:&lt;br /&gt;
[https://github.com/schen35/expertiza/blob/master/spec/models/criterion_spec.rb criterion_spec.rb] [https://github.com/schen35/expertiza/blob/master/spec/models/scale_spec.rb scale_spec.rb] &lt;br /&gt;
[https://github.com/schen35/expertiza/blob/master/spec/models/checkbox_spec.rb checkbox_spec.rb] &lt;br /&gt;
[https://github.com/schen35/expertiza/blob/master/spec/models/upload_file_spec.rb upload_file_spec.rb].&lt;/div&gt;</summary>
		<author><name>Hguan2</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=MainPage&amp;diff=101312</id>
		<title>MainPage</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=MainPage&amp;diff=101312"/>
		<updated>2016-03-24T02:57:06Z</updated>

		<summary type="html">&lt;p&gt;Hguan2: Undo revision 101259 by Xpan (talk)&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Course-Specific Topics==&lt;br /&gt;
&lt;br /&gt;
* [[CSC/ECE 517 Summer 2008]]&lt;br /&gt;
* [[CSC/ECE 517 Fall 2010]]&lt;br /&gt;
* [[CSC/ECE 517 Fall 2011]]&lt;br /&gt;
* [[CSC/ECE 517 Fall 2012]]&lt;br /&gt;
* [[CSC/ECE 517 Fall 2013]]&lt;br /&gt;
* [[CSC/ECE 517 Fall 2014]]&lt;br /&gt;
* [[CSC/ECE 517 Fall 2015]]&lt;br /&gt;
* [[CSC/ECE 517 Spring 2014]]&lt;br /&gt;
* [[CSC/ECE 517 Spring 2015]]&lt;br /&gt;
* [[CSC/ECE 517 Spring 2016]]&lt;br /&gt;
* [[CSC 456 Spring 2011|CSC 456 Spring 2012]]&lt;br /&gt;
* [[ECE 633]]&lt;br /&gt;
* [[KCU]]&lt;br /&gt;
* [[Progress reports]]&lt;br /&gt;
&lt;br /&gt;
==Application Behavior==&lt;br /&gt;
* [[Grading]]&lt;br /&gt;
&lt;br /&gt;
==Metaprogramming==&lt;br /&gt;
* [[CSC/ECE_517_Spring_2013/ch1b_1k_hf|Lecture on Metaprogramming]]&lt;br /&gt;
&lt;br /&gt;
==Development==&lt;br /&gt;
&lt;br /&gt;
''Expertiza now has a Java dependency, so the machine you are using to develop Expertiza on should have the JVM installed.''&lt;br /&gt;
&lt;br /&gt;
* [[Setting Up a Development Machine]]&lt;br /&gt;
* [[Creating a Linux Development Environment for Expertiza - Installation Guide]]&lt;br /&gt;
* [[Using git and github for projects]]&lt;br /&gt;
* [[Using heroku to deploy your projects]]&lt;br /&gt;
* [[How to Begin a Project from the Current Expertiza Repository]]&lt;br /&gt;
* [[Git]]&lt;br /&gt;
* [[How to Change a User's Password on a Development Machine]]&lt;br /&gt;
* [[Debugging Rails]]&lt;br /&gt;
&lt;br /&gt;
==Production==&lt;br /&gt;
* [[Deploying to Production]]&lt;br /&gt;
* [[Downloading Production Data]]&lt;br /&gt;
* [[Accessing the Production Server]]&lt;br /&gt;
&lt;br /&gt;
==Testing==&lt;br /&gt;
* [[Using Cucumber with Expertiza]]&lt;br /&gt;
* [[Rails Testing Overview]]&lt;br /&gt;
* [[Expertiza Continuous Integration]]&lt;br /&gt;
&lt;br /&gt;
==References==&lt;br /&gt;
* [[Object-Oriented Design and Programming]]&lt;/div&gt;</summary>
		<author><name>Hguan2</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=MainPage&amp;diff=101311</id>
		<title>MainPage</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=MainPage&amp;diff=101311"/>
		<updated>2016-03-24T02:56:57Z</updated>

		<summary type="html">&lt;p&gt;Hguan2: Undo revision 101260 by Xpan (talk)&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Functional tests for assignment creation function Topics==&lt;br /&gt;
&lt;br /&gt;
* [[CSC/ECE 517 Summer 2008]]&lt;br /&gt;
* [[CSC/ECE 517 Fall 2010]]&lt;br /&gt;
* [[CSC/ECE 517 Fall 2011]]&lt;br /&gt;
* [[CSC/ECE 517 Fall 2012]]&lt;br /&gt;
* [[CSC/ECE 517 Fall 2013]]&lt;br /&gt;
* [[CSC/ECE 517 Fall 2014]]&lt;br /&gt;
* [[CSC/ECE 517 Fall 2015]]&lt;br /&gt;
* [[CSC/ECE 517 Spring 2014]]&lt;br /&gt;
* [[CSC/ECE 517 Spring 2015]]&lt;br /&gt;
* [[CSC/ECE 517 Spring 2016]]&lt;br /&gt;
* [[CSC 456 Spring 2011|CSC 456 Spring 2012]]&lt;br /&gt;
* [[ECE 633]]&lt;br /&gt;
* [[KCU]]&lt;br /&gt;
* [[Progress reports]]&lt;br /&gt;
&lt;br /&gt;
==Application Behavior==&lt;br /&gt;
* [[Grading]]&lt;br /&gt;
&lt;br /&gt;
==Metaprogramming==&lt;br /&gt;
* [[CSC/ECE_517_Spring_2013/ch1b_1k_hf|Lecture on Metaprogramming]]&lt;br /&gt;
&lt;br /&gt;
==Development==&lt;br /&gt;
&lt;br /&gt;
''Expertiza now has a Java dependency, so the machine you are using to develop Expertiza on should have the JVM installed.''&lt;br /&gt;
&lt;br /&gt;
* [[Setting Up a Development Machine]]&lt;br /&gt;
* [[Creating a Linux Development Environment for Expertiza - Installation Guide]]&lt;br /&gt;
* [[Using git and github for projects]]&lt;br /&gt;
* [[Using heroku to deploy your projects]]&lt;br /&gt;
* [[How to Begin a Project from the Current Expertiza Repository]]&lt;br /&gt;
* [[Git]]&lt;br /&gt;
* [[How to Change a User's Password on a Development Machine]]&lt;br /&gt;
* [[Debugging Rails]]&lt;br /&gt;
&lt;br /&gt;
==Production==&lt;br /&gt;
* [[Deploying to Production]]&lt;br /&gt;
* [[Downloading Production Data]]&lt;br /&gt;
* [[Accessing the Production Server]]&lt;br /&gt;
&lt;br /&gt;
==Testing==&lt;br /&gt;
* [[Using Cucumber with Expertiza]]&lt;br /&gt;
* [[Rails Testing Overview]]&lt;br /&gt;
* [[Expertiza Continuous Integration]]&lt;br /&gt;
&lt;br /&gt;
==References==&lt;br /&gt;
* [[Object-Oriented Design and Programming]]&lt;/div&gt;</summary>
		<author><name>Hguan2</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=MainPage&amp;diff=101310</id>
		<title>MainPage</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=MainPage&amp;diff=101310"/>
		<updated>2016-03-24T02:56:46Z</updated>

		<summary type="html">&lt;p&gt;Hguan2: Undo revision 101261 by Xpan (talk)&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Functional tests for assignment creation function==&lt;br /&gt;
&lt;br /&gt;
&amp;quot;General&amp;quot; tab function,&lt;br /&gt;
&amp;quot;Topics&amp;quot; tab function, you need to ensure topic creation functionality works.&lt;br /&gt;
&amp;quot;Rubrics&amp;quot; tab function, you need to test each questionnaire dropdowns, scored-question display style dropdowns, weight text fields and notification limit text fields and make sure they can be saved successfully.&lt;br /&gt;
&amp;quot;Due dates&amp;quot; tab function, you need to test “Date &amp;amp; time” date selectors and other action-allowed dropdowns and make sure they can be saved successfully.&lt;br /&gt;
==Application Behavior==&lt;br /&gt;
* [[Grading]]&lt;br /&gt;
&lt;br /&gt;
==Metaprogramming==&lt;br /&gt;
* [[CSC/ECE_517_Spring_2013/ch1b_1k_hf|Lecture on Metaprogramming]]&lt;br /&gt;
&lt;br /&gt;
==Development==&lt;br /&gt;
&lt;br /&gt;
''Expertiza now has a Java dependency, so the machine you are using to develop Expertiza on should have the JVM installed.''&lt;br /&gt;
&lt;br /&gt;
* [[Setting Up a Development Machine]]&lt;br /&gt;
* [[Creating a Linux Development Environment for Expertiza - Installation Guide]]&lt;br /&gt;
* [[Using git and github for projects]]&lt;br /&gt;
* [[Using heroku to deploy your projects]]&lt;br /&gt;
* [[How to Begin a Project from the Current Expertiza Repository]]&lt;br /&gt;
* [[Git]]&lt;br /&gt;
* [[How to Change a User's Password on a Development Machine]]&lt;br /&gt;
* [[Debugging Rails]]&lt;br /&gt;
&lt;br /&gt;
==Production==&lt;br /&gt;
* [[Deploying to Production]]&lt;br /&gt;
* [[Downloading Production Data]]&lt;br /&gt;
* [[Accessing the Production Server]]&lt;br /&gt;
&lt;br /&gt;
==Testing==&lt;br /&gt;
* [[Using Cucumber with Expertiza]]&lt;br /&gt;
* [[Rails Testing Overview]]&lt;br /&gt;
* [[Expertiza Continuous Integration]]&lt;br /&gt;
&lt;br /&gt;
==References==&lt;br /&gt;
* [[Object-Oriented Design and Programming]]&lt;/div&gt;</summary>
		<author><name>Hguan2</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=MainPage&amp;diff=101309</id>
		<title>MainPage</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=MainPage&amp;diff=101309"/>
		<updated>2016-03-24T02:56:34Z</updated>

		<summary type="html">&lt;p&gt;Hguan2: Undo revision 101262 by Xpan (talk)&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Functional tests for assignment creation function==&lt;br /&gt;
&lt;br /&gt;
&amp;quot;General&amp;quot; tab function,&lt;br /&gt;
&amp;quot;Topics&amp;quot; tab function, you need to ensure topic creation functionality works.&lt;br /&gt;
&amp;quot;Rubrics&amp;quot; tab function, you need to test each questionnaire dropdowns, scored-question display style dropdowns, weight text fields and notification limit text fields and make sure they can be saved successfully.&lt;br /&gt;
&amp;quot;Due dates&amp;quot; tab function, you need to test “Date &amp;amp; time” date selectors and other action-allowed dropdowns and make sure they can be saved successfully.&lt;br /&gt;
==Application Behavior==&lt;br /&gt;
* [[Grading]]&lt;br /&gt;
&lt;br /&gt;
==&amp;quot;General&amp;quot; tab function==&lt;br /&gt;
 you need to test assignment name, course, submission directory, description URL, ‘Has team?’, ‘Has quiz?’ and ‘Calibrated peer-review for training’ and make sure either text fields or checkboxes can be saved successfully.&lt;br /&gt;
&lt;br /&gt;
==&amp;quot;Topics&amp;quot; tab function==&lt;br /&gt;
&lt;br /&gt;
''Expertiza now has a Java dependency, so the machine you are using to develop Expertiza on should have the JVM installed.''&lt;br /&gt;
&lt;br /&gt;
* [[Setting Up a Development Machine]]&lt;br /&gt;
* [[Creating a Linux Development Environment for Expertiza - Installation Guide]]&lt;br /&gt;
* [[Using git and github for projects]]&lt;br /&gt;
* [[Using heroku to deploy your projects]]&lt;br /&gt;
* [[How to Begin a Project from the Current Expertiza Repository]]&lt;br /&gt;
* [[Git]]&lt;br /&gt;
* [[How to Change a User's Password on a Development Machine]]&lt;br /&gt;
* [[Debugging Rails]]&lt;br /&gt;
&lt;br /&gt;
==&amp;quot;Rubrics&amp;quot; tab function==&lt;br /&gt;
* [[Deploying to Production]]&lt;br /&gt;
* [[Downloading Production Data]]&lt;br /&gt;
* [[Accessing the Production Server]]&lt;br /&gt;
&lt;br /&gt;
==&amp;quot;Due dates&amp;quot; tab function==&lt;br /&gt;
* [[Using Cucumber with Expertiza]]&lt;br /&gt;
* [[Rails Testing Overview]]&lt;br /&gt;
* [[Expertiza Continuous Integration]]&lt;br /&gt;
&lt;br /&gt;
==References==&lt;br /&gt;
* [[Object-Oriented Design and Programming]]&lt;/div&gt;</summary>
		<author><name>Hguan2</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=MainPage&amp;diff=101308</id>
		<title>MainPage</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=MainPage&amp;diff=101308"/>
		<updated>2016-03-24T02:56:26Z</updated>

		<summary type="html">&lt;p&gt;Hguan2: Undo revision 101271 by Xpan (talk)&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Functional tests for assignment creation function==&lt;br /&gt;
&lt;br /&gt;
&amp;quot;General&amp;quot; tab function,&lt;br /&gt;
&amp;quot;Topics&amp;quot; tab function, you need to ensure topic creation functionality works.&lt;br /&gt;
&amp;quot;Rubrics&amp;quot; tab function, you need to test each questionnaire dropdowns, scored-question display style dropdowns, weight text fields and notification limit text fields and make sure they can be saved successfully.&lt;br /&gt;
&amp;quot;Due dates&amp;quot; tab function, you need to test “Date &amp;amp; time” date selectors and other action-allowed dropdowns and make sure they can be saved successfully.&lt;br /&gt;
==Application Behavior==&lt;br /&gt;
* [[Grading]]&lt;br /&gt;
&lt;br /&gt;
==&amp;quot;General&amp;quot; tab function==&lt;br /&gt;
 you need to test assignment name, course, submission directory, description URL, ‘Has team?’, ‘Has quiz?’ and ‘Calibrated peer-review for training’ and make sure either text fields or checkboxes can be saved successfully.&lt;br /&gt;
&lt;br /&gt;
==&amp;quot;Topics&amp;quot; tab function==&lt;br /&gt;
&lt;br /&gt;
==&amp;quot;Rubrics&amp;quot; tab function==&lt;br /&gt;
&lt;br /&gt;
==&amp;quot;Due dates&amp;quot; tab function==&lt;/div&gt;</summary>
		<author><name>Hguan2</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=MainPage&amp;diff=101307</id>
		<title>MainPage</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=MainPage&amp;diff=101307"/>
		<updated>2016-03-24T02:56:18Z</updated>

		<summary type="html">&lt;p&gt;Hguan2: Undo revision 101272 by Xpan (talk)&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Functional tests for assignment creation function==&lt;br /&gt;
&lt;br /&gt;
&amp;quot;General&amp;quot; tab function,&lt;br /&gt;
&amp;quot;Topics&amp;quot; tab function&lt;br /&gt;
&amp;quot;Rubrics&amp;quot; tab function&lt;br /&gt;
&amp;quot;Due dates&amp;quot; tab function&lt;br /&gt;
&lt;br /&gt;
==&amp;quot;General&amp;quot; tab function==&lt;br /&gt;
 you need to test assignment name, course, submission directory, description URL, ‘Has team?’, ‘Has quiz?’ and ‘Calibrated peer-review for training’ and make sure either text fields or checkboxes can be saved successfully.&lt;br /&gt;
&lt;br /&gt;
==&amp;quot;Topics&amp;quot; tab function==&lt;br /&gt;
&lt;br /&gt;
==&amp;quot;Rubrics&amp;quot; tab function==&lt;br /&gt;
&lt;br /&gt;
==&amp;quot;Due dates&amp;quot; tab function==&lt;/div&gt;</summary>
		<author><name>Hguan2</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=MainPage&amp;diff=101306</id>
		<title>MainPage</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=MainPage&amp;diff=101306"/>
		<updated>2016-03-24T02:56:04Z</updated>

		<summary type="html">&lt;p&gt;Hguan2: Undo revision 101274 by Xpan (talk)&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Functional tests for assignment creation function==&lt;br /&gt;
&lt;br /&gt;
*&amp;quot;General&amp;quot; tab function,&lt;br /&gt;
*&amp;quot;Topics&amp;quot; tab function,&lt;br /&gt;
*&amp;quot;Rubrics&amp;quot; tab function,&lt;br /&gt;
*&amp;quot;Due dates&amp;quot; tab function,&lt;br /&gt;
&lt;br /&gt;
==&amp;quot;General&amp;quot; tab function==&lt;br /&gt;
 you need to test assignment name, course, submission directory, description URL, ‘Has team?’, ‘Has quiz?’ and ‘Calibrated peer-review for training’ and make sure either text fields or checkboxes can be saved successfully.&lt;br /&gt;
&lt;br /&gt;
==&amp;quot;Topics&amp;quot; tab function==&lt;br /&gt;
&lt;br /&gt;
==&amp;quot;Rubrics&amp;quot; tab function==&lt;br /&gt;
&lt;br /&gt;
==&amp;quot;Due dates&amp;quot; tab function==&lt;/div&gt;</summary>
		<author><name>Hguan2</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=MainPage&amp;diff=101305</id>
		<title>MainPage</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=MainPage&amp;diff=101305"/>
		<updated>2016-03-24T02:55:55Z</updated>

		<summary type="html">&lt;p&gt;Hguan2: Undo revision 101285 by Xpan (talk)&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Functional tests for assignment creation function==&lt;br /&gt;
&lt;br /&gt;
*&amp;quot;General&amp;quot; tab function,&lt;br /&gt;
*&amp;quot;Topics&amp;quot; tab function,&lt;br /&gt;
*&amp;quot;Rubrics&amp;quot; tab function,&lt;br /&gt;
*&amp;quot;Due dates&amp;quot; tab function,&lt;br /&gt;
&lt;br /&gt;
==&amp;quot;General&amp;quot; tab function==&lt;br /&gt;
you need to test assignment name, course, submission directory, description URL, ‘Has team?’, ‘Has quiz?’ and ‘Calibrated peer-review for training’ and make sure either text fields or checkboxes can be saved successfully.&lt;br /&gt;
&lt;br /&gt;
==&amp;quot;Topics&amp;quot; tab function==&lt;br /&gt;
&lt;br /&gt;
==&amp;quot;Rubrics&amp;quot; tab function==&lt;br /&gt;
&lt;br /&gt;
==&amp;quot;Due dates&amp;quot; tab function==&lt;/div&gt;</summary>
		<author><name>Hguan2</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=MainPage&amp;diff=101304</id>
		<title>MainPage</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=MainPage&amp;diff=101304"/>
		<updated>2016-03-24T02:55:46Z</updated>

		<summary type="html">&lt;p&gt;Hguan2: Undo revision 101287 by Xpan (talk)&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Functional tests for assignment creation function==&lt;br /&gt;
&lt;br /&gt;
*&amp;quot;General&amp;quot; tab function,&lt;br /&gt;
*&amp;quot;Topics&amp;quot; tab function,&lt;br /&gt;
*&amp;quot;Rubrics&amp;quot; tab function,&lt;br /&gt;
*&amp;quot;Due dates&amp;quot; tab function,&lt;br /&gt;
&lt;br /&gt;
==&amp;quot;General&amp;quot; tab function==&lt;br /&gt;
In this section, the functional test includes assignment name, course, submission directory, description URL, &amp;quot;Has team?&amp;quot;, &amp;quot;Has quiz?&amp;quot; and &amp;quot;Calibrated peer-review for training&amp;quot;.&lt;br /&gt;
*assignment name&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==&amp;quot;Topics&amp;quot; tab function==&lt;br /&gt;
&lt;br /&gt;
==&amp;quot;Rubrics&amp;quot; tab function==&lt;br /&gt;
&lt;br /&gt;
==&amp;quot;Due dates&amp;quot; tab function==&lt;/div&gt;</summary>
		<author><name>Hguan2</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=MainPage&amp;diff=101303</id>
		<title>MainPage</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=MainPage&amp;diff=101303"/>
		<updated>2016-03-24T02:55:33Z</updated>

		<summary type="html">&lt;p&gt;Hguan2: Undo revision 101294 by Xpan (talk)&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Functional tests for assignment creation function==&lt;br /&gt;
&lt;br /&gt;
*&amp;quot;General&amp;quot; tab function,&lt;br /&gt;
*&amp;quot;Topics&amp;quot; tab function,&lt;br /&gt;
*&amp;quot;Rubrics&amp;quot; tab function,&lt;br /&gt;
*&amp;quot;Due dates&amp;quot; tab function,&lt;br /&gt;
&lt;br /&gt;
==&amp;quot;General&amp;quot; tab function==&lt;br /&gt;
In this section, the functional test includes assignment name, course, submission directory, description URL, &amp;quot;Has team?&amp;quot;, &amp;quot;Has quiz?&amp;quot; and &amp;quot;Calibrated peer-review for training&amp;quot;.&lt;br /&gt;
*assignment name&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    it &amp;quot;can set assginment name&amp;quot; do&lt;br /&gt;
      login_as(&amp;quot;instructor6&amp;quot;)&lt;br /&gt;
      visit '/assignments/new?private=0'&lt;br /&gt;
      expect(page).to have_content &amp;quot;Assignment name&amp;quot;&lt;br /&gt;
      fill_in &amp;quot;Assignment name:&amp;quot;, with: 'assignment for test'&lt;br /&gt;
      click_button &amp;quot;Create&amp;quot;&lt;br /&gt;
      expect(Assignment.where(name: &amp;quot;assignment for test&amp;quot;)).to exist&lt;br /&gt;
    end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
*course&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    it &amp;quot;can select course&amp;quot; do&lt;br /&gt;
      login_as(&amp;quot;instructor6&amp;quot;)&lt;br /&gt;
      visit '/assignments/new?private=0'&lt;br /&gt;
      select('5', :from =&amp;gt; 'assignment_form_assignment_course_id')&lt;br /&gt;
      click_button &amp;quot;Create&amp;quot;&lt;br /&gt;
    end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
==&amp;quot;Topics&amp;quot; tab function==&lt;br /&gt;
&lt;br /&gt;
==&amp;quot;Rubrics&amp;quot; tab function==&lt;br /&gt;
&lt;br /&gt;
==&amp;quot;Due dates&amp;quot; tab function==&lt;/div&gt;</summary>
		<author><name>Hguan2</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=MainPage&amp;diff=101302</id>
		<title>MainPage</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=MainPage&amp;diff=101302"/>
		<updated>2016-03-24T02:55:11Z</updated>

		<summary type="html">&lt;p&gt;Hguan2: Undo revision 101297 by Xpan (talk)&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Functional tests for assignment creation function==&lt;br /&gt;
&lt;br /&gt;
*&amp;quot;General&amp;quot; tab function,&lt;br /&gt;
*&amp;quot;Topics&amp;quot; tab function,&lt;br /&gt;
*&amp;quot;Rubrics&amp;quot; tab function,&lt;br /&gt;
*&amp;quot;Due dates&amp;quot; tab function,&lt;br /&gt;
&lt;br /&gt;
==&amp;quot;General&amp;quot; tab function==&lt;br /&gt;
In this section, the functional test includes assignment name, course, submission directory, description URL, &amp;quot;Has team?&amp;quot;, &amp;quot;Has quiz?&amp;quot; and &amp;quot;Calibrated peer-review for training&amp;quot;.&lt;br /&gt;
*assignment name&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    it &amp;quot;can set assginment name&amp;quot; do&lt;br /&gt;
      login_as(&amp;quot;instructor6&amp;quot;)&lt;br /&gt;
      visit '/assignments/new?private=0'&lt;br /&gt;
      expect(page).to have_content &amp;quot;Assignment name&amp;quot;&lt;br /&gt;
      fill_in &amp;quot;Assignment name:&amp;quot;, with: 'assignment for test'&lt;br /&gt;
      click_button &amp;quot;Create&amp;quot;&lt;br /&gt;
      expect(Assignment.where(name: &amp;quot;assignment for test&amp;quot;)).to exist&lt;br /&gt;
    end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
*course&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    it &amp;quot;can select course&amp;quot; do&lt;br /&gt;
      login_as(&amp;quot;instructor6&amp;quot;)&lt;br /&gt;
      visit '/assignments/new?private=0'&lt;br /&gt;
      select('5', :from =&amp;gt; 'assignment_form_assignment_course_id')&lt;br /&gt;
      click_button &amp;quot;Create&amp;quot;&lt;br /&gt;
    end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
*submission directory&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    it &amp;quot;can set assginment Submission directory&amp;quot; do&lt;br /&gt;
      login_as(&amp;quot;instructor6&amp;quot;)&lt;br /&gt;
      visit '/assignments/new?private=0'&lt;br /&gt;
      fill_in &amp;quot;Assignment name:&amp;quot;, with: 'assignment for test 2'&lt;br /&gt;
      expect(page).to have_content &amp;quot;Submission directory&amp;quot;&lt;br /&gt;
      fill_in &amp;quot;Submission directory:&amp;quot;, with: 'Submission directory for test'&lt;br /&gt;
      click_button &amp;quot;Create&amp;quot;&lt;br /&gt;
      expect(Assignment.find(2).directory_path).to eq 'Submission directory for test'&lt;br /&gt;
    end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
*description URL&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    it &amp;quot;can set assginment Description URL&amp;quot; do&lt;br /&gt;
      login_as(&amp;quot;instructor6&amp;quot;)&lt;br /&gt;
      visit '/assignments/new?private=0'&lt;br /&gt;
      fill_in &amp;quot;Assignment name:&amp;quot;, with: 'assignment for test 3'&lt;br /&gt;
      expect(page).to have_content &amp;quot;Description URL&amp;quot;&lt;br /&gt;
      fill_in &amp;quot;Description URL:&amp;quot;, with: 'Description URL for test'&lt;br /&gt;
      click_button &amp;quot;Create&amp;quot;&lt;br /&gt;
      expect(Assignment.find(2).spec_location).to eq 'Description URL for test'&lt;br /&gt;
    end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
*&amp;quot;Has team?&amp;quot;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    it &amp;quot;can Has teams and set team number&amp;quot; do&lt;br /&gt;
      login_as(&amp;quot;instructor6&amp;quot;)&lt;br /&gt;
      visit '/assignments/new?private=0'&lt;br /&gt;
      fill_in &amp;quot;Assignment name:&amp;quot;, with: 'assignment for test 5'&lt;br /&gt;
      find('#team_assignment').set(true)&lt;br /&gt;
      expect(page).to have_content &amp;quot;Maximum number of members per team&amp;quot;&lt;br /&gt;
      expect(page).to have_content &amp;quot;Show teammate reviews&amp;quot;&lt;br /&gt;
      fill_in 'assignment_form_assignment_max_team_size', with: 4&lt;br /&gt;
      find('#assignment_form_assignment_show_teammate_reviews').set(true)&lt;br /&gt;
      click_button &amp;quot;Create&amp;quot;&lt;br /&gt;
      expect(Assignment.find(2).show_teammate_reviews).to eq true&lt;br /&gt;
    end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
*&amp;quot;Has quiz?&amp;quot;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    it &amp;quot;can save the number of quiz questions&amp;quot; do&lt;br /&gt;
      login_as(&amp;quot;instructor6&amp;quot;)&lt;br /&gt;
      visit '/assignments/new?private=0'&lt;br /&gt;
      fill_in &amp;quot;Assignment name:&amp;quot;, with: '11'&lt;br /&gt;
      select('5', :from =&amp;gt; 'assignment_form_assignment_course_id')&lt;br /&gt;
      find('#assignment_form_assignment_require_quiz').set(true)&lt;br /&gt;
      click_button &amp;quot;Create&amp;quot;&lt;br /&gt;
      visit '/assignments/2/edit'&lt;br /&gt;
      expect(page).to have_content &amp;quot;Number of Quiz questions&amp;quot;&lt;br /&gt;
    end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
*&amp;quot;Calibrated peer-review for training&amp;quot;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    it &amp;quot;can set Calibrated peer-view for training&amp;quot; do&lt;br /&gt;
      login_as(&amp;quot;instructor6&amp;quot;)&lt;br /&gt;
      visit '/assignments/new?private=0'&lt;br /&gt;
      fill_in &amp;quot;Assignment name:&amp;quot;, with: 'assignment for test 4'&lt;br /&gt;
      find('#assignment_form_assignment_is_calibrated').set(true)&lt;br /&gt;
      click_button &amp;quot;Create&amp;quot;&lt;br /&gt;
      expect(Assignment.find(2).is_calibrated).to eq true&lt;br /&gt;
    end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
==&amp;quot;Topics&amp;quot; tab function==&lt;br /&gt;
&lt;br /&gt;
==&amp;quot;Rubrics&amp;quot; tab function==&lt;br /&gt;
&lt;br /&gt;
==&amp;quot;Due dates&amp;quot; tab function==&lt;/div&gt;</summary>
		<author><name>Hguan2</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=MainPage&amp;diff=101300</id>
		<title>MainPage</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=MainPage&amp;diff=101300"/>
		<updated>2016-03-24T02:51:27Z</updated>

		<summary type="html">&lt;p&gt;Hguan2: Undo revision 101298 by Xpan (talk)&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Functional tests for assignment creation function==&lt;br /&gt;
&lt;br /&gt;
*&amp;quot;General&amp;quot; tab function,&lt;br /&gt;
*&amp;quot;Topics&amp;quot; tab function,&lt;br /&gt;
*&amp;quot;Rubrics&amp;quot; tab function,&lt;br /&gt;
*&amp;quot;Due dates&amp;quot; tab function,&lt;br /&gt;
&lt;br /&gt;
==&amp;quot;General&amp;quot; tab function==&lt;br /&gt;
In this section, the functional test includes assignment name, course, submission directory, description URL, &amp;quot;Has team?&amp;quot;, &amp;quot;Has quiz?&amp;quot; and &amp;quot;Calibrated peer-review for training&amp;quot;.&lt;br /&gt;
*assignment name&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    it &amp;quot;can set assginment name&amp;quot; do&lt;br /&gt;
      login_as(&amp;quot;instructor6&amp;quot;)&lt;br /&gt;
      visit '/assignments/new?private=0'&lt;br /&gt;
      expect(page).to have_content &amp;quot;Assignment name&amp;quot;&lt;br /&gt;
      fill_in &amp;quot;Assignment name:&amp;quot;, with: 'assignment for test'&lt;br /&gt;
      click_button &amp;quot;Create&amp;quot;&lt;br /&gt;
      expect(Assignment.where(name: &amp;quot;assignment for test&amp;quot;)).to exist&lt;br /&gt;
    end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
*course&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    it &amp;quot;can select course&amp;quot; do&lt;br /&gt;
      login_as(&amp;quot;instructor6&amp;quot;)&lt;br /&gt;
      visit '/assignments/new?private=0'&lt;br /&gt;
      select('5', :from =&amp;gt; 'assignment_form_assignment_course_id')&lt;br /&gt;
      click_button &amp;quot;Create&amp;quot;&lt;br /&gt;
    end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
==&amp;quot;Topics&amp;quot; tab function==&lt;br /&gt;
&lt;br /&gt;
==&amp;quot;Rubrics&amp;quot; tab function==&lt;br /&gt;
&lt;br /&gt;
==&amp;quot;Due dates&amp;quot; tab function==&lt;/div&gt;</summary>
		<author><name>Hguan2</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2016/Refactor_and_write_unit_tests_for_question_type.rb&amp;diff=100986</id>
		<title>CSC/ECE 517 Spring 2016/Refactor and write unit tests for question type.rb</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2016/Refactor_and_write_unit_tests_for_question_type.rb&amp;diff=100986"/>
		<updated>2016-03-21T21:11:00Z</updated>

		<summary type="html">&lt;p&gt;Hguan2: /* Our contribution */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This wiki page is for the description of changes made under E1608 OSS assignment for Spring 2016, CSC/ECE 517. The assignment task is to  refactor &amp;amp; write unit tests for [question_type].rb (eg. criterion.rb).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Problem Statement ==&lt;br /&gt;
===Files related===&lt;br /&gt;
Four models is related: criterion.rb, scale.rb, checkbox.rb, questionnaire_header.rb, upload_file.rb. There are 4 methods “edit”, “view_question_text”, “complete” and “view_completed_question” correspond to different views. &lt;br /&gt;
&lt;br /&gt;
*edit ~&amp;gt;	when instructor add/edit new questions&lt;br /&gt;
*view ~&amp;gt; when instructor view existed questions&lt;br /&gt;
*complete ~&amp;gt; when students do peer reviews&lt;br /&gt;
*view_completed_question ~&amp;gt; when student view existed peer reviews&lt;br /&gt;
&lt;br /&gt;
===Expertiza question types inheritance hierarchy===&lt;br /&gt;
&lt;br /&gt;
*Choice question&lt;br /&gt;
**Scored question&lt;br /&gt;
***Scale&lt;br /&gt;
***Criterion&lt;br /&gt;
**Unscored question&lt;br /&gt;
***Dropdown&lt;br /&gt;
***CheckBox&lt;br /&gt;
*TextResponse&lt;br /&gt;
**TextArea&lt;br /&gt;
**TextField&lt;br /&gt;
*UploadFile&lt;br /&gt;
&lt;br /&gt;
===Files problem===&lt;br /&gt;
&lt;br /&gt;
There are some issues in each file, such as security, complexity, duplication, etc. And currently there is no unit tests for [question_type].rb.&lt;br /&gt;
&lt;br /&gt;
===Our contribution===&lt;br /&gt;
*Refactor these [question_type].rb files and fix issues.&lt;br /&gt;
*Keep the inputs and outputs of these methods (edit, view, complete, view_completed_question) the same as before.&lt;br /&gt;
*Write unit tests for [question_type].rb listed above.&lt;br /&gt;
*Create RSpec files for each question type in /spec/models/ folder&lt;br /&gt;
*Create multiple tests to check valid and invalid cases, such as input including special character double quote (“”).&lt;/div&gt;</summary>
		<author><name>Hguan2</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2016/Refactor_and_write_unit_tests_for_question_type.rb&amp;diff=100985</id>
		<title>CSC/ECE 517 Spring 2016/Refactor and write unit tests for question type.rb</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2016/Refactor_and_write_unit_tests_for_question_type.rb&amp;diff=100985"/>
		<updated>2016-03-21T21:10:06Z</updated>

		<summary type="html">&lt;p&gt;Hguan2: /* Problem Statement */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This wiki page is for the description of changes made under E1608 OSS assignment for Spring 2016, CSC/ECE 517. The assignment task is to  refactor &amp;amp; write unit tests for [question_type].rb (eg. criterion.rb).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Problem Statement ==&lt;br /&gt;
===Files related===&lt;br /&gt;
Four models is related: criterion.rb, scale.rb, checkbox.rb, questionnaire_header.rb, upload_file.rb. There are 4 methods “edit”, “view_question_text”, “complete” and “view_completed_question” correspond to different views. &lt;br /&gt;
&lt;br /&gt;
*edit ~&amp;gt;	when instructor add/edit new questions&lt;br /&gt;
*view ~&amp;gt; when instructor view existed questions&lt;br /&gt;
*complete ~&amp;gt; when students do peer reviews&lt;br /&gt;
*view_completed_question ~&amp;gt; when student view existed peer reviews&lt;br /&gt;
&lt;br /&gt;
===Expertiza question types inheritance hierarchy===&lt;br /&gt;
&lt;br /&gt;
*Choice question&lt;br /&gt;
**Scored question&lt;br /&gt;
***Scale&lt;br /&gt;
***Criterion&lt;br /&gt;
**Unscored question&lt;br /&gt;
***Dropdown&lt;br /&gt;
***CheckBox&lt;br /&gt;
*TextResponse&lt;br /&gt;
**TextArea&lt;br /&gt;
**TextField&lt;br /&gt;
*UploadFile&lt;br /&gt;
&lt;br /&gt;
===Files problem===&lt;br /&gt;
&lt;br /&gt;
There are some issues in each file, such as security, complexity, duplication, etc. And currently there is no unit tests for [question_type].rb.&lt;br /&gt;
&lt;br /&gt;
===Our contribution===&lt;br /&gt;
Refactor these [question_type].rb files and fix issues.&lt;br /&gt;
Keep the inputs and outputs of these methods (edit, view, complete, view_completed_question) the same as before.&lt;br /&gt;
Write unit tests for [question_type].rb listed above.&lt;br /&gt;
Create RSpec files for each question type in /spec/models/ folder&lt;br /&gt;
Create multiple tests to check valid and invalid cases, such as input including special character double quote (“”).&lt;/div&gt;</summary>
		<author><name>Hguan2</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2016/Refactor_and_write_unit_tests_for_question_type.rb&amp;diff=100984</id>
		<title>CSC/ECE 517 Spring 2016/Refactor and write unit tests for question type.rb</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2016/Refactor_and_write_unit_tests_for_question_type.rb&amp;diff=100984"/>
		<updated>2016-03-21T21:09:15Z</updated>

		<summary type="html">&lt;p&gt;Hguan2: /* Problem Statement */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This wiki page is for the description of changes made under E1608 OSS assignment for Spring 2016, CSC/ECE 517. The assignment task is to  refactor &amp;amp; write unit tests for [question_type].rb (eg. criterion.rb).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Problem Statement ==&lt;br /&gt;
Files involved: criterion.rb, scale.rb, checkbox.rb, questionnaire_header.rb, upload_file.rb. There are 4 methods “edit”, “view_question_text”, “complete” and “view_completed_question” correspond to different views. &lt;br /&gt;
&lt;br /&gt;
*edit ~&amp;gt;	when instructor add/edit new questions&lt;br /&gt;
*view ~&amp;gt; when instructor view existed questions&lt;br /&gt;
*complete ~&amp;gt; when students do peer reviews&lt;br /&gt;
*view_completed_question ~&amp;gt; when student view existed peer reviews&lt;br /&gt;
&lt;br /&gt;
===Expertiza question types inheritance hierarchy===&lt;br /&gt;
&lt;br /&gt;
*Choice question&lt;br /&gt;
**Scored question&lt;br /&gt;
***Scale&lt;br /&gt;
***Criterion&lt;br /&gt;
**Unscored question&lt;br /&gt;
***Dropdown&lt;br /&gt;
***CheckBox&lt;br /&gt;
*TextResponse&lt;br /&gt;
**TextArea&lt;br /&gt;
**TextField&lt;br /&gt;
*UploadFile&lt;br /&gt;
&lt;br /&gt;
===Files problem===&lt;br /&gt;
&lt;br /&gt;
There are some issues in each file, such as security, complexity, duplication, etc. And currently there is no unit tests for [question_type].rb.&lt;br /&gt;
&lt;br /&gt;
===Our contribution===&lt;br /&gt;
Refactor these [question_type].rb files and fix issues.&lt;br /&gt;
Keep the inputs and outputs of these methods (edit, view, complete, view_completed_question) the same as before.&lt;br /&gt;
Write unit tests for [question_type].rb listed above.&lt;br /&gt;
Create RSpec files for each question type in /spec/models/ folder&lt;br /&gt;
Create multiple tests to check valid and invalid cases, such as input including special character double quote (“”).&lt;/div&gt;</summary>
		<author><name>Hguan2</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2016/Refactor_and_write_unit_tests_for_question_type.rb&amp;diff=100983</id>
		<title>CSC/ECE 517 Spring 2016/Refactor and write unit tests for question type.rb</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2016/Refactor_and_write_unit_tests_for_question_type.rb&amp;diff=100983"/>
		<updated>2016-03-21T21:05:26Z</updated>

		<summary type="html">&lt;p&gt;Hguan2: /* Problem Statement */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This wiki page is for the description of changes made under E1608 OSS assignment for Spring 2016, CSC/ECE 517. The assignment task is to  refactor &amp;amp; write unit tests for [question_type].rb (eg. criterion.rb).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Problem Statement ==&lt;br /&gt;
Files involved: criterion.rb, scale.rb, checkbox.rb, questionnaire_header.rb, upload_file.rb. There are 4 methods “edit”, “view_question_text”, “complete” and “view_completed_question” correspond to different views. &lt;br /&gt;
&lt;br /&gt;
*edit ~&amp;gt;	when instructor add/edit new questions&lt;br /&gt;
*view ~&amp;gt; when instructor view existed questions&lt;br /&gt;
*complete ~&amp;gt; when students do peer reviews&lt;br /&gt;
*view_completed_question ~&amp;gt; when student view existed peer reviews&lt;br /&gt;
&lt;br /&gt;
Expertiza question types inheritance hierarchy&lt;br /&gt;
*Choice question&lt;br /&gt;
**Scored question&lt;br /&gt;
***Scale&lt;br /&gt;
***Criterion&lt;br /&gt;
**Unscored question&lt;br /&gt;
***Dropdown&lt;br /&gt;
***CheckBox&lt;br /&gt;
**TextResponse&lt;br /&gt;
***TextArea&lt;br /&gt;
***TextField&lt;br /&gt;
*UploadFile&lt;br /&gt;
&lt;br /&gt;
What’s wrong with it:  You can click these [question_type].rb files listed above. These links will redirect to Code Climate. You need to fix these issues in each file, such as security, complexity, duplication, etc. And currently there is no unit tests for [question_type].rb.&lt;br /&gt;
What needs to be done:&lt;br /&gt;
Refactor these [question_type].rb files and fix issues.&lt;br /&gt;
Keep the inputs and outputs of these methods (edit, view, complete, view_completed_question) the same as before.&lt;br /&gt;
Write unit tests for [question_type].rb listed above.&lt;br /&gt;
Create RSpec files for each question type in /spec/models/ folder&lt;br /&gt;
Create multiple tests to check valid and invalid cases, such as input including special character double quote (“”).&lt;/div&gt;</summary>
		<author><name>Hguan2</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2016/Refactor_and_write_unit_tests_for_question_type.rb&amp;diff=100982</id>
		<title>CSC/ECE 517 Spring 2016/Refactor and write unit tests for question type.rb</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2016/Refactor_and_write_unit_tests_for_question_type.rb&amp;diff=100982"/>
		<updated>2016-03-21T21:04:46Z</updated>

		<summary type="html">&lt;p&gt;Hguan2: /* Problem Statement */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This wiki page is for the description of changes made under E1608 OSS assignment for Spring 2016, CSC/ECE 517. The assignment task is to  refactor &amp;amp; write unit tests for [question_type].rb (eg. criterion.rb).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Problem Statement ==&lt;br /&gt;
Files involved: criterion.rb, scale.rb, checkbox.rb, questionnaire_header.rb, upload_file.rb. There are 4 methods “edit”, “view_question_text”, “complete” and “view_completed_question” correspond to different views. &lt;br /&gt;
&lt;br /&gt;
*edit ~&amp;gt;	when instructor add/edit new questions&lt;br /&gt;
*view ~&amp;gt; when instructor view existed questions&lt;br /&gt;
*complete ~&amp;gt; when students do peer reviews&lt;br /&gt;
*view_completed_question ~&amp;gt; when student view existed peer reviews&lt;br /&gt;
&lt;br /&gt;
Expertiza question types inheritance hierarchy&lt;br /&gt;
*Choice question&lt;br /&gt;
**Scored question&lt;br /&gt;
***Scale&lt;br /&gt;
***Criterion&lt;br /&gt;
Unscored question&lt;br /&gt;
Dropdown&lt;br /&gt;
CheckBox&lt;br /&gt;
TextResponse&lt;br /&gt;
TextArea&lt;br /&gt;
TextField&lt;br /&gt;
UploadFile&lt;br /&gt;
&lt;br /&gt;
What’s wrong with it:  You can click these [question_type].rb files listed above. These links will redirect to Code Climate. You need to fix these issues in each file, such as security, complexity, duplication, etc. And currently there is no unit tests for [question_type].rb.&lt;br /&gt;
What needs to be done:&lt;br /&gt;
Refactor these [question_type].rb files and fix issues.&lt;br /&gt;
Keep the inputs and outputs of these methods (edit, view, complete, view_completed_question) the same as before.&lt;br /&gt;
Write unit tests for [question_type].rb listed above.&lt;br /&gt;
Create RSpec files for each question type in /spec/models/ folder&lt;br /&gt;
Create multiple tests to check valid and invalid cases, such as input including special character double quote (“”).&lt;/div&gt;</summary>
		<author><name>Hguan2</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2016/Refactor_and_write_unit_tests_for_question_type.rb&amp;diff=100981</id>
		<title>CSC/ECE 517 Spring 2016/Refactor and write unit tests for question type.rb</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2016/Refactor_and_write_unit_tests_for_question_type.rb&amp;diff=100981"/>
		<updated>2016-03-21T21:03:02Z</updated>

		<summary type="html">&lt;p&gt;Hguan2: problem statement&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This wiki page is for the description of changes made under E1608 OSS assignment for Spring 2016, CSC/ECE 517. The assignment task is to  refactor &amp;amp; write unit tests for [question_type].rb (eg. criterion.rb).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Problem Statement ==&lt;br /&gt;
Files involved: criterion.rb, scale.rb, checkbox.rb, questionnaire_header.rb, upload_file.rb. There are 4 methods “edit”, “view_question_text”, “complete” and “view_completed_question” correspond to different views. &lt;br /&gt;
&lt;br /&gt;
edit ~&amp;gt;	when instructor add/edit new questions&lt;br /&gt;
view ~&amp;gt; when instructor view existed questions&lt;br /&gt;
complete ~&amp;gt; when students do peer reviews&lt;br /&gt;
view_completed_question ~&amp;gt; when student view existed peer reviews&lt;br /&gt;
&lt;br /&gt;
Expertiza question types inheritance hierarchy&lt;br /&gt;
Choice question&lt;br /&gt;
Scored question&lt;br /&gt;
Scale&lt;br /&gt;
Criterion&lt;br /&gt;
Unscored question&lt;br /&gt;
Dropdown&lt;br /&gt;
CheckBox&lt;br /&gt;
TextResponse&lt;br /&gt;
TextArea&lt;br /&gt;
TextField&lt;br /&gt;
UploadFile&lt;br /&gt;
&lt;br /&gt;
What’s wrong with it:  You can click these [question_type].rb files listed above. These links will redirect to Code Climate. You need to fix these issues in each file, such as security, complexity, duplication, etc. And currently there is no unit tests for [question_type].rb.&lt;br /&gt;
What needs to be done:&lt;br /&gt;
Refactor these [question_type].rb files and fix issues.&lt;br /&gt;
Keep the inputs and outputs of these methods (edit, view, complete, view_completed_question) the same as before.&lt;br /&gt;
Write unit tests for [question_type].rb listed above.&lt;br /&gt;
Create RSpec files for each question type in /spec/models/ folder&lt;br /&gt;
Create multiple tests to check valid and invalid cases, such as input including special character double quote (“”).&lt;/div&gt;</summary>
		<author><name>Hguan2</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2016/Refactor_and_write_unit_tests_for_question_type.rb&amp;diff=100980</id>
		<title>CSC/ECE 517 Spring 2016/Refactor and write unit tests for question type.rb</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2016/Refactor_and_write_unit_tests_for_question_type.rb&amp;diff=100980"/>
		<updated>2016-03-21T20:59:11Z</updated>

		<summary type="html">&lt;p&gt;Hguan2: test&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This wiki page is for the description of changes made under E1608OSS assignment for Spring 2016, CSC/ECE 517.&lt;/div&gt;</summary>
		<author><name>Hguan2</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2016/Refactor_and_write_unit_tests_for_question_type.rb&amp;diff=100978</id>
		<title>CSC/ECE 517 Spring 2016/Refactor and write unit tests for question type.rb</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2016/Refactor_and_write_unit_tests_for_question_type.rb&amp;diff=100978"/>
		<updated>2016-03-21T20:13:51Z</updated>

		<summary type="html">&lt;p&gt;Hguan2: initialize&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;E1608.  Refactor &amp;amp; write unit tests for [question_type].rb (eg. criterion.rb)&lt;br /&gt;
Contact: Zhewei Hu (zhu6@ncsu.edu)&lt;br /&gt;
What it does:  In last summer we refactored different class of questions to make them follow the same design (you can take a look on Criterion.rb): there are 4 methods “edit”, “view_question_text”, “complete” and “view_completed_question” correspond to different views. &lt;br /&gt;
Files involved: criterion.rb, scale.rb, checkbox.rb, questionnaire_header.rb, upload_file.rb&lt;br /&gt;
edit ~&amp;gt;	when instructor add/edit new questions&lt;br /&gt;
view ~&amp;gt; when instructor view existed questions&lt;br /&gt;
complete ~&amp;gt; when students do peer reviews&lt;br /&gt;
view_completed_question ~&amp;gt; when student view existed peer reviews&lt;br /&gt;
Expertiza question types inheritance hierarchy&lt;br /&gt;
Choice question&lt;br /&gt;
Scored question&lt;br /&gt;
Scale&lt;br /&gt;
Criterion&lt;br /&gt;
Unscored question&lt;br /&gt;
Dropdown&lt;br /&gt;
CheckBox&lt;br /&gt;
TextResponse&lt;br /&gt;
TextArea&lt;br /&gt;
TextField&lt;br /&gt;
UploadFile&lt;br /&gt;
What’s wrong with it:  You can click these [question_type].rb files listed above. These links will redirect to Code Climate. You need to fix these issues in each file, such as security, complexity, duplication, etc. And currently there is no unit tests for [question_type].rb.&lt;br /&gt;
What needs to be done:&lt;br /&gt;
Refactor these [question_type].rb files and fix issues.&lt;br /&gt;
Keep the inputs and outputs of these methods (edit, view, complete, view_completed_question) the same as before.&lt;br /&gt;
Write unit tests for [question_type].rb listed above.&lt;br /&gt;
Create RSpec files for each question type in /spec/models/ folder&lt;br /&gt;
Create multiple tests to check valid and invalid cases, such as input including special character double quote (“”).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
�&lt;br /&gt;
&lt;br /&gt;
What needs to be done:&lt;br /&gt;
Refactor&lt;br /&gt;
Criterion.rb&lt;br /&gt;
1. Method has too many lines: Line 35 - 158 [106/30]&lt;br /&gt;
2. Cyclomatic complexity for complete is too high: Line 35 - 158 [28/6]&lt;br /&gt;
3. Identical code found in 1 other location: Line 20 - 32 (mass = 89)&lt;br /&gt;
4. Identical code found in 1 other location: Line 135 - 139 (mass = 50)&lt;br /&gt;
5. Identical code found in 1 other location Line 13 - 14 (mass = 40)&lt;br /&gt;
6.  Similar code found in 1 other location Line 103 - 105 (mass = 26)&lt;br /&gt;
7. Similar code found in 2 other locations Line 152 - 153 (mass = 22)&lt;br /&gt;
8. Similar code found in 3 other locations: Line 130 - 134 (mass = 18)&lt;br /&gt;
Scale.rb&lt;br /&gt;
Cyclomatic complexity for complete is too high. Method has too many lines&lt;br /&gt;
Identical code found in 1 other location: line 17-28&lt;br /&gt;
Identical code  found in 1 other location: line 50-54&lt;br /&gt;
Identical code found in 1 other location: line 10-11&lt;br /&gt;
Similar code found in 3 other locations: line 60-64&lt;br /&gt;
Checkbox.rb&lt;br /&gt;
Method has too many lines.&lt;br /&gt;
Cyclomatic complexity for complete is too high.&lt;br /&gt;
Similar codes in edit method are found in 2 other locations.&lt;br /&gt;
Similar codes in view_question_text method are found in 4 other locations.&lt;br /&gt;
Questionnaire_header.rb&lt;br /&gt;
Upload_file.rb&lt;br /&gt;
Unit-test&lt;br /&gt;
Criterion.rb&lt;br /&gt;
Scale.rb&lt;br /&gt;
Checkbox.rb&lt;br /&gt;
Questionnaire_header.rb&lt;br /&gt;
Upload_file.rb&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Refactor&lt;br /&gt;
 Criterion.rb&lt;br /&gt;
&lt;br /&gt;
     1. Method has too many lines: Line 35 - 158 [106/30] &lt;br /&gt;
       def complete(count, answer=nil, questionnaire_min, questionnaire_max, dropdown_or_scale)&lt;br /&gt;
        Wrap the specific code into different instance methods&lt;br /&gt;
     2. Cyclomatic complexity for complete is too high: Line 35 - 158 [28/6]&lt;br /&gt;
        def complete(count, answer=nil, questionnaire_min, questionnaire_max, dropdown_or_scale)&lt;br /&gt;
         Wrap the code into different instance methods to reduce cyclomatic complexity&lt;br /&gt;
&lt;br /&gt;
def complete(count, answer=nil, questionnaire_min, questionnaire_max, dropdown_or_scale)&lt;br /&gt;
    if self.size.nil?&lt;br /&gt;
      cols = '70'&lt;br /&gt;
      rows = '1'&lt;br /&gt;
    else&lt;br /&gt;
      cols = self.size.split(',')[0]&lt;br /&gt;
      rows = self.size.split(',')[1]&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    html = '&amp;lt;li&amp;gt;&amp;lt;div&amp;gt;&amp;lt;label for=&amp;quot;responses_' +count.to_s+ '&amp;quot;&amp;gt;' +self.txt+ '&amp;lt;/label&amp;gt;&amp;lt;/div&amp;gt;'&lt;br /&gt;
    #show advice for each criterion question&lt;br /&gt;
    question_advices = QuestionAdvice.where(question_id: self.id).sort_by { |advice| advice.id }&lt;br /&gt;
    advice_total_length = 0&lt;br /&gt;
&lt;br /&gt;
    question_advices.each do |question_advice|&lt;br /&gt;
      if question_advice.advice &amp;amp;&amp;amp; !question_advice.advice == &amp;quot;&amp;quot;&lt;br /&gt;
        advice_total_length += question_advice.advice.length&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    if question_advices.length &amp;gt; 0 and advice_total_length &amp;gt; 0&lt;br /&gt;
      # html += '&amp;lt;a id=&amp;quot;showAdivce_' + self.id.to_s + '&amp;quot; onclick=&amp;quot;showAdvice(' + self.id.to_s + ')&amp;quot;&amp;gt;Show advice&amp;lt;/a&amp;gt;'&lt;br /&gt;
      # html += '&amp;lt;script&amp;gt;'&lt;br /&gt;
      # html += 'function showAdvice(i){'&lt;br /&gt;
      # html += 'var element = document.getElementById(&amp;quot;showAdivce_&amp;quot; + i.toString());'&lt;br /&gt;
      # html += 'var show = element.innerHTML == &amp;quot;Hide advice&amp;quot;;'&lt;br /&gt;
      # html += 'if (show){'&lt;br /&gt;
      # html += 'element.innerHTML=&amp;quot;Show advice&amp;quot;;'&lt;br /&gt;
      # html += '}else{'&lt;br /&gt;
      # html += 'element.innerHTML=&amp;quot;Hide advice&amp;quot;;}'&lt;br /&gt;
      # html += 'toggleAdvice(i);}'&lt;br /&gt;
      #&lt;br /&gt;
      # html += 'function toggleAdvice(i) {'&lt;br /&gt;
      # html += 'var elem = document.getElementById(i.toString() + &amp;quot;_myDiv&amp;quot;);'&lt;br /&gt;
      # html += 'if (elem.style.display == &amp;quot;none&amp;quot;) {'&lt;br /&gt;
      # html += 'elem.style.display = &amp;quot;&amp;quot;;'&lt;br /&gt;
      # html += '} else {'&lt;br /&gt;
      # html += 'elem.style.display = &amp;quot;none&amp;quot;;}}'&lt;br /&gt;
      # html += '&amp;lt;/script&amp;gt;'&lt;br /&gt;
      #&lt;br /&gt;
      # html += '&amp;lt;div id=&amp;quot;' + self.id.to_s + '_myDiv&amp;quot; style=&amp;quot;display: none;&amp;quot;&amp;gt;'&lt;br /&gt;
&lt;br /&gt;
      # code added to reduce complexity&lt;br /&gt;
       html = complete_show_advice(self, html)&lt;br /&gt;
&lt;br /&gt;
      #[2015-10-26] Zhewei:&lt;br /&gt;
      #best to order advices high to low, e.g., 5 to 1&lt;br /&gt;
      #each level used to be a link;&lt;br /&gt;
      #clicking on the link caused the dropbox to be filled in with the corresponding number&lt;br /&gt;
      question_advices.reverse.each_with_index do |question_advice, index|&lt;br /&gt;
        html += '&amp;lt;a id=&amp;quot;changeScore_&amp;gt;' + self.id.to_s + '&amp;quot; onclick=&amp;quot;changeScore(' + count.to_s + ',' + index.to_s + ')&amp;quot;&amp;gt;'&lt;br /&gt;
        html += (question_advices.length - index).to_s + ' - ' + question_advice.advice + '&amp;lt;/a&amp;gt;&amp;lt;br/&amp;gt;'&lt;br /&gt;
        html += '&amp;lt;script&amp;gt;'&lt;br /&gt;
        html += 'function changeScore(i, j) {'&lt;br /&gt;
        html += 'var elem = jQuery(&amp;quot;#responses_&amp;quot; + i.toString() + &amp;quot;_score&amp;quot;);'&lt;br /&gt;
        html += 'var opts = elem.children(&amp;quot;option&amp;quot;).length;'&lt;br /&gt;
        html += 'elem.val((opts - j - 1).toString());}'&lt;br /&gt;
        html += '&amp;lt;/script&amp;gt;'&lt;br /&gt;
      end&lt;br /&gt;
      html += '&amp;lt;/div&amp;gt;'&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    if dropdown_or_scale == 'dropdown'&lt;br /&gt;
      # html += '&amp;lt;div&amp;gt;&amp;lt;select id=&amp;quot;responses_' +count.to_s+ '_score&amp;quot; name=&amp;quot;responses[' +count.to_s+ '][score]&amp;quot;&amp;gt;'&lt;br /&gt;
      # html += '&amp;lt;option value=''&amp;gt;--&amp;lt;/option&amp;gt;'&lt;br /&gt;
      # for j in questionnaire_min..questionnaire_max&lt;br /&gt;
      #   if !answer.nil? and j == answer.answer&lt;br /&gt;
      #     html += '&amp;lt;option value=' + j.to_s + ' selected=&amp;quot;selected&amp;quot;&amp;gt;'&lt;br /&gt;
      #   else&lt;br /&gt;
      #     html += '&amp;lt;option value=' + j.to_s + '&amp;gt;'&lt;br /&gt;
      #   end&lt;br /&gt;
      #   if j == questionnaire_min&lt;br /&gt;
      #     html += j.to_s&lt;br /&gt;
      #     html += &amp;quot;-&amp;quot; + self.min_label if self.min_label &amp;amp;&amp;amp; self.min_label.length&amp;gt;0&lt;br /&gt;
      #     html += &amp;quot;&amp;lt;/option&amp;gt;&amp;quot;&lt;br /&gt;
      #   elsif j == questionnaire_max&lt;br /&gt;
      #     html += j.to_s&lt;br /&gt;
      #     html += &amp;quot;-&amp;quot; + self.max_label if self.max_label &amp;amp;&amp;amp; self.max_label.length&amp;gt;0&lt;br /&gt;
      #     html += &amp;quot;&amp;lt;/option&amp;gt;&amp;quot;&lt;br /&gt;
      #   else&lt;br /&gt;
      #     html += j.to_s + &amp;quot;&amp;lt;/option&amp;gt;&amp;quot;&lt;br /&gt;
      #   end&lt;br /&gt;
      # end&lt;br /&gt;
      # html += &amp;quot;&amp;lt;/select&amp;gt;&amp;lt;/div&amp;gt;&amp;quot;&lt;br /&gt;
      # html += '&amp;lt;textarea cols=' +cols+ ' rows=' +rows+ ' id=&amp;quot;responses_' +count.to_s+ '_comments&amp;quot; name=&amp;quot;responses[' +count.to_s+ '][comment]&amp;quot; style=&amp;quot;overflow:hidden;&amp;quot;&amp;gt;'&lt;br /&gt;
      # html += answer.comments if !answer.nil?&lt;br /&gt;
      # html += '&amp;lt;/textarea&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;/br&amp;gt;&amp;lt;br/&amp;gt;'&lt;br /&gt;
&lt;br /&gt;
      ## code added  to reduce Cyclomatic Complexity&lt;br /&gt;
      html = complete_drop_down(self, html, count, answer, questionnaire_min, questionnaire_max)&lt;br /&gt;
&lt;br /&gt;
    elsif dropdown_or_scale == 'scale'&lt;br /&gt;
      # html += '&amp;lt;input id=&amp;quot;responses_' +count.to_s+ '_score&amp;quot; name=&amp;quot;responses[' +count.to_s+ '][score]&amp;quot; type=&amp;quot;hidden&amp;quot;'&lt;br /&gt;
      # html += 'value=&amp;quot;'+answer.answer.to_s+'&amp;quot;' if !answer.nil?&lt;br /&gt;
      # html += '&amp;gt;'&lt;br /&gt;
      #&lt;br /&gt;
      # html += '&amp;lt;table&amp;gt;'&lt;br /&gt;
      # html += '&amp;lt;tr&amp;gt;&amp;lt;td width=&amp;quot;10%&amp;quot;&amp;gt;&amp;lt;/td&amp;gt;'&lt;br /&gt;
      # for j in questionnaire_min..questionnaire_max&lt;br /&gt;
      #   html += '&amp;lt;td width=&amp;quot;10%&amp;quot;&amp;gt;&amp;lt;label&amp;gt;' +j.to_s+ '&amp;lt;/label&amp;gt;&amp;lt;/td&amp;gt;'&lt;br /&gt;
      # end&lt;br /&gt;
      # html += '&amp;lt;td width=&amp;quot;10%&amp;quot;&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;tr&amp;gt;'&lt;br /&gt;
      #&lt;br /&gt;
      # # if !self.min_label.nil?&lt;br /&gt;
      # #   html += '&amp;lt;td width=&amp;quot;10%&amp;quot;&amp;gt;' +self.min_label+ '&amp;lt;/td&amp;gt;'&lt;br /&gt;
      # # else&lt;br /&gt;
      # #   html += '&amp;lt;td width=&amp;quot;10%&amp;quot;&amp;gt;&amp;lt;/td&amp;gt;'&lt;br /&gt;
      # # end&lt;br /&gt;
      # ## code added  to remove duplicated code&lt;br /&gt;
      #  html = complete_min_label_condition(self, html)&lt;br /&gt;
      #&lt;br /&gt;
      #&lt;br /&gt;
      # ##&lt;br /&gt;
      # # for j in questionnaire_min..questionnaire_max&lt;br /&gt;
      # #   html += '&amp;lt;td width=&amp;quot;10%&amp;quot;&amp;gt;&amp;lt;input type=&amp;quot;radio&amp;quot; id=&amp;quot;' +j.to_s+ '&amp;quot; value=&amp;quot;' +j.to_s+ '&amp;quot; name=&amp;quot;Radio_' +self.id.to_s+ '&amp;quot;'&lt;br /&gt;
      # #   html += 'checked=&amp;quot;checked&amp;quot;' if (!answer.nil? and answer.answer == j) or (answer.nil? and questionnaire_min == j)&lt;br /&gt;
      # #   html += '&amp;gt;&amp;lt;/td&amp;gt;'&lt;br /&gt;
      # # end&lt;br /&gt;
      # ## code added  to remove duplicated code&lt;br /&gt;
      #  html = complete_questionnaire_min_to_questionnaire_max(self, html, answer, questionnaire_min, questionnaire_max)&lt;br /&gt;
      #&lt;br /&gt;
      # html += '&amp;lt;script&amp;gt;jQuery(&amp;quot;input[name=Radio_' +self.id.to_s+ ']:radio&amp;quot;).change(function() {'&lt;br /&gt;
      # html += 'var response_score = jQuery(&amp;quot;#responses_' +count.to_s+ '_score&amp;quot;);'&lt;br /&gt;
      # html += 'var checked_value = jQuery(&amp;quot;input[name=Radio_' +self.id.to_s+ ']:checked&amp;quot;).val();'&lt;br /&gt;
      # html += 'response_score.val(checked_value);});&amp;lt;/script&amp;gt;'&lt;br /&gt;
      #&lt;br /&gt;
      # # if !self.max_label.nil?&lt;br /&gt;
      # #   html += '&amp;lt;td width=&amp;quot;10%&amp;quot;&amp;gt;' +self.max_label+ '&amp;lt;/td&amp;gt;'&lt;br /&gt;
      # # else&lt;br /&gt;
      # #   html += '&amp;lt;td width=&amp;quot;10%&amp;quot;&amp;gt;&amp;lt;/td&amp;gt;'&lt;br /&gt;
      # # end&lt;br /&gt;
      # ## code added  to remove duplicated code&lt;br /&gt;
      #  html = complete_max_label_condition(self, html)&lt;br /&gt;
      #&lt;br /&gt;
      # html += '&amp;lt;td width=&amp;quot;10%&amp;quot;&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;/table&amp;gt;'&lt;br /&gt;
      # html += '&amp;lt;textarea cols=' +cols+ ' rows=' +rows+ ' id=&amp;quot;responses_' +count.to_s+ '_comments&amp;quot; name=&amp;quot;responses[' +count.to_s+ '][comment]&amp;quot; style=&amp;quot;overflow:hidden;&amp;quot;&amp;gt;'&lt;br /&gt;
      # html += answer.comments if !answer.nil?&lt;br /&gt;
      # html += '&amp;lt;/textarea&amp;gt;&amp;lt;br/&amp;gt;&amp;lt;br/&amp;gt;'&lt;br /&gt;
&lt;br /&gt;
      ## code added  to reduce Cyclomatic Complexity&lt;br /&gt;
       html = complete_scale(self, html, count, answer, questionnaire_min, questionnaire_max)&lt;br /&gt;
    end&lt;br /&gt;
    html.html_safe&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
     3. Identical code found in 1 other location: Line 20 - 32 (mass = 89)&lt;br /&gt;
            Also found in   app/models/scale.rb:17…28&lt;br /&gt;
         The following method is removed from subclass: criterion and added to their superclass: scaled_question&lt;br /&gt;
       def view_question_text&lt;br /&gt;
            &lt;br /&gt;
def view_question_text&lt;br /&gt;
    html = '&amp;lt;TR&amp;gt;&amp;lt;TD align=&amp;quot;left&amp;quot;&amp;gt; '+self.txt+' &amp;lt;/TD&amp;gt;'&lt;br /&gt;
    html += '&amp;lt;TD align=&amp;quot;left&amp;quot;&amp;gt;'+self.type+'&amp;lt;/TD&amp;gt;'&lt;br /&gt;
    html += '&amp;lt;td align=&amp;quot;center&amp;quot;&amp;gt;'+self.weight.to_s+'&amp;lt;/TD&amp;gt;'&lt;br /&gt;
    questionnaire = self.questionnaire&lt;br /&gt;
    if !self.max_label.nil? &amp;amp;&amp;amp; !self.min_label.nil?&lt;br /&gt;
      html += '&amp;lt;TD align=&amp;quot;center&amp;quot;&amp;gt; ('+self.min_label+') '+questionnaire.min_question_score.to_s+' to '+ questionnaire.max_question_score.to_s + ' ('+self.max_label+')&amp;lt;/TD&amp;gt;'&lt;br /&gt;
    else&lt;br /&gt;
      html += '&amp;lt;TD align=&amp;quot;center&amp;quot;&amp;gt;'+questionnaire.min_question_score.to_s+' to '+ questionnaire.max_question_score.to_s + '&amp;lt;/TD&amp;gt;'&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    html += '&amp;lt;/TR&amp;gt;'&lt;br /&gt;
    Html.html_safe&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
    4. Identical code found in 1 other location: Line 135 - 139 (mass = 50)&lt;br /&gt;
          Also found in  app/models/scale.rb:50…54&lt;br /&gt;
       Wrap the duplicated code into an instance method and add the instance method into superclass: scaled_question&lt;br /&gt;
# add the following functions to refactor duplicates.&lt;br /&gt;
  def complete_questionnaire_min_to_questionnaire_max(ob, html, answer, questionnaire_min, questionnaire_max)&lt;br /&gt;
    for j in questionnaire_min..questionnaire_max&lt;br /&gt;
      html += '&amp;lt;td width=&amp;quot;10%&amp;quot;&amp;gt;&amp;lt;input type=&amp;quot;radio&amp;quot; id=&amp;quot;' +j.to_s+ '&amp;quot; value=&amp;quot;' +j.to_s+ '&amp;quot; name=&amp;quot;Radio_' +ob.id.to_s+ '&amp;quot;'&lt;br /&gt;
      html += 'checked=&amp;quot;checked&amp;quot;' if (!answer.nil? and answer.answer == j) or (answer.nil? and questionnaire_min == j)&lt;br /&gt;
      html += '&amp;gt;&amp;lt;/td&amp;gt;'&lt;br /&gt;
    end&lt;br /&gt;
    return html&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
         5. Identical code found in 1 other location Line 13 - 14 (mass = 40)&lt;br /&gt;
            Also found in  app/models/scale.rb:10…11&lt;br /&gt;
         Wrap the duplicated code into an instance method and add the instance method into superclass: scaled_question&lt;br /&gt;
  # add the following functions to refactor duplicates.  &lt;br /&gt;
def edit_end(ob, html)&lt;br /&gt;
    html+='&amp;lt;td&amp;gt; max_label &amp;lt;input size=&amp;quot;4&amp;quot; value=&amp;quot;'+ob.max_label.to_s+'&amp;quot; name=&amp;quot;question['+ob.id.to_s+'][max_label]&amp;quot; id=&amp;quot;question_'+ob.id.to_s+'_max_label&amp;quot; type=&amp;quot;text&amp;quot;&amp;gt;  min_label &amp;lt;input size=&amp;quot;4&amp;quot; value=&amp;quot;'+ob.min_label.to_s+'&amp;quot; name=&amp;quot;question['+ob.id.to_s+'][min_label]&amp;quot; id=&amp;quot;question_'+ob.id.to_s+'_min_label&amp;quot; type=&amp;quot;text&amp;quot;&amp;gt;&amp;lt;/td&amp;gt;'&lt;br /&gt;
    html+='&amp;lt;/tr&amp;gt;'&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
     6.  Similar code found in 1 other location Line 103 - 105 (mass = 26)&lt;br /&gt;
              Also found in   app/models/criterion.rb:107…110&lt;br /&gt;
          Wrap the duplicated code into an instance method&lt;br /&gt;
&lt;br /&gt;
def complete_drop_down_label_config(html, label)&lt;br /&gt;
    html += j.to_s&lt;br /&gt;
    html += &amp;quot;-&amp;quot; + label if label &amp;amp;&amp;amp; label.length&amp;gt;0&lt;br /&gt;
    html += &amp;quot;&amp;lt;/option&amp;gt;&amp;quot;&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
      7. Similar code found in 2 other locations Line 152 - 153 (mass = 22)&lt;br /&gt;
              Also found in   app/models/criterion.rb:115…116&lt;br /&gt;
                                         app/models/text_area.rb:12…13&lt;br /&gt;
           Wrap the duplicated code into an instance method&lt;br /&gt;
&lt;br /&gt;
def complete_answer_comment(count, html, answer)&lt;br /&gt;
    html += '&amp;lt;textarea cols=' +cols+ ' rows=' +rows+ ' id=&amp;quot;responses_' +count.to_s+ '_comments&amp;quot; name=&amp;quot;responses[' +count.to_s+ '][comment]&amp;quot; style=&amp;quot;overflow:hidden;&amp;quot;&amp;gt;'&lt;br /&gt;
    html += answer.comments if !answer.nil?&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
        8. Similar code found in 3 other locations: Line 130 - 134 (mass = 18)&lt;br /&gt;
                 Also found in    app/models/criterion.rb:145…149&lt;br /&gt;
                                             app/models/scale.rb:45…49&lt;br /&gt;
                                             app/models/scale.rb:60…64&lt;br /&gt;
Wrap the duplicated code into an instance method and add the instance method into superclass: scaled_question&lt;br /&gt;
&lt;br /&gt;
  # add the following functions to refactor duplicates.  &lt;br /&gt;
  def complete_label(label, html)&lt;br /&gt;
    if !label.nil?&lt;br /&gt;
      html += '&amp;lt;td width=&amp;quot;10%&amp;quot;&amp;gt;' +label+ '&amp;lt;/td&amp;gt;'&lt;br /&gt;
    else&lt;br /&gt;
      html += '&amp;lt;td width=&amp;quot;10%&amp;quot;&amp;gt;&amp;lt;/td&amp;gt;'&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Scale.rb&lt;br /&gt;
Cyclomatic complexity for complete is too high. Method has too many lines&lt;br /&gt;
 def complete(count, answer=nil, questionnaire_min, questionnaire_max)&lt;br /&gt;
&lt;br /&gt;
def complete(count, answer=nil, questionnaire_min, questionnaire_max)&lt;br /&gt;
  	html = self.txt + '&amp;lt;br&amp;gt;'&lt;br /&gt;
    html += '&amp;lt;input id=&amp;quot;responses_' +count.to_s+ '_score&amp;quot; name=&amp;quot;responses[' +count.to_s+ '][score]&amp;quot; type=&amp;quot;hidden&amp;quot;'&lt;br /&gt;
    html += 'value=&amp;quot;'+answer.answer.to_s+'&amp;quot;' if !answer.nil?&lt;br /&gt;
    html += '&amp;gt;'&lt;br /&gt;
    html += '&amp;lt;input id=&amp;quot;responses_' +count.to_s+ '_comments&amp;quot; name=&amp;quot;responses[' +count.to_s+ '][comment]&amp;quot; type=&amp;quot;hidden&amp;quot; value=&amp;quot;&amp;quot;&amp;gt;'&lt;br /&gt;
&lt;br /&gt;
    html += '&amp;lt;table&amp;gt;'&lt;br /&gt;
    html += '&amp;lt;tr&amp;gt;&amp;lt;td width=&amp;quot;10%&amp;quot;&amp;gt;&amp;lt;/td&amp;gt;'&lt;br /&gt;
    for j in questionnaire_min..questionnaire_max&lt;br /&gt;
      html += '&amp;lt;td width=&amp;quot;10%&amp;quot;&amp;gt;&amp;lt;label&amp;gt;' +j.to_s+ '&amp;lt;/label&amp;gt;&amp;lt;/td&amp;gt;'&lt;br /&gt;
    end&lt;br /&gt;
    html += '&amp;lt;td width=&amp;quot;10%&amp;quot;&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;tr&amp;gt;'&lt;br /&gt;
&lt;br /&gt;
    # Identical code found in 1 other location, replaced with a method&lt;br /&gt;
    # if !self.min_label.nil?&lt;br /&gt;
    #   html += '&amp;lt;td width=&amp;quot;10%&amp;quot;&amp;gt;' +self.min_label+ '&amp;lt;/td&amp;gt;'&lt;br /&gt;
    # else&lt;br /&gt;
    #   html += '&amp;lt;td width=&amp;quot;10%&amp;quot;&amp;gt;&amp;lt;/td&amp;gt;'&lt;br /&gt;
    # end&lt;br /&gt;
    html = complete_label(self.min_label, html)&lt;br /&gt;
&lt;br /&gt;
    # comment by Hui, replaced with a method&lt;br /&gt;
    # for j in questionnaire_min..questionnaire_max&lt;br /&gt;
    #   html += '&amp;lt;td width=&amp;quot;10%&amp;quot;&amp;gt;&amp;lt;input type=&amp;quot;radio&amp;quot; id=&amp;quot;' +j.to_s+ '&amp;quot; value=&amp;quot;' +j.to_s+ '&amp;quot; name=&amp;quot;Radio_' +self.id.to_s+ '&amp;quot;'&lt;br /&gt;
    #   html += 'checked=&amp;quot;checked&amp;quot;' if (!answer.nil? and answer.answer == j) or (answer.nil? and questionnaire_min == j)&lt;br /&gt;
    #   html += '&amp;gt;&amp;lt;/td&amp;gt;'&lt;br /&gt;
    # end&lt;br /&gt;
    html = complete_questionnaire_min_to_questionnaire_max(self, html, answer, questionnaire_min, questionnaire_max)&lt;br /&gt;
&lt;br /&gt;
    html += '&amp;lt;script&amp;gt;jQuery(&amp;quot;input[name=Radio_' +self.id.to_s+ ']:radio&amp;quot;).change(function() {'&lt;br /&gt;
    html += 'var response_score = jQuery(&amp;quot;#responses_' +count.to_s+ '_score&amp;quot;);'&lt;br /&gt;
    html += 'var checked_value = jQuery(&amp;quot;input[name=Radio_' +self.id.to_s+ ']:checked&amp;quot;).val();'&lt;br /&gt;
    html += 'response_score.val(checked_value);});&amp;lt;/script&amp;gt;'&lt;br /&gt;
&lt;br /&gt;
    # comment by Hui, replaced with a method&lt;br /&gt;
    # if !self.max_label.nil?&lt;br /&gt;
    #   html += '&amp;lt;td width=&amp;quot;10%&amp;quot;&amp;gt;' +self.max_label+ '&amp;lt;/td&amp;gt;'&lt;br /&gt;
    # else&lt;br /&gt;
    #   html += '&amp;lt;td width=&amp;quot;10%&amp;quot;&amp;gt;&amp;lt;/td&amp;gt;'&lt;br /&gt;
    # end&lt;br /&gt;
    html = complete_label(self.max_label, html)&lt;br /&gt;
&lt;br /&gt;
    html += '&amp;lt;td width=&amp;quot;10%&amp;quot;&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;/table&amp;gt;'&lt;br /&gt;
    html.html_safe&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Identical code found in 1 other location: line 17-28&lt;br /&gt;
app/models/criterion.rb:20…32&lt;br /&gt;
 def view_question_text&lt;br /&gt;
The following method is removed from subclass: scale and added to their superclass: scaled_question&lt;br /&gt;
&lt;br /&gt;
  #This method returns what to display if an instructor (etc.) is viewing a questionnaire&lt;br /&gt;
  def view_question_text&lt;br /&gt;
    html = '&amp;lt;TR&amp;gt;&amp;lt;TD align=&amp;quot;left&amp;quot;&amp;gt; '+self.txt+' &amp;lt;/TD&amp;gt;'&lt;br /&gt;
    html += '&amp;lt;TD align=&amp;quot;left&amp;quot;&amp;gt;'+self.type+'&amp;lt;/TD&amp;gt;'&lt;br /&gt;
    html += '&amp;lt;td align=&amp;quot;center&amp;quot;&amp;gt;'+self.weight.to_s+'&amp;lt;/TD&amp;gt;'&lt;br /&gt;
    questionnaire = self.questionnaire&lt;br /&gt;
    if !self.max_label.nil? &amp;amp;&amp;amp; !self.min_label.nil?&lt;br /&gt;
      html += '&amp;lt;TD align=&amp;quot;center&amp;quot;&amp;gt; ('+self.min_label+') '+questionnaire.min_question_score.to_s+' to '+ questionnaire.max_question_score.to_s + ' ('+self.max_label+')&amp;lt;/TD&amp;gt;'&lt;br /&gt;
    else&lt;br /&gt;
      html += '&amp;lt;TD align=&amp;quot;center&amp;quot;&amp;gt;'+questionnaire.min_question_score.to_s+' to '+ questionnaire.max_question_score.to_s + '&amp;lt;/TD&amp;gt;'&lt;br /&gt;
    end&lt;br /&gt;
    html += '&amp;lt;/TR&amp;gt;'&lt;br /&gt;
    html.html_safe&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Identical code  found in 1 other location: line 50-54&lt;br /&gt;
app/models/criterion.rb:135…139&lt;br /&gt;
Wrap the duplicated code into an instance method and add the instance method into superclass: scaled_question&lt;br /&gt;
&lt;br /&gt;
  # add the following functions to refactor duplicates.&lt;br /&gt;
  def complete_questionnaire_min_to_questionnaire_max(ob, html, answer, questionnaire_min, questionnaire_max)&lt;br /&gt;
    for j in questionnaire_min..questionnaire_max&lt;br /&gt;
      html += '&amp;lt;td width=&amp;quot;10%&amp;quot;&amp;gt;&amp;lt;input type=&amp;quot;radio&amp;quot; id=&amp;quot;' +j.to_s+ '&amp;quot; value=&amp;quot;' +j.to_s+ '&amp;quot; name=&amp;quot;Radio_' +ob.id.to_s+ '&amp;quot;'&lt;br /&gt;
      html += 'checked=&amp;quot;checked&amp;quot;' if (!answer.nil? and answer.answer == j) or (answer.nil? and questionnaire_min == j)&lt;br /&gt;
      html += '&amp;gt;&amp;lt;/td&amp;gt;'&lt;br /&gt;
    end&lt;br /&gt;
    return html&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Identical code found in 1 other location: line 10-11&lt;br /&gt;
 app/models/criterion.rb:13…14&lt;br /&gt;
Wrap the duplicated code into an instance method and add the instance method into superclass: scaled_question&lt;br /&gt;
  # add the following functions to refactor duplicates.  &lt;br /&gt;
def edit_end(ob, html)&lt;br /&gt;
    html+='&amp;lt;td&amp;gt; max_label &amp;lt;input size=&amp;quot;4&amp;quot; value=&amp;quot;'+ob.max_label.to_s+'&amp;quot; name=&amp;quot;question['+ob.id.to_s+'][max_label]&amp;quot; id=&amp;quot;question_'+ob.id.to_s+'_max_label&amp;quot; type=&amp;quot;text&amp;quot;&amp;gt;  min_label &amp;lt;input size=&amp;quot;4&amp;quot; value=&amp;quot;'+ob.min_label.to_s+'&amp;quot; name=&amp;quot;question['+ob.id.to_s+'][min_label]&amp;quot; id=&amp;quot;question_'+ob.id.to_s+'_min_label&amp;quot; type=&amp;quot;text&amp;quot;&amp;gt;&amp;lt;/td&amp;gt;'&lt;br /&gt;
    html+='&amp;lt;/tr&amp;gt;'&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Similar code found in 3 other locations: line 60-64&lt;br /&gt;
app/models/criterion.rb:130…134&lt;br /&gt;
app/models/criterion.rb:145…149&lt;br /&gt;
app/models/scale.rb:45…49&lt;br /&gt;
Wrap the duplicated code into an instance method and add the instance method into superclass: scaled_question&lt;br /&gt;
&lt;br /&gt;
  # add the following functions to refactor duplicates.  &lt;br /&gt;
  def complete_label(label, html)&lt;br /&gt;
    if !label.nil?&lt;br /&gt;
      html += '&amp;lt;td width=&amp;quot;10%&amp;quot;&amp;gt;' +label+ '&amp;lt;/td&amp;gt;'&lt;br /&gt;
    else&lt;br /&gt;
      html += '&amp;lt;td width=&amp;quot;10%&amp;quot;&amp;gt;&amp;lt;/td&amp;gt;'&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Checkbox.rb&lt;br /&gt;
Method has too many lines.&lt;br /&gt;
	By moving codes to private methods outside this method, this problem can be fixed together with the following one. Here is the new complete method together with two additional private methods: hasAnswer(html, answer) and nextQuestionTail(html, next_question). The source codes are listed as below.&lt;br /&gt;
&lt;br /&gt;
def complete(count, answer=nil)&lt;br /&gt;
    curr_question = Question.find(self.id)&lt;br /&gt;
    prev_question = Question.where(&amp;quot;seq &amp;lt; ?&amp;quot;, curr_question.seq).order(:seq).last&lt;br /&gt;
    next_question = Question.where(&amp;quot;seq &amp;gt; ?&amp;quot;, curr_question.seq).order(:seq).first&lt;br /&gt;
    html = ''&lt;br /&gt;
    if prev_question.type == 'ColumnHeader'&lt;br /&gt;
      html = '&amp;lt;td style=&amp;quot;padding: 15px;&amp;quot;&amp;gt;'&lt;br /&gt;
    #else&lt;br /&gt;
    #  html = ''&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    html += '&amp;lt;input id=&amp;quot;responses_' +count.to_s+ '_comments&amp;quot; name=&amp;quot;responses[' +count.to_s+ '][comment]&amp;quot; type=&amp;quot;hidden&amp;quot; value=&amp;quot;&amp;quot;&amp;gt;'&lt;br /&gt;
    html += '&amp;lt;input id=&amp;quot;responses_' +count.to_s+ '_score&amp;quot; name=&amp;quot;responses[' +count.to_s+ '][score]&amp;quot; type=&amp;quot;hidden&amp;quot;'&lt;br /&gt;
    html += hasAnswer(html , answer)&lt;br /&gt;
#    if !answer.nil? and answer.answer == 1&lt;br /&gt;
#      html += 'value=&amp;quot;1&amp;quot;'&lt;br /&gt;
#    else&lt;br /&gt;
#      html += 'value=&amp;quot;0&amp;quot;'&lt;br /&gt;
#    end &lt;br /&gt;
    html += '&amp;gt;'&lt;br /&gt;
    html += '&amp;lt;input id=&amp;quot;responses_' +count.to_s+ '_checkbox&amp;quot; type=&amp;quot;checkbox&amp;quot; onchange=&amp;quot;checkbox' +count.to_s+ 'Changed()&amp;quot;'&lt;br /&gt;
    html += 'checked=&amp;quot;checked&amp;quot;' if !answer.nil? and answer.answer == 1&lt;br /&gt;
    html += '&amp;gt;'&lt;br /&gt;
    html += '&amp;lt;label for=&amp;quot;responses_' +count.to_s+ '&amp;quot;&amp;gt;' +self.txt+ '&amp;lt;/label&amp;gt;'&lt;br /&gt;
&lt;br /&gt;
    html += '&amp;lt;script&amp;gt;function checkbox' +count.to_s+ 'Changed() {'&lt;br /&gt;
    html += ' var checkbox = jQuery(&amp;quot;#responses_' +count.to_s+ '_checkbox&amp;quot;);'&lt;br /&gt;
    html += ' var response_score = jQuery(&amp;quot;#responses_' +count.to_s+ '_score&amp;quot;);'&lt;br /&gt;
    html += 'if (checkbox.is(&amp;quot;:checked&amp;quot;)) {'&lt;br /&gt;
    html += 'response_score.val(&amp;quot;1&amp;quot;);'&lt;br /&gt;
    html += '} else {'&lt;br /&gt;
    html += 'response_score.val(&amp;quot;0&amp;quot;);}}&amp;lt;/script&amp;gt;'&lt;br /&gt;
&lt;br /&gt;
    html = nextQuestionTail(html, next_question)&lt;br /&gt;
#    if next_question.type == 'ColumnHeader'&lt;br /&gt;
#      html += '&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;'&lt;br /&gt;
#    elsif next_question.type == 'SectionHeader' or next_question.type == 'TableHeader'&lt;br /&gt;
#      html += '&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;/table&amp;gt;&amp;lt;br/&amp;gt;'&lt;br /&gt;
#    else&lt;br /&gt;
#      html += '&amp;lt;BR/&amp;gt;'&lt;br /&gt;
#    end&lt;br /&gt;
    html.html_safe&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  #YJ private for complete()&lt;br /&gt;
  def hasAnswer(html, answer)&lt;br /&gt;
    if !answer.nil? and answer.answer == 1&lt;br /&gt;
      html += 'value=&amp;quot;1&amp;quot;'&lt;br /&gt;
    else&lt;br /&gt;
      html += 'value=&amp;quot;0&amp;quot;'&lt;br /&gt;
    end&lt;br /&gt;
    return html&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def nextQuestionTail(html, next_q)&lt;br /&gt;
    if next_question.type == 'ColumnHeader'&lt;br /&gt;
      html += '&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;'&lt;br /&gt;
    elsif next_question.type == 'SectionHeader' or next_question.type == 'TableHeader'&lt;br /&gt;
      html += '&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;/table&amp;gt;&amp;lt;br/&amp;gt;'&lt;br /&gt;
    else&lt;br /&gt;
      html += '&amp;lt;BR/&amp;gt;'&lt;br /&gt;
    end&lt;br /&gt;
    return html&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
Cyclomatic complexity for complete is too high.&lt;br /&gt;
	This problem can be solved by moving branches outside to other private methods. See source code above.&lt;br /&gt;
Similar codes in edit method are found in 2 other locations.&lt;br /&gt;
(questionnaire_header.rb and upload_file.rb)&lt;br /&gt;
Such code duplication can be eliminated by moving the identical part of the similar edit method to a new function, named edit_prefix(html, count) to their common superclass, which is Question (question.rb).&lt;br /&gt;
Here is the source code of the added edit_prefix method in question.rb:&lt;br /&gt;
&lt;br /&gt;
 def edit_prefix(ob, html)&lt;br /&gt;
    html ='&amp;lt;tr&amp;gt;'&lt;br /&gt;
    html+='&amp;lt;td align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;a rel=&amp;quot;nofollow&amp;quot; data-method=&amp;quot;delete&amp;quot; href=&amp;quot;/questions/' +ob.id.to_s+ '&amp;quot;&amp;gt;Remove&amp;lt;/a&amp;gt;&amp;lt;/td&amp;gt;'&lt;br /&gt;
    html+='&amp;lt;td&amp;gt;&amp;lt;input size=&amp;quot;6&amp;quot; value=&amp;quot;'+ob.seq.to_s+'&amp;quot; name=&amp;quot;question['+ob.id.to_s+'][seq]&amp;quot; id=&amp;quot;question_'+ob.id.to_s+'_seq&amp;quot; type=&amp;quot;text&amp;quot;&amp;gt;&amp;lt;/td&amp;gt;'&lt;br /&gt;
    html+='&amp;lt;td&amp;gt;&amp;lt;textarea cols=&amp;quot;50&amp;quot; rows=&amp;quot;1&amp;quot; name=&amp;quot;question['+ob.id.to_s+'][txt]&amp;quot; id=&amp;quot;question_'+ob.id.to_s+'_txt&amp;quot;&amp;gt;'+ob.txt+'&amp;lt;/textarea&amp;gt;&amp;lt;/td&amp;gt;'&lt;br /&gt;
    html+='&amp;lt;td&amp;gt;&amp;lt;input size=&amp;quot;10&amp;quot; disabled=&amp;quot;disabled&amp;quot; value=&amp;quot;'+ob.type+'&amp;quot; name=&amp;quot;question['+ob.id.to_s+'][type]&amp;quot; id=&amp;quot;question_'+ob.id.to_s+'_type&amp;quot; type=&amp;quot;text&amp;quot;&amp;gt;''&amp;lt;/td&amp;gt;'&lt;br /&gt;
  end&lt;br /&gt;
The original code are commented out and insert the function call of the above function, html will be returned in the above function, see codes below:&lt;br /&gt;
&lt;br /&gt;
def edit(count)&lt;br /&gt;
     html = edit_prefix(self, html)&lt;br /&gt;
#    html ='&amp;lt;tr&amp;gt;'&lt;br /&gt;
#    html+='&amp;lt;td align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;a rel=&amp;quot;nofollow&amp;quot; data-method=&amp;quot;delete&amp;quot; href=&amp;quot;/questions/' +self.id.to_s+ '&amp;quot;&amp;gt;Remove&amp;lt;/a&amp;gt;&amp;lt;/td&amp;gt;'&lt;br /&gt;
#    html+='&amp;lt;td&amp;gt;&amp;lt;input size=&amp;quot;6&amp;quot; value=&amp;quot;'+self.seq.to_s+'&amp;quot; name=&amp;quot;question['+self.id.to_s+'][seq]&amp;quot; id=&amp;quot;question_'+self.id.to_s+'_seq&amp;quot; type=&amp;quot;text&amp;quot;&amp;gt;&amp;lt;/td&amp;gt;'&lt;br /&gt;
#    html+='&amp;lt;td&amp;gt;&amp;lt;textarea cols=&amp;quot;50&amp;quot; rows=&amp;quot;1&amp;quot; name=&amp;quot;question['+self.id.to_s+'][txt]&amp;quot; id=&amp;quot;question_'+self.id.to_s+'_txt&amp;quot;&amp;gt;'+self.txt+'&amp;lt;/textarea&amp;gt;&amp;lt;/td&amp;gt;'&lt;br /&gt;
#    html+='&amp;lt;td&amp;gt;&amp;lt;input size=&amp;quot;10&amp;quot; disabled=&amp;quot;disabled&amp;quot; value=&amp;quot;'+self.type+'&amp;quot; name=&amp;quot;question['+self.id.to_s+'][type]&amp;quot; id=&amp;quot;question_'+self.id.to_s+'_type&amp;quot; type=&amp;quot;text&amp;quot;&amp;gt;''&amp;lt;/td&amp;gt;'&lt;br /&gt;
    html+='&amp;lt;td&amp;gt;&amp;lt;!--placeholder (UnscoredQuestion does not need weight)--&amp;gt;&amp;lt;/td&amp;gt;'&lt;br /&gt;
    html+='&amp;lt;/tr&amp;gt;'&lt;br /&gt;
&lt;br /&gt;
    html.html_safe&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
Similar codes in view_question_text method are found in 4 other locations.&lt;br /&gt;
(dropdown.rb, questionnaire_header.rb, text_response.rb, upload_file.rb)&lt;br /&gt;
The solution to this problem is the same as above one, below is the function added in the most common superclass, which is Question, that contains the common parts of the codes found in the view_question_text methods in all five classes.&lt;br /&gt;
  def view_qt_prefix(ob, html)&lt;br /&gt;
    html = '&amp;lt;TR&amp;gt;&amp;lt;TD align=&amp;quot;left&amp;quot;&amp;gt; '+ob.txt+ ' &amp;lt;/TD&amp;gt;'&lt;br /&gt;
    html += '&amp;lt;TD align=&amp;quot;left&amp;quot;&amp;gt;'+ob.type+'&amp;lt;/TD&amp;gt;'&lt;br /&gt;
    html += '&amp;lt;td align=&amp;quot;center&amp;quot;&amp;gt;'+ob.weight.to_s+'&amp;lt;/TD&amp;gt;'&lt;br /&gt;
  end&lt;br /&gt;
The original code are commented out and insert the function call of the above function, html will be returned in the above function, see codes below:&lt;br /&gt;
&lt;br /&gt;
def view_question_text&lt;br /&gt;
    html = view_qt_prefix(ob, html)&lt;br /&gt;
#    html = '&amp;lt;TR&amp;gt;&amp;lt;TD align=&amp;quot;left&amp;quot;&amp;gt; '+self.txt+' &amp;lt;/TD&amp;gt;'&lt;br /&gt;
#    html += '&amp;lt;TD align=&amp;quot;left&amp;quot;&amp;gt;'+self.type+'&amp;lt;/TD&amp;gt;'&lt;br /&gt;
#    html += '&amp;lt;td align=&amp;quot;center&amp;quot;&amp;gt;'+self.weight.to_s+'&amp;lt;/TD&amp;gt;'&lt;br /&gt;
    html += '&amp;lt;TD align=&amp;quot;center&amp;quot;&amp;gt;Checked/Unchecked&amp;lt;/TD&amp;gt;'&lt;br /&gt;
    html += '&amp;lt;/TR&amp;gt;'&lt;br /&gt;
    html.html_safe&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
Questionnaire_header.rb&lt;br /&gt;
All problems in this file are solved after solving the problems found in checkbox.rb.&lt;br /&gt;
Upload_file.rb&lt;br /&gt;
All problems in this file are solved after solving the problems found in checkbox.rb.&lt;br /&gt;
Unit-test&lt;br /&gt;
Criterion.rb&lt;br /&gt;
Scale.rb&lt;br /&gt;
Checkbox.rb&lt;br /&gt;
Questionnaire_header.rb&lt;br /&gt;
Upload_file.rb&lt;/div&gt;</summary>
		<author><name>Hguan2</name></author>
	</entry>
</feed>