<?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=Agcarrut</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=Agcarrut"/>
	<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=Special:Contributions/Agcarrut"/>
	<updated>2026-09-28T16:45:35Z</updated>
	<subtitle>User contributions</subtitle>
	<generator>MediaWiki 1.41.0</generator>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=File:E2170-assessments_for.png&amp;diff=141318</id>
		<title>File:E2170-assessments for.png</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=File:E2170-assessments_for.png&amp;diff=141318"/>
		<updated>2021-11-08T23:13:04Z</updated>

		<summary type="html">&lt;p&gt;Agcarrut: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Agcarrut</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2021_-_E2170._Testing_-_Response_Maps&amp;diff=141317</id>
		<title>CSC/ECE 517 Fall 2021 - E2170. Testing - Response Maps</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2021_-_E2170._Testing_-_Response_Maps&amp;diff=141317"/>
		<updated>2021-11-08T23:12:15Z</updated>

		<summary type="html">&lt;p&gt;Agcarrut: /* self.assessments_for(team) */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
== Description about project ==&lt;br /&gt;
This page is a description of Expertiza OSS project E2170 which aims to adequately test several files regarding the ResponseMap model. Here is a description of what response maps do:&lt;br /&gt;
*In Expertiza, response maps establish a relationship between a reviewer, a reviewee, and an object to be reviewed.  The reviewer is an assignment_participant, the reviewee is an assignment_team, and the reviewed object is either an assignment or another response_map. Each (reviewer, reviewee) pair will have a separate response map. Every time a new review is performed (e.g, every round), a new Response object is created whose map_id is that response map.&lt;br /&gt;
&lt;br /&gt;
The breakdown of the ResponseMap model can be found [https://expertiza.csc.ncsu.edu/index.php/Response_maps here]. There are several types of ResponseMaps that extend functionality of the original ResponseMap. None of which including the superclass are adequately tested. These files include:&lt;br /&gt;
&lt;br /&gt;
* review_response_map.rb  &amp;lt;--------- 92.5% coverage&lt;br /&gt;
&lt;br /&gt;
* metareview_response_map.rb &amp;lt;------ 23.08% coverage&lt;br /&gt;
&lt;br /&gt;
* teammate_review_response_map.rb &amp;lt;- no coverage&lt;br /&gt;
&lt;br /&gt;
* response_map.rb &amp;lt;----------------- 74.47% coverage&lt;br /&gt;
&lt;br /&gt;
This project aims to get all the response maps to at least a 90% level of coverage for every Response Map file by writing unit tests for each uncovered method listed in the next section.&lt;br /&gt;
&lt;br /&gt;
== Team ==&lt;br /&gt;
&lt;br /&gt;
* Connor Smith (cpsmith6)&lt;br /&gt;
&lt;br /&gt;
* Abir Majumder (aamajumd)&lt;br /&gt;
&lt;br /&gt;
* Quinn Dibble (qdibble)&lt;br /&gt;
&lt;br /&gt;
* Alex Carruth (agcarrut)&lt;br /&gt;
&lt;br /&gt;
== Test Files Involved ==&lt;br /&gt;
There are 4 test files involved in this project:&lt;br /&gt;
* review_response_map_spec.rb&lt;br /&gt;
&lt;br /&gt;
* metareview_response_map_spec.rb&lt;br /&gt;
&lt;br /&gt;
* teammate_review_response_map_spec.rb&lt;br /&gt;
&lt;br /&gt;
* response_map_spec.rb&lt;br /&gt;
of these files, only review_response_map_spec.rb currently exists; the rest will be added.&lt;br /&gt;
&lt;br /&gt;
== Methods Tested Per File ==&lt;br /&gt;
&lt;br /&gt;
=== review_response_map_spec.rb ===&lt;br /&gt;
Currently this file is 92.5% covered and there are no plans to cover it further.&lt;br /&gt;
&lt;br /&gt;
=== metareview_response_map_spec.rb ===&lt;br /&gt;
The functions for metareview_response_map.rb that will be tested are:&lt;br /&gt;
====get_all_versions====&lt;br /&gt;
This returns a sorted array of all the different versions of what is being reviewed in this response map. This means for a test, we will need to create a reviewer, a reviewee, several types of reviews of different versions to be sorted correctly.&lt;br /&gt;
&lt;br /&gt;
[[File:E2170-get all versions.PNG]]&lt;br /&gt;
&lt;br /&gt;
====contributor====&lt;br /&gt;
Returns the team associated with the ReviewResponseMap that is to be metareviewed. We will need to create a ReviewResponseMap that has a team associated with it. Then we must create MetareviewResponseMap that points to a created ReviewResponseMap via the reviewed_object_id attribute. We will test if it indeed returns the team associated with ReviewResponseMap.&lt;br /&gt;
&lt;br /&gt;
[[File:E2170-contributor.PNG]]&lt;br /&gt;
&lt;br /&gt;
====questionnaire====&lt;br /&gt;
Returns all questionnaires associated to the assignment of this MetareviewResponseMap that is of type 'MetareviewQuestionnaire'. We will need to create a valid MetareviewResponseMap including at least one MetareviewQuestionnaire that can be returned.&lt;br /&gt;
&lt;br /&gt;
[[File:E2170-questionnaire.PNG]]&lt;br /&gt;
&lt;br /&gt;
====get_title====&lt;br /&gt;
Returns string &amp;quot;Metareview&amp;quot;. We will test if this string is the same as typed out.&lt;br /&gt;
&lt;br /&gt;
[[File:E2170-get title.PNG]]&lt;br /&gt;
&lt;br /&gt;
====exports====&lt;br /&gt;
This function takes 3 parameters: csv (the csv file that will contain the exported metareview information), parent_id (the assignment ID containing the requested metareviews), and _options. The function sends all the information about the metareviews to a csv file. We will test that the information is properly exported to the csv file.&amp;lt;br&amp;gt;&lt;br /&gt;
[[File:E2170-export.jpg]]&lt;br /&gt;
&lt;br /&gt;
====export_fields====&lt;br /&gt;
Takes a parameter called &amp;quot;_options&amp;quot; that returns the three field columns associated with metareviews to be exported for use by other controllers. We will test to see that these three columns are properly returned.&amp;lt;br&amp;gt;&lt;br /&gt;
[[File:E2170-export_fields.jpg]]&lt;br /&gt;
&lt;br /&gt;
====import====&lt;br /&gt;
This function takes 3 parameters: row_hash (represents the hash of the metareview data we want to import), session, and id (representing the id of the assignment we want to import metareview data for). The function imports the data from the hash map, and if the information is input correctly, the data is extracted from the hash and creates a metareview for the requested assignment, otherwise it flashes an error saying the data was input incorrectly. We will test to make sure the imported data is properly converted into a metareview.&amp;lt;br&amp;gt;&lt;br /&gt;
[[File:E2170-import.jpg]]&lt;br /&gt;
&lt;br /&gt;
====email====&lt;br /&gt;
This function takes 3 parameters: defn, _participant (the user who will be receiving the email), and assignment (the assignment associated with the metareview). The function sends an email to the participant when they have a new metareview to complete. We will test to make sure the email is sent to the correct participant.&amp;lt;br&amp;gt;&lt;br /&gt;
[[File:E2170-email.jpg]]&lt;br /&gt;
&lt;br /&gt;
=== teammate_review_response_map_spec.rb ===&lt;br /&gt;
The functions for teammate_review_response_map.rb that will be tested are:&lt;br /&gt;
==== questionnaire ====&lt;br /&gt;
This function searches for a TeammateReviewQuestionnaire object and returns it.&lt;br /&gt;
&lt;br /&gt;
[[File:E2170-teammate review response map-questionnaire.PNG]]&lt;br /&gt;
&lt;br /&gt;
==== get_title ====&lt;br /&gt;
This function returns the string &amp;quot;Teammate Review&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
[[File:E2170-teammate_review_response_map-get_title.png]]&lt;br /&gt;
&lt;br /&gt;
==== teammate_response_report ====&lt;br /&gt;
This function returns the teammate response report given the reviewer ID.&lt;br /&gt;
&lt;br /&gt;
[[File:E2170-teammate_review_response_map-teammate_response_report.PNG]]&lt;br /&gt;
&lt;br /&gt;
==== email ====&lt;br /&gt;
This function sends a notification email to a student who has been reviewed by their teammate.&lt;br /&gt;
&lt;br /&gt;
[[File:E2170-teammate_review_response_map-email.png]]&lt;br /&gt;
&lt;br /&gt;
=== response_map_spec.rb ===&lt;br /&gt;
The functions for response_map.rb that will be tested are:&lt;br /&gt;
==== self.assessments_for(team) ====&lt;br /&gt;
Gets all submitted Review Responses or all regular Responses for a team, sorts the responses by version, and returns the latest Responses.&lt;br /&gt;
&lt;br /&gt;
[[File:E2170-assessments_for.png]]&lt;br /&gt;
&lt;br /&gt;
==== comparator ====&lt;br /&gt;
Compares two Responses version numbers and returns a -1,0, or 1 depending on which version number is greater. If there is no version number for the first response, -1 is returned, otherwise 1 is returned.&lt;br /&gt;
&lt;br /&gt;
[[File:E2170-comparator.png]]&lt;br /&gt;
&lt;br /&gt;
==== self.reviewer_assessments_for(team, reviewer) ====&lt;br /&gt;
Gets the Responses for a team reviewed by a specific reviewer and returns the latest response.&lt;br /&gt;
&lt;br /&gt;
[[File:E2170-reviewer_assessments_for.png]]&lt;br /&gt;
&lt;br /&gt;
==== metareviewed_by? ====&lt;br /&gt;
Returns whether the Response Map has been metareviewed&lt;br /&gt;
&lt;br /&gt;
[[File:E2170-metareviewed_by.png]]&lt;br /&gt;
&lt;br /&gt;
==== assign_metareviewer ====&lt;br /&gt;
This function is in charge of assigning a metareviewer to this review (i.e. a reviewer to review the review).&lt;br /&gt;
&lt;br /&gt;
[[File:E2170-response_map-assign_metareviewer.png]]&lt;br /&gt;
&lt;br /&gt;
==== find_team_member ====&lt;br /&gt;
This function returns the team that the reviewer is part of.&lt;br /&gt;
&lt;br /&gt;
[[File:E2170-response_map-find_team_member.png]]&lt;br /&gt;
&lt;br /&gt;
== Running Tests ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  rspec ./spec/controllers/&amp;lt;test file name&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;/div&gt;</summary>
		<author><name>Agcarrut</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2021_-_E2170._Testing_-_Response_Maps&amp;diff=141316</id>
		<title>CSC/ECE 517 Fall 2021 - E2170. Testing - Response Maps</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2021_-_E2170._Testing_-_Response_Maps&amp;diff=141316"/>
		<updated>2021-11-08T23:12:01Z</updated>

		<summary type="html">&lt;p&gt;Agcarrut: /* response_map_spec.rb */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
== Description about project ==&lt;br /&gt;
This page is a description of Expertiza OSS project E2170 which aims to adequately test several files regarding the ResponseMap model. Here is a description of what response maps do:&lt;br /&gt;
*In Expertiza, response maps establish a relationship between a reviewer, a reviewee, and an object to be reviewed.  The reviewer is an assignment_participant, the reviewee is an assignment_team, and the reviewed object is either an assignment or another response_map. Each (reviewer, reviewee) pair will have a separate response map. Every time a new review is performed (e.g, every round), a new Response object is created whose map_id is that response map.&lt;br /&gt;
&lt;br /&gt;
The breakdown of the ResponseMap model can be found [https://expertiza.csc.ncsu.edu/index.php/Response_maps here]. There are several types of ResponseMaps that extend functionality of the original ResponseMap. None of which including the superclass are adequately tested. These files include:&lt;br /&gt;
&lt;br /&gt;
* review_response_map.rb  &amp;lt;--------- 92.5% coverage&lt;br /&gt;
&lt;br /&gt;
* metareview_response_map.rb &amp;lt;------ 23.08% coverage&lt;br /&gt;
&lt;br /&gt;
* teammate_review_response_map.rb &amp;lt;- no coverage&lt;br /&gt;
&lt;br /&gt;
* response_map.rb &amp;lt;----------------- 74.47% coverage&lt;br /&gt;
&lt;br /&gt;
This project aims to get all the response maps to at least a 90% level of coverage for every Response Map file by writing unit tests for each uncovered method listed in the next section.&lt;br /&gt;
&lt;br /&gt;
== Team ==&lt;br /&gt;
&lt;br /&gt;
* Connor Smith (cpsmith6)&lt;br /&gt;
&lt;br /&gt;
* Abir Majumder (aamajumd)&lt;br /&gt;
&lt;br /&gt;
* Quinn Dibble (qdibble)&lt;br /&gt;
&lt;br /&gt;
* Alex Carruth (agcarrut)&lt;br /&gt;
&lt;br /&gt;
== Test Files Involved ==&lt;br /&gt;
There are 4 test files involved in this project:&lt;br /&gt;
* review_response_map_spec.rb&lt;br /&gt;
&lt;br /&gt;
* metareview_response_map_spec.rb&lt;br /&gt;
&lt;br /&gt;
* teammate_review_response_map_spec.rb&lt;br /&gt;
&lt;br /&gt;
* response_map_spec.rb&lt;br /&gt;
of these files, only review_response_map_spec.rb currently exists; the rest will be added.&lt;br /&gt;
&lt;br /&gt;
== Methods Tested Per File ==&lt;br /&gt;
&lt;br /&gt;
=== review_response_map_spec.rb ===&lt;br /&gt;
Currently this file is 92.5% covered and there are no plans to cover it further.&lt;br /&gt;
&lt;br /&gt;
=== metareview_response_map_spec.rb ===&lt;br /&gt;
The functions for metareview_response_map.rb that will be tested are:&lt;br /&gt;
====get_all_versions====&lt;br /&gt;
This returns a sorted array of all the different versions of what is being reviewed in this response map. This means for a test, we will need to create a reviewer, a reviewee, several types of reviews of different versions to be sorted correctly.&lt;br /&gt;
&lt;br /&gt;
[[File:E2170-get all versions.PNG]]&lt;br /&gt;
&lt;br /&gt;
====contributor====&lt;br /&gt;
Returns the team associated with the ReviewResponseMap that is to be metareviewed. We will need to create a ReviewResponseMap that has a team associated with it. Then we must create MetareviewResponseMap that points to a created ReviewResponseMap via the reviewed_object_id attribute. We will test if it indeed returns the team associated with ReviewResponseMap.&lt;br /&gt;
&lt;br /&gt;
[[File:E2170-contributor.PNG]]&lt;br /&gt;
&lt;br /&gt;
====questionnaire====&lt;br /&gt;
Returns all questionnaires associated to the assignment of this MetareviewResponseMap that is of type 'MetareviewQuestionnaire'. We will need to create a valid MetareviewResponseMap including at least one MetareviewQuestionnaire that can be returned.&lt;br /&gt;
&lt;br /&gt;
[[File:E2170-questionnaire.PNG]]&lt;br /&gt;
&lt;br /&gt;
====get_title====&lt;br /&gt;
Returns string &amp;quot;Metareview&amp;quot;. We will test if this string is the same as typed out.&lt;br /&gt;
&lt;br /&gt;
[[File:E2170-get title.PNG]]&lt;br /&gt;
&lt;br /&gt;
====exports====&lt;br /&gt;
This function takes 3 parameters: csv (the csv file that will contain the exported metareview information), parent_id (the assignment ID containing the requested metareviews), and _options. The function sends all the information about the metareviews to a csv file. We will test that the information is properly exported to the csv file.&amp;lt;br&amp;gt;&lt;br /&gt;
[[File:E2170-export.jpg]]&lt;br /&gt;
&lt;br /&gt;
====export_fields====&lt;br /&gt;
Takes a parameter called &amp;quot;_options&amp;quot; that returns the three field columns associated with metareviews to be exported for use by other controllers. We will test to see that these three columns are properly returned.&amp;lt;br&amp;gt;&lt;br /&gt;
[[File:E2170-export_fields.jpg]]&lt;br /&gt;
&lt;br /&gt;
====import====&lt;br /&gt;
This function takes 3 parameters: row_hash (represents the hash of the metareview data we want to import), session, and id (representing the id of the assignment we want to import metareview data for). The function imports the data from the hash map, and if the information is input correctly, the data is extracted from the hash and creates a metareview for the requested assignment, otherwise it flashes an error saying the data was input incorrectly. We will test to make sure the imported data is properly converted into a metareview.&amp;lt;br&amp;gt;&lt;br /&gt;
[[File:E2170-import.jpg]]&lt;br /&gt;
&lt;br /&gt;
====email====&lt;br /&gt;
This function takes 3 parameters: defn, _participant (the user who will be receiving the email), and assignment (the assignment associated with the metareview). The function sends an email to the participant when they have a new metareview to complete. We will test to make sure the email is sent to the correct participant.&amp;lt;br&amp;gt;&lt;br /&gt;
[[File:E2170-email.jpg]]&lt;br /&gt;
&lt;br /&gt;
=== teammate_review_response_map_spec.rb ===&lt;br /&gt;
The functions for teammate_review_response_map.rb that will be tested are:&lt;br /&gt;
==== questionnaire ====&lt;br /&gt;
This function searches for a TeammateReviewQuestionnaire object and returns it.&lt;br /&gt;
&lt;br /&gt;
[[File:E2170-teammate review response map-questionnaire.PNG]]&lt;br /&gt;
&lt;br /&gt;
==== get_title ====&lt;br /&gt;
This function returns the string &amp;quot;Teammate Review&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
[[File:E2170-teammate_review_response_map-get_title.png]]&lt;br /&gt;
&lt;br /&gt;
==== teammate_response_report ====&lt;br /&gt;
This function returns the teammate response report given the reviewer ID.&lt;br /&gt;
&lt;br /&gt;
[[File:E2170-teammate_review_response_map-teammate_response_report.PNG]]&lt;br /&gt;
&lt;br /&gt;
==== email ====&lt;br /&gt;
This function sends a notification email to a student who has been reviewed by their teammate.&lt;br /&gt;
&lt;br /&gt;
[[File:E2170-teammate_review_response_map-email.png]]&lt;br /&gt;
&lt;br /&gt;
=== response_map_spec.rb ===&lt;br /&gt;
The functions for response_map.rb that will be tested are:&lt;br /&gt;
==== self.assessments_for(team) ====&lt;br /&gt;
Gets all submitted Review Responses or all regular Responses for a team, sorts the responses by version, and returns the latest Responses.&lt;br /&gt;
[[File:E2170-assessments_for.png]]&lt;br /&gt;
&lt;br /&gt;
==== comparator ====&lt;br /&gt;
Compares two Responses version numbers and returns a -1,0, or 1 depending on which version number is greater. If there is no version number for the first response, -1 is returned, otherwise 1 is returned.&lt;br /&gt;
&lt;br /&gt;
[[File:E2170-comparator.png]]&lt;br /&gt;
&lt;br /&gt;
==== self.reviewer_assessments_for(team, reviewer) ====&lt;br /&gt;
Gets the Responses for a team reviewed by a specific reviewer and returns the latest response.&lt;br /&gt;
&lt;br /&gt;
[[File:E2170-reviewer_assessments_for.png]]&lt;br /&gt;
&lt;br /&gt;
==== metareviewed_by? ====&lt;br /&gt;
Returns whether the Response Map has been metareviewed&lt;br /&gt;
&lt;br /&gt;
[[File:E2170-metareviewed_by.png]]&lt;br /&gt;
&lt;br /&gt;
==== assign_metareviewer ====&lt;br /&gt;
This function is in charge of assigning a metareviewer to this review (i.e. a reviewer to review the review).&lt;br /&gt;
&lt;br /&gt;
[[File:E2170-response_map-assign_metareviewer.png]]&lt;br /&gt;
&lt;br /&gt;
==== find_team_member ====&lt;br /&gt;
This function returns the team that the reviewer is part of.&lt;br /&gt;
&lt;br /&gt;
[[File:E2170-response_map-find_team_member.png]]&lt;br /&gt;
&lt;br /&gt;
== Running Tests ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  rspec ./spec/controllers/&amp;lt;test file name&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;/div&gt;</summary>
		<author><name>Agcarrut</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2021_-_E2170._Testing_-_Response_Maps&amp;diff=141313</id>
		<title>CSC/ECE 517 Fall 2021 - E2170. Testing - Response Maps</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2021_-_E2170._Testing_-_Response_Maps&amp;diff=141313"/>
		<updated>2021-11-08T22:59:21Z</updated>

		<summary type="html">&lt;p&gt;Agcarrut: /* response_map_spec.rb */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
== Description about project ==&lt;br /&gt;
This page is a description of Expertiza OSS project E2170 which aims to adequately test several files regarding the ResponseMap model. Here is a description of what response maps do:&lt;br /&gt;
*In Expertiza, response maps establish a relationship between a reviewer, a reviewee, and an object to be reviewed.  The reviewer is an assignment_participant, the reviewee is an assignment_team, and the reviewed object is either an assignment or another response_map. Each (reviewer, reviewee) pair will have a separate response map. Every time a new review is performed (e.g, every round), a new Response object is created whose map_id is that response map.&lt;br /&gt;
&lt;br /&gt;
The breakdown of the ResponseMap model can be found [https://expertiza.csc.ncsu.edu/index.php/Response_maps here]. There are several types of ResponseMaps that extend functionality of the original ResponseMap. None of which including the superclass are adequately tested. These files include:&lt;br /&gt;
&lt;br /&gt;
* review_response_map.rb  &amp;lt;--------- 92.5% coverage&lt;br /&gt;
&lt;br /&gt;
* metareview_response_map.rb &amp;lt;------ 23.08% coverage&lt;br /&gt;
&lt;br /&gt;
* teammate_review_response_map.rb &amp;lt;- no coverage&lt;br /&gt;
&lt;br /&gt;
* response_map.rb &amp;lt;----------------- 74.47% coverage&lt;br /&gt;
&lt;br /&gt;
This project aims to get all the response maps to at least a 90% level of coverage for every Response Map file by writing unit tests for each uncovered method listed in the next section.&lt;br /&gt;
&lt;br /&gt;
== Team ==&lt;br /&gt;
&lt;br /&gt;
* Connor Smith (cpsmith6)&lt;br /&gt;
&lt;br /&gt;
* Abir Majumder (aamajumd)&lt;br /&gt;
&lt;br /&gt;
* Quinn Dibble (qdibble)&lt;br /&gt;
&lt;br /&gt;
* Alex Carruth (agcarrut)&lt;br /&gt;
&lt;br /&gt;
== Test Files Involved ==&lt;br /&gt;
There are 4 test files involved in this project:&lt;br /&gt;
* review_response_map_spec.rb&lt;br /&gt;
&lt;br /&gt;
* metareview_response_map_spec.rb&lt;br /&gt;
&lt;br /&gt;
* teammate_review_response_map_spec.rb&lt;br /&gt;
&lt;br /&gt;
* response_map_spec.rb&lt;br /&gt;
of these files, only review_response_map_spec.rb currently exists; the rest will be added.&lt;br /&gt;
&lt;br /&gt;
== Methods Tested Per File ==&lt;br /&gt;
&lt;br /&gt;
=== review_response_map_spec.rb ===&lt;br /&gt;
Currently this file is 92.5% covered and there are no plans to cover it further.&lt;br /&gt;
&lt;br /&gt;
=== metareview_response_map_spec.rb ===&lt;br /&gt;
The functions for metareview_response_map.rb that will be tested are:&lt;br /&gt;
====get_all_versions====&lt;br /&gt;
This returns a sorted array of all the different versions of what is being reviewed in this response map. This means for a test, we will need to create a reviewer, a reviewee, several types of reviews of different versions to be sorted correctly.&lt;br /&gt;
&lt;br /&gt;
[[File:E2170-get all versions.PNG]]&lt;br /&gt;
&lt;br /&gt;
====contributor====&lt;br /&gt;
Returns the team associated with the ReviewResponseMap that is to be metareviewed. We will need to create a ReviewResponseMap that has a team associated with it. Then we must create MetareviewResponseMap that points to a created ReviewResponseMap via the reviewed_object_id attribute. We will test if it indeed returns the team associated with ReviewResponseMap.&lt;br /&gt;
&lt;br /&gt;
[[File:E2170-contributor.PNG]]&lt;br /&gt;
&lt;br /&gt;
====questionnaire====&lt;br /&gt;
Returns all questionnaires associated to the assignment of this MetareviewResponseMap that is of type 'MetareviewQuestionnaire'. We will need to create a valid MetareviewResponseMap including at least one MetareviewQuestionnaire that can be returned.&lt;br /&gt;
&lt;br /&gt;
[[File:E2170-questionnaire.PNG]]&lt;br /&gt;
&lt;br /&gt;
====get_title====&lt;br /&gt;
Returns string &amp;quot;Metareview&amp;quot;. We will test if this string is the same as typed out.&lt;br /&gt;
&lt;br /&gt;
[[File:E2170-get title.PNG]]&lt;br /&gt;
&lt;br /&gt;
====exports====&lt;br /&gt;
This function takes 3 parameters: csv (the csv file that will contain the exported metareview information), parent_id (the assignment ID containing the requested metareviews), and _options. The function sends all the information about the metareviews to a csv file. We will test that the information is properly exported to the csv file.&amp;lt;br&amp;gt;&lt;br /&gt;
[[File:E2170-export.jpg]]&lt;br /&gt;
&lt;br /&gt;
====export_fields====&lt;br /&gt;
Takes a parameter called &amp;quot;_options&amp;quot; that returns the three field columns associated with metareviews to be exported for use by other controllers. We will test to see that these three columns are properly returned.&amp;lt;br&amp;gt;&lt;br /&gt;
[[File:E2170-export_fields.jpg]]&lt;br /&gt;
&lt;br /&gt;
====import====&lt;br /&gt;
This function takes 3 parameters: row_hash (represents the hash of the metareview data we want to import), session, and id (representing the id of the assignment we want to import metareview data for). The function imports the data from the hash map, and if the information is input correctly, the data is extracted from the hash and creates a metareview for the requested assignment, otherwise it flashes an error saying the data was input incorrectly. We will test to make sure the imported data is properly converted into a metareview.&amp;lt;br&amp;gt;&lt;br /&gt;
[[File:E2170-import.jpg]]&lt;br /&gt;
&lt;br /&gt;
====email====&lt;br /&gt;
This function takes 3 parameters: defn, _participant (the user who will be receiving the email), and assignment (the assignment associated with the metareview). The function sends an email to the participant when they have a new metareview to complete. We will test to make sure the email is sent to the correct participant.&amp;lt;br&amp;gt;&lt;br /&gt;
[[File:E2170-email.jpg]]&lt;br /&gt;
&lt;br /&gt;
=== teammate_review_response_map_spec.rb ===&lt;br /&gt;
The functions for teammate_review_response_map.rb that will be tested are:&lt;br /&gt;
==== questionnaire ====&lt;br /&gt;
This function searches for a TeammateReviewQuestionnaire object and returns it.&lt;br /&gt;
&lt;br /&gt;
[[File:E2170-teammate review response map-questionnaire.PNG]]&lt;br /&gt;
&lt;br /&gt;
==== get_title ====&lt;br /&gt;
This function returns the string &amp;quot;Teammate Review&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
[[File:E2170-teammate_review_response_map-get_title.png]]&lt;br /&gt;
&lt;br /&gt;
==== teammate_response_report ====&lt;br /&gt;
This function returns the teammate response report given the reviewer ID.&lt;br /&gt;
&lt;br /&gt;
[[File:E2170-teammate_review_response_map-teammate_response_report.PNG]]&lt;br /&gt;
&lt;br /&gt;
==== email ====&lt;br /&gt;
This function sends a notification email to a student who has been reviewed by their teammate.&lt;br /&gt;
&lt;br /&gt;
[[File:E2170-teammate_review_response_map-email.png]]&lt;br /&gt;
&lt;br /&gt;
=== response_map_spec.rb ===&lt;br /&gt;
The functions for response_map.rb that will be tested are:&lt;br /&gt;
==== self.assessments_for(team) ====&lt;br /&gt;
Gets all submitted Review Responses or all regular Responses for a team, sorts the responses by version, and returns the latest Responses.&lt;br /&gt;
&lt;br /&gt;
==== comparator ====&lt;br /&gt;
Compares two Responses version numbers and returns a -1,0, or 1 depending on which version number is greater. If there is no version number for the first response, -1 is returned, otherwise 1 is returned.&lt;br /&gt;
&lt;br /&gt;
[[File:E2170-comparator.png]]&lt;br /&gt;
&lt;br /&gt;
==== self.reviewer_assessments_for(team, reviewer) ====&lt;br /&gt;
Gets the Responses for a team reviewed by a specific reviewer and returns the latest response.&lt;br /&gt;
&lt;br /&gt;
[[File:E2170-reviewer_assessments_for.png]]&lt;br /&gt;
&lt;br /&gt;
==== metareviewed_by? ====&lt;br /&gt;
Returns whether the Response Map has been metareviewed&lt;br /&gt;
&lt;br /&gt;
[[File:E2170-metareviewed_by.png]]&lt;br /&gt;
&lt;br /&gt;
==== assign_metareviewer ====&lt;br /&gt;
This function is in charge of assigning a metareviewer to this review (i.e. a reviewer to review the review).&lt;br /&gt;
&lt;br /&gt;
[[File:E2170-response_map-assign_metareviewer.png]]&lt;br /&gt;
&lt;br /&gt;
==== find_team_member ====&lt;br /&gt;
This function returns the team that the reviewer is part of.&lt;br /&gt;
&lt;br /&gt;
[[File:E2170-response_map-find_team_member.png]]&lt;br /&gt;
&lt;br /&gt;
== Running Tests ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  rspec ./spec/controllers/&amp;lt;test file name&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;/div&gt;</summary>
		<author><name>Agcarrut</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=File:E2170-metareviewed_by.png&amp;diff=141312</id>
		<title>File:E2170-metareviewed by.png</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=File:E2170-metareviewed_by.png&amp;diff=141312"/>
		<updated>2021-11-08T22:57:11Z</updated>

		<summary type="html">&lt;p&gt;Agcarrut: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Agcarrut</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=File:E2170-reviewer_assessments_for.png&amp;diff=141311</id>
		<title>File:E2170-reviewer assessments for.png</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=File:E2170-reviewer_assessments_for.png&amp;diff=141311"/>
		<updated>2021-11-08T22:56:27Z</updated>

		<summary type="html">&lt;p&gt;Agcarrut: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Agcarrut</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=File:E2170-comparator.png&amp;diff=141310</id>
		<title>File:E2170-comparator.png</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=File:E2170-comparator.png&amp;diff=141310"/>
		<updated>2021-11-08T22:55:22Z</updated>

		<summary type="html">&lt;p&gt;Agcarrut: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Agcarrut</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2021_-_E2170._Testing_-_Response_Maps&amp;diff=141309</id>
		<title>CSC/ECE 517 Fall 2021 - E2170. Testing - Response Maps</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2021_-_E2170._Testing_-_Response_Maps&amp;diff=141309"/>
		<updated>2021-11-08T22:54:56Z</updated>

		<summary type="html">&lt;p&gt;Agcarrut: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
== Description about project ==&lt;br /&gt;
This page is a description of Expertiza OSS project E2170 which aims to adequately test several files regarding the ResponseMap model. Here is a description of what response maps do:&lt;br /&gt;
*In Expertiza, response maps establish a relationship between a reviewer, a reviewee, and an object to be reviewed.  The reviewer is an assignment_participant, the reviewee is an assignment_team, and the reviewed object is either an assignment or another response_map. Each (reviewer, reviewee) pair will have a separate response map. Every time a new review is performed (e.g, every round), a new Response object is created whose map_id is that response map.&lt;br /&gt;
&lt;br /&gt;
The breakdown of the ResponseMap model can be found [https://expertiza.csc.ncsu.edu/index.php/Response_maps here]. There are several types of ResponseMaps that extend functionality of the original ResponseMap. None of which including the superclass are adequately tested. These files include:&lt;br /&gt;
&lt;br /&gt;
* review_response_map.rb  &amp;lt;--------- 92.5% coverage&lt;br /&gt;
&lt;br /&gt;
* metareview_response_map.rb &amp;lt;------ 23.08% coverage&lt;br /&gt;
&lt;br /&gt;
* teammate_review_response_map.rb &amp;lt;- no coverage&lt;br /&gt;
&lt;br /&gt;
* response_map.rb &amp;lt;----------------- 74.47% coverage&lt;br /&gt;
&lt;br /&gt;
This project aims to get all the response maps to at least a 90% level of coverage for every Response Map file by writing unit tests for each uncovered method listed in the next section.&lt;br /&gt;
&lt;br /&gt;
== Team ==&lt;br /&gt;
&lt;br /&gt;
* Connor Smith (cpsmith6)&lt;br /&gt;
&lt;br /&gt;
* Abir Majumder (aamajumd)&lt;br /&gt;
&lt;br /&gt;
* Quinn Dibble (qdibble)&lt;br /&gt;
&lt;br /&gt;
* Alex Carruth (agcarrut)&lt;br /&gt;
&lt;br /&gt;
== Test Files Involved ==&lt;br /&gt;
There are 4 test files involved in this project:&lt;br /&gt;
* review_response_map_spec.rb&lt;br /&gt;
&lt;br /&gt;
* metareview_response_map_spec.rb&lt;br /&gt;
&lt;br /&gt;
* teammate_review_response_map_spec.rb&lt;br /&gt;
&lt;br /&gt;
* response_map_spec.rb&lt;br /&gt;
of these files, only review_response_map_spec.rb currently exists; the rest will be added.&lt;br /&gt;
&lt;br /&gt;
== Methods Tested Per File ==&lt;br /&gt;
&lt;br /&gt;
=== review_response_map_spec.rb ===&lt;br /&gt;
Currently this file is 92.5% covered and there are no plans to cover it further.&lt;br /&gt;
&lt;br /&gt;
=== metareview_response_map_spec.rb ===&lt;br /&gt;
The functions for metareview_response_map.rb that will be tested are:&lt;br /&gt;
====get_all_versions====&lt;br /&gt;
This returns a sorted array of all the different versions of what is being reviewed in this response map. This means for a test, we will need to create a reviewer, a reviewee, several types of reviews of different versions to be sorted correctly.&lt;br /&gt;
&lt;br /&gt;
[[File:E2170-get all versions.PNG]]&lt;br /&gt;
&lt;br /&gt;
====contributor====&lt;br /&gt;
Returns the team associated with the ReviewResponseMap that is to be metareviewed. We will need to create a ReviewResponseMap that has a team associated with it. Then we must create MetareviewResponseMap that points to a created ReviewResponseMap via the reviewed_object_id attribute. We will test if it indeed returns the team associated with ReviewResponseMap.&lt;br /&gt;
&lt;br /&gt;
[[File:E2170-contributor.PNG]]&lt;br /&gt;
&lt;br /&gt;
====questionnaire====&lt;br /&gt;
Returns all questionnaires associated to the assignment of this MetareviewResponseMap that is of type 'MetareviewQuestionnaire'. We will need to create a valid MetareviewResponseMap including at least one MetareviewQuestionnaire that can be returned.&lt;br /&gt;
&lt;br /&gt;
[[File:E2170-questionnaire.PNG]]&lt;br /&gt;
&lt;br /&gt;
====get_title====&lt;br /&gt;
Returns string &amp;quot;Metareview&amp;quot;. We will test if this string is the same as typed out.&lt;br /&gt;
&lt;br /&gt;
[[File:E2170-get title.PNG]]&lt;br /&gt;
&lt;br /&gt;
====exports====&lt;br /&gt;
This function takes 3 parameters: csv (the csv file that will contain the exported metareview information), parent_id (the assignment ID containing the requested metareviews), and _options. The function sends all the information about the metareviews to a csv file. We will test that the information is properly exported to the csv file.&amp;lt;br&amp;gt;&lt;br /&gt;
[[File:E2170-export.jpg]]&lt;br /&gt;
&lt;br /&gt;
====export_fields====&lt;br /&gt;
Takes a parameter called &amp;quot;_options&amp;quot; that returns the three field columns associated with metareviews to be exported for use by other controllers. We will test to see that these three columns are properly returned.&amp;lt;br&amp;gt;&lt;br /&gt;
[[File:E2170-export_fields.jpg]]&lt;br /&gt;
&lt;br /&gt;
====import====&lt;br /&gt;
This function takes 3 parameters: row_hash (represents the hash of the metareview data we want to import), session, and id (representing the id of the assignment we want to import metareview data for). The function imports the data from the hash map, and if the information is input correctly, the data is extracted from the hash and creates a metareview for the requested assignment, otherwise it flashes an error saying the data was input incorrectly. We will test to make sure the imported data is properly converted into a metareview.&amp;lt;br&amp;gt;&lt;br /&gt;
[[File:E2170-import.jpg]]&lt;br /&gt;
&lt;br /&gt;
====email====&lt;br /&gt;
This function takes 3 parameters: defn, _participant (the user who will be receiving the email), and assignment (the assignment associated with the metareview). The function sends an email to the participant when they have a new metareview to complete. We will test to make sure the email is sent to the correct participant.&amp;lt;br&amp;gt;&lt;br /&gt;
[[File:E2170-email.jpg]]&lt;br /&gt;
&lt;br /&gt;
=== teammate_review_response_map_spec.rb ===&lt;br /&gt;
The functions for teammate_review_response_map.rb that will be tested are:&lt;br /&gt;
==== questionnaire ====&lt;br /&gt;
This function searches for a TeammateReviewQuestionnaire object and returns it.&lt;br /&gt;
&lt;br /&gt;
[[File:E2170-teammate review response map-questionnaire.PNG]]&lt;br /&gt;
&lt;br /&gt;
==== get_title ====&lt;br /&gt;
This function returns the string &amp;quot;Teammate Review&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
[[File:E2170-teammate_review_response_map-get_title.png]]&lt;br /&gt;
&lt;br /&gt;
==== teammate_response_report ====&lt;br /&gt;
This function returns the teammate response report given the reviewer ID.&lt;br /&gt;
&lt;br /&gt;
[[File:E2170-teammate_review_response_map-teammate_response_report.PNG]]&lt;br /&gt;
&lt;br /&gt;
==== email ====&lt;br /&gt;
This function sends a notification email to a student who has been reviewed by their teammate.&lt;br /&gt;
&lt;br /&gt;
[[File:E2170-teammate_review_response_map-email.png]]&lt;br /&gt;
&lt;br /&gt;
=== response_map_spec.rb ===&lt;br /&gt;
The functions for response_map.rb that will be tested are:&lt;br /&gt;
==== self.assessments_for(team) ====&lt;br /&gt;
Gets all submitted Review Responses or all regular Responses for a team, sorts the responses by version, and returns the latest Responses.&lt;br /&gt;
&lt;br /&gt;
==== comparator ====&lt;br /&gt;
Compares two Responses version numbers and returns a -1,0, or 1 depending on which version number is greater. If there is no version number for the first response, -1 is returned, otherwise 1 is returned.&lt;br /&gt;
&lt;br /&gt;
[[File:E2170-comparator.png]]&lt;br /&gt;
&lt;br /&gt;
==== self.reviewer_assessments_for(team, reviewer) ====&lt;br /&gt;
Gets the responses for a team reviewed by a specific reviewer and returns the latest response.&lt;br /&gt;
&lt;br /&gt;
[[File:E2170-reviewer_assessments_for.png]]&lt;br /&gt;
&lt;br /&gt;
==== metareviewed_by? ====&lt;br /&gt;
Returns whether the response map has been metareviewed&lt;br /&gt;
&lt;br /&gt;
[[File:E2170-metareviewed_by.png]]&lt;br /&gt;
&lt;br /&gt;
==== assign_metareviewer ====&lt;br /&gt;
This function is in charge of assigning a metareviewer to this review (i.e. a reviewer to review the review).&lt;br /&gt;
&lt;br /&gt;
[[File:E2170-response_map-assign_metareviewer.png]]&lt;br /&gt;
&lt;br /&gt;
==== find_team_member ====&lt;br /&gt;
This function returns the team that the reviewer is part of.&lt;br /&gt;
&lt;br /&gt;
[[File:E2170-response_map-find_team_member.png]]&lt;br /&gt;
&lt;br /&gt;
== Running Tests ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  rspec ./spec/controllers/&amp;lt;test file name&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;/div&gt;</summary>
		<author><name>Agcarrut</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2021_-_E2170._Testing_-_Response_Maps&amp;diff=140461</id>
		<title>CSC/ECE 517 Fall 2021 - E2170. Testing - Response Maps</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2021_-_E2170._Testing_-_Response_Maps&amp;diff=140461"/>
		<updated>2021-11-02T21:09:33Z</updated>

		<summary type="html">&lt;p&gt;Agcarrut: /* Description about project */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
== Description about project ==&lt;br /&gt;
This page is a description of Expertiza OSS project E2170 which aims to adequately test several files regarding the ResponseMap model. Here is a description of what response maps do:&lt;br /&gt;
*In Expertiza, response maps establish a relationship between a reviewer, a reviewee, and an object to be reviewed.  The reviewer is an assignment_participant, the reviewee is an assignment_team, and the reviewed object is either an assignment or another response_map. Each (reviewer, reviewee) pair will have a separate response map. Every time a new review is performed (e.g, every round), a new Response object is created whose map_id is that response map.&lt;br /&gt;
&lt;br /&gt;
The breakdown of the ResponseMap model can be found [https://expertiza.csc.ncsu.edu/index.php/Response_maps here]. There are several types of ResponseMaps that extend functionality of the original ResponseMap. None of which including the superclass are adequately tested. These files include:&lt;br /&gt;
&lt;br /&gt;
* review_response_map.rb  &amp;lt;--------- 92.5% coverage&lt;br /&gt;
&lt;br /&gt;
* metareview_response_map.rb &amp;lt;------ 23.08% coverage&lt;br /&gt;
&lt;br /&gt;
* teammate_review_response_map.rb &amp;lt;- no coverage&lt;br /&gt;
&lt;br /&gt;
* response_map.rb &amp;lt;----------------- 74.47% coverage&lt;br /&gt;
&lt;br /&gt;
This project aims to get all the response maps to at least a 90% level of coverage for every Response Map file.&lt;br /&gt;
&lt;br /&gt;
== Team ==&lt;br /&gt;
&lt;br /&gt;
* Connor Smith (cpsmith6)&lt;br /&gt;
&lt;br /&gt;
* Abir Majumder (aamajumd)&lt;br /&gt;
&lt;br /&gt;
* Quinn Dibble (qdibble)&lt;br /&gt;
&lt;br /&gt;
* Alex Carruth (agcarrut)&lt;br /&gt;
&lt;br /&gt;
== Test Files Involved ==&lt;br /&gt;
There are 4 test files involved in this project:&lt;br /&gt;
* review_response_map_spec.rb&lt;br /&gt;
&lt;br /&gt;
* metareview_response_map_spec.rb&lt;br /&gt;
&lt;br /&gt;
* teammate_review_response_map_spec.rb&lt;br /&gt;
&lt;br /&gt;
* response_map_spec.rb&lt;br /&gt;
of these files, only review_response_map_spec.rb currently exists in this project.&lt;br /&gt;
&lt;br /&gt;
== Description of modifications/additions ==&lt;br /&gt;
&lt;br /&gt;
=== review_response_map_spec.rb ===&lt;br /&gt;
Currently this file is 92.5% covered and there are no plans to cover it further.&lt;br /&gt;
&lt;br /&gt;
=== metareview_response_map_spec.rb ===&lt;br /&gt;
The functions for metareview_response_map.rb that will be tested are:&lt;br /&gt;
* get_all_versions&lt;br /&gt;
* contributor&lt;br /&gt;
* questionnaire&lt;br /&gt;
* get_title&lt;br /&gt;
* export&lt;br /&gt;
* export_fields&lt;br /&gt;
* import&lt;br /&gt;
* email&lt;br /&gt;
&lt;br /&gt;
=== teammate_review_response_map_spec.rb ===&lt;br /&gt;
The functions for teammate_review_response_map.rb that will be tested are:&lt;br /&gt;
* questionnaire&lt;br /&gt;
* get_title&lt;br /&gt;
* teammate_response_report&lt;br /&gt;
* email&lt;br /&gt;
&lt;br /&gt;
=== response_map_spec.rb ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Running Tests ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  rspec ./spec/controllers/&amp;lt;test file name&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Relevant Methods ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Results ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Relevant Links ===&lt;/div&gt;</summary>
		<author><name>Agcarrut</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2021_-_E2144._Refactor_delayed_mailer_and_scheduled_task&amp;diff=140208</id>
		<title>CSC/ECE 517 Fall 2021 - E2144. Refactor delayed mailer and scheduled task</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2021_-_E2144._Refactor_delayed_mailer_and_scheduled_task&amp;diff=140208"/>
		<updated>2021-10-27T02:58:04Z</updated>

		<summary type="html">&lt;p&gt;Agcarrut: /* MailWorker and DropOustandingReviews Test */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;__TOC__&lt;br /&gt;
&lt;br /&gt;
== Background ==&lt;br /&gt;
This project revolves around the Sidekiq gem for asynchronous processing of email tasks. It has a queue system to hold and then process jobs. Sidekiq’s queue replaces DelayedMailer’s queue. The previous team that worked on this also created a method &amp;lt;code&amp;gt;perform()&amp;lt;/code&amp;gt; to gather email IDs of all participants in an assignment and send them an email reminder. Some test cases exist for this work.&lt;br /&gt;
&lt;br /&gt;
=== Previous Setup ===&lt;br /&gt;
Initial work can be found [https://expertiza.csc.ncsu.edu/index.php/E1835_Refactor_delayed_mailer_and_scheduled_task here].&lt;br /&gt;
&lt;br /&gt;
Code in the [https://github.com/expertiza/expertiza/pull/1245/files pull request] was found to be reasonable and working. The method &amp;lt;code&amp;gt;perform()&amp;lt;/code&amp;gt; has:&lt;br /&gt;
{| class=wikitable style=text-align:right&lt;br /&gt;
|+ Metrics for &amp;lt;code&amp;gt;perform&amp;lt;/code&amp;gt; method&lt;br /&gt;
|-&lt;br /&gt;
! Metric !! Current Value !! Limit&lt;br /&gt;
|-&lt;br /&gt;
! Cognitive Complexity&lt;br /&gt;
| 15 || 5&lt;br /&gt;
|-&lt;br /&gt;
! Cyclomatic Complexity&lt;br /&gt;
| 8 || 6&lt;br /&gt;
|-&lt;br /&gt;
! Assignment Branch Condition size&lt;br /&gt;
| 22.93 || 15&lt;br /&gt;
|-&lt;br /&gt;
! Perceived complexity&lt;br /&gt;
| 10 || 7&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Previous pull request also has duplicated commit messages and the commits need to be squashed.&lt;br /&gt;
&lt;br /&gt;
Files involved (some changed should not have been changed):&lt;br /&gt;
* app/controllers/assignments_controller.rb&lt;br /&gt;
* app/mailers/mail_worker.rb&lt;br /&gt;
* app/models/assignment_form.rb&lt;br /&gt;
* config/sidekiq.yml&lt;br /&gt;
* spec/models/assignment_form_spec.rb&lt;br /&gt;
* spec/sidekiq_mail_worker_spec.rb&lt;br /&gt;
* spec/spec_helper.rb&lt;br /&gt;
&lt;br /&gt;
There are minor styling issues such as missing or trailing whitespaces, lines that are too long, extra empty line, unused arguments.&lt;br /&gt;
&lt;br /&gt;
=== Problem Statement ===&lt;br /&gt;
&lt;br /&gt;
This project revolves around the Sidekiq gem for asynchronous processing of email tasks. It has a queue system to hold and then process jobs. Sidekiq's queue replaces DelayedMailer’s queue. The previous team that worked on this also created a method perform() to gather email IDs of all participants in an assignment and send them an email reminder. Some test cases exist for this work.&lt;br /&gt;
The project was partially merged.&lt;br /&gt;
​&lt;br /&gt;
&lt;br /&gt;
What needs to be done:  &lt;br /&gt;
Feedback from the previous team (E1835) is:&lt;br /&gt;
Code in pull request seems pretty reasonable.  Some concerns wrt. naming functions, but otherwise reviewers seem to agree that the code is good.&lt;br /&gt;
​&lt;br /&gt;
&lt;br /&gt;
Your pull request has many duplicated commit messages. Please try to &amp;lt;code&amp;gt;squash&amp;lt;/code&amp;gt; similar commits.&lt;br /&gt;
And using meaningful commit messages later.&lt;br /&gt;
​&lt;br /&gt;
&lt;br /&gt;
You should commit changes to the DB schema (&amp;lt;code&amp;gt;db/schema.rb&amp;lt;/code&amp;gt;) only if you have created new DB migrations.&lt;br /&gt;
Please double check your code. If you did not aim to change the DB, please revert the DB schema changes. ***** Important, try not to change the DB.&lt;br /&gt;
​&lt;br /&gt;
&lt;br /&gt;
You should not change &amp;lt;code&amp;gt;rails_helper.rb&amp;lt;/code&amp;gt; or &amp;lt;code&amp;gt;spec_helper.rb&amp;lt;/code&amp;gt; file; please revert these changes.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The previous team’s code needs a refactor in some places, though the actual function of it seems solid. It is very possible that in the three years since this code has been worked on, more mailer functionality has been added. There are other teams this semester working on mailer code as well. Try to keep your code as contained and simple as possible, so that merging these projects is possible.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Summary of Work Needed ==&lt;br /&gt;
After discussing with our project mentor and Dr. Gehringer, we determined the main tasks to be the following:&lt;br /&gt;
# Refactor the single Sidekiq worker into multiple workers&lt;br /&gt;
# Remove all code related to the &amp;lt;code&amp;gt;drop_one_member_topics&amp;lt;/code&amp;gt; deadline type&lt;br /&gt;
# Update and add unit tests according to the above changes&lt;br /&gt;
# Test all new worker classes to ensure Sidekiq jobs were being dequeued and run as expected&lt;br /&gt;
# Code cleanup&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Refactor the single Sidekiq worker into multiple workers ===&lt;br /&gt;
Previously there was only a single worker class that handled all types of jobs. Its top-level method &amp;lt;code&amp;gt;perform&amp;lt;/code&amp;gt; looked like the following.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def perform(assignment_id, deadline_type, due_at)&lt;br /&gt;
    self.assignment_id = assignment_id&lt;br /&gt;
    self.deadline_type = deadline_type&lt;br /&gt;
    self.due_at = due_at&lt;br /&gt;
&lt;br /&gt;
    assignment = Assignment.find(self.assignment_id)&lt;br /&gt;
    participant_mails = find_participant_emails&lt;br /&gt;
&lt;br /&gt;
    if %w[drop_one_member_topics drop_outstanding_reviews compare_files_with_simicheck].include?(self.deadline_type)&lt;br /&gt;
      drop_one_member_topics if self.deadline_type == &amp;quot;drop_outstanding_reviews&amp;quot; &amp;amp;&amp;amp; assignment.team_assignment&lt;br /&gt;
      drop_outstanding_reviews if self.deadline_type == &amp;quot;drop_outstanding_reviews&amp;quot;&lt;br /&gt;
      perform_simicheck_comparisons(self.assignment_id) if self.deadline_type == &amp;quot;compare_files_with_simicheck&amp;quot;&lt;br /&gt;
    else&lt;br /&gt;
      # Can we rename deadline_type(metareview) to &amp;quot;teammate review&amp;quot;. If, yes then we donot need this if clause below!&lt;br /&gt;
      deadlineText = if self.deadline_type == &amp;quot;metareview&amp;quot;&lt;br /&gt;
                       &amp;quot;teammate review&amp;quot;&lt;br /&gt;
                     else&lt;br /&gt;
                       self.deadline_type&lt;br /&gt;
      end&lt;br /&gt;
&lt;br /&gt;
      email_reminder(participant_mails, deadlineText) unless participant_mails.empty?&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The processing was different depending on the &amp;lt;code&amp;gt;deadline_type&amp;lt;/code&amp;gt;. The &amp;lt;code&amp;gt;deadline_type&amp;lt;/code&amp;gt;s in&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
%w[drop_one_member_topics drop_outstanding_reviews compare_files_with_simicheck]&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
did not lead to an email reminder being sent, but they were still handled in this &amp;lt;code&amp;gt;MailWorker&amp;lt;/code&amp;gt; class.&lt;br /&gt;
&lt;br /&gt;
To make the code more manageable and easier to follow, it made sense to break up the responsibilities of this single &amp;lt;code&amp;gt;MailWorker&amp;lt;/code&amp;gt; class into multiple workers:&lt;br /&gt;
* &amp;lt;code&amp;gt;SimicheckWorker&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;DropOutstandingReviewsWorker&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;MailWorker&amp;lt;/code&amp;gt;&lt;br /&gt;
All three workers extended an &amp;quot;abstract class&amp;quot; called &amp;lt;code&amp;gt;Worker&amp;lt;/code&amp;gt; that contained the Sidekiq-related &amp;lt;code&amp;gt;include&amp;lt;/code&amp;gt; and the queue name to which all jobs would be sent.&lt;br /&gt;
&lt;br /&gt;
For simplicity, we still had all new workers continue to use a single queue, which we renamed from &amp;lt;code&amp;gt;mailers&amp;lt;/code&amp;gt; to &amp;lt;code&amp;gt;jobs&amp;lt;/code&amp;gt;. A future improvement could divide these jobs to go to multiple different queues if needed.&lt;br /&gt;
&lt;br /&gt;
=== Remove all code related to the &amp;lt;code&amp;gt;drop_one_member_topics&amp;lt;/code&amp;gt; deadline type ===&lt;br /&gt;
It was decided that code used for dropping one member or two member teams from topics would never need to be implemented in the Expertiza website. Thus, we removed all code related to the drop_one_member_topics method within the Expertiza beta. This involved removing the &amp;lt;code&amp;gt;drop_one_member_topics&amp;lt;/code&amp;gt; function from &amp;lt;code&amp;gt;drop_outstanding_reviews_mail_worker.rb&amp;lt;/code&amp;gt;, now renamed &amp;lt;code&amp;gt;drop_outstanding_reviews_worker.rb&amp;lt;/code&amp;gt;. The &amp;lt;code&amp;gt;drop_one_member_topics&amp;lt;/code&amp;gt; method was called from the &amp;lt;code&amp;gt;prepare_data&amp;lt;/code&amp;gt; method, which was then called by the Sidekiq method &amp;lt;code&amp;gt;perform&amp;lt;/code&amp;gt; so we removed this call. The &amp;lt;code&amp;gt;drop_one_member_topics&amp;lt;/code&amp;gt; was also referenced in &amp;lt;code&amp;gt;assignment_form.rb&amp;lt;/code&amp;gt; using &amp;lt;code&amp;gt;add_delayed_job&amp;lt;/code&amp;gt; in the &amp;lt;code&amp;gt;add_to_delayed_queue&amp;lt;/code&amp;gt; method and in &amp;lt;code&amp;gt;delayed_mailer.html.erb&amp;lt;/code&amp;gt; as an option for the handler so both of these code snippets were removed as well.&lt;br /&gt;
&lt;br /&gt;
=== Code Cleanup ===&lt;br /&gt;
Smaller improvements done while implementing the main tasks included:&lt;br /&gt;
* Using ActiveSupport::Duration objects in order to calculate the minutes and seconds related to the dequeue times&lt;br /&gt;
* Refactoring the time calculations for the dequeue times to the DueDate class&lt;br /&gt;
* Correcting the parameters passed to the workers, which were previously incorrect. As an example:&lt;br /&gt;
&amp;lt;blockquote&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def add_delayed_job(_assignment, deadline_type, due_date, min_left)&lt;br /&gt;
    delayed_job_id = MailWorker.perform_in(min_left * 60, due_date.parent_id, deadline_type, due_date.due_at)&lt;br /&gt;
    delayed_job_id&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
The first parameter after the time delay must be assignment ID, and &amp;lt;code&amp;gt;due_date.parent_id&amp;lt;/code&amp;gt; is not an assignment ID.&lt;br /&gt;
&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
* Removing whitespace issues reported by codeclimate&lt;br /&gt;
* Refactoring all variable names to be in snake_case&lt;br /&gt;
* Removing identical blocks of code&lt;br /&gt;
* Adding method comments to make methods more understandable&lt;br /&gt;
&lt;br /&gt;
== Test Plan ==&lt;br /&gt;
&lt;br /&gt;
=== Unit Tests ===&lt;br /&gt;
In order to properly test that our refactoring had worked properly, we found that we would have to add in multiple tests to account for our new methods as well as refactor old tests to work with the changes that we had made.&lt;br /&gt;
&lt;br /&gt;
For every worker, we have added a test case in the &amp;lt;code&amp;gt;spec/workers/sidekiq_mail_worker_spec.rb&amp;lt;/code&amp;gt; file: one each for MailWorker, SimicheckWorker, DropOutstandingReviewsWorker.&lt;br /&gt;
&lt;br /&gt;
Further, we moved methods &amp;lt;code&amp;gt;find_min_from_now_duration&amp;lt;/code&amp;gt; from &amp;lt;code&amp;gt;assignment_form.rb&amp;lt;/code&amp;gt; to &amp;lt;code&amp;gt;due_date.rb&amp;lt;/code&amp;gt;. Along with that we introduced some methods to make it easier to understand the conversions and values that are being set.&lt;br /&gt;
&lt;br /&gt;
=== Functional Tests ===&lt;br /&gt;
We decided that functional testing would need to be done by manually checking to see if Sidekiq tasks were queued as expected when changes to assignments were made. The three important functional tests that we decided needed to be verified were that the Simicheck Worker was queuing, the Mail Worker was queueing, and the Drop Outstanding Reviews Worker was queuing. These could be considered verified under the condition that the '''When''' field, '''Job''' field, and '''Arguments''' field in the Sidekiq view all came out as expected.&lt;br /&gt;
&lt;br /&gt;
=== Considering Edge Cases and Other Possibilities ===&lt;br /&gt;
&lt;br /&gt;
If we try to set the due date to be a date that has passed, no new jobs are queued as expected.&lt;br /&gt;
&lt;br /&gt;
== Implementing Test Plan ==&lt;br /&gt;
&lt;br /&gt;
=== Update and add unit tests according to the refactoring changes made  ===&lt;br /&gt;
&lt;br /&gt;
The following tests were added according to the methods we moved and created:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  describe &amp;quot;#find_min_from_now_duration&amp;quot; do&lt;br /&gt;
    it &amp;quot;returns time difference between due_date and now&amp;quot; do&lt;br /&gt;
      allow(DateTime).to receive(:now).and_return(DateTime.new(2021, 10, 20, 11, 11, 11).in_time_zone)&lt;br /&gt;
      due_at = Time.parse(DateTime.new(2021, 10, 20, 12, 12, 12).in_time_zone.to_s(:db))&lt;br /&gt;
      expect(DueDate.find_min_from_now_duration(due_at)).to eq(61)&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  describe &amp;quot;#get_dequeue_time_as_seconds_duration_from_now&amp;quot; do&lt;br /&gt;
    it &amp;quot;returns time difference between now and dequeue of job in seconds&amp;quot; do&lt;br /&gt;
      allow(DateTime).to receive(:now).and_return(DateTime.new(2021, 10, 20, 11, 00, 00).in_time_zone)&lt;br /&gt;
      due_at = DateTime.new(2021, 10, 20, 12, 00, 00)&lt;br /&gt;
      delay_duration = 1.hour&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: due_at, parent_id: assignment_id)&lt;br /&gt;
      expect(DueDate.get_dequeue_time_as_seconds_duration_from_now(due_date, delay_duration)).to eq(7200)&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Test all new worker classes to ensure Sidekiq jobs were being dequeued and run as expected ===&lt;br /&gt;
==== Sidekiq setup ====&lt;br /&gt;
In order to test the Sidekiq workers, we needed to run Sidekiq (steps were obtained from [https://tudip.com/blog-post/how-to-use-sidekiq-in-rails-for-background-processing/ this site]):&lt;br /&gt;
# In a terminal separate from the one in which the main rails application is running, run&lt;br /&gt;
&amp;lt;blockquote&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
bundle exec sidekiq&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This Sidekiq-specific terminal will show logs and printed statements from the workers.&lt;br /&gt;
&lt;br /&gt;
NB: To create a generic sidekiq worker to test with, you could use&lt;br /&gt;
&amp;lt;pre&amp;gt;rails g sidekiq:worker SimicheckWorker&amp;lt;/pre&amp;gt;&lt;br /&gt;
to create a shell worker class.&lt;br /&gt;
&lt;br /&gt;
===== Sidekiq UI =====&lt;br /&gt;
To see which messages were being enqueued and dequeued in Sidekiq, we use the Sidekiq user interface, which can be accessed via the &amp;lt;code&amp;gt;/sidekiq&amp;lt;/code&amp;gt; route of the application.&lt;br /&gt;
[[File:Sidekiq-ui.png|950px|The Sidekiq UI]]&lt;br /&gt;
&lt;br /&gt;
==== SimicheckWorker Test ====&lt;br /&gt;
To enqueue a Simicheck job:&lt;br /&gt;
# Edit an assignment.&lt;br /&gt;
# Select the &amp;lt;code&amp;gt;Use simicheck?&amp;lt;/code&amp;gt; box.&lt;br /&gt;
# Set &amp;lt;code&amp;gt;Simicheck Delay&amp;lt;/code&amp;gt; to &amp;lt;code&amp;gt;0&amp;lt;/code&amp;gt; (or to a nonzero value to observe a delay).&lt;br /&gt;
# Set the SimiCheck Similarity Threshold to a nonzero value.&lt;br /&gt;
# Ensure the Late Policy is set to &amp;lt;code&amp;gt;--None--&amp;lt;/code&amp;gt; under the Due Dates tab. If there is a late policy set, per pre-existing code, the enqueued SimicheckWorker job will be deleted and will not appear in the Sidekiq UI (unless it is dequeued quickly, before the code can delete the jobs in the queue).&lt;br /&gt;
# Click &amp;lt;code&amp;gt;Save&amp;lt;/code&amp;gt;.&lt;br /&gt;
# Observe a Simicheck Worker job enqueued and dequeued in the Sidekiq UI.&lt;br /&gt;
&lt;br /&gt;
[[File:Enqueue-simicheck-job.png|500px|How to Enqueue a Simicheck Worker Job]]&lt;br /&gt;
&lt;br /&gt;
[[File:simicheck-job-enqueued.png|950px|How to Enqueue a Simicheck Worker Job]]&lt;br /&gt;
&lt;br /&gt;
==== MailWorker and DropOustandingReviews Test ====&lt;br /&gt;
The Mail Worker sends out notifications to students if the due date of an assignment is changed. Drop Outstanding Reviews Worker drops all reviews that had not been worked on before the due date was changed. These both can be tested together, as when an assignment with a review is updated, Sidekiq should queue both the jobs for Mail Worker and Drop Outstanding Reviews Worker. To test these:&lt;br /&gt;
# Log into Expertiza as an instructor.&lt;br /&gt;
# Navigate to '''Manage'''&amp;gt;'''Assignments''' in the navigation.&lt;br /&gt;
# Click the plus button in the top right corner on the '''Manage Assignments''' and create an assignment with default settings. &lt;br /&gt;
# Go to the '''Due Dates''' tab and assign due dates for both the assignment and the review.&lt;br /&gt;
# Select a late policy next to '''Apply penalty policy:'''. If a late policy has not been created, press '''New Late Policy''' and follow the steps for creating a late policy.&lt;br /&gt;
# Assign student7613 to the assignment you created by clicking the person with the plus icon in the icons next to the assignment on the '''Manage Assignments''' page. &lt;br /&gt;
# Edit the assignment, go to the due dates tab, and change the due date on the review to be a day ahead of its current due date, and press save. The assignment due date must be changed to a time at least an hour ahead of the current time for the job to be queued.&lt;br /&gt;
# To ensure that the assignments are now queued on Sidekiq, visit the Sidekiq UI by going to [Expertiza VCL URL]/sidekiq.&lt;br /&gt;
# Upon arriving on this page, verify that the jobs added to the queue were correct by clicking to '''Scheduled'''. After arriving on this page, you should see something like the following:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[File:Sidekiq-jobs.png|950px|Sidekiq jobs]]&lt;br /&gt;
&lt;br /&gt;
The job '''MailWorker''' that had been queued successfully shows that our refactoring of Mail Worker had worked properly and the Mail Worker was operational. The job '''DropOutstandingReviewsWorker''' showed that our refactoring of Drop Outstanding Reviews Worker had also been done correctly.&lt;br /&gt;
&lt;br /&gt;
=== Automated Tests ===&lt;br /&gt;
&lt;br /&gt;
The following tests were added to test the workers:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
describe &amp;quot;test different workers&amp;quot; do&lt;br /&gt;
    it &amp;quot;should increase the size of queue by 1 when MailWorker is used&amp;quot; do&lt;br /&gt;
      Sidekiq::Testing.fake!&lt;br /&gt;
      MailWorker.perform_in(42.minutes, 1, &amp;quot;review&amp;quot;, &amp;quot;2021-10-27 00:00:01&amp;quot;)&lt;br /&gt;
      queue = Sidekiq::Queues[&amp;quot;jobs&amp;quot;]&lt;br /&gt;
      expect(queue.size).to eq(1)&lt;br /&gt;
      queue.clear&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    it &amp;quot;should increase the size of queue by 1 when SimicheckWorker is used&amp;quot; do&lt;br /&gt;
      Sidekiq::Testing.fake!&lt;br /&gt;
      SimicheckWorker.perform_in(42.minutes, 1)&lt;br /&gt;
      queue = Sidekiq::Queues[&amp;quot;jobs&amp;quot;]&lt;br /&gt;
      expect(queue.size).to eq(1)&lt;br /&gt;
      queue.clear&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    it &amp;quot;should increase the size of queue by 1 when DropOutstandingReviewsWorker is used&amp;quot; do&lt;br /&gt;
      Sidekiq::Testing.fake!&lt;br /&gt;
      DropOutstandingReviewsWorker.perform_in(42.minutes, 1, &amp;quot;review&amp;quot;, &amp;quot;2021-10-27 00:00:01&amp;quot;)&lt;br /&gt;
      queue = Sidekiq::Queues[&amp;quot;jobs&amp;quot;]&lt;br /&gt;
      expect(queue.size).to eq(1)&lt;br /&gt;
      queue.clear&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;/div&gt;</summary>
		<author><name>Agcarrut</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2021_-_E2144._Refactor_delayed_mailer_and_scheduled_task&amp;diff=140207</id>
		<title>CSC/ECE 517 Fall 2021 - E2144. Refactor delayed mailer and scheduled task</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2021_-_E2144._Refactor_delayed_mailer_and_scheduled_task&amp;diff=140207"/>
		<updated>2021-10-27T02:56:45Z</updated>

		<summary type="html">&lt;p&gt;Agcarrut: /* MailWorker and DropOustandingReviews Test */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;__TOC__&lt;br /&gt;
&lt;br /&gt;
== Background ==&lt;br /&gt;
This project revolves around the Sidekiq gem for asynchronous processing of email tasks. It has a queue system to hold and then process jobs. Sidekiq’s queue replaces DelayedMailer’s queue. The previous team that worked on this also created a method &amp;lt;code&amp;gt;perform()&amp;lt;/code&amp;gt; to gather email IDs of all participants in an assignment and send them an email reminder. Some test cases exist for this work.&lt;br /&gt;
&lt;br /&gt;
=== Previous Setup ===&lt;br /&gt;
Initial work can be found [https://expertiza.csc.ncsu.edu/index.php/E1835_Refactor_delayed_mailer_and_scheduled_task here].&lt;br /&gt;
&lt;br /&gt;
Code in the [https://github.com/expertiza/expertiza/pull/1245/files pull request] was found to be reasonable and working. The method &amp;lt;code&amp;gt;perform()&amp;lt;/code&amp;gt; has:&lt;br /&gt;
{| class=wikitable style=text-align:right&lt;br /&gt;
|+ Metrics for &amp;lt;code&amp;gt;perform&amp;lt;/code&amp;gt; method&lt;br /&gt;
|-&lt;br /&gt;
! Metric !! Current Value !! Limit&lt;br /&gt;
|-&lt;br /&gt;
! Cognitive Complexity&lt;br /&gt;
| 15 || 5&lt;br /&gt;
|-&lt;br /&gt;
! Cyclomatic Complexity&lt;br /&gt;
| 8 || 6&lt;br /&gt;
|-&lt;br /&gt;
! Assignment Branch Condition size&lt;br /&gt;
| 22.93 || 15&lt;br /&gt;
|-&lt;br /&gt;
! Perceived complexity&lt;br /&gt;
| 10 || 7&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Previous pull request also has duplicated commit messages and the commits need to be squashed.&lt;br /&gt;
&lt;br /&gt;
Files involved (some changed should not have been changed):&lt;br /&gt;
* app/controllers/assignments_controller.rb&lt;br /&gt;
* app/mailers/mail_worker.rb&lt;br /&gt;
* app/models/assignment_form.rb&lt;br /&gt;
* config/sidekiq.yml&lt;br /&gt;
* spec/models/assignment_form_spec.rb&lt;br /&gt;
* spec/sidekiq_mail_worker_spec.rb&lt;br /&gt;
* spec/spec_helper.rb&lt;br /&gt;
&lt;br /&gt;
There are minor styling issues such as missing or trailing whitespaces, lines that are too long, extra empty line, unused arguments.&lt;br /&gt;
&lt;br /&gt;
=== Problem Statement ===&lt;br /&gt;
&lt;br /&gt;
This project revolves around the Sidekiq gem for asynchronous processing of email tasks. It has a queue system to hold and then process jobs. Sidekiq's queue replaces DelayedMailer’s queue. The previous team that worked on this also created a method perform() to gather email IDs of all participants in an assignment and send them an email reminder. Some test cases exist for this work.&lt;br /&gt;
The project was partially merged.&lt;br /&gt;
​&lt;br /&gt;
&lt;br /&gt;
What needs to be done:  &lt;br /&gt;
Feedback from the previous team (E1835) is:&lt;br /&gt;
Code in pull request seems pretty reasonable.  Some concerns wrt. naming functions, but otherwise reviewers seem to agree that the code is good.&lt;br /&gt;
​&lt;br /&gt;
&lt;br /&gt;
Your pull request has many duplicated commit messages. Please try to &amp;lt;code&amp;gt;squash&amp;lt;/code&amp;gt; similar commits.&lt;br /&gt;
And using meaningful commit messages later.&lt;br /&gt;
​&lt;br /&gt;
&lt;br /&gt;
You should commit changes to the DB schema (&amp;lt;code&amp;gt;db/schema.rb&amp;lt;/code&amp;gt;) only if you have created new DB migrations.&lt;br /&gt;
Please double check your code. If you did not aim to change the DB, please revert the DB schema changes. ***** Important, try not to change the DB.&lt;br /&gt;
​&lt;br /&gt;
&lt;br /&gt;
You should not change &amp;lt;code&amp;gt;rails_helper.rb&amp;lt;/code&amp;gt; or &amp;lt;code&amp;gt;spec_helper.rb&amp;lt;/code&amp;gt; file; please revert these changes.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The previous team’s code needs a refactor in some places, though the actual function of it seems solid. It is very possible that in the three years since this code has been worked on, more mailer functionality has been added. There are other teams this semester working on mailer code as well. Try to keep your code as contained and simple as possible, so that merging these projects is possible.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Summary of Work Needed ==&lt;br /&gt;
After discussing with our project mentor and Dr. Gehringer, we determined the main tasks to be the following:&lt;br /&gt;
# Refactor the single Sidekiq worker into multiple workers&lt;br /&gt;
# Remove all code related to the &amp;lt;code&amp;gt;drop_one_member_topics&amp;lt;/code&amp;gt; deadline type&lt;br /&gt;
# Update and add unit tests according to the above changes&lt;br /&gt;
# Test all new worker classes to ensure Sidekiq jobs were being dequeued and run as expected&lt;br /&gt;
# Code cleanup&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Refactor the single Sidekiq worker into multiple workers ===&lt;br /&gt;
Previously there was only a single worker class that handled all types of jobs. Its top-level method &amp;lt;code&amp;gt;perform&amp;lt;/code&amp;gt; looked like the following.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def perform(assignment_id, deadline_type, due_at)&lt;br /&gt;
    self.assignment_id = assignment_id&lt;br /&gt;
    self.deadline_type = deadline_type&lt;br /&gt;
    self.due_at = due_at&lt;br /&gt;
&lt;br /&gt;
    assignment = Assignment.find(self.assignment_id)&lt;br /&gt;
    participant_mails = find_participant_emails&lt;br /&gt;
&lt;br /&gt;
    if %w[drop_one_member_topics drop_outstanding_reviews compare_files_with_simicheck].include?(self.deadline_type)&lt;br /&gt;
      drop_one_member_topics if self.deadline_type == &amp;quot;drop_outstanding_reviews&amp;quot; &amp;amp;&amp;amp; assignment.team_assignment&lt;br /&gt;
      drop_outstanding_reviews if self.deadline_type == &amp;quot;drop_outstanding_reviews&amp;quot;&lt;br /&gt;
      perform_simicheck_comparisons(self.assignment_id) if self.deadline_type == &amp;quot;compare_files_with_simicheck&amp;quot;&lt;br /&gt;
    else&lt;br /&gt;
      # Can we rename deadline_type(metareview) to &amp;quot;teammate review&amp;quot;. If, yes then we donot need this if clause below!&lt;br /&gt;
      deadlineText = if self.deadline_type == &amp;quot;metareview&amp;quot;&lt;br /&gt;
                       &amp;quot;teammate review&amp;quot;&lt;br /&gt;
                     else&lt;br /&gt;
                       self.deadline_type&lt;br /&gt;
      end&lt;br /&gt;
&lt;br /&gt;
      email_reminder(participant_mails, deadlineText) unless participant_mails.empty?&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The processing was different depending on the &amp;lt;code&amp;gt;deadline_type&amp;lt;/code&amp;gt;. The &amp;lt;code&amp;gt;deadline_type&amp;lt;/code&amp;gt;s in&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
%w[drop_one_member_topics drop_outstanding_reviews compare_files_with_simicheck]&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
did not lead to an email reminder being sent, but they were still handled in this &amp;lt;code&amp;gt;MailWorker&amp;lt;/code&amp;gt; class.&lt;br /&gt;
&lt;br /&gt;
To make the code more manageable and easier to follow, it made sense to break up the responsibilities of this single &amp;lt;code&amp;gt;MailWorker&amp;lt;/code&amp;gt; class into multiple workers:&lt;br /&gt;
* &amp;lt;code&amp;gt;SimicheckWorker&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;DropOutstandingReviewsWorker&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;MailWorker&amp;lt;/code&amp;gt;&lt;br /&gt;
All three workers extended an &amp;quot;abstract class&amp;quot; called &amp;lt;code&amp;gt;Worker&amp;lt;/code&amp;gt; that contained the Sidekiq-related &amp;lt;code&amp;gt;include&amp;lt;/code&amp;gt; and the queue name to which all jobs would be sent.&lt;br /&gt;
&lt;br /&gt;
For simplicity, we still had all new workers continue to use a single queue, which we renamed from &amp;lt;code&amp;gt;mailers&amp;lt;/code&amp;gt; to &amp;lt;code&amp;gt;jobs&amp;lt;/code&amp;gt;. A future improvement could divide these jobs to go to multiple different queues if needed.&lt;br /&gt;
&lt;br /&gt;
=== Remove all code related to the &amp;lt;code&amp;gt;drop_one_member_topics&amp;lt;/code&amp;gt; deadline type ===&lt;br /&gt;
It was decided that code used for dropping one member or two member teams from topics would never need to be implemented in the Expertiza website. Thus, we removed all code related to the drop_one_member_topics method within the Expertiza beta. This involved removing the &amp;lt;code&amp;gt;drop_one_member_topics&amp;lt;/code&amp;gt; function from &amp;lt;code&amp;gt;drop_outstanding_reviews_mail_worker.rb&amp;lt;/code&amp;gt;, now renamed &amp;lt;code&amp;gt;drop_outstanding_reviews_worker.rb&amp;lt;/code&amp;gt;. The &amp;lt;code&amp;gt;drop_one_member_topics&amp;lt;/code&amp;gt; method was called from the &amp;lt;code&amp;gt;prepare_data&amp;lt;/code&amp;gt; method, which was then called by the Sidekiq method &amp;lt;code&amp;gt;perform&amp;lt;/code&amp;gt; so we removed this call. The &amp;lt;code&amp;gt;drop_one_member_topics&amp;lt;/code&amp;gt; was also referenced in &amp;lt;code&amp;gt;assignment_form.rb&amp;lt;/code&amp;gt; using &amp;lt;code&amp;gt;add_delayed_job&amp;lt;/code&amp;gt; in the &amp;lt;code&amp;gt;add_to_delayed_queue&amp;lt;/code&amp;gt; method and in &amp;lt;code&amp;gt;delayed_mailer.html.erb&amp;lt;/code&amp;gt; as an option for the handler so both of these code snippets were removed as well.&lt;br /&gt;
&lt;br /&gt;
=== Code Cleanup ===&lt;br /&gt;
Smaller improvements done while implementing the main tasks included:&lt;br /&gt;
* Using ActiveSupport::Duration objects in order to calculate the minutes and seconds related to the dequeue times&lt;br /&gt;
* Refactoring the time calculations for the dequeue times to the DueDate class&lt;br /&gt;
* Correcting the parameters passed to the workers, which were previously incorrect. As an example:&lt;br /&gt;
&amp;lt;blockquote&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def add_delayed_job(_assignment, deadline_type, due_date, min_left)&lt;br /&gt;
    delayed_job_id = MailWorker.perform_in(min_left * 60, due_date.parent_id, deadline_type, due_date.due_at)&lt;br /&gt;
    delayed_job_id&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
The first parameter after the time delay must be assignment ID, and &amp;lt;code&amp;gt;due_date.parent_id&amp;lt;/code&amp;gt; is not an assignment ID.&lt;br /&gt;
&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
* Removing whitespace issues reported by codeclimate&lt;br /&gt;
* Refactoring all variable names to be in snake_case&lt;br /&gt;
* Removing identical blocks of code&lt;br /&gt;
* Adding method comments to make methods more understandable&lt;br /&gt;
&lt;br /&gt;
== Test Plan ==&lt;br /&gt;
&lt;br /&gt;
=== Unit Tests ===&lt;br /&gt;
In order to properly test that our refactoring had worked properly, we found that we would have to add in multiple tests to account for our new methods as well as refactor old tests to work with the changes that we had made.&lt;br /&gt;
&lt;br /&gt;
For every worker, we have added a test case in the &amp;lt;code&amp;gt;spec/workers/sidekiq_mail_worker_spec.rb&amp;lt;/code&amp;gt; file: one each for MailWorker, SimicheckWorker, DropOutstandingReviewsWorker.&lt;br /&gt;
&lt;br /&gt;
Further, we moved methods &amp;lt;code&amp;gt;find_min_from_now_duration&amp;lt;/code&amp;gt; from &amp;lt;code&amp;gt;assignment_form.rb&amp;lt;/code&amp;gt; to &amp;lt;code&amp;gt;due_date.rb&amp;lt;/code&amp;gt;. Along with that we introduced some methods to make it easier to understand the conversions and values that are being set.&lt;br /&gt;
&lt;br /&gt;
=== Functional Tests ===&lt;br /&gt;
We decided that functional testing would need to be done by manually checking to see if Sidekiq tasks were queued as expected when changes to assignments were made. The three important functional tests that we decided needed to be verified were that the Simicheck Worker was queuing, the Mail Worker was queueing, and the Drop Outstanding Reviews Worker was queuing. These could be considered verified under the condition that the '''When''' field, '''Job''' field, and '''Arguments''' field in the Sidekiq view all came out as expected.&lt;br /&gt;
&lt;br /&gt;
=== Considering Edge Cases and Other Possibilities ===&lt;br /&gt;
&lt;br /&gt;
If we try to set the due date to be a date that has passed, no new jobs are queued as expected.&lt;br /&gt;
&lt;br /&gt;
== Implementing Test Plan ==&lt;br /&gt;
&lt;br /&gt;
=== Update and add unit tests according to the refactoring changes made  ===&lt;br /&gt;
&lt;br /&gt;
The following tests were added according to the methods we moved and created:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  describe &amp;quot;#find_min_from_now_duration&amp;quot; do&lt;br /&gt;
    it &amp;quot;returns time difference between due_date and now&amp;quot; do&lt;br /&gt;
      allow(DateTime).to receive(:now).and_return(DateTime.new(2021, 10, 20, 11, 11, 11).in_time_zone)&lt;br /&gt;
      due_at = Time.parse(DateTime.new(2021, 10, 20, 12, 12, 12).in_time_zone.to_s(:db))&lt;br /&gt;
      expect(DueDate.find_min_from_now_duration(due_at)).to eq(61)&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  describe &amp;quot;#get_dequeue_time_as_seconds_duration_from_now&amp;quot; do&lt;br /&gt;
    it &amp;quot;returns time difference between now and dequeue of job in seconds&amp;quot; do&lt;br /&gt;
      allow(DateTime).to receive(:now).and_return(DateTime.new(2021, 10, 20, 11, 00, 00).in_time_zone)&lt;br /&gt;
      due_at = DateTime.new(2021, 10, 20, 12, 00, 00)&lt;br /&gt;
      delay_duration = 1.hour&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: due_at, parent_id: assignment_id)&lt;br /&gt;
      expect(DueDate.get_dequeue_time_as_seconds_duration_from_now(due_date, delay_duration)).to eq(7200)&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Test all new worker classes to ensure Sidekiq jobs were being dequeued and run as expected ===&lt;br /&gt;
==== Sidekiq setup ====&lt;br /&gt;
In order to test the Sidekiq workers, we needed to run Sidekiq (steps were obtained from [https://tudip.com/blog-post/how-to-use-sidekiq-in-rails-for-background-processing/ this site]):&lt;br /&gt;
# In a terminal separate from the one in which the main rails application is running, run&lt;br /&gt;
&amp;lt;blockquote&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
bundle exec sidekiq&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This Sidekiq-specific terminal will show logs and printed statements from the workers.&lt;br /&gt;
&lt;br /&gt;
NB: To create a generic sidekiq worker to test with, you could use&lt;br /&gt;
&amp;lt;pre&amp;gt;rails g sidekiq:worker SimicheckWorker&amp;lt;/pre&amp;gt;&lt;br /&gt;
to create a shell worker class.&lt;br /&gt;
&lt;br /&gt;
===== Sidekiq UI =====&lt;br /&gt;
To see which messages were being enqueued and dequeued in Sidekiq, we use the Sidekiq user interface, which can be accessed via the &amp;lt;code&amp;gt;/sidekiq&amp;lt;/code&amp;gt; route of the application.&lt;br /&gt;
[[File:Sidekiq-ui.png|950px|The Sidekiq UI]]&lt;br /&gt;
&lt;br /&gt;
==== SimicheckWorker Test ====&lt;br /&gt;
To enqueue a Simicheck job:&lt;br /&gt;
# Edit an assignment.&lt;br /&gt;
# Select the &amp;lt;code&amp;gt;Use simicheck?&amp;lt;/code&amp;gt; box.&lt;br /&gt;
# Set &amp;lt;code&amp;gt;Simicheck Delay&amp;lt;/code&amp;gt; to &amp;lt;code&amp;gt;0&amp;lt;/code&amp;gt; (or to a nonzero value to observe a delay).&lt;br /&gt;
# Set the SimiCheck Similarity Threshold to a nonzero value.&lt;br /&gt;
# Ensure the Late Policy is set to &amp;lt;code&amp;gt;--None--&amp;lt;/code&amp;gt; under the Due Dates tab. If there is a late policy set, per pre-existing code, the enqueued SimicheckWorker job will be deleted and will not appear in the Sidekiq UI (unless it is dequeued quickly, before the code can delete the jobs in the queue).&lt;br /&gt;
# Click &amp;lt;code&amp;gt;Save&amp;lt;/code&amp;gt;.&lt;br /&gt;
# Observe a Simicheck Worker job enqueued and dequeued in the Sidekiq UI.&lt;br /&gt;
&lt;br /&gt;
[[File:Enqueue-simicheck-job.png|500px|How to Enqueue a Simicheck Worker Job]]&lt;br /&gt;
&lt;br /&gt;
[[File:simicheck-job-enqueued.png|950px|How to Enqueue a Simicheck Worker Job]]&lt;br /&gt;
&lt;br /&gt;
==== MailWorker and DropOustandingReviews Test ====&lt;br /&gt;
The Mail Worker sends out notifications to students if the due date of an assignment is changed. Drop Outstanding Reviews Worker drops all reviews that had not been worked on before the due date was changed. These both can be tested together, as when an assignment with a review is updated, Sidekiq should queue both the jobs for Mail Worker and Drop Outstanding Reviews Worker. To test these:&lt;br /&gt;
# Log into Expertiza as an instructor&lt;br /&gt;
# Navigate to '''Manage'''&amp;gt;'''Assignments''' in the navigation&lt;br /&gt;
# Click the plus button in the top right corner on the '''Manage Assignments''' and create an assignment with default settings. &lt;br /&gt;
# Go to the '''Due Dates''' tab and assign due dates for both the assignment and the review.&lt;br /&gt;
# Select a late policy next to '''Apply penalty policy:'''. If a late policy has not been created, press '''New Late Policy''' and follow the steps for creating a late policy.&lt;br /&gt;
# Assign student7613 to the assignment you created by clicking the person with the plus icon in the icons next to the assignment on the '''Manage Assignments''' page. &lt;br /&gt;
# Go to the assignment that student7613 had been assigned to&lt;br /&gt;
# Edit the assignment, go to the due dates tab, and change the due date on the review to be a day ahead of its current due date, and press save. The assignment due date must be changed to a time at least an hour ahead of the current time for the reminder to be sent.&lt;br /&gt;
# To ensure that the assignments are now queued on Sidekiq, visit the Sidekiq UI by going to [Expertiza VCL URL]/sidekiq.&lt;br /&gt;
# Upon arriving on this page, verify that the jobs added to the queue were correct by clicking to '''Scheduled'''. After arriving on this page, you should see something like the following:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[File:Sidekiq-jobs.png|950px|Sidekiq jobs]]&lt;br /&gt;
&lt;br /&gt;
The job '''MailWorker''' that had been queued successfully shows that our refactoring of Mail Worker had worked properly and the Mail Worker was operational. The job '''DropOutstandingReviewsWorker''' showed that our refactoring of Drop Outstanding Reviews Worker had also been done correctly.&lt;br /&gt;
&lt;br /&gt;
=== Automated Tests ===&lt;br /&gt;
&lt;br /&gt;
The following tests were added to test the workers:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
describe &amp;quot;test different workers&amp;quot; do&lt;br /&gt;
    it &amp;quot;should increase the size of queue by 1 when MailWorker is used&amp;quot; do&lt;br /&gt;
      Sidekiq::Testing.fake!&lt;br /&gt;
      MailWorker.perform_in(42.minutes, 1, &amp;quot;review&amp;quot;, &amp;quot;2021-10-27 00:00:01&amp;quot;)&lt;br /&gt;
      queue = Sidekiq::Queues[&amp;quot;jobs&amp;quot;]&lt;br /&gt;
      expect(queue.size).to eq(1)&lt;br /&gt;
      queue.clear&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    it &amp;quot;should increase the size of queue by 1 when SimicheckWorker is used&amp;quot; do&lt;br /&gt;
      Sidekiq::Testing.fake!&lt;br /&gt;
      SimicheckWorker.perform_in(42.minutes, 1)&lt;br /&gt;
      queue = Sidekiq::Queues[&amp;quot;jobs&amp;quot;]&lt;br /&gt;
      expect(queue.size).to eq(1)&lt;br /&gt;
      queue.clear&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    it &amp;quot;should increase the size of queue by 1 when DropOutstandingReviewsWorker is used&amp;quot; do&lt;br /&gt;
      Sidekiq::Testing.fake!&lt;br /&gt;
      DropOutstandingReviewsWorker.perform_in(42.minutes, 1, &amp;quot;review&amp;quot;, &amp;quot;2021-10-27 00:00:01&amp;quot;)&lt;br /&gt;
      queue = Sidekiq::Queues[&amp;quot;jobs&amp;quot;]&lt;br /&gt;
      expect(queue.size).to eq(1)&lt;br /&gt;
      queue.clear&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;/div&gt;</summary>
		<author><name>Agcarrut</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2021_-_E2144._Refactor_delayed_mailer_and_scheduled_task&amp;diff=140179</id>
		<title>CSC/ECE 517 Fall 2021 - E2144. Refactor delayed mailer and scheduled task</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2021_-_E2144._Refactor_delayed_mailer_and_scheduled_task&amp;diff=140179"/>
		<updated>2021-10-27T01:51:00Z</updated>

		<summary type="html">&lt;p&gt;Agcarrut: /* Test all new worker classes to ensure Sidekiq jobs were being dequeued and run as expected */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;__TOC__&lt;br /&gt;
&lt;br /&gt;
== Background ==&lt;br /&gt;
This project revolves around the Sidekiq gem for asynchronous processing of email tasks. It has a queue system to hold and then process jobs. Sidekiq’s queue replaces DelayedMailer’s queue. The previous team that worked on this also created a method &amp;lt;code&amp;gt;perform()&amp;lt;/code&amp;gt; to gather email IDs of all participants in an assignment and send them an email reminder. Some test cases exist for this work.&lt;br /&gt;
&lt;br /&gt;
=== Previous Setup ===&lt;br /&gt;
Initial work can be found [https://expertiza.csc.ncsu.edu/index.php/E1835_Refactor_delayed_mailer_and_scheduled_task here].&lt;br /&gt;
&lt;br /&gt;
Code in the [https://github.com/expertiza/expertiza/pull/1245/files pull request] was found to be reasonable and working. The method &amp;lt;code&amp;gt;perform()&amp;lt;/code&amp;gt; has:&lt;br /&gt;
{| class=wikitable style=text-align:right&lt;br /&gt;
|+ Metrics for &amp;lt;code&amp;gt;perform&amp;lt;/code&amp;gt; method&lt;br /&gt;
|-&lt;br /&gt;
! Metric !! Current Value !! Limit&lt;br /&gt;
|-&lt;br /&gt;
! Cognitive Complexity&lt;br /&gt;
| 15 || 5&lt;br /&gt;
|-&lt;br /&gt;
! Cyclomatic Complexity&lt;br /&gt;
| 8 || 6&lt;br /&gt;
|-&lt;br /&gt;
! Assignment Branch Condition size&lt;br /&gt;
| 22.93 || 15&lt;br /&gt;
|-&lt;br /&gt;
! Perceived complexity&lt;br /&gt;
| 10 || 7&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Previous pull request also has duplicated commit messages and the commits need to be squashed.&lt;br /&gt;
&lt;br /&gt;
Files involved (some changed should not have been changed):&lt;br /&gt;
* app/controllers/assignments_controller.rb&lt;br /&gt;
* app/mailers/mail_worker.rb&lt;br /&gt;
* app/models/assignment_form.rb&lt;br /&gt;
* config/sidekiq.yml&lt;br /&gt;
* spec/models/assignment_form_spec.rb&lt;br /&gt;
* spec/sidekiq_mail_worker_spec.rb&lt;br /&gt;
* spec/spec_helper.rb&lt;br /&gt;
&lt;br /&gt;
There are minor styling issues such as missing or trailing whitespaces, lines that are too long, extra empty line, unused arguments.&lt;br /&gt;
&lt;br /&gt;
=== Problem Statement ===&lt;br /&gt;
&lt;br /&gt;
This project revolves around the Sidekiq gem for asynchronous processing of email tasks. It has a queue system to hold and then process jobs. Sidekiq's queue replaces DelayedMailer’s queue. The previous team that worked on this also created a method perform() to gather email IDs of all participants in an assignment and send them an email reminder. Some test cases exist for this work.&lt;br /&gt;
The project was partially merged.&lt;br /&gt;
​&lt;br /&gt;
&lt;br /&gt;
What needs to be done:  &lt;br /&gt;
Feedback from the previous team (E1835) is:&lt;br /&gt;
Code in pull request seems pretty reasonable.  Some concerns wrt. naming functions, but otherwise reviewers seem to agree that the code is good.&lt;br /&gt;
​&lt;br /&gt;
&lt;br /&gt;
Your pull request has many duplicated commit messages. Please try to &amp;lt;code&amp;gt;squash&amp;lt;/code&amp;gt; similar commits.&lt;br /&gt;
And using meaningful commit messages later.&lt;br /&gt;
​&lt;br /&gt;
&lt;br /&gt;
You should commit changes to the DB schema (&amp;lt;code&amp;gt;db/schema.rb&amp;lt;/code&amp;gt;) only if you have created new DB migrations.&lt;br /&gt;
Please double check your code. If you did not aim to change the DB, please revert the DB schema changes. ***** Important, try not to change the DB.&lt;br /&gt;
​&lt;br /&gt;
&lt;br /&gt;
You should not change &amp;lt;code&amp;gt;rails_helper.rb&amp;lt;/code&amp;gt; or &amp;lt;code&amp;gt;spec_helper.rb&amp;lt;/code&amp;gt; file; please revert these changes.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The previous team’s code needs a refactor in some places, though the actual function of it seems solid. It is very possible that in the three years since this code has been worked on, more mailer functionality has been added. There are other teams this semester working on mailer code as well. Try to keep your code as contained and simple as possible, so that merging these projects is possible.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Summary of Work Needed ==&lt;br /&gt;
After discussing with our project mentor and Dr. Gehringer, we determined the main tasks to be the following:&lt;br /&gt;
# Refactor the single Sidekiq worker into multiple workers&lt;br /&gt;
# Remove all code related to the &amp;lt;code&amp;gt;drop_one_member_topics&amp;lt;/code&amp;gt; deadline type&lt;br /&gt;
# Update and add unit tests according to the above changes&lt;br /&gt;
# Test all new worker classes to ensure Sidekiq jobs were being dequeued and run as expected&lt;br /&gt;
# Code cleanup&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Refactor the single Sidekiq worker into multiple workers ===&lt;br /&gt;
Previously there was only a single worker class that handled all types of jobs. Its top-level method &amp;lt;code&amp;gt;perform&amp;lt;/code&amp;gt; looked like the following.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def perform(assignment_id, deadline_type, due_at)&lt;br /&gt;
    self.assignment_id = assignment_id&lt;br /&gt;
    self.deadline_type = deadline_type&lt;br /&gt;
    self.due_at = due_at&lt;br /&gt;
&lt;br /&gt;
    assignment = Assignment.find(self.assignment_id)&lt;br /&gt;
    participant_mails = find_participant_emails&lt;br /&gt;
&lt;br /&gt;
    if %w[drop_one_member_topics drop_outstanding_reviews compare_files_with_simicheck].include?(self.deadline_type)&lt;br /&gt;
      drop_one_member_topics if self.deadline_type == &amp;quot;drop_outstanding_reviews&amp;quot; &amp;amp;&amp;amp; assignment.team_assignment&lt;br /&gt;
      drop_outstanding_reviews if self.deadline_type == &amp;quot;drop_outstanding_reviews&amp;quot;&lt;br /&gt;
      perform_simicheck_comparisons(self.assignment_id) if self.deadline_type == &amp;quot;compare_files_with_simicheck&amp;quot;&lt;br /&gt;
    else&lt;br /&gt;
      # Can we rename deadline_type(metareview) to &amp;quot;teammate review&amp;quot;. If, yes then we donot need this if clause below!&lt;br /&gt;
      deadlineText = if self.deadline_type == &amp;quot;metareview&amp;quot;&lt;br /&gt;
                       &amp;quot;teammate review&amp;quot;&lt;br /&gt;
                     else&lt;br /&gt;
                       self.deadline_type&lt;br /&gt;
      end&lt;br /&gt;
&lt;br /&gt;
      email_reminder(participant_mails, deadlineText) unless participant_mails.empty?&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The processing was different depending on the &amp;lt;code&amp;gt;deadline_type&amp;lt;/code&amp;gt;. The &amp;lt;code&amp;gt;deadline_type&amp;lt;/code&amp;gt;s in&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
%w[drop_one_member_topics drop_outstanding_reviews compare_files_with_simicheck]&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
did not lead to an email reminder being sent, but they were still handled in this &amp;lt;code&amp;gt;MailWorker&amp;lt;/code&amp;gt; class.&lt;br /&gt;
&lt;br /&gt;
To make the code more manageable and easier to follow, it made sense to break up the responsibilities of this single &amp;lt;code&amp;gt;MailWorker&amp;lt;/code&amp;gt; class into multiple workers:&lt;br /&gt;
* &amp;lt;code&amp;gt;SimicheckWorker&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;DropOutstandingReviewsWorker&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;MailWorker&amp;lt;/code&amp;gt;&lt;br /&gt;
All three workers extended an &amp;quot;abstract class&amp;quot; called &amp;lt;code&amp;gt;Worker&amp;lt;/code&amp;gt; that contained the Sidekiq-related &amp;lt;code&amp;gt;include&amp;lt;/code&amp;gt; and the queue name to which all jobs would be sent.&lt;br /&gt;
&lt;br /&gt;
For simplicity, we still had all new workers continue to use a single queue, which we renamed from &amp;lt;code&amp;gt;mailers&amp;lt;/code&amp;gt; to &amp;lt;code&amp;gt;jobs&amp;lt;/code&amp;gt;. A future improvement could divide these jobs to go to multiple different queues if needed.&lt;br /&gt;
&lt;br /&gt;
=== Remove all code related to the &amp;lt;code&amp;gt;drop_one_member_topics&amp;lt;/code&amp;gt; deadline type ===&lt;br /&gt;
It was decided that code used for dropping one member or two member teams from topics would never need to be implemented in the Expertiza website. Thus, we removed all code related to the drop_one_member_topics method within the Expertiza beta. This involved removing the &amp;lt;code&amp;gt;drop_one_member_topics&amp;lt;/code&amp;gt; function from &amp;lt;code&amp;gt;drop_outstanding_reviews_mail_worker.rb&amp;lt;/code&amp;gt;, now renamed &amp;lt;code&amp;gt;drop_outstanding_reviews_worker.rb&amp;lt;/code&amp;gt;. The &amp;lt;code&amp;gt;drop_one_member_topics&amp;lt;/code&amp;gt; method was called from the &amp;lt;code&amp;gt;prepare_data&amp;lt;/code&amp;gt; method, which was then called by the Sidekiq method &amp;lt;code&amp;gt;perform&amp;lt;/code&amp;gt; so we removed this call. The &amp;lt;code&amp;gt;drop_one_member_topics&amp;lt;/code&amp;gt; was also referenced in &amp;lt;code&amp;gt;assignment_form.rb&amp;lt;/code&amp;gt; using &amp;lt;code&amp;gt;add_delayed_job&amp;lt;/code&amp;gt; in the &amp;lt;code&amp;gt;add_to_delayed_queue&amp;lt;/code&amp;gt; method and in &amp;lt;code&amp;gt;delayed_mailer.html.erb&amp;lt;/code&amp;gt; as an option for the handler so both of these code snippets were removed as well.&lt;br /&gt;
&lt;br /&gt;
=== Code Cleanup ===&lt;br /&gt;
Smaller improvements done while implementing the main tasks included:&lt;br /&gt;
* Using ActiveSupport::Duration objects in order to calculate the minutes and seconds related to the dequeue times&lt;br /&gt;
* Refactoring the time calculations for the dequeue times to the DueDate class&lt;br /&gt;
* Correcting the parameters passed to the workers, which were previously incorrect. As an example:&lt;br /&gt;
&amp;lt;blockquote&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def add_delayed_job(_assignment, deadline_type, due_date, min_left)&lt;br /&gt;
    delayed_job_id = MailWorker.perform_in(min_left * 60, due_date.parent_id, deadline_type, due_date.due_at)&lt;br /&gt;
    delayed_job_id&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
The first parameter after the time delay must be assignment ID, and &amp;lt;code&amp;gt;due_date.parent_id&amp;lt;/code&amp;gt; is not an assignment ID.&lt;br /&gt;
&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
* Removing whitespace issues reported by codeclimate&lt;br /&gt;
* Refactoring all variable names to be in snake_case&lt;br /&gt;
* Removing identical blocks of code&lt;br /&gt;
* Adding method comments to make methods more understandable&lt;br /&gt;
&lt;br /&gt;
== Test Plan ==&lt;br /&gt;
&lt;br /&gt;
=== Unit Tests ===&lt;br /&gt;
In order to properly test that our refactoring had worked properly, we found that we would have to add in multiple tests to account for our new methods as well as refactor old tests to work with the changes that we had made.&lt;br /&gt;
&lt;br /&gt;
For every worker, we have added a test case in the &amp;lt;code&amp;gt;spec/workers/sidekiq_mail_worker_spec.rb&amp;lt;/code&amp;gt; file: one each for MailWorker, SimicheckWorker, DropOutstandingReviewsWorker.&lt;br /&gt;
&lt;br /&gt;
Further, we moved methods &amp;lt;code&amp;gt;find_min_from_now_duration&amp;lt;/code&amp;gt; from &amp;lt;code&amp;gt;assignment_form.rb&amp;lt;/code&amp;gt; to &amp;lt;code&amp;gt;due_date.rb&amp;lt;/code&amp;gt;. Along with that we introduced some methods to make it easier to understand the conversions and values that are being set.&lt;br /&gt;
&lt;br /&gt;
=== Functional Tests ===&lt;br /&gt;
We decided that functional testing would need to be done by manually checking to see if Sidekiq tasks were queued as expected when changes to assignments were made. The three important functional tests that we decided needed to be verified were that the Simicheck Worker was queuing, the Mail Worker was queueing, and the Drop Outstanding Reviews Worker was queuing. These could be considered verified under the condition that the '''When''' field, '''Job''' field, and '''Arguments''' field in the Sidekiq view all came out as expected.&lt;br /&gt;
&lt;br /&gt;
=== Considering Edge Cases and Other Possibilities ===&lt;br /&gt;
&lt;br /&gt;
== Implementing Test Plan ==&lt;br /&gt;
&lt;br /&gt;
=== Update and add unit tests according to the refactoring changes made  ===&lt;br /&gt;
&lt;br /&gt;
The following tests were added according to the methods we moved and created:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  describe &amp;quot;#find_min_from_now_duration&amp;quot; do&lt;br /&gt;
    it &amp;quot;returns time difference between due_date and now&amp;quot; do&lt;br /&gt;
      allow(DateTime).to receive(:now).and_return(DateTime.new(2021, 10, 20, 11, 11, 11).in_time_zone)&lt;br /&gt;
      due_at = Time.parse(DateTime.new(2021, 10, 20, 12, 12, 12).in_time_zone.to_s(:db))&lt;br /&gt;
      expect(DueDate.find_min_from_now_duration(due_at)).to eq(61)&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  describe &amp;quot;#get_dequeue_time_as_seconds_duration_from_now&amp;quot; do&lt;br /&gt;
    it &amp;quot;returns time difference between now and dequeue of job in seconds&amp;quot; do&lt;br /&gt;
      allow(DateTime).to receive(:now).and_return(DateTime.new(2021, 10, 20, 11, 00, 00).in_time_zone)&lt;br /&gt;
      due_at = DateTime.new(2021, 10, 20, 12, 00, 00)&lt;br /&gt;
      delay_duration = 1.hour&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: due_at, parent_id: assignment_id)&lt;br /&gt;
      expect(DueDate.get_dequeue_time_as_seconds_duration_from_now(due_date, delay_duration)).to eq(7200)&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Test all new worker classes to ensure Sidekiq jobs were being dequeued and run as expected ===&lt;br /&gt;
==== Sidekiq setup ====&lt;br /&gt;
In order to test the Sidekiq workers, we needed to run Sidekiq (steps were obtained from [https://tudip.com/blog-post/how-to-use-sidekiq-in-rails-for-background-processing/ this site]):&lt;br /&gt;
# In a terminal separate from the one in which the main rails application is running, run&lt;br /&gt;
&amp;lt;blockquote&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
bundle exec sidekiq&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This Sidekiq-specific terminal will show logs and printed statements from the workers.&lt;br /&gt;
&lt;br /&gt;
NB: To create a generic sidekiq worker to test with, you could use&lt;br /&gt;
&amp;lt;pre&amp;gt;rails g sidekiq:worker SimicheckWorker&amp;lt;/pre&amp;gt;&lt;br /&gt;
to create a shell worker class.&lt;br /&gt;
&lt;br /&gt;
===== Sidekiq UI =====&lt;br /&gt;
To see which messages were being enqueued and dequeued in Sidekiq, we use the Sidekiq user interface, which can be accessed via the &amp;lt;code&amp;gt;/sidekiq&amp;lt;/code&amp;gt; route of the application.&lt;br /&gt;
[[File:Sidekiq-ui.png|950px|The Sidekiq UI]]&lt;br /&gt;
&lt;br /&gt;
==== SimicheckWorker Test ====&lt;br /&gt;
To enqueue a Simicheck job:&lt;br /&gt;
# Edit an assignment.&lt;br /&gt;
# Select the &amp;lt;code&amp;gt;Use simicheck?&amp;lt;/code&amp;gt; box.&lt;br /&gt;
# Set &amp;lt;code&amp;gt;Simicheck Delay&amp;lt;/code&amp;gt; to &amp;lt;code&amp;gt;0&amp;lt;/code&amp;gt; (or to a nonzero value to observe a delay).&lt;br /&gt;
# Set the SimiCheck Similarity Threshold to a nonzero value.&lt;br /&gt;
# Click &amp;lt;code&amp;gt;Save&amp;lt;/code&amp;gt;.&lt;br /&gt;
# Observe a Simicheck Worker job enqueued and dequeued in the Sidekiq UI.&lt;br /&gt;
&lt;br /&gt;
[[File:Enqueue-simicheck-job.png|500px|How to Enqueue a Simicheck Worker Job]]&lt;br /&gt;
&lt;br /&gt;
==== MailWorker and DropOustandingReviews Test ====&lt;br /&gt;
The Mail Worker sends out notifications to students if the due date of an assignment is changed. Drop Outstanding Reviews Worker drops all reviews that had not been worked on before the due date was changed. These both can be tested together, as when an assignment with a review is updated, Sidekiq should queue both the jobs for Mail Worker and Drop Outstanding Reviews Worker. To test these:&lt;br /&gt;
# Log into Expertiza as an instructor&lt;br /&gt;
# Navigate to '''Manage'''&amp;gt;'''Assignments''' in the navigation&lt;br /&gt;
# Click the plus button in the top right corner on the '''Manage Assignments''' and create an assignment with default settings. Make sure when creating the assignment to go to the '''Due Dates''' tab and assign due dates for both the assignment and the review. &lt;br /&gt;
# Assign student7613 to the assignment you created by clicking the person with the plus icon in the icons next to the assignment on the '''Manage Assignments''' page. &lt;br /&gt;
&lt;br /&gt;
At this point, we realized we need to alter the code to test if the code was properly queuing the Mail Worker because the current if statement to add items to the delayed queue required that it have a late policy. However, the late policy code is not currently working. Thus, in the &amp;lt;code&amp;gt;assignment_form.rb&amp;lt;/code&amp;gt; model file, we edited the following code:&lt;br /&gt;
&lt;br /&gt;
[[File:Change_late_policy.png|950px|Late policy code to alter]]&lt;br /&gt;
&lt;br /&gt;
We removed &amp;lt;code&amp;gt;and has_late_policy&amp;lt;/code&amp;gt; so &amp;lt;code&amp;gt;add_delayed_queue&amp;lt;/code&amp;gt; can run even without late policies being implemented. After saving this file, we started up Expertiza again.&lt;br /&gt;
&amp;lt;ol start=&amp;quot;5&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; Go to the assignment that student7613 had been assigned to &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; Edit the assignment, go to the due dates tab, and change the due date on the review to be a day ahead of its current due date, and press save. The assignment due date must be changed to a time at least an hour ahead of the current time for the reminder to be sent. &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; To ensure that the assignments are now queued on Sidekiq, visit the Sidekiq UI by going to [Expertiza VCL URL]/sidekiq. &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; Upon arriving on this page, verify that the jobs added to the queue were correct by clicking to '''Scheduled'''. After arriving on this page, you should see something like the following: &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ol&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[File:Sidekiq-jobs.png|950px|Sidekiq jobs]]&lt;br /&gt;
&lt;br /&gt;
The job '''MailWorker''' that had been queued successfully shows that our refactoring of Mail Worker had worked properly and the Mail Worker was operational. The job '''DropOutstandingReviewsWorker''' showed that our refactoring of Drop Outstanding Reviews Worker had also been done correctly.&lt;br /&gt;
&lt;br /&gt;
=== Automated Tests ===&lt;br /&gt;
&lt;br /&gt;
The following tests were added to test the workers:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
describe &amp;quot;test different workers&amp;quot; do&lt;br /&gt;
    it &amp;quot;should increase the size of queue by 1 when MailWorker is used&amp;quot; do&lt;br /&gt;
      Sidekiq::Testing.fake!&lt;br /&gt;
      MailWorker.perform_in(42.minutes, 1, &amp;quot;review&amp;quot;, &amp;quot;2021-10-27 00:00:01&amp;quot;)&lt;br /&gt;
      queue = Sidekiq::Queues[&amp;quot;jobs&amp;quot;]&lt;br /&gt;
      expect(queue.size).to eq(1)&lt;br /&gt;
      queue.clear&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    it &amp;quot;should increase the size of queue by 1 when SimicheckWorker is used&amp;quot; do&lt;br /&gt;
      Sidekiq::Testing.fake!&lt;br /&gt;
      SimicheckWorker.perform_in(42.minutes, 1)&lt;br /&gt;
      queue = Sidekiq::Queues[&amp;quot;jobs&amp;quot;]&lt;br /&gt;
      expect(queue.size).to eq(1)&lt;br /&gt;
      queue.clear&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    it &amp;quot;should increase the size of queue by 1 when DropOutstandingReviewsWorker is used&amp;quot; do&lt;br /&gt;
      Sidekiq::Testing.fake!&lt;br /&gt;
      DropOutstandingReviewsWorker.perform_in(42.minutes, 1, &amp;quot;review&amp;quot;, &amp;quot;2021-10-27 00:00:01&amp;quot;)&lt;br /&gt;
      queue = Sidekiq::Queues[&amp;quot;jobs&amp;quot;]&lt;br /&gt;
      expect(queue.size).to eq(1)&lt;br /&gt;
      queue.clear&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;/div&gt;</summary>
		<author><name>Agcarrut</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2021_-_E2144._Refactor_delayed_mailer_and_scheduled_task&amp;diff=140171</id>
		<title>CSC/ECE 517 Fall 2021 - E2144. Refactor delayed mailer and scheduled task</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2021_-_E2144._Refactor_delayed_mailer_and_scheduled_task&amp;diff=140171"/>
		<updated>2021-10-27T01:29:31Z</updated>

		<summary type="html">&lt;p&gt;Agcarrut: /* MailWorker and DropOustandingReviews Test */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;__TOC__&lt;br /&gt;
&lt;br /&gt;
== Background ==&lt;br /&gt;
This project revolves around the Sidekiq gem for asynchronous processing of email tasks. It has a queue system to hold and then process jobs. Sidekiq’s queue replaces DelayedMailer’s queue. The previous team that worked on this also created a method &amp;lt;code&amp;gt;perform()&amp;lt;/code&amp;gt; to gather email IDs of all participants in an assignment and send them an email reminder. Some test cases exist for this work.&lt;br /&gt;
&lt;br /&gt;
=== Previous Setup ===&lt;br /&gt;
Initial work can be found [https://expertiza.csc.ncsu.edu/index.php/E1835_Refactor_delayed_mailer_and_scheduled_task here].&lt;br /&gt;
&lt;br /&gt;
Code in the [https://github.com/expertiza/expertiza/pull/1245/files pull request] was found to be reasonable and working. The method &amp;lt;code&amp;gt;perform()&amp;lt;/code&amp;gt; has:&lt;br /&gt;
{| class=wikitable style=text-align:right&lt;br /&gt;
|+ Metrics for &amp;lt;code&amp;gt;perform&amp;lt;/code&amp;gt; method&lt;br /&gt;
|-&lt;br /&gt;
! Metric !! Current Value !! Limit&lt;br /&gt;
|-&lt;br /&gt;
! Cognitive Complexity&lt;br /&gt;
| 15 || 5&lt;br /&gt;
|-&lt;br /&gt;
! Cyclomatic Complexity&lt;br /&gt;
| 8 || 6&lt;br /&gt;
|-&lt;br /&gt;
! Assignment Branch Condition size&lt;br /&gt;
| 22.93 || 15&lt;br /&gt;
|-&lt;br /&gt;
! Perceived complexity&lt;br /&gt;
| 10 || 7&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Previous pull request also has duplicated commit messages and the commits need to be squashed.&lt;br /&gt;
&lt;br /&gt;
Files involved (some changed should not have been changed):&lt;br /&gt;
* app/controllers/assignments_controller.rb&lt;br /&gt;
* app/mailers/mail_worker.rb&lt;br /&gt;
* app/models/assignment_form.rb&lt;br /&gt;
* config/sidekiq.yml&lt;br /&gt;
* spec/models/assignment_form_spec.rb&lt;br /&gt;
* spec/sidekiq_mail_worker_spec.rb&lt;br /&gt;
* spec/spec_helper.rb&lt;br /&gt;
&lt;br /&gt;
There are minor styling issues such as missing or trailing whitespaces, lines that are too long, extra empty line, unused arguments.&lt;br /&gt;
&lt;br /&gt;
=== Problem Statement ===&lt;br /&gt;
&lt;br /&gt;
This project revolves around the Sidekiq gem for asynchronous processing of email tasks. It has a queue system to hold and then process jobs. Sidekiq's queue replaces DelayedMailer’s queue. The previous team that worked on this also created a method perform() to gather email IDs of all participants in an assignment and send them an email reminder. Some test cases exist for this work.&lt;br /&gt;
The project was partially merged.&lt;br /&gt;
​&lt;br /&gt;
&lt;br /&gt;
What needs to be done:  &lt;br /&gt;
Feedback from the previous team (E1835) is:&lt;br /&gt;
Code in pull request seems pretty reasonable.  Some concerns wrt. naming functions, but otherwise reviewers seem to agree that the code is good.&lt;br /&gt;
​&lt;br /&gt;
&lt;br /&gt;
Your pull request has many duplicated commit messages. Please try to &amp;lt;code&amp;gt;squash&amp;lt;/code&amp;gt; similar commits.&lt;br /&gt;
And using meaningful commit messages later.&lt;br /&gt;
​&lt;br /&gt;
&lt;br /&gt;
You should commit changes to the DB schema (&amp;lt;code&amp;gt;db/schema.rb&amp;lt;/code&amp;gt;) only if you have created new DB migrations.&lt;br /&gt;
Please double check your code. If you did not aim to change the DB, please revert the DB schema changes. ***** Important, try not to change the DB.&lt;br /&gt;
​&lt;br /&gt;
&lt;br /&gt;
You should not change &amp;lt;code&amp;gt;rails_helper.rb&amp;lt;/code&amp;gt; or &amp;lt;code&amp;gt;spec_helper.rb&amp;lt;/code&amp;gt; file; please revert these changes.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The previous team’s code needs a refactor in some places, though the actual function of it seems solid. It is very possible that in the three years since this code has been worked on, more mailer functionality has been added. There are other teams this semester working on mailer code as well. Try to keep your code as contained and simple as possible, so that merging these projects is possible.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Summary of Work Needed ==&lt;br /&gt;
After discussing with our project mentor and Dr. Gehringer, we determined the main tasks to be the following:&lt;br /&gt;
# Refactor the single Sidekiq worker into multiple workers&lt;br /&gt;
# Remove all code related to the &amp;lt;code&amp;gt;drop_one_member_topics&amp;lt;/code&amp;gt; deadline type&lt;br /&gt;
# Update and add unit tests according to the above changes&lt;br /&gt;
# Test all new worker classes to ensure Sidekiq jobs were being dequeued and run as expected&lt;br /&gt;
# Code cleanup&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Refactor the single Sidekiq worker into multiple workers ===&lt;br /&gt;
Previously there was only a single worker class that handled all types of jobs. Its top-level method &amp;lt;code&amp;gt;perform&amp;lt;/code&amp;gt; looked like the following.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def perform(assignment_id, deadline_type, due_at)&lt;br /&gt;
    self.assignment_id = assignment_id&lt;br /&gt;
    self.deadline_type = deadline_type&lt;br /&gt;
    self.due_at = due_at&lt;br /&gt;
&lt;br /&gt;
    assignment = Assignment.find(self.assignment_id)&lt;br /&gt;
    participant_mails = find_participant_emails&lt;br /&gt;
&lt;br /&gt;
    if %w[drop_one_member_topics drop_outstanding_reviews compare_files_with_simicheck].include?(self.deadline_type)&lt;br /&gt;
      drop_one_member_topics if self.deadline_type == &amp;quot;drop_outstanding_reviews&amp;quot; &amp;amp;&amp;amp; assignment.team_assignment&lt;br /&gt;
      drop_outstanding_reviews if self.deadline_type == &amp;quot;drop_outstanding_reviews&amp;quot;&lt;br /&gt;
      perform_simicheck_comparisons(self.assignment_id) if self.deadline_type == &amp;quot;compare_files_with_simicheck&amp;quot;&lt;br /&gt;
    else&lt;br /&gt;
      # Can we rename deadline_type(metareview) to &amp;quot;teammate review&amp;quot;. If, yes then we donot need this if clause below!&lt;br /&gt;
      deadlineText = if self.deadline_type == &amp;quot;metareview&amp;quot;&lt;br /&gt;
                       &amp;quot;teammate review&amp;quot;&lt;br /&gt;
                     else&lt;br /&gt;
                       self.deadline_type&lt;br /&gt;
      end&lt;br /&gt;
&lt;br /&gt;
      email_reminder(participant_mails, deadlineText) unless participant_mails.empty?&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The processing was different depending on the &amp;lt;code&amp;gt;deadline_type&amp;lt;/code&amp;gt;. The &amp;lt;code&amp;gt;deadline_type&amp;lt;/code&amp;gt;s in&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
%w[drop_one_member_topics drop_outstanding_reviews compare_files_with_simicheck]&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
did not lead to an email reminder being sent, but they were still handled in this &amp;lt;code&amp;gt;MailWorker&amp;lt;/code&amp;gt; class.&lt;br /&gt;
&lt;br /&gt;
To make the code more manageable and easier to follow, it made sense to break up the responsibilities of this single &amp;lt;code&amp;gt;MailWorker&amp;lt;/code&amp;gt; class into multiple workers:&lt;br /&gt;
* &amp;lt;code&amp;gt;SimicheckWorker&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;DropOutstandingReviewsWorker&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;MailWorker&amp;lt;/code&amp;gt;&lt;br /&gt;
All three workers extended an &amp;quot;abstract class&amp;quot; called &amp;lt;code&amp;gt;Worker&amp;lt;/code&amp;gt; that contained the Sidekiq-related &amp;lt;code&amp;gt;include&amp;lt;/code&amp;gt; and the queue name to which all jobs would be sent.&lt;br /&gt;
&lt;br /&gt;
For simplicity, we still had all new workers continue to use a single queue, which we renamed from &amp;lt;code&amp;gt;mailers&amp;lt;/code&amp;gt; to &amp;lt;code&amp;gt;jobs&amp;lt;/code&amp;gt;. A future improvement could divide these jobs to go to multiple different queues if needed.&lt;br /&gt;
&lt;br /&gt;
=== Remove all code related to the &amp;lt;code&amp;gt;drop_one_member_topics&amp;lt;/code&amp;gt; deadline type ===&lt;br /&gt;
It was decided that code used for dropping one member or two member teams from topics would never need to be implemented in the Expertiza website. Thus, we removed all code related to the drop_one_member_topics method within the Expertiza beta. This involved removing the &amp;lt;code&amp;gt;drop_one_member_topics&amp;lt;/code&amp;gt; function from &amp;lt;code&amp;gt;drop_outstanding_reviews_mail_worker.rb&amp;lt;/code&amp;gt;, now renamed &amp;lt;code&amp;gt;drop_outstanding_reviews_worker.rb&amp;lt;/code&amp;gt;. The &amp;lt;code&amp;gt;drop_one_member_topics&amp;lt;/code&amp;gt; method was called from the &amp;lt;code&amp;gt;prepare_data&amp;lt;/code&amp;gt; method, which was then called by the Sidekiq method &amp;lt;code&amp;gt;perform&amp;lt;/code&amp;gt; so we removed this call. The &amp;lt;code&amp;gt;drop_one_member_topics&amp;lt;/code&amp;gt; was also referenced in &amp;lt;code&amp;gt;assignment_form.rb&amp;lt;/code&amp;gt; using &amp;lt;code&amp;gt;add_delayed_job&amp;lt;/code&amp;gt; in the &amp;lt;code&amp;gt;add_to_delayed_queue&amp;lt;/code&amp;gt; method and in &amp;lt;code&amp;gt;delayed_mailer.html.erb&amp;lt;/code&amp;gt; as an option for the handler so both of these code snippets were removed as well.&lt;br /&gt;
&lt;br /&gt;
=== Code Cleanup ===&lt;br /&gt;
Smaller improvements done while implementing the main tasks included:&lt;br /&gt;
* Using ActiveSupport::Duration objects in order to calculate the minutes and seconds related to the dequeue times&lt;br /&gt;
* Refactoring the time calculations for the dequeue times to the DueDate class&lt;br /&gt;
* Correcting the parameters passed to the workers, which were previously incorrect. As an example:&lt;br /&gt;
&amp;lt;blockquote&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def add_delayed_job(_assignment, deadline_type, due_date, min_left)&lt;br /&gt;
    delayed_job_id = MailWorker.perform_in(min_left * 60, due_date.parent_id, deadline_type, due_date.due_at)&lt;br /&gt;
    delayed_job_id&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
The first parameter after the time delay must be assignment ID, and &amp;lt;code&amp;gt;due_date.parent_id&amp;lt;/code&amp;gt; is not an assignment ID.&lt;br /&gt;
&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
* Removing whitespace issues reported by codeclimate&lt;br /&gt;
* Refactoring all variable names to be in snake_case&lt;br /&gt;
* Removing identical blocks of code&lt;br /&gt;
* Adding method comments to make methods more understandable&lt;br /&gt;
&lt;br /&gt;
== Test Plan ==&lt;br /&gt;
&lt;br /&gt;
=== Unit Tests ===&lt;br /&gt;
In order to properly test that our refactoring had worked properly, we found that we would have to add in multiple tests to account for our new methods as well as refactor old tests to work with the changes that we had made. &lt;br /&gt;
&lt;br /&gt;
=== Functional Tests ===&lt;br /&gt;
We decided that functional testing would need to be done by manually checking to see if Sidekiq tasks were queued as expected when changes to assignments were made. The three important functional tests that we decided needed to be verified were that the Simicheck Worker was queuing, the Mail Worker was queueing, and the Drop Outstanding Reviews Worker was queuing. These could be considered verified under the condition that the '''When''' field, '''Job''' field, and '''Arguments''' field in the Sidekiq view all came out as expected.&lt;br /&gt;
&lt;br /&gt;
=== Considering Edge Cases and Other Possibilities ===&lt;br /&gt;
&lt;br /&gt;
== Implementing Test Plan ==&lt;br /&gt;
&lt;br /&gt;
=== Update and add unit tests according to the refactoring changes made  ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Test all new worker classes to ensure Sidekiq jobs were being dequeued and run as expected ===&lt;br /&gt;
==== Sidekiq setup ====&lt;br /&gt;
In order to test the Sidekiq workers, a few steps were needed to set up the workers and run Sidekiq (steps were obtained from [https://tudip.com/blog-post/how-to-use-sidekiq-in-rails-for-background-processing/ this site]):&lt;br /&gt;
# Initialize three new workers, each having one of the three new worker types:&lt;br /&gt;
## &amp;lt;code&amp;gt;rails g sidekiq:worker SimicheckWorker&amp;lt;/code&amp;gt;&lt;br /&gt;
## &amp;lt;code&amp;gt;rails g sidekiq:worker DropOutstandingReviewsWorker&amp;lt;/code&amp;gt;&lt;br /&gt;
## &amp;lt;code&amp;gt;rails g sidekiq:worker MailWorker&amp;lt;/code&amp;gt;&lt;br /&gt;
# In a terminal separate from the one in which the main rails application is running, run&lt;br /&gt;
&amp;lt;blockquote&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
bundle exec sidekiq&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This Sidekiq-specific terminal will show logs and printed statements from the workers.&lt;br /&gt;
&lt;br /&gt;
==== SimicheckWorker Test ====&lt;br /&gt;
To enqueue a Simicheck job:&lt;br /&gt;
# Edit an assignment.&lt;br /&gt;
# Select the &amp;lt;code&amp;gt;Use simicheck?&amp;lt;/code&amp;gt; box.&lt;br /&gt;
# Set &amp;lt;code&amp;gt;Simicheck Delay&amp;lt;/code&amp;gt; to &amp;lt;code&amp;gt;0&amp;lt;/code&amp;gt; (or to a nonzero value to observe a delay).&lt;br /&gt;
# Set the SimiCheck Similarity Threshold to a nonzero value.&lt;br /&gt;
# Click &amp;lt;code&amp;gt;Save&amp;lt;/code&amp;gt;.&lt;br /&gt;
# Observe a Simicheck Worker job enqueued and dequeued in the Sidekiq UI.&lt;br /&gt;
&lt;br /&gt;
[[File:Enqueue-simicheck-job.png|500px|How to Enqueue a Simicheck Worker Job]]&lt;br /&gt;
&lt;br /&gt;
==== MailWorker and DropOustandingReviews Test ====&lt;br /&gt;
The Mail Worker sends out notifications to students if the due date of an assignment is changed. Drop Outstanding Reviews Worker drops all reviews that had not been worked on before the due date was changed. These both can be tested together, as when an assignment with a review is updated, Sidekiq should queue both the jobs for Mail Worker and Drop Outstanding Reviews Worker. To test these:&lt;br /&gt;
# Log into Expertiza as an instructor&lt;br /&gt;
# Navigate to '''Manage'''&amp;gt;'''Assignments''' in the navigation&lt;br /&gt;
# Click the plus button in the top right corner on the '''Manage Assignments''' and create an assignment with default settings. Make sure when creating the assignment to go to the '''Due Dates''' tab and assign due dates for both the assignment and the review. &lt;br /&gt;
# Assign student7613 to the assignment you created by clicking the person with the plus icon in the icons next to the assignment on the '''Manage Assignments''' page. &lt;br /&gt;
&lt;br /&gt;
At this point, we realized we need to alter the code to test if the code was properly queuing the Mail Worker because the current if statement to add items to the delayed queue required that it have a late policy. However, the late policy code is not currently working. Thus, in the &amp;lt;code&amp;gt;assignment_form.rb&amp;lt;/code&amp;gt; model file, we edited the following code:&lt;br /&gt;
&lt;br /&gt;
[[File:Change_late_policy.png|950px|Late policy code to alter]]&lt;br /&gt;
&lt;br /&gt;
We removed &amp;lt;code&amp;gt;and has_late_policy&amp;lt;/code&amp;gt; so &amp;lt;code&amp;gt;add_delayed_queue&amp;lt;/code&amp;gt; can run even without late policies being implemented. After saving this file, we started up Expertiza again.&lt;br /&gt;
&amp;lt;ol start=&amp;quot;5&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; Go to the assignment that student7613 had been assigned to &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; Edit the assignment, go to the due dates tab, and change the due date on the review to be a day ahead of its current due date, and press save. The assignment due date must be changed to a time at least an hour ahead of the current time for the reminder to be sent. &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; To ensure that the assignments are now queued on Sidekiq, visit the Sidekiq UI by going to [Expertiza VCL URL]/sidekiq. &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; Upon arriving on this page, verify that the jobs added to the queue were correct by clicking to '''Scheduled'''. After arriving on this page, you should see something like the following: &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ol&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[File:Sidekiq-jobs.png|950px|Sidekiq jobs]]&lt;br /&gt;
&lt;br /&gt;
The job '''MailWorker''' that had been queued successfully shows that our refactoring of Mail Worker had worked properly and the Mail Worker was operational. The job '''DropOutstandingReviewsWorker''' showed that our refactoring of Drop Outstanding Reviews Worker had also been done correctly.&lt;br /&gt;
&lt;br /&gt;
=== Sidekiq UI ===&lt;br /&gt;
To see which messages were being enqueued and dequeued in Sidekiq, we use the Sidekiq user interface, which can be accessed via the &amp;lt;code&amp;gt;/sidekiq&amp;lt;/code&amp;gt; route of the application.&lt;br /&gt;
[[File:Sidekiq-ui.png|950px|The Sidekiq UI]]&lt;/div&gt;</summary>
		<author><name>Agcarrut</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2021_-_E2144._Refactor_delayed_mailer_and_scheduled_task&amp;diff=140170</id>
		<title>CSC/ECE 517 Fall 2021 - E2144. Refactor delayed mailer and scheduled task</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2021_-_E2144._Refactor_delayed_mailer_and_scheduled_task&amp;diff=140170"/>
		<updated>2021-10-27T01:28:51Z</updated>

		<summary type="html">&lt;p&gt;Agcarrut: /* MailWorker and DropOustandingReviews Test */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;__TOC__&lt;br /&gt;
&lt;br /&gt;
== Background ==&lt;br /&gt;
This project revolves around the Sidekiq gem for asynchronous processing of email tasks. It has a queue system to hold and then process jobs. Sidekiq’s queue replaces DelayedMailer’s queue. The previous team that worked on this also created a method &amp;lt;code&amp;gt;perform()&amp;lt;/code&amp;gt; to gather email IDs of all participants in an assignment and send them an email reminder. Some test cases exist for this work.&lt;br /&gt;
&lt;br /&gt;
=== Previous Setup ===&lt;br /&gt;
Initial work can be found [https://expertiza.csc.ncsu.edu/index.php/E1835_Refactor_delayed_mailer_and_scheduled_task here].&lt;br /&gt;
&lt;br /&gt;
Code in the [https://github.com/expertiza/expertiza/pull/1245/files pull request] was found to be reasonable and working. The method &amp;lt;code&amp;gt;perform()&amp;lt;/code&amp;gt; has:&lt;br /&gt;
{| class=wikitable style=text-align:right&lt;br /&gt;
|+ Metrics for &amp;lt;code&amp;gt;perform&amp;lt;/code&amp;gt; method&lt;br /&gt;
|-&lt;br /&gt;
! Metric !! Current Value !! Limit&lt;br /&gt;
|-&lt;br /&gt;
! Cognitive Complexity&lt;br /&gt;
| 15 || 5&lt;br /&gt;
|-&lt;br /&gt;
! Cyclomatic Complexity&lt;br /&gt;
| 8 || 6&lt;br /&gt;
|-&lt;br /&gt;
! Assignment Branch Condition size&lt;br /&gt;
| 22.93 || 15&lt;br /&gt;
|-&lt;br /&gt;
! Perceived complexity&lt;br /&gt;
| 10 || 7&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Previous pull request also has duplicated commit messages and the commits need to be squashed.&lt;br /&gt;
&lt;br /&gt;
Files involved (some changed should not have been changed):&lt;br /&gt;
* app/controllers/assignments_controller.rb&lt;br /&gt;
* app/mailers/mail_worker.rb&lt;br /&gt;
* app/models/assignment_form.rb&lt;br /&gt;
* config/sidekiq.yml&lt;br /&gt;
* spec/models/assignment_form_spec.rb&lt;br /&gt;
* spec/sidekiq_mail_worker_spec.rb&lt;br /&gt;
* spec/spec_helper.rb&lt;br /&gt;
&lt;br /&gt;
There are minor styling issues such as missing or trailing whitespaces, lines that are too long, extra empty line, unused arguments.&lt;br /&gt;
&lt;br /&gt;
=== Problem Statement ===&lt;br /&gt;
&lt;br /&gt;
This project revolves around the Sidekiq gem for asynchronous processing of email tasks. It has a queue system to hold and then process jobs. Sidekiq's queue replaces DelayedMailer’s queue. The previous team that worked on this also created a method perform() to gather email IDs of all participants in an assignment and send them an email reminder. Some test cases exist for this work.&lt;br /&gt;
The project was partially merged.&lt;br /&gt;
​&lt;br /&gt;
&lt;br /&gt;
What needs to be done:  &lt;br /&gt;
Feedback from the previous team (E1835) is:&lt;br /&gt;
Code in pull request seems pretty reasonable.  Some concerns wrt. naming functions, but otherwise reviewers seem to agree that the code is good.&lt;br /&gt;
​&lt;br /&gt;
&lt;br /&gt;
Your pull request has many duplicated commit messages. Please try to &amp;lt;code&amp;gt;squash&amp;lt;/code&amp;gt; similar commits.&lt;br /&gt;
And using meaningful commit messages later.&lt;br /&gt;
​&lt;br /&gt;
&lt;br /&gt;
You should commit changes to the DB schema (&amp;lt;code&amp;gt;db/schema.rb&amp;lt;/code&amp;gt;) only if you have created new DB migrations.&lt;br /&gt;
Please double check your code. If you did not aim to change the DB, please revert the DB schema changes. ***** Important, try not to change the DB.&lt;br /&gt;
​&lt;br /&gt;
&lt;br /&gt;
You should not change &amp;lt;code&amp;gt;rails_helper.rb&amp;lt;/code&amp;gt; or &amp;lt;code&amp;gt;spec_helper.rb&amp;lt;/code&amp;gt; file; please revert these changes.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The previous team’s code needs a refactor in some places, though the actual function of it seems solid. It is very possible that in the three years since this code has been worked on, more mailer functionality has been added. There are other teams this semester working on mailer code as well. Try to keep your code as contained and simple as possible, so that merging these projects is possible.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Summary of Work Needed ==&lt;br /&gt;
After discussing with our project mentor and Dr. Gehringer, we determined the main tasks to be the following:&lt;br /&gt;
# Refactor the single Sidekiq worker into multiple workers&lt;br /&gt;
# Remove all code related to the &amp;lt;code&amp;gt;drop_one_member_topics&amp;lt;/code&amp;gt; deadline type&lt;br /&gt;
# Update and add unit tests according to the above changes&lt;br /&gt;
# Test all new worker classes to ensure Sidekiq jobs were being dequeued and run as expected&lt;br /&gt;
# Code cleanup&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Refactor the single Sidekiq worker into multiple workers ===&lt;br /&gt;
Previously there was only a single worker class that handled all types of jobs. Its top-level method &amp;lt;code&amp;gt;perform&amp;lt;/code&amp;gt; looked like the following.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def perform(assignment_id, deadline_type, due_at)&lt;br /&gt;
    self.assignment_id = assignment_id&lt;br /&gt;
    self.deadline_type = deadline_type&lt;br /&gt;
    self.due_at = due_at&lt;br /&gt;
&lt;br /&gt;
    assignment = Assignment.find(self.assignment_id)&lt;br /&gt;
    participant_mails = find_participant_emails&lt;br /&gt;
&lt;br /&gt;
    if %w[drop_one_member_topics drop_outstanding_reviews compare_files_with_simicheck].include?(self.deadline_type)&lt;br /&gt;
      drop_one_member_topics if self.deadline_type == &amp;quot;drop_outstanding_reviews&amp;quot; &amp;amp;&amp;amp; assignment.team_assignment&lt;br /&gt;
      drop_outstanding_reviews if self.deadline_type == &amp;quot;drop_outstanding_reviews&amp;quot;&lt;br /&gt;
      perform_simicheck_comparisons(self.assignment_id) if self.deadline_type == &amp;quot;compare_files_with_simicheck&amp;quot;&lt;br /&gt;
    else&lt;br /&gt;
      # Can we rename deadline_type(metareview) to &amp;quot;teammate review&amp;quot;. If, yes then we donot need this if clause below!&lt;br /&gt;
      deadlineText = if self.deadline_type == &amp;quot;metareview&amp;quot;&lt;br /&gt;
                       &amp;quot;teammate review&amp;quot;&lt;br /&gt;
                     else&lt;br /&gt;
                       self.deadline_type&lt;br /&gt;
      end&lt;br /&gt;
&lt;br /&gt;
      email_reminder(participant_mails, deadlineText) unless participant_mails.empty?&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The processing was different depending on the &amp;lt;code&amp;gt;deadline_type&amp;lt;/code&amp;gt;. The &amp;lt;code&amp;gt;deadline_type&amp;lt;/code&amp;gt;s in&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
%w[drop_one_member_topics drop_outstanding_reviews compare_files_with_simicheck]&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
did not lead to an email reminder being sent, but they were still handled in this &amp;lt;code&amp;gt;MailWorker&amp;lt;/code&amp;gt; class.&lt;br /&gt;
&lt;br /&gt;
To make the code more manageable and easier to follow, it made sense to break up the responsibilities of this single &amp;lt;code&amp;gt;MailWorker&amp;lt;/code&amp;gt; class into multiple workers:&lt;br /&gt;
* &amp;lt;code&amp;gt;SimicheckWorker&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;DropOutstandingReviewsWorker&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;MailWorker&amp;lt;/code&amp;gt;&lt;br /&gt;
All three workers extended an &amp;quot;abstract class&amp;quot; called &amp;lt;code&amp;gt;Worker&amp;lt;/code&amp;gt; that contained the Sidekiq-related &amp;lt;code&amp;gt;include&amp;lt;/code&amp;gt; and the queue name to which all jobs would be sent.&lt;br /&gt;
&lt;br /&gt;
For simplicity, we still had all new workers continue to use a single queue, which we renamed from &amp;lt;code&amp;gt;mailers&amp;lt;/code&amp;gt; to &amp;lt;code&amp;gt;jobs&amp;lt;/code&amp;gt;. A future improvement could divide these jobs to go to multiple different queues if needed.&lt;br /&gt;
&lt;br /&gt;
=== Remove all code related to the &amp;lt;code&amp;gt;drop_one_member_topics&amp;lt;/code&amp;gt; deadline type ===&lt;br /&gt;
It was decided that code used for dropping one member or two member teams from topics would never need to be implemented in the Expertiza website. Thus, we removed all code related to the drop_one_member_topics method within the Expertiza beta. This involved removing the &amp;lt;code&amp;gt;drop_one_member_topics&amp;lt;/code&amp;gt; function from &amp;lt;code&amp;gt;drop_outstanding_reviews_mail_worker.rb&amp;lt;/code&amp;gt;, now renamed &amp;lt;code&amp;gt;drop_outstanding_reviews_worker.rb&amp;lt;/code&amp;gt;. The &amp;lt;code&amp;gt;drop_one_member_topics&amp;lt;/code&amp;gt; method was called from the &amp;lt;code&amp;gt;prepare_data&amp;lt;/code&amp;gt; method, which was then called by the Sidekiq method &amp;lt;code&amp;gt;perform&amp;lt;/code&amp;gt; so we removed this call. The &amp;lt;code&amp;gt;drop_one_member_topics&amp;lt;/code&amp;gt; was also referenced in &amp;lt;code&amp;gt;assignment_form.rb&amp;lt;/code&amp;gt; using &amp;lt;code&amp;gt;add_delayed_job&amp;lt;/code&amp;gt; in the &amp;lt;code&amp;gt;add_to_delayed_queue&amp;lt;/code&amp;gt; method and in &amp;lt;code&amp;gt;delayed_mailer.html.erb&amp;lt;/code&amp;gt; as an option for the handler so both of these code snippets were removed as well.&lt;br /&gt;
&lt;br /&gt;
=== Code Cleanup ===&lt;br /&gt;
Smaller improvements done while implementing the main tasks included:&lt;br /&gt;
* Using ActiveSupport::Duration objects in order to calculate the minutes and seconds related to the dequeue times&lt;br /&gt;
* Refactoring the time calculations for the dequeue times to the DueDate class&lt;br /&gt;
* Correcting the parameters passed to the workers, which were previously incorrect. As an example:&lt;br /&gt;
&amp;lt;blockquote&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def add_delayed_job(_assignment, deadline_type, due_date, min_left)&lt;br /&gt;
    delayed_job_id = MailWorker.perform_in(min_left * 60, due_date.parent_id, deadline_type, due_date.due_at)&lt;br /&gt;
    delayed_job_id&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
The first parameter after the time delay must be assignment ID, and &amp;lt;code&amp;gt;due_date.parent_id&amp;lt;/code&amp;gt; is not an assignment ID.&lt;br /&gt;
&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
* Removing whitespace issues reported by codeclimate&lt;br /&gt;
* Refactoring all variable names to be in snake_case&lt;br /&gt;
* Removing identical blocks of code&lt;br /&gt;
* Adding method comments to make methods more understandable&lt;br /&gt;
&lt;br /&gt;
== Test Plan ==&lt;br /&gt;
&lt;br /&gt;
=== Unit Tests ===&lt;br /&gt;
In order to properly test that our refactoring had worked properly, we found that we would have to add in multiple tests to account for our new methods as well as refactor old tests to work with the changes that we had made. &lt;br /&gt;
&lt;br /&gt;
=== Functional Tests ===&lt;br /&gt;
We decided that functional testing would need to be done by manually checking to see if Sidekiq tasks were queued as expected when changes to assignments were made. The three important functional tests that we decided needed to be verified were that the Simicheck Worker was queuing, the Mail Worker was queueing, and the Drop Outstanding Reviews Worker was queuing. These could be considered verified under the condition that the '''When''' field, '''Job''' field, and '''Arguments''' field in the Sidekiq view all came out as expected.&lt;br /&gt;
&lt;br /&gt;
=== Considering Edge Cases and Other Possibilities ===&lt;br /&gt;
&lt;br /&gt;
== Implementing Test Plan ==&lt;br /&gt;
&lt;br /&gt;
=== Update and add unit tests according to the refactoring changes made  ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Test all new worker classes to ensure Sidekiq jobs were being dequeued and run as expected ===&lt;br /&gt;
==== Sidekiq setup ====&lt;br /&gt;
In order to test the Sidekiq workers, a few steps were needed to set up the workers and run Sidekiq (steps were obtained from [https://tudip.com/blog-post/how-to-use-sidekiq-in-rails-for-background-processing/ this site]):&lt;br /&gt;
# Initialize three new workers, each having one of the three new worker types:&lt;br /&gt;
## &amp;lt;code&amp;gt;rails g sidekiq:worker SimicheckWorker&amp;lt;/code&amp;gt;&lt;br /&gt;
## &amp;lt;code&amp;gt;rails g sidekiq:worker DropOutstandingReviewsWorker&amp;lt;/code&amp;gt;&lt;br /&gt;
## &amp;lt;code&amp;gt;rails g sidekiq:worker MailWorker&amp;lt;/code&amp;gt;&lt;br /&gt;
# In a terminal separate from the one in which the main rails application is running, run&lt;br /&gt;
&amp;lt;blockquote&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
bundle exec sidekiq&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This Sidekiq-specific terminal will show logs and printed statements from the workers.&lt;br /&gt;
&lt;br /&gt;
==== SimicheckWorker Test ====&lt;br /&gt;
To enqueue a Simicheck job:&lt;br /&gt;
# Edit an assignment.&lt;br /&gt;
# Select the &amp;lt;code&amp;gt;Use simicheck?&amp;lt;/code&amp;gt; box.&lt;br /&gt;
# Set &amp;lt;code&amp;gt;Simicheck Delay&amp;lt;/code&amp;gt; to &amp;lt;code&amp;gt;0&amp;lt;/code&amp;gt; (or to a nonzero value to observe a delay).&lt;br /&gt;
# Set the SimiCheck Similarity Threshold to a nonzero value.&lt;br /&gt;
# Click &amp;lt;code&amp;gt;Save&amp;lt;/code&amp;gt;.&lt;br /&gt;
# Observe a Simicheck Worker job enqueued and dequeued in the Sidekiq UI.&lt;br /&gt;
&lt;br /&gt;
[[File:Enqueue-simicheck-job.png|500px|How to Enqueue a Simicheck Worker Job]]&lt;br /&gt;
&lt;br /&gt;
==== MailWorker and DropOustandingReviews Test ====&lt;br /&gt;
The Mail Worker sends out notifications to students if the due date of an assignment is changed. Drop Outstanding Reviews Worker drops all reviews that had not been worked on before the due date was changed. These both can be tested together, as when an assignment with a review is updated, Sidekiq should queue both the jobs for Mail Worker and Drop Outstanding Reviews Worker. To test these:&lt;br /&gt;
# Log into Expertiza as an instructor&lt;br /&gt;
# Navigate to '''Manage'''&amp;gt;'''Assignments''' in the navigation&lt;br /&gt;
# Click the plus button in the top right corner on the '''Manage Assignments''' and create an assignment with default settings. Make sure when creating the assignment to go to the '''Due Dates''' tab and assign due dates for both the assignment and the review. &lt;br /&gt;
# Assign student7613 to the assignment you created by clicking the person with the plus icon in the icons next to the assignment on the '''Manage Assignments''' page. &lt;br /&gt;
&lt;br /&gt;
At this point, we realized we need to alter the code to test if the code was properly queuing the Mail Worker because the current if statement to add items to the delayed queue required that it have a late policy. However, the late policy code is not currently working. Thus, in the &amp;lt;code&amp;gt;assignment_form.rb&amp;lt;/code&amp;gt; model file, we edited the following code:&lt;br /&gt;
&lt;br /&gt;
[[File:Change_late_policy.png|950px|Late policy code to alter]]&lt;br /&gt;
&lt;br /&gt;
We removed &amp;lt;code&amp;gt;and has_late_policy&amp;lt;/code&amp;gt; so &amp;lt;code&amp;gt;add_delayed_queue&amp;lt;/code&amp;gt; can run even without late policies being implemented. After saving this file, we started up Expertiza again.&lt;br /&gt;
&amp;lt;ol start=&amp;quot;5&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; Go to the assignment that student7613 had been assigned to &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; Edit the assignment, go to the due dates tab, and change the due date on the review to be a day ahead of its current due date, and press save. Note: The assignment due date must be changed to a time at least an hour ahead of the current time for the reminder to be sent. &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; To ensure that the assignments are now queued on Sidekiq, visit the Sidekiq UI by going to [Expertiza VCL URL]/sidekiq. &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; Upon arriving on this page, verify that the jobs added to the queue were correct by clicking to '''Scheduled'''. After arriving on this page, you should see something like the following: &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ol&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[File:Sidekiq-jobs.png|950px|Sidekiq jobs]]&lt;br /&gt;
&lt;br /&gt;
The job '''MailWorker''' that had been queued successfully shows that our refactoring of Mail Worker had worked properly and the Mail Worker was operational. The job '''DropOutstandingReviewsWorker''' showed that our refactoring of Drop Outstanding Reviews Worker had also been done correctly.&lt;br /&gt;
&lt;br /&gt;
=== Sidekiq UI ===&lt;br /&gt;
To see which messages were being enqueued and dequeued in Sidekiq, we use the Sidekiq user interface, which can be accessed via the &amp;lt;code&amp;gt;/sidekiq&amp;lt;/code&amp;gt; route of the application.&lt;br /&gt;
[[File:Sidekiq-ui.png|950px|The Sidekiq UI]]&lt;/div&gt;</summary>
		<author><name>Agcarrut</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2021_-_E2144._Refactor_delayed_mailer_and_scheduled_task&amp;diff=140169</id>
		<title>CSC/ECE 517 Fall 2021 - E2144. Refactor delayed mailer and scheduled task</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2021_-_E2144._Refactor_delayed_mailer_and_scheduled_task&amp;diff=140169"/>
		<updated>2021-10-27T01:25:09Z</updated>

		<summary type="html">&lt;p&gt;Agcarrut: /* MailWorker and DropOustandingReviews Test */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;__TOC__&lt;br /&gt;
&lt;br /&gt;
== Background ==&lt;br /&gt;
This project revolves around the Sidekiq gem for asynchronous processing of email tasks. It has a queue system to hold and then process jobs. Sidekiq’s queue replaces DelayedMailer’s queue. The previous team that worked on this also created a method &amp;lt;code&amp;gt;perform()&amp;lt;/code&amp;gt; to gather email IDs of all participants in an assignment and send them an email reminder. Some test cases exist for this work.&lt;br /&gt;
&lt;br /&gt;
=== Previous Setup ===&lt;br /&gt;
Initial work can be found [https://expertiza.csc.ncsu.edu/index.php/E1835_Refactor_delayed_mailer_and_scheduled_task here].&lt;br /&gt;
&lt;br /&gt;
Code in the [https://github.com/expertiza/expertiza/pull/1245/files pull request] was found to be reasonable and working. The method &amp;lt;code&amp;gt;perform()&amp;lt;/code&amp;gt; has:&lt;br /&gt;
{| class=wikitable style=text-align:right&lt;br /&gt;
|+ Metrics for &amp;lt;code&amp;gt;perform&amp;lt;/code&amp;gt; method&lt;br /&gt;
|-&lt;br /&gt;
! Metric !! Current Value !! Limit&lt;br /&gt;
|-&lt;br /&gt;
! Cognitive Complexity&lt;br /&gt;
| 15 || 5&lt;br /&gt;
|-&lt;br /&gt;
! Cyclomatic Complexity&lt;br /&gt;
| 8 || 6&lt;br /&gt;
|-&lt;br /&gt;
! Assignment Branch Condition size&lt;br /&gt;
| 22.93 || 15&lt;br /&gt;
|-&lt;br /&gt;
! Perceived complexity&lt;br /&gt;
| 10 || 7&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Previous pull request also has duplicated commit messages and the commits need to be squashed.&lt;br /&gt;
&lt;br /&gt;
Files involved (some changed should not have been changed):&lt;br /&gt;
* app/controllers/assignments_controller.rb&lt;br /&gt;
* app/mailers/mail_worker.rb&lt;br /&gt;
* app/models/assignment_form.rb&lt;br /&gt;
* config/sidekiq.yml&lt;br /&gt;
* spec/models/assignment_form_spec.rb&lt;br /&gt;
* spec/sidekiq_mail_worker_spec.rb&lt;br /&gt;
* spec/spec_helper.rb&lt;br /&gt;
&lt;br /&gt;
There are minor styling issues such as missing or trailing whitespaces, lines that are too long, extra empty line, unused arguments.&lt;br /&gt;
&lt;br /&gt;
=== Problem Statement ===&lt;br /&gt;
&lt;br /&gt;
This project revolves around the Sidekiq gem for asynchronous processing of email tasks. It has a queue system to hold and then process jobs. Sidekiq's queue replaces DelayedMailer’s queue. The previous team that worked on this also created a method perform() to gather email IDs of all participants in an assignment and send them an email reminder. Some test cases exist for this work.&lt;br /&gt;
The project was partially merged.&lt;br /&gt;
​&lt;br /&gt;
&lt;br /&gt;
What needs to be done:  &lt;br /&gt;
Feedback from the previous team (E1835) is:&lt;br /&gt;
Code in pull request seems pretty reasonable.  Some concerns wrt. naming functions, but otherwise reviewers seem to agree that the code is good.&lt;br /&gt;
​&lt;br /&gt;
&lt;br /&gt;
Your pull request has many duplicated commit messages. Please try to &amp;lt;code&amp;gt;squash&amp;lt;/code&amp;gt; similar commits.&lt;br /&gt;
And using meaningful commit messages later.&lt;br /&gt;
​&lt;br /&gt;
&lt;br /&gt;
You should commit changes to the DB schema (&amp;lt;code&amp;gt;db/schema.rb&amp;lt;/code&amp;gt;) only if you have created new DB migrations.&lt;br /&gt;
Please double check your code. If you did not aim to change the DB, please revert the DB schema changes. ***** Important, try not to change the DB.&lt;br /&gt;
​&lt;br /&gt;
&lt;br /&gt;
You should not change &amp;lt;code&amp;gt;rails_helper.rb&amp;lt;/code&amp;gt; or &amp;lt;code&amp;gt;spec_helper.rb&amp;lt;/code&amp;gt; file; please revert these changes.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The previous team’s code needs a refactor in some places, though the actual function of it seems solid. It is very possible that in the three years since this code has been worked on, more mailer functionality has been added. There are other teams this semester working on mailer code as well. Try to keep your code as contained and simple as possible, so that merging these projects is possible.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Summary of Work Needed ==&lt;br /&gt;
After discussing with our project mentor and Dr. Gehringer, we determined the main tasks to be the following:&lt;br /&gt;
# Refactor the single Sidekiq worker into multiple workers&lt;br /&gt;
# Remove all code related to the &amp;lt;code&amp;gt;drop_one_member_topics&amp;lt;/code&amp;gt; deadline type&lt;br /&gt;
# Update and add unit tests according to the above changes&lt;br /&gt;
# Test all new worker classes to ensure Sidekiq jobs were being dequeued and run as expected&lt;br /&gt;
# Code cleanup&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Refactor the single Sidekiq worker into multiple workers ===&lt;br /&gt;
Previously there was only a single worker class that handled all types of jobs. Its top-level method &amp;lt;code&amp;gt;perform&amp;lt;/code&amp;gt; looked like the following.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def perform(assignment_id, deadline_type, due_at)&lt;br /&gt;
    self.assignment_id = assignment_id&lt;br /&gt;
    self.deadline_type = deadline_type&lt;br /&gt;
    self.due_at = due_at&lt;br /&gt;
&lt;br /&gt;
    assignment = Assignment.find(self.assignment_id)&lt;br /&gt;
    participant_mails = find_participant_emails&lt;br /&gt;
&lt;br /&gt;
    if %w[drop_one_member_topics drop_outstanding_reviews compare_files_with_simicheck].include?(self.deadline_type)&lt;br /&gt;
      drop_one_member_topics if self.deadline_type == &amp;quot;drop_outstanding_reviews&amp;quot; &amp;amp;&amp;amp; assignment.team_assignment&lt;br /&gt;
      drop_outstanding_reviews if self.deadline_type == &amp;quot;drop_outstanding_reviews&amp;quot;&lt;br /&gt;
      perform_simicheck_comparisons(self.assignment_id) if self.deadline_type == &amp;quot;compare_files_with_simicheck&amp;quot;&lt;br /&gt;
    else&lt;br /&gt;
      # Can we rename deadline_type(metareview) to &amp;quot;teammate review&amp;quot;. If, yes then we donot need this if clause below!&lt;br /&gt;
      deadlineText = if self.deadline_type == &amp;quot;metareview&amp;quot;&lt;br /&gt;
                       &amp;quot;teammate review&amp;quot;&lt;br /&gt;
                     else&lt;br /&gt;
                       self.deadline_type&lt;br /&gt;
      end&lt;br /&gt;
&lt;br /&gt;
      email_reminder(participant_mails, deadlineText) unless participant_mails.empty?&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The processing was different depending on the &amp;lt;code&amp;gt;deadline_type&amp;lt;/code&amp;gt;. The &amp;lt;code&amp;gt;deadline_type&amp;lt;/code&amp;gt;s in&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
%w[drop_one_member_topics drop_outstanding_reviews compare_files_with_simicheck]&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
did not lead to an email reminder being sent, but they were still handled in this &amp;lt;code&amp;gt;MailWorker&amp;lt;/code&amp;gt; class.&lt;br /&gt;
&lt;br /&gt;
To make the code more manageable and easier to follow, it made sense to break up the responsibilities of this single &amp;lt;code&amp;gt;MailWorker&amp;lt;/code&amp;gt; class into multiple workers:&lt;br /&gt;
* &amp;lt;code&amp;gt;SimicheckWorker&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;DropOutstandingReviewsWorker&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;MailWorker&amp;lt;/code&amp;gt;&lt;br /&gt;
All three workers extended an &amp;quot;abstract class&amp;quot; called &amp;lt;code&amp;gt;Worker&amp;lt;/code&amp;gt; that contained the Sidekiq-related &amp;lt;code&amp;gt;include&amp;lt;/code&amp;gt; and the queue name to which all jobs would be sent.&lt;br /&gt;
&lt;br /&gt;
For simplicity, we still had all new workers continue to use a single queue, which we renamed from &amp;lt;code&amp;gt;mailers&amp;lt;/code&amp;gt; to &amp;lt;code&amp;gt;jobs&amp;lt;/code&amp;gt;. A future improvement could divide these jobs to go to multiple different queues if needed.&lt;br /&gt;
&lt;br /&gt;
=== Remove all code related to the &amp;lt;code&amp;gt;drop_one_member_topics&amp;lt;/code&amp;gt; deadline type ===&lt;br /&gt;
It was decided that code used for dropping one member or two member teams from topics would never need to be implemented in the Expertiza website. Thus, we removed all code related to the drop_one_member_topics method within the Expertiza beta. This involved removing the &amp;lt;code&amp;gt;drop_one_member_topics&amp;lt;/code&amp;gt; function from &amp;lt;code&amp;gt;drop_outstanding_reviews_mail_worker.rb&amp;lt;/code&amp;gt;, now renamed &amp;lt;code&amp;gt;drop_outstanding_reviews_worker.rb&amp;lt;/code&amp;gt;. The &amp;lt;code&amp;gt;drop_one_member_topics&amp;lt;/code&amp;gt; method was called from the &amp;lt;code&amp;gt;prepare_data&amp;lt;/code&amp;gt; method, which was then called by the Sidekiq method &amp;lt;code&amp;gt;perform&amp;lt;/code&amp;gt; so we removed this call. The &amp;lt;code&amp;gt;drop_one_member_topics&amp;lt;/code&amp;gt; was also referenced in &amp;lt;code&amp;gt;assignment_form.rb&amp;lt;/code&amp;gt; using &amp;lt;code&amp;gt;add_delayed_job&amp;lt;/code&amp;gt; in the &amp;lt;code&amp;gt;add_to_delayed_queue&amp;lt;/code&amp;gt; method and in &amp;lt;code&amp;gt;delayed_mailer.html.erb&amp;lt;/code&amp;gt; as an option for the handler so both of these code snippets were removed as well.&lt;br /&gt;
&lt;br /&gt;
=== Code Cleanup ===&lt;br /&gt;
Smaller improvements done while implementing the main tasks included:&lt;br /&gt;
* Using ActiveSupport::Duration objects in order to calculate the minutes and seconds related to the dequeue times&lt;br /&gt;
* Refactoring the time calculations for the dequeue times to the DueDate class&lt;br /&gt;
* Correcting the parameters passed to the workers, which were previously incorrect. As an example:&lt;br /&gt;
&amp;lt;blockquote&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def add_delayed_job(_assignment, deadline_type, due_date, min_left)&lt;br /&gt;
    delayed_job_id = MailWorker.perform_in(min_left * 60, due_date.parent_id, deadline_type, due_date.due_at)&lt;br /&gt;
    delayed_job_id&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
The first parameter after the time delay must be assignment ID, and &amp;lt;code&amp;gt;due_date.parent_id&amp;lt;/code&amp;gt; is not an assignment ID.&lt;br /&gt;
&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
* Removing whitespace issues reported by codeclimate&lt;br /&gt;
* Refactoring all variable names to be in snake_case&lt;br /&gt;
* Removing identical blocks of code&lt;br /&gt;
* Adding method comments to make methods more understandable&lt;br /&gt;
&lt;br /&gt;
== Test Plan ==&lt;br /&gt;
&lt;br /&gt;
=== Unit Tests ===&lt;br /&gt;
In order to properly test that our refactoring had worked properly, we found that we would have to add in multiple tests to account for our new methods as well as refactor old tests to work with the changes that we had made. &lt;br /&gt;
&lt;br /&gt;
=== Functional Tests ===&lt;br /&gt;
We decided that functional testing would need to be done by manually checking to see if Sidekiq tasks were queued as expected when changes to assignments were made. The three important functional tests that we decided needed to be verified were that the Simicheck Worker was queuing, the Mail Worker was queueing, and the Drop Outstanding Reviews Worker was queuing. These could be considered verified under the condition that the '''When''' field, '''Job''' field, and '''Arguments''' field in the Sidekiq view all came out as expected.&lt;br /&gt;
&lt;br /&gt;
=== Considering Edge Cases and Other Possibilities ===&lt;br /&gt;
&lt;br /&gt;
== Implementing Test Plan ==&lt;br /&gt;
&lt;br /&gt;
=== Update and add unit tests according to the refactoring changes made  ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Test all new worker classes to ensure Sidekiq jobs were being dequeued and run as expected ===&lt;br /&gt;
==== Sidekiq setup ====&lt;br /&gt;
In order to test the Sidekiq workers, a few steps were needed to set up the workers and run Sidekiq (steps were obtained from [https://tudip.com/blog-post/how-to-use-sidekiq-in-rails-for-background-processing/ this site]):&lt;br /&gt;
# Initialize three new workers, each having one of the three new worker types:&lt;br /&gt;
## &amp;lt;code&amp;gt;rails g sidekiq:worker SimicheckWorker&amp;lt;/code&amp;gt;&lt;br /&gt;
## &amp;lt;code&amp;gt;rails g sidekiq:worker DropOutstandingReviewsWorker&amp;lt;/code&amp;gt;&lt;br /&gt;
## &amp;lt;code&amp;gt;rails g sidekiq:worker MailWorker&amp;lt;/code&amp;gt;&lt;br /&gt;
# In a terminal separate from the one in which the main rails application is running, run&lt;br /&gt;
&amp;lt;blockquote&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
bundle exec sidekiq&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This Sidekiq-specific terminal will show logs and printed statements from the workers.&lt;br /&gt;
&lt;br /&gt;
==== SimicheckWorker Test ====&lt;br /&gt;
To enqueue a Simicheck job:&lt;br /&gt;
# Edit an assignment.&lt;br /&gt;
# Select the &amp;lt;code&amp;gt;Use simicheck?&amp;lt;/code&amp;gt; box.&lt;br /&gt;
# Set &amp;lt;code&amp;gt;Simicheck Delay&amp;lt;/code&amp;gt; to &amp;lt;code&amp;gt;0&amp;lt;/code&amp;gt; (or to a nonzero value to observe a delay).&lt;br /&gt;
# Set the SimiCheck Similarity Threshold to a nonzero value.&lt;br /&gt;
# Click &amp;lt;code&amp;gt;Save&amp;lt;/code&amp;gt;.&lt;br /&gt;
# Observe a Simicheck Worker job enqueued and dequeued in the Sidekiq UI.&lt;br /&gt;
&lt;br /&gt;
[[File:Enqueue-simicheck-job.png|500px|How to Enqueue a Simicheck Worker Job]]&lt;br /&gt;
&lt;br /&gt;
==== MailWorker and DropOustandingReviews Test ====&lt;br /&gt;
The Mail Worker sends out notifications to students if the due date of an assignment is changed. Drop Outstanding Reviews Worker drops all reviews that had not been worked on before the due date was changed. These both can be tested together, as when an assignment with a review is updated, Sidekiq should queue both the jobs for Mail Worker and Drop Outstanding Reviews Worker. To test these:&lt;br /&gt;
# Log into Expertiza as an instructor&lt;br /&gt;
# Navigate to '''Manage'''&amp;gt;'''Assignments''' in the navigation&lt;br /&gt;
# Click the plus button in the top right corner on the '''Manage Assignments''' and create an assignment with default settings. Make sure when creating the assignment to go to the '''Due Dates''' tab and assign due dates for both the assignment and the review. &lt;br /&gt;
# Assign student7613 to the assignment you created by clicking the person with the plus icon in the icons next to the assignment on the '''Manage Assignments''' page. &lt;br /&gt;
&lt;br /&gt;
At this point, we realized we need to alter the code to test if the code was properly queuing the Mail Worker because the current if statement to add items to the delayed queue required that it have a late policy. However, the late policy code is not currently working. Thus, in the &amp;lt;code&amp;gt;assignment_form.rb&amp;lt;/code&amp;gt; model file, we edited the following code:&lt;br /&gt;
&lt;br /&gt;
[[File:Change_late_policy.png|950px|Late policy code to alter]]&lt;br /&gt;
&lt;br /&gt;
We removed &amp;lt;code&amp;gt;and has_late_policy&amp;lt;/code&amp;gt; so &amp;lt;code&amp;gt;add_delayed_queue&amp;lt;/code&amp;gt; can run even without late policies being implemented. After saving this file, we started up Expertiza again.&lt;br /&gt;
5. Go to the assignment that student7613 had been assigned to.&lt;br /&gt;
&lt;br /&gt;
6. Edit the assignment, go to the due dates tab, and change the due date on the review to be a day ahead of its current due date, and press save. Note: The assignment due date must be changed to a time at least an hour ahead of the current time for the reminder to be sent.&lt;br /&gt;
&lt;br /&gt;
7. To ensure that the assignments are now queued on Sidekiq, visit the Sidekiq UI by going to [Expertiza VCL URL]/sidekiq.&lt;br /&gt;
&lt;br /&gt;
8. Upon arriving on this page, verify that the jobs added to the queue were correct by clicking to '''Scheduled'''. After arriving on this page, you should see something like the following:&lt;br /&gt;
&lt;br /&gt;
[[File:Sidekiq-jobs.png|950px|Sidekiq jobs]]&lt;br /&gt;
&lt;br /&gt;
The job '''MailWorker''' that had been queued successfully shows that our refactoring of Mail Worker had worked properly and the Mail Worker was operational. The job '''DropOutstandingReviewsWorker''' showed that our refactoring of Drop Outstanding Reviews Worker had also been done correctly.&lt;br /&gt;
&lt;br /&gt;
=== Sidekiq UI ===&lt;br /&gt;
To see which messages were being enqueued and dequeued in Sidekiq, we use the Sidekiq user interface, which can be accessed via the &amp;lt;code&amp;gt;/sidekiq&amp;lt;/code&amp;gt; route of the application.&lt;br /&gt;
[[File:Sidekiq-ui.png|950px|The Sidekiq UI]]&lt;/div&gt;</summary>
		<author><name>Agcarrut</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2021_-_E2144._Refactor_delayed_mailer_and_scheduled_task&amp;diff=140168</id>
		<title>CSC/ECE 517 Fall 2021 - E2144. Refactor delayed mailer and scheduled task</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2021_-_E2144._Refactor_delayed_mailer_and_scheduled_task&amp;diff=140168"/>
		<updated>2021-10-27T01:24:49Z</updated>

		<summary type="html">&lt;p&gt;Agcarrut: /* MailWorker and DropOustandingReviews Test */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;__TOC__&lt;br /&gt;
&lt;br /&gt;
== Background ==&lt;br /&gt;
This project revolves around the Sidekiq gem for asynchronous processing of email tasks. It has a queue system to hold and then process jobs. Sidekiq’s queue replaces DelayedMailer’s queue. The previous team that worked on this also created a method &amp;lt;code&amp;gt;perform()&amp;lt;/code&amp;gt; to gather email IDs of all participants in an assignment and send them an email reminder. Some test cases exist for this work.&lt;br /&gt;
&lt;br /&gt;
=== Previous Setup ===&lt;br /&gt;
Initial work can be found [https://expertiza.csc.ncsu.edu/index.php/E1835_Refactor_delayed_mailer_and_scheduled_task here].&lt;br /&gt;
&lt;br /&gt;
Code in the [https://github.com/expertiza/expertiza/pull/1245/files pull request] was found to be reasonable and working. The method &amp;lt;code&amp;gt;perform()&amp;lt;/code&amp;gt; has:&lt;br /&gt;
{| class=wikitable style=text-align:right&lt;br /&gt;
|+ Metrics for &amp;lt;code&amp;gt;perform&amp;lt;/code&amp;gt; method&lt;br /&gt;
|-&lt;br /&gt;
! Metric !! Current Value !! Limit&lt;br /&gt;
|-&lt;br /&gt;
! Cognitive Complexity&lt;br /&gt;
| 15 || 5&lt;br /&gt;
|-&lt;br /&gt;
! Cyclomatic Complexity&lt;br /&gt;
| 8 || 6&lt;br /&gt;
|-&lt;br /&gt;
! Assignment Branch Condition size&lt;br /&gt;
| 22.93 || 15&lt;br /&gt;
|-&lt;br /&gt;
! Perceived complexity&lt;br /&gt;
| 10 || 7&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Previous pull request also has duplicated commit messages and the commits need to be squashed.&lt;br /&gt;
&lt;br /&gt;
Files involved (some changed should not have been changed):&lt;br /&gt;
* app/controllers/assignments_controller.rb&lt;br /&gt;
* app/mailers/mail_worker.rb&lt;br /&gt;
* app/models/assignment_form.rb&lt;br /&gt;
* config/sidekiq.yml&lt;br /&gt;
* spec/models/assignment_form_spec.rb&lt;br /&gt;
* spec/sidekiq_mail_worker_spec.rb&lt;br /&gt;
* spec/spec_helper.rb&lt;br /&gt;
&lt;br /&gt;
There are minor styling issues such as missing or trailing whitespaces, lines that are too long, extra empty line, unused arguments.&lt;br /&gt;
&lt;br /&gt;
=== Problem Statement ===&lt;br /&gt;
&lt;br /&gt;
This project revolves around the Sidekiq gem for asynchronous processing of email tasks. It has a queue system to hold and then process jobs. Sidekiq's queue replaces DelayedMailer’s queue. The previous team that worked on this also created a method perform() to gather email IDs of all participants in an assignment and send them an email reminder. Some test cases exist for this work.&lt;br /&gt;
The project was partially merged.&lt;br /&gt;
​&lt;br /&gt;
&lt;br /&gt;
What needs to be done:  &lt;br /&gt;
Feedback from the previous team (E1835) is:&lt;br /&gt;
Code in pull request seems pretty reasonable.  Some concerns wrt. naming functions, but otherwise reviewers seem to agree that the code is good.&lt;br /&gt;
​&lt;br /&gt;
&lt;br /&gt;
Your pull request has many duplicated commit messages. Please try to &amp;lt;code&amp;gt;squash&amp;lt;/code&amp;gt; similar commits.&lt;br /&gt;
And using meaningful commit messages later.&lt;br /&gt;
​&lt;br /&gt;
&lt;br /&gt;
You should commit changes to the DB schema (&amp;lt;code&amp;gt;db/schema.rb&amp;lt;/code&amp;gt;) only if you have created new DB migrations.&lt;br /&gt;
Please double check your code. If you did not aim to change the DB, please revert the DB schema changes. ***** Important, try not to change the DB.&lt;br /&gt;
​&lt;br /&gt;
&lt;br /&gt;
You should not change &amp;lt;code&amp;gt;rails_helper.rb&amp;lt;/code&amp;gt; or &amp;lt;code&amp;gt;spec_helper.rb&amp;lt;/code&amp;gt; file; please revert these changes.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The previous team’s code needs a refactor in some places, though the actual function of it seems solid. It is very possible that in the three years since this code has been worked on, more mailer functionality has been added. There are other teams this semester working on mailer code as well. Try to keep your code as contained and simple as possible, so that merging these projects is possible.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Summary of Work Needed ==&lt;br /&gt;
After discussing with our project mentor and Dr. Gehringer, we determined the main tasks to be the following:&lt;br /&gt;
# Refactor the single Sidekiq worker into multiple workers&lt;br /&gt;
# Remove all code related to the &amp;lt;code&amp;gt;drop_one_member_topics&amp;lt;/code&amp;gt; deadline type&lt;br /&gt;
# Update and add unit tests according to the above changes&lt;br /&gt;
# Test all new worker classes to ensure Sidekiq jobs were being dequeued and run as expected&lt;br /&gt;
# Code cleanup&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Refactor the single Sidekiq worker into multiple workers ===&lt;br /&gt;
Previously there was only a single worker class that handled all types of jobs. Its top-level method &amp;lt;code&amp;gt;perform&amp;lt;/code&amp;gt; looked like the following.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def perform(assignment_id, deadline_type, due_at)&lt;br /&gt;
    self.assignment_id = assignment_id&lt;br /&gt;
    self.deadline_type = deadline_type&lt;br /&gt;
    self.due_at = due_at&lt;br /&gt;
&lt;br /&gt;
    assignment = Assignment.find(self.assignment_id)&lt;br /&gt;
    participant_mails = find_participant_emails&lt;br /&gt;
&lt;br /&gt;
    if %w[drop_one_member_topics drop_outstanding_reviews compare_files_with_simicheck].include?(self.deadline_type)&lt;br /&gt;
      drop_one_member_topics if self.deadline_type == &amp;quot;drop_outstanding_reviews&amp;quot; &amp;amp;&amp;amp; assignment.team_assignment&lt;br /&gt;
      drop_outstanding_reviews if self.deadline_type == &amp;quot;drop_outstanding_reviews&amp;quot;&lt;br /&gt;
      perform_simicheck_comparisons(self.assignment_id) if self.deadline_type == &amp;quot;compare_files_with_simicheck&amp;quot;&lt;br /&gt;
    else&lt;br /&gt;
      # Can we rename deadline_type(metareview) to &amp;quot;teammate review&amp;quot;. If, yes then we donot need this if clause below!&lt;br /&gt;
      deadlineText = if self.deadline_type == &amp;quot;metareview&amp;quot;&lt;br /&gt;
                       &amp;quot;teammate review&amp;quot;&lt;br /&gt;
                     else&lt;br /&gt;
                       self.deadline_type&lt;br /&gt;
      end&lt;br /&gt;
&lt;br /&gt;
      email_reminder(participant_mails, deadlineText) unless participant_mails.empty?&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The processing was different depending on the &amp;lt;code&amp;gt;deadline_type&amp;lt;/code&amp;gt;. The &amp;lt;code&amp;gt;deadline_type&amp;lt;/code&amp;gt;s in&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
%w[drop_one_member_topics drop_outstanding_reviews compare_files_with_simicheck]&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
did not lead to an email reminder being sent, but they were still handled in this &amp;lt;code&amp;gt;MailWorker&amp;lt;/code&amp;gt; class.&lt;br /&gt;
&lt;br /&gt;
To make the code more manageable and easier to follow, it made sense to break up the responsibilities of this single &amp;lt;code&amp;gt;MailWorker&amp;lt;/code&amp;gt; class into multiple workers:&lt;br /&gt;
* &amp;lt;code&amp;gt;SimicheckWorker&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;DropOutstandingReviewsWorker&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;MailWorker&amp;lt;/code&amp;gt;&lt;br /&gt;
All three workers extended an &amp;quot;abstract class&amp;quot; called &amp;lt;code&amp;gt;Worker&amp;lt;/code&amp;gt; that contained the Sidekiq-related &amp;lt;code&amp;gt;include&amp;lt;/code&amp;gt; and the queue name to which all jobs would be sent.&lt;br /&gt;
&lt;br /&gt;
For simplicity, we still had all new workers continue to use a single queue, which we renamed from &amp;lt;code&amp;gt;mailers&amp;lt;/code&amp;gt; to &amp;lt;code&amp;gt;jobs&amp;lt;/code&amp;gt;. A future improvement could divide these jobs to go to multiple different queues if needed.&lt;br /&gt;
&lt;br /&gt;
=== Remove all code related to the &amp;lt;code&amp;gt;drop_one_member_topics&amp;lt;/code&amp;gt; deadline type ===&lt;br /&gt;
It was decided that code used for dropping one member or two member teams from topics would never need to be implemented in the Expertiza website. Thus, we removed all code related to the drop_one_member_topics method within the Expertiza beta. This involved removing the &amp;lt;code&amp;gt;drop_one_member_topics&amp;lt;/code&amp;gt; function from &amp;lt;code&amp;gt;drop_outstanding_reviews_mail_worker.rb&amp;lt;/code&amp;gt;, now renamed &amp;lt;code&amp;gt;drop_outstanding_reviews_worker.rb&amp;lt;/code&amp;gt;. The &amp;lt;code&amp;gt;drop_one_member_topics&amp;lt;/code&amp;gt; method was called from the &amp;lt;code&amp;gt;prepare_data&amp;lt;/code&amp;gt; method, which was then called by the Sidekiq method &amp;lt;code&amp;gt;perform&amp;lt;/code&amp;gt; so we removed this call. The &amp;lt;code&amp;gt;drop_one_member_topics&amp;lt;/code&amp;gt; was also referenced in &amp;lt;code&amp;gt;assignment_form.rb&amp;lt;/code&amp;gt; using &amp;lt;code&amp;gt;add_delayed_job&amp;lt;/code&amp;gt; in the &amp;lt;code&amp;gt;add_to_delayed_queue&amp;lt;/code&amp;gt; method and in &amp;lt;code&amp;gt;delayed_mailer.html.erb&amp;lt;/code&amp;gt; as an option for the handler so both of these code snippets were removed as well.&lt;br /&gt;
&lt;br /&gt;
=== Code Cleanup ===&lt;br /&gt;
Smaller improvements done while implementing the main tasks included:&lt;br /&gt;
* Using ActiveSupport::Duration objects in order to calculate the minutes and seconds related to the dequeue times&lt;br /&gt;
* Refactoring the time calculations for the dequeue times to the DueDate class&lt;br /&gt;
* Correcting the parameters passed to the workers, which were previously incorrect. As an example:&lt;br /&gt;
&amp;lt;blockquote&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def add_delayed_job(_assignment, deadline_type, due_date, min_left)&lt;br /&gt;
    delayed_job_id = MailWorker.perform_in(min_left * 60, due_date.parent_id, deadline_type, due_date.due_at)&lt;br /&gt;
    delayed_job_id&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
The first parameter after the time delay must be assignment ID, and &amp;lt;code&amp;gt;due_date.parent_id&amp;lt;/code&amp;gt; is not an assignment ID.&lt;br /&gt;
&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
* Removing whitespace issues reported by codeclimate&lt;br /&gt;
* Refactoring all variable names to be in snake_case&lt;br /&gt;
* Removing identical blocks of code&lt;br /&gt;
* Adding method comments to make methods more understandable&lt;br /&gt;
&lt;br /&gt;
== Test Plan ==&lt;br /&gt;
&lt;br /&gt;
=== Unit Tests ===&lt;br /&gt;
In order to properly test that our refactoring had worked properly, we found that we would have to add in multiple tests to account for our new methods as well as refactor old tests to work with the changes that we had made. &lt;br /&gt;
&lt;br /&gt;
=== Functional Tests ===&lt;br /&gt;
We decided that functional testing would need to be done by manually checking to see if Sidekiq tasks were queued as expected when changes to assignments were made. The three important functional tests that we decided needed to be verified were that the Simicheck Worker was queuing, the Mail Worker was queueing, and the Drop Outstanding Reviews Worker was queuing. These could be considered verified under the condition that the '''When''' field, '''Job''' field, and '''Arguments''' field in the Sidekiq view all came out as expected.&lt;br /&gt;
&lt;br /&gt;
=== Considering Edge Cases and Other Possibilities ===&lt;br /&gt;
&lt;br /&gt;
== Implementing Test Plan ==&lt;br /&gt;
&lt;br /&gt;
=== Update and add unit tests according to the refactoring changes made  ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Test all new worker classes to ensure Sidekiq jobs were being dequeued and run as expected ===&lt;br /&gt;
==== Sidekiq setup ====&lt;br /&gt;
In order to test the Sidekiq workers, a few steps were needed to set up the workers and run Sidekiq (steps were obtained from [https://tudip.com/blog-post/how-to-use-sidekiq-in-rails-for-background-processing/ this site]):&lt;br /&gt;
# Initialize three new workers, each having one of the three new worker types:&lt;br /&gt;
## &amp;lt;code&amp;gt;rails g sidekiq:worker SimicheckWorker&amp;lt;/code&amp;gt;&lt;br /&gt;
## &amp;lt;code&amp;gt;rails g sidekiq:worker DropOutstandingReviewsWorker&amp;lt;/code&amp;gt;&lt;br /&gt;
## &amp;lt;code&amp;gt;rails g sidekiq:worker MailWorker&amp;lt;/code&amp;gt;&lt;br /&gt;
# In a terminal separate from the one in which the main rails application is running, run&lt;br /&gt;
&amp;lt;blockquote&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
bundle exec sidekiq&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This Sidekiq-specific terminal will show logs and printed statements from the workers.&lt;br /&gt;
&lt;br /&gt;
==== SimicheckWorker Test ====&lt;br /&gt;
To enqueue a Simicheck job:&lt;br /&gt;
# Edit an assignment.&lt;br /&gt;
# Select the &amp;lt;code&amp;gt;Use simicheck?&amp;lt;/code&amp;gt; box.&lt;br /&gt;
# Set &amp;lt;code&amp;gt;Simicheck Delay&amp;lt;/code&amp;gt; to &amp;lt;code&amp;gt;0&amp;lt;/code&amp;gt; (or to a nonzero value to observe a delay).&lt;br /&gt;
# Set the SimiCheck Similarity Threshold to a nonzero value.&lt;br /&gt;
# Click &amp;lt;code&amp;gt;Save&amp;lt;/code&amp;gt;.&lt;br /&gt;
# Observe a Simicheck Worker job enqueued and dequeued in the Sidekiq UI.&lt;br /&gt;
&lt;br /&gt;
[[File:Enqueue-simicheck-job.png|500px|How to Enqueue a Simicheck Worker Job]]&lt;br /&gt;
&lt;br /&gt;
==== MailWorker and DropOustandingReviews Test ====&lt;br /&gt;
The Mail Worker sends out notifications to students if the due date of an assignment is changed. Drop Outstanding Reviews Worker drops all reviews that had not been worked on before the due date was changed. These both can be tested together, as when an assignment with a review is updated, Sidekiq should queue both the jobs for Mail Worker and Drop Outstanding Reviews Worker. To test these:&lt;br /&gt;
# Log into Expertiza as an instructor&lt;br /&gt;
# Navigate to '''Manage'''&amp;gt;'''Assignments''' in the navigation&lt;br /&gt;
# Click the plus button in the top right corner on the '''Manage Assignments''' and create an assignment with default settings. Make sure when creating the assignment to go to the '''Due Dates''' tab and assign due dates for both the assignment and the review. &lt;br /&gt;
# Assign student7613 to the assignment you created by clicking the person with the plus icon in the icons next to the assignment on the '''Manage Assignments''' page. &lt;br /&gt;
&lt;br /&gt;
At this point, we realized we need to alter the code to test if the code was properly queuing the Mail Worker because the current if statement to add items to the delayed queue required that it have a late policy. However, the late policy code is not currently working. Thus, in the &amp;lt;code&amp;gt;assignment_form.rb&amp;lt;/code&amp;gt; model file, we edited the following code:&lt;br /&gt;
&lt;br /&gt;
[[File:Change_late_policy.png|950px|Late policy code to alter]]&lt;br /&gt;
&lt;br /&gt;
We removed &amp;lt;code&amp;gt;and has_late_policy&amp;lt;/code&amp;gt; so &amp;lt;code&amp;gt;add_delayed_queue&amp;lt;/code&amp;gt; can run even without late policies being implemented. After saving this file, we started up Expertiza again.&lt;br /&gt;
5. Go to the assignment that student7613 had been assigned to.&lt;br /&gt;
6. Edit the assignment, go to the due dates tab, and change the due date on the review to be a day ahead of its current due date, and press save. Note: The assignment due date must be changed to a time at least an hour ahead of the current time for the reminder to be sent.&lt;br /&gt;
7. To ensure that the assignments are now queued on Sidekiq, visit the Sidekiq UI by going to [Expertiza VCL URL]/sidekiq.&lt;br /&gt;
8. Upon arriving on this page, verify that the jobs added to the queue were correct by clicking to '''Scheduled'''. After arriving on this page, you should see something like the following:&lt;br /&gt;
&lt;br /&gt;
[[File:Sidekiq-jobs.png|950px|Sidekiq jobs]]&lt;br /&gt;
&lt;br /&gt;
The job '''MailWorker''' that had been queued successfully shows that our refactoring of Mail Worker had worked properly and the Mail Worker was operational. The job '''DropOutstandingReviewsWorker''' showed that our refactoring of Drop Outstanding Reviews Worker had also been done correctly.&lt;br /&gt;
&lt;br /&gt;
=== Sidekiq UI ===&lt;br /&gt;
To see which messages were being enqueued and dequeued in Sidekiq, we use the Sidekiq user interface, which can be accessed via the &amp;lt;code&amp;gt;/sidekiq&amp;lt;/code&amp;gt; route of the application.&lt;br /&gt;
[[File:Sidekiq-ui.png|950px|The Sidekiq UI]]&lt;/div&gt;</summary>
		<author><name>Agcarrut</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2021_-_E2144._Refactor_delayed_mailer_and_scheduled_task&amp;diff=140167</id>
		<title>CSC/ECE 517 Fall 2021 - E2144. Refactor delayed mailer and scheduled task</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2021_-_E2144._Refactor_delayed_mailer_and_scheduled_task&amp;diff=140167"/>
		<updated>2021-10-27T01:24:23Z</updated>

		<summary type="html">&lt;p&gt;Agcarrut: /* MailWorker and DropOustandingReviews Test */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;__TOC__&lt;br /&gt;
&lt;br /&gt;
== Background ==&lt;br /&gt;
This project revolves around the Sidekiq gem for asynchronous processing of email tasks. It has a queue system to hold and then process jobs. Sidekiq’s queue replaces DelayedMailer’s queue. The previous team that worked on this also created a method &amp;lt;code&amp;gt;perform()&amp;lt;/code&amp;gt; to gather email IDs of all participants in an assignment and send them an email reminder. Some test cases exist for this work.&lt;br /&gt;
&lt;br /&gt;
=== Previous Setup ===&lt;br /&gt;
Initial work can be found [https://expertiza.csc.ncsu.edu/index.php/E1835_Refactor_delayed_mailer_and_scheduled_task here].&lt;br /&gt;
&lt;br /&gt;
Code in the [https://github.com/expertiza/expertiza/pull/1245/files pull request] was found to be reasonable and working. The method &amp;lt;code&amp;gt;perform()&amp;lt;/code&amp;gt; has:&lt;br /&gt;
{| class=wikitable style=text-align:right&lt;br /&gt;
|+ Metrics for &amp;lt;code&amp;gt;perform&amp;lt;/code&amp;gt; method&lt;br /&gt;
|-&lt;br /&gt;
! Metric !! Current Value !! Limit&lt;br /&gt;
|-&lt;br /&gt;
! Cognitive Complexity&lt;br /&gt;
| 15 || 5&lt;br /&gt;
|-&lt;br /&gt;
! Cyclomatic Complexity&lt;br /&gt;
| 8 || 6&lt;br /&gt;
|-&lt;br /&gt;
! Assignment Branch Condition size&lt;br /&gt;
| 22.93 || 15&lt;br /&gt;
|-&lt;br /&gt;
! Perceived complexity&lt;br /&gt;
| 10 || 7&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Previous pull request also has duplicated commit messages and the commits need to be squashed.&lt;br /&gt;
&lt;br /&gt;
Files involved (some changed should not have been changed):&lt;br /&gt;
* app/controllers/assignments_controller.rb&lt;br /&gt;
* app/mailers/mail_worker.rb&lt;br /&gt;
* app/models/assignment_form.rb&lt;br /&gt;
* config/sidekiq.yml&lt;br /&gt;
* spec/models/assignment_form_spec.rb&lt;br /&gt;
* spec/sidekiq_mail_worker_spec.rb&lt;br /&gt;
* spec/spec_helper.rb&lt;br /&gt;
&lt;br /&gt;
There are minor styling issues such as missing or trailing whitespaces, lines that are too long, extra empty line, unused arguments.&lt;br /&gt;
&lt;br /&gt;
=== Problem Statement ===&lt;br /&gt;
&lt;br /&gt;
This project revolves around the Sidekiq gem for asynchronous processing of email tasks. It has a queue system to hold and then process jobs. Sidekiq's queue replaces DelayedMailer’s queue. The previous team that worked on this also created a method perform() to gather email IDs of all participants in an assignment and send them an email reminder. Some test cases exist for this work.&lt;br /&gt;
The project was partially merged.&lt;br /&gt;
​&lt;br /&gt;
&lt;br /&gt;
What needs to be done:  &lt;br /&gt;
Feedback from the previous team (E1835) is:&lt;br /&gt;
Code in pull request seems pretty reasonable.  Some concerns wrt. naming functions, but otherwise reviewers seem to agree that the code is good.&lt;br /&gt;
​&lt;br /&gt;
&lt;br /&gt;
Your pull request has many duplicated commit messages. Please try to &amp;lt;code&amp;gt;squash&amp;lt;/code&amp;gt; similar commits.&lt;br /&gt;
And using meaningful commit messages later.&lt;br /&gt;
​&lt;br /&gt;
&lt;br /&gt;
You should commit changes to the DB schema (&amp;lt;code&amp;gt;db/schema.rb&amp;lt;/code&amp;gt;) only if you have created new DB migrations.&lt;br /&gt;
Please double check your code. If you did not aim to change the DB, please revert the DB schema changes. ***** Important, try not to change the DB.&lt;br /&gt;
​&lt;br /&gt;
&lt;br /&gt;
You should not change &amp;lt;code&amp;gt;rails_helper.rb&amp;lt;/code&amp;gt; or &amp;lt;code&amp;gt;spec_helper.rb&amp;lt;/code&amp;gt; file; please revert these changes.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The previous team’s code needs a refactor in some places, though the actual function of it seems solid. It is very possible that in the three years since this code has been worked on, more mailer functionality has been added. There are other teams this semester working on mailer code as well. Try to keep your code as contained and simple as possible, so that merging these projects is possible.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Summary of Work Needed ==&lt;br /&gt;
After discussing with our project mentor and Dr. Gehringer, we determined the main tasks to be the following:&lt;br /&gt;
# Refactor the single Sidekiq worker into multiple workers&lt;br /&gt;
# Remove all code related to the &amp;lt;code&amp;gt;drop_one_member_topics&amp;lt;/code&amp;gt; deadline type&lt;br /&gt;
# Update and add unit tests according to the above changes&lt;br /&gt;
# Test all new worker classes to ensure Sidekiq jobs were being dequeued and run as expected&lt;br /&gt;
# Code cleanup&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Refactor the single Sidekiq worker into multiple workers ===&lt;br /&gt;
Previously there was only a single worker class that handled all types of jobs. Its top-level method &amp;lt;code&amp;gt;perform&amp;lt;/code&amp;gt; looked like the following.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def perform(assignment_id, deadline_type, due_at)&lt;br /&gt;
    self.assignment_id = assignment_id&lt;br /&gt;
    self.deadline_type = deadline_type&lt;br /&gt;
    self.due_at = due_at&lt;br /&gt;
&lt;br /&gt;
    assignment = Assignment.find(self.assignment_id)&lt;br /&gt;
    participant_mails = find_participant_emails&lt;br /&gt;
&lt;br /&gt;
    if %w[drop_one_member_topics drop_outstanding_reviews compare_files_with_simicheck].include?(self.deadline_type)&lt;br /&gt;
      drop_one_member_topics if self.deadline_type == &amp;quot;drop_outstanding_reviews&amp;quot; &amp;amp;&amp;amp; assignment.team_assignment&lt;br /&gt;
      drop_outstanding_reviews if self.deadline_type == &amp;quot;drop_outstanding_reviews&amp;quot;&lt;br /&gt;
      perform_simicheck_comparisons(self.assignment_id) if self.deadline_type == &amp;quot;compare_files_with_simicheck&amp;quot;&lt;br /&gt;
    else&lt;br /&gt;
      # Can we rename deadline_type(metareview) to &amp;quot;teammate review&amp;quot;. If, yes then we donot need this if clause below!&lt;br /&gt;
      deadlineText = if self.deadline_type == &amp;quot;metareview&amp;quot;&lt;br /&gt;
                       &amp;quot;teammate review&amp;quot;&lt;br /&gt;
                     else&lt;br /&gt;
                       self.deadline_type&lt;br /&gt;
      end&lt;br /&gt;
&lt;br /&gt;
      email_reminder(participant_mails, deadlineText) unless participant_mails.empty?&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The processing was different depending on the &amp;lt;code&amp;gt;deadline_type&amp;lt;/code&amp;gt;. The &amp;lt;code&amp;gt;deadline_type&amp;lt;/code&amp;gt;s in&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
%w[drop_one_member_topics drop_outstanding_reviews compare_files_with_simicheck]&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
did not lead to an email reminder being sent, but they were still handled in this &amp;lt;code&amp;gt;MailWorker&amp;lt;/code&amp;gt; class.&lt;br /&gt;
&lt;br /&gt;
To make the code more manageable and easier to follow, it made sense to break up the responsibilities of this single &amp;lt;code&amp;gt;MailWorker&amp;lt;/code&amp;gt; class into multiple workers:&lt;br /&gt;
* &amp;lt;code&amp;gt;SimicheckWorker&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;DropOutstandingReviewsWorker&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;MailWorker&amp;lt;/code&amp;gt;&lt;br /&gt;
All three workers extended an &amp;quot;abstract class&amp;quot; called &amp;lt;code&amp;gt;Worker&amp;lt;/code&amp;gt; that contained the Sidekiq-related &amp;lt;code&amp;gt;include&amp;lt;/code&amp;gt; and the queue name to which all jobs would be sent.&lt;br /&gt;
&lt;br /&gt;
For simplicity, we still had all new workers continue to use a single queue, which we renamed from &amp;lt;code&amp;gt;mailers&amp;lt;/code&amp;gt; to &amp;lt;code&amp;gt;jobs&amp;lt;/code&amp;gt;. A future improvement could divide these jobs to go to multiple different queues if needed.&lt;br /&gt;
&lt;br /&gt;
=== Remove all code related to the &amp;lt;code&amp;gt;drop_one_member_topics&amp;lt;/code&amp;gt; deadline type ===&lt;br /&gt;
It was decided that code used for dropping one member or two member teams from topics would never need to be implemented in the Expertiza website. Thus, we removed all code related to the drop_one_member_topics method within the Expertiza beta. This involved removing the &amp;lt;code&amp;gt;drop_one_member_topics&amp;lt;/code&amp;gt; function from &amp;lt;code&amp;gt;drop_outstanding_reviews_mail_worker.rb&amp;lt;/code&amp;gt;, now renamed &amp;lt;code&amp;gt;drop_outstanding_reviews_worker.rb&amp;lt;/code&amp;gt;. The &amp;lt;code&amp;gt;drop_one_member_topics&amp;lt;/code&amp;gt; method was called from the &amp;lt;code&amp;gt;prepare_data&amp;lt;/code&amp;gt; method, which was then called by the Sidekiq method &amp;lt;code&amp;gt;perform&amp;lt;/code&amp;gt; so we removed this call. The &amp;lt;code&amp;gt;drop_one_member_topics&amp;lt;/code&amp;gt; was also referenced in &amp;lt;code&amp;gt;assignment_form.rb&amp;lt;/code&amp;gt; using &amp;lt;code&amp;gt;add_delayed_job&amp;lt;/code&amp;gt; in the &amp;lt;code&amp;gt;add_to_delayed_queue&amp;lt;/code&amp;gt; method and in &amp;lt;code&amp;gt;delayed_mailer.html.erb&amp;lt;/code&amp;gt; as an option for the handler so both of these code snippets were removed as well.&lt;br /&gt;
&lt;br /&gt;
=== Code Cleanup ===&lt;br /&gt;
Smaller improvements done while implementing the main tasks included:&lt;br /&gt;
* Using ActiveSupport::Duration objects in order to calculate the minutes and seconds related to the dequeue times&lt;br /&gt;
* Refactoring the time calculations for the dequeue times to the DueDate class&lt;br /&gt;
* Correcting the parameters passed to the workers, which were previously incorrect. As an example:&lt;br /&gt;
&amp;lt;blockquote&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def add_delayed_job(_assignment, deadline_type, due_date, min_left)&lt;br /&gt;
    delayed_job_id = MailWorker.perform_in(min_left * 60, due_date.parent_id, deadline_type, due_date.due_at)&lt;br /&gt;
    delayed_job_id&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
The first parameter after the time delay must be assignment ID, and &amp;lt;code&amp;gt;due_date.parent_id&amp;lt;/code&amp;gt; is not an assignment ID.&lt;br /&gt;
&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
* Removing whitespace issues reported by codeclimate&lt;br /&gt;
* Refactoring all variable names to be in snake_case&lt;br /&gt;
* Removing identical blocks of code&lt;br /&gt;
* Adding method comments to make methods more understandable&lt;br /&gt;
&lt;br /&gt;
== Test Plan ==&lt;br /&gt;
&lt;br /&gt;
=== Unit Tests ===&lt;br /&gt;
In order to properly test that our refactoring had worked properly, we found that we would have to add in multiple tests to account for our new methods as well as refactor old tests to work with the changes that we had made. &lt;br /&gt;
&lt;br /&gt;
=== Functional Tests ===&lt;br /&gt;
We decided that functional testing would need to be done by manually checking to see if Sidekiq tasks were queued as expected when changes to assignments were made. The three important functional tests that we decided needed to be verified were that the Simicheck Worker was queuing, the Mail Worker was queueing, and the Drop Outstanding Reviews Worker was queuing. These could be considered verified under the condition that the '''When''' field, '''Job''' field, and '''Arguments''' field in the Sidekiq view all came out as expected.&lt;br /&gt;
&lt;br /&gt;
=== Considering Edge Cases and Other Possibilities ===&lt;br /&gt;
&lt;br /&gt;
== Implementing Test Plan ==&lt;br /&gt;
&lt;br /&gt;
=== Update and add unit tests according to the refactoring changes made  ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Test all new worker classes to ensure Sidekiq jobs were being dequeued and run as expected ===&lt;br /&gt;
==== Sidekiq setup ====&lt;br /&gt;
In order to test the Sidekiq workers, a few steps were needed to set up the workers and run Sidekiq (steps were obtained from [https://tudip.com/blog-post/how-to-use-sidekiq-in-rails-for-background-processing/ this site]):&lt;br /&gt;
# Initialize three new workers, each having one of the three new worker types:&lt;br /&gt;
## &amp;lt;code&amp;gt;rails g sidekiq:worker SimicheckWorker&amp;lt;/code&amp;gt;&lt;br /&gt;
## &amp;lt;code&amp;gt;rails g sidekiq:worker DropOutstandingReviewsWorker&amp;lt;/code&amp;gt;&lt;br /&gt;
## &amp;lt;code&amp;gt;rails g sidekiq:worker MailWorker&amp;lt;/code&amp;gt;&lt;br /&gt;
# In a terminal separate from the one in which the main rails application is running, run&lt;br /&gt;
&amp;lt;blockquote&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
bundle exec sidekiq&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This Sidekiq-specific terminal will show logs and printed statements from the workers.&lt;br /&gt;
&lt;br /&gt;
==== SimicheckWorker Test ====&lt;br /&gt;
To enqueue a Simicheck job:&lt;br /&gt;
# Edit an assignment.&lt;br /&gt;
# Select the &amp;lt;code&amp;gt;Use simicheck?&amp;lt;/code&amp;gt; box.&lt;br /&gt;
# Set &amp;lt;code&amp;gt;Simicheck Delay&amp;lt;/code&amp;gt; to &amp;lt;code&amp;gt;0&amp;lt;/code&amp;gt; (or to a nonzero value to observe a delay).&lt;br /&gt;
# Set the SimiCheck Similarity Threshold to a nonzero value.&lt;br /&gt;
# Click &amp;lt;code&amp;gt;Save&amp;lt;/code&amp;gt;.&lt;br /&gt;
# Observe a Simicheck Worker job enqueued and dequeued in the Sidekiq UI.&lt;br /&gt;
&lt;br /&gt;
[[File:Enqueue-simicheck-job.png|500px|How to Enqueue a Simicheck Worker Job]]&lt;br /&gt;
&lt;br /&gt;
==== MailWorker and DropOustandingReviews Test ====&lt;br /&gt;
The Mail Worker sends out notifications to students if the due date of an assignment is changed. Drop Outstanding Reviews Worker drops all reviews that had not been worked on before the due date was changed. These both can be tested together, as when an assignment with a review is updated, Sidekiq should queue both the jobs for Mail Worker and Drop Outstanding Reviews Worker. To test these:&lt;br /&gt;
# Log into Expertiza as an instructor&lt;br /&gt;
# Navigate to '''Manage'''&amp;gt;'''Assignments''' in the navigation&lt;br /&gt;
# Click the plus button in the top right corner on the '''Manage Assignments''' and create an assignment with default settings. Make sure when creating the assignment to go to the '''Due Dates''' tab and assign due dates for both the assignment and the review. &lt;br /&gt;
# Assign student7613 to the assignment you created by clicking the person with the plus icon in the icons next to the assignment on the '''Manage Assignments''' page. &lt;br /&gt;
&lt;br /&gt;
At this point, we realized we need to alter the code to test if the code was properly queuing the Mail Worker because the current if statement to add items to the delayed queue required that it have a late policy. However, the late policy code is not currently working. Thus, in the &amp;lt;code&amp;gt;assignment_form.rb&amp;lt;/code&amp;gt; model file, we edited the following code:&lt;br /&gt;
&lt;br /&gt;
[[File:Change_late_policy.png|950px|Late policy code to alter]]&lt;br /&gt;
&lt;br /&gt;
We removed &amp;lt;code&amp;gt;and has_late_policy&amp;lt;/code&amp;gt; so &amp;lt;code&amp;gt;add_delayed_queue&amp;lt;/code&amp;gt; can run even without late policies being implemented. After saving this file, we started up Expertiza again.&lt;br /&gt;
# Go to the assignment that student7613 had been assigned to.&lt;br /&gt;
# Edit the assignment, go to the due dates tab, and change the due date on the review to be a day ahead of its current due date, and press save. Note: The assignment due date must be changed to a time at least an hour ahead of the current time for the reminder to be sent.&lt;br /&gt;
# To ensure that the assignments are now queued on Sidekiq, visit the Sidekiq UI by going to [Expertiza VCL URL]/sidekiq.&lt;br /&gt;
# Upon arriving on this page, verify that the jobs added to the queue were correct by clicking to '''Scheduled'''. After arriving on this page, you should see something like the following:&lt;br /&gt;
&lt;br /&gt;
[[File:Sidekiq-jobs.png|950px|Sidekiq jobs]]&lt;br /&gt;
&lt;br /&gt;
The job '''MailWorker''' that had been queued successfully shows that our refactoring of Mail Worker had worked properly and the Mail Worker was operational. The job '''DropOutstandingReviewsWorker''' showed that our refactoring of Drop Outstanding Reviews Worker had also been done correctly.&lt;br /&gt;
&lt;br /&gt;
=== Sidekiq UI ===&lt;br /&gt;
To see which messages were being enqueued and dequeued in Sidekiq, we use the Sidekiq user interface, which can be accessed via the &amp;lt;code&amp;gt;/sidekiq&amp;lt;/code&amp;gt; route of the application.&lt;br /&gt;
[[File:Sidekiq-ui.png|950px|The Sidekiq UI]]&lt;/div&gt;</summary>
		<author><name>Agcarrut</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2021_-_E2144._Refactor_delayed_mailer_and_scheduled_task&amp;diff=140166</id>
		<title>CSC/ECE 517 Fall 2021 - E2144. Refactor delayed mailer and scheduled task</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2021_-_E2144._Refactor_delayed_mailer_and_scheduled_task&amp;diff=140166"/>
		<updated>2021-10-27T01:20:50Z</updated>

		<summary type="html">&lt;p&gt;Agcarrut: /* MailWorker and DropOustandingReviews Test */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;__TOC__&lt;br /&gt;
&lt;br /&gt;
== Background ==&lt;br /&gt;
This project revolves around the Sidekiq gem for asynchronous processing of email tasks. It has a queue system to hold and then process jobs. Sidekiq’s queue replaces DelayedMailer’s queue. The previous team that worked on this also created a method &amp;lt;code&amp;gt;perform()&amp;lt;/code&amp;gt; to gather email IDs of all participants in an assignment and send them an email reminder. Some test cases exist for this work.&lt;br /&gt;
&lt;br /&gt;
=== Previous Setup ===&lt;br /&gt;
Initial work can be found [https://expertiza.csc.ncsu.edu/index.php/E1835_Refactor_delayed_mailer_and_scheduled_task here].&lt;br /&gt;
&lt;br /&gt;
Code in the [https://github.com/expertiza/expertiza/pull/1245/files pull request] was found to be reasonable and working. The method &amp;lt;code&amp;gt;perform()&amp;lt;/code&amp;gt; has:&lt;br /&gt;
{| class=wikitable style=text-align:right&lt;br /&gt;
|+ Metrics for &amp;lt;code&amp;gt;perform&amp;lt;/code&amp;gt; method&lt;br /&gt;
|-&lt;br /&gt;
! Metric !! Current Value !! Limit&lt;br /&gt;
|-&lt;br /&gt;
! Cognitive Complexity&lt;br /&gt;
| 15 || 5&lt;br /&gt;
|-&lt;br /&gt;
! Cyclomatic Complexity&lt;br /&gt;
| 8 || 6&lt;br /&gt;
|-&lt;br /&gt;
! Assignment Branch Condition size&lt;br /&gt;
| 22.93 || 15&lt;br /&gt;
|-&lt;br /&gt;
! Perceived complexity&lt;br /&gt;
| 10 || 7&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Previous pull request also has duplicated commit messages and the commits need to be squashed.&lt;br /&gt;
&lt;br /&gt;
Files involved (some changed should not have been changed):&lt;br /&gt;
* app/controllers/assignments_controller.rb&lt;br /&gt;
* app/mailers/mail_worker.rb&lt;br /&gt;
* app/models/assignment_form.rb&lt;br /&gt;
* config/sidekiq.yml&lt;br /&gt;
* spec/models/assignment_form_spec.rb&lt;br /&gt;
* spec/sidekiq_mail_worker_spec.rb&lt;br /&gt;
* spec/spec_helper.rb&lt;br /&gt;
&lt;br /&gt;
There are minor styling issues such as missing or trailing whitespaces, lines that are too long, extra empty line, unused arguments.&lt;br /&gt;
&lt;br /&gt;
=== Problem Statement ===&lt;br /&gt;
&lt;br /&gt;
This project revolves around the Sidekiq gem for asynchronous processing of email tasks. It has a queue system to hold and then process jobs. Sidekiq's queue replaces DelayedMailer’s queue. The previous team that worked on this also created a method perform() to gather email IDs of all participants in an assignment and send them an email reminder. Some test cases exist for this work.&lt;br /&gt;
The project was partially merged.&lt;br /&gt;
​&lt;br /&gt;
&lt;br /&gt;
What needs to be done:  &lt;br /&gt;
Feedback from the previous team (E1835) is:&lt;br /&gt;
Code in pull request seems pretty reasonable.  Some concerns wrt. naming functions, but otherwise reviewers seem to agree that the code is good.&lt;br /&gt;
​&lt;br /&gt;
&lt;br /&gt;
Your pull request has many duplicated commit messages. Please try to &amp;lt;code&amp;gt;squash&amp;lt;/code&amp;gt; similar commits.&lt;br /&gt;
And using meaningful commit messages later.&lt;br /&gt;
​&lt;br /&gt;
&lt;br /&gt;
You should commit changes to the DB schema (&amp;lt;code&amp;gt;db/schema.rb&amp;lt;/code&amp;gt;) only if you have created new DB migrations.&lt;br /&gt;
Please double check your code. If you did not aim to change the DB, please revert the DB schema changes. ***** Important, try not to change the DB.&lt;br /&gt;
​&lt;br /&gt;
&lt;br /&gt;
You should not change &amp;lt;code&amp;gt;rails_helper.rb&amp;lt;/code&amp;gt; or &amp;lt;code&amp;gt;spec_helper.rb&amp;lt;/code&amp;gt; file; please revert these changes.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The previous team’s code needs a refactor in some places, though the actual function of it seems solid. It is very possible that in the three years since this code has been worked on, more mailer functionality has been added. There are other teams this semester working on mailer code as well. Try to keep your code as contained and simple as possible, so that merging these projects is possible.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Summary of Work Needed ==&lt;br /&gt;
After discussing with our project mentor and Dr. Gehringer, we determined the main tasks to be the following:&lt;br /&gt;
# Refactor the single Sidekiq worker into multiple workers&lt;br /&gt;
# Remove all code related to the &amp;lt;code&amp;gt;drop_one_member_topics&amp;lt;/code&amp;gt; deadline type&lt;br /&gt;
# Update and add unit tests according to the above changes&lt;br /&gt;
# Test all new worker classes to ensure Sidekiq jobs were being dequeued and run as expected&lt;br /&gt;
# Code cleanup&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Refactor the single Sidekiq worker into multiple workers ===&lt;br /&gt;
Previously there was only a single worker class that handled all types of jobs. Its top-level method &amp;lt;code&amp;gt;perform&amp;lt;/code&amp;gt; looked like the following.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def perform(assignment_id, deadline_type, due_at)&lt;br /&gt;
    self.assignment_id = assignment_id&lt;br /&gt;
    self.deadline_type = deadline_type&lt;br /&gt;
    self.due_at = due_at&lt;br /&gt;
&lt;br /&gt;
    assignment = Assignment.find(self.assignment_id)&lt;br /&gt;
    participant_mails = find_participant_emails&lt;br /&gt;
&lt;br /&gt;
    if %w[drop_one_member_topics drop_outstanding_reviews compare_files_with_simicheck].include?(self.deadline_type)&lt;br /&gt;
      drop_one_member_topics if self.deadline_type == &amp;quot;drop_outstanding_reviews&amp;quot; &amp;amp;&amp;amp; assignment.team_assignment&lt;br /&gt;
      drop_outstanding_reviews if self.deadline_type == &amp;quot;drop_outstanding_reviews&amp;quot;&lt;br /&gt;
      perform_simicheck_comparisons(self.assignment_id) if self.deadline_type == &amp;quot;compare_files_with_simicheck&amp;quot;&lt;br /&gt;
    else&lt;br /&gt;
      # Can we rename deadline_type(metareview) to &amp;quot;teammate review&amp;quot;. If, yes then we donot need this if clause below!&lt;br /&gt;
      deadlineText = if self.deadline_type == &amp;quot;metareview&amp;quot;&lt;br /&gt;
                       &amp;quot;teammate review&amp;quot;&lt;br /&gt;
                     else&lt;br /&gt;
                       self.deadline_type&lt;br /&gt;
      end&lt;br /&gt;
&lt;br /&gt;
      email_reminder(participant_mails, deadlineText) unless participant_mails.empty?&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The processing was different depending on the &amp;lt;code&amp;gt;deadline_type&amp;lt;/code&amp;gt;. The &amp;lt;code&amp;gt;deadline_type&amp;lt;/code&amp;gt;s in&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
%w[drop_one_member_topics drop_outstanding_reviews compare_files_with_simicheck]&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
did not lead to an email reminder being sent, but they were still handled in this &amp;lt;code&amp;gt;MailWorker&amp;lt;/code&amp;gt; class.&lt;br /&gt;
&lt;br /&gt;
To make the code more manageable and easier to follow, it made sense to break up the responsibilities of this single &amp;lt;code&amp;gt;MailWorker&amp;lt;/code&amp;gt; class into multiple workers:&lt;br /&gt;
* &amp;lt;code&amp;gt;SimicheckWorker&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;DropOutstandingReviewsWorker&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;MailWorker&amp;lt;/code&amp;gt;&lt;br /&gt;
All three workers extended an &amp;quot;abstract class&amp;quot; called &amp;lt;code&amp;gt;Worker&amp;lt;/code&amp;gt; that contained the Sidekiq-related &amp;lt;code&amp;gt;include&amp;lt;/code&amp;gt; and the queue name to which all jobs would be sent.&lt;br /&gt;
&lt;br /&gt;
For simplicity, we still had all new workers continue to use a single queue, which we renamed from &amp;lt;code&amp;gt;mailers&amp;lt;/code&amp;gt; to &amp;lt;code&amp;gt;jobs&amp;lt;/code&amp;gt;. A future improvement could divide these jobs to go to multiple different queues if needed.&lt;br /&gt;
&lt;br /&gt;
=== Remove all code related to the &amp;lt;code&amp;gt;drop_one_member_topics&amp;lt;/code&amp;gt; deadline type ===&lt;br /&gt;
It was decided that code used for dropping one member or two member teams from topics would never need to be implemented in the Expertiza website. Thus, we removed all code related to the drop_one_member_topics method within the Expertiza beta. This involved removing the &amp;lt;code&amp;gt;drop_one_member_topics&amp;lt;/code&amp;gt; function from &amp;lt;code&amp;gt;drop_outstanding_reviews_mail_worker.rb&amp;lt;/code&amp;gt;, now renamed &amp;lt;code&amp;gt;drop_outstanding_reviews_worker.rb&amp;lt;/code&amp;gt;. The &amp;lt;code&amp;gt;drop_one_member_topics&amp;lt;/code&amp;gt; method was called from the &amp;lt;code&amp;gt;prepare_data&amp;lt;/code&amp;gt; method, which was then called by the Sidekiq method &amp;lt;code&amp;gt;perform&amp;lt;/code&amp;gt; so we removed this call. The &amp;lt;code&amp;gt;drop_one_member_topics&amp;lt;/code&amp;gt; was also referenced in &amp;lt;code&amp;gt;assignment_form.rb&amp;lt;/code&amp;gt; using &amp;lt;code&amp;gt;add_delayed_job&amp;lt;/code&amp;gt; in the &amp;lt;code&amp;gt;add_to_delayed_queue&amp;lt;/code&amp;gt; method and in &amp;lt;code&amp;gt;delayed_mailer.html.erb&amp;lt;/code&amp;gt; as an option for the handler so both of these code snippets were removed as well.&lt;br /&gt;
&lt;br /&gt;
=== Code Cleanup ===&lt;br /&gt;
Smaller improvements done while implementing the main tasks included:&lt;br /&gt;
* Using ActiveSupport::Duration objects in order to calculate the minutes and seconds related to the dequeue times&lt;br /&gt;
* Refactoring the time calculations for the dequeue times to the DueDate class&lt;br /&gt;
* Correcting the parameters passed to the workers, which were previously incorrect. As an example:&lt;br /&gt;
&amp;lt;blockquote&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def add_delayed_job(_assignment, deadline_type, due_date, min_left)&lt;br /&gt;
    delayed_job_id = MailWorker.perform_in(min_left * 60, due_date.parent_id, deadline_type, due_date.due_at)&lt;br /&gt;
    delayed_job_id&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
The first parameter after the time delay must be assignment ID, and &amp;lt;code&amp;gt;due_date.parent_id&amp;lt;/code&amp;gt; is not an assignment ID.&lt;br /&gt;
&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
* Removing whitespace issues reported by codeclimate&lt;br /&gt;
* Refactoring all variable names to be in snake_case&lt;br /&gt;
* Removing identical blocks of code&lt;br /&gt;
* Adding method comments to make methods more understandable&lt;br /&gt;
&lt;br /&gt;
== Test Plan ==&lt;br /&gt;
&lt;br /&gt;
=== Unit Tests ===&lt;br /&gt;
In order to properly test that our refactoring had worked properly, we found that we would have to add in multiple tests to account for our new methods as well as refactor old tests to work with the changes that we had made. &lt;br /&gt;
&lt;br /&gt;
=== Functional Tests ===&lt;br /&gt;
We decided that functional testing would need to be done by manually checking to see if Sidekiq tasks were queued as expected when changes to assignments were made. The three important functional tests that we decided needed to be verified were that the Simicheck Worker was queuing, the Mail Worker was queueing, and the Drop Outstanding Reviews Worker was queuing. These could be considered verified under the condition that the '''When''' field, '''Job''' field, and '''Arguments''' field in the Sidekiq view all came out as expected.&lt;br /&gt;
&lt;br /&gt;
=== Considering Edge Cases and Other Possibilities ===&lt;br /&gt;
&lt;br /&gt;
== Implementing Test Plan ==&lt;br /&gt;
&lt;br /&gt;
=== Update and add unit tests according to the refactoring changes made  ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Test all new worker classes to ensure Sidekiq jobs were being dequeued and run as expected ===&lt;br /&gt;
==== Sidekiq setup ====&lt;br /&gt;
In order to test the Sidekiq workers, a few steps were needed to set up the workers and run Sidekiq (steps were obtained from [https://tudip.com/blog-post/how-to-use-sidekiq-in-rails-for-background-processing/ this site]):&lt;br /&gt;
# Initialize three new workers, each having one of the three new worker types:&lt;br /&gt;
## &amp;lt;code&amp;gt;rails g sidekiq:worker SimicheckWorker&amp;lt;/code&amp;gt;&lt;br /&gt;
## &amp;lt;code&amp;gt;rails g sidekiq:worker DropOutstandingReviewsWorker&amp;lt;/code&amp;gt;&lt;br /&gt;
## &amp;lt;code&amp;gt;rails g sidekiq:worker MailWorker&amp;lt;/code&amp;gt;&lt;br /&gt;
# In a terminal separate from the one in which the main rails application is running, run&lt;br /&gt;
&amp;lt;blockquote&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
bundle exec sidekiq&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This Sidekiq-specific terminal will show logs and printed statements from the workers.&lt;br /&gt;
&lt;br /&gt;
==== SimicheckWorker Test ====&lt;br /&gt;
To enqueue a Simicheck job:&lt;br /&gt;
# Edit an assignment.&lt;br /&gt;
# Select the &amp;lt;code&amp;gt;Use simicheck?&amp;lt;/code&amp;gt; box.&lt;br /&gt;
# Set &amp;lt;code&amp;gt;Simicheck Delay&amp;lt;/code&amp;gt; to &amp;lt;code&amp;gt;0&amp;lt;/code&amp;gt; (or to a nonzero value to observe a delay).&lt;br /&gt;
# Set the SimiCheck Similarity Threshold to a nonzero value.&lt;br /&gt;
# Click &amp;lt;code&amp;gt;Save&amp;lt;/code&amp;gt;.&lt;br /&gt;
# Observe a Simicheck Worker job enqueued and dequeued in the Sidekiq UI.&lt;br /&gt;
&lt;br /&gt;
[[File:Enqueue-simicheck-job.png|500px|How to Enqueue a Simicheck Worker Job]]&lt;br /&gt;
&lt;br /&gt;
==== MailWorker and DropOustandingReviews Test ====&lt;br /&gt;
The Mail Worker sends out notifications to students if the due date of an assignment is changed. Drop Outstanding Reviews Worker drops all reviews that had not been worked on before the due date was changed. These both can be tested together, as when an assignment with a review is updated, Sidekiq should queue both the jobs for Mail Worker and Drop Outstanding Reviews Worker. To test these, we:&lt;br /&gt;
# Logged into Expertiza as an instructor&lt;br /&gt;
# Navigated to '''Manage'''&amp;gt;'''Assignments''' in the navigation&lt;br /&gt;
# Clicked the plus button in the top right corner on the '''Manage Assignments''' and create an assignment with default settings. Make sure when creating the assignment to go to the '''Due Dates''' tab and assign due dates for both the assignment and the review. &lt;br /&gt;
# Assign student7613 to the assignment we had created by clicking the person with the plus icon in the icons next to the assignment on the '''Manage Assignments''' page. At this point, we realized we need to alter the code to test if the code was properly queuing the Mail Worker because the current if statement to add items to the delayed queue required that it have a late policy. However, the late policy code is not currently working. Thus, in the &amp;lt;code&amp;gt;assignment_form.rb&amp;lt;/code&amp;gt; model file, we edited the following code:&lt;br /&gt;
&lt;br /&gt;
[[File:Change_late_policy.png|950px|Late policy code to alter]]&lt;br /&gt;
&lt;br /&gt;
We removed &amp;lt;code&amp;gt;and has_late_policy&amp;lt;/code&amp;gt; so &amp;lt;code&amp;gt;add_delayed_queue&amp;lt;/code&amp;gt; can run even without late policies being implemented. After saving this file, we started up Expertiza again and went to the assignment that student7613 had been assigned to. We then edited the assignment, went to the due dates tab, changed the due date on the review to be a day ahead of its current due date, and pressed save. To ensure that the assignments were now queued on Sidekiq, we visited the Sidekiq UI by going to [Expertiza VCL URL]/sidekiq. Upon arriving on this page, we verified that the jobs added to the queue were correct by clicking to '''Scheduled'''. After arriving on this page, we saw the following:&lt;br /&gt;
&lt;br /&gt;
[[File:Sidekiq-jobs.png|950px|Sidekiq jobs]]&lt;br /&gt;
&lt;br /&gt;
The job '''MailWorker''' that had been queued successfully shows that our refactoring of Mail Worker had worked properly and the Mail Worker was operational. The job '''DropOutstandingReviewsWorker''' showed that our refactoring of Drop Outstanding Reviews Worker had also been done correctly.&lt;br /&gt;
&lt;br /&gt;
=== Sidekiq UI ===&lt;br /&gt;
To see which messages were being enqueued and dequeued in Sidekiq, we use the Sidekiq user interface, which can be accessed via the &amp;lt;code&amp;gt;/sidekiq&amp;lt;/code&amp;gt; route of the application.&lt;br /&gt;
[[File:Sidekiq-ui.png|950px|The Sidekiq UI]]&lt;/div&gt;</summary>
		<author><name>Agcarrut</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2021_-_E2144._Refactor_delayed_mailer_and_scheduled_task&amp;diff=140102</id>
		<title>CSC/ECE 517 Fall 2021 - E2144. Refactor delayed mailer and scheduled task</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2021_-_E2144._Refactor_delayed_mailer_and_scheduled_task&amp;diff=140102"/>
		<updated>2021-10-26T18:09:12Z</updated>

		<summary type="html">&lt;p&gt;Agcarrut: Moved code cleanup&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;__TOC__&lt;br /&gt;
&lt;br /&gt;
== Background ==&lt;br /&gt;
This project revolves around the Sidekiq gem for asynchronous processing of email tasks. It has a queue system to hold and then process jobs. Sidekiq’s queue replaces DelayedMailer’s queue. The previous team that worked on this also created a method &amp;lt;code&amp;gt;perform()&amp;lt;/code&amp;gt; to gather email IDs of all participants in an assignment and send them an email reminder. Some test cases exist for this work.&lt;br /&gt;
&lt;br /&gt;
=== Previous Setup ===&lt;br /&gt;
Initial work can be found [https://expertiza.csc.ncsu.edu/index.php/E1835_Refactor_delayed_mailer_and_scheduled_task here].&lt;br /&gt;
&lt;br /&gt;
Code in the [https://github.com/expertiza/expertiza/pull/1245/files pull request] was found to be reasonable and working. The method &amp;lt;code&amp;gt;perform()&amp;lt;/code&amp;gt; has:&lt;br /&gt;
{| class=wikitable style=text-align:right&lt;br /&gt;
|+ Metrics for &amp;lt;code&amp;gt;perform&amp;lt;/code&amp;gt; method&lt;br /&gt;
|-&lt;br /&gt;
! Metric !! Current Value !! Limit&lt;br /&gt;
|-&lt;br /&gt;
! Cognitive Complexity&lt;br /&gt;
| 15 || 5&lt;br /&gt;
|-&lt;br /&gt;
! Cyclomatic Complexity&lt;br /&gt;
| 8 || 6&lt;br /&gt;
|-&lt;br /&gt;
! Assignment Branch Condition size&lt;br /&gt;
| 22.93 || 15&lt;br /&gt;
|-&lt;br /&gt;
! Perceived complexity&lt;br /&gt;
| 10 || 7&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Previous pull request also has duplicated commit messages and the commits need to be squashed.&lt;br /&gt;
&lt;br /&gt;
Files involved (some changed should not have been changed):&lt;br /&gt;
* app/controllers/assignments_controller.rb&lt;br /&gt;
* app/mailers/mail_worker.rb&lt;br /&gt;
* app/models/assignment_form.rb&lt;br /&gt;
* config/sidekiq.yml&lt;br /&gt;
* spec/models/assignment_form_spec.rb&lt;br /&gt;
* spec/sidekiq_mail_worker_spec.rb&lt;br /&gt;
* spec/spec_helper.rb&lt;br /&gt;
&lt;br /&gt;
There are minor styling issues such as missing or trailing whitespaces, lines that are too long, extra empty line, unused arguments.&lt;br /&gt;
&lt;br /&gt;
=== Problem Statement ===&lt;br /&gt;
&lt;br /&gt;
This project revolves around the Sidekiq gem for asynchronous processing of email tasks. It has a queue system to hold and then process jobs. Sidekiq's queue replaces DelayedMailer’s queue. The previous team that worked on this also created a method perform() to gather email IDs of all participants in an assignment and send them an email reminder. Some test cases exist for this work.&lt;br /&gt;
The project was partially merged.&lt;br /&gt;
​&lt;br /&gt;
&lt;br /&gt;
What needs to be done:  &lt;br /&gt;
Feedback from the previous team (E1835) is:&lt;br /&gt;
Code in pull request seems pretty reasonable.  Some concerns wrt. naming functions, but otherwise reviewers seem to agree that the code is good.&lt;br /&gt;
​&lt;br /&gt;
&lt;br /&gt;
Your pull request has many duplicated commit messages. Please try to &amp;lt;code&amp;gt;squash&amp;lt;/code&amp;gt; similar commits.&lt;br /&gt;
And using meaningful commit messages later.&lt;br /&gt;
​&lt;br /&gt;
&lt;br /&gt;
You should commit changes to the DB schema (&amp;lt;code&amp;gt;db/schema.rb&amp;lt;/code&amp;gt;) only if you have created new DB migrations.&lt;br /&gt;
Please double check your code. If you did not aim to change the DB, please revert the DB schema changes. ***** Important, try not to change the DB.&lt;br /&gt;
​&lt;br /&gt;
&lt;br /&gt;
You should not change &amp;lt;code&amp;gt;rails_helper.rb&amp;lt;/code&amp;gt; or &amp;lt;code&amp;gt;spec_helper.rb&amp;lt;/code&amp;gt; file; please revert these changes.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The previous team’s code needs a refactor in some places, though the actual function of it seems solid. It is very possible that in the three years since this code has been worked on, more mailer functionality has been added. There are other teams this semester working on mailer code as well. Try to keep your code as contained and simple as possible, so that merging these projects is possible.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Summary of Work Needed ==&lt;br /&gt;
After discussing with our project mentor and Dr. Gehringer, we determined the main tasks to be the following:&lt;br /&gt;
# Refactor the single Sidekiq worker into multiple workers&lt;br /&gt;
# Remove all code related to the &amp;lt;code&amp;gt;drop_one_member_topics&amp;lt;/code&amp;gt; deadline type&lt;br /&gt;
# Update and add unit tests according to the above changes&lt;br /&gt;
# Test all new worker classes to ensure Sidekiq jobs were being dequeued and run as expected&lt;br /&gt;
# Code cleanup&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Refactor the single Sidekiq worker into multiple workers ===&lt;br /&gt;
Previously there was only a single worker class that handled all types of jobs. Its top-level method &amp;lt;code&amp;gt;perform&amp;lt;/code&amp;gt; looked like the following.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def perform(assignment_id, deadline_type, due_at)&lt;br /&gt;
    self.assignment_id = assignment_id&lt;br /&gt;
    self.deadline_type = deadline_type&lt;br /&gt;
    self.due_at = due_at&lt;br /&gt;
&lt;br /&gt;
    assignment = Assignment.find(self.assignment_id)&lt;br /&gt;
    participant_mails = find_participant_emails&lt;br /&gt;
&lt;br /&gt;
    if %w[drop_one_member_topics drop_outstanding_reviews compare_files_with_simicheck].include?(self.deadline_type)&lt;br /&gt;
      drop_one_member_topics if self.deadline_type == &amp;quot;drop_outstanding_reviews&amp;quot; &amp;amp;&amp;amp; assignment.team_assignment&lt;br /&gt;
      drop_outstanding_reviews if self.deadline_type == &amp;quot;drop_outstanding_reviews&amp;quot;&lt;br /&gt;
      perform_simicheck_comparisons(self.assignment_id) if self.deadline_type == &amp;quot;compare_files_with_simicheck&amp;quot;&lt;br /&gt;
    else&lt;br /&gt;
      # Can we rename deadline_type(metareview) to &amp;quot;teammate review&amp;quot;. If, yes then we donot need this if clause below!&lt;br /&gt;
      deadlineText = if self.deadline_type == &amp;quot;metareview&amp;quot;&lt;br /&gt;
                       &amp;quot;teammate review&amp;quot;&lt;br /&gt;
                     else&lt;br /&gt;
                       self.deadline_type&lt;br /&gt;
      end&lt;br /&gt;
&lt;br /&gt;
      email_reminder(participant_mails, deadlineText) unless participant_mails.empty?&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The processing was different depending on the &amp;lt;code&amp;gt;deadline_type&amp;lt;/code&amp;gt;. The &amp;lt;code&amp;gt;deadline_type&amp;lt;/code&amp;gt;s in&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
%w[drop_one_member_topics drop_outstanding_reviews compare_files_with_simicheck]&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
did not lead to an email reminder being sent, but they were still handled in this &amp;lt;code&amp;gt;MailWorker&amp;lt;/code&amp;gt; class.&lt;br /&gt;
&lt;br /&gt;
To make the code more manageable and easier to follow, it made sense to break up the responsibilities of this single &amp;lt;code&amp;gt;MailWorker&amp;lt;/code&amp;gt; class into multiple workers:&lt;br /&gt;
* &amp;lt;code&amp;gt;SimicheckWorker&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;DropOutstandingReviewsWorker&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;MailWorker&amp;lt;/code&amp;gt;&lt;br /&gt;
All three workers extended an &amp;quot;abstract class&amp;quot; called &amp;lt;code&amp;gt;Worker&amp;lt;/code&amp;gt; that contained the Sidekiq-related &amp;lt;code&amp;gt;include&amp;lt;/code&amp;gt; and the queue name to which all jobs would be sent.&lt;br /&gt;
&lt;br /&gt;
For simplicity, we still had all new workers continue to use a single queue, which we renamed from &amp;lt;code&amp;gt;mailers&amp;lt;/code&amp;gt; to &amp;lt;code&amp;gt;jobs&amp;lt;/code&amp;gt;. A future improvement could divide these jobs to go to multiple different queues if needed.&lt;br /&gt;
&lt;br /&gt;
=== Remove all code related to the &amp;lt;code&amp;gt;drop_one_member_topics&amp;lt;/code&amp;gt; deadline type ===&lt;br /&gt;
It was decided that code used for dropping one member or two member teams from topics would never need to be implemented in the Expertiza website. Thus, we removed all code related to the drop_one_member_topics method within the Expertiza beta. This involved removing the &amp;lt;code&amp;gt;drop_one_member_topics&amp;lt;/code&amp;gt; function from &amp;lt;code&amp;gt;drop_outstanding_reviews_mail_worker.rb&amp;lt;/code&amp;gt;, now renamed &amp;lt;code&amp;gt;drop_outstanding_reviews_worker.rb&amp;lt;/code&amp;gt;. The &amp;lt;code&amp;gt;drop_one_member_topics&amp;lt;/code&amp;gt; method was called from the &amp;lt;code&amp;gt;prepare_data&amp;lt;/code&amp;gt; method, which was then called by the Sidekiq method &amp;lt;code&amp;gt;perform&amp;lt;/code&amp;gt; so we removed this call. The &amp;lt;code&amp;gt;drop_one_member_topics&amp;lt;/code&amp;gt; was also referenced in &amp;lt;code&amp;gt;assignment_form.rb&amp;lt;/code&amp;gt; using &amp;lt;code&amp;gt;add_delayed_job&amp;lt;/code&amp;gt; in the &amp;lt;code&amp;gt;add_to_delayed_queue&amp;lt;/code&amp;gt; method and in &amp;lt;code&amp;gt;delayed_mailer.html.erb&amp;lt;/code&amp;gt; as an option for the handler so both of these code snippets were removed as well.&lt;br /&gt;
&lt;br /&gt;
=== Code Cleanup ===&lt;br /&gt;
Smaller improvements done while implementing the main tasks included:&lt;br /&gt;
* Using ActiveSupport::Duration objects in order to calculate the minutes and seconds related to the dequeue times&lt;br /&gt;
* Refactoring the time calculations for the dequeue times to the DueDate class&lt;br /&gt;
* Correcting the parameters passed to the workers, which were previously incorrect. As an example:&lt;br /&gt;
&amp;lt;blockquote&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def add_delayed_job(_assignment, deadline_type, due_date, min_left)&lt;br /&gt;
    delayed_job_id = MailWorker.perform_in(min_left * 60, due_date.parent_id, deadline_type, due_date.due_at)&lt;br /&gt;
    delayed_job_id&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
The first parameter after the time delay must be assignment ID, and &amp;lt;code&amp;gt;due_date.parent_id&amp;lt;/code&amp;gt; is not an assignment ID.&lt;br /&gt;
&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
* Removing whitespace issues reported by codeclimate&lt;br /&gt;
* Refactoring all variable names to be in snake_case&lt;br /&gt;
* Removing identical blocks of code&lt;br /&gt;
* Adding method comments to make methods more understandable&lt;br /&gt;
&lt;br /&gt;
== Test Plan ==&lt;br /&gt;
&lt;br /&gt;
=== Unit Tests ===&lt;br /&gt;
In order to properly test that our refactoring had worked properly, we found that we would have to add in multiple tests to account for our new methods as well as refactor old tests to work with the changes that we had made. &lt;br /&gt;
&lt;br /&gt;
=== Functional Tests ===&lt;br /&gt;
We decided that functional testing would need to be done by manually checking to see if Sidekiq tasks were queued as expected when changes to assignments were made. The three important functional tests that we decided needed to be verified were that the Simicheck Worker was queuing, the Mail Worker was queueing, and the Drop Outstanding Reviews Worker was queuing. These could be considered verified under the condition that the '''When''' field, '''Job''' field, and '''Arguments''' field in the Sidekiq view all came out as expected.&lt;br /&gt;
&lt;br /&gt;
=== Considering Edge Cases and Other Possibilities ===&lt;br /&gt;
&lt;br /&gt;
== Implementing Test Plan ==&lt;br /&gt;
&lt;br /&gt;
=== Update and add unit tests according to the refactoring changes made  ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Test all new worker classes to ensure Sidekiq jobs were being dequeued and run as expected ===&lt;br /&gt;
==== Sidekiq setup ====&lt;br /&gt;
In order to test the Sidekiq workers, a few steps were needed to set up the workers and run Sidekiq (steps were obtained from [https://tudip.com/blog-post/how-to-use-sidekiq-in-rails-for-background-processing/ this site]):&lt;br /&gt;
# Initialize three new workers, each having one of the three new worker types:&lt;br /&gt;
## &amp;lt;code&amp;gt;rails g sidekiq:worker SimicheckWorker&amp;lt;/code&amp;gt;&lt;br /&gt;
## &amp;lt;code&amp;gt;rails g sidekiq:worker DropOutstandingReviewsWorker&amp;lt;/code&amp;gt;&lt;br /&gt;
## &amp;lt;code&amp;gt;rails g sidekiq:worker MailWorker&amp;lt;/code&amp;gt;&lt;br /&gt;
# In a terminal separate from the one in which the main rails application is running, run&lt;br /&gt;
&amp;lt;blockquote&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
bundle exec sidekiq&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This Sidekiq-specific terminal will show logs and printed statements from the workers.&lt;br /&gt;
&lt;br /&gt;
==== SimicheckWorker Test ====&lt;br /&gt;
&lt;br /&gt;
==== MailWorker and DropOustandingReviews Test ====&lt;br /&gt;
The Mail Worker sends out notifications to students if the due date of an assignment is changed. Drop Outstanding Reviews Worker drops all reviews that had not been worked on before the due date was changed. These both can be tested together, as when an assignment with a review is updated, Sidekiq should queue both the jobs for Mail Worker and Drop Outstanding Reviews Worker. To test these, we first created an assignment with the default options by logging in as an instructor, going to '''Manage'''&amp;gt;'''Assignments''' in the navigation, and clicking the plus button in the top right corner on the '''Manage Assignments'''. Make sure when creating the assignment to go to the '''Due Dates''' tab and assign due dates for both the assignment and the review. We then assigned student7613 to the assignment we had created by clicking the person with the plus icon in the icons next to the assignment on the '''Manage Assignments''' page. At this point, we realized we need to alter the code to test if the code was properly queuing the Mail Worker because the current if statement to add items to the delayed queue required that it have a late policy. However, the late policy code is not currently working. Thus, in the &amp;lt;code&amp;gt;assignment_form.rb&amp;lt;/code&amp;gt; model file, we edited the following code:&lt;br /&gt;
&lt;br /&gt;
[[File:Change_late_policy.png|950px|Late policy code to alter]]&lt;br /&gt;
&lt;br /&gt;
We removed &amp;lt;code&amp;gt;and has_late_policy&amp;lt;/code&amp;gt; so &amp;lt;code&amp;gt;add_delayed_queue&amp;lt;/code&amp;gt; can run even without late policies being implemented. After saving this file, we started up Expertiza again and went to the assignment that student7613 had been assigned to. We then edited the assignment, went to the due dates tab, changed the due date on the review to be a day ahead of its current due date, and pressed save. To ensure that the assignments were now queued on Sidekiq, we visited the Sidekiq UI by going to [Expertiza VCL URL]/sidekiq. Upon arriving on this page, we verified that the jobs added to the queue were correct by clicking to '''Scheduled'''. After arriving on this page, we saw the following:&lt;br /&gt;
&lt;br /&gt;
[[File:Sidekiq-jobs.png|950px|Sidekiq jobs]]&lt;br /&gt;
&lt;br /&gt;
The job '''MailWorker''' that had been queued successfully shows that our refactoring of Mail Worker had worked properly and the Mail Worker was operational. The job '''DropOutstandingReviewsWorker''' showed that our refactoring of Drop Outstanding Reviews Worker had also been done correctly.&lt;br /&gt;
&lt;br /&gt;
=== Sidekiq UI ===&lt;br /&gt;
To see which messages were being enqueued and dequeued in Sidekiq, we use the Sidekiq user interface, which can be accessed via the &amp;lt;code&amp;gt;/sidekiq&amp;lt;/code&amp;gt; route of the application.&lt;br /&gt;
[[File:Sidekiq-ui.png|950px|The Sidekiq UI]]&lt;/div&gt;</summary>
		<author><name>Agcarrut</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2021_-_E2144._Refactor_delayed_mailer_and_scheduled_task&amp;diff=140101</id>
		<title>CSC/ECE 517 Fall 2021 - E2144. Refactor delayed mailer and scheduled task</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2021_-_E2144._Refactor_delayed_mailer_and_scheduled_task&amp;diff=140101"/>
		<updated>2021-10-26T18:07:58Z</updated>

		<summary type="html">&lt;p&gt;Agcarrut: Added test plan&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;__TOC__&lt;br /&gt;
&lt;br /&gt;
== Background ==&lt;br /&gt;
This project revolves around the Sidekiq gem for asynchronous processing of email tasks. It has a queue system to hold and then process jobs. Sidekiq’s queue replaces DelayedMailer’s queue. The previous team that worked on this also created a method &amp;lt;code&amp;gt;perform()&amp;lt;/code&amp;gt; to gather email IDs of all participants in an assignment and send them an email reminder. Some test cases exist for this work.&lt;br /&gt;
&lt;br /&gt;
=== Previous Setup ===&lt;br /&gt;
Initial work can be found [https://expertiza.csc.ncsu.edu/index.php/E1835_Refactor_delayed_mailer_and_scheduled_task here].&lt;br /&gt;
&lt;br /&gt;
Code in the [https://github.com/expertiza/expertiza/pull/1245/files pull request] was found to be reasonable and working. The method &amp;lt;code&amp;gt;perform()&amp;lt;/code&amp;gt; has:&lt;br /&gt;
{| class=wikitable style=text-align:right&lt;br /&gt;
|+ Metrics for &amp;lt;code&amp;gt;perform&amp;lt;/code&amp;gt; method&lt;br /&gt;
|-&lt;br /&gt;
! Metric !! Current Value !! Limit&lt;br /&gt;
|-&lt;br /&gt;
! Cognitive Complexity&lt;br /&gt;
| 15 || 5&lt;br /&gt;
|-&lt;br /&gt;
! Cyclomatic Complexity&lt;br /&gt;
| 8 || 6&lt;br /&gt;
|-&lt;br /&gt;
! Assignment Branch Condition size&lt;br /&gt;
| 22.93 || 15&lt;br /&gt;
|-&lt;br /&gt;
! Perceived complexity&lt;br /&gt;
| 10 || 7&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Previous pull request also has duplicated commit messages and the commits need to be squashed.&lt;br /&gt;
&lt;br /&gt;
Files involved (some changed should not have been changed):&lt;br /&gt;
* app/controllers/assignments_controller.rb&lt;br /&gt;
* app/mailers/mail_worker.rb&lt;br /&gt;
* app/models/assignment_form.rb&lt;br /&gt;
* config/sidekiq.yml&lt;br /&gt;
* spec/models/assignment_form_spec.rb&lt;br /&gt;
* spec/sidekiq_mail_worker_spec.rb&lt;br /&gt;
* spec/spec_helper.rb&lt;br /&gt;
&lt;br /&gt;
There are minor styling issues such as missing or trailing whitespaces, lines that are too long, extra empty line, unused arguments.&lt;br /&gt;
&lt;br /&gt;
=== Problem Statement ===&lt;br /&gt;
&lt;br /&gt;
This project revolves around the Sidekiq gem for asynchronous processing of email tasks. It has a queue system to hold and then process jobs. Sidekiq's queue replaces DelayedMailer’s queue. The previous team that worked on this also created a method perform() to gather email IDs of all participants in an assignment and send them an email reminder. Some test cases exist for this work.&lt;br /&gt;
The project was partially merged.&lt;br /&gt;
​&lt;br /&gt;
&lt;br /&gt;
What needs to be done:  &lt;br /&gt;
Feedback from the previous team (E1835) is:&lt;br /&gt;
Code in pull request seems pretty reasonable.  Some concerns wrt. naming functions, but otherwise reviewers seem to agree that the code is good.&lt;br /&gt;
​&lt;br /&gt;
&lt;br /&gt;
Your pull request has many duplicated commit messages. Please try to &amp;lt;code&amp;gt;squash&amp;lt;/code&amp;gt; similar commits.&lt;br /&gt;
And using meaningful commit messages later.&lt;br /&gt;
​&lt;br /&gt;
&lt;br /&gt;
You should commit changes to the DB schema (&amp;lt;code&amp;gt;db/schema.rb&amp;lt;/code&amp;gt;) only if you have created new DB migrations.&lt;br /&gt;
Please double check your code. If you did not aim to change the DB, please revert the DB schema changes. ***** Important, try not to change the DB.&lt;br /&gt;
​&lt;br /&gt;
&lt;br /&gt;
You should not change &amp;lt;code&amp;gt;rails_helper.rb&amp;lt;/code&amp;gt; or &amp;lt;code&amp;gt;spec_helper.rb&amp;lt;/code&amp;gt; file; please revert these changes.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The previous team’s code needs a refactor in some places, though the actual function of it seems solid. It is very possible that in the three years since this code has been worked on, more mailer functionality has been added. There are other teams this semester working on mailer code as well. Try to keep your code as contained and simple as possible, so that merging these projects is possible.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Summary of Work Needed ==&lt;br /&gt;
After discussing with our project mentor and Dr. Gehringer, we determined the main tasks to be the following:&lt;br /&gt;
# Refactor the single Sidekiq worker into multiple workers&lt;br /&gt;
# Remove all code related to the &amp;lt;code&amp;gt;drop_one_member_topics&amp;lt;/code&amp;gt; deadline type&lt;br /&gt;
# Update and add unit tests according to the above changes&lt;br /&gt;
# Test all new worker classes to ensure Sidekiq jobs were being dequeued and run as expected&lt;br /&gt;
# Code cleanup&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Refactor the single Sidekiq worker into multiple workers ===&lt;br /&gt;
Previously there was only a single worker class that handled all types of jobs. Its top-level method &amp;lt;code&amp;gt;perform&amp;lt;/code&amp;gt; looked like the following.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def perform(assignment_id, deadline_type, due_at)&lt;br /&gt;
    self.assignment_id = assignment_id&lt;br /&gt;
    self.deadline_type = deadline_type&lt;br /&gt;
    self.due_at = due_at&lt;br /&gt;
&lt;br /&gt;
    assignment = Assignment.find(self.assignment_id)&lt;br /&gt;
    participant_mails = find_participant_emails&lt;br /&gt;
&lt;br /&gt;
    if %w[drop_one_member_topics drop_outstanding_reviews compare_files_with_simicheck].include?(self.deadline_type)&lt;br /&gt;
      drop_one_member_topics if self.deadline_type == &amp;quot;drop_outstanding_reviews&amp;quot; &amp;amp;&amp;amp; assignment.team_assignment&lt;br /&gt;
      drop_outstanding_reviews if self.deadline_type == &amp;quot;drop_outstanding_reviews&amp;quot;&lt;br /&gt;
      perform_simicheck_comparisons(self.assignment_id) if self.deadline_type == &amp;quot;compare_files_with_simicheck&amp;quot;&lt;br /&gt;
    else&lt;br /&gt;
      # Can we rename deadline_type(metareview) to &amp;quot;teammate review&amp;quot;. If, yes then we donot need this if clause below!&lt;br /&gt;
      deadlineText = if self.deadline_type == &amp;quot;metareview&amp;quot;&lt;br /&gt;
                       &amp;quot;teammate review&amp;quot;&lt;br /&gt;
                     else&lt;br /&gt;
                       self.deadline_type&lt;br /&gt;
      end&lt;br /&gt;
&lt;br /&gt;
      email_reminder(participant_mails, deadlineText) unless participant_mails.empty?&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The processing was different depending on the &amp;lt;code&amp;gt;deadline_type&amp;lt;/code&amp;gt;. The &amp;lt;code&amp;gt;deadline_type&amp;lt;/code&amp;gt;s in&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
%w[drop_one_member_topics drop_outstanding_reviews compare_files_with_simicheck]&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
did not lead to an email reminder being sent, but they were still handled in this &amp;lt;code&amp;gt;MailWorker&amp;lt;/code&amp;gt; class.&lt;br /&gt;
&lt;br /&gt;
To make the code more manageable and easier to follow, it made sense to break up the responsibilities of this single &amp;lt;code&amp;gt;MailWorker&amp;lt;/code&amp;gt; class into multiple workers:&lt;br /&gt;
* &amp;lt;code&amp;gt;SimicheckWorker&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;DropOutstandingReviewsWorker&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;MailWorker&amp;lt;/code&amp;gt;&lt;br /&gt;
All three workers extended an &amp;quot;abstract class&amp;quot; called &amp;lt;code&amp;gt;Worker&amp;lt;/code&amp;gt; that contained the Sidekiq-related &amp;lt;code&amp;gt;include&amp;lt;/code&amp;gt; and the queue name to which all jobs would be sent.&lt;br /&gt;
&lt;br /&gt;
For simplicity, we still had all new workers continue to use a single queue, which we renamed from &amp;lt;code&amp;gt;mailers&amp;lt;/code&amp;gt; to &amp;lt;code&amp;gt;jobs&amp;lt;/code&amp;gt;. A future improvement could divide these jobs to go to multiple different queues if needed.&lt;br /&gt;
&lt;br /&gt;
=== Remove all code related to the &amp;lt;code&amp;gt;drop_one_member_topics&amp;lt;/code&amp;gt; deadline type ===&lt;br /&gt;
It was decided that code used for dropping one member or two member teams from topics would never need to be implemented in the Expertiza website. Thus, we removed all code related to the drop_one_member_topics method within the Expertiza beta. This involved removing the &amp;lt;code&amp;gt;drop_one_member_topics&amp;lt;/code&amp;gt; function from &amp;lt;code&amp;gt;drop_outstanding_reviews_mail_worker.rb&amp;lt;/code&amp;gt;, now renamed &amp;lt;code&amp;gt;drop_outstanding_reviews_worker.rb&amp;lt;/code&amp;gt;. The &amp;lt;code&amp;gt;drop_one_member_topics&amp;lt;/code&amp;gt; method was called from the &amp;lt;code&amp;gt;prepare_data&amp;lt;/code&amp;gt; method, which was then called by the Sidekiq method &amp;lt;code&amp;gt;perform&amp;lt;/code&amp;gt; so we removed this call. The &amp;lt;code&amp;gt;drop_one_member_topics&amp;lt;/code&amp;gt; was also referenced in &amp;lt;code&amp;gt;assignment_form.rb&amp;lt;/code&amp;gt; using &amp;lt;code&amp;gt;add_delayed_job&amp;lt;/code&amp;gt; in the &amp;lt;code&amp;gt;add_to_delayed_queue&amp;lt;/code&amp;gt; method and in &amp;lt;code&amp;gt;delayed_mailer.html.erb&amp;lt;/code&amp;gt; as an option for the handler so both of these code snippets were removed as well.&lt;br /&gt;
&lt;br /&gt;
== Test Plan ==&lt;br /&gt;
&lt;br /&gt;
=== Unit Tests ===&lt;br /&gt;
In order to properly test that our refactoring had worked properly, we found that we would have to add in multiple tests to account for our new methods as well as refactor old tests to work with the changes that we had made. &lt;br /&gt;
&lt;br /&gt;
=== Functional Tests ===&lt;br /&gt;
We decided that functional testing would need to be done by manually checking to see if Sidekiq tasks were queued as expected when changes to assignments were made. The three important functional tests that we decided needed to be verified were that the Simicheck Worker was queuing, the Mail Worker was queueing, and the Drop Outstanding Reviews Worker was queuing. These could be considered verified under the condition that the '''When''' field, '''Job''' field, and '''Arguments''' field in the Sidekiq view all came out as expected.&lt;br /&gt;
&lt;br /&gt;
=== Considering Edge Cases and Other Possibilities ===&lt;br /&gt;
&lt;br /&gt;
== Implementing Test Plan ==&lt;br /&gt;
&lt;br /&gt;
=== Update and add unit tests according to the refactoring changes made  ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Test all new worker classes to ensure Sidekiq jobs were being dequeued and run as expected ===&lt;br /&gt;
==== Sidekiq setup ====&lt;br /&gt;
In order to test the Sidekiq workers, a few steps were needed to set up the workers and run Sidekiq (steps were obtained from [https://tudip.com/blog-post/how-to-use-sidekiq-in-rails-for-background-processing/ this site]):&lt;br /&gt;
# Initialize three new workers, each having one of the three new worker types:&lt;br /&gt;
## &amp;lt;code&amp;gt;rails g sidekiq:worker SimicheckWorker&amp;lt;/code&amp;gt;&lt;br /&gt;
## &amp;lt;code&amp;gt;rails g sidekiq:worker DropOutstandingReviewsWorker&amp;lt;/code&amp;gt;&lt;br /&gt;
## &amp;lt;code&amp;gt;rails g sidekiq:worker MailWorker&amp;lt;/code&amp;gt;&lt;br /&gt;
# In a terminal separate from the one in which the main rails application is running, run&lt;br /&gt;
&amp;lt;blockquote&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
bundle exec sidekiq&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This Sidekiq-specific terminal will show logs and printed statements from the workers.&lt;br /&gt;
&lt;br /&gt;
==== SimicheckWorker Test ====&lt;br /&gt;
&lt;br /&gt;
==== MailWorker and DropOustandingReviews Test ====&lt;br /&gt;
The Mail Worker sends out notifications to students if the due date of an assignment is changed. Drop Outstanding Reviews Worker drops all reviews that had not been worked on before the due date was changed. These both can be tested together, as when an assignment with a review is updated, Sidekiq should queue both the jobs for Mail Worker and Drop Outstanding Reviews Worker. To test these, we first created an assignment with the default options by logging in as an instructor, going to '''Manage'''&amp;gt;'''Assignments''' in the navigation, and clicking the plus button in the top right corner on the '''Manage Assignments'''. Make sure when creating the assignment to go to the '''Due Dates''' tab and assign due dates for both the assignment and the review. We then assigned student7613 to the assignment we had created by clicking the person with the plus icon in the icons next to the assignment on the '''Manage Assignments''' page. At this point, we realized we need to alter the code to test if the code was properly queuing the Mail Worker because the current if statement to add items to the delayed queue required that it have a late policy. However, the late policy code is not currently working. Thus, in the &amp;lt;code&amp;gt;assignment_form.rb&amp;lt;/code&amp;gt; model file, we edited the following code:&lt;br /&gt;
&lt;br /&gt;
[[File:Change_late_policy.png|950px|Late policy code to alter]]&lt;br /&gt;
&lt;br /&gt;
We removed &amp;lt;code&amp;gt;and has_late_policy&amp;lt;/code&amp;gt; so &amp;lt;code&amp;gt;add_delayed_queue&amp;lt;/code&amp;gt; can run even without late policies being implemented. After saving this file, we started up Expertiza again and went to the assignment that student7613 had been assigned to. We then edited the assignment, went to the due dates tab, changed the due date on the review to be a day ahead of its current due date, and pressed save. To ensure that the assignments were now queued on Sidekiq, we visited the Sidekiq UI by going to [Expertiza VCL URL]/sidekiq. Upon arriving on this page, we verified that the jobs added to the queue were correct by clicking to '''Scheduled'''. After arriving on this page, we saw the following:&lt;br /&gt;
&lt;br /&gt;
[[File:Sidekiq-jobs.png|950px|Sidekiq jobs]]&lt;br /&gt;
&lt;br /&gt;
The job '''MailWorker''' that had been queued successfully shows that our refactoring of Mail Worker had worked properly and the Mail Worker was operational. The job '''DropOutstandingReviewsWorker''' showed that our refactoring of Drop Outstanding Reviews Worker had also been done correctly.&lt;br /&gt;
&lt;br /&gt;
=== Sidekiq UI ===&lt;br /&gt;
To see which messages were being enqueued and dequeued in Sidekiq, we use the Sidekiq user interface, which can be accessed via the &amp;lt;code&amp;gt;/sidekiq&amp;lt;/code&amp;gt; route of the application.&lt;br /&gt;
[[File:Sidekiq-ui.png|950px|The Sidekiq UI]]&lt;br /&gt;
&lt;br /&gt;
=== Code Cleanup ===&lt;br /&gt;
Smaller improvements done while implementing the main tasks included:&lt;br /&gt;
* Using ActiveSupport::Duration objects in order to calculate the minutes and seconds related to the dequeue times&lt;br /&gt;
* Refactoring the time calculations for the dequeue times to the DueDate class&lt;br /&gt;
* Correcting the parameters passed to the workers, which were previously incorrect. As an example:&lt;br /&gt;
&amp;lt;blockquote&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def add_delayed_job(_assignment, deadline_type, due_date, min_left)&lt;br /&gt;
    delayed_job_id = MailWorker.perform_in(min_left * 60, due_date.parent_id, deadline_type, due_date.due_at)&lt;br /&gt;
    delayed_job_id&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
The first parameter after the time delay must be assignment ID, and &amp;lt;code&amp;gt;due_date.parent_id&amp;lt;/code&amp;gt; is not an assignment ID.&lt;br /&gt;
&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
* Removing whitespace issues reported by codeclimate&lt;br /&gt;
* Refactoring all variable names to be in snake_case&lt;br /&gt;
* Removing identical blocks of code&lt;br /&gt;
* Adding method comments to make methods more understandable&lt;br /&gt;
* ...&lt;/div&gt;</summary>
		<author><name>Agcarrut</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2021_-_E2144._Refactor_delayed_mailer_and_scheduled_task&amp;diff=140100</id>
		<title>CSC/ECE 517 Fall 2021 - E2144. Refactor delayed mailer and scheduled task</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2021_-_E2144._Refactor_delayed_mailer_and_scheduled_task&amp;diff=140100"/>
		<updated>2021-10-26T17:57:43Z</updated>

		<summary type="html">&lt;p&gt;Agcarrut: /* MailWorker and DropOustandingReviews Test */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;__TOC__&lt;br /&gt;
&lt;br /&gt;
== Background ==&lt;br /&gt;
This project revolves around the Sidekiq gem for asynchronous processing of email tasks. It has a queue system to hold and then process jobs. Sidekiq’s queue replaces DelayedMailer’s queue. The previous team that worked on this also created a method &amp;lt;code&amp;gt;perform()&amp;lt;/code&amp;gt; to gather email IDs of all participants in an assignment and send them an email reminder. Some test cases exist for this work.&lt;br /&gt;
&lt;br /&gt;
=== Previous Setup ===&lt;br /&gt;
Initial work can be found [https://expertiza.csc.ncsu.edu/index.php/E1835_Refactor_delayed_mailer_and_scheduled_task here].&lt;br /&gt;
&lt;br /&gt;
Code in the [https://github.com/expertiza/expertiza/pull/1245/files pull request] was found to be reasonable and working. The method &amp;lt;code&amp;gt;perform()&amp;lt;/code&amp;gt; has:&lt;br /&gt;
{| class=wikitable style=text-align:right&lt;br /&gt;
|+ Metrics for &amp;lt;code&amp;gt;perform&amp;lt;/code&amp;gt; method&lt;br /&gt;
|-&lt;br /&gt;
! Metric !! Current Value !! Limit&lt;br /&gt;
|-&lt;br /&gt;
! Cognitive Complexity&lt;br /&gt;
| 15 || 5&lt;br /&gt;
|-&lt;br /&gt;
! Cyclomatic Complexity&lt;br /&gt;
| 8 || 6&lt;br /&gt;
|-&lt;br /&gt;
! Assignment Branch Condition size&lt;br /&gt;
| 22.93 || 15&lt;br /&gt;
|-&lt;br /&gt;
! Perceived complexity&lt;br /&gt;
| 10 || 7&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Previous pull request also has duplicated commit messages and the commits need to be squashed.&lt;br /&gt;
&lt;br /&gt;
Files involved (some changed should not have been changed):&lt;br /&gt;
* app/controllers/assignments_controller.rb&lt;br /&gt;
* app/mailers/mail_worker.rb&lt;br /&gt;
* app/models/assignment_form.rb&lt;br /&gt;
* config/sidekiq.yml&lt;br /&gt;
* spec/models/assignment_form_spec.rb&lt;br /&gt;
* spec/sidekiq_mail_worker_spec.rb&lt;br /&gt;
* spec/spec_helper.rb&lt;br /&gt;
&lt;br /&gt;
There are minor styling issues such as missing or trailing whitespaces, lines that are too long, extra empty line, unused arguments.&lt;br /&gt;
&lt;br /&gt;
=== Problem Statement ===&lt;br /&gt;
&lt;br /&gt;
This project revolves around the Sidekiq gem for asynchronous processing of email tasks. It has a queue system to hold and then process jobs. Sidekiq's queue replaces DelayedMailer’s queue. The previous team that worked on this also created a method perform() to gather email IDs of all participants in an assignment and send them an email reminder. Some test cases exist for this work.&lt;br /&gt;
The project was partially merged.&lt;br /&gt;
​&lt;br /&gt;
&lt;br /&gt;
What needs to be done:  &lt;br /&gt;
Feedback from the previous team (E1835) is:&lt;br /&gt;
Code in pull request seems pretty reasonable.  Some concerns wrt. naming functions, but otherwise reviewers seem to agree that the code is good.&lt;br /&gt;
​&lt;br /&gt;
&lt;br /&gt;
Your pull request has many duplicated commit messages. Please try to &amp;lt;code&amp;gt;squash&amp;lt;/code&amp;gt; similar commits.&lt;br /&gt;
And using meaningful commit messages later.&lt;br /&gt;
​&lt;br /&gt;
&lt;br /&gt;
You should commit changes to the DB schema (&amp;lt;code&amp;gt;db/schema.rb&amp;lt;/code&amp;gt;) only if you have created new DB migrations.&lt;br /&gt;
Please double check your code. If you did not aim to change the DB, please revert the DB schema changes. ***** Important, try not to change the DB.&lt;br /&gt;
​&lt;br /&gt;
&lt;br /&gt;
You should not change &amp;lt;code&amp;gt;rails_helper.rb&amp;lt;/code&amp;gt; or &amp;lt;code&amp;gt;spec_helper.rb&amp;lt;/code&amp;gt; file; please revert these changes.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The previous team’s code needs a refactor in some places, though the actual function of it seems solid. It is very possible that in the three years since this code has been worked on, more mailer functionality has been added. There are other teams this semester working on mailer code as well. Try to keep your code as contained and simple as possible, so that merging these projects is possible.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Summary of Work Needed ==&lt;br /&gt;
After discussing with our project mentor and Dr. Gehringer, we determined the main tasks to be the following:&lt;br /&gt;
# Refactor the single Sidekiq worker into multiple workers&lt;br /&gt;
# Remove all code related to the &amp;lt;code&amp;gt;drop_one_member_topics&amp;lt;/code&amp;gt; deadline type&lt;br /&gt;
# Update and add unit tests according to the above changes&lt;br /&gt;
# Test all new worker classes to ensure Sidekiq jobs were being dequeued and run as expected&lt;br /&gt;
# Code cleanup&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Refactor the single Sidekiq worker into multiple workers ===&lt;br /&gt;
Previously there was only a single worker class that handled all types of jobs. Its top-level method &amp;lt;code&amp;gt;perform&amp;lt;/code&amp;gt; looked like the following.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def perform(assignment_id, deadline_type, due_at)&lt;br /&gt;
    self.assignment_id = assignment_id&lt;br /&gt;
    self.deadline_type = deadline_type&lt;br /&gt;
    self.due_at = due_at&lt;br /&gt;
&lt;br /&gt;
    assignment = Assignment.find(self.assignment_id)&lt;br /&gt;
    participant_mails = find_participant_emails&lt;br /&gt;
&lt;br /&gt;
    if %w[drop_one_member_topics drop_outstanding_reviews compare_files_with_simicheck].include?(self.deadline_type)&lt;br /&gt;
      drop_one_member_topics if self.deadline_type == &amp;quot;drop_outstanding_reviews&amp;quot; &amp;amp;&amp;amp; assignment.team_assignment&lt;br /&gt;
      drop_outstanding_reviews if self.deadline_type == &amp;quot;drop_outstanding_reviews&amp;quot;&lt;br /&gt;
      perform_simicheck_comparisons(self.assignment_id) if self.deadline_type == &amp;quot;compare_files_with_simicheck&amp;quot;&lt;br /&gt;
    else&lt;br /&gt;
      # Can we rename deadline_type(metareview) to &amp;quot;teammate review&amp;quot;. If, yes then we donot need this if clause below!&lt;br /&gt;
      deadlineText = if self.deadline_type == &amp;quot;metareview&amp;quot;&lt;br /&gt;
                       &amp;quot;teammate review&amp;quot;&lt;br /&gt;
                     else&lt;br /&gt;
                       self.deadline_type&lt;br /&gt;
      end&lt;br /&gt;
&lt;br /&gt;
      email_reminder(participant_mails, deadlineText) unless participant_mails.empty?&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The processing was different depending on the &amp;lt;code&amp;gt;deadline_type&amp;lt;/code&amp;gt;. The &amp;lt;code&amp;gt;deadline_type&amp;lt;/code&amp;gt;s in&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
%w[drop_one_member_topics drop_outstanding_reviews compare_files_with_simicheck]&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
did not lead to an email reminder being sent, but they were still handled in this &amp;lt;code&amp;gt;MailWorker&amp;lt;/code&amp;gt; class.&lt;br /&gt;
&lt;br /&gt;
To make the code more manageable and easier to follow, it made sense to break up the responsibilities of this single &amp;lt;code&amp;gt;MailWorker&amp;lt;/code&amp;gt; class into multiple workers:&lt;br /&gt;
* &amp;lt;code&amp;gt;SimicheckWorker&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;DropOutstandingReviewsWorker&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;MailWorker&amp;lt;/code&amp;gt;&lt;br /&gt;
All three workers extended an &amp;quot;abstract class&amp;quot; called &amp;lt;code&amp;gt;Worker&amp;lt;/code&amp;gt; that contained the Sidekiq-related &amp;lt;code&amp;gt;include&amp;lt;/code&amp;gt; and the queue name to which all jobs would be sent.&lt;br /&gt;
&lt;br /&gt;
For simplicity, we still had all new workers continue to use a single queue, which we renamed from &amp;lt;code&amp;gt;mailers&amp;lt;/code&amp;gt; to &amp;lt;code&amp;gt;jobs&amp;lt;/code&amp;gt;. A future improvement could divide these jobs to go to multiple different queues if needed.&lt;br /&gt;
&lt;br /&gt;
=== Remove all code related to the &amp;lt;code&amp;gt;drop_one_member_topics&amp;lt;/code&amp;gt; deadline type ===&lt;br /&gt;
It was decided that code used for dropping one member or two member teams from topics would never need to be implemented in the Expertiza website. Thus, we removed all code related to the drop_one_member_topics method within the Expertiza beta. This involved removing the &amp;lt;code&amp;gt;drop_one_member_topics&amp;lt;/code&amp;gt; function from &amp;lt;code&amp;gt;drop_outstanding_reviews_mail_worker.rb&amp;lt;/code&amp;gt;, now renamed &amp;lt;code&amp;gt;drop_outstanding_reviews_worker.rb&amp;lt;/code&amp;gt;. The &amp;lt;code&amp;gt;drop_one_member_topics&amp;lt;/code&amp;gt; method was called from the &amp;lt;code&amp;gt;prepare_data&amp;lt;/code&amp;gt; method, which was then called by the Sidekiq method &amp;lt;code&amp;gt;perform&amp;lt;/code&amp;gt; so we removed this call. The &amp;lt;code&amp;gt;drop_one_member_topics&amp;lt;/code&amp;gt; was also referenced in &amp;lt;code&amp;gt;assignment_form.rb&amp;lt;/code&amp;gt; using &amp;lt;code&amp;gt;add_delayed_job&amp;lt;/code&amp;gt; in the &amp;lt;code&amp;gt;add_to_delayed_queue&amp;lt;/code&amp;gt; method and in &amp;lt;code&amp;gt;delayed_mailer.html.erb&amp;lt;/code&amp;gt; as an option for the handler so both of these code snippets were removed as well.&lt;br /&gt;
&lt;br /&gt;
=== Update and add unit tests according to the above changes ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Test all new worker classes to ensure Sidekiq jobs were being dequeued and run as expected ===&lt;br /&gt;
==== Sidekiq setup ====&lt;br /&gt;
In order to test the Sidekiq workers, a few steps were needed to set up the workers and run Sidekiq (steps were obtained from [https://tudip.com/blog-post/how-to-use-sidekiq-in-rails-for-background-processing/ this site]):&lt;br /&gt;
# Initialize three new workers, each having one of the three new worker types:&lt;br /&gt;
## &amp;lt;code&amp;gt;rails g sidekiq:worker SimicheckWorker&amp;lt;/code&amp;gt;&lt;br /&gt;
## &amp;lt;code&amp;gt;rails g sidekiq:worker DropOutstandingReviewsWorker&amp;lt;/code&amp;gt;&lt;br /&gt;
## &amp;lt;code&amp;gt;rails g sidekiq:worker MailWorker&amp;lt;/code&amp;gt;&lt;br /&gt;
# In a terminal separate from the one in which the main rails application is running, run&lt;br /&gt;
&amp;lt;blockquote&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
bundle exec sidekiq&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This Sidekiq-specific terminal will show logs and printed statements from the workers.&lt;br /&gt;
&lt;br /&gt;
==== SimicheckWorker Test ====&lt;br /&gt;
&lt;br /&gt;
==== MailWorker and DropOustandingReviews Test ====&lt;br /&gt;
The Mail Worker sends out notifications to students if the due date of an assignment is changed. Drop Outstanding Reviews Worker drops all reviews that had not been worked on before the due date was changed. These both can be tested together, as when an assignment with a review is updated, Sidekiq should queue both the jobs for Mail Worker and Drop Outstanding Reviews Worker. To test these, we first created an assignment with the default options by logging in as an instructor, going to '''Manage'''&amp;gt;'''Assignments''' in the navigation, and clicking the plus button in the top right corner on the '''Manage Assignments'''. Make sure when creating the assignment to go to the '''Due Dates''' tab and assign due dates for both the assignment and the review. We then assigned student7613 to the assignment we had created by clicking the person with the plus icon in the icons next to the assignment on the '''Manage Assignments''' page. At this point, we realized we need to alter the code to test if the code was properly queuing the Mail Worker because the current if statement to add items to the delayed queue required that it have a late policy. However, the late policy code is not currently working. Thus, in the &amp;lt;code&amp;gt;assignment_form.rb&amp;lt;/code&amp;gt; model file, we edited the following code:&lt;br /&gt;
&lt;br /&gt;
[[File:Change_late_policy.png|950px|Late policy code to alter]]&lt;br /&gt;
&lt;br /&gt;
We removed &amp;lt;code&amp;gt;and has_late_policy&amp;lt;/code&amp;gt; so &amp;lt;code&amp;gt;add_delayed_queue&amp;lt;/code&amp;gt; can run even without late policies being implemented. After saving this file, we started up Expertiza again and went to the assignment that student7613 had been assigned to. We then edited the assignment, went to the due dates tab, changed the due date on the review to be a day ahead of its current due date, and pressed save. To ensure that the assignments were now queued on Sidekiq, we visited the Sidekiq UI by going to [Expertiza VCL URL]/sidekiq. Upon arriving on this page, we verified that the jobs added to the queue were correct by clicking to '''Scheduled'''. After arriving on this page, we saw the following:&lt;br /&gt;
&lt;br /&gt;
[[File:Sidekiq-jobs.png|950px|Sidekiq jobs]]&lt;br /&gt;
&lt;br /&gt;
The job '''MailWorker''' that had been queued successfully shows that our refactoring of Mail Worker had worked properly and the Mail Worker was operational. The job '''DropOutstandingReviewsWorker''' showed that our refactoring of Drop Outstanding Reviews Worker had also been done correctly.&lt;br /&gt;
&lt;br /&gt;
=== Sidekiq UI ===&lt;br /&gt;
To see which messages were being enqueued and dequeued in Sidekiq, we use the Sidekiq user interface, which can be accessed via the &amp;lt;code&amp;gt;/sidekiq&amp;lt;/code&amp;gt; route of the application.&lt;br /&gt;
[[File:Sidekiq-ui.png|950px|The Sidekiq UI]]&lt;br /&gt;
&lt;br /&gt;
=== Code Cleanup ===&lt;br /&gt;
Smaller improvements done while implementing the main tasks included:&lt;br /&gt;
* Using ActiveSupport::Duration objects in order to calculate the minutes and seconds related to the dequeue times&lt;br /&gt;
* Refactoring the time calculations for the dequeue times to the DueDate class&lt;br /&gt;
* Correcting the parameters passed to the workers, which were previously incorrect. As an example:&lt;br /&gt;
&amp;lt;blockquote&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def add_delayed_job(_assignment, deadline_type, due_date, min_left)&lt;br /&gt;
    delayed_job_id = MailWorker.perform_in(min_left * 60, due_date.parent_id, deadline_type, due_date.due_at)&lt;br /&gt;
    delayed_job_id&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
The first parameter after the time delay must be assignment ID, and &amp;lt;code&amp;gt;due_date.parent_id&amp;lt;/code&amp;gt; is not an assignment ID.&lt;br /&gt;
&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
* Removing whitespace issues reported by codeclimate&lt;br /&gt;
* Refactoring all variable names to be in snake_case&lt;br /&gt;
* Removing identical blocks of code&lt;br /&gt;
* Adding method comments to make methods more understandable&lt;br /&gt;
* ...&lt;/div&gt;</summary>
		<author><name>Agcarrut</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2021_-_E2144._Refactor_delayed_mailer_and_scheduled_task&amp;diff=140099</id>
		<title>CSC/ECE 517 Fall 2021 - E2144. Refactor delayed mailer and scheduled task</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2021_-_E2144._Refactor_delayed_mailer_and_scheduled_task&amp;diff=140099"/>
		<updated>2021-10-26T17:50:52Z</updated>

		<summary type="html">&lt;p&gt;Agcarrut: /* MailWorker and DropOustandingReviews Test */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;__TOC__&lt;br /&gt;
&lt;br /&gt;
== Background ==&lt;br /&gt;
This project revolves around the Sidekiq gem for asynchronous processing of email tasks. It has a queue system to hold and then process jobs. Sidekiq’s queue replaces DelayedMailer’s queue. The previous team that worked on this also created a method &amp;lt;code&amp;gt;perform()&amp;lt;/code&amp;gt; to gather email IDs of all participants in an assignment and send them an email reminder. Some test cases exist for this work.&lt;br /&gt;
&lt;br /&gt;
=== Previous Setup ===&lt;br /&gt;
Initial work can be found [https://expertiza.csc.ncsu.edu/index.php/E1835_Refactor_delayed_mailer_and_scheduled_task here].&lt;br /&gt;
&lt;br /&gt;
Code in the [https://github.com/expertiza/expertiza/pull/1245/files pull request] was found to be reasonable and working. The method &amp;lt;code&amp;gt;perform()&amp;lt;/code&amp;gt; has:&lt;br /&gt;
{| class=wikitable style=text-align:right&lt;br /&gt;
|+ Metrics for &amp;lt;code&amp;gt;perform&amp;lt;/code&amp;gt; method&lt;br /&gt;
|-&lt;br /&gt;
! Metric !! Current Value !! Limit&lt;br /&gt;
|-&lt;br /&gt;
! Cognitive Complexity&lt;br /&gt;
| 15 || 5&lt;br /&gt;
|-&lt;br /&gt;
! Cyclomatic Complexity&lt;br /&gt;
| 8 || 6&lt;br /&gt;
|-&lt;br /&gt;
! Assignment Branch Condition size&lt;br /&gt;
| 22.93 || 15&lt;br /&gt;
|-&lt;br /&gt;
! Perceived complexity&lt;br /&gt;
| 10 || 7&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Previous pull request also has duplicated commit messages and the commits need to be squashed.&lt;br /&gt;
&lt;br /&gt;
Files involved (some changed should not have been changed):&lt;br /&gt;
* app/controllers/assignments_controller.rb&lt;br /&gt;
* app/mailers/mail_worker.rb&lt;br /&gt;
* app/models/assignment_form.rb&lt;br /&gt;
* config/sidekiq.yml&lt;br /&gt;
* spec/models/assignment_form_spec.rb&lt;br /&gt;
* spec/sidekiq_mail_worker_spec.rb&lt;br /&gt;
* spec/spec_helper.rb&lt;br /&gt;
&lt;br /&gt;
There are minor styling issues such as missing or trailing whitespaces, lines that are too long, extra empty line, unused arguments.&lt;br /&gt;
&lt;br /&gt;
=== Problem Statement ===&lt;br /&gt;
&lt;br /&gt;
This project revolves around the Sidekiq gem for asynchronous processing of email tasks. It has a queue system to hold and then process jobs. Sidekiq's queue replaces DelayedMailer’s queue. The previous team that worked on this also created a method perform() to gather email IDs of all participants in an assignment and send them an email reminder. Some test cases exist for this work.&lt;br /&gt;
The project was partially merged.&lt;br /&gt;
​&lt;br /&gt;
&lt;br /&gt;
What needs to be done:  &lt;br /&gt;
Feedback from the previous team (E1835) is:&lt;br /&gt;
Code in pull request seems pretty reasonable.  Some concerns wrt. naming functions, but otherwise reviewers seem to agree that the code is good.&lt;br /&gt;
​&lt;br /&gt;
&lt;br /&gt;
Your pull request has many duplicated commit messages. Please try to &amp;lt;code&amp;gt;squash&amp;lt;/code&amp;gt; similar commits.&lt;br /&gt;
And using meaningful commit messages later.&lt;br /&gt;
​&lt;br /&gt;
&lt;br /&gt;
You should commit changes to the DB schema (&amp;lt;code&amp;gt;db/schema.rb&amp;lt;/code&amp;gt;) only if you have created new DB migrations.&lt;br /&gt;
Please double check your code. If you did not aim to change the DB, please revert the DB schema changes. ***** Important, try not to change the DB.&lt;br /&gt;
​&lt;br /&gt;
&lt;br /&gt;
You should not change &amp;lt;code&amp;gt;rails_helper.rb&amp;lt;/code&amp;gt; or &amp;lt;code&amp;gt;spec_helper.rb&amp;lt;/code&amp;gt; file; please revert these changes.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The previous team’s code needs a refactor in some places, though the actual function of it seems solid. It is very possible that in the three years since this code has been worked on, more mailer functionality has been added. There are other teams this semester working on mailer code as well. Try to keep your code as contained and simple as possible, so that merging these projects is possible.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Summary of Work Needed ==&lt;br /&gt;
After discussing with our project mentor and Dr. Gehringer, we determined the main tasks to be the following:&lt;br /&gt;
# Refactor the single Sidekiq worker into multiple workers&lt;br /&gt;
# Remove all code related to the &amp;lt;code&amp;gt;drop_one_member_topics&amp;lt;/code&amp;gt; deadline type&lt;br /&gt;
# Update and add unit tests according to the above changes&lt;br /&gt;
# Test all new worker classes to ensure Sidekiq jobs were being dequeued and run as expected&lt;br /&gt;
# Code cleanup&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Refactor the single Sidekiq worker into multiple workers ===&lt;br /&gt;
Previously there was only a single worker class that handled all types of jobs. Its top-level method &amp;lt;code&amp;gt;perform&amp;lt;/code&amp;gt; looked like the following.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def perform(assignment_id, deadline_type, due_at)&lt;br /&gt;
    self.assignment_id = assignment_id&lt;br /&gt;
    self.deadline_type = deadline_type&lt;br /&gt;
    self.due_at = due_at&lt;br /&gt;
&lt;br /&gt;
    assignment = Assignment.find(self.assignment_id)&lt;br /&gt;
    participant_mails = find_participant_emails&lt;br /&gt;
&lt;br /&gt;
    if %w[drop_one_member_topics drop_outstanding_reviews compare_files_with_simicheck].include?(self.deadline_type)&lt;br /&gt;
      drop_one_member_topics if self.deadline_type == &amp;quot;drop_outstanding_reviews&amp;quot; &amp;amp;&amp;amp; assignment.team_assignment&lt;br /&gt;
      drop_outstanding_reviews if self.deadline_type == &amp;quot;drop_outstanding_reviews&amp;quot;&lt;br /&gt;
      perform_simicheck_comparisons(self.assignment_id) if self.deadline_type == &amp;quot;compare_files_with_simicheck&amp;quot;&lt;br /&gt;
    else&lt;br /&gt;
      # Can we rename deadline_type(metareview) to &amp;quot;teammate review&amp;quot;. If, yes then we donot need this if clause below!&lt;br /&gt;
      deadlineText = if self.deadline_type == &amp;quot;metareview&amp;quot;&lt;br /&gt;
                       &amp;quot;teammate review&amp;quot;&lt;br /&gt;
                     else&lt;br /&gt;
                       self.deadline_type&lt;br /&gt;
      end&lt;br /&gt;
&lt;br /&gt;
      email_reminder(participant_mails, deadlineText) unless participant_mails.empty?&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The processing was different depending on the &amp;lt;code&amp;gt;deadline_type&amp;lt;/code&amp;gt;. The &amp;lt;code&amp;gt;deadline_type&amp;lt;/code&amp;gt;s in&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
%w[drop_one_member_topics drop_outstanding_reviews compare_files_with_simicheck]&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
did not lead to an email reminder being sent, but they were still handled in this &amp;lt;code&amp;gt;MailWorker&amp;lt;/code&amp;gt; class.&lt;br /&gt;
&lt;br /&gt;
To make the code more manageable and easier to follow, it made sense to break up the responsibilities of this single &amp;lt;code&amp;gt;MailWorker&amp;lt;/code&amp;gt; class into multiple workers:&lt;br /&gt;
* &amp;lt;code&amp;gt;SimicheckWorker&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;DropOutstandingReviewsWorker&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;MailWorker&amp;lt;/code&amp;gt;&lt;br /&gt;
All three workers extended an &amp;quot;abstract class&amp;quot; called &amp;lt;code&amp;gt;Worker&amp;lt;/code&amp;gt; that contained the Sidekiq-related &amp;lt;code&amp;gt;include&amp;lt;/code&amp;gt; and the queue name to which all jobs would be sent.&lt;br /&gt;
&lt;br /&gt;
For simplicity, we still had all new workers continue to use a single queue, which we renamed from &amp;lt;code&amp;gt;mailers&amp;lt;/code&amp;gt; to &amp;lt;code&amp;gt;jobs&amp;lt;/code&amp;gt;. A future improvement could divide these jobs to go to multiple different queues if needed.&lt;br /&gt;
&lt;br /&gt;
=== Remove all code related to the &amp;lt;code&amp;gt;drop_one_member_topics&amp;lt;/code&amp;gt; deadline type ===&lt;br /&gt;
It was decided that code used for dropping one member or two member teams from topics would never need to be implemented in the Expertiza website. Thus, we removed all code related to the drop_one_member_topics method within the Expertiza beta. This involved removing the &amp;lt;code&amp;gt;drop_one_member_topics&amp;lt;/code&amp;gt; function from &amp;lt;code&amp;gt;drop_outstanding_reviews_mail_worker.rb&amp;lt;/code&amp;gt;, now renamed &amp;lt;code&amp;gt;drop_outstanding_reviews_worker.rb&amp;lt;/code&amp;gt;. The &amp;lt;code&amp;gt;drop_one_member_topics&amp;lt;/code&amp;gt; method was called from the &amp;lt;code&amp;gt;prepare_data&amp;lt;/code&amp;gt; method, which was then called by the Sidekiq method &amp;lt;code&amp;gt;perform&amp;lt;/code&amp;gt; so we removed this call. The &amp;lt;code&amp;gt;drop_one_member_topics&amp;lt;/code&amp;gt; was also referenced in &amp;lt;code&amp;gt;assignment_form.rb&amp;lt;/code&amp;gt; using &amp;lt;code&amp;gt;add_delayed_job&amp;lt;/code&amp;gt; in the &amp;lt;code&amp;gt;add_to_delayed_queue&amp;lt;/code&amp;gt; method and in &amp;lt;code&amp;gt;delayed_mailer.html.erb&amp;lt;/code&amp;gt; as an option for the handler so both of these code snippets were removed as well.&lt;br /&gt;
&lt;br /&gt;
=== Update and add unit tests according to the above changes ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Test all new worker classes to ensure Sidekiq jobs were being dequeued and run as expected ===&lt;br /&gt;
==== Sidekiq setup ====&lt;br /&gt;
In order to test the Sidekiq workers, a few steps were needed to set up the workers and run Sidekiq (steps were obtained from [https://tudip.com/blog-post/how-to-use-sidekiq-in-rails-for-background-processing/ this site]):&lt;br /&gt;
# Initialize three new workers, each having one of the three new worker types:&lt;br /&gt;
## &amp;lt;code&amp;gt;rails g sidekiq:worker SimicheckWorker&amp;lt;/code&amp;gt;&lt;br /&gt;
## &amp;lt;code&amp;gt;rails g sidekiq:worker DropOutstandingReviewsWorker&amp;lt;/code&amp;gt;&lt;br /&gt;
## &amp;lt;code&amp;gt;rails g sidekiq:worker MailWorker&amp;lt;/code&amp;gt;&lt;br /&gt;
# In a terminal separate from the one in which the main rails application is running, run&lt;br /&gt;
&amp;lt;blockquote&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
bundle exec sidekiq&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This Sidekiq-specific terminal will show logs and printed statements from the workers.&lt;br /&gt;
&lt;br /&gt;
==== SimicheckWorker Test ====&lt;br /&gt;
&lt;br /&gt;
==== MailWorker and DropOustandingReviews Test ====&lt;br /&gt;
The Mail Worker sends out notifications to students if the due date of an assignment is changed. To test Mail Worker, we first created an assignment with the default options by logging in as an instructor, going to '''Manage'''&amp;gt;'''Assignments''' in the navigation, and clicking the plus button in the top right corner on the '''Manage Assignments'''. We then assigned student7613 to the assignment we had created by clicking the person with the plus icon in the icons next to the assignment on the '''Manage Assignments''' page. At this point, we realized we need to alter the code to test if the code was properly queuing the Mail Worker because the current if statement to add items to the delayed queue required that it have a late policy. However, the late policy code is not currently working. Thus, in the &amp;lt;code&amp;gt;assignment_form.rb&amp;lt;/code&amp;gt; model file, we edited the following code:&lt;br /&gt;
&lt;br /&gt;
[[File:Change_late_policy.png|950px|Late policy code to alter]]&lt;br /&gt;
&lt;br /&gt;
We removed &amp;lt;code&amp;gt;and has_late_policy&amp;lt;/code&amp;gt; so &amp;lt;code&amp;gt;add_delayed_queue&amp;lt;/code&amp;gt; can run even without late policies being implemented. After saving this file, we started up Expertiza again and went to the assignment that student7613 had been assigned to. We then edited the assignment, went to the due dates tab, changed the due date on the review to be a day ahead of its current due date, and pressed save. To ensure that the assignments were now queued on Sidekiq, we visited the Sidekiq UI by going to [Expertiza VCL URL]/sidekiq. Upon arriving on this page, we verified that the jobs added to the queue were correct by clicking to '''Scheduled'''. After arriving on this page, we saw the following:&lt;br /&gt;
&lt;br /&gt;
[[File:Sidekiq-jobs.png|950px|Sidekiq jobs]]&lt;br /&gt;
&lt;br /&gt;
The job '''MailWorker''' that had been queued successfully shows that our refactoring had worked properly and the Mail Worker was operational.&lt;br /&gt;
&lt;br /&gt;
=== Sidekiq UI ===&lt;br /&gt;
To see which messages were being enqueued and dequeued in Sidekiq, we use the Sidekiq user interface, which can be accessed via the &amp;lt;code&amp;gt;/sidekiq&amp;lt;/code&amp;gt; route of the application.&lt;br /&gt;
[[File:Sidekiq-ui.png|950px|The Sidekiq UI]]&lt;br /&gt;
&lt;br /&gt;
=== Code Cleanup ===&lt;br /&gt;
Smaller improvements done while implementing the main tasks included:&lt;br /&gt;
* Using ActiveSupport::Duration objects in order to calculate the minutes and seconds related to the dequeue times&lt;br /&gt;
* Refactoring the time calculations for the dequeue times to the DueDate class&lt;br /&gt;
* Correcting the parameters passed to the workers, which were previously incorrect. As an example:&lt;br /&gt;
&amp;lt;blockquote&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def add_delayed_job(_assignment, deadline_type, due_date, min_left)&lt;br /&gt;
    delayed_job_id = MailWorker.perform_in(min_left * 60, due_date.parent_id, deadline_type, due_date.due_at)&lt;br /&gt;
    delayed_job_id&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
The first parameter after the time delay must be assignment ID, and &amp;lt;code&amp;gt;due_date.parent_id&amp;lt;/code&amp;gt; is not an assignment ID.&lt;br /&gt;
&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
* Removing whitespace issues reported by codeclimate&lt;br /&gt;
* Refactoring all variable names to be in snake_case&lt;br /&gt;
* Removing identical blocks of code&lt;br /&gt;
* Adding method comments to make methods more understandable&lt;br /&gt;
* ...&lt;/div&gt;</summary>
		<author><name>Agcarrut</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2021_-_E2144._Refactor_delayed_mailer_and_scheduled_task&amp;diff=140091</id>
		<title>CSC/ECE 517 Fall 2021 - E2144. Refactor delayed mailer and scheduled task</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2021_-_E2144._Refactor_delayed_mailer_and_scheduled_task&amp;diff=140091"/>
		<updated>2021-10-26T17:24:54Z</updated>

		<summary type="html">&lt;p&gt;Agcarrut: /* DropOutstandingReviewsWorker Test */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;__TOC__&lt;br /&gt;
&lt;br /&gt;
== Background ==&lt;br /&gt;
This project revolves around the Sidekiq gem for asynchronous processing of email tasks. It has a queue system to hold and then process jobs. Sidekiq’s queue replaces DelayedMailer’s queue. The previous team that worked on this also created a method &amp;lt;code&amp;gt;perform()&amp;lt;/code&amp;gt; to gather email IDs of all participants in an assignment and send them an email reminder. Some test cases exist for this work.&lt;br /&gt;
&lt;br /&gt;
=== Previous Setup ===&lt;br /&gt;
Initial work can be found [https://expertiza.csc.ncsu.edu/index.php/E1835_Refactor_delayed_mailer_and_scheduled_task here].&lt;br /&gt;
&lt;br /&gt;
Code in the [https://github.com/expertiza/expertiza/pull/1245/files pull request] was found to be reasonable and working. The method &amp;lt;code&amp;gt;perform()&amp;lt;/code&amp;gt; has:&lt;br /&gt;
{| class=wikitable style=text-align:right&lt;br /&gt;
|+ Metrics for &amp;lt;code&amp;gt;perform&amp;lt;/code&amp;gt; method&lt;br /&gt;
|-&lt;br /&gt;
! Metric !! Current Value !! Limit&lt;br /&gt;
|-&lt;br /&gt;
! Cognitive Complexity&lt;br /&gt;
| 15 || 5&lt;br /&gt;
|-&lt;br /&gt;
! Cyclomatic Complexity&lt;br /&gt;
| 8 || 6&lt;br /&gt;
|-&lt;br /&gt;
! Assignment Branch Condition size&lt;br /&gt;
| 22.93 || 15&lt;br /&gt;
|-&lt;br /&gt;
! Perceived complexity&lt;br /&gt;
| 10 || 7&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Previous pull request also has duplicated commit messages and the commits need to be squashed.&lt;br /&gt;
&lt;br /&gt;
Files involved (some changed should not have been changed):&lt;br /&gt;
* app/controllers/assignments_controller.rb&lt;br /&gt;
* app/mailers/mail_worker.rb&lt;br /&gt;
* app/models/assignment_form.rb&lt;br /&gt;
* config/sidekiq.yml&lt;br /&gt;
* spec/models/assignment_form_spec.rb&lt;br /&gt;
* spec/sidekiq_mail_worker_spec.rb&lt;br /&gt;
* spec/spec_helper.rb&lt;br /&gt;
&lt;br /&gt;
There are minor styling issues such as missing or trailing whitespaces, lines that are too long, extra empty line, unused arguments.&lt;br /&gt;
&lt;br /&gt;
=== Problem Statement ===&lt;br /&gt;
&lt;br /&gt;
This project revolves around the Sidekiq gem for asynchronous processing of email tasks. It has a queue system to hold and then process jobs. Sidekiq's queue replaces DelayedMailer’s queue. The previous team that worked on this also created a method perform() to gather email IDs of all participants in an assignment and send them an email reminder. Some test cases exist for this work.&lt;br /&gt;
The project was partially merged.&lt;br /&gt;
​&lt;br /&gt;
&lt;br /&gt;
What needs to be done:  &lt;br /&gt;
Feedback from the previous team (E1835) is:&lt;br /&gt;
Code in pull request seems pretty reasonable.  Some concerns wrt. naming functions, but otherwise reviewers seem to agree that the code is good.&lt;br /&gt;
​&lt;br /&gt;
&lt;br /&gt;
Your pull request has many duplicated commit messages. Please try to &amp;lt;code&amp;gt;squash&amp;lt;/code&amp;gt; similar commits.&lt;br /&gt;
And using meaningful commit messages later.&lt;br /&gt;
​&lt;br /&gt;
&lt;br /&gt;
You should commit changes to the DB schema (&amp;lt;code&amp;gt;db/schema.rb&amp;lt;/code&amp;gt;) only if you have created new DB migrations.&lt;br /&gt;
Please double check your code. If you did not aim to change the DB, please revert the DB schema changes. ***** Important, try not to change the DB.&lt;br /&gt;
​&lt;br /&gt;
&lt;br /&gt;
You should not change &amp;lt;code&amp;gt;rails_helper.rb&amp;lt;/code&amp;gt; or &amp;lt;code&amp;gt;spec_helper.rb&amp;lt;/code&amp;gt; file; please revert these changes.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The previous team’s code needs a refactor in some places, though the actual function of it seems solid. It is very possible that in the three years since this code has been worked on, more mailer functionality has been added. There are other teams this semester working on mailer code as well. Try to keep your code as contained and simple as possible, so that merging these projects is possible.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Summary of Work Needed ==&lt;br /&gt;
After discussing with our project mentor and Dr. Gehringer, we determined the main tasks to be the following:&lt;br /&gt;
# Refactor the single Sidekiq worker into multiple workers&lt;br /&gt;
# Remove all code related to the &amp;lt;code&amp;gt;drop_one_member_topics&amp;lt;/code&amp;gt; deadline type&lt;br /&gt;
# Update and add unit tests according to the above changes&lt;br /&gt;
# Test all new worker classes to ensure Sidekiq jobs were being dequeued and run as expected&lt;br /&gt;
# Code cleanup&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Refactor the single Sidekiq worker into multiple workers ===&lt;br /&gt;
Previously there was only a single worker class that handled all types of jobs. Its top-level method &amp;lt;code&amp;gt;perform&amp;lt;/code&amp;gt; looked like the following.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def perform(assignment_id, deadline_type, due_at)&lt;br /&gt;
    self.assignment_id = assignment_id&lt;br /&gt;
    self.deadline_type = deadline_type&lt;br /&gt;
    self.due_at = due_at&lt;br /&gt;
&lt;br /&gt;
    assignment = Assignment.find(self.assignment_id)&lt;br /&gt;
    participant_mails = find_participant_emails&lt;br /&gt;
&lt;br /&gt;
    if %w[drop_one_member_topics drop_outstanding_reviews compare_files_with_simicheck].include?(self.deadline_type)&lt;br /&gt;
      drop_one_member_topics if self.deadline_type == &amp;quot;drop_outstanding_reviews&amp;quot; &amp;amp;&amp;amp; assignment.team_assignment&lt;br /&gt;
      drop_outstanding_reviews if self.deadline_type == &amp;quot;drop_outstanding_reviews&amp;quot;&lt;br /&gt;
      perform_simicheck_comparisons(self.assignment_id) if self.deadline_type == &amp;quot;compare_files_with_simicheck&amp;quot;&lt;br /&gt;
    else&lt;br /&gt;
      # Can we rename deadline_type(metareview) to &amp;quot;teammate review&amp;quot;. If, yes then we donot need this if clause below!&lt;br /&gt;
      deadlineText = if self.deadline_type == &amp;quot;metareview&amp;quot;&lt;br /&gt;
                       &amp;quot;teammate review&amp;quot;&lt;br /&gt;
                     else&lt;br /&gt;
                       self.deadline_type&lt;br /&gt;
      end&lt;br /&gt;
&lt;br /&gt;
      email_reminder(participant_mails, deadlineText) unless participant_mails.empty?&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The processing was different depending on the &amp;lt;code&amp;gt;deadline_type&amp;lt;/code&amp;gt;. The &amp;lt;code&amp;gt;deadline_type&amp;lt;/code&amp;gt;s in&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
%w[drop_one_member_topics drop_outstanding_reviews compare_files_with_simicheck]&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
did not lead to an email reminder being sent, but they were still handled in this &amp;lt;code&amp;gt;MailWorker&amp;lt;/code&amp;gt; class.&lt;br /&gt;
&lt;br /&gt;
To make the code more manageable and easier to follow, it made sense to break up the responsibilities of this single &amp;lt;code&amp;gt;MailWorker&amp;lt;/code&amp;gt; class into multiple workers:&lt;br /&gt;
* &amp;lt;code&amp;gt;SimicheckWorker&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;DropOutstandingReviewsWorker&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;MailWorker&amp;lt;/code&amp;gt;&lt;br /&gt;
All three workers extended an &amp;quot;abstract class&amp;quot; called &amp;lt;code&amp;gt;Worker&amp;lt;/code&amp;gt; that contained the Sidekiq-related &amp;lt;code&amp;gt;include&amp;lt;/code&amp;gt; and the queue name to which all jobs would be sent.&lt;br /&gt;
&lt;br /&gt;
For simplicity, we still had all new workers continue to use a single queue, which we renamed from &amp;lt;code&amp;gt;mailers&amp;lt;/code&amp;gt; to &amp;lt;code&amp;gt;jobs&amp;lt;/code&amp;gt;. A future improvement could divide these jobs to go to multiple different queues if needed.&lt;br /&gt;
&lt;br /&gt;
=== Remove all code related to the &amp;lt;code&amp;gt;drop_one_member_topics&amp;lt;/code&amp;gt; deadline type ===&lt;br /&gt;
It was decided that code used for dropping one member or two member teams from topics would never need to be implemented in the Expertiza website. Thus, we removed all code related to the drop_one_member_topics method within the Expertiza beta. This involved removing the &amp;lt;code&amp;gt;drop_one_member_topics&amp;lt;/code&amp;gt; function from &amp;lt;code&amp;gt;drop_outstanding_reviews_mail_worker.rb&amp;lt;/code&amp;gt;, now renamed &amp;lt;code&amp;gt;drop_outstanding_reviews_worker.rb&amp;lt;/code&amp;gt;. The &amp;lt;code&amp;gt;drop_one_member_topics&amp;lt;/code&amp;gt; method was called from the &amp;lt;code&amp;gt;prepare_data&amp;lt;/code&amp;gt; method, which was then called by the Sidekiq method &amp;lt;code&amp;gt;perform&amp;lt;/code&amp;gt; so we removed this call. The &amp;lt;code&amp;gt;drop_one_member_topics&amp;lt;/code&amp;gt; was also referenced in &amp;lt;code&amp;gt;assignment_form.rb&amp;lt;/code&amp;gt; using &amp;lt;code&amp;gt;add_delayed_job&amp;lt;/code&amp;gt; in the &amp;lt;code&amp;gt;add_to_delayed_queue&amp;lt;/code&amp;gt; method and in &amp;lt;code&amp;gt;delayed_mailer.html.erb&amp;lt;/code&amp;gt; as an option for the handler so both of these code snippets were removed as well.&lt;br /&gt;
&lt;br /&gt;
=== Update and add unit tests according to the above changes ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Test all new worker classes to ensure Sidekiq jobs were being dequeued and run as expected ===&lt;br /&gt;
==== Sidekiq setup ====&lt;br /&gt;
In order to test the Sidekiq workers, a few steps were needed to set up the workers and run Sidekiq (steps were obtained from [https://tudip.com/blog-post/how-to-use-sidekiq-in-rails-for-background-processing/ this site]):&lt;br /&gt;
# Initialize three new workers, each having one of the three new worker types:&lt;br /&gt;
## &amp;lt;code&amp;gt;rails g sidekiq:worker SimicheckWorker&amp;lt;/code&amp;gt;&lt;br /&gt;
## &amp;lt;code&amp;gt;rails g sidekiq:worker DropOutstandingReviewsWorker&amp;lt;/code&amp;gt;&lt;br /&gt;
## &amp;lt;code&amp;gt;rails g sidekiq:worker MailWorker&amp;lt;/code&amp;gt;&lt;br /&gt;
# In a terminal separate from the one in which the main rails application is running, run&lt;br /&gt;
&amp;lt;blockquote&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
bundle exec sidekiq&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This Sidekiq-specific terminal will show logs and printed statements from the workers.&lt;br /&gt;
&lt;br /&gt;
==== SimicheckWorker Test ====&lt;br /&gt;
&lt;br /&gt;
==== MailWorker and DropOustandingReviews Test ====&lt;br /&gt;
The Mail Worker sends out notifications to students if the due date of an assignment is changed. To test Mail Worker, we first created an assignment with the default options by logging in as an instructor, going to '''Manage'''&amp;gt;'''Assignments''' in the navigation, and clicking the plus button in the top right corner on the '''Manage Assignments'''. We then assigned student7613 to the assignment we had created by clicking the person with the plus icon in the icons next to the assignment on the '''Manage Assignments''' page. At this point, we realized we need to alter the code to test if the code was properly queuing the Mail Worker because the current if statement to add items to the delayed queue required that it have a late policy. However, the late policy code is not currently working. Thus, in the &amp;lt;code&amp;gt;assignment_form.rb&amp;lt;/code&amp;gt; model file, we edited the following code:&lt;br /&gt;
&lt;br /&gt;
[[File:Change_late_policy.png|950px|Late policy code to alter]]&lt;br /&gt;
&lt;br /&gt;
We removed &amp;lt;code&amp;gt;and has_late_policy&amp;lt;/code&amp;gt; so &amp;lt;code&amp;gt;add_delayed_queue&amp;lt;/code&amp;gt; can run even without late policies being implemented. After saving this file, we started up Expertiza again and went to the assignment that student7613 had been assigned to. We then edited the assignment, went to the due dates tab, and changed the due date to be a day ahead of its current due date. Following this, we pressed save on the assignment, and then moved back to the '''Home''' page by hitting '''Home''' on the navigation bar to ensure that everything on the page had been updated correctly. To ensure that the assignments were now queued on Sidekiq, we visited the Sidekiq UI by going to [Expertiza VCL URL]/sidekiq. Upon arriving on this page, we verified that the jobs added to the queue were correct by clicking to '''Scheduled'''. After arriving on this page, we saw the following:&lt;br /&gt;
&lt;br /&gt;
[[File:Sidekiq-jobs.png|950px|Sidekiq jobs]]&lt;br /&gt;
&lt;br /&gt;
The job '''MailWorker''' that had been queued successfully shows that our refactoring had worked properly and the Mail Worker was operational.&lt;br /&gt;
&lt;br /&gt;
=== Sidekiq UI ===&lt;br /&gt;
To see which messages were being enqueued and dequeued in Sidekiq, we use the Sidekiq user interface, which can be accessed via the &amp;lt;code&amp;gt;/sidekiq&amp;lt;/code&amp;gt; route of the application.&lt;br /&gt;
[[File:Sidekiq-ui.png|950px|The Sidekiq UI]]&lt;br /&gt;
&lt;br /&gt;
=== Code Cleanup ===&lt;br /&gt;
Smaller improvements done while implementing the main tasks included:&lt;br /&gt;
* Using ActiveSupport::Duration objects in order to calculate the minutes and seconds related to the dequeue times&lt;br /&gt;
* Refactoring the time calculations for the dequeue times to the DueDate class&lt;br /&gt;
* Correcting the parameters passed to the workers, which were previously incorrect. As an example:&lt;br /&gt;
&amp;lt;blockquote&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def add_delayed_job(_assignment, deadline_type, due_date, min_left)&lt;br /&gt;
    delayed_job_id = MailWorker.perform_in(min_left * 60, due_date.parent_id, deadline_type, due_date.due_at)&lt;br /&gt;
    delayed_job_id&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
The first parameter after the time delay must be assignment ID, and &amp;lt;code&amp;gt;due_date.parent_id&amp;lt;/code&amp;gt; is not an assignment ID.&lt;br /&gt;
&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
* Removing whitespace issues reported by codeclimate&lt;br /&gt;
* Refactoring all variable names to be in snake_case&lt;br /&gt;
* Removing identical blocks of code&lt;br /&gt;
* Adding method comments to make methods more understandable&lt;br /&gt;
* ...&lt;/div&gt;</summary>
		<author><name>Agcarrut</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2021_-_E2144._Refactor_delayed_mailer_and_scheduled_task&amp;diff=140090</id>
		<title>CSC/ECE 517 Fall 2021 - E2144. Refactor delayed mailer and scheduled task</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2021_-_E2144._Refactor_delayed_mailer_and_scheduled_task&amp;diff=140090"/>
		<updated>2021-10-26T17:24:47Z</updated>

		<summary type="html">&lt;p&gt;Agcarrut: /* MailWorker Test */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;__TOC__&lt;br /&gt;
&lt;br /&gt;
== Background ==&lt;br /&gt;
This project revolves around the Sidekiq gem for asynchronous processing of email tasks. It has a queue system to hold and then process jobs. Sidekiq’s queue replaces DelayedMailer’s queue. The previous team that worked on this also created a method &amp;lt;code&amp;gt;perform()&amp;lt;/code&amp;gt; to gather email IDs of all participants in an assignment and send them an email reminder. Some test cases exist for this work.&lt;br /&gt;
&lt;br /&gt;
=== Previous Setup ===&lt;br /&gt;
Initial work can be found [https://expertiza.csc.ncsu.edu/index.php/E1835_Refactor_delayed_mailer_and_scheduled_task here].&lt;br /&gt;
&lt;br /&gt;
Code in the [https://github.com/expertiza/expertiza/pull/1245/files pull request] was found to be reasonable and working. The method &amp;lt;code&amp;gt;perform()&amp;lt;/code&amp;gt; has:&lt;br /&gt;
{| class=wikitable style=text-align:right&lt;br /&gt;
|+ Metrics for &amp;lt;code&amp;gt;perform&amp;lt;/code&amp;gt; method&lt;br /&gt;
|-&lt;br /&gt;
! Metric !! Current Value !! Limit&lt;br /&gt;
|-&lt;br /&gt;
! Cognitive Complexity&lt;br /&gt;
| 15 || 5&lt;br /&gt;
|-&lt;br /&gt;
! Cyclomatic Complexity&lt;br /&gt;
| 8 || 6&lt;br /&gt;
|-&lt;br /&gt;
! Assignment Branch Condition size&lt;br /&gt;
| 22.93 || 15&lt;br /&gt;
|-&lt;br /&gt;
! Perceived complexity&lt;br /&gt;
| 10 || 7&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Previous pull request also has duplicated commit messages and the commits need to be squashed.&lt;br /&gt;
&lt;br /&gt;
Files involved (some changed should not have been changed):&lt;br /&gt;
* app/controllers/assignments_controller.rb&lt;br /&gt;
* app/mailers/mail_worker.rb&lt;br /&gt;
* app/models/assignment_form.rb&lt;br /&gt;
* config/sidekiq.yml&lt;br /&gt;
* spec/models/assignment_form_spec.rb&lt;br /&gt;
* spec/sidekiq_mail_worker_spec.rb&lt;br /&gt;
* spec/spec_helper.rb&lt;br /&gt;
&lt;br /&gt;
There are minor styling issues such as missing or trailing whitespaces, lines that are too long, extra empty line, unused arguments.&lt;br /&gt;
&lt;br /&gt;
=== Problem Statement ===&lt;br /&gt;
&lt;br /&gt;
This project revolves around the Sidekiq gem for asynchronous processing of email tasks. It has a queue system to hold and then process jobs. Sidekiq's queue replaces DelayedMailer’s queue. The previous team that worked on this also created a method perform() to gather email IDs of all participants in an assignment and send them an email reminder. Some test cases exist for this work.&lt;br /&gt;
The project was partially merged.&lt;br /&gt;
​&lt;br /&gt;
&lt;br /&gt;
What needs to be done:  &lt;br /&gt;
Feedback from the previous team (E1835) is:&lt;br /&gt;
Code in pull request seems pretty reasonable.  Some concerns wrt. naming functions, but otherwise reviewers seem to agree that the code is good.&lt;br /&gt;
​&lt;br /&gt;
&lt;br /&gt;
Your pull request has many duplicated commit messages. Please try to &amp;lt;code&amp;gt;squash&amp;lt;/code&amp;gt; similar commits.&lt;br /&gt;
And using meaningful commit messages later.&lt;br /&gt;
​&lt;br /&gt;
&lt;br /&gt;
You should commit changes to the DB schema (&amp;lt;code&amp;gt;db/schema.rb&amp;lt;/code&amp;gt;) only if you have created new DB migrations.&lt;br /&gt;
Please double check your code. If you did not aim to change the DB, please revert the DB schema changes. ***** Important, try not to change the DB.&lt;br /&gt;
​&lt;br /&gt;
&lt;br /&gt;
You should not change &amp;lt;code&amp;gt;rails_helper.rb&amp;lt;/code&amp;gt; or &amp;lt;code&amp;gt;spec_helper.rb&amp;lt;/code&amp;gt; file; please revert these changes.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The previous team’s code needs a refactor in some places, though the actual function of it seems solid. It is very possible that in the three years since this code has been worked on, more mailer functionality has been added. There are other teams this semester working on mailer code as well. Try to keep your code as contained and simple as possible, so that merging these projects is possible.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Summary of Work Needed ==&lt;br /&gt;
After discussing with our project mentor and Dr. Gehringer, we determined the main tasks to be the following:&lt;br /&gt;
# Refactor the single Sidekiq worker into multiple workers&lt;br /&gt;
# Remove all code related to the &amp;lt;code&amp;gt;drop_one_member_topics&amp;lt;/code&amp;gt; deadline type&lt;br /&gt;
# Update and add unit tests according to the above changes&lt;br /&gt;
# Test all new worker classes to ensure Sidekiq jobs were being dequeued and run as expected&lt;br /&gt;
# Code cleanup&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Refactor the single Sidekiq worker into multiple workers ===&lt;br /&gt;
Previously there was only a single worker class that handled all types of jobs. Its top-level method &amp;lt;code&amp;gt;perform&amp;lt;/code&amp;gt; looked like the following.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def perform(assignment_id, deadline_type, due_at)&lt;br /&gt;
    self.assignment_id = assignment_id&lt;br /&gt;
    self.deadline_type = deadline_type&lt;br /&gt;
    self.due_at = due_at&lt;br /&gt;
&lt;br /&gt;
    assignment = Assignment.find(self.assignment_id)&lt;br /&gt;
    participant_mails = find_participant_emails&lt;br /&gt;
&lt;br /&gt;
    if %w[drop_one_member_topics drop_outstanding_reviews compare_files_with_simicheck].include?(self.deadline_type)&lt;br /&gt;
      drop_one_member_topics if self.deadline_type == &amp;quot;drop_outstanding_reviews&amp;quot; &amp;amp;&amp;amp; assignment.team_assignment&lt;br /&gt;
      drop_outstanding_reviews if self.deadline_type == &amp;quot;drop_outstanding_reviews&amp;quot;&lt;br /&gt;
      perform_simicheck_comparisons(self.assignment_id) if self.deadline_type == &amp;quot;compare_files_with_simicheck&amp;quot;&lt;br /&gt;
    else&lt;br /&gt;
      # Can we rename deadline_type(metareview) to &amp;quot;teammate review&amp;quot;. If, yes then we donot need this if clause below!&lt;br /&gt;
      deadlineText = if self.deadline_type == &amp;quot;metareview&amp;quot;&lt;br /&gt;
                       &amp;quot;teammate review&amp;quot;&lt;br /&gt;
                     else&lt;br /&gt;
                       self.deadline_type&lt;br /&gt;
      end&lt;br /&gt;
&lt;br /&gt;
      email_reminder(participant_mails, deadlineText) unless participant_mails.empty?&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The processing was different depending on the &amp;lt;code&amp;gt;deadline_type&amp;lt;/code&amp;gt;. The &amp;lt;code&amp;gt;deadline_type&amp;lt;/code&amp;gt;s in&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
%w[drop_one_member_topics drop_outstanding_reviews compare_files_with_simicheck]&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
did not lead to an email reminder being sent, but they were still handled in this &amp;lt;code&amp;gt;MailWorker&amp;lt;/code&amp;gt; class.&lt;br /&gt;
&lt;br /&gt;
To make the code more manageable and easier to follow, it made sense to break up the responsibilities of this single &amp;lt;code&amp;gt;MailWorker&amp;lt;/code&amp;gt; class into multiple workers:&lt;br /&gt;
* &amp;lt;code&amp;gt;SimicheckWorker&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;DropOutstandingReviewsWorker&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;MailWorker&amp;lt;/code&amp;gt;&lt;br /&gt;
All three workers extended an &amp;quot;abstract class&amp;quot; called &amp;lt;code&amp;gt;Worker&amp;lt;/code&amp;gt; that contained the Sidekiq-related &amp;lt;code&amp;gt;include&amp;lt;/code&amp;gt; and the queue name to which all jobs would be sent.&lt;br /&gt;
&lt;br /&gt;
For simplicity, we still had all new workers continue to use a single queue, which we renamed from &amp;lt;code&amp;gt;mailers&amp;lt;/code&amp;gt; to &amp;lt;code&amp;gt;jobs&amp;lt;/code&amp;gt;. A future improvement could divide these jobs to go to multiple different queues if needed.&lt;br /&gt;
&lt;br /&gt;
=== Remove all code related to the &amp;lt;code&amp;gt;drop_one_member_topics&amp;lt;/code&amp;gt; deadline type ===&lt;br /&gt;
It was decided that code used for dropping one member or two member teams from topics would never need to be implemented in the Expertiza website. Thus, we removed all code related to the drop_one_member_topics method within the Expertiza beta. This involved removing the &amp;lt;code&amp;gt;drop_one_member_topics&amp;lt;/code&amp;gt; function from &amp;lt;code&amp;gt;drop_outstanding_reviews_mail_worker.rb&amp;lt;/code&amp;gt;, now renamed &amp;lt;code&amp;gt;drop_outstanding_reviews_worker.rb&amp;lt;/code&amp;gt;. The &amp;lt;code&amp;gt;drop_one_member_topics&amp;lt;/code&amp;gt; method was called from the &amp;lt;code&amp;gt;prepare_data&amp;lt;/code&amp;gt; method, which was then called by the Sidekiq method &amp;lt;code&amp;gt;perform&amp;lt;/code&amp;gt; so we removed this call. The &amp;lt;code&amp;gt;drop_one_member_topics&amp;lt;/code&amp;gt; was also referenced in &amp;lt;code&amp;gt;assignment_form.rb&amp;lt;/code&amp;gt; using &amp;lt;code&amp;gt;add_delayed_job&amp;lt;/code&amp;gt; in the &amp;lt;code&amp;gt;add_to_delayed_queue&amp;lt;/code&amp;gt; method and in &amp;lt;code&amp;gt;delayed_mailer.html.erb&amp;lt;/code&amp;gt; as an option for the handler so both of these code snippets were removed as well.&lt;br /&gt;
&lt;br /&gt;
=== Update and add unit tests according to the above changes ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Test all new worker classes to ensure Sidekiq jobs were being dequeued and run as expected ===&lt;br /&gt;
==== Sidekiq setup ====&lt;br /&gt;
In order to test the Sidekiq workers, a few steps were needed to set up the workers and run Sidekiq (steps were obtained from [https://tudip.com/blog-post/how-to-use-sidekiq-in-rails-for-background-processing/ this site]):&lt;br /&gt;
# Initialize three new workers, each having one of the three new worker types:&lt;br /&gt;
## &amp;lt;code&amp;gt;rails g sidekiq:worker SimicheckWorker&amp;lt;/code&amp;gt;&lt;br /&gt;
## &amp;lt;code&amp;gt;rails g sidekiq:worker DropOutstandingReviewsWorker&amp;lt;/code&amp;gt;&lt;br /&gt;
## &amp;lt;code&amp;gt;rails g sidekiq:worker MailWorker&amp;lt;/code&amp;gt;&lt;br /&gt;
# In a terminal separate from the one in which the main rails application is running, run&lt;br /&gt;
&amp;lt;blockquote&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
bundle exec sidekiq&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This Sidekiq-specific terminal will show logs and printed statements from the workers.&lt;br /&gt;
&lt;br /&gt;
==== SimicheckWorker Test ====&lt;br /&gt;
&lt;br /&gt;
==== MailWorker and DropOustandingReviews Test ====&lt;br /&gt;
The Mail Worker sends out notifications to students if the due date of an assignment is changed. To test Mail Worker, we first created an assignment with the default options by logging in as an instructor, going to '''Manage'''&amp;gt;'''Assignments''' in the navigation, and clicking the plus button in the top right corner on the '''Manage Assignments'''. We then assigned student7613 to the assignment we had created by clicking the person with the plus icon in the icons next to the assignment on the '''Manage Assignments''' page. At this point, we realized we need to alter the code to test if the code was properly queuing the Mail Worker because the current if statement to add items to the delayed queue required that it have a late policy. However, the late policy code is not currently working. Thus, in the &amp;lt;code&amp;gt;assignment_form.rb&amp;lt;/code&amp;gt; model file, we edited the following code:&lt;br /&gt;
&lt;br /&gt;
[[File:Change_late_policy.png|950px|Late policy code to alter]]&lt;br /&gt;
&lt;br /&gt;
We removed &amp;lt;code&amp;gt;and has_late_policy&amp;lt;/code&amp;gt; so &amp;lt;code&amp;gt;add_delayed_queue&amp;lt;/code&amp;gt; can run even without late policies being implemented. After saving this file, we started up Expertiza again and went to the assignment that student7613 had been assigned to. We then edited the assignment, went to the due dates tab, and changed the due date to be a day ahead of its current due date. Following this, we pressed save on the assignment, and then moved back to the '''Home''' page by hitting '''Home''' on the navigation bar to ensure that everything on the page had been updated correctly. To ensure that the assignments were now queued on Sidekiq, we visited the Sidekiq UI by going to [Expertiza VCL URL]/sidekiq. Upon arriving on this page, we verified that the jobs added to the queue were correct by clicking to '''Scheduled'''. After arriving on this page, we saw the following:&lt;br /&gt;
&lt;br /&gt;
[[File:Sidekiq-jobs.png|950px|Sidekiq jobs]]&lt;br /&gt;
&lt;br /&gt;
The job '''MailWorker''' that had been queued successfully shows that our refactoring had worked properly and the Mail Worker was operational.&lt;br /&gt;
&lt;br /&gt;
==== DropOutstandingReviewsWorker Test ====&lt;br /&gt;
&lt;br /&gt;
=== Sidekiq UI ===&lt;br /&gt;
To see which messages were being enqueued and dequeued in Sidekiq, we use the Sidekiq user interface, which can be accessed via the &amp;lt;code&amp;gt;/sidekiq&amp;lt;/code&amp;gt; route of the application.&lt;br /&gt;
[[File:Sidekiq-ui.png|950px|The Sidekiq UI]]&lt;br /&gt;
&lt;br /&gt;
=== Code Cleanup ===&lt;br /&gt;
Smaller improvements done while implementing the main tasks included:&lt;br /&gt;
* Using ActiveSupport::Duration objects in order to calculate the minutes and seconds related to the dequeue times&lt;br /&gt;
* Refactoring the time calculations for the dequeue times to the DueDate class&lt;br /&gt;
* Correcting the parameters passed to the workers, which were previously incorrect. As an example:&lt;br /&gt;
&amp;lt;blockquote&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def add_delayed_job(_assignment, deadline_type, due_date, min_left)&lt;br /&gt;
    delayed_job_id = MailWorker.perform_in(min_left * 60, due_date.parent_id, deadline_type, due_date.due_at)&lt;br /&gt;
    delayed_job_id&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
The first parameter after the time delay must be assignment ID, and &amp;lt;code&amp;gt;due_date.parent_id&amp;lt;/code&amp;gt; is not an assignment ID.&lt;br /&gt;
&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
* Removing whitespace issues reported by codeclimate&lt;br /&gt;
* Refactoring all variable names to be in snake_case&lt;br /&gt;
* Removing identical blocks of code&lt;br /&gt;
* Adding method comments to make methods more understandable&lt;br /&gt;
* ...&lt;/div&gt;</summary>
		<author><name>Agcarrut</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2021_-_E2144._Refactor_delayed_mailer_and_scheduled_task&amp;diff=140088</id>
		<title>CSC/ECE 517 Fall 2021 - E2144. Refactor delayed mailer and scheduled task</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2021_-_E2144._Refactor_delayed_mailer_and_scheduled_task&amp;diff=140088"/>
		<updated>2021-10-26T17:24:20Z</updated>

		<summary type="html">&lt;p&gt;Agcarrut: /* MailWorker Test */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;__TOC__&lt;br /&gt;
&lt;br /&gt;
== Background ==&lt;br /&gt;
This project revolves around the Sidekiq gem for asynchronous processing of email tasks. It has a queue system to hold and then process jobs. Sidekiq’s queue replaces DelayedMailer’s queue. The previous team that worked on this also created a method &amp;lt;code&amp;gt;perform()&amp;lt;/code&amp;gt; to gather email IDs of all participants in an assignment and send them an email reminder. Some test cases exist for this work.&lt;br /&gt;
&lt;br /&gt;
=== Previous Setup ===&lt;br /&gt;
Initial work can be found [https://expertiza.csc.ncsu.edu/index.php/E1835_Refactor_delayed_mailer_and_scheduled_task here].&lt;br /&gt;
&lt;br /&gt;
Code in the [https://github.com/expertiza/expertiza/pull/1245/files pull request] was found to be reasonable and working. The method &amp;lt;code&amp;gt;perform()&amp;lt;/code&amp;gt; has:&lt;br /&gt;
{| class=wikitable style=text-align:right&lt;br /&gt;
|+ Metrics for &amp;lt;code&amp;gt;perform&amp;lt;/code&amp;gt; method&lt;br /&gt;
|-&lt;br /&gt;
! Metric !! Current Value !! Limit&lt;br /&gt;
|-&lt;br /&gt;
! Cognitive Complexity&lt;br /&gt;
| 15 || 5&lt;br /&gt;
|-&lt;br /&gt;
! Cyclomatic Complexity&lt;br /&gt;
| 8 || 6&lt;br /&gt;
|-&lt;br /&gt;
! Assignment Branch Condition size&lt;br /&gt;
| 22.93 || 15&lt;br /&gt;
|-&lt;br /&gt;
! Perceived complexity&lt;br /&gt;
| 10 || 7&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Previous pull request also has duplicated commit messages and the commits need to be squashed.&lt;br /&gt;
&lt;br /&gt;
Files involved (some changed should not have been changed):&lt;br /&gt;
* app/controllers/assignments_controller.rb&lt;br /&gt;
* app/mailers/mail_worker.rb&lt;br /&gt;
* app/models/assignment_form.rb&lt;br /&gt;
* config/sidekiq.yml&lt;br /&gt;
* spec/models/assignment_form_spec.rb&lt;br /&gt;
* spec/sidekiq_mail_worker_spec.rb&lt;br /&gt;
* spec/spec_helper.rb&lt;br /&gt;
&lt;br /&gt;
There are minor styling issues such as missing or trailing whitespaces, lines that are too long, extra empty line, unused arguments.&lt;br /&gt;
&lt;br /&gt;
=== Problem Statement ===&lt;br /&gt;
&lt;br /&gt;
This project revolves around the Sidekiq gem for asynchronous processing of email tasks. It has a queue system to hold and then process jobs. Sidekiq's queue replaces DelayedMailer’s queue. The previous team that worked on this also created a method perform() to gather email IDs of all participants in an assignment and send them an email reminder. Some test cases exist for this work.&lt;br /&gt;
The project was partially merged.&lt;br /&gt;
​&lt;br /&gt;
&lt;br /&gt;
What needs to be done:  &lt;br /&gt;
Feedback from the previous team (E1835) is:&lt;br /&gt;
Code in pull request seems pretty reasonable.  Some concerns wrt. naming functions, but otherwise reviewers seem to agree that the code is good.&lt;br /&gt;
​&lt;br /&gt;
&lt;br /&gt;
Your pull request has many duplicated commit messages. Please try to &amp;lt;code&amp;gt;squash&amp;lt;/code&amp;gt; similar commits.&lt;br /&gt;
And using meaningful commit messages later.&lt;br /&gt;
​&lt;br /&gt;
&lt;br /&gt;
You should commit changes to the DB schema (&amp;lt;code&amp;gt;db/schema.rb&amp;lt;/code&amp;gt;) only if you have created new DB migrations.&lt;br /&gt;
Please double check your code. If you did not aim to change the DB, please revert the DB schema changes. ***** Important, try not to change the DB.&lt;br /&gt;
​&lt;br /&gt;
&lt;br /&gt;
You should not change &amp;lt;code&amp;gt;rails_helper.rb&amp;lt;/code&amp;gt; or &amp;lt;code&amp;gt;spec_helper.rb&amp;lt;/code&amp;gt; file; please revert these changes.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The previous team’s code needs a refactor in some places, though the actual function of it seems solid. It is very possible that in the three years since this code has been worked on, more mailer functionality has been added. There are other teams this semester working on mailer code as well. Try to keep your code as contained and simple as possible, so that merging these projects is possible.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Summary of Work Needed ==&lt;br /&gt;
After discussing with our project mentor and Dr. Gehringer, we determined the main tasks to be the following:&lt;br /&gt;
# Refactor the single Sidekiq worker into multiple workers&lt;br /&gt;
# Remove all code related to the &amp;lt;code&amp;gt;drop_one_member_topics&amp;lt;/code&amp;gt; deadline type&lt;br /&gt;
# Update and add unit tests according to the above changes&lt;br /&gt;
# Test all new worker classes to ensure Sidekiq jobs were being dequeued and run as expected&lt;br /&gt;
# Code cleanup&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Refactor the single Sidekiq worker into multiple workers ===&lt;br /&gt;
Previously there was only a single worker class that handled all types of jobs. Its top-level method &amp;lt;code&amp;gt;perform&amp;lt;/code&amp;gt; looked like the following.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def perform(assignment_id, deadline_type, due_at)&lt;br /&gt;
    self.assignment_id = assignment_id&lt;br /&gt;
    self.deadline_type = deadline_type&lt;br /&gt;
    self.due_at = due_at&lt;br /&gt;
&lt;br /&gt;
    assignment = Assignment.find(self.assignment_id)&lt;br /&gt;
    participant_mails = find_participant_emails&lt;br /&gt;
&lt;br /&gt;
    if %w[drop_one_member_topics drop_outstanding_reviews compare_files_with_simicheck].include?(self.deadline_type)&lt;br /&gt;
      drop_one_member_topics if self.deadline_type == &amp;quot;drop_outstanding_reviews&amp;quot; &amp;amp;&amp;amp; assignment.team_assignment&lt;br /&gt;
      drop_outstanding_reviews if self.deadline_type == &amp;quot;drop_outstanding_reviews&amp;quot;&lt;br /&gt;
      perform_simicheck_comparisons(self.assignment_id) if self.deadline_type == &amp;quot;compare_files_with_simicheck&amp;quot;&lt;br /&gt;
    else&lt;br /&gt;
      # Can we rename deadline_type(metareview) to &amp;quot;teammate review&amp;quot;. If, yes then we donot need this if clause below!&lt;br /&gt;
      deadlineText = if self.deadline_type == &amp;quot;metareview&amp;quot;&lt;br /&gt;
                       &amp;quot;teammate review&amp;quot;&lt;br /&gt;
                     else&lt;br /&gt;
                       self.deadline_type&lt;br /&gt;
      end&lt;br /&gt;
&lt;br /&gt;
      email_reminder(participant_mails, deadlineText) unless participant_mails.empty?&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The processing was different depending on the &amp;lt;code&amp;gt;deadline_type&amp;lt;/code&amp;gt;. The &amp;lt;code&amp;gt;deadline_type&amp;lt;/code&amp;gt;s in&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
%w[drop_one_member_topics drop_outstanding_reviews compare_files_with_simicheck]&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
did not lead to an email reminder being sent, but they were still handled in this &amp;lt;code&amp;gt;MailWorker&amp;lt;/code&amp;gt; class.&lt;br /&gt;
&lt;br /&gt;
To make the code more manageable and easier to follow, it made sense to break up the responsibilities of this single &amp;lt;code&amp;gt;MailWorker&amp;lt;/code&amp;gt; class into multiple workers:&lt;br /&gt;
* &amp;lt;code&amp;gt;SimicheckWorker&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;DropOutstandingReviewsWorker&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;MailWorker&amp;lt;/code&amp;gt;&lt;br /&gt;
All three workers extended an &amp;quot;abstract class&amp;quot; called &amp;lt;code&amp;gt;Worker&amp;lt;/code&amp;gt; that contained the Sidekiq-related &amp;lt;code&amp;gt;include&amp;lt;/code&amp;gt; and the queue name to which all jobs would be sent.&lt;br /&gt;
&lt;br /&gt;
For simplicity, we still had all new workers continue to use a single queue, which we renamed from &amp;lt;code&amp;gt;mailers&amp;lt;/code&amp;gt; to &amp;lt;code&amp;gt;jobs&amp;lt;/code&amp;gt;. A future improvement could divide these jobs to go to multiple different queues if needed.&lt;br /&gt;
&lt;br /&gt;
=== Remove all code related to the &amp;lt;code&amp;gt;drop_one_member_topics&amp;lt;/code&amp;gt; deadline type ===&lt;br /&gt;
It was decided that code used for dropping one member or two member teams from topics would never need to be implemented in the Expertiza website. Thus, we removed all code related to the drop_one_member_topics method within the Expertiza beta. This involved removing the &amp;lt;code&amp;gt;drop_one_member_topics&amp;lt;/code&amp;gt; function from &amp;lt;code&amp;gt;drop_outstanding_reviews_mail_worker.rb&amp;lt;/code&amp;gt;, now renamed &amp;lt;code&amp;gt;drop_outstanding_reviews_worker.rb&amp;lt;/code&amp;gt;. The &amp;lt;code&amp;gt;drop_one_member_topics&amp;lt;/code&amp;gt; method was called from the &amp;lt;code&amp;gt;prepare_data&amp;lt;/code&amp;gt; method, which was then called by the Sidekiq method &amp;lt;code&amp;gt;perform&amp;lt;/code&amp;gt; so we removed this call. The &amp;lt;code&amp;gt;drop_one_member_topics&amp;lt;/code&amp;gt; was also referenced in &amp;lt;code&amp;gt;assignment_form.rb&amp;lt;/code&amp;gt; using &amp;lt;code&amp;gt;add_delayed_job&amp;lt;/code&amp;gt; in the &amp;lt;code&amp;gt;add_to_delayed_queue&amp;lt;/code&amp;gt; method and in &amp;lt;code&amp;gt;delayed_mailer.html.erb&amp;lt;/code&amp;gt; as an option for the handler so both of these code snippets were removed as well.&lt;br /&gt;
&lt;br /&gt;
=== Update and add unit tests according to the above changes ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Test all new worker classes to ensure Sidekiq jobs were being dequeued and run as expected ===&lt;br /&gt;
==== Sidekiq setup ====&lt;br /&gt;
In order to test the Sidekiq workers, a few steps were needed to set up the workers and run Sidekiq (steps were obtained from [https://tudip.com/blog-post/how-to-use-sidekiq-in-rails-for-background-processing/ this site]):&lt;br /&gt;
# Initialize three new workers, each having one of the three new worker types:&lt;br /&gt;
## &amp;lt;code&amp;gt;rails g sidekiq:worker SimicheckWorker&amp;lt;/code&amp;gt;&lt;br /&gt;
## &amp;lt;code&amp;gt;rails g sidekiq:worker DropOutstandingReviewsWorker&amp;lt;/code&amp;gt;&lt;br /&gt;
## &amp;lt;code&amp;gt;rails g sidekiq:worker MailWorker&amp;lt;/code&amp;gt;&lt;br /&gt;
# In a terminal separate from the one in which the main rails application is running, run&lt;br /&gt;
&amp;lt;blockquote&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
bundle exec sidekiq&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This Sidekiq-specific terminal will show logs and printed statements from the workers.&lt;br /&gt;
&lt;br /&gt;
==== SimicheckWorker Test ====&lt;br /&gt;
&lt;br /&gt;
==== MailWorker Test ====&lt;br /&gt;
The Mail Worker sends out notifications to students if the due date of an assignment is changed. To test Mail Worker, we first created an assignment with the default options by logging in as an instructor, going to '''Manage'''&amp;gt;'''Assignments''' in the navigation, and clicking the plus button in the top right corner on the '''Manage Assignments'''. We then assigned student7613 to the assignment we had created by clicking the person with the plus icon in the icons next to the assignment on the '''Manage Assignments''' page. At this point, we realized we need to alter the code to test if the code was properly queuing the Mail Worker because the current if statement to add items to the delayed queue required that it have a late policy. However, the late policy code is not currently working. Thus, in the &amp;lt;code&amp;gt;assignment_form.rb&amp;lt;/code&amp;gt; model file, we edited the following code:&lt;br /&gt;
&lt;br /&gt;
[[File:Change_late_policy.png|950px|Late policy code to alter]]&lt;br /&gt;
&lt;br /&gt;
We removed &amp;lt;code&amp;gt;and has_late_policy&amp;lt;/code&amp;gt; so &amp;lt;code&amp;gt;add_delayed_queue&amp;lt;/code&amp;gt; can run even without late policies being implemented. After saving this file, we started up Expertiza again and went to the assignment that student7613 had been assigned to. We then edited the assignment, went to the due dates tab, and changed the due date to be a day ahead of its current due date. Following this, we pressed save on the assignment, and then moved back to the '''Home''' page by hitting '''Home''' on the navigation bar to ensure that everything on the page had been updated correctly. To ensure that the assignments were now queued on Sidekiq, we visited the Sidekiq UI by going to [Expertiza VCL URL]/sidekiq. Upon arriving on this page, we verified that the jobs added to the queue were correct by clicking to '''Scheduled'''. After arriving on this page, we saw the following:&lt;br /&gt;
&lt;br /&gt;
[[File:Sidekiq-jobs.png|950px|Sidekiq jobs]]&lt;br /&gt;
&lt;br /&gt;
The job '''MailWorker''' that had been queued successfully shows that our refactoring had worked properly and the Mail Worker was operational.&lt;br /&gt;
&lt;br /&gt;
==== DropOutstandingReviewsWorker Test ====&lt;br /&gt;
&lt;br /&gt;
=== Sidekiq UI ===&lt;br /&gt;
To see which messages were being enqueued and dequeued in Sidekiq, we use the Sidekiq user interface, which can be accessed via the &amp;lt;code&amp;gt;/sidekiq&amp;lt;/code&amp;gt; route of the application.&lt;br /&gt;
[[File:Sidekiq-ui.png|950px|The Sidekiq UI]]&lt;br /&gt;
&lt;br /&gt;
=== Code Cleanup ===&lt;br /&gt;
Smaller improvements done while implementing the main tasks included:&lt;br /&gt;
* Using ActiveSupport::Duration objects in order to calculate the minutes and seconds related to the dequeue times&lt;br /&gt;
* Refactoring the time calculations for the dequeue times to the DueDate class&lt;br /&gt;
* Correcting the parameters passed to the workers, which were previously incorrect. As an example:&lt;br /&gt;
&amp;lt;blockquote&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def add_delayed_job(_assignment, deadline_type, due_date, min_left)&lt;br /&gt;
    delayed_job_id = MailWorker.perform_in(min_left * 60, due_date.parent_id, deadline_type, due_date.due_at)&lt;br /&gt;
    delayed_job_id&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
The first parameter after the time delay must be assignment ID, and &amp;lt;code&amp;gt;due_date.parent_id&amp;lt;/code&amp;gt; is not an assignment ID.&lt;br /&gt;
&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
* Removing whitespace issues reported by codeclimate&lt;br /&gt;
* Refactoring all variable names to be in snake_case&lt;br /&gt;
* Removing identical blocks of code&lt;br /&gt;
* Adding method comments to make methods more understandable&lt;br /&gt;
* ...&lt;/div&gt;</summary>
		<author><name>Agcarrut</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=File:Sidekiq-jobs.png&amp;diff=140087</id>
		<title>File:Sidekiq-jobs.png</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=File:Sidekiq-jobs.png&amp;diff=140087"/>
		<updated>2021-10-26T17:24:00Z</updated>

		<summary type="html">&lt;p&gt;Agcarrut: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Agcarrut</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=File:Sidekiq_jobs.png&amp;diff=140086</id>
		<title>File:Sidekiq jobs.png</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=File:Sidekiq_jobs.png&amp;diff=140086"/>
		<updated>2021-10-26T17:23:16Z</updated>

		<summary type="html">&lt;p&gt;Agcarrut: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Agcarrut</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2021_-_E2144._Refactor_delayed_mailer_and_scheduled_task&amp;diff=140085</id>
		<title>CSC/ECE 517 Fall 2021 - E2144. Refactor delayed mailer and scheduled task</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2021_-_E2144._Refactor_delayed_mailer_and_scheduled_task&amp;diff=140085"/>
		<updated>2021-10-26T17:23:04Z</updated>

		<summary type="html">&lt;p&gt;Agcarrut: /* MailWorker Test */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;__TOC__&lt;br /&gt;
&lt;br /&gt;
== Background ==&lt;br /&gt;
This project revolves around the Sidekiq gem for asynchronous processing of email tasks. It has a queue system to hold and then process jobs. Sidekiq’s queue replaces DelayedMailer’s queue. The previous team that worked on this also created a method &amp;lt;code&amp;gt;perform()&amp;lt;/code&amp;gt; to gather email IDs of all participants in an assignment and send them an email reminder. Some test cases exist for this work.&lt;br /&gt;
&lt;br /&gt;
=== Previous Setup ===&lt;br /&gt;
Initial work can be found [https://expertiza.csc.ncsu.edu/index.php/E1835_Refactor_delayed_mailer_and_scheduled_task here].&lt;br /&gt;
&lt;br /&gt;
Code in the [https://github.com/expertiza/expertiza/pull/1245/files pull request] was found to be reasonable and working. The method &amp;lt;code&amp;gt;perform()&amp;lt;/code&amp;gt; has:&lt;br /&gt;
{| class=wikitable style=text-align:right&lt;br /&gt;
|+ Metrics for &amp;lt;code&amp;gt;perform&amp;lt;/code&amp;gt; method&lt;br /&gt;
|-&lt;br /&gt;
! Metric !! Current Value !! Limit&lt;br /&gt;
|-&lt;br /&gt;
! Cognitive Complexity&lt;br /&gt;
| 15 || 5&lt;br /&gt;
|-&lt;br /&gt;
! Cyclomatic Complexity&lt;br /&gt;
| 8 || 6&lt;br /&gt;
|-&lt;br /&gt;
! Assignment Branch Condition size&lt;br /&gt;
| 22.93 || 15&lt;br /&gt;
|-&lt;br /&gt;
! Perceived complexity&lt;br /&gt;
| 10 || 7&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Previous pull request also has duplicated commit messages and the commits need to be squashed.&lt;br /&gt;
&lt;br /&gt;
Files involved (some changed should not have been changed):&lt;br /&gt;
* app/controllers/assignments_controller.rb&lt;br /&gt;
* app/mailers/mail_worker.rb&lt;br /&gt;
* app/models/assignment_form.rb&lt;br /&gt;
* config/sidekiq.yml&lt;br /&gt;
* spec/models/assignment_form_spec.rb&lt;br /&gt;
* spec/sidekiq_mail_worker_spec.rb&lt;br /&gt;
* spec/spec_helper.rb&lt;br /&gt;
&lt;br /&gt;
There are minor styling issues such as missing or trailing whitespaces, lines that are too long, extra empty line, unused arguments.&lt;br /&gt;
&lt;br /&gt;
=== Problem Statement ===&lt;br /&gt;
&lt;br /&gt;
This project revolves around the Sidekiq gem for asynchronous processing of email tasks. It has a queue system to hold and then process jobs. Sidekiq's queue replaces DelayedMailer’s queue. The previous team that worked on this also created a method perform() to gather email IDs of all participants in an assignment and send them an email reminder. Some test cases exist for this work.&lt;br /&gt;
The project was partially merged.&lt;br /&gt;
​&lt;br /&gt;
&lt;br /&gt;
What needs to be done:  &lt;br /&gt;
Feedback from the previous team (E1835) is:&lt;br /&gt;
Code in pull request seems pretty reasonable.  Some concerns wrt. naming functions, but otherwise reviewers seem to agree that the code is good.&lt;br /&gt;
​&lt;br /&gt;
&lt;br /&gt;
Your pull request has many duplicated commit messages. Please try to &amp;lt;code&amp;gt;squash&amp;lt;/code&amp;gt; similar commits.&lt;br /&gt;
And using meaningful commit messages later.&lt;br /&gt;
​&lt;br /&gt;
&lt;br /&gt;
You should commit changes to the DB schema (&amp;lt;code&amp;gt;db/schema.rb&amp;lt;/code&amp;gt;) only if you have created new DB migrations.&lt;br /&gt;
Please double check your code. If you did not aim to change the DB, please revert the DB schema changes. ***** Important, try not to change the DB.&lt;br /&gt;
​&lt;br /&gt;
&lt;br /&gt;
You should not change &amp;lt;code&amp;gt;rails_helper.rb&amp;lt;/code&amp;gt; or &amp;lt;code&amp;gt;spec_helper.rb&amp;lt;/code&amp;gt; file; please revert these changes.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The previous team’s code needs a refactor in some places, though the actual function of it seems solid. It is very possible that in the three years since this code has been worked on, more mailer functionality has been added. There are other teams this semester working on mailer code as well. Try to keep your code as contained and simple as possible, so that merging these projects is possible.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Summary of Work Needed ==&lt;br /&gt;
After discussing with our project mentor and Dr. Gehringer, we determined the main tasks to be the following:&lt;br /&gt;
# Refactor the single Sidekiq worker into multiple workers&lt;br /&gt;
# Remove all code related to the &amp;lt;code&amp;gt;drop_one_member_topics&amp;lt;/code&amp;gt; deadline type&lt;br /&gt;
# Update and add unit tests according to the above changes&lt;br /&gt;
# Test all new worker classes to ensure Sidekiq jobs were being dequeued and run as expected&lt;br /&gt;
# Code cleanup&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Refactor the single Sidekiq worker into multiple workers ===&lt;br /&gt;
Previously there was only a single worker class that handled all types of jobs. Its top-level method &amp;lt;code&amp;gt;perform&amp;lt;/code&amp;gt; looked like the following.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def perform(assignment_id, deadline_type, due_at)&lt;br /&gt;
    self.assignment_id = assignment_id&lt;br /&gt;
    self.deadline_type = deadline_type&lt;br /&gt;
    self.due_at = due_at&lt;br /&gt;
&lt;br /&gt;
    assignment = Assignment.find(self.assignment_id)&lt;br /&gt;
    participant_mails = find_participant_emails&lt;br /&gt;
&lt;br /&gt;
    if %w[drop_one_member_topics drop_outstanding_reviews compare_files_with_simicheck].include?(self.deadline_type)&lt;br /&gt;
      drop_one_member_topics if self.deadline_type == &amp;quot;drop_outstanding_reviews&amp;quot; &amp;amp;&amp;amp; assignment.team_assignment&lt;br /&gt;
      drop_outstanding_reviews if self.deadline_type == &amp;quot;drop_outstanding_reviews&amp;quot;&lt;br /&gt;
      perform_simicheck_comparisons(self.assignment_id) if self.deadline_type == &amp;quot;compare_files_with_simicheck&amp;quot;&lt;br /&gt;
    else&lt;br /&gt;
      # Can we rename deadline_type(metareview) to &amp;quot;teammate review&amp;quot;. If, yes then we donot need this if clause below!&lt;br /&gt;
      deadlineText = if self.deadline_type == &amp;quot;metareview&amp;quot;&lt;br /&gt;
                       &amp;quot;teammate review&amp;quot;&lt;br /&gt;
                     else&lt;br /&gt;
                       self.deadline_type&lt;br /&gt;
      end&lt;br /&gt;
&lt;br /&gt;
      email_reminder(participant_mails, deadlineText) unless participant_mails.empty?&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The processing was different depending on the &amp;lt;code&amp;gt;deadline_type&amp;lt;/code&amp;gt;. The &amp;lt;code&amp;gt;deadline_type&amp;lt;/code&amp;gt;s in&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
%w[drop_one_member_topics drop_outstanding_reviews compare_files_with_simicheck]&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
did not lead to an email reminder being sent, but they were still handled in this &amp;lt;code&amp;gt;MailWorker&amp;lt;/code&amp;gt; class.&lt;br /&gt;
&lt;br /&gt;
To make the code more manageable and easier to follow, it made sense to break up the responsibilities of this single &amp;lt;code&amp;gt;MailWorker&amp;lt;/code&amp;gt; class into multiple workers:&lt;br /&gt;
* &amp;lt;code&amp;gt;SimicheckWorker&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;DropOutstandingReviewsWorker&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;MailWorker&amp;lt;/code&amp;gt;&lt;br /&gt;
All three workers extended an &amp;quot;abstract class&amp;quot; called &amp;lt;code&amp;gt;Worker&amp;lt;/code&amp;gt; that contained the Sidekiq-related &amp;lt;code&amp;gt;include&amp;lt;/code&amp;gt; and the queue name to which all jobs would be sent.&lt;br /&gt;
&lt;br /&gt;
For simplicity, we still had all new workers continue to use a single queue, which we renamed from &amp;lt;code&amp;gt;mailers&amp;lt;/code&amp;gt; to &amp;lt;code&amp;gt;jobs&amp;lt;/code&amp;gt;. A future improvement could divide these jobs to go to multiple different queues if needed.&lt;br /&gt;
&lt;br /&gt;
=== Remove all code related to the &amp;lt;code&amp;gt;drop_one_member_topics&amp;lt;/code&amp;gt; deadline type ===&lt;br /&gt;
It was decided that code used for dropping one member or two member teams from topics would never need to be implemented in the Expertiza website. Thus, we removed all code related to the drop_one_member_topics method within the Expertiza beta. This involved removing the &amp;lt;code&amp;gt;drop_one_member_topics&amp;lt;/code&amp;gt; function from &amp;lt;code&amp;gt;drop_outstanding_reviews_mail_worker.rb&amp;lt;/code&amp;gt;, now renamed &amp;lt;code&amp;gt;drop_outstanding_reviews_worker.rb&amp;lt;/code&amp;gt;. The &amp;lt;code&amp;gt;drop_one_member_topics&amp;lt;/code&amp;gt; method was called from the &amp;lt;code&amp;gt;prepare_data&amp;lt;/code&amp;gt; method, which was then called by the Sidekiq method &amp;lt;code&amp;gt;perform&amp;lt;/code&amp;gt; so we removed this call. The &amp;lt;code&amp;gt;drop_one_member_topics&amp;lt;/code&amp;gt; was also referenced in &amp;lt;code&amp;gt;assignment_form.rb&amp;lt;/code&amp;gt; using &amp;lt;code&amp;gt;add_delayed_job&amp;lt;/code&amp;gt; in the &amp;lt;code&amp;gt;add_to_delayed_queue&amp;lt;/code&amp;gt; method and in &amp;lt;code&amp;gt;delayed_mailer.html.erb&amp;lt;/code&amp;gt; as an option for the handler so both of these code snippets were removed as well.&lt;br /&gt;
&lt;br /&gt;
=== Update and add unit tests according to the above changes ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Test all new worker classes to ensure Sidekiq jobs were being dequeued and run as expected ===&lt;br /&gt;
==== Sidekiq setup ====&lt;br /&gt;
In order to test the Sidekiq workers, a few steps were needed to set up the workers and run Sidekiq (steps were obtained from [https://tudip.com/blog-post/how-to-use-sidekiq-in-rails-for-background-processing/ this site]):&lt;br /&gt;
# Initialize three new workers, each having one of the three new worker types:&lt;br /&gt;
## &amp;lt;code&amp;gt;rails g sidekiq:worker SimicheckWorker&amp;lt;/code&amp;gt;&lt;br /&gt;
## &amp;lt;code&amp;gt;rails g sidekiq:worker DropOutstandingReviewsWorker&amp;lt;/code&amp;gt;&lt;br /&gt;
## &amp;lt;code&amp;gt;rails g sidekiq:worker MailWorker&amp;lt;/code&amp;gt;&lt;br /&gt;
# In a terminal separate from the one in which the main rails application is running, run&lt;br /&gt;
&amp;lt;blockquote&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
bundle exec sidekiq&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This Sidekiq-specific terminal will show logs and printed statements from the workers.&lt;br /&gt;
&lt;br /&gt;
==== SimicheckWorker Test ====&lt;br /&gt;
&lt;br /&gt;
==== MailWorker Test ====&lt;br /&gt;
The Mail Worker sends out notifications to students if the due date of an assignment is changed. To test Mail Worker, we first created an assignment with the default options by logging in as an instructor, going to '''Manage'''&amp;gt;'''Assignments''' in the navigation, and clicking the plus button in the top right corner on the '''Manage Assignments'''. We then assigned student7613 to the assignment we had created by clicking the person with the plus icon in the icons next to the assignment on the '''Manage Assignments''' page. At this point, we realized we need to alter the code to test if the code was properly queuing the Mail Worker because the current if statement to add items to the delayed queue required that it have a late policy. However, the late policy code is not currently working. Thus, in the &amp;lt;code&amp;gt;assignment_form.rb&amp;lt;/code&amp;gt; model file, we edited the following code:&lt;br /&gt;
&lt;br /&gt;
[[File:Change_late_policy.png|950px|Late policy code to alter]]&lt;br /&gt;
&lt;br /&gt;
We removed &amp;lt;code&amp;gt;and has_late_policy&amp;lt;/code&amp;gt; so &amp;lt;code&amp;gt;add_delayed_queue&amp;lt;/code&amp;gt; can run even without late policies being implemented. After saving this file, we started up Expertiza again and went to the assignment that student7613 had been assigned to. We then edited the assignment, went to the due dates tab, and changed the due date to be a day ahead of its current due date. Following this, we pressed save on the assignment, and then moved back to the '''Home''' page by hitting '''Home''' on the navigation bar to ensure that everything on the page had been updated correctly. To ensure that the assignments were now queued on Sidekiq, we visited the Sidekiq UI by going to [Expertiza VCL URL]/sidekiq. Upon arriving on this page, we verified that the jobs added to the queue were correct by clicking to '''Scheduled'''. After arriving on this page, we saw the following:&lt;br /&gt;
&lt;br /&gt;
[[File:Sidekiq_jobs.png|950px|Sidekiq jobs]]&lt;br /&gt;
&lt;br /&gt;
The job '''MailWorker''' that had been queued successfully shows that our refactoring had worked properly and the Mail Worker was operational.&lt;br /&gt;
&lt;br /&gt;
==== DropOutstandingReviewsWorker Test ====&lt;br /&gt;
&lt;br /&gt;
=== Sidekiq UI ===&lt;br /&gt;
To see which messages were being enqueued and dequeued in Sidekiq, we use the Sidekiq user interface, which can be accessed via the &amp;lt;code&amp;gt;/sidekiq&amp;lt;/code&amp;gt; route of the application.&lt;br /&gt;
[[File:Sidekiq-ui.png|950px|The Sidekiq UI]]&lt;br /&gt;
&lt;br /&gt;
=== Code Cleanup ===&lt;br /&gt;
Smaller improvements done while implementing the main tasks included:&lt;br /&gt;
* Using ActiveSupport::Duration objects in order to calculate the minutes and seconds related to the dequeue times&lt;br /&gt;
* Refactoring the time calculations for the dequeue times to the DueDate class&lt;br /&gt;
* Correcting the parameters passed to the workers, which were previously incorrect. As an example:&lt;br /&gt;
&amp;lt;blockquote&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def add_delayed_job(_assignment, deadline_type, due_date, min_left)&lt;br /&gt;
    delayed_job_id = MailWorker.perform_in(min_left * 60, due_date.parent_id, deadline_type, due_date.due_at)&lt;br /&gt;
    delayed_job_id&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
The first parameter after the time delay must be assignment ID, and &amp;lt;code&amp;gt;due_date.parent_id&amp;lt;/code&amp;gt; is not an assignment ID.&lt;br /&gt;
&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
* Removing whitespace issues reported by codeclimate&lt;br /&gt;
* Refactoring all variable names to be in snake_case&lt;br /&gt;
* Removing identical blocks of code&lt;br /&gt;
* Adding method comments to make methods more understandable&lt;br /&gt;
* ...&lt;/div&gt;</summary>
		<author><name>Agcarrut</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2021_-_E2144._Refactor_delayed_mailer_and_scheduled_task&amp;diff=140084</id>
		<title>CSC/ECE 517 Fall 2021 - E2144. Refactor delayed mailer and scheduled task</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2021_-_E2144._Refactor_delayed_mailer_and_scheduled_task&amp;diff=140084"/>
		<updated>2021-10-26T17:12:49Z</updated>

		<summary type="html">&lt;p&gt;Agcarrut: /* MailWorker Test */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;__TOC__&lt;br /&gt;
&lt;br /&gt;
== Background ==&lt;br /&gt;
This project revolves around the Sidekiq gem for asynchronous processing of email tasks. It has a queue system to hold and then process jobs. Sidekiq’s queue replaces DelayedMailer’s queue. The previous team that worked on this also created a method &amp;lt;code&amp;gt;perform()&amp;lt;/code&amp;gt; to gather email IDs of all participants in an assignment and send them an email reminder. Some test cases exist for this work.&lt;br /&gt;
&lt;br /&gt;
=== Previous Setup ===&lt;br /&gt;
Initial work can be found [https://expertiza.csc.ncsu.edu/index.php/E1835_Refactor_delayed_mailer_and_scheduled_task here].&lt;br /&gt;
&lt;br /&gt;
Code in the [https://github.com/expertiza/expertiza/pull/1245/files pull request] was found to be reasonable and working. The method &amp;lt;code&amp;gt;perform()&amp;lt;/code&amp;gt; has:&lt;br /&gt;
{| class=wikitable style=text-align:right&lt;br /&gt;
|+ Metrics for &amp;lt;code&amp;gt;perform&amp;lt;/code&amp;gt; method&lt;br /&gt;
|-&lt;br /&gt;
! Metric !! Current Value !! Limit&lt;br /&gt;
|-&lt;br /&gt;
! Cognitive Complexity&lt;br /&gt;
| 15 || 5&lt;br /&gt;
|-&lt;br /&gt;
! Cyclomatic Complexity&lt;br /&gt;
| 8 || 6&lt;br /&gt;
|-&lt;br /&gt;
! Assignment Branch Condition size&lt;br /&gt;
| 22.93 || 15&lt;br /&gt;
|-&lt;br /&gt;
! Perceived complexity&lt;br /&gt;
| 10 || 7&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Previous pull request also has duplicated commit messages and the commits need to be squashed.&lt;br /&gt;
&lt;br /&gt;
Files involved (some changed should not have been changed):&lt;br /&gt;
* app/controllers/assignments_controller.rb&lt;br /&gt;
* app/mailers/mail_worker.rb&lt;br /&gt;
* app/models/assignment_form.rb&lt;br /&gt;
* config/sidekiq.yml&lt;br /&gt;
* spec/models/assignment_form_spec.rb&lt;br /&gt;
* spec/sidekiq_mail_worker_spec.rb&lt;br /&gt;
* spec/spec_helper.rb&lt;br /&gt;
&lt;br /&gt;
There are minor styling issues such as missing or trailing whitespaces, lines that are too long, extra empty line, unused arguments.&lt;br /&gt;
&lt;br /&gt;
=== Problem Statement ===&lt;br /&gt;
&lt;br /&gt;
This project revolves around the Sidekiq gem for asynchronous processing of email tasks. It has a queue system to hold and then process jobs. Sidekiq's queue replaces DelayedMailer’s queue. The previous team that worked on this also created a method perform() to gather email IDs of all participants in an assignment and send them an email reminder. Some test cases exist for this work.&lt;br /&gt;
The project was partially merged.&lt;br /&gt;
​&lt;br /&gt;
&lt;br /&gt;
What needs to be done:  &lt;br /&gt;
Feedback from the previous team (E1835) is:&lt;br /&gt;
Code in pull request seems pretty reasonable.  Some concerns wrt. naming functions, but otherwise reviewers seem to agree that the code is good.&lt;br /&gt;
​&lt;br /&gt;
&lt;br /&gt;
Your pull request has many duplicated commit messages. Please try to &amp;lt;code&amp;gt;squash&amp;lt;/code&amp;gt; similar commits.&lt;br /&gt;
And using meaningful commit messages later.&lt;br /&gt;
​&lt;br /&gt;
&lt;br /&gt;
You should commit changes to the DB schema (&amp;lt;code&amp;gt;db/schema.rb&amp;lt;/code&amp;gt;) only if you have created new DB migrations.&lt;br /&gt;
Please double check your code. If you did not aim to change the DB, please revert the DB schema changes. ***** Important, try not to change the DB.&lt;br /&gt;
​&lt;br /&gt;
&lt;br /&gt;
You should not change &amp;lt;code&amp;gt;rails_helper.rb&amp;lt;/code&amp;gt; or &amp;lt;code&amp;gt;spec_helper.rb&amp;lt;/code&amp;gt; file; please revert these changes.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The previous team’s code needs a refactor in some places, though the actual function of it seems solid. It is very possible that in the three years since this code has been worked on, more mailer functionality has been added. There are other teams this semester working on mailer code as well. Try to keep your code as contained and simple as possible, so that merging these projects is possible.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Summary of Work Needed ==&lt;br /&gt;
After discussing with our project mentor and Dr. Gehringer, we determined the main tasks to be the following:&lt;br /&gt;
# Refactor the single Sidekiq worker into multiple workers&lt;br /&gt;
# Remove all code related to the &amp;lt;code&amp;gt;drop_one_member_topics&amp;lt;/code&amp;gt; deadline type&lt;br /&gt;
# Update and add unit tests according to the above changes&lt;br /&gt;
# Test all new worker classes to ensure Sidekiq jobs were being dequeued and run as expected&lt;br /&gt;
# Code cleanup&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Refactor the single Sidekiq worker into multiple workers ===&lt;br /&gt;
Previously there was only a single worker class that handled all types of jobs. Its top-level method &amp;lt;code&amp;gt;perform&amp;lt;/code&amp;gt; looked like the following.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def perform(assignment_id, deadline_type, due_at)&lt;br /&gt;
    self.assignment_id = assignment_id&lt;br /&gt;
    self.deadline_type = deadline_type&lt;br /&gt;
    self.due_at = due_at&lt;br /&gt;
&lt;br /&gt;
    assignment = Assignment.find(self.assignment_id)&lt;br /&gt;
    participant_mails = find_participant_emails&lt;br /&gt;
&lt;br /&gt;
    if %w[drop_one_member_topics drop_outstanding_reviews compare_files_with_simicheck].include?(self.deadline_type)&lt;br /&gt;
      drop_one_member_topics if self.deadline_type == &amp;quot;drop_outstanding_reviews&amp;quot; &amp;amp;&amp;amp; assignment.team_assignment&lt;br /&gt;
      drop_outstanding_reviews if self.deadline_type == &amp;quot;drop_outstanding_reviews&amp;quot;&lt;br /&gt;
      perform_simicheck_comparisons(self.assignment_id) if self.deadline_type == &amp;quot;compare_files_with_simicheck&amp;quot;&lt;br /&gt;
    else&lt;br /&gt;
      # Can we rename deadline_type(metareview) to &amp;quot;teammate review&amp;quot;. If, yes then we donot need this if clause below!&lt;br /&gt;
      deadlineText = if self.deadline_type == &amp;quot;metareview&amp;quot;&lt;br /&gt;
                       &amp;quot;teammate review&amp;quot;&lt;br /&gt;
                     else&lt;br /&gt;
                       self.deadline_type&lt;br /&gt;
      end&lt;br /&gt;
&lt;br /&gt;
      email_reminder(participant_mails, deadlineText) unless participant_mails.empty?&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The processing was different depending on the &amp;lt;code&amp;gt;deadline_type&amp;lt;/code&amp;gt;. The &amp;lt;code&amp;gt;deadline_type&amp;lt;/code&amp;gt;s in&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
%w[drop_one_member_topics drop_outstanding_reviews compare_files_with_simicheck]&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
did not lead to an email reminder being sent, but they were still handled in this &amp;lt;code&amp;gt;MailWorker&amp;lt;/code&amp;gt; class.&lt;br /&gt;
&lt;br /&gt;
To make the code more manageable and easier to follow, it made sense to break up the responsibilities of this single &amp;lt;code&amp;gt;MailWorker&amp;lt;/code&amp;gt; class into multiple workers:&lt;br /&gt;
* &amp;lt;code&amp;gt;SimicheckWorker&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;DropOutstandingReviewsWorker&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;MailWorker&amp;lt;/code&amp;gt;&lt;br /&gt;
All three workers extended an &amp;quot;abstract class&amp;quot; called &amp;lt;code&amp;gt;Worker&amp;lt;/code&amp;gt; that contained the Sidekiq-related &amp;lt;code&amp;gt;include&amp;lt;/code&amp;gt; and the queue name to which all jobs would be sent.&lt;br /&gt;
&lt;br /&gt;
For simplicity, we still had all new workers continue to use a single queue, which we renamed from &amp;lt;code&amp;gt;mailers&amp;lt;/code&amp;gt; to &amp;lt;code&amp;gt;jobs&amp;lt;/code&amp;gt;. A future improvement could divide these jobs to go to multiple different queues if needed.&lt;br /&gt;
&lt;br /&gt;
=== Remove all code related to the &amp;lt;code&amp;gt;drop_one_member_topics&amp;lt;/code&amp;gt; deadline type ===&lt;br /&gt;
It was decided that code used for dropping one member or two member teams from topics would never need to be implemented in the Expertiza website. Thus, we removed all code related to the drop_one_member_topics method within the Expertiza beta. This involved removing the &amp;lt;code&amp;gt;drop_one_member_topics&amp;lt;/code&amp;gt; function from &amp;lt;code&amp;gt;drop_outstanding_reviews_mail_worker.rb&amp;lt;/code&amp;gt;, now renamed &amp;lt;code&amp;gt;drop_outstanding_reviews_worker.rb&amp;lt;/code&amp;gt;. The &amp;lt;code&amp;gt;drop_one_member_topics&amp;lt;/code&amp;gt; method was called from the &amp;lt;code&amp;gt;prepare_data&amp;lt;/code&amp;gt; method, which was then called by the Sidekiq method &amp;lt;code&amp;gt;perform&amp;lt;/code&amp;gt; so we removed this call. The &amp;lt;code&amp;gt;drop_one_member_topics&amp;lt;/code&amp;gt; was also referenced in &amp;lt;code&amp;gt;assignment_form.rb&amp;lt;/code&amp;gt; using &amp;lt;code&amp;gt;add_delayed_job&amp;lt;/code&amp;gt; in the &amp;lt;code&amp;gt;add_to_delayed_queue&amp;lt;/code&amp;gt; method and in &amp;lt;code&amp;gt;delayed_mailer.html.erb&amp;lt;/code&amp;gt; as an option for the handler so both of these code snippets were removed as well.&lt;br /&gt;
&lt;br /&gt;
=== Update and add unit tests according to the above changes ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Test all new worker classes to ensure Sidekiq jobs were being dequeued and run as expected ===&lt;br /&gt;
==== Sidekiq setup ====&lt;br /&gt;
In order to test the Sidekiq workers, a few steps were needed to set up the workers and run Sidekiq (steps were obtained from [https://tudip.com/blog-post/how-to-use-sidekiq-in-rails-for-background-processing/ this site]):&lt;br /&gt;
# Initialize three new workers, each having one of the three new worker types:&lt;br /&gt;
## &amp;lt;code&amp;gt;rails g sidekiq:worker SimicheckWorker&amp;lt;/code&amp;gt;&lt;br /&gt;
## &amp;lt;code&amp;gt;rails g sidekiq:worker DropOutstandingReviewsWorker&amp;lt;/code&amp;gt;&lt;br /&gt;
## &amp;lt;code&amp;gt;rails g sidekiq:worker MailWorker&amp;lt;/code&amp;gt;&lt;br /&gt;
# In a terminal separate from the one in which the main rails application is running, run&lt;br /&gt;
&amp;lt;blockquote&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
bundle exec sidekiq&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This Sidekiq-specific terminal will show logs and printed statements from the workers.&lt;br /&gt;
&lt;br /&gt;
==== SimicheckWorker Test ====&lt;br /&gt;
&lt;br /&gt;
==== MailWorker Test ====&lt;br /&gt;
The General Mail Worker sends out notifications to students if the due date of an assignment is changed. To test General Mail Worker, we first created an assignment with the default options by logging in as an instructor, going to Manage&amp;gt;Assignments in the navigation, and clicking the plus button in the top right corner on the Manage Assignments. We then assigned student7613 to the assignment we had created by clicking the person with the plus icon in the icons next to the assignment on the Manage Assignments page. At this point, we realized we need to alter the code to test if the code was properly queuing the General Mail Worker because the current if statement to add items to the delayed queue required that it have a late policy. However, the late policy code is not currently working. Thus, in the &amp;lt;code&amp;gt;assignment_form.rb&amp;lt;/code&amp;gt; model file, we edited the following code:&lt;br /&gt;
&lt;br /&gt;
[[File:Change_late_policy.png|950px|Late policy code to alter]]&lt;br /&gt;
&lt;br /&gt;
We removed &amp;lt;/code&amp;gt;and has_late_policy&amp;lt;/code&amp;gt; so &amp;lt;code&amp;gt;add_delayed_queue&amp;lt;/code&amp;gt; can run even without late policies being implemented.&lt;br /&gt;
&lt;br /&gt;
==== DropOutstandingReviewsWorker Test ====&lt;br /&gt;
&lt;br /&gt;
=== Sidekiq UI ===&lt;br /&gt;
To see which messages were being enqueued and dequeued in Sidekiq, we use the Sidekiq user interface, which can be accessed via the &amp;lt;code&amp;gt;/sidekiq&amp;lt;/code&amp;gt; route of the application.&lt;br /&gt;
[[File:Sidekiq-ui.png|950px|The Sidekiq UI]]&lt;br /&gt;
&lt;br /&gt;
=== Code Cleanup ===&lt;br /&gt;
Smaller improvements done while implementing the main tasks included:&lt;br /&gt;
* Using ActiveSupport::Duration objects in order to calculate the minutes and seconds related to the dequeue times&lt;br /&gt;
* Refactoring the time calculations for the dequeue times to the DueDate class&lt;br /&gt;
* Correcting the parameters passed to the workers, which were previously incorrect. As an example:&lt;br /&gt;
&amp;lt;blockquote&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def add_delayed_job(_assignment, deadline_type, due_date, min_left)&lt;br /&gt;
    delayed_job_id = MailWorker.perform_in(min_left * 60, due_date.parent_id, deadline_type, due_date.due_at)&lt;br /&gt;
    delayed_job_id&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
The first parameter after the time delay must be assignment ID, and &amp;lt;code&amp;gt;due_date.parent_id&amp;lt;/code&amp;gt; is not an assignment ID.&lt;br /&gt;
&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
* Removing whitespace issues reported by codeclimate&lt;br /&gt;
* Refactoring all variable names to be in snake_case&lt;br /&gt;
* Removing identical blocks of code&lt;br /&gt;
* Adding method comments to make methods more understandable&lt;br /&gt;
* ...&lt;/div&gt;</summary>
		<author><name>Agcarrut</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2021_-_E2144._Refactor_delayed_mailer_and_scheduled_task&amp;diff=140083</id>
		<title>CSC/ECE 517 Fall 2021 - E2144. Refactor delayed mailer and scheduled task</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2021_-_E2144._Refactor_delayed_mailer_and_scheduled_task&amp;diff=140083"/>
		<updated>2021-10-26T17:12:00Z</updated>

		<summary type="html">&lt;p&gt;Agcarrut: /* MailWorker Test */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;__TOC__&lt;br /&gt;
&lt;br /&gt;
== Background ==&lt;br /&gt;
This project revolves around the Sidekiq gem for asynchronous processing of email tasks. It has a queue system to hold and then process jobs. Sidekiq’s queue replaces DelayedMailer’s queue. The previous team that worked on this also created a method &amp;lt;code&amp;gt;perform()&amp;lt;/code&amp;gt; to gather email IDs of all participants in an assignment and send them an email reminder. Some test cases exist for this work.&lt;br /&gt;
&lt;br /&gt;
=== Previous Setup ===&lt;br /&gt;
Initial work can be found [https://expertiza.csc.ncsu.edu/index.php/E1835_Refactor_delayed_mailer_and_scheduled_task here].&lt;br /&gt;
&lt;br /&gt;
Code in the [https://github.com/expertiza/expertiza/pull/1245/files pull request] was found to be reasonable and working. The method &amp;lt;code&amp;gt;perform()&amp;lt;/code&amp;gt; has:&lt;br /&gt;
{| class=wikitable style=text-align:right&lt;br /&gt;
|+ Metrics for &amp;lt;code&amp;gt;perform&amp;lt;/code&amp;gt; method&lt;br /&gt;
|-&lt;br /&gt;
! Metric !! Current Value !! Limit&lt;br /&gt;
|-&lt;br /&gt;
! Cognitive Complexity&lt;br /&gt;
| 15 || 5&lt;br /&gt;
|-&lt;br /&gt;
! Cyclomatic Complexity&lt;br /&gt;
| 8 || 6&lt;br /&gt;
|-&lt;br /&gt;
! Assignment Branch Condition size&lt;br /&gt;
| 22.93 || 15&lt;br /&gt;
|-&lt;br /&gt;
! Perceived complexity&lt;br /&gt;
| 10 || 7&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Previous pull request also has duplicated commit messages and the commits need to be squashed.&lt;br /&gt;
&lt;br /&gt;
Files involved (some changed should not have been changed):&lt;br /&gt;
* app/controllers/assignments_controller.rb&lt;br /&gt;
* app/mailers/mail_worker.rb&lt;br /&gt;
* app/models/assignment_form.rb&lt;br /&gt;
* config/sidekiq.yml&lt;br /&gt;
* spec/models/assignment_form_spec.rb&lt;br /&gt;
* spec/sidekiq_mail_worker_spec.rb&lt;br /&gt;
* spec/spec_helper.rb&lt;br /&gt;
&lt;br /&gt;
There are minor styling issues such as missing or trailing whitespaces, lines that are too long, extra empty line, unused arguments.&lt;br /&gt;
&lt;br /&gt;
=== Problem Statement ===&lt;br /&gt;
&lt;br /&gt;
This project revolves around the Sidekiq gem for asynchronous processing of email tasks. It has a queue system to hold and then process jobs. Sidekiq's queue replaces DelayedMailer’s queue. The previous team that worked on this also created a method perform() to gather email IDs of all participants in an assignment and send them an email reminder. Some test cases exist for this work.&lt;br /&gt;
The project was partially merged.&lt;br /&gt;
​&lt;br /&gt;
&lt;br /&gt;
What needs to be done:  &lt;br /&gt;
Feedback from the previous team (E1835) is:&lt;br /&gt;
Code in pull request seems pretty reasonable.  Some concerns wrt. naming functions, but otherwise reviewers seem to agree that the code is good.&lt;br /&gt;
​&lt;br /&gt;
&lt;br /&gt;
Your pull request has many duplicated commit messages. Please try to &amp;lt;code&amp;gt;squash&amp;lt;/code&amp;gt; similar commits.&lt;br /&gt;
And using meaningful commit messages later.&lt;br /&gt;
​&lt;br /&gt;
&lt;br /&gt;
You should commit changes to the DB schema (&amp;lt;code&amp;gt;db/schema.rb&amp;lt;/code&amp;gt;) only if you have created new DB migrations.&lt;br /&gt;
Please double check your code. If you did not aim to change the DB, please revert the DB schema changes. ***** Important, try not to change the DB.&lt;br /&gt;
​&lt;br /&gt;
&lt;br /&gt;
You should not change &amp;lt;code&amp;gt;rails_helper.rb&amp;lt;/code&amp;gt; or &amp;lt;code&amp;gt;spec_helper.rb&amp;lt;/code&amp;gt; file; please revert these changes.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The previous team’s code needs a refactor in some places, though the actual function of it seems solid. It is very possible that in the three years since this code has been worked on, more mailer functionality has been added. There are other teams this semester working on mailer code as well. Try to keep your code as contained and simple as possible, so that merging these projects is possible.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Summary of Work Needed ==&lt;br /&gt;
After discussing with our project mentor and Dr. Gehringer, we determined the main tasks to be the following:&lt;br /&gt;
# Refactor the single Sidekiq worker into multiple workers&lt;br /&gt;
# Remove all code related to the &amp;lt;code&amp;gt;drop_one_member_topics&amp;lt;/code&amp;gt; deadline type&lt;br /&gt;
# Update and add unit tests according to the above changes&lt;br /&gt;
# Test all new worker classes to ensure Sidekiq jobs were being dequeued and run as expected&lt;br /&gt;
# Code cleanup&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Refactor the single Sidekiq worker into multiple workers ===&lt;br /&gt;
Previously there was only a single worker class that handled all types of jobs. Its top-level method &amp;lt;code&amp;gt;perform&amp;lt;/code&amp;gt; looked like the following.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def perform(assignment_id, deadline_type, due_at)&lt;br /&gt;
    self.assignment_id = assignment_id&lt;br /&gt;
    self.deadline_type = deadline_type&lt;br /&gt;
    self.due_at = due_at&lt;br /&gt;
&lt;br /&gt;
    assignment = Assignment.find(self.assignment_id)&lt;br /&gt;
    participant_mails = find_participant_emails&lt;br /&gt;
&lt;br /&gt;
    if %w[drop_one_member_topics drop_outstanding_reviews compare_files_with_simicheck].include?(self.deadline_type)&lt;br /&gt;
      drop_one_member_topics if self.deadline_type == &amp;quot;drop_outstanding_reviews&amp;quot; &amp;amp;&amp;amp; assignment.team_assignment&lt;br /&gt;
      drop_outstanding_reviews if self.deadline_type == &amp;quot;drop_outstanding_reviews&amp;quot;&lt;br /&gt;
      perform_simicheck_comparisons(self.assignment_id) if self.deadline_type == &amp;quot;compare_files_with_simicheck&amp;quot;&lt;br /&gt;
    else&lt;br /&gt;
      # Can we rename deadline_type(metareview) to &amp;quot;teammate review&amp;quot;. If, yes then we donot need this if clause below!&lt;br /&gt;
      deadlineText = if self.deadline_type == &amp;quot;metareview&amp;quot;&lt;br /&gt;
                       &amp;quot;teammate review&amp;quot;&lt;br /&gt;
                     else&lt;br /&gt;
                       self.deadline_type&lt;br /&gt;
      end&lt;br /&gt;
&lt;br /&gt;
      email_reminder(participant_mails, deadlineText) unless participant_mails.empty?&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The processing was different depending on the &amp;lt;code&amp;gt;deadline_type&amp;lt;/code&amp;gt;. The &amp;lt;code&amp;gt;deadline_type&amp;lt;/code&amp;gt;s in&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
%w[drop_one_member_topics drop_outstanding_reviews compare_files_with_simicheck]&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
did not lead to an email reminder being sent, but they were still handled in this &amp;lt;code&amp;gt;MailWorker&amp;lt;/code&amp;gt; class.&lt;br /&gt;
&lt;br /&gt;
To make the code more manageable and easier to follow, it made sense to break up the responsibilities of this single &amp;lt;code&amp;gt;MailWorker&amp;lt;/code&amp;gt; class into multiple workers:&lt;br /&gt;
* &amp;lt;code&amp;gt;SimicheckWorker&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;DropOutstandingReviewsWorker&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;MailWorker&amp;lt;/code&amp;gt;&lt;br /&gt;
All three workers extended an &amp;quot;abstract class&amp;quot; called &amp;lt;code&amp;gt;Worker&amp;lt;/code&amp;gt; that contained the Sidekiq-related &amp;lt;code&amp;gt;include&amp;lt;/code&amp;gt; and the queue name to which all jobs would be sent.&lt;br /&gt;
&lt;br /&gt;
For simplicity, we still had all new workers continue to use a single queue, which we renamed from &amp;lt;code&amp;gt;mailers&amp;lt;/code&amp;gt; to &amp;lt;code&amp;gt;jobs&amp;lt;/code&amp;gt;. A future improvement could divide these jobs to go to multiple different queues if needed.&lt;br /&gt;
&lt;br /&gt;
=== Remove all code related to the &amp;lt;code&amp;gt;drop_one_member_topics&amp;lt;/code&amp;gt; deadline type ===&lt;br /&gt;
It was decided that code used for dropping one member or two member teams from topics would never need to be implemented in the Expertiza website. Thus, we removed all code related to the drop_one_member_topics method within the Expertiza beta. This involved removing the &amp;lt;code&amp;gt;drop_one_member_topics&amp;lt;/code&amp;gt; function from &amp;lt;code&amp;gt;drop_outstanding_reviews_mail_worker.rb&amp;lt;/code&amp;gt;, now renamed &amp;lt;code&amp;gt;drop_outstanding_reviews_worker.rb&amp;lt;/code&amp;gt;. The &amp;lt;code&amp;gt;drop_one_member_topics&amp;lt;/code&amp;gt; method was called from the &amp;lt;code&amp;gt;prepare_data&amp;lt;/code&amp;gt; method, which was then called by the Sidekiq method &amp;lt;code&amp;gt;perform&amp;lt;/code&amp;gt; so we removed this call. The &amp;lt;code&amp;gt;drop_one_member_topics&amp;lt;/code&amp;gt; was also referenced in &amp;lt;code&amp;gt;assignment_form.rb&amp;lt;/code&amp;gt; using &amp;lt;code&amp;gt;add_delayed_job&amp;lt;/code&amp;gt; in the &amp;lt;code&amp;gt;add_to_delayed_queue&amp;lt;/code&amp;gt; method and in &amp;lt;code&amp;gt;delayed_mailer.html.erb&amp;lt;/code&amp;gt; as an option for the handler so both of these code snippets were removed as well.&lt;br /&gt;
&lt;br /&gt;
=== Update and add unit tests according to the above changes ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Test all new worker classes to ensure Sidekiq jobs were being dequeued and run as expected ===&lt;br /&gt;
==== Sidekiq setup ====&lt;br /&gt;
In order to test the Sidekiq workers, a few steps were needed to set up the workers and run Sidekiq (steps were obtained from [https://tudip.com/blog-post/how-to-use-sidekiq-in-rails-for-background-processing/ this site]):&lt;br /&gt;
# Initialize three new workers, each having one of the three new worker types:&lt;br /&gt;
## &amp;lt;code&amp;gt;rails g sidekiq:worker SimicheckWorker&amp;lt;/code&amp;gt;&lt;br /&gt;
## &amp;lt;code&amp;gt;rails g sidekiq:worker DropOutstandingReviewsWorker&amp;lt;/code&amp;gt;&lt;br /&gt;
## &amp;lt;code&amp;gt;rails g sidekiq:worker MailWorker&amp;lt;/code&amp;gt;&lt;br /&gt;
# In a terminal separate from the one in which the main rails application is running, run&lt;br /&gt;
&amp;lt;blockquote&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
bundle exec sidekiq&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This Sidekiq-specific terminal will show logs and printed statements from the workers.&lt;br /&gt;
&lt;br /&gt;
==== SimicheckWorker Test ====&lt;br /&gt;
&lt;br /&gt;
==== MailWorker Test ====&lt;br /&gt;
The General Mail Worker sends out notifications to students if the due date of an assignment is changed. To test General Mail Worker, we first created an assignment with the default options by logging in as an instructor, going to Manage&amp;gt;Assignments in the navigation, and clicking the plus button in the top right corner on the Manage Assignments. We then assigned student7613 to the assignment we had created by clicking the person with the plus icon in the icons next to the assignment on the Manage Assignments page. At this point, we realized we need to alter the code to test if the code was properly queuing the General Mail Worker because the current if statement to add items to the delayed queue required that it have a late policy. However, the late policy code is not currently working. Thus, in the &amp;lt;code&amp;gt;assignment_form.rb&amp;lt;/code&amp;gt; model file, we edited the following code:&lt;br /&gt;
[[File:Change_late_policy.png|500px|Late policy code to alter]]&lt;br /&gt;
We removed &amp;lt;/code&amp;gt;and has_late_policy&amp;lt;/code&amp;gt; so &amp;lt;code&amp;gt;add_delayed_queue&amp;lt;/code&amp;gt; can run even without late policies being implemented.&lt;br /&gt;
&lt;br /&gt;
==== DropOutstandingReviewsWorker Test ====&lt;br /&gt;
&lt;br /&gt;
=== Sidekiq UI ===&lt;br /&gt;
To see which messages were being enqueued and dequeued in Sidekiq, we use the Sidekiq user interface, which can be accessed via the &amp;lt;code&amp;gt;/sidekiq&amp;lt;/code&amp;gt; route of the application.&lt;br /&gt;
[[File:Sidekiq-ui.png|950px|The Sidekiq UI]]&lt;br /&gt;
&lt;br /&gt;
=== Code Cleanup ===&lt;br /&gt;
Smaller improvements done while implementing the main tasks included:&lt;br /&gt;
* Using ActiveSupport::Duration objects in order to calculate the minutes and seconds related to the dequeue times&lt;br /&gt;
* Refactoring the time calculations for the dequeue times to the DueDate class&lt;br /&gt;
* Correcting the parameters passed to the workers, which were previously incorrect. As an example:&lt;br /&gt;
&amp;lt;blockquote&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def add_delayed_job(_assignment, deadline_type, due_date, min_left)&lt;br /&gt;
    delayed_job_id = MailWorker.perform_in(min_left * 60, due_date.parent_id, deadline_type, due_date.due_at)&lt;br /&gt;
    delayed_job_id&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
The first parameter after the time delay must be assignment ID, and &amp;lt;code&amp;gt;due_date.parent_id&amp;lt;/code&amp;gt; is not an assignment ID.&lt;br /&gt;
&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
* Removing whitespace issues reported by codeclimate&lt;br /&gt;
* Refactoring all variable names to be in snake_case&lt;br /&gt;
* Removing identical blocks of code&lt;br /&gt;
* Adding method comments to make methods more understandable&lt;br /&gt;
* ...&lt;/div&gt;</summary>
		<author><name>Agcarrut</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=File:Change_late_policy.png&amp;diff=140082</id>
		<title>File:Change late policy.png</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=File:Change_late_policy.png&amp;diff=140082"/>
		<updated>2021-10-26T17:11:13Z</updated>

		<summary type="html">&lt;p&gt;Agcarrut: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Agcarrut</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2021_-_E2144._Refactor_delayed_mailer_and_scheduled_task&amp;diff=140081</id>
		<title>CSC/ECE 517 Fall 2021 - E2144. Refactor delayed mailer and scheduled task</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2021_-_E2144._Refactor_delayed_mailer_and_scheduled_task&amp;diff=140081"/>
		<updated>2021-10-26T17:08:05Z</updated>

		<summary type="html">&lt;p&gt;Agcarrut: /* MailWorker Test */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;__TOC__&lt;br /&gt;
&lt;br /&gt;
== Background ==&lt;br /&gt;
This project revolves around the Sidekiq gem for asynchronous processing of email tasks. It has a queue system to hold and then process jobs. Sidekiq’s queue replaces DelayedMailer’s queue. The previous team that worked on this also created a method &amp;lt;code&amp;gt;perform()&amp;lt;/code&amp;gt; to gather email IDs of all participants in an assignment and send them an email reminder. Some test cases exist for this work.&lt;br /&gt;
&lt;br /&gt;
=== Previous Setup ===&lt;br /&gt;
Initial work can be found [https://expertiza.csc.ncsu.edu/index.php/E1835_Refactor_delayed_mailer_and_scheduled_task here].&lt;br /&gt;
&lt;br /&gt;
Code in the [https://github.com/expertiza/expertiza/pull/1245/files pull request] was found to be reasonable and working. The method &amp;lt;code&amp;gt;perform()&amp;lt;/code&amp;gt; has:&lt;br /&gt;
{| class=wikitable style=text-align:right&lt;br /&gt;
|+ Metrics for &amp;lt;code&amp;gt;perform&amp;lt;/code&amp;gt; method&lt;br /&gt;
|-&lt;br /&gt;
! Metric !! Current Value !! Limit&lt;br /&gt;
|-&lt;br /&gt;
! Cognitive Complexity&lt;br /&gt;
| 15 || 5&lt;br /&gt;
|-&lt;br /&gt;
! Cyclomatic Complexity&lt;br /&gt;
| 8 || 6&lt;br /&gt;
|-&lt;br /&gt;
! Assignment Branch Condition size&lt;br /&gt;
| 22.93 || 15&lt;br /&gt;
|-&lt;br /&gt;
! Perceived complexity&lt;br /&gt;
| 10 || 7&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Previous pull request also has duplicated commit messages and the commits need to be squashed.&lt;br /&gt;
&lt;br /&gt;
Files involved (some changed should not have been changed):&lt;br /&gt;
* app/controllers/assignments_controller.rb&lt;br /&gt;
* app/mailers/mail_worker.rb&lt;br /&gt;
* app/models/assignment_form.rb&lt;br /&gt;
* config/sidekiq.yml&lt;br /&gt;
* spec/models/assignment_form_spec.rb&lt;br /&gt;
* spec/sidekiq_mail_worker_spec.rb&lt;br /&gt;
* spec/spec_helper.rb&lt;br /&gt;
&lt;br /&gt;
There are minor styling issues such as missing or trailing whitespaces, lines that are too long, extra empty line, unused arguments.&lt;br /&gt;
&lt;br /&gt;
=== Problem Statement ===&lt;br /&gt;
&lt;br /&gt;
This project revolves around the Sidekiq gem for asynchronous processing of email tasks. It has a queue system to hold and then process jobs. Sidekiq's queue replaces DelayedMailer’s queue. The previous team that worked on this also created a method perform() to gather email IDs of all participants in an assignment and send them an email reminder. Some test cases exist for this work.&lt;br /&gt;
The project was partially merged.&lt;br /&gt;
​&lt;br /&gt;
&lt;br /&gt;
What needs to be done:  &lt;br /&gt;
Feedback from the previous team (E1835) is:&lt;br /&gt;
Code in pull request seems pretty reasonable.  Some concerns wrt. naming functions, but otherwise reviewers seem to agree that the code is good.&lt;br /&gt;
​&lt;br /&gt;
&lt;br /&gt;
Your pull request has many duplicated commit messages. Please try to &amp;lt;code&amp;gt;squash&amp;lt;/code&amp;gt; similar commits.&lt;br /&gt;
And using meaningful commit messages later.&lt;br /&gt;
​&lt;br /&gt;
&lt;br /&gt;
You should commit changes to the DB schema (&amp;lt;code&amp;gt;db/schema.rb&amp;lt;/code&amp;gt;) only if you have created new DB migrations.&lt;br /&gt;
Please double check your code. If you did not aim to change the DB, please revert the DB schema changes. ***** Important, try not to change the DB.&lt;br /&gt;
​&lt;br /&gt;
&lt;br /&gt;
You should not change &amp;lt;code&amp;gt;rails_helper.rb&amp;lt;/code&amp;gt; or &amp;lt;code&amp;gt;spec_helper.rb&amp;lt;/code&amp;gt; file; please revert these changes.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The previous team’s code needs a refactor in some places, though the actual function of it seems solid. It is very possible that in the three years since this code has been worked on, more mailer functionality has been added. There are other teams this semester working on mailer code as well. Try to keep your code as contained and simple as possible, so that merging these projects is possible.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Summary of Work Needed ==&lt;br /&gt;
After discussing with our project mentor and Dr. Gehringer, we determined the main tasks to be the following:&lt;br /&gt;
# Refactor the single Sidekiq worker into multiple workers&lt;br /&gt;
# Remove all code related to the &amp;lt;code&amp;gt;drop_one_member_topics&amp;lt;/code&amp;gt; deadline type&lt;br /&gt;
# Update and add unit tests according to the above changes&lt;br /&gt;
# Test all new worker classes to ensure Sidekiq jobs were being dequeued and run as expected&lt;br /&gt;
# Code cleanup&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Refactor the single Sidekiq worker into multiple workers ===&lt;br /&gt;
Previously there was only a single worker class that handled all types of jobs. Its top-level method &amp;lt;code&amp;gt;perform&amp;lt;/code&amp;gt; looked like the following.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def perform(assignment_id, deadline_type, due_at)&lt;br /&gt;
    self.assignment_id = assignment_id&lt;br /&gt;
    self.deadline_type = deadline_type&lt;br /&gt;
    self.due_at = due_at&lt;br /&gt;
&lt;br /&gt;
    assignment = Assignment.find(self.assignment_id)&lt;br /&gt;
    participant_mails = find_participant_emails&lt;br /&gt;
&lt;br /&gt;
    if %w[drop_one_member_topics drop_outstanding_reviews compare_files_with_simicheck].include?(self.deadline_type)&lt;br /&gt;
      drop_one_member_topics if self.deadline_type == &amp;quot;drop_outstanding_reviews&amp;quot; &amp;amp;&amp;amp; assignment.team_assignment&lt;br /&gt;
      drop_outstanding_reviews if self.deadline_type == &amp;quot;drop_outstanding_reviews&amp;quot;&lt;br /&gt;
      perform_simicheck_comparisons(self.assignment_id) if self.deadline_type == &amp;quot;compare_files_with_simicheck&amp;quot;&lt;br /&gt;
    else&lt;br /&gt;
      # Can we rename deadline_type(metareview) to &amp;quot;teammate review&amp;quot;. If, yes then we donot need this if clause below!&lt;br /&gt;
      deadlineText = if self.deadline_type == &amp;quot;metareview&amp;quot;&lt;br /&gt;
                       &amp;quot;teammate review&amp;quot;&lt;br /&gt;
                     else&lt;br /&gt;
                       self.deadline_type&lt;br /&gt;
      end&lt;br /&gt;
&lt;br /&gt;
      email_reminder(participant_mails, deadlineText) unless participant_mails.empty?&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The processing was different depending on the &amp;lt;code&amp;gt;deadline_type&amp;lt;/code&amp;gt;. The &amp;lt;code&amp;gt;deadline_type&amp;lt;/code&amp;gt;s in&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
%w[drop_one_member_topics drop_outstanding_reviews compare_files_with_simicheck]&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
did not lead to an email reminder being sent, but they were still handled in this &amp;lt;code&amp;gt;MailWorker&amp;lt;/code&amp;gt; class.&lt;br /&gt;
&lt;br /&gt;
To make the code more manageable and easier to follow, it made sense to break up the responsibilities of this single &amp;lt;code&amp;gt;MailWorker&amp;lt;/code&amp;gt; class into multiple workers:&lt;br /&gt;
* &amp;lt;code&amp;gt;SimicheckWorker&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;DropOutstandingReviewsWorker&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;MailWorker&amp;lt;/code&amp;gt;&lt;br /&gt;
All three workers extended an &amp;quot;abstract class&amp;quot; called &amp;lt;code&amp;gt;Worker&amp;lt;/code&amp;gt; that contained the Sidekiq-related &amp;lt;code&amp;gt;include&amp;lt;/code&amp;gt; and the queue name to which all jobs would be sent.&lt;br /&gt;
&lt;br /&gt;
For simplicity, we still had all new workers continue to use a single queue, which we renamed from &amp;lt;code&amp;gt;mailers&amp;lt;/code&amp;gt; to &amp;lt;code&amp;gt;jobs&amp;lt;/code&amp;gt;. A future improvement could divide these jobs to go to multiple different queues if needed.&lt;br /&gt;
&lt;br /&gt;
=== Remove all code related to the &amp;lt;code&amp;gt;drop_one_member_topics&amp;lt;/code&amp;gt; deadline type ===&lt;br /&gt;
It was decided that code used for dropping one member or two member teams from topics would never need to be implemented in the Expertiza website. Thus, we removed all code related to the drop_one_member_topics method within the Expertiza beta. This involved removing the &amp;lt;code&amp;gt;drop_one_member_topics&amp;lt;/code&amp;gt; function from &amp;lt;code&amp;gt;drop_outstanding_reviews_mail_worker.rb&amp;lt;/code&amp;gt;, now renamed &amp;lt;code&amp;gt;drop_outstanding_reviews_worker.rb&amp;lt;/code&amp;gt;. The &amp;lt;code&amp;gt;drop_one_member_topics&amp;lt;/code&amp;gt; method was called from the &amp;lt;code&amp;gt;prepare_data&amp;lt;/code&amp;gt; method, which was then called by the Sidekiq method &amp;lt;code&amp;gt;perform&amp;lt;/code&amp;gt; so we removed this call. The &amp;lt;code&amp;gt;drop_one_member_topics&amp;lt;/code&amp;gt; was also referenced in &amp;lt;code&amp;gt;assignment_form.rb&amp;lt;/code&amp;gt; using &amp;lt;code&amp;gt;add_delayed_job&amp;lt;/code&amp;gt; in the &amp;lt;code&amp;gt;add_to_delayed_queue&amp;lt;/code&amp;gt; method and in &amp;lt;code&amp;gt;delayed_mailer.html.erb&amp;lt;/code&amp;gt; as an option for the handler so both of these code snippets were removed as well.&lt;br /&gt;
&lt;br /&gt;
=== Update and add unit tests according to the above changes ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Test all new worker classes to ensure Sidekiq jobs were being dequeued and run as expected ===&lt;br /&gt;
==== Sidekiq setup ====&lt;br /&gt;
In order to test the Sidekiq workers, a few steps were needed to set up the workers and run Sidekiq (steps were obtained from [https://tudip.com/blog-post/how-to-use-sidekiq-in-rails-for-background-processing/ this site]):&lt;br /&gt;
# Initialize three new workers, each having one of the three new worker types:&lt;br /&gt;
## &amp;lt;code&amp;gt;rails g sidekiq:worker SimicheckWorker&amp;lt;/code&amp;gt;&lt;br /&gt;
## &amp;lt;code&amp;gt;rails g sidekiq:worker DropOutstandingReviewsWorker&amp;lt;/code&amp;gt;&lt;br /&gt;
## &amp;lt;code&amp;gt;rails g sidekiq:worker MailWorker&amp;lt;/code&amp;gt;&lt;br /&gt;
# In a terminal separate from the one in which the main rails application is running, run&lt;br /&gt;
&amp;lt;blockquote&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
bundle exec sidekiq&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This Sidekiq-specific terminal will show logs and printed statements from the workers.&lt;br /&gt;
&lt;br /&gt;
==== SimicheckWorker Test ====&lt;br /&gt;
&lt;br /&gt;
==== MailWorker Test ====&lt;br /&gt;
The General Mail Worker sends out notifications to students if the due date of an assignment is changed. To test General Mail Worker, we first created an assignment with the default options by logging in as an instructor, going to Manage&amp;gt;Assignments in the navigation, and clicking the plus button in the top right corner on the Manage Assignments. We then assigned student7613 to the assignment we had created by clicking the person with the plus icon in the icons next to the assignment on the Manage Assignments page. At this point, we realized we need to alter the code to test if the code was properly queuing the General Mail Worker because the current if statement to add items to the delayed queue required that it have a late policy. However, the late policy code is not currently working. Thus, in the &amp;lt;code&amp;gt;assignment_form.rb&amp;lt;/code&amp;gt; model file, we edited the following code:&lt;br /&gt;
[[File:Change_it.png|500px|Late policy code to alter]]&lt;br /&gt;
We removed &amp;lt;/code&amp;gt;and has_late_policy&amp;lt;/code&amp;gt; so &amp;lt;code&amp;gt;add_delayed_queue&amp;lt;/code&amp;gt; can run even without late policies being implemented.&lt;br /&gt;
&lt;br /&gt;
==== DropOutstandingReviewsWorker Test ====&lt;br /&gt;
&lt;br /&gt;
=== Sidekiq UI ===&lt;br /&gt;
To see which messages were being enqueued and dequeued in Sidekiq, we use the Sidekiq user interface, which can be accessed via the &amp;lt;code&amp;gt;/sidekiq&amp;lt;/code&amp;gt; route of the application.&lt;br /&gt;
[[File:Sidekiq-ui.png|950px|The Sidekiq UI]]&lt;br /&gt;
&lt;br /&gt;
=== Code Cleanup ===&lt;br /&gt;
Smaller improvements done while implementing the main tasks included:&lt;br /&gt;
* Using ActiveSupport::Duration objects in order to calculate the minutes and seconds related to the dequeue times&lt;br /&gt;
* Refactoring the time calculations for the dequeue times to the DueDate class&lt;br /&gt;
* Correcting the parameters passed to the workers, which were previously incorrect. As an example:&lt;br /&gt;
&amp;lt;blockquote&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def add_delayed_job(_assignment, deadline_type, due_date, min_left)&lt;br /&gt;
    delayed_job_id = MailWorker.perform_in(min_left * 60, due_date.parent_id, deadline_type, due_date.due_at)&lt;br /&gt;
    delayed_job_id&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
The first parameter after the time delay must be assignment ID, and &amp;lt;code&amp;gt;due_date.parent_id&amp;lt;/code&amp;gt; is not an assignment ID.&lt;br /&gt;
&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
* Removing whitespace issues reported by codeclimate&lt;br /&gt;
* Refactoring all variable names to be in snake_case&lt;br /&gt;
* Removing identical blocks of code&lt;br /&gt;
* Adding method comments to make methods more understandable&lt;br /&gt;
* ...&lt;/div&gt;</summary>
		<author><name>Agcarrut</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2021_-_E2144._Refactor_delayed_mailer_and_scheduled_task&amp;diff=140080</id>
		<title>CSC/ECE 517 Fall 2021 - E2144. Refactor delayed mailer and scheduled task</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2021_-_E2144._Refactor_delayed_mailer_and_scheduled_task&amp;diff=140080"/>
		<updated>2021-10-26T17:02:41Z</updated>

		<summary type="html">&lt;p&gt;Agcarrut: /* MailWorker Test */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;__TOC__&lt;br /&gt;
&lt;br /&gt;
== Background ==&lt;br /&gt;
This project revolves around the Sidekiq gem for asynchronous processing of email tasks. It has a queue system to hold and then process jobs. Sidekiq’s queue replaces DelayedMailer’s queue. The previous team that worked on this also created a method &amp;lt;code&amp;gt;perform()&amp;lt;/code&amp;gt; to gather email IDs of all participants in an assignment and send them an email reminder. Some test cases exist for this work.&lt;br /&gt;
&lt;br /&gt;
=== Previous Setup ===&lt;br /&gt;
Initial work can be found [https://expertiza.csc.ncsu.edu/index.php/E1835_Refactor_delayed_mailer_and_scheduled_task here].&lt;br /&gt;
&lt;br /&gt;
Code in the [https://github.com/expertiza/expertiza/pull/1245/files pull request] was found to be reasonable and working. The method &amp;lt;code&amp;gt;perform()&amp;lt;/code&amp;gt; has:&lt;br /&gt;
{| class=wikitable style=text-align:right&lt;br /&gt;
|+ Metrics for &amp;lt;code&amp;gt;perform&amp;lt;/code&amp;gt; method&lt;br /&gt;
|-&lt;br /&gt;
! Metric !! Current Value !! Limit&lt;br /&gt;
|-&lt;br /&gt;
! Cognitive Complexity&lt;br /&gt;
| 15 || 5&lt;br /&gt;
|-&lt;br /&gt;
! Cyclomatic Complexity&lt;br /&gt;
| 8 || 6&lt;br /&gt;
|-&lt;br /&gt;
! Assignment Branch Condition size&lt;br /&gt;
| 22.93 || 15&lt;br /&gt;
|-&lt;br /&gt;
! Perceived complexity&lt;br /&gt;
| 10 || 7&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Previous pull request also has duplicated commit messages and the commits need to be squashed.&lt;br /&gt;
&lt;br /&gt;
Files involved (some changed should not have been changed):&lt;br /&gt;
* app/controllers/assignments_controller.rb&lt;br /&gt;
* app/mailers/mail_worker.rb&lt;br /&gt;
* app/models/assignment_form.rb&lt;br /&gt;
* config/sidekiq.yml&lt;br /&gt;
* spec/models/assignment_form_spec.rb&lt;br /&gt;
* spec/sidekiq_mail_worker_spec.rb&lt;br /&gt;
* spec/spec_helper.rb&lt;br /&gt;
&lt;br /&gt;
There are minor styling issues such as missing or trailing whitespaces, lines that are too long, extra empty line, unused arguments.&lt;br /&gt;
&lt;br /&gt;
=== Problem Statement ===&lt;br /&gt;
&lt;br /&gt;
This project revolves around the Sidekiq gem for asynchronous processing of email tasks. It has a queue system to hold and then process jobs. Sidekiq's queue replaces DelayedMailer’s queue. The previous team that worked on this also created a method perform() to gather email IDs of all participants in an assignment and send them an email reminder. Some test cases exist for this work.&lt;br /&gt;
The project was partially merged.&lt;br /&gt;
​&lt;br /&gt;
&lt;br /&gt;
What needs to be done:  &lt;br /&gt;
Feedback from the previous team (E1835) is:&lt;br /&gt;
Code in pull request seems pretty reasonable.  Some concerns wrt. naming functions, but otherwise reviewers seem to agree that the code is good.&lt;br /&gt;
​&lt;br /&gt;
&lt;br /&gt;
Your pull request has many duplicated commit messages. Please try to &amp;lt;code&amp;gt;squash&amp;lt;/code&amp;gt; similar commits.&lt;br /&gt;
And using meaningful commit messages later.&lt;br /&gt;
​&lt;br /&gt;
&lt;br /&gt;
You should commit changes to the DB schema (&amp;lt;code&amp;gt;db/schema.rb&amp;lt;/code&amp;gt;) only if you have created new DB migrations.&lt;br /&gt;
Please double check your code. If you did not aim to change the DB, please revert the DB schema changes. ***** Important, try not to change the DB.&lt;br /&gt;
​&lt;br /&gt;
&lt;br /&gt;
You should not change &amp;lt;code&amp;gt;rails_helper.rb&amp;lt;/code&amp;gt; or &amp;lt;code&amp;gt;spec_helper.rb&amp;lt;/code&amp;gt; file; please revert these changes.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The previous team’s code needs a refactor in some places, though the actual function of it seems solid. It is very possible that in the three years since this code has been worked on, more mailer functionality has been added. There are other teams this semester working on mailer code as well. Try to keep your code as contained and simple as possible, so that merging these projects is possible.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Summary of Work Needed ==&lt;br /&gt;
After discussing with our project mentor and Dr. Gehringer, we determined the main tasks to be the following:&lt;br /&gt;
# Refactor the single Sidekiq worker into multiple workers&lt;br /&gt;
# Remove all code related to the &amp;lt;code&amp;gt;drop_one_member_topics&amp;lt;/code&amp;gt; deadline type&lt;br /&gt;
# Update and add unit tests according to the above changes&lt;br /&gt;
# Test all new worker classes to ensure Sidekiq jobs were being dequeued and run as expected&lt;br /&gt;
# Code cleanup&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Refactor the single Sidekiq worker into multiple workers ===&lt;br /&gt;
Previously there was only a single worker class that handled all types of jobs. Its top-level method &amp;lt;code&amp;gt;perform&amp;lt;/code&amp;gt; looked like the following.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def perform(assignment_id, deadline_type, due_at)&lt;br /&gt;
    self.assignment_id = assignment_id&lt;br /&gt;
    self.deadline_type = deadline_type&lt;br /&gt;
    self.due_at = due_at&lt;br /&gt;
&lt;br /&gt;
    assignment = Assignment.find(self.assignment_id)&lt;br /&gt;
    participant_mails = find_participant_emails&lt;br /&gt;
&lt;br /&gt;
    if %w[drop_one_member_topics drop_outstanding_reviews compare_files_with_simicheck].include?(self.deadline_type)&lt;br /&gt;
      drop_one_member_topics if self.deadline_type == &amp;quot;drop_outstanding_reviews&amp;quot; &amp;amp;&amp;amp; assignment.team_assignment&lt;br /&gt;
      drop_outstanding_reviews if self.deadline_type == &amp;quot;drop_outstanding_reviews&amp;quot;&lt;br /&gt;
      perform_simicheck_comparisons(self.assignment_id) if self.deadline_type == &amp;quot;compare_files_with_simicheck&amp;quot;&lt;br /&gt;
    else&lt;br /&gt;
      # Can we rename deadline_type(metareview) to &amp;quot;teammate review&amp;quot;. If, yes then we donot need this if clause below!&lt;br /&gt;
      deadlineText = if self.deadline_type == &amp;quot;metareview&amp;quot;&lt;br /&gt;
                       &amp;quot;teammate review&amp;quot;&lt;br /&gt;
                     else&lt;br /&gt;
                       self.deadline_type&lt;br /&gt;
      end&lt;br /&gt;
&lt;br /&gt;
      email_reminder(participant_mails, deadlineText) unless participant_mails.empty?&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The processing was different depending on the &amp;lt;code&amp;gt;deadline_type&amp;lt;/code&amp;gt;. The &amp;lt;code&amp;gt;deadline_type&amp;lt;/code&amp;gt;s in&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
%w[drop_one_member_topics drop_outstanding_reviews compare_files_with_simicheck]&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
did not lead to an email reminder being sent, but they were still handled in this &amp;lt;code&amp;gt;MailWorker&amp;lt;/code&amp;gt; class.&lt;br /&gt;
&lt;br /&gt;
To make the code more manageable and easier to follow, it made sense to break up the responsibilities of this single &amp;lt;code&amp;gt;MailWorker&amp;lt;/code&amp;gt; class into multiple workers:&lt;br /&gt;
* &amp;lt;code&amp;gt;SimicheckWorker&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;DropOutstandingReviewsWorker&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;MailWorker&amp;lt;/code&amp;gt;&lt;br /&gt;
All three workers extended an &amp;quot;abstract class&amp;quot; called &amp;lt;code&amp;gt;Worker&amp;lt;/code&amp;gt; that contained the Sidekiq-related &amp;lt;code&amp;gt;include&amp;lt;/code&amp;gt; and the queue name to which all jobs would be sent.&lt;br /&gt;
&lt;br /&gt;
For simplicity, we still had all new workers continue to use a single queue, which we renamed from &amp;lt;code&amp;gt;mailers&amp;lt;/code&amp;gt; to &amp;lt;code&amp;gt;jobs&amp;lt;/code&amp;gt;. A future improvement could divide these jobs to go to multiple different queues if needed.&lt;br /&gt;
&lt;br /&gt;
=== Remove all code related to the &amp;lt;code&amp;gt;drop_one_member_topics&amp;lt;/code&amp;gt; deadline type ===&lt;br /&gt;
It was decided that code used for dropping one member or two member teams from topics would never need to be implemented in the Expertiza website. Thus, we removed all code related to the drop_one_member_topics method within the Expertiza beta. This involved removing the &amp;lt;code&amp;gt;drop_one_member_topics&amp;lt;/code&amp;gt; function from &amp;lt;code&amp;gt;drop_outstanding_reviews_mail_worker.rb&amp;lt;/code&amp;gt;, now renamed &amp;lt;code&amp;gt;drop_outstanding_reviews_worker.rb&amp;lt;/code&amp;gt;. The &amp;lt;code&amp;gt;drop_one_member_topics&amp;lt;/code&amp;gt; method was called from the &amp;lt;code&amp;gt;prepare_data&amp;lt;/code&amp;gt; method, which was then called by the Sidekiq method &amp;lt;code&amp;gt;perform&amp;lt;/code&amp;gt; so we removed this call. The &amp;lt;code&amp;gt;drop_one_member_topics&amp;lt;/code&amp;gt; was also referenced in &amp;lt;code&amp;gt;assignment_form.rb&amp;lt;/code&amp;gt; using &amp;lt;code&amp;gt;add_delayed_job&amp;lt;/code&amp;gt; in the &amp;lt;code&amp;gt;add_to_delayed_queue&amp;lt;/code&amp;gt; method and in &amp;lt;code&amp;gt;delayed_mailer.html.erb&amp;lt;/code&amp;gt; as an option for the handler so both of these code snippets were removed as well.&lt;br /&gt;
&lt;br /&gt;
=== Update and add unit tests according to the above changes ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Test all new worker classes to ensure Sidekiq jobs were being dequeued and run as expected ===&lt;br /&gt;
==== Sidekiq setup ====&lt;br /&gt;
In order to test the Sidekiq workers, a few steps were needed to set up the workers and run Sidekiq (steps were obtained from [https://tudip.com/blog-post/how-to-use-sidekiq-in-rails-for-background-processing/ this site]):&lt;br /&gt;
# Initialize three new workers, each having one of the three new worker types:&lt;br /&gt;
## &amp;lt;code&amp;gt;rails g sidekiq:worker SimicheckWorker&amp;lt;/code&amp;gt;&lt;br /&gt;
## &amp;lt;code&amp;gt;rails g sidekiq:worker DropOutstandingReviewsWorker&amp;lt;/code&amp;gt;&lt;br /&gt;
## &amp;lt;code&amp;gt;rails g sidekiq:worker MailWorker&amp;lt;/code&amp;gt;&lt;br /&gt;
# In a terminal separate from the one in which the main rails application is running, run&lt;br /&gt;
&amp;lt;blockquote&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
bundle exec sidekiq&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This Sidekiq-specific terminal will show logs and printed statements from the workers.&lt;br /&gt;
&lt;br /&gt;
==== SimicheckWorker Test ====&lt;br /&gt;
&lt;br /&gt;
==== MailWorker Test ====&lt;br /&gt;
The General Mail Worker sends out notifications to students if the due date of an assignment is changed. To test General Mail Worker, we first created an assignment with the default options by logging in as an instructor, going to Manage&amp;gt;Assignments in the navigation, and clicking the plus button in the top right corner on the Manage Assignments. We then assigned student7613 to the assignment we had created by clicking the person with the plus icon in the icons next to the assignment on the Manage Assignments page. At this point, we realized we need to alter the code to test if the code was properly queuing the General Mail Worker because the current if statement to add items to the delayed queue required that it have a late policy. In the &amp;lt;code&amp;gt;assignment_form.rb&amp;lt;/code&amp;gt; model file, we edited the following code:&lt;br /&gt;
[[File:Change-it.png|500px|Late policy code to alter]]&lt;br /&gt;
&lt;br /&gt;
==== DropOutstandingReviewsWorker Test ====&lt;br /&gt;
&lt;br /&gt;
=== Sidekiq UI ===&lt;br /&gt;
To see which messages were being enqueued and dequeued in Sidekiq, we use the Sidekiq user interface, which can be accessed via the &amp;lt;code&amp;gt;/sidekiq&amp;lt;/code&amp;gt; route of the application.&lt;br /&gt;
[[File:Sidekiq-ui.png|950px|The Sidekiq UI]]&lt;br /&gt;
&lt;br /&gt;
=== Code Cleanup ===&lt;br /&gt;
Smaller improvements done while implementing the main tasks included:&lt;br /&gt;
* Using ActiveSupport::Duration objects in order to calculate the minutes and seconds related to the dequeue times&lt;br /&gt;
* Refactoring the time calculations for the dequeue times to the DueDate class&lt;br /&gt;
* Correcting the parameters passed to the workers, which were previously incorrect. As an example:&lt;br /&gt;
&amp;lt;blockquote&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def add_delayed_job(_assignment, deadline_type, due_date, min_left)&lt;br /&gt;
    delayed_job_id = MailWorker.perform_in(min_left * 60, due_date.parent_id, deadline_type, due_date.due_at)&lt;br /&gt;
    delayed_job_id&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
The first parameter after the time delay must be assignment ID, and &amp;lt;code&amp;gt;due_date.parent_id&amp;lt;/code&amp;gt; is not an assignment ID.&lt;br /&gt;
&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
* Removing whitespace issues reported by codeclimate&lt;br /&gt;
* Refactoring all variable names to be in snake_case&lt;br /&gt;
* Removing identical blocks of code&lt;br /&gt;
* Adding method comments to make methods more understandable&lt;br /&gt;
* ...&lt;/div&gt;</summary>
		<author><name>Agcarrut</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=File:Change_it.PNG&amp;diff=140079</id>
		<title>File:Change it.PNG</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=File:Change_it.PNG&amp;diff=140079"/>
		<updated>2021-10-26T17:00:09Z</updated>

		<summary type="html">&lt;p&gt;Agcarrut: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Agcarrut</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2021_-_E2144._Refactor_delayed_mailer_and_scheduled_task&amp;diff=140078</id>
		<title>CSC/ECE 517 Fall 2021 - E2144. Refactor delayed mailer and scheduled task</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2021_-_E2144._Refactor_delayed_mailer_and_scheduled_task&amp;diff=140078"/>
		<updated>2021-10-26T16:58:19Z</updated>

		<summary type="html">&lt;p&gt;Agcarrut: /* MailWorker Test */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;__TOC__&lt;br /&gt;
&lt;br /&gt;
== Background ==&lt;br /&gt;
This project revolves around the Sidekiq gem for asynchronous processing of email tasks. It has a queue system to hold and then process jobs. Sidekiq’s queue replaces DelayedMailer’s queue. The previous team that worked on this also created a method &amp;lt;code&amp;gt;perform()&amp;lt;/code&amp;gt; to gather email IDs of all participants in an assignment and send them an email reminder. Some test cases exist for this work.&lt;br /&gt;
&lt;br /&gt;
=== Previous Setup ===&lt;br /&gt;
Initial work can be found [https://expertiza.csc.ncsu.edu/index.php/E1835_Refactor_delayed_mailer_and_scheduled_task here].&lt;br /&gt;
&lt;br /&gt;
Code in the [https://github.com/expertiza/expertiza/pull/1245/files pull request] was found to be reasonable and working. The method &amp;lt;code&amp;gt;perform()&amp;lt;/code&amp;gt; has:&lt;br /&gt;
{| class=wikitable style=text-align:right&lt;br /&gt;
|+ Metrics for &amp;lt;code&amp;gt;perform&amp;lt;/code&amp;gt; method&lt;br /&gt;
|-&lt;br /&gt;
! Metric !! Current Value !! Limit&lt;br /&gt;
|-&lt;br /&gt;
! Cognitive Complexity&lt;br /&gt;
| 15 || 5&lt;br /&gt;
|-&lt;br /&gt;
! Cyclomatic Complexity&lt;br /&gt;
| 8 || 6&lt;br /&gt;
|-&lt;br /&gt;
! Assignment Branch Condition size&lt;br /&gt;
| 22.93 || 15&lt;br /&gt;
|-&lt;br /&gt;
! Perceived complexity&lt;br /&gt;
| 10 || 7&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Previous pull request also has duplicated commit messages and the commits need to be squashed.&lt;br /&gt;
&lt;br /&gt;
Files involved (some changed should not have been changed):&lt;br /&gt;
* app/controllers/assignments_controller.rb&lt;br /&gt;
* app/mailers/mail_worker.rb&lt;br /&gt;
* app/models/assignment_form.rb&lt;br /&gt;
* config/sidekiq.yml&lt;br /&gt;
* spec/models/assignment_form_spec.rb&lt;br /&gt;
* spec/sidekiq_mail_worker_spec.rb&lt;br /&gt;
* spec/spec_helper.rb&lt;br /&gt;
&lt;br /&gt;
There are minor styling issues such as missing or trailing whitespaces, lines that are too long, extra empty line, unused arguments.&lt;br /&gt;
&lt;br /&gt;
=== Problem Statement ===&lt;br /&gt;
&lt;br /&gt;
This project revolves around the Sidekiq gem for asynchronous processing of email tasks. It has a queue system to hold and then process jobs. Sidekiq's queue replaces DelayedMailer’s queue. The previous team that worked on this also created a method perform() to gather email IDs of all participants in an assignment and send them an email reminder. Some test cases exist for this work.&lt;br /&gt;
The project was partially merged.&lt;br /&gt;
​&lt;br /&gt;
&lt;br /&gt;
What needs to be done:  &lt;br /&gt;
Feedback from the previous team (E1835) is:&lt;br /&gt;
Code in pull request seems pretty reasonable.  Some concerns wrt. naming functions, but otherwise reviewers seem to agree that the code is good.&lt;br /&gt;
​&lt;br /&gt;
&lt;br /&gt;
Your pull request has many duplicated commit messages. Please try to &amp;lt;code&amp;gt;squash&amp;lt;/code&amp;gt; similar commits.&lt;br /&gt;
And using meaningful commit messages later.&lt;br /&gt;
​&lt;br /&gt;
&lt;br /&gt;
You should commit changes to the DB schema (&amp;lt;code&amp;gt;db/schema.rb&amp;lt;/code&amp;gt;) only if you have created new DB migrations.&lt;br /&gt;
Please double check your code. If you did not aim to change the DB, please revert the DB schema changes. ***** Important, try not to change the DB.&lt;br /&gt;
​&lt;br /&gt;
&lt;br /&gt;
You should not change &amp;lt;code&amp;gt;rails_helper.rb&amp;lt;/code&amp;gt; or &amp;lt;code&amp;gt;spec_helper.rb&amp;lt;/code&amp;gt; file; please revert these changes.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The previous team’s code needs a refactor in some places, though the actual function of it seems solid. It is very possible that in the three years since this code has been worked on, more mailer functionality has been added. There are other teams this semester working on mailer code as well. Try to keep your code as contained and simple as possible, so that merging these projects is possible.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Summary of Work Needed ==&lt;br /&gt;
After discussing with our project mentor and Dr. Gehringer, we determined the main tasks to be the following:&lt;br /&gt;
# Refactor the single Sidekiq worker into multiple workers&lt;br /&gt;
# Remove all code related to the &amp;lt;code&amp;gt;drop_one_member_topics&amp;lt;/code&amp;gt; deadline type&lt;br /&gt;
# Update and add unit tests according to the above changes&lt;br /&gt;
# Test all new worker classes to ensure Sidekiq jobs were being dequeued and run as expected&lt;br /&gt;
# Code cleanup&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Refactor the single Sidekiq worker into multiple workers ===&lt;br /&gt;
Previously there was only a single worker class that handled all types of jobs. Its top-level method &amp;lt;code&amp;gt;perform&amp;lt;/code&amp;gt; looked like the following.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def perform(assignment_id, deadline_type, due_at)&lt;br /&gt;
    self.assignment_id = assignment_id&lt;br /&gt;
    self.deadline_type = deadline_type&lt;br /&gt;
    self.due_at = due_at&lt;br /&gt;
&lt;br /&gt;
    assignment = Assignment.find(self.assignment_id)&lt;br /&gt;
    participant_mails = find_participant_emails&lt;br /&gt;
&lt;br /&gt;
    if %w[drop_one_member_topics drop_outstanding_reviews compare_files_with_simicheck].include?(self.deadline_type)&lt;br /&gt;
      drop_one_member_topics if self.deadline_type == &amp;quot;drop_outstanding_reviews&amp;quot; &amp;amp;&amp;amp; assignment.team_assignment&lt;br /&gt;
      drop_outstanding_reviews if self.deadline_type == &amp;quot;drop_outstanding_reviews&amp;quot;&lt;br /&gt;
      perform_simicheck_comparisons(self.assignment_id) if self.deadline_type == &amp;quot;compare_files_with_simicheck&amp;quot;&lt;br /&gt;
    else&lt;br /&gt;
      # Can we rename deadline_type(metareview) to &amp;quot;teammate review&amp;quot;. If, yes then we donot need this if clause below!&lt;br /&gt;
      deadlineText = if self.deadline_type == &amp;quot;metareview&amp;quot;&lt;br /&gt;
                       &amp;quot;teammate review&amp;quot;&lt;br /&gt;
                     else&lt;br /&gt;
                       self.deadline_type&lt;br /&gt;
      end&lt;br /&gt;
&lt;br /&gt;
      email_reminder(participant_mails, deadlineText) unless participant_mails.empty?&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The processing was different depending on the &amp;lt;code&amp;gt;deadline_type&amp;lt;/code&amp;gt;. The &amp;lt;code&amp;gt;deadline_type&amp;lt;/code&amp;gt;s in&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
%w[drop_one_member_topics drop_outstanding_reviews compare_files_with_simicheck]&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
did not lead to an email reminder being sent, but they were still handled in this &amp;lt;code&amp;gt;MailWorker&amp;lt;/code&amp;gt; class.&lt;br /&gt;
&lt;br /&gt;
To make the code more manageable and easier to follow, it made sense to break up the responsibilities of this single &amp;lt;code&amp;gt;MailWorker&amp;lt;/code&amp;gt; class into multiple workers:&lt;br /&gt;
* &amp;lt;code&amp;gt;SimicheckWorker&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;DropOutstandingReviewsWorker&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;MailWorker&amp;lt;/code&amp;gt;&lt;br /&gt;
All three workers extended an &amp;quot;abstract class&amp;quot; called &amp;lt;code&amp;gt;Worker&amp;lt;/code&amp;gt; that contained the Sidekiq-related &amp;lt;code&amp;gt;include&amp;lt;/code&amp;gt; and the queue name to which all jobs would be sent.&lt;br /&gt;
&lt;br /&gt;
For simplicity, we still had all new workers continue to use a single queue, which we renamed from &amp;lt;code&amp;gt;mailers&amp;lt;/code&amp;gt; to &amp;lt;code&amp;gt;jobs&amp;lt;/code&amp;gt;. A future improvement could divide these jobs to go to multiple different queues if needed.&lt;br /&gt;
&lt;br /&gt;
=== Remove all code related to the &amp;lt;code&amp;gt;drop_one_member_topics&amp;lt;/code&amp;gt; deadline type ===&lt;br /&gt;
It was decided that code used for dropping one member or two member teams from topics would never need to be implemented in the Expertiza website. Thus, we removed all code related to the drop_one_member_topics method within the Expertiza beta. This involved removing the &amp;lt;code&amp;gt;drop_one_member_topics&amp;lt;/code&amp;gt; function from &amp;lt;code&amp;gt;drop_outstanding_reviews_mail_worker.rb&amp;lt;/code&amp;gt;, now renamed &amp;lt;code&amp;gt;drop_outstanding_reviews_worker.rb&amp;lt;/code&amp;gt;. The &amp;lt;code&amp;gt;drop_one_member_topics&amp;lt;/code&amp;gt; method was called from the &amp;lt;code&amp;gt;prepare_data&amp;lt;/code&amp;gt; method, which was then called by the Sidekiq method &amp;lt;code&amp;gt;perform&amp;lt;/code&amp;gt; so we removed this call. The &amp;lt;code&amp;gt;drop_one_member_topics&amp;lt;/code&amp;gt; was also referenced in &amp;lt;code&amp;gt;assignment_form.rb&amp;lt;/code&amp;gt; using &amp;lt;code&amp;gt;add_delayed_job&amp;lt;/code&amp;gt; in the &amp;lt;code&amp;gt;add_to_delayed_queue&amp;lt;/code&amp;gt; method and in &amp;lt;code&amp;gt;delayed_mailer.html.erb&amp;lt;/code&amp;gt; as an option for the handler so both of these code snippets were removed as well.&lt;br /&gt;
&lt;br /&gt;
=== Update and add unit tests according to the above changes ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Test all new worker classes to ensure Sidekiq jobs were being dequeued and run as expected ===&lt;br /&gt;
==== Sidekiq setup ====&lt;br /&gt;
In order to test the Sidekiq workers, a few steps were needed to set up the workers and run Sidekiq (steps were obtained from [https://tudip.com/blog-post/how-to-use-sidekiq-in-rails-for-background-processing/ this site]):&lt;br /&gt;
# Initialize three new workers, each having one of the three new worker types:&lt;br /&gt;
## &amp;lt;code&amp;gt;rails g sidekiq:worker SimicheckWorker&amp;lt;/code&amp;gt;&lt;br /&gt;
## &amp;lt;code&amp;gt;rails g sidekiq:worker DropOutstandingReviewsWorker&amp;lt;/code&amp;gt;&lt;br /&gt;
## &amp;lt;code&amp;gt;rails g sidekiq:worker MailWorker&amp;lt;/code&amp;gt;&lt;br /&gt;
# In a terminal separate from the one in which the main rails application is running, run&lt;br /&gt;
&amp;lt;blockquote&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
bundle exec sidekiq&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This Sidekiq-specific terminal will show logs and printed statements from the workers.&lt;br /&gt;
&lt;br /&gt;
==== SimicheckWorker Test ====&lt;br /&gt;
&lt;br /&gt;
==== MailWorker Test ====&lt;br /&gt;
The General Mail Worker sends out notifications to students if the due date of an assignment is changed. To test General Mail Worker, we first created an assignment with the default options by logging in as an instructor, going to Manage&amp;gt;Assignments in the navigation, and clicking the plus button in the top right corner on the Manage Assignments. We then assigned student7613 to the assignment we had created by clicking the person with the plus icon in the icons next to the assignment on the Manage Assignments page. At this point, we realized we need to alter the code to test if the code was properly queuing the General Mail Worker because the current if statement to add items to the delayed queue required that it have a late policy.&lt;br /&gt;
&lt;br /&gt;
==== DropOutstandingReviewsWorker Test ====&lt;br /&gt;
&lt;br /&gt;
=== Sidekiq UI ===&lt;br /&gt;
To see which messages were being enqueued and dequeued in Sidekiq, we use the Sidekiq user interface, which can be accessed via the &amp;lt;code&amp;gt;/sidekiq&amp;lt;/code&amp;gt; route of the application.&lt;br /&gt;
[[File:Sidekiq-ui.png|950px|The Sidekiq UI]]&lt;br /&gt;
&lt;br /&gt;
=== Code Cleanup ===&lt;br /&gt;
Smaller improvements done while implementing the main tasks included:&lt;br /&gt;
* Using ActiveSupport::Duration objects in order to calculate the minutes and seconds related to the dequeue times&lt;br /&gt;
* Refactoring the time calculations for the dequeue times to the DueDate class&lt;br /&gt;
* Correcting the parameters passed to the workers, which were previously incorrect. As an example:&lt;br /&gt;
&amp;lt;blockquote&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def add_delayed_job(_assignment, deadline_type, due_date, min_left)&lt;br /&gt;
    delayed_job_id = MailWorker.perform_in(min_left * 60, due_date.parent_id, deadline_type, due_date.due_at)&lt;br /&gt;
    delayed_job_id&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
The first parameter after the time delay must be assignment ID, and &amp;lt;code&amp;gt;due_date.parent_id&amp;lt;/code&amp;gt; is not an assignment ID.&lt;br /&gt;
&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
* Removing whitespace issues reported by codeclimate&lt;br /&gt;
* Refactoring all variable names to be in snake_case&lt;br /&gt;
* Removing identical blocks of code&lt;br /&gt;
* Adding method comments to make methods more understandable&lt;br /&gt;
* ...&lt;/div&gt;</summary>
		<author><name>Agcarrut</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2021_-_E2144._Refactor_delayed_mailer_and_scheduled_task&amp;diff=139506</id>
		<title>CSC/ECE 517 Fall 2021 - E2144. Refactor delayed mailer and scheduled task</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2021_-_E2144._Refactor_delayed_mailer_and_scheduled_task&amp;diff=139506"/>
		<updated>2021-10-20T20:28:53Z</updated>

		<summary type="html">&lt;p&gt;Agcarrut: Added more code cleanup that was done&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;__TOC__&lt;br /&gt;
&lt;br /&gt;
== Background ==&lt;br /&gt;
This project revolves around the Sidekiq gem for asynchronous processing of email tasks. It has a queue system to hold and then process jobs. Sidekiq’s queue replaces DelayedMailer’s queue. The previous team that worked on this also created a method &amp;lt;code&amp;gt;perform()&amp;lt;/code&amp;gt; to gather email IDs of all participants in an assignment and send them an email reminder. Some test cases exist for this work.&lt;br /&gt;
&lt;br /&gt;
=== Previous Setup ===&lt;br /&gt;
Initial work can be found [https://expertiza.csc.ncsu.edu/index.php/E1835_Refactor_delayed_mailer_and_scheduled_task here].&lt;br /&gt;
&lt;br /&gt;
Code in the [https://github.com/expertiza/expertiza/pull/1245/files pull request] was found to be reasonable and working. The method &amp;lt;code&amp;gt;perform()&amp;lt;/code&amp;gt; has:&lt;br /&gt;
{| class=wikitable style=text-align:right&lt;br /&gt;
|+ Metrics for &amp;lt;code&amp;gt;perform&amp;lt;/code&amp;gt; method&lt;br /&gt;
|-&lt;br /&gt;
! Metric !! Current Value !! Limit&lt;br /&gt;
|-&lt;br /&gt;
! Cognitive Complexity&lt;br /&gt;
| 15 || 5&lt;br /&gt;
|-&lt;br /&gt;
! Cyclomatic Complexity&lt;br /&gt;
| 8 || 6&lt;br /&gt;
|-&lt;br /&gt;
! Assignment Branch Condition size&lt;br /&gt;
| 22.93 || 15&lt;br /&gt;
|-&lt;br /&gt;
! Perceived complexity&lt;br /&gt;
| 10 || 7&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Previous pull request also has duplicated commit messages and the commits need to be squashed.&lt;br /&gt;
&lt;br /&gt;
Files involved (some changed should not have been changed):&lt;br /&gt;
* app/controllers/assignments_controller.rb&lt;br /&gt;
* app/mailers/mail_worker.rb&lt;br /&gt;
* app/models/assignment_form.rb&lt;br /&gt;
* config/sidekiq.yml&lt;br /&gt;
* spec/models/assignment_form_spec.rb&lt;br /&gt;
* spec/sidekiq_mail_worker_spec.rb&lt;br /&gt;
* spec/spec_helper.rb&lt;br /&gt;
&lt;br /&gt;
There are minor styling issues such as missing or trailing whitespaces, lines that are too long, extra empty line, unused arguments.&lt;br /&gt;
&lt;br /&gt;
=== Problem Statement ===&lt;br /&gt;
&lt;br /&gt;
This project revolves around the Sidekiq gem for asynchronous processing of email tasks. It has a queue system to hold and then process jobs. Sidekiq's queue replaces DelayedMailer’s queue. The previous team that worked on this also created a method perform() to gather email IDs of all participants in an assignment and send them an email reminder. Some test cases exist for this work.&lt;br /&gt;
The project was partially merged.&lt;br /&gt;
​&lt;br /&gt;
&lt;br /&gt;
What needs to be done:  &lt;br /&gt;
Feedback from the previous team (E1835) is:&lt;br /&gt;
Code in pull request seems pretty reasonable.  Some concerns wrt. naming functions, but otherwise reviewers seem to agree that the code is good.&lt;br /&gt;
​&lt;br /&gt;
&lt;br /&gt;
Your pull request has many duplicated commit messages. Please try to &amp;lt;code&amp;gt;squash&amp;lt;/code&amp;gt; similar commits.&lt;br /&gt;
And using meaningful commit messages later.&lt;br /&gt;
​&lt;br /&gt;
&lt;br /&gt;
You should commit changes to the DB schema (&amp;lt;code&amp;gt;db/schema.rb&amp;lt;/code&amp;gt;) only if you have created new DB migrations.&lt;br /&gt;
Please double check your code. If you did not aim to change the DB, please revert the DB schema changes. ***** Important, try not to change the DB.&lt;br /&gt;
​&lt;br /&gt;
&lt;br /&gt;
You should not change &amp;lt;code&amp;gt;rails_helper.rb&amp;lt;/code&amp;gt; or &amp;lt;code&amp;gt;spec_helper.rb&amp;lt;/code&amp;gt; file; please revert these changes.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The previous team’s code needs a refactor in some places, though the actual function of it seems solid. It is very possible that in the three years since this code has been worked on, more mailer functionality has been added. There are other teams this semester working on mailer code as well. Try to keep your code as contained and simple as possible, so that merging these projects is possible.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Summary of Work Needed ==&lt;br /&gt;
After discussing with our project mentor and Dr. Gehringer, we determined the main tasks to be the following:&lt;br /&gt;
# Refactor the single Sidekiq worker into multiple workers&lt;br /&gt;
# Remove all code related to the &amp;lt;code&amp;gt;drop_one_member_topics&amp;lt;/code&amp;gt; deadline type&lt;br /&gt;
# Update and add unit tests according to the above changes&lt;br /&gt;
# Test all new worker classes to ensure Sidekiq jobs were being dequeued and run as expected&lt;br /&gt;
# Code cleanup&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Refactor the single Sidekiq worker into multiple workers ===&lt;br /&gt;
Previously there was only a single worker class that handled all types of jobs. Its top-level method &amp;lt;code&amp;gt;perform&amp;lt;/code&amp;gt; looked like the following.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def perform(assignment_id, deadline_type, due_at)&lt;br /&gt;
    self.assignment_id = assignment_id&lt;br /&gt;
    self.deadline_type = deadline_type&lt;br /&gt;
    self.due_at = due_at&lt;br /&gt;
&lt;br /&gt;
    assignment = Assignment.find(self.assignment_id)&lt;br /&gt;
    participant_mails = find_participant_emails&lt;br /&gt;
&lt;br /&gt;
    if %w[drop_one_member_topics drop_outstanding_reviews compare_files_with_simicheck].include?(self.deadline_type)&lt;br /&gt;
      drop_one_member_topics if self.deadline_type == &amp;quot;drop_outstanding_reviews&amp;quot; &amp;amp;&amp;amp; assignment.team_assignment&lt;br /&gt;
      drop_outstanding_reviews if self.deadline_type == &amp;quot;drop_outstanding_reviews&amp;quot;&lt;br /&gt;
      perform_simicheck_comparisons(self.assignment_id) if self.deadline_type == &amp;quot;compare_files_with_simicheck&amp;quot;&lt;br /&gt;
    else&lt;br /&gt;
      # Can we rename deadline_type(metareview) to &amp;quot;teammate review&amp;quot;. If, yes then we donot need this if clause below!&lt;br /&gt;
      deadlineText = if self.deadline_type == &amp;quot;metareview&amp;quot;&lt;br /&gt;
                       &amp;quot;teammate review&amp;quot;&lt;br /&gt;
                     else&lt;br /&gt;
                       self.deadline_type&lt;br /&gt;
      end&lt;br /&gt;
&lt;br /&gt;
      email_reminder(participant_mails, deadlineText) unless participant_mails.empty?&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The processing was different depending on the &amp;lt;code&amp;gt;deadline_type&amp;lt;/code&amp;gt;. The &amp;lt;code&amp;gt;deadline_type&amp;lt;/code&amp;gt;s in&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
%w[drop_one_member_topics drop_outstanding_reviews compare_files_with_simicheck]&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
did not lead to an email reminder being sent, but they were still handled in this &amp;lt;code&amp;gt;MailWorker&amp;lt;/code&amp;gt; class.&lt;br /&gt;
&lt;br /&gt;
To make the code more manageable and easier to follow, it made sense to break up the responsibilities of this single &amp;lt;code&amp;gt;MailWorker&amp;lt;/code&amp;gt; class into multiple workers:&lt;br /&gt;
* &amp;lt;code&amp;gt;SimicheckWorker&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;DropOutstandingReviewsWorker&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;MailWorker&amp;lt;/code&amp;gt;&lt;br /&gt;
All three workers extended an &amp;quot;abstract class&amp;quot; called &amp;lt;code&amp;gt;Worker&amp;lt;/code&amp;gt; that contained the Sidekiq-related &amp;lt;code&amp;gt;include&amp;lt;/code&amp;gt; and the queue name to which all jobs would be sent.&lt;br /&gt;
&lt;br /&gt;
For simplicity, we still had all new workers continue to use a single queue, which we renamed from &amp;lt;code&amp;gt;mailers&amp;lt;/code&amp;gt; to &amp;lt;code&amp;gt;jobs&amp;lt;/code&amp;gt;. A future improvement could divide these jobs to go to multiple different queues if needed.&lt;br /&gt;
&lt;br /&gt;
=== Remove all code related to the &amp;lt;code&amp;gt;drop_one_member_topics&amp;lt;/code&amp;gt; deadline type ===&lt;br /&gt;
It was decided that code used for dropping one member or two member teams from topics would never need to be implemented in the Expertiza website. Thus, we removed all code related to the drop_one_member_topics method within the Expertiza beta. This involved removing the &amp;lt;code&amp;gt;drop_one_member_topics&amp;lt;/code&amp;gt; function from &amp;lt;code&amp;gt;drop_outstanding_reviews_mail_worker.rb&amp;lt;/code&amp;gt;, now renamed &amp;lt;code&amp;gt;drop_outstanding_reviews_worker.rb&amp;lt;/code&amp;gt;. The &amp;lt;code&amp;gt;drop_one_member_topics&amp;lt;/code&amp;gt; method was called from the &amp;lt;code&amp;gt;prepare_data&amp;lt;/code&amp;gt; method, which was then called by the Sidekiq method &amp;lt;code&amp;gt;perform&amp;lt;/code&amp;gt; so we removed this call. The &amp;lt;code&amp;gt;drop_one_member_topics&amp;lt;/code&amp;gt; was also referenced in &amp;lt;code&amp;gt;assignment_form.rb&amp;lt;/code&amp;gt; using &amp;lt;code&amp;gt;add_delayed_job&amp;lt;/code&amp;gt; in the &amp;lt;code&amp;gt;add_to_delayed_queue&amp;lt;/code&amp;gt; method and in &amp;lt;code&amp;gt;delayed_mailer.html.erb&amp;lt;/code&amp;gt; as an option for the handler so both of these code snippets were removed as well.&lt;br /&gt;
&lt;br /&gt;
=== Update and add unit tests according to the above changes ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Test all new worker classes to ensure Sidekiq jobs were being dequeued and run as expected ===&lt;br /&gt;
==== Sidekiq setup ====&lt;br /&gt;
In order to test the Sidekiq workers, a few steps were needed to set up the workers and run Sidekiq (steps were obtained from [https://tudip.com/blog-post/how-to-use-sidekiq-in-rails-for-background-processing/ this site]):&lt;br /&gt;
# Initialize three new workers, each having one of the three new worker types:&lt;br /&gt;
## &amp;lt;code&amp;gt;rails g sidekiq:worker SimicheckWorker&amp;lt;/code&amp;gt;&lt;br /&gt;
## &amp;lt;code&amp;gt;rails g sidekiq:worker DropOutstandingReviewsWorker&amp;lt;/code&amp;gt;&lt;br /&gt;
## &amp;lt;code&amp;gt;rails g sidekiq:worker MailWorker&amp;lt;/code&amp;gt;&lt;br /&gt;
# In a terminal separate from the one in which the main rails application is running, run&lt;br /&gt;
&amp;lt;blockquote&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
bundle exec sidekiq&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This Sidekiq-specific terminal will show logs and printed statements from the workers.&lt;br /&gt;
&lt;br /&gt;
=== Sidekiq UI ===&lt;br /&gt;
To see which messages were being enqueued and dequeued in Sidekiq, we use the Sidekiq user interface, which can be accessed via the &amp;lt;code&amp;gt;/sidekiq&amp;lt;/code&amp;gt; route of the application.&lt;br /&gt;
[[File:Sidekiq-ui.png|950px|The Sidekiq UI]]&lt;br /&gt;
&lt;br /&gt;
=== Code Cleanup ===&lt;br /&gt;
Smaller improvements done while implementing the main tasks included:&lt;br /&gt;
* Using ActiveSupport::Duration objects in order to calculate the minutes and seconds related to the dequeue times&lt;br /&gt;
* Refactoring the time calculations for the dequeue times to the DueDate class&lt;br /&gt;
* Correcting the parameters passed to the workers, which were previously incorrect. As an example:&lt;br /&gt;
&amp;lt;blockquote&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def add_delayed_job(_assignment, deadline_type, due_date, min_left)&lt;br /&gt;
    delayed_job_id = MailWorker.perform_in(min_left * 60, due_date.parent_id, deadline_type, due_date.due_at)&lt;br /&gt;
    delayed_job_id&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
The first parameter after the time delay must be assignment ID, and &amp;lt;code&amp;gt;due_date.parent_id&amp;lt;/code&amp;gt; is not an assignment ID.&lt;br /&gt;
&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
* Removing whitespace issues reported by codeclimate&lt;br /&gt;
* Refactoring all variable names to be in snake_case&lt;br /&gt;
* Removing identical blocks of code&lt;br /&gt;
* Adding method comments to make methods more understandable&lt;br /&gt;
* ...&lt;/div&gt;</summary>
		<author><name>Agcarrut</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2021_-_E2144._Refactor_delayed_mailer_and_scheduled_task&amp;diff=139502</id>
		<title>CSC/ECE 517 Fall 2021 - E2144. Refactor delayed mailer and scheduled task</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2021_-_E2144._Refactor_delayed_mailer_and_scheduled_task&amp;diff=139502"/>
		<updated>2021-10-20T20:25:25Z</updated>

		<summary type="html">&lt;p&gt;Agcarrut: Added info on drop_one_member_topics&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;__TOC__&lt;br /&gt;
&lt;br /&gt;
== Background ==&lt;br /&gt;
This project revolves around the Sidekiq gem for asynchronous processing of email tasks. It has a queue system to hold and then process jobs. Sidekiq’s queue replaces DelayedMailer’s queue. The previous team that worked on this also created a method &amp;lt;code&amp;gt;perform()&amp;lt;/code&amp;gt; to gather email IDs of all participants in an assignment and send them an email reminder. Some test cases exist for this work.&lt;br /&gt;
&lt;br /&gt;
=== Previous Setup ===&lt;br /&gt;
Initial work can be found [https://expertiza.csc.ncsu.edu/index.php/E1835_Refactor_delayed_mailer_and_scheduled_task here].&lt;br /&gt;
&lt;br /&gt;
Code in the [https://github.com/expertiza/expertiza/pull/1245/files pull request] was found to be reasonable and working. The method &amp;lt;code&amp;gt;perform()&amp;lt;/code&amp;gt; has:&lt;br /&gt;
{| class=wikitable style=text-align:right&lt;br /&gt;
|+ Metrics for &amp;lt;code&amp;gt;perform&amp;lt;/code&amp;gt; method&lt;br /&gt;
|-&lt;br /&gt;
! Metric !! Current Value !! Limit&lt;br /&gt;
|-&lt;br /&gt;
! Cognitive Complexity&lt;br /&gt;
| 15 || 5&lt;br /&gt;
|-&lt;br /&gt;
! Cyclomatic Complexity&lt;br /&gt;
| 8 || 6&lt;br /&gt;
|-&lt;br /&gt;
! Assignment Branch Condition size&lt;br /&gt;
| 22.93 || 15&lt;br /&gt;
|-&lt;br /&gt;
! Perceived complexity&lt;br /&gt;
| 10 || 7&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Previous pull request also has duplicated commit messages and the commits need to be squashed.&lt;br /&gt;
&lt;br /&gt;
Files involved (some changed should not have been changed):&lt;br /&gt;
* app/controllers/assignments_controller.rb&lt;br /&gt;
* app/mailers/mail_worker.rb&lt;br /&gt;
* app/models/assignment_form.rb&lt;br /&gt;
* config/sidekiq.yml&lt;br /&gt;
* spec/models/assignment_form_spec.rb&lt;br /&gt;
* spec/sidekiq_mail_worker_spec.rb&lt;br /&gt;
* spec/spec_helper.rb&lt;br /&gt;
&lt;br /&gt;
There are minor styling issues such as missing or trailing whitespaces, lines that are too long, extra empty line, unused arguments.&lt;br /&gt;
&lt;br /&gt;
=== Problem Statement ===&lt;br /&gt;
&lt;br /&gt;
This project revolves around the Sidekiq gem for asynchronous processing of email tasks. It has a queue system to hold and then process jobs. Sidekiq's queue replaces DelayedMailer’s queue. The previous team that worked on this also created a method perform() to gather email IDs of all participants in an assignment and send them an email reminder. Some test cases exist for this work.&lt;br /&gt;
The project was partially merged.&lt;br /&gt;
​&lt;br /&gt;
&lt;br /&gt;
What needs to be done:  &lt;br /&gt;
Feedback from the previous team (E1835) is:&lt;br /&gt;
Code in pull request seems pretty reasonable.  Some concerns wrt. naming functions, but otherwise reviewers seem to agree that the code is good.&lt;br /&gt;
​&lt;br /&gt;
&lt;br /&gt;
Your pull request has many duplicated commit messages. Please try to &amp;lt;code&amp;gt;squash&amp;lt;/code&amp;gt; similar commits.&lt;br /&gt;
And using meaningful commit messages later.&lt;br /&gt;
​&lt;br /&gt;
&lt;br /&gt;
You should commit changes to the DB schema (&amp;lt;code&amp;gt;db/schema.rb&amp;lt;/code&amp;gt;) only if you have created new DB migrations.&lt;br /&gt;
Please double check your code. If you did not aim to change the DB, please revert the DB schema changes. ***** Important, try not to change the DB.&lt;br /&gt;
​&lt;br /&gt;
&lt;br /&gt;
You should not change &amp;lt;code&amp;gt;rails_helper.rb&amp;lt;/code&amp;gt; or &amp;lt;code&amp;gt;spec_helper.rb&amp;lt;/code&amp;gt; file; please revert these changes.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The previous team’s code needs a refactor in some places, though the actual function of it seems solid. It is very possible that in the three years since this code has been worked on, more mailer functionality has been added. There are other teams this semester working on mailer code as well. Try to keep your code as contained and simple as possible, so that merging these projects is possible.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Summary of Work Needed ==&lt;br /&gt;
After discussing with our project mentor and Dr. Gehringer, we determined the main tasks to be the following:&lt;br /&gt;
# Refactor the single Sidekiq worker into multiple workers&lt;br /&gt;
# Remove all code related to the &amp;lt;code&amp;gt;drop_one_member_topics&amp;lt;/code&amp;gt; deadline type&lt;br /&gt;
# Update and add unit tests according to the above changes&lt;br /&gt;
# Test all new worker classes to ensure Sidekiq jobs were being dequeued and run as expected&lt;br /&gt;
# Code cleanup&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Refactor the single Sidekiq worker into multiple workers ===&lt;br /&gt;
Previously there was only a single worker class that handled all types of jobs. Its top-level method &amp;lt;code&amp;gt;perform&amp;lt;/code&amp;gt; looked like the following.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def perform(assignment_id, deadline_type, due_at)&lt;br /&gt;
    self.assignment_id = assignment_id&lt;br /&gt;
    self.deadline_type = deadline_type&lt;br /&gt;
    self.due_at = due_at&lt;br /&gt;
&lt;br /&gt;
    assignment = Assignment.find(self.assignment_id)&lt;br /&gt;
    participant_mails = find_participant_emails&lt;br /&gt;
&lt;br /&gt;
    if %w[drop_one_member_topics drop_outstanding_reviews compare_files_with_simicheck].include?(self.deadline_type)&lt;br /&gt;
      drop_one_member_topics if self.deadline_type == &amp;quot;drop_outstanding_reviews&amp;quot; &amp;amp;&amp;amp; assignment.team_assignment&lt;br /&gt;
      drop_outstanding_reviews if self.deadline_type == &amp;quot;drop_outstanding_reviews&amp;quot;&lt;br /&gt;
      perform_simicheck_comparisons(self.assignment_id) if self.deadline_type == &amp;quot;compare_files_with_simicheck&amp;quot;&lt;br /&gt;
    else&lt;br /&gt;
      # Can we rename deadline_type(metareview) to &amp;quot;teammate review&amp;quot;. If, yes then we donot need this if clause below!&lt;br /&gt;
      deadlineText = if self.deadline_type == &amp;quot;metareview&amp;quot;&lt;br /&gt;
                       &amp;quot;teammate review&amp;quot;&lt;br /&gt;
                     else&lt;br /&gt;
                       self.deadline_type&lt;br /&gt;
      end&lt;br /&gt;
&lt;br /&gt;
      email_reminder(participant_mails, deadlineText) unless participant_mails.empty?&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The processing was different depending on the &amp;lt;code&amp;gt;deadline_type&amp;lt;/code&amp;gt;. The &amp;lt;code&amp;gt;deadline_type&amp;lt;/code&amp;gt;s in&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
%w[drop_one_member_topics drop_outstanding_reviews compare_files_with_simicheck]&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
did not lead to an email reminder being sent, but they were still handled in this &amp;lt;code&amp;gt;MailWorker&amp;lt;/code&amp;gt; class.&lt;br /&gt;
&lt;br /&gt;
To make the code more manageable and easier to follow, it made sense to break up the responsibilities of this single &amp;lt;code&amp;gt;MailWorker&amp;lt;/code&amp;gt; class into multiple workers:&lt;br /&gt;
* &amp;lt;code&amp;gt;SimicheckWorker&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;DropOutstandingReviewsWorker&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;MailWorker&amp;lt;/code&amp;gt;&lt;br /&gt;
All three workers extended an &amp;quot;abstract class&amp;quot; called &amp;lt;code&amp;gt;Worker&amp;lt;/code&amp;gt; that contained the Sidekiq-related &amp;lt;code&amp;gt;include&amp;lt;/code&amp;gt; and the queue name to which all jobs would be sent.&lt;br /&gt;
&lt;br /&gt;
For simplicity, we still had all new workers continue to use a single queue, which we renamed from &amp;lt;code&amp;gt;mailers&amp;lt;/code&amp;gt; to &amp;lt;code&amp;gt;jobs&amp;lt;/code&amp;gt;. A future improvement could divide these jobs to go to multiple different queues if needed.&lt;br /&gt;
&lt;br /&gt;
=== Remove all code related to the &amp;lt;code&amp;gt;drop_one_member_topics&amp;lt;/code&amp;gt; deadline type ===&lt;br /&gt;
It was decided that code used for dropping one member or two member teams from topics would never need to be implemented in the Expertiza website. Thus, we removed all code related to the drop_one_member_topics method within the Expertiza beta. This involved removing the &amp;lt;code&amp;gt;drop_one_member_topics&amp;lt;/code&amp;gt; function from &amp;lt;code&amp;gt;drop_outstanding_reviews_mail_worker.rb&amp;lt;/code&amp;gt;, now renamed &amp;lt;code&amp;gt;drop_outstanding_reviews_worker.rb&amp;lt;/code&amp;gt;. The &amp;lt;code&amp;gt;drop_one_member_topics&amp;lt;/code&amp;gt; method was called from the &amp;lt;code&amp;gt;prepare_data&amp;lt;/code&amp;gt; method, which was then called by the Sidekiq method &amp;lt;code&amp;gt;perform&amp;lt;/code&amp;gt; so we removed this call. The &amp;lt;code&amp;gt;drop_one_member_topics&amp;lt;/code&amp;gt; was also referenced in &amp;lt;code&amp;gt;assignment_form.rb&amp;lt;/code&amp;gt; using &amp;lt;code&amp;gt;add_delayed_job&amp;lt;/code&amp;gt; in the &amp;lt;code&amp;gt;add_to_delayed_queue&amp;lt;/code&amp;gt; method and in &amp;lt;code&amp;gt;delayed_mailer.html.erb&amp;lt;/code&amp;gt; as an option for the handler so both of these code snippets were removed as well.&lt;br /&gt;
&lt;br /&gt;
=== Update and add unit tests according to the above changes ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Test all new worker classes to ensure Sidekiq jobs were being dequeued and run as expected ===&lt;br /&gt;
==== Sidekiq setup ====&lt;br /&gt;
In order to test the Sidekiq workers, a few steps were needed to set up the workers and run Sidekiq (steps were obtained from [https://tudip.com/blog-post/how-to-use-sidekiq-in-rails-for-background-processing/ this site]):&lt;br /&gt;
# Initialize three new workers, each having one of the three new worker types:&lt;br /&gt;
## &amp;lt;code&amp;gt;rails g sidekiq:worker SimicheckWorker&amp;lt;/code&amp;gt;&lt;br /&gt;
## &amp;lt;code&amp;gt;rails g sidekiq:worker DropOutstandingReviewsWorker&amp;lt;/code&amp;gt;&lt;br /&gt;
## &amp;lt;code&amp;gt;rails g sidekiq:worker MailWorker&amp;lt;/code&amp;gt;&lt;br /&gt;
# In a terminal separate from the one in which the main rails application is running, run&lt;br /&gt;
&amp;lt;blockquote&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
bundle exec sidekiq&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This Sidekiq-specific terminal will show logs and printed statements from the workers.&lt;br /&gt;
&lt;br /&gt;
=== Sidekiq UI ===&lt;br /&gt;
To see which messages were being enqueued and dequeued in Sidekiq, we use the Sidekiq user interface, which can be accessed via the &amp;lt;code&amp;gt;/sidekiq&amp;lt;/code&amp;gt; route of the application.&lt;br /&gt;
[[File:Sidekiq-ui.png|950px|The Sidekiq UI]]&lt;br /&gt;
&lt;br /&gt;
=== Code Cleanup ===&lt;br /&gt;
Smaller improvements done while implementing the main tasks included:&lt;br /&gt;
* Using ActiveSupport::Duration objects in order to calculate the minutes and seconds related to the dequeue times&lt;br /&gt;
* Refactored the time calculations for the dequeue times to the DueDate class&lt;br /&gt;
* Correcting the parameters passed to the workers, which were previously incorrect. As an example:&lt;br /&gt;
&amp;lt;blockquote&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def add_delayed_job(_assignment, deadline_type, due_date, min_left)&lt;br /&gt;
    delayed_job_id = MailWorker.perform_in(min_left * 60, due_date.parent_id, deadline_type, due_date.due_at)&lt;br /&gt;
    delayed_job_id&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
The first parameter after the time delay must be assignment ID, and &amp;lt;code&amp;gt;due_date.parent_id&amp;lt;/code&amp;gt; is not an assignment ID.&lt;br /&gt;
&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
* ...&lt;/div&gt;</summary>
		<author><name>Agcarrut</name></author>
	</entry>
</feed>