<?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=Kbyarbor</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=Kbyarbor"/>
	<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=Special:Contributions/Kbyarbor"/>
	<updated>2026-08-07T18:06:42Z</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_2013/FINAL_PROJECT_E736_UNDO_DELIVERABLE&amp;diff=75090</id>
		<title>CSC/ECE 517 Spring 2013/FINAL PROJECT E736 UNDO DELIVERABLE</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2013/FINAL_PROJECT_E736_UNDO_DELIVERABLE&amp;diff=75090"/>
		<updated>2013-04-22T01:20:17Z</updated>

		<summary type="html">&lt;p&gt;Kbyarbor: /* Classes Modified */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= E736. Undo Functionality for Expertiza =&lt;br /&gt;
*Contacts: Ed Gehringer (efg@ncsu.edu) and Andrew Kofink (ajkofink@ncsu.edu)&lt;br /&gt;
*[http://wiki.expertiza.ncsu.edu/index.php/CSC/ECE_517_Spring_2013/FINAL_PROJECT_E736_UNDO Design Document]&lt;br /&gt;
*[https://docs.google.com/a/ncsu.edu/document/d/11YTjxFXFR13vJ769yFBbqn9qOueK2Ktz0Pd-gyS2W5U/ Project Description Doc]&lt;br /&gt;
== Team Members ==&lt;br /&gt;
*Chun Sing Tsui (ctsui@ncsu.edu)&lt;br /&gt;
*Kenny Yarboro (kbyarbor@ncsu.edu)&lt;br /&gt;
*Meng Cao (mcao2@ncsu.edu)&lt;br /&gt;
*Travis Folsom (twfolsom@ncsu.edu)&lt;br /&gt;
&lt;br /&gt;
== Project Deliverables ==&lt;br /&gt;
&lt;br /&gt;
=== Screencast Video Overview ===&lt;br /&gt;
A video overview of the project was created via [http://www.screencast-o-matic.com/ Screencast-O-Matic] and can be found [http://www.youtube.com/watch?v=1DYS5InjBOk here].  &lt;br /&gt;
&lt;br /&gt;
=== Overview of Undo Functionality ===&lt;br /&gt;
*Undo allows the user to undo their most recent actions for any items that offer the undo functionality.  &lt;br /&gt;
*The undo of file submissions was not required; however, we did or did not do these....depends on if we complete it...&lt;br /&gt;
*If an undo is attempted on an item already modified by another user, a message is displayed stating why undo cannot be performed.  Otherwise, the user is able to undo any changes to an item with the undo functionality.  &lt;br /&gt;
*When multiple actions are performed in one step, the undo functionality groups all of the changes together for the purposes of restoring all items affected by the action previously performed.&lt;br /&gt;
&lt;br /&gt;
=== List of Items Now Supported by Undo Functionality === &lt;br /&gt;
*Add Signup Sheet&lt;br /&gt;
**Delete Topic&lt;br /&gt;
**Edit Topic&lt;br /&gt;
**New Topic&lt;br /&gt;
*Assignments&lt;br /&gt;
**Add Participants&lt;br /&gt;
**Copy&lt;br /&gt;
**Create&lt;br /&gt;
**Delete&lt;br /&gt;
**Edit&lt;br /&gt;
*Courses&lt;br /&gt;
**Add Participants&lt;br /&gt;
**Copy&lt;br /&gt;
**Create&lt;br /&gt;
**Delete&lt;br /&gt;
**Edit&lt;br /&gt;
**Toggle Private/Public&lt;br /&gt;
*Import&lt;br /&gt;
**Import Participants&lt;br /&gt;
**Import Teams&lt;br /&gt;
**Import Users&lt;br /&gt;
*Student Actions&lt;br /&gt;
**Create Team&lt;br /&gt;
**Edit Team Name&lt;br /&gt;
**Leave Team&lt;br /&gt;
**Submit Hyperlink&lt;br /&gt;
*Questions&lt;br /&gt;
**Copy&lt;br /&gt;
**Create&lt;br /&gt;
**Delete&lt;br /&gt;
**Edit&lt;br /&gt;
*Questionnaires&lt;br /&gt;
**Copy&lt;br /&gt;
**Create&lt;br /&gt;
**Delete&lt;br /&gt;
**Edit&lt;br /&gt;
*Teams&lt;br /&gt;
**Add&lt;br /&gt;
**Create (Manual)&lt;br /&gt;
**Create (Random)&lt;br /&gt;
**Delete&lt;br /&gt;
**Delete All Teams&lt;br /&gt;
**Edit&lt;br /&gt;
&lt;br /&gt;
=== Redo Functionality ===&lt;br /&gt;
In addition to the Undo functionality being added, the ability to Redo an undone action is also implemented.  Whenever an Undo is performed, the user is given an option to Redo the action that was undone.  Whenever a Redo is performed, the user is given an option to Undo the action again.  &lt;br /&gt;
&lt;br /&gt;
=== Design Patterns and Designs ===&lt;br /&gt;
*DRY&lt;br /&gt;
**&amp;quot;Don't Repeat Yourself&amp;quot; practice was followed. &lt;br /&gt;
**The app/controllers/application_controller.rb file contains all of the Undo functionality code for Expertiza.  All other controllers are able to call the necessary undo-related methods to enable the Undo functionality.&lt;br /&gt;
&lt;br /&gt;
=== Framework Leveraged &amp;amp; Enhanced ===&lt;br /&gt;
*Paper Trail(https://github.com/airblade/paper_trail)&lt;br /&gt;
**Paper Trail allows for tracking changes to model data. &lt;br /&gt;
***Good for auditing or versioning. &lt;br /&gt;
**Offers many functionalities including:&lt;br /&gt;
****Viewing a model at any stage in its lifecycle. &lt;br /&gt;
****Reverting a model to any version.&lt;br /&gt;
****Undeleting items after they have been destroyed.&lt;br /&gt;
**Compatible with Rails-2.3.15, which is the version Expertiza uses. &lt;br /&gt;
**There is a [http://railscasts.com/episodes/255-undo-with-paper-trail Railscast] showing how to implement the undo feature with Paper Trail. &lt;br /&gt;
**Ranked as the most popular framework for Active Record versioning feature in [https://www.ruby-toolbox.com/categories/Active_Record_Versioning here]&lt;br /&gt;
*Enhancement&lt;br /&gt;
**Paper Trail only supported undo of the most recent action and did not restore associations.   &lt;br /&gt;
**Paper Trail customized to add support for restoring associations within the Expertiza system.  &lt;br /&gt;
***Database transactions paired with timestamps and user ids to group them together.&lt;br /&gt;
&lt;br /&gt;
=== Classes Modified ===&lt;br /&gt;
*apps/&lt;br /&gt;
**controllers/&lt;br /&gt;
***application_controller.rb&lt;br /&gt;
***assignment_controller.rb&lt;br /&gt;
***course_controller.rb&lt;br /&gt;
***import_file_controller.rb&lt;br /&gt;
***participants_controller.rb&lt;br /&gt;
***sign_up_sheet_controller.rb&lt;br /&gt;
***student_team_controller.rb&lt;br /&gt;
***team_controller.rb&lt;br /&gt;
***teams_users_controller.rb&lt;br /&gt;
***versions_controller.rb&lt;br /&gt;
**models/&lt;br /&gt;
***assignment_participant.rb&lt;br /&gt;
***course.rb&lt;br /&gt;
***participant.rb&lt;br /&gt;
***sign_up_topic.rb&lt;br /&gt;
***ta_mapping.rb&lt;br /&gt;
***team_node.rb&lt;br /&gt;
***teams_user.rb&lt;br /&gt;
&lt;br /&gt;
=== Unit &amp;amp; Functional Tests ===&lt;br /&gt;
The implementation of the Undo functionality did not afford any testing opportunities applicable to unit or functional tests.&lt;br /&gt;
&lt;br /&gt;
=== Bug Fixes &amp;amp; Other Improvements ===&lt;br /&gt;
The following bugs were found within Expertiza and fixed:&lt;br /&gt;
*ApplicationController enhanced to rescue from ActiveRecord::RecordNotFound errors and redirect to tree display.  &lt;br /&gt;
*Copy of Assignment opened Edit page for the original Assignment and now correctly opens the Edit page for the copy of the assignment.  &lt;br /&gt;
&lt;br /&gt;
The following general improvements were made:&lt;br /&gt;
*Assignment object associated with an AssignmentNode to eliminate the manual deletion of a related AssignmentNode with the code.  &lt;br /&gt;
*Edited the Copy of Course flash message to be more clear that the copy had already been created and to resolve a misspelling. &lt;br /&gt;
&lt;br /&gt;
=== Problem Areas with Expertiza ===&lt;br /&gt;
There were some areas of functionality within Expertiza that did not work.  There were some cases in which the undo functionality could not be added due to the inherent problems.  These problem areas were:&lt;br /&gt;
*Assigning surveys in an assignment.&lt;br /&gt;
*Dates in assignments do not show up when the assignment is edited.   &lt;br /&gt;
*Unable to assign random reviewers. &lt;br /&gt;
*Unable to edit advice for questions in questionnaire. &lt;br /&gt;
*Unable to remove participants from a course.&lt;br /&gt;
&lt;br /&gt;
=== Future Recommendations ===&lt;br /&gt;
*Add integration tests. &lt;br /&gt;
*Add undo functionality to other areas of Expertiza.&lt;br /&gt;
*Determine appropriate methodology for cleaning up Versions table.&lt;/div&gt;</summary>
		<author><name>Kbyarbor</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2013/FINAL_PROJECT_E736_UNDO_DELIVERABLE&amp;diff=75089</id>
		<title>CSC/ECE 517 Spring 2013/FINAL PROJECT E736 UNDO DELIVERABLE</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2013/FINAL_PROJECT_E736_UNDO_DELIVERABLE&amp;diff=75089"/>
		<updated>2013-04-22T01:19:17Z</updated>

		<summary type="html">&lt;p&gt;Kbyarbor: /* Unit &amp;amp; Functional Tests */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= E736. Undo Functionality for Expertiza =&lt;br /&gt;
*Contacts: Ed Gehringer (efg@ncsu.edu) and Andrew Kofink (ajkofink@ncsu.edu)&lt;br /&gt;
*[http://wiki.expertiza.ncsu.edu/index.php/CSC/ECE_517_Spring_2013/FINAL_PROJECT_E736_UNDO Design Document]&lt;br /&gt;
*[https://docs.google.com/a/ncsu.edu/document/d/11YTjxFXFR13vJ769yFBbqn9qOueK2Ktz0Pd-gyS2W5U/ Project Description Doc]&lt;br /&gt;
== Team Members ==&lt;br /&gt;
*Chun Sing Tsui (ctsui@ncsu.edu)&lt;br /&gt;
*Kenny Yarboro (kbyarbor@ncsu.edu)&lt;br /&gt;
*Meng Cao (mcao2@ncsu.edu)&lt;br /&gt;
*Travis Folsom (twfolsom@ncsu.edu)&lt;br /&gt;
&lt;br /&gt;
== Project Deliverables ==&lt;br /&gt;
&lt;br /&gt;
=== Screencast Video Overview ===&lt;br /&gt;
A video overview of the project was created via [http://www.screencast-o-matic.com/ Screencast-O-Matic] and can be found [http://www.youtube.com/watch?v=1DYS5InjBOk here].  &lt;br /&gt;
&lt;br /&gt;
=== Overview of Undo Functionality ===&lt;br /&gt;
*Undo allows the user to undo their most recent actions for any items that offer the undo functionality.  &lt;br /&gt;
*The undo of file submissions was not required; however, we did or did not do these....depends on if we complete it...&lt;br /&gt;
*If an undo is attempted on an item already modified by another user, a message is displayed stating why undo cannot be performed.  Otherwise, the user is able to undo any changes to an item with the undo functionality.  &lt;br /&gt;
*When multiple actions are performed in one step, the undo functionality groups all of the changes together for the purposes of restoring all items affected by the action previously performed.&lt;br /&gt;
&lt;br /&gt;
=== List of Items Now Supported by Undo Functionality === &lt;br /&gt;
*Add Signup Sheet&lt;br /&gt;
**Delete Topic&lt;br /&gt;
**Edit Topic&lt;br /&gt;
**New Topic&lt;br /&gt;
*Assignments&lt;br /&gt;
**Add Participants&lt;br /&gt;
**Copy&lt;br /&gt;
**Create&lt;br /&gt;
**Delete&lt;br /&gt;
**Edit&lt;br /&gt;
*Courses&lt;br /&gt;
**Add Participants&lt;br /&gt;
**Copy&lt;br /&gt;
**Create&lt;br /&gt;
**Delete&lt;br /&gt;
**Edit&lt;br /&gt;
**Toggle Private/Public&lt;br /&gt;
*Import&lt;br /&gt;
**Import Participants&lt;br /&gt;
**Import Teams&lt;br /&gt;
**Import Users&lt;br /&gt;
*Student Actions&lt;br /&gt;
**Create Team&lt;br /&gt;
**Edit Team Name&lt;br /&gt;
**Leave Team&lt;br /&gt;
**Submit Hyperlink&lt;br /&gt;
*Questions&lt;br /&gt;
**Copy&lt;br /&gt;
**Create&lt;br /&gt;
**Delete&lt;br /&gt;
**Edit&lt;br /&gt;
*Questionnaires&lt;br /&gt;
**Copy&lt;br /&gt;
**Create&lt;br /&gt;
**Delete&lt;br /&gt;
**Edit&lt;br /&gt;
*Teams&lt;br /&gt;
**Add&lt;br /&gt;
**Create (Manual)&lt;br /&gt;
**Create (Random)&lt;br /&gt;
**Delete&lt;br /&gt;
**Delete All Teams&lt;br /&gt;
**Edit&lt;br /&gt;
&lt;br /&gt;
=== Redo Functionality ===&lt;br /&gt;
In addition to the Undo functionality being added, the ability to Redo an undone action is also implemented.  Whenever an Undo is performed, the user is given an option to Redo the action that was undone.  Whenever a Redo is performed, the user is given an option to Undo the action again.  &lt;br /&gt;
&lt;br /&gt;
=== Design Patterns and Designs ===&lt;br /&gt;
*DRY&lt;br /&gt;
**&amp;quot;Don't Repeat Yourself&amp;quot; practice was followed. &lt;br /&gt;
**The app/controllers/application_controller.rb file contains all of the Undo functionality code for Expertiza.  All other controllers are able to call the necessary undo-related methods to enable the Undo functionality.&lt;br /&gt;
&lt;br /&gt;
=== Framework Leveraged &amp;amp; Enhanced ===&lt;br /&gt;
*Paper Trail(https://github.com/airblade/paper_trail)&lt;br /&gt;
**Paper Trail allows for tracking changes to model data. &lt;br /&gt;
***Good for auditing or versioning. &lt;br /&gt;
**Offers many functionalities including:&lt;br /&gt;
****Viewing a model at any stage in its lifecycle. &lt;br /&gt;
****Reverting a model to any version.&lt;br /&gt;
****Undeleting items after they have been destroyed.&lt;br /&gt;
**Compatible with Rails-2.3.15, which is the version Expertiza uses. &lt;br /&gt;
**There is a [http://railscasts.com/episodes/255-undo-with-paper-trail Railscast] showing how to implement the undo feature with Paper Trail. &lt;br /&gt;
**Ranked as the most popular framework for Active Record versioning feature in [https://www.ruby-toolbox.com/categories/Active_Record_Versioning here]&lt;br /&gt;
*Enhancement&lt;br /&gt;
**Paper Trail only supported undo of the most recent action and did not restore associations.   &lt;br /&gt;
**Paper Trail customized to add support for restoring associations within the Expertiza system.  &lt;br /&gt;
***Database transactions paired with timestamps and user ids to group them together.&lt;br /&gt;
&lt;br /&gt;
=== Classes Modified ===&lt;br /&gt;
*apps/&lt;br /&gt;
**controllers/&lt;br /&gt;
***application_controller.rb&lt;br /&gt;
***assignment_controller.rb&lt;br /&gt;
***course_controller.rb&lt;br /&gt;
***import_file_controller.rb&lt;br /&gt;
***participants_controller.rb&lt;br /&gt;
***sign_up_sheet_controller.rb&lt;br /&gt;
***student_team_controller.rb&lt;br /&gt;
***team_controller.rb&lt;br /&gt;
***teams_users_controller.rb&lt;br /&gt;
***versions_controller.rb&lt;br /&gt;
**models/&lt;br /&gt;
***assignment_participant.rb&lt;br /&gt;
***participant.rb&lt;br /&gt;
***sign_up_topic.rb&lt;br /&gt;
***ta_mapping.rb&lt;br /&gt;
***team_node.rb&lt;br /&gt;
***teams_user.rb&lt;br /&gt;
&lt;br /&gt;
=== Unit &amp;amp; Functional Tests ===&lt;br /&gt;
The implementation of the Undo functionality did not afford any testing opportunities applicable to unit or functional tests.&lt;br /&gt;
&lt;br /&gt;
=== Bug Fixes &amp;amp; Other Improvements ===&lt;br /&gt;
The following bugs were found within Expertiza and fixed:&lt;br /&gt;
*ApplicationController enhanced to rescue from ActiveRecord::RecordNotFound errors and redirect to tree display.  &lt;br /&gt;
*Copy of Assignment opened Edit page for the original Assignment and now correctly opens the Edit page for the copy of the assignment.  &lt;br /&gt;
&lt;br /&gt;
The following general improvements were made:&lt;br /&gt;
*Assignment object associated with an AssignmentNode to eliminate the manual deletion of a related AssignmentNode with the code.  &lt;br /&gt;
*Edited the Copy of Course flash message to be more clear that the copy had already been created and to resolve a misspelling. &lt;br /&gt;
&lt;br /&gt;
=== Problem Areas with Expertiza ===&lt;br /&gt;
There were some areas of functionality within Expertiza that did not work.  There were some cases in which the undo functionality could not be added due to the inherent problems.  These problem areas were:&lt;br /&gt;
*Assigning surveys in an assignment.&lt;br /&gt;
*Dates in assignments do not show up when the assignment is edited.   &lt;br /&gt;
*Unable to assign random reviewers. &lt;br /&gt;
*Unable to edit advice for questions in questionnaire. &lt;br /&gt;
*Unable to remove participants from a course.&lt;br /&gt;
&lt;br /&gt;
=== Future Recommendations ===&lt;br /&gt;
*Add integration tests. &lt;br /&gt;
*Add undo functionality to other areas of Expertiza.&lt;br /&gt;
*Determine appropriate methodology for cleaning up Versions table.&lt;/div&gt;</summary>
		<author><name>Kbyarbor</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2013/FINAL_PROJECT_E736_UNDO_DELIVERABLE&amp;diff=75088</id>
		<title>CSC/ECE 517 Spring 2013/FINAL PROJECT E736 UNDO DELIVERABLE</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2013/FINAL_PROJECT_E736_UNDO_DELIVERABLE&amp;diff=75088"/>
		<updated>2013-04-22T01:09:12Z</updated>

		<summary type="html">&lt;p&gt;Kbyarbor: /* Future Recommendations */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= E736. Undo Functionality for Expertiza =&lt;br /&gt;
*Contacts: Ed Gehringer (efg@ncsu.edu) and Andrew Kofink (ajkofink@ncsu.edu)&lt;br /&gt;
*[http://wiki.expertiza.ncsu.edu/index.php/CSC/ECE_517_Spring_2013/FINAL_PROJECT_E736_UNDO Design Document]&lt;br /&gt;
*[https://docs.google.com/a/ncsu.edu/document/d/11YTjxFXFR13vJ769yFBbqn9qOueK2Ktz0Pd-gyS2W5U/ Project Description Doc]&lt;br /&gt;
== Team Members ==&lt;br /&gt;
*Chun Sing Tsui (ctsui@ncsu.edu)&lt;br /&gt;
*Kenny Yarboro (kbyarbor@ncsu.edu)&lt;br /&gt;
*Meng Cao (mcao2@ncsu.edu)&lt;br /&gt;
*Travis Folsom (twfolsom@ncsu.edu)&lt;br /&gt;
&lt;br /&gt;
== Project Deliverables ==&lt;br /&gt;
&lt;br /&gt;
=== Screencast Video Overview ===&lt;br /&gt;
A video overview of the project was created via [http://www.screencast-o-matic.com/ Screencast-O-Matic] and can be found [http://www.youtube.com/watch?v=1DYS5InjBOk here].  &lt;br /&gt;
&lt;br /&gt;
=== Overview of Undo Functionality ===&lt;br /&gt;
*Undo allows the user to undo their most recent actions for any items that offer the undo functionality.  &lt;br /&gt;
*The undo of file submissions was not required; however, we did or did not do these....depends on if we complete it...&lt;br /&gt;
*If an undo is attempted on an item already modified by another user, a message is displayed stating why undo cannot be performed.  Otherwise, the user is able to undo any changes to an item with the undo functionality.  &lt;br /&gt;
*When multiple actions are performed in one step, the undo functionality groups all of the changes together for the purposes of restoring all items affected by the action previously performed.&lt;br /&gt;
&lt;br /&gt;
=== List of Items Now Supported by Undo Functionality === &lt;br /&gt;
*Add Signup Sheet&lt;br /&gt;
**Delete Topic&lt;br /&gt;
**Edit Topic&lt;br /&gt;
**New Topic&lt;br /&gt;
*Assignments&lt;br /&gt;
**Add Participants&lt;br /&gt;
**Copy&lt;br /&gt;
**Create&lt;br /&gt;
**Delete&lt;br /&gt;
**Edit&lt;br /&gt;
*Courses&lt;br /&gt;
**Add Participants&lt;br /&gt;
**Copy&lt;br /&gt;
**Create&lt;br /&gt;
**Delete&lt;br /&gt;
**Edit&lt;br /&gt;
**Toggle Private/Public&lt;br /&gt;
*Import&lt;br /&gt;
**Import Participants&lt;br /&gt;
**Import Teams&lt;br /&gt;
**Import Users&lt;br /&gt;
*Student Actions&lt;br /&gt;
**Create Team&lt;br /&gt;
**Edit Team Name&lt;br /&gt;
**Leave Team&lt;br /&gt;
**Submit Hyperlink&lt;br /&gt;
*Questions&lt;br /&gt;
**Copy&lt;br /&gt;
**Create&lt;br /&gt;
**Delete&lt;br /&gt;
**Edit&lt;br /&gt;
*Questionnaires&lt;br /&gt;
**Copy&lt;br /&gt;
**Create&lt;br /&gt;
**Delete&lt;br /&gt;
**Edit&lt;br /&gt;
*Teams&lt;br /&gt;
**Add&lt;br /&gt;
**Create (Manual)&lt;br /&gt;
**Create (Random)&lt;br /&gt;
**Delete&lt;br /&gt;
**Delete All Teams&lt;br /&gt;
**Edit&lt;br /&gt;
&lt;br /&gt;
=== Redo Functionality ===&lt;br /&gt;
In addition to the Undo functionality being added, the ability to Redo an undone action is also implemented.  Whenever an Undo is performed, the user is given an option to Redo the action that was undone.  Whenever a Redo is performed, the user is given an option to Undo the action again.  &lt;br /&gt;
&lt;br /&gt;
=== Design Patterns and Designs ===&lt;br /&gt;
*DRY&lt;br /&gt;
**&amp;quot;Don't Repeat Yourself&amp;quot; practice was followed. &lt;br /&gt;
**The app/controllers/application_controller.rb file contains all of the Undo functionality code for Expertiza.  All other controllers are able to call the necessary undo-related methods to enable the Undo functionality.&lt;br /&gt;
&lt;br /&gt;
=== Framework Leveraged &amp;amp; Enhanced ===&lt;br /&gt;
*Paper Trail(https://github.com/airblade/paper_trail)&lt;br /&gt;
**Paper Trail allows for tracking changes to model data. &lt;br /&gt;
***Good for auditing or versioning. &lt;br /&gt;
**Offers many functionalities including:&lt;br /&gt;
****Viewing a model at any stage in its lifecycle. &lt;br /&gt;
****Reverting a model to any version.&lt;br /&gt;
****Undeleting items after they have been destroyed.&lt;br /&gt;
**Compatible with Rails-2.3.15, which is the version Expertiza uses. &lt;br /&gt;
**There is a [http://railscasts.com/episodes/255-undo-with-paper-trail Railscast] showing how to implement the undo feature with Paper Trail. &lt;br /&gt;
**Ranked as the most popular framework for Active Record versioning feature in [https://www.ruby-toolbox.com/categories/Active_Record_Versioning here]&lt;br /&gt;
*Enhancement&lt;br /&gt;
**Paper Trail only supported undo of the most recent action and did not restore associations.   &lt;br /&gt;
**Paper Trail customized to add support for restoring associations within the Expertiza system.  &lt;br /&gt;
***Database transactions paired with timestamps and user ids to group them together.&lt;br /&gt;
&lt;br /&gt;
=== Classes Modified ===&lt;br /&gt;
*apps/&lt;br /&gt;
**controllers/&lt;br /&gt;
***application_controller.rb&lt;br /&gt;
***assignment_controller.rb&lt;br /&gt;
***course_controller.rb&lt;br /&gt;
***import_file_controller.rb&lt;br /&gt;
***participants_controller.rb&lt;br /&gt;
***sign_up_sheet_controller.rb&lt;br /&gt;
***student_team_controller.rb&lt;br /&gt;
***team_controller.rb&lt;br /&gt;
***teams_users_controller.rb&lt;br /&gt;
***versions_controller.rb&lt;br /&gt;
**models/&lt;br /&gt;
***assignment_participant.rb&lt;br /&gt;
***participant.rb&lt;br /&gt;
***sign_up_topic.rb&lt;br /&gt;
***ta_mapping.rb&lt;br /&gt;
***team_node.rb&lt;br /&gt;
***teams_user.rb&lt;br /&gt;
&lt;br /&gt;
=== Unit &amp;amp; Functional Tests ===&lt;br /&gt;
The implementation of the Undo functionality did not afford any testing opportunities applicable to unit or functional tests.&lt;br /&gt;
&lt;br /&gt;
=== Future Recommendations ===&lt;br /&gt;
*Add integration tests. &lt;br /&gt;
*Add undo functionality to other areas of Expertiza.&lt;br /&gt;
*Determine appropriate methodology for cleaning up Versions table.&lt;/div&gt;</summary>
		<author><name>Kbyarbor</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2013/FINAL_PROJECT_E736_UNDO_DELIVERABLE&amp;diff=75087</id>
		<title>CSC/ECE 517 Spring 2013/FINAL PROJECT E736 UNDO DELIVERABLE</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2013/FINAL_PROJECT_E736_UNDO_DELIVERABLE&amp;diff=75087"/>
		<updated>2013-04-22T01:04:09Z</updated>

		<summary type="html">&lt;p&gt;Kbyarbor: /* Framework Leveraged &amp;amp; Enhanced */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= E736. Undo Functionality for Expertiza =&lt;br /&gt;
*Contacts: Ed Gehringer (efg@ncsu.edu) and Andrew Kofink (ajkofink@ncsu.edu)&lt;br /&gt;
*[http://wiki.expertiza.ncsu.edu/index.php/CSC/ECE_517_Spring_2013/FINAL_PROJECT_E736_UNDO Design Document]&lt;br /&gt;
*[https://docs.google.com/a/ncsu.edu/document/d/11YTjxFXFR13vJ769yFBbqn9qOueK2Ktz0Pd-gyS2W5U/ Project Description Doc]&lt;br /&gt;
== Team Members ==&lt;br /&gt;
*Chun Sing Tsui (ctsui@ncsu.edu)&lt;br /&gt;
*Kenny Yarboro (kbyarbor@ncsu.edu)&lt;br /&gt;
*Meng Cao (mcao2@ncsu.edu)&lt;br /&gt;
*Travis Folsom (twfolsom@ncsu.edu)&lt;br /&gt;
&lt;br /&gt;
== Project Deliverables ==&lt;br /&gt;
&lt;br /&gt;
=== Screencast Video Overview ===&lt;br /&gt;
A video overview of the project was created via [http://www.screencast-o-matic.com/ Screencast-O-Matic] and can be found [http://www.youtube.com/watch?v=1DYS5InjBOk here].  &lt;br /&gt;
&lt;br /&gt;
=== Overview of Undo Functionality ===&lt;br /&gt;
*Undo allows the user to undo their most recent actions for any items that offer the undo functionality.  &lt;br /&gt;
*The undo of file submissions was not required; however, we did or did not do these....depends on if we complete it...&lt;br /&gt;
*If an undo is attempted on an item already modified by another user, a message is displayed stating why undo cannot be performed.  Otherwise, the user is able to undo any changes to an item with the undo functionality.  &lt;br /&gt;
*When multiple actions are performed in one step, the undo functionality groups all of the changes together for the purposes of restoring all items affected by the action previously performed.&lt;br /&gt;
&lt;br /&gt;
=== List of Items Now Supported by Undo Functionality === &lt;br /&gt;
*Add Signup Sheet&lt;br /&gt;
**Delete Topic&lt;br /&gt;
**Edit Topic&lt;br /&gt;
**New Topic&lt;br /&gt;
*Assignments&lt;br /&gt;
**Add Participants&lt;br /&gt;
**Copy&lt;br /&gt;
**Create&lt;br /&gt;
**Delete&lt;br /&gt;
**Edit&lt;br /&gt;
*Courses&lt;br /&gt;
**Add Participants&lt;br /&gt;
**Copy&lt;br /&gt;
**Create&lt;br /&gt;
**Delete&lt;br /&gt;
**Edit&lt;br /&gt;
**Toggle Private/Public&lt;br /&gt;
*Import&lt;br /&gt;
**Import Participants&lt;br /&gt;
**Import Teams&lt;br /&gt;
**Import Users&lt;br /&gt;
*Student Actions&lt;br /&gt;
**Create Team&lt;br /&gt;
**Edit Team Name&lt;br /&gt;
**Leave Team&lt;br /&gt;
**Submit Hyperlink&lt;br /&gt;
*Questions&lt;br /&gt;
**Copy&lt;br /&gt;
**Create&lt;br /&gt;
**Delete&lt;br /&gt;
**Edit&lt;br /&gt;
*Questionnaires&lt;br /&gt;
**Copy&lt;br /&gt;
**Create&lt;br /&gt;
**Delete&lt;br /&gt;
**Edit&lt;br /&gt;
*Teams&lt;br /&gt;
**Add&lt;br /&gt;
**Create (Manual)&lt;br /&gt;
**Create (Random)&lt;br /&gt;
**Delete&lt;br /&gt;
**Delete All Teams&lt;br /&gt;
**Edit&lt;br /&gt;
&lt;br /&gt;
=== Redo Functionality ===&lt;br /&gt;
In addition to the Undo functionality being added, the ability to Redo an undone action is also implemented.  Whenever an Undo is performed, the user is given an option to Redo the action that was undone.  Whenever a Redo is performed, the user is given an option to Undo the action again.  &lt;br /&gt;
&lt;br /&gt;
=== Design Patterns and Designs ===&lt;br /&gt;
*DRY&lt;br /&gt;
**&amp;quot;Don't Repeat Yourself&amp;quot; practice was followed. &lt;br /&gt;
**The app/controllers/application_controller.rb file contains all of the Undo functionality code for Expertiza.  All other controllers are able to call the necessary undo-related methods to enable the Undo functionality.&lt;br /&gt;
&lt;br /&gt;
=== Framework Leveraged &amp;amp; Enhanced ===&lt;br /&gt;
*Paper Trail(https://github.com/airblade/paper_trail)&lt;br /&gt;
**Paper Trail allows for tracking changes to model data. &lt;br /&gt;
***Good for auditing or versioning. &lt;br /&gt;
**Offers many functionalities including:&lt;br /&gt;
****Viewing a model at any stage in its lifecycle. &lt;br /&gt;
****Reverting a model to any version.&lt;br /&gt;
****Undeleting items after they have been destroyed.&lt;br /&gt;
**Compatible with Rails-2.3.15, which is the version Expertiza uses. &lt;br /&gt;
**There is a [http://railscasts.com/episodes/255-undo-with-paper-trail Railscast] showing how to implement the undo feature with Paper Trail. &lt;br /&gt;
**Ranked as the most popular framework for Active Record versioning feature in [https://www.ruby-toolbox.com/categories/Active_Record_Versioning here]&lt;br /&gt;
*Enhancement&lt;br /&gt;
**Paper Trail only supported undo of the most recent action and did not restore associations.   &lt;br /&gt;
**Paper Trail customized to add support for restoring associations within the Expertiza system.  &lt;br /&gt;
***Database transactions paired with timestamps and user ids to group them together.&lt;br /&gt;
&lt;br /&gt;
=== Classes Modified ===&lt;br /&gt;
*apps/&lt;br /&gt;
**controllers/&lt;br /&gt;
***application_controller.rb&lt;br /&gt;
***assignment_controller.rb&lt;br /&gt;
***course_controller.rb&lt;br /&gt;
***import_file_controller.rb&lt;br /&gt;
***participants_controller.rb&lt;br /&gt;
***sign_up_sheet_controller.rb&lt;br /&gt;
***student_team_controller.rb&lt;br /&gt;
***team_controller.rb&lt;br /&gt;
***teams_users_controller.rb&lt;br /&gt;
***versions_controller.rb&lt;br /&gt;
**models/&lt;br /&gt;
***assignment_participant.rb&lt;br /&gt;
***participant.rb&lt;br /&gt;
***sign_up_topic.rb&lt;br /&gt;
***ta_mapping.rb&lt;br /&gt;
***team_node.rb&lt;br /&gt;
***teams_user.rb&lt;br /&gt;
&lt;br /&gt;
=== Unit &amp;amp; Functional Tests ===&lt;br /&gt;
The implementation of the Undo functionality did not afford any testing opportunities applicable to unit or functional tests.&lt;br /&gt;
&lt;br /&gt;
=== Future Recommendations ===&lt;br /&gt;
*Add integration tests. &lt;br /&gt;
*Add undo functionality to other areas of Expertiza.&lt;/div&gt;</summary>
		<author><name>Kbyarbor</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2013/FINAL_PROJECT_E736_UNDO_DELIVERABLE&amp;diff=75086</id>
		<title>CSC/ECE 517 Spring 2013/FINAL PROJECT E736 UNDO DELIVERABLE</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2013/FINAL_PROJECT_E736_UNDO_DELIVERABLE&amp;diff=75086"/>
		<updated>2013-04-22T01:03:01Z</updated>

		<summary type="html">&lt;p&gt;Kbyarbor: /* Functional Testing Plans */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= E736. Undo Functionality for Expertiza =&lt;br /&gt;
*Contacts: Ed Gehringer (efg@ncsu.edu) and Andrew Kofink (ajkofink@ncsu.edu)&lt;br /&gt;
*[http://wiki.expertiza.ncsu.edu/index.php/CSC/ECE_517_Spring_2013/FINAL_PROJECT_E736_UNDO Design Document]&lt;br /&gt;
*[https://docs.google.com/a/ncsu.edu/document/d/11YTjxFXFR13vJ769yFBbqn9qOueK2Ktz0Pd-gyS2W5U/ Project Description Doc]&lt;br /&gt;
== Team Members ==&lt;br /&gt;
*Chun Sing Tsui (ctsui@ncsu.edu)&lt;br /&gt;
*Kenny Yarboro (kbyarbor@ncsu.edu)&lt;br /&gt;
*Meng Cao (mcao2@ncsu.edu)&lt;br /&gt;
*Travis Folsom (twfolsom@ncsu.edu)&lt;br /&gt;
&lt;br /&gt;
== Project Deliverables ==&lt;br /&gt;
&lt;br /&gt;
=== Screencast Video Overview ===&lt;br /&gt;
A video overview of the project was created via [http://www.screencast-o-matic.com/ Screencast-O-Matic] and can be found [http://www.youtube.com/watch?v=1DYS5InjBOk here].  &lt;br /&gt;
&lt;br /&gt;
=== Overview of Undo Functionality ===&lt;br /&gt;
*Undo allows the user to undo their most recent actions for any items that offer the undo functionality.  &lt;br /&gt;
*The undo of file submissions was not required; however, we did or did not do these....depends on if we complete it...&lt;br /&gt;
*If an undo is attempted on an item already modified by another user, a message is displayed stating why undo cannot be performed.  Otherwise, the user is able to undo any changes to an item with the undo functionality.  &lt;br /&gt;
*When multiple actions are performed in one step, the undo functionality groups all of the changes together for the purposes of restoring all items affected by the action previously performed.&lt;br /&gt;
&lt;br /&gt;
=== List of Items Now Supported by Undo Functionality === &lt;br /&gt;
*Add Signup Sheet&lt;br /&gt;
**Delete Topic&lt;br /&gt;
**Edit Topic&lt;br /&gt;
**New Topic&lt;br /&gt;
*Assignments&lt;br /&gt;
**Add Participants&lt;br /&gt;
**Copy&lt;br /&gt;
**Create&lt;br /&gt;
**Delete&lt;br /&gt;
**Edit&lt;br /&gt;
*Courses&lt;br /&gt;
**Add Participants&lt;br /&gt;
**Copy&lt;br /&gt;
**Create&lt;br /&gt;
**Delete&lt;br /&gt;
**Edit&lt;br /&gt;
**Toggle Private/Public&lt;br /&gt;
*Import&lt;br /&gt;
**Import Participants&lt;br /&gt;
**Import Teams&lt;br /&gt;
**Import Users&lt;br /&gt;
*Student Actions&lt;br /&gt;
**Create Team&lt;br /&gt;
**Edit Team Name&lt;br /&gt;
**Leave Team&lt;br /&gt;
**Submit Hyperlink&lt;br /&gt;
*Questions&lt;br /&gt;
**Copy&lt;br /&gt;
**Create&lt;br /&gt;
**Delete&lt;br /&gt;
**Edit&lt;br /&gt;
*Questionnaires&lt;br /&gt;
**Copy&lt;br /&gt;
**Create&lt;br /&gt;
**Delete&lt;br /&gt;
**Edit&lt;br /&gt;
*Teams&lt;br /&gt;
**Add&lt;br /&gt;
**Create (Manual)&lt;br /&gt;
**Create (Random)&lt;br /&gt;
**Delete&lt;br /&gt;
**Delete All Teams&lt;br /&gt;
**Edit&lt;br /&gt;
&lt;br /&gt;
=== Redo Functionality ===&lt;br /&gt;
In addition to the Undo functionality being added, the ability to Redo an undone action is also implemented.  Whenever an Undo is performed, the user is given an option to Redo the action that was undone.  Whenever a Redo is performed, the user is given an option to Undo the action again.  &lt;br /&gt;
&lt;br /&gt;
=== Design Patterns and Designs ===&lt;br /&gt;
*DRY&lt;br /&gt;
**&amp;quot;Don't Repeat Yourself&amp;quot; practice was followed. &lt;br /&gt;
**The app/controllers/application_controller.rb file contains all of the Undo functionality code for Expertiza.  All other controllers are able to call the necessary undo-related methods to enable the Undo functionality.&lt;br /&gt;
&lt;br /&gt;
=== Framework Leveraged &amp;amp; Enhanced ===&lt;br /&gt;
*Paper Trail(https://github.com/airblade/paper_trail)&lt;br /&gt;
**Paper Trail allows for tracking changes to model data. &lt;br /&gt;
***Good for auditing or versioning. &lt;br /&gt;
**Offers many functionalities including:&lt;br /&gt;
****Viewing a model at any stage in its lifecycle. &lt;br /&gt;
****Reverting a model to any version.&lt;br /&gt;
****Undeleting items after they have been destroyed.&lt;br /&gt;
**Compatible with Rails-2.3.15, which is the version Expertiza uses. &lt;br /&gt;
**There is a [http://railscasts.com/episodes/255-undo-with-paper-trail Railscast] showing how to implement the undo feature with Paper Trail. &lt;br /&gt;
**Ranked as the most popular framework for Active Record versioning feature in [https://www.ruby-toolbox.com/categories/Active_Record_Versioning here]&lt;br /&gt;
*Enhancement&lt;br /&gt;
**Paper Trail only supported undo of the most recent action and did not restore associations.   &lt;br /&gt;
**Paper Trail customized to add support for restoring associations within the Expertiza system.  &lt;br /&gt;
***Description of modification...&lt;br /&gt;
&lt;br /&gt;
=== Classes Modified ===&lt;br /&gt;
*apps/&lt;br /&gt;
**controllers/&lt;br /&gt;
***application_controller.rb&lt;br /&gt;
***assignment_controller.rb&lt;br /&gt;
***course_controller.rb&lt;br /&gt;
***import_file_controller.rb&lt;br /&gt;
***participants_controller.rb&lt;br /&gt;
***sign_up_sheet_controller.rb&lt;br /&gt;
***student_team_controller.rb&lt;br /&gt;
***team_controller.rb&lt;br /&gt;
***teams_users_controller.rb&lt;br /&gt;
***versions_controller.rb&lt;br /&gt;
**models/&lt;br /&gt;
***assignment_participant.rb&lt;br /&gt;
***participant.rb&lt;br /&gt;
***sign_up_topic.rb&lt;br /&gt;
***ta_mapping.rb&lt;br /&gt;
***team_node.rb&lt;br /&gt;
***teams_user.rb&lt;br /&gt;
&lt;br /&gt;
=== Unit &amp;amp; Functional Tests ===&lt;br /&gt;
The implementation of the Undo functionality did not afford any testing opportunities applicable to unit or functional tests.&lt;br /&gt;
&lt;br /&gt;
=== Future Recommendations ===&lt;br /&gt;
*Add integration tests. &lt;br /&gt;
*Add undo functionality to other areas of Expertiza.&lt;/div&gt;</summary>
		<author><name>Kbyarbor</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2013/FINAL_PROJECT_E736_UNDO_DELIVERABLE&amp;diff=75085</id>
		<title>CSC/ECE 517 Spring 2013/FINAL PROJECT E736 UNDO DELIVERABLE</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2013/FINAL_PROJECT_E736_UNDO_DELIVERABLE&amp;diff=75085"/>
		<updated>2013-04-22T01:01:46Z</updated>

		<summary type="html">&lt;p&gt;Kbyarbor: /* Unit Tests */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= E736. Undo Functionality for Expertiza =&lt;br /&gt;
*Contacts: Ed Gehringer (efg@ncsu.edu) and Andrew Kofink (ajkofink@ncsu.edu)&lt;br /&gt;
*[http://wiki.expertiza.ncsu.edu/index.php/CSC/ECE_517_Spring_2013/FINAL_PROJECT_E736_UNDO Design Document]&lt;br /&gt;
*[https://docs.google.com/a/ncsu.edu/document/d/11YTjxFXFR13vJ769yFBbqn9qOueK2Ktz0Pd-gyS2W5U/ Project Description Doc]&lt;br /&gt;
== Team Members ==&lt;br /&gt;
*Chun Sing Tsui (ctsui@ncsu.edu)&lt;br /&gt;
*Kenny Yarboro (kbyarbor@ncsu.edu)&lt;br /&gt;
*Meng Cao (mcao2@ncsu.edu)&lt;br /&gt;
*Travis Folsom (twfolsom@ncsu.edu)&lt;br /&gt;
&lt;br /&gt;
== Project Deliverables ==&lt;br /&gt;
&lt;br /&gt;
=== Screencast Video Overview ===&lt;br /&gt;
A video overview of the project was created via [http://www.screencast-o-matic.com/ Screencast-O-Matic] and can be found [http://www.youtube.com/watch?v=1DYS5InjBOk here].  &lt;br /&gt;
&lt;br /&gt;
=== Overview of Undo Functionality ===&lt;br /&gt;
*Undo allows the user to undo their most recent actions for any items that offer the undo functionality.  &lt;br /&gt;
*The undo of file submissions was not required; however, we did or did not do these....depends on if we complete it...&lt;br /&gt;
*If an undo is attempted on an item already modified by another user, a message is displayed stating why undo cannot be performed.  Otherwise, the user is able to undo any changes to an item with the undo functionality.  &lt;br /&gt;
*When multiple actions are performed in one step, the undo functionality groups all of the changes together for the purposes of restoring all items affected by the action previously performed.&lt;br /&gt;
&lt;br /&gt;
=== List of Items Now Supported by Undo Functionality === &lt;br /&gt;
*Add Signup Sheet&lt;br /&gt;
**Delete Topic&lt;br /&gt;
**Edit Topic&lt;br /&gt;
**New Topic&lt;br /&gt;
*Assignments&lt;br /&gt;
**Add Participants&lt;br /&gt;
**Copy&lt;br /&gt;
**Create&lt;br /&gt;
**Delete&lt;br /&gt;
**Edit&lt;br /&gt;
*Courses&lt;br /&gt;
**Add Participants&lt;br /&gt;
**Copy&lt;br /&gt;
**Create&lt;br /&gt;
**Delete&lt;br /&gt;
**Edit&lt;br /&gt;
**Toggle Private/Public&lt;br /&gt;
*Import&lt;br /&gt;
**Import Participants&lt;br /&gt;
**Import Teams&lt;br /&gt;
**Import Users&lt;br /&gt;
*Student Actions&lt;br /&gt;
**Create Team&lt;br /&gt;
**Edit Team Name&lt;br /&gt;
**Leave Team&lt;br /&gt;
**Submit Hyperlink&lt;br /&gt;
*Questions&lt;br /&gt;
**Copy&lt;br /&gt;
**Create&lt;br /&gt;
**Delete&lt;br /&gt;
**Edit&lt;br /&gt;
*Questionnaires&lt;br /&gt;
**Copy&lt;br /&gt;
**Create&lt;br /&gt;
**Delete&lt;br /&gt;
**Edit&lt;br /&gt;
*Teams&lt;br /&gt;
**Add&lt;br /&gt;
**Create (Manual)&lt;br /&gt;
**Create (Random)&lt;br /&gt;
**Delete&lt;br /&gt;
**Delete All Teams&lt;br /&gt;
**Edit&lt;br /&gt;
&lt;br /&gt;
=== Redo Functionality ===&lt;br /&gt;
In addition to the Undo functionality being added, the ability to Redo an undone action is also implemented.  Whenever an Undo is performed, the user is given an option to Redo the action that was undone.  Whenever a Redo is performed, the user is given an option to Undo the action again.  &lt;br /&gt;
&lt;br /&gt;
=== Design Patterns and Designs ===&lt;br /&gt;
*DRY&lt;br /&gt;
**&amp;quot;Don't Repeat Yourself&amp;quot; practice was followed. &lt;br /&gt;
**The app/controllers/application_controller.rb file contains all of the Undo functionality code for Expertiza.  All other controllers are able to call the necessary undo-related methods to enable the Undo functionality.&lt;br /&gt;
&lt;br /&gt;
=== Framework Leveraged &amp;amp; Enhanced ===&lt;br /&gt;
*Paper Trail(https://github.com/airblade/paper_trail)&lt;br /&gt;
**Paper Trail allows for tracking changes to model data. &lt;br /&gt;
***Good for auditing or versioning. &lt;br /&gt;
**Offers many functionalities including:&lt;br /&gt;
****Viewing a model at any stage in its lifecycle. &lt;br /&gt;
****Reverting a model to any version.&lt;br /&gt;
****Undeleting items after they have been destroyed.&lt;br /&gt;
**Compatible with Rails-2.3.15, which is the version Expertiza uses. &lt;br /&gt;
**There is a [http://railscasts.com/episodes/255-undo-with-paper-trail Railscast] showing how to implement the undo feature with Paper Trail. &lt;br /&gt;
**Ranked as the most popular framework for Active Record versioning feature in [https://www.ruby-toolbox.com/categories/Active_Record_Versioning here]&lt;br /&gt;
*Enhancement&lt;br /&gt;
**Paper Trail only supported undo of the most recent action and did not restore associations.   &lt;br /&gt;
**Paper Trail customized to add support for restoring associations within the Expertiza system.  &lt;br /&gt;
***Description of modification...&lt;br /&gt;
&lt;br /&gt;
=== Classes Modified ===&lt;br /&gt;
*apps/&lt;br /&gt;
**controllers/&lt;br /&gt;
***application_controller.rb&lt;br /&gt;
***assignment_controller.rb&lt;br /&gt;
***course_controller.rb&lt;br /&gt;
***import_file_controller.rb&lt;br /&gt;
***participants_controller.rb&lt;br /&gt;
***sign_up_sheet_controller.rb&lt;br /&gt;
***student_team_controller.rb&lt;br /&gt;
***team_controller.rb&lt;br /&gt;
***teams_users_controller.rb&lt;br /&gt;
***versions_controller.rb&lt;br /&gt;
**models/&lt;br /&gt;
***assignment_participant.rb&lt;br /&gt;
***participant.rb&lt;br /&gt;
***sign_up_topic.rb&lt;br /&gt;
***ta_mapping.rb&lt;br /&gt;
***team_node.rb&lt;br /&gt;
***teams_user.rb&lt;br /&gt;
&lt;br /&gt;
=== Unit &amp;amp; Functional Tests ===&lt;br /&gt;
The implementation of the Undo functionality did not afford any testing opportunities applicable to unit or functional tests.&lt;br /&gt;
&lt;br /&gt;
=== Functional Testing Plans ===&lt;br /&gt;
*Modified Tests&lt;br /&gt;
**test file&lt;br /&gt;
***test method&lt;br /&gt;
*New Tests&lt;br /&gt;
**test file&lt;br /&gt;
***test method&lt;/div&gt;</summary>
		<author><name>Kbyarbor</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2013/FINAL_PROJECT_E736_UNDO_DELIVERABLE&amp;diff=75084</id>
		<title>CSC/ECE 517 Spring 2013/FINAL PROJECT E736 UNDO DELIVERABLE</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2013/FINAL_PROJECT_E736_UNDO_DELIVERABLE&amp;diff=75084"/>
		<updated>2013-04-22T00:59:11Z</updated>

		<summary type="html">&lt;p&gt;Kbyarbor: /* Classes Modified */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= E736. Undo Functionality for Expertiza =&lt;br /&gt;
*Contacts: Ed Gehringer (efg@ncsu.edu) and Andrew Kofink (ajkofink@ncsu.edu)&lt;br /&gt;
*[http://wiki.expertiza.ncsu.edu/index.php/CSC/ECE_517_Spring_2013/FINAL_PROJECT_E736_UNDO Design Document]&lt;br /&gt;
*[https://docs.google.com/a/ncsu.edu/document/d/11YTjxFXFR13vJ769yFBbqn9qOueK2Ktz0Pd-gyS2W5U/ Project Description Doc]&lt;br /&gt;
== Team Members ==&lt;br /&gt;
*Chun Sing Tsui (ctsui@ncsu.edu)&lt;br /&gt;
*Kenny Yarboro (kbyarbor@ncsu.edu)&lt;br /&gt;
*Meng Cao (mcao2@ncsu.edu)&lt;br /&gt;
*Travis Folsom (twfolsom@ncsu.edu)&lt;br /&gt;
&lt;br /&gt;
== Project Deliverables ==&lt;br /&gt;
&lt;br /&gt;
=== Screencast Video Overview ===&lt;br /&gt;
A video overview of the project was created via [http://www.screencast-o-matic.com/ Screencast-O-Matic] and can be found [http://www.youtube.com/watch?v=1DYS5InjBOk here].  &lt;br /&gt;
&lt;br /&gt;
=== Overview of Undo Functionality ===&lt;br /&gt;
*Undo allows the user to undo their most recent actions for any items that offer the undo functionality.  &lt;br /&gt;
*The undo of file submissions was not required; however, we did or did not do these....depends on if we complete it...&lt;br /&gt;
*If an undo is attempted on an item already modified by another user, a message is displayed stating why undo cannot be performed.  Otherwise, the user is able to undo any changes to an item with the undo functionality.  &lt;br /&gt;
*When multiple actions are performed in one step, the undo functionality groups all of the changes together for the purposes of restoring all items affected by the action previously performed.&lt;br /&gt;
&lt;br /&gt;
=== List of Items Now Supported by Undo Functionality === &lt;br /&gt;
*Add Signup Sheet&lt;br /&gt;
**Delete Topic&lt;br /&gt;
**Edit Topic&lt;br /&gt;
**New Topic&lt;br /&gt;
*Assignments&lt;br /&gt;
**Add Participants&lt;br /&gt;
**Copy&lt;br /&gt;
**Create&lt;br /&gt;
**Delete&lt;br /&gt;
**Edit&lt;br /&gt;
*Courses&lt;br /&gt;
**Add Participants&lt;br /&gt;
**Copy&lt;br /&gt;
**Create&lt;br /&gt;
**Delete&lt;br /&gt;
**Edit&lt;br /&gt;
**Toggle Private/Public&lt;br /&gt;
*Import&lt;br /&gt;
**Import Participants&lt;br /&gt;
**Import Teams&lt;br /&gt;
**Import Users&lt;br /&gt;
*Student Actions&lt;br /&gt;
**Create Team&lt;br /&gt;
**Edit Team Name&lt;br /&gt;
**Leave Team&lt;br /&gt;
**Submit Hyperlink&lt;br /&gt;
*Questions&lt;br /&gt;
**Copy&lt;br /&gt;
**Create&lt;br /&gt;
**Delete&lt;br /&gt;
**Edit&lt;br /&gt;
*Questionnaires&lt;br /&gt;
**Copy&lt;br /&gt;
**Create&lt;br /&gt;
**Delete&lt;br /&gt;
**Edit&lt;br /&gt;
*Teams&lt;br /&gt;
**Add&lt;br /&gt;
**Create (Manual)&lt;br /&gt;
**Create (Random)&lt;br /&gt;
**Delete&lt;br /&gt;
**Delete All Teams&lt;br /&gt;
**Edit&lt;br /&gt;
&lt;br /&gt;
=== Redo Functionality ===&lt;br /&gt;
In addition to the Undo functionality being added, the ability to Redo an undone action is also implemented.  Whenever an Undo is performed, the user is given an option to Redo the action that was undone.  Whenever a Redo is performed, the user is given an option to Undo the action again.  &lt;br /&gt;
&lt;br /&gt;
=== Design Patterns and Designs ===&lt;br /&gt;
*DRY&lt;br /&gt;
**&amp;quot;Don't Repeat Yourself&amp;quot; practice was followed. &lt;br /&gt;
**The app/controllers/application_controller.rb file contains all of the Undo functionality code for Expertiza.  All other controllers are able to call the necessary undo-related methods to enable the Undo functionality.&lt;br /&gt;
&lt;br /&gt;
=== Framework Leveraged &amp;amp; Enhanced ===&lt;br /&gt;
*Paper Trail(https://github.com/airblade/paper_trail)&lt;br /&gt;
**Paper Trail allows for tracking changes to model data. &lt;br /&gt;
***Good for auditing or versioning. &lt;br /&gt;
**Offers many functionalities including:&lt;br /&gt;
****Viewing a model at any stage in its lifecycle. &lt;br /&gt;
****Reverting a model to any version.&lt;br /&gt;
****Undeleting items after they have been destroyed.&lt;br /&gt;
**Compatible with Rails-2.3.15, which is the version Expertiza uses. &lt;br /&gt;
**There is a [http://railscasts.com/episodes/255-undo-with-paper-trail Railscast] showing how to implement the undo feature with Paper Trail. &lt;br /&gt;
**Ranked as the most popular framework for Active Record versioning feature in [https://www.ruby-toolbox.com/categories/Active_Record_Versioning here]&lt;br /&gt;
*Enhancement&lt;br /&gt;
**Paper Trail only supported undo of the most recent action and did not restore associations.   &lt;br /&gt;
**Paper Trail customized to add support for restoring associations within the Expertiza system.  &lt;br /&gt;
***Description of modification...&lt;br /&gt;
&lt;br /&gt;
=== Classes Modified ===&lt;br /&gt;
*apps/&lt;br /&gt;
**controllers/&lt;br /&gt;
***application_controller.rb&lt;br /&gt;
***assignment_controller.rb&lt;br /&gt;
***course_controller.rb&lt;br /&gt;
***import_file_controller.rb&lt;br /&gt;
***participants_controller.rb&lt;br /&gt;
***sign_up_sheet_controller.rb&lt;br /&gt;
***student_team_controller.rb&lt;br /&gt;
***team_controller.rb&lt;br /&gt;
***teams_users_controller.rb&lt;br /&gt;
***versions_controller.rb&lt;br /&gt;
**models/&lt;br /&gt;
***assignment_participant.rb&lt;br /&gt;
***participant.rb&lt;br /&gt;
***sign_up_topic.rb&lt;br /&gt;
***ta_mapping.rb&lt;br /&gt;
***team_node.rb&lt;br /&gt;
***teams_user.rb&lt;br /&gt;
&lt;br /&gt;
=== Unit Tests ===&lt;br /&gt;
*Modified Tests&lt;br /&gt;
**test file&lt;br /&gt;
***test method&lt;br /&gt;
*New Tests&lt;br /&gt;
**test file&lt;br /&gt;
***test method&lt;br /&gt;
&lt;br /&gt;
=== Functional Testing Plans ===&lt;br /&gt;
*Modified Tests&lt;br /&gt;
**test file&lt;br /&gt;
***test method&lt;br /&gt;
*New Tests&lt;br /&gt;
**test file&lt;br /&gt;
***test method&lt;/div&gt;</summary>
		<author><name>Kbyarbor</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2013/FINAL_PROJECT_E736_UNDO_DELIVERABLE&amp;diff=75083</id>
		<title>CSC/ECE 517 Spring 2013/FINAL PROJECT E736 UNDO DELIVERABLE</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2013/FINAL_PROJECT_E736_UNDO_DELIVERABLE&amp;diff=75083"/>
		<updated>2013-04-22T00:56:56Z</updated>

		<summary type="html">&lt;p&gt;Kbyarbor: /* Design Patterns and Designs */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= E736. Undo Functionality for Expertiza =&lt;br /&gt;
*Contacts: Ed Gehringer (efg@ncsu.edu) and Andrew Kofink (ajkofink@ncsu.edu)&lt;br /&gt;
*[http://wiki.expertiza.ncsu.edu/index.php/CSC/ECE_517_Spring_2013/FINAL_PROJECT_E736_UNDO Design Document]&lt;br /&gt;
*[https://docs.google.com/a/ncsu.edu/document/d/11YTjxFXFR13vJ769yFBbqn9qOueK2Ktz0Pd-gyS2W5U/ Project Description Doc]&lt;br /&gt;
== Team Members ==&lt;br /&gt;
*Chun Sing Tsui (ctsui@ncsu.edu)&lt;br /&gt;
*Kenny Yarboro (kbyarbor@ncsu.edu)&lt;br /&gt;
*Meng Cao (mcao2@ncsu.edu)&lt;br /&gt;
*Travis Folsom (twfolsom@ncsu.edu)&lt;br /&gt;
&lt;br /&gt;
== Project Deliverables ==&lt;br /&gt;
&lt;br /&gt;
=== Screencast Video Overview ===&lt;br /&gt;
A video overview of the project was created via [http://www.screencast-o-matic.com/ Screencast-O-Matic] and can be found [http://www.youtube.com/watch?v=1DYS5InjBOk here].  &lt;br /&gt;
&lt;br /&gt;
=== Overview of Undo Functionality ===&lt;br /&gt;
*Undo allows the user to undo their most recent actions for any items that offer the undo functionality.  &lt;br /&gt;
*The undo of file submissions was not required; however, we did or did not do these....depends on if we complete it...&lt;br /&gt;
*If an undo is attempted on an item already modified by another user, a message is displayed stating why undo cannot be performed.  Otherwise, the user is able to undo any changes to an item with the undo functionality.  &lt;br /&gt;
*When multiple actions are performed in one step, the undo functionality groups all of the changes together for the purposes of restoring all items affected by the action previously performed.&lt;br /&gt;
&lt;br /&gt;
=== List of Items Now Supported by Undo Functionality === &lt;br /&gt;
*Add Signup Sheet&lt;br /&gt;
**Delete Topic&lt;br /&gt;
**Edit Topic&lt;br /&gt;
**New Topic&lt;br /&gt;
*Assignments&lt;br /&gt;
**Add Participants&lt;br /&gt;
**Copy&lt;br /&gt;
**Create&lt;br /&gt;
**Delete&lt;br /&gt;
**Edit&lt;br /&gt;
*Courses&lt;br /&gt;
**Add Participants&lt;br /&gt;
**Copy&lt;br /&gt;
**Create&lt;br /&gt;
**Delete&lt;br /&gt;
**Edit&lt;br /&gt;
**Toggle Private/Public&lt;br /&gt;
*Import&lt;br /&gt;
**Import Participants&lt;br /&gt;
**Import Teams&lt;br /&gt;
**Import Users&lt;br /&gt;
*Student Actions&lt;br /&gt;
**Create Team&lt;br /&gt;
**Edit Team Name&lt;br /&gt;
**Leave Team&lt;br /&gt;
**Submit Hyperlink&lt;br /&gt;
*Questions&lt;br /&gt;
**Copy&lt;br /&gt;
**Create&lt;br /&gt;
**Delete&lt;br /&gt;
**Edit&lt;br /&gt;
*Questionnaires&lt;br /&gt;
**Copy&lt;br /&gt;
**Create&lt;br /&gt;
**Delete&lt;br /&gt;
**Edit&lt;br /&gt;
*Teams&lt;br /&gt;
**Add&lt;br /&gt;
**Create (Manual)&lt;br /&gt;
**Create (Random)&lt;br /&gt;
**Delete&lt;br /&gt;
**Delete All Teams&lt;br /&gt;
**Edit&lt;br /&gt;
&lt;br /&gt;
=== Redo Functionality ===&lt;br /&gt;
In addition to the Undo functionality being added, the ability to Redo an undone action is also implemented.  Whenever an Undo is performed, the user is given an option to Redo the action that was undone.  Whenever a Redo is performed, the user is given an option to Undo the action again.  &lt;br /&gt;
&lt;br /&gt;
=== Design Patterns and Designs ===&lt;br /&gt;
*DRY&lt;br /&gt;
**&amp;quot;Don't Repeat Yourself&amp;quot; practice was followed. &lt;br /&gt;
**The app/controllers/application_controller.rb file contains all of the Undo functionality code for Expertiza.  All other controllers are able to call the necessary undo-related methods to enable the Undo functionality.&lt;br /&gt;
&lt;br /&gt;
=== Framework Leveraged &amp;amp; Enhanced ===&lt;br /&gt;
*Paper Trail(https://github.com/airblade/paper_trail)&lt;br /&gt;
**Paper Trail allows for tracking changes to model data. &lt;br /&gt;
***Good for auditing or versioning. &lt;br /&gt;
**Offers many functionalities including:&lt;br /&gt;
****Viewing a model at any stage in its lifecycle. &lt;br /&gt;
****Reverting a model to any version.&lt;br /&gt;
****Undeleting items after they have been destroyed.&lt;br /&gt;
**Compatible with Rails-2.3.15, which is the version Expertiza uses. &lt;br /&gt;
**There is a [http://railscasts.com/episodes/255-undo-with-paper-trail Railscast] showing how to implement the undo feature with Paper Trail. &lt;br /&gt;
**Ranked as the most popular framework for Active Record versioning feature in [https://www.ruby-toolbox.com/categories/Active_Record_Versioning here]&lt;br /&gt;
*Enhancement&lt;br /&gt;
**Paper Trail only supported undo of the most recent action and did not restore associations.   &lt;br /&gt;
**Paper Trail customized to add support for restoring associations within the Expertiza system.  &lt;br /&gt;
***Description of modification...&lt;br /&gt;
&lt;br /&gt;
=== Classes Modified ===&lt;br /&gt;
*apps/&lt;br /&gt;
**controllers/&lt;br /&gt;
***course_controller.rb&lt;br /&gt;
***import_file_controller.rb&lt;br /&gt;
***participants_controller.rb&lt;br /&gt;
***team_controller.rb&lt;br /&gt;
***teams_users_controller.rb&lt;br /&gt;
**models/&lt;br /&gt;
***participant.rb&lt;br /&gt;
***ta_mapping.rb&lt;br /&gt;
***team_node.rb&lt;br /&gt;
***teams_user.rb&lt;br /&gt;
&lt;br /&gt;
=== Unit Tests ===&lt;br /&gt;
*Modified Tests&lt;br /&gt;
**test file&lt;br /&gt;
***test method&lt;br /&gt;
*New Tests&lt;br /&gt;
**test file&lt;br /&gt;
***test method&lt;br /&gt;
&lt;br /&gt;
=== Functional Testing Plans ===&lt;br /&gt;
*Modified Tests&lt;br /&gt;
**test file&lt;br /&gt;
***test method&lt;br /&gt;
*New Tests&lt;br /&gt;
**test file&lt;br /&gt;
***test method&lt;/div&gt;</summary>
		<author><name>Kbyarbor</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2013/FINAL_PROJECT_E736_UNDO_DELIVERABLE&amp;diff=75082</id>
		<title>CSC/ECE 517 Spring 2013/FINAL PROJECT E736 UNDO DELIVERABLE</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2013/FINAL_PROJECT_E736_UNDO_DELIVERABLE&amp;diff=75082"/>
		<updated>2013-04-22T00:53:00Z</updated>

		<summary type="html">&lt;p&gt;Kbyarbor: /* Design Patterns and Designs */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= E736. Undo Functionality for Expertiza =&lt;br /&gt;
*Contacts: Ed Gehringer (efg@ncsu.edu) and Andrew Kofink (ajkofink@ncsu.edu)&lt;br /&gt;
*[http://wiki.expertiza.ncsu.edu/index.php/CSC/ECE_517_Spring_2013/FINAL_PROJECT_E736_UNDO Design Document]&lt;br /&gt;
*[https://docs.google.com/a/ncsu.edu/document/d/11YTjxFXFR13vJ769yFBbqn9qOueK2Ktz0Pd-gyS2W5U/ Project Description Doc]&lt;br /&gt;
== Team Members ==&lt;br /&gt;
*Chun Sing Tsui (ctsui@ncsu.edu)&lt;br /&gt;
*Kenny Yarboro (kbyarbor@ncsu.edu)&lt;br /&gt;
*Meng Cao (mcao2@ncsu.edu)&lt;br /&gt;
*Travis Folsom (twfolsom@ncsu.edu)&lt;br /&gt;
&lt;br /&gt;
== Project Deliverables ==&lt;br /&gt;
&lt;br /&gt;
=== Screencast Video Overview ===&lt;br /&gt;
A video overview of the project was created via [http://www.screencast-o-matic.com/ Screencast-O-Matic] and can be found [http://www.youtube.com/watch?v=1DYS5InjBOk here].  &lt;br /&gt;
&lt;br /&gt;
=== Overview of Undo Functionality ===&lt;br /&gt;
*Undo allows the user to undo their most recent actions for any items that offer the undo functionality.  &lt;br /&gt;
*The undo of file submissions was not required; however, we did or did not do these....depends on if we complete it...&lt;br /&gt;
*If an undo is attempted on an item already modified by another user, a message is displayed stating why undo cannot be performed.  Otherwise, the user is able to undo any changes to an item with the undo functionality.  &lt;br /&gt;
*When multiple actions are performed in one step, the undo functionality groups all of the changes together for the purposes of restoring all items affected by the action previously performed.&lt;br /&gt;
&lt;br /&gt;
=== List of Items Now Supported by Undo Functionality === &lt;br /&gt;
*Add Signup Sheet&lt;br /&gt;
**Delete Topic&lt;br /&gt;
**Edit Topic&lt;br /&gt;
**New Topic&lt;br /&gt;
*Assignments&lt;br /&gt;
**Add Participants&lt;br /&gt;
**Copy&lt;br /&gt;
**Create&lt;br /&gt;
**Delete&lt;br /&gt;
**Edit&lt;br /&gt;
*Courses&lt;br /&gt;
**Add Participants&lt;br /&gt;
**Copy&lt;br /&gt;
**Create&lt;br /&gt;
**Delete&lt;br /&gt;
**Edit&lt;br /&gt;
**Toggle Private/Public&lt;br /&gt;
*Import&lt;br /&gt;
**Import Participants&lt;br /&gt;
**Import Teams&lt;br /&gt;
**Import Users&lt;br /&gt;
*Student Actions&lt;br /&gt;
**Create Team&lt;br /&gt;
**Edit Team Name&lt;br /&gt;
**Leave Team&lt;br /&gt;
**Submit Hyperlink&lt;br /&gt;
*Questions&lt;br /&gt;
**Copy&lt;br /&gt;
**Create&lt;br /&gt;
**Delete&lt;br /&gt;
**Edit&lt;br /&gt;
*Questionnaires&lt;br /&gt;
**Copy&lt;br /&gt;
**Create&lt;br /&gt;
**Delete&lt;br /&gt;
**Edit&lt;br /&gt;
*Teams&lt;br /&gt;
**Add&lt;br /&gt;
**Create (Manual)&lt;br /&gt;
**Create (Random)&lt;br /&gt;
**Delete&lt;br /&gt;
**Delete All Teams&lt;br /&gt;
**Edit&lt;br /&gt;
&lt;br /&gt;
=== Redo Functionality ===&lt;br /&gt;
In addition to the Undo functionality being added, the ability to Redo an undone action is also implemented.  Whenever an Undo is performed, the user is given an option to Redo the action that was undone.  Whenever a Redo is performed, the user is given an option to Undo the action again.  &lt;br /&gt;
&lt;br /&gt;
=== Design Patterns and Designs ===&lt;br /&gt;
*DRY&lt;br /&gt;
**&amp;quot;Don't Repeat Yourself&amp;quot; practice was followed. &lt;br /&gt;
*Memento&lt;br /&gt;
**The memento pattern is a software design pattern that provides the ability to restore an object to its previous state (undo via rollback). The memento pattern is implemented with two objects: the originator and a caretaker. The originator is some object that has an internal state. The caretaker is going to do something to the originator, but wants to be able to undo the change. The caretaker first asks the originator for a memento object. Then it does whatever operation (or sequence of operations) it was going to do. To roll back to the state before the operations, it returns the memento object to the originator. The memento object itself is an opaque object (one which the caretaker cannot, or should not, change). When using this pattern, care should be taken if the originator may change other objects or resources - the memento pattern operates on a single object. Classic examples of the memento pattern include the seed of a pseudorandom number generator (it will always produce the same sequence thereafter when initialized with the seed state) and the state in a finite state machine.&lt;br /&gt;
**The Memento pattern will be followed through PaperTrail, an open-source Ruby gem leveraged by the project.&lt;br /&gt;
&lt;br /&gt;
=== Framework Leveraged &amp;amp; Enhanced ===&lt;br /&gt;
*Paper Trail(https://github.com/airblade/paper_trail)&lt;br /&gt;
**Paper Trail allows for tracking changes to model data. &lt;br /&gt;
***Good for auditing or versioning. &lt;br /&gt;
**Offers many functionalities including:&lt;br /&gt;
****Viewing a model at any stage in its lifecycle. &lt;br /&gt;
****Reverting a model to any version.&lt;br /&gt;
****Undeleting items after they have been destroyed.&lt;br /&gt;
**Compatible with Rails-2.3.15, which is the version Expertiza uses. &lt;br /&gt;
**There is a [http://railscasts.com/episodes/255-undo-with-paper-trail Railscast] showing how to implement the undo feature with Paper Trail. &lt;br /&gt;
**Ranked as the most popular framework for Active Record versioning feature in [https://www.ruby-toolbox.com/categories/Active_Record_Versioning here]&lt;br /&gt;
*Enhancement&lt;br /&gt;
**Paper Trail only supported undo of the most recent action and did not restore associations.   &lt;br /&gt;
**Paper Trail customized to add support for restoring associations within the Expertiza system.  &lt;br /&gt;
***Description of modification...&lt;br /&gt;
&lt;br /&gt;
=== Classes Modified ===&lt;br /&gt;
*apps/&lt;br /&gt;
**controllers/&lt;br /&gt;
***course_controller.rb&lt;br /&gt;
***import_file_controller.rb&lt;br /&gt;
***participants_controller.rb&lt;br /&gt;
***team_controller.rb&lt;br /&gt;
***teams_users_controller.rb&lt;br /&gt;
**models/&lt;br /&gt;
***participant.rb&lt;br /&gt;
***ta_mapping.rb&lt;br /&gt;
***team_node.rb&lt;br /&gt;
***teams_user.rb&lt;br /&gt;
&lt;br /&gt;
=== Unit Tests ===&lt;br /&gt;
*Modified Tests&lt;br /&gt;
**test file&lt;br /&gt;
***test method&lt;br /&gt;
*New Tests&lt;br /&gt;
**test file&lt;br /&gt;
***test method&lt;br /&gt;
&lt;br /&gt;
=== Functional Testing Plans ===&lt;br /&gt;
*Modified Tests&lt;br /&gt;
**test file&lt;br /&gt;
***test method&lt;br /&gt;
*New Tests&lt;br /&gt;
**test file&lt;br /&gt;
***test method&lt;/div&gt;</summary>
		<author><name>Kbyarbor</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2013/FINAL_PROJECT_E736_UNDO_DELIVERABLE&amp;diff=75081</id>
		<title>CSC/ECE 517 Spring 2013/FINAL PROJECT E736 UNDO DELIVERABLE</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2013/FINAL_PROJECT_E736_UNDO_DELIVERABLE&amp;diff=75081"/>
		<updated>2013-04-22T00:50:03Z</updated>

		<summary type="html">&lt;p&gt;Kbyarbor: /* List of Items to be Supported by Undo Functionality */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= E736. Undo Functionality for Expertiza =&lt;br /&gt;
*Contacts: Ed Gehringer (efg@ncsu.edu) and Andrew Kofink (ajkofink@ncsu.edu)&lt;br /&gt;
*[http://wiki.expertiza.ncsu.edu/index.php/CSC/ECE_517_Spring_2013/FINAL_PROJECT_E736_UNDO Design Document]&lt;br /&gt;
*[https://docs.google.com/a/ncsu.edu/document/d/11YTjxFXFR13vJ769yFBbqn9qOueK2Ktz0Pd-gyS2W5U/ Project Description Doc]&lt;br /&gt;
== Team Members ==&lt;br /&gt;
*Chun Sing Tsui (ctsui@ncsu.edu)&lt;br /&gt;
*Kenny Yarboro (kbyarbor@ncsu.edu)&lt;br /&gt;
*Meng Cao (mcao2@ncsu.edu)&lt;br /&gt;
*Travis Folsom (twfolsom@ncsu.edu)&lt;br /&gt;
&lt;br /&gt;
== Project Deliverables ==&lt;br /&gt;
&lt;br /&gt;
=== Screencast Video Overview ===&lt;br /&gt;
A video overview of the project was created via [http://www.screencast-o-matic.com/ Screencast-O-Matic] and can be found [http://www.youtube.com/watch?v=1DYS5InjBOk here].  &lt;br /&gt;
&lt;br /&gt;
=== Overview of Undo Functionality ===&lt;br /&gt;
*Undo allows the user to undo their most recent actions for any items that offer the undo functionality.  &lt;br /&gt;
*The undo of file submissions was not required; however, we did or did not do these....depends on if we complete it...&lt;br /&gt;
*If an undo is attempted on an item already modified by another user, a message is displayed stating why undo cannot be performed.  Otherwise, the user is able to undo any changes to an item with the undo functionality.  &lt;br /&gt;
*When multiple actions are performed in one step, the undo functionality groups all of the changes together for the purposes of restoring all items affected by the action previously performed.&lt;br /&gt;
&lt;br /&gt;
=== List of Items Now Supported by Undo Functionality === &lt;br /&gt;
*Add Signup Sheet&lt;br /&gt;
**Delete Topic&lt;br /&gt;
**Edit Topic&lt;br /&gt;
**New Topic&lt;br /&gt;
*Assignments&lt;br /&gt;
**Add Participants&lt;br /&gt;
**Copy&lt;br /&gt;
**Create&lt;br /&gt;
**Delete&lt;br /&gt;
**Edit&lt;br /&gt;
*Courses&lt;br /&gt;
**Add Participants&lt;br /&gt;
**Copy&lt;br /&gt;
**Create&lt;br /&gt;
**Delete&lt;br /&gt;
**Edit&lt;br /&gt;
**Toggle Private/Public&lt;br /&gt;
*Import&lt;br /&gt;
**Import Participants&lt;br /&gt;
**Import Teams&lt;br /&gt;
**Import Users&lt;br /&gt;
*Student Actions&lt;br /&gt;
**Create Team&lt;br /&gt;
**Edit Team Name&lt;br /&gt;
**Leave Team&lt;br /&gt;
**Submit Hyperlink&lt;br /&gt;
*Questions&lt;br /&gt;
**Copy&lt;br /&gt;
**Create&lt;br /&gt;
**Delete&lt;br /&gt;
**Edit&lt;br /&gt;
*Questionnaires&lt;br /&gt;
**Copy&lt;br /&gt;
**Create&lt;br /&gt;
**Delete&lt;br /&gt;
**Edit&lt;br /&gt;
*Teams&lt;br /&gt;
**Add&lt;br /&gt;
**Create (Manual)&lt;br /&gt;
**Create (Random)&lt;br /&gt;
**Delete&lt;br /&gt;
**Delete All Teams&lt;br /&gt;
**Edit&lt;br /&gt;
&lt;br /&gt;
=== Design Patterns and Designs ===&lt;br /&gt;
*DRY&lt;br /&gt;
**&amp;quot;Don't Repeat Yourself&amp;quot; practice was followed. &lt;br /&gt;
*Memento&lt;br /&gt;
**The memento pattern is a software design pattern that provides the ability to restore an object to its previous state (undo via rollback). The memento pattern is implemented with two objects: the originator and a caretaker. The originator is some object that has an internal state. The caretaker is going to do something to the originator, but wants to be able to undo the change. The caretaker first asks the originator for a memento object. Then it does whatever operation (or sequence of operations) it was going to do. To roll back to the state before the operations, it returns the memento object to the originator. The memento object itself is an opaque object (one which the caretaker cannot, or should not, change). When using this pattern, care should be taken if the originator may change other objects or resources - the memento pattern operates on a single object. Classic examples of the memento pattern include the seed of a pseudorandom number generator (it will always produce the same sequence thereafter when initialized with the seed state) and the state in a finite state machine.&lt;br /&gt;
**The Memento pattern will be followed through PaperTrail, an open-source Ruby gem leveraged by the project.&lt;br /&gt;
&lt;br /&gt;
=== Framework Leveraged &amp;amp; Enhanced ===&lt;br /&gt;
*Paper Trail(https://github.com/airblade/paper_trail)&lt;br /&gt;
**Paper Trail allows for tracking changes to model data. &lt;br /&gt;
***Good for auditing or versioning. &lt;br /&gt;
**Offers many functionalities including:&lt;br /&gt;
****Viewing a model at any stage in its lifecycle. &lt;br /&gt;
****Reverting a model to any version.&lt;br /&gt;
****Undeleting items after they have been destroyed.&lt;br /&gt;
**Compatible with Rails-2.3.15, which is the version Expertiza uses. &lt;br /&gt;
**There is a [http://railscasts.com/episodes/255-undo-with-paper-trail Railscast] showing how to implement the undo feature with Paper Trail. &lt;br /&gt;
**Ranked as the most popular framework for Active Record versioning feature in [https://www.ruby-toolbox.com/categories/Active_Record_Versioning here]&lt;br /&gt;
*Enhancement&lt;br /&gt;
**Paper Trail only supported undo of the most recent action and did not restore associations.   &lt;br /&gt;
**Paper Trail customized to add support for restoring associations within the Expertiza system.  &lt;br /&gt;
***Description of modification...&lt;br /&gt;
&lt;br /&gt;
=== Classes Modified ===&lt;br /&gt;
*apps/&lt;br /&gt;
**controllers/&lt;br /&gt;
***course_controller.rb&lt;br /&gt;
***import_file_controller.rb&lt;br /&gt;
***participants_controller.rb&lt;br /&gt;
***team_controller.rb&lt;br /&gt;
***teams_users_controller.rb&lt;br /&gt;
**models/&lt;br /&gt;
***participant.rb&lt;br /&gt;
***ta_mapping.rb&lt;br /&gt;
***team_node.rb&lt;br /&gt;
***teams_user.rb&lt;br /&gt;
&lt;br /&gt;
=== Unit Tests ===&lt;br /&gt;
*Modified Tests&lt;br /&gt;
**test file&lt;br /&gt;
***test method&lt;br /&gt;
*New Tests&lt;br /&gt;
**test file&lt;br /&gt;
***test method&lt;br /&gt;
&lt;br /&gt;
=== Functional Testing Plans ===&lt;br /&gt;
*Modified Tests&lt;br /&gt;
**test file&lt;br /&gt;
***test method&lt;br /&gt;
*New Tests&lt;br /&gt;
**test file&lt;br /&gt;
***test method&lt;/div&gt;</summary>
		<author><name>Kbyarbor</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2013/FINAL_PROJECT_E736_UNDO_DELIVERABLE&amp;diff=75080</id>
		<title>CSC/ECE 517 Spring 2013/FINAL PROJECT E736 UNDO DELIVERABLE</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2013/FINAL_PROJECT_E736_UNDO_DELIVERABLE&amp;diff=75080"/>
		<updated>2013-04-22T00:42:33Z</updated>

		<summary type="html">&lt;p&gt;Kbyarbor: /* Design Document */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= E736. Undo Functionality for Expertiza =&lt;br /&gt;
*Contacts: Ed Gehringer (efg@ncsu.edu) and Andrew Kofink (ajkofink@ncsu.edu)&lt;br /&gt;
*[http://wiki.expertiza.ncsu.edu/index.php/CSC/ECE_517_Spring_2013/FINAL_PROJECT_E736_UNDO Design Document]&lt;br /&gt;
*[https://docs.google.com/a/ncsu.edu/document/d/11YTjxFXFR13vJ769yFBbqn9qOueK2Ktz0Pd-gyS2W5U/ Project Description Doc]&lt;br /&gt;
== Team Members ==&lt;br /&gt;
*Chun Sing Tsui (ctsui@ncsu.edu)&lt;br /&gt;
*Kenny Yarboro (kbyarbor@ncsu.edu)&lt;br /&gt;
*Meng Cao (mcao2@ncsu.edu)&lt;br /&gt;
*Travis Folsom (twfolsom@ncsu.edu)&lt;br /&gt;
&lt;br /&gt;
== Project Deliverables ==&lt;br /&gt;
&lt;br /&gt;
=== Screencast Video Overview ===&lt;br /&gt;
A video overview of the project was created via [http://www.screencast-o-matic.com/ Screencast-O-Matic] and can be found [http://www.youtube.com/watch?v=1DYS5InjBOk here].  &lt;br /&gt;
&lt;br /&gt;
=== Overview of Undo Functionality ===&lt;br /&gt;
*Undo allows the user to undo their most recent actions for any items that offer the undo functionality.  &lt;br /&gt;
*The undo of file submissions was not required; however, we did or did not do these....depends on if we complete it...&lt;br /&gt;
*If an undo is attempted on an item already modified by another user, a message is displayed stating why undo cannot be performed.  Otherwise, the user is able to undo any changes to an item with the undo functionality.  &lt;br /&gt;
*When multiple actions are performed in one step, the undo functionality groups all of the changes together for the purposes of restoring all items affected by the action previously performed.&lt;br /&gt;
&lt;br /&gt;
=== List of Items to be Supported by Undo Functionality === &lt;br /&gt;
*Courses&lt;br /&gt;
**Create&lt;br /&gt;
**Delete&lt;br /&gt;
**Edit&lt;br /&gt;
*Import&lt;br /&gt;
**Import Participants&lt;br /&gt;
**Import Teams&lt;br /&gt;
**Import Users&lt;br /&gt;
*Teams&lt;br /&gt;
**Create (Manual)&lt;br /&gt;
**Create (Random)&lt;br /&gt;
**Edit&lt;br /&gt;
&lt;br /&gt;
=== Design Patterns and Designs ===&lt;br /&gt;
*DRY&lt;br /&gt;
**&amp;quot;Don't Repeat Yourself&amp;quot; practice was followed. &lt;br /&gt;
*Memento&lt;br /&gt;
**The memento pattern is a software design pattern that provides the ability to restore an object to its previous state (undo via rollback). The memento pattern is implemented with two objects: the originator and a caretaker. The originator is some object that has an internal state. The caretaker is going to do something to the originator, but wants to be able to undo the change. The caretaker first asks the originator for a memento object. Then it does whatever operation (or sequence of operations) it was going to do. To roll back to the state before the operations, it returns the memento object to the originator. The memento object itself is an opaque object (one which the caretaker cannot, or should not, change). When using this pattern, care should be taken if the originator may change other objects or resources - the memento pattern operates on a single object. Classic examples of the memento pattern include the seed of a pseudorandom number generator (it will always produce the same sequence thereafter when initialized with the seed state) and the state in a finite state machine.&lt;br /&gt;
**The Memento pattern will be followed through PaperTrail, an open-source Ruby gem leveraged by the project.&lt;br /&gt;
&lt;br /&gt;
=== Framework Leveraged &amp;amp; Enhanced ===&lt;br /&gt;
*Paper Trail(https://github.com/airblade/paper_trail)&lt;br /&gt;
**Paper Trail allows for tracking changes to model data. &lt;br /&gt;
***Good for auditing or versioning. &lt;br /&gt;
**Offers many functionalities including:&lt;br /&gt;
****Viewing a model at any stage in its lifecycle. &lt;br /&gt;
****Reverting a model to any version.&lt;br /&gt;
****Undeleting items after they have been destroyed.&lt;br /&gt;
**Compatible with Rails-2.3.15, which is the version Expertiza uses. &lt;br /&gt;
**There is a [http://railscasts.com/episodes/255-undo-with-paper-trail Railscast] showing how to implement the undo feature with Paper Trail. &lt;br /&gt;
**Ranked as the most popular framework for Active Record versioning feature in [https://www.ruby-toolbox.com/categories/Active_Record_Versioning here]&lt;br /&gt;
*Enhancement&lt;br /&gt;
**Paper Trail only supported undo of the most recent action and did not restore associations.   &lt;br /&gt;
**Paper Trail customized to add support for restoring associations within the Expertiza system.  &lt;br /&gt;
***Description of modification...&lt;br /&gt;
&lt;br /&gt;
=== Classes Modified ===&lt;br /&gt;
*apps/&lt;br /&gt;
**controllers/&lt;br /&gt;
***course_controller.rb&lt;br /&gt;
***import_file_controller.rb&lt;br /&gt;
***participants_controller.rb&lt;br /&gt;
***team_controller.rb&lt;br /&gt;
***teams_users_controller.rb&lt;br /&gt;
**models/&lt;br /&gt;
***participant.rb&lt;br /&gt;
***ta_mapping.rb&lt;br /&gt;
***team_node.rb&lt;br /&gt;
***teams_user.rb&lt;br /&gt;
&lt;br /&gt;
=== Unit Tests ===&lt;br /&gt;
*Modified Tests&lt;br /&gt;
**test file&lt;br /&gt;
***test method&lt;br /&gt;
*New Tests&lt;br /&gt;
**test file&lt;br /&gt;
***test method&lt;br /&gt;
&lt;br /&gt;
=== Functional Testing Plans ===&lt;br /&gt;
*Modified Tests&lt;br /&gt;
**test file&lt;br /&gt;
***test method&lt;br /&gt;
*New Tests&lt;br /&gt;
**test file&lt;br /&gt;
***test method&lt;/div&gt;</summary>
		<author><name>Kbyarbor</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2013/FINAL_PROJECT_E736_UNDO_DELIVERABLE&amp;diff=74799</id>
		<title>CSC/ECE 517 Spring 2013/FINAL PROJECT E736 UNDO DELIVERABLE</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2013/FINAL_PROJECT_E736_UNDO_DELIVERABLE&amp;diff=74799"/>
		<updated>2013-04-14T23:30:39Z</updated>

		<summary type="html">&lt;p&gt;Kbyarbor: /* Functional Testing Plans */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= E736. Undo Functionality for Expertiza =&lt;br /&gt;
*Contacts: Ed Gehringer (efg@ncsu.edu) and Andrew Kofink (ajkofink@ncsu.edu)&lt;br /&gt;
*[http://wiki.expertiza.ncsu.edu/index.php/CSC/ECE_517_Spring_2013/FINAL_PROJECT_E736_UNDO Design Document]&lt;br /&gt;
*[https://docs.google.com/a/ncsu.edu/document/d/11YTjxFXFR13vJ769yFBbqn9qOueK2Ktz0Pd-gyS2W5U/ Project Description Doc]&lt;br /&gt;
== Team Members ==&lt;br /&gt;
*Chun Sing Tsui (ctsui@ncsu.edu)&lt;br /&gt;
*Kenny Yarboro (kbyarbor@ncsu.edu)&lt;br /&gt;
*Meng Cao (mcao2@ncsu.edu)&lt;br /&gt;
*Travis Folsom (twfolsom@ncsu.edu)&lt;br /&gt;
&lt;br /&gt;
== Design Document ==&lt;br /&gt;
&lt;br /&gt;
=== Overview of Undo Functionality ===&lt;br /&gt;
*Undo allows the user to undo their most recent actions for any items that offer the undo functionality.  &lt;br /&gt;
*The undo of file submissions was not required; however, we did or did not do these....depends on if we complete it...&lt;br /&gt;
*If an undo is attempted on an item already modified by another user, a message is displayed stating why undo cannot be performed.  Otherwise, the user is able to undo any changes to an item with the undo functionality.  &lt;br /&gt;
*When multiple actions are performed in one step, the undo functionality groups all of the changes together for the purposes of restoring all items affected by the action previously performed.&lt;br /&gt;
&lt;br /&gt;
=== List of Items to be Supported by Undo Functionality === &lt;br /&gt;
*Courses&lt;br /&gt;
**Create&lt;br /&gt;
**Delete&lt;br /&gt;
**Edit&lt;br /&gt;
*Import&lt;br /&gt;
**Import Participants&lt;br /&gt;
**Import Teams&lt;br /&gt;
**Import Users&lt;br /&gt;
*Teams&lt;br /&gt;
**Create (Manual)&lt;br /&gt;
**Create (Random)&lt;br /&gt;
**Edit&lt;br /&gt;
&lt;br /&gt;
=== Design Patterns and Designs ===&lt;br /&gt;
*DRY&lt;br /&gt;
**&amp;quot;Don't Repeat Yourself&amp;quot; practice was followed. &lt;br /&gt;
*Memento&lt;br /&gt;
**The memento pattern is a software design pattern that provides the ability to restore an object to its previous state (undo via rollback). The memento pattern is implemented with two objects: the originator and a caretaker. The originator is some object that has an internal state. The caretaker is going to do something to the originator, but wants to be able to undo the change. The caretaker first asks the originator for a memento object. Then it does whatever operation (or sequence of operations) it was going to do. To roll back to the state before the operations, it returns the memento object to the originator. The memento object itself is an opaque object (one which the caretaker cannot, or should not, change). When using this pattern, care should be taken if the originator may change other objects or resources - the memento pattern operates on a single object. Classic examples of the memento pattern include the seed of a pseudorandom number generator (it will always produce the same sequence thereafter when initialized with the seed state) and the state in a finite state machine.&lt;br /&gt;
**The Memento pattern will be followed through PaperTrail, an open-source Ruby gem leveraged by the project.&lt;br /&gt;
&lt;br /&gt;
=== Framework Leveraged &amp;amp; Enhanced ===&lt;br /&gt;
*Paper Trail(https://github.com/airblade/paper_trail)&lt;br /&gt;
**Paper Trail allows for tracking changes to model data. &lt;br /&gt;
***Good for auditing or versioning. &lt;br /&gt;
**Offers many functionalities including:&lt;br /&gt;
****Viewing a model at any stage in its lifecycle. &lt;br /&gt;
****Reverting a model to any version.&lt;br /&gt;
****Undeleting items after they have been destroyed.&lt;br /&gt;
**Compatible with Rails-2.3.15, which is the version Expertiza uses. &lt;br /&gt;
**There is a [http://railscasts.com/episodes/255-undo-with-paper-trail Railscast] showing how to implement the undo feature with Paper Trail. &lt;br /&gt;
**Ranked as the most popular framework for Active Record versioning feature in [https://www.ruby-toolbox.com/categories/Active_Record_Versioning here]&lt;br /&gt;
*Enhancement&lt;br /&gt;
**Paper Trail only supported undo of the most recent action and did not restore associations.   &lt;br /&gt;
**Paper Trail customized to add support for restoring associations within the Expertiza system.  &lt;br /&gt;
***Description of modification...&lt;br /&gt;
&lt;br /&gt;
=== Classes Modified ===&lt;br /&gt;
*apps/&lt;br /&gt;
**controllers/&lt;br /&gt;
***course_controller.rb&lt;br /&gt;
***import_file_controller.rb&lt;br /&gt;
***participants_controller.rb&lt;br /&gt;
***team_controller.rb&lt;br /&gt;
***teams_users_controller.rb&lt;br /&gt;
**models/&lt;br /&gt;
***participant.rb&lt;br /&gt;
***ta_mapping.rb&lt;br /&gt;
***team_node.rb&lt;br /&gt;
***teams_user.rb&lt;br /&gt;
&lt;br /&gt;
=== Unit Tests ===&lt;br /&gt;
*Modified Tests&lt;br /&gt;
**test file&lt;br /&gt;
***test method&lt;br /&gt;
*New Tests&lt;br /&gt;
**test file&lt;br /&gt;
***test method&lt;br /&gt;
&lt;br /&gt;
=== Functional Testing Plans ===&lt;br /&gt;
*Modified Tests&lt;br /&gt;
**test file&lt;br /&gt;
***test method&lt;br /&gt;
*New Tests&lt;br /&gt;
**test file&lt;br /&gt;
***test method&lt;/div&gt;</summary>
		<author><name>Kbyarbor</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2013/FINAL_PROJECT_E736_UNDO_DELIVERABLE&amp;diff=74798</id>
		<title>CSC/ECE 517 Spring 2013/FINAL PROJECT E736 UNDO DELIVERABLE</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2013/FINAL_PROJECT_E736_UNDO_DELIVERABLE&amp;diff=74798"/>
		<updated>2013-04-14T23:30:06Z</updated>

		<summary type="html">&lt;p&gt;Kbyarbor: /* Unit Testing Plans */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= E736. Undo Functionality for Expertiza =&lt;br /&gt;
*Contacts: Ed Gehringer (efg@ncsu.edu) and Andrew Kofink (ajkofink@ncsu.edu)&lt;br /&gt;
*[http://wiki.expertiza.ncsu.edu/index.php/CSC/ECE_517_Spring_2013/FINAL_PROJECT_E736_UNDO Design Document]&lt;br /&gt;
*[https://docs.google.com/a/ncsu.edu/document/d/11YTjxFXFR13vJ769yFBbqn9qOueK2Ktz0Pd-gyS2W5U/ Project Description Doc]&lt;br /&gt;
== Team Members ==&lt;br /&gt;
*Chun Sing Tsui (ctsui@ncsu.edu)&lt;br /&gt;
*Kenny Yarboro (kbyarbor@ncsu.edu)&lt;br /&gt;
*Meng Cao (mcao2@ncsu.edu)&lt;br /&gt;
*Travis Folsom (twfolsom@ncsu.edu)&lt;br /&gt;
&lt;br /&gt;
== Design Document ==&lt;br /&gt;
&lt;br /&gt;
=== Overview of Undo Functionality ===&lt;br /&gt;
*Undo allows the user to undo their most recent actions for any items that offer the undo functionality.  &lt;br /&gt;
*The undo of file submissions was not required; however, we did or did not do these....depends on if we complete it...&lt;br /&gt;
*If an undo is attempted on an item already modified by another user, a message is displayed stating why undo cannot be performed.  Otherwise, the user is able to undo any changes to an item with the undo functionality.  &lt;br /&gt;
*When multiple actions are performed in one step, the undo functionality groups all of the changes together for the purposes of restoring all items affected by the action previously performed.&lt;br /&gt;
&lt;br /&gt;
=== List of Items to be Supported by Undo Functionality === &lt;br /&gt;
*Courses&lt;br /&gt;
**Create&lt;br /&gt;
**Delete&lt;br /&gt;
**Edit&lt;br /&gt;
*Import&lt;br /&gt;
**Import Participants&lt;br /&gt;
**Import Teams&lt;br /&gt;
**Import Users&lt;br /&gt;
*Teams&lt;br /&gt;
**Create (Manual)&lt;br /&gt;
**Create (Random)&lt;br /&gt;
**Edit&lt;br /&gt;
&lt;br /&gt;
=== Design Patterns and Designs ===&lt;br /&gt;
*DRY&lt;br /&gt;
**&amp;quot;Don't Repeat Yourself&amp;quot; practice was followed. &lt;br /&gt;
*Memento&lt;br /&gt;
**The memento pattern is a software design pattern that provides the ability to restore an object to its previous state (undo via rollback). The memento pattern is implemented with two objects: the originator and a caretaker. The originator is some object that has an internal state. The caretaker is going to do something to the originator, but wants to be able to undo the change. The caretaker first asks the originator for a memento object. Then it does whatever operation (or sequence of operations) it was going to do. To roll back to the state before the operations, it returns the memento object to the originator. The memento object itself is an opaque object (one which the caretaker cannot, or should not, change). When using this pattern, care should be taken if the originator may change other objects or resources - the memento pattern operates on a single object. Classic examples of the memento pattern include the seed of a pseudorandom number generator (it will always produce the same sequence thereafter when initialized with the seed state) and the state in a finite state machine.&lt;br /&gt;
**The Memento pattern will be followed through PaperTrail, an open-source Ruby gem leveraged by the project.&lt;br /&gt;
&lt;br /&gt;
=== Framework Leveraged &amp;amp; Enhanced ===&lt;br /&gt;
*Paper Trail(https://github.com/airblade/paper_trail)&lt;br /&gt;
**Paper Trail allows for tracking changes to model data. &lt;br /&gt;
***Good for auditing or versioning. &lt;br /&gt;
**Offers many functionalities including:&lt;br /&gt;
****Viewing a model at any stage in its lifecycle. &lt;br /&gt;
****Reverting a model to any version.&lt;br /&gt;
****Undeleting items after they have been destroyed.&lt;br /&gt;
**Compatible with Rails-2.3.15, which is the version Expertiza uses. &lt;br /&gt;
**There is a [http://railscasts.com/episodes/255-undo-with-paper-trail Railscast] showing how to implement the undo feature with Paper Trail. &lt;br /&gt;
**Ranked as the most popular framework for Active Record versioning feature in [https://www.ruby-toolbox.com/categories/Active_Record_Versioning here]&lt;br /&gt;
*Enhancement&lt;br /&gt;
**Paper Trail only supported undo of the most recent action and did not restore associations.   &lt;br /&gt;
**Paper Trail customized to add support for restoring associations within the Expertiza system.  &lt;br /&gt;
***Description of modification...&lt;br /&gt;
&lt;br /&gt;
=== Classes Modified ===&lt;br /&gt;
*apps/&lt;br /&gt;
**controllers/&lt;br /&gt;
***course_controller.rb&lt;br /&gt;
***import_file_controller.rb&lt;br /&gt;
***participants_controller.rb&lt;br /&gt;
***team_controller.rb&lt;br /&gt;
***teams_users_controller.rb&lt;br /&gt;
**models/&lt;br /&gt;
***participant.rb&lt;br /&gt;
***ta_mapping.rb&lt;br /&gt;
***team_node.rb&lt;br /&gt;
***teams_user.rb&lt;br /&gt;
&lt;br /&gt;
=== Unit Tests ===&lt;br /&gt;
*Modified Tests&lt;br /&gt;
**test file&lt;br /&gt;
***test method&lt;br /&gt;
*New Tests&lt;br /&gt;
**test file&lt;br /&gt;
***test method&lt;br /&gt;
&lt;br /&gt;
=== Functional Testing Plans ===&lt;br /&gt;
*The following functional test plans will be followed for all items enhanced with the Undo functionality:&lt;br /&gt;
**Test that an item may be changed, then undo performed successfully.  &lt;br /&gt;
**Test that a sequence of changes may be performed by one user, then undo performed successfully for each action from the sequence. &lt;br /&gt;
**Test that an item may be changed by one user, changed again by another user, then undo performed by the original user will display a failure message with description.&lt;/div&gt;</summary>
		<author><name>Kbyarbor</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2013/FINAL_PROJECT_E736_UNDO_DELIVERABLE&amp;diff=74797</id>
		<title>CSC/ECE 517 Spring 2013/FINAL PROJECT E736 UNDO DELIVERABLE</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2013/FINAL_PROJECT_E736_UNDO_DELIVERABLE&amp;diff=74797"/>
		<updated>2013-04-14T23:28:41Z</updated>

		<summary type="html">&lt;p&gt;Kbyarbor: /* Expected Classes to be Modified */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= E736. Undo Functionality for Expertiza =&lt;br /&gt;
*Contacts: Ed Gehringer (efg@ncsu.edu) and Andrew Kofink (ajkofink@ncsu.edu)&lt;br /&gt;
*[http://wiki.expertiza.ncsu.edu/index.php/CSC/ECE_517_Spring_2013/FINAL_PROJECT_E736_UNDO Design Document]&lt;br /&gt;
*[https://docs.google.com/a/ncsu.edu/document/d/11YTjxFXFR13vJ769yFBbqn9qOueK2Ktz0Pd-gyS2W5U/ Project Description Doc]&lt;br /&gt;
== Team Members ==&lt;br /&gt;
*Chun Sing Tsui (ctsui@ncsu.edu)&lt;br /&gt;
*Kenny Yarboro (kbyarbor@ncsu.edu)&lt;br /&gt;
*Meng Cao (mcao2@ncsu.edu)&lt;br /&gt;
*Travis Folsom (twfolsom@ncsu.edu)&lt;br /&gt;
&lt;br /&gt;
== Design Document ==&lt;br /&gt;
&lt;br /&gt;
=== Overview of Undo Functionality ===&lt;br /&gt;
*Undo allows the user to undo their most recent actions for any items that offer the undo functionality.  &lt;br /&gt;
*The undo of file submissions was not required; however, we did or did not do these....depends on if we complete it...&lt;br /&gt;
*If an undo is attempted on an item already modified by another user, a message is displayed stating why undo cannot be performed.  Otherwise, the user is able to undo any changes to an item with the undo functionality.  &lt;br /&gt;
*When multiple actions are performed in one step, the undo functionality groups all of the changes together for the purposes of restoring all items affected by the action previously performed.&lt;br /&gt;
&lt;br /&gt;
=== List of Items to be Supported by Undo Functionality === &lt;br /&gt;
*Courses&lt;br /&gt;
**Create&lt;br /&gt;
**Delete&lt;br /&gt;
**Edit&lt;br /&gt;
*Import&lt;br /&gt;
**Import Participants&lt;br /&gt;
**Import Teams&lt;br /&gt;
**Import Users&lt;br /&gt;
*Teams&lt;br /&gt;
**Create (Manual)&lt;br /&gt;
**Create (Random)&lt;br /&gt;
**Edit&lt;br /&gt;
&lt;br /&gt;
=== Design Patterns and Designs ===&lt;br /&gt;
*DRY&lt;br /&gt;
**&amp;quot;Don't Repeat Yourself&amp;quot; practice was followed. &lt;br /&gt;
*Memento&lt;br /&gt;
**The memento pattern is a software design pattern that provides the ability to restore an object to its previous state (undo via rollback). The memento pattern is implemented with two objects: the originator and a caretaker. The originator is some object that has an internal state. The caretaker is going to do something to the originator, but wants to be able to undo the change. The caretaker first asks the originator for a memento object. Then it does whatever operation (or sequence of operations) it was going to do. To roll back to the state before the operations, it returns the memento object to the originator. The memento object itself is an opaque object (one which the caretaker cannot, or should not, change). When using this pattern, care should be taken if the originator may change other objects or resources - the memento pattern operates on a single object. Classic examples of the memento pattern include the seed of a pseudorandom number generator (it will always produce the same sequence thereafter when initialized with the seed state) and the state in a finite state machine.&lt;br /&gt;
**The Memento pattern will be followed through PaperTrail, an open-source Ruby gem leveraged by the project.&lt;br /&gt;
&lt;br /&gt;
=== Framework Leveraged &amp;amp; Enhanced ===&lt;br /&gt;
*Paper Trail(https://github.com/airblade/paper_trail)&lt;br /&gt;
**Paper Trail allows for tracking changes to model data. &lt;br /&gt;
***Good for auditing or versioning. &lt;br /&gt;
**Offers many functionalities including:&lt;br /&gt;
****Viewing a model at any stage in its lifecycle. &lt;br /&gt;
****Reverting a model to any version.&lt;br /&gt;
****Undeleting items after they have been destroyed.&lt;br /&gt;
**Compatible with Rails-2.3.15, which is the version Expertiza uses. &lt;br /&gt;
**There is a [http://railscasts.com/episodes/255-undo-with-paper-trail Railscast] showing how to implement the undo feature with Paper Trail. &lt;br /&gt;
**Ranked as the most popular framework for Active Record versioning feature in [https://www.ruby-toolbox.com/categories/Active_Record_Versioning here]&lt;br /&gt;
*Enhancement&lt;br /&gt;
**Paper Trail only supported undo of the most recent action and did not restore associations.   &lt;br /&gt;
**Paper Trail customized to add support for restoring associations within the Expertiza system.  &lt;br /&gt;
***Description of modification...&lt;br /&gt;
&lt;br /&gt;
=== Classes Modified ===&lt;br /&gt;
*apps/&lt;br /&gt;
**controllers/&lt;br /&gt;
***course_controller.rb&lt;br /&gt;
***import_file_controller.rb&lt;br /&gt;
***participants_controller.rb&lt;br /&gt;
***team_controller.rb&lt;br /&gt;
***teams_users_controller.rb&lt;br /&gt;
**models/&lt;br /&gt;
***participant.rb&lt;br /&gt;
***ta_mapping.rb&lt;br /&gt;
***team_node.rb&lt;br /&gt;
***teams_user.rb&lt;br /&gt;
&lt;br /&gt;
=== Unit Testing Plans ===&lt;br /&gt;
*Every class method modified will be tested via unit test. &lt;br /&gt;
*Every new method added will be tested via at least one unit test. &lt;br /&gt;
*All test methods shall be named with an appropriately descriptive name that is not too long.&lt;br /&gt;
&lt;br /&gt;
=== Functional Testing Plans ===&lt;br /&gt;
*The following functional test plans will be followed for all items enhanced with the Undo functionality:&lt;br /&gt;
**Test that an item may be changed, then undo performed successfully.  &lt;br /&gt;
**Test that a sequence of changes may be performed by one user, then undo performed successfully for each action from the sequence. &lt;br /&gt;
**Test that an item may be changed by one user, changed again by another user, then undo performed by the original user will display a failure message with description.&lt;/div&gt;</summary>
		<author><name>Kbyarbor</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2013/FINAL_PROJECT_E736_UNDO_DELIVERABLE&amp;diff=74796</id>
		<title>CSC/ECE 517 Spring 2013/FINAL PROJECT E736 UNDO DELIVERABLE</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2013/FINAL_PROJECT_E736_UNDO_DELIVERABLE&amp;diff=74796"/>
		<updated>2013-04-14T23:26:05Z</updated>

		<summary type="html">&lt;p&gt;Kbyarbor: /* Framework Leveraged */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= E736. Undo Functionality for Expertiza =&lt;br /&gt;
*Contacts: Ed Gehringer (efg@ncsu.edu) and Andrew Kofink (ajkofink@ncsu.edu)&lt;br /&gt;
*[http://wiki.expertiza.ncsu.edu/index.php/CSC/ECE_517_Spring_2013/FINAL_PROJECT_E736_UNDO Design Document]&lt;br /&gt;
*[https://docs.google.com/a/ncsu.edu/document/d/11YTjxFXFR13vJ769yFBbqn9qOueK2Ktz0Pd-gyS2W5U/ Project Description Doc]&lt;br /&gt;
== Team Members ==&lt;br /&gt;
*Chun Sing Tsui (ctsui@ncsu.edu)&lt;br /&gt;
*Kenny Yarboro (kbyarbor@ncsu.edu)&lt;br /&gt;
*Meng Cao (mcao2@ncsu.edu)&lt;br /&gt;
*Travis Folsom (twfolsom@ncsu.edu)&lt;br /&gt;
&lt;br /&gt;
== Design Document ==&lt;br /&gt;
&lt;br /&gt;
=== Overview of Undo Functionality ===&lt;br /&gt;
*Undo allows the user to undo their most recent actions for any items that offer the undo functionality.  &lt;br /&gt;
*The undo of file submissions was not required; however, we did or did not do these....depends on if we complete it...&lt;br /&gt;
*If an undo is attempted on an item already modified by another user, a message is displayed stating why undo cannot be performed.  Otherwise, the user is able to undo any changes to an item with the undo functionality.  &lt;br /&gt;
*When multiple actions are performed in one step, the undo functionality groups all of the changes together for the purposes of restoring all items affected by the action previously performed.&lt;br /&gt;
&lt;br /&gt;
=== List of Items to be Supported by Undo Functionality === &lt;br /&gt;
*Courses&lt;br /&gt;
**Create&lt;br /&gt;
**Delete&lt;br /&gt;
**Edit&lt;br /&gt;
*Import&lt;br /&gt;
**Import Participants&lt;br /&gt;
**Import Teams&lt;br /&gt;
**Import Users&lt;br /&gt;
*Teams&lt;br /&gt;
**Create (Manual)&lt;br /&gt;
**Create (Random)&lt;br /&gt;
**Edit&lt;br /&gt;
&lt;br /&gt;
=== Design Patterns and Designs ===&lt;br /&gt;
*DRY&lt;br /&gt;
**&amp;quot;Don't Repeat Yourself&amp;quot; practice was followed. &lt;br /&gt;
*Memento&lt;br /&gt;
**The memento pattern is a software design pattern that provides the ability to restore an object to its previous state (undo via rollback). The memento pattern is implemented with two objects: the originator and a caretaker. The originator is some object that has an internal state. The caretaker is going to do something to the originator, but wants to be able to undo the change. The caretaker first asks the originator for a memento object. Then it does whatever operation (or sequence of operations) it was going to do. To roll back to the state before the operations, it returns the memento object to the originator. The memento object itself is an opaque object (one which the caretaker cannot, or should not, change). When using this pattern, care should be taken if the originator may change other objects or resources - the memento pattern operates on a single object. Classic examples of the memento pattern include the seed of a pseudorandom number generator (it will always produce the same sequence thereafter when initialized with the seed state) and the state in a finite state machine.&lt;br /&gt;
**The Memento pattern will be followed through PaperTrail, an open-source Ruby gem leveraged by the project.&lt;br /&gt;
&lt;br /&gt;
=== Framework Leveraged &amp;amp; Enhanced ===&lt;br /&gt;
*Paper Trail(https://github.com/airblade/paper_trail)&lt;br /&gt;
**Paper Trail allows for tracking changes to model data. &lt;br /&gt;
***Good for auditing or versioning. &lt;br /&gt;
**Offers many functionalities including:&lt;br /&gt;
****Viewing a model at any stage in its lifecycle. &lt;br /&gt;
****Reverting a model to any version.&lt;br /&gt;
****Undeleting items after they have been destroyed.&lt;br /&gt;
**Compatible with Rails-2.3.15, which is the version Expertiza uses. &lt;br /&gt;
**There is a [http://railscasts.com/episodes/255-undo-with-paper-trail Railscast] showing how to implement the undo feature with Paper Trail. &lt;br /&gt;
**Ranked as the most popular framework for Active Record versioning feature in [https://www.ruby-toolbox.com/categories/Active_Record_Versioning here]&lt;br /&gt;
*Enhancement&lt;br /&gt;
**Paper Trail only supported undo of the most recent action and did not restore associations.   &lt;br /&gt;
**Paper Trail customized to add support for restoring associations within the Expertiza system.  &lt;br /&gt;
***Description of modification...&lt;br /&gt;
&lt;br /&gt;
=== Expected Classes to be Modified ===&lt;br /&gt;
*Assignment-related Classes&lt;br /&gt;
*Course-related Classes&lt;br /&gt;
*More classes may be covered as time allows.&lt;br /&gt;
&lt;br /&gt;
=== Unit Testing Plans ===&lt;br /&gt;
*Every class method modified will be tested via unit test. &lt;br /&gt;
*Every new method added will be tested via at least one unit test. &lt;br /&gt;
*All test methods shall be named with an appropriately descriptive name that is not too long.&lt;br /&gt;
&lt;br /&gt;
=== Functional Testing Plans ===&lt;br /&gt;
*The following functional test plans will be followed for all items enhanced with the Undo functionality:&lt;br /&gt;
**Test that an item may be changed, then undo performed successfully.  &lt;br /&gt;
**Test that a sequence of changes may be performed by one user, then undo performed successfully for each action from the sequence. &lt;br /&gt;
**Test that an item may be changed by one user, changed again by another user, then undo performed by the original user will display a failure message with description.&lt;/div&gt;</summary>
		<author><name>Kbyarbor</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2013/FINAL_PROJECT_E736_UNDO_DELIVERABLE&amp;diff=74795</id>
		<title>CSC/ECE 517 Spring 2013/FINAL PROJECT E736 UNDO DELIVERABLE</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2013/FINAL_PROJECT_E736_UNDO_DELIVERABLE&amp;diff=74795"/>
		<updated>2013-04-14T23:23:42Z</updated>

		<summary type="html">&lt;p&gt;Kbyarbor: /* Frameworks to Leverage */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= E736. Undo Functionality for Expertiza =&lt;br /&gt;
*Contacts: Ed Gehringer (efg@ncsu.edu) and Andrew Kofink (ajkofink@ncsu.edu)&lt;br /&gt;
*[http://wiki.expertiza.ncsu.edu/index.php/CSC/ECE_517_Spring_2013/FINAL_PROJECT_E736_UNDO Design Document]&lt;br /&gt;
*[https://docs.google.com/a/ncsu.edu/document/d/11YTjxFXFR13vJ769yFBbqn9qOueK2Ktz0Pd-gyS2W5U/ Project Description Doc]&lt;br /&gt;
== Team Members ==&lt;br /&gt;
*Chun Sing Tsui (ctsui@ncsu.edu)&lt;br /&gt;
*Kenny Yarboro (kbyarbor@ncsu.edu)&lt;br /&gt;
*Meng Cao (mcao2@ncsu.edu)&lt;br /&gt;
*Travis Folsom (twfolsom@ncsu.edu)&lt;br /&gt;
&lt;br /&gt;
== Design Document ==&lt;br /&gt;
&lt;br /&gt;
=== Overview of Undo Functionality ===&lt;br /&gt;
*Undo allows the user to undo their most recent actions for any items that offer the undo functionality.  &lt;br /&gt;
*The undo of file submissions was not required; however, we did or did not do these....depends on if we complete it...&lt;br /&gt;
*If an undo is attempted on an item already modified by another user, a message is displayed stating why undo cannot be performed.  Otherwise, the user is able to undo any changes to an item with the undo functionality.  &lt;br /&gt;
*When multiple actions are performed in one step, the undo functionality groups all of the changes together for the purposes of restoring all items affected by the action previously performed.&lt;br /&gt;
&lt;br /&gt;
=== List of Items to be Supported by Undo Functionality === &lt;br /&gt;
*Courses&lt;br /&gt;
**Create&lt;br /&gt;
**Delete&lt;br /&gt;
**Edit&lt;br /&gt;
*Import&lt;br /&gt;
**Import Participants&lt;br /&gt;
**Import Teams&lt;br /&gt;
**Import Users&lt;br /&gt;
*Teams&lt;br /&gt;
**Create (Manual)&lt;br /&gt;
**Create (Random)&lt;br /&gt;
**Edit&lt;br /&gt;
&lt;br /&gt;
=== Design Patterns and Designs ===&lt;br /&gt;
*DRY&lt;br /&gt;
**&amp;quot;Don't Repeat Yourself&amp;quot; practice was followed. &lt;br /&gt;
*Memento&lt;br /&gt;
**The memento pattern is a software design pattern that provides the ability to restore an object to its previous state (undo via rollback). The memento pattern is implemented with two objects: the originator and a caretaker. The originator is some object that has an internal state. The caretaker is going to do something to the originator, but wants to be able to undo the change. The caretaker first asks the originator for a memento object. Then it does whatever operation (or sequence of operations) it was going to do. To roll back to the state before the operations, it returns the memento object to the originator. The memento object itself is an opaque object (one which the caretaker cannot, or should not, change). When using this pattern, care should be taken if the originator may change other objects or resources - the memento pattern operates on a single object. Classic examples of the memento pattern include the seed of a pseudorandom number generator (it will always produce the same sequence thereafter when initialized with the seed state) and the state in a finite state machine.&lt;br /&gt;
**The Memento pattern will be followed through PaperTrail, an open-source Ruby gem leveraged by the project.&lt;br /&gt;
&lt;br /&gt;
=== Framework Leveraged ===&lt;br /&gt;
*Paper Trail(https://github.com/airblade/paper_trail)&lt;br /&gt;
**PaperTrail allows for tracking changes to model data. &lt;br /&gt;
***Good for auditing or versioning. &lt;br /&gt;
**Offers many functionalities including:&lt;br /&gt;
****Viewing a model at any stage in its lifecycle. &lt;br /&gt;
****Reverting a model to any version.&lt;br /&gt;
****Undeleting items after they have been destroyed.&lt;br /&gt;
**Compatible with Rails-2.3.15, which is the version Expertiza uses. &lt;br /&gt;
**There is a [http://railscasts.com/episodes/255-undo-with-paper-trail Railscast] showing how to implement the undo feature with Paper Trail. &lt;br /&gt;
**Ranked as the most popular framework for Active Record versioning feature in [https://www.ruby-toolbox.com/categories/Active_Record_Versioning here]&lt;br /&gt;
&lt;br /&gt;
=== Expected Classes to be Modified ===&lt;br /&gt;
*Assignment-related Classes&lt;br /&gt;
*Course-related Classes&lt;br /&gt;
*More classes may be covered as time allows.&lt;br /&gt;
&lt;br /&gt;
=== Unit Testing Plans ===&lt;br /&gt;
*Every class method modified will be tested via unit test. &lt;br /&gt;
*Every new method added will be tested via at least one unit test. &lt;br /&gt;
*All test methods shall be named with an appropriately descriptive name that is not too long.&lt;br /&gt;
&lt;br /&gt;
=== Functional Testing Plans ===&lt;br /&gt;
*The following functional test plans will be followed for all items enhanced with the Undo functionality:&lt;br /&gt;
**Test that an item may be changed, then undo performed successfully.  &lt;br /&gt;
**Test that a sequence of changes may be performed by one user, then undo performed successfully for each action from the sequence. &lt;br /&gt;
**Test that an item may be changed by one user, changed again by another user, then undo performed by the original user will display a failure message with description.&lt;/div&gt;</summary>
		<author><name>Kbyarbor</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2013/FINAL_PROJECT_E736_UNDO_DELIVERABLE&amp;diff=74794</id>
		<title>CSC/ECE 517 Spring 2013/FINAL PROJECT E736 UNDO DELIVERABLE</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2013/FINAL_PROJECT_E736_UNDO_DELIVERABLE&amp;diff=74794"/>
		<updated>2013-04-14T23:23:07Z</updated>

		<summary type="html">&lt;p&gt;Kbyarbor: /* Design Patterns and Designs */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= E736. Undo Functionality for Expertiza =&lt;br /&gt;
*Contacts: Ed Gehringer (efg@ncsu.edu) and Andrew Kofink (ajkofink@ncsu.edu)&lt;br /&gt;
*[http://wiki.expertiza.ncsu.edu/index.php/CSC/ECE_517_Spring_2013/FINAL_PROJECT_E736_UNDO Design Document]&lt;br /&gt;
*[https://docs.google.com/a/ncsu.edu/document/d/11YTjxFXFR13vJ769yFBbqn9qOueK2Ktz0Pd-gyS2W5U/ Project Description Doc]&lt;br /&gt;
== Team Members ==&lt;br /&gt;
*Chun Sing Tsui (ctsui@ncsu.edu)&lt;br /&gt;
*Kenny Yarboro (kbyarbor@ncsu.edu)&lt;br /&gt;
*Meng Cao (mcao2@ncsu.edu)&lt;br /&gt;
*Travis Folsom (twfolsom@ncsu.edu)&lt;br /&gt;
&lt;br /&gt;
== Design Document ==&lt;br /&gt;
&lt;br /&gt;
=== Overview of Undo Functionality ===&lt;br /&gt;
*Undo allows the user to undo their most recent actions for any items that offer the undo functionality.  &lt;br /&gt;
*The undo of file submissions was not required; however, we did or did not do these....depends on if we complete it...&lt;br /&gt;
*If an undo is attempted on an item already modified by another user, a message is displayed stating why undo cannot be performed.  Otherwise, the user is able to undo any changes to an item with the undo functionality.  &lt;br /&gt;
*When multiple actions are performed in one step, the undo functionality groups all of the changes together for the purposes of restoring all items affected by the action previously performed.&lt;br /&gt;
&lt;br /&gt;
=== List of Items to be Supported by Undo Functionality === &lt;br /&gt;
*Courses&lt;br /&gt;
**Create&lt;br /&gt;
**Delete&lt;br /&gt;
**Edit&lt;br /&gt;
*Import&lt;br /&gt;
**Import Participants&lt;br /&gt;
**Import Teams&lt;br /&gt;
**Import Users&lt;br /&gt;
*Teams&lt;br /&gt;
**Create (Manual)&lt;br /&gt;
**Create (Random)&lt;br /&gt;
**Edit&lt;br /&gt;
&lt;br /&gt;
=== Design Patterns and Designs ===&lt;br /&gt;
*DRY&lt;br /&gt;
**&amp;quot;Don't Repeat Yourself&amp;quot; practice was followed. &lt;br /&gt;
*Memento&lt;br /&gt;
**The memento pattern is a software design pattern that provides the ability to restore an object to its previous state (undo via rollback). The memento pattern is implemented with two objects: the originator and a caretaker. The originator is some object that has an internal state. The caretaker is going to do something to the originator, but wants to be able to undo the change. The caretaker first asks the originator for a memento object. Then it does whatever operation (or sequence of operations) it was going to do. To roll back to the state before the operations, it returns the memento object to the originator. The memento object itself is an opaque object (one which the caretaker cannot, or should not, change). When using this pattern, care should be taken if the originator may change other objects or resources - the memento pattern operates on a single object. Classic examples of the memento pattern include the seed of a pseudorandom number generator (it will always produce the same sequence thereafter when initialized with the seed state) and the state in a finite state machine.&lt;br /&gt;
**The Memento pattern will be followed through PaperTrail, an open-source Ruby gem leveraged by the project.&lt;br /&gt;
&lt;br /&gt;
=== Frameworks to Leverage ===&lt;br /&gt;
*Paper Trail(https://github.com/airblade/paper_trail)&lt;br /&gt;
**PaperTrail allows for tracking changes to model data. &lt;br /&gt;
***Good for auditing or versioning. &lt;br /&gt;
**Offers many functionalities including:&lt;br /&gt;
****Viewing a model at any stage in its lifecycle. &lt;br /&gt;
****Reverting a model to any version.&lt;br /&gt;
****Undeleting items after they have been destroyed.&lt;br /&gt;
**Compatible with Rails-2.3.15, which is the version Expertiza uses. &lt;br /&gt;
**There is a [http://railscasts.com/episodes/255-undo-with-paper-trail Railscast] showing how to implement the undo feature with Paper Trail. &lt;br /&gt;
**Ranked as the most popular framework for Active Record versioning feature in [https://www.ruby-toolbox.com/categories/Active_Record_Versioning here]&lt;br /&gt;
**Alternative Frameworks are listed [https://www.ruby-toolbox.com/categories/Active_Record_Versioning here].&lt;br /&gt;
&lt;br /&gt;
=== Expected Classes to be Modified ===&lt;br /&gt;
*Assignment-related Classes&lt;br /&gt;
*Course-related Classes&lt;br /&gt;
*More classes may be covered as time allows.&lt;br /&gt;
&lt;br /&gt;
=== Unit Testing Plans ===&lt;br /&gt;
*Every class method modified will be tested via unit test. &lt;br /&gt;
*Every new method added will be tested via at least one unit test. &lt;br /&gt;
*All test methods shall be named with an appropriately descriptive name that is not too long.&lt;br /&gt;
&lt;br /&gt;
=== Functional Testing Plans ===&lt;br /&gt;
*The following functional test plans will be followed for all items enhanced with the Undo functionality:&lt;br /&gt;
**Test that an item may be changed, then undo performed successfully.  &lt;br /&gt;
**Test that a sequence of changes may be performed by one user, then undo performed successfully for each action from the sequence. &lt;br /&gt;
**Test that an item may be changed by one user, changed again by another user, then undo performed by the original user will display a failure message with description.&lt;/div&gt;</summary>
		<author><name>Kbyarbor</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2013/FINAL_PROJECT_E736_UNDO_DELIVERABLE&amp;diff=74793</id>
		<title>CSC/ECE 517 Spring 2013/FINAL PROJECT E736 UNDO DELIVERABLE</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2013/FINAL_PROJECT_E736_UNDO_DELIVERABLE&amp;diff=74793"/>
		<updated>2013-04-14T23:22:35Z</updated>

		<summary type="html">&lt;p&gt;Kbyarbor: /* List of Items to be Supported by Undo Functionality */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= E736. Undo Functionality for Expertiza =&lt;br /&gt;
*Contacts: Ed Gehringer (efg@ncsu.edu) and Andrew Kofink (ajkofink@ncsu.edu)&lt;br /&gt;
*[http://wiki.expertiza.ncsu.edu/index.php/CSC/ECE_517_Spring_2013/FINAL_PROJECT_E736_UNDO Design Document]&lt;br /&gt;
*[https://docs.google.com/a/ncsu.edu/document/d/11YTjxFXFR13vJ769yFBbqn9qOueK2Ktz0Pd-gyS2W5U/ Project Description Doc]&lt;br /&gt;
== Team Members ==&lt;br /&gt;
*Chun Sing Tsui (ctsui@ncsu.edu)&lt;br /&gt;
*Kenny Yarboro (kbyarbor@ncsu.edu)&lt;br /&gt;
*Meng Cao (mcao2@ncsu.edu)&lt;br /&gt;
*Travis Folsom (twfolsom@ncsu.edu)&lt;br /&gt;
&lt;br /&gt;
== Design Document ==&lt;br /&gt;
&lt;br /&gt;
=== Overview of Undo Functionality ===&lt;br /&gt;
*Undo allows the user to undo their most recent actions for any items that offer the undo functionality.  &lt;br /&gt;
*The undo of file submissions was not required; however, we did or did not do these....depends on if we complete it...&lt;br /&gt;
*If an undo is attempted on an item already modified by another user, a message is displayed stating why undo cannot be performed.  Otherwise, the user is able to undo any changes to an item with the undo functionality.  &lt;br /&gt;
*When multiple actions are performed in one step, the undo functionality groups all of the changes together for the purposes of restoring all items affected by the action previously performed.&lt;br /&gt;
&lt;br /&gt;
=== List of Items to be Supported by Undo Functionality === &lt;br /&gt;
*Courses&lt;br /&gt;
**Create&lt;br /&gt;
**Delete&lt;br /&gt;
**Edit&lt;br /&gt;
*Import&lt;br /&gt;
**Import Participants&lt;br /&gt;
**Import Teams&lt;br /&gt;
**Import Users&lt;br /&gt;
*Teams&lt;br /&gt;
**Create (Manual)&lt;br /&gt;
**Create (Random)&lt;br /&gt;
**Edit&lt;br /&gt;
&lt;br /&gt;
=== Design Patterns and Designs ===&lt;br /&gt;
*DRY&lt;br /&gt;
**&amp;quot;Don't Repeat Yourself&amp;quot; practice will be followed. &lt;br /&gt;
*Memento&lt;br /&gt;
**The memento pattern is a software design pattern that provides the ability to restore an object to its previous state (undo via rollback). The memento pattern is implemented with two objects: the originator and a caretaker. The originator is some object that has an internal state. The caretaker is going to do something to the originator, but wants to be able to undo the change. The caretaker first asks the originator for a memento object. Then it does whatever operation (or sequence of operations) it was going to do. To roll back to the state before the operations, it returns the memento object to the originator. The memento object itself is an opaque object (one which the caretaker cannot, or should not, change). When using this pattern, care should be taken if the originator may change other objects or resources - the memento pattern operates on a single object. Classic examples of the memento pattern include the seed of a pseudorandom number generator (it will always produce the same sequence thereafter when initialized with the seed state) and the state in a finite state machine.&lt;br /&gt;
**The Memento pattern will be followed through open-source Ruby gems leveraged by the project.&lt;br /&gt;
&lt;br /&gt;
=== Frameworks to Leverage ===&lt;br /&gt;
*Paper Trail(https://github.com/airblade/paper_trail)&lt;br /&gt;
**PaperTrail allows for tracking changes to model data. &lt;br /&gt;
***Good for auditing or versioning. &lt;br /&gt;
**Offers many functionalities including:&lt;br /&gt;
****Viewing a model at any stage in its lifecycle. &lt;br /&gt;
****Reverting a model to any version.&lt;br /&gt;
****Undeleting items after they have been destroyed.&lt;br /&gt;
**Compatible with Rails-2.3.15, which is the version Expertiza uses. &lt;br /&gt;
**There is a [http://railscasts.com/episodes/255-undo-with-paper-trail Railscast] showing how to implement the undo feature with Paper Trail. &lt;br /&gt;
**Ranked as the most popular framework for Active Record versioning feature in [https://www.ruby-toolbox.com/categories/Active_Record_Versioning here]&lt;br /&gt;
**Alternative Frameworks are listed [https://www.ruby-toolbox.com/categories/Active_Record_Versioning here].&lt;br /&gt;
&lt;br /&gt;
=== Expected Classes to be Modified ===&lt;br /&gt;
*Assignment-related Classes&lt;br /&gt;
*Course-related Classes&lt;br /&gt;
*More classes may be covered as time allows.&lt;br /&gt;
&lt;br /&gt;
=== Unit Testing Plans ===&lt;br /&gt;
*Every class method modified will be tested via unit test. &lt;br /&gt;
*Every new method added will be tested via at least one unit test. &lt;br /&gt;
*All test methods shall be named with an appropriately descriptive name that is not too long.&lt;br /&gt;
&lt;br /&gt;
=== Functional Testing Plans ===&lt;br /&gt;
*The following functional test plans will be followed for all items enhanced with the Undo functionality:&lt;br /&gt;
**Test that an item may be changed, then undo performed successfully.  &lt;br /&gt;
**Test that a sequence of changes may be performed by one user, then undo performed successfully for each action from the sequence. &lt;br /&gt;
**Test that an item may be changed by one user, changed again by another user, then undo performed by the original user will display a failure message with description.&lt;/div&gt;</summary>
		<author><name>Kbyarbor</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2013/FINAL_PROJECT_E736_UNDO_DELIVERABLE&amp;diff=74792</id>
		<title>CSC/ECE 517 Spring 2013/FINAL PROJECT E736 UNDO DELIVERABLE</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2013/FINAL_PROJECT_E736_UNDO_DELIVERABLE&amp;diff=74792"/>
		<updated>2013-04-14T23:22:01Z</updated>

		<summary type="html">&lt;p&gt;Kbyarbor: /* Overview of Undo Functionality */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= E736. Undo Functionality for Expertiza =&lt;br /&gt;
*Contacts: Ed Gehringer (efg@ncsu.edu) and Andrew Kofink (ajkofink@ncsu.edu)&lt;br /&gt;
*[http://wiki.expertiza.ncsu.edu/index.php/CSC/ECE_517_Spring_2013/FINAL_PROJECT_E736_UNDO Design Document]&lt;br /&gt;
*[https://docs.google.com/a/ncsu.edu/document/d/11YTjxFXFR13vJ769yFBbqn9qOueK2Ktz0Pd-gyS2W5U/ Project Description Doc]&lt;br /&gt;
== Team Members ==&lt;br /&gt;
*Chun Sing Tsui (ctsui@ncsu.edu)&lt;br /&gt;
*Kenny Yarboro (kbyarbor@ncsu.edu)&lt;br /&gt;
*Meng Cao (mcao2@ncsu.edu)&lt;br /&gt;
*Travis Folsom (twfolsom@ncsu.edu)&lt;br /&gt;
&lt;br /&gt;
== Design Document ==&lt;br /&gt;
&lt;br /&gt;
=== Overview of Undo Functionality ===&lt;br /&gt;
*Undo allows the user to undo their most recent actions for any items that offer the undo functionality.  &lt;br /&gt;
*The undo of file submissions was not required; however, we did or did not do these....depends on if we complete it...&lt;br /&gt;
*If an undo is attempted on an item already modified by another user, a message is displayed stating why undo cannot be performed.  Otherwise, the user is able to undo any changes to an item with the undo functionality.  &lt;br /&gt;
*When multiple actions are performed in one step, the undo functionality groups all of the changes together for the purposes of restoring all items affected by the action previously performed.&lt;br /&gt;
&lt;br /&gt;
=== List of Items to be Supported by Undo Functionality ===&lt;br /&gt;
*Assignments&lt;br /&gt;
*Courses&lt;br /&gt;
*More items may be covered if time allows.&lt;br /&gt;
&lt;br /&gt;
=== Design Patterns and Designs ===&lt;br /&gt;
*DRY&lt;br /&gt;
**&amp;quot;Don't Repeat Yourself&amp;quot; practice will be followed. &lt;br /&gt;
*Memento&lt;br /&gt;
**The memento pattern is a software design pattern that provides the ability to restore an object to its previous state (undo via rollback). The memento pattern is implemented with two objects: the originator and a caretaker. The originator is some object that has an internal state. The caretaker is going to do something to the originator, but wants to be able to undo the change. The caretaker first asks the originator for a memento object. Then it does whatever operation (or sequence of operations) it was going to do. To roll back to the state before the operations, it returns the memento object to the originator. The memento object itself is an opaque object (one which the caretaker cannot, or should not, change). When using this pattern, care should be taken if the originator may change other objects or resources - the memento pattern operates on a single object. Classic examples of the memento pattern include the seed of a pseudorandom number generator (it will always produce the same sequence thereafter when initialized with the seed state) and the state in a finite state machine.&lt;br /&gt;
**The Memento pattern will be followed through open-source Ruby gems leveraged by the project.&lt;br /&gt;
&lt;br /&gt;
=== Frameworks to Leverage ===&lt;br /&gt;
*Paper Trail(https://github.com/airblade/paper_trail)&lt;br /&gt;
**PaperTrail allows for tracking changes to model data. &lt;br /&gt;
***Good for auditing or versioning. &lt;br /&gt;
**Offers many functionalities including:&lt;br /&gt;
****Viewing a model at any stage in its lifecycle. &lt;br /&gt;
****Reverting a model to any version.&lt;br /&gt;
****Undeleting items after they have been destroyed.&lt;br /&gt;
**Compatible with Rails-2.3.15, which is the version Expertiza uses. &lt;br /&gt;
**There is a [http://railscasts.com/episodes/255-undo-with-paper-trail Railscast] showing how to implement the undo feature with Paper Trail. &lt;br /&gt;
**Ranked as the most popular framework for Active Record versioning feature in [https://www.ruby-toolbox.com/categories/Active_Record_Versioning here]&lt;br /&gt;
**Alternative Frameworks are listed [https://www.ruby-toolbox.com/categories/Active_Record_Versioning here].&lt;br /&gt;
&lt;br /&gt;
=== Expected Classes to be Modified ===&lt;br /&gt;
*Assignment-related Classes&lt;br /&gt;
*Course-related Classes&lt;br /&gt;
*More classes may be covered as time allows.&lt;br /&gt;
&lt;br /&gt;
=== Unit Testing Plans ===&lt;br /&gt;
*Every class method modified will be tested via unit test. &lt;br /&gt;
*Every new method added will be tested via at least one unit test. &lt;br /&gt;
*All test methods shall be named with an appropriately descriptive name that is not too long.&lt;br /&gt;
&lt;br /&gt;
=== Functional Testing Plans ===&lt;br /&gt;
*The following functional test plans will be followed for all items enhanced with the Undo functionality:&lt;br /&gt;
**Test that an item may be changed, then undo performed successfully.  &lt;br /&gt;
**Test that a sequence of changes may be performed by one user, then undo performed successfully for each action from the sequence. &lt;br /&gt;
**Test that an item may be changed by one user, changed again by another user, then undo performed by the original user will display a failure message with description.&lt;/div&gt;</summary>
		<author><name>Kbyarbor</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2013/FINAL_PROJECT_E736_UNDO_DELIVERABLE&amp;diff=74791</id>
		<title>CSC/ECE 517 Spring 2013/FINAL PROJECT E736 UNDO DELIVERABLE</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2013/FINAL_PROJECT_E736_UNDO_DELIVERABLE&amp;diff=74791"/>
		<updated>2013-04-14T23:21:02Z</updated>

		<summary type="html">&lt;p&gt;Kbyarbor: /* Overview of Undo Functionality */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= E736. Undo Functionality for Expertiza =&lt;br /&gt;
*Contacts: Ed Gehringer (efg@ncsu.edu) and Andrew Kofink (ajkofink@ncsu.edu)&lt;br /&gt;
*[http://wiki.expertiza.ncsu.edu/index.php/CSC/ECE_517_Spring_2013/FINAL_PROJECT_E736_UNDO Design Document]&lt;br /&gt;
*[https://docs.google.com/a/ncsu.edu/document/d/11YTjxFXFR13vJ769yFBbqn9qOueK2Ktz0Pd-gyS2W5U/ Project Description Doc]&lt;br /&gt;
== Team Members ==&lt;br /&gt;
*Chun Sing Tsui (ctsui@ncsu.edu)&lt;br /&gt;
*Kenny Yarboro (kbyarbor@ncsu.edu)&lt;br /&gt;
*Meng Cao (mcao2@ncsu.edu)&lt;br /&gt;
*Travis Folsom (twfolsom@ncsu.edu)&lt;br /&gt;
&lt;br /&gt;
== Design Document ==&lt;br /&gt;
&lt;br /&gt;
=== Overview of Undo Functionality ===&lt;br /&gt;
*Undo covers the following functionalities:  &lt;br /&gt;
**Courses&lt;br /&gt;
***Create&lt;br /&gt;
***Delete&lt;br /&gt;
***Edit&lt;br /&gt;
**Import&lt;br /&gt;
***Import Participants&lt;br /&gt;
***Import Teams&lt;br /&gt;
***Import Users&lt;br /&gt;
**Teams&lt;br /&gt;
***Create (Manual)&lt;br /&gt;
***Create (Random)&lt;br /&gt;
***Edit&lt;br /&gt;
*The undo of file submissions was not required; however, we did or did not do these....depends on if we complete it...&lt;br /&gt;
*If an undo is attempted on an item already modified by another user, a message is displayed stating why undo cannot be performed.  Otherwise, the user is able to undo any changes to an item with the undo functionality.  &lt;br /&gt;
*When multiple actions are performed in one step, the undo functionality groups all of the changes together for the purposes of restoring all items affected by the action previously performed.&lt;br /&gt;
&lt;br /&gt;
=== List of Items to be Supported by Undo Functionality ===&lt;br /&gt;
*Assignments&lt;br /&gt;
*Courses&lt;br /&gt;
*More items may be covered if time allows.&lt;br /&gt;
&lt;br /&gt;
=== Design Patterns and Designs ===&lt;br /&gt;
*DRY&lt;br /&gt;
**&amp;quot;Don't Repeat Yourself&amp;quot; practice will be followed. &lt;br /&gt;
*Memento&lt;br /&gt;
**The memento pattern is a software design pattern that provides the ability to restore an object to its previous state (undo via rollback). The memento pattern is implemented with two objects: the originator and a caretaker. The originator is some object that has an internal state. The caretaker is going to do something to the originator, but wants to be able to undo the change. The caretaker first asks the originator for a memento object. Then it does whatever operation (or sequence of operations) it was going to do. To roll back to the state before the operations, it returns the memento object to the originator. The memento object itself is an opaque object (one which the caretaker cannot, or should not, change). When using this pattern, care should be taken if the originator may change other objects or resources - the memento pattern operates on a single object. Classic examples of the memento pattern include the seed of a pseudorandom number generator (it will always produce the same sequence thereafter when initialized with the seed state) and the state in a finite state machine.&lt;br /&gt;
**The Memento pattern will be followed through open-source Ruby gems leveraged by the project.&lt;br /&gt;
&lt;br /&gt;
=== Frameworks to Leverage ===&lt;br /&gt;
*Paper Trail(https://github.com/airblade/paper_trail)&lt;br /&gt;
**PaperTrail allows for tracking changes to model data. &lt;br /&gt;
***Good for auditing or versioning. &lt;br /&gt;
**Offers many functionalities including:&lt;br /&gt;
****Viewing a model at any stage in its lifecycle. &lt;br /&gt;
****Reverting a model to any version.&lt;br /&gt;
****Undeleting items after they have been destroyed.&lt;br /&gt;
**Compatible with Rails-2.3.15, which is the version Expertiza uses. &lt;br /&gt;
**There is a [http://railscasts.com/episodes/255-undo-with-paper-trail Railscast] showing how to implement the undo feature with Paper Trail. &lt;br /&gt;
**Ranked as the most popular framework for Active Record versioning feature in [https://www.ruby-toolbox.com/categories/Active_Record_Versioning here]&lt;br /&gt;
**Alternative Frameworks are listed [https://www.ruby-toolbox.com/categories/Active_Record_Versioning here].&lt;br /&gt;
&lt;br /&gt;
=== Expected Classes to be Modified ===&lt;br /&gt;
*Assignment-related Classes&lt;br /&gt;
*Course-related Classes&lt;br /&gt;
*More classes may be covered as time allows.&lt;br /&gt;
&lt;br /&gt;
=== Unit Testing Plans ===&lt;br /&gt;
*Every class method modified will be tested via unit test. &lt;br /&gt;
*Every new method added will be tested via at least one unit test. &lt;br /&gt;
*All test methods shall be named with an appropriately descriptive name that is not too long.&lt;br /&gt;
&lt;br /&gt;
=== Functional Testing Plans ===&lt;br /&gt;
*The following functional test plans will be followed for all items enhanced with the Undo functionality:&lt;br /&gt;
**Test that an item may be changed, then undo performed successfully.  &lt;br /&gt;
**Test that a sequence of changes may be performed by one user, then undo performed successfully for each action from the sequence. &lt;br /&gt;
**Test that an item may be changed by one user, changed again by another user, then undo performed by the original user will display a failure message with description.&lt;/div&gt;</summary>
		<author><name>Kbyarbor</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2013/FINAL_PROJECT_E736_UNDO_DELIVERABLE&amp;diff=74790</id>
		<title>CSC/ECE 517 Spring 2013/FINAL PROJECT E736 UNDO DELIVERABLE</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2013/FINAL_PROJECT_E736_UNDO_DELIVERABLE&amp;diff=74790"/>
		<updated>2013-04-14T23:12:23Z</updated>

		<summary type="html">&lt;p&gt;Kbyarbor: /* E736. Undo Functionality for Expertiza */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= E736. Undo Functionality for Expertiza =&lt;br /&gt;
*Contacts: Ed Gehringer (efg@ncsu.edu) and Andrew Kofink (ajkofink@ncsu.edu)&lt;br /&gt;
*[http://wiki.expertiza.ncsu.edu/index.php/CSC/ECE_517_Spring_2013/FINAL_PROJECT_E736_UNDO Design Document]&lt;br /&gt;
*[https://docs.google.com/a/ncsu.edu/document/d/11YTjxFXFR13vJ769yFBbqn9qOueK2Ktz0Pd-gyS2W5U/ Project Description Doc]&lt;br /&gt;
== Team Members ==&lt;br /&gt;
*Chun Sing Tsui (ctsui@ncsu.edu)&lt;br /&gt;
*Kenny Yarboro (kbyarbor@ncsu.edu)&lt;br /&gt;
*Meng Cao (mcao2@ncsu.edu)&lt;br /&gt;
*Travis Folsom (twfolsom@ncsu.edu)&lt;br /&gt;
&lt;br /&gt;
== Design Document ==&lt;br /&gt;
&lt;br /&gt;
=== Overview of Undo Functionality ===&lt;br /&gt;
*Undo should cover any edit functionalities and any submissions of links.  File submissions do not need to be included for the scope of this project. &lt;br /&gt;
*User should be able to undo any changes to an item (such as course or assignment) as long as no other user has edited that same item within the user's current session.  &lt;br /&gt;
*If undo is attempted on an item already modified by another user, display a message stating why undo cannot be done.  &lt;br /&gt;
&lt;br /&gt;
=== List of Items to be Supported by Undo Functionality ===&lt;br /&gt;
*Assignments&lt;br /&gt;
*Courses&lt;br /&gt;
*More items may be covered if time allows.&lt;br /&gt;
&lt;br /&gt;
=== Design Patterns and Designs ===&lt;br /&gt;
*DRY&lt;br /&gt;
**&amp;quot;Don't Repeat Yourself&amp;quot; practice will be followed. &lt;br /&gt;
*Memento&lt;br /&gt;
**The memento pattern is a software design pattern that provides the ability to restore an object to its previous state (undo via rollback). The memento pattern is implemented with two objects: the originator and a caretaker. The originator is some object that has an internal state. The caretaker is going to do something to the originator, but wants to be able to undo the change. The caretaker first asks the originator for a memento object. Then it does whatever operation (or sequence of operations) it was going to do. To roll back to the state before the operations, it returns the memento object to the originator. The memento object itself is an opaque object (one which the caretaker cannot, or should not, change). When using this pattern, care should be taken if the originator may change other objects or resources - the memento pattern operates on a single object. Classic examples of the memento pattern include the seed of a pseudorandom number generator (it will always produce the same sequence thereafter when initialized with the seed state) and the state in a finite state machine.&lt;br /&gt;
**The Memento pattern will be followed through open-source Ruby gems leveraged by the project.&lt;br /&gt;
&lt;br /&gt;
=== Frameworks to Leverage ===&lt;br /&gt;
*Paper Trail(https://github.com/airblade/paper_trail)&lt;br /&gt;
**PaperTrail allows for tracking changes to model data. &lt;br /&gt;
***Good for auditing or versioning. &lt;br /&gt;
**Offers many functionalities including:&lt;br /&gt;
****Viewing a model at any stage in its lifecycle. &lt;br /&gt;
****Reverting a model to any version.&lt;br /&gt;
****Undeleting items after they have been destroyed.&lt;br /&gt;
**Compatible with Rails-2.3.15, which is the version Expertiza uses. &lt;br /&gt;
**There is a [http://railscasts.com/episodes/255-undo-with-paper-trail Railscast] showing how to implement the undo feature with Paper Trail. &lt;br /&gt;
**Ranked as the most popular framework for Active Record versioning feature in [https://www.ruby-toolbox.com/categories/Active_Record_Versioning here]&lt;br /&gt;
**Alternative Frameworks are listed [https://www.ruby-toolbox.com/categories/Active_Record_Versioning here].&lt;br /&gt;
&lt;br /&gt;
=== Expected Classes to be Modified ===&lt;br /&gt;
*Assignment-related Classes&lt;br /&gt;
*Course-related Classes&lt;br /&gt;
*More classes may be covered as time allows.&lt;br /&gt;
&lt;br /&gt;
=== Unit Testing Plans ===&lt;br /&gt;
*Every class method modified will be tested via unit test. &lt;br /&gt;
*Every new method added will be tested via at least one unit test. &lt;br /&gt;
*All test methods shall be named with an appropriately descriptive name that is not too long.&lt;br /&gt;
&lt;br /&gt;
=== Functional Testing Plans ===&lt;br /&gt;
*The following functional test plans will be followed for all items enhanced with the Undo functionality:&lt;br /&gt;
**Test that an item may be changed, then undo performed successfully.  &lt;br /&gt;
**Test that a sequence of changes may be performed by one user, then undo performed successfully for each action from the sequence. &lt;br /&gt;
**Test that an item may be changed by one user, changed again by another user, then undo performed by the original user will display a failure message with description.&lt;/div&gt;</summary>
		<author><name>Kbyarbor</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2013/FINAL_PROJECT_E736_UNDO_DELIVERABLE&amp;diff=74789</id>
		<title>CSC/ECE 517 Spring 2013/FINAL PROJECT E736 UNDO DELIVERABLE</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2013/FINAL_PROJECT_E736_UNDO_DELIVERABLE&amp;diff=74789"/>
		<updated>2013-04-14T23:11:05Z</updated>

		<summary type="html">&lt;p&gt;Kbyarbor: Created page with &amp;quot;= E736. Undo Functionality for Expertiza = *Contacts: Ed Gehringer (efg@ncsu.edu) and Andrew Kofink (ajkofink@ncsu.edu) *Begin implementing SQL transactions (ActiveRecord:Transac...&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= E736. Undo Functionality for Expertiza =&lt;br /&gt;
*Contacts: Ed Gehringer (efg@ncsu.edu) and Andrew Kofink (ajkofink@ncsu.edu)&lt;br /&gt;
*Begin implementing SQL transactions (ActiveRecord:Transactions).  This should let the user &amp;quot;roll back&amp;quot; any creation or update of a SQL table (assignments, rubrics, etc.)  Several issues arise, that you should discuss with me. &lt;br /&gt;
**Should students be able to roll back, e.g., submissions or reviews?&lt;br /&gt;
**Suppose an instructor is trying to roll back and a TA is editing the same assignment?  How can conflicts be presented?&lt;br /&gt;
**Do rollbacks affect only what's in the db, or do they also affect submitted files?&lt;br /&gt;
*[https://docs.google.com/a/ncsu.edu/document/d/11YTjxFXFR13vJ769yFBbqn9qOueK2Ktz0Pd-gyS2W5U/ Project Description Doc]&lt;br /&gt;
== Team Members ==&lt;br /&gt;
*Chun Sing Tsui (ctsui@ncsu.edu)&lt;br /&gt;
*Kenny Yarboro (kbyarbor@ncsu.edu)&lt;br /&gt;
*Meng Cao (mcao2@ncsu.edu)&lt;br /&gt;
*Travis Folsom (twfolsom@ncsu.edu)&lt;br /&gt;
&lt;br /&gt;
== Design Document ==&lt;br /&gt;
&lt;br /&gt;
=== Overview of Undo Functionality ===&lt;br /&gt;
*Undo should cover any edit functionalities and any submissions of links.  File submissions do not need to be included for the scope of this project. &lt;br /&gt;
*User should be able to undo any changes to an item (such as course or assignment) as long as no other user has edited that same item within the user's current session.  &lt;br /&gt;
*If undo is attempted on an item already modified by another user, display a message stating why undo cannot be done.  &lt;br /&gt;
&lt;br /&gt;
=== List of Items to be Supported by Undo Functionality ===&lt;br /&gt;
*Assignments&lt;br /&gt;
*Courses&lt;br /&gt;
*More items may be covered if time allows.&lt;br /&gt;
&lt;br /&gt;
=== Design Patterns and Designs ===&lt;br /&gt;
*DRY&lt;br /&gt;
**&amp;quot;Don't Repeat Yourself&amp;quot; practice will be followed. &lt;br /&gt;
*Memento&lt;br /&gt;
**The memento pattern is a software design pattern that provides the ability to restore an object to its previous state (undo via rollback). The memento pattern is implemented with two objects: the originator and a caretaker. The originator is some object that has an internal state. The caretaker is going to do something to the originator, but wants to be able to undo the change. The caretaker first asks the originator for a memento object. Then it does whatever operation (or sequence of operations) it was going to do. To roll back to the state before the operations, it returns the memento object to the originator. The memento object itself is an opaque object (one which the caretaker cannot, or should not, change). When using this pattern, care should be taken if the originator may change other objects or resources - the memento pattern operates on a single object. Classic examples of the memento pattern include the seed of a pseudorandom number generator (it will always produce the same sequence thereafter when initialized with the seed state) and the state in a finite state machine.&lt;br /&gt;
**The Memento pattern will be followed through open-source Ruby gems leveraged by the project.&lt;br /&gt;
&lt;br /&gt;
=== Frameworks to Leverage ===&lt;br /&gt;
*Paper Trail(https://github.com/airblade/paper_trail)&lt;br /&gt;
**PaperTrail allows for tracking changes to model data. &lt;br /&gt;
***Good for auditing or versioning. &lt;br /&gt;
**Offers many functionalities including:&lt;br /&gt;
****Viewing a model at any stage in its lifecycle. &lt;br /&gt;
****Reverting a model to any version.&lt;br /&gt;
****Undeleting items after they have been destroyed.&lt;br /&gt;
**Compatible with Rails-2.3.15, which is the version Expertiza uses. &lt;br /&gt;
**There is a [http://railscasts.com/episodes/255-undo-with-paper-trail Railscast] showing how to implement the undo feature with Paper Trail. &lt;br /&gt;
**Ranked as the most popular framework for Active Record versioning feature in [https://www.ruby-toolbox.com/categories/Active_Record_Versioning here]&lt;br /&gt;
**Alternative Frameworks are listed [https://www.ruby-toolbox.com/categories/Active_Record_Versioning here].&lt;br /&gt;
&lt;br /&gt;
=== Expected Classes to be Modified ===&lt;br /&gt;
*Assignment-related Classes&lt;br /&gt;
*Course-related Classes&lt;br /&gt;
*More classes may be covered as time allows.&lt;br /&gt;
&lt;br /&gt;
=== Unit Testing Plans ===&lt;br /&gt;
*Every class method modified will be tested via unit test. &lt;br /&gt;
*Every new method added will be tested via at least one unit test. &lt;br /&gt;
*All test methods shall be named with an appropriately descriptive name that is not too long.&lt;br /&gt;
&lt;br /&gt;
=== Functional Testing Plans ===&lt;br /&gt;
*The following functional test plans will be followed for all items enhanced with the Undo functionality:&lt;br /&gt;
**Test that an item may be changed, then undo performed successfully.  &lt;br /&gt;
**Test that a sequence of changes may be performed by one user, then undo performed successfully for each action from the sequence. &lt;br /&gt;
**Test that an item may be changed by one user, changed again by another user, then undo performed by the original user will display a failure message with description.&lt;/div&gt;</summary>
		<author><name>Kbyarbor</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2013/FINAL_PROJECT_E736_UNDO&amp;diff=74506</id>
		<title>CSC/ECE 517 Spring 2013/FINAL PROJECT E736 UNDO</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2013/FINAL_PROJECT_E736_UNDO&amp;diff=74506"/>
		<updated>2013-04-02T00:44:09Z</updated>

		<summary type="html">&lt;p&gt;Kbyarbor: /* Functional Testing Plans */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= E736. Undo Functionality for Expertiza =&lt;br /&gt;
*Contacts: Ed Gehringer (efg@ncsu.edu) and Andrew Kofink (ajkofink@ncsu.edu)&lt;br /&gt;
*Begin implementing SQL transactions (ActiveRecord:Transactions).  This should let the user &amp;quot;roll back&amp;quot; any creation or update of a SQL table (assignments, rubrics, etc.)  Several issues arise, that you should discuss with me. &lt;br /&gt;
**Should students be able to roll back, e.g., submissions or reviews?&lt;br /&gt;
**Suppose an instructor is trying to roll back and a TA is editing the same assignment?  How can conflicts be presented?&lt;br /&gt;
**Do rollbacks affect only what's in the db, or do they also affect submitted files?&lt;br /&gt;
&lt;br /&gt;
== Team Members ==&lt;br /&gt;
*Chun Sing Tsui (ctsui@ncsu.edu)&lt;br /&gt;
*Kenny Yarboro (kbyarbor@ncsu.edu)&lt;br /&gt;
*Meng Cao (mcao2@ncsu.edu)&lt;br /&gt;
*Travis Folsom (twfolsom@ncsu.edu)&lt;br /&gt;
&lt;br /&gt;
== Design Document ==&lt;br /&gt;
&lt;br /&gt;
=== Overview of Undo Functionality ===&lt;br /&gt;
*Undo should cover any edit functionalities and any submissions of links.  File submissions do not need to be included for the scope of this project. &lt;br /&gt;
*User should be able to undo any changes to an item (such as course or assignment) as long as no other user has edited that same item within the user's current session.  &lt;br /&gt;
*If undo is attempted on an item already modified by another user, display a message stating why undo cannot be done.  &lt;br /&gt;
&lt;br /&gt;
=== List of Items to be Supported by Undo Functionality ===&lt;br /&gt;
*Assignments&lt;br /&gt;
*Courses&lt;br /&gt;
*More items may be covered if time allows.&lt;br /&gt;
&lt;br /&gt;
=== Design Patterns and Designs ===&lt;br /&gt;
*DRY&lt;br /&gt;
**&amp;quot;Don't Repeat Yourself&amp;quot; practice will be followed. &lt;br /&gt;
*Memento&lt;br /&gt;
**The Memento pattern will be followed through open-source Ruby gems leveraged by the project.&lt;br /&gt;
&lt;br /&gt;
=== Frameworks to Leverage ===&lt;br /&gt;
*Paper Trail(https://github.com/airblade/paper_trail)&lt;br /&gt;
**PaperTrail allows for tracking changes to model data. &lt;br /&gt;
***Good for auditing or versioning. &lt;br /&gt;
**Offers many functionalities including:&lt;br /&gt;
****Viewing a model at any stage in its lifecycle. &lt;br /&gt;
****Reverting a model to any version.&lt;br /&gt;
****Undeleting items after they have been destroyed.&lt;br /&gt;
**Compatible with Rails-2.3.15, which is the version Expertiza uses. &lt;br /&gt;
**There is a [http://railscasts.com/episodes/255-undo-with-paper-trail Railscast] showing how to implement the undo feature with Paper Trail. &lt;br /&gt;
**Ranked as the most popular framework for Active Record versioning feature in [https://www.ruby-toolbox.com/categories/Active_Record_Versioning here]&lt;br /&gt;
**Alternative Frameworks are listed [https://www.ruby-toolbox.com/categories/Active_Record_Versioning here].&lt;br /&gt;
&lt;br /&gt;
=== Expected Classes to be Modified ===&lt;br /&gt;
*Assignment-related Classes&lt;br /&gt;
*Course-related Classes&lt;br /&gt;
*More classes may be covered as time allows.&lt;br /&gt;
&lt;br /&gt;
=== Unit Testing Plans ===&lt;br /&gt;
*Every class method modified will be tested via unit test. &lt;br /&gt;
*Every new method added will be tested via at least one unit test. &lt;br /&gt;
*All test methods shall be named with an appropriately descriptive name that is not too long.&lt;br /&gt;
&lt;br /&gt;
=== Functional Testing Plans ===&lt;br /&gt;
*The following functional test plans will be followed for all items enhanced with the Undo functionality:&lt;br /&gt;
**Test that an item may be changed, then undo performed successfully.  &lt;br /&gt;
**Test that a sequence of changes may be performed by one user, then undo performed successfully for each action from the sequence. &lt;br /&gt;
**Test that an item may be changed by one user, changed again by another user, then undo performed by the original user will display a failure message with description.&lt;/div&gt;</summary>
		<author><name>Kbyarbor</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2013/FINAL_PROJECT_E736_UNDO&amp;diff=74505</id>
		<title>CSC/ECE 517 Spring 2013/FINAL PROJECT E736 UNDO</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2013/FINAL_PROJECT_E736_UNDO&amp;diff=74505"/>
		<updated>2013-04-02T00:39:56Z</updated>

		<summary type="html">&lt;p&gt;Kbyarbor: /* Expected Functional Tests to Include */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= E736. Undo Functionality for Expertiza =&lt;br /&gt;
*Contacts: Ed Gehringer (efg@ncsu.edu) and Andrew Kofink (ajkofink@ncsu.edu)&lt;br /&gt;
*Begin implementing SQL transactions (ActiveRecord:Transactions).  This should let the user &amp;quot;roll back&amp;quot; any creation or update of a SQL table (assignments, rubrics, etc.)  Several issues arise, that you should discuss with me. &lt;br /&gt;
**Should students be able to roll back, e.g., submissions or reviews?&lt;br /&gt;
**Suppose an instructor is trying to roll back and a TA is editing the same assignment?  How can conflicts be presented?&lt;br /&gt;
**Do rollbacks affect only what's in the db, or do they also affect submitted files?&lt;br /&gt;
&lt;br /&gt;
== Team Members ==&lt;br /&gt;
*Chun Sing Tsui (ctsui@ncsu.edu)&lt;br /&gt;
*Kenny Yarboro (kbyarbor@ncsu.edu)&lt;br /&gt;
*Meng Cao (mcao2@ncsu.edu)&lt;br /&gt;
*Travis Folsom (twfolsom@ncsu.edu)&lt;br /&gt;
&lt;br /&gt;
== Design Document ==&lt;br /&gt;
&lt;br /&gt;
=== Overview of Undo Functionality ===&lt;br /&gt;
*Undo should cover any edit functionalities and any submissions of links.  File submissions do not need to be included for the scope of this project. &lt;br /&gt;
*User should be able to undo any changes to an item (such as course or assignment) as long as no other user has edited that same item within the user's current session.  &lt;br /&gt;
*If undo is attempted on an item already modified by another user, display a message stating why undo cannot be done.  &lt;br /&gt;
&lt;br /&gt;
=== List of Items to be Supported by Undo Functionality ===&lt;br /&gt;
*Assignments&lt;br /&gt;
*Courses&lt;br /&gt;
*More items may be covered if time allows.&lt;br /&gt;
&lt;br /&gt;
=== Design Patterns and Designs ===&lt;br /&gt;
*DRY&lt;br /&gt;
**&amp;quot;Don't Repeat Yourself&amp;quot; practice will be followed. &lt;br /&gt;
*Memento&lt;br /&gt;
**The Memento pattern will be followed through open-source Ruby gems leveraged by the project.&lt;br /&gt;
&lt;br /&gt;
=== Frameworks to Leverage ===&lt;br /&gt;
*Paper Trail(https://github.com/airblade/paper_trail)&lt;br /&gt;
**PaperTrail allows for tracking changes to model data. &lt;br /&gt;
***Good for auditing or versioning. &lt;br /&gt;
**Offers many functionalities including:&lt;br /&gt;
****Viewing a model at any stage in its lifecycle. &lt;br /&gt;
****Reverting a model to any version.&lt;br /&gt;
****Undeleting items after they have been destroyed.&lt;br /&gt;
**Compatible with Rails-2.3.15, which is the version Expertiza uses. &lt;br /&gt;
**There is a [http://railscasts.com/episodes/255-undo-with-paper-trail Railscast] showing how to implement the undo feature with Paper Trail. &lt;br /&gt;
**Ranked as the most popular framework for Active Record versioning feature in [https://www.ruby-toolbox.com/categories/Active_Record_Versioning here]&lt;br /&gt;
**Alternative Frameworks are listed [https://www.ruby-toolbox.com/categories/Active_Record_Versioning here].&lt;br /&gt;
&lt;br /&gt;
=== Expected Classes to be Modified ===&lt;br /&gt;
*Assignment-related Classes&lt;br /&gt;
*Course-related Classes&lt;br /&gt;
*More classes may be covered as time allows.&lt;br /&gt;
&lt;br /&gt;
=== Unit Testing Plans ===&lt;br /&gt;
*Every class method modified will be tested via unit test. &lt;br /&gt;
*Every new method added will be tested via at least one unit test. &lt;br /&gt;
*All test methods shall be named with an appropriately descriptive name that is not too long.&lt;br /&gt;
&lt;br /&gt;
=== Functional Testing Plans ===&lt;br /&gt;
*one&lt;br /&gt;
*two&lt;/div&gt;</summary>
		<author><name>Kbyarbor</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2013/FINAL_PROJECT_E736_UNDO&amp;diff=74502</id>
		<title>CSC/ECE 517 Spring 2013/FINAL PROJECT E736 UNDO</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2013/FINAL_PROJECT_E736_UNDO&amp;diff=74502"/>
		<updated>2013-04-02T00:37:49Z</updated>

		<summary type="html">&lt;p&gt;Kbyarbor: /* Expected Unit Tests to Include */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= E736. Undo Functionality for Expertiza =&lt;br /&gt;
*Contacts: Ed Gehringer (efg@ncsu.edu) and Andrew Kofink (ajkofink@ncsu.edu)&lt;br /&gt;
*Begin implementing SQL transactions (ActiveRecord:Transactions).  This should let the user &amp;quot;roll back&amp;quot; any creation or update of a SQL table (assignments, rubrics, etc.)  Several issues arise, that you should discuss with me. &lt;br /&gt;
**Should students be able to roll back, e.g., submissions or reviews?&lt;br /&gt;
**Suppose an instructor is trying to roll back and a TA is editing the same assignment?  How can conflicts be presented?&lt;br /&gt;
**Do rollbacks affect only what's in the db, or do they also affect submitted files?&lt;br /&gt;
&lt;br /&gt;
== Team Members ==&lt;br /&gt;
*Chun Sing Tsui (ctsui@ncsu.edu)&lt;br /&gt;
*Kenny Yarboro (kbyarbor@ncsu.edu)&lt;br /&gt;
*Meng Cao (mcao2@ncsu.edu)&lt;br /&gt;
*Travis Folsom (twfolsom@ncsu.edu)&lt;br /&gt;
&lt;br /&gt;
== Design Document ==&lt;br /&gt;
&lt;br /&gt;
=== Overview of Undo Functionality ===&lt;br /&gt;
*Undo should cover any edit functionalities and any submissions of links.  File submissions do not need to be included for the scope of this project. &lt;br /&gt;
*User should be able to undo any changes to an item (such as course or assignment) as long as no other user has edited that same item within the user's current session.  &lt;br /&gt;
*If undo is attempted on an item already modified by another user, display a message stating why undo cannot be done.  &lt;br /&gt;
&lt;br /&gt;
=== List of Items to be Supported by Undo Functionality ===&lt;br /&gt;
*Assignments&lt;br /&gt;
*Courses&lt;br /&gt;
*More items may be covered if time allows.&lt;br /&gt;
&lt;br /&gt;
=== Design Patterns and Designs ===&lt;br /&gt;
*DRY&lt;br /&gt;
**&amp;quot;Don't Repeat Yourself&amp;quot; practice will be followed. &lt;br /&gt;
*Memento&lt;br /&gt;
**The Memento pattern will be followed through open-source Ruby gems leveraged by the project.&lt;br /&gt;
&lt;br /&gt;
=== Frameworks to Leverage ===&lt;br /&gt;
*Paper Trail(https://github.com/airblade/paper_trail)&lt;br /&gt;
**PaperTrail allows for tracking changes to model data. &lt;br /&gt;
***Good for auditing or versioning. &lt;br /&gt;
**Offers many functionalities including:&lt;br /&gt;
****Viewing a model at any stage in its lifecycle. &lt;br /&gt;
****Reverting a model to any version.&lt;br /&gt;
****Undeleting items after they have been destroyed.&lt;br /&gt;
**Compatible with Rails-2.3.15, which is the version Expertiza uses. &lt;br /&gt;
**There is a [http://railscasts.com/episodes/255-undo-with-paper-trail Railscast] showing how to implement the undo feature with Paper Trail. &lt;br /&gt;
**Ranked as the most popular framework for Active Record versioning feature in [https://www.ruby-toolbox.com/categories/Active_Record_Versioning here]&lt;br /&gt;
**Alternative Frameworks are listed [https://www.ruby-toolbox.com/categories/Active_Record_Versioning here].&lt;br /&gt;
&lt;br /&gt;
=== Expected Classes to be Modified ===&lt;br /&gt;
*Assignment-related Classes&lt;br /&gt;
*Course-related Classes&lt;br /&gt;
*More classes may be covered as time allows.&lt;br /&gt;
&lt;br /&gt;
=== Unit Testing Plans ===&lt;br /&gt;
*Every class method modified will be tested via unit test. &lt;br /&gt;
*Every new method added will be tested via at least one unit test. &lt;br /&gt;
*All test methods shall be named with an appropriately descriptive name that is not too long.&lt;br /&gt;
&lt;br /&gt;
=== Expected Functional Tests to Include ===&lt;br /&gt;
*Happy Path&lt;br /&gt;
**User successfully undoes his/her action on various models(Course, Assignment, etc).&lt;br /&gt;
*Sad path&lt;br /&gt;
**User is unable to undo, due to reasons as&lt;br /&gt;
***user has no privilege to the undo action: a student can't undo his/her submission after due date.&lt;br /&gt;
***some other user is editing the same item at the same time.&lt;/div&gt;</summary>
		<author><name>Kbyarbor</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2013/FINAL_PROJECT_E736_UNDO&amp;diff=74501</id>
		<title>CSC/ECE 517 Spring 2013/FINAL PROJECT E736 UNDO</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2013/FINAL_PROJECT_E736_UNDO&amp;diff=74501"/>
		<updated>2013-04-02T00:35:06Z</updated>

		<summary type="html">&lt;p&gt;Kbyarbor: /* Expected Classes to be Modified */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= E736. Undo Functionality for Expertiza =&lt;br /&gt;
*Contacts: Ed Gehringer (efg@ncsu.edu) and Andrew Kofink (ajkofink@ncsu.edu)&lt;br /&gt;
*Begin implementing SQL transactions (ActiveRecord:Transactions).  This should let the user &amp;quot;roll back&amp;quot; any creation or update of a SQL table (assignments, rubrics, etc.)  Several issues arise, that you should discuss with me. &lt;br /&gt;
**Should students be able to roll back, e.g., submissions or reviews?&lt;br /&gt;
**Suppose an instructor is trying to roll back and a TA is editing the same assignment?  How can conflicts be presented?&lt;br /&gt;
**Do rollbacks affect only what's in the db, or do they also affect submitted files?&lt;br /&gt;
&lt;br /&gt;
== Team Members ==&lt;br /&gt;
*Chun Sing Tsui (ctsui@ncsu.edu)&lt;br /&gt;
*Kenny Yarboro (kbyarbor@ncsu.edu)&lt;br /&gt;
*Meng Cao (mcao2@ncsu.edu)&lt;br /&gt;
*Travis Folsom (twfolsom@ncsu.edu)&lt;br /&gt;
&lt;br /&gt;
== Design Document ==&lt;br /&gt;
&lt;br /&gt;
=== Overview of Undo Functionality ===&lt;br /&gt;
*Undo should cover any edit functionalities and any submissions of links.  File submissions do not need to be included for the scope of this project. &lt;br /&gt;
*User should be able to undo any changes to an item (such as course or assignment) as long as no other user has edited that same item within the user's current session.  &lt;br /&gt;
*If undo is attempted on an item already modified by another user, display a message stating why undo cannot be done.  &lt;br /&gt;
&lt;br /&gt;
=== List of Items to be Supported by Undo Functionality ===&lt;br /&gt;
*Assignments&lt;br /&gt;
*Courses&lt;br /&gt;
*More items may be covered if time allows.&lt;br /&gt;
&lt;br /&gt;
=== Design Patterns and Designs ===&lt;br /&gt;
*DRY&lt;br /&gt;
**&amp;quot;Don't Repeat Yourself&amp;quot; practice will be followed. &lt;br /&gt;
*Memento&lt;br /&gt;
**The Memento pattern will be followed through open-source Ruby gems leveraged by the project.&lt;br /&gt;
&lt;br /&gt;
=== Frameworks to Leverage ===&lt;br /&gt;
*Paper Trail(https://github.com/airblade/paper_trail)&lt;br /&gt;
**PaperTrail allows for tracking changes to model data. &lt;br /&gt;
***Good for auditing or versioning. &lt;br /&gt;
**Offers many functionalities including:&lt;br /&gt;
****Viewing a model at any stage in its lifecycle. &lt;br /&gt;
****Reverting a model to any version.&lt;br /&gt;
****Undeleting items after they have been destroyed.&lt;br /&gt;
**Compatible with Rails-2.3.15, which is the version Expertiza uses. &lt;br /&gt;
**There is a [http://railscasts.com/episodes/255-undo-with-paper-trail Railscast] showing how to implement the undo feature with Paper Trail. &lt;br /&gt;
**Ranked as the most popular framework for Active Record versioning feature in [https://www.ruby-toolbox.com/categories/Active_Record_Versioning here]&lt;br /&gt;
**Alternative Frameworks are listed [https://www.ruby-toolbox.com/categories/Active_Record_Versioning here].&lt;br /&gt;
&lt;br /&gt;
=== Expected Classes to be Modified ===&lt;br /&gt;
*Assignment-related Classes&lt;br /&gt;
*Course-related Classes&lt;br /&gt;
*More classes may be covered as time allows.&lt;br /&gt;
&lt;br /&gt;
=== Expected Unit Tests to Include ===&lt;br /&gt;
*at least one per method...&lt;br /&gt;
&lt;br /&gt;
=== Expected Functional Tests to Include ===&lt;br /&gt;
*Happy Path&lt;br /&gt;
**User successfully undoes his/her action on various models(Course, Assignment, etc).&lt;br /&gt;
*Sad path&lt;br /&gt;
**User is unable to undo, due to reasons as&lt;br /&gt;
***user has no privilege to the undo action: a student can't undo his/her submission after due date.&lt;br /&gt;
***some other user is editing the same item at the same time.&lt;/div&gt;</summary>
		<author><name>Kbyarbor</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2013/FINAL_PROJECT_E736_UNDO&amp;diff=74500</id>
		<title>CSC/ECE 517 Spring 2013/FINAL PROJECT E736 UNDO</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2013/FINAL_PROJECT_E736_UNDO&amp;diff=74500"/>
		<updated>2013-04-02T00:34:45Z</updated>

		<summary type="html">&lt;p&gt;Kbyarbor: /* Expected Classes to be Modified */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= E736. Undo Functionality for Expertiza =&lt;br /&gt;
*Contacts: Ed Gehringer (efg@ncsu.edu) and Andrew Kofink (ajkofink@ncsu.edu)&lt;br /&gt;
*Begin implementing SQL transactions (ActiveRecord:Transactions).  This should let the user &amp;quot;roll back&amp;quot; any creation or update of a SQL table (assignments, rubrics, etc.)  Several issues arise, that you should discuss with me. &lt;br /&gt;
**Should students be able to roll back, e.g., submissions or reviews?&lt;br /&gt;
**Suppose an instructor is trying to roll back and a TA is editing the same assignment?  How can conflicts be presented?&lt;br /&gt;
**Do rollbacks affect only what's in the db, or do they also affect submitted files?&lt;br /&gt;
&lt;br /&gt;
== Team Members ==&lt;br /&gt;
*Chun Sing Tsui (ctsui@ncsu.edu)&lt;br /&gt;
*Kenny Yarboro (kbyarbor@ncsu.edu)&lt;br /&gt;
*Meng Cao (mcao2@ncsu.edu)&lt;br /&gt;
*Travis Folsom (twfolsom@ncsu.edu)&lt;br /&gt;
&lt;br /&gt;
== Design Document ==&lt;br /&gt;
&lt;br /&gt;
=== Overview of Undo Functionality ===&lt;br /&gt;
*Undo should cover any edit functionalities and any submissions of links.  File submissions do not need to be included for the scope of this project. &lt;br /&gt;
*User should be able to undo any changes to an item (such as course or assignment) as long as no other user has edited that same item within the user's current session.  &lt;br /&gt;
*If undo is attempted on an item already modified by another user, display a message stating why undo cannot be done.  &lt;br /&gt;
&lt;br /&gt;
=== List of Items to be Supported by Undo Functionality ===&lt;br /&gt;
*Assignments&lt;br /&gt;
*Courses&lt;br /&gt;
*More items may be covered if time allows.&lt;br /&gt;
&lt;br /&gt;
=== Design Patterns and Designs ===&lt;br /&gt;
*DRY&lt;br /&gt;
**&amp;quot;Don't Repeat Yourself&amp;quot; practice will be followed. &lt;br /&gt;
*Memento&lt;br /&gt;
**The Memento pattern will be followed through open-source Ruby gems leveraged by the project.&lt;br /&gt;
&lt;br /&gt;
=== Frameworks to Leverage ===&lt;br /&gt;
*Paper Trail(https://github.com/airblade/paper_trail)&lt;br /&gt;
**PaperTrail allows for tracking changes to model data. &lt;br /&gt;
***Good for auditing or versioning. &lt;br /&gt;
**Offers many functionalities including:&lt;br /&gt;
****Viewing a model at any stage in its lifecycle. &lt;br /&gt;
****Reverting a model to any version.&lt;br /&gt;
****Undeleting items after they have been destroyed.&lt;br /&gt;
**Compatible with Rails-2.3.15, which is the version Expertiza uses. &lt;br /&gt;
**There is a [http://railscasts.com/episodes/255-undo-with-paper-trail Railscast] showing how to implement the undo feature with Paper Trail. &lt;br /&gt;
**Ranked as the most popular framework for Active Record versioning feature in [https://www.ruby-toolbox.com/categories/Active_Record_Versioning here]&lt;br /&gt;
**Alternative Frameworks are listed [https://www.ruby-toolbox.com/categories/Active_Record_Versioning here].&lt;br /&gt;
&lt;br /&gt;
=== Expected Classes to be Modified ===&lt;br /&gt;
*Assignment-related Classes&lt;br /&gt;
*Course-related Classes&lt;br /&gt;
*More classes may be added as time allows.&lt;br /&gt;
&lt;br /&gt;
=== Expected Unit Tests to Include ===&lt;br /&gt;
*at least one per method...&lt;br /&gt;
&lt;br /&gt;
=== Expected Functional Tests to Include ===&lt;br /&gt;
*Happy Path&lt;br /&gt;
**User successfully undoes his/her action on various models(Course, Assignment, etc).&lt;br /&gt;
*Sad path&lt;br /&gt;
**User is unable to undo, due to reasons as&lt;br /&gt;
***user has no privilege to the undo action: a student can't undo his/her submission after due date.&lt;br /&gt;
***some other user is editing the same item at the same time.&lt;/div&gt;</summary>
		<author><name>Kbyarbor</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2013/FINAL_PROJECT_E736_UNDO&amp;diff=74498</id>
		<title>CSC/ECE 517 Spring 2013/FINAL PROJECT E736 UNDO</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2013/FINAL_PROJECT_E736_UNDO&amp;diff=74498"/>
		<updated>2013-04-02T00:33:58Z</updated>

		<summary type="html">&lt;p&gt;Kbyarbor: /* Frameworks to Leverage */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= E736. Undo Functionality for Expertiza =&lt;br /&gt;
*Contacts: Ed Gehringer (efg@ncsu.edu) and Andrew Kofink (ajkofink@ncsu.edu)&lt;br /&gt;
*Begin implementing SQL transactions (ActiveRecord:Transactions).  This should let the user &amp;quot;roll back&amp;quot; any creation or update of a SQL table (assignments, rubrics, etc.)  Several issues arise, that you should discuss with me. &lt;br /&gt;
**Should students be able to roll back, e.g., submissions or reviews?&lt;br /&gt;
**Suppose an instructor is trying to roll back and a TA is editing the same assignment?  How can conflicts be presented?&lt;br /&gt;
**Do rollbacks affect only what's in the db, or do they also affect submitted files?&lt;br /&gt;
&lt;br /&gt;
== Team Members ==&lt;br /&gt;
*Chun Sing Tsui (ctsui@ncsu.edu)&lt;br /&gt;
*Kenny Yarboro (kbyarbor@ncsu.edu)&lt;br /&gt;
*Meng Cao (mcao2@ncsu.edu)&lt;br /&gt;
*Travis Folsom (twfolsom@ncsu.edu)&lt;br /&gt;
&lt;br /&gt;
== Design Document ==&lt;br /&gt;
&lt;br /&gt;
=== Overview of Undo Functionality ===&lt;br /&gt;
*Undo should cover any edit functionalities and any submissions of links.  File submissions do not need to be included for the scope of this project. &lt;br /&gt;
*User should be able to undo any changes to an item (such as course or assignment) as long as no other user has edited that same item within the user's current session.  &lt;br /&gt;
*If undo is attempted on an item already modified by another user, display a message stating why undo cannot be done.  &lt;br /&gt;
&lt;br /&gt;
=== List of Items to be Supported by Undo Functionality ===&lt;br /&gt;
*Assignments&lt;br /&gt;
*Courses&lt;br /&gt;
*More items may be covered if time allows.&lt;br /&gt;
&lt;br /&gt;
=== Design Patterns and Designs ===&lt;br /&gt;
*DRY&lt;br /&gt;
**&amp;quot;Don't Repeat Yourself&amp;quot; practice will be followed. &lt;br /&gt;
*Memento&lt;br /&gt;
**The Memento pattern will be followed through open-source Ruby gems leveraged by the project.&lt;br /&gt;
&lt;br /&gt;
=== Frameworks to Leverage ===&lt;br /&gt;
*Paper Trail(https://github.com/airblade/paper_trail)&lt;br /&gt;
**PaperTrail allows for tracking changes to model data. &lt;br /&gt;
***Good for auditing or versioning. &lt;br /&gt;
**Offers many functionalities including:&lt;br /&gt;
****Viewing a model at any stage in its lifecycle. &lt;br /&gt;
****Reverting a model to any version.&lt;br /&gt;
****Undeleting items after they have been destroyed.&lt;br /&gt;
**Compatible with Rails-2.3.15, which is the version Expertiza uses. &lt;br /&gt;
**There is a [http://railscasts.com/episodes/255-undo-with-paper-trail Railscast] showing how to implement the undo feature with Paper Trail. &lt;br /&gt;
**Ranked as the most popular framework for Active Record versioning feature in [https://www.ruby-toolbox.com/categories/Active_Record_Versioning here]&lt;br /&gt;
**Alternative Frameworks are listed [https://www.ruby-toolbox.com/categories/Active_Record_Versioning here].&lt;br /&gt;
&lt;br /&gt;
=== Expected Classes to be Modified ===&lt;br /&gt;
*Course&lt;br /&gt;
*Assignment&lt;br /&gt;
*etc&lt;br /&gt;
&lt;br /&gt;
=== Expected Unit Tests to Include ===&lt;br /&gt;
*at least one per method...&lt;br /&gt;
&lt;br /&gt;
=== Expected Functional Tests to Include ===&lt;br /&gt;
*Happy Path&lt;br /&gt;
**User successfully undoes his/her action on various models(Course, Assignment, etc).&lt;br /&gt;
*Sad path&lt;br /&gt;
**User is unable to undo, due to reasons as&lt;br /&gt;
***user has no privilege to the undo action: a student can't undo his/her submission after due date.&lt;br /&gt;
***some other user is editing the same item at the same time.&lt;/div&gt;</summary>
		<author><name>Kbyarbor</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2013/FINAL_PROJECT_E736_UNDO&amp;diff=74493</id>
		<title>CSC/ECE 517 Spring 2013/FINAL PROJECT E736 UNDO</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2013/FINAL_PROJECT_E736_UNDO&amp;diff=74493"/>
		<updated>2013-04-02T00:27:54Z</updated>

		<summary type="html">&lt;p&gt;Kbyarbor: /* Design Patterns and Designs */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= E736. Undo Functionality for Expertiza =&lt;br /&gt;
*Contacts: Ed Gehringer (efg@ncsu.edu) and Andrew Kofink (ajkofink@ncsu.edu)&lt;br /&gt;
*Begin implementing SQL transactions (ActiveRecord:Transactions).  This should let the user &amp;quot;roll back&amp;quot; any creation or update of a SQL table (assignments, rubrics, etc.)  Several issues arise, that you should discuss with me. &lt;br /&gt;
**Should students be able to roll back, e.g., submissions or reviews?&lt;br /&gt;
**Suppose an instructor is trying to roll back and a TA is editing the same assignment?  How can conflicts be presented?&lt;br /&gt;
**Do rollbacks affect only what's in the db, or do they also affect submitted files?&lt;br /&gt;
&lt;br /&gt;
== Team Members ==&lt;br /&gt;
*Chun Sing Tsui (ctsui@ncsu.edu)&lt;br /&gt;
*Kenny Yarboro (kbyarbor@ncsu.edu)&lt;br /&gt;
*Meng Cao (mcao2@ncsu.edu)&lt;br /&gt;
*Travis Folsom (twfolsom@ncsu.edu)&lt;br /&gt;
&lt;br /&gt;
== Design Document ==&lt;br /&gt;
&lt;br /&gt;
=== Overview of Undo Functionality ===&lt;br /&gt;
*Undo should cover any edit functionalities and any submissions of links.  File submissions do not need to be included for the scope of this project. &lt;br /&gt;
*User should be able to undo any changes to an item (such as course or assignment) as long as no other user has edited that same item within the user's current session.  &lt;br /&gt;
*If undo is attempted on an item already modified by another user, display a message stating why undo cannot be done.  &lt;br /&gt;
&lt;br /&gt;
=== List of Items to be Supported by Undo Functionality ===&lt;br /&gt;
*Assignments&lt;br /&gt;
*Courses&lt;br /&gt;
*More items may be covered if time allows.&lt;br /&gt;
&lt;br /&gt;
=== Design Patterns and Designs ===&lt;br /&gt;
*DRY&lt;br /&gt;
**&amp;quot;Don't Repeat Yourself&amp;quot; practice will be followed. &lt;br /&gt;
*Memento&lt;br /&gt;
**The Memento pattern will be followed through open-source Ruby gems leveraged by the project.&lt;br /&gt;
&lt;br /&gt;
=== Frameworks to Leverage ===&lt;br /&gt;
*Paper Trail(https://github.com/airblade/paper_trail)&lt;br /&gt;
**PaperTrail lets you track changes to your models' data. It's good for auditing or versioning. You can see how a model looked at any stage in its lifecycle, revert it to any version, and even undelete it after it's been destroyed.&lt;br /&gt;
**It is compatible with Rails-2.3.15, which is the version Expertiza used. &lt;br /&gt;
**There is a [http://railscasts.com/episodes/255-undo-with-paper-trail Railscast] shows how to implement undo feature with Paper Trail&lt;br /&gt;
**It is ranked as the most popular framework for Active Record versioning feature in [https://www.ruby-toolbox.com/categories/Active_Record_Versioning here]&lt;br /&gt;
*Alternative Frameworks are listed [https://www.ruby-toolbox.com/categories/Active_Record_Versioning here].&lt;br /&gt;
&lt;br /&gt;
=== Expected Classes to be Modified ===&lt;br /&gt;
*Course&lt;br /&gt;
*Assignment&lt;br /&gt;
*etc&lt;br /&gt;
&lt;br /&gt;
=== Expected Unit Tests to Include ===&lt;br /&gt;
*at least one per method...&lt;br /&gt;
&lt;br /&gt;
=== Expected Functional Tests to Include ===&lt;br /&gt;
*Happy Path&lt;br /&gt;
**User successfully undoes his/her action on various models(Course, Assignment, etc).&lt;br /&gt;
*Sad path&lt;br /&gt;
**User is unable to undo, due to reasons as&lt;br /&gt;
***user has no privilege to the undo action: a student can't undo his/her submission after due date.&lt;br /&gt;
***some other user is editing the same item at the same time.&lt;/div&gt;</summary>
		<author><name>Kbyarbor</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2013/FINAL_PROJECT_E736_UNDO&amp;diff=74492</id>
		<title>CSC/ECE 517 Spring 2013/FINAL PROJECT E736 UNDO</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2013/FINAL_PROJECT_E736_UNDO&amp;diff=74492"/>
		<updated>2013-04-02T00:26:55Z</updated>

		<summary type="html">&lt;p&gt;Kbyarbor: /* List of Items to be Supported by Undo Functionality */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= E736. Undo Functionality for Expertiza =&lt;br /&gt;
*Contacts: Ed Gehringer (efg@ncsu.edu) and Andrew Kofink (ajkofink@ncsu.edu)&lt;br /&gt;
*Begin implementing SQL transactions (ActiveRecord:Transactions).  This should let the user &amp;quot;roll back&amp;quot; any creation or update of a SQL table (assignments, rubrics, etc.)  Several issues arise, that you should discuss with me. &lt;br /&gt;
**Should students be able to roll back, e.g., submissions or reviews?&lt;br /&gt;
**Suppose an instructor is trying to roll back and a TA is editing the same assignment?  How can conflicts be presented?&lt;br /&gt;
**Do rollbacks affect only what's in the db, or do they also affect submitted files?&lt;br /&gt;
&lt;br /&gt;
== Team Members ==&lt;br /&gt;
*Chun Sing Tsui (ctsui@ncsu.edu)&lt;br /&gt;
*Kenny Yarboro (kbyarbor@ncsu.edu)&lt;br /&gt;
*Meng Cao (mcao2@ncsu.edu)&lt;br /&gt;
*Travis Folsom (twfolsom@ncsu.edu)&lt;br /&gt;
&lt;br /&gt;
== Design Document ==&lt;br /&gt;
&lt;br /&gt;
=== Overview of Undo Functionality ===&lt;br /&gt;
*Undo should cover any edit functionalities and any submissions of links.  File submissions do not need to be included for the scope of this project. &lt;br /&gt;
*User should be able to undo any changes to an item (such as course or assignment) as long as no other user has edited that same item within the user's current session.  &lt;br /&gt;
*If undo is attempted on an item already modified by another user, display a message stating why undo cannot be done.  &lt;br /&gt;
&lt;br /&gt;
=== List of Items to be Supported by Undo Functionality ===&lt;br /&gt;
*Assignments&lt;br /&gt;
*Courses&lt;br /&gt;
*More items may be covered if time allows.&lt;br /&gt;
&lt;br /&gt;
=== Design Patterns and Designs ===&lt;br /&gt;
*DRY&lt;br /&gt;
**don't repeat code...&lt;br /&gt;
*Memento&lt;br /&gt;
**reason one...&lt;br /&gt;
&lt;br /&gt;
=== Frameworks to Leverage ===&lt;br /&gt;
*Paper Trail(https://github.com/airblade/paper_trail)&lt;br /&gt;
**PaperTrail lets you track changes to your models' data. It's good for auditing or versioning. You can see how a model looked at any stage in its lifecycle, revert it to any version, and even undelete it after it's been destroyed.&lt;br /&gt;
**It is compatible with Rails-2.3.15, which is the version Expertiza used. &lt;br /&gt;
**There is a [http://railscasts.com/episodes/255-undo-with-paper-trail Railscast] shows how to implement undo feature with Paper Trail&lt;br /&gt;
**It is ranked as the most popular framework for Active Record versioning feature in [https://www.ruby-toolbox.com/categories/Active_Record_Versioning here]&lt;br /&gt;
*Alternative Frameworks are listed [https://www.ruby-toolbox.com/categories/Active_Record_Versioning here].&lt;br /&gt;
&lt;br /&gt;
=== Expected Classes to be Modified ===&lt;br /&gt;
*Course&lt;br /&gt;
*Assignment&lt;br /&gt;
*etc&lt;br /&gt;
&lt;br /&gt;
=== Expected Unit Tests to Include ===&lt;br /&gt;
*at least one per method...&lt;br /&gt;
&lt;br /&gt;
=== Expected Functional Tests to Include ===&lt;br /&gt;
*Happy Path&lt;br /&gt;
**User successfully undoes his/her action on various models(Course, Assignment, etc).&lt;br /&gt;
*Sad path&lt;br /&gt;
**User is unable to undo, due to reasons as&lt;br /&gt;
***user has no privilege to the undo action: a student can't undo his/her submission after due date.&lt;br /&gt;
***some other user is editing the same item at the same time.&lt;/div&gt;</summary>
		<author><name>Kbyarbor</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2013/OSS_E608&amp;diff=74416</id>
		<title>CSC/ECE 517 Spring 2013/OSS E608</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2013/OSS_E608&amp;diff=74416"/>
		<updated>2013-03-28T03:39:05Z</updated>

		<summary type="html">&lt;p&gt;Kbyarbor: /* E608. Refactoring and Testing - Course Related Classes */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[https://docs.google.com/a/ncsu.edu/document/d/1SVNx7Eh6dUdrz2a9rGSgBxLkxAmuBUm8eu08nHEdjIg/edit# Write-up of This Topic.]&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
= Expertiza Project =&lt;br /&gt;
Expertiza is a web-based class management system.  This page will discuss one of its related modification projects conducted in the CSC/ECE 517 Spring 2003 class at North Carolina State University.  Learn more about Expertiza by visiting its main page:  http://wikis.lib.ncsu.edu/index.php/Expertiza&lt;br /&gt;
&lt;br /&gt;
= E608. Refactoring and Testing - Course Related Classes =&lt;br /&gt;
Classes Involved:&lt;br /&gt;
*/app/models/course.rb (76 lines)&lt;br /&gt;
*/app/models/course_participant.rb (94 lines)&lt;br /&gt;
*/app/models/course_team.rb (116 lines)&lt;br /&gt;
*/app/models/course_node.rb (95 lines)&lt;br /&gt;
&lt;br /&gt;
What it does: &lt;br /&gt;
Involves creation and management of courses in Expertiza&lt;br /&gt;
&lt;br /&gt;
What needs to be done:&lt;br /&gt;
*It is not clear what a method named 'create_node' is doing in the 'course' class. Refactor by renaming this method appropriately.&lt;br /&gt;
*In the course_team class the import method seems to be doing too many things. See if this method can be broken down into smaller methods with specific functionality.&lt;br /&gt;
*The 'get' method in course_node.rb appears to be doing a lot. Refactor this method by breaking it up into smaller methods.&lt;br /&gt;
*Look for any unused methods or variables in these files.&lt;br /&gt;
*Also apply other refactorings such as Rename variable, Rename method to give the variables and methods more meaningful names.&lt;br /&gt;
*Write unit tests for all the methods in each of the listed model classes.&lt;br /&gt;
&lt;br /&gt;
== Changes for /app/models/course.rb ==&lt;br /&gt;
The following changes were made:&lt;br /&gt;
* Since the method create_node simply creates a course node associated with the newly created or copied course, we replaced its functionality by adding the line CourseNode.create(:node_object_id =&amp;gt; course.id) in the course_controller's create method and copy method. The function of getting the CourseNode's parent id is extracted as a class method of CourseNode model since this parent id is independent of the course. With all of its functionalities refactored to other places, this method is hereby removed. &lt;br /&gt;
* Added the line &amp;quot;has_many :assigments, :dependent =&amp;gt; :destroy&amp;quot; to allow CourseTest.test_destroy unit test to pass.&lt;br /&gt;
&lt;br /&gt;
== Changes for /app/models/course_participant.rb ==&lt;br /&gt;
* CourseParticipant.get_parent_name is removed&lt;br /&gt;
** This method is never called in the project.  Additionally, the method CourseParticipant.get_course_string provides the same functionality as CourseParticipant.get_parent_name, so it was deleted to follow the principle of DRY.&lt;br /&gt;
&lt;br /&gt;
== Changes for /app/models/course_team.rb ==&lt;br /&gt;
&lt;br /&gt;
=== ''import'' Method ===&lt;br /&gt;
Functionality: Import a single course team for a course from an input array. The first element in the array is optionally used to specify a name for the team that is being imported.&lt;br /&gt;
&lt;br /&gt;
Usage: The method is used by the import file controller to import course teams to a course.   &lt;br /&gt;
&lt;br /&gt;
==== Decomposition ====&lt;br /&gt;
The import method can be decomposed into 5 separate parts: &lt;br /&gt;
&lt;br /&gt;
===== Part 1 – Preparation =====&lt;br /&gt;
&lt;br /&gt;
Functionality: Ensure that the array has enough elements and that the class in which the user wants to import the team exists.  &lt;br /&gt;
&lt;br /&gt;
 if row.length &amp;lt; 2&lt;br /&gt;
     raise ArgumentError, &amp;quot;Not enough items&amp;quot; &lt;br /&gt;
 end &lt;br /&gt;
 course = Course.find(id)&lt;br /&gt;
 if course == nil&lt;br /&gt;
     raise ImportError, &amp;quot;The course with id \&amp;quot;&amp;quot;+id.to_s+&amp;quot;\&amp;quot; was not found. &amp;lt;a href='/assignment/new'&amp;gt;Create&amp;lt;/a&amp;gt; this assignment?&amp;quot;&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
===== Part 2 – Naming the New Team =====&lt;br /&gt;
&lt;br /&gt;
Functionality: The method will either import the team name from the array if has_column_name is set to true or generate a new team name if has_column_name is set to false.&lt;br /&gt;
&lt;br /&gt;
 if options[:has_column_names] == &amp;quot;true&amp;quot;&lt;br /&gt;
     name = row[0].to_s.strip&lt;br /&gt;
     index = 1&lt;br /&gt;
 else&lt;br /&gt;
     name = generate_team_name()&lt;br /&gt;
     index = 0&lt;br /&gt;
 end &lt;br /&gt;
&lt;br /&gt;
===== Part 3 – Handling Duplicate Team =====&lt;br /&gt;
&lt;br /&gt;
Functionality: If a team with the same team name exists, this part of the method will handle the conflict based on the option handle_duplicate.&lt;br /&gt;
&lt;br /&gt;
 currTeam = CourseTeam.find(:first, :conditions =&amp;gt; [&amp;quot;name =? and parent_id =?&amp;quot;,name,course.id])  &lt;br /&gt;
 if options[:handle_dups] == &amp;quot;ignore&amp;quot; &amp;amp;&amp;amp; currTeam != nil&lt;br /&gt;
     return&lt;br /&gt;
 end  &lt;br /&gt;
 if currTeam != nil &amp;amp;&amp;amp; options[:handle_dups] == &amp;quot;rename&amp;quot;&lt;br /&gt;
     name = generate_team_name()&lt;br /&gt;
     currTeam = nil&lt;br /&gt;
 end&lt;br /&gt;
 if options[:handle_dups] == &amp;quot;replace&amp;quot; &amp;amp;&amp;amp; teams.first != nil        &lt;br /&gt;
 for teamsuser in TeamsUser.find(:all, :conditions =&amp;gt; [&amp;quot;team_id =?&amp;quot;, currTeam.id])&lt;br /&gt;
     teamsuser.destroy&lt;br /&gt;
     end    &lt;br /&gt;
     currTeam.destroy&lt;br /&gt;
     currTeam = nil&lt;br /&gt;
 end     &lt;br /&gt;
    &lt;br /&gt;
===== Part 4 – Create the New Team and Node =====&lt;br /&gt;
&lt;br /&gt;
Functionality: Creates a new team and team node base on the information gathered by the above parts.&lt;br /&gt;
&lt;br /&gt;
 if currTeam == nil&lt;br /&gt;
     currTeam = CourseTeam.new&lt;br /&gt;
     currTeam.name = name&lt;br /&gt;
     currTeam.parent_id = course.id&lt;br /&gt;
     currTeam.save&lt;br /&gt;
     parent = CourseNode.find_by_node_object_id(course.id)&lt;br /&gt;
     TeamNode.create(:parent_id =&amp;gt; parent.id, :node_object_id =&amp;gt; currTeam.id)&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
===== Part 5 – Import the Participants to the New Team =====&lt;br /&gt;
&lt;br /&gt;
Functionality: Verify that the users specified in the array exist, then add the users to the newly created team.&lt;br /&gt;
&lt;br /&gt;
 while(index &amp;lt; row.length) &lt;br /&gt;
     user = User.find_by_name(row[index].to_s.strip)&lt;br /&gt;
     if user == nil&lt;br /&gt;
         raise ImportError, &amp;quot;The user \&amp;quot;&amp;quot;+row[index].to_s.strip+&amp;quot;\&amp;quot; was not found. &amp;lt;a href='/users/new'&amp;gt;Create&amp;lt;/a&amp;gt; this user?&amp;quot;                           &lt;br /&gt;
     elsif currTeam != nil         &lt;br /&gt;
         currUser = TeamsUser.find(:first, :conditions =&amp;gt; [&amp;quot;team_id =? and user_id =?&amp;quot;, currTeam.id,user.id])          &lt;br /&gt;
         if currUser == nil&lt;br /&gt;
             currTeam.add_member(user)            &lt;br /&gt;
         end                      &lt;br /&gt;
     end&lt;br /&gt;
     index = index+1      &lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
==== Refactor ====&lt;br /&gt;
From the decomposition, Part 5 can be seen as needing to be separated into its own method. &lt;br /&gt;
&lt;br /&gt;
  def import_participants(starting_index, row)&lt;br /&gt;
    index = starting_index&lt;br /&gt;
    while(index &amp;lt; row.length)&lt;br /&gt;
      user = User.find_by_name(row[index].to_s.strip)&lt;br /&gt;
      if user.nil?&lt;br /&gt;
        raise ImportError, &amp;quot;The user \&amp;quot;&amp;quot;+row[index].to_s.strip+&amp;quot;\&amp;quot; was not found. &amp;lt;a href='/users/new'&amp;gt;Create&amp;lt;/a&amp;gt; this user?&amp;quot;&lt;br /&gt;
      else&lt;br /&gt;
        if TeamsUser.find(:first, :conditions =&amp;gt; [&amp;quot;team_id =? and user_id =?&amp;quot;, id, user.id]).nil?&lt;br /&gt;
          add_member(user)&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
      index = index + 1&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
From the decomposition, the logic of Part 2 and Part 3 show that they could be simplified. Originally, Part 4 was executed regardless of if the team name was generated or imported. However, if the team name is generated instead of imported, there will not be another team with the same name. Therefore, we extracted Part 4 into its own method and modified the logic of Part 3.&lt;br /&gt;
&lt;br /&gt;
  def self.handle_duplicate(name, course_id, handle_dups)&lt;br /&gt;
    team = find(:first, :conditions =&amp;gt; [&amp;quot;name =? and parent_id =?&amp;quot;, name, course_id])&lt;br /&gt;
    if team.nil? #no duplicate&lt;br /&gt;
      return name&lt;br /&gt;
    end&lt;br /&gt;
    if handle_dups == &amp;quot;ignore&amp;quot; #ignore: not create the new team&lt;br /&gt;
      return nil&lt;br /&gt;
    end&lt;br /&gt;
    if handle_dups == &amp;quot;rename&amp;quot; #rename: rename new team&lt;br /&gt;
      return generate_team_name&lt;br /&gt;
    end&lt;br /&gt;
    if handle_dups == &amp;quot;replace&amp;quot; #replace: delete old team&lt;br /&gt;
      team.delete&lt;br /&gt;
      return name&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
After the modifications to Part 3 and Part 4 are completed, the import method becomes:&lt;br /&gt;
 &lt;br /&gt;
    if options[:has_column_names] == &amp;quot;true&amp;quot;&lt;br /&gt;
      name = row[0].to_s.strip&lt;br /&gt;
      name = handle_duplicate(name, course_id, options[:handle_dups])&lt;br /&gt;
      index = 1&lt;br /&gt;
    else&lt;br /&gt;
      name = generate_team_name&lt;br /&gt;
      index = 0&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
==== Miscellaneous Changes ====&lt;br /&gt;
The condition in Part 1 is incorrect because the number of elements could be less than 2 if the array does not have a team name column.&lt;br /&gt;
&lt;br /&gt;
 if (row.length &amp;lt; 2 and options[:has_column_names] == &amp;quot;true&amp;quot;) or (row.length &amp;lt; 1 and options[:has_column_names] != &amp;quot;true&amp;quot;)&lt;br /&gt;
   raise ArgumentError, &amp;quot;Not enough items&amp;quot;&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
Part 4 of the method was simplified to improve the readability.&lt;br /&gt;
&lt;br /&gt;
 team = CourseTeam.create(:name =&amp;gt; name, :parent_id =&amp;gt; course_id)&lt;br /&gt;
 course_node = CourseNode.find_by_node_object_id(course_id)&lt;br /&gt;
 TeamNode.create(:parent_id =&amp;gt; course_node.id, :node_object_id =&amp;gt; team.id)&lt;br /&gt;
&lt;br /&gt;
==== Other Issues ====&lt;br /&gt;
The input variable session was unused in the method; therefore, it needed to be removed.  However, this change was not made in this project due to the way that the method is being called in the import file controller.&lt;br /&gt;
&lt;br /&gt;
=== ''export'' Method ===&lt;br /&gt;
==== Functionality Bug ====&lt;br /&gt;
Originally, the export method in the CourseTeam class exported the assignment teams that were associated with the course to which a course team belonged.  This is not the behavior that one would expect from the export method in the CourseTeam class. &lt;br /&gt;
&lt;br /&gt;
Upon examining the AssignmentTeam class, the export method for CourseTeam was determined to export all of the course teams associated with a course. &lt;br /&gt;
&lt;br /&gt;
 def self.export(csv, parent_id, options)&lt;br /&gt;
    currentCourse = Course.find(parent_id)&lt;br /&gt;
    currentCourse.teams.each { |team|&lt;br /&gt;
      tcsv = Array.new&lt;br /&gt;
      teamUsers = Array.new&lt;br /&gt;
      tcsv.push(team.name)&lt;br /&gt;
      if (options[&amp;quot;team_name&amp;quot;] == &amp;quot;false&amp;quot;)&lt;br /&gt;
        teamMembers = TeamsUser.find(:all, :conditions =&amp;gt; ['team_id = ?', team.id])&lt;br /&gt;
        teamMembers.each do |user|&lt;br /&gt;
          teamUsers.push(user.name)&lt;br /&gt;
          teamUsers.push(&amp;quot; &amp;quot;)&lt;br /&gt;
        end&lt;br /&gt;
        tcsv.push(teamUsers)&lt;br /&gt;
      end&lt;br /&gt;
      tcsv.push(currentCourse.name)&lt;br /&gt;
      csv &amp;lt;&amp;lt; tcsv&lt;br /&gt;
    }&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
Note that this is a direct port of code from the source of the export function in the AssignmentTeam class.&lt;br /&gt;
&lt;br /&gt;
The original export function was renamed to export_all_assignment_team_related_to_course to reflect its actual functionality.  The function was marked deprecated and if the functionality is later found to be needed, the function should be re-written and moved to the Course class. &lt;br /&gt;
&lt;br /&gt;
==== Analysis and Refactor ====&lt;br /&gt;
The part of the export method within the if block is used to export all of the participants of a team.  This part can be separated into its own method to reduce the complexity of the export method. &lt;br /&gt;
&lt;br /&gt;
  def export_participants&lt;br /&gt;
    userNames = Array.new&lt;br /&gt;
    participants = TeamsUser.find(:all, :conditions =&amp;gt; ['team_id = ?', self.id])&lt;br /&gt;
    participants.each do |participant|&lt;br /&gt;
      userNames.push(participant.name)&lt;br /&gt;
      userNames.push(&amp;quot; &amp;quot;)&lt;br /&gt;
    end&lt;br /&gt;
    return userNames&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
Furthermore, an instance method was added to the CourseTeam class to export the team.  The class method export can call the instance method to reduce the complexity and improve the readability.&lt;br /&gt;
&lt;br /&gt;
  def export(team_name_only)&lt;br /&gt;
    output = Array.new&lt;br /&gt;
    output.push(self.name)&lt;br /&gt;
    if team_name_only == &amp;quot;false&amp;quot;&lt;br /&gt;
      output.push(self.export_participants)&lt;br /&gt;
    end&lt;br /&gt;
    course = Course.find(self.parent_id)&lt;br /&gt;
    output.push(course.name)&lt;br /&gt;
    return output&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
The export function as it looked after refactoring:&lt;br /&gt;
&lt;br /&gt;
  def self.export(csv, parent_id, options)&lt;br /&gt;
    course = Course.find(parent_id)&lt;br /&gt;
    if course.nil?&lt;br /&gt;
      raise ImportError, &amp;quot;The course with id \&amp;quot;&amp;quot;+course_id.to_s+&amp;quot;\&amp;quot; was not found. &amp;lt;a href='/assignment/new'&amp;gt;Create&amp;lt;/a&amp;gt; this course?&amp;quot;&lt;br /&gt;
    end&lt;br /&gt;
    teams = CourseTeam.find_all_by_parent_id(parent_id)&lt;br /&gt;
    teams.each do |team|&lt;br /&gt;
      csv &amp;lt;&amp;lt; team.export(options[:team_name])&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
==== Other Issues ====&lt;br /&gt;
The method name export does not accurately describe the functionality of this method.  It is recommended that this method name be changed to export_all. This change was not made due to the export method in the AssignmentTeam class and the way that the method is being called by the export file controller.&lt;br /&gt;
&lt;br /&gt;
The meaning of the option team_name in the method is ambiguous. Upon further examination, it was discovered that the option team_name controls if the method should only export team names without exporting the name of the participants in the team. This option should be renamed to team_name_only for better clarity.&lt;br /&gt;
&lt;br /&gt;
=== ''get_export_fields'' Method ===&lt;br /&gt;
Inferring from the code, the get_export_field method seems to return an array that contains the options used for controlling the export method.&lt;br /&gt;
&lt;br /&gt;
As discussed earlier, the team_name option for expert method controls if the export should contain the name of the team participants.&lt;br /&gt;
&lt;br /&gt;
Originally, the get_export_fields method will include the string “team member” if the option team_name is true. &lt;br /&gt;
&lt;br /&gt;
Furthermore, the get_export_fields method is trying to get the value of string(“team_name”) in hash variable options instead of symbol(:team_name).&lt;br /&gt;
&lt;br /&gt;
Here is the method after making the noted changes:&lt;br /&gt;
&lt;br /&gt;
  def self.get_export_fields(options)&lt;br /&gt;
    fields = Array.new&lt;br /&gt;
    fields.push(&amp;quot;Team Name&amp;quot;)&lt;br /&gt;
    if (options[:team_name] == &amp;quot;false&amp;quot;)&lt;br /&gt;
      fields.push(&amp;quot;Team members&amp;quot;)&lt;br /&gt;
    end&lt;br /&gt;
    fields.push(&amp;quot;Course Name&amp;quot;)&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
=== ''copy'' Method === &lt;br /&gt;
This method is inferred to be used to create a new assignment team and copy all of the participants of the course team to that new assignment team.&lt;br /&gt;
&lt;br /&gt;
If this is later confirmed to be the intended functionality of this method, then this method should belong to AssignmentTeam class instead of CourseTeam class.&lt;br /&gt;
&lt;br /&gt;
This method calls the create_node_object method in Team class, which does not work (explained in a later section) and has an ambiguous return type, functionality, and name.&lt;br /&gt;
&lt;br /&gt;
Logically, the copy method should create a new course team and copy the participants of a team into the new course team.&lt;br /&gt;
Currently, this is dead code and not used in the program.  &lt;br /&gt;
&lt;br /&gt;
This function was marked deprecated and it is recommended to be removed from the program.&lt;br /&gt;
&lt;br /&gt;
=== ''add_participant'' Method === &lt;br /&gt;
This method is used to add a participant to the course that the course team to which it belongs.&lt;br /&gt;
&lt;br /&gt;
This method is called by the add_member method in the Team class to add a participant to the course when a member is added to a course team.&lt;br /&gt;
&lt;br /&gt;
This method does belong in the Course class and not the CourseTeam class.  The Course class already has the method add_participant with similar functionality.&lt;br /&gt;
&lt;br /&gt;
This function was marked deprecated and it is recommended that the function should be removed from the program and the add_member method in the Team class should call the add_participant method from Course class.&lt;br /&gt;
&lt;br /&gt;
== Changes for /app/models/course_node.rb ==&lt;br /&gt;
* models/course_node.rb &lt;br /&gt;
** The &amp;quot;get&amp;quot; method was improved. &lt;br /&gt;
*** Added &amp;quot;get_courses_managed_by_user&amp;quot; method to hold logic extracted from the &amp;quot;get&amp;quot;method.  &lt;br /&gt;
*** Added &amp;quot;get_course_query_conditions&amp;quot; method to hold logic extracted from the &amp;quot;get&amp;quot; method.  &lt;br /&gt;
*** Modified any checks on if the user is a teaching assistant to use polymorphism to make the determination.  &lt;br /&gt;
*** Removed the initial conditional for setting the &amp;quot;conditions&amp;quot; value since the remaining conditions was overwriting the value regardless of how the initial conditional was evaluated. &lt;br /&gt;
*** Renaming the &amp;quot;get&amp;quot; method was considered; however, the name of the method is necessary for polymorphism reasons related to Assignment nodes.  As such, a comment was added to explain why the method name should remain.     &lt;br /&gt;
*** The &amp;quot;sortorder&amp;quot; parameter is given a default value of &amp;quot;ASC&amp;quot; for ascending.  This allowed for a related conditional to be removed from the method.  &lt;br /&gt;
*** The &amp;quot;sortvar&amp;quot; parameter is given a default value of &amp;quot;name&amp;quot; for sorting by course name.  This allowed for a related conditional to be removed from the method.&lt;br /&gt;
** Renaming the &amp;quot;get_children&amp;quot; method was considered; however, the name of the method is necessary for polymorphism reasons related to Assignment Nodes.  As such, a comment was added to explain why the method name should remain. &lt;br /&gt;
** The &amp;quot;get_survey_distribution_id&amp;quot; method was removed after finding it to be dead code.&lt;br /&gt;
* models/ta.rb&lt;br /&gt;
** Added &amp;quot;is_teaching_assistant?&amp;quot; method to override the inherited method from the User model.  This supported usage of polymorphism to determine if the user is a teaching assistant.  &lt;br /&gt;
* models/user.rb&lt;br /&gt;
** Added &amp;quot;is_teaching_assistant?&amp;quot; method to enable usage of polymorphism to determine if the user is a teaching assistant.&lt;br /&gt;
&lt;br /&gt;
== Methods Found That Are Not Currently Being Used ==&lt;br /&gt;
The following methods were not found to be used currently by the project, but have been left in the code for potential future usages of the functionality:&lt;br /&gt;
* /app/models/course.rb&lt;br /&gt;
** Course.get_participant(user_id)&lt;br /&gt;
* /app/models/course_participant.rb&lt;br /&gt;
** CourseParticipant.copy(assignment_id)&lt;br /&gt;
** CourseParticipant.get_parent_name&lt;br /&gt;
* /app/models/course_node.rb&lt;br /&gt;
** CourseNode.get_modified_date&lt;br /&gt;
&lt;br /&gt;
== Other Observations and Suggestion for Future Work == &lt;br /&gt;
=== Redundant Code in Team Related Classes ===&lt;br /&gt;
Classes: Team, CourseTeam, AssignmentTeam&lt;br /&gt;
&lt;br /&gt;
Files: team.rb, course_team.rb, assignment_team.rb&lt;br /&gt;
&lt;br /&gt;
The class CourseTeam and AssignmentTeam both inherit from the class Team. However, there are a lot of duplicated functionalities.  In order to adhere to the &amp;quot;DRY&amp;quot; principle, the refactoring mentioned earlier for the CourseTeam should be applied to AssignmentTeam and duplicated methods should be extracted to the super-class Team.&lt;br /&gt;
&lt;br /&gt;
=== Naming Inconsistency in Team Related Classes ===&lt;br /&gt;
Classes: Team, CourseTeam, AssignmentTeam&lt;br /&gt;
&lt;br /&gt;
Files: team.rb, course_team.rb, assignment_team.rb&lt;br /&gt;
&lt;br /&gt;
Participants in a team have many different names in these three classes. For example: member, user, participants. Common vocabulary should be established in order to eliminate confusion. &lt;br /&gt;
&lt;br /&gt;
=== Bugs in Team Class ===&lt;br /&gt;
Class: Team&lt;br /&gt;
&lt;br /&gt;
File: team.rb&lt;br /&gt;
&lt;br /&gt;
Method: create_node_object&lt;br /&gt;
&lt;br /&gt;
The create_node_object method in Team class does not work because the class method get_parent_model in both CourseTeam and Assignment team is an instance method and not a class method.&lt;br /&gt;
&lt;br /&gt;
Based on the code of the object and the usage of this code, the method is supposed to create a new course or assignment team along with a new team node and then return the newly created team as output.  This function should be deprecated and removed from the class.  The functionality should be moved to the new method in the team controller if the functionality is found to be necessary.&lt;br /&gt;
&lt;br /&gt;
=== Inelegance Code in Team Class ===&lt;br /&gt;
Class: Team&lt;br /&gt;
&lt;br /&gt;
File: team.rb&lt;br /&gt;
&lt;br /&gt;
Methods: randomize_all_by_parent, check_for_existing, create_node_object, copy_members&lt;br /&gt;
&lt;br /&gt;
These methods uses Object.const_get() with an input string that dynamically locates the object that is associated with different team types (assignment or course); however, the uses of Object.const_get() are inconsistent throughout these methods.&lt;br /&gt;
&lt;br /&gt;
It is recommended that instead of using query methods, such as get_participant_type and get_parent_model, in the assignment and course team to return a string containing the name of the object, these methods should be used to return the object itself.  This will eliminate the need for Object.const_get().&lt;br /&gt;
&lt;br /&gt;
== List of New Unit Tests and Testcases ==&lt;br /&gt;
The following lists shows new unit files and/or new testcases:&lt;br /&gt;
* test/unit/course_node_test.rb (new test file)&lt;br /&gt;
** test_get_children_with_show_true_and_non_TA_and_ascending_order_by_name&lt;br /&gt;
** test_get_children_with_show_true_and_non_TA_and_descending_order_by_name&lt;br /&gt;
** test_get_children_with_show_true_and_TA_and_ascending_order_by_name&lt;br /&gt;
** test_get_children_with_show_true_and_TA_and_descending_order_by_name&lt;br /&gt;
** test_get_children_with_show_false_and_non_TA_and_ascending_order_by_name&lt;br /&gt;
** test_get_children_with_show_false_and_non_TA_and_descending_order_by_name&lt;br /&gt;
** test_get_children_with_show_false_and_TA_and_ascending_order_by_name&lt;br /&gt;
** test_get_children_with_show_false_and_TA_and_descending_order_by_name&lt;br /&gt;
** test_get_children_with_show_false_and_non_TA_and_nil_order_by_nil&lt;br /&gt;
** test_get_name&lt;br /&gt;
** test_get_directory&lt;br /&gt;
** test_get_creation_date&lt;br /&gt;
** test_get_modified_date&lt;br /&gt;
** test_get_teams&lt;br /&gt;
** test_get_parent_id&lt;br /&gt;
* test/unit/course_test.rb (previously existing test file)&lt;br /&gt;
** test_get_teams&lt;br /&gt;
** test_get_path&lt;br /&gt;
** test_get_participants&lt;br /&gt;
** test_get_participant&lt;br /&gt;
** test_add_participant&lt;br /&gt;
** test_copy_participants&lt;br /&gt;
* test/unit/course_participant_test.rb (previously existing test file)&lt;br /&gt;
** test_get_course_string&lt;br /&gt;
** test_import&lt;br /&gt;
** test_get_path&lt;br /&gt;
** test_export&lt;br /&gt;
** test_get_export_field&lt;br /&gt;
* test/unit/course_team_test.rb (new test file)&lt;br /&gt;
** test_retrieval&lt;br /&gt;
** test_import_participants&lt;br /&gt;
** test_export_participants&lt;br /&gt;
** test_instance_export&lt;br /&gt;
** test_handle_duplicate&lt;br /&gt;
** test_import&lt;br /&gt;
** test_class_export&lt;br /&gt;
&lt;br /&gt;
== List of Modified Unit Tests ==&lt;br /&gt;
The following unit test files and/or testcases were modified:&lt;br /&gt;
* test/unit/course_test.rb&lt;br /&gt;
** The line &amp;quot;fixtures :courses&amp;quot; was changed to &amp;quot;fixtures :courses,:teams,:users,:participants,:assignments,:nodes,:tree_folders&amp;quot;.&lt;/div&gt;</summary>
		<author><name>Kbyarbor</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2013/FINAL_PROJECT_E736_UNDO&amp;diff=74403</id>
		<title>CSC/ECE 517 Spring 2013/FINAL PROJECT E736 UNDO</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2013/FINAL_PROJECT_E736_UNDO&amp;diff=74403"/>
		<updated>2013-03-27T03:56:32Z</updated>

		<summary type="html">&lt;p&gt;Kbyarbor: Created page with &amp;quot;= E736. Undo Functionality for Expertiza = *Contacts: Ed Gehringer (efg@ncsu.edu) and Andrew Kofink (ajkofink@ncsu.edu) *Begin implementing SQL transactions (ActiveRecord:Transac...&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= E736. Undo Functionality for Expertiza =&lt;br /&gt;
*Contacts: Ed Gehringer (efg@ncsu.edu) and Andrew Kofink (ajkofink@ncsu.edu)&lt;br /&gt;
*Begin implementing SQL transactions (ActiveRecord:Transactions).  This should let the user &amp;quot;roll back&amp;quot; any creation or update of a SQL table (assignments, rubrics, etc.)  Several issues arise, that you should discuss with me. &lt;br /&gt;
**Should students be able to roll back, e.g., submissions or reviews?&lt;br /&gt;
**Suppose an instructor is trying to roll back and a TA is editing the same assignment?  How can conflicts be presented?&lt;br /&gt;
**Do rollbacks affect only what's in the db, or do they also affect submitted files?&lt;br /&gt;
&lt;br /&gt;
== Team Members ==&lt;br /&gt;
*Chun Sing Tsui (ctsui@ncsu.edu)&lt;br /&gt;
*Kenny Yarboro (kbyarbor@ncsu.edu)&lt;br /&gt;
*Meng Cao (mcao2Wncsu.edu)&lt;br /&gt;
*Travis Folsom (twfolsom@ncsu.edu)&lt;br /&gt;
&lt;br /&gt;
== Design Document ==&lt;br /&gt;
&lt;br /&gt;
=== Overview of Undo Functionality ===&lt;br /&gt;
*Undo should cover any edit functionalities and any submissions of links.  File submissions do not need to be included for the scope of this project. &lt;br /&gt;
*User should be able to undo any changes to an item (such as course or assignment) as long as no other user has edited that same item within the user's current session.  &lt;br /&gt;
*If undo is attempted on an item already modified by another user, display a message stating why undo cannot be done.  &lt;br /&gt;
&lt;br /&gt;
=== List of Items to be Supported by Undo Functionality ===&lt;br /&gt;
*Assignments&lt;br /&gt;
*Courses&lt;br /&gt;
*etc...&lt;br /&gt;
&lt;br /&gt;
=== Design Patterns and Designs ===&lt;br /&gt;
*DRY&lt;br /&gt;
**don't repeat code...&lt;br /&gt;
*Memento&lt;br /&gt;
**reason one...&lt;br /&gt;
&lt;br /&gt;
=== Frameworks to Leverage ===&lt;br /&gt;
*list pre-existing frameworks that we will use&lt;br /&gt;
**reason to use...&lt;br /&gt;
&lt;br /&gt;
=== Expected Classes to be Modified ===&lt;br /&gt;
*class one...&lt;br /&gt;
&lt;br /&gt;
=== Expected Unit Tests to Include ===&lt;br /&gt;
*at least one per method...&lt;br /&gt;
&lt;br /&gt;
=== Expected Functional Tests to Include ===&lt;br /&gt;
*cover happy path...&lt;br /&gt;
*cover sad path...&lt;/div&gt;</summary>
		<author><name>Kbyarbor</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2013/OSS_E608&amp;diff=74297</id>
		<title>CSC/ECE 517 Spring 2013/OSS E608</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2013/OSS_E608&amp;diff=74297"/>
		<updated>2013-03-21T03:14:32Z</updated>

		<summary type="html">&lt;p&gt;Kbyarbor: /* Other Observations and Suggestion for Future Work */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[https://docs.google.com/a/ncsu.edu/document/d/1SVNx7Eh6dUdrz2a9rGSgBxLkxAmuBUm8eu08nHEdjIg/edit# Write-up of This Topic.]&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
= E608. Refactoring and Testing - Course Related Classes =&lt;br /&gt;
Classes Involved:&lt;br /&gt;
*/app/models/course.rb (76 lines)&lt;br /&gt;
*/app/models/course_participant.rb (94 lines)&lt;br /&gt;
*/app/models/course_team.rb (116 lines)&lt;br /&gt;
*/app/models/course_node.rb (95 lines)&lt;br /&gt;
&lt;br /&gt;
What it does: &lt;br /&gt;
Involves creation and management of courses in Expertiza&lt;br /&gt;
&lt;br /&gt;
What needs to be done:&lt;br /&gt;
*It is not clear what a method named 'create_node' is doing in the 'course' class. Refactor by renaming this method appropriately.&lt;br /&gt;
*In the course_team class the import method seems to be doing too many things. See if this method can be broken down into smaller methods with specific functionality.&lt;br /&gt;
*The 'get' method in course_node.rb appears to be doing a lot. Refactor this method by breaking it up into smaller methods.&lt;br /&gt;
*Look for any unused methods or variables in these files.&lt;br /&gt;
*Also apply other refactorings such as Rename variable, Rename method to give the variables and methods more meaningful names.&lt;br /&gt;
*Write unit tests for all the methods in each of the listed model classes.&lt;br /&gt;
&lt;br /&gt;
== Changes for /app/models/course.rb ==&lt;br /&gt;
The following changes were made:&lt;br /&gt;
* Since the method create_node simply creates a course node associated with the newly created or copied course, we replaced its functionality by adding the line CourseNode.create(:node_object_id =&amp;gt; course.id) in the course_controller's create method and copy method. The function of getting the CourseNode's parent id is extracted as a class method of CourseNode model since this parent id is independent of the course. With all of its functionalities refactored to other places, this method is hereby removed. &lt;br /&gt;
* Added the line &amp;quot;has_many :assigments, :dependent =&amp;gt; :destroy&amp;quot; to allow CourseTest.test_destroy unit test to pass.&lt;br /&gt;
&lt;br /&gt;
== Changes for /app/models/course_participant.rb ==&lt;br /&gt;
* CourseParticipant.get_parent_name is removed&lt;br /&gt;
** This method is never called in the project.  Additionally, the method CourseParticipant.get_course_string provides the same functionality as CourseParticipant.get_parent_name, so it was deleted to follow the principle of DRY.&lt;br /&gt;
&lt;br /&gt;
== Changes for /app/models/course_team.rb ==&lt;br /&gt;
&lt;br /&gt;
=== ''import'' Method ===&lt;br /&gt;
Functionality: Import a single course team for a course from an input array. The first element in the array is optionally used to specify a name for the team that is being imported.&lt;br /&gt;
&lt;br /&gt;
Usage: The method is used by the import file controller to import course teams to a course.   &lt;br /&gt;
&lt;br /&gt;
==== Decomposition ====&lt;br /&gt;
The import method can be decomposed into 5 separate parts: &lt;br /&gt;
&lt;br /&gt;
===== Part 1 – Preparation =====&lt;br /&gt;
&lt;br /&gt;
Functionality: Ensure that the array has enough elements and that the class in which the user wants to import the team exists.  &lt;br /&gt;
&lt;br /&gt;
 if row.length &amp;lt; 2&lt;br /&gt;
     raise ArgumentError, &amp;quot;Not enough items&amp;quot; &lt;br /&gt;
 end &lt;br /&gt;
 course = Course.find(id)&lt;br /&gt;
 if course == nil&lt;br /&gt;
     raise ImportError, &amp;quot;The course with id \&amp;quot;&amp;quot;+id.to_s+&amp;quot;\&amp;quot; was not found. &amp;lt;a href='/assignment/new'&amp;gt;Create&amp;lt;/a&amp;gt; this assignment?&amp;quot;&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
===== Part 2 – Naming the New Team =====&lt;br /&gt;
&lt;br /&gt;
Functionality: The method will either import the team name from the array if has_column_name is set to true or generate a new team name if has_column_name is set to false.&lt;br /&gt;
&lt;br /&gt;
 if options[:has_column_names] == &amp;quot;true&amp;quot;&lt;br /&gt;
     name = row[0].to_s.strip&lt;br /&gt;
     index = 1&lt;br /&gt;
 else&lt;br /&gt;
     name = generate_team_name()&lt;br /&gt;
     index = 0&lt;br /&gt;
 end &lt;br /&gt;
&lt;br /&gt;
===== Part 3 – Handling Duplicate Team =====&lt;br /&gt;
&lt;br /&gt;
Functionality: If a team with the same team name exists, this part of the method will handle the conflict based on the option handle_duplicate.&lt;br /&gt;
&lt;br /&gt;
 currTeam = CourseTeam.find(:first, :conditions =&amp;gt; [&amp;quot;name =? and parent_id =?&amp;quot;,name,course.id])  &lt;br /&gt;
 if options[:handle_dups] == &amp;quot;ignore&amp;quot; &amp;amp;&amp;amp; currTeam != nil&lt;br /&gt;
     return&lt;br /&gt;
 end  &lt;br /&gt;
 if currTeam != nil &amp;amp;&amp;amp; options[:handle_dups] == &amp;quot;rename&amp;quot;&lt;br /&gt;
     name = generate_team_name()&lt;br /&gt;
     currTeam = nil&lt;br /&gt;
 end&lt;br /&gt;
 if options[:handle_dups] == &amp;quot;replace&amp;quot; &amp;amp;&amp;amp; teams.first != nil        &lt;br /&gt;
 for teamsuser in TeamsUser.find(:all, :conditions =&amp;gt; [&amp;quot;team_id =?&amp;quot;, currTeam.id])&lt;br /&gt;
     teamsuser.destroy&lt;br /&gt;
     end    &lt;br /&gt;
     currTeam.destroy&lt;br /&gt;
     currTeam = nil&lt;br /&gt;
 end     &lt;br /&gt;
    &lt;br /&gt;
===== Part 4 – Create the New Team and Node =====&lt;br /&gt;
&lt;br /&gt;
Functionality: Creates a new team and team node base on the information gathered by the above parts.&lt;br /&gt;
&lt;br /&gt;
 if currTeam == nil&lt;br /&gt;
     currTeam = CourseTeam.new&lt;br /&gt;
     currTeam.name = name&lt;br /&gt;
     currTeam.parent_id = course.id&lt;br /&gt;
     currTeam.save&lt;br /&gt;
     parent = CourseNode.find_by_node_object_id(course.id)&lt;br /&gt;
     TeamNode.create(:parent_id =&amp;gt; parent.id, :node_object_id =&amp;gt; currTeam.id)&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
===== Part 5 – Import the Participants to the New Team =====&lt;br /&gt;
&lt;br /&gt;
Functionality: Verify that the users specified in the array exist, then add the users to the newly created team.&lt;br /&gt;
&lt;br /&gt;
 while(index &amp;lt; row.length) &lt;br /&gt;
     user = User.find_by_name(row[index].to_s.strip)&lt;br /&gt;
     if user == nil&lt;br /&gt;
         raise ImportError, &amp;quot;The user \&amp;quot;&amp;quot;+row[index].to_s.strip+&amp;quot;\&amp;quot; was not found. &amp;lt;a href='/users/new'&amp;gt;Create&amp;lt;/a&amp;gt; this user?&amp;quot;                           &lt;br /&gt;
     elsif currTeam != nil         &lt;br /&gt;
         currUser = TeamsUser.find(:first, :conditions =&amp;gt; [&amp;quot;team_id =? and user_id =?&amp;quot;, currTeam.id,user.id])          &lt;br /&gt;
         if currUser == nil&lt;br /&gt;
             currTeam.add_member(user)            &lt;br /&gt;
         end                      &lt;br /&gt;
     end&lt;br /&gt;
     index = index+1      &lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
==== Refactor ====&lt;br /&gt;
From the decomposition, Part 5 can be seen as needing to be separated into its own method. &lt;br /&gt;
&lt;br /&gt;
  def import_participants(starting_index, row)&lt;br /&gt;
    index = starting_index&lt;br /&gt;
    while(index &amp;lt; row.length)&lt;br /&gt;
      user = User.find_by_name(row[index].to_s.strip)&lt;br /&gt;
      if user.nil?&lt;br /&gt;
        raise ImportError, &amp;quot;The user \&amp;quot;&amp;quot;+row[index].to_s.strip+&amp;quot;\&amp;quot; was not found. &amp;lt;a href='/users/new'&amp;gt;Create&amp;lt;/a&amp;gt; this user?&amp;quot;&lt;br /&gt;
      else&lt;br /&gt;
        if TeamsUser.find(:first, :conditions =&amp;gt; [&amp;quot;team_id =? and user_id =?&amp;quot;, id, user.id]).nil?&lt;br /&gt;
          add_member(user)&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
      index = index + 1&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
From the decomposition, the logic of Part 2 and Part 3 show that they could be simplified. Originally, Part 4 was executed regardless of if the team name was generated or imported. However, if the team name is generated instead of imported, there will not be another team with the same name. Therefore, we extracted Part 4 into its own method and modified the logic of Part 3.&lt;br /&gt;
&lt;br /&gt;
  def self.handle_duplicate(name, course_id, handle_dups)&lt;br /&gt;
    team = find(:first, :conditions =&amp;gt; [&amp;quot;name =? and parent_id =?&amp;quot;, name, course_id])&lt;br /&gt;
    if team.nil? #no duplicate&lt;br /&gt;
      return name&lt;br /&gt;
    end&lt;br /&gt;
    if handle_dups == &amp;quot;ignore&amp;quot; #ignore: not create the new team&lt;br /&gt;
      return nil&lt;br /&gt;
    end&lt;br /&gt;
    if handle_dups == &amp;quot;rename&amp;quot; #rename: rename new team&lt;br /&gt;
      return generate_team_name&lt;br /&gt;
    end&lt;br /&gt;
    if handle_dups == &amp;quot;replace&amp;quot; #replace: delete old team&lt;br /&gt;
      team.delete&lt;br /&gt;
      return name&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
After the modifications to Part 3 and Part 4 are completed, the import method becomes:&lt;br /&gt;
 &lt;br /&gt;
    if options[:has_column_names] == &amp;quot;true&amp;quot;&lt;br /&gt;
      name = row[0].to_s.strip&lt;br /&gt;
      name = handle_duplicate(name, course_id, options[:handle_dups])&lt;br /&gt;
      index = 1&lt;br /&gt;
    else&lt;br /&gt;
      name = generate_team_name&lt;br /&gt;
      index = 0&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
==== Miscellaneous Changes ====&lt;br /&gt;
The condition in Part 1 is incorrect because the number of elements could be less than 2 if the array does not have a team name column.&lt;br /&gt;
&lt;br /&gt;
 if (row.length &amp;lt; 2 and options[:has_column_names] == &amp;quot;true&amp;quot;) or (row.length &amp;lt; 1 and options[:has_column_names] != &amp;quot;true&amp;quot;)&lt;br /&gt;
   raise ArgumentError, &amp;quot;Not enough items&amp;quot;&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
Part 4 of the method was simplified to improve the readability.&lt;br /&gt;
&lt;br /&gt;
 team = CourseTeam.create(:name =&amp;gt; name, :parent_id =&amp;gt; course_id)&lt;br /&gt;
 course_node = CourseNode.find_by_node_object_id(course_id)&lt;br /&gt;
 TeamNode.create(:parent_id =&amp;gt; course_node.id, :node_object_id =&amp;gt; team.id)&lt;br /&gt;
&lt;br /&gt;
==== Other Issues ====&lt;br /&gt;
The input variable session was unused in the method; therefore, it needed to be removed.  However, this change was not made in this project due to the way that the method is being called in the import file controller.&lt;br /&gt;
&lt;br /&gt;
=== ''export'' Method ===&lt;br /&gt;
==== Functionality Bug ====&lt;br /&gt;
Originally, the export method in the CourseTeam class exported the assignment teams that were associated with the course to which a course team belonged.  This is not the behavior that one would expect from the export method in the CourseTeam class. &lt;br /&gt;
&lt;br /&gt;
Upon examining the AssignmentTeam class, the export method for CourseTeam was determined to export all of the course teams associated with a course. &lt;br /&gt;
&lt;br /&gt;
 def self.export(csv, parent_id, options)&lt;br /&gt;
    currentCourse = Course.find(parent_id)&lt;br /&gt;
    currentCourse.teams.each { |team|&lt;br /&gt;
      tcsv = Array.new&lt;br /&gt;
      teamUsers = Array.new&lt;br /&gt;
      tcsv.push(team.name)&lt;br /&gt;
      if (options[&amp;quot;team_name&amp;quot;] == &amp;quot;false&amp;quot;)&lt;br /&gt;
        teamMembers = TeamsUser.find(:all, :conditions =&amp;gt; ['team_id = ?', team.id])&lt;br /&gt;
        teamMembers.each do |user|&lt;br /&gt;
          teamUsers.push(user.name)&lt;br /&gt;
          teamUsers.push(&amp;quot; &amp;quot;)&lt;br /&gt;
        end&lt;br /&gt;
        tcsv.push(teamUsers)&lt;br /&gt;
      end&lt;br /&gt;
      tcsv.push(currentCourse.name)&lt;br /&gt;
      csv &amp;lt;&amp;lt; tcsv&lt;br /&gt;
    }&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
Note that this is a direct port of code from the source of the export function in the AssignmentTeam class.&lt;br /&gt;
&lt;br /&gt;
The original export function was renamed to export_all_assignment_team_related_to_course to reflect its actual functionality.  The function was marked deprecated and if the functionality is later found to be needed, the function should be re-written and moved to the Course class. &lt;br /&gt;
&lt;br /&gt;
==== Analysis and Refactor ====&lt;br /&gt;
The part of the export method within the if block is used to export all of the participants of a team.  This part can be separated into its own method to reduce the complexity of the export method. &lt;br /&gt;
&lt;br /&gt;
  def export_participants&lt;br /&gt;
    userNames = Array.new&lt;br /&gt;
    participants = TeamsUser.find(:all, :conditions =&amp;gt; ['team_id = ?', self.id])&lt;br /&gt;
    participants.each do |participant|&lt;br /&gt;
      userNames.push(participant.name)&lt;br /&gt;
      userNames.push(&amp;quot; &amp;quot;)&lt;br /&gt;
    end&lt;br /&gt;
    return userNames&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
Furthermore, an instance method was added to the CourseTeam class to export the team.  The class method export can call the instance method to reduce the complexity and improve the readability.&lt;br /&gt;
&lt;br /&gt;
  def export(team_name_only)&lt;br /&gt;
    output = Array.new&lt;br /&gt;
    output.push(self.name)&lt;br /&gt;
    if team_name_only == &amp;quot;false&amp;quot;&lt;br /&gt;
      output.push(self.export_participants)&lt;br /&gt;
    end&lt;br /&gt;
    course = Course.find(self.parent_id)&lt;br /&gt;
    output.push(course.name)&lt;br /&gt;
    return output&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
The export function as it looked after refactoring:&lt;br /&gt;
&lt;br /&gt;
  def self.export(csv, parent_id, options)&lt;br /&gt;
    course = Course.find(parent_id)&lt;br /&gt;
    if course.nil?&lt;br /&gt;
      raise ImportError, &amp;quot;The course with id \&amp;quot;&amp;quot;+course_id.to_s+&amp;quot;\&amp;quot; was not found. &amp;lt;a href='/assignment/new'&amp;gt;Create&amp;lt;/a&amp;gt; this course?&amp;quot;&lt;br /&gt;
    end&lt;br /&gt;
    teams = CourseTeam.find_all_by_parent_id(parent_id)&lt;br /&gt;
    teams.each do |team|&lt;br /&gt;
      csv &amp;lt;&amp;lt; team.export(options[:team_name])&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
==== Other Issues ====&lt;br /&gt;
The method name export does not accurately describe the functionality of this method.  It is recommended that this method name be changed to export_all. This change was not made due to the export method in the AssignmentTeam class and the way that the method is being called by the export file controller.&lt;br /&gt;
&lt;br /&gt;
The meaning of the option team_name in the method is ambiguous. Upon further examination, it was discovered that the option team_name controls if the method should only export team names without exporting the name of the participants in the team. This option should be renamed to team_name_only for better clarity.&lt;br /&gt;
&lt;br /&gt;
=== ''get_export_fields'' Method ===&lt;br /&gt;
Inferring from the code, the get_export_field method seems to return an array that contains the options used for controlling the export method.&lt;br /&gt;
&lt;br /&gt;
As discussed earlier, the team_name option for expert method controls if the export should contain the name of the team participants.&lt;br /&gt;
&lt;br /&gt;
Originally, the get_export_fields method will include the string “team member” if the option team_name is true. &lt;br /&gt;
&lt;br /&gt;
Furthermore, the get_export_fields method is trying to get the value of string(“team_name”) in hash variable options instead of symbol(:team_name).&lt;br /&gt;
&lt;br /&gt;
Here is the method after making the noted changes:&lt;br /&gt;
&lt;br /&gt;
  def self.get_export_fields(options)&lt;br /&gt;
    fields = Array.new&lt;br /&gt;
    fields.push(&amp;quot;Team Name&amp;quot;)&lt;br /&gt;
    if (options[:team_name] == &amp;quot;false&amp;quot;)&lt;br /&gt;
      fields.push(&amp;quot;Team members&amp;quot;)&lt;br /&gt;
    end&lt;br /&gt;
    fields.push(&amp;quot;Course Name&amp;quot;)&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
=== ''copy'' Method === &lt;br /&gt;
This method is inferred to be used to create a new assignment team and copy all of the participants of the course team to that new assignment team.&lt;br /&gt;
&lt;br /&gt;
If this is later confirmed to be the intended functionality of this method, then this method should belong to AssignmentTeam class instead of CourseTeam class.&lt;br /&gt;
&lt;br /&gt;
This method calls the create_node_object method in Team class, which does not work (explained in a later section) and has an ambiguous return type, functionality, and name.&lt;br /&gt;
&lt;br /&gt;
Logically, the copy method should create a new course team and copy the participants of a team into the new course team.&lt;br /&gt;
Currently, this is dead code and not used in the program.  &lt;br /&gt;
&lt;br /&gt;
This function was marked deprecated and it is recommended to be removed from the program.&lt;br /&gt;
&lt;br /&gt;
=== ''add_participant'' Method === &lt;br /&gt;
This method is used to add a participant to the course that the course team to which it belongs.&lt;br /&gt;
&lt;br /&gt;
This method is called by the add_member method in the Team class to add a participant to the course when a member is added to a course team.&lt;br /&gt;
&lt;br /&gt;
This method does belong in the Course class and not the CourseTeam class.  The Course class already has the method add_participant with similar functionality.&lt;br /&gt;
&lt;br /&gt;
This function was marked deprecated and it is recommended that the function should be removed from the program and the add_member method in the Team class should call the add_participant method from Course class.&lt;br /&gt;
&lt;br /&gt;
== Changes for /app/models/course_node.rb ==&lt;br /&gt;
* models/course_node.rb &lt;br /&gt;
** The &amp;quot;get&amp;quot; method was improved. &lt;br /&gt;
*** Added &amp;quot;get_courses_managed_by_user&amp;quot; method to hold logic extracted from the &amp;quot;get&amp;quot;method.  &lt;br /&gt;
*** Added &amp;quot;get_course_query_conditions&amp;quot; method to hold logic extracted from the &amp;quot;get&amp;quot; method.  &lt;br /&gt;
*** Modified any checks on if the user is a teaching assistant to use polymorphism to make the determination.  &lt;br /&gt;
*** Removed the initial conditional for setting the &amp;quot;conditions&amp;quot; value since the remaining conditions was overwriting the value regardless of how the initial conditional was evaluated. &lt;br /&gt;
*** Renaming the &amp;quot;get&amp;quot; method was considered; however, the name of the method is necessary for polymorphism reasons related to Assignment nodes.  As such, a comment was added to explain why the method name should remain.     &lt;br /&gt;
*** The &amp;quot;sortorder&amp;quot; parameter is given a default value of &amp;quot;ASC&amp;quot; for ascending.  This allowed for a related conditional to be removed from the method.  &lt;br /&gt;
*** The &amp;quot;sortvar&amp;quot; parameter is given a default value of &amp;quot;name&amp;quot; for sorting by course name.  This allowed for a related conditional to be removed from the method.&lt;br /&gt;
** Renaming the &amp;quot;get_children&amp;quot; method was considered; however, the name of the method is necessary for polymorphism reasons related to Assignment Nodes.  As such, a comment was added to explain why the method name should remain. &lt;br /&gt;
** The &amp;quot;get_survey_distribution_id&amp;quot; method was removed after finding it to be dead code.&lt;br /&gt;
* models/ta.rb&lt;br /&gt;
** Added &amp;quot;is_teaching_assistant?&amp;quot; method to override the inherited method from the User model.  This supported usage of polymorphism to determine if the user is a teaching assistant.  &lt;br /&gt;
* models/user.rb&lt;br /&gt;
** Added &amp;quot;is_teaching_assistant?&amp;quot; method to enable usage of polymorphism to determine if the user is a teaching assistant.&lt;br /&gt;
&lt;br /&gt;
== Methods Found That Are Not Currently Being Used ==&lt;br /&gt;
The following methods were not found to be used currently by the project, but have been left in the code for potential future usages of the functionality:&lt;br /&gt;
* /app/models/course.rb&lt;br /&gt;
** Course.get_participant(user_id)&lt;br /&gt;
* /app/models/course_participant.rb&lt;br /&gt;
** CourseParticipant.copy(assignment_id)&lt;br /&gt;
** CourseParticipant.get_parent_name&lt;br /&gt;
* /app/models/course_node.rb&lt;br /&gt;
** CourseNode.get_modified_date&lt;br /&gt;
&lt;br /&gt;
== Other Observations and Suggestion for Future Work == &lt;br /&gt;
=== Redundant Code in Team Related Classes ===&lt;br /&gt;
Classes: Team, CourseTeam, AssignmentTeam&lt;br /&gt;
&lt;br /&gt;
Files: team.rb, course_team.rb, assignment_team.rb&lt;br /&gt;
&lt;br /&gt;
The class CourseTeam and AssignmentTeam both inherit from the class Team. However, there are a lot of duplicated functionalities.  In order to adhere to the &amp;quot;DRY&amp;quot; principle, the refactoring mentioned earlier for the CourseTeam should be applied to AssignmentTeam and duplicated methods should be extracted to the super-class Team.&lt;br /&gt;
&lt;br /&gt;
=== Naming Inconsistency in Team Related Classes ===&lt;br /&gt;
Classes: Team, CourseTeam, AssignmentTeam&lt;br /&gt;
&lt;br /&gt;
Files: team.rb, course_team.rb, assignment_team.rb&lt;br /&gt;
&lt;br /&gt;
Participants in a team have many different names in these three classes. For example: member, user, participants. Common vocabulary should be established in order to eliminate confusion. &lt;br /&gt;
&lt;br /&gt;
=== Bugs in Team Class ===&lt;br /&gt;
Class: Team&lt;br /&gt;
&lt;br /&gt;
File: team.rb&lt;br /&gt;
&lt;br /&gt;
Method: create_node_object&lt;br /&gt;
&lt;br /&gt;
The create_node_object method in Team class does not work because the class method get_parent_model in both CourseTeam and Assignment team is an instance method and not a class method.&lt;br /&gt;
&lt;br /&gt;
Based on the code of the object and the usage of this code, the method is supposed to create a new course or assignment team along with a new team node and then return the newly created team as output.  This function should be deprecated and removed from the class.  The functionality should be moved to the new method in the team controller if the functionality is found to be necessary.&lt;br /&gt;
&lt;br /&gt;
=== Inelegance Code in Team Class ===&lt;br /&gt;
Class: Team&lt;br /&gt;
&lt;br /&gt;
File: team.rb&lt;br /&gt;
&lt;br /&gt;
Methods: randomize_all_by_parent, check_for_existing, create_node_object, copy_members&lt;br /&gt;
&lt;br /&gt;
These methods uses Object.const_get() with an input string that dynamically locates the object that is associated with different team types (assignment or course); however, the uses of Object.const_get() are inconsistent throughout these methods.&lt;br /&gt;
&lt;br /&gt;
It is recommended that instead of using query methods, such as get_participant_type and get_parent_model, in the assignment and course team to return a string containing the name of the object, these methods should be used to return the object itself.  This will eliminate the need for Object.const_get().&lt;br /&gt;
&lt;br /&gt;
== List of New Unit Tests and Testcases ==&lt;br /&gt;
The following lists shows new unit files and/or new testcases:&lt;br /&gt;
* test/unit/course_node_test.rb (new test file)&lt;br /&gt;
** test_get_children_with_show_true_and_non_TA_and_ascending_order_by_name&lt;br /&gt;
** test_get_children_with_show_true_and_non_TA_and_descending_order_by_name&lt;br /&gt;
** test_get_children_with_show_true_and_TA_and_ascending_order_by_name&lt;br /&gt;
** test_get_children_with_show_true_and_TA_and_descending_order_by_name&lt;br /&gt;
** test_get_children_with_show_false_and_non_TA_and_ascending_order_by_name&lt;br /&gt;
** test_get_children_with_show_false_and_non_TA_and_descending_order_by_name&lt;br /&gt;
** test_get_children_with_show_false_and_TA_and_ascending_order_by_name&lt;br /&gt;
** test_get_children_with_show_false_and_TA_and_descending_order_by_name&lt;br /&gt;
** test_get_children_with_show_false_and_non_TA_and_nil_order_by_nil&lt;br /&gt;
** test_get_name&lt;br /&gt;
** test_get_directory&lt;br /&gt;
** test_get_creation_date&lt;br /&gt;
** test_get_modified_date&lt;br /&gt;
** test_get_teams&lt;br /&gt;
** test_get_parent_id&lt;br /&gt;
* test/unit/course_test.rb (previously existing test file)&lt;br /&gt;
** test_get_teams&lt;br /&gt;
** test_get_path&lt;br /&gt;
** test_get_participants&lt;br /&gt;
** test_get_participant&lt;br /&gt;
** test_add_participant&lt;br /&gt;
** test_copy_participants&lt;br /&gt;
* test/unit/course_participant_test.rb (previously existing test file)&lt;br /&gt;
** test_get_course_string&lt;br /&gt;
** test_import&lt;br /&gt;
** test_get_path&lt;br /&gt;
** test_export&lt;br /&gt;
** test_get_export_field&lt;br /&gt;
* test/unit/course_team_test.rb (new test file)&lt;br /&gt;
** test_retrieval&lt;br /&gt;
** test_import_participants&lt;br /&gt;
** test_export_participants&lt;br /&gt;
** test_instance_export&lt;br /&gt;
** test_handle_duplicate&lt;br /&gt;
** test_import&lt;br /&gt;
** test_class_export&lt;br /&gt;
&lt;br /&gt;
== List of Modified Unit Tests ==&lt;br /&gt;
The following unit test files and/or testcases were modified:&lt;br /&gt;
* test/unit/course_test.rb&lt;br /&gt;
** The line &amp;quot;fixtures :courses&amp;quot; was changed to &amp;quot;fixtures :courses,:teams,:users,:participants,:assignments,:nodes,:tree_folders&amp;quot;.&lt;/div&gt;</summary>
		<author><name>Kbyarbor</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2013/OSS_E608&amp;diff=74286</id>
		<title>CSC/ECE 517 Spring 2013/OSS E608</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2013/OSS_E608&amp;diff=74286"/>
		<updated>2013-03-21T03:07:00Z</updated>

		<summary type="html">&lt;p&gt;Kbyarbor: /* Miscellaneous Changes for Quality Improvement and Readability */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[https://docs.google.com/a/ncsu.edu/document/d/1SVNx7Eh6dUdrz2a9rGSgBxLkxAmuBUm8eu08nHEdjIg/edit# Write-up of This Topic.]&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
= E608. Refactoring and Testing - Course Related Classes =&lt;br /&gt;
Classes Involved:&lt;br /&gt;
*/app/models/course.rb (76 lines)&lt;br /&gt;
*/app/models/course_participant.rb (94 lines)&lt;br /&gt;
*/app/models/course_team.rb (116 lines)&lt;br /&gt;
*/app/models/course_node.rb (95 lines)&lt;br /&gt;
&lt;br /&gt;
What it does: &lt;br /&gt;
Involves creation and management of courses in Expertiza&lt;br /&gt;
&lt;br /&gt;
What needs to be done:&lt;br /&gt;
*It is not clear what a method named 'create_node' is doing in the 'course' class. Refactor by renaming this method appropriately.&lt;br /&gt;
*In the course_team class the import method seems to be doing too many things. See if this method can be broken down into smaller methods with specific functionality.&lt;br /&gt;
*The 'get' method in course_node.rb appears to be doing a lot. Refactor this method by breaking it up into smaller methods.&lt;br /&gt;
*Look for any unused methods or variables in these files.&lt;br /&gt;
*Also apply other refactorings such as Rename variable, Rename method to give the variables and methods more meaningful names.&lt;br /&gt;
*Write unit tests for all the methods in each of the listed model classes.&lt;br /&gt;
&lt;br /&gt;
== Changes for /app/models/course.rb ==&lt;br /&gt;
The following changes were made:&lt;br /&gt;
* Since the method create_node simply creates a course node associated with the newly created or copied course, we replaced its functionality by adding the line CourseNode.create(:node_object_id =&amp;gt; course.id) in the course_controller's create method and copy method. The function of getting the CourseNode's parent id is extracted as a class method of CourseNode model since this parent id is independent of the course. With all of its functionalities refactored to other places, this method is hereby removed. &lt;br /&gt;
* Added the line &amp;quot;has_many :assigments, :dependent =&amp;gt; :destroy&amp;quot; to allow CourseTest.test_destroy unit test to pass.&lt;br /&gt;
&lt;br /&gt;
== Changes for /app/models/course_participant.rb ==&lt;br /&gt;
* CourseParticipant.get_parent_name is removed&lt;br /&gt;
** This method is never called in the project.  Additionally, the method CourseParticipant.get_course_string provides the same functionality as CourseParticipant.get_parent_name, so it was deleted to follow the principle of DRY.&lt;br /&gt;
&lt;br /&gt;
== Changes for /app/models/course_team.rb ==&lt;br /&gt;
&lt;br /&gt;
=== ''import'' Method ===&lt;br /&gt;
Functionality: Import a single course team for a course from an input array. The first element in the array is optionally used to specify a name for the team that is being imported.&lt;br /&gt;
&lt;br /&gt;
Usage: The method is used by the import file controller to import course teams to a course.   &lt;br /&gt;
&lt;br /&gt;
==== Decomposition ====&lt;br /&gt;
The import method can be decomposed into 5 separate parts: &lt;br /&gt;
&lt;br /&gt;
===== Part 1 – Preparation =====&lt;br /&gt;
&lt;br /&gt;
Functionality: Ensure that the array has enough elements and that the class in which the user wants to import the team exists.  &lt;br /&gt;
&lt;br /&gt;
 if row.length &amp;lt; 2&lt;br /&gt;
     raise ArgumentError, &amp;quot;Not enough items&amp;quot; &lt;br /&gt;
 end &lt;br /&gt;
 course = Course.find(id)&lt;br /&gt;
 if course == nil&lt;br /&gt;
     raise ImportError, &amp;quot;The course with id \&amp;quot;&amp;quot;+id.to_s+&amp;quot;\&amp;quot; was not found. &amp;lt;a href='/assignment/new'&amp;gt;Create&amp;lt;/a&amp;gt; this assignment?&amp;quot;&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
===== Part 2 – Naming the New Team =====&lt;br /&gt;
&lt;br /&gt;
Functionality: The method will either import the team name from the array if has_column_name is set to true or generate a new team name if has_column_name is set to false.&lt;br /&gt;
&lt;br /&gt;
 if options[:has_column_names] == &amp;quot;true&amp;quot;&lt;br /&gt;
     name = row[0].to_s.strip&lt;br /&gt;
     index = 1&lt;br /&gt;
 else&lt;br /&gt;
     name = generate_team_name()&lt;br /&gt;
     index = 0&lt;br /&gt;
 end &lt;br /&gt;
&lt;br /&gt;
===== Part 3 – Handling Duplicate Team =====&lt;br /&gt;
&lt;br /&gt;
Functionality: If a team with the same team name exists, this part of the method will handle the conflict based on the option handle_duplicate.&lt;br /&gt;
&lt;br /&gt;
 currTeam = CourseTeam.find(:first, :conditions =&amp;gt; [&amp;quot;name =? and parent_id =?&amp;quot;,name,course.id])  &lt;br /&gt;
 if options[:handle_dups] == &amp;quot;ignore&amp;quot; &amp;amp;&amp;amp; currTeam != nil&lt;br /&gt;
     return&lt;br /&gt;
 end  &lt;br /&gt;
 if currTeam != nil &amp;amp;&amp;amp; options[:handle_dups] == &amp;quot;rename&amp;quot;&lt;br /&gt;
     name = generate_team_name()&lt;br /&gt;
     currTeam = nil&lt;br /&gt;
 end&lt;br /&gt;
 if options[:handle_dups] == &amp;quot;replace&amp;quot; &amp;amp;&amp;amp; teams.first != nil        &lt;br /&gt;
 for teamsuser in TeamsUser.find(:all, :conditions =&amp;gt; [&amp;quot;team_id =?&amp;quot;, currTeam.id])&lt;br /&gt;
     teamsuser.destroy&lt;br /&gt;
     end    &lt;br /&gt;
     currTeam.destroy&lt;br /&gt;
     currTeam = nil&lt;br /&gt;
 end     &lt;br /&gt;
    &lt;br /&gt;
===== Part 4 – Create the New Team and Node =====&lt;br /&gt;
&lt;br /&gt;
Functionality: Creates a new team and team node base on the information gathered by the above parts.&lt;br /&gt;
&lt;br /&gt;
 if currTeam == nil&lt;br /&gt;
     currTeam = CourseTeam.new&lt;br /&gt;
     currTeam.name = name&lt;br /&gt;
     currTeam.parent_id = course.id&lt;br /&gt;
     currTeam.save&lt;br /&gt;
     parent = CourseNode.find_by_node_object_id(course.id)&lt;br /&gt;
     TeamNode.create(:parent_id =&amp;gt; parent.id, :node_object_id =&amp;gt; currTeam.id)&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
===== Part 5 – Import the Participants to the New Team =====&lt;br /&gt;
&lt;br /&gt;
Functionality: Verify that the users specified in the array exist, then add the users to the newly created team.&lt;br /&gt;
&lt;br /&gt;
 while(index &amp;lt; row.length) &lt;br /&gt;
     user = User.find_by_name(row[index].to_s.strip)&lt;br /&gt;
     if user == nil&lt;br /&gt;
         raise ImportError, &amp;quot;The user \&amp;quot;&amp;quot;+row[index].to_s.strip+&amp;quot;\&amp;quot; was not found. &amp;lt;a href='/users/new'&amp;gt;Create&amp;lt;/a&amp;gt; this user?&amp;quot;                           &lt;br /&gt;
     elsif currTeam != nil         &lt;br /&gt;
         currUser = TeamsUser.find(:first, :conditions =&amp;gt; [&amp;quot;team_id =? and user_id =?&amp;quot;, currTeam.id,user.id])          &lt;br /&gt;
         if currUser == nil&lt;br /&gt;
             currTeam.add_member(user)            &lt;br /&gt;
         end                      &lt;br /&gt;
     end&lt;br /&gt;
     index = index+1      &lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
==== Refactor ====&lt;br /&gt;
From the decomposition, Part 5 can be seen as needing to be separated into its own method. &lt;br /&gt;
&lt;br /&gt;
  def import_participants(starting_index, row)&lt;br /&gt;
    index = starting_index&lt;br /&gt;
    while(index &amp;lt; row.length)&lt;br /&gt;
      user = User.find_by_name(row[index].to_s.strip)&lt;br /&gt;
      if user.nil?&lt;br /&gt;
        raise ImportError, &amp;quot;The user \&amp;quot;&amp;quot;+row[index].to_s.strip+&amp;quot;\&amp;quot; was not found. &amp;lt;a href='/users/new'&amp;gt;Create&amp;lt;/a&amp;gt; this user?&amp;quot;&lt;br /&gt;
      else&lt;br /&gt;
        if TeamsUser.find(:first, :conditions =&amp;gt; [&amp;quot;team_id =? and user_id =?&amp;quot;, id, user.id]).nil?&lt;br /&gt;
          add_member(user)&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
      index = index + 1&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
From the decomposition, the logic of Part 2 and Part 3 show that they could be simplified. Originally, Part 4 was executed regardless of if the team name was generated or imported. However, if the team name is generated instead of imported, there will not be another team with the same name. Therefore, we extracted Part 4 into its own method and modified the logic of Part 3.&lt;br /&gt;
&lt;br /&gt;
  def self.handle_duplicate(name, course_id, handle_dups)&lt;br /&gt;
    team = find(:first, :conditions =&amp;gt; [&amp;quot;name =? and parent_id =?&amp;quot;, name, course_id])&lt;br /&gt;
    if team.nil? #no duplicate&lt;br /&gt;
      return name&lt;br /&gt;
    end&lt;br /&gt;
    if handle_dups == &amp;quot;ignore&amp;quot; #ignore: not create the new team&lt;br /&gt;
      return nil&lt;br /&gt;
    end&lt;br /&gt;
    if handle_dups == &amp;quot;rename&amp;quot; #rename: rename new team&lt;br /&gt;
      return generate_team_name&lt;br /&gt;
    end&lt;br /&gt;
    if handle_dups == &amp;quot;replace&amp;quot; #replace: delete old team&lt;br /&gt;
      team.delete&lt;br /&gt;
      return name&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
After the modifications to Part 3 and Part 4 are completed, the import method becomes:&lt;br /&gt;
 &lt;br /&gt;
    if options[:has_column_names] == &amp;quot;true&amp;quot;&lt;br /&gt;
      name = row[0].to_s.strip&lt;br /&gt;
      name = handle_duplicate(name, course_id, options[:handle_dups])&lt;br /&gt;
      index = 1&lt;br /&gt;
    else&lt;br /&gt;
      name = generate_team_name&lt;br /&gt;
      index = 0&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
==== Miscellaneous Changes ====&lt;br /&gt;
The condition in Part 1 is incorrect because the number of elements could be less than 2 if the array does not have a team name column.&lt;br /&gt;
&lt;br /&gt;
 if (row.length &amp;lt; 2 and options[:has_column_names] == &amp;quot;true&amp;quot;) or (row.length &amp;lt; 1 and options[:has_column_names] != &amp;quot;true&amp;quot;)&lt;br /&gt;
   raise ArgumentError, &amp;quot;Not enough items&amp;quot;&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
Part 4 of the method was simplified to improve the readability.&lt;br /&gt;
&lt;br /&gt;
 team = CourseTeam.create(:name =&amp;gt; name, :parent_id =&amp;gt; course_id)&lt;br /&gt;
 course_node = CourseNode.find_by_node_object_id(course_id)&lt;br /&gt;
 TeamNode.create(:parent_id =&amp;gt; course_node.id, :node_object_id =&amp;gt; team.id)&lt;br /&gt;
&lt;br /&gt;
==== Other Issues ====&lt;br /&gt;
The input variable session was unused in the method; therefore, it needed to be removed.  However, this change was not made in this project due to the way that the method is being called in the import file controller.&lt;br /&gt;
&lt;br /&gt;
=== ''export'' Method ===&lt;br /&gt;
==== Functionality Bug ====&lt;br /&gt;
Originally, the export method in the CourseTeam class exported the assignment teams that were associated with the course to which a course team belonged.  This is not the behavior that one would expect from the export method in the CourseTeam class. &lt;br /&gt;
&lt;br /&gt;
Upon examining the AssignmentTeam class, the export method for CourseTeam was determined to export all of the course teams associated with a course. &lt;br /&gt;
&lt;br /&gt;
 def self.export(csv, parent_id, options)&lt;br /&gt;
    currentCourse = Course.find(parent_id)&lt;br /&gt;
    currentCourse.teams.each { |team|&lt;br /&gt;
      tcsv = Array.new&lt;br /&gt;
      teamUsers = Array.new&lt;br /&gt;
      tcsv.push(team.name)&lt;br /&gt;
      if (options[&amp;quot;team_name&amp;quot;] == &amp;quot;false&amp;quot;)&lt;br /&gt;
        teamMembers = TeamsUser.find(:all, :conditions =&amp;gt; ['team_id = ?', team.id])&lt;br /&gt;
        teamMembers.each do |user|&lt;br /&gt;
          teamUsers.push(user.name)&lt;br /&gt;
          teamUsers.push(&amp;quot; &amp;quot;)&lt;br /&gt;
        end&lt;br /&gt;
        tcsv.push(teamUsers)&lt;br /&gt;
      end&lt;br /&gt;
      tcsv.push(currentCourse.name)&lt;br /&gt;
      csv &amp;lt;&amp;lt; tcsv&lt;br /&gt;
    }&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
Note that this is a direct port of code from the source of the export function in the AssignmentTeam class.&lt;br /&gt;
&lt;br /&gt;
The original export function was renamed to export_all_assignment_team_related_to_course to reflect its actual functionality.  The function was marked deprecated and if the functionality is later found to be needed, the function should be re-written and moved to the Course class. &lt;br /&gt;
&lt;br /&gt;
==== Analysis and Refactor ====&lt;br /&gt;
The part of the export method within the if block is used to export all of the participants of a team.  This part can be separated into its own method to reduce the complexity of the export method. &lt;br /&gt;
&lt;br /&gt;
  def export_participants&lt;br /&gt;
    userNames = Array.new&lt;br /&gt;
    participants = TeamsUser.find(:all, :conditions =&amp;gt; ['team_id = ?', self.id])&lt;br /&gt;
    participants.each do |participant|&lt;br /&gt;
      userNames.push(participant.name)&lt;br /&gt;
      userNames.push(&amp;quot; &amp;quot;)&lt;br /&gt;
    end&lt;br /&gt;
    return userNames&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
Furthermore, an instance method was added to the CourseTeam class to export the team.  The class method export can call the instance method to reduce the complexity and improve the readability.&lt;br /&gt;
&lt;br /&gt;
  def export(team_name_only)&lt;br /&gt;
    output = Array.new&lt;br /&gt;
    output.push(self.name)&lt;br /&gt;
    if team_name_only == &amp;quot;false&amp;quot;&lt;br /&gt;
      output.push(self.export_participants)&lt;br /&gt;
    end&lt;br /&gt;
    course = Course.find(self.parent_id)&lt;br /&gt;
    output.push(course.name)&lt;br /&gt;
    return output&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
The export function as it looked after refactoring:&lt;br /&gt;
&lt;br /&gt;
  def self.export(csv, parent_id, options)&lt;br /&gt;
    course = Course.find(parent_id)&lt;br /&gt;
    if course.nil?&lt;br /&gt;
      raise ImportError, &amp;quot;The course with id \&amp;quot;&amp;quot;+course_id.to_s+&amp;quot;\&amp;quot; was not found. &amp;lt;a href='/assignment/new'&amp;gt;Create&amp;lt;/a&amp;gt; this course?&amp;quot;&lt;br /&gt;
    end&lt;br /&gt;
    teams = CourseTeam.find_all_by_parent_id(parent_id)&lt;br /&gt;
    teams.each do |team|&lt;br /&gt;
      csv &amp;lt;&amp;lt; team.export(options[:team_name])&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
==== Other Issues ====&lt;br /&gt;
The method name export does not accurately describe the functionality of this method.  It is recommended that this method name be changed to export_all. This change was not made due to the export method in the AssignmentTeam class and the way that the method is being called by the export file controller.&lt;br /&gt;
&lt;br /&gt;
The meaning of the option team_name in the method is ambiguous. Upon further examination, it was discovered that the option team_name controls if the method should only export team names without exporting the name of the participants in the team. This option should be renamed to team_name_only for better clarity.&lt;br /&gt;
&lt;br /&gt;
=== ''get_export_fields'' Method ===&lt;br /&gt;
Inferring from the code, the get_export_field method seems to return an array that contains the options used for controlling the export method.&lt;br /&gt;
&lt;br /&gt;
As discussed earlier, the team_name option for expert method controls if the export should contain the name of the team participants.&lt;br /&gt;
&lt;br /&gt;
Originally, the get_export_fields method will include the string “team member” if the option team_name is true. &lt;br /&gt;
&lt;br /&gt;
Furthermore, the get_export_fields method is trying to get the value of string(“team_name”) in hash variable options instead of symbol(:team_name).&lt;br /&gt;
&lt;br /&gt;
Here is the method after making the noted changes:&lt;br /&gt;
&lt;br /&gt;
  def self.get_export_fields(options)&lt;br /&gt;
    fields = Array.new&lt;br /&gt;
    fields.push(&amp;quot;Team Name&amp;quot;)&lt;br /&gt;
    if (options[:team_name] == &amp;quot;false&amp;quot;)&lt;br /&gt;
      fields.push(&amp;quot;Team members&amp;quot;)&lt;br /&gt;
    end&lt;br /&gt;
    fields.push(&amp;quot;Course Name&amp;quot;)&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
=== ''copy'' Method === &lt;br /&gt;
This method is inferred to be used to create a new assignment team and copy all of the participants of the course team to that new assignment team.&lt;br /&gt;
&lt;br /&gt;
If this is later confirmed to be the intended functionality of this method, then this method should belong to AssignmentTeam class instead of CourseTeam class.&lt;br /&gt;
&lt;br /&gt;
This method calls the create_node_object method in Team class, which does not work (explained in a later section) and has an ambiguous return type, functionality, and name.&lt;br /&gt;
&lt;br /&gt;
Logically, the copy method should create a new course team and copy the participants of a team into the new course team.&lt;br /&gt;
Currently, this is dead code and not used in the program.  &lt;br /&gt;
&lt;br /&gt;
This function was marked deprecated and it is recommended to be removed from the program.&lt;br /&gt;
&lt;br /&gt;
=== ''add_participant'' Method === &lt;br /&gt;
This method is used to add a participant to the course that the course team to which it belongs.&lt;br /&gt;
&lt;br /&gt;
This method is called by the add_member method in the Team class to add a participant to the course when a member is added to a course team.&lt;br /&gt;
&lt;br /&gt;
This method does belong in the Course class and not the CourseTeam class.  The Course class already has the method add_participant with similar functionality.&lt;br /&gt;
&lt;br /&gt;
This function was marked deprecated and it is recommended that the function should be removed from the program and the add_member method in the Team class should call the add_participant method from Course class.&lt;br /&gt;
&lt;br /&gt;
== Changes for /app/models/course_node.rb ==&lt;br /&gt;
* models/course_node.rb &lt;br /&gt;
** The &amp;quot;get&amp;quot; method was improved. &lt;br /&gt;
*** Added &amp;quot;get_courses_managed_by_user&amp;quot; method to hold logic extracted from the &amp;quot;get&amp;quot;method.  &lt;br /&gt;
*** Added &amp;quot;get_course_query_conditions&amp;quot; method to hold logic extracted from the &amp;quot;get&amp;quot; method.  &lt;br /&gt;
*** Modified any checks on if the user is a teaching assistant to use polymorphism to make the determination.  &lt;br /&gt;
*** Removed the initial conditional for setting the &amp;quot;conditions&amp;quot; value since the remaining conditions was overwriting the value regardless of how the initial conditional was evaluated. &lt;br /&gt;
*** Renaming the &amp;quot;get&amp;quot; method was considered; however, the name of the method is necessary for polymorphism reasons related to Assignment nodes.  As such, a comment was added to explain why the method name should remain.     &lt;br /&gt;
*** The &amp;quot;sortorder&amp;quot; parameter is given a default value of &amp;quot;ASC&amp;quot; for ascending.  This allowed for a related conditional to be removed from the method.  &lt;br /&gt;
*** The &amp;quot;sortvar&amp;quot; parameter is given a default value of &amp;quot;name&amp;quot; for sorting by course name.  This allowed for a related conditional to be removed from the method.&lt;br /&gt;
** Renaming the &amp;quot;get_children&amp;quot; method was considered; however, the name of the method is necessary for polymorphism reasons related to Assignment Nodes.  As such, a comment was added to explain why the method name should remain. &lt;br /&gt;
** The &amp;quot;get_survey_distribution_id&amp;quot; method was removed after finding it to be dead code.&lt;br /&gt;
* models/ta.rb&lt;br /&gt;
** Added &amp;quot;is_teaching_assistant?&amp;quot; method to override the inherited method from the User model.  This supported usage of polymorphism to determine if the user is a teaching assistant.  &lt;br /&gt;
* models/user.rb&lt;br /&gt;
** Added &amp;quot;is_teaching_assistant?&amp;quot; method to enable usage of polymorphism to determine if the user is a teaching assistant.&lt;br /&gt;
&lt;br /&gt;
== Methods Found That Are Not Currently Being Used ==&lt;br /&gt;
The following methods were not found to be used currently by the project, but have been left in the code for potential future usages of the functionality:&lt;br /&gt;
* /app/models/course.rb&lt;br /&gt;
** Course.get_participant(user_id)&lt;br /&gt;
* /app/models/course_participant.rb&lt;br /&gt;
** CourseParticipant.copy(assignment_id)&lt;br /&gt;
** CourseParticipant.get_parent_name&lt;br /&gt;
* /app/models/course_node.rb&lt;br /&gt;
** CourseNode.get_modified_date&lt;br /&gt;
&lt;br /&gt;
== Other Observations and Suggestion for Future Work == &lt;br /&gt;
=== Redundant Code in Team Related Classes ===&lt;br /&gt;
Classes: Team, CourseTeam, AssignmentTeam&lt;br /&gt;
&lt;br /&gt;
Files: team.rb, course_team.rb, assignment_team.rb&lt;br /&gt;
&lt;br /&gt;
The class CourseTeam and AssignmentTeam both inherits from the class Team. However that are a lot of duplicated functionalities in order to adhere to the &amp;quot;DRY&amp;quot; principle refactor for the CourseTeam mentioned in this document should be applied to AssignmentTeam and duplicated methods should be extracted to the super-class Team.&lt;br /&gt;
&lt;br /&gt;
=== Naming Inconsistency in Team Related Classes ===&lt;br /&gt;
Classes: Team, CourseTeam, AssignmentTeam&lt;br /&gt;
&lt;br /&gt;
Files: team.rb, course_team.rb, assignment_team.rb&lt;br /&gt;
&lt;br /&gt;
Participant in a team have many different names in these three classes. For example: member, user, participants. Common vocabulary should be established in-order to eliminate confusion. &lt;br /&gt;
&lt;br /&gt;
=== Bugs in Team Class ===&lt;br /&gt;
Class: Team&lt;br /&gt;
&lt;br /&gt;
File: team.rb&lt;br /&gt;
&lt;br /&gt;
Method: create_node_object&lt;br /&gt;
&lt;br /&gt;
The create_node_object method in Team class does not work because the class method get_parent_model in both CourseTeam and Assignment team is an instance method not a class method.&lt;br /&gt;
&lt;br /&gt;
From the code of the object and the usage of this code we inferred that the method supposed to create a new course or assignment team and a new team node and return the newly created team as output.&lt;br /&gt;
This function should be deprecated and removed from the class, the functionality should be move to the new method in the team controller if the functionality is truly necessary.&lt;br /&gt;
&lt;br /&gt;
=== Inelegance Code in Team Class ===&lt;br /&gt;
Class: Team&lt;br /&gt;
&lt;br /&gt;
File: team.rb&lt;br /&gt;
&lt;br /&gt;
Methods: randomize_all_by_parent, check_for_existing, create_node_object, copy_members&lt;br /&gt;
&lt;br /&gt;
These methods uses Object.const_get() with a input string that dynamically locate the object that are associated with different team types (assignment or course) however  the use of Object.const_get() are inconsistent throughout these methods.&lt;br /&gt;
&lt;br /&gt;
We suggests instead of using query methods such as get_participant_type  and get_parent_model  in the assignment and course team return string containing the name of the object we can use these method to return the object itself thus eliminating the need for Object.const_get().&lt;br /&gt;
&lt;br /&gt;
== List of New Unit Tests and Testcases ==&lt;br /&gt;
The following lists shows new unit files and/or new testcases:&lt;br /&gt;
* test/unit/course_node_test.rb (new test file)&lt;br /&gt;
** test_get_children_with_show_true_and_non_TA_and_ascending_order_by_name&lt;br /&gt;
** test_get_children_with_show_true_and_non_TA_and_descending_order_by_name&lt;br /&gt;
** test_get_children_with_show_true_and_TA_and_ascending_order_by_name&lt;br /&gt;
** test_get_children_with_show_true_and_TA_and_descending_order_by_name&lt;br /&gt;
** test_get_children_with_show_false_and_non_TA_and_ascending_order_by_name&lt;br /&gt;
** test_get_children_with_show_false_and_non_TA_and_descending_order_by_name&lt;br /&gt;
** test_get_children_with_show_false_and_TA_and_ascending_order_by_name&lt;br /&gt;
** test_get_children_with_show_false_and_TA_and_descending_order_by_name&lt;br /&gt;
** test_get_children_with_show_false_and_non_TA_and_nil_order_by_nil&lt;br /&gt;
** test_get_name&lt;br /&gt;
** test_get_directory&lt;br /&gt;
** test_get_creation_date&lt;br /&gt;
** test_get_modified_date&lt;br /&gt;
** test_get_teams&lt;br /&gt;
** test_get_parent_id&lt;br /&gt;
* test/unit/course_test.rb (previously existing test file)&lt;br /&gt;
** test_get_teams&lt;br /&gt;
** test_get_path&lt;br /&gt;
** test_get_participants&lt;br /&gt;
** test_get_participant&lt;br /&gt;
** test_add_participant&lt;br /&gt;
** test_copy_participants&lt;br /&gt;
* test/unit/course_participant_test.rb (previously existing test file)&lt;br /&gt;
** test_get_course_string&lt;br /&gt;
** test_import&lt;br /&gt;
** test_get_path&lt;br /&gt;
** test_export&lt;br /&gt;
** test_get_export_field&lt;br /&gt;
* test/unit/course_team_test.rb (new test file)&lt;br /&gt;
** test_retrieval&lt;br /&gt;
** test_import_participants&lt;br /&gt;
** test_export_participants&lt;br /&gt;
** test_instance_export&lt;br /&gt;
** test_handle_duplicate&lt;br /&gt;
** test_import&lt;br /&gt;
** test_class_export&lt;br /&gt;
&lt;br /&gt;
== List of Modified Unit Tests ==&lt;br /&gt;
The following unit test files and/or testcases were modified:&lt;br /&gt;
* test/unit/course_test.rb&lt;br /&gt;
** The line &amp;quot;fixtures :courses&amp;quot; was changed to &amp;quot;fixtures :courses,:teams,:users,:participants,:assignments,:nodes,:tree_folders&amp;quot;.&lt;/div&gt;</summary>
		<author><name>Kbyarbor</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2013/OSS_E608&amp;diff=74283</id>
		<title>CSC/ECE 517 Spring 2013/OSS E608</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2013/OSS_E608&amp;diff=74283"/>
		<updated>2013-03-21T03:05:25Z</updated>

		<summary type="html">&lt;p&gt;Kbyarbor: /* E608. Refactoring and Testing - Course Related Classes */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[https://docs.google.com/a/ncsu.edu/document/d/1SVNx7Eh6dUdrz2a9rGSgBxLkxAmuBUm8eu08nHEdjIg/edit# Write-up of This Topic.]&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
= E608. Refactoring and Testing - Course Related Classes =&lt;br /&gt;
Classes Involved:&lt;br /&gt;
*/app/models/course.rb (76 lines)&lt;br /&gt;
*/app/models/course_participant.rb (94 lines)&lt;br /&gt;
*/app/models/course_team.rb (116 lines)&lt;br /&gt;
*/app/models/course_node.rb (95 lines)&lt;br /&gt;
&lt;br /&gt;
What it does: &lt;br /&gt;
Involves creation and management of courses in Expertiza&lt;br /&gt;
&lt;br /&gt;
What needs to be done:&lt;br /&gt;
*It is not clear what a method named 'create_node' is doing in the 'course' class. Refactor by renaming this method appropriately.&lt;br /&gt;
*In the course_team class the import method seems to be doing too many things. See if this method can be broken down into smaller methods with specific functionality.&lt;br /&gt;
*The 'get' method in course_node.rb appears to be doing a lot. Refactor this method by breaking it up into smaller methods.&lt;br /&gt;
*Look for any unused methods or variables in these files.&lt;br /&gt;
*Also apply other refactorings such as Rename variable, Rename method to give the variables and methods more meaningful names.&lt;br /&gt;
*Write unit tests for all the methods in each of the listed model classes.&lt;br /&gt;
&lt;br /&gt;
== Changes for /app/models/course.rb ==&lt;br /&gt;
The following changes were made:&lt;br /&gt;
* Since the method create_node simply creates a course node associated with the newly created or copied course, we replaced its functionality by adding the line CourseNode.create(:node_object_id =&amp;gt; course.id) in the course_controller's create method and copy method. The function of getting the CourseNode's parent id is extracted as a class method of CourseNode model since this parent id is independent of the course. With all of its functionalities refactored to other places, this method is hereby removed. &lt;br /&gt;
* Added the line &amp;quot;has_many :assigments, :dependent =&amp;gt; :destroy&amp;quot; to allow CourseTest.test_destroy unit test to pass.&lt;br /&gt;
&lt;br /&gt;
== Changes for /app/models/course_participant.rb ==&lt;br /&gt;
* CourseParticipant.get_parent_name is removed&lt;br /&gt;
** This method is never called in the project.  Additionally, the method CourseParticipant.get_course_string provides the same functionality as CourseParticipant.get_parent_name, so it was deleted to follow the principle of DRY.&lt;br /&gt;
&lt;br /&gt;
== Changes for /app/models/course_team.rb ==&lt;br /&gt;
&lt;br /&gt;
=== ''import'' Method ===&lt;br /&gt;
Functionality: Import a single course team for a course from an input array. The first element in the array is optionally used to specify a name for the team that is being imported.&lt;br /&gt;
&lt;br /&gt;
Usage: The method is used by the import file controller to import course teams to a course.   &lt;br /&gt;
&lt;br /&gt;
==== Decomposition ====&lt;br /&gt;
The import method can be decomposed into 5 separate parts: &lt;br /&gt;
&lt;br /&gt;
===== Part 1 – Preparation =====&lt;br /&gt;
&lt;br /&gt;
Functionality: Ensure that the array has enough elements and that the class in which the user wants to import the team exists.  &lt;br /&gt;
&lt;br /&gt;
 if row.length &amp;lt; 2&lt;br /&gt;
     raise ArgumentError, &amp;quot;Not enough items&amp;quot; &lt;br /&gt;
 end &lt;br /&gt;
 course = Course.find(id)&lt;br /&gt;
 if course == nil&lt;br /&gt;
     raise ImportError, &amp;quot;The course with id \&amp;quot;&amp;quot;+id.to_s+&amp;quot;\&amp;quot; was not found. &amp;lt;a href='/assignment/new'&amp;gt;Create&amp;lt;/a&amp;gt; this assignment?&amp;quot;&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
===== Part 2 – Naming the New Team =====&lt;br /&gt;
&lt;br /&gt;
Functionality: The method will either import the team name from the array if has_column_name is set to true or generate a new team name if has_column_name is set to false.&lt;br /&gt;
&lt;br /&gt;
 if options[:has_column_names] == &amp;quot;true&amp;quot;&lt;br /&gt;
     name = row[0].to_s.strip&lt;br /&gt;
     index = 1&lt;br /&gt;
 else&lt;br /&gt;
     name = generate_team_name()&lt;br /&gt;
     index = 0&lt;br /&gt;
 end &lt;br /&gt;
&lt;br /&gt;
===== Part 3 – Handling Duplicate Team =====&lt;br /&gt;
&lt;br /&gt;
Functionality: If a team with the same team name exists, this part of the method will handle the conflict based on the option handle_duplicate.&lt;br /&gt;
&lt;br /&gt;
 currTeam = CourseTeam.find(:first, :conditions =&amp;gt; [&amp;quot;name =? and parent_id =?&amp;quot;,name,course.id])  &lt;br /&gt;
 if options[:handle_dups] == &amp;quot;ignore&amp;quot; &amp;amp;&amp;amp; currTeam != nil&lt;br /&gt;
     return&lt;br /&gt;
 end  &lt;br /&gt;
 if currTeam != nil &amp;amp;&amp;amp; options[:handle_dups] == &amp;quot;rename&amp;quot;&lt;br /&gt;
     name = generate_team_name()&lt;br /&gt;
     currTeam = nil&lt;br /&gt;
 end&lt;br /&gt;
 if options[:handle_dups] == &amp;quot;replace&amp;quot; &amp;amp;&amp;amp; teams.first != nil        &lt;br /&gt;
 for teamsuser in TeamsUser.find(:all, :conditions =&amp;gt; [&amp;quot;team_id =?&amp;quot;, currTeam.id])&lt;br /&gt;
     teamsuser.destroy&lt;br /&gt;
     end    &lt;br /&gt;
     currTeam.destroy&lt;br /&gt;
     currTeam = nil&lt;br /&gt;
 end     &lt;br /&gt;
    &lt;br /&gt;
===== Part 4 – Create the New Team and Node =====&lt;br /&gt;
&lt;br /&gt;
Functionality: Creates a new team and team node base on the information gathered by the above parts.&lt;br /&gt;
&lt;br /&gt;
 if currTeam == nil&lt;br /&gt;
     currTeam = CourseTeam.new&lt;br /&gt;
     currTeam.name = name&lt;br /&gt;
     currTeam.parent_id = course.id&lt;br /&gt;
     currTeam.save&lt;br /&gt;
     parent = CourseNode.find_by_node_object_id(course.id)&lt;br /&gt;
     TeamNode.create(:parent_id =&amp;gt; parent.id, :node_object_id =&amp;gt; currTeam.id)&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
===== Part 5 – Import the Participants to the New Team =====&lt;br /&gt;
&lt;br /&gt;
Functionality: Verify that the users specified in the array exist, then add the users to the newly created team.&lt;br /&gt;
&lt;br /&gt;
 while(index &amp;lt; row.length) &lt;br /&gt;
     user = User.find_by_name(row[index].to_s.strip)&lt;br /&gt;
     if user == nil&lt;br /&gt;
         raise ImportError, &amp;quot;The user \&amp;quot;&amp;quot;+row[index].to_s.strip+&amp;quot;\&amp;quot; was not found. &amp;lt;a href='/users/new'&amp;gt;Create&amp;lt;/a&amp;gt; this user?&amp;quot;                           &lt;br /&gt;
     elsif currTeam != nil         &lt;br /&gt;
         currUser = TeamsUser.find(:first, :conditions =&amp;gt; [&amp;quot;team_id =? and user_id =?&amp;quot;, currTeam.id,user.id])          &lt;br /&gt;
         if currUser == nil&lt;br /&gt;
             currTeam.add_member(user)            &lt;br /&gt;
         end                      &lt;br /&gt;
     end&lt;br /&gt;
     index = index+1      &lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
==== Refactor ====&lt;br /&gt;
From the decomposition, Part 5 can be seen as needing to be separated into its own method. &lt;br /&gt;
&lt;br /&gt;
  def import_participants(starting_index, row)&lt;br /&gt;
    index = starting_index&lt;br /&gt;
    while(index &amp;lt; row.length)&lt;br /&gt;
      user = User.find_by_name(row[index].to_s.strip)&lt;br /&gt;
      if user.nil?&lt;br /&gt;
        raise ImportError, &amp;quot;The user \&amp;quot;&amp;quot;+row[index].to_s.strip+&amp;quot;\&amp;quot; was not found. &amp;lt;a href='/users/new'&amp;gt;Create&amp;lt;/a&amp;gt; this user?&amp;quot;&lt;br /&gt;
      else&lt;br /&gt;
        if TeamsUser.find(:first, :conditions =&amp;gt; [&amp;quot;team_id =? and user_id =?&amp;quot;, id, user.id]).nil?&lt;br /&gt;
          add_member(user)&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
      index = index + 1&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
From the decomposition, the logic of Part 2 and Part 3 show that they could be simplified. Originally, Part 4 was executed regardless of if the team name was generated or imported. However, if the team name is generated instead of imported, there will not be another team with the same name. Therefore, we extracted Part 4 into its own method and modified the logic of Part 3.&lt;br /&gt;
&lt;br /&gt;
  def self.handle_duplicate(name, course_id, handle_dups)&lt;br /&gt;
    team = find(:first, :conditions =&amp;gt; [&amp;quot;name =? and parent_id =?&amp;quot;, name, course_id])&lt;br /&gt;
    if team.nil? #no duplicate&lt;br /&gt;
      return name&lt;br /&gt;
    end&lt;br /&gt;
    if handle_dups == &amp;quot;ignore&amp;quot; #ignore: not create the new team&lt;br /&gt;
      return nil&lt;br /&gt;
    end&lt;br /&gt;
    if handle_dups == &amp;quot;rename&amp;quot; #rename: rename new team&lt;br /&gt;
      return generate_team_name&lt;br /&gt;
    end&lt;br /&gt;
    if handle_dups == &amp;quot;replace&amp;quot; #replace: delete old team&lt;br /&gt;
      team.delete&lt;br /&gt;
      return name&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
After the modifications to Part 3 and Part 4 are completed, the import method becomes:&lt;br /&gt;
 &lt;br /&gt;
    if options[:has_column_names] == &amp;quot;true&amp;quot;&lt;br /&gt;
      name = row[0].to_s.strip&lt;br /&gt;
      name = handle_duplicate(name, course_id, options[:handle_dups])&lt;br /&gt;
      index = 1&lt;br /&gt;
    else&lt;br /&gt;
      name = generate_team_name&lt;br /&gt;
      index = 0&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
==== Miscellaneous Changes ====&lt;br /&gt;
The condition in Part 1 is incorrect because the number of elements could be less than 2 if the array does not have a team name column.&lt;br /&gt;
&lt;br /&gt;
 if (row.length &amp;lt; 2 and options[:has_column_names] == &amp;quot;true&amp;quot;) or (row.length &amp;lt; 1 and options[:has_column_names] != &amp;quot;true&amp;quot;)&lt;br /&gt;
   raise ArgumentError, &amp;quot;Not enough items&amp;quot;&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
Part 4 of the method was simplified to improve the readability.&lt;br /&gt;
&lt;br /&gt;
 team = CourseTeam.create(:name =&amp;gt; name, :parent_id =&amp;gt; course_id)&lt;br /&gt;
 course_node = CourseNode.find_by_node_object_id(course_id)&lt;br /&gt;
 TeamNode.create(:parent_id =&amp;gt; course_node.id, :node_object_id =&amp;gt; team.id)&lt;br /&gt;
&lt;br /&gt;
==== Other Issues ====&lt;br /&gt;
The input variable session was unused in the method; therefore, it needed to be removed.  However, this change was not made in this project due to the way that the method is being called in the import file controller.&lt;br /&gt;
&lt;br /&gt;
=== ''export'' Method ===&lt;br /&gt;
==== Functionality Bug ====&lt;br /&gt;
Originally, the export method in the CourseTeam class exported the assignment teams that were associated with the course to which a course team belonged.  This is not the behavior that one would expect from the export method in the CourseTeam class. &lt;br /&gt;
&lt;br /&gt;
Upon examining the AssignmentTeam class, the export method for CourseTeam was determined to export all of the course teams associated with a course. &lt;br /&gt;
&lt;br /&gt;
 def self.export(csv, parent_id, options)&lt;br /&gt;
    currentCourse = Course.find(parent_id)&lt;br /&gt;
    currentCourse.teams.each { |team|&lt;br /&gt;
      tcsv = Array.new&lt;br /&gt;
      teamUsers = Array.new&lt;br /&gt;
      tcsv.push(team.name)&lt;br /&gt;
      if (options[&amp;quot;team_name&amp;quot;] == &amp;quot;false&amp;quot;)&lt;br /&gt;
        teamMembers = TeamsUser.find(:all, :conditions =&amp;gt; ['team_id = ?', team.id])&lt;br /&gt;
        teamMembers.each do |user|&lt;br /&gt;
          teamUsers.push(user.name)&lt;br /&gt;
          teamUsers.push(&amp;quot; &amp;quot;)&lt;br /&gt;
        end&lt;br /&gt;
        tcsv.push(teamUsers)&lt;br /&gt;
      end&lt;br /&gt;
      tcsv.push(currentCourse.name)&lt;br /&gt;
      csv &amp;lt;&amp;lt; tcsv&lt;br /&gt;
    }&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
Note that this is a direct port of code from the source of the export function in the AssignmentTeam class.&lt;br /&gt;
&lt;br /&gt;
The original export function was renamed to export_all_assignment_team_related_to_course to reflect its actual functionality.  The function was marked deprecated and if the functionality is later found to be needed, the function should be re-written and moved to the Course class. &lt;br /&gt;
&lt;br /&gt;
==== Analysis and Refactor ====&lt;br /&gt;
The part of the export method within the if block is used to export all of the participants of a team.  This part can be separated into its own method to reduce the complexity of the export method. &lt;br /&gt;
&lt;br /&gt;
  def export_participants&lt;br /&gt;
    userNames = Array.new&lt;br /&gt;
    participants = TeamsUser.find(:all, :conditions =&amp;gt; ['team_id = ?', self.id])&lt;br /&gt;
    participants.each do |participant|&lt;br /&gt;
      userNames.push(participant.name)&lt;br /&gt;
      userNames.push(&amp;quot; &amp;quot;)&lt;br /&gt;
    end&lt;br /&gt;
    return userNames&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
Furthermore, an instance method was added to the CourseTeam class to export the team.  The class method export can call the instance method to reduce the complexity and improve the readability.&lt;br /&gt;
&lt;br /&gt;
  def export(team_name_only)&lt;br /&gt;
    output = Array.new&lt;br /&gt;
    output.push(self.name)&lt;br /&gt;
    if team_name_only == &amp;quot;false&amp;quot;&lt;br /&gt;
      output.push(self.export_participants)&lt;br /&gt;
    end&lt;br /&gt;
    course = Course.find(self.parent_id)&lt;br /&gt;
    output.push(course.name)&lt;br /&gt;
    return output&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
The export function as it looked after refactoring:&lt;br /&gt;
&lt;br /&gt;
  def self.export(csv, parent_id, options)&lt;br /&gt;
    course = Course.find(parent_id)&lt;br /&gt;
    if course.nil?&lt;br /&gt;
      raise ImportError, &amp;quot;The course with id \&amp;quot;&amp;quot;+course_id.to_s+&amp;quot;\&amp;quot; was not found. &amp;lt;a href='/assignment/new'&amp;gt;Create&amp;lt;/a&amp;gt; this course?&amp;quot;&lt;br /&gt;
    end&lt;br /&gt;
    teams = CourseTeam.find_all_by_parent_id(parent_id)&lt;br /&gt;
    teams.each do |team|&lt;br /&gt;
      csv &amp;lt;&amp;lt; team.export(options[:team_name])&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
==== Other Issues ====&lt;br /&gt;
The method name export does not accurately describe the functionality of this method.  It is recommended that this method name be changed to export_all. This change was not made due to the export method in the AssignmentTeam class and the way that the method is being called by the export file controller.&lt;br /&gt;
&lt;br /&gt;
The meaning of the option team_name in the method is ambiguous. Upon further examination, it was discovered that the option team_name controls if the method should only export team names without exporting the name of the participants in the team. This option should be renamed to team_name_only for better clarity.&lt;br /&gt;
&lt;br /&gt;
=== ''get_export_fields'' Method ===&lt;br /&gt;
Inferring from the code, the get_export_field method seems to return an array that contains the options used for controlling the export method.&lt;br /&gt;
&lt;br /&gt;
As discussed earlier, the team_name option for expert method controls if the export should contain the name of the team participants.&lt;br /&gt;
&lt;br /&gt;
Originally, the get_export_fields method will include the string “team member” if the option team_name is true. &lt;br /&gt;
&lt;br /&gt;
Furthermore, the get_export_fields method is trying to get the value of string(“team_name”) in hash variable options instead of symbol(:team_name).&lt;br /&gt;
&lt;br /&gt;
Here is the method after making the noted changes:&lt;br /&gt;
&lt;br /&gt;
  def self.get_export_fields(options)&lt;br /&gt;
    fields = Array.new&lt;br /&gt;
    fields.push(&amp;quot;Team Name&amp;quot;)&lt;br /&gt;
    if (options[:team_name] == &amp;quot;false&amp;quot;)&lt;br /&gt;
      fields.push(&amp;quot;Team members&amp;quot;)&lt;br /&gt;
    end&lt;br /&gt;
    fields.push(&amp;quot;Course Name&amp;quot;)&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
=== ''copy'' Method === &lt;br /&gt;
This method is inferred to be used to create a new assignment team and copy all of the participants of the course team to that new assignment team.&lt;br /&gt;
&lt;br /&gt;
If this is later confirmed to be the intended functionality of this method, then this method should belong to AssignmentTeam class instead of CourseTeam class.&lt;br /&gt;
&lt;br /&gt;
This method calls the create_node_object method in Team class, which does not work (explained in a later section) and has an ambiguous return type, functionality, and name.&lt;br /&gt;
&lt;br /&gt;
Logically, the copy method should create a new course team and copy the participants of a team into the new course team.&lt;br /&gt;
Currently, this is dead code and not used in the program.  &lt;br /&gt;
&lt;br /&gt;
This function was marked deprecated and it is recommended to be removed from the program.&lt;br /&gt;
&lt;br /&gt;
=== ''add_participant'' Method === &lt;br /&gt;
This method is used to add a participant to the course that the course team to which it belongs.&lt;br /&gt;
&lt;br /&gt;
This method is called by the add_member method in the Team class to add a participant to the course when a member is added to a course team.&lt;br /&gt;
&lt;br /&gt;
This method does belong in the Course class and not the CourseTeam class.  The Course class already has the method add_participant with similar functionality.&lt;br /&gt;
&lt;br /&gt;
This function was marked deprecated and it is recommended that the function should be removed from the program and the add_member method in the Team class should call the add_participant method from Course class.&lt;br /&gt;
&lt;br /&gt;
== Changes for /app/models/course_node.rb ==&lt;br /&gt;
* models/course_node.rb &lt;br /&gt;
** The &amp;quot;get&amp;quot; method was improved. &lt;br /&gt;
*** Added &amp;quot;get_courses_managed_by_user&amp;quot; method to hold logic extracted from the &amp;quot;get&amp;quot;method.  &lt;br /&gt;
*** Added &amp;quot;get_course_query_conditions&amp;quot; method to hold logic extracted from the &amp;quot;get&amp;quot; method.  &lt;br /&gt;
*** Modified any checks on if the user is a teaching assistant to use polymorphism to make the determination.  &lt;br /&gt;
*** Removed the initial conditional for setting the &amp;quot;conditions&amp;quot; value since the remaining conditions was overwriting the value regardless of how the initial conditional was evaluated. &lt;br /&gt;
*** Renaming the &amp;quot;get&amp;quot; method was considered; however, the name of the method is necessary for polymorphism reasons related to Assignment nodes.  As such, a comment was added to explain why the method name should remain.     &lt;br /&gt;
*** The &amp;quot;sortorder&amp;quot; parameter is given a default value of &amp;quot;ASC&amp;quot; for ascending.  This allowed for a related conditional to be removed from the method.  &lt;br /&gt;
*** The &amp;quot;sortvar&amp;quot; parameter is given a default value of &amp;quot;name&amp;quot; for sorting by course name.  This allowed for a related conditional to be removed from the method.&lt;br /&gt;
** Renaming the &amp;quot;get_children&amp;quot; method was considered; however, the name of the method is necessary for polymorphism reasons related to Assignment Nodes.  As such, a comment was added to explain why the method name should remain. &lt;br /&gt;
** The &amp;quot;get_survey_distribution_id&amp;quot; method was removed after finding it to be dead code.&lt;br /&gt;
* models/ta.rb&lt;br /&gt;
** Added &amp;quot;is_teaching_assistant?&amp;quot; method to override the inherited method from the User model.  This supported usage of polymorphism to determine if the user is a teaching assistant.  &lt;br /&gt;
* models/user.rb&lt;br /&gt;
** Added &amp;quot;is_teaching_assistant?&amp;quot; method to enable usage of polymorphism to determine if the user is a teaching assistant.&lt;br /&gt;
&lt;br /&gt;
== Methods Found That Are Not Currently Being Used ==&lt;br /&gt;
The following methods were not found to be used currently by the project, but have been left in the code for potential future usages of the functionality:&lt;br /&gt;
* /app/models/course.rb&lt;br /&gt;
** Course.get_participant(user_id)&lt;br /&gt;
* /app/models/course_participant.rb&lt;br /&gt;
** CourseParticipant.copy(assignment_id)&lt;br /&gt;
** CourseParticipant.get_parent_name&lt;br /&gt;
* /app/models/course_node.rb&lt;br /&gt;
** CourseNode.get_modified_date&lt;br /&gt;
&lt;br /&gt;
== Miscellaneous Changes for Quality Improvement and Readability ==&lt;br /&gt;
&lt;br /&gt;
== Other Observations and Suggestion for Future Work == &lt;br /&gt;
=== Redundant Code in Team Related Classes ===&lt;br /&gt;
Classes: Team, CourseTeam, AssignmentTeam&lt;br /&gt;
&lt;br /&gt;
Files: team.rb, course_team.rb, assignment_team.rb&lt;br /&gt;
&lt;br /&gt;
The class CourseTeam and AssignmentTeam both inherits from the class Team. However that are a lot of duplicated functionalities in order to adhere to the &amp;quot;DRY&amp;quot; principle refactor for the CourseTeam mentioned in this document should be applied to AssignmentTeam and duplicated methods should be extracted to the super-class Team.&lt;br /&gt;
&lt;br /&gt;
=== Naming Inconsistency in Team Related Classes ===&lt;br /&gt;
Classes: Team, CourseTeam, AssignmentTeam&lt;br /&gt;
&lt;br /&gt;
Files: team.rb, course_team.rb, assignment_team.rb&lt;br /&gt;
&lt;br /&gt;
Participant in a team have many different names in these three classes. For example: member, user, participants. Common vocabulary should be established in-order to eliminate confusion. &lt;br /&gt;
&lt;br /&gt;
=== Bugs in Team Class ===&lt;br /&gt;
Class: Team&lt;br /&gt;
&lt;br /&gt;
File: team.rb&lt;br /&gt;
&lt;br /&gt;
Method: create_node_object&lt;br /&gt;
&lt;br /&gt;
The create_node_object method in Team class does not work because the class method get_parent_model in both CourseTeam and Assignment team is an instance method not a class method.&lt;br /&gt;
&lt;br /&gt;
From the code of the object and the usage of this code we inferred that the method supposed to create a new course or assignment team and a new team node and return the newly created team as output.&lt;br /&gt;
This function should be deprecated and removed from the class, the functionality should be move to the new method in the team controller if the functionality is truly necessary.&lt;br /&gt;
&lt;br /&gt;
=== Inelegance Code in Team Class ===&lt;br /&gt;
Class: Team&lt;br /&gt;
&lt;br /&gt;
File: team.rb&lt;br /&gt;
&lt;br /&gt;
Methods: randomize_all_by_parent, check_for_existing, create_node_object, copy_members&lt;br /&gt;
&lt;br /&gt;
These methods uses Object.const_get() with a input string that dynamically locate the object that are associated with different team types (assignment or course) however  the use of Object.const_get() are inconsistent throughout these methods.&lt;br /&gt;
&lt;br /&gt;
We suggests instead of using query methods such as get_participant_type  and get_parent_model  in the assignment and course team return string containing the name of the object we can use these method to return the object itself thus eliminating the need for Object.const_get().&lt;br /&gt;
&lt;br /&gt;
== List of New Unit Tests and Testcases ==&lt;br /&gt;
The following lists shows new unit files and/or new testcases:&lt;br /&gt;
* test/unit/course_node_test.rb (new test file)&lt;br /&gt;
** test_get_children_with_show_true_and_non_TA_and_ascending_order_by_name&lt;br /&gt;
** test_get_children_with_show_true_and_non_TA_and_descending_order_by_name&lt;br /&gt;
** test_get_children_with_show_true_and_TA_and_ascending_order_by_name&lt;br /&gt;
** test_get_children_with_show_true_and_TA_and_descending_order_by_name&lt;br /&gt;
** test_get_children_with_show_false_and_non_TA_and_ascending_order_by_name&lt;br /&gt;
** test_get_children_with_show_false_and_non_TA_and_descending_order_by_name&lt;br /&gt;
** test_get_children_with_show_false_and_TA_and_ascending_order_by_name&lt;br /&gt;
** test_get_children_with_show_false_and_TA_and_descending_order_by_name&lt;br /&gt;
** test_get_children_with_show_false_and_non_TA_and_nil_order_by_nil&lt;br /&gt;
** test_get_name&lt;br /&gt;
** test_get_directory&lt;br /&gt;
** test_get_creation_date&lt;br /&gt;
** test_get_modified_date&lt;br /&gt;
** test_get_teams&lt;br /&gt;
** test_get_parent_id&lt;br /&gt;
* test/unit/course_test.rb (previously existing test file)&lt;br /&gt;
** test_get_teams&lt;br /&gt;
** test_get_path&lt;br /&gt;
** test_get_participants&lt;br /&gt;
** test_get_participant&lt;br /&gt;
** test_add_participant&lt;br /&gt;
** test_copy_participants&lt;br /&gt;
* test/unit/course_participant_test.rb (previously existing test file)&lt;br /&gt;
** test_get_course_string&lt;br /&gt;
** test_import&lt;br /&gt;
** test_get_path&lt;br /&gt;
** test_export&lt;br /&gt;
** test_get_export_field&lt;br /&gt;
* test/unit/course_team_test.rb (new test file)&lt;br /&gt;
** test_retrieval&lt;br /&gt;
** test_import_participants&lt;br /&gt;
** test_export_participants&lt;br /&gt;
** test_instance_export&lt;br /&gt;
** test_handle_duplicate&lt;br /&gt;
** test_import&lt;br /&gt;
** test_class_export&lt;br /&gt;
&lt;br /&gt;
== List of Modified Unit Tests ==&lt;br /&gt;
The following unit test files and/or testcases were modified:&lt;br /&gt;
* test/unit/course_test.rb&lt;br /&gt;
** The line &amp;quot;fixtures :courses&amp;quot; was changed to &amp;quot;fixtures :courses,:teams,:users,:participants,:assignments,:nodes,:tree_folders&amp;quot;.&lt;/div&gt;</summary>
		<author><name>Kbyarbor</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2013/OSS_E608&amp;diff=74274</id>
		<title>CSC/ECE 517 Spring 2013/OSS E608</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2013/OSS_E608&amp;diff=74274"/>
		<updated>2013-03-21T02:51:15Z</updated>

		<summary type="html">&lt;p&gt;Kbyarbor: /* E608. Refactoring and Testing - Course Related Classes */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[https://docs.google.com/a/ncsu.edu/document/d/1SVNx7Eh6dUdrz2a9rGSgBxLkxAmuBUm8eu08nHEdjIg/edit# Write-up of This Topic.]&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
= E608. Refactoring and Testing - Course Related Classes =&lt;br /&gt;
Classes Involved:&lt;br /&gt;
*/app/models/course.rb (76 lines)&lt;br /&gt;
*/app/models/course_participant.rb (94 lines)&lt;br /&gt;
*/app/models/course_team.rb (116 lines)&lt;br /&gt;
*/app/models/course_node.rb (95 lines)&lt;br /&gt;
&lt;br /&gt;
What it does: &lt;br /&gt;
Involves creation and management of courses in Expertiza&lt;br /&gt;
&lt;br /&gt;
What needs to be done:&lt;br /&gt;
*It is not clear what a method named 'create_node' is doing in the 'course' class. Refactor by renaming this method appropriately.&lt;br /&gt;
*In the course_team class the import method seems to be doing too many things. See if this method can be broken down into smaller methods with specific functionality.&lt;br /&gt;
*The 'get' method in course_node.rb appears to be doing a lot. Refactor this method by breaking it up into smaller methods.&lt;br /&gt;
*Look for any unused methods or variables in these files.&lt;br /&gt;
*Also apply other refactorings such as Rename variable, Rename method to give the variables and methods more meaningful names.&lt;br /&gt;
*Write unit tests for all the methods in each of the listed model classes.&lt;br /&gt;
&lt;br /&gt;
== Changes for /app/models/course.rb ==&lt;br /&gt;
The following changes were made:&lt;br /&gt;
* Since the method create_node simply creates a course node associated with the newly created or copied course, we replaced its functionality by adding the line CourseNode.create(:node_object_id =&amp;gt; course.id) in the course_controller's create method and copy method. The function of getting the CourseNode's parent id is extracted as a class method of CourseNode model since this parent id is independent of the course. With all of its functionalities refactored to other places, this method is hereby removed. &lt;br /&gt;
* Added the line &amp;quot;has_many :assigments, :dependent =&amp;gt; :destroy&amp;quot; to allow CourseTest.test_destroy unit test to pass.&lt;br /&gt;
&lt;br /&gt;
== Changes for /app/models/course_participant.rb ==&lt;br /&gt;
* CourseParticipant.get_parent_name is removed&lt;br /&gt;
** This method is never called in the project.  Additionally, the method CourseParticipant.get_course_string provides the same functionality as CourseParticipant.get_parent_name, so it was deleted to follow the principle of DRY.&lt;br /&gt;
&lt;br /&gt;
== Changes for /app/models/course_team.rb ==&lt;br /&gt;
&lt;br /&gt;
=== ''import'' Method ===&lt;br /&gt;
Functionality: Import a single course team for a course from an input array. The first element in the array is optionally used to specify a name for the team that is being imported.&lt;br /&gt;
&lt;br /&gt;
Usage: The method is used by the import file controller to import course teams to a course.   &lt;br /&gt;
&lt;br /&gt;
==== Decomposition ====&lt;br /&gt;
The import method can be decomposed into 5 separate parts: &lt;br /&gt;
&lt;br /&gt;
===== Part 1 – Preparation =====&lt;br /&gt;
&lt;br /&gt;
Functionality: Ensure that the array has enough elements and that the class in which the user wants to import the team exists.  &lt;br /&gt;
&lt;br /&gt;
 if row.length &amp;lt; 2&lt;br /&gt;
     raise ArgumentError, &amp;quot;Not enough items&amp;quot; &lt;br /&gt;
 end &lt;br /&gt;
 course = Course.find(id)&lt;br /&gt;
 if course == nil&lt;br /&gt;
     raise ImportError, &amp;quot;The course with id \&amp;quot;&amp;quot;+id.to_s+&amp;quot;\&amp;quot; was not found. &amp;lt;a href='/assignment/new'&amp;gt;Create&amp;lt;/a&amp;gt; this assignment?&amp;quot;&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
===== Part 2 – Naming the New Team =====&lt;br /&gt;
&lt;br /&gt;
Functionality: The method will either import the team name from the array if has_column_name is set to true or generate a new team name if has_column_name is set to false.&lt;br /&gt;
&lt;br /&gt;
 if options[:has_column_names] == &amp;quot;true&amp;quot;&lt;br /&gt;
     name = row[0].to_s.strip&lt;br /&gt;
     index = 1&lt;br /&gt;
 else&lt;br /&gt;
     name = generate_team_name()&lt;br /&gt;
     index = 0&lt;br /&gt;
 end &lt;br /&gt;
&lt;br /&gt;
===== Part 3 – Handling Duplicate Team =====&lt;br /&gt;
&lt;br /&gt;
Functionality: If a team with the same team name exists, this part of the method will handle the conflict based on the option handle_duplicate.&lt;br /&gt;
&lt;br /&gt;
 currTeam = CourseTeam.find(:first, :conditions =&amp;gt; [&amp;quot;name =? and parent_id =?&amp;quot;,name,course.id])  &lt;br /&gt;
 if options[:handle_dups] == &amp;quot;ignore&amp;quot; &amp;amp;&amp;amp; currTeam != nil&lt;br /&gt;
     return&lt;br /&gt;
 end  &lt;br /&gt;
 if currTeam != nil &amp;amp;&amp;amp; options[:handle_dups] == &amp;quot;rename&amp;quot;&lt;br /&gt;
     name = generate_team_name()&lt;br /&gt;
     currTeam = nil&lt;br /&gt;
 end&lt;br /&gt;
 if options[:handle_dups] == &amp;quot;replace&amp;quot; &amp;amp;&amp;amp; teams.first != nil        &lt;br /&gt;
 for teamsuser in TeamsUser.find(:all, :conditions =&amp;gt; [&amp;quot;team_id =?&amp;quot;, currTeam.id])&lt;br /&gt;
     teamsuser.destroy&lt;br /&gt;
     end    &lt;br /&gt;
     currTeam.destroy&lt;br /&gt;
     currTeam = nil&lt;br /&gt;
 end     &lt;br /&gt;
    &lt;br /&gt;
===== Part 4 – Create the New Team and Node =====&lt;br /&gt;
&lt;br /&gt;
Functionality: Creates a new team and team node base on the information gathered by the above parts.&lt;br /&gt;
&lt;br /&gt;
 if currTeam == nil&lt;br /&gt;
     currTeam = CourseTeam.new&lt;br /&gt;
     currTeam.name = name&lt;br /&gt;
     currTeam.parent_id = course.id&lt;br /&gt;
     currTeam.save&lt;br /&gt;
     parent = CourseNode.find_by_node_object_id(course.id)&lt;br /&gt;
     TeamNode.create(:parent_id =&amp;gt; parent.id, :node_object_id =&amp;gt; currTeam.id)&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
===== Part 5 – Import the Participants to the New Team =====&lt;br /&gt;
&lt;br /&gt;
Functionality: Verify that the users specified in the array exist, then add the users to the newly created team.&lt;br /&gt;
&lt;br /&gt;
 while(index &amp;lt; row.length) &lt;br /&gt;
     user = User.find_by_name(row[index].to_s.strip)&lt;br /&gt;
     if user == nil&lt;br /&gt;
         raise ImportError, &amp;quot;The user \&amp;quot;&amp;quot;+row[index].to_s.strip+&amp;quot;\&amp;quot; was not found. &amp;lt;a href='/users/new'&amp;gt;Create&amp;lt;/a&amp;gt; this user?&amp;quot;                           &lt;br /&gt;
     elsif currTeam != nil         &lt;br /&gt;
         currUser = TeamsUser.find(:first, :conditions =&amp;gt; [&amp;quot;team_id =? and user_id =?&amp;quot;, currTeam.id,user.id])          &lt;br /&gt;
         if currUser == nil&lt;br /&gt;
             currTeam.add_member(user)            &lt;br /&gt;
         end                      &lt;br /&gt;
     end&lt;br /&gt;
     index = index+1      &lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
==== Refactor ====&lt;br /&gt;
From the decomposition, Part 5 can be seen as needing to be separated into its own method. &lt;br /&gt;
&lt;br /&gt;
  def import_participants(starting_index, row)&lt;br /&gt;
    index = starting_index&lt;br /&gt;
    while(index &amp;lt; row.length)&lt;br /&gt;
      user = User.find_by_name(row[index].to_s.strip)&lt;br /&gt;
      if user.nil?&lt;br /&gt;
        raise ImportError, &amp;quot;The user \&amp;quot;&amp;quot;+row[index].to_s.strip+&amp;quot;\&amp;quot; was not found. &amp;lt;a href='/users/new'&amp;gt;Create&amp;lt;/a&amp;gt; this user?&amp;quot;&lt;br /&gt;
      else&lt;br /&gt;
        if TeamsUser.find(:first, :conditions =&amp;gt; [&amp;quot;team_id =? and user_id =?&amp;quot;, id, user.id]).nil?&lt;br /&gt;
          add_member(user)&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
      index = index + 1&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
From the decomposition, the logic of Part 2 and Part 3 show that they could be simplified. Originally, Part 4 was executed regardless of if the team name was generated or imported. However, if the team name is generated instead of imported, there will not be another team with the same name. Therefore, we extracted Part 4 into its own method and modified the logic of Part 3.&lt;br /&gt;
&lt;br /&gt;
  def self.handle_duplicate(name, course_id, handle_dups)&lt;br /&gt;
    team = find(:first, :conditions =&amp;gt; [&amp;quot;name =? and parent_id =?&amp;quot;, name, course_id])&lt;br /&gt;
    if team.nil? #no duplicate&lt;br /&gt;
      return name&lt;br /&gt;
    end&lt;br /&gt;
    if handle_dups == &amp;quot;ignore&amp;quot; #ignore: not create the new team&lt;br /&gt;
      return nil&lt;br /&gt;
    end&lt;br /&gt;
    if handle_dups == &amp;quot;rename&amp;quot; #rename: rename new team&lt;br /&gt;
      return generate_team_name&lt;br /&gt;
    end&lt;br /&gt;
    if handle_dups == &amp;quot;replace&amp;quot; #replace: delete old team&lt;br /&gt;
      team.delete&lt;br /&gt;
      return name&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
After the modifications to Part 3 and Part 4 are completed, the import method becomes:&lt;br /&gt;
 &lt;br /&gt;
    if options[:has_column_names] == &amp;quot;true&amp;quot;&lt;br /&gt;
      name = row[0].to_s.strip&lt;br /&gt;
      name = handle_duplicate(name, course_id, options[:handle_dups])&lt;br /&gt;
      index = 1&lt;br /&gt;
    else&lt;br /&gt;
      name = generate_team_name&lt;br /&gt;
      index = 0&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
==== Miscellaneous Changes ====&lt;br /&gt;
Check in part 1 is wrong because number of element can be less than 2 if the array does not have a team name column.&lt;br /&gt;
&lt;br /&gt;
 if (row.length &amp;lt; 2 and options[:has_column_names] == &amp;quot;true&amp;quot;) or (row.length &amp;lt; 1 and options[:has_column_names] != &amp;quot;true&amp;quot;)&lt;br /&gt;
   raise ArgumentError, &amp;quot;Not enough items&amp;quot;&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
Part 4 of the method was simplified to improve the readability.&lt;br /&gt;
&lt;br /&gt;
 team = CourseTeam.create(:name =&amp;gt; name, :parent_id =&amp;gt; course_id)&lt;br /&gt;
 course_node = CourseNode.find_by_node_object_id(course_id)&lt;br /&gt;
 TeamNode.create(:parent_id =&amp;gt; course_node.id, :node_object_id =&amp;gt; team.id)&lt;br /&gt;
&lt;br /&gt;
==== Other Issues ====&lt;br /&gt;
The input variable session was unused in the method therefore it should be removed, however due to the way that the method is being called in the import file controller this change was not made in this project.&lt;br /&gt;
&lt;br /&gt;
=== ''export'' Method ===&lt;br /&gt;
==== Functionality Bug ====&lt;br /&gt;
Originally the export method in the CourseTeam class export the assignment teams that are associated with the course that a course team belongs.  This is not the behavior that one would expect from the export method in the CourseTeam class. &lt;br /&gt;
&lt;br /&gt;
Upon examining the AssignmentTeam class and confirming with the professor we discover that the export method for CourseTeam should export all of the course teams associated with a course. &lt;br /&gt;
&lt;br /&gt;
 def self.export(csv, parent_id, options)&lt;br /&gt;
    currentCourse = Course.find(parent_id)&lt;br /&gt;
    currentCourse.teams.each { |team|&lt;br /&gt;
      tcsv = Array.new&lt;br /&gt;
      teamUsers = Array.new&lt;br /&gt;
      tcsv.push(team.name)&lt;br /&gt;
      if (options[&amp;quot;team_name&amp;quot;] == &amp;quot;false&amp;quot;)&lt;br /&gt;
        teamMembers = TeamsUser.find(:all, :conditions =&amp;gt; ['team_id = ?', team.id])&lt;br /&gt;
        teamMembers.each do |user|&lt;br /&gt;
          teamUsers.push(user.name)&lt;br /&gt;
          teamUsers.push(&amp;quot; &amp;quot;)&lt;br /&gt;
        end&lt;br /&gt;
        tcsv.push(teamUsers)&lt;br /&gt;
      end&lt;br /&gt;
      tcsv.push(currentCourse.name)&lt;br /&gt;
      csv &amp;lt;&amp;lt; tcsv&lt;br /&gt;
    }&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
Note that this is a director port from the source of export function in the AssignmentTeam class&lt;br /&gt;
&lt;br /&gt;
The original export function was rename to export_all_assignment_team_related_to_course to reflect its actually functionality &lt;br /&gt;
the function was marked deprecated and if the functionality was truly needed we suggest that function should be re-written and move to the Course class&lt;br /&gt;
&lt;br /&gt;
==== Analysis and Refactor ====&lt;br /&gt;
The part of the export method within the if block is use to export all of the participants of a team this part can be separated an turn into its own method to reduce the complexity of the export method&lt;br /&gt;
&lt;br /&gt;
  def export_participants&lt;br /&gt;
    userNames = Array.new&lt;br /&gt;
    participants = TeamsUser.find(:all, :conditions =&amp;gt; ['team_id = ?', self.id])&lt;br /&gt;
    participants.each do |participant|&lt;br /&gt;
      userNames.push(participant.name)&lt;br /&gt;
      userNames.push(&amp;quot; &amp;quot;)&lt;br /&gt;
    end&lt;br /&gt;
    return userNames&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
Furthermore, an instance method was added to the CourseTeam class to export the team and the class method export can call the instance method to reduce the complexity and improve the readability.&lt;br /&gt;
&lt;br /&gt;
  def export(team_name_only)&lt;br /&gt;
    output = Array.new&lt;br /&gt;
    output.push(self.name)&lt;br /&gt;
    if team_name_only == &amp;quot;false&amp;quot;&lt;br /&gt;
      output.push(self.export_participants)&lt;br /&gt;
    end&lt;br /&gt;
    course = Course.find(self.parent_id)&lt;br /&gt;
    output.push(course.name)&lt;br /&gt;
    return output&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
The export function after refactoring &lt;br /&gt;
&lt;br /&gt;
  def self.export(csv, parent_id, options)&lt;br /&gt;
    course = Course.find(parent_id)&lt;br /&gt;
    if course.nil?&lt;br /&gt;
      raise ImportError, &amp;quot;The course with id \&amp;quot;&amp;quot;+course_id.to_s+&amp;quot;\&amp;quot; was not found. &amp;lt;a href='/assignment/new'&amp;gt;Create&amp;lt;/a&amp;gt; this course?&amp;quot;&lt;br /&gt;
    end&lt;br /&gt;
    teams = CourseTeam.find_all_by_parent_id(parent_id)&lt;br /&gt;
    teams.each do |team|&lt;br /&gt;
      csv &amp;lt;&amp;lt; team.export(options[:team_name])&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
==== Other Issues ====&lt;br /&gt;
the method name export does not accurately describe the functionality of this method. We suggest that the name should be change to export_all. This change was not made due to the export method in the AssignmentTeam class and the way that the method is being called by the export file controller.&lt;br /&gt;
&lt;br /&gt;
The meaning of the option team_name in the method is ambiguous. Upon further examination we discover that the option team_name control if the method should only export team names without exporting the name of the participants in the team. This option should be renamed to team_name_only for better clarity.&lt;br /&gt;
&lt;br /&gt;
=== ''get_export_fields'' Method ===&lt;br /&gt;
Inferring from the code we think that get_export_field method supposed to returns an array that contains the options that used for controlling the export method.&lt;br /&gt;
&lt;br /&gt;
As we discussed earlier the team_name option for expert method controls if the export should contain the name of the team participants.&lt;br /&gt;
&lt;br /&gt;
Originally the get_export_fields method will include the string “team member” if the option team_name is true. This is the opposite of what we expected if our interpretation of the option team_name is correct. &lt;br /&gt;
&lt;br /&gt;
Further more the get_export_fields method is trying to get the value of string(“team_name”) in hash variable options instead of symbol(:team_name).&lt;br /&gt;
&lt;br /&gt;
After consulting with the professor we confirm that our suspicion is right and made the change accordingly &lt;br /&gt;
&lt;br /&gt;
  def self.get_export_fields(options)&lt;br /&gt;
    fields = Array.new&lt;br /&gt;
    fields.push(&amp;quot;Team Name&amp;quot;)&lt;br /&gt;
    if (options[:team_name] == &amp;quot;false&amp;quot;)&lt;br /&gt;
      fields.push(&amp;quot;Team members&amp;quot;)&lt;br /&gt;
    end&lt;br /&gt;
    fields.push(&amp;quot;Course Name&amp;quot;)&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
=== ''copy'' Method === &lt;br /&gt;
From reading the code we inferred that this method is used to create a new assignment team and copy all of the participants of the course team to that new assignment team.&lt;br /&gt;
&lt;br /&gt;
If this is truly the intended functionality of this method than this method should belongs to AssignmentTeam class instead of CourseTeam class.&lt;br /&gt;
&lt;br /&gt;
This method calls the create_node_object method in Team class which does not work (explained in the later section) and has ambiguous return type, functionality and name.&lt;br /&gt;
&lt;br /&gt;
Logically the copy method should create a new course team and copy the participants of a team into the new course team.&lt;br /&gt;
Currently this is dead code and not used in the program.  &lt;br /&gt;
&lt;br /&gt;
This function was marked deprecated and we suggest that the function should be removed from the program.&lt;br /&gt;
&lt;br /&gt;
=== ''add_participant'' Method === &lt;br /&gt;
From reading the code we inferred that this method is used to add a participant to the course that the course team belongs to.&lt;br /&gt;
&lt;br /&gt;
This method is called by the add_member method in the Team class to add a participant to the course when a member is added to a course team.&lt;br /&gt;
&lt;br /&gt;
This method does belong in the Course class and not the CourseTeam class.  The Course class already has the method add_participant with similar functionality.&lt;br /&gt;
&lt;br /&gt;
This function was marked deprecated and we suggest that the function should be removed from the program and the add_member method in the Team class should call the add_participant method from Course class.&lt;br /&gt;
&lt;br /&gt;
== Changes for /app/models/course_node.rb ==&lt;br /&gt;
* models/course_node.rb &lt;br /&gt;
** The &amp;quot;get&amp;quot; method was improved. &lt;br /&gt;
*** Added &amp;quot;get_courses_managed_by_user&amp;quot; method to hold logic extracted from the &amp;quot;get&amp;quot;method.  &lt;br /&gt;
*** Added &amp;quot;get_course_query_conditions&amp;quot; method to hold logic extracted from the &amp;quot;get&amp;quot; method.  &lt;br /&gt;
*** Modified any checks on if the user is a teaching assistant to use polymorphism to make the determination.  &lt;br /&gt;
*** Removed the initial conditional for setting the &amp;quot;conditions&amp;quot; value since the remaining conditions was overwriting the value regardless of how the initial conditional was evaluated. &lt;br /&gt;
*** Renaming the &amp;quot;get&amp;quot; method was considered; however, the name of the method is necessary for polymorphism reasons related to Assignment nodes.  As such, a comment was added to explain why the method name should remain.     &lt;br /&gt;
*** The &amp;quot;sortorder&amp;quot; parameter is given a default value of &amp;quot;ASC&amp;quot; for ascending.  This allowed for a related conditional to be removed from the method.  &lt;br /&gt;
*** The &amp;quot;sortvar&amp;quot; parameter is given a default value of &amp;quot;name&amp;quot; for sorting by course name.  This allowed for a related conditional to be removed from the method.&lt;br /&gt;
** Renaming the &amp;quot;get_children&amp;quot; method was considered; however, the name of the method is necessary for polymorphism reasons related to Assignment Nodes.  As such, a comment was added to explain why the method name should remain. &lt;br /&gt;
** The &amp;quot;get_survey_distribution_id&amp;quot; method was removed after finding it to be dead code.&lt;br /&gt;
* models/ta.rb&lt;br /&gt;
** Added &amp;quot;is_teaching_assistant?&amp;quot; method to override the inherited method from the User model.  This supported usage of polymorphism to determine if the user is a teaching assistant.  &lt;br /&gt;
* models/user.rb&lt;br /&gt;
** Added &amp;quot;is_teaching_assistant?&amp;quot; method to enable usage of polymorphism to determine if the user is a teaching assistant.&lt;br /&gt;
&lt;br /&gt;
== Methods Found That Are Not Currently Being Used ==&lt;br /&gt;
The following methods were not found to be used currently by the project, but have been left in the code for potential future usages of the functionality:&lt;br /&gt;
* /app/models/course.rb&lt;br /&gt;
** Course.get_participant(user_id)&lt;br /&gt;
* /app/models/course_participant.rb&lt;br /&gt;
** CourseParticipant.copy(assignment_id)&lt;br /&gt;
** CourseParticipant.get_parent_name&lt;br /&gt;
* /app/models/course_node.rb&lt;br /&gt;
** CourseNode.get_modified_date&lt;br /&gt;
&lt;br /&gt;
== Miscellaneous Changes for Quality Improvement and Readability ==&lt;br /&gt;
&lt;br /&gt;
== Other Observations and Suggestion for Future Work == &lt;br /&gt;
=== Redundant Code in Team Related Classes ===&lt;br /&gt;
Classes: Team, CourseTeam, AssignmentTeam&lt;br /&gt;
&lt;br /&gt;
Files: team.rb, course_team.rb, assignment_team.rb&lt;br /&gt;
&lt;br /&gt;
The class CourseTeam and AssignmentTeam both inherits from the class Team. However that are a lot of duplicated functionalities in order to adhere to the &amp;quot;DRY&amp;quot; principle refactor for the CourseTeam mentioned in this document should be applied to AssignmentTeam and duplicated methods should be extracted to the super-class Team.&lt;br /&gt;
&lt;br /&gt;
=== Naming Inconsistency in Team Related Classes ===&lt;br /&gt;
Classes: Team, CourseTeam, AssignmentTeam&lt;br /&gt;
&lt;br /&gt;
Files: team.rb, course_team.rb, assignment_team.rb&lt;br /&gt;
&lt;br /&gt;
Participant in a team have many different names in these three classes. For example: member, user, participants. Common vocabulary should be established in-order to eliminate confusion. &lt;br /&gt;
&lt;br /&gt;
=== Bugs in Team Class ===&lt;br /&gt;
Class: Team&lt;br /&gt;
&lt;br /&gt;
File: team.rb&lt;br /&gt;
&lt;br /&gt;
Method: create_node_object&lt;br /&gt;
&lt;br /&gt;
The create_node_object method in Team class does not work because the class method get_parent_model in both CourseTeam and Assignment team is an instance method not a class method.&lt;br /&gt;
&lt;br /&gt;
From the code of the object and the usage of this code we inferred that the method supposed to create a new course or assignment team and a new team node and return the newly created team as output.&lt;br /&gt;
This function should be deprecated and removed from the class, the functionality should be move to the new method in the team controller if the functionality is truly necessary.&lt;br /&gt;
&lt;br /&gt;
=== Inelegance Code in Team Class ===&lt;br /&gt;
Class: Team&lt;br /&gt;
&lt;br /&gt;
File: team.rb&lt;br /&gt;
&lt;br /&gt;
Methods: randomize_all_by_parent, check_for_existing, create_node_object, copy_members&lt;br /&gt;
&lt;br /&gt;
These methods uses Object.const_get() with a input string that dynamically locate the object that are associated with different team types (assignment or course) however  the use of Object.const_get() are inconsistent throughout these methods.&lt;br /&gt;
&lt;br /&gt;
We suggests instead of using query methods such as get_participant_type  and get_parent_model  in the assignment and course team return string containing the name of the object we can use these method to return the object itself thus eliminating the need for Object.const_get().&lt;br /&gt;
&lt;br /&gt;
== List of New Unit Tests and Testcases ==&lt;br /&gt;
The following lists shows new unit files and/or new testcases:&lt;br /&gt;
* test/unit/course_node_test.rb (new test file)&lt;br /&gt;
** test_get_children_with_show_true_and_non_TA_and_ascending_order_by_name&lt;br /&gt;
** test_get_children_with_show_true_and_non_TA_and_descending_order_by_name&lt;br /&gt;
** test_get_children_with_show_true_and_TA_and_ascending_order_by_name&lt;br /&gt;
** test_get_children_with_show_true_and_TA_and_descending_order_by_name&lt;br /&gt;
** test_get_children_with_show_false_and_non_TA_and_ascending_order_by_name&lt;br /&gt;
** test_get_children_with_show_false_and_non_TA_and_descending_order_by_name&lt;br /&gt;
** test_get_children_with_show_false_and_TA_and_ascending_order_by_name&lt;br /&gt;
** test_get_children_with_show_false_and_TA_and_descending_order_by_name&lt;br /&gt;
** test_get_children_with_show_false_and_non_TA_and_nil_order_by_nil&lt;br /&gt;
** test_get_name&lt;br /&gt;
** test_get_directory&lt;br /&gt;
** test_get_creation_date&lt;br /&gt;
** test_get_modified_date&lt;br /&gt;
** test_get_teams&lt;br /&gt;
** test_get_parent_id&lt;br /&gt;
* test/unit/course_test.rb (previously existing test file)&lt;br /&gt;
** test_get_teams&lt;br /&gt;
** test_get_path&lt;br /&gt;
** test_get_participants&lt;br /&gt;
** test_get_participant&lt;br /&gt;
** test_add_participant&lt;br /&gt;
** test_copy_participants&lt;br /&gt;
* test/unit/course_participant_test.rb (previously existing test file)&lt;br /&gt;
** test_get_course_string&lt;br /&gt;
** test_import&lt;br /&gt;
** test_get_path&lt;br /&gt;
** test_export&lt;br /&gt;
** test_get_export_field&lt;br /&gt;
* test/unit/course_team_test.rb (new test file)&lt;br /&gt;
** test_retrieval&lt;br /&gt;
** test_import_participants&lt;br /&gt;
** test_export_participants&lt;br /&gt;
** test_instance_export&lt;br /&gt;
** test_handle_duplicate&lt;br /&gt;
** test_import&lt;br /&gt;
** test_class_export&lt;br /&gt;
&lt;br /&gt;
== List of Modified Unit Tests ==&lt;br /&gt;
The following unit test files and/or testcases were modified:&lt;br /&gt;
* test/unit/course_test.rb&lt;br /&gt;
** The line &amp;quot;fixtures :courses&amp;quot; was changed to &amp;quot;fixtures :courses,:teams,:users,:participants,:assignments,:nodes,:tree_folders&amp;quot;.&lt;/div&gt;</summary>
		<author><name>Kbyarbor</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2013/OSS_E608&amp;diff=74231</id>
		<title>CSC/ECE 517 Spring 2013/OSS E608</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2013/OSS_E608&amp;diff=74231"/>
		<updated>2013-03-21T02:32:12Z</updated>

		<summary type="html">&lt;p&gt;Kbyarbor: /* Changes for models/course_team.rb */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[https://docs.google.com/a/ncsu.edu/document/d/1SVNx7Eh6dUdrz2a9rGSgBxLkxAmuBUm8eu08nHEdjIg/edit# Write-up of This Topic.]&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
= E608. Refactoring and Testing - Course Related Classes =&lt;br /&gt;
Classes Involved:&lt;br /&gt;
*models/course.rb (76 lines)&lt;br /&gt;
*models/course_participant.rb (94 lines)&lt;br /&gt;
*models/course_team.rb (116 lines)&lt;br /&gt;
*models/course_node.rb (95 lines)&lt;br /&gt;
&lt;br /&gt;
What it does: &lt;br /&gt;
Involves creation and management of courses in Expertiza&lt;br /&gt;
&lt;br /&gt;
What needs to be done:&lt;br /&gt;
*It is not clear what a method named 'create_node' is doing in the 'course' class. Refactor by renaming this method appropriately.&lt;br /&gt;
*In the course_team class the import method seems to be doing too many things. See if this method can be broken down into smaller methods with specific functionality.&lt;br /&gt;
*The 'get' method in course_node.rb appears to be doing a lot. Refactor this method by breaking it up into smaller methods.&lt;br /&gt;
*Look for any unused methods or variables in these files.&lt;br /&gt;
*Also apply other refactorings such as Rename variable, Rename method to give the variables and methods more meaningful names.&lt;br /&gt;
*Write unit tests for all the methods in each of the listed model classes.&lt;br /&gt;
&lt;br /&gt;
== Changes for models/course.rb ==&lt;br /&gt;
The following changes were made:&lt;br /&gt;
* Since the method create_node simply creates a course node associated with the newly created or copied course, we replaced its functionality by adding the line CourseNode.create(:node_object_id =&amp;gt; course.id) in the course_controller's create method and copy method. The function of getting the CourseNode's parent id is extracted as a class method of CourseNode model, since this parent id is independent of the course. With all of its functionalities refactored to other places, this method is hereby removed. &lt;br /&gt;
* Added the line &amp;quot;has_many :assigments, :dependent =&amp;gt; :destroy&amp;quot; to allow CourseTest.test_destroy unit test to pass.&lt;br /&gt;
&lt;br /&gt;
== Changes for models/course_participant.rb ==&lt;br /&gt;
* CourseParticipant.get_parent_name is removed&lt;br /&gt;
** This method is never called in the project, plus method CourseParticipant.get_course_string provides the same functionality as CourseParticipant.get_parent_name. So we deleted this method following the principle of DRY.&lt;br /&gt;
&lt;br /&gt;
== Changes for models/course_team.rb ==&lt;br /&gt;
File Location: /app/models/course_team.rb&lt;br /&gt;
&lt;br /&gt;
=== ''import'' Method ===&lt;br /&gt;
Functionality: import a single course team for a course from an input array. The first element in the array optionally used to specify a name for the team that’s being imported.&lt;br /&gt;
&lt;br /&gt;
Usage: the method is used by the import file controller to import course teams to a course.   &lt;br /&gt;
&lt;br /&gt;
==== Decomposition ====&lt;br /&gt;
The import method can be decompose into 5 separate parts &lt;br /&gt;
&lt;br /&gt;
Part 1 – Preparation&lt;br /&gt;
&lt;br /&gt;
Functionality: ensure that the array has enough elements also that the class that the use wishes to import the team to exist.&lt;br /&gt;
&lt;br /&gt;
 if row.length &amp;lt; 2&lt;br /&gt;
     raise ArgumentError, &amp;quot;Not enough items&amp;quot; &lt;br /&gt;
 end &lt;br /&gt;
 course = Course.find(id)&lt;br /&gt;
 if course == nil&lt;br /&gt;
     raise ImportError, &amp;quot;The course with id \&amp;quot;&amp;quot;+id.to_s+&amp;quot;\&amp;quot; was not found. &amp;lt;a href='/assignment/new'&amp;gt;Create&amp;lt;/a&amp;gt; this assignment?&amp;quot;&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
Part 2 – Naming the New Team&lt;br /&gt;
&lt;br /&gt;
Functionality: depending on the option has_column_name the method will either import the team name from the array if has_column_name is set to true or generate a new team name if has_column_name is set to false.&lt;br /&gt;
&lt;br /&gt;
 if options[:has_column_names] == &amp;quot;true&amp;quot;&lt;br /&gt;
     name = row[0].to_s.strip&lt;br /&gt;
     index = 1&lt;br /&gt;
 else&lt;br /&gt;
     name = generate_team_name()&lt;br /&gt;
     index = 0&lt;br /&gt;
 end &lt;br /&gt;
&lt;br /&gt;
Part 3 – Handling Duplicate Team&lt;br /&gt;
&lt;br /&gt;
Functionality: if a team with the same team name exist this part of the method will handle the conflict depending on the option handle_duplicate.&lt;br /&gt;
&lt;br /&gt;
 currTeam = CourseTeam.find(:first, :conditions =&amp;gt; [&amp;quot;name =? and parent_id =?&amp;quot;,name,course.id])  &lt;br /&gt;
 if options[:handle_dups] == &amp;quot;ignore&amp;quot; &amp;amp;&amp;amp; currTeam != nil&lt;br /&gt;
     return&lt;br /&gt;
 end  &lt;br /&gt;
 if currTeam != nil &amp;amp;&amp;amp; options[:handle_dups] == &amp;quot;rename&amp;quot;&lt;br /&gt;
     name = generate_team_name()&lt;br /&gt;
     currTeam = nil&lt;br /&gt;
 end&lt;br /&gt;
 if options[:handle_dups] == &amp;quot;replace&amp;quot; &amp;amp;&amp;amp; teams.first != nil        &lt;br /&gt;
 for teamsuser in TeamsUser.find(:all, :conditions =&amp;gt; [&amp;quot;team_id =?&amp;quot;, currTeam.id])&lt;br /&gt;
     teamsuser.destroy&lt;br /&gt;
     end    &lt;br /&gt;
     currTeam.destroy&lt;br /&gt;
     currTeam = nil&lt;br /&gt;
 end     &lt;br /&gt;
    &lt;br /&gt;
Part 4 – Create the New Team and Node&lt;br /&gt;
&lt;br /&gt;
Functionality: creates a new team and team node base on the information gather by the above parts.&lt;br /&gt;
&lt;br /&gt;
 if currTeam == nil&lt;br /&gt;
     currTeam = CourseTeam.new&lt;br /&gt;
     currTeam.name = name&lt;br /&gt;
     currTeam.parent_id = course.id&lt;br /&gt;
     currTeam.save&lt;br /&gt;
     parent = CourseNode.find_by_node_object_id(course.id)&lt;br /&gt;
     TeamNode.create(:parent_id =&amp;gt; parent.id, :node_object_id =&amp;gt; currTeam.id)&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
Part 5 – Import the Participants to the New Team&lt;br /&gt;
&lt;br /&gt;
Functionality: verify that the users specified in the array exist than add the users to the newly created team.&lt;br /&gt;
&lt;br /&gt;
 while(index &amp;lt; row.length) &lt;br /&gt;
     user = User.find_by_name(row[index].to_s.strip)&lt;br /&gt;
     if user == nil&lt;br /&gt;
         raise ImportError, &amp;quot;The user \&amp;quot;&amp;quot;+row[index].to_s.strip+&amp;quot;\&amp;quot; was not found. &amp;lt;a href='/users/new'&amp;gt;Create&amp;lt;/a&amp;gt; this user?&amp;quot;                           &lt;br /&gt;
     elsif currTeam != nil         &lt;br /&gt;
         currUser = TeamsUser.find(:first, :conditions =&amp;gt; [&amp;quot;team_id =? and user_id =?&amp;quot;, currTeam.id,user.id])          &lt;br /&gt;
         if currUser == nil&lt;br /&gt;
             currTeam.add_member(user)            &lt;br /&gt;
         end                      &lt;br /&gt;
     end&lt;br /&gt;
     index = index+1      &lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
==== Refactor ====&lt;br /&gt;
At the first glance from the decomposition we can clearly see that part 5 can be separated into its own method &lt;br /&gt;
&lt;br /&gt;
  def import_participants(starting_index, row)&lt;br /&gt;
    index = starting_index&lt;br /&gt;
    while(index &amp;lt; row.length)&lt;br /&gt;
      user = User.find_by_name(row[index].to_s.strip)&lt;br /&gt;
      if user.nil?&lt;br /&gt;
        raise ImportError, &amp;quot;The user \&amp;quot;&amp;quot;+row[index].to_s.strip+&amp;quot;\&amp;quot; was not found. &amp;lt;a href='/users/new'&amp;gt;Create&amp;lt;/a&amp;gt; this user?&amp;quot;&lt;br /&gt;
      else&lt;br /&gt;
        if TeamsUser.find(:first, :conditions =&amp;gt; [&amp;quot;team_id =? and user_id =?&amp;quot;, id, user.id]).nil?&lt;br /&gt;
          add_member(user)&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
      index = index + 1&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
From the decomposition we notice that the logic of part 2 and part 3 can be simplified. Originally, part 4 gets executed regardless if the team name is generated or imported. However, if the team name is generated instead of imported there will not be another team with the same name. Therefore, we extracted part 4 into its own method and modified the logic of part 3.&lt;br /&gt;
&lt;br /&gt;
  def self.handle_duplicate(name, course_id, handle_dups)&lt;br /&gt;
    team = find(:first, :conditions =&amp;gt; [&amp;quot;name =? and parent_id =?&amp;quot;, name, course_id])&lt;br /&gt;
    if team.nil? #no duplicate&lt;br /&gt;
      return name&lt;br /&gt;
    end&lt;br /&gt;
    if handle_dups == &amp;quot;ignore&amp;quot; #ignore: not create the new team&lt;br /&gt;
      return nil&lt;br /&gt;
    end&lt;br /&gt;
    if handle_dups == &amp;quot;rename&amp;quot; #rename: rename new team&lt;br /&gt;
      return generate_team_name&lt;br /&gt;
    end&lt;br /&gt;
    if handle_dups == &amp;quot;replace&amp;quot; #replace: delete old team&lt;br /&gt;
      team.delete&lt;br /&gt;
      return name&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
after modification part 3 and 4 in the import method becomes&lt;br /&gt;
 &lt;br /&gt;
    if options[:has_column_names] == &amp;quot;true&amp;quot;&lt;br /&gt;
      name = row[0].to_s.strip&lt;br /&gt;
      name = handle_duplicate(name, course_id, options[:handle_dups])&lt;br /&gt;
      index = 1&lt;br /&gt;
    else&lt;br /&gt;
      name = generate_team_name&lt;br /&gt;
      index = 0&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
==== Miscellaneous Changes ====&lt;br /&gt;
Check in part 1 is wrong because number of element can be less than 2 if the array does not have a team name column.&lt;br /&gt;
&lt;br /&gt;
 if (row.length &amp;lt; 2 and options[:has_column_names] == &amp;quot;true&amp;quot;) or (row.length &amp;lt; 1 and options[:has_column_names] != &amp;quot;true&amp;quot;)&lt;br /&gt;
   raise ArgumentError, &amp;quot;Not enough items&amp;quot;&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
Part 4 of the method was simplified to improve the readability.&lt;br /&gt;
&lt;br /&gt;
 team = CourseTeam.create(:name =&amp;gt; name, :parent_id =&amp;gt; course_id)&lt;br /&gt;
 course_node = CourseNode.find_by_node_object_id(course_id)&lt;br /&gt;
 TeamNode.create(:parent_id =&amp;gt; course_node.id, :node_object_id =&amp;gt; team.id)&lt;br /&gt;
&lt;br /&gt;
==== Other Issues ====&lt;br /&gt;
The input variable session was unused in the method therefore it should be removed, however due to the way that the method is being called in the import file controller this change was not made in this project.&lt;br /&gt;
&lt;br /&gt;
=== ''export'' Method ===&lt;br /&gt;
==== Functionality Bug ====&lt;br /&gt;
Originally the export method in the CourseTeam class export the assignment teams that are associated with the course that a course team belongs.  This is not the behavior that one would expect from the export method in the CourseTeam class. &lt;br /&gt;
&lt;br /&gt;
Upon examining the AssignmentTeam class and confirming with the professor we discover that the export method for CourseTeam should export all of the course teams associated with a course. &lt;br /&gt;
&lt;br /&gt;
 def self.export(csv, parent_id, options)&lt;br /&gt;
    currentCourse = Course.find(parent_id)&lt;br /&gt;
    currentCourse.teams.each { |team|&lt;br /&gt;
      tcsv = Array.new&lt;br /&gt;
      teamUsers = Array.new&lt;br /&gt;
      tcsv.push(team.name)&lt;br /&gt;
      if (options[&amp;quot;team_name&amp;quot;] == &amp;quot;false&amp;quot;)&lt;br /&gt;
        teamMembers = TeamsUser.find(:all, :conditions =&amp;gt; ['team_id = ?', team.id])&lt;br /&gt;
        teamMembers.each do |user|&lt;br /&gt;
          teamUsers.push(user.name)&lt;br /&gt;
          teamUsers.push(&amp;quot; &amp;quot;)&lt;br /&gt;
        end&lt;br /&gt;
        tcsv.push(teamUsers)&lt;br /&gt;
      end&lt;br /&gt;
      tcsv.push(currentCourse.name)&lt;br /&gt;
      csv &amp;lt;&amp;lt; tcsv&lt;br /&gt;
    }&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
Note that this is a director port from the source of export function in the AssignmentTeam class&lt;br /&gt;
&lt;br /&gt;
The original export function was rename to export_all_assignment_team_related_to_course to reflect its actually functionality &lt;br /&gt;
the function was marked deprecated and if the functionality was truly needed we suggest that function should be re-written and move to the Course class&lt;br /&gt;
&lt;br /&gt;
==== Analysis and Refactor ====&lt;br /&gt;
The part of the export method within the if block is use to export all of the participants of a team this part can be separated an turn into its own method to reduce the complexity of the export method&lt;br /&gt;
&lt;br /&gt;
  def export_participants&lt;br /&gt;
    userNames = Array.new&lt;br /&gt;
    participants = TeamsUser.find(:all, :conditions =&amp;gt; ['team_id = ?', self.id])&lt;br /&gt;
    participants.each do |participant|&lt;br /&gt;
      userNames.push(participant.name)&lt;br /&gt;
      userNames.push(&amp;quot; &amp;quot;)&lt;br /&gt;
    end&lt;br /&gt;
    return userNames&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
Furthermore, an instance method was added to the CourseTeam class to export the team and the class method export can call the instance method to reduce the complexity and improve the readability.&lt;br /&gt;
&lt;br /&gt;
  def export(team_name_only)&lt;br /&gt;
    output = Array.new&lt;br /&gt;
    output.push(self.name)&lt;br /&gt;
    if team_name_only == &amp;quot;false&amp;quot;&lt;br /&gt;
      output.push(self.export_participants)&lt;br /&gt;
    end&lt;br /&gt;
    course = Course.find(self.parent_id)&lt;br /&gt;
    output.push(course.name)&lt;br /&gt;
    return output&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
The export function after refactoring &lt;br /&gt;
&lt;br /&gt;
  def self.export(csv, parent_id, options)&lt;br /&gt;
    course = Course.find(parent_id)&lt;br /&gt;
    if course.nil?&lt;br /&gt;
      raise ImportError, &amp;quot;The course with id \&amp;quot;&amp;quot;+course_id.to_s+&amp;quot;\&amp;quot; was not found. &amp;lt;a href='/assignment/new'&amp;gt;Create&amp;lt;/a&amp;gt; this course?&amp;quot;&lt;br /&gt;
    end&lt;br /&gt;
    teams = CourseTeam.find_all_by_parent_id(parent_id)&lt;br /&gt;
    teams.each do |team|&lt;br /&gt;
      csv &amp;lt;&amp;lt; team.export(options[:team_name])&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
==== Other Issues ====&lt;br /&gt;
the method name export does not accurately describe the functionality of this method. We suggest that the name should be change to export_all. This change was not made due to the export method in the AssignmentTeam class and the way that the method is being called by the export file controller.&lt;br /&gt;
&lt;br /&gt;
The meaning of the option team_name in the method is ambiguous. Upon further examination we discover that the option team_name control if the method should only export team names without exporting the name of the participants in the team. This option should be renamed to team_name_only for better clarity.&lt;br /&gt;
&lt;br /&gt;
=== ''get_export_fields'' Method ===&lt;br /&gt;
Inferring from the code we think that get_export_field method supposed to returns an array that contains the options that used for controlling the export method.&lt;br /&gt;
&lt;br /&gt;
As we discussed earlier the team_name option for expert method controls if the export should contain the name of the team participants.&lt;br /&gt;
&lt;br /&gt;
Originally the get_export_fields method will include the string “team member” if the option team_name is true. This is the opposite of what we expected if our interpretation of the option team_name is correct. &lt;br /&gt;
&lt;br /&gt;
Further more the get_export_fields method is trying to get the value of string(“team_name”) in hash variable options instead of symbol(:team_name).&lt;br /&gt;
&lt;br /&gt;
After consulting with the professor we confirm that our suspicion is right and made the change accordingly &lt;br /&gt;
&lt;br /&gt;
  def self.get_export_fields(options)&lt;br /&gt;
    fields = Array.new&lt;br /&gt;
    fields.push(&amp;quot;Team Name&amp;quot;)&lt;br /&gt;
    if (options[:team_name] == &amp;quot;false&amp;quot;)&lt;br /&gt;
      fields.push(&amp;quot;Team members&amp;quot;)&lt;br /&gt;
    end&lt;br /&gt;
    fields.push(&amp;quot;Course Name&amp;quot;)&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
=== ''copy'' Method === &lt;br /&gt;
From reading the code we inferred that this method is used to create a new assignment team and copy all of the participants of the course team to that new assignment team.&lt;br /&gt;
&lt;br /&gt;
If this is truly the intended functionality of this method than this method should belongs to AssignmentTeam class instead of CourseTeam class.&lt;br /&gt;
&lt;br /&gt;
This method calls the create_node_object method in Team class which does not work (explained in the later section) and has ambiguous return type, functionality and name.&lt;br /&gt;
&lt;br /&gt;
Logically the copy method should create a new course team and copy the participants of a team into the new course team.&lt;br /&gt;
Currently this is dead code and not used in the program.  &lt;br /&gt;
&lt;br /&gt;
This function was marked deprecated and we suggest that the function should be removed from the program.&lt;br /&gt;
&lt;br /&gt;
=== ''add_participant'' Method === &lt;br /&gt;
From reading the code we inferred that this method is used to add a participant to the course that the course team belongs to.&lt;br /&gt;
&lt;br /&gt;
This method is called by the add_member method in the Team class to add a participant to the course when a member is added to a course team.&lt;br /&gt;
&lt;br /&gt;
This method does belong in the Course class and not the CourseTeam class.  The Course class already has the method add_participant with similar functionality.&lt;br /&gt;
&lt;br /&gt;
This function was marked deprecated and we suggest that the function should be removed from the program and the add_member method in the Team class should call the add_participant method from Course class.&lt;br /&gt;
&lt;br /&gt;
== Changes for models/course_node.rb ==&lt;br /&gt;
* models/course_node.rb &lt;br /&gt;
** The &amp;quot;get&amp;quot; method was improved. &lt;br /&gt;
*** Added &amp;quot;get_courses_managed_by_user&amp;quot; method to hold logic extracted from the &amp;quot;get&amp;quot;method.  &lt;br /&gt;
*** Added &amp;quot;get_course_query_conditions&amp;quot; method to hold logic extracted from the &amp;quot;get&amp;quot; method.  &lt;br /&gt;
*** Modified any checks on if the user is a teaching assistant to use polymorphism to make the determination.  &lt;br /&gt;
*** Removed the initial conditional for setting the &amp;quot;conditions&amp;quot; value since the remaining conditions was overwriting the value regardless of how the initial conditional was evaluated. &lt;br /&gt;
*** Renaming the &amp;quot;get&amp;quot; method was considered; however, the name of the method is necessary for polymorphism reasons related to Assignment nodes.  As such, a comment was added to explain why the method name should remain.     &lt;br /&gt;
*** The &amp;quot;sortorder&amp;quot; parameter is given a default value of &amp;quot;ASC&amp;quot; for ascending.  This allowed for a related conditional to be removed from the method.  &lt;br /&gt;
*** The &amp;quot;sortvar&amp;quot; parameter is given a default value of &amp;quot;name&amp;quot; for sorting by course name.  This allowed for a related conditional to be removed from the method.&lt;br /&gt;
** Renaming the &amp;quot;get_children&amp;quot; method was considered; however, the name of the method is necessary for polymorphism reasons related to Assignment Nodes.  As such, a comment was added to explain why the method name should remain. &lt;br /&gt;
** The &amp;quot;get_survey_distribution_id&amp;quot; method was removed after finding it to be dead code.&lt;br /&gt;
* models/ta.rb&lt;br /&gt;
** Added &amp;quot;is_teaching_assistant?&amp;quot; method to override the inherited method from the User model.  This supported usage of polymorphism to determine if the user is a teaching assistant.  &lt;br /&gt;
* models/user.rb&lt;br /&gt;
** Added &amp;quot;is_teaching_assistant?&amp;quot; method to enable usage of polymorphism to determine if the user is a teaching assistant.&lt;br /&gt;
&lt;br /&gt;
== Methods Found That Are Not Currently Being Used ==&lt;br /&gt;
The following methods were not found to be used currently by the project, but have been left in the code for potential future usages of the functionality:&lt;br /&gt;
* models/course.rb&lt;br /&gt;
** Course.get_participant(user_id)&lt;br /&gt;
* models/course_participant.rb&lt;br /&gt;
** CourseParticipant.copy(assignment_id)&lt;br /&gt;
** CourseParticipant.get_parent_name&lt;br /&gt;
* models/course_node.rb&lt;br /&gt;
** CourseNode.get_modified_date&lt;br /&gt;
&lt;br /&gt;
== Miscellaneous Changes for Quality Improvement and Readability ==&lt;br /&gt;
&lt;br /&gt;
== Other Observations and Suggestion for Future Work == &lt;br /&gt;
=== Redundant Code in Team Related Classes ===&lt;br /&gt;
Classes: Team, CourseTeam, AssignmentTeam&lt;br /&gt;
&lt;br /&gt;
Files: team.rb, course_team.rb, assignment_team.rb&lt;br /&gt;
&lt;br /&gt;
The class CourseTeam and AssignmentTeam both inherits from the class Team. However that are a lot of duplicated functionalities in order to adhere to the &amp;quot;DRY&amp;quot; principle refactor for the CourseTeam mentioned in this document should be applied to AssignmentTeam and duplicated methods should be extracted to the super-class Team.&lt;br /&gt;
&lt;br /&gt;
=== Naming Inconsistency in Team Related Classes ===&lt;br /&gt;
Classes: Team, CourseTeam, AssignmentTeam&lt;br /&gt;
&lt;br /&gt;
Files: team.rb, course_team.rb, assignment_team.rb&lt;br /&gt;
&lt;br /&gt;
Participant in a team have many different names in these three classes. For example: member, user, participants. Common vocabulary should be established in-order to eliminate confusion. &lt;br /&gt;
&lt;br /&gt;
=== Bugs in Team Class ===&lt;br /&gt;
Class: Team&lt;br /&gt;
&lt;br /&gt;
File: team.rb&lt;br /&gt;
&lt;br /&gt;
Method: create_node_object&lt;br /&gt;
&lt;br /&gt;
The create_node_object method in Team class does not work because the class method get_parent_model in both CourseTeam and Assignment team is an instance method not a class method.&lt;br /&gt;
&lt;br /&gt;
From the code of the object and the usage of this code we inferred that the method supposed to create a new course or assignment team and a new team node and return the newly created team as output.&lt;br /&gt;
This function should be deprecated and removed from the class, the functionality should be move to the new method in the team controller if the functionality is truly necessary.&lt;br /&gt;
&lt;br /&gt;
=== Inelegance Code in Team Class ===&lt;br /&gt;
Class: Team&lt;br /&gt;
&lt;br /&gt;
File: team.rb&lt;br /&gt;
&lt;br /&gt;
Methods: randomize_all_by_parent, check_for_existing, create_node_object, copy_members&lt;br /&gt;
&lt;br /&gt;
These methods uses Object.const_get() with a input string that dynamically locate the object that are associated with different team types (assignment or course) however  the use of Object.const_get() are inconsistent throughout these methods.&lt;br /&gt;
&lt;br /&gt;
We suggests instead of using query methods such as get_participant_type  and get_parent_model  in the assignment and course team return string containing the name of the object we can use these method to return the object itself thus eliminating the need for Object.const_get().&lt;br /&gt;
&lt;br /&gt;
== List of New Unit Tests and Testcases ==&lt;br /&gt;
The following lists shows new unit files and/or new testcases:&lt;br /&gt;
* test/unit/course_node_test.rb (new test file)&lt;br /&gt;
** test_get_children_with_show_true_and_non_TA_and_ascending_order_by_name&lt;br /&gt;
** test_get_children_with_show_true_and_non_TA_and_descending_order_by_name&lt;br /&gt;
** test_get_children_with_show_true_and_TA_and_ascending_order_by_name&lt;br /&gt;
** test_get_children_with_show_true_and_TA_and_descending_order_by_name&lt;br /&gt;
** test_get_children_with_show_false_and_non_TA_and_ascending_order_by_name&lt;br /&gt;
** test_get_children_with_show_false_and_non_TA_and_descending_order_by_name&lt;br /&gt;
** test_get_children_with_show_false_and_TA_and_ascending_order_by_name&lt;br /&gt;
** test_get_children_with_show_false_and_TA_and_descending_order_by_name&lt;br /&gt;
** test_get_children_with_show_false_and_non_TA_and_nil_order_by_nil&lt;br /&gt;
** test_get_name&lt;br /&gt;
** test_get_directory&lt;br /&gt;
** test_get_creation_date&lt;br /&gt;
** test_get_modified_date&lt;br /&gt;
** test_get_teams&lt;br /&gt;
** test_get_parent_id&lt;br /&gt;
* test/unit/course_test.rb (previously existing test file)&lt;br /&gt;
** test_get_teams&lt;br /&gt;
** test_get_path&lt;br /&gt;
** test_get_participants&lt;br /&gt;
** test_get_participant&lt;br /&gt;
** test_add_participant&lt;br /&gt;
** test_copy_participants&lt;br /&gt;
* test/unit/course_participant_test.rb (previously existing test file)&lt;br /&gt;
** test_get_course_string&lt;br /&gt;
** test_import&lt;br /&gt;
** test_get_path&lt;br /&gt;
** test_export&lt;br /&gt;
** test_get_export_field&lt;br /&gt;
* test/unit/course_team_test.rb (new test file)&lt;br /&gt;
** test_retrieval&lt;br /&gt;
** test_import_participants&lt;br /&gt;
** test_export_participants&lt;br /&gt;
** test_instance_export&lt;br /&gt;
** test_handle_duplicate&lt;br /&gt;
** test_import&lt;br /&gt;
** test_class_export&lt;br /&gt;
&lt;br /&gt;
== List of Modified Unit Tests ==&lt;br /&gt;
The following unit test files and/or testcases were modified:&lt;br /&gt;
* test/unit/course_test.rb&lt;br /&gt;
** The line &amp;quot;fixtures :courses&amp;quot; was changed to &amp;quot;fixtures :courses,:teams,:users,:participants,:assignments,:nodes,:tree_folders&amp;quot;.&lt;/div&gt;</summary>
		<author><name>Kbyarbor</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2013/OSS_E608&amp;diff=73870</id>
		<title>CSC/ECE 517 Spring 2013/OSS E608</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2013/OSS_E608&amp;diff=73870"/>
		<updated>2013-03-10T20:49:55Z</updated>

		<summary type="html">&lt;p&gt;Kbyarbor: /* Methods Found That Are Not Currently Being Used */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[https://docs.google.com/a/ncsu.edu/document/d/1SVNx7Eh6dUdrz2a9rGSgBxLkxAmuBUm8eu08nHEdjIg/edit# Write-up of This Topic.]&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
= E608. Refactoring and Testing - Course Related Classes =&lt;br /&gt;
Classes Involved:&lt;br /&gt;
*models/course.rb (76 lines)&lt;br /&gt;
*models/course_participant.rb (94 lines)&lt;br /&gt;
*models/course_team.rb (116 lines)&lt;br /&gt;
*models/course_node.rb (95 lines)&lt;br /&gt;
&lt;br /&gt;
What it does: &lt;br /&gt;
Involves creation and management of courses in Expertiza&lt;br /&gt;
&lt;br /&gt;
What needs to be done:&lt;br /&gt;
*It is not clear what a method named 'create_node' is doing in the 'course' class. Refactor by renaming this method appropriately.&lt;br /&gt;
*In the course_team class the import method seems to be doing too many things. See if this method can be broken down into smaller methods with specific functionality.&lt;br /&gt;
*The 'get' method in course_node.rb appears to be doing a lot. Refactor this method by breaking it up into smaller methods.&lt;br /&gt;
*Look for any unused methods or variables in these files.&lt;br /&gt;
*Also apply other refactorings such as Rename variable, Rename method to give the variables and methods more meaningful names.&lt;br /&gt;
*Write unit tests for all the methods in each of the listed model classes.&lt;br /&gt;
&lt;br /&gt;
== Changes for models/course.rb ==&lt;br /&gt;
The following changes were made:&lt;br /&gt;
* Renamed create_node method to create_course_node to accurately reflect the functionality of the method. &lt;br /&gt;
* Added the line &amp;quot;has_many :assigments, :dependent =&amp;gt; :destroy&amp;quot; to allow CourseTest.test_destroy unit test to pass.  &lt;br /&gt;
&lt;br /&gt;
== Changes for models/course_participant.rb ==&lt;br /&gt;
&lt;br /&gt;
== Changes for models/course_team.rb ==&lt;br /&gt;
&lt;br /&gt;
== Changes for models/course_node.rb ==&lt;br /&gt;
* models/course_node.rb &lt;br /&gt;
** The &amp;quot;get&amp;quot; method was improved. &lt;br /&gt;
*** Added &amp;quot;get_courses_managed_by_user&amp;quot; method to hold logic extracted from the &amp;quot;get&amp;quot;method.  &lt;br /&gt;
*** Added &amp;quot;get_course_query_conditions&amp;quot; method to hold logic extracted from the &amp;quot;get&amp;quot; method.  &lt;br /&gt;
*** Modified any checks on if the user is a teaching assistant to use polymorphism to make the determination.  &lt;br /&gt;
*** Removed the initial conditional for setting the &amp;quot;conditions&amp;quot; value since the remaining conditions was overwriting the value regardless of how the initial conditional was evaluated. &lt;br /&gt;
*** Renaming the &amp;quot;get&amp;quot; method was considered; however, the name of the method is necessary for polymorphism reasons related to Assignment nodes.  As such, a comment was added to explain why the method name should remain.     &lt;br /&gt;
*** The &amp;quot;sortorder&amp;quot; parameter is given a default value of &amp;quot;ASC&amp;quot; for ascending.  This allowed for a related conditional to be removed from the method.  &lt;br /&gt;
*** The &amp;quot;sortvar&amp;quot; parameter is given a default value of &amp;quot;name&amp;quot; for sorting by course name.  This allowed for a related conditional to be removed from the method.&lt;br /&gt;
** Renaming the &amp;quot;get_children&amp;quot; method was considered; however, the name of the method is necessary for polymorphism reasons related to Assignment Nodes.  As such, a comment was added to explain why the method name should remain. &lt;br /&gt;
** The &amp;quot;get_survey_distribution_id&amp;quot; method was removed after finding it to be dead code.&lt;br /&gt;
* models/ta.rb&lt;br /&gt;
** Added &amp;quot;is_teaching_assistant?&amp;quot; method to override the inherited method from the User model.  This supported usage of polymorphism to determine if the user is a teaching assistant.  &lt;br /&gt;
* models/user.rb&lt;br /&gt;
** Added &amp;quot;is_teaching_assistant?&amp;quot; method to enable usage of polymorphism to determine if the user is a teaching assistant.&lt;br /&gt;
&lt;br /&gt;
== Methods Found That Are Not Currently Being Used ==&lt;br /&gt;
The following methods were not found to be used currently by the project, but have been left in the code for potential future usages of the functionality:&lt;br /&gt;
* models/course.rb&lt;br /&gt;
** Course.get_participant(user_id)&lt;br /&gt;
* models/course_participant.rb&lt;br /&gt;
** CourseParticipant.copy(assignment_id)&lt;br /&gt;
** CourseParticipant.get_parent_name&lt;br /&gt;
* models/course_node.rb&lt;br /&gt;
** CourseNode.get_modified_date&lt;br /&gt;
&lt;br /&gt;
== Miscellaneous Changes for Quality Improvement and Readability ==&lt;br /&gt;
&lt;br /&gt;
== List of New Unit Tests and Testcases ==&lt;br /&gt;
The following lists shows new unit files and/or new testcases:&lt;br /&gt;
* test/unit/course_node_test.rb (new test file)&lt;br /&gt;
** test_get_children_with_show_true_and_non_TA_and_ascending_order_by_name&lt;br /&gt;
** test_get_children_with_show_true_and_non_TA_and_descending_order_by_name&lt;br /&gt;
** test_get_children_with_show_true_and_TA_and_ascending_order_by_name&lt;br /&gt;
** test_get_children_with_show_true_and_TA_and_descending_order_by_name&lt;br /&gt;
** test_get_children_with_show_false_and_non_TA_and_ascending_order_by_name&lt;br /&gt;
** test_get_children_with_show_false_and_non_TA_and_descending_order_by_name&lt;br /&gt;
** test_get_children_with_show_false_and_TA_and_ascending_order_by_name&lt;br /&gt;
** test_get_children_with_show_false_and_TA_and_descending_order_by_name&lt;br /&gt;
** test_get_children_with_show_false_and_non_TA_and_nil_order_by_nil&lt;br /&gt;
** test_get_name&lt;br /&gt;
** test_get_directory&lt;br /&gt;
** test_get_creation_date&lt;br /&gt;
** test_get_modified_date&lt;br /&gt;
** test_get_teams&lt;br /&gt;
* test/unit/course_test.rb (previously existing test file)&lt;br /&gt;
** test_get_teams&lt;br /&gt;
** test_get_path&lt;br /&gt;
** test_get_participants&lt;br /&gt;
** test_get_participant&lt;br /&gt;
** test_add_participant&lt;br /&gt;
** test_copy_participants&lt;br /&gt;
** test_create_course_node&lt;br /&gt;
&lt;br /&gt;
== List of Modified Unit Tests ==&lt;br /&gt;
The following unit test files and/or testcases were modified:&lt;br /&gt;
* test/unit/course_test.rb&lt;br /&gt;
** The line &amp;quot;fixtures :courses&amp;quot; was changed to &amp;quot;fixtures :courses,:teams,:users,:participants,:assignments,:nodes,:tree_folders&amp;quot;.&lt;/div&gt;</summary>
		<author><name>Kbyarbor</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2013/OSS_E608&amp;diff=73869</id>
		<title>CSC/ECE 517 Spring 2013/OSS E608</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2013/OSS_E608&amp;diff=73869"/>
		<updated>2013-03-10T20:46:55Z</updated>

		<summary type="html">&lt;p&gt;Kbyarbor: /* E608. Refactoring and Testing - Course Related Classes */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[https://docs.google.com/a/ncsu.edu/document/d/1SVNx7Eh6dUdrz2a9rGSgBxLkxAmuBUm8eu08nHEdjIg/edit# Write-up of This Topic.]&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
= E608. Refactoring and Testing - Course Related Classes =&lt;br /&gt;
Classes Involved:&lt;br /&gt;
*models/course.rb (76 lines)&lt;br /&gt;
*models/course_participant.rb (94 lines)&lt;br /&gt;
*models/course_team.rb (116 lines)&lt;br /&gt;
*models/course_node.rb (95 lines)&lt;br /&gt;
&lt;br /&gt;
What it does: &lt;br /&gt;
Involves creation and management of courses in Expertiza&lt;br /&gt;
&lt;br /&gt;
What needs to be done:&lt;br /&gt;
*It is not clear what a method named 'create_node' is doing in the 'course' class. Refactor by renaming this method appropriately.&lt;br /&gt;
*In the course_team class the import method seems to be doing too many things. See if this method can be broken down into smaller methods with specific functionality.&lt;br /&gt;
*The 'get' method in course_node.rb appears to be doing a lot. Refactor this method by breaking it up into smaller methods.&lt;br /&gt;
*Look for any unused methods or variables in these files.&lt;br /&gt;
*Also apply other refactorings such as Rename variable, Rename method to give the variables and methods more meaningful names.&lt;br /&gt;
*Write unit tests for all the methods in each of the listed model classes.&lt;br /&gt;
&lt;br /&gt;
== Changes for models/course.rb ==&lt;br /&gt;
The following changes were made:&lt;br /&gt;
* Renamed create_node method to create_course_node to accurately reflect the functionality of the method. &lt;br /&gt;
* Added the line &amp;quot;has_many :assigments, :dependent =&amp;gt; :destroy&amp;quot; to allow CourseTest.test_destroy unit test to pass.  &lt;br /&gt;
&lt;br /&gt;
== Changes for models/course_participant.rb ==&lt;br /&gt;
&lt;br /&gt;
== Changes for models/course_team.rb ==&lt;br /&gt;
&lt;br /&gt;
== Changes for models/course_node.rb ==&lt;br /&gt;
* models/course_node.rb &lt;br /&gt;
** The &amp;quot;get&amp;quot; method was improved. &lt;br /&gt;
*** Added &amp;quot;get_courses_managed_by_user&amp;quot; method to hold logic extracted from the &amp;quot;get&amp;quot;method.  &lt;br /&gt;
*** Added &amp;quot;get_course_query_conditions&amp;quot; method to hold logic extracted from the &amp;quot;get&amp;quot; method.  &lt;br /&gt;
*** Modified any checks on if the user is a teaching assistant to use polymorphism to make the determination.  &lt;br /&gt;
*** Removed the initial conditional for setting the &amp;quot;conditions&amp;quot; value since the remaining conditions was overwriting the value regardless of how the initial conditional was evaluated. &lt;br /&gt;
*** Renaming the &amp;quot;get&amp;quot; method was considered; however, the name of the method is necessary for polymorphism reasons related to Assignment nodes.  As such, a comment was added to explain why the method name should remain.     &lt;br /&gt;
*** The &amp;quot;sortorder&amp;quot; parameter is given a default value of &amp;quot;ASC&amp;quot; for ascending.  This allowed for a related conditional to be removed from the method.  &lt;br /&gt;
*** The &amp;quot;sortvar&amp;quot; parameter is given a default value of &amp;quot;name&amp;quot; for sorting by course name.  This allowed for a related conditional to be removed from the method.&lt;br /&gt;
** Renaming the &amp;quot;get_children&amp;quot; method was considered; however, the name of the method is necessary for polymorphism reasons related to Assignment Nodes.  As such, a comment was added to explain why the method name should remain. &lt;br /&gt;
** The &amp;quot;get_survey_distribution_id&amp;quot; method was removed after finding it to be dead code.&lt;br /&gt;
* models/ta.rb&lt;br /&gt;
** Added &amp;quot;is_teaching_assistant?&amp;quot; method to override the inherited method from the User model.  This supported usage of polymorphism to determine if the user is a teaching assistant.  &lt;br /&gt;
* models/user.rb&lt;br /&gt;
** Added &amp;quot;is_teaching_assistant?&amp;quot; method to enable usage of polymorphism to determine if the user is a teaching assistant.&lt;br /&gt;
&lt;br /&gt;
== Methods Found That Are Not Currently Being Used ==&lt;br /&gt;
The following methods were not found to be used currently by the project, but have been left in the code for potential future usages of the functionality:&lt;br /&gt;
* models/course.rb&lt;br /&gt;
** Course.get_participant(user_id)&lt;br /&gt;
* models/course_participant.rb&lt;br /&gt;
** copy&lt;br /&gt;
** get_parent_name&lt;br /&gt;
* models/course_node.rb&lt;br /&gt;
** get_modified_date&lt;br /&gt;
&lt;br /&gt;
== Miscellaneous Changes for Quality Improvement and Readability ==&lt;br /&gt;
&lt;br /&gt;
== List of New Unit Tests and Testcases ==&lt;br /&gt;
The following lists shows new unit files and/or new testcases:&lt;br /&gt;
* test/unit/course_node_test.rb (new test file)&lt;br /&gt;
** test_get_children_with_show_true_and_non_TA_and_ascending_order_by_name&lt;br /&gt;
** test_get_children_with_show_true_and_non_TA_and_descending_order_by_name&lt;br /&gt;
** test_get_children_with_show_true_and_TA_and_ascending_order_by_name&lt;br /&gt;
** test_get_children_with_show_true_and_TA_and_descending_order_by_name&lt;br /&gt;
** test_get_children_with_show_false_and_non_TA_and_ascending_order_by_name&lt;br /&gt;
** test_get_children_with_show_false_and_non_TA_and_descending_order_by_name&lt;br /&gt;
** test_get_children_with_show_false_and_TA_and_ascending_order_by_name&lt;br /&gt;
** test_get_children_with_show_false_and_TA_and_descending_order_by_name&lt;br /&gt;
** test_get_children_with_show_false_and_non_TA_and_nil_order_by_nil&lt;br /&gt;
** test_get_name&lt;br /&gt;
** test_get_directory&lt;br /&gt;
** test_get_creation_date&lt;br /&gt;
** test_get_modified_date&lt;br /&gt;
** test_get_teams&lt;br /&gt;
* test/unit/course_test.rb (previously existing test file)&lt;br /&gt;
** test_get_teams&lt;br /&gt;
** test_get_path&lt;br /&gt;
** test_get_participants&lt;br /&gt;
** test_get_participant&lt;br /&gt;
** test_add_participant&lt;br /&gt;
** test_copy_participants&lt;br /&gt;
** test_create_course_node&lt;br /&gt;
&lt;br /&gt;
== List of Modified Unit Tests ==&lt;br /&gt;
The following unit test files and/or testcases were modified:&lt;br /&gt;
* test/unit/course_test.rb&lt;br /&gt;
** The line &amp;quot;fixtures :courses&amp;quot; was changed to &amp;quot;fixtures :courses,:teams,:users,:participants,:assignments,:nodes,:tree_folders&amp;quot;.&lt;/div&gt;</summary>
		<author><name>Kbyarbor</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2013/OSS_E608&amp;diff=73868</id>
		<title>CSC/ECE 517 Spring 2013/OSS E608</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2013/OSS_E608&amp;diff=73868"/>
		<updated>2013-03-10T20:26:55Z</updated>

		<summary type="html">&lt;p&gt;Kbyarbor: /* Changes for models/course_node.rb */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[https://docs.google.com/a/ncsu.edu/document/d/1SVNx7Eh6dUdrz2a9rGSgBxLkxAmuBUm8eu08nHEdjIg/edit# Write-up of This Topic.]&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
= E608. Refactoring and Testing - Course Related Classes =&lt;br /&gt;
Classes Involved:&lt;br /&gt;
*models/course.rb (76 lines)&lt;br /&gt;
*models/course_participant.rb (94 lines)&lt;br /&gt;
*models/course_team.rb (116 lines)&lt;br /&gt;
*models/course_node.rb (95 lines)&lt;br /&gt;
&lt;br /&gt;
What it does: &lt;br /&gt;
Involves creation and management of courses in Expertiza&lt;br /&gt;
&lt;br /&gt;
What needs to be done:&lt;br /&gt;
*It is not clear what a method named 'create_node' is doing in the 'course' class. Refactor by renaming this method appropriately.&lt;br /&gt;
*In the course_team class the import method seems to be doing too many things. See if this method can be broken down into smaller methods with specific functionality.&lt;br /&gt;
*The 'get' method in course_node.rb appears to be doing a lot. Refactor this method by breaking it up into smaller methods.&lt;br /&gt;
*Look for any unused methods or variables in these files.&lt;br /&gt;
*Also apply other refactorings such as Rename variable, Rename method to give the variables and methods more meaningful names.&lt;br /&gt;
*Write unit tests for all the methods in each of the listed model classes.&lt;br /&gt;
&lt;br /&gt;
== Changes for models/course.rb ==&lt;br /&gt;
The following changes were made:&lt;br /&gt;
* Renamed create_node method to create_course_node to accurately reflect the functionality of the method. &lt;br /&gt;
* Added the line &amp;quot;has_many :assigments, :dependent =&amp;gt; :destroy&amp;quot; to allow CourseTest.test_destroy unit test to pass.  &lt;br /&gt;
&lt;br /&gt;
== Changes for models/course_participant.rb ==&lt;br /&gt;
&lt;br /&gt;
== Changes for models/course_team.rb ==&lt;br /&gt;
&lt;br /&gt;
== Changes for models/course_node.rb ==&lt;br /&gt;
* models/course_node.rb &lt;br /&gt;
** The &amp;quot;get&amp;quot; method was improved. &lt;br /&gt;
*** Added &amp;quot;get_courses_managed_by_user&amp;quot; method to hold logic extracted from the &amp;quot;get&amp;quot;method.  &lt;br /&gt;
*** Added &amp;quot;get_course_query_conditions&amp;quot; method to hold logic extracted from the &amp;quot;get&amp;quot; method.  &lt;br /&gt;
*** Modified any checks on if the user is a teaching assistant to use polymorphism to make the determination.  &lt;br /&gt;
*** Removed the initial conditional for setting the &amp;quot;conditions&amp;quot; value since the remaining conditions was overwriting the value regardless of how the initial conditional was evaluated. &lt;br /&gt;
*** Renaming the &amp;quot;get&amp;quot; method was considered; however, the name of the method is necessary for polymorphism reasons related to Assignment nodes.  As such, a comment was added to explain why the method name should remain.     &lt;br /&gt;
*** The &amp;quot;sortorder&amp;quot; parameter is given a default value of &amp;quot;ASC&amp;quot; for ascending.  This allowed for a related conditional to be removed from the method.  &lt;br /&gt;
*** The &amp;quot;sortvar&amp;quot; parameter is given a default value of &amp;quot;name&amp;quot; for sorting by course name.  This allowed for a related conditional to be removed from the method.&lt;br /&gt;
** Renaming the &amp;quot;get_children&amp;quot; method was considered; however, the name of the method is necessary for polymorphism reasons related to Assignment Nodes.  As such, a comment was added to explain why the method name should remain. &lt;br /&gt;
** The &amp;quot;get_survey_distribution_id&amp;quot; method was removed after finding it to be dead code.&lt;br /&gt;
* models/ta.rb&lt;br /&gt;
** Added &amp;quot;is_teaching_assistant?&amp;quot; method to override the inherited method from the User model.  This supported usage of polymorphism to determine if the user is a teaching assistant.  &lt;br /&gt;
* models/user.rb&lt;br /&gt;
** Added &amp;quot;is_teaching_assistant?&amp;quot; method to enable usage of polymorphism to determine if the user is a teaching assistant.&lt;br /&gt;
&lt;br /&gt;
== Miscellaneous Changes for Quality Improvement and Readability ==&lt;br /&gt;
&lt;br /&gt;
== List of New Unit Tests and Testcases ==&lt;br /&gt;
The following lists shows new unit files and/or new testcases:&lt;br /&gt;
* test/unit/course_node_test.rb (new test file)&lt;br /&gt;
** test_get_children_with_show_true_and_non_TA_and_ascending_order_by_name&lt;br /&gt;
** test_get_children_with_show_true_and_non_TA_and_descending_order_by_name&lt;br /&gt;
** test_get_children_with_show_true_and_TA_and_ascending_order_by_name&lt;br /&gt;
** test_get_children_with_show_true_and_TA_and_descending_order_by_name&lt;br /&gt;
** test_get_children_with_show_false_and_non_TA_and_ascending_order_by_name&lt;br /&gt;
** test_get_children_with_show_false_and_non_TA_and_descending_order_by_name&lt;br /&gt;
** test_get_children_with_show_false_and_TA_and_ascending_order_by_name&lt;br /&gt;
** test_get_children_with_show_false_and_TA_and_descending_order_by_name&lt;br /&gt;
** test_get_children_with_show_false_and_non_TA_and_nil_order_by_nil&lt;br /&gt;
** test_get_name&lt;br /&gt;
** test_get_directory&lt;br /&gt;
** test_get_creation_date&lt;br /&gt;
** test_get_modified_date&lt;br /&gt;
** test_get_teams&lt;br /&gt;
* test/unit/course_test.rb (previously existing test file)&lt;br /&gt;
** test_get_teams&lt;br /&gt;
** test_get_path&lt;br /&gt;
** test_get_participants&lt;br /&gt;
** test_get_participant&lt;br /&gt;
** test_add_participant&lt;br /&gt;
** test_copy_participants&lt;br /&gt;
** test_create_course_node&lt;br /&gt;
&lt;br /&gt;
== List of Modified Unit Tests ==&lt;br /&gt;
The following unit test files and/or testcases were modified:&lt;br /&gt;
* test/unit/course_test.rb&lt;br /&gt;
** The line &amp;quot;fixtures :courses&amp;quot; was changed to &amp;quot;fixtures :courses,:teams,:users,:participants,:assignments,:nodes,:tree_folders&amp;quot;.&lt;/div&gt;</summary>
		<author><name>Kbyarbor</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2013/OSS_E608&amp;diff=73867</id>
		<title>CSC/ECE 517 Spring 2013/OSS E608</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2013/OSS_E608&amp;diff=73867"/>
		<updated>2013-03-10T19:30:39Z</updated>

		<summary type="html">&lt;p&gt;Kbyarbor: /* Changes for models/course_node.rb */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[https://docs.google.com/a/ncsu.edu/document/d/1SVNx7Eh6dUdrz2a9rGSgBxLkxAmuBUm8eu08nHEdjIg/edit# Write-up of This Topic.]&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
= E608. Refactoring and Testing - Course Related Classes =&lt;br /&gt;
Classes Involved:&lt;br /&gt;
*models/course.rb (76 lines)&lt;br /&gt;
*models/course_participant.rb (94 lines)&lt;br /&gt;
*models/course_team.rb (116 lines)&lt;br /&gt;
*models/course_node.rb (95 lines)&lt;br /&gt;
&lt;br /&gt;
What it does: &lt;br /&gt;
Involves creation and management of courses in Expertiza&lt;br /&gt;
&lt;br /&gt;
What needs to be done:&lt;br /&gt;
*It is not clear what a method named 'create_node' is doing in the 'course' class. Refactor by renaming this method appropriately.&lt;br /&gt;
*In the course_team class the import method seems to be doing too many things. See if this method can be broken down into smaller methods with specific functionality.&lt;br /&gt;
*The 'get' method in course_node.rb appears to be doing a lot. Refactor this method by breaking it up into smaller methods.&lt;br /&gt;
*Look for any unused methods or variables in these files.&lt;br /&gt;
*Also apply other refactorings such as Rename variable, Rename method to give the variables and methods more meaningful names.&lt;br /&gt;
*Write unit tests for all the methods in each of the listed model classes.&lt;br /&gt;
&lt;br /&gt;
== Changes for models/course.rb ==&lt;br /&gt;
The following changes were made:&lt;br /&gt;
* Renamed create_node method to create_course_node to accurately reflect the functionality of the method. &lt;br /&gt;
* Added the line &amp;quot;has_many :assigments, :dependent =&amp;gt; :destroy&amp;quot; to allow CourseTest.test_destroy unit test to pass.  &lt;br /&gt;
&lt;br /&gt;
== Changes for models/course_participant.rb ==&lt;br /&gt;
&lt;br /&gt;
== Changes for models/course_team.rb ==&lt;br /&gt;
&lt;br /&gt;
== Changes for models/course_node.rb ==&lt;br /&gt;
* models/course_node.rb &lt;br /&gt;
** The &amp;quot;get&amp;quot; method was improved. &lt;br /&gt;
*** Added &amp;quot;get_courses_managed_by_user&amp;quot; method to hold logic extracted from the &amp;quot;get&amp;quot;method.  &lt;br /&gt;
*** Added &amp;quot;get_course_query_conditions&amp;quot; method to hold logic extracted from the &amp;quot;get&amp;quot; method.  &lt;br /&gt;
*** Modified any checks on if the user is a teaching assistant to use polymorphism to make the determination.  &lt;br /&gt;
*** Renaming the &amp;quot;get&amp;quot; method was considered; however, the name of the method is necessary for polymorphism reasons related to Assignment nodes.  As such, a comment was added to explain why the method name should remain.     &lt;br /&gt;
*** The &amp;quot;sortorder&amp;quot; parameter is given a default value of &amp;quot;ASC&amp;quot; for ascending.  This allowed for a related conditional to be removed from the method.  &lt;br /&gt;
*** The &amp;quot;sortvar&amp;quot; parameter is given a default value of &amp;quot;name&amp;quot; for sorting by course name.  This allowed for a related conditional to be removed from the method.&lt;br /&gt;
** Renaming the &amp;quot;get_children&amp;quot; method was considered; however, the name of the method is necessary for polymorphism reasons related to Assignment Nodes.  As such, a comment was added to explain why the method name should remain. &lt;br /&gt;
** The &amp;quot;get_survey_distribution_id&amp;quot; method was removed after finding it to be dead code.&lt;br /&gt;
* models/ta.rb&lt;br /&gt;
** Added &amp;quot;is_teaching_assistant?&amp;quot; method to override the inherited method from the User model.  This supported usage of polymorphism to determine if the user is a teaching assistant.  &lt;br /&gt;
* models/user.rb&lt;br /&gt;
** Added &amp;quot;is_teaching_assistant?&amp;quot; method to enable usage of polymorphism to determine if the user is a teaching assistant.&lt;br /&gt;
&lt;br /&gt;
== Miscellaneous Changes for Quality Improvement and Readability ==&lt;br /&gt;
&lt;br /&gt;
== List of New Unit Tests and Testcases ==&lt;br /&gt;
The following lists shows new unit files and/or new testcases:&lt;br /&gt;
* test/unit/course_node_test.rb (new test file)&lt;br /&gt;
** test_get_children_with_show_true_and_non_TA_and_ascending_order_by_name&lt;br /&gt;
** test_get_children_with_show_true_and_non_TA_and_descending_order_by_name&lt;br /&gt;
** test_get_children_with_show_true_and_TA_and_ascending_order_by_name&lt;br /&gt;
** test_get_children_with_show_true_and_TA_and_descending_order_by_name&lt;br /&gt;
** test_get_children_with_show_false_and_non_TA_and_ascending_order_by_name&lt;br /&gt;
** test_get_children_with_show_false_and_non_TA_and_descending_order_by_name&lt;br /&gt;
** test_get_children_with_show_false_and_TA_and_ascending_order_by_name&lt;br /&gt;
** test_get_children_with_show_false_and_TA_and_descending_order_by_name&lt;br /&gt;
** test_get_children_with_show_false_and_non_TA_and_nil_order_by_nil&lt;br /&gt;
** test_get_name&lt;br /&gt;
** test_get_directory&lt;br /&gt;
** test_get_creation_date&lt;br /&gt;
** test_get_modified_date&lt;br /&gt;
** test_get_teams&lt;br /&gt;
* test/unit/course_test.rb (previously existing test file)&lt;br /&gt;
** test_get_teams&lt;br /&gt;
** test_get_path&lt;br /&gt;
** test_get_participants&lt;br /&gt;
** test_get_participant&lt;br /&gt;
** test_add_participant&lt;br /&gt;
** test_copy_participants&lt;br /&gt;
** test_create_course_node&lt;br /&gt;
&lt;br /&gt;
== List of Modified Unit Tests ==&lt;br /&gt;
The following unit test files and/or testcases were modified:&lt;br /&gt;
* test/unit/course_test.rb&lt;br /&gt;
** The line &amp;quot;fixtures :courses&amp;quot; was changed to &amp;quot;fixtures :courses,:teams,:users,:participants,:assignments,:nodes,:tree_folders&amp;quot;.&lt;/div&gt;</summary>
		<author><name>Kbyarbor</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2013/OSS_E608&amp;diff=73866</id>
		<title>CSC/ECE 517 Spring 2013/OSS E608</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2013/OSS_E608&amp;diff=73866"/>
		<updated>2013-03-10T19:17:49Z</updated>

		<summary type="html">&lt;p&gt;Kbyarbor: /* Changes for models/course_node.rb */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[https://docs.google.com/a/ncsu.edu/document/d/1SVNx7Eh6dUdrz2a9rGSgBxLkxAmuBUm8eu08nHEdjIg/edit# Write-up of This Topic.]&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
= E608. Refactoring and Testing - Course Related Classes =&lt;br /&gt;
Classes Involved:&lt;br /&gt;
*models/course.rb (76 lines)&lt;br /&gt;
*models/course_participant.rb (94 lines)&lt;br /&gt;
*models/course_team.rb (116 lines)&lt;br /&gt;
*models/course_node.rb (95 lines)&lt;br /&gt;
&lt;br /&gt;
What it does: &lt;br /&gt;
Involves creation and management of courses in Expertiza&lt;br /&gt;
&lt;br /&gt;
What needs to be done:&lt;br /&gt;
*It is not clear what a method named 'create_node' is doing in the 'course' class. Refactor by renaming this method appropriately.&lt;br /&gt;
*In the course_team class the import method seems to be doing too many things. See if this method can be broken down into smaller methods with specific functionality.&lt;br /&gt;
*The 'get' method in course_node.rb appears to be doing a lot. Refactor this method by breaking it up into smaller methods.&lt;br /&gt;
*Look for any unused methods or variables in these files.&lt;br /&gt;
*Also apply other refactorings such as Rename variable, Rename method to give the variables and methods more meaningful names.&lt;br /&gt;
*Write unit tests for all the methods in each of the listed model classes.&lt;br /&gt;
&lt;br /&gt;
== Changes for models/course.rb ==&lt;br /&gt;
The following changes were made:&lt;br /&gt;
* Renamed create_node method to create_course_node to accurately reflect the functionality of the method. &lt;br /&gt;
* Added the line &amp;quot;has_many :assigments, :dependent =&amp;gt; :destroy&amp;quot; to allow CourseTest.test_destroy unit test to pass.  &lt;br /&gt;
&lt;br /&gt;
== Changes for models/course_participant.rb ==&lt;br /&gt;
&lt;br /&gt;
== Changes for models/course_team.rb ==&lt;br /&gt;
&lt;br /&gt;
== Changes for models/course_node.rb ==&lt;br /&gt;
** The &amp;quot;get&amp;quot; method was improved. &lt;br /&gt;
*** Renaming the &amp;quot;get&amp;quot; method was considered; however, the name of the method is necessary for polymorphism reasons related to Assignment nodes.  As such, a comment was added to explain why the method name should remain.  &lt;br /&gt;
*** Renaming the &amp;quot;get_children&amp;quot; method was considered; however, the name of the method is necessary for polymorphism reasons related to Assignment Nodes.  As such, a comment was added to explain why the method name should remain.  &lt;br /&gt;
*** The &amp;quot;sortorder&amp;quot; parameter is given a default value of &amp;quot;ASC&amp;quot; for ascending.  This allowed for a related conditional to be removed from the method.  &lt;br /&gt;
*** The &amp;quot;sortvar&amp;quot; parameter is given a default value of &amp;quot;name&amp;quot; for sorting by course name.  This allowed for a related conditional to be removed from the method.&lt;br /&gt;
&lt;br /&gt;
== Miscellaneous Changes for Quality Improvement and Readability ==&lt;br /&gt;
&lt;br /&gt;
== List of New Unit Tests and Testcases ==&lt;br /&gt;
The following lists shows new unit files and/or new testcases:&lt;br /&gt;
* test/unit/course_node_test.rb (new test file)&lt;br /&gt;
** test_get_children_with_show_true_and_non_TA_and_ascending_order_by_name&lt;br /&gt;
** test_get_children_with_show_true_and_non_TA_and_descending_order_by_name&lt;br /&gt;
** test_get_children_with_show_true_and_TA_and_ascending_order_by_name&lt;br /&gt;
** test_get_children_with_show_true_and_TA_and_descending_order_by_name&lt;br /&gt;
** test_get_children_with_show_false_and_non_TA_and_ascending_order_by_name&lt;br /&gt;
** test_get_children_with_show_false_and_non_TA_and_descending_order_by_name&lt;br /&gt;
** test_get_children_with_show_false_and_TA_and_ascending_order_by_name&lt;br /&gt;
** test_get_children_with_show_false_and_TA_and_descending_order_by_name&lt;br /&gt;
** test_get_children_with_show_false_and_non_TA_and_nil_order_by_nil&lt;br /&gt;
** test_get_name&lt;br /&gt;
** test_get_directory&lt;br /&gt;
** test_get_creation_date&lt;br /&gt;
** test_get_modified_date&lt;br /&gt;
** test_get_teams&lt;br /&gt;
* test/unit/course_test.rb (previously existing test file)&lt;br /&gt;
** test_get_teams&lt;br /&gt;
** test_get_path&lt;br /&gt;
** test_get_participants&lt;br /&gt;
** test_get_participant&lt;br /&gt;
** test_add_participant&lt;br /&gt;
** test_copy_participants&lt;br /&gt;
** test_create_course_node&lt;br /&gt;
&lt;br /&gt;
== List of Modified Unit Tests ==&lt;br /&gt;
The following unit test files and/or testcases were modified:&lt;br /&gt;
* test/unit/course_test.rb&lt;br /&gt;
** The line &amp;quot;fixtures :courses&amp;quot; was changed to &amp;quot;fixtures :courses,:teams,:users,:participants,:assignments,:nodes,:tree_folders&amp;quot;.&lt;/div&gt;</summary>
		<author><name>Kbyarbor</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2013/OSS_E608&amp;diff=73865</id>
		<title>CSC/ECE 517 Spring 2013/OSS E608</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2013/OSS_E608&amp;diff=73865"/>
		<updated>2013-03-10T19:11:33Z</updated>

		<summary type="html">&lt;p&gt;Kbyarbor: /* List of Modified Unit Tests */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[https://docs.google.com/a/ncsu.edu/document/d/1SVNx7Eh6dUdrz2a9rGSgBxLkxAmuBUm8eu08nHEdjIg/edit# Write-up of This Topic.]&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
= E608. Refactoring and Testing - Course Related Classes =&lt;br /&gt;
Classes Involved:&lt;br /&gt;
*models/course.rb (76 lines)&lt;br /&gt;
*models/course_participant.rb (94 lines)&lt;br /&gt;
*models/course_team.rb (116 lines)&lt;br /&gt;
*models/course_node.rb (95 lines)&lt;br /&gt;
&lt;br /&gt;
What it does: &lt;br /&gt;
Involves creation and management of courses in Expertiza&lt;br /&gt;
&lt;br /&gt;
What needs to be done:&lt;br /&gt;
*It is not clear what a method named 'create_node' is doing in the 'course' class. Refactor by renaming this method appropriately.&lt;br /&gt;
*In the course_team class the import method seems to be doing too many things. See if this method can be broken down into smaller methods with specific functionality.&lt;br /&gt;
*The 'get' method in course_node.rb appears to be doing a lot. Refactor this method by breaking it up into smaller methods.&lt;br /&gt;
*Look for any unused methods or variables in these files.&lt;br /&gt;
*Also apply other refactorings such as Rename variable, Rename method to give the variables and methods more meaningful names.&lt;br /&gt;
*Write unit tests for all the methods in each of the listed model classes.&lt;br /&gt;
&lt;br /&gt;
== Changes for models/course.rb ==&lt;br /&gt;
The following changes were made:&lt;br /&gt;
* Renamed create_node method to create_course_node to accurately reflect the functionality of the method. &lt;br /&gt;
* Added the line &amp;quot;has_many :assigments, :dependent =&amp;gt; :destroy&amp;quot; to allow CourseTest.test_destroy unit test to pass.  &lt;br /&gt;
&lt;br /&gt;
== Changes for models/course_participant.rb ==&lt;br /&gt;
&lt;br /&gt;
== Changes for models/course_team.rb ==&lt;br /&gt;
&lt;br /&gt;
== Changes for models/course_node.rb ==&lt;br /&gt;
&lt;br /&gt;
== Miscellaneous Changes for Quality Improvement and Readability ==&lt;br /&gt;
&lt;br /&gt;
== List of New Unit Tests and Testcases ==&lt;br /&gt;
The following lists shows new unit files and/or new testcases:&lt;br /&gt;
* test/unit/course_node_test.rb (new test file)&lt;br /&gt;
** test_get_children_with_show_true_and_non_TA_and_ascending_order_by_name&lt;br /&gt;
** test_get_children_with_show_true_and_non_TA_and_descending_order_by_name&lt;br /&gt;
** test_get_children_with_show_true_and_TA_and_ascending_order_by_name&lt;br /&gt;
** test_get_children_with_show_true_and_TA_and_descending_order_by_name&lt;br /&gt;
** test_get_children_with_show_false_and_non_TA_and_ascending_order_by_name&lt;br /&gt;
** test_get_children_with_show_false_and_non_TA_and_descending_order_by_name&lt;br /&gt;
** test_get_children_with_show_false_and_TA_and_ascending_order_by_name&lt;br /&gt;
** test_get_children_with_show_false_and_TA_and_descending_order_by_name&lt;br /&gt;
** test_get_children_with_show_false_and_non_TA_and_nil_order_by_nil&lt;br /&gt;
** test_get_name&lt;br /&gt;
** test_get_directory&lt;br /&gt;
** test_get_creation_date&lt;br /&gt;
** test_get_modified_date&lt;br /&gt;
** test_get_teams&lt;br /&gt;
* test/unit/course_test.rb (previously existing test file)&lt;br /&gt;
** test_get_teams&lt;br /&gt;
** test_get_path&lt;br /&gt;
** test_get_participants&lt;br /&gt;
** test_get_participant&lt;br /&gt;
** test_add_participant&lt;br /&gt;
** test_copy_participants&lt;br /&gt;
** test_create_course_node&lt;br /&gt;
&lt;br /&gt;
== List of Modified Unit Tests ==&lt;br /&gt;
The following unit test files and/or testcases were modified:&lt;br /&gt;
* test/unit/course_test.rb&lt;br /&gt;
** The line &amp;quot;fixtures :courses&amp;quot; was changed to &amp;quot;fixtures :courses,:teams,:users,:participants,:assignments,:nodes,:tree_folders&amp;quot;.&lt;/div&gt;</summary>
		<author><name>Kbyarbor</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2013/OSS_E608&amp;diff=73864</id>
		<title>CSC/ECE 517 Spring 2013/OSS E608</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2013/OSS_E608&amp;diff=73864"/>
		<updated>2013-03-10T19:11:18Z</updated>

		<summary type="html">&lt;p&gt;Kbyarbor: /* List of Modified Unit Tests */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[https://docs.google.com/a/ncsu.edu/document/d/1SVNx7Eh6dUdrz2a9rGSgBxLkxAmuBUm8eu08nHEdjIg/edit# Write-up of This Topic.]&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
= E608. Refactoring and Testing - Course Related Classes =&lt;br /&gt;
Classes Involved:&lt;br /&gt;
*models/course.rb (76 lines)&lt;br /&gt;
*models/course_participant.rb (94 lines)&lt;br /&gt;
*models/course_team.rb (116 lines)&lt;br /&gt;
*models/course_node.rb (95 lines)&lt;br /&gt;
&lt;br /&gt;
What it does: &lt;br /&gt;
Involves creation and management of courses in Expertiza&lt;br /&gt;
&lt;br /&gt;
What needs to be done:&lt;br /&gt;
*It is not clear what a method named 'create_node' is doing in the 'course' class. Refactor by renaming this method appropriately.&lt;br /&gt;
*In the course_team class the import method seems to be doing too many things. See if this method can be broken down into smaller methods with specific functionality.&lt;br /&gt;
*The 'get' method in course_node.rb appears to be doing a lot. Refactor this method by breaking it up into smaller methods.&lt;br /&gt;
*Look for any unused methods or variables in these files.&lt;br /&gt;
*Also apply other refactorings such as Rename variable, Rename method to give the variables and methods more meaningful names.&lt;br /&gt;
*Write unit tests for all the methods in each of the listed model classes.&lt;br /&gt;
&lt;br /&gt;
== Changes for models/course.rb ==&lt;br /&gt;
The following changes were made:&lt;br /&gt;
* Renamed create_node method to create_course_node to accurately reflect the functionality of the method. &lt;br /&gt;
* Added the line &amp;quot;has_many :assigments, :dependent =&amp;gt; :destroy&amp;quot; to allow CourseTest.test_destroy unit test to pass.  &lt;br /&gt;
&lt;br /&gt;
== Changes for models/course_participant.rb ==&lt;br /&gt;
&lt;br /&gt;
== Changes for models/course_team.rb ==&lt;br /&gt;
&lt;br /&gt;
== Changes for models/course_node.rb ==&lt;br /&gt;
&lt;br /&gt;
== Miscellaneous Changes for Quality Improvement and Readability ==&lt;br /&gt;
&lt;br /&gt;
== List of New Unit Tests and Testcases ==&lt;br /&gt;
The following lists shows new unit files and/or new testcases:&lt;br /&gt;
* test/unit/course_node_test.rb (new test file)&lt;br /&gt;
** test_get_children_with_show_true_and_non_TA_and_ascending_order_by_name&lt;br /&gt;
** test_get_children_with_show_true_and_non_TA_and_descending_order_by_name&lt;br /&gt;
** test_get_children_with_show_true_and_TA_and_ascending_order_by_name&lt;br /&gt;
** test_get_children_with_show_true_and_TA_and_descending_order_by_name&lt;br /&gt;
** test_get_children_with_show_false_and_non_TA_and_ascending_order_by_name&lt;br /&gt;
** test_get_children_with_show_false_and_non_TA_and_descending_order_by_name&lt;br /&gt;
** test_get_children_with_show_false_and_TA_and_ascending_order_by_name&lt;br /&gt;
** test_get_children_with_show_false_and_TA_and_descending_order_by_name&lt;br /&gt;
** test_get_children_with_show_false_and_non_TA_and_nil_order_by_nil&lt;br /&gt;
** test_get_name&lt;br /&gt;
** test_get_directory&lt;br /&gt;
** test_get_creation_date&lt;br /&gt;
** test_get_modified_date&lt;br /&gt;
** test_get_teams&lt;br /&gt;
* test/unit/course_test.rb (previously existing test file)&lt;br /&gt;
** test_get_teams&lt;br /&gt;
** test_get_path&lt;br /&gt;
** test_get_participants&lt;br /&gt;
** test_get_participant&lt;br /&gt;
** test_add_participant&lt;br /&gt;
** test_copy_participants&lt;br /&gt;
** test_create_course_node&lt;br /&gt;
&lt;br /&gt;
== List of Modified Unit Tests ==&lt;br /&gt;
The following unit test files and/or testcases were modified:&lt;br /&gt;
* test/unit/course_test.rb&lt;br /&gt;
** The line &amp;quot;fixtures :courses&amp;quot; to &amp;quot;fixtures :courses,:teams,:users,:participants,:assignments,:nodes,:tree_folders&amp;quot;.&lt;/div&gt;</summary>
		<author><name>Kbyarbor</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2013/OSS_E608&amp;diff=73863</id>
		<title>CSC/ECE 517 Spring 2013/OSS E608</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2013/OSS_E608&amp;diff=73863"/>
		<updated>2013-03-10T19:08:29Z</updated>

		<summary type="html">&lt;p&gt;Kbyarbor: /* List of New Unit Tests and Testcases */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[https://docs.google.com/a/ncsu.edu/document/d/1SVNx7Eh6dUdrz2a9rGSgBxLkxAmuBUm8eu08nHEdjIg/edit# Write-up of This Topic.]&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
= E608. Refactoring and Testing - Course Related Classes =&lt;br /&gt;
Classes Involved:&lt;br /&gt;
*models/course.rb (76 lines)&lt;br /&gt;
*models/course_participant.rb (94 lines)&lt;br /&gt;
*models/course_team.rb (116 lines)&lt;br /&gt;
*models/course_node.rb (95 lines)&lt;br /&gt;
&lt;br /&gt;
What it does: &lt;br /&gt;
Involves creation and management of courses in Expertiza&lt;br /&gt;
&lt;br /&gt;
What needs to be done:&lt;br /&gt;
*It is not clear what a method named 'create_node' is doing in the 'course' class. Refactor by renaming this method appropriately.&lt;br /&gt;
*In the course_team class the import method seems to be doing too many things. See if this method can be broken down into smaller methods with specific functionality.&lt;br /&gt;
*The 'get' method in course_node.rb appears to be doing a lot. Refactor this method by breaking it up into smaller methods.&lt;br /&gt;
*Look for any unused methods or variables in these files.&lt;br /&gt;
*Also apply other refactorings such as Rename variable, Rename method to give the variables and methods more meaningful names.&lt;br /&gt;
*Write unit tests for all the methods in each of the listed model classes.&lt;br /&gt;
&lt;br /&gt;
== Changes for models/course.rb ==&lt;br /&gt;
The following changes were made:&lt;br /&gt;
* Renamed create_node method to create_course_node to accurately reflect the functionality of the method. &lt;br /&gt;
* Added the line &amp;quot;has_many :assigments, :dependent =&amp;gt; :destroy&amp;quot; to allow CourseTest.test_destroy unit test to pass.  &lt;br /&gt;
&lt;br /&gt;
== Changes for models/course_participant.rb ==&lt;br /&gt;
&lt;br /&gt;
== Changes for models/course_team.rb ==&lt;br /&gt;
&lt;br /&gt;
== Changes for models/course_node.rb ==&lt;br /&gt;
&lt;br /&gt;
== Miscellaneous Changes for Quality Improvement and Readability ==&lt;br /&gt;
&lt;br /&gt;
== List of New Unit Tests and Testcases ==&lt;br /&gt;
The following lists shows new unit files and/or new testcases:&lt;br /&gt;
* test/unit/course_node_test.rb (new test file)&lt;br /&gt;
** test_get_children_with_show_true_and_non_TA_and_ascending_order_by_name&lt;br /&gt;
** test_get_children_with_show_true_and_non_TA_and_descending_order_by_name&lt;br /&gt;
** test_get_children_with_show_true_and_TA_and_ascending_order_by_name&lt;br /&gt;
** test_get_children_with_show_true_and_TA_and_descending_order_by_name&lt;br /&gt;
** test_get_children_with_show_false_and_non_TA_and_ascending_order_by_name&lt;br /&gt;
** test_get_children_with_show_false_and_non_TA_and_descending_order_by_name&lt;br /&gt;
** test_get_children_with_show_false_and_TA_and_ascending_order_by_name&lt;br /&gt;
** test_get_children_with_show_false_and_TA_and_descending_order_by_name&lt;br /&gt;
** test_get_children_with_show_false_and_non_TA_and_nil_order_by_nil&lt;br /&gt;
** test_get_name&lt;br /&gt;
** test_get_directory&lt;br /&gt;
** test_get_creation_date&lt;br /&gt;
** test_get_modified_date&lt;br /&gt;
** test_get_teams&lt;br /&gt;
* test/unit/course_test.rb (previously existing test file)&lt;br /&gt;
** test_get_teams&lt;br /&gt;
** test_get_path&lt;br /&gt;
** test_get_participants&lt;br /&gt;
** test_get_participant&lt;br /&gt;
** test_add_participant&lt;br /&gt;
** test_copy_participants&lt;br /&gt;
** test_create_course_node&lt;br /&gt;
&lt;br /&gt;
== List of Modified Unit Tests ==&lt;/div&gt;</summary>
		<author><name>Kbyarbor</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2013/OSS_E608&amp;diff=73862</id>
		<title>CSC/ECE 517 Spring 2013/OSS E608</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2013/OSS_E608&amp;diff=73862"/>
		<updated>2013-03-10T19:03:06Z</updated>

		<summary type="html">&lt;p&gt;Kbyarbor: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[https://docs.google.com/a/ncsu.edu/document/d/1SVNx7Eh6dUdrz2a9rGSgBxLkxAmuBUm8eu08nHEdjIg/edit# Write-up of This Topic.]&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
= E608. Refactoring and Testing - Course Related Classes =&lt;br /&gt;
Classes Involved:&lt;br /&gt;
*models/course.rb (76 lines)&lt;br /&gt;
*models/course_participant.rb (94 lines)&lt;br /&gt;
*models/course_team.rb (116 lines)&lt;br /&gt;
*models/course_node.rb (95 lines)&lt;br /&gt;
&lt;br /&gt;
What it does: &lt;br /&gt;
Involves creation and management of courses in Expertiza&lt;br /&gt;
&lt;br /&gt;
What needs to be done:&lt;br /&gt;
*It is not clear what a method named 'create_node' is doing in the 'course' class. Refactor by renaming this method appropriately.&lt;br /&gt;
*In the course_team class the import method seems to be doing too many things. See if this method can be broken down into smaller methods with specific functionality.&lt;br /&gt;
*The 'get' method in course_node.rb appears to be doing a lot. Refactor this method by breaking it up into smaller methods.&lt;br /&gt;
*Look for any unused methods or variables in these files.&lt;br /&gt;
*Also apply other refactorings such as Rename variable, Rename method to give the variables and methods more meaningful names.&lt;br /&gt;
*Write unit tests for all the methods in each of the listed model classes.&lt;br /&gt;
&lt;br /&gt;
== Changes for models/course.rb ==&lt;br /&gt;
The following changes were made:&lt;br /&gt;
* Renamed create_node method to create_course_node to accurately reflect the functionality of the method. &lt;br /&gt;
* Added the line &amp;quot;has_many :assigments, :dependent =&amp;gt; :destroy&amp;quot; to allow CourseTest.test_destroy unit test to pass.  &lt;br /&gt;
&lt;br /&gt;
== Changes for models/course_participant.rb ==&lt;br /&gt;
&lt;br /&gt;
== Changes for models/course_team.rb ==&lt;br /&gt;
&lt;br /&gt;
== Changes for models/course_node.rb ==&lt;br /&gt;
&lt;br /&gt;
== Miscellaneous Changes for Quality Improvement and Readability ==&lt;br /&gt;
&lt;br /&gt;
== List of New Unit Tests and Testcases ==&lt;br /&gt;
The following lists shows new unit files and/or new testcases:&lt;br /&gt;
* test/unit/course_test.rb (previously existing test file)&lt;br /&gt;
** test_get_teams&lt;br /&gt;
** test_get_path&lt;br /&gt;
** test_get_participants&lt;br /&gt;
** test_get_participant&lt;br /&gt;
** test_add_participant&lt;br /&gt;
** test_copy_participants&lt;br /&gt;
** test_create_course_node &lt;br /&gt;
&lt;br /&gt;
== List of Modified Unit Tests ==&lt;/div&gt;</summary>
		<author><name>Kbyarbor</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2013/OSS_E608&amp;diff=73861</id>
		<title>CSC/ECE 517 Spring 2013/OSS E608</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2013/OSS_E608&amp;diff=73861"/>
		<updated>2013-03-10T18:52:58Z</updated>

		<summary type="html">&lt;p&gt;Kbyarbor: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[https://docs.google.com/a/ncsu.edu/document/d/1SVNx7Eh6dUdrz2a9rGSgBxLkxAmuBUm8eu08nHEdjIg/edit# Write-up of This Topic.]&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
= E608. Refactoring and Testing - Course Related Classes =&lt;br /&gt;
Classes Involved:&lt;br /&gt;
*models/course.rb (76 lines)&lt;br /&gt;
*models/course_participant.rb (94 lines)&lt;br /&gt;
*models/course_team.rb (116 lines)&lt;br /&gt;
*models/course_node.rb (95 lines)&lt;br /&gt;
&lt;br /&gt;
What it does: &lt;br /&gt;
Involves creation and management of courses in Expertiza&lt;br /&gt;
&lt;br /&gt;
What needs to be done:&lt;br /&gt;
*It is not clear what a method named 'create_node' is doing in the 'course' class. Refactor by renaming this method appropriately.&lt;br /&gt;
*In the course_team class the import method seems to be doing too many things. See if this method can be broken down into smaller methods with specific functionality.&lt;br /&gt;
*The 'get' method in course_node.rb appears to be doing a lot. Refactor this method by breaking it up into smaller methods.&lt;br /&gt;
*Look for any unused methods or variables in these files.&lt;br /&gt;
*Also apply other refactorings such as Rename variable, Rename method to give the variables and methods more meaningful names.&lt;br /&gt;
*Write unit tests for all the methods in each of the listed model classes.&lt;br /&gt;
&lt;br /&gt;
== Changes for models/course.rb ==&lt;br /&gt;
&lt;br /&gt;
== Changes for models/course_participant.rb ==&lt;br /&gt;
&lt;br /&gt;
== Changes for models/course_team.rb ==&lt;br /&gt;
&lt;br /&gt;
== Changes for models/course_node.rb ==&lt;br /&gt;
&lt;br /&gt;
== Miscellaneous Changes for Quality Improvement and Readability ==&lt;br /&gt;
&lt;br /&gt;
== List of New Unit Tests ==&lt;br /&gt;
&lt;br /&gt;
== List of Modified Unit Tests ==&lt;/div&gt;</summary>
		<author><name>Kbyarbor</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2013/OSS_E608&amp;diff=73860</id>
		<title>CSC/ECE 517 Spring 2013/OSS E608</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2013/OSS_E608&amp;diff=73860"/>
		<updated>2013-03-10T18:51:41Z</updated>

		<summary type="html">&lt;p&gt;Kbyarbor: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[https://docs.google.com/a/ncsu.edu/document/d/1SVNx7Eh6dUdrz2a9rGSgBxLkxAmuBUm8eu08nHEdjIg/edit# Write-up of This Topic.]&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
= E608. Refactoring and Testing - Course Related Classes =&lt;br /&gt;
Classes Involved:&lt;br /&gt;
*models/course.rb (76 lines)&lt;br /&gt;
*models/course_participant.rb (94 lines)&lt;br /&gt;
*models/course_team.rb (116 lines)&lt;br /&gt;
*models/course_node.rb (95 lines)&lt;br /&gt;
&lt;br /&gt;
What it does: &lt;br /&gt;
Involves creation and management of courses in Expertiza&lt;br /&gt;
&lt;br /&gt;
What needs to be done:&lt;br /&gt;
*It is not clear what a method named 'create_node' is doing in the 'course' class. Refactor by renaming this method appropriately.&lt;br /&gt;
*In the course_team class the import method seems to be doing too many things. See if this method can be broken down into smaller methods with specific functionality.&lt;br /&gt;
*The 'get' method in course_node.rb appears to be doing a lot. Refactor this method by breaking it up into smaller methods.&lt;br /&gt;
*Look for any unused methods or variables in these files.&lt;br /&gt;
*Also apply other refactorings such as Rename variable, Rename method to give the variables and methods more meaningful names.&lt;br /&gt;
*Write unit tests for all the methods in each of the listed model classes.&lt;br /&gt;
&lt;br /&gt;
== Changes for models/course.rb ==&lt;br /&gt;
&lt;br /&gt;
== Changes for models/course_participant.rb ==&lt;br /&gt;
&lt;br /&gt;
== Changes for models/course_team.rb ==&lt;br /&gt;
&lt;br /&gt;
== Changes for models/course_node.rb ==&lt;br /&gt;
&lt;br /&gt;
== Miscellaneous Changes for Quality Improvement and Readability ==&lt;/div&gt;</summary>
		<author><name>Kbyarbor</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2013/ch1_1a_MK&amp;diff=73003</id>
		<title>CSC/ECE 517 Spring 2013/ch1 1a MK</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2013/ch1_1a_MK&amp;diff=73003"/>
		<updated>2013-02-15T03:45:04Z</updated>

		<summary type="html">&lt;p&gt;Kbyarbor: /* References */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Writing Meaningful Test case =&lt;br /&gt;
== Introduction ==&lt;br /&gt;
When testing an application, there are several testing methods that can be followed.  Ideally, an application will be tested using all appropriate methods of testing.  This document details four types of testing.  Unit testing deals with tests at an object or class level.  Functional testing verifies the behavior of the application.  Integration testing validates object interaction.  Performance tests focus on the responsiveness and scalability of an application.  A commonality of all these testing methods is that the test results are only as valuable as the tests are meaningful.  Even with almost 100% code coverage, many tests could have assertions returning inaccurate results.  Understanding the testing methods is key to writing meaningful tests cases aimed at testing the most valuable system components with industry best practices.&lt;br /&gt;
&lt;br /&gt;
== Unit Test ==&lt;br /&gt;
The purpose of the unit test process is to ensure each line of code for a module functions correctly to meet functional and technical requirements. In Test Driven Development, test code is developed before or alongside application code. Automated unit tests execute application code after it is built and provide reports on test results.  Furthermore, unit tests are a critical tool for any developer. They allow developers to quickly and easily test code in a repeatable and maintainable way. [http://www.javaworld.com/javaworld/jw-03-2009/jw-03-good-unit-tests-1.html (2)]&lt;br /&gt;
&lt;br /&gt;
=== Advantages and Limitations ===&lt;br /&gt;
==== Advantages ====&lt;br /&gt;
Unit testing provides the following advantages&lt;br /&gt;
* Catch bugs at time of implementation by testing as you develop. Small units of work are easier to code and debug. If you write all  of your code and start testing when coding is complete, then testing will be much more difficult.&lt;br /&gt;
* Easily test changes in code. Because the unit test is designed to test the business case, if the technical implementation changes, the unit test can be rerun to ensure that the technical redesign has not changed the program's result.&lt;br /&gt;
* Prove to your supervisor and yourself that the code works after refactoring or adding functionality.&lt;br /&gt;
* Verify 'corner' cases that may not be tested within the System Test phase.&lt;br /&gt;
* Demonstrate a level of quality to the client.&lt;br /&gt;
* Ensure that no other developer has undermined the quality of the code.&lt;br /&gt;
&lt;br /&gt;
==== Limitation ====&lt;br /&gt;
Software testing is a combinatorial problem. For example, every boolean decision statement requires at least two tests: one with an outcome of &amp;quot;true&amp;quot; and one with an outcome of &amp;quot;false&amp;quot;. As a result, for every line of code written, programmers often need 3 to 5 lines of test code.[http://en.wikipedia.org/wiki/Unit_testing (3)] This obviously takes time and its investment may not be worth the effort. There are also many problems that cannot easily be tested.  For example, those that are nondeterministic or involve multiple threads. In addition, writing code for a unit test is as likely as the source code to be at least as buggy as the code it is testing.&lt;br /&gt;
&lt;br /&gt;
=== Best Practices ===&lt;br /&gt;
[http://wiki.developerforce.com/index.php/How_to_Write_Good_Unit_Tests (4)]&lt;br /&gt;
[http://msdn.microsoft.com/en-us/magazine/cc163665.aspx (5)]&lt;br /&gt;
==== Testing Trivial Code ====&lt;br /&gt;
Unit tests should test those segments of code that are likely to have defects when first developed, or are likely to have defects introduced when changed. Like all software development activities, there is a cost benefit analysis that can be applied to writing unit tests. For normal enterprise business software, it is not worthwhile to test trivial code.&lt;br /&gt;
&lt;br /&gt;
Typical examples of trivial code in Java include simple getter and setter methods for properties and simple constructors.&lt;br /&gt;
&lt;br /&gt;
 class User {&lt;br /&gt;
   private String name;&lt;br /&gt;
 &lt;br /&gt;
   public String getName() {&lt;br /&gt;
     return name;&lt;br /&gt;
   }&lt;br /&gt;
 &lt;br /&gt;
   public void setName(String newName) {&lt;br /&gt;
     name = newName;&lt;br /&gt;
   }&lt;br /&gt;
 }&lt;br /&gt;
 &lt;br /&gt;
 class UserTest extends TestSuite {&lt;br /&gt;
   public void testNameProperty() {&lt;br /&gt;
     User user = new User();&lt;br /&gt;
     assertNull(user.getName());&lt;br /&gt;
 &lt;br /&gt;
     String testName = &amp;quot;test&amp;quot;;&lt;br /&gt;
     user.setName(testName);&lt;br /&gt;
     assertEquals(testName, user.getName());&lt;br /&gt;
   }&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
==== Using hardcoded values when checking test results ====&lt;br /&gt;
Some tests have a hardcoded value when checking the results of some operation. This value is often separately hardcoded in the application code being tested. When the value is changed in the application code, the test is guaranteed to fail. [http://wiki.developerforce.com/index.php/How_to_Write_Good_Unit_Tests (4)]&lt;br /&gt;
&lt;br /&gt;
 class CustomerWebController {&lt;br /&gt;
   public String doOperationReturningNextPage(UserInput input) {&lt;br /&gt;
     // some random logic...&lt;br /&gt;
     return &amp;quot;newCustomer.jsp&amp;quot;;&lt;br /&gt;
   }&lt;br /&gt;
 }&lt;br /&gt;
 &lt;br /&gt;
 class CustomerWebControllerTest extends TestSuite {&lt;br /&gt;
   public void testDoOperation() {&lt;br /&gt;
     CustomerWebController controller = new CustomerWebController();&lt;br /&gt;
     UserInput input = getInputForNewCustomer();&lt;br /&gt;
     String result = controller.doOperationReturningNextPage(input);&lt;br /&gt;
     assertEquals(&amp;quot;newCustomer.jsp&amp;quot;, result);&lt;br /&gt;
   }&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
==== The DRY Principle (Don't Repeat Yourself) ====&lt;br /&gt;
The fix for this is simply the application of the DRY principle: Don't Repeat Yourself (from the book The Pragmatic Programmer: From Journeyman to Master by Andrew Hunt and David Thomas). When you go to use a magic value more than once, define it as a constant (or method) and then refer to that constant (or method).&lt;br /&gt;
To improve the example, we define a constant for the &amp;quot;newCustomer.jsp&amp;quot; value.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
 class CustomerWebController {&lt;br /&gt;
   public static final NEW_CUSTOMER_PAGE = &amp;quot;newCustomer.jsp&amp;quot;;&lt;br /&gt;
     public String doOperationReturningNextPage(UserInput input) {&lt;br /&gt;
       // some random logic...&lt;br /&gt;
       return NEW_CUSTOMER_PAGE;&lt;br /&gt;
     }&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
 &lt;br /&gt;
 class CustomerWebControllerTest extends TestSuite {&lt;br /&gt;
   public void testDoOperation() {&lt;br /&gt;
     CustomerWebController controller = new CustomerWebController();&lt;br /&gt;
     UserInput input = getInputForNewCustomer();&lt;br /&gt;
     String result = controller.doOperationReturningNextPage(input);&lt;br /&gt;
     assertEquals(CustomerWebController.NEW_CUSTOMER_PAGE, result);&lt;br /&gt;
   }&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
==== Being too dependent on specific test data ====&lt;br /&gt;
There is some debate on whether or not unit tests should involve the database.  In practice, this is actually quite common and serves a useful purpose. However, problems often occur because such tests are overly dependent on specific data in the database. As new tests are written and new test data is added, this can cause existing tests to fail regardless of if they are related.  &lt;br /&gt;
&lt;br /&gt;
 class CustomerDataAccess {&lt;br /&gt;
   public List findCustomers(CustomerCriteria criteria) {&lt;br /&gt;
     // Logic to query database based on criteria&lt;br /&gt;
     return customersFound;&lt;br /&gt;
   }&lt;br /&gt;
 &lt;br /&gt;
 class CustomerDataAccessTest extends TestSuite {&lt;br /&gt;
   public void testFindCustomers {&lt;br /&gt;
     CustomerDataAccess customerDataAccess = new CustomerDataAccess();&lt;br /&gt;
     CustomerCriteria criteria = new CustomerCriteria();&lt;br /&gt;
     String firstNameToFind = &amp;quot;Bob&amp;quot;;&lt;br /&gt;
     criteria.firstNameEquals(firstNameToFind);&lt;br /&gt;
     List results = customerDataAcess.findCustomers(criteria);&lt;br /&gt;
     assertEquals(2, results.size());&lt;br /&gt;
   }&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
The following example code has a problem in that the test expects there to be only two customers with a first name of 'Bob', which must have been the case when the test was first written and executed. However, a developer could add another customer named 'Bob' at any point in time while unaware of the existing code.  This could suddenly cause this test to fail.  The general fix for situations such as this it to minimize the number of assumptions you make about the test data. This reduces the level of coupling between the test and the data, which makes either easier to change independently of the other.&lt;br /&gt;
&lt;br /&gt;
To improve this particular example, we simply need to change the test to check that each result matches the criteria we specified.&lt;br /&gt;
&lt;br /&gt;
 class CustomerDataAccessTest extends TestSuite {&lt;br /&gt;
   public void testFindCustomers {&lt;br /&gt;
     CustomerDataAccess customerDataAccess = new CustomerDataAccess();&lt;br /&gt;
     CustomerCriteria criteria = new CustomerCriteria();&lt;br /&gt;
     String firstNameToFind = &amp;quot;Bob&amp;quot;;&lt;br /&gt;
     criteria.firstNameEquals(firstNameToFind);&lt;br /&gt;
     List results = customerDataAcess.findCustomers(criteria);&lt;br /&gt;
     for (Customer customer : results) {&lt;br /&gt;
       assertEquals(firstNameToFind, customer.getFirstName());&lt;br /&gt;
     }&lt;br /&gt;
   }&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
=== Code Coverage ===&lt;br /&gt;
This is an analysis method that determines which parts of the software have been executed (covered) by the test case suite.  It also determines which parts have not been executed and may require additional attention. &lt;br /&gt;
&lt;br /&gt;
http://en.wikipedia.org/wiki/Code_coverage&lt;br /&gt;
&lt;br /&gt;
=== Some Additional Best Practices ===&lt;br /&gt;
*Keep each test independent of others.  &lt;br /&gt;
**Do not make unnecessary assumptions.&lt;br /&gt;
***It is counterproductive to assert anything that is already asserted by another test.  &lt;br /&gt;
***Avoids increasing the frequency of failures related to the same root cause.  &lt;br /&gt;
***Only apply asserts that apply to the functionality being tested.  &lt;br /&gt;
***Follow a rule of one assertion per test.  &lt;br /&gt;
**Test one set of code at a time.  &lt;br /&gt;
**Avoid unnecessary preconditions.  &lt;br /&gt;
***Only run preliminary code that is related to the test to be run.  &lt;br /&gt;
***Use common preliminary code only when the associated tests actually require it.  &lt;br /&gt;
*Keep configuration settings separate from the unit tests.  &lt;br /&gt;
*Use clear and consistent naming for all unit tests.&lt;br /&gt;
&lt;br /&gt;
[http://blog.stevensanderson.com/2009/08/24/writing-great-unit-tests-best-and-worst-practises/ (17)]&lt;br /&gt;
&lt;br /&gt;
=== Effective Use of Assertions ===&lt;br /&gt;
*Make one logical assertion per test.  &lt;br /&gt;
*Each assert should be made in relation to the functionality being tested.  &lt;br /&gt;
*Avoid making any assertions that are already covered by another existing assertion.&lt;br /&gt;
&lt;br /&gt;
=== Writing Effective Unit Tests ===&lt;br /&gt;
*Scope is crucial. &lt;br /&gt;
**Narrow scope may result in trivial test results that provide no real value.  &lt;br /&gt;
**Broad scope may test too much that it becomes difficult to determine root cause of failures.  &lt;br /&gt;
*Group tests according to a major feature/functionality.&lt;br /&gt;
**Include enough tests to cover that specific feature/functionality.  &lt;br /&gt;
*Define unit tests at the method level.&lt;br /&gt;
**Some methods will involve groups of objects.  In this case, testing should isolate the groups of objects for testing.  &lt;br /&gt;
***Identifies segments of related code.  &lt;br /&gt;
*Read the code and check if it catches an error or throws an error.  &lt;br /&gt;
**Easy identification of a method with potential to break.  &lt;br /&gt;
**Unit tests should cover error scenarios.&lt;br /&gt;
*Total unit tests should cover the functional requirements of the code at a minimum.&lt;br /&gt;
&lt;br /&gt;
[http://users.csc.calpoly.edu/~cstaley/General/TestingHowTo.htm (8)][http://ubiquity.acm.org/article.cfm?id=358976 (18)]&lt;br /&gt;
&lt;br /&gt;
=== Brief Description of Some Available Unit Testing Tools ===&lt;br /&gt;
[http://www.tejasconsulting.com/open-testware/feature/unit-test-tool-survey.html (6)][http://www.aptest.com/resources.html (9)]&lt;br /&gt;
*GrandTestAuto [http://grandtestauto.org/ (19)]&lt;br /&gt;
**Enables completely automated testing of Java software. &lt;br /&gt;
**More advanced than JUnit.  &lt;br /&gt;
**Simple to use.  &lt;br /&gt;
**Supports distribution of tests across a network. &lt;br /&gt;
**Integrates with additional tools.  &lt;br /&gt;
*JUnit [http://www.softwaresummit.com/2004/speakers/SteltingTestingJ2EE.pdf (7)][http://www.javapractices.com/topic/TopicAction.do?Id=33 (20)]&lt;br /&gt;
**Enables automated testing of Java software. &lt;br /&gt;
**Simple to use.  &lt;br /&gt;
**Makes it easy to identify test failures.  &lt;br /&gt;
**Open source tool.  &lt;br /&gt;
*NUnit [http://nunit.org/ (21)]&lt;br /&gt;
**Provides a unit testing framework for .NET software.  &lt;br /&gt;
**Takes advantage of existing .NET language features.&lt;br /&gt;
&lt;br /&gt;
== Functional Test ==&lt;br /&gt;
The purpose of functional test is to measure the behavioral quality of a software application. Functional tests verify that the system responds appropriately from the user perspective and functions according to the design requirements used to specify the application. The functional test must determine if each component of a software application performs in accordance to the specifications, responds correctly to all conditions that may be presented by incoming events, processes incoming events correctly from one business event to the other, and produces an appropriate outcome from incoming events.&lt;br /&gt;
&lt;br /&gt;
=== Advantages ===&lt;br /&gt;
Functional has several benefits in order to develop a robust software application. Here are the advantages:&lt;br /&gt;
* It verifies that an application works as per specifications across multiple platforms, browsers and technologies.&lt;br /&gt;
* Make sure that a certain feature is completed from a user's point of view.&lt;br /&gt;
* A tester needs no knowledge of implementation, including specific programming languages in order to execute the test.&lt;br /&gt;
* Tester and programmer are independent from each other &lt;br /&gt;
* It will help to expose any ambiguities or inconsistencies in the specification&lt;br /&gt;
* Test cases can be designed as soon as the specification is completed.&lt;br /&gt;
&lt;br /&gt;
=== Best Practices ===&lt;br /&gt;
Functional tests are the measurement for an application's code completion. It makes sure that all the feature and functionalities are working as expected from an end user perspective. Therefore, it is important to design functional tests that will expose any vulnerabilities and assure confidence in an application. Before writing a test, it is very important to understand how the software is supposed to behave. Functional specification documents will have all the details about the behavior of the application. The first thing to do before writing any test cases is to write the functional specification document. Once the specification is read, it is important to organize tests to make sure that they cover each and every feature and functionality of the application. This will make sure that all the components are thoroughly tested and enable identify any gaps in testing. Test cases should be written prior to developing functionality. This will lead to identification of preconditions and establish expected behavior.  Additionally, this will help to automate the functional tests and enables another person to run the test regardless of their knowledge of the expected behavior. The test cases should also cover very rare situations. Software developers tend to develop applications strictly according to its specification. They may not appropriately code the program to work for rare cases. A majority of the bugs are found when applications are used in rare input conditions.  Therefore, it is important to make sure that functional tests are created to test boundary conditions, error cases, and rare input cases.&lt;br /&gt;
&lt;br /&gt;
=== Ensuring Effectiveness and Efficiency Through the Functional Testing Lifecycle ===&lt;br /&gt;
*Requirements Gathering&lt;br /&gt;
**Define clear and complete requirements that can be tested.  &lt;br /&gt;
*Test Planning&lt;br /&gt;
**Establish guidelines and standards for creating tests.  &lt;br /&gt;
**Identify the required hardware and software for the testing environment.  &lt;br /&gt;
*Test Strategizing&lt;br /&gt;
**Utilize resources to achieve optimum test coverage. &lt;br /&gt;
*Test Execution&lt;br /&gt;
**Define an efficient test execution flow.  &lt;br /&gt;
*Collect Testing Metrics&lt;br /&gt;
**Gauge the test progress and quality of the testing. &lt;br /&gt;
**Make continuous improvements as needed.&lt;br /&gt;
&lt;br /&gt;
[http://www.infosys.com/engineering-services/white-papers/Documents/functional-testing.pdf (22)]&lt;br /&gt;
&lt;br /&gt;
=== Writing functional tests ===&lt;br /&gt;
An application may have several features and each of those features have several functionalities of their own. With a vast number of overall functionalities, there is a possibility that a functionality may be overlooked.  Therefore, it is a good practice to organize test cases by their features and functionalities. This can help ensure that no feature or functionality is missed. &lt;br /&gt;
&lt;br /&gt;
The following is a sample organization structure of functional test cases:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;Feature 1&amp;gt;&lt;br /&gt;
   &amp;lt;Function 1&amp;gt;&lt;br /&gt;
     &amp;lt;Test 1&amp;gt;&lt;br /&gt;
     &amp;lt;Test 1/&amp;gt;&lt;br /&gt;
     &amp;lt;Test 2&amp;gt;&lt;br /&gt;
     &amp;lt;Test 2/&amp;gt;&lt;br /&gt;
     …&lt;br /&gt;
   &amp;lt;Function 1/&amp;gt;&lt;br /&gt;
 &amp;lt;Feature 1/&amp;gt;&lt;br /&gt;
 &amp;lt;Feature 2&amp;gt;&lt;br /&gt;
   &amp;lt;Function 1&amp;gt;&lt;br /&gt;
     &amp;lt;Test 1&amp;gt;&lt;br /&gt;
     &amp;lt;Test 1/&amp;gt;&lt;br /&gt;
     …&lt;br /&gt;
   &amp;lt;Function 1/&amp;gt;&lt;br /&gt;
   …&lt;br /&gt;
 &amp;lt;Feature 2/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Test cases can be executed by anybody if they are written in a meaningful way for anyone to understand. In order to create a meaningful test case, a test case should have specific components. First, it should have a purpose statement on what it is intended to test. Second, the test case should have a setup component that is run prior to executing the test. Third, it should have steps to execute the test. Fourth, it should have expected behavior to compare against for the determination of if the test passed or failed.  Finally, it should have a cleanup procedure to make sure that the system is reverting back to the original state. &lt;br /&gt;
&lt;br /&gt;
Here is a sample of a test case:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;Test 1&amp;gt;&lt;br /&gt;
   &amp;lt;Purpose&amp;gt;&lt;br /&gt;
     “Purpose of the test case”&lt;br /&gt;
   &amp;lt;Purpose/&amp;gt;&lt;br /&gt;
   &amp;lt;Setup&amp;gt;&lt;br /&gt;
     “Steps to prepare the system prior to executing the test case”&lt;br /&gt;
   &amp;lt;Setup/&amp;gt;&lt;br /&gt;
   &amp;lt;Execution&amp;gt;&lt;br /&gt;
     “Steps required executing the test”&lt;br /&gt;
   &amp;lt;Execution/&amp;gt;&lt;br /&gt;
   &amp;lt;Expected Behavior&amp;gt;&lt;br /&gt;
     “Expected behavior of the test case”&lt;br /&gt;
   &amp;lt;Expected Behavior/&amp;gt;&lt;br /&gt;
   &amp;lt;Cleanup&amp;gt;&lt;br /&gt;
     “Steps required to cleaning up the environment to revert back”&lt;br /&gt;
   &amp;lt;Cleanup/&amp;gt;&lt;br /&gt;
 &amp;lt;Test 1/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Writing functional test cases for 100% coverage can be a seemingly impossible task that would require a tester to continue writing functional test forever. Even when there are several functionalities requiring testing, there can be situations in which the functional testing of major functionalities and features must be completed in a short amount of time.  This type of situation can be handled by assigning priorities to each functional test.  Higher priority tests should cover key features.  Lower priority tests should cover less important features.&lt;br /&gt;
&lt;br /&gt;
=== Functionality test tools ===&lt;br /&gt;
Functional tests can become very large in size and that can make them difficult to maintain and time-consuming to execute manually. Therefore, it is a good practice to automate the test cases. Automating tests can reduce the amount of time between notifications of problem introductions and having such problems addressed.  [http://dmcnulla.wordpress.com/2012/01/28/good-practices-for-automating-functional-tests/ (1)] There are several tools available that automate functional testing. Here are some lists of some of the tools available:&lt;br /&gt;
&lt;br /&gt;
==== Quick Test Professional ====&lt;br /&gt;
The Quick Test Professional tool enables the automation of functional tests through an user interface. It detects objects in the user interface and performs desired operations simulating a mouse click or keyboard events. The tool can also be used to automate functional tests on graphical and non-graphical user interfaces. It allows collaboration through the storage of similar object definitions in a single repository manager, which can be shared among other testers. The same repository can maintain automated and manual test cases.&lt;br /&gt;
&lt;br /&gt;
==== JFunc ====&lt;br /&gt;
JFunc is an open-source functional testing tool that helps to automate functional test cases.  JFunc is an extension of the JUnit test framework. It serves to ease the creation of manual functional test suites. JFunc can handle multiple test failures by allowing the functional test to not exit after the first failure.  Verbose assertions have more detail about the test failures and error messages.  New arguments can be passed into a test each time it runs.&lt;br /&gt;
&lt;br /&gt;
==== Waitir ====&lt;br /&gt;
Waitir is a web application testing tool for the Ruby language. Waitir tests the web application on all web browsers on different platforms. It distinguishes from other web application functional testing tools by executing tests at the web browser layer and by driving a web browser and the interacting with objects on a web page.  This is more accurate than manual functional testing. Here is a sample test case that validates the search operation:&lt;br /&gt;
&lt;br /&gt;
 #------------------------------------------------------------------------------------------------------------------#&lt;br /&gt;
 # Purpose: To Validate the search capability of the browser.&lt;br /&gt;
 #------------------------------------------------------------------------------------------------------------------#&lt;br /&gt;
 #------------------------------------------------------------------------------------------------------------------#&lt;br /&gt;
 # Setup:&lt;br /&gt;
 #------------------------------------------------------------------------------------------------------------------#&lt;br /&gt;
   require &amp;quot;watir&amp;quot;&lt;br /&gt;
   test_site = &amp;quot;http://www.google.com&amp;quot;&lt;br /&gt;
   browser = Watir::Browser.new&lt;br /&gt;
   browser.goto test_site&lt;br /&gt;
   browser.text_field(:name, &amp;quot;q&amp;quot;).set &amp;quot;pickaxe&amp;quot;&lt;br /&gt;
 #------------------------------------------------------------------------------------------------------------------#&lt;br /&gt;
 # Execution:&lt;br /&gt;
 #------------------------------------------------------------------------------------------------------------------#&lt;br /&gt;
   browser.button(:name, &amp;quot;btnG&amp;quot;).click # &amp;quot;btnG&amp;quot; is the name of the Search button&lt;br /&gt;
 #-------------------------------------------------------------#&lt;br /&gt;
 # Expected Behavior: “A Google page with results should be shown. 'Programming Ruby' should be high on the list.&amp;quot;&lt;br /&gt;
 #------------------------------------------------------------------------------------------------------------------#&lt;br /&gt;
   if browser.text.include? &amp;quot;Programming Ruby&amp;quot;  &lt;br /&gt;
     puts &amp;quot;  Test Passed. Found the test string: 'Programming Ruby'. Actual Results match Expected Results.&amp;quot;&lt;br /&gt;
   else&lt;br /&gt;
     puts &amp;quot;  Test Failed! Could not find: 'Programming Ruby'.&amp;quot; &lt;br /&gt;
   End&lt;br /&gt;
 #------------------------------------------------------------------------------------------------------------------#&lt;br /&gt;
 #Cleanup: &lt;br /&gt;
 #------------------------------------------------------------------------------------------------------------------#&lt;br /&gt;
   browser.close&lt;br /&gt;
&lt;br /&gt;
=== Additional Functional Testing Tools ===&lt;br /&gt;
*Arbiter [http://arbiter.sourceforge.net/ (24)]&lt;br /&gt;
**Document-based acceptance testing. &lt;br /&gt;
**Driven by requirements documents in Microsoft Word or RTF file formats.  &lt;br /&gt;
**Requirements are used to establish a glossary and test suite.  &lt;br /&gt;
*Blerby Test Runner [https://github.com/tmpvar/Blerby-Test-Runner (25)]&lt;br /&gt;
**Ajax test runner for php software. &lt;br /&gt;
**Allows for instant feedback while performing on-the-fly code refactoring.  &lt;br /&gt;
**Tracks test dependencies.&lt;br /&gt;
**Automatically re-runs affected tests when corresponding code changes.&lt;br /&gt;
*Concordion [http://www.concordion.org/ (26)]&lt;br /&gt;
**Open source framework for testing Java software. &lt;br /&gt;
**Allows for plain English descriptions of requirements to be converted into automated tests.  &lt;br /&gt;
**Specifications are linked to the software system itself and prevents tests from becoming outdated. &lt;br /&gt;
**Notifications inform when a change in system behavior causes associated test to fail.  &lt;br /&gt;
*Eclipse Jubula [http://www.eclipse.org/jubula/ (27)]&lt;br /&gt;
**Provides automated UI functional testing for HTML and Java applications.  &lt;br /&gt;
**Aimed at creating tests from the user perspective.  &lt;br /&gt;
**Limited coding efforts required.&lt;br /&gt;
*Robotium [http://code.google.com/p/robotium/ (28)]&lt;br /&gt;
**Test framework to write black-box and white-box tests for Android applications. &lt;br /&gt;
**Requires test case suite to be installed on the same device or simulator as the application.  &lt;br /&gt;
**Access the application to execute tests scenarios in a real environment.&lt;br /&gt;
&lt;br /&gt;
[http://www.opensourcetesting.org/functional.php (23)]&lt;br /&gt;
&lt;br /&gt;
== Integration Test == &lt;br /&gt;
The purpose of integration testing is to test the combination of individual components working together.  This type of testing can expose faults that result from the interaction between the integrated components.  [http://softwaretestingfundamentals.com/integration-testing/ (13)]&lt;br /&gt;
&lt;br /&gt;
=== Various Approaches to Integration Testing ===&lt;br /&gt;
*Big Bang - All or most of the individual components are combined and tested at one time.  This approach is typically utilized when a test team receives an entire software bundle. &lt;br /&gt;
*Top Down - Top level components are tested initially.  Lower level components are tested subsequently in a step by step method.  This approach is used whenever development is taking the same type of approach.  In this approach, test stubs are needed to simulate lower level components that are not yet available.  &lt;br /&gt;
*Bottom Up - Bottom level components are tested initially.  This approach is used whenever development is taking the same type of approach.  In this approach, test stubs are needed to simulate higher level components that are not yet available.  &lt;br /&gt;
*Sandwich/Hybrid - This approach is a combination of the Top Down and Bottom up approaches.&lt;br /&gt;
&lt;br /&gt;
=== Advantages to Each Approach ===&lt;br /&gt;
*Big Bang&lt;br /&gt;
**Convenient for smaller systems. &lt;br /&gt;
**Quick.&lt;br /&gt;
**Cheap.&lt;br /&gt;
**No stubs or stand-in objects are needed.&lt;br /&gt;
*Top Down&lt;br /&gt;
**Potential for early identification of major flaws near the top of the product.  &lt;br /&gt;
**Critical components are tested on priority.  &lt;br /&gt;
**Easier to isolate root cause of interface errors due to the incremental approach.&lt;br /&gt;
*Bottom Up&lt;br /&gt;
**Potential for early identification of major flaws near the bottom of the product. &lt;br /&gt;
**Easier to create test conditions. &lt;br /&gt;
**No need to wait for all modules to be developed.  &lt;br /&gt;
**Each component and unit gets tested for correctness before being integrated.  &lt;br /&gt;
**Typically results in a more robust system.  &lt;br /&gt;
*Sandwich/Hybrid&lt;br /&gt;
**Useful for larger projects with several subprojects.&lt;br /&gt;
&lt;br /&gt;
[http://www.itdivisioninc.com/IntegrationTesting.aspx (15)]&lt;br /&gt;
&lt;br /&gt;
=== Best Practices ===&lt;br /&gt;
*Create only the integration tests needed.  These tests offer great value at the cost of a great amount of work to properly set up and time to execute.  Consider only testing the default scenarios.  There should be enough testing to validate that critical or high-severity defects no longer exist.  &lt;br /&gt;
*Do not depend on specific data to be available to the test.  Always have any necessary data created prior to the execution of a test.  Anyone with proper access could delete or modify test data and break a test, which is another reason it should not be assumed to be available.  &lt;br /&gt;
*Use multiple asserts for each test.  Due to the time consumption of integration tests, it is recommended that tests be consolidated.  In this type of testing, it is considered better to ignore following a one assert per test rule.  &lt;br /&gt;
*When seeking to validate the same functionality and there is an option between creating a unit test or an integration test, always choose the unit test.  Unit tests will run faster and be easier to set up.&lt;br /&gt;
&lt;br /&gt;
[http://msdn.microsoft.com/en-us/library/vstudio/hh323698(v=vs.100).aspx#erg (14)]&lt;br /&gt;
&lt;br /&gt;
=== Available Integration Testing Tools ===&lt;br /&gt;
*eggPlant [http://www.testplant.com/products/eggplant/ (30)]&lt;br /&gt;
**Focused on testing the user experience.  [http://www.testplant.com/blog/2011/06/09/integration-testing/ (29)]&lt;br /&gt;
**Black-box test automation tool. &lt;br /&gt;
**Low overhead.&lt;br /&gt;
**Non-invasive.  Not required to run on the same system under test.  &lt;br /&gt;
**Image capture and search techniques prevent most UI changes from affecting existing tests.&lt;br /&gt;
*Ruby Capybara [https://www.ruby-toolbox.com/projects/capybara (31)]&lt;br /&gt;
**Designed for Ruby on Rails applications. &lt;br /&gt;
**Tests rack-based web applications.  &lt;br /&gt;
**Simulates how a user interacts with a website.  &lt;br /&gt;
*Selenium  [http://seleniumhq.org/ (33)]&lt;br /&gt;
**Provides automated integration testing for Java web applications.  [http://www.developer.com/java/web/article.php/3872691/Selenium-Automated-Integration-Testing-for-Java-Web-Apps.htm (32)]&lt;br /&gt;
**Provides automation-aided exploratory testing.  &lt;br /&gt;
**Distributes testing across many environments.  &lt;br /&gt;
**Supports testing on many types of web browsers.&lt;br /&gt;
&lt;br /&gt;
== Performance Test ==&lt;br /&gt;
The purpose of performance testing is to determine speed and effectiveness.  Various quantitative and qualitative attributes may be used.  Examples of quantitative attributes include response time and number of MIPS (millions of instructions per second).  Examples of qualitative attributes include scalability, interoperability, and reliability.  [http://performance-testing.org/performance-testing-definitions (10)]&lt;br /&gt;
&lt;br /&gt;
Performance testing can be used to determine the speed of a specific aspect of a system with a specific workload.  This allows for the identification of poor performance areas and for the establishment of acceptable thresholds required to maintain acceptable response time.  &lt;br /&gt;
&lt;br /&gt;
There are several types of performance testing.  Understanding the various types helps to minimize cost, reduce risk, and to know when it is appropriate to apply which type of test on a project.  &lt;br /&gt;
&lt;br /&gt;
=== Key Types of Performance Testing &amp;amp; Their Advantages === &lt;br /&gt;
*Performance test - Determines speed, stability, and/or scalability.&lt;br /&gt;
**Focuses on determining user satisfaction with regards to performance. &lt;br /&gt;
**Identifies differences between the expectations and reality of existing performance. &lt;br /&gt;
**Supports optimization and capacity planning. &lt;br /&gt;
*Load test - Verifies application behavior under both normal and peak load conditions. &lt;br /&gt;
**The hardware environment is evaluated for adequacy.  &lt;br /&gt;
**Detects concurrency issues.  &lt;br /&gt;
**Detects functional errors that occur under load.  &lt;br /&gt;
**Supports determination of maximum simultaneous users prior to performance being compromised. &lt;br /&gt;
**Supports determination of maximum load before limits of resource utilization are exceeded. &lt;br /&gt;
*Stress test - Determines behavior when conditions exceed normal or peak load conditions.&lt;br /&gt;
**Identifies if over-stressing the system can corrupt data. &lt;br /&gt;
**Supports establishment of application-monitoring triggers that can warn of impending failures.  &lt;br /&gt;
**Determines side effects of failures related to hardware or applications. &lt;br /&gt;
**Identifies the kinds of failures to plan for.   &lt;br /&gt;
*Capacity test - Determines the amount of users and/or transactions that can be supported while continuing to meet performance goals.  &lt;br /&gt;
**Provides capacity data that can be used to validate or enhance models.  &lt;br /&gt;
**Determines current usage and capacity of the system. &lt;br /&gt;
**Provides data on capacity and usage trends of the system.&lt;br /&gt;
&lt;br /&gt;
[http://msdn.microsoft.com/en-us/library/bb924357.aspx (11)]&lt;br /&gt;
&lt;br /&gt;
=== Best Practices ===&lt;br /&gt;
*Test the code with the same granularity as used for unit tests. &lt;br /&gt;
*Do not perform lots of assertions on the test results. &lt;br /&gt;
*Test enough to measure statistically significant performance differences. &lt;br /&gt;
*Ideal performance tests should run relatively fast. &lt;br /&gt;
*Test setup should be performed independent of the actual test method.&lt;br /&gt;
&lt;br /&gt;
[http://www.mantidproject.org/Writing_Performance_Tests#Best_Practice_Advice (12)]&lt;br /&gt;
&lt;br /&gt;
=== Available Performance Testing Tools ===&lt;br /&gt;
*AgileLoad&lt;br /&gt;
**Provides load testing for mobile and web applications. &lt;br /&gt;
**Designed to fit into the Agile Development methodology.  &lt;br /&gt;
**Windows-based.  &lt;br /&gt;
**Tests applications designed for use on cloud or internal networks. &lt;br /&gt;
*Forecast&lt;br /&gt;
**Tests IT systems for performance, reliability, and scalability.&lt;br /&gt;
**Realistically simulates multiple thousands of unique users simultaneously accessing functionalities.  &lt;br /&gt;
**Avoids the overhead and expense associated with hardware costs. &lt;br /&gt;
*HP LoadRunner&lt;br /&gt;
**Detects bottlenecks.  &lt;br /&gt;
**Emulates production workloads.  &lt;br /&gt;
**Diagnoses root cause of performance issues.  &lt;br /&gt;
**Improves performance prior to application deployment.  &lt;br /&gt;
*IBM Rational Performance Tester&lt;br /&gt;
**Identifies both the presence and cause of performance bottlenecks.  &lt;br /&gt;
**Provides problem identification and problem diagnosis.  &lt;br /&gt;
**Root Cause Analysis features allows for identifying source code causing performance issues.  &lt;br /&gt;
**Real-time reports are viewable via web browser.   &lt;br /&gt;
*RTI&lt;br /&gt;
**Measures application performance based on response times for transactions with poor performance.  &lt;br /&gt;
**Dynamically collects performance data and diagnoses problems throughout system aspects.  &lt;br /&gt;
**Quantifies and validates application architectures.  &lt;br /&gt;
*SilkPerformer&lt;br /&gt;
**Provides performance and load testing for software applications. &lt;br /&gt;
**Automates software load and stress.  &lt;br /&gt;
**Enables identification of bottlenecks.   &lt;br /&gt;
**Diagnostic tools may be applied to resolve performance issues.&lt;br /&gt;
&lt;br /&gt;
[http://www.toolsjournal.com/tools-world/item/156-top-performance-testing-tools (34)]&lt;br /&gt;
&lt;br /&gt;
== References == &lt;br /&gt;
[1] http://dmcnulla.wordpress.com/2012/01/28/good-practices-for-automating-functional-tests/&lt;br /&gt;
&lt;br /&gt;
[2] http://www.javaworld.com/javaworld/jw-03-2009/jw-03-good-unit-tests-1.html&lt;br /&gt;
&lt;br /&gt;
[3] http://en.wikipedia.org/wiki/Unit_testing&lt;br /&gt;
&lt;br /&gt;
[4] http://wiki.developerforce.com/index.php/How_to_Write_Good_Unit_Tests&lt;br /&gt;
&lt;br /&gt;
[5] http://msdn.microsoft.com/en-us/magazine/cc163665.aspx&lt;br /&gt;
&lt;br /&gt;
[6] http://www.tejasconsulting.com/open-testware/feature/unit-test-tool-survey.html&lt;br /&gt;
&lt;br /&gt;
[7] http://www.softwaresummit.com/2004/speakers/SteltingTestingJ2EE.pdf&lt;br /&gt;
&lt;br /&gt;
[8] http://users.csc.calpoly.edu/~cstaley/General/TestingHowTo.htm&lt;br /&gt;
&lt;br /&gt;
[9] http://www.aptest.com/resources.html&lt;br /&gt;
&lt;br /&gt;
[10] http://performance-testing.org/performance-testing-definitions&lt;br /&gt;
&lt;br /&gt;
[11] http://msdn.microsoft.com/en-us/library/bb924357.aspx&lt;br /&gt;
&lt;br /&gt;
[12] http://www.mantidproject.org/Writing_Performance_Tests#Best_Practice_Advice&lt;br /&gt;
&lt;br /&gt;
[13] http://softwaretestingfundamentals.com/integration-testing/&lt;br /&gt;
&lt;br /&gt;
[14] http://msdn.microsoft.com/en-us/library/vstudio/hh323698(v=vs.100).aspx#erg&lt;br /&gt;
&lt;br /&gt;
[15] http://www.itdivisioninc.com/IntegrationTesting.aspx&lt;br /&gt;
&lt;br /&gt;
[16] http://wiki.expertiza.ncsu.edu/index.php/CSC/ECE_517_Fall_2010/ch1_2e_RI&lt;br /&gt;
&lt;br /&gt;
[17] http://blog.stevensanderson.com/2009/08/24/writing-great-unit-tests-best-and-worst-practises/&lt;br /&gt;
&lt;br /&gt;
[18] http://ubiquity.acm.org/article.cfm?id=358976&lt;br /&gt;
&lt;br /&gt;
[19] http://grandtestauto.org/&lt;br /&gt;
&lt;br /&gt;
[20] http://www.javapractices.com/topic/TopicAction.do?Id=33&lt;br /&gt;
&lt;br /&gt;
[21] http://nunit.org/&lt;br /&gt;
&lt;br /&gt;
[22] http://www.infosys.com/engineering-services/white-papers/Documents/functional-testing.pdf&lt;br /&gt;
&lt;br /&gt;
[23] http://www.opensourcetesting.org/functional.php&lt;br /&gt;
&lt;br /&gt;
[24] http://arbiter.sourceforge.net/&lt;br /&gt;
&lt;br /&gt;
[25] https://github.com/tmpvar/Blerby-Test-Runner&lt;br /&gt;
&lt;br /&gt;
[26] http://www.concordion.org/&lt;br /&gt;
&lt;br /&gt;
[27] http://www.eclipse.org/jubula/&lt;br /&gt;
&lt;br /&gt;
[28] http://code.google.com/p/robotium/&lt;br /&gt;
&lt;br /&gt;
[29] http://www.testplant.com/blog/2011/06/09/integration-testing/&lt;br /&gt;
&lt;br /&gt;
[30] http://www.testplant.com/products/eggplant/&lt;br /&gt;
&lt;br /&gt;
[31] https://www.ruby-toolbox.com/projects/capybara&lt;br /&gt;
&lt;br /&gt;
[32] http://www.developer.com/java/web/article.php/3872691/Selenium-Automated-Integration-Testing-for-Java-Web-Apps.htm&lt;br /&gt;
&lt;br /&gt;
[33] http://seleniumhq.org/&lt;br /&gt;
&lt;br /&gt;
[34] http://www.toolsjournal.com/tools-world/item/156-top-performance-testing-tools&lt;/div&gt;</summary>
		<author><name>Kbyarbor</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2013/ch1_1a_MK&amp;diff=73002</id>
		<title>CSC/ECE 517 Spring 2013/ch1 1a MK</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2013/ch1_1a_MK&amp;diff=73002"/>
		<updated>2013-02-15T03:44:49Z</updated>

		<summary type="html">&lt;p&gt;Kbyarbor: /* Functionality test tools */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Writing Meaningful Test case =&lt;br /&gt;
== Introduction ==&lt;br /&gt;
When testing an application, there are several testing methods that can be followed.  Ideally, an application will be tested using all appropriate methods of testing.  This document details four types of testing.  Unit testing deals with tests at an object or class level.  Functional testing verifies the behavior of the application.  Integration testing validates object interaction.  Performance tests focus on the responsiveness and scalability of an application.  A commonality of all these testing methods is that the test results are only as valuable as the tests are meaningful.  Even with almost 100% code coverage, many tests could have assertions returning inaccurate results.  Understanding the testing methods is key to writing meaningful tests cases aimed at testing the most valuable system components with industry best practices.&lt;br /&gt;
&lt;br /&gt;
== Unit Test ==&lt;br /&gt;
The purpose of the unit test process is to ensure each line of code for a module functions correctly to meet functional and technical requirements. In Test Driven Development, test code is developed before or alongside application code. Automated unit tests execute application code after it is built and provide reports on test results.  Furthermore, unit tests are a critical tool for any developer. They allow developers to quickly and easily test code in a repeatable and maintainable way. [http://www.javaworld.com/javaworld/jw-03-2009/jw-03-good-unit-tests-1.html (2)]&lt;br /&gt;
&lt;br /&gt;
=== Advantages and Limitations ===&lt;br /&gt;
==== Advantages ====&lt;br /&gt;
Unit testing provides the following advantages&lt;br /&gt;
* Catch bugs at time of implementation by testing as you develop. Small units of work are easier to code and debug. If you write all  of your code and start testing when coding is complete, then testing will be much more difficult.&lt;br /&gt;
* Easily test changes in code. Because the unit test is designed to test the business case, if the technical implementation changes, the unit test can be rerun to ensure that the technical redesign has not changed the program's result.&lt;br /&gt;
* Prove to your supervisor and yourself that the code works after refactoring or adding functionality.&lt;br /&gt;
* Verify 'corner' cases that may not be tested within the System Test phase.&lt;br /&gt;
* Demonstrate a level of quality to the client.&lt;br /&gt;
* Ensure that no other developer has undermined the quality of the code.&lt;br /&gt;
&lt;br /&gt;
==== Limitation ====&lt;br /&gt;
Software testing is a combinatorial problem. For example, every boolean decision statement requires at least two tests: one with an outcome of &amp;quot;true&amp;quot; and one with an outcome of &amp;quot;false&amp;quot;. As a result, for every line of code written, programmers often need 3 to 5 lines of test code.[http://en.wikipedia.org/wiki/Unit_testing (3)] This obviously takes time and its investment may not be worth the effort. There are also many problems that cannot easily be tested.  For example, those that are nondeterministic or involve multiple threads. In addition, writing code for a unit test is as likely as the source code to be at least as buggy as the code it is testing.&lt;br /&gt;
&lt;br /&gt;
=== Best Practices ===&lt;br /&gt;
[http://wiki.developerforce.com/index.php/How_to_Write_Good_Unit_Tests (4)]&lt;br /&gt;
[http://msdn.microsoft.com/en-us/magazine/cc163665.aspx (5)]&lt;br /&gt;
==== Testing Trivial Code ====&lt;br /&gt;
Unit tests should test those segments of code that are likely to have defects when first developed, or are likely to have defects introduced when changed. Like all software development activities, there is a cost benefit analysis that can be applied to writing unit tests. For normal enterprise business software, it is not worthwhile to test trivial code.&lt;br /&gt;
&lt;br /&gt;
Typical examples of trivial code in Java include simple getter and setter methods for properties and simple constructors.&lt;br /&gt;
&lt;br /&gt;
 class User {&lt;br /&gt;
   private String name;&lt;br /&gt;
 &lt;br /&gt;
   public String getName() {&lt;br /&gt;
     return name;&lt;br /&gt;
   }&lt;br /&gt;
 &lt;br /&gt;
   public void setName(String newName) {&lt;br /&gt;
     name = newName;&lt;br /&gt;
   }&lt;br /&gt;
 }&lt;br /&gt;
 &lt;br /&gt;
 class UserTest extends TestSuite {&lt;br /&gt;
   public void testNameProperty() {&lt;br /&gt;
     User user = new User();&lt;br /&gt;
     assertNull(user.getName());&lt;br /&gt;
 &lt;br /&gt;
     String testName = &amp;quot;test&amp;quot;;&lt;br /&gt;
     user.setName(testName);&lt;br /&gt;
     assertEquals(testName, user.getName());&lt;br /&gt;
   }&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
==== Using hardcoded values when checking test results ====&lt;br /&gt;
Some tests have a hardcoded value when checking the results of some operation. This value is often separately hardcoded in the application code being tested. When the value is changed in the application code, the test is guaranteed to fail. [http://wiki.developerforce.com/index.php/How_to_Write_Good_Unit_Tests (4)]&lt;br /&gt;
&lt;br /&gt;
 class CustomerWebController {&lt;br /&gt;
   public String doOperationReturningNextPage(UserInput input) {&lt;br /&gt;
     // some random logic...&lt;br /&gt;
     return &amp;quot;newCustomer.jsp&amp;quot;;&lt;br /&gt;
   }&lt;br /&gt;
 }&lt;br /&gt;
 &lt;br /&gt;
 class CustomerWebControllerTest extends TestSuite {&lt;br /&gt;
   public void testDoOperation() {&lt;br /&gt;
     CustomerWebController controller = new CustomerWebController();&lt;br /&gt;
     UserInput input = getInputForNewCustomer();&lt;br /&gt;
     String result = controller.doOperationReturningNextPage(input);&lt;br /&gt;
     assertEquals(&amp;quot;newCustomer.jsp&amp;quot;, result);&lt;br /&gt;
   }&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
==== The DRY Principle (Don't Repeat Yourself) ====&lt;br /&gt;
The fix for this is simply the application of the DRY principle: Don't Repeat Yourself (from the book The Pragmatic Programmer: From Journeyman to Master by Andrew Hunt and David Thomas). When you go to use a magic value more than once, define it as a constant (or method) and then refer to that constant (or method).&lt;br /&gt;
To improve the example, we define a constant for the &amp;quot;newCustomer.jsp&amp;quot; value.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
 class CustomerWebController {&lt;br /&gt;
   public static final NEW_CUSTOMER_PAGE = &amp;quot;newCustomer.jsp&amp;quot;;&lt;br /&gt;
     public String doOperationReturningNextPage(UserInput input) {&lt;br /&gt;
       // some random logic...&lt;br /&gt;
       return NEW_CUSTOMER_PAGE;&lt;br /&gt;
     }&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
 &lt;br /&gt;
 class CustomerWebControllerTest extends TestSuite {&lt;br /&gt;
   public void testDoOperation() {&lt;br /&gt;
     CustomerWebController controller = new CustomerWebController();&lt;br /&gt;
     UserInput input = getInputForNewCustomer();&lt;br /&gt;
     String result = controller.doOperationReturningNextPage(input);&lt;br /&gt;
     assertEquals(CustomerWebController.NEW_CUSTOMER_PAGE, result);&lt;br /&gt;
   }&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
==== Being too dependent on specific test data ====&lt;br /&gt;
There is some debate on whether or not unit tests should involve the database.  In practice, this is actually quite common and serves a useful purpose. However, problems often occur because such tests are overly dependent on specific data in the database. As new tests are written and new test data is added, this can cause existing tests to fail regardless of if they are related.  &lt;br /&gt;
&lt;br /&gt;
 class CustomerDataAccess {&lt;br /&gt;
   public List findCustomers(CustomerCriteria criteria) {&lt;br /&gt;
     // Logic to query database based on criteria&lt;br /&gt;
     return customersFound;&lt;br /&gt;
   }&lt;br /&gt;
 &lt;br /&gt;
 class CustomerDataAccessTest extends TestSuite {&lt;br /&gt;
   public void testFindCustomers {&lt;br /&gt;
     CustomerDataAccess customerDataAccess = new CustomerDataAccess();&lt;br /&gt;
     CustomerCriteria criteria = new CustomerCriteria();&lt;br /&gt;
     String firstNameToFind = &amp;quot;Bob&amp;quot;;&lt;br /&gt;
     criteria.firstNameEquals(firstNameToFind);&lt;br /&gt;
     List results = customerDataAcess.findCustomers(criteria);&lt;br /&gt;
     assertEquals(2, results.size());&lt;br /&gt;
   }&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
The following example code has a problem in that the test expects there to be only two customers with a first name of 'Bob', which must have been the case when the test was first written and executed. However, a developer could add another customer named 'Bob' at any point in time while unaware of the existing code.  This could suddenly cause this test to fail.  The general fix for situations such as this it to minimize the number of assumptions you make about the test data. This reduces the level of coupling between the test and the data, which makes either easier to change independently of the other.&lt;br /&gt;
&lt;br /&gt;
To improve this particular example, we simply need to change the test to check that each result matches the criteria we specified.&lt;br /&gt;
&lt;br /&gt;
 class CustomerDataAccessTest extends TestSuite {&lt;br /&gt;
   public void testFindCustomers {&lt;br /&gt;
     CustomerDataAccess customerDataAccess = new CustomerDataAccess();&lt;br /&gt;
     CustomerCriteria criteria = new CustomerCriteria();&lt;br /&gt;
     String firstNameToFind = &amp;quot;Bob&amp;quot;;&lt;br /&gt;
     criteria.firstNameEquals(firstNameToFind);&lt;br /&gt;
     List results = customerDataAcess.findCustomers(criteria);&lt;br /&gt;
     for (Customer customer : results) {&lt;br /&gt;
       assertEquals(firstNameToFind, customer.getFirstName());&lt;br /&gt;
     }&lt;br /&gt;
   }&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
=== Code Coverage ===&lt;br /&gt;
This is an analysis method that determines which parts of the software have been executed (covered) by the test case suite.  It also determines which parts have not been executed and may require additional attention. &lt;br /&gt;
&lt;br /&gt;
http://en.wikipedia.org/wiki/Code_coverage&lt;br /&gt;
&lt;br /&gt;
=== Some Additional Best Practices ===&lt;br /&gt;
*Keep each test independent of others.  &lt;br /&gt;
**Do not make unnecessary assumptions.&lt;br /&gt;
***It is counterproductive to assert anything that is already asserted by another test.  &lt;br /&gt;
***Avoids increasing the frequency of failures related to the same root cause.  &lt;br /&gt;
***Only apply asserts that apply to the functionality being tested.  &lt;br /&gt;
***Follow a rule of one assertion per test.  &lt;br /&gt;
**Test one set of code at a time.  &lt;br /&gt;
**Avoid unnecessary preconditions.  &lt;br /&gt;
***Only run preliminary code that is related to the test to be run.  &lt;br /&gt;
***Use common preliminary code only when the associated tests actually require it.  &lt;br /&gt;
*Keep configuration settings separate from the unit tests.  &lt;br /&gt;
*Use clear and consistent naming for all unit tests.&lt;br /&gt;
&lt;br /&gt;
[http://blog.stevensanderson.com/2009/08/24/writing-great-unit-tests-best-and-worst-practises/ (17)]&lt;br /&gt;
&lt;br /&gt;
=== Effective Use of Assertions ===&lt;br /&gt;
*Make one logical assertion per test.  &lt;br /&gt;
*Each assert should be made in relation to the functionality being tested.  &lt;br /&gt;
*Avoid making any assertions that are already covered by another existing assertion.&lt;br /&gt;
&lt;br /&gt;
=== Writing Effective Unit Tests ===&lt;br /&gt;
*Scope is crucial. &lt;br /&gt;
**Narrow scope may result in trivial test results that provide no real value.  &lt;br /&gt;
**Broad scope may test too much that it becomes difficult to determine root cause of failures.  &lt;br /&gt;
*Group tests according to a major feature/functionality.&lt;br /&gt;
**Include enough tests to cover that specific feature/functionality.  &lt;br /&gt;
*Define unit tests at the method level.&lt;br /&gt;
**Some methods will involve groups of objects.  In this case, testing should isolate the groups of objects for testing.  &lt;br /&gt;
***Identifies segments of related code.  &lt;br /&gt;
*Read the code and check if it catches an error or throws an error.  &lt;br /&gt;
**Easy identification of a method with potential to break.  &lt;br /&gt;
**Unit tests should cover error scenarios.&lt;br /&gt;
*Total unit tests should cover the functional requirements of the code at a minimum.&lt;br /&gt;
&lt;br /&gt;
[http://users.csc.calpoly.edu/~cstaley/General/TestingHowTo.htm (8)][http://ubiquity.acm.org/article.cfm?id=358976 (18)]&lt;br /&gt;
&lt;br /&gt;
=== Brief Description of Some Available Unit Testing Tools ===&lt;br /&gt;
[http://www.tejasconsulting.com/open-testware/feature/unit-test-tool-survey.html (6)][http://www.aptest.com/resources.html (9)]&lt;br /&gt;
*GrandTestAuto [http://grandtestauto.org/ (19)]&lt;br /&gt;
**Enables completely automated testing of Java software. &lt;br /&gt;
**More advanced than JUnit.  &lt;br /&gt;
**Simple to use.  &lt;br /&gt;
**Supports distribution of tests across a network. &lt;br /&gt;
**Integrates with additional tools.  &lt;br /&gt;
*JUnit [http://www.softwaresummit.com/2004/speakers/SteltingTestingJ2EE.pdf (7)][http://www.javapractices.com/topic/TopicAction.do?Id=33 (20)]&lt;br /&gt;
**Enables automated testing of Java software. &lt;br /&gt;
**Simple to use.  &lt;br /&gt;
**Makes it easy to identify test failures.  &lt;br /&gt;
**Open source tool.  &lt;br /&gt;
*NUnit [http://nunit.org/ (21)]&lt;br /&gt;
**Provides a unit testing framework for .NET software.  &lt;br /&gt;
**Takes advantage of existing .NET language features.&lt;br /&gt;
&lt;br /&gt;
== Functional Test ==&lt;br /&gt;
The purpose of functional test is to measure the behavioral quality of a software application. Functional tests verify that the system responds appropriately from the user perspective and functions according to the design requirements used to specify the application. The functional test must determine if each component of a software application performs in accordance to the specifications, responds correctly to all conditions that may be presented by incoming events, processes incoming events correctly from one business event to the other, and produces an appropriate outcome from incoming events.&lt;br /&gt;
&lt;br /&gt;
=== Advantages ===&lt;br /&gt;
Functional has several benefits in order to develop a robust software application. Here are the advantages:&lt;br /&gt;
* It verifies that an application works as per specifications across multiple platforms, browsers and technologies.&lt;br /&gt;
* Make sure that a certain feature is completed from a user's point of view.&lt;br /&gt;
* A tester needs no knowledge of implementation, including specific programming languages in order to execute the test.&lt;br /&gt;
* Tester and programmer are independent from each other &lt;br /&gt;
* It will help to expose any ambiguities or inconsistencies in the specification&lt;br /&gt;
* Test cases can be designed as soon as the specification is completed.&lt;br /&gt;
&lt;br /&gt;
=== Best Practices ===&lt;br /&gt;
Functional tests are the measurement for an application's code completion. It makes sure that all the feature and functionalities are working as expected from an end user perspective. Therefore, it is important to design functional tests that will expose any vulnerabilities and assure confidence in an application. Before writing a test, it is very important to understand how the software is supposed to behave. Functional specification documents will have all the details about the behavior of the application. The first thing to do before writing any test cases is to write the functional specification document. Once the specification is read, it is important to organize tests to make sure that they cover each and every feature and functionality of the application. This will make sure that all the components are thoroughly tested and enable identify any gaps in testing. Test cases should be written prior to developing functionality. This will lead to identification of preconditions and establish expected behavior.  Additionally, this will help to automate the functional tests and enables another person to run the test regardless of their knowledge of the expected behavior. The test cases should also cover very rare situations. Software developers tend to develop applications strictly according to its specification. They may not appropriately code the program to work for rare cases. A majority of the bugs are found when applications are used in rare input conditions.  Therefore, it is important to make sure that functional tests are created to test boundary conditions, error cases, and rare input cases.&lt;br /&gt;
&lt;br /&gt;
=== Ensuring Effectiveness and Efficiency Through the Functional Testing Lifecycle ===&lt;br /&gt;
*Requirements Gathering&lt;br /&gt;
**Define clear and complete requirements that can be tested.  &lt;br /&gt;
*Test Planning&lt;br /&gt;
**Establish guidelines and standards for creating tests.  &lt;br /&gt;
**Identify the required hardware and software for the testing environment.  &lt;br /&gt;
*Test Strategizing&lt;br /&gt;
**Utilize resources to achieve optimum test coverage. &lt;br /&gt;
*Test Execution&lt;br /&gt;
**Define an efficient test execution flow.  &lt;br /&gt;
*Collect Testing Metrics&lt;br /&gt;
**Gauge the test progress and quality of the testing. &lt;br /&gt;
**Make continuous improvements as needed.&lt;br /&gt;
&lt;br /&gt;
[http://www.infosys.com/engineering-services/white-papers/Documents/functional-testing.pdf (22)]&lt;br /&gt;
&lt;br /&gt;
=== Writing functional tests ===&lt;br /&gt;
An application may have several features and each of those features have several functionalities of their own. With a vast number of overall functionalities, there is a possibility that a functionality may be overlooked.  Therefore, it is a good practice to organize test cases by their features and functionalities. This can help ensure that no feature or functionality is missed. &lt;br /&gt;
&lt;br /&gt;
The following is a sample organization structure of functional test cases:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;Feature 1&amp;gt;&lt;br /&gt;
   &amp;lt;Function 1&amp;gt;&lt;br /&gt;
     &amp;lt;Test 1&amp;gt;&lt;br /&gt;
     &amp;lt;Test 1/&amp;gt;&lt;br /&gt;
     &amp;lt;Test 2&amp;gt;&lt;br /&gt;
     &amp;lt;Test 2/&amp;gt;&lt;br /&gt;
     …&lt;br /&gt;
   &amp;lt;Function 1/&amp;gt;&lt;br /&gt;
 &amp;lt;Feature 1/&amp;gt;&lt;br /&gt;
 &amp;lt;Feature 2&amp;gt;&lt;br /&gt;
   &amp;lt;Function 1&amp;gt;&lt;br /&gt;
     &amp;lt;Test 1&amp;gt;&lt;br /&gt;
     &amp;lt;Test 1/&amp;gt;&lt;br /&gt;
     …&lt;br /&gt;
   &amp;lt;Function 1/&amp;gt;&lt;br /&gt;
   …&lt;br /&gt;
 &amp;lt;Feature 2/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Test cases can be executed by anybody if they are written in a meaningful way for anyone to understand. In order to create a meaningful test case, a test case should have specific components. First, it should have a purpose statement on what it is intended to test. Second, the test case should have a setup component that is run prior to executing the test. Third, it should have steps to execute the test. Fourth, it should have expected behavior to compare against for the determination of if the test passed or failed.  Finally, it should have a cleanup procedure to make sure that the system is reverting back to the original state. &lt;br /&gt;
&lt;br /&gt;
Here is a sample of a test case:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;Test 1&amp;gt;&lt;br /&gt;
   &amp;lt;Purpose&amp;gt;&lt;br /&gt;
     “Purpose of the test case”&lt;br /&gt;
   &amp;lt;Purpose/&amp;gt;&lt;br /&gt;
   &amp;lt;Setup&amp;gt;&lt;br /&gt;
     “Steps to prepare the system prior to executing the test case”&lt;br /&gt;
   &amp;lt;Setup/&amp;gt;&lt;br /&gt;
   &amp;lt;Execution&amp;gt;&lt;br /&gt;
     “Steps required executing the test”&lt;br /&gt;
   &amp;lt;Execution/&amp;gt;&lt;br /&gt;
   &amp;lt;Expected Behavior&amp;gt;&lt;br /&gt;
     “Expected behavior of the test case”&lt;br /&gt;
   &amp;lt;Expected Behavior/&amp;gt;&lt;br /&gt;
   &amp;lt;Cleanup&amp;gt;&lt;br /&gt;
     “Steps required to cleaning up the environment to revert back”&lt;br /&gt;
   &amp;lt;Cleanup/&amp;gt;&lt;br /&gt;
 &amp;lt;Test 1/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Writing functional test cases for 100% coverage can be a seemingly impossible task that would require a tester to continue writing functional test forever. Even when there are several functionalities requiring testing, there can be situations in which the functional testing of major functionalities and features must be completed in a short amount of time.  This type of situation can be handled by assigning priorities to each functional test.  Higher priority tests should cover key features.  Lower priority tests should cover less important features.&lt;br /&gt;
&lt;br /&gt;
=== Functionality test tools ===&lt;br /&gt;
Functional tests can become very large in size and that can make them difficult to maintain and time-consuming to execute manually. Therefore, it is a good practice to automate the test cases. Automating tests can reduce the amount of time between notifications of problem introductions and having such problems addressed.  [http://dmcnulla.wordpress.com/2012/01/28/good-practices-for-automating-functional-tests/ (1)] There are several tools available that automate functional testing. Here are some lists of some of the tools available:&lt;br /&gt;
&lt;br /&gt;
==== Quick Test Professional ====&lt;br /&gt;
The Quick Test Professional tool enables the automation of functional tests through an user interface. It detects objects in the user interface and performs desired operations simulating a mouse click or keyboard events. The tool can also be used to automate functional tests on graphical and non-graphical user interfaces. It allows collaboration through the storage of similar object definitions in a single repository manager, which can be shared among other testers. The same repository can maintain automated and manual test cases.&lt;br /&gt;
&lt;br /&gt;
==== JFunc ====&lt;br /&gt;
JFunc is an open-source functional testing tool that helps to automate functional test cases.  JFunc is an extension of the JUnit test framework. It serves to ease the creation of manual functional test suites. JFunc can handle multiple test failures by allowing the functional test to not exit after the first failure.  Verbose assertions have more detail about the test failures and error messages.  New arguments can be passed into a test each time it runs.&lt;br /&gt;
&lt;br /&gt;
==== Waitir ====&lt;br /&gt;
Waitir is a web application testing tool for the Ruby language. Waitir tests the web application on all web browsers on different platforms. It distinguishes from other web application functional testing tools by executing tests at the web browser layer and by driving a web browser and the interacting with objects on a web page.  This is more accurate than manual functional testing. Here is a sample test case that validates the search operation:&lt;br /&gt;
&lt;br /&gt;
 #------------------------------------------------------------------------------------------------------------------#&lt;br /&gt;
 # Purpose: To Validate the search capability of the browser.&lt;br /&gt;
 #------------------------------------------------------------------------------------------------------------------#&lt;br /&gt;
 #------------------------------------------------------------------------------------------------------------------#&lt;br /&gt;
 # Setup:&lt;br /&gt;
 #------------------------------------------------------------------------------------------------------------------#&lt;br /&gt;
   require &amp;quot;watir&amp;quot;&lt;br /&gt;
   test_site = &amp;quot;http://www.google.com&amp;quot;&lt;br /&gt;
   browser = Watir::Browser.new&lt;br /&gt;
   browser.goto test_site&lt;br /&gt;
   browser.text_field(:name, &amp;quot;q&amp;quot;).set &amp;quot;pickaxe&amp;quot;&lt;br /&gt;
 #------------------------------------------------------------------------------------------------------------------#&lt;br /&gt;
 # Execution:&lt;br /&gt;
 #------------------------------------------------------------------------------------------------------------------#&lt;br /&gt;
   browser.button(:name, &amp;quot;btnG&amp;quot;).click # &amp;quot;btnG&amp;quot; is the name of the Search button&lt;br /&gt;
 #-------------------------------------------------------------#&lt;br /&gt;
 # Expected Behavior: “A Google page with results should be shown. 'Programming Ruby' should be high on the list.&amp;quot;&lt;br /&gt;
 #------------------------------------------------------------------------------------------------------------------#&lt;br /&gt;
   if browser.text.include? &amp;quot;Programming Ruby&amp;quot;  &lt;br /&gt;
     puts &amp;quot;  Test Passed. Found the test string: 'Programming Ruby'. Actual Results match Expected Results.&amp;quot;&lt;br /&gt;
   else&lt;br /&gt;
     puts &amp;quot;  Test Failed! Could not find: 'Programming Ruby'.&amp;quot; &lt;br /&gt;
   End&lt;br /&gt;
 #------------------------------------------------------------------------------------------------------------------#&lt;br /&gt;
 #Cleanup: &lt;br /&gt;
 #------------------------------------------------------------------------------------------------------------------#&lt;br /&gt;
   browser.close&lt;br /&gt;
&lt;br /&gt;
=== Additional Functional Testing Tools ===&lt;br /&gt;
*Arbiter [http://arbiter.sourceforge.net/ (24)]&lt;br /&gt;
**Document-based acceptance testing. &lt;br /&gt;
**Driven by requirements documents in Microsoft Word or RTF file formats.  &lt;br /&gt;
**Requirements are used to establish a glossary and test suite.  &lt;br /&gt;
*Blerby Test Runner [https://github.com/tmpvar/Blerby-Test-Runner (25)]&lt;br /&gt;
**Ajax test runner for php software. &lt;br /&gt;
**Allows for instant feedback while performing on-the-fly code refactoring.  &lt;br /&gt;
**Tracks test dependencies.&lt;br /&gt;
**Automatically re-runs affected tests when corresponding code changes.&lt;br /&gt;
*Concordion [http://www.concordion.org/ (26)]&lt;br /&gt;
**Open source framework for testing Java software. &lt;br /&gt;
**Allows for plain English descriptions of requirements to be converted into automated tests.  &lt;br /&gt;
**Specifications are linked to the software system itself and prevents tests from becoming outdated. &lt;br /&gt;
**Notifications inform when a change in system behavior causes associated test to fail.  &lt;br /&gt;
*Eclipse Jubula [http://www.eclipse.org/jubula/ (27)]&lt;br /&gt;
**Provides automated UI functional testing for HTML and Java applications.  &lt;br /&gt;
**Aimed at creating tests from the user perspective.  &lt;br /&gt;
**Limited coding efforts required.&lt;br /&gt;
*Robotium [http://code.google.com/p/robotium/ (28)]&lt;br /&gt;
**Test framework to write black-box and white-box tests for Android applications. &lt;br /&gt;
**Requires test case suite to be installed on the same device or simulator as the application.  &lt;br /&gt;
**Access the application to execute tests scenarios in a real environment.&lt;br /&gt;
&lt;br /&gt;
[http://www.opensourcetesting.org/functional.php (23)]&lt;br /&gt;
&lt;br /&gt;
== Integration Test == &lt;br /&gt;
The purpose of integration testing is to test the combination of individual components working together.  This type of testing can expose faults that result from the interaction between the integrated components.  [http://softwaretestingfundamentals.com/integration-testing/ (13)]&lt;br /&gt;
&lt;br /&gt;
=== Various Approaches to Integration Testing ===&lt;br /&gt;
*Big Bang - All or most of the individual components are combined and tested at one time.  This approach is typically utilized when a test team receives an entire software bundle. &lt;br /&gt;
*Top Down - Top level components are tested initially.  Lower level components are tested subsequently in a step by step method.  This approach is used whenever development is taking the same type of approach.  In this approach, test stubs are needed to simulate lower level components that are not yet available.  &lt;br /&gt;
*Bottom Up - Bottom level components are tested initially.  This approach is used whenever development is taking the same type of approach.  In this approach, test stubs are needed to simulate higher level components that are not yet available.  &lt;br /&gt;
*Sandwich/Hybrid - This approach is a combination of the Top Down and Bottom up approaches.&lt;br /&gt;
&lt;br /&gt;
=== Advantages to Each Approach ===&lt;br /&gt;
*Big Bang&lt;br /&gt;
**Convenient for smaller systems. &lt;br /&gt;
**Quick.&lt;br /&gt;
**Cheap.&lt;br /&gt;
**No stubs or stand-in objects are needed.&lt;br /&gt;
*Top Down&lt;br /&gt;
**Potential for early identification of major flaws near the top of the product.  &lt;br /&gt;
**Critical components are tested on priority.  &lt;br /&gt;
**Easier to isolate root cause of interface errors due to the incremental approach.&lt;br /&gt;
*Bottom Up&lt;br /&gt;
**Potential for early identification of major flaws near the bottom of the product. &lt;br /&gt;
**Easier to create test conditions. &lt;br /&gt;
**No need to wait for all modules to be developed.  &lt;br /&gt;
**Each component and unit gets tested for correctness before being integrated.  &lt;br /&gt;
**Typically results in a more robust system.  &lt;br /&gt;
*Sandwich/Hybrid&lt;br /&gt;
**Useful for larger projects with several subprojects.&lt;br /&gt;
&lt;br /&gt;
[http://www.itdivisioninc.com/IntegrationTesting.aspx (15)]&lt;br /&gt;
&lt;br /&gt;
=== Best Practices ===&lt;br /&gt;
*Create only the integration tests needed.  These tests offer great value at the cost of a great amount of work to properly set up and time to execute.  Consider only testing the default scenarios.  There should be enough testing to validate that critical or high-severity defects no longer exist.  &lt;br /&gt;
*Do not depend on specific data to be available to the test.  Always have any necessary data created prior to the execution of a test.  Anyone with proper access could delete or modify test data and break a test, which is another reason it should not be assumed to be available.  &lt;br /&gt;
*Use multiple asserts for each test.  Due to the time consumption of integration tests, it is recommended that tests be consolidated.  In this type of testing, it is considered better to ignore following a one assert per test rule.  &lt;br /&gt;
*When seeking to validate the same functionality and there is an option between creating a unit test or an integration test, always choose the unit test.  Unit tests will run faster and be easier to set up.&lt;br /&gt;
&lt;br /&gt;
[http://msdn.microsoft.com/en-us/library/vstudio/hh323698(v=vs.100).aspx#erg (14)]&lt;br /&gt;
&lt;br /&gt;
=== Available Integration Testing Tools ===&lt;br /&gt;
*eggPlant [http://www.testplant.com/products/eggplant/ (30)]&lt;br /&gt;
**Focused on testing the user experience.  [http://www.testplant.com/blog/2011/06/09/integration-testing/ (29)]&lt;br /&gt;
**Black-box test automation tool. &lt;br /&gt;
**Low overhead.&lt;br /&gt;
**Non-invasive.  Not required to run on the same system under test.  &lt;br /&gt;
**Image capture and search techniques prevent most UI changes from affecting existing tests.&lt;br /&gt;
*Ruby Capybara [https://www.ruby-toolbox.com/projects/capybara (31)]&lt;br /&gt;
**Designed for Ruby on Rails applications. &lt;br /&gt;
**Tests rack-based web applications.  &lt;br /&gt;
**Simulates how a user interacts with a website.  &lt;br /&gt;
*Selenium  [http://seleniumhq.org/ (33)]&lt;br /&gt;
**Provides automated integration testing for Java web applications.  [http://www.developer.com/java/web/article.php/3872691/Selenium-Automated-Integration-Testing-for-Java-Web-Apps.htm (32)]&lt;br /&gt;
**Provides automation-aided exploratory testing.  &lt;br /&gt;
**Distributes testing across many environments.  &lt;br /&gt;
**Supports testing on many types of web browsers.&lt;br /&gt;
&lt;br /&gt;
== Performance Test ==&lt;br /&gt;
The purpose of performance testing is to determine speed and effectiveness.  Various quantitative and qualitative attributes may be used.  Examples of quantitative attributes include response time and number of MIPS (millions of instructions per second).  Examples of qualitative attributes include scalability, interoperability, and reliability.  [http://performance-testing.org/performance-testing-definitions (10)]&lt;br /&gt;
&lt;br /&gt;
Performance testing can be used to determine the speed of a specific aspect of a system with a specific workload.  This allows for the identification of poor performance areas and for the establishment of acceptable thresholds required to maintain acceptable response time.  &lt;br /&gt;
&lt;br /&gt;
There are several types of performance testing.  Understanding the various types helps to minimize cost, reduce risk, and to know when it is appropriate to apply which type of test on a project.  &lt;br /&gt;
&lt;br /&gt;
=== Key Types of Performance Testing &amp;amp; Their Advantages === &lt;br /&gt;
*Performance test - Determines speed, stability, and/or scalability.&lt;br /&gt;
**Focuses on determining user satisfaction with regards to performance. &lt;br /&gt;
**Identifies differences between the expectations and reality of existing performance. &lt;br /&gt;
**Supports optimization and capacity planning. &lt;br /&gt;
*Load test - Verifies application behavior under both normal and peak load conditions. &lt;br /&gt;
**The hardware environment is evaluated for adequacy.  &lt;br /&gt;
**Detects concurrency issues.  &lt;br /&gt;
**Detects functional errors that occur under load.  &lt;br /&gt;
**Supports determination of maximum simultaneous users prior to performance being compromised. &lt;br /&gt;
**Supports determination of maximum load before limits of resource utilization are exceeded. &lt;br /&gt;
*Stress test - Determines behavior when conditions exceed normal or peak load conditions.&lt;br /&gt;
**Identifies if over-stressing the system can corrupt data. &lt;br /&gt;
**Supports establishment of application-monitoring triggers that can warn of impending failures.  &lt;br /&gt;
**Determines side effects of failures related to hardware or applications. &lt;br /&gt;
**Identifies the kinds of failures to plan for.   &lt;br /&gt;
*Capacity test - Determines the amount of users and/or transactions that can be supported while continuing to meet performance goals.  &lt;br /&gt;
**Provides capacity data that can be used to validate or enhance models.  &lt;br /&gt;
**Determines current usage and capacity of the system. &lt;br /&gt;
**Provides data on capacity and usage trends of the system.&lt;br /&gt;
&lt;br /&gt;
[http://msdn.microsoft.com/en-us/library/bb924357.aspx (11)]&lt;br /&gt;
&lt;br /&gt;
=== Best Practices ===&lt;br /&gt;
*Test the code with the same granularity as used for unit tests. &lt;br /&gt;
*Do not perform lots of assertions on the test results. &lt;br /&gt;
*Test enough to measure statistically significant performance differences. &lt;br /&gt;
*Ideal performance tests should run relatively fast. &lt;br /&gt;
*Test setup should be performed independent of the actual test method.&lt;br /&gt;
&lt;br /&gt;
[http://www.mantidproject.org/Writing_Performance_Tests#Best_Practice_Advice (12)]&lt;br /&gt;
&lt;br /&gt;
=== Available Performance Testing Tools ===&lt;br /&gt;
*AgileLoad&lt;br /&gt;
**Provides load testing for mobile and web applications. &lt;br /&gt;
**Designed to fit into the Agile Development methodology.  &lt;br /&gt;
**Windows-based.  &lt;br /&gt;
**Tests applications designed for use on cloud or internal networks. &lt;br /&gt;
*Forecast&lt;br /&gt;
**Tests IT systems for performance, reliability, and scalability.&lt;br /&gt;
**Realistically simulates multiple thousands of unique users simultaneously accessing functionalities.  &lt;br /&gt;
**Avoids the overhead and expense associated with hardware costs. &lt;br /&gt;
*HP LoadRunner&lt;br /&gt;
**Detects bottlenecks.  &lt;br /&gt;
**Emulates production workloads.  &lt;br /&gt;
**Diagnoses root cause of performance issues.  &lt;br /&gt;
**Improves performance prior to application deployment.  &lt;br /&gt;
*IBM Rational Performance Tester&lt;br /&gt;
**Identifies both the presence and cause of performance bottlenecks.  &lt;br /&gt;
**Provides problem identification and problem diagnosis.  &lt;br /&gt;
**Root Cause Analysis features allows for identifying source code causing performance issues.  &lt;br /&gt;
**Real-time reports are viewable via web browser.   &lt;br /&gt;
*RTI&lt;br /&gt;
**Measures application performance based on response times for transactions with poor performance.  &lt;br /&gt;
**Dynamically collects performance data and diagnoses problems throughout system aspects.  &lt;br /&gt;
**Quantifies and validates application architectures.  &lt;br /&gt;
*SilkPerformer&lt;br /&gt;
**Provides performance and load testing for software applications. &lt;br /&gt;
**Automates software load and stress.  &lt;br /&gt;
**Enables identification of bottlenecks.   &lt;br /&gt;
**Diagnostic tools may be applied to resolve performance issues.&lt;br /&gt;
&lt;br /&gt;
[http://www.toolsjournal.com/tools-world/item/156-top-performance-testing-tools (34)]&lt;br /&gt;
&lt;br /&gt;
== References == &lt;br /&gt;
[1] http://codebetter.com/blogs/jeremy.miller/archive/2005/07/20/129552.aspx&lt;br /&gt;
&lt;br /&gt;
[2] http://www.javaworld.com/javaworld/jw-03-2009/jw-03-good-unit-tests-1.html&lt;br /&gt;
&lt;br /&gt;
[3] http://en.wikipedia.org/wiki/Unit_testing&lt;br /&gt;
&lt;br /&gt;
[4] http://wiki.developerforce.com/index.php/How_to_Write_Good_Unit_Tests&lt;br /&gt;
&lt;br /&gt;
[5] http://msdn.microsoft.com/en-us/magazine/cc163665.aspx&lt;br /&gt;
&lt;br /&gt;
[6] http://www.tejasconsulting.com/open-testware/feature/unit-test-tool-survey.html&lt;br /&gt;
&lt;br /&gt;
[7] http://www.softwaresummit.com/2004/speakers/SteltingTestingJ2EE.pdf&lt;br /&gt;
&lt;br /&gt;
[8] http://users.csc.calpoly.edu/~cstaley/General/TestingHowTo.htm&lt;br /&gt;
&lt;br /&gt;
[9] http://www.aptest.com/resources.html&lt;br /&gt;
&lt;br /&gt;
[10] http://performance-testing.org/performance-testing-definitions&lt;br /&gt;
&lt;br /&gt;
[11] http://msdn.microsoft.com/en-us/library/bb924357.aspx&lt;br /&gt;
&lt;br /&gt;
[12] http://www.mantidproject.org/Writing_Performance_Tests#Best_Practice_Advice&lt;br /&gt;
&lt;br /&gt;
[13] http://softwaretestingfundamentals.com/integration-testing/&lt;br /&gt;
&lt;br /&gt;
[14] http://msdn.microsoft.com/en-us/library/vstudio/hh323698(v=vs.100).aspx#erg&lt;br /&gt;
&lt;br /&gt;
[15] http://www.itdivisioninc.com/IntegrationTesting.aspx&lt;br /&gt;
&lt;br /&gt;
[16] http://wiki.expertiza.ncsu.edu/index.php/CSC/ECE_517_Fall_2010/ch1_2e_RI&lt;br /&gt;
&lt;br /&gt;
[17] http://blog.stevensanderson.com/2009/08/24/writing-great-unit-tests-best-and-worst-practises/&lt;br /&gt;
&lt;br /&gt;
[18] http://ubiquity.acm.org/article.cfm?id=358976&lt;br /&gt;
&lt;br /&gt;
[19] http://grandtestauto.org/&lt;br /&gt;
&lt;br /&gt;
[20] http://www.javapractices.com/topic/TopicAction.do?Id=33&lt;br /&gt;
&lt;br /&gt;
[21] http://nunit.org/&lt;br /&gt;
&lt;br /&gt;
[22] http://www.infosys.com/engineering-services/white-papers/Documents/functional-testing.pdf&lt;br /&gt;
&lt;br /&gt;
[23] http://www.opensourcetesting.org/functional.php&lt;br /&gt;
&lt;br /&gt;
[24] http://arbiter.sourceforge.net/&lt;br /&gt;
&lt;br /&gt;
[25] https://github.com/tmpvar/Blerby-Test-Runner&lt;br /&gt;
&lt;br /&gt;
[26] http://www.concordion.org/&lt;br /&gt;
&lt;br /&gt;
[27] http://www.eclipse.org/jubula/&lt;br /&gt;
&lt;br /&gt;
[28] http://code.google.com/p/robotium/&lt;br /&gt;
&lt;br /&gt;
[29] http://www.testplant.com/blog/2011/06/09/integration-testing/&lt;br /&gt;
&lt;br /&gt;
[30] http://www.testplant.com/products/eggplant/&lt;br /&gt;
&lt;br /&gt;
[31] https://www.ruby-toolbox.com/projects/capybara&lt;br /&gt;
&lt;br /&gt;
[32] http://www.developer.com/java/web/article.php/3872691/Selenium-Automated-Integration-Testing-for-Java-Web-Apps.htm&lt;br /&gt;
&lt;br /&gt;
[33] http://seleniumhq.org/&lt;br /&gt;
&lt;br /&gt;
[34] http://www.toolsjournal.com/tools-world/item/156-top-performance-testing-tools&lt;/div&gt;</summary>
		<author><name>Kbyarbor</name></author>
	</entry>
</feed>