<?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=Nthanik</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=Nthanik"/>
	<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=Special:Contributions/Nthanik"/>
	<updated>2026-07-03T06:48:18Z</updated>
	<subtitle>User contributions</subtitle>
	<generator>MediaWiki 1.41.0</generator>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2016_E1682:_Improve_score_calculation&amp;diff=106530</id>
		<title>CSC/ECE 517 Fall 2016 E1682: Improve score calculation</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2016_E1682:_Improve_score_calculation&amp;diff=106530"/>
		<updated>2016-12-05T04:31:45Z</updated>

		<summary type="html">&lt;p&gt;Nthanik: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;E1682. Improve score calculation&lt;br /&gt;
&lt;br /&gt;
== Introduction ==&lt;br /&gt;
&lt;br /&gt;
=== Expertiza ===&lt;br /&gt;
Expertiza is an open source project for school assignment management for instructors and students based on the Ruby on Rails framework. Expertiza allows the instructor to create new assignments and customize new or existing assignments. It also allows the instructor to create a list of topics the students can sign up for. Students can form teams in Expertiza to work on various projects and assignments. Students can also peer review other students' submissions. Expertiza supports submission across various document types, including the URLs and word documents. Expertiza provides a dashboard for all the assignments corresponding to a course and provides absolute control to the Instructors and Teaching Assistants. In addition to assignments, it encompasses peer reviews wherein participants are allowed to provide feedback anonymously about each other's work thereby providing scope for the better outcome. The due_date.rb file is responsible for informing the users about the deadline for submission of the each assignment. Due dates in Expertiza have their association with many other components like assignments, reviews etc.&lt;br /&gt;
&lt;br /&gt;
=== Purpose ===&lt;br /&gt;
The purpose of the project is to improve the functionality of score calculation. The scores in expertiza were calculated by taking the sum of weighted scores to calculate the total every time it is called. This takes considerable amount of time as there is a calculation involved each time. The methodology behind score calculation in expertiza can be significantly improved. The design behind calculating and storing scores can be tweaked to offer significant performance improvements. To achieve this, it is ideal to store overall holistic stores in addition to individual criterion scores.&lt;br /&gt;
&lt;br /&gt;
=== Problem Statement ===&lt;br /&gt;
The current drawback of the expertiza system lies in how the scores are stored: Expertiza stores the scores based on each response to each criterion, but no holistic scores are stored. As a result of this mechanism, the process slows down. This means that if we need to know what score user A gives to user B based on 100, we have to rely on the code to calculate it (since in answers table we only have the score that A gives B on each criterion).&lt;br /&gt;
&lt;br /&gt;
To overcome this bottleneck, two additional mechanisms can be included for handling the holistic scores.&lt;br /&gt;
&lt;br /&gt;
== Overall Description ==&lt;br /&gt;
Expertiza currently calculates scores dynamically when a page is called by taking the weighted scores of each question into consideration. This calculation is a time consuming process with a considerable overhead that significantly affects the performance. To solve the issue we propose a solution to store the holistic scores in a database, retrieving it every time it is required. This reduces the calculation that is required every time the score is called. When the user wants to check the scores of a completed assignment, a method localDB_calc is called and expertiza retrieves the scores of the student from the database rather than calculating the total from weighted scores. But, when the scores of an ongoing assignment is required, a method on_the_fly_calc is called that calculates the current score of the user. To determine which method will be invoked(on_the_fly_calc and localDB_calc), the current system time will be compared with last_review_deadline   &lt;br /&gt;
* If system time is greater than last_review_deadline, indicating that the deadline has passed, the method localDbcal will retrieve the holistic score from the database   &lt;br /&gt;
* If system time is lesser than last_review_deadline, indicating that the deadline has not passed, the method on_the_fly_cal will calculate the holistic score and display it.   &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The Dataflow diagram (DFD) for the proposed system is shown below.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[File:Flowchart12.png|center|frame|flowchart]]&lt;br /&gt;
&lt;br /&gt;
== Tasks Identified ==&lt;br /&gt;
The two suggested mechanisms for handling the storage and calculation of holistic scores for peer-reviews, as specified in the requirements document are :&lt;br /&gt;
* on_the_fly_calc&lt;br /&gt;
* localDB_calc&lt;br /&gt;
&lt;br /&gt;
=== on_the_fly_calc ===&lt;br /&gt;
When the assignment is still ongoing , this method is called and it calculates holistic scores over a set of data (in this case, a set of record in answers table, namely the responses from user A to user B on each criterion) and store it in localdbscores. This stored score is retrieved and printed when the user A clicks on the &amp;quot;Your scores&amp;quot; link.&lt;br /&gt;
&lt;br /&gt;
In the current implementation, when a user A wants to view the score given by user B, user A's score(i.e. out of 100) will be calculated everytime using the scores given by user B for each criterion (i.e.. score out of 5).&lt;br /&gt;
&lt;br /&gt;
Handles the calculation of reputations for each reviewer in the case of an ongoing assignment.&lt;br /&gt;
&lt;br /&gt;
=== localDB_calc ===&lt;br /&gt;
Once the deadline for an assignment is completed, the method localDB_calc calculates the holistic score over a single db query (in this case, a query would be: “get the score that user A gives user B on assignment 999 on round 2”). The query can also ask to print the average of all the scores in round 1 and round2, this average will be retrieved from localdbscores and printed.&lt;br /&gt;
&lt;br /&gt;
This method handles the calculation of reputations for each reviewer in the case of a finished assignment. (all the reputations are calculated and stored since they are finalized).&lt;br /&gt;
&lt;br /&gt;
=== Database ===&lt;br /&gt;
To store the holistic scores when an assignment is completed, a database localdbscores needs to be created. The value from this db is retrieved and displayed when the scores of a completed assignment needs to be viewed. The database Design is shown below.&lt;br /&gt;
&lt;br /&gt;
== Database Design ==&lt;br /&gt;
A table localdbscores will be created as:&lt;br /&gt;
&lt;br /&gt;
class CreateLocalDB&amp;lt;ActiveRecord::Migration&lt;br /&gt;
&lt;br /&gt;
def self.up&lt;br /&gt;
&lt;br /&gt;
create_table :localdb_scores do |t|&lt;br /&gt;
&lt;br /&gt;
t.column :id, :integer&lt;br /&gt;
&lt;br /&gt;
t.column :score, :integer&lt;br /&gt;
&lt;br /&gt;
t.column :round, :integer&lt;br /&gt;
&lt;br /&gt;
t.column :type, :string&lt;br /&gt;
&lt;br /&gt;
t.column :reference_id, :integer&lt;br /&gt;
&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
with id, score, round, type, reference_id as its attributes as shown in the table below&lt;br /&gt;
&lt;br /&gt;
&amp;quot;localdbscores&amp;quot; will have the following scores&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|&lt;br /&gt;
|t.integer    &amp;quot;id&amp;quot;,         limit: 24&lt;br /&gt;
|id&lt;br /&gt;
|Primary Key, Auto generated&lt;br /&gt;
|-&lt;br /&gt;
|&lt;br /&gt;
|t.string    &amp;quot;Type&amp;quot;,      limit: 255&lt;br /&gt;
|Type&lt;br /&gt;
|Type of score: either final or intermediate&lt;br /&gt;
|-&lt;br /&gt;
|&lt;br /&gt;
|t.integer    &amp;quot;Score&amp;quot;,  limit: 24&lt;br /&gt;
|Score&lt;br /&gt;
|Total score calculated based on each response to each criterion&lt;br /&gt;
|-&lt;br /&gt;
|&lt;br /&gt;
|t.integer   &amp;quot;Round&amp;quot;,  limit:24&lt;br /&gt;
|Round&lt;br /&gt;
|The completed round number&lt;br /&gt;
|-&lt;br /&gt;
|&lt;br /&gt;
|t.integer  &amp;quot;Reference_id&amp;quot; , limit:45&lt;br /&gt;
|Reference_id&lt;br /&gt;
|Acts as the foreign Key&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Implementation ==&lt;br /&gt;
&lt;br /&gt;
=== Assignment.rb ===&lt;br /&gt;
A new function get_last_review_date is added which takes assignid as a parameter and returns the last review deadline of the assignment. The deadline obtained from AssignmentDueDate for the corresponding assignid is stored in last_review_deadline and is returned.&lt;br /&gt;
&lt;br /&gt;
=== Parent Class:ScoreCal ===&lt;br /&gt;
ScoreCal stores the score calculated by its sub classes: on_the_fly_cal and LocalDbcal to the database. In the database, a new table localdbscore is created with the schema as explained in section 2.2. Depending upon the deadline_type, object of either on_the_fly_cal or LocalDbcal is created and the appropriate functions within the classes are called.&lt;br /&gt;
&lt;br /&gt;
=== Sub class 1: on_the_fly_cal ===&lt;br /&gt;
This is a subclass of class Scorecal contains a method calc_score whose functionality is to compute the holistic score. An object of on_the_fly_cal is called when the current time has not yet surpassed the time stored in last_review_deadline variable which contains the review duedate indicating that the assignment is still ongoing and has not been completed. The individual scores are retrieved from the database ScoreView and is stored in QuestionnaireData from which the holistic score of a student is calculated .&lt;br /&gt;
&lt;br /&gt;
When the user accesses the scores for a review, the current implementation does not store a holistic score but rather calculates the holistic score from the score for every individual criterion. To calculate the total holistic score for a specific round, the individual scores are weighted and added.&lt;br /&gt;
&lt;br /&gt;
This functionality is achieved by on_the_fly_calc.&lt;br /&gt;
&lt;br /&gt;
A snapshot of the system before implementing the changes is shown below.&lt;br /&gt;
[[File:rsz_flycur.png]]&lt;br /&gt;
&lt;br /&gt;
The proposed implementation involves computing the holistic score once and storing it in the local_db_scores database for a particular user and for a specified round. The stored value is accessed and obtained instead of computing the holistic score every single time.&lt;br /&gt;
&lt;br /&gt;
[[File:rsz_flyadb.png]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Sub class 2: LocalDbcal ===&lt;br /&gt;
This is a subclass of Scorecal and contains a function calc_score in class localDbcal. An object of LocalDbcal is called when the current time has surpassed the time stored in last_review_deadline variable which contains the review due date indicating that the assignment has been completed. This subclass retrieves the score from the database localDbscores for a corresponding student. If the score is not found in the database localDbscores, the function calc_score of on_the_fly_cal class is called to calculate the total from the weighted scores of each question. This calculated score is then inserted into the database.&lt;br /&gt;
&lt;br /&gt;
This score is now returned to the view from where it was called.&lt;br /&gt;
[[File:rsz_loccur.png]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The proposed implementation retrieves the round wise scores from the local_db_scores database and displays the average score once the deadline has passed rather than computing the average of the weighted scores for every access of the page as shown below.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[File:rsz_locadb.png]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== _review_table.html.erb ===&lt;br /&gt;
The current implementation of this was to calculate the score and display it which as we know is a time consuming process. It has been changed to check if the current time has crossed the last_review_deadline obtained in assignments.rb and call the corresponding class as required.&lt;br /&gt;
&lt;br /&gt;
If the current date has surpassed the last_review_deadline, it is an indication that the due date has passed and the class localDbcal is called to retrieve a value from the database as mentioned above. On the other hand, on_the_fly_cal is called when the current date has not surpassed the last_review_deadline, indicating that the assignment is ongoing and the holistic score is calculated and passed to the view.&lt;br /&gt;
&lt;br /&gt;
== Design Pattern ==&lt;br /&gt;
The ScoreCal superclass has 2 subclasses: OnTheFlyCal and LocalDbCal. ScoreCal acts as an interface to obtain the scores, either from OnTheFlyCal or LocalDbCal depending on the last_review_deadline obtained from the get_last_review_date() in the assignment model. This pattern is similar to strategy pattern where the client is the _review_tble.html.erb, interface is the superclass and the subclasses are called accordingly.&lt;br /&gt;
&lt;br /&gt;
[[File:UseCaseDiagram2.png]]&lt;br /&gt;
&lt;br /&gt;
== Testing ==&lt;br /&gt;
The testing for model: on_the_fly_calc is carried out by questionnaire_spec.rb in the spec folder. The minimum and maximum score that an user gives for each criterion is checked.&lt;br /&gt;
&lt;br /&gt;
Two more test cases to check whether the average score of each review falls within a given range:(0,100) will be added.&lt;br /&gt;
&lt;br /&gt;
For LocalDB_calc, the average calculated across round 1 and round 2 will be checked to fall within 0 to 100. These test cases will be added to questionnaire_spec.rb.&lt;/div&gt;</summary>
		<author><name>Nthanik</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2016_E1682:_Improve_score_calculation&amp;diff=106529</id>
		<title>CSC/ECE 517 Fall 2016 E1682: Improve score calculation</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2016_E1682:_Improve_score_calculation&amp;diff=106529"/>
		<updated>2016-12-05T04:27:23Z</updated>

		<summary type="html">&lt;p&gt;Nthanik: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;E1682. Improve score calculation&lt;br /&gt;
&lt;br /&gt;
== Introduction ==&lt;br /&gt;
&lt;br /&gt;
=== Expertiza ===&lt;br /&gt;
Expertiza is an open source project for school assignment management for instructors and students based on the Ruby on Rails framework. Expertiza allows the instructor to create new assignments and customize new or existing assignments. It also allows the instructor to create a list of topics the students can sign up for. Students can form teams in Expertiza to work on various projects and assignments. Students can also peer review other students' submissions. Expertiza supports submission across various document types, including the URLs and word documents. Expertiza provides a dashboard for all the assignments corresponding to a course and provides absolute control to the Instructors and Teaching Assistants. In addition to assignments, it encompasses peer reviews wherein participants are allowed to provide feedback anonymously about each other's work thereby providing scope for the better outcome. The due_date.rb file is responsible for informing the users about the deadline for submission of the each assignment. Due dates in Expertiza have their association with many other components like assignments, reviews etc.&lt;br /&gt;
&lt;br /&gt;
=== Purpose ===&lt;br /&gt;
The purpose of the project is to improve the functionality of score calculation. The scores in expertiza were calculated by taking the sum of weighted scores to calculate the total every time it is called. This takes considerable amount of time as there is a calculation involved each time. The methodology behind score calculation in expertiza can be significantly improved. The design behind calculating and storing scores can be tweaked to offer significant performance improvements. To achieve this, it is ideal to store overall holistic stores in addition to individual criterion scores.&lt;br /&gt;
&lt;br /&gt;
=== Problem Statement ===&lt;br /&gt;
The current drawback of the expertiza system lies in how the scores are stored: Expertiza stores the scores based on each response to each criterion, but no holistic scores are stored. As a result of this mechanism, the process slows down. This means that if we need to know what score user A gives to user B based on 100, we have to rely on the code to calculate it (since in answers table we only have the score that A gives B on each criterion).&lt;br /&gt;
&lt;br /&gt;
To overcome this bottleneck, two additional mechanisms can be included for handling the holistic scores.&lt;br /&gt;
&lt;br /&gt;
== Overall Description ==&lt;br /&gt;
Expertiza currently calculates scores dynamically when a page is called by taking the weighted scores of each question into consideration. This calculation is a time consuming process with a considerable overhead that significantly affects the performance. To solve the issue we propose a solution to store the holistic scores in a database, retrieving it every time it is required. This reduces the calculation that is required every time the score is called. When the user wants to check the scores of a completed assignment, a method localDB_calc is called and expertiza retrieves the scores of the student from the database rather than calculating the total from weighted scores. But, when the scores of an ongoing assignment is required, a method on_the_fly_calc is called that calculates the current score of the user. To determine which method will be invoked(on_the_fly_calc and localDB_calc), the current system time will be compared with last_review_deadline   &lt;br /&gt;
* If system time is greater than last_review_deadline, indicating that the deadline has passed, the method localDbcal will retrieve the holistic score from the database   &lt;br /&gt;
* If system time is lesser than last_review_deadline, indicating that the deadline has not passed, the method on_the_fly_cal will calculate the holistic score and display it.   &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The Dataflow diagram (DFD) for the proposed system is shown below.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[File:Flowchart12.png|center|frame|flowchart]]&lt;br /&gt;
&lt;br /&gt;
== Tasks Identified ==&lt;br /&gt;
The two suggested mechanisms for handling the storage and calculation of holistic scores for peer-reviews, as specified in the requirements document are :&lt;br /&gt;
* on_the_fly_calc&lt;br /&gt;
* localDB_calc&lt;br /&gt;
&lt;br /&gt;
=== on_the_fly_calc ===&lt;br /&gt;
When the assignment is still ongoing , this method is called and it calculates holistic scores over a set of data (in this case, a set of record in answers table, namely the responses from user A to user B on each criterion) and store it in localdbscores. This stored score is retrieved and printed when the user A clicks on the &amp;quot;Your scores&amp;quot; link.&lt;br /&gt;
&lt;br /&gt;
In the current implementation, when a user A wants to view the score given by user B, user A's score(i.e. out of 100) will be calculated everytime using the scores given by user B for each criterion (i.e.. score out of 5).&lt;br /&gt;
&lt;br /&gt;
Handles the calculation of reputations for each reviewer in the case of an ongoing assignment.&lt;br /&gt;
&lt;br /&gt;
=== localDB_calc ===&lt;br /&gt;
Once the deadline for an assignment is completed, the method localDB_calc calculates the holistic score over a single db query (in this case, a query would be: “get the score that user A gives user B on assignment 999 on round 2”). The query can also ask to print the average of all the scores in round 1 and round2, this average will be retrieved from localdbscores and printed.&lt;br /&gt;
&lt;br /&gt;
This method handles the calculation of reputations for each reviewer in the case of a finished assignment. (all the reputations are calculated and stored since they are finalized).&lt;br /&gt;
&lt;br /&gt;
=== Database ===&lt;br /&gt;
To store the holistic scores when an assignment is completed, a database localdbscores needs to be created. The value from this db is retrieved and displayed when the scores of a completed assignment needs to be viewed. The database Design is shown below.&lt;br /&gt;
&lt;br /&gt;
== Database Design ==&lt;br /&gt;
A table localdbscores will be created as:&lt;br /&gt;
&lt;br /&gt;
class CreateLocalDB&amp;lt;ActiveRecord::Migration&lt;br /&gt;
&lt;br /&gt;
def self.up&lt;br /&gt;
&lt;br /&gt;
create_table :localdb_scores do |t|&lt;br /&gt;
&lt;br /&gt;
t.column :id, :integer&lt;br /&gt;
&lt;br /&gt;
t.column :score, :integer&lt;br /&gt;
&lt;br /&gt;
t.column :round, :integer&lt;br /&gt;
&lt;br /&gt;
t.column :type, :string&lt;br /&gt;
&lt;br /&gt;
t.column :reference_id, :integer&lt;br /&gt;
&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
with id, score, round, type, reference_id as its attributes as shown in the table below&lt;br /&gt;
&lt;br /&gt;
&amp;quot;localdbscores&amp;quot; will have the following scores&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|&lt;br /&gt;
|t.integer    &amp;quot;id&amp;quot;,         limit: 24&lt;br /&gt;
|id&lt;br /&gt;
|Primary Key, Auto generated&lt;br /&gt;
|-&lt;br /&gt;
|&lt;br /&gt;
|t.string    &amp;quot;Type&amp;quot;,      limit: 255&lt;br /&gt;
|Type&lt;br /&gt;
|Type of score: either final or intermediate&lt;br /&gt;
|-&lt;br /&gt;
|&lt;br /&gt;
|t.integer    &amp;quot;Score&amp;quot;,  limit: 24&lt;br /&gt;
|Score&lt;br /&gt;
|Total score calculated based on each response to each criterion&lt;br /&gt;
|-&lt;br /&gt;
|&lt;br /&gt;
|t.integer   &amp;quot;Round&amp;quot;,  limit:24&lt;br /&gt;
|Round&lt;br /&gt;
|The completed round number&lt;br /&gt;
|-&lt;br /&gt;
|&lt;br /&gt;
|t.integer  &amp;quot;Reference_id&amp;quot; , limit:45&lt;br /&gt;
|Reference_id&lt;br /&gt;
|Acts as the foreign Key&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Implementation ==&lt;br /&gt;
&lt;br /&gt;
=== Assignment.rb ===&lt;br /&gt;
A new function get_last_review_date is added which takes assignid as a parameter and returns the last review deadline of the assignment. The deadline obtained from AssignmentDueDate for the corresponding assignid is stored in last_review_deadline and is returned.&lt;br /&gt;
&lt;br /&gt;
=== Parent Class:ScoreCal ===&lt;br /&gt;
ScoreCal stores the score calculated by its sub classes: on_the_fly_cal and LocalDbcal to the database. In the database, a new table localdbscore is created with the schema as explained in section 2.2. Depending upon the deadline_type, object of either on_the_fly_cal or LocalDbcal is created and the appropriate functions within the classes are called.&lt;br /&gt;
&lt;br /&gt;
=== Sub class 1: on_the_fly_cal ===&lt;br /&gt;
This is a subclass of class Scorecal contains a method calc_score whose functionality is to compute the holistic score. An object of on_the_fly_cal is called when the current time has not yet surpassed the time stored in last_review_deadline variable which contains the review duedate indicating that the assignment is still ongoing and has not been completed. The individual scores are retrieved from the database ScoreView and is stored in QuestionnaireData from which the holistic score of a student is calculated .&lt;br /&gt;
&lt;br /&gt;
When the user accesses the scores for a review, the current implementation does not store a holistic score but rather calculates the holistic score from the score for every individual criterion. To calculate the total holistic score for a specific round, the individual scores are weighted and added.&lt;br /&gt;
&lt;br /&gt;
This functionality is achieved by on_the_fly_calc.&lt;br /&gt;
&lt;br /&gt;
A snapshot of the system before implementing the changes is shown below.&lt;br /&gt;
[[File:rsz_flycur.png]]&lt;br /&gt;
&lt;br /&gt;
The proposed implementation involves computing the holistic score once and storing it in the local_db_scores database for a particular user and for a specified round. The stored value is accessed and obtained instead of computing the holistic score every single time.&lt;br /&gt;
&lt;br /&gt;
[[File:rsz_flyadb.png]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Sub class 2: LocalDbcal ===&lt;br /&gt;
This is a subclass of Scorecal and contains a function calc_score in class localDbcal. An object of LocalDbcal is called when the current time has surpassed the time stored in last_review_deadline variable which contains the review due date indicating that the assignment has been completed. This subclass retrieves the score from the database localDbscores for a corresponding student. If the score is not found in the database localDbscores, the function calc_score of on_the_fly_cal class is called to calculate the total from the weighted scores of each question. This calculated score is then inserted into the database.&lt;br /&gt;
&lt;br /&gt;
This score is now returned to the view from where it was called.&lt;br /&gt;
[[File:rsz_loccur.png]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The proposed implementation retrieves the round wise scores from the local_db_scores database and displays the average score once the deadline has passed rather than computing the average of the weighted scores for every access of the page as shown below.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[File:rsz_locadb.png]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Design Pattern ==&lt;br /&gt;
The ScoreCal superclass has 2 subclasses: OnTheFlyCal and LocalDbCal. ScoreCal acts as an interface to obtain the scores, either from OnTheFlyCal or LocalDbCal depending on the last_review_deadline obtained from the get_last_review_date() in the assignment model. This pattern is similar to strategy pattern where the client is the _review_tble.html.erb, interface is the superclass and the subclasses are called accordingly.&lt;br /&gt;
&lt;br /&gt;
[[File:UseCaseDiagram2.png]]&lt;br /&gt;
&lt;br /&gt;
== Testing ==&lt;br /&gt;
The testing for model: on_the_fly_calc is carried out by questionnaire_spec.rb in the spec folder. The minimum and maximum score that an user gives for each criterion is checked.&lt;br /&gt;
&lt;br /&gt;
Two more test cases to check whether the average score of each review falls within a given range:(0,100) will be added.&lt;br /&gt;
&lt;br /&gt;
For LocalDB_calc, the average calculated across round 1 and round 2 will be checked to fall within 0 to 100. These test cases will be added to questionnaire_spec.rb.&lt;/div&gt;</summary>
		<author><name>Nthanik</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2016_E1682:_Improve_score_calculation&amp;diff=106528</id>
		<title>CSC/ECE 517 Fall 2016 E1682: Improve score calculation</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2016_E1682:_Improve_score_calculation&amp;diff=106528"/>
		<updated>2016-12-05T04:26:48Z</updated>

		<summary type="html">&lt;p&gt;Nthanik: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;E1682. Improve score calculation&lt;br /&gt;
&lt;br /&gt;
== Introduction ==&lt;br /&gt;
&lt;br /&gt;
=== Expertiza ===&lt;br /&gt;
Expertiza is an open source project for school assignment management for instructors and students based on the Ruby on Rails framework. Expertiza allows the instructor to create new assignments and customize new or existing assignments. It also allows the instructor to create a list of topics the students can sign up for. Students can form teams in Expertiza to work on various projects and assignments. Students can also peer review other students' submissions. Expertiza supports submission across various document types, including the URLs and word documents. Expertiza provides a dashboard for all the assignments corresponding to a course and provides absolute control to the Instructors and Teaching Assistants. In addition to assignments, it encompasses peer reviews wherein participants are allowed to provide feedback anonymously about each other's work thereby providing scope for the better outcome. The due_date.rb file is responsible for informing the users about the deadline for submission of the each assignment. Due dates in Expertiza have their association with many other components like assignments, reviews etc.&lt;br /&gt;
&lt;br /&gt;
=== Purpose ===&lt;br /&gt;
The purpose of the project is to improve the functionality of score calculation. The scores in expertiza were calculated by taking the sum of weighted scores to calculate the total every time it is called. This takes considerable amount of time as there is a calculation involved each time. The methodology behind score calculation in expertiza can be significantly improved. The design behind calculating and storing scores can be tweaked to offer significant performance improvements. To achieve this, it is ideal to store overall holistic stores in addition to individual criterion scores.&lt;br /&gt;
&lt;br /&gt;
=== Problem Statement ===&lt;br /&gt;
The current drawback of the expertiza system lies in how the scores are stored: Expertiza stores the scores based on each response to each criterion, but no holistic scores are stored. As a result of this mechanism, the process slows down. This means that if we need to know what score user A gives to user B based on 100, we have to rely on the code to calculate it (since in answers table we only have the score that A gives B on each criterion).&lt;br /&gt;
&lt;br /&gt;
To overcome this bottleneck, two additional mechanisms can be included for handling the holistic scores.&lt;br /&gt;
&lt;br /&gt;
== Overall Description ==&lt;br /&gt;
Expertiza currently calculates scores dynamically when a page is called by taking the weighted scores of each question into consideration. This calculation is a time consuming process with a considerable overhead that significantly affects the performance. To solve the issue we propose a solution to store the holistic scores in a database, retrieving it every time it is required. This reduces the calculation that is required every time the score is called. When the user wants to check the scores of a completed assignment, a method localDB_calc is called and expertiza retrieves the scores of the student from the database rather than calculating the total from weighted scores. But, when the scores of an ongoing assignment is required, a method on_the_fly_calc is called that calculates the current score of the user. To determine which method will be invoked(on_the_fly_calc and localDB_calc), the current system time will be compared with last_review_deadline   &lt;br /&gt;
* If system time is greater than last_review_deadline, indicating that the deadline has passed, the method localDbcal will retrieve the holistic score from the database   &lt;br /&gt;
* If system time is lesser than last_review_deadline, indicating that the deadline has not passed, the method on_the_fly_cal will calculate the holistic score and display it.   &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The Dataflow diagram (DFD) for the proposed system is shown below.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[File:Flowchart12.png|center|frame|flowchart]]&lt;br /&gt;
&lt;br /&gt;
== Tasks Identified ==&lt;br /&gt;
The two suggested mechanisms for handling the storage and calculation of holistic scores for peer-reviews, as specified in the requirements document are :&lt;br /&gt;
* on_the_fly_calc&lt;br /&gt;
* localDB_calc&lt;br /&gt;
&lt;br /&gt;
=== on_the_fly_calc ===&lt;br /&gt;
When the assignment is still ongoing , this method is called and it calculates holistic scores over a set of data (in this case, a set of record in answers table, namely the responses from user A to user B on each criterion) and store it in localdbscores. This stored score is retrieved and printed when the user A clicks on the &amp;quot;Your scores&amp;quot; link.&lt;br /&gt;
&lt;br /&gt;
In the current implementation, when a user A wants to view the score given by user B, user A's score(i.e. out of 100) will be calculated everytime using the scores given by user B for each criterion (i.e.. score out of 5).&lt;br /&gt;
&lt;br /&gt;
Handles the calculation of reputations for each reviewer in the case of an ongoing assignment.&lt;br /&gt;
&lt;br /&gt;
=== localDB_calc ===&lt;br /&gt;
Once the deadline for an assignment is completed, the method localDB_calc calculates the holistic score over a single db query (in this case, a query would be: “get the score that user A gives user B on assignment 999 on round 2”). The query can also ask to print the average of all the scores in round 1 and round2, this average will be retrieved from localdbscores and printed.&lt;br /&gt;
&lt;br /&gt;
This method handles the calculation of reputations for each reviewer in the case of a finished assignment. (all the reputations are calculated and stored since they are finalized).&lt;br /&gt;
&lt;br /&gt;
=== Database ===&lt;br /&gt;
To store the holistic scores when an assignment is completed, a database localdbscores needs to be created. The value from this db is retrieved and displayed when the scores of a completed assignment needs to be viewed. The database Design is shown below.&lt;br /&gt;
&lt;br /&gt;
== Database Design ==&lt;br /&gt;
A table localdbscores will be created as:&lt;br /&gt;
&lt;br /&gt;
class CreateLocalDB&amp;lt;ActiveRecord::Migration&lt;br /&gt;
&lt;br /&gt;
def self.up&lt;br /&gt;
&lt;br /&gt;
create_table :localdb_scores do |t|&lt;br /&gt;
&lt;br /&gt;
t.column :id, :integer&lt;br /&gt;
&lt;br /&gt;
t.column :score, :integer&lt;br /&gt;
&lt;br /&gt;
t.column :round, :integer&lt;br /&gt;
&lt;br /&gt;
t.column :type, :string&lt;br /&gt;
&lt;br /&gt;
t.column :reference_id, :integer&lt;br /&gt;
&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
with id, score, round, type, reference_id as its attributes as shown in the table below&lt;br /&gt;
&lt;br /&gt;
&amp;quot;localdbscores&amp;quot; will have the following scores&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|&lt;br /&gt;
|t.integer    &amp;quot;id&amp;quot;,         limit: 24&lt;br /&gt;
|id&lt;br /&gt;
|Primary Key, Auto generated&lt;br /&gt;
|-&lt;br /&gt;
|&lt;br /&gt;
|t.string    &amp;quot;Type&amp;quot;,      limit: 255&lt;br /&gt;
|Type&lt;br /&gt;
|Type of score: either final or intermediate&lt;br /&gt;
|-&lt;br /&gt;
|&lt;br /&gt;
|t.integer    &amp;quot;Score&amp;quot;,  limit: 24&lt;br /&gt;
|Score&lt;br /&gt;
|Total score calculated based on each response to each criterion&lt;br /&gt;
|-&lt;br /&gt;
|&lt;br /&gt;
|t.integer   &amp;quot;Round&amp;quot;,  limit:24&lt;br /&gt;
|Round&lt;br /&gt;
|The completed round number&lt;br /&gt;
|-&lt;br /&gt;
|&lt;br /&gt;
|t.integer  &amp;quot;Reference_id&amp;quot; , limit:45&lt;br /&gt;
|Reference_id&lt;br /&gt;
|Acts as the foreign Key&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Implementation ==&lt;br /&gt;
&lt;br /&gt;
=== Assignment.rb ===&lt;br /&gt;
A new function get_last_review_date is added which takes assignid as a parameter and returns the last review deadline of the assignment. The deadline obtained from AssignmentDueDate for the corresponding assignid is stored in last_review_deadline and is returned.&lt;br /&gt;
&lt;br /&gt;
=== Parent Class:ScoreCal ===&lt;br /&gt;
ScoreCal stores the score calculated by its sub classes: on_the_fly_cal and LocalDbcal to the database. In the database, a new table localdbscore is created with the schema as explained in section 2.2. Depending upon the deadline_type, object of either on_the_fly_cal or LocalDbcal is created and the appropriate functions within the classes are called.&lt;br /&gt;
&lt;br /&gt;
=== Sub class 1: on_the_fly_cal ===&lt;br /&gt;
This is a subclass of class Scorecal contains a method calc_score whose functionality is to compute the holistic score. An object of on_the_fly_cal is called when the current time has not yet surpassed the time stored in last_review_deadline variable which contains the review duedate indicating that the assignment is still ongoing and has not been completed. The individual scores are retrieved from the database ScoreView and is stored in QuestionnaireData from which the holistic score of a student is calculated .&lt;br /&gt;
&lt;br /&gt;
When the user accesses the scores for a review, the current implementation does not store a holistic score but rather calculates the holistic score from the score for every individual criterion. To calculate the total holistic score for a specific round, the individual scores are weighted and added.&lt;br /&gt;
&lt;br /&gt;
This functionality is achieved by on_the_fly_calc.&lt;br /&gt;
&lt;br /&gt;
A snapshot of the system before implementing the changes is shown below.&lt;br /&gt;
[[File:rsz_flycur.png]]&lt;br /&gt;
&lt;br /&gt;
The proposed implementation involves computing the holistic score once and storing it in the local_db_scores database for a particular user and for a specified round. The stored value is accessed and obtained instead of computing the holistic score every single time.&lt;br /&gt;
&lt;br /&gt;
[[File:rsz_flyadb.png]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Sub class 2: LocalDbcal ===&lt;br /&gt;
This is a subclass of Scorecal and contains a function calc_score in class localDbcal. An object of LocalDbcal is called when the current time has surpassed the time stored in last_review_deadline variable which contains the review due date indicating that the assignment has been completed. This subclass retrieves the score from the database localDbscores for a corresponding student. If the score is not found in the database localDbscores, the function calc_score of on_the_fly_cal class is called to calculate the total from the weighted scores of each question. This calculated score is then inserted into the database.&lt;br /&gt;
&lt;br /&gt;
This score is now returned to the view from where it was called.&lt;br /&gt;
[[File:rsz_loccur.png]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The proposed implementation retrieves the round wise scores from the local_db_scores database and displays the average score once the deadline has passed rather than computing the average of the weighted scores for every access of the page as shown below.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[File:rsz_locadb.png]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== _review_table.html.erb ===&lt;br /&gt;
The current implementation of this was to calculate the score and display it which as we know is a time consuming process. It has been changed to check if the current time has crossed the last_review_deadline obtained in assignments.rb and call the corresponding class as required.&lt;br /&gt;
&lt;br /&gt;
If the current date has surpassed the last_review_deadline, it is an indication that the due date has passed and the class localDbcal is called to retrieve a value from the database as mentioned above. On the other hand, on_the_fly_cal is called when the current date has not surpassed the last_review_deadline, indicating that the assignment is ongoing and the holistic score is calculated and passed to the view.&lt;br /&gt;
&lt;br /&gt;
== Design Pattern ==&lt;br /&gt;
The ScoreCal superclass has 2 subclasses: OnTheFlyCal and LocalDbCal. ScoreCal acts as an interface to obtain the scores, either from OnTheFlyCal or LocalDbCal depending on the last_review_deadline obtained from the get_last_review_date() in the assignment model. This pattern is similar to strategy pattern where the client is the _review_tble.html.erb, interface is the superclass and the subclasses are called accordingly.&lt;br /&gt;
&lt;br /&gt;
[[File:UseCaseDiagram2.png]]&lt;br /&gt;
&lt;br /&gt;
== Testing ==&lt;br /&gt;
The testing for model: on_the_fly_calc is carried out by questionnaire_spec.rb in the spec folder. The minimum and maximum score that an user gives for each criterion is checked.&lt;br /&gt;
&lt;br /&gt;
Two more test cases to check whether the average score of each review falls within a given range:(0,100) will be added.&lt;br /&gt;
&lt;br /&gt;
For LocalDB_calc, the average calculated across round 1 and round 2 will be checked to fall within 0 to 100. These test cases will be added to questionnaire_spec.rb.&lt;/div&gt;</summary>
		<author><name>Nthanik</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2016_E1682:_Improve_score_calculation&amp;diff=106527</id>
		<title>CSC/ECE 517 Fall 2016 E1682: Improve score calculation</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2016_E1682:_Improve_score_calculation&amp;diff=106527"/>
		<updated>2016-12-05T04:26:10Z</updated>

		<summary type="html">&lt;p&gt;Nthanik: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;E1682. Improve score calculation&lt;br /&gt;
&lt;br /&gt;
== Introduction ==&lt;br /&gt;
&lt;br /&gt;
=== Expertiza ===&lt;br /&gt;
Expertiza is an open source project for school assignment management for instructors and students based on the Ruby on Rails framework. Expertiza allows the instructor to create new assignments and customize new or existing assignments. It also allows the instructor to create a list of topics the students can sign up for. Students can form teams in Expertiza to work on various projects and assignments. Students can also peer review other students' submissions. Expertiza supports submission across various document types, including the URLs and word documents. Expertiza provides a dashboard for all the assignments corresponding to a course and provides absolute control to the Instructors and Teaching Assistants. In addition to assignments, it encompasses peer reviews wherein participants are allowed to provide feedback anonymously about each other's work thereby providing scope for the better outcome. The due_date.rb file is responsible for informing the users about the deadline for submission of the each assignment. Due dates in Expertiza have their association with many other components like assignments, reviews etc.&lt;br /&gt;
&lt;br /&gt;
=== Purpose ===&lt;br /&gt;
The purpose of the project is to improve the functionality of score calculation. The scores in expertiza were calculated by taking the sum of weighted scores to calculate the total every time it is called. This takes considerable amount of time as there is a calculation involved each time. The methodology behind score calculation in expertiza can be significantly improved. The design behind calculating and storing scores can be tweaked to offer significant performance improvements. To achieve this, it is ideal to store overall holistic stores in addition to individual criterion scores.&lt;br /&gt;
&lt;br /&gt;
=== Problem Statement ===&lt;br /&gt;
The current drawback of the expertiza system lies in how the scores are stored: Expertiza stores the scores based on each response to each criterion, but no holistic scores are stored. As a result of this mechanism, the process slows down. This means that if we need to know what score user A gives to user B based on 100, we have to rely on the code to calculate it (since in answers table we only have the score that A gives B on each criterion).&lt;br /&gt;
&lt;br /&gt;
To overcome this bottleneck, two additional mechanisms can be included for handling the holistic scores.&lt;br /&gt;
&lt;br /&gt;
== Overall Description ==&lt;br /&gt;
Expertiza currently calculates scores dynamically when a page is called by taking the weighted scores of each question into consideration. This calculation is a time consuming process with a considerable overhead that significantly affects the performance. To solve the issue we propose a solution to store the holistic scores in a database, retrieving it every time it is required. This reduces the calculation that is required every time the score is called. When the user wants to check the scores of a completed assignment, a method localDB_calc is called and expertiza retrieves the scores of the student from the database rather than calculating the total from weighted scores. But, when the scores of an ongoing assignment is required, a method on_the_fly_calc is called that calculates the current score of the user. To determine which method will be invoked(on_the_fly_calc and localDB_calc), the current system time will be compared with last_review_deadline   &lt;br /&gt;
* If system time is greater than last_review_deadline, indicating that the deadline has passed, the method localDbcal will retrieve the holistic score from the database   &lt;br /&gt;
* If system time is lesser than last_review_deadline, indicating that the deadline has not passed, the method on_the_fly_cal will calculate the holistic score and display it.   &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The Dataflow diagram (DFD) for the proposed system is shown below.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[File:Flowchart12.png|center|frame|flowchart]]&lt;br /&gt;
&lt;br /&gt;
== Tasks Identified ==&lt;br /&gt;
The two suggested mechanisms for handling the storage and calculation of holistic scores for peer-reviews, as specified in the requirements document are :&lt;br /&gt;
* on_the_fly_calc&lt;br /&gt;
* localDB_calc&lt;br /&gt;
&lt;br /&gt;
=== on_the_fly_calc ===&lt;br /&gt;
When the assignment is still ongoing , this method is called and it calculates holistic scores over a set of data (in this case, a set of record in answers table, namely the responses from user A to user B on each criterion) and store it in localdbscores. This stored score is retrieved and printed when the user A clicks on the &amp;quot;Your scores&amp;quot; link.&lt;br /&gt;
&lt;br /&gt;
In the current implementation, when a user A wants to view the score given by user B, user A's score(i.e. out of 100) will be calculated everytime using the scores given by user B for each criterion (i.e.. score out of 5).&lt;br /&gt;
&lt;br /&gt;
Handles the calculation of reputations for each reviewer in the case of an ongoing assignment.&lt;br /&gt;
&lt;br /&gt;
=== localDB_calc ===&lt;br /&gt;
Once the deadline for an assignment is completed, the method localDB_calc calculates the holistic score over a single db query (in this case, a query would be: “get the score that user A gives user B on assignment 999 on round 2”). The query can also ask to print the average of all the scores in round 1 and round2, this average will be retrieved from localdbscores and printed.&lt;br /&gt;
&lt;br /&gt;
This method handles the calculation of reputations for each reviewer in the case of a finished assignment. (all the reputations are calculated and stored since they are finalized).&lt;br /&gt;
&lt;br /&gt;
=== Database ===&lt;br /&gt;
To store the holistic scores when an assignment is completed, a database localdbscores needs to be created. The value from this db is retrieved and displayed when the scores of a completed assignment needs to be viewed. The database Design is shown below.&lt;br /&gt;
&lt;br /&gt;
== Database Design ==&lt;br /&gt;
A table localdbscores will be created as:&lt;br /&gt;
&lt;br /&gt;
class CreateLocalDB&amp;lt;ActiveRecord::Migration&lt;br /&gt;
&lt;br /&gt;
def self.up&lt;br /&gt;
&lt;br /&gt;
create_table :localdb_scores do |t|&lt;br /&gt;
&lt;br /&gt;
t.column :id, :integer&lt;br /&gt;
&lt;br /&gt;
t.column :score, :integer&lt;br /&gt;
&lt;br /&gt;
t.column :round, :integer&lt;br /&gt;
&lt;br /&gt;
t.column :type, :string&lt;br /&gt;
&lt;br /&gt;
t.column :reference_id, :integer&lt;br /&gt;
&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
with id, score, round, type, reference_id as its attributes as shown in the table below&lt;br /&gt;
&lt;br /&gt;
&amp;quot;localdbscores&amp;quot; will have the following scores&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|&lt;br /&gt;
|t.integer    &amp;quot;id&amp;quot;,         limit: 24&lt;br /&gt;
|id&lt;br /&gt;
|Primary Key, Auto generated&lt;br /&gt;
|-&lt;br /&gt;
|&lt;br /&gt;
|t.string    &amp;quot;Type&amp;quot;,      limit: 255&lt;br /&gt;
|Type&lt;br /&gt;
|Type of score: either final or intermediate&lt;br /&gt;
|-&lt;br /&gt;
|&lt;br /&gt;
|t.integer    &amp;quot;Score&amp;quot;,  limit: 24&lt;br /&gt;
|Score&lt;br /&gt;
|Total score calculated based on each response to each criterion&lt;br /&gt;
|-&lt;br /&gt;
|&lt;br /&gt;
|t.integer   &amp;quot;Round&amp;quot;,  limit:24&lt;br /&gt;
|Round&lt;br /&gt;
|The completed round number&lt;br /&gt;
|-&lt;br /&gt;
|&lt;br /&gt;
|t.integer  &amp;quot;Reference_id&amp;quot; , limit:45&lt;br /&gt;
|Reference_id&lt;br /&gt;
|Acts as the foreign Key&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Implementation ==&lt;br /&gt;
&lt;br /&gt;
=== Assignment.rb ===&lt;br /&gt;
A new function get_last_review_date is added which takes assignid as a parameter and returns the last review deadline of the assignment. The deadline obtained from AssignmentDueDate for the corresponding assignid is stored in last_review_deadline and is returned.&lt;br /&gt;
&lt;br /&gt;
=== Parent Class:ScoreCal ===&lt;br /&gt;
ScoreCal stores the score calculated by its sub classes: on_the_fly_cal and LocalDbcal to the database. In the database, a new table localdbscore is created with the schema as explained in section 2.2. Depending upon the deadline_type, object of either on_the_fly_cal or LocalDbcal is created and the appropriate functions within the classes are called.&lt;br /&gt;
&lt;br /&gt;
=== Sub class 1: on_the_fly_cal ===&lt;br /&gt;
This is a subclass of class Scorecal contains a method calc_score whose functionality is to compute the holistic score. An object of on_the_fly_cal is called when the current time has not yet surpassed the time stored in last_review_deadline variable which contains the review duedate indicating that the assignment is still ongoing and has not been completed. The individual scores are retrieved from the database ScoreView and is stored in QuestionnaireData from which the holistic score of a student is calculated .&lt;br /&gt;
&lt;br /&gt;
When the user accesses the scores for a review, the current implementation does not store a holistic score but rather calculates the holistic score from the score for every individual criterion. To calculate the total holistic score for a specific round, the individual scores are weighted and added.&lt;br /&gt;
&lt;br /&gt;
This functionality is achieved by on_the_fly_calc.&lt;br /&gt;
&lt;br /&gt;
A snapshot of the system before implementing the changes is shown below.&lt;br /&gt;
[[File:rsz_flycur.png]]&lt;br /&gt;
&lt;br /&gt;
The proposed implementation involves computing the holistic score once and storing it in the local_db_scores database for a particular user and for a specified round. The stored value is accessed and obtained instead of computing the holistic score every single time.&lt;br /&gt;
&lt;br /&gt;
[[File:rsz_flyadb.png]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Sub class 2: LocalDbcal ===&lt;br /&gt;
This is a subclass of Scorecal and contains a function calc_score in class localDbcal. An object of LocalDbcal is called when the current time has surpassed the time stored in last_review_deadline variable which contains the review due date indicating that the assignment has been completed. This subclass retrieves the score from the database localDbscores for a corresponding student. If the score is not found in the database localDbscores, the function calc_score of on_the_fly_cal class is called to calculate the total from the weighted scores of each question. This calculated score is then inserted into the database.&lt;br /&gt;
&lt;br /&gt;
This score is now returned to the view from where it was called.&lt;br /&gt;
[[File:rsz_loccur.png]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The proposed implementation retrieves the round wise scores from the local_db_scores database and displays the average score once the deadline has passed rather than computing the average of the weighted scores for every access of the page as shown below.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[File:rsz_locadb.png]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== _review_table.html.erb ===&lt;br /&gt;
The current implementation of this was to calculate the score and display it which as we know is a time consuming process. It has been changed to check if the current time has crossed the last_review_deadline obtained in assignments.rb and call the corresponding class as required.&lt;br /&gt;
&lt;br /&gt;
If the current date has surpassed the last_review_deadline, it is an indication that the due date has passed and the class localDbcal is called to retrieve a value from the database as mentioned above. On the other hand, on_the_fly_cal is called when the current date has not surpassed the last_review_deadline, indicating that the assignment is ongoing and the holistic score is calculated and passed to the view.&lt;br /&gt;
&lt;br /&gt;
== Design Pattern ==&lt;br /&gt;
The ScoreCal superclass has 2 subclasses: OnTheFlyCal and LocalDbCal. ScoreCal acts as an interface to obtain the scores, either from OnTheFlyCal or LocalDbCal depending on the last_review_deadline obtained from the get_last_review_date() in the assignment model. This pattern is similar to strategy pattern where the client is the _review_tble.html.erb, interface is the superclass and the subclasses are called accordingly.&lt;br /&gt;
[[File:UseCaseDiagram2.png]]&lt;br /&gt;
&lt;br /&gt;
== Testing ==&lt;br /&gt;
The testing for model: on_the_fly_calc is carried out by questionnaire_spec.rb in the spec folder. The minimum and maximum score that an user gives for each criterion is checked.&lt;br /&gt;
&lt;br /&gt;
Two more test cases to check whether the average score of each review falls within a given range:(0,100) will be added.&lt;br /&gt;
&lt;br /&gt;
For LocalDB_calc, the average calculated across round 1 and round 2 will be checked to fall within 0 to 100. These test cases will be added to questionnaire_spec.rb.&lt;/div&gt;</summary>
		<author><name>Nthanik</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2016_E1682:_Improve_score_calculation&amp;diff=106526</id>
		<title>CSC/ECE 517 Fall 2016 E1682: Improve score calculation</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2016_E1682:_Improve_score_calculation&amp;diff=106526"/>
		<updated>2016-12-05T04:25:31Z</updated>

		<summary type="html">&lt;p&gt;Nthanik: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;E1682. Improve score calculation&lt;br /&gt;
&lt;br /&gt;
== Introduction ==&lt;br /&gt;
&lt;br /&gt;
=== Expertiza ===&lt;br /&gt;
Expertiza is an open source project for school assignment management for instructors and students based on the Ruby on Rails framework. Expertiza allows the instructor to create new assignments and customize new or existing assignments. It also allows the instructor to create a list of topics the students can sign up for. Students can form teams in Expertiza to work on various projects and assignments. Students can also peer review other students' submissions. Expertiza supports submission across various document types, including the URLs and word documents. Expertiza provides a dashboard for all the assignments corresponding to a course and provides absolute control to the Instructors and Teaching Assistants. In addition to assignments, it encompasses peer reviews wherein participants are allowed to provide feedback anonymously about each other's work thereby providing scope for the better outcome. The due_date.rb file is responsible for informing the users about the deadline for submission of the each assignment. Due dates in Expertiza have their association with many other components like assignments, reviews etc.&lt;br /&gt;
&lt;br /&gt;
=== Purpose ===&lt;br /&gt;
The purpose of the project is to improve the functionality of score calculation. The scores in expertiza were calculated by taking the sum of weighted scores to calculate the total every time it is called. This takes considerable amount of time as there is a calculation involved each time. The methodology behind score calculation in expertiza can be significantly improved. The design behind calculating and storing scores can be tweaked to offer significant performance improvements. To achieve this, it is ideal to store overall holistic stores in addition to individual criterion scores.&lt;br /&gt;
&lt;br /&gt;
=== Problem Statement ===&lt;br /&gt;
The current drawback of the expertiza system lies in how the scores are stored: Expertiza stores the scores based on each response to each criterion, but no holistic scores are stored. As a result of this mechanism, the process slows down. This means that if we need to know what score user A gives to user B based on 100, we have to rely on the code to calculate it (since in answers table we only have the score that A gives B on each criterion).&lt;br /&gt;
&lt;br /&gt;
To overcome this bottleneck, two additional mechanisms can be included for handling the holistic scores.&lt;br /&gt;
&lt;br /&gt;
== Overall Description ==&lt;br /&gt;
Expertiza currently calculates scores dynamically when a page is called by taking the weighted scores of each question into consideration. This calculation is a time consuming process with a considerable overhead that significantly affects the performance. To solve the issue we propose a solution to store the holistic scores in a database, retrieving it every time it is required. This reduces the calculation that is required every time the score is called. When the user wants to check the scores of a completed assignment, a method localDB_calc is called and expertiza retrieves the scores of the student from the database rather than calculating the total from weighted scores. But, when the scores of an ongoing assignment is required, a method on_the_fly_calc is called that calculates the current score of the user. To determine which method will be invoked(on_the_fly_calc and localDB_calc), the current system time will be compared with last_review_deadline   &lt;br /&gt;
* If system time is greater than last_review_deadline, indicating that the deadline has passed, the method localDbcal will retrieve the holistic score from the database   &lt;br /&gt;
* If system time is lesser than last_review_deadline, indicating that the deadline has not passed, the method on_the_fly_cal will calculate the holistic score and display it.   &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The Dataflow diagram (DFD) for the proposed system is shown below.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[File:Flowchart12.png|center|frame|flowchart]]&lt;br /&gt;
&lt;br /&gt;
== Tasks Identified ==&lt;br /&gt;
The two suggested mechanisms for handling the storage and calculation of holistic scores for peer-reviews, as specified in the requirements document are :&lt;br /&gt;
* on_the_fly_calc&lt;br /&gt;
* localDB_calc&lt;br /&gt;
&lt;br /&gt;
=== on_the_fly_calc ===&lt;br /&gt;
When the assignment is still ongoing , this method is called and it calculates holistic scores over a set of data (in this case, a set of record in answers table, namely the responses from user A to user B on each criterion) and store it in localdbscores. This stored score is retrieved and printed when the user A clicks on the &amp;quot;Your scores&amp;quot; link.&lt;br /&gt;
&lt;br /&gt;
In the current implementation, when a user A wants to view the score given by user B, user A's score(i.e. out of 100) will be calculated everytime using the scores given by user B for each criterion (i.e.. score out of 5).&lt;br /&gt;
&lt;br /&gt;
Handles the calculation of reputations for each reviewer in the case of an ongoing assignment.&lt;br /&gt;
&lt;br /&gt;
=== localDB_calc ===&lt;br /&gt;
Once the deadline for an assignment is completed, the method localDB_calc calculates the holistic score over a single db query (in this case, a query would be: “get the score that user A gives user B on assignment 999 on round 2”). The query can also ask to print the average of all the scores in round 1 and round2, this average will be retrieved from localdbscores and printed.&lt;br /&gt;
&lt;br /&gt;
This method handles the calculation of reputations for each reviewer in the case of a finished assignment. (all the reputations are calculated and stored since they are finalized).&lt;br /&gt;
&lt;br /&gt;
=== Database ===&lt;br /&gt;
To store the holistic scores when an assignment is completed, a database localdbscores needs to be created. The value from this db is retrieved and displayed when the scores of a completed assignment needs to be viewed. The database Design is shown below.&lt;br /&gt;
&lt;br /&gt;
== Database Design ==&lt;br /&gt;
A table localdbscores will be created as:&lt;br /&gt;
&lt;br /&gt;
class CreateLocalDB&amp;lt;ActiveRecord::Migration&lt;br /&gt;
&lt;br /&gt;
def self.up&lt;br /&gt;
&lt;br /&gt;
create_table :localdb_scores do |t|&lt;br /&gt;
&lt;br /&gt;
t.column :id, :integer&lt;br /&gt;
&lt;br /&gt;
t.column :score, :integer&lt;br /&gt;
&lt;br /&gt;
t.column :round, :integer&lt;br /&gt;
&lt;br /&gt;
t.column :type, :string&lt;br /&gt;
&lt;br /&gt;
t.column :reference_id, :integer&lt;br /&gt;
&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
with id, score, round, type, reference_id as its attributes as shown in the table below&lt;br /&gt;
&lt;br /&gt;
&amp;quot;localdbscores&amp;quot; will have the following scores&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|&lt;br /&gt;
|t.integer    &amp;quot;id&amp;quot;,         limit: 24&lt;br /&gt;
|id&lt;br /&gt;
|Primary Key, Auto generated&lt;br /&gt;
|-&lt;br /&gt;
|&lt;br /&gt;
|t.string    &amp;quot;Type&amp;quot;,      limit: 255&lt;br /&gt;
|Type&lt;br /&gt;
|Type of score: either final or intermediate&lt;br /&gt;
|-&lt;br /&gt;
|&lt;br /&gt;
|t.integer    &amp;quot;Score&amp;quot;,  limit: 24&lt;br /&gt;
|Score&lt;br /&gt;
|Total score calculated based on each response to each criterion&lt;br /&gt;
|-&lt;br /&gt;
|&lt;br /&gt;
|t.integer   &amp;quot;Round&amp;quot;,  limit:24&lt;br /&gt;
|Round&lt;br /&gt;
|The completed round number&lt;br /&gt;
|-&lt;br /&gt;
|&lt;br /&gt;
|t.integer  &amp;quot;Reference_id&amp;quot; , limit:45&lt;br /&gt;
|Reference_id&lt;br /&gt;
|Acts as the foreign Key&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Implementation ==&lt;br /&gt;
&lt;br /&gt;
=== Assignment.rb ===&lt;br /&gt;
A new function get_last_review_date is added which takes assignid as a parameter and returns the last review deadline of the assignment. The deadline obtained from AssignmentDueDate for the corresponding assignid is stored in last_review_deadline and is returned.&lt;br /&gt;
&lt;br /&gt;
=== Parent Class:ScoreCal ===&lt;br /&gt;
ScoreCal stores the score calculated by its sub classes: on_the_fly_cal and LocalDbcal to the database. In the database, a new table localdbscore is created with the schema as explained in section 2.2. Depending upon the deadline_type, object of either on_the_fly_cal or LocalDbcal is created and the appropriate functions within the classes are called.&lt;br /&gt;
&lt;br /&gt;
=== Sub class 1: on_the_fly_cal ===&lt;br /&gt;
This is a subclass of class Scorecal contains a method calc_score whose functionality is to compute the holistic score. An object of on_the_fly_cal is called when the current time has not yet surpassed the time stored in last_review_deadline variable which contains the review duedate indicating that the assignment is still ongoing and has not been completed. The individual scores are retrieved from the database ScoreView and is stored in QuestionnaireData from which the holistic score of a student is calculated .&lt;br /&gt;
&lt;br /&gt;
When the user accesses the scores for a review, the current implementation does not store a holistic score but rather calculates the holistic score from the score for every individual criterion. To calculate the total holistic score for a specific round, the individual scores are weighted and added.&lt;br /&gt;
&lt;br /&gt;
This functionality is achieved by on_the_fly_calc.&lt;br /&gt;
&lt;br /&gt;
A snapshot of the system before implementing the changes is shown below.&lt;br /&gt;
[[File:rsz_flycur.png]]&lt;br /&gt;
&lt;br /&gt;
The proposed implementation involves computing the holistic score once and storing it in the local_db_scores database for a particular user and for a specified round. The stored value is accessed and obtained instead of computing the holistic score every single time.&lt;br /&gt;
&lt;br /&gt;
[[File:rsz_flyadb.png]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Sub class 2: LocalDbcal ===&lt;br /&gt;
This is a subclass of Scorecal and contains a function calc_score in class localDbcal. An object of LocalDbcal is called when the current time has surpassed the time stored in last_review_deadline variable which contains the review due date indicating that the assignment has been completed. This subclass retrieves the score from the database localDbscores for a corresponding student. If the score is not found in the database localDbscores, the function calc_score of on_the_fly_cal class is called to calculate the total from the weighted scores of each question. This calculated score is then inserted into the database.&lt;br /&gt;
&lt;br /&gt;
This score is now returned to the view from where it was called.&lt;br /&gt;
[[File:rsz_loccur.png]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The proposed implementation retrieves the round wise scores from the local_db_scores database and displays the average score once the deadline has passed rather than computing the average of the weighted scores for every access of the page as shown below.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[File:rsz_locadb.png]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== _review_table.html.erb ===&lt;br /&gt;
The current implementation of this was to calculate the score and display it which as we know is a time consuming process. It has been changed to check if the current time has crossed the last_review_deadline obtained in assignments.rb and call the corresponding class as required.&lt;br /&gt;
&lt;br /&gt;
If the current date has surpassed the last_review_deadline, it is an indication that the due date has passed and the class localDbcal is called to retrieve a value from the database as mentioned above. On the other hand, on_the_fly_cal is called when the current date has not surpassed the last_review_deadline, indicating that the assignment is ongoing and the holistic score is calculated and passed to the view.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Design Pattern ==&lt;br /&gt;
The ScoreCal superclass has 2 subclasses: OnTheFlyCal and LocalDbCal. ScoreCal acts as an interface to obtain the scores, either from OnTheFlyCal or LocalDbCal depending on the last_review_deadline obtained from the get_last_review_date() in the assignment model. This pattern is similar to strategy pattern where the client is the _review_tble.html.erb, interface is the superclass and the subclasses are called accordingly.&lt;br /&gt;
[[File:UseCaseDiagram2.png]]&lt;br /&gt;
&lt;br /&gt;
== Implementation ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Testing ==&lt;br /&gt;
The testing for model: on_the_fly_calc is carried out by questionnaire_spec.rb in the spec folder. The minimum and maximum score that an user gives for each criterion is checked.&lt;br /&gt;
&lt;br /&gt;
Two more test cases to check whether the average score of each review falls within a given range:(0,100) will be added.&lt;br /&gt;
&lt;br /&gt;
For LocalDB_calc, the average calculated across round 1 and round 2 will be checked to fall within 0 to 100. These test cases will be added to questionnaire_spec.rb.&lt;/div&gt;</summary>
		<author><name>Nthanik</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2016_E1682:_Improve_score_calculation&amp;diff=106525</id>
		<title>CSC/ECE 517 Fall 2016 E1682: Improve score calculation</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2016_E1682:_Improve_score_calculation&amp;diff=106525"/>
		<updated>2016-12-05T04:22:42Z</updated>

		<summary type="html">&lt;p&gt;Nthanik: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;E1682. Improve score calculation&lt;br /&gt;
&lt;br /&gt;
== Introduction ==&lt;br /&gt;
&lt;br /&gt;
=== Expertiza ===&lt;br /&gt;
Expertiza is an open source project for school assignment management for instructors and students based on the Ruby on Rails framework. Expertiza allows the instructor to create new assignments and customize new or existing assignments. It also allows the instructor to create a list of topics the students can sign up for. Students can form teams in Expertiza to work on various projects and assignments. Students can also peer review other students' submissions. Expertiza supports submission across various document types, including the URLs and word documents. Expertiza provides a dashboard for all the assignments corresponding to a course and provides absolute control to the Instructors and Teaching Assistants. In addition to assignments, it encompasses peer reviews wherein participants are allowed to provide feedback anonymously about each other's work thereby providing scope for the better outcome. The due_date.rb file is responsible for informing the users about the deadline for submission of the each assignment. Due dates in Expertiza have their association with many other components like assignments, reviews etc.&lt;br /&gt;
&lt;br /&gt;
=== Purpose ===&lt;br /&gt;
The purpose of the project is to improve the functionality of score calculation. The scores in expertiza were calculated by taking the sum of weighted scores to calculate the total every time it is called. This takes considerable amount of time as there is a calculation involved each time. The methodology behind score calculation in expertiza can be significantly improved. The design behind calculating and storing scores can be tweaked to offer significant performance improvements. To achieve this, it is ideal to store overall holistic stores in addition to individual criterion scores.&lt;br /&gt;
&lt;br /&gt;
=== Problem Statement ===&lt;br /&gt;
The current drawback of the expertiza system lies in how the scores are stored: Expertiza stores the scores based on each response to each criterion, but no holistic scores are stored. As a result of this mechanism, the process slows down. This means that if we need to know what score user A gives to user B based on 100, we have to rely on the code to calculate it (since in answers table we only have the score that A gives B on each criterion).&lt;br /&gt;
&lt;br /&gt;
To overcome this bottleneck, two additional mechanisms can be included for handling the holistic scores.&lt;br /&gt;
&lt;br /&gt;
== Overall Description ==&lt;br /&gt;
Expertiza currently calculates scores dynamically when a page is called by taking the weighted scores of each question into consideration. This calculation is a time consuming process with a considerable overhead that significantly affects the performance. To solve the issue we propose a solution to store the holistic scores in a database, retrieving it every time it is required. This reduces the calculation that is required every time the score is called. When the user wants to check the scores of a completed assignment, a method localDB_calc is called and expertiza retrieves the scores of the student from the database rather than calculating the total from weighted scores. But, when the scores of an ongoing assignment is required, a method on_the_fly_calc is called that calculates the current score of the user. To determine which method will be invoked(on_the_fly_calc and localDB_calc), the current system time will be compared with last_review_deadline   &lt;br /&gt;
* If system time is greater than last_review_deadline, indicating that the deadline has passed, the method localDbcal will retrieve the holistic score from the database   &lt;br /&gt;
* If system time is lesser than last_review_deadline, indicating that the deadline has not passed, the method on_the_fly_cal will calculate the holistic score and display it.   &lt;br /&gt;
&lt;br /&gt;
== *FLOW CHART ==&lt;br /&gt;
&lt;br /&gt;
== Tasks Identified ==&lt;br /&gt;
The two suggested mechanisms for handling the storage and calculation of holistic scores for peer-reviews, as specified in the requirements document are :&lt;br /&gt;
* on_the_fly_calc&lt;br /&gt;
* localDB_calc&lt;br /&gt;
&lt;br /&gt;
=== on_the_fly_calc ===&lt;br /&gt;
When the assignment is still ongoing , this method is called and it calculates holistic scores over a set of data (in this case, a set of record in answers table, namely the responses from user A to user B on each criterion) and store it in localdbscores. This stored score is retrieved and printed when the user A clicks on the &amp;quot;Your scores&amp;quot; link.&lt;br /&gt;
&lt;br /&gt;
In the current implementation, when a user A wants to view the score given by user B, user A's score(i.e. out of 100) will be calculated everytime using the scores given by user B for each criterion (i.e.. score out of 5).&lt;br /&gt;
&lt;br /&gt;
Handles the calculation of reputations for each reviewer in the case of an ongoing assignment.&lt;br /&gt;
&lt;br /&gt;
=== localDB_calc ===&lt;br /&gt;
Once the deadline for an assignment is completed, the method localDB_calc calculates the holistic score over a single db query (in this case, a query would be: “get the score that user A gives user B on assignment 999 on round 2”). The query can also ask to print the average of all the scores in round 1 and round2, this average will be retrieved from localdbscores and printed.&lt;br /&gt;
&lt;br /&gt;
This method handles the calculation of reputations for each reviewer in the case of a finished assignment. (all the reputations are calculated and stored since they are finalized).&lt;br /&gt;
&lt;br /&gt;
=== Database ===&lt;br /&gt;
To store the holistic scores when an assignment is completed, a database localdbscores needs to be created. The value from this db is retrieved and displayed when the scores of a completed assignment needs to be viewed. The database Design is shown below.&lt;br /&gt;
&lt;br /&gt;
== Database Design ==&lt;br /&gt;
A table localdbscores will be created as:&lt;br /&gt;
&lt;br /&gt;
class CreateLocalDB&amp;lt;ActiveRecord::Migration&lt;br /&gt;
&lt;br /&gt;
def self.up&lt;br /&gt;
&lt;br /&gt;
create_table :localdb_scores do |t|&lt;br /&gt;
&lt;br /&gt;
t.column :id, :integer&lt;br /&gt;
&lt;br /&gt;
t.column :score, :integer&lt;br /&gt;
&lt;br /&gt;
t.column :round, :integer&lt;br /&gt;
&lt;br /&gt;
t.column :type, :string&lt;br /&gt;
&lt;br /&gt;
t.column :reference_id, :integer&lt;br /&gt;
&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
with id, score, round, type, reference_id as its attributes as shown in the table below&lt;br /&gt;
&lt;br /&gt;
&amp;quot;localdbscores&amp;quot; will have the following scores&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|&lt;br /&gt;
|t.integer    &amp;quot;id&amp;quot;,         limit: 24&lt;br /&gt;
|id&lt;br /&gt;
|Primary Key, Auto generated&lt;br /&gt;
|-&lt;br /&gt;
|&lt;br /&gt;
|t.string    &amp;quot;Type&amp;quot;,      limit: 255&lt;br /&gt;
|Type&lt;br /&gt;
|Type of score: either final or intermediate&lt;br /&gt;
|-&lt;br /&gt;
|&lt;br /&gt;
|t.integer    &amp;quot;Score&amp;quot;,  limit: 24&lt;br /&gt;
|Score&lt;br /&gt;
|Total score calculated based on each response to each criterion&lt;br /&gt;
|-&lt;br /&gt;
|&lt;br /&gt;
|t.integer   &amp;quot;Round&amp;quot;,  limit:24&lt;br /&gt;
|Round&lt;br /&gt;
|The completed round number&lt;br /&gt;
|-&lt;br /&gt;
|&lt;br /&gt;
|t.integer  &amp;quot;Reference_id&amp;quot; , limit:45&lt;br /&gt;
|Reference_id&lt;br /&gt;
|Acts as the foreign Key&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Implementation ==&lt;br /&gt;
&lt;br /&gt;
=== Assignment.rb ===&lt;br /&gt;
A new function get_last_review_date is added which takes assignid as a parameter and returns the last review deadline of the assignment. The deadline obtained from AssignmentDueDate for the corresponding assignid is stored in last_review_deadline and is returned.&lt;br /&gt;
&lt;br /&gt;
=== Parent Class:ScoreCal ===&lt;br /&gt;
ScoreCal stores the score calculated by its sub classes: on_the_fly_cal and LocalDbcal to the database. In the database, a new table localdbscore is created with the schema as explained in section 2.2. Depending upon the deadline_type, object of either on_the_fly_cal or LocalDbcal is created and the appropriate functions within the classes are called.&lt;br /&gt;
&lt;br /&gt;
=== Sub class 1: on_the_fly_cal ===&lt;br /&gt;
This is a subclass of class Scorecal contains a method calc_score whose functionality is to compute the holistic score. An object of on_the_fly_cal is called when the current time has not yet surpassed the time stored in last_review_deadline variable which contains the review duedate indicating that the assignment is still ongoing and has not been completed. The individual scores are retrieved from the database ScoreView and is stored in QuestionnaireData from which the holistic score of a student is calculated .&lt;br /&gt;
&lt;br /&gt;
When the user accesses the scores for a review, the current implementation does not store a holistic score but rather calculates the holistic score from the score for every individual criterion. To calculate the total holistic score for a specific round, the individual scores are weighted and added.&lt;br /&gt;
&lt;br /&gt;
This functionality is achieved by on_the_fly_calc.&lt;br /&gt;
&lt;br /&gt;
A snapshot of the system before implementing the changes is shown below.&lt;br /&gt;
&lt;br /&gt;
=== Sub class 2: LocalDbcal ===&lt;br /&gt;
This is a subclass of Scorecal and contains a function calc_score in class localDbcal. An object of LocalDbcal is called when the current time has surpassed the time stored in last_review_deadline variable which contains the review due date indicating that the assignment has been completed. This subclass retrieves the score from the database localDbscores for a corresponding student. If the score is not found in the database localDbscores, the function calc_score of on_the_fly_cal class is called to calculate the total from the weighted scores of each question. This calculated score is then inserted into the database.&lt;br /&gt;
&lt;br /&gt;
This score is now returned to the view from where it was called.&lt;br /&gt;
&lt;br /&gt;
=== _review_table.html.erb ===&lt;br /&gt;
The current implementation of this was to calculate the score and display it which as we know is a time consuming process. It has been changed to check if the current time has crossed the last_review_deadline obtained in assignments.rb and call the corresponding class as required.&lt;br /&gt;
&lt;br /&gt;
If the current date has surpassed the last_review_deadline, it is an indication that the due date has passed and the class localDbcal is called to retrieve a value from the database as mentioned above. On the other hand, on_the_fly_cal is called when the current date has not surpassed the last_review_deadline, indicating that the assignment is ongoing and the holistic score is calculated and passed to the view.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Design Pattern ==&lt;br /&gt;
The ScoreCal superclass has 2 subclasses: OnTheFlyCal and LocalDbCal. ScoreCal acts as an interface to obtain the scores, either from OnTheFlyCal or LocalDbCal depending on the last_review_deadline obtained from the get_last_review_date() in the assignment model. This pattern is similar to strategy pattern where the client is the _review_tble.html.erb, interface is the superclass and the subclasses are called accordingly.&lt;br /&gt;
[[File:UseCaseDiagram2.png]]&lt;br /&gt;
&lt;br /&gt;
== Implementation ==&lt;br /&gt;
&lt;br /&gt;
=== Parent Class:ScoreCalc ===&lt;br /&gt;
ScoreCalc stores the score calculated by its sub classes: on_the_fly_calc and LocalDBcalc to the database. In the database, a new table local_db_scoresn is created with the schema as explained in section 2.2. Depending upon the deadline_type, object of either on_the_fly_calc or LocalDBcalc is created and the appropriate functions within the classes are called. &lt;br /&gt;
&lt;br /&gt;
==== Database design ====&lt;br /&gt;
A table local_db_scores will be created as:&lt;br /&gt;
&lt;br /&gt;
create_table &amp;quot;local_db_scores&amp;quot;,force::cascade do|t|&lt;br /&gt;
&lt;br /&gt;
&amp;quot;local_db_scores&amp;quot; will have the following scores &lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|&lt;br /&gt;
|t.integer    &amp;quot;id&amp;quot;,         limit: 24&lt;br /&gt;
|id&lt;br /&gt;
|Primary Key, Auto generated&lt;br /&gt;
|-&lt;br /&gt;
|&lt;br /&gt;
|t.string    &amp;quot;Type&amp;quot;,      limit: 255&lt;br /&gt;
|Type&lt;br /&gt;
|Type of score: either final or intermediate&lt;br /&gt;
|-&lt;br /&gt;
|&lt;br /&gt;
|t.integer    &amp;quot;Score&amp;quot;,  limit: 24&lt;br /&gt;
|Score&lt;br /&gt;
|Total score calculated based on each response to each criterion&lt;br /&gt;
|-&lt;br /&gt;
|&lt;br /&gt;
|t.integer   &amp;quot;Round&amp;quot;,  limit:24&lt;br /&gt;
|Round&lt;br /&gt;
|The completed round number&lt;br /&gt;
|-&lt;br /&gt;
|&lt;br /&gt;
|t.integer  &amp;quot;Reference_id&amp;quot; , limit:45&lt;br /&gt;
|Reference_id&lt;br /&gt;
|Acts as the foreign Key&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Sub class 1: on_the_fly_calc ===&lt;br /&gt;
An object of on_the_fly_calc is called when the deadline_type is not &amp;quot;review of review&amp;quot; which means that the assignment is ongoing and has not been completed and stores the scores till the current stage that will change once the assignment passes the deadline&lt;br /&gt;
&lt;br /&gt;
The function compute_total_scores(scores) is used to calculate the total score based on each response to each criterion. The function is as below:&lt;br /&gt;
&lt;br /&gt;
def compute_total_scores(scores) &lt;br /&gt;
&lt;br /&gt;
total=0&lt;br /&gt;
&lt;br /&gt;
self.questionnaires.each{|questionnaire| total+=questionnaire.get_weighted_score(self,scores)}&lt;br /&gt;
&lt;br /&gt;
total &lt;br /&gt;
&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
The value in variable &amp;quot;total&amp;quot; needs to be stored in local_db_scores under &amp;quot;Score&amp;quot; and will be retrieved by using another function retrieve_total_score to display the total score instead of calculating it every time a user wants to view the scores.&lt;br /&gt;
&lt;br /&gt;
When the user accesses the scores for a review, the current implementation does not store a holistic score but rather calculates the holistic score from the score for every individual criterion. To calculate the total holistic score for a specific round, the individual scores are weighted and added. &lt;br /&gt;
&lt;br /&gt;
This functionality is achieved by on_the_fly_calc.&lt;br /&gt;
&lt;br /&gt;
The current system calculates the holistic score every single time from the individual criterion. A snapshot of the system before implementing the changes is shown below.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[File:rsz_flycur.png]]&lt;br /&gt;
&lt;br /&gt;
The proposed implementation involves computing the holistic score once and storing it in the local_db_scores database for a particular user and for a specified round. The stored value is accessed and obtained instead of computing the holistic score every single time.&lt;br /&gt;
&lt;br /&gt;
[[File:rsz_flyadb.png]]&lt;br /&gt;
&lt;br /&gt;
=== Sub class 2: LocalDB_calc ===&lt;br /&gt;
An object of LocalDB_calc is called when the deadline_type is &amp;quot;review of review&amp;quot; which means that the assignment is completed and stores the final score in the database local_db_scores after computing it rather than computing it every time the score is required.&lt;br /&gt;
&lt;br /&gt;
Function compute_total_scores(scores) is added to the class which calculates the total score based on each response to each criterion. The function(polymorphism) is as below:&lt;br /&gt;
&lt;br /&gt;
def compute_total_scores(scores) &lt;br /&gt;
&lt;br /&gt;
total=0&lt;br /&gt;
&lt;br /&gt;
self.questionnaires.each{|questionnaire| total+=questionnaire.get_weighted_score(self,scores)}&lt;br /&gt;
&lt;br /&gt;
total &lt;br /&gt;
&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
The value in variable &amp;quot;total&amp;quot; needs to be stored in local_db_scores under &amp;quot;Score&amp;quot; and will be retrieved by using another function retrieve_total_score to display the total score instead of calculating it every time a user wants to view the scores.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The snapshots prior to and post implementation are shown below :&lt;br /&gt;
&lt;br /&gt;
[[File:rsz_loccur.png]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The proposed implementation retrieves the round wise scores from the local_db_scores database and displays the average score once the deadline has passed rather than computing the average of the weighted scores for every access of the page as shown below.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[File:rsz_locadb.png]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The Dataflow diagram (DFD) for the proposed system is shown below.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[File:Flowchart12.png|center|frame|flowchart]]&lt;br /&gt;
&lt;br /&gt;
== Testing ==&lt;br /&gt;
The testing for model: on_the_fly_calc is carried out by questionnaire_spec.rb in the spec folder. The minimum and maximum score that an user gives for each criterion is checked.&lt;br /&gt;
&lt;br /&gt;
Two more test cases to check whether the average score of each review falls within a given range:(0,100) will be added.&lt;br /&gt;
&lt;br /&gt;
For LocalDB_calc, the average calculated across round 1 and round 2 will be checked to fall within 0 to 100. These test cases will be added to questionnaire_spec.rb.&lt;/div&gt;</summary>
		<author><name>Nthanik</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2016_E1682:_Improve_score_calculation&amp;diff=106524</id>
		<title>CSC/ECE 517 Fall 2016 E1682: Improve score calculation</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2016_E1682:_Improve_score_calculation&amp;diff=106524"/>
		<updated>2016-12-05T04:20:14Z</updated>

		<summary type="html">&lt;p&gt;Nthanik: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;E1682. Improve score calculation&lt;br /&gt;
&lt;br /&gt;
== Introduction ==&lt;br /&gt;
&lt;br /&gt;
=== Expertiza ===&lt;br /&gt;
Expertiza is an open source project for school assignment management for instructors and students based on the Ruby on Rails framework. Expertiza allows the instructor to create new assignments and customize new or existing assignments. It also allows the instructor to create a list of topics the students can sign up for. Students can form teams in Expertiza to work on various projects and assignments. Students can also peer review other students' submissions. Expertiza supports submission across various document types, including the URLs and word documents. Expertiza provides a dashboard for all the assignments corresponding to a course and provides absolute control to the Instructors and Teaching Assistants. In addition to assignments, it encompasses peer reviews wherein participants are allowed to provide feedback anonymously about each other's work thereby providing scope for the better outcome. The due_date.rb file is responsible for informing the users about the deadline for submission of the each assignment. Due dates in Expertiza have their association with many other components like assignments, reviews etc.&lt;br /&gt;
&lt;br /&gt;
=== Purpose ===&lt;br /&gt;
The purpose of the project is to improve the functionality of score calculation. The scores in expertiza were calculated by taking the sum of weighted scores to calculate the total every time it is called. This takes considerable amount of time as there is a calculation involved each time. The methodology behind score calculation in expertiza can be significantly improved. The design behind calculating and storing scores can be tweaked to offer significant performance improvements. To achieve this, it is ideal to store overall holistic stores in addition to individual criterion scores.&lt;br /&gt;
&lt;br /&gt;
=== Problem Statement ===&lt;br /&gt;
The current drawback of the expertiza system lies in how the scores are stored: Expertiza stores the scores based on each response to each criterion, but no holistic scores are stored. As a result of this mechanism, the process slows down. This means that if we need to know what score user A gives to user B based on 100, we have to rely on the code to calculate it (since in answers table we only have the score that A gives B on each criterion).&lt;br /&gt;
&lt;br /&gt;
To overcome this bottleneck, two additional mechanisms can be included for handling the holistic scores.&lt;br /&gt;
&lt;br /&gt;
== Overall Description ==&lt;br /&gt;
Expertiza currently calculates scores dynamically when a page is called by taking the weighted scores of each question into consideration. This calculation is a time consuming process with a considerable overhead that significantly affects the performance. To solve the issue we propose a solution to store the holistic scores in a database, retrieving it every time it is required. This reduces the calculation that is required every time the score is called. When the user wants to check the scores of a completed assignment, a method localDB_calc is called and expertiza retrieves the scores of the student from the database rather than calculating the total from weighted scores. But, when the scores of an ongoing assignment is required, a method on_the_fly_calc is called that calculates the current score of the user. To determine which method will be invoked(on_the_fly_calc and localDB_calc), the current system time will be compared with last_review_deadline   &lt;br /&gt;
* If system time is greater than last_review_deadline, indicating that the deadline has passed, the method localDbcal will retrieve the holistic score from the database   &lt;br /&gt;
* If system time is lesser than last_review_deadline, indicating that the deadline has not passed, the method on_the_fly_cal will calculate the holistic score and display it.   &lt;br /&gt;
&lt;br /&gt;
== *FLOW CHART ==&lt;br /&gt;
&lt;br /&gt;
== Tasks Identified ==&lt;br /&gt;
The two suggested mechanisms for handling the storage and calculation of holistic scores for peer-reviews, as specified in the requirements document are :&lt;br /&gt;
* on_the_fly_calc&lt;br /&gt;
* localDB_calc&lt;br /&gt;
&lt;br /&gt;
=== on_the_fly_calc ===&lt;br /&gt;
When the assignment is still ongoing , this method is called and it calculates holistic scores over a set of data (in this case, a set of record in answers table, namely the responses from user A to user B on each criterion) and store it in localdbscores. This stored score is retrieved and printed when the user A clicks on the &amp;quot;Your scores&amp;quot; link.&lt;br /&gt;
&lt;br /&gt;
In the current implementation, when a user A wants to view the score given by user B, user A's score(i.e. out of 100) will be calculated everytime using the scores given by user B for each criterion (i.e.. score out of 5).&lt;br /&gt;
&lt;br /&gt;
Handles the calculation of reputations for each reviewer in the case of an ongoing assignment.&lt;br /&gt;
&lt;br /&gt;
=== localDB_calc ===&lt;br /&gt;
Once the deadline for an assignment is completed, the method localDB_calc calculates the holistic score over a single db query (in this case, a query would be: “get the score that user A gives user B on assignment 999 on round 2”). The query can also ask to print the average of all the scores in round 1 and round2, this average will be retrieved from localdbscores and printed.&lt;br /&gt;
&lt;br /&gt;
This method handles the calculation of reputations for each reviewer in the case of a finished assignment. (all the reputations are calculated and stored since they are finalized).&lt;br /&gt;
&lt;br /&gt;
=== Database ===&lt;br /&gt;
To store the holistic scores when an assignment is completed, a database localdbscores needs to be created. The value from this db is retrieved and displayed when the scores of a completed assignment needs to be viewed. The database Design is shown below.&lt;br /&gt;
&lt;br /&gt;
== Database Design ==&lt;br /&gt;
A table localdbscores will be created as:&lt;br /&gt;
&lt;br /&gt;
class CreateLocalDB&amp;lt;ActiveRecord::Migration&lt;br /&gt;
&lt;br /&gt;
def self.up&lt;br /&gt;
&lt;br /&gt;
create_table :localdb_scores do |t|&lt;br /&gt;
&lt;br /&gt;
t.column :id, :integer&lt;br /&gt;
&lt;br /&gt;
t.column :score, :integer&lt;br /&gt;
&lt;br /&gt;
t.column :round, :integer&lt;br /&gt;
&lt;br /&gt;
t.column :type, :string&lt;br /&gt;
&lt;br /&gt;
t.column :reference_id, :integer&lt;br /&gt;
&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
with id, score, round, type, reference_id as its attributes as shown in the table below&lt;br /&gt;
&lt;br /&gt;
&amp;quot;localdbscores&amp;quot; will have the following scores&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|&lt;br /&gt;
|t.integer    &amp;quot;id&amp;quot;,         limit: 24&lt;br /&gt;
|id&lt;br /&gt;
|Primary Key, Auto generated&lt;br /&gt;
|-&lt;br /&gt;
|&lt;br /&gt;
|t.string    &amp;quot;Type&amp;quot;,      limit: 255&lt;br /&gt;
|Type&lt;br /&gt;
|Type of score: either final or intermediate&lt;br /&gt;
|-&lt;br /&gt;
|&lt;br /&gt;
|t.integer    &amp;quot;Score&amp;quot;,  limit: 24&lt;br /&gt;
|Score&lt;br /&gt;
|Total score calculated based on each response to each criterion&lt;br /&gt;
|-&lt;br /&gt;
|&lt;br /&gt;
|t.integer   &amp;quot;Round&amp;quot;,  limit:24&lt;br /&gt;
|Round&lt;br /&gt;
|The completed round number&lt;br /&gt;
|-&lt;br /&gt;
|&lt;br /&gt;
|t.integer  &amp;quot;Reference_id&amp;quot; , limit:45&lt;br /&gt;
|Reference_id&lt;br /&gt;
|Acts as the foreign Key&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Implementation ==&lt;br /&gt;
&lt;br /&gt;
=== Assignment.rb ===&lt;br /&gt;
A new function get_last_review_date is added which takes assignid as a parameter and returns the last review deadline of the assignment. The deadline obtained from AssignmentDueDate for the corresponding assignid is stored in last_review_deadline and is returned.&lt;br /&gt;
&lt;br /&gt;
=== Parent Class:ScoreCal ===&lt;br /&gt;
ScoreCal stores the score calculated by its sub classes: on_the_fly_cal and LocalDbcal to the database. In the database, a new table localdbscore is created with the schema as explained in section 2.2. Depending upon the deadline_type, object of either on_the_fly_cal or LocalDbcal is created and the appropriate functions within the classes are called.&lt;br /&gt;
&lt;br /&gt;
=== Sub class 1: on_the_fly_cal ===&lt;br /&gt;
This is a subclass of class Scorecal contains a method calc_score whose functionality is to compute the holistic score. An object of on_the_fly_cal is called when the current time has not yet surpassed the time stored in last_review_deadline variable which contains the review duedate indicating that the assignment is still ongoing and has not been completed. The individual scores are retrieved from the database ScoreView and is stored in QuestionnaireData from which the holistic score of a student is calculated .&lt;br /&gt;
&lt;br /&gt;
When the user accesses the scores for a review, the current implementation does not store a holistic score but rather calculates the holistic score from the score for every individual criterion. To calculate the total holistic score for a specific round, the individual scores are weighted and added.&lt;br /&gt;
&lt;br /&gt;
This functionality is achieved by on_the_fly_calc.&lt;br /&gt;
&lt;br /&gt;
A snapshot of the system before implementing the changes is shown below.&lt;br /&gt;
&lt;br /&gt;
=== Sub class 2: LocalDbcal ===&lt;br /&gt;
This is a subclass of Scorecal and contains a function calc_score in class localDbcal. An object of LocalDbcal is called when the current time has surpassed the time stored in last_review_deadline variable which contains the review due date indicating that the assignment has been completed. This subclass retrieves the score from the database localDbscores for a corresponding student. If the score is not found in the database localDbscores, the function calc_score of on_the_fly_cal class is called to calculate the total from the weighted scores of each question. This calculated score is then inserted into the database.&lt;br /&gt;
&lt;br /&gt;
This score is now returned to the view from where it was called.&lt;br /&gt;
&lt;br /&gt;
=== _review_table.html.erb ===&lt;br /&gt;
The current implementation of this was to calculate the score and display it which as we know is a time consuming process. It has been changed to check if the current time has crossed the last_review_deadline obtained in assignments.rb and call the corresponding class as required.&lt;br /&gt;
&lt;br /&gt;
If the current date has surpassed the last_review_deadline, it is an indication that the due date has passed and the class localDbcal is called to retrieve a value from the database as mentioned above. On the other hand, on_the_fly_cal is called when the current date has not surpassed the last_review_deadline, indicating that the assignment is ongoing and the holistic score is calculated and passed to the view.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Introduction ==&lt;br /&gt;
&lt;br /&gt;
=== Purpose ===&lt;br /&gt;
The methodology behind score calculation in expertiza can be significantly improved. The design behind calculating and storing scores can be tweaked to offer significant performance improvements. To achieve this, it is ideal to store overall holistic stores in addition to individual criterion scores. &lt;br /&gt;
&lt;br /&gt;
=== Problem Statement ===&lt;br /&gt;
The current drawback of the expertiza system lies in  how the scores are stored: Expertiza stores the scores based on each response to each criterion, but no holistic scores are stored. As a result of this mechanism, the process slows down. This means that if we need to know what score user A gives to user B based on 100, we have to rely on the code to calculate it (since in answers table we only have the score that A gives B on each criterion).&lt;br /&gt;
&lt;br /&gt;
To overcome this bottleneck, two additional mechanisms can be included for handling the holistic scores.&lt;br /&gt;
&lt;br /&gt;
== Proposed changes ==&lt;br /&gt;
The two suggested mechanisms for handling the storage and calculation of holistic scores for peer-reviews, as specified in the requirements document are :&lt;br /&gt;
* on_the_fly_calc&lt;br /&gt;
* localDB_calc&lt;br /&gt;
&lt;br /&gt;
=== on_the_fly_calc ===&lt;br /&gt;
Calculate holistic scores over a set of data (in this case, a set of record in answers table, namely the responses from user A to user B on each criterion) and store it in local_db_scores. This stored score is retrieved and printed when the user A clicks on the &amp;quot;Your scores&amp;quot; link.&lt;br /&gt;
&lt;br /&gt;
In the current implementation, when a user A wants to view the score given by user B, user A's score(i.e. out of 100) will be calculated everytime using the scores given by user B for each criterion (i.e.. score out of 5).&lt;br /&gt;
&lt;br /&gt;
Handles the calculation of reputations for each reviewer in the case of an ongoing assignment.&lt;br /&gt;
&lt;br /&gt;
=== localDB_calc ===&lt;br /&gt;
Calculate the holistic score over a single db query (in this case, a query would be: “get the score that user A gives user B on assignment 999 on round 2”). The query can also ask to print the average of all the scores in round 1 and round2, this average will be retrieved from local_db_scores and printed.&lt;br /&gt;
&lt;br /&gt;
Handles the calculation of reputations for each reviewer in the case of a finished assignment. (all the reputations are calculated and stored since they are finalized).&lt;br /&gt;
&lt;br /&gt;
== Design Pattern ==&lt;br /&gt;
The ScoreCal superclass has 2 subclasses: OnTheFlyCal and LocalDbCal. ScoreCal acts as an interface to obtain the scores, either from OnTheFlyCal or LocalDbCal depending on the last_review_deadline obtained from the get_last_review_date() in the assignment model. This pattern is similar to strategy pattern where the client is the _review_tble.html.erb, interface is the superclass and the subclasses are called accordingly.&lt;br /&gt;
[[File:UseCaseDiagram2.png]]&lt;br /&gt;
&lt;br /&gt;
== Implementation ==&lt;br /&gt;
&lt;br /&gt;
=== Parent Class:ScoreCalc ===&lt;br /&gt;
ScoreCalc stores the score calculated by its sub classes: on_the_fly_calc and LocalDBcalc to the database. In the database, a new table local_db_scoresn is created with the schema as explained in section 2.2. Depending upon the deadline_type, object of either on_the_fly_calc or LocalDBcalc is created and the appropriate functions within the classes are called. &lt;br /&gt;
&lt;br /&gt;
==== Database design ====&lt;br /&gt;
A table local_db_scores will be created as:&lt;br /&gt;
&lt;br /&gt;
create_table &amp;quot;local_db_scores&amp;quot;,force::cascade do|t|&lt;br /&gt;
&lt;br /&gt;
&amp;quot;local_db_scores&amp;quot; will have the following scores &lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|&lt;br /&gt;
|t.integer    &amp;quot;id&amp;quot;,         limit: 24&lt;br /&gt;
|id&lt;br /&gt;
|Primary Key, Auto generated&lt;br /&gt;
|-&lt;br /&gt;
|&lt;br /&gt;
|t.string    &amp;quot;Type&amp;quot;,      limit: 255&lt;br /&gt;
|Type&lt;br /&gt;
|Type of score: either final or intermediate&lt;br /&gt;
|-&lt;br /&gt;
|&lt;br /&gt;
|t.integer    &amp;quot;Score&amp;quot;,  limit: 24&lt;br /&gt;
|Score&lt;br /&gt;
|Total score calculated based on each response to each criterion&lt;br /&gt;
|-&lt;br /&gt;
|&lt;br /&gt;
|t.integer   &amp;quot;Round&amp;quot;,  limit:24&lt;br /&gt;
|Round&lt;br /&gt;
|The completed round number&lt;br /&gt;
|-&lt;br /&gt;
|&lt;br /&gt;
|t.integer  &amp;quot;Reference_id&amp;quot; , limit:45&lt;br /&gt;
|Reference_id&lt;br /&gt;
|Acts as the foreign Key&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Sub class 1: on_the_fly_calc ===&lt;br /&gt;
An object of on_the_fly_calc is called when the deadline_type is not &amp;quot;review of review&amp;quot; which means that the assignment is ongoing and has not been completed and stores the scores till the current stage that will change once the assignment passes the deadline&lt;br /&gt;
&lt;br /&gt;
The function compute_total_scores(scores) is used to calculate the total score based on each response to each criterion. The function is as below:&lt;br /&gt;
&lt;br /&gt;
def compute_total_scores(scores) &lt;br /&gt;
&lt;br /&gt;
total=0&lt;br /&gt;
&lt;br /&gt;
self.questionnaires.each{|questionnaire| total+=questionnaire.get_weighted_score(self,scores)}&lt;br /&gt;
&lt;br /&gt;
total &lt;br /&gt;
&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
The value in variable &amp;quot;total&amp;quot; needs to be stored in local_db_scores under &amp;quot;Score&amp;quot; and will be retrieved by using another function retrieve_total_score to display the total score instead of calculating it every time a user wants to view the scores.&lt;br /&gt;
&lt;br /&gt;
When the user accesses the scores for a review, the current implementation does not store a holistic score but rather calculates the holistic score from the score for every individual criterion. To calculate the total holistic score for a specific round, the individual scores are weighted and added. &lt;br /&gt;
&lt;br /&gt;
This functionality is achieved by on_the_fly_calc.&lt;br /&gt;
&lt;br /&gt;
The current system calculates the holistic score every single time from the individual criterion. A snapshot of the system before implementing the changes is shown below.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[File:rsz_flycur.png]]&lt;br /&gt;
&lt;br /&gt;
The proposed implementation involves computing the holistic score once and storing it in the local_db_scores database for a particular user and for a specified round. The stored value is accessed and obtained instead of computing the holistic score every single time.&lt;br /&gt;
&lt;br /&gt;
[[File:rsz_flyadb.png]]&lt;br /&gt;
&lt;br /&gt;
=== Sub class 2: LocalDB_calc ===&lt;br /&gt;
An object of LocalDB_calc is called when the deadline_type is &amp;quot;review of review&amp;quot; which means that the assignment is completed and stores the final score in the database local_db_scores after computing it rather than computing it every time the score is required.&lt;br /&gt;
&lt;br /&gt;
Function compute_total_scores(scores) is added to the class which calculates the total score based on each response to each criterion. The function(polymorphism) is as below:&lt;br /&gt;
&lt;br /&gt;
def compute_total_scores(scores) &lt;br /&gt;
&lt;br /&gt;
total=0&lt;br /&gt;
&lt;br /&gt;
self.questionnaires.each{|questionnaire| total+=questionnaire.get_weighted_score(self,scores)}&lt;br /&gt;
&lt;br /&gt;
total &lt;br /&gt;
&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
The value in variable &amp;quot;total&amp;quot; needs to be stored in local_db_scores under &amp;quot;Score&amp;quot; and will be retrieved by using another function retrieve_total_score to display the total score instead of calculating it every time a user wants to view the scores.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The snapshots prior to and post implementation are shown below :&lt;br /&gt;
&lt;br /&gt;
[[File:rsz_loccur.png]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The proposed implementation retrieves the round wise scores from the local_db_scores database and displays the average score once the deadline has passed rather than computing the average of the weighted scores for every access of the page as shown below.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[File:rsz_locadb.png]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The Dataflow diagram (DFD) for the proposed system is shown below.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[File:Flowchart12.png|center|frame|flowchart]]&lt;br /&gt;
&lt;br /&gt;
== Testing ==&lt;br /&gt;
The testing for model: on_the_fly_calc is carried out by questionnaire_spec.rb in the spec folder. The minimum and maximum score that an user gives for each criterion is checked.&lt;br /&gt;
&lt;br /&gt;
Two more test cases to check whether the average score of each review falls within a given range:(0,100) will be added.&lt;br /&gt;
&lt;br /&gt;
For LocalDB_calc, the average calculated across round 1 and round 2 will be checked to fall within 0 to 100. These test cases will be added to questionnaire_spec.rb.&lt;/div&gt;</summary>
		<author><name>Nthanik</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2016_E1682:_Improve_score_calculation&amp;diff=105773</id>
		<title>CSC/ECE 517 Fall 2016 E1682: Improve score calculation</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2016_E1682:_Improve_score_calculation&amp;diff=105773"/>
		<updated>2016-11-15T01:06:32Z</updated>

		<summary type="html">&lt;p&gt;Nthanik: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;E1682. Improve score calculation&lt;br /&gt;
&lt;br /&gt;
== Introduction ==&lt;br /&gt;
&lt;br /&gt;
=== Purpose ===&lt;br /&gt;
The methodology behind score calculation in expertiza can be significantly improved. The design behind calculating and storing scores can be tweaked to offer significant performance improvements. To achieve this, it is ideal to store overall holistic stores in addition to individual criterion scores. &lt;br /&gt;
&lt;br /&gt;
=== Problem Statement ===&lt;br /&gt;
The current drawback of the expertiza system lies in  how the scores are stored: Expertiza stores the scores based on each response to each criterion, but no holistic scores are stored. As a result of this mechanism, the process slows down. This means that if we need to know what score user A gives to user B based on 100, we have to rely on the code to calculate it (since in answers table we only have the score that A gives B on each criterion).&lt;br /&gt;
&lt;br /&gt;
To overcome this bottleneck, two additional mechanisms can be included for handling the holistic scores.&lt;br /&gt;
&lt;br /&gt;
== Proposed changes ==&lt;br /&gt;
The two suggested mechanisms for handling the storage and calculation of holistic scores for peer-reviews, as specified in the requirements document are :&lt;br /&gt;
* on_the_fly_calc&lt;br /&gt;
* localDB_calc&lt;br /&gt;
&lt;br /&gt;
=== on_the_fly_calc ===&lt;br /&gt;
Calculate holistic scores over a set of data (in this case, a set of record in answers table, namely the responses from user A to user B on each criterion) and store it in local_db_scores. This stored score is retrieved and printed when the user A clicks on the &amp;quot;Your scores&amp;quot; link.&lt;br /&gt;
&lt;br /&gt;
In the current implementation, when a user A wants to view the score given by user B, user A's score(i.e. out of 100) will be calculated everytime using the scores given by user B for each criterion (i.e.. score out of 5).&lt;br /&gt;
&lt;br /&gt;
Handles the calculation of reputations for each reviewer in the case of an ongoing assignment.&lt;br /&gt;
&lt;br /&gt;
=== localDB_calc ===&lt;br /&gt;
Calculate the holistic score over a single db query (in this case, a query would be: “get the score that user A gives user B on assignment 999 on round 2”). The query can also ask to print the average of all the scores in round 1 and round2, this average will be retrieved from local_db_scores and printed.&lt;br /&gt;
&lt;br /&gt;
Handles the calculation of reputations for each reviewer in the case of a finished assignment. (all the reputations are calculated and stored since they are finalized).&lt;br /&gt;
&lt;br /&gt;
=== Observer Pattern ===&lt;br /&gt;
Observer pattern will be used where the dependent:local_db_score will be updated when the deadline_type is changed. If the dead_line_type is anything other than &amp;quot;review of review&amp;quot;, the weighted scores for each review will be calculated and scored in local_db_scores. If the deadline_type is &amp;quot;review of review&amp;quot;, then the average of the weighted score for each round across users will be calculated and stored in local_db_score.&lt;br /&gt;
&lt;br /&gt;
== Implementation ==&lt;br /&gt;
&lt;br /&gt;
=== Parent Class:ScoreCalc ===&lt;br /&gt;
ScoreCalc stores the score calculated by its sub classes: on_the_fly_calc and LocalDBcalc to the database. In the database, a new table local_db_scoresn is created with the schema as explained in section 2.2. Depending upon the deadline_type, object of either on_the_fly_calc or LocalDBcalc is created and the appropriate functions within the classes are called. &lt;br /&gt;
&lt;br /&gt;
==== Database design ====&lt;br /&gt;
A table local_db_scores will be created as:&lt;br /&gt;
&lt;br /&gt;
create_table &amp;quot;local_db_scores&amp;quot;,force::cascade do|t|&lt;br /&gt;
&lt;br /&gt;
&amp;quot;local_db_scores&amp;quot; will have the following scores &lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|&lt;br /&gt;
|t.integer    &amp;quot;id&amp;quot;,         limit: 24&lt;br /&gt;
|id&lt;br /&gt;
|Primary Key, Auto generated&lt;br /&gt;
|-&lt;br /&gt;
|&lt;br /&gt;
|t.string    &amp;quot;Type&amp;quot;,      limit: 255&lt;br /&gt;
|Type&lt;br /&gt;
|Type of score: either final or intermediate&lt;br /&gt;
|-&lt;br /&gt;
|&lt;br /&gt;
|t.integer    &amp;quot;Score&amp;quot;,  limit: 24&lt;br /&gt;
|Score&lt;br /&gt;
|Total score calculated based on each response to each criterion&lt;br /&gt;
|-&lt;br /&gt;
|&lt;br /&gt;
|t.integer   &amp;quot;Round&amp;quot;,  limit:24&lt;br /&gt;
|Round&lt;br /&gt;
|The completed round number&lt;br /&gt;
|-&lt;br /&gt;
|&lt;br /&gt;
|t.integer  &amp;quot;Reference_id&amp;quot; , limit:45&lt;br /&gt;
|Reference_id&lt;br /&gt;
|Acts as the foreign Key&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Sub class 1: on_the_fly_calc ===&lt;br /&gt;
An object of on_the_fly_calc is called when the deadline_type is not &amp;quot;review of review&amp;quot; which means that the assignment is ongoing and has not been completed and stores the scores till the current stage that will change once the assignment passes the deadline&lt;br /&gt;
&lt;br /&gt;
The function compute_total_scores(scores) is used to calculate the total score based on each response to each criterion. The function is as below:&lt;br /&gt;
&lt;br /&gt;
def compute_total_scores(scores) &lt;br /&gt;
&lt;br /&gt;
total=0&lt;br /&gt;
&lt;br /&gt;
self.questionnaires.each{|questionnaire| total+=questionnaire.get_weighted_score(self,scores)}&lt;br /&gt;
&lt;br /&gt;
total &lt;br /&gt;
&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
The value in variable &amp;quot;total&amp;quot; needs to be stored in local_db_scores under &amp;quot;Score&amp;quot; and will be retrieved by using another function retrieve_total_score to display the total score instead of calculating it every time a user wants to view the scores.&lt;br /&gt;
&lt;br /&gt;
When the user accesses the scores for a review, the current implementation does not store a holistic score but rather calculates the holistic score from the score for every individual criterion. To calculate the total holistic score for a specific round, the individual scores are weighted and added. &lt;br /&gt;
&lt;br /&gt;
This functionality is achieved by on_the_fly_calc.&lt;br /&gt;
&lt;br /&gt;
The current system calculates the holistic score every single time from the individual criterion. A snapshot of the system before implementing the changes is shown below.&lt;br /&gt;
&lt;br /&gt;
The proposed implementation involves computing the holistic score once and storing it in the local_db_scores database for a particular user and for a specified round. The stored value is accessed and obtained instead of computing the holistic score every single time.&lt;br /&gt;
[[File:FlyADB.png|thumb|Proposed Implementation ]]&lt;br /&gt;
[[File:FlyCur.png|thumb|Current implementation]]&lt;br /&gt;
&lt;br /&gt;
=== Sub class 2: LocalDB_calc ===&lt;br /&gt;
An object of LocalDB_calc is called when the deadline_type is &amp;quot;review of review&amp;quot; which means that the assignment is completed and stores the final score in the database local_db_scores after computing it rather than computing it every time the score is required.&lt;br /&gt;
&lt;br /&gt;
Function compute_total_scores(scores) is added to the class which calculates the total score based on each response to each criterion. The function(polymorphism) is as below:&lt;br /&gt;
&lt;br /&gt;
def compute_total_scores(scores) &lt;br /&gt;
&lt;br /&gt;
total=0&lt;br /&gt;
&lt;br /&gt;
self.questionnaires.each{|questionnaire| total+=questionnaire.get_weighted_score(self,scores)}&lt;br /&gt;
&lt;br /&gt;
total &lt;br /&gt;
&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
The value in variable &amp;quot;total&amp;quot; needs to be stored in local_db_scores under &amp;quot;Score&amp;quot; and will be retrieved by using another function retrieve_total_score to display the total score instead of calculating it every time a user wants to view the scores.&lt;br /&gt;
&lt;br /&gt;
The proposed implementation retrieves the round wise scores from the local_db_scores database and displays the average score once the deadline has passed rather than computing the average of the weighted scores for every access of the page.&lt;br /&gt;
&lt;br /&gt;
The snapshots prior to and post implementation are shown below :&lt;br /&gt;
[[File:LocCur.png|thumb|Current System]]&lt;br /&gt;
[[File:LocADB.png|thumb|System after implementing changes]]&lt;br /&gt;
[[File:Flowchart12.png|center|frame|flowchart]]&lt;br /&gt;
&lt;br /&gt;
== Testing ==&lt;br /&gt;
The testing for model: on_the_fly_calc is carried out by questionnaire_spec.rb in the spec folder. The minimum and maximum score that an user gives for each criterion is checked.&lt;br /&gt;
&lt;br /&gt;
Two more test cases to check whether the average score of each review falls within a given range:(0,100) will be added.&lt;br /&gt;
&lt;br /&gt;
For LocalDB_calc, the average calculated across round 1 and round 2 will be checked to fall within 0 to 100. These test cases will be added to questionnaire_spec.rb.&lt;/div&gt;</summary>
		<author><name>Nthanik</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2016_E1682:_Improve_score_calculation&amp;diff=104963</id>
		<title>CSC/ECE 517 Fall 2016 E1682: Improve score calculation</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2016_E1682:_Improve_score_calculation&amp;diff=104963"/>
		<updated>2016-11-09T20:06:26Z</updated>

		<summary type="html">&lt;p&gt;Nthanik: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;E1682. Improve score calculation&lt;br /&gt;
=== LocalDBCalc: ===&lt;br /&gt;
Calculate the holistic score over a single db query (in this case, a query would be: “get the score that user A gives user B on assignment 999 on round 2”)&lt;br /&gt;
&lt;br /&gt;
Handles the calculation of reputations for each reviewer in the case of a finished assignment. (all the reputations are calculated and stored since they are finalized)&lt;br /&gt;
&lt;br /&gt;
== Implementation ==&lt;br /&gt;
&lt;br /&gt;
=== Parent Class:ScoreCalc ===&lt;br /&gt;
ScoreCalc stores the score calculated by its sub classes: on_the_fly_calc and LocalDBcalc to the database. In the database, a new table local_db_scoresn is created with the schema as explained in section 2.2. Depending upon the deadline_type, object of either on_the_fly_calc or LocalDBcalc is created and the appropriate functions within the classes are called. &lt;br /&gt;
&lt;br /&gt;
==== Database design ====&lt;br /&gt;
A table local_db_scores will be created as:&lt;br /&gt;
&lt;br /&gt;
create_table &amp;quot;local_db_scores&amp;quot;,force::cascade do|t|&lt;br /&gt;
&lt;br /&gt;
&amp;quot;local_db_scores&amp;quot; will have the following scores &lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|&lt;br /&gt;
|t.integer    &amp;quot;id&amp;quot;,         limit: 24&lt;br /&gt;
|id&lt;br /&gt;
|Primary Key, Auto generated&lt;br /&gt;
|-&lt;br /&gt;
|&lt;br /&gt;
|t.string    &amp;quot;Type&amp;quot;,      limit: 255&lt;br /&gt;
|Type&lt;br /&gt;
|Type of score: either final or intermediate&lt;br /&gt;
|-&lt;br /&gt;
|&lt;br /&gt;
|t.integer    &amp;quot;Score&amp;quot;,  limit: 24&lt;br /&gt;
|Score&lt;br /&gt;
|Total score calculated based on each response to each criterion&lt;br /&gt;
|-&lt;br /&gt;
|&lt;br /&gt;
|t.integer   &amp;quot;Round&amp;quot;,  limit:24&lt;br /&gt;
|Round&lt;br /&gt;
|The completed round number&lt;br /&gt;
|-&lt;br /&gt;
|&lt;br /&gt;
|t.integer  &amp;quot;Reference_id&amp;quot; , limit:45&lt;br /&gt;
|Reference_id&lt;br /&gt;
|Acts as the foreign Key&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Sub class 1: on_the_fly_calc ===&lt;br /&gt;
An object of on_the_fly_calc is called when the deadline_type is not &amp;quot;review of review&amp;quot; which means that the assignment is ongoing and has not been completed and stores the scores till the current stage that will change once the assignment passes the deadline&lt;br /&gt;
&lt;br /&gt;
The function compute_total_scores(scores) is used to calculate the total score based on each response to each criterion. The function is as below:&lt;br /&gt;
&lt;br /&gt;
def compute_total_scores(scores) &lt;br /&gt;
&lt;br /&gt;
:total=0&lt;br /&gt;
&lt;br /&gt;
:self.questionnaires.each{|questionnaire| total+=questionnaire.get_weighted_score(self,scores)}&lt;br /&gt;
&lt;br /&gt;
:total &lt;br /&gt;
&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
The value in variable &amp;quot;total&amp;quot; needs to be stored in local_db_scores under &amp;quot;Score&amp;quot; and will be retrieved by using another function retrieve_total_score to display the total score instead of calculating it every time a user wants to view the scores.&lt;br /&gt;
&lt;br /&gt;
=== Sub class 2: LocalDB_calc ===&lt;br /&gt;
An object of LocalDB_calc is called when the deadline_type is &amp;quot;review of review&amp;quot; which means that the assignment is completed and stores the final score in the database local_db_scores after computing it rather than computing it every time the score is required.&lt;br /&gt;
&lt;br /&gt;
Function compute_total_scores(scores) is added to the class which calculates the total score based on each response to each criterion. The function(polymorphism) is as below:&lt;br /&gt;
&lt;br /&gt;
def compute_total_scores(scores) &lt;br /&gt;
&lt;br /&gt;
:total=0&lt;br /&gt;
&lt;br /&gt;
:self.questionnaires.each{|questionnaire| total+=questionnaire.get_weighted_score(self,scores)}&lt;br /&gt;
&lt;br /&gt;
:total &lt;br /&gt;
&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
The value in variable &amp;quot;total&amp;quot; needs to be stored in local_db_scores under &amp;quot;Score&amp;quot; and will be retrieved by using another function retrieve_total_score to display the total score instead of calculating it every time a user wants to view the scores.&lt;br /&gt;
[[File:Flowchart12.png]]&lt;/div&gt;</summary>
		<author><name>Nthanik</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=File:Flowchart12.png&amp;diff=104956</id>
		<title>File:Flowchart12.png</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=File:Flowchart12.png&amp;diff=104956"/>
		<updated>2016-11-09T19:49:18Z</updated>

		<summary type="html">&lt;p&gt;Nthanik: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Nthanik</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2016_E1682:_Improve_score_calculation&amp;diff=104955</id>
		<title>CSC/ECE 517 Fall 2016 E1682: Improve score calculation</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2016_E1682:_Improve_score_calculation&amp;diff=104955"/>
		<updated>2016-11-09T19:48:59Z</updated>

		<summary type="html">&lt;p&gt;Nthanik: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;E1682. Improve score calculation&lt;br /&gt;
&lt;br /&gt;
=== Sub class 1: on_the_fly_calc ===&lt;br /&gt;
An object of on_the_fly_calc is called when the deadline_type is not &amp;quot;review of review&amp;quot; which means that the assignment is ongoing and has not been completed and stores the scores till the current stage that will change once the assignment passes the deadline&lt;br /&gt;
&lt;br /&gt;
The function compute_total_scores(scores) is used to calculate the total score based on each response to each criterion. The function is as below:&lt;br /&gt;
&lt;br /&gt;
def compute_total_scores(scores) &lt;br /&gt;
&lt;br /&gt;
total=0&lt;br /&gt;
&lt;br /&gt;
self.questionnaires.each{|questionnaire| total+=questionnaire.get_weighted_score(self,scores)}&lt;br /&gt;
&lt;br /&gt;
total &lt;br /&gt;
&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
The value in variable &amp;quot;total&amp;quot; needs to be stored in local_db_scores under &amp;quot;Score&amp;quot; and will be retrieved by using another function retrieve_total_score to display the total score instead of calculating it every time a user wants to view the scores.&lt;br /&gt;
&lt;br /&gt;
=== Sub class 2: LocalDB_calc ===&lt;br /&gt;
An object of LocalDB_calc is called when the deadline_type is &amp;quot;review of review&amp;quot; which means that the assignment is completed and stores the final score in the database local_db_scores after computing it rather than computing it every time the score is required.&lt;br /&gt;
&lt;br /&gt;
Function compute_total_scores(scores) is added to the class which calculates the total score based on each response to each criterion. The function(polymorphism) is as below:&lt;br /&gt;
&lt;br /&gt;
def compute_total_scores(scores) &lt;br /&gt;
&lt;br /&gt;
total=0&lt;br /&gt;
&lt;br /&gt;
self.questionnaires.each{|questionnaire| total+=questionnaire.get_weighted_score(self,scores)}&lt;br /&gt;
&lt;br /&gt;
total &lt;br /&gt;
&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
The value in variable &amp;quot;total&amp;quot; needs to be stored in local_db_scores under &amp;quot;Score&amp;quot; and will be retrieved by using another function retrieve_total_score to display the total score instead of calculating it every time a user wants to view the scores.&lt;br /&gt;
[[File:Flowchart12.png]]&lt;/div&gt;</summary>
		<author><name>Nthanik</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2016_E1682:_Improve_score_calculation&amp;diff=104954</id>
		<title>CSC/ECE 517 Fall 2016 E1682: Improve score calculation</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2016_E1682:_Improve_score_calculation&amp;diff=104954"/>
		<updated>2016-11-09T19:48:09Z</updated>

		<summary type="html">&lt;p&gt;Nthanik: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;E1682. Improve score calculation&lt;br /&gt;
&lt;br /&gt;
=== Sub class 1: on_the_fly_calc ===&lt;br /&gt;
An object of on_the_fly_calc is called when the deadline_type is not &amp;quot;review of review&amp;quot; which means that the assignment is ongoing and has not been completed and stores the scores till the current stage that will change once the assignment passes the deadline&lt;br /&gt;
&lt;br /&gt;
The function compute_total_scores(scores) is used to calculate the total score based on each response to each criterion. The function is as below:&lt;br /&gt;
&lt;br /&gt;
def compute_total_scores(scores) &lt;br /&gt;
&lt;br /&gt;
total=0&lt;br /&gt;
&lt;br /&gt;
self.questionnaires.each{|questionnaire| total+=questionnaire.get_weighted_score(self,scores)}&lt;br /&gt;
&lt;br /&gt;
total &lt;br /&gt;
&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
The value in variable &amp;quot;total&amp;quot; needs to be stored in local_db_scores under &amp;quot;Score&amp;quot; and will be retrieved by using another function retrieve_total_score to display the total score instead of calculating it every time a user wants to view the scores.&lt;br /&gt;
&lt;br /&gt;
=== Sub class 2: LocalDB_calc ===&lt;br /&gt;
An object of LocalDB_calc is called when the deadline_type is &amp;quot;review of review&amp;quot; which means that the assignment is completed and stores the final score in the database local_db_scores after computing it rather than computing it every time the score is required.&lt;br /&gt;
&lt;br /&gt;
Function compute_total_scores(scores) is added to the class which calculates the total score based on each response to each criterion. The function(polymorphism) is as below:&lt;br /&gt;
&lt;br /&gt;
def compute_total_scores(scores) &lt;br /&gt;
&lt;br /&gt;
total=0&lt;br /&gt;
&lt;br /&gt;
self.questionnaires.each{|questionnaire| total+=questionnaire.get_weighted_score(self,scores)}&lt;br /&gt;
&lt;br /&gt;
total &lt;br /&gt;
&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
The value in variable &amp;quot;total&amp;quot; needs to be stored in local_db_scores under &amp;quot;Score&amp;quot; and will be retrieved by using another function retrieve_total_score to display the total score instead of calculating it every time a user wants to view the scores.&lt;br /&gt;
[File:Flowchart12.png|center|frame|flowchart]&lt;/div&gt;</summary>
		<author><name>Nthanik</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2016_E1682:_Improve_score_calculation&amp;diff=104953</id>
		<title>CSC/ECE 517 Fall 2016 E1682: Improve score calculation</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2016_E1682:_Improve_score_calculation&amp;diff=104953"/>
		<updated>2016-11-09T19:47:42Z</updated>

		<summary type="html">&lt;p&gt;Nthanik: Created page with &amp;quot;E1682. Improve score calculation  === Sub class 1: on_the_fly_calc === An object of on_the_fly_calc is called when the deadline_type is not &amp;quot;review of review&amp;quot; which means that th...&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;E1682. Improve score calculation&lt;br /&gt;
&lt;br /&gt;
=== Sub class 1: on_the_fly_calc ===&lt;br /&gt;
An object of on_the_fly_calc is called when the deadline_type is not &amp;quot;review of review&amp;quot; which means that the assignment is ongoing and has not been completed and stores the scores till the current stage that will change once the assignment passes the deadline&lt;br /&gt;
&lt;br /&gt;
The function compute_total_scores(scores) is used to calculate the total score based on each response to each criterion. The function is as below:&lt;br /&gt;
&lt;br /&gt;
def compute_total_scores(scores) &lt;br /&gt;
&lt;br /&gt;
total=0&lt;br /&gt;
&lt;br /&gt;
self.questionnaires.each{|questionnaire| total+=questionnaire.get_weighted_score(self,scores)}&lt;br /&gt;
&lt;br /&gt;
total &lt;br /&gt;
&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
The value in variable &amp;quot;total&amp;quot; needs to be stored in local_db_scores under &amp;quot;Score&amp;quot; and will be retrieved by using another function retrieve_total_score to display the total score instead of calculating it every time a user wants to view the scores.&lt;br /&gt;
&lt;br /&gt;
=== Sub class 2: LocalDB_calc ===&lt;br /&gt;
An object of LocalDB_calc is called when the deadline_type is &amp;quot;review of review&amp;quot; which means that the assignment is completed and stores the final score in the database local_db_scores after computing it rather than computing it every time the score is required.&lt;br /&gt;
&lt;br /&gt;
Function compute_total_scores(scores) is added to the class which calculates the total score based on each response to each criterion. The function(polymorphism) is as below:&lt;br /&gt;
&lt;br /&gt;
def compute_total_scores(scores) &lt;br /&gt;
&lt;br /&gt;
total=0&lt;br /&gt;
&lt;br /&gt;
self.questionnaires.each{|questionnaire| total+=questionnaire.get_weighted_score(self,scores)}&lt;br /&gt;
&lt;br /&gt;
total &lt;br /&gt;
&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
The value in variable &amp;quot;total&amp;quot; needs to be stored in local_db_scores under &amp;quot;Score&amp;quot; and will be retrieved by using another function retrieve_total_score to display the total score instead of calculating it every time a user wants to view the scores.&lt;br /&gt;
[[File:Flowchart12.png|center|frame|flowchart]]&lt;/div&gt;</summary>
		<author><name>Nthanik</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2016&amp;diff=104952</id>
		<title>CSC/ECE 517 Fall 2016</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2016&amp;diff=104952"/>
		<updated>2016-11-09T19:44:42Z</updated>

		<summary type="html">&lt;p&gt;Nthanik: /* Final Project Design Document */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[http://www.example.com link title]==Calibration Assignment Submissions==&lt;br /&gt;
*[[Calibration Assignment Submission (Firebrick JS)]]&lt;br /&gt;
*[[Calibration Assignment Submission (Active Job)]]&lt;br /&gt;
==Writing Assignments 2==&lt;br /&gt;
*[[CSC/ECE 517 Fall 2016/E1666. Test team functionality]]&lt;br /&gt;
*[[CSC/ECE 517 Fall 2016/E1643. Refactor Suggestion controller]]&lt;br /&gt;
*[[CSC/ECE 517 Fall 2016/E1631. Refactoring Bidding Interface]]&lt;br /&gt;
*[[CSC/ECE 517 Fall 2016/E1674.Refactor leaderboard.rb and write unit tests]]&lt;br /&gt;
*[[CSC/ECE 517 Fall 2016/E1671. Unit Tests for participants.rb Hierarchy]]&lt;br /&gt;
*[[CSC/ECE 517 Fall 2016/E1668.Test e-mailing functionality]]&lt;br /&gt;
*[[CSC/ECE 517 Fall 2016/E1658. Refractor lottery_controller.rb and write integration tests]]&lt;br /&gt;
*[[CSC/ECE 517 Fall 2016/E1660. Review requirements and thresholds]]&lt;br /&gt;
*[[CSC/ECE 517 Fall 2016/E1650. Sort instructor views alphabetically by default]]&lt;br /&gt;
*[[CSC/ECE 517 Fall 2016/E1644. Refactor and test Teams Controller]]&lt;br /&gt;
*[[CSC/ECE 517 Fall 2016/E1645. Refactoring Tree Display Controller]]&lt;br /&gt;
*[[CSC/ECE 517 Fall 2016/E1659. Refactor on_the_fly_calc.rb]]&lt;br /&gt;
*[[CSC/ECE 517 Fall 2016/E1657. Introduce a Student View for instructors]]&lt;br /&gt;
*[[CSC/ECE 517 Fall 2016/E1653. Fix and improve rubric criteria]]&lt;br /&gt;
*[[CSC/ECE 517 Fall 2016/E1642. Refactor review_response_map.rb]]&lt;br /&gt;
*[[CSC/ECE 517 Fall 2016/E1633. Refactor different question types from quiz feature]]&lt;br /&gt;
*[[CSC/ECE_517_Fall_2016/E1664:_Feature_Test_Assignment_Creation]]&lt;br /&gt;
*[[CSC/ECE 517 Fall 2016/E1666. Test team functionality]]&lt;br /&gt;
*[[CSC/ECE_517_Fall_2016/E1654. Improve_date-picker_and_deadlines]]&lt;br /&gt;
*[[CSC/ECE_517_Fall_2016/E1652 Fix teammate advertisements and requests to join a team ]]&lt;br /&gt;
*[[CSC/ECE_517_Fall_2016/E1662. UI issues/fixes]]&lt;br /&gt;
*[[CSC/ECE_517_Fall_2016/E1673. Refactor question_type.rb]]&lt;br /&gt;
*[[CSC/ECE_517_Fall_2016/E1675. Timestamp for student file &amp;amp; hyperlink submissions]]&lt;br /&gt;
*[[CSC/ECE_517_Fall_2016/E1640. Refactor response.rb and response_helper.rb]]&lt;br /&gt;
*[[CSC/ECE 517 Fall 2016/E1634. Refactor and write unit test of due_date.rb and deadline_helper.rb]]&lt;br /&gt;
*[[CSC/ECE_517_Fall_2016/M1654._Improve_network_security_features]]&lt;br /&gt;
*[[CSC/ECE_517_Fall_2016/E1670._Unit_tests_for_answers.rb]]&lt;br /&gt;
*[[CSC/ECE_517_Fall_2016/E1641. Refactor review_mapping_controller.rb]]&lt;br /&gt;
*[[CSC/ECE_517_Fall_2016/M1652_Implement_ImageMap_Support_Servo]]&lt;br /&gt;
*[[CSC/ECE_517_Fall_2016/E1648/Add_past_due_assignment]]&lt;br /&gt;
*[[CSC/ECE 517 Fall 2016/E1656. Improve imports]]&lt;br /&gt;
*[[CSC/ECE_517_Fall_2016/M1653_Implement_HTML_form_validation]]&lt;br /&gt;
==Final Project Design Document==&lt;br /&gt;
*[[CSC/ECE 517 Fall 2016 E1696  Improve Self-Review]]&lt;br /&gt;
*[[CSC/ECE 517 Fall 2016 E1676  Role-based reviewing]]&lt;br /&gt;
*[[CSC/ECE 517 Fall 2016/E1680. Improve survey functionality]]&lt;br /&gt;
*[[CSC/ECE 517 Fall 2016/E1693. Drag-and-drop interface for creating rubrics]]&lt;br /&gt;
*[[CSC/ECE 517 Fall 2016/E1701. Accelerate RSpec testing]]&lt;br /&gt;
*[[CSC/ECE 517 Fall 2016/E1705. Tracking the time students look at the others' submissions]]&lt;br /&gt;
*[[CSC/ECE 517 Fall 2016/E1688. Send feedback to support + tree display improvement]]&lt;br /&gt;
*[[CSC/ECE 517 Fall 2016 E1707: Top trading cycles to exclude previous teammates]]&lt;br /&gt;
*[[CSC/ECE 517 Fall 2016 E1678: Review configuration options]]&lt;br /&gt;
*[[CSC/ECE 517 Fall 2016 E1682: Improve score calculation]]&lt;/div&gt;</summary>
		<author><name>Nthanik</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2016/E1634.Refactor_and_write_unit_test_of_due_date.rb_and_deadline_helper.rb&amp;diff=103379</id>
		<title>CSC/ECE 517 Fall 2016/E1634.Refactor and write unit test of due date.rb and deadline helper.rb</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2016/E1634.Refactor_and_write_unit_test_of_due_date.rb_and_deadline_helper.rb&amp;diff=103379"/>
		<updated>2016-10-29T00:03:30Z</updated>

		<summary type="html">&lt;p&gt;Nthanik: Blanked the page&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Nthanik</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2016/E1634.Refactor_and_write_unit_test_of_due_date.rb_and_deadline_helper.rb&amp;diff=103371</id>
		<title>CSC/ECE 517 Fall 2016/E1634.Refactor and write unit test of due date.rb and deadline helper.rb</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2016/E1634.Refactor_and_write_unit_test_of_due_date.rb_and_deadline_helper.rb&amp;diff=103371"/>
		<updated>2016-10-29T00:01:47Z</updated>

		<summary type="html">&lt;p&gt;Nthanik: Undo revision 102936 by Nthanik (talk)&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Introduction&lt;br /&gt;
Expertiza&lt;br /&gt;
Expertiza is an open source project for school assignment management for instructors and students based on the Ruby on Rails framework. Expertiza allows the instructor to create new assignments and customise new or existing assignments. It also allows the instructor to create a list of topics the students can sign up for. Students can form teams in Expertiza to work on various projects and assignments. Students can also peer review other students' submissions. Expertiza supports submission across various document types, including the URLs and word documents. Expertiza provides a dashboard for all the assignments corresponding to a course and provides absolute control to the Instructors and Teaching Assistants. In addition to assignments, it encompasses peer reviews wherein participants are allowed to provide feedback anonymously about each other's work thereby providing scope for the better outcome. The due_date.rb file is responsible for informing the users about the deadline for submission of the each assignment. Due dates in Expertiza have their association with many other components like assignments, reviews etc.&lt;br /&gt;
&lt;br /&gt;
Code Climate&lt;br /&gt;
Code Climate[1] is a tool that runs static analysis on a GitHub project and outputs many details like test coverage, complexity, duplication, security, style, and more. There is a Google Chrome extension to integrate the Code Climate results generated directly into GitHub which is visible when browsing the repository on the browser. It allows us to see issues displayed directly inside GitHub's UI, to review which lines are covered in diffs and files, and add repositories and open tickets without changing your workflow.&lt;br /&gt;
&lt;br /&gt;
Tasks Identified&lt;br /&gt;
To install Code climate Chrome Extension that highlights the duplicated code.&lt;br /&gt;
&lt;br /&gt;
To refactor the following two files:&lt;br /&gt;
&lt;br /&gt;
Due_date.rb&lt;br /&gt;
Ternary operators must not be nested. Prefer `if` or `else` constructs instead.&lt;br /&gt;
Useless assignment to variable - `sorted_deadlines`.&lt;br /&gt;
Prefer `each` over `for`.&lt;br /&gt;
Use `find_by` instead of `where.first`.&lt;br /&gt;
Correct the use of Time function&lt;br /&gt;
Deadline_helper.rb&lt;br /&gt;
Do not use `Time.now` without zone. Use one of `Time.zone.now`, `Time.current`, `Time.now.in_time_zone`, `Time.now.utc`, `Time.now.getlocal`, `Time.now.iso8601`, `Time.now.jisx0301`, `Time.now.rfc3339`, `Time.now.to_i`, `Time.now.to_f` instead.&lt;br /&gt;
Trailing whitespace detected.&lt;br /&gt;
Extra empty line detected at module body end.&lt;br /&gt;
Create respective RSpec files in /spec/models/ and /spec/helper folder and write unit tests for each method in due_date.rb and deadline_helper.rb.&lt;br /&gt;
Current Implementation&lt;br /&gt;
DueDate is a Model class to manage the deadlines of an assignment. It has methods for setting due dates for an assignment, copying due dates from one assignment to a new assignment etc. DeadlineHelper provides helper functions that help DueDate perform certain tasks. The assignment focuses on refactoring some of the methods based on warnings received from Code Climate's static analysis and modifying the language to make it more Ruby-friendly. The assignment also involves writing unit test cases for due_date.rb and deadline_helper.rb in order to increase test coverage.&lt;br /&gt;
&lt;br /&gt;
The goal of this project is to attempt to make this part of the application easier to read and write unit test cases that the application must pass.&lt;br /&gt;
&lt;br /&gt;
Changed Implementation&lt;br /&gt;
Changes implemented involves refactoring the code and making it more understandable by adding comments in the code.&lt;br /&gt;
&lt;br /&gt;
The modified files are&lt;br /&gt;
&lt;br /&gt;
Due_date.rb (path: /app/models)&lt;br /&gt;
Deadline_helper.rb (path: /app/helpers)&lt;br /&gt;
Testing files&lt;br /&gt;
&lt;br /&gt;
Due_date_spec.rb (path: /spec/models)&lt;br /&gt;
Deadline_helper_spec.rb (path: /spec/helpers)&lt;br /&gt;
Due_date.rb&lt;br /&gt;
Converted for..in loop to object.each in order to follow better Ruby syntax.&lt;br /&gt;
Unnecessary assignment to sorted_deadlines removed.&lt;br /&gt;
Nested ternary operators have been changed to if..else in order to make it more readable.&lt;br /&gt;
&lt;br /&gt;
Due_date.rb&lt;br /&gt;
Changed where(...).first to find_by(...) which is the newer recommended syntax.&lt;br /&gt;
Corrected the Time.now functions by adding the correct zones to them such as Time.zone.now.&lt;br /&gt;
Removed trailing whitespaces.&lt;br /&gt;
&lt;br /&gt;
Deadline_helper.rb&lt;br /&gt;
Time functions were changed to functions with zones&lt;br /&gt;
Extra line removed&lt;br /&gt;
&lt;br /&gt;
Deadline_helper&lt;br /&gt;
RSpec testing&lt;br /&gt;
There were no existing tests for the functions in due_date.rb and deadline_helper.rb. We have added exhaustive set of RSpec tests to test all the code. We have added two new spec files 'due_date_spec.rb' and ‘deadline_helper_spec.rb’ which cover the testing scenarios for the functions in ‘due_date.rb’ and ‘deadline_helper.rb’.&lt;br /&gt;
&lt;br /&gt;
These RSpec files have 100% code coverage visible at: /coverage/index.html&lt;br /&gt;
&lt;br /&gt;
due_date_spec.rb&lt;br /&gt;
This file is located at spec/models and tests the functionalities of the due_date.rb file located in app/models. There are 18 test cases in total which are listed below.&lt;br /&gt;
&lt;br /&gt;
If the factory is successfully able to build the due_date objects.&lt;br /&gt;
it &amp;quot;due date factory created successfully&amp;quot; do&lt;br /&gt;
    expect(@assignment_due_date).to be_valid&lt;br /&gt;
end&lt;br /&gt;
it &amp;quot;due dates created correctly&amp;quot; do&lt;br /&gt;
    expect(@due_dates.length).to be == 10&lt;br /&gt;
end&lt;br /&gt;
If the function &amp;quot;set_flag&amp;quot; successfully sets the due_date flag.&lt;br /&gt;
it &amp;quot;due date flag is set&amp;quot; do&lt;br /&gt;
    expect(@assignment_due_date.flag).to be false&lt;br /&gt;
    @assignment_due_date.set_flag&lt;br /&gt;
    expect(@assignment_due_date.flag).to be true&lt;br /&gt;
end&lt;br /&gt;
If the function &amp;quot;due_at_is_valid_datetime&amp;quot; returns nil (no errors) for a valid datetime in due_at (no invalid test cases can be added here because model does not allow invalid datetime to be set at all).&lt;br /&gt;
it &amp;quot;due at is valid datetime&amp;quot; do&lt;br /&gt;
    expect(@assignment_due_date.due_at_is_valid_datetime).to be nil&lt;br /&gt;
end&lt;br /&gt;
If the function &amp;quot;self.copy&amp;quot; is able to copy due dates from one assignment to another.&lt;br /&gt;
it &amp;quot;copy due dates to new assignment&amp;quot; do&lt;br /&gt;
    new_assignment_id = build(:assignment, id: 999).id&lt;br /&gt;
    old_assignment_id = @assignment_due_date.assignment.id&lt;br /&gt;
    DueDate.copy(old_assignment_id, new_assignment_id)&lt;br /&gt;
    expect(DueDate.where(parent_id: new_assignment_id).count).to eql DueDate.where(parent_id: old_assignment_id).count&lt;br /&gt;
end&lt;br /&gt;
If the function &amp;quot;self.set_duedate&amp;quot; is able to create another due date by copying data from an existing due date object.&lt;br /&gt;
it &amp;quot;create new duedate record with values&amp;quot; do&lt;br /&gt;
    DueDate.set_duedate({id: 999}, @assignment_due_date.deadline_type_id,&lt;br /&gt;
                        @assignment_due_date.parent_id, @assignment_due_date.round)&lt;br /&gt;
    new_due_date = DueDate.find_by(id: 999)&lt;br /&gt;
    expect(new_due_date).to be_valid&lt;br /&gt;
    expect(new_due_date.deadline_type_id).to eql @assignment_due_date.deadline_type_id&lt;br /&gt;
    expect(new_due_date.parent_id).to eql @assignment_due_date.parent_id&lt;br /&gt;
    expect(new_due_date.round).to eql @assignment_due_date.round&lt;br /&gt;
end&lt;br /&gt;
If the function &amp;quot;self.deadline_sort&amp;quot; is able to sort the due dates in ascending order.&lt;br /&gt;
it &amp;quot;sort duedate records&amp;quot; do&lt;br /&gt;
    sorted_due_dates = @due_dates&lt;br /&gt;
    expect(sorted_due_dates.each_cons(2).all?{|m1, m2| (m1.due_at &amp;lt;=&amp;gt; m2.due_at) != 1}).to eql false&lt;br /&gt;
&lt;br /&gt;
    sorted_due_dates = DueDate.deadline_sort(@due_dates)&lt;br /&gt;
    expect(sorted_due_dates.each_cons(2).all?{|m1, m2| (m1.due_at &amp;lt;=&amp;gt; m2.due_at) != 1}).to eql true&lt;br /&gt;
end&lt;br /&gt;
If the function &amp;quot;self.done_in_assignment_round&amp;quot; returns the correct number of rounds for specific inputs. This involves an invalid test case as well for 0 rounds.&lt;br /&gt;
describe &amp;quot;#done_in_assignment_round&amp;quot; do&lt;br /&gt;
    it &amp;quot;return 0 when no response map&amp;quot; do&lt;br /&gt;
      response = ReviewResponseMap.create&lt;br /&gt;
      response.type = &amp;quot;ResponseMap&amp;quot;&lt;br /&gt;
      response.save&lt;br /&gt;
      expect(DueDate.done_in_assignment_round(1, response)).to eql 0&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    it &amp;quot;return round 1 for single round&amp;quot; do&lt;br /&gt;
      response = ReviewResponseMap.create&lt;br /&gt;
      expect(DueDate.done_in_assignment_round(@assignment_due_date.parent_id, response)).to eql 1&lt;br /&gt;
    end&lt;br /&gt;
end&lt;br /&gt;
If the function &amp;quot;self.get_next_due_date&amp;quot; works as expected. This involves several invalid test cases as well.&lt;br /&gt;
describe &amp;quot;#get_next_due_date&amp;quot; do&lt;br /&gt;
    it &amp;quot;no subsequent due date&amp;quot; do&lt;br /&gt;
      expect(DueDate.get_next_due_date(@assignment_due_date.parent_id)).to be nil&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    it &amp;quot;nil value throws exception&amp;quot; do&lt;br /&gt;
      expect { DueDate.get_next_due_date(nil) }.to raise_exception(ActiveRecord::RecordNotFound)&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    it &amp;quot;get next assignment due date&amp;quot; do&lt;br /&gt;
      due_date = create(:assignment_due_date, deadline_type: @deadline_type,&lt;br /&gt;
        submission_allowed_id: @deadline_right.id, review_allowed_id: @deadline_right.id,&lt;br /&gt;
        review_of_review_allowed_id: @deadline_right.id, due_at: Time.zone.now + 5000)&lt;br /&gt;
      expect(DueDate.get_next_due_date(due_date.parent_id)).to be_valid&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    it &amp;quot;get next due date from topic for staggered deadline&amp;quot; do&lt;br /&gt;
      assignment_id = create(:assignment, staggered_deadline: true, name: &amp;quot;testassignment&amp;quot;).id&lt;br /&gt;
      due_date = create(:topic_due_date, deadline_type: @deadline_type,&lt;br /&gt;
        submission_allowed_id: @deadline_right.id, review_allowed_id: @deadline_right.id,&lt;br /&gt;
        review_of_review_allowed_id: @deadline_right.id, due_at: Time.zone.now + 5000, parent_id: assignment_id)&lt;br /&gt;
      expect(DueDate.get_next_due_date(assignment_id, due_date.parent_id)).to be_valid&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    it &amp;quot;next due date does not exist for staggered deadline&amp;quot; do&lt;br /&gt;
      assignment_id = create(:assignment, staggered_deadline: true, name: &amp;quot;testassignment&amp;quot;).id&lt;br /&gt;
      due_date = create(:topic_due_date, deadline_type: @deadline_type,&lt;br /&gt;
        submission_allowed_id: @deadline_right, review_allowed_id: @deadline_right,&lt;br /&gt;
        review_of_review_allowed_id: @deadline_right, due_at: Time.zone.now + 5000, parent_id: assignment_id)&lt;br /&gt;
      expect(DueDate.get_next_due_date(assignment_id)).to be nil&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    it &amp;quot;next due date is before Time.now for staggered deadline&amp;quot; do&lt;br /&gt;
      assignment_id = create(:assignment, staggered_deadline: true, name: &amp;quot;testassignment&amp;quot;).id&lt;br /&gt;
      due_date = create(:topic_due_date, deadline_type: @deadline_type,&lt;br /&gt;
        submission_allowed_id: @deadline_right, review_allowed_id: @deadline_right,&lt;br /&gt;
        review_of_review_allowed_id: @deadline_right, due_at: Time.zone.now - 5000, parent_id: assignment_id)&lt;br /&gt;
      expect(DueDate.get_next_due_date(assignment_id, due_date.parent_id)).to be nil&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    it &amp;quot;get next due date from assignment for staggered deadline&amp;quot; do&lt;br /&gt;
      assignment_id = create(:assignment, staggered_deadline: true, name: &amp;quot;testassignment&amp;quot;).id&lt;br /&gt;
      due_date = create(:assignment_due_date, deadline_type: @deadline_type,&lt;br /&gt;
        submission_allowed_id: @deadline_right, review_allowed_id: @deadline_right,&lt;br /&gt;
        review_of_review_allowed_id: @deadline_right, due_at: Time.zone.now + 5000, parent_id: assignment_id)&lt;br /&gt;
      expect(DueDate.get_next_due_date(assignment_id)).to be_valid&lt;br /&gt;
    end&lt;br /&gt;
end&lt;br /&gt;
If the function &amp;quot;self.default_permission&amp;quot; returns the correct default permissions for particular deadline and permission types.&lt;br /&gt;
it &amp;quot;metareview review_of_review_allowed default permission OK&amp;quot; do&lt;br /&gt;
    expect(DueDate.default_permission('metareview', 'review_of_review_allowed')).to be == DeadlineRight::OK&lt;br /&gt;
end&lt;br /&gt;
it &amp;quot;review submission_allowed default permission NO&amp;quot; do&lt;br /&gt;
    expect(DueDate.default_permission('review', 'submission_allowed')).to be == DeadlineRight::NO&lt;br /&gt;
end&lt;br /&gt;
To test this file run the following command:&lt;br /&gt;
&lt;br /&gt;
rspec spec/models/due_date_spec.rb&lt;br /&gt;
The output of this RSpec file is present in below screenshot:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Code coverage details of the above RSpec files is present in below screenshot:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Code coverage details of the above RSpec files is present in below screenshot:&lt;br /&gt;
&lt;br /&gt;
deadline_helper_spec.rb&lt;br /&gt;
This is a test file for testing the functionalities of Deadline_helper.rb file located at app/helpers. Different test cases present in this file are:&lt;br /&gt;
&lt;br /&gt;
Check if the factory is valid:&lt;br /&gt;
it &amp;quot;has a valid factory&amp;quot; do&lt;br /&gt;
    factory = FactoryGirl.build(:topic_due_date)&lt;br /&gt;
    expect(factory).to be_valid&lt;br /&gt;
end&lt;br /&gt;
Fail if the due date is invalid:&lt;br /&gt;
it &amp;quot;should fail because of invalid due_date&amp;quot; do&lt;br /&gt;
      expect { DeadlineHelper.create_topic_deadline(nil, 0, 0)}.to raise_exception(NoMethodError)&lt;br /&gt;
end&lt;br /&gt;
If new due_date object is created:&lt;br /&gt;
it &amp;quot;new due_date object created&amp;quot; do&lt;br /&gt;
      DeadlineHelper.create_topic_deadline(@topic_due_date, 0, 1)&lt;br /&gt;
      expect(TopicDueDate.count).to be == 2&lt;br /&gt;
end&lt;br /&gt;
due_at should be same for 0 offset:&lt;br /&gt;
 it &amp;quot;due_at should be same for 0 offset&amp;quot; do&lt;br /&gt;
      DeadlineHelper.create_topic_deadline(@topic_due_date, 0, 10)&lt;br /&gt;
      new_due_date = TopicDueDate.find_by(parent_id: 10)&lt;br /&gt;
      expect(new_due_date).to be_valid&lt;br /&gt;
      expect(new_due_date.due_at.to_s).to be == @topic_due_date.due_at.to_s&lt;br /&gt;
end&lt;br /&gt;
due_at is calculated correctly if offset is positive:&lt;br /&gt;
it &amp;quot;due_at calculated correctly for positive offset&amp;quot; do&lt;br /&gt;
      DeadlineHelper.create_topic_deadline(@topic_due_date, 5000, 10)&lt;br /&gt;
      new_due_date = TopicDueDate.find_by(parent_id: 10)&lt;br /&gt;
      expect(new_due_date).to be_valid&lt;br /&gt;
      expect(new_due_date.due_at.to_s).to be == (Time.zone.parse(@topic_due_date.due_at.to_s) + 5000).to_s&lt;br /&gt;
end&lt;br /&gt;
due_at is calculated correctly if offset is negative:&lt;br /&gt;
it &amp;quot;due_at calculated correctly for negative offset&amp;quot; do&lt;br /&gt;
      DeadlineHelper.create_topic_deadline(@topic_due_date, -5000, 10)&lt;br /&gt;
      new_due_date = TopicDueDate.find_by(parent_id: 10)&lt;br /&gt;
      expect(new_due_date).to be_valid&lt;br /&gt;
      expect(new_due_date.due_at.to_s).to be == (Time.zone.parse(@topic_due_date.due_at.to_s) - 5000).to_s&lt;br /&gt;
end&lt;br /&gt;
The offset is being converted to integer properly:&lt;br /&gt;
it &amp;quot;offset converted to integer correctly&amp;quot; do&lt;br /&gt;
      DeadlineHelper.create_topic_deadline(@topic_due_date, 5000.15, 10)&lt;br /&gt;
      new_due_date = TopicDueDate.find_by(parent_id: 10)&lt;br /&gt;
      expect(new_due_date).to be_valid&lt;br /&gt;
      expect(new_due_date.due_at.to_s).to be == (Time.zone.parse(@topic_due_date.due_at.to_s) + 5000).to_s&lt;br /&gt;
end&lt;br /&gt;
To test this file run the following command:&lt;br /&gt;
&lt;br /&gt;
rspec spec/models/deadline_helper_spec.rb&lt;br /&gt;
The output of this RSpec file is present in below screenshot:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Code coverage details of the above RSpec files is present in below screenshot:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
References&lt;br /&gt;
&amp;quot;Log in to your Code Climate dashboard with GitHub or your email.&amp;quot;. codeclimate.com. Retrieved 2016-10-28.&lt;/div&gt;</summary>
		<author><name>Nthanik</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2016/E1634.Refactor_and_write_unit_test_of_due_date.rb_and_deadline_helper.rb&amp;diff=103369</id>
		<title>CSC/ECE 517 Fall 2016/E1634.Refactor and write unit test of due date.rb and deadline helper.rb</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2016/E1634.Refactor_and_write_unit_test_of_due_date.rb_and_deadline_helper.rb&amp;diff=103369"/>
		<updated>2016-10-29T00:01:35Z</updated>

		<summary type="html">&lt;p&gt;Nthanik: Undo revision 102952 by Nthanik (talk)&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;'''Introduction&lt;br /&gt;
'''Expertiza&lt;br /&gt;
Expertiza is an open source project for school assignment management for instructors and students based on the Ruby on Rails framework. Expertiza allows the instructor to create new assignments and customise new or existing assignments. It also allows the instructor to create a list of topics the students can sign up for. Students can form teams in Expertiza to work on various projects and assignments. Students can also peer review other students' submissions. Expertiza supports submission across various document types, including the URLs and word documents. Expertiza provides a dashboard for all the assignments corresponding to a course and provides absolute control to the Instructors and Teaching Assistants. In addition to assignments, it encompasses peer reviews wherein participants are allowed to provide feedback anonymously about each other's work thereby providing scope for the better outcome. The due_date.rb file is responsible for informing the users about the deadline for submission of the each assignment. Due dates in Expertiza have their association with many other components like assignments, reviews etc.&lt;br /&gt;
&lt;br /&gt;
Code Climate&lt;br /&gt;
Code Climate[1] is a tool that runs static analysis on a GitHub project and outputs many details like test coverage, complexity, duplication, security, style, and more. There is a Google Chrome extension to integrate the Code Climate results generated directly into GitHub which is visible when browsing the repository on the browser. It allows us to see issues displayed directly inside GitHub's UI, to review which lines are covered in diffs and files, and add repositories and open tickets without changing your workflow.&lt;br /&gt;
&lt;br /&gt;
Tasks Identified&lt;br /&gt;
To install Code climate Chrome Extension that highlights the duplicated code.&lt;br /&gt;
&lt;br /&gt;
To refactor the following two files:&lt;br /&gt;
&lt;br /&gt;
Due_date.rb&lt;br /&gt;
Ternary operators must not be nested. Prefer `if` or `else` constructs instead.&lt;br /&gt;
Useless assignment to variable - `sorted_deadlines`.&lt;br /&gt;
Prefer `each` over `for`.&lt;br /&gt;
Use `find_by` instead of `where.first`.&lt;br /&gt;
Correct the use of Time function&lt;br /&gt;
Deadline_helper.rb&lt;br /&gt;
Do not use `Time.now` without zone. Use one of `Time.zone.now`, `Time.current`, `Time.now.in_time_zone`, `Time.now.utc`, `Time.now.getlocal`, `Time.now.iso8601`, `Time.now.jisx0301`, `Time.now.rfc3339`, `Time.now.to_i`, `Time.now.to_f` instead.&lt;br /&gt;
Trailing whitespace detected.&lt;br /&gt;
Extra empty line detected at module body end.&lt;br /&gt;
Create respective RSpec files in /spec/models/ and /spec/helper folder and write unit tests for each method in due_date.rb and deadline_helper.rb.&lt;br /&gt;
Current Implementation&lt;br /&gt;
DueDate is a Model class to manage the deadlines of an assignment. It has methods for setting due dates for an assignment, copying due dates from one assignment to a new assignment etc. DeadlineHelper provides helper functions that help DueDate perform certain tasks. The assignment focuses on refactoring some of the methods based on warnings received from Code Climate's static analysis and modifying the language to make it more Ruby-friendly. The assignment also involves writing unit test cases for due_date.rb and deadline_helper.rb in order to increase test coverage.&lt;br /&gt;
&lt;br /&gt;
The goal of this project is to attempt to make this part of the application easier to read and write unit test cases that the application must pass.&lt;br /&gt;
&lt;br /&gt;
Changed Implementation&lt;br /&gt;
Changes implemented involves refactoring the code and making it more understandable by adding comments in the code.&lt;br /&gt;
&lt;br /&gt;
The modified files are&lt;br /&gt;
&lt;br /&gt;
Due_date.rb (path: /app/models)&lt;br /&gt;
Deadline_helper.rb (path: /app/helpers)&lt;br /&gt;
Testing files&lt;br /&gt;
&lt;br /&gt;
Due_date_spec.rb (path: /spec/models)&lt;br /&gt;
Deadline_helper_spec.rb (path: /spec/helpers)&lt;br /&gt;
Due_date.rb&lt;br /&gt;
Converted for..in loop to object.each in order to follow better Ruby syntax.&lt;br /&gt;
Unnecessary assignment to sorted_deadlines removed.&lt;br /&gt;
Nested ternary operators have been changed to if..else in order to make it more readable.&lt;br /&gt;
&lt;br /&gt;
Due_date.rb&lt;br /&gt;
Changed where(...).first to find_by(...) which is the newer recommended syntax.&lt;br /&gt;
Corrected the Time.now functions by adding the correct zones to them such as Time.zone.now.&lt;br /&gt;
Removed trailing whitespaces.&lt;br /&gt;
&lt;br /&gt;
Deadline_helper.rb&lt;br /&gt;
Time functions were changed to functions with zones&lt;br /&gt;
Extra line removed&lt;br /&gt;
&lt;br /&gt;
Deadline_helper&lt;br /&gt;
RSpec testing&lt;br /&gt;
There were no existing tests for the functions in due_date.rb and deadline_helper.rb. We have added exhaustive set of RSpec tests to test all the code. We have added two new spec files 'due_date_spec.rb' and ‘deadline_helper_spec.rb’ which cover the testing scenarios for the functions in ‘due_date.rb’ and ‘deadline_helper.rb’.&lt;br /&gt;
&lt;br /&gt;
These RSpec files have 100% code coverage visible at: /coverage/index.html&lt;br /&gt;
&lt;br /&gt;
due_date_spec.rb&lt;br /&gt;
This file is located at spec/models and tests the functionalities of the due_date.rb file located in app/models. There are 18 test cases in total which are listed below.&lt;br /&gt;
&lt;br /&gt;
If the factory is successfully able to build the due_date objects.&lt;br /&gt;
it &amp;quot;due date factory created successfully&amp;quot; do&lt;br /&gt;
    expect(@assignment_due_date).to be_valid&lt;br /&gt;
end&lt;br /&gt;
it &amp;quot;due dates created correctly&amp;quot; do&lt;br /&gt;
    expect(@due_dates.length).to be == 10&lt;br /&gt;
end&lt;br /&gt;
If the function &amp;quot;set_flag&amp;quot; successfully sets the due_date flag.&lt;br /&gt;
it &amp;quot;due date flag is set&amp;quot; do&lt;br /&gt;
    expect(@assignment_due_date.flag).to be false&lt;br /&gt;
    @assignment_due_date.set_flag&lt;br /&gt;
    expect(@assignment_due_date.flag).to be true&lt;br /&gt;
end&lt;br /&gt;
If the function &amp;quot;due_at_is_valid_datetime&amp;quot; returns nil (no errors) for a valid datetime in due_at (no invalid test cases can be added here because model does not allow invalid datetime to be set at all).&lt;br /&gt;
it &amp;quot;due at is valid datetime&amp;quot; do&lt;br /&gt;
    expect(@assignment_due_date.due_at_is_valid_datetime).to be nil&lt;br /&gt;
end&lt;br /&gt;
If the function &amp;quot;self.copy&amp;quot; is able to copy due dates from one assignment to another.&lt;br /&gt;
it &amp;quot;copy due dates to new assignment&amp;quot; do&lt;br /&gt;
    new_assignment_id = build(:assignment, id: 999).id&lt;br /&gt;
    old_assignment_id = @assignment_due_date.assignment.id&lt;br /&gt;
    DueDate.copy(old_assignment_id, new_assignment_id)&lt;br /&gt;
    expect(DueDate.where(parent_id: new_assignment_id).count).to eql DueDate.where(parent_id: old_assignment_id).count&lt;br /&gt;
end&lt;br /&gt;
If the function &amp;quot;self.set_duedate&amp;quot; is able to create another due date by copying data from an existing due date object.&lt;br /&gt;
it &amp;quot;create new duedate record with values&amp;quot; do&lt;br /&gt;
    DueDate.set_duedate({id: 999}, @assignment_due_date.deadline_type_id,&lt;br /&gt;
                        @assignment_due_date.parent_id, @assignment_due_date.round)&lt;br /&gt;
    new_due_date = DueDate.find_by(id: 999)&lt;br /&gt;
    expect(new_due_date).to be_valid&lt;br /&gt;
    expect(new_due_date.deadline_type_id).to eql @assignment_due_date.deadline_type_id&lt;br /&gt;
    expect(new_due_date.parent_id).to eql @assignment_due_date.parent_id&lt;br /&gt;
    expect(new_due_date.round).to eql @assignment_due_date.round&lt;br /&gt;
end&lt;br /&gt;
If the function &amp;quot;self.deadline_sort&amp;quot; is able to sort the due dates in ascending order.&lt;br /&gt;
it &amp;quot;sort duedate records&amp;quot; do&lt;br /&gt;
    sorted_due_dates = @due_dates&lt;br /&gt;
    expect(sorted_due_dates.each_cons(2).all?{|m1, m2| (m1.due_at &amp;lt;=&amp;gt; m2.due_at) != 1}).to eql false&lt;br /&gt;
&lt;br /&gt;
    sorted_due_dates = DueDate.deadline_sort(@due_dates)&lt;br /&gt;
    expect(sorted_due_dates.each_cons(2).all?{|m1, m2| (m1.due_at &amp;lt;=&amp;gt; m2.due_at) != 1}).to eql true&lt;br /&gt;
end&lt;br /&gt;
If the function &amp;quot;self.done_in_assignment_round&amp;quot; returns the correct number of rounds for specific inputs. This involves an invalid test case as well for 0 rounds.&lt;br /&gt;
describe &amp;quot;#done_in_assignment_round&amp;quot; do&lt;br /&gt;
    it &amp;quot;return 0 when no response map&amp;quot; do&lt;br /&gt;
      response = ReviewResponseMap.create&lt;br /&gt;
      response.type = &amp;quot;ResponseMap&amp;quot;&lt;br /&gt;
      response.save&lt;br /&gt;
      expect(DueDate.done_in_assignment_round(1, response)).to eql 0&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    it &amp;quot;return round 1 for single round&amp;quot; do&lt;br /&gt;
      response = ReviewResponseMap.create&lt;br /&gt;
      expect(DueDate.done_in_assignment_round(@assignment_due_date.parent_id, response)).to eql 1&lt;br /&gt;
    end&lt;br /&gt;
end&lt;br /&gt;
If the function &amp;quot;self.get_next_due_date&amp;quot; works as expected. This involves several invalid test cases as well.&lt;br /&gt;
describe &amp;quot;#get_next_due_date&amp;quot; do&lt;br /&gt;
    it &amp;quot;no subsequent due date&amp;quot; do&lt;br /&gt;
      expect(DueDate.get_next_due_date(@assignment_due_date.parent_id)).to be nil&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    it &amp;quot;nil value throws exception&amp;quot; do&lt;br /&gt;
      expect { DueDate.get_next_due_date(nil) }.to raise_exception(ActiveRecord::RecordNotFound)&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    it &amp;quot;get next assignment due date&amp;quot; do&lt;br /&gt;
      due_date = create(:assignment_due_date, deadline_type: @deadline_type,&lt;br /&gt;
        submission_allowed_id: @deadline_right.id, review_allowed_id: @deadline_right.id,&lt;br /&gt;
        review_of_review_allowed_id: @deadline_right.id, due_at: Time.zone.now + 5000)&lt;br /&gt;
      expect(DueDate.get_next_due_date(due_date.parent_id)).to be_valid&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    it &amp;quot;get next due date from topic for staggered deadline&amp;quot; do&lt;br /&gt;
      assignment_id = create(:assignment, staggered_deadline: true, name: &amp;quot;testassignment&amp;quot;).id&lt;br /&gt;
      due_date = create(:topic_due_date, deadline_type: @deadline_type,&lt;br /&gt;
        submission_allowed_id: @deadline_right.id, review_allowed_id: @deadline_right.id,&lt;br /&gt;
        review_of_review_allowed_id: @deadline_right.id, due_at: Time.zone.now + 5000, parent_id: assignment_id)&lt;br /&gt;
      expect(DueDate.get_next_due_date(assignment_id, due_date.parent_id)).to be_valid&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    it &amp;quot;next due date does not exist for staggered deadline&amp;quot; do&lt;br /&gt;
      assignment_id = create(:assignment, staggered_deadline: true, name: &amp;quot;testassignment&amp;quot;).id&lt;br /&gt;
      due_date = create(:topic_due_date, deadline_type: @deadline_type,&lt;br /&gt;
        submission_allowed_id: @deadline_right, review_allowed_id: @deadline_right,&lt;br /&gt;
        review_of_review_allowed_id: @deadline_right, due_at: Time.zone.now + 5000, parent_id: assignment_id)&lt;br /&gt;
      expect(DueDate.get_next_due_date(assignment_id)).to be nil&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    it &amp;quot;next due date is before Time.now for staggered deadline&amp;quot; do&lt;br /&gt;
      assignment_id = create(:assignment, staggered_deadline: true, name: &amp;quot;testassignment&amp;quot;).id&lt;br /&gt;
      due_date = create(:topic_due_date, deadline_type: @deadline_type,&lt;br /&gt;
        submission_allowed_id: @deadline_right, review_allowed_id: @deadline_right,&lt;br /&gt;
        review_of_review_allowed_id: @deadline_right, due_at: Time.zone.now - 5000, parent_id: assignment_id)&lt;br /&gt;
      expect(DueDate.get_next_due_date(assignment_id, due_date.parent_id)).to be nil&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    it &amp;quot;get next due date from assignment for staggered deadline&amp;quot; do&lt;br /&gt;
      assignment_id = create(:assignment, staggered_deadline: true, name: &amp;quot;testassignment&amp;quot;).id&lt;br /&gt;
      due_date = create(:assignment_due_date, deadline_type: @deadline_type,&lt;br /&gt;
        submission_allowed_id: @deadline_right, review_allowed_id: @deadline_right,&lt;br /&gt;
        review_of_review_allowed_id: @deadline_right, due_at: Time.zone.now + 5000, parent_id: assignment_id)&lt;br /&gt;
      expect(DueDate.get_next_due_date(assignment_id)).to be_valid&lt;br /&gt;
    end&lt;br /&gt;
end&lt;br /&gt;
If the function &amp;quot;self.default_permission&amp;quot; returns the correct default permissions for particular deadline and permission types.&lt;br /&gt;
it &amp;quot;metareview review_of_review_allowed default permission OK&amp;quot; do&lt;br /&gt;
    expect(DueDate.default_permission('metareview', 'review_of_review_allowed')).to be == DeadlineRight::OK&lt;br /&gt;
end&lt;br /&gt;
it &amp;quot;review submission_allowed default permission NO&amp;quot; do&lt;br /&gt;
    expect(DueDate.default_permission('review', 'submission_allowed')).to be == DeadlineRight::NO&lt;br /&gt;
end&lt;br /&gt;
To test this file run the following command:&lt;br /&gt;
&lt;br /&gt;
rspec spec/models/due_date_spec.rb&lt;br /&gt;
The output of this RSpec file is present in below screenshot:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Code coverage details of the above RSpec files is present in below screenshot:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Code coverage details of the above RSpec files is present in below screenshot:&lt;br /&gt;
&lt;br /&gt;
deadline_helper_spec.rb&lt;br /&gt;
This is a test file for testing the functionalities of Deadline_helper.rb file located at app/helpers. Different test cases present in this file are:&lt;br /&gt;
&lt;br /&gt;
Check if the factory is valid:&lt;br /&gt;
it &amp;quot;has a valid factory&amp;quot; do&lt;br /&gt;
    factory = FactoryGirl.build(:topic_due_date)&lt;br /&gt;
    expect(factory).to be_valid&lt;br /&gt;
end&lt;br /&gt;
Fail if the due date is invalid:&lt;br /&gt;
it &amp;quot;should fail because of invalid due_date&amp;quot; do&lt;br /&gt;
      expect { DeadlineHelper.create_topic_deadline(nil, 0, 0)}.to raise_exception(NoMethodError)&lt;br /&gt;
end&lt;br /&gt;
If new due_date object is created:&lt;br /&gt;
it &amp;quot;new due_date object created&amp;quot; do&lt;br /&gt;
      DeadlineHelper.create_topic_deadline(@topic_due_date, 0, 1)&lt;br /&gt;
      expect(TopicDueDate.count).to be == 2&lt;br /&gt;
end&lt;br /&gt;
due_at should be same for 0 offset:&lt;br /&gt;
 it &amp;quot;due_at should be same for 0 offset&amp;quot; do&lt;br /&gt;
      DeadlineHelper.create_topic_deadline(@topic_due_date, 0, 10)&lt;br /&gt;
      new_due_date = TopicDueDate.find_by(parent_id: 10)&lt;br /&gt;
      expect(new_due_date).to be_valid&lt;br /&gt;
      expect(new_due_date.due_at.to_s).to be == @topic_due_date.due_at.to_s&lt;br /&gt;
end&lt;br /&gt;
due_at is calculated correctly if offset is positive:&lt;br /&gt;
it &amp;quot;due_at calculated correctly for positive offset&amp;quot; do&lt;br /&gt;
      DeadlineHelper.create_topic_deadline(@topic_due_date, 5000, 10)&lt;br /&gt;
      new_due_date = TopicDueDate.find_by(parent_id: 10)&lt;br /&gt;
      expect(new_due_date).to be_valid&lt;br /&gt;
      expect(new_due_date.due_at.to_s).to be == (Time.zone.parse(@topic_due_date.due_at.to_s) + 5000).to_s&lt;br /&gt;
end&lt;br /&gt;
due_at is calculated correctly if offset is negative:&lt;br /&gt;
it &amp;quot;due_at calculated correctly for negative offset&amp;quot; do&lt;br /&gt;
      DeadlineHelper.create_topic_deadline(@topic_due_date, -5000, 10)&lt;br /&gt;
      new_due_date = TopicDueDate.find_by(parent_id: 10)&lt;br /&gt;
      expect(new_due_date).to be_valid&lt;br /&gt;
      expect(new_due_date.due_at.to_s).to be == (Time.zone.parse(@topic_due_date.due_at.to_s) - 5000).to_s&lt;br /&gt;
end&lt;br /&gt;
The offset is being converted to integer properly:&lt;br /&gt;
it &amp;quot;offset converted to integer correctly&amp;quot; do&lt;br /&gt;
      DeadlineHelper.create_topic_deadline(@topic_due_date, 5000.15, 10)&lt;br /&gt;
      new_due_date = TopicDueDate.find_by(parent_id: 10)&lt;br /&gt;
      expect(new_due_date).to be_valid&lt;br /&gt;
      expect(new_due_date.due_at.to_s).to be == (Time.zone.parse(@topic_due_date.due_at.to_s) + 5000).to_s&lt;br /&gt;
end&lt;br /&gt;
To test this file run the following command:&lt;br /&gt;
&lt;br /&gt;
rspec spec/models/deadline_helper_spec.rb&lt;br /&gt;
The output of this RSpec file is present in below screenshot:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Code coverage details of the above RSpec files is present in below screenshot:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
References&lt;br /&gt;
&amp;quot;Log in to your Code Climate dashboard with GitHub or your email.&amp;quot;. codeclimate.com. Retrieved 2016-10-28.&lt;/div&gt;</summary>
		<author><name>Nthanik</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2016/E1634.Refactor_and_write_unit_test_of_due_date.rb_and_deadline_helper.rb&amp;diff=103366</id>
		<title>CSC/ECE 517 Fall 2016/E1634.Refactor and write unit test of due date.rb and deadline helper.rb</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2016/E1634.Refactor_and_write_unit_test_of_due_date.rb_and_deadline_helper.rb&amp;diff=103366"/>
		<updated>2016-10-29T00:01:22Z</updated>

		<summary type="html">&lt;p&gt;Nthanik: Undo revision 103200 by Nthanik (talk)&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== '''Introduction''' ==&lt;br /&gt;
&lt;br /&gt;
=== Expertiza ===&lt;br /&gt;
Expertiza is an open source project for school assignment management for instructors and students based on the Ruby on Rails framework. Expertiza allows the instructor to create new assignments and customise new or existing assignments. It also allows the instructor to create a list of topics the students can sign up for. Students can form teams in Expertiza to work on various projects and assignments. Students can also peer review other students' submissions. Expertiza supports submission across various document types, including the URLs and word documents. Expertiza provides a dashboard for all the assignments corresponding to a course and provides absolute control to the Instructors and Teaching Assistants. In addition to assignments, it encompasses peer reviews wherein participants are allowed to provide feedback anonymously about each other's work thereby providing scope for the better outcome. The due_date.rb file is responsible for informing the users about the deadline for submission of the each assignment. Due dates in Expertiza have their association with many other components like assignments, reviews etc.&lt;br /&gt;
&lt;br /&gt;
=== Code Climate ===&lt;br /&gt;
Code Climate&amp;lt;ref&amp;gt;{{Cite web|url=https://codeclimate.com/dashboard|title=Log in to your Code Climate dashboard with GitHub or your email.|website=codeclimate.com|access-date=2016-10-28}}&amp;lt;/ref&amp;gt; is a tool that runs static analysis on a GitHub project and outputs many details like test coverage, complexity, duplication, security, style, and more. There is a Google Chrome extension to integrate the Code Climate results generated directly into GitHub which is visible when browsing the repository on the browser. It allows us to see issues displayed directly inside GitHub's UI, to review which lines are covered in diffs and files, and add repositories and open tickets without changing your workflow.&lt;br /&gt;
&lt;br /&gt;
== '''Tasks Identified''' ==&lt;br /&gt;
To install Code climate Chrome Extension that highlights the duplicated code.&lt;br /&gt;
&lt;br /&gt;
To refactor the following two files:&lt;br /&gt;
* Due_date.rb&lt;br /&gt;
** Ternary operators must not be nested. Prefer `if` or `else` constructs instead.&lt;br /&gt;
** Useless assignment to variable - `sorted_deadlines`.&lt;br /&gt;
** Prefer `each` over `for`.&lt;br /&gt;
** Use `find_by` instead of `where.first`.&lt;br /&gt;
** Correct the use of Time function&lt;br /&gt;
* Deadline_helper.rb&lt;br /&gt;
** Do not use `Time.now` without zone. Use one of `Time.zone.now`, `Time.current`, `Time.now.in_time_zone`, `Time.now.utc`, `Time.now.getlocal`, `Time.now.iso8601`, `Time.now.jisx0301`, `Time.now.rfc3339`, `Time.now.to_i`, `Time.now.to_f` instead.&lt;br /&gt;
** Trailing whitespace detected.&lt;br /&gt;
** Extra empty line detected at module body end.&lt;br /&gt;
&lt;br /&gt;
* Create respective RSpec files in /spec/models/ and /spec/helper folder and write unit tests for each method in due_date.rb and deadline_helper.rb.&lt;br /&gt;
&lt;br /&gt;
== '''Current Implementation''' ==&lt;br /&gt;
DueDate is a Model class to manage the deadlines of an assignment. It has methods for setting due dates for an assignment, copying due dates from one assignment to a new assignment etc. DeadlineHelper provides helper functions that help DueDate perform certain tasks. The assignment focuses on refactoring some of the methods based on warnings received from Code Climate's static analysis and modifying the language to make it more Ruby-friendly. The assignment also involves writing unit test cases for due_date.rb and deadline_helper.rb in order to increase test coverage. &lt;br /&gt;
&lt;br /&gt;
The goal of this project is to attempt to make this part of the application easier to read and write unit test cases that the application must pass. &lt;br /&gt;
&lt;br /&gt;
== '''Changed Implementation''' ==&lt;br /&gt;
Changes implemented involves refactoring the code and making it more understandable by adding comments in the code.&lt;br /&gt;
&lt;br /&gt;
The modified files are&lt;br /&gt;
* Due_date.rb (path: /app/models)&lt;br /&gt;
&lt;br /&gt;
* Deadline_helper.rb (path: /app/helpers)&lt;br /&gt;
Testing files&lt;br /&gt;
* Due_date_spec.rb (path: /spec/models)&lt;br /&gt;
* Deadline_helper_spec.rb (path: /spec/helpers)&lt;br /&gt;
=== Due_date.rb ===&lt;br /&gt;
* Converted for..in loop to object.each in order to follow better Ruby syntax.&lt;br /&gt;
* Unnecessary assignment to sorted_deadlines removed.&lt;br /&gt;
* Nested ternary operators have been changed to if..else in order to make it more readable.&lt;br /&gt;
**[[File:Duedaterb.png|thumb|Due_date.rb|center|500x500px]]&lt;br /&gt;
* Changed where(...).first to find_by(...) which is the newer recommended syntax.&lt;br /&gt;
* Corrected the Time.now functions by adding the correct zones to them such as Time.zone.now.&lt;br /&gt;
* Removed trailing whitespaces.[[File:DueDaterb2.png|center|thumb|565x565px]]&lt;br /&gt;
&lt;br /&gt;
=== Deadline_helper.rb ===&lt;br /&gt;
* Time functions were changed to functions with zones&lt;br /&gt;
* Extra line removed&lt;br /&gt;
[[File:Deadlinehelper.png|center|thumb|631x631px|Deadline_helper]]&lt;br /&gt;
&lt;br /&gt;
== '''RSpec testing''' ==&lt;br /&gt;
There were no existing tests for the functions in due_date.rb and deadline_helper.rb. We have added exhaustive set of RSpec tests to test all the code. We have added two new spec files 'due_date_spec.rb' and ‘deadline_helper_spec.rb’ which cover the testing scenarios for the functions in ‘due_date.rb’ and ‘deadline_helper.rb’.&lt;br /&gt;
&lt;br /&gt;
These RSpec files have 100% code coverage visible at: /coverage/index.html&lt;br /&gt;
&lt;br /&gt;
=== due_date_spec.rb ===&lt;br /&gt;
This file is located at spec/models and tests the functionalities of the due_date.rb file located in app/models. There are 18 test cases in total which are listed below.&lt;br /&gt;
* If the factory is successfully able to build the due_date objects.&amp;lt;syntaxhighlight lang=&amp;quot;ruby&amp;quot;&amp;gt;&lt;br /&gt;
it &amp;quot;due date factory created successfully&amp;quot; do&lt;br /&gt;
    expect(@assignment_due_date).to be_valid&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&amp;lt;syntaxhighlight lang=&amp;quot;ruby&amp;quot;&amp;gt;&lt;br /&gt;
it &amp;quot;due dates created correctly&amp;quot; do&lt;br /&gt;
    expect(@due_dates.length).to be == 10&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
* If the function &amp;quot;set_flag&amp;quot; successfully sets the due_date flag.&amp;lt;syntaxhighlight lang=&amp;quot;ruby&amp;quot;&amp;gt;&lt;br /&gt;
it &amp;quot;due date flag is set&amp;quot; do&lt;br /&gt;
    expect(@assignment_due_date.flag).to be false&lt;br /&gt;
    @assignment_due_date.set_flag&lt;br /&gt;
    expect(@assignment_due_date.flag).to be true&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
* If the function &amp;quot;due_at_is_valid_datetime&amp;quot; returns nil (no errors) for a valid datetime in due_at (no invalid test cases can be added here because model does not allow invalid datetime to be set at all).&amp;lt;syntaxhighlight lang=&amp;quot;ruby&amp;quot;&amp;gt;&lt;br /&gt;
it &amp;quot;due at is valid datetime&amp;quot; do&lt;br /&gt;
    expect(@assignment_due_date.due_at_is_valid_datetime).to be nil&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
* If the function &amp;quot;self.copy&amp;quot; is able to copy due dates from one assignment to another.&amp;lt;syntaxhighlight lang=&amp;quot;ruby&amp;quot;&amp;gt;&lt;br /&gt;
it &amp;quot;copy due dates to new assignment&amp;quot; do&lt;br /&gt;
    new_assignment_id = build(:assignment, id: 999).id&lt;br /&gt;
    old_assignment_id = @assignment_due_date.assignment.id&lt;br /&gt;
    DueDate.copy(old_assignment_id, new_assignment_id)&lt;br /&gt;
    expect(DueDate.where(parent_id: new_assignment_id).count).to eql DueDate.where(parent_id: old_assignment_id).count&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
* If the function &amp;quot;self.set_duedate&amp;quot; is able to create another due date by copying data from an existing due date object.&amp;lt;syntaxhighlight lang=&amp;quot;ruby&amp;quot;&amp;gt;&lt;br /&gt;
it &amp;quot;create new duedate record with values&amp;quot; do&lt;br /&gt;
    DueDate.set_duedate({id: 999}, @assignment_due_date.deadline_type_id,&lt;br /&gt;
                        @assignment_due_date.parent_id, @assignment_due_date.round)&lt;br /&gt;
    new_due_date = DueDate.find_by(id: 999)&lt;br /&gt;
    expect(new_due_date).to be_valid&lt;br /&gt;
    expect(new_due_date.deadline_type_id).to eql @assignment_due_date.deadline_type_id&lt;br /&gt;
    expect(new_due_date.parent_id).to eql @assignment_due_date.parent_id&lt;br /&gt;
    expect(new_due_date.round).to eql @assignment_due_date.round&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
* If the function &amp;quot;self.deadline_sort&amp;quot; is able to sort the due dates in ascending order.&amp;lt;syntaxhighlight lang=&amp;quot;ruby&amp;quot;&amp;gt;&lt;br /&gt;
it &amp;quot;sort duedate records&amp;quot; do&lt;br /&gt;
    sorted_due_dates = @due_dates&lt;br /&gt;
    expect(sorted_due_dates.each_cons(2).all?{|m1, m2| (m1.due_at &amp;lt;=&amp;gt; m2.due_at) != 1}).to eql false&lt;br /&gt;
&lt;br /&gt;
    sorted_due_dates = DueDate.deadline_sort(@due_dates)&lt;br /&gt;
    expect(sorted_due_dates.each_cons(2).all?{|m1, m2| (m1.due_at &amp;lt;=&amp;gt; m2.due_at) != 1}).to eql true&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
* If the function &amp;quot;self.done_in_assignment_round&amp;quot; returns the correct number of rounds for specific inputs. This involves an invalid test case as well for 0 rounds.&amp;lt;syntaxhighlight lang=&amp;quot;ruby&amp;quot;&amp;gt;&lt;br /&gt;
describe &amp;quot;#done_in_assignment_round&amp;quot; do&lt;br /&gt;
    it &amp;quot;return 0 when no response map&amp;quot; do&lt;br /&gt;
      response = ReviewResponseMap.create&lt;br /&gt;
      response.type = &amp;quot;ResponseMap&amp;quot;&lt;br /&gt;
      response.save&lt;br /&gt;
      expect(DueDate.done_in_assignment_round(1, response)).to eql 0&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    it &amp;quot;return round 1 for single round&amp;quot; do&lt;br /&gt;
      response = ReviewResponseMap.create&lt;br /&gt;
      expect(DueDate.done_in_assignment_round(@assignment_due_date.parent_id, response)).to eql 1&lt;br /&gt;
    end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
* If the function &amp;quot;self.get_next_due_date&amp;quot; works as expected. This involves several invalid test cases as well.&amp;lt;syntaxhighlight lang=&amp;quot;ruby&amp;quot;&amp;gt;&lt;br /&gt;
describe &amp;quot;#get_next_due_date&amp;quot; do&lt;br /&gt;
    it &amp;quot;no subsequent due date&amp;quot; do&lt;br /&gt;
      expect(DueDate.get_next_due_date(@assignment_due_date.parent_id)).to be nil&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    it &amp;quot;nil value throws exception&amp;quot; do&lt;br /&gt;
      expect { DueDate.get_next_due_date(nil) }.to raise_exception(ActiveRecord::RecordNotFound)&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    it &amp;quot;get next assignment due date&amp;quot; do&lt;br /&gt;
      due_date = create(:assignment_due_date, deadline_type: @deadline_type,&lt;br /&gt;
        submission_allowed_id: @deadline_right.id, review_allowed_id: @deadline_right.id,&lt;br /&gt;
        review_of_review_allowed_id: @deadline_right.id, due_at: Time.zone.now + 5000)&lt;br /&gt;
      expect(DueDate.get_next_due_date(due_date.parent_id)).to be_valid&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    it &amp;quot;get next due date from topic for staggered deadline&amp;quot; do&lt;br /&gt;
      assignment_id = create(:assignment, staggered_deadline: true, name: &amp;quot;testassignment&amp;quot;).id&lt;br /&gt;
      due_date = create(:topic_due_date, deadline_type: @deadline_type,&lt;br /&gt;
        submission_allowed_id: @deadline_right.id, review_allowed_id: @deadline_right.id,&lt;br /&gt;
        review_of_review_allowed_id: @deadline_right.id, due_at: Time.zone.now + 5000, parent_id: assignment_id)&lt;br /&gt;
      expect(DueDate.get_next_due_date(assignment_id, due_date.parent_id)).to be_valid&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    it &amp;quot;next due date does not exist for staggered deadline&amp;quot; do&lt;br /&gt;
      assignment_id = create(:assignment, staggered_deadline: true, name: &amp;quot;testassignment&amp;quot;).id&lt;br /&gt;
      due_date = create(:topic_due_date, deadline_type: @deadline_type,&lt;br /&gt;
        submission_allowed_id: @deadline_right, review_allowed_id: @deadline_right,&lt;br /&gt;
        review_of_review_allowed_id: @deadline_right, due_at: Time.zone.now + 5000, parent_id: assignment_id)&lt;br /&gt;
      expect(DueDate.get_next_due_date(assignment_id)).to be nil&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    it &amp;quot;next due date is before Time.now for staggered deadline&amp;quot; do&lt;br /&gt;
      assignment_id = create(:assignment, staggered_deadline: true, name: &amp;quot;testassignment&amp;quot;).id&lt;br /&gt;
      due_date = create(:topic_due_date, deadline_type: @deadline_type,&lt;br /&gt;
        submission_allowed_id: @deadline_right, review_allowed_id: @deadline_right,&lt;br /&gt;
        review_of_review_allowed_id: @deadline_right, due_at: Time.zone.now - 5000, parent_id: assignment_id)&lt;br /&gt;
      expect(DueDate.get_next_due_date(assignment_id, due_date.parent_id)).to be nil&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    it &amp;quot;get next due date from assignment for staggered deadline&amp;quot; do&lt;br /&gt;
      assignment_id = create(:assignment, staggered_deadline: true, name: &amp;quot;testassignment&amp;quot;).id&lt;br /&gt;
      due_date = create(:assignment_due_date, deadline_type: @deadline_type,&lt;br /&gt;
        submission_allowed_id: @deadline_right, review_allowed_id: @deadline_right,&lt;br /&gt;
        review_of_review_allowed_id: @deadline_right, due_at: Time.zone.now + 5000, parent_id: assignment_id)&lt;br /&gt;
      expect(DueDate.get_next_due_date(assignment_id)).to be_valid&lt;br /&gt;
    end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
* If the function &amp;quot;self.default_permission&amp;quot; returns the correct default permissions for particular deadline and permission types.&amp;lt;syntaxhighlight lang=&amp;quot;ruby&amp;quot;&amp;gt;&lt;br /&gt;
it &amp;quot;metareview review_of_review_allowed default permission OK&amp;quot; do&lt;br /&gt;
    expect(DueDate.default_permission('metareview', 'review_of_review_allowed')).to be == DeadlineRight::OK&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&amp;lt;syntaxhighlight lang=&amp;quot;ruby&amp;quot;&amp;gt;&lt;br /&gt;
it &amp;quot;review submission_allowed default permission NO&amp;quot; do&lt;br /&gt;
    expect(DueDate.default_permission('review', 'submission_allowed')).to be == DeadlineRight::NO&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
To test this file run the following command:&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
rspec spec/models/due_date_spec.rb&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
The output of this RSpec file is present in below screenshot:&lt;br /&gt;
[[File:Duedaterspec.png|center|thumb|558x558px]]&lt;br /&gt;
&lt;br /&gt;
Code coverage details of the above RSpec files is present in below screenshot:&lt;br /&gt;
[[File:Duedatecoverage.png|center|thumb|736x736px]]&lt;br /&gt;
&lt;br /&gt;
Code coverage details of the above RSpec files is present in below screenshot:&lt;br /&gt;
&lt;br /&gt;
=== deadline_helper_spec.rb ===&lt;br /&gt;
This is a test file for testing the functionalities of Deadline_helper.rb file located at app/helpers. Different test cases present in this file are:&lt;br /&gt;
* Check if the factory is valid:  &lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;ruby&amp;quot;&amp;gt;&lt;br /&gt;
it &amp;quot;has a valid factory&amp;quot; do&lt;br /&gt;
    factory = FactoryGirl.build(:topic_due_date)&lt;br /&gt;
    expect(factory).to be_valid&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
* Fail if the due date is invalid:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;ruby&amp;quot;&amp;gt;&lt;br /&gt;
it &amp;quot;should fail because of invalid due_date&amp;quot; do&lt;br /&gt;
      expect { DeadlineHelper.create_topic_deadline(nil, 0, 0)}.to raise_exception(NoMethodError)&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
* If new due_date object is created:&amp;lt;syntaxhighlight lang=&amp;quot;ruby&amp;quot;&amp;gt;&lt;br /&gt;
it &amp;quot;new due_date object created&amp;quot; do&lt;br /&gt;
      DeadlineHelper.create_topic_deadline(@topic_due_date, 0, 1)&lt;br /&gt;
      expect(TopicDueDate.count).to be == 2&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
* due_at should be same for 0 offset:&amp;lt;syntaxhighlight lang=&amp;quot;ruby&amp;quot;&amp;gt;&lt;br /&gt;
 it &amp;quot;due_at should be same for 0 offset&amp;quot; do&lt;br /&gt;
      DeadlineHelper.create_topic_deadline(@topic_due_date, 0, 10)&lt;br /&gt;
      new_due_date = TopicDueDate.find_by(parent_id: 10)&lt;br /&gt;
      expect(new_due_date).to be_valid&lt;br /&gt;
      expect(new_due_date.due_at.to_s).to be == @topic_due_date.due_at.to_s&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
* due_at is calculated correctly if offset is positive:&amp;lt;syntaxhighlight lang=&amp;quot;ruby&amp;quot;&amp;gt;&lt;br /&gt;
it &amp;quot;due_at calculated correctly for positive offset&amp;quot; do&lt;br /&gt;
      DeadlineHelper.create_topic_deadline(@topic_due_date, 5000, 10)&lt;br /&gt;
      new_due_date = TopicDueDate.find_by(parent_id: 10)&lt;br /&gt;
      expect(new_due_date).to be_valid&lt;br /&gt;
      expect(new_due_date.due_at.to_s).to be == (Time.zone.parse(@topic_due_date.due_at.to_s) + 5000).to_s&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
* due_at is calculated correctly if offset is negative:&amp;lt;syntaxhighlight lang=&amp;quot;ruby&amp;quot;&amp;gt;&lt;br /&gt;
it &amp;quot;due_at calculated correctly for negative offset&amp;quot; do&lt;br /&gt;
      DeadlineHelper.create_topic_deadline(@topic_due_date, -5000, 10)&lt;br /&gt;
      new_due_date = TopicDueDate.find_by(parent_id: 10)&lt;br /&gt;
      expect(new_due_date).to be_valid&lt;br /&gt;
      expect(new_due_date.due_at.to_s).to be == (Time.zone.parse(@topic_due_date.due_at.to_s) - 5000).to_s&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
* The offset is being converted to integer properly:&amp;lt;syntaxhighlight lang=&amp;quot;ruby&amp;quot;&amp;gt;&lt;br /&gt;
it &amp;quot;offset converted to integer correctly&amp;quot; do&lt;br /&gt;
      DeadlineHelper.create_topic_deadline(@topic_due_date, 5000.15, 10)&lt;br /&gt;
      new_due_date = TopicDueDate.find_by(parent_id: 10)&lt;br /&gt;
      expect(new_due_date).to be_valid&lt;br /&gt;
      expect(new_due_date.due_at.to_s).to be == (Time.zone.parse(@topic_due_date.due_at.to_s) + 5000).to_s&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
To test this file run the following command:&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
rspec spec/models/deadline_helper_spec.rb&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;The output of this RSpec file is present in below screenshot:&lt;br /&gt;
[[File:Deadlinerspec.png|center|thumb|705x705px]]&lt;br /&gt;
&lt;br /&gt;
Code coverage details of the above RSpec files is present in below screenshot:&lt;br /&gt;
[[File:Deadlinecoverage.png|center|thumb|823x823px]]&lt;br /&gt;
&lt;br /&gt;
== '''References''' ==&lt;/div&gt;</summary>
		<author><name>Nthanik</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2016/E1634.Refactor_and_write_unit_test_of_due_date.rb_and_deadline_helper.rb&amp;diff=103365</id>
		<title>CSC/ECE 517 Fall 2016/E1634.Refactor and write unit test of due date.rb and deadline helper.rb</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2016/E1634.Refactor_and_write_unit_test_of_due_date.rb_and_deadline_helper.rb&amp;diff=103365"/>
		<updated>2016-10-29T00:01:12Z</updated>

		<summary type="html">&lt;p&gt;Nthanik: Undo revision 103202 by Nthanik (talk)&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== '''Introduction''' ==&lt;br /&gt;
&lt;br /&gt;
=== Expertiza ===&lt;br /&gt;
Expertiza is an open source project for school assignment management for instructors and students based on the Ruby on Rails framework. Expertiza allows the instructor to create new assignments and customise new or existing assignments. It also allows the instructor to create a list of topics the students can sign up for. Students can form teams in Expertiza to work on various projects and assignments. Students can also peer review other students' submissions. Expertiza supports submission across various document types, including the URLs and word documents. Expertiza provides a dashboard for all the assignments corresponding to a course and provides absolute control to the Instructors and Teaching Assistants. In addition to assignments, it encompasses peer reviews wherein participants are allowed to provide feedback anonymously about each other's work thereby providing scope for the better outcome. The due_date.rb file is responsible for informing the users about the deadline for submission of the each assignment. Due dates in Expertiza have their association with many other components like assignments, reviews etc.&lt;br /&gt;
&lt;br /&gt;
=== Code Climate ===&lt;br /&gt;
Code Climate&amp;lt;ref&amp;gt;{{Cite web|url=https://codeclimate.com/dashboard|title=Log in to your Code Climate dashboard with GitHub or your email.|website=codeclimate.com|access-date=2016-10-28}}&amp;lt;/ref&amp;gt; is a tool that runs static analysis on a GitHub project and outputs many details like test coverage, complexity, duplication, security, style, and more. There is a Google Chrome extension to integrate the Code Climate results generated directly into GitHub which is visible when browsing the repository on the browser. It allows us to see issues displayed directly inside GitHub's UI, to review which lines are covered in diffs and files, and add repositories and open tickets without changing your workflow.&lt;br /&gt;
&lt;br /&gt;
== '''Tasks Identified''' ==&lt;br /&gt;
To install Code climate Chrome Extension that highlights the duplicated code.&lt;br /&gt;
&lt;br /&gt;
To refactor the following two files:&lt;br /&gt;
* Due_date.rb&lt;br /&gt;
** Ternary operators must not be nested. Prefer `if` or `else` constructs instead.&lt;br /&gt;
** Useless assignment to variable - `sorted_deadlines`.&lt;br /&gt;
** Prefer `each` over `for`.&lt;br /&gt;
** Use `find_by` instead of `where.first`.&lt;br /&gt;
** Correct the use of Time function&lt;br /&gt;
* Deadline_helper.rb&lt;br /&gt;
** Do not use `Time.now` without zone. Use one of `Time.zone.now`, `Time.current`, `Time.now.in_time_zone`, `Time.now.utc`, `Time.now.getlocal`, `Time.now.iso8601`, `Time.now.jisx0301`, `Time.now.rfc3339`, `Time.now.to_i`, `Time.now.to_f` instead.&lt;br /&gt;
** Trailing whitespace detected.&lt;br /&gt;
** Extra empty line detected at module body end.&lt;br /&gt;
&lt;br /&gt;
* Create respective RSpec files in /spec/models/ and /spec/helper folder and write unit tests for each method in due_date.rb and deadline_helper.rb.&lt;br /&gt;
&lt;br /&gt;
== '''Current Implementation''' ==&lt;br /&gt;
DueDate is a Model class to manage the deadlines of an assignment. It has methods for setting due dates for an assignment, copying due dates from one assignment to a new assignment etc. DeadlineHelper provides helper functions that help DueDate perform certain tasks. The assignment focuses on refactoring some of the methods based on warnings received from Code Climate's static analysis and modifying the language to make it more Ruby-friendly. The assignment also involves writing unit test cases for due_date.rb and deadline_helper.rb in order to increase test coverage. &lt;br /&gt;
&lt;br /&gt;
The goal of this project is to attempt to make this part of the application easier to read and write unit test cases that the application must pass. &lt;br /&gt;
&lt;br /&gt;
== '''Changed Implementation''' ==&lt;br /&gt;
Changes implemented involves refactoring the code and making it more understandable by adding comments in the code.&lt;br /&gt;
&lt;br /&gt;
The modified files are&lt;br /&gt;
* Due_date.rb (path: /app/models)&lt;br /&gt;
&lt;br /&gt;
* Deadline_helper.rb (path: /app/helpers)&lt;br /&gt;
Testing files&lt;br /&gt;
* Due_date_spec.rb (path: /spec/models)&lt;br /&gt;
* Deadline_helper_spec.rb (path: /spec/helpers)&lt;br /&gt;
=== Due_date.rb ===&lt;br /&gt;
* Converted for..in loop to object.each in order to follow better Ruby syntax.&lt;br /&gt;
* Unnecessary assignment to sorted_deadlines removed.&lt;br /&gt;
* Nested ternary operators have been changed to if..else in order to make it more readable.&lt;br /&gt;
[[File:Duedaterb.png]]&lt;br /&gt;
* Changed where(...).first to find_by(...) which is the newer recommended syntax.&lt;br /&gt;
* Corrected the Time.now functions by adding the correct zones to them such as Time.zone.now.&lt;br /&gt;
* Removed trailing whitespaces.&lt;br /&gt;
[[File:DueDaterb2.png]]&lt;br /&gt;
&lt;br /&gt;
=== Deadline_helper.rb ===&lt;br /&gt;
* Time functions were changed to functions with zones&lt;br /&gt;
* Extra line removed&lt;br /&gt;
[[File:Deadlinehelper.png]]&lt;br /&gt;
&lt;br /&gt;
== '''RSpec testing''' ==&lt;br /&gt;
There were no existing tests for the functions in due_date.rb and deadline_helper.rb. We have added exhaustive set of RSpec tests to test all the code. We have added two new spec files 'due_date_spec.rb' and ‘deadline_helper_spec.rb’ which cover the testing scenarios for the functions in ‘due_date.rb’ and ‘deadline_helper.rb’.&lt;br /&gt;
&lt;br /&gt;
These RSpec files have 100% code coverage visible at: /coverage/index.html&lt;br /&gt;
&lt;br /&gt;
=== due_date_spec.rb ===&lt;br /&gt;
This file is located at spec/models and tests the functionalities of the due_date.rb file located in app/models. There are 18 test cases in total which are listed below.&lt;br /&gt;
* If the factory is successfully able to build the due_date objects.&amp;lt;syntaxhighlight lang=&amp;quot;ruby&amp;quot;&amp;gt;&lt;br /&gt;
it &amp;quot;due date factory created successfully&amp;quot; do&lt;br /&gt;
    expect(@assignment_due_date).to be_valid&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&amp;lt;syntaxhighlight lang=&amp;quot;ruby&amp;quot;&amp;gt;&lt;br /&gt;
it &amp;quot;due dates created correctly&amp;quot; do&lt;br /&gt;
    expect(@due_dates.length).to be == 10&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
* If the function &amp;quot;set_flag&amp;quot; successfully sets the due_date flag.&amp;lt;syntaxhighlight lang=&amp;quot;ruby&amp;quot;&amp;gt;&lt;br /&gt;
it &amp;quot;due date flag is set&amp;quot; do&lt;br /&gt;
    expect(@assignment_due_date.flag).to be false&lt;br /&gt;
    @assignment_due_date.set_flag&lt;br /&gt;
    expect(@assignment_due_date.flag).to be true&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
* If the function &amp;quot;due_at_is_valid_datetime&amp;quot; returns nil (no errors) for a valid datetime in due_at (no invalid test cases can be added here because model does not allow invalid datetime to be set at all).&amp;lt;syntaxhighlight lang=&amp;quot;ruby&amp;quot;&amp;gt;&lt;br /&gt;
it &amp;quot;due at is valid datetime&amp;quot; do&lt;br /&gt;
    expect(@assignment_due_date.due_at_is_valid_datetime).to be nil&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
* If the function &amp;quot;self.copy&amp;quot; is able to copy due dates from one assignment to another.&amp;lt;syntaxhighlight lang=&amp;quot;ruby&amp;quot;&amp;gt;&lt;br /&gt;
it &amp;quot;copy due dates to new assignment&amp;quot; do&lt;br /&gt;
    new_assignment_id = build(:assignment, id: 999).id&lt;br /&gt;
    old_assignment_id = @assignment_due_date.assignment.id&lt;br /&gt;
    DueDate.copy(old_assignment_id, new_assignment_id)&lt;br /&gt;
    expect(DueDate.where(parent_id: new_assignment_id).count).to eql DueDate.where(parent_id: old_assignment_id).count&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
* If the function &amp;quot;self.set_duedate&amp;quot; is able to create another due date by copying data from an existing due date object.&amp;lt;syntaxhighlight lang=&amp;quot;ruby&amp;quot;&amp;gt;&lt;br /&gt;
it &amp;quot;create new duedate record with values&amp;quot; do&lt;br /&gt;
    DueDate.set_duedate({id: 999}, @assignment_due_date.deadline_type_id,&lt;br /&gt;
                        @assignment_due_date.parent_id, @assignment_due_date.round)&lt;br /&gt;
    new_due_date = DueDate.find_by(id: 999)&lt;br /&gt;
    expect(new_due_date).to be_valid&lt;br /&gt;
    expect(new_due_date.deadline_type_id).to eql @assignment_due_date.deadline_type_id&lt;br /&gt;
    expect(new_due_date.parent_id).to eql @assignment_due_date.parent_id&lt;br /&gt;
    expect(new_due_date.round).to eql @assignment_due_date.round&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
* If the function &amp;quot;self.deadline_sort&amp;quot; is able to sort the due dates in ascending order.&amp;lt;syntaxhighlight lang=&amp;quot;ruby&amp;quot;&amp;gt;&lt;br /&gt;
it &amp;quot;sort duedate records&amp;quot; do&lt;br /&gt;
    sorted_due_dates = @due_dates&lt;br /&gt;
    expect(sorted_due_dates.each_cons(2).all?{|m1, m2| (m1.due_at &amp;lt;=&amp;gt; m2.due_at) != 1}).to eql false&lt;br /&gt;
&lt;br /&gt;
    sorted_due_dates = DueDate.deadline_sort(@due_dates)&lt;br /&gt;
    expect(sorted_due_dates.each_cons(2).all?{|m1, m2| (m1.due_at &amp;lt;=&amp;gt; m2.due_at) != 1}).to eql true&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
* If the function &amp;quot;self.done_in_assignment_round&amp;quot; returns the correct number of rounds for specific inputs. This involves an invalid test case as well for 0 rounds.&amp;lt;syntaxhighlight lang=&amp;quot;ruby&amp;quot;&amp;gt;&lt;br /&gt;
describe &amp;quot;#done_in_assignment_round&amp;quot; do&lt;br /&gt;
    it &amp;quot;return 0 when no response map&amp;quot; do&lt;br /&gt;
      response = ReviewResponseMap.create&lt;br /&gt;
      response.type = &amp;quot;ResponseMap&amp;quot;&lt;br /&gt;
      response.save&lt;br /&gt;
      expect(DueDate.done_in_assignment_round(1, response)).to eql 0&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    it &amp;quot;return round 1 for single round&amp;quot; do&lt;br /&gt;
      response = ReviewResponseMap.create&lt;br /&gt;
      expect(DueDate.done_in_assignment_round(@assignment_due_date.parent_id, response)).to eql 1&lt;br /&gt;
    end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
* If the function &amp;quot;self.get_next_due_date&amp;quot; works as expected. This involves several invalid test cases as well.&amp;lt;syntaxhighlight lang=&amp;quot;ruby&amp;quot;&amp;gt;&lt;br /&gt;
describe &amp;quot;#get_next_due_date&amp;quot; do&lt;br /&gt;
    it &amp;quot;no subsequent due date&amp;quot; do&lt;br /&gt;
      expect(DueDate.get_next_due_date(@assignment_due_date.parent_id)).to be nil&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    it &amp;quot;nil value throws exception&amp;quot; do&lt;br /&gt;
      expect { DueDate.get_next_due_date(nil) }.to raise_exception(ActiveRecord::RecordNotFound)&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    it &amp;quot;get next assignment due date&amp;quot; do&lt;br /&gt;
      due_date = create(:assignment_due_date, deadline_type: @deadline_type,&lt;br /&gt;
        submission_allowed_id: @deadline_right.id, review_allowed_id: @deadline_right.id,&lt;br /&gt;
        review_of_review_allowed_id: @deadline_right.id, due_at: Time.zone.now + 5000)&lt;br /&gt;
      expect(DueDate.get_next_due_date(due_date.parent_id)).to be_valid&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    it &amp;quot;get next due date from topic for staggered deadline&amp;quot; do&lt;br /&gt;
      assignment_id = create(:assignment, staggered_deadline: true, name: &amp;quot;testassignment&amp;quot;).id&lt;br /&gt;
      due_date = create(:topic_due_date, deadline_type: @deadline_type,&lt;br /&gt;
        submission_allowed_id: @deadline_right.id, review_allowed_id: @deadline_right.id,&lt;br /&gt;
        review_of_review_allowed_id: @deadline_right.id, due_at: Time.zone.now + 5000, parent_id: assignment_id)&lt;br /&gt;
      expect(DueDate.get_next_due_date(assignment_id, due_date.parent_id)).to be_valid&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    it &amp;quot;next due date does not exist for staggered deadline&amp;quot; do&lt;br /&gt;
      assignment_id = create(:assignment, staggered_deadline: true, name: &amp;quot;testassignment&amp;quot;).id&lt;br /&gt;
      due_date = create(:topic_due_date, deadline_type: @deadline_type,&lt;br /&gt;
        submission_allowed_id: @deadline_right, review_allowed_id: @deadline_right,&lt;br /&gt;
        review_of_review_allowed_id: @deadline_right, due_at: Time.zone.now + 5000, parent_id: assignment_id)&lt;br /&gt;
      expect(DueDate.get_next_due_date(assignment_id)).to be nil&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    it &amp;quot;next due date is before Time.now for staggered deadline&amp;quot; do&lt;br /&gt;
      assignment_id = create(:assignment, staggered_deadline: true, name: &amp;quot;testassignment&amp;quot;).id&lt;br /&gt;
      due_date = create(:topic_due_date, deadline_type: @deadline_type,&lt;br /&gt;
        submission_allowed_id: @deadline_right, review_allowed_id: @deadline_right,&lt;br /&gt;
        review_of_review_allowed_id: @deadline_right, due_at: Time.zone.now - 5000, parent_id: assignment_id)&lt;br /&gt;
      expect(DueDate.get_next_due_date(assignment_id, due_date.parent_id)).to be nil&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    it &amp;quot;get next due date from assignment for staggered deadline&amp;quot; do&lt;br /&gt;
      assignment_id = create(:assignment, staggered_deadline: true, name: &amp;quot;testassignment&amp;quot;).id&lt;br /&gt;
      due_date = create(:assignment_due_date, deadline_type: @deadline_type,&lt;br /&gt;
        submission_allowed_id: @deadline_right, review_allowed_id: @deadline_right,&lt;br /&gt;
        review_of_review_allowed_id: @deadline_right, due_at: Time.zone.now + 5000, parent_id: assignment_id)&lt;br /&gt;
      expect(DueDate.get_next_due_date(assignment_id)).to be_valid&lt;br /&gt;
    end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
* If the function &amp;quot;self.default_permission&amp;quot; returns the correct default permissions for particular deadline and permission types.&amp;lt;syntaxhighlight lang=&amp;quot;ruby&amp;quot;&amp;gt;&lt;br /&gt;
it &amp;quot;metareview review_of_review_allowed default permission OK&amp;quot; do&lt;br /&gt;
    expect(DueDate.default_permission('metareview', 'review_of_review_allowed')).to be == DeadlineRight::OK&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&amp;lt;syntaxhighlight lang=&amp;quot;ruby&amp;quot;&amp;gt;&lt;br /&gt;
it &amp;quot;review submission_allowed default permission NO&amp;quot; do&lt;br /&gt;
    expect(DueDate.default_permission('review', 'submission_allowed')).to be == DeadlineRight::NO&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
To test this file run the following command:&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
rspec spec/models/due_date_spec.rb&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
The output of this RSpec file is present in below screenshot:&lt;br /&gt;
[[File:Duedaterspec.png|center|thumb|558x558px]]&lt;br /&gt;
&lt;br /&gt;
Code coverage details of the above RSpec files is present in below screenshot:&lt;br /&gt;
[[File:Duedatecoverage.png|center|thumb|736x736px]]&lt;br /&gt;
&lt;br /&gt;
Code coverage details of the above RSpec files is present in below screenshot:&lt;br /&gt;
&lt;br /&gt;
=== deadline_helper_spec.rb ===&lt;br /&gt;
This is a test file for testing the functionalities of Deadline_helper.rb file located at app/helpers. Different test cases present in this file are:&lt;br /&gt;
* Check if the factory is valid:  &lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;ruby&amp;quot;&amp;gt;&lt;br /&gt;
it &amp;quot;has a valid factory&amp;quot; do&lt;br /&gt;
    factory = FactoryGirl.build(:topic_due_date)&lt;br /&gt;
    expect(factory).to be_valid&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
* Fail if the due date is invalid:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;ruby&amp;quot;&amp;gt;&lt;br /&gt;
it &amp;quot;should fail because of invalid due_date&amp;quot; do&lt;br /&gt;
      expect { DeadlineHelper.create_topic_deadline(nil, 0, 0)}.to raise_exception(NoMethodError)&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
* If new due_date object is created:&amp;lt;syntaxhighlight lang=&amp;quot;ruby&amp;quot;&amp;gt;&lt;br /&gt;
it &amp;quot;new due_date object created&amp;quot; do&lt;br /&gt;
      DeadlineHelper.create_topic_deadline(@topic_due_date, 0, 1)&lt;br /&gt;
      expect(TopicDueDate.count).to be == 2&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
* due_at should be same for 0 offset:&amp;lt;syntaxhighlight lang=&amp;quot;ruby&amp;quot;&amp;gt;&lt;br /&gt;
 it &amp;quot;due_at should be same for 0 offset&amp;quot; do&lt;br /&gt;
      DeadlineHelper.create_topic_deadline(@topic_due_date, 0, 10)&lt;br /&gt;
      new_due_date = TopicDueDate.find_by(parent_id: 10)&lt;br /&gt;
      expect(new_due_date).to be_valid&lt;br /&gt;
      expect(new_due_date.due_at.to_s).to be == @topic_due_date.due_at.to_s&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
* due_at is calculated correctly if offset is positive:&amp;lt;syntaxhighlight lang=&amp;quot;ruby&amp;quot;&amp;gt;&lt;br /&gt;
it &amp;quot;due_at calculated correctly for positive offset&amp;quot; do&lt;br /&gt;
      DeadlineHelper.create_topic_deadline(@topic_due_date, 5000, 10)&lt;br /&gt;
      new_due_date = TopicDueDate.find_by(parent_id: 10)&lt;br /&gt;
      expect(new_due_date).to be_valid&lt;br /&gt;
      expect(new_due_date.due_at.to_s).to be == (Time.zone.parse(@topic_due_date.due_at.to_s) + 5000).to_s&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
* due_at is calculated correctly if offset is negative:&amp;lt;syntaxhighlight lang=&amp;quot;ruby&amp;quot;&amp;gt;&lt;br /&gt;
it &amp;quot;due_at calculated correctly for negative offset&amp;quot; do&lt;br /&gt;
      DeadlineHelper.create_topic_deadline(@topic_due_date, -5000, 10)&lt;br /&gt;
      new_due_date = TopicDueDate.find_by(parent_id: 10)&lt;br /&gt;
      expect(new_due_date).to be_valid&lt;br /&gt;
      expect(new_due_date.due_at.to_s).to be == (Time.zone.parse(@topic_due_date.due_at.to_s) - 5000).to_s&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
* The offset is being converted to integer properly:&amp;lt;syntaxhighlight lang=&amp;quot;ruby&amp;quot;&amp;gt;&lt;br /&gt;
it &amp;quot;offset converted to integer correctly&amp;quot; do&lt;br /&gt;
      DeadlineHelper.create_topic_deadline(@topic_due_date, 5000.15, 10)&lt;br /&gt;
      new_due_date = TopicDueDate.find_by(parent_id: 10)&lt;br /&gt;
      expect(new_due_date).to be_valid&lt;br /&gt;
      expect(new_due_date.due_at.to_s).to be == (Time.zone.parse(@topic_due_date.due_at.to_s) + 5000).to_s&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
To test this file run the following command:&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
rspec spec/models/deadline_helper_spec.rb&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;The output of this RSpec file is present in below screenshot:&lt;br /&gt;
[[File:Deadlinerspec.png|center|thumb|705x705px]]&lt;br /&gt;
&lt;br /&gt;
Code coverage details of the above RSpec files is present in below screenshot:&lt;br /&gt;
[[File:Deadlinecoverage.png|center|thumb|823x823px]]&lt;br /&gt;
&lt;br /&gt;
== '''References''' ==&lt;/div&gt;</summary>
		<author><name>Nthanik</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2016/E1634.Refactor_and_write_unit_test_of_due_date.rb_and_deadline_helper.rb&amp;diff=103364</id>
		<title>CSC/ECE 517 Fall 2016/E1634.Refactor and write unit test of due date.rb and deadline helper.rb</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2016/E1634.Refactor_and_write_unit_test_of_due_date.rb_and_deadline_helper.rb&amp;diff=103364"/>
		<updated>2016-10-29T00:01:04Z</updated>

		<summary type="html">&lt;p&gt;Nthanik: Undo revision 103232 by Nthanik (talk)&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== '''Introduction''' ==&lt;br /&gt;
&lt;br /&gt;
=== Expertiza ===&lt;br /&gt;
Expertiza is an open source project for school assignment management for instructors and students based on the Ruby on Rails framework. Expertiza allows the instructor to create new assignments and customise new or existing assignments. It also allows the instructor to create a list of topics the students can sign up for. Students can form teams in Expertiza to work on various projects and assignments. Students can also peer review other students' submissions. Expertiza supports submission across various document types, including the URLs and word documents. Expertiza provides a dashboard for all the assignments corresponding to a course and provides absolute control to the Instructors and Teaching Assistants. In addition to assignments, it encompasses peer reviews wherein participants are allowed to provide feedback anonymously about each other's work thereby providing scope for the better outcome. The due_date.rb file is responsible for informing the users about the deadline for submission of the each assignment. Due dates in Expertiza have their association with many other components like assignments, reviews etc.&lt;br /&gt;
&lt;br /&gt;
=== Code Climate ===&lt;br /&gt;
Code Climate&amp;lt;ref&amp;gt;{{Cite web|url=https://codeclimate.com/dashboard|title=Log in to your Code Climate dashboard with GitHub or your email.|website=codeclimate.com|access-date=2016-10-28}}&amp;lt;/ref&amp;gt; is a tool that runs static analysis on a GitHub project and outputs many details like test coverage, complexity, duplication, security, style, and more. There is a Google Chrome extension to integrate the Code Climate results generated directly into GitHub which is visible when browsing the repository on the browser. It allows us to see issues displayed directly inside GitHub's UI, to review which lines are covered in diffs and files, and add repositories and open tickets without changing your workflow.&lt;br /&gt;
&lt;br /&gt;
== '''Tasks Identified''' ==&lt;br /&gt;
To install Code climate Chrome Extension that highlights the duplicated code.&lt;br /&gt;
&lt;br /&gt;
To refactor the following two files:&lt;br /&gt;
* Due_date.rb&lt;br /&gt;
** Ternary operators must not be nested. Prefer `if` or `else` constructs instead.&lt;br /&gt;
** Useless assignment to variable - `sorted_deadlines`.&lt;br /&gt;
** Prefer `each` over `for`.&lt;br /&gt;
** Use `find_by` instead of `where.first`.&lt;br /&gt;
** Correct the use of Time function&lt;br /&gt;
* Deadline_helper.rb&lt;br /&gt;
** Do not use `Time.now` without zone. Use one of `Time.zone.now`, `Time.current`, `Time.now.in_time_zone`, `Time.now.utc`, `Time.now.getlocal`, `Time.now.iso8601`, `Time.now.jisx0301`, `Time.now.rfc3339`, `Time.now.to_i`, `Time.now.to_f` instead.&lt;br /&gt;
** Trailing whitespace detected.&lt;br /&gt;
** Extra empty line detected at module body end.&lt;br /&gt;
&lt;br /&gt;
* Create respective RSpec files in /spec/models/ and /spec/helper folder and write unit tests for each method in due_date.rb and deadline_helper.rb.&lt;br /&gt;
&lt;br /&gt;
== '''Current Implementation''' ==&lt;br /&gt;
DueDate is a Model class to manage the deadlines of an assignment. It has methods for setting due dates for an assignment, copying due dates from one assignment to a new assignment etc. DeadlineHelper provides helper functions that help DueDate perform certain tasks. The assignment focuses on refactoring some of the methods based on warnings received from Code Climate's static analysis and modifying the language to make it more Ruby-friendly. The assignment also involves writing unit test cases for due_date.rb and deadline_helper.rb in order to increase test coverage. &lt;br /&gt;
&lt;br /&gt;
The goal of this project is to attempt to make this part of the application easier to read and write unit test cases that the application must pass. &lt;br /&gt;
&lt;br /&gt;
== '''Changed Implementation''' ==&lt;br /&gt;
Changes implemented involves refactoring the code and making it more understandable by adding comments in the code.&lt;br /&gt;
&lt;br /&gt;
The modified files are&lt;br /&gt;
* Due_date.rb (path: /app/models)&lt;br /&gt;
&lt;br /&gt;
* Deadline_helper.rb (path: /app/helpers)&lt;br /&gt;
Testing files&lt;br /&gt;
* Due_date_spec.rb (path: /spec/models)&lt;br /&gt;
* Deadline_helper_spec.rb (path: /spec/helpers)&lt;br /&gt;
=== Due_date.rb ===&lt;br /&gt;
* Converted for..in loop to object.each in order to follow better Ruby syntax.&lt;br /&gt;
* Unnecessary assignment to sorted_deadlines removed.&lt;br /&gt;
* Nested ternary operators have been changed to if..else in order to make it more readable.&lt;br /&gt;
[[File:Duedaterb.png]]&lt;br /&gt;
* Changed where(...).first to find_by(...) which is the newer recommended syntax.&lt;br /&gt;
* Corrected the Time.now functions by adding the correct zones to them such as Time.zone.now.&lt;br /&gt;
* Removed trailing whitespaces.&lt;br /&gt;
[[File:DueDaterb2.png]]&lt;br /&gt;
&lt;br /&gt;
=== Deadline_helper.rb ===&lt;br /&gt;
* Time functions were changed to functions with zones&lt;br /&gt;
* Extra line removed&lt;br /&gt;
[[File:Deadlinehelper.png]]&lt;br /&gt;
&lt;br /&gt;
== '''RSpec testing''' ==&lt;br /&gt;
There were no existing tests for the functions in due_date.rb and deadline_helper.rb. We have added exhaustive set of RSpec tests to test all the code. We have added two new spec files 'due_date_spec.rb' and ‘deadline_helper_spec.rb’ which cover the testing scenarios for the functions in ‘due_date.rb’ and ‘deadline_helper.rb’.&lt;br /&gt;
&lt;br /&gt;
These RSpec files have 100% code coverage visible at: /coverage/index.html&lt;br /&gt;
&lt;br /&gt;
=== due_date_spec.rb ===&lt;br /&gt;
This file is located at spec/models and tests the functionalities of the due_date.rb file located in app/models. There are 18 test cases in total which are listed below.&lt;br /&gt;
* If the factory is successfully able to build the due_date objects.&amp;lt;syntaxhighlight lang=&amp;quot;ruby&amp;quot;&amp;gt;&lt;br /&gt;
it &amp;quot;due date factory created successfully&amp;quot; do&lt;br /&gt;
    expect(@assignment_due_date).to be_valid&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&amp;lt;syntaxhighlight lang=&amp;quot;ruby&amp;quot;&amp;gt;&lt;br /&gt;
it &amp;quot;due dates created correctly&amp;quot; do&lt;br /&gt;
    expect(@due_dates.length).to be == 10&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
* If the function &amp;quot;set_flag&amp;quot; successfully sets the due_date flag.&amp;lt;syntaxhighlight lang=&amp;quot;ruby&amp;quot;&amp;gt;&lt;br /&gt;
it &amp;quot;due date flag is set&amp;quot; do&lt;br /&gt;
    expect(@assignment_due_date.flag).to be false&lt;br /&gt;
    @assignment_due_date.set_flag&lt;br /&gt;
    expect(@assignment_due_date.flag).to be true&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
* If the function &amp;quot;due_at_is_valid_datetime&amp;quot; returns nil (no errors) for a valid datetime in due_at (no invalid test cases can be added here because model does not allow invalid datetime to be set at all).&amp;lt;syntaxhighlight lang=&amp;quot;ruby&amp;quot;&amp;gt;&lt;br /&gt;
it &amp;quot;due at is valid datetime&amp;quot; do&lt;br /&gt;
    expect(@assignment_due_date.due_at_is_valid_datetime).to be nil&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
* If the function &amp;quot;self.copy&amp;quot; is able to copy due dates from one assignment to another.&amp;lt;syntaxhighlight lang=&amp;quot;ruby&amp;quot;&amp;gt;&lt;br /&gt;
it &amp;quot;copy due dates to new assignment&amp;quot; do&lt;br /&gt;
    new_assignment_id = build(:assignment, id: 999).id&lt;br /&gt;
    old_assignment_id = @assignment_due_date.assignment.id&lt;br /&gt;
    DueDate.copy(old_assignment_id, new_assignment_id)&lt;br /&gt;
    expect(DueDate.where(parent_id: new_assignment_id).count).to eql DueDate.where(parent_id: old_assignment_id).count&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
* If the function &amp;quot;self.set_duedate&amp;quot; is able to create another due date by copying data from an existing due date object.&amp;lt;syntaxhighlight lang=&amp;quot;ruby&amp;quot;&amp;gt;&lt;br /&gt;
it &amp;quot;create new duedate record with values&amp;quot; do&lt;br /&gt;
    DueDate.set_duedate({id: 999}, @assignment_due_date.deadline_type_id,&lt;br /&gt;
                        @assignment_due_date.parent_id, @assignment_due_date.round)&lt;br /&gt;
    new_due_date = DueDate.find_by(id: 999)&lt;br /&gt;
    expect(new_due_date).to be_valid&lt;br /&gt;
    expect(new_due_date.deadline_type_id).to eql @assignment_due_date.deadline_type_id&lt;br /&gt;
    expect(new_due_date.parent_id).to eql @assignment_due_date.parent_id&lt;br /&gt;
    expect(new_due_date.round).to eql @assignment_due_date.round&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
* If the function &amp;quot;self.deadline_sort&amp;quot; is able to sort the due dates in ascending order.&amp;lt;syntaxhighlight lang=&amp;quot;ruby&amp;quot;&amp;gt;&lt;br /&gt;
it &amp;quot;sort duedate records&amp;quot; do&lt;br /&gt;
    sorted_due_dates = @due_dates&lt;br /&gt;
    expect(sorted_due_dates.each_cons(2).all?{|m1, m2| (m1.due_at &amp;lt;=&amp;gt; m2.due_at) != 1}).to eql false&lt;br /&gt;
&lt;br /&gt;
    sorted_due_dates = DueDate.deadline_sort(@due_dates)&lt;br /&gt;
    expect(sorted_due_dates.each_cons(2).all?{|m1, m2| (m1.due_at &amp;lt;=&amp;gt; m2.due_at) != 1}).to eql true&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
* If the function &amp;quot;self.done_in_assignment_round&amp;quot; returns the correct number of rounds for specific inputs. This involves an invalid test case as well for 0 rounds.&amp;lt;syntaxhighlight lang=&amp;quot;ruby&amp;quot;&amp;gt;&lt;br /&gt;
describe &amp;quot;#done_in_assignment_round&amp;quot; do&lt;br /&gt;
    it &amp;quot;return 0 when no response map&amp;quot; do&lt;br /&gt;
      response = ReviewResponseMap.create&lt;br /&gt;
      response.type = &amp;quot;ResponseMap&amp;quot;&lt;br /&gt;
      response.save&lt;br /&gt;
      expect(DueDate.done_in_assignment_round(1, response)).to eql 0&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    it &amp;quot;return round 1 for single round&amp;quot; do&lt;br /&gt;
      response = ReviewResponseMap.create&lt;br /&gt;
      expect(DueDate.done_in_assignment_round(@assignment_due_date.parent_id, response)).to eql 1&lt;br /&gt;
    end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
* If the function &amp;quot;self.get_next_due_date&amp;quot; works as expected. This involves several invalid test cases as well.&amp;lt;syntaxhighlight lang=&amp;quot;ruby&amp;quot;&amp;gt;&lt;br /&gt;
describe &amp;quot;#get_next_due_date&amp;quot; do&lt;br /&gt;
    it &amp;quot;no subsequent due date&amp;quot; do&lt;br /&gt;
      expect(DueDate.get_next_due_date(@assignment_due_date.parent_id)).to be nil&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    it &amp;quot;nil value throws exception&amp;quot; do&lt;br /&gt;
      expect { DueDate.get_next_due_date(nil) }.to raise_exception(ActiveRecord::RecordNotFound)&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    it &amp;quot;get next assignment due date&amp;quot; do&lt;br /&gt;
      due_date = create(:assignment_due_date, deadline_type: @deadline_type,&lt;br /&gt;
        submission_allowed_id: @deadline_right.id, review_allowed_id: @deadline_right.id,&lt;br /&gt;
        review_of_review_allowed_id: @deadline_right.id, due_at: Time.zone.now + 5000)&lt;br /&gt;
      expect(DueDate.get_next_due_date(due_date.parent_id)).to be_valid&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    it &amp;quot;get next due date from topic for staggered deadline&amp;quot; do&lt;br /&gt;
      assignment_id = create(:assignment, staggered_deadline: true, name: &amp;quot;testassignment&amp;quot;).id&lt;br /&gt;
      due_date = create(:topic_due_date, deadline_type: @deadline_type,&lt;br /&gt;
        submission_allowed_id: @deadline_right.id, review_allowed_id: @deadline_right.id,&lt;br /&gt;
        review_of_review_allowed_id: @deadline_right.id, due_at: Time.zone.now + 5000, parent_id: assignment_id)&lt;br /&gt;
      expect(DueDate.get_next_due_date(assignment_id, due_date.parent_id)).to be_valid&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    it &amp;quot;next due date does not exist for staggered deadline&amp;quot; do&lt;br /&gt;
      assignment_id = create(:assignment, staggered_deadline: true, name: &amp;quot;testassignment&amp;quot;).id&lt;br /&gt;
      due_date = create(:topic_due_date, deadline_type: @deadline_type,&lt;br /&gt;
        submission_allowed_id: @deadline_right, review_allowed_id: @deadline_right,&lt;br /&gt;
        review_of_review_allowed_id: @deadline_right, due_at: Time.zone.now + 5000, parent_id: assignment_id)&lt;br /&gt;
      expect(DueDate.get_next_due_date(assignment_id)).to be nil&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    it &amp;quot;next due date is before Time.now for staggered deadline&amp;quot; do&lt;br /&gt;
      assignment_id = create(:assignment, staggered_deadline: true, name: &amp;quot;testassignment&amp;quot;).id&lt;br /&gt;
      due_date = create(:topic_due_date, deadline_type: @deadline_type,&lt;br /&gt;
        submission_allowed_id: @deadline_right, review_allowed_id: @deadline_right,&lt;br /&gt;
        review_of_review_allowed_id: @deadline_right, due_at: Time.zone.now - 5000, parent_id: assignment_id)&lt;br /&gt;
      expect(DueDate.get_next_due_date(assignment_id, due_date.parent_id)).to be nil&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    it &amp;quot;get next due date from assignment for staggered deadline&amp;quot; do&lt;br /&gt;
      assignment_id = create(:assignment, staggered_deadline: true, name: &amp;quot;testassignment&amp;quot;).id&lt;br /&gt;
      due_date = create(:assignment_due_date, deadline_type: @deadline_type,&lt;br /&gt;
        submission_allowed_id: @deadline_right, review_allowed_id: @deadline_right,&lt;br /&gt;
        review_of_review_allowed_id: @deadline_right, due_at: Time.zone.now + 5000, parent_id: assignment_id)&lt;br /&gt;
      expect(DueDate.get_next_due_date(assignment_id)).to be_valid&lt;br /&gt;
    end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
* If the function &amp;quot;self.default_permission&amp;quot; returns the correct default permissions for particular deadline and permission types.&amp;lt;syntaxhighlight lang=&amp;quot;ruby&amp;quot;&amp;gt;&lt;br /&gt;
it &amp;quot;metareview review_of_review_allowed default permission OK&amp;quot; do&lt;br /&gt;
    expect(DueDate.default_permission('metareview', 'review_of_review_allowed')).to be == DeadlineRight::OK&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&amp;lt;syntaxhighlight lang=&amp;quot;ruby&amp;quot;&amp;gt;&lt;br /&gt;
it &amp;quot;review submission_allowed default permission NO&amp;quot; do&lt;br /&gt;
    expect(DueDate.default_permission('review', 'submission_allowed')).to be == DeadlineRight::NO&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
To test this file run the following command:&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
rspec spec/models/due_date_spec.rb&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
The output of this RSpec file is present in below screenshot:&lt;br /&gt;
[[File:Duedaterspec.png]]&lt;br /&gt;
&lt;br /&gt;
Code coverage details of the above RSpec files is present in below screenshot:&lt;br /&gt;
[[File:Duedatecoverage.png]]&lt;br /&gt;
&lt;br /&gt;
Code coverage details of the above RSpec files is present in below screenshot:&lt;br /&gt;
&lt;br /&gt;
=== deadline_helper_spec.rb ===&lt;br /&gt;
This is a test file for testing the functionalities of Deadline_helper.rb file located at app/helpers. Different test cases present in this file are:&lt;br /&gt;
* Check if the factory is valid:  &lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;ruby&amp;quot;&amp;gt;&lt;br /&gt;
it &amp;quot;has a valid factory&amp;quot; do&lt;br /&gt;
    factory = FactoryGirl.build(:topic_due_date)&lt;br /&gt;
    expect(factory).to be_valid&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
* Fail if the due date is invalid:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;ruby&amp;quot;&amp;gt;&lt;br /&gt;
it &amp;quot;should fail because of invalid due_date&amp;quot; do&lt;br /&gt;
      expect { DeadlineHelper.create_topic_deadline(nil, 0, 0)}.to raise_exception(NoMethodError)&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
* If new due_date object is created:&amp;lt;syntaxhighlight lang=&amp;quot;ruby&amp;quot;&amp;gt;&lt;br /&gt;
it &amp;quot;new due_date object created&amp;quot; do&lt;br /&gt;
      DeadlineHelper.create_topic_deadline(@topic_due_date, 0, 1)&lt;br /&gt;
      expect(TopicDueDate.count).to be == 2&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
* due_at should be same for 0 offset:&amp;lt;syntaxhighlight lang=&amp;quot;ruby&amp;quot;&amp;gt;&lt;br /&gt;
 it &amp;quot;due_at should be same for 0 offset&amp;quot; do&lt;br /&gt;
      DeadlineHelper.create_topic_deadline(@topic_due_date, 0, 10)&lt;br /&gt;
      new_due_date = TopicDueDate.find_by(parent_id: 10)&lt;br /&gt;
      expect(new_due_date).to be_valid&lt;br /&gt;
      expect(new_due_date.due_at.to_s).to be == @topic_due_date.due_at.to_s&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
* due_at is calculated correctly if offset is positive:&amp;lt;syntaxhighlight lang=&amp;quot;ruby&amp;quot;&amp;gt;&lt;br /&gt;
it &amp;quot;due_at calculated correctly for positive offset&amp;quot; do&lt;br /&gt;
      DeadlineHelper.create_topic_deadline(@topic_due_date, 5000, 10)&lt;br /&gt;
      new_due_date = TopicDueDate.find_by(parent_id: 10)&lt;br /&gt;
      expect(new_due_date).to be_valid&lt;br /&gt;
      expect(new_due_date.due_at.to_s).to be == (Time.zone.parse(@topic_due_date.due_at.to_s) + 5000).to_s&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
* due_at is calculated correctly if offset is negative:&amp;lt;syntaxhighlight lang=&amp;quot;ruby&amp;quot;&amp;gt;&lt;br /&gt;
it &amp;quot;due_at calculated correctly for negative offset&amp;quot; do&lt;br /&gt;
      DeadlineHelper.create_topic_deadline(@topic_due_date, -5000, 10)&lt;br /&gt;
      new_due_date = TopicDueDate.find_by(parent_id: 10)&lt;br /&gt;
      expect(new_due_date).to be_valid&lt;br /&gt;
      expect(new_due_date.due_at.to_s).to be == (Time.zone.parse(@topic_due_date.due_at.to_s) - 5000).to_s&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
* The offset is being converted to integer properly:&amp;lt;syntaxhighlight lang=&amp;quot;ruby&amp;quot;&amp;gt;&lt;br /&gt;
it &amp;quot;offset converted to integer correctly&amp;quot; do&lt;br /&gt;
      DeadlineHelper.create_topic_deadline(@topic_due_date, 5000.15, 10)&lt;br /&gt;
      new_due_date = TopicDueDate.find_by(parent_id: 10)&lt;br /&gt;
      expect(new_due_date).to be_valid&lt;br /&gt;
      expect(new_due_date.due_at.to_s).to be == (Time.zone.parse(@topic_due_date.due_at.to_s) + 5000).to_s&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
To test this file run the following command:&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
rspec spec/models/deadline_helper_spec.rb&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;The output of this RSpec file is present in below screenshot:&lt;br /&gt;
[[File:Deadlinerspec.png]]&lt;br /&gt;
&lt;br /&gt;
Code coverage details of the above RSpec files is present in below screenshot:&lt;br /&gt;
[[File:Deadlinecoverage.png]]&lt;br /&gt;
&lt;br /&gt;
== '''References''' ==&lt;/div&gt;</summary>
		<author><name>Nthanik</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2016/E1634.Refactor_and_write_unit_test_of_due_date.rb_and_deadline_helper.rb&amp;diff=103363</id>
		<title>CSC/ECE 517 Fall 2016/E1634.Refactor and write unit test of due date.rb and deadline helper.rb</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2016/E1634.Refactor_and_write_unit_test_of_due_date.rb_and_deadline_helper.rb&amp;diff=103363"/>
		<updated>2016-10-29T00:00:54Z</updated>

		<summary type="html">&lt;p&gt;Nthanik: Undo revision 103255 by Nthanik (talk)&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== '''Introduction''' ==&lt;br /&gt;
&lt;br /&gt;
=== Expertiza ===&lt;br /&gt;
Expertiza is an open source project for school assignment management for instructors and students based on the Ruby on Rails framework. Expertiza allows the instructor to create new assignments and customise new or existing assignments. It also allows the instructor to create a list of topics the students can sign up for. Students can form teams in Expertiza to work on various projects and assignments. Students can also peer review other students' submissions. Expertiza supports submission across various document types, including the URLs and word documents. Expertiza provides a dashboard for all the assignments corresponding to a course and provides absolute control to the Instructors and Teaching Assistants. In addition to assignments, it encompasses peer reviews wherein participants are allowed to provide feedback anonymously about each other's work thereby providing scope for the better outcome. The due_date.rb file is responsible for informing the users about the deadline for submission of the each assignment. Due dates in Expertiza have their association with many other components like assignments, reviews etc.&lt;br /&gt;
&lt;br /&gt;
=== Code Climate ===&lt;br /&gt;
Code Climate&amp;lt;ref&amp;gt;{{Cite web|url=https://codeclimate.com/dashboard|title=Log in to your Code Climate dashboard with GitHub or your email.|website=codeclimate.com|access-date=2016-10-28}}&amp;lt;/ref&amp;gt; is a tool that runs static analysis on a GitHub project and outputs many details like test coverage, complexity, duplication, security, style, and more. There is a Google Chrome extension to integrate the Code Climate results generated directly into GitHub which is visible when browsing the repository on the browser. It allows us to see issues displayed directly inside GitHub's UI, to review which lines are covered in diffs and files, and add repositories and open tickets without changing your workflow.&lt;br /&gt;
&lt;br /&gt;
== '''Tasks Identified''' ==&lt;br /&gt;
To install Code climate Chrome Extension that highlights the duplicated code.&lt;br /&gt;
&lt;br /&gt;
To refactor the following two files:&lt;br /&gt;
* Due_date.rb&lt;br /&gt;
** Ternary operators must not be nested. Prefer `if` or `else` constructs instead.&lt;br /&gt;
** Useless assignment to variable - `sorted_deadlines`.&lt;br /&gt;
** Prefer `each` over `for`.&lt;br /&gt;
** Use `find_by` instead of `where.first`.&lt;br /&gt;
** Correct the use of Time function&lt;br /&gt;
* Deadline_helper.rb&lt;br /&gt;
** Do not use `Time.now` without zone. Use one of `Time.zone.now`, `Time.current`, `Time.now.in_time_zone`, `Time.now.utc`, `Time.now.getlocal`, `Time.now.iso8601`, `Time.now.jisx0301`, `Time.now.rfc3339`, `Time.now.to_i`, `Time.now.to_f` instead.&lt;br /&gt;
** Trailing whitespace detected.&lt;br /&gt;
** Extra empty line detected at module body end.&lt;br /&gt;
&lt;br /&gt;
* Create respective RSpec files in /spec/models/ and /spec/helper folder and write unit tests for each method in due_date.rb and deadline_helper.rb.&lt;br /&gt;
&lt;br /&gt;
== '''Current Implementation''' ==&lt;br /&gt;
DueDate is a Model class to manage the deadlines of an assignment. It has methods for setting due dates for an assignment, copying due dates from one assignment to a new assignment etc. DeadlineHelper provides helper functions that help DueDate perform certain tasks. The assignment focuses on refactoring some of the methods based on warnings received from Code Climate's static analysis and modifying the language to make it more Ruby-friendly. The assignment also involves writing unit test cases for due_date.rb and deadline_helper.rb in order to increase test coverage. &lt;br /&gt;
&lt;br /&gt;
The goal of this project is to attempt to make this part of the application easier to read and write unit test cases that the application must pass. &lt;br /&gt;
&lt;br /&gt;
== '''Changed Implementation''' ==&lt;br /&gt;
Changes implemented involves refactoring the code and making it more understandable by adding comments in the code.&lt;br /&gt;
&lt;br /&gt;
The modified files are&lt;br /&gt;
* Due_date.rb (path: /app/models)&lt;br /&gt;
&lt;br /&gt;
* Deadline_helper.rb (path: /app/helpers)&lt;br /&gt;
Testing files&lt;br /&gt;
* Due_date_spec.rb (path: /spec/models)&lt;br /&gt;
* Deadline_helper_spec.rb (path: /spec/helpers)&lt;br /&gt;
=== Due_date.rb ===&lt;br /&gt;
* Converted for..in loop to object.each in order to follow better Ruby syntax.&lt;br /&gt;
* Unnecessary assignment to sorted_deadlines removed.&lt;br /&gt;
* Nested ternary operators have been changed to if..else in order to make it more readable.&lt;br /&gt;
[[File:Duedaterb.png]]&lt;br /&gt;
* Changed where(...).first to find_by(...) which is the newer recommended syntax.&lt;br /&gt;
* Corrected the Time.now functions by adding the correct zones to them such as Time.zone.now.&lt;br /&gt;
* Removed trailing whitespaces.&lt;br /&gt;
[[File:DueDaterb2.png]]&lt;br /&gt;
&lt;br /&gt;
=== Deadline_helper.rb ===&lt;br /&gt;
* Time functions were changed to functions with zones&lt;br /&gt;
* Extra line removed&lt;br /&gt;
[[File:Deadlinehelper.png]]&lt;br /&gt;
&lt;br /&gt;
== '''RSpec testing''' ==&lt;br /&gt;
There were no existing tests for the functions in due_date.rb and deadline_helper.rb. We have added exhaustive set of RSpec tests to test all the code. We have added two new spec files 'due_date_spec.rb' and ‘deadline_helper_spec.rb’ which cover the testing scenarios for the functions in ‘due_date.rb’ and ‘deadline_helper.rb’.&lt;br /&gt;
&lt;br /&gt;
These RSpec files have 100% code coverage visible at: /coverage/index.html&lt;br /&gt;
&lt;br /&gt;
=== due_date_spec.rb ===&lt;br /&gt;
This file is located at spec/models and tests the functionalities of the due_date.rb file located in app/models. There are 18 test cases in total which are listed below.&lt;br /&gt;
* If the factory is successfully able to build the due_date objects.&amp;lt;syntaxhighlight lang=&amp;quot;ruby&amp;quot;&amp;gt;&lt;br /&gt;
it &amp;quot;due date factory created successfully&amp;quot; do&lt;br /&gt;
    expect(@assignment_due_date).to be_valid&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&amp;lt;syntaxhighlight lang=&amp;quot;ruby&amp;quot;&amp;gt;&lt;br /&gt;
it &amp;quot;due dates created correctly&amp;quot; do&lt;br /&gt;
    expect(@due_dates.length).to be == 10&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
* If the function &amp;quot;set_flag&amp;quot; successfully sets the due_date flag.&amp;lt;syntaxhighlight lang=&amp;quot;ruby&amp;quot;&amp;gt;&lt;br /&gt;
it &amp;quot;due date flag is set&amp;quot; do&lt;br /&gt;
    expect(@assignment_due_date.flag).to be false&lt;br /&gt;
    @assignment_due_date.set_flag&lt;br /&gt;
    expect(@assignment_due_date.flag).to be true&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
* If the function &amp;quot;due_at_is_valid_datetime&amp;quot; returns nil (no errors) for a valid datetime in due_at (no invalid test cases can be added here because model does not allow invalid datetime to be set at all).&amp;lt;syntaxhighlight lang=&amp;quot;ruby&amp;quot;&amp;gt;&lt;br /&gt;
it &amp;quot;due at is valid datetime&amp;quot; do&lt;br /&gt;
    expect(@assignment_due_date.due_at_is_valid_datetime).to be nil&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
* If the function &amp;quot;self.copy&amp;quot; is able to copy due dates from one assignment to another.&amp;lt;syntaxhighlight lang=&amp;quot;ruby&amp;quot;&amp;gt;&lt;br /&gt;
it &amp;quot;copy due dates to new assignment&amp;quot; do&lt;br /&gt;
    new_assignment_id = build(:assignment, id: 999).id&lt;br /&gt;
    old_assignment_id = @assignment_due_date.assignment.id&lt;br /&gt;
    DueDate.copy(old_assignment_id, new_assignment_id)&lt;br /&gt;
    expect(DueDate.where(parent_id: new_assignment_id).count).to eql DueDate.where(parent_id: old_assignment_id).count&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
* If the function &amp;quot;self.set_duedate&amp;quot; is able to create another due date by copying data from an existing due date object.&amp;lt;syntaxhighlight lang=&amp;quot;ruby&amp;quot;&amp;gt;&lt;br /&gt;
it &amp;quot;create new duedate record with values&amp;quot; do&lt;br /&gt;
    DueDate.set_duedate({id: 999}, @assignment_due_date.deadline_type_id,&lt;br /&gt;
                        @assignment_due_date.parent_id, @assignment_due_date.round)&lt;br /&gt;
    new_due_date = DueDate.find_by(id: 999)&lt;br /&gt;
    expect(new_due_date).to be_valid&lt;br /&gt;
    expect(new_due_date.deadline_type_id).to eql @assignment_due_date.deadline_type_id&lt;br /&gt;
    expect(new_due_date.parent_id).to eql @assignment_due_date.parent_id&lt;br /&gt;
    expect(new_due_date.round).to eql @assignment_due_date.round&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
* If the function &amp;quot;self.deadline_sort&amp;quot; is able to sort the due dates in ascending order.&amp;lt;syntaxhighlight lang=&amp;quot;ruby&amp;quot;&amp;gt;&lt;br /&gt;
it &amp;quot;sort duedate records&amp;quot; do&lt;br /&gt;
    sorted_due_dates = @due_dates&lt;br /&gt;
    expect(sorted_due_dates.each_cons(2).all?{|m1, m2| (m1.due_at &amp;lt;=&amp;gt; m2.due_at) != 1}).to eql false&lt;br /&gt;
&lt;br /&gt;
    sorted_due_dates = DueDate.deadline_sort(@due_dates)&lt;br /&gt;
    expect(sorted_due_dates.each_cons(2).all?{|m1, m2| (m1.due_at &amp;lt;=&amp;gt; m2.due_at) != 1}).to eql true&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
* If the function &amp;quot;self.done_in_assignment_round&amp;quot; returns the correct number of rounds for specific inputs. This involves an invalid test case as well for 0 rounds.&amp;lt;syntaxhighlight lang=&amp;quot;ruby&amp;quot;&amp;gt;&lt;br /&gt;
describe &amp;quot;#done_in_assignment_round&amp;quot; do&lt;br /&gt;
    it &amp;quot;return 0 when no response map&amp;quot; do&lt;br /&gt;
      response = ReviewResponseMap.create&lt;br /&gt;
      response.type = &amp;quot;ResponseMap&amp;quot;&lt;br /&gt;
      response.save&lt;br /&gt;
      expect(DueDate.done_in_assignment_round(1, response)).to eql 0&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    it &amp;quot;return round 1 for single round&amp;quot; do&lt;br /&gt;
      response = ReviewResponseMap.create&lt;br /&gt;
      expect(DueDate.done_in_assignment_round(@assignment_due_date.parent_id, response)).to eql 1&lt;br /&gt;
    end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
* If the function &amp;quot;self.get_next_due_date&amp;quot; works as expected. This involves several invalid test cases as well.&amp;lt;syntaxhighlight lang=&amp;quot;ruby&amp;quot;&amp;gt;&lt;br /&gt;
describe &amp;quot;#get_next_due_date&amp;quot; do&lt;br /&gt;
    it &amp;quot;no subsequent due date&amp;quot; do&lt;br /&gt;
      expect(DueDate.get_next_due_date(@assignment_due_date.parent_id)).to be nil&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    it &amp;quot;nil value throws exception&amp;quot; do&lt;br /&gt;
      expect { DueDate.get_next_due_date(nil) }.to raise_exception(ActiveRecord::RecordNotFound)&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    it &amp;quot;get next assignment due date&amp;quot; do&lt;br /&gt;
      due_date = create(:assignment_due_date, deadline_type: @deadline_type,&lt;br /&gt;
        submission_allowed_id: @deadline_right.id, review_allowed_id: @deadline_right.id,&lt;br /&gt;
        review_of_review_allowed_id: @deadline_right.id, due_at: Time.zone.now + 5000)&lt;br /&gt;
      expect(DueDate.get_next_due_date(due_date.parent_id)).to be_valid&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    it &amp;quot;get next due date from topic for staggered deadline&amp;quot; do&lt;br /&gt;
      assignment_id = create(:assignment, staggered_deadline: true, name: &amp;quot;testassignment&amp;quot;).id&lt;br /&gt;
      due_date = create(:topic_due_date, deadline_type: @deadline_type,&lt;br /&gt;
        submission_allowed_id: @deadline_right.id, review_allowed_id: @deadline_right.id,&lt;br /&gt;
        review_of_review_allowed_id: @deadline_right.id, due_at: Time.zone.now + 5000, parent_id: assignment_id)&lt;br /&gt;
      expect(DueDate.get_next_due_date(assignment_id, due_date.parent_id)).to be_valid&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    it &amp;quot;next due date does not exist for staggered deadline&amp;quot; do&lt;br /&gt;
      assignment_id = create(:assignment, staggered_deadline: true, name: &amp;quot;testassignment&amp;quot;).id&lt;br /&gt;
      due_date = create(:topic_due_date, deadline_type: @deadline_type,&lt;br /&gt;
        submission_allowed_id: @deadline_right, review_allowed_id: @deadline_right,&lt;br /&gt;
        review_of_review_allowed_id: @deadline_right, due_at: Time.zone.now + 5000, parent_id: assignment_id)&lt;br /&gt;
      expect(DueDate.get_next_due_date(assignment_id)).to be nil&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    it &amp;quot;next due date is before Time.now for staggered deadline&amp;quot; do&lt;br /&gt;
      assignment_id = create(:assignment, staggered_deadline: true, name: &amp;quot;testassignment&amp;quot;).id&lt;br /&gt;
      due_date = create(:topic_due_date, deadline_type: @deadline_type,&lt;br /&gt;
        submission_allowed_id: @deadline_right, review_allowed_id: @deadline_right,&lt;br /&gt;
        review_of_review_allowed_id: @deadline_right, due_at: Time.zone.now - 5000, parent_id: assignment_id)&lt;br /&gt;
      expect(DueDate.get_next_due_date(assignment_id, due_date.parent_id)).to be nil&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    it &amp;quot;get next due date from assignment for staggered deadline&amp;quot; do&lt;br /&gt;
      assignment_id = create(:assignment, staggered_deadline: true, name: &amp;quot;testassignment&amp;quot;).id&lt;br /&gt;
      due_date = create(:assignment_due_date, deadline_type: @deadline_type,&lt;br /&gt;
        submission_allowed_id: @deadline_right, review_allowed_id: @deadline_right,&lt;br /&gt;
        review_of_review_allowed_id: @deadline_right, due_at: Time.zone.now + 5000, parent_id: assignment_id)&lt;br /&gt;
      expect(DueDate.get_next_due_date(assignment_id)).to be_valid&lt;br /&gt;
    end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
* If the function &amp;quot;self.default_permission&amp;quot; returns the correct default permissions for particular deadline and permission types.&amp;lt;syntaxhighlight lang=&amp;quot;ruby&amp;quot;&amp;gt;&lt;br /&gt;
it &amp;quot;metareview review_of_review_allowed default permission OK&amp;quot; do&lt;br /&gt;
    expect(DueDate.default_permission('metareview', 'review_of_review_allowed')).to be == DeadlineRight::OK&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&amp;lt;syntaxhighlight lang=&amp;quot;ruby&amp;quot;&amp;gt;&lt;br /&gt;
it &amp;quot;review submission_allowed default permission NO&amp;quot; do&lt;br /&gt;
    expect(DueDate.default_permission('review', 'submission_allowed')).to be == DeadlineRight::NO&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
To test this file run the following command:&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
rspec spec/models/due_date_spec.rb&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
The output of this RSpec file is present in below screenshot:&lt;br /&gt;
[[File:Duedaterspec.png]]&lt;br /&gt;
&lt;br /&gt;
Code coverage details of the above RSpec files is present in below screenshot:&lt;br /&gt;
[[File:Duedatecoverage.png]]&lt;br /&gt;
&lt;br /&gt;
Code coverage details of the above RSpec files is present in below screenshot:&lt;br /&gt;
&lt;br /&gt;
=== deadline_helper_spec.rb ===&lt;br /&gt;
This is a test file for testing the functionalities of Deadline_helper.rb file located at app/helpers. Different test cases present in this file are:&lt;br /&gt;
* Check if the factory is valid:  &lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;ruby&amp;quot;&amp;gt;&lt;br /&gt;
it &amp;quot;has a valid factory&amp;quot; do&lt;br /&gt;
    factory = FactoryGirl.build(:topic_due_date)&lt;br /&gt;
    expect(factory).to be_valid&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
* Fail if the due date is invalid:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;ruby&amp;quot;&amp;gt;&lt;br /&gt;
it &amp;quot;should fail because of invalid due_date&amp;quot; do&lt;br /&gt;
      expect { DeadlineHelper.create_topic_deadline(nil, 0, 0)}.to raise_exception(NoMethodError)&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
* If new due_date object is created:&amp;lt;syntaxhighlight lang=&amp;quot;ruby&amp;quot;&amp;gt;&lt;br /&gt;
it &amp;quot;new due_date object created&amp;quot; do&lt;br /&gt;
      DeadlineHelper.create_topic_deadline(@topic_due_date, 0, 1)&lt;br /&gt;
      expect(TopicDueDate.count).to be == 2&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
* due_at should be same for 0 offset:&amp;lt;syntaxhighlight lang=&amp;quot;ruby&amp;quot;&amp;gt;&lt;br /&gt;
 it &amp;quot;due_at should be same for 0 offset&amp;quot; do&lt;br /&gt;
      DeadlineHelper.create_topic_deadline(@topic_due_date, 0, 10)&lt;br /&gt;
      new_due_date = TopicDueDate.find_by(parent_id: 10)&lt;br /&gt;
      expect(new_due_date).to be_valid&lt;br /&gt;
      expect(new_due_date.due_at.to_s).to be == @topic_due_date.due_at.to_s&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
* due_at is calculated correctly if offset is positive:&amp;lt;syntaxhighlight lang=&amp;quot;ruby&amp;quot;&amp;gt;&lt;br /&gt;
it &amp;quot;due_at calculated correctly for positive offset&amp;quot; do&lt;br /&gt;
      DeadlineHelper.create_topic_deadline(@topic_due_date, 5000, 10)&lt;br /&gt;
      new_due_date = TopicDueDate.find_by(parent_id: 10)&lt;br /&gt;
      expect(new_due_date).to be_valid&lt;br /&gt;
      expect(new_due_date.due_at.to_s).to be == (Time.zone.parse(@topic_due_date.due_at.to_s) + 5000).to_s&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
* due_at is calculated correctly if offset is negative:&amp;lt;syntaxhighlight lang=&amp;quot;ruby&amp;quot;&amp;gt;&lt;br /&gt;
it &amp;quot;due_at calculated correctly for negative offset&amp;quot; do&lt;br /&gt;
      DeadlineHelper.create_topic_deadline(@topic_due_date, -5000, 10)&lt;br /&gt;
      new_due_date = TopicDueDate.find_by(parent_id: 10)&lt;br /&gt;
      expect(new_due_date).to be_valid&lt;br /&gt;
      expect(new_due_date.due_at.to_s).to be == (Time.zone.parse(@topic_due_date.due_at.to_s) - 5000).to_s&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;[[asd]]&lt;br /&gt;
* The offset is being converted to integer properly:&amp;lt;syntaxhighlight lang=&amp;quot;ruby&amp;quot;&amp;gt;&lt;br /&gt;
it &amp;quot;offset converted to integer correctly&amp;quot; do&lt;br /&gt;
      DeadlineHelper.create_topic_deadline(@topic_due_date, 5000.15, 10)&lt;br /&gt;
      new_due_date = TopicDueDate.find_by(parent_id: 10)&lt;br /&gt;
      expect(new_due_date).to be_valid&lt;br /&gt;
      expect(new_due_date.due_at.to_s).to be == (Time.zone.parse(@topic_due_date.due_at.to_s) + 5000).to_s&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
To test this file run the following command:&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
rspec spec/models/deadline_helper_spec.rb&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;The output of this RSpec file is present in below screenshot:&lt;br /&gt;
[[File:Deadlinerspec.png]]&lt;br /&gt;
&lt;br /&gt;
Code coverage details of the above RSpec files is present in below screenshot:&lt;br /&gt;
[[File:Deadlinecoverage.png]]&lt;br /&gt;
&lt;br /&gt;
== '''References''' ==&lt;br /&gt;
&amp;quot;[http://www.expertiza.ncsu.edu]&amp;quot;&lt;br /&gt;
&amp;quot;[Ruby on Rails]&amp;quot;. [http://www.rubyonrails.org]. Retrieved 2016-10-28.&lt;br /&gt;
&amp;quot;[Log in to your Code Climate dashboard with GitHub or your email].&amp;quot;. [http://www.codeclimate.com]. Retrieved 2016-10-28.&lt;br /&gt;
&amp;quot;[RSpec: Behaviour Driven Development for Ruby]&amp;quot;. [http://www.rspec.info]. Retrieved 2016-10-28.&lt;br /&gt;
&amp;quot;[Travis CI - Test and Deploy with Confidence]&amp;quot;. [http://www.travis-ci.com link title]. Retrieved 2016-10-28&lt;br /&gt;
&amp;quot;[Working Effectively with Data Factories Using FactoryGirl]&amp;quot;. [http://www.semaphoreci.com]. Retrieved 2016-10-28&lt;/div&gt;</summary>
		<author><name>Nthanik</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2016/E1634.Refactor_and_write_unit_test_of_due_date.rb_and_deadline_helper.rb&amp;diff=103360</id>
		<title>CSC/ECE 517 Fall 2016/E1634.Refactor and write unit test of due date.rb and deadline helper.rb</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2016/E1634.Refactor_and_write_unit_test_of_due_date.rb_and_deadline_helper.rb&amp;diff=103360"/>
		<updated>2016-10-29T00:00:04Z</updated>

		<summary type="html">&lt;p&gt;Nthanik: Undo revision 103346 by Nthanik (talk)&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== '''Introduction''' ==&lt;br /&gt;
&lt;br /&gt;
=== Expertiza ===&lt;br /&gt;
Expertiza&amp;lt;ref&amp;gt;{{Cite web|url=http://www.expertiza.ncsu.edu|access-date=2016-10-28}}&amp;lt;/ref&amp;gt; is an open source project for school assignment management for instructors and students based on the Ruby on Rails&amp;lt;ref&amp;gt;{{Cite web|url=http://www.rubyonrails.org|access-date=2016-10-28}}&amp;lt;/ref&amp;gt; framework. Expertiza allows the instructor to create new assignments and customise new or existing assignments. It also allows the instructor to create a list of topics the students can sign up for. Students can form teams in Expertiza to work on various projects and assignments. Students can also peer review other students' submissions. Expertiza supports submission across various document types, including the URLs and word documents. Expertiza provides a dashboard for all the assignments corresponding to a course and provides absolute control to the Instructors and Teaching Assistants. In addition to assignments, it encompasses peer reviews wherein participants are allowed to provide feedback anonymously about each other's work thereby providing scope for the better outcome. The due_date.rb file is responsible for informing the users about the deadline for submission of the each assignment. Due dates in Expertiza have their association with many other components like assignments, reviews etc.&lt;br /&gt;
&lt;br /&gt;
=== Code Climate ===&lt;br /&gt;
Code Climate&amp;lt;ref&amp;gt;{{Cite web|url=https://codeclimate.com/dashboard|title=Log in to your Code Climate dashboard with GitHub or your email.|website=codeclimate.com|access-date=2016-10-28}}&amp;lt;/ref&amp;gt; is a tool that runs static analysis on a GitHub project and outputs many details like test coverage, complexity, duplication, security, style, and more. There is a Google Chrome extension to integrate the Code Climate results generated directly into GitHub which is visible when browsing the repository on the browser. It allows us to see issues displayed directly inside GitHub's UI, to review which lines are covered in diffs and files, and add repositories and open tickets without changing your workflow.&lt;br /&gt;
&lt;br /&gt;
== '''Tasks Identified''' ==&lt;br /&gt;
To install Code climate Chrome Extension that highlights the duplicated code.&lt;br /&gt;
&lt;br /&gt;
To refactor the following two files:&lt;br /&gt;
* Due_date.rb&lt;br /&gt;
** Ternary operators must not be nested. Prefer `if` or `else` constructs instead.&lt;br /&gt;
** Useless assignment to variable - `sorted_deadlines`.&lt;br /&gt;
** Prefer `each` over `for`.&lt;br /&gt;
** Use `find_by` instead of `where.first`.&lt;br /&gt;
** Correct the use of Time function&lt;br /&gt;
* Deadline_helper.rb&lt;br /&gt;
** Do not use `Time.now` without zone. Use one of `Time.zone.now`, `Time.current`, `Time.now.in_time_zone`, `Time.now.utc`, `Time.now.getlocal`, `Time.now.iso8601`, `Time.now.jisx0301`, `Time.now.rfc3339`, `Time.now.to_i`, `Time.now.to_f` instead.&lt;br /&gt;
** Trailing whitespace detected.&lt;br /&gt;
** Extra empty line detected at module body end.&lt;br /&gt;
&lt;br /&gt;
* Create respective RSpec&amp;lt;ref&amp;gt;{{Cite web|url=http://www.rspec.info|access-date=2016-10-28}}&amp;lt;/ref&amp;gt;files in /spec/models/ and /spec/helper folder and write unit tests for each method in due_date.rb and deadline_helper.rb.&lt;br /&gt;
&lt;br /&gt;
== '''Current Implementation''' ==&lt;br /&gt;
DueDate is a Model class to manage the deadlines of an assignment. It has methods for setting due dates for an assignment, copying due dates from one assignment to a new assignment etc. DeadlineHelper provides helper functions that help DueDate perform certain tasks. The assignment focuses on refactoring some of the methods based on warnings received from Code Climate's static analysis and modifying the language to make it more Ruby-friendly. The assignment also involves writing unit test cases for due_date.rb and deadline_helper.rb in order to increase test coverage. &lt;br /&gt;
&lt;br /&gt;
The goal of this project is to attempt to make this part of the application easier to read and write unit test cases that the application must pass. &lt;br /&gt;
&lt;br /&gt;
== '''Changed Implementation''' ==&lt;br /&gt;
Changes implemented involves refactoring the code and making it more understandable by adding comments in the code.&lt;br /&gt;
&lt;br /&gt;
The modified files are&lt;br /&gt;
* Due_date.rb (path: /app/models)&lt;br /&gt;
&lt;br /&gt;
* Deadline_helper.rb (path: /app/helpers)&lt;br /&gt;
Testing files&lt;br /&gt;
* Due_date_spec.rb (path: /spec/models)&lt;br /&gt;
* Deadline_helper_spec.rb (path: /spec/helpers)&lt;br /&gt;
=== Due_date.rb ===&lt;br /&gt;
* Converted for..in loop to object.each in order to follow better Ruby syntax.&lt;br /&gt;
* Unnecessary assignment to sorted_deadlines removed.&lt;br /&gt;
* Nested ternary operators have been changed to if..else in order to make it more readable.&lt;br /&gt;
[[File:Duedaterb.png]]&lt;br /&gt;
* Changed where(...).first to find_by(...) which is the newer recommended syntax.&lt;br /&gt;
* Corrected the Time.now functions by adding the correct zones to them such as Time.zone.now.&lt;br /&gt;
* Removed trailing whitespaces.&lt;br /&gt;
[[File:DueDaterb2.png]]&lt;br /&gt;
&lt;br /&gt;
=== Deadline_helper.rb ===&lt;br /&gt;
* Time functions were changed to functions with zones&lt;br /&gt;
* Extra line removed&lt;br /&gt;
[[File:Deadlinehelper.png]]&lt;br /&gt;
&lt;br /&gt;
== '''RSpec testing''' ==&lt;br /&gt;
There were no existing tests for the functions in due_date.rb and deadline_helper.rb. We have added exhaustive set of RSpec tests to test all the code. We have added two new spec files 'due_date_spec.rb' and ‘deadline_helper_spec.rb’ which cover the testing scenarios for the functions in ‘due_date.rb’ and ‘deadline_helper.rb’.For both of these two files, all Travis CI&amp;lt;ref&amp;gt;{{Cite web|url=http://http://www.travis-ci.com|access-date=2016-10-28}}&amp;lt;/ref&amp;gt; test cases have passed.&lt;br /&gt;
&lt;br /&gt;
These RSpec files have 100% code coverage visible at: /coverage/index.html&lt;br /&gt;
&lt;br /&gt;
=== due_date_spec.rb ===&lt;br /&gt;
This file is located at spec/models and tests the functionalities of the due_date.rb file located in app/models. There are 18 test cases in total which are listed below.&lt;br /&gt;
* If the factory is successfully able to build the due_date objects.&amp;lt;syntaxhighlight lang=&amp;quot;ruby&amp;quot;&amp;gt;&lt;br /&gt;
it &amp;quot;due date factory created successfully&amp;quot; do&lt;br /&gt;
    expect(@assignment_due_date).to be_valid&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&amp;lt;syntaxhighlight lang=&amp;quot;ruby&amp;quot;&amp;gt;&lt;br /&gt;
it &amp;quot;due dates created correctly&amp;quot; do&lt;br /&gt;
    expect(@due_dates.length).to be == 10&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
* If the function &amp;quot;set_flag&amp;quot; successfully sets the due_date flag.&amp;lt;syntaxhighlight lang=&amp;quot;ruby&amp;quot;&amp;gt;&lt;br /&gt;
it &amp;quot;due date flag is set&amp;quot; do&lt;br /&gt;
    expect(@assignment_due_date.flag).to be false&lt;br /&gt;
    @assignment_due_date.set_flag&lt;br /&gt;
    expect(@assignment_due_date.flag).to be true&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
* If the function &amp;quot;due_at_is_valid_datetime&amp;quot; returns nil (no errors) for a valid datetime in due_at (no invalid test cases can be added here because model does not allow invalid datetime to be set at all).&amp;lt;syntaxhighlight lang=&amp;quot;ruby&amp;quot;&amp;gt;&lt;br /&gt;
it &amp;quot;due at is valid datetime&amp;quot; do&lt;br /&gt;
    expect(@assignment_due_date.due_at_is_valid_datetime).to be nil&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
* If the function &amp;quot;self.copy&amp;quot; is able to copy due dates from one assignment to another.&amp;lt;syntaxhighlight lang=&amp;quot;ruby&amp;quot;&amp;gt;&lt;br /&gt;
it &amp;quot;copy due dates to new assignment&amp;quot; do&lt;br /&gt;
    new_assignment_id = build(:assignment, id: 999).id&lt;br /&gt;
    old_assignment_id = @assignment_due_date.assignment.id&lt;br /&gt;
    DueDate.copy(old_assignment_id, new_assignment_id)&lt;br /&gt;
    expect(DueDate.where(parent_id: new_assignment_id).count).to eql DueDate.where(parent_id: old_assignment_id).count&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
* If the function &amp;quot;self.set_duedate&amp;quot; is able to create another due date by copying data from an existing due date object.&amp;lt;syntaxhighlight lang=&amp;quot;ruby&amp;quot;&amp;gt;&lt;br /&gt;
it &amp;quot;create new duedate record with values&amp;quot; do&lt;br /&gt;
    DueDate.set_duedate({id: 999}, @assignment_due_date.deadline_type_id,&lt;br /&gt;
                        @assignment_due_date.parent_id, @assignment_due_date.round)&lt;br /&gt;
    new_due_date = DueDate.find_by(id: 999)&lt;br /&gt;
    expect(new_due_date).to be_valid&lt;br /&gt;
    expect(new_due_date.deadline_type_id).to eql @assignment_due_date.deadline_type_id&lt;br /&gt;
    expect(new_due_date.parent_id).to eql @assignment_due_date.parent_id&lt;br /&gt;
    expect(new_due_date.round).to eql @assignment_due_date.round&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
* If the function &amp;quot;self.deadline_sort&amp;quot; is able to sort the due dates in ascending order.&amp;lt;syntaxhighlight lang=&amp;quot;ruby&amp;quot;&amp;gt;&lt;br /&gt;
it &amp;quot;sort duedate records&amp;quot; do&lt;br /&gt;
    sorted_due_dates = @due_dates&lt;br /&gt;
    expect(sorted_due_dates.each_cons(2).all?{|m1, m2| (m1.due_at &amp;lt;=&amp;gt; m2.due_at) != 1}).to eql false&lt;br /&gt;
&lt;br /&gt;
    sorted_due_dates = DueDate.deadline_sort(@due_dates)&lt;br /&gt;
    expect(sorted_due_dates.each_cons(2).all?{|m1, m2| (m1.due_at &amp;lt;=&amp;gt; m2.due_at) != 1}).to eql true&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
* If the function &amp;quot;self.done_in_assignment_round&amp;quot; returns the correct number of rounds for specific inputs. This involves an invalid test case as well for 0 rounds.&amp;lt;syntaxhighlight lang=&amp;quot;ruby&amp;quot;&amp;gt;&lt;br /&gt;
describe &amp;quot;#done_in_assignment_round&amp;quot; do&lt;br /&gt;
    it &amp;quot;return 0 when no response map&amp;quot; do&lt;br /&gt;
      response = ReviewResponseMap.create&lt;br /&gt;
      response.type = &amp;quot;ResponseMap&amp;quot;&lt;br /&gt;
      response.save&lt;br /&gt;
      expect(DueDate.done_in_assignment_round(1, response)).to eql 0&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    it &amp;quot;return round 1 for single round&amp;quot; do&lt;br /&gt;
      response = ReviewResponseMap.create&lt;br /&gt;
      expect(DueDate.done_in_assignment_round(@assignment_due_date.parent_id, response)).to eql 1&lt;br /&gt;
    end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
* If the function &amp;quot;self.get_next_due_date&amp;quot; works as expected. This involves several invalid test cases as well.&amp;lt;syntaxhighlight lang=&amp;quot;ruby&amp;quot;&amp;gt;&lt;br /&gt;
describe &amp;quot;#get_next_due_date&amp;quot; do&lt;br /&gt;
    it &amp;quot;no subsequent due date&amp;quot; do&lt;br /&gt;
      expect(DueDate.get_next_due_date(@assignment_due_date.parent_id)).to be nil&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    it &amp;quot;nil value throws exception&amp;quot; do&lt;br /&gt;
      expect { DueDate.get_next_due_date(nil) }.to raise_exception(ActiveRecord::RecordNotFound)&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    it &amp;quot;get next assignment due date&amp;quot; do&lt;br /&gt;
      due_date = create(:assignment_due_date, deadline_type: @deadline_type,&lt;br /&gt;
        submission_allowed_id: @deadline_right.id, review_allowed_id: @deadline_right.id,&lt;br /&gt;
        review_of_review_allowed_id: @deadline_right.id, due_at: Time.zone.now + 5000)&lt;br /&gt;
      expect(DueDate.get_next_due_date(due_date.parent_id)).to be_valid&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    it &amp;quot;get next due date from topic for staggered deadline&amp;quot; do&lt;br /&gt;
      assignment_id = create(:assignment, staggered_deadline: true, name: &amp;quot;testassignment&amp;quot;).id&lt;br /&gt;
      due_date = create(:topic_due_date, deadline_type: @deadline_type,&lt;br /&gt;
        submission_allowed_id: @deadline_right.id, review_allowed_id: @deadline_right.id,&lt;br /&gt;
        review_of_review_allowed_id: @deadline_right.id, due_at: Time.zone.now + 5000, parent_id: assignment_id)&lt;br /&gt;
      expect(DueDate.get_next_due_date(assignment_id, due_date.parent_id)).to be_valid&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    it &amp;quot;next due date does not exist for staggered deadline&amp;quot; do&lt;br /&gt;
      assignment_id = create(:assignment, staggered_deadline: true, name: &amp;quot;testassignment&amp;quot;).id&lt;br /&gt;
      due_date = create(:topic_due_date, deadline_type: @deadline_type,&lt;br /&gt;
        submission_allowed_id: @deadline_right, review_allowed_id: @deadline_right,&lt;br /&gt;
        review_of_review_allowed_id: @deadline_right, due_at: Time.zone.now + 5000, parent_id: assignment_id)&lt;br /&gt;
      expect(DueDate.get_next_due_date(assignment_id)).to be nil&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    it &amp;quot;next due date is before Time.now for staggered deadline&amp;quot; do&lt;br /&gt;
      assignment_id = create(:assignment, staggered_deadline: true, name: &amp;quot;testassignment&amp;quot;).id&lt;br /&gt;
      due_date = create(:topic_due_date, deadline_type: @deadline_type,&lt;br /&gt;
        submission_allowed_id: @deadline_right, review_allowed_id: @deadline_right,&lt;br /&gt;
        review_of_review_allowed_id: @deadline_right, due_at: Time.zone.now - 5000, parent_id: assignment_id)&lt;br /&gt;
      expect(DueDate.get_next_due_date(assignment_id, due_date.parent_id)).to be nil&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    it &amp;quot;get next due date from assignment for staggered deadline&amp;quot; do&lt;br /&gt;
      assignment_id = create(:assignment, staggered_deadline: true, name: &amp;quot;testassignment&amp;quot;).id&lt;br /&gt;
      due_date = create(:assignment_due_date, deadline_type: @deadline_type,&lt;br /&gt;
        submission_allowed_id: @deadline_right, review_allowed_id: @deadline_right,&lt;br /&gt;
        review_of_review_allowed_id: @deadline_right, due_at: Time.zone.now + 5000, parent_id: assignment_id)&lt;br /&gt;
      expect(DueDate.get_next_due_date(assignment_id)).to be_valid&lt;br /&gt;
    end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
* If the function &amp;quot;self.default_permission&amp;quot; returns the correct default permissions for particular deadline and permission types.&amp;lt;syntaxhighlight lang=&amp;quot;ruby&amp;quot;&amp;gt;&lt;br /&gt;
it &amp;quot;metareview review_of_review_allowed default permission OK&amp;quot; do&lt;br /&gt;
    expect(DueDate.default_permission('metareview', 'review_of_review_allowed')).to be == DeadlineRight::OK&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&amp;lt;syntaxhighlight lang=&amp;quot;ruby&amp;quot;&amp;gt;&lt;br /&gt;
it &amp;quot;review submission_allowed default permission NO&amp;quot; do&lt;br /&gt;
    expect(DueDate.default_permission('review', 'submission_allowed')).to be == DeadlineRight::NO&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
To test this file run the following command:&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
rspec spec/models/due_date_spec.rb&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
The output of this RSpec file is present in below screenshot:&lt;br /&gt;
[[File:Duedaterspec.png]]&lt;br /&gt;
&lt;br /&gt;
Code coverage details of the above RSpec files is present in below screenshot:&lt;br /&gt;
[[File:Duedatecoverage.png]]&lt;br /&gt;
&lt;br /&gt;
Code coverage details of the above RSpec files is present in below screenshot:&lt;br /&gt;
&lt;br /&gt;
=== deadline_helper_spec.rb ===&lt;br /&gt;
This is a test file for testing the functionalities of Deadline_helper.rb file located at app/helpers. Different test cases present in this file are:&lt;br /&gt;
* Check if the factory&amp;lt;ref&amp;gt;{{Cite web|url=http://http://www.semaphoreci.com|access-date=2016-10-28}}&amp;lt;/ref&amp;gt; is valid:  &lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;ruby&amp;quot;&amp;gt;&lt;br /&gt;
it &amp;quot;has a valid factory&amp;quot; do&lt;br /&gt;
    factory = FactoryGirl.build(:topic_due_date)&lt;br /&gt;
    expect(factory).to be_valid&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
* Fail if the due date is invalid:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;ruby&amp;quot;&amp;gt;&lt;br /&gt;
it &amp;quot;should fail because of invalid due_date&amp;quot; do&lt;br /&gt;
      expect { DeadlineHelper.create_topic_deadline(nil, 0, 0)}.to raise_exception(NoMethodError)&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
* If new due_date object is created:&amp;lt;syntaxhighlight lang=&amp;quot;ruby&amp;quot;&amp;gt;&lt;br /&gt;
it &amp;quot;new due_date object created&amp;quot; do&lt;br /&gt;
      DeadlineHelper.create_topic_deadline(@topic_due_date, 0, 1)&lt;br /&gt;
      expect(TopicDueDate.count).to be == 2&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
* due_at should be same for 0 offset:&amp;lt;syntaxhighlight lang=&amp;quot;ruby&amp;quot;&amp;gt;&lt;br /&gt;
 it &amp;quot;due_at should be same for 0 offset&amp;quot; do&lt;br /&gt;
      DeadlineHelper.create_topic_deadline(@topic_due_date, 0, 10)&lt;br /&gt;
      new_due_date = TopicDueDate.find_by(parent_id: 10)&lt;br /&gt;
      expect(new_due_date).to be_valid&lt;br /&gt;
      expect(new_due_date.due_at.to_s).to be == @topic_due_date.due_at.to_s&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
* due_at is calculated correctly if offset is positive:&amp;lt;syntaxhighlight lang=&amp;quot;ruby&amp;quot;&amp;gt;&lt;br /&gt;
it &amp;quot;due_at calculated correctly for positive offset&amp;quot; do&lt;br /&gt;
      DeadlineHelper.create_topic_deadline(@topic_due_date, 5000, 10)&lt;br /&gt;
      new_due_date = TopicDueDate.find_by(parent_id: 10)&lt;br /&gt;
      expect(new_due_date).to be_valid&lt;br /&gt;
      expect(new_due_date.due_at.to_s).to be == (Time.zone.parse(@topic_due_date.due_at.to_s) + 5000).to_s&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
* due_at is calculated correctly if offset is negative:&amp;lt;syntaxhighlight lang=&amp;quot;ruby&amp;quot;&amp;gt;&lt;br /&gt;
it &amp;quot;due_at calculated correctly for negative offset&amp;quot; do&lt;br /&gt;
      DeadlineHelper.create_topic_deadline(@topic_due_date, -5000, 10)&lt;br /&gt;
      new_due_date = TopicDueDate.find_by(parent_id: 10)&lt;br /&gt;
      expect(new_due_date).to be_valid&lt;br /&gt;
      expect(new_due_date.due_at.to_s).to be == (Time.zone.parse(@topic_due_date.due_at.to_s) - 5000).to_s&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;[[asd]]&lt;br /&gt;
* The offset is being converted to integer properly:&amp;lt;syntaxhighlight lang=&amp;quot;ruby&amp;quot;&amp;gt;&lt;br /&gt;
it &amp;quot;offset converted to integer correctly&amp;quot; do&lt;br /&gt;
      DeadlineHelper.create_topic_deadline(@topic_due_date, 5000.15, 10)&lt;br /&gt;
      new_due_date = TopicDueDate.find_by(parent_id: 10)&lt;br /&gt;
      expect(new_due_date).to be_valid&lt;br /&gt;
      expect(new_due_date.due_at.to_s).to be == (Time.zone.parse(@topic_due_date.due_at.to_s) + 5000).to_s&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
To test this file run the following command:&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
rspec spec/models/deadline_helper_spec.rb&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;The output of this RSpec file is present in below screenshot:&lt;br /&gt;
[[File:Deadlinerspec.png]]&lt;br /&gt;
&lt;br /&gt;
Code coverage details of the above RSpec files is present in below screenshot:&lt;br /&gt;
[[File:Deadlinecoverage.png]]&lt;br /&gt;
&lt;br /&gt;
== '''References''' ==&lt;br /&gt;
&amp;quot;[http://www.expertiza.ncsu.edu]&amp;quot;&lt;br /&gt;
&amp;quot;[Ruby on Rails]&amp;quot;. [http://www.rubyonrails.org]. Retrieved 2016-10-28.&lt;br /&gt;
&amp;quot;[Log in to your Code Climate dashboard with GitHub or your email].&amp;quot;. [http://www.codeclimate.com]. Retrieved 2016-10-28.&lt;br /&gt;
&amp;quot;[RSpec: Behaviour Driven Development for Ruby]&amp;quot;. [http://www.rspec.info]. Retrieved 2016-10-28.&lt;br /&gt;
&amp;quot;[Travis CI - Test and Deploy with Confidence]&amp;quot;. [http://www.travis-ci.com link title]. Retrieved 2016-10-28&lt;br /&gt;
&amp;quot;[Working Effectively with Data Factories Using FactoryGirl]&amp;quot;. [http://www.semaphoreci.com]. Retrieved 2016-10-28&lt;/div&gt;</summary>
		<author><name>Nthanik</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2016/E1634.Refactor_and_write_unit_test_of_due_date.rb_and_deadline_helper.rb&amp;diff=103346</id>
		<title>CSC/ECE 517 Fall 2016/E1634.Refactor and write unit test of due date.rb and deadline helper.rb</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2016/E1634.Refactor_and_write_unit_test_of_due_date.rb_and_deadline_helper.rb&amp;diff=103346"/>
		<updated>2016-10-28T23:53:27Z</updated>

		<summary type="html">&lt;p&gt;Nthanik: Blanked the page&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Nthanik</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=File:DueDaterb2.png&amp;diff=103339</id>
		<title>File:DueDaterb2.png</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=File:DueDaterb2.png&amp;diff=103339"/>
		<updated>2016-10-28T23:52:04Z</updated>

		<summary type="html">&lt;p&gt;Nthanik: uploaded a new version of &amp;amp;quot;File:DueDaterb2.png&amp;amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Nthanik</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=File:DueDaterb2.png&amp;diff=103336</id>
		<title>File:DueDaterb2.png</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=File:DueDaterb2.png&amp;diff=103336"/>
		<updated>2016-10-28T23:50:18Z</updated>

		<summary type="html">&lt;p&gt;Nthanik: uploaded a new version of &amp;amp;quot;File:DueDaterb2.png&amp;amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Nthanik</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2016/E1634._Refactor_and_write_unit_test_of_due_date.rb_and_deadline_helper.rb&amp;diff=103294</id>
		<title>CSC/ECE 517 Fall 2016/E1634. Refactor and write unit test of due date.rb and deadline helper.rb</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2016/E1634._Refactor_and_write_unit_test_of_due_date.rb_and_deadline_helper.rb&amp;diff=103294"/>
		<updated>2016-10-28T23:26:52Z</updated>

		<summary type="html">&lt;p&gt;Nthanik: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== '''Introduction''' ==&lt;br /&gt;
&lt;br /&gt;
=== Expertiza ===&lt;br /&gt;
Expertiza&amp;lt;ref&amp;gt;{{Cite web|url=http://www.expertiza.ncsu.edu|access-date=2016-10-28}}&amp;lt;/ref&amp;gt; is an open source project for school assignment management for instructors and students based on the Ruby on Rails&amp;lt;ref&amp;gt;{{Cite web|url=http://www.rubyonrails.org|access-date=2016-10-28}}&amp;lt;/ref&amp;gt; framework. Expertiza allows the instructor to create new assignments and customise new or existing assignments. It also allows the instructor to create a list of topics the students can sign up for. Students can form teams in Expertiza to work on various projects and assignments. Students can also peer review other students' submissions. Expertiza supports submission across various document types, including the URLs and word documents. Expertiza provides a dashboard for all the assignments corresponding to a course and provides absolute control to the Instructors and Teaching Assistants. In addition to assignments, it encompasses peer reviews wherein participants are allowed to provide feedback anonymously about each other's work thereby providing scope for the better outcome. The due_date.rb file is responsible for informing the users about the deadline for submission of the each assignment. Due dates in Expertiza have their association with many other components like assignments, reviews etc.&lt;br /&gt;
&lt;br /&gt;
=== Code Climate ===&lt;br /&gt;
Code Climate&amp;lt;ref&amp;gt;{{Cite web|url=https://codeclimate.com/dashboard|title=Log in to your Code Climate dashboard with GitHub or your email.|website=codeclimate.com|access-date=2016-10-28}}&amp;lt;/ref&amp;gt; is a tool that runs static analysis on a GitHub project and outputs many details like test coverage, complexity, duplication, security, style, and more. There is a Google Chrome extension to integrate the Code Climate results generated directly into GitHub which is visible when browsing the repository on the browser. It allows us to see issues displayed directly inside GitHub's UI, to review which lines are covered in diffs and files, and add repositories and open tickets without changing your workflow.&lt;br /&gt;
&lt;br /&gt;
== '''Tasks Identified''' ==&lt;br /&gt;
To install Code climate Chrome Extension that highlights the duplicated code.&lt;br /&gt;
&lt;br /&gt;
To refactor the following two files:&lt;br /&gt;
* Due_date.rb&lt;br /&gt;
** Ternary operators must not be nested. Prefer `if` or `else` constructs instead.&lt;br /&gt;
** Useless assignment to variable - `sorted_deadlines`.&lt;br /&gt;
** Prefer `each` over `for`.&lt;br /&gt;
** Use `find_by` instead of `where.first`.&lt;br /&gt;
** Correct the use of Time function&lt;br /&gt;
* Deadline_helper.rb&lt;br /&gt;
** Do not use `Time.now` without zone. Use one of `Time.zone.now`, `Time.current`, `Time.now.in_time_zone`, `Time.now.utc`, `Time.now.getlocal`, `Time.now.iso8601`, `Time.now.jisx0301`, `Time.now.rfc3339`, `Time.now.to_i`, `Time.now.to_f` instead.&lt;br /&gt;
** Trailing whitespace detected.&lt;br /&gt;
** Extra empty line detected at module body end.&lt;br /&gt;
&lt;br /&gt;
* Create respective RSpec&amp;lt;ref&amp;gt;{{Cite web|url=http://www.rspec.info|access-date=2016-10-28}}&amp;lt;/ref&amp;gt;files in /spec/models/ and /spec/helper folder and write unit tests for each method in due_date.rb and deadline_helper.rb.&lt;br /&gt;
&lt;br /&gt;
== '''Current Implementation''' ==&lt;br /&gt;
DueDate is a Model class to manage the deadlines of an assignment. It has methods for setting due dates for an assignment, copying due dates from one assignment to a new assignment etc. DeadlineHelper provides helper functions that help DueDate perform certain tasks. The assignment focuses on refactoring some of the methods based on warnings received from Code Climate's static analysis and modifying the language to make it more Ruby-friendly. The assignment also involves writing unit test cases for due_date.rb and deadline_helper.rb in order to increase test coverage. &lt;br /&gt;
&lt;br /&gt;
The goal of this project is to attempt to make this part of the application easier to read and write unit test cases that the application must pass. &lt;br /&gt;
&lt;br /&gt;
== '''Changed Implementation''' ==&lt;br /&gt;
Changes implemented involves refactoring the code and making it more understandable by adding comments in the code.&lt;br /&gt;
&lt;br /&gt;
The modified files are&lt;br /&gt;
* Due_date.rb (path: /app/models)&lt;br /&gt;
&lt;br /&gt;
* Deadline_helper.rb (path: /app/helpers)&lt;br /&gt;
Testing files&lt;br /&gt;
* Due_date_spec.rb (path: /spec/models)&lt;br /&gt;
* Deadline_helper_spec.rb (path: /spec/helpers)&lt;br /&gt;
=== Due_date.rb ===&lt;br /&gt;
* Converted for..in loop to object.each in order to follow better Ruby syntax.&lt;br /&gt;
* Unnecessary assignment to sorted_deadlines removed.&lt;br /&gt;
* Nested ternary operators have been changed to if..else in order to make it more readable.&lt;br /&gt;
[[File:Duedaterb.png]]&lt;br /&gt;
* Changed where(...).first to find_by(...) which is the newer recommended syntax.&lt;br /&gt;
* Corrected the Time.now functions by adding the correct zones to them such as Time.zone.now.&lt;br /&gt;
* Removed trailing whitespaces.&lt;br /&gt;
[[File:DueDaterb2.png]]&lt;br /&gt;
&lt;br /&gt;
=== Deadline_helper.rb ===&lt;br /&gt;
* Time functions were changed to functions with zones&lt;br /&gt;
* Extra line removed&lt;br /&gt;
[[File:Deadlinehelper.png]]&lt;/div&gt;</summary>
		<author><name>Nthanik</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2016/E1634._Refactor_and_write_unit_test_of_due_date.rb_and_deadline_helper.rb&amp;diff=103287</id>
		<title>CSC/ECE 517 Fall 2016/E1634. Refactor and write unit test of due date.rb and deadline helper.rb</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2016/E1634._Refactor_and_write_unit_test_of_due_date.rb_and_deadline_helper.rb&amp;diff=103287"/>
		<updated>2016-10-28T23:20:32Z</updated>

		<summary type="html">&lt;p&gt;Nthanik: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== '''Introduction''' ==&lt;br /&gt;
&lt;br /&gt;
=== Expertiza ===&lt;br /&gt;
Expertiza&amp;lt;ref&amp;gt;{{Cite web|url=http://www.expertiza.ncsu.edu|access-date=2016-10-28}}&amp;lt;/ref&amp;gt; is an open source project for school assignment management for instructors and students based on the Ruby on Rails&amp;lt;ref&amp;gt;{{Cite web|url=http://www.rubyonrails.org|access-date=2016-10-28}}&amp;lt;/ref&amp;gt; framework. Expertiza allows the instructor to create new assignments and customise new or existing assignments. It also allows the instructor to create a list of topics the students can sign up for. Students can form teams in Expertiza to work on various projects and assignments. Students can also peer review other students' submissions. Expertiza supports submission across various document types, including the URLs and word documents. Expertiza provides a dashboard for all the assignments corresponding to a course and provides absolute control to the Instructors and Teaching Assistants. In addition to assignments, it encompasses peer reviews wherein participants are allowed to provide feedback anonymously about each other's work thereby providing scope for the better outcome. The due_date.rb file is responsible for informing the users about the deadline for submission of the each assignment. Due dates in Expertiza have their association with many other components like assignments, reviews etc.&lt;br /&gt;
&lt;br /&gt;
=== Code Climate ===&lt;br /&gt;
Code Climate&amp;lt;ref&amp;gt;{{Cite web|url=https://codeclimate.com/dashboard|title=Log in to your Code Climate dashboard with GitHub or your email.|website=codeclimate.com|access-date=2016-10-28}}&amp;lt;/ref&amp;gt; is a tool that runs static analysis on a GitHub project and outputs many details like test coverage, complexity, duplication, security, style, and more. There is a Google Chrome extension to integrate the Code Climate results generated directly into GitHub which is visible when browsing the repository on the browser. It allows us to see issues displayed directly inside GitHub's UI, to review which lines are covered in diffs and files, and add repositories and open tickets without changing your workflow.&lt;br /&gt;
&lt;br /&gt;
== '''Tasks Identified''' ==&lt;br /&gt;
To install Code climate Chrome Extension that highlights the duplicated code.&lt;br /&gt;
&lt;br /&gt;
To refactor the following two files:&lt;br /&gt;
* Due_date.rb&lt;br /&gt;
** Ternary operators must not be nested. Prefer `if` or `else` constructs instead.&lt;br /&gt;
** Useless assignment to variable - `sorted_deadlines`.&lt;br /&gt;
** Prefer `each` over `for`.&lt;br /&gt;
** Use `find_by` instead of `where.first`.&lt;br /&gt;
** Correct the use of Time function&lt;br /&gt;
* Deadline_helper.rb&lt;br /&gt;
** Do not use `Time.now` without zone. Use one of `Time.zone.now`, `Time.current`, `Time.now.in_time_zone`, `Time.now.utc`, `Time.now.getlocal`, `Time.now.iso8601`, `Time.now.jisx0301`, `Time.now.rfc3339`, `Time.now.to_i`, `Time.now.to_f` instead.&lt;br /&gt;
** Trailing whitespace detected.&lt;br /&gt;
** Extra empty line detected at module body end.&lt;br /&gt;
&lt;br /&gt;
* Create respective RSpec&amp;lt;ref&amp;gt;{{Cite web|url=http://www.rspec.info|access-date=2016-10-28}}&amp;lt;/ref&amp;gt;files in /spec/models/ and /spec/helper folder and write unit tests for each method in due_date.rb and deadline_helper.rb.&lt;br /&gt;
&lt;br /&gt;
== '''Current Implementation''' ==&lt;br /&gt;
DueDate is a Model class to manage the deadlines of an assignment. It has methods for setting due dates for an assignment, copying due dates from one assignment to a new assignment etc. DeadlineHelper provides helper functions that help DueDate perform certain tasks. The assignment focuses on refactoring some of the methods based on warnings received from Code Climate's static analysis and modifying the language to make it more Ruby-friendly. The assignment also involves writing unit test cases for due_date.rb and deadline_helper.rb in order to increase test coverage. &lt;br /&gt;
&lt;br /&gt;
The goal of this project is to attempt to make this part of the application easier to read and write unit test cases that the application must pass. &lt;br /&gt;
&lt;br /&gt;
== '''Changed Implementation''' ==&lt;br /&gt;
Changes implemented involves refactoring the code and making it more understandable by adding comments in the code.&lt;br /&gt;
&lt;br /&gt;
The modified files are&lt;br /&gt;
* Due_date.rb (path: /app/models)&lt;br /&gt;
&lt;br /&gt;
* Deadline_helper.rb (path: /app/helpers)&lt;br /&gt;
Testing files&lt;br /&gt;
* Due_date_spec.rb (path: /spec/models)&lt;br /&gt;
* Deadline_helper_spec.rb (path: /spec/helpers)&lt;br /&gt;
=== Due_date.rb ===&lt;br /&gt;
* Converted for..in loop to object.each in order to follow better Ruby syntax.&lt;br /&gt;
* Unnecessary assignment to sorted_deadlines removed.&lt;br /&gt;
* Nested ternary operators have been changed to if..else in order to make it more readable.&lt;br /&gt;
[[File:Duedaterb.png]]&lt;br /&gt;
* Changed where(...).first to find_by(...) which is the newer recommended syntax.&lt;br /&gt;
* Corrected the Time.now functions by adding the correct zones to them such as Time.zone.now.&lt;br /&gt;
* Removed trailing whitespaces.&lt;br /&gt;
[[File:DueDaterb2.png]]&lt;br /&gt;
&lt;br /&gt;
=== Deadline_helper.rb ===&lt;br /&gt;
* Time functions were changed to functions with zones&lt;br /&gt;
* Extra line removed&lt;br /&gt;
[[File:Deadlinehelper.png]]&lt;br /&gt;
&lt;br /&gt;
== '''RSpec testing''' ==&lt;br /&gt;
There were no existing tests for the functions in due_date.rb and deadline_helper.rb. We have added exhaustive set of RSpec tests to test all the code. We have added two new spec files 'due_date_spec.rb' and ‘deadline_helper_spec.rb’ which cover the testing scenarios for the functions in ‘due_date.rb’ and ‘deadline_helper.rb’.For both of these two files, all Travis CI&amp;lt;ref&amp;gt;{{Cite web|url=http://http://www.travis-ci.com|access-date=2016-10-28}}&amp;lt;/ref&amp;gt; test cases have passed.&lt;br /&gt;
&lt;br /&gt;
These RSpec files have 100% code coverage visible at: /coverage/index.html&lt;br /&gt;
&lt;br /&gt;
=== due_date_spec.rb ===&lt;br /&gt;
This file is located at spec/models and tests the functionalities of the due_date.rb file located in app/models. There are 18 test cases in total which are listed below.&lt;br /&gt;
* If the factory is successfully able to build the due_date objects.&amp;lt;syntaxhighlight lang=&amp;quot;ruby&amp;quot;&amp;gt;&lt;br /&gt;
it &amp;quot;due date factory created successfully&amp;quot; do&lt;br /&gt;
    expect(@assignment_due_date).to be_valid&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&amp;lt;syntaxhighlight lang=&amp;quot;ruby&amp;quot;&amp;gt;&lt;br /&gt;
it &amp;quot;due dates created correctly&amp;quot; do&lt;br /&gt;
    expect(@due_dates.length).to be == 10&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
* If the function &amp;quot;set_flag&amp;quot; successfully sets the due_date flag.&amp;lt;syntaxhighlight lang=&amp;quot;ruby&amp;quot;&amp;gt;&lt;br /&gt;
it &amp;quot;due date flag is set&amp;quot; do&lt;br /&gt;
    expect(@assignment_due_date.flag).to be false&lt;br /&gt;
    @assignment_due_date.set_flag&lt;br /&gt;
    expect(@assignment_due_date.flag).to be true&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
* If the function &amp;quot;due_at_is_valid_datetime&amp;quot; returns nil (no errors) for a valid datetime in due_at (no invalid test cases can be added here because model does not allow invalid datetime to be set at all).&amp;lt;syntaxhighlight lang=&amp;quot;ruby&amp;quot;&amp;gt;&lt;br /&gt;
it &amp;quot;due at is valid datetime&amp;quot; do&lt;br /&gt;
    expect(@assignment_due_date.due_at_is_valid_datetime).to be nil&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
* If the function &amp;quot;self.copy&amp;quot; is able to copy due dates from one assignment to another.&amp;lt;syntaxhighlight lang=&amp;quot;ruby&amp;quot;&amp;gt;&lt;br /&gt;
it &amp;quot;copy due dates to new assignment&amp;quot; do&lt;br /&gt;
    new_assignment_id = build(:assignment, id: 999).id&lt;br /&gt;
    old_assignment_id = @assignment_due_date.assignment.id&lt;br /&gt;
    DueDate.copy(old_assignment_id, new_assignment_id)&lt;br /&gt;
    expect(DueDate.where(parent_id: new_assignment_id).count).to eql DueDate.where(parent_id: old_assignment_id).count&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
* If the function &amp;quot;self.set_duedate&amp;quot; is able to create another due date by copying data from an existing due date object.&amp;lt;syntaxhighlight lang=&amp;quot;ruby&amp;quot;&amp;gt;&lt;br /&gt;
it &amp;quot;create new duedate record with values&amp;quot; do&lt;br /&gt;
    DueDate.set_duedate({id: 999}, @assignment_due_date.deadline_type_id,&lt;br /&gt;
                        @assignment_due_date.parent_id, @assignment_due_date.round)&lt;br /&gt;
    new_due_date = DueDate.find_by(id: 999)&lt;br /&gt;
    expect(new_due_date).to be_valid&lt;br /&gt;
    expect(new_due_date.deadline_type_id).to eql @assignment_due_date.deadline_type_id&lt;br /&gt;
    expect(new_due_date.parent_id).to eql @assignment_due_date.parent_id&lt;br /&gt;
    expect(new_due_date.round).to eql @assignment_due_date.round&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
* If the function &amp;quot;self.deadline_sort&amp;quot; is able to sort the due dates in ascending order.&amp;lt;syntaxhighlight lang=&amp;quot;ruby&amp;quot;&amp;gt;&lt;br /&gt;
it &amp;quot;sort duedate records&amp;quot; do&lt;br /&gt;
    sorted_due_dates = @due_dates&lt;br /&gt;
    expect(sorted_due_dates.each_cons(2).all?{|m1, m2| (m1.due_at &amp;lt;=&amp;gt; m2.due_at) != 1}).to eql false&lt;br /&gt;
&lt;br /&gt;
    sorted_due_dates = DueDate.deadline_sort(@due_dates)&lt;br /&gt;
    expect(sorted_due_dates.each_cons(2).all?{|m1, m2| (m1.due_at &amp;lt;=&amp;gt; m2.due_at) != 1}).to eql true&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
* If the function &amp;quot;self.done_in_assignment_round&amp;quot; returns the correct number of rounds for specific inputs. This involves an invalid test case as well for 0 rounds.&amp;lt;syntaxhighlight lang=&amp;quot;ruby&amp;quot;&amp;gt;&lt;br /&gt;
describe &amp;quot;#done_in_assignment_round&amp;quot; do&lt;br /&gt;
    it &amp;quot;return 0 when no response map&amp;quot; do&lt;br /&gt;
      response = ReviewResponseMap.create&lt;br /&gt;
      response.type = &amp;quot;ResponseMap&amp;quot;&lt;br /&gt;
      response.save&lt;br /&gt;
      expect(DueDate.done_in_assignment_round(1, response)).to eql 0&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    it &amp;quot;return round 1 for single round&amp;quot; do&lt;br /&gt;
      response = ReviewResponseMap.create&lt;br /&gt;
      expect(DueDate.done_in_assignment_round(@assignment_due_date.parent_id, response)).to eql 1&lt;br /&gt;
    end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
* If the function &amp;quot;self.get_next_due_date&amp;quot; works as expected. This involves several invalid test cases as well.&amp;lt;syntaxhighlight lang=&amp;quot;ruby&amp;quot;&amp;gt;&lt;br /&gt;
describe &amp;quot;#get_next_due_date&amp;quot; do&lt;br /&gt;
    it &amp;quot;no subsequent due date&amp;quot; do&lt;br /&gt;
      expect(DueDate.get_next_due_date(@assignment_due_date.parent_id)).to be nil&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    it &amp;quot;nil value throws exception&amp;quot; do&lt;br /&gt;
      expect { DueDate.get_next_due_date(nil) }.to raise_exception(ActiveRecord::RecordNotFound)&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    it &amp;quot;get next assignment due date&amp;quot; do&lt;br /&gt;
      due_date = create(:assignment_due_date, deadline_type: @deadline_type,&lt;br /&gt;
        submission_allowed_id: @deadline_right.id, review_allowed_id: @deadline_right.id,&lt;br /&gt;
        review_of_review_allowed_id: @deadline_right.id, due_at: Time.zone.now + 5000)&lt;br /&gt;
      expect(DueDate.get_next_due_date(due_date.parent_id)).to be_valid&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    it &amp;quot;get next due date from topic for staggered deadline&amp;quot; do&lt;br /&gt;
      assignment_id = create(:assignment, staggered_deadline: true, name: &amp;quot;testassignment&amp;quot;).id&lt;br /&gt;
      due_date = create(:topic_due_date, deadline_type: @deadline_type,&lt;br /&gt;
        submission_allowed_id: @deadline_right.id, review_allowed_id: @deadline_right.id,&lt;br /&gt;
        review_of_review_allowed_id: @deadline_right.id, due_at: Time.zone.now + 5000, parent_id: assignment_id)&lt;br /&gt;
      expect(DueDate.get_next_due_date(assignment_id, due_date.parent_id)).to be_valid&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    it &amp;quot;next due date does not exist for staggered deadline&amp;quot; do&lt;br /&gt;
      assignment_id = create(:assignment, staggered_deadline: true, name: &amp;quot;testassignment&amp;quot;).id&lt;br /&gt;
      due_date = create(:topic_due_date, deadline_type: @deadline_type,&lt;br /&gt;
        submission_allowed_id: @deadline_right, review_allowed_id: @deadline_right,&lt;br /&gt;
        review_of_review_allowed_id: @deadline_right, due_at: Time.zone.now + 5000, parent_id: assignment_id)&lt;br /&gt;
      expect(DueDate.get_next_due_date(assignment_id)).to be nil&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    it &amp;quot;next due date is before Time.now for staggered deadline&amp;quot; do&lt;br /&gt;
      assignment_id = create(:assignment, staggered_deadline: true, name: &amp;quot;testassignment&amp;quot;).id&lt;br /&gt;
      due_date = create(:topic_due_date, deadline_type: @deadline_type,&lt;br /&gt;
        submission_allowed_id: @deadline_right, review_allowed_id: @deadline_right,&lt;br /&gt;
        review_of_review_allowed_id: @deadline_right, due_at: Time.zone.now - 5000, parent_id: assignment_id)&lt;br /&gt;
      expect(DueDate.get_next_due_date(assignment_id, due_date.parent_id)).to be nil&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    it &amp;quot;get next due date from assignment for staggered deadline&amp;quot; do&lt;br /&gt;
      assignment_id = create(:assignment, staggered_deadline: true, name: &amp;quot;testassignment&amp;quot;).id&lt;br /&gt;
      due_date = create(:assignment_due_date, deadline_type: @deadline_type,&lt;br /&gt;
        submission_allowed_id: @deadline_right, review_allowed_id: @deadline_right,&lt;br /&gt;
        review_of_review_allowed_id: @deadline_right, due_at: Time.zone.now + 5000, parent_id: assignment_id)&lt;br /&gt;
      expect(DueDate.get_next_due_date(assignment_id)).to be_valid&lt;br /&gt;
    end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
* If the function &amp;quot;self.default_permission&amp;quot; returns the correct default permissions for particular deadline and permission types.&amp;lt;syntaxhighlight lang=&amp;quot;ruby&amp;quot;&amp;gt;&lt;br /&gt;
it &amp;quot;metareview review_of_review_allowed default permission OK&amp;quot; do&lt;br /&gt;
    expect(DueDate.default_permission('metareview', 'review_of_review_allowed')).to be == DeadlineRight::OK&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&amp;lt;syntaxhighlight lang=&amp;quot;ruby&amp;quot;&amp;gt;&lt;br /&gt;
it &amp;quot;review submission_allowed default permission NO&amp;quot; do&lt;br /&gt;
    expect(DueDate.default_permission('review', 'submission_allowed')).to be == DeadlineRight::NO&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
To test this file run the following command:&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
rspec spec/models/due_date_spec.rb&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
The output of this RSpec file is present in below screenshot:&lt;br /&gt;
[[File:Duedaterspec.png]]&lt;br /&gt;
&lt;br /&gt;
Code coverage details of the above RSpec files is present in below screenshot:&lt;br /&gt;
[[File:Duedatecoverage.png]]&lt;br /&gt;
&lt;br /&gt;
Code coverage details of the above RSpec files is present in below screenshot:&lt;br /&gt;
&lt;br /&gt;
=== deadline_helper_spec.rb ===&lt;br /&gt;
This is a test file for testing the functionalities of Deadline_helper.rb file located at app/helpers. Different test cases present in this file are:&lt;br /&gt;
* Check if the factory&amp;lt;ref&amp;gt;{{Cite web|url=http://http://www.semaphoreci.com|access-date=2016-10-28}}&amp;lt;/ref&amp;gt; is valid:  &lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;ruby&amp;quot;&amp;gt;&lt;br /&gt;
it &amp;quot;has a valid factory&amp;quot; do&lt;br /&gt;
    factory = FactoryGirl.build(:topic_due_date)&lt;br /&gt;
    expect(factory).to be_valid&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
* Fail if the due date is invalid:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;ruby&amp;quot;&amp;gt;&lt;br /&gt;
it &amp;quot;should fail because of invalid due_date&amp;quot; do&lt;br /&gt;
      expect { DeadlineHelper.create_topic_deadline(nil, 0, 0)}.to raise_exception(NoMethodError)&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
* If new due_date object is created:&amp;lt;syntaxhighlight lang=&amp;quot;ruby&amp;quot;&amp;gt;&lt;br /&gt;
it &amp;quot;new due_date object created&amp;quot; do&lt;br /&gt;
      DeadlineHelper.create_topic_deadline(@topic_due_date, 0, 1)&lt;br /&gt;
      expect(TopicDueDate.count).to be == 2&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
* due_at should be same for 0 offset:&amp;lt;syntaxhighlight lang=&amp;quot;ruby&amp;quot;&amp;gt;&lt;br /&gt;
 it &amp;quot;due_at should be same for 0 offset&amp;quot; do&lt;br /&gt;
      DeadlineHelper.create_topic_deadline(@topic_due_date, 0, 10)&lt;br /&gt;
      new_due_date = TopicDueDate.find_by(parent_id: 10)&lt;br /&gt;
      expect(new_due_date).to be_valid&lt;br /&gt;
      expect(new_due_date.due_at.to_s).to be == @topic_due_date.due_at.to_s&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
* due_at is calculated correctly if offset is positive:&amp;lt;syntaxhighlight lang=&amp;quot;ruby&amp;quot;&amp;gt;&lt;br /&gt;
it &amp;quot;due_at calculated correctly for positive offset&amp;quot; do&lt;br /&gt;
      DeadlineHelper.create_topic_deadline(@topic_due_date, 5000, 10)&lt;br /&gt;
      new_due_date = TopicDueDate.find_by(parent_id: 10)&lt;br /&gt;
      expect(new_due_date).to be_valid&lt;br /&gt;
      expect(new_due_date.due_at.to_s).to be == (Time.zone.parse(@topic_due_date.due_at.to_s) + 5000).to_s&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
* due_at is calculated correctly if offset is negative:&amp;lt;syntaxhighlight lang=&amp;quot;ruby&amp;quot;&amp;gt;&lt;br /&gt;
it &amp;quot;due_at calculated correctly for negative offset&amp;quot; do&lt;br /&gt;
      DeadlineHelper.create_topic_deadline(@topic_due_date, -5000, 10)&lt;br /&gt;
      new_due_date = TopicDueDate.find_by(parent_id: 10)&lt;br /&gt;
      expect(new_due_date).to be_valid&lt;br /&gt;
      expect(new_due_date.due_at.to_s).to be == (Time.zone.parse(@topic_due_date.due_at.to_s) - 5000).to_s&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;[[asd]]&lt;br /&gt;
* The offset is being converted to integer properly:&amp;lt;syntaxhighlight lang=&amp;quot;ruby&amp;quot;&amp;gt;&lt;br /&gt;
it &amp;quot;offset converted to integer correctly&amp;quot; do&lt;br /&gt;
      DeadlineHelper.create_topic_deadline(@topic_due_date, 5000.15, 10)&lt;br /&gt;
      new_due_date = TopicDueDate.find_by(parent_id: 10)&lt;br /&gt;
      expect(new_due_date).to be_valid&lt;br /&gt;
      expect(new_due_date.due_at.to_s).to be == (Time.zone.parse(@topic_due_date.due_at.to_s) + 5000).to_s&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
To test this file run the following command:&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
rspec spec/models/deadline_helper_spec.rb&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;The output of this RSpec file is present in below screenshot:&lt;br /&gt;
[[File:Deadlinerspec.png]]&lt;br /&gt;
&lt;br /&gt;
Code coverage details of the above RSpec files is present in below screenshot:&lt;br /&gt;
[[File:Deadlinecoverage.png]]&lt;br /&gt;
&lt;br /&gt;
== '''References''' ==&lt;br /&gt;
&amp;quot;[http://www.expertiza.ncsu.edu]&amp;quot;&lt;br /&gt;
&amp;quot;[Ruby on Rails]&amp;quot;. [http://www.rubyonrails.org]. Retrieved 2016-10-28.&lt;br /&gt;
&amp;quot;[Log in to your Code Climate dashboard with GitHub or your email].&amp;quot;. [http://www.codeclimate.com]. Retrieved 2016-10-28.&lt;br /&gt;
&amp;quot;[RSpec: Behaviour Driven Development for Ruby]&amp;quot;. [http://www.rspec.info]. Retrieved 2016-10-28.&lt;br /&gt;
&amp;quot;[Travis CI - Test and Deploy with Confidence]&amp;quot;. [http://www.travis-ci.com link title]. Retrieved 2016-10-28&lt;br /&gt;
&amp;quot;[Working Effectively with Data Factories Using FactoryGirl]&amp;quot;. [http://www.semaphoreci.com]. Retrieved 2016-10-28&lt;/div&gt;</summary>
		<author><name>Nthanik</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=User:Nthanik&amp;diff=103267</id>
		<title>User:Nthanik</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=User:Nthanik&amp;diff=103267"/>
		<updated>2016-10-28T23:14:00Z</updated>

		<summary type="html">&lt;p&gt;Nthanik: moved User:Nthanik to CSC/ECE 517 Fall 2016/E1634.Refactor and write unit test of due date.rb and deadline helper.rb&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;#REDIRECT [[CSC/ECE 517 Fall 2016/E1634.Refactor and write unit test of due date.rb and deadline helper.rb]]&lt;/div&gt;</summary>
		<author><name>Nthanik</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2016/E1634.Refactor_and_write_unit_test_of_due_date.rb_and_deadline_helper.rb&amp;diff=103266</id>
		<title>CSC/ECE 517 Fall 2016/E1634.Refactor and write unit test of due date.rb and deadline helper.rb</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2016/E1634.Refactor_and_write_unit_test_of_due_date.rb_and_deadline_helper.rb&amp;diff=103266"/>
		<updated>2016-10-28T23:14:00Z</updated>

		<summary type="html">&lt;p&gt;Nthanik: moved User:Nthanik to CSC/ECE 517 Fall 2016/E1634.Refactor and write unit test of due date.rb and deadline helper.rb&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== '''Introduction''' ==&lt;br /&gt;
&lt;br /&gt;
=== Expertiza ===&lt;br /&gt;
Expertiza&amp;lt;ref&amp;gt;{{Cite web|url=http://www.expertiza.ncsu.edu|access-date=2016-10-28}}&amp;lt;/ref&amp;gt; is an open source project for school assignment management for instructors and students based on the Ruby on Rails&amp;lt;ref&amp;gt;{{Cite web|url=http://www.rubyonrails.org|access-date=2016-10-28}}&amp;lt;/ref&amp;gt; framework. Expertiza allows the instructor to create new assignments and customise new or existing assignments. It also allows the instructor to create a list of topics the students can sign up for. Students can form teams in Expertiza to work on various projects and assignments. Students can also peer review other students' submissions. Expertiza supports submission across various document types, including the URLs and word documents. Expertiza provides a dashboard for all the assignments corresponding to a course and provides absolute control to the Instructors and Teaching Assistants. In addition to assignments, it encompasses peer reviews wherein participants are allowed to provide feedback anonymously about each other's work thereby providing scope for the better outcome. The due_date.rb file is responsible for informing the users about the deadline for submission of the each assignment. Due dates in Expertiza have their association with many other components like assignments, reviews etc.&lt;br /&gt;
&lt;br /&gt;
=== Code Climate ===&lt;br /&gt;
Code Climate&amp;lt;ref&amp;gt;{{Cite web|url=https://codeclimate.com/dashboard|title=Log in to your Code Climate dashboard with GitHub or your email.|website=codeclimate.com|access-date=2016-10-28}}&amp;lt;/ref&amp;gt; is a tool that runs static analysis on a GitHub project and outputs many details like test coverage, complexity, duplication, security, style, and more. There is a Google Chrome extension to integrate the Code Climate results generated directly into GitHub which is visible when browsing the repository on the browser. It allows us to see issues displayed directly inside GitHub's UI, to review which lines are covered in diffs and files, and add repositories and open tickets without changing your workflow.&lt;br /&gt;
&lt;br /&gt;
== '''Tasks Identified''' ==&lt;br /&gt;
To install Code climate Chrome Extension that highlights the duplicated code.&lt;br /&gt;
&lt;br /&gt;
To refactor the following two files:&lt;br /&gt;
* Due_date.rb&lt;br /&gt;
** Ternary operators must not be nested. Prefer `if` or `else` constructs instead.&lt;br /&gt;
** Useless assignment to variable - `sorted_deadlines`.&lt;br /&gt;
** Prefer `each` over `for`.&lt;br /&gt;
** Use `find_by` instead of `where.first`.&lt;br /&gt;
** Correct the use of Time function&lt;br /&gt;
* Deadline_helper.rb&lt;br /&gt;
** Do not use `Time.now` without zone. Use one of `Time.zone.now`, `Time.current`, `Time.now.in_time_zone`, `Time.now.utc`, `Time.now.getlocal`, `Time.now.iso8601`, `Time.now.jisx0301`, `Time.now.rfc3339`, `Time.now.to_i`, `Time.now.to_f` instead.&lt;br /&gt;
** Trailing whitespace detected.&lt;br /&gt;
** Extra empty line detected at module body end.&lt;br /&gt;
&lt;br /&gt;
* Create respective RSpec&amp;lt;ref&amp;gt;{{Cite web|url=http://www.rspec.info|access-date=2016-10-28}}&amp;lt;/ref&amp;gt;files in /spec/models/ and /spec/helper folder and write unit tests for each method in due_date.rb and deadline_helper.rb.&lt;br /&gt;
&lt;br /&gt;
== '''Current Implementation''' ==&lt;br /&gt;
DueDate is a Model class to manage the deadlines of an assignment. It has methods for setting due dates for an assignment, copying due dates from one assignment to a new assignment etc. DeadlineHelper provides helper functions that help DueDate perform certain tasks. The assignment focuses on refactoring some of the methods based on warnings received from Code Climate's static analysis and modifying the language to make it more Ruby-friendly. The assignment also involves writing unit test cases for due_date.rb and deadline_helper.rb in order to increase test coverage. &lt;br /&gt;
&lt;br /&gt;
The goal of this project is to attempt to make this part of the application easier to read and write unit test cases that the application must pass. &lt;br /&gt;
&lt;br /&gt;
== '''Changed Implementation''' ==&lt;br /&gt;
Changes implemented involves refactoring the code and making it more understandable by adding comments in the code.&lt;br /&gt;
&lt;br /&gt;
The modified files are&lt;br /&gt;
* Due_date.rb (path: /app/models)&lt;br /&gt;
&lt;br /&gt;
* Deadline_helper.rb (path: /app/helpers)&lt;br /&gt;
Testing files&lt;br /&gt;
* Due_date_spec.rb (path: /spec/models)&lt;br /&gt;
* Deadline_helper_spec.rb (path: /spec/helpers)&lt;br /&gt;
=== Due_date.rb ===&lt;br /&gt;
* Converted for..in loop to object.each in order to follow better Ruby syntax.&lt;br /&gt;
* Unnecessary assignment to sorted_deadlines removed.&lt;br /&gt;
* Nested ternary operators have been changed to if..else in order to make it more readable.&lt;br /&gt;
[[File:Duedaterb.png]]&lt;br /&gt;
* Changed where(...).first to find_by(...) which is the newer recommended syntax.&lt;br /&gt;
* Corrected the Time.now functions by adding the correct zones to them such as Time.zone.now.&lt;br /&gt;
* Removed trailing whitespaces.&lt;br /&gt;
[[File:DueDaterb2.png]]&lt;br /&gt;
&lt;br /&gt;
=== Deadline_helper.rb ===&lt;br /&gt;
* Time functions were changed to functions with zones&lt;br /&gt;
* Extra line removed&lt;br /&gt;
[[File:Deadlinehelper.png]]&lt;br /&gt;
&lt;br /&gt;
== '''RSpec testing''' ==&lt;br /&gt;
There were no existing tests for the functions in due_date.rb and deadline_helper.rb. We have added exhaustive set of RSpec tests to test all the code. We have added two new spec files 'due_date_spec.rb' and ‘deadline_helper_spec.rb’ which cover the testing scenarios for the functions in ‘due_date.rb’ and ‘deadline_helper.rb’.For both of these two files, all Travis CI&amp;lt;ref&amp;gt;{{Cite web|url=http://http://www.travis-ci.com|access-date=2016-10-28}}&amp;lt;/ref&amp;gt; test cases have passed.&lt;br /&gt;
&lt;br /&gt;
These RSpec files have 100% code coverage visible at: /coverage/index.html&lt;br /&gt;
&lt;br /&gt;
=== due_date_spec.rb ===&lt;br /&gt;
This file is located at spec/models and tests the functionalities of the due_date.rb file located in app/models. There are 18 test cases in total which are listed below.&lt;br /&gt;
* If the factory is successfully able to build the due_date objects.&amp;lt;syntaxhighlight lang=&amp;quot;ruby&amp;quot;&amp;gt;&lt;br /&gt;
it &amp;quot;due date factory created successfully&amp;quot; do&lt;br /&gt;
    expect(@assignment_due_date).to be_valid&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&amp;lt;syntaxhighlight lang=&amp;quot;ruby&amp;quot;&amp;gt;&lt;br /&gt;
it &amp;quot;due dates created correctly&amp;quot; do&lt;br /&gt;
    expect(@due_dates.length).to be == 10&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
* If the function &amp;quot;set_flag&amp;quot; successfully sets the due_date flag.&amp;lt;syntaxhighlight lang=&amp;quot;ruby&amp;quot;&amp;gt;&lt;br /&gt;
it &amp;quot;due date flag is set&amp;quot; do&lt;br /&gt;
    expect(@assignment_due_date.flag).to be false&lt;br /&gt;
    @assignment_due_date.set_flag&lt;br /&gt;
    expect(@assignment_due_date.flag).to be true&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
* If the function &amp;quot;due_at_is_valid_datetime&amp;quot; returns nil (no errors) for a valid datetime in due_at (no invalid test cases can be added here because model does not allow invalid datetime to be set at all).&amp;lt;syntaxhighlight lang=&amp;quot;ruby&amp;quot;&amp;gt;&lt;br /&gt;
it &amp;quot;due at is valid datetime&amp;quot; do&lt;br /&gt;
    expect(@assignment_due_date.due_at_is_valid_datetime).to be nil&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
* If the function &amp;quot;self.copy&amp;quot; is able to copy due dates from one assignment to another.&amp;lt;syntaxhighlight lang=&amp;quot;ruby&amp;quot;&amp;gt;&lt;br /&gt;
it &amp;quot;copy due dates to new assignment&amp;quot; do&lt;br /&gt;
    new_assignment_id = build(:assignment, id: 999).id&lt;br /&gt;
    old_assignment_id = @assignment_due_date.assignment.id&lt;br /&gt;
    DueDate.copy(old_assignment_id, new_assignment_id)&lt;br /&gt;
    expect(DueDate.where(parent_id: new_assignment_id).count).to eql DueDate.where(parent_id: old_assignment_id).count&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
* If the function &amp;quot;self.set_duedate&amp;quot; is able to create another due date by copying data from an existing due date object.&amp;lt;syntaxhighlight lang=&amp;quot;ruby&amp;quot;&amp;gt;&lt;br /&gt;
it &amp;quot;create new duedate record with values&amp;quot; do&lt;br /&gt;
    DueDate.set_duedate({id: 999}, @assignment_due_date.deadline_type_id,&lt;br /&gt;
                        @assignment_due_date.parent_id, @assignment_due_date.round)&lt;br /&gt;
    new_due_date = DueDate.find_by(id: 999)&lt;br /&gt;
    expect(new_due_date).to be_valid&lt;br /&gt;
    expect(new_due_date.deadline_type_id).to eql @assignment_due_date.deadline_type_id&lt;br /&gt;
    expect(new_due_date.parent_id).to eql @assignment_due_date.parent_id&lt;br /&gt;
    expect(new_due_date.round).to eql @assignment_due_date.round&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
* If the function &amp;quot;self.deadline_sort&amp;quot; is able to sort the due dates in ascending order.&amp;lt;syntaxhighlight lang=&amp;quot;ruby&amp;quot;&amp;gt;&lt;br /&gt;
it &amp;quot;sort duedate records&amp;quot; do&lt;br /&gt;
    sorted_due_dates = @due_dates&lt;br /&gt;
    expect(sorted_due_dates.each_cons(2).all?{|m1, m2| (m1.due_at &amp;lt;=&amp;gt; m2.due_at) != 1}).to eql false&lt;br /&gt;
&lt;br /&gt;
    sorted_due_dates = DueDate.deadline_sort(@due_dates)&lt;br /&gt;
    expect(sorted_due_dates.each_cons(2).all?{|m1, m2| (m1.due_at &amp;lt;=&amp;gt; m2.due_at) != 1}).to eql true&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
* If the function &amp;quot;self.done_in_assignment_round&amp;quot; returns the correct number of rounds for specific inputs. This involves an invalid test case as well for 0 rounds.&amp;lt;syntaxhighlight lang=&amp;quot;ruby&amp;quot;&amp;gt;&lt;br /&gt;
describe &amp;quot;#done_in_assignment_round&amp;quot; do&lt;br /&gt;
    it &amp;quot;return 0 when no response map&amp;quot; do&lt;br /&gt;
      response = ReviewResponseMap.create&lt;br /&gt;
      response.type = &amp;quot;ResponseMap&amp;quot;&lt;br /&gt;
      response.save&lt;br /&gt;
      expect(DueDate.done_in_assignment_round(1, response)).to eql 0&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    it &amp;quot;return round 1 for single round&amp;quot; do&lt;br /&gt;
      response = ReviewResponseMap.create&lt;br /&gt;
      expect(DueDate.done_in_assignment_round(@assignment_due_date.parent_id, response)).to eql 1&lt;br /&gt;
    end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
* If the function &amp;quot;self.get_next_due_date&amp;quot; works as expected. This involves several invalid test cases as well.&amp;lt;syntaxhighlight lang=&amp;quot;ruby&amp;quot;&amp;gt;&lt;br /&gt;
describe &amp;quot;#get_next_due_date&amp;quot; do&lt;br /&gt;
    it &amp;quot;no subsequent due date&amp;quot; do&lt;br /&gt;
      expect(DueDate.get_next_due_date(@assignment_due_date.parent_id)).to be nil&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    it &amp;quot;nil value throws exception&amp;quot; do&lt;br /&gt;
      expect { DueDate.get_next_due_date(nil) }.to raise_exception(ActiveRecord::RecordNotFound)&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    it &amp;quot;get next assignment due date&amp;quot; do&lt;br /&gt;
      due_date = create(:assignment_due_date, deadline_type: @deadline_type,&lt;br /&gt;
        submission_allowed_id: @deadline_right.id, review_allowed_id: @deadline_right.id,&lt;br /&gt;
        review_of_review_allowed_id: @deadline_right.id, due_at: Time.zone.now + 5000)&lt;br /&gt;
      expect(DueDate.get_next_due_date(due_date.parent_id)).to be_valid&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    it &amp;quot;get next due date from topic for staggered deadline&amp;quot; do&lt;br /&gt;
      assignment_id = create(:assignment, staggered_deadline: true, name: &amp;quot;testassignment&amp;quot;).id&lt;br /&gt;
      due_date = create(:topic_due_date, deadline_type: @deadline_type,&lt;br /&gt;
        submission_allowed_id: @deadline_right.id, review_allowed_id: @deadline_right.id,&lt;br /&gt;
        review_of_review_allowed_id: @deadline_right.id, due_at: Time.zone.now + 5000, parent_id: assignment_id)&lt;br /&gt;
      expect(DueDate.get_next_due_date(assignment_id, due_date.parent_id)).to be_valid&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    it &amp;quot;next due date does not exist for staggered deadline&amp;quot; do&lt;br /&gt;
      assignment_id = create(:assignment, staggered_deadline: true, name: &amp;quot;testassignment&amp;quot;).id&lt;br /&gt;
      due_date = create(:topic_due_date, deadline_type: @deadline_type,&lt;br /&gt;
        submission_allowed_id: @deadline_right, review_allowed_id: @deadline_right,&lt;br /&gt;
        review_of_review_allowed_id: @deadline_right, due_at: Time.zone.now + 5000, parent_id: assignment_id)&lt;br /&gt;
      expect(DueDate.get_next_due_date(assignment_id)).to be nil&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    it &amp;quot;next due date is before Time.now for staggered deadline&amp;quot; do&lt;br /&gt;
      assignment_id = create(:assignment, staggered_deadline: true, name: &amp;quot;testassignment&amp;quot;).id&lt;br /&gt;
      due_date = create(:topic_due_date, deadline_type: @deadline_type,&lt;br /&gt;
        submission_allowed_id: @deadline_right, review_allowed_id: @deadline_right,&lt;br /&gt;
        review_of_review_allowed_id: @deadline_right, due_at: Time.zone.now - 5000, parent_id: assignment_id)&lt;br /&gt;
      expect(DueDate.get_next_due_date(assignment_id, due_date.parent_id)).to be nil&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    it &amp;quot;get next due date from assignment for staggered deadline&amp;quot; do&lt;br /&gt;
      assignment_id = create(:assignment, staggered_deadline: true, name: &amp;quot;testassignment&amp;quot;).id&lt;br /&gt;
      due_date = create(:assignment_due_date, deadline_type: @deadline_type,&lt;br /&gt;
        submission_allowed_id: @deadline_right, review_allowed_id: @deadline_right,&lt;br /&gt;
        review_of_review_allowed_id: @deadline_right, due_at: Time.zone.now + 5000, parent_id: assignment_id)&lt;br /&gt;
      expect(DueDate.get_next_due_date(assignment_id)).to be_valid&lt;br /&gt;
    end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
* If the function &amp;quot;self.default_permission&amp;quot; returns the correct default permissions for particular deadline and permission types.&amp;lt;syntaxhighlight lang=&amp;quot;ruby&amp;quot;&amp;gt;&lt;br /&gt;
it &amp;quot;metareview review_of_review_allowed default permission OK&amp;quot; do&lt;br /&gt;
    expect(DueDate.default_permission('metareview', 'review_of_review_allowed')).to be == DeadlineRight::OK&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&amp;lt;syntaxhighlight lang=&amp;quot;ruby&amp;quot;&amp;gt;&lt;br /&gt;
it &amp;quot;review submission_allowed default permission NO&amp;quot; do&lt;br /&gt;
    expect(DueDate.default_permission('review', 'submission_allowed')).to be == DeadlineRight::NO&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
To test this file run the following command:&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
rspec spec/models/due_date_spec.rb&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
The output of this RSpec file is present in below screenshot:&lt;br /&gt;
[[File:Duedaterspec.png]]&lt;br /&gt;
&lt;br /&gt;
Code coverage details of the above RSpec files is present in below screenshot:&lt;br /&gt;
[[File:Duedatecoverage.png]]&lt;br /&gt;
&lt;br /&gt;
Code coverage details of the above RSpec files is present in below screenshot:&lt;br /&gt;
&lt;br /&gt;
=== deadline_helper_spec.rb ===&lt;br /&gt;
This is a test file for testing the functionalities of Deadline_helper.rb file located at app/helpers. Different test cases present in this file are:&lt;br /&gt;
* Check if the factory&amp;lt;ref&amp;gt;{{Cite web|url=http://http://www.semaphoreci.com|access-date=2016-10-28}}&amp;lt;/ref&amp;gt; is valid:  &lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;ruby&amp;quot;&amp;gt;&lt;br /&gt;
it &amp;quot;has a valid factory&amp;quot; do&lt;br /&gt;
    factory = FactoryGirl.build(:topic_due_date)&lt;br /&gt;
    expect(factory).to be_valid&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
* Fail if the due date is invalid:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;ruby&amp;quot;&amp;gt;&lt;br /&gt;
it &amp;quot;should fail because of invalid due_date&amp;quot; do&lt;br /&gt;
      expect { DeadlineHelper.create_topic_deadline(nil, 0, 0)}.to raise_exception(NoMethodError)&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
* If new due_date object is created:&amp;lt;syntaxhighlight lang=&amp;quot;ruby&amp;quot;&amp;gt;&lt;br /&gt;
it &amp;quot;new due_date object created&amp;quot; do&lt;br /&gt;
      DeadlineHelper.create_topic_deadline(@topic_due_date, 0, 1)&lt;br /&gt;
      expect(TopicDueDate.count).to be == 2&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
* due_at should be same for 0 offset:&amp;lt;syntaxhighlight lang=&amp;quot;ruby&amp;quot;&amp;gt;&lt;br /&gt;
 it &amp;quot;due_at should be same for 0 offset&amp;quot; do&lt;br /&gt;
      DeadlineHelper.create_topic_deadline(@topic_due_date, 0, 10)&lt;br /&gt;
      new_due_date = TopicDueDate.find_by(parent_id: 10)&lt;br /&gt;
      expect(new_due_date).to be_valid&lt;br /&gt;
      expect(new_due_date.due_at.to_s).to be == @topic_due_date.due_at.to_s&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
* due_at is calculated correctly if offset is positive:&amp;lt;syntaxhighlight lang=&amp;quot;ruby&amp;quot;&amp;gt;&lt;br /&gt;
it &amp;quot;due_at calculated correctly for positive offset&amp;quot; do&lt;br /&gt;
      DeadlineHelper.create_topic_deadline(@topic_due_date, 5000, 10)&lt;br /&gt;
      new_due_date = TopicDueDate.find_by(parent_id: 10)&lt;br /&gt;
      expect(new_due_date).to be_valid&lt;br /&gt;
      expect(new_due_date.due_at.to_s).to be == (Time.zone.parse(@topic_due_date.due_at.to_s) + 5000).to_s&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
* due_at is calculated correctly if offset is negative:&amp;lt;syntaxhighlight lang=&amp;quot;ruby&amp;quot;&amp;gt;&lt;br /&gt;
it &amp;quot;due_at calculated correctly for negative offset&amp;quot; do&lt;br /&gt;
      DeadlineHelper.create_topic_deadline(@topic_due_date, -5000, 10)&lt;br /&gt;
      new_due_date = TopicDueDate.find_by(parent_id: 10)&lt;br /&gt;
      expect(new_due_date).to be_valid&lt;br /&gt;
      expect(new_due_date.due_at.to_s).to be == (Time.zone.parse(@topic_due_date.due_at.to_s) - 5000).to_s&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;[[asd]]&lt;br /&gt;
* The offset is being converted to integer properly:&amp;lt;syntaxhighlight lang=&amp;quot;ruby&amp;quot;&amp;gt;&lt;br /&gt;
it &amp;quot;offset converted to integer correctly&amp;quot; do&lt;br /&gt;
      DeadlineHelper.create_topic_deadline(@topic_due_date, 5000.15, 10)&lt;br /&gt;
      new_due_date = TopicDueDate.find_by(parent_id: 10)&lt;br /&gt;
      expect(new_due_date).to be_valid&lt;br /&gt;
      expect(new_due_date.due_at.to_s).to be == (Time.zone.parse(@topic_due_date.due_at.to_s) + 5000).to_s&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
To test this file run the following command:&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
rspec spec/models/deadline_helper_spec.rb&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;The output of this RSpec file is present in below screenshot:&lt;br /&gt;
[[File:Deadlinerspec.png]]&lt;br /&gt;
&lt;br /&gt;
Code coverage details of the above RSpec files is present in below screenshot:&lt;br /&gt;
[[File:Deadlinecoverage.png]]&lt;br /&gt;
&lt;br /&gt;
== '''References''' ==&lt;br /&gt;
&amp;quot;[http://www.expertiza.ncsu.edu]&amp;quot;&lt;br /&gt;
&amp;quot;[Ruby on Rails]&amp;quot;. [http://www.rubyonrails.org]. Retrieved 2016-10-28.&lt;br /&gt;
&amp;quot;[Log in to your Code Climate dashboard with GitHub or your email].&amp;quot;. [http://www.codeclimate.com]. Retrieved 2016-10-28.&lt;br /&gt;
&amp;quot;[RSpec: Behaviour Driven Development for Ruby]&amp;quot;. [http://www.rspec.info]. Retrieved 2016-10-28.&lt;br /&gt;
&amp;quot;[Travis CI - Test and Deploy with Confidence]&amp;quot;. [http://www.travis-ci.com link title]. Retrieved 2016-10-28&lt;br /&gt;
&amp;quot;[Working Effectively with Data Factories Using FactoryGirl]&amp;quot;. [http://www.semaphoreci.com]. Retrieved 2016-10-28&lt;/div&gt;</summary>
		<author><name>Nthanik</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2016/E1634.Refactor_and_write_unit_test_of_due_date.rb_and_deadline_helper.rb&amp;diff=103255</id>
		<title>CSC/ECE 517 Fall 2016/E1634.Refactor and write unit test of due date.rb and deadline helper.rb</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2016/E1634.Refactor_and_write_unit_test_of_due_date.rb_and_deadline_helper.rb&amp;diff=103255"/>
		<updated>2016-10-28T23:08:28Z</updated>

		<summary type="html">&lt;p&gt;Nthanik: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== '''Introduction''' ==&lt;br /&gt;
&lt;br /&gt;
=== Expertiza ===&lt;br /&gt;
Expertiza&amp;lt;ref&amp;gt;{{Cite web|url=http://www.expertiza.ncsu.edu|access-date=2016-10-28}}&amp;lt;/ref&amp;gt; is an open source project for school assignment management for instructors and students based on the Ruby on Rails&amp;lt;ref&amp;gt;{{Cite web|url=http://www.rubyonrails.org|access-date=2016-10-28}}&amp;lt;/ref&amp;gt; framework. Expertiza allows the instructor to create new assignments and customise new or existing assignments. It also allows the instructor to create a list of topics the students can sign up for. Students can form teams in Expertiza to work on various projects and assignments. Students can also peer review other students' submissions. Expertiza supports submission across various document types, including the URLs and word documents. Expertiza provides a dashboard for all the assignments corresponding to a course and provides absolute control to the Instructors and Teaching Assistants. In addition to assignments, it encompasses peer reviews wherein participants are allowed to provide feedback anonymously about each other's work thereby providing scope for the better outcome. The due_date.rb file is responsible for informing the users about the deadline for submission of the each assignment. Due dates in Expertiza have their association with many other components like assignments, reviews etc.&lt;br /&gt;
&lt;br /&gt;
=== Code Climate ===&lt;br /&gt;
Code Climate&amp;lt;ref&amp;gt;{{Cite web|url=https://codeclimate.com/dashboard|title=Log in to your Code Climate dashboard with GitHub or your email.|website=codeclimate.com|access-date=2016-10-28}}&amp;lt;/ref&amp;gt; is a tool that runs static analysis on a GitHub project and outputs many details like test coverage, complexity, duplication, security, style, and more. There is a Google Chrome extension to integrate the Code Climate results generated directly into GitHub which is visible when browsing the repository on the browser. It allows us to see issues displayed directly inside GitHub's UI, to review which lines are covered in diffs and files, and add repositories and open tickets without changing your workflow.&lt;br /&gt;
&lt;br /&gt;
== '''Tasks Identified''' ==&lt;br /&gt;
To install Code climate Chrome Extension that highlights the duplicated code.&lt;br /&gt;
&lt;br /&gt;
To refactor the following two files:&lt;br /&gt;
* Due_date.rb&lt;br /&gt;
** Ternary operators must not be nested. Prefer `if` or `else` constructs instead.&lt;br /&gt;
** Useless assignment to variable - `sorted_deadlines`.&lt;br /&gt;
** Prefer `each` over `for`.&lt;br /&gt;
** Use `find_by` instead of `where.first`.&lt;br /&gt;
** Correct the use of Time function&lt;br /&gt;
* Deadline_helper.rb&lt;br /&gt;
** Do not use `Time.now` without zone. Use one of `Time.zone.now`, `Time.current`, `Time.now.in_time_zone`, `Time.now.utc`, `Time.now.getlocal`, `Time.now.iso8601`, `Time.now.jisx0301`, `Time.now.rfc3339`, `Time.now.to_i`, `Time.now.to_f` instead.&lt;br /&gt;
** Trailing whitespace detected.&lt;br /&gt;
** Extra empty line detected at module body end.&lt;br /&gt;
&lt;br /&gt;
* Create respective RSpec&amp;lt;ref&amp;gt;{{Cite web|url=http://www.rspec.info|access-date=2016-10-28}}&amp;lt;/ref&amp;gt;files in /spec/models/ and /spec/helper folder and write unit tests for each method in due_date.rb and deadline_helper.rb.&lt;br /&gt;
&lt;br /&gt;
== '''Current Implementation''' ==&lt;br /&gt;
DueDate is a Model class to manage the deadlines of an assignment. It has methods for setting due dates for an assignment, copying due dates from one assignment to a new assignment etc. DeadlineHelper provides helper functions that help DueDate perform certain tasks. The assignment focuses on refactoring some of the methods based on warnings received from Code Climate's static analysis and modifying the language to make it more Ruby-friendly. The assignment also involves writing unit test cases for due_date.rb and deadline_helper.rb in order to increase test coverage. &lt;br /&gt;
&lt;br /&gt;
The goal of this project is to attempt to make this part of the application easier to read and write unit test cases that the application must pass. &lt;br /&gt;
&lt;br /&gt;
== '''Changed Implementation''' ==&lt;br /&gt;
Changes implemented involves refactoring the code and making it more understandable by adding comments in the code.&lt;br /&gt;
&lt;br /&gt;
The modified files are&lt;br /&gt;
* Due_date.rb (path: /app/models)&lt;br /&gt;
&lt;br /&gt;
* Deadline_helper.rb (path: /app/helpers)&lt;br /&gt;
Testing files&lt;br /&gt;
* Due_date_spec.rb (path: /spec/models)&lt;br /&gt;
* Deadline_helper_spec.rb (path: /spec/helpers)&lt;br /&gt;
=== Due_date.rb ===&lt;br /&gt;
* Converted for..in loop to object.each in order to follow better Ruby syntax.&lt;br /&gt;
* Unnecessary assignment to sorted_deadlines removed.&lt;br /&gt;
* Nested ternary operators have been changed to if..else in order to make it more readable.&lt;br /&gt;
[[File:Duedaterb.png]]&lt;br /&gt;
* Changed where(...).first to find_by(...) which is the newer recommended syntax.&lt;br /&gt;
* Corrected the Time.now functions by adding the correct zones to them such as Time.zone.now.&lt;br /&gt;
* Removed trailing whitespaces.&lt;br /&gt;
[[File:DueDaterb2.png]]&lt;br /&gt;
&lt;br /&gt;
=== Deadline_helper.rb ===&lt;br /&gt;
* Time functions were changed to functions with zones&lt;br /&gt;
* Extra line removed&lt;br /&gt;
[[File:Deadlinehelper.png]]&lt;br /&gt;
&lt;br /&gt;
== '''RSpec testing''' ==&lt;br /&gt;
There were no existing tests for the functions in due_date.rb and deadline_helper.rb. We have added exhaustive set of RSpec tests to test all the code. We have added two new spec files 'due_date_spec.rb' and ‘deadline_helper_spec.rb’ which cover the testing scenarios for the functions in ‘due_date.rb’ and ‘deadline_helper.rb’.For both of these two files, all Travis CI&amp;lt;ref&amp;gt;{{Cite web|url=http://http://www.travis-ci.com|access-date=2016-10-28}}&amp;lt;/ref&amp;gt; test cases have passed.&lt;br /&gt;
&lt;br /&gt;
These RSpec files have 100% code coverage visible at: /coverage/index.html&lt;br /&gt;
&lt;br /&gt;
=== due_date_spec.rb ===&lt;br /&gt;
This file is located at spec/models and tests the functionalities of the due_date.rb file located in app/models. There are 18 test cases in total which are listed below.&lt;br /&gt;
* If the factory is successfully able to build the due_date objects.&amp;lt;syntaxhighlight lang=&amp;quot;ruby&amp;quot;&amp;gt;&lt;br /&gt;
it &amp;quot;due date factory created successfully&amp;quot; do&lt;br /&gt;
    expect(@assignment_due_date).to be_valid&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&amp;lt;syntaxhighlight lang=&amp;quot;ruby&amp;quot;&amp;gt;&lt;br /&gt;
it &amp;quot;due dates created correctly&amp;quot; do&lt;br /&gt;
    expect(@due_dates.length).to be == 10&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
* If the function &amp;quot;set_flag&amp;quot; successfully sets the due_date flag.&amp;lt;syntaxhighlight lang=&amp;quot;ruby&amp;quot;&amp;gt;&lt;br /&gt;
it &amp;quot;due date flag is set&amp;quot; do&lt;br /&gt;
    expect(@assignment_due_date.flag).to be false&lt;br /&gt;
    @assignment_due_date.set_flag&lt;br /&gt;
    expect(@assignment_due_date.flag).to be true&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
* If the function &amp;quot;due_at_is_valid_datetime&amp;quot; returns nil (no errors) for a valid datetime in due_at (no invalid test cases can be added here because model does not allow invalid datetime to be set at all).&amp;lt;syntaxhighlight lang=&amp;quot;ruby&amp;quot;&amp;gt;&lt;br /&gt;
it &amp;quot;due at is valid datetime&amp;quot; do&lt;br /&gt;
    expect(@assignment_due_date.due_at_is_valid_datetime).to be nil&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
* If the function &amp;quot;self.copy&amp;quot; is able to copy due dates from one assignment to another.&amp;lt;syntaxhighlight lang=&amp;quot;ruby&amp;quot;&amp;gt;&lt;br /&gt;
it &amp;quot;copy due dates to new assignment&amp;quot; do&lt;br /&gt;
    new_assignment_id = build(:assignment, id: 999).id&lt;br /&gt;
    old_assignment_id = @assignment_due_date.assignment.id&lt;br /&gt;
    DueDate.copy(old_assignment_id, new_assignment_id)&lt;br /&gt;
    expect(DueDate.where(parent_id: new_assignment_id).count).to eql DueDate.where(parent_id: old_assignment_id).count&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
* If the function &amp;quot;self.set_duedate&amp;quot; is able to create another due date by copying data from an existing due date object.&amp;lt;syntaxhighlight lang=&amp;quot;ruby&amp;quot;&amp;gt;&lt;br /&gt;
it &amp;quot;create new duedate record with values&amp;quot; do&lt;br /&gt;
    DueDate.set_duedate({id: 999}, @assignment_due_date.deadline_type_id,&lt;br /&gt;
                        @assignment_due_date.parent_id, @assignment_due_date.round)&lt;br /&gt;
    new_due_date = DueDate.find_by(id: 999)&lt;br /&gt;
    expect(new_due_date).to be_valid&lt;br /&gt;
    expect(new_due_date.deadline_type_id).to eql @assignment_due_date.deadline_type_id&lt;br /&gt;
    expect(new_due_date.parent_id).to eql @assignment_due_date.parent_id&lt;br /&gt;
    expect(new_due_date.round).to eql @assignment_due_date.round&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
* If the function &amp;quot;self.deadline_sort&amp;quot; is able to sort the due dates in ascending order.&amp;lt;syntaxhighlight lang=&amp;quot;ruby&amp;quot;&amp;gt;&lt;br /&gt;
it &amp;quot;sort duedate records&amp;quot; do&lt;br /&gt;
    sorted_due_dates = @due_dates&lt;br /&gt;
    expect(sorted_due_dates.each_cons(2).all?{|m1, m2| (m1.due_at &amp;lt;=&amp;gt; m2.due_at) != 1}).to eql false&lt;br /&gt;
&lt;br /&gt;
    sorted_due_dates = DueDate.deadline_sort(@due_dates)&lt;br /&gt;
    expect(sorted_due_dates.each_cons(2).all?{|m1, m2| (m1.due_at &amp;lt;=&amp;gt; m2.due_at) != 1}).to eql true&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
* If the function &amp;quot;self.done_in_assignment_round&amp;quot; returns the correct number of rounds for specific inputs. This involves an invalid test case as well for 0 rounds.&amp;lt;syntaxhighlight lang=&amp;quot;ruby&amp;quot;&amp;gt;&lt;br /&gt;
describe &amp;quot;#done_in_assignment_round&amp;quot; do&lt;br /&gt;
    it &amp;quot;return 0 when no response map&amp;quot; do&lt;br /&gt;
      response = ReviewResponseMap.create&lt;br /&gt;
      response.type = &amp;quot;ResponseMap&amp;quot;&lt;br /&gt;
      response.save&lt;br /&gt;
      expect(DueDate.done_in_assignment_round(1, response)).to eql 0&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    it &amp;quot;return round 1 for single round&amp;quot; do&lt;br /&gt;
      response = ReviewResponseMap.create&lt;br /&gt;
      expect(DueDate.done_in_assignment_round(@assignment_due_date.parent_id, response)).to eql 1&lt;br /&gt;
    end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
* If the function &amp;quot;self.get_next_due_date&amp;quot; works as expected. This involves several invalid test cases as well.&amp;lt;syntaxhighlight lang=&amp;quot;ruby&amp;quot;&amp;gt;&lt;br /&gt;
describe &amp;quot;#get_next_due_date&amp;quot; do&lt;br /&gt;
    it &amp;quot;no subsequent due date&amp;quot; do&lt;br /&gt;
      expect(DueDate.get_next_due_date(@assignment_due_date.parent_id)).to be nil&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    it &amp;quot;nil value throws exception&amp;quot; do&lt;br /&gt;
      expect { DueDate.get_next_due_date(nil) }.to raise_exception(ActiveRecord::RecordNotFound)&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    it &amp;quot;get next assignment due date&amp;quot; do&lt;br /&gt;
      due_date = create(:assignment_due_date, deadline_type: @deadline_type,&lt;br /&gt;
        submission_allowed_id: @deadline_right.id, review_allowed_id: @deadline_right.id,&lt;br /&gt;
        review_of_review_allowed_id: @deadline_right.id, due_at: Time.zone.now + 5000)&lt;br /&gt;
      expect(DueDate.get_next_due_date(due_date.parent_id)).to be_valid&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    it &amp;quot;get next due date from topic for staggered deadline&amp;quot; do&lt;br /&gt;
      assignment_id = create(:assignment, staggered_deadline: true, name: &amp;quot;testassignment&amp;quot;).id&lt;br /&gt;
      due_date = create(:topic_due_date, deadline_type: @deadline_type,&lt;br /&gt;
        submission_allowed_id: @deadline_right.id, review_allowed_id: @deadline_right.id,&lt;br /&gt;
        review_of_review_allowed_id: @deadline_right.id, due_at: Time.zone.now + 5000, parent_id: assignment_id)&lt;br /&gt;
      expect(DueDate.get_next_due_date(assignment_id, due_date.parent_id)).to be_valid&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    it &amp;quot;next due date does not exist for staggered deadline&amp;quot; do&lt;br /&gt;
      assignment_id = create(:assignment, staggered_deadline: true, name: &amp;quot;testassignment&amp;quot;).id&lt;br /&gt;
      due_date = create(:topic_due_date, deadline_type: @deadline_type,&lt;br /&gt;
        submission_allowed_id: @deadline_right, review_allowed_id: @deadline_right,&lt;br /&gt;
        review_of_review_allowed_id: @deadline_right, due_at: Time.zone.now + 5000, parent_id: assignment_id)&lt;br /&gt;
      expect(DueDate.get_next_due_date(assignment_id)).to be nil&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    it &amp;quot;next due date is before Time.now for staggered deadline&amp;quot; do&lt;br /&gt;
      assignment_id = create(:assignment, staggered_deadline: true, name: &amp;quot;testassignment&amp;quot;).id&lt;br /&gt;
      due_date = create(:topic_due_date, deadline_type: @deadline_type,&lt;br /&gt;
        submission_allowed_id: @deadline_right, review_allowed_id: @deadline_right,&lt;br /&gt;
        review_of_review_allowed_id: @deadline_right, due_at: Time.zone.now - 5000, parent_id: assignment_id)&lt;br /&gt;
      expect(DueDate.get_next_due_date(assignment_id, due_date.parent_id)).to be nil&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    it &amp;quot;get next due date from assignment for staggered deadline&amp;quot; do&lt;br /&gt;
      assignment_id = create(:assignment, staggered_deadline: true, name: &amp;quot;testassignment&amp;quot;).id&lt;br /&gt;
      due_date = create(:assignment_due_date, deadline_type: @deadline_type,&lt;br /&gt;
        submission_allowed_id: @deadline_right, review_allowed_id: @deadline_right,&lt;br /&gt;
        review_of_review_allowed_id: @deadline_right, due_at: Time.zone.now + 5000, parent_id: assignment_id)&lt;br /&gt;
      expect(DueDate.get_next_due_date(assignment_id)).to be_valid&lt;br /&gt;
    end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
* If the function &amp;quot;self.default_permission&amp;quot; returns the correct default permissions for particular deadline and permission types.&amp;lt;syntaxhighlight lang=&amp;quot;ruby&amp;quot;&amp;gt;&lt;br /&gt;
it &amp;quot;metareview review_of_review_allowed default permission OK&amp;quot; do&lt;br /&gt;
    expect(DueDate.default_permission('metareview', 'review_of_review_allowed')).to be == DeadlineRight::OK&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&amp;lt;syntaxhighlight lang=&amp;quot;ruby&amp;quot;&amp;gt;&lt;br /&gt;
it &amp;quot;review submission_allowed default permission NO&amp;quot; do&lt;br /&gt;
    expect(DueDate.default_permission('review', 'submission_allowed')).to be == DeadlineRight::NO&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
To test this file run the following command:&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
rspec spec/models/due_date_spec.rb&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
The output of this RSpec file is present in below screenshot:&lt;br /&gt;
[[File:Duedaterspec.png]]&lt;br /&gt;
&lt;br /&gt;
Code coverage details of the above RSpec files is present in below screenshot:&lt;br /&gt;
[[File:Duedatecoverage.png]]&lt;br /&gt;
&lt;br /&gt;
Code coverage details of the above RSpec files is present in below screenshot:&lt;br /&gt;
&lt;br /&gt;
=== deadline_helper_spec.rb ===&lt;br /&gt;
This is a test file for testing the functionalities of Deadline_helper.rb file located at app/helpers. Different test cases present in this file are:&lt;br /&gt;
* Check if the factory&amp;lt;ref&amp;gt;{{Cite web|url=http://http://www.semaphoreci.com|access-date=2016-10-28}}&amp;lt;/ref&amp;gt; is valid:  &lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;ruby&amp;quot;&amp;gt;&lt;br /&gt;
it &amp;quot;has a valid factory&amp;quot; do&lt;br /&gt;
    factory = FactoryGirl.build(:topic_due_date)&lt;br /&gt;
    expect(factory).to be_valid&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
* Fail if the due date is invalid:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;ruby&amp;quot;&amp;gt;&lt;br /&gt;
it &amp;quot;should fail because of invalid due_date&amp;quot; do&lt;br /&gt;
      expect { DeadlineHelper.create_topic_deadline(nil, 0, 0)}.to raise_exception(NoMethodError)&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
* If new due_date object is created:&amp;lt;syntaxhighlight lang=&amp;quot;ruby&amp;quot;&amp;gt;&lt;br /&gt;
it &amp;quot;new due_date object created&amp;quot; do&lt;br /&gt;
      DeadlineHelper.create_topic_deadline(@topic_due_date, 0, 1)&lt;br /&gt;
      expect(TopicDueDate.count).to be == 2&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
* due_at should be same for 0 offset:&amp;lt;syntaxhighlight lang=&amp;quot;ruby&amp;quot;&amp;gt;&lt;br /&gt;
 it &amp;quot;due_at should be same for 0 offset&amp;quot; do&lt;br /&gt;
      DeadlineHelper.create_topic_deadline(@topic_due_date, 0, 10)&lt;br /&gt;
      new_due_date = TopicDueDate.find_by(parent_id: 10)&lt;br /&gt;
      expect(new_due_date).to be_valid&lt;br /&gt;
      expect(new_due_date.due_at.to_s).to be == @topic_due_date.due_at.to_s&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
* due_at is calculated correctly if offset is positive:&amp;lt;syntaxhighlight lang=&amp;quot;ruby&amp;quot;&amp;gt;&lt;br /&gt;
it &amp;quot;due_at calculated correctly for positive offset&amp;quot; do&lt;br /&gt;
      DeadlineHelper.create_topic_deadline(@topic_due_date, 5000, 10)&lt;br /&gt;
      new_due_date = TopicDueDate.find_by(parent_id: 10)&lt;br /&gt;
      expect(new_due_date).to be_valid&lt;br /&gt;
      expect(new_due_date.due_at.to_s).to be == (Time.zone.parse(@topic_due_date.due_at.to_s) + 5000).to_s&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
* due_at is calculated correctly if offset is negative:&amp;lt;syntaxhighlight lang=&amp;quot;ruby&amp;quot;&amp;gt;&lt;br /&gt;
it &amp;quot;due_at calculated correctly for negative offset&amp;quot; do&lt;br /&gt;
      DeadlineHelper.create_topic_deadline(@topic_due_date, -5000, 10)&lt;br /&gt;
      new_due_date = TopicDueDate.find_by(parent_id: 10)&lt;br /&gt;
      expect(new_due_date).to be_valid&lt;br /&gt;
      expect(new_due_date.due_at.to_s).to be == (Time.zone.parse(@topic_due_date.due_at.to_s) - 5000).to_s&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;[[asd]]&lt;br /&gt;
* The offset is being converted to integer properly:&amp;lt;syntaxhighlight lang=&amp;quot;ruby&amp;quot;&amp;gt;&lt;br /&gt;
it &amp;quot;offset converted to integer correctly&amp;quot; do&lt;br /&gt;
      DeadlineHelper.create_topic_deadline(@topic_due_date, 5000.15, 10)&lt;br /&gt;
      new_due_date = TopicDueDate.find_by(parent_id: 10)&lt;br /&gt;
      expect(new_due_date).to be_valid&lt;br /&gt;
      expect(new_due_date.due_at.to_s).to be == (Time.zone.parse(@topic_due_date.due_at.to_s) + 5000).to_s&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
To test this file run the following command:&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
rspec spec/models/deadline_helper_spec.rb&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;The output of this RSpec file is present in below screenshot:&lt;br /&gt;
[[File:Deadlinerspec.png]]&lt;br /&gt;
&lt;br /&gt;
Code coverage details of the above RSpec files is present in below screenshot:&lt;br /&gt;
[[File:Deadlinecoverage.png]]&lt;br /&gt;
&lt;br /&gt;
== '''References''' ==&lt;br /&gt;
&amp;quot;[http://www.expertiza.ncsu.edu]&amp;quot;&lt;br /&gt;
&amp;quot;[Ruby on Rails]&amp;quot;. [http://www.rubyonrails.org]. Retrieved 2016-10-28.&lt;br /&gt;
&amp;quot;[Log in to your Code Climate dashboard with GitHub or your email].&amp;quot;. [http://www.codeclimate.com]. Retrieved 2016-10-28.&lt;br /&gt;
&amp;quot;[RSpec: Behaviour Driven Development for Ruby]&amp;quot;. [http://www.rspec.info]. Retrieved 2016-10-28.&lt;br /&gt;
&amp;quot;[Travis CI - Test and Deploy with Confidence]&amp;quot;. [http://www.travis-ci.com link title]. Retrieved 2016-10-28&lt;br /&gt;
&amp;quot;[Working Effectively with Data Factories Using FactoryGirl]&amp;quot;. [http://www.semaphoreci.com]. Retrieved 2016-10-28&lt;/div&gt;</summary>
		<author><name>Nthanik</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2016/E1634.Refactor_and_write_unit_test_of_due_date.rb_and_deadline_helper.rb&amp;diff=103232</id>
		<title>CSC/ECE 517 Fall 2016/E1634.Refactor and write unit test of due date.rb and deadline helper.rb</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2016/E1634.Refactor_and_write_unit_test_of_due_date.rb_and_deadline_helper.rb&amp;diff=103232"/>
		<updated>2016-10-28T22:56:27Z</updated>

		<summary type="html">&lt;p&gt;Nthanik: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== '''Introduction''' ==&lt;br /&gt;
&lt;br /&gt;
=== Expertiza ===&lt;br /&gt;
Expertiza is an open source project for school assignment management for instructors and students based on the Ruby on Rails framework. Expertiza allows the instructor to create new assignments and customise new or existing assignments. It also allows the instructor to create a list of topics the students can sign up for. Students can form teams in Expertiza to work on various projects and assignments. Students can also peer review other students' submissions. Expertiza supports submission across various document types, including the URLs and word documents. Expertiza provides a dashboard for all the assignments corresponding to a course and provides absolute control to the Instructors and Teaching Assistants. In addition to assignments, it encompasses peer reviews wherein participants are allowed to provide feedback anonymously about each other's work thereby providing scope for the better outcome. The due_date.rb file is responsible for informing the users about the deadline for submission of the each assignment. Due dates in Expertiza have their association with many other components like assignments, reviews etc.&lt;br /&gt;
&lt;br /&gt;
=== Code Climate ===&lt;br /&gt;
Code Climate&amp;lt;ref&amp;gt;{{Cite web|url=https://codeclimate.com/dashboard|title=Log in to your Code Climate dashboard with GitHub or your email.|website=codeclimate.com|access-date=2016-10-28}}&amp;lt;/ref&amp;gt; is a tool that runs static analysis on a GitHub project and outputs many details like test coverage, complexity, duplication, security, style, and more. There is a Google Chrome extension to integrate the Code Climate results generated directly into GitHub which is visible when browsing the repository on the browser. It allows us to see issues displayed directly inside GitHub's UI, to review which lines are covered in diffs and files, and add repositories and open tickets without changing your workflow.&lt;br /&gt;
&lt;br /&gt;
== '''Tasks Identified''' ==&lt;br /&gt;
To install Code climate Chrome Extension that highlights the duplicated code.&lt;br /&gt;
&lt;br /&gt;
To refactor the following two files:&lt;br /&gt;
* Due_date.rb&lt;br /&gt;
** Ternary operators must not be nested. Prefer `if` or `else` constructs instead.&lt;br /&gt;
** Useless assignment to variable - `sorted_deadlines`.&lt;br /&gt;
** Prefer `each` over `for`.&lt;br /&gt;
** Use `find_by` instead of `where.first`.&lt;br /&gt;
** Correct the use of Time function&lt;br /&gt;
* Deadline_helper.rb&lt;br /&gt;
** Do not use `Time.now` without zone. Use one of `Time.zone.now`, `Time.current`, `Time.now.in_time_zone`, `Time.now.utc`, `Time.now.getlocal`, `Time.now.iso8601`, `Time.now.jisx0301`, `Time.now.rfc3339`, `Time.now.to_i`, `Time.now.to_f` instead.&lt;br /&gt;
** Trailing whitespace detected.&lt;br /&gt;
** Extra empty line detected at module body end.&lt;br /&gt;
&lt;br /&gt;
* Create respective RSpec files in /spec/models/ and /spec/helper folder and write unit tests for each method in due_date.rb and deadline_helper.rb.&lt;br /&gt;
&lt;br /&gt;
== '''Current Implementation''' ==&lt;br /&gt;
DueDate is a Model class to manage the deadlines of an assignment. It has methods for setting due dates for an assignment, copying due dates from one assignment to a new assignment etc. DeadlineHelper provides helper functions that help DueDate perform certain tasks. The assignment focuses on refactoring some of the methods based on warnings received from Code Climate's static analysis and modifying the language to make it more Ruby-friendly. The assignment also involves writing unit test cases for due_date.rb and deadline_helper.rb in order to increase test coverage. &lt;br /&gt;
&lt;br /&gt;
The goal of this project is to attempt to make this part of the application easier to read and write unit test cases that the application must pass. &lt;br /&gt;
&lt;br /&gt;
== '''Changed Implementation''' ==&lt;br /&gt;
Changes implemented involves refactoring the code and making it more understandable by adding comments in the code.&lt;br /&gt;
&lt;br /&gt;
The modified files are&lt;br /&gt;
* Due_date.rb (path: /app/models)&lt;br /&gt;
&lt;br /&gt;
* Deadline_helper.rb (path: /app/helpers)&lt;br /&gt;
Testing files&lt;br /&gt;
* Due_date_spec.rb (path: /spec/models)&lt;br /&gt;
* Deadline_helper_spec.rb (path: /spec/helpers)&lt;br /&gt;
=== Due_date.rb ===&lt;br /&gt;
* Converted for..in loop to object.each in order to follow better Ruby syntax.&lt;br /&gt;
* Unnecessary assignment to sorted_deadlines removed.&lt;br /&gt;
* Nested ternary operators have been changed to if..else in order to make it more readable.&lt;br /&gt;
[[File:Duedaterb.png]]&lt;br /&gt;
* Changed where(...).first to find_by(...) which is the newer recommended syntax.&lt;br /&gt;
* Corrected the Time.now functions by adding the correct zones to them such as Time.zone.now.&lt;br /&gt;
* Removed trailing whitespaces.&lt;br /&gt;
[[File:DueDaterb2.png]]&lt;br /&gt;
&lt;br /&gt;
=== Deadline_helper.rb ===&lt;br /&gt;
* Time functions were changed to functions with zones&lt;br /&gt;
* Extra line removed&lt;br /&gt;
[[File:Deadlinehelper.png]]&lt;br /&gt;
&lt;br /&gt;
== '''RSpec testing''' ==&lt;br /&gt;
There were no existing tests for the functions in due_date.rb and deadline_helper.rb. We have added exhaustive set of RSpec tests to test all the code. We have added two new spec files 'due_date_spec.rb' and ‘deadline_helper_spec.rb’ which cover the testing scenarios for the functions in ‘due_date.rb’ and ‘deadline_helper.rb’.&lt;br /&gt;
&lt;br /&gt;
These RSpec files have 100% code coverage visible at: /coverage/index.html&lt;br /&gt;
&lt;br /&gt;
=== due_date_spec.rb ===&lt;br /&gt;
This file is located at spec/models and tests the functionalities of the due_date.rb file located in app/models. There are 18 test cases in total which are listed below.&lt;br /&gt;
* If the factory is successfully able to build the due_date objects.&amp;lt;syntaxhighlight lang=&amp;quot;ruby&amp;quot;&amp;gt;&lt;br /&gt;
it &amp;quot;due date factory created successfully&amp;quot; do&lt;br /&gt;
    expect(@assignment_due_date).to be_valid&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&amp;lt;syntaxhighlight lang=&amp;quot;ruby&amp;quot;&amp;gt;&lt;br /&gt;
it &amp;quot;due dates created correctly&amp;quot; do&lt;br /&gt;
    expect(@due_dates.length).to be == 10&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
* If the function &amp;quot;set_flag&amp;quot; successfully sets the due_date flag.&amp;lt;syntaxhighlight lang=&amp;quot;ruby&amp;quot;&amp;gt;&lt;br /&gt;
it &amp;quot;due date flag is set&amp;quot; do&lt;br /&gt;
    expect(@assignment_due_date.flag).to be false&lt;br /&gt;
    @assignment_due_date.set_flag&lt;br /&gt;
    expect(@assignment_due_date.flag).to be true&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
* If the function &amp;quot;due_at_is_valid_datetime&amp;quot; returns nil (no errors) for a valid datetime in due_at (no invalid test cases can be added here because model does not allow invalid datetime to be set at all).&amp;lt;syntaxhighlight lang=&amp;quot;ruby&amp;quot;&amp;gt;&lt;br /&gt;
it &amp;quot;due at is valid datetime&amp;quot; do&lt;br /&gt;
    expect(@assignment_due_date.due_at_is_valid_datetime).to be nil&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
* If the function &amp;quot;self.copy&amp;quot; is able to copy due dates from one assignment to another.&amp;lt;syntaxhighlight lang=&amp;quot;ruby&amp;quot;&amp;gt;&lt;br /&gt;
it &amp;quot;copy due dates to new assignment&amp;quot; do&lt;br /&gt;
    new_assignment_id = build(:assignment, id: 999).id&lt;br /&gt;
    old_assignment_id = @assignment_due_date.assignment.id&lt;br /&gt;
    DueDate.copy(old_assignment_id, new_assignment_id)&lt;br /&gt;
    expect(DueDate.where(parent_id: new_assignment_id).count).to eql DueDate.where(parent_id: old_assignment_id).count&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
* If the function &amp;quot;self.set_duedate&amp;quot; is able to create another due date by copying data from an existing due date object.&amp;lt;syntaxhighlight lang=&amp;quot;ruby&amp;quot;&amp;gt;&lt;br /&gt;
it &amp;quot;create new duedate record with values&amp;quot; do&lt;br /&gt;
    DueDate.set_duedate({id: 999}, @assignment_due_date.deadline_type_id,&lt;br /&gt;
                        @assignment_due_date.parent_id, @assignment_due_date.round)&lt;br /&gt;
    new_due_date = DueDate.find_by(id: 999)&lt;br /&gt;
    expect(new_due_date).to be_valid&lt;br /&gt;
    expect(new_due_date.deadline_type_id).to eql @assignment_due_date.deadline_type_id&lt;br /&gt;
    expect(new_due_date.parent_id).to eql @assignment_due_date.parent_id&lt;br /&gt;
    expect(new_due_date.round).to eql @assignment_due_date.round&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
* If the function &amp;quot;self.deadline_sort&amp;quot; is able to sort the due dates in ascending order.&amp;lt;syntaxhighlight lang=&amp;quot;ruby&amp;quot;&amp;gt;&lt;br /&gt;
it &amp;quot;sort duedate records&amp;quot; do&lt;br /&gt;
    sorted_due_dates = @due_dates&lt;br /&gt;
    expect(sorted_due_dates.each_cons(2).all?{|m1, m2| (m1.due_at &amp;lt;=&amp;gt; m2.due_at) != 1}).to eql false&lt;br /&gt;
&lt;br /&gt;
    sorted_due_dates = DueDate.deadline_sort(@due_dates)&lt;br /&gt;
    expect(sorted_due_dates.each_cons(2).all?{|m1, m2| (m1.due_at &amp;lt;=&amp;gt; m2.due_at) != 1}).to eql true&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
* If the function &amp;quot;self.done_in_assignment_round&amp;quot; returns the correct number of rounds for specific inputs. This involves an invalid test case as well for 0 rounds.&amp;lt;syntaxhighlight lang=&amp;quot;ruby&amp;quot;&amp;gt;&lt;br /&gt;
describe &amp;quot;#done_in_assignment_round&amp;quot; do&lt;br /&gt;
    it &amp;quot;return 0 when no response map&amp;quot; do&lt;br /&gt;
      response = ReviewResponseMap.create&lt;br /&gt;
      response.type = &amp;quot;ResponseMap&amp;quot;&lt;br /&gt;
      response.save&lt;br /&gt;
      expect(DueDate.done_in_assignment_round(1, response)).to eql 0&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    it &amp;quot;return round 1 for single round&amp;quot; do&lt;br /&gt;
      response = ReviewResponseMap.create&lt;br /&gt;
      expect(DueDate.done_in_assignment_round(@assignment_due_date.parent_id, response)).to eql 1&lt;br /&gt;
    end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
* If the function &amp;quot;self.get_next_due_date&amp;quot; works as expected. This involves several invalid test cases as well.&amp;lt;syntaxhighlight lang=&amp;quot;ruby&amp;quot;&amp;gt;&lt;br /&gt;
describe &amp;quot;#get_next_due_date&amp;quot; do&lt;br /&gt;
    it &amp;quot;no subsequent due date&amp;quot; do&lt;br /&gt;
      expect(DueDate.get_next_due_date(@assignment_due_date.parent_id)).to be nil&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    it &amp;quot;nil value throws exception&amp;quot; do&lt;br /&gt;
      expect { DueDate.get_next_due_date(nil) }.to raise_exception(ActiveRecord::RecordNotFound)&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    it &amp;quot;get next assignment due date&amp;quot; do&lt;br /&gt;
      due_date = create(:assignment_due_date, deadline_type: @deadline_type,&lt;br /&gt;
        submission_allowed_id: @deadline_right.id, review_allowed_id: @deadline_right.id,&lt;br /&gt;
        review_of_review_allowed_id: @deadline_right.id, due_at: Time.zone.now + 5000)&lt;br /&gt;
      expect(DueDate.get_next_due_date(due_date.parent_id)).to be_valid&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    it &amp;quot;get next due date from topic for staggered deadline&amp;quot; do&lt;br /&gt;
      assignment_id = create(:assignment, staggered_deadline: true, name: &amp;quot;testassignment&amp;quot;).id&lt;br /&gt;
      due_date = create(:topic_due_date, deadline_type: @deadline_type,&lt;br /&gt;
        submission_allowed_id: @deadline_right.id, review_allowed_id: @deadline_right.id,&lt;br /&gt;
        review_of_review_allowed_id: @deadline_right.id, due_at: Time.zone.now + 5000, parent_id: assignment_id)&lt;br /&gt;
      expect(DueDate.get_next_due_date(assignment_id, due_date.parent_id)).to be_valid&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    it &amp;quot;next due date does not exist for staggered deadline&amp;quot; do&lt;br /&gt;
      assignment_id = create(:assignment, staggered_deadline: true, name: &amp;quot;testassignment&amp;quot;).id&lt;br /&gt;
      due_date = create(:topic_due_date, deadline_type: @deadline_type,&lt;br /&gt;
        submission_allowed_id: @deadline_right, review_allowed_id: @deadline_right,&lt;br /&gt;
        review_of_review_allowed_id: @deadline_right, due_at: Time.zone.now + 5000, parent_id: assignment_id)&lt;br /&gt;
      expect(DueDate.get_next_due_date(assignment_id)).to be nil&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    it &amp;quot;next due date is before Time.now for staggered deadline&amp;quot; do&lt;br /&gt;
      assignment_id = create(:assignment, staggered_deadline: true, name: &amp;quot;testassignment&amp;quot;).id&lt;br /&gt;
      due_date = create(:topic_due_date, deadline_type: @deadline_type,&lt;br /&gt;
        submission_allowed_id: @deadline_right, review_allowed_id: @deadline_right,&lt;br /&gt;
        review_of_review_allowed_id: @deadline_right, due_at: Time.zone.now - 5000, parent_id: assignment_id)&lt;br /&gt;
      expect(DueDate.get_next_due_date(assignment_id, due_date.parent_id)).to be nil&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    it &amp;quot;get next due date from assignment for staggered deadline&amp;quot; do&lt;br /&gt;
      assignment_id = create(:assignment, staggered_deadline: true, name: &amp;quot;testassignment&amp;quot;).id&lt;br /&gt;
      due_date = create(:assignment_due_date, deadline_type: @deadline_type,&lt;br /&gt;
        submission_allowed_id: @deadline_right, review_allowed_id: @deadline_right,&lt;br /&gt;
        review_of_review_allowed_id: @deadline_right, due_at: Time.zone.now + 5000, parent_id: assignment_id)&lt;br /&gt;
      expect(DueDate.get_next_due_date(assignment_id)).to be_valid&lt;br /&gt;
    end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
* If the function &amp;quot;self.default_permission&amp;quot; returns the correct default permissions for particular deadline and permission types.&amp;lt;syntaxhighlight lang=&amp;quot;ruby&amp;quot;&amp;gt;&lt;br /&gt;
it &amp;quot;metareview review_of_review_allowed default permission OK&amp;quot; do&lt;br /&gt;
    expect(DueDate.default_permission('metareview', 'review_of_review_allowed')).to be == DeadlineRight::OK&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&amp;lt;syntaxhighlight lang=&amp;quot;ruby&amp;quot;&amp;gt;&lt;br /&gt;
it &amp;quot;review submission_allowed default permission NO&amp;quot; do&lt;br /&gt;
    expect(DueDate.default_permission('review', 'submission_allowed')).to be == DeadlineRight::NO&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
To test this file run the following command:&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
rspec spec/models/due_date_spec.rb&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
The output of this RSpec file is present in below screenshot:&lt;br /&gt;
[[File:Duedaterspec.png]]&lt;br /&gt;
&lt;br /&gt;
Code coverage details of the above RSpec files is present in below screenshot:&lt;br /&gt;
[[File:Duedatecoverage.png]]&lt;br /&gt;
&lt;br /&gt;
Code coverage details of the above RSpec files is present in below screenshot:&lt;br /&gt;
&lt;br /&gt;
=== deadline_helper_spec.rb ===&lt;br /&gt;
This is a test file for testing the functionalities of Deadline_helper.rb file located at app/helpers. Different test cases present in this file are:&lt;br /&gt;
* Check if the factory is valid:  &lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;ruby&amp;quot;&amp;gt;&lt;br /&gt;
it &amp;quot;has a valid factory&amp;quot; do&lt;br /&gt;
    factory = FactoryGirl.build(:topic_due_date)&lt;br /&gt;
    expect(factory).to be_valid&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
* Fail if the due date is invalid:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;ruby&amp;quot;&amp;gt;&lt;br /&gt;
it &amp;quot;should fail because of invalid due_date&amp;quot; do&lt;br /&gt;
      expect { DeadlineHelper.create_topic_deadline(nil, 0, 0)}.to raise_exception(NoMethodError)&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
* If new due_date object is created:&amp;lt;syntaxhighlight lang=&amp;quot;ruby&amp;quot;&amp;gt;&lt;br /&gt;
it &amp;quot;new due_date object created&amp;quot; do&lt;br /&gt;
      DeadlineHelper.create_topic_deadline(@topic_due_date, 0, 1)&lt;br /&gt;
      expect(TopicDueDate.count).to be == 2&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
* due_at should be same for 0 offset:&amp;lt;syntaxhighlight lang=&amp;quot;ruby&amp;quot;&amp;gt;&lt;br /&gt;
 it &amp;quot;due_at should be same for 0 offset&amp;quot; do&lt;br /&gt;
      DeadlineHelper.create_topic_deadline(@topic_due_date, 0, 10)&lt;br /&gt;
      new_due_date = TopicDueDate.find_by(parent_id: 10)&lt;br /&gt;
      expect(new_due_date).to be_valid&lt;br /&gt;
      expect(new_due_date.due_at.to_s).to be == @topic_due_date.due_at.to_s&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
* due_at is calculated correctly if offset is positive:&amp;lt;syntaxhighlight lang=&amp;quot;ruby&amp;quot;&amp;gt;&lt;br /&gt;
it &amp;quot;due_at calculated correctly for positive offset&amp;quot; do&lt;br /&gt;
      DeadlineHelper.create_topic_deadline(@topic_due_date, 5000, 10)&lt;br /&gt;
      new_due_date = TopicDueDate.find_by(parent_id: 10)&lt;br /&gt;
      expect(new_due_date).to be_valid&lt;br /&gt;
      expect(new_due_date.due_at.to_s).to be == (Time.zone.parse(@topic_due_date.due_at.to_s) + 5000).to_s&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
* due_at is calculated correctly if offset is negative:&amp;lt;syntaxhighlight lang=&amp;quot;ruby&amp;quot;&amp;gt;&lt;br /&gt;
it &amp;quot;due_at calculated correctly for negative offset&amp;quot; do&lt;br /&gt;
      DeadlineHelper.create_topic_deadline(@topic_due_date, -5000, 10)&lt;br /&gt;
      new_due_date = TopicDueDate.find_by(parent_id: 10)&lt;br /&gt;
      expect(new_due_date).to be_valid&lt;br /&gt;
      expect(new_due_date.due_at.to_s).to be == (Time.zone.parse(@topic_due_date.due_at.to_s) - 5000).to_s&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;[[asd]]&lt;br /&gt;
* The offset is being converted to integer properly:&amp;lt;syntaxhighlight lang=&amp;quot;ruby&amp;quot;&amp;gt;&lt;br /&gt;
it &amp;quot;offset converted to integer correctly&amp;quot; do&lt;br /&gt;
      DeadlineHelper.create_topic_deadline(@topic_due_date, 5000.15, 10)&lt;br /&gt;
      new_due_date = TopicDueDate.find_by(parent_id: 10)&lt;br /&gt;
      expect(new_due_date).to be_valid&lt;br /&gt;
      expect(new_due_date.due_at.to_s).to be == (Time.zone.parse(@topic_due_date.due_at.to_s) + 5000).to_s&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
To test this file run the following command:&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
rspec spec/models/deadline_helper_spec.rb&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;The output of this RSpec file is present in below screenshot:&lt;br /&gt;
[[File:Deadlinerspec.png]]&lt;br /&gt;
&lt;br /&gt;
Code coverage details of the above RSpec files is present in below screenshot:&lt;br /&gt;
[[File:Deadlinecoverage.png]]&lt;br /&gt;
&lt;br /&gt;
== '''References''' ==&lt;br /&gt;
&amp;quot;[http://www.expertiza.ncsu.edu]&amp;quot;&lt;br /&gt;
&amp;quot;[Ruby on Rails]&amp;quot;. [http://www.rubyonrails.org]. Retrieved 2016-10-28.&lt;br /&gt;
&amp;quot;[Log in to your Code Climate dashboard with GitHub or your email].&amp;quot;. [http://www.codeclimate.com]. Retrieved 2016-10-28.&lt;br /&gt;
&amp;quot;[RSpec: Behaviour Driven Development for Ruby]&amp;quot;. [http://www.rspec.info]. Retrieved 2016-10-28.&lt;br /&gt;
&amp;quot;[Travis CI - Test and Deploy with Confidence]&amp;quot;. [http://www.travis-ci.com link title]. Retrieved 2016-10-28&lt;br /&gt;
&amp;quot;[Working Effectively with Data Factories Using FactoryGirl]&amp;quot;. [http://www.semaphoreci.com]. Retrieved 2016-10-28&lt;/div&gt;</summary>
		<author><name>Nthanik</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=File:Duedaterspec.png&amp;diff=103207</id>
		<title>File:Duedaterspec.png</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=File:Duedaterspec.png&amp;diff=103207"/>
		<updated>2016-10-28T22:38:09Z</updated>

		<summary type="html">&lt;p&gt;Nthanik: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Nthanik</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=File:Duedatecoverage.png&amp;diff=103206</id>
		<title>File:Duedatecoverage.png</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=File:Duedatecoverage.png&amp;diff=103206"/>
		<updated>2016-10-28T22:37:47Z</updated>

		<summary type="html">&lt;p&gt;Nthanik: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Nthanik</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=File:Deadlinerspec.png&amp;diff=103205</id>
		<title>File:Deadlinerspec.png</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=File:Deadlinerspec.png&amp;diff=103205"/>
		<updated>2016-10-28T22:37:24Z</updated>

		<summary type="html">&lt;p&gt;Nthanik: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Nthanik</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=File:Deadlinecoverage.png&amp;diff=103203</id>
		<title>File:Deadlinecoverage.png</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=File:Deadlinecoverage.png&amp;diff=103203"/>
		<updated>2016-10-28T22:35:47Z</updated>

		<summary type="html">&lt;p&gt;Nthanik: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Nthanik</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2016/E1634.Refactor_and_write_unit_test_of_due_date.rb_and_deadline_helper.rb&amp;diff=103202</id>
		<title>CSC/ECE 517 Fall 2016/E1634.Refactor and write unit test of due date.rb and deadline helper.rb</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2016/E1634.Refactor_and_write_unit_test_of_due_date.rb_and_deadline_helper.rb&amp;diff=103202"/>
		<updated>2016-10-28T22:34:08Z</updated>

		<summary type="html">&lt;p&gt;Nthanik: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== '''Introduction''' ==&lt;br /&gt;
&lt;br /&gt;
=== Expertiza ===&lt;br /&gt;
Expertiza is an open source project for school assignment management for instructors and students based on the Ruby on Rails framework. Expertiza allows the instructor to create new assignments and customise new or existing assignments. It also allows the instructor to create a list of topics the students can sign up for. Students can form teams in Expertiza to work on various projects and assignments. Students can also peer review other students' submissions. Expertiza supports submission across various document types, including the URLs and word documents. Expertiza provides a dashboard for all the assignments corresponding to a course and provides absolute control to the Instructors and Teaching Assistants. In addition to assignments, it encompasses peer reviews wherein participants are allowed to provide feedback anonymously about each other's work thereby providing scope for the better outcome. The due_date.rb file is responsible for informing the users about the deadline for submission of the each assignment. Due dates in Expertiza have their association with many other components like assignments, reviews etc.&lt;br /&gt;
&lt;br /&gt;
=== Code Climate ===&lt;br /&gt;
Code Climate&amp;lt;ref&amp;gt;{{Cite web|url=https://codeclimate.com/dashboard|title=Log in to your Code Climate dashboard with GitHub or your email.|website=codeclimate.com|access-date=2016-10-28}}&amp;lt;/ref&amp;gt; is a tool that runs static analysis on a GitHub project and outputs many details like test coverage, complexity, duplication, security, style, and more. There is a Google Chrome extension to integrate the Code Climate results generated directly into GitHub which is visible when browsing the repository on the browser. It allows us to see issues displayed directly inside GitHub's UI, to review which lines are covered in diffs and files, and add repositories and open tickets without changing your workflow.&lt;br /&gt;
&lt;br /&gt;
== '''Tasks Identified''' ==&lt;br /&gt;
To install Code climate Chrome Extension that highlights the duplicated code.&lt;br /&gt;
&lt;br /&gt;
To refactor the following two files:&lt;br /&gt;
* Due_date.rb&lt;br /&gt;
** Ternary operators must not be nested. Prefer `if` or `else` constructs instead.&lt;br /&gt;
** Useless assignment to variable - `sorted_deadlines`.&lt;br /&gt;
** Prefer `each` over `for`.&lt;br /&gt;
** Use `find_by` instead of `where.first`.&lt;br /&gt;
** Correct the use of Time function&lt;br /&gt;
* Deadline_helper.rb&lt;br /&gt;
** Do not use `Time.now` without zone. Use one of `Time.zone.now`, `Time.current`, `Time.now.in_time_zone`, `Time.now.utc`, `Time.now.getlocal`, `Time.now.iso8601`, `Time.now.jisx0301`, `Time.now.rfc3339`, `Time.now.to_i`, `Time.now.to_f` instead.&lt;br /&gt;
** Trailing whitespace detected.&lt;br /&gt;
** Extra empty line detected at module body end.&lt;br /&gt;
&lt;br /&gt;
* Create respective RSpec files in /spec/models/ and /spec/helper folder and write unit tests for each method in due_date.rb and deadline_helper.rb.&lt;br /&gt;
&lt;br /&gt;
== '''Current Implementation''' ==&lt;br /&gt;
DueDate is a Model class to manage the deadlines of an assignment. It has methods for setting due dates for an assignment, copying due dates from one assignment to a new assignment etc. DeadlineHelper provides helper functions that help DueDate perform certain tasks. The assignment focuses on refactoring some of the methods based on warnings received from Code Climate's static analysis and modifying the language to make it more Ruby-friendly. The assignment also involves writing unit test cases for due_date.rb and deadline_helper.rb in order to increase test coverage. &lt;br /&gt;
&lt;br /&gt;
The goal of this project is to attempt to make this part of the application easier to read and write unit test cases that the application must pass. &lt;br /&gt;
&lt;br /&gt;
== '''Changed Implementation''' ==&lt;br /&gt;
Changes implemented involves refactoring the code and making it more understandable by adding comments in the code.&lt;br /&gt;
&lt;br /&gt;
The modified files are&lt;br /&gt;
* Due_date.rb (path: /app/models)&lt;br /&gt;
&lt;br /&gt;
* Deadline_helper.rb (path: /app/helpers)&lt;br /&gt;
Testing files&lt;br /&gt;
* Due_date_spec.rb (path: /spec/models)&lt;br /&gt;
* Deadline_helper_spec.rb (path: /spec/helpers)&lt;br /&gt;
=== Due_date.rb ===&lt;br /&gt;
* Converted for..in loop to object.each in order to follow better Ruby syntax.&lt;br /&gt;
* Unnecessary assignment to sorted_deadlines removed.&lt;br /&gt;
* Nested ternary operators have been changed to if..else in order to make it more readable.&lt;br /&gt;
[[File:Duedaterb.png]]&lt;br /&gt;
* Changed where(...).first to find_by(...) which is the newer recommended syntax.&lt;br /&gt;
* Corrected the Time.now functions by adding the correct zones to them such as Time.zone.now.&lt;br /&gt;
* Removed trailing whitespaces.&lt;br /&gt;
[[File:DueDaterb2.png]]&lt;br /&gt;
&lt;br /&gt;
=== Deadline_helper.rb ===&lt;br /&gt;
* Time functions were changed to functions with zones&lt;br /&gt;
* Extra line removed&lt;br /&gt;
[[File:Deadlinehelper.png]]&lt;br /&gt;
&lt;br /&gt;
== '''RSpec testing''' ==&lt;br /&gt;
There were no existing tests for the functions in due_date.rb and deadline_helper.rb. We have added exhaustive set of RSpec tests to test all the code. We have added two new spec files 'due_date_spec.rb' and ‘deadline_helper_spec.rb’ which cover the testing scenarios for the functions in ‘due_date.rb’ and ‘deadline_helper.rb’.&lt;br /&gt;
&lt;br /&gt;
These RSpec files have 100% code coverage visible at: /coverage/index.html&lt;br /&gt;
&lt;br /&gt;
=== due_date_spec.rb ===&lt;br /&gt;
This file is located at spec/models and tests the functionalities of the due_date.rb file located in app/models. There are 18 test cases in total which are listed below.&lt;br /&gt;
* If the factory is successfully able to build the due_date objects.&amp;lt;syntaxhighlight lang=&amp;quot;ruby&amp;quot;&amp;gt;&lt;br /&gt;
it &amp;quot;due date factory created successfully&amp;quot; do&lt;br /&gt;
    expect(@assignment_due_date).to be_valid&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&amp;lt;syntaxhighlight lang=&amp;quot;ruby&amp;quot;&amp;gt;&lt;br /&gt;
it &amp;quot;due dates created correctly&amp;quot; do&lt;br /&gt;
    expect(@due_dates.length).to be == 10&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
* If the function &amp;quot;set_flag&amp;quot; successfully sets the due_date flag.&amp;lt;syntaxhighlight lang=&amp;quot;ruby&amp;quot;&amp;gt;&lt;br /&gt;
it &amp;quot;due date flag is set&amp;quot; do&lt;br /&gt;
    expect(@assignment_due_date.flag).to be false&lt;br /&gt;
    @assignment_due_date.set_flag&lt;br /&gt;
    expect(@assignment_due_date.flag).to be true&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
* If the function &amp;quot;due_at_is_valid_datetime&amp;quot; returns nil (no errors) for a valid datetime in due_at (no invalid test cases can be added here because model does not allow invalid datetime to be set at all).&amp;lt;syntaxhighlight lang=&amp;quot;ruby&amp;quot;&amp;gt;&lt;br /&gt;
it &amp;quot;due at is valid datetime&amp;quot; do&lt;br /&gt;
    expect(@assignment_due_date.due_at_is_valid_datetime).to be nil&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
* If the function &amp;quot;self.copy&amp;quot; is able to copy due dates from one assignment to another.&amp;lt;syntaxhighlight lang=&amp;quot;ruby&amp;quot;&amp;gt;&lt;br /&gt;
it &amp;quot;copy due dates to new assignment&amp;quot; do&lt;br /&gt;
    new_assignment_id = build(:assignment, id: 999).id&lt;br /&gt;
    old_assignment_id = @assignment_due_date.assignment.id&lt;br /&gt;
    DueDate.copy(old_assignment_id, new_assignment_id)&lt;br /&gt;
    expect(DueDate.where(parent_id: new_assignment_id).count).to eql DueDate.where(parent_id: old_assignment_id).count&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
* If the function &amp;quot;self.set_duedate&amp;quot; is able to create another due date by copying data from an existing due date object.&amp;lt;syntaxhighlight lang=&amp;quot;ruby&amp;quot;&amp;gt;&lt;br /&gt;
it &amp;quot;create new duedate record with values&amp;quot; do&lt;br /&gt;
    DueDate.set_duedate({id: 999}, @assignment_due_date.deadline_type_id,&lt;br /&gt;
                        @assignment_due_date.parent_id, @assignment_due_date.round)&lt;br /&gt;
    new_due_date = DueDate.find_by(id: 999)&lt;br /&gt;
    expect(new_due_date).to be_valid&lt;br /&gt;
    expect(new_due_date.deadline_type_id).to eql @assignment_due_date.deadline_type_id&lt;br /&gt;
    expect(new_due_date.parent_id).to eql @assignment_due_date.parent_id&lt;br /&gt;
    expect(new_due_date.round).to eql @assignment_due_date.round&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
* If the function &amp;quot;self.deadline_sort&amp;quot; is able to sort the due dates in ascending order.&amp;lt;syntaxhighlight lang=&amp;quot;ruby&amp;quot;&amp;gt;&lt;br /&gt;
it &amp;quot;sort duedate records&amp;quot; do&lt;br /&gt;
    sorted_due_dates = @due_dates&lt;br /&gt;
    expect(sorted_due_dates.each_cons(2).all?{|m1, m2| (m1.due_at &amp;lt;=&amp;gt; m2.due_at) != 1}).to eql false&lt;br /&gt;
&lt;br /&gt;
    sorted_due_dates = DueDate.deadline_sort(@due_dates)&lt;br /&gt;
    expect(sorted_due_dates.each_cons(2).all?{|m1, m2| (m1.due_at &amp;lt;=&amp;gt; m2.due_at) != 1}).to eql true&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
* If the function &amp;quot;self.done_in_assignment_round&amp;quot; returns the correct number of rounds for specific inputs. This involves an invalid test case as well for 0 rounds.&amp;lt;syntaxhighlight lang=&amp;quot;ruby&amp;quot;&amp;gt;&lt;br /&gt;
describe &amp;quot;#done_in_assignment_round&amp;quot; do&lt;br /&gt;
    it &amp;quot;return 0 when no response map&amp;quot; do&lt;br /&gt;
      response = ReviewResponseMap.create&lt;br /&gt;
      response.type = &amp;quot;ResponseMap&amp;quot;&lt;br /&gt;
      response.save&lt;br /&gt;
      expect(DueDate.done_in_assignment_round(1, response)).to eql 0&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    it &amp;quot;return round 1 for single round&amp;quot; do&lt;br /&gt;
      response = ReviewResponseMap.create&lt;br /&gt;
      expect(DueDate.done_in_assignment_round(@assignment_due_date.parent_id, response)).to eql 1&lt;br /&gt;
    end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
* If the function &amp;quot;self.get_next_due_date&amp;quot; works as expected. This involves several invalid test cases as well.&amp;lt;syntaxhighlight lang=&amp;quot;ruby&amp;quot;&amp;gt;&lt;br /&gt;
describe &amp;quot;#get_next_due_date&amp;quot; do&lt;br /&gt;
    it &amp;quot;no subsequent due date&amp;quot; do&lt;br /&gt;
      expect(DueDate.get_next_due_date(@assignment_due_date.parent_id)).to be nil&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    it &amp;quot;nil value throws exception&amp;quot; do&lt;br /&gt;
      expect { DueDate.get_next_due_date(nil) }.to raise_exception(ActiveRecord::RecordNotFound)&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    it &amp;quot;get next assignment due date&amp;quot; do&lt;br /&gt;
      due_date = create(:assignment_due_date, deadline_type: @deadline_type,&lt;br /&gt;
        submission_allowed_id: @deadline_right.id, review_allowed_id: @deadline_right.id,&lt;br /&gt;
        review_of_review_allowed_id: @deadline_right.id, due_at: Time.zone.now + 5000)&lt;br /&gt;
      expect(DueDate.get_next_due_date(due_date.parent_id)).to be_valid&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    it &amp;quot;get next due date from topic for staggered deadline&amp;quot; do&lt;br /&gt;
      assignment_id = create(:assignment, staggered_deadline: true, name: &amp;quot;testassignment&amp;quot;).id&lt;br /&gt;
      due_date = create(:topic_due_date, deadline_type: @deadline_type,&lt;br /&gt;
        submission_allowed_id: @deadline_right.id, review_allowed_id: @deadline_right.id,&lt;br /&gt;
        review_of_review_allowed_id: @deadline_right.id, due_at: Time.zone.now + 5000, parent_id: assignment_id)&lt;br /&gt;
      expect(DueDate.get_next_due_date(assignment_id, due_date.parent_id)).to be_valid&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    it &amp;quot;next due date does not exist for staggered deadline&amp;quot; do&lt;br /&gt;
      assignment_id = create(:assignment, staggered_deadline: true, name: &amp;quot;testassignment&amp;quot;).id&lt;br /&gt;
      due_date = create(:topic_due_date, deadline_type: @deadline_type,&lt;br /&gt;
        submission_allowed_id: @deadline_right, review_allowed_id: @deadline_right,&lt;br /&gt;
        review_of_review_allowed_id: @deadline_right, due_at: Time.zone.now + 5000, parent_id: assignment_id)&lt;br /&gt;
      expect(DueDate.get_next_due_date(assignment_id)).to be nil&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    it &amp;quot;next due date is before Time.now for staggered deadline&amp;quot; do&lt;br /&gt;
      assignment_id = create(:assignment, staggered_deadline: true, name: &amp;quot;testassignment&amp;quot;).id&lt;br /&gt;
      due_date = create(:topic_due_date, deadline_type: @deadline_type,&lt;br /&gt;
        submission_allowed_id: @deadline_right, review_allowed_id: @deadline_right,&lt;br /&gt;
        review_of_review_allowed_id: @deadline_right, due_at: Time.zone.now - 5000, parent_id: assignment_id)&lt;br /&gt;
      expect(DueDate.get_next_due_date(assignment_id, due_date.parent_id)).to be nil&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    it &amp;quot;get next due date from assignment for staggered deadline&amp;quot; do&lt;br /&gt;
      assignment_id = create(:assignment, staggered_deadline: true, name: &amp;quot;testassignment&amp;quot;).id&lt;br /&gt;
      due_date = create(:assignment_due_date, deadline_type: @deadline_type,&lt;br /&gt;
        submission_allowed_id: @deadline_right, review_allowed_id: @deadline_right,&lt;br /&gt;
        review_of_review_allowed_id: @deadline_right, due_at: Time.zone.now + 5000, parent_id: assignment_id)&lt;br /&gt;
      expect(DueDate.get_next_due_date(assignment_id)).to be_valid&lt;br /&gt;
    end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
* If the function &amp;quot;self.default_permission&amp;quot; returns the correct default permissions for particular deadline and permission types.&amp;lt;syntaxhighlight lang=&amp;quot;ruby&amp;quot;&amp;gt;&lt;br /&gt;
it &amp;quot;metareview review_of_review_allowed default permission OK&amp;quot; do&lt;br /&gt;
    expect(DueDate.default_permission('metareview', 'review_of_review_allowed')).to be == DeadlineRight::OK&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&amp;lt;syntaxhighlight lang=&amp;quot;ruby&amp;quot;&amp;gt;&lt;br /&gt;
it &amp;quot;review submission_allowed default permission NO&amp;quot; do&lt;br /&gt;
    expect(DueDate.default_permission('review', 'submission_allowed')).to be == DeadlineRight::NO&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
To test this file run the following command:&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
rspec spec/models/due_date_spec.rb&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
The output of this RSpec file is present in below screenshot:&lt;br /&gt;
[[File:Duedaterspec.png]]&lt;br /&gt;
&lt;br /&gt;
Code coverage details of the above RSpec files is present in below screenshot:&lt;br /&gt;
[[File:Duedatecoverage.png]]&lt;br /&gt;
&lt;br /&gt;
Code coverage details of the above RSpec files is present in below screenshot:&lt;br /&gt;
&lt;br /&gt;
=== deadline_helper_spec.rb ===&lt;br /&gt;
This is a test file for testing the functionalities of Deadline_helper.rb file located at app/helpers. Different test cases present in this file are:&lt;br /&gt;
* Check if the factory is valid:  &lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;ruby&amp;quot;&amp;gt;&lt;br /&gt;
it &amp;quot;has a valid factory&amp;quot; do&lt;br /&gt;
    factory = FactoryGirl.build(:topic_due_date)&lt;br /&gt;
    expect(factory).to be_valid&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
* Fail if the due date is invalid:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;ruby&amp;quot;&amp;gt;&lt;br /&gt;
it &amp;quot;should fail because of invalid due_date&amp;quot; do&lt;br /&gt;
      expect { DeadlineHelper.create_topic_deadline(nil, 0, 0)}.to raise_exception(NoMethodError)&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
* If new due_date object is created:&amp;lt;syntaxhighlight lang=&amp;quot;ruby&amp;quot;&amp;gt;&lt;br /&gt;
it &amp;quot;new due_date object created&amp;quot; do&lt;br /&gt;
      DeadlineHelper.create_topic_deadline(@topic_due_date, 0, 1)&lt;br /&gt;
      expect(TopicDueDate.count).to be == 2&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
* due_at should be same for 0 offset:&amp;lt;syntaxhighlight lang=&amp;quot;ruby&amp;quot;&amp;gt;&lt;br /&gt;
 it &amp;quot;due_at should be same for 0 offset&amp;quot; do&lt;br /&gt;
      DeadlineHelper.create_topic_deadline(@topic_due_date, 0, 10)&lt;br /&gt;
      new_due_date = TopicDueDate.find_by(parent_id: 10)&lt;br /&gt;
      expect(new_due_date).to be_valid&lt;br /&gt;
      expect(new_due_date.due_at.to_s).to be == @topic_due_date.due_at.to_s&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
* due_at is calculated correctly if offset is positive:&amp;lt;syntaxhighlight lang=&amp;quot;ruby&amp;quot;&amp;gt;&lt;br /&gt;
it &amp;quot;due_at calculated correctly for positive offset&amp;quot; do&lt;br /&gt;
      DeadlineHelper.create_topic_deadline(@topic_due_date, 5000, 10)&lt;br /&gt;
      new_due_date = TopicDueDate.find_by(parent_id: 10)&lt;br /&gt;
      expect(new_due_date).to be_valid&lt;br /&gt;
      expect(new_due_date.due_at.to_s).to be == (Time.zone.parse(@topic_due_date.due_at.to_s) + 5000).to_s&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
* due_at is calculated correctly if offset is negative:&amp;lt;syntaxhighlight lang=&amp;quot;ruby&amp;quot;&amp;gt;&lt;br /&gt;
it &amp;quot;due_at calculated correctly for negative offset&amp;quot; do&lt;br /&gt;
      DeadlineHelper.create_topic_deadline(@topic_due_date, -5000, 10)&lt;br /&gt;
      new_due_date = TopicDueDate.find_by(parent_id: 10)&lt;br /&gt;
      expect(new_due_date).to be_valid&lt;br /&gt;
      expect(new_due_date.due_at.to_s).to be == (Time.zone.parse(@topic_due_date.due_at.to_s) - 5000).to_s&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
* The offset is being converted to integer properly:&amp;lt;syntaxhighlight lang=&amp;quot;ruby&amp;quot;&amp;gt;&lt;br /&gt;
it &amp;quot;offset converted to integer correctly&amp;quot; do&lt;br /&gt;
      DeadlineHelper.create_topic_deadline(@topic_due_date, 5000.15, 10)&lt;br /&gt;
      new_due_date = TopicDueDate.find_by(parent_id: 10)&lt;br /&gt;
      expect(new_due_date).to be_valid&lt;br /&gt;
      expect(new_due_date.due_at.to_s).to be == (Time.zone.parse(@topic_due_date.due_at.to_s) + 5000).to_s&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
To test this file run the following command:&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
rspec spec/models/deadline_helper_spec.rb&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;The output of this RSpec file is present in below screenshot:&lt;br /&gt;
[[File:Deadlinerspec.png]]&lt;br /&gt;
&lt;br /&gt;
Code coverage details of the above RSpec files is present in below screenshot:&lt;br /&gt;
[[File:Deadlinecoverage.png]]&lt;br /&gt;
&lt;br /&gt;
== '''References''' ==&lt;/div&gt;</summary>
		<author><name>Nthanik</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2016/E1634.Refactor_and_write_unit_test_of_due_date.rb_and_deadline_helper.rb&amp;diff=103200</id>
		<title>CSC/ECE 517 Fall 2016/E1634.Refactor and write unit test of due date.rb and deadline helper.rb</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2016/E1634.Refactor_and_write_unit_test_of_due_date.rb_and_deadline_helper.rb&amp;diff=103200"/>
		<updated>2016-10-28T22:33:11Z</updated>

		<summary type="html">&lt;p&gt;Nthanik: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== '''Introduction''' ==&lt;br /&gt;
&lt;br /&gt;
=== Expertiza ===&lt;br /&gt;
Expertiza is an open source project for school assignment management for instructors and students based on the Ruby on Rails framework. Expertiza allows the instructor to create new assignments and customise new or existing assignments. It also allows the instructor to create a list of topics the students can sign up for. Students can form teams in Expertiza to work on various projects and assignments. Students can also peer review other students' submissions. Expertiza supports submission across various document types, including the URLs and word documents. Expertiza provides a dashboard for all the assignments corresponding to a course and provides absolute control to the Instructors and Teaching Assistants. In addition to assignments, it encompasses peer reviews wherein participants are allowed to provide feedback anonymously about each other's work thereby providing scope for the better outcome. The due_date.rb file is responsible for informing the users about the deadline for submission of the each assignment. Due dates in Expertiza have their association with many other components like assignments, reviews etc.&lt;br /&gt;
&lt;br /&gt;
=== Code Climate ===&lt;br /&gt;
Code Climate&amp;lt;ref&amp;gt;{{Cite web|url=https://codeclimate.com/dashboard|title=Log in to your Code Climate dashboard with GitHub or your email.|website=codeclimate.com|access-date=2016-10-28}}&amp;lt;/ref&amp;gt; is a tool that runs static analysis on a GitHub project and outputs many details like test coverage, complexity, duplication, security, style, and more. There is a Google Chrome extension to integrate the Code Climate results generated directly into GitHub which is visible when browsing the repository on the browser. It allows us to see issues displayed directly inside GitHub's UI, to review which lines are covered in diffs and files, and add repositories and open tickets without changing your workflow.&lt;br /&gt;
&lt;br /&gt;
== '''Tasks Identified''' ==&lt;br /&gt;
To install Code climate Chrome Extension that highlights the duplicated code.&lt;br /&gt;
&lt;br /&gt;
To refactor the following two files:&lt;br /&gt;
* Due_date.rb&lt;br /&gt;
** Ternary operators must not be nested. Prefer `if` or `else` constructs instead.&lt;br /&gt;
** Useless assignment to variable - `sorted_deadlines`.&lt;br /&gt;
** Prefer `each` over `for`.&lt;br /&gt;
** Use `find_by` instead of `where.first`.&lt;br /&gt;
** Correct the use of Time function&lt;br /&gt;
* Deadline_helper.rb&lt;br /&gt;
** Do not use `Time.now` without zone. Use one of `Time.zone.now`, `Time.current`, `Time.now.in_time_zone`, `Time.now.utc`, `Time.now.getlocal`, `Time.now.iso8601`, `Time.now.jisx0301`, `Time.now.rfc3339`, `Time.now.to_i`, `Time.now.to_f` instead.&lt;br /&gt;
** Trailing whitespace detected.&lt;br /&gt;
** Extra empty line detected at module body end.&lt;br /&gt;
&lt;br /&gt;
* Create respective RSpec files in /spec/models/ and /spec/helper folder and write unit tests for each method in due_date.rb and deadline_helper.rb.&lt;br /&gt;
&lt;br /&gt;
== '''Current Implementation''' ==&lt;br /&gt;
DueDate is a Model class to manage the deadlines of an assignment. It has methods for setting due dates for an assignment, copying due dates from one assignment to a new assignment etc. DeadlineHelper provides helper functions that help DueDate perform certain tasks. The assignment focuses on refactoring some of the methods based on warnings received from Code Climate's static analysis and modifying the language to make it more Ruby-friendly. The assignment also involves writing unit test cases for due_date.rb and deadline_helper.rb in order to increase test coverage. &lt;br /&gt;
&lt;br /&gt;
The goal of this project is to attempt to make this part of the application easier to read and write unit test cases that the application must pass. &lt;br /&gt;
&lt;br /&gt;
== '''Changed Implementation''' ==&lt;br /&gt;
Changes implemented involves refactoring the code and making it more understandable by adding comments in the code.&lt;br /&gt;
&lt;br /&gt;
The modified files are&lt;br /&gt;
* Due_date.rb (path: /app/models)&lt;br /&gt;
&lt;br /&gt;
* Deadline_helper.rb (path: /app/helpers)&lt;br /&gt;
Testing files&lt;br /&gt;
* Due_date_spec.rb (path: /spec/models)&lt;br /&gt;
* Deadline_helper_spec.rb (path: /spec/helpers)&lt;br /&gt;
=== Due_date.rb ===&lt;br /&gt;
* Converted for..in loop to object.each in order to follow better Ruby syntax.&lt;br /&gt;
* Unnecessary assignment to sorted_deadlines removed.&lt;br /&gt;
* Nested ternary operators have been changed to if..else in order to make it more readable.&lt;br /&gt;
[[File:Duedaterb.png]]&lt;br /&gt;
* Changed where(...).first to find_by(...) which is the newer recommended syntax.&lt;br /&gt;
* Corrected the Time.now functions by adding the correct zones to them such as Time.zone.now.&lt;br /&gt;
* Removed trailing whitespaces.&lt;br /&gt;
[[File:DueDaterb2.png]]&lt;br /&gt;
&lt;br /&gt;
=== Deadline_helper.rb ===&lt;br /&gt;
* Time functions were changed to functions with zones&lt;br /&gt;
* Extra line removed&lt;br /&gt;
[[File:Deadlinehelper.png]]&lt;br /&gt;
&lt;br /&gt;
== '''RSpec testing''' ==&lt;br /&gt;
There were no existing tests for the functions in due_date.rb and deadline_helper.rb. We have added exhaustive set of RSpec tests to test all the code. We have added two new spec files 'due_date_spec.rb' and ‘deadline_helper_spec.rb’ which cover the testing scenarios for the functions in ‘due_date.rb’ and ‘deadline_helper.rb’.&lt;br /&gt;
&lt;br /&gt;
These RSpec files have 100% code coverage visible at: /coverage/index.html&lt;br /&gt;
&lt;br /&gt;
=== due_date_spec.rb ===&lt;br /&gt;
This file is located at spec/models and tests the functionalities of the due_date.rb file located in app/models. There are 18 test cases in total which are listed below.&lt;br /&gt;
* If the factory is successfully able to build the due_date objects.&amp;lt;syntaxhighlight lang=&amp;quot;ruby&amp;quot;&amp;gt;&lt;br /&gt;
it &amp;quot;due date factory created successfully&amp;quot; do&lt;br /&gt;
    expect(@assignment_due_date).to be_valid&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&amp;lt;syntaxhighlight lang=&amp;quot;ruby&amp;quot;&amp;gt;&lt;br /&gt;
it &amp;quot;due dates created correctly&amp;quot; do&lt;br /&gt;
    expect(@due_dates.length).to be == 10&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
* If the function &amp;quot;set_flag&amp;quot; successfully sets the due_date flag.&amp;lt;syntaxhighlight lang=&amp;quot;ruby&amp;quot;&amp;gt;&lt;br /&gt;
it &amp;quot;due date flag is set&amp;quot; do&lt;br /&gt;
    expect(@assignment_due_date.flag).to be false&lt;br /&gt;
    @assignment_due_date.set_flag&lt;br /&gt;
    expect(@assignment_due_date.flag).to be true&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
* If the function &amp;quot;due_at_is_valid_datetime&amp;quot; returns nil (no errors) for a valid datetime in due_at (no invalid test cases can be added here because model does not allow invalid datetime to be set at all).&amp;lt;syntaxhighlight lang=&amp;quot;ruby&amp;quot;&amp;gt;&lt;br /&gt;
it &amp;quot;due at is valid datetime&amp;quot; do&lt;br /&gt;
    expect(@assignment_due_date.due_at_is_valid_datetime).to be nil&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
* If the function &amp;quot;self.copy&amp;quot; is able to copy due dates from one assignment to another.&amp;lt;syntaxhighlight lang=&amp;quot;ruby&amp;quot;&amp;gt;&lt;br /&gt;
it &amp;quot;copy due dates to new assignment&amp;quot; do&lt;br /&gt;
    new_assignment_id = build(:assignment, id: 999).id&lt;br /&gt;
    old_assignment_id = @assignment_due_date.assignment.id&lt;br /&gt;
    DueDate.copy(old_assignment_id, new_assignment_id)&lt;br /&gt;
    expect(DueDate.where(parent_id: new_assignment_id).count).to eql DueDate.where(parent_id: old_assignment_id).count&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
* If the function &amp;quot;self.set_duedate&amp;quot; is able to create another due date by copying data from an existing due date object.&amp;lt;syntaxhighlight lang=&amp;quot;ruby&amp;quot;&amp;gt;&lt;br /&gt;
it &amp;quot;create new duedate record with values&amp;quot; do&lt;br /&gt;
    DueDate.set_duedate({id: 999}, @assignment_due_date.deadline_type_id,&lt;br /&gt;
                        @assignment_due_date.parent_id, @assignment_due_date.round)&lt;br /&gt;
    new_due_date = DueDate.find_by(id: 999)&lt;br /&gt;
    expect(new_due_date).to be_valid&lt;br /&gt;
    expect(new_due_date.deadline_type_id).to eql @assignment_due_date.deadline_type_id&lt;br /&gt;
    expect(new_due_date.parent_id).to eql @assignment_due_date.parent_id&lt;br /&gt;
    expect(new_due_date.round).to eql @assignment_due_date.round&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
* If the function &amp;quot;self.deadline_sort&amp;quot; is able to sort the due dates in ascending order.&amp;lt;syntaxhighlight lang=&amp;quot;ruby&amp;quot;&amp;gt;&lt;br /&gt;
it &amp;quot;sort duedate records&amp;quot; do&lt;br /&gt;
    sorted_due_dates = @due_dates&lt;br /&gt;
    expect(sorted_due_dates.each_cons(2).all?{|m1, m2| (m1.due_at &amp;lt;=&amp;gt; m2.due_at) != 1}).to eql false&lt;br /&gt;
&lt;br /&gt;
    sorted_due_dates = DueDate.deadline_sort(@due_dates)&lt;br /&gt;
    expect(sorted_due_dates.each_cons(2).all?{|m1, m2| (m1.due_at &amp;lt;=&amp;gt; m2.due_at) != 1}).to eql true&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
* If the function &amp;quot;self.done_in_assignment_round&amp;quot; returns the correct number of rounds for specific inputs. This involves an invalid test case as well for 0 rounds.&amp;lt;syntaxhighlight lang=&amp;quot;ruby&amp;quot;&amp;gt;&lt;br /&gt;
describe &amp;quot;#done_in_assignment_round&amp;quot; do&lt;br /&gt;
    it &amp;quot;return 0 when no response map&amp;quot; do&lt;br /&gt;
      response = ReviewResponseMap.create&lt;br /&gt;
      response.type = &amp;quot;ResponseMap&amp;quot;&lt;br /&gt;
      response.save&lt;br /&gt;
      expect(DueDate.done_in_assignment_round(1, response)).to eql 0&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    it &amp;quot;return round 1 for single round&amp;quot; do&lt;br /&gt;
      response = ReviewResponseMap.create&lt;br /&gt;
      expect(DueDate.done_in_assignment_round(@assignment_due_date.parent_id, response)).to eql 1&lt;br /&gt;
    end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
* If the function &amp;quot;self.get_next_due_date&amp;quot; works as expected. This involves several invalid test cases as well.&amp;lt;syntaxhighlight lang=&amp;quot;ruby&amp;quot;&amp;gt;&lt;br /&gt;
describe &amp;quot;#get_next_due_date&amp;quot; do&lt;br /&gt;
    it &amp;quot;no subsequent due date&amp;quot; do&lt;br /&gt;
      expect(DueDate.get_next_due_date(@assignment_due_date.parent_id)).to be nil&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    it &amp;quot;nil value throws exception&amp;quot; do&lt;br /&gt;
      expect { DueDate.get_next_due_date(nil) }.to raise_exception(ActiveRecord::RecordNotFound)&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    it &amp;quot;get next assignment due date&amp;quot; do&lt;br /&gt;
      due_date = create(:assignment_due_date, deadline_type: @deadline_type,&lt;br /&gt;
        submission_allowed_id: @deadline_right.id, review_allowed_id: @deadline_right.id,&lt;br /&gt;
        review_of_review_allowed_id: @deadline_right.id, due_at: Time.zone.now + 5000)&lt;br /&gt;
      expect(DueDate.get_next_due_date(due_date.parent_id)).to be_valid&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    it &amp;quot;get next due date from topic for staggered deadline&amp;quot; do&lt;br /&gt;
      assignment_id = create(:assignment, staggered_deadline: true, name: &amp;quot;testassignment&amp;quot;).id&lt;br /&gt;
      due_date = create(:topic_due_date, deadline_type: @deadline_type,&lt;br /&gt;
        submission_allowed_id: @deadline_right.id, review_allowed_id: @deadline_right.id,&lt;br /&gt;
        review_of_review_allowed_id: @deadline_right.id, due_at: Time.zone.now + 5000, parent_id: assignment_id)&lt;br /&gt;
      expect(DueDate.get_next_due_date(assignment_id, due_date.parent_id)).to be_valid&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    it &amp;quot;next due date does not exist for staggered deadline&amp;quot; do&lt;br /&gt;
      assignment_id = create(:assignment, staggered_deadline: true, name: &amp;quot;testassignment&amp;quot;).id&lt;br /&gt;
      due_date = create(:topic_due_date, deadline_type: @deadline_type,&lt;br /&gt;
        submission_allowed_id: @deadline_right, review_allowed_id: @deadline_right,&lt;br /&gt;
        review_of_review_allowed_id: @deadline_right, due_at: Time.zone.now + 5000, parent_id: assignment_id)&lt;br /&gt;
      expect(DueDate.get_next_due_date(assignment_id)).to be nil&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    it &amp;quot;next due date is before Time.now for staggered deadline&amp;quot; do&lt;br /&gt;
      assignment_id = create(:assignment, staggered_deadline: true, name: &amp;quot;testassignment&amp;quot;).id&lt;br /&gt;
      due_date = create(:topic_due_date, deadline_type: @deadline_type,&lt;br /&gt;
        submission_allowed_id: @deadline_right, review_allowed_id: @deadline_right,&lt;br /&gt;
        review_of_review_allowed_id: @deadline_right, due_at: Time.zone.now - 5000, parent_id: assignment_id)&lt;br /&gt;
      expect(DueDate.get_next_due_date(assignment_id, due_date.parent_id)).to be nil&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    it &amp;quot;get next due date from assignment for staggered deadline&amp;quot; do&lt;br /&gt;
      assignment_id = create(:assignment, staggered_deadline: true, name: &amp;quot;testassignment&amp;quot;).id&lt;br /&gt;
      due_date = create(:assignment_due_date, deadline_type: @deadline_type,&lt;br /&gt;
        submission_allowed_id: @deadline_right, review_allowed_id: @deadline_right,&lt;br /&gt;
        review_of_review_allowed_id: @deadline_right, due_at: Time.zone.now + 5000, parent_id: assignment_id)&lt;br /&gt;
      expect(DueDate.get_next_due_date(assignment_id)).to be_valid&lt;br /&gt;
    end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
* If the function &amp;quot;self.default_permission&amp;quot; returns the correct default permissions for particular deadline and permission types.&amp;lt;syntaxhighlight lang=&amp;quot;ruby&amp;quot;&amp;gt;&lt;br /&gt;
it &amp;quot;metareview review_of_review_allowed default permission OK&amp;quot; do&lt;br /&gt;
    expect(DueDate.default_permission('metareview', 'review_of_review_allowed')).to be == DeadlineRight::OK&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&amp;lt;syntaxhighlight lang=&amp;quot;ruby&amp;quot;&amp;gt;&lt;br /&gt;
it &amp;quot;review submission_allowed default permission NO&amp;quot; do&lt;br /&gt;
    expect(DueDate.default_permission('review', 'submission_allowed')).to be == DeadlineRight::NO&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
To test this file run the following command:&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
rspec spec/models/due_date_spec.rb&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
The output of this RSpec file is present in below screenshot:&lt;br /&gt;
[[File:Duedaterspec.png|center|thumb|558x558px]]&lt;br /&gt;
&lt;br /&gt;
Code coverage details of the above RSpec files is present in below screenshot:&lt;br /&gt;
[[File:Duedatecoverage.png|center|thumb|736x736px]]&lt;br /&gt;
&lt;br /&gt;
Code coverage details of the above RSpec files is present in below screenshot:&lt;br /&gt;
&lt;br /&gt;
=== deadline_helper_spec.rb ===&lt;br /&gt;
This is a test file for testing the functionalities of Deadline_helper.rb file located at app/helpers. Different test cases present in this file are:&lt;br /&gt;
* Check if the factory is valid:  &lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;ruby&amp;quot;&amp;gt;&lt;br /&gt;
it &amp;quot;has a valid factory&amp;quot; do&lt;br /&gt;
    factory = FactoryGirl.build(:topic_due_date)&lt;br /&gt;
    expect(factory).to be_valid&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
* Fail if the due date is invalid:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;ruby&amp;quot;&amp;gt;&lt;br /&gt;
it &amp;quot;should fail because of invalid due_date&amp;quot; do&lt;br /&gt;
      expect { DeadlineHelper.create_topic_deadline(nil, 0, 0)}.to raise_exception(NoMethodError)&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
* If new due_date object is created:&amp;lt;syntaxhighlight lang=&amp;quot;ruby&amp;quot;&amp;gt;&lt;br /&gt;
it &amp;quot;new due_date object created&amp;quot; do&lt;br /&gt;
      DeadlineHelper.create_topic_deadline(@topic_due_date, 0, 1)&lt;br /&gt;
      expect(TopicDueDate.count).to be == 2&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
* due_at should be same for 0 offset:&amp;lt;syntaxhighlight lang=&amp;quot;ruby&amp;quot;&amp;gt;&lt;br /&gt;
 it &amp;quot;due_at should be same for 0 offset&amp;quot; do&lt;br /&gt;
      DeadlineHelper.create_topic_deadline(@topic_due_date, 0, 10)&lt;br /&gt;
      new_due_date = TopicDueDate.find_by(parent_id: 10)&lt;br /&gt;
      expect(new_due_date).to be_valid&lt;br /&gt;
      expect(new_due_date.due_at.to_s).to be == @topic_due_date.due_at.to_s&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
* due_at is calculated correctly if offset is positive:&amp;lt;syntaxhighlight lang=&amp;quot;ruby&amp;quot;&amp;gt;&lt;br /&gt;
it &amp;quot;due_at calculated correctly for positive offset&amp;quot; do&lt;br /&gt;
      DeadlineHelper.create_topic_deadline(@topic_due_date, 5000, 10)&lt;br /&gt;
      new_due_date = TopicDueDate.find_by(parent_id: 10)&lt;br /&gt;
      expect(new_due_date).to be_valid&lt;br /&gt;
      expect(new_due_date.due_at.to_s).to be == (Time.zone.parse(@topic_due_date.due_at.to_s) + 5000).to_s&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
* due_at is calculated correctly if offset is negative:&amp;lt;syntaxhighlight lang=&amp;quot;ruby&amp;quot;&amp;gt;&lt;br /&gt;
it &amp;quot;due_at calculated correctly for negative offset&amp;quot; do&lt;br /&gt;
      DeadlineHelper.create_topic_deadline(@topic_due_date, -5000, 10)&lt;br /&gt;
      new_due_date = TopicDueDate.find_by(parent_id: 10)&lt;br /&gt;
      expect(new_due_date).to be_valid&lt;br /&gt;
      expect(new_due_date.due_at.to_s).to be == (Time.zone.parse(@topic_due_date.due_at.to_s) - 5000).to_s&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
* The offset is being converted to integer properly:&amp;lt;syntaxhighlight lang=&amp;quot;ruby&amp;quot;&amp;gt;&lt;br /&gt;
it &amp;quot;offset converted to integer correctly&amp;quot; do&lt;br /&gt;
      DeadlineHelper.create_topic_deadline(@topic_due_date, 5000.15, 10)&lt;br /&gt;
      new_due_date = TopicDueDate.find_by(parent_id: 10)&lt;br /&gt;
      expect(new_due_date).to be_valid&lt;br /&gt;
      expect(new_due_date.due_at.to_s).to be == (Time.zone.parse(@topic_due_date.due_at.to_s) + 5000).to_s&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
To test this file run the following command:&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
rspec spec/models/deadline_helper_spec.rb&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;The output of this RSpec file is present in below screenshot:&lt;br /&gt;
[[File:Deadlinerspec.png|center|thumb|705x705px]]&lt;br /&gt;
&lt;br /&gt;
Code coverage details of the above RSpec files is present in below screenshot:&lt;br /&gt;
[[File:Deadlinecoverage.png|center|thumb|823x823px]]&lt;br /&gt;
&lt;br /&gt;
== '''References''' ==&lt;/div&gt;</summary>
		<author><name>Nthanik</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=File:Deadlinehelper.png&amp;diff=103194</id>
		<title>File:Deadlinehelper.png</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=File:Deadlinehelper.png&amp;diff=103194"/>
		<updated>2016-10-28T22:31:00Z</updated>

		<summary type="html">&lt;p&gt;Nthanik: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Nthanik</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=File:DueDaterb2.png&amp;diff=103181</id>
		<title>File:DueDaterb2.png</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=File:DueDaterb2.png&amp;diff=103181"/>
		<updated>2016-10-28T22:24:44Z</updated>

		<summary type="html">&lt;p&gt;Nthanik: uploaded a new version of &amp;amp;quot;File:DueDaterb2.png&amp;amp;quot;: due&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Nthanik</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=File:DueDaterb2.png&amp;diff=103173</id>
		<title>File:DueDaterb2.png</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=File:DueDaterb2.png&amp;diff=103173"/>
		<updated>2016-10-28T22:17:24Z</updated>

		<summary type="html">&lt;p&gt;Nthanik: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Nthanik</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=File:Duedaterb.png&amp;diff=103160</id>
		<title>File:Duedaterb.png</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=File:Duedaterb.png&amp;diff=103160"/>
		<updated>2016-10-28T22:11:14Z</updated>

		<summary type="html">&lt;p&gt;Nthanik: uploaded a new version of &amp;amp;quot;File:Duedaterb.png&amp;amp;quot;: Reverted to version as of 22:08, 28 October 2016&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Due_date.rb&lt;/div&gt;</summary>
		<author><name>Nthanik</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=File:Duedaterb.png&amp;diff=103158</id>
		<title>File:Duedaterb.png</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=File:Duedaterb.png&amp;diff=103158"/>
		<updated>2016-10-28T22:11:05Z</updated>

		<summary type="html">&lt;p&gt;Nthanik: uploaded a new version of &amp;amp;quot;File:Duedaterb.png&amp;amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Due_date.rb&lt;/div&gt;</summary>
		<author><name>Nthanik</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=File:Duedaterb.png&amp;diff=103154</id>
		<title>File:Duedaterb.png</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=File:Duedaterb.png&amp;diff=103154"/>
		<updated>2016-10-28T22:09:31Z</updated>

		<summary type="html">&lt;p&gt;Nthanik: uploaded a new version of &amp;amp;quot;File:Duedaterb.png&amp;amp;quot;: Reverted to version as of 22:08, 28 October 2016&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Due_date.rb&lt;/div&gt;</summary>
		<author><name>Nthanik</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=File:Duedaterb.png&amp;diff=103152</id>
		<title>File:Duedaterb.png</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=File:Duedaterb.png&amp;diff=103152"/>
		<updated>2016-10-28T22:09:15Z</updated>

		<summary type="html">&lt;p&gt;Nthanik: uploaded a new version of &amp;amp;quot;File:Duedaterb.png&amp;amp;quot;: Due&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Due_date.rb&lt;/div&gt;</summary>
		<author><name>Nthanik</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=File:Duedaterb.png&amp;diff=103150</id>
		<title>File:Duedaterb.png</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=File:Duedaterb.png&amp;diff=103150"/>
		<updated>2016-10-28T22:08:41Z</updated>

		<summary type="html">&lt;p&gt;Nthanik: Due_date.rb&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Due_date.rb&lt;/div&gt;</summary>
		<author><name>Nthanik</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2016/E1634.Refactor_and_write_unit_test_of_due_date.rb_and_deadline_helper.rb&amp;diff=102952</id>
		<title>CSC/ECE 517 Fall 2016/E1634.Refactor and write unit test of due date.rb and deadline helper.rb</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2016/E1634.Refactor_and_write_unit_test_of_due_date.rb_and_deadline_helper.rb&amp;diff=102952"/>
		<updated>2016-10-28T20:40:09Z</updated>

		<summary type="html">&lt;p&gt;Nthanik: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== '''Introduction''' ==&lt;br /&gt;
&lt;br /&gt;
=== Expertiza ===&lt;br /&gt;
Expertiza is an open source project for school assignment management for instructors and students based on the Ruby on Rails framework. Expertiza allows the instructor to create new assignments and customise new or existing assignments. It also allows the instructor to create a list of topics the students can sign up for. Students can form teams in Expertiza to work on various projects and assignments. Students can also peer review other students' submissions. Expertiza supports submission across various document types, including the URLs and word documents. Expertiza provides a dashboard for all the assignments corresponding to a course and provides absolute control to the Instructors and Teaching Assistants. In addition to assignments, it encompasses peer reviews wherein participants are allowed to provide feedback anonymously about each other's work thereby providing scope for the better outcome. The due_date.rb file is responsible for informing the users about the deadline for submission of the each assignment. Due dates in Expertiza have their association with many other components like assignments, reviews etc.&lt;br /&gt;
&lt;br /&gt;
=== Code Climate ===&lt;br /&gt;
Code Climate&amp;lt;ref&amp;gt;{{Cite web|url=https://codeclimate.com/dashboard|title=Log in to your Code Climate dashboard with GitHub or your email.|website=codeclimate.com|access-date=2016-10-28}}&amp;lt;/ref&amp;gt; is a tool that runs static analysis on a GitHub project and outputs many details like test coverage, complexity, duplication, security, style, and more. There is a Google Chrome extension to integrate the Code Climate results generated directly into GitHub which is visible when browsing the repository on the browser. It allows us to see issues displayed directly inside GitHub's UI, to review which lines are covered in diffs and files, and add repositories and open tickets without changing your workflow.&lt;br /&gt;
&lt;br /&gt;
== '''Tasks Identified''' ==&lt;br /&gt;
To install Code climate Chrome Extension that highlights the duplicated code.&lt;br /&gt;
&lt;br /&gt;
To refactor the following two files:&lt;br /&gt;
* Due_date.rb&lt;br /&gt;
** Ternary operators must not be nested. Prefer `if` or `else` constructs instead.&lt;br /&gt;
** Useless assignment to variable - `sorted_deadlines`.&lt;br /&gt;
** Prefer `each` over `for`.&lt;br /&gt;
** Use `find_by` instead of `where.first`.&lt;br /&gt;
** Correct the use of Time function&lt;br /&gt;
* Deadline_helper.rb&lt;br /&gt;
** Do not use `Time.now` without zone. Use one of `Time.zone.now`, `Time.current`, `Time.now.in_time_zone`, `Time.now.utc`, `Time.now.getlocal`, `Time.now.iso8601`, `Time.now.jisx0301`, `Time.now.rfc3339`, `Time.now.to_i`, `Time.now.to_f` instead.&lt;br /&gt;
** Trailing whitespace detected.&lt;br /&gt;
** Extra empty line detected at module body end.&lt;br /&gt;
&lt;br /&gt;
* Create respective RSpec files in /spec/models/ and /spec/helper folder and write unit tests for each method in due_date.rb and deadline_helper.rb.&lt;br /&gt;
&lt;br /&gt;
== '''Current Implementation''' ==&lt;br /&gt;
DueDate is a Model class to manage the deadlines of an assignment. It has methods for setting due dates for an assignment, copying due dates from one assignment to a new assignment etc. DeadlineHelper provides helper functions that help DueDate perform certain tasks. The assignment focuses on refactoring some of the methods based on warnings received from Code Climate's static analysis and modifying the language to make it more Ruby-friendly. The assignment also involves writing unit test cases for due_date.rb and deadline_helper.rb in order to increase test coverage. &lt;br /&gt;
&lt;br /&gt;
The goal of this project is to attempt to make this part of the application easier to read and write unit test cases that the application must pass. &lt;br /&gt;
&lt;br /&gt;
== '''Changed Implementation''' ==&lt;br /&gt;
Changes implemented involves refactoring the code and making it more understandable by adding comments in the code.&lt;br /&gt;
&lt;br /&gt;
The modified files are&lt;br /&gt;
* Due_date.rb (path: /app/models)&lt;br /&gt;
&lt;br /&gt;
* Deadline_helper.rb (path: /app/helpers)&lt;br /&gt;
Testing files&lt;br /&gt;
* Due_date_spec.rb (path: /spec/models)&lt;br /&gt;
* Deadline_helper_spec.rb (path: /spec/helpers)&lt;br /&gt;
=== Due_date.rb ===&lt;br /&gt;
* Converted for..in loop to object.each in order to follow better Ruby syntax.&lt;br /&gt;
* Unnecessary assignment to sorted_deadlines removed.&lt;br /&gt;
* Nested ternary operators have been changed to if..else in order to make it more readable.&lt;br /&gt;
**[[File:Duedaterb.png|thumb|Due_date.rb|center|500x500px]]&lt;br /&gt;
* Changed where(...).first to find_by(...) which is the newer recommended syntax.&lt;br /&gt;
* Corrected the Time.now functions by adding the correct zones to them such as Time.zone.now.&lt;br /&gt;
* Removed trailing whitespaces.[[File:DueDaterb2.png|center|thumb|565x565px]]&lt;br /&gt;
&lt;br /&gt;
=== Deadline_helper.rb ===&lt;br /&gt;
* Time functions were changed to functions with zones&lt;br /&gt;
* Extra line removed&lt;br /&gt;
[[File:Deadlinehelper.png|center|thumb|631x631px|Deadline_helper]]&lt;br /&gt;
&lt;br /&gt;
== '''RSpec testing''' ==&lt;br /&gt;
There were no existing tests for the functions in due_date.rb and deadline_helper.rb. We have added exhaustive set of RSpec tests to test all the code. We have added two new spec files 'due_date_spec.rb' and ‘deadline_helper_spec.rb’ which cover the testing scenarios for the functions in ‘due_date.rb’ and ‘deadline_helper.rb’.&lt;br /&gt;
&lt;br /&gt;
These RSpec files have 100% code coverage visible at: /coverage/index.html&lt;br /&gt;
&lt;br /&gt;
=== due_date_spec.rb ===&lt;br /&gt;
This file is located at spec/models and tests the functionalities of the due_date.rb file located in app/models. There are 18 test cases in total which are listed below.&lt;br /&gt;
* If the factory is successfully able to build the due_date objects.&amp;lt;syntaxhighlight lang=&amp;quot;ruby&amp;quot;&amp;gt;&lt;br /&gt;
it &amp;quot;due date factory created successfully&amp;quot; do&lt;br /&gt;
    expect(@assignment_due_date).to be_valid&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&amp;lt;syntaxhighlight lang=&amp;quot;ruby&amp;quot;&amp;gt;&lt;br /&gt;
it &amp;quot;due dates created correctly&amp;quot; do&lt;br /&gt;
    expect(@due_dates.length).to be == 10&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
* If the function &amp;quot;set_flag&amp;quot; successfully sets the due_date flag.&amp;lt;syntaxhighlight lang=&amp;quot;ruby&amp;quot;&amp;gt;&lt;br /&gt;
it &amp;quot;due date flag is set&amp;quot; do&lt;br /&gt;
    expect(@assignment_due_date.flag).to be false&lt;br /&gt;
    @assignment_due_date.set_flag&lt;br /&gt;
    expect(@assignment_due_date.flag).to be true&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
* If the function &amp;quot;due_at_is_valid_datetime&amp;quot; returns nil (no errors) for a valid datetime in due_at (no invalid test cases can be added here because model does not allow invalid datetime to be set at all).&amp;lt;syntaxhighlight lang=&amp;quot;ruby&amp;quot;&amp;gt;&lt;br /&gt;
it &amp;quot;due at is valid datetime&amp;quot; do&lt;br /&gt;
    expect(@assignment_due_date.due_at_is_valid_datetime).to be nil&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
* If the function &amp;quot;self.copy&amp;quot; is able to copy due dates from one assignment to another.&amp;lt;syntaxhighlight lang=&amp;quot;ruby&amp;quot;&amp;gt;&lt;br /&gt;
it &amp;quot;copy due dates to new assignment&amp;quot; do&lt;br /&gt;
    new_assignment_id = build(:assignment, id: 999).id&lt;br /&gt;
    old_assignment_id = @assignment_due_date.assignment.id&lt;br /&gt;
    DueDate.copy(old_assignment_id, new_assignment_id)&lt;br /&gt;
    expect(DueDate.where(parent_id: new_assignment_id).count).to eql DueDate.where(parent_id: old_assignment_id).count&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
* If the function &amp;quot;self.set_duedate&amp;quot; is able to create another due date by copying data from an existing due date object.&amp;lt;syntaxhighlight lang=&amp;quot;ruby&amp;quot;&amp;gt;&lt;br /&gt;
it &amp;quot;create new duedate record with values&amp;quot; do&lt;br /&gt;
    DueDate.set_duedate({id: 999}, @assignment_due_date.deadline_type_id,&lt;br /&gt;
                        @assignment_due_date.parent_id, @assignment_due_date.round)&lt;br /&gt;
    new_due_date = DueDate.find_by(id: 999)&lt;br /&gt;
    expect(new_due_date).to be_valid&lt;br /&gt;
    expect(new_due_date.deadline_type_id).to eql @assignment_due_date.deadline_type_id&lt;br /&gt;
    expect(new_due_date.parent_id).to eql @assignment_due_date.parent_id&lt;br /&gt;
    expect(new_due_date.round).to eql @assignment_due_date.round&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
* If the function &amp;quot;self.deadline_sort&amp;quot; is able to sort the due dates in ascending order.&amp;lt;syntaxhighlight lang=&amp;quot;ruby&amp;quot;&amp;gt;&lt;br /&gt;
it &amp;quot;sort duedate records&amp;quot; do&lt;br /&gt;
    sorted_due_dates = @due_dates&lt;br /&gt;
    expect(sorted_due_dates.each_cons(2).all?{|m1, m2| (m1.due_at &amp;lt;=&amp;gt; m2.due_at) != 1}).to eql false&lt;br /&gt;
&lt;br /&gt;
    sorted_due_dates = DueDate.deadline_sort(@due_dates)&lt;br /&gt;
    expect(sorted_due_dates.each_cons(2).all?{|m1, m2| (m1.due_at &amp;lt;=&amp;gt; m2.due_at) != 1}).to eql true&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
* If the function &amp;quot;self.done_in_assignment_round&amp;quot; returns the correct number of rounds for specific inputs. This involves an invalid test case as well for 0 rounds.&amp;lt;syntaxhighlight lang=&amp;quot;ruby&amp;quot;&amp;gt;&lt;br /&gt;
describe &amp;quot;#done_in_assignment_round&amp;quot; do&lt;br /&gt;
    it &amp;quot;return 0 when no response map&amp;quot; do&lt;br /&gt;
      response = ReviewResponseMap.create&lt;br /&gt;
      response.type = &amp;quot;ResponseMap&amp;quot;&lt;br /&gt;
      response.save&lt;br /&gt;
      expect(DueDate.done_in_assignment_round(1, response)).to eql 0&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    it &amp;quot;return round 1 for single round&amp;quot; do&lt;br /&gt;
      response = ReviewResponseMap.create&lt;br /&gt;
      expect(DueDate.done_in_assignment_round(@assignment_due_date.parent_id, response)).to eql 1&lt;br /&gt;
    end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
* If the function &amp;quot;self.get_next_due_date&amp;quot; works as expected. This involves several invalid test cases as well.&amp;lt;syntaxhighlight lang=&amp;quot;ruby&amp;quot;&amp;gt;&lt;br /&gt;
describe &amp;quot;#get_next_due_date&amp;quot; do&lt;br /&gt;
    it &amp;quot;no subsequent due date&amp;quot; do&lt;br /&gt;
      expect(DueDate.get_next_due_date(@assignment_due_date.parent_id)).to be nil&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    it &amp;quot;nil value throws exception&amp;quot; do&lt;br /&gt;
      expect { DueDate.get_next_due_date(nil) }.to raise_exception(ActiveRecord::RecordNotFound)&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    it &amp;quot;get next assignment due date&amp;quot; do&lt;br /&gt;
      due_date = create(:assignment_due_date, deadline_type: @deadline_type,&lt;br /&gt;
        submission_allowed_id: @deadline_right.id, review_allowed_id: @deadline_right.id,&lt;br /&gt;
        review_of_review_allowed_id: @deadline_right.id, due_at: Time.zone.now + 5000)&lt;br /&gt;
      expect(DueDate.get_next_due_date(due_date.parent_id)).to be_valid&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    it &amp;quot;get next due date from topic for staggered deadline&amp;quot; do&lt;br /&gt;
      assignment_id = create(:assignment, staggered_deadline: true, name: &amp;quot;testassignment&amp;quot;).id&lt;br /&gt;
      due_date = create(:topic_due_date, deadline_type: @deadline_type,&lt;br /&gt;
        submission_allowed_id: @deadline_right.id, review_allowed_id: @deadline_right.id,&lt;br /&gt;
        review_of_review_allowed_id: @deadline_right.id, due_at: Time.zone.now + 5000, parent_id: assignment_id)&lt;br /&gt;
      expect(DueDate.get_next_due_date(assignment_id, due_date.parent_id)).to be_valid&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    it &amp;quot;next due date does not exist for staggered deadline&amp;quot; do&lt;br /&gt;
      assignment_id = create(:assignment, staggered_deadline: true, name: &amp;quot;testassignment&amp;quot;).id&lt;br /&gt;
      due_date = create(:topic_due_date, deadline_type: @deadline_type,&lt;br /&gt;
        submission_allowed_id: @deadline_right, review_allowed_id: @deadline_right,&lt;br /&gt;
        review_of_review_allowed_id: @deadline_right, due_at: Time.zone.now + 5000, parent_id: assignment_id)&lt;br /&gt;
      expect(DueDate.get_next_due_date(assignment_id)).to be nil&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    it &amp;quot;next due date is before Time.now for staggered deadline&amp;quot; do&lt;br /&gt;
      assignment_id = create(:assignment, staggered_deadline: true, name: &amp;quot;testassignment&amp;quot;).id&lt;br /&gt;
      due_date = create(:topic_due_date, deadline_type: @deadline_type,&lt;br /&gt;
        submission_allowed_id: @deadline_right, review_allowed_id: @deadline_right,&lt;br /&gt;
        review_of_review_allowed_id: @deadline_right, due_at: Time.zone.now - 5000, parent_id: assignment_id)&lt;br /&gt;
      expect(DueDate.get_next_due_date(assignment_id, due_date.parent_id)).to be nil&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    it &amp;quot;get next due date from assignment for staggered deadline&amp;quot; do&lt;br /&gt;
      assignment_id = create(:assignment, staggered_deadline: true, name: &amp;quot;testassignment&amp;quot;).id&lt;br /&gt;
      due_date = create(:assignment_due_date, deadline_type: @deadline_type,&lt;br /&gt;
        submission_allowed_id: @deadline_right, review_allowed_id: @deadline_right,&lt;br /&gt;
        review_of_review_allowed_id: @deadline_right, due_at: Time.zone.now + 5000, parent_id: assignment_id)&lt;br /&gt;
      expect(DueDate.get_next_due_date(assignment_id)).to be_valid&lt;br /&gt;
    end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
* If the function &amp;quot;self.default_permission&amp;quot; returns the correct default permissions for particular deadline and permission types.&amp;lt;syntaxhighlight lang=&amp;quot;ruby&amp;quot;&amp;gt;&lt;br /&gt;
it &amp;quot;metareview review_of_review_allowed default permission OK&amp;quot; do&lt;br /&gt;
    expect(DueDate.default_permission('metareview', 'review_of_review_allowed')).to be == DeadlineRight::OK&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&amp;lt;syntaxhighlight lang=&amp;quot;ruby&amp;quot;&amp;gt;&lt;br /&gt;
it &amp;quot;review submission_allowed default permission NO&amp;quot; do&lt;br /&gt;
    expect(DueDate.default_permission('review', 'submission_allowed')).to be == DeadlineRight::NO&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
To test this file run the following command:&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
rspec spec/models/due_date_spec.rb&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
The output of this RSpec file is present in below screenshot:&lt;br /&gt;
[[File:Duedaterspec.png|center|thumb|558x558px]]&lt;br /&gt;
&lt;br /&gt;
Code coverage details of the above RSpec files is present in below screenshot:&lt;br /&gt;
[[File:Duedatecoverage.png|center|thumb|736x736px]]&lt;br /&gt;
&lt;br /&gt;
Code coverage details of the above RSpec files is present in below screenshot:&lt;br /&gt;
&lt;br /&gt;
=== deadline_helper_spec.rb ===&lt;br /&gt;
This is a test file for testing the functionalities of Deadline_helper.rb file located at app/helpers. Different test cases present in this file are:&lt;br /&gt;
* Check if the factory is valid:  &lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;ruby&amp;quot;&amp;gt;&lt;br /&gt;
it &amp;quot;has a valid factory&amp;quot; do&lt;br /&gt;
    factory = FactoryGirl.build(:topic_due_date)&lt;br /&gt;
    expect(factory).to be_valid&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
* Fail if the due date is invalid:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;ruby&amp;quot;&amp;gt;&lt;br /&gt;
it &amp;quot;should fail because of invalid due_date&amp;quot; do&lt;br /&gt;
      expect { DeadlineHelper.create_topic_deadline(nil, 0, 0)}.to raise_exception(NoMethodError)&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
* If new due_date object is created:&amp;lt;syntaxhighlight lang=&amp;quot;ruby&amp;quot;&amp;gt;&lt;br /&gt;
it &amp;quot;new due_date object created&amp;quot; do&lt;br /&gt;
      DeadlineHelper.create_topic_deadline(@topic_due_date, 0, 1)&lt;br /&gt;
      expect(TopicDueDate.count).to be == 2&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
* due_at should be same for 0 offset:&amp;lt;syntaxhighlight lang=&amp;quot;ruby&amp;quot;&amp;gt;&lt;br /&gt;
 it &amp;quot;due_at should be same for 0 offset&amp;quot; do&lt;br /&gt;
      DeadlineHelper.create_topic_deadline(@topic_due_date, 0, 10)&lt;br /&gt;
      new_due_date = TopicDueDate.find_by(parent_id: 10)&lt;br /&gt;
      expect(new_due_date).to be_valid&lt;br /&gt;
      expect(new_due_date.due_at.to_s).to be == @topic_due_date.due_at.to_s&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
* due_at is calculated correctly if offset is positive:&amp;lt;syntaxhighlight lang=&amp;quot;ruby&amp;quot;&amp;gt;&lt;br /&gt;
it &amp;quot;due_at calculated correctly for positive offset&amp;quot; do&lt;br /&gt;
      DeadlineHelper.create_topic_deadline(@topic_due_date, 5000, 10)&lt;br /&gt;
      new_due_date = TopicDueDate.find_by(parent_id: 10)&lt;br /&gt;
      expect(new_due_date).to be_valid&lt;br /&gt;
      expect(new_due_date.due_at.to_s).to be == (Time.zone.parse(@topic_due_date.due_at.to_s) + 5000).to_s&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
* due_at is calculated correctly if offset is negative:&amp;lt;syntaxhighlight lang=&amp;quot;ruby&amp;quot;&amp;gt;&lt;br /&gt;
it &amp;quot;due_at calculated correctly for negative offset&amp;quot; do&lt;br /&gt;
      DeadlineHelper.create_topic_deadline(@topic_due_date, -5000, 10)&lt;br /&gt;
      new_due_date = TopicDueDate.find_by(parent_id: 10)&lt;br /&gt;
      expect(new_due_date).to be_valid&lt;br /&gt;
      expect(new_due_date.due_at.to_s).to be == (Time.zone.parse(@topic_due_date.due_at.to_s) - 5000).to_s&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
* The offset is being converted to integer properly:&amp;lt;syntaxhighlight lang=&amp;quot;ruby&amp;quot;&amp;gt;&lt;br /&gt;
it &amp;quot;offset converted to integer correctly&amp;quot; do&lt;br /&gt;
      DeadlineHelper.create_topic_deadline(@topic_due_date, 5000.15, 10)&lt;br /&gt;
      new_due_date = TopicDueDate.find_by(parent_id: 10)&lt;br /&gt;
      expect(new_due_date).to be_valid&lt;br /&gt;
      expect(new_due_date.due_at.to_s).to be == (Time.zone.parse(@topic_due_date.due_at.to_s) + 5000).to_s&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
To test this file run the following command:&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
rspec spec/models/deadline_helper_spec.rb&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;The output of this RSpec file is present in below screenshot:&lt;br /&gt;
[[File:Deadlinerspec.png|center|thumb|705x705px]]&lt;br /&gt;
&lt;br /&gt;
Code coverage details of the above RSpec files is present in below screenshot:&lt;br /&gt;
[[File:Deadlinecoverage.png|center|thumb|823x823px]]&lt;br /&gt;
&lt;br /&gt;
== '''References''' ==&lt;/div&gt;</summary>
		<author><name>Nthanik</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2016/E1634.Refactor_and_write_unit_test_of_due_date.rb_and_deadline_helper.rb&amp;diff=102936</id>
		<title>CSC/ECE 517 Fall 2016/E1634.Refactor and write unit test of due date.rb and deadline helper.rb</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2016/E1634.Refactor_and_write_unit_test_of_due_date.rb_and_deadline_helper.rb&amp;diff=102936"/>
		<updated>2016-10-28T20:36:42Z</updated>

		<summary type="html">&lt;p&gt;Nthanik: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;'''Introduction&lt;br /&gt;
'''Expertiza&lt;br /&gt;
Expertiza is an open source project for school assignment management for instructors and students based on the Ruby on Rails framework. Expertiza allows the instructor to create new assignments and customise new or existing assignments. It also allows the instructor to create a list of topics the students can sign up for. Students can form teams in Expertiza to work on various projects and assignments. Students can also peer review other students' submissions. Expertiza supports submission across various document types, including the URLs and word documents. Expertiza provides a dashboard for all the assignments corresponding to a course and provides absolute control to the Instructors and Teaching Assistants. In addition to assignments, it encompasses peer reviews wherein participants are allowed to provide feedback anonymously about each other's work thereby providing scope for the better outcome. The due_date.rb file is responsible for informing the users about the deadline for submission of the each assignment. Due dates in Expertiza have their association with many other components like assignments, reviews etc.&lt;br /&gt;
&lt;br /&gt;
Code Climate&lt;br /&gt;
Code Climate[1] is a tool that runs static analysis on a GitHub project and outputs many details like test coverage, complexity, duplication, security, style, and more. There is a Google Chrome extension to integrate the Code Climate results generated directly into GitHub which is visible when browsing the repository on the browser. It allows us to see issues displayed directly inside GitHub's UI, to review which lines are covered in diffs and files, and add repositories and open tickets without changing your workflow.&lt;br /&gt;
&lt;br /&gt;
Tasks Identified&lt;br /&gt;
To install Code climate Chrome Extension that highlights the duplicated code.&lt;br /&gt;
&lt;br /&gt;
To refactor the following two files:&lt;br /&gt;
&lt;br /&gt;
Due_date.rb&lt;br /&gt;
Ternary operators must not be nested. Prefer `if` or `else` constructs instead.&lt;br /&gt;
Useless assignment to variable - `sorted_deadlines`.&lt;br /&gt;
Prefer `each` over `for`.&lt;br /&gt;
Use `find_by` instead of `where.first`.&lt;br /&gt;
Correct the use of Time function&lt;br /&gt;
Deadline_helper.rb&lt;br /&gt;
Do not use `Time.now` without zone. Use one of `Time.zone.now`, `Time.current`, `Time.now.in_time_zone`, `Time.now.utc`, `Time.now.getlocal`, `Time.now.iso8601`, `Time.now.jisx0301`, `Time.now.rfc3339`, `Time.now.to_i`, `Time.now.to_f` instead.&lt;br /&gt;
Trailing whitespace detected.&lt;br /&gt;
Extra empty line detected at module body end.&lt;br /&gt;
Create respective RSpec files in /spec/models/ and /spec/helper folder and write unit tests for each method in due_date.rb and deadline_helper.rb.&lt;br /&gt;
Current Implementation&lt;br /&gt;
DueDate is a Model class to manage the deadlines of an assignment. It has methods for setting due dates for an assignment, copying due dates from one assignment to a new assignment etc. DeadlineHelper provides helper functions that help DueDate perform certain tasks. The assignment focuses on refactoring some of the methods based on warnings received from Code Climate's static analysis and modifying the language to make it more Ruby-friendly. The assignment also involves writing unit test cases for due_date.rb and deadline_helper.rb in order to increase test coverage.&lt;br /&gt;
&lt;br /&gt;
The goal of this project is to attempt to make this part of the application easier to read and write unit test cases that the application must pass.&lt;br /&gt;
&lt;br /&gt;
Changed Implementation&lt;br /&gt;
Changes implemented involves refactoring the code and making it more understandable by adding comments in the code.&lt;br /&gt;
&lt;br /&gt;
The modified files are&lt;br /&gt;
&lt;br /&gt;
Due_date.rb (path: /app/models)&lt;br /&gt;
Deadline_helper.rb (path: /app/helpers)&lt;br /&gt;
Testing files&lt;br /&gt;
&lt;br /&gt;
Due_date_spec.rb (path: /spec/models)&lt;br /&gt;
Deadline_helper_spec.rb (path: /spec/helpers)&lt;br /&gt;
Due_date.rb&lt;br /&gt;
Converted for..in loop to object.each in order to follow better Ruby syntax.&lt;br /&gt;
Unnecessary assignment to sorted_deadlines removed.&lt;br /&gt;
Nested ternary operators have been changed to if..else in order to make it more readable.&lt;br /&gt;
&lt;br /&gt;
Due_date.rb&lt;br /&gt;
Changed where(...).first to find_by(...) which is the newer recommended syntax.&lt;br /&gt;
Corrected the Time.now functions by adding the correct zones to them such as Time.zone.now.&lt;br /&gt;
Removed trailing whitespaces.&lt;br /&gt;
&lt;br /&gt;
Deadline_helper.rb&lt;br /&gt;
Time functions were changed to functions with zones&lt;br /&gt;
Extra line removed&lt;br /&gt;
&lt;br /&gt;
Deadline_helper&lt;br /&gt;
RSpec testing&lt;br /&gt;
There were no existing tests for the functions in due_date.rb and deadline_helper.rb. We have added exhaustive set of RSpec tests to test all the code. We have added two new spec files 'due_date_spec.rb' and ‘deadline_helper_spec.rb’ which cover the testing scenarios for the functions in ‘due_date.rb’ and ‘deadline_helper.rb’.&lt;br /&gt;
&lt;br /&gt;
These RSpec files have 100% code coverage visible at: /coverage/index.html&lt;br /&gt;
&lt;br /&gt;
due_date_spec.rb&lt;br /&gt;
This file is located at spec/models and tests the functionalities of the due_date.rb file located in app/models. There are 18 test cases in total which are listed below.&lt;br /&gt;
&lt;br /&gt;
If the factory is successfully able to build the due_date objects.&lt;br /&gt;
it &amp;quot;due date factory created successfully&amp;quot; do&lt;br /&gt;
    expect(@assignment_due_date).to be_valid&lt;br /&gt;
end&lt;br /&gt;
it &amp;quot;due dates created correctly&amp;quot; do&lt;br /&gt;
    expect(@due_dates.length).to be == 10&lt;br /&gt;
end&lt;br /&gt;
If the function &amp;quot;set_flag&amp;quot; successfully sets the due_date flag.&lt;br /&gt;
it &amp;quot;due date flag is set&amp;quot; do&lt;br /&gt;
    expect(@assignment_due_date.flag).to be false&lt;br /&gt;
    @assignment_due_date.set_flag&lt;br /&gt;
    expect(@assignment_due_date.flag).to be true&lt;br /&gt;
end&lt;br /&gt;
If the function &amp;quot;due_at_is_valid_datetime&amp;quot; returns nil (no errors) for a valid datetime in due_at (no invalid test cases can be added here because model does not allow invalid datetime to be set at all).&lt;br /&gt;
it &amp;quot;due at is valid datetime&amp;quot; do&lt;br /&gt;
    expect(@assignment_due_date.due_at_is_valid_datetime).to be nil&lt;br /&gt;
end&lt;br /&gt;
If the function &amp;quot;self.copy&amp;quot; is able to copy due dates from one assignment to another.&lt;br /&gt;
it &amp;quot;copy due dates to new assignment&amp;quot; do&lt;br /&gt;
    new_assignment_id = build(:assignment, id: 999).id&lt;br /&gt;
    old_assignment_id = @assignment_due_date.assignment.id&lt;br /&gt;
    DueDate.copy(old_assignment_id, new_assignment_id)&lt;br /&gt;
    expect(DueDate.where(parent_id: new_assignment_id).count).to eql DueDate.where(parent_id: old_assignment_id).count&lt;br /&gt;
end&lt;br /&gt;
If the function &amp;quot;self.set_duedate&amp;quot; is able to create another due date by copying data from an existing due date object.&lt;br /&gt;
it &amp;quot;create new duedate record with values&amp;quot; do&lt;br /&gt;
    DueDate.set_duedate({id: 999}, @assignment_due_date.deadline_type_id,&lt;br /&gt;
                        @assignment_due_date.parent_id, @assignment_due_date.round)&lt;br /&gt;
    new_due_date = DueDate.find_by(id: 999)&lt;br /&gt;
    expect(new_due_date).to be_valid&lt;br /&gt;
    expect(new_due_date.deadline_type_id).to eql @assignment_due_date.deadline_type_id&lt;br /&gt;
    expect(new_due_date.parent_id).to eql @assignment_due_date.parent_id&lt;br /&gt;
    expect(new_due_date.round).to eql @assignment_due_date.round&lt;br /&gt;
end&lt;br /&gt;
If the function &amp;quot;self.deadline_sort&amp;quot; is able to sort the due dates in ascending order.&lt;br /&gt;
it &amp;quot;sort duedate records&amp;quot; do&lt;br /&gt;
    sorted_due_dates = @due_dates&lt;br /&gt;
    expect(sorted_due_dates.each_cons(2).all?{|m1, m2| (m1.due_at &amp;lt;=&amp;gt; m2.due_at) != 1}).to eql false&lt;br /&gt;
&lt;br /&gt;
    sorted_due_dates = DueDate.deadline_sort(@due_dates)&lt;br /&gt;
    expect(sorted_due_dates.each_cons(2).all?{|m1, m2| (m1.due_at &amp;lt;=&amp;gt; m2.due_at) != 1}).to eql true&lt;br /&gt;
end&lt;br /&gt;
If the function &amp;quot;self.done_in_assignment_round&amp;quot; returns the correct number of rounds for specific inputs. This involves an invalid test case as well for 0 rounds.&lt;br /&gt;
describe &amp;quot;#done_in_assignment_round&amp;quot; do&lt;br /&gt;
    it &amp;quot;return 0 when no response map&amp;quot; do&lt;br /&gt;
      response = ReviewResponseMap.create&lt;br /&gt;
      response.type = &amp;quot;ResponseMap&amp;quot;&lt;br /&gt;
      response.save&lt;br /&gt;
      expect(DueDate.done_in_assignment_round(1, response)).to eql 0&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    it &amp;quot;return round 1 for single round&amp;quot; do&lt;br /&gt;
      response = ReviewResponseMap.create&lt;br /&gt;
      expect(DueDate.done_in_assignment_round(@assignment_due_date.parent_id, response)).to eql 1&lt;br /&gt;
    end&lt;br /&gt;
end&lt;br /&gt;
If the function &amp;quot;self.get_next_due_date&amp;quot; works as expected. This involves several invalid test cases as well.&lt;br /&gt;
describe &amp;quot;#get_next_due_date&amp;quot; do&lt;br /&gt;
    it &amp;quot;no subsequent due date&amp;quot; do&lt;br /&gt;
      expect(DueDate.get_next_due_date(@assignment_due_date.parent_id)).to be nil&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    it &amp;quot;nil value throws exception&amp;quot; do&lt;br /&gt;
      expect { DueDate.get_next_due_date(nil) }.to raise_exception(ActiveRecord::RecordNotFound)&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    it &amp;quot;get next assignment due date&amp;quot; do&lt;br /&gt;
      due_date = create(:assignment_due_date, deadline_type: @deadline_type,&lt;br /&gt;
        submission_allowed_id: @deadline_right.id, review_allowed_id: @deadline_right.id,&lt;br /&gt;
        review_of_review_allowed_id: @deadline_right.id, due_at: Time.zone.now + 5000)&lt;br /&gt;
      expect(DueDate.get_next_due_date(due_date.parent_id)).to be_valid&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    it &amp;quot;get next due date from topic for staggered deadline&amp;quot; do&lt;br /&gt;
      assignment_id = create(:assignment, staggered_deadline: true, name: &amp;quot;testassignment&amp;quot;).id&lt;br /&gt;
      due_date = create(:topic_due_date, deadline_type: @deadline_type,&lt;br /&gt;
        submission_allowed_id: @deadline_right.id, review_allowed_id: @deadline_right.id,&lt;br /&gt;
        review_of_review_allowed_id: @deadline_right.id, due_at: Time.zone.now + 5000, parent_id: assignment_id)&lt;br /&gt;
      expect(DueDate.get_next_due_date(assignment_id, due_date.parent_id)).to be_valid&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    it &amp;quot;next due date does not exist for staggered deadline&amp;quot; do&lt;br /&gt;
      assignment_id = create(:assignment, staggered_deadline: true, name: &amp;quot;testassignment&amp;quot;).id&lt;br /&gt;
      due_date = create(:topic_due_date, deadline_type: @deadline_type,&lt;br /&gt;
        submission_allowed_id: @deadline_right, review_allowed_id: @deadline_right,&lt;br /&gt;
        review_of_review_allowed_id: @deadline_right, due_at: Time.zone.now + 5000, parent_id: assignment_id)&lt;br /&gt;
      expect(DueDate.get_next_due_date(assignment_id)).to be nil&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    it &amp;quot;next due date is before Time.now for staggered deadline&amp;quot; do&lt;br /&gt;
      assignment_id = create(:assignment, staggered_deadline: true, name: &amp;quot;testassignment&amp;quot;).id&lt;br /&gt;
      due_date = create(:topic_due_date, deadline_type: @deadline_type,&lt;br /&gt;
        submission_allowed_id: @deadline_right, review_allowed_id: @deadline_right,&lt;br /&gt;
        review_of_review_allowed_id: @deadline_right, due_at: Time.zone.now - 5000, parent_id: assignment_id)&lt;br /&gt;
      expect(DueDate.get_next_due_date(assignment_id, due_date.parent_id)).to be nil&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    it &amp;quot;get next due date from assignment for staggered deadline&amp;quot; do&lt;br /&gt;
      assignment_id = create(:assignment, staggered_deadline: true, name: &amp;quot;testassignment&amp;quot;).id&lt;br /&gt;
      due_date = create(:assignment_due_date, deadline_type: @deadline_type,&lt;br /&gt;
        submission_allowed_id: @deadline_right, review_allowed_id: @deadline_right,&lt;br /&gt;
        review_of_review_allowed_id: @deadline_right, due_at: Time.zone.now + 5000, parent_id: assignment_id)&lt;br /&gt;
      expect(DueDate.get_next_due_date(assignment_id)).to be_valid&lt;br /&gt;
    end&lt;br /&gt;
end&lt;br /&gt;
If the function &amp;quot;self.default_permission&amp;quot; returns the correct default permissions for particular deadline and permission types.&lt;br /&gt;
it &amp;quot;metareview review_of_review_allowed default permission OK&amp;quot; do&lt;br /&gt;
    expect(DueDate.default_permission('metareview', 'review_of_review_allowed')).to be == DeadlineRight::OK&lt;br /&gt;
end&lt;br /&gt;
it &amp;quot;review submission_allowed default permission NO&amp;quot; do&lt;br /&gt;
    expect(DueDate.default_permission('review', 'submission_allowed')).to be == DeadlineRight::NO&lt;br /&gt;
end&lt;br /&gt;
To test this file run the following command:&lt;br /&gt;
&lt;br /&gt;
rspec spec/models/due_date_spec.rb&lt;br /&gt;
The output of this RSpec file is present in below screenshot:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Code coverage details of the above RSpec files is present in below screenshot:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Code coverage details of the above RSpec files is present in below screenshot:&lt;br /&gt;
&lt;br /&gt;
deadline_helper_spec.rb&lt;br /&gt;
This is a test file for testing the functionalities of Deadline_helper.rb file located at app/helpers. Different test cases present in this file are:&lt;br /&gt;
&lt;br /&gt;
Check if the factory is valid:&lt;br /&gt;
it &amp;quot;has a valid factory&amp;quot; do&lt;br /&gt;
    factory = FactoryGirl.build(:topic_due_date)&lt;br /&gt;
    expect(factory).to be_valid&lt;br /&gt;
end&lt;br /&gt;
Fail if the due date is invalid:&lt;br /&gt;
it &amp;quot;should fail because of invalid due_date&amp;quot; do&lt;br /&gt;
      expect { DeadlineHelper.create_topic_deadline(nil, 0, 0)}.to raise_exception(NoMethodError)&lt;br /&gt;
end&lt;br /&gt;
If new due_date object is created:&lt;br /&gt;
it &amp;quot;new due_date object created&amp;quot; do&lt;br /&gt;
      DeadlineHelper.create_topic_deadline(@topic_due_date, 0, 1)&lt;br /&gt;
      expect(TopicDueDate.count).to be == 2&lt;br /&gt;
end&lt;br /&gt;
due_at should be same for 0 offset:&lt;br /&gt;
 it &amp;quot;due_at should be same for 0 offset&amp;quot; do&lt;br /&gt;
      DeadlineHelper.create_topic_deadline(@topic_due_date, 0, 10)&lt;br /&gt;
      new_due_date = TopicDueDate.find_by(parent_id: 10)&lt;br /&gt;
      expect(new_due_date).to be_valid&lt;br /&gt;
      expect(new_due_date.due_at.to_s).to be == @topic_due_date.due_at.to_s&lt;br /&gt;
end&lt;br /&gt;
due_at is calculated correctly if offset is positive:&lt;br /&gt;
it &amp;quot;due_at calculated correctly for positive offset&amp;quot; do&lt;br /&gt;
      DeadlineHelper.create_topic_deadline(@topic_due_date, 5000, 10)&lt;br /&gt;
      new_due_date = TopicDueDate.find_by(parent_id: 10)&lt;br /&gt;
      expect(new_due_date).to be_valid&lt;br /&gt;
      expect(new_due_date.due_at.to_s).to be == (Time.zone.parse(@topic_due_date.due_at.to_s) + 5000).to_s&lt;br /&gt;
end&lt;br /&gt;
due_at is calculated correctly if offset is negative:&lt;br /&gt;
it &amp;quot;due_at calculated correctly for negative offset&amp;quot; do&lt;br /&gt;
      DeadlineHelper.create_topic_deadline(@topic_due_date, -5000, 10)&lt;br /&gt;
      new_due_date = TopicDueDate.find_by(parent_id: 10)&lt;br /&gt;
      expect(new_due_date).to be_valid&lt;br /&gt;
      expect(new_due_date.due_at.to_s).to be == (Time.zone.parse(@topic_due_date.due_at.to_s) - 5000).to_s&lt;br /&gt;
end&lt;br /&gt;
The offset is being converted to integer properly:&lt;br /&gt;
it &amp;quot;offset converted to integer correctly&amp;quot; do&lt;br /&gt;
      DeadlineHelper.create_topic_deadline(@topic_due_date, 5000.15, 10)&lt;br /&gt;
      new_due_date = TopicDueDate.find_by(parent_id: 10)&lt;br /&gt;
      expect(new_due_date).to be_valid&lt;br /&gt;
      expect(new_due_date.due_at.to_s).to be == (Time.zone.parse(@topic_due_date.due_at.to_s) + 5000).to_s&lt;br /&gt;
end&lt;br /&gt;
To test this file run the following command:&lt;br /&gt;
&lt;br /&gt;
rspec spec/models/deadline_helper_spec.rb&lt;br /&gt;
The output of this RSpec file is present in below screenshot:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Code coverage details of the above RSpec files is present in below screenshot:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
References&lt;br /&gt;
&amp;quot;Log in to your Code Climate dashboard with GitHub or your email.&amp;quot;. codeclimate.com. Retrieved 2016-10-28.&lt;/div&gt;</summary>
		<author><name>Nthanik</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2016/E1634.Refactor_and_write_unit_test_of_due_date.rb_and_deadline_helper.rb&amp;diff=102934</id>
		<title>CSC/ECE 517 Fall 2016/E1634.Refactor and write unit test of due date.rb and deadline helper.rb</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2016/E1634.Refactor_and_write_unit_test_of_due_date.rb_and_deadline_helper.rb&amp;diff=102934"/>
		<updated>2016-10-28T20:36:18Z</updated>

		<summary type="html">&lt;p&gt;Nthanik: Created page with &amp;quot;Introduction Expertiza Expertiza is an open source project for school assignment management for instructors and students based on the Ruby on Rails framework. Expertiza allows th...&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Introduction&lt;br /&gt;
Expertiza&lt;br /&gt;
Expertiza is an open source project for school assignment management for instructors and students based on the Ruby on Rails framework. Expertiza allows the instructor to create new assignments and customise new or existing assignments. It also allows the instructor to create a list of topics the students can sign up for. Students can form teams in Expertiza to work on various projects and assignments. Students can also peer review other students' submissions. Expertiza supports submission across various document types, including the URLs and word documents. Expertiza provides a dashboard for all the assignments corresponding to a course and provides absolute control to the Instructors and Teaching Assistants. In addition to assignments, it encompasses peer reviews wherein participants are allowed to provide feedback anonymously about each other's work thereby providing scope for the better outcome. The due_date.rb file is responsible for informing the users about the deadline for submission of the each assignment. Due dates in Expertiza have their association with many other components like assignments, reviews etc.&lt;br /&gt;
&lt;br /&gt;
Code Climate&lt;br /&gt;
Code Climate[1] is a tool that runs static analysis on a GitHub project and outputs many details like test coverage, complexity, duplication, security, style, and more. There is a Google Chrome extension to integrate the Code Climate results generated directly into GitHub which is visible when browsing the repository on the browser. It allows us to see issues displayed directly inside GitHub's UI, to review which lines are covered in diffs and files, and add repositories and open tickets without changing your workflow.&lt;br /&gt;
&lt;br /&gt;
Tasks Identified&lt;br /&gt;
To install Code climate Chrome Extension that highlights the duplicated code.&lt;br /&gt;
&lt;br /&gt;
To refactor the following two files:&lt;br /&gt;
&lt;br /&gt;
Due_date.rb&lt;br /&gt;
Ternary operators must not be nested. Prefer `if` or `else` constructs instead.&lt;br /&gt;
Useless assignment to variable - `sorted_deadlines`.&lt;br /&gt;
Prefer `each` over `for`.&lt;br /&gt;
Use `find_by` instead of `where.first`.&lt;br /&gt;
Correct the use of Time function&lt;br /&gt;
Deadline_helper.rb&lt;br /&gt;
Do not use `Time.now` without zone. Use one of `Time.zone.now`, `Time.current`, `Time.now.in_time_zone`, `Time.now.utc`, `Time.now.getlocal`, `Time.now.iso8601`, `Time.now.jisx0301`, `Time.now.rfc3339`, `Time.now.to_i`, `Time.now.to_f` instead.&lt;br /&gt;
Trailing whitespace detected.&lt;br /&gt;
Extra empty line detected at module body end.&lt;br /&gt;
Create respective RSpec files in /spec/models/ and /spec/helper folder and write unit tests for each method in due_date.rb and deadline_helper.rb.&lt;br /&gt;
Current Implementation&lt;br /&gt;
DueDate is a Model class to manage the deadlines of an assignment. It has methods for setting due dates for an assignment, copying due dates from one assignment to a new assignment etc. DeadlineHelper provides helper functions that help DueDate perform certain tasks. The assignment focuses on refactoring some of the methods based on warnings received from Code Climate's static analysis and modifying the language to make it more Ruby-friendly. The assignment also involves writing unit test cases for due_date.rb and deadline_helper.rb in order to increase test coverage.&lt;br /&gt;
&lt;br /&gt;
The goal of this project is to attempt to make this part of the application easier to read and write unit test cases that the application must pass.&lt;br /&gt;
&lt;br /&gt;
Changed Implementation&lt;br /&gt;
Changes implemented involves refactoring the code and making it more understandable by adding comments in the code.&lt;br /&gt;
&lt;br /&gt;
The modified files are&lt;br /&gt;
&lt;br /&gt;
Due_date.rb (path: /app/models)&lt;br /&gt;
Deadline_helper.rb (path: /app/helpers)&lt;br /&gt;
Testing files&lt;br /&gt;
&lt;br /&gt;
Due_date_spec.rb (path: /spec/models)&lt;br /&gt;
Deadline_helper_spec.rb (path: /spec/helpers)&lt;br /&gt;
Due_date.rb&lt;br /&gt;
Converted for..in loop to object.each in order to follow better Ruby syntax.&lt;br /&gt;
Unnecessary assignment to sorted_deadlines removed.&lt;br /&gt;
Nested ternary operators have been changed to if..else in order to make it more readable.&lt;br /&gt;
&lt;br /&gt;
Due_date.rb&lt;br /&gt;
Changed where(...).first to find_by(...) which is the newer recommended syntax.&lt;br /&gt;
Corrected the Time.now functions by adding the correct zones to them such as Time.zone.now.&lt;br /&gt;
Removed trailing whitespaces.&lt;br /&gt;
&lt;br /&gt;
Deadline_helper.rb&lt;br /&gt;
Time functions were changed to functions with zones&lt;br /&gt;
Extra line removed&lt;br /&gt;
&lt;br /&gt;
Deadline_helper&lt;br /&gt;
RSpec testing&lt;br /&gt;
There were no existing tests for the functions in due_date.rb and deadline_helper.rb. We have added exhaustive set of RSpec tests to test all the code. We have added two new spec files 'due_date_spec.rb' and ‘deadline_helper_spec.rb’ which cover the testing scenarios for the functions in ‘due_date.rb’ and ‘deadline_helper.rb’.&lt;br /&gt;
&lt;br /&gt;
These RSpec files have 100% code coverage visible at: /coverage/index.html&lt;br /&gt;
&lt;br /&gt;
due_date_spec.rb&lt;br /&gt;
This file is located at spec/models and tests the functionalities of the due_date.rb file located in app/models. There are 18 test cases in total which are listed below.&lt;br /&gt;
&lt;br /&gt;
If the factory is successfully able to build the due_date objects.&lt;br /&gt;
it &amp;quot;due date factory created successfully&amp;quot; do&lt;br /&gt;
    expect(@assignment_due_date).to be_valid&lt;br /&gt;
end&lt;br /&gt;
it &amp;quot;due dates created correctly&amp;quot; do&lt;br /&gt;
    expect(@due_dates.length).to be == 10&lt;br /&gt;
end&lt;br /&gt;
If the function &amp;quot;set_flag&amp;quot; successfully sets the due_date flag.&lt;br /&gt;
it &amp;quot;due date flag is set&amp;quot; do&lt;br /&gt;
    expect(@assignment_due_date.flag).to be false&lt;br /&gt;
    @assignment_due_date.set_flag&lt;br /&gt;
    expect(@assignment_due_date.flag).to be true&lt;br /&gt;
end&lt;br /&gt;
If the function &amp;quot;due_at_is_valid_datetime&amp;quot; returns nil (no errors) for a valid datetime in due_at (no invalid test cases can be added here because model does not allow invalid datetime to be set at all).&lt;br /&gt;
it &amp;quot;due at is valid datetime&amp;quot; do&lt;br /&gt;
    expect(@assignment_due_date.due_at_is_valid_datetime).to be nil&lt;br /&gt;
end&lt;br /&gt;
If the function &amp;quot;self.copy&amp;quot; is able to copy due dates from one assignment to another.&lt;br /&gt;
it &amp;quot;copy due dates to new assignment&amp;quot; do&lt;br /&gt;
    new_assignment_id = build(:assignment, id: 999).id&lt;br /&gt;
    old_assignment_id = @assignment_due_date.assignment.id&lt;br /&gt;
    DueDate.copy(old_assignment_id, new_assignment_id)&lt;br /&gt;
    expect(DueDate.where(parent_id: new_assignment_id).count).to eql DueDate.where(parent_id: old_assignment_id).count&lt;br /&gt;
end&lt;br /&gt;
If the function &amp;quot;self.set_duedate&amp;quot; is able to create another due date by copying data from an existing due date object.&lt;br /&gt;
it &amp;quot;create new duedate record with values&amp;quot; do&lt;br /&gt;
    DueDate.set_duedate({id: 999}, @assignment_due_date.deadline_type_id,&lt;br /&gt;
                        @assignment_due_date.parent_id, @assignment_due_date.round)&lt;br /&gt;
    new_due_date = DueDate.find_by(id: 999)&lt;br /&gt;
    expect(new_due_date).to be_valid&lt;br /&gt;
    expect(new_due_date.deadline_type_id).to eql @assignment_due_date.deadline_type_id&lt;br /&gt;
    expect(new_due_date.parent_id).to eql @assignment_due_date.parent_id&lt;br /&gt;
    expect(new_due_date.round).to eql @assignment_due_date.round&lt;br /&gt;
end&lt;br /&gt;
If the function &amp;quot;self.deadline_sort&amp;quot; is able to sort the due dates in ascending order.&lt;br /&gt;
it &amp;quot;sort duedate records&amp;quot; do&lt;br /&gt;
    sorted_due_dates = @due_dates&lt;br /&gt;
    expect(sorted_due_dates.each_cons(2).all?{|m1, m2| (m1.due_at &amp;lt;=&amp;gt; m2.due_at) != 1}).to eql false&lt;br /&gt;
&lt;br /&gt;
    sorted_due_dates = DueDate.deadline_sort(@due_dates)&lt;br /&gt;
    expect(sorted_due_dates.each_cons(2).all?{|m1, m2| (m1.due_at &amp;lt;=&amp;gt; m2.due_at) != 1}).to eql true&lt;br /&gt;
end&lt;br /&gt;
If the function &amp;quot;self.done_in_assignment_round&amp;quot; returns the correct number of rounds for specific inputs. This involves an invalid test case as well for 0 rounds.&lt;br /&gt;
describe &amp;quot;#done_in_assignment_round&amp;quot; do&lt;br /&gt;
    it &amp;quot;return 0 when no response map&amp;quot; do&lt;br /&gt;
      response = ReviewResponseMap.create&lt;br /&gt;
      response.type = &amp;quot;ResponseMap&amp;quot;&lt;br /&gt;
      response.save&lt;br /&gt;
      expect(DueDate.done_in_assignment_round(1, response)).to eql 0&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    it &amp;quot;return round 1 for single round&amp;quot; do&lt;br /&gt;
      response = ReviewResponseMap.create&lt;br /&gt;
      expect(DueDate.done_in_assignment_round(@assignment_due_date.parent_id, response)).to eql 1&lt;br /&gt;
    end&lt;br /&gt;
end&lt;br /&gt;
If the function &amp;quot;self.get_next_due_date&amp;quot; works as expected. This involves several invalid test cases as well.&lt;br /&gt;
describe &amp;quot;#get_next_due_date&amp;quot; do&lt;br /&gt;
    it &amp;quot;no subsequent due date&amp;quot; do&lt;br /&gt;
      expect(DueDate.get_next_due_date(@assignment_due_date.parent_id)).to be nil&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    it &amp;quot;nil value throws exception&amp;quot; do&lt;br /&gt;
      expect { DueDate.get_next_due_date(nil) }.to raise_exception(ActiveRecord::RecordNotFound)&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    it &amp;quot;get next assignment due date&amp;quot; do&lt;br /&gt;
      due_date = create(:assignment_due_date, deadline_type: @deadline_type,&lt;br /&gt;
        submission_allowed_id: @deadline_right.id, review_allowed_id: @deadline_right.id,&lt;br /&gt;
        review_of_review_allowed_id: @deadline_right.id, due_at: Time.zone.now + 5000)&lt;br /&gt;
      expect(DueDate.get_next_due_date(due_date.parent_id)).to be_valid&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    it &amp;quot;get next due date from topic for staggered deadline&amp;quot; do&lt;br /&gt;
      assignment_id = create(:assignment, staggered_deadline: true, name: &amp;quot;testassignment&amp;quot;).id&lt;br /&gt;
      due_date = create(:topic_due_date, deadline_type: @deadline_type,&lt;br /&gt;
        submission_allowed_id: @deadline_right.id, review_allowed_id: @deadline_right.id,&lt;br /&gt;
        review_of_review_allowed_id: @deadline_right.id, due_at: Time.zone.now + 5000, parent_id: assignment_id)&lt;br /&gt;
      expect(DueDate.get_next_due_date(assignment_id, due_date.parent_id)).to be_valid&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    it &amp;quot;next due date does not exist for staggered deadline&amp;quot; do&lt;br /&gt;
      assignment_id = create(:assignment, staggered_deadline: true, name: &amp;quot;testassignment&amp;quot;).id&lt;br /&gt;
      due_date = create(:topic_due_date, deadline_type: @deadline_type,&lt;br /&gt;
        submission_allowed_id: @deadline_right, review_allowed_id: @deadline_right,&lt;br /&gt;
        review_of_review_allowed_id: @deadline_right, due_at: Time.zone.now + 5000, parent_id: assignment_id)&lt;br /&gt;
      expect(DueDate.get_next_due_date(assignment_id)).to be nil&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    it &amp;quot;next due date is before Time.now for staggered deadline&amp;quot; do&lt;br /&gt;
      assignment_id = create(:assignment, staggered_deadline: true, name: &amp;quot;testassignment&amp;quot;).id&lt;br /&gt;
      due_date = create(:topic_due_date, deadline_type: @deadline_type,&lt;br /&gt;
        submission_allowed_id: @deadline_right, review_allowed_id: @deadline_right,&lt;br /&gt;
        review_of_review_allowed_id: @deadline_right, due_at: Time.zone.now - 5000, parent_id: assignment_id)&lt;br /&gt;
      expect(DueDate.get_next_due_date(assignment_id, due_date.parent_id)).to be nil&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    it &amp;quot;get next due date from assignment for staggered deadline&amp;quot; do&lt;br /&gt;
      assignment_id = create(:assignment, staggered_deadline: true, name: &amp;quot;testassignment&amp;quot;).id&lt;br /&gt;
      due_date = create(:assignment_due_date, deadline_type: @deadline_type,&lt;br /&gt;
        submission_allowed_id: @deadline_right, review_allowed_id: @deadline_right,&lt;br /&gt;
        review_of_review_allowed_id: @deadline_right, due_at: Time.zone.now + 5000, parent_id: assignment_id)&lt;br /&gt;
      expect(DueDate.get_next_due_date(assignment_id)).to be_valid&lt;br /&gt;
    end&lt;br /&gt;
end&lt;br /&gt;
If the function &amp;quot;self.default_permission&amp;quot; returns the correct default permissions for particular deadline and permission types.&lt;br /&gt;
it &amp;quot;metareview review_of_review_allowed default permission OK&amp;quot; do&lt;br /&gt;
    expect(DueDate.default_permission('metareview', 'review_of_review_allowed')).to be == DeadlineRight::OK&lt;br /&gt;
end&lt;br /&gt;
it &amp;quot;review submission_allowed default permission NO&amp;quot; do&lt;br /&gt;
    expect(DueDate.default_permission('review', 'submission_allowed')).to be == DeadlineRight::NO&lt;br /&gt;
end&lt;br /&gt;
To test this file run the following command:&lt;br /&gt;
&lt;br /&gt;
rspec spec/models/due_date_spec.rb&lt;br /&gt;
The output of this RSpec file is present in below screenshot:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Code coverage details of the above RSpec files is present in below screenshot:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Code coverage details of the above RSpec files is present in below screenshot:&lt;br /&gt;
&lt;br /&gt;
deadline_helper_spec.rb&lt;br /&gt;
This is a test file for testing the functionalities of Deadline_helper.rb file located at app/helpers. Different test cases present in this file are:&lt;br /&gt;
&lt;br /&gt;
Check if the factory is valid:&lt;br /&gt;
it &amp;quot;has a valid factory&amp;quot; do&lt;br /&gt;
    factory = FactoryGirl.build(:topic_due_date)&lt;br /&gt;
    expect(factory).to be_valid&lt;br /&gt;
end&lt;br /&gt;
Fail if the due date is invalid:&lt;br /&gt;
it &amp;quot;should fail because of invalid due_date&amp;quot; do&lt;br /&gt;
      expect { DeadlineHelper.create_topic_deadline(nil, 0, 0)}.to raise_exception(NoMethodError)&lt;br /&gt;
end&lt;br /&gt;
If new due_date object is created:&lt;br /&gt;
it &amp;quot;new due_date object created&amp;quot; do&lt;br /&gt;
      DeadlineHelper.create_topic_deadline(@topic_due_date, 0, 1)&lt;br /&gt;
      expect(TopicDueDate.count).to be == 2&lt;br /&gt;
end&lt;br /&gt;
due_at should be same for 0 offset:&lt;br /&gt;
 it &amp;quot;due_at should be same for 0 offset&amp;quot; do&lt;br /&gt;
      DeadlineHelper.create_topic_deadline(@topic_due_date, 0, 10)&lt;br /&gt;
      new_due_date = TopicDueDate.find_by(parent_id: 10)&lt;br /&gt;
      expect(new_due_date).to be_valid&lt;br /&gt;
      expect(new_due_date.due_at.to_s).to be == @topic_due_date.due_at.to_s&lt;br /&gt;
end&lt;br /&gt;
due_at is calculated correctly if offset is positive:&lt;br /&gt;
it &amp;quot;due_at calculated correctly for positive offset&amp;quot; do&lt;br /&gt;
      DeadlineHelper.create_topic_deadline(@topic_due_date, 5000, 10)&lt;br /&gt;
      new_due_date = TopicDueDate.find_by(parent_id: 10)&lt;br /&gt;
      expect(new_due_date).to be_valid&lt;br /&gt;
      expect(new_due_date.due_at.to_s).to be == (Time.zone.parse(@topic_due_date.due_at.to_s) + 5000).to_s&lt;br /&gt;
end&lt;br /&gt;
due_at is calculated correctly if offset is negative:&lt;br /&gt;
it &amp;quot;due_at calculated correctly for negative offset&amp;quot; do&lt;br /&gt;
      DeadlineHelper.create_topic_deadline(@topic_due_date, -5000, 10)&lt;br /&gt;
      new_due_date = TopicDueDate.find_by(parent_id: 10)&lt;br /&gt;
      expect(new_due_date).to be_valid&lt;br /&gt;
      expect(new_due_date.due_at.to_s).to be == (Time.zone.parse(@topic_due_date.due_at.to_s) - 5000).to_s&lt;br /&gt;
end&lt;br /&gt;
The offset is being converted to integer properly:&lt;br /&gt;
it &amp;quot;offset converted to integer correctly&amp;quot; do&lt;br /&gt;
      DeadlineHelper.create_topic_deadline(@topic_due_date, 5000.15, 10)&lt;br /&gt;
      new_due_date = TopicDueDate.find_by(parent_id: 10)&lt;br /&gt;
      expect(new_due_date).to be_valid&lt;br /&gt;
      expect(new_due_date.due_at.to_s).to be == (Time.zone.parse(@topic_due_date.due_at.to_s) + 5000).to_s&lt;br /&gt;
end&lt;br /&gt;
To test this file run the following command:&lt;br /&gt;
&lt;br /&gt;
rspec spec/models/deadline_helper_spec.rb&lt;br /&gt;
The output of this RSpec file is present in below screenshot:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Code coverage details of the above RSpec files is present in below screenshot:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
References&lt;br /&gt;
&amp;quot;Log in to your Code Climate dashboard with GitHub or your email.&amp;quot;. codeclimate.com. Retrieved 2016-10-28.&lt;/div&gt;</summary>
		<author><name>Nthanik</name></author>
	</entry>
</feed>